AppImage built with lnuxdeployqt can't get work SSL connection
LeoCAD uses linuxdeployqt for AppImage builds, but resulted AppImages can't work with SSL:
- YAML: https://github.com/leozide/leocad/blob/5772688318f8b7df41c2b8ae5b5659f8c4b2c1e5/appveyor.yml#L88
- Builds: https://github.com/leozide/leocad/releases/tag/continuous
Error output when trying to connect:
$ ./LeoCAD-Linux-8eec5756-x86_64.AppImage
qt.network.ssl: QSslSocket: cannot resolve EVP_PKEY_base_id
qt.network.ssl: QSslSocket: cannot resolve SSL_get_peer_certificate
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_get_peer_certificate
How to solve it in YAML?
Note: there was the same issue described for other AppImages built with linuxdeploy/linuxdeploy:
- https://discourse.appimage.org/t/app-diverting-to-host-oss-openssl-libraries-in-runtime/2701
Thanks for reporting this @app4soft. We need some OpenSSL and/or Qt experts to explain what is going on and how to fix this. I don't know the answer unfortunately.
Related OpenSSL issue:
- https://github.com/openssl/openssl/issues/7481
@probonopd, is there a way to setup AppImage build to not bundle any connection related libs at all and set AppImage to use all the connection related libs from the system? (not only SSL).
I mean, is there a way to exclude Qt 6 networking module from AppImage and set it to use libQt6Network.so.6 from the system? (and how to do that with YAML build script)
Same way as AppImage already did for the core Linux libs, which are not included, but used from the system.
I think that would crash badly as soon as the target system has even a slightly different Qt version installed locally than what is in the bundle.
Here is a solution used in FreeCAD's AppImage:
- https://github.com/FreeCAD/FreeCAD-Bundle/commit/9db09e470163bfc7e36d4a1f00da6c54fe5ef483
AppRun entry code:
...
# SSL
# https://forum.freecadweb.org/viewtopic.php?f=4&t=34873&start=20#p327416
export SSL_CERT_FILE=$PREFIX/ssl/cacert.pem
# https://github.com/FreeCAD/FreeCAD-AppImage/pull/20
export GIT_SSL_CAINFO=$HERE/usr/ssl/cacert.pem
...
I tried it with LeoCAD's AppImages, but it does not solves the issue:
$ export SSL_CERT_FILE=$PREFIX/ssl/cacert.pem
$ ~/AppImages/LeoCAD*.AppImage
qt.network.ssl: QSslSocket: cannot resolve EVP_PKEY_base_id
qt.network.ssl: QSslSocket: cannot resolve SSL_get_peer_certificate
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_get_peer_certificate
Is it due to SSL_CERT_FILE is a custom FreeCAD's variable?
If so, how to workaround this solution and make it universal for Qt5/Qt6 apps AppImages?
REFERENCE
- https://stackoverflow.com/questions/14681012/how-to-include-openssl-in-a-qt-project
- https://stackoverflow.com/a/22103277
From George at "Unable to use AES files of OpenSSL in Qt Creator": https://stackoverflow.com/questions/22093148/unable-to-use-aes-files-of-openssl-in-qt-creator
If this is on Linux, add the following into your .pro file:
PKGCONFIG += opensslIt will handle all necessary header paths, compile-linker options and the libraries.
And make sure you have the openssl-devel package installed in your system.
- https://doc.qt.io/qt-6/ssl.html#enabling-and-disabling-ssl-support-when-building-qt-from-source
When building a version of Qt linked against OpenSSL, Qt's build system will use CMake's
FindOpenSSLcommand to find OpenSSL in several standard locations. You can set the CMake variableOPENSSL_ROOT_DIRto force a specific location.For example:
configure -openssl-linked -- -D OPENSSL_ROOT_DIR=<openssl_dir>To disable SSL support in a Qt build, configure Qt with the
-no-openssloption.
I have the same issue before. I found linuxdeployqt does not bundle ssl plugin for some reason. So I have to add -extra-plugins=tls to fix this issue, and also add the environment variables to AppRun for some Linux distributions compatibility:
this_dir="\$(readlink -f "\$(dirname "\$0")")"
export XDG_DATA_DIRS="\${this_dir}/usr/share:\${XDG_DATA_DIRS}:/usr/share:/usr/local/share"
export QT_QPA_PLATFORMTHEME=gtk3
unset QT_STYLE_OVERRIDE
# Force set openssl config directory to an invalid directory to fallback to use default openssl config.
# This can avoid some distributions (mainly Fedora) having some strange patches or configurations
# for openssl that make the libssl in Appimage bundle unavailable.
export OPENSSL_CONF="\${this_dir}"
# Find the system certificates location
# https://gitlab.com/probono/platformissues/blob/master/README.md#certificates
possible_locations=(
"/etc/ssl/certs/ca-certificates.crt" # Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt" # Fedora/RHEL
"/etc/ssl/ca-bundle.pem" # OpenSUSE
"/etc/pki/tls/cacert.pem" # OpenELEC
"/etc/ssl/certs" # SLES10/SLES11, https://golang.org/issue/12139
"/usr/share/ca-certs/.prebuilt-store/" # Clear Linux OS; https://github.com/knapsu/plex-media-player-appimage/issues/17#issuecomment-437710032
"/system/etc/security/cacerts" # Android
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" # CentOS/RHEL 7
"/etc/ssl/cert.pem" # Alpine Linux
)
for location in "\${possible_locations[@]}"; do
if [ -r "\${location}" ]; then
export SSL_CERT_FILE="\${location}"
break
fi
done
Full script can be found: https://github.com/c0re100/qBittorrent-Enhanced-Edition/blob/v5_0_x/.github/workflows/build_appimage.sh#L343
Full script can be found:
@abcfy2, Thanks.
Could you point me how/where to insert your solution into LeoCAD's YAML?
- https://github.com/leozide/leocad/blob/master/appveyor.yml
@app4soft Try to modify these lines: https://github.com/leozide/leocad/blob/bf3f1d5db8ae0eecf194ac5178a5a12db5d3808b/appveyor.yml#L92-L95
before:
- ./linuxdeployqt*.AppImage ./AppDir/usr/share/applications/*.desktop -bundle-non-qt-libs
- ./linuxdeployqt*.AppImage --appimage-extract
- export PATH=$(readlink -f ./squashfs-root/usr/bin/):$PATH
- ./squashfs-root/usr/bin/appimagetool AppDir/
after:
- |
cat > AppDir/AppRun <<EOF
#!/bin/bash -e
this_dir="\$(readlink -f "\$(dirname "\$0")")"
export XDG_DATA_DIRS="\${this_dir}/usr/share:\${XDG_DATA_DIRS}:/usr/share:/usr/local/share"
export QT_QPA_PLATFORMTHEME=gtk3
unset QT_STYLE_OVERRIDE
# Find the system certificates location
# https://gitlab.com/probono/platformissues/blob/master/README.md#certificates
possible_locations=(
"/etc/ssl/certs/ca-certificates.crt" # Debian/Ubuntu/Gentoo etc.
"/etc/pki/tls/certs/ca-bundle.crt" # Fedora/RHEL
"/etc/ssl/ca-bundle.pem" # OpenSUSE
"/etc/pki/tls/cacert.pem" # OpenELEC
"/etc/ssl/certs" # SLES10/SLES11, https://golang.org/issue/12139
"/usr/share/ca-certs/.prebuilt-store/" # Clear Linux OS; https://github.com/knapsu/plex-media-player-appimage/issues/17#issuecomment-437710032
"/system/etc/security/cacerts" # Android
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" # CentOS/RHEL 7
"/etc/ssl/cert.pem" # Alpine Linux
)
for location in "\${possible_locations[@]}"; do
if [ -r "\${location}" ]; then
export SSL_CERT_FILE="\${location}"
break
fi
done
exec "\${this_dir}/usr/bin/leocad" "\$@"
EOF
- ./linuxdeployqt*.AppImage ./AppDir/usr/share/applications/*.desktop -appimage -always-overwrite -extra-plugins=tls -no-copy-copyright-files
Key points:
- generate your own
AppRuninstead of default soft link to add some environment variables to make better compatibility -
linuxdeployqtcan generate AppImage directly, so just use-appimageis enough. The most important is append-extra-plugins=tlsto bundle qtTLSplugin to support https
@abcfy2, Thanks.
Here are a few missed considerations regarding the LeoCAD correction:
On Appveyor, LeoCAD is built on Qt5 - see export PATH=$HOME/Qt/5.15/gcc_64/bin:$PATH in the LeoCAD appveyor.yml. However...
The most important is append -extra-plugins=tls to bundle qt TLS plugin to support https
The TLS plugin was introduced in Qt 6.2 so using the -extra-plugins=tls argument will only solicit the message:
WARNING: The plugin "/usr/lib/x86_64-linux-gnu/qt5/plugins/tls" could not be found. Please check spelling and try again!
generate your own AppRun instead of default soft link to add some environment variables to make better compatibility
It is not necessary to remove the appveyor.yml lines suggested above. Simply copy your AppRun file to AppDir before running linuxdeployqt - it will be preserved. Here is the linuxdeployqt source code that creates the AppRun link - if a file does not already exist:
QFile appRun(appDirPath + "/AppRun");
if(appRun.exists()){
qDebug() << "Keeping existing AppRun";
} else {
if (!QFile::link(relativeBinPath, appDirPath + "/AppRun")) {
LogError() << "Could not create AppRun link";
}
}
In the end the only modification to the LeoCAD appveyor.yml is to copy your AppRun file to the AppDir folder before calling linuxdeployqt. The cat content will be the AppRun file.
- cp tools/setup/AppRun AppDir
Be careful about cutting and pasting. QT_QPA_PLATFORMTHEME=gtk3
and QT_STYLE_OVERRIDE has nothing to do with qt.network.ssl.
Cheers,