View previous topic :: View next topic |
Author |
Message |
toralf Developer


Joined: 01 Feb 2004 Posts: 3841 Location: Hamburg
|
Posted: Fri Jan 26, 2018 10:16 pm Post subject: dnsmasq and privileged ports |
|
|
Today I realized at my server that a Code: | strace -p `pgrep dnsmasq` 2>&1 | grep -B 5 EACCE | spews a lot of findings like Code: | bind(29, {sa_family=AF_INET, sin_port=htons(95), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EACCES (Permission denied) | The author of dnsmasq gave me the hint to use Now I do wonder why the dnsmasq at the server can't use privileged ports. FWIW an Code: | setcap 'CAP_NET_BIND_SERVICE=+eip' /usr/sbin/dnsmasq | doesn't helped. |
|
Back to top |
|
 |
Hu Moderator

Joined: 06 Mar 2007 Posts: 16513
|
Posted: Sat Jan 27, 2018 12:36 am Post subject: |
|
|
What is the output of cat -n /proc/$(pgrep dnsmasq)/status? |
|
Back to top |
|
 |
toralf Developer


Joined: 01 Feb 2004 Posts: 3841 Location: Hamburg
|
Posted: Sat Jan 27, 2018 8:39 am Post subject: |
|
|
Hu wrote: | What is the output of cat -n /proc/$(pgrep dnsmasq)/status? |
Code: | mr-fox ~ # cat -n /proc/$(pgrep dnsmasq)/status
1 Name: dnsmasq
2 Umask: 0022
3 State: S (sleeping)
4 Tgid: 19647
5 Ngid: 0
6 Pid: 19647
7 PPid: 1
8 TracerPid: 0
9 Uid: 104 104 104 104
10 Gid: 242 242 242 242
11 FDSize: 128
12 Groups:
13 NStgid: 19647
14 NSpid: 19647
15 NSpgid: 19646
16 NSsid: 19646
17 VmPeak: 26832 kB
18 VmSize: 26832 kB
19 VmLck: 0 kB
20 VmPin: 0 kB
21 VmHWM: 5048 kB
22 VmRSS: 5048 kB
23 RssAnon: 2668 kB
24 RssFile: 2380 kB
25 RssShmem: 0 kB
26 VmData: 2828 kB
27 VmStk: 132 kB
28 VmExe: 328 kB
29 VmLib: 3068 kB
30 VmPTE: 68 kB
31 VmPMD: 12 kB
32 VmSwap: 0 kB
33 Threads: 1
34 SigQ: 0/255389
35 SigPnd: 0000000000000000
36 ShdPnd: 0000000000000000
37 SigBlk: 0000000000000000
38 SigIgn: 0000000000001000
39 SigCgt: 0000000000016a01
40 CapInh: 0000000000000000
41 CapPrm: 0000000000003000
42 CapEff: 0000000000003000
43 CapBnd: 0000003fffffffff
44 CapAmb: 0000000000000000
45 NoNewPrivs: 0
46 Seccomp: 0
47 Cpus_allowed: fff
48 Cpus_allowed_list: 0-11
49 voluntary_ctxt_switches: 4101625
50 nonvoluntary_ctxt_switches: 56342
mr- |
|
|
Back to top |
|
 |
mike155 Advocate

Joined: 17 Sep 2010 Posts: 2578 Location: Frankfurt, Germany
|
Posted: Sat Jan 27, 2018 1:10 pm Post subject: |
|
|
1) Please look at the lines following the bind request. Is the bind request part of an outgoing request to an DNS server? Below in an example of such a request:
Code: | bind(11, {sa_family=AF_INET, sin_port=htons(20189), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
sendto(11, "\277l\1\0\0\1\0\0\0\0\0\0\3www\6google\2de\0\0\34\0\1", 31, 0, \
{sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("W.X.Y.Z")}, 16) = 31
...
recvfrom(11, "\277l\201\200\0\1\0\1\0\0\0\0\3www\6google\2de\0\0\34\0\1\300"..., 5131, 0, \
{sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("W.X.Y.Z")}, [16]) = 59
|
Or is it something else?
2) What is the output of "cat /proc/sys/net/ipv4/ip_local_port_range"? |
|
Back to top |
|
 |
toralf Developer


Joined: 01 Feb 2004 Posts: 3841 Location: Hamburg
|
Posted: Sat Jan 27, 2018 1:58 pm Post subject: |
|
|
mike155 wrote: | 1) Please look at the lines following the bind request. Is the bind request part of an outgoing request to an DNS server? Below in an example of such a request:
Code: | bind(11, {sa_family=AF_INET, sin_port=htons(20189), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
sendto(11, "\277l\1\0\0\1\0\0\0\0\0\0\3www\6google\2de\0\0\34\0\1", 31, 0, \
{sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("W.X.Y.Z")}, 16) = 31
...
recvfrom(11, "\277l\201\200\0\1\0\1\0\0\0\0\3www\6google\2de\0\0\34\0\1\300"..., 5131, 0, \
{sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("W.X.Y.Z")}, [16]) = 59
|
Or is it something else?
|
Code: | bind(18, {sa_family=AF_INET6, sin6_port=htons(39368), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 0
sendto(18, "Bq\1\0\0\1\0\0\0\0\0\1\23ARcherYBraNDApPareL"..., 52, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 52
recvfrom(18, "Bq\201\200\0\1\0\0\0\6\0\1\23ARcherYBraNDApPareL"..., 5131, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 773
recvfrom(26, "\273\307\201\200\0\1\0\0\0\1\0\1\23ARcHErybraNdaPpAreL"..., 5131, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 114
recvmsg(4, {msg_name={sa_family=AF_INET, sin_port=htons(60281), sin_addr=inet_addr("127.0.0.1")}, msg_namelen=28->16, msg_iov=[{iov_base="\0\250\1\0\0\1\0\0\0\0\0\0\7andRoId\nGOoglEaPiS\3"..., iov_len=4096}], msg_iovlen=1, msg_control=[{cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=IP_PKTINFO, cmsg_data={ipi_ifindex=if_nametoindex("lo"), ipi_spec_dst=inet_addr("127.0.0.1"), ipi_addr=inet_addr("127.0.0.1")}}], msg_controllen=32, msg_flags=0}, 0) = 40
bind(18, {sa_family=AF_INET6, sin6_port=htons(64690), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 0
sendto(18, ";@\1\0\0\1\0\0\0\0\0\1\7andRoId\nGOoglEaPiS\3"..., 51, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 51
recvmsg(4, {msg_name={sa_family=AF_INET, sin_port=htons(60281), sin_addr=inet_addr("127.0.0.1")}, msg_namelen=28->16, msg_iov=[{iov_base="yI\1\0\0\1\0\0\0\0\0\0\7aNDRoID\ngOOgLeAPiS\3"..., iov_len=4096}], msg_iovlen=1, msg_control=[{cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=IP_PKTINFO, cmsg_data={ipi_ifindex=if_nametoindex("lo"), ipi_spec_dst=inet_addr("127.0.0.1"), ipi_addr=inet_addr("127.0.0.1")}}], msg_controllen=32, msg_flags=0}, 0) = 40
bind(24, {sa_family=AF_INET6, sin6_port=htons(56974), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 0
sendto(24, "\213\377\1\0\0\1\0\0\0\0\0\1\7aNDRoID\ngOOgLeAPiS\3"..., 51, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = 51
recvfrom(18, ";@\201\200\0\1\0\21\0\0\0\1\7andRoId\nGOoglEaPiS\3"..., 5131, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 341
recvfrom(24, "\213\377\201\200\0\1\0\2\0\0\0\1\7aNDRoID\ngOOgLeAPiS\3"..., 5131, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "2a01:4f8:0:a0a1::add:1010", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, [28]) = 113 |
mike155 wrote: | 2) What is the output of "cat /proc/sys/net/ipv4/ip_local_port_range"? |
Code: | t44 ~ # cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999
|
|
|
Back to top |
|
 |
mike155 Advocate

Joined: 17 Sep 2010 Posts: 2578 Location: Frankfurt, Germany
|
Posted: Sat Jan 27, 2018 2:36 pm Post subject: |
|
|
Toralf, I'm confused now. The strace output you showed in your first post was IPv4. The output you showed in your last post is IPv6.
1) outgoing DNS requests seem to use IPv6 and they are OK. They use source ports in the range 32768 - 60999. They don't generate errors and they seem to work.
2) ...which brings me back to your first post. I guess that the IPv4 request you showed is not part of an outgoing DNS request. So what can it be? Port 95 (supdup) is highly unusual. Is it really 95? Or is it 953? Please post the lines following such an IPv4 request. |
|
Back to top |
|
 |
toralf Developer


Joined: 01 Feb 2004 Posts: 3841 Location: Hamburg
|
Posted: Sat Jan 27, 2018 2:52 pm Post subject: |
|
|
I do have ipv4 and ipv6 at that server acticated. The dnsmasq is : Code: | tinderbox@mr-fox ~ $ grep -v -e '^$' -e '#' /etc/dnsmasq.conf
domain-needed
conf-file=/usr/share/dnsmasq/trust-anchors.conf
dnssec
dnssec-check-unsigned
no-resolv
server=213.133.98.98
server=213.133.99.99
server=213.133.100.100
server=2a01:4f8:0:a0a1::add:1010
server=2a01:4f8:0:a102::add:9999
server=2a01:4f8:0:a111::add:9898
cache-size=10000
| and Code: | tinderbox@mr-fox ~ $ cat /etc/conf.d/dnsmasq
# /etc/conf.d/dnsmasq: config file for /etc/init.d/dnsmasq
# See the dnsmasq(8) man page for possible options to put here.
DNSMASQ_OPTS="--user=dnsmasq --group=dnsmasq --min-port=1024"
#DNSMASQ_OPTS="--user=dnsmasq --group=dnsmasq"
| The strace is derived via Code: | strace -p `pgrep dnsmasq` 2>&1 | grep -e ^bind -e ^sendto -e ^rec | .
It is a fast Tor exit relay having >10,000 connecitons open and >100new per seconds or so.
The question is just how to let dnsmasq to use lower ports. |
|
Back to top |
|
 |
mike155 Advocate

Joined: 17 Sep 2010 Posts: 2578 Location: Frankfurt, Germany
|
Posted: Sat Jan 27, 2018 3:56 pm Post subject: |
|
|
Quote: | The question is just how to let dnsmasq to use lower ports. |
There are two ways to go on:
1) One way is, as you suggest, to allow dnsmasq to use source ports < 1024. I doubt it will help you.
2) The other way is to try to find out why dnsmasq wants to open a source port < 1024 at all.
EDIT: the next paragraph is wrong (sorry!) - please ignore it
# You wrote that your computer has more than 10.000 open connections. But your local port range is only 32768 - 60999.
# So maybe (!) dnsmasq (or your # kernel) decides that there are no more free source ports and then uses source ports < 1024.
# In that is true, something is going wrong and it wouldn't help # you to allow ports < 1024. Note: this is only a guess!
#
# 1) You could increase the range of local source ports to 1024 - 65536?
# See: https://www.cyberciti.biz/tips/linux-increase-outgoing-network-sockets-range.html.
# But make sure that this doesn't have negative effects on other services running on your computer like Tor.
#
# 2) Another solution could be to use a second IP address (if you have one) and configure dnsmasq to use the second
# IP address for outgoing DNS requests. This would give you a new set of epheremal ports.
I looked at /var/tmp/portage/net-dns/dnsmasq-2.78/work/dnsmasq-2.78/src/network.c, function: int random_sock(int family)
1) dnsmasq doesn't use values defined in proc/sys/net/ipv4/ip_local_port_range. For that reason, it doesn't make sense to change these values. A possible reason can be found here (see first answer).
2) dnsmasq uses its own port range. The default is 0 - 65535. The default range can be modified with options --min-port and --max-port.
3) EDIT: this topic is probably not true - I think I saw this bug this afternoon, but I can't reproduce it: There seems to be a bug in dnsmasq's option parser. It doesn't process the last parameter. For that reason, DNSMASQ_OPTS="--user=dnsmasq --group=dnsmasq --min-port=1024" doesn't change the port range. Solution: add another parameter after --min-port. You could use '--max-port=65000' - but this parameter will be ignored.
4) If dnsmasq wants to send an outgoing DNS request, it randomly selects a port number from the port range and tries to bind to a socket with this source port. If it gets an error, it will randomly select another port and retry. It will retry up to 100 times.
Code: | bind(29, {sa_family=AF_INET, sin_port=htons(95), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EACCES (Permission denied)
|
This algorithm and the default port range (0-65536) could explain the bind request with source port 95.
Conclusion (so far):
The default value for min-port is 0. It should be 1024. So everybody should add "--min-port=1024" to DNSMASQ_OPTS. I sent a bug report to the developers of dnsmasq. I don't know why this didn't work for Toralf - maybe he also suffered from topic 3) - I saw it, but I can't reproduce it. |
|
Back to top |
|
 |
Hu Moderator

Joined: 06 Mar 2007 Posts: 16513
|
Posted: Sat Jan 27, 2018 11:33 pm Post subject: |
|
|
toralf wrote: | Code: | 41 CapPrm: 0000000000003000
42 CapEff: 0000000000003000 |
| That at least makes sense. It has CAP_NET_ADMIN and CAP_NET_RAW, but privileged ports are provided via CAP_NET_BIND_SERVICE. So I think it is expected that requesting a low port fails in this case. Whether it should be requesting a low port, and whether it should be retaining a capability that allows it to request a low port, are both good questions that I cannot address.
If you want it to use low ports (why?), then you need it to retain CAP_NET_BIND_SERVICE. |
|
Back to top |
|
 |
toralf Developer


Joined: 01 Feb 2004 Posts: 3841 Location: Hamburg
|
Posted: Sun Jan 28, 2018 9:11 am Post subject: |
|
|
Hu wrote: | toralf wrote: | Code: | 41 CapPrm: 0000000000003000
42 CapEff: 0000000000003000 |
| That at least makes sense. It has CAP_NET_ADMIN and CAP_NET_RAW, but privileged ports are provided via CAP_NET_BIND_SERVICE. So I think it is expected that requesting a low port fails in this case. Whether it should be requesting a low port, and whether it should be retaining a capability that allows it to request a low port, are both good questions that I cannot address.
If you want it to use low ports (why?), then you need it to retain CAP_NET_BIND_SERVICE. | I run Code: | setcap 'CAP_NET_BIND_SERVICE=+eip' /usr/sbin/dnsmasq | changed back /etc/conf.d/dnsmasq to Code: | DNSMASQ_OPTS="--user=dnsmasq --group=dnsmasq" | restarted dnsmasq and verified the caps : Code: | mr-fox ~ # cat -n /proc/$(pgrep dnsmasq)/status | grep -i cap
40 CapInh: 0000000000000000
41 CapPrm: 0000000000003000
42 CapEff: 0000000000003000
43 CapBnd: 0000003fffffffff
44 CapAmb: 0000000000000000
| but Code: | strace -p `pgrep dnsmasq` 2>&1 | grep EACCE | still shows the EACCES error |
|
Back to top |
|
 |
Hu Moderator

Joined: 06 Mar 2007 Posts: 16513
|
Posted: Sun Jan 28, 2018 5:18 pm Post subject: |
|
|
CAP_NET_BIND_SERVICE is defined as 10 (here), so you should expect 1 << 10 = 400 to be enabled if that change worked. Looking at the source, it seems dnsmasq includes code to drop unwanted capabilities. Based on your output, that if test yielded false, so dnsmasq decided to drop CAP_NET_BIND_SERVICE. Code: | /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind
ports because of DAD, or we're doing it dynamically,
we need CAP_NET_BIND_SERVICE too. */
if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
data->effective = data->permitted = data->inheritable =
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) |
(1 << CAP_SETUID) | (1 << CAP_NET_BIND_SERVICE);
else
data->effective = data->permitted = data->inheritable =
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID); | Does it help if you explicitly enable option OPT_CLEVERBLIND? I think that you would pass --bind-dynamic to do this. |
|
Back to top |
|
 |
mike155 Advocate

Joined: 17 Sep 2010 Posts: 2578 Location: Frankfurt, Germany
|
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|