WireGuard 服务安装配置指南
1. 系统准备
# 更新镜像并安装WireGuard
apt update && apt install -y wireguard
# 开启IP转发
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
2. 生成密钥对
# 创建配置目录
mkdir -p /etc/wireguard && chmod 0777 /etc/wireguard
cd /etc/wireguard
umask 077
# 生成服务器密钥
wg genkey | tee server_privatekey | wg pubkey > server_publickey
# 生成客户端密钥(可生成多个)
wg genkey | tee client1_privatekey | wg pubkey > client1_publickey
3. 服务端配置
# 创建配置文件(注意替换eth0为实际网卡名)
cat > wg0.conf <<EOF
[Interface]
PrivateKey = $(cat server_privatekey)
Address = 10.0.8.1/24
ListenPort = 50814
DNS = 8.8.8.8
MTU = 1420
# 流量转发规则(eth0需替换)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# 客户端1配置
PublicKey = $(cat client1_publickey)
AllowedIPs = 10.0.8.10/32
EOF
4. 启动服务
# 设置开机自启
systemctl enable wg-quick@wg0
# 启动服务
wg-quick up wg0
# 检查状态
wg show
5. 客户端配置
# 生成客户端配置
cat > client1.conf <<EOF
[Interface]
PrivateKey = $(cat client1_privatekey)
Address = 10.0.8.10/32
DNS = 8.8.8.8
MTU = 1420
[Peer]
PublicKey = $(cat server_publickey)
Endpoint = [服务器公网IP]:50814
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
6. 多客户端配置
在服务端配置中追加新的Peer段:
# 生成新客户端密钥
wg genkey | tee client2_privatekey | wg pubkey > client2_publickey
# 追加到wg0.conf
cat >> wg0.conf <<EOF
[Peer]
# 客户端2配置
PublicKey = $(cat client2_publickey)
AllowedIPs = 10.0.8.11/32
EOF
# 重载配置
wg syncconf wg0 <(wg-quick strip wg0)
7. 客户端使用说明
Windows:
- 安装官方WireGuard客户端
- 导入生成的client1.conf文件
Linux:
# 安装客户端
apt install wireguard
# 使用配置
wg-quick up ./client1.conf
关键注意事项:
- 防火墙需放行UDP 50814端口
eth0需替换为服务器实际公网网卡名- 每个客户端应有独立的IP地址
- MTU值可根据网络情况调整(默认1420)
- 配置文件需妥善保管,PrivateKey不可泄露
常用命令:
- 查看连接状态:
wg show - 临时关闭服务:
wg-quick down wg0 - 查看运行日志:
journalctl -u wg-quick@wg0 -f
8. 其他命令
wg set 命令
# peer 添加客户端公钥 allowed-ips 用于添加互联ip以及网段
wg set wg0 peer [客户端公钥] allowed-ips 10.0.8.11/32
# 移除客户端
sudo wg set wg0 peer [客户端公钥] remove
wg addconf命令
echo '
[Peer]
# 这是新客户端的公钥
PublicKey = [客户端公钥]
# 这是为新客户端分配的IP
AllowedIPs = 10.0.0.11/32
' | sudo tee /new_peer.conf
# 添加配置
sudo wg addconf wg0 new_peer.conf
9. 将当前运行配置保存
# wg0为wireguard接口
wg-quick save wg0
客户端配置脚本
#!/bin/bash
# 设置错误处理:任何命令失败则退出脚本
set -e
# 配置常量
WG_INTERFACE="对应的隧道接口"
SERVER_CONFIG_FILE="/etc/wireguard/$WG_INTERFACE.conf"
SERVER_PUBLIC_KEY_FILE="server_publickey"
SERVER_ENDPOINT="对应的公网地址:50814"
DEFAULT_DNS="8.8.8.8"
DEFAULT_MTU="1420"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 函数:生成随机名称(数字加字母组合并与时间戳挂钩)
generate_random_name() {
local timestamp=$(date +%s) # 获取当前时间戳
local random_chars=$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 6)
echo "${timestamp}${random_chars}"
}
# 函数:打印彩色消息
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_info() {
echo -e "${CYAN}[INFO]${NC} $1"
}
# 函数:验证IP地址格式
validate_ip() {
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
# 函数:检查IP地址是否已被使用
is_ip_used() {
local ip=$1
# 检查wg show输出中是否包含该IP
if wg show "$WG_INTERFACE" 2>/dev/null | grep -q "$ip/32"; then
return 0 # IP已被使用
else
return 1 # IP未被使用
fi
}
# 函数:确认操作
confirm() {
local prompt="$1"
local default="${2:-y}"
if [ "$default" = "y" ]; then
prompt="$prompt [Y/n] "
else
prompt="$prompt [y/N] "
fi
while true; do
read -p "$prompt" answer
answer=${answer:-$default}
case "$answer" in
y|Y|yes|YES)
return 0
;;
n|N|no|NO)
return 1
;;
*)
echo "请输入 y 或 n"
;;
esac
done
}
# 函数:显示服务器网络信息
show_server_network_info() {
echo
print_info "=== 服务器网络信息 ==="
# 获取服务器接口地址
if ip addr show "$WG_INTERFACE" &>/dev/null; then
SERVER_ADDR=$(ip -4 addr show "$WG_INTERFACE" | grep -oP '(?<=inet\s)\d+(\.\d+){3}/\d+')
print_info "服务器接口地址: $SERVER_ADDR"
# 提取网络地址和掩码
NETWORK_ADDR=$(echo "$SERVER_ADDR" | cut -d'/' -f1)
NETWORK_MASK=$(echo "$SERVER_ADDR" | cut -d'/' -f2)
# 计算网络段
IFS=. read -r i1 i2 i3 i4 <<< "$NETWORK_ADDR"
IFS=. read -r m1 m2 m3 m4 <<< $(cidr_to_netmask "$NETWORK_MASK")
NETWORK_SEGMENT=$(printf "%d.%d.%d.%d" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))")
print_info "网络段: $NETWORK_SEGMENT/$NETWORK_MASK"
else
print_warning "无法获取服务器接口信息,$WG_INTERFACE 接口可能未启动"
# 尝试从配置文件获取
if [ -f "$SERVER_CONFIG_FILE" ]; then
SERVER_ADDR=$(grep -E "^Address" "$SERVER_CONFIG_FILE" | head -1 | awk '{print $3}')
if [ -n "$SERVER_ADDR" ]; then
print_info "从配置文件获取的服务器地址: $SERVER_ADDR"
NETWORK_ADDR=$(echo "$SERVER_ADDR" | cut -d'/' -f1)
NETWORK_MASK=$(echo "$SERVER_ADDR" | cut -d'/' -f2)
# 计算网络段
IFS=. read -r i1 i2 i3 i4 <<< "$NETWORK_ADDR"
IFS=. read -r m1 m2 m3 m4 <<< $(cidr_to_netmask "$NETWORK_MASK")
NETWORK_SEGMENT=$(printf "%d.%d.%d.%d" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))")
print_info "网络段: $NETWORK_SEGMENT/$NETWORK_MASK"
fi
fi
fi
# 显示已分配的客户端IP
print_info "已分配的客户端IP地址:"
if wg show "$WG_INTERFACE" &>/dev/null; then
wg show "$WG_INTERFACE" | grep "allowed ips" | awk '{print " - " $3}'
else
print_warning "无法获取已分配IP列表,WireGuard 接口可能未启动"
fi
echo
}
# 函数:将CIDR掩码转换为点分十进制格式
cidr_to_netmask() {
local bits=$1
local mask=$((0xffffffff << (32 - bits) & 0xffffffff))
printf "%d.%d.%d.%d" \
$((mask >> 24)) \
$((mask >> 16 & 0xff)) \
$((mask >> 8 & 0xff)) \
$((mask & 0xff))
}
# 主脚本开始
clear
echo "=== WireGuard 客户端配置生成脚本 ==="
echo
# 检查服务器公钥文件是否存在
if [ ! -f "$SERVER_PUBLIC_KEY_FILE" ]; then
print_error "服务器公钥文件不存在: $SERVER_PUBLIC_KEY_FILE"
exit 1
fi
# 获取客户端名称
while true; do
read -p "请输入客户端名称 (直接回车将使用随机名称): " name
# 如果用户没有输入名称,则生成随机名称
if [ -z "$name" ]; then
name=$(generate_random_name)
print_info "使用随机生成的客户端名称: $name"
break
fi
# 检查名称是否已存在
if [ -d "./$name" ]; then
print_warning "客户端 '$name' 的配置已存在"
if confirm "是否覆盖现有配置?" "n"; then
rm -rf "./$name"
break
else
continue
fi
else
break
fi
done
# 显示服务器网络信息
show_server_network_info
# 获取客户端IP地址
while true; do
read -p "请分配客户端IP地址: " ipaddr
if [ -z "$ipaddr" ]; then
print_error "IP地址不能为空"
continue
fi
if ! validate_ip "$ipaddr"; then
print_error "IP地址格式无效: $ipaddr"
continue
fi
if is_ip_used "$ipaddr"; then
print_error "IP地址已被使用: $ipaddr"
echo "当前已使用的IP地址:"
wg show "$WG_INTERFACE" | grep "allowed ips" | awk '{print " - " $3}'
echo
continue
fi
break
done
# 创建客户端目录
mkdir -p "./$name"
cd "./$name"
# 生成密钥对
print_status "创建客户端公私钥中..."
privatekey="${name}_privatekey"
publickey="${name}_publickey"
wg genkey | tee "$privatekey" | wg pubkey > "$publickey"
# 创建配置文件
print_status "生成客户端配置文件..."
cat > "$name.conf" <<EOF
[Interface]
PrivateKey = $(cat "$privatekey")
Address = $ipaddr/32
DNS = $DEFAULT_DNS
MTU = $DEFAULT_MTU
[Peer]
PublicKey = $(cat ../"$SERVER_PUBLIC_KEY_FILE")
Endpoint = $SERVER_ENDPOINT
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF
print_success "客户端配置创建完成: $(pwd)/$name.conf"
# 显示配置内容预览
if confirm "是否查看配置文件内容?" "y"; then
echo
echo "=== 配置文件内容 ==="
cat "$name.conf"
echo
fi
# 确认是否启用客户端
if confirm "是否立即启用客户端?" "y"; then
print_status "正在启用客户端..."
# 尝试添加对等节点
if sudo wg set "$WG_INTERFACE" peer "$(cat "$publickey")" allowed-ips "$ipaddr/32"; then
print_success "客户端 $name ($ipaddr/32) 已成功启用"
# 保存配置到持久存储
if confirm "是否保存配置到持久存储?" "y"; then
sudo wg-quick save "$WG_INTERFACE"
print_success "配置已保存到持久存储"
fi
else
print_error "启用客户端失败,请检查WireGuard服务状态"
exit 1
fi
else
print_warning "客户端未启用,您可以在需要时手动启用"
echo "启用命令: sudo wg set $WG_INTERFACE peer $(cat "$publickey") allowed-ips $ipaddr/32"
fi
# 显示配置摘要
echo
echo "=== 配置摘要 ==="
echo "客户端名称: $name"
echo "IP 地址: $ipaddr/32"
echo "配置文件: $(pwd)/$name.conf"
echo
print_success "客户端配置流程完成!"