406 lines
8.1 KiB
Groff
406 lines
8.1 KiB
Groff
.TH BANFORGE 5 "24 February 2026" "BanForge 1.0"
|
|
.
|
|
.SH NAME
|
|
banforge \- BanForge configuration file format
|
|
.
|
|
.SH DESCRIPTION
|
|
BanForge uses TOML configuration files stored in \fI/etc/banforge/\fR:
|
|
.RS
|
|
.IP \(bu 2
|
|
\fIconfig.toml\fR \- main daemon configuration
|
|
.IP \(bu 2
|
|
\fIrules.toml\fR \- default rules (legacy)
|
|
.IP \(bu 2
|
|
\fIrules.d/*.toml\fR \- individual rule files (recommended)
|
|
.RE
|
|
.
|
|
.SH "CONFIG.TOML FORMAT"
|
|
.PP
|
|
Main configuration file for BanForge daemon.
|
|
.PP
|
|
\fBStructure:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fB[firewall]\fR \- firewall parameters
|
|
.IP \(bu 2
|
|
\fB[[service]]\fR \- service monitoring configuration (multiple allowed)
|
|
.IP \(bu 2
|
|
\fB[metrics]\fR \- Prometheus metrics configuration (optional)
|
|
.RE
|
|
.
|
|
.SS "Firewall Section"
|
|
.PP
|
|
\fB[firewall]\fR
|
|
.PP
|
|
Defines firewall parameters. The \fBbanforge init\fR command automatically
|
|
detects your installed firewall (nftables, iptables, ufw, firewalld).
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBname\fR \- Firewall type (nftables, iptables, ufw, firewalld)
|
|
.IP \(bu 2
|
|
\fBconfig\fR \- Path to firewall configuration file
|
|
.RE
|
|
.PP
|
|
\fBExample:\fR
|
|
.RS
|
|
.nf
|
|
[firewall]
|
|
name = "nftables"
|
|
config = "/etc/nftables.conf"
|
|
.fi
|
|
.RE
|
|
.
|
|
.SS "Service Section"
|
|
.PP
|
|
\fB[[service]]\fR
|
|
.PP
|
|
Configures service monitoring. Multiple service blocks are allowed.
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBname\fR \- Service name (nginx, apache, ssh, etc.) \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBlogging\fR \- Log source type: "file" or "journald" \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBlog_path\fR \- Path to log file or journal unit name \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBenabled\fR \- Enable/disable service monitoring (true/false)
|
|
.RE
|
|
.PP
|
|
\fBExamples:\fR
|
|
.RS
|
|
.nf
|
|
# File-based logging
|
|
[[service]]
|
|
name = "nginx"
|
|
logging = "file"
|
|
log_path = "/var/log/nginx/access.log"
|
|
enabled = true
|
|
|
|
# Journald logging
|
|
[[service]]
|
|
name = "nginx"
|
|
logging = "journald"
|
|
log_path = "nginx"
|
|
enabled = false
|
|
.fi
|
|
.RE
|
|
.PP
|
|
\fBNote:\fR When using journald logging, specify the service name in \fBlog_path\fR.
|
|
.
|
|
.SS "Metrics Section"
|
|
.PP
|
|
\fB[metrics]\fR
|
|
.PP
|
|
Configures Prometheus metrics endpoint (optional).
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBenabled\fR \- Enable/disable metrics (true/false)
|
|
.IP \(bu 2
|
|
\fBport\fR \- Port for metrics endpoint
|
|
.RE
|
|
.PP
|
|
\fBExample:\fR
|
|
.RS
|
|
.nf
|
|
[metrics]
|
|
enabled = true
|
|
port = 9090
|
|
.fi
|
|
.RE
|
|
.
|
|
.SH "RULES.TOML FORMAT"
|
|
.PP
|
|
Detection rules define conditions for blocking IP addresses.
|
|
Rules are stored in \fI/etc/banforge/rules.d/\fR as individual \fI.toml\fR files.
|
|
.
|
|
.SS "Rule Section"
|
|
.PP
|
|
\fB[[rule]]\fR
|
|
.PP
|
|
Defines a single detection rule.
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBname\fR \- Rule name (used as filename) \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBservice\fR \- Service name (nginx, apache, ssh, etc.) \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBpath\fR \- Request path to match (e.g., "/admin/*", "*.php")
|
|
.IP \(bu 2
|
|
\fBstatus\fR \- HTTP status code (403, 404, 304, etc.)
|
|
.IP \(bu 2
|
|
\fBmethod\fR \- HTTP method (GET, POST, etc.)
|
|
.IP \(bu 2
|
|
\fBmax_retry\fR \- Max retries before ban (0 = ban on first request)
|
|
.IP \(bu 2
|
|
\fBban_time\fR \- Ban duration (e.g., "1m", "1h", "1d", "1M", "1y")
|
|
.RE
|
|
.PP
|
|
\fBNote:\fR At least one of \fBpath\fR, \fBstatus\fR, or \fBmethod\fR must be specified.
|
|
.PP
|
|
\fBExamples:\fR
|
|
.RS
|
|
.nf
|
|
# Ban on HTTP 304 status
|
|
[[rule]]
|
|
name = "304 http"
|
|
service = "nginx"
|
|
path = ""
|
|
status = "304"
|
|
max_retry = 3
|
|
method = ""
|
|
ban_time = "1m"
|
|
|
|
# Ban on path pattern (admin panel)
|
|
[[rule]]
|
|
name = "Admin Access"
|
|
service = "nginx"
|
|
path = "/admin/*"
|
|
status = ""
|
|
method = ""
|
|
max_retry = 2
|
|
ban_time = "2h"
|
|
|
|
# SSH brute force protection
|
|
[[rule]]
|
|
name = "SSH Bruteforce"
|
|
service = "ssh"
|
|
path = ""
|
|
status = "Failed"
|
|
method = ""
|
|
max_retry = 5
|
|
ban_time = "1h"
|
|
.fi
|
|
.RE
|
|
.
|
|
.SH "BAN TIME FORMAT"
|
|
.PP
|
|
Use the following suffixes for ban duration:
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBs\fR \- Seconds
|
|
.IP \(bu 2
|
|
\fBm\fR \- Minutes
|
|
.IP \(bu 2
|
|
\fBh\fR \- Hours
|
|
.IP \(bu 2
|
|
\fBd\fR \- Days
|
|
.IP \(bu 2
|
|
\fBM\fR \- Months (30 days)
|
|
.IP \(bu 2
|
|
\fBy\fR \- Years (365 days)
|
|
.RE
|
|
.
|
|
.SH "ACTIONS"
|
|
.PP
|
|
Rules can trigger custom actions when an IP is banned.
|
|
Multiple actions can be configured per rule.
|
|
Actions are executed after successful ban at firewall level.
|
|
.
|
|
.SS "Supported Action Types"
|
|
.PP
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBemail\fR \- Send email notification via SMTP
|
|
.IP \(bu 2
|
|
\fBwebhook\fR \- Send HTTP request to external service
|
|
.IP \(bu 2
|
|
\fBscript\fR \- Execute custom script
|
|
.RE
|
|
.
|
|
.SS "Variables"
|
|
.PP
|
|
The following variables can be used in \fBbody\fR fields:
|
|
.RS
|
|
.IP \(bu 2
|
|
\fB{ip}\fR \- Banned IP address
|
|
.IP \(bu 2
|
|
\fB{rule}\fR \- Rule name that triggered the ban
|
|
.IP \(bu 2
|
|
\fB{service}\fR \- Service name
|
|
.IP \(bu 2
|
|
\fB{ban_time}\fR \- Ban duration
|
|
.RE
|
|
.
|
|
.SS "Script Action"
|
|
.PP
|
|
Execute a custom script when an IP is banned.
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBtype\fR \- "script"
|
|
.IP \(bu 2
|
|
\fBenabled\fR \- Enable/disable action (true/false)
|
|
.IP \(bu 2
|
|
\fBinterpretator\fR \- Script interpretator (e.g., "bash", "python")
|
|
.IP \(bu 2
|
|
\fBscript\fR \- Path to script file
|
|
.RE
|
|
.PP
|
|
\fBExample:\fR
|
|
.RS
|
|
.nf
|
|
[[rule]]
|
|
name = "Notify on Ban"
|
|
service = "nginx"
|
|
status = "403"
|
|
ban_time = "1h"
|
|
|
|
[[rule.action]]
|
|
type = "script"
|
|
enabled = true
|
|
interpretator = "bash"
|
|
script = "/opt/banforge/scripts/notify.sh"
|
|
.fi
|
|
.RE
|
|
.
|
|
.SS "Webhook Action"
|
|
.PP
|
|
Send HTTP webhook when an IP is banned.
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBtype\fR \- "webhook"
|
|
.IP \(bu 2
|
|
\fBenabled\fR \- Enable/disable action (true/false)
|
|
.IP \(bu 2
|
|
\fBurl\fR \- Webhook URL \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBmethod\fR \- HTTP method (POST, GET, etc.)
|
|
.IP \(bu 2
|
|
\fBheaders\fR \- Custom headers (key-value pairs)
|
|
.IP \(bu 2
|
|
\fBbody\fR \- Request body (supports variables)
|
|
.RE
|
|
.PP
|
|
\fBExample:\fR
|
|
.RS
|
|
.nf
|
|
[[rule.action]]
|
|
type = "webhook"
|
|
enabled = true
|
|
url = "https://hooks.example.com/ban"
|
|
method = "POST"
|
|
headers = { "Content-Type" = "application/json", "Authorization" = "Bearer TOKEN" }
|
|
body = "{\\\"ip\\\": \\\"{ip}\\\", \\\"rule\\\": \\\"{rule}\\\"}"
|
|
.fi
|
|
.RE
|
|
.
|
|
.SS "Email Action"
|
|
.PP
|
|
Send email notification when an IP is banned.
|
|
.PP
|
|
\fBFields:\fR
|
|
.RS
|
|
.IP \(bu 2
|
|
\fBtype\fR \- "email"
|
|
.IP \(bu 2
|
|
\fBenabled\fR \- Enable/disable action (true/false)
|
|
.IP \(bu 2
|
|
\fBemail\fR \- Recipient email address \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBemail_sender\fR \- Sender email address \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBemail_subject\fR \- Email subject (default: "BanForge Alert")
|
|
.IP \(bu 2
|
|
\fBsmtp_host\fR \- SMTP server host \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBsmtp_port\fR \- SMTP server port \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBsmtp_user\fR \- SMTP username \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBsmtp_password\fR \- SMTP password \fI(required)\fR
|
|
.IP \(bu 2
|
|
\fBsmtp_tls\fR \- Enable TLS (true/false)
|
|
.IP \(bu 2
|
|
\fBbody\fR \- Email body text (supports variables)
|
|
.RE
|
|
.PP
|
|
\fBExample:\fR
|
|
.RS
|
|
.nf
|
|
[[rule.action]]
|
|
type = "email"
|
|
enabled = true
|
|
email = "admin@example.com"
|
|
email_sender = "banforge@example.com"
|
|
email_subject = "IP Banned"
|
|
smtp_host = "smtp.example.com"
|
|
smtp_port = 587
|
|
smtp_user = "banforge"
|
|
smtp_password = "secret"
|
|
smtp_tls = true
|
|
body = "IP {ip} has been banned for rule {rule}"
|
|
.fi
|
|
.RE
|
|
.
|
|
.SH "COMPLETE RULE EXAMPLE WITH ACTIONS"
|
|
.PP
|
|
.RS
|
|
.nf
|
|
[[rule]]
|
|
name = "nginx-403"
|
|
service = "nginx"
|
|
status = "403"
|
|
max_retry = 3
|
|
ban_time = "1h"
|
|
|
|
# Email notification
|
|
[[rule.action]]
|
|
type = "email"
|
|
enabled = true
|
|
email = "admin@example.com"
|
|
email_sender = "banforge@example.com"
|
|
smtp_host = "smtp.example.com"
|
|
smtp_port = 587
|
|
smtp_user = "banforge"
|
|
smtp_password = "secret"
|
|
smtp_tls = true
|
|
body = "IP {ip} banned by rule {rule}"
|
|
|
|
# Slack webhook
|
|
[[rule.action]]
|
|
type = "webhook"
|
|
enabled = true
|
|
url = "https://hooks.slack.com/services/XXX/YYY/ZZZ"
|
|
method = "POST"
|
|
headers = { "Content-Type" = "application/json" }
|
|
body = "{\\\"text\\\": \\\"IP {ip} banned for rule {rule}\\\"}"
|
|
|
|
# Custom script
|
|
[[rule.action]]
|
|
type = "script"
|
|
enabled = true
|
|
script = "/usr/local/bin/ban-notify.sh"
|
|
interpretator = "bash"
|
|
.fi
|
|
.RE
|
|
.
|
|
.SH FILES
|
|
.PP
|
|
.RS
|
|
.IP \(bu 2
|
|
\fI/etc/banforge/config.toml\fR \- main configuration
|
|
.IP \(bu 2
|
|
\fI/etc/banforge/rules.d/\fR \- rule files directory
|
|
.RE
|
|
.
|
|
.SH "SEE ALSO"
|
|
.BR banforge (1),
|
|
.BR iptables (8),
|
|
.BR nftables (8),
|
|
.BR systemd (1)
|
|
.
|
|
.SH AUTHOR
|
|
.PP
|
|
Ilya "d3m0k1d" Chernishev contact@d3m0k1d.ru
|