아이엠 !나이롱맨😎
article thumbnail
반응형

Iptables 를 알아보기 전에 먼저 Netfilter 에 대해 알아보죠 !

 

Netfilter 와 Iptables


AWS EC2 인스턴스를 생성할 때 Security Group 이라는 것을 설정합니다. 이름 그대로 외부로 들어오는 트래픽을 조절할 수 있게 해주는 방화벽 기능이죠. EC2 인스턴스 앞단에 이를 처리해주는 아마 물리적인 기계가 있어서 어떤 트래픽은 허용하고, 어떤 트래픽은 거부하겠죠.

 

Security Group 이 하드웨어 방화벽 이라면 Netfilter 는 소프트웨어 방화벽이라고 생각하면 이해하기 쉽습니다.

 

Netfilter 는 다음과 같은 특징이 있습니다.

  • 소프트웨어 방화벽
  • 패킷 필터링
  • 리눅스 커널 내부의 프레임워크
  • 포트 주소, 변환, 포트 포워딩 및 패킷 변경
  • 라우팅 전후에 데이터 및 IP 패킷 헤더 변경

 

그치만 위와 같은 기능을 사용할 때 Netfilter 에 직접 접근하지 않고, 어떤 소프트웨어를 사용해서 변경하는데 이때 사용하는 것이 바로 Iptables 입니다.

 

즉, Iptables 는 Netfilter 를 컨트롤하는 소프트웨어라고 생각하면 됩니다.

 

헷갈리시다면, Iptables 과 Netfilter 를 동일시 생각해도 크게 이 글을 이해하는데 지장은 없을 겁니다 😀

 

Netfilter Chains


Netfilter 에는 다음과 같이 5 개의 Chains 라는 것이 존재합니다.

Netfilter Chains

 

Input

  • 들어오는 패킷을 허용하거나 거부(Drop)
  • 호스트로 들어오는 모든 패킷은 예외없이 Input 규칙을 따름
  • Input 규칙을 건너뛸 수 있는 패킷은 없음
$ iptables -t filter -A INPUT -p icmp -j DROP

# 들어오는 모든 icmp 를 DROP 한다
# ping 을 iptables 를 적용한 호스트로 보내면 응답이 오지 않는다

Output

  • 나가는 패킷을 허용하거나 거부(Drop)
  • 호스트가 Source 가 됨
$ iptables -t filter -A OUTPUT -d netfilter.org -j DROP

# 호스트에서 netfilter.org 로 나가는 모든 패킷은 드롭된다

 

이외 Prerouting, Forward, PostRouting 가 존재하는데 이는 좀 더 뒤에서 다루도록 하죠 🧐

 

 

Netfilter Tables


Netfilter 에선 Chain 말고 Table 라는 것을 사용하는데 총 4가지가 존재합니다.

Iptables 에서 생성한 룰을 정의하는 Table 이죠.

 

Chain 과 Table

 

filter

  • iptables 에서 가장 널리 사용되는 테이블 
  • 모든 작업이 일반적으로 방화벽과 연결되는 곳
  • 여기서 패킷을 허용할지 거부할지 정함
$ iptables -A INPUT -p tcp --dport 22 -s 5.3.6.6 -j ACCEPT
$ iptables -A INPUT -p tcp --dport 22 -j DROP

# 체인은 등록된 순서로 작동한다
# 5.3.6.6:22 의 패킷만 허용된다
# 하지만 두번째 체인에서 22 포트로 오는 패킷은 어떤 IP 든 드롭된다

 

nat

  • DNAT, SNAT 관련 룰을 정의함

 

나머지 mangle 과 raw 테이블은 다루지 않겠습니다.. 사용했던 적이 없어요.. 😅

 

 

기본적인 Command


Iptables 를 사용하기 위해선 iptables 라는 명령어를 사용합니다. 아래와 같이 말이죠.

$ iptables -vnL

 

핵심 Command 만 한번 알아보죠 ! 

 

참고: iptables 명령어는 root 계정만 가능합니다
참고: -t nat 와 같이 table 을 지정하지 않으면 자동으로 filter 를 사용합니다

 

L 옵션

iptables 에 존재하는 Rule 을 리스트합니다.

$ iptables -L
# 리스트를 보여줌

$ iptables -vnL
# 더 자세하게 보여줌
# -v : verbose
# -n : numberic

iptables -L
iptables -vnL

 

 

A 옵션

iptables 에 Rule 을 추가하는 옵션입니다.

$ iptables -A INPUT -p tcp --dport 80 -j DROP
# 80 포트로 들어오는 패킷을 드롭함

$ iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
# 8080 포트로 들어오는 패킷은 허용함

$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 규칙은 위에서 아래로 적용되기 때문에 첫번째 규칙에 의해 DROP 되어
# 이 규칙은 사실상 무의미함

 

I 옵션

A 옵션과 똑같이 규칙을 추가하지만 A 옵션 같은 경우는 뒤에서 추가하고, I 옵션 같은 경우는 첫번째에서 추가합니다.

다음 이미지를 보면 이해하기 쉽습니다.

 

현재 80 포트를 DROP 하는 규칙이 한개 있습니다. 이때 I 옵션을 사용한다면 DROP 규칙 아래가 아닌 위에 생성되게 됩니다.

$ iptables -A INPUT -p tcp --dport 80 -j DROP
$ iptables -I INPUT -p tcp --dport 80 -j ACCEPT

아래가 아닌 위에 생긴 것을 볼 수 있습니다.

전에 이야기했지만 규칙은 위에서 아래로 적용되기 때문에 이런 경우 80 포트는 들어오는 트래픽은 무조건 허용됩니다.

 

F 옵션

그럼 위에서 추가한 규칙을 다 삭제해보죠!

$ iptables -F

규칙이 다 삭제(Flush) 된 것을 볼 수 있습니다.

 

그럼 이제 예제를 통해 지금까지 배운 걸 활용해보죠 😎

 

기본 예제


 

Case 1) 80 포트로 들어오는 트래픽을 모두 거부하자!

 

현재 Host 에서 80 포트는 Nginx 프로세스입니다. 

Client 에서 curl 를 이용해서 Host 의 Nginx 에 접근해보죠 !

Nginx

무리없이 응답을 받고 있습니다. 그럼 이를 거부하는 Rule 을 추가해보죠!

 

Host 로 이동해서 아래와 같은 명령어를 실행합니다.

$ iptables -A INPUT -p tcp --dport 80 -j DROP
# -p : protocol
# 포트는 L4 이후부터 가능하므로 -p tcp 라는 옵션을 추가해주어야 함

80 포트로 들어오는 모든 트래픽을 DROP 했기 때문에 curl 을 해도 응답이 오질 않습니다.

그럼 다시 이를 ACCEPT 할 수 있게 새로운 규칙을 추가해보죠! 어떤 옵션을 쓰면 될까요?

 

Case 2) -F 를 사용하지 않고 80 포트를 다시 허용해주자!

감이 오시나요? 맞습니다. I 옵션을 사용하면 됩니다.

$ iptables -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -vnL

그럼 다시 curl 를 보내볼까요?

DROP 되는 규칙이 있긴 하지만 계속 이야기하다시피 규칙은 위에서 아래로 읽기 때문에 ACCEPT 가 되는 걸 알 수 있습니다 🤟

 

그럼 좀 더 심화된 기능을 알아보죠 !

 

DNAT 과 SNAT 그리고 MASQUERADE


iptables 의 핵심 기능이라고 볼 수 있습니다.

DNAT 과 SNAT 을 이해하기 위해선 우선 NAT 이라는 개념을 알아야 합니다.

 

NAT 은 Network Address Translation 의 약자로 이름 그대로 Network 주소를 변환하는 기술을 말합니다.

NAT 에 관한 글은 아니니 자세한 건 여기를 참고해주세요 !

 

DNAT 의 D 는 Destination, SNAT 의 S 는 Source 를 의미하며 DNAT 은 Destination 의 주소를 변환하고, SNAT 은 Source 의 주소를 변환합니다.

 

DNAT
SNAT

 

DNAT 은 항상 PREROUTING 체인 규칙을 사용해야하며, SNAT 은 항상 POSTROUTING 체인 규칙을 사용해야 합니다.

 

그럼 이제 MASQUERADE 에 대해 알아보죠!

MASQUERADE 는 SNAT 의 일종이며 SNAT 과 다르게 동적으로 소스 IP 를 처리할 수 있도록 해줍니다.

때문에 보통 SNAT 보단 MASQUERADE 를 통해서 규칙을 지정하는게 편리합니다.

 

이제 이해가 잘안되신다구요?

 

그럼 예제를 통해 한번 알아보죠!

 

심화 예제 - iptables 을 이용하여 로드밸런서를 만들어보자!


iptables 를 사용하면 로드밸런싱을 쉽게 구현할 수 있습니다. 그럼 바로 가보죠! 🤟

 

기능은 아주 간단합니다. Load Balancer 에 3000 포트로 접근하면 Server A 로 가고, 3010 포트로 접근하면 Server B 로 갑니다.

 

구조도

 

그럼 우선 Server A 와 Server B 에 요청을 보내면 무슨 응답이 오는지 확인해보죠.

둘 다 ok 가 응답으로 오는 아주 간단한 서버입니다.

 

그럼 이제 직접 Server A 와 Server B 에 요청하는 것이 아닌 Load Balancer 를 통해 요청을 보내보죠!

 

그 전에 우선 Route 기능을 활성화해줍니다.

echo "1" > /proc/sys/net/ipv4/ip_forward

 

이후 다음과 같이 Load Balancer 용도의 Host 에 추가합니다.

$ iptables -t nat -A PREROUTING -p tcp --dport 3000 -j DNAT --to-destination 54.180.126.167:9090
# 3000 으로 들어오는 트래픽은 54.180.126.167:9090 로 나감

$ iptables -t nat -A PREROUTING -p tcp --dport 3010 -j DNAT --to-destination 54.180.126.167:4040
# 3010 으로 들어오는 트래픽은 54.180.126.167:4040 로 나감

$ iptables -t nat -A POSTROUTING -j MASQUERADE
# Host 를 나갈 때 Source IP 또한 MASQUERADE 로 자동으로 변환함

 

모든 준비는 끝났습니다. 그럼 한번 Load Balancer 에 접근해보죠 😎

성공적입니다!

 

사실 Load Balancer 라고 하기에 기능이 많이 부족하지만 좀 손보면 충분히 만들 수 있을거 같습니다. 

 

지금까지 긴 글 읽어주셔서 감사합니다 😄

반응형

article prev thumbnail
profile on loading

Loading...