Skip to content

Instantly share code, notes, and snippets.

@congzhangzh
Forked from vishvananda/tunnel.sh
Last active November 9, 2019 12:53
Show Gist options
  • Save congzhangzh/cc255b2e570670583d9baf51faf59f6c to your computer and use it in GitHub Desktop.
Save congzhangzh/cc255b2e570670583d9baf51faf59f6c to your computer and use it in GitHub Desktop.
A script setup an ip sec tunnel to a server and use server as default route, this in fact create a security vpn which is very fast and NAT friendly which work for both NAT behind host. All the input parameter need be set in file which mark as input section!!!
#!/bin/bash
#
# the basic idea from https://gist.github.com/vishvananda/7094676
#
# if [ "$4" == "" ]; then
# echo "usage: $0 <local_ip> <remote_ip> <new_local_ip> <new_remote_ip>"
# echo "creates an ipsec tunnel between two machines"
# exit 1
# fi
# SRC="$1"; shift
# DST="$1"; shift
# LOCAL="$1"; shift
# REMOTE="$1"; shift
#############################################################begin overview #############################################################
#input
# local base dev
# remote pub
# remote user
# remote base dev
# local vpn ip
# remote vpn ip
# local masq route table ?
#intermedia
# client local
# client pub
# server local
#output
# a sec tunnel and default route to it
#############################################################end overview #############################################################
#-----------------------begin input part----------------------------
LOCAL_DEV='xxxx' # like eth0
REMOTE_IP='xxx.xxx.xxx.xxx' # # server public ip like 8.8.8.8
REMOTE_USER='xxxx' # like ubuntu
REMOTE_DEV='xxxx' # like eth0
LOCAL_VPN_IP="xxx.xxx.xxx.xxx"; # like 10.1.1.2
REMOTE_VPN_IP="xxx.xxx.xxx.xxx"; # like 10.1.1.1
#MASQ_ROUTE_TABLE=5432;
cat <<EOF
--begin input result--
LOCAL_DEV is $LOCAL_DEV
REMOTE_IP is $REMOTE_IP
REMOTE_USER is $REMOTE_USER
REMOTE_DEV is $REMOTE_DEV
LOCAL_VPN_IP is $LOCAL_VPN_IP
REMOTE_VPN_IP is $REMOTE_VPN_IP
MASQ_ROUTE_TABLE is $MASQ_ROUTE_TABLE
--begin input result--
EOF
#-----------------------end input part----------------------------
#-----------------------begin get all intermiedia-------------------------
#SRC="192.168.1.5"; # local local
local_inner_ip=$(ip -4 addr show dev $LOCAL_DEV | grep -oP '(?<=inet\s)[\d\.]+')
local_pub_ip=`curl -4 checkip.dns.he.net 2> /dev/null |grep -oP "([[:digit:]]+\.){3}[[:digit:]]+"`; # local pub
old_default_route=$( ip route| grep -oP '(?<=via ).*(?=dev)' )
remote_inner_ip=$( ssh $REMOTE_USER@$REMOTE_IP ip -4 addr show dev $REMOTE_DEV | grep -oP '(?<=inet\s)[\d\.]+' )
remote_pub_ip=$REMOTE_IP
cat <<EOF
--begin intermiedia result--
local_inner_ip is $local_inner_ip
local_pub_ip is $local_pub_ip
remote_inner_ip is $remote_inner_ip
old_default_route is $old_default_route
--end intermiedia result--
EOF
#------------------------end get all intermedia---------------------------
#####################################################
SRC=$local_inner_ip
DST=$remote_pub_ip; # remote pub
LOCAL=$LOCAL_VPN_IP;
REMOTE=$REMOTE_VPN_IP;
OLD_DEFAULT_ROUTE=$old_default_route
KEY1=0x`dd if=/dev/urandom count=32 bs=1 2> /dev/null| xxd -p -c 64`
KEY2=0x`dd if=/dev/urandom count=32 bs=1 2> /dev/null| xxd -p -c 64`
ID=0x`dd if=/dev/urandom count=4 bs=1 2> /dev/null| xxd -p -c 8`
cat<<EOF
SRC is $SRC
DST is $DST
LOCAL is $LOCAL
REMOTE is $REMOTE
KEY1 is $KEY1
KEY2 is $KEY2
ID is $ID
OLD_DEFAULT_ROUTE is $OLD_DEFAULT_ROUTE
EOF
# #--begin-- pre get something
# SRC_PUB=`curl -4 checkip.dns.he.net 2> /dev/null |grep -oP "([[:digit:]]+\.){3}[[:digit:]]+"`; # local pub
# DST_LOCAL=
# #--end-- pre get something
#echo "spdflush; flush;" | sudo setkey -c
sudo ip xfrm state flush
sudo ip xfrm state add src $SRC dst $DST proto esp spi $ID reqid $ID mode tunnel auth sha256 $KEY1 enc aes $KEY2
sudo ip xfrm state add src $DST dst $SRC proto esp spi $ID reqid $ID mode tunnel auth sha256 $KEY1 enc aes $KEY2
sudo ip xfrm policy flush
# sudo ip xfrm policy add src $LOCAL dst $REMOTE dir out tmpl src $SRC dst $DST proto esp reqid $ID mode tunnel
# sudo ip xfrm policy add src $REMOTE dst $LOCAL dir in tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
sudo ip xfrm policy add src $LOCAL dir out tmpl src $SRC dst $DST proto esp reqid $ID mode tunnel
#sudo ip xfrm policy add src $REMOTE dir fwd tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
#sudo ip xfrm policy add dst $LOCAL dir fwd tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
#sudo ip xfrm policy add src $REMOTE dir in tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
sudo ip xfrm policy add dst $LOCAL dir in tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
sudo ip route add $DST dev $LOCAL_DEV src $SRC via $OLD_DEFAULT_ROUTE
sudo ip addr add $LOCAL dev lo
#sudo ip route add $REMOTE dev $LOCAL_DEV src $LOCAL
#sudo ip route del default
#sudo ip route replace default dev $LOCAL_DEV src $LOCAL
#sudo ip route add default dev $LOCAL_DEV src $LOCAL
sudo ip route add 0.0.0.0/1 dev $LOCAL_DEV src $LOCAL
sudo ip route add 128.0.0.0/1 dev $LOCAL_DEV src $LOCAL
#sudo ip route replace default via $REMOTE table $MASQ_ROUTE_TABLE
#################################################################################
SRC=$local_pub_ip
DST=$remote_inner_ip; # remote pub
#DST="xx.xx.xx.xx"; # TODO remote local, how?
ssh $REMOTE_USER@$DST /bin/bash << EOF
sudo ip xfrm state flush
sudo ip xfrm state add src $SRC dst $DST proto esp spi $ID reqid $ID mode tunnel auth sha256 $KEY1 enc aes $KEY2
sudo ip xfrm state add src $DST dst $SRC proto esp spi $ID reqid $ID mode tunnel auth sha256 $KEY1 enc aes $KEY2
sudo ip xfrm policy flush
# sudo ip xfrm policy add src $REMOTE dst $LOCAL dir out tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
# sudo ip xfrm policy add src $LOCAL dst $REMOTE dir in tmpl src $SRC dst $DST proto esp reqid $ID mode tunnel
#sudo ip xfrm policy add src $REMOTE dir out tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
sudo ip xfrm policy add dst $LOCAL dir out tmpl src $DST dst $SRC proto esp reqid $ID mode tunnel
#sudo ip xfrm policy add src $LOCAL dir fwd tmpl src $SRC dst $DST proto esp reqid $ID mode tunnel
sudo ip xfrm policy add src $LOCAL dir fwd tmpl src $SRC dst $DST proto esp reqid $ID mode tunnel
sudo ip xfrm policy add src $LOCAL dir in tmpl src $SRC dst $DST proto esp reqid $ID mode tunnel
sudo ip addr add $REMOTE dev lo
#sudo ip route add $LOCAL dev eth1 src $REMOTE
#sudo ip route add $LOCAL dev $REMOTE_DEV src $REMOTE
#sudo ip route replace $LOCAL dev $REMOTE_DEV src $REMOTE
sudo iptables -t nat -D POSTROUTING -s $LOCAL/32 -j MASQUERADE &> /dev/null ; sudo iptables -t nat -A POSTROUTING -s $LOCAL/32 -j MASQUERADE
ping -c1 $LOCAL
EOF
ping -c1 $REMOTE
### --begin-- how to check
# sudo ip route ; sudo ip xfrm policy ; sudo ip xfrm state ; sudo iptables-save ; sudo ip addr
### --end-- how to check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment