메인 컨텐츠로 가기

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

SSH 도어를 위한 세 가지 잠금 장치

해커 지망생들의 삶을 더 피곤하게 만드는 기술

Federico Kereki, Systems Engineer, 自由职业者
Photo of Federico Kereki
Federico Kereki はウルグアイ人のシステム・エンジニアであり、システム開発やコンサルティング、大学での教育に 20 年を超える経験があります。現在はおなじみの頭字語、SOA、GWT、Ajax、PHP、そしてもちろん FLOSS を渾然一体に扱いながら業務を行っています。
(An IBM developerWorks Contributing Author)

요약:  보안에는 항상 여러 계층의 스킴이 필요합니다. SSH가 그 좋은 예입니다. 간단한 sshd 구성에서부터 SSH를 사용할 수 있는 사람을 지정하기 위한 PAM 사용, 포트 노킹 기술의 적용 또는 SSH 액세스가 존재한다는 사실조차 숨기는 방법까지, 매우 다양한 방법이 있습니다. 이런 기술들을 적용하면 시스템에 침입하려는 자들이 생소한 세 가지 장벽을 통과해야 하므로 해킹하기 훨씬 더 어려워집니다.

원문 게재일:  2010 년 8 월 31 일 번역 게재일:   2010 년 12 월 14 일
난이도:  중급 원문:  보기 PDF:  A4 and Letter (57KB | 14 pages)Get Adobe® Reader®
페이지뷰:  3373 회
의견:  


소개

컴퓨터에 대한 원격 액세스가 필요하여 SSH(Secure Shell) 연결을 사용하는 경우, 방어망을 뚫고 시스템의 통제권을 뺏으려는 해커들을 자연스럽게 끌어들이게 될 것이라는 점을 인정해야 한다. 시스템이 "h4x0r"에 의한 "0wn3d"이 아닐 것이라는 보장이 없더라도, 몇 가지 간단한 솔루션으로 SSH 도어를 강화함으로써 침입하려는 자들에게 좀 더 어려움을 안겨줄 수 있다. 이 기사에서는 다음과 같은 세 가지 기술을 고려한다.

자주 사용하는 약어

  • API: Application programming interface
  • DNS: Domain Name System
  • IETF: Internet Engineering Task Force
  • LDAP: Lightweight Directory Access Protocol
  • RFC: Request for comments
  • TCP: Transmission Control Protocol
  • UDP: User Datagram Protocol
  1. SSH의 표준 포트를 생소한 값으로 변경하고 SSH 구성을 강화하여 장난삼아 하는 단순한 공격은 그냥 튕겨 나가도록 한다.
  2. 로그인이 허용되는 사용자 목록을 한정하여 정의한다.
  3. SSH 액세스를 허용한다는 사실 자체를 완전히 숨기고 액세스 가능한 사용자로 인식되려면 특수한 "노크" 시퀀스를 필요하게끔 한다.

이런 기술을 적용하려면 루트 계정에 액세스해야 한다. 또한, 몇몇 패키지를 설치해야 할 것이며, 방화벽과 라우터가 있다면 특정 포트를 여닫아 이들 패키지를 시스템으로 전달하도록 방화벽과 라우터를 구성해야 한다.


도어 강화

"모호함을 통한 보안"이란 개념은 잘 알려져 있을 뿐 아니라, 많은 조롱도 받고 있다. 왜냐하면 아무도 이런 방법을 파악하지 못할 것이라는 기대를 안고 모호한 방법으로 보안을 설정하는 것은 단지 문제를 일으킬 뿐이기 때문이다. 하지만, 어떤 상황에서는 약간의 모호함이 도움이 될 수 있다. 간단한 대책으로 단호한 자세로 공격하는 해커를 막을 수는 없더라도, 최소한 스크립트가 대체로 그렇게 완전하지 않은 "초보적 스크립트"에 대해 더 잘 방어될 수 있다.

SSH 연결을 위한 표준 포트가 22라는 사실은 모든 이가 알고 있다. 따라서 시스템의 보안을 더욱 강화하기 위해 취해야 할 첫 번째 단계는 그냥 포트를 사용하지 않는 포트로 변경하고 포트 번호도 22960과 같은 생소한 번호로 변경하는 것이다. 1024를 초과하는 번호는 보통 안전하지만, 발생 가능한 문제를 피하려면 참고자료를 확인한다. 이 변경은 단순히 이 명령행을 사용하여 컴퓨터에 연결해야 한다는 의미다.

ssh -p 22960 your.machine.url

이런 일종의 속임수를 적용하려면 /etc/ssh/sshd_config 파일에서 간단히 변경한다. 파일을 편집하고(이를 위해 루트로 작업해야 함), 포트 22라는 행을 찾고, 사용자가 선택한 것으로 번호를 변경한다(이 행이 파운드 기호[#]로 시작하기 때문에 주석 처리되는 경우 주석 처리 제거해야 함). 파일을 저장하고 /etc/init.d/sshd restart 명령으로 SSH를 다시 시작한다. 또한, 방화벽에서 선택한 포트를 열고 포트 22를 닫아야 한다.

그러나 훨씬 더 많은 일을 할 수 있다. 구성 파일에 목록 1에 표시된 행이 포함되도록 한다. 이들 행 중 몇 개는 이미 존재할 수 있지만, 주석 처리될 수 있다.


목록 1. SSH 구성 파일에서 몇 가지 내용을 변경하여 적은 비용으로 보안 강화
	
Port 22960 
LoginGraceTime 30 
MaxAuthTries 3 
Protocol 2 
PermitRootLogin no 

LoginGraceTime으로 로그인에 30초를 허용한다. 사용자가 로그인에 이보다 오래 걸리는 경우 그 사용자에게는 액세스가 허용되지 않으므로 다시 로그인해야 한다. MaxAuthTries는 사용자가 잘못된 로그인 시도를 3회까지만 할 수 있도록 한정하고, 그 후에는 로그인 시도가 거부된다. Protocol 2 행은 다소 약한 프로토콜을 사용하지 못하게 하는 역할을 한다. 최종적으로, 마지막 행은 누구도 루트로 로그인하지 못하게 하여, 해커가 침입하기 어렵게 만든다. 또한, 추가적인 제한을 위해 DenyUsers, AllowUsers, DenyGroupsAllowGroups 옵션을 사용할 수 있다. 이런 변경이 실질적으로 시스템의 보안을 강화시키지는 않지만, 표준 포트 22에서 무차별 암호 대입 공격을 시도하는 공통 스크립트가 아무런 해도 끼치지 않고 실패한다. 어떤 경우에도, 이것을 올바른 방향의 첫 단계로 간주한다. 이 기사를 계속 읽어나가면서 포트 번호를 변경할 뿐 아니라 완전히 숨기기 위한 훨씬 안전한 방법을 사용할 것이다.


들어갈 수 있는 사용자는?

대부분의 사람들은 PAM이라고 하면 캔에 들어 있는 요리용 기름을 떠올릴 것이다. 하지만 Linux® 보안의 관점에서 볼 때, PAM은 Pluggable Authentication Modules의 약자이다. 이 모듈은 시스템에 대한 액세스 보안을 강화하기 위한 추가적인 인증 규칙을 제공한다.

"도대체 왜 PAM을 사용하는가?"라는 기본적인 질문부터 시작해보자. 모든 프로그램이 고유의 인증 논리를 정의해야 했다면 무척 혼란스러웠을 것이다. 모든 애플리케이션에서 동일한 테스트와 검사를 구현했는지 어떻게 확신할 수 있을까? 추가적인 제어 장치가 필요하다면, 심지어 모든 것을 다시 프로그래밍해야 한다면 어떻게 할 것인가? 컴퓨터 과학에서는 추가 계층으로 모든 것을 해결할 수 있다고들 하며, 최소한 보안에 대해서라면 맞는 말이다. 프로그램에서 사용자를 인증할 필요가 있는 경우, PAM API를 호출할 수 있다. API는 PAM 구성 파일에서 지정했을 수 있는 모든 검사를 실행하는 일을 맡게 된다. PAM을 인식하는 모든 프로그램이 코드를 변경할 필요 없이 새 규칙을 적용하기 시작하기 때문에, 이 방법에서는 도중에 인증 규칙을 수정할 수도 있다. 생체 측정 검사(예: 홍채 스캐너 또는 지문 리더)를 사용하고 제조업체에서 PAM을 제공하는 경우, 준비는 끝났다. 구성 파일에 모듈 호출을 포함하면 모든 애플리케이션에서 장치를 사용할 수 있을 것이다.

PAM 구성

애플리케이션에서 이 모든 것을 요구하지는 않겠지만, PAM은 네 개의 별개 보안 영역을 제공한다. 예를 들어, passwd 명령에서는 아래 목록에서 세 번째 그룹만 필요하다.

  • account는 계정 제한 사항을 다룬다. 사용자가 유효한 경우, 사용자에게 허용되는 작업은 무엇인가?
  • auth는 예컨대 사용자 이름과 비밀번호를 입력하는 사용자 식별과 관계가 있다.
  • password는 새 비밀번호 설정과 같이 비밀번호와 관련된 기능에만 관계가 있다.
  • session은 로깅을 포함한 연결 관리 문제를 다룬다.

PAM을 사용하게 될 각 애플리케이션에 대해 /etc/pam.d 디렉토리에서 구성 파일을 만들어야 하고, 파일 이름은 애플리케이션의 이름과 동일할 것이다. 예를 들어, login 명령에 대한 구성 파일은 /etc/pam.d/login이 된다.

어떤 모듈이 적용될 것인지 정의하여 작업의 "스택"을 작성해야 한다. PAM은 적절한 스택에서 모든 모듈을 통해 실행되고, 그 결과에 따라 사용자의 요청을 허용하거나 거부한다. 검사가 필수 사항인지 여부도 정의해야 한다. 마지막으로, 다른 파일에서는 구체적인 규칙 없이 임의의 애플리케이션에 대한 기본 규칙을 제공한다.

  • optional 모듈은 성공하거나 실패할 수 있다. PAM은 어떤 모듈이 결국 성공할지 여부에 따라 success 또는 failure를 리턴한다.
  • required 모듈은 필수적이다. 실패 시, PAM은 failure를 리턴하지만 같은 스택에서 나머지 모듈을 실행한 후에만 그렇다.
  • requisite 모듈 역시 성공할 필요가 있다. 그러나 실패하는 경우, PAM은 다른 어떤 모듈도 실행하지 않고 즉시 failure를 리턴한다.
  • sufficient 모듈이 성공하면 다른 어떤 모듈도 실행하지 않고 PAM에서 즉시 success를 리턴한다.

구성 파일의 구조는 간단하다. 해시 문자(#)로 시작하는 주석을 포함하고 백슬래시(\)로 종료하여 긴 행을 계속한다. 행에는 영역(account, auth, password 또는 session), 제어 플래그(optional, required, requisite 또는 sufficient), 실행될 모듈에 대한 경로 및 가능한 매개변수의 세 가지 필드가 있다. 두 번째 필드는 더 복잡할 수 있다. 자세한 내용은 참고자료를 참조한다. 또한, auth include common-account에서와 같이, include 규칙을 사용하여 다른 파일의 규칙을 포함할 수 있다.

특수한 /etc/pam.d/other 파일은 고유의 특정 구성 파일 없이 애플리케이션에 규칙이 자동으로 적용되는 "기본" 구성 파일이다(목록 2 참조). 안전하게 하려면, (other 구성이 사용되도록) /etc/pam.d 파일을 빠르게 검토한 후 사용하지 않는 모든 구성 파일의 이름을 바꾼다. 실제로 애플리케이션이 필요하다고 결정하는 경우에는 그냥 구성 파일의 이름을 원래 이름으로 바꾼다. 기본 구성에서는 보통 (pam_deny.so 모듈을 사용하여) 모든 요구사항을 거부하고 관리자가 이 문제를 해결할 수 있도록 (pam_warn.so 모듈을 통해) 관리자에게 경고한다.

표준 "other" 구성 파일은 고유의 구성 파일 없이 모든 애플리케이션에 대한 보안 기본값(모든 것을 거부함)을 제공한다.


목록 2. 표준 "other" 구성 파일
	
account required pam_deny.so 
auth required pam_deny.so 
auth required pam_warn.so 
password required pam_deny.so 
password required pam_warn.so 
session required pam_deny.so 

pam_deny.sopam_unix.so로 바꾸면 표준 인증 방법(사용자 이름과 비밀번호 입력)이 적용된다. 마찬가지로, 보안에 대해 신경을 쓰지 않으면 어떤 요청이라도 기꺼이 허용하는 pam_permit.so를 대신 사용한다.

사용 가능한 몇 가지 모듈

표준 모듈 목록이 있지만, 모든 배포 버전에는 다음 옵션이 대부분 포함된다. 모듈이 있는 /lib/security 또는 /usr/lib/security 디렉토리를 확인한다. 64비트 운영 체제의 경우, liblib64로 바꾼다. 자세한 정보가 필요하면 man the.name.of.the.module을 사용할 수 있지만, 직접 실행하면 안 된다. PAM은 실행 가능한 2진 파일이 아니다.

  • pam_access는 /etc/security/access.conf 파일에 따라 액세스를 허용하거나 거부한다. 나중에 이 모듈을 사용하여 로그인이 허용되는 사용자를 결정할 것이다.
  • pam_cracklibpam_pwcheck은 보안 강화를 위해 가능한 새 비밀번호를 검사한다.
  • pam_denypam_permit이 기본이며, 항상 액세스를 거부 또는 허용한다.
  • pam_echo는 주어진 파일의 내용을 사용자에게 표시한다.
  • pam_lastlog는 사용자의 마지막 로그인 날짜와 시간을 표시한다.
  • 사용자는 pam_ldap.so를 사용하여 LDAP 서버에 대해 인증을 하여 네트워크 상에서 중앙 인증을 제공할 수 있다.
  • pam_limits 모듈을 사용하여 /etc/security/limits.conf 파일에 정의된 것과 같은 시스템 자원 제한을 지정할 수 있다.
  • 그러나 pam_listfile은 파일의 내용을 바탕으로 서비스를 허용하거나 거부하기 위한 다른 방법을 제공한다.
  • pam_mail은 사용자가 보류 중인 메일이 있는지 검사한다.
  • pam_motd는 사용자에게 "message of the day" 파일을 표시한다.
  • pam_nologin은 /etc/nologin이라는 이름의 파일이 있는 경우 모든 로그인을 차단한다.
  • pam_rootok은 더 이상의 검사 없이 루트 사용자에 대한 액세스를 허용한다. 이 모듈은 보통 /etc/pam.d/su에 포함되며, 필수 행은 auth sufficient pam_rootok.so이다. 비밀번호를 입력할 필요 없이 루트가 다른 사용자로 작용할 수 있다.
  • pam_succeed_if는 특정 그룹의 구성원이 되는 것과 같이, 원하는 특정 계정의 특성을 검사한다.
  • pam_time은 /etc/security/time.conf에 있는 규칙에 지정되어 있는 것처럼 서비스에 대한 액세스를 제한할 수 있다.
  • pam_unix(또는 pam_unix2)는 /etc/passwd 및 /etc/shadow 파일에 대해 고전적인 UNIX® 스타일의 인증 기능을 제공한다.
  • pam_userdb는 Berkeley 데이터베이스에 대한 인증 기능을 제공한다.
  • pam_warn은 시스템 로그에 정보를 기록한다.
  • pam_wheelwheel 그룹의 구성원에 대한 루트 액세스 권한을 제공할 뿐이다. 필수 행은 auth required pam_wheel.so이다.

다른 모듈에 대한 정보와 고유한 모듈의 작성에 대한 정보는 참고자료 섹션을 확인한다. 이제는 시스템에 로그인할 수 있는 사용자를 결정할 수 있도록 PAM을 사용한다.

PAM으로 액세스 제한

이제, PAM을 사용하여 서버에 연결을 허용할 사용자를 제한해보자. 목록 3과 같이 되도록 /etc/pam.d/sshd 파일을 편집해야 한다.


목록 3. sshd PAM 파일에 pam_access.so 추가
	
#%PAM-1.0 
account include common-account 
account required pam_access.so 
auth include common-auth 
auth required pam_nologin.so 
password include common-password 
session include common-session 

sshd PAM 파일에 pam_access.so를 추가하면 SSH를 사용하여 시스템에 연결할 수 있는 사용자를 손쉽게 정의할 수 있다. 목록 4에 나타낸 것처럼, pam_access.so 모듈은 /etc/security/access.conf 파일을 바탕으로 보안 제어를 구현한다.


목록 4. pam_access.so로 SSH를 사용할 수 있거나 없는 사용자를 정의할 수 있음
	
+ : ALL : 192.168.1. 
+ : jack : ALL 
+ : jill : ALL 
- : ALL : ALL 

첫 번째 행은 모든 이(ALL)가 내부 네트워크 내에서 로그인할 수 있게 해준다. 다음 두 행을 통해 사용자인 jackjill이 어느 위치에서든 서버에 액세스할 수 있도록 허용한다. 마지막 행은 "catch-all"로서, 다른 모든 이가 다른 모든 주소에서 액세스하는 것을 거부한다. 여러 사용자 액세스를 지원하는 다른 방법은 pam_listfile.so를 사용하여 승인된 사용자 목록(예: /etc/ssh_users)을 작성하는 것이다. /etc/pam.d/sshd 파일에 다음 행을 추가한다.

auth required pam_listfile.so item=user sense=allow 
   file=/etc/ssh_users onerr=fail

아직 끝난 것이 아니다. /etc/ssh/sshd_config 파일에서 PAM을 사용하도록 이 파일을 더 수정해야 한다. 파일에 UsePAM yes 행을 추가하고 sshd 디먼을 다시 시작해야 끝나는 것이다.


정말 도어가 있는 것인가?

이전 섹션에서 모두 적당한 방법을 사용했지만, 해커들은 어떤 예방 조처를 취해놓았다 해도 시스템에서 어디든 열린 도어를 통해 침입하려고 수단과 방법을 가리지 않을 것이라 생각해야 한다. SSH 포트 번호를 변경하는 것은 충분한 지식을 갖춘 예비 침입자에게는 약간 귀찮은 일이 될 뿐이며, 사용자에 대한 제한도 도움이 된다(비밀번호가 노출되는 해킹 또는 소셜 엔지니어링 공격에 당하는 사용자가 없는 경우). 하지만, 시스템에 도어가 있다는 단순한 사실이 해커들을 유혹하기에는 충분하다.

시스템에 보안을 추가하기 위한 마지막 스킴이 가장 대담한 것이라 할 수 있다. 열린 포트를 닫아 사실상 어떤 공격에도 시스템을 난공불락으로 만들 것이다. 사용자가 비밀번호를 입력하여 시스템에 대한 액세스 권한을 얻을 수 있도록 필요한 포트를 여는 "시크릿 노크"를 제공할 수 있는 사용자에게만 포트를 열어준다.

포트 노킹이라는 이 기술은 공용 사용자는 사용할 수 없는 서버에 대한 액세스 권한이 필요한 사용자에게 적당하다. 사용자가 시크릿 노크 시퀀스(시퀀스는 구현하기 쉽고 적당한 자원이 필요함)를 제공할 때까지 서버는 모든 포트를 닫은 상태로 유지할 수 있다.

시크릿 포트가 열릴 때, 통상적인 보안 메커니즘(예: 비밀번호 또는 인증서)이 적용될 것이다. 시크릿 포트가 필요한 모든 서비스는 방화벽 레벨에서 제공되는 추가적인 보안 계층에서 올바로 작동할 것이다.

이 방법의 핵심은 모든 포트를 닫고 외부의 연결 시도를 모니터하는 것이다. 미리 정의된 특정한 연결 시도 시퀀스(노크 시퀀스라고 함)가 인식될 때마다, 외부인이 들어올 수 있도록 포트 열기와 같은 작업을 실행할 수 있다. 노크 시퀀스는 간단한 목록(예: TCP 포트 7000, UDP 포트 7100, TCP 포트 7200 사용)부터 일회용으로만 사용되는 시퀀스 콜렉션까지, 사용자가 원하는 만큼 복잡해질 수 있다. (암호화의 관점에서 이 개념은 알려진 것 중 가장 안전한 암호화 방법인 "일회용 암호"와 유사하다. 외부인이 SSH를 사용하려면 포트 번호와 비밀번호를 알아야 할 뿐 아니라, 그 포트를 열고 비밀번호를 사용하는 데 필요한 노크 시퀀스도 알아야 한다. 시퀀스가 맞지 않으면 연결 시도가 그냥 자동으로 실패한다.

이것이 훌륭한 안전판 역할을 하는 이유는 무엇일까? 그것은 바로 가능한 포트 수가 65,535개나 되기 때문이다(참고자료 참조). 포트가 이미 지정되어 있다고 생각할지라도, 여전히 60,000여 개의 사용 가능한 포트가 남아 있다. 시퀀스의 길이가 네 번의 "노크"일 뿐이라고 결정하는 경우, 무차별 암호 대입으로 추측해보려는 해커라면 무려 약 1,300경 가지(13 뒤에 0이 18개나 붙는 큰 수)의 가능한 시퀀스를 테스트해야 한다. 그런 무모한 공격이 성공할 리 없다는 점은 너무나 명백하다. 물론, 무차별 암호 대입 또는 완전히 운으로 맞추는 방법이 올바른 시퀀스를 추측할 수 있는 유일한 방법이라 생각해서는 안 된다. 그것이 바로 단일 보안 방법을 사용하지 않고, 일련의 보안 계층을 마련하여 해커가 추측하기 힘들게 만드는 이유이다.

knockd 노킹 디먼을 설치해야 한다. 이 디먼은 노크 시퀀스를 모니터하고 유효한 노크 시퀀스를 발견하는 역할을 한다. 원한다면, 소스에서 이것을 빌드할 수 있겠지만, 이 패키지는 대부분의(전부가 아닌 경우) 배포 버전에서 제공되므로 패키지 관리 도구를 사용하는 것이 더 낫다. 예를 들어, OpenSUSE에서는 Yast2를 사용하거나 sudo zypper install knockd를 실행하여 이 디먼을 설치할 수 있다. 이와 유사하게, Ubuntu에서는 sudo apt-get install knockd를, Debian에서는 sudo aptitude install knockd를 사용할 수 있다. 배포 버전의 소프트웨어 설치 도구에서 knockd를 검색하기만 하면 준비가 끝난다.

패키지를 설치한 후, /etc/knockd.conf 파일을 편집하여 포트 노킹 규칙을 지정하고 디먼 실행을 시작해야 한다. 필수 설정 작업을 위해 방화벽이 어떻게 작동하는지 알고 있어야 한다. 예를 들어, OpenSUSE에서는 목록 5에 나타낸 설정과 같은 것을 사용할 수 있다.


목록 5. OpenSUSE 방화벽용으로 디자인된 샘플 구성 파일
	
[opencloseSSH] 
  sequence= 7000,8000,9000 
  tcpflags= syn 
  seq_timeout= 15 
  cmd_timeout= 30 
  start_command= /usr/sbin/iptables -s %IP% -I input_ext 1 -p tcp --dport 22960 -j ACCEPT 
  stop_command= /usr/sbin/iptables -s %IP% -D input_ext -p tcp --dport 22960 -j ACCEPT 

위 샘플에서는 각각 포트 7000, 8000 및 9000에서 연속으로 노크가 발생한 후 SSH 액세스가 지원된다.

knockd를 시작하기 전에 포트 22960을 닫고 원격으로 로그인한다. 아래 목록 6에 표시된 것처럼, 이 시도는 실패로 돌아간다.


목록 6. SSH 액세스를 종료하고 노크 디먼을 시작하지 않으면 로그인 시도가 그냥 실패로 돌아간다.
	
> ssh the.url.for.your.site -p 22960 -o ConnectTimeout=15 
ssh: connect to host the.url.for.your.site port 22960: Connection timed out 

이제는 결국 같은 명령인 sudo /etc/init.d/knockd start 또는 sudo knockd -d를 사용하여 포트 노킹 디먼을 시작한 후 다시 시도해보자. 포트 열기 시퀀스에서는 포트 7000, 8000 및 9000에서 노킹이 필요하다. 이 시퀀스를 15초 내에 완료해야 한다. 인식 후 포트가 열리면, 30초 내에 로그인해야 한다. 그렇지 않으면, 포트가 다시 닫힐 것이다.

이 프로세스를 확인하려면 원격 시스템으로 다시 돌아가서 로그인한다. 이때는 목록 7에 나타낸 것처럼 필수 노크를 제공한다. knock 명령은 보통 knockd를 가져올 때 설치된다. 그렇지 않으면, 그냥 배포된 소프트웨어의 패키지 관리 도구를 사용하여 찾아본다.


목록 7. 필요한 노크 시퀀스를 제공한 후 성공한 로그인
	
> knock the.url.for.your.site 7000 
> knock the.url.for.your.site 8000 
> knock the.url.for.your.site 9000 
> ssh the.url.for.your.site -p 22960 -o ConnectTimeout=10 
Password: 

잘못된 노크 시퀀스를 제공했거나 전혀 아무런 노크도 제공하지 않은 경우에는 "Connection timed out" 메시지가 표시되고 SSH 포트가 존재한다는 아무런 조짐도 없이 완전히 닫힌 상태로 남게 된다.

라우터 뒤에 있는 경우

서버가 라우터를 통해 인터넷에 연결되어 있는 경우, 라우터의 구성을 약간 변경해야 한다. 세부사항은 라우터 및 방화벽마다 다르지만, 일반적으로는 다음 작업을 수행해야 한다.

  • knockd가 노크 포트를 인식하여 처리할 수 있도록 노크 포트를 열어 시스템으로 전달한다.
  • 포트 22960(SSH 연결을 위해 사용 중인 포트)을 시스템 상의 포트 22960으로 전달한다.
  • 포트 22960과 노크 포트에 대한 연결을 거부하도록 시스템 방화벽을 구성한다.

라우터의 일부 포트가 열리더라도, 이들 포트에 대한 모든 액세스는 시스템의 방화벽으로 안내된다. 정확한 포트 노크 시퀀스가 분명히 발견되지 않는 한, 액세스가 차단된다.

노크 구성

/etc/knockd.conf 파일에는 일반적인 옵션 섹션인 options와 사용하려는 각 노크 시퀀스에 대한 섹션이 있다. 옵션을 대문자, 소문자 또는 이 둘을 혼합한 형식으로 쓸 수 있다.

  • 표준 기능으로서, knockd는 eth0 인터페이스를 모니터한다. 다른 인터페이스(예: eth1)로 작업하려면 Interface=eth1 행을 포함하면 된다. 전체 경로가 아니라 그냥 장치 이름만 포함한다.
  • 로깅을 사용하려면 useSyslog 행을 포함하여 표준 Linux 로그 파일을 선택하거나 LogFile=/the/full/path/to/your/file을 포함하여 고유의 특정 파일을 사용할 수 있다. 하지만, 로깅이 약점임을 인식해야 한다. 해커가 로그를 손대는 경우 그 침입자는 포트 노킹 시퀀스를 손쉽게 손에 넣게 된다.
  • knockd가 여전히 실행 중인지 검사할 수 있게 하려면 PidFile=/the/full/path/to/a/PID/file을 포함한다. 그러면 디먼의 프로세스 ID(PID)가 이 파일에 저장될 것이다. 필요한 경우, knockd가 여전히 작동 중이고 이를 다시 시작하는지 주기적으로 검사하는 cron 작업이 있어야 한다. 충돌이 발생하는 경우에도 시스템은 안전할 것이다. 모든 포트가 닫혀 액세스할 수 없게 되기 때문이다. 하지만, 디먼이 다시 실행되기 시작할 때까지는 로그인할 수 없을 것이다.

knockd가 여러 시퀀스를 수신 대기하고 각 시퀀스에 대해 다른 방식으로 반응하도록 할 수 있다. 이전 예제에서는 knockd가 SSH 포트를 열도록 했고 그냥 손쉽게 HTTP 포트를 사용할 수 있었으므로, 웹 서버에 액세스할 수 있거나 웹 서버가 특정 프로세스를 실행한다. 각 시퀀스에 대한 구성 파일에 섹션이 있을 것이다.

  • 7000,8000,9000에서와 같이, sequence를 사용하여 노크 시퀀스를 정의한다. 기본적으로 노크는 TCP를 사용하지만, 7000,8000:udp,9000에서와 같이 UDP를 추가하여 좀 더 혼합할 수 있다.
  • 단일 혼합 시퀀스를 두는 것에 대한 대안으로서, 사용된 후 지워져 다시 사용할 수 없는 "일회용 시퀀스"로 파일을 지정할 수 있다. 그런 시퀀스를 지정하려면 다음을 사용한다.
    one_time_sequences=/the/full/path/to/a/sequences/file
    

    텍스트 편집기를 사용하여 파일을 작성한다. 파일의 각 행에는 (위에 표시된 형식의) 시퀀스가 있어야 한다. 로그인 방법을 기억할 수 있도록 원격 시스템에 이 파일의 사본이 있어야 한다.

  • 스캔하여 ACK, FIN, PSH, RST, SYN 또는 URG 플래그와 일치하지 않는 것은 버릴 수신 TCP 패킷을 지정할 수 있다. SSH 연결에서는 TCPFlags=SYN을 사용해야 한다.
  • Seq_Timeout=seconds.to.wait로 시퀀스를 완료하기 위한 최대 시간을 정의할 수 있다. 이때 완전한 시퀀스가 입력되지 않으면 인식되지 않아 액세스 권한이 부여되지 않는다.
  • 유사한 방법으로, Cmd_Timeout=seconds.to.wait로 시퀀스가 인식된 후 사용자가 두 번째 명령을 실행하기 위한 최대 시간을 설정할 수 있다. 노크 시퀀스를 제공한 사용자가 빠르게 행동(예: 로그인)하지 않으면 포트가 다시 닫힌다.
  • 가장 중요한 매개변수 하나는 Start_command=some.command.to.execute로서, 이 매개변수는 정확한 노크 시퀀스가 인식된 후 실행할 명령 또는 스크립트를 지정한다. (예를 들어, 노커의 시스템에서 사용자의 시스템으로의 연결을 허용하기 위해) 노커의 IP 주소를 참조할 필요가 있는 경우, %IP%를 사용할 수 있다. 그러면 실행 시간에 이것이 올바른 값으로 바뀐다. 위 예제에서는 다음과 같이 썼다.
    /usr/sbin/iptables -s %IP% -I input_ext 1 -p tcp --dport 22960 -j ACCEPT
    

    iptables는 노크 시퀀스가 온 곳의 IP 주소에서 자동으로 포트 22960을 연다.

  • 다른 중요한 매개변수인 Stop_command=some.command.to.executeCmd_timeout 시간이 경과한 후에 실행된다.

이 경우에는 단지 포트 22960을 열거나 닫으려고 했기 때문에, 단일 명령만으로 충분했다. 사용자의 요구가 더 복잡한 경우에는 포트 열기와는 전혀 관계가 없더라도 스크립트를 호출하여 원하는 작업을 무엇이든 할 수 있다. 프로세스 실행 또는 백업 수행과 같은 작업을 트리거할 수 있다. 물론, 어떤 명령을 사용할지 알기 어려울 수 있다. 예를 들어, OpenSUSE를 실행 중이었고 OpenSUSE는 고유의 방화벽 프론트엔드를 제공하기 때문에, iptables -l의 출력을 검사하여 포트 22960을 열거나 닫으려면 어떤 명령을 입력해야 할지 파악해야 했다.

knockd 자체에 관하여 고려할 옵션은 몇 가지 되지 않는다.

  • -c: 기본값인 /etc/knockd.conf 이외의 구성 파일을 지정할 수 있다.
  • -d: knockd가 백그라운드 디먼으로 실행되도록 만들며, 이는 knockd를 실행하기 위한 기본적인 방법이다.
  • -D: 출력 디버깅 메시지를 제공한다.
  • -h: 구문과 옵션에 대한 도움말을 제공한다.
  • -i: 기본값인 eth0에서 보기 위한 인터페이스를 변경할 수 있다.
  • -l: 로그 항목에 대한 DNS 검색을 사용한다. 시스템에서 DNS 트래픽을 사용하도록 강제 실행하는 상황에서는 은밀성을 잃게 되므로 나쁜 방법이다.
  • -v: 더 자세한 메시지와 설명을 제공한다.
  • -V: 프로그램의 버전 번호를 표시한다.

마지막으로, 노크 시퀀스 자체를 만들기 위해 많은 방법을 사용할 수 있겠지만, knock를 프로그래밍하는 것이 가장 간단한 방법이다.

방법은 간단하다.

knock the.url.for.your.site 7000

위는 TCP 포트 7000을 노킹하는 방법이다.

knock the.url.for.your.site -u 8000

또는

knock the.url.for.your.site 8000:udp

위는 UDP 포트 8000을 노킹하는 방법이다. -h 매개변수를 사용하면 이 명령에 대한 도움말이 제공된다.


결론

시스템에 대한 SSH 액세스 보안을 강화하는 세 가지 방법, 즉 sshd 구성 매개변수를 수정하거나, PAM을 사용하여 로그인할 수 있는 사용자를 선택하거나, 포트 노킹 시퀀스를 사용하여 SSH 액세스의 존재를 숨기는 방법을 살펴보았다. 어떤 시스템이든 완벽히 보안을 유지할 방법은 없다고 말했지만, 이 세 가지 계층을 추가하면 약간 더 안전한 수준을 훨씬 뛰어넘어 서버를 매우 안전하게 보호할 수 있을 것이다.


참고자료

교육

제품 및 기술 얻기

  • knock and knockd: 이들 디먼을 다운로드하여 전체 문서를 살펴보자.

  • PAM: 주 PAM 사이트에서 더 자세히 알아볼 수 있다.

  • SSH protocols: SSH 프로토콜, 특히 IETF RFC 4252를 구할 수 있다.

토론

필자소개

Photo of Federico Kereki developerWorks Contributing author level

Federico Kereki はウルグアイ人のシステム・エンジニアであり、システム開発やコンサルティング、大学での教育に 20 年を超える経験があります。現在はおなじみの頭字語、SOA、GWT、Ajax、PHP、そしてもちろん FLOSS を渾然一体に扱いながら業務を行っています。

잘못된 도움말 신고

부정사용 신고

감사합니다. 이 항목은 운영자가 관심을 표시했습니다.


잘못된 도움말 신고

부정사용 신고

제출실패 신고. 나중에 다시 실행해주세요.


디벨로퍼웍스 로그인


IBM ID가 필요하세요?
IBM ID를 잊으셨습니까?


비밀번호를 잊으셨습니까?
비밀번호 변경

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

화면상에 보여지는 닉네임을 정하세요.

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

3개의 &이나 대쉬를 포함해주시고 31글자내로 제한해주세요.


developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


아티클 순위

의견

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=20
Zone=AIX와 UNIX
ArticleID=600276
ArticleTitle=SSH 도어를 위한 세 가지 잠금 장치
publish-date=08312010
author1-email=fkereki@gmail.com
author1-email-cc=

태그

Help
검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오.

태그를 더 많이 보거나 적게 보기 위해 슬라이더 막대를 사용하십시오.

인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다.

내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.

검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오. 인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다. 내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.