Bundling SSL Certificates with PyInstaller and aiohttp

Mar 3, 2024 ยท 2 min read

When building executables with PyInstaller for Python applications that use aiohttp and SSL, you need to ensure the SSL certificates and configuration are bundled properly for the app to function correctly. This article provides guidance on the key steps.

Include certifi with PyInstaller

The certifi package provides Mozilla's curated list of root CA certificates that SSL connections rely on to validate certificates. Include this as a hidden import in your .spec file so PyInstaller bundles it:

a = Analysis(['your_app.py'],
             hiddenimports=['certifi'],
             hookspath=[])

Bundle CA file location

By default, aiohttp expects the CA file path to be available in the SSL_CERT_FILE environment variable at runtime.

When freezing to an executable, the environment is isolated, so you need to configure aiohttp to load the CA file from the bundled certifi resources instead.

import certifi
import aiohttp

ssl_context = aiohttp.ClientSSLContext()
ssl_context.load_verify_locations(cafile=certifi.where())

OpenSSL linking on Linux

If building a Linux executable, you may hit an error about missing OpenSSL libraries. To resolve this:

  1. Install openssl-devel system package
  2. Set the LDFLAGS option in PyInstaller to link the OpenSSL libraries:
pyinstaller --add-data certifi:certifi \
             --hidden-import certifi \ 
             --runtime-tmpdir . \  
             --ldflags '-Wl,-rpath,$$ORIGIN/lib' \
             your_app.py

The key part is --ldflags pointing to the bundled OpenSSL files location to resolve linking.

Avoid openssl.cnf issues

Bundling the OpenSSL config file openssl.cnf can cause issues with path conflicts when running the packed executable.

Avoid this by specifying the OPENSSL_CONF environment variable to use the bundled file:

import os
os.environ['OPENSSL_CONF']=os.path.dirname(certifi.where()) + '/openssl.cnf' 

Troubleshooting Issues

Some common issues to check if your app doesn't connect properly over SSL after bundling with PyInstaller:

  • Ensure certifi is imported and CA file path set correctly.
  • Check for any OpenSSL linking errors during packaging.
  • Try unpacking the executable and check if CA certificates and config files are bundled.
  • Make sure no conflicts or permission issues accessing the CA resources at runtime.
  • Bundling SSL resources properly while freezing apps with PyInstaller takes some trial-and-error, but these tips should help troubleshoot and get everything working smoothly.

    Browse by tags:

    Browse by language:

    The easiest way to do Web Scraping

    Get HTML from any page with a simple API call. We handle proxy rotation, browser identities, automatic retries, CAPTCHAs, JavaScript rendering, etc automatically for you


    Try ProxiesAPI for free

    curl "http://api.proxiesapi.com/?key=API_KEY&url=https://example.com"

    <!doctype html>
    <html>
    <head>
        <title>Example Domain</title>
        <meta charset="utf-8" />
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    ...

    X

    Don't leave just yet!

    Enter your email below to claim your free API key: