1
0
Fork 0
mirror of https://github.com/binwiederhier/ntfy.git synced 2024-12-14 11:47:33 +00:00
binwiederhier-ntfy/docs/config.md
2021-12-05 15:57:37 -05:00

11 KiB

Configuring the ntfy server

The ntfy server can be configured in three ways: using a config file (typically at /etc/ntfy/config.yml, see config.yml), via command line arguments or using environment variables.

Quick start

By default, simply running ntfy will start the server at port 80. No configuration needed. Batteries included 😀. If everything works as it should, you'll see something like this:

$ ntfy                
2021/11/30 19:59:08 Listening on :80

You can immediately start publishing messages, or subscribe via the Android app, the web UI, or simply via curl or your favorite HTTP client. To configure the server further, check out the config options table or simply type ntfy --help to get a list of command line options.

Message cache

If desired, ntfy can temporarily keep notifications in an in-memory or an on-disk cache. Caching messages for a short period of time is important to allow phones and other devices with brittle Internet connections to be able to retrieve notifications that they may have missed.

By default, ntfy keeps messages in-memory for 12 hours, which means that cached messages do not survive an application restart. You can override this behavior using the following config settings:

  • cache-file: if set, ntfy will store messages in a SQLite based cache (default is empty, which means in-memory cache). This is required if you'd like messages to be retained across restarts.
  • cache-duration: defines the duration for which messages are stored in the cache (default is 12h)

Subscribers can retrieve cached messaging using the poll=1 parameter, as well as the since= parameter.

Behind a proxy (TLS, etc.)

!!! warning If you are running ntfy behind a proxy, you must set the behind-proxy flag. Otherwise all visitors are rate limited as if they are one.

Rate limiting: If you are running ntfy behind a proxy (e.g. nginx, HAproxy or Apache), you should set the behind-proxy flag. This will instruct the rate limiting logic to use the X-Forwarded-For header as the primary identifier for a visitor, as opposed to the remote IP address. If the behind-proxy flag is not set, all visitors will be counted as one, because from the perspective of the ntfy server, they all share the proxy's IP address.

TLS/SSL: ntfy supports HTTPS/TLS by setting the listen-https config option. However, if you are behind a proxy, it is recommended that TLS/SSL termination is done by the proxy itself.

Firebase (FCM)

!!! info Using Firebase is optional and only works if you modify and build your own Android .apk. For a self-hosted instance, it's easier to just not bother with FCM.

Firebase Cloud Messaging (FCM) is the Google approved way to send push messages to Android devices. FCM is the only method that an Android app can receive messages without having to run a foreground service.

For the main host ntfy.sh, the ntfy Android app uses Firebase to send messages to the device. For other hosts, instant delivery is used and FCM is not involved.

To configure FCM for your self-hosted instance of the ntfy server, follow these steps:

  1. Sign up for a Firebase account
  2. Create a Firebase app and download the key file (e.g. myapp-firebase-adminsdk-...json)
  3. Place the key file in /etc/ntfy, set the firebase-key-file in config.yml accordingly and restart the ntfy server
  4. Build your own Android .apk following these instructions

Example:

# If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app.
# This is optional and only required to support Android apps (which don't allow background services anymore).
#
firebase-key-file: "/etc/ntfy/ntfy-sh-firebase-adminsdk-ahnce-9f4d6f14b5.json"

Rate limiting

!!! info Be aware that if you are running ntfy behind a proxy, you must set the behind-proxy flag. Otherwise all visitors are rate limited as if they are one.

By default, ntfy runs without authentication, so it is vitally important that we protect the server from abuse or overload. There are various limits and rate limits in place that you can use to configure the server. Let's do the easy ones first:

  • global-topic-limit defines the total number of topics before the server rejects new topics. It defaults to 5000.
  • visitor-subscription-limit is the number of subscriptions (open connections) per visitor. This value defaults to 30.

A visitor is identified by its IP address (or the X-Forwarded-For header if behind-proxy is set). All config options that start with the word visitor apply only on a per-visitor basis.

In addition to the limits above, there is a requests/second limit per visitor for all sensitive GET/PUT/POST requests. This limit uses a token bucket (using Go's rate package):

Each visitor has a bucket of 60 requests they can fire against the server (defined by visitor-request-limit-burst). After the 60, new requests will encounter a 429 Too Many Requests response. The visitor request bucket is refilled at a rate of one request every 10s (defined by visitor-request-limit-replenish)

  • visitor-request-limit-burst is the initial bucket of requests each visitor has. This defaults to 60.
  • visitor-request-limit-replenish is the rate at which the bucket is refilled (one request per x). Defaults to 10s.

During normal usage, you shouldn't encounter this limit at all, and even if you burst a few requests shortly (e.g. when you reconnect after a connection drop), it shouldn't have any effect.

Config options

Each config option can be set in the config file /etc/ntfy/config.yml (e.g. listen-http: :80) or as a CLI option (e.g. --listen-http :80. Here's a list of all available options. Alternatively, you can set an environment variable before running the ntfy command (e.g. export NTFY_LISTEN_HTTP=:80).

Config option Env variable Format Default Description
listen-http NTFY_LISTEN_HTTP [host]:port :80 Listen address for the HTTP web server
listen-https NTFY_LISTEN_HTTPS [host]:port - Listen address for the HTTPS web server. If set, you also need to set key-file and cert-file.
key-file NTFY_KEY_FILE filename - HTTPS/TLS private key file, only used if listen-https is set.
cert-file NTFY_CERT_FILE filename - HTTPS/TLS certificate file, only used if listen-https is set.
firebase-key-file NTFY_FIREBASE_KEY_FILE filename - If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app. This is optional and only required to save battery when using the Android app. See Firebase (FCM.
cache-file NTFY_CACHE_FILE filename - If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. See message cache.
cache-duration NTFY_CACHE_DURATION duration 12h Duration for which messages will be buffered before they are deleted. This is required to support the since=... and poll=1 parameter.
keepalive-interval NTFY_KEEPALIVE_INTERVAL duration 30s Interval in which keepalive messages are sent to the client. This is to prevent intermediaries closing the connection for inactivity. Note that the Android app has a hardcoded timeout at 77s, so it should be less than that.
manager-interval $NTFY_MANAGER_INTERVAL duration 1m Interval in which the manager prunes old messages, deletes topics and prints the stats.
global-topic-limit NTFY_GLOBAL_TOPIC_LIMIT number 5000 Rate limiting: Total number of topics before the server rejects new topics.
visitor-subscription-limit NTFY_VISITOR_SUBSCRIPTION_LIMIT number 30 Rate limiting: Number of subscriptions per visitor (IP address)
visitor-request-limit-burst NTFY_VISITOR_REQUEST_LIMIT_BURST number 60 Allowed GET/PUT/POST requests per second, per visitor. This setting is the initial bucket of requests each visitor has
visitor-request-limit-replenish NTFY_VISITOR_REQUEST_LIMIT_REPLENISH duration 10s Strongly related to visitor-request-limit-burst: The rate at which the bucket is refilled
behind-proxy NTFY_BEHIND_PROXY bool false If set, the X-Forwarded-For header is used to determine the visitor IP address instead of the remote address of the connection.

The format for a duration is: <number>(smh), e.g. 30s, 20m or 1h.

Command line options

$ ntfy --help
NAME:
   ntfy - Simple pub-sub notification service

USAGE:
   ntfy [OPTION..]

GLOBAL OPTIONS:
   --config value, -c value                           config file (default: /etc/ntfy/config.yml) [$NTFY_CONFIG_FILE]
   --listen-http value, -l value                      ip:port used to as listen address (default: ":80") [$NTFY_LISTEN_HTTP]
   --firebase-key-file value, -F value                Firebase credentials file; if set additionally publish to FCM topic [$NTFY_FIREBASE_KEY_FILE]
   --cache-file value, -C value                       cache file used for message caching [$NTFY_CACHE_FILE]
   --cache-duration since, -b since                   buffer messages for this time to allow since requests (default: 12h0m0s) [$NTFY_CACHE_DURATION]
   --keepalive-interval value, -k value               interval of keepalive messages (default: 30s) [$NTFY_KEEPALIVE_INTERVAL]
   --manager-interval value, -m value                 interval of for message pruning and stats printing (default: 1m0s) [$NTFY_MANAGER_INTERVAL]
   --global-topic-limit value, -T value               total number of topics allowed (default: 5000) [$NTFY_GLOBAL_TOPIC_LIMIT]
   --visitor-subscription-limit value, -V value       number of subscriptions per visitor (default: 30) [$NTFY_VISITOR_SUBSCRIPTION_LIMIT]
   --visitor-request-limit-burst value, -B value      initial limit of requests per visitor (default: 60) [$NTFY_VISITOR_REQUEST_LIMIT_BURST]
   --visitor-request-limit-replenish value, -R value  interval at which burst limit is replenished (one per x) (default: 10s) [$NTFY_VISITOR_REQUEST_LIMIT_REPLENISH]
   --behind-proxy, -P                                 if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting) (default: false) [$NTFY_BEHIND_PROXY]

Try 'ntfy COMMAND --help' for more information.

ntfy v1.4.8 (7b8185c), runtime go1.17, built at 1637872539
Copyright (C) 2021 Philipp C. Heckel, distributed under the Apache License 2.0