From 2052520a9007b19b89a59d2a70204b0f3bb3eb10 Mon Sep 17 00:00:00 2001 From: Nathan Price Date: Sun, 19 Jan 2025 03:10:39 -0500 Subject: [PATCH] Initial commit after history reset --- .gitignore | 1 + Docker Images/bluesky-pds.md | 115 ++++++++ Docker Images/bluesky-pds/cloudflare.png | Bin 0 -> 22620 bytes Docker Images/bluesky-pds/middleware.md | 21 ++ Docker Images/bluesky-pds/standalone.md | 24 ++ Docker Images/bluesky-pds/traefik.md | 41 +++ Docker Images/quartz.md | 113 ++++++++ .../quartz/Developing with Quartz.md | 33 +++ Tutorials/Docker/Proxy Network.md | 17 ++ Tutorials/Docker/getting started.md | 5 + Tutorials/Traefik/CloudFlare.md | 23 ++ index.md | 21 ++ templates/primary.md | 6 + utilities/fail2ban-manager.md | 96 ++++++ utilities/fail2ban-manager/base.md | 274 ++++++++++++++++++ .../fail2ban-manager/plugins/cloudflare.md | 113 ++++++++ utilities/fail2ban-manager/plugins/hetzner.md | 176 +++++++++++ .../fail2ban-manager/plugins/telegram.md | 144 +++++++++ 18 files changed, 1223 insertions(+) create mode 100644 .gitignore create mode 100644 Docker Images/bluesky-pds.md create mode 100644 Docker Images/bluesky-pds/cloudflare.png create mode 100644 Docker Images/bluesky-pds/middleware.md create mode 100644 Docker Images/bluesky-pds/standalone.md create mode 100644 Docker Images/bluesky-pds/traefik.md create mode 100644 Docker Images/quartz.md create mode 100644 Docker Images/quartz/Developing with Quartz.md create mode 100644 Tutorials/Docker/Proxy Network.md create mode 100644 Tutorials/Docker/getting started.md create mode 100644 Tutorials/Traefik/CloudFlare.md create mode 100644 index.md create mode 100644 templates/primary.md create mode 100644 utilities/fail2ban-manager.md create mode 100644 utilities/fail2ban-manager/base.md create mode 100644 utilities/fail2ban-manager/plugins/cloudflare.md create mode 100644 utilities/fail2ban-manager/plugins/hetzner.md create mode 100644 utilities/fail2ban-manager/plugins/telegram.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6b6248 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.obsidian/ diff --git a/Docker Images/bluesky-pds.md b/Docker Images/bluesky-pds.md new file mode 100644 index 0000000..b48d7e9 --- /dev/null +++ b/Docker Images/bluesky-pds.md @@ -0,0 +1,115 @@ +--- +title: bluesky-pds +draft: false +date: 2025-01-18 +--- + +| | | +| ---------------------------- | ---------------------------------------------------------------------------------------------- | +| Official bluesky-pds project | [GitHub - bluesky-social/pds](https://github.com/bluesky-social/pds) | +| Image on Forgejo | [Forgejo](https://code.modernleft.org/gravityfargo/-/packages/container/bluesky-pds/latest) | +| Image on Dockerhub | [Dockerhub](https://hub.docker.com/r/gravityfargo/bluesky-pds) | +| Image Source | [Forgejo](https://code.modernleft.org/gravityfargo/bluesky-pds-docker) | +| Issue Tracker | [GitHub - gravityfargo/bluesky-pds-docker](https://github.com/gravityfargo/bluesky-pds-docker) | + +```bash +docker pull code.modernleft.org/gravityfargo/bluesky-pds:latest +``` + +--- + +A self-contained Docker image for the [Bluesky PDS (Personal Data Server) ](https://github.com/bluesky-social/pds) for use with Traefik. This image is pinned to v0.4.74. + +It is required to run the instance behind a proxy (like [Traefik](https://doc.traefik.io/traefik/)) to generate SSL certificates. This will not work otherwise. The standard pds install includes caddy to handle this. A wildcard DNS assignment along with a wildcard SSL certificate is required. I use Cloudflare for this, see the screenshot below. + +This is not intended for production, and I am not responsible for any data loss or security issues. This is a personal project, and I am not affiliated with Bluesky. + +> [!warning] Data Warning +> Before changing images, upgrading, or any other modification always backup your data! + +### Requirements + +I haven't verified these are the minimum requirements, but they are what I found to be necessary during development. I probably had some dependencies installed already. + +#### Manjaro/Arch + +```bash +sudo pacman -S jq +``` + +#### Debian/Ubuntu + +```bash +sudo apt install make xxd +``` + +### Setup + +Generate secrets and add them to `.env` file. +See [example.env](https://code.modernleft.org/gravityfargo/bluesky-pds-docker/src/branch/main/example.env) as an example. + +```bash +# Generate secret environment variables +echo PDS_ADMIN_PASSWORD: $(openssl rand --hex 16) + +echo PDS_JWT_SECRET: $(openssl rand --hex 16) + +echo PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: $(openssl ecparam --name secp256k1 --genkey --noout --outform DER | tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32) +``` + +### Docker Compose Setup + +Full list of additional Environment Variables provided by bluesky upstream can be found in the +[packages/pds/src/config/env.ts](https://github.com/bluesky-social/atproto/blob/main/packages/pds/src/config/env.ts) + +If you'd like to learn more about my docker setup, head over to [[getting started|Docker - Getting Started]] + +By default, the image uses 1000:1000 as the UID:GID for the user. This can be changed by setting the `PUID` and `PGID` environment variables. +The compose element `hostname` must be the same value as `PDS_HOSTNAME`. + +![[traefik]] + +Optionally, you can use the [[middleware|BlueskyHeaders]] middleware to set headers. + +--- + +I do not run this, but it should be possible. + +![[standalone]] + +### Running Commands + +Nothing has changed in this department, other than not needing `sudo`. The commands are the same as the upstream project. Such as + +- [Creating an account using pdsadmin](https://github.com/bluesky-social/pds?tab=readme-ov-file#creating-an-account-using-pdsadmin) +- [Creating an account using an invite code](https://github.com/bluesky-social/pds?tab=readme-ov-file#creating-an-account-using-an-invite-code) + +```bash +docker exec -it bluesky-pds bash +pdsadmin account create +pdsadmin create-invite-code +``` + +> [!danger] Update Warning +> Do not under any circumstances update the image using `pdsadmin update`. I have not tested this, and it may break the image. Submit an +> [issue to my repository](https://github.com/gravityfargo/bluesky-pds-docker) requesting an update, +> and I will update this image and pin the pds to the new version. + +### Cloudflare DNS + +After various testing, I have figured out two things. + +1. In order for email verification to work, you cannot have the DNS Proxy enabled or `AAAA` records active. +2. After you have verified emails, and do not intend to use the email feature, you can re-enable the DNS Proxy and `AAAA` records. + +![[cloudflare.png]] + +## SMTP + +I use protonmail for my SMTP server. You can use any SMTP server you like, but I figured I'd share this information. +These are the environment variables I use. + +``` +PDS_EMAIL_SMTP_URL: smtp://user@example.com:TOKEN@smtp.protonmail.ch:587/ +PDS_EMAIL_FROM_ADDRESS: user@example.com +``` diff --git a/Docker Images/bluesky-pds/cloudflare.png b/Docker Images/bluesky-pds/cloudflare.png new file mode 100644 index 0000000000000000000000000000000000000000..72bd5b8b293aceba6042788acc765581666745c9 GIT binary patch literal 22620 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 Ih-lpZU!<(@smtp.resend.com:465/ + PDS_EMAIL_FROM_ADDRESS: admin@example.com + PUID: 1000 + PGID: 1001 + volumes: + - ./bluesky-pds:/pds + labels: + traefik.enable: "true" + traefik.http.routers.bluesky-pds-insecure.entrypoints: http + traefik.http.routers.bluesky-pds-insecure.rule: HostRegexp(`^.+\.example\.com$`) || Host(`example.com`) + # traefik.http.routers.bluesky-pds-insecure.middlewares: BlueskyHeaders@file + traefik.http.routers.bluesky-pds-secure.entrypoints: https + traefik.http.routers.bluesky-pds-secure.rule: HostRegexp(`^.+\.example\.com$`) || Host(`example.com`) + traefik.http.routers.bluesky-pds-secure.tls: "true" + traefik.http.services.bluesky-pds.loadbalancer.server.scheme: http + traefik.http.services.bluesky-pds.loadbalancer.server.port: 3000 + # traefik.http.routers.bluesky-pds-secure.middlewares: BlueskyHeaders@file +``` diff --git a/Docker Images/quartz.md b/Docker Images/quartz.md new file mode 100644 index 0000000..edec654 --- /dev/null +++ b/Docker Images/quartz.md @@ -0,0 +1,113 @@ +--- +title: quartz +draft: false +date: 2025-01-16 +--- + +| | | +| ----------------------- | ---------------------------------------------------------------------------------------------- | +| Image on Forgejo | [Forgejo](https://code.modernleft.org/gravityfargo/-/packages/container/quartz-docker/v4.4.0) | +| Official quartz project | [GitHub - jackyzha0/quartz](https://github.com/jackyzha0/quartz) | +| Image Source | [Forgejo - gravityfargo/quartz-docker](https://code.modernleft.org/gravityfargo/quartz-docker) | +| Issue Tracker | | + +```bash +docker pull code.modernleft.org/gravityfargo/quartz-docker:v4.4.0 +``` + +--- + +This project runs Quartz v4.4.0, a fast, batteries-included static site generator, inside a Docker container. It transforms Markdown content into a fully functional website. + +While Quartz provides [Docker support](https://quartz.jzhao.xyz/features/Docker-Support), it is not as self contained as this project. + +There is no support for SSL or any other features that are not directly related to building the site. I run everything behind traefik, so I don't need it. + +## 🐳 Docker Compose Setup + +Create a data directory + +```bash +mkdir -p /srv/quartz +``` + +```yaml title="docker-compose.yml" +services: + quartz-wiki: + container_name: quartz-wiki + image: code.modernleft.org/gravityfargo/quartz-docker:dev + ports: + - 80:80 + environment: + USER_ID: 1000 + GROUP_ID: 1001 + SERVER_NAME: "docs.modernleft.org" + ENABLE_CRON: "true" + BUILD_SCHEDULE: "*/30 * * * *" + CONTENT_REPO: "https://code.modernleft.org/gravityfargo/modernleft-docs.git" + volumes: + - /srv/quartz:/quartz +``` + +**First Run** + +```bash +docker-compose up -d +docker stop quartz-wiki +``` + +On first run, the container will download the necessary dependencies, build the site, and download the content repository. + +After that, you can configure whatever you would like in `/srv/quartz/src` using the stock options found in the quartz [documentation](https://quartz.jzhao.xyz/configuration) Bare minimum should be `baseUrl` and `pageTitle`. + +🥳 Done! 🎉 + +## Manually Building the Site + +If you don't use the cron job, and don't feel like restarting the container, you can build the site manually. + +```bash +docker exec -it quartz-wiki bash +# +cd /quartz/content/ && git restore . && git pull +cd /quartz/src/ && npx quartz build +``` + +## ⚙️ Configuration + +**cron** + +This is the an equivalent command to the cron job. + +```bash +cd /quartz/content +git restore . +git pull +cd /quartz/src & +npx quartz build +echo 'Content Updated.' +``` + +Setting `ENABLE_CRON` to `true` and defining `BUILD_SCHEDULE` performs these actions. +If you need help configuring [Crontab.guru - The cron schedule expression generator](https://crontab.guru/) is a useful tool for that + +Example: + +```yaml +environment: + ENABLE_CRON: "true" + BUILD_SCHEDULE: "*/1 * * * *" # Runs every minute +``` + +### Environment Variables + +| Variable | Description | Default Value | +| -------------------- | ---------------------------------------------------- | ---------------------------------------------------- | +| `USER_ID`/`GROUP_ID` | UID/GID that` /quartz` will be chown'd to on startup | `1000`:`1000` | +| `NGINX_PORT` | Port for the Nginx server | `80` | +| `SERVER_NAME` | NGINX server name | `quartz.zhao.xyz` | +| `ENABLE_CRON` | Enables scheduled builds (`true` or `false`) | `false` | +| `BUILD_SCHEDULE` | Cron expression for scheduling site builds | `"*/10 * * * *"` every 10 min | +| `CONTENT_REPO` | URL of the content repository | `https://code.modernleft.org/gravityfargo/empty.git` | + +> [!NOTE] > `CONTENT_REPO` Must use https, not git. diff --git a/Docker Images/quartz/Developing with Quartz.md b/Docker Images/quartz/Developing with Quartz.md new file mode 100644 index 0000000..dc7fe54 --- /dev/null +++ b/Docker Images/quartz/Developing with Quartz.md @@ -0,0 +1,33 @@ +--- +title: Developing with Quartz +draft: false +date: 2025-01-17 +--- + +This container is also good for quickly developing components for Quartz. It is a good way to test things out without having to install anything on your local machine, and a simple `make run` -> `ctrl-c` -> `up arrow` -> `enter` is all you need to see your changes. + +I keep all of my projects in `~/Repositories`, so I would do this: + +Link my primary development folder to the container repo's source folder: +```bash +cd ~/Repositories +git clone git@git.modernleft.org:gravityfargo/quartz-docker.git +git clone git@github.com:jackyzha0/quartz.git +``` + +Then mount the quartz directory to the development docker-compose file: +```yaml +volumes: +- ~/Repositories/quartz:/quartz/src +``` +Then, you can run the container with the following command: +```bash +cd ~/Repositories/quartz-docker +make run +``` + +If 200+ files are claiming to be modified, you may need to disable filemode checking: + +```bash +git config core.fileMode false +``` diff --git a/Tutorials/Docker/Proxy Network.md b/Tutorials/Docker/Proxy Network.md new file mode 100644 index 0000000..93ab31e --- /dev/null +++ b/Tutorials/Docker/Proxy Network.md @@ -0,0 +1,17 @@ +--- +title: Proxy Network +draft: true +date: 2025-01-18 +--- + +```json title="/etc/docker/daemon.json" +{ + "ipv6": true, + "fixed-cidr-v6": "2001:db8:1::/64" +} +``` + +```bash +sudo systemctl reboot +docker network create --subnet=192.168.1.0/24 --ipv6 --attachable proxy +``` diff --git a/Tutorials/Docker/getting started.md b/Tutorials/Docker/getting started.md new file mode 100644 index 0000000..131e3f6 --- /dev/null +++ b/Tutorials/Docker/getting started.md @@ -0,0 +1,5 @@ +--- +title: Getting Started +draft: true +date: 2025-01-18 +--- diff --git a/Tutorials/Traefik/CloudFlare.md b/Tutorials/Traefik/CloudFlare.md new file mode 100644 index 0000000..1236a75 --- /dev/null +++ b/Tutorials/Traefik/CloudFlare.md @@ -0,0 +1,23 @@ +--- +title: CloudFlare +draft: true +date: 2025-01-18 +--- + +Disable: +- Always Use HTTPS +- Automatic HTTPS Rewrites +Enable: +- gRPC +- Pseudo IPv4 (headers) + + +If you have A and AAAA then the plugin `github.com/Paxxs/traefik-get-real-ip` + +192.168.1.20 - - [19/Jan/2025:01:01:32 +0000] "GET /static/contentIndex.json HTTP/1.1" 304 0 "[https://docs.modernleft.org/"](https://docs.modernleft.org/"); "Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0" "2603:7080:f400:ed43:939f:266:9bef:e628, 172.71.255.28" + +192.168.1.20 - proxy +172.71.255.28 - cloudflare ipv4 +2603:7080:f400:ed43:939f:266:9bef:e628 - the actual user's ip + +"Pseudo IPv4" is needed for this \ No newline at end of file diff --git a/index.md b/index.md new file mode 100644 index 0000000..58c51e5 --- /dev/null +++ b/index.md @@ -0,0 +1,21 @@ +--- +title: Home +draft: false +date: 2025-01-16 +--- + +Welcome to the ModernLeft Documentation! + +This is a consolidated wiki for most of my projects. + +--- + +## Docker Containers + +### [[quartz]] + +Simply [quartz](https://quartz.jzhao.xyz/), in a docker container. This wiki is running on it. + +### [[bluesky-pds]] + +A self-contained Docker image for the [Bluesky PDS (Personal Data Server)](https://github.com/bluesky-social/pds) for use with Traefik. diff --git a/templates/primary.md b/templates/primary.md new file mode 100644 index 0000000..046d170 --- /dev/null +++ b/templates/primary.md @@ -0,0 +1,6 @@ +--- +title: ModernLeft - CHANGEME +draft: false +date: <% tp.file.creation_date("YYYY-MM-DD") %> +--- + diff --git a/utilities/fail2ban-manager.md b/utilities/fail2ban-manager.md new file mode 100644 index 0000000..bf9d288 --- /dev/null +++ b/utilities/fail2ban-manager.md @@ -0,0 +1,96 @@ +--- +title: fail2ban-manager +draft: true +date: 2025-01-16 +--- + +An extensible CLI tool for managing [fail2ban](https://github.com/fail2ban/fail2ban). + +- [Introduction](#introduction) +- [Working with Jails](#working-with-jails) +- [Plugins](#plugins) + - [Cloudflare](#cloudflare) + - [Plugin: Hetzner](#plugin-hetzner) + - [Plugin: Telegram](#plugin-telegram) +- [Credits](#credits) + +## Introduction + +Source Code hosted on my [Forgejo instance](https://forgejo.gravityfargo.dev/gravityfargo/fail2ban-manager). Registration is enabled for the public with GitHub via Authentik. + +Any issues and feature requests can be submitted here on GitHub. + +This tool is designed to make managing fail2ban easier without the need to edit configuration files. It is designed to be extensible via plugins, and easy to use. + +## Working with Jails + +## Plugins + +### Cloudflare + +> Ban an IP address using IP Rules in [Cloudflare WAF](https://developers.cloudflare.com/waf/tools/ip-access-rules/create/). Jails are configured create rules in a specific DNS zone. Bans are cached in a database for fail2ban's check action to use. + +| Notes | | +| -------------------- | ----------------------------------------------------------------- | +| Typer generated docs | [Link](man/cloudflare.md) | +| Provided via | [Officicial SDK](https://github.com/cloudflare/cloudflare-python) | + +--- + +https://github.com/Paxxs/traefik-get-real-ip + +| Variable | Purpose | +| ---------------------- | ----------------------------------------- | +| `CLOUDFLARE_EMAIL` | Email address for Cloudflare account | +| `CLOUDFLARE_API_TOKEN` | Token with permissions to manage IP Rules | + +1. Enable the Cloudflare plugin + +```bash +f2bm plugin enable cloudflare +``` + +1. Create an [API Token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) +2. Get the [Zone ID](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/) from Cloudflare and create a zone in the database + +```bash +f2bm cloudflare create-zone 11111111111111111111111111111111 example.com +``` + +### Plugin: Hetzner + +> Whitelist ip addresses in the [Hetzner](https://www.hetzner.com/) cloud firewall, and bulk whitelist Cloudflare IP addresses. + +| Notes | | +| -------------------- | --------------------------------------------------------------- | +| Typer generated docs | [Link](man/hetzner.md) | +| Provided via | [Officicial SDK](https://github.com/hetznercloud/hcloud-python) | + +--- + +1. Enable the Hetzner plugin + +```bash +f2bm plugin enable hetzner +``` + +2. Create an [API Token](https://docs.hetzner.com/cloud/api/getting-started/generating-api-token/) + +### Plugin: Telegram + +> Send a message to a Telegram chat. Custom messages per-jail are supported as well as seperate groups for each jail. + +| Notes | | +| -------------------- | ----------------------------------------------------------------- | +| Typer generated docs | [Link](man/telegram.md) | +| Provided via | [Rest API](https://forgejo.gravityfargo.dev/gravityfargo/envoyer) | + +--- + +## Credits + +- [Typer](https://github.com/fastapi/typer), build great CLIs. Easy to code. Based on Python type hints. + +- [Rich](https://github.com/Textualize/rich) is a Python library for rich text and beautiful formatting in the terminal. + +- [envoyer](https://forgejo.gravityfargo.dev/gravityfargo/envoyer) Stupid simple notifications library. (My Project) diff --git a/utilities/fail2ban-manager/base.md b/utilities/fail2ban-manager/base.md new file mode 100644 index 0000000..6fa9c9b --- /dev/null +++ b/utilities/fail2ban-manager/base.md @@ -0,0 +1,274 @@ +--- +title: fail2ban-manager plugin +draft: true +date: 2025-01-16 +--- + +**Usage**: + +```console +$ fail2ban-manager [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--install-completion`: Install completion for the current shell. +- `--show-completion`: Show completion for the current shell, to copy it or customize the installation. +- `--help`: Show this message and exit. + +**Commands**: + +- `jail`: Configure Fail2ban jails. +- `config`: Configure fail2ban-manager's configuration. +- `plugin`: Configure fail2ban-manager's plugins. + +## `fail2ban-manager jail` + +Configure Fail2ban jails. + +**Usage**: + +```console +$ fail2ban-manager jail [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `ls`: List all defined jails. +- `enable`: Enable a jail. +- `disable`: Disable a jail. +- `info`: Display information about a jail. +- `edit`: Edit the properties of a jail. + +### `fail2ban-manager jail ls` + +List all defined jails. + +**Usage**: + +```console +$ fail2ban-manager jail ls [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +### `fail2ban-manager jail enable` + +Enable a jail. + +**Usage**: + +```console +$ fail2ban-manager jail enable [OPTIONS] NAME +``` + +**Arguments**: + +- `NAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +### `fail2ban-manager jail disable` + +Disable a jail. + +**Usage**: + +```console +$ fail2ban-manager jail disable [OPTIONS] NAME +``` + +**Arguments**: + +- `NAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +### `fail2ban-manager jail info` + +Display information about a jail. + +**Usage**: + +```console +$ fail2ban-manager jail info [OPTIONS] NAME +``` + +**Arguments**: + +- `NAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +### `fail2ban-manager jail edit` + +Edit the properties of a jail. + +**Usage**: + +```console +$ fail2ban-manager jail edit [OPTIONS] NAME +``` + +**Arguments**: + +- `NAME`: Name of the jail. [required] + +**Options**: + +- `--backend TEXT`: The backend used to get file modifications. + +Options: . + +- `--bantime-increment`: Enable searching previously banned IPs to increment the ban time. +- `--bantime-rndtime INTEGER`: Add random time (in seconds) to the calculated ban time. +- `--bantime-maxtime INTEGER`: Maximum ban time (in seconds) that can be reached. +- `--bantime-factor FLOAT`: Factor used for exponential growth of ban time. +- `--bantime-formula TEXT`: Custom formula for calculating the next ban time. +- `--bantime-multipliers TEXT`: Custom multipliers for calculating the next ban time (e.g., 1 5 30 60). +- `--bantime-overalljails`: Search for banned IPs across all jails (default: false). +- `--ignoreself`: Ignore local/own IP addresses (default: true). +- `--ignoreip TEXT`: List of IPs, CIDR masks, or DNS hosts to ignore. + +Example: "127.0.0.1/8 ::1" + +- `--ignorecommand TEXT`: Command to dynamically determine if an IP should be ignored. +- `--bantime TEXT`: Duration for which a host is banned (e.g., 10m, 1h). +- `--findtime TEXT`: Time window for counting failed attempts before a ban (e.g., 10m). +- `--maxretry INTEGER`: Number of failed attempts allowed before a ban is triggered. +- `--maxmatches INTEGER`: Maximum number of stored matches for actions (defaults to maxretry). +- `--protocol TEXT`: Protocol to be banned (default: tcp). +- `--port TEXT`: Ports to ban (e.g., 0:65535 to ban all ports). +- `--chain TEXT`: Specify the chain where jumps will be added for ban actions. +- `--usedns TEXT`: Behavior for DNS lookups (yes, warn, no, raw). +- `--logencoding TEXT`: Encoding of the log files (e.g., utf-8, ascii, auto). +- `--action TEXT`: Default action for banning. + +EX: action\_, action_mw, action_mwl, action_xarf, action_cf_mwl, action_abuseipdb + +multiple values can be specified. +`--action action_ --action action_mw` + +- `--mta TEXT`: Mail Transfer Agent (e.g., sendmail). +- `--sender TEXT`: Sender email address for notifications. +- `--destemail TEXT`: Destination email address for notifications. +- `--fail2ban-agent TEXT`: User-agent format for Fail2Ban. +- `--delete TEXT`: Delete an option from the jail. + +Example: `--delete bantime` + +- `--help`: Show this message and exit. + +## `fail2ban-manager config` + +Configure fail2ban-manager's configuration. + +**Usage**: + +```console +$ fail2ban-manager config [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `reset`: Copy default configurations from `*.conf`... + +### `fail2ban-manager config reset` + +Copy default configurations from `*.conf` to `*.local` and json files. + +**Usage**: + +```console +$ fail2ban-manager config reset [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager plugin` + +Configure fail2ban-manager's plugins. + +**Usage**: + +```console +$ fail2ban-manager plugin [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `ls`: List installed plugins. +- `enable`: Enable a plugin. +- `disable`: Disable a plugin. + +### `fail2ban-manager plugin ls` + +List installed plugins. + +**Usage**: + +```console +$ fail2ban-manager plugin ls [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +### `fail2ban-manager plugin enable` + +Enable a plugin. + +**Usage**: + +```console +$ fail2ban-manager plugin enable [OPTIONS] PLUGIN_NAME +``` + +**Arguments**: + +- `PLUGIN_NAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +### `fail2ban-manager plugin disable` + +Disable a plugin. + +**Usage**: + +```console +$ fail2ban-manager plugin disable [OPTIONS] PLUGIN_NAME +``` + +**Arguments**: + +- `PLUGIN_NAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. diff --git a/utilities/fail2ban-manager/plugins/cloudflare.md b/utilities/fail2ban-manager/plugins/cloudflare.md new file mode 100644 index 0000000..ffd0859 --- /dev/null +++ b/utilities/fail2ban-manager/plugins/cloudflare.md @@ -0,0 +1,113 @@ +--- +title: fail2ban-manager plugin - cloudflare +draft: true +date: 2025-01-16 +--- + +**Usage**: + +```console +$ fail2ban-manager cloudflare [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `zones`: List configured zones +- `zone-info`: Show information about a zone. +- `create-zone`: Create a new zone in the database. +- `check-ip`: Check if an IP is banned based on rules... +- `ban`: Check if an IP is banned based on rules... + +## `fail2ban-manager cloudflare zones` + +List configured zones + +**Usage**: + +```console +$ fail2ban-manager cloudflare zones [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager cloudflare zone-info` + +Show information about a zone. + +This command will pull the rules from Cloudflare and update the database as well as display the rules in a table. + +**Usage**: + +```console +$ fail2ban-manager cloudflare zone-info [OPTIONS] ZONE_ID +``` + +**Arguments**: + +- `ZONE_ID`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager cloudflare create-zone` + +Create a new zone in the database. + +**Usage**: + +```console +$ fail2ban-manager cloudflare create-zone [OPTIONS] ZONE_ID NAME +``` + +**Arguments**: + +- `ZONE_ID`: [required] +- `NAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager cloudflare check-ip` + +Check if an IP is banned based on rules cached in the database. + +**Usage**: + +```console +$ fail2ban-manager cloudflare check-ip [OPTIONS] IP +``` + +**Arguments**: + +- `IP`: IP Address to check [required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager cloudflare ban` + +Check if an IP is banned based on rules cached in the database. + +**Usage**: + +```console +$ fail2ban-manager cloudflare ban [OPTIONS] ZONE_ID IP +``` + +**Arguments**: + +- `ZONE_ID`: [required] +- `IP`: IP Address to ban [required] + +**Options**: + +- `--help`: Show this message and exit. diff --git a/utilities/fail2ban-manager/plugins/hetzner.md b/utilities/fail2ban-manager/plugins/hetzner.md new file mode 100644 index 0000000..a721660 --- /dev/null +++ b/utilities/fail2ban-manager/plugins/hetzner.md @@ -0,0 +1,176 @@ +--- +title: fail2ban-manager plugin - hetzner +draft: true +date: 2025-01-16 +--- + +**Usage**: + +```console +$ fail2ban-manager hetzner [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--help`: Show this message and exit. + +**Commands**: + +- `info`: Check the status of the Hetzner plugin. +- `update`: Update the configuration. +- `reset`: Reset the configuration to defaults. +- `token`: Set Hetzner API token. +- `firewall-info`: Pull the firewalls from the server. +- `whitelist`: Whitelist an IP address. +- `whitelist-cloudflare`: Whitelist Cloudflare IP addresses. +- `delete-rule`: Delete a firewall rule. + +## `fail2ban-manager hetzner info` + +Check the status of the Hetzner plugin. + +**Usage**: + +```console +$ fail2ban-manager hetzner info [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner update` + +Update the configuration. + +**Usage**: + +```console +$ fail2ban-manager hetzner update [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner reset` + +Reset the configuration to defaults. + +**Usage**: + +```console +$ fail2ban-manager hetzner reset [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner token` + +Set Hetzner API token. + +Warning: If token_str is specified, it will be save in plaintext in the database. + +**Usage**: + +```console +$ fail2ban-manager hetzner token [OPTIONS] [TOKEN_STR] +``` + +**Arguments**: + +- `[TOKEN_STR]`: The Hetzner API token. + +**Options**: + +- `--use-env`: Use the `HETZNER_TOKEN` environment variable. +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner firewall-info` + +Pull the firewalls from the server. + +**Usage**: + +```console +$ fail2ban-manager hetzner firewall-info [OPTIONS] FIREWALL_ID +``` + +**Arguments**: + +- `FIREWALL_ID`: The ID of the firewall to pull from the server. [required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner whitelist` + +Whitelist an IP address. + +## Examples + +fail2ban-manager hetzner whitelist <FIREWALLID> --self +fail2ban-manager hetzner whitelist <FIREWALLID> <IP> + +**Usage**: + +```console +$ fail2ban-manager hetzner whitelist [OPTIONS] FIREWALL_ID [IP] [PORT] +``` + +**Arguments**: + +- `FIREWALL_ID`: The ID of the firewall to pull from the server. [required] +- `[IP]`: An IP to whitelist. +- `[PORT]`: any, 443, 80-85 [default: any] + +**Options**: + +- `--self`: Whitelist the External IP of the current machine. +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner whitelist-cloudflare` + +Whitelist Cloudflare IP addresses. + +**Usage**: + +```console +$ fail2ban-manager hetzner whitelist-cloudflare [OPTIONS] FIREWALL_ID [PORT] +``` + +**Arguments**: + +- `FIREWALL_ID`: The ID of the firewall to pull from the server. [required] +- `[PORT]`: any, 443, 80-85 [default: 443] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager hetzner delete-rule` + +Delete a firewall rule. + +## Examples + +fail2ban-manager hetzner delete-rule <FIREWALLID> "fail2ban-manager whitelist - <PORT>" +fail2ban-manager hetzner delete-rule <FIREWALLID> "fail2ban-manager cloudflare whitelist - <PORT>" + +**Usage**: + +```console +$ fail2ban-manager hetzner delete-rule [OPTIONS] FIREWALL_ID DESCRIPTION +``` + +**Arguments**: + +- `FIREWALL_ID`: The ID of the firewall to pull from the server. [required] +- `DESCRIPTION`: The description of the rule to delete. [required] + +**Options**: + +- `--help`: Show this message and exit. diff --git a/utilities/fail2ban-manager/plugins/telegram.md b/utilities/fail2ban-manager/plugins/telegram.md new file mode 100644 index 0000000..fdd0895 --- /dev/null +++ b/utilities/fail2ban-manager/plugins/telegram.md @@ -0,0 +1,144 @@ +--- +title: fail2ban-manager plugin - telegram +draft: true +date: 2025-01-16 +--- + +**Usage**: + +```console +$ fail2ban-manager telegram [OPTIONS] COMMAND [ARGS]... +``` + +**Options**: + +- `--install-completion`: Install completion for the current shell. +- `--show-completion`: Show completion for the current shell, to copy it or customize the installation. +- `--help`: Show this message and exit. + +**Commands**: + +- `ls`: List all jails with Telegram notifications. +- `add-to-jail`: Add the Telegram provider to a jail. +- `remove-from-jail`: Remove the Telegram provider from a jail. +- `edit-message`: Set the message for a specific action. +- `enable-message`: Enable a message for a specific action in... +- `send`: Send a messague to a Telegram bot. + +## `fail2ban-manager telegram ls` + +List all jails with Telegram notifications. + +**Usage**: + +```console +$ fail2ban-manager telegram ls [OPTIONS] +``` + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager telegram add-to-jail` + +Add the Telegram provider to a jail. + +**Usage**: + +```console +$ fail2ban-manager telegram add-to-jail [OPTIONS] JAILNAME TOKEN CHATID +``` + +**Arguments**: + +- `JAILNAME`: [required] +- `TOKEN`: [env var: TELEGRAM_API_TOKEN; required] +- `CHATID`: [env var: TELEGRAM_CHAT_ID; required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager telegram remove-from-jail` + +Remove the Telegram provider from a jail. + +**Usage**: + +```console +$ fail2ban-manager telegram remove-from-jail [OPTIONS] JAILNAME +``` + +**Arguments**: + +- `JAILNAME`: [required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager telegram edit-message` + +Set the message for a specific action. + +**Usage**: + +```console +$ fail2ban-manager telegram edit-message [OPTIONS] JAILNAME ACTION MESSAGE +``` + +**Arguments**: + +- `JAILNAME`: [required] +- `ACTION`: The action to send a message for. [required] +- `MESSAGE`: The action to send. [required] + +**Options**: + +- `--help`: Show this message and exit. + +## `fail2ban-manager telegram enable-message` + +Enable a message for a specific action in a jail. + +**Usage**: + +```console +$ fail2ban-manager telegram enable-message [OPTIONS] JAILNAME +``` + +**Arguments**: + +- `JAILNAME`: [required] + +**Options**: + +- `--start`: Enable message for start action. +- `--stop`: Enable message for stop action. +- `--check`: Enable message for check action. +- `--ban`: Enable message for ban action. +- `--unban`: Enable message for unban action. +- `--help`: Show this message and exit. + +## `fail2ban-manager telegram send` + +Send a messague to a Telegram bot. + +**Usage**: + +```console +$ fail2ban-manager telegram send [OPTIONS] ACTION JAILNAME [TOKEN] [CHATID] +``` + +**Arguments**: + +- `ACTION`: The action to send a message for. [required] +- `JAILNAME`: Name of the jail sending the message [required] +- `[TOKEN]`: [env var: TELEGRAM_API_TOKEN] +- `[CHATID]`: [env var: TELEGRAM_CHAT_ID] + +**Options**: + +- `--ip TEXT`: IP address of the banned/unbanned IP +- `--failures INTEGER`: Number of failures before ban [default: 0] +- `--help`: Show this message and exit.