Skip to content

Commit fef5c4b

Browse files
d12fkcron2
authored andcommitted
dns: apply settings via script on unixoid systems
This introduces a new script hook, the dns-updown, and implements such a command script for a few popular systems (and a default for the not so popular ones). Like the name suggests this hook is soleley for dealing with modifying how names are resolved when the VPN pushes some --dns settings. The default dns updown command is part of the distribution and is installed with openvpn. You can change the path the command is located at as a compile time option, defaults to libexecdir. You can compile-time disable that the default dns-updown hook is run by passing --disable-dns-updown-by-default to configure or ccmake ENABLE_DNS_UPDOWN_BY_DEFAULT to OFF. There's also a new runtime option --dns-updown, which can run a custom command, force running the default when disabled or disable execution of the dns-updown altogether. Change-Id: Ifbe4ffb44d3bfcaa50adb38cacb3436fcdc71b10 Signed-off-by: Heiko Hund <heiko@ist.eigentlich.net> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <20250514135334.14377-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg31639.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
1 parent ad7a694 commit fef5c4b

15 files changed

+707
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ doc/openvpn.8.html
4949
/doc/doxygen/latex/
5050
/doc/doxygen/openvpn.doxyfile
5151
distro/systemd/*.service
52+
distro/dns-scripts/dns-updown
5253
sample/sample-keys/sample-ca/
5354
vendor/cmocka_build
5455
vendor/dist

CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ option(ENABLE_PKCS11 "BUILD with pkcs11-helper" ON)
4141
option(USE_WERROR "Treat compiler warnings as errors (-Werror)" ON)
4242
option(FAKE_ANDROID "Target Android but do not use actual cross compile/Android cmake to build for simple compile checks on Linux")
4343

44-
set(PLUGIN_DIR /usr/local/lib/openvpn/plugins CACHE FILEPATH "Location of the plugin directory")
44+
option(ENABLE_DNS_UPDOWN_BY_DEFAULT "Run --dns-updown hook by default" ON)
45+
set(DNS_UPDOWN_PATH "${CMAKE_INSTALL_PREFIX}/libexec/openvpn/dns-updown" CACHE STRING "Default location for the DNS up/down script")
46+
47+
set(PLUGIN_DIR "${CMAKE_INSTALL_PREFIX}/lib/openvpn/plugins" CACHE FILEPATH "Location of the plugin directory")
4548

4649
# Create machine readable compile commands
4750
option(ENABLE_COMPILE_COMMANDS "Generate compile_commands.json and a symlink for clangd to find it" OFF)
@@ -601,6 +604,8 @@ add_executable(openvpn ${SOURCE_FILES})
601604

602605
add_library_deps(openvpn)
603606

607+
target_compile_options(openvpn PRIVATE -DDEFAULT_DNS_UPDOWN=\"${DNS_UPDOWN_PATH}\")
608+
604609
if(MINGW)
605610
target_compile_options(openvpn PRIVATE -municode -UUNICODE)
606611
target_link_options(openvpn PRIVATE -municode)

config.h.cmake.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
/* Enable LZO compression library */
3636
#cmakedefine ENABLE_LZO
3737

38+
/* Enable dns-updown script hook */
39+
#cmakedefine ENABLE_DNS_UPDOWN
40+
3841
/* Enable NTLMv2 proxy support */
3942
#define ENABLE_NTLM 1
4043

configure.ac

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ AC_ARG_ENABLE(
9595
[enable_x509_alt_username="no"]
9696
)
9797

98+
AC_ARG_ENABLE(
99+
[dns-updown-by-default],
100+
[AS_HELP_STRING([--disable-dns-updown-by-default], [disable running --dns-updown by default @<:@default=yes@:>@])],
101+
,
102+
[enable_dns_updown_by_default="yes"]
103+
)
104+
98105
AC_ARG_ENABLE(
99106
[ntlm],
100107
[AS_HELP_STRING([--disable-ntlm], [disable NTLMv2 proxy support @<:@default=yes@:>@])],
@@ -315,66 +322,85 @@ else
315322
plugindir="\${libdir}/openvpn/plugins"
316323
fi
317324

325+
AC_ARG_VAR([SCRIPTDIR], [Path of script directory @<:@default=PKGLIBEXECDIR@:>@])
326+
if test -n "${SCRIPTDIR}"; then
327+
scriptdir="${SCRIPTDIR}"
328+
else
329+
scriptdir="\${pkglibexecdir}"
330+
fi
331+
318332
AC_DEFINE_UNQUOTED([TARGET_ALIAS], ["${host}"], [A string representing our host])
319-
AM_CONDITIONAL([TARGET_LINUX], [false])
333+
AM_CONDITIONAL([ENABLE_DNS_UPDOWN],[true])
320334
case "$host" in
321335
*-*-linux*)
322336
AC_DEFINE([TARGET_LINUX], [1], [Are we running on Linux?])
323-
AM_CONDITIONAL([TARGET_LINUX], [true])
324337
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["L"], [Target prefix])
338+
AC_SUBST([DNS_UPDOWN_TYPE], ["systemd"])
325339
have_sitnl="yes"
326340
pkg_config_required="yes"
327341
;;
328342
*-*-solaris*)
329343
AC_DEFINE([TARGET_SOLARIS], [1], [Are we running on Solaris?])
330344
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["S"], [Target prefix])
345+
AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"])
331346
CPPFLAGS="$CPPFLAGS -D_XPG4_2"
332347
test -x /bin/bash && SHELL="/bin/bash"
333348
;;
334349
*-*-openbsd*)
335350
AC_DEFINE([TARGET_OPENBSD], [1], [Are we running on OpenBSD?])
336351
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["O"], [Target prefix])
352+
AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"])
337353
;;
338354
*-*-freebsd*)
339355
AC_DEFINE([TARGET_FREEBSD], [1], [Are we running on FreeBSD?])
340356
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["F"], [Target prefix])
357+
AC_SUBST([DNS_UPDOWN_TYPE], ["openresolv"])
341358
;;
342359
*-*-netbsd*)
343360
AC_DEFINE([TARGET_NETBSD], [1], [Are we running NetBSD?])
344361
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["N"], [Target prefix])
362+
AC_SUBST([DNS_UPDOWN_TYPE], ["openresolv"])
345363
;;
346364
*-*-darwin*)
347365
AC_DEFINE([TARGET_DARWIN], [1], [Are we running on Mac OS X?])
348366
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["M"], [Target prefix])
367+
AM_CONDITIONAL([ENABLE_DNS_UPDOWN], [false])
368+
AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"])
349369
have_tap_header="yes"
350370
ac_cv_type_struct_in_pktinfo=no
351371
;;
352372
*-mingw*)
353373
AC_DEFINE([TARGET_WIN32], [1], [Are we running WIN32?])
354374
AC_DEFINE([ENABLE_DCO], [1], [DCO is always enabled on Windows])
355375
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["W"], [Target prefix])
376+
AM_CONDITIONAL([ENABLE_DNS_UPDOWN], [false])
377+
AC_SUBST([DNS_UPDOWN_TYPE], ["windows"])
356378
CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
357379
CPPFLAGS="${CPPFLAGS} -DNTDDI_VERSION=NTDDI_VISTA -D_WIN32_WINNT=_WIN32_WINNT_VISTA"
358380
WIN32=yes
359381
;;
360382
*-*-dragonfly*)
361383
AC_DEFINE([TARGET_DRAGONFLY], [1], [Are we running on DragonFlyBSD?])
362384
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["D"], [Target prefix])
385+
AC_SUBST([DNS_UPDOWN_TYPE], ["openresolv"])
363386
;;
364387
*-aix*)
365388
AC_DEFINE([TARGET_AIX], [1], [Are we running AIX?])
366389
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["A"], [Target prefix])
390+
AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"])
367391
ROUTE="/usr/sbin/route"
368392
have_tap_header="yes"
369393
ac_cv_header_net_if_h="no" # exists, but breaks things
370394
;;
371395
*-*-haiku*)
372396
AC_DEFINE([TARGET_HAIKU], [1], [Are we running Haiku?])
373397
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["H"], [Target prefix])
398+
AC_SUBST([DNS_UPDOWN_TYPE], ["haikuos_file"])
374399
LIBS="${LIBS} -lnetwork"
375400
;;
376401
*)
377402
AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["X"], [Target prefix])
403+
AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"])
378404
have_tap_header="yes"
379405
;;
380406
esac
@@ -1317,7 +1343,7 @@ test "${enable_debug}" = "yes" && AC_DEFINE([ENABLE_DEBUG], [1], [Enable debuggi
13171343
test "${enable_small}" = "yes" && AC_DEFINE([ENABLE_SMALL], [1], [Enable smaller executable size])
13181344
test "${enable_fragment}" = "yes" && AC_DEFINE([ENABLE_FRAGMENT], [1], [Enable internal fragmentation support])
13191345
test "${enable_port_share}" = "yes" && AC_DEFINE([ENABLE_PORT_SHARE], [1], [Enable TCP Server port sharing])
1320-
1346+
test "${enable_dns_updown_by_default}" = "yes" && AC_DEFINE([ENABLE_DNS_UPDOWN_BY_DEFAULT], [1], [Enable dns-updown hook by default])
13211347
test "${enable_ntlm}" = "yes" && AC_DEFINE([ENABLE_NTLM], [1], [Enable NTLMv2 proxy support])
13221348
test "${enable_crypto_ofb_cfb}" = "yes" && AC_DEFINE([ENABLE_OFB_CFB_MODE], [1], [Enable OFB and CFB cipher modes])
13231349
if test "${have_export_keying_material}" = "yes"; then
@@ -1505,6 +1531,7 @@ AM_CONDITIONAL([OPENSSL_ENGINE], [test "${have_openssl_engine}" = "yes"])
15051531

15061532
sampledir="\$(docdir)/sample"
15071533
AC_SUBST([plugindir])
1534+
AC_SUBST([scriptdir])
15081535
AC_SUBST([sampledir])
15091536

15101537
AC_SUBST([systemdunitdir])
@@ -1541,6 +1568,7 @@ AC_CONFIG_FILES([
15411568
Makefile
15421569
distro/Makefile
15431570
distro/systemd/Makefile
1571+
distro/dns-scripts/Makefile
15441572
doc/Makefile
15451573
doc/doxygen/Makefile
15461574
doc/doxygen/openvpn.doxyfile

distro/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ MAINTAINERCLEANFILES = \
1313
$(srcdir)/Makefile.in
1414

1515
SUBDIRS = systemd
16+
17+
if ENABLE_DNS_UPDOWN
18+
SUBDIRS += dns-scripts
19+
endif

distro/dns-scripts/Makefile.am

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#
2+
# OpenVPN -- An application to securely tunnel IP networks
3+
# over a single UDP port, with support for SSL/TLS-based
4+
# session authentication and key exchange,
5+
# packet encryption, packet authentication, and
6+
# packet compression.
7+
#
8+
# Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9+
#
10+
11+
MAINTAINERCLEANFILES = \
12+
$(srcdir)/Makefile.in
13+
14+
EXTRA_DIST = \
15+
systemd-dns-updown.sh \
16+
openresolv-dns-updown.sh \
17+
haikuos_file-dns-updown.sh \
18+
resolvconf_file-dns-updown.sh
19+
20+
script_SCRIPTS = \
21+
dns-updown
22+
23+
CLEANFILES = $(script_SCRIPTS)
24+
25+
dns-updown: @DNS_UPDOWN_TYPE@-dns-updown.sh
26+
cp ${srcdir}/@DNS_UPDOWN_TYPE@-dns-updown.sh $@
27+
chmod +x $@
28+
29+
all: $(script_SCRIPTS)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/sh
2+
#
3+
# Simple OpenVPN up/down script for modifying Haiku OS resolv.conf
4+
# (C) Copyright 2024 OpenVPN Inc <sales@openvpn.net>
5+
#
6+
# SPDX-License-Identifier: BSD-2-Clause
7+
#
8+
# Example env from openvpn (most are not applied):
9+
#
10+
# dev tun0
11+
# script_type dns-up
12+
# dns_search_domain_1 mycorp.in
13+
# dns_search_domain_2 eu.mycorp.com
14+
# dns_server_1_address_1 192.168.99.254
15+
# dns_server_1_address_2 fd00::99:53
16+
# dns_server_1_port_1 53
17+
# dns_server_1_port_2 53
18+
# dns_server_1_resolve_domain_1 mycorp.in
19+
# dns_server_1_resolve_domain_2 eu.mycorp.com
20+
# dns_server_1_dnssec true
21+
# dns_server_1_transport DoH
22+
# dns_server_1_sni dns.mycorp.in
23+
#
24+
25+
set -e +u
26+
27+
conly_standard_server_ports() {
28+
i=1
29+
while true; do
30+
eval addr=\"\$dns_server_${n}_address_${i}\"
31+
[ -n "$addr" ] || return 0
32+
33+
eval port=\"\$dns_server_${n}_port_${i}\"
34+
[ -z "$port" -o "$port" = "53" ] || return 1
35+
36+
i=$(expr $i + 1)
37+
done
38+
}
39+
40+
onf=/boot/system/settings/network/resolv.conf
41+
test -e "$conf" || exit 1
42+
case "${script_type}" in
43+
dns-up)
44+
n=1
45+
while :; do
46+
eval addr=\"\$dns_server_${n}_address_1\"
47+
[ -n "$addr" ] || {
48+
echo "setting DNS failed, no compatible server profile"
49+
exit 1
50+
}
51+
52+
# Skip server profiles which require DNSSEC,
53+
# secure transport or use a custom port
54+
eval dnssec=\"\$dns_server_${n}_dnssec\"
55+
eval transport=\"\$dns_server_${n}_transport\"
56+
[ -z "$transport" -o "$transport" = "plain" ] \
57+
&& [ -z "$dnssec" -o "$dnssec" = "no" ] \
58+
&& only_standard_server_ports && break
59+
60+
n=$(expr $n + 1)
61+
done
62+
63+
eval addr1=\"\$dns_server_${n}_address_1\"
64+
eval addr2=\"\$dns_server_${n}_address_2\"
65+
eval addr3=\"\$dns_server_${n}_address_3\"
66+
text="### openvpn ${dev} begin ###\n"
67+
text="${text}nameserver $addr1\n"
68+
test -z "$addr2" || text="${text}nameserver $addr2\n"
69+
test -z "$addr3" || text="${text}nameserver $addr3\n"
70+
71+
test -z "$dns_search_domain_1" || {
72+
for i in $(seq 1 6); do
73+
eval domains=\"$domains\$dns_search_domain_${i} \" || break
74+
done
75+
text="${text}search $domains\n"
76+
}
77+
text="${text}### openvpn ${dev} end ###"
78+
text="${text}\n$(cat ${conf})"
79+
80+
echo "${text}" > "${conf}"
81+
;;
82+
dns-down)
83+
sed -i'' -e "/### openvpn ${dev} begin ###/,/### openvpn ${dev} end ###/d" "$conf"
84+
;;
85+
esac
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/bin/sh
2+
#
3+
# Simple OpenVPN up/down script for openresolv integration
4+
# (C) Copyright 2016 Baptiste Daroussin
5+
# 2024 OpenVPN Inc <sales@openvpn.net>
6+
#
7+
# SPDX-License-Identifier: BSD-2-Clause
8+
#
9+
# Example env from openvpn (most are not applied):
10+
#
11+
# dev tun0
12+
# script_type dns-up
13+
# dns_search_domain_1 mycorp.in
14+
# dns_search_domain_2 eu.mycorp.com
15+
# dns_server_1_address_1 192.168.99.254
16+
# dns_server_1_address_2 fd00::99:53
17+
# dns_server_1_port_1 53
18+
# dns_server_1_port_2 53
19+
# dns_server_1_resolve_domain_1 mycorp.in
20+
# dns_server_1_resolve_domain_2 eu.mycorp.com
21+
# dns_server_1_dnssec true
22+
# dns_server_1_transport DoH
23+
# dns_server_1_sni dns.mycorp.in
24+
#
25+
26+
set -e +u
27+
28+
only_standard_server_ports() {
29+
i=1
30+
while true; do
31+
eval addr=\"\$dns_server_${n}_address_${i}\"
32+
[ -n "$addr" ] || return 0
33+
34+
eval port=\"\$dns_server_${n}_port_${i}\"
35+
[ -z "$port" -o "$port" = "53" ] || return 1
36+
37+
i=$(expr $i + 1)
38+
done
39+
}
40+
41+
: ${script_type:=dns-down}
42+
case "${script_type}" in
43+
dns-up)
44+
n=1
45+
while :; do
46+
eval addr=\"\$dns_server_${n}_address_1\"
47+
[ -n "$addr" ] || {
48+
echo "setting DNS failed, no compatible server profile"
49+
exit 1
50+
}
51+
52+
# Skip server profiles which require DNSSEC,
53+
# secure transport or use a custom port
54+
eval dnssec=\"\$dns_server_${n}_dnssec\"
55+
eval transport=\"\$dns_server_${n}_transport\"
56+
[ -z "$transport" -o "$transport" = "plain" ] \
57+
&& [ -z "$dnssec" -o "$dnssec" = "no" ] \
58+
&& only_standard_server_ports && break
59+
60+
n=$(expr $n + 1)
61+
done
62+
63+
{
64+
i=1
65+
maxns=3
66+
while :; do
67+
maxns=$((maxns - 1))
68+
[ $maxns -gt 0 ] || break
69+
eval option=\"\$dns_server_${n}_address_${i}\" || break
70+
[ "${option}" ] || break
71+
i=$((i + 1))
72+
echo "nameserver ${option}"
73+
done
74+
i=1
75+
maxdom=6
76+
while :; do
77+
maxdom=$((maxdom - 1))
78+
[ $maxdom -gt 0 ] || break
79+
eval option=\"\$dns_search_domain_${i}\" || break
80+
[ "${option}" ] || break
81+
i=$((i + 1))
82+
echo "search ${option}"
83+
done
84+
} | /sbin/resolvconf -a "${dev}"
85+
;;
86+
dns-down)
87+
/sbin/resolvconf -d "${dev}" -f
88+
;;
89+
esac

0 commit comments

Comments
 (0)