update dnsmasq to 2.78 for CVE fix

This commit is contained in:
coolsnowwolf 2017-10-13 22:25:22 +08:00
parent fe825bbce6
commit b29e9ad979
13 changed files with 574 additions and 356 deletions

View File

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_VERSION:=2.76
PKG_RELEASE:=12
PKG_VERSION:=2.78
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
PKG_MD5SUM:=00f5ee66b4e4b7f14538bf62ae3c9461
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/
PKG_HASH:=89949f438c74b0c7543f06689c319484bd126cc4b1f8c745c742ab397681252b
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
@ -37,6 +37,7 @@ define Package/dnsmasq/Default
CATEGORY:=Base system
TITLE:=DNS and DHCP server
URL:=http://www.thekelleys.org.uk/dnsmasq/
DEPENDS:=+libubus
USERID:=dnsmasq=453:dnsmasq=453
endef
@ -48,14 +49,14 @@ endef
define Package/dnsmasq-dhcpv6
$(call Package/dnsmasq/Default)
TITLE += (with DHCPv6 support)
DEPENDS:=@IPV6
DEPENDS+=@IPV6
VARIANT:=dhcpv6
endef
define Package/dnsmasq-full
$(call Package/dnsmasq/Default)
TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset, Conntrack, NO_ID enabled by default)
DEPENDS:=+PACKAGE_dnsmasq_full_dnssec:libnettle \
DEPENDS+=+PACKAGE_dnsmasq_full_dnssec:libnettle \
+PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \
+PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack
VARIANT:=full
@ -137,7 +138,7 @@ endif
MAKE_FLAGS := \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS)" \
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
COPTS="$(COPTS)" \
PREFIX="/usr"
@ -150,8 +151,17 @@ define Package/dnsmasq/install
$(INSTALL_DATA) ./files/dnsmasq.conf $(1)/etc/dnsmasq.conf
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
$(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp
$(INSTALL_DIR) $(1)/etc/hotplug.d/neigh
$(INSTALL_DIR) $(1)/etc/hotplug.d/ntp
$(INSTALL_DIR) $(1)/etc/hotplug.d/tftp
$(INSTALL_DATA) ./files/dnsmasqsec.hotplug $(1)/etc/hotplug.d/ntp/25-dnsmasqsec
$(INSTALL_DIR) $(1)/usr/share/dnsmasq
$(INSTALL_DATA) ./files/rfc6761.conf $(1)/usr/share/dnsmasq/
$(INSTALL_DIR) $(1)/usr/lib/dnsmasq
$(INSTALL_BIN) ./files/dhcp-script.sh $(1)/usr/lib/dnsmasq/dhcp-script.sh
$(INSTALL_DIR) $(1)/usr/share/acl.d
$(INSTALL_DATA) ./files/dnsmasq_acl.json $(1)/usr/share/acl.d/
endef
Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)

View File

@ -0,0 +1,46 @@
#!/bin/sh
[ -f "$USER_DHCPSCRIPT" ] && . "$USER_DHCPSCRIPT" "$@"
case "$1" in
add)
export ACTION="add"
export MACADDR="$2"
export IPADDR="$3"
export HOSTNAME="$4"
exec /sbin/hotplug-call dhcp
;;
del)
export ACTION="remove"
export MACADDR="$2"
export IPADDR="$3"
export HOSTNAME="$4"
exec /sbin/hotplug-call dhcp
;;
old)
export ACTION="update"
export MACADDR="$2"
export IPADDR="$3"
export HOSTNAME="$4"
exec /sbin/hotplug-call dhcp
;;
arp-add)
export ACTION="add"
export MACADDR="$2"
export IPADDR="$3"
exec /sbin/hotplug-call neigh
;;
arp-del)
export ACTION="remove"
export MACADDR="$2"
export IPADDR="$3"
exec /sbin/hotplug-call neigh
;;
tftp)
export ACTION="add"
export TFTP_SIZE="$2"
export TFTP_ADDR="$3"
export TFTP_PATH="$4"
exec /sbin/hotplug-call tftp
;;
esac

View File

@ -15,7 +15,7 @@ config dnsmasq
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
#list server '/mycompany.local/1.2.3.4'
#option nonwildcard 1
option nonwildcard 1 # bind to & keep track of interfaces
#list interface br-lan
#list notinterface lo
#list bogusnxdomain '64.94.110.11'

View File

@ -8,6 +8,8 @@ PROG=/usr/sbin/dnsmasq
ADD_LOCAL_DOMAIN=1
ADD_LOCAL_HOSTNAME=1
ADD_WAN_FQDN=0
ADD_LOCAL_FQDN=""
BASECONFIGFILE="/var/etc/dnsmasq.conf"
BASEHOSTFILE="/tmp/hosts/dhcp"
@ -15,6 +17,10 @@ BASETIMESTAMPFILE="/etc/dnsmasq.time"
TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
TIMEVALIDFILE="/var/state/dnsmasqsec"
BASEDHCPSTAMPFILE="/var/run/dnsmasq"
RFC6761FILE="/usr/share/dnsmasq/rfc6761.conf"
DHCPSCRIPT="/usr/lib/dnsmasq/dhcp-script.sh"
DNSMASQ_DHCP_VER=4
xappend() {
local value="$1"
@ -23,22 +29,22 @@ xappend() {
}
hex_to_hostid() {
local var="$1"
local hex="${2#0x}" # strip optional "0x" prefix
local var="$1"
local hex="${2#0x}" # strip optional "0x" prefix
if [ -n "${hex//[0-9a-fA-F]/}" ]; then
# is invalid hex literal
return 1
fi
if [ -n "${hex//[0-9a-fA-F]/}" ]; then
# is invalid hex literal
return 1
fi
# convert into host id
export "$var=$(
printf "%0x:%0x" \
$(((0x$hex >> 16) % 65536)) \
$(( 0x$hex % 256))
)"
# convert into host id
export "$var=$(
printf "%0x:%0x" \
$(((0x$hex >> 16) % 65536)) \
$(( 0x$hex % 65536))
)"
return 0
return 0
}
dhcp_calc() {
@ -83,12 +89,24 @@ log_once() {
logger -t dnsmasq "$@"
}
has_handler() {
local file
for file in /etc/hotplug.d/dhcp/* /etc/hotplug.d/tftp/* /etc/hotplug.d/neigh/*; do
[ -f "$file" ] && return 0
done
return 1
}
append_bool() {
local section="$1"
local option="$2"
local value="$3"
local default="$4"
local _loctmp
config_get_bool _loctmp "$section" "$option" 0
[ -z "$default" ] && default="0"
config_get_bool _loctmp "$section" "$option" "$default"
[ $_loctmp -gt 0 ] && xappend "$value"
}
@ -107,6 +125,10 @@ append_server() {
xappend "--server=$1"
}
append_rev_server() {
xappend "--rev-server=$1"
}
append_address() {
xappend "--address=$1"
}
@ -116,12 +138,12 @@ append_ipset() {
}
append_interface() {
network_get_device ifname "$1" || return
network_get_device ifname "$1" || ifname="$1"
xappend "--interface=$ifname"
}
append_notinterface() {
network_get_device ifname "$1" || return
network_get_device ifname "$1" || ifname="$1"
xappend "--except-interface=$ifname"
}
@ -137,6 +159,10 @@ append_pxe_service() {
xappend "--pxe-service=$1"
}
append_interface_name() {
xappend "--interface-name=$1,$2"
}
filter_dnsmasq() {
local cfg="$1" func="$2" match_cfg="$3" found_cfg
@ -180,6 +206,7 @@ dhcp_remoteid_add() {
}
dhcp_circuitid_add() {
# TODO: DHCPV6 does not have circuitid; catch "option6:"
local cfg="$1"
config_get networkid "$cfg" networkid
@ -212,6 +239,7 @@ dhcp_userclass_add() {
}
dhcp_vendorclass_add() {
# TODO: DHCPV6 vendor class has stricter definitions; catch? fixup?
local cfg="$1"
config_get networkid "$cfg" networkid
@ -245,6 +273,7 @@ dhcp_match_add() {
dhcp_host_add() {
local cfg="$1"
local hosttag nametime addrs duids
config_get_bool force "$cfg" force 0
@ -256,7 +285,9 @@ dhcp_host_add() {
config_get name "$cfg" name
config_get ip "$cfg" ip
[ -n "$ip" -o -n "$name" ] || return 0
config_get hostid "$cfg" hostid
[ -n "$ip" -o -n "$name" -o -n "$hostid" ] || return 0
config_get_bool dns "$cfg" dns 0
[ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && {
@ -264,35 +295,105 @@ dhcp_host_add() {
}
config_get mac "$cfg" mac
config_get duid "$cfg" duid
config_get tag "$cfg" tag
if [ -n "$mac" ]; then
# --dhcp-host=00:20:e0:3b:13:af,192.168.0.199,lap
# many MAC are possible to track a laptop ON/OFF dock
macs=""
for m in $mac; do append macs "$m" ","; done
else
# --dhcp-host=lap,192.168.0.199
fi
if [ $DNSMASQ_DHCP_VER -eq 6 -a -n "$duid" ]; then
# --dhcp-host=id:00:03:00:01:12:00:00:01:02:03,[::beef],lap
# one (virtual) machine gets one DUID per RFC3315
duids="id:${duid// */}"
fi
if [ -z "$macs" -a -z "$duids" ]; then
# --dhcp-host=lap,192.168.0.199,[::beef]
[ -n "$name" ] || return 0
macs="$name"
name=""
fi
config_get tag "$cfg" tag
if [ -n "$hostid" ]; then
hex_to_hostid hostid "$hostid"
fi
if [ "$DHCPv6CAPABLE" -eq 1 ]; then
config_get hostid "$cfg" hostid
if [ -n "$hostid" ]; then
hex_to_hostid hostid "$hostid"
fi
tags=""
if [ -n "$tag" ]; then
for t in $tag; do append tags "$t" ",set:"; done
fi
config_get_bool broadcast "$cfg" broadcast 0
[ "$broadcast" = "0" ] && broadcast=
config_get leasetime "$cfg" leasetime
xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${broadcast:+,set:needs-broadcast}${tag:+,set:$tag}${ip:+,$ip${hostid:+,[::$hostid]}}${name:+,$name}${leasetime:+,$leasetime}"
[ "$broadcast" = "0" ] && broadcast= || broadcast=",set:needs-broadcast"
hosttag="${networkid:+,set:${networkid}}${tags:+,set:${tags}}$broadcast"
nametime="${name:+,$name}${leasetime:+,$leasetime}"
if [ $DNSMASQ_DHCP_VER -eq 6 ]; then
addrs="${ip:+,$ip}${hostid:+,[::$hostid]}"
xappend "--dhcp-host=$macs${duids:+,$duids}$hosttag$addrs$nametime"
else
xappend "--dhcp-host=$macs$hosttag${ip:+,$ip}$nametime"
fi
}
dhcp_this_host_add() {
local net="$1"
local ifname="$2"
local mode="$3"
local routerstub routername ifdashname
local lanaddr lanaddr6 lanaddrs6 ulaprefix
if [ "$mode" -gt 0 ] ; then
ifdashname="${ifname//./-}"
routerstub="$( md5sum /etc/os-release )"
routerstub="router-${routerstub// */}"
routername="$( uci_get system @system[0] hostname $routerstub )"
if [ "$mode" -gt 1 ] ; then
if [ "$mode" -gt 2 ] ; then
if [ "$mode" -gt 3 ] ; then
append_interface_name "$ifdashname.$routername.$DOMAIN" "$ifname"
fi
append_interface_name "$routername.$DOMAIN" "$ifname"
fi
# All IP addresses discovered by dnsmasq will be labeled (except fe80::)
append_interface_name "$routername" "$ifname"
else
# This uses a static host file entry for only limited addresses.
# Use dnsmasq option "--expandhosts" to enable FQDN on host files.
ulaprefix="$(uci_get network @globals[0] ula_prefix)"
network_get_ipaddr lanaddr "$net"
network_get_ipaddrs6 lanaddrs6 "$net"
if [ -n "$lanaddr" ] ; then
dhcp_domain_add "" "$routername" "$lanaddr"
fi
if [ -n "$ulaprefix" -a -n "$lanaddrs6" ] ; then
for lanaddr6 in $lanaddrs6 ; do
case "$lanaddr6" in
"${ulaprefix%%:/*}"*)
dhcp_domain_add "" "$routername" "$lanaddr6"
;;
esac
done
fi
fi
fi
}
dhcp_tag_add() {
# NOTE: dnsmasq has explicit "option6:" prefix for DHCPv6 so no collisions
local cfg="$1"
tag="$cfg"
@ -323,6 +424,7 @@ dhcp_mac_add() {
}
dhcp_boot_add() {
# TODO: BOOTURL is different between DHCPv4 and DHCPv6
local cfg="$1"
config_get networkid "$cfg" networkid
@ -345,24 +447,30 @@ dhcp_boot_add() {
dhcp_add() {
local cfg="$1"
local dhcp6range="::"
local nettag
local tags
config_get net "$cfg" interface
[ -n "$net" ] || return 0
config_get dhcpv4 "$cfg" dhcpv4
[ "$dhcpv4" != "disabled" ] || return 0
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || networkid="$net"
network_get_subnet subnet "$net" || return 0
network_get_device ifname "$net" || return 0
network_get_protocol proto "$net" || return 0
[ "$cachelocal" = "0" ] && network_get_dnsserver dnsserver "$net" && {
DNS_SERVERS="$DNS_SERVERS $dnsserver"
}
append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0
append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && {
# Many ISP do not have useful names for DHCP customers (your WAN).
dhcp_this_host_add "$net" "$ifname" "$ADD_WAN_FQDN"
return 0
}
network_get_subnet subnet "$net" || return 0
network_get_protocol proto "$net" || return 0
# Do not support non-static interfaces for now
[ static = "$proto" ] || return 0
@ -374,35 +482,142 @@ dhcp_add() {
config_get_bool force "$cfg" force 0
[ $force -gt 0 ] || dhcp_check "$ifname" || return 0
config_get start "$cfg" start
config_get limit "$cfg" limit
config_get leasetime "$cfg" leasetime
config_get start "$cfg" start 100
config_get limit "$cfg" limit 150
config_get leasetime "$cfg" leasetime 12h
config_get options "$cfg" options
config_get_bool dynamicdhcp "$cfg" dynamicdhcp 1
leasetime="${leasetime:-12h}"
start="$(dhcp_calc "${start:-100}")"
limit="${limit:-150}"
[ "$limit" -gt 0 ] && limit=$((limit-1))
eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)"
if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
config_get dhcpv4 "$cfg" dhcpv4
config_get dhcpv6 "$cfg" dhcpv6
dhcp_option_add "$cfg" "$networkid"
config_get ra "$cfg" ra
config_get ra_management "$cfg" ra_management
config_get ra_preference "$cfg" ra_preference
config_get dns "$cfg" dns
config_list_foreach "$cfg" "interface_name" append_interface_name "$ifname"
# Put the router host name on this DHCP served interface address(es)
dhcp_this_host_add "$net" "$ifname" "$ADD_LOCAL_FQDN"
start="$( dhcp_calc "$start" )"
add_tag() {
tags="${tags}tag:$1,"
}
config_list_foreach "$cfg" tag add_tag
nettag="${networkid:+set:${networkid},}"
if [ "$limit" -gt 0 ] ; then
limit=$((limit-1))
fi
eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)"
if [ "$dynamicdhcp" = "0" ] ; then
END="static"
dhcp6range="::,static"
else
dhcp6range="::1000,::ffff"
fi
if [ "$dhcpv4" != "disabled" ] ; then
xappend "--dhcp-range=$tags$nettag$START,$END,$NETMASK,$leasetime${options:+ $options}"
fi
if [ $DNSMASQ_DHCP_VER -eq 6 -a "$ra" = "server" ] ; then
# Note: dnsmasq cannot just be a DHCPv6 server (all-in-1)
# and let some other machine(s) send RA pointing to it.
case $ra_preference in
*high*)
xappend "--ra-param=$ifname,high,0,7200"
;;
*low*)
xappend "--ra-param=$ifname,low,0,7200"
;;
*)
# Send UNSOLICITED RA at default interval and live for 2 hours.
# TODO: convert flexible lease time into route life time (only seconds).
xappend "--ra-param=$ifname,0,7200"
;;
esac
if [ "$dhcpv6" = "disabled" ] ; then
ra_management="3"
fi
case $ra_management in
0)
# SLACC with DCHP for extended options
xappend "--dhcp-range=$nettag::,constructor:$ifname,ra-stateless,ra-names"
;;
2)
# DHCP address and RA only for management redirection
xappend "--dhcp-range=$nettag$dhcp6range,constructor:$ifname,$leasetime"
;;
3)
# SLAAC only but dnsmasq attempts to link HOSTNAME, DHCPv4 MAC, and SLAAC
xappend "--dhcp-range=$nettag::,constructor:$ifname,ra-only,ra-names"
;;
*)
# SLAAC and full DHCP
xappend "--dhcp-range=$nettag$dhcp6range,constructor:$ifname,slaac,ra-names,$leasetime"
;;
esac
if [ -n "$dns" ]; then
dnss=""
for d in $dns; do append dnss "[$d]" ","; done
else
dnss="[::]"
fi
dhcp_option_append "option6:dns-server,$dnss" "$networkid"
fi
dhcp_option_add "$cfg" "$networkid" 0
dhcp_option_add "$cfg" "$networkid" 2
}
dhcp_option_add() {
local cfg="$1"
dhcp_option_append() {
local option="$1"
local networkid="$2"
local force="$3"
xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$option"
}
dhcp_option_add() {
# NOTE: dnsmasq has explicit "option6:" prefix for DHCPv6 so no collisions
local cfg="$1"
local networkid="$2"
local force="$3"
local opt="dhcp_option"
[ "$force" = "0" ] && force=
[ "$force" = "2" ] && opt="dhcp_option_force"
config_get dhcp_option "$cfg" dhcp_option
for o in $dhcp_option; do
xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o"
done
local list_len
config_get list_len "$cfg" "${opt}_LENGTH"
if [ -n "$list_len" ]; then
config_list_foreach "$cfg" "$opt" dhcp_option_append "$networkid" "$force"
else
config_get dhcp_option "$cfg" "$opt"
[ -n "$dhcp_option" ] && echo "Warning: the 'option $opt' syntax is deprecated, use 'list $opt'" >&2
local option
for option in $dhcp_option; do
dhcp_option_append "$option" "$networkid" "$force"
done
fi
}
dhcp_domain_add() {
@ -507,13 +722,14 @@ dhcp_relay_add() {
if [ -z "$interface" ]; then
xappend "--dhcp-relay=$local_addr,$server_addr"
else
xappend "--dhcp-relay=$local_addr,$server_addr,$interface"
network_get_device ifname "$interface" || return
xappend "--dhcp-relay=$local_addr,$server_addr,$ifname"
fi
}
dnsmasq_start()
{
local cfg="$1" disabled
local cfg="$1" disabled resolvfile user_dhcpscript
config_get_bool disabled "$cfg" disabled 0
[ "$disabled" -gt 0 ] && return 0
@ -546,6 +762,41 @@ dnsmasq_start()
$PROG --version | grep -osqE "^Compile time options:.* DHCPv6( |$)" && DHCPv6CAPABLE=1 || DHCPv6CAPABLE=0
if [ -x /usr/sbin/odhcpd -a -x /etc/init.d/odhcpd ] ; then
local odhcpd_is_main odhcpd_is_enabled
config_get odhcpd_is_main odhcpd maindhcp 0
/etc/init.d/odhcpd enabled && odhcpd_is_enabled=1 || odhcpd_is_enabled=0
if [ "$odhcpd_is_enabled" -eq 0 -a "$DHCPv6CAPABLE" -eq 1 ] ; then
# DHCP V4 and V6 in DNSMASQ
DNSMASQ_DHCP_VER=6
elif [ "$odhcpd_is_main" -gt 0 ] ; then
# ODHCPD is doing it all
DNSMASQ_DHCP_VER=0
else
# You have ODHCPD but use DNSMASQ for DHCPV4
DNSMASQ_DHCP_VER=4
fi
elif [ "$DHCPv6CAPABLE" -eq 1 ] ; then
# DHCP V4 and V6 in DNSMASQ
DNSMASQ_DHCP_VER=6
else
DNSMASQ_DHCP_VER=4
fi
# Allow DHCP/DHCPv6 to be handled by ISC DHCPD
if [ -x /usr/sbin/dhcpd ] ; then
if [ -x /etc/init.d/dhcpd ] ; then
/etc/init.d/dhcpd enabled && DNSMASQ_DHCP_VER=0
fi
if [ -x /etc/init.d/dhcpd6 -a "$DNSMASQ_DHCP_VER" -gt 0 ] ; then
/etc/init.d/dhcpd6 enabled && DNSMASQ_DHCP_VER=4
fi
fi
append_bool "$cfg" authoritative "--dhcp-authoritative"
append_bool "$cfg" nodaemon "--no-daemon"
append_bool "$cfg" domainneeded "--domain-needed"
@ -558,12 +809,11 @@ dnsmasq_start()
append_bool "$cfg" localise_queries "--localise-queries"
append_bool "$cfg" readethers "--read-ethers"
append_bool "$cfg" dbus "--enable-dbus"
append_bool "$cfg" boguspriv "--bogus-priv"
append_bool "$cfg" expandhosts "--expand-hosts"
config_get tftp_root "$cfg" "tftp_root"
[ -d "$tftp_root" ] && append_bool "$cfg" enable_tftp "--enable-tftp"
[ -n "$tftp_root" ] && mkdir -p "$tftp_root" && append_bool "$cfg" enable_tftp "--enable-tftp"
append_bool "$cfg" tftp_no_fail "--tftp-no-fail"
append_bool "$cfg" nonwildcard "--bind-dynamic"
append_bool "$cfg" nonwildcard "--bind-dynamic" 1
append_bool "$cfg" fqdn "--dhcp-fqdn"
append_bool "$cfg" proxydnssec "--proxy-dnssec"
append_bool "$cfg" localservice "--local-service"
@ -573,7 +823,8 @@ dnsmasq_start()
append_bool "$cfg" allservers "--all-servers"
append_bool "$cfg" noping "--no-ping"
append_parm "$cfg" dhcpscript "--dhcp-script"
append_parm "$cfg" logfacility "--log-facility"
append_parm "$cfg" cachesize "--cache-size"
append_parm "$cfg" dnsforwardmax "--dns-forward-max"
append_parm "$cfg" port "--port"
@ -585,6 +836,7 @@ dnsmasq_start()
append_parm "$cfg" "domain" "--domain"
append_parm "$cfg" "local" "--server"
config_list_foreach "$cfg" "server" append_server
config_list_foreach "$cfg" "rev_server" append_rev_server
config_list_foreach "$cfg" "address" append_address
config_list_foreach "$cfg" "ipset" append_ipset
config_list_foreach "$cfg" "interface" append_interface
@ -592,7 +844,6 @@ dnsmasq_start()
config_list_foreach "$cfg" "addnhosts" append_addnhosts
config_list_foreach "$cfg" "bogusnxdomain" append_bogusnxdomain
append_parm "$cfg" "leasefile" "--dhcp-leasefile" "/tmp/dhcp.leases"
append_parm "$cfg" "resolvfile" "--resolv-file" "/tmp/resolv.conf.auto"
append_parm "$cfg" "serversfile" "--servers-file"
append_parm "$cfg" "tftp_root" "--tftp-root"
append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
@ -603,12 +854,21 @@ dnsmasq_start()
config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1
config_get ADD_LOCAL_FQDN "$cfg" add_local_fqdn ""
config_get ADD_WAN_FQDN "$cfg" add_wan_fqdn 0
if [ -z "$ADD_LOCAL_FQDN" ] ; then
# maintain support for previous UCI
ADD_LOCAL_FQDN="$ADD_LOCAL_HOSTNAME"
fi
config_get_bool readethers "$cfg" readethers
[ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers
config_get resolvfile $cfg resolvfile
config_get dhcpscript $cfg dhcpscript
config_get user_dhcpscript $cfg dhcpscript
if has_handler || [ -n "$user_dhcpscript" ]; then
xappend "--dhcp-script=$DHCPSCRIPT"
fi
config_get leasefile $cfg leasefile "/tmp/dhcp.leases"
[ -n "$leasefile" -a \! -e "$leasefile" ] && touch "$leasefile"
@ -621,6 +881,8 @@ dnsmasq_start()
[ -n "$resolvfile" -a \! -e "$resolvfile" ] && touch "$resolvfile"
fi
[ -n "$resolvfile" ] && xappend "--resolv-file=$resolvfile"
config_get hostsfile "$cfg" dhcphostsfile
[ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile"
@ -667,10 +929,11 @@ dnsmasq_start()
}
dhcp_option_add "$cfg" "" 0
dhcp_option_add "$cfg" "" 2
xappend "--dhcp-broadcast=tag:needs-broadcast"
xappend "--addn-hosts=$HOSTFILE"
xappend "--addn-hosts=$(dirname $HOSTFILE)"
config_get dnsmasqconfdir "$cfg" confdir "/tmp/dnsmasq.d"
[ ! -d "$dnsmasqconfdir" ] && mkdir -p $dnsmasqconfdir
@ -700,37 +963,31 @@ dnsmasq_start()
config_foreach filter_dnsmasq hostrecord dhcp_hostrecord_add "$cfg"
config_foreach filter_dnsmasq relay dhcp_relay_add "$cfg"
# add own hostname
[ $ADD_LOCAL_HOSTNAME -eq 1 ] && {
local lanaddr lanaddr6
local ulaprefix="$(uci_get network @globals[0] ula_prefix)"
local hostname="$(uci_get system @system[0] hostname Lede)"
network_get_ipaddr lanaddr "lan" && {
dhcp_domain_add "" "$hostname" "$lanaddr"
}
[ -n "$ulaprefix" ] && network_get_ipaddrs6 lanaddr6 "lan" && {
for lanaddr6 in $lanaddr6; do
case "$lanaddr6" in
"${ulaprefix%%:/*}"*)
dhcp_domain_add "" "$hostname" "$lanaddr6"
;;
esac
done
}
}
echo >> $CONFIGFILE_TMP
config_foreach filter_dnsmasq srvhost dhcp_srv_add "$cfg"
config_foreach filter_dnsmasq mxhost dhcp_mx_add "$cfg"
echo >> $CONFIGFILE_TMP
config_get odhcpd_is_active odhcpd maindhcp
if [ "$odhcpd_is_active" != "1" ]; then
config_get_bool boguspriv "$cfg" boguspriv 1
[ "$boguspriv" -gt 0 ] && {
xappend "--bogus-priv"
[ -r "$RFC6761FILE" ] && xappend "--conf-file=$RFC6761FILE"
}
if [ "$DNSMASQ_DHCP_VER" -gt 4 ] ; then
# Enable RA feature for when/if it is constructed,
# and RA is selected per interface pool (RA, DHCP, or both),
# but no one (should) want RA broadcast in syslog
config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
xappend "--enable-ra"
xappend "--quiet-ra"
append_bool "$cfg" quietdhcp "--quiet-dhcp6"
elif [ "$DNSMASQ_DHCP_VER" -gt 0 ] ; then
config_foreach filter_dnsmasq dhcp dhcp_add "$cfg"
fi
echo >> $CONFIGFILE_TMP
config_foreach filter_dnsmasq cname dhcp_cname_add "$cfg"
echo >> $CONFIGFILE_TMP
@ -752,6 +1009,7 @@ dnsmasq_start()
procd_open_instance $cfg
procd_set_param command $PROG -C $CONFIGFILE -k -x /var/run/dnsmasq/dnsmasq."${cfg}".pid
procd_set_param file $CONFIGFILE
[ -n "$user_dhcpscript" ] && procd_set_param env USER_DHCPSCRIPT="$user_dhcpscript"
procd_set_param respawn
local dnsmasqconffile="/etc/dnsmasq.${cfg}.conf"
@ -760,7 +1018,7 @@ dnsmasq_start()
fi
procd_add_jail dnsmasq ubus log
procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom $dnsmasqconffile $dnsmasqconfdir $resolvfile $dhcpscript /etc/hosts /etc/ethers $EXTRA_MOUNT
procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE $RFC6761FILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom $dnsmasqconffile $dnsmasqconfdir $resolvfile $user_dhcpscript /etc/hosts /etc/ethers /sbin/hotplug-call $EXTRA_MOUNT $DHCPSCRIPT
procd_add_jail_mount_rw /var/run/dnsmasq/ $leasefile
procd_close_instance

View File

@ -0,0 +1,4 @@
{
"user": "dnsmasq",
"publish": [ "dnsmasq" ]
}

View File

@ -1,5 +1,7 @@
#!/bin/sh
. /lib/functions/procd.sh
TIMEVALIDFILE="/var/state/dnsmasqsec"
[ "$ACTION" = stratum ] || exit 0
@ -7,8 +9,6 @@ TIMEVALIDFILE="/var/state/dnsmasqsec"
[ -f "$TIMEVALIDFILE" ] || {
echo "ntpd says time is valid" >$TIMEVALIDFILE
/etc/init.d/dnsmasq enabled && {
pid=$(pidof dnsmasq)
[ "$(readlink /proc/$pid/exe)" = "/usr/sbin/dnsmasq" ] && kill -SIGHUP $pid \
|| /etc/init.d/dnsmasq restart
procd_send_signal dnsmasq
}
}

View File

@ -0,0 +1,15 @@
# RFC6761 included configuration file for dnsmasq
#
# includes a list of domains that should not be forwarded to Internet name servers
# to reduce burden on them, asking questions that they won't know the answer to.
server=/bind/
server=/example/
server=/example.com/
server=/example.org/
server=/example.net/
server=/invalid/
server=/local/
server=/localhost/
server=/onion/
server=/test/

View File

@ -1,47 +0,0 @@
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -147,7 +147,7 @@ void dhcp_packet(time_t now, int pxe_fd)
ssize_t sz;
int iface_index = 0, unicast_dest = 0, is_inform = 0;
int rcvd_iface_index;
- struct in_addr iface_addr;
+ struct in_addr iface_addr, *addrp = NULL;
struct iface_param parm;
#ifdef HAVE_LINUX_NETWORK
struct arpreq arp_req;
@@ -277,11 +277,9 @@ void dhcp_packet(time_t now, int pxe_fd)
{
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
- iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
- else
{
- my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
- return;
+ addrp = &iface_addr;
+ iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
}
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
@@ -300,7 +298,7 @@ void dhcp_packet(time_t now, int pxe_fd)
parm.relay_local.s_addr = 0;
parm.ind = iface_index;
- if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL))
+ if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, NULL))
{
/* If we failed to match the primary address of the interface, see if we've got a --listen-address
for a secondary */
@@ -320,6 +318,12 @@ void dhcp_packet(time_t now, int pxe_fd)
complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
}
+ if (!addrp)
+ {
+ my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
+ return;
+ }
+
if (!iface_enumerate(AF_INET, &parm, complete_context))
return;

View File

@ -44,67 +44,22 @@
(buffer = safe_malloc(BUFF_SZ)) &&
(ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
(bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
@@ -168,62 +149,16 @@ static int new_add_to_ipset(const char *
}
-static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)
-{
- socklen_t size;
- struct ip_set_req_adt_get {
- unsigned op;
- unsigned version;
- union {
- char name[IPSET_MAXNAMELEN];
- uint16_t index;
- } set;
- char typename[IPSET_MAXNAMELEN];
- } req_adt_get;
- struct ip_set_req_adt {
- unsigned op;
- uint16_t index;
- uint32_t ip;
- } req_adt;
-
- if (strlen(setname) >= sizeof(req_adt_get.set.name))
- {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- req_adt_get.op = 0x10;
- req_adt_get.version = 3;
- strcpy(req_adt_get.set.name, setname);
- size = sizeof(req_adt_get);
- if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0)
- return -1;
- req_adt.op = remove ? 0x102 : 0x101;
- req_adt.index = req_adt_get.set.index;
- req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);
- if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
- return -1;
-
- return 0;
-}
-
-
-
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
{
int af = AF_INET;
#ifdef HAVE_IPV6
@@ -217,17 +198,10 @@ int add_to_ipset(const char *setname, co
if (flags & F_IPV6)
- {
{
af = AF_INET6;
- /* old method only supports IPv4 */
- if (old_kernel)
- return -1;
- }
- {
- errno = EAFNOSUPPORT ;
- ret = -1;
- }
}
#endif
- return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
+ return new_add_to_ipset(setname, ipaddr, af, remove);
}
- if (ret != -1)
- ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
+ ret = new_add_to_ipset(setname, ipaddr, af, remove);
#endif
if (ret == -1)
my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));

View File

@ -1,149 +0,0 @@
From f6bea86c78ba9efbd01da3dd2fb18764ec806290 Mon Sep 17 00:00:00 2001
From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
Date: Wed, 7 Sep 2016 09:35:07 +0100
Subject: [PATCH] dnsmasq: compile time option NO_ID
Some consider it good practice to obscure software version numbers to
clients. Compiling with -DNO_ID removes the *.bind info structure.
This includes: version, author, copyright, cachesize, cache insertions,
evictions, misses & hits, auth & servers.
Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
---
src/cache.c | 2 ++
src/config.h | 5 +++++
src/dnsmasq.h | 4 ++++
src/option.c | 8 ++++++--
src/rfc1035.c | 3 ++-
5 files changed, 19 insertions(+), 3 deletions(-)
--- a/src/cache.c
+++ b/src/cache.c
@@ -1290,6 +1290,7 @@ void cache_add_dhcp_entry(char *host_nam
}
#endif
+#ifndef NO_ID
int cache_make_stat(struct txt_record *t)
{
static char *buff = NULL;
@@ -1385,6 +1386,7 @@ int cache_make_stat(struct txt_record *t
*buff = len;
return 1;
}
+#endif
/* There can be names in the cache containing control chars, don't
mess up logging or open security holes. */
--- a/src/config.h
+++ b/src/config.h
@@ -120,6 +120,8 @@ HAVE_LOOP
HAVE_INOTIFY
use the Linux inotify facility to efficiently re-read configuration files.
+NO_ID
+ Don't report *.bind CHAOS info to clients.
NO_IPV6
NO_TFTP
NO_DHCP
@@ -434,6 +436,9 @@ static char *compile_opts =
"no-"
#endif
"DNSSEC "
+#ifdef NO_ID
+"no-ID "
+#endif
#ifndef HAVE_LOOP
"no-"
#endif
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -286,6 +286,7 @@ struct naptr {
struct naptr *next;
};
+#ifndef NO_ID
#define TXT_STAT_CACHESIZE 1
#define TXT_STAT_INSERTS 2
#define TXT_STAT_EVICTIONS 3
@@ -293,6 +294,7 @@ struct naptr {
#define TXT_STAT_HITS 5
#define TXT_STAT_AUTH 6
#define TXT_STAT_SERVERS 7
+#endif
struct txt_record {
char *name;
@@ -1078,7 +1080,9 @@ void cache_add_dhcp_entry(char *host_nam
struct in_addr a_record_from_hosts(char *name, time_t now);
void cache_unhash_dhcp(void);
void dump_cache(time_t now);
+#ifndef NO_ID
int cache_make_stat(struct txt_record *t);
+#endif
char *cache_get_name(struct crec *crecp);
char *cache_get_cname_target(struct crec *crecp);
struct crec *cache_enumerate(int init);
--- a/src/option.c
+++ b/src/option.c
@@ -657,7 +657,8 @@ static int atoi_check8(char *a, int *res
return 1;
}
#endif
-
+
+#ifndef NO_ID
static void add_txt(char *name, char *txt, int stat)
{
struct txt_record *r = opt_malloc(sizeof(struct txt_record));
@@ -670,13 +671,14 @@ static void add_txt(char *name, char *tx
*(r->txt) = len;
memcpy((r->txt)+1, txt, len);
}
-
+
r->stat = stat;
r->name = opt_string_alloc(name);
r->next = daemon->txt;
daemon->txt = r;
r->class = C_CHAOS;
}
+#endif
static void do_usage(void)
{
@@ -4515,6 +4517,7 @@ void read_opts(int argc, char **argv, ch
daemon->soa_expiry = SOA_EXPIRY;
daemon->max_port = MAX_PORT;
+#ifndef NO_ID
add_txt("version.bind", "dnsmasq-" VERSION, 0 );
add_txt("authors.bind", "Simon Kelley", 0);
add_txt("copyright.bind", COPYRIGHT, 0);
@@ -4527,6 +4530,7 @@ void read_opts(int argc, char **argv, ch
add_txt("auth.bind", NULL, TXT_STAT_AUTH);
#endif
add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
+#endif
while (1)
{
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -1264,6 +1264,7 @@ size_t answer_request(struct dns_header
unsigned long ttl = daemon->local_ttl;
int ok = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
+#ifndef NO_ID
/* Dynamically generate stat record */
if (t->stat != 0)
{
@@ -1271,7 +1272,7 @@ size_t answer_request(struct dns_header
if (!cache_make_stat(t))
ok = 0;
}
-
+#endif
if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
ttl, NULL,
T_TXT, t->class, "t", t->len, t->txt))

View File

@ -35,13 +35,13 @@ Signed-off-by: Steven Barth <steven@midlink.org>
+ if (difftime(now, base) >= 0 && difftime(timestamp_time, now) <= 0)
{
/* time already OK, update timestamp, and do key checking from the start. */
if (utime(daemon->timestamp_file, NULL) == -1)
if (utimes(daemon->timestamp_file, NULL) == -1)
@@ -493,7 +500,7 @@ int setup_timestamp(void)
close(fd);
- timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
+ timestamp_time = timbuf.actime = timbuf.modtime = base;
if (utime(daemon->timestamp_file, &timbuf) == 0)
goto check_and_exit;
}
- timestamp_time = 1420070400; /* 1-1-2015 */
+ timestamp_time = base; /* 1-1-2015 */
tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(daemon->timestamp_file, tv) == 0)

View File

@ -7,7 +7,7 @@ Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -82,7 +82,7 @@ typedef unsigned long long u64;
@@ -88,7 +88,7 @@ typedef unsigned long long u64;
#if defined(HAVE_SOLARIS_NETWORK)
# include <sys/sockio.h>
#endif

View File

@ -0,0 +1,126 @@
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -19,6 +19,8 @@
#include "dnsmasq.h"
+#include <libubus.h>
+
struct daemon *daemon;
static volatile pid_t pid = 0;
@@ -32,6 +34,62 @@ static void fatal_event(struct event_des
static int read_event(int fd, struct event_desc *evp, char **msg);
static void poll_resolv(int force, int do_reload, time_t now);
+static struct ubus_context *ubus;
+static struct blob_buf b;
+
+static struct ubus_object_type ubus_object_type = {
+ .name = "dnsmasq",
+};
+
+static struct ubus_object ubus_object = {
+ .name = "dnsmasq",
+ .type = &ubus_object_type,
+};
+
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name)
+{
+ if (!ubus || !ubus_object.has_subscribers)
+ return;
+
+ blob_buf_init(&b, 0);
+ if (mac)
+ blobmsg_add_string(&b, "mac", mac);
+ if (ip)
+ blobmsg_add_string(&b, "ip", ip);
+ if (name)
+ blobmsg_add_string(&b, "name", name);
+ ubus_notify(ubus, &ubus_object, type, b.head, -1);
+}
+
+static void set_ubus_listeners(void)
+{
+ if (!ubus)
+ return;
+
+ poll_listen(ubus->sock.fd, POLLIN);
+ poll_listen(ubus->sock.fd, POLLERR);
+ poll_listen(ubus->sock.fd, POLLHUP);
+}
+
+static void check_ubus_listeners()
+{
+ if (!ubus) {
+ ubus = ubus_connect(NULL);
+ if (ubus)
+ ubus_add_object(ubus, &ubus_object);
+ else
+ return;
+ }
+
+ if (poll_check(ubus->sock.fd, POLLIN))
+ ubus_handle_event(ubus);
+
+ if (poll_check(ubus->sock.fd, POLLHUP)) {
+ ubus_free(ubus);
+ ubus = NULL;
+ }
+}
+
int main (int argc, char **argv)
{
int bind_fallback = 0;
@@ -911,6 +969,7 @@ int main (int argc, char **argv)
set_dbus_listeners();
#endif
+ set_ubus_listeners();
#ifdef HAVE_DHCP
if (daemon->dhcp || daemon->relay4)
{
@@ -1041,6 +1100,8 @@ int main (int argc, char **argv)
check_dbus_listeners();
#endif
+ check_ubus_listeners();
+
check_dns_listeners(now);
#ifdef HAVE_TFTP
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,7 @@ all : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
top="$(top)" \
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \
+ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) -lubox -lubus" \
-f $(top)/Makefile dnsmasq
mostly_clean :
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1397,6 +1397,8 @@ void emit_dbus_signal(int action, struct
# endif
#endif
+void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name);
+
/* ipset.c */
#ifdef HAVE_IPSET
void ipset_init(void);
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -1621,6 +1621,10 @@ static void log_packet(char *type, void
daemon->namebuff,
string ? string : "",
err ? err : "");
+ if (!strcmp(type, "DHCPACK"))
+ ubus_event_bcast("dhcp.ack", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL);
+ else if (!strcmp(type, "DHCPRELEASE"))
+ ubus_event_bcast("dhcp.release", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL);
}
static void log_options(unsigned char *start, u32 xid)