Jun 20, 2026
8 min read
Advanced SSH Server Configuration and WAF Deployment
Securing Web Infrastructure: Advanced SSH Server Configuration and WAF Deployment. Modern web infrastructure demands a layered defense strategy. Relying solely on standard cloud firewalls leaves applications vulnerable to sophisticated application-layer threats, brute-force exploits, and credential-stuffing attacks. To build a robust, secure infrastructure, administrators must secure both the remote administration pipeline and the public-facing HTTP traffic stream.This guide details the step-by-step implementation of a secure remote management standard using OpenSSH, alongside the integration of a Web Application Firewall (WAF) using Nginx and ModSecurity v3.1. Advanced SSH Server Hardening ArchitectureThe Secure Shell (SSH) protocol provides administrative access to your core infrastructure. Because it grants root-level execution capabilities, an unhardened SSH service is a prime target for continuous automated scanning and brute-force campaigns. Securing this pipeline requires moving away from default configurations and enforcing cryptographically sound access patterns.Enforcing Key-Based AuthenticationPassword-based authentication is fundamentally vulnerable to social engineering, dictionary attacks, and credential stuffing. Cryptographic key pairs (specifically Ed25519) offer superior protection by utilizing asymmetric cryptography that cannot be brute-forced.To generate a secure key pair on your local client machine, execute:bashssh-keygen -t ed25519 -a 100 -C "admin@infrastructure"Use code with caution.-t ed25519: Specifies the Ed25519 public-key algorithm, which offers better performance and security than legacy RSA keys.-a 100: Increases the number of KDF (Key Derivation Function) rounds to make passphrase cracking significantly slower.Deploy the public key to the remote web server using:bashssh-copy-id -i ~/.ssh/id_ed25519.pub username@server_ipUse code with caution.Modifying the SSH Deamon Configuration (sshd_config)Once your cryptographic key access is confirmed working, modify the primary daemon configuration file at /etc/ssh/sshd_config. Open the file using a standard terminal text editor:bashsudo nano /etc/ssh/sshd_configUse code with caution.Incorporate or adjust the following configuration parameters to disable legacy access vectors and restrict communication lanes:text# Move off the default port to reduce automated script sweepsPort 2222# Explicitly enforce SSH Protocol 2Protocol 2# Disable root login entirely; require users to log in as unprivileged accounts and scale privileges via sudoPermitRootLogin no# Block password authentication completely, rendering brute-force attacks uselessPasswordAuthentication noPermitEmptyPasswords no# Enforce strict key authentication compliancePubkeyAuthentication yes# Terminate inactive sessions promptly to prevent session hijacking on open terminalsClientAliveInterval 300ClientAliveCountMax 2# Limit concurrent unauthenticated connections to mitigate Denial of Service (DoS) attemptsMaxStartups 10:30:100# Strict explicit user access control mappingAllowUsers adminuser webdeployerUse code with caution.Implementing Multi-Factor Authentication (MFA)For high-security compliance environments, combine SSH keys with a secondary Time-based One-Time Password (TOTP).Install the Google Authenticator PAM module on your server:bashsudo apt update && sudo apt install libpam-google-authenticator -y
Use code with caution.Run the initialization wizard as the target administrative user:bashgoogle-authenticator
Use code with caution.Follow the interactive prompts to generate your emergency scratch codes, display the authentication QR code, and update your local security file settings.Next, open the PAM configuration file for SSH:bashsudo nano /etc/pam.d/sshd
Use code with caution.Append the following execution line to the bottom of the file structure:textauth required pam_google_authenticator.so nullokUse code with caution.Finally, re-open /etc/ssh/sshd_config and adjust the authentication methods rule to require both factors sequentially:textKbdInteractiveAuthentication yesAuthenticationMethods publickey,keyboard-interactiveUse code with caution.Test your syntax validation profile before restarting the service framework:bashsudo sshd -tsudo systemctl restart sshdUse code with caution.2. Web Application Firewall (WAF) Settings and Compilation StrategyWhile network firewalls filter traffic based on IP addresses and ports, a Web Application Firewall operates at Layer 7 (the application layer) of the OSI model. It inspects the actual content of HTTP requests to identify and block malicious payloads such as SQL Injection (SQLi), Cross-Site Scripting (XSS), and Remote Code Execution (RCE) vulnerabilities.The production configuration below couples the high-performance Nginx reverse proxy web server with ModSecurity v3 (libmodsecurity) and the OWASP Core Rule Set (CRS).Installing Prerequisites and Building ModSecurity v3To maximize performance and security control, compile ModSecurity v3 directly on the target distribution instance. First, install the necessary dependencies:bashsudo apt updatesudo apt install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev \ libgeoip-dev liblmdb-dev libpcre3-dev libtool libxml2-dev libyajl-dev pkgconf zlib1g-devUse code with caution.Clone the repository and compile the library framework source components:bashcd /usr/local/srcsudo git clone --depth 1 -b v3/master https://github.comcd ModSecuritysudo git submodule initsudo git submodule updatesudo ./build.shsudo ./configuresudo make -j$(nproc)sudo make installUse code with caution.Compiling Nginx with the ModSecurity Connector ModuleNginx interacts with the ModSecurity core engine using an external dynamic module link layer. Download the connector source alongside a matching version of the Nginx core engine:bashcd /usr/local/srcsudo git clone --depth 1 https://github.com# Determine current Nginx version package to pull matching development buildsnginx -v# Example uses Nginx version 1.26.1sudo wget http://nginx.orgsudo tar -xvzf nginx-1.26.1.tar.gzcd nginx-1.26.1# Configure Nginx arguments to compile the module dynamicallysudo ./configure --with-compat --add-dynamic-module=/usr/local/src/ModSecurity-nginxsudo make modulessudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/Use code with caution.Load the module file configuration inside the primary global context file area at /etc/nginx/nginx.conf:nginxuser www-data;worker_processes auto;pid /run/nginx.pid;include /etc/nginx/modules-enabled/*.conf;# Explicitly inject the compiled WAF module binary targetload_module modules/ngx_http_modsecurity_module.so;Use code with caution.3. Implementing the OWASP Core Rule Set (CRS)The WAF engine requires a rule set to define what constitutes an attack. The OWASP Core Rule Set (CRS) provides a widely trusted collection of generic attack detection rules designed to catch zero-day vulnerabilities and common web exploits.bashcd /etc/nginxsudo mkdir wafcd wafsudo git clone --depth 1 -b v4/dev https://github.comsudo cp coreruleset/crs-setup.conf.example crs-setup.confsudo cp -r coreruleset/rules .Use code with caution.Create a master compilation wrapper profile at /etc/nginx/waf/modsecurity.conf to organize rule ingestion steps:bash# Initialize using the default sample templatesudo cp /usr/local/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/waf/modsecurity.confsudo cp /usr/local/src/ModSecurity/unicode.mapping /etc/nginx/waf/Use code with caution.Edit /etc/nginx/waf/modsecurity.conf to toggle the inspection engine from monitoring mode to active intervention block deployment:text# Change from DetectionOnly to On to actively block malicious trafficSecRuleEngine OnSecRequestBodyAccess OnSecResponseBodyAccess OnSecAuditEngine RelevantOnlySecAuditLogParts ABIJDEFHZSecAuditLog /var/log/nginx/modsec_audit.logUse code with caution.Append your rule ingestion pipeline configurations directly to the bottom of the master /etc/nginx/waf/modsecurity.conf structure layout:text# Include the primary configuration file blockInclude /etc/nginx/waf/crs-setup.conf# Include the target application rule setsInclude /etc/nginx/waf/rules/*.confUse code with caution.4. Activating WAF Filtering in Nginx Server BlocksWith the module compiled and the OWASP rules configured, you can now activate the WAF inside your virtual host or server block profiles. Open your active production site layout mapping at /etc/nginx/sites-available/default:nginxserver { listen 80; listen [::]:80; server_name example.com ://example.com; # Global WAF Engine activation configurations modsecurity on; modsecurity_rules_file /etc/nginx/waf/modsecurity.conf; root /var/www/html; index index.html index.htm; location / { try_files $uri $uri/ =404; } # Custom localization rules overrides example zone location /api/public/ { # Retain standard parameters while tuning anomaly profiles specifically for API integrations proxy_pass http://api_backend; } # Restrict administrative login routes exclusively to known internal subnets location /admin { allow 192.168.10.0/24; allow 10.0.5.0/24; deny all; } error_page 403 /custom_403.html; location = /custom_403.html { root /usr/share/nginx/html; internal; }}Use code with caution.Verify your Nginx pipeline layout parameters before forcing service reloads:bashsudo nginx -tsudo systemctl restart nginxUse code with caution.5. Verification and Diagnostic Validation CommandsTo verify that your security architecture is working correctly, test both the SSH entry constraints and the WAF intervention mechanisms.Testing Hardened SSH Verification LinesAttempt to connect from an outside node using password prompts or legacy parameters:bash# Attempting a connection over standard legacy default ports should timeoutssh username@server_ip -p 22# Explicitly force-testing connection utilizing password override settings should immediately failssh username@server_ip -p 2222 -o PubkeyAuthentication=noUse code with caution.The output logs should print an unambiguous Permission denied (publickey) or refuse connection mapping parameters entirely.Simulating Web Attacks to Validate WAF PerformanceYou can test the WAF by simulating web exploits using standard command-line tools like curl. Run these tests from an external machine to see if the WAF intercepts the malicious requests.Test 1: Simple Directory Traversal Attack Simulationbashcurl -I "http://example.com"Use code with caution.Test 2: Standard SQL Injection (SQLi) Vector Simulationbashcurl -I "http://example.com"Use code with caution.Expected Output BehaviorIf ModSecurity and the OWASP CRS are running correctly, the server will block these requests before they reach your web application. The output log terminal will display an HTTP 403 Forbidden status code:textHTTP/1.1 403 ForbiddenServer: nginxDate: Sat, 20 Jun 2026 09:14:22 GMTContent-Type: text/htmlConnection: closeUse code with caution.Analyzing Real-Time Security LogsWhen the WAF blocks an attack, it logs detailed transaction records to your audit trails. Inspect these logs to review incoming attack payloads and debug potential false positives:bash# Review system block transactions in real timesudo tail -f /var/log/nginx/modsec_audit.logUse code with caution.A typical alert entry contains deep structural metadata indicating the exact rule that was triggered:text[Message: Warning. Pattern match "(?i)(?:\\b(?:etc\\b\\bpasswd\\b))" at ARGS:file.][Action: Keep (Anomaly Score updated to 5)][Severity: Critical][ID: 930110]Use code with caution.ConclusionBy hardening your SSH configuration and deploying a compiled Nginx ModSecurity WAF, you establish a solid security baseline for your web application infrastructure. These layers protect against remote administration exploits while inspecting public HTTP traffic to block web vulnerabilities before they hit your application logic.