Certbot: Timeout during connect (likely firewall problem)

Hello all,
I’m having an issue generating an SSL certificate for my passbolt instance and I can’t seem to be able to fix it.

Setup

  • I’m locally hosting my passbolt instance on Raspberry PI 4 Model B
  • The pi is running on Ubuntu 24.04
  • The instance is containerized via Docker
  • The registar I’m using is AWS Route 53
  • I have followed the guides: Install Passbolt on Docker, Docker automatic HTTPS configuration
  • I have added my passbolt domain at /etc/hosts

Observations

  • when I try to curl into the instance by using it’s direct IP, it doesn’t respond (possible network issue on the docker side?)

Checks

  • I have double checked that the record is pointing to the pi’s external IP address
  • I have enabled firewall rules for port 80 and 443

docker-compose-ce.yaml

version: "3.9"
services:
  db:
    image: mariadb:10.11
    restart: unless-stopped
    environment:
      APP_FULL_BASE_URL: "https://example.com"
      MYSQL_RANDOM_ROOT_PASSWORD: "true"
      MYSQL_DATABASE: "passbolt"
      MYSQL_USER: "passbolt"
      MYSQL_PASSWORD: "P4ssb0lt"
      EMAIL_DEFAULT_FROM_NAME: "Passbolt"
      EMAIL_DEFAULT_FROM: "John.Doe@hotmail.com"
      EMAIL_TRANSPORT_DEFAULT_HOST: "smtp-mail.outlook.com"
      EMAIL_TRANSPORT_DEFAULT_PORT: 587
      EMAIL_TRANSPORT_DEFAULT_USERNAME: "John.Doe@hotmail.com"
      EMAIL_TRANSPORT_DEFAULT_PASSWORD: ""
      EMAIL_TRANSPORT_DEFAULT_TLS: ""

    volumes:
      - database_volume:/var/lib/mysql

  passbolt:
    image: passbolt/passbolt:latest-ce
    #Alternatively you can use rootless:
    #image: passbolt/passbolt:latest-ce-non-root
    restart: unless-stopped
    depends_on: 
      - db
    environment:
      APP_FULL_BASE_URL: https://example.com
      DATASOURCES_DEFAULT_HOST: "db"
      DATASOURCES_DEFAULT_USERNAME: "passbolt"
      DATASOURCES_DEFAULT_PASSWORD: "P4ssb0lt"
      DATASOURCES_DEFAULT_DATABASE: "passbolt"
    volumes:
      - gpg_volume:/etc/passbolt/gpg
      - jwt_volume:/etc/passbolt/jwt
    command:
      [
        "/usr/bin/wait-for.sh",
        "-t",
        "0",
        "db:3306",
        "--",
        "/docker-entrypoint.sh",
      ]

    labels:
      traefik.enable: "true"
      traefik.http.routers.passbolt-http.entrypoints: "web"
      traefik.http.routers.passbolt-http.rule: "Host(`example.com`)"
      traefik.http.routers.passbolt-http.middlewares: "SslHeader@file"
      traefik.http.routers.passbolt-https.middlewares: "SslHeader@file"
      traefik.http.routers.passbolt-https.entrypoints: "websecure"
      traefik.http.routers.passbolt-https.rule: "Host(`example.com`)"
      traefik.http.routers.passbolt-https.tls: "true"
      traefik.http.routers.passbolt-https.tls.certresolver: "letsencrypt"
 
  traefik:
    image: traefik:2.6
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.yaml:/traefik.yaml:ro
      - ./conf/:/etc/traefik/conf
      - ./shared/:/shared

volumes:
  database_volume:
  gpg_volume:
  jwt_volume:

Any help would be much appreciated!

Hi can you share the following file please?

Can you also share the server logs

Hey @max ,
Sure, thanks for taking a look.

       │ File: traefik.yaml
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ global:
   2   │   sendAnonymousUsage: false
   3   │ log:
   4   │   level: INFO
   5   │   format: common
   6   │ providers:
   7   │   docker:
   8   │     endpoint: 'unix:///var/run/docker.sock'
   9   │     watch: true
  10   │     exposedByDefault: true
  11   │     swarmMode: false
  12   │   file:
  13   │     directory: /etc/traefik/conf/
  14   │     watch: true
  15   │ api:
  16   │   dashboard: false
  17   │   debug: false
  18   │   insecure: false
  19   │ entryPoints:
  20   │   web:
  21   │     address: ':80'
  22   │     http:
  23   │       redirections:
  24   │         entryPoint:
  25   │           to: websecure
  26   │           scheme: https
  27   │           permanent: true
  28   │   websecure:
  29   │     address: ':443'
  30   │ certificatesResolvers:
  31   │   letsencrypt:
  32   │     acme:
  33   │       email: john.doe@hotmail.com
  34   │       storage: /shared/acme.json
  35   │       caServer: 'https://acme-v02.api.letsencrypt.org/directory'
  36   │       keyType: EC256
  37   │       httpChallenge:
  38   │         entryPoint: web
  39   │       tlsChallenge: {}

Logs for passbolt instance:

wait-for.sh: waiting for db:3306 without a timeout
wait-for.sh: db:3306 is available after 2 seconds
gpg: keybox '/var/lib/passbolt/.gnupg/pubring.kbx' created
gpg: /var/lib/passbolt/.gnupg/trustdb.gpg: trustdb created
gpg: key 2CE3371C6EC1405B: public key "Passbolt default user <passbolt@yourdomain.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: key 2CE3371C6EC1405B: "Passbolt default user <passbolt@yourdomain.com>" not changed
gpg: key 2CE3371C6EC1405B: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

Installing passbolt

     ____                  __          ____
    / __ \____  _____ ____/ /_  ____  / / /_
   / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/
  / ____/ /_/ (__  |__  ) /_/ / /_/ / / /
 /_/    \__,_/____/____/_.___/\____/_/\__/

 Open source password manager for teams
-------------------------------------------------------------------------------
Running baseline checks, please wait...
The /etc/passbolt/jwt/ directory should not be writable.
Please run ./bin/cake passbolt healthcheck for more information and help.
Running migrations

     ____                  __          ____
    / __ \____  _____ ____/ /_  ____  / / /_
   / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/
  / ____/ /_/ (__  |__  ) /_/ / /_/ / / /
 /_/    \__,_/____/____/_.___/\____/_/\__/

 Open source password manager for teams
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 Running migration scripts.
-------------------------------------------------------------------------------
using migration paths
 - /etc/passbolt/Migrations
using seed paths
using environment default
using adapter mysql
using database passbolt
ordering by creation time

All Done. Took 0.0463s
Clearing cake caches
Clearing _cake_model_
Cleared _cake_model_ cache
Clearing _cake_core_
Cleared _cake_core_ cache
Enjoy! ☮

/usr/lib/python3/dist-packages/supervisor/options.py:474: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
  self.warnings.warn(
2024-10-08 14:33:06,752 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
2024-10-08 14:33:06,752 INFO Included extra file "/etc/supervisor/conf.d/cron.conf" during parsing
2024-10-08 14:33:06,752 INFO Included extra file "/etc/supervisor/conf.d/nginx.conf" during parsing
2024-10-08 14:33:06,752 INFO Included extra file "/etc/supervisor/conf.d/php.conf" during parsing
2024-10-08 14:33:06,763 INFO RPC interface 'supervisor' initialized
2024-10-08 14:33:06,763 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2024-10-08 14:33:06,764 INFO supervisord started with pid 1
2024-10-08 14:33:07,775 INFO spawned: 'php-fpm' with pid 109
2024-10-08 14:33:07,783 INFO spawned: 'nginx' with pid 110
2024-10-08 14:33:07,791 INFO spawned: 'cron' with pid 111
[08-Oct-2024 14:33:08] NOTICE: fpm is running, pid 109
[08-Oct-2024 14:33:08] NOTICE: ready to handle connections
[08-Oct-2024 14:33:08] NOTICE: systemd monitor interval set to 10000ms
2024-10-08 14:33:09,078 INFO success: php-fpm entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-10-08 14:33:09,079 INFO success: nginx entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2024-10-08 14:33:09,079 INFO success: cron entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

Logs for traefik:

time="2024-10-08T14:32:49Z" level=info msg="Configuration loaded from file: /traefik.yaml"
time="2024-10-08T14:32:49Z" level=info msg="Traefik version 2.6.7 built on 2022-05-24T14:19:52Z"
time="2024-10-08T14:32:49Z" level=info msg="\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://doc.traefik.io/traefik/contributing/data-collection/\n"
time="2024-10-08T14:32:49Z" level=info msg="Starting provider aggregator.ProviderAggregator"
time="2024-10-08T14:32:49Z" level=info msg="Starting provider *file.Provider"
time="2024-10-08T14:32:49Z" level=info msg="Starting provider *docker.Provider"
time="2024-10-08T14:32:49Z" level=info msg="Starting provider *acme.ChallengeTLSALPN"
time="2024-10-08T14:32:49Z" level=info msg="Starting provider *traefik.Provider"
time="2024-10-08T14:32:49Z" level=info msg="Starting provider *acme.Provider"
time="2024-10-08T14:32:49Z" level=info msg="Testing certificate renew..." providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
time="2024-10-08T14:33:10Z" level=error msg="Unable to obtain ACME certificate for domains \"passbolt.domain.com\": unable to generate a certificate for the domains [passbolt.domain.com]: error: one or more domains had a problem:\n[passbolt.domain.com] acme: error: 400 :: urn:ietf:params:acme:error:connection :: 198.51.100.0: Timeout during connect (likely firewall problem)\n" ACME CA="https://acme-v02.api.letsencrypt.org/directory" rule="Host(`passbolt.domain.com`)" routerName=passbolt-https@docker providerName=letsencrypt.acme
time="2024-10-08T14:33:29Z" level=error msg="Unable to obtain ACME certificate for domains \"passbolt.domain.com\": unable to generate a certificate for the domains [passbolt.domain.com]: error: one or more domains had a problem:\n[passbolt.domain.com] acme: error: 400 :: urn:ietf:params:acme:error:connection :: 198.51.100.0: Timeout during connect (likely firewall problem)\n" rule="Host(`passbolt.domain.com`)" providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=passbolt-https@docker
time="2024-10-08T14:33:44Z" level=error msg="Unable to obtain ACME certificate for domains \"passbolt.domain.com\": unable to generate a certificate for the domains [passbolt.domain.com]: error: one or more domains had a problem:\n[passbolt.domain.com] acme: error: 400 :: urn:ietf:params:acme:error:connection :: 198.51.100.0: Connection refused\n" providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=passbolt-https@docker rule="Host(`passbolt.domain.com`)"

I have replaced my actual domain with a placeholder: passbolt.domain.com and the IP with: 198.51.100.0

Is port 80 blocked by firewall? It is required for letsencrypt to be able to generate a cert.

Hey @joe,

Yes, port 80 is defined on traefiik, I have also enabled it on the Ubuntu side and I’ve been using the bridge network for my containers.

Status: active

To                         Action      From
--                         ------      ----
443/udp                    ALLOW       Anywhere
80/udp                     ALLOW       Anywhere
443/udp (v6)               ALLOW       Anywhere (v6)
80/udp (v6)                ALLOW       Anywhere (v6)

I have also tried doing port forwarding on my router, but unfortunately there was no difference . :frowning:

Has a certificate been successfully generated for the site in /etc/letsencrypt? If not, can you run certbot certonly -d <passbolt domain name> and paste the output here?

nope, letsencypt hasn’t even created a directory yet.

root@f7494cbbd189:/usr/share/php/passbolt# certbot certonly -d passbolt.domain.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?


1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)


Input the webroot for passbolt.domain.com`: (Enter ‘c’ to cancel): /etc/nginx/sites-enabled

Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
Domain: passbolt.domain.com
Type: connection
Detail: 198.51.100.0: Fetching http://passbolt.domain.com/.well-known/acme-challenge/5gDFu-o7vu9eHzGeIDKHRg-rvHvQtnRmXlDze0xjXgM: Timeout during connect (likely firewall problem)

Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot. Ensure that the listed domains serve their content from the provided --webroot-path/-w and that files created there can be downloaded from the internet.

Some challenges have failed.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
root@f7494cbbd189:/usr/share/php/passbolt#

The problem was due to my ISP provider not allowing port 80 on their end.
I have requested a static DHCP and now i can execute the certbot cert process.

Sorry for the inconvenience.
Closing the thread.

1 Like