- WireGuard 是一款简单易用、安全可靠的开源 VPN 协议和软件,旨在提供更快的速度和更简化的配置体验。
- 运行脚本前务必先开核心端口 51820/UDP 端口在防火墙 + 安全组双层开放,否则部署后客户端无法连接;
- 验证端口监听状态是确认部署成功的关键步骤,若端口未监听,需检查容器是否正常启动(通过脚本菜单第 5 项查看状态)。

第一步 创建脚本文件
vim wg.sh
第二部 复制一下代码
#!/bin/bash
set -euo pipefail
# ======================== 核心配置(可自定义)========================
DEPLOY_DIR="/opt/wireguard" # WireGuard部署目录
PUID=1000 # 用户UID(默认1000,可用id命令查看)
PGID=1000 # 用户GID
TZ="Asia/Shanghai" # 时区
SERVER_PORT=51820 # WireGuard监听端口(UDP)
SERVER_URL="auto" # 服务端公网IP(auto自动检测/手动填如1.2.3.4)
INIT_PEERS="pc,phone,laptop" # 初始客户端(仅首次部署生效)
PEER_DNS="auto" # 客户端DNS(auto/8.8.8.8/114.114.114.114)
ALLOWED_IPS="0.0.0.0/0" # 客户端可访问网段
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 重置颜色
# ======================== 核心检测与安装函数 ========================
# 检测WireGuard是否已部署
check_wireguard_installed() {
if [ -f "$DEPLOY_DIR/docker-compose.yml" ] && docker ps -a --format "{{.Names}}" | grep -q "^wireguard$"; then
return 0 # 已部署
else
return 1 # 未部署
fi
}
# 检测并交互式安装Docker/Docker Compose
check_and_install_docker() {
local docker_installed=1
local compose_installed=1
# 检测Docker
if ! command -v docker &> /dev/null; then
echo -e "${YELLOW}未检测到Docker环境${NC}"
read -p "是否自动安装Docker?(y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${BLUE}开始安装Docker...${NC}"
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
echo -e "${GREEN}Docker安装完成${NC}"
else
echo -e "${RED}Docker未安装,脚本退出${NC}"
exit 1
fi
else
echo -e "${GREEN}Docker已安装${NC}"
fi
# 检测Docker Compose
if ! command -v docker-compose &> /dev/null; then
echo -e "${YELLOW}未检测到Docker Compose${NC}"
read -p "是否自动安装Docker Compose?(y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${BLUE}开始安装Docker Compose...${NC}"
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
echo -e "${GREEN}Docker Compose安装完成${NC}"
else
echo -e "${RED}Docker Compose未安装,脚本退出${NC}"
exit 1
fi
else
echo -e "${GREEN}Docker Compose已安装${NC}"
fi
}
# 检测端口占用
check_port_used() {
if lsof -i UDP:"$SERVER_PORT" &> /dev/null && ! docker ps --format "{{.Ports}}" | grep -q "$SERVER_PORT/udp"; then
echo -e "${RED}错误:端口$SERVER_PORT(UDP)已被非WireGuard进程占用!${NC}"
exit 1
fi
}
# ======================== 部署核心函数 ========================
# 首次部署WireGuard
deploy_wireguard() {
echo -e "${BLUE}=== 开始首次部署WireGuard ===${NC}"
# 环境检测与安装(交互式)
check_and_install_docker
check_port_used
# 创建部署目录
mkdir -p "$DEPLOY_DIR"
cd "$DEPLOY_DIR"
# 生成docker-compose.yml
cat > docker-compose.yml << EOF
version: "3.8"
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=$PUID
- PGID=$PGID
- TZ=$TZ
- SERVERURL=$SERVER_URL
- SERVERPORT=$SERVER_PORT
- PEERS=$INIT_PEERS
- PEERDNS=$PEER_DNS
- ALLOWEDIPS=$ALLOWED_IPS
volumes:
- ./config:/config
- /lib/modules:/lib/modules
ports:
- "$SERVER_PORT:$SERVER_PORT/udp"
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped
EOF
# 启动容器
docker-compose up -d
# 验证启动状态
if docker-compose ps | grep -q "Up"; then
echo -e "${GREEN}WireGuard首次部署成功!${NC}"
show_all_peers
else
echo -e "${RED}WireGuard启动失败,日志:${NC}"
docker-compose logs wireguard
exit 1
fi
}
# ======================== 客户端管理函数 ========================
# 展示所有客户端配置(含二维码)
show_all_peers() {
echo -e "\n${BLUE}=== 所有客户端配置信息 ===${NC}"
cd "$DEPLOY_DIR" || exit
# 从容器中获取实际的PEERS列表
local current_peers=$(docker exec wireguard env 2>/dev/null | grep "^PEERS=" | cut -d'=' -f2)
if [ -z "$current_peers" ]; then
echo -e "${YELLOW}暂无客户端配置${NC}"
return
fi
# 遍历展示每个客户端
for peer in ${current_peers//,/ }; do
echo -e "${YELLOW}--- 客户端:$peer ---${NC}"
local conf_path="$DEPLOY_DIR/config/peer_$peer/peer_$peer.conf"
if [ -f "$conf_path" ]; then
echo "配置文件路径:$conf_path"
echo "二维码(手机扫码):"
docker exec -it wireguard /app/show-peer "$peer" 2>/dev/null || echo -e "${RED}该客户端二维码生成失败${NC}"
else
echo -e "${RED}配置文件不存在:$conf_path${NC}"
fi
echo -e "${NC}"
done
}
# 添加新客户端(支持批量,自动去重)
add_new_peer() {
cd "$DEPLOY_DIR" || exit
read -p "请输入新增客户端名称(多个用逗号分隔,如new1,new2):" new_peers
# 空值校验
if [ -z "$new_peers" ]; then
echo -e "${RED}错误:客户端名称不能为空!${NC}"
return
fi
# 获取当前PEERS列表
local current_peers=$(docker exec wireguard env | grep "^PEERS=" | cut -d'=' -f2)
local updated_peers="$current_peers,$new_peers"
# 去重(避免重复添加)
updated_peers=$(echo "$updated_peers" | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//')
# 修改docker-compose.yml
sed -i "s/^ - PEERS=.*/ - PEERS=$updated_peers/" "$DEPLOY_DIR/docker-compose.yml"
# 重建容器(仅更新WireGuard服务,保留数据)
echo -e "${BLUE}正在添加新客户端并重建容器...${NC}"
docker-compose up -d --force-recreate --no-deps wireguard
echo -e "${GREEN}新客户端添加成功!${NC}"
# 展示新增客户端配置
for peer in ${new_peers//,/ }; do
echo -e "${YELLOW}--- 新增客户端:$peer ---${NC}"
docker exec -it wireguard /app/show-peer "$peer" 2>/dev/null || echo -e "${RED}客户端$peer配置生成失败${NC}"
done
}
# 删除客户端配置(支持批量,清理本地文件)
delete_peer() {
cd "$DEPLOY_DIR" || exit
# 展示当前客户端列表
local current_peers=$(docker exec wireguard env 2>/dev/null | grep "^PEERS=" | cut -d'=' -f2)
if [ -z "$current_peers" ]; then
echo -e "${YELLOW}暂无客户端可删除${NC}"
return
fi
echo -e "${BLUE}当前客户端列表:$current_peers${NC}"
read -p "请输入要删除的客户端名称(多个用逗号分隔):" del_peers
# 空值校验
if [ -z "$del_peers" ]; then
echo -e "${RED}错误:客户端名称不能为空!${NC}"
return
fi
# 二次确认
read -p "确认删除客户端[$del_peers]?删除后配置无法恢复 (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}删除操作已取消${NC}"
return
fi
# 过滤要保留的客户端
local keep_peers=""
for peer in ${current_peers//,/ }; do
if ! echo "$del_peers" | tr ',' '\n' | grep -q "^$peer$"; then
keep_peers="$keep_peers,$peer"
fi
done
# 去除开头的逗号
keep_peers=${keep_peers#,}
# 修改docker-compose.yml
sed -i "s/^ - PEERS=.*/ - PEERS=$keep_peers/" "$DEPLOY_DIR/docker-compose.yml"
# 删除本地配置文件
for peer in ${del_peers//,/ }; do
if [ -d "$DEPLOY_DIR/config/peer_$peer" ]; then
rm -rf "$DEPLOY_DIR/config/peer_$peer"
echo -e "${GREEN}已删除客户端$peer的本地配置${NC}"
else
echo -e "${YELLOW}客户端$peer的本地配置不存在${NC}"
fi
done
# 重建容器
echo -e "${BLUE}正在删除客户端并重建容器...${NC}"
docker-compose up -d --force-recreate --no-deps wireguard
echo -e "${GREEN}客户端删除完成,剩余客户端:$keep_peers${NC}"
}
# ======================== 运维函数 ========================
# 精准重启WireGuard容器(保留配置)
restart_wireguard() {
cd "$DEPLOY_DIR" || exit
# 二次确认
read -p "确认重启WireGuard容器?重启期间连接会中断 (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}重启操作已取消${NC}"
return
fi
echo -e "${BLUE}=== 重启WireGuard容器 ===${NC}"
docker-compose restart wireguard
# 验证重启状态
sleep 3
if docker-compose ps | grep -q "Up"; then
echo -e "${GREEN}WireGuard容器重启成功!${NC}"
else
echo -e "${RED}WireGuard重启失败,日志:${NC}"
docker-compose logs wireguard
fi
}
# 查看WireGuard状态(容器+服务)
show_wireguard_status() {
cd "$DEPLOY_DIR" || exit
echo -e "${BLUE}=== WireGuard容器状态 ===${NC}"
docker-compose ps
echo -e "\n${BLUE}=== WireGuard服务状态 ===${NC}"
docker exec -it wireguard wg show 2>/dev/null || echo -e "${RED}WireGuard服务未运行${NC}"
}
# 查看容器日志(实时)
show_wireguard_logs() {
cd "$DEPLOY_DIR" || exit
echo -e "${BLUE}=== WireGuard容器日志(按Ctrl+C退出)===${NC}"
docker-compose logs -f wireguard
}
# 停止WireGuard容器
stop_wireguard() {
cd "$DEPLOY_DIR" || exit
read -p "确认停止WireGuard容器?停止后无法访问VPN (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}停止操作已取消${NC}"
return
fi
echo -e "${BLUE}=== 停止WireGuard容器 ===${NC}"
docker-compose down
echo -e "${GREEN}WireGuard容器已停止${NC}"
}
# ======================== 主菜单 ========================
main_menu() {
clear
echo -e "${BLUE}==================== WireGuard Docker 管理脚本 ====================${NC}"
echo "部署目录:$DEPLOY_DIR"
echo "容器状态:$(if docker ps --format "{{.Names}}" | grep -q "^wireguard$"; then echo -e "${GREEN}运行中${NC}"; else echo -e "${RED}已停止${NC}"; fi)"
echo -e "\n【功能菜单】"
echo "1. 查看所有客户端配置(含二维码)"
echo "2. 添加新客户端(支持批量)"
echo "3. 删除客户端配置(支持批量)"
echo "4. 重启WireGuard容器"
echo "5. 查看WireGuard运行状态"
echo "6. 查看容器实时日志"
echo "7. 停止WireGuard容器"
echo "8. 退出脚本"
read -p "请选择操作(1-8):" option
case $option in
1) show_all_peers ;;
2) add_new_peer ;;
3) delete_peer ;;
4) restart_wireguard ;;
5) show_wireguard_status ;;
6) show_wireguard_logs ;;
7) stop_wireguard ;;
8) echo -e "${GREEN}退出脚本,再见!${NC}"; exit 0 ;;
*) echo -e "${RED}错误:无效选项,请输入1-8之间的数字!${NC}" ;;
esac
# 操作完成后等待回车,返回菜单
read -p "\n操作完成,按回车键返回主菜单..." -n 1 -r
main_menu
}
# ======================== 主流程 ========================
main() {
# 检查root权限
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}错误:请使用root权限运行(sudo ./wireguard-deploy.sh)${NC}"
exit 1
fi
# 判断是否首次部署
if check_wireguard_installed; then
echo -e "${GREEN}检测到WireGuard已部署,进入管理菜单...${NC}"
sleep 1
main_menu
else
echo -e "${YELLOW}未检测到WireGuard部署,准备首次部署${NC}"
read -p "确认开始首次部署?(y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
deploy_wireguard
# 部署完成后进入管理菜单
main_menu
else
echo -e "${YELLOW}部署操作已取消,脚本退出${NC}"
exit 0
fi
fi
}
# 执行主流程
main
第三步 给脚本执行权限
chmod +x wg.sh
第四步 启动脚本
sudo ./wg.sh
客户端下载:
IOS端:官网下载
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END









