Skip to main content

Nginx via script

Nginx support via script was added in knocknoc-agent version 1.0.30. This allows for flexible ACL management from Knocknoc server for nginx.

Setup for the Nginx server

To get started, make sure you have knocknoc-agent version 1.0.30 or above installed.

The following example shows how you can use Knocknoc to block access to Librenms, only allowing it once users have authenticated. Please adapt it to whatever virtual hosting config suits your needs. 

SSH to your nginx server machine, and carry out the following steps

Sudo setup

Your sudoers file needs to contain the following:

knocknoc-agent ALL=(ALL) NOPASSWD: /usr/sbin/nginx -s reload

in /etc/sudoers.d/knocknoc-agent

ACL Setup

mkdir /etc/nginx/acl

and chown knocknoc-agent /etc/nginx/acl/

then touch /etc/nginx/acl/librenms.acl as an example.

Nginx Config file

A sample nginx config file for librenms is as follows:

server {
 listen      80;
 server_name librenms.domain.com;
 return 301 https://$host$request_uri;
}

server {
 listen 443 ssl;
 server_name librenms.domain.com;
 root        /opt/librenms/html;
 index       index.php;

 ssl_certificate     /etc/nginx/ssl/star.domain.com.crt;
 ssl_certificate_key /etc/nginx/ssl/star.domain.com.key;

# Knocknoc manages this ACL
 include /etc/nginx/acl/librenms.acl;

 charset utf-8;
 gzip on;
 gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
 location / {
  try_files $uri $uri/ /index.php?$query_string;
 }
 location ~ [^/]\.php(/|$) {
  fastcgi_pass unix:/var/run/php/php-fpm-librenms.sock;
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  include fastcgi.conf;
 }
 location ~ /\.(?!well-known).* {
  deny all;
 }

}

Then, when a user with right ACL allocated logs in to knocknoc, they get added to the librenms ACL. Note that the script ensures all IPs are blocked by default.

Knocknoc-agent nginx ACL script

Here is a copy of the script, and of course you can modify this to behave as you desire.

#!/bin/bash
# need to mkdir /etc/nginx/acl and chown it knocknoc-agent

ACTION=$1
ACL_FILE=$2
IP=$3

# Ensure the ACL file path is absolute, starts with /etc/nginx/, and prevent directory traversal
if [[ ! "$ACL_FILE" =~ ^/etc/nginx/acl/.*$ ]] || [[ "$ACL_FILE" =~ \.\. ]]; then
    echo "Invalid ACL file path."
    exit 1
fi

# Validate IP address format for add and del actions
if ! [[ $IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && [ "$ACTION" != "flush" ]; then
    echo "Invalid IP address format."
    exit 1
fi

reload_nginx() {
    sudo /usr/sbin/nginx -s reload
}

ensure_deny_all() {
    # Ensure "deny all;" is always the last line of the file
    if ! tail -n1 "$ACL_FILE" | grep -q "deny all;"; then
        echo "deny all;" >> "$ACL_FILE"
    fi
}

case $ACTION in
    add)
        # Prevent adding an IP if it already exists
        if grep -q "allow $IP;" "$ACL_FILE"; then
            echo "IP already allowed."
        else
            # Insert the allow rule before the last line (deny all;)
            sed -i "$ i\allow $IP;" "$ACL_FILE"
            reload_nginx
        fi
        ;;
    del)
        # Only remove the IP if it exists
        if grep -q "allow $IP;" "$ACL_FILE"; then
            sed -i "/allow $IP;/d" "$ACL_FILE"
            reload_nginx
        else
            echo "IP not found."
        fi
        ;;
    flush)
        # Reset the file to only contain "deny all;"
        echo "deny all;" > "$ACL_FILE"
        reload_nginx
        ;;
    *)
        echo "Usage: $0 {add|del|flush} <ACL_FILE> <IP>"
        echo "Example: $0 add /etc/nginx/acl/librenms.acl 192.168.1.100"
        echo "Note: IP argument is not needed for 'flush' action."
        exit 1
        ;;
esac

# Ensure "deny all;" is properly placed at the end of the file for all actions except flush
if [ "$ACTION" != "flush" ]; then
    ensure_deny_all
fi

Knocknoc Admin config

First you need to configure the Backend to choose your librenms agent, and map it to the backend type of script, and enter the path to the nginx-acl.sh script like below:

image.png

The ACL config for the above script is as follows. Note this allows for other ACLs to be updated, for example for other virtual hosts, just by changing the ACL name to the path of the ACL file to be updated.

image.png

Then you would simply map this ACL into the relevant group of users, and those users will have their IP added to the librenms ACL on login.