#!/bin/bash ############################################################# #### ntfy Push Notification Server Setup #### #### Install and configure ntfy as a systemd service #### #### #### #### Author: Phil Connor #### #### Contact: contact@mylinux.work #### #### License: MIT #### #### Version: 1.0 #### #### #### #### Usage: sudo ./install-ntfy-server.sh #### ############################################################# set -euo pipefail # --- Configuration (edit these before running) --- NTFY_VERSION="2.8.0" DOMAIN="ntfy.example.com" NTFY_USER="ntfy" NTFY_DIR="/var/lib/ntfy" CONFIG_DIR="/etc/ntfy" # Ensure script is run as root if [[ $EUID -ne 0 ]]; then echo "ERROR: This script must be run as root (use sudo)." exit 1 fi echo "=== Installing ntfy v${NTFY_VERSION} ===" # Create ntfy user if ! id "$NTFY_USER" &>/dev/null; then echo "Creating ntfy user..." useradd --system --no-create-home --shell /usr/sbin/nologin "$NTFY_USER" fi # Create directories echo "Creating directories..." mkdir -p "$NTFY_DIR" "$CONFIG_DIR" chown "$NTFY_USER:$NTFY_USER" "$NTFY_DIR" # Download and install ntfy echo "Downloading ntfy..." rm -rf /tmp/ntfy_extract mkdir -p /tmp/ntfy_extract wget -q -O /tmp/ntfy.tar.gz "https://github.com/binwiederhier/ntfy/releases/download/v${NTFY_VERSION}/ntfy_${NTFY_VERSION}_linux_amd64.tar.gz" tar -xzf /tmp/ntfy.tar.gz -C /tmp/ntfy_extract find /tmp/ntfy_extract -name "ntfy" -type f -exec mv {} /usr/local/bin/ntfy \; chmod +x /usr/local/bin/ntfy rm -rf /tmp/ntfy.tar.gz /tmp/ntfy_extract # Verify installation echo "Verifying installation..." if [ -x /usr/local/bin/ntfy ]; then echo "✓ ntfy binary installed at /usr/local/bin/ntfy" else echo "✗ ntfy binary not found" exit 1 fi # Create configuration echo "Installing configuration..." cat > "$CONFIG_DIR/server.yml" << EOF # ntfy server configuration # Location: /etc/ntfy/server.yml # Base URL for the server (used in notification links) base-url: "http://${DOMAIN}" # Listen address - use internal port, proxy externally listen-http: "127.0.0.1:8090" # Authentication - deny by default, require tokens auth-default-access: "deny-all" auth-file: "/var/lib/ntfy/user.db" # Cache for offline message delivery cache-file: "/var/lib/ntfy/cache.db" cache-duration: "24h" # Behind nginx/caddy reverse proxy behind-proxy: true # Attachment settings attachment-cache-dir: "/var/lib/ntfy/attachments" attachment-total-size-limit: "1G" attachment-file-size-limit: "10M" attachment-expiry-duration: "24h" # Logging log-level: "info" log-format: "json" # Rate limiting per visitor visitor-subscription-limit: 30 visitor-request-limit-burst: 60 visitor-request-limit-replenish: "5s" EOF cat > /etc/systemd/system/ntfy.service << 'EOF' # ntfy systemd service # Location: /etc/systemd/system/ntfy.service [Unit] Description=ntfy push notification server Documentation=https://ntfy.sh/docs/ After=network.target [Service] Type=simple User=ntfy Group=ntfy ExecStart=/usr/local/bin/ntfy serve --config /etc/ntfy/server.yml Restart=always RestartSec=5 # Security hardening NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=/var/lib/ntfy # Resource limits LimitNOFILE=65535 MemoryMax=512M [Install] WantedBy=multi-user.target EOF # Enable and start service echo "Enabling ntfy service..." systemctl daemon-reload systemctl enable ntfy systemctl start ntfy # Wait for service to start sleep 2 # Check status if systemctl is-active --quiet ntfy; then echo "✓ ntfy service is running" else echo "✗ ntfy service failed to start" systemctl status ntfy exit 1 fi echo "" echo "=== Setting up authentication ===" echo "" # Create admin user (skip if exists) echo "Creating admin user..." if ntfy user list 2>/dev/null | grep -q "^admin "; then echo "✓ admin user already exists" else ntfy user add --role=admin admin fi echo "" # Set access permissions for alert topics echo "Setting access permissions for alert topics..." ntfy access admin 'alerts-*' rw echo "✓ admin has rw access to alerts-*" echo "" echo "=== Next Steps ===" echo "" echo "1. Create user accounts for desktop clients:" echo " ntfy user add --role=user " echo " ntfy token add " echo "" echo "2. Grant topic access:" echo " ntfy access alerts-myapp ro # Read-only to app alerts" echo " ntfy access alerts-critical ro # Read-only to critical alerts" echo "" echo "3. Set up a reverse proxy (nginx/caddy) for ${DOMAIN}" echo " pointing to 127.0.0.1:8090" echo "" echo "4. Test with:" echo " curl -u admin: -d 'Test notification' http://127.0.0.1:8090/alerts-test" echo "" echo "=== Installation complete ==="