본문으로 바로가기

안녕하세요, SATAz입니다.

IPTables에 대해서 소개를 드린지 열세 번째 포스팅입니다.



지난 포스팅은 IPTables의 GeoIP 모듈(매치)을 설치하는 내용을 다루었습니다.

이번 포스팅은 IPTables의 GeoIP를 사용하는 방법에 대해서 다루려고 합니다.

 



▣주의!!! : 이 블로그에 작성된 IPTables 포스팅들은 교육용으로 작성된 내용입니다. 

 서비스 중인 서버에 아래의 내용만 갖고 바로 적용하지 마시고, 서버에 적용 전에 반드시 테스트를 거치시기 바랍니다.  IPTables도 방화벽인지라, 무턱대고 서버에 적용했다가는 서비스 중단되는 사태가 발생할 수 있습니다. 필히 주의하셔야합니다!!!


#IPTables 설정를 위한 환경


- 테스트 머신 : VMware WorkStation 12 Player

- 운영체제 : CentOS/RHEL 7 - 64bit ( Minimal 설치 )

- 메모리 : 2GB

- IPTables Version : iptables v1.4.21

- 서버 아이피 : 192.168.0.18



1. IPTables의 GeoIP 관련 명령어 예시


# 중국을 차단하는 명령어 - 80 서비스만

iptables -I INPUT -p tcp -d 192.168.0.18 --dport 80 -m geoip --src-cc CN -j DROP


첫 번째 예시는 192.168.0.18서버의 80포트로, 중국에서 접근하는 모든 TCP패킷들은 차단하겠다는 의미입니다.


# 미국을 차단하는 명령어 - 모든 포트를 차단

iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip --src-cc US -j DROP


두 번째 예시는 192.168.0.18서버로오는, 미국에서 오는 모든 TCP패킷들은 차단하겠다는 의미입니다.


# 대한민국을 제외하고 모든 국가를 차단하는 명령어 - 모든 포트를 차단

iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip ! --src-cc KR -j DROP


세 번째 예시는 192.168.0.18서버로 오는, 대한민국을 제외한 모든 국가에서 오는 TCP패킷들을 차단하겠다는 의미입니다.


자세히 살펴보시면 1,2번째 예시와 3번째 예시가 다른 점이 있습니다.

바로 "--src-cc" 앞에 !가 붙었다는 점인데요, !(느낌표)는 개발 언어에서도 "~가 아닌"의미를 가진 특수문자입니다.


IPTables에서도 마찬가지로 느낌표(!)는 "~가 아닌 것"을 의미합니다.

따라서, 대한민국이 아닌 것들에 대해서 DROP을 한다는 의미가 되겠죠.


▣주의!!! : "! --src-cc KR" 설정은 사설아이피의 통신마저 차단되기 때문에, 굉장히 신중하셔야 합니다.

사설 아이피로 NAT를 구성하셔서 서비스하시는 분들은, 사설아이피 통신이 가능하도록 미리 조치하셔야 합니다.


명령어의 적용을 한번 살펴보겠습니다.


# 명령어의 적용

######### 첫 번째 예시의 적용 #########

[root@localhost ~]# 

[root@localhost ~]# iptables -I INPUT -p tcp -d 192.168.0.18 --dport 80 -m geoip --src-cc CN -j DROP

[root@localhost ~]# iptables -nL

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

DROP       tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80 -m geoip --source-country CN 

ACCEPT     tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80

ACCEPT     all  --  0.0.0.0/0            192.168.0.18         state RELATED,ESTABLISHED

ACCEPT     tcp  --  192.168.0.2          192.168.0.18         tcp dpt:22

ACCEPT     all  --  192.168.0.1          192.168.0.18        

ACCEPT     all  --  8.8.8.8              192.168.0.18        

DROP       all  --  0.0.0.0/0            192.168.0.18        


Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         


Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination         


######### 두 번째 예시의 적용 #########

[root@localhost ~]# iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip --src-cc US -j DROP

[root@localhost ~]# iptables -nL

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

DROP       tcp  --  0.0.0.0/0            192.168.0.18         -m geoip --source-country US 

ACCEPT     tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80

ACCEPT     all  --  0.0.0.0/0            192.168.0.18         state RELATED,ESTABLISHED

ACCEPT     tcp  --  192.168.0.2          192.168.0.18         tcp dpt:22

ACCEPT     all  --  192.168.0.1          192.168.0.18        

ACCEPT     all  --  8.8.8.8              192.168.0.18        

DROP       all  --  0.0.0.0/0            192.168.0.18        


Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         


Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination    


######### 세 번째 예시의 적용 #########

[root@localhost ~]# iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip ! --src-cc KR -j DROP

[root@localhost ~]# iptables -nL

Chain INPUT (policy ACCEPT)

target     prot opt source               destination           

DROP       tcp  --  0.0.0.0/0            192.168.0.18         -m geoip ! --source-country KR 

ACCEPT     tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80

ACCEPT     all  --  0.0.0.0/0            192.168.0.18         state RELATED,ESTABLISHED

ACCEPT     tcp  --  192.168.0.2          192.168.0.18         tcp dpt:22

ACCEPT     all  --  192.168.0.1          192.168.0.18        

ACCEPT     all  --  8.8.8.8              192.168.0.18        

DROP       all  --  0.0.0.0/0            192.168.0.18        


Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         


Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination


저는 이 명령어를 입력하면서, 사설아이피의 통신이 차단되면스 ssh접속이 끊겼습니다.

위의 주의에도 적어두었듯이, 사설아이피로 NAT를 구성하셔서 서비스하시는 분들은 각별한 주의가 필요합니다.



2. 국가를 차단시켰는데, 해당 국가의 특정 아이피만 허용하고 싶은 경우는 어떻게?

물론 특정 국가를 차단시키는데, 그 국가에서 특정 아이피는 반드시 통신이 되어야 하는 상황이 발생할 수 있습니다.

뭐... Google API를 이용해야하는데 해외 서버로 통신을 하는 경우도 있을 수 있고....

차단시킨 국가로 서버 관리자가 출장을 가서 원격 접속을 해야할 수도 있는 등... 

다양한 상황이 발생할 수 있겠습니다.


그럴 경우, DROP 정책 위에 허용하고자 하는 아이피를 추가하시면 됩니다.

위에 있는 룰(Rule)이 우선순위가 높기 때문에 가능합니다.


미국의 아이피가 1.1.1.1이고, 그 아이피를 허용한다는 가정으로 명령어를 작성하겠습니다.


# 미국 차단 위에, 특정 아이피 허용하기

iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip --src-cc US -j DROP

iptables -I INPUT -p tcp -s 1.1.1.1 -d 192.168.0.18 -j ACCEPT


# 명령어의 적용

[root@localhost ~]# iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip --src-cc US -j DROP

[root@localhost ~]# iptables -I INPUT -p tcp -s 1.1.1.1 -d 192.168.0.18 -j ACCEPT

[root@localhost ~]# 

[root@localhost ~]# iptables -nL

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     tcp  --  1.1.1.1              192.168.0.18        

DROP       tcp  --  0.0.0.0/0            192.168.0.18         -m geoip --source-country US 

ACCEPT     tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80

ACCEPT     all  --  0.0.0.0/0            192.168.0.18         state RELATED,ESTABLISHED

ACCEPT     tcp  --  192.168.0.2          192.168.0.18         tcp dpt:22

ACCEPT     all  --  192.168.0.1          192.168.0.18        

ACCEPT     all  --  8.8.8.8              192.168.0.18        

DROP       all  --  0.0.0.0/0            192.168.0.18        


Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         


Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination 



3. 국가를 차단하고자 한다면, 룰의 순서를 조심하자

IPTables 정책 룰은 Top to bottom 방식이기 때문에, 위에 있는 Rule이 우선순위를 갖게 됩니다.

만약, 외국 아이피들을 차단하고 그 위에 전체 80포트 전체허용을 적용하게 되면 어떻게 될까요?


# 상황 예제 1 - 국가정책 위에 전체허용

[root@localhost ~]# iptables -I INPUT -p tcp -d 192.168.0.18 -m geoip ! --src-cc KR -j DROP

[root@localhost ~]# iptables -I INPUT -p tcp -d 192.168.0.18 --dport 80 -j ACCEPT

[root@localhost ~]# iptables -nL

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80   

DROP       tcp  --  0.0.0.0/0            192.168.0.18         -m geoip ! --source-country KR 

ACCEPT     tcp  --  0.0.0.0/0            192.168.0.18         tcp dpt:80

ACCEPT     all  --  0.0.0.0/0            192.168.0.18         state RELATED,ESTABLISHED

ACCEPT     tcp  --  192.168.0.2          192.168.0.18         tcp dpt:22

ACCEPT     all  --  192.168.0.1          192.168.0.18        

ACCEPT     all  --  8.8.8.8              192.168.0.18        

DROP       all  --  0.0.0.0/0            192.168.0.18        


Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         


Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination    


위의 iptables 정책을 보시면, 80포트 허용정책이 외국 차단 정책보다 위에 있는 것을 확인하실 수 있습니다.

결론부터 말씀드리자면 외국에서도 80(웹서비스) 접속이 가능하게 됩니다.


그 이유를 말씀드리면 KR 외의 모든 국가를 차단하도록 해두었는데, 

상단에 있는 Rule이 우선순위를 가지면서 그 위에 있는 80포트에 대해서는 모든 접근을 허용되었기 때문입니다.

만약에 80포트가 아니라, 모든 서비스까지 전체 ACCEPT가 된다면... 외국의 모든 아이피도 모든 접근이 허용된다는 것을 인지하셔야 합니다.


그렇기 때문에, IPTables에서는 Rule의 순서가 상당히 중요합니다.



3. GeoIP의 활용 범위

GeoIP는 국가별로 패킷들을 차단할 수 있는 기능을 지원합니다. 따라서, 아래의 경우에 사용될 수 있습니다.

1) 불특정 다수의 아이피가 SSH Brute Force 공격을 시도하고있는데, 특정 국가의 아이피들만 들어올 경우에 차단할 때 쓰입니다.

2) 불특정 다수의 아이피가 DDOS 공격을 시도하고 있는데, 특정 국가의 아이피들만 들어올 경우 차단할 때 쓰입니다.

3) 불특정 다수의 아이피가 해킹을 시도하고 있는데, 특정 국가의 아이피들만 들어올 경우 차단할 때 쓰입니다.

4) 국내에서만 서비스를 하고 싶을 때, 사용할 수 있습니다.


그 특징 그대로, 상황에 맞게 사용된다고 보시면 됩니다 ^^



4. GeoIP에서 아쉬운점...

1) GeoIP는 국가별 패킷 필터링에 충실한 매치입니다. 하지만 그 아이피 목록의 정확성은 90%정도가 된다고 합니다. 100%는 아닌점이 상당히 아쉽습니다.

2) 국가별 아이피 목록은 항상 업데이트가 됩니다. 한개의 아이피를 가지고도, 이나라 저나라에서 바꿔가면서 쓴다는 의미입니다. 주기적으로 "GeoIPCountryWhois.csv" 파일을 받아서, 국가별 목록을 업데이트해주셔야 합니다.

(물론 자동 업데이트 스크립트를 만들어서 crontab에다가 걸어두면 편하실 것입니다)



이렇게 GeoIP의 사용법에 대해서 알아보았습니다.

다음 포스팅부터는 IPTables로 NAT를 다뤄볼까........도 생각중입니다만..... 데스크탑 컴퓨터의 VM머신을 어떻게 구성해야하는지 고민하고 있습니다...

긴 글 읽어주셔서 감사합니다 ^^




댓글을 달아 주세요

  1. 늑대와춤을 2018.06.22 18:12

    순서대로 따라하다가 룰을 추가하면, iptables: No chain/target/match by that name. 라는 메시지가 표시됩니다.

    추가한 룰입니다.
    iptables -I INPUT -p tcp -d 192.168.0.18 --dport 80 -m geoip --src-cc CN -j DROP

    구글에서 검색을 해도 해결이 안되서 글 남겨 봅니다.

    • SATAz 2018.08.12 18:28 신고

      제가 자격증을 준비하다보니.... 신경을 못썼습니다. 답변이 늦어져서 죄송합니다.

      https://kldp.org/node/124363 글을 확인해보세요,

      현재 설치되어있는 커널 버전과 IPTables 버전이 xt_geoip 모듈이 호환하지 않는 버전이어서 그런 것 같습니다.

      커널을 업데이트를 하시는 것이 가장 편한 방법일 것 같아요. 아니면 xtables-addons를 현재 사용하시는 커널, IPTables 버전과 호환되는 것을 찾아서 설치하시는 방법이 있습니다. ^^

    • SATAz 2018.08.12 18:30 신고

      아니면 혹시... GeoIP 설치를 안하셔서 에러메시지가 나오는 것일 수 있어요....

      12번글 http://sata.kr/entry/IPTables-12-IPTables%EC%97%90-GeoIP%EB%A5%BC-%EC%84%A4%EC%B9%98%ED%95%B4%EB%B3%B4%EC%9E%90-GeoIP-CentOS-6CentOS-7 도 한번 참고해주세요 ^^

  2. Tony_Kim 2018.08.12 17:49

    국내 서비스라 한국을 제외한 모든 해외 IP차단이 필요했는데 12번글부터 따라하니 정말 막힘없이 진행되었습니다. 감사합니다. 다만 iptables -nL명령어를 통해 iptables목록을 조회했을때
    보여주신 결과와 달리 DROP tcp -- 0.0.0.0/0 192.168.0.18 Source country: ! KR
    라고 나오는데 큰 문제는 없을까요?

    • SATAz 2018.08.12 18:16 신고

      적용이 잘 되셨다니 다행입니다.
      IPTables 버전별로 표기되는 방식이 조금 달라서 그럴꺼에요.

      "!KR" 의미가 "한국을 제외한 것들"을 의미하기에 문제 없을 것 같습니다 ^^