Manuals
RU EN

Server · 84

Firewall on a VDS for a PHP website

Server 6 min read

A fresh VDS from a provider panel often exposes everything: SSH, sometimes MySQL, and a panel on an odd port. Configure the firewall before deploying a script with real data, not after a breach.

The goal is simple: expose only what people and administrators need. A PHP website usually needs 80/443, while admins need SSH. MySQL does not need to be on the internet.

Minimum ports

  • 22/tcp, or your custom SSH port, only for admins; preferably restricted by IP if the IP is stable.
  • 80/tcp for HTTP, redirects, and Let's Encrypt issuance.
  • 443/tcp for HTTPS.
  • 3306/tcp from outside: close it. Listen on 127.0.0.1.

ISPmanager or another panel has a separate port; either close it from outside and use an SSH tunnel, or restrict it strictly by IP. Leaving a panel open to the world with the password from an email is not acceptable.

UFW on Ubuntu - typical base

ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Before enable, make sure the SSH rule exists, or you will lock yourself out. Keep the provider console, KVM/VNC, ready.

firewalld on CentOS/RHEL follows the same idea with different commands: ssh, http, https in the public zone; do not open mysql.

MySQL only locally

Set bind-address = 127.0.0.1, or the MariaDB equivalent. A script on the same machine connects to localhost, which is enough. Remote database access from a home PC should use an SSH tunnel, not an open 3306.

Open MySQL with password root/root on a fresh VDS is scanner folklore. Even with a strong password, it is unnecessary surface area.

SSH

  • Keys instead of password.
  • fail2ban or equivalent.
  • If possible, another port plus disabled root password login.

Do not confuse "close 22" with "keep only keys on 22". If you close SSH incorrectly, only the provider console can save you.

Cloudflare and origin. If you proxy the site through CF, still keep a firewall on origin. You can restrict 80/443 to Cloudflare IPs, but then direct checks by server IP become harder. Do it deliberately.

Let's Encrypt

The HTTP-01 challenge requires port 80 to be reachable from outside, unless you use DNS challenge. Do not close 80 completely if you use HTTP validation. After issuance, redirecting to 443 is normal. SSL: manual.

Connection with the stack

Nginx/FPM: setup. VDS choice: VDS for PHP. Root access: VPS with root. Install the script after basic security: installation.

Check

From another machine:

nmap -p 22,80,443,3306 YOUR_IP

3306 must not show open to the world. From the server itself, mysql on 127.0.0.1 should work.

If the site does not open after firewall changes, check ufw status and whether nginx listens on 0.0.0.0:80/443. Connection refused to the site is not a PHP error.

Backups and monitoring

A firewall does not replace backups and does not catch a vulnerability in the PHP script. Copies: backup. Availability: monitoring. Product incidents: support.

On a local Windows MicroServer, you usually do not touch the home firewall for *.loc; that is a different flow: local server.

Rule order matters

In iptables/ufw, allow SSH first, then the rest, then enable the deny policy. The reverse order on a remote machine without KVM is a classic way to close your own access. Before experimenting, open the provider web console and confirm it works.

If you changed SSH to port 2222, the ufw rule must allow 2222, not only the OpenSSH profile on 22. Otherwise the current session remains alive, but a new login is impossible.

Panels and additional ports

ISPmanager, phpMyAdmin, RabbitMQ, Redis UI - all of these may listen on ports. Either close them from outside or restrict by IP. Redis and MySQL on 0.0.0.0 with password "1" is a ready-made incident. For a Microscript PHP script, the outside world needs only web and SSH.

If you need MySQL access from a work laptop, use an SSH tunnel:

ssh -L 3307:127.0.0.1:3306 user@vds

Locally, connect to 127.0.0.1:3307. Do not open port 3306 on the public interface.

Provider firewall and ufw together

Many VDS providers have security groups or a firewall in the account panel. Rules there and on the machine must agree. You opened 443 in ufw but forgot it in the provider panel: externally, the port is closed. The reverse also happens. When "the site does not open", check both layers before Nginx.

Geo and scanners

After a VDS starts, auth logs immediately show foreign login attempts. This is normal internet background noise. fail2ban on sshd reduces it. Do not keep the root password from the welcome email longer than the first hour. SSH keys are the base. General hardening after purchase: VPS with root, VDS choice.

What to do after web setup

  1. Check from a phone on LTE, not the same Wi-Fi/VPN, that the site opens.
  2. Check that external nmap does not show 3306.
  3. Issue SSL: SSL.
  4. Install the script: installation.
  5. Enable uptime monitoring: monitoring.

If the site disappears after ufw enable while SSH stays alive, you probably forgot allow 80/443. If everything disappears, use the provider console and ufw disable or fix the rules.

Docker and firewall

Docker likes to insert its own iptables chains. UFW rules can sometimes be bypassed by container port publishing. If you run MySQL in Docker with publish 3306:3306 on 0.0.0.0, you get a hole despite the "logical" policy. Publish to 127.0.0.1:3306 or do not publish at all; leave it inside the Docker network.

For a classic Nginx+PHP-FPM+MariaDB stack on the host without Docker, there are fewer surprises: Nginx + PHP-FPM. Backups and migrations after the perimeter is closed: backup, migration.

Do not temporarily open everything to everyone with ufw allow 3306 overnight for a colleague's convenience; in the morning you will forget to close it. A tunnel is faster to set up once than investigating a hacked database. The same applies to a panel on 8080/1500: use VPN or allow a specific IP. After any firewall edit, check the site from mobile internet and open a new SSH terminal, not only the already open session. If you locked yourself out, use the provider console, not immediate VDS reinstall. Machine and root choice: VDS, VPS with root. Install the script behind the closed perimeter: installation.

FAQ

Firewall on vds for php website?

An externally open MySQL port is a common hole on a fresh VDS.

How long does “Firewall on a VDS for a PHP website” take?

About 6 minutes to read. In practice it depends on your hosting and database setup.

Do I need a dedicated server?

For most scripts, shared hosting or a VDS with PHP and MySQL is enough. See the VDS section and PHP/MySQL requirements.

Vds for a php site with mysql?

See the related manual for this query. vds for a php site with mysql

Vps with root for a php script?

See the related manual for this query. vps with root for a php script

Section
VDS and PHP server

A PHP/MySQL server: from plan choice to Nginx and firewall.