Git, Apache and HTTPS with a free certificate
Prerequisites
- Ubuntu CLI understanding
- Git knowledge
- Ubuntu, this was tested using Ubuntu 16
- Apache 2
Git using Apache
This is a basic setup to allow Git on a server to be accessible via HTTP (no HTTPS yet, read further).
- Install Apache
sudo apt-get install apache2 apache2-utils
- Enable necessary modules
a2enmod cgi alias env
- (Optional) Add user(s) to the htpasswd file. This step is optional if this setup is going to serve only anonymous repository (pull/fetch). However if you want to push or if you want to allow to only obtain a repository using user/pass combo this step is necessary (see next step).
# Create file and add a user # -c = create file # The file is stored in /git/ the git repository for this specific setup htpasswd -c /git/.htpasswd [user name] # This will ask for a password # Add a user to the file htpasswd /git/.htpasswd [user name]
- To allow to obtain a git repository using http, add the following to the apache2.conf
# Path to the Git directory (inside the OS) SetEnv GIT_PROJECT_ROOT /git # Allows all projects to be served # If commented a file must exist in each available repository via Apache, file name: git-daemon-export-ok SetEnv GIT_HTTP_EXPORT_ALL # Defines the URL path where git is located, as seen via http # First param is path, second is os path to git-http-backend, don't forget the last slash ScriptAlias /git/ /usr/lib/git-core/git-http-backend/ # Access configuration <Files "git-http-backend"> # Enable Basic HTTP Authentication AuthType Basic AuthName "Git Access" AuthUserFile /git/.htpasswd # The following line allows to obtain a repository (pull/fetch) without having a user/pass combo # Comment it if user/pass are needed to obtain info as well Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#) Require valid-user # END Enable Basic HTTP Authentication </Files>
Additional info:
- Git - Smart HTTP
- Git - git-http-backend Documentation
- For more info on htpasswd, read the docs.
Self signed Certificate
How Certificates work
Here are some videos on how certificates and SSL (TLS) work:
Additional info:
- What is the SSL Certificate Chain? - DNSimple Help, explains how the certificate chain works.
- Types of SSL certificates – choose the right one | Symantec Connect, explains the different certificate types that can be used.
- DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them, explains different file types for certificates.
- X.509 - Wikipedia, X.509 public key certificate standard.
Why certificates are needed
To allow git to be served using https the server must have a certificate. Now, this certificate can be signed by a root Certificate Authority (CA), an Intermediate Cerfificate Authority (validated by a root CA) or a self signed certificate. To get a root or intermediate CA Certificate you must contact a company to give you one and pay for it. You could also create your own root or intermediate CA but this outside the scope of this article.
How to create a Self-Signed Certificate
Disclaimer: I am not an expert in OpenSSL, these are my tests and I might have made wrong assumptions. Please read the OpenSSL docs.
This is done on an Ubuntu 16 but you could do this in another system, you do need OpenSSl. The process is actually very simple.
Here are three ways of creating a Self-Signed Certificate:
# Way 1 - One line
# ********************
# This command outputs two files, the private key and the certificate. The certificate will be valid for 1 year (use '-days [number]' to change this).
#
#
# -nodes = not encrypted, if you leave this out, Apache will ask for a password when using the private key
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt
# Way 2 - Two steps
# ********************
# First the key is generated and second the certificate is generated using the generated key.
#
# Step 1: Generate the Private Key
# Step 1 - Option 1) -des3 encrypts the key, Apache will ask for a password when using the private key
openssl genrsa -des3 -out selfsigned.key 2048
# Step 1 - Option 2) No key encryption
openssl genrsa -out selfsigned.key 2048
#
# Step 2
# The certificate will be valid for 1 year (use '-days [number]' to change this).
openssl req -x509 -new -key selfsigned.key -out selfsigned.crt
# Way 3 - Three steps
# ********************
# First the key is generated, then a signing request is generated and finally the certificate is generated using the generated key and the signing request.
#
# Step 1: Generate the Private Key
# Step 1 - Option 1) -des3 encrypts the key, Apache will ask for a password when using the private key
openssl genrsa -des3 -out selfsigned.key 2048
# Step 1 - Option 2) No key encryption
openssl genrsa -out selfsigned.key 2048
#
# Step 2: Generate the Signing Request (.csr = Certificate Signing Request)
openssl req -new -key selfsigned.key -out selfsigned.csr
#
# Step 3: Generate the certificate using the Private Key and the Signing Request
# The certificate will be valid for 1 year (use '-days [number]' to change this).
openssl x509 -req -in selfsigned.csr -signkey selfsigned.key -out selfsigned.crt
# Check the certificate (a.k.a. see what's inside)
# ********************
openssl x509 -text -noout -in selfsigned.crt
Sources:
- IBM Knowledge Center
- Creating Your Own SSL Certificate Authority (and Dumping Self Signed Certs) | The Data Center Overlords
More info on how to create a root Certificate and how to create a Certificate Authority
- Howto: Make Your Own Cert With OpenSSL | Didier Stevens
- Howto: Make Your Own Cert With OpenSSL - YouTube, this are the steps from the previous link put in a video
- OpenSSL Certificate Authority — Jamie Nguyen
Adding the certificate to Apache
- https://www.maketecheasier.com/apache-server-ssl-support/
- https://www.digicert.com/ssl-certificate-installation-apache.htm
Ensuring the right protocol:
- https://askubuntu.com/questions/643037/how-to-enable-tls-1-2-in-apache
- https://tecadmin.net/enable-tls-in-modssl-and-apache/
- https://serverfault.com/questions/314858/how-to-enable-tls-1-1-and-1-2-with-openssl-and-apache
Other links:
Configuring Git to use the self signed certificate
- https://stackoverflow.com/questions/11621768/how-can-i-make-git-accept-a-self-signed-certificate
- https://stackoverflow.com/questions/23807313/adding-self-signed-ssl-certificate-without-disabling-authority-signed-ones
More sites:
Client based authentication using certificates in Apache
Used links:
- http://wiki.cacert.org/ApacheServerClientCertificateAuthentication
- https://stackoverflow.com/a/24543642/1071459
- http://stuff-things.net/2015/09/28/configuring-apache-for-ssl-client-certificate-authentication/
Other links:
- http://pages.cs.wisc.edu/~zmiller/ca-howto/
- https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslcacertificatefile
(Possibly) Giving Git a Client Certificate
More (possibly useful) info
- https://www.creang.com/howtoforge/howto_set_up_git_over_https_with_apache_on_ubuntu/
- http://ubuntuwiki.net/index.php/Apache,_Digest_authentication