Merge pull request #1 from teddysun/master

Update from teddysun
This commit is contained in:
谈天才 2019-09-24 22:40:45 +09:00 committed by GitHub
commit 8ad81c077d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 801 additions and 46 deletions

View File

@ -87,4 +87,4 @@ pptp.sh(Deprecated, DO NOT USE)
- Description: Auto Install PPTP for CentOS 6
- Intro: https://teddysun.com/134.html
Copyright (C) 2013-2018 Teddysun <i@teddysun.com>
Copyright (C) 2013-2019 Teddysun <i@teddysun.com>

View File

@ -2,7 +2,7 @@
#
# Description: Auto test download & I/O speed script
#
# Copyright (C) 2015 - 2018 Teddysun <i@teddysun.com>
# Copyright (C) 2015 - 2019 Teddysun <i@teddysun.com>
#
# Thanks: LookBack <admin@dwhd.org>
#
@ -49,7 +49,7 @@ speed_test_v6() {
speed_v4() {
speed_test_v4 'http://cachefly.cachefly.net/100mb.test' 'CacheFly'
speed_test_v4 'http://speedtest.tokyo.linode.com/100MB-tokyo.bin' 'Linode, Tokyo, JP'
speed_test_v4 'http://speedtest.tokyo2.linode.com/100MB-tokyo2.bin' 'Linode, Tokyo2, JP'
speed_test_v4 'http://speedtest.singapore.linode.com/100MB-singapore.bin' 'Linode, Singapore, SG'
speed_test_v4 'http://speedtest.london.linode.com/100MB-london.bin' 'Linode, London, UK'
speed_test_v4 'http://speedtest.frankfurt.linode.com/100MB-frankfurt.bin' 'Linode, Frankfurt, DE'
@ -66,7 +66,7 @@ speed_v6() {
speed_test_v6 'http://speedtest.dallas.linode.com/100MB-dallas.bin' 'Linode, Dallas, TX'
speed_test_v6 'http://speedtest.newark.linode.com/100MB-newark.bin' 'Linode, Newark, NJ'
speed_test_v6 'http://speedtest.singapore.linode.com/100MB-singapore.bin' 'Linode, Singapore, SG'
speed_test_v6 'http://speedtest.tokyo.linode.com/100MB-tokyo.bin' 'Linode, Tokyo, JP'
speed_test_v6 'http://speedtest.tokyo2.linode.com/100MB-tokyo2.bin' 'Linode, Tokyo2, JP'
speed_test_v6 'http://speedtest.sjc03.softlayer.com/downloads/test100.zip' 'Softlayer, San Jose, CA'
speed_test_v6 'http://speedtest.wdc01.softlayer.com/downloads/test100.zip' 'Softlayer, Washington, WA'
speed_test_v6 'http://speedtest.par01.softlayer.com/downloads/test100.zip' 'Softlayer, Paris, FR'
@ -95,7 +95,7 @@ calc_disk() {
cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo )
freq=$( awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
freq=$( awk -F'[ :]' '/cpu MHz/ {print $4;exit}' /proc/cpuinfo )
tram=$( free -m | awk '/Mem/ {print $2}' )
uram=$( free -m | awk '/Mem/ {print $3}' )
swap=$( free -m | awk '/Swap/ {print $2}' )
@ -106,7 +106,7 @@ opsy=$( get_opsy )
arch=$( uname -m )
lbit=$( getconf LONG_BIT )
kern=$( uname -r )
ipv6=$( wget -qO- -t1 -T2 ipv6.icanhazip.com )
#ipv6=$( wget -qO- -t1 -T2 ipv6.icanhazip.com )
disk_size1=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem|udev|docker' | awk '{print $2}' ))
disk_size2=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem|udev|docker' | awk '{print $3}' ))
disk_total_size=$( calc_disk "${disk_size1[@]}" )
@ -144,7 +144,7 @@ echo -e "Average I/O speed : ${YELLOW}$ioavg MB/s${PLAIN}"
next
printf "%-32s%-24s%-14s\n" "Node Name" "IPv4 address" "Download Speed"
speed_v4 && next
if [[ "$ipv6" != "" ]]; then
printf "%-32s%-24s%-14s\n" "Node Name" "IPv6 address" "Download Speed"
speed_v6 && next
fi
#if [[ "$ipv6" != "" ]]; then
# printf "%-32s%-24s%-14s\n" "Node Name" "IPv6 address" "Download Speed"
# speed_v6 && next
#fi

View File

@ -1,5 +1,5 @@
# Dockerfile for KMS Server
# Copyright (C) 2018 Teddysun <i@teddysun.com>
# Copyright (C) 2018 - 2019 Teddysun <i@teddysun.com>
# Reference URL:
# https://github.com/Wind4/vlmcsd

View File

@ -25,7 +25,7 @@ It can be found at [Docker Hub][3].
## Start a container
```bash
$ docker run -d -p 1688:1688 --name kms teddysun/kms
$ docker run -d -p 1688:1688 --name kms --restart=always teddysun/kms
```
**Note**: The TCP port number `1688` must be opened in firewall.

View File

@ -1,7 +1,7 @@
# Dockerfile for L2TP/IPSec VPN Server
# Copyright (C) 2018 Teddysun <i@teddysun.com>
# Copyright (C) 2018 - 2019 Teddysun <i@teddysun.com>
FROM debian:stretch
FROM debian:buster
LABEL maintainer="Teddysun <i@teddysun.com>"
RUN set -ex \

View File

@ -2,9 +2,9 @@
Docker image to run a L2TP/IPsec VPN Server, with both `L2TP/IPsec PSK` and `IPSec Xauth PSK`.
1. Based on Debian 9 (Stretch) with [libreswan-3.27 (IPsec VPN software)](https://github.com/libreswan/libreswan) and [xl2tpd-1.3.12 (L2TP daemon)](https://github.com/xelerance/xl2tpd).
1. Based on Debian 10 (Buster) with [libreswan-3.29 (IPsec VPN software)](https://packages.debian.org/sid/libreswan) and [xl2tpd-1.3.12 (L2TP daemon)](https://packages.debian.org/sid/xl2tpd).
2. Based on alpine with [libreswan-3.21 (IPsec VPN software)](https://pkgs.alpinelinux.org/package/v3.8/community/x86_64/libreswan) and [xl2tpd-1.3.10 (L2TP daemon)](https://pkgs.alpinelinux.org/package/v3.8/main/x86_64/xl2tpd).
2. Based on Alpine with [libreswan-3.29 (IPsec VPN software)](https://pkgs.alpinelinux.org/package/edge/community/x86_64/libreswan) and [xl2tpd-1.3.14 (L2TP daemon)](https://pkgs.alpinelinux.org/package/edge/main/x86_64/xl2tpd).
Docker images are built for quick deployment in various computing cloud providers.
@ -48,24 +48,40 @@ VPN_DNS2=
```
This will create a default user account for L2TP/IPsec VPN login, which can be used by your **multiple devices**.
The IPSec PSK (pre-shared key) is specified by the `VPN_IPSEC_PSK` environment variable.
The username is specified in `VPN_USER` environment variable.
and password is specified in `VPN_PASSWORD` environment variable.
If your VPS has multiple public IP addresses, maybe public IP need to specified in `VPN_PUBLIC_IP` environment variable.
The IPSec PSK (pre-shared key) is specified by the `VPN_IPSEC_PSK`.
The **default username** is specified in `VPN_USER`.
The **default password** is specified in `VPN_PASSWORD`.
If your VPS has multiple public IP addresses, maybe public IP need to specified in `VPN_PUBLIC_IP`.
If you want to specify a other private network, maybe need to specified in `VPN_L2TP_NET` (default `192.168.18.0/24`).
If you want to specify a other private network, maybe need to specified in `VPN_XAUTH_NET` (default `192.168.20.0/24`).
If you want to specify a `local ip` for `xl2tpd.conf`, maybe need to specified in `VPN_L2TP_LOCAL` (default `192.168.18.1`).
If you want to specify a `ip range` for `xl2tpd.conf`, maybe need to specified in `VPN_L2TP_REMOTE` (default `192.168.18.10-192.168.18.250`).
If you want to specify a `rightaddresspool` for `ipsec.conf`, maybe need to specified in `VPN_XAUTH_REMOTE` (default `192.168.20.10-192.168.20.250`).
If you want to specify a other DNS servers, maybe need to specified in `VPN_DNS1` and `VPN_DNS2` (default `8.8.8.8`, `8.8.4.4`).
There is an example to start a container:
```bash
$ docker run -d --privileged -p 500:500/udp -p 4500:4500/udp --name l2tp --env-file /etc/l2tp.env -v /lib/modules:/lib/modules teddysun/l2tp
$ docker run -d --privileged -p 500:500/udp -p 4500:4500/udp --name l2tp --restart=always --env-file /etc/l2tp.env -v /lib/modules:/lib/modules teddysun/l2tp
```
or start a container with tag **alpine**
```bash
$ docker run -d --privileged -p 500:500/udp -p 4500:4500/udp --name l2tp --env-file /etc/l2tp.env -v /lib/modules:/lib/modules teddysun/l2tp:alpine
$ docker run -d --privileged -p 500:500/udp -p 4500:4500/udp --name l2tp --restart=always --env-file /etc/l2tp.env -v /lib/modules:/lib/modules teddysun/l2tp:alpine
```
**Note**: The UDP port number `500` and `4500` must be opened in firewall.
**Warning**: The UDP port number `500` and `4500` must be opened in firewall.
## Check container details
@ -132,6 +148,12 @@ $ docker exec -it l2tp l2tpctl -d
$ docker exec -it l2tp l2tpctl -m
```
### Print Libreswan & xl2tpd version
```bash
$ docker exec -it l2tp l2tpctl -v
```
### Print help information
```bash

View File

@ -1,7 +1,7 @@
# Dockerfile for L2TP/IPSec VPN Server based alpine
# Copyright (C) 2018 Teddysun <i@teddysun.com>
# Copyright (C) 2018 - 2019 Teddysun <i@teddysun.com>
FROM alpine:latest
FROM alpine:edge
LABEL maintainer="Teddysun <i@teddysun.com>"
RUN apk add -U openssl libreswan xl2tpd ppp-l2tp \

View File

@ -137,8 +137,7 @@ conn xauth-psk
auto=add
leftsubnet=0.0.0.0/0
rightaddresspool=${XAUTH_REMOTE}
modecfgdns1=${DNS1}
modecfgdns2=${DNS2}
modecfgdns=${DNS1},${DNS2}
leftxauthserver=yes
rightxauthclient=yes
leftmodecfgserver=yes
@ -186,14 +185,18 @@ cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "${VPN_IPSEC_PSK}"
EOF
cat > /etc/ppp/chap-secrets <<EOF
if ! grep -qw "${VPN_USER}" /etc/ppp/chap-secrets 2>/dev/null; then
cat > /etc/ppp/chap-secrets <<EOF
${VPN_USER} l2tpd ${VPN_PASSWORD} *
EOF
fi
VPN_PASSWORD_ENC=$(openssl passwd -1 "${VPN_PASSWORD}")
cat > /etc/ipsec.d/passwd <<EOF
if ! grep -qw "${VPN_USER}" /etc/ipsec.d/passwd 2>/dev/null; then
cat > /etc/ipsec.d/passwd <<EOF
${VPN_USER}:${VPN_PASSWORD_ENC}:xauth-psk
EOF
fi
chmod 600 /etc/ipsec.secrets /etc/ppp/chap-secrets /etc/ipsec.d/passwd

View File

@ -99,6 +99,11 @@ mod_user(){
echo "Username ${user}'s password has been changed."
}
get_version(){
ipsec --version
xl2tpd --version
}
action=$1
case ${action} in
-l|--list)
@ -113,14 +118,18 @@ case ${action} in
-m|--mod)
mod_user
;;
-v|--version)
get_version
;;
-h|--help)
echo "Usage: `basename $0` -l,--list List all users"
echo " `basename $0` -a,--add Add a user"
echo " `basename $0` -d,--del Delete a user"
echo " `basename $0` -m,--mod Modify a user password"
echo " `basename $0` -v,--version Print program version"
echo " `basename $0` -h,--help Print this help information"
;;
*)
echo "Usage: `basename $0` [-l,--list|-a,--add|-d,--del|-m,--mod|-h,--help]" && exit
echo "Usage: `basename $0` [-l,--list|-a,--add|-d,--del|-m,--mod|-v,--version|-h,--help]" && exit
;;
esac

View File

@ -185,14 +185,18 @@ cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "${VPN_IPSEC_PSK}"
EOF
cat > /etc/ppp/chap-secrets <<EOF
if ! grep -qw "${VPN_USER}" /etc/ppp/chap-secrets 2>/dev/null; then
cat > /etc/ppp/chap-secrets <<EOF
${VPN_USER} l2tpd ${VPN_PASSWORD} *
EOF
fi
VPN_PASSWORD_ENC=$(openssl passwd -1 "${VPN_PASSWORD}")
cat > /etc/ipsec.d/passwd <<EOF
if ! grep -qw "${VPN_USER}" /etc/ipsec.d/passwd 2>/dev/null; then
cat > /etc/ipsec.d/passwd <<EOF
${VPN_USER}:${VPN_PASSWORD_ENC}:xauth-psk
EOF
fi
chmod 600 /etc/ipsec.secrets /etc/ppp/chap-secrets /etc/ipsec.d/passwd

View File

@ -99,6 +99,11 @@ mod_user(){
echo "Username ${user}'s password has been changed."
}
get_version(){
ipsec --version
xl2tpd --version
}
action=$1
case ${action} in
-l|--list)
@ -113,14 +118,18 @@ case ${action} in
-m|--mod)
mod_user
;;
-v|--version)
get_version
;;
-h|--help)
echo "Usage: `basename $0` -l,--list List all users"
echo " `basename $0` -a,--add Add a user"
echo " `basename $0` -d,--del Delete a user"
echo " `basename $0` -m,--mod Modify a user password"
echo " `basename $0` -v,--version Print program version"
echo " `basename $0` -h,--help Print this help information"
;;
*)
echo "Usage: `basename $0` [-l,--list|-a,--add|-d,--del|-m,--mod|-h,--help]" && exit
echo "Usage: `basename $0` [-l,--list|-a,--add|-d,--del|-m,--mod|-v,--version|-h,--help]" && exit
;;
esac

2
kms.sh
View File

@ -147,7 +147,7 @@ install_main() {
fi
elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
apt-get -y update
apt-get install gcc git make libnss3 curl libcurl3-nss
apt-get install -y gcc git make libnss3 curl libcurl3-nss
if ! wget --no-check-certificate -O /etc/init.d/kms https://raw.githubusercontent.com/teddysun/across/master/kms-debian; then
echo -e "[${red}Error:${plain}] Failed to download KMS Server script."
exit 1

708
wireguard.sh Normal file
View File

@ -0,0 +1,708 @@
#!/usr/bin/env bash
#
# This is a Shell script for configure and start WireGuard VPN server.
#
# Copyright (C) 2019 Teddysun <i@teddysun.com>
#
# Reference URL:
# https://www.wireguard.com
# https://git.zx2c4.com/WireGuard
trap _exit INT QUIT TERM
_red() {
printf '\033[1;31;31m%b\033[0m' "$1"
}
_green() {
printf '\033[1;31;32m%b\033[0m' "$1"
}
_yellow() {
printf '\033[1;31;33m%b\033[0m' "$1"
}
_printargs() {
printf -- "%s" "[$(date)] "
printf -- "%s" "$1"
printf "\n"
}
_info() {
_printargs "$@"
}
_warn() {
printf -- "%s" "[$(date)] "
_yellow "$1"
printf "\n"
}
_error() {
printf -- "%s" "[$(date)] "
_red "$1"
printf "\n"
exit 2
}
_exit() {
printf "\n"
_red "$0 has been terminated."
printf "\n"
exit 1
}
_exists() {
local cmd="$1"
if eval type type > /dev/null 2>&1; then
eval type "$cmd" > /dev/null 2>&1
elif command > /dev/null 2>&1; then
command -v "$cmd" > /dev/null 2>&1
else
which "$cmd" > /dev/null 2>&1
fi
rt="$?"
return ${rt}
}
_ipv4() {
local ipv4="$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )"
[ -z "${ipv4}" ] && ipv4="$( wget -qO- -t1 -T2 ipv4.icanhazip.com )"
[ -z "${ipv4}" ] && ipv4="$( wget -qO- -t1 -T2 ipinfo.io/ip )"
printf -- "%s" "${ipv4}"
}
_ipv6() {
local ipv6=""
ipv6="$(wget -qO- -t1 -T2 ipv6.icanhazip.com)"
printf -- "%s" "${ipv6}"
}
_nic() {
local nic=""
nic="$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)"
printf -- "%s" "${nic}"
}
_port() {
local port="$(shuf -i 1024-20480 -n 1)"
while true
do
if _exists "netstat" && netstat -tunlp | grep -w "${port}" > /dev/null 2>&1; then
port="$(shuf -i 1024-20480 -n 1)"
else
break
fi
done
printf -- "%s" "${port}"
}
_os() {
local os=""
[ -f "/etc/debian_version" ] && source /etc/os-release && os="${ID}" && printf -- "%s" "${os}" && return
[ -f "/etc/fedora-release" ] && os="fedora" && printf -- "%s" "${os}" && return
[ -f "/etc/redhat-release" ] && os="centos" && printf -- "%s" "${os}" && return
}
_os_full() {
[ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
[ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
[ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}
_os_ver() {
local main_ver="$( echo $(_os_full) | grep -oE "[0-9.]+")"
printf -- "%s" "${main_ver%%.*}"
}
_error_detect() {
local cmd="$1"
_info "${cmd}"
eval ${cmd} 1> /dev/null
if [ $? -ne 0 ]; then
_error "Execution command (${cmd}) failed, please check it and try again."
fi
}
_version_gt(){
test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"
}
_is_installed() {
if _exists "wg" && _exists "wg-quick"; then
if [ -s "/lib/modules/$(uname -r)/extra/wireguard.ko" ] || [ -s "/lib/modules/$(uname -r)/extra/wireguard.ko.xz" ] \
|| [ -s "/lib/modules/$(uname -r)/updates/dkms/wireguard.ko" ]; then
return 0
else
return 1
fi
else
return 2
fi
}
_get_latest_ver() {
wireguard_ver="$(wget --no-check-certificate -qO- https://api.github.com/repos/WireGuard/WireGuard/tags | grep 'name' | head -1 | cut -d\" -f4)"
if [ -z "${wireguard_ver}" ]; then
wireguard_ver="$(curl -Lso- https://api.github.com/repos/WireGuard/WireGuard/tags | grep 'name' | head -1 | cut -d\" -f4)"
fi
[ -z "${wireguard_ver}" ] && _error "Failed to get wireguard latest version from github"
}
# Check OS version
check_os() {
_info "Check OS version"
if _exists "virt-what"; then
virt="$(virt-what)"
elif _exists "systemd-detect-virt"; then
virt="$(systemd-detect-virt)"
fi
if [ -n "${virt}" -a "${virt}" = "lxc" ]; then
_error "Virtualization method is LXC, which is not supported."
fi
if [ -n "${virt}" -a "${virt}" = "openvz" ] || [ -d "/proc/vz" ]; then
_error "Virtualization method is OpenVZ, which is not supported."
fi
[ -z "$(_os)" ] && _error "Not supported OS."
case "$(_os)" in
ubuntu)
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 16 ] && _error "Not supported OS, please change to Ubuntu 16+ and try again."
;;
debian)
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 8 ] && _error "Not supported OS, please change to Debian 8+ and try again."
;;
fedora)
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 29 ] && _error "Not supported OS, please change to Fedora 29+ and try again."
;;
centos)
[ -n "$(_os_ver)" -a "$(_os_ver)" -lt 7 ] && _error "Not supported OS, please change to CentOS 7+ and try again."
;;
*)
;; # do nothing
esac
}
# Install from repository
install_wg_1() {
_info "Install wireguard from repository"
case "$(_os)" in
ubuntu)
_error_detect "add-apt-repository ppa:wireguard/wireguard"
_error_detect "apt-get update"
_error_detect "apt-get -y install linux-headers-$(uname -r)"
_error_detect "apt-get -y install qrencode"
_error_detect "apt-get -y install iptables"
_error_detect "apt-get -y install wireguard"
;;
debian)
echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
_error_detect "apt-get update"
_error_detect "apt-get -y install linux-headers-$(uname -r)"
_error_detect "apt-get -y install qrencode"
_error_detect "apt-get -y install iptables"
_error_detect "apt-get -y install wireguard"
;;
fedora)
_error_detect "dnf -y copr enable jdoss/wireguard"
_error_detect "dnf -y install kernel-devel"
_error_detect "dnf -y install kernel-headers"
_error_detect "dnf -y install qrencode"
_error_detect "dnf -y install wireguard-dkms wireguard-tools"
;;
centos)
_error_detect "curl -Lso /etc/yum.repos.d/wireguard.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo"
_error_detect "yum -y install epel-release"
_error_detect "yum -y install kernel-devel"
_error_detect "yum -y install kernel-headers"
_error_detect "yum -y install qrencode"
_error_detect "yum -y install wireguard-dkms wireguard-tools"
;;
*)
;; # do nothing
esac
if ! _is_installed; then
_error "Failed to install wireguard, the kernel is most likely not configured correctly"
fi
}
# Install from source
install_wg_2() {
_info "Install wireguard from source"
case "$(_os)" in
ubuntu|debian)
_error_detect "apt-get update"
[ ! -d "/usr/src/linux-headers-$(uname -r)" ] && _error_detect "apt-get -y install linux-headers-$(uname -r)"
_error_detect "apt-get -y install qrencode"
_error_detect "apt-get -y install iptables"
_error_detect "apt-get -y install bc"
_error_detect "apt-get -y install gcc"
_error_detect "apt-get -y install make"
_error_detect "apt-get -y install libmnl-dev"
;;
fedora)
[ ! -d "/usr/src/kernels/$(uname -r)" ] && _error_detect "dnf -y install kernel-headers" && _error_detect "dnf -y install kernel-devel"
_error_detect "dnf -y install qrencode"
_error_detect "dnf -y install bc"
_error_detect "dnf -y install gcc"
_error_detect "dnf -y install make"
_error_detect "dnf -y install libmnl-devel"
;;
centos)
_error_detect "yum -y install epel-release"
[ ! -d "/usr/src/kernels/$(uname -r)" ] && _error_detect "yum -y install kernel-headers" && _error_detect "yum -y install kernel-devel"
_error_detect "yum -y install qrencode"
_error_detect "yum -y install bc"
_error_detect "yum -y install gcc"
_error_detect "yum -y install make"
_error_detect "yum -y install libmnl-devel"
;;
*)
;; # do nothing
esac
_get_latest_ver
wireguard_name="WireGuard-${wireguard_ver}"
wireguard_url="https://github.com/WireGuard/WireGuard/archive/${wireguard_ver}.tar.gz"
_error_detect "wget --no-check-certificate -qO ${wireguard_name}.tar.gz ${wireguard_url}"
_error_detect "tar zxf ${wireguard_name}.tar.gz"
_error_detect "cd ${wireguard_name}/src"
_error_detect "make tools"
_error_detect "make module"
_error_detect "make install"
_error_detect "cd ${cur_dir} && rm -fr ${wireguard_name}.tar.gz ${wireguard_name}"
if ! _is_installed; then
_error "Failed to install wireguard, the kernel is most likely not configured correctly"
fi
}
# Create server interface
create_server_if() {
SERVER_PRIVATE_KEY="$(wg genkey)"
SERVER_PUBLIC_KEY="$(echo ${SERVER_PRIVATE_KEY} | wg pubkey)"
CLIENT_PRIVATE_KEY="$(wg genkey)"
CLIENT_PUBLIC_KEY="$(echo ${CLIENT_PRIVATE_KEY} | wg pubkey)"
CLIENT_PRE_SHARED_KEY="$( wg genpsk )"
_info "Create server interface: /etc/wireguard/${SERVER_WG_NIC}.conf"
[ ! -d "/etc/wireguard" ] && mkdir -p "/etc/wireguard"
if [ -n "${SERVER_PUB_IPV6}" ]; then
cat > /etc/wireguard/${SERVER_WG_NIC}.conf <<EOF
[Interface]
Address = ${SERVER_WG_IPV4}/24,${SERVER_WG_IPV6}/64
ListenPort = ${SERVER_WG_PORT}
PrivateKey = ${SERVER_PRIVATE_KEY}
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
else
cat > /etc/wireguard/${SERVER_WG_NIC}.conf <<EOF
[Interface]
Address = ${SERVER_WG_IPV4}/24
ListenPort = ${SERVER_WG_PORT}
PrivateKey = ${SERVER_PRIVATE_KEY}
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${CLIENT_WG_IPV4}/32
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
fi
chmod 600 /etc/wireguard/${SERVER_WG_NIC}.conf
}
# Create client interface
create_client_if() {
_info "Create client interface: /etc/wireguard/${SERVER_WG_NIC}_client"
if [ -n "${SERVER_PUB_IPV6}" ]; then
cat > /etc/wireguard/${SERVER_WG_NIC}_client <<EOF
[Interface]
Address = ${CLIENT_WG_IPV4}/24,${CLIENT_WG_IPV6}/64
PrivateKey = ${CLIENT_PRIVATE_KEY}
DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2}
[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${SERVER_PUB_IPV4}:${SERVER_WG_PORT}
AllowedIPs = 0.0.0.0/0,::/0
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
else
cat > /etc/wireguard/${SERVER_WG_NIC}_client <<EOF
[Interface]
Address = ${CLIENT_WG_IPV4}/24
PrivateKey = ${CLIENT_PRIVATE_KEY}
DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2}
[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${SERVER_PUB_IPV4}:${SERVER_WG_PORT}
AllowedIPs = 0.0.0.0/0
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
fi
chmod 600 /etc/wireguard/${SERVER_WG_NIC}_client
}
# Generate a QR Code picture with default client interface
generate_qr() {
_info "Generate a QR Code picture with client interface"
_error_detect "qrencode -s8 -o /etc/wireguard/${SERVER_WG_NIC}_client.png < /etc/wireguard/${SERVER_WG_NIC}_client"
}
# Enable IP forwarding
enable_ip_forward() {
_info "Enable IP forward"
sed -i '/net.ipv4.ip_forward/d' /etc/sysctl.conf
[ -n "${SERVER_PUB_IPV6}" ] && sed -i '/net.ipv6.conf.all.forwarding/d' /etc/sysctl.conf
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[ -n "${SERVER_PUB_IPV6}" ] && echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
sysctl -p >/dev/null 2>&1
}
# Set firewall rules
set_firewall() {
_info "Setting firewall rules"
if _exists "firewall-cmd"; then
if [ "$(firewall-cmd --state | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g")" = "running" ]; then
default_zone="$(firewall-cmd --get-default-zone)"
if [ "$(firewall-cmd --zone=${default_zone} --query-masquerade)" = "no" ]; then
_error_detect "firewall-cmd --zone=${default_zone} --add-masquerade"
fi
if ! firewall-cmd --list-ports | grep -qw "${SERVER_WG_PORT}/udp"; then
_error_detect "firewall-cmd --permanent --zone=${default_zone} --add-port=${SERVER_WG_PORT}/udp"
fi
_error_detect "firewall-cmd --reload"
else
_warn "Firewalld looks like not running, please start it and manually set"
fi
else
if _exists "iptables"; then
iptables -A INPUT -p udp --dport ${SERVER_WG_PORT} -j ACCEPT
iptables -A FORWARD -i ${SERVER_WG_NIC} -j ACCEPT
iptables -t nat -A POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE
iptables-save > /etc/iptables.rules
if [ -d "/etc/network/if-up.d" ]; then
cat > /etc/network/if-up.d/iptables <<EOF
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.rules
EOF
chmod +x /etc/network/if-up.d/iptables
fi
fi
if _exists "ip6tables"; then
ip6tables -A INPUT -p udp --dport ${SERVER_WG_PORT} -j ACCEPT
ip6tables -A FORWARD -i ${SERVER_WG_NIC} -j ACCEPT
ip6tables -t nat -A POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE
ip6tables-save > /etc/ip6tables.rules
if [ -d "/etc/network/if-up.d" ]; then
cat > /etc/network/if-up.d/ip6tables <<EOF
#!/bin/sh
/sbin/ip6tables-restore < /etc/ip6tables.rules
EOF
chmod +x /etc/network/if-up.d/ip6tables
fi
fi
fi
}
# WireGuard installation completed
install_completed() {
_info "Starting WireGuard via wg-quick for ${SERVER_WG_NIC}"
_error_detect "systemctl daemon-reload"
_error_detect "systemctl start wg-quick@${SERVER_WG_NIC}"
_error_detect "systemctl enable wg-quick@${SERVER_WG_NIC}"
_info "WireGuard VPN Server installation completed"
_info "WireGuard VPN default client file is below:"
_info "$(_green "/etc/wireguard/${SERVER_WG_NIC}_client")"
_info "WireGuard VPN default client QR Code is below:"
_info "$(_green "/etc/wireguard/${SERVER_WG_NIC}_client.png")"
_info "Download and scan this QR Code with your phone, enjoy it"
}
add_client() {
if ! _is_installed; then
_red "WireGuard looks like not installed, please installed it try again\n" && exit 1
fi
default_server_if="/etc/wireguard/${SERVER_WG_NIC}.conf"
default_client_if="/etc/wireguard/${SERVER_WG_NIC}_client"
[ ! -s "${default_server_if}" ] && echo "The default server interface ($(_red ${default_server_if})) does not exists" && exit 1
[ ! -s "${default_client_if}" ] && echo "The default client interface ($(_red ${default_client_if})) does not exists" && exit 1
while true
do
read -p "Please enter a client name (for example: wg1):" client
if [ -z "${client}" ]; then
_red "Client name can not be empty\n"
else
new_client_if="/etc/wireguard/${client}_client"
if [ "${client}" = "${SERVER_WG_NIC}" ]; then
echo "The default client ($(_yellow ${client})) already exists. Please re-enter it"
elif [ -s "${new_client_if}" ]; then
echo "The client ($(_yellow ${client})) already exists. Please re-enter it"
else
break
fi
fi
done
# Get information from default interface file
client_files=($(find /etc/wireguard -name "*_client" | sort))
client_ipv4=()
client_ipv6=()
for ((i=0; i<${#client_files[@]}; i++)); do
tmp_ipv4="$(grep -w "Address" ${client_files[$i]} | awk '{print $3}' | cut -d\/ -f1 )"
tmp_ipv6="$(grep -w "Address" ${client_files[$i]} | awk '{print $3}' | awk -F, '{print $2}' | cut -d\/ -f1 )"
client_ipv4=(${client_ipv4[@]} ${tmp_ipv4})
client_ipv6=(${client_ipv6[@]} ${tmp_ipv6})
done
# Sort array
client_ipv4_sorted=($(printf '%s\n' "${client_ipv4[@]}" | sort))
index=$(expr ${#client_ipv4[@]} - 1)
last_ip=$(echo ${client_ipv4_sorted[$index]} | cut -d. -f4)
issue_ip_last=$(expr ${last_ip} + 1)
[ ${issue_ip_last} -gt 254 ] && _red "Too many client, IP addresses might not be enough\n" && exit 1
ipv4_comm=$(echo ${client_ipv4[$index]} | cut -d. -f1-3)
ipv6_comm=$(echo ${client_ipv6[$index]} | awk -F: '{print $1":"$2":"$3":"$4}')
CLIENT_PRIVATE_KEY="$(wg genkey)"
CLIENT_PUBLIC_KEY="$(echo ${CLIENT_PRIVATE_KEY} | wg pubkey)"
SERVER_PUBLIC_KEY="$(grep -w "PublicKey" ${default_client_if} | awk '{print $3}')"
CLIENT_ENDPOINT="$(grep -w "Endpoint" ${default_client_if} | awk '{print $3}')"
CLIENT_PRE_SHARED_KEY="$(grep -w "PresharedKey" ${default_client_if} | awk '{print $3}')"
CLIENT_WG_IPV4="${ipv4_comm}.${issue_ip_last}"
CLIENT_WG_IPV6="${ipv6_comm}:${issue_ip_last}"
# Create a new client interface
if [ -n "${SERVER_PUB_IPV6}" ]; then
cat > ${new_client_if} <<EOF
[Interface]
Address = ${CLIENT_WG_IPV4}/24,${CLIENT_WG_IPV6}/64
PrivateKey = ${CLIENT_PRIVATE_KEY}
DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2}
[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${CLIENT_ENDPOINT}
AllowedIPs = 0.0.0.0/0,::/0
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
# Add a new client to default server interface
cat >> ${default_server_if} <<EOF
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
else
cat > ${new_client_if} <<EOF
[Interface]
Address = ${CLIENT_WG_IPV4}/24
PrivateKey = ${CLIENT_PRIVATE_KEY}
DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2}
[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${CLIENT_ENDPOINT}
AllowedIPs = 0.0.0.0/0
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
cat >> ${default_server_if} <<EOF
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${CLIENT_WG_IPV4}/32
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
EOF
fi
chmod 600 ${new_client_if}
echo "Add a WireGuard client ($(_green ${client})) completed"
systemctl restart wg-quick@${SERVER_WG_NIC}
# Generate a new QR Code picture
qrencode -s8 -o ${new_client_if}.png < ${new_client_if}
echo "Generate a QR Code picture with new client ($(_green ${client})) completed"
echo
echo "WireGuard VPN new client ($(_green ${client})) file is below:"
_green "/etc/wireguard/${client}_client\n"
echo
echo "WireGuard VPN new client ($(_green ${client})) QR Code is below:"
_green "/etc/wireguard/${client}_client.png\n"
echo "Download and scan this QR Code with your phone, enjoy it"
}
remove_client() {
if ! _is_installed; then
_red "WireGuard looks like not installed, please installed it try again\n" && exit 1
fi
default_server_if="/etc/wireguard/${SERVER_WG_NIC}.conf"
[ ! -s "${default_server_if}" ] && echo "The default server interface ($(_red ${default_server_if})) does not exists" && exit 1
while true
do
read -p "Please enter a client name you want to delete it (for example: wg1):" client
if [ -z "${client}" ]; then
_red "Client name can not be empty\n"
else
if [ "${client}" = "${SERVER_WG_NIC}" ]; then
echo "The default client ($(_yellow ${client})) can not be delete"
else
break
fi
fi
done
client_if="/etc/wireguard/${client}_client"
[ ! -s "${client_if}" ] && echo "The client file ($(_red ${client_if})) does not exists" && exit 1
tmp_tag="$(grep -w "Address" ${client_if} | awk '{print $3}' | cut -d\/ -f1 )"
[ -n "${tmp_tag}" ] && sed -i '/'"$tmp_tag"'/,+1d;:a;1,3!{P;$!N;D};N;ba' ${default_server_if}
# Delete client interface file
rm -f ${client_if}
[ -s "/etc/wireguard/${client}_client.png" ] && rm -f /etc/wireguard/${client}_client.png
systemctl restart wg-quick@${SERVER_WG_NIC}
echo "The client name ($(_green ${client})) has been deleted"
}
list_clients() {
if ! _is_installed; then
_red "WireGuard looks like not installed, please installed it try again\n" && exit 1
fi
default_server_if="/etc/wireguard/${SERVER_WG_NIC}.conf"
[ ! -s "${default_server_if}" ] && echo "The default server interface ($(_red ${default_server_if})) does not exists" && exit 1
local line="+-------------------------------------------------------------------------+\n"
local string=%-35s
printf "${line}|${string} |${string} |\n${line}" " Client Interface" " Client's IP"
client_files=($(find /etc/wireguard -name "*_client" | sort))
ips=($(grep -w "AllowedIPs" ${default_server_if} | awk '{print $3}'))
[ ${#client_files[@]} -ne ${#ips[@]} ] && echo "One or more client interface file is missing in /etc/wireguard" && exit 1
for ((i=0; i<${#ips[@]}; i++)); do
tmp_ipv4="$(echo ${ips[$i]} | cut -d\/ -f1)"
for ((j=0; j<${#client_files[@]}; j++)); do
if grep -qw "${tmp_ipv4}" "${client_files[$j]}"; then
printf "|${string} |${string} |\n" " ${client_files[$j]}" " ${ips[$i]}"
break
fi
done
done
printf ${line}
}
check_version() {
_is_installed
rt=$?
if [ ${rt} -eq 0 ]; then
_exists "modinfo" && installed_wg_ver="$(modinfo -F version wireguard)"
[ -n "${installed_wg_ver}" ] && echo "WireGuard version: $(_green ${installed_wg_ver})" && return 0
elif [ ${rt} -eq 1 ]; then
_red "WireGuard kernel module does not exists\n" && return 1
elif [ ${rt} -eq 2 ]; then
_red "WireGuard is not installed\n" && return 2
fi
}
show_help() {
printf "
Usage: $0 [Options]
Options:
-h, --help Print this help text and exit
-r, --repo Install WireGuard from repository
-s, --source Install WireGuard from source
-u, --update Upgrade WireGuard from source
-v, --version Print WireGuard version if installed
-a, --add Add a WireGuard client
-d, --del Delete a WireGuard client
-l, --list List all WireGuard client's IP
"
}
install_from_repo() {
check_os
install_wg_1
create_server_if
create_client_if
generate_qr
enable_ip_forward
set_firewall
install_completed
}
install_from_source() {
check_os
install_wg_2
create_server_if
create_client_if
generate_qr
enable_ip_forward
set_firewall
install_completed
}
update_from_source() {
if check_version; then
_get_latest_ver
echo "WireGuard latest version: $(_green ${wireguard_ver})"
if _version_gt "${wireguard_ver}" "${installed_wg_ver}"; then
echo "Do you want to upgrade WireGuard? (y/n)"
read -p "(Default: n):" update_wg
[ -z "${update_wg}" ] && update_wg="n"
if [ "${update_wg}" = "y" -o "${update_wg}" = "Y" ]; then
install_wg_2
systemctl restart wg-quick@${SERVER_WG_NIC}
echo "Update WireGuard completed"
else
echo "Update WireGuard canceled"
fi
else
echo "No updates needed to update WireGuard"
fi
fi
}
cur_dir="$(pwd)"
[ ${EUID} -ne 0 ] && _error "This script must be run as root"
SERVER_PUB_IPV4="${VPN_SERVER_PUB_IPV4:-$(_ipv4)}"
SERVER_PUB_IPV6="${VPN_SERVER_PUB_IPV6:-$(_ipv6)}"
SERVER_PUB_NIC="${VPN_SERVER_PUB_NIC:-$(_nic)}"
SERVER_WG_NIC="${VPN_SERVER_WG_NIC:-wg0}"
SERVER_WG_IPV4="${VPN_SERVER_WG_IPV4:-10.88.88.1}"
SERVER_WG_IPV6="${VPN_SERVER_WG_IPV6:-fd88:88:88::1}"
SERVER_WG_PORT="${VPN_SERVER_WG_PORT:-$(_port)}"
CLIENT_WG_IPV4="${VPN_CLIENT_WG_IPV4:-10.88.88.2}"
CLIENT_WG_IPV6="${VPN_CLIENT_WG_IPV6:-fd88:88:88::2}"
CLIENT_DNS_1="${VPN_CLIENT_DNS_1:-1.1.1.1}"
CLIENT_DNS_2="${VPN_CLIENT_DNS_2:-8.8.8.8}"
main() {
action="$1"
[ -z "${action}" ] && show_help && exit 0
case "${action}" in
-h|--help)
show_help
;;
-r|--repo)
install_from_repo
;;
-s|--source)
install_from_source
;;
-u|--update)
update_from_source
;;
-v|--version)
check_version
;;
-a|--add)
add_client
;;
-d|--del)
remove_client
;;
-l|--list)
list_clients
;;
*)
show_help
;;
esac
}
main "$@"