Commit 0bf8da10 authored by Pepijn Boers's avatar Pepijn Boers
Browse files

Update readme

parent 47b3c387
## Matomo behind reverse proxy.
# Matomo behind reverse proxy.
Let's create a reverse proxy with nginx, we're listening to port 80 and 443 and pass request to multiple matomo installations on different (local) ports.
"When NGINX proxies a request, it sends the request to a specified proxied server, fetches the response, and sends it back to the client."
We want to run two matomo servers, one that does respect DNT and one that does not. Since we want to compare their measures, they need to have their own database. Nginx configurations are stored in `nginx/nginx.conf`. Make sure to update the `server_name` and names of `ssl` certificate/key.
We have created a reverse proxy with nginx, which listens to port 80 and 443 and passes requests to multiple matomo installations.
### Matomo (no DNT)
name-matomo: app (5001:80 & 5002:443 - ssl not used internally)
## nginx config
Nginx has acces to ports 80 (HTTP) and 443 (HTTPS), but redirects all connections to port 443.
name-db: db
```
server {
listen 80 default_server;
server_name matomo.science.ru.nl www.matomo.science.ru.nl;
### Matomo (DNT)
name-matomo: app-dnt (5011:80 & 5012:443 - ssl not used internally)
# redirects both www and non-www to https
return 301 https://matomo.science.ru.nl$request_uri;
}
```
name-db: db-dnt
All traffic entering port 443 is encrypted and gets decrypted before moving to internal servers.
All containers are started using docker-compose, see the `docker-compose.yml`.
```
server {
listen 443 ssl;
server_name matomo.science.ru.nl www.matomo.science.ru.nl;
ssl_certificate /etc/ssl/private/matomo.science.ru.nl.crt;
ssl_certificate_key /etc/ssl/private/matomo.science.ru.nl.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
```
## update config/config.ini.php
Because the secure connection is handled by nginx we can assume that the protocol is secure and send to matomo over http. Add these rules to `config/config.ini.php`:
All traffic to `matomo.science.ru.nl` is handled by `location /`. Nginx's documentation metions that: "By default, NGINX redefines two header fields in proxied requests, “Host” and “Connection”, and eliminates the header fields whose values are empty strings.". So we manually set those headers to the correct values and pass all requests to our matomo installation under the name `app`.
```
[General]
assume_secure_protocol = 1
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://app;
}
```
Our second server (DNT) can be accessed via `matomo.science.ru.nl/dnt` and is configured in a similar way as the main server. Strip the '/dnt' from the original url, as we do not want to send requests to `app-dnt/dnt` but to `app-dnt/`:
[General]
proxy_client_headers[] = HTTP_X_FORWARDED_FOR
proxy_host_headers[] = HTTP_X_FORWARDED_HOST
```
location /dnt/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
rewrite ^/dnt(.*) /$1 break;
proxy_set_header X-Forwarded-Uri "/dnt";
proxy_pass http://app-dnt;
}
```
In the second installation (behind sub-path) add in `config/config.ini.php`:
Since the second server works from a subdirectory, we have to add this line to matomo's `config/config.ini.php` file to make sure the respones redirect clients to `/dnt`:
```
[General]
; Use the header HTTP_X_FORWARDED_URI to construct the current script name
proxy_uri_header = 1
```
## Start/stop everything using docker-compose
Use docker-compose to automatically restart failed containers:
JS tracking requests go to `/matomo.php`. We use the nginx (mirror module)[ngx_http_mirror_module] to duplicate the request and send it to our second server as well (only the original request gets a response). We have to adjust our proxy header again to store the client's original IP.
```
docker-compose up -d
location /matomo.php {
# duplicate request to /mirror
mirror /mirror;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://app$request_uri;
}
```
To stop everything type:
Somehow the proxy header forgot our settings (even if we mirror after setting proxy headers), so we have to set the proxy headers again in the mirror section.
```
location = /mirror {
internal;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $realip_remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://app-dnt$request_uri;
}
```
In order to let matomo know it is behind a reverse proxy we have to add some lines to the `config/config.ini.php` file in both installations, see this (faq)[https://matomo.org/faq/how-to-install/faq_98/]. Also we can assume our request are secure, because the connection client-proxy is over https, see illustration below.
<object data="img/setup/reverse_proxy.pdf" type="application/pdf" width="700px" height="700px">
<embed src="img/setup/reverse_proxy.pdf">
<p>This browser does not support PDFs. Please download the PDF to view it: <a href="http://yoursite.com/the.pdf">Download PDF</a>.</p>
</embed>
</object>
```
[General]
assume_secure_protocol = 1
proxy_client_headers[] = HTTP_X_FORWARDED_FOR
proxy_host_headers[] = HTTP_X_FORWARDED_HOST
```
## Matomo installations
The matomo servers depend on a:
- MySql database
- Config file: `config/config.ini.php`
- Plugin folder: `plugins`
Both servers, databases and the single proxy server live in their individual docker container and are created, started and managed by `docker-compose`. The exact setup can be found in (docker-compose.yml)[docker-compose.yml] and is started/stopped with:
```
docker-compose up -d
docker-compose stop
```
- to implement: [ngx_http_mirror_module](https://nginx.org/en/docs/http/ngx_http_mirror_module.html)
- [docker-compose 12 min tutorial](https://www.youtube.com/watch?v=Qw9zlE3t8Ko)
- [tutorial repo](https://github.com/jakewright/tutorials/tree/master/docker/02-docker-compose)
- [nginx and docker reverse proxy](https://www.youtube.com/watch?v=hxngRDmHTM0)
\ No newline at end of file
Note: The warning: `(skip warning) mbind: Operation not permitted` is silenced using (this)[https://stackoverflow.com/a/55706057] stack overflow suggestion. The problem is explained (here)[https://github.com/docker-library/mysql/issues/422#issue-320548753]
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment