0xERR0R / blocky

Fast and lightweight DNS proxy as ad-blocker for local network with many features
https://0xERR0R.github.io/blocky/
Apache License 2.0
4.69k stars 208 forks source link

Blocky does not pick up the new certificate #1625

Open izidormatusov opened 4 days ago

izidormatusov commented 4 days ago

Is there a way to get blocky to pick up renewed certificate?

My blocky instance has run for roughly 3 months and the original letsencrypt SSL certificate expired. Blocky did not picked up the renewed certificate, becoming unavailable when serving DNS-over-TLS:

$ doggo @tls://$DOMAIN google.com
time=2024-10-13T15:22:32.213+02:00 level=ERROR msg="error in lookup" error="tls: failed to verify certificate: x509: certificate has expired or is not yet valid: “$DOMAIN” certificate is expired"
NAME    TYPE    CLASS   TTL     ADDRESS NAMESERVER

Blocky reports the old certificate expiry

$ openssl s_client -showcerts -connect $DOMAIN:853  </dev/null
...
Certificate chain
...
   v:NotBefore: Jul 14 18:21:11 2024 GMT; NotAfter: Oct 12 18:21:10 2024 GMT

After I restarted blocky:

$ openssl s_client -showcerts -connect $DOMAIN:853  </dev/null
...
Certificate chain
...
   v:NotBefore: Sep 12 22:56:03 2024 GMT; NotAfter: Dec 11 22:56:02 2024 GMT

which matches the certificate expiry date:

$ openssl x509 -in /var/apps/blocky/certs/fullchain.pem -noout -enddate
notAfter=Dec 11 22:56:02 2024 GMT

Could blocky automatically pick up new certificates with long expiry date?

blocky's configuration:

certFile: /var/apps/blocky/certs/fullchain.pem
keyFile: /var/apps/blocky/certs/privkey.pem

ports:
  # Disable serving on 53 port
  dns: null
  # 853 is the standard for DNS-over-TLS
  # Android uses DNS-over-TLS
  tls: :853
  # Port for DNS-over-HTTP
  http: 127.0.0.1:{{ blocky_port }}

log:
  level: error
  privacy: true

upstreams:
  init:
    strategy: failOnError

  groups:
    default:
      - tcp-tls:1.1.1.1
      - tcp-tls:8.8.8.8

blocking:
  denylists:
    ads:
      - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
      - http://sysctl.org/cameleon/hosts
      - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt

  clientGroupsBlock:
    default:
      - ads
zdeneksvarc commented 3 days ago

If using Blocky in the Docker, you can use the restarter sidecar like:

# compose.yml

services
  restarter:
    image: docker
    volumes: ["/var/run/docker.sock:/var/run/docker.sock"]
    command: ["/bin/sh", "-c", "while true; do sleep 86400; docker restart <blocky_container_name>; done"]
    restart: unless-stopped

  blocky:
    ...
izidormatusov commented 2 days ago

I'm running blocky as a systemd service. I guess I can add a similar cron job that periodically restarts blocky systemd service. It seems like hassle, especially when other software dealing with SSL certificates (e.g. nginx) are able to use the up to date TLS certificates.

zdeneksvarc commented 2 days ago

Certificate reloading is generally a pain in non cloud-native environment. Relying on cronjob is not sexy. Try considering systemd timers.

izidormatusov commented 2 days ago

Can you clarify why certificate reloading is pain? Quick search shows that the pattern of dynamically reloading SSL certificate is quite common:

The patch would require making sure that the certificate is loaded only when the file gets modified. blocky codebase already indirectly depends on fsnotify:

$ go mod why -m github.com/fsnotify/fsnotify
# github.com/fsnotify/fsnotify
github.com/0xERR0R/blocky/log
github.com/x-cray/logrus-prefixed-formatter
github.com/x-cray/logrus-prefixed-formatter.test
github.com/onsi/ginkgo
github.com/onsi/ginkgo/internal/remote
github.com/nxadm/tail
github.com/nxadm/tail/watch
github.com/fsnotify/fsnotify
zdeneksvarc commented 2 days ago

It's a pain for ops, not developers. So thanks for the cloud-native environment.