From: Michael Tremer Date: Thu, 21 Jun 2012 23:05:09 +0000 (+0000) Subject: DNS: Add options to configure local DNS servers. X-Git-Url: http://git.ipfire.org/?p=people%2Fstevee%2Fnetwork.git;a=commitdiff_plain;h=acc9efd5b5d1c68494fef866c12a9e944fd27c2f DNS: Add options to configure local DNS servers. --- diff --git a/functions.config b/functions.config index bc808c04..618e6ba1 100644 --- a/functions.config +++ b/functions.config @@ -58,7 +58,7 @@ function config_print() { local param for param in $(listsort $@); do - printf "%-16s = %s\n" "${param}" "${!param}" + printf "%-24s = %s\n" "${param}" "${!param}" done } @@ -121,6 +121,9 @@ function network_config_read() { function network_config_write() { config_write ${NETWORK_CONFIG_FILE} ${NETWORK_CONFIG_FILE_PARAMS} + + # Update DNS configuration. + dns_generate_resolvconf } function network_config_print() { diff --git a/functions.dns b/functions.dns index ee7d5c3f..85c0f3f3 100644 --- a/functions.dns +++ b/functions.dns @@ -19,12 +19,109 @@ # # ############################################################################### +# Set this to true if localhost should be added as the first DNS server. +DNS_USE_LOCAL_RESOLVER=true +NETWORK_CONFIG_FILE_PARAMS="${NETWORK_CONFIG_FILE_PARAMS} DNS_USE_LOCAL_RESOLVER" + +# Set this option to true if the DNS servers should be queried in a random order. +# This is useful to load balance between multiple servers. +DNS_RANDOMIZE=false +NETWORK_CONFIG_FILE_PARAMS="${NETWORK_CONFIG_FILE_PARAMS} DNS_RANDOMIZE" + +DNS_SERVER_CONFIG_FILE="${NETWORK_CONFIG_DIR}/dns-servers" + +# Path to the configuration file of the DNS resolver. +RESOLV_CONF="/etc/resolv.conf" + function dns_get_hostname() { local address=${1} assert isset address - #( - # eval $(ipcalc -h ${address}) - # echo "${HOSTNAME}" - #) + ( + unset HOSTNAME + eval $(ipcalc -h ${address} 2>/dev/null) + echo "${HOSTNAME}" + ) +} + +function __dns_server_println() { + local server=${1} + local priority=${2} + + print "%-20s %s" "${server}" "${priority}" +} + +function __dns_server_sort() { + sort -k2 -u -g +} + +function dns_server_list() { + [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_OK} + + local server priority + while read server priority; do + if [ -n "${server}" ] && [ -n "${priority}" ]; then + __dns_server_println "${server}" "${priority}" + fi + done < ${DNS_SERVER_CONFIG_FILE} | __dns_server_sort +} + +function dns_server_add() { + local server=${1} + assert isset server + + local priority=${2} + if ! isset priority; then + priority=20 + fi + assert isinteger priority + + ( + dns_server_list + __dns_server_println "${server}" "${priority}" + ) | __dns_server_sort > ${DNS_SERVER_CONFIG_FILE}.new + + mv ${DNS_SERVER_CONFIG_FILE}{.new,} +} + +function dns_server_remove() { + local server=${1} + assert isset server + + local entry priority + local entries=$(dns_server_list) + + while read entry priority; do + [ "${entry}" = "${server}" ] && continue + __dns_server_println "${server}" "${priority}" + done <<< ${entries} | __dns_server_sort > ${DNS_SERVER_CONFIG_FILE} +} + +function dns_server_flush() { + : > ${DNS_SERVER_CONFIG_FILE} +} + +function dns_generate_resolvconf() { + local file=${RESOLV_CONF} + + log INFO "Updating resolver configuration..." + + config_header "resolver configutation file" > ${file} + + if enabled DNS_RANDOMIZE; then + print "option rotate\n" >> ${file} + fi + + # XXX Add search domain. + + # Add the local resolver as the first DNS server if enabled. + if enabled DNS_USE_LOCAL_RESOLVER; then + print "nameserver ::1" >> ${file} + fi + + # Dump all DNS servers (if any). + local server priority + dns_server_list | while read server priority; do + print "nameserver ${server}" + done >> ${file} } diff --git a/functions.util b/functions.util index 163888fd..da2d036d 100644 --- a/functions.util +++ b/functions.util @@ -21,7 +21,9 @@ # A simple print statement function print() { - printf "$@\n" + local fmt=${1}; shift + + printf "${fmt}\n" "$@" } # Print a pretty error message @@ -89,7 +91,7 @@ function touch() { function enabled() { local param=${1} - [ "${!param}" = "yes" ] || [ "${!param}" = "on" ] || [ "${!param}" = "1" ] + listmatch "${!param}" yes on true 1 } function mac_generate() { diff --git a/man/Makefile b/man/Makefile index 52fcf2c8..a9e07ac0 100644 --- a/man/Makefile +++ b/man/Makefile @@ -29,6 +29,7 @@ MANPAGES8 = \ network.8 \ network-config.8 \ network-device.8 \ + network-dns.8 \ network-zone.8 \ network-zone-bridge.8 \ network-zone-pppoe.8 diff --git a/man/network-config.8.in b/man/network-config.8.in index bbaa2ba5..03de638b 100644 --- a/man/network-config.8.in +++ b/man/network-config.8.in @@ -10,8 +10,8 @@ network-config \- A list of global configuration options. .SH DESCRIPTION The \fBnetwork config\fR command may be used to set global configuration options permanently. -These options are mostly display options or debugging settings and do not influcence -the behaviour of the networking code itself. +.PP +Please also have look at the individual man pages for more options. .SH OPTIONS This is a list of possible configuration values: @@ -37,7 +37,7 @@ console. .PP .SH SEE ALSO -network(8) +network(8), network-dns(8) .SH AUTHOR Michael Tremer (michael.tremer@ipfire.org) diff --git a/man/network-dns.8.in b/man/network-dns.8.in new file mode 100644 index 00000000..12f975e6 --- /dev/null +++ b/man/network-dns.8.in @@ -0,0 +1,74 @@ +.TH network-dns 8 "22 Jun 2012" "@VERSION@" "network man page" + +.SH NAME +network-dns \- Network Configuration Control Program + +.SH SYNOPSIS +\fBnetwork [OPTIONS] dns [add|remove] []\fR +.P +\fBnetwork [OPTIONS] dns list\fR +.P +\fBnetwork [OPTIONS] dns update\fR + +.SH DESCRIPTION +With help of the \fBdns\fR subcommand, you will be able to configure the +local DNS configuration. DNS is short for \fBDomain Name System\fR. +.PP +You may add and remove DNS servers as well as view the settings. + +.SH OPTIONS +The \fBnetwork dns\fR command offers various commands: + +\fBadd []\fR +.RS 4 +A new DNS server may be added to the list by the \fBadd\fR command. A priority that +will rank the server may optionally be given. +.PP +\fB\fR must be a valid IP address and \fB\fR must be an integer. +The smaller the number, the higher is the rank of the server. +.RE +.PP + +\fBremove \fR +.RS 4 +A server may be removed by this command where \fB\fR must an IP address. +.RE +.PP + +\fBlist\fR +.RS 4 +Outputs a list of all servers that are currently in use. +.RE +.PP + +\fBupdate\fR +.RS 4 +This command will recreate the system's configuration file. It should not be +required to use this command very often. +.RE +.PP + +.SH CONFIG OPTIONS +These options may be set with the \fBnetwork-config\fR(8) command: + +\fBDNS_USE_LOCAL_RESOLVER\fR = [\fBtrue\fR|false] +.RS 4 +This option defines whether the local DNS resolver should be used or not. +.PP +Basically, the option adds localhost to the list of nameservers in +\fBresolv.conf\fR(5). +.RE +.PP + +\fBDNS_RANDOMIZE\fR = [true|\fBfalse\fR] +.RS 4 +This option will break the DNS server ranks and will query them in a +random order which is useful to load-balance multiple DNS servers. +.RE +.PP + +.SH SEE ALSO +network(8), network-config(8) + +.SH AUTHOR +Michael Tremer (michael.tremer@ipfire.org) diff --git a/man/network.8.in b/man/network.8.in index e8f52677..e013a276 100644 --- a/man/network.8.in +++ b/man/network.8.in @@ -105,6 +105,12 @@ after the next reboot. .RE .PP +\fBdns ...\fR +.RS 4 +The \fBdns\fR command will help you configuring the local DNS servers. +.RE +.PP + \fBreset\fR .RS 4 The \fBreset\fR command will reset all network configuration. That means all zone configurations @@ -122,6 +128,7 @@ Please report all bugs to the official bugtracker at http://bugs.ipfire.org/. .SH SEE ALSO network-config(8), network-device(8), +network-dns(8), network-port(8), network-zone(8) diff --git a/network b/network index 3e6b0935..3ecc439b 100755 --- a/network +++ b/network @@ -496,6 +496,9 @@ function cli_reset() { port_remove ${port} done + # Flush all DNS servers. + dns_server_flush + # Re-run the initialization functions init_run @@ -528,13 +531,53 @@ function cli_help() { hook_exec ${type} ${what} help } +function cli_dns() { + if cli_help_requested $@; then + cli_show_man network-dns + exit ${EXIT_OK} + fi + + # Get the command. + local cmd=${1}; shift + if [ -z "${cmd}" ]; then + cli_show_man network-dns + exit ${EXIT_ERROR} + fi + + case "${cmd}" in + list) + __dns_server_println "SERVER" "PRIORITY" + dns_server_list + ;; + add) + log INFO "Adding new DNS server: ${server}..." + dns_server_add $@ + ;; + remove) + log INFO "Removing DNS server: ${server}..." + dns_server_remove $@ + ;; + update) + # Just run the update afterwards. + ;; + *) + error "No such command: ${cmd}" + exit ${EXIT_ERROR} + esac + + # Update the local DNS configuration after changes have been made. + dns_generate_resolvconf + + exit ${EXIT_OK} +} + # Process the given action case "${action}" in init) init_run ;; - config|hostname|port|device|zone|start|stop|restart|status|reset) + config|hostname|port|device|zone|start|stop|restart|status|reset|dns) cli_${action} $@ ;;