這個VPN服務器可以使用ubuntu 16.04(建議)、21.04,優點是快速建置、操作簡單、完全免費,缺點是不像其他廠牌的remote-access VPN(即SSL-VPN)具備豐富功能的policy管理。
我建議使用ubuntu16,是因為測試多個Linux發行版中,目前它最穩定。
雖然ubuntu21也算能用,但是當VPN連線建立完成,用戶端只能連回內網、且不能經由VPN連線出外網,我猜應該是路由的問題、找無預設閘道;關於這個也困擾我很久,或許哪天有空再試再更新(或等高手指點)。
拓樸與環境說明
區網為10.0.0.0 / 24,ubuntu16為VPN服務器並以PPPoE取得浮動實體IP。Internal Resource使用基於思科路由器並啟用HTTP服務,用途是示範VPN用戶端從外網連回內網並存取任意服務。
接著是利用ubuntu16建置VPN服務的步驟說明。
(1)下載檔案,指令wget https://git.io/vpnsetup -O vpn.sh
或請複製貼上最下面的原始碼。
(2)編輯VPN參數
在我的示範中,我設定預共享密鑰vpn、使用者名稱chin、使用者密碼chin,請參考如下並儲存檔案
YOUR_IPSEC_PSK='vpn'
YOUR_USERNAME='chin'
YOUR_PASSWORD='chin'
(3)啟動VPN服務,指令sudo sh vpn.sh
很快只要幾秒鐘,終端會顯示如下輸出(擷取關鍵部分)
IPsec VPN server is now ready for use!
Connect to your new VPN with these details:
Server IP: 111.253.48.185
IPsec PSK: vpn
Username: chin
Password: chin
建置VPN服務器已完成!接著是用戶端連線,在此我使用iphone示範(機型iphone 7plus、系統14.7.1)。
(1)「設定」>「一般」>「VPN」>「加入VPN設定」,類型IPsec、L2TP皆可。
(1-1)「描述」欄位:有字就好
(1-2)「伺服器」:111.253.48.185
(1-3)「帳號」:chin
(1-4)「密碼」:chin
(1-5)「密鑰」:vpn
(1-6)按「完成」
(2)如先前已建立多個VPN連線,請選擇你現在新增的連線。打開它,你將完成VPN連線的建立,請參考
(3)存取內網資源與經由VPN連線出外網。
(3-1)存取內網資源
使用思科路由器並啟用HTTP當作內部資源的設定命令已在拓樸展示,思科路由器的IP地址是10.0.0.105,並從手機打開瀏覽器輸入這個地址與帳密
(3-2)經由VPN連線出外網
This VPN server, you can use ubuntu16.04(recommendation), 21.04 . The advantage are fast build, operate easy and free, but the disadvantage has not with rule / policy control and so on.
I suggest use ubuntu16, because I tried more Linux distributions, it is the stable version.
I think the problem is for routing, not found default gateway. That is confused me long time, I will update if I troubleshoot. Or some-expert can advise please.
The topology and environment explains
[topology]
The LAN is 10.0.0.0 / 24, ubuntu16 is VPN server and got public IP address by PPPoE.
「Internal Resource」 is HTTP server, it is demo Cisco router based. It application is VPN client(s)'s connection from external network to internal network and to access any service.
(1)To download file, command「wget https://git.io/vpnsetup -O vpn.sh」
Or you can copy and paste the original code in buttom.
(2)To edit VPN arguments.
In my demo, I had setting pre-share key is 「vpn」, username is 「chin」, password is 「chin」. Please refer these info and write file.
YOUR_IPSEC_PSK='vpn'
YOUR_USERNAME='chin'
YOUR_PASSWORD='chin'
(3)To start VPN service, command 「sudo sh vpn.sh」
It is quickly for few seconds. Your terminal will show these output(capture key part)
IPsec VPN server is now ready for use!
Connect to your new VPN with these details:
Server IP: 111.253.48.185
IPsec PSK: vpn
Username: chin
Password: chin
Now, you are finished build VPN server, and then is client(s) connection. I used iphone to demo this lab.(mechine is iphone7 plus, system is 14.7.1) .
(1)「Settings」>「General」>「VPN」>「Add VPN configuration」, types can to select IPsec or L2TP.
(1-1)「Description」field:(any char)
(1-2)「Server」field:111.253.48.185
(1-3)「Account」field:chin
(1-4)「Password」field:chin
(1-5)「Secret」field:vpn
(1-6)To press 「Done」
(2)If you have been multiple VPN configuration previously. please to select now added connection. Open it, you will finish VPN connection, please refer
[Image with VPN icon]
(3)To access internal resource, and to connect to external network by tunnel.
(3-1)To access internal resource
I used Cisco router and enable HTTP as internal resource, its configuration on topology.
The Cisco router IP address is 10.0.0.105, and then to open explorer key-in this address and username/password by mobile.
[image with internal resource]
(3-2)To connect external network by tunnel.
(image, with what is my ip)
===================================original code=================================
chin@ubuntu16:~$ cat vpn.sh
#!/bin/sh
#
# Script for automatic setup of an IPsec VPN server on Ubuntu, Debian,
# CentOS/RHEL, Rocky Linux, AlmaLinux, Amazon Linux 2 and Alpine Linux
# Works on any dedicated server or virtual private server (VPS)
#
# DO NOT RUN THIS SCRIPT ON YOUR PC OR MAC!
#
# The latest version of this script is available at:
# https://github.com/hwdsl2/setup-ipsec-vpn
#
# Copyright (C) 2021 Lin Song <linsongui@gmail.com>
#
# 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!
# =====================================================
# Define your own values for these variables
# - IPsec pre-shared key, VPN username and password
# - All values MUST be placed inside 'single quotes'
# - DO NOT use these special characters within values: \ " '
YOUR_IPSEC_PSK=''
YOUR_USERNAME=''
YOUR_PASSWORD=''
# Important notes: https://git.io/vpnnotes
# Setup VPN clients: https://git.io/vpnclients
# IKEv2 guide: https://git.io/ikev2
# =====================================================
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
exiterr() { echo "Error: $1" >&2; exit 1; }
check_ip() {
IP_REGEX='^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
}
check_root() {
if [ "$(id -u)" != 0 ]; then
exiterr "Script must be run as root. Try 'sudo sh $0'"
fi
}
check_vz() {
if [ -f /proc/user_beancounters ]; then
exiterr "OpenVZ VPS is not supported."
fi
}
check_lxc() {
# shellcheck disable=SC2154
if [ "$container" = "lxc" ] && [ ! -e /dev/ppp ]; then
cat 1>&2 <<'EOF'
Error: /dev/ppp is missing. LXC containers require configuration.
See: https://github.com/hwdsl2/setup-ipsec-vpn/issues/1014
EOF
exit 1
fi
}
check_os() {
os_type=centos
rh_file="/etc/redhat-release"
if grep -qs "Red Hat" "$rh_file"; then
os_type=rhel
fi
if grep -qs "release 7" "$rh_file"; then
os_ver=7
elif grep -qs "release 8" "$rh_file"; then
os_ver=8
grep -qi stream "$rh_file" && os_ver=8s
grep -qi rocky "$rh_file" && os_type=rocky
grep -qi alma "$rh_file" && os_type=alma
elif grep -qs "Amazon Linux release 2" /etc/system-release; then
os_type=amzn
os_ver=2
else
os_type=$(lsb_release -si 2>/dev/null)
[ -z "$os_type" ] && [ -f /etc/os-release ] && os_type=$(. /etc/os-release && printf '%s' "$ID")
case $os_type in
[Uu]buntu)
os_type=ubuntu
;;
[Dd]ebian)
os_type=debian
;;
[Rr]aspbian)
os_type=raspbian
;;
[Aa]lpine)
os_type=alpine
;;
*)
cat 1>&2 <<'EOF'
Error: This script only supports one of the following OS:
Ubuntu, Debian, CentOS/RHEL 7/8, Rocky Linux, AlmaLinux,
Amazon Linux 2 or Alpine Linux
EOF
exit 1
;;
esac
if [ "$os_type" = "alpine" ]; then
os_ver=$(. /etc/os-release && printf '%s' "$VERSION_ID" | cut -d '.' -f 1,2)
if [ "$os_ver" != "3.14" ]; then
exiterr "This script only supports Alpine Linux 3.14."
fi
else
os_ver=$(sed 's/\..*//' /etc/debian_version | tr -dc 'A-Za-z0-9')
if [ "$os_ver" = "8" ] || [ "$os_ver" = "jessiesid" ]; then
exiterr "Debian 8 or Ubuntu < 16.04 is not supported."
fi
fi
fi
}
check_iface() {
def_iface=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$')
if [ "$os_type" != "alpine" ]; then
[ -z "$def_iface" ] && def_iface=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)')
fi
def_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null)
check_wl=0
if [ -n "$def_state" ] && [ "$def_state" != "down" ]; then
if [ "$os_type" = "ubuntu" ] || [ "$os_type" = "debian" ] || [ "$os_type" = "raspbian" ]; then
if ! uname -m | grep -qi -e '^arm' -e '^aarch64'; then
check_wl=1
fi
else
check_wl=1
fi
fi
if [ "$check_wl" = "1" ]; then
case $def_iface in
wl*)
exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!"
;;
esac
fi
}
check_creds() {
[ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
[ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME"
[ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD"
if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
return 0
fi
if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then
exiterr "All VPN credentials must be specified. Edit the script and re-enter them."
fi
if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then
exiterr "VPN credentials must not contain non-ASCII characters."
fi
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in
*[\\\"\']*)
exiterr "VPN credentials must not contain these special characters: \\ \" '"
;;
esac
}
check_dns() {
if { [ -n "$VPN_DNS_SRV1" ] && ! check_ip "$VPN_DNS_SRV1"; } \
|| { [ -n "$VPN_DNS_SRV2" ] && ! check_ip "$VPN_DNS_SRV2"; } then
exiterr "The DNS server specified is invalid."
fi
}
check_iptables() {
if [ "$os_type" = "ubuntu" ] || [ "$os_type" = "debian" ] || [ "$os_type" = "raspbian" ]; then
if [ -x /sbin/iptables ] && ! iptables -nL INPUT >/dev/null 2>&1; then
exiterr "IPTables check failed. Reboot and re-run this script."
fi
fi
}
wait_for_apt() {
count=0
apt_lk=/var/lib/apt/lists/lock
pkg_lk=/var/lib/dpkg/lock
while fuser "$apt_lk" "$pkg_lk" >/dev/null 2>&1 \
|| lsof "$apt_lk" >/dev/null 2>&1 || lsof "$pkg_lk" >/dev/null 2>&1; do
[ "$count" = "0" ] && echo "## Waiting for apt to be available..."
[ "$count" -ge "100" ] && exiterr "Could not get apt/dpkg lock."
count=$((count+1))
printf '%s' '.'
sleep 3
done
}
install_pkgs() {
if ! command -v wget >/dev/null 2>&1; then
if [ "$os_type" = "ubuntu" ] || [ "$os_type" = "debian" ] || [ "$os_type" = "raspbian" ]; then
wait_for_apt
export DEBIAN_FRONTEND=noninteractive
(
set -x
apt-get -yqq update
) || exiterr "'apt-get update' failed."
(
set -x
apt-get -yqq install wget >/dev/null
) || exiterr "'apt-get install wget' failed."
elif [ "$os_type" != "alpine" ]; then
(
set -x
yum -y -q install wget >/dev/null
) || exiterr "'yum install wget' failed."
fi
fi
if [ "$os_type" = "alpine" ]; then
(
set -x
apk add -U -q bash coreutils grep net-tools sed wget
) || exiterr "'apk add' failed."
fi
}
get_setup_url() {
base_url="https://github.com/hwdsl2/setup-ipsec-vpn/raw/master"
sh_file="vpnsetup_ubuntu.sh"
if [ "$os_type" = "centos" ] || [ "$os_type" = "rhel" ] || [ "$os_type" = "rocky" ] || [ "$os_type" = "alma" ]; then
sh_file="vpnsetup_centos.sh"
elif [ "$os_type" = "amzn" ]; then
sh_file="vpnsetup_amzn.sh"
elif [ "$os_type" = "alpine" ]; then
sh_file="vpnsetup_alpine.sh"
fi
setup_url="$base_url/$sh_file"
}
run_setup() {
status=0
if tmpdir=$(mktemp --tmpdir -d vpn.XXXXX 2>/dev/null); then
if ( set -x; wget -t 3 -T 30 -q -O "$tmpdir/vpn.sh" "$setup_url" \
|| curl -fsL "$setup_url" -o "$tmpdir/vpn.sh" 2>/dev/null ); then
VPN_IPSEC_PSK="$VPN_IPSEC_PSK" VPN_USER="$VPN_USER" VPN_PASSWORD="$VPN_PASSWORD" \
VPN_PUBLIC_IP="$VPN_PUBLIC_IP" VPN_L2TP_NET="$VPN_L2TP_NET" \
VPN_L2TP_LOCAL="$VPN_L2TP_LOCAL" VPN_L2TP_POOL="$VPN_L2TP_POOL" \
VPN_XAUTH_NET="$VPN_XAUTH_NET" VPN_XAUTH_POOL="$VPN_XAUTH_POOL" \
VPN_DNS_SRV1="$VPN_DNS_SRV1" VPN_DNS_SRV2="$VPN_DNS_SRV2" \
/bin/bash "$tmpdir/vpn.sh" || status=1
else
status=1
echo "Error: Could not download VPN setup script." >&2
fi
/bin/rm -f "$tmpdir/vpn.sh"
/bin/rmdir "$tmpdir"
else
exiterr "Could not create temporary directory."
fi
}
vpnsetup() {
check_root
check_vz
check_lxc
check_os
check_iface
check_creds
check_dns
check_iptables
install_pkgs
get_setup_url
run_setup
}
## Defer setup until we have the complete script
vpnsetup "$@"
exit "$status"
chin@ubuntu16:~$
===================================original code=================================
留言列表