#!/bin/bash

SCRIPT_VER="1.1"

APP="L2TP-IPsec VPN (Swan)"
APP_CATEGORY="System Services"
APP_SCOPE="system"
APP_ENABLED="no"
STORED_PASSWORD_SERVICE="l2tp_ipsec"
SUPPORTED_ON="CentOS7,CentOS8,CentOSStream8,Ubuntu16.04,Ubuntu18.04,Ubuntu20.04"
LIBRARY="functions4.sh"

IPSEC_PSK="12345"

if [ "${SUPPORT-}" = '' ]; then
    SUPPORT="https://installers.rapidseedbox.com/scripts/whmcs_client_installers/support"
fi

LOGFILE="/var/log/whmcs_client_installers/${0}.log"
[ ! -d "/var/log/whmcs_client_installers" ] && mkdir -p "/var/log/whmcs_client_installers"

wget -4 -nc -q --no-check-certificate --timeout=20 --tries=5 ${SUPPORT}/${LIBRARY} >> "${LOGFILE}" 2>&1
if [ ! -f "./${LIBRARY}" ] ; then
    echo "55"
    echo "Error downloading \"${SUPPORT}/${LIBRARY}\"" >> "${LOGFILE}"
    exit 55
fi

# shellcheck source=support/functions4.sh
. "./${LIBRARY}"
SCRIPTENTRY


while : ; do

    main_rc=1

    CHECK_APP ; _rc=$?
    if [ ${_rc} -ne 0 ] ; then
        main_rc=${_rc}
        break
    fi

    case "${LSB_VENDOR}" in
      "CentOS")
          ${PKG_INSTALL} "libreswan" || break
          ;;
      "Debian"|"Ubuntu")
          ${PKG_INSTALL} "strongswan" || break
          ;;
    esac
    ${PKG_INSTALL} "xl2tpd" "ppp" "lsof" || break

    cat <<-EOF > "/etc/sysctl.d/065-vpn.conf"
	# VPN
	net.ipv4.ip_forward = 1
	net.ipv4.conf.all.accept_redirects = 0
	net.ipv4.conf.all.send_redirects = 0
	EOF

    # Configure 'iptables'
    case "${LSB_VENDOR}" in
      "CentOS")
          # 1. NAT
          RUN_LOG "iptables -t nat -D POSTROUTING -o ${DEV} ! -p esp -j SNAT --to-source ${IP}"
          RUN_LOG "iptables -t nat -A POSTROUTING -o ${DEV} ! -p esp -j SNAT --to-source ${IP}"
          RUN_LOG "iptables -D FORWARD -s 10.254.254.0/24 -j ACCEPT"
          RUN_LOG "iptables -A FORWARD -s 10.254.254.0/24 -j ACCEPT"
          RUN_LOG "iptables -D FORWARD -d 10.254.254.0/24 -j ACCEPT"
          RUN_LOG "iptables -A FORWARD -d 10.254.254.0/24 -j ACCEPT"
          RUN_LOG "iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited" \
              && RUN_LOG "iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited"
          RUN_LOG "iptables -D FORWARD -j LOGGING" \
              && RUN_LOG "iptables -A FORWARD -j LOGGING"
          # 2. ISAKMP (handling of security associations)
          RUN_LOG "iptables -D INPUT -p udp -m udp --dport 500 -m conntrack --ctstate NEW -j ACCEPT"
          RUN_LOG "iptables -A INPUT -p udp -m udp --dport 500 -m conntrack --ctstate NEW -j ACCEPT"
          # 3. NAT-T (handling of IPsec between natted devices)
          RUN_LOG "iptables -D INPUT -p udp -m udp --dport 4500 -m conntrack --ctstate NEW -j ACCEPT"
          RUN_LOG "iptables -A INPUT -p udp -m udp --dport 4500 -m conntrack --ctstate NEW -j ACCEPT"
          # 4. L2TP
          RUN_LOG "iptables -D INPUT -p udp -m udp --dport 1701 -m conntrack --ctstate NEW -j ACCEPT"
          RUN_LOG "iptables -A INPUT -p udp -m udp --dport 1701 -m conntrack --ctstate NEW -j ACCEPT"
          # 5. ESP payload (the encrypted data packets)
          RUN_LOG "iptables -D INPUT -p esp -j ACCEPT"
          RUN_LOG "iptables -A INPUT -p esp -j ACCEPT"
#          # 6. packets on PPP interface - always accept
#          RUN_LOG "iptables -D INPUT -i ppp+ -j ACCEPT"
#          RUN_LOG "iptables -A INPUT -i ppp+ -j ACCEPT"
          # 7. Fallback rule(s)
          RUN_LOG "iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited" \
              && RUN_LOG "iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited"
          RUN_LOG "iptables -D INPUT -j LOGGING" \
              && RUN_LOG "iptables -A INPUT -j LOGGING"
          RUN_LOG "service iptables save"
          ;;
      "Debian"|"Ubuntu")
          #
          # NB!!! Firewal is 'open' on Debian & Ubuntu by default !!!
          #
          # 1. NAT
          RUN_LOG "iptables -t nat -D POSTROUTING -o ${DEV} ! -p esp -j SNAT --to-source ${IP}"
          RUN_LOG "iptables -t nat -A POSTROUTING -o ${DEV} ! -p esp -j SNAT --to-source ${IP}"
          cat <<-EOF > "/etc/rsb.init.d/065.vpn.sh"
		#!/bin/bash

		IP=\$( ip route get 8.8.8.8 | awk '/8.8.8.8/ {print \$NF}' )
		DEV=\$( ip route get 8.8.8.8 | awk '/8.8.8.8/ {print \$3}' )

		# 1. NAT
		iptables -t nat -D POSTROUTING -o \${DEV} ! -p esp -j SNAT --to-source \${IP}
		iptables -t nat -A POSTROUTING -o \${DEV} ! -p esp -j SNAT --to-source \${IP}
		EOF
          ;;
    esac


    case "${LSB_VENDOR}" in
      "CentOS")
          cat <<-EOF > "/etc/ipsec.conf"
	# ipsec.conf - libreSwan IPsec configuration file
	# basic configuration
 
	config setup
	      # strictcrlpolicy=yes
	      # uniqueids = no
	      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,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10 

	# Add connections here.
	conn L2TP-PSK-NAT
	      rightsubnet=vhost:%priv
	      also=L2TP-PSK-noNAT
 
	conn L2TP-PSK-noNAT
	      authby=secret # Auth with PSK ( preshared key )
	      pfs=no
	      auto=add
	      keyingtries=3
	      rekey=no
	      ikelifetime=8h
	      type=transport           # type of l2tp connection ( tunnel / transport )
	      left=${IP}       # left - is internet IP of l2tp server
	      leftprotoport=17/1701
	      right=%any               # right - is IP of client ( if client NATed ,
	                               #         that IP of client is IP in NAT
	      rightprotoport=17/1701
	EOF
          ;;

      "Debian"|"Ubuntu")
          cat <<-EOF > "/etc/ipsec.conf"
	# ipsec.conf - strongSwan IPsec configuration file
	# basic configuration
 
	config setup
	      # strictcrlpolicy=yes
	      # uniqueids = no
 
	# Add connections here.
	conn L2TP-PSK-NAT
	      also=L2TP-PSK-noNAT
 
	conn L2TP-PSK-noNAT
	      authby=secret # Auth with PSK ( preshared key )
	      auto=add
	      keyingtries=3
	      rekey=no
	      ikelifetime=8h
	      type=transport           # type of l2tp connection ( tunnel / transport )
	      left=${IP}       # left - is internet IP of l2tp server
	      leftprotoport=17/1701
	      right=%any               # right - is IP of client ( if client NATed ,
	                               #         that IP of client is IP in NAT
	      rightprotoport=17/1701
		EOF
          cat <<-EOF > "/etc/ipsec.secrets"
		# This file holds shared secrets or RSA private keys for authentication.

		# RSA private key for this host, authenticating it to any other host
		# which knows the public part.

		include /etc/ipsec.d/*.secrets

		# this file is managed with debconf and will contain the automatically created private key
		include /var/lib/strongswan/ipsec.secrets.inc
		EOF
          ;;
    esac

    cat <<-EOF > "/etc/ipsec.d/vpn.secrets"
	# This file holds shared secrets or RSA private keys for authentication.
	# RSA private key for this host, authenticating it to any other host
	# which knows the public part.
	${IP} %any : PSK "${IPSEC_PSK}"       # left - is internet IP of l2tp server
	EOF
    CHMOD_FILE 0600 "/etc/ipsec.d/vpn.secrets"
    CHMOD_FILE 0600 "/etc/ipsec.secrets"

    SVC_ENABLE  "ipsec"
    SVC_RESTART "ipsec"

    # XL2TPD
    if [ "${SVC_SYSTEM}" = "systemd" ] ; then
        SVC_DISABLE  "xl2tpd"
        SVC_STOP "xl2tpd"
        cat <<-EOF > "/etc/systemd/system/xl2tpd.service"
	[Unit]
	Description=Level 2 Tunnel Protocol Daemon (L2TP)
	Wants=network-online.target
	After=network-online.target
	After=ipsec.service
	# Some ISPs in Russia use l2tp without IPsec, so don't insist anymore
	#Wants=ipsec.service

	[Service]
	Type=simple
	PIDFile=/var/run/xl2tpd/xl2tpd.pid
	ExecStart=/usr/sbin/xl2tpd -D
	ExecStartPre=/bin/mkdir -p /var/run/xl2tpd
	Restart=always

	[Install]
	WantedBy=multi-user.target
	EOF
    fi

    cat <<-EOF > "/etc/xl2tpd/xl2tpd.conf"
	[global]
	port = 1701
	auth file = /etc/xl2tpd/l2tp-secrets
	;debug avp = yes
	;debug network = yes
	;debug packet = yes
	;debug state = yes
	;debug tunnel = yes

	[lns default]
	ip range = 10.254.254.2-10.254.254.250
	local ip = 10.254.254.1
	refuse pap = yes
	require authentication = yes
	;ppp debug = yes
	ppp debug = no
	pppoptfile = /etc/ppp/options.xl2tpd
	length bit = yes
	exclusive = no
	assign ip = yes
	name = xl2tpd
	EOF

    cat <<-EOF > "/etc/xl2tpd/l2tp-secrets"
	# Secrets for authenticating l2tp tunnels
	# us    them    secret
	# *             marko blah2
	# zeus          marko   blah
	# *     *       interop
	*   *   *       # let all , because we use auth with chap
	EOF

    SVC_ENABLE  "xl2tpd"
    SVC_RESTART "xl2tpd"

    # PPP
    cat <<-EOF > "/etc/ppp/options.xl2tpd"
	refuse-mschap-v2
	refuse-mschap
	ms-dns 8.8.8.8
	ms-dns 8.8.4.4
	asyncmap 0
	auth
	crtscts
	idle 1800
	mtu 1280
	mru 1280
	lock
	hide-password
	local
	#debug
	name l2tpd
	proxyarp
	lcp-echo-interval 30
	lcp-echo-failure 4
	EOF
    cat <<-EOF > "/etc/ppp/chap-secrets"
	# Secrets for authentication using CHAP
	# client        server  secret                  IP addresses
	${USERNAME}            l2tpd   ${USERPASSWORD}                    *
	EOF
    CHMOD_FILE 0600 "/etc/ppp/chap-secrets"


    main_rc=0
    break

done

SCRIPTEXIT
