Merge branch 'release-2.26.x'

This commit is contained in:
binwiederhier
2026-07-20 23:42:03 +02:00
17 changed files with 961 additions and 63 deletions

View File

@@ -2129,6 +2129,72 @@ chain.
The official ntfy.sh server uses fail2ban to ban IPs. Check out ntfy.sh's [Ansible fail2ban role](https://github.com/binwiederhier/ntfy-ansible/tree/main/roles/fail2ban) for details. Ban actors are banned for 1 hour initially, and up to
4 hours at a time for repeated offenses. IPv4 addresses are banned individually, while IPv6 addresses are banned by their `/56` prefix.
#### Ban-feed
In addition to the fail2ban setup above, ntfy can detect abusive visitors itself and write their IP
addresses to a file for fail2ban to ban from. ntfy keeps a per-prefix weighted "strike" budget, and
each rejected request costs strikes based on its response code -- the ntfy error code, or its HTTP
status (see `ban-weights`) -- so different kinds of rejection can be weighted differently or exempted
entirely. When a prefix exceeds the budget, ntfy appends the offending IP address to `ban-file`. Since
every line is already a confirmed offender, the fail2ban jail can ban on first sight (`maxretry = 1`).
- `ban-file` is the file offenders are appended to. If it is not set, the ban-feed is disabled. Its
parent directory must exist and be writable by ntfy. Be sure to rotate it (e.g. with logrotate and
`copytruncate`) so it does not grow unbounded.
- `ban-window` is the rolling window over which weighted strikes are counted, per IP prefix.
- `ban-threshold` is the number of weighted strikes per `ban-window` before a prefix is written to
`ban-file`. Each prefix has one shared budget, so it cannot be gamed by mixing error codes.
- `ban-weights` assigns a strike weight per matcher key, formatted as `KEY:WEIGHT`. A key is an exact
ntfy error code (`42909`), a code family (`429*`, `403*`, `4*`), a bare HTTP status (`403`, short for
`403*`), or `*`. The longest matching key wins. A weight of `0` exempts a code entirely (it never
counts toward a ban), useful to spare a specific code from a `*` catch-all. Heavier weights ban faster. If you do not
include a `*` rule, any code that matches nothing defaults to weight `1` (i.e. it can be banned);
set `*:0` to exempt everything that is not explicitly weighted.
Only rejections (4xx/5xx) count towards a ban; successful requests never do. Because the budget
refills over `ban-window`, the trigger is a sustained rate: a prefix is only written out once it
exceeds `ban-threshold / ban-window` rejections per second (with the defaults, `100 / 10m` = ~0.17/s).
Each line in `ban-file` has the format `<RFC3339-timestamp> <ip> <prefix> <http-code> <ntfy-code>`, for example:
```
2026-01-15T20:56:32Z 1.2.3.4 1.2.3.4/32 429 42901
2026-01-15T20:56:32Z 2001:db8::abcd 2001:db8::/64 429 42909
```
`<prefix>` is `<ip>` masked to the rate-limiting prefix (`visitor-prefix-bits-ipv4`/`-ipv6`) -- the
same unit ntfy rate-limits by. Have the fail2ban filter capture the bare `<ip>` (the action then
applies the prefix):
=== "server.yml"
```yaml
ban-file: "/var/log/ntfy/ban.log"
ban-window: "10m"
ban-threshold: 100
ban-weights:
- "42909:10" # too many auth failures -> brute force, ban fast
# everything else 4xx/5xx defaults to weight 1
```
=== "/etc/fail2ban/filter.d/ntfy-ban.conf"
```
[Definition]
failregex = ^\S+ <HOST> \S+ \d+ \d+$
datepattern = ^%%Y-%%m-%%dT%%H:%%M:%%S
ignoreregex =
```
=== "/etc/fail2ban/jail.d/ntfy-ban.local"
```
[ntfy-ban]
enabled = true
filter = ntfy-ban
action = iptables-multiport[name=ntfy-ban, port="http,https", protocol=tcp]
logpath = /var/log/ntfy/ban.log
maxretry = 1
findtime = 1m
bantime = 1h
```
## IPv6 support
ntfy fully supports IPv6, though there are a few things to keep in mind.
@@ -2329,6 +2395,10 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
| `visitor-topic-creation-limit-replenish` | `NTFY_VISITOR_TOPIC_CREATION_LIMIT_REPLENISH` | *duration* | 1m | Rate limiting: Rate at which the per-visitor topic-creation bucket is refilled (one new topic per x). |
| `visitor-prefix-bits-ipv4` | `NTFY_VISITOR_PREFIX_BITS_IPV4` | *number* | 32 | Rate limiting: Number of bits to use for IPv4 visitor prefix, e.g. 24 for /24 |
| `visitor-prefix-bits-ipv6` | `NTFY_VISITOR_PREFIX_BITS_IPV6` | *number* | 64 | Rate limiting: Number of bits to use for IPv6 visitor prefix, e.g. 48 for /48 |
| `ban-file` | `NTFY_BAN_FILE` | *filename* | - | Abuse ban-feed: file confirmed abusive visitor IPs are appended to, for fail2ban to tail. Empty disables the feature. See [Banning bad actors](#banning-bad-actors-fail2ban) |
| `ban-window` | `NTFY_BAN_WINDOW` | *duration* | 10m | Abuse ban-feed: rolling window over which weighted strikes are counted, per IP prefix |
| `ban-threshold` | `NTFY_BAN_THRESHOLD` | *number* | 100 | Abuse ban-feed: weighted strikes per `ban-window` before a prefix is written to `ban-file` |
| `ban-weights` | `NTFY_BAN_WEIGHTS` | *list of KEY:WEIGHT* | `42909:10`| Abuse ban-feed: per-code strike weights (exact code, family `429*`, or `*`; longest match wins; `0` exempts). See [Banning bad actors](#banning-bad-actors-fail2ban) |
| `web-root` | `NTFY_WEB_ROOT` | *path*, e.g. `/` or `/app`, or `disable` | `/` | Sets root of the web app (e.g. /, or /app), or disables it entirely (disable) |
| `enable-signup` | `NTFY_ENABLE_SIGNUP` | *boolean* (`true` or `false`) | `false` | Allows users to sign up via the web app, or API |
| `enable-login` | `NTFY_ENABLE_LOGIN` | *boolean* (`true` or `false`) | `false` | Allows users to log in via the web app, or API |

View File

@@ -28,7 +28,7 @@ via the following channels:
| Channel | Contact | Description |
|-----------------------|-----------------------------------------------------|------------------------------------------|
| **General Support** | [support@mail.ntfy.sh](mailto:support@mail.ntfy.sh) | Direct email support for Pro subscribers |
| **Billing Inquiries** | [billing@mail.ntfy.sh](mailto:support@mail.ntfy.sh) | Inquire about billing issues |
| **Billing Inquiries** | [billing@mail.ntfy.sh](mailto:billing@mail.ntfy.sh) | Inquire about billing issues |
| **Discord/Matrix** | Mention your Pro status | Priority responses in community channels |
Please include your ntfy.sh username when contacting support so we can verify your subscription status.
@@ -37,6 +37,11 @@ Please include your ntfy.sh username when contacting support so we can verify yo
If you discover a security vulnerability, please report it responsibly via [security@mail.ntfy.sh](mailto:security@mail.ntfy.sh). See also: [SECURITY.md](https://github.com/binwiederhier/ntfy/blob/main/SECURITY.md).
## Abuse reports
To report spam, phishing, or other abuse of ntfy.sh, please email [abuse@mail.ntfy.sh](mailto:abuse@mail.ntfy.sh).
Please include the topic name and any relevant message details so we can investigate.
## Other inquiries
For questions about our [privacy policy](privacy.md), data handling, or to exercise your data rights

View File

@@ -34,37 +34,37 @@ as a service starting at boot time.
=== "x86_64/amd64"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_amd64.tar.gz
tar zxvf ntfy_2.26.0_linux_amd64.tar.gz
sudo cp -a ntfy_2.26.0_linux_amd64/ntfy /usr/local/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.0_linux_amd64/{client,server}/*.yml /etc/ntfy
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_amd64.tar.gz
tar zxvf ntfy_2.26.3_linux_amd64.tar.gz
sudo cp -a ntfy_2.26.3_linux_amd64/ntfy /usr/local/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.3_linux_amd64/{client,server}/*.yml /etc/ntfy
sudo ntfy serve
```
=== "armv6"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_armv6.tar.gz
tar zxvf ntfy_2.26.0_linux_armv6.tar.gz
sudo cp -a ntfy_2.26.0_linux_armv6/ntfy /usr/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.0_linux_armv6/{client,server}/*.yml /etc/ntfy
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_armv6.tar.gz
tar zxvf ntfy_2.26.3_linux_armv6.tar.gz
sudo cp -a ntfy_2.26.3_linux_armv6/ntfy /usr/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.3_linux_armv6/{client,server}/*.yml /etc/ntfy
sudo ntfy serve
```
=== "armv7/armhf"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_armv7.tar.gz
tar zxvf ntfy_2.26.0_linux_armv7.tar.gz
sudo cp -a ntfy_2.26.0_linux_armv7/ntfy /usr/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.0_linux_armv7/{client,server}/*.yml /etc/ntfy
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_armv7.tar.gz
tar zxvf ntfy_2.26.3_linux_armv7.tar.gz
sudo cp -a ntfy_2.26.3_linux_armv7/ntfy /usr/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.3_linux_armv7/{client,server}/*.yml /etc/ntfy
sudo ntfy serve
```
=== "arm64"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_arm64.tar.gz
tar zxvf ntfy_2.26.0_linux_arm64.tar.gz
sudo cp -a ntfy_2.26.0_linux_arm64/ntfy /usr/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.0_linux_arm64/{client,server}/*.yml /etc/ntfy
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_arm64.tar.gz
tar zxvf ntfy_2.26.3_linux_arm64.tar.gz
sudo cp -a ntfy_2.26.3_linux_arm64/ntfy /usr/bin/ntfy
sudo mkdir /etc/ntfy && sudo cp ntfy_2.26.3_linux_arm64/{client,server}/*.yml /etc/ntfy
sudo ntfy serve
```
@@ -84,25 +84,25 @@ Install the ntfy server unit file (which contains parameters to start the servic
=== "x86_64/amd64"
```bash
sudo mv ntfy_2.26.0_linux_amd64/server/ntfy.service /etc/systemd/system/
sudo mv ntfy_2.26.3_linux_amd64/server/ntfy.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/ntfy.service
```
=== "armv6"
```bash
sudo mv ntfy_2.26.0_linux_armv6/server/ntfy.service /etc/systemd/system/
sudo mv ntfy_2.26.3_linux_armv6/server/ntfy.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/ntfy.service
```
=== "armv7/armhf"
```bash
sudo mv ntfy_2.26.0_linux_armv7/server/ntfy.service /etc/systemd/system/
sudo mv ntfy_2.26.3_linux_armv7/server/ntfy.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/ntfy.service
```
=== "arm64"
```bash
sudo mv ntfy_2.26.0_linux_arm64/server/ntfy.service /etc/systemd/system/
sudo mv ntfy_2.26.3_linux_arm64/server/ntfy.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/ntfy.service
```
@@ -118,25 +118,25 @@ Install the ntfy server service script:
=== "x86_64/amd64"
```bash
sudo mv ntfy_2.26.0_linux_amd64/server/ntfy.openrc /etc/init.d/ntfy
sudo mv ntfy_2.26.3_linux_amd64/server/ntfy.openrc /etc/init.d/ntfy
sudo chmod 755 /etc/init.d/ntfy
```
=== "armv6"
```bash
sudo mv ntfy_2.26.0_linux_armv6/server/ntfy.openrc /etc/init.d/ntfy
sudo mv ntfy_2.26.3_linux_armv6/server/ntfy.openrc /etc/init.d/ntfy
sudo chmod 755 /etc/init.d/ntfy
```
=== "armv7/armhf"
```bash
sudo mv ntfy_2.26.0_linux_armv7/server/ntfy.openrc /etc/init.d/ntfy
sudo mv ntfy_2.26.3_linux_armv7/server/ntfy.openrc /etc/init.d/ntfy
sudo chmod 755 /etc/init.d/ntfy
```
=== "arm64"
```bash
sudo mv ntfy_2.26.0_linux_arm64/server/ntfy.openrc /etc/init.d/ntfy
sudo mv ntfy_2.26.3_linux_arm64/server/ntfy.openrc /etc/init.d/ntfy
sudo chmod 755 /etc/init.d/ntfy
```
@@ -204,7 +204,7 @@ Manually installing the .deb file:
=== "x86_64/amd64"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_amd64.deb
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_amd64.deb
sudo dpkg -i ntfy_*.deb
sudo systemctl enable ntfy
sudo systemctl start ntfy
@@ -212,7 +212,7 @@ Manually installing the .deb file:
=== "armv6"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_armv6.deb
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_armv6.deb
sudo dpkg -i ntfy_*.deb
sudo systemctl enable ntfy
sudo systemctl start ntfy
@@ -220,7 +220,7 @@ Manually installing the .deb file:
=== "armv7/armhf"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_armv7.deb
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_armv7.deb
sudo dpkg -i ntfy_*.deb
sudo systemctl enable ntfy
sudo systemctl start ntfy
@@ -228,7 +228,7 @@ Manually installing the .deb file:
=== "arm64"
```bash
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_arm64.deb
wget https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_arm64.deb
sudo dpkg -i ntfy_*.deb
sudo systemctl enable ntfy
sudo systemctl start ntfy
@@ -238,28 +238,28 @@ Manually installing the .deb file:
=== "x86_64/amd64"
```bash
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_amd64.rpm
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_amd64.rpm
sudo systemctl enable ntfy
sudo systemctl start ntfy
```
=== "armv6"
```bash
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_armv6.rpm
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_armv6.rpm
sudo systemctl enable ntfy
sudo systemctl start ntfy
```
=== "armv7/armhf"
```bash
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_armv7.rpm
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_armv7.rpm
sudo systemctl enable ntfy
sudo systemctl start ntfy
```
=== "arm64"
```bash
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_linux_arm64.rpm
sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_linux_arm64.rpm
sudo systemctl enable ntfy
sudo systemctl start ntfy
```
@@ -301,18 +301,18 @@ pkg install go-ntfy
## macOS
The [ntfy CLI](subscribe/cli.md) (`ntfy publish` and `ntfy subscribe` only) is supported on macOS as well.
To install, please [download the tarball](https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_darwin_all.tar.gz),
To install, please [download the tarball](https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_darwin_all.tar.gz),
extract it and place it somewhere in your `PATH` (e.g. `/usr/local/bin/ntfy`).
If run as `root`, ntfy will look for its config at `/etc/ntfy/client.yml`. For all other users, it'll look for it at
`~/Library/Application Support/ntfy/client.yml` (sample included in the tarball).
```bash
curl -L https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_darwin_all.tar.gz > ntfy_2.26.0_darwin_all.tar.gz
tar zxvf ntfy_2.26.0_darwin_all.tar.gz
sudo cp -a ntfy_2.26.0_darwin_all/ntfy /usr/local/bin/ntfy
curl -L https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_darwin_all.tar.gz > ntfy_2.26.3_darwin_all.tar.gz
tar zxvf ntfy_2.26.3_darwin_all.tar.gz
sudo cp -a ntfy_2.26.3_darwin_all/ntfy /usr/local/bin/ntfy
mkdir ~/Library/Application\ Support/ntfy
cp ntfy_2.26.0_darwin_all/client/client.yml ~/Library/Application\ Support/ntfy/client.yml
cp ntfy_2.26.3_darwin_all/client/client.yml ~/Library/Application\ Support/ntfy/client.yml
ntfy --help
```
@@ -333,7 +333,7 @@ brew install ntfy
The ntfy server and CLI are fully supported on Windows. You can run the ntfy server directly or as a Windows service.
To install, you can either
* [Download the latest ZIP](https://github.com/binwiederhier/ntfy/releases/download/v2.26.0/ntfy_2.26.0_windows_amd64.zip),
* [Download the latest ZIP](https://github.com/binwiederhier/ntfy/releases/download/v2.26.3/ntfy_2.26.3_windows_amd64.zip),
extract it and place the `ntfy.exe` binary somewhere in your `%Path%`.
* Or install ntfy from the [Scoop](https://scoop.sh) main repository via `scoop install ntfy`

View File

@@ -4,14 +4,26 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
## Current stable releases
| Component | Version | Release date |
|------------------|---------|---------------|
| ntfy server | v2.26.0 | July 9, 2026 |
| ntfy Android app | v1.24.0 | Mar 5, 2026 |
| ntfy iOS app | v1.7.0 | May 30, 2026 |
| Component | Version | Release date |
|------------------|---------|--------------|
| ntfy server | v2.26.3 | Jul 20, 2026 |
| ntfy Android app | v1.24.0 | Mar 5, 2026 |
| ntfy iOS app | v1.7.0 | May 30, 2026 |
Please check out the release notes for [upcoming releases](#not-released-yet) below.
### ntfy server v2.26.3
Released July 20, 2026
This is a hotfix release, useful pretty much only for ntfy.sh. It was adds the ability to track abusive IPs more
efficiently, reducing the load on the IP banning services and preventing them from falling behind and leaving abusers
unbanned for too long. It works by tracking HTTP errors, and writing out a ban file that fail2ban can read and ban
offenders instantly. See [ban-feed](config.md#ban-feed) for details.
**Features:**
* Add an abuse ban-feed: when enabled via `ban-file`, ntfy tracks a weighted strike budget per visitor and appends abusive IPs to a file that fail2ban can tail and ban on sight (`ban-file`, `ban-window`, `ban-threshold`, `ban-weights`; see [ban-feed docs](config.md#ban-feed))
### ntfy server v2.26.0
Released July 9, 2026