Alpine static compiled binary failed with Routines:tls_process_server_certificate:certificate verify failed (OpenSSL::SSL::Error) when run it on CentOS 8

I am porting a really simple ruby script to Crystal.

As you can see, it really simple, and works on my own laoptop (Arch Linux) when build use alpine static.

Then when i copy my binary into my another laptop which use CentOS Stream release 8, this binary not work like this:

[root@etc]# ./myip 
Unhandled exception: SSL_connect: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed (OpenSSL::SSL::Error)
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???
  from ???

I use official crystallang/crystal:1.5.0-alpine-build, build with:

shards build --production --release  --static --progress

Any idea on how to fix that? thank you.

The OpenSSL library expects a certain system configuration (such as the location where certificates are looked up), which differs between Linux distributions. When linked statically, the resulting binary expects the system configuration used at compile time (i.e. Alpine linux’s). That same library won’t work on CentOS because it uses a different configuration.

This is a well-known problem which restricts the portability of statically linked OpenSSL libraries, so there are lots of resources on the web.

There are some workarounds. For example, you could use a statically linked library from the target system or build it on the host system but with the configuration for the target system.
Alternatively, it should be possible to change the configuration at runtime, either explicitly or with some automatic path lookup (like GitHub - alexcrichton/openssl-probe does for example).
Or avoid linking OpenSSL statically. The dynamic system library should always be configured to integrate well with the target system.

Thanks, for my that myip package, i just release 0.3.0 workaround this issue use another site which not use TLS. http://www.ip111.cn.

Or avoid linking OpenSSL statically

I consider this solution is more easier? can i know how to link OpenSSL in Alpine dynamically?

BTW: i guess what you means is only link OpenSSL dynamically, but others dependencies, still link use musl static, right?

@straight-shoota , Hi, maybe i misunderstood something, is there possible to link OpenSSL dynamically(to avoid this issue) when build a musl static binary from alpine?

If you link libssl dynamically, you won’t have a fully statically linked binary anymore (that’s what “static binary” usually means).

You should technically be able to link musl libc statically while linking libssl dynamically. You’ll get a dynamically linked executable as a result, though.
And you have to care for compatibility between libc and libssl. So it might not be a very practical approach.

1 Like