Apache#

Server monitoring#

By changing the log format you can have a better idea of what is happening in real time to your web server without relying on external trackers. You can install programs that are able to read Apache’s logs in realtime.

See also

  • GoAccess - Visual Web Log Analyzer [1]

  • mod_log_config - Apache HTTP Server Version 2.4 [2]

  • Apache2 Reverse Proxy + GoAccess How To Guide · Issue #1789 · allinurl/goaccess · GitHub [3]

  1. install the dependencies

    apt-get install goaccess
    
  2. edit the log module setup in the main Apache configuration file. I added ServerName as variable and changed the date-time format to RFC3339.

    /etc/apache2/apache2.conf#
     1# [ ... ]
     2
     3<IfModule log_config_module>
     4   LogFormat "%v %h %l %u [%{%F %T}t %{%z}t] \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
     5   LogFormat "%v %h %l %u [%{%F %T}t %{%z}t] \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" common
     6   <IfModule logio_module>
     7       LogFormat "%v %h %l %u [%{%F %T}t %{%z}t] \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
     8   </IfModule>
     9   CustomLog "/var/log/apache2/access.log" common
    10</IfModule>
    11
    12# [ ... ]
    
  3. serve the html file via HTTP by creating a new Apache virtual host. Replace FQDN with the appropriate domain and include this file from the Apache configuration. You may notice that the reverse proxy configuration uses wss (WebSocket Secure) instead of ws (WebSocket)

    /etc/apache2/goaccess.apache.conf#
     1############
     2# goaccess #
     3############
     4<IfModule mod_ssl.c>
     5<VirtualHost 192.168.0.100:80>
     6    ServerName ${FQDN}
     7
     8    # Force https.
     9    UseCanonicalName on
    10    RewriteEngine on
    11    RewriteCond %{SERVER_NAME} =${FQDN}
    12
    13    # Ignore rewrite rules for 127.0.0.1
    14    RewriteCond %{HTTP_HOST} !=127.0.0.1
    15    RewriteCond %{REMOTE_ADDR} !=127.0.0.1
    16
    17    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
    18</VirtualHost>
    19</IfModule>
    20
    21<IfModule mod_ssl.c>
    22<VirtualHost *:443>
    23    UseCanonicalName on
    24
    25    Keepalive On
    26    RewriteEngine on
    27
    28    ServerName ${FQDN}
    29
    30    SSLCompression      off
    31
    32    RequestHeader set X-Forwarded-Proto "https"
    33    RequestHeader set X-Forwarded-Port "443"
    34    RequestHeader set X-Forwarded-Host "${FQDN}"
    35
    36    DocumentRoot "/srv/http/${FQDN}"
    37    <Directory "/srv/http/${FQDN}">
    38        Options -ExecCGI -Includes -indexes
    39        # Localhost.
    40        AllowOverride None
    41
    42        #
    43        # Controls who can get stuff from this server.
    44        #
    45        Require all granted
    46    </Directory>
    47
    48    <Location "/">
    49        Require ip 127.0.0.1
    50        Require ip 192.168.0.
    51    </Location>
    52
    53    SSLProxyEngine On
    54    SSLProxyVerify None
    55    SSLProxyCheckPeerCN Off
    56    SSLProxyCheckPeerName Off
    57
    58    ProxyRequests On
    59
    60    # keep the host
    61    ProxyPreserveHost On
    62
    63        RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
    64        Header always set Strict-Transport-Security "max-age=15552000; preload"
    65        Header always set X-Content-Type-Options nosniff
    66        Header always set X-Robots-Tag none
    67        Header always set X-XSS-Protection "1; mode=block"
    68        Header always set X-Frame-Options "SAMEORIGIN"
    69        Header always set Referrer-Policy "strict-origin-when-cross-origin"
    70
    71    ProxyPass /wss/ wss://127.0.0.1:7890
    72    ProxyPassReverse /wss/ wss://127.0.0.1:7890
    73
    74    Include /etc/letsencrypt/options-ssl-apache.conf
    75    SSLCertificateFile /etc/letsencrypt/live/${FQDN}/fullchain.pem
    76    SSLCertificateKeyFile /etc/letsencrypt/live/${FQDN}/privkey.pem
    77</VirtualHost>
    78</IfModule>
    
  4. create the jobs directories and files

    mkdir -p /home/jobs/scripts/by-user/root/goaccess/goaccess.db
    chmod 700 /home/jobs/scripts/by-user/root/goaccess
    
  5. run the program manually without the configuration to check if the supplied formats are working correctly. This command open a curses terminal. Press q to quit

    goaccess /var/log/apache2/access.log \
    --log-format='%v %h %l %u %^[%d %t %^] \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"' \
    --date-format="%F" \
    --time-format="%T"
    
  6. use this configuration file as example. You can find all the options in Debian’s provided configuration file at /etc/goaccess/goaccess.conf

    /home/jobs/scripts/by-user/root/goaccess/goaccess.conf#
     1time-format %T
     2date-format %F
     3log-format %v %h %l %u %^[%d %t %^] "%r" %>s %b "%{Referer}i" "%{User-Agent}i"
     4color-scheme 3
     5config-dialog false
     6hl-header true
     7html-prefs {"theme":"bright","perPage":5,"layout":"horizontal","showTables":true,"visitors":{"plot":{"chartType":"bar"}}}
     8html-report-title GoAccess Stats
     9json-pretty-print true
    10no-color false
    11no-column-names false
    12no-csv-summary false
    13no-progress false
    14no-tab-scroll false
    15with-mouse false
    16addr 127.0.0.1
    17origin https://${FQDN}
    18port 7890
    19pid-file /var/run/goaccess.pid
    20real-time-html true
    21ws-url wss://${FQDN}:443/wss/
    22agent-list true
    23with-output-resolver true
    24http-method yes
    25http-protocol yes
    26no-query-string false
    27no-term-resolver false
    28444-as-404 false
    294xx-to-unique-count false
    30all-static-files false
    31double-decode false
    32ignore-crawlers false
    33crawlers-only false
    34real-os true
    35ssl-cert /etc/letsencrypt/live/${FQDN}/fullchain.pem
    36ssl-key /etc/letsencrypt/live/${FQDN}/privkey.pem
    37exclude-ip 192.168.0.1-192.168.0.254
    38exclude-ip 172.16.0.0-172.31.255.255
    39exclude-ip 127.0.0.1
    40persist true
    41restore true
    42db-path /home/jobs/scripts/by-user/root/goaccess/goaccess.db
    

    Note

    Replace FQDN with appropriate value.

  7. create a Systemd unit file

    /home/jobs/services/by-user/root/goaccess.service#
     1[Unit]
     2Requires=network-online.target
     3After=network-online.target
     4
     5[Service]
     6Type=simple
     7WorkingDirectory=/home/jobs/scripts/by-user/root/goaccess
     8Restart=always
     9ExecStart=/usr/bin/goaccess /var/log/apache2/access.log -a -p goaccess.conf -o /srv/http/${FQDN}/index.html
    10
    11[Install]
    12WantedBy=multi-user.target
    

    Note

    Replace FQDN with appropriate value.

  8. run the deploy script

Footnotes