LinkedIn Sourceforge

Vincent's Blog

Pleasure in the job puts perfection in the work (Aristote)

Install python3 inside an OpenBSD chroot environment for later cgi scripts

Posted on 2026-02-17 20:19:00 from Vincent in got

On OpenBSD, the built-in httpd runs inside a strict chroot located at /var/www, which greatly improves security but also limits available system resources. When trying to execute Python CGI scripts, administrators often encounter missing shared library errors. This happens because the chroot environment does not automatically include the base system libraries required by Python. In this article, we’ll walk through the exact steps needed to properly install Python 3.12 inside the OpenBSD chroot and make it fully functional.


Photo by Saad Chaudhry on Unsplash

Installing Python 3.12 Inside an OpenBSD Chroot (httpd /var/www)

Running CGI scripts with OpenBSD’s httpd, or nginx, means working inside the default chroot located at /var/www.
If you try to execute a Python script inside that chroot without preparing the environment correctly, you will quickly face missing library errors such as:

ld.so: python3.12: can't load library 'libpython3.12.so.0.0'

This article explains step-by-step how to properly install Python 3.12 inside /var/www and resolve all required shared library dependencies.

1. Preparing the /dev Directory Inside the Chroot

The chroot needs its own minimal /dev structure.

mkdir /var/www/dev
cp /dev/MAKEDEV /var/www/dev
cd /var/www/dev
./MAKEDEV std

This creates the standard device nodes required for basic operation.

2. Preparing the Dynamic Linker Environment

The dynamic linker inside the chroot must know where to find shared libraries.

Create Required Directories

cd /var/www
mkdir etc
mkdir sbin

Configure Library Search Paths

Create /var/www/etc/ld.so.conf:

echo "/usr/lib" >> etc/ld.so.conf
echo "/usr/local/lib" >> etc/ld.so.conf

Copy ldconfig Into the Chroot

cp /sbin/ldconfig sbin

Generate the Library Cache

chroot /var/www ldconfig /usr/lib /usr/local/lib

At this stage, the chroot is capable of handling shared libraries — provided they exist inside it.

3. Attempting to Install Python

Now try installing Python into the chroot:

pkg_add -B /var/www python

You will likely see errors like:

Can't install python-3.12.11 because of libraries
| library crypto.57.1 not found
| library curses.16.0 not found
| library expat.17.0 not found
| library panel.7.0 not found
| library pthread.28.0 not found
| library readline.6.0 not found
| library ssl.60.1 not found

This happens because pkg_add -B installs into the alternate root but does not automatically copy base system shared libraries into the chroot.

4. Manually Copy Required Shared Libraries

You must manually copy the required libraries from the host system into the chroot.

Copy Base System Libraries

cd /usr/lib
cp -p         libcrypto.so.*         libssl.so.*         libcurses.so.*         libpanel.so.*         libexpat.so.*         libpthread.so.*         libreadline.so.*         /var/www/usr/lib/

Copy other required Libraries

cp /usr/local/lib/libintl.so.8.1 /var/www/usr/local/lib/
cp /usr/local/lib/libiconv.so.7.1 /var/www/usr/local/lib/
cp /usr/lib/libpthread.so.28.0 /var/www/usr/lib/

Make sure the directory structure exists:

mkdir -p /var/www/usr/lib
mkdir -p /var/www/usr/local/lib

5. Run pkg_add Again

Now retry:

pkg_add -B /var/www python

This time, the installation should proceed correctly.

6. Why This Is Necessary

In OpenBSD:

  • The base system libraries live in /usr/lib
  • Third-party packages live in /usr/local/lib
  • httpd runs inside /var/www
  • The chroot is intentionally minimal to enhance security

Because of this isolation, shared libraries must be explicitly present inside the chroot, otherwise the dynamic linker cannot resolve dependencies.

7. Important Notes

  • Every OpenBSD upgrade may change library versions → you must re-copy updated .so files.
  • Running ldd /path/to/binary helps identify missing dependencies.
  • Keep the chroot minimal — only copy what is strictly required.
  • If you need additional Python modules later, you may have to copy further dependencies.

8. Conclusion

You now have:

  • A working Python 3.12 installation inside /var/www
  • A functional dynamic linker configuration
  • A properly prepared chroot environment for CGI scripts

This setup allows you to safely run Python-based CGI scripts under OpenBSD’s httpd while keeping the strong security model of the default chroot.



0, 0
displayed: 36



What is the first letter of the word Moon?