Skip to main content

Apache Webserver

Apache 2.4 and above have slightly different ACL syntax, so this page covers how you can use Knocknoc to manage ACLs. The script for managing Apache ACLs as per this document was added to knocknoc-agent in version 1.0.31

Setup for your Apache webserver

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

Install Knocknoc Agent, and enrol it in your Knocknoc server.

Sudo setup

Your sudoers file needs to contain the following:

knocknoc-agent ALL=(ALL) NOPASSWD: systemctl reload apache2

or for Redhat based systems:

knocknoc-agent ALL=(ALL) NOPASSWD: systemctl reload httpd

in /etc/sudoers.d/knocknoc-agent

Apache ACL setup

mkdir /etc/apache2/acl

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

then touch /etc/apache2/acl/librenms_acl.conf as an example.

Sample Apache config for LibreNMS

A sample config file for apache2.4 for librenms. Please adapt it to your needs for whatever virtual host you may require.
Note the Include needs to be in a <Directory> section.

<VirtualHost *:80>
    ServerName librenms.domain.com
    # Redirect HTTP to HTTPS
    Redirect permanent / https://librenms.domain.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName librenms.domain.com
    DocumentRoot /opt/librenms/html
    DirectoryIndex index.php

    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/star.domain.com.crt
    SSLCertificateKeyFile /etc/apache2/ssl/star.domain.com.key


    # Enable gzip compression
    # Note: Apache needs mod_deflate enabled.
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript
    </IfModule>

    # PHP processing
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php-fpm-librenms.sock|fcgi://localhost"
    </FilesMatch>

    # Rewrite rules
    <Directory /opt/librenms/html>
        AllowOverride All
        Require all granted
        
        # Deny access to dot files
        <FilesMatch "/\.(?!well-known).*">
            Require all denied
        </FilesMatch>

        # URL rewriting
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^ index.php [QSA,L]

        # Knocknoc manages this ACL
        Include /etc/apache2/acl/librenms_acl.conf

    </Directory>

</VirtualHost>

Knocknoc Agent Script

The script:

#!/bin/bash
# Update the following line to the correct directory based on your Apache installation
# need to mkdir /etc/apache2/acl and chown it to the appropriate user

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

# Ensure the ACL file path is absolute, starts with your Apache config path, and prevent directory traversal
if [[ ! "$ACL_FILE" =~ ^/etc/apache2/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_apache() {
    # Check for Debian-based systems like Ubuntu
    if [ -f /etc/debian_version ]; then
        echo "Detected Debian-based system"
        sudo systemctl reload apache2
    # Check for Red Hat-based systems like CentOS, Fedora, or RHEL
    elif [ -f /etc/redhat-release ]; then
        echo "Detected Red Hat-based system"
        sudo systemctl reload httpd
    # Fallback if system is neither Red Hat nor Debian-based, try using apache2 first
    else
        echo "Attempting to reload Apache using apache2"
        if ! sudo systemctl reload apache2 2>/dev/null; then
            echo "Failed, attempting to reload Apache using httpd"
            sudo systemctl reload httpd
        fi
    fi
}


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

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

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

Knocknoc Server Setup

The backend config is as follows, selecting the name of the agent above.

image.png

And the ACL config like so, to match the script and Apache config above:

image.png