88551536e6
Amp-Thread-ID: https://ampcode.com/threads/T-019cc404-c628-759e-a50b-f5eeea35b91f Co-authored-by: Amp <amp@ampcode.com>
190 lines
4.9 KiB
Bash
190 lines
4.9 KiB
Bash
#!/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 <username>"
|
|
echo " ntfy token add <username>"
|
|
echo ""
|
|
echo "2. Grant topic access:"
|
|
echo " ntfy access <username> alerts-myapp ro # Read-only to app alerts"
|
|
echo " ntfy access <username> 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:<password> -d 'Test notification' http://127.0.0.1:8090/alerts-test"
|
|
echo ""
|
|
echo "=== Installation complete ==="
|