我已将 OpenVPN 配置为服务器来托管我自己的 VPN,并且我想使用 DNSMasq 来解析 VPN 上的主机名。
假设我有 OpenVPN 服务器、内网上的两台计算机和外网的一台计算机,所有客户端都是 VPN(192.168.254.0/24):
- 内部网络:192.168.1.0/24
- 服务器:IP:192.168.1.1
- A:IP:192.168.1.2,VPN:192.168.254.2
- 乙:IP:192.168.1.3,VPN:192.168.254.3
- 外部网络:192.168.2.0/24
- C:IP:192.168.2.1,VPN:192.168.254.4
使用我当前的设置,两者A和乙可以通过内部网络上的 DNSMasq 解析其主机名。并且,所有A,乙, 和C可以通过直接 IP 互相访问。但是,我想允许C访问A和乙通过主机名(DNS解析,而不是NetBIOS)而不是通过VPN引导所有网络流量。
OpenVPN配置:
proto tcp
dev tap
server 192.168.254.0 255.255.255.0
client-to-client
persist-key
persist-tun
我是否还需要将 VPN 服务器配置为客户端?我是否需要通过 VPN 从内部网络推送域?我需要做什么?
答案1
由于非常复杂,我得到了一些类似于 VPN 上的 DNS 的东西。
首先,我必须在向 OpenVPN 添加地址时运行一个脚本。在服务器配置中:
ifconfig-pool-persist ip-pool # Store mappings of CN,IP, 1 per line
script-security 2 # Allow OpenVPN to run user scripts
learn-address /path/to/learn-address.sh
我开始learn-address.sh
来自旧 OpenVPN 线程的脚本ip-pool
但由于我正在运行 TAP 接口,所以我必须添加脚本来解析文件:
#!/bin/sh
# openvpn learn-address script to manage a hosts-like file
# - intended to allow dnsmasq to resolve openvpn clients
# addn-hosts=/etc/hosts.openvpn-clients
#
# Changelog
# 2006-10-13 BDL original
# 2018-12-10 Palswim change to query OpenVPN Persistent pool for TAP interfaces
# replace with a sub-domain of your domain, use a sub-domain to
# prevent VPN clients from stealing existing names
DOMAIN=example
HOSTS=/etc/openvpn/hosts
h="hosts-openvpn-$DOMAIN"
LOCKFILE="/var/run/$h.lock"
IP="$2"
CN="$3"
if [ -z "$IP" ]; then
echo "$0: IP not provided" >&2
exit 1
else
# In TAP mode, OpenVPN passes MAC instead of IP, since with TAP, clients can use protocols other than IP
MAC="$IP"
IP=$(grep "^$CN[[:space:]]*," ip-pool | head -n 1 | cut -d, -f 2)
if [ -z "$IP" ]; then
echo "$0: Failed to find IP in ipconfig-pool" >&2
exit 0
else
echo "$0: Translated MAC ($MAC) to IP ($IP)"
fi
fi
case "$1" in
add|update)
if [ -z "$CN" ]; then
echo "$0: Common Name not provided" >&2
exit 0
fi
;;
delete)
;;
*)
echo "$0: unknown operation [$1]" >&2
exit 1
;;
esac
# serialise concurrent accesses
[ -x /bin/lock ] && /bin/lock "$LOCKFILE"
# clean up IP if we can
[ -x /bin/ipcalc ] && eval $(ipcalc "$IP")
FQDN="$CN"
# busybox mktemp must have exactly six X's
t=$(/bin/mktemp "/run/shm/$h.XXXXXX")
if [ $? -ne 0 ]; then
echo "$0: mktemp failed" >&2
exit 1
fi
case "$1" in
add|update)
/usr/bin/awk '
# update/uncomment address|FQDN with new record, drop any duplicates:
$1 == "'"$IP"'" || $1 == "#'"$IP"'" || $2 == "'"$FQDN"'" \
{ if (!m) print "'"$IP"'\t'"$FQDN"'"; m=1; next }
{ print }
END { if (!m) print "'"$IP"'\t'"$FQDN"'" } # add new address to end
' "$HOSTS" > "$t" && cat "$t" > "$HOSTS"
;;
delete)
/usr/bin/awk '
# no FQDN, comment out all matching addresses (should only be one)
$1 == "'"$IP"'" { print "#" $0; next }
{ print }
' "$HOSTS" > "$t" && cat "$t" > "$HOSTS"
;;
esac
# signal dnsmasq to reread hosts file
kill -HUP $(cat /var/run/dnsmasq/dnsmasq.pid)
rm "$t"
[ -x /bin/lock ] && /bin/lock -u "$LOCKFILE"
exit 0
我最终在一台服务器上为自己的 LAN 运行 DNSMasq,在另一台服务器上为 VPN 运行 DNSMasq。我必须/etc/dnsmasq.conf
在 VPN DNS 服务器上更新我的配置 ():
no-resolv # Didn't want to serve anything but VPN requests
interface=tap0
no-hosts # Don't use /etc/hosts
addn-hosts=/etc/openvpn/hosts # Target the output of the learn-address.sh script
expand-hosts
domain=example
完成这些后,我必须通过 OpenVPN 的 DHCP 服务器推送一些选项。同样,在 OpenVPN 服务器配置中:
server 192.168.254.0 255.255.255.0 # Assuming this VPN network
push "dhcp-option DNS 192.168.254.1"
push "dhcp-option DOMAIN example" # Push domain to clients
不幸的是,只有 Windows 版本的 OpenVPN 支持自动设置这些选项。Linux 客户端需要配置脚本以在连接建立/断开时运行。如果您的 Linux 系统使用/etc/resolv.conf
,最终,您需要您的 VPN 域出现在您的search
列表中,并且您的服务器 IP 显示为nameserver
:
search example # you may have other strings here too, separated by a space
# ... other nameservers, then:
nameserver 192.168.254.1