V** tunneling
vpn关键词好像会被屏蔽
Task 1: Network Setup
启动容器
测试下列情况
- Host U can communicate with VPN Server.
进入server查看ip
在host中ping server
-
VPN Server can communicate with Host V.
进入server ping 两个host
-
Host U should not be able to communicate with Host V.
进入client,ping两个host(无法成功)
-
Run tcpdump on the router, and sniff the traffific on each of the network. Show that you can capture packets.
进入router启动tcpdump
在host中ping router和另一个host
router中检测到数据包
Task 2: Create and Confifigure TUN Interface
Task 2.a: Name of the Interface
在server router中赋予tun.py权限,并执行
chmod a+x tun.py
tun.py
可以发现tun0接口
Task 2.b: Set up the TUN Interface
在tun.py 中添加下面两行
os.system("ip addr add 192.168.53.99/24 dev {}".format(ifname))
os.system("ip link set dev {} up".format(ifname))
再次查看,该接口有了IP地址
Task 2.c: Read from the TUN Interface
替换tun.py中的循环,在router中启动
while True:
# Get a packet from the tun interface
packet = os.read(tun, 2048)
if packet:
ip = IP(packet)
print(ip.summary())
ping 192.168.53.8,观察tun发现输出了消息
ping 192.168.60.6,tun未输出消息
Task 2.d: Write to the TUN Interface
修改tun.py中的循环
while True:
packet = os.read(tun, 2048)
if packet:
ip=IP(packet)
newip = IP(src='1.2.3.4', dst=ip.src)
newpkt = newip/ip.payload
os.write(tun, bytes(newpkt))
print(newip.summary())
重新ping 192.168.53.8,tun中消息发生了改变
Task 3: Send the IP Packet to VPN Server Through a Tunnel
在volumes中添加tun_server.py文件
#!/usr/bin/env python3
from scapy.all import *
IP_A = "0.0.0.0"
PORT = 9090
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((IP_A, PORT))
while True:
data, (ip, port) = sock.recvfrom(2048)
print("{}:{} --> {}:{}".format(ip, port, IP_A, PORT))
pkt = IP(data)
print(" Inside: {} --> {}".format(pkt.src, pkt.dst))
在server中启动tun_server.py
修改tun.py,替换while循环,重命名为tun_client.py,在client中启动
# Create UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
# Get a packet from the tun interface
packet = os.read(tun, 2048)
if packet:
# Send the packet via the tunnel
sock.sendto(packet, ('10.9.0.11', 9090))
ping 192.168.53.8,server中有输出
ping 192.168.60.5,server中无输出
在tun_client.py中添加路由
Host_V= '192.168.60.0/24'
os.system("ip route add {} dev {} via 192.168.53.99".format(Host_V, ifname))
再次ping 192.168.60.5,server中有了输出
Task 4: Set Up the VPN Server
修改tun_server.py中的内容
#!/usr/bin/env python3
import fcntl
import struct
import os
import time
from scapy.all import *
TUNSETIFF = 0x400454ca
IFF_TUN = 0x0001
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000
Host_U = '192.168.53.0/24'
# Create the tun interface
tun = os.open("/dev/net/tun", os.O_RDWR)
ifr = struct.pack('16sH', b'sun_s%d', IFF_TUN | IFF_NO_PI)
ifname_bytes = fcntl.ioctl(tun, TUNSETIFF, ifr)
# Get the interface name
ifname = ifname_bytes.decode('UTF-8')[:16].strip("\x00")
print("Interface Name: {}".format(ifname))
# Assign an IP address & bring up the interface
os.system("ip addr add 192.168.78.100/24 dev {}".format(ifname))
os.system("ip link set dev {} up".format(ifname))
# Send Host-V package to sun0
os.system("ip route add {} dev {} via 192.168.78.100".format(Host_U, ifname))
IP_A = "0.0.0.0"
PORT = 9090
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((IP_A, PORT))
while True:
data, (ip, port) = sock.recvfrom(2048)
print("{}:{} --> {}:{}".format(ip, port, IP_A, PORT))
packet = IP(data)
print(" Inside: {} --> {}".format(packet.src, packet.dst))
if packet:
ip = packet
if ICMP in ip:
# Send out a packet using the tun interface
os.write(tun, bytes(ip))
print('Send out:')
print(ip.summary())
print()
启动server和client后ping 192.168.60.5
查看wireshark
Task 5: Handling Traffific in Both Directions
替换server和client的循环
server:
# We assume that sock and tun file descriptors have already been created.
while True:
# this will block until at least one interface is ready
ready, _, _ = select.select([sock, tun], [], [])
for fd in ready:
if fd is sock:
data, (ip, port) = sock.recvfrom(2048)
pkt = IP(data)
print("From socket <==: {} --> {}".format(pkt.src, pkt.dst))
... (code needs to be added by students) ...
if fd is tun:
packet = os.read(tun, 2048)
pkt = IP(packet)
print("From tun ==>: {} --> {}".format(pkt.src, pkt.dst))
... (code needs to be added by students) ...
client
# Create UDP socket
IP_A = "0.0.0.0"
PORT = 9090
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((IP_A, PORT))
while True:
# this will block until at least one interface is ready
ready, _, _ = select.select([sock, tun], [], [])
for fd in ready:
if fd is sock:
# IP 0.0.0.0 Port 9090: Has receive a VPN package!!!
data, (ip, port) = sock.recvfrom(2048)
print("{}:{} --> {}:{}".format(ip, port, IP_A, PORT))
packet = IP(data)
print(" Inside: {} --> {}".format(packet.src, packet.dst))
if packet:
ip = packet
# Send out a packet using the tun interface
os.write(tun, bytes(ip))
print('Send out:')
print(ip.summary())
print()
if fd is tun:
# Get a packet from the tun interface
packet = os.read(tun, 2048)
pkt = IP(packet)
print("From tun ==>: {} --> {}".format(pkt.src, pkt.dst))
if packet:
# Send the packet via the tunnel
sock.sendto(packet, ('10.9.0.11', 9090))
client最终可以成功ping到192.168.60.5
Task 6: Tunnel-Breaking Experiment
在保持远程登录在线状态的同时,打破客户端或服务器的隧道服务,都出现了同样的情况,即无法在远程登录界面输入任何文字,并且不再会有新的输出。当短时间重新连回服务时,积压在TUN文件的报文缓存就会被逐个释放。如图:
Task 7: Routing Experiment on Host V
在client删除默认路由,再添加新路由,查看路由信息
Task 8: VPN Between Private Networks
改用新的容器配置命令启动容器
docker-compose -f docker-compose2.yml build
docker-compose -f docker-compose2.yml up
docker-compose -f docker-compose2.yml down
在 HostU 中 ping 不到Host
然后在客户机与服务器同时打开程序(修改server的发送IP地址)。此时左侧已经可以与右侧通信: