Git Product home page Git Product logo

dotege's Introduction

Dotege

Dotege is a tool to automatically generate configuration files from templates based on running docker containers. It also obtains SSL certificates for domains using Let’s Encrypt, and can send a signal (such as HUP) to another container when the template changes.

Out of the box it supports writing a HAProxy configuration file with appropriate entries for all containers with com.chameth.* labels. This enables automatic reverse proxying to any container with the relevant networks.

Configuration

Dotege is configured using environment variables:

Certificates

DOTEGE_CERTIFICATE_DEPLOYMENT

Determines how Dotege will deploy certificates. Valid options are:

  • disabled: Dotege will not request certificates or deploy them to disk.

  • combined: The certificate and private key will be written to one .pem file. Default.

  • splitkeys: The certificate will be written to a .pem file, and the private key to a .key file.

If certificate deployment is disabled, no other options in this section are used.

DOTEGE_CERT_DESTINATION

The folder where certificates will be placed. Defaults to /data/certs.

DOTEGE_CERT_GID

If specified, certificate files will be chowned to this numeric group ID.

DOTEGE_CERT_MODE

The file mode that should be applied to certificate files. Defaults to 0600.

Take care when configuring this in a YAML file as YAML supports octal integers, resulting in the wrong value being passed:

DOTEGE_CERT_MODE: 0640   # Passes a mode string of "416" to Dotege due to octal->decimal conversion
DOTEGE_CERT_MODE: 640    # Works as expected
DOTEGE_CERT_MODE: "0640" # Works as expected
DOTEGE_CERT_UID

If specified, certificate files will be chowned to this numeric user ID.

DOTEGE_DNS_PROVIDER

The DNS provider to use. Must be one supported by Lego. The DNS provider will also be configured using environmental variables, as documented by the Lego project. Required if certificate deployment is enabled.

DOTEGE_ACME_CACHE_FILE

The path to a JSON file to store ACME credentials and certificates. This file will contain the private keys for all certificates generated by Dotege, so must not be accessible to other users or processes. Defaults to /data/config/certs.json.

DOTEGE_ACME_EMAIL

The e-mail address to provide to the ACME service for updates, renewal reminders, etc. Required if certificate deployment is enabled.

DOTEGE_ACME_ENDPOINT

The ACME server to request certificates from. Defaults to the Let’s Encrypt production server at https://acme-v02.api.letsencrypt.org/directory. For staging, this can be set to https://acme-staging-v02.api.letsencrypt.org/directory.

DOTEGE_ACME_KEY_TYPE

The key type to use for private keys when generating a certificate using ACME. Valid values are:

  • P256 for EC256

  • P384 for EC384

  • 2048 for RSA-2048

  • 4096 for RSA-4096

  • 8192 for RSA-8192

    The default value is P384.

DOTEGE_WILDCARD_DOMAINS

A space or comma separated list of domains that should use wildcard certificates. Defaults to an empty list.

Other settings

DOTEGE_DEBUG

Enables advanced logging of certain information in Dotege. Comma-separated list of topics to enable logging for. Optional. Valid options are:

  • containers - containers that are seen to start/stop

  • headers - custom headers (com.chameth.headers labels)

  • hostnames - mapping of containers to hostnames

DOTEGE_PROXYTAG

Only containers with a matching com.chameth.proxytag label will be processed by Dotege. This allows you to run multiple instances that handle separate containers. If not specified, any container without a com.chameth.proxytag label will be included.

DOTEGE_SIGNAL_CONTAINER

The name of a container that should be sent a signal when the template or certificates are changed. No signal is sent if not specified.

DOTEGE_SIGNAL_TYPE

The type of signal to send to the DOTEGE_SIGNAL_CONTAINER. Defaults to HUP.

DOTEGE_TEMPLATE_DESTINATION

Location to write the templated configuration file to. Defaults to /data/output/haproxy.cfg.

DOTEGE_TEMPLATE_SOURCE

Path to a template to use to generate configuration. Defaults to ./templates/haproxy.cfg.tpl, which is a bundled basic template for generating HAProxy configurations.

DOTEGE_USERS

A YAML (or JSON) list of users, their password hashes, and their group memberships, to use for ACLs. See Using ACLs below for detailed usage.

Docker labels

Dotege operates by parsing labels applied to docker containers. It understands the following:

com.chameth.auth

Specifies the name of an auth group (which must be defined in the DOTEGE_USERS env variable) that users are required to be in to access the container. See Using ACLs below for detailed usage.

com.chameth.headers

Specifies response headers to be sent to the client for all requests to the container. Any label with this as a prefix will be used, so multiple headers can be specified as com.chameth.headers.1, or com.chameth.headers-frame-options, for example.

com.chameth.proxy

The port on which the container is listening for requests. If com.chameth.vhost is specified and com.chameth.proxy is not and the container exposes a single non-bound port then Dotege will automatically use that port. That means you do not need to manually label the port for an nginx server, for instance, as the nginx image exposes port 80 (only).

com.chameth.proxytag

Arbitrary tag to control which containers an instance of Dotege will deal with. If specified, the container will be ignored by any instance of Dotege that does not have the same value passed in using the DOTEGE_PROXYTAG env var.

com.chameth.vhost

Comma- or space-delimited list of hostnames that the container will handle requests for. Certificates will have the first host as the subject, and any additional hosts will be alternate names. Certificates are only reused if all hostnames match.

Example compose file

version: '3.5'
services:
  dotege:
    image: ghcr.io/csmith/dotege
    restart: always
    volumes:
      - data:/data/config
      - certs:/data/certs
      - config:/data/output
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DOTEGE_ACME_EMAIL=email@address
      - DOTEGE_DNS_PROVIDER=httpreq
      - DOTEGE_SIGNAL_CONTAINER=dotege_haproxy_1
      - DOTEGE_SIGNAL_TYPE=USR2
      - DOTEGE_WILDCARD_DOMAINS=mydomain.com
      - HTTPREQ_ENDPOINT=https://example.com/
      - HTTPREQ_USERNAME=user@name
      - HTTPREQ_PASSWORD=p@ssw0rd

  haproxy:
    image: haproxy:2.0.1
    restart: always
    volumes:
      - config:/usr/local/etc/haproxy:ro
      - certs:/certs:ro
    ports:
      - 443:443
      - 80:80
    networks:
      - web

networks:
  web:
    external: true

volumes:
  data:
  certs:
  config:

This creates an instance of Dotege, configured to use httpreq to perform DNS operations in order to generate SSL certificates. You can see the list of supported providers and their required environment variables in the Lego docs.

The haproxy instance has read-only access to the config and certs volumes that will be populated by Dotege, and Dotege will send it the USR2 signal whenever the config or certs change. With the default haproxy image this will cause it to reload the configuration.

Container names must be resolvable from the haproxy container with the default template. This means the haproxy container should be on the same network as the containers it’s proxying to. I recommend creating a global 'web' network (or similar) that all web-facing containers sit in.

Using ACLs

Dotege, with the default HAProxy template, allows you to specify users in an environment variable and for individual containers to then require a specific group of users using labels.

Defining users

Dotege expects the DOTEGE_USERS environment variable to contain a list of users, and each user must have a "name" and "password" property, and an optional "groups" property. For example if we want our user list to look like this:

- name: chris
  password: hashedPasswordHere
  groups: [admins]
- name: bob
  password: hashedPasswordHere

Then we’d use the following environment variable:

DOTEGE_USERS="- name: chris\n  password: hashedPasswordHere\n  groups: [admins]\n- name: bob\n  password: hashedPasswordHere"

Alternatively, removing the need for line breaks:

DOTEGE_USERS="[{name: chris, password: hashedPasswordHere, groups: [admins]}, {name: bob, password: hashedPasswordHere}]"

If you are using configuring the container using YAML (e.g. in a docker-compose file), you can use the pipe operator to treat YAML content as a scalar, which is vastly easier to use:

services:
  dotege:
    environment:
      DOTEGE_USERS: |
        - name: chris
          password: hashedPasswordHere
          groups: [admins]
        - name: bob
          password: hashedPasswordHere

For HAProxy, passwords are hashed using the crypt(3) system call - the easiest way to generate them is using the mkpassword utility.

NB: If you are using docker-compose then any $ characters in the hashed password will need to be escaped by doubling them up (i.e. replace $ with $$).

Restricting access

To require basic authentication, the container should have the com.chameth.auth label. The label should be a space separated list of groups that are allowed access; if it is blank then all defined users are allowed.

For example:

services:
  public:
    labels:
      com.chameth.vhost: "public.example.com"
  private1:
    labels:
      com.chameth.vhost: "private1.example.com"
      com.chameth.auth: ""
  private2:
    labels:
      com.chameth.vhost: "private2.example.com"
      com.chameth.auth: "admins"

Of these services, public won’t require any authentication. private1 will require any valid user (so from our example above, either "chris" or "bob"), while private2 will require a user in the "admins" group (so from our example above only "chris" would be allowed access).

Writing templates

Dotege comes with two templates out of the box - one to create a working HAProxy config, and one to output a list of domains suitable for use with a tool like Dehydrated.

Dotege uses Go’s built in text/template package which provides extensive documentation for the template syntax itself. If you’ve used Smarty, Jinja or other templating systems the syntax should look pretty similar.

Dotege provides the following data to templates:

  • Containers - a map of container IDs to the container’s details:

    • Id - the ID of the container

    • Headers - map of header names to values from com.chameth.headers labels

    • Labels - map of all label names to values

    • Name - the name of the container

    • Port - the port the container accepts traffic on, or -1 if it couldn’t be determined

    • Ports - all ports exposed by the container

    • ShouldProxy - boolean indicating whether the container has a hostname and port

  • Groups - a list of unique group names specified in the DOTEGE_USERS key

  • Hostnames - a map of known primary hostnames to their details:

    • Alternatives - a map of alternate names for this hostname

    • AuthGroup - the name of the group users must be a member of to access this hostname (if RequiresAuth is true)

    • Containers - all containers that accept traffic for this hostname

    • Headers - map of header names to values from com.chameth.headers labels

    • Name - the name of the primary hostname

    • RequiresAuth - boolean indicating whether authentication is required

  • Users - a list of users defined in the DOTEGE_USERS key

    • Name - the username of the user

    • Password - the (hashed) password of the user

    • Groups - list of groups the user belongs to

Most templates will want to act on the Hostnames data primarily, as this groups up containers that accept traffic to the same domains, and avoids having to deal with containers that aren’t configured for use with Dotege.

Build tags

If you know in advance you will only use a single DNS provider, you can use build tags to include only support for that provider in the binary. For example to support only the httpreq provider you can build with go build -tags lego_httpreq. See the legotapas project for more info.

Contributing

Contributions are welcome! Please raise an issue if you have any feature requests or spot a bug, or open a pull request if you want to suggest any code changes.

Licence and credits

Dotege is licensed under the MIT licence. A full copy of the licence is available in the LICENCE file.

Dotege makes use of a number of third-party libraries. See the go.mod file for a list of direct dependencies. Users of the docker image will find a copy of the relevant licence and notice files under the /notices directory in the image.

dotege's People

Contributors

csmith avatar dependabot[bot] avatar greboid avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.