/ca

Scripts for becoming a certificate authority and creating self-signed certificates

Primary LanguagePythonMIT LicenseMIT

Self-signed certificates

Become a Certificate Authority and sign your own certificates.

Based on scripts found at https://stackoverflow.com/questions/7580508/getting-chrome-to-accept-self-signed-localhost-certificate

Instructions

Before you start:

  • You need a real or fake hostname (like mypc.example.com) that points to the server. You can set this up using your hosts file or some form of DNS.

Create a Certificate Authority (CA)

./create_certificate_authority.py --help
  • Be sure to encrypt the private key, and store the password in a proper password manager.
  • You can do this once, and generate many certificates from the one CA.
  • Any client that has the CA will trust all certificates generated by the CA.

Create a certificate using the CA

./create_certificate.py --help
  • You will need the password of the private key of the CA.

Install the CA on the client

Globally on Ubuntu (also works on LinuxMint)

Normally, the CA file ends with .pem and the certificate file ends with .crt. However, Ubuntu wants the CA file to end in .crt. Don’t get confused between these two files!

  1. Make a link to your CA in /usr/local/share/ca-certificates
    ln -s /path/to/caname_ca.pem /usr/local/share/ca-certificates/caname_ca.crt
  2. Update your CA Store
    sudo update-ca-certificates

Globally on Windows

See https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate

Locally in Chrome

For Chrome on Windows, see https://blog.eldernode.com/install-root-certificate-in-chrome/

Locally in Firefox

See https://support.mozilla.org/en-US/kb/setting-certificate-authorities-firefox

Install the certificate on the server

Nginx

In your site config, e.g. at /etc/nginx/sites-enables/mysite, replacing 443 with your preferred port, and tld with the same domain name for which you generated the certificate:

server {
  listen 443 ssl;
  server_name tld;
  ssl_certificate "/path/to/tld.crt";
  ssl_certificate_key "/path/to/tld.key";
  ...
}

ISPConfig

On the website's SSL tab, paste the contents of these files into the corresponding fields:

  • out/ca/domain/private.key → SSL Key
  • out/ca/domain/request.csr → SSL Request
  • out/ca/domain/certificate.crt → SSL Certificate
  • out/ca/root.pem → SSL Bundle

Source: https://www.httpcs.com/en/help/certificats/tutorial/how-to-install-an-ssl-certificate-on-ispconfig

Kubernetes

Create the TLS secret

Here {{ .Values.crt | b64enc }} is helm syntax. If you are not using helm, replace this with the base64-encoded contents of the corresponding files.

apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
  name: my-certificate
  namespace: my-app
data:
  tls.crt: {{ .Values.crt | b64enc }}  # From `out/ca/domain/certificate.crt`
  tls.key: {{ .Values.key | b64enc }}  # From `out/ca/domain/private.key`

Alternatively, you can generate the above snippet using kubectl:

kubectl create secret tls --help
kubectl create secret tls my-certificate --key out/ca/domain/private.key --cert out/ca/domain/certificate.crt --dry-run=client --output=yaml 
Use the TLS secret in an ingress

This assumes you are using the nginx ingress controller.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-app
spec:
  tls:
    - hosts:
        - mypc.example.com  # This has to be one of the domains passed to `create_certificate.py`.
      secretName: my-certificate

Using your CA with cert-manager in Kubernetes

You can generate a root CA and give it to cert-manager to have certificates automatically generated for you Kubernetes ingresses. Then you don't need the create_certificate.py script.

See https://cert-manager.io/docs/configuration/ca/