
主要实现在 OpenWRT 路由器系统下搭建 OpenVPN 服务器方便远程连接
之前一直是在 OpenWRT 使用 Openconnect VPN,因为是 SSLVPN 使用起来结合 CISCO 的 anyconnect 客户端是很方便的,但是由于现在 ISP 连这种基于 SSL 的流量也有可以做识别并封公网 IP,所以不得不考虑切换至基于 UDP 的 OpenVPN 了。>
下面主要分三步:
( 1 )在 OpenWRT 安装并配置好 OpenVPN
( 2 )配置多用户方案
( 3 )结合 Luci 去显示 OpenVPN
那么现在开始吧,目前系统是使用了最新的 OpenWRT 19.07.0-rc1, 同时适用于 OpenWrt 18.06.4
1.在 OpenWRT 安装并配置好 OpenVPN
先安装好本次所需的全部软件
opkg update opkg install openvpn-easy-rsa openvpn-mbedtls luci-app-openvpn 配置防火墙开放相应端口
# Configure firewall uci rename firewall.@zone[0]="lan" uci rename firewall.@zone[1]="wan" uci rename firewall.@forwarding[0]="lan_wan" uci del_list firewall.lan.device="tun0" uci add_list firewall.lan.device="tun0" uci -q delete firewall.vpn uci set firewall.ovpn="rule" uci set firewall.ovpn.name="Allow-OpenVPN" uci set firewall.ovpn.src="wan" uci set firewall.ovpn.dest_port="1194" uci set firewall.ovpn.proto="udp" uci set firewall.ovpn.target="ACCEPT" uci commit firewall /etc/init.d/firewall restart 生成服务器和客户端证书
# Configuration parameters export EASYRSA_PKI="/etc/easy-rsa/pki" export EASYRSA_REQ_CN="ovpnca" # Remove and re-initialize the PKI directory easyrsa --batch init-pki # Generate DH parameters # 此步会较久 easyrsa --batch gen-dh # Create a new CA easyrsa --batch build-ca nopass # Generate a keypair and sign locally for a server easyrsa --batch build-server-full server nopass # Generate a keypair and sign locally for a client easyrsa --batch build-client-full client nopass 生成服务器配置文件
# Generate TLS PSK OVPN_PKI="/etc/easy-rsa/pki" openvpn --genkey --secret ${OVPN_PKI}/tc.pem # Configuration parameters OVPN_DIR="/etc/openvpn" OVPN_PKI="/etc/easy-rsa/pki" OVPN_DEV="$(uci get firewall.lan.device | sed -e "s/^.*\s//")" OVPN_PORT="$(uci get firewall.ovpn.dest_port)" OVPN_PROTO="$(uci get firewall.ovpn.proto)" OVPN_POOL="192.168.8.0 255.255.255.0" OVPN_DNS="${OVPN_POOL%.* *}.1" OVPN_DOMAIN="$(uci get dhcp.@dnsmasq[0].domain)" OVPN_DH="$(cat ${OVPN_PKI}/dh.pem)" OVPN_TC="$(sed -e "/^#/d;/^\w/N;s/\n//" ${OVPN_PKI}/tc.pem)" OVPN_CA="$(openssl x509 -in ${OVPN_PKI}/ca.crt)" NL=$'\n' # Configure VPN server umask u=rw,g=,o= grep -l -r -e "TLS Web Server Auth" "${OVPN_PKI}/issued" \ | sed -e "s/^.*\///;s/\.\w*$//" \ | while read -r OVPN_ID do OVPN_CERT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt)" OVPN_KEY="$(cat ${OVPN_PKI}/private/${OVPN_ID}.key)" cat << EOF > ${OVPN_DIR}/${OVPN_ID}.conf verb 3 user nobody group nogroup dev ${OVPN_DEV} port ${OVPN_PORT} proto ${OVPN_PROTO} server ${OVPN_POOL} topology subnet client-to-client keepalive 10 120 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>${NL}${OVPN_DH}${NL}</dh> <tls-crypt>${NL}${OVPN_TC}${NL}</tls-crypt> <ca>${NL}${OVPN_CA}${NL}</ca> <cert>${NL}${OVPN_CERT}${NL}</cert> <key>${NL}${OVPN_KEY}${NL}</key> EOF done /etc/init.d/openvpn restart OVPN_POOL="192.168.8.0 255.255.255.0" 定义的地址池不要和内网已有的地址冲突 push "redirect-gateway def1" 是将 OpenVPN 的网关作为默认网关,会创建默认路由指向 OpenVPN 的网关,如果只是需要访问家里的网络,可将这条按需要修改,如push "route 192.168.1.0 255.255.255.0 192.168.8.1"
用ip addr show tun0和cat /var/run/openvpn.server.status确认一下 OpenVPN 运行状态
生成客户端 ovpn 文件
# 先确定使用 DDNS 还是公网 IP 作为 OpenVPN 连接使用,并配置好 OVPN_SERV 参数,本次以 DDNS 地址为例子 OVPN_SERV="ddns.example.com" # Configuration parameters OVPN_DIR="/etc/openvpn" OVPN_PKI="/etc/easy-rsa/pki" OVPN_DEV="$(uci get firewall.lan.device | sed -e "s/^.*\s//")" OVPN_PORT="$(uci get firewall.ovpn.dest_port)" OVPN_PROTO="$(uci get firewall.ovpn.proto)" OVPN_TC="$(sed -e "/^#/d;/^\w/N;s/\n//" ${OVPN_PKI}/tc.pem)" OVPN_CA="$(openssl x509 -in ${OVPN_PKI}/ca.crt)" NL=$'\n' # Generate VPN client profiles umask u=rw,g=,o= grep -l -r -e "TLS Web Client Auth" "${OVPN_PKI}/issued" \ | sed -e "s/^.*\///;s/\.\w*$//" \ | while read -r OVPN_ID do OVPN_CERT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt)" OVPN_KEY="$(cat ${OVPN_PKI}/private/${OVPN_ID}.key)" cat << EOF > ${OVPN_DIR}/${OVPN_ID}.ovpn verb 3 dev ${OVPN_DEV%%[0-9]*} nobind client remote ${OVPN_SERV} ${OVPN_PORT} ${OVPN_PROTO} auth-nocache remote-cert-tls server <tls-crypt>${NL}${OVPN_TC}${NL}</tls-crypt> <ca>${NL}${OVPN_CA}${NL}</ca> <cert>${NL}${OVPN_CERT}${NL}</cert> <key>${NL}${OVPN_KEY}${NL}</key> EOF done ls ${OVPN_DIR}/*.ovpn 将该 ovpn 导入到 OpenVPN 的客户端就可以链接上 OpenVPN 服务器
至此一般的 OpenVPN Server 配置已经完成,目前存在的问题就是一个证书只能连接上一个客户端,下一步就是将会配置多用户的方案。
2.多用户模式
多用户方案有两种,一种是生成多个证书文件,每个用户单独使用一个证书;另外一种就是使用单证书配合用户密码的形式。
这两种都会贴一下配置,因为连回家主要是为了方便,所以会以用户名密码的方式为主。
多证书方式:
需要生成另外一组用户公钥和私钥
# Configuration parameters export EASYRSA_PKI="/etc/easy-rsa/pki" # Add one more client easyrsa --batch build-client-full client1 nopass 然后在/etc/easy-rsa/pki/issued找到client1.crt,在/etc/easy-rsa/pki/private找到client1.key
将client1.crt的 cert 和client1.key的 key 替换 ovpn 文件中的<cert><key>段即可生成给第二位用户的 ovpn 文件</key></cert>
单证书多用户模式:
创建用户认证脚本(checkpsw.sh)
/etc/openvpn/checkpsw.sh
#!/bin/sh ########################################################### # checkpsw.sh (C) 2004 Mathias Sundman <[email protected]> # # This script will authenticate OpenVPN users against # a plain text file. The passfile should simply contain # one row per user with the username first followed by # one or more space(s) or tab(s) and then the password. PASSFILE="/etc/openvpn/psw-file" LOG_FILE="/etc/openvpn/openvpn-password.log" TIME_STAMP=`date "+%Y-%m-%d %T"` ########################################################### if [ ! -r "${PASSFILE}" ]; then echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE} exit 1 fi CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}` if [ "${CORRECT_PASSWORD}" = "" ]; then echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE} exit 1 fi if [ "${password}" = "${CORRECT_PASSWORD}" ]; then echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE} exit 0 fi echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE} exit 1 配置执行权限
chmod +x /etc/openvpn/checkpsw.sh
配置用户密码文件
/etc/openvpn/psw-file user1 passwd1 user2 passwd2
修改服务端配置文件
在/etc/openvpn/server.conf后面添加
script-security 3 auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env username-as-common-name verify-client-cert none 修改客户端配置文件
删除掉<cert>和<key>
添加如下内容:
auth-user-pass
那样就可以使用用户密码登录了。
3.OpenWRT Luci 集成
这一步主要是方便在 OpenWRT 的 Web 界面方便看到 OpenVPN 的状态信息
确保已经安装好
opkg install luci-app-openvpn
通过命令修改 luci 配置
# Provide VPN instance management ls /etc/openvpn/*.conf \ | while read -r OVPN_CONF do OVPN_ID="$(basename ${OVPN_CONF%.*} | sed -e "s/\W/_/g")" uci -q delete openvpn.${OVPN_ID} uci set openvpn.${OVPN_ID}="openvpn" uci set openvpn.${OVPN_ID}.enabled="1" uci set openvpn.${OVPN_ID}.cOnfig="${OVPN_CONF}" done uci commit openvpn /etc/init.d/openvpn restart refer:
3.原文链接
1 cwbsw 2019-11-29 11:13:18 +08:00 考虑性能,换 wireguard。 考虑 QoS 和方便客户端接入,换 ipsec。 |
2 bilibilifi 2019-11-29 11:14:30 +08:00 via iPhone 还用 openvpn... WireGuard 不香吗? |
3 hiplon OP WireGuard 按我理解是不是应该做 site2site 比较方便,但是 dial up 可能不是很好管理? |
4 buddha 2019-11-29 12:21:12 +08:00 OpenConnect/AnyConnect 也是用的 UDP |
6 zro 2019-11-29 13:36:34 +08:00 是我,会继续选择 WireGuard 吧。。比 OpenVPN 轻量多了,或者在 OpenWRT 部署 5S 也简单些吧? |
7 hiplon OP 等我看看 wireguard 下面有没方便一点的 peers 管理,到时再试一下 |
8 hiplon OP @cwbsw #5 如果用户更多一般是加 RADIUS 上的,主要是自己家宽也有几个朋友( 5-6 )个经常会一起连局域网打翔鹰帝国,这个时候还是不得不考虑下用户的问题,之前 openconncent 就很适合这种场景 |
9 Archeb 2019-11-29 14:56:16 +08:00 via Android 我建议 softether vpn 一次满足你的三个愿望(l2tp-ipsec sstp openvpn sevpn) |
10 immike 2020-02-17 13:12:44 +08:00 有支持 Wireguard 的 IP 话机吗? |
11 hanssx 2022-09-21 19:14:55 +08:00 比较难受得是 Wg 是 UDP ,如果要弄成 TCP ,Windows 下没有好用的工具,udp2raw 一直握手失败。 |