This document provides practical, adaptable steps for customizing SELinux policy to securely enable httpd
to establish outbound access to a non-standard network port, e.g., 7003/TCP.
Related Documents
/usr/sbin/httpd
) with Oracle WebLogic plugin DSO (mod_wl.so
)mod_wl
are configured to retrieve contents from backends on 7003/TCP.mod_wl
installer does not provide SELinux policy adjustments.mod_wl
) attempts to connect to backend servers on 7003/TCP.👉 For SELinux-specific terminology, see the centralized Glossary in the README.md for this folder.
dnf install policycoreutils-devel selinux-policy-devel
# Optional:
dnf install setools-console
Search for SELinux denials related to the httpd process:
ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR | grep httpd
In the output, look for denied { ... }
and tclass=...
entries.
Example denial output:
type=AVC msg=audit(1695093000.123:12345): avc: denied { name_connect } for pid=1234 comm="httpd" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket permissive=0
👉 For alternative audit log search methods (exact process matching, filtering by time, etc.), see Audit Log Search Cheat Sheet in the related document: SELinux Policy Troubleshooting.
— Moderate Security: Allow All unreserved_ports
from httpd —
⚠️ Caution:
When filtering audit logs for use withaudit2allow
, be aware that using the-m
option (e.g.,-m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR
) may accidentally exclude relevant SELinux messages.
For best results, omit the-m
option when pipingausearch
output toaudit2allow
; the tool will ignore unrelated messages and process all necessary SELinux denials.
ausearch -c httpd | audit2allow -R
Create a working directory (use any name you like):
mkdir -p myhttpd_mod_wl-auto
cd myhttpd_mod_wl-auto
ausearch -c httpd --raw | audit2allow -M myhttpd_mod_wl
ls -l
You should see myhttpd_mod_wl.te
(policy source) and myhttpd_mod_wl.pp
(compiled module) created.
semodule -v -X 300 -i myhttpd_mod_wl.pp
Verify installation:
semodule -lfull | grep myhttpd_mod_wl
ls -l /var/lib/selinux/targeted/active/modules/*/myhttpd_mod_wl
Check the actual permission rule:
sesearch --allow -s httpd_t -t unreserved_port_t -c tcp_socket -p name_connect
— More Secure and Controllable —
If the outbound port is well-known and commonly used, you must use the predefined type name. If the port is not defined on your OS, you will need to define a new type, or you may wish to assign your own type name for clarity or future maintenance.
semanage port -l | grep -w '700[0-9]' | grep tcp
Example output:
afs3_callback_port_t tcp 7001
afs_pt_port_t tcp 7002
gatekeeper_port_t tcp 1721, 7000
Check for Multiple Ports or Ranges (See also Tips: Expand Port Ranges)
echo $(semanage port -l | awk '$1=="afs3_callback_port_t" && $2=="tcp" {$1=$2=""; print $0}')
⚠️ Never delete a port assignment without confirming it is not actively used by another domain.
2-1. Safety Check Before Deleting Port Assignment
If you need to assign a custom SELinux port type to a port already associated with another type, you must first delete the existing assignment.
Follow these steps before deleting:
2-1-1. Find the SELinux type mapped to the port (e.g., 7003/TCP):
bash
semanage port -l | grep -w '7003' | grep tcp
# Note the SELinux type in the first column of the output.
2-1-2. Check which SELinux domains are allowed to use this type:
Replace <SELinux_port_type>
with the type found above (e.g., afs3_callback_port_t
):
bash
sesearch --allow -t <SELinux_port_type> -c tcp_socket -p name_connect
sesearch --allow -t <SELinux_port_type> -c tcp_socket -p name_bind
2-1-3. Check if any process is actively using the port:
bash
netstat -lntp | grep ':7003'
# Find the PID, then check its SELinux context:
ps -Z -p <pid>
# Ensure the running process is not using a domain that needs this port type.
2-2. If you have confirmed the port is not in use:
semanage port -d -p tcp 7003
Otherwise, reuse the predefined port type.
semanage port -l | awk '$1=="afs3_callback_port_t" && $2=="tcp" {$1=$2=""; print $0}' | \
tr ',' '\n' | while read p; do
if [[ "$p" == *-* ]]; then seq ${p%-*} ${p#*-}; else echo $p; fi
done
Prepare a module directory (use any name you like):
mkdir -p myhttpd_mod_wl
cd myhttpd_mod_wl
Create the policy module source .te
file: myhttpd_wls_type.te
module myhttpd_wls_type 1.0;
require {
attribute port_type;
}
type httpd_wls_port_t;
typeattribute httpd_wls_port_t port_type;
⚠️ Use Underscores in Names
Avoid using dashes (-
), dots (.
), or other punctuation for word separation in SELinux type names. These characters can prevent SELinux policies from working properly or may cause errors during policy installation.
Build and Install the Module
checkmodule -M -m -o myhttpd_wls_type.mod myhttpd_wls_type.te
semodule_package -o myhttpd_wls_type.pp -m myhttpd_wls_type.mod
semodule -v -X 300 -i myhttpd_wls_type.pp
Verify installation:
semodule -lfull | grep myhttpd_wls_type
Create the policy module source .te
file: myhttpd_mod_wl.te
module myhttpd_mod_wl 1.0;
require {
type httpd_t;
type httpd_wls_port_t;
class tcp_socket name_connect;
}
allow httpd_t httpd_wls_port_t:tcp_socket name_connect;
Alternatively, if you decide to reuse a predefined port type (e.g., 7001: afs3_callback_port_t
):
module myhttpd_mod_wl 1.0;
require {
type httpd_t;
type afs3_callback_port_t;
class tcp_socket name_connect;
}
allow httpd_t afs3_callback_port_t:tcp_socket name_connect;
You can blend the above if you want to allow more than one port type.
Build and Install the Module
checkmodule -M -m -o myhttpd_mod_wl.mod myhttpd_mod_wl.te
semodule_package -o myhttpd_mod_wl.pp -m myhttpd_mod_wl.mod
semodule -v -X 300 -i myhttpd_mod_wl.pp
Verify installation:
semodule -lfull | grep myhttpd_mod_wl
ls -l /var/lib/selinux/targeted/active/modules/*/myhttpd_mod_wl
Check the actual permission rule:
sesearch --allow -s httpd_t -t httpd_wls_port_t -c tcp_socket -p name_connect
— Required Only When Manual Build —
semanage port -a -t httpd_wls_port_t -p tcp 7003
Verify assignment:
echo $(semanage port -l | awk '$1=="httpd_wls_port_t" && $2=="tcp" {$1=$2=""; print $0}')
Start the httpd service and check logs:
systemctl start httpd.service
Return to See What Is Going On to check for AVC denials.
Stop the httpd service, then follow the steps below.
semodule -v -X 300 -r myhttpd_wls_type
semodule -lfull | grep myhttpd_wls_type
semodule -v -X 300 -r myhttpd_mod_wl
semodule -lfull | grep myhttpd_mod_wl
👉 For more complex uninstall scenarios—such as multi-module dependencies or thorough label cleanup—refer to
Uninstalling Policy Modules (When Needed)
in the related document: Create SELinux Policy Module for Your Own Service.