Weird SELinux problem with Dnsmasq and /etc/resolv.conf

Hi,

I just installed Rocky Linux 8 on a PC engines routerboard with three NICs. This board serves as my local router/gateway/DNS/proxy server. The complete Ansible configuration is here:

I have a weird problem with this machine. It’s running Dnsmasq to provide DHCP/DNS for my local machines. Now some of the machines work very well. Other can’t seem to get an IP address from Dnsmasq. In the logs (/var/log/dnsmasq.log) this looks like this:

May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPDISCOVER(enp2s0) 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPOFFER(enp2s0) 192.168.2.191 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPDISCOVER(enp2s0) 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPOFFER(enp2s0) 192.168.2.191 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPDISCOVER(enp2s0) 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPOFFER(enp2s0) 192.168.2.191 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPDISCOVER(enp2s0) 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPOFFER(enp2s0) 192.168.2.191 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPDISCOVER(enp2s0) 68:5a:cf:33:23:2e 
May 15 10:14:06 dnsmasq-dhcp[2031]: DHCPOFFER(enp2s0) 192.168.2.191 68:5a:cf:33:23:2e 
May 15 10:14:09 dnsmasq-dhcp[2031]: DHCPDISCOVER(enp2s0) 68:5a:cf:33:23:2e 
May 15 10:14:09 dnsmasq-dhcp[2031]: DHCPOFFER(enp2s0) 192.168.2.191 68:5a:cf:33:23:2e

I took a peek at SELinux alerts and found this:

# sealert -a /var/log/audit/audit.log 
100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------

SELinux is preventing /usr/sbin/dnsmasq from getattr access on the file /etc/resolv.conf.

*****  Plugin restorecon (99.5 confidence) suggests   ************************

If you want to fix the label. 
/etc/resolv.conf default label should be net_conf_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /etc/resolv.conf

Curiously enough, there seems to be nothing wrong with resolv.conf:

# ls -Z /etc/resolv.conf 
system_u:object_r:net_conf_t:s0 /etc/resolv.conf

Running restorecon on that file doesn’t change anything:

# restorecon -v /etc/resolv.conf 
[root@proxy:configure_dnsmasq] # ls -Z /etc/resolv.conf 
system_u:object_r:net_conf_t:s0 /etc/resolv.conf

Curiously enough, when I disable SELinux temporarily (setenforce 0) all machines can connect OK.

Any idea what’s going on here ?

Mhh, whats the output of ls -laZ /etc/ /etc/resolv.conf |head?

dnsmasq is running under system_u:object_r:dnsmasq_exec_t

$ matchpathcon /usr/sbin/dnsmasq
/usr/sbin/dnsmasq	system_u:object_r:dnsmasq_exec_t:s0
$

This type is only allowed to interact with the following:

$sesearch --allow -s dnsmasq_exec_t
allow dnsmasq_exec_t dnsmasq_exec_t:filesystem associate;
allow file_type cephfs_t:filesystem associate;
allow file_type fs_t:filesystem associate;
allow file_type hugetlbfs_t:filesystem associate;
allow file_type noxattrfs:filesystem associate;
allow file_type ramfs_t:filesystem associate;
allow file_type tmp_t:filesystem associate;
allow file_type tmpfs_t:filesystem associate;
$

/etc/resolv.conf has system_u:object_r:net_conf_t:

$ matchpathcon /etc/resolv.conf
/etc/resolv.conf	system_u:object_r:net_conf_t:s0
$

which isn’t in the set for dnsmasq, and thus isn’t allowed to interact with it:

$sesearch --allow -s dnsmasq_exec_t -t net_conf_t
$

What does audit2allow -a say?

Right, here goes. I performed a fresh installation of Rocky Linux 8 on a routerboard. I installed and configured Dnsmasq, and here’s what sealert says:

# sealert -a /var/log/audit/audit.log 
100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------

SELinux is preventing /usr/sbin/dnsmasq from getattr access on the file /etc/resolv.conf.

*****  Plugin restorecon (99.5 confidence) suggests   ************************

If you want to fix the label. 
/etc/resolv.conf default label should be net_conf_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /etc/resolv.conf

*****  Plugin catchall (1.49 confidence) suggests   **************************

If you believe that dnsmasq should be allowed getattr access on the resolv.conf file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'dnsmasq' --raw | audit2allow -M my-dnsmasq
# semodule -X 300 -i my-dnsmasq.pp

Additional Information:
Source Context                system_u:system_r:dnsmasq_t:s0
Target Context                unconfined_u:object_r:admin_home_t:s0
Target Objects                /etc/resolv.conf [ file ]
Source                        dnsmasq
Source Path                   /usr/sbin/dnsmasq
Port                          <Unknown>
Host                          <Unknown>
Source RPM Packages           dnsmasq-2.79-33.el8_10.x86_64
Target RPM Packages           
SELinux Policy RPM            selinux-policy-targeted-3.14.3-139.el8_10.1.noarch
Local Policy RPM              selinux-policy-targeted-3.14.3-139.el8_10.1.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     squidbox
Platform                      Linux squidbox 4.18.0-553.el8_10.x86_64 #1 SMP Fri
                              May 24 13:05:10 UTC 2024 x86_64 x86_64
Alert Count                   1
First Seen                    2025-05-23 07:00:51 CEST
Last Seen                     2025-05-23 07:00:51 CEST
Local ID                      95436d03-0844-42f2-8085-89f109ed328b

Here’s my Ansible role to install and configure Dnsmasq:

I tried to perform what the message suggested and did exactly this:

# ausearch -c 'dnsmasq' --raw | audit2allow -M my-dnsmasq
# semodule -X 300 -i my-dnsmasq.pp

This seemed to work. Now I wonder if there is any way I can add this to my playbook.

Any suggestions ?

There’s a config (and command line) setting where you can tell it not to use /etc/resolv.conf

In addition, there’s a potential confusion with ‘dnsmasq’, the “normal” one, and the one that’s buried in libvirt (if you use it).

I need Dnsmasq to use resolv.conf.

There is another [Skywalker].

Yes, you can run a standalone dnsmasq.service and yes, the libvirt can start dnsmasq for a “virtual network” in order to provide DHCP and DNS for it, but also the NetworkManager can start dnsmasq. The NM will also pass necessary config to that instance; not via resolv.conf. Furthermore, it is possible to customize the config of that instance to do more than just relay and cache DNS.