3

I have a (private) apt repository setup on a server. I'm only allowing access to this repository over SSL, and only with a client certificate. I have tested the connection using curl:

$ curl --cacert /opt/CA.crt --cert /opt/user.crt --key /opt/user.key --pass 1234 https://example.com/dists/lucid/main/binary-amd64/Packages.gz

The content is downloaded as expected.

I've created a file in /etc/apt/apt.conf.d/45example-com with

Debug::Acquire::https "true";

Acquire::https::example.com {
    Verify-Peer "true";
    Verify-Host "true";

    CaInfo "/opt/CA.crt";

    SslCert "/opt/user.crt";
    SslKey  "/opt/user.key";
};

I've added a file at /etc/apt/sources.list.d/example.com.list with:

deb https://example.com/ lucid main

There seems to be a problem with the CA cert, when I try an update I get the following:

# apt-get update
* Connected to example.com (8.0.0.8) port 443 (#0)
* found 1 certificates in /opt/CA.crt
* error reading X.509 key or certificate file
* Closing connection #0

The server logs on example.com show that no request got there, so I guess that apt-get is failing before trying to send the request (which matches what the log says).

I've had a hard time finding any documentation on apt-get with ssl on the interwebs, and haven't even been able to find the source code.

Does anyone have any ideas?

3 Answers 3

2

After some searching I have a better idea of what is happening (but no solution yet).

I found the source code for apt at https://code.launchpad.net/~ubuntu-branches/ubuntu/lucid/apt/lucid. It uses libcurl for ssl, which in turn uses gntls.

The error message comes from libcurl, and it is complaining about the key/password, not the CA certificate. The line:

* found 1 certificates in /opt/CA.crt

is saying that CA.crt was correctly loaded. The error message comes from the following:

if(gnutls_certificate_set_x509_key_file(
     conn->ssl[sockindex].cred,
     data->set.str[STRING_CERT],
     data->set.str[STRING_KEY] ?
     data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
     do_file_type(data->set.str[STRING_CERT_TYPE]) ) !=
   GNUTLS_E_SUCCESS) {
  failf(data, "error reading X.509 key or certificate file");
  return CURLE_SSL_CONNECT_ERROR;
}

(From gtls.c in http://alpha.gnu.org/gnu/gnutls/libtasn1-0.2.10.tar.gz)

The problem is with the password that is associated with that key. I've stripped the password from the key using:

$ openssl rsa -in user.key -out user-nopasswd.key

This isn't ideal, but it seems to work.

0

One issue I ran into while attempting to get apt-get to run over https was that for the SslCert option you cannot use a .pem file as apt-get will fail to recognize this as a valid format for use with connecting to your repository. I have a self signed .pem that I use to connect to my webserver and it is in a .pem format which is why I attempted to use it.

The solution was to just split the .pem into the correct files a .crt and a .key and apt-get successfully connected.

TLDR: split your .pem file into a .crt and a .key and it will work.

0

Actually, you don't have to split them as @ihatecache stated, you can set both cert and key as single pem:

Acquire::https {
            SslCert "/opt/user.pem";
            SslKey  "/opt/user.pem";
        };
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .