SELinux blocks Full Host Image access to external Smart Proxy on port 8000

Problem:

We are running Foreman without Katello and use an external Smart Proxy for provisioning Ubuntu hosts with Full Host Image.

The installation media is exposed through the Smart Proxy over HTTP on TCP/8000, for example:

http://<smart-proxy>:8000/httpboot/installation_media/ubuntu/24.04-x86_64

When generating a Full Host Image, Foreman downloads vmlinuz and initrd using the configured Installation Media URL:

http://<smart-proxy>:8000/httpboot/installation_media/ubuntu/24.04-x86_64/casper/vmlinuz

This fails because SELinux blocks the Foreman Rails process from connecting to TCP/8000:

Failed to open TCP connection to <smart-proxy>:8000
(Permission denied - connect(2))

The SELinux AVC shows:

avc: denied { name_connect }
scontext=system_u:system_r:foreman_rails_t:s0
tcontext=system_u:object_r:soundd_port_t:s0
tclass=tcp_socket
dest=8000

TCP/8000 is assigned to soundd_port_t by the default SELinux policy:

# semanage port -l | grep -E '(^http_port_t|8000)'

http_port_t    tcp    80, 81, 443, 488, 8008, 8009, 8443, 9000
soundd_port_t  tcp    8000, 9433, 16001

A manual request to the same URL works, including when running curl as the foreman Unix user. The problem occurs specifically when Foreman Rails, running in the foreman_rails_t SELinux domain, accesses TCP/8000.

Since TCP/8000 is also the documented HTTP port for Smart Proxy provisioning/HTTPBoot, it seems that Full Host Image introduces a case where the Foreman server itself needs to connect to this port.

Expected outcome:

Foreman should be able to generate a Full Host Image using boot files provided by an external Smart Proxy on the documented HTTP provisioning port without disabling SELinux.

Is foreman_rails_t expected to be allowed to connect to soundd_port_t for this use case?

Would the recommended workaround be a local SELinux policy such as:

allow foreman_rails_t soundd_port_t:tcp_socket name_connect;

or is there another supported configuration for Full Host Image with an external Smart Proxy?

We would prefer not to relabel TCP/8000 or put SELinux into permissive mode.

Foreman and Proxy versions:

Foreman: 3.19
Smart Proxy: 3.19.1

Foreman and Proxy plugin versions:

Foreman Bootdisk / Full Host Image
No Katello

Distribution and version:

<Foreman server OS and version>
<Smart Proxy OS and version>
SELinux: Enforcing

Other relevant data:

Smart Proxy HTTPBoot is available on TCP/8000 and HTTPS/API on TCP/9090.

The Smart Proxy successfully serves the requested boot file:

GET /httpboot/installation_media/ubuntu/24.04-x86_64/casper/vmlinuz
HTTP/1.1 200 OK

The same URL can be downloaded manually from the Foreman server, so DNS, routing and firewall connectivity are working.

The issue appears to be specifically the SELinux transition:

foreman_rails_t
    -> TCP name_connect
    -> soundd_port_t (TCP/8000)
    -> denied

Hello, SELinux policy for smart-proxy is incomplete and not working. If you install Foreman from packages, it is never loaded automatically unless you run foreman-proxy-selinux-enable.

Feel free to send a patch to foreman-selinux git repository if you want this, however, depending on your smart proxy modules and plugins, you will likely encounter many other denials.

If you want increased security, I recommend to consider container deployment via foremanctl. In this setup, the host machine SELinux policy is enforced and no foreman-selinux is needed.

Thanks for the explanation and the suggestions.

We have worked around the issue with our own local SELinux policy. Since our Smart Proxy setup is quite minimal and uses only a few modules/plugins, this seems manageable for us at the moment.

Also, thanks for pointing out that the Smart Proxy SELinux policy is not loaded automatically when installing from packages. That is definitely useful to know.

Thanks also for the tip about the container deployment with foremanctl. I will evaluate that option for our setup.

Geat, in that case we would love to see patches:

Cheers! :smiley: