Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
dnsmasq and privileged ports
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Networking & Security
View previous topic :: View next topic  
Author Message
toralf
Developer
Developer


Joined: 01 Feb 2004
Posts: 3647
Location: Hamburg

PostPosted: Fri Jan 26, 2018 10:16 pm    Post subject: dnsmasq and privileged ports Reply with quote

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
Code:
--min-port=1024
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
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 13493

PostPosted: Sat Jan 27, 2018 12:36 am    Post subject: Reply with quote

What is the output of cat -n /proc/$(pgrep dnsmasq)/status?
Back to top
View user's profile Send private message
toralf
Developer
Developer


Joined: 01 Feb 2004
Posts: 3647
Location: Hamburg

PostPosted: Sat Jan 27, 2018 8:39 am    Post subject: Reply with quote

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
View user's profile Send private message
mike155
l33t
l33t


Joined: 17 Sep 2010
Posts: 989
Location: Frankfurt, Germany

PostPosted: Sat Jan 27, 2018 1:10 pm    Post subject: Reply with quote

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
View user's profile Send private message
toralf
Developer
Developer


Joined: 01 Feb 2004
Posts: 3647
Location: Hamburg

PostPosted: Sat Jan 27, 2018 1:58 pm    Post subject: Reply with quote

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
View user's profile Send private message
mike155
l33t
l33t


Joined: 17 Sep 2010
Posts: 989
Location: Frankfurt, Germany

PostPosted: Sat Jan 27, 2018 2:36 pm    Post subject: Reply with quote

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
View user's profile Send private message
toralf
Developer
Developer


Joined: 01 Feb 2004
Posts: 3647
Location: Hamburg

PostPosted: Sat Jan 27, 2018 2:52 pm    Post subject: Reply with quote

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
View user's profile Send private message
mike155
l33t
l33t


Joined: 17 Sep 2010
Posts: 989
Location: Frankfurt, Germany

PostPosted: Sat Jan 27, 2018 3:56 pm    Post subject: Reply with quote

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
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 13493

PostPosted: Sat Jan 27, 2018 11:33 pm    Post subject: Reply with quote

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
View user's profile Send private message
toralf
Developer
Developer


Joined: 01 Feb 2004
Posts: 3647
Location: Hamburg

PostPosted: Sun Jan 28, 2018 9:11 am    Post subject: Reply with quote

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
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 13493

PostPosted: Sun Jan 28, 2018 5:18 pm    Post subject: Reply with quote

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
View user's profile Send private message
mike155
l33t
l33t


Joined: 17 Sep 2010
Posts: 989
Location: Frankfurt, Germany

PostPosted: Tue Jan 30, 2018 12:13 am    Post subject: Reply with quote

Simon Kelley (one of the developers of dnsmasq) just checked in a patch that sets the default value of min-port to 1024.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Networking & Security All times are GMT
Page 1 of 1

 
Jump to:  
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