본문으로 바로가기

안녕하세요, SATAz입니다.

이번 포스팅은 IPTables에 대해서 소개드리는 네 번째 내용입니다.





지난 포스팅에서는 IPTables를 이용한 특정 서비스 포트 차단/허용하는 내용을 다루었는데요,

이번 포스팅은 IPTables의 -m 옵션 활용 방법에 대해서 알려드리고자 합니다.



▣주의!!! : 이 블로그에 작성된 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에서의 -m 옵션이란?

 -m 옵션은 IPTables에서 확장 모듈을 활성화하기 위해 사용하는 플래그입니다.

 

2. IPTables에서의 -m state 확장모듈

 1) state 모듈의 4가지 상태 (NEW, ESTABLISHED, RELATED, INVALID)

 state 옵션은 "연결 상태에 따른 패킷"을 것을 다루는데, 아래의 3가지 형태의 연결 상태에 따른 패킷 확인하여 패킷필터링을 합니다.


# state 매치 연결 상태의 종류 [INPUT Chain에 적용된 것을 기준으로 설명드립니다.]

NEW : 이전에 없던 패킷의 새로운 첫 연결 요청이 Client PC로부터 들어오는 패킷을 의미한다.

ESTABLISHED : NEW 상태를 거친 이후의 패킷 / 새로운 연결 요청에 관한 그 후의 패킷들이 오고가는 상태를 의미한다.

RELATED : 새로운 연결 요청이지만, 기존의 연결과 관련된 패킷을 의미한다. (FTP 데이터 전송, ICMP 에러 전송 등)

INVALID : 이전 상태 중에 어떠한 것도 적용되지 않으면 패킷의 상태를 INVALID로 표시합니다. (결론: 비정상적인 접근)


*FTP 데이터 전송(tcp/20번)포트를 RELATED를 이용하여 허용하고자 할 때에는, nf_conntrack_ftp 모듈을 별도로 사용해야한다.


 2) state 옵션의 명령어 구조


# state 매치 연결의 종류


[root@localhost ~]# iptables -[옵션] [체인명] -m state --state [연결상태] -p [프로토콜]  -j [정책]



물론 state 옵션을 사용할 때에도 -s 옵션, -d 옵션, --dport 옵션을 이용해서 특정 서비스에 대한 접근을 제어할 수 있습니다.



 3) IPTables에서의 state 모듈 활성화 - 명령어로 적용하는 방법


예제)

Source IP : Any -> Destination IP : 192.168.0.18, Service Port : Any, state INVALID - 차단

Source IP : Any -> Destination IP : 192.168.0.18, Service Port : Any, state ESTABLISHED, RELATED - 허용


# 예제를 적용하기 위한 명령어

iptables -I INPUT -m state -d 192.168.0.18 -p all --state ESTABLISHED,RELATED -j ACCEPT

iptables -I INPUT -m state -d 192.168.0.18 -p all --state INVALID -j DROP


위의 예제는, ESTABLISHED 상태와 RELATED 상태의 패킷은 허용하고, INVALID 상태의 패킷은 차단하겠다는 것을 의미합니다.

NEW 상태가 없기 때문에, Client PC에서 Server로 요청을 넣는 모든 패킷은 차단이 될 것입니다.


# 명령어 적용하기 전의 상황

[root@localhost ~]# iptables -nL

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

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 ~]# ping google.com

PING google.com (172.217.25.206) 56(84) bytes of data.

^C

--- google.com ping statistics ---

8 packets transmitted, 0 received, 100% packet loss, time 7009ms


위와 같이 가장 기본적인 방화벽 룰셋만 있는 상태에서는 google.com으로 ping이 갈 수가 없습니다.

Ping Request를 google.com으로 보냈지만, IPTables 때문에 Ping Reply가 서버로 들어오지 못했기 때문입니다.

아래와 같이 명령어를 입력한 다음에 다시한번 ping을 보내면 정상적으로 통신이 가능합니다.



# 명령어 적용하고난 후의 상황

[root@localhost ~]# iptables -I INPUT -m state -d 192.168.0.18 -p all --state ESTABLISHED,RELATED -j ACCEPT

[root@localhost ~]# iptables -I INPUT -m state -d 192.168.0.18 -p all --state INVALID -j DROP

[root@localhost ~]#

[root@localhost ~]# ping google.com

PING google.com (216.58.197.174) 56(84) bytes of data.

64 bytes from nrt12s02-in-f174.1e100.net (216.58.197.174): icmp_seq=1 ttl=53 time=34.3 ms

64 bytes from nrt12s02-in-f174.1e100.net (216.58.197.174): icmp_seq=2 ttl=53 time=32.3 ms

64 bytes from nrt12s02-in-f174.1e100.net (216.58.197.174): icmp_seq=3 ttl=53 time=32.2 ms

64 bytes from nrt12s02-in-f174.1e100.net (216.58.197.174): icmp_seq=4 ttl=53 time=32.3 ms

^C

--- google.com ping statistics ---

4 packets transmitted, 4 received, 0% packet loss, time 3005ms

rtt min/avg/max/mdev = 32.295/32.834/34.381/0.920 ms


이번에는 ESTABLISH state의 룰 덕분에, Ping Reply가 정상적을 도달할 수가 있어서 Ping 결과가 잘 나왔습니다.



3. 그 외로 사용되는 -m 옵션

1) GeoIP

#GeoIP match

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

[root@localhost ~]# iptables -I INPUT -m geoip -d 192.168.0.18 --src-cc KR -j ACCEPT


GeoIP를 이용하면, 국가별로 아이피를 차단하고 하용할 수가 있습니다.

물론 GeoIP라는 모듈을 별도로 설치해주셔야합니다. GeoIP 모듈 설치 방법은 추후에 포스팅하도록 하겠습니다.



2) TCP

#tcp match

[root@localhost ~]# iptables -I INPUT -m tcp -p tcp -d 192.168.0.18 --dport 22 -j DROP 

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


사실 그냥 -p 옵션만 쓰고 tcp 프로토콜임을 지정해줘도 상관은 없습니다. -m tcp를 생략해도 자동으로 등록되는 것 같습니다.


3) connlimit

#connlimit

[root@localhost ~]# iptables -I INPUT -m connlimit -p tcp -d 192.168.0.18 --dport 80 --connlimit-above 10 -j DROP


-d [목적지 아이피]로 들어오는 패킷들의 연결 개수를 제한하는 것을 의미합니다. 추후에 포스팅할 예정이지만, 10번 이상의 접근이 발생하면 iptables를 재시작할 때 까지 Source IP 는 접근을 할 수가 없습니다.


4) limit

#limit

[root@localhost ~]# iptables -I INPUT -m limit -p tcp -d 192.168.0.18 --dport 80 --limit 100/m --limit-burst 5 -j DROP


-d [목적지 아이피]로 들어오는 패킷이 --limit-burst 개수만큼 매칭이 된 후, 1초/1분/1시간당 [특정 횟수] 만큼 패킷을 차단하고, 그 이후의 패킷들은 허용하는 정책입니다. 

조금... 복잡한 내용입니다. 이 내용도 추후에 포스팅에서 다룰 예정입니다.


5) recent

#recent

[root@localhost ~]# iptables -A INPUT -m recent -p tcp -d 192.168.0.18 --dport 80 --set --name testblock

[root@localhost ~]# iptables -A INPUT -m recent -p tcp -d 192.168.0.18 --dport 80 --update --seconds 600 --hitcount 10 --name testblock  -j DROP


-d [목적지 아이피]로 들어오는 패킷들을 testblock 테이블에 추가한 다음, 10분동안 10번 이상의 접근이 발생하면 접근을 차단한다는 내용입니다. --update 말고도 --rcheck 라는 옵션도 있는데, 자세한 내용은 이것도 추후 포스팅에서 다룰 예정입니다.


나중에는 제가 iptables로 DDOS를 방어하는 방법에 대해서 설명을 드리려고 합니다.

그 때, connlimit, limit, recent 모듈을 같이 다룰 예정이니 기대해주면 감사하겠습니다 ^^



다음 포스팅에서는, -m 옵션으로 FTP 데이터 전송 포트를 설정하는 방법에 대해서 포스팅하도록 하겠습니다 ^^

두서없는 글을 읽어주셔서 정말 감사합니다.

반응형