Available from 0.9.22. Earlier releases record refused logins among ordinary traffic in the main
logs, with no separate file to watch.
What gets recorded
One line per refusal, in a file that holds nothing else.
The gateway’s file looks like this, and is meant to be read by hand as well as by fail2ban:
grep ip=203.0.113.9 auth-failed.log answers the obvious question with no tooling. SMPP and gRPC
lines also name the listener and the port the attempt arrived on, so you can see which port is being
worked:
What deliberately is not recorded
This is the more important half, and it is what makes the feature safe to switch on. Only failures to prove identity go in. Everything that happens after a credential has been accepted stays out, however much it looks like a refusal — because the caller is an authenticated customer, and blocking them cuts off their working logins too.A sender ID or template that is not approved
A sender ID or template that is not approved
The API answers
403 for this, and it answers 403 for a wrong password as well. A jail reading the
HTTP access log could not tell them apart, and would block a paying customer whose registration is
still pending. That is the whole reason refused logins have a file of their own.A product that is not sold, on a bind
A product that is not sold, on a bind
The credential was good; the product is a typo or a catalogue that has not caught up. The bind is
refused, and nothing is recorded for blocking.
The per-IP and per-account connection limits
The per-IP and per-account connection limits
Capacity, not an attack. A customer whose client reconnects harder than the limit allows is not
guessing anything. Those refusals are counted on the metrics endpoint instead — see
Prometheus and Grafana.
An expired gRPC session
An expired gRPC session
gRPC sessions live in the gateway’s memory, so a restart — or a customer’s channel moving to another
node — expires every one of them, and each customer’s next call is refused once with
reason=sessionExpired before it logs in again. That reason never bans. Counting it would ban
every reconnecting customer after every restart, on every port. It is still written, so the Security
page shows it. A gRPC call with no token at all is missingCredential, and does count.A sign-in link we could not send
A sign-in link we could not send
If your SMTP is unconfigured, or the panel’s base URL is unset, a customer’s sign-in link fails to
send. That is your fault, not theirs. Blocking them for it would cut a customer off because your
mailer broke, and they would never learn why.
Fill in the never-ban list first
Before you enable a single jail. A ban is on an address, and an address usually carries a whole customer — so one wrong password in their configuration takes their working logins down with it.# comments, IPv4 and IPv6 both. What belongs in it:
- your monitoring and uptime probes, which authenticate on a loop and will eventually get one wrong
- your own office and VPN, so a mistyped password cannot lock you out of the panel you would fix it from
- any customer whose traffic you cannot afford to interrupt while the numbers are still being tuned
ignoreip line in the jail:
No installer ever rewrites it. The jail file is rewritten on every upgrade, so an address added
there disappears silently and the first you hear of it is a banned customer.
Changes apply on the next attempt. No reload, no restart, no service interruption — which is
exactly what you want, because you edit this file at the moment somebody is being blocked and you
need it to stop now.
An ignored address is still recorded. This stops the ban, not the log line, so a trusted address
that starts failing to sign in still appears on the Security page. That is deliberate: it is how a
compromised trusted host stays visible instead of becoming the one place nobody looks.
Turning it on
On a gateway that is already installed — which is most of them:update also refreshes an installed filter.d/fireflo-gateway.conf when the release’s
differs — the 0.15.9 filter is the one that ignores sessionExpired — and reloads fail2ban. It never
installs a filter where fail2ban was not set up.
What it writes:
The panel jail is written only when a control panel is actually installed on the host. A jail
whose log path matches nothing starts, reports itself as running, and protects nothing — so an
absent panel is said out loud instead.
The two settings that matter
maxretry on the gateway jail is deliberately generous. A misconfigured ESME retries a bad bind
in a tight loop, so a value tuned for SSH would ban a customer with a typo within seconds. The panel
jail is tighter — a person typing a password does not get five wrong, and nothing there retries
automatically.
Bans cover every port, not just the listener’s — that is deliberate, on the grounds that
somebody working through SMPP passwords has no business anywhere on the host. It also means a false
positive costs that address everything, which is why the never-ban list above is not optional and
why a reboot releases them.
Seeing who was refused, and who is blocked
Security, under Gateway in the control panel. All three surfaces in one list — because the same actor moves between them, and an address working through system IDs is often the one trying the panel afterwards — with filters, a window, and refusals-per-hour so a burst reads as a shape rather than as rows. The blocked list is asked of fail2ban directly rather than reconstructed, so it cannot drift from what is actually dropping traffic. The recorded bans and releases are still kept, because they are the only record of an address that was blocked and has since been let go. On the host:A reboot releases FireFlo’s bans
fail2ban keeps its bans in a database and restores every unexpired one when it restarts, so without this a reboot would bring back an address banned ten minutes earlier. Since a ban covers every port — including SSH — that would make a reboot useless as an escape from a lockout, which is the one thing a reboot is for. So--with-fail2ban also installs a small unit that runs after fail2ban at boot and releases
FireFlo’s jails. Only FireFlo’s: your sshd, postfix and other jails keep their bans, because
clearing those is not this installer’s business.
The cost is that an attacker mid-ban is also released by a reboot. With a one-hour ban and reboots
being rare, that is a small window, and they are banned again on their next attempt — whereas an
operator locked out of their own host by a whole-port ban has no other lever.
Forcing a disconnect, and holding a client out
Fail2ban answers repeated failed logins. When a client is logged in and misbehaving, use Force disconnect instead — on a server’s page, on a login’s live-sessions box under the account’s Logins tab, or on Security:- Choose the target: an IP address, an account, or a login. It’s matched exactly, never by prefix,
so
acmenever touchesacme2. A preview lists the sessions that would be dropped before anything happens. - Choose what happens next:
- Allow them to reconnect: the sessions are dropped, and a client with a reconnect loop is back within seconds.
- Keep them out for 15 minutes, 1 hour, 24 hours or until lifted: new SMPP binds from that target are refused on every node while the hold lasts.
- Lifting: active holds are listed on Security → Held out, with who made them and why. Lift ends a hold at once on the node you’re on, and on the others within ten seconds.
reason=heldOut, which the fail2ban filter
ignores — the hold is already the response, and a host-wide ban on top would outlast it. Holds are
kept in the database (from 0.12.8); without one they last until the gateway restarts.
Disabling a login still stops it binding for good, and now drops its live sessions in one step.
Releasing an address
From the Security page, if the panel was given the grant at install time, or on the host:--with-fail2ban was never passed — the
button is absent and the page prints the host command instead.
Check it before you trust it
A filter that matches nothing and a filter that is working look identical once enabled. Both report the jail as running.403, and
confirm nothing was banned. Without that second check, “it blocks attackers” and “it blocks
customers” are the same test.
Related
Tokens and access
The management port’s two secrets, and why they differ.
Binds and listeners
When a customer cannot bind and nothing is blocking them.