Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
c8a80487
Commit
c8a80487
authored
Mar 05, 2014
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
--local-service. Default protection from DNS amplification attacks.
parent
4ea8e80d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
133 additions
and
2 deletions
+133
-2
CHANGELOG
CHANGELOG
+10
-1
man/dnsmasq.8
man/dnsmasq.8
+8
-0
src/dnsmasq.h
src/dnsmasq.h
+3
-1
src/forward.c
src/forward.c
+62
-0
src/network.c
src/network.c
+42
-0
src/option.c
src/option.c
+8
-0
No files found.
CHANGELOG
View file @
c8a80487
...
@@ -67,7 +67,16 @@ version 2.69
...
@@ -67,7 +67,16 @@ version 2.69
Add --servers-file. Allows dynamic update of upstream servers
Add --servers-file. Allows dynamic update of upstream servers
full access to configuration.
full access to configuration.
Add --local-service. Accept DNS queries only from hosts
whose address is on a local subnet, ie a subnet for which
an interface exists on the server. This option
only has effect is there are no --interface --except-interface,
--listen-address or --auth-server options. It is intended
to be set as a default on installation, to allow
unconfigured installations to be useful but also safe from
being used for DNS amplification attacks.
version 2.68
version 2.68
Use random addresses for DHCPv6 temporary address
Use random addresses for DHCPv6 temporary address
allocations, instead of algorithmically determined stable
allocations, instead of algorithmically determined stable
...
...
man/dnsmasq.8
View file @
c8a80487
...
@@ -208,6 +208,14 @@ resolve in the global DNS to a A and/or AAAA record which points to
...
@@ -208,6 +208,14 @@ resolve in the global DNS to a A and/or AAAA record which points to
the address dnsmasq is listening on. When an interface is specified,
the address dnsmasq is listening on. When an interface is specified,
it may be qualified with "/4" or "/6" to specify only the IPv4 or IPv6
it may be qualified with "/4" or "/6" to specify only the IPv4 or IPv6
addresses associated with the interface.
addresses associated with the interface.
.TP
.B --local-service
Accept DNS queries only from hosts whose address is on a local subnet,
ie a subnet for which an interface exists on the server. This option
only has effect is there are no --interface --except-interface,
--listen-address or --auth-server options. It is intended to be set as
a default on installation, to allow unconfigured installations to be
useful but also safe from being used for DNS amplification attacks.
.TP
.TP
.B \-2, --no-dhcp-interface=<interface name>
.B \-2, --no-dhcp-interface=<interface name>
Do not provide DHCP or TFTP on the specified interface, but do provide DNS service.
Do not provide DHCP or TFTP on the specified interface, but do provide DNS service.
...
...
src/dnsmasq.h
View file @
c8a80487
...
@@ -233,7 +233,8 @@ struct event_desc {
...
@@ -233,7 +233,8 @@ struct event_desc {
#define OPT_DNSSEC_PERMISS 46
#define OPT_DNSSEC_PERMISS 46
#define OPT_DNSSEC_DEBUG 47
#define OPT_DNSSEC_DEBUG 47
#define OPT_DNSSEC_NO_SIGN 48
#define OPT_DNSSEC_NO_SIGN 48
#define OPT_LAST 49
#define OPT_LOCAL_SERVICE 49
#define OPT_LAST 50
/* extra flags for my_syslog, we use a couple of facilities since they are known
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
...
@@ -966,6 +967,7 @@ extern struct daemon {
...
@@ -966,6 +967,7 @@ extern struct daemon {
pid_t
tcp_pids
[
MAX_PROCS
];
pid_t
tcp_pids
[
MAX_PROCS
];
struct
randfd
randomsocks
[
RANDOM_SOCKS
];
struct
randfd
randomsocks
[
RANDOM_SOCKS
];
int
v6pktinfo
;
int
v6pktinfo
;
struct
addrlist
*
interface_addrs
;
/* list of all addresses/prefix lengths associated with all local interfaces */
/* DHCP state */
/* DHCP state */
int
dhcpfd
,
helperfd
,
pxefd
;
int
dhcpfd
,
helperfd
,
pxefd
;
...
...
src/forward.c
View file @
c8a80487
...
@@ -1081,6 +1081,37 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -1081,6 +1081,37 @@ void receive_query(struct listener *listen, time_t now)
source_addr
.
in6
.
sin6_flowinfo
=
0
;
source_addr
.
in6
.
sin6_flowinfo
=
0
;
#endif
#endif
/* We can be configured to only accept queries from at-most-one-hop-away addresses. */
if
(
option_bool
(
OPT_LOCAL_SERVICE
))
{
struct
addrlist
*
addr
;
#ifdef HAVE_IPV6
if
(
listen
->
family
==
AF_INET6
)
{
for
(
addr
=
daemon
->
interface_addrs
;
addr
;
addr
=
addr
->
next
)
if
((
addr
->
flags
&
ADDRLIST_IPV6
)
&&
is_same_net6
(
&
addr
->
addr
.
addr
.
addr6
,
&
source_addr
.
in6
.
sin6_addr
,
addr
->
prefixlen
))
break
;
}
else
#endif
{
struct
in_addr
netmask
;
for
(
addr
=
daemon
->
interface_addrs
;
addr
;
addr
=
addr
->
next
)
{
netmask
.
s_addr
=
0xffffffff
<<
(
32
-
addr
->
prefixlen
);
if
(
!
(
addr
->
flags
&
ADDRLIST_IPV6
)
&&
is_same_net
(
addr
->
addr
.
addr
.
addr4
,
source_addr
.
in
.
sin_addr
,
netmask
))
break
;
}
}
if
(
!
addr
)
{
my_syslog
(
LOG_WARNING
,
_
(
"Ignoring query from non-local network"
));
return
;
}
}
if
(
check_dst
)
if
(
check_dst
)
{
{
struct
ifreq
ifr
;
struct
ifreq
ifr
;
...
@@ -1544,6 +1575,37 @@ unsigned char *tcp_request(int confd, time_t now,
...
@@ -1544,6 +1575,37 @@ unsigned char *tcp_request(int confd, time_t now,
if
(
getpeername
(
confd
,
(
struct
sockaddr
*
)
&
peer_addr
,
&
peer_len
)
==
-
1
)
if
(
getpeername
(
confd
,
(
struct
sockaddr
*
)
&
peer_addr
,
&
peer_len
)
==
-
1
)
return
packet
;
return
packet
;
/* We can be configured to only accept queries from at-most-one-hop-away addresses. */
if
(
option_bool
(
OPT_LOCAL_SERVICE
))
{
struct
addrlist
*
addr
;
#ifdef HAVE_IPV6
if
(
peer_addr
.
sa
.
sa_family
==
AF_INET6
)
{
for
(
addr
=
daemon
->
interface_addrs
;
addr
;
addr
=
addr
->
next
)
if
((
addr
->
flags
&
ADDRLIST_IPV6
)
&&
is_same_net6
(
&
addr
->
addr
.
addr
.
addr6
,
&
peer_addr
.
in6
.
sin6_addr
,
addr
->
prefixlen
))
break
;
}
else
#endif
{
struct
in_addr
netmask
;
for
(
addr
=
daemon
->
interface_addrs
;
addr
;
addr
=
addr
->
next
)
{
netmask
.
s_addr
=
0xffffffff
<<
(
32
-
addr
->
prefixlen
);
if
(
!
(
addr
->
flags
&
ADDRLIST_IPV6
)
&&
is_same_net
(
addr
->
addr
.
addr
.
addr4
,
peer_addr
.
in
.
sin_addr
,
netmask
))
break
;
}
}
if
(
!
addr
)
{
my_syslog
(
LOG_WARNING
,
_
(
"Ignoring query from non-local network"
));
return
packet
;
}
}
while
(
1
)
while
(
1
)
{
{
...
...
src/network.c
View file @
c8a80487
...
@@ -268,7 +268,40 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
...
@@ -268,7 +268,40 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
if
(
!
label
)
if
(
!
label
)
label
=
ifr
.
ifr_name
;
label
=
ifr
.
ifr_name
;
/* maintain a list of all addresses on all interfaces for --local-service option */
if
(
option_bool
(
OPT_LOCAL_SERVICE
))
{
struct
addrlist
*
al
;
if
(
param
->
spare
)
{
al
=
param
->
spare
;
param
->
spare
=
al
->
next
;
}
else
al
=
whine_malloc
(
sizeof
(
struct
addrlist
));
if
(
al
)
{
al
->
next
=
daemon
->
interface_addrs
;
daemon
->
interface_addrs
=
al
;
al
->
prefixlen
=
prefixlen
;
if
(
addr
->
sa
.
sa_family
==
AF_INET
)
{
al
->
addr
.
addr
.
addr4
=
addr
->
in
.
sin_addr
;
al
->
flags
=
0
;
}
#ifdef HAVE_IPV6
else
{
al
->
addr
.
addr
.
addr6
=
addr
->
in6
.
sin6_addr
;
al
->
flags
=
ADDRLIST_IPV6
;
}
#endif
}
}
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
if
(
addr
->
sa
.
sa_family
!=
AF_INET6
||
!
IN6_IS_ADDR_LINKLOCAL
(
&
addr
->
in6
.
sin6_addr
))
if
(
addr
->
sa
.
sa_family
!=
AF_INET6
||
!
IN6_IS_ADDR_LINKLOCAL
(
&
addr
->
in6
.
sin6_addr
))
...
@@ -565,6 +598,15 @@ int enumerate_interfaces(int reset)
...
@@ -565,6 +598,15 @@ int enumerate_interfaces(int reset)
intname
->
addr
=
NULL
;
intname
->
addr
=
NULL
;
}
}
/* Remove list of addresses of local interfaces */
for
(
addr
=
daemon
->
interface_addrs
;
addr
;
addr
=
tmp
)
{
tmp
=
addr
->
next
;
addr
->
next
=
spare
;
spare
=
addr
;
}
daemon
->
interface_addrs
=
NULL
;
#ifdef HAVE_AUTH
#ifdef HAVE_AUTH
/* remove addresses stored against auth_zone subnets, but not
/* remove addresses stored against auth_zone subnets, but not
ones configured as address literals */
ones configured as address literals */
...
...
src/option.c
View file @
c8a80487
...
@@ -144,6 +144,7 @@ struct myoption {
...
@@ -144,6 +144,7 @@ struct myoption {
#define LOPT_REV_SERV 332
#define LOPT_REV_SERV 332
#define LOPT_SERVERS_FILE 333
#define LOPT_SERVERS_FILE 333
#define LOPT_DNSSEC_CHECK 334
#define LOPT_DNSSEC_CHECK 334
#define LOPT_LOCAL_SERVICE 335
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
static
const
struct
option
opts
[]
=
static
const
struct
option
opts
[]
=
...
@@ -175,6 +176,7 @@ static const struct myoption opts[] =
...
@@ -175,6 +176,7 @@ static const struct myoption opts[] =
{
"domain-suffix"
,
1
,
0
,
's'
},
{
"domain-suffix"
,
1
,
0
,
's'
},
{
"interface"
,
1
,
0
,
'i'
},
{
"interface"
,
1
,
0
,
'i'
},
{
"listen-address"
,
1
,
0
,
'a'
},
{
"listen-address"
,
1
,
0
,
'a'
},
{
"local-service"
,
0
,
0
,
LOPT_LOCAL_SERVICE
},
{
"bogus-priv"
,
0
,
0
,
'b'
},
{
"bogus-priv"
,
0
,
0
,
'b'
},
{
"bogus-nxdomain"
,
1
,
0
,
'B'
},
{
"bogus-nxdomain"
,
1
,
0
,
'B'
},
{
"selfmx"
,
0
,
0
,
'e'
},
{
"selfmx"
,
0
,
0
,
'e'
},
...
@@ -448,6 +450,7 @@ static struct {
...
@@ -448,6 +450,7 @@ static struct {
{
LOPT_QUIET_DHCP
,
OPT_QUIET_DHCP
,
NULL
,
gettext_noop
(
"Do not log routine DHCP."
),
NULL
},
{
LOPT_QUIET_DHCP
,
OPT_QUIET_DHCP
,
NULL
,
gettext_noop
(
"Do not log routine DHCP."
),
NULL
},
{
LOPT_QUIET_DHCP6
,
OPT_QUIET_DHCP6
,
NULL
,
gettext_noop
(
"Do not log routine DHCPv6."
),
NULL
},
{
LOPT_QUIET_DHCP6
,
OPT_QUIET_DHCP6
,
NULL
,
gettext_noop
(
"Do not log routine DHCPv6."
),
NULL
},
{
LOPT_QUIET_RA
,
OPT_QUIET_RA
,
NULL
,
gettext_noop
(
"Do not log RA."
),
NULL
},
{
LOPT_QUIET_RA
,
OPT_QUIET_RA
,
NULL
,
gettext_noop
(
"Do not log RA."
),
NULL
},
{
LOPT_LOCAL_SERVICE
,
OPT_LOCAL_SERVICE
,
NULL
,
gettext_noop
(
"Accept queries only from directly-connected networks"
),
NULL
},
{
0
,
0
,
NULL
,
NULL
,
NULL
}
{
0
,
0
,
NULL
,
NULL
,
NULL
}
};
};
...
@@ -4457,6 +4460,11 @@ void read_opts(int argc, char **argv, char *compile_opts)
...
@@ -4457,6 +4460,11 @@ void read_opts(int argc, char **argv, char *compile_opts)
else
if
(
option_bool
(
OPT_DHCP_FQDN
))
else
if
(
option_bool
(
OPT_DHCP_FQDN
))
die
(
_
(
"there must be a default domain when --dhcp-fqdn is set"
),
NULL
,
EC_BADCONF
);
die
(
_
(
"there must be a default domain when --dhcp-fqdn is set"
),
NULL
,
EC_BADCONF
);
/* If there's access-control config, then ignore --local-service, it's intended
as a system default to keep otherwise unconfigured installations safe. */
if
(
daemon
->
if_names
||
daemon
->
if_except
||
daemon
->
if_addrs
||
daemon
->
authserver
)
reset_option_bool
(
OPT_LOCAL_SERVICE
);
if
(
testmode
)
if
(
testmode
)
{
{
fprintf
(
stderr
,
"dnsmasq: %s.
\n
"
,
_
(
"syntax check OK"
));
fprintf
(
stderr
,
"dnsmasq: %s.
\n
"
,
_
(
"syntax check OK"
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment