Server Security Configuration for an Independent Website
Server security is not finished when one security product is installed. Common risks for independent websites include default accounts, unnecessary open ports, outdated software, public databases, and backups that have never been restored. The goal is not to promise that a server can never be attacked. The goal is to reduce the attack surface, limit the blast radius, and detect and recover from problems quickly.
1. Use least-privilege accounts
Do not use root for everyday login or deployment. Create a regular administrator account and use sudo only for system administration. Run the application under a separate low-privilege service account.
Also review these basics:
- Remove or lock accounts that are no longer needed.
- Do not share one administrator account among multiple people.
- Give each operator a separate SSH key so access can be revoked individually.
- Never commit passwords, private keys, PayPal secrets, or database credentials to Git or frontend code.
Ubuntu's security guidance recommends the principle of least privilege: use non-root accounts and reserve sudo for administrative tasks. The same principle applies to deployment scripts, scheduled jobs, and application processes.
2. Harden SSH access
Prefer SSH key authentication. After confirming that the new key works, disable password login and direct root login. Restrict SSH by source address when possible; a fixed office network or VPN can be limited to the management port.
Do not close your only active session while changing SSH configuration. A safer process is:
1. Keep one authenticated administration session open. 2. Edit the configuration and validate its syntax. 3. Test a new connection from another terminal. 4. Reload the SSH service only after the new connection works.
Changing the default SSH port is not a replacement for strong authentication and access control. At most, it reduces some low-quality automated scanning noise.
3. Expose only necessary ports
A public website usually needs ports 80 and 443. The SSH port should be restricted. Databases, Redis, internal admin panels, and debugging ports should not be directly exposed to the public internet. Ubuntu's official documentation recommends UFW for managing a host firewall and checking the current rule order and status after changes.
A common baseline is:
- Deny inbound connections by default.
- Allow 80 and 443 for web traffic.
- Allow SSH only from a management network or VPN.
- Allow outbound traffic by default, then restrict it as the application requires.
- Run
ufw status verboseafter every firewall change.
Configure both the cloud security group and the host firewall. A cloud security group is not a substitute for a host firewall; two layers reduce the impact of a single configuration mistake.
4. Use HTTPS and protect the origin
The website, login flow, dashboard, payment callbacks, and APIs should use HTTPS. Configure automatic certificate renewal and monitor certificate expiration. Google sign-in and PayPal callbacks also require the correct HTTPS domain and redirect settings.
If you use a CDN or reverse proxy, configure the origin to accept traffic only from the proxy's egress IPs when appropriate. Cloudflare's origin protection guidance recommends proxied DNS to hide the origin IP and using an origin firewall to allow only Cloudflare IP ranges. It also recommends auditing DNS-only records so subdomains or TXT records do not accidentally reveal the origin.
Do not put every endpoint behind a public cache without a clear policy. Payment, login, admin, and API responses need special cache rules, and sensitive responses must not be publicly cached. The connection from the CDN to the origin should also use HTTPS with correct certificate, Host, and SNI settings.
5. Update regularly and minimize software
Every package, panel, plugin, and listening service increases the attack surface. Install only what the business needs, remove unused services, and periodically review listening ports and system users.
Ubuntu Server documentation recommends regular security updates and supports unattended-upgrades for automatic security patches. Automatic updates are not a complete change-management process: production still needs backups, health checks, change records, and a reboot plan so an update does not fail silently.
6. Protect secrets, databases, and backups
Provide environment variables through a secrets manager or a restricted configuration file. Only the application service and a small number of administrators should be able to read them. Databases should not listen on public addresses, and backups should be encrypted and stored separately from the origin server.
A backup policy should answer four questions:
- What is backed up? Databases, uploaded files, configuration, and certificate-related information.
- How long is it kept? Use separate retention periods for quick recovery points and long-term archives.
- Who can access it? Backup storage should not reuse the root key for the website server.
- How is it restored? Run recovery drills instead of checking only that a backup job reported success.
7. Use monitoring to detect problems
After security configuration, observe the actual system. Monitor website availability, TLS certificates, DNS resolution, response time, 5xx errors, disk space, CPU, memory, and unusual login activity. Send alerts to an independent email address or notification channel instead of writing everything only to the same server's logs.
Also distinguish an HTTP 200 response from correct business content. A server can return 200 while serving an error page, maintenance page, or modified content. For that reason, website monitoring should check expected keywords or response content when the business requires it, not only the status code.
A minimum production security baseline
If time is limited, complete these items first:
1. Regular administrator account plus SSH keys; disable root password login. 2. Firewall with only web ports and a restricted management port exposed. 3. HTTPS for the website, APIs, login, and payment callbacks. 4. No public access to databases or internal services. 5. Security updates enabled, with a health check after updates. 6. Secrets kept out of the repository and backups stored separately. 7. Monitoring for normal responses, technical failures, and content mismatches.