Adding SSL (HTTPS) to Sourcegraph with a self-signed certificate

This is for external Sourcegraph instances that need a self-signed certificate because they don't yet have a certificate from a globally trusted Certificate Authority (CA). It includes how to get the self-signed certificate trusted by your browser.

Configuring NGINX with a self-signed certificate to support SSL requires:

  1. Installing mkcert.
  2. Creating the self-signed certificate
  3. Configuring NGINX for SSL
  4. Changing the Sourcegraph container to listen on port 443
  5. Getting the self-signed certificate to be trusted (valid) on external instances

1. Installing mkcert

While the OpenSSL CLI can can generate self-signed certificates, its API is challenging unless you're well versed in SSL.

A better alternative is mkcert, an abstraction over OpenSSL written by Filippo Valsorda, a cryptographer working at Google on the Go team.

To set up mkcert on the Sourcegraph instance:

  1. Install mkcert
  2. Create the root CA by running:
sudo CAROOT=~/.sourcegraph/config mkcert -install

2. Creating the self-signed certificate

Now that the root CA has been created, mkcert can issue a self-signed certificate (sourcegraph.crt) and key (sourcegraph.key).

sudo CAROOT=~/.sourcegraph/config mkcert \
  -cert-file ~/.sourcegraph/config/sourcegraph.crt \
  -key-file ~/.sourcegraph/config/sourcegraph.key \
  $HOSTNAME_OR_IP

Run sudo ls -la ~/.sourcegraph/config and you should see the CA and SSL certificates and keys.

3. Adding SSL support to NGINX

Change the default ~/.sourcegraph/config/nginx.conf by:

1. Replacing listen 7080; with listen 7080 ssl;.

2. Adding the following two lines below the listen 7080 ssl; statement.

ssl_certificate         sourcegraph.crt;
ssl_certificate_key     sourcegraph.key;

The nginx.conf should now look like:

...
http {
    ...
    server {
       ...
        listen 7080 ssl;
        ssl_certificate         sourcegraph.crt;
        ssl_certificate_key     sourcegraph.key;
        ...
    }
}

4. Changing the Sourcegraph container to listen on port 443

Now that NGINX is listening on port 443, we need the Sourcegraph container to listen on port 443 by adding --publish 443:7080 to the docker run command:

docker container run \
  --rm  \
  --publish 7080:7080 \
  --publish 2633:2633 \
  --publish 443:7080 \
  \
  --volume ~/.sourcegraph/config:/etc/sourcegraph  \
  --volume ~/.sourcegraph/data:/var/opt/sourcegraph  \
  sourcegraph/server:3.10.1

Run the new Docker command, then validate by opening your browser at https://$HOSTNAME_OR_IP.

If running Sourcegraph locally, the certificate will be valid because mkcert added the root CA to the list trusted by your OS.

5. Getting the self-signed certificate to be trusted (valid) on external instances

To have the browser trust the certificate, the root CA on the Sourcegraph instance must be installed locally by:

1. Installing mkcert locally

2. Downloading rootCA-key.pem and rootCA.pem from ~/.sourcegraph/config/mkcert on the Sourcegraph instance to the location of mkcert -CAROOT on your local machine:

# Run locally: Ensure directory the root CA files will be downloaded to exists
mkdir -p "$(mkcert -CAROOT)"
# Run on Sourcegraph host: Ensure `scp` user can read (and therefore download) the root CA files
sudo chown $USER ~/.sourcegraph/config/root*
# Run locally: Download the files (change username and hostname)
scp [email protected]:~/.sourcegraph/config/root* "$(mkcert -CAROOT)"

3. Install the root CA by running:

mkcert -install

Open your browser again at https://$HOSTNAME_OR_IP and this time, your certificate should be valid.

Getting the self-signed cert trusted on other developer machines

This is largely the same as step 5, except easier. For other developer machines to trust the self-signed cert:

  • Install mkcert.
  • Download the rootCA-key.pem and rootCA.pem from Slack or other internal system.
  • Move the rootCA-key.pem and rootCA.pem files into the mkcert -CAROOT directory on their machine.
  • Run mkcert -install on their machine.

Next steps