Skip to content

Iptables

iptables is a user-space application program that allows a system administrator to configure the tables provided by the Linux kernel firewall (implemented as different Netfilter modules) and the chains and rules it stores. Different kernel modules and programs are currently used for different protocols; iptables applies to IPv4, ip6tables to IPv6, arptables to ARP, and ebtables to Ethernet frames.

Categories

  • netfilter
  • iptables/ip6tables
  • iptables-apply - a safer way to update iptables remotely
  • iptables-nft-save
  • iptables-save - dump iptables rules - 규칙을 저장할 때 사용하며, 보통 /sbin/iptables-save에 위치한다.
  • iptables-nft - iptables using nftables kernel api
  • iptables-restore - Restore IP Tables
  • iptables-translate
  • iptables-nft-restore
  • iptables-restore-translate
  • iptables-xml

About

리눅스 커널에는 IP 패킷 필터링 프레임워크 Netfilter와 이를 이용하기 위한 커맨드라인 프론트엔트 iptables/ip6tables가 준비되어 있다.

IP 패킷 필터링은 IP 패킷의 헤더를 참조하여 통과/파기/전송 등의 처리를 하는 것을 말한다. iptables를 이용하여 아래와 같은 네트워크 환경을 구축할 수 있다.

  • 파일 필터링으로 한 대의 호스트를 요새화
  • 인터넷과 LAN을 연결하나 인터넷에서 LAN 호스트를 감춤
  • LAN 호스트에서 인터넷으로의 접속성을 확보하고 출발지 주소를 변환
  • LAN의 특정 호스트에 패킷을 전송
  • 한정적 기능이기는 하나 로드밸런싱, 부하 분산

Terms

마스커레이드 (Masquerade)
내부 사설 IP의 PC들이 외부 인터넷이 연결 가능하도록 해주는 기능
NAT(Network Address Translation) : 네트워크 주소 변환 서비스
SNAT(Source NAT) : 내부 사설IP에서 외부로 나갈 때 공인IP로 변환 -> 마스커레이드와 비슷
DNAT(Destination NAT) : 외부에서 방화벽(외부IP)으로 요청되는 주소로 내부사설IP로 변환

What is packet filtering

패킷필터링은 지나가는 패킷의 해더를 보고 그 전체 패킷의 운명을 결정하는 것을 말한다.

(iptables의 경우 많은 개발중인 기능에서 헤더에 그치지 않고 data의 내용을 검토하기도 한다. 가장 대표적인것이 string match기능이다.)

iptables vs netfilter

iptables가 패킷을 필터링 하는것이 아니라 커널에 탑제된 netfilter기능이 실제로 필터링 하며,

iptables은 단지 netfilter에 룰을 세워줄 뿐이다. 즉 다시 말하자면 iptables은 룰-셋 구축 툴 이다.

최신 버전은 여러 기능을 통합하여 nftables를 사용한다지만 현업에서는 여전히 iptables를 많이 사용하는듯.

Packet Flow

Packet_flow_in_Netfilter_and_General_Networking_-_Simple.png

간단한 버전

Packet_flow_in_Netfilter_and_General_Networking.png

복잡한 버전

Install

이제 iptables-persistent 패키지를 설치합니다. 이를 통해 규칙 세트를 저장하고 부팅 시 자동으로 적용되도록 할 수 있습니다.

apt-get install -y iptables iptables-persistent

netfilter-persistentiptables-persistent를포함하여netfilter프레임워크의 규칙을 관리하는 도구입니다.iptables-persistent와함께ip6tables규칙을 관리할 수도 있습니다. <- 확인 필요.

서비스 재기동:

systemctl daemon-reload
systemctl enable iptables.service
systemctl start iptables.service

설치하는 동안 현재 규칙을 저장할 것인지 묻는 메시지가 나타나면 <예>를 선택합니다.

iptables 영구 방화벽 서비스를 실행하기 위해 netfilter-persistent 명령을 실행하게 됩니다. 다음으로 생성된 규칙 파일을 편집합니다.

시작하기 전에 IPv4와 IPv6에 대해 간략하게 설명하겠습니다. iptables 명령은 IPv4 트래픽만 처리합니다. IPv6 트래픽의 경우 ip6tables라는 별도의 동반 도구가 사용됩니다. 규칙은 별도의 테이블과 체인에 저장됩니다.

netfilter-persistent 명령의 경우

  • IPv4 규칙은 /etc/iptables/rules.v4 에서 쓰고 읽으며
  • IPv6 규칙은 /etc/iptables/rules.v6 에 저장됩니다.

서비스에서 IPv6를 활용하지 않는 경우 이 가이드에서 설명하는 것처럼 액세스를 완전히 차단하는 것이 더 안전합니다.

관련 스크립트는 /usr/share/netfilter-persistent 에도 있다.

  • /usr/share/netfilter-persistent/plugins.d/15-ip4tables start
  • /usr/share/netfilter-persistent/plugins.d/25-ip6tables start

주석 입력 방법

주석(Comment)는 #를 사용하긴 하는데 라인의 첫 글자부터 주석으로 만들어야 한다. 라인 끄트머리에 넣으면 안된다.

라인 끄트머리에 넣고싶다면 코맨트 모듈을 써야 한다.

... -m comment --comment "주석 입력할 내용"

기본값

sudo iptables -L

규칙 없이 모두 ACCEPT 상태 이다:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

살짝 널널한 보안 기본값

FORWARD와 OUTPUT은 기본 허용. INPUT을 제한한다.

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p udp --sport 123 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22   -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 6443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited

COMMIT

Rule

규칙 = 매칭 + 타깃

규칙 작성은 패킷 헤더의 추출(매칭)과 해당 패킷의 처리(타킷)를 정의하는 것을 말한다. 규칙 포맷은 다음과 같다.

$ iptables -A <체인> <매칭 옵션> -j <타깃>

Simple Example

$ iptables -A INPUT -s 192.168.2.0/24 -d 192.168.2.1 -p TCP --dport 22 -j ACCEPT
  • -AINPUT 체인에 규칙을 추가한다.
  • -s로 출발지 IP주소를 지정한다.
  • -d로 도착지 IP주소
  • -pTCP 프로토콜을 지정
  • --dport로 도착지 포트
  • -j로 타깃에 ACCEPT를 지정하여 매치된 패킷을 통과시킨다.

출발지 IP주소인 192.168.2.0/24의 네트워크 주소에 속하는 호스트로부터 도착지 IP주소인 192.168.2.1 주소를 가진 호스트의 22/TCP로의 접근을 지정하고 있다.

Table

테이블 = 체인 + 체인

특별히 -t로 테이블을 지정하지 않는 경우 filter 테이블이 생성된다. 테이블은 다음과 같다.

테이블

목적

이용 가능한 표준 체인

filter

목적 패킷을 필터링

INPUT, OUTPUT, FORWARD

nat

출발지 또는 도착지 주소를 변환

OUTPUT, PREROUTING, POSTROUTING

mangle

TTL 등 패킷 헤더를 수정

INPUT, OUTPUT, PREROUTING, POSTROUTING

raw

연결 추적을 하지 않는 변환 실시

OUTPUT, PREROUTING

  • 패킷 헤더 수정 등이 필요하지 않으면 filter와 nat 테이블만으로도 충분하다.
  • filter 테이블은 INPUT과 OUTPUT과 FORWARD 체인을 이용하여 ACCEPT/ DROP 등의 필터링을 실시한다.
  • nat 테이블은 NAT(Network Address Translation)을 실시하여 출발지나 도착지 주소를 변환한다.
  • mangle 테이블은 TTL(Time To Live, 라우터를 거칠 때마다 감소하는 패킷 생존수치) 값을 조정하여 LAN에서 얼마 만큼의 라우터를 거쳤는가 등의 정보들을 외부 네트워크로 새어나가지 않도록 막거나 TOS 타깃을 이용해 라우팅할 곳을 조정한다.

Chain

체인 용도 설명은 다음과 같다.

Chain INPUT
서버로 들어오는 기본 정책
Linux Server를 목적지로 삼는 모든 패킷은 INPUT Chain을 통과한다.
Chain FORWARD
서버에서 Forwarding 기본 정책
FORWARD Chain의 경우 현재의 Linux Server가 목적지가 아닌 패킷이 통과하는 Chain이다.
FORWARD Chain은 NAT기능 사용을 위해 사용된다.
Chain OUTPUT
서버에서 나가는 기본 정책
Linux Server에서 생성되 외부로 보내지는 모든 패킷은 OUTPUT Chain을 통과하게 된다.
PREROUTING
입력 전에 패킷을 변환한다.
POSTROUTING
입력 후에 패킷을 변환한다.

체인은 사용자가 독자적으로 만들 수 있다.

  • <coed>-N</code>으로 사용자 정의 체인을 만들고 이를 -A로 지정, 패킷 매칭과 타깃을 지정한다.
  • 표준 타깃을 지정하는 <coed>-P</coed>는 기본 내장 체인(INPUT, OUTPUT, FORWARD, PROROUTING, POSTROUTING)만 이용할 수 있다.
  • 사용자가 독자적으로 체인을 만들 때에는 가장 마지막에 DROP이나 REJECT를 지정해야 한다.

체인 작성 예는 다음과 같다.

$ iptables -N tcp-allow   # tcp-allow 체인 생성

$ iptables -A tcp-allow -p TCP --syn -j ACCEPT
$ iptables -A tcp-allow -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$ iptables -A tcp-allow -j DROP   # tcp-allow 체인 종료

$ iptables -A INPUT -p ICMP -j ACCEPT
$ iptables -A INPUT -p TCP -j tcp-allow   # tcp-allow 체인 호출

Target

타깃으로 이용할 수 있는 파라미터는 다음과 같다.

  • ACCEPT - 허용
  • DROP - 파기
  • REJECT - 거부 (DROP과 비슷하지만, ICMP 에러 응답을 전송한다. DDoS를 방지하고 싶다면 REJECT 보다는 DROP을 추천)
  • MASQUERADE - (마스커레이드) 출발지 IP와 포트번호를 자동변환 (내부 사설 IP의 PC들이 외부 인터넷이 연결 가능하도록 해주는 기능)
  • SNAT - 출발지 IP 주소 변환
  • DNAT - 목적지 IP 주소 변환
  • LOG - 로그 출력
  • QUEUE - 사용자 공간으로 패킷을 들여보냄
  • RETURN - 체인 종료

MASQUERADE

내부 웹사이트로 MASQUERADE하기.

iptables -t nat -A PREROUTING -m tcp --dport 80 -j DNAT --to 192.168.200.100:80

출발지 IP와 포트번호를 자동변환 (내부 사설 IP의 PC들이 외부 인터넷이 연결 가능하도록 해주는 기능)

PREROUTING은 들어오는 패킷에 대해서 매스쿼레이드를 할 때 사용하는 체인입니다. DNAT은 SNAT의 반대 기능을 합니다. SNAT은 출발지 소스를 바꿔주지만, DNAT은 목적지를 바꿔주는 타겟이라고 보시면 됩니다.

Options

  • -t [테이블]: 이용할 테이블을 지정한다. 기본은 filter.
  • -A [체인]:지정하는 체인에 규칙을 추가한다.
  • -D: 지정한 체인의 규칙 삭제
  • -P: 지정한 체인의 정책을 변경
  • -L [체인]: iptables 테이블의 규칙 리스트 표시
  • -N [체인]: 지정한 이름으로 사용자 정의 체인 생성
  • -X: 지정한 사용자 정의 체인 삭제
  • -I [규칙]: 번호를 지정해 규칙을 삽입
  • -F [체인]: 지정한 체인의 모든 규칙을 삭제 - WARNING !! 원격 접속했다면 통신이 안될수도 있다.
  • -t: iptables의 테이블을 지정
  • -v: 테이블의 상세한 내용을 표
  • -n: 테이블의 내용을 숫자 값으로 표시
  • -line-number: 규칙의 번호를 표시
  • -m [모듈]: 매칭 모듈을 지정한다. (addtype, conntrack, connlimit, iprange, mac, multiport, state)
    • 이 옵션 다음에 모듈별 옵션을 추가할 수 있다.
  • -p [프로토콜]: tcp/udp/icmp/all 중 하나를 지정한다. 기본은 all.
  • -d [도착지 주소]: 도착지 주소 지정
  • -s [출발지 주소]: 출발지 주소 지정
  • --dport [포트]: 도착지 포트 지정. -p tcp또는 -p udp와 함께 사용한다.
  • --sport [포트]: 출발지 포트 지정. -p tcp또는 -p udp와 함께 사용한다.
  • -i [인터페이스]: 패킷이 들어오는 네트워크 인터페이스를 지정한다.
  • -o [인터페이스]: 패킷이 나가는 네트워크 인터페이스를 지정한다.
  • -j [타깃]: #Target 항목 참조.

출발지와 목적지

옵션 중 다음의 내용:

  • -d [도착지 주소]: 도착지 주소 지정
  • -s [출발지 주소]: 출발지 주소 지정
  • --dport [포트]: 도착지 포트 지정. -p tcp또는 -p udp와 함께 사용한다.
  • --sport [포트]: 출발지 포트 지정. -p tcp또는 -p udp와 함께 사용한다.

INPUT 인가, OUTPUT 인가 에 따라 용도가 달라진다.

예를 들어 설명하면:

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

INPUT 에서의 src 는 클라이언트 dest 는 서버. 즉 192.168.0.18 서버에서 HTTP 서비스(80)를 제공하고 있으며, 모든 IP 주소에서 이 서버의 포트 80으로 들어오는 트래픽을 허용하고자 할 때 사용됩니다. 예를 들어, 웹 서버가 외부의 모든 클라이언트로부터 접속을 허용하려는 경우에 적합합니다.

iptables -A OUTPUT -s 192.168.10.10 -d 222.222.222.222 -p tcp --dport 80 -j ACCEPT

OUTPUT 에서의 src 는 서버 dest 는 클라이언트. 즉 192.168.10.10 IP를 가진 NIC에서 222.222.222.222 IP를 가진 서버의 포트 80으로 나가는 트래픽을 허용하는 설정입니다. 특정 클라이언트 프로그램에서 특정 외부 서버로의 HTTP 트래픽을 허용할 때 유용합니다.

Configuration file

  • /etc/sysconfig/iptables 확인.

Example

iptables --list or iptables -L
iptables 적용 목록 출력.
iptables -nL
iptables 적용 목록 출력. (-n 옵션은 IP 주소 및 포트를 숫자로 출력)
service iptables save
규칙 추가 후에 저장하기 (/etc/sysconfig/iptables 에 저장됨)
iptables -F
현재 iptables 규칙을 초기화 하기 - WARNING !!!!! 알지? 발할라 직행일 수 있다.
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
-A INPUT - INPUT 체인에 규칙을 추가(add)하라는 의미입니다. INPUT 체인은 들어오는 트래픽을 처리하는 데 사용됩니다.
-j REJECT - 이 규칙에 일치하는 패킷을 거부(reject)하라는 의미입니다. 즉, 패킷을 차단하지만 송신자에게 패킷이 거부되었음을 알립니다.
--reject-with icmp-host-prohibited - 패킷이 거부되었을 때 송신자에게 보낼 ICMP 메시지 유형을 지정합니다. 여기서는 "icmp-host-prohibited" 메시지를 사용하여 호스트가 접근을 허용하지 않는다는 것을 나타냅니다.
정리하면, 이 명령은 들어오는 모든 네트워크 트래픽을 거부하고, 해당 패킷의 송신자에게 "호스트 접근 금지"라는 ICMP 메시지를 보내도록 iptables에 규칙을 추가합니다. 이는 보안 강화를 위해 사용될 수 있으며, 예를 들어 허가되지 않은 트래픽을 차단하고 이에 대한 명확한 응답을 제공하는 데 유용합니다.
일반적으로 INPUT의 기본값이 ACCEPT일 경우 마지막 줄에 추가하여 필터링되지 않은 모든 패킷을 거부하기 위해 존재함.
sudo service iptables restart
sudo service ip6tables restart
sudo systemctl restart iptables
sudo systemctl restart ip6tables
IPv4와 IPv6에 대한 iptables 서비스를 재시작 한다.
iptables -P INPUT ACCEPT
INPUT 기본정책을 ACCEPT로 설정 (inbound)
iptables -P OUTPUT ACCEPT
OUTPUT 기본정책을 ACCEPT로 설정 (egress; outbound)
iptables -P FORWARD ACCEPT
FORWARD 기본정책을 ACCEPT로 설정
iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
로컬(127.0.0.1) 에서 발생하는 모든 (ICMP) 요청 (INPUT; inbound) 패킷에 대해 무시(DROP)한다.
위 규칙을 제거하고 싶다면 -A대신 -D로 적으면 된다.
iptables -D INPUT [필터링 번호]
필터링 번호로 규칙 제거. (필터링 번호는 service iptables stat을 통해 확인 가능)
iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP -j DROP
1초동안 80포트에 똑같은 IP가 10번 이상의 SYN가 들어오면 드랍시킨다. (즉, 정상적인 요청이 아닌 웹서비스 공격으로 간주하여 요청패킷을 폐기시켜 응답하지 않도록 한다.)
iptables -A INPUT -s 192.168.0.111 -j DROP
소스 ip가 192.168.0.111 인 접속의 모든 접속 포트를 막아라.
iptables -A INPUT -p icmp -s 127.0.0.1 -j DROP
INPUT 사슬에 출발지 주소가 127.0.0.1(-s 127.0.0.1) 인 icmp 프로토콜 패킷을 거부하는 정책을 추가
iptables -A INPUT -p tcp --dport 23 -j DROP
INPUT 사슬에 목적지 포트가 23번인 tcp 프로토콜 패킷을 거부하는규칙을 추가
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
INPUT 사슬에 목적지 포트 번호가 80번인 tcp 프로토콜 패킷을 받아들이는 규칙을 추가
iptables -A INPUT -p tcp --dport :1023 -j DROP
INPUT 사슬에 목적지 포트번호가 1023번 보다 작은 모든 포트에서 tcp 프로토콜 패킷을 거부하는규칙을 추가
iptables -I INPUT -p tcp --dport 21 -j ACCEPT
ftp포트(21번)를 열어라
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
http포트(80번)를 열어라.
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
https포트(443번)를 열어라.
iptables -R INPUT 2 -p tcp --dport 8880 -j ACCEPT
웹서버 포트 80 -> 8880 으로 교체하라 ( 웹서비스 포트 변경시 /etc/services 에서도 변경 해줘야 함)
cat access.log | awk '{print $1}' | sort | uniq | xargs iptables -A INPUT -s {} -j DROP
access.log 파일에 있는 모든 ip의 모든 접속 포트를 막아라 (DOS공격 방어시 사용)

시스템 관리자를 위한 16가지 팁 & 트릭

작업을 시작하기 전에 구성을 백업하라.
다음 명령을 사용하여 구성을 백업합니다. (백업시 백업 날짜 추가)
/sbin/iptables-save > /root/iptables-works-$(date +%F)
정책의 백업 복사본을 만들 때마다 이름에 "최신"이 포함된 파일에 대한 링크를 만듭니다.
ln –s /root/iptables-works-(date +%F) /root/iptables-works-latest
특정 규칙(Specific Rules)은 정책 상단에, 일반 규칙(Generic rules)은 하단에 배치하십시오.
정책이 적용되는 순서는 위에서 부터 아래로, 이미 적용될 경우 덮어쓰기(Overwrite)가 안됩니다.
정책 규칙 상단에 iptables -A INPUT -p tcp --dport 22 -j DROP와 같은 일반적인 규칙을 사용하지 마세요.
규칙에 더 많은 기준을 지정할수록 자신을 잠글 가능성이 줄어듭니다. 위의 매우 일반적인 규칙 대신 다음과 같이 사용하십시오.
iptables -A INPUT -p tcp --dport 22 –s 10.0.0.0/8 –d 192.168.100.101 -j DROP
정책 규칙 상단에 IP 주소를 허용 목록에 추가하세요.
이것은 자신을 잠그지 않는 매우 효과적인 방법입니다. 다른 사람들은 그다지 많지 않습니다.
iptables -I INPUT -s<your IP>-j ACCEPT

워크스테이션 방화벽 정책 설정

시나리오: 제한적인 방화벽 정책으로 워크스테이션을 설정하려고 합니다.

기본 정책을 DROP으로 설정하십시오.
# Set a default policy of DROP
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
  • 참고로 첫 번째 줄의 *filter는 필터 테이블에 적용하라는 의미이다.
  • [0:0]은 카운터이며 지금까지 도착하거나 떠나거나 전달된 패킷이 없음을 의미합니다. 1
연결되거나(ESTABLISHED) 관련있는(RELATED) 상태는 ACCEPT.
-I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
참고로 -I INPUT 1 는 첫 번째 규칙으로 삽입 하라는 의미. 2
사용자가 작업을 완료하는 데 필요한 최소한의 서비스를 허용하십시오.
iptables 규칙은 워크스테이션이 DHCP(-p udp --dport 67:68 --sport 67:68) 를 통해 IP 주소, 넷마스크 및 기타 중요한 정보를 가져오도록 허용해야 합니다.
원격 관리를 위해 규칙:

전체 내용:

# Set a default policy of DROP
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

# Accept any related or established connections
-I INPUT  1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow all traffic on the loopback interface
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# Allow outbound DHCP request
-A OUTPUT –o eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT

# Allow inbound SSH
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW  -j ACCEPT

# Allow outbound email
-A OUTPUT -o eth0 -p tcp -m tcp --dport 25 -m state --state NEW  -j ACCEPT

# Outbound DNS lookups
-A OUTPUT -o eth0 -p udp -m udp --dport 53 -j ACCEPT

# Outbound PING requests
-A OUTPUT –o eth0 -p icmp -j ACCEPT

# Outbound Network Time Protocol (NTP) requests
-A OUTPUT –o eth0 -p udp --dport 123 --sport 123 -j ACCEPT

# Outbound HTTP
-A OUTPUT -o eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT

COMMIT

루프백 (lo)과 이더넷 (eth0) 은 자신의 환경에서 확인하자.

IP 주소 범위 제한

시나리오: 회사의 CEO는 직원들이 Facebook에서 너무 많은 시간을 보내고 아무 작업도 하지 않는다고 생각합니다. CEO는 CIO에게 직원들이 Facebook에서 시간을 낭비하는 것에 대해 조치를 취하라고 지시합니다. CIO는 CISO에게 Facebook에서 시간을 낭비하는 직원에 대해 조치를 취하라고 지시합니다. 결국 직원들이 Facebook에서 너무 많은 시간을 낭비하고 있다는 말을 듣고 이에 대해 조치를 취해야 합니다. Facebook에 대한 모든 액세스를 차단하기로 결정했습니다. 먼저 hostwhois 명령을 사용하여 Facebook의 IP 주소를 찾습니다.

$ host -t a www.facebook.com
www.facebook.com is an alias for star.c10r.facebook.com.
star.c10r.facebook.com has address 31.13.65.17

$ whois 31.13.65.17 | grep inetnum
inetnum:        31.13.64.0 - 31.13.127.255

그런 다음 CIDR에서 IPv4로 변환 페이지를 사용하여 해당 범위를 CIDR 표기법으로 변환합니다. 31.13.64.0/18 이 됩니다 . www.facebook.com 에 대한 발신 액세스를 방지하려면 다음을 입력하십시오.

iptables -A OUTPUT -p tcp -i eth0 –o eth1 –d 31.13.64.0/18 -j DROP

시간에 따라 규제

시나리오: Facebook 액세스 거부에 대한 회사 직원의 반발로 인해 CEO는 약간 누그러졌습니다(그와 그의 관리 비서는 그녀가 HIS Facebook 페이지를 최신 상태로 유지한다고 그에게 상기시킵니다). CEO는 점심 시간(오후 12시~오후 1시)에만 Facebook.com에 대한 액세스를 허용하기로 결정합니다. 기본 정책이 DROP이라고 가정하고 iptables의 시간 기능을 사용하여 액세스를 엽니다.

iptables –A OUTPUT -p tcp -m multiport --dport http,https -i eth0 -o eth1 -m time --timestart 12:00 --timestart 12:00 –timestop 13:00 –d 
31.13.64.0/18  -j ACCEPT

이 명령은 Facebook.com (–d 31.13.64.0/18) 에 대해 정오(--timestart 12:00)와 오후 13시(--timestop 13:00) 사이에 httphttps(-m multiport --dport http,https)를 허용(-j ACCEPT)하도록 정책을 설정합니다.

시간에 따라 조절 - 2회 복용

시나리오: 시스템 유지 관리를 위해 계획된 중단 시간 동안 유지 관리 작업이 들어오는 트래픽으로 인해 중단되지 않도록 오전 2시에서 오전 3시 사이의 모든 TCP 및 UDP 트래픽을 거부해야 합니다.

두 가지 iptables 규칙이 필요합니다.

iptables -A INPUT -p tcp -m time --timestart 02:00 --timestop 03:00 -j DROP 
iptables -A INPUT -p udp -m time --timestart 02:00 --timestop 03:00 -j DROP

TCP and UDP traffic (-p tcpand -p udp) are denied (-j DROP) between the hours of 2AM (--timestart 02:00) and 3AM (--timestop 03:00) on input (-A INPUT).

iptables와의 연결 제한

시나리오: 인터넷에 연결된 웹 서버가 DoS(서비스 거부)를 시도하는 전 세계의 나쁜 행위자로부터 공격을 받고 있습니다. 이러한 공격을 완화하려면 단일 IP 주소가 웹 서버에 가질 수 있는 연결 수를 제한합니다.

iptables –A INPUT –p tcp –syn -m multiport -–dport http,https –m connlimit -–connlimit-above 20 –j REJECT -–reject-with-tcp-reset

이 규칙이 무엇을 하는지 살펴보겠습니다. 호스트가 1분 동안 웹 서버(-–dport http,https)에 대해 20개(-–connlimit-above 20) 이상의 새 연결(–p tcp –syn)을 만드는 경우 새 연결을 거부하고(–j REJECT) 연결 호스트에 연결을 거부한다고 알립니다(--reject-with-tcp-reset).

기본 정책(Policy)를 ACCEPT로 할 경우

오라클 클라우드에서 저장되어 있는 기본 룰이 이렇게 되어있더라.

체인의 마지막에는 리젝하도록 한다.

*filter
:INPUT ACCEPT [0:0]
...
-A INPUT -j REJECT --reject-with icmp-host-prohibited

참고로 -A INPUT -j REJECT --reject-with icmp-host-prohibited 는, "모든 트래픽을 ICMP 호스트 금지 메시지와 함께 거부합니다." 이다.

Oracle Cloud Default Settings

오라클 클라우드에서 저장되어 있는 /etc/iptables/rules.v4 파일의 기본 룰이 이렇게 되어있더라.

# CLOUD_IMG: This file was created/modified by the Cloud Image build process
# iptables configuration for Oracle Cloud Infrastructure

# See the Oracle-Provided Images section in the Oracle Cloud Infrastructure
# documentation for security impact of modifying or removing these rule

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [463:49013]
:InstanceServices - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p udp --sport 123 -j ACCEPT
# ----------------------------------------------------------------------------------------------------------------------------------
# 내가 추가한 사용자 정의 체인
-A INPUT -p tcp -m state --state NEW -m tcp --dport   22 -j ACCEPT -m comment --comment "SSH"
-A INPUT -p udp -m state --state NEW -m udp --dport   53 -j ACCEPT -m comment --comment "DNS (Nebula Lighthouse)"
-A INPUT -p tcp -m state --state NEW -m udp --dport  443 -j ACCEPT -m comment --comment "HTTPS (Caddy)"
-A INPUT -p udp -m state --state NEW -m udp --dport 4242 -j ACCEPT -m comment --comment "Nebula Lighthouse"
# ----------------------------------------------------------------------------------------------------------------------------------
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A OUTPUT -d 169.254.0.0/16 -j InstanceServices
-A InstanceServices -d 169.254.0.2/32 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.2.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.4.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.5.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.2/32 -p tcp -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 53 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p tcp -m tcp --dport 53 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.3/32 -p tcp -m owner --uid-owner 0 -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.4/32 -p tcp -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 67 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 69 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp --dport 123 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.0/16 -p tcp -m tcp -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j REJECT --reject-with tcp-reset
-A InstanceServices -d 169.254.0.0/16 -p udp -m udp -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j REJECT --reject-with icmp-port-unreachable
COMMIT

모든 ipv6 연결 차단

적극적으로 사용하지 않거나 애매하면 그냥 다 끄자.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT

*raw
:PREROUTING DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT

*nat
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT

*security
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT

*mangle
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT

iptables 규칙 모니터링

시나리오: iptables는 패킷이 체인의 규칙을 통과할 때 "첫 번째 일치 승리" 기반으로 작동하므로 자주 일치하는 규칙은 정책의 맨 위에 있어야 하고 덜 자주 일치하는 규칙은 맨 아래에 있어야 합니다. 어떤 규칙이 가장 많이 또는 가장 적게 통과되어 위쪽 또는 아래쪽에 더 가깝게 정렬될 수 있는지 어떻게 알 수 있습니까?

각 규칙이 적중된 횟수를 확인하십시오.

다음 명령을 사용하십시오.

sudo iptables -nvL --line-numbers
  • -n - 잘 알려진 이름이 아닌, 숫자로 출력 (e.g. anywhere == 0.0.0.0/0)
  • -v - 패킷 및 바이트 카운터를 출력
  • -L - 체인의 모든 규칙을 나열
  • --line-numbers - 각 규칙의 시작 부분에 줄 번호 표시

다음과 같은 느낌으로 출력됨.

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
  991  128K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0
   69  5654 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:123
    5   280 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
   12   720 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 775 packets, 1077K bytes)
 pkts bytes target     prot opt in     out     source               destination
  126  8837 InstanceServices  all  --  *      *       0.0.0.0/0            169.254.0.0/16

Chain InstanceServices (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.0.2          owner UID match 0 tcp dpt:3260 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.2.0/24       owner UID match 0 tcp dpt:3260 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.4.0/24       owner UID match 0 tcp dpt:3260 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.5.0/24       owner UID match 0 tcp dpt:3260 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.0.2          tcp dpt:80 
    5   406 ACCEPT     udp  --  *      *       0.0.0.0/0            169.254.169.254      udp dpt:53 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.169.254      tcp dpt:53 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.0.3          owner UID match 0 tcp dpt:80 
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.0.4          tcp dpt:80 
  120  8355 ACCEPT     tcp  --  *      *       0.0.0.0/0            169.254.169.254      tcp dpt:80 
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            169.254.169.254      udp dpt:67 
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            169.254.169.254      udp dpt:69 
    1    76 ACCEPT     udp  --  *      *       0.0.0.0/0            169.254.169.254      udp dpt:123 
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            169.254.0.0/16       tcp
    0     0 REJECT     udp  --  *      *       0.0.0.0/0            169.254.0.0/16       udp

패킷 및 바이트 수를 사용하여 가장 자주 순회하는 규칙을 맨 위로, 가장 적게 순회하는 규칙을 맨 아래로 정렬할 수 있습니다.

모니터링할 경우 watch 명령과 함께 사용할 수 있다.

sudo watch -n 0.1 'iptables -nvL --line-numbers'

netstat 명령과 함께 조합하여 사용하자.

불필요한 규칙을 제거하십시오

어떤 규칙이 전혀 매치되지 않습니까? 이들은 정책에서 제거하기에 좋은 후보가 될 것입니다. 다음 명령으로 확인할 수 있습니다.

iptables -nvL | grep -v "0     0"

참고: 0과 0사이에 5개의 공백이 있습니다.

진행 상황을 모니터링합니다

top과 같이 실시간으로 iptables에서 무슨 일이 일어나고 있는지 모니터링하고 싶습니다. 이 명령을 사용하여 iptables 활동을 동적으로 모니터링하고 능동적으로 순회 중인 규칙만 표시합니다.

$ watch -n 0.1  'sudo iptables -nvL'

iptables에 대한 보고

시나리오: 관리자는 이 iptables 방화벽이 훌륭하다고 생각하지만 일일 활동 보고서가 더 나을 것입니다. 때로는 작업을 수행하는 것보다 보고서를 작성하는 것이 더 중요합니다.

패킷 필터/방화벽/IDS 로그 분석기 FWLogwatch를 사용하여 iptables 방화벽 로그를 기반으로 보고서를 생성합니다. FWLogwatch는 많은 로그 형식을 지원하고 많은 분석 옵션을 제공합니다. 로그 파일의 일별 및 월별 요약을 생성하여 보안 관리자가 상당한 시간을 확보하고 네트워크 보안을 보다 잘 제어하며 눈에 띄지 않는 공격을 줄일 수 있습니다.

다음은 FWLogwatch의 샘플 출력입니다.

Fwlogwatch_-_sample.png

State Module

연결 추적을 시행하는 모듈이다.

  • -m state 옵션을 사용한 직후 --state [인수]를 추가할 수 있다.
  • 인수는 탐지할 패킷의 상태를 지정한다.
  • 복수의 상태를 지정할 때는 위의 예시와 같이 반점(,)을 넣어 구분한다.

패킷의 상태 목록은 다음과 같다.

  • NEW: 새로운 연결을 요청하는 패킷, 예, HTTP 요청
  • ESTABLISHED: 접속 요구(SYN) 후 응답(SYN/ACK)이 있었던 또는 응답(SYN/ACK) 후에 (ACK)가 와서 접속 상태가 되는 패킷 (기존 연결의 일부인 패킷)
  • RELATED: 접속 상태인 패킷과 관련된 패킷. FTP의 데이터 포트(20/tcp)는 이것을 이용한다.
    • 기존 연결에 속하지만 새로운 연결을 요청하는 패킷, 예를 들면 접속 포트가 20인 수동 FTP의 경우 전송 포트는 사용되지 않은 1024 이상의 어느 포트라도 사용 가능합니다.
  • INVALID: NEW, ESTABLISHED, RELATED 이외의 패킷. 대부분이 DROP해도 되는 패킷이다.

State Module Example

$ iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

이것은 eth0에서 eth1로 전송하는 패킷에서 ESTABLISHED(접속 상태) 또는 RELATED(접속 상태에 있는 패킷의 관련 패킷)을 ACCEPT하는 규칙이다.

Chain

체인 = 규칙 + 규칙 + ...

체인은 규칙의 집합이다. 규칙을 정의하는 순번도 중요하다. 패킷은 규칙 순서대로 매칭되기 때문에 때로는 중요한 패킷을 누락시켜버리는 경우도 발생한다.

체인 목록:

  • INPUT - 호스트에 들어온 패킷
  • OUTPUT - 로컬 호스트에서 만들어진 패킷
  • FORWARD - 호스트를 통과하는 패킷
  • PREROUTING - 들어오는 패킷을 변환
  • POSTROUTING - 나가는 패킷을 변환

Chain Example

$ iptables -P INPUT DROP
$ iptables -A INPUT -p TCP -d 192.168.2.1 -dport 22 -s 192.168.2.0/24 -j ACCEPT
$ iptables -A INPUT -p TCP -d 192.168.2.1 -dport 80 -s 192.168.2.0/24 -j ACCEPT
$ iptables -A INPUT -p UDP -d 192.168.2.1 -dport 53 -s 192.168.2.0/24 -j ACCEPT
  • INPUT이라는 체인에서 22/TCP, 80/TCP, 53/UDP를 받아들이고 나머지는 DROP하는 규칙의 집합이다.
  • 먼저 정책을 DROP 등으로 지정하고 그 뒤에 통과시킬 패킷을 지정하는 것이 표준 체인의 사용법이다.
  • 여러 개의 규칙으로 INPUT이라는 체인을 구축하게 되며 체인은 사용자가 자유롭게 정의할 수도 있다.

커스텀 체인

Logging

타깃에 LOG나 ULOG를 지정하면 syslog나 ulog에 패킷 로그를 기록할 수 있다.

  • 패킷 로그는 기본으로 커널 로그에 기록된다.
  • 로그 facility를 변경할 때에는 --log-level을 이용한다.
  • 로그 기록 시에는 prefix를 지정할 수도 있다.
  • --log-prefix로 문자열을 지정해 두면 기록된 패킷이 어느 규칙에 매치되었는지 판단할 수 있다.
  • 타깃에 LOG/ULOG를 지정하면 해당 규칙을 통과한 후 다음 규칙의 검토에 들어간다.
  • 그리고 LOG/ULOG 타깃 뒤에는 타깃의 DROP이나 REJECT 규칙을 다시 한 번 추가해두도록 한다.
$ iptables -N LOGGING # LOGGING 체인 생성
$ iptables -A INPUT -j LOGGING
$ iptables -A INPUT -p ICMP -d 192.168.2.121 -j ACCEPT
$ iptables -A LOGGING -j LOG # 상기 규칙 이외의 패킷을 로그 기록
$ iptables -A LOGGING -j DROP # LOGGING 체인 종료

Config

/etc/sysconfig/iptables파일을 확인하면 된다.

트래픽 제어

특정 문자열 패킷 차단

iptables -I INPUT -p tcp --dport 9090 -m string --string "name" --algo bm -j DROP
Request URL에 포함된 string으로 차단
"name"이 포함된 9090 port로 인입되는 packet을 차단하도록 설정
iptables -I INPUT -p tcp --sport 9090 -m string --string "pong" --algo bm -j DROP
Response Body에 포함된 string으로 차단
"pong"이 포함된 9090 port에서 인입되는 packet을 차단하도록 설정

DOCKER-USER Chain 에서 특정 포트로 들어오는 패킷 차단

iptables -I DOCKER-USER -p tcp --dport 8888 -j DROP
DOCKER-USER Chain에 destination port 8888 로 들어오는 packet 차단하기
Docker docs에 의하면 DOCKER Chain에 등록된 룰에 해당하는 경우는 DOCKER Chain에 해당하는 룰이 우선된다는 정보를 보고 이번엔 DOCKER-USER Chain에 추가를 해보도록 한다.

가상 네트워크 구축

Troubleshooting

Roles order

설정파일의 적용순서에 따라서 최종적으로 반영되는 결과가 다르다.

서비스 재시작시 규칙이 중복으로 겹쳐지는 현상

iptables 규칙을 초기화한 후 재시작하자.

WARNING

원격 접속된 서버에서 iptables -F 날린 순간 바랄라로 날라갈수 있으니 주의하자

iptables -F
sudo systemctl restart iptables

See also

  • Network
  • firewalld
  • lokkit
  • UFW (Ubuntu)
  • traceroute
  • iproute2
  • 마스커레이딩 (masquerade) - 마스커레이딩이란 로컬네트워크에 있는 컴퓨터가 방화벽 기능을 하는 리눅스 서버(또는 게이트웨이/프록시)를 통해서 외부로 데이터 등을 보내려고 할 때, 리눅스 서버가 그 컴퓨터를 '마스커레이딩'한다고 말한다.
  • arptables
  • ebtables
  • nftables

Favorite site

in Ubuntu

Tutorials

Online Tools

Best Practice

References