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


12

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

  1. 검열 될 가능성이있는 패킷을 파악하여 터널링합니다.
  2. 다른 모든 트래픽은 그대로 유지하십시오.

당신은 내가 anticensorship 도구를 구축하려고하는 것 같아요. 신뢰할 수있는 DNS 만 사용할 수 있기 때문에
터널링에 대한 결정은 tun0 프로세스 내에서 이루어져야합니다
.

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

아래는 모든 트래픽이 tun0을 통과하고 실패 (핑 실패)하는 방법입니다.

컴파일

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

구성

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. 테이블 존 만들기

    $ 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캡처 된 패킷이 표시되지 않습니다 iif tun0 lookup main. 이는 규칙을 통해 패킷이 tun0에서 wlp2s0으로 전송되지 않음을 의미 합니다.

  2. 내가 대체 할 때 tun0lo사방 그것은 나를 위해 일했습니다.

또한 시도

  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

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

답변:


10

따라서 구성에서 인터페이스를 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.1wlp2s0출력 패킷에 대한 인터페이스 할당 주소 로 변경해야 합니다. 모든 연결을 기억하고 응답 패킷이 되돌아 오면 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

이제, SNATiptables -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
ilyaigpetrov

작동하지만 성능이 매우 간헐적입니다 (10 초 동안 정지 한 다음 작업을 계속할 수 있음). 왜 이런 일이 발생하고 어떻게 해결할 수 있는지 알아 보겠습니다.
ilyaigpetrov

1
죄송합니다. 오타였습니다. 내 답변에 다른 접근법을 추가했습니다. 성능 문제에 대해 모른다. 그런데 iptables DNAT와 함께 투명한 프록시를 사용하여 트래픽을 필터링하고 전환하지 않는 이유는 무엇입니까?
tifssoft

나는 당신의 마크 접근법을 재현 할 수 없습니다. 나는 그것에 추가 sudo ip rule add iif tun0 lookup main priority 500했지만 여전히 작동하지 않았습니다. 나는이 접근법이 마음에 들지 않습니다.
ilyaigpetrov 2016

1
새로운 접근 방식에 감사드립니다. 단계별로 수행했으며 완벽하게 작동했습니다. 그러나 왜 우리가 ip를 변경 해야하는지 이해하지 못합니다. 가장 중요한 것은 작동합니다. TCP 프록시를 사용한 계획에 실패한 경우 답변으로 돌아갈 수 있습니다. 당신은 여기에 많은 네트워킹 기술을 보여 주었고 당신의 기술이 탐낼 지 의심 스럽습니다. 행운을 빕니다!
ilyaigpetrov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.