November 2024
M T W T F S S
 123
45678910
11121314151617
18192021222324
252627282930  

Categories

November 2024
M T W T F S S
 123
45678910
11121314151617
18192021222324
252627282930  

Configuring SSL and Gitlab through an Apache Reverse Proxy

Configuring SSL and Gitlab through an Apache Reverse Proxy

I’ve recently started to use Gitlab as an alternative to a Github paid account for projects I don’t wish to make public. I wanted to install Gitlab on a server which is used for a few other applications which all use Apache, while Gitlab is really easy to install it installs nginx by default and expects to run on port 80. Normally in this situation I would configure Nginx to point to a non standard port, proxy through apache on the same server and terminate the SSL at apache, however there are some quirks in Gitlab which make this difficult; in this post I’ll describe how to proxy Gitlab through apache using SSL.

The Problem

While Gitlab can be manually installed to work with apache this makes upgrades / changes difficult, it comes with a very nice Chef based installer but it assumes it’s the only thing installed, if a simple HTTPS proxy is configured (terminating the SLL at Apache) then Gitlab will still mix in some non SSL URLs as it thinks it’s still using an unencrypted connection, while not a huge risk this is untidy and annoyed me.

The Solution

The solution is to configure Gitlab to use SSL too and enable an SSL proxy in Apache, this involves defining options in two files:

gitlab.rb

external_url 'https://<url>:4443'
nginx['ssl_certificate'] = "/etc/ssl/localcerts/<certname>.crt"
nginx['ssl_certificate_key'] = "/etc/ssl/localcerts/<keyname>.key"

After which don’t forget to run

 sudo gitlab-ctl reconfigure 

to push the changes into the nginx config

Apache vhost

<VirtualHost <ip>:443>

        ServerName <server url>
        SSLEngine on
        SSLCertificateFile /etc/ssl/localcerts/<certname>.crt
        SSLCertificateKeyFile /etc/ssl/localcerts/<keyname>.key
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    SSLProxyEngine on
    ProxyRequests Off
    ProxyPass / https://<url>:4443/
    ProxyPassReverse / https://<url>/

    Header edit Location ^http://<url>/ https://<url>/
    RequestHeader set X-Forwarded-Proto "https"


Proxying from Apache HTTPS to some backend server that only speaks HTTP

Here’s a use case: You want to run an application server that only speaks HTTP, but securely, over HTTPS. The problem is that the application server won’t know that it’s being accessed via HTTPS, so any URLs and redirects it generates might point to HTTP. Here’s an example virtual host entry that takes care of that by rewriting the header.

You need Apache, mod_proxy and mod_headers.

<VirtualHost *:443>
  ServerName foo.bar.example.com

  SSLEngine on
  SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
  SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
  Header edit Location "^http:(.*)$" "https:$1"

  PassengerEnabled off
  ProxyPass / http://127.0.0.1:3000/
  ProxyPassReverse / http://127.0.0.1:3000/

  DocumentRoot /var/www/foo/bar
  <Directory /var/www/foo/bar>
    AllowOverride none
    Options -MultiViews
  </Directory>
</VirtualHost>

The magical line is the one with “Header edit…”. This makes sure any request your app server would have sent to HTTP are rewritten to HTTPS.

302 Redirects behind SSL-terminating proxies
Problem

You have a web site all with SSL. There is a reverse proxy or load balancer that acts as SSL termination point. Behind that reverse proxy you have an Apache web server running plain http.

Your application uses 302 redirects to announce new URLs or whatever the reason is for doing so. Since the web server does not know that https URLs should be announced, the response header is wrong and looks like following:

Location http://www.example.com/your-fancy-url

The browser interprets that location header and send a request to this non-SSL URL instead of https:///www.example.com/your-fancy-url

If your reverse proxy does not know how to handle this, a connection will time-out. How to circumvent this if you have access to the web server but not to the reverse proxy or load balancer? What to do if your load balancer (such as Blue Coat devices) are closed down appliances that are not able to rewrite response headers?

Search engines do obviously not know the answer or I simply did not asked the right question.

Solution

Since Apache version 2.2.4 mod_headers is able to rewrite response headers. Just add the following to your httpd.conf

Header edit Location ^http://(.*)$ https://$1
This configuration statement will solve your problem. Redirects triggered by your back end web servers will be re-rewritten to comply with your SSL terminating reverse proxy/load balancer.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>