35 Setup Reverse Proxy
scrapix edited this page 2023-11-15 09:56:39 +01:00

Reverse Proxy

Reverse proxy configuration examples for apache, nginx and IIS (on Windows) to use Calibre-Web:

Login via Header from Upstream Authentication Source

If your reverse proxy has some kind of authentication mechanism, you can configure Calibre-Web to log users in based on headers received from the proxy. If using this feature, it's important that only the proxy is exposed to users, because if the Calibre-Web instance is at all directly exposed to traffic, then a malicious user will be able to log in as any user that exists via simply setting a header.

In the admin configuration, check the box marked Allow Reverse Proxy Authentication, and then fill in the text box that appears with the name of the header that will contain the username. If you pass a username that isn't present in the database, nothing will happen - the user must exist beforehand in order to login.

Table of contents

  1. nginx
  2. Nginx Proxy Manager
  3. Apache 2.4
  4. Internet Information Service IIS 10
  5. Lighttpd 1.4
  6. Traefik 2.0
  7. Traefik >= 2.4.1 with Authelia forward auth
  8. Authelia & Calibre-Web Logout Button
  9. Traefik 2.6.0 Example with Kobo Sync Fix Enabled
  10. Caddy

nginx

nginx configuration for a local server listening on port 8080, mapping Calibre-Web to /calibre:

http {
    server {
            client_max_body_size 20M;
            location /calibre {
                proxy_bind              $server_addr;
                proxy_pass              http://127.0.0.1:8083;
                proxy_set_header        Host            $http_host;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Scheme        $scheme;
                proxy_set_header        X-Script-Name   /calibre;  # IMPORTANT: path has NO trailing slash 
        }
    }
}

If you want to use nginx as proxy for subdomain (or domain) just replace the /calibre in the location line with / and remove the X-Script-Name line. Do not change anything else and it will work. The X-Scheme directive is used to preserve the protocol (http/https), it could be hard coded to http or https to force this type of protocol.

E.g

sudo nano /etc/nginx/sites-enabled/calibre

server {
            listen 80;
            server_name  subdomain.example.com;
            client_max_body_size 20M;

            location / { # Reduced to "/"
                proxy_bind              $server_addr;
                proxy_pass              http://127.0.0.1:8083;
                proxy_set_header        Host            $http_host;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Scheme        $scheme;
                # Removed proxy_set_header
        }
    }

Note: If using SSL in your reverse proxy on a non-standard port (e.g.12345), the following proxy_redirect line may be required:

proxy_redirect http://$host/ https://$host:12345/;

Note: If you're encountering sync problems, consider adding the proxy settings described in the next section to the nginx config described above.

Nginx Proxy Manager

Credits to @norangebit see issue 1891

In Nginx Proxy Manager create a new proxy host for Calibre-Web. You can enable force SSL, HSTS and Block Common Exploits without any problems. Go to advanced tab and enter the following parameters:

proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;

If you have an Authentication server like Authelia setup, you can skip authentication for kobo sync using the additional NGINX-config below. Make sure the location /kobo { matches your situation.

location /kobo {
set $upstream_calibreweb $forward_scheme://$server:$port;
proxy_set_header X-Forwarded-Host $http_host;
proxy_pass $upstream_calibreweb;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}

Optional Kobo sync support

Calibre-Web

  1. Go to admin setting in and enable Kobo sync.
  2. Set Server External Port to 80.
  3. If the port is set to 443, it is not possible to fetch covers.
  4. Go to your profile page, enable Kobo sync and copy the api endpoint.

Kobo

Open .kobo/Kobo/Kobo eReader.conf file in a text editor end edit your api endpoint. Make sure you use HTTPS and not HTTP. This is an example of a correct line: api_endpoint=https://books.<domain>/kobo/<token>

Apache 2.4

Apache 2.4 configuration for a local server listening on port 443, mapping Calibre-Web to /calibre-web:

The following modules have to be activated: headers, proxy, proxy_http, rewrite.

Listen 443

<VirtualHost *:443>
    SSLEngine on
    SSLProxyEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    SSLCertificateFile "C:\Apache24\conf\ssl\test.crt"
    SSLCertificateKeyFile "C:\Apache24\conf\ssl\test.key"

    <Location /calibre-web >
        RequestHeader set X-SCRIPT-NAME /calibre-web
        RequestHeader set X-SCHEME https
        ProxyPass http://localhost:8083/
        ProxyPassReverse http://localhost:8083/
        ProxyPassReverseCookiePath  /  /calibre-web/
    </Location>
</VirtualHost>

Internet Information Service (IIS) 10

First you need to install: The URL rewrite extension:
http://www.iis.net/downloads/microsoft/url-rewrite
and the application request routing:
https://www.iis.net/downloads/microsoft/application-request-routing
Enable the proxy stuff:
Enable Proxy step1

Enable Proxy step2

Enable Proxy step3

Go to your site and start URL-Rewriting:

url rewrite step1

url rewrite step1

Add the server variable:

server variable

(The local is comming on it's own) with UNDERSCORE and excact Name: HTTP_X-SCRIPT_NAME

Then add Reverse Proxy Rules:

proxy rules step1variable

proxy rules step2

Add the ip address and port of your Calibre-Web instance: e.g. http://127.0.0.1:8083

Change the rule afterwards:

proxy rules step2

Enter the folder you want to have Calibre-Web in (/calibre-web instead of ^ might also works). End the name without a slash, otherwise a call to /calibre-web would go to nowhere. And Add the server variable to the request and give it the same name as the folder above with starting slash (/calibre-web in my example, again without trailing slash)

proxy rules step2

The rewrite rule should look like this:

proxy rules step2

My web.config file looks like this:

proxy rules step2

The crossed out sections aren't needed, they are leftovers from my experiments.

Lighttpd 1.4

Lighttpd 1.4 configuration for a reverse proxy to Calibre-Web to /calibre-web:

The following modules have to be activated: mod_setenv, mod_redirect and mod_proxy. Example is for https connection, to have an normal http frontend, the X-SCHEME line has to be deleted.(?)

$HTTP["url"] =~ "^/calibre-web" {
    setenv.add-request-header = (
        "X-SCRIPT-NAME" => "/calibre-web",
        "X-SCHEME" => "https"
    )
    proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "8083" ) ) )
}

Traefik 2.0.0

traefik.toml:

[log]
  level = "DEBUG"
  filePath = "log-file.log"

[accessLog]
  filePath =  "log-access.log"
  bufferingSize =  100

[providers]
  [providers.file]
    filename = "traefik-proxy.toml"

[entryPoints]
  [entryPoints.web]
    address = ":80"

traefik-proxy.toml:

[http]
    [http.middlewares]
      [http.middlewares.cwHeader.headers]
        [http.middlewares.cwHeader.headers.customRequestHeaders]
            X-Script-Name = "/cw"
      [http.middlewares.cwStrip.stripPrefixRegex]
            regex = ["/cw"]

    [http.routers]
       [http.routers.cw-router]
          rule = "(Host(`127.0.0.1`) && PathPrefix(`/cw`))"
          service = "calibre-web"
          entryPoints = ["web"]
          middlewares = ["cwStrip","cwHeader"]
    [http.services]
          [http.services.cw-router.loadbalancer]
            [[http.services.cw-router.loadbalancer.servers]]
              url = "http://127.0.0.1:8083"

This example is only working for 127.0.0.1 for other hostnames the routing rule has to be extended.

Traefik >= 2.4.1 with Authelia Forward Auth

When you have a setup of Traefik >= 2.4.1 in combination with Authelia forward authorization, Authelia can provide all required information via a Middleware.

Setting up is as easy as:

  1. Adding authResponseHeaders=Remote-User to the forwardauth middleware
  2. Adding "Remote-User" as Reverse proxy header name in the Calibre configuration section

Example of Authelia middleware definition:

  - 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://login.example.com/'
  - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
  - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'
  - 'traefik.http.middlewares.authelia-basic.forwardauth.address=http://authelia:9091/api/verify?auth=basic'

Authelia & Calibre-Web Logout Button

calibre-web's logout button by default logs you out of calibre-web, but does not log you out of authelia. To log out of calibre-web and authelia at once when clickling the logout button within calibre-web you need to define a small middleware in traefik and add this to the calibre router as follows:

http:
  routers:
    calibre:
      service: calibre-web-calibre@docker
      rule: "Host(`library.domain`)"
      tls:
        certResolver: "yourCertResolver"
        domains:
          - main: "domain"
          - sans: "library.domain"
      middlewares:
        - authelia
        - calibre-logout
        
middlewares:
    calibre-logout:
      redirectRegex:
        regex: "https://library.domain/login"
        replacement: "https://auth.domain/logout?rd=https%3A%2F%2Flibrary.domain%2F&rm=GET"

Traefik 2.6.0 Example (Kobo Sync Fix Enabled)

The following example presumes that you are using the linuxserver Calibre-Web image for your container and that you have setup traefik 2.6.0 correctly to automatically redirect http to https requests on the websecure entry point (sometimes setup as https entrypoint)

  calibre-web:
    image: linuxserver/calibre-web
    container_name: calibre-web
    hostname: calibre-web
    ports:
      - 8083:8083
    environment:
      - DOCKER_MODS=linuxserver/calibre-web:calibre
    volumes:
      - ${CONFIG}/calibre-web:/config
      - ${DATA}/media/books:/data/media/books
    restart: always
    labels:
      # Enables Traefik for this Container
      - "traefik.enable=true"
      # Creates a middleware that adds in a header to tell Calibre-Web the X-Scheme is https
      # (this is similar to the nginx examples) and required for Kobo Sync
      - "traefik.http.middlewares.kobo-sync-headers.headers.customrequestheaders.X-Scheme=https"
      # Sets up the router for to use websecure router (https) that:
      # - Uses a secure https entry point
      # - Sets the domain to books.example.com
      # - Applies HTTPS headers, the middleware headers above required for Kobo Sync,
      #   and sends requests through authelia for authentication
      # - Sets TLS to true
      # - And sets up a load balancing service to redirect to port 8083
      - "traefik.http.routers.calibre-web-secure.entrypoints=websecure"
      - "traefik.http.routers.calibre-web-secure.rule=Host(`books.${DOMAIN}`)"
      - 'traefik.http.routers.calibre-web-secure.middlewares=secure-headers,kobo-sync-headers,authelia@docker'
      - "traefik.http.routers.calibre-web-secure.tls=true"
      - "traefik.http.routers.calibre-web-secure.service=calibre-web-secure"
      - "traefik.http.services.calibre-web-secure.loadbalancer.server.port=8083"

Additionally if you're using Authelia as a middleware, be sure to change the following setting in your Authelia config file. You can read more about this Here, Here, and Here. You might need to set write_buffer_size to the same size as your read.

server:
  read_buffer_size: 10485760

An example Authelia Rule of Kobo Sync bypass is here:

    - domain: books.domain.com
      policy: bypass
      resources:
      - "^/kobo([/?].*)?$"

Caddy

A working caddy configuration for https, using the domain calibre.mydomain.com:

calibre.mydomain.com {
        reverse_proxy localhost:8083 {
             header_up X-Scheme https
        }
}