Created
August 23, 2018 18:39
-
-
Save vbuaraujo/073ccd3d8a15bf393552e1a4830b87ce to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# vpnsetup.sh - Set up a L2TP VPN on Debian/Ubuntu systems. | |
# Written by Vítor De Araújo <https://elmord.org/>. | |
# Version 1.2, 2018-08-23. | |
# Location where the VPN control script will be installed. | |
VPNCTL_SCRIPT=/usr/local/bin/vpn | |
# Am I bash? | |
[[ 1 ]] 2>/dev/null || { | |
echo "ERROR: I need to run with 'bash', not 'sh'." | |
exit 1 | |
} | |
yes_or_no() { | |
local prompt="$1" reply | |
while :; do | |
read -n 1 -p "$prompt [y/n] " reply | |
echo "" | |
case "$reply" in | |
[yY]) return 0 ;; | |
[nN]) return 1 ;; | |
*) echo "Please answer 'y' or 'n'!" ;; | |
esac | |
done | |
} | |
prompt() { | |
local prompt="$1" var="$2" | |
while :; do | |
read -p "$prompt" "$var" | |
if [[ -z "${!var}" ]]; then | |
echo "Please type an answer!" | |
else | |
return 0 | |
fi | |
done | |
} | |
# Am I root? | |
if [[ $UID -ne 0 ]]; then | |
echo "ERROR: I need to run as root." | |
exit 1 | |
fi | |
# Ask configs from user. | |
echo "WARNING: This script will overwrite your IPSec and xl2tpd files." | |
echo "If you have other VPNs configured, they will be lost!" | |
yes_or_no "Continue?" || exit | |
prompt "Enter the remote IP address: " REMOTE_IP | |
prompt "Enter the VPN secret key: " PSK | |
prompt "Enter your username: " USERNAME | |
prompt "Enter your password: " PASSWORD | |
echo "" | |
echo "I need to know your local IP address." | |
# Try to discover local IP address. | |
LOCAL_IP= | |
local_ips="$( | |
ip addr | | |
sed -n 's/^ *inet \([^/]*\).*/\1/p' | | |
grep -vF '127.0.0.1' | |
)" | |
local_ips_count="$(wc -l <<<"$local_ips")" | |
if (( local_ips_count == 1 )) && | |
yes_or_no "Is your local IP address $local_ips?" | |
then | |
LOCAL_IP="$local_ips" | |
else | |
if (( local_ips_count > 1 )); then | |
echo "Hint: it's probably one of these:" | |
echo "$local_ips" | |
fi | |
prompt "Enter your local IP address: " LOCAL_IP | |
fi | |
echo "" | |
# Install things. | |
echo "Running 'apt-get update' before installing packages can help" | |
echo "avoid some installation errors." | |
if yes_or_no "Do you want to run it?"; then | |
apt-get update | |
fi | |
echo "Installing xl2tpd..." | |
apt-get install xl2tpd | |
if yes_or_no "Download and compile Openswan?"; then | |
echo "Downloading dependencies..." | |
apt-get install --no-install-recommends \ | |
gcc make libc6-dev libgmp3-dev flex bison || { | |
yes_or_no "Errors while installing dependencies. Continue?" || | |
exit 1 | |
} | |
mkdir /tmp/openswan | |
cd /tmp/openswan | |
wget https://download.openswan.org/openswan/openswan-latest.tar.gz \ | |
-O pkg-openswan-latest.tar.gz | |
tar -xvf pkg-openswan-latest.tar.gz | |
cd openswan-* | |
make programs | |
make install | |
make install programs | |
fi | |
# Create config files. | |
cat <<EOF >/etc/ipsec.conf | |
version 2.0 # conforms to second version of ipsec.conf specification | |
config setup | |
dumpdir=/var/run/pluto/ | |
nat_traversal=yes | |
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10 | |
oe=off | |
protostack=auto | |
conn L2TP-PSK-CLIENT | |
authby=secret | |
pfs=no | |
rekey=yes | |
keyingtries=3 | |
type=transport | |
left=$LOCAL_IP | |
leftprotoport=17/1701 | |
right=$REMOTE_IP | |
rightprotoport=17/1701 | |
auto=add | |
EOF | |
cat <<EOF >/etc/ipsec.secrets | |
$LOCAL_IP $REMOTE_IP : PSK "$PSK" | |
EOF | |
cat <<EOF >/etc/xl2tpd/xl2tpd.conf | |
[lac L2TPserver] | |
lns = $REMOTE_IP | |
; require chap = yes | |
; refuse pap = yes | |
; require authentication = yes | |
ppp debug = yes | |
pppoptfile = /etc/ppp/options.l2tpd.client | |
length bit = yes | |
EOF | |
cat <<EOF >/etc/ppp/options.l2tpd.client | |
ipcp-accept-local | |
ipcp-accept-remote | |
refuse-eap | |
require-mschap-v2 | |
noccp | |
noauth | |
idle 1800 | |
mtu 1410 | |
mru 1410 | |
#defaultroute | |
#usepeerdns | |
debug | |
connect-delay 5000 | |
name "$USERNAME" | |
password "$PASSWORD" | |
EOF | |
# This seems to be necessary on Ubuntu, though not Debian. | |
NETFILTER_MODULES_FILE="/etc/modules-load.d/vpn-netfilter.conf" | |
cat <<EOF >"$NETFILTER_MODULES_FILE" | |
nf_nat_pptp | |
nf_conntrack_pptp | |
nf_conntrack_proto_gre | |
EOF | |
echo "Loading netfilter modules..." | |
while read module; do | |
modprobe "$module" | |
done <"$NETFILTER_MODULES_FILE" | |
# Create the vpn script. | |
cat <<'EOF' >"$VPNCTL_SCRIPT" | |
#!/bin/bash | |
usage() { | |
echo "Usage: ${0##*/} up|down" >&2 | |
} | |
restart_services() { | |
echo "Stopping xl2tpd..." | |
service xl2tpd stop | |
sleep 5 | |
echo "Restarting ipsec..." | |
/etc/init.d/ipsec restart || service ipsec restart | |
sleep 2 | |
echo "Starting xl2tpd..." | |
service xl2tpd start | |
sleep 5 | |
} | |
vpn_up() { | |
restart_services | |
echo "Bringing up IPsec client connection..." | |
ipsec auto --up L2TP-PSK-CLIENT | |
sleep 2 | |
echo "Bringing up xl2tpd connection..." | |
start_tail_syslog | |
echo "c L2TPserver" >/var/run/xl2tpd/l2tp-control | |
sleep 15 | |
stop_tail_syslog | |
echo "Adding route to remote network..." | |
#route add -net 10.98.0.0/24 dev ppp0 | |
ip route add 10.98.0.0/24 dev ppp0 | |
echo "Done!" | |
} | |
vpn_down() { | |
echo "Bringing down xl2tpd connection..." | |
start_tail_syslog | |
echo "d L2TPserver" >/var/run/xl2tpd/l2tp-control | |
sleep 10 | |
stop_tail_syslog | |
echo "Bringing down IPsec client connection..." | |
ipsec auto --down L2TP-PSK-CLIENT | |
echo "Done!" | |
} | |
start_tail_syslog() { | |
tail -f /var/log/syslog & | |
tail_pid="$!" | |
disown # Avoid annoying 'Terminated' message at the end. | |
trap "kill $tail_pid; exit" EXIT INT | |
} | |
stop_tail_syslog() { | |
kill "$tail_pid" | |
trap - EXIT INT | |
} | |
[[ $# -eq 1 ]] || { usage; exit 1; } | |
case "$1" in | |
up) vpn_up ;; | |
down) vpn_down ;; | |
*) usage; exit 1 ;; | |
esac | |
EOF | |
chmod 755 "$VPNCTL_SCRIPT" | |
echo "" | |
echo "Script $VPNCTL_SCRIPT created." | |
echo "You can now run '${VPNCTL_SCRIPT##*/} up' to bring up the VPN." | |
echo "" | |
if yes_or_no "Do you want to start the VPN now?"; then | |
echo "Running '${VPNCTL_SCRIPT##*/} up'..." | |
"$VPNCTL_SCRIPT" up | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment