49

Solved Wow, these guys are fast... It's basically this https://github.com/pyca/cryptography/issues/2750 It turned out that a security update for openssl was released (DROWN Attack) and that update contained an unexpected function signature change which caused the incompatibility, so this was just bad luck for me.


I need to use pip install cryptography in a Docker container running Alpine Linux. Actually, it's another module, service_identity, but the problem resides in the cryptography module, which is a dependency.

I have the following Dockerfile

FROM alpine:3.3

RUN apk --update add build-base libffi-dev openssl-dev python-dev py-pip
RUN pip install cryptography

which fails with the following error

generating cffi module 'build/temp.linux-x86_64-2.7/_openssl.c'
building '_openssl' extension
creating build/temp.linux-x86_64-2.7/build
creating build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7
gcc -fno-strict-aliasing -Os -fomit-frame-pointer -DNDEBUG -Os -fomit-frame-pointer -fPIC -I/usr/include/python2.7 -c build/temp.linux-x86_64-2.7/_openssl.c -o build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7/_openssl.o
build/temp.linux-x86_64-2.7/_openssl.c:726:6: error: conflicting types for 'BIO_new_mem_buf'
 BIO *BIO_new_mem_buf(void *, int);
      ^
In file included from /usr/include/openssl/asn1.h:65:0,
                 from build/temp.linux-x86_64-2.7/_openssl.c:434:
/usr/include/openssl/bio.h:692:6: note: previous declaration of 'BIO_new_mem_buf' was here
 BIO *BIO_new_mem_buf(const void *buf, int len);
      ^
error: command 'gcc' failed with exit status 1

openssl 1.0.2g was released on 2016-03-01 (yesterday) and the alpine package already got updated to that version. Can it be related to this?

How can I resolve this issue? Maybe some environment variables which I can set?

Update I've been checking the GitHub Repo for openssl, and in fact BIO *BIO_new_mem_buf(void *buf, int len) of openssl/bio.h got changed to BIO *BIO_new_mem_buf(const void *buf, int len) during the 1.0.2f to 1.0.2g transition (search for "BIO_new_mem_buf" in https://github.com/openssl/openssl/compare/OpenSSL_1_0_2f...OpenSSL_1_0_2g). I don't know where this openssl/asn1.h is coming from, which is importing an outdated version of openssl/bio.h, as it does not look like the one in the openssl repo. Any ideas?

Ok, I see some are already working on this: https://github.com/pyca/cryptography/issues/2750

Daniel F
  • 13,684
  • 11
  • 87
  • 116

5 Answers5

79

For those who are still experiencing problems installing cryptography==2.1.4 in Alpine 3.7 like this:

writing manifest file 'src/cryptography.egg-info/SOURCES.txt'
running build_ext
generating cffi module 'build/temp.linux-x86_64-2.7/_padding.c'
creating build/temp.linux-x86_64-2.7
generating cffi module 'build/temp.linux-x86_64-2.7/_constant_time.c'
generating cffi module 'build/temp.linux-x86_64-2.7/_openssl.c'
building '_openssl' extension
creating build/temp.linux-x86_64-2.7/build
creating build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7
gcc -fno-strict-aliasing -Os -fomit-frame-pointer -g -DNDEBUG -Os -fomit-frame-pointer -g -DTHREAD_STACK_SIZE=0x100000 -fPIC -I/usr/include/python2.7 -c build/temp.linux-x86_64-2.7/_openssl.c -o build/temp.linux-x86_64-2.7/build/temp.linux-x86_64-2.7/_openssl.o -Wconversion -Wno-error=sign-conversion
build/temp.linux-x86_64-2.7/_openssl.c:493:30: fatal error: openssl/opensslv.h: No such file or directory
 #include <openssl/opensslv.h>
                              ^
compilation terminated.
error: command 'gcc' failed with exit status 1

Solution

Install these dependencies in the Alpine container:

$ apk add --no-cache libressl-dev musl-dev libffi-dev

To install these dependencies using a Dockerfile:

RUN apk add --no-cache \
        libressl-dev \
        musl-dev \
        libffi-dev && \
    pip install --no-cache-dir cryptography==2.1.4 && \
    apk del \
        libressl-dev \
        musl-dev \
        libffi-dev

Reference

Installation instructions for cryptography on Alpine can be found here:

Here is the relevant portion:

Building cryptography on Linux

[skipping over the part for non-Alpine Linux]

$ pip install cryptography

If you are on Alpine or just want to compile it yourself then cryptography requires a compiler, headers for Python (if you're not using pypy), and headers for the OpenSSL and libffi libraries available on your system.

Alpine

Replace python3-dev with python-dev if you're using Python 2.

$ sudo apk add gcc musl-dev python3-dev libffi-dev openssl-dev

If you get an error with openssl-dev you may have to use libressl-dev.

damon
  • 14,485
  • 14
  • 56
  • 75
Manoj Kasyap
  • 801
  • 6
  • 5
  • Thanks for your answer. Please elaborate on the code in the answer in case the link dies. – interesting-name-here Nov 30 '18 at 17:47
  • please elobrate your answer – varnit Nov 30 '18 at 18:08
  • The Question got solved back then by the developers of the `cryptography` module, which was out of sync with the `OpenSSL` library. The approach you are mentioning here replaces `OpenSSL` with `LibreSSL`. It provides a workaround, not a solution. Are all these libraries like `tini` and so on really required? Thanks for offering an alternative approach (I'm assuming that it works, won't try it out, though). – Daniel F Nov 30 '18 at 19:47
  • While rearranging your code for proper formatting, I noticed that you are actually not installing the module `cryptography` – Daniel F Nov 30 '18 at 19:50
  • 1
    @DanielF Btw, I included tini and other libraries in example not in the actual solution. I am removing it if its too deviating.... – Manoj Kasyap Nov 30 '18 at 20:22
  • JFYI, the docker command referenced above is missing `gcc` which is required for this to work. – Android Jan 01 '21 at 18:57
  • For me adding `libressl-dev libffi-dev` solved the problem with `python:3.7-alpine` – A Campos Jan 18 '21 at 17:46
  • `libressl-dev` saved me – Song Mar 19 '21 at 08:58
  • Alpine 3.10 required `cryptography==3.3.2` – onkar May 23 '21 at 22:15
  • `libressl-dev` does not seem to work for all settings. With an outdated postgreSQL alpine image I get `ERROR: Service 'xyz' failed to build: The command '/bin/sh -c apk add libressl-dev' returned a non-zero code: 2`. – questionto42 Aug 30 '21 at 13:14
14

If it fails because of Rust version, then following is recommended in cryptography's docs:

The Rust available by default in Alpine < 3.12 is older than the 
minimum supported version. See the Rust installation instructions
 for information about installing a newer Rust.
$ sudo apk add gcc musl-dev python3-dev libffi-dev openssl-dev cargo

in my case, python3.8-alpine, adding cargo resolved.

muon
  • 12,821
  • 11
  • 69
  • 88
  • "cargo" installs "Rust" (tested). Strangely, installing Poetry and having had at least a similar error at the point when Poetry tried to install "cryptography", the error of Poetry stayed the same also with the installed "cargo", still saying that it needs "Rust". I had to install "cryptography" on its own to get the installation done, like the accepted answer does. Having an older Python version, I also had to add a chosen version, see [Failed to install cryptography package with Poetry on Python 3.9](https://stackoverflow.com/a/68985895/11154841). After that, I could install Poetry. – questionto42 Aug 30 '21 at 16:47
  • I was having this issue without docker on Ubuntu 22.04 with python 3.6. I just had to use `curl https://sh.rustup.rs -sSf | sh` and add `$HOME/.cargo/bin` to my path to get it to work. – Caleb Syring Aug 20 '22 at 14:10
0

Add this before install:

RUN apk -U upgrade

RUN apk add --no-cache libffi-dev openssl-dev

Fabián
  • 39
  • 6
0

Alternatively use build-base:

RUN apk add --no-cache --upgrade --virtual .build-deps build-base

Details here: https://git.alpinelinux.org/aports/tree/main/build-base/APKBUILD?h=3.3-stable

Zaffer
  • 1,290
  • 13
  • 32
-1

Check if you are building for the right architecture !!

x86-64 or amd64 architecture runs similar softwares and the other category is aarch64 or arm architecture chips like Apple Silicon M1 or your mobile phone cpu

Daniyal
  • 19
  • 2
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30160203) – f.khantsis Oct 24 '21 at 09:03