본문으로 바로가기



안녕하세요, SATAz입니다.

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




지난 포스팅에서는 IPTables의 -m 옵션을 활용하는 내용을 다루었는데요,

이번 포스팅은 IPTables 때문에 FTP 디렉토리 조회가 실패했을 때의 조치방법에 대해서 알려드리고자 합니다.



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

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


#IPTables 설정를 위한 환경


- 테스트 머신 : VMware WorkStation 12 Player

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

- 메모리 : 2GB

- IPTables Version : iptables v1.4.21

- 서버 아이피 : 192.168.0.18


- FTP 서버 패키지 : vsftpd

- FTP 클라이언트 프로그램 : FileZilla


FTP에 대한 개요와, 연결 방식에 대한 내용은 아래의 포스팅에서 설명해두었습니다.

한 번 쯤은 읽어보시는 것이 좋습니다 ^^


클릭하여 포스팅 보기>  [FTP] FTP의 Active Mode와 Passive Mode 차이점 - 2017-07-16 < 클릭하여 포스팅 보기


0. 기존 방화벽 설정 (관리용을 제외한 모든 INPUT 접근을 차단)

# 기존 방화벽 설정.

[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   


상태 1 : 정말 기본적인 것을 제외하고는, 모든 INPUT 접근을 차단함

상태 2 : OUTPUT 방향의 패킷은 전체적으로 허용함


1. 일단 FTP에서 인증/명령을 담당하는 21/tcp를 열어주자

 아마 여러분이 사용하시는 FTP서버의 방화벽에서 21/tcp가 허용되어있지 않다면, 로그인 자체가 되지 않을 것입니다.

21/tcp가 허용되지 않은 상태에서의 FTP 클라이언트에서는 아래와 같은 메시지를 출력합니다.


# FTP 클라이언트 FileZilla 의 작업 로그

상태: 192.168.0.18:21에 연결...

오류: Connection timed out after 20 seconds of inactivity

오류: 서버에 연결하지 못함

상태: 재시도 대기...

상태: 192.168.0.18:21에 연결...

오류: Connection timed out after 20 seconds of inactivity

오류: 서버에 연결하지 못함

상태: 재시도 대기...


로그인에 성공하기 위해서는, 아래의 명령어로 21번 포트를 허용하도록 추가해야 합니다. (전체아이피에 대해서 21/tcp 포트 접근 허용)


# 21/tcp 포트를 허용하는 명령어

iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 21 -j ACCEPT


# 명령어 적용 후 방화벽 상태

[root@localhost ~]# iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 21 -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:21

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 


방화벽에서 21/tcp를 허용한 후에, FTP Client 작업로그를 통해서 로그인에 성공한 것을 확인할 수 있습니다.


# FTP 클라이언트 FileZilla 의 작업 로그 - Active Mode 일 때...

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: 디렉터리 목록 조회...

상태: "/home/test" 디렉터리 목록 조회 성공


# FTP 클라이언트 FileZilla 의 작업 로그 - Passive Mode 일 때...

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: 디렉터리 목록 조회...

명령: PWD

응답: 257 "/home/test"

명령: TYPE I

응답: 200 Switching to Binary mode.

명령: PASV

응답: 227 Entering Passive Mode (192,168,0,18,48,196).

명령: LIST

오류: Connection timed out after 20 seconds of inactivity

오류: 디렉터리 목록 조회 실패


FTP Server를 Active-Mode로 설정했을 때에는 로그인 및 디렉토리 목록 조회까지 성공하는 것을 확인할 수가 있습니다.

그러나 Passive-Mode로 설정했을 때에는 로그인까지만 성공하고 디렉토리 목록 조회를 실패하게됩니다.


Active Mode와 Passive Mode의 차이가 발생하는 이유에 대해서 추가로 설명드리겠지만, 자세한 이해를 위해서는 아래의 포스팅을 먼저 읽어주시기 바랍니다.

클릭하여 포스팅 보기>  [FTP] FTP의 Active Mode와 Passive Mode 차이점 - 2017-07-16 < 클릭하여 포스팅 보기



2. Active Mode에서 파일 업/다운로드가 되지 않는다?

Active Mode에서 디렉토리 조회를 성공했다 하더라도, 파일 업/다운로드를 시도했을 때에는 아래와 같은 메시지가 확인될 것입니다.


# FTP 클라이언트 FileZilla 의 작업 로그

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: D:\Operating System ISO\CentOS-6.9-x86_64-bin-DVD1.iso 업로드 시작

상태: "/home/test" 디렉터리 목록 조회...

명령: TYPE I

응답: 200 Switching to Binary mode.

명령: PORT 192,168,0,2,218,152

응답: 200 PORT command successful. Consider using PASV.

명령: LIST

오류: Connection timed out after 20 seconds of inactivity

오류: 파일 전송 실패


Active Mode에서 파일 업/다운로드가 되지 않는 이유는 20번 포트에 대한 INPUT이 허용되어있지 않기 때문입니다.

그에 대한 이해하기 위해서는, FTP 통신에서 아래와 같은 통신이 이루어 진다는 것을 알아야 합니다.


아래 그림과 같이 3번째 패킷 전달 과정인, DATA Channel 접근 요청을 FTP Server에서 -> Client PC로 보내는 것은 성공했기 때문에 디렉토리 목록 조회까지는 가능합니다.

하지만 4번째 패킷 전달 과정에서 패킷이 차단되기 때문에 파일 업/다운로드는 실패하는 것이죠.




Active Mode에서 파일 업/다운로드가 안되는 것을 해결하기 위해서는, 방화벽에서 아래와 같이 20/tcp 포트 허용 설정을 해주셔야 합니다.


# 21/tcp 포트를 허용하는 명령어

iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 20 -j ACCEPT


# 명령어 적용 후 방화벽 상태

[root@localhost ~]# iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 20 -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:20

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

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     


그리고 다시 파일을 업로드해보겠습니다.


# FTP 클라이언트 FileZilla 의 작업 로그

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: 디렉터리 목록 조회...

상태: "/home/test" 디렉터리 목록 조회 성공

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: D:\Operating System ISO\CentOS-6.9-x86_64-bin-DVD1.iso 업로드 시작

상태: 파일 전송 성공, 3,972,005,888 바이트를 165 초에 전송

상태: "/home/test" 디렉터리 목록 조회...

상태: "/home/test" 디렉터리 목록 조회 성공


역시 파일 업로드에 성공했습니다. 그러면 다운로드도 시도해보겠습니다.


# FTP 클라이언트 FileZilla 의 작업 로그

상태: 서버와의 연결이 종료됨

상태: 직전 연결 실패로 5초 연결 지연...

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 서버에 의해 연결 닫힘

상태: 로그인

상태: /home/test/CentOS-6.9-x86_64-bin-DVD1.iso 다운로드 시작
상태: 파일 전송 성공, 3,972,005,888 바이트를 186 초에 전송


다운로드도 성공적으로 완료된 것으로 확인되었습니다.



3. Passive Mode에서 디렉토리 목록 조회 실패의 이유는?

Passive Mode에서는 DATA Channel 포트를 1024~65534/tcp 중에서 랜덤하게 포트를 사용하여 통신하게 되며, 통신 방식은 아래와 같습니다.

아래 그림과 같이 3번째 패킷 전달 과정인, DATA Channel 접근 요청을 Client PC에서 -> FTP Server (포트 1024~65534)로 보내게 되는데요,

IPTables에서는 1024~65534 포트 전체가 차단되어 디렉토리 목록 조회부터 실패하게 됩니다.





그런데 INPUT에서 1024~65535/tcp 포트에 대한 모든 접근을, 전체적으로 허용해줄 수는 없는 일이잖아요?

(당연히 불필요한 포트를 허용해 놓는 것은 보안상으로 상당히 좋지 않습니다...;;)

이를 해결하는 방법으로는 2가지가 있습니다.



1) FTP Server에서 Passive Port의 범위를 지정하고, 그 범위를 허용하자.

먼저 vsftpd의 기준에서는 /etc/vsftpd/vsftpd.conf 파일에서 아래와 같이 내용을 추가 또는 수정을 해주어야 합니다.


# /etc/vsftpd/vsftpd.conf 파일 수정

[root@localhost ~]# view /etc/vsftpd/vsftpd.conf

##

#아래의 내용을 추가#

pasv_enable=Yes

pasv_min_port=10090

pasv_max_port=10100

################



:wq! (저장하고 나가기)


# vsftpd 서비스 재시작

[root@localhost ~]# view /etc/vsftpd/vsftpd.conf 

[root@localhost ~]# systemctl restart vsftpd


위와 같이 진행할 경우, Passive Mode의 FTP에서 파일을 전송할 때 DATA-Channel을 10090 ~ 10100 포트만을 사용하게 됩니다.

따라서 아래와 같이 방화벽에서 허용해주면 됩니다.


# 10090 ~ 10100/tcp 포트를 허용하는 명령어

iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 10090:10100 -j ACCEPT


# 명령어 적용 후 방화벽 상태

[root@localhost ~]# iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 10090:10100 -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 dpts:10090:10100

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

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

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     


그럼 아래와 같이 로그인에 성공하고 디렉토리 목록 조회에도 성공하는 것을 확인하실 수 있습니다.

물론 업/다운로드도 잘 됩니다 ^^


# FTP 클라이언트 FileZilla 의 작업 로그

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

응답: 220 (vsFTPd 3.0.2)

명령: AUTH TLS

응답: 530 Please login with USER and PASS.

명령: AUTH SSL

응답: 530 Please login with USER and PASS.

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

명령: USER test

응답: 331 Please specify the password.

명령: PASS **********

응답: 230 Login successful.

명령: OPTS UTF8 ON

응답: 200 Always in UTF8 mode.

상태: 로그인

상태: 디렉터리 목록 조회...

상태: "/home/test" 디렉터리 목록 조회 성공




2) IPTables에서 nf_conntrack_ftp 와 -m state를 활용하자


nf_conntrack 이란, 기존에 오고간 패킷들의 상태를 따로 저장해두었다가 ESTABLISHED 또는 RELATED 상태로 활용할 수 있게 해주는 모듈입니다. 그중에 nf_conntrack_ftp를 사용하여 FTP 인증/명령 채널 포트 번호를 지정해두고면, FTP에서 Passive Mode의 통신이 가능하게끔 해주는 역할을 합니다.


# nf_conntrack_ftp 추가하기

modprobe nf_conntrack_ftp

modprobe nf_conntrack_ftp ports=21

lsmod | grep nf_conntrack


# iptables 룰 설정하기

iptables -I INPUT -m state -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 1024:65534 --state ESTABLISHED,RELATED -j ACCEPT


# 명령어 적용 방법

[root@localhost ~]# modprobe nf_conntrack_ftp

[root@localhost ~]# modprobe nf_conntrack_ftp ports=21

[root@localhost ~]# cat /sys/module/nf_conntrack_ftp/parameters/ports

21

[root@localhost ~]# lsmod | grep nf_conntrack

nf_conntrack_ftp       18638  0 

nf_conntrack          111302  1 nf_conntrack_ftp

[root@localhost ~]# iptables -I INPUT -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 21 -j ACCEPT

[root@localhost ~]# iptables -I INPUT -m state -s 0.0.0.0/0 -d 192.168.0.18 -p tcp --dport 1024:65534 --state ESTABLISHED,RELATED -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         state RELATED,ESTABLISHED tcp dpts:1024:65534

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

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 


# FTP 클라이언트 FileZilla 의 작업 로그

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: 디렉터리 목록 조회...

상태: "/home/test" 디렉터리 목록 조회 성공

상태: 서버와의 연결이 종료됨

상태: 192.168.0.18:21에 연결...

상태: 연결 수립, 환영 메시지를 기다림...

상태: 보안되지 않은 서버입니다. TLS를 통한 FTP를 지원하지 않습니다.

상태: 로그인

상태: 디렉터리 목록 조회...

상태: "/home/test" 디렉터리 목록 조회 성공


이렇게 두 가지의 방법이 있습니다.

위의 2개 중에 한가지 방법만 사용하는 것 보다는, 2가지 방법을 같이 사용하는 것이 좋을 것 같습니다.

(FTP Passive Port 범위를 지정하고, 지정된 범위의 포트를 nf_conntrack_ftp로 ESTABLISHED, RELATED만 허용)




지금까지 FTP의 연결 방식에 따른 IPTables 방화벽 설정 방법에 대해서 설명드렸습니다.

다음 포스팅은 DOS를 방어하는 설정을 진행해보고자 합니다.


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




댓글을 달아 주세요

  1. 치즈 2019.10.24 18:48

    passive 모드에서 연결이 안 되어서 고생했는데 글 잘 보았습니다~ 감사해요!

    • SATAz 2019.10.26 14:06 신고

      도움이 되셨다니 정말 다행입니다 ^^
      혹시 안되는거 있으시면 언제든지 댓글 남겨주세요 ^^ 최대한 도와드리겠습니다 ^^