2 Commits

Author SHA1 Message Date
d3m0k1d
b9754f605b fix: Delete sudo calls on exec
All checks were successful
build / build (push) Successful in 3m8s
CD - BanForge Release / release (push) Successful in 5m24s
2026-01-27 16:20:03 +03:00
d3m0k1d
be6b19426b docs: Add installation guide
All checks were successful
build / build (push) Successful in 3m16s
2026-01-26 16:51:40 +03:00
5 changed files with 90 additions and 26 deletions

View File

@@ -32,15 +32,79 @@ If you have any questions or suggestions, create issue on [Github](https://githu
- ufw/iptables/nftables/firewalld - ufw/iptables/nftables/firewalld
# Installation # Installation
Search for a release on the [Gitea](https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases) releases page and download it. Then create or copy(/build dir) a systemd unit(openrc script) file. Search for a release on the [Gitea](https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases) releases page and download it.
Or clone the repo and use the Makefile. In release page you can find rpm, deb, apk packages, for amd or arm architecture.
```
git clone https://gitea.d3m0k1d.ru/d3m0k1d/BanForge.git ## Installation guide for packages
cd BanForge
sudo make build-daemon ### Debian/Ubuntu(.deb)
cd bin ```bash
# Download the latest DEB package
wget https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases/download/v0.4.0/banforge_0.4.0_linux_amd64.deb
# Install
sudo dpkg -i banforge_0.4.0_linux_amd64.deb
# Verify installation
sudo systemctl status banforge
``` ```
### RHEL-based(.rpm)
```bash
# Download
wget https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases/download/v0.4.0/banforge_0.4.0_linux_amd64.rpm
# Install
sudo rpm -i banforge_0.4.0_linux_amd64.rpm
# Or with dnf (CentOS 8+, AlmaLinux)
sudo dnf install banforge_0.4.0_linux_amd64.rpm
# Verify
sudo systemctl status banforge
```
### Alpine(.apk)
```bash
# Download
wget https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases/download/v0.4.0/banforge_0.4.0_linux_amd64.apk
# Install
sudo apk add --allow-untrusted banforge_0.4.0_linux_amd64.apk
# Verify
sudo rc-service banforge status
```
### Arch Linux(.pkg.tar.zst)
```bash
# Download
wget https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases/download/v0.4.0/banforge_0.4.0_linux_amd64.pkg.tar.zst
# Install
sudo pacman -U banforge_0.4.0_linux_amd64.pkg.tar.zst
# Verify
sudo systemctl status banforge
```
This is examples for other versions with different architecture or new versions check release page on [Gitea](https://gitea.d3m0k1d.ru/d3m0k1d/BanForge/releases).
## Installation guide for source code
```bash
# Download
git clone https://github.com/d3m0k1d/BanForge.git
cd BanForge
make build-daemon
cd bin
mv banforge /usr/bin/banforge
cd ..
# Add init script and uses banforge init
cd build
./postinstall.sh
```
# Usage # Usage
For first steps use this commands For first steps use this commands
```bash ```bash

View File

@@ -21,14 +21,14 @@ func (f *Firewalld) Ban(ip string) error {
if err != nil { if err != nil {
return err return err
} }
cmd := exec.Command("sudo", "firewall-cmd", "--zone=drop", "--add-source", ip, "--permanent") cmd := exec.Command("firewall-cmd", "--zone=drop", "--add-source", ip, "--permanent")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
f.logger.Error(err.Error()) f.logger.Error(err.Error())
return err return err
} }
f.logger.Info("Add source " + ip + " " + string(output)) f.logger.Info("Add source " + ip + " " + string(output))
output, err = exec.Command("sudo", "firewall-cmd", "--reload").CombinedOutput() output, err = exec.Command("firewall-cmd", "--reload").CombinedOutput()
if err != nil { if err != nil {
f.logger.Error(err.Error()) f.logger.Error(err.Error())
return err return err
@@ -42,14 +42,14 @@ func (f *Firewalld) Unban(ip string) error {
if err != nil { if err != nil {
return err return err
} }
cmd := exec.Command("sudo", "firewall-cmd", "--zone=drop", "--remove-source", ip, "--permanent") cmd := exec.Command("firewall-cmd", "--zone=drop", "--remove-source", ip, "--permanent")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
f.logger.Error(err.Error()) f.logger.Error(err.Error())
return err return err
} }
f.logger.Info("Remove source " + ip + " " + string(output)) f.logger.Info("Remove source " + ip + " " + string(output))
output, err = exec.Command("sudo", "firewall-cmd", "--reload").CombinedOutput() output, err = exec.Command("firewall-cmd", "--reload").CombinedOutput()
if err != nil { if err != nil {
f.logger.Error(err.Error()) f.logger.Error(err.Error())
return err return err

View File

@@ -27,7 +27,7 @@ func (f *Iptables) Ban(ip string) error {
if err != nil { if err != nil {
return err return err
} }
cmd := exec.Command("sudo", "iptables", "-A", "INPUT", "-s", ip, "-j", "DROP") cmd := exec.Command("iptables", "-A", "INPUT", "-s", ip, "-j", "DROP")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
f.logger.Error("failed to ban IP", f.logger.Error("failed to ban IP",
@@ -45,7 +45,7 @@ func (f *Iptables) Ban(ip string) error {
return err return err
} }
// #nosec G204 - f.config is validated above via validateConfigPath() // #nosec G204 - f.config is validated above via validateConfigPath()
cmd = exec.Command("sudo", "iptables-save", "-f", f.config) cmd = exec.Command("iptables-save", "-f", f.config)
output, err = cmd.CombinedOutput() output, err = cmd.CombinedOutput()
if err != nil { if err != nil {
f.logger.Error("failed to save config", f.logger.Error("failed to save config",
@@ -69,7 +69,7 @@ func (f *Iptables) Unban(ip string) error {
if err != nil { if err != nil {
return err return err
} }
cmd := exec.Command("sudo", "iptables", "-D", "INPUT", "-s", ip, "-j", "DROP") cmd := exec.Command("iptables", "-D", "INPUT", "-s", ip, "-j", "DROP")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
f.logger.Error("failed to unban IP", f.logger.Error("failed to unban IP",
@@ -87,7 +87,7 @@ func (f *Iptables) Unban(ip string) error {
return err return err
} }
// #nosec G204 - f.config is validated above via validateConfigPath() // #nosec G204 - f.config is validated above via validateConfigPath()
cmd = exec.Command("sudo", "iptables-save", "-f", f.config) cmd = exec.Command("iptables-save", "-f", f.config)
output, err = cmd.CombinedOutput() output, err = cmd.CombinedOutput()
if err != nil { if err != nil {
f.logger.Error("failed to save config", f.logger.Error("failed to save config",

View File

@@ -26,7 +26,7 @@ func (n *Nftables) Ban(ip string) error {
return err return err
} }
cmd := exec.Command("sudo", "nft", "add", "rule", "inet", "banforge", "banned", cmd := exec.Command("nft", "add", "rule", "inet", "banforge", "banned",
"ip", "saddr", ip, "drop") "ip", "saddr", ip, "drop")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
@@ -70,7 +70,7 @@ func (n *Nftables) Unban(ip string) error {
return fmt.Errorf("no rule found for IP %s", ip) return fmt.Errorf("no rule found for IP %s", ip)
} }
// #nosec G204 - handle is extracted from nftables output and validated // #nosec G204 - handle is extracted from nftables output and validated
cmd := exec.Command("sudo", "nft", "delete", "rule", "inet", "banforge", "banned", cmd := exec.Command("nft", "delete", "rule", "inet", "banforge", "banned",
"handle", handle) "handle", handle)
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
@@ -112,7 +112,7 @@ func (n *Nftables) Setup(config string) error {
} }
} }
` `
cmd := exec.Command("sudo", "tee", config) cmd := exec.Command("tee", config)
stdin, err := cmd.StdinPipe() stdin, err := cmd.StdinPipe()
if err != nil { if err != nil {
return fmt.Errorf("failed to create stdin pipe: %w", err) return fmt.Errorf("failed to create stdin pipe: %w", err)
@@ -135,7 +135,7 @@ func (n *Nftables) Setup(config string) error {
return fmt.Errorf("failed to save config: %w", err) return fmt.Errorf("failed to save config: %w", err)
} }
cmd = exec.Command("sudo", "nft", "-f", config) cmd = exec.Command("nft", "-f", config)
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("failed to load nftables config: %s", string(output)) return fmt.Errorf("failed to load nftables config: %s", string(output))
@@ -145,7 +145,7 @@ func (n *Nftables) Setup(config string) error {
} }
func (n *Nftables) findRuleHandle(ip string) (string, error) { func (n *Nftables) findRuleHandle(ip string) (string, error) {
cmd := exec.Command("sudo", "nft", "-a", "list", "chain", "inet", "banforge", "banned") cmd := exec.Command("nft", "-a", "list", "chain", "inet", "banforge", "banned")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return "", fmt.Errorf("failed to list chain rules: %w", err) return "", fmt.Errorf("failed to list chain rules: %w", err)
@@ -172,13 +172,13 @@ func saveNftablesConfig(configPath string) error {
return err return err
} }
cmd := exec.Command("sudo", "nft", "list", "ruleset") cmd := exec.Command("nft", "list", "ruleset")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("failed to get nftables ruleset: %w", err) return fmt.Errorf("failed to get nftables ruleset: %w", err)
} }
cmd = exec.Command("sudo", "tee", configPath) cmd = exec.Command("tee", configPath)
stdin, err := cmd.StdinPipe() stdin, err := cmd.StdinPipe()
if err != nil { if err != nil {
return fmt.Errorf("failed to create stdin pipe: %w", err) return fmt.Errorf("failed to create stdin pipe: %w", err)

View File

@@ -23,7 +23,7 @@ func (u *Ufw) Ban(ip string) error {
return err return err
} }
cmd := exec.Command("sudo", "ufw", "--force", "deny", "from", ip) cmd := exec.Command("ufw", "--force", "deny", "from", ip)
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
u.logger.Error("failed to ban IP", u.logger.Error("failed to ban IP",
@@ -42,7 +42,7 @@ func (u *Ufw) Unban(ip string) error {
return err return err
} }
cmd := exec.Command("sudo", "ufw", "--force", "delete", "deny", "from", ip) cmd := exec.Command("ufw", "--force", "delete", "deny", "from", ip)
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
u.logger.Error("failed to unban IP", u.logger.Error("failed to unban IP",
@@ -59,7 +59,7 @@ func (u *Ufw) Unban(ip string) error {
func (u *Ufw) Setup(config string) error { func (u *Ufw) Setup(config string) error {
if config != "" { if config != "" {
fmt.Printf("Ufw dont support config file\n") fmt.Printf("Ufw dont support config file\n")
cmd := exec.Command("sudo", "ufw", "enable") cmd := exec.Command("ufw", "enable")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
u.logger.Error("failed to enable ufw", u.logger.Error("failed to enable ufw",
@@ -69,7 +69,7 @@ func (u *Ufw) Setup(config string) error {
} }
} }
if config == "" { if config == "" {
cmd := exec.Command("sudo", "ufw", "enable") cmd := exec.Command("ufw", "enable")
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
u.logger.Error("failed to enable ufw", u.logger.Error("failed to enable ufw",