diff --git a/board/common/rootfs/etc/dnsmasq.conf b/board/common/rootfs/etc/dnsmasq.conf new file mode 100644 index 00000000..f093056b --- /dev/null +++ b/board/common/rootfs/etc/dnsmasq.conf @@ -0,0 +1,14 @@ +# dnsmasq is the system resolver, the file /etc/resolv.conf is +# managed by openresolv. DHCP lease, VPN tunnel establishment, +# and similar events feed servers and configuration to dnsmasq. +domain-needed +#interface=lo +listen-address=127.0.0.1 +enable-dbus + +# Generated by openresolv +resolv-file=/var/lib/misc/resolv.conf + +# Include all files in a directory which end in .conf +conf-dir=/etc/dnsmasq.d/,*.conf + diff --git a/board/common/rootfs/etc/dnsmasq.d/.empty b/board/common/rootfs/etc/dnsmasq.d/.empty new file mode 100644 index 00000000..e69de29b diff --git a/board/common/rootfs/etc/resolvconf.conf b/board/common/rootfs/etc/resolvconf.conf new file mode 100644 index 00000000..d7055fee --- /dev/null +++ b/board/common/rootfs/etc/resolvconf.conf @@ -0,0 +1,10 @@ +# dnsmasq is the system resolver +name_servers="127.0.0.1" + +resolv_conf=/etc/resolv.conf +resolv_conf_options="edns0 trust-ad" + +# dnsmasq specific settings and list of +# nameservers in non-standard locations +dnsmasq_conf=/etc/dnsmasq.d/resolvconf.conf +dnsmasq_resolv=/var/lib/misc/resolv.conf diff --git a/board/common/rootfs/etc/resolvconf/interface-order b/board/common/rootfs/etc/resolvconf/interface-order new file mode 100644 index 00000000..75476e0f --- /dev/null +++ b/board/common/rootfs/etc/resolvconf/interface-order @@ -0,0 +1 @@ +lo diff --git a/board/common/rootfs/lib/infix/clean-etc b/board/common/rootfs/lib/infix/clean-etc index ab2a0ddc..0ced63a0 100755 --- a/board/common/rootfs/lib/infix/clean-etc +++ b/board/common/rootfs/lib/infix/clean-etc @@ -7,7 +7,7 @@ # ... except for some core services reserved() { - for svc in clixon getty lldpd nginx sysklogd; do + for svc in clixon dnsmasq getty lldpd nginx sysklogd; do [ "$1" = "${svc}.conf" ] && return 0 done diff --git a/package/mech/clixon.conf b/package/mech/clixon.conf index 4f497826..1fdd25d4 100644 --- a/package/mech/clixon.conf +++ b/package/mech/clixon.conf @@ -5,3 +5,4 @@ run if: name:clixon :boot log:prio:daemon.warning \ service if: name:clixon log:prio:daemon.warning \ [12345789] clixon_backend -F -l s -D 7 -s none -- Configuration daemon +task if: [12345789] resolvconf -u -- Update DNS configuration diff --git a/package/mech/tmpfiles.conf b/package/mech/tmpfiles.conf index 6356a630..6906299b 100644 --- a/package/mech/tmpfiles.conf +++ b/package/mech/tmpfiles.conf @@ -1 +1,2 @@ -d /run/clixon - - - +d /run/clixon - - - +d /run/resolvconf/interfaces - - - diff --git a/package/skeleton-init-finit/skeleton/etc/finit.d/available/dnsmasq.conf b/package/skeleton-init-finit/skeleton/etc/finit.d/available/dnsmasq.conf index 3b34dfe5..84562903 100644 --- a/package/skeleton-init-finit/skeleton/etc/finit.d/available/dnsmasq.conf +++ b/package/skeleton-init-finit/skeleton/etc/finit.d/available/dnsmasq.conf @@ -1 +1 @@ -service [2345] dnsmasq -k -- DHCP/DNS proxy +service [S12345789] dnsmasq -k -u root -- DHCP/DNS proxy diff --git a/patches/openresolv/3.12.0/finit-support.patch b/patches/openresolv/3.12.0/finit-support.patch new file mode 100644 index 00000000..6b9be23e --- /dev/null +++ b/patches/openresolv/3.12.0/finit-support.patch @@ -0,0 +1,12 @@ +diff -ru openresolv-3.12.0.orig/resolvconf.in openresolv-3.12.0/resolvconf.in +--- openresolv-3.12.0.orig/resolvconf.in 2020-12-27 19:05:10.000000000 +0100 ++++ openresolv-3.12.0/resolvconf.in 2023-03-27 00:19:03.365164029 +0200 +@@ -315,6 +315,8 @@ + then + /usr/bin/systemctl restart $1.service + fi' ++ elif [ -x /sbin/initctl ]; then ++ RESTARTCMD="/sbin/initctl -bnq restart \$1" + elif [ -x /sbin/rc-service ] && + { [ -s /libexec/rc/init.d/softlevel ] || + [ -s /run/openrc/softlevel ]; } diff --git a/patches/openresolv/foo-3.12.0/finit-support.patch b/patches/openresolv/foo-3.12.0/finit-support.patch new file mode 100644 index 00000000..1e1588df --- /dev/null +++ b/patches/openresolv/foo-3.12.0/finit-support.patch @@ -0,0 +1,16 @@ +diff -ru openresolv-3.12.0.orig/resolvconf.in openresolv-3.12.0/resolvconf.in +--- openresolv-3.12.0.orig/resolvconf.in 2020-12-27 19:05:10.000000000 +0100 ++++ openresolv-3.12.0/resolvconf.in 2023-03-27 00:19:03.365164029 +0200 +@@ -315,6 +315,12 @@ + then + /usr/bin/systemctl restart $1.service + fi' ++ elif [ -x /sbin/initctl ]; then ++ # Finit ++ RESTARTCMD=' ++ if /sbin/initctl -bq status $1; then ++ /sbin/initctl -bnq restart $1 ++ fi' + elif [ -x /sbin/rc-service ] && + { [ -s /libexec/rc/init.d/softlevel ] || + [ -s /run/openrc/softlevel ]; } diff --git a/src/mech/src/ietf-system/ietf-system.c b/src/mech/src/ietf-system/ietf-system.c index 69db9bc7..ce02ceba 100644 --- a/src/mech/src/ietf-system/ietf-system.c +++ b/src/mech/src/ietf-system/ietf-system.c @@ -89,6 +89,20 @@ static bool is_true(cxobj *xp, char *name) return false; } +static char *get_str(cxobj *xp, char *name) +{ + cxobj *obj; + + if (!xp || !name) + return NULL; + + obj = xml_find(xp, name); + if (obj) + return xml_body(obj); + + return NULL; +} + static int sys_reload_services(void) { return run("initctl -nbq touch sysklogd lldpd"); @@ -244,6 +258,83 @@ disable: return run("initctl -nbq disable chronyd"); } +/* + * dnsmasq is the resolver, it gets its nameservers from various + * sources: static, dhcp, vpn, via the resolvconf wrapper. + */ +int ietf_sys_tr_commit_dns(cxobj *src, cxobj *tgt) +{ + const char *fn = "/etc/resolv.conf.head"; + cxobj *obj, *opt = NULL, *srv = NULL; + int first = 1, valid = 0; + FILE *fp; + + clicon_log(LOG_ERR, "ietf-system: dns src %p tgt %p", src, tgt); + if (!tgt) + goto disable; + + fp = fopen(fn, "w"); + if (!fp) { + clicon_log(LOG_WARNING, "ietf-system: failed updating %s: %s", fn, strerror(errno)); + return -1; + } + + obj = xml_find(tgt, "options"); + if (obj) { + char *str; + + fprintf(fp, "options"); + str = get_str(obj, "timeout"); + if (str) + fprintf(fp, " timeout:%s", str); + str = get_str(obj, "attempts"); + if (str) + fprintf(fp, " attempts:%s ", str); + fprintf(fp, "\n"); + } + + while ((opt = xml_child_each(tgt, opt, CX_ELMNT))) { + if (strcmp(xml_name(opt), "search")) + continue; + + if (first) { + fprintf(fp, "search "); + first = 0; + } + fprintf(fp, "%s ", xml_body(opt)); + } + if (!first) + fprintf(fp, "\n"); + + while ((srv = xml_child_each(tgt, srv, CX_ELMNT))) { + cxobj *tmp; + + if (strcmp(xml_name(srv), "server")) + continue; + + tmp = xml_find(srv, "udp-and-tcp"); + if (tmp) { + obj = xml_find(tmp, "address"); + if (obj) { + fprintf(fp, "nameserver %s\n", xml_body(obj)); + valid++; + } + } + } + fclose(fp); +disable: + if (!valid) + remove(fn); + + if (run("initctl cond get hook/sys/up")) { + clicon_log(LOG_ERR, "ietf-system: failed cond get hook/sys/up"); + return 0; + } + + clicon_log(LOG_ERR, "ietf-status: calling resolvconf -u"); + return run("resolvconf -u"); +} + int ietf_sys_tr_commit(clicon_handle h, transaction_data td) { cxobj *src = transaction_src(td), *tgt = transaction_target(td); @@ -270,10 +361,16 @@ int ietf_sys_tr_commit(clicon_handle h, transaction_data td) tlen ? xml_find(tsys[0], "clock") : NULL); if (err) goto err; + err = ietf_sys_tr_commit_ntp(slen ? xml_find(ssys[0], "ntp") : NULL, tlen ? xml_find(tsys[0], "ntp") : NULL); if (err) goto err; + + err = ietf_sys_tr_commit_dns(slen ? xml_find(ssys[0], "dns-resolver") : NULL, + tlen ? xml_find(tsys[0], "dns-resolver") : NULL); + if (err) + goto err; err: err = err ? : aug_save(aug); return err;