Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld,
I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/1062?usp=email to review the following change. Change subject: dns: add updown script for macOS ...................................................................... dns: add updown script for macOS Change-Id: Iade06a8454ccf53668deef61f07217ead8ec6c63 Signed-off-by: Heiko Hund <he...@ist.eigentlich.net> --- M configure.ac M distro/dns-scripts/Makefile.am A distro/dns-scripts/macos-dns-updown.sh 3 files changed, 218 insertions(+), 2 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/62/1062/1 diff --git a/configure.ac b/configure.ac index 8bdec32..02b45f8 100644 --- a/configure.ac +++ b/configure.ac @@ -364,8 +364,7 @@ *-*-darwin*) AC_DEFINE([TARGET_DARWIN], [1], [Are we running on Mac OS X?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["M"], [Target prefix]) - AM_CONDITIONAL([ENABLE_DNS_UPDOWN], [false]) - AC_SUBST([DNS_UPDOWN_TYPE], ["resolvconf_file"]) + AC_SUBST([DNS_UPDOWN_TYPE], ["macos"]) have_tap_header="yes" ac_cv_type_struct_in_pktinfo=no ;; diff --git a/distro/dns-scripts/Makefile.am b/distro/dns-scripts/Makefile.am index 9fcd3f7..e3f9043 100644 --- a/distro/dns-scripts/Makefile.am +++ b/distro/dns-scripts/Makefile.am @@ -12,6 +12,7 @@ $(srcdir)/Makefile.in EXTRA_DIST = \ + macos-dns-updown.sh \ systemd-dns-updown.sh \ openresolv-dns-updown.sh \ haikuos_file-dns-updown.sh \ diff --git a/distro/dns-scripts/macos-dns-updown.sh b/distro/dns-scripts/macos-dns-updown.sh new file mode 100644 index 0000000..6ffb8de --- /dev/null +++ b/distro/dns-scripts/macos-dns-updown.sh @@ -0,0 +1,216 @@ +#!/bin/bash +# +# dns-updown - add/remove openvpn provided DNS information +# +# (C) Copyright 2025 OpenVPN Inc <sa...@openvpn.net> +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Example env from openvpn (most are not applied): +# +# dns_vars_file /tmp/openvpn_dvf_58b95c0c97b2db43afb5d745f986c53c.tmp +# +# or +# +# dev utun0 +# script_type dns-up +# dns_search_domain_1 mycorp.in +# dns_search_domain_2 eu.mycorp.com +# dns_server_1_address_1 192.168.99.254 +# dns_server_1_address_2 fd00::99:53 +# dns_server_1_port_2 53 +# dns_server_1_resolve_domain_1 mycorp.in +# dns_server_1_resolve_domain_2 eu.mycorp.com +# dns_server_1_dnssec true +# dns_server_1_transport DoH +# dns_server_1_sni dns.mycorp.in +# + +[ -z "${dns_vars_file}" ] || . "${dns_vars_file}" + +itf_dns_key="State:/Network/Service/openvpn-${dev}/DNS" +dns_backup_key="State:/Network/Service/openvpn-${dev}/DnsBackup" + +function primary_dns_key { + local uuid=$(echo "show State:/Network/Global/IPv4" | /usr/sbin/scutil | grep "PrimaryService" | cut -d: -f2 | xargs) + echo "State:/Network/Service/${uuid}/DNS" +} + +function only_standard_server_ports { + local i=1 + while :; do + local addr_var=dns_server_${n}_address_${i} + [ -n "${!addr_var}" ] || return 0 + + local port_var=dns_server_${n}_port_${i} + [ -z "${!port_var}" -o "${!port_var}" = "53" ] || return 1 + + i=$((i+1)) + done +} + +function find_compat_profile { + local n=1 + while :; do + local addr_var=dns_server_${n}_address_1 + [ -n "${!addr_var}" ] || { + echo "setting DNS failed, no compatible server profile" + exit 1 + } + + # Skip server profiles which require DNSSEC, + # secure transport or use a custom port + local dnssec_var=dns_server_${n}_dnssec + local transport_var=dns_server_${n}_transport + [ -z "${!transport_var}" -o "${!transport_var}" = "plain" ] \ + && [ -z "${!dnssec_var}" -o "${!dnssec_var}" = "no" ] \ + && only_standard_server_ports && break + + n=$((n+1)) + done + return $n +} + +function get_search_domains { + local search_domains="" + local resolver=0 + /usr/sbin/scutil --dns | while read line; do + if [[ "$line" =~ resolver.# ]]; then + resolver=$((resolver+1)) + elif [ "$resolver" = 1 ] && [[ "$line" =~ search.domain ]]; then + search_domains+="$(echo $line | cut -d: -f2 | xargs) " + elif [ "$resolver" -gt 1 ]; then + echo "$search_domains" + break + fi + done +} + +function set_search_domains { + [ -n "$1" ] || return + dns_key=$(primary_dns_key) + search_domains="${1}$(get_search_domains)" + + local cmds="" + cmds+="get ${dns_key}\n" + cmds+="d.add SearchDomains * ${search_domains}\n" + cmds+="set ${dns_key}\n" + echo -e "${cmds}" | /usr/sbin/scutil +} + +function unset_search_domains { + [ -n "$1" ] || return + dns_key=$(primary_dns_key) + search_domains="$(get_search_domains)" + search_domains=$(echo $search_domains | sed -e "s/$1//") + + local cmds="" + cmds+="get ${dns_key}\n" + cmds+="d.add SearchDomains * ${search_domains}\n" + cmds+="set ${dns_key}\n" + echo -e "${cmds}" | /usr/sbin/scutil +} + +function set_dns { + find_compat_profile + local n=$? + + local i=1 + local addrs="" + while :; do + local addr_var=dns_server_${n}_address_${i} + local addr="${!addr_var}" + [ -n "$addr" ] || break + + local port_var=dns_server_${n}_port_${i} + if [ -n "${!port_var}" ]; then + if [[ "$addr" =~ : ]]; then + addr="[$addr]" + fi + addrs+="${addr}:${!port_var}${sni} " + else + addrs+="${addr}${sni} " + fi + i=$((i+1)) + done + + i=1 + local match_domains="" + while :; do + domain_var=dns_server_${n}_resolve_domain_${i} + [ -n "${!domain_var}" ] || break + # Add as match domain, if it doesn't already exist + [[ "$match_domains" =~ (^| )${!domain_var}( |$) ]] \ + || match_domains+="${!domain_var} " + i=$((i+1)) + done + + i=1 + local search_domains="" + while :; do + domain_var=dns_search_domain_${i} + [ -n "${!domain_var}" ] || break + # Add as search domain, if it doesn't already exist + [[ "$search_domains" =~ (^| )${!domain_var}( |$) ]] \ + || search_domains+="${!domain_var} " + i=$((i+1)) + done + + if [ -n "$match_domains" ]; then + local cmds="" + cmds+="d.init\n" + cmds+="d.add ServerAddresses * ${addrs}\n" + cmds+="d.add SupplementalMatchDomains * ${match_domains}\n" + cmds+="d.add SupplementalMatchDomainsNoSearch # 1\n" + cmds+="add ${itf_dns_key}\n" + echo -e "${cmds}" | /usr/sbin/scutil + set_search_domains "$search_domains" + else + local cmds="" + cmds+="get $(primary_dns_key)\n" + cmds+="set ${dns_backup_key}\n" + cmds+="d.init\n" + cmds+="d.add ServerAddresses * ${addrs}\n" + cmds+="d.add SearchDomains * ${search_domains}\n" + cmds+="set $(primary_dns_key)\n" + echo -e "${cmds}" | /usr/sbin/scutil + fi + + /usr/bin/dscacheutil -flushcache +} + +function unset_dns { + find_compat_profile + local n=$? + + local i=1 + local search_domains="" + while :; do + domain_var=dns_search_domain_${i} + [ -n "${!domain_var}" ] || break + # Add as search domain, if it doesn't already exist + [[ "$search_domains" =~ (^| )${!domain_var}( |$) ]] \ + || search_domains+="${!domain_var} " + i=$((i+1)) + done + + domain_var=dns_server_${n}_resolve_domain_1 + if [ -n "${!domain_var}" ]; then + echo "remove ${itf_dns_key}" | /usr/sbin/scutil + unset_search_domains "$search_domains" + else + local cmds="" + cmds+="get ${dns_backup_key}\n" + cmds+="set $(primary_dns_key)\n" + cmds+="remove ${dns_backup_key}\n" + echo -e "${cmds}" | /usr/sbin/scutil + fi + + /usr/bin/dscacheutil -flushcache +} + +if [ "$script_type" = "dns-up" ]; then + set_dns +else + unset_dns +fi -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/1062?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: Iade06a8454ccf53668deef61f07217ead8ec6c63 Gerrit-Change-Number: 1062 Gerrit-PatchSet: 1 Gerrit-Owner: d12fk <he...@openvpn.net> Gerrit-Reviewer: flichtenheld <fr...@lichtenheld.com> Gerrit-Reviewer: plaisthos <arne-open...@rfc2549.org> Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net> Gerrit-Attention: plaisthos <arne-open...@rfc2549.org> Gerrit-Attention: flichtenheld <fr...@lichtenheld.com> Gerrit-MessageType: newchange
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel