Since I run a server for hosting my websites and providing mail, I decided to setup tunnel service as well. Just in case I get stuck in an airport with limited internet access. Initially, I chose ICMP as the tunneling protocol, but more will follow later.
The server is used as the tunnel endpoint, and must always be running the tunnel service, as you never know when you will need it. To accomplish this, I installed hans and configured it using systemd.
[Unit] Description=ICMP Tunneling Daemon After=syslog.target network.target [Service] Type=forking EnvironmentFile=/etc/conf.d/hans Restart=on-abort ExecStart=/usr/bin/hans -s $HANS_IP -d $HANS_DEV -p $HANS_PASS ExecStartPost=/usr/bin/ip link set dev $HANS_DEV mtu 1200 ExecStartPost=/usr/bin/sysctl -w net.ipv4.ip_forward=1 ExecStartPost=/usr/bin/iptables -t nat -A POSTROUTING -o $HANS_WAN -j MASQUERADE ExecStartPost=/usr/bin/iptables -A FORWARD -i $HANS_DEV -j ACCEPT ExecStopPost=/usr/bin/iptables -D FORWARD -i $HANS_DEV -j ACCEPT ExecStopPost=/usr/bin/iptables -t nat -D POSTROUTING -o $HANS_WAN -j MASQUERADE [Install] WantedBy=multi-user.target
The service file sets up
hans and configures NAT-routing on virtual interface created by
hans. It expects a config file in
HANS_IP=10.0.0.1 HANS_DEV=tun1 HANS_PASS=<password> HANS_WAN=eth0
Now change the password in
/etc/conf.d/hans and test the service with systemctl:
# systemctl start hans
If systemd doesn't complain, you can enable the service at boot time:
# systemctl enable hans
The server is now ready to accept tunnel-connections from the outside.
Since we use ICMP tunneling only occasionally, we don't need
hans to run as a service on our clients. Instead I cooked a little bash script to start
hans and configure the network to use the tunnel as default internet connection:
#!/bin/bash host=<hostname> ip=$(host -t A $host | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") gw=$(ip route | grep default | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") wan=$(ip route | grep default | grep -E -o "dev [a-z]+[0-9]+") pass=<password> hans_gw=10.0.0.1 hans_dev=tun1 if [ $UID -ne 0 ]; then echo Must be root exit 1 fi echo starting icmp tunnel hans -c $host -p $pass -d $hans_dev || exit 1 echo decreasing mtu ip link set dev $hans_dev mtu 1200 || exit 1 echo waiting for hans to connect while sleep 1; do if ip addr show dev $hans_dev | grep -q inet; then break fi done echo adding route to icmp server if ip route | grep -q $ip; then ip route del $ip || exit 1 fi ip route add $ip via $gw $wan || exit 1 echo changing default route to icmp tunnel if ip route | grep -q default; then ip route del default via $gw $wan || exit 1 fi ip route add default via $hans_gw dev $hans_dev || exit 1 echo "Done" echo "" echo "To revert to primary connection, execute the following:" echo " # killall hans" echo " # ip route add default via $gw $wan"
The script starts
hans with the parameters in the top of the script (don't forget to change the hostname and password), and then configures a route to run the tunnel on, and finally sets the default route to use the tunnel for everything else.