1
0
mirror of synced 2024-11-22 21:16:02 +03:00

Improve VPN setup

- Refactor VPN setup scripts into functions
- Cleanup
This commit is contained in:
hwdsl2 2021-08-19 02:01:34 -05:00
parent fc33e1c451
commit 9336c1c2c2
3 changed files with 1061 additions and 859 deletions

View File

@ -46,139 +46,161 @@ check_ip() {
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX" 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_-') check_os() {
if ! grep -qs "Amazon Linux release 2" /etc/system-release; then os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-')
exiterr "This script only supports Amazon Linux 2." if ! grep -qs "Amazon Linux release 2" /etc/system-release; then
fi exiterr "This script only supports Amazon Linux 2."
fi
}
if [ "$(id -u)" != 0 ]; then check_iface() {
exiterr "Script must be run as root. Try 'sudo sh $0'" def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$')
fi [ -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 '[^ ]*$') check_creds() {
[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME"
if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then [ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD"
case $def_iface in
wl*) if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" 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/urandom 2>/dev/null | head -c 20)
VPN_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/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 esac
NET_IFACE="$def_iface" }
else
eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) check_dns() {
if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
exiterr "Could not detect the default network interface." || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
exiterr "The DNS server specified is invalid."
fi fi
NET_IFACE=eth0 }
fi
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" # shellcheck disable=SC2154,SC2039,SC3047
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" start_setup() {
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" 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 install_setup_pkgs() {
bigecho "VPN credentials not set by user. Generating random PSK and password..." bigecho "Installing packages required for setup..."
VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 20) (
VPN_USER=vpnuser set -x
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16) yum -y -q install wget bind-utils openssl tar \
fi iptables iproute gawk grep sed net-tools >/dev/null
) || exiterr2
}
if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then detect_ip() {
exiterr "All VPN credentials must be specified. Edit the script and re-enter them." bigecho "Trying to auto discover IP of this server..."
fi 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 add_epel_repo() {
exiterr "VPN credentials must not contain non-ASCII characters." bigecho "Adding the EPEL repository..."
fi (
set -x
amazon-linux-extras install epel -y >/dev/null
) || exiterr2
}
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in install_vpn_pkgs_1() {
*[\\\"\']*) bigecho "Installing packages required for the VPN..."
exiterr "VPN credentials must not contain these special characters: \\ \" '" (
;; set -x
esac 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"; } \ install_vpn_pkgs_2() {
|| { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then (
exiterr "The DNS server specified is invalid." set -x
fi 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 get_ikev2_script() {
cd /opt/src || exit 1 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"
}
( install_libreswan() {
set -x bigecho "Compiling and installing Libreswan, please wait..."
yum -y -q install wget bind-utils openssl tar \ cd "libreswan-$SWAN_VER" || exit 1
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
cat > Makefile.inc.local <<'EOF' cat > Makefile.inc.local <<'EOF'
WERROR_CFLAGS=-w -s WERROR_CFLAGS=-w -s
USE_DNSSEC=false USE_DNSSEC=false
@ -186,36 +208,38 @@ USE_DH2=true
USE_NSS_KDF=false USE_NSS_KDF=false
FINALNSSDIR=/etc/ipsec.d FINALNSSDIR=/etc/ipsec.d
EOF EOF
if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then
echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local
fi fi
NPROCS=$(grep -c ^processor /proc/cpuinfo) NPROCS=$(grep -c ^processor /proc/cpuinfo)
[ -z "$NPROCS" ] && NPROCS=1 [ -z "$NPROCS" ] && NPROCS=1
( (
set -x set -x
make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null
) )
cd /opt/src || exit 1 cd /opt/src || exit 1
/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then
exiterr "Libreswan $SWAN_VER failed to build." exiterr "Libreswan $SWAN_VER failed to build."
fi fi
}
bigecho "Creating VPN configuration..." create_vpn_config() {
bigecho "Creating VPN configuration..."
L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'}
L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'}
L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'}
XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'}
XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'}
DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'}
DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'}
DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\""
[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" [ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1"
# Create IPsec config # Create IPsec config
conf_bk "/etc/ipsec.conf" conf_bk "/etc/ipsec.conf"
cat > /etc/ipsec.conf <<EOF cat > /etc/ipsec.conf <<EOF
version 2.0 version 2.0
@ -265,14 +289,14 @@ conn xauth-psk
include /etc/ipsec.d/*.conf include /etc/ipsec.d/*.conf
EOF EOF
# Specify IPsec PSK # Specify IPsec PSK
conf_bk "/etc/ipsec.secrets" conf_bk "/etc/ipsec.secrets"
cat > /etc/ipsec.secrets <<EOF cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "$VPN_IPSEC_PSK" %any %any : PSK "$VPN_IPSEC_PSK"
EOF EOF
# Create xl2tpd config # Create xl2tpd config
conf_bk "/etc/xl2tpd/xl2tpd.conf" conf_bk "/etc/xl2tpd/xl2tpd.conf"
cat > /etc/xl2tpd/xl2tpd.conf <<EOF cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global] [global]
port = 1701 port = 1701
@ -288,8 +312,8 @@ pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes length bit = yes
EOF EOF
# Set xl2tpd options # Set xl2tpd options
conf_bk "/etc/ppp/options.xl2tpd" conf_bk "/etc/ppp/options.xl2tpd"
cat > /etc/ppp/options.xl2tpd <<EOF cat > /etc/ppp/options.xl2tpd <<EOF
+mschap-v2 +mschap-v2
ipcp-accept-local ipcp-accept-local
@ -305,28 +329,43 @@ connect-delay 5000
ms-dns $DNS_SRV1 ms-dns $DNS_SRV1
EOF EOF
if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then
cat >> /etc/ppp/options.xl2tpd <<EOF cat >> /etc/ppp/options.xl2tpd <<EOF
ms-dns $DNS_SRV2 ms-dns $DNS_SRV2
EOF EOF
fi fi
# Create VPN credentials # Create VPN credentials
conf_bk "/etc/ppp/chap-secrets" conf_bk "/etc/ppp/chap-secrets"
cat > /etc/ppp/chap-secrets <<EOF cat > /etc/ppp/chap-secrets <<EOF
"$VPN_USER" l2tpd "$VPN_PASSWORD" * "$VPN_USER" l2tpd "$VPN_PASSWORD" *
EOF EOF
conf_bk "/etc/ipsec.d/passwd" conf_bk "/etc/ipsec.d/passwd"
VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD") VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD")
cat > /etc/ipsec.d/passwd <<EOF cat > /etc/ipsec.d/passwd <<EOF
$VPN_USER:$VPN_PASSWORD_ENC:xauth-psk $VPN_USER:$VPN_PASSWORD_ENC:xauth-psk
EOF EOF
}
bigecho "Updating sysctl settings..." create_f2b_config() {
F2B_FILE=/etc/fail2ban/jail.local
if [ ! -f "$F2B_FILE" ]; then
bigecho "Creating basic Fail2Ban rules..."
cat > "$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 update_sysctl() {
conf_bk "/etc/sysctl.conf" bigecho "Updating sysctl settings..."
if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then
conf_bk "/etc/sysctl.conf"
cat >> /etc/sysctl.conf <<EOF cat >> /etc/sysctl.conf <<EOF
# Added by hwdsl2 VPN script # Added by hwdsl2 VPN script
@ -348,66 +387,56 @@ net.core.rmem_max = 12582912
net.ipv4.tcp_rmem = 10240 87380 12582912 net.ipv4.tcp_rmem = 10240 87380 12582912
net.ipv4.tcp_wmem = 10240 87380 12582912 net.ipv4.tcp_wmem = 10240 87380 12582912
EOF EOF
fi
F2B_FILE=/etc/fail2ban/jail.local
if [ ! -f "$F2B_FILE" ]; then
bigecho "Creating basic Fail2Ban rules..."
cat > "$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 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' cat >> /etc/rc.local <<'EOF'
# Added by hwdsl2 VPN script # Added by hwdsl2 VPN script
@ -416,45 +445,35 @@ service ipsec restart
service xl2tpd restart service xl2tpd restart
echo 1 > /proc/sys/net/ipv4/ip_forward)& echo 1 > /proc/sys/net/ipv4/ip_forward)&
EOF EOF
fi fi
}
bigecho "Starting services..." start_services() {
bigecho "Starting services..."
sysctl -e -q -p
restorecon /etc/ipsec.d/*db 2>/dev/null chmod +x /etc/rc.local
restorecon /usr/local/sbin -Rv 2>/dev/null chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd*
restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null
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 iptables-restore < "$IPT_FILE"
chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd*
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 mkdir -p /run/pluto
if ! modprobe -q l2tp_ppp; then service fail2ban restart 2>/dev/null
sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service service ipsec restart 2>/dev/null
systemctl daemon-reload service xl2tpd restart 2>/dev/null
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 <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update, run:
wget https://git.io/vpnupgrade -O vpnup.sh && sudo sh vpnup.sh
EOF
fi
show_vpn_info() {
cat <<EOF cat <<EOF
================================================ ================================================
@ -477,7 +496,52 @@ IKEv2 guide: https://git.io/ikev2
================================================ ================================================
EOF EOF
}
check_swan_ver() {
swan_ver_url="https://dl.ls20.com/v1/amzn/2/swanver?arch=$os_arch&ver=$SWAN_VER"
[ "$1" != "0" ] && swan_ver_url="$swan_ver_url&e=$2"
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}$' \
&& [ "$1" = "0" ] && [ -n "$SWAN_VER" ] && [ "$SWAN_VER" != "$swan_ver_latest" ] \
&& printf '%s\n%s' "$SWAN_VER" "$swan_ver_latest" | sort -C -V; then
cat <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update, run:
wget https://git.io/vpnupgrade -O vpnup.sh && sudo sh vpnup.sh
EOF
fi
}
finish() {
check_swan_ver "$1" "$2"
exit "$1"
}
vpnsetup() {
check_root
check_os
check_iface
check_creds
check_dns
start_setup
install_setup_pkgs
detect_ip
add_epel_repo
install_vpn_pkgs_1
install_vpn_pkgs_2
install_fail2ban
get_ikev2_script
get_libreswan
install_libreswan
create_vpn_config
create_f2b_config
update_sysctl
update_iptables
enable_on_boot
start_services
show_vpn_info
} }
## Defer setup until we have the complete script ## Defer setup until we have the complete script

View File

@ -47,188 +47,214 @@ check_ip() {
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX" 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_type=centos check_vz() {
os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-') if [ -f /proc/user_beancounters ]; then
rh_file="/etc/redhat-release" exiterr "OpenVZ VPS is not supported."
if grep -qs "Red Hat" "$rh_file"; then fi
os_type=rhel }
fi
if grep -qs "release 7" "$rh_file"; then
os_ver=7
elif grep -qs "release 8" "$rh_file"; then
os_ver=8
grep -qi stream "$rh_file" && os_ver=8s
grep -qi rocky "$rh_file" && os_type=rocky
grep -qi alma "$rh_file" && os_type=alma
else
exiterr "This script only supports CentOS/RHEL 7 and 8."
fi
if [ -f /proc/user_beancounters ]; then check_os() {
exiterr "OpenVZ VPS is not supported." os_type=centos
fi os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-')
rh_file="/etc/redhat-release"
if grep -qs "Red Hat" "$rh_file"; then
os_type=rhel
fi
if grep -qs "release 7" "$rh_file"; then
os_ver=7
elif grep -qs "release 8" "$rh_file"; then
os_ver=8
grep -qi stream "$rh_file" && os_ver=8s
grep -qi rocky "$rh_file" && os_type=rocky
grep -qi alma "$rh_file" && os_type=alma
else
exiterr "This script only supports CentOS/RHEL 7 and 8."
fi
}
if [ "$(id -u)" != 0 ]; then check_iface() {
exiterr "Script must be run as root. Try 'sudo sh $0'" def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$')
fi [ -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 '[^ ]*$') check_creds() {
[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME"
if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then [ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD"
case $def_iface in
wl*) if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" 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/urandom 2>/dev/null | head -c 20)
VPN_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/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 esac
NET_IFACE="$def_iface" }
else
eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) check_dns() {
if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
exiterr "Could not detect the default network interface." || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
exiterr "The DNS server specified is invalid."
fi fi
NET_IFACE=eth0 }
fi
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" # shellcheck disable=SC2154,SC2039,SC3047
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" start_setup() {
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" 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 install_setup_pkgs() {
bigecho "VPN credentials not set by user. Generating random PSK and password..." bigecho "Installing packages required for setup..."
VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 20)
VPN_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/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
( (
set -x 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 ) || 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 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 ) || exiterr2
if systemctl is-active --quiet firewalld \ }
|| systemctl is-active --quiet nftables \
|| grep -qs "hwdsl2 VPN script" /etc/sysconfig/nftables.conf; then install_vpn_pkgs_1() {
use_nft=1 bigecho "Installing packages required for the VPN..."
p4=nftables 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 fi
}
install_fail2ban() {
bigecho "Installing Fail2Ban to protect SSH..."
( (
set -x set -x
yum -y -q install $p4 >/dev/null yum "$rp1" -y -q install fail2ban >/dev/null
) || exiterr2 ) || 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
}
( get_libreswan() {
set -x bigecho "Downloading Libreswan..."
yum "$rp1" -y -q install fail2ban >/dev/null SWAN_VER=4.4
) || exiterr2 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..." install_libreswan() {
bigecho "Compiling and installing Libreswan, please wait..."
ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" cd "libreswan-$SWAN_VER" || exit 1
(
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
cat > Makefile.inc.local <<'EOF' cat > Makefile.inc.local <<'EOF'
WERROR_CFLAGS=-w -s WERROR_CFLAGS=-w -s
USE_DNSSEC=false USE_DNSSEC=false
@ -236,36 +262,38 @@ USE_DH2=true
USE_NSS_KDF=false USE_NSS_KDF=false
FINALNSSDIR=/etc/ipsec.d FINALNSSDIR=/etc/ipsec.d
EOF EOF
if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then
echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local
fi fi
NPROCS=$(grep -c ^processor /proc/cpuinfo) NPROCS=$(grep -c ^processor /proc/cpuinfo)
[ -z "$NPROCS" ] && NPROCS=1 [ -z "$NPROCS" ] && NPROCS=1
( (
set -x set -x
make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null
) )
cd /opt/src || exit 1 cd /opt/src || exit 1
/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then
exiterr "Libreswan $SWAN_VER failed to build." exiterr "Libreswan $SWAN_VER failed to build."
fi fi
}
bigecho "Creating VPN configuration..." create_vpn_config() {
bigecho "Creating VPN configuration..."
L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'}
L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'}
L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'}
XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'}
XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'}
DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'}
DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'}
DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\""
[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" [ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1"
# Create IPsec config # Create IPsec config
conf_bk "/etc/ipsec.conf" conf_bk "/etc/ipsec.conf"
cat > /etc/ipsec.conf <<EOF cat > /etc/ipsec.conf <<EOF
version 2.0 version 2.0
@ -315,14 +343,14 @@ conn xauth-psk
include /etc/ipsec.d/*.conf include /etc/ipsec.d/*.conf
EOF EOF
# Specify IPsec PSK # Specify IPsec PSK
conf_bk "/etc/ipsec.secrets" conf_bk "/etc/ipsec.secrets"
cat > /etc/ipsec.secrets <<EOF cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "$VPN_IPSEC_PSK" %any %any : PSK "$VPN_IPSEC_PSK"
EOF EOF
# Create xl2tpd config # Create xl2tpd config
conf_bk "/etc/xl2tpd/xl2tpd.conf" conf_bk "/etc/xl2tpd/xl2tpd.conf"
cat > /etc/xl2tpd/xl2tpd.conf <<EOF cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global] [global]
port = 1701 port = 1701
@ -338,8 +366,8 @@ pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes length bit = yes
EOF EOF
# Set xl2tpd options # Set xl2tpd options
conf_bk "/etc/ppp/options.xl2tpd" conf_bk "/etc/ppp/options.xl2tpd"
cat > /etc/ppp/options.xl2tpd <<EOF cat > /etc/ppp/options.xl2tpd <<EOF
+mschap-v2 +mschap-v2
ipcp-accept-local ipcp-accept-local
@ -355,28 +383,53 @@ connect-delay 5000
ms-dns $DNS_SRV1 ms-dns $DNS_SRV1
EOF EOF
if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then
cat >> /etc/ppp/options.xl2tpd <<EOF cat >> /etc/ppp/options.xl2tpd <<EOF
ms-dns $DNS_SRV2 ms-dns $DNS_SRV2
EOF EOF
fi fi
# Create VPN credentials # Create VPN credentials
conf_bk "/etc/ppp/chap-secrets" conf_bk "/etc/ppp/chap-secrets"
cat > /etc/ppp/chap-secrets <<EOF cat > /etc/ppp/chap-secrets <<EOF
"$VPN_USER" l2tpd "$VPN_PASSWORD" * "$VPN_USER" l2tpd "$VPN_PASSWORD" *
EOF EOF
conf_bk "/etc/ipsec.d/passwd" conf_bk "/etc/ipsec.d/passwd"
VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD") VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD")
cat > /etc/ipsec.d/passwd <<EOF cat > /etc/ipsec.d/passwd <<EOF
$VPN_USER:$VPN_PASSWORD_ENC:xauth-psk $VPN_USER:$VPN_PASSWORD_ENC:xauth-psk
EOF EOF
}
bigecho "Updating sysctl settings..." create_f2b_config() {
F2B_FILE=/etc/fail2ban/jail.local
if [ ! -f "$F2B_FILE" ]; then
bigecho "Creating basic Fail2Ban rules..."
cat > "$F2B_FILE" <<'EOF'
[ssh-iptables]
enabled = true
filter = sshd
logpath = /var/log/secure
EOF
if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then if [ "$use_nft" = "1" ]; then
conf_bk "/etc/sysctl.conf" 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 <<EOF cat >> /etc/sysctl.conf <<EOF
# Added by hwdsl2 VPN script # Added by hwdsl2 VPN script
@ -397,104 +450,84 @@ net.core.wmem_max = 12582912
net.core.rmem_max = 12582912 net.core.rmem_max = 12582912
net.ipv4.tcp_rmem = 10240 87380 12582912 net.ipv4.tcp_rmem = 10240 87380 12582912
net.ipv4.tcp_wmem = 10240 87380 12582912 net.ipv4.tcp_wmem = 10240 87380 12582912
EOF
fi
F2B_FILE=/etc/fail2ban/jail.local
if [ ! -f "$F2B_FILE" ]; then
bigecho "Creating basic Fail2Ban rules..."
cat > "$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 EOF
fi fi
fi }
bigecho "Updating IPTables rules..." update_iptables() {
bigecho "Updating IPTables rules..."
IPT_FILE=/etc/sysconfig/iptables IPT_FILE=/etc/sysconfig/iptables
[ "$use_nft" = "1" ] && IPT_FILE=/etc/sysconfig/nftables.conf [ "$use_nft" = "1" ] && IPT_FILE=/etc/sysconfig/nftables.conf
ipt_flag=0 ipt_flag=0
if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then
ipt_flag=1 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"
fi fi
$ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
$ipi 2 -m conntrack --ctstate INVALID -j DROP ipi='iptables -I INPUT'
$ipi 3 -m conntrack --ctstate "$res" -j ACCEPT ipf='iptables -I FORWARD'
$ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT ipp='iptables -t nat -I POSTROUTING'
$ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT res='RELATED,ESTABLISHED'
$ipi 6 -p udp --dport 1701 -j DROP nff='nft insert rule inet firewalld'
$ipf 1 -m conntrack --ctstate INVALID -j DROP nfn='nft insert rule inet nftables_svc'
$ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT if [ "$ipt_flag" = "1" ]; then
$ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT service fail2ban stop >/dev/null 2>&1
$ipf 4 -i ppp+ -o ppp+ -j ACCEPT if [ "$use_nft" = "1" ]; then
$ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT nft list ruleset > "$IPT_FILE.old-$SYS_DT"
$ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT chmod 600 "$IPT_FILE.old-$SYS_DT"
$ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT else
iptables -A FORWARD -j DROP iptables-save > "$IPT_FILE.old-$SYS_DT"
$ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE fi
$ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" $ipi 2 -m conntrack --ctstate INVALID -j DROP
if [ "$use_nft" = "1" ]; then $ipi 3 -m conntrack --ctstate "$res" -j ACCEPT
for vport in 500 4500 1701; do $ipi 4 -p udp -m multiport --dports 500,4500 -j ACCEPT
$nff filter_INPUT udp dport "$vport" accept 2>/dev/null $ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT
$nfn allow udp dport "$vport" accept 2>/dev/null $ipi 6 -p udp --dport 1701 -j DROP
done $ipf 1 -m conntrack --ctstate INVALID -j DROP
for vnet in "$L2TP_NET" "$XAUTH_NET"; do $ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT
for vdir in saddr daddr; do $ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT
$nff filter_FORWARD ip "$vdir" "$vnet" accept 2>/dev/null $ipf 4 -i ppp+ -o ppp+ -j ACCEPT
$nfn FORWARD ip "$vdir" "$vnet" accept 2>/dev/null $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
done for vnet in "$L2TP_NET" "$XAUTH_NET"; do
echo "flush ruleset" >> "$IPT_FILE" for vdir in saddr daddr; do
nft list ruleset >> "$IPT_FILE" $nff filter_FORWARD ip "$vdir" "$vnet" accept 2>/dev/null
else $nfn FORWARD ip "$vdir" "$vnet" accept 2>/dev/null
iptables-save >> "$IPT_FILE" done
done
echo "flush ruleset" >> "$IPT_FILE"
nft list ruleset >> "$IPT_FILE"
else
iptables-save >> "$IPT_FILE"
fi
fi fi
fi }
bigecho "Enabling services on boot..." enable_on_boot() {
bigecho "Enabling services on boot..."
systemctl --now mask firewalld 2>/dev/null systemctl --now mask firewalld 2>/dev/null
if [ "$use_nft" = "1" ]; then if [ "$use_nft" = "1" ]; then
systemctl enable nftables fail2ban 2>/dev/null 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"
else else
echo '#!/bin/sh' > /etc/rc.local systemctl enable iptables fail2ban 2>/dev/null
fi 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' cat >> /etc/rc.local <<'EOF'
# Added by hwdsl2 VPN script # Added by hwdsl2 VPN script
@ -503,49 +536,39 @@ service ipsec restart
service xl2tpd restart service xl2tpd restart
echo 1 > /proc/sys/net/ipv4/ip_forward)& echo 1 > /proc/sys/net/ipv4/ip_forward)&
EOF EOF
fi fi
}
bigecho "Starting services..." start_services() {
bigecho "Starting services..."
sysctl -e -q -p
restorecon /etc/ipsec.d/*db 2>/dev/null chmod +x /etc/rc.local
restorecon /usr/local/sbin -Rv 2>/dev/null chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd*
restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null
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 if [ "$use_nft" = "1" ]; then
chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* nft -f "$IPT_FILE"
else
iptables-restore < "$IPT_FILE"
fi
if [ "$use_nft" = "1" ]; then # Fix xl2tpd if l2tp_ppp is unavailable
nft -f "$IPT_FILE" if ! modprobe -q l2tp_ppp; then
else sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service
iptables-restore < "$IPT_FILE" systemctl daemon-reload
fi fi
# Fix xl2tpd if l2tp_ppp is unavailable mkdir -p /run/pluto
if ! modprobe -q l2tp_ppp; then service fail2ban restart 2>/dev/null
sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service service ipsec restart 2>/dev/null
systemctl daemon-reload service xl2tpd restart 2>/dev/null
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 <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update, run:
wget https://git.io/vpnupgrade -O vpnup.sh && sudo sh vpnup.sh
EOF
fi
show_vpn_info() {
cat <<EOF cat <<EOF
================================================ ================================================
@ -568,7 +591,54 @@ IKEv2 guide: https://git.io/ikev2
================================================ ================================================
EOF EOF
}
check_swan_ver() {
swan_ver_url="https://dl.ls20.com/v1/$os_type/$os_ver/swanver?arch=$os_arch&ver=$SWAN_VER"
[ "$1" != "0" ] && swan_ver_url="$swan_ver_url&e=$2"
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}$' \
&& [ "$1" = "0" ] && [ -n "$SWAN_VER" ] && [ "$SWAN_VER" != "$swan_ver_latest" ] \
&& printf '%s\n%s' "$SWAN_VER" "$swan_ver_latest" | sort -C -V; then
cat <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update, run:
wget https://git.io/vpnupgrade -O vpnup.sh && sudo sh vpnup.sh
EOF
fi
}
finish() {
check_swan_ver "$1" "$2"
exit "$1"
}
vpnsetup() {
check_root
check_vz
check_os
check_iface
check_creds
check_dns
start_setup
install_setup_pkgs
detect_ip
add_epel_repo
install_vpn_pkgs_1
install_vpn_pkgs_2
install_vpn_pkgs_3
install_fail2ban
get_ikev2_script
get_libreswan
install_libreswan
create_vpn_config
create_f2b_config
update_sysctl
update_iptables
enable_on_boot
start_services
show_vpn_info
} }
## Defer setup until we have the complete script ## Defer setup until we have the complete script

View File

@ -47,175 +47,202 @@ check_ip() {
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX" printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
} }
vpnsetup() { check_root() {
if [ "$(id -u)" != 0 ]; then
os_type=$(lsb_release -si 2>/dev/null) exiterr "Script must be run as root. Try 'sudo sh $0'"
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
fi fi
NET_IFACE="$def_iface" }
else
eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) check_vz() {
if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then if [ -f /proc/user_beancounters ]; then
exiterr "Could not detect the default network interface." exiterr "OpenVZ VPS is not supported."
fi fi
NET_IFACE=eth0 }
fi
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" check_os() {
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" os_type=$(lsb_release -si 2>/dev/null)
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" 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 os_ver=$(sed 's/\..*//' /etc/debian_version | tr -dc 'A-Za-z0-9')
bigecho "VPN credentials not set by user. Generating random PSK and password..." if [ "$os_ver" = "8" ] || [ "$os_ver" = "jessiesid" ]; then
VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 20) exiterr "Debian 8 or Ubuntu < 16.04 is not supported."
VPN_USER=vpnuser fi
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16) if { [ "$os_ver" = "10" ] || [ "$os_ver" = "11" ]; } && [ ! -e /dev/ppp ]; then
fi 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 check_iface() {
exiterr "All VPN credentials must be specified. Edit the script and re-enter them." def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$')
fi [ -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 check_creds() {
exiterr "VPN credentials must not contain non-ASCII characters." [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
fi [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME"
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD"
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
*[\\\"\']*) bigecho "VPN credentials not set by user. Generating random PSK and password..."
exiterr "VPN credentials must not contain these special characters: \\ \" '" VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 20)
;; VPN_USER=vpnuser
esac VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16)
fi
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then
|| { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then exiterr "All VPN credentials must be specified. Edit the script and re-enter them."
exiterr "The DNS server specified is invalid." fi
fi
if [ -x /sbin/iptables ] && ! iptables -nL INPUT >/dev/null 2>&1; then if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then
exiterr "IPTables check failed. Reboot and re-run this script." exiterr "VPN credentials must not contain non-ASCII characters."
fi 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 check_dns() {
apt_lk=/var/lib/apt/lists/lock if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
pkg_lk=/var/lib/dpkg/lock || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
while fuser "$apt_lk" "$pkg_lk" >/dev/null 2>&1 \ exiterr "The DNS server specified is invalid."
|| lsof "$apt_lk" >/dev/null 2>&1 || lsof "$pkg_lk" >/dev/null 2>&1; do fi
[ "$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
mkdir -p /opt/src check_iptables() {
cd /opt/src || exit 1 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 wait_for_apt() {
( count=0
set -x apt_lk=/var/lib/apt/lists/lock
apt-get -yqq update pkg_lk=/var/lib/dpkg/lock
) || exiterr "'apt-get update' failed." 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
set -x [ "$count" = "0" ] && echo "## Waiting for apt to be available..."
apt-get -yqq install wget dnsutils openssl \ [ "$count" -ge "100" ] && exiterr "Could not get apt/dpkg lock."
iptables iproute2 gawk grep sed net-tools >/dev/null count=$((count+1))
) || exiterr2 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:-''} install_setup_pkgs_2() {
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) set -x
check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it as variable 'VPN_PUBLIC_IP' and re-run this script." 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."
}
( install_vpn_pkgs() {
set -x bigecho "Installing packages required for the VPN..."
apt-get -yqq install libnss3-dev libnspr4-dev pkg-config \ (
libpam0g-dev libcap-ng-dev libcap-ng-utils libselinux1-dev \ set -x
libcurl4-nss-dev flex bison gcc make libnss3-tools \ apt-get -yqq install libnss3-dev libnspr4-dev pkg-config \
libevent-dev libsystemd-dev uuid-runtime ppp xl2tpd >/dev/null libpam0g-dev libcap-ng-dev libcap-ng-utils libselinux1-dev \
) || exiterr2 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
}
( get_ikev2_script() {
set -x bigecho "Downloading IKEv2 script..."
apt-get -yqq install fail2ban >/dev/null ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh"
) || exiterr2 (
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" install_libreswan() {
( bigecho "Compiling and installing Libreswan, please wait..."
set -x cd "libreswan-$SWAN_VER" || exit 1
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
cat > Makefile.inc.local <<'EOF' cat > Makefile.inc.local <<'EOF'
WERROR_CFLAGS=-w -s WERROR_CFLAGS=-w -s
USE_DNSSEC=false USE_DNSSEC=false
@ -223,44 +250,46 @@ USE_DH2=true
USE_NSS_KDF=false USE_NSS_KDF=false
FINALNSSDIR=/etc/ipsec.d FINALNSSDIR=/etc/ipsec.d
EOF EOF
if ! grep -qs 'VERSION_CODENAME=' /etc/os-release; then if ! grep -qs 'VERSION_CODENAME=' /etc/os-release; then
cat >> Makefile.inc.local <<'EOF' cat >> Makefile.inc.local <<'EOF'
USE_DH31=false USE_DH31=false
USE_NSS_AVA_COPY=true USE_NSS_AVA_COPY=true
USE_NSS_IPSEC_PROFILE=false USE_NSS_IPSEC_PROFILE=false
USE_GLIBC_KERN_FLIP_HEADERS=true USE_GLIBC_KERN_FLIP_HEADERS=true
EOF EOF
fi fi
if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then if ! grep -qs IFLA_XFRM_LINK /usr/include/linux/if_link.h; then
echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local echo "USE_XFRM_INTERFACE_IFLA_HEADER=true" >> Makefile.inc.local
fi fi
NPROCS=$(grep -c ^processor /proc/cpuinfo) NPROCS=$(grep -c ^processor /proc/cpuinfo)
[ -z "$NPROCS" ] && NPROCS=1 [ -z "$NPROCS" ] && NPROCS=1
( (
set -x set -x
make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null make "-j$((NPROCS+1))" -s base >/dev/null && make -s install-base >/dev/null
) )
cd /opt/src || exit 1 cd /opt/src || exit 1
/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then
exiterr "Libreswan $SWAN_VER failed to build." exiterr "Libreswan $SWAN_VER failed to build."
fi fi
}
bigecho "Creating VPN configuration..." create_vpn_config() {
bigecho "Creating VPN configuration..."
L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'} L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'}
L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'} L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'}
L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'} L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'}
XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'} XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'}
XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'} XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'}
DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'} DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'}
DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'} DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'}
DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\"" DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\""
[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1" [ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1"
# Create IPsec config # Create IPsec config
conf_bk "/etc/ipsec.conf" conf_bk "/etc/ipsec.conf"
cat > /etc/ipsec.conf <<EOF cat > /etc/ipsec.conf <<EOF
version 2.0 version 2.0
@ -310,20 +339,20 @@ conn xauth-psk
include /etc/ipsec.d/*.conf include /etc/ipsec.d/*.conf
EOF EOF
if uname -m | grep -qi '^arm'; then if uname -m | grep -qi '^arm'; then
if ! modprobe -q sha512; then if ! modprobe -q sha512; then
sed -i '/phase2alg/s/,aes256-sha2_512//' /etc/ipsec.conf sed -i '/phase2alg/s/,aes256-sha2_512//' /etc/ipsec.conf
fi
fi fi
fi
# Specify IPsec PSK # Specify IPsec PSK
conf_bk "/etc/ipsec.secrets" conf_bk "/etc/ipsec.secrets"
cat > /etc/ipsec.secrets <<EOF cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "$VPN_IPSEC_PSK" %any %any : PSK "$VPN_IPSEC_PSK"
EOF EOF
# Create xl2tpd config # Create xl2tpd config
conf_bk "/etc/xl2tpd/xl2tpd.conf" conf_bk "/etc/xl2tpd/xl2tpd.conf"
cat > /etc/xl2tpd/xl2tpd.conf <<EOF cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global] [global]
port = 1701 port = 1701
@ -339,8 +368,8 @@ pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes length bit = yes
EOF EOF
# Set xl2tpd options # Set xl2tpd options
conf_bk "/etc/ppp/options.xl2tpd" conf_bk "/etc/ppp/options.xl2tpd"
cat > /etc/ppp/options.xl2tpd <<EOF cat > /etc/ppp/options.xl2tpd <<EOF
+mschap-v2 +mschap-v2
ipcp-accept-local ipcp-accept-local
@ -356,28 +385,29 @@ connect-delay 5000
ms-dns $DNS_SRV1 ms-dns $DNS_SRV1
EOF EOF
if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then
cat >> /etc/ppp/options.xl2tpd <<EOF cat >> /etc/ppp/options.xl2tpd <<EOF
ms-dns $DNS_SRV2 ms-dns $DNS_SRV2
EOF EOF
fi fi
# Create VPN credentials # Create VPN credentials
conf_bk "/etc/ppp/chap-secrets" conf_bk "/etc/ppp/chap-secrets"
cat > /etc/ppp/chap-secrets <<EOF cat > /etc/ppp/chap-secrets <<EOF
"$VPN_USER" l2tpd "$VPN_PASSWORD" * "$VPN_USER" l2tpd "$VPN_PASSWORD" *
EOF EOF
conf_bk "/etc/ipsec.d/passwd" conf_bk "/etc/ipsec.d/passwd"
VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD") VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD")
cat > /etc/ipsec.d/passwd <<EOF cat > /etc/ipsec.d/passwd <<EOF
$VPN_USER:$VPN_PASSWORD_ENC:xauth-psk $VPN_USER:$VPN_PASSWORD_ENC:xauth-psk
EOF EOF
}
bigecho "Updating sysctl settings..." update_sysctl() {
bigecho "Updating sysctl settings..."
if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then
conf_bk "/etc/sysctl.conf" conf_bk "/etc/sysctl.conf"
cat >> /etc/sysctl.conf <<EOF cat >> /etc/sysctl.conf <<EOF
# Added by hwdsl2 VPN script # Added by hwdsl2 VPN script
@ -399,69 +429,71 @@ net.core.rmem_max = 12582912
net.ipv4.tcp_rmem = 10240 87380 12582912 net.ipv4.tcp_rmem = 10240 87380 12582912
net.ipv4.tcp_wmem = 10240 87380 12582912 net.ipv4.tcp_wmem = 10240 87380 12582912
EOF EOF
fi
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
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 [ -f "$IPT_FILE2" ]; then
conf_bk "$IPT_FILE2"
/bin/cp -f "$IPT_FILE" "$IPT_FILE2"
fi 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 ipi='iptables -I INPUT'
IPT_PST2=/usr/share/netfilter-persistent/plugins.d/15-ip4tables ipf='iptables -I FORWARD'
ipt_load=1 ipp='iptables -t nat -I POSTROUTING'
if [ -f "$IPT_FILE2" ] && { [ -f "$IPT_PST" ] || [ -f "$IPT_PST2" ]; }; then res='RELATED,ESTABLISHED'
ipt_load=0 if [ "$ipt_flag" = "1" ]; then
fi 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 if [ -f "$IPT_FILE2" ]; then
mkdir -p /etc/network/if-pre-up.d 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' cat > /etc/network/if-pre-up.d/iptablesload <<'EOF'
#!/bin/sh #!/bin/sh
iptables-restore < /etc/iptables.rules iptables-restore < /etc/iptables.rules
exit 0 exit 0
EOF 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 if [ -f /usr/sbin/netplan ]; then
mkdir -p /etc/systemd/system mkdir -p /etc/systemd/system
cat > /etc/systemd/system/load-iptables-rules.service <<'EOF' cat > /etc/systemd/system/load-iptables-rules.service <<'EOF'
[Unit] [Unit]
Description = Load /etc/iptables.rules Description = Load /etc/iptables.rules
@ -480,22 +512,22 @@ ExecStart=/etc/network/if-pre-up.d/iptablesload
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
systemctl enable load-iptables-rules 2>/dev/null systemctl enable load-iptables-rules 2>/dev/null
fi
fi fi
fi
for svc in fail2ban ipsec xl2tpd; do for svc in fail2ban ipsec xl2tpd; do
update-rc.d "$svc" enable >/dev/null 2>&1 update-rc.d "$svc" enable >/dev/null 2>&1
systemctl enable "$svc" 2>/dev/null systemctl enable "$svc" 2>/dev/null
done done
if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then
if [ -f /etc/rc.local ]; then if [ -f /etc/rc.local ]; then
conf_bk "/etc/rc.local" conf_bk "/etc/rc.local"
sed --follow-symlinks -i '/^exit 0/d' /etc/rc.local sed --follow-symlinks -i '/^exit 0/d' /etc/rc.local
else else
echo '#!/bin/sh' > /etc/rc.local echo '#!/bin/sh' > /etc/rc.local
fi fi
cat >> /etc/rc.local <<'EOF' cat >> /etc/rc.local <<'EOF'
# Added by hwdsl2 VPN script # Added by hwdsl2 VPN script
@ -505,33 +537,23 @@ service xl2tpd restart
echo 1 > /proc/sys/net/ipv4/ip_forward)& echo 1 > /proc/sys/net/ipv4/ip_forward)&
exit 0 exit 0
EOF 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 mkdir -p /run/pluto
chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd* service fail2ban restart 2>/dev/null
service ipsec restart 2>/dev/null
mkdir -p /run/pluto service xl2tpd restart 2>/dev/null
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 <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update, run:
wget https://git.io/vpnupgrade -O vpnup.sh && sudo sh vpnup.sh
EOF
fi
show_vpn_info() {
cat <<EOF cat <<EOF
================================================ ================================================
@ -554,7 +576,53 @@ IKEv2 guide: https://git.io/ikev2
================================================ ================================================
EOF EOF
}
check_swan_ver() {
swan_ver_url="https://dl.ls20.com/v1/$os_type/$os_ver/swanver?arch=$os_arch&ver=$SWAN_VER"
[ "$1" != "0" ] && swan_ver_url="$swan_ver_url&e=$2"
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}$' \
&& [ "$1" = "0" ] && [ -n "$SWAN_VER" ] && [ "$SWAN_VER" != "$swan_ver_latest" ] \
&& printf '%s\n%s' "$SWAN_VER" "$swan_ver_latest" | sort -C -V; then
cat <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update, run:
wget https://git.io/vpnupgrade -O vpnup.sh && sudo sh vpnup.sh
EOF
fi
}
finish() {
check_swan_ver "$1" "$2"
exit "$1"
}
vpnsetup() {
check_root
check_vz
check_os
check_iface
check_creds
check_dns
check_iptables
start_setup
wait_for_apt
install_setup_pkgs_1
install_setup_pkgs_2
detect_ip
install_vpn_pkgs
install_fail2ban
get_ikev2_script
get_libreswan
install_libreswan
create_vpn_config
update_sysctl
update_iptables
enable_on_boot
start_services
show_vpn_info
} }
## Defer setup until we have the complete script ## Defer setup until we have the complete script