# OpenVPN 龙芯服务器部署与使用文档
| 项目 | 说明 |
|------|------|
| 服务器架构 | LoongArch64 |
| 操作系统 | AOSC OS 13.3.0 |
| 服务器内网 IP | 19.190.1.4 |
| 服务端口 | 1194 (TCP) |
| VPN 虚拟网段 | 10.8.0.0/24 |
| 代理范围 | 19.190.1.4、19.190.3.0/24、19.190.7.0/24 |
| 认证方式 | 用户名 + 密码(SHA256) |
---
## 一、部署环境
| 项目 | 参数 |
|------|------|
| CPU | LoongArch 64 |
| 内核 | 7.0.12-aosc-main-16k |
| TLS 库 | OpenSSL 3.6.3 |
| 数据压缩 | LZO 2.10 |
---
## 二、安装步骤
AOSC OS 仓库不含 OpenVPN,从 Debian Ports 下载 `loong64` 架构的 deb 包安装。
### 2.1 下载依赖包
```bash
cd /tmp
MIRROR='https://mirror.iscas.ac.cn/debian-ports/pool-loong64/main'
wget "$MIRROR/o/openvpn/openvpn_2.7.0~rc3-1_loong64.deb"
wget "$MIRROR/l/lzo2/liblzo2-2_2.10-3+b1_loong64.deb"
wget "$MIRROR/libn/libnl3/libnl-3-200_3.11.0-2_loong64.deb"
wget "$MIRROR/libn/libnl3/libnl-genl-3-200_3.11.0-2_loong64.deb"
wget "$MIRROR/p/pkcs11-helper/libpkcs11-helper1t64_1.31.0-1_loong64.deb"
```
### 2.2 安装
```bash
sudo dpkg -i liblzo2-2_*.deb libnl-3-200_*.deb libnl-genl-3-200_*.deb libpkcs11-helper1t64_*.deb
sudo dpkg --force-depends -i openvpn_*.deb
# postinst 脚本报错可忽略(AOSC 无 update-rc.d)
```
### 2.3 修复库路径
AOSC OS 的 `ld.so.conf` 未包含 multiarch 路径:
```bash
echo '/usr/lib/loongarch64-linux-gnu' | sudo tee /etc/ld.so.conf.d/multiarch.conf
sudo ldconfig
```
### 2.4 验证安装
```bash
/usr/sbin/openvpn --version
# OpenVPN 2.7_rc3 loongarch64-unknown-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [AEAD] [DCO]
```
---
## 三、证书生成
### 3.1 工作目录
```bash
sudo mkdir -p /etc/openvpn/pki
cd /etc/openvpn/pki
```
### 3.2 生成 CA 根证书
```bash
sudo openssl genrsa -out ca.key 2048
sudo openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj '/CN=OpenVPN-CA'
```
### 3.3 生成服务器证书
> OpenVPN 2.7 客户端启用 `remote-cert-tls server` 时,服务器证书**必须**包含 `serverAuth` 扩展密钥用途,否则 TLS 握手失败。
```bash
sudo openssl genrsa -out server.key 2048
# 创建扩展配置文件
sudo tee server_ext.cnf << 'EOF'
[server_ext]
nsCertType = server
extendedKeyUsage = serverAuth
subjectAltName = DNS:server
EOF
sudo openssl req -new -key server.key -out server.csr -subj '/CN=OpenVPN-Server'
sudo openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -extfile server_ext.cnf -extensions server_ext
```
验证证书 EKU:
```bash
openssl x509 -in server.crt -text -noout | grep -A1 'Extended Key Usage'
# 应输出:TLS Web Server Authentication
```
### 3.4 生成 tls-crypt 静态密钥
```bash
sudo openvpn --genkey secret ta.key
```
### 3.5 权限加固
```bash
sudo chmod 600 ca.key server.key ta.key
```
### 3.6 关于 DH 参数
OpenSSL 3.x 不兼容小型 DH 参数,服务端配置使用 `dh none` + `ecdh-curve prime256v1` 替代,无需生成 dh.pem。
---
## 四、用户认证配置
### 4.1 密码文件
格式:`用户名 密码的SHA256哈希值`
```bash
# 生成哈希
echo -n '密码' | sha256sum
# 创建密码文件
sudo tee /etc/openvpn/users.pwd << 'EOF'
testuser ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae
EOF
# nobody 用户需可读
sudo chmod 644 /etc/openvpn/users.pwd
```
### 4.2 认证脚本 (`/etc/openvpn/checkpsw.sh`)
> **关键**:`via-file` 模式下 OpenVPN 将用户名和密码写入临时文件(第一行用户名、第二行密码),文件路径作为 `$1` 传给脚本。`$2` 在 `via-file` 模式下为空。
```bash
sudo tee /etc/openvpn/checkpsw.sh << 'EOF'
#!/bin/bash
USERNAME=$(head -1 "$1")
PASSWORD=$(tail -1 "$1")
HASH=$(echo -n "$PASSWORD" | sha256sum | cut -d" " -f1)
if grep -q "^$USERNAME $HASH$" /etc/openvpn/users.pwd; then
exit 0
else
exit 1
fi
EOF
sudo chmod 755 /etc/openvpn/checkpsw.sh
```
### 4.3 手动测试认证
```bash
echo -e "testuser\ntest123" > /tmp/test_auth.txt
sudo /etc/openvpn/checkpsw.sh /tmp/test_auth.txt
echo $? # 0=成功, 1=失败
```
### 4.4 用户管理
```bash
# 添加用户
USER="新用户名"
PASS="新密码"
HASH=$(echo -n "$PASS" | sha256sum | cut -d' ' -f1)
echo "$USER $HASH" | sudo tee -a /etc/openvpn/users.pwd
# 删除用户
sudo sed -i '/^用户名 /d' /etc/openvpn/users.pwd
# 修改密码
sudo sed -i '/^用户名 /d' /etc/openvpn/users.pwd
HASH=$(echo -n '新密码' | sha256sum | cut -d' ' -f1)
echo "用户名 $HASH" | sudo tee -a /etc/openvpn/users.pwd
# 查看所有用户
sudo awk '{print $1}' /etc/openvpn/users.pwd
```
---
## 五、服务器配置
### 5.1 主配置文件 (`/etc/openvpn/server.conf`)
```ini
port 1194
proto tcp
dev tun
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/server.crt
key /etc/openvpn/pki/server.key
dh none
ecdh-curve prime256v1
tls-crypt /etc/openvpn/pki/ta.key
server 10.8.0.0 255.255.255.0
push "route 19.190.1.4 255.255.255.255"
push "route 19.190.3.0 255.255.255.0"
push "route 19.190.7.0 255.255.255.0"
push "dhcp-option DNS 223.5.5.5"
keepalive 10 120
cipher AES-256-GCM
data-ciphers AES-256-GCM:AES-128-GCM
auth SHA256
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-file
script-security 3
verify-client-cert none
username-as-common-name
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log
log /var/log/openvpn.log
verb 7
duplicate-cn
```
| 参数 | 说明 |
|------|------|
| `proto tcp` | 使用 TCP 协议(跨网段稳定性优于 UDP) |
| `dh none` + `ecdh-curve prime256v1` | OpenSSL 3.x 兼容的密钥交换方式 |
| `push "route ..."` | 仅推送指定网段路由(分流模式) |
| `verify-client-cert none` | 客户端无需证书,仅用用户名密码认证 |
| `auth-user-pass-verify via-file` | 通过临时文件传递用户名密码给验证脚本 |
| `username-as-common-name` | 以用户名作为客户端标识写入日志 |
| `duplicate-cn` | 允许同一用户名多设备同时在线 |
| `verb 7` | 调试级日志(正常运行后可降为 3) |
### 5.2 网络转发
```bash
# 开启 IP 转发
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl -p /etc/sysctl.d/99-openvpn.conf
# 配置 NAT(VPN 客户端访问目标网段时做源地址转换)
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -j ACCEPT
sudo iptables -A FORWARD -o tun0 -j ACCEPT
# 持久化 iptables
sudo mkdir -p /etc/iptables
sudo iptables-save | sudo tee /etc/iptables/rules.v4
```
### 5.3 systemd 服务
`/etc/systemd/system/openvpn-server.service`:
```ini
[Unit]
Description=OpenVPN Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/server.conf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
> `Type=simple`(前台运行)而非 `Type=forking`(daemon 模式),systemd 可直接管理进程状态。
启用服务:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now openvpn-server
```
### 5.4 服务管理
```bash
systemctl start openvpn-server # 启动
systemctl stop openvpn-server # 停止
systemctl restart openvpn-server # 重启
systemctl status openvpn-server # 查看状态
tail -f /var/log/openvpn.log # 查看日志
```
---
## 六、外网访问
### 6.1 端口映射
在路由器/防火墙上配置:
| 配置项 | 值 |
|--------|-----|
| 协议 | TCP |
| 公网端口 | 1194 |
| 内网 IP | 19.190.1.4 |
| 内网端口 | 1194 |
映射完成后,客户端将 `remote` 行改为公网 IP 即可从外网连接。
---
## 七、客户端配置与使用
### 7.1 客户端配置文件 (`client.ovpn`)
```ini
client
dev tun
proto tcp
remote 19.190.1.4 1194
resolv-retry infinite
nobind
persist-key
persist-tun
auth-user-pass
cipher AES-256-GCM
auth SHA256
remote-cert-tls server
verb 3
-----BEGIN CERTIFICATE-----
MIIDCzCCAfOgAwIBAgIUK8A2WwhxFWOjZEoP3PQCHi/6/XMwDQYJKoZIhvcNAQEL
BQAwFTETMBEGA1UEAwwKT3BlblZQTi1DQTAeFw0yNjA3MTYwNDM1MzFaFw0zNjA3
MTMwNDM1MzFaMBUxEzARBgNVBAMMCk9wZW5WUE4tQ0EwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQClOp8AE0MCKWuXIt5En4VdZ8PaasUvUAtUvquApGVR
Ek6M0dT52hyNThk9TbSc1aTxacWl23BBxDkawBqt1K/mQUXZAV2go0np4lqGevLG
bTbeNzyneqwYmpkLCjkjnbiZbnq0/IjMGZ/nXoe/+HRqMkNWIdjEGHfylNBNeKtl
0NldhhkQwtkIVi8Q9rGqi46gMpctg9xTcybFeO+EcqcDm3MqJwMfyE5EzOfk8HWg
AfgjthAtTWEOx93UA4cjtKG4p+J4/yqNVpnFg1NvSfqxf3lNQ6K01WQBzmibaZgZ
EymnaF4FZ5wfGJuCh2KH/xHeARxdlFGZrsL6O2TUMuCVAgMBAAGjUzBRMB0GA1Ud
DgQWBBTxCh91OWB+pFtNID/HmfIW3LB35TAfBgNVHSMEGDAWgBTxCh91OWB+pFtN
ID/HmfIW3LB35TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCE
HoswQvzRINNtV+pUUqnenz8OKwgfAHNoM5jq+9+zsr+pK1h8cR6CINWFGbUQedTp
gmNZE43GJUFA572ubOIHczy5TVcjjWK3SNSFFUD5GOcwDMcD7eN5/Uif6DlHZsE6
0MMUC/CjLV0CJizU870S9orsDyUszD8suy//Ba1QwaWcQgup092fD6IuBUP0GgqV
MpNcRpoK0vuAROg5XNFSvtGiJ+JXjBFdenDsdD/MSRh7NPIX/AQhZt1KBetEJtuv
cj19EqB7nw3n0LWN+CwCke9PP2D0OHeRrOR9Oe6yxR8ctxn1IiuGlcA7U5PzosR2
NGjofX9h4FpMl20G5EnH
-----END CERTIFICATE-----
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
db58e39acfa391eb79f6dc471136914c
19d80570505ee60b479758e5f05613d5
298b745eb80724b6205387093d91d25d
b7cf84f3edb5de6aaeb992b82f55b765
05333b9499f50435a8fd002a0f435d5d
4c4def2c482e0c44cd87c8f3f89d6765
7a215c61a9b3e1ebffdb25616d61070b
4cea80c10dcaa0cc8b16e1d8845842e7
da6ac5cad01d5062b8e8700da706fb92
bdf2bf7418fe237f05fbf408d46e0647
7164168b38f23ad5a929197c5943790d
2aa9edfd17dbccc78a72e55dc7c69480
087835fce4fcf6882e1aa920b86566f5
de5c2eb7b11d5bd6e4dc9216e44e2907
5cce76c9d762fea3e167ba7ac83e316b
0519e233673b9c2e7d8d2626a537b576
-----END OpenVPN Static key V1-----
```
### 7.2 客户端配置参数说明
| 参数 | 说明 |
|------|------|
| `client` | 客户端模式 |
| `proto tcp` | 与服务端协议一致 |
| `remote 19.190.1.4 1194` | 服务端地址(内网)和端口 |
| `auth-user-pass` | 连接时弹窗输入用户名密码 |
| `...` | 内嵌 CA 证书 |
| `...` | 内嵌 TLS-Crypt 静态密钥 |
| `remote-cert-tls server` | 验证服务端证书,防中间人攻击 |
### 7.3 外网连接
将 `remote` 中的内网 IP 替换为公网 IP 或域名:
```ini
remote 公网IP 1194
```
### 7.4 各平台使用
**macOS(Tunnelblick)**:
1. 下载安装 [Tunnelblick](https://tunnelblick.net/)
2. 双击 `client.ovpn` 导入配置
3. 点击菜单栏 Tunnelblick 图标 → 连接
4. 输入用户名和密码
5. 连接成功后图标变黑
**Windows**:
1. 下载安装 [OpenVPN Connect](https://openvpn.net/client/)
2. 将 `client.ovpn` 导入应用
3. 连接时输入用户名密码
**Linux**:
```bash
sudo openvpn --config client.ovpn
```
**Android / iOS**:
1. 应用商店安装 OpenVPN Connect
2. 将 `.ovpn` 文件传输到手机并导入
3. 连接时输入用户名密码
---
## 八、分流说明
VPN 采用分流模式,**仅代理以下目标**,其余流量走本地网络:
| 目标 | 掩码 | 说明 |
|------|------|------|
| 19.190.1.4 | /32 | OpenVPN 服务器本身 |
| 19.190.3.0 | /24 | 目标业务网段 |
| 19.190.7.0 | /24 | 目标业务网段 |
### 验证分流效果
```bash
# 查看 VPN 路由
netstat -rn -f inet | grep utun
# 预期输出:
# 10.8/24 10.8.0.x UGSc utun4
# 19.190.1.4 10.8.0.1 UGSc utun4
# 19.190.3/24 10.8.0.1 UGSc utun4
# 19.190.7/24 10.8.0.1 UGSc utun4
```
```bash
# 目标网段走 VPN(第一跳为 10.8.0.1)
traceroute 19.190.3.1
# 公网走本地(第一跳为本地网关)
traceroute 8.8.8.8
```
---
## 九、在线用户查看
```bash
sudo cat /var/log/openvpn-status.log
```
示例输出:
```
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
testuser,tcp4-server:192.168.110.33:50694,227750,165584,Fri Jul 17 09:58:00 2026
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.8.0.2,testuser,tcp4-server:192.168.110.33:50694,Fri Jul 17 09:58:00 2026
```
---
## 十、故障排查
### 10.1 服务启动失败
```bash
# 查看 systemd 日志
sudo journalctl -u openvpn-server -n 50 --no-pager
# 前台启动看详细报错
sudo openvpn --config /etc/openvpn/server.conf
```
### 10.2 客户端无法连接
| 检查项 | 命令 | 正常结果 |
|--------|------|----------|
| 服务进程 | `ps aux \| grep '[o]penvpn'` | 有 openvpn 进程 |
| 端口监听 | `sudo ss -tlnp \| grep 1194` | 0.0.0.0:1194 |
| tun0 网卡 | `ip addr show tun0` | 10.8.0.1/24 |
### 10.3 TLS 握手失败
```bash
# 确认服务器证书包含 serverAuth EKU
openssl x509 -in /etc/openvpn/pki/server.crt -text -noout | grep -A1 'Extended Key Usage'
# 确认客户端 tls-crypt 密钥与服务器一致
sudo md5sum /etc/openvpn/pki/ta.key
# 对比客户端 .ovpn 文件中 段的内容
```
### 10.4 认证失败
```bash
# 查看认证调试日志
cat /tmp/auth-debug.log
# 手动测试认证
echo -e "testuser\ntest123" > /tmp/test_auth.txt
sudo /etc/openvpn/checkpsw.sh /tmp/test_auth.txt
echo $? # 0=成功, 1=失败
```
### 10.5 已连接但无法访问目标
```bash
# 检查 IP 转发(必须为 1)
sysctl net.ipv4.ip_forward
# 检查 NAT 规则(必须有 MASQUERADE)
sudo iptables -t nat -L POSTROUTING | grep 10.8.0
# 如缺失则重新添加
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -j ACCEPT
sudo iptables -A FORWARD -o tun0 -j ACCEPT
```
### 10.6 常见错误速查
| 错误日志 | 原因 | 解决方法 |
|----------|------|----------|
| `dh key too small` | OpenSSL 3.x 不兼容小型 DH 参数 | 使用 `dh none` + `ecdh-curve prime256v1` |
| `TLS Error: TLS key negotiation failed` | tls-crypt 密钥不一致 | 重新拷贝 ta.key 到客户端 ovpn 文件 |
| `AUTH_FAILED` | 认证脚本问题 | 检查 `via-file` 模式下脚本是否正确读取临时文件 |
| `Cannot open TUN/TAP dev` | tun 内核模块未加载 | `sudo modprobe tun` |
| `Address already in use` | 端口被占用 | `sudo ss -tlnp \| grep 1194` 查占用进程 |
---
## 十一、关键路径速查
| 文件 | 路径 |
|------|------|
| 服务端配置 | `/etc/openvpn/server.conf` |
| CA 证书 | `/etc/openvpn/pki/ca.crt` |
| CA 私钥 | `/etc/openvpn/pki/ca.key` |
| 服务端证书 | `/etc/openvpn/pki/server.crt` |
| 服务端私钥 | `/etc/openvpn/pki/server.key` |
| TLS-Crypt 密钥 | `/etc/openvpn/pki/ta.key` |
| 认证脚本 | `/etc/openvpn/checkpsw.sh` |
| 用户密码文件 | `/etc/openvpn/users.pwd` |
| 运行日志 | `/var/log/openvpn.log` |
| 状态文件 | `/var/log/openvpn-status.log` |
| 认证调试日志 | `/tmp/auth-debug.log` |
| systemd 服务 | `/etc/systemd/system/openvpn-server.service` |
---
*部署日期:2026-07-16*
*适用平台:AOSC OS 13.3.0 / LoongArch64 + OpenVPN 2.7*