port knocking을 이용한 고급 기술 구현
작성자 정보
- 관리자 작성
- 작성일
컨텐츠 정보
- 1,037 조회
- 0 추천
- 목록
본문
port knocking을 이용한 고급 기술 구현
iptables의 recent 모듈을 이용하면 port knocking이라는 기술을 구현할 수 있다.
port knocking을 우리말로 해석하자면 “포트 두드리기” 정도가 될 텐데, 이는 특정한 조건이 충족될 때에만 포트가 dynamic하게 오픈된다는 특징을 가지고 있다.
이 기술은 recent 모듈을 이용하여 구현할 수 있는데, iptables의 확장 기능인 recent는 최근 버전에서는 기본적으로 제공하고 있으나 구버전에서는 p-o-m 패치를 하여야 이용할 수 있는데, recent 모듈의 기능과 특징에 대해서는 아래 URL을 참고하기 바란다.
http://www.iptables.org/documentation/HOWTO//netfilter-extensions-HOWTO-3.html#ss3.16
recent가 제공하는 옵션은 다음과 같다.
--name : 명령어에 대한 목록을 정의하며 별도로 정의하지 않으면 DEFAULT가 사용된다.
--set : 목록에 소스IP를 추가한다.
만약 IP가 있으면 업데이트를 한다.
--rcheck : 목록에 소스IP가 있는지 확인한다.
--update : 목록에 소스IP가 있는지 확인 후 있으면 업데이트한다.
--remove : 목록에 소스IP가 있는지 확인 후 있으면 삭제한다.
--seconds xxx : rcheck나 update와만 사용되며 룰에 매칭될 경우 해당 초동안 적용된다.
--hitcount hits : rcheck나 update와만 사용되며 해당 수치이상의 패킷을 수신할 경우 적용된다.
이를 활용하여 다음과 같은 룰을 만들어보자. 편의상 각 룰에 번호를 할당하였다.
HOST_IP="12.34.56.78" 1) iptables -N INTO-PHASE2 iptables -A INTO-PHASE2 -m recent --name PHASE1 --remove iptables -A INTO-PHASE2 -m recent --name PHASE2 --set iptables -A INTO-PHASE2 -j LOG --log-prefix "INTO PHASE2: " 2) iptables -N INTO-PHASE3 iptables -A INTO-PHASE3 -m recent --name PHASE2 --remove iptables -A INTO-PHASE3 -m recent --name PHASE3 --set iptables -A INTO-PHASE3 -j LOG --log-prefix "INTO PHASE3: " 3) iptables -N INTO-PHASE4 iptables -A INTO-PHASE4 -m recent --name PHASE3 --remove iptables -A INTO-PHASE4 -m recent --name PHASE4 --set iptables -A INTO-PHASE4 -j LOG --log-prefix "INTO PHASE4: " 4) iptables -A INPUT -m recent --update --name PHASE1 iptables -A INPUT -p tcp --dport 100 -m recent --set --name PHASE1 iptables -A INPUT -p tcp --dport 200 -m recent --rcheck --name PHASE1 -j INTO-PHASE2 iptables -A INPUT -p tcp --dport 300 -m recent --rcheck --name PHASE2 -j INTO-PHASE3 iptables -A INPUT -p tcp --dport 400 -m recent --rcheck --name PHASE3 -j INTO-PHASE4
iptables -A INPUT -p tcp -s $HOST_IP --dport 22 -m recent --rcheck --seconds 5 --name PHASE4 -j ACCEPT 5) iptables -A INPUT -p tcp -s 192.168.1.1 --dport 22 -j ACCEPT iptables -A INPUT -p tcp -s 0/0 --dport 22 -j DROP
|
위의 룰은 상당히 복잡해 보이는데, 해당 서버에 대해 100/tcp, 200/tcp, 300/tcp, 400/tcp를 순차적으로 접속한 IP에 대해서만 dynamic하게 ssh(22/tcp) 접속을 허용하는 예이다.
다음과 같이 5개의 그룹으로 설정된 룰이 있다고 가정하자. 먼저 4)번 룰부터 살펴보자.
iptables -A INPUT -p tcp --dport 100 -m recent --set --name PHASE1
이는 100/tcp로 패킷이 들어오면 해당 소스IP에 대해 PHASE1에 입력한다.
iptables -A INPUT -p tcp --dport 200 -m recent --rcheck --name PHASE1 -j INTO-PHASE2
그 다음 룰은, 어떤 소스IP에서 200/tcp로 패킷이 들어오면 PHASE1에 그 IP가 있는지 확인 후 있으면 INTO-PHASE2 chain으로 보내게 된다.
INTO-PHASE2 chain은 (1)번 룰에 해당하는데, 이 룰의 의미는 먼저 INTO-PHASE2를 생성 후, PHASE1 에 해당 소스IP가 있으면 삭제하고, PHASE2에 소스IP를 추가한다는 의미이다.
다시 4)번 룰로 돌아와 300/tcp, 400/tcp도 마찬가지로 진행하게 된다.
결국 PHASE4는 PHASE1~3까지 모두 통과한 패킷 즉, 100,200,300,400을 순서대로 요청한 패킷이 되며 따라서 아래의 마지막 룰은 소스IP가 $HOST_IP인 접속에 대해 22/tcp에 대해 5초안에 PHASE4에 보이는 경우에만 접속을 허용한다는 의미가 된다.
iptables -A INPUT -p tcp -s $HOST_IP --dport 22 -m recent --rcheck --seconds 5 --name PHASE4 -j ACCEPT
만약, IP에 관계없이 순차적으로 100부터 400까지 접속한 IP에 대해서만 허용하려면 -s $HOST_IP 부분을 빼면 된다.
그리고 5)와 같이 설정해 주어야 실제 다른 IP는 접속이 차단되므로 주의하기 바란다.
그렇다면 이처럼 복잡하게 하지 않고, 22/tcp 접속 시 ping을 받은 ip에 대해서만 dynamic하게 허용하려면 어떻게 하여야 할까? 아래와 같이 아주 간단하게 설정할 수 있다.
iptables -A INPUT -p icmp --icmp-type echo-request -m recent --set --name PING iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name PING -j ACCEPT iptables -A INPUT -p tcp -s 0/0 --dport 22 -j DROP |
이처럼 port knocking을 활용하면 사전에 정의된 룰(ssh 접속을 하기 전에는 5초안에 ping을 시도해야 하는 등)을 아는 유저만 접속할 수 있으므로 유동IP를 사용하는 환경에서도 안전하게 접근을 허용할 수 있다는 장점이 있다.
관련자료
-
이전
-
다음