系列文章回顾
这是「开源VPN实战」系列的第五篇(完结篇)。前四篇我们介绍了 Pritunl 的安装部署、安全加固、SSO 集成和多云互联,本篇将深入讲解生产环境的高可用架构和运维最佳实践。
系列文章:
- 第一篇:Pritunl 入门与安装配置
- 第二篇:安全功能详解
- 第三篇:SSO单点登录企业集成
- 第四篇:多云站点到站点互联
- 第五篇:高可用与运维实战(本文)
高可用架构
单机架构(开发/测试)
`
┌─────────────────┐
│ Pritunl 服务器 │
│ + MongoDB │
└─────────────────┘
`
适用场景:开发测试、小型团队(< 50 用户)
双机高可用架构
`
┌─────────────────┐ ┌─────────────────┐
│ Pritunl 主机 1 │ │ Pritunl 主机 2 │
└────────┬────────┘ └────────┬────────┘
│ │
└───────────┬───────────┘
│
┌────────▼────────┐
│ MongoDB 副本集 │
│ (Atlas/自托管) │
└─────────────────┘
`
适用场景:中小企业(50-500 用户)
多机集群架构
`
┌────────┐ ┌────────┐ ┌────────┐
│Pritunl │ │Pritunl │ │Pritunl │
│ 节点 1 │ │ 节点 2 │ │ 节点 3 │
└───┬────┘ └───┬────┘ └───┬────┘
│ │ │
└──────────┼──────────┘
│
┌────────▼────────┐
│ MongoDB 副本集 │
│ (3 节点) │
└─────────────────┘
`
适用场景:大型企业(500+ 用户)
MongoDB 高可用配置
方案 1:MongoDB Atlas(推荐)
MongoDB Atlas 是官方托管服务,提供:
- 自动备份
- 自动故障转移
- 内置监控
- 免费层级可用
配置步骤:
- 注册 MongoDB Atlas
- 创建集群
- 配置网络访问(白名单)
- 创建数据库用户
- 获取连接字符串
Pritunl 配置:
`bash
# 设置 MongoDB URI
sudo pritunl set app.mongodb_uri “mongodb+srv://user:password@cluster.mongodb.net/pritunl?retryWrites=true&w=majority”
# 重启服务
sudo systemctl restart pritunl
`
方案 2:自托管副本集
部署 3 节点副本集
节点 1(Primary):
`bash
# 编辑 /etc/mongod.conf
replication:
replSetName: “pritunl-rs”
net:
bindIp: 0.0.0.0
port: 27017
security:
authorization: enabled
`
节点 2、3(Secondary):
配置相同,但 bindIp 为各自 IP。
初始化副本集
`bash
# 连接到 Primary 节点
mongo –host
# 初始化副本集
rs.initiate({
_id: “pritunl-rs”,
members: [
{ _id: 0, host: “:27017”, priority: 2 },
{ _id: 1, host: “:27017”, priority: 1 },
{ _id: 2, host: “:27017”, priority: 1 }
]
})
`
创建管理员用户
`javascript
use admin;
db.createUser({
user: “admin”,
pwd: “secure_password”,
roles: [{ role: “root”, db: “admin” }]
});
use pritunl;
db.createUser({
user: “pritunl”,
pwd: “secure_password”,
roles: [{ role: “dbOwner”, db: “pritunl” }]
});
`
配置 Pritunl
`bash
# MongoDB URI(副本集)
sudo pritunl set app.mongodb_uri “mongodb://pritunl:password@node1:27017,node2:27017,node3:27017/pritunl?replicaSet=pritunl-rs&authSource=admin”
sudo systemctl restart pritunl
`
Pritunl 集群部署
步骤 1:激活许可证
在第一个节点上:
`bash
# 激活企业许可证(如需要)
sudo pritunl set app.license_key “YOUR_LICENSE_KEY”
`
步骤 2:配置数据库
在每个节点上配置相同的 MongoDB URI:
`bash
# 配置 MongoDB URI
sudo pritunl set app.mongodb_uri “mongodb://…”
# 或通过 Web 界面配置
sudo pritunl setup-key
`
步骤 3:验证集群
- 登录任意节点的 Web 控制台
- 导航到 Hosts 页面
- 所有节点应显示为在线
步骤 4:配置 VPN 服务器
- 创建 VPN 服务器
- 将多个主机附加到服务器
- 启动服务器
故障转移行为:
- 主机故障时自动切换到其他主机
- 故障转移时间约 3-30 秒
- 客户端自动重连
监控与告警
InfluxDB + Grafana 监控
1. 安装 InfluxDB
`bash
# 添加仓库
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo ‘393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key’ | sha256sum -c && cat influxdata-archive_compat.key | gpg –dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo ‘deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main’ | sudo tee /etc/apt/sources.list.d/influxdata.list
# 安装
sudo apt update
sudo apt -y install influxdb
# 启动
sudo systemctl enable influxdb
sudo systemctl start influxdb
`
2. 创建数据库
`bash
# 连接到 InfluxDB
influx
# 创建数据库
CREATE DATABASE pritunl
CREATE RETENTION POLICY “30d” ON “pritunl” DURATION 30d REPLICATION 1 DEFAULT
`
3. 配置 Pritunl
在 Web 控制台设置中:
| 配置项 | 值 |
|---|
|——–|—–|
| Monitoring Mode | InfluxDB |
|---|---|
| InfluxDB URL | http://localhost:8086 |
| InfluxDB Database | pritunl |
4. 安装 Grafana
`bash
# 添加仓库
sudo apt -y install software-properties-common
sudo add-apt-repository “deb https://packages.grafana.com/oss/deb stable main”
wget -q -O – https://packages.grafana.com/gpg.key | sudo apt-key add –
# 安装
sudo apt update
sudo apt -y install grafana
# 启动
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
`
5. 配置 Grafana 数据源
- 访问
http://server-ip:3000 - 默认登录:admin/admin
- 添加 InfluxDB 数据源:
- URL:
http://localhost:8086 - Database:
pritunl
6. 导入仪表板
Pritunl 提供预配置的 Grafana 仪表板 JSON:
`bash
# 下载仪表板
wget https://raw.githubusercontent.com/pritunl/pritunl-monitoring/master/grafana_dashboard.json
`
在 Grafana 中导入此 JSON 文件。
监控指标
关键指标:
vpn_connections:VPN 连接数vpn_traffic_in/out:流量server_cpu/memory:服务器资源mongodb_operations:数据库操作
告警配置
Grafana 告警规则
`json
{
“alert”: {
“name”: “VPN 连接数过高”,
“message”: “当前连接数超过阈值”,
“conditions”: [
{
“evaluator”: {
“params”: [1000],
“type”: “gt”
},
“operator”: {
“type”: “and”
},
“query”: {
“params”: [“A”, “5m”, “now”]
},
“reducer”: {
“params”: [],
“type”: “avg”
}
}
],
“executionErrorState”: “alerting”,
“noDataState”: “no_data”,
“frequency”: “1m”
}
}
`
备份与恢复
MongoDB 备份
Atlas 自动备份
MongoDB Atlas 提供:
- 连续备份
- 时间点恢复
- 跨区域备份
自托管备份脚本
`bash
#!/bin/bash
# backup_mongodb.sh
BACKUP_DIR=”/backup/mongodb”
DATE=$(date +%Y%m%d_%H%M%S)
MONGO_URI=”mongodb://admin:password@localhost:27017/pritunl?authSource=admin”
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 执行备份
mongodump –uri=”${MONGO_URI}” –out=”${BACKUP_DIR}/${DATE}”
# 压缩
tar -czf “${BACKUP_DIR}/${DATE}.tar.gz” -C “${BACKUP_DIR}” “${DATE}”
rm -rf “${BACKUP_DIR}/${DATE}”
# 保留最近 30 天
find “${BACKUP_DIR}” -name “*.tar.gz” -mtime +30 -delete
echo “备份完成: ${BACKUP_DIR}/${DATE}.tar.gz”
`
Cron 定时备份
`bash
# 每天凌晨 2 点备份
0 2 * * * /opt/scripts/backup_mongodb.sh >> /var/log/mongodb_backup.log 2>&1
`
Pritunl 配置备份
`bash
#!/bin/bash
# backup_pritunl.sh
BACKUP_DIR=”/backup/pritunl”
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p ${BACKUP_DIR}
# 备份配置文件
tar -czf “${BACKUP_DIR}/pritunl_config_${DATE}.tar.gz”
/etc/pritunl.conf
/var/lib/pritunl/
# 备份 MongoDB(使用上面的脚本)
/opt/scripts/backup_mongodb.sh
echo “Pritunl 备份完成”
`
恢复流程
1. 恢复 MongoDB
`bash
# 恢复备份
mongorestore –uri=”mongodb://admin:password@localhost:27017″
–drop
/backup/mongodb/20260607_020000/pritunl
`
2. 恢复 Pritunl 配置
`bash
# 停止服务
sudo systemctl stop pritunl
# 恢复配置
tar -xzf /backup/pritunl/pritunl_config_20260607.tar.gz -C /
# 启动服务
sudo systemctl start pritunl
`
性能调优
服务器调优
1. 增加文件限制
`bash
# /etc/security/limits.conf
* hard nofile 64000
* soft nofile 64000
root hard nofile 64000
root soft nofile 64000
`
2. 调整内核参数
`bash
# /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.core.netdev_max_backlog = 65535
`
`bash
# 应用配置
sudo sysctl -p
`
3. 队列和线程配置
根据服务器规格调整:
`bash
# 低容量 (1 CPU, 4GB RAM)
sudo pritunl set app.request_queue_size 200
sudo pritunl set app.request_accepted_queue_size 100
sudo pritunl set app.request_thread_count 20
sudo pritunl set app.request_max_thread_count 100
# 标准容量 (2 CPU, 4GB RAM)
sudo pritunl set app.request_queue_size 600
sudo pritunl set app.request_accepted_queue_size 300
sudo pritunl set app.request_thread_count 50
sudo pritunl set app.request_max_thread_count 300
# 高容量 (4 CPU, 4GB RAM)
sudo pritunl set app.request_queue_size 1200
sudo pritunl set app.request_accepted_queue_size 600
sudo pritunl set app.request_thread_count 100
sudo pritunl set app.request_max_thread_count 600
# 极限容量 (8 CPU, 8GB RAM)
sudo pritunl set app.request_queue_size 4000
sudo pritunl set app.request_accepted_queue_size 2000
sudo pritunl set app.request_thread_count 100
sudo pritunl set app.request_max_thread_count 2000
`
OpenVPN 调优
1. 选择合适的加密算法
`bash
# AES-128-GCM(推荐,性能最佳)
sudo pritunl set app.encryption_cipher aes-128-gcm
# SHA-256 哈希
sudo pritunl set app.hash_algorithm SHA-256
`
2. 启用 WireGuard
WireGuard 性能优于 OpenVPN:
- 在服务器设置中启用 WireGuard
- 用户可在客户端切换协议
3. 调整 MTU
`bash
# 检查路径 MTU
ping -M do -s 1400
# 设置 MTU(如需要)
sudo pritunl set app.mtu 1400
`
数据库调优
MongoDB WiredTiger 缓存
`yaml
# /etc/mongod.conf
storage:
wiredtiger:
engineConfig:
cacheSizeGB: 2 # 根据内存调整
`
索引优化
`javascript
// 连接到 MongoDB
mongo
// 查看索引
use pritunl
db.users.getIndexes()
// 创建索引(如需要)
db.users.createIndex({ “org_id”: 1, “status”: 1 })
`
插件开发
插件系统概述
Pritunl 支持 Python 插件扩展功能:
`python
# plugin_example.py
def on_user_connect(user, server, client_address):
“””用户连接时触发”””
print(f”User {user[‘name’]} connected from {client_address}”)
def on_user_disconnect(user, server, client_address):
“””用户断开时触发”””
print(f”User {user[‘name’]} disconnected”)
def on_server_start(server):
“””服务器启动时触发”””
print(f”Server {server[‘name’]} started”)
def on_server_stop(server):
“””服务器停止时触发”””
print(f”Server {server[‘name’]} stopped”)
`
插件事件
| 事件 | 说明 | 参数 |
|---|
|——|——|——|
on_user_connect |
用户连接 | user, server, client_address |
|---|---|---|
on_user_disconnect |
用户断开 | user, server, client_address |
on_server_start |
服务器启动 | server |
on_server_stop |
服务器停止 | server |
on_server_update |
服务器更新 | server |
安装插件
- 将插件文件放到
/var/lib/pritunl/plugins/ - 在 Web 控制台启用插件
- 重启 Pritunl
API 使用
认证
`bash
# 获取 API 密钥
sudo pritunl set app.api_key “YOUR_API_KEY”
# 或在 Web 控制台设置中配置
`
常用 API 示例
获取所有用户
`bash
curl -k “https://your-server/api/v1/user”
-H “Auth-Token: YOUR_TOKEN”
-H “Auth-Secret: YOUR_SECRET”
`
创建用户
`bash
curl -k -X POST “https://your-server/api/v1/user”
-H “Auth-Token: YOUR_TOKEN”
-H “Auth-Secret: YOUR_SECRET”
-H “Content-Type: application/json”
-d ‘{
“organization_id”: “ORG_ID”,
“name”: “new_user”,
“email”: “user@example.com”,
“pin”: “1234”
}’
`
获取服务器状态
`bash
curl -k “https://your-server/api/v1/server/SERVER_ID”
-H “Auth-Token: YOUR_TOKEN”
-H “Auth-Secret: YOUR_SECRET”
`
API 自动化脚本
`python
#!/usr/bin/env python3
# pritunl_api.py
import requests
import json
class PritunlAPI:
def __init__(self, base_url, api_key, api_secret):
self.base_url = base_url
self.headers = {
‘Auth-Token’: api_key,
‘Auth-Secret’: api_secret,
‘Content-Type’: ‘application/json’
}
def get_users(self, org_id):
url = f”{self.base_url}/api/v1/user/{org_id}”
response = requests.get(url, headers=self.headers, verify=False)
return response.json()
def create_user(self, org_id, name, email, pin=None):
url = f”{self.base_url}/api/v1/user/{org_id}”
data = {
‘name’: name,
’email’: email
}
if pin:
data[‘pin’] = pin
response = requests.post(url, headers=self.headers, json=data, verify=False)
return response.json()
def delete_user(self, org_id, user_id):
url = f”{self.base_url}/api/v1/user/{org_id}/{user_id}”
response = requests.delete(url, headers=self.headers, verify=False)
return response.status_code
# 使用示例
api = PritunlAPI(‘https://vpn.example.com’, ‘api_key’, ‘api_secret’)
users = api.get_users(‘org_id’)
print(json.dumps(users, indent=2))
`
升级与维护
升级 Pritunl
`bash
# AlmaLinux/Rocky Linux
sudo dnf update pritunl
# Ubuntu
sudo apt update
sudo apt upgrade pritunl
# 重启服务
sudo systemctl restart pritunl
`
升级 MongoDB
`bash
# 备份数据库
mongodump –uri=”mongodb://…” –out=/backup/pre_upgrade
# 升级 MongoDB
sudo apt update
sudo apt upgrade mongodb-org
# 重启
sudo systemctl restart mongod
`
滚动升级(集群)
- 升级 Secondary 节点
- 验证 Secondary 正常
- 切换 Primary
- 升级原 Primary
- 验证所有节点
故障排查
常见问题
Q1: 连接重置错误
症状:客户端日志显示 “connection reset by peer”
解决:
`bash
# 增加队列容量
sudo pritunl set app.request_queue_size 600
sudo pritunl set app.request_thread_count 50
sudo systemctl restart pritunl
`
Q2: 数据库连接失败
检查:
`bash
# 检查 MongoDB 状态
sudo systemctl status mongod
# 测试连接
mongo –host localhost –port 27017 -u pritunl -p password
`
Q3: 集群节点不同步
检查:
`bash
# 查看副本集状态
mongo
rs.status()
# 查看节点同步状态
db.getReplicationInfo()
`
日志分析
`bash
# Pritunl 日志
sudo journalctl -u pritunl -f
# MongoDB 日志
sudo journalctl -u mongod -f
# OpenVPN 日志
sudo journalctl -u openvpn -f
`
性能诊断
`bash
# CPU 分析(使用 py-spy)
sudo /usr/lib/pritunl/usr/bin/py-spy top –pid $(pgrep pritunl)
# 网络连接
sudo netstat -tulpn | grep pritunl
# 文件限制
sudo lsof -p $(pgrep pritunl) | wc -l
`
运维检查清单
每日检查
- [ ] 服务器状态(CPU/内存/磁盘)
- [ ] VPN 连接数
- [ ] 错误日志
- [ ] 备份状态
每周检查
- [ ] 安全更新
- [ ] 证书有效期
- [ ] 用户审计
- [ ] 性能指标
每月检查
- [ ] 容量规划
- [ ] 备份恢复测试
- [ ] 安全审计
- [ ] 文档更新
总结
通过本系列文章,你已经掌握了:
✅ 基础部署:从零搭建 Pritunl VPN 服务器
✅ 安全加固:SELinux、动态防火墙、设备认证
✅ 企业集成:SSO 单点登录(Google/Azure/Okta 等)
✅ 多云互联:AWS/Azure/Google Cloud 站点到站点
✅ 生产运维:高可用、监控、备份、性能调优
Pritunl 作为开源 VPN 解决方案,提供了企业级的功能和安全性,同时避免了商业 VPN 的高昂许可费用。希望本系列文章能帮助你成功部署和运维 Pritunl VPN。
相关资源:
- 官方文档:https://docs.pritunl.com/
- GitHub:https://github.com/pritunl
- 社区支持:https://pritunl.com/community
- MongoDB Atlas:https://www.mongodb.com/cloud/atlas
*本文基于 Pritunl 官方文档整理,更多技术细节请访问官方文档。*
发表回复