Linux에서 모든 트래픽이 하나의 인터페이스를 통과하도록 만드는 방법

Linux에서 모든 트래픽이 하나의 인터페이스를 통과하도록 만드는 방법

나는자체 작성 인터페이스 tun0(턴/탭기반) 수신한 내용을 출력합니다.
이 인터페이스를 통해 흐르려면 시스템의 모든 트래픽이 필요합니다.
인터페이스의 역할은 다음과 같습니다.

  1. 검열될 가능성이 있는 패킷을 파악하고 이를 터널링합니다.
  2. 다른 모든 트래픽은 그대로 전달합니다.

짐작하셨겠지만 저는 검열 방지 도구를 만들려고 노력하고 있습니다.
터널링에 대한 결정은 tun0 프로세스 내부에서만 이루어져야 합니다.
왜냐하면 그곳에서만 신뢰할 수 있는 DNS를 사용할 수 있기 때문입니다.

자체 작성된 인터페이스 tun0을 통해 모든 트래픽 흐름을 만드는 방법을 보여주기 위해 여러분의 도움이 필요합니다. tun0에 변경이 필요한 경우 그러한 변경 사항을 제공하도록 요청합니다.

다음은 모든 트래픽이 tun0을 통과하도록 시도했지만 실패(핑 실패)한 방법입니다.

컴파일 중

  1. gcc tun0.c
  2. sudo ./a.out

구성

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. John 테이블 생성

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

순서가 중요합니다:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. sudo ip rule add iif tun0 lookup main priority 500

    $ ip rule
    0:      from all lookup local 
    500:    from all iif tun0 lookup main 
    32765:  from all lookup John 
    32766:  from all lookup main 
    35000:  from all lookup default 
    

문제 해결

  1. sudo tcpdump -i wlp2s0 -qtln icmp그러면 ping -I tun0 8.8.8.8캡처된 패킷이 표시되지 않습니다. 이는 규칙을 통해 tun0에서 wlp2s0으로 패킷이 전송되지 않음을 의미합니다 iif tun0 lookup main.

  2. tun0내가 모든 곳 으로 교체했을 때 lo그것은 나를 위해 일했습니다.

또한 시도

  1. rp_filter=0역방향 경로 필터링 끄기/etc/sysctl.conf

답변 문제 해결

iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD " 
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT " 
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING " 
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog

답변에서 수정된 소스도 있습니다.여기.

답변1

따라서 구성에서 처음에 네트워크로 보내려고 하는 모든 패킷은 인터페이스를 10.0.0.1통과 tun0하고 로컬 주소가 이기 때문 10.0.0.1입니다. 패킷을 캡처하면 지금까지 모든 것이 정상입니다.
이제 tun0패킷을 더 보냅니다.소스 주소당신 은 10.0.0.1패킷이 다른 인터페이스를 통해 나가기를 원합니다( wlp2s0귀하의 경우). 그건라우팅먼저 라우팅을 활성화해 보겠습니다.

sysctl -w net.ipv4.ip_forward=1

그 후, 패킷이 wlan 인터페이스의 소스 주소가 아닌 소스 주소로 떠나는 것을 볼 수 있습니다(제 생각에 예상할 수 있는 것입니다) tcpdump. 따라서 소스 주소를 변경해야 하며 이를 호출합니다.wlp2s010.0.0.1소스 NAT. 리눅스에서는 다음의 도움으로 쉽습니다.넷필터/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.넷필터소스 IP를 출력 패킷의 인터페이스 할당 주소 10.0.0.1로 변경해야 합니다. wlp2s0이는 모든 연결을 기억하고 응답 패킷이 되돌아갈 때(있는 경우) 인터페이스에 wlp2s0할당된 주소 의 대상 주소를 변경합니다 10.0.0.1("conntrack" 기능).
글쎄, 그래야 하지만 그렇지 않습니다. 것 같다,넷필터OUTPUT이러한 복잡한 라우팅 구성과 동일한 패킷이 먼저 체인을 통과한 다음 라우팅되어 체인에 도달한다는 사실과 혼동됩니다 PREROUTING. 적어도 Debian 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/POSTROUTINGSNAT

접근법 #1

혼란을 없애는 가장 좋은 방법넷필터tun0.c애플리케이션 에서 패킷의 소스 IP 주소를 변경하는 것입니다 . 가장 자연스러운 방법이기도 합니다. 우리는10.0.0.1을 10.0.0.2로 변경바깥으로 가는 길과10.0.0.2~10.0.0.1돌아 오는 길에. 소스주소 변경코드로
수정했습니다 .tun0.c여기 새 파일이 있습니다그리고여기 패치파일이 있어요당신을 위해 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

" " IP 주소를 참고하십시오 10.0.55.1. 이는 다릅니다. 여기서는 어떤 IP든 사용할 수 있습니다. 상관없습니다. 이전에 소스 IP를 변경하면 패킷이 인터페이스 nat/POSTROUTING의 체인에 도달합니다. wlp2s0이제 WLAN 인터페이스는 고정 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

그것은 또 다른 "해킹"입니다라우팅그리고넷필터내 Debian 8 상자에서 작동하지만 여전히 첫 번째 접근 방식이 더 자연스럽고 해킹을 사용하지 않기 때문에 권장합니다.


또한 애플리케이션을 다음과 같이 구축하는 것을 고려할 수도 있습니다.투명 프록시. tun 장치에서 패킷을 분석하는 것보다 훨씬 쉬울 것이라고 생각합니다.

관련 정보