#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2012 IPFire Network Development Team # # # # 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 . # # # ############################################################################### # 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_SEARCH_DOMAINS="" NETWORK_CONFIG_FILE_PARAMS="${NETWORK_CONFIG_FILE_PARAMS} DNS_SEARCH_DOMAINS" # Set this option to true if the DNS servers should be advertised by # radvd. DNS_ADVERTISE_SERVERS="true" DNS_SERVER_CONFIG_FILE="${NETWORK_CONFIG_DIR}/dns-servers" NETWORK_CONFIG_DNS_SERVER_PARAMS="server priority" # Set the default priority for DNS servers. DNS_SERVER_DEFAULT_PRIORITY="100" DNS_SERVER_DYNAMIC_PRIORITY="10" # Path to the configuration file of the DNS resolver. RESOLV_CONF="/etc/resolv.conf" function dns_get_hostname() { local address=${1} assert isset address ( unset HOSTNAME eval $(ipcalc -h ${address} 2>/dev/null) echo "${HOSTNAME}" ) } function dns_server_list() { [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_OK} local line local ${NETWORK_CONFIG_DNS_SERVER_PARAMS} local format="%-20s %-8s" print "${format}" "SERVER" "PRIORITY" while read -r line; do dns_server_parse_line ${line} || continue print "${format}" "${server}" "${priority}" done < ${DNS_SERVER_CONFIG_FILE} return ${EXIT_OK} } function dns_server_list_sorted() { [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_OK} local servers=$( # First get all servers from the configuration file. while read -r line; do dns_server_parse_line ${line} || continue print "%d %s" "${priority}" "${server}" done < ${DNS_SERVER_CONFIG_FILE} # Then get all dynamically assigned DNS servers. dns_server_get_zone_name_servers ) # Nothing to do if we have got no DNS servers. isset servers || return ${EXIT_OK} # Sort everything we have got. servers=$(sort -g -k1 <<< "${servers}") # Remove the priority bit. local server server_list while read -r priority server; do list_append server_list "${server}" done <<< "${servers}" # Return the list but remove duplicate entries, keeping # the first and removing all others. list_unique ${server_list} return ${EXIT_OK} } function dns_server_add() { local server=${1} assert isset server local priority=${2} if ! isset priority; then priority="${DNS_SERVER_DEFAULT_PRIORITY}" fi assert isinteger priority # Add a new line to the configuration file. print "server=\"%s\" priority=\"%d\"" "${server}" "${priority}" \ >> ${DNS_SERVER_CONFIG_FILE} return ${EXIT_OK} } function dns_server_exists() { local entry=${1} assert isset entry [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_FALSE} local line ${NETWORK_CONFIG_DNS_SERVER_PARAMS} while read -r line; do dns_server_parse_line ${line} || continue [ "${entry}" = "${server}" ] && return ${EXIT_TRUE} done < ${DNS_SERVER_CONFIG_FILE} return ${EXIT_FALSE} } function dns_server_remove() { local entry=${1} assert isset entry # Check if the DNS server configuration file exists. [ -r "${DNS_SERVER_CONFIG_FILE}" ] || return ${EXIT_ERROR} # Create a tempfile. local tempfile=$(mktemp) local line ${NETWORK_CONFIG_DNS_SERVER_PARAMS} while read -r line; do dns_server_parse_line ${line} || continue # Skip the line with the server we are searching for. [ "${entry}" = "${server}" ] && continue # Re-add the old line. print "${line}" done < ${DNS_SERVER_CONFIG_FILE} > ${tempfile} # Overwrite the old content without the entry that has just been removed. fread "${tempfile}" > ${DNS_SERVER_CONFIG_FILE} # Remove the temporary file. rm -f ${tempfile} return ${EXIT_OK} } function dns_server_flush() { : > ${DNS_SERVER_CONFIG_FILE} } function dns_server_parse_line() { local arg for arg in ${NETWORK_CONFIG_DNS_SERVER_PARAMS}; do assign "${arg}" "" done while read -r arg; do case "${arg}" in server=*) server=$(cli_get_val ${arg}) ;; priority=*) priority=$(cli_get_val ${arg}) ;; esac done <<< "$(args $@)" # The server address must be set. isset server || return ${EXIT_ERROR} # The server address must also be a valid IP address. ip_is_valid ${server} || return ${EXIT_ERROR} # If priority is set, it must be an integer number. if isset priority; then isinteger priority || return ${EXIT_ERROR} # Otherwise assign the default priority. else priority=${DNS_SERVER_DEFAULT_PRIORITY} fi return ${EXIT_OK} } # Update resolv.conf(5) when initializing the network. init_register dns_generate_resolvconf 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 # Write search domains to file. print "# Search domains" >> ${file} local domain for domain in $(dns_get_search_domains); do print "search ${domain}" done >> ${file} print "\n# Nameservers" >> ${file} # 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. for server in $(dns_server_list_sorted); do print "nameserver ${server}" done >> ${file} } function dns_get_search_domains() { # Add search domains. local search_domains="$(unquote ${DNS_SEARCH_DOMAINS})" # Get search domains from DHCP clients, etc. local domain proto zone for zone in $(zones_get_all); do for proto in ${IP_SUPPORTED_PROTOCOLS}; do domain=$(routing_db_get ${zone} ${proto} domain-name) isset domain || continue list_append search_domains "${domainname}" done done # Sort out duplicate entries. list_unique ${search_domains} } function dns_server_get_zone_name_servers() { local priority proto server servers zone for zone in $(zones_get_all); do for proto in ${IP_SUPPORTED_PROTOCOLS}; do priority=$(routing_db_get ${zone} ${proto} domain-name-servers-priority) isset priority || priority="${DNS_SERVER_DYNAMIC_PRIORITY}" servers=$(routing_db_get ${zone} ${proto} domain-name-servers) for server in ${servers}; do print "${priority} ${server}" done done done }