Отправить необработанный IP-пакет с устройства Tun

Я пытаюсь программно построить и отправить пакет IP через устройство TUN.

Я настроил устройство TUN и правильные маршруты:

# ip tuntap add mode tun tun0
# ip link set tun0 up
# ip addr add 10.0.0.2/24 dev tun0

что приводит к:

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use 
Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    600    0        0 wlp3s0
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 tun0
192.168.0.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0

$ ifconfig tun0
tun0: flags=4241<UP,POINTOPOINT,NOARP,MULTICAST>  mtu 1500
    inet 10.0.0.2  netmask 255.255.255.0  destination 10.0.0.2
    inet6 fe80::f834:5267:3a1:5d1d  prefixlen 64  scopeid 0x20<link>
    unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)

Переадресация IP включена: # echo 1 > /proc/sys/net/ipv4/ip_forward

Я настроил NAT для tun0 пакеты:

# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o wlp3s0 -j MASQUERADE
# iptables -t nat -L -v
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination                   
0     0 MASQUERADE  all  --  any    wlp3s0  10.0.0.0/24          anywhere

Тогда у меня есть сценарий Python для производства ICMP пакеты:

import os
from fcntl import ioctl
import struct
import time
import random

# pip install pypacker==4.0
from pypacker.layer3.ip import IP
from pypacker.layer3.icmp import ICMP

TUNSETIFF = 0x400454ca
IFF_TUN   = 0x0001
IFF_NO_PI = 0x1000

ftun = os.open("/dev/net/tun", os.O_RDWR)
ioctl(ftun, TUNSETIFF, struct.pack("16sH", b"tun0", IFF_TUN | IFF_NO_PI))

req_nr = 1
req_id = random.randint(1, 65000)
while True:
    icmp_req = IP(src_s="10.0.0.2", dst_s="8.8.8.8", p=1) +\
        ICMP(type=8) +\
        ICMP.Echo(id=req_id, seq=req_nr, body_bytes=b"povilas-test")
    os.write(ftun, icmp_req.bin())
    time.sleep(1)
    req_nr += 1

Я вижу пакеты, исходящие из tun0 интерфейс:

# tshark -i tun0
1 0.000000000     10.0.0.2 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb673, seq=1/256, ttl=64
2 1.001695939     10.0.0.2 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb673, seq=2/512, ttl=64
3 2.003375319     10.0.0.2 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb673, seq=3/768, ttl=6

Но wlp3s0 интерфейс молчит, таким образом, кажется, что пакеты не получают NAT и направляются в wlp3s0 интерфейс, который является моей картой WLAN.

Есть идеи, что мне не хватает?

1 ответ

Решение

Я использую Debian 9. И оказывается, что пересылка пакетов была отключена - по умолчанию для цепочки FORWARD используется DROP:

# iptables -L -v
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Поэтому я изменил политику:

# iptables -P FORWARD ACCEPT
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Кроме того, я должен был изменить IP адрес источника пакета, отличный от 10.0.0.2 который является предпочтительным адресом источника для tun0 интерфейс:

$ ip route
10.0.0.0/24 dev tun0 proto kernel scope link src 10.0.0.2

Поэтому я изменил адрес источника пакета на 10.0.0.4:

icmp_req = IP(src_s="10.0.0.4", dst_s="8.8.8.8", p=1) +\
    ICMP(type=8) +\
    ICMP.Echo(id=req_id, seq=req_nr, body_bytes=b"povilas-test")

Затем ядро ​​начало пересылку пакетов из tun0 интерфейс к интерфейсу шлюза:

# tshark -i wlp3s0

5 0.008428567 192.168.0.103 → 8.8.8.8      ICMP 62 Echo (ping) request  id=0xb5c7, seq=9/2304, ttl=63
6 0.041114028      8.8.8.8 → 192.168.0.103 ICMP 62 Echo (ping) reply    id=0xb5c7, seq=9/2304, ttl=48 (request in 5)

Также пинг ответы были отправлены обратно tun0:

# tshark -i tun0

1 0.000000000     10.0.0.4 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb5c7, seq=113/28928, ttl=64
2 0.035470191      8.8.8.8 → 10.0.0.4     ICMP 48 Echo (ping) reply    id=0xb5c7, seq=113/28928, ttl=47 (request in 1)
Другие вопросы по тегам