wieguard脚本

WireGuard 服务端一键安装脚本(Bash 完整版)

#!/bin/bash
# WireGuard 服务端一键安装配置脚本
# 需要以 root 身份运行

set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }

# 检查 root
if [ "$EUID" -ne 0 ]; then
    log_error "请以 root 身份运行此脚本"
fi

# 配置变量
SERVER_PORT=51820              # ⭐ VPN端口
SERVER_INTERFACE_IP="10.0.0.1/24"
CLIENT_IP="10.0.0.2/32"
OUTPUT_DIR="/root/wireguard_client"
WG_CONF="/etc/wireguard/wg0.conf"

# 获取默认网卡(用于 NAT)
DEFAULT_NIC=$(ip route show default | awk '/default/ {print $5}' | head -1)   # ⭐ 出口网卡
[ -z "$DEFAULT_NIC" ] && log_error "无法获取默认网卡名称"

log_info "检测到默认网卡: $DEFAULT_NIC"
log_info "开始安装 WireGuard..."

# 1. 安装 WireGuard 和 iptables
apt update -y
apt install -y wireguard iptables

# 2. 创建输出目录
mkdir -p "$OUTPUT_DIR"
cd /etc/wireguard || log_error "无法进入 /etc/wireguard"
umask 077

# 3. 生成服务端密钥对
log_info "生成服务端密钥..."
wg genkey | tee server_private.key | wg pubkey > server_public.key   # ⭐ 服务端密钥
SERVER_PRIV=$(cat server_private.key)
SERVER_PUB=$(cat server_public.key)

# 4. 生成客户端密钥对
log_info "生成客户端密钥..."
wg genkey | tee client_private.key | wg pubkey > client_public.key   # ⭐ 客户端密钥
CLIENT_PRIV=$(cat client_private.key)
CLIENT_PUB=$(cat client_public.key)

# 5. 创建服务端配置文件
log_info "创建服务端配置文件 $WG_CONF"
cat > "$WG_CONF" <<EOF
[Interface]
Address = $SERVER_INTERFACE_IP
ListenPort = $SERVER_PORT
PrivateKey = $SERVER_PRIV
PostUp = iptables -t nat -A POSTROUTING -o $DEFAULT_NIC -j MASQUERADE   # ⭐ NAT转发
PostDown = iptables -t nat -D POSTROUTING -o $DEFAULT_NIC -j MASQUERADE

[Peer]
PublicKey = $CLIENT_PUB
AllowedIPs = $CLIENT_IP
EOF

# 6. 开启 IP 转发
log_info "开启 IP 转发..."
if ! grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf; then
    echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
fi
sysctl -p   # ⭐ 生效

# 7. 启动 WireGuard 服务
log_info "启动 WireGuard..."
wg-quick up wg0 2>/dev/null || true   # ⭐ 启动VPN
systemctl enable wg-quick@wg0

# 8. 生成客户端配置文件
CLIENT_CONF="$OUTPUT_DIR/client.conf"
log_info "生成客户端配置文件 $CLIENT_CONF"
cat > "$CLIENT_CONF" <<EOF
[Interface]
PrivateKey = $CLIENT_PRIV
Address = ${CLIENT_IP/\/32/\/24}
DNS = 8.8.8.8

[Peer]
PublicKey = $SERVER_PUB
Endpoint = $(curl -s ifconfig.me):$SERVER_PORT   # ⭐ 公网IP
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF

# 9. 复制密钥文件到输出目录
cp client_private.key client_public.key "$OUTPUT_DIR/"
cp server_public.key "$OUTPUT_DIR/"  # 可选,方便客户端手动配置

# 10. 设置权限
chmod 600 "$OUTPUT_DIR"/*.key "$CLIENT_CONF" 2>/dev/null || true

# 11. 输出完成信息
clear
log_info "========================================="
log_info "WireGuard 服务端安装完成!"
log_info "========================================="
echo -e "${GREEN}服务端配置文件:${NC} $WG_CONF"
echo -e "${GREEN}客户端配置文件:${NC} $CLIENT_CONF"
echo -e "${GREEN}客户端私钥:${NC} $OUTPUT_DIR/client_private.key"
echo -e "${GREEN}客户端公钥:${NC} $OUTPUT_DIR/client_public.key"
echo -e "${GREEN}服务端公钥:${NC} $OUTPUT_DIR/server_public.key"
echo ""
log_info "当前 WireGuard 状态:"
wg show
echo ""
log_warn "⚠️  如果是云服务器,请在安全组/防火墙中放行 UDP 端口 $SERVER_PORT (来源: 0.0.0.0/0)"
log_info "客户端连接时,请将 $CLIENT_CONF 导入 WireGuard 客户端"
log_info "========================================="


WireGuard 服务端一键安装脚本(Python 完整版)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# WireGuard 服务端一键安装配置脚本 (Python 实现)
# 需要以 root 身份运行

import os
import subprocess
import sys
import re
import shutil

# ---------- 颜色输出 ----------
class Colors:
    GREEN = '\033[0;32m'
    YELLOW = '\033[1;33m'
    RED = '\033[0;31m'
    NC = '\033[0m'

def log_info(msg):
    print(f"{Colors.GREEN}[INFO]{Colors.NC} {msg}")

def log_warn(msg):
    print(f"{Colors.YELLOW}[WARN]{Colors.NC} {msg}")

def log_error(msg):
    print(f"{Colors.RED}[ERROR]{Colors.NC} {msg}")
    sys.exit(1)

# 检查 root
if os.geteuid() != 0:
    log_error("请以 root 身份运行此脚本")

# ---------- 配置变量 ----------
SERVER_PORT = 51820              # ⭐ VPN端口
SERVER_INTERFACE_IP = "10.0.0.1/24"
CLIENT_IP = "10.0.0.2/32"
OUTPUT_DIR = "/root/wireguard_client"
WG_CONF = "/etc/wireguard/wg0.conf"
CLIENT_CONF = os.path.join(OUTPUT_DIR, "client.conf")

# ---------- 辅助函数 ----------
def run_cmd(cmd, check=True, capture=False):
    """执行命令,可选捕获输出"""
    try:
        if capture:
            result = subprocess.run(cmd, shell=True, capture_output=True, text=True, check=check)
            return result.stdout.strip()
        else:
            subprocess.run(cmd, shell=True, check=check)
            return ""
    except subprocess.CalledProcessError as e:
        log_error(f"命令执行失败: {cmd}\n{e.stderr if capture else ''}")

def get_default_nic():
    """获取默认路由网卡名称"""
    out = run_cmd("ip route show default", capture=True)
    match = re.search(r'dev\s+(\S+)', out)
    if not match:
        log_error("无法获取默认网卡名称")
    return match.group(1)   # ⭐ 获取出口网卡

def file_write(path, content, mode='w'):
    with open(path, mode) as f:
        f.write(content)
    os.chmod(path, 0o600)

def file_read(path):
    with open(path, 'r') as f:
        return f.read().strip()

# ---------- 主流程 ----------
def main():
    log_info("开始安装 WireGuard...")

    # 获取默认网卡
    default_nic = get_default_nic()
    log_info(f"检测到默认网卡: {default_nic}")

    # 1. 安装软件
    log_info("安装 WireGuard 和 iptables...")
    run_cmd("apt update -y")
    run_cmd("apt install -y wireguard iptables")

    # 2. 创建目录并进入
    os.makedirs("/etc/wireguard", exist_ok=True)
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    os.chdir("/etc/wireguard")
    os.umask(0o077)

    # 3. 生成服务端密钥
    log_info("生成服务端密钥...")
    run_cmd("wg genkey | tee server_private.key | wg pubkey > server_public.key")   # ⭐ 服务端密钥
    server_priv = file_read("server_private.key")
    server_pub = file_read("server_public.key")

    # 4. 生成客户端密钥
    log_info("生成客户端密钥...")
    run_cmd("wg genkey | tee client_private.key | wg pubkey > client_public.key")   # ⭐ 客户端密钥
    client_priv = file_read("client_private.key")
    client_pub = file_read("client_public.key")

    # 5. 创建服务端配置文件
    log_info(f"创建服务端配置文件 {WG_CONF}")
    wg_config = f"""[Interface]
Address = {SERVER_INTERFACE_IP}
ListenPort = {SERVER_PORT}
PrivateKey = {server_priv}
PostUp = iptables -t nat -A POSTROUTING -o {default_nic} -j MASQUERADE   # ⭐ NAT转发
PostDown = iptables -t nat -D POSTROUTING -o {default_nic} -j MASQUERADE

[Peer]
PublicKey = {client_pub}
AllowedIPs = {CLIENT_IP}
"""
    file_write(WG_CONF, wg_config)

    # 6. 开启 IP 转发
    log_info("开启 IP 转发...")
    sysctl_conf = "/etc/sysctl.conf"
    with open(sysctl_conf, 'r+') as f:
        content = f.read()
        if "net.ipv4.ip_forward=1" not in content:
            f.write("\nnet.ipv4.ip_forward=1\n")
    run_cmd("sysctl -p")   # ⭐ 生效

    # 7. 启动 WireGuard
    log_info("启动 WireGuard...")
    run_cmd("wg-quick up wg0", check=False)   # ⭐ 启动VPN
    run_cmd("systemctl enable wg-quick@wg0")

    # 8. 生成客户端配置文件
    # 获取服务器公网 IP
    server_public_ip = run_cmd("curl -s ifconfig.me", capture=True)   # ⭐ 获取公网IP
    client_address = CLIENT_IP.replace("/32", "/24")
    client_config = f"""[Interface]
PrivateKey = {client_priv}
Address = {client_address}
DNS = 8.8.8.8

[Peer]
PublicKey = {server_pub}
Endpoint = {server_public_ip}:{SERVER_PORT}
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
"""
    file_write(CLIENT_CONF, client_config)

    # 9. 复制密钥文件到输出目录
    shutil.copy("client_private.key", OUTPUT_DIR)
    shutil.copy("client_public.key", OUTPUT_DIR)
    shutil.copy("server_public.key", OUTPUT_DIR)   # 可选

    # 10. 输出结果
    print("\n" + "="*50)
    log_info("WireGuard 服务端安装完成!")
    print("="*50)
    print(f"{Colors.GREEN}服务端配置文件:{Colors.NC} {WG_CONF}")
    print(f"{Colors.GREEN}客户端配置文件:{Colors.NC} {CLIENT_CONF}")
    print(f"{Colors.GREEN}客户端私钥:{Colors.NC} {OUTPUT_DIR}/client_private.key")
    print(f"{Colors.GREEN}客户端公钥:{Colors.NC} {OUTPUT_DIR}/client_public.key")
    print(f"{Colors.GREEN}服务端公钥:{Colors.NC} {OUTPUT_DIR}/server_public.key")
    print()
    log_info("当前 WireGuard 状态:")
    run_cmd("wg show")
    print()
    log_warn(f"⚠️  1.如果51820端口不通,可修改为443或53或其他端口。2.如果是云服务器,请在安全组/防火墙中放行 UDP 端口 {SERVER_PORT} (来源: 0.0.0.0/0)")
    log_info("客户端连接时,请将 client.conf 导入 WireGuard 客户端")
    print("="*50)

if __name__ == "__main__":
    main()
posted @ 2026-04-06 22:03  TestAL4193  阅读(3)  评论(0)    收藏  举报