Production Security And Server Hardening
CIS Hardening And Server Baselines
Server hardening is the work of reducing unnecessary risk before an incident forces the issue. A PHP application can have good input validation, prepared statements, escaping, and tests, but still run on a server with stale packages, password SSH login, unused network services, world-writable files, missing logs, no backup verification, and no clear owner. Hardening connects application security to the operating environment. It asks what the server exposes, who can change it, which services run, how configuration is reviewed, and how the team proves that the baseline remains true over time.
CIS Benchmarks and CIS Controls are useful references for this work, but they are not magic checklists. The Center for Internet Security publishes CIS Benchmarks for secure configuration guidance and CIS Controls as prioritized safeguards. CIS also describes Implementation Groups that help organizations prioritize safeguards by risk and resources. Use the official CIS pages for current materials, version names, supported technologies, and access requirements. A curriculum lesson should teach learners how to use a benchmark responsibly, not tell them to paste hardening commands into production without understanding the service they are protecting.
What A Baseline Means
A baseline is a documented expected state. For a production PHP server, a baseline can include operating system version, package sources, enabled services, open ports, local users, SSH policy, firewall policy, PHP-FPM pools, web server configuration, TLS termination, log locations, backup jobs, monitoring checks, and update process. It should also include ownership: who approves changes, who receives alerts, and who can recover access when a normal login path fails.
The baseline is not the same as a one-time setup script. A script can configure a server today. A baseline lets the team detect drift tomorrow. Drift happens when a package is installed for debugging and never removed, an emergency firewall change stays open, a temporary user account remains active, a service starts listening on a new interface, or a deploy script changes permissions to make a release work quickly. Hardening without drift detection slowly becomes documentation fiction.
A strong baseline is specific enough to verify. Secure SSH is not a baseline. Root login is disabled, password authentication is disabled for production, approved users authenticate with named keys, emergency access is documented, and failed login attempts are monitored is closer. The exact policy depends on the organization and operating system, but the statement is testable.
CIS As Guidance, Not Blind Law
CIS Benchmarks are detailed secure-configuration recommendations for specific technologies. That specificity is their strength and their risk. A benchmark written for one Linux distribution, cloud image, database version, or web server may not apply cleanly to another. Even when the benchmark matches the platform, some recommendations can break a required workload if applied without review.
For example, a recommendation to disable an unused service is usually sensible. A recommendation that changes filesystem mount options, authentication rules, logging behavior, kernel parameters, or service restrictions may affect deployment scripts, monitoring agents, backup software, PHP-FPM, web server behavior, or emergency access. The team should understand the control, test it in staging or a disposable environment, document exceptions, and verify production behavior after rollout.
This is the right mental model: CIS helps ask better questions and provides consensus-backed defaults, but the system owner remains responsible for fit. A control can be accepted, adapted, deferred, or rejected with a documented reason. Undocumented exceptions are dangerous because future maintainers cannot tell whether the server is intentionally different or simply neglected.
Inventory Comes First
Hardening starts with inventory. You cannot reduce attack surface if you do not know what exists. For a server, inventory includes users, groups, SSH keys, packages, services, timers, cron jobs, open ports, listening addresses, firewall rules, mounted filesystems, application directories, credentials, certificates, backups, log sinks, monitoring agents, and network paths.
For a PHP application host, include the application-specific pieces: PHP version, extensions, Composer dependency policy, web server, PHP-FPM pools, queue workers, scheduled jobs, writable directories, session storage, upload directories, cache directories, database connection paths, object storage access, and deployment user. Many incidents begin with a forgotten component: an old admin panel, an unused staging vhost, a backup script with broad credentials, or a worker process that still uses an old release.
Inventory should be repeatable. A spreadsheet created during setup is better than memory, but a command or configuration-management report is better when it can be rerun. The goal is not to collect trivia. The goal is to know which assets need patching, monitoring, access review, backup, and incident response.
Attack Surface Reduction
Attack surface is everything an attacker can reach or influence. Reducing it usually means removing unnecessary services, closing unnecessary ports, limiting network exposure, reducing privileges, disabling unused accounts, tightening file permissions, and keeping only required software installed. This is where hardening becomes practical.
A PHP web server usually needs inbound HTTP and HTTPS at the edge, and perhaps SSH from an admin network or bastion. It usually does not need a database listening publicly, a development server bound to all interfaces, an old FTP service, or a message queue exposed to the internet. Internal access should be explicit too. If the web server talks to a database, define which network path allows that. If deployment happens over SSH, define where it can originate.
Reducing services also reduces patch burden. Every installed daemon and package may have vulnerabilities, configuration requirements, logs, and update cycles. Removing what is not needed is often simpler than securing it forever. Be careful, though: remove services through a controlled process. Verify dependencies before disabling something a monitoring agent, backup system, or cloud image expects.
SSH And Administrative Access
SSH is often the most important administrative boundary on a Linux server. A hardened SSH policy typically prefers named user accounts, key-based authentication, no direct root login, limited users or groups, sensible logging, and a documented emergency path. Some environments add multi-factor authentication, bastion hosts, short-lived certificates, or just-in-time access. The correct design depends on team size, compliance needs, and recovery requirements.
Disabling password login can be a good production control, but only after verifying key access, emergency access, and console recovery. Locking out every administrator is not security; it is an outage. Root login should normally be disabled remotely because direct root access weakens accountability. Administrators can use privilege escalation with logging when required.
Key management is part of SSH hardening. Keys should be named, current, and removed when devices or people leave. Shared private keys are a serious smell because they destroy accountability and complicate rotation. A deploy key used by automation should be separate from a human administrator's key.
Updates, Vulnerabilities, And Change Windows
Hardening is not complete without update discipline. Operating system packages, PHP versions, web servers, OpenSSL, databases, monitoring agents, and application dependencies all receive security fixes. A server that was hardened six months ago but never patched is not hardened today.
Automatic security updates can be appropriate for some packages and environments, but they require monitoring and rollback thinking. Manual patch windows can be appropriate when changes need staging and coordination, but they fail if nobody schedules them. The team should define what updates happen automatically, what updates require review, how quickly critical security fixes are applied, how compatibility is tested, and how failures are detected.
Vulnerability management also needs asset inventory. A new OpenSSL vulnerability matters only if you know which servers and containers include affected versions. A PHP extension vulnerability matters only if you know where the extension is installed. Hardening and inventory reinforce each other.
Logging, Monitoring, And Evidence
A hardened baseline should include evidence. Logs should show authentication attempts, privilege escalation, web server errors, PHP application errors, service restarts, deployment events, and suspicious traffic where appropriate. Monitoring should detect service downtime, high error rates, disk exhaustion, expired certificates, failed backups, queue growth, unexpected ports, and unauthorized login attempts.
Do not wait for a compromise to decide where logs are. If an attacker deletes local logs and nothing was shipped elsewhere, investigation becomes harder. Centralized logging, immutable storage, or provider-managed log retention may be appropriate depending on risk. Even small applications benefit from basic external uptime checks and error alerts.
Evidence also matters for hardening itself. If the baseline says root SSH login is disabled, verify it. If the firewall says only ports 80 and 443 are public, scan from outside. If backups are configured, restore one. If updates are automatic, review update logs and alerting. A baseline without verification is a hope.
Exceptions And Documentation
Every real system has exceptions. A legacy integration may require an older package. A vendor agent may need a port. A migration may require temporary write access. The problem is not the existence of exceptions; the problem is undocumented exceptions that become permanent.
Document each exception with the control, reason, owner, risk, compensating control, and review date. For example: Password SSH remains enabled on staging until the contractor migration ends on July 31; access is limited to the VPN source range; logs are reviewed daily; production remains key-only. That is very different from discovering that password login is enabled everywhere and nobody remembers why.
Review Checklist
Review a server hardening baseline by asking whether the team can list assets, users, services, ports, credentials, update policy, backup policy, logging, monitoring, and recovery access. Confirm that CIS or other benchmark recommendations are mapped to the actual platform and that exceptions are documented. Verify controls from outside the server where possible. Confirm that changes are tested before production and that drift is detectable.
The learner should be able to explain what CIS Benchmarks are for, create a server baseline, distinguish secure configuration from blind hardening, inventory a PHP production host, reduce attack surface, reason about SSH and update policy, document exceptions, and verify that the hardened state remains true.
Practice
Build a baseline
Design a baseline checklist for a PHP production server running Nginx, PHP-FPM, a queue worker, cron jobs, and a PostgreSQL connection to another host.
Include at least ten items covering users, services, ports, updates, logs, backups, credentials, and monitoring.
Show solution
- operating system and package source versions;
- approved local users and groups;
- SSH policy, allowed users, and emergency access;
- open inbound ports and firewall rules;
- enabled services, including Nginx, PHP-FPM, queue worker, and cron;
- disabled or removed unused services;
- PHP version, extensions, and FPM pool user;
- application writable directories and permissions;
- database network path and credential storage;
- backup job schedule and latest restore test;
- log locations and centralized log forwarding;
- update policy and security patch window;
- uptime, error-rate, disk, certificate, and queue monitoring.
The checklist is useful because each item can be verified and assigned to an owner.
Review a CIS exception
We are not applying the SSH benchmark because it breaks access.
Rewrite it into an acceptable exception record.
Acceptance criteria:
- Name the specific control or setting being deferred.
- Explain the reason.
- Add an owner and review date.
- Add at least one compensating control.
Show solution
Control: Disable SSH password authentication on production web-01.
Status: Deferred until 2026-07-31.
Reason: Two emergency administrators still need hardware-key enrollment before key-only access can be enforced.
Owner: Operations lead.
Compensating controls: SSH is restricted to the VPN source range, root login is disabled, authentication logs are forwarded centrally, and failed login alerts are enabled.
Review date: 2026-07-15.
This record is specific, temporary, owned, and reviewable. It does not use a vague compatibility claim to bypass hardening indefinitely.
Verify hardening
- only ports 80 and 443 are public;
- root SSH login is disabled;
- backups run nightly;
- queue workers restart after deployment;
- application errors alert the team.
For each claim, describe one verification method and what failure would mean.
Show solution
- Public ports: scan from outside the network or check cloud firewall exposure. Failure means the external attack surface is larger than documented.
- Root SSH login: inspect SSH configuration and attempt a controlled login test through the approved path. Failure means administrative accountability is weaker than expected.
- Backups: inspect job logs and perform a restore test. Failure means backups may not support recovery.
- Queue workers: deploy to staging and confirm worker process restart plus successful processing of a safe test job. Failure means background work may run old code or stop after release.
- Error alerts: trigger a safe test error in staging or use the monitoring tool's test notification. Failure means production errors may go unnoticed.
The point is to prove the baseline from observable evidence, not to trust that a document is still true.