Skip to content

Instantly share code, notes, and snippets.

@pawohl
Last active January 29, 2018 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pawohl/cafbc6917d637e0d47917512fd2be932 to your computer and use it in GitHub Desktop.
Save pawohl/cafbc6917d637e0d47917512fd2be932 to your computer and use it in GitHub Desktop.
Notes on how to upgrade OpenCast from HTTP to full HTTPS

Upgrading Opencast 2.2 to HTTPS

Disclaimer: We are using the opencast-docker images: admin, worker and presentation

Note: This value will be written to all generated mediapackages and thus cannot be changed easily for already processed media. At least not without an extra amount of work involving modifications to the database. That is why you should think about this setting carefully.

This naturally is not only relevant to domain changes but also to schema/ protocol or port changes, including upgrading from HTTP to HTTPS after media packages have been processed.

HTTPS for Opencast, why?

Your site visitor's privacy. While ISPs and public HotSpot operators and those who sniff unencrypted WiFi traffic might be able to see your visitors connecting to your site, they can't see, which video is watched when HTTPS is enabled. Think of a lecture about the human rights situation in China and a visitor from there watching the video. Or someone wanting to gain access, stealing your user's session cookies or credentials.

How can HTTPS be enabled in Opencast?

This is the "easy" part. Either install a proxy, or in opencast/etc/, use the org.ops4j.pax.web.cfg file for configuration:

# ...

# Whether Opencast itself should handle HTTPS traffic.
# Even if you set this to 'false',you can still use an HTTP proxy to handle SSL.
org.osgi.service.http.secure.enabled=true

# The secure server port to use if running Opencast with HTTPS (as opposed to
# a proxy handling HTTPS).
# Note that we use the docker proxy for the port-mapping from 8843 from within
# the container to 443 at the host
# Don't run Opencast with root privileges, which is a security issue
org.osgi.service.http.port.secure=8443

# Path to the keystore file.
# Use the Java `keytool` to generate this file.
# Example:
#   keytool -genkey -keyalg RSA -validity 365 -alias serverkey \
#     -keypass password -storepass password -keystore keystore.jks
org.ops4j.pax.web.ssl.keystore=<path_to_keystore>

# Password used for keystore integrity check.
org.ops4j.pax.web.ssl.password=<the_keystore_password>

# Password used for keystore.
org.ops4j.pax.web.ssl.keypassword=<the_key_password>

Creating the keystore

What you need, is the TLS private key and the certificate including the whole chain between the root certificate, all intermediates and the certificate itself.

Obtaining the certificate chain

If you only have the key and the certificate, I recommend certificatechain.io or cert-chain-resolver. The latter can be used as follows:

# Obtain the chain for cert.pem and save it at opencast.chain.pem.tmp
# The -s command switch includes the root certificate; this is not
# mandatory and might add some overhead
cert-chain-resolver -s -o "opencast.chain.pem.tmp" "cert.pem"

# Verify the certificate using the chain
openssl verify -crl_download -crl_check -untrusted "opencast.chain.pem.tmp" "cert.pem"

Create the p12 keystore

If the private key (assumed to be key.pem) is encrypted (password protected), issue the following command. Note that there are safer ways supplying the key's password to OpenSSL.

openssl pkcs12 \
        -export \
        -inkey "key.pem" \
        -passin "pass:<the_keys_password>" \
        -in "opencast.chain.pem.tmp" \
        -name "serverkey" \
        -out "opencast.p12" \
        -passout "pass:<the_keystore_password>"

In case the private key is not protected by password:

openssl pkcs12 \
        -export \
        -inkey "key.pem" \
        -in "opencast.chain.pem.tmp" \
        -name "serverkey" \
        -out "opencast.p12" \
        -passout "pass:<the_keystore_password>"

Import the p12 keystore into a Java keystore:

keytool \
        -importkeystore \
        -srckeystore "opencast.p12" \
        -srcstoretype "pkcs12" \
        -srcstorepass "<the_keystore_password>" \
        -destkeystore "keystore.jks" \
        -storepass "<the_keystore_password>"
# print out details about the JKS built
keytool \
        -keystore "keystore.jks" \
        -list \
        -destalias serverkey \
        -storepass "<the_keystore_password>"

After reading that, you may find this shell script useful.

Editing the media packages, recreating indices

  1. Backup your database, and the solr and adminui indices.
  2. Tell your other Opencast systems to use HTTPS for each other, or at least for the system delivering the videos to the visitors and creating the search indices.
  3. Put all your nodes into maintenance mode, or, at least do not process any videos.
  4. Update the media packages: find . -type f -name "*.xml" -exec \ sed -i 's/http\:\/\/presentation\.opencast\.example\.com\:80/https:\/\/presentation.opencast.example.com/g' {} +
  5. Update 2 database tables:
   UPDATE opencast.mh_archive_episode
   SET mediapackage_xml =
      REPLACE( mediapackage_xml,
               'http://presentation.opencast.example.com:80',
               'https://presentation.opencast.example.com')
      WHERE INSTR( mediapackage_xml,
                   'http://presentation.opencast.example.com:80') > 0;
   UPDATE opencast.mh_search
   SET mediapackage_xml =
      REPLACE( mediapackage_xml,
               'http://presentation.opencast.example.com:80',
               'https://presentation.opencast.example.com')
      WHERE INSTR( mediapackage_xml,
                   'http://presentation.opencast.example.com:80') > 0;
  1. Rebuild the AdminUI (lucene?) indices. Visit your REST API and push the button: https://admin.opencast.example.com/docs.html?path=/admin-ng/index
  2. Move the old Solr search indices away. There might be a directory named solr-indexes/search but its configuration really depends on org.opencastproject.solr.dir, or if set in custom.properties, org.opencastproject.search.solr.dir
  3. Rebuild the Solr indices. For this to work, make sure to have a service serving mediapackages running (e.g. a presentation node). Start another node, whose task is to re-index episodes (e.g. a second presentation). Ensure the JVM of the indexing service has sufficient virtual memory.
@pawohl
Copy link
Author

pawohl commented Aug 16, 2017

This document is licensed CC-0. I am the author.

@pawohl
Copy link
Author

pawohl commented Aug 16, 2017

Hi community,
we just recently upgraded implemented HTTPS on our servers. After we did that, we found that static content was still served over HTTP because the media packages and the indices had URIs containing the scheme hardcoded in them triggering mixed-content warnings in browsers.
Might be helpful for anyone who's not a professional Opencast or not even familiar with how Java implements HTTPS.

@lkiesow
Copy link

lkiesow commented Aug 21, 2017

Hi, since you spent some time writing this guide, you might want to consider submitting it as part of the official documentation. I think what's left is only to add some notes about the use of reverse proxies which I could offer to add. If you want to help, please create a pull request.

One more thing: Opencast has no capital “C” in its name. If possible, could you fix that before other people start picking up that error?

@Rillke
Copy link

Rillke commented Nov 20, 2017

One more thing: Opencast has no capital “C” in its name.

@lkiesow That is fixed.

I re-read the guide and in order to fit into Opencast's documentation some adjustments are required.

@pawohl
Copy link
Author

pawohl commented Jan 29, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment