开源VPN实战(五):Pritunl 高可用与运维实战

作者:

系列文章回顾

这是「开源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 是官方托管服务,提供:

  • 自动备份
  • 自动故障转移
  • 内置监控
  • 免费层级可用

配置步骤

  1. 注册 MongoDB Atlas
  2. 创建集群
  3. 配置网络访问(白名单)
  4. 创建数据库用户
  5. 获取连接字符串

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:验证集群

  1. 登录任意节点的 Web 控制台
  2. 导航到 Hosts 页面
  3. 所有节点应显示为在线

步骤 4:配置 VPN 服务器

  1. 创建 VPN 服务器
  2. 将多个主机附加到服务器
  3. 启动服务器

故障转移行为

  • 主机故障时自动切换到其他主机
  • 故障转移时间约 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 数据源

  1. 访问 http://server-ip:3000
  2. 默认登录:admin/admin
  3. 添加 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:

  1. 在服务器设置中启用 WireGuard
  2. 用户可在客户端切换协议

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

安装插件

  1. 将插件文件放到 /var/lib/pritunl/plugins/
  2. 在 Web 控制台启用插件
  3. 重启 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

`

滚动升级(集群)

  1. 升级 Secondary 节点
  2. 验证 Secondary 正常
  3. 切换 Primary
  4. 升级原 Primary
  5. 验证所有节点

故障排查

常见问题

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 官方文档整理,更多技术细节请访问官方文档。*

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注