You will run several services (web, DNS, database) safely on one hardened Linux host behind a default-deny firewall, each managed by systemd. By the end the server delivers all three services with least-privilege exposure.

Learning Objectives

  • Install and manage web, DNS, and database services.
  • Expose only the required ports with nftables.
  • Monitor service health with systemd and logs.
  • Time: ~12 hours · Difficulty: Advanced · Prereqs: the Linux server labs.

Architecture Overview

Environment Setup

  • A Linux server with systemd and nftables.
  • Nginx, BIND9, and PostgreSQL packages.

Step-by-Step Execution

01
Install and enable the services
sudo apt install -y nginx bind9 postgresql && sudo systemctl enable --now nginx named postgresql
02
Expose only required ports

The database stays local-only; only web and DNS are reachable.

sudo nft add rule inet filter input tcp dport {80,443} accept && sudo nft add rule inet filter input udp dport 53 accept
03
Verify all services are healthy
$ systemctl is-active nginx named postgresql
active active active

Progress So Far

Testing & Validation

curl -s -o /dev/null -w "%{http_code}\n" http://localhost && dig @localhost lab +short && nft list ruleset | grep 5432 || echo "db not exposed"

Web returns 200, DNS resolves, and the database port is not exposed externally. If so, the server runs all services with least privilege.

Troubleshooting
  • Service won't start: inspect journalctl -u <service> for the failure.
  • Port unreachable: confirm the nftables accept rule precedes the default drop.
  • DB reachable externally: bind PostgreSQL to localhost and block 5432 at the firewall.

Extension Ideas

Key Results

  • Ran web, DNS, and database on one hardened host.
  • Exposed only the required ports via default-deny nftables.
  • Kept the database local-only with no external exposure.
  • Verified health of all three services.