Change the firewall safely
In this guide a superuser changes the host firewall (ufw) from the panel. Every change is applied with a snapshot of the old rules and a rollback timer, so a change that cuts you off undoes itself.
Prerequisites
Section titled “Prerequisites”- A superuser account.
ufwon the host (GET /firewall/reportsavailable).
PANEL=https://panel.example.comH='Authorization: Bearer gsl_xxxxxxxxxxxxxxxx'J='Content-Type: application/json'How a change is applied
Section titled “How a change is applied”- The API records the change and returns it (
201). Only one change can be in progress at a time, so another request gets409. - The worker applies it through
gisila-agent firewall. The agent refuses anything that would cut off SSH or the panel:- blocking the host’s SSH ports (22 and any
Portinsshd_config), 80, 443, or the port your request came in on; - blocking a source that contains your IP;
- removing the last allow rule for one of those ports;
- turning the firewall on while a rule blocks you. Turning it on first adds allow rules for SSH, 80 and 443.
- blocking the host’s SSH ports (22 and any
- The agent saves the old rules and starts a transient systemd timer outside
the panel. The change moves to
awaiting_confirmation. - Confirm within the window (5 minutes by default,
FIREWALL_CONFIRM_MINUTES, 1 to 10). In the browser, any panel page confirms it automatically: if that request gets through, the panel is still reachable. If nobody confirms, the old rules come back.
Change statuses: queued, applying, awaiting_confirmation,
confirm_requested, revert_requested, applied, rolled_back, failed
(refused, with the reason in error).
1. Look at the current state
Section titled “1. Look at the current state”curl -s $PANEL/firewall/ -H "$H" | jq '{available, active, defaultIncoming, sshPorts, rules, open}'Each rule has an origin: panel (added here, removable here), base,
web or other. Rules from apps, databases or the shell are read-only here.
2. Add a rule
Section titled “2. Add a rule”CHANGE=$(curl -sX POST $PANEL/firewall/rules -H "$H" -H "$J" -d '{ "action": "allow", "proto": "tcp", "port": "8000:8100", "from": "198.51.100.0/24", "note": "office"}' | jq .id)| Field | Values |
|---|---|
action |
allow, deny, reject, limit |
proto |
tcp, udp, any |
port |
"22", a range "8000:8100", or empty for every port |
from |
any, an IP or a CIDR |
note |
Up to 60 characters |
3. Confirm it
Section titled “3. Confirm it”From a script, poll until the change is applied, then confirm. Only the
person who made the change can confirm it, before its confirmBy time.
until [ "$(curl -s $PANEL/firewall/changes/$CHANGE -H "$H" | jq -r .status)" = awaiting_confirmation ]; do sleep 2donecurl -sX POST $PANEL/firewall/changes/$CHANGE/confirm -H "$H"To undo it right away instead: POST /firewall/changes/{id}/revert.
4. Remove a rule
Section titled “4. Remove a rule”Send the same fields as the rule to remove. Only origin: panel rules match.
curl -sX POST $PANEL/firewall/rules/remove -H "$H" -H "$J" \ -d '{"action": "allow", "proto": "tcp", "port": "8000:8100", "from": "198.51.100.0/24"}'Confirm it the same way.
5. Turn the firewall on or off
Section titled “5. Turn the firewall on or off”curl -sX POST $PANEL/firewall/enable -H "$H"curl -sX POST $PANEL/firewall/disable -H "$H"6. Restrict 80 and 443 to a CDN
Section titled “6. Restrict 80 and 443 to a CDN”When every site is proxied through Cloudflare:
curl -sX POST $PANEL/firewall/web-sources -H "$H" -H "$J" -d '{"preset": "cloudflare"}'# or your own list:curl -sX POST $PANEL/firewall/web-sources -H "$H" -H "$J" \ -d '{"sources": "203.0.113.0/24, 2001:db8::/32"}'# open them to everyone again:curl -sX POST $PANEL/firewall/web-sources -H "$H" -H "$J" -d '{"sources": "any"}'The panel swaps its allow-from-anywhere rules for 80 and 443 for
gisila-web rules. It refuses when your own address isn’t among the
sources, or when another rule still lets everyone in on 80 or 443.
Verify it works
Section titled “Verify it works”curl -s $PANEL/firewall/pending -H "$H" # {"open": null} when nothing is in progresssudo ufw status numbered # on the hostThe panel re-reads ufw every minute. POST /firewall/refresh forces it.