강좌
클라우드/리눅스에 관한 강좌입니다.
해킹&보안 분류

FTP 서비스를 위한 iptables 룰 설정

작성자 정보

  • 관리자 작성
  • 작성일

컨텐츠 정보

본문

FTP 서비스를 위한 iptables 룰 설정




 

초기에 방화벽을 구현할 때 가장 어려웠던 것 중 하나는 바로 FTP 서비스였다.

 

 

 

 

FTP 서비스는 다른 서비스와 달리 Active 모드와 Passive 모드라는 2개의 모드가 존재하며 또한 각각의 모드에서는 2개 또는 2개 이상의 포트가 작동하기 때문이다.

 

 

 

 

이 때문에 일부 구형 방화벽이나 공유기 제품의 경우 FTP가 제대로 되지 않는 경우가 있었는데, iptables의 경우 상태 추적이 도입되면서 FTP 구현이 매우 쉬워졌다.

 

FTP가 사용하는 포트는 다른 서비스와 달리 data 포트와 command 포트(또는 control 포트) 이렇게 2개의 포트를 사용하는데, 흔히 초기 접속 시 사용되는 21번은 command 포트, 데이터 전송 시 사용되는 20번 또는 1024 이후의 포트는 data 포트라고 한다.

 

 

 

 

그럼 iptables에서 FTP 룰을 정확히 설정하기 위하여 active모드와 passive모드에 대해 각각 알아보도록 하자.

 

Active FTP 모드

 

기본 설정으로 많이 사용하는 active 모드에서의 작동 방식은 다음과 같다.

 

 

 

 

먼저 클라이언트에서 서버의 21번 포트로 접속 후 클라이언트가 사용할 두 번째 포트를 서버에 알려준다.

 

 

 

 

서버는 이에 대해 ack로 응답하고(여기까지는 일반적인 TCP/IP 작동 방식과 동일하다.), 서버의 20번 포트는 클라이언트가 알려준 두 번째 포트로 접속을 시도한다.

 

 

 

 

마지막으로 클라이언트가 ack로 응답한다.

 

 

 

 

active 모드의 문제점은 바로 3번째 단계 즉, 일반적인 TCP/IP 의 특징인 클라이언트가 서버에 접속을 시도하는 것이 아니라 반대로 '서버가 클라이언트에 접속을 시도한다'는 점이다.

 

 

 

 

이 때문에 만약 클라이언트 PC등에 방화벽이 설치되어 있거나 ftp를 잘 이해하지 못하는 공유기 등을 사용하여 외부에서의 접속을 허용하지 않는다면 세 번째 프로세스가 작동하지 않게 되어 ftp 접속이 제대로 되지 않는 문제가 있다.

 

 

 

 

이러한 경우 ftp 접속은 되지만 이후 데이터 목록을 받아오지 못하여 에러가 발생하게 된다.

 

 

 

 

 

373a19c45acc0921a2ae9e29fe340001_1683007549_976.png
 

[그림] active ftp의 작동방식

 

Passive FTP 모드

 

서버가 클라이언트에 접속시도를 하는 비정상적인 active 모드와 관련된 문제를 해결하기 위한 대안으로 passive 모드가 디자인되었다.

 

 

 

 

passive 모드에서는 먼저 클라이언트가 command 포트로 접속을 시도하면 서버에서는 서버가 사용할 두 번째 포트를 알려준다.

 

 

 

 

클라이언트는 다른 포트를 열어 서버가 알려준 이 포트로 접속을 시도하고, 서버는 ack로 응답한다.

 

 

 

 

passive 모드에서는 두 번째 data 포트로서 active 모드가 사용했던 20번을 사용하지 않고 대신 1024 이후의 임의의 비특권 포트를 사용하게 된다.

 

 

 

 

따라서 passive 모드는 서버에서 클라이언트로 연결을 시도하는 active 모드의 문제점을 해결하기는 했지만, 서버의 비 특권 포트(1024부터 65535까지)를 방화벽에서 모두 열어 두어야 한다는 또 다른 문제점을 낳았다.

 

 

 

 

그러나 wu-ftpdproftpd등 대부분의 ftp 데몬에서는 클라이언트가 passive 모드로 접속 시 사용할 수 있는 포트를 제한설정 할 수 있는 기능을 지원하므로 이의 문제점을 미봉책이나마 어느 정도는 해결할 수 있다.

 

 

 

 

 

 

373a19c45acc0921a2ae9e29fe340001_1683007609_8238.png
 

[그림] passive ftp의 작동방식

 

참고로 ftp가 사용할 모드는 서버에서 선택하는 것이 아니라 클라이언트에서 선택하는 것이며 ncftp나 셸에서 사용하는 솔라리스의 ftp등 일부 클라이언트는 기본적으로 passive 모드를 지원하지 않는다.

 

 

 

 

아마 이쯤 되면 어지럽기도 하고 다소 헛갈릴 수 있는데, 다시 한 번 정리를 해보자.

 

서버관리자 입장에서 방화벽을 구성할 때 서버의 비 특권 포트(high port)를 모두 열어두어야 하는 passive 모드에 비해 두 개의 포트에 대해서만 정책을 설정하면 되므로 active 모드가 관리 면에서는 편할지 모르지만, 클라이언트에 방화벽이 있거나 공유기를 사용할 경우 제대로 동작하지 않는다는 문제가 있으므로 이러한 경우에는 passive 모드를 사용하여야 한다.

 

 

 

 

active, passive 모드의 작동방식은 아래와 같이 접속 시 몇 가지 옵션을 주어 테스트해 볼 수 있다.

 

먼저 active 모드에서의 접속을 확인해 보자.



 

 

# ftp -d 211.47.65.106

Connected to server.

220 Server ready ..

Name (server:root): user1

---> USER user1

331 Password required for user1.

Password:xxxx

---> PASS XXXX

230 User user1 logged in.

---> SYST

215 UNIX Type: L8

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> dir

---> PORT 211,47,66,50,164,232

200 PORT command successful

---> LIST

150 Opening ASCII mode data connection for file list

drwx-----x 6 user1 user1 8192 Aug 7 01:09 .

drwx-----x 122 root root 4096 Aug 6 04:34 ..

-rw-rw-r-- 1 user1 user1 9412 Mar 25 05:30 test.c

226 Transfer complete.

ftp>




 

여기에서 -ddebug 모드이며 아무런 언급이 없으므로 active 모드로 접속하겠다는 의미이다.

 

 

 

 

그리고 dir 명령어를 입력하자 PORT 211,47,66,50,164,232 라는 부분이 출력되었는데, 이는 active 모드에서 클라이언트가 서버에게 자신의 두 번째 포트를 알려주는 부분이며 이 메시지의 의미는 클라이언트가 211.47.66.50이며 두 번째로 사용할 포트가 164x256+232=42216번이라는 것을 알려주는 것이다.

 

 

 

 

그리고 “200 PORT command successful” 부분은 서버가 클라이언트에게 수신을 확인하는 부분이다.

 

 

 

 

이후에는 새롭게 알려준 포트로 데이터가 전송되게 되며 아래는 관련 패킷을 캡처한 부분이다.



 

11:03:08.009521 211.47.66.50.42179 > 211.47.65.106.ftp: P 35:62(27) ack 722 win 5840 (DF) [tos 0x10]

0x0000 4510 0043 f7b7 4000 3f06 19f2 d32f 4232 E..C..@.?..../B2

0x0010 d32f 416a a4c3 0015 36bf 53b2 a9b1 83bf ./Aj....6.S.....

0x0020 5018 16d0 5489 0000 504f 5254 2032 3131 P...T...PORT.211

0x0030 2c34 372c 3636 2c35 302c 3136 342c 3233 ,47,66,50,164,23

0x0040 320d 0a 2..




---> PORT 211,47,66,50,164,232 부분이다.



 

11:03:08.009521 211.47.65.106.ftp > 211.47.66.50.42179: P 722:752(30) ack 62 win 5840 (DF)

0x0000 4500 0046 2f9a 4000 4006 e11c d32f 416a E..F/.@.@..../Aj

0x0010 d32f 4232 0015 a4c3 a9b1 83bf 36bf 53cd ./B2........6.S.

0x0020 5018 16d0 5525 0000 3230 3020 504f 5254 P...U%..200.PORT

0x0030 2063 6f6d 6d61 6e64 2073 7563 6365 7373 .command.success

0x0040 6675 6c2e 0d0a ful...

--> 200 PORT command successful 부분이다.

 

 

 

 

 

 

11:03:08.009521 211.47.65.106.ftp-data > 211.47.66.50.42216: S 2899401794:2899401794(0) win 5840 <mss 1460,sackOK,timestamp 118801298 0,nop,wscale 0> (DF)

0x0000 4500 003c 9fd0 4000 4006 70f0 d32f 416a E..<..@.@.p../Aj

0x0010 d32f 4232 0014 a4e8 acd1 5c42 0000 0000 ./B2......\B....

0x0020 a002 16d0 8e84 0000 0204 05b4 0402 080a ................

0x0030 0714 c392 0000 0000 0103 0300 ............

 

11:03:08.009521 211.47.66.50.42216 > 211.47.65.106.ftp-data: S 965725808:965725808(0) ack 2899401795 win 5840 <mss 1460> (DF) [tos 0x8]

0x0000 4508 002c 0000 4000 3f06 11c9 d32f 4232 E..,..@.?..../B2

0x0010 d32f 416a a4e8 0014 398f ce70 acd1 5c43 ./Aj....9..p..\C

0x0020 6012 16d0 a139 0000 0204 05b4 0000 `....9........

 

11:03:08.009521 211.47.65.106.ftp-data > 211.47.66.50.42216: . ack 1 win 5840 (DF)

0x0000 4500 0028 9fd1 4000 4006 7103 d32f 416a E..(..@.@.q../Aj

0x0010 d32f 4232 0014 a4e8 acd1 5c43 398f ce71 ./B2......\C9..q

0x0020 5010 16d0 b8f6 0000 P.......





--> 위 세부분은 각각 또 하나의 포트로 ftp-data 포트와 새롭게 3 way handshake하는 부분이다.

 

 

 

 

앞에서 언급했듯이 접속에 대한 요청(SYN)을 클라이언트인 211.47.66.50이 아닌 211.47.65.106인 서버가 하는 것을 알 수 있다.

 

 

 

 

 

다음은 passive 모드에서의 접속을 확인해 보자.


 

 

# ftp -d -p 211.47.65.106

Connected to server.

220 Server ready ..

Name (server:root): user1

---> USER user1

331 Password required for korea.

Password:xxxx

---> PASS XXXX

230 User korea logged in.

---> SYST

215 UNIX Type: L8

Remote system type is UNIX.

Using binary mode to transfer files.

ftp> dir

---> PASV

227 Entering Passive Mode (211,47,65,106,199,167).

---> LIST

150 Opening ASCII mode data connection for file list

drwx-----x 6 user1 user1 8192 Aug 7 01:09 .

drwx-----x 122 root root 4096 Aug 6 04:34 ..

-rw-rw-r-- 1 user1 user1 9412 Mar 25 05:30 test.c

226 Transfer complete.

ftp>




 

11:16:24.119521 211.47.66.50.42499 > 211.47.65.106.ftp: P 1805254075:1805254081(6) ack 3757504938 win 5840 (DF) [tos 0x10]

0x0000 4510 002e 11d5 4000 3f06 ffe9 d32f 4232 E.....@.?..../B2

0x0010 d32f 416a a603 0015 6b99 fdbb dff6 f9aa ./Aj....k.......

0x0020 5018 16d0 d549 0000 5041 5356 0d0a P....I..PASV..




--> 클라이언트가 dir을 입력과 동시에 서버에 ---> PASV를 요청하는 부분이다.

 

 

 

 

 

 

11:16:24.119521 211.47.65.106.ftp > 211.47.66.50.42499: P 1:53(52) ack 6 win 5840 (DF)

0x0000 4500 005c 015f 4000 4006 0f42 d32f 416a E..\._@.@..B./Aj

0x0010 d32f 4232 0015 a603 dff6 f9aa 6b99 fdc1 ./B2........k...

0x0020 5018 16d0 d3f0 0000 3232 3720 456e 7465 P.......227.Ente

0x0030 7269 6e67 2050 6173 7369 7665 204d 6f64 ring.Passive.Mod

0x0040 6520 2832 3131 2c34 372c 3635 2c31 3036 e.(211,47,65,106

0x0050 2c31 ,1





--> 서버에서 “227 Entering Passive Mode (211,47,65,106,199,167).”로 응답하는 부분이다.

 

 

 

 

 

 

11:16:24.129521 211.47.66.50.42501 > 211.47.65.106.51111: S 1813746966:1813746966(0) win 5840 <mss 1460> (DF)

0x0000 4500 002c 7a45 4000 3f06 978b d32f 4232 E..,zE@.?..../B2

0x0010 d32f 416a a605 c7a7 6c1b 9516 0000 0000 ./Aj....l.......

0x0020 6002 16d0 e87b 0000 0204 05b4 0000 `....{........

11:16:24.129521 211.47.65.106.51111 > 211.47.66.50.42501: S 3762635290:3762635290(0) ack 1813746967 win 5840 <mss 1460> (DF)

0x0000 4500 002c 0000 4000 4006 10d1 d32f 416a E..,..@.@..../Aj

0x0010 d32f 4232 c7a7 a605 e045 421a 6c1b 9517 ./B2.....EB.l...

0x0020 6012 16d0 c60a 0000 0204 05b4 `...........

11:16:24.129521 211.47.66.50.42501 > 211.47.65.106.51111: . ack 1 win 5840 (DF)

0x0000 4500 0028 7a46 4000 3f06 978e d32f 4232 E..(zF@.?..../B2

0x0010 d32f 416a a605 c7a7 6c1b 9517 e045 421b ./Aj....l....EB.

0x0020 5010 16d0 ddc7 0000 0000 0000 0000 P.............





--> 위 세부분은 각각 또 하나의 포트로 20번이 아닌 ftpdata 포트와 새롭게 3 way handshake하는 부분이다.

 

 

 

 

앞에서 언급했듯이 접속에 대한 요청(SYN)을 앞의 active와 반대로 클라이언트인 211.47.66.50이 하는 것을 알 수 있다.

 

 

 

 

 

11:16:24.129521 211.47.66.50.42499 > 211.47.65.106.ftp: P 6:12(6) ack 53 win 5840 (DF) [tos 0x10]

0x0000 4510 002e 11d7 4000 3f06 ffe7 d32f 4232 E.....@.?..../B2

0x0010 d32f 416a a603 0015 6b99 fdc1 dff6 f9de ./Aj....k.......

0x0020 5018 16d0 d909 0000 4c49 5354 0d0a P.......LIST..

11:16:24.129521 211.47.65.106.ftp > 211.47.66.50.42499: P 53:107(54) ack 12 win 5840 (DF)

0x0000 4500 005e 0160 4000 4006 0f3f d32f 416a E..^.`@.@..?./Aj

0x0010 d32f 4232 0015 a603 dff6 f9de 6b99 fdc7 ./B2........k...

0x0020 5018 16d0 9561 0000 3135 3020 4f70 656e P....a..150.Open

0x0030 696e 6720 4153 4349 4920 6d6f 6465 2064 ing.ASCII.mode.d

0x0040 6174 6120 636f 6e6e 6563 7469 6f6e 2066 ata.connection.f

0x0050 6f72





--> 이후에 명령은 다시 명령 채널인 21번을 통해 이루어진다.

 

 

 

 

 

여기에서 -ddebug 모드이며 -ppassive모드로 접속하겠다는 의미이다.

 

 

 

 

그리고 dir 명령어를 입력하자 서버 쪽에서 Entering Passive Mode (211,47,65,106,199,167)라고 응답하였는데, 이는 passive 모드의 2번째 단계에서 클라이언트의 요청에 서버가 사용할 포트를 알려주는 부분이며 이 메시지의 의미는 ftp 서버의 IP 주소가 211.47.65.106이며 서버에서 사용할 포트가 199x256+167=51111번이라는 것을 알려주는 것이다.

 

 

 

 

ftp는 매우 복잡하므로 그림과 함께 여러 번 반복적으로 살펴보고 익숙하게 만들어두기 바란다.

 

 

 

 

 

만약 ftp 접속시 -p 옵션이 지원되지 않으면 ftp 접속 후 ftp>passive를 실행하면 된다.




 

ftp 서비스에 대해 살펴보았으니 이제 각각의 ftp 서비스에 대한 룰을 작성해 보자. ftp의 룰 작성은 작동 방식만큼 복잡하므로 반드시 active 모드와 passive 모드의 그림을 그려서 생각해 보기 바란다.

 

 

 

 

먼저 ftp 서버로서 외부에서 들어오는 연결을 허용하는 룰을 작성해 보자.



 

외부에서 들어오는 ftp 접속 요청


 

첫 번째 프로세스는 active 모드나 passive 모드에 관계없이 다른 tcp 프로토콜의 작동방식과 동일하다.

 

 

 

 

먼저 접속을 시도하는 클라이언트에서 1024 이후의 포트를 이용해 서버의 21번으로 SYN 접속시도를 하므로 이 접속시도를 허용하였고, 이에 대한 응답으로 소스 포트는 21, 응답포트는 1024 이후의 포트로 하여 나가는(OUTPUT) 패킷을 허용하였는데, SYN에 대한 응답이므로 ! --syn이라 언급하였고 상태는 ESTABLISHED가 된다.



 

$IPTABLES -A INPUT -p TCP --sport 1024: --dport 21 -m state --state NEW -j ACCEPT

$IPTABLES -A OUTPUT -p TCP ! --syn --sport 21 --dport 1024: -m state --state ESTABLISHED -j ACCEPT

 

 


active 모드에서의 데이터 교환



 

이제 그 다음 두 번째 포트가 작동할 차례이다.

 

 

 

 

active 모드에서는 클라이언트에서 서버로 접속 시도를 하는 것이 아니라 서버에서 클라이언트로 연결을 먼저 시도하므로 OUTPUT을 먼저 정의하였다.

 

 

 

 

서버 쪽의 소스포트는 20번이고 목적지 포트는 1024 이후의 임의의 포트가 된다.

 

 

 

 

그리고 이에 대한 응답으로 소스포트는 1024 이후의 포트에서 목적지 포트 20번으로 들어오는 패킷을 허용하여야 한다.

 

 

 

 

앞에서 잠깐 언급했듯이 20번 포트의 작동은 기존의 21번 포트의 작동을 통해 주고받은 포트정보와 연관되어 있으므로 여기에서는 NEW 대신 예외적으로 RELATED를 사용하여야 한다.

 

 

 

 

물론 기존의 포트 정보와도 다르므로 ESTABLISHED도 아니다.

 

 

 

 

 

 

$IPTABLES -A OUTPUT -p TCP --sport 20 --dport 1024: -m state --state RELATED -j ACCEPT

$IPTABLES -A INPUT -p TCP ! --syn --sport 1024: --dport 20 -m state --state ESTABLISHED -j ACCEPT

 


 

passive모드에서의 데이터 교환


 

passive 모드에서는 일반 tcp 통신처럼 클라이언트에서 서버로 연결을 시도하는 방식이다.




그러나 소스 포트와 목적지 포트 모두 1024 이후의 비 특권 포트를 사용한다는 특징이 있다는 것을 앞에서 알아보았다.

 

 

 

 

먼저 소스포트가 1024 이후인 클라이언트에서 목적지 포트가 역시 1024 이후인 포트로 들어오는 패킷을 허용하였다.

 

 

 

 

여기에서도 active 모드와 같이 두 번째 포트의 작동은 기존의 21번 포트의 통신을 통해 주고받은 포트정보와 연관되어 있으므로 여기에서는 NEW 대신 RELATED를 사용한다.

 

 

 

 

 

그리고 이에 대한 응답이므로 SYN패킷이 아니면서(! --syn) 목적지 포트가 1024 이후인 나가는 패킷을 허용하였다.

 

 

 

 

 

 

$IPTABLES -A INPUT -p TCP --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A OUTPUT -p TCP ! --syn --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT




active 모드나 passive 모드의 사용은 서버에서 정하는 것이 아니라 클라이언트에서 정하는 것이므로 불특정 다수를 대상으로 서비스를 제공하는 입장에서는 클라이언트가 어떤 방식으로 접근할 지 알 수 없으므로 두 가지 모드를 모두 열어두어야 할 것이다. 

 

 

 

 

그러나 내부 직원 등 일부 한정된 유저만 접근한다면 특정한 정책을 정하여 한 가지 모드로 통일하여 사용하도록 제한할 수도 있을 것이다.

 

 

 

 

참고로, OUTPUT의 기본정책(default policy)ACCEPT인 경우, 아래 두 줄만으로 active, passive 관계없이 FTP 서비스는 안전하게 허용할 수 있다.

 

 

 

 

참고로 첫 번째 룰은 앞에서 이미 허용한 바 있으므로 실제로는 두 번째 룰인 21/tcp만 허용하면 복잡한 ftp 문제는 간단히 해결된다.


 

$IPTABLES -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A INPUT -p TCP -s 0/0 --sport 1024:65535 --dport 21 -m state --state NEW -j ACCEPT



 

앞에서 알아본 방법을 토대로 이번에는 여러분이 방화벽에서 외부 ftp 서버로 접근하는 것을 허용하는 룰을 직접 작성해 보기 바란다.

 

 

 

 

INPUT, OUTPUT만 적절히 바꾸어주면 되므로 그리 어렵지 않을 것이다.



 

????[유용한 팁]



만약 ftp 데몬으로 proftpd를 사용한다면 proftpd.conf"PassivePorts 51000 51999"와 같이 지정할 경우 passive모드에서 사용할 포트범위를 지정할 수도 있다.

 

 

 

 

그러나 접속 후 동시에 많은 파일을 전송할 때에는 포트가 부족할 수도 있다.

 

 

 

 

왜냐하면 active 모드에서는 여러 파일을 동시에 전송한다 하더라도 데이터 포트로서 서버에서는 20번 포트만 사용되지만 passive 모드에서는 선택한 파일의 수만큼 데이터 포트가 열리게 되기 때문이다.

 

 

 

 

각자 passive 모드로 접속해서 tcpdump로 테스트해 보기 바란다.

 

 

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,043 명
  • 현재 강좌수 :  35,853 개
  • 현재 접속자 :  110 명