|
#!/bin/bash -x |
|
|
|
# This script encapsulates a dumb non-configurable device which creates a USB NIC with a static address. |
|
# The encapsulation allows the host system to communicate with this device using a different IP address and |
|
# makes sure the non-configurable static address of the device is not normally accessible or propagated via ARP. |
|
|
|
: ${GPS_DEV:=enp6s0f3u1u3} # The non-configurable device |
|
[ -n "$1" ] && GPS_DEV="$1" |
|
|
|
: ${NS:=reach} # Network namespace, can be anything |
|
: ${NET:=24} # Network mask |
|
: ${HOST_IP:=192.168.4.1} # Static IP of the host that will be used for communication with the dumb device |
|
: ${HOST_NS_IP:=192.168.4.2} # Static IP of the host inside the network namespace $NS (not important) |
|
: ${GPS_NS_IP:=192.168.4.3} # Static IP under which the dumb device will be accessible from the host |
|
: ${HOST_FAKE_IP:=192.168.2.1} # Fake IP address of the host computer in the subnet of the dumb device (not important, but dumb device has to have a route and ARP to it) |
|
: ${GPS_IP:=192.168.2.15} # Static IP address of the dumb device |
|
|
|
# With the given configuration, you will be able to `ping 192.168.4.3` from the host, while actually pinging the `192.168.2.15` static IP of the dumb device. |
|
# If you can SSH to the dumb device, then the host computer is reachable via `192.168.2.1`. |
|
|
|
# Create the network namespace |
|
ip netns add $NS |
|
|
|
# Create a tunnel between the host and the network namespace |
|
ip link add host-$NS type veth peer name ns-$NS |
|
|
|
# Move the dumb device's interface and one end of the tunnel to the namespace |
|
ip link set $GPS_DEV netns $NS |
|
ip link set ns-$NS netns $NS |
|
|
|
# Bring up all 3 devices |
|
ip link set host-$NS up |
|
ip -n $NS link set ns-$NS up |
|
ip -n $NS link set $GPS_DEV up |
|
|
|
# Assign static IP addresses to the devices |
|
ip addr add $HOST_IP/$NET dev host-$NS |
|
ip -n $NS addr add $HOST_NS_IP/$NET dev ns-$NS |
|
ip -n $NS addr add $HOST_FAKE_IP/$NET dev $GPS_DEV |
|
|
|
# Tell the network inside namespace that all unknown traffic should be directed through the tunnel. |
|
ip netns exec $NS ip ro add default dev ns-$NS |
|
|
|
# Enable IPv4 forwarding from the host to the GPS device |
|
echo 1 > /proc/sys/net/ipv4/ip_forward |
|
# Enable IPv4 forwarding inside the namespace |
|
echo 1 | ip netns exec $NS tee /proc/sys/net/ipv4/ip_forward |
|
|
|
# Enable proxy ARP behavior inside the namespace. This is needed so that we can fake the addresses and it works both on the IP and ARP layer. |
|
echo 1 | ip netns exec $NS tee /proc/sys/net/ipv4/conf/$GPS_DEV/proxy_arp |
|
echo 1 | ip netns exec $NS tee /proc/sys/net/ipv4/conf/$GPS_DEV/proxy_arp_pvlan |
|
echo 1 | ip netns exec $NS tee /proc/sys/net/ipv4/conf/ns-$NS/proxy_arp |
|
echo 1 | ip netns exec $NS tee /proc/sys/net/ipv4/conf/ns-$NS/proxy_arp_pvlan |
|
|
|
# Set up standard 1:1 NAT inside the namespace between the dumb device and one end of the tunnel |
|
ip netns exec $NS iptables -t nat -A PREROUTING -i $GPS_DEV -d $HOST_FAKE_IP -j DNAT --to $HOST_IP |
|
ip netns exec $NS iptables -t nat -A PREROUTING -i ns-$NS -d $GPS_NS_IP -j DNAT --to $GPS_IP |
|
ip netns exec $NS iptables -t nat -A POSTROUTING -o $GPS_DEV -s $HOST_IP -j SNAT --to $HOST_FAKE_IP |
|
ip netns exec $NS iptables -t nat -A POSTROUTING -o ns-$NS -s $GPS_IP -j SNAT --to $GPS_NS_IP |
|
|
|
# These gateways are needed so that proxy ARP can find which interfaces to assign to the fake IP addresses. |
|
ip netns exec $NS route add $HOST_FAKE_IP gw 127.0.0.1 |
|
ip netns exec $NS route add $GPS_NS_IP gw 127.0.0.1 |
|
|
|
# Expose a TCP port from the dumb device on a different port of the host computer |
|
: ${GPS_PORT:=80} # The port on the dumb device on which a service is running |
|
: ${HOST_PORT:=8088} # The port on host on which the service will be available (on any interface); feel free to change it to port 80 if you do not need Apache running on the host |
|
iptables -A FORWARD -p tcp -d $GPS_NS_IP --dport $GPS_PORT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT |
|
iptables -A FORWARD -p tcp -s $GPS_NS_IP --sport $GPS_PORT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT |
|
iptables -t nat -A PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to-destination $GPS_NS_IP:$GPS_PORT |
|
iptables -t nat -A POSTROUTING -o host-$NS -j MASQUERADE |
Names of the files have underscores instead of slashes because Gists do not allow absolute paths...