456 lines
13 KiB
Bash
456 lines
13 KiB
Bash
#!/bin/bash
|
|
|
|
Red="\033[31m" # 红色
|
|
Green="\033[32m" # 绿色
|
|
Yellow="\033[33m" # 黄色
|
|
Blue="\033[34m" # 蓝色
|
|
Nc="\033[0m" # 重置颜色
|
|
Red_globa="\033[41;37m" # 红底白字
|
|
Green_globa="\033[42;37m" # 绿底白字
|
|
Yellow_globa="\033[43;37m" # 黄底白字
|
|
Blue_globa="\033[44;37m" # 蓝底白字
|
|
Info="${Green}[信息]${Nc}"
|
|
Error="${Red}[错误]${Nc}"
|
|
Tip="${Yellow}[提示]${Nc}"
|
|
|
|
# 检查是否为root用户
|
|
check_root(){
|
|
if [ -d "/proc/vz" ]; then
|
|
echo -e "${Error} 警告: 你的VPS基于OpenVZ,内核可能不支持IPSec。"
|
|
echo -e "${Tip} L2TP安装已取消。"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$(id -u)" != "0" ]; then
|
|
echo -e "${Error} 当前非root用户(或没有root权限),无法继续操作,请更换root用户或使用 ${Green_globa}sudo -i${Nc} 命令获取临时root权限。"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -c "/dev/ppp" ]; then
|
|
echo -e "${Error} 警告: 当前内核不支持PPP,无法安装L2TP。"
|
|
echo -e "${Tip} 当前内核版本: $(uname -r)"
|
|
echo -e "${Tip} 请更换支持PPP的标准Linux内核。"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_release(){
|
|
if [[ -e /etc/os-release ]]; then
|
|
. /etc/os-release
|
|
release=$ID
|
|
elif [[ -e /usr/lib/os-release ]]; then
|
|
. /usr/lib/os-release
|
|
release=$ID
|
|
fi
|
|
os_version=$(echo $VERSION_ID | cut -d. -f1,2)
|
|
|
|
if [[ "${release}" == "ol" ]]; then
|
|
release=oracle
|
|
elif [[ ! "${release}" =~ ^(kali|centos|ubuntu|fedora|debian|almalinux|rocky|alpine)$ ]]; then
|
|
echo -e "${Error} 抱歉,此脚本不支持您的操作系统。"
|
|
echo -e "${Info} 请确保您使用的是以下支持的操作系统之一:"
|
|
echo -e "-${Red} Ubuntu ${Nc}"
|
|
echo -e "-${Red} Debian ${Nc}"
|
|
echo -e "-${Red} CentOS ${Nc}"
|
|
echo -e "-${Red} Fedora ${Nc}"
|
|
echo -e "-${Red} Kali ${Nc}"
|
|
echo -e "-${Red} AlmaLinux ${Nc}"
|
|
echo -e "-${Red} Rocky Linux ${Nc}"
|
|
echo -e "-${Red} Oracle Linux ${Nc}"
|
|
echo -e "-${Red} Alpine Linux ${Nc}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_pmc(){
|
|
check_release
|
|
if [[ "$release" == "debian" || "$release" == "ubuntu" || "$release" == "kali" ]]; then
|
|
updates="apt update -y"
|
|
installs="apt install -y"
|
|
apps=("curl" "xl2tpd" "strongswan" "pptpd" "nftables")
|
|
elif [[ "$release" == "alpine" ]]; then
|
|
updates="apk update -f"
|
|
installs="apk add -f"
|
|
apps=("curl" "xl2tpd" "strongswan" "pptpd" "nftables")
|
|
elif [[ "$release" == "almalinux" || "$release" == "rocky" || "$release" == "oracle" ]]; then
|
|
updates="dnf update -y"
|
|
installs="dnf install -y"
|
|
check_install="dnf list installed"
|
|
apps=("curl" "xl2tpd" "strongswan" "pptpd" "nftables")
|
|
elif [[ "$release" == "centos" ]]; then
|
|
updates="yum update -y"
|
|
installs="yum install -y"
|
|
apps=("curl" "xl2tpd" "strongswan" "pptpd" "nftables")
|
|
elif [[ "$release" == "fedora" ]]; then
|
|
updates="dnf update -y"
|
|
installs="dnf install -y"
|
|
apps=("curl" "xl2tpd" "strongswan" "pptpd" "nftables")
|
|
fi
|
|
}
|
|
|
|
install_base(){
|
|
check_pmc
|
|
cmds=("curl" "xl2tpd" "ipsec" "pptpd" "nft")
|
|
echo -e "${Info} 你的系统是${Red} $release $os_version ${Nc}"
|
|
echo
|
|
|
|
for i in "${!cmds[@]}"; do
|
|
if ! which "${cmds[i]}" &>/dev/null; then
|
|
APPS+=("${apps[i]}")
|
|
fi
|
|
done
|
|
|
|
if [ ${#APPS[@]} -gt 0 ]; then
|
|
echo -e "${Tip} 正在安装依赖:${Green}${APPS[*]}${Nc} 请稍后..."
|
|
$updates &>/dev/null
|
|
$installs "${APPS[@]}" &>/dev/null
|
|
$installs ppp &>/dev/null
|
|
else
|
|
echo -e "${Info} 所有依赖已存在,不需要额外安装。"
|
|
fi
|
|
}
|
|
|
|
rand(){
|
|
local length=${1:-10}
|
|
local chars=({a..z} {A..Z} {0..9})
|
|
local str=""
|
|
|
|
for i in $(seq 1 $length); do
|
|
str+="${chars[$RANDOM%62]}"
|
|
done
|
|
echo "$str"
|
|
}
|
|
|
|
get_public_ip(){
|
|
InFaces=($(ls /sys/class/net | grep -E '^(eth|ens|eno|esp|enp|vif)'))
|
|
IP_API=(
|
|
"api64.ipify.org"
|
|
"4.ipw.cn"
|
|
"ip.sb"
|
|
"checkip.amazonaws.com"
|
|
"icanhazip.com"
|
|
"ipinfo.io/ip"
|
|
)
|
|
|
|
for iface in "${InFaces[@]}"; do
|
|
for ip_api in "${IP_API[@]}"; do
|
|
IPv4=$(curl -s4 --max-time 2 --interface "$iface" "$ip_api")
|
|
|
|
if [[ -n "$IPv4" ]]; then
|
|
inface="$iface"
|
|
break 2
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
install_vpn(){
|
|
get_public_ip
|
|
set_conf
|
|
cat > /etc/ipsec.conf<<EOF
|
|
config setup
|
|
charondebug="ike 2, knl 2, cfg 2"
|
|
uniqueids=no
|
|
|
|
conn %default
|
|
keyexchange=ikev1
|
|
authby=secret
|
|
ike=aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
|
|
esp=aes256-sha1,aes128-sha1,3des-sha1!
|
|
keyingtries=3
|
|
ikelifetime=8h
|
|
lifetime=1h
|
|
dpdaction=clear
|
|
dpddelay=30s
|
|
dpdtimeout=120s
|
|
rekey=no
|
|
forceencaps=yes
|
|
fragmentation=yes
|
|
|
|
conn L2TP-PSK
|
|
left=%any
|
|
leftid=${IPv4}
|
|
leftfirewall=yes
|
|
leftprotoport=17/${l2tpport}
|
|
right=%any
|
|
rightprotoport=17/%any
|
|
type=transport
|
|
auto=add
|
|
also=%default
|
|
|
|
EOF
|
|
cat > /etc/ipsec.secrets<<EOF
|
|
%any %any : PSK "${l2tppsk}"
|
|
|
|
EOF
|
|
cat > /etc/xl2tpd/xl2tpd.conf<<EOF
|
|
[global]
|
|
port = ${l2tpport}
|
|
|
|
[lns default]
|
|
ip range = ${l2tplocip}.11-${l2tplocip}.255
|
|
local ip = ${l2tplocip}.1
|
|
require chap = yes
|
|
refuse pap = yes
|
|
require authentication = yes
|
|
name = l2tpd
|
|
ppp debug = yes
|
|
pppoptfile = /etc/ppp/options.xl2tpd
|
|
length bit = yes
|
|
|
|
EOF
|
|
cat > /etc/ppp/options.xl2tpd<<EOF
|
|
ipcp-accept-local
|
|
ipcp-accept-remote
|
|
require-mschap-v2
|
|
noccp
|
|
auth
|
|
hide-password
|
|
idle 1800
|
|
mtu 1410
|
|
mru 1410
|
|
nodefaultroute
|
|
debug
|
|
proxyarp
|
|
connect-delay 5000
|
|
|
|
EOF
|
|
|
|
cat > /etc/pptpd.conf<<EOF
|
|
option /etc/ppp/pptpd-options
|
|
debug
|
|
localip ${pptplocip}.1
|
|
remoteip ${pptplocip}.11-255
|
|
|
|
EOF
|
|
|
|
cat > /etc/ppp/pptpd-options<<EOF
|
|
name pptpd
|
|
refuse-pap
|
|
refuse-chap
|
|
refuse-mschap
|
|
require-mschap-v2
|
|
require-mppe-128
|
|
proxyarp
|
|
lock
|
|
nobsdcomp
|
|
novj
|
|
novjccomp
|
|
nologfd
|
|
|
|
EOF
|
|
|
|
cat > /etc/ppp/chap-secrets <<EOF
|
|
# Secrets for authentication using CHAP
|
|
# client server secret IP addresses
|
|
${l2tpuser} l2tpd ${l2tppass} ${l2tplocip}.10
|
|
${pptpuser} pptpd ${pptppass} ${pptplocip}.10
|
|
EOF
|
|
|
|
for num in $(seq 11 255); do
|
|
echo "${l2tpuser}${num} l2tpd ${l2tppass}${num} ${l2tplocip}.${num}" >> /etc/ppp/chap-secrets
|
|
done
|
|
for num in $(seq 11 255); do
|
|
echo "${pptpuser}${num} pptpd ${pptppass}${num} ${pptplocip}.${num}" >> /etc/ppp/chap-secrets
|
|
done
|
|
|
|
set_icmp
|
|
set_nftables
|
|
}
|
|
|
|
set_icmp(){
|
|
seticmp1="net.ipv4.ip_forward=1"
|
|
seticmp2="net.ipv4.conf.all.send_redirects=0"
|
|
seticmp3="net.ipv4.conf.default.send_redirects=0"
|
|
seticmp4="net.ipv4.conf.all.accept_redirects=0"
|
|
seticmp5="net.ipv4.conf.default.accept_redirects=0"
|
|
|
|
for seticmp in "$seticmp1" "$seticmp2" "$seticmp3" "$seticmp4" "$seticmp5"; do
|
|
if grep -qE "^\s*${seticmp%=*}\s*=" /etc/sysctl.conf; then
|
|
sed -i "s|^\s*${seticmp%=*}\s*=.*|${seticmp}|g" /etc/sysctl.conf
|
|
else
|
|
echo "$seticmp" >> /etc/sysctl.conf
|
|
fi
|
|
done
|
|
|
|
sysctl -p &> /dev/null
|
|
}
|
|
|
|
set_nftables(){
|
|
[ -f /etc/nftables.conf ] && cp -pf /etc/nftables.conf /etc/nftables.conf.old.`date +%Y%m%d`
|
|
cat > /etc/nftables.conf <<EOF
|
|
#!/usr/sbin/nft -f
|
|
|
|
flush ruleset
|
|
|
|
table inet filter {
|
|
chain input {
|
|
type filter hook input priority 0;
|
|
ct state established,related accept
|
|
ip protocol icmp accept
|
|
iif lo accept
|
|
udp dport {500,4500,${l2tpport},${pptpport}} accept
|
|
accept
|
|
}
|
|
chain forward {
|
|
type filter hook forward priority 0;
|
|
ct state established,related accept
|
|
ip saddr ${l2tplocip}.0/24 accept
|
|
ip saddr ${pptplocip}.0/24 accept
|
|
accept
|
|
}
|
|
chain output {
|
|
type filter hook output priority 0;
|
|
accept
|
|
}
|
|
}
|
|
|
|
table ip nat {
|
|
chain prerouting {
|
|
type nat hook prerouting priority 0;
|
|
accept
|
|
}
|
|
chain postrouting {
|
|
type nat hook postrouting priority 100;
|
|
oif "${inface}" masquerade
|
|
}
|
|
chain output {
|
|
type nat hook output priority 0;
|
|
accept
|
|
}
|
|
}
|
|
EOF
|
|
systemctl daemon-reload
|
|
systemctl enable nftables
|
|
systemctl restart nftables
|
|
}
|
|
|
|
vpn_start(){
|
|
systemctl daemon-reload
|
|
systemctl enable ipsec
|
|
systemctl enable xl2tpd
|
|
systemctl enable pptpd
|
|
|
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
systemctl restart ipsec
|
|
systemctl restart xl2tpd
|
|
systemctl restart pptpd
|
|
}
|
|
|
|
set_conf(){
|
|
echo
|
|
# L2tp
|
|
echo -e "${Tip} 请输入L2tpIP范围:"
|
|
read -p "(默认范围: 10.10.10):" l2tplocip
|
|
[ -z "${l2tplocip}" ] && l2tplocip="10.10.10"
|
|
|
|
echo -e "${Tip} 请输入L2tp端口:"
|
|
read -p "(默认端口: 1701):" l2tpport
|
|
[ -z "${l2tpport}" ] && l2tpport=1701
|
|
|
|
# 端口范围检查
|
|
while ! [[ "$l2tpport" =~ ^[0-9]+$ ]] || [ "$l2tpport" -lt 1000 ] || [ "$l2tpport" -gt 65535 ]; do
|
|
echo -e "${Error} 端口必须为1000-65535之间的数字"
|
|
read -p "请重新输入端口 (1000-65535):" l2tpport
|
|
[ -z "${l2tpport}" ] && l2tpport=1701
|
|
done
|
|
|
|
l2tpuser=$(rand 5)
|
|
echo -e "${Tip} 请输入L2tp用户名:"
|
|
read -p "(默认用户名: ${l2tpuser}):" tmpl2tpuser
|
|
[ -n "${tmpl2tpuser}" ] && l2tpuser="${tmpl2tpuser}"
|
|
|
|
l2tppass=$(rand 7)
|
|
echo -e "${Tip} 请输入 ${l2tpuser} 的密码:"
|
|
read -p "(默认密码: ${l2tppass}):" tmpl2tppass
|
|
[ -n "${tmpl2tppass}" ] && l2tppass="${tmpl2tppass}"
|
|
|
|
l2tppsk=$(rand 20)
|
|
echo -e "${Tip} 请输入L2tp PSK密钥:"
|
|
read -p "(默认PSK: ${l2tppsk}):" tmppsk
|
|
[ -n "${tmppsk}" ] && l2tppsk="${tmppsk}"
|
|
|
|
# Pptp
|
|
echo -e "${Tip} 请输入Pptp IP范围:"
|
|
read -p "(默认范围: 192.168.30):" pptplocip
|
|
[ -z "${pptplocip}" ] && pptplocip="192.168.30"
|
|
|
|
echo -e "${Tip} 请输入Pptp端口:"
|
|
read -p "(默认端口: 1723):" pptpport
|
|
[ -z "${pptpport}" ] && pptpport=1723
|
|
|
|
# 端口范围检查
|
|
while ! [[ "$pptpport" =~ ^[0-9]+$ ]] || [ "$pptpport" -lt 1000 ] || [ "$pptpport" -gt 65535 ]; do
|
|
echo -e "${Error} 端口必须为1000-65535之间的数字"
|
|
read -p "请重新输入端口 (1000-65535):" l2tpport
|
|
[ -z "${pptpport}" ] && pptpport=1723
|
|
done
|
|
|
|
pptpuser=$(rand 5)
|
|
echo -e "${Tip} 请输入Pptp用户名:"
|
|
read -p "(默认用户名: ${pptpuser}):" tmppptpuser
|
|
[ -n "${tmppptpuser}" ] && pptpuser="${tmppptpuser}"
|
|
|
|
pptppass=$(rand 7)
|
|
echo -e "${Tip} 请输入 ${pptpuser} 的密码:"
|
|
read -p "(默认密码: ${pptppass}):" tmppptppass
|
|
[ -n "${tmppptppass}" ] && pptppass="${tmppptppass}"
|
|
|
|
echo
|
|
echo -e "${Info} L2tp服务器本地IP: ${Green}${l2tplocip}.1${Nc}"
|
|
echo -e "${Info} L2tp客户端IP范围: ${Green}${l2tplocip}.11-${l2tplocip}.255${Nc}"
|
|
echo -e "${Info} L2tp端口 : ${Green}${l2tpport}${Nc}"
|
|
echo -e "${Info} L2tp用户名 : ${Green}${l2tpuser}${Nc}"
|
|
echo -e "${Info} L2tp密码 : ${Green}${l2tppass}${Nc}"
|
|
echo -e "${Info} L2tpPSK密钥 : ${Green}${l2tppsk}${Nc}"
|
|
echo
|
|
echo -e "${Info} Pptp服务器本地IP: ${Green}${pptplocip}.1${Nc}"
|
|
echo -e "${Info} Pptp客户端IP范围: ${Green}${pptplocip}.11-${pptplocip}.255${Nc}"
|
|
echo -e "${Info} Pttp端口 : ${Green}${pptpport}${Nc}"
|
|
echo -e "${Info} Pttp用户名 : ${Green}${pptpuser}${Nc}"
|
|
echo -e "${Info} Pttp密码 : ${Green}${pptppass}${Nc}"
|
|
echo
|
|
}
|
|
|
|
finally(){
|
|
echo "请稍候..."
|
|
sleep 3
|
|
vpn_start
|
|
echo
|
|
echo "###############################################################"
|
|
echo "# VPN 安装脚本 #"
|
|
echo "###############################################################"
|
|
echo
|
|
echo -e "${Info} 默认用户名和密码如下:"
|
|
echo
|
|
echo -e "${Info} 服务器IP: ${Green}${IPv4}${Nc}"
|
|
echo
|
|
echo -e "${Info} L2tp端口 : ${Green}${l2tpport}${Nc}"
|
|
echo -e "${Info} L2tp用户名 : ${Green}${l2tpuser}${Nc}"
|
|
echo -e "${Info} L2tp密码 : ${Green}${l2tppass}${Nc}"
|
|
echo -e "${Info} L2tpPSK密钥 : ${Green}${l2tppsk}${Nc}"
|
|
echo
|
|
echo -e "${Info} Pttp端口 : ${Green}${pptpport}${Nc}"
|
|
echo -e "${Info} Pttp用户名 : ${Green}${pptpuser}${Nc}"
|
|
echo -e "${Info} Pttp密码 : ${Green}${pptppass}${Nc}"
|
|
echo
|
|
echo -e "${Info} 完整的用户配置请查看 ${Green}/etc/ppp/chap-secrets${Nc} 文件"
|
|
echo
|
|
}
|
|
|
|
|
|
vpn(){
|
|
clear
|
|
echo
|
|
echo "###############################################################"
|
|
echo "# VPN 安装脚本 #"
|
|
echo "###############################################################"
|
|
echo
|
|
check_root
|
|
install_base
|
|
install_vpn
|
|
finally
|
|
}
|
|
|
|
vpn
|