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.
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 -tOutputs syntax OK messages. Reload configuration with: /usr/local/nginx/sbin/nginx -s reload Stop the server with:
/usr/local/nginx/sbin/nginx -s stop1. 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 23. 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 = 14. 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 installTo 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.pp7. 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 0Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
