Featured image of post Use Umami to build a source analysis server and avoid the security issue of Umami ApiKey being leaked

Use Umami to build a source analysis server and avoid the security issue of Umami ApiKey being leaked

This article applies to self-built Umami servers.

In the past two days, I added source analysis to the website, and the number of clicks is displayed in the article title. The analysis platform used is Umami.

Docker Compose

Here we use the postgresql version of the image ghcr.io/umami-software/umami:postgresql-latest

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    container_name: umami
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:umami@db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: <your secret string>
    depends_on:
      db:
        condition: service_healthy
    init: true
    restart: unless-stopped
  db:
    image: postgres:15-alpine
    container_name: umami_db
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: umami
    volumes:
      - db:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
      interval: 5s
      timeout: 5s
      retries: 5
volumes:
  db:

Reverse Proxy

Then use nginx for service reverse proxy (this step is more important, and request filtering will be performed later to solve security issues)

1
2
3
4
5
6
7
8
9
server {
  listen 80;
  server_name u.example.com;

  location / {
    include proxy_pass.conf;  # Here we introduce the predefined proxy request header
    proxy_pass http://127.0.0.1:3000;
  }
}

Now our service is set up, and we can use Cloudflare Tunnel to pass the service to your domain name.

Security Question

But a problem arises. In order for a static website to obtain URL clicks, it is necessary to store the token in the front-end page (or use Cloudflare Worker to circumvent it, which we will not go into here for the time being). How to prevent other users from logging into the management page of the Umami site after obtaining the token?

A simple method is to whitelist the specified URL requests. We count and check the request addresses used, only /script.js, /api/send, /api/websites/<id>/stats, so we filter them in the nginx reverse generation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server {
  ...

  location ~ ^/(script.js|api/send|api/websites/[0-9a-f-]+/stats)$ {
    inclue proxy_pass.conf;
    proxy_pass http://127.0.0.1:3000;
  }

  location / {
    return 404;
  }
}

New Problem

This solves our security problem, but we can only log in and view statistics in the intranet environment.

In the next article, we will use Cloudflare Worker to wrap stats requests to completely solve this problem, and no longer limit self-built servers.

Built with Hugo
Theme Stack designed by Jimmy