準(zhǔn)備環(huán)境
- 創(chuàng)建tun設(shè)備
- 啟動(dòng)tun設(shè)備
- 設(shè)置ip
- 設(shè)置nat铜跑,將源地址改為對(duì)應(yīng)的網(wǎng)關(guān)地址
- 允許tun設(shè)備上對(duì)應(yīng)網(wǎng)段的進(jìn)出流量
# Sets up a tun/tap device on Linux
sudo ip tuntap add name tun0 mode tun user $USER
sudo ip link set tun0 up
sudo ip addr add 192.0.2.1 peer 192.0.2.2 dev tun0
sudo iptables -t nat -A POSTROUTING -s 192.0.2.2 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -s 192.0.2.2 -j ACCEPT
sudo iptables -A FORWARD -o tun0 -d 192.0.2.2 -j ACCEPT
程序讀寫tun設(shè)備
# Sends a SYN packet to `example.com`
import struct
from fcntl import ioctl
def openTun(tunName):
tun = open("/dev/net/tun", "r+b", buffering=0)
LINUX_IFF_TUN = 0x0001
LINUX_IFF_NO_PI = 0x1000
LINUX_TUNSETIFF = 0x400454CA
flags = LINUX_IFF_TUN | LINUX_IFF_NO_PI
ifs = struct.pack("16sH22s", tunName, flags, b"")
ioctl(tun, LINUX_TUNSETIFF, ifs)
return tun
syn = b'E\x00\x00,\x00\x01\x00\x00@\x06\x00\xc4\xc0\x00\x02\x02"\xc2\x95Cx\x0c\x00P\xf4p\x98\x8b\x00\x00\x00\x00`\x02\xff\xff\x18\xc6\x00\x00\x02\x04\x05\xb4'
tun = openTun(b"tun0")
tun.write(syn)
reply = tun.read(1024)
print(repr(reply))
通過tcpdump抓包
(base) [root@iZ8vb0t5v537xbzma7j0ryZ ~]# tcpdump -ni tun0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
21:54:45.179898 IP 192.0.2.2.30732 > 34.194.149.67.http: Flags [S], seq 4101019787, win 65535, options [mss 1460], length 0
21:54:45.408688 IP 34.194.149.67.http > 192.0.2.2.30732: Flags [S.], seq 3807671113, ack 4101019788, win 64480, options [mss 1240], length 0