Secure Owncloud setup

While the Owncloud Manual suggests enabling SSL, it unfortunately does not go into detail how to get a secure setup. The core problem is that the default SSL settings of Apache are not sane as in they do not enforce strong encryption. Furthermore the used default certificate will not match your server name and produce errors in the browser.

In the following a short guide in how to set-up a secure Apache 2.4 server for Owncloud will be presented.

Generating a secure Certificate

A secure TLS connection starts with the Server authenticating itself to the client with the server certificate. Therefore we will start the setup of our server with generating that certificate.
The purpose of the certificate is to ensure that if you type in “your.website.net” you are indeed talking to your server and not to a man-in-the-middle who intercepted your connection. Therefore the certificate contains the server name and the public key of the server.

As mentioned above the default certificate will not match your server name and therefore you will have to generate a matching one.

Unfortunately following the apache SSL FAQ will results in a certificate using the possibly vulnerable SHA-1 hashing function. A better alternative is SHA-256, but it has to be explicitly requested during certificate creation. The according call to openssl for certificate creation is

openssl req -new -sha256 -x509 -nodes -days 365 -out your.website.net.pem -keyout your.website.net.key

The resulting certificate and private key have to be referenced in your website configuration. On Debian/ Ubuntu you have to edit
/etc/apache2/sites-enabled/owncloud.conf

SSLCertificateFile    /path/to/your.website.net.pem
SSLCertificateKeyFile /path/to/your.website.net.key

Note that this results in a so called self-signed certificate. Usually certificates on the web are approved by a Certificate Authority (a digital notary) which confirms your identity. By trusting the CA you can also trust websites that are otherwise unknown to you, but which were approved by the CA.
While this makes sense for public websites, you probably already trust your own server, so there is no need for a CA signed certificate.
Just add your self-signed certificate to the trusted list of your browser on first visit.
If you fear a man-in-the-middle attack during the initial connection, you can also manually copy the generated pem file on a USB-drive and import it in the browser from there.

Using secure ciphers

Using the secure certificate we only know that we are indeed talking to the server we want to talk to. Next we actually want to start sending encrypted messages. In theory we could encrypt data with the public key of the server using asymmetric encryption like RSA. However asymmetric encryption is slow and therefore not suitable for large amounts of data. Furthermore our communication could be decrypted if somebody would record it and at some point in the future get access to the private key of the server. Therefore we want to use a one-time symmetric key. This way we achieve forward secrecy.The symmetric encryption should be also secure in a sense that even when large amounts of data is collected, it is must not be possible to reconstruct the key and decode the data.
Last but not least the chosen cipher should be supported by our clients. Surprisingly it is the Owncloud desktop client which does not support modern ciphers, while current browsers and even the android app does.

Instead of discussing all available ciphers in regard of the above requirements, I would rather refer to the excellent TLS server configuration guide by Mozilla.
Yet we can still improve the suggested configuration. Mozilla has to consider compability with old web-browsers which we do not have to. So without further ado this is the recommend cipher configuration

SSLProtocol all -SSLv2 -SSLv3
SSLCompression off
SSLHonorCipherOrder On
SSLCipherSuite EECDH+AESGCM:EECDH+AES

The rationale behind this suggestion is

  • Allow TLS 1.0 for compability with mobile apps
  • Disable SSL compression to mitigate the CRIME attack
  • always use Diffie Hellman(DH) key exchange(Kx) for forward secrecy
  • use Elliptic Curve Diffie Hellman (ECDH) variant for performance
  • always use AES for symmetric encryption
  • prefer AES GCM mode for security and performance

Notes

The only reason for allowing TLSv1 is compability with the mobile apps because openssl on android up to 4.4 does not yet support TLS1.1+. This circumstance is not really critical as BEAST is not applicable in the sync apps and browsers will connect to the server with TLS1.1+ or work around the vulnerability.
However if you are on android 5.0+ you can add -TLSv1 to SSLProtocol to enforce a TLS1.1+ connection.

Update: The issue with the Owncloud desktop client that forced us to enable non EC DH key exchange was fixed in version 1.7.1.
If you need compatibility with desktop clients older than 1.7.1 append EDH+AES to SSLCipherSuite
However besides being much slower than ECDH, a weak modulus is used for DH Kx up to (including) Apache 2.4.6. While there are no practical attacks exploiting this yet, we can only be completely on the safe side by updating to Apache 2.4.7.

To see which actual ciphers the SSLCipherSuite determines, run

openssl ciphers -V 'EECDH+AESGCM:EECDH+AES -SSLv3'

possible output:

 0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
 0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
 0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
 0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
 0xC0,0x28 - ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
 0xC0,0x24 - ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
 0xC0,0x27 - ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
 0xC0,0x23 - ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256

 

Enforcing HTTPS

At this point the secure connection to your server is ready, but we still have to ensure that it is the only way data is exchanged with the clients.
While you can only enable apache on port 443, you will always have to remember to type in https:// in the browser. A better way is to automatically redirect from port 80 to port 443 like

<VirtualHost *:80>
        ServerName your.website.net
        Redirect permanent / https://your.website.net/
</VirtualHost>

Note that you do not have to use mod_rewrite here as Owncloud sets the HSTS header, so browsers will automatically prefix all requests with https after the first visit.

But whatever you do, remember this

  • https://ohkashdoller.wordpress.com/ Kash Dymé

    The code you are mentioning in the boxes, are they supposed to be in a config file somewhere? If so, what are the names? You lost me there.

  • Daniel Ferradal

    I noticed for android clients I couldn’t get connection to SSL connection to work correctly until I also added:

    ECDHE-RSA-AES256-SHA (which is TLSv1)

    …as a valid cipher in the list you provided.

    Cheers

  • http://cloudberry.pl Łukasz Przeniosło

    Hello there, I am trying to use you guide but I am lost at the “cipters” section. I dont know where to type that part. I tried to do it in default-ssl.conf but after that I cannot connect to the website using https and also my windows client cannot connect. I would aprichiate any help. So far I have generated the keys and replaced the path to them in the default-ssl.conf + added those “citers”. Also forwarded the port in default.conf.

  • Pingback: SSL configuration problem topic | ubuntu()

  • Will O’Neal

    Cant you tell me where I would “The resulting certificate and private key have to be referenced in Apache as following”?

    Where do I reference that in Apache?

  • geoIndigo

    This has taken some pain! Owncloud initially kept crashing when I tried to redirect the account to https, but works after enforcing https via port 443. But no matter what I can’t seem to get Chrome to accept the certificate, which is an annoyance more than anything.