Created
December 1, 2021 20:32
-
-
Save Tatsh/8ad5aa75721d6ba018a20906a04a6fa3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 9ed72ef140d40bc1ccea5911b38fa78e7faea160 Mon Sep 17 00:00:00 2001 | |
From: Dan Aloni <[email protected]> | |
Date: Wed, 1 Apr 2020 12:28:15 +0300 | |
Subject: [PATCH 1/2] Support a script to be executed when the device goes up | |
This adds the `ifup_script` config option. The script receives the | |
following environment variables as input: | |
- NET_DEVICE: The name of the network device of the VPN. | |
- DNS_SUFFIX: DNS domain search prefix, if provided by the VPN server. | |
- DNS_SERVERS: A list of the DNS server addresses if provided by the VPN | |
server. | |
--- | |
src/config.c | 5 ++++- | |
src/config.h | 2 ++ | |
src/tunnel.c | 37 +++++++++++++++++++++++++++++++++++-- | |
3 files changed, 41 insertions(+), 3 deletions(-) | |
diff --git a/src/config.c b/src/config.c | |
index 825febb..dc58dd2 100644 | |
--- a/src/config.c | |
+++ b/src/config.c | |
@@ -297,8 +297,11 @@ int load_config(struct vpn_config *cfg, const char *filename) | |
free(cfg->pinentry); | |
cfg->pinentry = strdup(val); | |
} else if (strcmp(key, "realm") == 0) { | |
- strncpy(cfg->realm, val, REALM_SIZE); | |
+ strncpy(cfg->realm, val, REALM_SIZE - 1); | |
cfg->realm[REALM_SIZE] = '\0'; | |
+ } else if (strcmp(key, "ifup-script") == 0) { | |
+ strncpy(cfg->ifup_script, val, MAXPATHLEN - 1); | |
+ cfg->ifup_script[MAXPATHLEN] = '\0'; | |
} else if (strcmp(key, "set-dns") == 0) { | |
int set_dns = strtob(val); | |
diff --git a/src/config.h b/src/config.h | |
index f7783e1..9801f68 100644 | |
--- a/src/config.h | |
+++ b/src/config.h | |
@@ -18,6 +18,7 @@ | |
#ifndef OPENFORTIVPN_CONFIG_H | |
#define OPENFORTIVPN_CONFIG_H | |
+#include <sys/param.h> | |
#include <netinet/in.h> | |
#include <net/if.h> | |
@@ -96,6 +97,7 @@ struct vpn_config { | |
char *pinentry; | |
char iface_name[IF_NAMESIZE]; | |
char realm[REALM_SIZE + 1]; | |
+ char ifup_script[MAXPATHLEN + 1]; | |
int set_routes; | |
int set_dns; | |
diff --git a/src/tunnel.c b/src/tunnel.c | |
index 7aede6f..658d1d4 100644 | |
--- a/src/tunnel.c | |
+++ b/src/tunnel.c | |
@@ -107,13 +107,39 @@ static int ofv_append_varr(struct ofv_varr *p, const char *x) | |
return 0; | |
} | |
+static int ipv4_run_ifup_script(struct tunnel *tunnel) | |
+{ | |
+ char ns[32]; | |
+ | |
+ setenv("NET_DEVICE", tunnel->ppp_iface, 0); | |
+ | |
+ ns[0] = '\0'; | |
+ | |
+ if (tunnel->ipv4.ns1_addr.s_addr != 0) | |
+ strncat(ns, inet_ntoa(tunnel->ipv4.ns1_addr), 15); | |
+ | |
+ if (tunnel->ipv4.ns2_addr.s_addr != 0) { | |
+ strcpy(ns, " "); | |
+ strncat(ns, inet_ntoa(tunnel->ipv4.ns2_addr), 15); | |
+ } | |
+ | |
+ setenv("DNS_SERVERS", ns, 0); | |
+ | |
+ if (tunnel->ipv4.dns_suffix != NULL) | |
+ setenv("DNS_SUFFIX", tunnel->ipv4.dns_suffix, 0); | |
+ else | |
+ setenv("DNS_SUFFIX", "", 0); | |
+ | |
+ return system(tunnel->config->ifup_script); | |
+} | |
+ | |
static int on_ppp_if_up(struct tunnel *tunnel) | |
{ | |
+ int ret; | |
+ | |
log_info("Interface %s is UP.\n", tunnel->ppp_iface); | |
if (tunnel->config->set_routes) { | |
- int ret; | |
- | |
log_info("Setting new routes...\n"); | |
ret = ipv4_set_tunnel_routes(tunnel); | |
@@ -127,6 +153,13 @@ static int on_ppp_if_up(struct tunnel *tunnel) | |
ipv4_add_nameservers_to_resolv_conf(tunnel); | |
} | |
+ if (tunnel->config->ifup_script) { | |
+ log_info("Running `ifup` script...\n"); | |
+ ret = ipv4_run_ifup_script(tunnel); | |
+ if (ret != 0) | |
+ log_warn("The `ifup` script failed. Please check your logs.\n"); | |
+ } | |
+ | |
log_info("Tunnel is up and running.\n"); | |
#if HAVE_SYSTEMD | |
-- | |
2.34.1 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 90a42f08ba08eb781b82450658a06be552f66ad9 Mon Sep 17 00:00:00 2001 | |
From: Dan Aloni <[email protected]> | |
Date: Wed, 1 Apr 2020 12:28:15 +0300 | |
Subject: [PATCH 2/2] Add a script to be used for updating systemd-resolved | |
--- | |
contrib/ifup-systemd-resolved.sh | 119 +++++++++++++++++++++++++++++++ | |
1 file changed, 119 insertions(+) | |
create mode 100755 contrib/ifup-systemd-resolved.sh | |
diff --git a/contrib/ifup-systemd-resolved.sh b/contrib/ifup-systemd-resolved.sh | |
new file mode 100755 | |
index 0000000..47d422a | |
--- /dev/null | |
+++ b/contrib/ifup-systemd-resolved.sh | |
@@ -0,0 +1,119 @@ | |
+#!/bin/bash | |
+ | |
+# ------------------------------------------------------------------------------- | |
+# LICENSE: | |
+# | |
+# This program is free software: you can redistribute it and/or modify | |
+# it under the terms of the GNU General Public License as published by | |
+# the Free Software Foundation, either version 3 of the License, or | |
+# (at your option) any later version. | |
+# | |
+# This program is distributed in the hope that it will be useful, | |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+# GNU General Public License for more details. | |
+# | |
+# You should have received a copy of the GNU General Public License | |
+# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
+# ------------------------------------------------------------------------------- | |
+ | |
+# This is an `ifup` script to be used for integrating openfortivpn and | |
+# systemd-resolved. When the network interface goes up, the DNS server information | |
+# will be added to `systemd-resolved` without modifying /etc/resolve.conf. | |
+# | |
+# This script is largely based on the main script from the `update-systemd-resolved` | |
+# package, see: https://github.com/jonathanio/update-systemd-resolved | |
+ | |
+DBUS_DEST="org.freedesktop.resolve1" | |
+DBUS_NODE="/org/freedesktop/resolve1" | |
+ | |
+SCRIPT_NAME="${BASH_SOURCE[0]##*/}" | |
+ | |
+log() { | |
+ logger -s -t "$SCRIPT_NAME" "$@" | |
+} | |
+ | |
+for level in emerg err warning info debug; do | |
+ printf -v functext -- '%s() { log -p user.%s -- "$@" ; }' "$level" "$level" | |
+ eval "$functext" | |
+done | |
+ | |
+get_link_info() { | |
+ dev="$1" | |
+ shift | |
+ | |
+ link='' | |
+ link="$(ip link show dev "$dev")" || return $? | |
+ | |
+ echo "$dev" "${link%%:*}" | |
+} | |
+ | |
+busctl_call() { | |
+ # Preserve busctl's exit status | |
+ busctl call "$DBUS_DEST" "$DBUS_NODE" "${DBUS_DEST}.Manager" "$@" || { | |
+ local -i status=$? | |
+ emerg "'busctl' exited with status $status" | |
+ return $status | |
+ } | |
+} | |
+ | |
+up() { | |
+ local link="$1" | |
+ shift | |
+ local if_index="$1" | |
+ shift | |
+ | |
+ local -a dns_servers=() dns_domain=() dns_search=() dns_routed=() | |
+ local -i dns_server_count=0 dns_domain_count=0 dns_search_count=0 dns_routed_count=0 | |
+ local dns_sec="" | |
+ | |
+ for address in ${DNS_SERVERS}; do | |
+ (( dns_server_count += 1 )) | |
+ dns_servers+=(2 4 ${address//./ }) | |
+ done | |
+ | |
+ for domain in ${DNS_SUFFIX}; do | |
+ (( dns_search_count += 1 )) | |
+ dns_search+=("${domain}" false) | |
+ done | |
+ | |
+ if [[ "${#dns_servers[*]}" -gt 0 ]]; then | |
+ busctl_params=("$if_index" "$dns_server_count" "${dns_servers[@]}") | |
+ info "SetLinkDNS(${busctl_params[*]})" | |
+ busctl_call SetLinkDNS 'ia(iay)' "${busctl_params[@]}" || return $? | |
+ fi | |
+ | |
+ if [[ "${#dns_domain[*]}" -gt 0 \ | |
+ || "${#dns_search[*]}" -gt 0 \ | |
+ || "${#dns_routed[*]}" -gt 0 ]]; then | |
+ dns_count=$((dns_domain_count+dns_search_count+dns_routed_count)) | |
+ busctl_params=("$if_index" "$dns_count") | |
+ if [[ "${#dns_domain[*]}" -gt 0 ]]; then | |
+ busctl_params+=("${dns_domain[@]}") | |
+ fi | |
+ if [[ "${#dns_search[*]}" -gt 0 ]]; then | |
+ busctl_params+=("${dns_search[@]}") | |
+ fi | |
+ if [[ "${#dns_routed[*]}" -gt 0 ]]; then | |
+ busctl_params+=("${dns_routed[@]}") | |
+ fi | |
+ info "SetLinkDomains(${busctl_params[*]})" | |
+ busctl_call SetLinkDomains 'ia(sb)' "${busctl_params[@]}" || return $? | |
+ fi | |
+ | |
+ if [[ -n "${dns_sec}" ]]; then | |
+ if [[ "${dns_sec}" == "default" ]]; then | |
+ # We need to provide an empty string to use the default settings | |
+ info "SetLinkDNSSEC($if_index '')" | |
+ busctl_call SetLinkDNSSEC 'is' "$if_index" "" || return $? | |
+ else | |
+ info "SetLinkDNSSEC($if_index ${dns_sec})" | |
+ busctl_call SetLinkDNSSEC 'is' "$if_index" "${dns_sec}" || return $? | |
+ fi | |
+ fi | |
+} | |
+ | |
+dev=${NET_DEVICE} | |
+read -r link if_index _ < <(get_link_info "$dev") | |
+up "$link" "$if_index" | |
+systemd-resolve --flush-caches | |
-- | |
2.34.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment