1
0
mirror of synced 2024-11-22 13:06: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
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'" exiterr "Script must be run as root. Try 'sudo sh $0'"
fi fi
}
def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$') check_os() {
[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)') os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-')
def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null) if ! grep -qs "Amazon Linux release 2" /etc/system-release; then
if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then exiterr "This script only supports Amazon Linux 2."
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 case $def_iface in
wl*) wl*)
exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!"
;; ;;
esac esac
NET_IFACE="$def_iface" NET_IFACE="$def_iface"
else else
eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null)
if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then
exiterr "Could not detect the default network interface." exiterr "Could not detect the default network interface."
fi fi
NET_IFACE=eth0 NET_IFACE=eth0
fi fi
}
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" check_creds() {
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" [ -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 if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
bigecho "VPN credentials not set by user. Generating random PSK and password..." 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_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_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16) VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16)
fi fi
if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then 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." exiterr "All VPN credentials must be specified. Edit the script and re-enter them."
fi fi
if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then 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." exiterr "VPN credentials must not contain non-ASCII characters."
fi fi
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in
*[\\\"\']*) *[\\\"\']*)
exiterr "VPN credentials must not contain these special characters: \\ \" '" exiterr "VPN credentials must not contain these special characters: \\ \" '"
;; ;;
esac esac
}
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ check_dns() {
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
|| { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
exiterr "The DNS server specified is invalid." exiterr "The DNS server specified is invalid."
fi fi
}
bigecho "VPN setup in progress... Please be patient." # 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
}
mkdir -p /opt/src install_setup_pkgs() {
cd /opt/src || exit 1 bigecho "Installing packages required for setup..."
(
bigecho "Installing packages required for setup..."
(
set -x set -x
yum -y -q install wget bind-utils openssl tar \ yum -y -q install wget bind-utils openssl tar \
iptables iproute gawk grep sed net-tools >/dev/null iptables iproute gawk grep sed net-tools >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Trying to auto discover IP of this server..." 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."
}
public_ip=${VPN_PUBLIC_IP:-''} add_epel_repo() {
check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) bigecho "Adding the EPEL repository..."
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 set -x
amazon-linux-extras install epel -y >/dev/null amazon-linux-extras install epel -y >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Installing packages required for the VPN..." install_vpn_pkgs_1() {
bigecho "Installing packages required for the VPN..."
( (
set -x set -x
yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \ yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \
libcap-ng-devel libselinux-devel curl-devel nss-tools \ libcap-ng-devel libselinux-devel curl-devel nss-tools \
flex bison gcc make util-linux ppp \ flex bison gcc make util-linux ppp \
systemd-devel iptables-services \ systemd-devel iptables-services \
libevent-devel fipscheck-devel >/dev/null libevent-devel fipscheck-devel >/dev/null
) || exiterr2 ) || exiterr2
( }
install_vpn_pkgs_2() {
(
set -x set -x
yum --enablerepo=epel -y -q install xl2tpd >/dev/null 2>&1 yum --enablerepo=epel -y -q install xl2tpd >/dev/null 2>&1
) || exiterr2 ) || exiterr2
}
bigecho "Installing Fail2Ban to protect SSH..." install_fail2ban() {
bigecho "Installing Fail2Ban to protect SSH..."
( (
set -x set -x
yum --enablerepo=epel -y -q install fail2ban >/dev/null yum --enablerepo=epel -y -q install fail2ban >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Downloading IKEv2 script..." get_ikev2_script() {
bigecho "Downloading IKEv2 script..."
ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh"
( (
set -x set -x
wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url"
) || /bin/rm -f ikev2.sh ) || /bin/rm -f ikev2.sh
[ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null [ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null
}
bigecho "Downloading Libreswan..." get_libreswan() {
bigecho "Downloading Libreswan..."
SWAN_VER=4.4 SWAN_VER=4.4
swan_file="libreswan-$SWAN_VER.tar.gz" swan_file="libreswan-$SWAN_VER.tar.gz"
swan_url1="https://github.com/libreswan/libreswan/archive/v$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" swan_url2="https://download.libreswan.org/$swan_file"
( (
set -x set -x
wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2"
) || exit 1 ) || exit 1
/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
tar xzf "$swan_file" && /bin/rm -f "$swan_file" tar xzf "$swan_file" && /bin/rm -f "$swan_file"
}
bigecho "Compiling and installing Libreswan, please wait..." install_libreswan() {
bigecho "Compiling and installing Libreswan, please wait..."
cd "libreswan-$SWAN_VER" || exit 1 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,27 +329,42 @@ 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() {
bigecho "Updating sysctl settings..."
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
@ -348,33 +387,22 @@ 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 fi
}
F2B_FILE=/etc/fail2ban/jail.local update_iptables() {
if [ ! -f "$F2B_FILE" ]; then bigecho "Updating IPTables rules..."
bigecho "Creating basic Fail2Ban rules..." IPT_FILE=/etc/sysconfig/iptables
cat > "$F2B_FILE" <<'EOF' ipt_flag=0
[ssh-iptables] if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE"; then
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 ipt_flag=1
fi fi
ipi='iptables -I INPUT' ipi='iptables -I INPUT'
ipf='iptables -I FORWARD' ipf='iptables -I FORWARD'
ipp='iptables -t nat -I POSTROUTING' ipp='iptables -t nat -I POSTROUTING'
res='RELATED,ESTABLISHED' res='RELATED,ESTABLISHED'
if [ "$ipt_flag" = "1" ]; then if [ "$ipt_flag" = "1" ]; then
service fail2ban stop >/dev/null 2>&1 service fail2ban stop >/dev/null 2>&1
iptables-save > "$IPT_FILE.old-$SYS_DT" iptables-save > "$IPT_FILE.old-$SYS_DT"
$ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
@ -395,14 +423,15 @@ if [ "$ipt_flag" = "1" ]; then
$ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE $ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE
echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE" echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE"
iptables-save >> "$IPT_FILE" iptables-save >> "$IPT_FILE"
fi fi
}
bigecho "Enabling services on boot..." enable_on_boot() {
bigecho "Enabling services on boot..."
systemctl --now mask firewalld 2>/dev/null
systemctl enable iptables fail2ban 2>/dev/null
systemctl --now mask firewalld 2>/dev/null if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then
systemctl enable iptables fail2ban 2>/dev/null
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"
else else
@ -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
# Fix xl2tpd if l2tp_ppp is unavailable
if ! modprobe -q l2tp_ppp; then
sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service
systemctl daemon-reload systemctl daemon-reload
fi fi
mkdir -p /run/pluto mkdir -p /run/pluto
service fail2ban restart 2>/dev/null service fail2ban restart 2>/dev/null
service ipsec restart 2>/dev/null service ipsec restart 2>/dev/null
service xl2tpd 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,140 +47,162 @@ 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
}
check_os() {
os_type=centos
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 os_type=rhel
fi fi
if grep -qs "release 7" "$rh_file"; then if grep -qs "release 7" "$rh_file"; then
os_ver=7 os_ver=7
elif grep -qs "release 8" "$rh_file"; then elif grep -qs "release 8" "$rh_file"; then
os_ver=8 os_ver=8
grep -qi stream "$rh_file" && os_ver=8s grep -qi stream "$rh_file" && os_ver=8s
grep -qi rocky "$rh_file" && os_type=rocky grep -qi rocky "$rh_file" && os_type=rocky
grep -qi alma "$rh_file" && os_type=alma grep -qi alma "$rh_file" && os_type=alma
else else
exiterr "This script only supports CentOS/RHEL 7 and 8." exiterr "This script only supports CentOS/RHEL 7 and 8."
fi fi
}
if [ -f /proc/user_beancounters ]; then check_iface() {
exiterr "OpenVZ VPS is not supported." 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 [ "$(id -u)" != 0 ]; then if [ -n "$def_state" ] && [ "$def_state" != "down" ]; 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
case $def_iface in case $def_iface in
wl*) wl*)
exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!" exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!"
;; ;;
esac esac
NET_IFACE="$def_iface" NET_IFACE="$def_iface"
else else
eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null)
if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then
exiterr "Could not detect the default network interface." exiterr "Could not detect the default network interface."
fi fi
NET_IFACE=eth0 NET_IFACE=eth0
fi fi
}
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" check_creds() {
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" [ -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 if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
bigecho "VPN credentials not set by user. Generating random PSK and password..." 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_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_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16) VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16)
fi fi
if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then 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." exiterr "All VPN credentials must be specified. Edit the script and re-enter them."
fi fi
if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then 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." exiterr "VPN credentials must not contain non-ASCII characters."
fi fi
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in
*[\\\"\']*) *[\\\"\']*)
exiterr "VPN credentials must not contain these special characters: \\ \" '" exiterr "VPN credentials must not contain these special characters: \\ \" '"
;; ;;
esac esac
}
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ check_dns() {
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
|| { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
exiterr "The DNS server specified is invalid." exiterr "The DNS server specified is invalid."
fi fi
}
bigecho "VPN setup in progress... Please be patient." # 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
}
mkdir -p /opt/src install_setup_pkgs() {
cd /opt/src || exit 1 bigecho "Installing packages required for setup..."
(
bigecho "Installing packages required for setup..."
(
set -x set -x
yum -y -q install wget bind-utils openssl tar \ yum -y -q install wget bind-utils openssl tar \
iptables iproute gawk grep sed net-tools >/dev/null iptables iproute gawk grep sed net-tools >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Trying to auto discover IP of this server..." 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."
}
public_ip=${VPN_PUBLIC_IP:-''} add_epel_repo() {
check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) bigecho "Adding the EPEL repository..."
check_ip "$public_ip" || public_ip=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com) epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E '%{rhel}').noarch.rpm"
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 set -x
yum -y -q install epel-release >/dev/null 2>&1 || yum -y -q install "$epel_url" >/dev/null yum -y -q install epel-release >/dev/null 2>&1 || yum -y -q install "$epel_url" >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Installing packages required for the VPN..." 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-*"
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 set -x
yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \ yum -y -q install nss-devel nspr-devel pkgconfig pam-devel \
libcap-ng-devel libselinux-devel curl-devel nss-tools \ libcap-ng-devel libselinux-devel curl-devel nss-tools \
flex bison gcc make util-linux ppp >/dev/null flex bison gcc make util-linux ppp >/dev/null
) || exiterr2 ) || exiterr2
( }
install_vpn_pkgs_2() {
(
set -x set -x
yum "$rp1" -y -q install xl2tpd >/dev/null 2>&1 yum "$rp1" -y -q install xl2tpd >/dev/null 2>&1
) || exiterr2 ) || exiterr2
}
use_nft=0 install_vpn_pkgs_3() {
p1=systemd-devel use_nft=0
p2=libevent-devel p1=systemd-devel
p3=fipscheck-devel p2=libevent-devel
p4=iptables-services p3=fipscheck-devel
if [ "$os_ver" = "7" ]; then 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 "$rp2" "$rp3" -y -q install $p1 $p2 $p3 $p4 >/dev/null
) || exiterr2 ) || exiterr2
else else
( (
set -x set -x
yum "$rp4" -y -q install $p1 $p2 $p3 >/dev/null yum "$rp4" -y -q install $p1 $p2 $p3 >/dev/null
@ -195,40 +217,44 @@ else
set -x set -x
yum -y -q install $p4 >/dev/null yum -y -q install $p4 >/dev/null
) || exiterr2 ) || exiterr2
fi fi
}
bigecho "Installing Fail2Ban to protect SSH..." install_fail2ban() {
bigecho "Installing Fail2Ban to protect SSH..."
( (
set -x set -x
yum "$rp1" -y -q install fail2ban >/dev/null yum "$rp1" -y -q install fail2ban >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Downloading IKEv2 script..." get_ikev2_script() {
bigecho "Downloading IKEv2 script..."
ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh"
( (
set -x set -x
wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url"
) || /bin/rm -f ikev2.sh ) || /bin/rm -f ikev2.sh
[ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null [ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null
}
bigecho "Downloading Libreswan..." get_libreswan() {
bigecho "Downloading Libreswan..."
SWAN_VER=4.4 SWAN_VER=4.4
swan_file="libreswan-$SWAN_VER.tar.gz" swan_file="libreswan-$SWAN_VER.tar.gz"
swan_url1="https://github.com/libreswan/libreswan/archive/v$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" swan_url2="https://download.libreswan.org/$swan_file"
( (
set -x set -x
wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2"
) || exit 1 ) || exit 1
/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
tar xzf "$swan_file" && /bin/rm -f "$swan_file" tar xzf "$swan_file" && /bin/rm -f "$swan_file"
}
bigecho "Compiling and installing Libreswan, please wait..." install_libreswan() {
bigecho "Compiling and installing Libreswan, please wait..."
cd "libreswan-$SWAN_VER" || exit 1 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,27 +383,52 @@ 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
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" conf_bk "/etc/sysctl.conf"
cat >> /etc/sysctl.conf <<EOF cat >> /etc/sysctl.conf <<EOF
@ -397,47 +450,26 @@ 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 fi
ipi='iptables -I INPUT' ipi='iptables -I INPUT'
ipf='iptables -I FORWARD' ipf='iptables -I FORWARD'
ipp='iptables -t nat -I POSTROUTING' ipp='iptables -t nat -I POSTROUTING'
res='RELATED,ESTABLISHED' res='RELATED,ESTABLISHED'
nff='nft insert rule inet firewalld' nff='nft insert rule inet firewalld'
nfn='nft insert rule inet nftables_svc' nfn='nft insert rule inet nftables_svc'
if [ "$ipt_flag" = "1" ]; then if [ "$ipt_flag" = "1" ]; then
service fail2ban stop >/dev/null 2>&1 service fail2ban stop >/dev/null 2>&1
if [ "$use_nft" = "1" ]; then if [ "$use_nft" = "1" ]; then
nft list ruleset > "$IPT_FILE.old-$SYS_DT" nft list ruleset > "$IPT_FILE.old-$SYS_DT"
@ -478,18 +510,19 @@ if [ "$ipt_flag" = "1" ]; then
else else
iptables-save >> "$IPT_FILE" 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 else
systemctl enable iptables fail2ban 2>/dev/null systemctl enable iptables fail2ban 2>/dev/null
fi fi
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"
else else
@ -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*
if [ "$use_nft" = "1" ]; then
nft -f "$IPT_FILE" nft -f "$IPT_FILE"
else else
iptables-restore < "$IPT_FILE" iptables-restore < "$IPT_FILE"
fi fi
# Fix xl2tpd if l2tp_ppp is unavailable # Fix xl2tpd if l2tp_ppp is unavailable
if ! modprobe -q l2tp_ppp; then if ! modprobe -q l2tp_ppp; then
sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service sed -i '/^ExecStartPre=\//s/=/=-/' /usr/lib/systemd/system/xl2tpd.service
systemctl daemon-reload systemctl daemon-reload
fi fi
mkdir -p /run/pluto mkdir -p /run/pluto
service fail2ban restart 2>/dev/null service fail2ban restart 2>/dev/null
service ipsec restart 2>/dev/null service ipsec restart 2>/dev/null
service xl2tpd 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,12 +47,23 @@ 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=$(lsb_release -si 2>/dev/null) check_vz() {
os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-') if [ -f /proc/user_beancounters ]; then
[ -z "$os_type" ] && [ -f /etc/os-release ] && os_type=$(. /etc/os-release && printf '%s' "$ID") exiterr "OpenVZ VPS is not supported."
case $os_type in fi
}
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) [Uu]buntu)
os_type=ubuntu os_type=ubuntu
;; ;;
@ -65,28 +76,22 @@ case $os_type in
*) *)
exiterr "This script only supports Ubuntu and Debian." exiterr "This script only supports Ubuntu and Debian."
;; ;;
esac esac
os_ver=$(sed 's/\..*//' /etc/debian_version | tr -dc 'A-Za-z0-9') os_ver=$(sed 's/\..*//' /etc/debian_version | tr -dc 'A-Za-z0-9')
if [ "$os_ver" = "8" ] || [ "$os_ver" = "jessiesid" ]; then if [ "$os_ver" = "8" ] || [ "$os_ver" = "jessiesid" ]; then
exiterr "Debian 8 or Ubuntu < 16.04 is not supported." exiterr "Debian 8 or Ubuntu < 16.04 is not supported."
fi fi
if { [ "$os_ver" = "10" ] || [ "$os_ver" = "11" ]; } && [ ! -e /dev/ppp ]; then 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" exiterr "/dev/ppp is missing. Debian 11 or 10 users, see: https://git.io/vpndebian10"
fi fi
}
if [ -f /proc/user_beancounters ]; then check_iface() {
exiterr "OpenVZ VPS is not supported." 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 [ "$(id -u)" != 0 ]; then if [ -n "$def_state" ] && [ "$def_state" != "down" ]; 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 if ! uname -m | grep -qi -e '^arm' -e '^aarch64'; then
case $def_iface in case $def_iface in
wl*) wl*)
@ -95,127 +100,149 @@ if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then
esac esac
fi fi
NET_IFACE="$def_iface" NET_IFACE="$def_iface"
else else
eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null) eth0_state=$(cat "/sys/class/net/eth0/operstate" 2>/dev/null)
if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then if [ -z "$eth0_state" ] || [ "$eth0_state" = "down" ]; then
exiterr "Could not detect the default network interface." exiterr "Could not detect the default network interface."
fi fi
NET_IFACE=eth0 NET_IFACE=eth0
fi fi
}
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK" check_creds() {
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME" [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD" [ -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 if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
bigecho "VPN credentials not set by user. Generating random PSK and password..." 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_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_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16) VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16)
fi fi
if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then 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." exiterr "All VPN credentials must be specified. Edit the script and re-enter them."
fi fi
if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then 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." exiterr "VPN credentials must not contain non-ASCII characters."
fi fi
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in
*[\\\"\']*) *[\\\"\']*)
exiterr "VPN credentials must not contain these special characters: \\ \" '" exiterr "VPN credentials must not contain these special characters: \\ \" '"
;; ;;
esac esac
}
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \ check_dns() {
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
|| { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then || { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
exiterr "The DNS server specified is invalid." exiterr "The DNS server specified is invalid."
fi fi
}
if [ -x /sbin/iptables ] && ! iptables -nL INPUT >/dev/null 2>&1; then check_iptables() {
if [ -x /sbin/iptables ] && ! iptables -nL INPUT >/dev/null 2>&1; then
exiterr "IPTables check failed. Reboot and re-run this script." exiterr "IPTables check failed. Reboot and re-run this script."
fi fi
}
bigecho "VPN setup in progress... Please be patient." # 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
}
count=0 wait_for_apt() {
apt_lk=/var/lib/apt/lists/lock count=0
pkg_lk=/var/lib/dpkg/lock apt_lk=/var/lib/apt/lists/lock
while fuser "$apt_lk" "$pkg_lk" >/dev/null 2>&1 \ 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 || 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" = "0" ] && echo "## Waiting for apt to be available..."
[ "$count" -ge "100" ] && exiterr "Could not get apt/dpkg lock." [ "$count" -ge "100" ] && exiterr "Could not get apt/dpkg lock."
count=$((count+1)) count=$((count+1))
printf '%s' '.' printf '%s' '.'
sleep 3 sleep 3
done done
}
mkdir -p /opt/src install_setup_pkgs_1() {
cd /opt/src || exit 1 bigecho "Installing packages required for setup..."
export DEBIAN_FRONTEND=noninteractive
bigecho "Installing packages required for setup..." (
export DEBIAN_FRONTEND=noninteractive
(
set -x set -x
apt-get -yqq update apt-get -yqq update
) || exiterr "'apt-get update' failed." ) || exiterr "'apt-get update' failed."
( }
install_setup_pkgs_2() {
(
set -x set -x
apt-get -yqq install wget dnsutils openssl \ apt-get -yqq install wget dnsutils openssl \
iptables iproute2 gawk grep sed net-tools >/dev/null iptables iproute2 gawk grep sed net-tools >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Trying to auto discover IP of this server..." 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."
}
public_ip=${VPN_PUBLIC_IP:-''} install_vpn_pkgs() {
check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short) bigecho "Installing packages required for the VPN..."
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 "Installing packages required for the VPN..."
(
set -x set -x
apt-get -yqq install libnss3-dev libnspr4-dev pkg-config \ apt-get -yqq install libnss3-dev libnspr4-dev pkg-config \
libpam0g-dev libcap-ng-dev libcap-ng-utils libselinux1-dev \ libpam0g-dev libcap-ng-dev libcap-ng-utils libselinux1-dev \
libcurl4-nss-dev flex bison gcc make libnss3-tools \ libcurl4-nss-dev flex bison gcc make libnss3-tools \
libevent-dev libsystemd-dev uuid-runtime ppp xl2tpd >/dev/null libevent-dev libsystemd-dev uuid-runtime ppp xl2tpd >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Installing Fail2Ban to protect SSH..." install_fail2ban() {
bigecho "Installing Fail2Ban to protect SSH..."
( (
set -x set -x
apt-get -yqq install fail2ban >/dev/null apt-get -yqq install fail2ban >/dev/null
) || exiterr2 ) || exiterr2
}
bigecho "Downloading IKEv2 script..." get_ikev2_script() {
bigecho "Downloading IKEv2 script..."
ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh" ikev2_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master/extras/ikev2setup.sh"
( (
set -x set -x
wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url" wget -t 3 -T 30 -q -O ikev2.sh "$ikev2_url"
) || /bin/rm -f ikev2.sh ) || /bin/rm -f ikev2.sh
[ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null [ -s ikev2.sh ] && chmod +x ikev2.sh && ln -s /opt/src/ikev2.sh /usr/bin 2>/dev/null
}
bigecho "Downloading Libreswan..." get_libreswan() {
bigecho "Downloading Libreswan..."
SWAN_VER=4.4 SWAN_VER=4.4
swan_file="libreswan-$SWAN_VER.tar.gz" swan_file="libreswan-$SWAN_VER.tar.gz"
swan_url1="https://github.com/libreswan/libreswan/archive/v$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" swan_url2="https://download.libreswan.org/$swan_file"
( (
set -x set -x
wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2" wget -t 3 -T 30 -q -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -q -O "$swan_file" "$swan_url2"
) || exit 1 ) || exit 1
/bin/rm -rf "/opt/src/libreswan-$SWAN_VER" /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
tar xzf "$swan_file" && /bin/rm -f "$swan_file" tar xzf "$swan_file" && /bin/rm -f "$swan_file"
}
bigecho "Compiling and installing Libreswan, please wait..." install_libreswan() {
bigecho "Compiling and installing Libreswan, please wait..."
cd "libreswan-$SWAN_VER" || exit 1 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,27 +385,28 @@ 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
@ -399,22 +429,23 @@ 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 fi
}
bigecho "Updating IPTables rules..." update_iptables() {
bigecho "Updating IPTables rules..."
IPT_FILE=/etc/iptables.rules IPT_FILE=/etc/iptables.rules
IPT_FILE2=/etc/iptables/rules.v4 IPT_FILE2=/etc/iptables/rules.v4
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 fi
ipi='iptables -I INPUT' ipi='iptables -I INPUT'
ipf='iptables -I FORWARD' ipf='iptables -I FORWARD'
ipp='iptables -t nat -I POSTROUTING' ipp='iptables -t nat -I POSTROUTING'
res='RELATED,ESTABLISHED' res='RELATED,ESTABLISHED'
if [ "$ipt_flag" = "1" ]; then if [ "$ipt_flag" = "1" ]; then
service fail2ban stop >/dev/null 2>&1 service fail2ban stop >/dev/null 2>&1
iptables-save > "$IPT_FILE.old-$SYS_DT" iptables-save > "$IPT_FILE.old-$SYS_DT"
$ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP $ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
@ -440,18 +471,19 @@ if [ "$ipt_flag" = "1" ]; then
conf_bk "$IPT_FILE2" conf_bk "$IPT_FILE2"
/bin/cp -f "$IPT_FILE" "$IPT_FILE2" /bin/cp -f "$IPT_FILE" "$IPT_FILE2"
fi fi
fi fi
}
bigecho "Enabling services on boot..." enable_on_boot() {
bigecho "Enabling services on boot..."
IPT_PST=/etc/init.d/iptables-persistent IPT_PST=/etc/init.d/iptables-persistent
IPT_PST2=/usr/share/netfilter-persistent/plugins.d/15-ip4tables IPT_PST2=/usr/share/netfilter-persistent/plugins.d/15-ip4tables
ipt_load=1 ipt_load=1
if [ -f "$IPT_FILE2" ] && { [ -f "$IPT_PST" ] || [ -f "$IPT_PST2" ]; }; then if [ -f "$IPT_FILE2" ] && { [ -f "$IPT_PST" ] || [ -f "$IPT_PST2" ]; }; then
ipt_load=0 ipt_load=0
fi fi
if [ "$ipt_load" = "1" ]; then if [ "$ipt_load" = "1" ]; then
mkdir -p /etc/network/if-pre-up.d 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
@ -482,14 +514,14 @@ 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
@ -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