Category Archives: Reverse proxy

Install and configure AWSTATS

General configuration

Using awstats to analyse your web usage statistics if your Apache webserver is running behind an Nginx reverse proxy server, needs some special configuration steps.

Install awstats on your system:

sudo apt install awstats

Enable the awstats apache configuration (and cgi if it is not enabled yet):

sudo a2enmod cgi
sudo a2enconf awstats

Restart the apache service:

sudo systemctl restart apache2

Edit the configuration awstats configuration file or create a configuration file for each virtual host. We are using combined log formats and need to configure this.

sudo cp /etc/awstats/awstats.conf /etc/awstats/awstats.www.mysite.com.conf 
sudo nano /etc/awstats/awstats.www.mysite.com.conf

Configure the virtual host log file path in your awstats configuration file. Make sure you select the correct one (might be the SSL log file).

LogFile="/var/log/apache2/www.mysite.com.access_log"
LogFormat=1

Configure the domain name and domain aliases:

SiteDomain="www.mysite.com"
HostAliases="mysite.com XYZ.mysite.com"

Optionally, if you want DNS lookup (conversing of IP’s into hostnames):

DNSLookup=1

Now update the awstats statistics folder by running the following command:

sudo /usr/lib/cgi-bin/awstats.pl -config=www.mysite.com -update 

Go to your awstats page:

https://www.mysite.com/cgi-bin/awstats.pl?config=www.mysite.com

Depending on your configuration, cgi-bin might need to be replaced by awstats.

Note on security: Make sure that your awstats statistics page is not visible from outside, even more if you are allowing your statistics to be updated through the web interface. I am forcing an htaccess realm through the Nginx reverse proxy on these directory.

If you want to update your statistics through the web interface, set the corresponding flag.

AllowToUpdateStatsFromBrowser=1

The following files have to be readable or writable by the apache service (www-data) user:

/var/lib/awstats (read & write)
/var/log/apache2/www.mysite.com.access_log (read)

Alternatively, add a crontab (edit /etc/crontab) entry:

* */15 * * * root /usr/lib/cgi-bin/awstats.pl -config=www.mysite.com -update > /dev/null

Configuration when running your web server behind an NGINX reverse proxy

Configure your reverse proxy correctly

In the NGINX reverse proxy configuration for your website, make sure you send the real IP-address of the client requesting your page through the header information to the web server. Add the following lines to the root location of your NGINX reverse proxy configuration for your web site (sudo nano /etc/nginx/sites-available/www.mysite.com). For more information on this, check here.

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;

Configure your web server to write the correct IP of the client into the log file (instead of the reverse proxy IP). Add the following to your apache virtual host file (sudo nano /etc/apache2/sites-available/www.mysite.com.conf):

RemoteIPHeader X-Real-IP
RemoteIPInternalProxy IP.PROXY.SERVER
RemoteIPTrustedProxy IP.PROXY.SERVER
RemoteIPHeader X-Forwarded-For
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

%{X-Forwarded-For}i replaces the first parameter in the combined log format, which normally is %h or %a. So if the LogFormat is set in your configuration file, make sure it has the above format.

Apache needs the remoteip module to be enabled in order to treat this information:

sudo a2enmod remoteip

To load the following module in the main Apache configuration file (sudo nano /etc/apache2/apache2.conf), delete the hash sign (#) before the following line:

LoadModule remoteip_module modules/mod_remoteip.so

Test the configuration and reload the apache service.

apache2ctl configtest
service apache2 restart

If you believe you have header issues and don’t know if the bug is on the level of the reverse proxy or the web server, check what header information is arriving at the web server.

Display the received headers (from reverse proxy) in html file

If you are running a reverse proxy server in front of your webserver, it might sometimes be useful to see which header variables are reaching your webserver. To achieve this, create the following headers.php file in the root of your webserver documents folder:

<?php
echo "<h1>Received Headers</h1>";
$headers =  getallheaders();
foreach($headers as $key=>$val){
  echo $key . ': ' . $val . '<br>';
}
echo "======================"
//echo '<pre>'; print_r($_SERVER); echo '</pre>';

?>

Home Assistant Nginx Proxy configuration

Here is a working NGINX proxy configuration for Home Assistant:

server {

    server_name HOST.DOMAIN.NAME;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        satisfy any;
        allow 10.X.X.0/24;
        allow 10.X.X.0/24;
        deny all;
        auth_basic              "Restricted access";
        auth_basic_user_file    /etc/passwords/passwords;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_headers_hash_max_size 512;
        proxy_headers_hash_bucket_size 128;
        proxy_pass http://INTERNAL_HOME_ASSISTANT_IP:8123;
        include proxy_params;
     }


    listen 443 ssl;

    ssl_certificate /etc/letsencrypt/live/HOST.DOMAIN.NAME/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/HOST.DOMAIN.NAME/privkey.pem; # managed by Certbot
}

server {
    if ($host = HOST.DOMAIN.NAME) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name HOST.DOMAIN.NAME;

}

Apache2: create Let’s encrypt certificate for SSL

Install the certbot:

apt install certbot python3-certbot-apache

Set the following in your vhost conf file:

ServerName mydomain.com
ServerAlias www.mydomain.com

Verify that your configuration is fine:

sudo apache2ctl configtest
sudo systemctl reload apache2

Make sure the dns entry in the external dns server points to your proxy server/web-server. Then launch the certification process:

sudo certbot --apache
sudo systemctl status certbot.timer
sudo certbot renew --dry-run

Note: nots ure about the last commands. Needs to be retested.

NGINX: create Let’s encrypt certificate for SSL

Before enabling SSL, make sure your vhost has been activated ( see instructions here: https://gilbert.busana.lu/?p=165 ).
If let’s encrypt’s certbot is not installed, proceed here:

sudo apt install certbot python3-certbot-nginx

To install the let’s encrypt certificate, you need to have your external DNS server pointing to your reverse-proxy/web-server. To install the certificates and have certbot modify your vhost config file for you, do:

sudo certbot --nginx -d www.mydomain.com

If failed, try:

certbot install --cert-name www.domain.com
nginx -t
systemctl restart nginx

If everything went well, your certificate is saved at: /etc/letsencrypt/live/www.mydomain.com/fullchain.pem
The key is saved at: /etc/letsencrypt/live/www.mydomain.com/privkey.pem
Certbot also modifies your vhost vonfiguration file and adds SSL on port 443 and redirects unencrypted (http) traffic to secure sockets (https). Check your configuration file here: /etc/nginx/sites-enabled/www.mydomain.com

NGINX: display reverse proxy headers

If you are having trouble with a web application sitting behind a reverse proxy, debugging can be facilitated by having your (backend) web-server displaying the headers that it receives.

<?php
echo “<h1>Headers received from the reverse proxy</h1>";
$headers =  getallheaders();
foreach($headers as $key=>$val){
  echo $key . ': ' . $val . '<br>';
}
?>
Commandparameter 1parameter 2output
proxy_set_headerX-Real-IP$remote_addr;IP Address of client
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;IP Address of client
proxy_set_headerX-Forwarded-Host$server_name;called vhost
proxy_set_headerX-Forwarded-Proto$scheme;https or http
proxy_set_header
Header commands and outputs

If you want to test how your page and headers look like from outside, call it from a site like https://testlocal.ly .

NGINX: HTTP basic authentication

The ngx_http_auth_basic_module module allows limiting access to resources by validating the user name and password using the “HTTP Basic Authentication” protocol.
Access can also be limited by address. Simultaneous limitation of access by address and by password is controlled by the satisfy directive.
Add the following to the vhost config file to limit access:

location / {
    auth_basic           “Restricted access";
    auth_basic_user_file /etc/nginx/passwords/passwords;
}

This enables validation of user name and password using the “HTTP Basic Authentication” protocol. The specified parameter is used as a realm. The special value off cancels the effect of the auth_basic directive inherited from the previous configuration level.
Specifies a file that keeps user names and passwords, in the following format:

# comment
name1:password1
name2:password2:comment
name3:password3

The following password types are supported:

  • encrypted with the crypt() function; can be generated using the “htpasswd” utility from the Apache HTTP Server distribution or the “openssl passwd” command;
  • hashed with the Apache variant of the MD5-based password algorithm (apr1); can be generated with the same tools;

Create password for first user:

htpasswd -c /etc/nginx/passwords/passwords paul

To add an additional user:

htpasswd /etc/nginx/passwords/passwords pierre

To allow per adddress:

location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
}

Allows access if all (all) or at least one (any) of the ngx_http_access_module, ngx_http_auth_basic_module, ngx_http_auth_request_module, or ngx_http_auth_jwt_module modules allow access.

location / {
    satisfy any;
    allow 192.168.1.0/24;
    allow 10.0.X.0/24;
    deny  all;

    auth_basic           "closed site";
    auth_basic_user_file conf/htpasswd;
}

Source: https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
Source: https://nginx.org/en/docs/http/ngx_http_access_module.html

NGINX: enable configuration

After creating a website or a reverse proxy vhost through the configuration file, the vhost has to be enabled:

ln -s /etc/nginx/sites-available/my.domain.com /etc/nginx/sites-enabled/my.domain.com

You can test the configuration file using the following command:

nginx -t

Do not forget to restart NGINX for the changes to be applied:

systemctl restart nginx

ATTENTION:
Always activate the vhost before generating the let’s encrypt SSL certificates. Failure to do so will result in having the default configuration file to be used which might result in the creation of two different vhosts using the same domain name. This will lead to one configuration being skipped on NGINX startup.

NGINX: redirect all HTTP traffic to HTTPS

To redirect all traffic from non secure to secure sockets layer (SSL), add the following lines to the virtual host config file in /etc/nginx/sites-available/my_vhost_config_file.

server {
    listen 80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

Explanations:

Listen 80: This instructs the system to catch all HTTP traffic on Port 80
Server_name _; : This will match any hostname
Return 301: This tells the browser (and search engines) that this is a permanent redirect
https://$host$request_uri: This is a short code to specify the HTTPS version of whatever the user has typed