OpenVPN Linux 客户端未启动 tap0 接口

OpenVPN Linux 客户端未启动 tap0 接口

我在 Linux 上有一个 OpenVPN 客户端,连接到 OpenVPN 服务器。服务器通过 DHCP 分配 IP,因此我使用轻敲界面而不是界面。

OpenVPN 连接、验证、与服务器聊天、喝杯咖啡,但却忘了打开 tap0 接口。连接后,我必须手动运行ifup tap0以打开接口并获取 IP。

我尝试在配置文件中添加一个运行的脚本

ip link set tap0 up
dhclient tap0

但它只启动了设备,并没有获取 IP。

清理后的client.conf:

# Openvpn config to connect to <DOMAIN>
tls-client
dev tap0
; dev tap ; this didn't work either

; run script after init (supposedly)
; script-security 2 ; to run up script
; up /etc/openvpn/tap0up.sh ; bring up tap0
; up-delay ; Didn't work with or without this; 

proto udp
remote <DOMAIN> 1194
resolv-retry infinite
nobind
persist-key
persist-tun

ca ca.crt
cert monkey.crt
key monkey.key

ns-cert-type server
comp-lzo
verb 3

还有 ifcfg-tap0,因为我不相信 NetworkManager

DEVICE=tap0
BOOTPROTO=dhcp
ONBOOT=yes
PEERDNS=no
ZONE=trusted

提前致谢!

编辑:有趣的事实:它将正确的静态路由添加到我的路由表中,用于它忘记启动的网络。

编辑2:OpenVPN 服务器配置,根据要求:

local <my.ext.ip>
port 1194
mode server
tls-server
proto udp

dev tap0
; dev tap

ca keys/ca.crt
cert keys/zombie.crt
key keys/zombie.key
dh keys/dh2048.pem

keepalive 10 120
comp-lzo

persist-key
persist-tun

status zombievpn-status.log
verb 3

答案1

根据我的经验,让 TAP 设备在 Ubuntu 17.10 及更高版本(以及使用 systemd-resolved 和/或网络管理器的其他操作系统)上运行良好并非易事,但经过大量实验后,我找到了一种运行良好的设置。

在描述我的解决方案之前,先介绍一下我的情况和要求。我在家庭网络中的路由器(带有 Asus Merlin 固件的 Asus RT-AC87U)上运行 OpenVPN 服务器,该路由器还运行 DHCP 服务器。DHCP 服务器配置为分发 TAP 接口的 IP,并推送 DNS 搜索域。这允许通过主机名发现连接的系统(例如,主机名为“desktop”的系统可以作为“desktop”被发现,由于搜索域为“mydomain.com”,因此扩展为“desktop.mydomain.com”)。我使用 TAP 网络,这样我就可以直接通过隧道使用局域网唤醒(局域网唤醒魔术包必须在 xxx255 地址上广播到应该唤醒系统的网络适配器的 MAC 地址,这是 TUN 设备无法做到的,因为它在错误的网络层运行,无法广播 2 级包)。服务器必须能够将 DNS 选项推送到客户端。我不希望所有互联网流量都通过隧道路由 - 这不是那种 VPN(我在另一个端口上运行单独的 TUN 服务器以用于该用例,但这超出了此答案的范围)。最后,当我关闭隧道时,我需要一切都恢复到原始状态(这不会自动发生)。

事实证明,所有的实验都很困难。最终,解决方案的配置并不复杂。我从 Ubuntu 存储库安装了 OpenVPN,撰写本文时版本为 2.4.4。

OpenVPN 服务器使用以下配置(服务器在 10.75.233.1(也是网关 IP)上运行 DNSMasq,用作 DHCP 服务器):

# Automatically generated configuration
daemon ovpn-server1
server-bridge   # proxy the DHCP server
push "route 0.0.0.0 255.255.255.255 net_gateway"
proto udp
port 1194
dev tap21
ncp-ciphers AES-256-GCM
auth SHA384
comp-lzo adaptive
keepalive 15 60
verb 2
push "dhcp-option DNS 10.75.233.1"   # Pushes the DNS server
tls-crypt static.key
ca ca.crt
dh dh.pem
cert server.crt
key server.key
crl-verify crl.pem
status-version 2
status status 5

# Custom Configuration
mssfix 1420  # You might not need this, it depends on your local network conditions
tun-mtu 1500  # You might not need this, it depends on your local network conditions
tls-version-min 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384

这些都不是那么有趣。这是客户端配置:

client
dev tap0
persist-tun
persist-key
proto udp
remote mydomain.com 1194
float
ncp-ciphers AES-256-GCM
auth sha384
comp-lzo adaptive
remote-cert-tls server
auth-nocache
tls-version-min 1.2
verb 2

ca /etc/openvpn/secrets/mydomain/ca.crt
cert /etc/openvpn/secrets/mydomain/client.crt
key /etc/openvpn/secrets/mydomain/client.key
tls-crypt /etc/openvpn/secrets/mydomain/ta.key

resolv-retry infinite
nobind

这也不是那么有趣,除了一件事——没有上/下脚本 [blow mind gif here]。

这样做的原因是,我认为让现有的操作系​​统服务尽可能地处理是最优雅的做法——换句话说,顺应操作系统的脉络而不是违背它。安装的默认启动/关闭脚本用于操作/etc/resolv.conf,Ubuntu 18.04 不再(直接)使用。它使用 systemd-resolved。直接操作 resolv.conf 会导致许多泪水,年轻的绝地武士。然而,这并没有导致 Ubuntu 开发人员默认为 systemd-resolved 安装启动/关闭脚本。这取决于你(sudo apt install openvpn-systemd-resolved——脚本将位于/etc/openvpn)。根据我的经验,它们适用于 TUN 设备,但也不能正确完成 TAP 设备的工作。

效果非常好的是,明确将 tap0 设备添加到您的网络接口(/etc/network/interfaces):

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

allow-hotplug tap0
iface tap0 inet dhcp

使用以下命令重新启动网络堆栈:

sudo systemctl daemon-reload
sudo systemctl restart networking

砰!操作系统现在将自行查询 DHCP 服务器并启动适配器,就像普通接口一样。当您连接到服务器时,ifconfig tap0应该会显示一个分配了 IP 地址的适配器。此外,systemd-resolve --status在输出的第一行应该会显示 OpenVPN 服务器推送的 DNS 搜索域和 DNS 服务器已设置为全局配置,并且快速操作nslookup desktop现在应该可以正常工作(前提是主机存在于隧道另一侧的某个地方)。

然而,当您关闭隧道时,这会导致一些问题。它关闭得很好,并且 tap0 设备在 ifconfig 输出中不再可见。但是,这将向systemd-resolve --status您显示您的搜索域和 DNS 服务器在很大程度上继续成为您存在的一部分。就我而言,因为我运行 VPN 服务器的域是“mydomain.com”,而搜索域也是“mydomain.com”,这导致我在隧道关闭后无法再次连接到 VPN 服务器,因为只要 systemd-resolved 仍然对讨厌的搜索域感到困惑,它的实际 IP 就无法再解析。重新启动 systemd-resolved 服务并不能解决问题,但重新启动可以。哦,致命的痛苦!

值得庆幸的是,这个问题也有解决办法。原来,在 处创建了一个临时配置文件,/run/systemd/resolved.conf.d/isc-dhcp-v4-tap0.conf导致 systemd-resolved 顽固地连接到我的 VPN 服务器的 DNS 服务器。删除该文件然后重新启动服务即可解决问题 ( sudo rm /run/systemd/resolved.conf.d/isc-dhcp-v4-tap0.conf && sudo systemctl restart systemd-resolved.service)。

因此,对于基本设置,这已经足够了。但是,我喜欢这种奢侈,我们可以使用一个不错的 systemd 服务来为我们提供它!请注意,使用 Ubuntu 的 OpenVPN 包,所有 OpenVPN 配置都可以使用“通配符”systemd 服务/etc/openvpn/client。您可以查看位于 的单元文件。它可以通过 进行控制。它完全适用于 TUN 样式的隧道,所以不要管它。我们将复制它以用于 TAP 设备。/lib/systemd/system/[email protected]sudo systemctl start [email protected]

创建文件/lib/systemd/system/openvpn-my-tap-service-name.service并添加:

[Unit]
Description=OpenVPN tunnel for mydomain.com
After=syslog.target network-online.target
Wants=network-online.target
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO

[Service]
Type=notify
PrivateTmp=true
WorkingDirectory=/etc/openvpn/client
ExecStart=/usr/sbin/openvpn --suppress-timestamps --nobind --config mydomain.com.conf
ExecStopPost=/etc/openvpn/post-tap0-service-stop.sh  # Removes search domain and DNS server from systemd-resolved config
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
ProtectSystem=true
ProtectHome=true
KillMode=process

[Install]
WantedBy=multi-user.target

这是默认服务的简单改编。要使其工作,您的客户端配置必须位于/etc/openvpn/client/mydomain.com.conf。只添加了一件事 - 一个小脚本来删除“临时”的 systemd 解析配置文件。

创建文件/etc/openvpn/post-tap0-service-stop.sh 并将其设置为可执行(使用chmod +x /etc/openvpn/post-tap0-service-stop.sh):

#!/bin/bash

FILE_MESSING_WITH_SYSTEMD_RESOLVED=/run/systemd/resolved.conf.d/isc-dhcp-v4-tap0.conf

echo "Removing $FILE_MESSING_WITH_SYSTEMD_RESOLVED..."
rm -f $FILE_MESSING_WITH_SYSTEMD_RESOLVED 

echo "Restarting systemd-resolved service..."
systemctl restart systemd-resolved.service

好了!现在您可以使用它来控制 OpenVPN 了sudo systemctl start/stop/restart/status openvpn-my-tap-service-namesudo systemctl daemon-reload当然,是在创建服务文件之后)。

只剩最后一步了。一直用密码控制服务很麻烦。我们可以通过将控制服务所需的命令添加到 sudoers 文件来解决这个问题。

执行以下命令pkexec visudo -f /etc/sudoers.d/openvpn并输入以下内容:

Cmnd_Alias OPENVPN = /bin/systemctl start openvpn-my-tap-service-name, \
                     /bin/systemctl stop openvpn-my-tap-service-name, \
                     /bin/systemctl restart openvpn-my-tap-service-name

%my-username ALL= NOPASSWD: OPENVPN

现在您可以sudo systemctl无需密码执行您的服务命令。

希望这会有帮助!

答案2

我也遇到过这种奇怪的情况。Openvpn 一直运行良好,直到我做了以下三项更改,试图禁用 openvpn dhcp 服务器并使用我自己的(桥接/tap 模式),但失败了。也许在你的情况下,你可能需要对配置应用相反的更改(添加服务器指令、删除 tls-server 和服务器 xy)。

  1. 在服务器配置中,我注释掉了该server X Y指令
  2. 在服务器配置中,我添加tls-servermode server注释掉了一个 IP 池选项,所有这些都是为了响应在启动 openvpn 时收到的致命错误消息,而无需 server x y

相关内容