따라서 구성에서 인터페이스를 10.0.0.1
통해 가고 tun0
로컬 주소가 이므로 처음에 네트워크로 보내려는 모든 패킷이 있습니다 10.0.0.1
. 패킷을 캡처하면 지금까지 모든 것이 정상입니다.
이제 tun0
패킷을 더 보냅니다. 소스 주소 는 10.0.0.1
패킷이 다른 인터페이스 ( wlp2s0
귀하의 경우)를 통해 나가기를 원합니다 . 그건 라우팅 의 첫 번째 라우팅 에이블 할 수 있도록 :
sysctl -w net.ipv4.ip_forward=1
당신은 볼 것이다 경우 그 후, tcpdump
을 위해 wlp2s0
당신이 알 수있는 패킷의 소스 주소를 남겨 10.0.0.1
아니라 무선 랜 인터페이스의 소스 주소 (당신은 내가 생각 무엇을 기대). 따라서 소스 주소를 변경해야하며이를 소스 NAT 라고 합니다 . 리눅스에서는 netfilter / iptables의 도움으로 쉽습니다 .
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
FORWARD
체인에 ACCEPT
정책 이 있는지 확인 하거나 다음과 같은 전달 을 허용 해야합니다 .
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
모든 것이 지금 작동해야합니다 : 리눅스 커널 은 라우팅을 수행하고 tun0
인터페이스 에서로 패킷을 이동 wlp2s0
시킵니다. netfilter 는 소스 IP 10.0.0.1
를 wlp2s0
출력 패킷에 대한 인터페이스 할당 주소 로 변경해야 합니다. 모든 연결을 기억하고 응답 패킷이 되돌아 오면 wlp2s0
인터페이스 할당 주소 의 대상 주소를 10.0.0.1
"conntrack"기능으로 변경합니다.
글쎄요, 그렇지 않습니다. netfilter 는이 복잡한 라우팅 구성과 동일한 패킷이 먼저 OUTPUT
체인을 통과 한 다음 라우팅되어 PREROUTING
체인 에 연결 된다는 사실과 혼동되는 것 같습니다 . 적어도 데비안 8 박스에서는 작동하지 않습니다.
넷 필터
문제를 해결하는 가장 좋은 방법 은 다음과 TRACE
같습니다.
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
ICMP 패킷에 대해서만 추적을 활성화하므로 다른 필터를 사용하여 디버깅 할 수 있습니다.
패킷이 통과하는 테이블과 체인을 보여줍니다. 그리고 패킷이 더 이상 FORWARD
체인으로 이동하지 않는다는 것을 알 수 있습니다 (그리고 nat/POSTROUTING
실제로 수행 하는 체인 에 걸리지 않습니다 SNAT
).
다음은이 작업을 수행하는 몇 가지 방법입니다.
접근법 # 1
넷 필터를 혼동하지 않는 가장 좋은 방법 은 tun0.c
응용 프로그램 에서 패킷의 소스 IP 주소를 변경하는 것 입니다. 또한 가장 자연스러운 방법입니다. 바깥쪽으로 10.0.0.1을 10.0.0.2 로, 되돌아가는 동안 10.0.0.2를 10.0.0.1 로 변경 해야합니다 . 소스 주소 변경 코드로
수정 tun0.c
했습니다. 여기 새 파일이 있고 여기에 대한 patchfile 이 있습니다 tun0.c
. IP 헤더 변경에는 체크섬 수정 도 포함 되므로 OpenVPN 프로젝트 에서 일부 코드를 가져 왔습니다 . 다음은 클린 재부팅 후 실행 한 전체 명령 목록입니다 tun0_changeip.c
.
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
이 경우 역방향 경로 필터링 을 해제 할 필요가 없습니다. 모든 것이 합법적 tun0
입니다. 서브넷에 속하는 패킷 만 수신하고 보냅니다. 또한 인터페이스 기반 대신 소스 기반 라우팅을 수행 할 수 있습니다.
접근법 # 2
SNAT
패킷 도달 tun0
인터페이스 전에 수행 할 수 있습니다. 그래도 정확하지 않습니다. 이 경우 역방향 경로 필터링 을 해제해야합니다 .
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
이제, SNAT
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface
여기서는 패킷이 장치에 도달 하기 직전에 소스 주소를 변경합니다 tun0
. tun0.c
코드는 이러한 패킷을 "있는 그대로"(소스 주소가 변경됨) 재전송하고 WLAN 인터페이스를 통해 성공적으로 라우팅됩니다. 그러나 wlan 인터페이스에 동적 IP가 MASQUERADE
있고 인터페이스 주소를 명시 적으로 지정하지 않기 위해 사용하려고 할 수 있습니다 . 사용하는 방법은 다음과 같습니다 MASQUERADE
.
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
" 10.0.55.1
"IP 주소가 다릅니다. 다른 주소입니다. 여기서 IP를 사용할 수 있지만 중요하지 않습니다. 이전에 소스 IP를 변경하면 패킷이 인터페이스의 nat/POSTROUTING
체인에 도달 wlp2s0
합니다. 그리고 이제는 무선 랜 인터페이스를위한 고정 IP에 의존하지 않습니다.
접근법 # 3
을 사용할 수도 있습니다 fwmark
. 그렇게 할 필요는 SNAT
없지만 나가는 패킷 만 캡처 할 수 있습니다.
먼저 다른 네트워크에 속하는 패킷을 전달 하기 때문에 역방향 경로 필터링 을 비활성화해야 tun0
합니다.
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
이것은 데비안 8 박스에서 작동하는 라우팅 과 넷 필터 를 위한 또 다른 "해킹" 이지만 여전히 자연스럽고 해킹을 사용하지 않기 때문에 첫 번째 방법을 사용하는 것이 좋습니다.
당신은 또한 투명한 프록시 로서 당신의 어플리케이션을 구축하는 것을 고려할 수 있습니다 . 나는 tun 장치의 패킷을 분석하는 것이 훨씬 쉬울 것이라고 생각합니다.
-j SNAT
,하지-s SNAT