SELinux Tips
Updating SELinux Permissions for Nginx
ngx_modsecurity_module.so: failed to map segment from shared object: Permission Denied
After installing a module in Nginx, /var/log/nginx/error.log can show a Permission Denied error when trying to reload nginx. You might need to configure SELinux to allow **executing** the shared object file:
semanage fcontext -a -t httpd_exec_t '/etc/nginx/modules(/.*)?' restorecon -R -v /etc/nginx/modules
On RHEL with a Node.js app that wouldn't start, I saw this error:
Aug 8 16:19:20 ip-172-31-1-214 systemd[1]: Failed to start web-client Node.js service.
I ran 'yum provides seinfo' and 'yum provides sealert' showed what to install to get more logging on SELinux errors. After the installs, starting my node service again gave me these verbose errors:
Aug 8 16:19:20 ip-172-31-1-214 setroubleshoot[4026]: SELinux is preventing /usr/bin/node from using the execmem access on a process. For complete SELinux messages run: sealert -l 96c61aac-cab4-459c-bd43-c9b3636b9889 Aug 8 16:19:20 ip-172-31-1-214 setroubleshoot[4026]: SELinux is preventing /usr/bin/node from using the execmem access on a process.#012#012***** Plugin allow_execmem (53.1 confi dence) suggests *********************#012#012If you know why node needs to map a memory region that is both executable and writable and understand that this is a potential securi ty problem.#012Then you can allow the mapping by switching one of the following booleans: httpd_execmem#012Do#012follow the advice of the catchall_boolean plugin, otherwise contact your security administrator and report this issue#012#012***** Plugin catchall_boolean ( 42.6 confidence) suggests ******************#012#012If you want to allow httpd to execme m#012Then you must tell SELinux about this by enabling the 'httpd_execmem' boolean.#012#01 2Do#012setsebool -P httpd_execmem 1#012#012***** Plugin catchall (5.76 confidence) sugges ts **************************#012#012If you believe that node should be allowed execmem access on processes labeled httpd_t by default.#012Then you should report this as a bug.#0 12You can generate a local policy module to allow this access.#012Do#012allow this access
After running the command shown in the logs:
setsebool -P httpd_execmem 1
Then I was able to successfully restart the Node.js app
Getting "Permission Denied while connectng to upstream" error in the Nginx error log. Resolved by enabling network access from nginx.
setsebool -P http_can_network_connect 1
Create semanage policy file by processing audit.log grep
grep nginx /var/log/audit/audit.log | audit2allow -M nginx
- this creates an SELinux policy file called nginx.pp, and a textual version of that as nginx.te
- Run the following commands to enable the policy: semodule -i nginx.pp semodule --enable nginx
- Also, view the
nginx.tefile and run therestorecon -R -vlines shown there to enable the policy you just imported.
Installing audit2allow
On Centos, running `yum provides audit2allow` returns: policycoreutils-python-2.5-34.el7.x86_64 : SELinux policy core python utilities Repo : base Matched from: Filename : /usr/bin/audit2allow
$> systemctl status web-client3
Aug 15 13:23:01 ip-172-31-1-214.us-west-2.compute.internal systemd[1]: Failed to start web-client Node.js service.
$> grep 'avc: denied' /var/log/audit/audit.log
type=SYSCALL msg=audit(1629033781.299:4509): arch=c000003e syscall=49 success=no exit=-13 a0=12 a1=7ffca623f4b0 a2=1c a3=7ffca623f424 items=0 ppid=1 pid=21379 auid=4294967295 uid=65534 gid=65534 euid=65534 suid=65534 fsuid=65534 egid=65534 sgid=65534 fsgid=65534 tty=(none) ses=4294967295 comm="node" exe="/usr/bin/node" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=bind AUID="unset" UID="nobody" GID="nobody" EUID="nobody" SUID="nobody" FSUID="nobody" EGID="nobody" SGID="nobody" FSGID="nobody"
type=AVC msg=audit(1629033781.299:4510): avc: denied { name_bind } for pid=21379 comm="node" src=3101 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0
$> grep node /var/log/audit/audit.log | audit2allow -m node
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t self:process execmem;
#!!!! This avc can be allowed using the boolean 'nis_enabled'
allow httpd_t unreserved_port_t:tcp_socket name_bind;
$> grep node /var/log/audit/audit.log | audit2allow -M node
$> cat node.te
cat node.te
module node 1.0;
require {
type httpd_t;
type unreserved_port_t;
class process execmem;
class tcp_socket name_bind;
}
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t self:process execmem;
#!!!! This avc can be allowed using the boolean 'nis_enabled'
allow httpd_t unreserved_port_t:tcp_socket name_bind;
How to log server name when all upstream servers are local?
$upstream_addr
access_log /var/log/nginx/$host/$upstream_addr;