# # Copyright (C) 2020-2022 Lin Song # # This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 # Unported License: http://creativecommons.org/licenses/by-sa/3.0/ # # Attribution required: please include my name in any derivative and let me # know how you have improved it! name: vpn test on: push: branches: [master] paths: - '**.sh' - '.github/workflows/main.yml' jobs: shellcheck: runs-on: ubuntu-20.04 if: github.repository_owner == 'hwdsl2' steps: - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # 2.4.0 with: persist-credentials: false - name: Check run: | if [ ! -x /usr/bin/shellcheck ]; then export DEBIAN_FRONTEND=noninteractive sudo apt-get -yqq update sudo apt-get -yqq install shellcheck fi cd "$GITHUB_WORKSPACE" pwd ls -ld vpnsetup.sh export SHELLCHECK_OPTS="-e SC1090,SC1091" shellcheck --version shopt -s globstar ls -ld -- **/*.sh shellcheck **/*.sh check_urls: needs: shellcheck runs-on: ubuntu-20.04 if: github.repository_owner == 'hwdsl2' steps: - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # 2.4.0 with: persist-credentials: false - name: Check run: | cd "$GITHUB_WORKSPACE" mkdir workdir cd workdir set -ex export DEBIAN_FRONTEND=noninteractive sudo apt-get -yqq update sudo apt-get -yqq install wget curl wg="wget -t 3 -T 30 -nv -O" gh="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master" gi="https://git.io" $wg vpnsetup.sh "$gi/vpnsetup" $wg vpnsetup_centos.sh "$gi/vpnsetup-centos" $wg vpnsetup_amzn.sh "$gi/vpnsetup-amzn" $wg vpnsetup_ubuntu.sh "$gi/vpnsetup-ubuntu" $wg vpnsetup_alpine.sh "$gi/vpnsetup-alpine" $wg quickstart.sh "$gi/vpnquickstart" $wg ikev2setup.sh "$gi/ikev2setup" $wg vpnupgrade.sh "$gi/vpnupgrade" $wg vpnupgrade_centos.sh "$gi/vpnupgrade-centos" $wg vpnupgrade_amzn.sh "$gi/vpnupgrade-amzn" $wg vpnupgrade_ubuntu.sh "$gi/vpnupgrade-ubuntu" $wg vpnupgrade_alpine.sh "$gi/vpnupgrade-alpine" $wg vpnuninstall.sh "$gi/vpnuninstall" $wg vpnsetup2.sh "$gh/vpnsetup.sh" $wg vpnsetup_centos2.sh "$gh/vpnsetup_centos.sh" $wg vpnsetup_amzn2.sh "$gh/vpnsetup_amzn.sh" $wg vpnsetup_ubuntu2.sh "$gh/vpnsetup_ubuntu.sh" $wg vpnsetup_alpine2.sh "$gh/vpnsetup_alpine.sh" $wg quickstart2.sh "$gh/extras/quickstart.sh" $wg ikev2setup2.sh "$gh/extras/ikev2setup.sh" $wg vpnupgrade2.sh "$gh/extras/vpnupgrade.sh" $wg vpnupgrade_centos2.sh "$gh/extras/vpnupgrade_centos.sh" $wg vpnupgrade_amzn2.sh "$gh/extras/vpnupgrade_amzn.sh" $wg vpnupgrade_ubuntu2.sh "$gh/extras/vpnupgrade_ubuntu.sh" $wg vpnupgrade_alpine2.sh "$gh/extras/vpnupgrade_alpine.sh" $wg vpnuninstall2.sh "$gh/extras/vpnuninstall.sh" diff vpnsetup.sh ../vpnsetup.sh diff vpnsetup_centos.sh ../vpnsetup_centos.sh diff vpnsetup_amzn.sh ../vpnsetup_amzn.sh diff vpnsetup_ubuntu.sh ../vpnsetup_ubuntu.sh diff vpnsetup_alpine.sh ../vpnsetup_alpine.sh diff quickstart.sh ../extras/quickstart.sh diff ikev2setup.sh ../extras/ikev2setup.sh diff vpnupgrade.sh ../extras/vpnupgrade.sh diff vpnupgrade_centos.sh ../extras/vpnupgrade_centos.sh diff vpnupgrade_amzn.sh ../extras/vpnupgrade_amzn.sh diff vpnupgrade_ubuntu.sh ../extras/vpnupgrade_ubuntu.sh diff vpnupgrade_alpine.sh ../extras/vpnupgrade_alpine.sh diff vpnuninstall.sh ../extras/vpnuninstall.sh diff vpnsetup2.sh ../vpnsetup.sh diff vpnsetup_centos2.sh ../vpnsetup_centos.sh diff vpnsetup_amzn2.sh ../vpnsetup_amzn.sh diff vpnsetup_ubuntu2.sh ../vpnsetup_ubuntu.sh diff vpnsetup_alpine2.sh ../vpnsetup_alpine.sh diff quickstart2.sh ../extras/quickstart.sh diff ikev2setup2.sh ../extras/ikev2setup.sh diff vpnupgrade2.sh ../extras/vpnupgrade.sh diff vpnupgrade_centos2.sh ../extras/vpnupgrade_centos.sh diff vpnupgrade_amzn2.sh ../extras/vpnupgrade_amzn.sh diff vpnupgrade_ubuntu2.sh ../extras/vpnupgrade_ubuntu.sh diff vpnupgrade_alpine2.sh ../extras/vpnupgrade_alpine.sh diff vpnuninstall2.sh ../extras/vpnuninstall.sh url1="https://mirrors.kernel.org/ubuntu/pool/main/n/nss" url2="https://mirrors.kernel.org/ubuntu/pool/universe/n/nss" deb1="libnss3_3.49.1-1ubuntu1.6_amd64.deb" deb2="libnss3-dev_3.49.1-1ubuntu1.6_amd64.deb" deb3="libnss3-tools_3.49.1-1ubuntu1.6_amd64.deb" $wg 1.deb "$url1/$deb1" $wg 2.deb "$url1/$deb2" $wg 3.deb "$url2/$deb3" bl="https://bit.ly" curl -fsSI "$bl/addvpnuser" | grep -q 'add_vpn_user.sh' curl -fsSI "$bl/delvpnuser" | grep -q 'del_vpn_user.sh' curl -fsSI "$bl/updatevpnusers" | grep -q 'update_vpn_users.sh' curl -fsSI "$bl/ikev2onlymode" | grep -q 'ikev2onlymode.sh' test_set_1: needs: [shellcheck, check_urls] runs-on: ubuntu-20.04 if: github.repository_owner == 'hwdsl2' strategy: matrix: os_version: ["centos:8s", "centos:7", "rockylinux:8", "almalinux:8", "amazonlinux:2"] fail-fast: false env: OS_VERSION: ${{ matrix.os_version }} steps: - name: Build run: | mkdir -p "$GITHUB_WORKSPACE/testing/${OS_VERSION//:}" cd "$GITHUB_WORKSPACE/testing/${OS_VERSION//:}" cat > run.sh <<'EOF' #!/bin/bash set -eEx log1=/var/log/secure log2=/var/log/messages trap 'catch $? $LINENO' ERR catch() { echo "Error $1 occurred on line $2." cat -n -- "$0" | tail -n+"$(($2 - 3))" | head -n7 exit 1 } restart_ipsec() { if ! command -v amazon-linux-extras; then systemctl restart ipsec fi echo "Waiting for IPsec to restart." count=0 while ! grep -q "pluto\[$(cat /var/run/pluto/pluto.pid)\]: listening for IKE messages" "$log1"; do [ "$count" -ge "30" ] && { echo "IPsec failed to start."; exit 1; } count=$((count+1)) printf '%s' '.' sleep 0.5 done echo } restart_fail2ban() { rm -f /var/log/fail2ban.log systemctl restart fail2ban echo "Waiting for Fail2ban to restart." count=0 while ! grep -qs -E "Jail '(sshd?|ssh-iptables)' started" /var/log/fail2ban.log; do [ "$count" -ge "30" ] && { echo "Fail2ban failed to start."; exit 1; } count=$((count+1)) printf '%s' '.' sleep 0.5 done echo } yum -y -q update yum -y -q install wget rsyslog systemctl start rsyslog wget -t 3 -T 30 -nv -O vpnsetup.sh https://git.io/vpnsetup sed -i '/curl /a sed -i "/swan_ver_latest=/s/^/#/" "$tmpdir/vpn.sh"' vpnsetup.sh sh vpnsetup.sh systemctl start xl2tpd restart_ipsec restart_fail2ban cat /var/log/fail2ban.log netstat -anpu | grep pluto netstat -anpu | grep xl2tpd iptables -nvL iptables -nvL | grep -q 'ppp+' iptables -nvL | grep -q '192\.168\.43\.0/24' iptables -nvL -t nat iptables -nvL -t nat | grep -q '192\.168\.42\.0/24' iptables -nvL -t nat | grep -q '192\.168\.43\.0/24' grep pluto "$log1" grep xl2tpd "$log2" ipsec status ipsec status | grep -q l2tp-psk ipsec status | grep -q xauth-psk ls -l /usr/bin/ikev2.sh ls -l /opt/src/ikev2.sh wget -t 3 -T 30 -nv -O vpnunst.sh https://git.io/vpnuninstall bash vpnunst.sh <&1 | grep -i "abort" 4 vpnclient2 ANSWERS bash ikev2.sh <&1 | grep -i "abort" 2 vpnclient2 ANSWERS bash ikev2.sh <&1 | grep -i "abort" 5 ANSWERS bash ikev2.sh <&1 | grep -i "invalid" sed -i '/^include /d' /etc/ipsec.conf VPN_CLIENT_NAME=vpnclient1 \ VPN_DNS_NAME=vpn.example.com \ VPN_DNS_SRV1=1.1.1.1 \ VPN_DNS_SRV2=1.0.0.1 \ bash ikev2.sh --auto grep -q 'leftid=@vpn.example.com' /etc/ipsec.d/ikev2.conf grep -q 'modecfgdns="1.1.1.1 1.0.0.1"' /etc/ipsec.d/ikev2.conf ls -ld /etc/ipsec.d/vpnclient1.mobileconfig ls -ld /etc/ipsec.d/vpnclient1.sswan ls -ld /etc/ipsec.d/vpnclient1.p12 grep -q 'vpn.example.com' /etc/ipsec.d/vpnclient1.mobileconfig grep -q 'vpn.example.com' /etc/ipsec.d/vpnclient1.sswan restart_ipsec ipsec status | grep -q ikev2-cp bash ikev2.sh --auto --addclient invalidclient: 2>&1 | grep -i "warning" bash ikev2.sh --addclient invalidclient: 2>&1 | grep -i "invalid" bash ikev2.sh --addclient vpnclient1 2>&1 | grep -i "already exists" bash ikev2.sh --addclient vpnclient2 ls -ld /etc/ipsec.d/vpnclient2.mobileconfig ls -ld /etc/ipsec.d/vpnclient2.sswan ls -ld /etc/ipsec.d/vpnclient2.p12 bash ikev2.sh --exportclient nonexistclient 2>&1 | grep -i "does not exist" rm -f /etc/ipsec.d/vpnclient2* bash ikev2.sh --exportclient vpnclient2 ls -ld /etc/ipsec.d/vpnclient2.mobileconfig ls -ld /etc/ipsec.d/vpnclient2.sswan ls -ld /etc/ipsec.d/vpnclient2.p12 bash ikev2.sh --addclient vpnclient2 --exportclient vpnclient2 2>&1 | grep -i "invalid" bash ikev2.sh --listclients | grep "vpnclient1 \+valid" bash ikev2.sh --listclients | grep "vpnclient2 \+valid" bash ikev2.sh --revokeclient nonexistclient 2>&1 | grep -i "does not exist" bash ikev2.sh --revokeclient vpnclient2 <&1 | grep -i "already been revoked" bash ikev2.sh --exportclient vpnclient2 2>&1 | grep -i "revoked" bash ikev2.sh -h 2>&1 | grep -i "usage:" bash ikev2.sh --invalidoption 2>&1 | grep -i "usage:" bash ikev2.sh --removeikev2 --exportclient vpnclient1 2>&1 | grep -i "invalid" bash ikev2.sh --removeikev2 < Dockerfile else echo "FROM $OS_VERSION" > Dockerfile fi cat >> Dockerfile <<'EOF' ENV container docker WORKDIR /opt/src RUN if command -v amazon-linux-extras; then amazon-linux-extras install -y kernel-ng; fi RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ "$i" = \ systemd-tmpfiles-setup.service ] || rm -f "$i"; done); \ rm -f /lib/systemd/system/multi-user.target.wants/*; \ rm -f /etc/systemd/system/*.wants/*; \ rm -f /lib/systemd/system/local-fs.target.wants/*; \ rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ rm -f /lib/systemd/system/basic.target.wants/*; \ rm -f /lib/systemd/system/anaconda.target.wants/*; COPY ./run.sh /opt/src/run.sh RUN chmod 755 /opt/src/run.sh VOLUME [ "/sys/fs/cgroup" ] CMD ["/sbin/init"] EOF cat Dockerfile cat run.sh docker build -t "${OS_VERSION//:}-test" . - name: Test run: | docker run -d --name "${OS_VERSION//:}-test-1" -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ --privileged "${OS_VERSION//:}-test" sleep 5 docker exec "${OS_VERSION//:}-test-1" /opt/src/run.sh "${OS_VERSION::6}" - name: Clear if: always() run: | rm -rf "$GITHUB_WORKSPACE/testing/${OS_VERSION//:}" docker rm -f "${OS_VERSION//:}-test-1" || true docker rmi "${OS_VERSION//:}-test" || true test_set_2: needs: [shellcheck, check_urls] runs-on: ubuntu-20.04 if: github.repository_owner == 'hwdsl2' strategy: matrix: os_version: ["ubuntu:20.04", "ubuntu:18.04", "debian:11", "debian:10", "debian:9", "alpine:3.14", "alpine:3.15"] fail-fast: false container: image: ${{ matrix.os_version }} options: --cap-add=NET_ADMIN --device=/dev/ppp steps: - name: Test run: | set -ex os_type="" [ -f /etc/os-release ] && os_type=$(. /etc/os-release && printf '%s' "$ID") [ -z "$os_type" ] && exit 1 log1=/var/log/auth.log if [ "$os_type" = "alpine" ]; then log2=/var/log/messages else log2=/var/log/syslog fi restart_ipsec() { if [ "$os_type" = "alpine" ]; then ipsec whack --shutdown || true ipsec pluto --config /etc/ipsec.conf fi echo "Waiting for IPsec to restart." count=0 while ! grep -q "pluto\[$(cat /var/run/pluto/pluto.pid)\]: listening for IKE messages" "$log1"; do [ "$count" -ge "30" ] && { echo "IPsec failed to start."; exit 1; } count=$((count+1)) printf '%s' '.' sleep 0.5 done echo } restart_fail2ban() { rm -f /var/log/fail2ban.log service fail2ban restart echo "Waiting for Fail2ban to restart." count=0 while ! grep -qs -E "Jail '(sshd?|ssh-iptables)' started" /var/log/fail2ban.log; do [ "$count" -ge "30" ] && { echo "Fail2ban failed to start."; exit 1; } count=$((count+1)) printf '%s' '.' sleep 0.5 done echo } mkdir -p /opt/src cd /opt/src echo "# hwdsl2" > run.sh if [ "$os_type" = "alpine" ]; then apk add -U wget rsyslog rsyslogd else export DEBIAN_FRONTEND=noninteractive apt-get -yqq update apt-get -yqq dist-upgrade apt-get -yqq install wget rsyslog service rsyslog start fi wget -t 3 -T 30 -nv -O vpnsetup.sh https://git.io/vpnsetup sed -i '/curl /a sed -i "/swan_ver_latest=/s/^/#/" "$tmpdir/vpn.sh"' vpnsetup.sh sh vpnsetup.sh if [ "$os_type" = "alpine" ]; then ipsec initnss xl2tpd -c /etc/xl2tpd/xl2tpd.conf restart_ipsec else restart_ipsec restart_fail2ban cat /var/log/fail2ban.log fi netstat -anpu | grep pluto netstat -anpu | grep xl2tpd iptables -nvL iptables -nvL | grep -q 'ppp+' iptables -nvL | grep -q '192\.168\.43\.0/24' iptables -nvL -t nat iptables -nvL -t nat | grep -q '192\.168\.42\.0/24' iptables -nvL -t nat | grep -q '192\.168\.43\.0/24' grep pluto "$log1" grep xl2tpd "$log2" ipsec status ipsec status | grep -q l2tp-psk ipsec status | grep -q xauth-psk ls -l /usr/bin/ikev2.sh ls -l /opt/src/ikev2.sh wget -t 3 -T 30 -nv -O vpnunst.sh https://git.io/vpnuninstall bash vpnunst.sh <&1 | grep -i "abort" 4 vpnclient2 ANSWERS bash ikev2.sh <&1 | grep -i "abort" 2 vpnclient2 ANSWERS bash ikev2.sh <&1 | grep -i "abort" 5 ANSWERS bash ikev2.sh <&1 | grep -i "invalid" if [ "$os_type" = "alpine" ]; then apk del uuidgen else apt-get -yqq remove uuid-runtime fi sed -i '/^include /d' /etc/ipsec.conf VPN_CLIENT_NAME=vpnclient1 \ VPN_DNS_NAME=vpn.example.com \ VPN_DNS_SRV1=1.1.1.1 \ VPN_DNS_SRV2=1.0.0.1 \ bash ikev2.sh --auto grep -q 'leftid=@vpn.example.com' /etc/ipsec.d/ikev2.conf grep -q 'modecfgdns="1.1.1.1 1.0.0.1"' /etc/ipsec.d/ikev2.conf ls -ld /etc/ipsec.d/vpnclient1.mobileconfig ls -ld /etc/ipsec.d/vpnclient1.sswan ls -ld /etc/ipsec.d/vpnclient1.p12 grep -q 'vpn.example.com' /etc/ipsec.d/vpnclient1.mobileconfig grep -q 'vpn.example.com' /etc/ipsec.d/vpnclient1.sswan restart_ipsec ipsec status | grep -q ikev2-cp bash ikev2.sh --auto --addclient invalidclient: 2>&1 | grep -i "warning" bash ikev2.sh --addclient invalidclient: 2>&1 | grep -i "invalid" bash ikev2.sh --addclient vpnclient1 2>&1 | grep -i "already exists" bash ikev2.sh --addclient vpnclient2 ls -ld /etc/ipsec.d/vpnclient2.mobileconfig ls -ld /etc/ipsec.d/vpnclient2.sswan ls -ld /etc/ipsec.d/vpnclient2.p12 bash ikev2.sh --exportclient nonexistclient 2>&1 | grep -i "does not exist" rm -f /etc/ipsec.d/vpnclient2* bash ikev2.sh --exportclient vpnclient2 ls -ld /etc/ipsec.d/vpnclient2.mobileconfig ls -ld /etc/ipsec.d/vpnclient2.sswan ls -ld /etc/ipsec.d/vpnclient2.p12 bash ikev2.sh --addclient vpnclient2 --exportclient vpnclient2 2>&1 | grep -i "invalid" bash ikev2.sh --listclients | grep "vpnclient1 \+valid" bash ikev2.sh --listclients | grep "vpnclient2 \+valid" bash ikev2.sh --revokeclient nonexistclient 2>&1 | grep -i "does not exist" bash ikev2.sh --revokeclient vpnclient2 <&1 | grep -i "already been revoked" bash ikev2.sh --exportclient vpnclient2 2>&1 | grep -i "revoked" bash ikev2.sh -h 2>&1 | grep -i "usage:" bash ikev2.sh --invalidoption 2>&1 | grep -i "usage:" bash ikev2.sh --removeikev2 --exportclient vpnclient1 2>&1 | grep -i "invalid" bash ikev2.sh --removeikev2 <