Skip to content

[solved] “ssl/tls alert handshake failure” in ZNC

  • by

Ow, right in the cryptography!

tl;dr: if you’re getting ssl/tls alert handshake failure reports in eg a weechat *status buffer, follow rpatterson’s advice and add a SSLCiphers setting to your ZNC configuration.


This is another shark-adjacent situation. It all started when I noticed my internet connection was acting a bit funny. Sure enough, the ping graph looked a bit funky:

I had actually suspected a DNS issue before I checked that ping graph as it had the slight lag of “try primary DNS and wait for it to time out”. Pihole was recently updated, and there’s still some oddness with queries- I seem to get a burst of them around the hour mark.

While DNS wasn’t the issue I did notice that irc.gimp.org was top of the list of queried domains. So I checked on my irc client and ZNC. A quick glance at the ZNC wiki showed some clear advice:

I also couldn’t connect to the web interface- the server just sent an empty response, both over HTTP and HTTPS. So I upgraded to the latest docker image, and split off the web interface onto a different port, exposed through traefik. Now, the docker image has some interesting behaviour insofar as it changes ownership of the directory the docker-compose.yml file lives in. So I ended up kicking the container over a few times during this process of trying to get things working*.

There were some connection issues, particularly with slashnet (for #xkcd):

17:31:15   slashnet  -- | irc: reconnecting to server...
17:31:15   slashnet  -- | irc: connecting to server 192.168.x.yyy/16667 (TLS)...
17:31:15   slashnet =!= | irc: TLS handshake failed
17:31:15   slashnet =!= | irc: error: Error in the pull function.
17:31:15   slashnet  -- | irc: reconnecting to server in 10 minutes
...
17:53:29   slashnet  -- | gnutls: receiving 1 certificate
17:53:29   slashnet  -- |  - certificate[1] info:
17:53:29   slashnet  -- |    - subject `EMAIL=Unknown@c953a71f3f84,CN=c953a71f3f84,OU=Unknown', issuer `EMAIL=Unknown@c953a71f3f84,CN=c953a71f3f84,OU=Unknown', serial 0x2101, RSA
                        | key 2048 bits, signed using RSA-SHA256, activated `2019-05-08 21:25:44 UTC', expires `2029-05-05 21:25:44 UTC',
                        | pin-sha256="y4S/QMacsOva8Pp0kEV7KVurXO0kxI5EnoLJWYHW0bg="
17:53:29   slashnet =!= | gnutls: the hostname in the certificate does NOT match "192.168.x.yyy"
17:53:29   slashnet =!= | gnutls: peer's certificate is NOT trusted
17:53:29   slashnet =!= | gnutls: peer's certificate issuer is unknown

And more:

17:55:44 *status | Disconnected from IRC (error:0A000410:SSL routines::ssl/tls alert handshake failure). Reconnecting...
17:55:44 *status | Disconnected from IRC. Reconnecting...
17:56:14 *status | Disconnected from IRC (error:0A000410:SSL routines::ssl/tls alert handshake failure). Reconnecting...
17:56:14 *status | Disconnected from IRC. Reconnecting...
17:56:45 *status | Disconnected from IRC (error:0A000410:SSL routines::ssl/tls alert handshake failure). Reconnecting...
17:56:45 *status | Disconnected from IRC. Reconnecting...

It took a fair bit of hunting down, but thanks to an excellent and well-referenced GitHub Issue by rpatterson:

When a remote IRC server is using old SSLCiphers, connections fail only with a ssl/tls alert handshake failure message and none of the SSL/TLS options in the network’s web config UI are able to workaround it. The only way to workaround this is to manually modify SSLCiphers in the global ZNC configuration which is both opaque and unnecessarily reduces the security of connections to most other servers.

For others working around this, I ended up copying the “Old backward compatibility” set of ciphers and that seems to workaround all the instances of this issue I’ve run into so far. At the time of writing that is:

SSLCiphers = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA

Shutdown ZNC, add that line to the global section of **/znc.conf, and restart ZNC.

I stopped ZNC, added that very line, restarted and hey presto:

18:00:48 *status | Disconnected from IRC. Reconnecting...
18:01:17      -- | irc: disconnected from server
18:02:33 *status | Connected!

Huzzah!

* After solving this, I could finally respond appreciatively to a quip made earlier by one of the members of #xkcd:

PS I also resolved the internet connection issue by kicking over the router and the ONT:

Hat tip to f8lure for the graphs- still going strong after many years.


docker-compose.yml after changes:

version: "3"
services:
  znc:
    image: znc:1.10.1
    container_name: znc
    ports:
      - 16667:16667
      - 6501:6501
    volumes:
      - .:/znc-data
    networks:
      - default
      - traefik_default
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_default"
      - "traefik.http.routers.zncweb.rule=Host(`znc.bertieb.org`)"
      - "traefik.http.routers.zncweb.tls=true"
      - "traefik.http.routers.matomo.tls.certresolver=myresolver"
      - "traefik.http.services.zncweb.loadbalancer.server.port=6501"


networks:
  traefik_default:
    external: true
  default:
    name: znc

Leave a Reply

Your email address will not be published. Required fields are marked *

Discover more from Rob's Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading