diff --git a/vpnsetup_amzn.sh b/vpnsetup_amzn.sh index f9a41f9..2876e21 100755 --- a/vpnsetup_amzn.sh +++ b/vpnsetup_amzn.sh @@ -46,139 +46,161 @@ check_ip() { printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX" } -vpnsetup() { +check_root() { + if [ "$(id -u)" != 0 ]; then + exiterr "Script must be run as root. Try 'sudo sh $0'" + fi +} -os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-') -if ! grep -qs "Amazon Linux release 2" /etc/system-release; then - exiterr "This script only supports Amazon Linux 2." -fi +check_os() { + os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-') + if ! grep -qs "Amazon Linux release 2" /etc/system-release; then + exiterr "This script only supports Amazon Linux 2." + fi +} -if [ "$(id -u)" != 0 ]; then - exiterr "Script must be run as root. Try 'sudo sh $0'" -fi +check_iface() { + def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') + [ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') + def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) + if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then + case $def_iface in + wl*) + exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" + ;; + esac + NET_IFACE="$def_iface" + else + eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) + if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then + exiterr "Could not detect the default network interface." + fi + NET_IFACE=eth0 + fi +} -def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') -[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') -def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) -if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then - case $def_iface in - wl*) - exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" +check_creds() { + [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" + [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" + [ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" + + if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then + bigecho "VPN credentials not set by user. Generating random PSK and password..." + VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 20) + VPN_USER=vpnuser + VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 16) + fi + + if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then + exiterr "All VPN credentials must be specified. Edit the script and re-enter them." + fi + + if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then + exiterr "VPN credentials must not contain non-ASCII characters." + fi + + case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in + *[\\\"\']*) + exiterr "VPN credentials must not contain these special characters: \\ \" '" ;; esac - NET_IFACE="$def_iface" -else - eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) - if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then - exiterr "Could not detect the default network interface." +} + +check_dns() { + if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ + || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then + exiterr "The DNS server specified is invalid." fi - NET_IFACE=eth0 -fi +} -[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" -[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" -[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" +# shellcheck disable=SC2154,SC2039,SC3047 +start_setup() { + bigecho "VPN setup in progress... Please be patient." + trap 'dlo=$dl;dl=$LINENO' DEBUG 2>/dev/null + trap 'finish $? $((dlo+1))' EXIT + mkdir -p /opt/src + cd /opt/src || exit 1 +} -if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then - bigecho "VPN credentials not set by user. Generating random PSK and password..." - VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 20) - VPN_USER=vpnuser - VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 16) -fi +install_setup_pkgs() { + bigecho "Installing packages required for setup..." + ( + set -x + yum -y -q install wget bind-utils openssl tar \ + iptables iproute gawk grep sed net-tools >/dev/null + ) || exiterr2 +} -if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then - exiterr "All VPN credentials must be specified. Edit the script and re-enter them." -fi +detect_ip() { + bigecho "Trying to auto discover IP of this server..." + public_ip=${VPN_PUBLIC_IP:-''} + check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) + check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) + check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." +} -if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then - exiterr "VPN credentials must not contain non-ASCII characters." -fi +add_epel_repo() { + bigecho "Adding the EPEL repository..." + ( + set -x + amazon-linux-extras install epel -y >/dev/null + ) || exiterr2 +} -case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in - *[\\\"\']*) - exiterr "VPN credentials must not contain these special characters: \\ \" '" - ;; -esac +install_vpn_pkgs_1() { + bigecho "Installing packages required for the VPN..." + ( + set -x + yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \ + libcap-ng-devel libselinux-devel curl-devel nss-tools \ + flex bison gcc make util-linux ppp \ + systemd-devel iptables-services \ + libevent-devel fipscheck-devel >/dev/null + ) || exiterr2 +} -if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ - || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then - exiterr "The DNS server specified is invalid." -fi +install_vpn_pkgs_2() { + ( + set -x + yum --enablerepo=epel -y -q install xl2tpd >/dev/null 2>&1 + ) || exiterr2 +} -bigecho "VPN setup in progress... Please be patient." +install_fail2ban() { + bigecho "Installing Fail2Ban to protect SSH..." + ( + set -x + yum --enablerepo=epel -y -q install fail2ban >/dev/null + ) || exiterr2 +} -mkdir -p /opt/src -cd /opt/src || exit 1 +get_ikev2_script() { + bigecho "Downloading IKEv2 script..." + ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" + ( + set -x + wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" + ) || /bin/rm -f ikev2.sh + [ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null +} -bigecho "Installing packages required for setup..." +get_libreswan() { + bigecho "Downloading Libreswan..." + SWAN_VER=4.4 + swan_file="libreswan-$SWAN_VER.tar.gz" + swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz" + swan_url2="https://download.libreswan.org/$swan_file" + ( + set -x + wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" + ) || exit 1 + /bin/rm -rf "/opt/src/libreswan-$SWAN_VER" + tar xzf "$swan_file" && /bin/rm -f "$swan_file" +} -( - set -x - yum -y -q install wget bind-utils openssl tar \ - iptables iproute gawk grep sed net-tools >/dev/null -) || exiterr2 - -bigecho "Trying to auto discover IP of this server..." - -public_ip=${VPN_PUBLIC_IP:-''} -check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) -check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) -check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." - -bigecho "Adding the EPEL repository..." - -( - set -x - amazon-linux-extras install epel -y >/dev/null -) || exiterr2 - -bigecho "Installing packages required for the VPN..." - -( - set -x - yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \ - libcap-ng-devel libselinux-devel curl-devel nss-tools \ - flex bison gcc make util-linux ppp \ - systemd-devel iptables-services \ - libevent-devel fipscheck-devel >/dev/null -) || exiterr2 -( - set -x - yum --enablerepo=epel -y -q install xl2tpd >/dev/null 2>&1 -) || exiterr2 - -bigecho "Installing Fail2Ban to protect SSH..." - -( - set -x - yum --enablerepo=epel -y -q install fail2ban >/dev/null -) || exiterr2 - -bigecho "Downloading IKEv2 script..." - -ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" -( - set -x - wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" -) || /bin/rm -f ikev2.sh -[ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null - -bigecho "Downloading Libreswan..." - -SWAN_VER=4.4 -swan_file="libreswan-$SWAN_VER.tar.gz" -swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz" -swan_url2="https://download.libreswan.org/$swan_file" -( - set -x - wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" -) || exit 1 -/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" -tar xzf "$swan_file" && /bin/rm -f "$swan_file" - -bigecho "Compiling and installing Libreswan, please wait..." - -cd "libreswan-$SWAN_VER" || exit 1 +install_libreswan() { + bigecho "Compiling and installing Libreswan, please wait..." + cd "libreswan-$SWAN_VER" || exit 1 cat > Makefile.inc.local <<'EOF' WERROR_CFLAGS=-w -s USE_DNSSEC=false @@ -186,36 +208,38 @@ USE_DH2=true USE_NSS_KDF=false FINALNSSDIR=/etc/ipsec.d EOF -if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then - echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local -fi -NPROCS=$(grep -c ^processor /proc/cpuinfo) -[ -z "$NPROCS" ] && NPROCS=1 -( - set -x - make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null -) + if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then + echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local + fi + NPROCS=$(grep -c ^processor /proc/cpuinfo) + [ -z "$NPROCS" ] && NPROCS=1 + ( + set -x + make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null + ) -cd /opt/src || exit 1 -/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" -if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then - exiterr "Libreswan $SWAN_VER failed to build." -fi + cd /opt/src || exit 1 + /bin/rm -rf "/opt/src/libreswan-$SWAN_VER" + if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then + exiterr "Libreswan $SWAN_VER failed to build." + fi +} -bigecho "Creating VPN configuration..." +create_vpn_config() { + bigecho "Creating VPN configuration..." -L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} -L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} -L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} -XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} -XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} -DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} -DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} -DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" -[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" + L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} + L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} + L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} + XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} + XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} + DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} + DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} + DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" + [ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" -# Create IPsec config -conf_bk "/etc/ipsec.conf" + # Create IPsec config + conf_bk "/etc/ipsec.conf" cat > /etc/ipsec.conf < /etc/ipsec.secrets < /etc/xl2tpd/xl2tpd.conf < /etc/ppp/options.xl2tpd <> /etc/ppp/options.xl2tpd < /etc/ppp/chap-secrets < /etc/ipsec.d/passwd < "$F2B_FILE" <<'EOF' +[ssh-iptables] +enabled = true +filter = sshd +logpath = /var/log/secure +action = iptables[name=SSH, port=ssh, protocol=tcp] +EOF + fi +} -if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then - conf_bk "/etc/sysctl.conf" +update_sysctl() { + bigecho "Updating sysctl settings..." + if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then + conf_bk "/etc/sysctl.conf" cat >> /etc/sysctl.conf < "$F2B_FILE" <<'EOF' -[ssh-iptables] -enabled = true -filter = sshd -logpath = /var/log/secure -action = iptables[name=SSH, port=ssh, protocol=tcp] -EOF -fi - -bigecho "Updating IPTables rules..." - -IPT_FILE=/etc/sysconfig/iptables -ipt_flag=0 -if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then - ipt_flag=1 -fi - -ipi='iptables -I INPUT' -ipf='iptables -I FORWARD' -ipp='iptables -t nat -I POSTROUTING' -res='RELATED,ESTABLISHED' -if [ "$ipt_flag" = "1" ]; then - service fail2ban stop >/dev/null 2>&1 - iptables-save > "$IPT_FILE.old-$SYS_DT" - $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP - $ipi 2 -m conntrack --ctstate INVALID -j DROP - $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT - $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT - $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT - $ipi 6 -p udp --dport 1701 -j DROP - $ipf 1 -m conntrack --ctstate INVALID -j DROP - $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT - $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT - $ipf 4 -i ppp+ -o ppp+ -j ACCEPT - $ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT - $ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT - $ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT - iptables -A FORWARD -j DROP - $ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE - $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE - echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" - iptables-save >> "$IPT_FILE" -fi - -bigecho "Enabling services on boot..." - -systemctl --now mask firewalld 2>/dev/null -systemctl enable iptables fail2ban 2>/dev/null - -if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then - if [ -f /etc/rc.local ]; then - conf_bk "/etc/rc.local" - else - echo '#!/bin/sh' > /etc/rc.local fi +} + +update_iptables() { + bigecho "Updating IPTables rules..." + IPT_FILE=/etc/sysconfig/iptables + ipt_flag=0 + if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then + ipt_flag=1 + fi + + ipi='iptables -I INPUT' + ipf='iptables -I FORWARD' + ipp='iptables -t nat -I POSTROUTING' + res='RELATED,ESTABLISHED' + if [ "$ipt_flag" = "1" ]; then + service fail2ban stop >/dev/null 2>&1 + iptables-save > "$IPT_FILE.old-$SYS_DT" + $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP + $ipi 2 -m conntrack --ctstate INVALID -j DROP + $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT + $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT + $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT + $ipi 6 -p udp --dport 1701 -j DROP + $ipf 1 -m conntrack --ctstate INVALID -j DROP + $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT + $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT + $ipf 4 -i ppp+ -o ppp+ -j ACCEPT + $ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT + $ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT + $ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT + iptables -A FORWARD -j DROP + $ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE + $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE + echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" + iptables-save >> "$IPT_FILE" + fi +} + +enable_on_boot() { + bigecho "Enabling services on boot..." + systemctl --now mask firewalld 2>/dev/null + systemctl enable iptables fail2ban 2>/dev/null + + if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then + if [ -f /etc/rc.local ]; then + conf_bk "/etc/rc.local" + else + echo '#!/bin/sh' > /etc/rc.local + fi cat >> /etc/rc.local <<'EOF' # Added by hwdsl2 VPN script @@ -416,45 +445,35 @@ service ipsec restart service xl2tpd restart echo 1 > /proc/sys/net/ipv4/ip_forward)& EOF -fi + fi +} -bigecho "Starting services..." +start_services() { + bigecho "Starting services..." + sysctl -e -q -p -restorecon /etc/ipsec.d/*db 2>/dev/null -restorecon /usr/local/sbin -Rv 2>/dev/null -restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null + chmod +x /etc/rc.local + chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* -sysctl -e -q -p + restorecon /etc/ipsec.d/*db 2>/dev/null + restorecon /usr/local/sbin -Rv 2>/dev/null + restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null -chmod +x /etc/rc.local -chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* + iptables-restore < "$IPT_FILE" -iptables-restore < "$IPT_FILE" + # Fix xl2tpd if l2tp_ppp is unavailable + if ! modprobe -q l2tp_ppp; then + sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service + systemctl daemon-reload + fi -# Fix xl2tpd if l2tp_ppp is unavailable -if ! modprobe -q l2tp_ppp; then - sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service - systemctl daemon-reload -fi - -mkdir -p /run/pluto -service fail2ban restart 2>/dev/null -service ipsec restart 2>/dev/null -service xl2tpd restart 2>/dev/null - -swan_ver_url="https://dl.ls20.com/v1/amzn/2/swanver?arch=$os_arch&ver=$SWAN_VER" -swan_ver_latest=$(wget -t 3 -T 15 -qO- "$swan_ver_url") -if printf '%s' "$swan_ver_latest" | grep -Eq '^([3-9]|[1-9][0-9]{1,2})(\.([0-9]|[1-9][0-9]{1,2})){1,2}$' \ - && [ -n "$SWAN_VER" ] && [ "$SWAN_VER" != "$swan_ver_latest" ] \ - && printf '%s\n%s' "$SWAN_VER" "$swan_ver_latest" | sort -C -V; then -cat </dev/null + service ipsec restart 2>/dev/null + service xl2tpd restart 2>/dev/null +} +show_vpn_info() { cat </dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') + [ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') + def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) + if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then + case $def_iface in + wl*) + exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" + ;; + esac + NET_IFACE="$def_iface" + else + eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) + if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then + exiterr "Could not detect the default network interface." + fi + NET_IFACE=eth0 + fi +} -def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') -[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') -def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) -if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then - case $def_iface in - wl*) - exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" +check_creds() { + [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" + [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" + [ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" + + if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then + bigecho "VPN credentials not set by user. Generating random PSK and password..." + VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 20) + VPN_USER=vpnuser + VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 16) + fi + + if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then + exiterr "All VPN credentials must be specified. Edit the script and re-enter them." + fi + + if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then + exiterr "VPN credentials must not contain non-ASCII characters." + fi + + case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in + *[\\\"\']*) + exiterr "VPN credentials must not contain these special characters: \\ \" '" ;; esac - NET_IFACE="$def_iface" -else - eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) - if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then - exiterr "Could not detect the default network interface." +} + +check_dns() { + if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ + || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then + exiterr "The DNS server specified is invalid." fi - NET_IFACE=eth0 -fi +} -[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" -[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" -[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" +# shellcheck disable=SC2154,SC2039,SC3047 +start_setup() { + bigecho "VPN setup in progress... Please be patient." + trap 'dlo=$dl;dl=$LINENO' DEBUG 2>/dev/null + trap 'finish $? $((dlo+1))' EXIT + mkdir -p /opt/src + cd /opt/src || exit 1 +} -if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then - bigecho "VPN credentials not set by user. Generating random PSK and password..." - VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 20) - VPN_USER=vpnuser - VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 16) -fi - -if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then - exiterr "All VPN credentials must be specified. Edit the script and re-enter them." -fi - -if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then - exiterr "VPN credentials must not contain non-ASCII characters." -fi - -case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in - *[\\\"\']*) - exiterr "VPN credentials must not contain these special characters: \\ \" '" - ;; -esac - -if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ - || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then - exiterr "The DNS server specified is invalid." -fi - -bigecho "VPN setup in progress... Please be patient." - -mkdir -p /opt/src -cd /opt/src || exit 1 - -bigecho "Installing packages required for setup..." - -( - set -x - yum -y -q install wget bind-utils openssl tar \ - iptables iproute gawk grep sed net-tools >/dev/null -) || exiterr2 - -bigecho "Trying to auto discover IP of this server..." - -public_ip=${VPN_PUBLIC_IP:-''} -check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) -check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) -check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." - -bigecho "Adding the EPEL repository..." - -epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E '%{rhel}').noarch.rpm" -( - set -x - yum -y -q install epel-release >/dev/null 2>&1 || yum -y -q install "$epel_url" >/dev/null -) || exiterr2 - -bigecho "Installing packages required for the VPN..." - -erp="--enablerepo" -rp1="$erp=epel" -rp2="$erp=*server-*optional*" -rp3="$erp=*releases-optional*" -rp4="$erp=[Pp]ower[Tt]ools" -[ "$os_type" = "rhel" ] && rp4="$erp=codeready-builder-for-rhel-8-*" - -( - set -x - yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \ - libcap-ng-devel libselinux-devel curl-devel nss-tools \ - flex bison gcc make util-linux ppp >/dev/null -) || exiterr2 -( - set -x - yum "$rp1" -y -q install xl2tpd >/dev/null 2>&1 -) || exiterr2 - -use_nft=0 -p1=systemd-devel -p2=libevent-devel -p3=fipscheck-devel -p4=iptables-services -if [ "$os_ver" = "7" ]; then +install_setup_pkgs() { + bigecho "Installing packages required for setup..." ( set -x - yum "$rp2" "$rp3" -y -q install $p1 $p2 $p3 $p4 >/dev/null + yum -y -q install wget bind-utils openssl tar \ + iptables iproute gawk grep sed net-tools >/dev/null ) || exiterr2 -else +} + +detect_ip() { + bigecho "Trying to auto discover IP of this server..." + public_ip=${VPN_PUBLIC_IP:-''} + check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) + check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) + check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." +} + +add_epel_repo() { + bigecho "Adding the EPEL repository..." + epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E '%{rhel}').noarch.rpm" ( set -x - yum "$rp4" -y -q install $p1 $p2 $p3 >/dev/null + yum -y -q install epel-release >/dev/null 2>&1 || yum -y -q install "$epel_url" >/dev/null ) || exiterr2 - if systemctl is-active --quiet firewalld \ - || systemctl is-active --quiet nftables \ - || grep -qs "hwdsl2 VPN script" /etc/sysconfig/nftables.conf; then - use_nft=1 - p4=nftables +} + +install_vpn_pkgs_1() { + bigecho "Installing packages required for the VPN..." + erp="--enablerepo" + rp1="$erp=epel" + rp2="$erp=*server-*optional*" + rp3="$erp=*releases-optional*" + rp4="$erp=[Pp]ower[Tt]ools" + [ "$os_type" = "rhel" ] && rp4="$erp=codeready-builder-for-rhel-8-*" + + ( + set -x + yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \ + libcap-ng-devel libselinux-devel curl-devel nss-tools \ + flex bison gcc make util-linux ppp >/dev/null + ) || exiterr2 +} + +install_vpn_pkgs_2() { + ( + set -x + yum "$rp1" -y -q install xl2tpd >/dev/null 2>&1 + ) || exiterr2 +} + +install_vpn_pkgs_3() { + use_nft=0 + p1=systemd-devel + p2=libevent-devel + p3=fipscheck-devel + p4=iptables-services + if [ "$os_ver" = "7" ]; then + ( + set -x + yum "$rp2" "$rp3" -y -q install $p1 $p2 $p3 $p4 >/dev/null + ) || exiterr2 + else + ( + set -x + yum "$rp4" -y -q install $p1 $p2 $p3 >/dev/null + ) || exiterr2 + if systemctl is-active --quiet firewalld \ + || systemctl is-active --quiet nftables \ + || grep -qs "hwdsl2 VPN script" /etc/sysconfig/nftables.conf; then + use_nft=1 + p4=nftables + fi + ( + set -x + yum -y -q install $p4 >/dev/null + ) || exiterr2 fi +} + +install_fail2ban() { + bigecho "Installing Fail2Ban to protect SSH..." ( set -x - yum -y -q install $p4 >/dev/null + yum "$rp1" -y -q install fail2ban >/dev/null ) || exiterr2 -fi +} -bigecho "Installing Fail2Ban to protect SSH..." +get_ikev2_script() { + bigecho "Downloading IKEv2 script..." + ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" + ( + set -x + wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" + ) || /bin/rm -f ikev2.sh + [ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null +} -( - set -x - yum "$rp1" -y -q install fail2ban >/dev/null -) || exiterr2 +get_libreswan() { + bigecho "Downloading Libreswan..." + SWAN_VER=4.4 + swan_file="libreswan-$SWAN_VER.tar.gz" + swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz" + swan_url2="https://download.libreswan.org/$swan_file" + ( + set -x + wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" + ) || exit 1 + /bin/rm -rf "/opt/src/libreswan-$SWAN_VER" + tar xzf "$swan_file" && /bin/rm -f "$swan_file" +} -bigecho "Downloading IKEv2 script..." - -ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" -( - set -x - wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" -) || /bin/rm -f ikev2.sh -[ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null - -bigecho "Downloading Libreswan..." - -SWAN_VER=4.4 -swan_file="libreswan-$SWAN_VER.tar.gz" -swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz" -swan_url2="https://download.libreswan.org/$swan_file" -( - set -x - wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" -) || exit 1 -/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" -tar xzf "$swan_file" && /bin/rm -f "$swan_file" - -bigecho "Compiling and installing Libreswan, please wait..." - -cd "libreswan-$SWAN_VER" || exit 1 +install_libreswan() { + bigecho "Compiling and installing Libreswan, please wait..." + cd "libreswan-$SWAN_VER" || exit 1 cat > Makefile.inc.local <<'EOF' WERROR_CFLAGS=-w -s USE_DNSSEC=false @@ -236,36 +262,38 @@ USE_DH2=true USE_NSS_KDF=false FINALNSSDIR=/etc/ipsec.d EOF -if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then - echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local -fi -NPROCS=$(grep -c ^processor /proc/cpuinfo) -[ -z "$NPROCS" ] && NPROCS=1 -( - set -x - make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null -) + if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then + echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local + fi + NPROCS=$(grep -c ^processor /proc/cpuinfo) + [ -z "$NPROCS" ] && NPROCS=1 + ( + set -x + make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null + ) -cd /opt/src || exit 1 -/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" -if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then - exiterr "Libreswan $SWAN_VER failed to build." -fi + cd /opt/src || exit 1 + /bin/rm -rf "/opt/src/libreswan-$SWAN_VER" + if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then + exiterr "Libreswan $SWAN_VER failed to build." + fi +} -bigecho "Creating VPN configuration..." +create_vpn_config() { + bigecho "Creating VPN configuration..." -L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} -L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} -L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} -XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} -XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} -DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} -DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} -DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" -[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" + L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} + L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} + L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} + XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} + XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} + DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} + DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} + DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" + [ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" -# Create IPsec config -conf_bk "/etc/ipsec.conf" + # Create IPsec config + conf_bk "/etc/ipsec.conf" cat > /etc/ipsec.conf < /etc/ipsec.secrets < /etc/xl2tpd/xl2tpd.conf < /etc/ppp/options.xl2tpd <> /etc/ppp/options.xl2tpd < /etc/ppp/chap-secrets < /etc/ipsec.d/passwd < "$F2B_FILE" <<'EOF' +[ssh-iptables] +enabled = true +filter = sshd +logpath = /var/log/secure +EOF -if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then - conf_bk "/etc/sysctl.conf" + if [ "$use_nft" = "1" ]; then +cat >> "$F2B_FILE" <<'EOF' +port = ssh +banaction = nftables-multiport[blocktype=drop] +EOF + else +cat >> "$F2B_FILE" <<'EOF' +action = iptables[name=SSH, port=ssh, protocol=tcp] +EOF + fi + fi +} + +update_sysctl() { + bigecho "Updating sysctl settings..." + if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then + conf_bk "/etc/sysctl.conf" cat >> /etc/sysctl.conf < "$F2B_FILE" <<'EOF' -[ssh-iptables] -enabled = true -filter = sshd -logpath = /var/log/secure -EOF - - if [ "$use_nft" = "1" ]; then -cat >> "$F2B_FILE" <<'EOF' -port = ssh -banaction = nftables-multiport[blocktype=drop] -EOF - else -cat >> "$F2B_FILE" <<'EOF' -action = iptables[name=SSH, port=ssh, protocol=tcp] EOF fi -fi +} -bigecho "Updating IPTables rules..." - -IPT_FILE=/etc/sysconfig/iptables -[ "$use_nft" = "1" ] && IPT_FILE=/etc/sysconfig/nftables.conf -ipt_flag=0 -if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then - ipt_flag=1 -fi - -ipi='iptables -I INPUT' -ipf='iptables -I FORWARD' -ipp='iptables -t nat -I POSTROUTING' -res='RELATED,ESTABLISHED' -nff='nft insert rule inet firewalld' -nfn='nft insert rule inet nftables_svc' -if [ "$ipt_flag" = "1" ]; then - service fail2ban stop >/dev/null 2>&1 - if [ "$use_nft" = "1" ]; then - nft list ruleset > "$IPT_FILE.old-$SYS_DT" - chmod 600 "$IPT_FILE.old-$SYS_DT" - else - iptables-save > "$IPT_FILE.old-$SYS_DT" +update_iptables() { + bigecho "Updating IPTables rules..." + IPT_FILE=/etc/sysconfig/iptables + [ "$use_nft" = "1" ] && IPT_FILE=/etc/sysconfig/nftables.conf + ipt_flag=0 + if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then + ipt_flag=1 fi - $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP - $ipi 2 -m conntrack --ctstate INVALID -j DROP - $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT - $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT - $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT - $ipi 6 -p udp --dport 1701 -j DROP - $ipf 1 -m conntrack --ctstate INVALID -j DROP - $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT - $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT - $ipf 4 -i ppp+ -o ppp+ -j ACCEPT - $ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT - $ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT - $ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT - iptables -A FORWARD -j DROP - $ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE - $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE - echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" - if [ "$use_nft" = "1" ]; then - for vport in 500 4500 1701; do - $nff filter_INPUT udp dport "$vport" accept 2>/dev/null - $nfn allow udp dport "$vport" accept 2>/dev/null - done - for vnet in "$L2TP_NET" "$XAUTH_NET"; do - for vdir in saddr daddr; do - $nff filter_FORWARD ip "$vdir" "$vnet" accept 2>/dev/null - $nfn FORWARD ip "$vdir" "$vnet" accept 2>/dev/null + + ipi='iptables -I INPUT' + ipf='iptables -I FORWARD' + ipp='iptables -t nat -I POSTROUTING' + res='RELATED,ESTABLISHED' + nff='nft insert rule inet firewalld' + nfn='nft insert rule inet nftables_svc' + if [ "$ipt_flag" = "1" ]; then + service fail2ban stop >/dev/null 2>&1 + if [ "$use_nft" = "1" ]; then + nft list ruleset > "$IPT_FILE.old-$SYS_DT" + chmod 600 "$IPT_FILE.old-$SYS_DT" + else + iptables-save > "$IPT_FILE.old-$SYS_DT" + fi + $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP + $ipi 2 -m conntrack --ctstate INVALID -j DROP + $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT + $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT + $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT + $ipi 6 -p udp --dport 1701 -j DROP + $ipf 1 -m conntrack --ctstate INVALID -j DROP + $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT + $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT + $ipf 4 -i ppp+ -o ppp+ -j ACCEPT + $ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT + $ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT + $ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT + iptables -A FORWARD -j DROP + $ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE + $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE + echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" + if [ "$use_nft" = "1" ]; then + for vport in 500 4500 1701; do + $nff filter_INPUT udp dport "$vport" accept 2>/dev/null + $nfn allow udp dport "$vport" accept 2>/dev/null done - done - echo "flush ruleset" >> "$IPT_FILE" - nft list ruleset >> "$IPT_FILE" - else - iptables-save >> "$IPT_FILE" + for vnet in "$L2TP_NET" "$XAUTH_NET"; do + for vdir in saddr daddr; do + $nff filter_FORWARD ip "$vdir" "$vnet" accept 2>/dev/null + $nfn FORWARD ip "$vdir" "$vnet" accept 2>/dev/null + done + done + echo "flush ruleset" >> "$IPT_FILE" + nft list ruleset >> "$IPT_FILE" + else + iptables-save >> "$IPT_FILE" + fi fi -fi +} -bigecho "Enabling services on boot..." - -systemctl --now mask firewalld 2>/dev/null -if [ "$use_nft" = "1" ]; then - systemctl enable nftables fail2ban 2>/dev/null -else - systemctl enable iptables fail2ban 2>/dev/null -fi - -if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then - if [ -f /etc/rc.local ]; then - conf_bk "/etc/rc.local" +enable_on_boot() { + bigecho "Enabling services on boot..." + systemctl --now mask firewalld 2>/dev/null + if [ "$use_nft" = "1" ]; then + systemctl enable nftables fail2ban 2>/dev/null else - echo '#!/bin/sh' > /etc/rc.local + systemctl enable iptables fail2ban 2>/dev/null fi + + if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then + if [ -f /etc/rc.local ]; then + conf_bk "/etc/rc.local" + else + echo '#!/bin/sh' > /etc/rc.local + fi cat >> /etc/rc.local <<'EOF' # Added by hwdsl2 VPN script @@ -503,49 +536,39 @@ service ipsec restart service xl2tpd restart echo 1 > /proc/sys/net/ipv4/ip_forward)& EOF -fi + fi +} -bigecho "Starting services..." +start_services() { + bigecho "Starting services..." + sysctl -e -q -p -restorecon /etc/ipsec.d/*db 2>/dev/null -restorecon /usr/local/sbin -Rv 2>/dev/null -restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null + chmod +x /etc/rc.local + chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* -sysctl -e -q -p + restorecon /etc/ipsec.d/*db 2>/dev/null + restorecon /usr/local/sbin -Rv 2>/dev/null + restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null -chmod +x /etc/rc.local -chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* + if [ "$use_nft" = "1" ]; then + nft -f "$IPT_FILE" + else + iptables-restore < "$IPT_FILE" + fi -if [ "$use_nft" = "1" ]; then - nft -f "$IPT_FILE" -else - iptables-restore < "$IPT_FILE" -fi + # Fix xl2tpd if l2tp_ppp is unavailable + if ! modprobe -q l2tp_ppp; then + sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service + systemctl daemon-reload + fi -# Fix xl2tpd if l2tp_ppp is unavailable -if ! modprobe -q l2tp_ppp; then - sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service - systemctl daemon-reload -fi - -mkdir -p /run/pluto -service fail2ban restart 2>/dev/null -service ipsec restart 2>/dev/null -service xl2tpd restart 2>/dev/null - -swan_ver_url="https://dl.ls20.com/v1/$os_type/$os_ver/swanver?arch=$os_arch&ver=$SWAN_VER" -swan_ver_latest=$(wget -t 3 -T 15 -qO- "$swan_ver_url") -if printf '%s' "$swan_ver_latest" | grep -Eq '^([3-9]|[1-9][0-9]{1,2})(\.([0-9]|[1-9][0-9]{1,2})){1,2}$' \ - && [ -n "$SWAN_VER" ] && [ "$SWAN_VER" != "$swan_ver_latest" ] \ - && printf '%s\n%s' "$SWAN_VER" "$swan_ver_latest" | sort -C -V; then -cat </dev/null + service ipsec restart 2>/dev/null + service xl2tpd restart 2>/dev/null +} +show_vpn_info() { cat </dev/null) -os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-') -[ -z "$os_type" ] && [ -f /etc/os-release ] && os_type=$(. /etc/os-release && printf '%s' "$ID") -case $os_type in - [Uu]buntu) - os_type=ubuntu - ;; - [Dd]ebian) - os_type=debian - ;; - [Rr]aspbian) - os_type=raspbian - ;; - *) - exiterr "This script only supports Ubuntu and Debian." - ;; -esac - -os_ver=$(sed 's/\..*//' /etc/debian_version | tr -dc 'A-Za-z0-9') -if [ "$os_ver" = "8" ] || [ "$os_ver" = "jessiesid" ]; then - exiterr "Debian 8 or Ubuntu < 16.04 is not supported." -fi -if { [ "$os_ver" = "10" ] || [ "$os_ver" = "11" ]; } && [ ! -e /dev/ppp ]; then - exiterr "/dev/ppp is missing. Debian 11 or 10 users, see: https://git.io/vpndebian10" -fi - -if [ -f /proc/user_beancounters ]; then - exiterr "OpenVZ VPS is not supported." -fi - -if [ "$(id -u)" != 0 ]; then - exiterr "Script must be run as root. Try 'sudo sh $0'" -fi - -def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') -[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') -def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) -if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then - if ! uname -m | grep -qi -e '^arm' -e '^aarch64'; then - case $def_iface in - wl*) - exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" - ;; - esac +check_root() { + if [ "$(id -u)" != 0 ]; then + exiterr "Script must be run as root. Try 'sudo sh $0'" fi - NET_IFACE="$def_iface" -else - eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) - if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then - exiterr "Could not detect the default network interface." +} + +check_vz() { + if [ -f /proc/user_beancounters ]; then + exiterr "OpenVZ VPS is not supported." fi - NET_IFACE=eth0 -fi +} -[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" -[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" -[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" +check_os() { + os_type=$(lsb_release -si 2>/dev/null) + os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-') + [ -z "$os_type" ] && [ -f /etc/os-release ] && os_type=$(. /etc/os-release && printf '%s' "$ID") + case $os_type in + [Uu]buntu) + os_type=ubuntu + ;; + [Dd]ebian) + os_type=debian + ;; + [Rr]aspbian) + os_type=raspbian + ;; + *) + exiterr "This script only supports Ubuntu and Debian." + ;; + esac -if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then - bigecho "VPN credentials not set by user. Generating random PSK and password..." - VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 20) - VPN_USER=vpnuser - VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 16) -fi + os_ver=$(sed 's/\..*//' /etc/debian_version | tr -dc 'A-Za-z0-9') + if [ "$os_ver" = "8" ] || [ "$os_ver" = "jessiesid" ]; then + exiterr "Debian 8 or Ubuntu < 16.04 is not supported." + fi + if { [ "$os_ver" = "10" ] || [ "$os_ver" = "11" ]; } && [ ! -e /dev/ppp ]; then + exiterr "/dev/ppp is missing. Debian 11 or 10 users, see: https://git.io/vpndebian10" + fi +} -if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then - exiterr "All VPN credentials must be specified. Edit the script and re-enter them." -fi +check_iface() { + def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') + [ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') + def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) + if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then + if ! uname -m | grep -qi -e '^arm' -e '^aarch64'; then + case $def_iface in + wl*) + exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" + ;; + esac + fi + NET_IFACE="$def_iface" + else + eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) + if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then + exiterr "Could not detect the default network interface." + fi + NET_IFACE=eth0 + fi +} -if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then - exiterr "VPN credentials must not contain non-ASCII characters." -fi +check_creds() { + [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" + [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" + [ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" -case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in - *[\\\"\']*) - exiterr "VPN credentials must not contain these special characters: \\ \" '" - ;; -esac + if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then + bigecho "VPN credentials not set by user. Generating random PSK and password..." + VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 20) + VPN_USER=vpnuser + VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' /dev/null | head -c 16) + fi -if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ - || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then - exiterr "The DNS server specified is invalid." -fi + if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then + exiterr "All VPN credentials must be specified. Edit the script and re-enter them." + fi -if [ -x /sbin/iptables ] && ! iptables -nL INPUT >/dev/null 2>&1; then - exiterr "IPTables check failed. Reboot and re-run this script." -fi + if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then + exiterr "VPN credentials must not contain non-ASCII characters." + fi -bigecho "VPN setup in progress... Please be patient." + case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in + *[\\\"\']*) + exiterr "VPN credentials must not contain these special characters: \\ \" '" + ;; + esac +} -count=0 -apt_lk=/var/lib/apt/lists/lock -pkg_lk=/var/lib/dpkg/lock -while fuser "$apt_lk" "$pkg_lk" >/dev/null 2>&1 \ - || lsof "$apt_lk" >/dev/null 2>&1 || lsof "$pkg_lk" >/dev/null 2>&1; do - [ "$count" = "0" ] && bigecho "Waiting for apt to be available..." - [ "$count" -ge "100" ] && exiterr "Could not get apt/dpkg lock." - count=$((count+1)) - printf '%s' '.' - sleep 3 -done +check_dns() { + if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ + || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then + exiterr "The DNS server specified is invalid." + fi +} -mkdir -p /opt/src -cd /opt/src || exit 1 +check_iptables() { + if [ -x /sbin/iptables ] && ! iptables -nL INPUT >/dev/null 2>&1; then + exiterr "IPTables check failed. Reboot and re-run this script." + fi +} -bigecho "Installing packages required for setup..." +# shellcheck disable=SC2154,SC2039,SC3047 +start_setup() { + bigecho "VPN setup in progress... Please be patient." + trap 'dlo=$dl;dl=$LINENO' DEBUG 2>/dev/null + trap 'finish $? $((dlo+1))' EXIT + mkdir -p /opt/src + cd /opt/src || exit 1 +} -export DEBIAN_FRONTEND=noninteractive -( - set -x - apt-get -yqq update -) || exiterr "'apt-get update' failed." -( - set -x - apt-get -yqq install wget dnsutils openssl \ - iptables iproute2 gawk grep sed net-tools >/dev/null -) || exiterr2 +wait_for_apt() { + count=0 + apt_lk=/var/lib/apt/lists/lock + pkg_lk=/var/lib/dpkg/lock + while fuser "$apt_lk" "$pkg_lk" >/dev/null 2>&1 \ + || lsof "$apt_lk" >/dev/null 2>&1 || lsof "$pkg_lk" >/dev/null 2>&1; do + [ "$count" = "0" ] && echo "## Waiting for apt to be available..." + [ "$count" -ge "100" ] && exiterr "Could not get apt/dpkg lock." + count=$((count+1)) + printf '%s' '.' + sleep 3 + done +} -bigecho "Trying to auto discover IP of this server..." +install_setup_pkgs_1() { + bigecho "Installing packages required for setup..." + export DEBIAN_FRONTEND=noninteractive + ( + set -x + apt-get -yqq update + ) || exiterr "'apt-get update' failed." +} -public_ip=${VPN_PUBLIC_IP:-''} -check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) -check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) -check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." +install_setup_pkgs_2() { + ( + set -x + apt-get -yqq install wget dnsutils openssl \ + iptables iproute2 gawk grep sed net-tools >/dev/null + ) || exiterr2 +} -bigecho "Installing packages required for the VPN..." +detect_ip() { + bigecho "Trying to auto discover IP of this server..." + public_ip=${VPN_PUBLIC_IP:-''} + check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) + check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) + check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." +} -( - set -x - apt-get -yqq install libnss3-dev libnspr4-dev pkg-config \ - libpam0g-dev libcap-ng-dev libcap-ng-utils libselinux1-dev \ - libcurl4-nss-dev flex bison gcc make libnss3-tools \ - libevent-dev libsystemd-dev uuid-runtime ppp xl2tpd >/dev/null -) || exiterr2 +install_vpn_pkgs() { + bigecho "Installing packages required for the VPN..." + ( + set -x + apt-get -yqq install libnss3-dev libnspr4-dev pkg-config \ + libpam0g-dev libcap-ng-dev libcap-ng-utils libselinux1-dev \ + libcurl4-nss-dev flex bison gcc make libnss3-tools \ + libevent-dev libsystemd-dev uuid-runtime ppp xl2tpd >/dev/null + ) || exiterr2 +} -bigecho "Installing Fail2Ban to protect SSH..." +install_fail2ban() { + bigecho "Installing Fail2Ban to protect SSH..." + ( + set -x + apt-get -yqq install fail2ban >/dev/null + ) || exiterr2 +} -( - set -x - apt-get -yqq install fail2ban >/dev/null -) || exiterr2 +get_ikev2_script() { + bigecho "Downloading IKEv2 script..." + ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" + ( + set -x + wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" + ) || /bin/rm -f ikev2.sh + [ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null +} -bigecho "Downloading IKEv2 script..." +get_libreswan() { + bigecho "Downloading Libreswan..." + SWAN_VER=4.4 + swan_file="libreswan-$SWAN_VER.tar.gz" + swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz" + swan_url2="https://download.libreswan.org/$swan_file" + ( + set -x + wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" + ) || exit 1 + /bin/rm -rf "/opt/src/libreswan-$SWAN_VER" + tar xzf "$swan_file" && /bin/rm -f "$swan_file" +} -ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" -( - set -x - wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" -) || /bin/rm -f ikev2.sh -[ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null - -bigecho "Downloading Libreswan..." - -SWAN_VER=4.4 -swan_file="libreswan-$SWAN_VER.tar.gz" -swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz" -swan_url2="https://download.libreswan.org/$swan_file" -( - set -x - wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" -) || exit 1 -/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" -tar xzf "$swan_file" && /bin/rm -f "$swan_file" - -bigecho "Compiling and installing Libreswan, please wait..." - -cd "libreswan-$SWAN_VER" || exit 1 +install_libreswan() { + bigecho "Compiling and installing Libreswan, please wait..." + cd "libreswan-$SWAN_VER" || exit 1 cat > Makefile.inc.local <<'EOF' WERROR_CFLAGS=-w -s USE_DNSSEC=false @@ -223,44 +250,46 @@ USE_DH2=true USE_NSS_KDF=false FINALNSSDIR=/etc/ipsec.d EOF -if ! grep -qs 'VERSION_CODENAME=' /etc/os-release; then + if ! grep -qs 'VERSION_CODENAME=' /etc/os-release; then cat >> Makefile.inc.local <<'EOF' USE_DH31=false USE_NSS_AVA_COPY=true USE_NSS_IPSEC_PROFILE=false USE_GLIBC_KERN_FLIP_HEADERS=true EOF -fi -if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then - echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local -fi -NPROCS=$(grep -c ^processor /proc/cpuinfo) -[ -z "$NPROCS" ] && NPROCS=1 -( - set -x - make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null -) + fi + if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then + echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local + fi + NPROCS=$(grep -c ^processor /proc/cpuinfo) + [ -z "$NPROCS" ] && NPROCS=1 + ( + set -x + make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null + ) -cd /opt/src || exit 1 -/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" -if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then - exiterr "Libreswan $SWAN_VER failed to build." -fi + cd /opt/src || exit 1 + /bin/rm -rf "/opt/src/libreswan-$SWAN_VER" + if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then + exiterr "Libreswan $SWAN_VER failed to build." + fi +} -bigecho "Creating VPN configuration..." +create_vpn_config() { + bigecho "Creating VPN configuration..." -L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} -L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} -L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} -XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} -XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} -DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} -DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} -DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" -[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" + L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} + L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} + L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} + XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} + XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} + DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} + DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} + DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" + [ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" -# Create IPsec config -conf_bk "/etc/ipsec.conf" + # Create IPsec config + conf_bk "/etc/ipsec.conf" cat > /etc/ipsec.conf < /etc/ipsec.secrets < /etc/xl2tpd/xl2tpd.conf < /etc/ppp/options.xl2tpd <> /etc/ppp/options.xl2tpd < /etc/ppp/chap-secrets < /etc/ipsec.d/passwd <> /etc/sysctl.conf </dev/null 2>&1 - iptables-save > "$IPT_FILE.old-$SYS_DT" - $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP - $ipi 2 -m conntrack --ctstate INVALID -j DROP - $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT - $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT - $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT - $ipi 6 -p udp --dport 1701 -j DROP - $ipf 1 -m conntrack --ctstate INVALID -j DROP - $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT - $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT - $ipf 4 -i ppp+ -o ppp+ -j ACCEPT - $ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT - $ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT - $ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT - iptables -A FORWARD -j DROP - $ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE - $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE - echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" - iptables-save >> "$IPT_FILE" - - if [ -f "$IPT_FILE2" ]; then - conf_bk "$IPT_FILE2" - /bin/cp -f "$IPT_FILE" "$IPT_FILE2" fi -fi +} -bigecho "Enabling services on boot..." +update_iptables() { + bigecho "Updating IPTables rules..." + IPT_FILE=/etc/iptables.rules + IPT_FILE2=/etc/iptables/rules.v4 + ipt_flag=0 + if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then + ipt_flag=1 + fi -IPT_PST=/etc/init.d/iptables-persistent -IPT_PST2=/usr/share/netfilter-persistent/plugins.d/15-ip4tables -ipt_load=1 -if [ -f "$IPT_FILE2" ] && { [ -f "$IPT_PST" ] || [ -f "$IPT_PST2" ]; }; then - ipt_load=0 -fi + ipi='iptables -I INPUT' + ipf='iptables -I FORWARD' + ipp='iptables -t nat -I POSTROUTING' + res='RELATED,ESTABLISHED' + if [ "$ipt_flag" = "1" ]; then + service fail2ban stop >/dev/null 2>&1 + iptables-save > "$IPT_FILE.old-$SYS_DT" + $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP + $ipi 2 -m conntrack --ctstate INVALID -j DROP + $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT + $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT + $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT + $ipi 6 -p udp --dport 1701 -j DROP + $ipf 1 -m conntrack --ctstate INVALID -j DROP + $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT + $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT + $ipf 4 -i ppp+ -o ppp+ -j ACCEPT + $ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT + $ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT + $ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT + iptables -A FORWARD -j DROP + $ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE + $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE + echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" + iptables-save >> "$IPT_FILE" -if [ "$ipt_load" = "1" ]; then - mkdir -p /etc/network/if-pre-up.d + if [ -f "$IPT_FILE2" ]; then + conf_bk "$IPT_FILE2" + /bin/cp -f "$IPT_FILE" "$IPT_FILE2" + fi + fi +} + +enable_on_boot() { + bigecho "Enabling services on boot..." + IPT_PST=/etc/init.d/iptables-persistent + IPT_PST2=/usr/share/netfilter-persistent/plugins.d/15-ip4tables + ipt_load=1 + if [ -f "$IPT_FILE2" ] && { [ -f "$IPT_PST" ] || [ -f "$IPT_PST2" ]; }; then + ipt_load=0 + fi + + if [ "$ipt_load" = "1" ]; then + mkdir -p /etc/network/if-pre-up.d cat > /etc/network/if-pre-up.d/iptablesload <<'EOF' #!/bin/sh iptables-restore < /etc/iptables.rules exit 0 EOF - chmod +x /etc/network/if-pre-up.d/iptablesload + chmod +x /etc/network/if-pre-up.d/iptablesload - if [ -f /usr/sbin/netplan ]; then - mkdir -p /etc/systemd/system + if [ -f /usr/sbin/netplan ]; then + mkdir -p /etc/systemd/system cat > /etc/systemd/system/load-iptables-rules.service <<'EOF' [Unit] Description = Load /etc/iptables.rules @@ -480,22 +512,22 @@ ExecStart=/etc/network/if-pre-up.d/iptablesload [Install] WantedBy=multi-user.target EOF - systemctl enable load-iptables-rules 2>/dev/null + systemctl enable load-iptables-rules 2>/dev/null + fi fi -fi -for svc in fail2ban ipsec xl2tpd; do - update-rc.d "$svc" enable >/dev/null 2>&1 - systemctl enable "$svc" 2>/dev/null -done + for svc in fail2ban ipsec xl2tpd; do + update-rc.d "$svc" enable >/dev/null 2>&1 + systemctl enable "$svc" 2>/dev/null + done -if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then - if [ -f /etc/rc.local ]; then - conf_bk "/etc/rc.local" - sed --follow-symlinks -i '/^exit 0/d' /etc/rc.local - else - echo '#!/bin/sh' > /etc/rc.local - fi + if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then + if [ -f /etc/rc.local ]; then + conf_bk "/etc/rc.local" + sed --follow-symlinks -i '/^exit 0/d' /etc/rc.local + else + echo '#!/bin/sh' > /etc/rc.local + fi cat >> /etc/rc.local <<'EOF' # Added by hwdsl2 VPN script @@ -505,33 +537,23 @@ service xl2tpd restart echo 1 > /proc/sys/net/ipv4/ip_forward)& exit 0 EOF -fi + fi +} -bigecho "Starting services..." +start_services() { + bigecho "Starting services..." + sysctl -e -q -p -sysctl -e -q -p + chmod +x /etc/rc.local + chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* -chmod +x /etc/rc.local -chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* - -mkdir -p /run/pluto -service fail2ban restart 2>/dev/null -service ipsec restart 2>/dev/null -service xl2tpd restart 2>/dev/null - -swan_ver_url="https://dl.ls20.com/v1/$os_type/$os_ver/swanver?arch=$os_arch&ver=$SWAN_VER" -swan_ver_latest=$(wget -t 3 -T 15 -qO- "$swan_ver_url") -if printf '%s' "$swan_ver_latest" | grep -Eq '^([3-9]|[1-9][0-9]{1,2})(\.([0-9]|[1-9][0-9]{1,2})){1,2}$' \ - && [ -n "$SWAN_VER" ] && [ "$SWAN_VER" != "$swan_ver_latest" ] \ - && printf '%s\n%s' "$SWAN_VER" "$swan_ver_latest" | sort -C -V; then -cat </dev/null + service ipsec restart 2>/dev/null + service xl2tpd restart 2>/dev/null +} +show_vpn_info() { cat <