OpenVPN Linux 客户端没有调出tap0 界面

Chr*_*ris 4 networking dhcp vpn openvpn tap

我在 Linux 上有一个 OpenVPN 客户端连接到 OpenVPN 服务器。服务器通过 DHCP 分配 IP,因此我使用tap接口而不是tun接口进行连接。

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

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

ip link set tap0 up
dhclient tap0
Run Code Online (Sandbox Code Playgroud)

但它只启动了设备,并没有获得 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
Run Code Online (Sandbox Code Playgroud)

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

DEVICE=tap0
BOOTPROTO=dhcp
ONBOOT=yes
PEERDNS=no
ZONE=trusted
Run Code Online (Sandbox Code Playgroud)

提前致谢!

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

Edit2: 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
Run Code Online (Sandbox Code Playgroud)

Juu*_*uul 5

让 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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

这样做的原因是我认为让现有的操作系​​统服务尽可能多地处理是最优雅的 - 换句话说,随着操作系统的粒度移动而不是与之相反。安装的默认 up/down 脚本用于操作/etc/resolv.conf,Ubuntu 18.04 不再(直接)使用它。它使用 systemd-resolved。直接操作resolv.conf会导致很多眼泪,年轻的绝地。然而,这并没有导致 Ubuntu 开发人员默认为 systemd-resolved 安装 up/down 脚本。这取决于您(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
Run Code Online (Sandbox Code Playgroud)

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

sudo systemctl daemon-reload
sudo systemctl restart networking
Run Code Online (Sandbox Code Playgroud)

繁荣!操作系统现在将自己查询 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 包,“通配符”systemd 服务可用于/etc/openvpn/client. 您可以查看应该位于/lib/systemd/system/openvpn-client@.service. 可以用 来控制sudo systemctl start openvpn-client@my-config-name-without-.conf。它适用于 TUN 风格的隧道完全正常,所以不要管它。我们将复制它以适用于 TAP 设备。

创建文件/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
Run Code Online (Sandbox Code Playgroud)

它是对默认服务的简单改编。要使其正常工作,您的客户端配置必须位于/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
Run Code Online (Sandbox Code Playgroud)

多啊!您现在可以使用 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
Run Code Online (Sandbox Code Playgroud)

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

当然希望这有帮助!