Skip to content

Instantly share code, notes, and snippets.

@justmao945
Last active December 14, 2015 17:29
Show Gist options
  • Save justmao945/5122525 to your computer and use it in GitHub Desktop.
Save justmao945/5122525 to your computer and use it in GitHub Desktop.
#!/bin/bash
####################
# Variables
####################
## How many seconds to wait for the ppp to come up each try
TIMEOUT=120
## How many seconds to wait for l2tpd to restart
L2TPD_TIMEOUT=10
## LAC name in config file
L2TPD_LAC=zju
L2TPD_CONTROL_DIR=/var/run/xl2tpd
L2TPD_CONTROL_FILE=$L2TPD_CONTROL_DIR/l2tp-control
L2TPD_INIT_FILE=/etc/init.d/xl2tpd
L2TPD_CFG_FILE=/etc/xl2tpd/xl2tpd.conf
CHAP_SECRET_FILE=/etc/ppp/chap-secrets
PPP_OPT_FILE=/etc/xl2tpd/options
LNS=10.5.1.9
## Global variables set by function
GW=0.0.0.0
PPP=ppp0
####################
# Commands
####################
function usage
{
echo "$0: A utility for ZJU school L2TP VPN."
echo "Usage: $0 [ACTION]"
echo
echo "Actions: "
echo " Default Connect."
echo " -d Disconnect."
echo " -r Reconnect."
echo " -c Configure."
echo " -h Show this information."
echo
}
function connect
{
if ppp_alive ; then
echo "[MSG] VPN already connected."
else
restart_l2tpd && bring_up_ppp && setup_route
fi
}
function disconnect
{
echo -n "[MSG] Disconnecting VPN ... "
echo "d $L2TPD_LAC" > $L2TPD_CONTROL_FILE
sleep 1
echo "Done!"
return 0
}
function reconnect
{
disconnect && restart_l2tpd && bring_up_ppp && setup_route
}
function configure
{
echo "Configure L2TP VPN for ZJU.";
read_param && write_settings && free_param && reconnect
}
####################
# Internal utility functions
####################
function init
{
GW=$(ip route get $LNS 2>/dev/null |grep "$LNS"|awk {'print $3'})
if [ -z "$GW" ];then
echo "[ERR] Network is not available"
exit 1
fi
if [ $(expr length "$GW") -ge 6 ]; then
PPP=ppp0
else
PPP=ppp1
GW=$(ip add show "$GW"| grep inet|awk {'print $2'})
fi
}
function super_user
{
if [ "$UID" = "0" ]; then
return 0 # Yes, super user
else
return 1
fi
}
function read_param
{
read -p "Username: " username
read -s -p "Password: " password
echo
}
function write_settings
{
if [ -e $L2TPD_CFG_FILE ]; then
mv $L2TPD_CFG_FILE $L2TPD_CFG_FILE.old
fi
cat>$L2TPD_CFG_FILE<<EOF
[global] ; Global parameters:
port = 1701 ; * Bind to port 1701
access control = yes ; * Refuse connections without IP match
rand source = dev ; Source for entropy for random
[lac zju]
lns = $LNS ; * Who is our LNS?
redial = yes ; * Redial if disconnected?
redial timeout = 3 ; * Wait n seconds between redials
max redials = 999 ; * Give up after n consecutive failures
require chap = yes ; * Require CHAP auth. by peer
refuse pap = yes ; * Refuse PAP authentication
require authentication = no ; * Require peer to authenticate
ppp debug = yes ; * Turn on PPP debugging
pppoptfile = $PPP_OPT_FILE ; * ppp options file for this lac
name = $username
EOF
if [ -e $PPP_OPT_FILE ]; then
mv $PPP_OPT_FILE $PPP_OPT_FILE.old
fi
cat>$PPP_OPT_FILE<<EOF
asyncmap 0
noauth
crtscts
lock
hide-password
modem
netmask 255.255.255.0
proxyarp
lcp-echo-failure 4
lcp-echo-interval 30
ipcp-accept-local
ipcp-accept-remote
noipx
defaultroute
mru 1400
mtu 1400
EOF
sed -i /$username/d $CHAP_SECRET_FILE
echo "$username * $password *" >> $CHAP_SECRET_FILE
chmod 600 $CHAP_SECRET_FILE
return 0
}
function free_param
{
unset username
unset password
return 0
}
function ppp_alive
{
if ip addr show | grep "inet.*$PPP" > /dev/null; then
return 0 # Yes, connected
else
return 1
fi
}
function bring_up_ppp
{
[ -d $L2TPD_CONTROL_DIR ] || mkdir $L2TPD_CONTROL_DIR
if [ ! -e $L2TPD_CONTROL_FILE ]; then
echo "[MSG] L2tpd daemon not running!"
if ! restart_l2tpd ; then
return 1 # l2tpd not started
fi
fi
echo "c $L2TPD_LAC" > $L2TPD_CONTROL_FILE
for i in $(seq 0 $TIMEOUT)
do
if ppp_alive; then
echo " Done!"
return 0 # Yes, brought up!
fi
echo -n -e "\\r[MSG] Trying to bring up vpn... $i secs..."
sleep 1
done
echo
echo "[ERR] Failed to bring up vpn!"
return 1
}
function setup_route
{
echo "[MSG] Detected gateway: $GW, PPP device: $PPP ."
echo -n "[MSG] Setting up route table... "
ip route add 10.0.0.0/8 metric 10 via $GW 2>/dev/null
ip route add 210.32.0.0/20 metric 10 via $GW 2>/dev/null
ip route add 210.32.128.0/18 metric 10 via $GW 2>/dev/null
ip route add 222.205.0.0/16 metric 10 via $GW 2>/dev/null
ip route del default 2>/dev/null
ip route add default dev $PPP 2>/dev/null
echo "Done!"
}
function restart_l2tpd
{
echo "[MSG] Restarting l2tpd... "
$L2TPD_INIT_FILE restart
for i in $(seq $L2TPD_TIMEOUT)
do
if [ -e $L2TPD_CONTROL_FILE ]; then
echo "[MSG] Done!"
return 0 # Successfully restarted!
fi
sleep 1
done
echo "[ERR] Failed to restart l2tpd!"
return 1 # Failed to restart l2tpd
}
####################
# Main
####################
if ! super_user ; then
echo "[ERR] You must be super user to run this utility!"
exit 1
fi
init ## Get $GW and $PPP
if [ $# -lt 1 ]; then
connect
elif [ "$1" = "-d" ]; then
disconnect
elif [ "$1" = "-r" ]; then
reconnect
elif [ "$1" = "-c" ]; then
configure
elif [ "$1" = "-h" ]; then
usage
else
echo "[ERR] Unknown parameter.";
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment