OpenWRT 搭建 OpenVPN 服务器 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hiplon
V2EX    宽带症候群

OpenWRT 搭建 OpenVPN 服务器

  •  1
     
  •   hiplon 2019-11-29 11:00:42 +08:00 29264 次点击
    这是一个创建于 2194 天前的主题,其中的信息可能已经有所发展或是发生改变。

    主要实现在 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 

    OpenWRT Firewall

    生成服务器和客户端证书

    # 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 tun0cat /var/run/openvpn.server.status确认一下 OpenVPN 运行状态

    OpenVPN Status

    生成客户端 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 服务器

    Connection Status

    至此一般的 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 

    Luci Status

    refer:

    1.OpenVPN basic

    2.Openvpn 2.4 设置用户密码认证

    3.原文链接

    11 条回复    2022-09-21 19:14:55 +08:00
    cwbsw
        1
    cwbsw  
       2019-11-29 11:13:18 +08:00   1
    考虑性能,换 wireguard。
    考虑 QoS 和方便客户端接入,换 ipsec。
    bilibilifi
        2
    bilibilifi  
       2019-11-29 11:14:30 +08:00 via iPhone
    还用 openvpn... WireGuard 不香吗?
    hiplon
        3
    hiplon  
    OP
       2019-11-29 11:18:58 +08:00
    WireGuard 按我理解是不是应该做 site2site 比较方便,但是 dial up 可能不是很好管理?
    buddha
        4
    buddha  
       2019-11-29 12:21:12 +08:00
    OpenConnect/AnyConnect 也是用的 UDP
    cwbsw
        5
    cwbsw  
       2019-11-29 13:27:19 +08:00   1
    @hiplon 目前是这样没错。但你的用户多到需要考虑管理问题了吗?
    zro
        6
    zro  
       2019-11-29 13:36:34 +08:00
    是我,会继续选择 WireGuard 吧。。比 OpenVPN 轻量多了,或者在 OpenWRT 部署 5S 也简单些吧?
    hiplon
        7
    hiplon  
    OP
       2019-11-29 14:02:53 +08:00
    等我看看 wireguard 下面有没方便一点的 peers 管理,到时再试一下
    hiplon
        8
    hiplon  
    OP
       2019-11-29 14:38:16 +08:00
    @cwbsw #5 如果用户更多一般是加 RADIUS 上的,主要是自己家宽也有几个朋友( 5-6 )个经常会一起连局域网打翔鹰帝国,这个时候还是不得不考虑下用户的问题,之前 openconncent 就很适合这种场景
    Archeb
        9
    Archeb  
       2019-11-29 14:56:16 +08:00 via Android
    我建议 softether vpn 一次满足你的三个愿望(l2tp-ipsec sstp openvpn sevpn)
    immike
        10
    immike  
       2020-02-17 13:12:44 +08:00
    有支持 Wireguard 的 IP 话机吗?
    hanssx
        11
    hanssx  
       2022-09-21 19:14:55 +08:00
    比较难受得是 Wg 是 UDP ,如果要弄成 TCP ,Windows 下没有好用的工具,udp2raw 一直握手失败。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2916 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 13:52 PVG 21:52 LAX 05:52 JFK 08:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86