Skip to content

Latest commit

 

History

History
151 lines (115 loc) · 7.13 KB

README.md

File metadata and controls

151 lines (115 loc) · 7.13 KB

Let's Block It server

As an alternative to the official instance and the render CLI, experienced administrators can self-host a server instance themselves. This documentation assumes good knowledge of self-hosting, and "easy install" methods will not be provided or supported by the project.

You will need:

  • The server binary, either the container image or a binary built from this repository,
  • A PostgreSQL 14 database and a role with sufficient privileges on it,
  • An authentication and authorization provider.

Running the server

a. Using the container image

The container image for the server is published as ghcr.io/letsblockit/server:latest on the GitHub container registry. We recommend you use the latest tag and pull it regularly to get filter updates and fixes.

  • All the options can be set via environment variables. Run docker run ghcr.io/letsblockit/server:latest server --help for an exhaustive list, read the rest of this document for the most important ones.
  • While the default value of LETSBLOCKIT_ADDRESS is shown as localhost (not serving on public interfaces), the container image overrides this with LETSBLOCKIT_ADDRESS=:8765 (all network interfaces) by default, to be reachable from your proxy container.

b. As a systemd unit

Static binaries are not published for now, but they can be built with go build ./cmd/server. NixOS users can use the server flake output, which powers the official instance.

Click here for an example systemd unit definition passing options as envvars.
[Unit]
After=postgresql.service
Description=letsblock.it server

[Service]
Environment="LETSBLOCKIT_AUTH_PROXY_HEADER_NAME=X-Auth-Request-User"
Environment="LETSBLOCKIT_AUTH_METHOD=proxy"
Environment="LETSBLOCKIT_DATABASE_URL=postgresql:///letsblockit"
ExecStart=/location/to/lbi/server
Restart=always
User=letsblockit
WorkingDirectory=/tmp
  • All the options can be set via environment variable. Run server --help for an exhaustive list, read the rest of this document for the most important ones.
  • By default, the server listens to localhost only, on the port 8765, assuming a reverse-proxy will sit on front of it. You can adjust LETSBLOCKIT_ADDRESS, or create a systemd socket and set LETSBLOCKIT_USE_SYSTEMD_SOCKET=true

PostgreSQL database

Lists and filter instances are stored in a PostgreSQL 14 database. The project is tested against version 14, and support for older versions is not guaranteed. You should provision a dedicated role and database for the server, with: CREATE USER letsblockit; CREATE DATABASE letsblockit OWNER letsblockit;

The LETSBLOCKIT_DATABASE_URL must be set with a valid connection string, usually a URI in the postgresql://user:password@host/database form, see the PSQL documentation for more details.

The server will create tables and run migrations automatically on startup, thanks to the golang-migrate project. You can look for the log lines starting with migrate[ during startup. Rollbacks are not supported, so we recommend you back up your database before upgrading the server.

Authentication and authorization

The server does not include user management, because I do not trust myself to write a secure implementation. Instead, the official instance relies on Ory Cloud, and an authenticating reverse-proxy can be used for self-hosted scenarios. Any authenticating reverse-proxy setup should work, assuming:

  • The requests to the /list/ prefix pass through without authentication, to allow for lists to be downloaded by the adblocker
  • All the other requests are authenticated, and a unique property of the user (username, email, UUID) is passed down as an HTTP Header

The simplest setup would use HTTP Basic auth and a static user list, but you can also use most identity providers (Authelia, Authentik, Keycloak, Oauth2 Proxy...), either as reverse-proxies or with forward authentication.

Some examples are documented below, but you can open an issue for configuration assistance on other setups.

HTTP basic authentication with Nginx

Create a htpasswd file following the documentation then configure your vhost accordingly:

location /list {  #  No auth for list download
    proxy_pass http://letsblockit:8765;
}
location / {  #  Basic auth for the rest
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/htpasswd;
    proxy_pass http://letsblockit:8765;
    proxy_set_header X-Forwarded-User $remote_user;
}

You can then run the server with the following variables:

  • LETSBLOCKIT_AUTH_METHOD=proxy
  • LETSBLOCKIT_AUTH_PROXY_HEADER_NAME=X-Forwarded-User

HTTP basic authentication with Traefik

You should read the basicauth middleware doc and make sure headerField is set. Here is an example envvars and labels for a letsblockit container, for Traefik listening on localhost, and the test:test and test2:test2 users:

environment:
    - LETSBLOCKIT_AUTH_METHOD=proxy
    - LETSBLOCKIT_AUTH_PROXY_HEADER_NAME=X-Forwarded-User
labels:
    # Allow access to list downloads without authentication
    - "traefik.http.routers.lbi-noauth.rule=Host(`localhost`) && PathPrefix(`/list/`)"
    # Authenticate the rest of the endpoints with basic auth and pass X-Forwarded-User
    - "traefik.http.routers.lbi.rule=Host(`localhost`)"
    - "traefik.http.routers.lbi.middlewares=lbi-auth"
    - "traefik.http.middlewares.lbi-auth.basicauth.headerField=X-Forwarded-User"
    - "traefik.http.middlewares.lbi-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"

OAuth2 authentication with OAuth2 Proxy

This proxy has been tested with letsblockit and can be used with a long list of providers.

  • Run the server with
    • LETSBLOCKIT_AUTH_METHOD=proxy
    • LETSBLOCKIT_AUTH_PROXY_HEADER_NAME set to either X-Forwarded-Email or X-Forwarded-User depending on your provider
  • Set the following options in oauth2-proxy's configuration:
pass_user_headers = true
skip_auth_routes = [ "GET=^/list/" ]

Warning: when using an external identity provider, anyone with an account on that platform can login by default. Check out the per-provider configuration options for details on restricting access to specific users / groups.

Using a self-hosted Kratos or Ory Cloud

Running with a self-hosted Kratos or even Ory Cloud should work (you'll need to set LETSBLOCKIT_AUTH_METHOD to kratos and LETSBLOCKIT_AUTH_KRATOS_URL). Don't hesitate to open an issue for assistance configuring Kratos itself.