10.3 Securing Network Services

Key Takeaways

  • Audit listening sockets with ss -lntup to see exactly which processes expose which TCP and UDP ports
  • A service bound to 127.0.0.1 is unreachable from the network; binding to 0.0.0.0 exposes it on every interface
  • TCP wrappers (/etc/hosts.allow, /etc/hosts.deny) only affect programs linked against libwrap and are largely superseded by nftables
  • Harden SSH with key-only authentication (PasswordAuthentication no, PermitRootLogin no) and run Apache with the minimum set of modules
  • Kali disables network services by default, so a fresh install has no listening services — anything listening is something you deliberately started
Last updated: July 2026

10.3 Securing Network Services

Quick Answer: The safest network service is the one that is not running. Audit what is actually exposed with ss -lntup, bind anything local-only to 127.0.0.1, filter the rest with nftables (TCP wrappers are a historical footnote), and harden the services you must run — key-only SSH, minimal Apache modules. Kali's default of no listening services means any open port on your machine is there because you chose it.

Auditing Listening Services with ss

You cannot secure what you have not enumerated. The standard audit command on Kali is:

ss -lntup

The flags decode as: -l listening sockets only, -n numeric (no DNS/service-name lookups), -t TCP, -u UDP, -p show the owning process. Typical output:

Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
udp   UNCONN 0      0      127.0.0.53%lo:53   0.0.0.0:*         users:(("systemd-resolve",pid=401,fd=12))
tcp   LISTEN 0      128    0.0.0.0:22          0.0.0.0:*         users:(("sshd",pid=1204,fd=3))

Read the Local Address column carefully — it tells you the exposure of every socket:

  • 127.0.0.1:5432 (or ::1) — reachable only from the machine itself; safe from network attack
  • 0.0.0.0:22 — listening on every IPv4 interface, including hostile Wi-Fi networks
  • 192.168.1.10:8080 — bound to one specific interface

Run this audit after installing new tools and before connecting to an untrusted network. lsof -i -P -n is a useful cross-check; ss reads socket state from the kernel over netlink (only the -p process mapping walks /proc) while lsof reads /proc directly, and both reveal the owning PID so you can trace a mystery port back to its package with dpkg -S $(readlink -f /proc/<pid>/exe).

Binding to Localhost

The cheapest hardening for a service that only local tools need — a database for a web app you are testing, a caching DNS resolver, a SOCKS proxy — is to bind it to the loopback address. Configuration examples:

  • PostgreSQL: listen_addresses = 'localhost' in /etc/postgresql/<version>/main/postgresql.conf
  • MariaDB/MySQL: bind-address = 127.0.0.1 in the [mysqld] section of its config
  • SSH on a jump host that should only answer on one NIC: ListenAddress 192.168.1.10:22 in /etc/ssh/sshd_config
  • Apache: Listen 127.0.0.1:8080 in /etc/apache2/ports.conf

After any change, restart the service (systemctl restart <service>) and re-run ss -lntup to verify the socket moved. Do not trust the config file alone — typos, included override files, and systemd socket activation can all silently defeat your intent.

TCP Wrappers vs Modern nftables

TCP wrappers were the original host-based access control: programs compiled against libwrap consulted /etc/hosts.allow and /etc/hosts.deny before accepting a connection. Rules were checked in order — hosts.allow first, then hosts.deny — and the first match won, for example:

# /etc/hosts.allow
sshd: 192.168.1.0/24
# /etc/hosts.deny
sshd: ALL

Know the limitations, because the exam tests them: wrappers only govern programs linked against libwrap (check with ldd /usr/sbin/sshd | grep libwrap), they act at the application level after the TCP connection is established, and the stack is deprecated — many modern daemons no longer link libwrap at all. The modern replacement is nftables, which filters in the kernel before any daemon sees the packet:

nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 22 accept
nft add rule inet filter input tcp dport 22 drop

Prefer nftables for new rules; mention TCP wrappers only when describing legacy systems.

One more operational note on firewall rules: rules added with nft on the command line live only in memory until you save them. Persist a working ruleset by writing it into /etc/nftables.conf (the nftables service loads that file at boot), and always keep an established SSH session open while testing a default-drop policy remotely — a bad rule applied over your only connection is the classic self-lockout.

Service Hardening Checklists

SSH — the most exposed service on any pentest box:

  1. Generate a key pair with ssh-keygen -t ed25519 and install the public key on the server with ssh-copy-id user@host.
  2. In /etc/ssh/sshd_config, set PasswordAuthentication no so brute-forcing passwords is pointless (this is what makes fail2ban a second layer rather than your only defense).
  3. Set PermitRootLogin no — authenticate as a normal user, then escalate with sudo.
  4. Optionally restrict users with AllowUsers analyst and move to a non-standard port only as noise reduction, never as a substitute for the above.
  5. Run sudo sshd -t (config syntax check) first, then sudo systemctl restart ssh, and open a second session to confirm you can still log in before closing the one you already have.
  6. Two Kali-specific prerequisites from the book: never enable SSH while the kali account still carries the live-image password kali, and regenerate the host keys (sudo rm /etc/ssh/ssh_host_* && sudo dpkg-reconfigure openssh-server) if the system came from a pre-generated image that shipped with keys already baked in.

Apache — the payload-hosting and phishing workhorse:

  1. Run only needed modules: list with apache2ctl -M, disable with a2dismod <module> (e.g. a2dismod status autoindex), enable with a2enmod.
  2. Set ServerTokens Prod and ServerSignature Off to stop leaking version banners.
  3. Remove or replace default content in /var/www/html/ so a visitor does not fingerprint a stock Kali page.
  4. Keep Options -Indexes so directory listings are never exposed.

Why Kali's Default Stance Matters

Kali ships with SSH, Apache, PostgreSQL and friends installed but disabled: a default install exposes zero network-reachable listening services (only loopback sockets such as systemd-resolved's remain). The book attaches three cautions to enabling any of them: there is no firewall by default, so a service bound to all interfaces is immediately public; some services ship with blank or well-known default credentials (check each package's README.Debian and kali.org/docs/introduction/default-credentials/, and reset every password); and many services run as root, so compromising one is a full compromise. This is policy-as-avoidance — the entire class of remote attacks against daemons you forgot about simply does not apply. It also gives you a clean baseline: after any engagement, ss -lntup should show nothing you cannot explain. If something is listening on a non-loopback address and you did not start it, treat that as a compromise indicator, not a curiosity. And remember the corollary: starting a service with systemctl start lasts until reboot, but systemctl enable makes it permanent — on a machine that joins hostile networks, permanence should be a deliberate, documented decision.

Test Your Knowledge

Which command shows all listening TCP and UDP sockets with numeric addresses and the processes that own them?

A
B
C
D
Test Your Knowledge

Which statement about TCP wrappers is accurate on a modern Kali system?

A
B
C
D