- Detect an existing ipset without timeout support and migrate it in place (temporary set + copy members + ipset swap + destroy) without unblocking. - IPv6: "<set>6" (family inet6) + ip6tables match-set rule; ban/unban pick the set by address family. IPv4 keeps working if IPv6 is unavailable. - Remove unwrap()/panics: MartilloMaldito::new/with_config and every public method return Result<_, MartilloError>; ignore multiport/range rules when parsing secured ports; handle an empty DOCKER-USER chain. - Ipset::save_all / save-ipsets for ipset-persistent (/etc/iptables/ipsets). - structopt -> clap 4, thiserror 1 -> 2. CLI exits 1 on errors. - Kernel tests skip without CAP_NET_ADMIN; run them with `unshare -rn`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
221 lines
5.2 KiB
Markdown
221 lines
5.2 KiB
Markdown
# Martillo Maldito
|
|
|
|
**Martillo Maldito** is an `iptables` wrapper that simplifies firewall rule management in an intuitive and structured way. This CLI allows you to manage secured ports, block IPs, save rules, and more.
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- Ban/unban IPv4 and IPv6 addresses with `ipset` (optional timeout).
|
|
- Retrieve all banned IPs.
|
|
- Query and manage secured ports.
|
|
- Allow or deny access by IP for specific ports.
|
|
- Rule persistence.
|
|
- Optional Docker integration.
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
- Rust 1.80 or higher.
|
|
- `iptables`, `ip6tables` and `ipset` installed on the system.
|
|
- Proper permissions to manage `iptables` rules (e.g., running as root, or `CAP_NET_ADMIN`).
|
|
|
|
---
|
|
|
|
## Banning with ipset
|
|
|
|
Bans are stored in two `hash:ip` sets with timeout support: `banned` (IPv4) and
|
|
`banned6` (IPv6), each matched by a `-m set --match-set <set> src -j DROP` rule at the
|
|
top of `INPUT` (or `DOCKER-USER` with `--docker`) in `iptables`/`ip6tables`. Sets and
|
|
rules are created on first use.
|
|
|
|
If a set already exists **without** timeout support (older versions created it like
|
|
that, and `ipset add ... timeout N` then fails), it is migrated automatically without
|
|
unblocking anyone: a temporary set with timeout is created, the members are copied,
|
|
`ipset swap` puts it in place and the old one is destroyed.
|
|
|
|
If IPv6 is not available (no `ip6tables`, no IPv6 in the kernel), IPv4 bans keep
|
|
working and banning an IPv6 address returns an error.
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
1. Clone the repository:
|
|
|
|
```bash
|
|
git clone https://github.com/your_user/martillo_maldito.git
|
|
cd martillo_maldito
|
|
```
|
|
|
|
2. Build the project:
|
|
|
|
```bash
|
|
cargo build --release
|
|
```
|
|
|
|
3. Optionally, copy the executable to a directory in your PATH:
|
|
|
|
```bash
|
|
cp target/release/martillo_maldito /usr/local/bin/
|
|
```
|
|
|
|
---
|
|
|
|
## Usage
|
|
|
|
### General Syntax
|
|
|
|
```bash
|
|
martillo_maldito <command> [options]
|
|
```
|
|
|
|
### Available Commands
|
|
|
|
#### 1. Retrieve all banned IPs
|
|
|
|
```bash
|
|
martillo_maldito get-banned-ips [--docker | -d]
|
|
```
|
|
|
|
**Options:**
|
|
- `--docker`, `-d`: Includes rules in Docker environments.
|
|
|
|
#### Ban / unban an IP
|
|
|
|
```bash
|
|
martillo_maldito ban-ip --ip <ip> [--timeout <seconds>] [--docker | -d]
|
|
martillo_maldito unban-ip --ip <ip> [--docker | -d]
|
|
```
|
|
|
|
IPv6 addresses go to the `banned6` set. Without `--timeout` the ban is permanent.
|
|
Every command prints `true`/`false` (or JSON) on stdout; on failure the error is
|
|
printed on stderr and the exit code is 1.
|
|
|
|
#### Save the ipsets
|
|
|
|
```bash
|
|
martillo_maldito save-ipsets [--file /etc/iptables/ipsets]
|
|
```
|
|
|
|
Writes every set in the format restored at boot by `ipset-persistent`.
|
|
|
|
#### 2. Retrieve all secured ports
|
|
|
|
```bash
|
|
martillo_maldito get-secured-ports [--docker | -d]
|
|
```
|
|
|
|
#### 3. Retrieve all secured ports with allowed IPs
|
|
|
|
```bash
|
|
martillo_maldito get-secured-ports-with-allowed-ips [--docker | -d]
|
|
```
|
|
|
|
#### 4. Check if a port is secured
|
|
|
|
```bash
|
|
martillo_maldito is-port-secured --port <port> [--docker | -d]
|
|
```
|
|
|
|
**Options:**
|
|
- `--port`, `-p`: Specifies the port to check.
|
|
- `--docker`, `-d`: Includes rules in Docker environments.
|
|
|
|
#### 5. Secure a port
|
|
|
|
```bash
|
|
martillo_maldito secure-port --port <port> [--position <position>] [--docker | -d]
|
|
```
|
|
|
|
**Options:**
|
|
- `--port`, `-p`: Specifies the port to secure.
|
|
- `--position`, `-P`: Specifies the rule position in `iptables`.
|
|
- `--docker`, `-d`: Includes rules in Docker environments.
|
|
|
|
#### 6. Unsecure a port
|
|
|
|
```bash
|
|
martillo_maldito unsecure-port --port <port> [--docker | -d]
|
|
```
|
|
|
|
**Options:**
|
|
- `--port`, `-p`: Specifies the port to unsecure.
|
|
- `--docker`, `-d`: Includes rules in Docker environments.
|
|
|
|
#### 7. Allow an IP for a port
|
|
|
|
```bash
|
|
martillo_maldito allow-ip-for-port --ip <ip> --port <port> [--position <position>] [--docker | -d]
|
|
```
|
|
|
|
**Options:**
|
|
- `--ip`, `-i`: Specifies the IP to allow.
|
|
- `--port`, `-p`: Specifies the port to allow the IP on.
|
|
- `--position`, `-P`: Specifies the rule position.
|
|
- `--docker`, `-d`: Includes rules in Docker environments.
|
|
|
|
#### 8. Remove an allowed IP from a port
|
|
|
|
```bash
|
|
martillo_maldito remove-allow-ip-port --ip <ip> --port <port> [--docker | -d]
|
|
```
|
|
|
|
**Options:**
|
|
- `--ip`, `-i`: Specifies the IP to remove.
|
|
- `--port`, `-p`: Specifies the port to remove the IP from.
|
|
- `--docker`, `-d`: Includes rules in Docker environments.
|
|
|
|
#### 9. Save rules
|
|
|
|
```bash
|
|
martillo_maldito save-rules
|
|
```
|
|
|
|
Saves all current `iptables` rules for future restoration.
|
|
|
|
---
|
|
|
|
## Examples
|
|
|
|
1. **Retrieve all banned IPs:**
|
|
|
|
```bash
|
|
martillo_maldito get-banned-ips
|
|
```
|
|
|
|
2. **Secure port 8080 with Docker enabled:**
|
|
|
|
```bash
|
|
martillo_maldito secure-port -p 8080 -d
|
|
```
|
|
|
|
3. **Allow access to IP 192.168.1.10 on port 22:**
|
|
|
|
```bash
|
|
martillo_maldito allow-ip-for-port -i 192.168.1.10 -p 22
|
|
```
|
|
|
|
4. **Save all current rules:**
|
|
|
|
```bash
|
|
martillo_maldito save-rules
|
|
```
|
|
|
|
---
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
cargo test # kernel tests are skipped without CAP_NET_ADMIN
|
|
unshare -rn cargo test # run them too, isolated, without sudo
|
|
cargo build --release && unshare -rn env SELF_ISOLATED=1 ./tests/integration_netns.sh
|
|
```
|
|
|
|
---
|
|
|
|
## Disclaimer
|
|
|
|
This repository is designed solely for experimental or educational purposes. It is not intended for use in production environments or critical projects. Use at your own risk.
|