Firewall (CSF)¶
ConfigServer Security & Firewall management: allow/deny lists, temporary blocks, profiles, country blocks.
All endpoints below are mounted under /api. Authentication: Authorization: Bearer <token> unless noted as public.
Endpoint count: 32
Endpoints¶
| Method | Path | Handler | Guards |
|---|---|---|---|
POST |
/api/firewall/allow |
firewallAllow |
RequirePermission(db, "firewall_management") |
DELETE |
/api/firewall/allow/*ip |
firewallRemoveAllow |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/cloudflare |
cloudflareStatus |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/cloudflare |
cloudflareOnly |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/countries |
firewallCountries |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/countries/block |
firewallCountryBlock |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/countries/list |
firewallCountryList |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/deny |
firewallDeny |
RequirePermission(db, "firewall_management") |
DELETE |
/api/firewall/deny/*ip |
firewallRemoveDeny |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/disable |
firewallDisable |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/enable |
firewallEnable |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/export |
firewallExport |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/geoip |
firewallGeoIP |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/import |
firewallImport |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/ipinfo |
firewallIPInfo |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/logs |
firewallLogs |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/port/close |
firewallClosePort |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/port/open |
firewallOpenPort |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/portinfo |
firewallPortInfo |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/ports |
firewallPorts |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/restart |
firewallRestart |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/rules |
firewallRules |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/settings |
firewallGetSettings |
RequirePermission(db, "firewall_management") |
PATCH |
/api/firewall/settings |
firewallUpdateSettings |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/settings |
firewallUpdateSetting |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/status |
firewallStatus |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/superaccess |
firewallSuperAccess |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/superaccess |
firewallAddSuperAccess |
RequirePermission(db, "firewall_management") |
DELETE |
/api/firewall/superaccess/:ip |
firewallRemoveSuperAccess |
RequirePermission(db, "firewall_management") |
GET |
/api/firewall/temp |
firewallTempList |
RequirePermission(db, "firewall_management") |
DELETE |
/api/firewall/temp/:ip |
firewallRemoveTemp |
RequirePermission(db, "firewall_management") |
POST |
/api/firewall/tempdeny |
firewallTempDeny |
RequirePermission(db, "firewall_management") |
Source¶
Handlers for this section live in api/routes/handlers_*.go in the StarkOne source. Each handler binds its request body with gin.ShouldBindJSON(&req) and responds with the standard envelope:
On error:
Reference¶
POST /api/firewall/allow¶
Adds an IP address to the CSF allow list (csf.allow) with an optional comment.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
ip |
string | yes | IP address (or CIDR) to allow. |
comment |
string | no | Free-text note stored alongside the rule. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (e.g. missing ip). |
400 |
firewall_error |
CSF rejected the allow operation. |
Side effects
- Calls
firewall.Allow(ip, comment), which writes the IP into the CSF allow list and reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/allow \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ip": "203.0.113.10", "comment": "office"}'
DELETE /api/firewall/allow/*ip¶
Removes an IP address from the CSF allow list.
Guards: RequirePermission(db, "firewall_management")
Path parameters
| Name | Type | Description |
|---|---|---|
ip |
string | The IP to remove. Captured as a wildcard (*ip); the handler strips the leading /. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
firewall_error |
CSF rejected the removal. |
Side effects
- Calls
firewall.RemoveAllow(ip), which deletes the matching entry from the CSF allow list and reloads CSF.
Example
curl -X DELETE https://panel.example.com:2087/api/firewall/allow/203.0.113.10 \
-H "Authorization: Bearer $TOKEN"
GET /api/firewall/cloudflare¶
Returns whether Cloudflare-only mode (restricting ports 80/443 to Cloudflare IP ranges) is enabled.
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
Example
POST /api/firewall/cloudflare¶
Enables or disables Cloudflare-only mode for HTTP/HTTPS ports.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
enabled |
boolean | yes | true enables Cloudflare-only mode, false disables it. Note: the field carries binding:"required", so a literal false value fails binding validation. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding. |
500 |
firewall_error |
Enabling/disabling Cloudflare-only mode failed. |
Side effects
- Calls
firewall.EnableCloudflareOnly()orfirewall.DisableCloudflareOnly(), which adjust CSF rules for ports 80/443 and reload CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/cloudflare \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
GET /api/firewall/countries¶
Returns the firewall's country-block configuration as provided by firewall.GetCountries().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The exact shape is determined by firewall.GetCountries(); it is returned verbatim inside data.
Example
POST /api/firewall/countries/block¶
Adds or removes a list of countries from the CSF CC_DENY country-block list.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
countries |
array of string | yes | ISO country codes to block or unblock. |
deny |
boolean | no | true to add the countries to CC_DENY, false to remove them. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (e.g. missing countries). |
500 |
firewall_error |
Updating the country-deny list failed. |
Side effects
- Calls
firewall.SetCountryDeny(countries, deny), which edits CSFCC_DENYconfiguration and reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/countries/block \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"countries": ["CN", "RU"], "deny": true}'
GET /api/firewall/countries/list¶
Returns all countries with their current block status as provided by firewall.GetCountryList().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The exact shape is determined by firewall.GetCountryList(); it is returned verbatim inside data.
Example
POST /api/firewall/deny¶
Adds an IP address to the CSF deny list (csf.deny) with an optional comment.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
ip |
string | yes | IP address (or CIDR) to deny. |
comment |
string | no | Free-text note stored alongside the rule. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (e.g. missing ip). |
400 |
firewall_error |
CSF rejected the deny operation. |
Side effects
- Calls
firewall.Deny(ip, comment), which writes the IP into the CSF deny list and reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/deny \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ip": "203.0.113.20", "comment": "abuse"}'
DELETE /api/firewall/deny/*ip¶
Removes an IP address from the CSF deny list.
Guards: RequirePermission(db, "firewall_management")
Path parameters
| Name | Type | Description |
|---|---|---|
ip |
string | The IP to remove. Captured as a wildcard (*ip); the handler strips the leading /. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
firewall_error |
CSF rejected the removal. |
Side effects
- Calls
firewall.RemoveDeny(ip), which deletes the matching entry from the CSF deny list and reloads CSF.
Example
curl -X DELETE https://panel.example.com:2087/api/firewall/deny/203.0.113.20 \
-H "Authorization: Bearer $TOKEN"
POST /api/firewall/disable¶
Disables the CSF firewall.
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
firewall_error |
Disabling CSF failed. |
Side effects
- Calls
firewall.Disable(), which disables CSF (equivalent tocsf -x).
Example
curl -X POST https://panel.example.com:2087/api/firewall/disable \
-H "Authorization: Bearer $TOKEN"
POST /api/firewall/enable¶
Enables the CSF firewall.
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
firewall_error |
Enabling CSF failed. |
Side effects
- Calls
firewall.Enable(), which enables CSF (equivalent tocsf -e).
Example
POST /api/firewall/export¶
Reads a fixed set of CSF configuration files from /etc/csf/ and returns their contents keyed by filename. Despite the POST method, no request body is read.
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
data is a map of filename to file contents. Only files that exist and are readable are included. The candidate files are: csf.conf, csf.allow, csf.deny, csf.ignore, csf.pignore, csf.blocklists, csf.dyndns, csf.fignore, csf.rignore, csf.signore, csf.suignore, csf.mignore, csf.logfiles, csf.syslogfiles, csf.uidignore, csf.dirwatch, csfpre.sh, csfpost.sh.
Side effects
- Reads files under
/etc/csf/. No writes.
Example
GET /api/firewall/geoip¶
Proxies ip-api.com to perform a GeoIP lookup for the supplied IP and streams the upstream JSON back to the caller.
Guards: RequirePermission(db, "firewall_management")
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
ip |
string | no | The IPv4 or IPv6 address to look up. |
Response - 200 OK
The upstream ip-api.com JSON is streamed through unchanged (the upstream status code is proxied; the content type is always set to application/json). It contains fields country, countryCode, city, isp, org, proxy, hosting. This response is NOT wrapped in the data envelope.
{ "country": "United States", "countryCode": "US", "city": "Ashburn", "isp": "Example ISP", "org": "Example Org", "proxy": false, "hosting": true }
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
ip query param missing. |
502 |
lookup_failed |
The request to ip-api.com failed. |
Side effects
- Makes an outbound HTTP request to
http://ip-api.com/json/<ip>(5s timeout).
Example
curl "https://panel.example.com:2087/api/firewall/geoip?ip=203.0.113.30" \
-H "Authorization: Bearer $TOKEN"
POST /api/firewall/import¶
Imports CSF configuration files: disables CSF, writes the supplied known CSF files into /etc/csf/, re-enables and restarts CSF.
Guards: RequirePermission(db, "firewall_management")
Request body
The body is a JSON object mapping filename to file contents. It may be wrapped in a data key, or be a flat map at the top level (both accepted).
| Field | Type | Required | Description |
|---|---|---|---|
data |
object | no | Map of filename to contents. If absent, the top-level object is used as the map directly. |
Only filenames starting with csf. plus csfpre.sh and csfpost.sh are written; entries with empty/non-string values are skipped.
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding. |
Side effects
- Runs
csf -x(disable), writes accepted files to/etc/csf/<filename>(mode 0644),chmod +xoncsfpre.shandcsfpost.sh, thencsf -e(enable) andcsf -r(restart).
Example
curl -X POST https://panel.example.com:2087/api/firewall/import \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"data": {"csf.allow": "203.0.113.10\n"}}'
GET /api/firewall/ipinfo¶
Returns detailed information about an IP as provided by firewall.GetIPInfo().
Guards: RequirePermission(db, "firewall_management")
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
ip |
string | no | The IP address to inspect. |
Response - 200 OK
The exact shape is determined by firewall.GetIPInfo(ip); it is returned verbatim inside data.
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
ip query param missing. |
Example
curl "https://panel.example.com:2087/api/firewall/ipinfo?ip=203.0.113.30" \
-H "Authorization: Bearer $TOKEN"
GET /api/firewall/logs¶
Returns recent firewall attack logs, newest first, limited by the limit query parameter.
Guards: RequirePermission(db, "firewall_management")
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
limit |
integer | yes | Max number of log entries. Defaults to 100; values outside 1-1000 are coerced back to 100. |
Response - 200 OK
data is an array of firewall.AttackLog entries (empty array when there are none).
Example
curl "https://panel.example.com:2087/api/firewall/logs?limit=50" \
-H "Authorization: Bearer $TOKEN"
POST /api/firewall/port/close¶
Closes a single port for a given protocol and direction in the firewall.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
port |
integer | yes | Port number, 1-65535. |
protocol |
string | yes | tcp or udp. |
direction |
string | yes | in or out. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (e.g. invalid port, protocol, or direction). |
500 |
firewall_error |
Closing the port failed. |
Side effects
- Calls
firewall.ClosePort(port, protocol, direction), which edits CSF port configuration and reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/port/close \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"port": 8080, "protocol": "tcp", "direction": "in"}'
POST /api/firewall/port/open¶
Opens a port or port range for a given protocol and direction in the firewall.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
port |
integer | no | Single port (legacy). Used only when port_range is empty and port > 0. |
port_range |
string | no | Port range such as "40000:40100". Takes precedence over port. |
protocol |
string | yes | tcp or udp. |
direction |
string | yes | in or out. |
At least one of port or port_range must be provided.
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Body failed JSON binding, or neither port nor port_range supplied. |
500 |
firewall_error |
Opening the port/range failed. |
Side effects
- Calls
firewall.OpenPortRange(portStr, protocol, direction), which edits CSF port configuration and reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/port/open \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"port_range": "40000:40100", "protocol": "tcp", "direction": "in"}'
GET /api/firewall/portinfo¶
Returns information about a specific port as provided by firewall.GetPortInfo().
Guards: RequirePermission(db, "firewall_management")
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
port |
integer | no | Port number, 1-65535. |
Response - 200 OK
The exact shape is determined by firewall.GetPortInfo(port); it is returned verbatim inside data.
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
port query param missing, non-numeric, or outside 1-65535. |
Example
curl "https://panel.example.com:2087/api/firewall/portinfo?port=443" \
-H "Authorization: Bearer $TOKEN"
GET /api/firewall/ports¶
Returns the list of firewall-configured ports as provided by firewall.GetPorts().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The value of ports is determined by firewall.GetPorts().
Example
POST /api/firewall/restart¶
Restarts the CSF firewall.
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
firewall_error |
Restarting CSF failed. |
Side effects
- Calls
firewall.Restart(), which restarts/reloads CSF (equivalent tocsf -r).
Example
curl -X POST https://panel.example.com:2087/api/firewall/restart \
-H "Authorization: Bearer $TOKEN"
GET /api/firewall/rules¶
Returns the current allow and deny lists.
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
allow comes from firewall.GetAllowList() and deny from firewall.GetDenyList().
Example
GET /api/firewall/settings¶
Returns the current CSF settings as provided by firewall.GetSettings().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The exact shape is determined by firewall.GetSettings(); it is returned verbatim inside data.
Example
PATCH /api/firewall/settings¶
Updates multiple CSF settings at once from a flat key/value map.
Guards: RequirePermission(db, "firewall_management")
Request body
A flat JSON object of setting key to string value.
| Field | Type | Required | Description |
|---|---|---|---|
| (any key) | string | n/a | CSF setting name mapped to its new string value. The body binds as map[string]string. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (not a string map). |
500 |
firewall_error |
Applying the settings failed. |
Side effects
- Calls
firewall.UpdateMultipleSettings(map), which writes the settings to CSF configuration and reloads CSF.
Example
curl -X PATCH https://panel.example.com:2087/api/firewall/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"TCP_IN": "20,21,22,80,443"}'
POST /api/firewall/settings¶
Updates a single CSF setting by key and value.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | yes | CSF setting name. Must be non-empty. |
value |
string | no | New value for the setting; may be an empty string. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Body failed JSON binding, or key is empty. |
400 |
firewall_error |
Applying the setting failed. |
Side effects
- Calls
firewall.UpdateSetting(key, value), which writes the setting to CSF configuration and reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/settings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"key": "TCP_IN", "value": "20,21,22,80,443"}'
GET /api/firewall/status¶
Returns the overall firewall status as provided by firewall.GetStatus().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The exact shape is determined by firewall.GetStatus(); it is returned verbatim inside data.
Example
GET /api/firewall/superaccess¶
Returns the list of super-access IPs (entries in csf.ignore) as provided by firewall.GetSuperAccessList().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The exact shape is determined by firewall.GetSuperAccessList(); it is returned verbatim inside data.
Example
POST /api/firewall/superaccess¶
Adds an IP to the super-access list (csf.ignore) with an optional comment.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
ip |
string | yes | IP address to grant super access. |
comment |
string | no | Free-text note stored alongside the entry. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (e.g. missing ip). |
500 |
firewall_error |
Adding the super-access entry failed. |
Side effects
- Calls
firewall.AddSuperAccess(ip, comment), which writes the IP intocsf.ignoreand reloads CSF.
Example
curl -X POST https://panel.example.com:2087/api/firewall/superaccess \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ip": "203.0.113.40", "comment": "admin"}'
DELETE /api/firewall/superaccess/:ip¶
Removes an IP from the super-access list (csf.ignore).
Guards: RequirePermission(db, "firewall_management")
Path parameters
| Name | Type | Description |
|---|---|---|
ip |
string | The IP to remove from super access. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
firewall_error |
Removing the super-access entry failed. |
Side effects
- Calls
firewall.RemoveSuperAccess(ip), which removes the IP fromcsf.ignoreand reloads CSF.
Example
curl -X DELETE https://panel.example.com:2087/api/firewall/superaccess/203.0.113.40 \
-H "Authorization: Bearer $TOKEN"
GET /api/firewall/temp¶
Returns the current temporary blocks as provided by firewall.GetTempList().
Guards: RequirePermission(db, "firewall_management")
Response - 200 OK
The exact shape is determined by firewall.GetTempList(); it is returned verbatim inside data.
Example
DELETE /api/firewall/temp/:ip¶
Removes a temporary block for the given IP.
Guards: RequirePermission(db, "firewall_management")
Path parameters
| Name | Type | Description |
|---|---|---|
ip |
string | The IP whose temporary block should be removed. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
firewall_error |
Removing the temporary block failed. |
Side effects
- Calls
firewall.RemoveTemp(ip), which removes the temporary block and reloads CSF.
Example
curl -X DELETE https://panel.example.com:2087/api/firewall/temp/203.0.113.50 \
-H "Authorization: Bearer $TOKEN"
POST /api/firewall/tempdeny¶
Adds a temporary deny (time-limited block) for an IP.
Guards: RequirePermission(db, "firewall_management")
Request body
| Field | Type | Required | Description |
|---|---|---|---|
ip |
string | yes | IP address to block temporarily. |
seconds |
integer | yes | Duration of the block in seconds. |
comment |
string | no | Free-text note stored alongside the block. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
bad_request |
Request body failed JSON binding (e.g. missing ip or seconds). |
400 |
firewall_error |
CSF rejected the temporary deny. |
Side effects
- Calls
firewall.TempDeny(ip, seconds, comment), which adds a temporary deny entry (equivalent tocsf -td) and reloads CSF.
Example