py-boto and LibreSSL

Having just recently performed an upgrade of OpenBSD 5.6 to OpenBSD 5.7, duplicity (my backup tool), stopped working for no apparent reason.

At first, I thought it had something to do with the 0.6 branch becoming deprecated, but in the end I found out that this was just a warning message.

Although the error message issue has been fixed in the 0.7 branch of duplicity, what was causing the issue while debugging was really hard to determine:

  File "/usr/local/lib/python2.7/site-packages/duplicity/backends/_boto_single.py", line 297, in _list raise BackendException("No connection to backend")
BackendException: No connection to backend

As you can see, the above message could mean any number of things, from AWS connectivity to a broken implementation due to the recent upgrade.

Digging around in the bug tracker for duplicity, users have had an issue with the pretty average output from errors, specifically to AWS S3.  So a correction was made to the 0.7 branch to fix the output and I decided to implement that in the 0.6 branch to see if I could get some better output.

In the /usr/local/lib/python2.7/site-packages/duplicity/backends/_boto_single.py file, I searched for:

self.bucket = self.conn.lookup(self.bucket_name)

and replaced it with:

self.bucket = self.conn.get_bucket(self.bucket_name)

This then gave me a far more descriptive error to work with.  I now got the following error (shortened for clarity):

  File "/usr/local/lib/python2.7/ssl.py", line 350, in wrap_socket
    _context=self)
  File "/usr/local/lib/python2.7/ssl.py", line 566, in __init__
    self.do_handshake()
  File "/usr/local/lib/python2.7/ssl.py", line 796, in do_handshake
    match_hostname(self.getpeercert(), self.server_hostname)
  File "/usr/local/lib/python2.7/ssl.py", line 269, in match_hostname
    % (hostname, ', '.join(map(repr, dnsnames))))
CertificateError: hostname 'something.bucket.s3.amazonaws.com' doesn't match either of '*.s3.amazonaws.com', 's3.amazonaws.com'

This was very interesting, as nothing has changed to the bucket or name since the upgrade.  So I tried doing a test backup using –s3-unencrypted-connection.  This was successful.  So now I know the transport and buckets were ok, it has something to do with the TLS/SSL component of the connection.

Again, looking at the above error and knowing that this version of OpenBSD now uses only LibreSSL this could be an explicit issue.  Wildcard SSL certificates are only applicable to immediate hosts, not multiple sub domains.  Technically, my bucket in ‘SSL speak’ would never pattern match the SSL certificate that was presented by AWS.  Maybe in the past, OpenSSL was not as strict at ensuring the hostname matched the applicable certificate but based on the rigor and attention to detail that the LibreSSL and OpenBSD teams have to security, this gap has now been fixed – probably to avoid a man-in-the-middle attack.

I created a new bucket, for example, using the above as an example – something-bucket instead of something.bucket.  I then ran a test backup and it all worked successfully.

My finial observation is, even though AWS lets you name S3 buckets that contain periods (yet they don’t let you use underscores), still don’t do it.  At some point it is going to break and you might not be so lucky to determine what the problem is.  Simply: Don’t use . in AWS S3 bucket names.