iptables 

Linux 커널 2.2 에는 ipchains 이라는 패킷 필터링/방화벽 프레임워크가 구현되어 있었고 2.4부터는 더 유연하고 다양한 기능을 가진 netfilter 로 기능이 교체 되었다.

iptables 는 netfilter 프레임워크의 최상단에 위치하는 사용자 레벨의 프로그램으로 관리자는 이를 이용하여 리눅스 서버로 들어오고 나가는 패킷을 필터링하거나 포트 포워딩을 설정할 수 있으며 방화벽으로도 사용할 수 있다.

본 절에서 iptables 을 다루는 이유는 뒷 장에서 다룰 서비스 프로그램을 설치하고 설정할 때 iptables 명령어로 서비스 포트를 열어 주는 작업이 필요하기 때문이며 이를 위한 iptables 의 구성과 주요 기능들을 알아보도록 하자.

 

구성 요소

리눅스 커널에 탑재되어 있는 netfilter는 테이블(talbe) 또는 정책 목록(rules lists) 이라 불리우는   다섯 가지의 패킷 필터링 설비를 갖고 있다.

  • filter
    네트워크 패킷을 처리하기 위한 기본 테이블로  INPUT, OUTPUT, FORWARD 세 개의 내장 체인을 갖고 있다.
  • nat
    네트워크 주소 변환(NAT- Network Address Translation) 을 처리하기 위한 테이블이다.
  • mangle
    특별한 패킷(TCP 헤더의 QOS 비트등)을 변경하는데 사용되는 테이블이다.
  • raw
    테이블의 연결 추적 기능을 더 상세하게 처리할 수 있으며 특정 패킷은 추적하지 않는 등의 설정이 가능한 테이블이다.
  • security 
    SELinux 의 강제 접근 통제(MAC - Mandatory Access Control)를 지원하기 위한 정책이다.

각각의 테이블은 내장된 체인 그룹을 갖고 있으며  각 체인은 패킷과 일치하는 규칙의 목록이다. filter 테이블은 다음 세 가지 체인을 갖고 있다.

  • INPUT
    목적지가 iptables 이 구동되는 현재 리눅스 박스인 네트워크 패킷에 대해서 적용된다.
  • OUTPUT
    리눅스 박스 내에서 생성된 외부로 나가려는 로컬 패킷에 대해서 적용되는 체인이다.
  • FORWARD
    리눅스 박스 밖으로 전달되는 패킷에 대해서 적용된다.

패킷이 테이블내 특정 규칙과 일치할 경우 목적지와 상관없이 특정 행동을 수행하도록 지정할 수 있으며 이를 타겟이라고 한다.  타겟은 다음과 같은 종류가 있다.

  • ACCEPT - 패킷을 목적지로 보내는 것을 허용한다. INPUT 체인일 경우 해당 포트를 리슨하는 프로그램에 전달되며 OUTPUT 체인일 경우 목적지 서버로 전송된다.
  • DROP - 목적지로 가는 것을 차단하고 패킷을 버리며 패킷의 송신자에게 아무 응답도 보내지 않는다.
  • REJECT - 목적지로 가는 것을 차단하고 패킷을 버리지만 송신자에게 에러 패킷을 전송한다. REJECT 시 기본적으로 송신자에게 icmp-port-unreachable 이 전달되며 --rejct-with 옵션 뒤에 송신할 ICMP 에러 유형을 지정할 수 있으며 icmp-net-unreachable, icmp-host-unreachable,icmp-proto-unreachable, icmp-net-prohibited 등을 설정할 수 있다.
  • QUEUE  - 사용자 스페이스로 패킷을 전달한다.

이제 넷필터에 대한 기본적인 지식을 익혔으니 이를 기반으로 iptables 의 설정 내용을 살펴 보자.


설정 파일

iptables 의 필터와 체인 설정은 /etc/sysconfig/iptables 파일을 통해 수정하며 IPV6 용 설정은 /etc/sysconfig/ip6tables 파일이다. iptables 는 부팅시 init 이 실행하는 script 이므로 설정이 변경되면 service 명령으로 재구동하여야 반영된다.

IPV4 용 설정 파일인  /etc/sysconfig/iptables 를 에디터로 열어보면 다음과 같은 형식으로 구성되어 있다.

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
BASH

iptables 설정 파일의 각 항목의 의미와 용도를 간략하게 살펴 보도록 하자. 

  • *filter
    필터 테이블을 사용하겠다는 의미로 명령행에서는 -t filter 와 동일하며 -t 옵션을 주지 않으면 기본적으로 필터 테이블을 사용한다. 파일을 통해 테이블을 설정할 경우 테이블 이름앞에 * 를 붙여준다.
  • :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0]
    세 개의 체인을 정의하는 명령어로 체인 이름 앞에는 : 을 붙여서 기술하며 ACCEPT 이므로 체인내 모든 액션을 허용하게 된다. 체인내 모든 룰은 "일치한 패킷의 수" 와 "일치한 패킷 바이트" 두 개의 카운터를 갖게 되며 대괄호 안의 숫자([0:0]는 카운터를 0 으로 리셋한다는 의미이다. iptable 의 현재 설정과 카운터는 iptables-save 명령어로 저장할 수 있으며 저장된 설정과 카운터는 iptables-restore 명령어로 복구할 수 있다.
  • -A(append) INPUT
    기존 룰에 추가한다는 의미이며 뒤에는 추가할 룰 이름을 기술한다. 예제에서는 INPUT 이라는 이름의 정책에 추가하겠다는 의미이다.
  • -m(match) 
    -m 은 패킷을 처리할 때 특정 상태나 프로토콜등과 일치하는지 여부를 판단하기 위해 사용하는 옵션으로 다음과 같은 설정이 가능하다.
    • -s, --source address[/mask]
      출발지 IP 주소나 네트워크와의 일치하는지 확인한다. -s 뒤에 출발지 IP 를 기술하며 대역폭으로 설정할 경우 192.168.152.0/24 또는 192.168.152.0/255.255.255.0 으로 기술할 수 있다.

    • -d, --destination
      목적지의 ip주소나 네트워크와 일치하는지 확인하며 -s 와 마찬가지로 목적지의 IP 를 기술하며 대역폭을 지정할 수도 있다.

    •  -p, --protocol protocol
      프로토콜과 일치 여부를 확인하며 프로토콜 이름을 적어주면 된다. 이름은 tcp, udp, icmp 등을 설정할 수 있으며 all 로 설정하면 모든 프로토콜에 해당된다.

    • -j, --jump target
      패킷이 정책과 일치할 경우 실행할 타겟을 지정하며 -j REJECT 는 일치하는 패킷은 REJECT 하겠다는 의미이다.

    • -i, --in-interface name
      패킷이 수신되는 네트워크 인터페이스(이더넷 카드등)와 일치하는지 확인한다. -i lo 는 loop back 인터페이스(IP 127.0.0.1)에서 온 모든 패킷에 대해서 일치한다.

    • -o, --out-interface name
      패킷이 송신되는 네트워크 인터페이스(이더넷 카드등)와 일치하는지 확인한다. -o eth0 은 인터페이스 이름이 eth0 인 이더넷 카드를 통해 나가는 모든 패킷에 대해서 일치한다.

    • --state state
      연결 상태와 일치하는지 확인하며 state 에는 다음  4가지 상태가 지정 가능한다.
      ESTABLISHED
      상대방과 양방향간 소켓 연결이 구축된 상태이다.
      INVALID
      패킷이 연결되지 않았거나 ICMP 에러를 수신한 상태이다.
      NEW
      새로운 연결이 생성되거나 또는 양방향 연결이 완료되지 않은 상태이다.service.
      RELATED
      연결된 상태에서 기존 연결과 관련된 새로운 연결이 생성된 상태로 FTP 의 경우 제어 포트(21)로 명령을 보내고 전송시에는 별도의 포트를 생성하므로 이 때 RELATED 상태가 된다. 보통 -A INPUT -m state --state ESTABLISHED,RELATED 처럼 두 개의 상태를 묶어서 정책을 만들게 된다.

 

이제 설정 파일에 기술된 항목들의 의미를 분석해 보자.

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT                             
-A INPUT -i lo -j ACCEPT

연결된 상태인 모든 패킷을 허용하고 (첫 줄) 프로토콜 유형이 icmp 인 패킷을 허용하고 (두번째 줄) 루프백 인터페이스에서 수신한 모든 패킷을 허용하겠다는 의미이다.

 

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

ssh (포트 22번) 서비스는 외부에서 내부로 연결하는 것을 허용하겠다는 의미이다. 더 안전하게 하려면 -s 옵션으로 허용할 IP 나 대역을 지정해 주면 된다. 여러 개의 IP 를 지정할 경우 여러 줄에 걸쳐서 기술해야 한다.

다음은 IP 가 192.168.152.10과 192.168.152.20 에서만 SSH 연결을 할 수 있는 iptables 설정이다.

-A INPUT -m state --state NEW -s 192.168.152.10 -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -s 192.168.152.20 -m tcp -p tcp --dport 22 -j ACCEPT

 

다음은 INPUT 체인의 나머지 모든 포트는 REJECT 타겟을 적용하며 송신자에서 전송할 ICMP 에러 유형으로 icmp-host-prohibited 을 사용하고 포워딩 체인의 모든 패킷도 REJECT 하겠다는 의미이다. 

설정이 끝났으면 COMMIT 명령어를 실행해야 iptables 정책에 반영된다.

-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

ACCEPT 타겟에 지정한 SSH 서비스 외의 모든 TCP/UDP 포트는 외부에서 이 서버로 연결이 불가능하다.

http/https 와 같은 서비스 데몬을 설치했을 경우 다음과 같이 /etc/sysconfig/iptables 에 INPUT 체인에 서비스의 프로토콜과 포트를 추가해 주고 ACCEPT 타겟을 지정한 해야 외부에서 이 서버로 연결이 가능하다.

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

설정을 변경했다면 iptables 를 재시작해야 하며 service iptables restart 명령으로 변경된 설정을 바로 적용할 수 있다.

 

lokkit

lokkit 는 커맨드 라인용 iptable 설정 유틸리티이다. /etc/sysconfig/iptables 을 에디터로 수정하여 변경하는 것은 번거롭고 실수할 여지가 크므로 lokki 을 사용하면 손쉽게 방화벽 정책을 수정할 수 있게 해준다.

lokkit 명령어 뒤에 옵션을 주어서 실행할 수 있으며 주요 옵션은 다음과 같다.

  • -n, --nostart
    lokkit 로 설정하면 iptables 도 자동으로 재시작한다. lokkit 로 설정시 -n 나 --nostart  옵션을 주면 설정 파일만 변경하고 iptables 를 재시작하지는 않는다.
  • --update
    --update 옵션을 주면 iptables 를 재시작해 변경을 반영한다.


Service 목록 보기

 --list-services 옵션을 주고 실행하면 lokkit 가 변경할 수 있는 있는 전체 서비스 목록을 볼 수 있으며 : 을 구분자로 하여 좌측은 서비스명이고 우측은 서비스의 설명이 표시된다.

# lokkit --list-services

기본값 환경으로 사전 정의된 서비스:
ipp-client: 네트워크 인쇄 클라이언트 (IPP)
default: desktop
ipp: 네트워크 인쇄 서버 (IPP)
mdns: mDNS (Multicast DNS)
default: desktop
ipsec: IPsec
default: desktop
ssh: SSH
default: server
http: WWW (HTTP)
ftp: FTP
nfs: NFS4
https: 보안 WWW (HTTPS)
smtp: 메일 (SMTP)

 

서비스 포트 오픈

-s 옵션뒤에 서비스명을 적어주면 서비스 포트를 열수 있다. 다음은 ssh 와 http/https 를 여는 예제이다. -v 옵션을 추가하면 실행시 자세한 정보를 볼 수 있다.

# lokkit -s ssh -s http -s https

 

서비스 포트 닫기

현재 lokkit 는 서비스 포트 닫는 옵션을 제공하지 않는다. 오픈한 서비스의 포트를 닫으려면 직접 /etc/sysconfig/iptables 파일의 설정을 수정하고 다음 명령어로 iptables 를 재구동해야 한다.

service iptables restart