| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- #!/bin/bash
- PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
- export PATH
- #
- # This is a Shell script for configure and start L2TP/IPSec VPN server with Docker image
- #
- # Copyright (C) 2018 Teddysun <[email protected]>
- #
- # Reference URL:
- # https://github.com/libreswan/libreswan
- # https://github.com/xelerance/xl2tpd
- if [ ! -f "/.dockerenv" ]; then
- echo "Error: This script must be run in a Docker container." >&2
- exit 1
- fi
- if ip link add dummy0 type dummy 2>&1 | grep -q "not permitted"; then
- echo "Error: This Docker image must be run in privileged mode." >&2
- exit 1
- fi
- ip link delete dummy0 >/dev/null 2>&1
- rand(){
- index=0
- str=""
- for i in {a..z}; do arr[index]=${i}; index=$(expr ${index} + 1); done
- for i in {A..Z}; do arr[index]=${i}; index=$(expr ${index} + 1); done
- for i in {0..9}; do arr[index]=${i}; index=$(expr ${index} + 1); done
- for i in {1..10}; do str="$str${arr[$RANDOM%$index]}"; done
- echo ${str}
- }
- is_64bit(){
- if [ "$(getconf WORD_BIT)" == "32" ] && [ "$(getconf LONG_BIT)" == "64" ]; then
- return 0
- else
- return 1
- fi
- }
- # Environment file name
- l2tp_env_file="/etc/l2tp.env"
- # Auto generated
- if [ -z "${VPN_IPSEC_PSK}" ] && [ -z "${VPN_USER}" ] && [ -z "${VPN_PASSWORD}" ]; then
- if [ -f "${l2tp_env_file}" ]; then
- echo "Loading previously generated environment variables for L2TP/IPSec VPN Server..."
- . "${l2tp_env_file}"
- else
- echo "L2TP/IPSec VPN Server environment variables is not set. Use default environment variables..."
- VPN_IPSEC_PSK="teddysun.com"
- VPN_USER="vpnuser"
- VPN_PASSWORD="$(rand)"
- echo "VPN_IPSEC_PSK=${VPN_IPSEC_PSK}" > ${l2tp_env_file}
- echo "VPN_USER=${VPN_USER}" >> ${l2tp_env_file}
- echo "VPN_PASSWORD=${VPN_PASSWORD}" >> ${l2tp_env_file}
- chmod 600 ${l2tp_env_file}
- fi
- fi
- # Environment variables:
- # VPN_IPSEC_PSK
- # VPN_USER
- # VPN_PASSWORD
- if [ -z "${VPN_IPSEC_PSK}" ] || [ -z "${VPN_USER}" ] || [ -z "${VPN_PASSWORD}" ]; then
- echo "Error: Environment variables must be specified. please edit your environment file and retry again." >&2
- exit 1
- fi
- if printf '%s' "${VPN_IPSEC_PSK} ${VPN_USER} ${VPN_PASSWORD}" | LC_ALL=C grep -q '[^ -~]\+'; then
- echo "Error: Environment variables must not contain non-ASCII characters." >&2
- exit 1
- fi
- case "${VPN_IPSEC_PSK} ${VPN_USER} ${VPN_PASSWORD}" in
- *[\\\"\']*)
- echo "Error: Environment variables must not contain these special characters like: \\ \" '"
- exit 1
- ;;
- esac
- # Environment variables:
- # VPN_PUBLIC_IP
- PUBLIC_IP=${VPN_PUBLIC_IP:-''}
- [ -z "${PUBLIC_IP}" ] && PUBLIC_IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
- [ -z "${PUBLIC_IP}" ] && PUBLIC_IP=$( wget -qO- -t1 -T2 ipinfo.io/ip )
- # Environment variables:
- # VPN_L2TP_NET
- # VPN_L2TP_LOCAL
- # VPN_L2TP_REMOTE
- # VPN_XAUTH_NET
- # VPN_XAUTH_REMOTE
- # VPN_DNS1
- # VPN_DNS2
- L2TP_NET=${VPN_L2TP_NET:-'192.168.18.0/24'}
- L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.18.1'}
- L2TP_REMOTE=${VPN_L2TP_REMOTE:-'192.168.18.10-192.168.18.250'}
- XAUTH_NET=${VPN_XAUTH_NET:-'192.168.20.0/24'}
- XAUTH_REMOTE=${VPN_XAUTH_REMOTE:-'192.168.20.10-192.168.20.250'}
- DNS1=${VPN_DNS1:-'8.8.8.8'}
- DNS2=${VPN_DNS2:-'8.8.4.4'}
- # Create IPSec config
- cat > /etc/ipsec.conf <<EOF
- version 2.0
- config setup
- protostack=netkey
- nhelpers=0
- uniqueids=no
- interfaces=%defaultroute
- virtual-private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!${L2TP_NET},%v4:!${XAUTH_NET}
- conn shared
- left=%defaultroute
- leftid=${PUBLIC_IP}
- right=%any
- encapsulation=yes
- authby=secret
- pfs=no
- rekey=no
- keyingtries=5
- dpddelay=30
- dpdtimeout=120
- dpdaction=clear
- ike=3des-sha1,3des-sha2,aes-sha1,aes-sha1;modp1024,aes-sha2,aes-sha2;modp1024
- phase2alg=3des-sha1,3des-sha2,aes-sha1,aes-sha2,aes256-sha2_512
- sha2-truncbug=yes
- conn l2tp-psk
- auto=add
- leftprotoport=17/1701
- rightprotoport=17/%any
- type=transport
- phase2=esp
- also=shared
- conn xauth-psk
- auto=add
- leftsubnet=0.0.0.0/0
- rightaddresspool=${XAUTH_REMOTE}
- modecfgdns=${DNS1},${DNS2}
- leftxauthserver=yes
- rightxauthclient=yes
- leftmodecfgserver=yes
- rightmodecfgclient=yes
- modecfgpull=yes
- xauthby=file
- ike-frag=yes
- ikev2=never
- cisco-unity=yes
- also=shared
- EOF
- cat > /etc/xl2tpd/xl2tpd.conf <<EOF
- [global]
- port = 1701
- [lns default]
- local ip = ${L2TP_LOCAL}
- ip range = ${L2TP_REMOTE}
- require chap = yes
- refuse pap = yes
- require authentication = yes
- name = l2tpd
- pppoptfile = /etc/ppp/options.xl2tpd
- length bit = yes
- EOF
- cat > /etc/ppp/options.xl2tpd <<EOF
- +mschap-v2
- ipcp-accept-local
- ipcp-accept-remote
- ms-dns ${DNS1}
- ms-dns ${DNS2}
- noccp
- auth
- mtu 1280
- mru 1280
- proxyarp
- lcp-echo-failure 4
- lcp-echo-interval 30
- connect-delay 5000
- EOF
- cat > /etc/ipsec.secrets <<EOF
- %any %any : PSK "${VPN_IPSEC_PSK}"
- EOF
- cat > /etc/ppp/chap-secrets <<EOF
- ${VPN_USER} l2tpd ${VPN_PASSWORD} *
- EOF
- VPN_PASSWORD_ENC=$(openssl passwd -1 "${VPN_PASSWORD}")
- cat > /etc/ipsec.d/passwd <<EOF
- ${VPN_USER}:${VPN_PASSWORD_ENC}:xauth-psk
- EOF
- chmod 600 /etc/ipsec.secrets /etc/ppp/chap-secrets /etc/ipsec.d/passwd
- # Update sysctl settings
- if is_64bit; then
- SHM_MAX=68719476736
- SHM_ALL=4294967296
- else
- SHM_MAX=4294967295
- SHM_ALL=268435456
- fi
- sysctl -eqw kernel.msgmnb=65536
- sysctl -eqw kernel.msgmax=65536
- sysctl -eqw kernel.shmmax=${SHM_MAX}
- sysctl -eqw kernel.shmall=${SHM_ALL}
- sysctl -eqw net.ipv4.ip_forward=1
- sysctl -eqw net.ipv4.conf.all.accept_source_route=0
- sysctl -eqw net.ipv4.conf.all.accept_redirects=0
- sysctl -eqw net.ipv4.conf.all.send_redirects=0
- sysctl -eqw net.ipv4.conf.all.rp_filter=0
- sysctl -eqw net.ipv4.conf.default.accept_source_route=0
- sysctl -eqw net.ipv4.conf.default.accept_redirects=0
- sysctl -eqw net.ipv4.conf.default.send_redirects=0
- sysctl -eqw net.ipv4.conf.default.rp_filter=0
- sysctl -eqw net.ipv4.conf.eth0.send_redirects=0
- sysctl -eqw net.ipv4.conf.eth0.rp_filter=0
- # Create iptables rules
- iptables -I INPUT 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
- iptables -I INPUT 2 -m conntrack --ctstate INVALID -j DROP
- iptables -I INPUT 3 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
- iptables -I INPUT 4 -p udp -m multiport --dports 500,4500 -j ACCEPT
- iptables -I INPUT 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT
- iptables -I INPUT 6 -p udp --dport 1701 -j DROP
- iptables -I FORWARD 1 -m conntrack --ctstate INVALID -j DROP
- iptables -I FORWARD 2 -i eth+ -o ppp+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
- iptables -I FORWARD 3 -i ppp+ -o eth+ -j ACCEPT
- iptables -I FORWARD 4 -i ppp+ -o ppp+ -s "${L2TP_NET}" -d "${L2TP_NET}" -j ACCEPT
- iptables -I FORWARD 5 -i eth+ -d "${XAUTH_NET}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
- iptables -I FORWARD 6 -s "${XAUTH_NET}" -o eth+ -j ACCEPT
- iptables -A FORWARD -j DROP
- iptables -t nat -I POSTROUTING -s "${XAUTH_NET}" -o eth+ -m policy --dir out --pol none -j MASQUERADE
- iptables -t nat -I POSTROUTING -s "${L2TP_NET}" -o eth+ -j MASQUERADE
- cat <<EOF
- L2TP/IPsec VPN Server with the Username and Password is below:
- Server IP: ${PUBLIC_IP}
- IPSec PSK: ${VPN_IPSEC_PSK}
- Username : ${VPN_USER}
- Password : ${VPN_PASSWORD}
- EOF
- # Load IPsec kernel module
- modprobe af_key
- # Start services
- mkdir -p /run/pluto /var/run/pluto /var/run/xl2tpd
- rm -f /run/pluto/pluto.pid /var/run/pluto/pluto.pid /var/run/xl2tpd.pid
- /usr/sbin/ipsec start
- exec /usr/sbin/xl2tpd -D -c /etc/xl2tpd/xl2tpd.conf
|