Notifications
easywall can tell you that something happened instead of waiting for you to open the dashboard. Notifications in the sidebar holds the whole setting: one destination, four triggers, one Save button.
Set a destination
| Send to | Address |
|---|---|
| Nothing | Notifications are off. This is the default |
| Webhook | Any HTTP endpoint that accepts a POST with a JSON body |
| ntfy | A topic URL, for example https://ntfy.sh/your-private-topic |
Only http:// and https:// are accepted. Nothing else is a web endpoint, and the
address is refused before it reaches the configuration file.
The address is a credential. Anyone who has it can post to your topic, and on a public ntfy server anyone who guesses it can read yours. Pick a topic name nobody will guess, or run your own.
Choose what you hear about
| Trigger | Sent when | Carries |
|---|---|---|
| An apply undid itself | the window closed unconfirmed, or you ended it by hand | which of the two it was |
| An apply was confirmed | you confirmed inside the window and the rules are live | the event, nothing more |
| Panic mode started or ended | on either edge, including easywall-core panic at the console |
which edge, in words |
| Repeated failed sign-ins | five failures from one address inside five minutes | the count and the address |
Nothing is sent for a trigger you leave unticked. The four take effect when you press Save notifications, not while you are ticking them.
The three the firewall raises
easywall reads its own status every 15 seconds. That is one socket round trip to the daemon on this host, and nothing to the network. The tick is longer than the status cache holds, so each one is a real ask rather than a free read. Confirmed and rolled back are states that stay, not instants that pass. A read landing after the 120-second window closed still finds the outcome, so nothing races that window.
A rollback carries the reason it happened, and the two reasons are not flattened into one: a window that expired is not a window an operator ended.
The one about sign-ins
Five is not a number chosen here: it is the rate limiter’s own ceiling, so the message is worth the same as easywall refusing that address. The same count, not the same moment: the limiter is a token bucket that refills, and this is a fixed five-minute window. Five failures spread over four minutes notify while the limiter still has tokens. The address then stays quiet for fifteen minutes, because the second hour of one attack is not news. Every other address keeps its own count.
Prove it arrives
Send a test posts one notification now, to the address in the field, whatever the four switches say. A test that stayed silent because a trigger is off would prove nothing about the endpoint. Under the triggers the page then shows when easywall last sent something, or what went wrong the last time it tried.
The public demo sends nothing, and says so before you press the button. It does not keep the settings either — the form works and the change is not written.
What arrives
A webhook
POST, with a JSON body:
{
"event": "rolled_back",
"severity": "warning",
"detail": "timeout",
"host": "gateway",
"version": "2.20.0",
"time": "2026-09-15T14:25:43Z"
}
severity is one of info, warning or critical, and time is UTC. event
has five values, one per row:
event |
Raised by |
|---|---|
test |
Send a test — the first one your receiver will ever see, and the one it gets with every switch off |
rolled_back |
the acceptance window closed unconfirmed, or you ended it |
accepted |
you confirmed inside the window |
panic |
panic mode, on either edge |
failed_logins |
the sign-in threshold |
A receiver written as a four-way switch over the triggers drops test, which is
the message the button exists to produce.
ntfy
POST, text/plain. The body is the detail above; the rest travels in headers:
| Header | Value |
|---|---|
Title |
this host’s name, then the event |
Priority |
3 for info, 4 for warning, 5 for critical |
Tags |
the event name |
ntfy has five priorities and easywall uses three. Nothing it has to say is worth ntfy’s lowest, and the highest is kept for the event that means this host is not filtering.
What is not promised
There is no queue and no delivery guarantee. A delivery that fails is tried once more and then dropped, with a line in the journal saying so. If the host has no route out when the rollback happens, that notification is gone.
The audit log is the record; a notification is a convenience. Reading it as a second record is the one way this feature can mislead you. So the page says what it last managed to send, rather than implying every attempt landed.
Redirects are refused. A destination that answers with one is never followed. Otherwise whoever controls its DNS could point your notifications at somebody else.
Of the five requests easywall makes, this and an own feed are the two whose destination it does not name. All five are listed under Security.