Table of Contents

OpenVPN 服务器

简介

目标

  • 加密您的互联网连接以加强安全和隐私。
    • 防止客户端的数据泄露和流量欺骗。
  • 使用商业vpn服务绕过区域限制。
    • 规避客户端内容过滤和互联网审查。
  • 更方便地远程访问您的局域网服务(无需端口转发)。

实现过程(命令、配置)

以下流程的实操环境为 OpenWrt 21.02.

如果你想在 更早版本的OpenWrt 上搭建OpenVPN服务器,为避免tls-crypt错误,请参照之前版本说明。 例如:forum post

1. 准备工作

安装所需软件包。

设定VPN服务器配置的一些参数。

# 安装软件包
opkg update
opkg install openvpn-openssl openvpn-easy-rsa
 
# 配置参数  # OVPN_POOL 除了本地网段意外,可以是任何网段。
OVPN_DIR="/etc/openvpn"
OVPN_PKI="/etc/easy-rsa/pki"
OVPN_PORT="1194"
OVPN_PROTO="udp"
OVPN_POOL="192.168.8.0 255.255.255.0"
OVPN_DNS="${OVPN_POOL%.* *}.1"
OVPN_DOMAIN="$(uci get dhcp.@dnsmasq[0].domain)"
 
# 获取WAN IP地址作为OVPN_SERV服务器地址
. /lib/functions/network.sh
network_flush_cache
network_find_wan NET_IF
network_get_ipaddr NET_ADDR "${NET_IF}"
OVPN_SERV="${NET_ADDR}"
 
# 对于非固定ip(例如PPPoE拨号上网)建议通过DDNS将动态IP地址映射到固定的域名
# 如果在openwrt部署DDNS,从DDNS获取FQDN,作为OVPN_SERV服务器地址
# 如果DDNS未部署在openwrt上,需自行设定OVPN_SERV
NET_FQDN="$(uci -q get ddns.@service[0].lookup_host)"
if [ -n "${NET_FQDN}" ]
then OVPN_SERV="${NET_FQDN}"
fi

2. 证书体系建立

使用 EasyRSA 管理 PKI 体系. 如有必要,可使用私钥密码保护。

# 配置参数
export EASYRSA_PKI="${OVPN_PKI}"
export EASYRSA_REQ_CN="ovpnca"
export EASYRSA_BATCH="1"
export EASYRSA_CERT_EXPIRE="3650" # Increases the client cert expiry from the default of 825 days to match the CA expiry
 
# 清空,并初始化 PKI 目录
easyrsa init-pki
 
# 生成 DH 参数
easyrsa gen-dh
 
# 新建 CA
easyrsa build-ca nopass
 
# 生成服务器秘钥和证书
easyrsa build-server-full server nopass
openvpn --genkey tls-crypt-v2-server ${EASYRSA_PKI}/private/server.pem
 
# 生成客户端秘钥和证书
easyrsa build-client-full client nopass
openvpn --tls-crypt-v2 ${EASYRSA_PKI}/private/server.pem \
--genkey tls-crypt-v2-client ${EASYRSA_PKI}/private/client.pem

3. 防火墙设置

VPN 网络视为私有网络。 将 VPN 接口 tun+ 分配给防火墙 LAN 区域的涵盖设备,以最小化防火墙设置。 允许从 WAN 区域访问 VPN 服务器。

# 配置防火墙
uci rename firewall.@zone[0]="lan"
uci rename firewall.@zone[1]="wan"
uci del_list firewall.lan.device="tun+"
uci add_list firewall.lan.device="tun+"
uci -q delete firewall.ovpn
uci set firewall.ovpn="rule"
uci set firewall.ovpn.name="Allow-OpenVPN"
uci set firewall.ovpn.src="wan"
uci set firewall.ovpn.dest_port="${OVPN_PORT}"
uci set firewall.ovpn.proto="${OVPN_PROTO}"
uci set firewall.ovpn.target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart

4. VPN 服务设置

配置VPN服务,生成客户端文件。

# 配置VPN服务,生成客户端文件
umask go=
OVPN_DH="$(cat ${OVPN_PKI}/dh.pem)"
OVPN_CA="$(openssl x509 -in ${OVPN_PKI}/ca.crt)"
ls ${OVPN_PKI}/issued \
| sed -e "s/\.\w*$//" \
| while read -r OVPN_ID
do
OVPN_TC="$(cat ${OVPN_PKI}/private/${OVPN_ID}.pem)"
OVPN_KEY="$(cat ${OVPN_PKI}/private/${OVPN_ID}.key)"
OVPN_CERT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt)"
OVPN_EKU="$(echo "${OVPN_CERT}" | openssl x509 -noout -purpose)"
case ${OVPN_EKU} in
(*"SSL server : Yes"*)
OVPN_CONF="${OVPN_DIR}/${OVPN_ID}.conf"
cat << EOF > ${OVPN_CONF} ;;
user nobody
group nogroup
dev tun
port ${OVPN_PORT}
proto ${OVPN_PROTO}
server ${OVPN_POOL}
topology subnet
client-to-client
keepalive 10 60
persist-tun
persist-key
push "dhcp-option DNS ${OVPN_DNS}"
push "dhcp-option DOMAIN ${OVPN_DOMAIN}"
push "redirect-gateway def1"
push "persist-tun"
push "persist-key"
<dh>
${OVPN_DH}
</dh>
EOF
(*"SSL client : Yes"*)
OVPN_CONF="${OVPN_DIR}/${OVPN_ID}.ovpn"
cat << EOF > ${OVPN_CONF} ;;
user nobody
group nogroup
dev tun
nobind
client
remote ${OVPN_SERV} ${OVPN_PORT} ${OVPN_PROTO}
auth-nocache
remote-cert-tls server
EOF
esac
cat << EOF >> ${OVPN_CONF}
<tls-crypt-v2>
${OVPN_TC}
</tls-crypt-v2>
<key>
${OVPN_KEY}
</key>
<cert>
${OVPN_CERT}
</cert>
<ca>
${OVPN_CA}
</ca>
EOF
done
/etc/init.d/openvpn restart
ls ${OVPN_DIR}/*.ovpn

通过openwrt luci后台的备份下载包含配置文件的压缩包 backup。 解压提取客户端配置文件,导入客户端。

在完成以上操作后,如需生成更多客户端配置文件 .ovpn :

  1. 通过运行此 multi-client 脚本快速生成.
  2. 需要修改脚本,确保脚本内有:上文第1条的“配置参数”部分,上文第4条的全部,方可运行脚本.
  3. 注意:新生成的ovpn配置文件的 “remote” 这一行可能不正确,请确认指向设置的服务器地址.

测试

建立 VPN 连接。 使用 traceroutetraceroute6 命令确认流量是否通过VPN网关.

traceroute openwrt.org
traceroute6 openwrt.org

检查客户端IP地址.

请确保客户端没有DNS泄露(DNS leak)发生。

如果使用IPv6,需将公共IPv6前缀委派给VPN网络作为默认配置。

故障排除

通过以下步骤,获取、分析日志.

# 重启日志、openvpn服务
/etc/init.d/log restart; /etc/init.d/openvpn restart; sleep 10
 
# 获取日志和openvpn状态
logread -e openvpn; netstat -l -n -p | grep -e openvpn
 
# 各项运行中的配置参数(openvpn运行配置、网络信息、防火墙配置)
pgrep -f -a openvpn
ip address show; ip route show table all
ip rule show; ip -6 rule show; nft list ruleset
 
# 配置文件情况
uci show network; uci show firewall; uci show openvpn
head -v -n -0 /etc/openvpn/*.conf