# Firewall, SSH and brute-force protection

> Source: https://www.allsweb.com/sixpanel/docs/firewall-and-ssh
> Markdown for agents: https://www.allsweb.com/sixpanel/docs/firewall-and-ssh.md
> Publisher: AllsWeb (www.allsweb.com)

Part of: SixPanel documentation

**What this page is for:** the firewall that runs on this server itself, the
**Allow traffic from Cloudflare only** switch, who may sign in over SSH, the
addresses fail2ban bans, and the security score that sums it all up.

- **Server → Firewall** — two tabs. **This server's firewall**: the server's own
  firewall, the reachability check, the Cloudflare-only switch and the rules that
  live on other pages. **Your hosting provider's firewall**: the rules to add at
  your provider (**[Firewall and ports](https://www.allsweb.com/sixpanel/docs/firewall)**). Each tab starts with a
  short **What to do** list.
- **Security → SSH** — password, key and root login, the SSH port, who signed in.
- **Security → Brute-force protection** — fail2ban's jails, bans, the never-ban
  list, permanent blocks and what it did.
- **Security → Security score** — one card of checks, each with its fix.

**You need**

- The owner's login. A temporary login and the read-only demo see none of this.
- For SSH changes: an SSH key that already works on an account that can use
  `sudo`. The panel refuses a change that would leave nobody able to sign in.

**The rule that does not move:** nothing here can close SSH, the panel's port,
or ports 80 and 443. Every firewall change undoes itself after 60 seconds
unless you press **Keep** in the browser — so if a change cuts you off, you are
back in a minute without doing anything.

---

## The server's own firewall

A firewall that runs on this server, in an nftables table of its own
(`inet sixpanel_fw`). It never touches fail2ban's table, Docker's rules or
anything your distribution set up. It is **off** until you turn it on.

### What is always open

These are open whatever the rules say, and the tab shows them as chips:

- every port SSH listens on (port 22, and any port in the SSH settings);
- the panel's own port;
- **80** and **443** — your websites and their certificate renewals (and UDP
  443 when the web server answers HTTP/3);
- answers to connections the server itself made, the server talking to
  itself, the replies that renew its network address, and the network messages
  the internet needs (for IPv6 these get through even with ping blocked —
  without them IPv6 stops working).

A rule that tries to close one of these is refused with a sentence that says
why, instead of being saved as a rule that does nothing.

### Turn it on

Turn the **Firewall** switch on. The dialog lists every program that listens on
a public address and would stop answering — a mail server, an FTP server — each
**ticked**, so it stays open unless you untick it. Press **Turn on**.

Then the **Keep** dialog opens and counts down from 60 seconds.

### Keep, or it undoes itself

Every change — turning it on or off, a rule, an address, an import — works the
same way:

1. the panel checks the new rules with `nft -c` (nothing changes yet);
2. it sets up the way back first: a timer that puts the previous rules back in
   60 seconds;
3. only then the new rules take effect;
4. **Keep**, pressed in your browser, stops the timer and saves the rules for
   the next boot.

If the new rules cut your browser off, you cannot press Keep — and a minute
later the server has put the old rules back by itself. Leaving the page without
pressing anything does the same. While a change waits, a banner at the top of
the tab offers **Keep** and **Undo now**, and no other change can start.

### Port rules

Open a port (or a range like `3000-3010`) to everyone or to a few addresses, or
close one. **TCP**, **UDP** or both. A rule that closes a port wins over one
that opens it. Up to 200 rules, each with up to 20 source addresses. Rules only
count while the firewall is on.

**Rules SixPanel keeps for a service.** While SixPanel Email or the FTP server is installed, each
of its ports is a rule here marked *Opened by SixPanel Email* (or *by the FTP server*) — *follows
the service*. SixPanel writes these itself, without the minute to Keep (it is the panel opening a
service it just installed, not a change made over the network): nftables checks them first, they
are kept at once and the activity log names each one. They go when the service is removed, a
mail-app port is switched off or an FTP port moves, and the panel puts them back in line when it
starts. They have no Remove button; to keep such a port closed, add a **deny** rule. Your own
rules are never changed, a port one of them already opens gets no second rule, and an export
carries only your own rules.

**Common port** fills the form for the ports owners open most — web on 8080 or
8443, an app on 3000, FTP, the mail ports, a DNS server, WireGuard and OpenVPN —
with the port, the protocol and a note. It changes nothing by itself: press
**Add rule**, then **Keep**, as for a rule you typed.

### Addresses

- **Block on every port** — that address or range gets nothing from this
  server, **even while the firewall is off**. These are also the **Blocked for
  good** list on **Security → Brute-force protection**.
- **Allow to every port** — that address may reach every port.

The panel refuses to block the address you are using, any address you are
signed in from, this server's own addresses, and special ranges (loopback,
link-local, multicast). A range can be no wider than a `/8` (IPv4) or a
`/16` (IPv6).

### Block ping

Stops the server answering `ping`. An uptime monitor that uses ping will report
the server down — the websites are unaffected.

### What listens on this server

Every port a program waits on, with what it is and whether the internet can
reach it with the rules in force: **Always open**, **Reachable**, **Only the
addresses in a rule**, **Closed by the firewall**, **Only from this server**.
Under it, **Suggested rules**: programs the firewall would close, each with an **Allow** button
(the ports of SixPanel's own Email and FTP server are not among them: SixPanel opens those itself).

**Docker.** A port a container publishes is forwarded by Docker's own rules,
which this firewall does not see: it stays reachable whatever the tab says, and
the row says **Docker — not filtered here**. Publish it on `127.0.0.1` when it
must not be public.

**ufw or firewalld.** If one of them is switched on too, both firewalls apply:
a port has to be open in both to answer. The tab says so.

### Import and export

**Download the rules** saves them as a JSON file. **Import a file…** reads one
from another SixPanel server: every rule is checked as if you typed it, then you
choose **Replace my rules** or **Add to my rules**, and it goes through Keep like
any other change.

### It stays as you kept it

The kept rules are loaded at boot (`/etc/sixpanel/firewall/rules.nft`,
`sixpanel-firewall.service`). Every five minutes, and when the panel starts, the
panel checks that the rules in force are the kept ones and puts them back if
something removed them. When the SSH port changes (below), the new port is open
at once.

## Allow traffic from Cloudflare only

On **Server → Firewall** and on **Security → Access**:

> **Allow traffic from Cloudflare only**
> (The name servers must point to Cloudflare, and the proxy needs to be enabled
> for your DNS records.)

While it is on, this server answers only connections that came through
Cloudflare — anyone who finds the server's own address and types your domain
into their request gets nothing. The server's own checks and its certificate
renewals still get through.

It is the same switch as **Allow traffic from Cloudflare only** on the
**[Cloudflare](https://www.allsweb.com/sixpanel/docs/cloudflare)** page — one switch, one name: changing it in one place changes both.
The panel will not switch it on until every address this server serves is
proved to go through Cloudflare, and the switch says which address stops it —
the webmail and mail-app settings names of a **SixPanel Email** domain included,
since the webmail answers behind the same switch. Mail itself (ports 25, 465, 587,
993 and 995) and the mail host never go through Cloudflare, and the switch does not
touch them.
Before you turn it on, think of anything that reaches this server by its bare
address — an uptime monitor, a payment provider's callback someone pasted with
the IP in it. Those stop working too.

Locked out? Over SSH: `sudo sixpanel origin-lock off`.

## Rules that live elsewhere

The last card on **Server → Firewall → This server's firewall** counts the other places that decide who
reaches this server, with a link to each:

| Rule | Where it is managed |
|---|---|
| Allow traffic from Cloudflare only | the switch above |
| Who may try to sign in to the panel | **Security → Access** (login allowlist) |
| Addresses blocked from the panel | **Security → Access** |
| Addresses locked out after failed sign-ins | **Security → Access** |
| Addresses banned by brute-force protection | **Security → Brute-force protection** |
| Cloudflare's own security rules | the **Cloudflare** page |
| Your hosting provider's firewall | your provider — its rules are on the **Your hosting provider's firewall** tab |

## Check that the internet can reach a port

Some server providers keep ports closed in a firewall of their own, in front of the
server — an AWS security group, Google Cloud's VPC firewall, a Hetzner or DigitalOcean
cloud firewall. The panel cannot see that firewall from inside: to the server, a port that
listens and a port nobody can reach look exactly alike. The **Can the internet reach this
server?** card on **Server → Firewall** finds out when you press **Check reachability**:

- **From the internet.** AllsWeb (allsweb.com) tries each port from outside — one
  connection per port, nothing sent. It tries **only this server's own address**, and only
  when the request came from that address: nothing on the page or in the request can name
  another one. It tries the ports SixPanel opens for its own services: 80, 443, the panel's
  port, the SSH port, the mail ports (25, 465, 587, 993, 995, and the alternate ports for mail
  apps that the email server has on) and the FTP ports (21, 2222 and one port of 40000–40100)
  while those are installed or something listens on them.
- **Out of this server.** A connection to servers that always answer on port 25 (sending
  mail straight to other mail servers), 465 and 587 (sending through a mail service) and 443 —
  and, with the email server installed, 2525, the port relay services take for a network that
  blocks 587 as well.

Each port then gets one verdict:

| Verdict | What it means | What to do |
|---|---|---|
| **Open** | reachable from the internet | nothing |
| **Nothing listens** | it reaches the server, but no program answers on it | start the service — or nothing is wrong |
| **Only this server** | a program listens on 127.0.0.1 only | normal for databases and caches |
| **Refused** | a program listens, but the connection from outside was turned away | another firewall on the server, or the program's own settings |
| **Blocked by this server's firewall** | SixPanel's own firewall closes it | allow the port in **Port rules** above |
| **Some addresses only** | SixPanel's own firewall lets it in only from the addresses a rule names | nothing, if you meant it; otherwise allow it from everywhere in **Port rules** |
| **Blocked before it arrives** | dropped on the way, and ufw or firewalld also runs on the server | `sudo ufw status` (or `sudo firewall-cmd --list-all`); if it lets the port in, it is the provider |
| **Blocked by your server provider** | dropped before it reaches the server | open the port in the provider's firewall (their cloud console), or ask their support |
| **Not checked from outside** | the outside check did not run (below) | what the server itself knows is shown |
| **Domain only** | the panel's own port, while the panel answers at its domain only (**Security → Access**) | nothing — it is reached through port 443 |
| **DNS not answering** | going out: this server could not look up the server it tried | check the server's DNS resolver |

A verdict you can fix carries a link to the tab that fixes it: **Blocked by this server's
firewall** and **Some addresses only** open **This server's firewall**, and **Blocked by your
server provider** and **Blocked before it arrives** open **Your hosting provider's firewall**.

SSH that reads **Blocked by your server provider** can be right: many owners allow SSH at the
provider from their own address only, and the card says so.

When the provider blocks a port, the card names the provider this server runs at when the
panel recognises it — AWS, Google Cloud, Azure, DigitalOcean, Hetzner, Akamai (Linode),
Vultr, Oracle Cloud, Contabo, OVHcloud, Alibaba Cloud, Scaleway — and says where a port is
opened there; for any other provider it says where to look. It also gives that provider's
rule for sending mail on port 25: Google Cloud never opens it, AWS opens it when you ask,
several others only on request for new accounts — a relay (**Email → Settings**) sends mail
either way.

The same card is on the **Email** page (the mail ports, and port 25 going out) and on a
website's **SSH/FTP** page (the FTP, SFTP and passive ports). After a check on the Firewall
tab, the **What listens on this server** table gets a last column, **Checked from outside**.

**When the check runs.** When you press **Check reachability** or **Check again**, or when you ask
Tia. The panel also checks by itself: a few minutes after the email or FTP server is installed or
the firewall is turned on or off, and once a day, never two of its own checks within ten minutes. Each answer is kept
with its time: a card shows the last one when it opens, and **Server → Health** reads it, so
opening Health never asks AllsWeb. An answer from before the firewall last changed is not shown as
the state now: the card says *Checked before this server's firewall changed*, the ports the
change moved show what the firewall lets in now (not tried from outside since), and the panel
checks again by itself about half a minute later. AllsWeb runs at most ten checks for one server in ten
minutes. The first check you press connects the panel to AllsWeb if it never was, as every
AllsWeb feature does — no AllsWeb account is needed; the panel's own checks wait for that.

### On Server → Health

The row **Ports SixPanel needs** lists what this server needs reachable, from what is installed:
80 and 443, the panel's port (unless the panel answers at its own domain only) and the SSH
port; with the email server every port it answers on and port 25 going out (or, with a relay,
the relay's port); with the FTP server its FTP, SFTP and passive ports; and 443 going out. Each
port that is blocked or closed says what to do — allow it on **Server → Firewall**, or open it
in your server provider's firewall, with where that is at the provider this server runs at —
and the row says when it was checked. Port 25 coming in is red: no mail can arrive without it.
**Take me there** opens the Firewall tab, where **Check reachability** checks again.

**When nothing is tried from outside**, the card says why, and shows what the server knows:

- AllsWeb could not be reached from the server just now;
- an older allsweb.com does not offer the check yet;
- the server reaches the internet through a different address than its own (AllsWeb tries
  only the address a request comes from, so it cannot check this one);
- AllsWeb cannot try that port itself. AllsWeb runs on a network that blocks outgoing port
  25, so inbound port 25 can read **Not checked from outside** — never a wrong "blocked".

## SSH

**Security → SSH** shows the SSH server — running or stopped, its version,
whether systemd starts it on the first connection (`ssh.socket`) or keeps it
running (`ssh.service`), and the ports it listens on. Turning SSH off for the
whole server is on **Server → Terminal** (**[Terminal and
SSH](https://www.allsweb.com/sixpanel/docs/terminal-and-ssh)**).

### Who may sign in

- **Password login** — off is safer: only a key can sign in, and guessing
  passwords gets nobody anywhere.
- **Key login** — keep it on: it is how you get in when password login is off.
- **Root login** — **No**, **With a key only**, or **With a key or a password**.

The panel writes these to a file of its own,
`/etc/ssh/sshd_config.d/05-sixpanel-server.conf`, which SSH reads before the
system's own files (SSH keeps the first value it reads). It checks the result
with `sshd -t`, asks SSH which values are now in force, and only then reloads
it. If another file still wins, the change is put back and the message names
that file. Connections that are open stay open.

The panel refuses, and says why:

- password login off while no account that can run `sudo` (or root) has a key
  this server accepts, and nobody signed in with a key in the last 30 days;
- password and key login both off;
- key login off while no such account has a password;
- root login off while root is the only account that can sign in.

Turning password login or root password login **on** asks you to confirm it is
you, the way turning SSH on does.

### Move SSH to another port

Two steps, so a port your provider's firewall blocks can never strand you:

1. Type the new port and press **Add this port**. SSH now listens on the old
   port **and** the new one; this server's own firewall opens the new one by
   itself. Open it at your hosting provider's firewall too.
2. From your computer, connect to the new port (`ssh -p <port> you@server`) and
   keep that window open. Press **Check again** — the card says it sees your
   connection — then **Finish — close the old port**. The panel refuses to
   finish without a live connection to the new port from another machine. A
   connection the server makes to itself — `ssh -p <port>` typed in the panel's
   Terminal — does not count: it never passed your provider's firewall.

**Cancel the move** goes back to the old port alone. Moving the port hides SSH
from the laziest scanners and nothing more; keys and brute-force protection are
what keep it safe, so the security score does not ask for it.

### Sign-ins

Counted from the system journal: sign-ins and failed attempts **today**,
**yesterday** and over the **last 7 days**, the last sign-ins (who, from where,
with a key or a password) and the addresses that failed most — each with a
**Block** button that blocks it on this server's own firewall (through Keep).

### Email on every SSH sign-in

Turn it on and every SSH sign-in sends an email: the account, the address and
how. At most one per account and address every six hours, and twelve an hour.
It needs email alerts set up on **Settings → Alerts**.

## Brute-force protection

fail2ban watches the logs for addresses that keep failing to sign in and bans
them for a while. **Security → Brute-force protection** shows:

- **Jails** — each service fail2ban watches (SSH, and the ones other parts of
  the panel add), with its failures before a ban, the window they are counted
  in, the ban's length and how many are banned now. **Change** sets those three
  in minutes, or switches a jail off; **Back to the defaults** drops your
  settings. The panel writes them to
  `/etc/fail2ban/jail.d/zz-sixpanel-owner.local`, checks the result with
  `fail2ban-client -t`, and reloads fail2ban — the bans it holds stay.
- **Banned now** — every banned address, since when and until when. **Let in**
  lifts the ban; **Block for good** blocks it on this server's own firewall.
- **Never ban** — addresses fail2ban never bans, however often they fail.
  **Add my address** adds the one you are using. A single address added here
  that is banned right now is let in at once.
- **Blocked for good** — the addresses blocked on this server's own firewall;
  adding or removing one goes through Keep.
- **What it did** — bans and lifted bans from fail2ban's own log, newest first.

When fail2ban is installed but stopped, the tab offers **Start fail2ban**.

## Security score

**Security → Security score** asks the server, when the tab opens: two-step
sign-in for the panel, the panel's own address with HTTPS and its IP address
closed, SSH with keys only, no password sign-in for root, brute-force protection
running for SSH, this server's own firewall, Cloudflare-only traffic, automatic
security updates, a restart waiting, email for alerts, the SSH sign-in email, and
PHP mail() and sendmail off on every website.

That last line names every website and 6amMart project whose PHP `mail()` and
`sendmail` are still on — after an update from an earlier SixPanel, every one that
was there, so that nothing that sent mail stopped — each with **Turn off** and a
link to the page its switch is on. While one is on, any code on it can send mail
as anyone from this server ([Email → PHP mail() and sendmail](https://www.allsweb.com/sixpanel/docs/email#php-mail-and-sendmail)).

**Brute-force protection for FTP and email** asks the same of the other services
that take a password from the internet: when the FTP server is installed its
`proftpd` jail, and when SixPanel Email is installed its `postfix-sasl` and
`dovecot` jails, must be running. Each one that is not is named — **Turn on** when
you switched it off, a link to Brute-force protection when fail2ban simply does not
run it. The line does not apply while neither is installed.

Each line is **Done**, **To do** or **Does not apply** — a line that does not
apply here (Cloudflare-only traffic on a server not behind Cloudflare) is left
out of the score. **Fix** does it in one press through the same route as the
tab it belongs to, with that tab's own refusals; **Open** goes to the page where
the decision is yours.

## What Tia can do here

Tia, the panel's assistant, can read all of it. She can propose a firewall or
fail2ban change — you approve each one, and a firewall change is then waiting
for **your** Keep on **Server → Firewall**; she cannot keep it. She never
changes who may sign in over SSH. She can run the reachability check and tell you
which port your server provider blocks and where to open it there — opening it at the
provider is yours, in their console.

## How to check it worked

- `sudo nft list table inet sixpanel_fw` prints the rules in force (with the
  firewall off and nothing blocked there is no such table).
- `sudo sshd -T | grep -E '^(port|passwordauthentication|pubkeyauthentication|permitrootlogin) '`
  prints the SSH values in force.
- `sudo fail2ban-client status sshd` prints the SSH jail's bans.
- The **Activity** page has a line for each change, Keep and undo.

## If it went wrong

- **A firewall change cut you off** — wait a minute: nobody pressed Keep, so the
  server puts the previous rules back by itself.
- **Your own address is blocked** (it landed inside a range you blocked) — from
  your provider's console, `sudo sixpanel server firewall off`. It switches the
  server's own firewall off, answers ping again and takes every blocked address
  off (the activity log names them, so you can put them back). It works with the
  panel up or down.
- **The website cannot be reached on the server's address after "Allow traffic
  from Cloudflare only"** — that is the switch working. To lift it without the
  panel: `sudo sixpanel origin-lock off`.
- **"The SSH server refused the new settings"** — the panel put the previous
  file back; the message carries what `sshd -t` said.
- **A Keep says "too late"** — the minute had passed and the previous rules are
  back. Make the change again and press Keep within the minute.
