TTL로 서브넷 내 구분 (iptables)

TTL 값으로 서브네트워크 분리



오랜만에 옛 본직 재료로서, 옛날에 이전 회사에서 한 일의 복습. 그 결과, 당시 사용했던 iptables 옵션과는 다르다. (그만큼 스킬이 유지되지 않는다.)

의도



한 프로젝트에서 같은 서브넷 내에서도 위치를 구별하고 싶은 것이있었습니다. 예를 들면 다음과 같습니다.

192.168.1.0/24라는 네트워크에는 네트워크 브리지를 분리하여 두 개의 영역(Area1과 Area2)이 있다. 각종 사정이 있었고 (이제 잊었지만 Payload를 바꾸고 싶지 않은 이유가 있었을 것이다), iptables와 TTL을 사용하여 두 개의 영역을 나누기로 했다.

구성



여기에서는 위 그림을 Virtualbox를 사용하여 실현한다. Virtualbox 설정 및 네트워크 브리지 설정은 이전 기사과 동일합니다. 일부 아래에 재게재.
~# cat /etc/network/interfaces
auto eth0
iface eth0 inet static
  address 0.0.0.0
auto eth1
iface eth1 inet static
  address 0.0.0.0
auto br0
iface br0 inet static
  address 0.0.0.0
  bridge_ports eth0 eth1

~# brctl show
bridge name bridge id       STP enabled interfaces
br0     8000.080027507ba3   no          eth0                                                                           eth1
~# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 08:00:27:50:7b:a3  txqueuelen 1000  (Ethernet)
        RX packets 6  bytes 336 (336.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 79  bytes 29072 (28.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 08:00:27:84:d4:75  txqueuelen 1000  (Ethernet)
        RX packets 43  bytes 3142 (3.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 201  bytes 61286 (59.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 08:00:27:50:7b:a3  txqueuelen 1000  (Ethernet)
        RX packets 43  bytes 3142 (3.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 201  bytes 61286 (59.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 12886  bytes 953420 (931.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12886  bytes 953420 (931.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

IPv6 주소가 할당되었지만 여기에서는 무시.

네트워크 브리지에 iptables 적용



iptables 자체 설명서는 여기 .

br_netfilter



이전에는 iptables만으로도 OK였던 것 같은 생각이 들지만, 이번에는 br_netfilter라는 커널 모듈을 의도적으로 로드할 필요가 있었다. 이전의 기록은 남아 있지 않고, 이번에 사용한 Linux의 Distribution(그리고 커널 버전)도 다르기 때문에, 뭐라고 말할 수 없어.
~# modprobe br_netfilter
~# sysctl -a | grep bridge
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-filter-pppoe-tagged = 0
net.bridge.bridge-nf-filter-vlan-tagged = 0
net.bridge.bridge-nf-pass-vlan-input-dev = 0

iptables 이용에는 "net.bridge.bridge-nf-call-iptables"가 "1"로 되어 있는 것이 필수인 것 같다. 이런 기사 가 참조.

덧붙여서, 매번 modprobe 하지 않고, 기동시에 자동적으로 로드하려면 ,/etc/modules에 기재하면 좋다.
~# cat /etc/modules 
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

br_netfilter

iptables



여기 에도 있듯이 이전에는 아래 명령으로 동작한 기억도 있었지만 이번에는 동작하지 않고 NG.
~# iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 3

대신 여기을 참고하여 아래 명령으로 작동하는 것 같습니다.
~# iptables -t mangle -A PREROUTING -j TTL --ttl-dec 3

다만, 이것이라고 하면, 최초의 그림의 Area2로부터 Area1에의 IP 패킷의 TTL도 줄어 버리므로,
~# iptables -t mangle -A PREROUTING -s 192.168.1.11 -j TTL --ttl-dec 3

Area1 내의 특정 송신 주소를 지정하기로 결정했습니다. 옵션에 대한 자세한 내용은 iptables 설명서를 확인하는 것이 좋습니다.

덧붙여 PRERUTING 대신 POSTROUTING이나 FORWARD에서도 OK의 모습. (단, INPUT/OUTPUT에서는 동작하지 않는다.)

확인의 모습



첫 번째 그림의 터미널 1에서 터미널 2로 TTL을 200으로 설정하고 핑합니다.
~# ping -c 1 -t 200 192.168.1.12

단말 1에서의 Wireshark




TTL은 ping 옵션으로 명시적으로 설정한 200.

터미널 2의 Wireshark




네트워크 브리지의 iptables에서 3 감소, TTL은 197이다.

끝에



iptables는 안쪽이 깊다는 것을 다시 깨닫는다.

좋은 웹페이지 즐겨찾기