Category Archives: Webserver

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>';

?>

peerTube administration

Upgrade

Run the upgrade script:

cd /var/www/peertube/peertube-latest/scripts && sudo -H -u peertube ./upgrade.sh
sudo systemctl restart peertube

Update peerTube configuration

Check for configuration changes, and report them in your config/production.yaml file

cd /var/www/peertube/versions
diff -u "$(ls --sort=t | head -2 | tail -1)/config/production.yaml.example" "$(ls --sort=t | head -1)/config/production.yaml.example"

Source: https://docs.joinpeertube.org/install/any-os

Execute Nextcloud OCC commands

Go to /var/www/html and execute the following command as the http user:

sudo -u www-data php occ db:add-missing-indices
sudo -u www-data php occ translate:download-models
sudo -u www-data php occ maintenance:mode --off 
sudo nextcloud.occ files:scan --all
sudo nextcloud.occ maintenance:repair
sudo -u www-data php occ -h

Running you own Matrix-Synapse server

We are setting up a matrix-synapse instance on our homeserver using an Ubuntu 22.04 VM. Most of these instructions were collected from the official documentation on github. We want to have our domain (example.com) responding for our matrix handle (e.g. @john:example.com), not the hostname (matrix.example.com) of the server.

Installation of Matrix-synapse

First install some packages we’ll need:

sudo apt install -y lsb-release wget apt-transport-https

Now add the keyrings and the repository for matrix-synapse server:

sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" |
    sudo tee /etc/apt/sources.list.d/matrix-org.list

Now update your apt repositories:

sudo apt update

And install matrix-synapse

sudo apt install matrix-synapse-py3

When asked for the server name, we enter example.com . For further informations on this, consult the first chapter of the installation instructions: Choosing your server name. Decide if you want to have homeserver usage statistics and you are done.

Setting up Synapse

Install PostgreSQL

sudo apt install postgresql

Select your geographic area. Done. Install the libpq5 libraries:

apt install libpq5

To set up the database, you need to be logged in as the postgres user:

sudo -u postgres bash

Create the synapse user

createuser --pwprompt synapse_user

Create a safe password and note it down. Create the database:

createdb --encoding=UTF8 --locale=C --template=template0 --owner=synapse_user synapse

Let’s enable password authentication so that synapse_user can connect to the database:

cd /etc/postgresql/14/main
nano pg_hba.conf

Add the (last) line for the synapse_user as follows to the pg_hba.conf file. As we use local, you do not need to provide an address (leave the fourth column empty). Save and exit.

local   replication   all                                peer
host    replication   all        127.0.0.1/32            scram-sha-256
host    replication   all        ::1/128                 scram-sha-256
local   synapse       synapse_user                       scram-sha-256

Exit the shell for postgres user and fall back to your standard user:

exit

Configure synapse to use postgreSQL

cd /etc/matrix-synapse
nano homeserver.yaml

Modify the database parameters in homeserver.yaml to match the following, save and exit.

database:
  name: psycopg2
  args:
    user: synapse_user
    password: <password>
    database: synapse
    host: localhost
    cp_min: 5
    cp_max: 10

Make sure that postgreSQL starts on boot. Open the postgres.conf file:

cd /etc/postgresql/14/main
nano postgresql.conf

Under Connection Settings, uncomment (delete the hash sign) the following line:

#listen_addresses = 'localhost' 

Save, exit. Now let’s restart matrix-synaose and the postgres service.

systemctl restart postgresql
systemctl restart matrix-synapse

For more information or debugging, consult the official documentation.

TLS certificates and reverse proxy setup

We assume that you have a functioning Nginx server. We set up two (see first paragraph of this page for the reason) basic reverse proxy configuration files in /etc/nginx/sites-available, one for the matrix server (matrix.example.com) and one for the domain itself (example.com), using the default files provided. Create the SSL certificates (do not forget to enable the sites first). Do not forget to point the corresponding DNS records to your reverse proxy and allow the firewall to let the incoming connections (port 80 & 443) through.

The matrix.example.com sites configuration file should look like this:

server {

    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/matrix.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/matrix.exmaple.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


    server_name matrix.example.com;
    access_log /var/log/nginx/matrix.example.com.access.log;
    error_log /var/log/nginx/matrix.example.com.error.log;

   location ~ ^(/|/_matrix|/_synapse/client) {
        # note: do not add a path (even a single /) after the port in `proxy_pass`,
        # otherwise nginx will canonicalise the URI and cause signature verification
        # errors.
        proxy_pass http://<IP OF SYNAPSE SERVER>:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;

        # Nginx by default only allows file uploads up to 1M in size
        # Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
        client_max_body_size 50M;

    # Synapse responses may be chunked, which is an HTTP/1.1 feature.
    proxy_http_version 1.1;
    }

}


server {
    if ($host = matrix.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;

    server_name matrix.example.com;
    return 404; # managed by Certbot

}

The example.com sites configuration file should look like this:

server {

    server_name example.com;
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

# the root folder should redirect to your regular website under your domain name (if needed)
location / {

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_headers_hash_max_size 512;
        proxy_headers_hash_bucket_size 128;
        proxy_pass http://<WEBSERVER>;
        include proxy_params;
     }

location /.well-known/matrix/client {
    return 200 '{"m.server": "matrix.example.com:443"}';
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
}

location /.well-known/matrix/server {
    return 200 '{"m.server": "matrix.example.com:443"}';
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
}
}


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


    listen 80;

    server_name example.com;
    return 404; # managed by Certbot


}

When configuring your client, use the matrix.example.com URL. The .well-known json message is used by other matrix servers that want to connect to your server. They will be informed that they should use a different hostname than the one provided by the user’s handles. More information is available in the official delegation documentation.

The official documentation states that port 8448 should be open for federation and also listened to by the reverse proxy, but our configuration works fine without it. Maybe the other matrix servers also try port 443 if 8448 is not available?

If your reverse proxy is running on a different machine than the synapse server, than you have to adjust the listeners bind_addresses in the /etc/matrix-synapse/homeserver.yaml to the following. Do not forget to restart the matrix service after saving the changes.

bind_addresses: ['::1', '0.0.0.0']

Test delegation / federation using the Matrix Federation Tester.

Adding a Matrix user

In order to be able to add users, you need to define the registration shared secret in the /etc/matrix-synapse/homeserver.yaml file. Add the following line at the end, generating some random salt. Restart the matrix service afterwards.

registration_shared_secret: YOURRANDOMSALTSTRING

Now add a user, using the following command:

register_new_matrix_user -u john -c /etc/matrix-synapse/homeserver.yaml -a https://matrix.example.com
-u, --user
Local part of the new user. Will prompt if omitted.
-p, --password
New password for user. Will prompt if omitted. Supplying the password on the command line is not recommended. Use the STDIN instead.
-a, --admin
Register new user as an admin. Will prompt if omitted.
-c, --config
Path to server config file containing the shared secret.
-k, --shared-secret
Shared secret as defined in server config file. This is an optional parameter as it can be also supplied via the YAML file.
server_url
URL of the home server. Defaults to ´https://localhost:8448´.

Use a matrix client (e.g. https://app.element.io) to test your server and user. Have fun!

Installing SearXNG

If you want to use a meta-search engine that does not track you, SearXNG is an excellent possibility.

To install SearXNG on Ubuntu, I chose to go the docker way described in the official instructions. Unfortunately, I run into some issues, thus deciding to setting up this extended tutorial. I assume you have docker and docker-compose installed.

Step 1: Get searxng-docker

cd /usr/local
git clone https://github.com/searxng/searxng-docker.git
cd searxng-docker

Step 2: Set hostname

Edit the .env file living in the root foled. Be aware that it is hidden. to see the file, you need to use ls -la. Edit the file with: nano .env

# By default listen on https://localhost
# To change this:
# * uncomment SEARXNG_HOSTNAME, and replace <host> by the SearXNG hostname
# * uncomment LETSENCRYPT_EMAIL, and replace <email> by your email (require to create a Let's Encrypt certificate)

SEARXNG_HOSTNAME=searxng.mysite.com
LETSENCRYPT_EMAIL=myaddress@mysite.com

Step 3: Generate your secret key.

sed -i "s|ultrasecretkey|$(openssl rand -hex 32)|g" searxng/settings.yml

You can see your new key in searxng/settings.yml .

Step 4: Adjust IP & port

To change the IP address and port, you need to edit the docker-compose yaml file.
nano docker-compose.yml.
Find the searxng chapter and change the 127.0.0.1:8080/8080 to whatever you prefer. Leaving the standard values (with no port collisions) left me without the ability to access the searXNG engine. So I replaced 127.0.0.1 by 0.0.0.0.

  searxng:
    container_name: searxng
    image: searxng/searxng:latest
    networks:
      - searxng
    ports:
     - "0.0.0.0:8888:8080"

Step 5: Bring searXNG up

Check that everything is working

docker-compose up

Start the daemon in the background with:

docker-compose up -d

If you want your searXNG engine to start on boot you need to start it with systemd.

cp searxng-docker.service.template searxng-docker.service
systemctl enable $(pwd)/searxng-docker.service
systemctl start searxng-docker.service

Run through reverse proxy (optional)

To avoid using a port number in the URL, I have my NGINX reverse proxy forwarding all requests to the docker image. As I then ran into the “too many requests” error, I had to set the limiter to false in the searxng/settings-yml file . If you want to run your instance outside your intranet, you should definitely protect your searXNG instance with an authentication method to avoid having your server flooded with un uncontrollable amount of requests.

searXNG accessed through reverse proxy

To see what containers are running

docker container list

It should list your searXNG container:

CONTAINER ID   IMAGE                     COMMAND                  CREATED             STATUS              PORTS                    NAMES
YOUR_ID        searxng/searxng:latest    "/sbin/tini -- /usr/…"   43 minutes ago      Up 43 minutes       0.0.0.0:8888->8080/tcp   searxng     

Consulting log files

To display the logs of all your running containers, use:

docker-compose logs -f

If you want to only display the logs of one of the specific containers used for searXNG, use one of the following commands:

docker-compose logs -f caddy
docker-compose logs -f searxng
docker-compose logs -f redis

Updating searXNG

To update your searXNG instance, do the following:

docker-compose pull
docker-compose down
docker-compose up

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: 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.