#!/bin/bash
clear
echo "============================================="
echo "    L2TP/IPSec VPN 一键安装脚本（小邹专用）  "
echo "                                             "
echo "    建议 Ubuntu22.04系统 其他版本自行测试    "
echo "============================================="

#================= 自定义账号密码 =================
VPN_USER="135492"
VPN_PASS="qq135492"
VPN_PSK="12345678"
#==================================================

# 优化1：精准识别网卡（兼容多网卡场景）
NIC=$(ip route show default | awk '/default/ {print $5}' | head -1)
[ -z "$NIC" ] && NIC="eth0"

echo -e "\n自动识别网卡：$NIC"
echo -e "VPN 账号：$VPN_USER"
echo -e "VPN 密码：$VPN_PASS"
echo -e "IPSec密钥：$VPN_PSK\n"

# 优化2：等待网络就绪（确保外网连通后再执行后续操作）
echo "[0] 等待网络就绪..."
wait_network() {
  local retry=0
  while ! ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1; do
    retry=$((retry + 1))
    if [ $retry -ge 10 ]; then
      echo "警告：网络连接超时，继续执行但可能影响VPN可用性！"
      break
    fi
    echo "等待网络连接...（$retry/10）"
    sleep 1
  done
}
wait_network

echo "[1] 安装依赖组件..."
if [ -f /etc/redhat-release ]; then
  yum install -y xl2tpd openswan ppp iptables-services >/dev/null 2>&1
else
  apt update -y >/dev/null 2>&1
  apt install -y xl2tpd strongswan ppp iptables iptables-persistent >/dev/null 2>&1
fi

echo "[2] 配置 IPSec 核心参数..."
cat >/etc/ipsec.conf <<EOF
config setup
        protostack=netkey
        nat_traversal=yes
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
        oe=off
        plutoopts="--debug 0"

conn L2TP-PSK
        authby=secret
        pfs=no
        auto=add
        keyingtries=3
        rekey=no
        ikelifetime=8h
        keylife=1h
        type=transport
        left=%defaultroute
        leftprotoport=17/1701
        right=%any
        rightprotoport=17/%any
        dpddelay=30
        dpdtimeout=120
        dpdaction=clear
EOF

cat >/etc/ipsec.secrets <<EOF
%any %any : PSK "$VPN_PSK"
EOF

echo "[3] 配置 XL2TPD 服务..."
cat >/etc/xl2tpd/xl2tpd.conf <<EOF
[global]
ipsec saref = yes
saref refinfo = 30
[lns default]
ip range = 192.168.23.10-192.168.23.254
local ip = 192.168.23.1
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF

cat >/etc/ppp/options.xl2tpd <<EOF
require-mschap-v2
ms-dns 8.8.8.8
ms-dns 1.1.1.1
asyncmap 0
auth
crtscts
lock
hide-password
modem
name l2tpd
proxyarp
nobsdcomp
novj
novjccomp
EOF

echo "[4] 写入账号密码配置..."
cat >/etc/ppp/chap-secrets <<EOF
$VPN_USER l2tpd $VPN_PASS *
EOF

echo "[5] 开启内核IP转发..."
# 优化3：先检查再修改，避免重复写入
grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf || {
  sed -i 's/net.ipv4.ip_forward=0/net.ipv4.ip_forward=1/' /etc/sysctl.conf
  echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
}
grep -q "net.ipv4.ip_no_pmtu_disc=1" /etc/sysctl.conf || {
  echo "net.ipv4.ip_no_pmtu_disc=1" >> /etc/sysctl.conf
}
sysctl -p >/dev/null 2>&1

echo "[6] 配置防火墙转发规则..."
iptables -t nat -F
iptables -t nat -A POSTROUTING -o $NIC -j MASQUERADE
iptables -A FORWARD -p tcp --syn -s 192.168.23.0/24 -j TCPMSS --set-mss 1356
iptables -A FORWARD -s 192.168.23.0/24 -j ACCEPT
iptables -A FORWARD -d 192.168.23.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp --dport 4500 -j ACCEPT

# 关闭冲突防火墙
systemctl stop firewalld >/dev/null 2>&1
systemctl disable firewalld >/dev/null 2>&1
ufw disable >/dev/null 2>&1

# 保存iptables规则（区分系统）
if [ -f /etc/redhat-release ]; then
  service iptables save >/dev/null 2>&1
  systemctl enable iptables >/dev/null 2>&1
else
  netfilter-persistent save >/dev/null 2>&1
fi

echo "[7] 启动并自启服务..."
# 优化4：先停止服务再启动，避免状态异常
if [ -f /etc/redhat-release ]; then
  systemctl stop ipsec xl2tpd >/dev/null 2>&1
  systemctl enable ipsec xl2tpd >/dev/null 2>&1
  systemctl start ipsec xl2tpd >/dev/null 2>&1
else
  systemctl stop strongswan xl2tpd >/dev/null 2>&1
  systemctl enable strongswan xl2tpd >/dev/null 2>&1
  systemctl start strongswan xl2tpd >/dev/null 2>&1
fi

# 优化5：检查服务状态并重试启动（确保服务真正运行）
check_service() {
  local service_name=$1
  local retry=0
  while ! systemctl is-active --quiet $service_name; do
    retry=$((retry + 1))
    if [ $retry -ge 3 ]; then
      echo "警告：$service_name 启动失败！"
      return 1
    fi
    echo "重试启动 $service_name...（$retry/3）"
    systemctl start $service_name >/dev/null 2>&1
    sleep 2
  done
  echo "$service_name 运行正常"
  return 0
}

if [ -f /etc/redhat-release ]; then
  check_service ipsec
  check_service xl2tpd
else
  check_service strongswan
  check_service xl2tpd
fi

# 优化6：替换rc.local为systemd服务（更可靠的开机自启）
# 移除旧的rc.local
rm -f /etc/rc.local >/dev/null 2>&1
rm -f /etc/systemd/system/rc-local.service >/dev/null 2>&1

# 创建专用的VPN自启服务
cat >/etc/systemd/system/vpn-l2tp.service <<EOF
[Unit]
Description=L2TP/IPSec VPN Auto Start
After=network-online.target strongswan.service xl2tpd.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c '\
  # 重新加载内核参数
  sysctl -p >/dev/null 2>&1; \
  # 重新加载防火墙规则
  iptables -t nat -F; \
  iptables -t nat -A POSTROUTING -o $NIC -j MASQUERADE; \
  iptables -A FORWARD -p tcp --syn -s 192.168.23.0/24 -j TCPMSS --set-mss 1356; \
  iptables -A FORWARD -s 192.168.23.0/24 -j ACCEPT; \
  iptables -A FORWARD -d 192.168.23.0/24 -j ACCEPT; \
  iptables -A INPUT -p udp --dport 500 -j ACCEPT; \
  iptables -A INPUT -p udp --dport 4500 -j ACCEPT; \
  # 保存防火墙规则
  if [ -f /etc/redhat-release ]; then \
    service iptables save >/dev/null 2>&1; \
  else \
    netfilter-persistent save >/dev/null 2>&1; \
  fi; \
  # 重启VPN服务
  if [ -f /etc/redhat-release ]; then \
    systemctl restart ipsec xl2tpd >/dev/null 2>&1; \
  else \
    systemctl restart strongswan xl2tpd >/dev/null 2>&1; \
  fi'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

# 启用自启服务
systemctl daemon-reload >/dev/null 2>&1
systemctl enable vpn-l2tp >/dev/null 2>&1

# 优化7：快速获取公网IP（多源重试）
WANIP=$(curl -s --connect-timeout 1 ipv4.icanhazip.com || curl -s --connect-timeout 1 ip.sb || curl -s --connect-timeout 1 myip.ipip.net | awk '{print $2}' | cut -d'=' -f2)
[ -z "$WANIP" ] && WANIP="【服务器公网IP】"

echo ""
echo "============================================="
echo "安装完成！"
echo ""
echo "服务器IP：$WANIP"
echo "VPN 账号：$VPN_USER"
echo "VPN 密码：$VPN_PASS"
echo "IPSec密钥：$VPN_PSK"
echo "协议类型：L2TP/IPSec"
echo "============================================="
echo "优化说明："
echo "1. 开机后等待网络就绪再启动VPN服务"
echo "2. 服务启动后自动检查状态并重试"
echo "3. 使用systemd专用服务替代rc.local，自启更可靠"
echo "4. 缩短防火墙/内核参数加载延迟"
echo "============================================="