Secure Your Nginx on Linux: SELinux, Sysctl Tweaks, Module Stripping & Firewall

This guide walks through hardening an Nginx web server on Linux by configuring default files, testing and reloading, enabling SELinux, mounting least‑privilege partitions, applying sysctl security parameters, removing unnecessary modules, and deploying an iptables‑based firewall with detailed command examples.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Secure Your Nginx on Linux: SELinux, Sysctl Tweaks, Module Stripping & Firewall

Default Nginx Configuration and Ports

The main configuration file is /usr/local/nginx/conf/nginx.conf; default document root is /usr/local/nginx/html/, logs are stored in /usr/local/nginx/logs/. HTTP listens on TCP 80 and HTTPS on TCP 443.

Testing and Reloading

/usr/local/nginx/sbin/nginx -t

Outputs syntax OK messages. Reload configuration with: /usr/local/nginx/sbin/nginx -s reload Stop the server with:

/usr/local/nginx/sbin/nginx -s stop

1. Enable SELinux

Check if SELinux is installed: rpm -qa | grep selinux List booleans with getsebool -a and adjust as needed.

2. Mount Separate Partition for Web Files

Create a dedicated partition (e.g., /dev/sda5) and mount it at /nginx with noexec,nosuid,nodev options:

LABEL=/nginx /nginx ext3 defaults,nosuid,noexec,nodev 1 2

3. Harden Kernel via /etc/sysctl.conf

Apply the following settings to mitigate common network attacks:

# Avoid a smurf attack
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Ignore bogus ICMP errors
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Enable SYN cookies
net.ipv4.tcp_syncookies = 1
# Log martian packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable reverse path filtering
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable IP forwarding
net.ipv4.ip_forward = 0
# Secure redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Increase file descriptor limits
fs.file-max = 65535
kernel.pid_max = 65536
net.ipv4.ip_local_port_range = 2000 65000
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1

4. Remove Unnecessary Nginx Modules

Compile Nginx with only required modules, e.g., disabling autoindex and SSI:

./configure --without-http_autoindex_module --without-http_ssi_module
make
make install

To hide the server version, edit src/http/ngx_http_header_filter_module.c and replace:

static char ngx_http_server_string[] = "Server: nginx" CRLF;
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;

with:

static char ngx_http_server_string[] = "Server: Ninja Web Server" CRLF;
static char ngx_http_server_full_string[] = "Server: Ninja Web Server" CRLF;

Then add server_tokens off; to nginx.conf.

5. mod_security (Apache Only)

Note: mod_security is an application‑level firewall for Apache and is not applicable to Nginx.

6. Install SELinux Policy for Nginx

yum -y install selinux-policy-targeted selinux-policy-devel
cd /opt
wget 'http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc'
tar -zxvf se-ngix_1_0_10.tar.gz
cd se-ngix_1_0_10/nginx
make
/usr/sbin/semodule -i nginx.pp

7. Iptables Firewall Script

The following bash script sets a default‑drop policy, allows loopback and VPN traffic, permits SSH from selected IPs, enables HTTP, NTP and SMTP, and logs/blocks malformed packets and spoofed addresses.

#!/bin/bash
IPT="/sbin/iptables"
# Default policies
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# Allow loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Allow VPN interface
$IPT -A INPUT -i eth1 -j ACCEPT
$IPT -A OUTPUT -o eth1 -j ACCEPT
# SSH from whitelisted IPs (example variable PUB_SSH_ONLY)
for ip in ${PUB_SSH_ONLY}; do
  $IPT -A INPUT -i eth0 -s $ip -p tcp --dport 22 -j ACCEPT
  $IPT -A OUTPUT -o eth0 -d $ip -p tcp --sport 22 -j ACCEPT
done
# HTTP
$IPT -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# NTP
$IPT -A OUTPUT -o eth0 -p udp --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i eth0 -p udp --sport 123 -m state --state ESTABLISHED -j ACCEPT
# SMTP
$IPT -A OUTPUT -o eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
# Log and drop everything else
$IPT -A INPUT -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix "DEFAULT DROP"
$IPT -A INPUT -j DROP
exit 0
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iptablessysctlLinux securitySELinuxHardeningmodule stripping
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.