Bug 1370425

Summary: missing security contexts for opendkim keys
Product: Red Hat Enterprise Linux 7 Reporter: Peter Ajamian <peter>
Component: selinux-policyAssignee: Miroslav Grepl <mgrepl>
Status: CLOSED NOTABUG QA Contact: Milos Malik <mmalik>
Severity: low Docs Contact:
Priority: unspecified    
Version: 7.0CC: lvrabec, mgrepl, mmalik, peter, plautrba, pvrabec, ssekidde, steve
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-08-29 09:09:49 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Peter Ajamian 2016-08-26 09:55:17 UTC
Description of problem:
With selinux set to enforcing opendkim won't start if private keys are placed in the default location of /etc/opendkim/keys.

Version-Release number of selected component (if applicable):
opendkim-2.10.3-7.el7.x86_64

How reproducible:
Always

Steps to Reproduce:
1.  yum install opendkim

2.  set up opendkim, create one or more keys and place in /etc/opendkim/keys and reference in /etc/opendkim.conf

3.  systemctl start opendkim.service

Actual results:
Job for opendkim.service failed because the control process exited with error code. See "systemctl status opendkim.service" and "journalctl -xe" for details.

Expected results:
No output

Additional info:
/var/log/messages shows the following:
Aug 26 09:15:11 endor systemd: Starting DomainKeys Identified Mail (DKIM) Milter...
Aug 26 09:15:11 endor opendkim: /etc/opendkim/keys/endor.key.pem: open(): Permission denied
Aug 26 09:15:11 endor opendkim: opendkim: /etc/opendkim.conf: /etc/opendkim/keys/endor.key.pem: open(): Permission denied
Aug 26 09:15:11 endor systemd: opendkim.service: control process exited, code=exited status=78
Aug 26 09:15:11 endor systemd: Failed to start DomainKeys Identified Mail (DKIM) Milter.
Aug 26 09:15:11 endor systemd: Unit opendkim.service entered failed state.
Aug 26 09:15:11 endor systemd: opendkim.service failed.

Doing the following fixes the issue:
semanage fcontext -a -t dkim_milter_private_key_t "/etc/opendkim/keys(/.*)?"
restorecon -Rv /etc/opendkim/keys

Comment 1 Steve Jenkins 2016-08-26 15:32:33 UTC
I believe this is addressed in Fedora since F24, but not sure about its status in RHEL7 (or other branches). Assigning to RHEL7 / selinux-policy, as that's where the proper fix should come from.

Comment 3 Milos Malik 2016-08-29 06:38:49 UTC
Could you collect and attach SELinux denials which appear during your scenario?

# ausearch -m avc -m user_avc -m selinux_err -m user_selinux_err -i -ts today

Comment 4 Peter Ajamian 2016-08-29 06:48:54 UTC
I've fixed the problem with the above mentioned fix, but I'll show you the denials from my logs before:

type=AVC msg=audit(1472202911.656:14966): avc:  denied  { read } for  pid=18888 comm="opendkim" name="endor.key.pem" dev="sda" ino=13600 scontext=system_u:system_r:dkim_milter_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=AVC msg=audit(1472203049.727:14970): avc:  denied  { read } for  pid=18992 comm="opendkim" name="endor.key.pem" dev="sda" ino=13600 scontext=system_u:system_r:dkim_milter_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=AVC msg=audit(1472203049.727:14970): avc:  denied  { open } for  pid=18992 comm="opendkim" path="/etc/opendkim/keys/endor.key.pem" dev="sda" ino=13600 scontext=system_u:system_r:dkim_milter_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=AVC msg=audit(1472203049.727:14971): avc:  denied  { getattr } for  pid=18992 comm="opendkim" path="/etc/opendkim/keys/endor.key.pem" dev="sda" ino=13600 scontext=system_u:system_r:dkim_milter_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file

Comment 5 Milos Malik 2016-08-29 06:50:12 UTC
It works fine when:

# opendkim-genkey --verbose 
opendkim-genkey: generating private key
opendkim-genkey: private key written to default.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to default.txt
# mv default.* /etc/opendkim/keys/
# restorecon -Rv /etc/opendkim/
restorecon reset /etc/opendkim/keys/default.private context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:etc_t:s0
restorecon reset /etc/opendkim/keys/default.txt context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:etc_t:s0
#

Comment 6 Peter Ajamian 2016-08-29 06:59:23 UTC
Did you configure opendkim to use that key?  If it's not configured as such then it won't barf because it doesn't try to read the key.

Comment 7 Milos Malik 2016-08-29 07:06:24 UTC
# grep -v -e '^#' -e '^$' /etc/opendkim.conf 
PidFile	/var/run/opendkim/opendkim.pid
Mode	v
Syslog	yes
SyslogSuccess	yes
LogWhy	yes
UserID	opendkim:opendkim
Socket	inet:8891@localhost
Umask	002
SendReports	yes
SoftwareHeader	yes
Canonicalization	relaxed/relaxed
Selector	default
MinimumKeyBits	1024
KeyFile	/etc/opendkim/keys/default.private
KeyTable	/etc/opendkim/KeyTable
SigningTable	refile:/etc/opendkim/SigningTable
OversignHeaders	From
#

Based on the AVCs from comment#4, the key files were mislabeled (admin_home_t, most likely copied from /root), therefore SELinux prevented the open call.

Comment 8 Peter Ajamian 2016-08-29 07:36:29 UTC
> Based on the AVCs from comment#4, the key files were mislabeled
> (admin_home_t, most likely copied from /root), therefore SELinux prevented
> the open call.

I see what you're saying, yes you are correct, I moved them from /root and failed to relabel them.  That said it does still seem more appropriate to set the context to dkim_milter_private_key_t than etc_t, though certainly not required at this point.  Also (and I may be mistaken here) won't setting the context on the directory itself cause files placed in that directory to inherit that context, thereby preventing this from being an issue?

Comment 9 Milos Malik 2016-08-29 08:05:33 UTC
There is a difference between cp and mv. The cp command creates another copy of an existing object and it can set the context:

# ls -al /etc/opendkim/keys/
total 0
drwxr-x---. 2 opendkim opendkim  6 Aug 29 09:53 .
drwxr-xr-x. 3 root     opendkim 70 Jan 29  2016 ..
# opendkim-genkey --verbose
opendkim-genkey: generating private key
opendkim-genkey: private key written to default.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to default.txt
# ls -Z default.*
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 default.private
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 default.txt
# cp default.* /etc/opendkim/keys/
# ls -Z /etc/opendkim/keys/
-rw-------. root root unconfined_u:object_r:etc_t:s0   default.private
-rw-------. root root unconfined_u:object_r:etc_t:s0   default.txt
# 

The mv command moves an existing object together with its context:

# ls -al /etc/opendkim/keys/
total 0
drwxr-x---. 2 opendkim opendkim  6 Aug 29 09:56 .
drwxr-xr-x. 3 root     opendkim 70 Jan 29  2016 ..
# opendkim-genkey --verbose
opendkim-genkey: generating private key
opendkim-genkey: private key written to default.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to default.txt
# ls -Z default.*
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 default.private
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 default.txt
# mv default.* /etc/opendkim/keys/
# ls -Z /etc/opendkim/keys/
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 default.private
-rw-------. root root unconfined_u:object_r:admin_home_t:s0 default.txt
# 

Alternatives are: cp -Z, mv -Z

Comment 10 Lukas Vrabec 2016-08-29 09:09:49 UTC
Milos is right, you can use -Z parameter to set default SELinux context of destination file. 

Closing this as NOTABUG.