CloudNetaStudy - Kubernets Networtk 3기 실습 스터디 게시글입니다.
- 컨테이너는 네트워크 네임스페이스로 호스트와 네트워크 격리 환경을 구성됩니다.
- 리눅스에서 방화벽 기능을 제공하는 IPtables 는 호스트와 컨테이너의 통신에 관여를 합니다.
- [Sam.0] Netfilter and iptables - Link , A Deep Dive into Iptables and Netfilter Architecture - Link
A Deep Dive into Iptables and Netfilter Architecture
netfilter와 iptables를 이해하기에 좋은 자료입니다.
netpple.github.io
- https://docs.google.com/presentation/d/1tXS3N0196WmdaWYa0ZLVpIMt7uDQdBO6PGdq25z0gvs/edit#slide=id.p 정독 추천!
[ 1. 도커 없이 네트워크 네임스페이스 환경에서 통신 구성 ]
1.1 RED ↔ BLUE 네트워크 네임스페이스 간 통신
- 결론 : 네트워크 네임스페이스 생성 시 호스트 네트워크와 구별된다
- 실습 : 터미널1~3 모두 관리자로 실습 진행
# 터미널1~3 관리자 sudo su - whoami # veth (가상 이더넷 디바이스) 생성, man ip-link ip link add veth0 type veth peer name veth1 # veth 생성 확인(상태 DOWN), ifconfig 에는 peer 정보 확인 안됨 # very pair 정보 확인 : ({iface}@if{pair#N}) ip -c link ip -c addr # 축약 ip -c a ifconfig -a # 네트워크 네임스페이스 생성 , man ip-netns ip netns add RED ip netns add BLUE # 네트워크 네임스페이스 확인 ip netns list # veth0 을 RED 네트워크 네임스페이스로 옮김 ip link set veth0 netns RED ip netns list ## 호스트의 ip a 목록에서 보이지 않음, veth1의 peer 정보가 변경됨 ip -c link ## RED 네임스페이스에서 ip a 확인됨(상태 DOWN), peer 정보 확인, link-netns RED, man ip-netns ip netns exec RED ip -c a # veth1 을 BLUE 네트워크 네임스페이스로 옮김 ip link set veth1 netns BLUE ip -c link ip netns exec BLUE ip -c a # veth0, veth1 상태 활성화(state UP) ip netns exec RED ip link set veth0 up ip netns exec RED ip -c a ip netns exec BLUE ip link set veth1 up ip netns exec BLUE ip -c a # veth0, veth1 에 IP 설정 ip netns exec RED ip addr add 11.11.11.2/24 dev veth0 ip netns exec RED ip -c a ip netns exec BLUE ip addr add 11.11.11.3/24 dev veth1 ip netns exec BLUE ip -c a # 터미널1 (RED 11.11.11.2) ## nsenter : 네임스페이스에 attach 하여 지정한 프로그램을 실행 tree /var/run/netns nsenter --net=/var/run/netns/RED ip -c a ## neighbour/arp tables management , man ip-neighbour ip -c neigh ## 라우팅 정보, iptables 정보 ip -c route iptables -t filter -S iptables -t nat -S # 터미널2 (호스트) lsns -t net # nsenter 실행 후 TYPE(net) CMD(-bash) 생성 확인 ip -c a ip -c neigh ip -c route iptables -t filter -S iptables -t nat -S # 터미널3 (BLUE 11.11.11.3) nsenter --net=/var/run/netns/BLUE ip -c a ip -c neigh ip -c route iptables -t filter -S iptables -t nat -S # ping 통신 확인 # 터미널3 (BLUE 11.11.11.3) tcpdump -i veth1 ip -c neigh exit # 터미널1 (RED 11.11.11.2) ping 11.11.11.3 -c 1 ip -c neigh exit # 삭제 ip netns delete RED ip netns delete BLUE
- ## RED 네임스페이스에서 ip a 확인됨(상태 DOWN), peer 정보 확인, link-netns RED, man ip-netns
- # 터미널2 (호스트)
- # 터미널3 (BLUE 11.11.11.3)
1.2 RED ← Bridge(br0) → BLUE 간 통신
결론 : arp table, route table, iptables 와 호스트의 bridge fdb 를 통하여 통신
- 기본 환경 설정 및 확인
# 네트워크 네임스페이스 및 veth 생성 ip netns add RED ip link add reth0 type veth peer name reth1 ip link set reth0 netns RED ip netns add BLUE ip link add beth0 type veth peer name beth1 ip link set beth0 netns BLUE # 확인 ip netns list ip -c link ip netns exec RED ip -c a ip netns exec BLUE ip -c a # 브리지 정보 확인 brctl show # br0 브리지 생성 ip link add br0 type bridge # br0 브리지 정보 확인 brctl show br0 brctl showmacs br0 brctl showstp br0 # reth1 beth1 을 br0 연결 ip link set reth1 master br0 ip link set beth1 master br0 brctl show br0 brctl showmacs br0 ip -br -c link # reth0 beth0 에 IP 설정 및 활성화, br0 활성화 ip netns exec RED ip addr add 11.11.11.2/24 dev reth0 ip netns exec BLUE ip addr add 11.11.11.3/24 dev beth0 ip netns exec RED ip link set reth0 up; ip link set reth1 up ip netns exec BLUE ip link set beth0 up; ip link set beth1 up ip link set br0 up ip -br -c addr # 터미널1 (RED 11.11.11.2) nsenter --net=/var/run/netns/RED ip -c a;echo; ip -c route;echo; ip -c neigh ## 현재 네트워크 네임스페이스 정보 확인 ip netns identify $$ RED # 터미널2 (호스트) brctl showmacs br0 bridge fdb show bridge fdb show dev br0 iptables -t filter -S iptables -t filter -L -n -v # 터미널3 (BLUE 11.11.11.3) nsenter --net=/var/run/netns/BLUE ip -c a;echo; ip -c route;echo; ip -c neigh ## 현재 네트워크 네임스페이스 정보 확인 ip netns identify $$ BLUE ============================================================== # 터미널2 (호스트) # ping 통신 전 사전 설정 ## iptables 정보 확인 iptables -t filter -S | grep '\-P' -P INPUT ACCEPT -P FORWARD DROP -P OUTPUT ACCEPT iptables -nvL -t filter ## Ubuntu 호스트에서 패킷 라우팅 설정 확인 : 커널의 IP Forwarding (routing) 기능 확인 - 0(off), 1(on) ## echo 1 > /proc/sys/net/ipv4/ip_forward cat /proc/sys/net/ipv4/ip_forward 1 ============================================================== # ping 통신 테스트 # 터미널1 (RED 11.11.11.2) >> ping 왜 실패했을까요? ping -c 1 11.11.11.3 # 터미널2 (호스트) tcpdump -l -i br0 watch -d 'iptables -v --numeric --table filter --list FORWARD' watch -d 'iptables -v --numeric --table filter --list FORWARD;echo;iptables -v --numeric --table filter --list DOCKER-USER;echo;iptables -v --numeric --table filter --list DOCKER-ISOLATION-STAGE-1' # 터미널3 (BLUE 11.11.11.3) tcpdump -l -i beth0
- RED → BLUE ping failed 분석
- IPtables : Basic firewall software
- Interacting with the packet filtering hooks in the kernel’s network stack
- Netfilter : These kernel hooks are known as the netfilter framework
- 5 hooks : INPUT, OUTPUT, PREROUTING, FORWARD, POSTROUTING
- Chain
Chain : INPUT - mangle, filter
Chain : OUTPUT - mangle , nat , filter
Chain : FORWARD - mangle , filter
Chain : PPEROUTING - mangle , nat
Chain : POSTROUTING - mangle , nat - Table
Filter : 필터링. 패킷 전송 여부
NAT : Network Address Translation. src/dst. 주소의 수정/방법 여부 결정
Mangle : 헤더 변조 (TTL조정, 홉 수 조정). 추가 처리를 위한 커널 마킹
Raw : connection tracking을 위한 패킷마킹 메커니즘 제공
Security : 패킷에 SELinux(보안) context 마킹
- Chain Rules
Chain Rules : matching
Chain Rules : targets (action - ACCEPT, DROP, REJECT, LOG, RETURN, JUMP)
targets (action) : Jump - 다른 체인으로 점프! - 주요 설정
-A : append, 해당 chain 끝 행에 룰 추가 -I [chain] [number] : insert, 해당 [chain] [number] 행에 룰 삽입 -D : delete, 행 번호 지정하여 룰 삭제 -R : replace, 행 번호 지정하여 룰 치환 -F : flush, 해당 체인의 모든 룰 삭제 -L : list, 룰 리스트 출력 -P : policy, 기본(default) 정책 설정. 체인의 모든 룰에 매칭되지 않으면 적용 -p : protocol, 예) tcp, udp, icmp, ... -s : source ip, 지정 안할 경우 any -d : destination ip, 지정 안할 경우 any -sport : source port -dport : destination port -i : input interface 예) eth0 -o : output interface 예 eth0
- Connection Tracking 과 State
Stateful Operations : ~ Check packets and Update states , ~ Add a new connection
States : NEW, ESTABLISHED, RELATED, INVALID, UNTRACKED, SNAT, DNAT
Netfilter : 커널 모듈로 네트워크 패킷을 처리하는 프레임워크 - 링크
- 네트워크 연산을 핸들러 형태로 처리할 수 있도록 hook 지점을 제공
- 패킷이 어떻게 전송될 지에 대한 결정 방법을 제공
- INPUT, OUTPUT
- FORWARD : 호스트 입장에서 '네트워크 네임스페이스'도 지나가는 패킷 처리(FORWARD)를 한다
Netfilter 과 IPtables
패킷은 netfliter(일종의 백엔드) 에서 파놓은 여러 hook 를 통과하는데 hook 별로 iptables 에서 정의한 각 체인룰을 점검
- iptables(일종의 프런트엔드 혹은 애플리케이션) : Netfileter 가 파놓은 hook 에 룰을 등록하고 관리하는 방법을 제공하는 툴
hook 에 정의된 체인은 테이블 순서대로 등록된 룰을 체크하고 조건을 만족하면 action(target)을 트리거합니다.
- table : 목적/용도별 rules 모음 → 예) filter, nat, mangle ...
- chain : 패킷이 지나가는 hook 별로 존재 → 예) PREROUTING, FORWARD, INPUT ... (넷필터의 hook 에 매핑됩니다)
- rule : table 과 chain matrix 에 대해서 정의 → 예) protocol type, dest/src.address, headers ...
- action(target) : 패킷이 룰에 매칭되면 트리거됨 → 예) ACCEPT, DROP, REJECT ... * -j : jump
- IPtables : Basic firewall software
- RED → BLUE ping 허용 설정 - 링크
- 호스트 입장에서는 "외부(RED, src) → 외부(BLUE, dst)" 패킷이므로 FORWARD 체인의 filter 테이블 룰을 봐야합니다 → 허용 정책 추가하자 - 링크
# 터미널2 (호스트) # iptables 설정 정보 확인 iptables -t filter -S iptables -t nat -S | grep '\-P' # iptables 설정 추가 -t(table), -I(insert chain), -j(jump to - ACCEPT 허용) iptables -t filter -I DOCKER-USER -j ACCEPT iptables -nvL -t filter iptables -t filter -S iptables -t nat -S | grep '\-P' watch -d 'iptables -v --numeric --table filter --list FORWARD;echo;iptables -v --numeric --table filter --list DOCKER-USER;echo;iptables -v --numeric --table filter --list DOCKER-ISOLATION-STAGE-1' tcpdump -l -i br0 ============================================================== # ping 통신 테스트 # 터미널1 (RED 11.11.11.2) ping -c 1 11.11.11.3 ip -c neigh # 터미널2 (호스트) watch -d 'iptables -v --numeric --table filter --list FORWARD;echo;iptables -v --numeric --table filter --list DOCKER-USER;echo;iptables -v --numeric --table filter --list DOCKER-ISOLATION-STAGE-1' tcpdump -l -i br0 ## 정보 확인 ip -c neigh # 터미널3 (BLUE 11.11.11.3) tcpdump -l -i beth0 ip -c neigh ============================================================== # (옵션) 추가 방안1 : 출발지 IP 11.2, 11.3 허용 ## -t(table), -A(APPEND chain rule), -s(출발지), -j(jump to - ACCEPT 허용) iptables -t filter -A FORWARD -s 11.11.11.2/32 -j ACCEPT iptables -t filter -A FORWARD -s 11.11.11.3/32 -j ACCEPT ## 추가 정책 삭제 시 iptables -t filter -D FORWARD -s 11.11.11.2/32 -j ACCEPT iptables -t filter -D FORWARD -s 11.11.11.3/32 -j ACCEPT # (옵션) 추가 방안2 : 11.11.11.0/24 대역 출발지 허용 iptables -t filter -A FORWARD -s 11.11.11.0/24 -j ACCEPT ## 추가 정책 삭제 시 iptables -t filter -D FORWARD -s 11.11.11.0/24 -j ACCEPT # (옵션) 추가 방안3 : FORWARD 기본 정책 허용으로 변경 iptables -t filter -P FORWARD ACCEPT ## 추가 정책 삭제 시 iptables -t filter -P FORWARD DROP
- 호스트 입장에서는 "외부(RED, src) → 외부(BLUE, dst)" 패킷이므로 FORWARD 체인의 filter 테이블 룰을 봐야합니다 → 허용 정책 추가하자 - 링크
1.3 RED/BLUE → 호스트 & 외부(인터넷) 통신
결론 : 호스트에 RED/BLUE와 통신 가능한 IP 설정 및 라우팅 추가, iptables NAT 를 통하여 통신
ip netns add RED
ip link add reth0 netns RED type veth peer name reth1
ip netns add BLUE
ip link add beth0 netns BLUE type veth peer name beth1
ip link add br0 type bridge
ip link set reth1 master br0
ip link set beth1 master br0
ip netns exec RED ip addr add 11.11.11.2/24 dev reth0
ip netns exec BLUE ip addr add 11.11.11.3/24 dev beth0
ip netns exec RED ip link set reth0 up; ip link set reth1 up;
ip netns exec BLUE ip link set beth0 up; ip link set beth1 up;
ip link set br0 up
# iptables -t filter -A FORWARD -s 11.11.11.0/24 -j ACCEPT
iptables -t filter -I DOCKER-USER -j ACCEPT
- 호스트에서 RED 나 BLUE 로 ping 통신 → RED 에서 외부로 통신
# 터미널1 (RED 11.11.11.2) nsenter --net=/var/run/netns/RED tcpdump -i any # 터미널3 (호스트) exit tcpdump -i br0 -n # 터미널2 (호스트) >> 호스트에서 RED 로 통신이 안되는 이유가 무엇일까요? ping -c 1 11.11.11.2 ip -c route ip -c addr ============================================================== # 터미널2 (호스트) >> br0 에 IP 추가(라우팅 정보) ip addr add 11.11.11.1/24 dev br0 ping -c 1 11.11.11.2 ping -c 1 11.11.11.3 # 터미널1 (RED 11.11.11.2) >> 192.168.50.10 와 통신이 안되는 이유는 무엇일까요? ping -c 1 11.11.11.1 ping -c 1 192.168.50.10 ip -c route ip -c addr ============================================================== # 터미널3 (호스트) tcpdump -i any icmp -n # 터미널1 (RED 11.11.11.2) ip route add default via 11.11.11.1 ping -c 1 192.168.50.10 ip -c route ping -c 1 8.8.8.8 >> 외부 대역(인터넷)과 통신이 안되는 이유가 무엇일까요? # 터미널2 (호스트) iptables -S -t nat iptables -nvL -t nat ## POSTROUTING : 라우팅 Outbound or 포워딩 트래픽에 의해 트리거되는 netfilter hook ## POSTROUTING 에서는 SNAT(Source NAT) 설정 iptables -t nat -A POSTROUTING -s 11.11.11.0/24 -j MASQUERADE watch -d 'iptables -v --numeric --table nat --list POSTROUTING' iptables -nvL -t nat conntrack -L --src-nat # 터미널1 (RED 11.11.11.2) ping -c 1 8.8.8.8 exit # 터미널3 (BLUE 11.11.11.3) nsenter --net=/var/run/netns/BLUE # 주의, 꼭 실행 후 아래 진행 할 것 ip route add default via 11.11.11.1 ping -c 1 8.8.8.8 exit # 삭제 ip netns delete RED ip netns delete BLUE ip link delete br0 iptables -t filter -D DOCKER-USER -j ACCEPT iptables -t nat -D POSTROUTING -s 11.11.11.0/24 -j MASQUERADE
* 네트워크 네임스페이스만으로도 직접 수동으로 설정할 경우 복잡 합니다.
도커는 컨테이너 실행(run) 시 자동으로 해당 컨테이너의 네임스페이스 (네트워크, 마운트, PID 등)를 생성(삭제 등)하여 호스트와 격리해줍니다.
'Kubernetes' 카테고리의 다른 글
[ Kans 3 Study - 2w ] 2. kind 기본 사용 (0) | 2024.09.08 |
---|---|
[ Kans 3 Study - 2w ] 1. Vagrant 설정 (1) | 2024.09.08 |
[ Kans 3 Study - 1w ] 컨테이너 네트워크 & IP Tables(3) (2) | 2024.09.01 |
[ Kans 3 Study - 1.3 ] 컨테이너 네트워크 & IP Tables (2) (0) | 2024.09.01 |
[Kans 3 Study - 1.1 ] 도커 컨테이너 격리 (0) | 2024.09.01 |