我通过以下方式在我的服务器上安装了 OpenVPN这个自动安装脚本并将生成的配置文件复制到我的客户端,也运行 OpenVPN。我想通过 VPN 路由所有客户端流量,并希望名称在服务器端解析。所有流量似乎都已成功路由,但名称由我在客户的 resolv.conf
。如何才能让它们在服务器端解析?相关服务器端配置:
root@marius:~# cat /etc/openvpn/server.conf | grep dhcp
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
我不熟悉 VPN 服务器,我不确定“推送”是否有必要,因为我不使用 DHCP 客户端。客户端resolv.conf
(手动设置,永不更改):
domain domain.name
search domain.name
# Local cache (dnsmasq)
nameserver 127.0.0.1
# VPN (doesn't work)
#nameserver 10.8.0.1
# ISP (doesn't work with VPN)
#nameserver 200.175.89.139
#nameserver 200.175.5.139
# Google (works with VPN)
nameserver 8.8.8.8
nameserver 8.8.4.4
使用重定向网关时,OpenVPN 客户端将通过 VPN 路由 DNS 查询,VPN 服务器将需要处理这些查询。这可以通过将 DNS 服务器地址推送到连接的客户端来实现,在 VPN 处于活动状态期间,该地址将替换其正常的 DNS 服务器设置。例如:
push "dhcp-option DNS 10.8.0.1"
将配置 Windows 客户端(或具有一些额外服务器端脚本的非 Windows 客户端)使用 10.8.0.1 作为其 DNS 服务器。任何可从客户端访问的地址均可用作 DNS 服务器地址。
但如上所述,这似乎不起作用。我假设我必须将我的 (VPN) 服务器也设置为 DNS 服务器才能使其工作。但这有必要吗?为什么 VPN 服务器不能通过它来处理转发的 DNS 查询resolv.conf
(无需成为 DNS 服务器,就像它无需成为其他所有服务器就可以处理其他所有事情一样)?我有点迷茫了。
如果需要的话,我可以提供任何额外的配置文件。
答案1
我不确定“推送”是否有必要,因为我不使用 DHCP 客户端。
OpenVPN 已经从服务器接收其 IP 地址和其他配置,因此即使某些“DHCP 选项”在技术上不是通过 DHCP 发送的,它也能自己理解。
我估计我必须将我的 (VPN) 服务器也设置为 DNS 服务器才能实现此功能。但这有必要吗?
是的。(具体来说,你需要一个解析器 - Unbound、dnsmasq、Bind9 都可以,但 NSD 不行,因为它是权威的。)
为什么 VPN 服务器不能通过其 resolv.conf 处理转发的 DNS 查询(不需要是 DNS 服务器,就像它不需要是其他所有服务器就可以处理其他所有事务一样)?
这根本不是一回事——VPN 服务器不会处理“其他一切”,它只是前锋IP 数据包。
例如,如果客户端连接到 Google 或将其用作8.8.8.8
DNS 服务器,VPN 服务器只会将其视为发往其他 IP 地址的 IPv4 数据包。因此 VPN 服务器不会尝试理解数据包的内容 - 只会将其发送到下一个路由器,依此类推,直到数据包最终到达真正的目的地。
但是,如果您希望 VPN 服务器遵守其规定resolv.conf
,那么它必须了解它与收到的数据包有何关系,以及应该生成什么样的答复 - 为此它需要两样东西:
首先,您的客户端必须使用 VPN 服务器自己的地址作为其“DNS 服务器”,这样服务器就会将自己视为数据包的最终目的地并实际解释其内容(作为 UDP)而不是将其转发到其他地方。
(这意味着“客户端 resolv.conf(手动设置,永不更改)”有问题。如果你使用
push
dns-server 选项,OpenVPN 客户端会理解它,并且它应该尝试更新客户端resolv.conf
,但这取决于系统。)现在 VPN 服务器正在接收发往 UDP 端口 53 的数据包,但它仍然无法自动理解数据包中包含的数据。就像您需要 Web 服务器来理解 HTTP 请求一样,您还需要 DNS 服务器来理解 DNS 请求并正确回复它们。
从技术上讲,你可以通过在 VPN 服务器上使用 iptables 来绕过第一个要求重定向-j REDIRECT
所有 UDP/53 数据包都发送给自身——我认为这在各种教程中被称为“透明代理” 。
但我建议,只有当您充分了解服务器转发数据包和服务器自行处理数据包之间的区别后,才可以这样做。否则,这只会增加混乱。
答案2
您需要使用合适的 shell 脚本将 OpenVPN 传递给您的选项(两个push dhcp-options...
都很好)与resolv.conf
文件进行交互通过resolvconf
您应该已经默认安装的包。
我在客户端上有/etc/openvpn
一个名为的文件(不是我的作品!)/etc/openvpn/update-resolv-conf
,它在客户的配置文件如下:
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
我确信这个 shell 脚本在网上可以广泛找到,但如果你无法找到它,可以参考以下代码:
#!/bin/bash
#
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood and Chris Hanson.
# Licensed under the GNU GPL. See /usr/share/common-licenses/GPL.
#
# Example envs set from openvpn:
#
# foreign_option_1='dhcp-option DNS 193.43.27.132'
# foreign_option_2='dhcp-option DNS 193.43.27.133'
# foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
#
[ -x /sbin/resolvconf ] || exit 0
[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0
split_into_parts()
{
part1="$1"
part2="$2"
part3="$3"
}
case "$script_type" in
up)
NMSRVRS=""
SRCHS=""
for optionvarname in ${!foreign_option_*} ; do
option="${!optionvarname}"
echo "$option"
split_into_parts $option
if [ "$part1" = "dhcp-option" ] ; then
if [ "$part2" = "DNS" ] ; then
NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
elif [ "$part2" = "DOMAIN" ] ; then
SRCHS="${SRCHS:+$SRCHS }$part3"
fi
fi
done
R=""
[ "$SRCHS" ] && R="search $SRCHS
"
for NS in $NMSRVRS ; do
R="${R}nameserver $NS
"
done
echo -n "$R" | /sbin/resolvconf -a "${dev}.openvpn"
;;
down)
/sbin/resolvconf -d "${dev}.openvpn"
;;
esac