[Linux]리눅스를 방화벽이 적용된 공유기로 사용해보자! 1/3 (iptables 편) (Ubuntu/우분투, Debian/데비안 기준)
Linux / Ubuntu 2014. 2. 6. 02:55리눅스가 설치되어 있는 컴퓨터 혹은 임베디드 장비를 이용하여
iptables와 dhcpd를 활용하여 방화벽이 적용된 공유기로 만드는 법을 설명해 드리고자 합니다.
또한 wol 기능을 이용하여 외부에서 내부 장비를 부팅 시키는 방법에 대해서 추가 설명을 드리고자 합니다.
여기서는 Ubuntu, Debian 기준으로 설명드리지만..
이미 리눅스를 사용하시는 분들이라면..
다른 배포판의 리눅스를 사용하시는 분들도 비슷한 방법으로 손쉽게 적용하실 수 있으리라 생각합니다..^^
iptables 활용이 처음엔 낯설고 어렵게 느껴지기 마련입니다...
저도 처음엔 명령어들이 복잡하고 적용하는게 만만치 않았었거든요;;ㅠ
따라서 여기서는 제가 그동안 구글링과 관력 서적을 참고하며 제가 미리 구성해둔 기본틀을 이용하여 설명해 드리고자 합니다.
또한, 여기서는 각 명령어 옵션들에 대해 자세한 설명을 하기 보다는 이 글을 보시는 여러분들이 이해하시기 쉽도록 기본 짜임새를 가지고 설정하는데 필요한 부분들 위주로 설명해 드리고자 합니다.
먼저 리눅스를 공유기 처럼 사용하시기 위해서는 기본적으로 LAN 인터페이스 2개, 크로스케이블, 스위칭 장비가 필요합니다.
(크로스 케이블 제작 방법 : http://forum.falinux.com/zbxe/index.php?document_srl=445420&mid=network_programming )
(일부 아파트의 경우 인터넷 단자함에 이미 스위칭 장비가 설치되어 있는 경우가 있습니다. 이를 활용하셔도 됩니다.)
네트워크 구성도는 다음과 같습니다. (발로 그려도 이거보단 잘 그릴지도...ㅠ)
리눅스 장비의 한 인터페이스는 외부 인터넷과 연결되어 있어야 하며, 여기서는 해당 장비를 eth0 이라 표기하였습니다.
리눅스 장비의 다른 한 인터페이스는 내부망, 즉 스위칭 장비와 크로스 케이블로 연결되어 있어야 하며 여기서는 해당 장비를 eth1 이라 표기하였습니다.
내부망에 사용될 장비들은 스위칭 장비의 나머지 포트들에 연결 하시면 됩니다.
이제 네트워크를 위와 같이 구성하셨다는 가정하에 본격적으로 설정을 시작해 보도록 하겠습니다.
첫째로 iptables 설정을 위한 스크립트를 만들어 보도록 하겠습니다.
[ IPTABLES 설정 하기 ]
먼저 터미널을 여신 후 (GNOME 환경 기준 단축키 : Ctrl+Alt+T)
sudo gedit /etc/iptables.sh
를 입력하여 제가 미리 구성해 놓은 기본틀인 아래의 스크립트를 넣어 주신후 저장 버튼을 눌러줍니다.
Applying Variables는 각자 환경에 맞게 설정해 주시기 바랍니다.
(OUTTER_INT 는 외부망과 연결되어 있는 인터페이스, INNER_INT 는 내부망과 연결되어 있는 인터페이스에 해당하고 INNER_NET은 내부 네트워크 대역에 해당합니다.)
또한 ## 연두색 글자 로 설명해 놓은것들을 참고하여 각자 원하는 대로 설정을 해주시기 바랍니다.
※ 참고로 네트워크 통신 특성상 내부망에 있는 두 장비간의 연결은 Linux 장비를 거치지 않기 때문에 해당 장비에서 별다른 설정이 없을 경우 차단되지 않습니다. (내부망의 장비와 Linux 장비간의 통신은 차단됩니다.)
※ 본 작업을 SSH 연결을 통해 작업하실 경우 기본 DROP 정책에 의해 SSH 연결이 차단됩니다!
>>>>>>>>스크립트 시작<<<<<<<<
#!/bin/bash
## 현재 스크립트가 루트/sudo 권한으로 실행중인지 체크하고 그렇지 않을 경우 에러 메세지를 표시합니다.
echo [*] Checking if run on the root...
if [ `whoami` != root ]; then
echo [!] Error : Please run this script as root or using sudo!!
exit 1
fi
echo [*] Setting Up IPTABLES Rules...
echo [*] Applying Variables...
OUTTER_INT=eth0
INNER_INT=eth1
INNER_NET=192.168.10.0/24
## 외부 IP 주소를 얻어옵니다. (이유는 NAT 정책에 설명해 놓은 글을 참고하시기 바랍니다.)
## ifconfig 출력 화면을 활용하여 현재 외부망으로 연결되어있는 인터페이스로 부터 외부 IP 주소를 얻어옵니다.
## 현재 IP주소는 root 계정의 홈폴더에 myip 라는 파일에 저장됩니다.
echo [*] Getting current ip address from Outter Interface...
ifconfig $OUTTER_INT > $HOME/myip.tmp1
sed "s/Bcast:/\n/" < $HOME/myip.tmp1 > $HOME/myip.tmp2
head -2 $HOME/myip.tmp2 | tail -1 > $HOME/myip.tmp3
sed "s/ \ \ \ \ \ \ \ \ \ inet\ addr://" < $HOME/myip.tmp3 > $HOME/myip
rm -rf $HOME/myip.tmp*
IP=$(cat $HOME/myip)
## 현재 iptables에 설정 되어 있는 항목들을 지웁니다.
echo [*] Flushing current iptables rules...
### Flush ###
iptables -F
iptables -F -t nat
iptables -X
## FTP Passive 모드 작동을 위한 모듈이 로드되어 있을 경우 해제합니다.
modprobe -r ip_conntrack_ftp
## iptables 기본 정책들을 DROP으로 설정합니다. 이로써 허용한 패킷들 외에는 모두 차단됩니다.
echo [*] Changing default policy to DROP...
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
## INPUT 정책을 설정합니다.
echo [*] Applying INPUT rules...
### INPUT ###
## Check Packets
## 들어온 패킷이 정상적으로 연결을 맺은 패킷이 아닐경우 차단합니다.
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
## Anti Spoofing
## 내부 주소로 부터 IP 스푸핑이 되는 것을 방지합니다.
iptables -A INPUT -i $INNER_INT ! -s $INNER_NET -j DROP
## Accept
## 외부와 통신하기 위한 포트 번호들을 설정합니다.
## 다른 포트 번호 추가시 -p tcp 또는 -p udp 를 지정한 후 --sport 뒤의 포트 번호를 수정하여 추가해주시면 됩니다.
## 1443은 금융사이트 이용시 TouchEn key 라는 키보드 보안 프로그램을 위한 포트번호입니다. 해당 포트 번호가 차단되어 있을 경우 금융사이트를 원활히 이용하실 수 없습니다.
## 각 포트 번호들에 설명은 Forward 정책에 표시해 뒀으니 참고하시기 바랍니다.
iptables -A INPUT -p tcp ! -s $IP --sport 20 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 21 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 80 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 443 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 465 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 993 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 1443 -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp ! -s $IP --sport 53 -d $IP --dport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp ! -s $IP --sport 123 -d $IP --dport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # from other to here
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT # from here to other
## OUTPUT 정책을 설정합니다. 기본 구조는 INPUT과 비슷하나 출발지와 목적지만 반대로 되어있다고 보시면 됩니다.
## 포트번호 추가시 INPUT 정책과 비슷한 방식으로 ACCEPT 부분에 -p tcp 또는 -p udp 지정 후 --dport 뒤의 포트 번호를 수정하여 추가해 주시면 됩니다.
echo [*] Applying OUTPUT rules...
### OUTPUT ###
## Check Packets
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
## ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 20 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 21 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 80 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 443 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 465 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 993 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s $IP --sport 1024:65535 ! -d $IP --dport 1443 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p udp -s $IP --sport 1024:65535 ! -d $IP --dport 53 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p udp -s $IP --sport 1024:65535 ! -d $IP --dport 123 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT # from other to here
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT # from here to other
## FTP Passive 모드와 통신하기 위한 모듈을 로드합니다.
echo [*] Loading FTP Passive Connection Tracking Module...
### Load FTP Passive Connection Tracking Module ###
modprobe ip_conntrack_ftp
## Forward 정책을 설정합니다.
## 마찬가지로 포트번호 추가시 ACCEPT 부분에 -p tcp 또는 -p udp 지정 후 --dport 뒤의 포트 번호를 수정하여 추가해 주시면 됩니다.
echo [*] Applying Forward rules...
### Forward ###
## Check Packets
iptables -A FORWARD -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
## Anti Spoofing
iptables -A FORWARD -i $INNER_INT ! -s $INNER_NET -j DROP
## ACCEPT
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 20 --syn -m state --state NEW -j ACCEPT # ftp-control
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 21 --syn -m state --state NEW -j ACCEPT # ftp-data
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 80 --syn -m state --state NEW -j ACCEPT # http
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 443 --syn -m state --state NEW -j ACCEPT # https
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 465 --syn -m state --state NEW -j ACCEPT # smtp-ssl
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 993 --syn -m state --state NEW -j ACCEPT # imap-ssl
iptables -A FORWARD -p tcp -i $INNER_INT -s $INNER_NET --dport 1443 --syn -m state --state NEW -j ACCEPT # TouchEn key
iptables -A FORWARD -p udp -i $INNER_INT -s $INNER_NET --dport 53 -m state --state NEW -j ACCEPT # dns
iptables -A FORWARD -p udp -i $INNER_INT -s $INNER_NET --dport 123 -m state --state NEW -j ACCEPT # ntp
iptables -A FORWARD -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -j ACCEPT
echo [*] Applying NAT rules...
### NAT ###
## 외부 주소를 내부 주소로 변환해 주기 위한 NAT 설정을 합니다.
## 보통 대부분 외부 주소는 부팅시 마다 IP 주소가 바뀌는 유동 IP로 지정되기 때문에 MASQUERADE 옵션을 사용하는데, 이 옵션은 대신에 CPU의 사용량이 많아 지게 집니다.
## 이렇게 되면 사양이 낮은 임베디드 장비의 경우 CPU 부하로 인해 인터넷 속도가 떨어지는 현상이 발생합니다.
## 따라서 저는 대신에 위에서 외부 IP 주소를 얻어오는 스크립트를 적용하였고 SNAT 옵션으로 외부 IP 주소를 고정적으로 설정하여 CPU 부하를 줄였습니다.
iptables -t nat -A POSTROUTING -s $INNER_NET -o $OUTTER_INT -j SNAT --to-source $IP
## 공유기 설정을 위한 IP 포워딩 설정을 해줍니다. 이로써 외부주소를 내부주소로 변환하는 작업이 가능해 집니다.
echo [*] Enabling IP fowarding...
### Enable IP Forwading ###
echo 1 > /proc/sys/net/ipv4/ip_forward
echo [*] Setting Up IPTABLES Rules Finished!!!
exit 0
>>>>>>>>스크립트 끝<<<<<<<<
추가 옵션들 예제... (포트포워딩 및 기타 옵션들...)
== 외부로 부터 Linux 장비(내부주소 192.168.10.1)로 1111 포트 번호를 통한 SSH 연결을 설정할 경우 ==
( 1111 을 원하는 포트 번호로 수정, 내부 SSH 사용 포트번호는 22 라 가정 )
## INPUT 정책 마지막에 다음 라인들 추가
iptables -A INPUT -p tcp ! -s $IP --sport 1024:65535 -d $IP --dport 1111 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 1024:65535 -d 192.168.10.1 --dport 22 --syn -m state --state NEW -j ACCEPT
## OUTPUT 정책 마지막에 다음 라인들 추가
iptables -A OUTPUT -p tcp -s $IP --sport 1111 ! -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s 192.168.10.1 --sport 22 ! -d 192.168.10.1 --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
## FORWARD 정책 마지막에 다음 라인 추가
iptables -A FORWARD -p tcp --dport 1111 --syn -m state --state NEW -j ACCEPT
## NAT 정책 마지막에 다음 라인 추가
iptables -t nat -A PREROUTING -p tcp -d $IP --dport 1111 -j DNAT --to 192.168.10.1:22
== 외부로 부터 내부에 있는 192.168.10.100 으로 2222 포트번호를 통한 원격 데스크톱 연결 을 설정할 경우 ==
( 2222 를 원하는 포트 번호로 수정, 내부 원격 데스크톱 연결 사용 포트번호는 3389 라 가정 )
## INPUT 정책 마지막에 다음 라인들 추가
iptables -A INPUT -p tcp ! -s $IP --sport 1024:65535 -d $IP --dport 2222 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp ! -s $IP --sport 1024:65535 -d 192.168.10.100 --dport 3389 --syn -m state --state NEW -j ACCEPT
## OUTPUT 정책 마지막에 다음 라인들 추가
iptables -A OUTPUT -p tcp -s $IP --sport 2222 ! -d $IP --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -s 192.168.10.100 --sport 3389 ! -d 192.168.10.100 --dport 1024:65535 --syn -m state --state NEW -j ACCEPT
## FORWARD 정책 마지막에 다음 라인들 추가
iptables -A FORWARD -p tcp --dport 2222 --syn -m state --state NEW -j ACCEPT
iptables -A FORWARD -p tcp -d 192.168.10.100 --dport 3389 --syn -m state --state NEW -j ACCEPT
## NAT 정책 마지막에 다음 라인들 추가
iptables -t nat -A PREROUTING -p tcp -d $IP --dport 2222 -j DNAT --to 192.168.10.100:3389
iptables -t nat -A POSTROUTING -p tcp -o $INNER_INT -s $INNER_NET -d 192.168.10.100 --dport 3389 -j SNAT --to 192.168.10.1 ## 내부망에서도 외부주소를 통한 접속이 가능해지도록 합니다.
== Linux 장비에 MySQL / php5-fpm 을 설치하여 사용하고자 할때 ==
( 설치형 블로그나 설치형 사이트 설정시 MySQL 주소는 127.0.0.1 로 지정해 주시면 정상 작동합니다.)
( 같은 방식으로 php5-fpm 모듈 사용시 3306 을 9000 으로 변경하여 추가해 주시면 됩니다.)
## INPUT 정책 마지막에 다음 라인 추가
iptables -A INPUT -p tcp -s 127.0.0.1 --sport 1024:65535 -d 127.0.0.1 --dport 3306 --syn -m state --state NEW -j ACCEPT
## OUTPUT 정책 마지막에 다음 라인 추가
iptables -A OUTPUT -p tcp -s 127.0.0.1 --sport 1024:65535 -d 127.0.0.1 --dport 3306 --syn -m state --state NEW -j ACCEPT
== Linux 장비에 xrdp 를 설치 할 경우 내부적으로 추가해 줘야 할 사항 ==
## INPUT 정책 마지막에 다음 라인들 추가
iptables -A INPUT -p tcp -s 127.0.0.1 --sport 1024:65535 -d 127.0.0.1 --dport 3350 --syn -m state --state NEW -j ACCEPT # xrdp-sesman
iptables -A INPUT -p tcp -s 127.0.0.1 --sport 1024:65535 -d 127.0.0.1 --dport 5910:5999 --syn -m state --state NEW -j ACCEPT # xrdp-sesman-xvnc
## OUTPUT 정책 마지막에 다음 라인들 추가
iptables -A OUTPUT -p tcp -s 127.0.0.1 --sport 1024:65535 -d 127.0.0.1 --dport 3350 --syn -m state --state NEW -j ACCEPT # xrdp-sesman
iptables -A OUTPUT -p tcp -s 127.0.0.1 --sport 1024:65535 -d 127.0.0.1 --dport 5910:5999 --syn -m state --state NEW -j ACCEPT # xrdp-sesman-xvnc
== 그외 포트 번호들... ==
U+ 고객센터 모바일 앱 : 210.124.165.18 / TCP 39080, TCP 39043
멜론 모바일 앱, 멜론 윈도8 앱 로그인 : TCP 4554
카트라이더 서버와의 통신 : TCP 39311, UDP 39311
카트라이더 실행시 Check ID : TCP 47611
Touch Enkey : TCP 1443
입맛대로 설정하고 저장을 완료하셨으면 터미널에 다음 명령어를 입력하여 iptables.sh 파일에 실행권한을 부여해 줍니다.
sudo chmod +x /etc/iptables.sh
다음으로 인터페이스 설정을 해보도록 하겠습니다.
우분투, 데비안 기준으로
sudo gedit /etc/network/interfaces
를 쳐서 인터페이스 설정 파일을 열고 다음과 같이 수정해 줍니다.
(Redhat 기반 배포판의 경우 설정 방법이 다르므로 인터넷 검색을 통해 참고해 주시기 바랍니다.)
(eth0, eth1 부분은 각자 환경에 맞게 적용해 주시기 바랍니다.)
(아래 설정파일을 열어서 인터페이스 설정을 수동으로 해주실 경우 network-manager 패키지가 설치되어 있을 경우 충돌이 일어나므로 해당 패키지를 제거해 주셔야 합니다.
$ sudo apt-get purge network-manager
명령어를 통해 해당 패키지를 제거해 주시면 됩니다.)
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet static
address 192.168.10.1
netmask 255.255.255.0
network 192.168.10.0
다음으로 iptables 설정 스크립트가 부팅시 자동으로 실행되도록 하기 위해 rc.local 파일을 열어 다음과 같이 수정해 줍니다.
우분투, 데비안 기준으로
(배포판에 따라 부팅스크립트 위치가 다를 수 있습니다.)
sudo gedit /etc/rc.local
로 해당 파일을 여신 후
/etc/iptables.sh
를 exit 0 이라 써있는 라인 위에 추가해 주시면 됩니다.
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
bash /etc/iptables.sh
exit 0
sudo bash /etc/iptables.sh
명령어만 입력해 주시면 됩니다.
위 명령어를 매번 치는것이 불편하시다면
$ echo "alias firewall='sudo bash /etc/iptables.sh'" >> .bashrc
명령을 실행하시고 $ bash 를 쳐서 bash 쉘을 다시 띄우시면 다음부터는
$ firewall
만의 입력으로도 바로 적용시킬 수 있습니다~^^
여기 까지 iptables 를 설정 하시느라 수고 많으셨습니다...^^
실제론 저 명령어들을 하나하나 입력하는 것이 만만치 않지만;; 제가 미리 써드린 스크립트를 활용하여 쉽게 적용하실 수 있으리라 생각합니다...^^
다음 편에선 내부망에 연결된 장비들에게 자동으로 내부 IP 주소를 부여해 줄 수 있도록 dhcpd 를 설정해 보도록 하겠습니다.