Blog:
嵌入式 Linux 系统 VPN 应用

Thursday, January 28, 2021

联网需求在各种嵌入式应用中正开始变得越来越普遍,随之而来就是数据传输的安全挑战。VPN 是应对该挑战的有效措施。除此之外,VPN 还能够穿透防火墙或者 NAT 实现异地组网,从而提供远程访问设备的功能。文章接下来在运行 Linux 系统的 Apalis iMX8QM 上演示如何使用 OpenVPN 和 WireGuard 两种 VPN 方案。

OpenVPN 一种使用较为广泛的 VPN,其基于 OpenSSL 提供多种加密方案,采用 TCP 或者 UDP 作为传输层协议,具有非常高的灵活性。WireGuard 是一种更加高效、快速、简单的 VPN 方案,最初直接基于 Linux 内核实现,支持最新的加密算法如Curve25519、ChaCha20、Poly1305、BLAKE2 等,传输层采用 UDP 协议。自 Linux 5.6 开始,WireGuard 已经集成到内核中,目前拥有非常活跃的开发群体,支持 Windows、macOS、BSD、iOS、Android。Toradex 针对其模块发布的 BSP 采用 Yocto 构建,OpenVPN 和 WireGuard 在 Yocto 中可以很方便得添加进来。

首先在 local.conf 配置文件添加一下内容,apache 网站服务器用于后面的远程连接演示。

IMAGE_INSTALL_append = " apache2 openvpn wireguard-module wireguard-tools"

修改 layers/meta-openembedded/meta-networking/recipes-kernel/wireguard/wireguard-module_1.0.20200401.bb,注释掉 PKG_${PN} = "kernel-module-${MODULE_NAME}"

# Kernel module packages MUST begin with 'kernel-module-', otherwise
# multilib image generation can fail.
#
# The following line is only necessary if the recipe name does not begin
# with kernel-module-.
#PKG_${PN} = "kernel-module-${MODULE_NAME}"

WireGuard 基于 Linux 内核实现,为了保证其代码的精简,其复用了内核中很多的网络功能,因此需要修改默认的内核配置。如果使用 OpenVPN ,则可以跳过该步骤,直接编译 BSP。

$ MACHINE=apalis-imx8 bitbake -c menuconfig virtual/kernel

Networking support → Networking options
[*]   IP: advanced router
[*]     FIB TRIE statistics
[*]     IP: policy routing 
[*]     IP: equal cost multipath  
[*]     IP: verbose route monitoring

Networking support → Networking options → Network packet filtering framework (Netfilter) → IP: Netfilter Configuration
<M>   raw table support (required for NOTRACK/TRACE) 

Networking support → Networking options → Network packet filtering framework (Netfilter) → Core Netfilter Configuration
<M>   "CONNMARK" target support 
<M>   "MARK" target support

*** Xtables matches ***  
<M>   "comment" match support
<M>   "mark" match support 
<M>   "connmark" connection mark match support  

完成配置后编译 BSP

$ MACHINE=apalis-imx8 bitbake tdx-reference-minimal-image

在开始配置之前,我们先介绍下测试所使用的网络拓扑。如下图所示,首先需要一台具有公网 IP 的服务器作为 VPN 服务器。 Apalis iMX8QM 通过以太网连接电信运营商提供的光猫。目前光猫通常只能获取的经过电信运营商 NAT 转换后的内网 IPv4 地址。用于测试的手机则通过基站接入公网。  

VPN 服务器设置

OpenVPN 和 WireGuard 官网均提供了详细的服务器配置说明。这里我们使用另外一个工具 PiVPN 来设置服务器。PiVPN 最初是为树莓派提供简单的服务器管理工具,但同样可以用于任何基于 Debian 发行版本,如 Ubuntu。运行下面命令即可安装。

curl -L $ https://install.pivpn.io | bash

运行pivpn 分别为 Apalis iMX8 和手机添加 OpenVPN 和 WireGuard 账户。

$ pivpn ovpn add
$ pivpn wg add

修改服务器网络配置

$ sudo iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT 
$ vi /etc/sysctl.conf
net.ipv4.ip_forward = 1
$ sysctl -p /etc/sysctl.conf

手机端设置

在手机上安装 OpenVPN 和 WireGuard 客户端,然后导入上面 PiVPN 生成的 ovpn 或者 conf 文件,亦或通过扫二维码。PiVPN 均提供十分易于使用的功能。

Apalis iMX8QM 设置

使用 system-networkd 作为网络管理器

root@apalis-imx8:~# systemctl disable connman
root@apalis-imx8:~# ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

将网络设置动态获取 IP 方式。

root@apalis-imx8:~# vi /etc/systemd/network/wired.network
[Match]
Name=eth0

[Network]
DHCP=ipv4

修改 Apache 网页服务器默认显示内容。其他客户端可以用 HTTP 访问该网页。

/usr/share/apache2/default-site/htdocs/index.html
<html><body><h1>It works! Apalis iMX8.</h1></body></html>

OpenVPN

开启 OpenVPN 连接

root@apalis-imx8:~# openvpn apalis-imx8.ovpn 

成功运行后会看到如下信息:

Thu Jan 28 03:16:44 2021 OpenVPN 2.4.9 aarch64-tdx-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on Apr 16 2020
Thu Jan 28 03:16:44 2021 library versions: OpenSSL 1.1.1i  8 Dec 2020, LZO 2.10
Enter Private Key Password:

Thu Jan 28 03:16:52 2021 /sbin/ip link set dev tun0 up mtu 1500
Thu Jan 28 03:16:52 2021 /sbin/ip addr add dev tun0 10.8.0.5/24 broadcast 10.8.0.255
Thu Jan 28 03:16:52 2021 /sbin/ip route add 125.107.107.37/32 via 192.168.123.1
Thu Jan 28 03:16:52 2021 /sbin/ip route add 0.0.0.0/1 via 10.8.0.1
Thu Jan 28 03:16:52 2021 /sbin/ip route add 128.0.0.0/1 via 10.8.0.1
Thu Jan 28 03:16:52 2021 Initialization Sequence Completed

使用 ifconfig 命令可以看到如下 tun0 接口。分配的IP 为 10.8.0.5。在其他连接到该 VPN 的客户端上可以使用该 IP 来访问 Apalis iMX8QM。

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
        inet addr:10.8.0.5  P-t-P:10.8.0.5  Mask:255.255.255.0
        inet6 addr: fe80::cd6f:13cd:62e9:4d1e/64 Scope:Link
        UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
        RX packets:2 errors:0 dropped:0 overruns:0 frame:0
        TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:100 
        RX bytes:190 (190.0 B)  TX bytes:1006 (1006.0 B)

在手机上连接  OpenVPN ,分配到的 IP 为 10.8.0.3。通过手机上的浏览器访问 Apalis iMX8QM 上的网页 http://10.8.0.5。

 

WireGuard 

将 PiVPN 生成的配置文件 apalis-imx8.conf 复制到 /etc/wireguard/wg0.conf,然后运行

root@apalis-imx8:~# wg-quick up wg0

使用 ifconfig 可以看到 wg0 接口,此时分配到的 IP 为 10.6.0.5。

wg0       Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
        inet addr:10.6.0.5  P-t-P:10.6.0.5  Mask:255.255.255.0
        UP POINTOPOINT RUNNING NOARP  MTU:1420  Metric:1
        RX packets:63 errors:0 dropped:0 overruns:0 frame:0
        TX packets:127 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000 
        RX bytes:6540 (6.3 KiB)  TX bytes:15988 (15.6 KiB)

在手机上启动 WireGuard 应用,访问 Apalis iMX8QM 上的网页 http://10.6.0.5。

总结

VPN 可以将不同网络的设备进行组网实现互联,方便远程管理。但同时也需要注意服务器的安全防护,通过该服务器可以获取到连接设备信息,包括登录验证信息。

Author: 胡珊逢,FAE,韬睿(上海)

Leave a comment

Please login to leave a comment!
Have a Question?