LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (http://www.linuxquestions.org/questions/linux-security-4/)
-   -   Working chrooted BIND 9 broken by SELinux (http://www.linuxquestions.org/questions/linux-security-4/working-chrooted-bind-9-broken-by-selinux-4175444581/)

rbees 01-07-2013 06:45 PM

Working chrooted BIND 9 broken by SELinux
 
Ladies & Gents,

I am having issues with bind9 after installing selinux on an external firewall/dhcp/dns host I am setting up. I have figured out what I think needs fixing. When I setup bind I put in in jail, not knowing that selinux makes that not really nessessary. So now selinux is not, due to policy, allowing bind access to the files in the jail. I have found the command to change the perimisions but I don't know what to change them to.

The jail is set /var/bind9/chroot/......

the permissions are set as

Code:

system_u:object_r:var_t:s0 named.conf
I am assuming that var_t needs to be change to something else but I have no idea what, named_conf_t maybe? If so then my command would be

Code:

# chcon -v --type=named_conf_t /var/bind9/chroot/etc/named.conf
The system is Debian Stable (Squeeze) (no gui) fully patched untill selinux broke my network. Machines connecting through the external host have internet access but the external host its self does not which is kind of strange.

Another issue is that a lot of the selinux doc's on google that I can understand are for RH based systems and file locations are not the same. For instance I see alot of reference to /var/log/audit/audit.log but I have no such. Also alot of the doc's are somewhat dated, almost 10 years now.

I found these and figured they might be all the permissions I need to fix it.

Code:

cat /etc/selinux/default/modules/active/file_contexts | grep /etc/bind > /home/rbees/chroot.bind[

/etc/bind(/.*)? system_u:object_r:named_zone_t:s0                                                       
/etc/bind/rndc\.key    --      system_u:object_r:dnssec_t:s0                                           
/etc/bind/named\.conf  --      system_u:object_r:named_conf_t:s0                                       
/etc/bind/named\.conf\.local    --      system_u:object_r:named_conf_t:s0                               
/etc/bind/named\.conf\.options  --      system_u:object_r:named_conf_t:s0
/var/cache/bind(/.*)?  system_u:object_r:named_cache_t:s0

So assuming they are I worked out these commands.

Code:

chcon -v --type=named_zone_t /var/bind9/chroot/etc/bind(/.*)?
chcon -v --type=dnssec_t /var/bind9/chroot/etc/bind\.key
chcon -v --type=named_conf_t /var/bind9/chroot/etc/bind\.conf
chcon -v --type=named_conf_t /var/bind9/chroot/etc/bind\.conf\.local
chcon -v --type=named_conf_t /var/bind9/chroot/etc/bind\.conf\.options
chcon -v --type=named_cache_t /var/bind9/chroot/var/cache/bind(/.*)?

Are they right? I would really like some kind of confirmation be for I run them and hose the system.

Thanks

unSpawn 01-07-2013 08:18 PM

First thing to do would be to look at AVC messages and run them through 'audit2allow'. /var/log/audit/audit.log only exists if you also installed the audit service, so check /var/log/messages or equivalent.

rbees 01-07-2013 08:44 PM

Thanks,

But don't have /var/log/audit/audit.log and with the internet access broke on the machine I can't install it. Guess I will have to figure out how to set selinux back to permissive instead of enforcing.

unSpawn 01-08-2013 08:25 AM

Quote:

Originally Posted by rbees (Post 4865064)
But don't have /var/log/audit/audit.log

...and that's why I pointed you to /var/log/messages or equivalent.


Quote:

Originally Posted by rbees (Post 4865064)
and with the internet access broke on the machine I can't install it.

Sneakernet?

rbees 01-09-2013 10:23 AM

Thanks unSpawn

Your guidance always helps. I have the steps to correct the permissions now but there are some log entries that I am not sure I should allow.

For instance I have a lot of entries like
Code:

[  33.154295] type=1400 audit 1357745774.794:5): avc:  denied  { read write } for pid=740 comm="vgscan" name="lvm" dev=dm-1 ino=32421 scontext=system_u:system_r:lvm_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir
I get that it is vgscan trying to access something on dm-1 but I have no idea what or why and if I should allow it with a custom rule or create an ignore rule.

audit2why says
Code:

Was caused by:  Missing type enforcement (TE) allow rule.
I also have single entries for hostname, logsave, and ifconfig.

Thanks

rbees 01-09-2013 10:25 AM

Oh yea, I did get internet access by setting selinux to permissive and rebooting.

unSpawn 01-09-2013 11:47 AM

Quote:

Originally Posted by rbees (Post 4866254)
I have the steps to correct the permissions now

Awesome.


Quote:

Originally Posted by rbees (Post 4866254)
but there are some log entries that I am not sure I should allow.

Bummer.


Quote:

Originally Posted by rbees (Post 4866254)
For instance I have a lot of entries like
Code:

[  33.154295] type=1400 audit 1357745774.794:5): avc:  denied  { read write } for pid=740 comm="vgscan" name="lvm" dev=dm-1 ino=32421 scontext=system_u:system_r:lvm_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir
I get that it is vgscan trying to access something on dm-1 but I have no idea what or why and if I should allow it with a custom rule or create an ignore rule.

Yes, you're right it tries to access /dev/dm-1 and for me /contexts/files/file_contexts says any "/dev/dm-[0-9]+" block devices should have a "fixed_disk_device_t" context.


Quote:

Originally Posted by rbees (Post 4866254)
audit2why says
Code:

Was caused by:  Missing type enforcement (TE) allow rule.

Generally speaking I would try to run 'restorecon -n -vv /dev/dm-1' to see if it would apply a "fixed_disk_device_t" context, or anything other than the generic "file_t", but with this error you have gotten (I get
Code:

#============= lvm_t ==============
allow lvm_t file_t:dir { read write };

instead) I wonder if it's something partially missing from the Debian SELinux policy, after all it does know about "lvm_t". Adding an allow policy would mean, barring any other rules, that anything from the "lvm_t" domain will have read and write access to anything in the "file_t" domain. To find out what's labeled "file_t" you could
Code:

grep ':file_t' -r /etc/selinux/targeted/contexts/
and
Code:

find / -xdev -context "*:*:file_t"

Quote:

Originally Posted by rbees (Post 4866254)
I also have single entries for hostname, logsave, and ifconfig.

Just post some entries, OK?

rbees 01-09-2013 01:26 PM

Please slow down a little.

How did you test to get
Quote:

#============= lvm_t ==============
allow lvm_t file_t:dir { read write };
Do you know of an easy cheat sheet of selinux commands? I did run
Code:

restorecon -n -vv /dev/dm-1
but there was no output.

I also have
Quote:

"/dev/dm-[0-9]+" block devices should have a "fixed_disk_device_t" contex
but it is in /etc/selinux/default/contexts/files/context_files

I tried
Code:

:/home/rbees/selinux# grep ':file_t' -r /etc/selinux/default/contexts/files/ > my-file_t
but my-file_t comes up empty. Not sure I have the command right though. Searching /etc/selinux/default/contexts/files/context_files in Midnight Commander for file_t finds nothing.

And I get
Code:

# find / -xdev -context "*:*:file_t" > my-file_t2
find: unknown predicate `-context'

Code:

type=1400 audit(1357745773.384:3): avc:  denied  { read write } for  pid=660 comm="hostname" name="tty1" dev=devtmpfs ino=1398 scontext=system_u:system_r:hostname_t:s0 tcontext=system_u:object_r:tty_device_t:s0 class=chr_file

Was caused by: Missing type enforcement (TE) allow rule.

Code:

type=1400 audit(1357745773.848:4): avc:  denied  { read write } for  pid=700 comm="logsave" name="tty1" dev=devtmpfs ino=1398 scontext=system_u:system_r:fsadm_t:s0 tcontext=system_u:object_r:tty_device_t:s0 tclass=chr_file

Was caused by: Missing type enforcement (TE) allow rule.

Code:

type=1400 audit(1357745778.980:21): avc:  denied  { read write } for  pid=1002 comm="ifconfig" name="tty1" dev=devtmpfs ino=1398 scontext=system_u:system_r:ifconfig_t:s0 tcontext=system_u:object_r:tty_device_t:s0 tclass=chr_file

Was caused by: Missing type enforcement (TE) allow rule.


unSpawn 01-09-2013 02:22 PM

Quote:

Originally Posted by rbees (Post 4866387)
How did you test to get
Code:

#============= lvm_t ==============
 allow lvm_t file_t:dir { read write };


*BTW note the inner ones are vBB [CODE][/CODE] tags, not [QUOTE][/QUOTE] tags.
I got it by running your "vgscan" through 'audit2allow':
Code:

echo 'type=1400 audit 1357745774.794:5): avc:  denied  { read write } for pid=740 comm="vgscan" name="lvm" dev=dm-1 ino=32421 scontext=system_u:system_r:lvm_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir'|audit2allow
but then again my SELinux policy may be different because I run CentOS.


Quote:

Originally Posted by rbees (Post 4866387)
Do you know of an easy cheat sheet of selinux commands?

Sorry, no. I usually point people to the Fedora Wiki SELinux documentation.


Quote:

Originally Posted by rbees (Post 4866387)
I did run
Code:

restorecon -n -vv /dev/dm-1
but there was no output.

Odd, can't explain that.


Quote:

Originally Posted by rbees (Post 4866387)
I also have but it is in /etc/selinux/default/contexts/files/context_files

That's where it should be.


Quote:

Originally Posted by rbees (Post 4866387)
I tried
Code:

:/home/rbees/selinux# grep ':file_t' -r /etc/selinux/default/contexts/files/ > my-file_t
but my-file_t comes up empty. Not sure I have the command right though.

Command line looks OK. Not sure what to say about this except noticing your policy apparently is called "default" (/etc/selinux/default/) whereas RHEL / Fedora / CentOS' default policy is "targeted" located at /etc/selinux/targeted/. What choice of policies does Debian offer?


Quote:

Originally Posted by rbees (Post 4866387)
And I get
Code:

find: unknown predicate `-context'

If 'man find' desn't say anything about a "-context" switch that would indicate 'find' isn't SELinux-enabled. Is this a machine that had SELinux bolted on or did you install SELinux at OS installation?


Quote:

Originally Posted by rbees (Post 4866387)
Code:

Was caused by: Missing type enforcement (TE) allow rule.

Looks like the policy isn't complete but I'll wait for you to tell us what policies Debian offers.

rbees 01-09-2013 02:59 PM

OK I get
Code:

echo 'type=1400 audit 1357745774.794:5): avc:  denied  { read write } for pid=740 comm="vgscan" name="lvm" dev=dm-1 ino=32421 scontext=system_u:system_r:lvm_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir'|audit2allow


#============= lvm_t ==============
allow lvm_t file_t:dir { read write };

Quote:

What choice of policies does Debian offer?
selinux-basic selinux-policy-default selinux-policy-dev selinux-policy-mls selinux-policy-src

I have basic and default installed

Quote:

Is this a machine that had SELinux bolted on or did you install SELinux at OS installation?
Installed from the deb repos

unSpawn 01-10-2013 07:56 AM

Quote:

Originally Posted by rbees (Post 4866434)
selinux-basic selinux-policy-default selinux-policy-dev selinux-policy-mls selinux-policy-src
I have basic and default installed

OK.


Quote:

Originally Posted by rbees (Post 4866434)
Installed from the deb repos

Your choice of answer should be either "at OS installation" or "added afterwards". It's not that you can't reset contexts later on by relabeling the file system or install SELinux-capable applications later on but given the level a MAC interlocks at with the system you really want to ensure SELinux gets configured and loaded as soon as possible. And that means OS installation time.


Quote:

Originally Posted by rbees
Was caused by: Missing type enforcement (TE) allow rule.

As for your earlier missing rules you can fix that by running the AVC warnings through audit2allow. If you post the output we'll discuss it here. More importantly before you do you should check the Debian bug tracker for related issues. If they don't know about missing TE rules then you should open a ticket and inform them.

rbees 01-10-2013 04:10 PM

From my bootlog (which is not enabled by default)

Code:

Thu Jan 10 08:44:16 2013: e2fsck 1.41.12 (17-May-2010)
Thu Jan 10 08:44:16 2013: /dev/mapper/external-usr: clean, 55876/549440 files, 304865/2196480 blocks
Thu Jan 10 08:44:16 2013: e2fsck 1.41.12 (17-May-2010)
Thu Jan 10 08:44:16 2013: /dev/mapper/external-var: clean, 3620/183264 files, 127527/732160 blocks
Thu Jan 10 08:44:16 2013: done.
Thu Jan 10 08:44:16 2013: Mounting local filesystems...done.
Thu Jan 10 08:44:16 2013: Activating swapfile swap...done.
Thu Jan 10 08:44:16 2013: Cleaning up temporary files....
Thu Jan 10 08:44:17 2013: Setting kernel variables ...done.
Thu Jan 10 08:44:17 2013: Setting up resolvconf...done.
Thu Jan 10 08:44:18 2013: Setting up networking....
Thu Jan 10 08:44:18 2013: Configuring network interfaces...done.
Thu Jan 10 08:44:19 2013: Starting portmap daemon....
Thu Jan 10 08:44:19 2013: Starting NFS common utilities: statd.
Thu Jan 10 08:44:19 2013: Cleaning up temporary files....
Thu Jan 10 08:44:19 2013: Starting Arno's Iptables Firewall...
Thu Jan 10 08:44:25 2013: Setting console screen modes.
Thu Jan 10 08:44:25 2013: ^[]R^[[9;30]^[[14;30]Skipping font and keymap setup (handled by console-setup).
Thu Jan 10 08:44:25 2013: Setting up console font and keymap...done.
Thu Jan 10 08:44:26 2013: Setting sensors limits.
Thu Jan 10 08:44:26 2013: Checking SELinux contexts: selinux-basics
Thu Jan 10 08:44:26 2013:.
Thu Jan 10 08:44:26 2013: INIT: Entering runlevel: 2

I don't know if that answers the question of "at installation or added afterwards". I set the machine up with all the software I plan to use and had it all working before I installed and setup selinux so selinux could not create problems getting the software configured. Was that not the correct way to do it as I thought. Seams I remember being told that by someone or reading it in a post at LQ.

There is also this in syslog after a fresh boot
Code:

.
.
Jan 10 08:44:27 external kernel: [    0.446616] pci 0000:00:10.4: PCI INT C disabled
Jan 10 08:44:27 external kernel: [    0.446682] pci 0000:00:11.0: Bypassing VIA 8237 APIC De-Assert Message
Jan 10 08:44:27 external kernel: [    0.446764] pci 0000:01:00.0: Boot video device
Jan 10 08:44:27 external kernel: [    0.446920] Unpacking initramfs...
Jan 10 08:44:27 external kernel: [    1.446889] Freeing initrd memory: 10023k freed
Jan 10 08:44:27 external kernel: [    1.465243] audit: initializing netlink socket (disabled)
Jan 10 08:44:27 external kernel: [    1.465336] type=2000 audit(1357825415.464:1): initialized
Jan 10 08:44:27 external kernel: [    1.477291] HugeTLB registered 4 MB page size, pre-allocated 0 pages
Jan 10 08:44:27 external kernel: [    1.482150] VFS: Disk quotas dquot_6.5.2
Jan 10 08:44:27 external kernel: [    1.482404] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
Jan 10 08:44:27 external kernel: [    1.482673] msgmni has been set to 875


Jan 10 08:44:27 external kernel: [    1.482999] SELinux:  Registering netfilter hooks


Jan 10 08:44:27 external kernel: [    1.483541] alg: No test for stdrng (krng)
Jan 10 08:44:27 external kernel: [    1.483815] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
Jan 10 08:44:27 external kernel: [    1.483891] io scheduler noop registered
Jan 10 08:44:27 external kernel: [    1.483950] io scheduler anticipatory registered
Jan 10 08:44:27 external kernel: [    1.484042] io scheduler deadline registered
Jan 10 08:44:27 external kernel: [    1.484213] io scheduler cfq registered (default)
Jan 10 08:44:27 external kernel: [    1.484759] isapnp: Scanning for PnP cards...
Jan 10 08:44:27 external kernel: [    1.839070] isapnp: No Plug & Play device found
Jan 10 08:44:27 external kernel: [    1.843131] Linux agpgart interface v0.103
.
.

To me it seams that selinux is loading very early in the boot process.

I have looked at debians bug tracker but I can't find any bugs that list "missing TE rules". But then I am not sure I am using it right.

Not sure how it may help but I ran the all the avc entries in syslog from yesterday through audit2allow and here is the mysys.te output.

Code:

module mysys 1.0;

require {
        type nagios_system_plugin_t;
        type home_root_t;
        type node_t;
        type boot_t;
        type sshd_var_run_t;
        type tty_device_t;
        type sysfs_t;
        type var_log_t;
        type tmp_t;
        type dhcpc_var_run_t;
        type ndc_t;
        type dhcpc_t;
        type nagios_checkdisk_plugin_t;
        type hostname_t;
        type rndc_port_t;
        type exim_t;
        type devpts_t;
        type ifconfig_t;
        type var_lock_t;
        type lvm_t;
        type file_t;
        type syslogd_t;
        type fsadm_t;
        type ping_t;
        type named_t;
        type var_lib_t;
        type nagios_t;
        type udev_t;
        type crond_tmp_t;
        type ntp_drift_t;
        type sshd_t;
        type crond_t;
        type nagios_services_plugin_t;
        type var_t;
        type tmpfs_t;
        class file { rename setattr read lock create write getattr unlink open append };
        class chr_file { write getattr read open };
        class tcp_socket { name_connect node_bind };
        class fifo_file read;
        class sock_file { create setattr };
        class dir { write getattr search read remove_name add_name };
}

#============= dhcpc_t ==============
allow dhcpc_t ntp_drift_t:dir search;

#============= exim_t ==============
allow exim_t crond_tmp_t:file { read write getattr };
allow exim_t dhcpc_var_run_t:file { read getattr open };

#============= fsadm_t ==============
allow fsadm_t tty_device_t:chr_file { read write };

#============= hostname_t ==============
allow hostname_t crond_t:fifo_file read;
allow hostname_t dhcpc_var_run_t:file { read getattr open };
allow hostname_t tty_device_t:chr_file { read write };

#============= ifconfig_t ==============
allow ifconfig_t tty_device_t:chr_file { read write };

#============= lvm_t ==============
allow lvm_t file_t:dir { read write add_name remove_name };
allow lvm_t file_t:file { getattr read lock create open append };

#============= nagios_checkdisk_plugin_t ==============
allow nagios_checkdisk_plugin_t boot_t:dir getattr;
allow nagios_checkdisk_plugin_t devpts_t:dir getattr;
allow nagios_checkdisk_plugin_t home_root_t:dir getattr;
allow nagios_checkdisk_plugin_t sysfs_t:dir getattr;
allow nagios_checkdisk_plugin_t tmp_t:dir getattr;
allow nagios_checkdisk_plugin_t tmpfs_t:dir getattr;
allow nagios_checkdisk_plugin_t var_lib_t:file { read write };

#============= nagios_services_plugin_t ==============
allow nagios_services_plugin_t var_lib_t:file { read write };

#============= nagios_system_plugin_t ==============
allow nagios_system_plugin_t var_lib_t:file { read write };

#============= nagios_t ==============
allow nagios_t dhcpc_var_run_t:file { read getattr open };
allow nagios_t var_lib_t:dir { write remove_name add_name };
allow nagios_t var_lib_t:file { rename write getattr read create unlink open };
allow nagios_t var_log_t:file { read getattr open append };
allow nagios_t var_t:dir { write remove_name add_name };
allow nagios_t var_t:file { rename setattr read create write getattr unlink open };

#============= named_t ==============
allow named_t var_t:chr_file { read getattr open };

#============= ndc_t ==============
allow ndc_t tty_device_t:chr_file { read write };
allow ndc_t var_t:file { read getattr open };

#============= ping_t ==============
allow ping_t var_lib_t:file { read write };

#============= sshd_t ==============
allow sshd_t dhcpc_var_run_t:file { read getattr open };

#============= syslogd_t ==============
allow syslogd_t dhcpc_var_run_t:file { read getattr open };
allow syslogd_t var_t:dir { write add_name };
allow syslogd_t var_t:sock_file { create setattr };

#============= udev_t ==============
allow udev_t node_t:tcp_socket node_bind;
allow udev_t rndc_port_t:tcp_socket name_connect;
allow udev_t sshd_var_run_t:file getattr;
allow udev_t var_lock_t:dir { write add_name };
allow udev_t var_lock_t:file create;
allow udev_t var_t:file { read getattr open };

I discovered after the system had been running awhile that there were a lot more entries in syslog that I originally thought.

unSpawn 01-10-2013 07:37 PM

After a quick check I don't see any unwanted action (like demanding execstack or shadow_t access) so I'd load them as local policies. Best separate them so you can disable modules at will should someone be visiting you (everybody expects Murphy's first Law but Nobody expects the Spanish Inquisition ;-p):
Code:

#!/bin/bash
CONTEXTLIST="dhcpc_t exim_t fsadm_t hostname_t ifconfig_t lvm_t named_t ndc_t ping_t sshd_t syslogd_t udev_t nagios_checkdisk_plugin_t nagios_services_plugin_t nagios_t"
for CONTEXT in CONTEXTLIST; do PPNAME=${CONTEXT//_t/}; PPNAME=${PPNAME//_/}
_MYTMPDIR=`mktemp -p /tmp -d semodule.XXXXXXXXXX` && { cd "${_MYTMPDIR}"
grep "scontext=.*:.*:${CONTEXT}:" /var/log/messages|audit2allow \
-M "$(/bin/date +'%Y%m%d')${PPNAME}" && \
semodule -i "$(/bin/date +'%Y%m%d')${PPNAME}".pp; }; rm -rf "${_MYTMPDIR}"
done; exit 0


rbees 01-10-2013 08:54 PM

Quote:

everybody expects Murphy's first Law but Nobody expects the Spanish Inquisition ;-p
Ain't that the truth.

So after looking at the script it looks like I run it and it will pull the info it needs out of /var/log/messages.

Should I run it from any place in particular? In the other modules I made with audit2allow I did it in a folder I have in my home folder specific to the config of the host as root. I see from my reading that where the file is created and the context that it is created in can change the selinux permissions.

Thanks again for your guidance.

unSpawn 01-11-2013 03:36 AM

You're welcome. It should be run as root and if you want to run it inside /root you only have to change the directory name 'mktemp' uses. This will create directories like /root/selinux_dhcpc.aabbccdd, leave their contents intact and only echo the 'semodule' load command:
Code:

#!/bin/bash
CONTEXTLIST="dhcpc_t exim_t fsadm_t hostname_t ifconfig_t lvm_t named_t ndc_t ping_t sshd_t syslogd_t udev_t nagios_checkdisk_plugin_t nagios_services_plugin_t nagios_t"
for CONTEXT in CONTEXTLIST; do PPNAME=${CONTEXT//_t/}; PPNAME=${PPNAME//_/}
_MYTMPDIR=`mktemp -p /root -d selinux_${PPNAME}.XXXXXXXXXX` && { cd "${_MYTMPDIR}"
grep "scontext=.*:.*:${CONTEXT}:" /var/log/messages|audit2allow -M "$(/bin/date +'%Y%m%d')${PPNAME}" && \
echo "semodule -i "${PWD}/$(/bin/date +'%Y%m%d')${PPNAME}".pp"; }; cd /root
done; exit 0



All times are GMT -5. The time now is 10:57 PM.