使用OpenVPN连接有公网IP与无公网IP的服务器

使用OpenVPN连接有公网IP与无公网IP的服务器

一、服务器A(OpenVPN服务器)配置

1. 安装必要软件

1
yum install openvpn easy-rsa -y

2. 配置服务器

1
2
3
4
5
# 复制配置模板
cp /usr/share/doc/openvpn/example/sample-config-files/server.conf /etc/openvpn/

# 编辑配置文件
vim /etc/openvpn/server.conf

重要配置项修改: - 修改协议(建议UDP): proto udp - 配置VPN网段: server 10.8.0.0 255.255.255.0 - 启用客户端之间通信(根据需要): 取消注释 client-to-client - 配置DNS(可选): 取消注释 push "dhcp-option DNS 8.8.8.8" - 设置用户权限: 取消注释 user nobodygroup nobody - 对于TCP模式: 注释 explicit-exit-notify 1

3. 准备证书环境

1. 复制并准备环境

1
2
3
4
# 创建工作目录(如果您之前没有创建过)
mkdir -p /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa

2. 配置变量文件

1
2
3
4
5
# 复制示例变量文件
cp vars.example vars

# 编辑变量文件(可选,但建议设置)
vim vars

在 vars 文件中,您可能需要设置以下变量:

1
2
3
4
5
6
set_var EASYRSA_REQ_COUNTRY    "CN"
set_var EASYRSA_REQ_PROVINCE "YourProvince"
set_var EASYRSA_REQ_CITY "YourCity"
set_var EASYRSA_REQ_ORG "YourOrganization"
set_var EASYRSA_REQ_EMAIL "admin@example.com"
set_var EASYRSA_REQ_OU "VPN"

3. 初始化 PKI 环境

1
2
3
4
5
6
# 设置环境变量
export EASYRSA=$(pwd)
export EASYRSA_PKI=$EASYRSA/pki

# 初始化 PKI
./easyrsa init-pki

4. 创建证书

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建CA证书(会提示输入密码)
./easyrsa build-ca

# 生成服务器证书和密钥
./easyrsa gen-req server nopass
./easyrsa sign-req server server

# 创建Diffie-Hellman参数文件
./easyrsa gen-dh

# 生成TLS验证密钥
cd /etc/openvpn
openvpn --genkey --secret ta.key

完成这些步骤后,您将拥有设置OpenVPN服务器所需的所有证书和密钥。下一步将是配置服务器文件并开始OpenVPN服务。

OpenVPN 证书和密钥生成详解

1. 初始化公钥基础设施(PKI)

1
./easyrsa init-pki

作用:创建证书和密钥所需的目录结构 - 初始化一个新的PKI环境,创建pki目录及其子目录 - 如果之前存在PKI目录,该命令会先清除旧数据 - 创建的目录包括:private(私钥)、issued(签发的证书)、reqs(证书请求)等

2. 创建证书授权中心(CA)

1
./easyrsa build-ca

作用:生成根证书和私钥,作为后续所有证书的签发者 - 生成ca.key(CA私钥)和ca.crt(CA证书) - 会提示输入CA证书的密码(用于保护私钥) - 会要求输入"通用名称"(Common Name),通常使用"OpenVPN-CA" - CA证书是整个VPN信任链的根源

3. 生成服务器证书请求和私钥

1
./easyrsa gen-req server nopass

作用:为OpenVPN服务器创建证书请求和私钥 - server指定证书名称为"server" - nopass参数表示私钥不加密(无密码保护) - 生成server.key(服务器私钥)和server.req(证书请求文件) - 会要求输入服务器的"通用名称",应使用"server"

4. 使用CA签署服务器证书

1
./easyrsa sign-req server server

作用:使用CA证书对服务器证书请求进行签名 - 第一个server参数表示证书类型为服务器证书 - 第二个server是证书请求的名称 - 需要输入之前设置的CA密码 - 生成server.crt(已签名的服务器证书)

5. 生成Diffie-Hellman参数

1
./easyrsa gen-dh

作用:创建用于密钥交换的DH参数文件 - 生成dh.pem文件,用于安全的密钥协商 - 此过程通常较耗时(几分钟到几十分钟不等) - DH参数用于提供完美前向保密(PFS)功能

6. 生成TLS认证密钥

1
openvpn --genkey --secret ta.key

作用:生成额外安全层的HMAC密钥 - 创建ta.key文件,用于TLS握手验证 - 有助于防御DoS攻击和UDP端口扫描 - 提供预共享密钥,客户端没有此密钥无法发起连接

7. 生成客户端证书请求和私钥

1
./easyrsa gen-req client nopass

作用:为OpenVPN客户端创建证书请求和私钥 - 与服务器证书类似,但名称为"client" - 生成client.key(客户端私钥)和client.req(证书请求)

8. 使用CA签署客户端证书

1
./easyrsa sign-req client client

作用:使用CA证书对客户端证书请求进行签名 - 类似于签署服务器证书,但类型为"client" - 生成client.crt(已签名的客户端证书)

9. 复制服务器所需文件到配置目录

1
2
cp pki/ca.crt pki/issued/server.crt pki/private/server.key \
pki/dh.pem ta.key /etc/openvpn/

作用:移动所有必要文件到OpenVPN服务器配置目录 - 确保OpenVPN服务器能找到所有所需的证书和密钥文件 - 保证文件路径与配置文件中指定的路径一致

这样,OpenVPN所需的完整PKI证书体系就建立完成,为后续安全通信提供了基础。

5. 启用IP转发(允许VPN客户端访问其他网络)

1
2
3
4
5
6
7
# 编辑系统配置
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# 配置NAT(假设eth0是公网接口)
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
# 保存iptables规则(根据系统可能有所不同)

6. 启动服务器

1
2
systemctl start openvpn@server
systemctl enable openvpn@server

二、服务器B(OpenVPN客户端)配置

1. 安装OpenVPN

1
yum install openvpn -y

2. 准备客户端配置文件

在服务器A上创建客户端配置文件:

1
vim /etc/openvpn/client.ovpn

基本配置内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
client
dev tun
proto udp
remote 182.92.187.31 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
key-direction 1
cipher AES-256-CBC
verb 3
verify-x509-name "server" name
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

3. 复制必要文件到客户端

从服务器A复制以下文件到服务器B的/etc/openvpn/目录: - client.ovpn - ca.crt - client.crt - client.key - ta.key

可通过安全方式传输:

1
2
3
4
5
6
7
# 在服务器A上
scp /etc/openvpn/client.ovpn /etc/openvpn/easy-rsa/pki/ca.crt \
/etc/openvpn/easy-rsa/pki/issued/client.crt \
/etc/openvpn/easy-rsa/pki/private/client.key \
/etc/openvpn/ta.key user@临时中转服务器IP:/tmp/

# 然后从中转服务器复制到服务器B

4. 连接到VPN服务器

1
2
cd /etc/openvpn
openvpn --config client.ovpn

也可以设置为系统服务:

1
2
3
4
# 将client.ovpn复制为client.conf
cp client.ovpn client.conf
systemctl start openvpn@client
systemctl enable openvpn@client

三、测试连接

  1. 检查服务器B上的网络接口:

    1
    ip addr show
    应该有一个新的tun0接口,IP地址在10.8.0.0/24网段

  2. 测试到服务器A的连接:

    1
    ping 10.8.0.1  # 服务器A在VPN中的地址

  3. 验证网络通信(在两台服务器上运行相同命令):

    1
    2
    ip route

    ## 三、windows客户端服务器配置

  4. 访问OpenVPN官方https://openvpn.net/community-downloads/ 下载Windows客户端

  5. 下载完成后运行安装程序

  6. 从OpenVPN服务器获取以下文件:

  • client.ovpn(客户端配置文件)
  • ca.crt(CA证书)
  • client.crt(客户端证书)
  • client.key(客户端私钥)
  • ta.key(TLS认证密钥)

导航到 C:Files

放置配置文件:

使用分离文件方式:将client.ovpn、ca.crt、client.crt、client.key和ta.key复制到配置目录

  1. 连接到VPN 以管理员权限运行OpenVPN GUI(右键点击 → 以管理员身份运行)
    程序启动后会在系统托盘区出现一个图标
    右键点击托盘图标,在弹出菜单中选择您的配置文件名,再点击"连接"
    如果配置正确,将显示连接进度,最终连接成功

  2. 在命令提示符中输入 ping 10.8.0.1 应该能成功ping通服务器端

通过OpenVPN让无公网IP的服务器对外提供服务

方法一:使用端口转发

通过在有公网IP的服务器A上配置端口转发,将来自互联网的请求转发到VPN网络中的服务器B:

1
2
3
4
5
6
7
# 在服务器A上配置
# 将公网8080端口转发到B服务器(10.8.0.2)的80端口
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.2:80
iptables -A FORWARD -p tcp -d 10.8.0.2 --dport 80 -j ACCEPT

# 保存iptables规则(根据系统不同有所变化)
iptables-save > /etc/iptables/rules.v4

这样,访问"服务器A的公网IP:8080"的请求会被转发到"服务器B的10.8.0.2:80"。

方法二:使用反向代理

在服务器A上设置Nginx/Apache反向代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 在服务器A上安装Nginx
apt install nginx -y # Debian/Ubuntu
# 或
yum install nginx -y # CentOS/RHEL

# 配置反向代理
cat > /etc/nginx/conf.d/proxy.conf << EOF
server {
listen 80;
server_name your-domain.com; # 或使用服务器A的IP

location / {
proxy_pass http://10.8.0.2:80;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
}
}
EOF

# 重启Nginx
systemctl restart nginx

注意事项

  1. 安全考量:仅开放必要的端口,考虑在防火墙上限制访问来源
  2. 域名设置:可以将域名指向服务器A的公网IP
  3. SSL证书:可以在服务器A上配置SSL证书,提供HTTPS服务
  4. VPN稳定性:确保VPN连接稳定,否则服务可用性会受影响
  5. 高可用性:考虑设置VPN连接监控和自动重连机制

通过这些方法,您可以有效地让没有公网IP的服务器B通过VPN向外界提供服务,同时利用服务器A作为安全的网关。

注意

防火墙限制 防火墙可能阻止了VPN网段访问:

1
iptables -A INPUT -s 10.8.0.0/24 -p tcp --dport 80 -j ACCEPT

使用OpenVPN连接有公网IP与无公网IP的服务器
https://jfsas.github.io/2025/04/08/使用OpenVPN连接有公网IP与无公网IP的服务器/
作者
JFSAS
发布于
2025年4月8日
许可协议