Configure SELinux policies for web applications and databases with custom rules and security hardening

Advanced 45 min Apr 11, 2026 229 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Learn how to implement mandatory access controls with SELinux for web servers and databases. Configure custom security contexts, create application-specific policies, and harden your infrastructure with advanced SELinux rules.

Prerequisites

  • Root or sudo access
  • Basic understanding of Linux permissions
  • Web server and database knowledge
  • Command line experience

What this solves

SELinux (Security-Enhanced Linux) provides mandatory access control that confines applications and system processes to minimal privileges, preventing unauthorized access even if an application is compromised. This tutorial covers installing SELinux on Debian-based systems, configuring security contexts for web applications and databases, creating custom policies, and implementing advanced security hardening rules.

Step-by-step installation

Install SELinux on Debian-based systems

SELinux comes pre-installed on RHEL-based distributions but requires manual installation on Debian-based systems.

sudo apt update
sudo apt install -y selinux-policy-default selinux-utils policycoreutils
sudo apt install -y setools-console selinux-policy-dev
sudo dnf update -y
sudo dnf install -y policycoreutils-python-utils setools-console
sudo dnf install -y selinux-policy-devel

Configure GRUB to enable SELinux

Add SELinux parameters to the kernel boot options to enable SELinux on system startup.

GRUB_CMDLINE_LINUX="selinux=1 security=selinux"

Update GRUB configuration and reboot:

sudo update-grub
sudo reboot

Set SELinux to permissive mode initially

Start with permissive mode to log policy violations without blocking operations during initial setup.

sudo setenforce 0
echo "SELINUX=permissive" | sudo tee /etc/selinux/config

Verify SELinux status:

sestatus
getenforce

Install and configure web server with SELinux contexts

Install Apache and configure proper SELinux contexts for web content.

sudo apt install -y apache2
sudo systemctl enable --now apache2
sudo dnf install -y httpd
sudo systemctl enable --now httpd

Configure SELinux contexts for web directories

Set proper security contexts for web content directories and files.

# Set context for web content directory
sudo semanage fcontext -a -t httpd_exec_t "/var/www/html(/.*)?"  
sudo semanage fcontext -a -t httpd_config_t "/etc/apache2(/.*)?"  
sudo restorecon -Rv /var/www/html
sudo restorecon -Rv /etc/apache2

Create a custom web application directory with proper contexts:

sudo mkdir -p /opt/webapps/myapp
sudo semanage fcontext -a -t httpd_exec_t "/opt/webapps/myapp(/.*)?"  
sudo restorecon -Rv /opt/webapps/myapp
sudo chown -R www-data:www-data /opt/webapps/myapp
sudo chmod -R 755 /opt/webapps/myapp

Configure SELinux boolean settings for web services

Enable necessary boolean settings for web server functionality.

# Allow Apache to connect to network
sudo setsebool -P httpd_can_network_connect on

Allow Apache to connect to databases

sudo setsebool -P httpd_can_network_connect_db on

Allow Apache to send emails

sudo setsebool -P httpd_can_sendmail on

Allow Apache to execute CGI scripts

sudo setsebool -P httpd_enable_cgi on

View current boolean settings:

getsebool -a | grep httpd

Install and configure database with SELinux

Install PostgreSQL and configure SELinux contexts for database operations.

sudo apt install -y postgresql postgresql-contrib
sudo systemctl enable --now postgresql
sudo dnf install -y postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql

Configure SELinux contexts for database directories

Set proper security contexts for PostgreSQL data directories and configuration files.

# Set contexts for PostgreSQL directories
sudo semanage fcontext -a -t postgresql_db_t "/var/lib/postgresql(/.*)?"  
sudo semanage fcontext -a -t postgresql_etc_t "/etc/postgresql(/.*)?"  
sudo restorecon -Rv /var/lib/postgresql
sudo restorecon -Rv /etc/postgresql

Configure custom database directory with proper contexts:

sudo mkdir -p /opt/database/backups
sudo semanage fcontext -a -t postgresql_db_t "/opt/database(/.*)?"  
sudo restorecon -Rv /opt/database
sudo chown -R postgres:postgres /opt/database
sudo chmod -R 700 /opt/database

Create custom SELinux policy for application

Generate a custom policy module for your specific application requirements.

# Create policy directory
sudo mkdir -p /etc/selinux/local
cd /etc/selinux/local

Create a custom policy file for web application database connections:

policy_module(myapp, 1.0)

require {
    type httpd_t;
    type postgresql_t;
    type postgresql_port_t;
    class tcp_socket name_connect;
    class file { read write create unlink };
}

Allow web server to connect to PostgreSQL

allow httpd_t postgresql_port_t:tcp_socket name_connect; allow httpd_t postgresql_t:tcp_socket { read write };

Allow web server to access custom log files

allow httpd_t admin_home_t:file { read write create unlink };

Compile and install custom policy

Compile the custom policy module and load it into the SELinux system.

# Compile policy module
sudo checkmodule -M -m -o myapp.mod myapp.te
sudo semodule_package -o myapp.pp -m myapp.mod

Install policy module

sudo semodule -i myapp.pp

Verify installation

sudo semodule -l | grep myapp

Configure SELinux port labels

Define custom port labels for applications running on non-standard ports.

# Add custom port for web application
sudo semanage port -a -t http_port_t -p tcp 8080

Add custom port for database connection

sudo semanage port -a -t postgresql_port_t -p tcp 5433

View current port assignments

sudo semanage port -l | grep http sudo semanage port -l | grep postgresql

Create SELinux user mappings

Configure SELinux user mappings for better access control.

# Create SELinux user for web applications
sudo semanage user -a -R "webadm_r system_r" webadm_u

Map system user to SELinux user

sudo semanage login -a -s webadm_u webapp

View user mappings

sudo semanage login -l

Configure audit logging for SELinux

Enable detailed audit logging to monitor SELinux policy violations and access attempts.

sudo apt install -y auditd
sudo systemctl enable --now auditd
sudo dnf install -y audit
sudo systemctl enable --now auditd

Configure audit rules for SELinux:

# SELinux audit rules
-w /etc/selinux/ -p wa -k selinux-config
-w /usr/sbin/semanage -p x -k selinux-manage
-w /usr/sbin/setsebool -p x -k selinux-booleans
sudo systemctl restart auditd

Switch to enforcing mode

After testing in permissive mode, switch to enforcing mode for full security.

Warning: Only switch to enforcing mode after thoroughly testing your applications in permissive mode. Monitor audit logs for any denied operations.
# Check for any policy violations in permissive mode
sudo ausearch -m avc -ts recent

Switch to enforcing mode

sudo setenforce 1 echo "SELINUX=enforcing" | sudo tee /etc/selinux/config

Advanced SELinux troubleshooting

Analyze SELinux denials

Use audit2why and audit2allow to understand and resolve policy violations.

# Analyze recent denials
sudo ausearch -m avc -ts recent | audit2why

Generate policy rules for denials

sudo ausearch -m avc -ts recent | audit2allow -M myapp_fix sudo semodule -i myapp_fix.pp

Monitor SELinux violations in real-time

Set up real-time monitoring of SELinux policy violations.

# Monitor audit log in real-time
sudo tail -f /var/log/audit/audit.log | grep AVC

Use sealert for user-friendly messages

sudo sealert -a /var/log/audit/audit.log

Verify your setup

# Check SELinux status
sestatus

Verify contexts are correctly applied

ls -Z /var/www/html ls -Z /var/lib/postgresql

Check loaded policy modules

sudo semodule -l | grep myapp

Verify boolean settings

getsebool -a | grep httpd

Test web server functionality

sudo systemctl status apache2 curl -I http://localhost

Test database connectivity

sudo -u postgres psql -c "SELECT version();"

Check for recent denials

sudo ausearch -m avc -ts today | wc -l

Common issues

SymptomCauseFix
Web server can't access filesIncorrect file contextssudo restorecon -Rv /var/www/html
Database connection deniedMissing boolean settingsudo setsebool -P httpd_can_network_connect_db on
Custom port access deniedPort not labeled correctlysudo semanage port -a -t http_port_t -p tcp PORT
Policy compilation failsSyntax errors in .te fileCheck syntax with checkmodule -M -m myapp.te
Application logs show denialsMissing policy rulesUse audit2allow to generate rules
SELinux not enforcingGRUB configuration missingAdd selinux=1 security=selinux to GRUB_CMDLINE_LINUX

Next steps

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle infrastructure security hardening for businesses that depend on uptime. From initial setup to ongoing operations.