Day_22 OpenVPN

前几天所述让我们能够连线回所架设的openwrt方法,虽然方便快速但比较粗糙,可以看到我连https部分也没有提到,因为免费的ddns几乎不提供ssl凭证,後续有机会再来补完。另外,开了port之後,建议连回的设备要备有防护功能阻止有骇客或爬虫破解。
介绍另一个相对安全的连线方式"VPN"。使用加密穿隧协定建立安全的虚拟私人网路,阻止截听与嗅探也避免资讯被窜改。依照不同协定可区分许多项,如:PPTP/L2TP/IPsec/WireGuard/OpenVPN等数样,今天来尝试安装及建立"OpenVPN"。

虚拟私人网路(英语:virtual private network,缩写:VPN)是常用於连接中、大型企业或团体间私人网路的通讯方法。它利用隧道协定(Tunneling Protocol)来达到传送端认证、讯息保密与准确性等功能。

OpenVPN是一个用於建立虚拟私人网路加密通道的软件套件,最早由James Yonan编写。OpenVPN允许建立的VPN使用公开金钥、电子凭证、或者使用者名称/密码来进行身分验证。它大量使用了OpenSSL加密库中的SSL/TLS协定函式库。

在OpenWRT doc中其实已经将openVPN步骤介绍得十分详细,透过CLI命令介面去设定与建立公/私钥、凭证等,按步骤就能取得client端的设定档。

  • 以命令介面登入openwrt,先安装这次会用上的套件

    opkg update
    opkg install openvpn-easy-rsa openvpn-mbedtls luci-app-openvpn 
    
  • OpenVPN参数配置设定

    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)"
    
  • 设定连线目标IP,因为我们已经在使用ddns服务,所以填上DDNS的网址

    OVPN_SERV="IP or Hostname"
    
  • 金钥制作。使用EasyRSA管理PKI,先进行设置

    export EASYRSA_PKI="${OVPN_PKI}"
    export EASYRSA_REQ_CN="ovpnca"
    export EASYRSA_BATCH="1"
    
  • 重新初始化pki设置
    easyrsa init-pki

  • 产生DH,这步骤会花点时间,等它跑完再往下
    easyrsa gen-dh

  • 建立新ca
    easyrsa build-ca nopass

  • 生成密钥
    easyrsa build-server-full server nopass

  • 建立client端密钥,要让几个帐户连入这边就重复输入不同的client名称,如下图
    easyrsa build-client-full client nopass

  • 生成 TLS PSK
    openvpn --genkey secret ${OVPN_PKI}/tc.pem

  • 防火墙与埠口设置,最後需要重启

    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
    
  • 配置 VPN服务并产生client端配置文件,最後列出所生成的key

umask go=
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)"
ls ${OVPN_PKI}/issued \
| sed -e "s/\.\w*$//" \
| while read -r OVPN_ID
do
OVPN_KEY="$(cat ${OVPN_PKI}/private/${OVPN_ID}.key)"
OVPN_CERT="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt)"
OVPN_EKU="$(openssl x509 -in ${OVPN_PKI}/issued/${OVPN_ID}.crt -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>
${OVPN_TC}
</tls-crypt>
<key>
${OVPN_KEY}
</key>
<cert>
${OVPN_CERT}
</cert>
<ca>
${OVPN_CA}
</ca>
EOF
done
/etc/init.d/openvpn restart
ls ${OVPN_DIR}/*.ovpn

  • 可用FTP或其他软件下载key。或用cat指令秀出配置档内容,复制全部内容并用文字档存下修改副档名(有点多,要全部复制到)

client 端设定与使用

到OpenVPN的client software下载对应作业系统的软件并安装。开启後会在隐藏的工作列里,汇入*.ovpn

点选连线,测试看是不是已经连入opevpn server

Troubleshooting

目前还在翻车查修中。安装luci-app-openvpnluci-i18n-openvpn-zh-tw可以在luci介面看到设定配置。
许多配置(如网卡介面/防火墙)确实有新增,但openvpn按理设定完应该会出现一个新的项目且启动,但目前只有原先几个样板。

另win系统中用"tracert"(linux使用"traceroute"),可以追踪封包传递到目的地所经的路径和时间。

# win
tracert openwrt.org
# linux
traceroute openwrt.org

Ref


<<:  [Day19] 团队管理:绩效对谈

>>:  【第二十天 - PHP反序列化(2)】

Unity与Photon的新手相遇旅途 | Day27-Photon角色同步控制设定

今天内容为设定PlayerController.cs的程序码,让角色控制能够顺利同步,以及修正之前的...

DAY 13 - 时钟怪 (2)

大家好~ 我是五岁~ 今天来继续把昨天未上色的时钟怪完成吧~!! 首先把昨天的成品做些微调 接下来就...

Vue.js 从零开始:props 元件的沟通

上篇component元件有说到每个元件范围都应该是独立的,更不应该发生子元件直接改变根元件的情况,...

【Day-29】我们是怎麽开始的?:一间传统软件公司从 0 开始建置的 DevOps 文化(心态篇)- 提供选择,别找藉口

前言 最後两天就让我们来谈谈做 DevOps 与软件的心态。 很多时候解释常常会变成一种藉口的感觉,...

array.filter()

array.filter(function(...){...}) filter是一种高阶函数 他的参...