curl localhost. Those local checks are essential for troubleshooting on the host, but they do not show how a remote client (browser or external curl) experiences the services — or how a host firewall (UFW) affects access.
In this lesson you’ll learn to use UFW (Uncomplicated Firewall) on Ubuntu to control which ports are reachable from the internet. We’ll show the commands and expected outputs for enabling UFW and adding rules for HTTP, HTTPS, and SSH. We also cover safe patterns for exposing backend services (like a Flask app) via a reverse proxy instead of opening nonstandard ports.
Overview of services on the host
Initially the firewall is inactive, so both ports are reachable from outside. We’ll enable UFW and restrict access to just the ports we want.
Quick local checks (server-side)
From the server shell you can confirm both services are responding usingcurl. These are local checks and only validate that the services are listening on the expected ports.
curl against the host’s public IP or domain.
Convenience UIs vs. proper firewall rules
Some cloud or development environments offer a “View ports” or similar UI that temporarily exposes a host port to your browser. That can be useful for demos but should not replace proper firewall configuration in production. Use UFW (or your cloud provider’s security groups/load balancer) to manage access in a secure, repeatable way.Enable UFW and add port rules
Best practice is to enable the firewall and open only the ports you need — typically 80 and 443 for web traffic, and 22 for SSH (preferably restricted to known IPs). Start by checking UFW status, enable it, and add rules:Allow SSH (port 22) before disconnecting
Important: If you’re connected over SSH, allow port 22 before you enable UFW or before you end your session — otherwise you may lock yourself out.Commands summary
Do not make backend applications publicly reachable on nonstandard ports (like 5000) unless absolutely necessary. Publicly exposing these ports can cause usability and security issues — most users expect websites on ports 80/443 and may omit port numbers in URLs.
Prefer exposing backend apps (for example, a Flask app on port 5000) through a reverse proxy or load balancer. Configure NGINX (or a cloud load balancer) to listen on 80/443 and forward requests internally to the backend port. This keeps only 80/443 (and SSH) open to the internet while backend services remain inaccessible directly.
Quick best-practice checklist
- Open only the ports you need. For public web services: 80 and 443. For administration: 22, ideally restricted to trusted IPs.
- Use a reverse proxy (NGINX) or load balancer to expose backend services on standard ports, instead of opening backend ports to the internet.
- Always enable UFW and verify rules before closing your administrative session.
- For production, enforce HTTPS (443) and consider automated certificate management (e.g., Let’s Encrypt).
Links and references
- UFW — Uncomplicated Firewall
- NGINX documentation
- Flask documentation
- Let’s Encrypt — Free SSL/TLS certificates