使用树莓派搭建 PPTP VPN 的 WiFi 热点
1 背景
为了响应国家的号召,媳妇的公司也让在家办公了,她们公司也提供了 VPN 方便访问公司内网。但是 VPN 用的是 PPTP 协议,由于安全原因,macOS 已不再支持此协议,甚至从 Catalina 开始,从内核移除了相关代码。
因为 VPN 是公司提供的,因此不考虑更换协议的可能性,摆在面前的选项就只有:
- 使用 Windows 办公。
- 使用第三方 macOS VPN 客户端(但都是收费的)。
- 自己折腾。
想到家里还有个正在吃灰的树莓派,正好可以练练手,因此选择了自己折腾。
2 方案
手头可用的材料有:
- 树莓派 3B + 一只,这个型号预置了 WiFi 模块,无需另接无线网卡。
- 支持树莓派的 Linux 系统:ArchLinux ARM。
目标方案为:树莓派通过有线网连接 VPN,用 WiFi 做热点,将从热点进来的流量全部导向 VPN。macOS 只需要连接树莓派的热点,即可通过 VPN 访问公司内网。
3 操作步骤
首先分解一下需要进行的操作:
- 连接 PPTP VPN。
- 配置 WiFi 热点。
- 将来自 WiFi 热点的流量导向 VPN。
下面就基于 ArchLinux ARM,介绍每一步的操作。
操作过程中的大部分指令,都需要以 root 权限执行,因此请先切换到 root 用户。如果不想切换到 root 用户,请在每个指令前加上 sudo
。
3.1 连接 PPTP VPN
在连接 VPN 之前,首先需要确保树莓派连接的有线网络的 IP 段,不与 VPN 的内网 IP 段相冲突。
假设 VPN 的内网 IP 段是 192.168.1.0/24
,那么树莓派的有线网络 IP 段不能与这个 IP 段有任何交集,比如使用 172.16.1.0/24
。
3.1.1 安装软件包
1 | pacman -Sy pptpclient |
有些 Linux 发行版已经预置了这个软件包,安装前可以先执行 pptpsetup --help
,检查一下软件包是否已经存在。
3.1.2 配置 VPN
1 | # 这里我们创建了一个VPN配置,将其命名为:officevpn |
3.1.3 连接 / 断开 VPN
1 | # 连接VPN |
3.1.4 查看 VPN 状态
执行命令 ip addr show
,查看所有的网络连接。
如果列表中有一个名字以”ppp” 开头的网络连接,且成功分配了 IP,即表示 VPN 连接成功。
3.2 配置 WiFi 热点
配置 WiFi 热点时,同样也需要为热点网络选择一个子网 IP 段,这个 IP 段也是不能与 VPN 内网的 IP 段冲突,另外最好也不要与有线网络的 IP 段冲突,例如使用 10.1.1.0/24
。
3.2.1 安装软件包
1 | pacman -Sy dnsmasq hostapd |
如果你比较习惯使用
NetworkManager
,也可以用它来配置热点,这里只是以dnsmasq
+hostapd
来举例。
3.2.2 配置 DHCP 客户端
首先我们需要为 WiFi 网卡配置一个静态 IP:10.1.1.1
。
备份并编辑文件”/etc/dhcpcd.conf”,在文件最后追加如下内容:
1 | interface wlan0 |
重启服务:
1 | systemctl restart dhcpcd |
3.2.3 配置 dnsmasq
在这里,仅将 dnsmasq 作为 DHCP 服务器来使用。
备份并编辑文件”/etc/dnsmasq.conf”,在里面添加如下内容:
1 | interface=wlan0 |
安装并启动 dnsmasq 服务:
1 | # 安装服务 |
3.2.4 配置 hostapd
hostapd 的配置文件为”/etc/hostapd/hostapd.conf”,如果文件已存在,建议将其改名备份,之后新建一份空白的同名文件,输入如下内容:
1 | interface=wlan0 |
配置中的”WiFi 名称” 和”WiFi 密码” 两项,可根据实际情况修改。其他参数,如果你不了解其意义,建议不要修改。
安装并启动 hostapd 服务:
1 | # 安装服务 |
3.2.5 测试热点
使用手机或者一台电脑,尝试搜索并连接前面配置的 WiFi。
如果能够成功连接到 WiFi,并分配到了一个在”10.1.1.2”~”10.1.1.255” 之间的 IP,即表示一切正常。
当然,这个阶段你还无法通过这个热点上网,这是接下来要做的事情。
3.3 流量转发
这里我们不需要任何第三方软件包,直接使用系统自带的 iproute2
和 iptables
工具包来搞定。
请先通过如下命令,判断一下你的系统是否有对应的工具包:
1 | # 测试iproute2 |
回顾一下方案,我们的需求是将所有来自 WiFI 热点的流量,导向 VPN 连接。因此,首先需要为所有来自 WiFi 热点的数据包做一个标记,然后将这些数据包全部转发到 VPN 连接。
3.3.1 启用数据包转发
1 | # 开启数据包转发 |
为了让该配置在重启后仍然生效,创建文件”/etc/sysctl.d/ip-forward.conf”,并在其中添加如下内容:
1 | net.ipv4.ip_forward=1 |
3.3.2 配置转发规则
在配置规则前,首先需要获取 VPN 连接的一些信息。
执行命令 ip addr show
,找到 ppp
开头的 VPN 连接信息,例如:
1 | 4: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1496 qdisc fq_codel state UNKNOWN group default qlen 3 |
记下其中的连接名称(例子中为 ppp0)和 peer IP(例子中为 192.168.1.33)。
现在开始配置转发规则:
1 | # 这里我们自定义了一个路由表,将其编号定义为201 |
配置完上述规则后,连接 WiFI 热点的设备,即可直接访问公司内网的资源。
3.3.3 自动配置
上一步配置的所有规则,都是不存盘的,因此每次连接 VPN 之后,都要重新配置。
所幸 pptpclient 提供了 hook 机制,当 pptp 连接建立成功时,它自动会执行”/etc/ppp/ip-up.d/“下面的所有”.sh” 脚本。因此我们可以创建一个 hook 脚本,实现自动配置规则。
在”/etc/ppp/ip-up.d/“下面创建文件” auto-hotspot.sh”,写入如下内容:
1 | #!/bin/sh |
最后,不要忘记为 hook 脚本添加执行权限:
1 | chmod a+x /etc/ppp/ip-up.d/auto-hotspot.sh |