Skip to content

Instantly share code, notes, and snippets.

@janodev
Last active August 5, 2020 12:48
Show Gist options
  • Save janodev/3b0c3c4a1f1a40f4e1eebf4e373decd0 to your computer and use it in GitHub Desktop.
Save janodev/3b0c3c4a1f1a40f4e1eebf4e373decd0 to your computer and use it in GitHub Desktop.
Securing Apache with client certificate authorisation
[ req ]
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = Janodev Notes User
.DEFAULT_GOAL := hello
CA = ca
CA_NAME = Janodev CA
SERVER = jano
SERVER_DOMAIN = jano.dev
CLIENT = client
CLIENT_NAME = Janodev Notes User
SERVER_CONF = server.conf
CLIENT_CONF = client.conf
LIGHTSAIL_INSTANCE = janodev
# Validity can’t be more than 825 days or else they are rejected with NET::ERR_CERT_VALIDITY_TOO_LONG
VALID_DAYS=800
create: clean
# pnrg seed
cat /dev/random | head -c 1024 > ~/.rnd
# random password
cat /dev/random | base64 | head -c 32 > passphrase.txt
# create a private key
openssl genpkey -des3 -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out $(CA).key -pass file:passphrase.txt
# create a root CA certificate request
openssl req -new -sha256 -subj "/C=ES/ST=Madrid/L=Madrid/O=Jano/OU=Org/CN=$(CA_NAME)" -x509 -days $(VALID_DAYS) -key $(CA).key -out $(CA).crt -passin file:passphrase.txt
# create a private key and certificate request for the server
openssl req -newkey rsa:4096 -nodes -keyout $(SERVER).key -out $(SERVER).csr -subj "/C=ES/ST=Madrid/L=Madrid/O=Jano/OU=Org/CN=$(SERVER_DOMAIN)" -config $(SERVER_CONF)
# create a certificate for the server
openssl x509 -req -days $(VALID_DAYS) -in $(SERVER).csr -CA $(CA).crt -CAkey $(CA).key -set_serial 01 -out $(SERVER).crt -passin file:passphrase.txt -extensions req_ext -extfile $(SERVER_CONF)
# create a private key and certificate request for the client
openssl req -newkey rsa:4096 -nodes -keyout $(CLIENT).key -out $(CLIENT).csr -subj "/C=ES/ST=Madrid/L=Madrid/O=Jano/OU=Org/CN=$(CLIENT_NAME)" -config $(CLIENT_CONF)
# create a certificate for the client
openssl x509 -req -days $(VALID_DAYS) -in $(CLIENT).csr -CA $(CA).crt -CAkey $(CA).key -set_serial 02 -out $(CLIENT).crt -passin file:passphrase.txt -extensions req_ext -extfile $(CLIENT_CONF)
# copy to the remote server. Note that I copy as sudo because of permissions.
rsync -a --rsync-path="sudo rsync" $(CA).crt ubuntu@$(LIGHTSAIL_INSTANCE):/etc/apache2/client-certs/$(CA).crt
rsync -a --rsync-path="sudo rsync" $(SERVER).crt ubuntu@$(LIGHTSAIL_INSTANCE):/etc/apache2/client-certs/$(SERVER).crt
rsync -a --rsync-path="sudo rsync" $(SERVER).key ubuntu@$(LIGHTSAIL_INSTANCE):/etc/apache2/client-certs/$(SERVER).key
# restart Apache
ssh ubuntu@$(LIGHTSAIL_INSTANCE) "sudo apachectl restart"
# Install the CA in the keychain. This will ask for the account password.
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain $(CA).crt
# Package the client certificate, private key, and CA certificate in a PFX container suitable to be imported in a browser.
openssl pkcs12 -export -out $(CLIENT).pfx -inkey $(CLIENT).key -in $(CLIENT).crt -certfile $(CA).crt -passout file:passphrase.txt
pbcopy < passphrase.txt
@echo Paste pfx password from clipboard.
say Paste pfx password from clipboard.
open $(CLIENT).pfx
hello:
@echo Type \'make create\', or \'make clean\'.
clean:
rm -f $(CA).crt
rm -f $(CA).key
rm -f $(SERVER).key
rm -f $(SERVER).csr
rm -f $(SERVER).crt
rm -f $(CLIENT).key
rm -f $(CLIENT).csr
rm -f $(CLIENT).crt
rm -f $(CLIENT).pfx
sudo security delete-certificate -c "$(CA_NAME)" | true
sudo security delete-certificate -c "$(CLIENT_NAME)" | true
sudo security delete-certificate -c "$(CA_NAME)" /Library/Keychains/System.keychain | true
[ req ]
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = jano.dev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment