# Fix Apache mod_status Page Not Accessible From Remote Hosts

You enable Apache's mod_status module to monitor server performance, but when you try to access https://example.com/server-status from your workstation, you get a 403 Forbidden error. The module is loaded, the configuration is present, but access is denied.

The Default Configuration

The default mod_status configuration restricts access to localhost only:

apache
<Location "/server-status">
    SetHandler server-status
    Require local
</Location>

Require local allows access only from 127.0.0.1, ::1, and localhost. Any request from a remote IP address is denied.

Allowing Access From Specific IPs

To monitor Apache from a remote workstation, add your IP address:

apache
<Location "/server-status">
    SetHandler server-status
    Require local
    Require ip 203.0.113.50
    Require ip 10.0.0.0/8
</Listing>

Or more concisely:

apache
<Location "/server-status">
    SetHandler server-status
    Require ip 203.0.113.50 10.0.0.0/8 127.0.0.1
</Location>

Important: Never use Require all granted for server-status. It exposes detailed information about every active connection, including client IP addresses, request URLs, and server load. This is sensitive operational data.

Enabling Extended Status

To get detailed information about each request (URL, client IP, processing time), enable extended status:

apache
ExtendedStatus On

This must be set in the main server configuration (not in a VirtualHost or .htaccess). Without it, server-status shows only basic worker information without request details.

Verifying mod_status Is Loaded

bash
apache2ctl -M | grep status

If not listed:

bash
sudo a2enmod status
sudo systemctl reload apache2

The server-status Query Parameters

The server-status page supports several query parameters:

```bash # Auto format (machine-readable) curl -s http://localhost/server-status?auto

# Show all workers including idle ones curl -s http://localhost/server-status?refresh=5

# JSON format (Apache 2.4.43+) curl -s http://localhost/server-status?json ```

The ?auto format is ideal for monitoring scripts:

bash
Total Accesses: 145234
Total kBytes: 892341
Uptime: 86400
ReqPerSec: 1.68
BytesPerSec: 10560
BytesPerReq: 6284
BusyWorkers: 12
IdleWorkers: 38
ConnsTotal: 45
ConnsAsyncWriting: 3
ConnsAsyncKeepAlive: 28
ConnsAsyncClosing: 2

Monitoring Script Using server-status

```bash #!/bin/bash # apache-monitor.sh

URL="http://localhost/server-status?auto" busy=$(curl -s "$URL" | grep "BusyWorkers" | awk '{print $2}') idle=$(curl -s "$URL" | grep "IdleWorkers" | awk '{print $2}') total=$((busy + idle)) pct=$((busy * 100 / total))

echo "$(date): Workers $busy/$total (${pct}% busy)"

if [ $pct -gt 80 ]; then echo "ALERT: Apache worker utilization above 80%" fi

# Log to file echo "$(date +%Y-%m-%dT%H:%M:%S) busy=$busy idle=$idle pct=$pct" >> /var/log/apache-monitor.log ```

Run this every minute via cron:

bash
* * * * * /usr/local/bin/apache-monitor.sh

Security Considerations

The server-status page reveals: - Client IP addresses of all active connections - Full request URLs being processed - Virtual server handling each request - Response sizes and processing times - Server uptime and total request count

Restrict access to trusted monitoring IPs only. If using a monitoring service (Datadog, New Relic, etc.), add their IP ranges to the Require ip list.

For automated monitoring from the same server, use Require local with a cron script that posts metrics to your monitoring system, rather than allowing remote access to server-status.