foxcpp / maddy

✉️ Composable all-in-one mail server.
https://maddy.email
GNU General Public License v3.0
4.95k stars 239 forks source link

Fails to import config from file using absolute path #592

Closed gareththered closed 7 months ago

gareththered commented 1 year ago

Describe the bug

Attempting to import ACME DNS api_token from a file fails if the path to the file is absolute.

Steps to reproduce

This is in a Docker Swarm stack, where the api_token is a Docker Secret.

The compose file is:

version: "3.8"

services:
  maddy:
    image: foxcpp/maddy
    environment:
      - MADDY_HOSTNAME=mx1.mydomain.here
      - MADDY_DOMAIN=int.mydomain.here
    secrets:
      - gandi_key
    volumes:
      - /persistent/maddy/data1:/data
    # stdin_open: true
    # tty: true
    # entrypoint: /bin/sh
    ports:
      - 25:25
      - 465:465
      - 587:587
      - 2525:2525
    deploy:
      restart_policy:
        condition: on-failure

secrets:
  gandi_key:
    external: true

With the stdin_open, tty, & entrypoint commented as above, the container fails instantaneously, with only:

/data/maddy.conf:45: unknown import: /run/secrets/gandi_key

in the container log.

Log files

It fails to start with:

/data/maddy.conf:45: unknown import: /run/secrets/gandi_key

No other logs are generated, even with debug = true set.

Configuration file

Extract from /data/maddy.conf:

tls.loader.acme acme_tls {
    debug on
    hostname mx1.mydomain.here
    store_path /data/acme
    email gareth@mydomain.here
    agreed # indicate your agreement with Let's Encrypt ToS
    ca https://acme-v02.api.letsencrypt.org/directory
    test_ca https://acme-staging-v02.api.letsencrypt.org/directory
    challenge dns-01
    dns gandi {
      import /run/secrets/gandi_key
      # import ../run/secrets/gandi_net
    }
}

and the file /run/secrets/gandi_key is populated by Docker to contain a single line:

api_token "myRealGandiApiToken"

Environment information

Latest version running on Docker Swarm

Additional Information

If I change the import to be relative to the /data working directory, by preceding it with .. :

    dns gandi {
       import ../run/secrets/gandi_net
    }

it seems to work:

/ # maddy run
tls.loader.acme/maintenance: started background certificate maintenance {"cache":"0xc0000acd20"}
table.file: ignoring non-existent file: /etc/maddy/aliases
tls.loader.acme/obtain: acquiring lock  {"identifier":"mx1.mydomain.herek"}
tls.loader.acme/obtain: lock acquired   {"identifier":"mx1.mydomain.here"}
tls.loader.acme/obtain: obtaining certificate   {"identifier":"mx1.mydomain.here"}

and so on.

foxcpp commented 1 year ago

Configuration forces all paths to be interpreted as relative to the config directory (/data for Docker). I guess this should be fixed to not apply for absolute paths.