Search code examples
gitlabcentos7httpd.confdirectadmin

How to setup Gitlab EE with HTTPS on a DirectAdmin Server?


I already have setup an Omnibus Gitlab server on my Centos7 VPS (DirectAdmin) using this post: how to install gitlab on a directadmin server

It worked great with HTTP requests. For security reasons I want to setup HTTPS on GitLab subdomain gitlab.domain.com. I want to use LetsEncrypt free SSL certificates. The problem is LetsEncrypt can't authenticate my domain using Certbot: certbot certonly --webroot --webroot-path=/var/www/letsencrypt -d gitlab.domain.com

It fails with output:

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: gitlab.domain.com
   Type:   unauthorized
   Detail: Invalid response from
   http://gitlab.domain.com/.well-known/acme-challenge/8Xj5vc-KMfhHYgH7PhXCFEetcxzQBDk-puiA2tRfoB4:
   "<!DOCTYPE html>\n<html class=\"devise-layout-html\">\n<head
   prefix=\"og: http://ogp.me/ns#\">\n<meta charset=\"utf-8\">\n<meta
   content=\"IE"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.

I googled for it and it seems LetsEncrypt have to reach a folder path:

http://gitlab.domain.com/.well-known/acme-challenge/xxxxxxxxxx

So I created the path and gave 777 permission and for test purposes put a test.html in it. Now I have access to file using HTTP but I can’t get to it using HTTPS.

curl -I -k https://gitlab.domain.com/.well-known/acme-challenge/test.html

Output:

HTTP/1.1 301 Moved Permanently
Date: Wed, 06 Feb 2019 10:05:40 GMT
Server: Apache/2
Location: http://gitlab.domain.com/.well-known/acme-challenge/test.html
Content-Type: text/html; charset=iso-8859-1

I already have DirectAdmin on server and I can't figure out how to customize HTTPD.conf file of my subdomain so that everything works fine.

Custom HTTPD.conf section of direct admin:

ServerName gitlab.domain.com
ServerSignature Off

ProxyPreserveHost On

# Ensure that encoded slashes are not decoded but left in their encoded state.
# http://doc.gitlab.com/ce/api/projects.html#get-single-project
AllowEncodedSlashes NoDecode

<Location />
  Order deny,allow
  Allow from all

  #Allow forwarding to gitlab-workhorse
  ProxyPassReverse http://127.0.0.1:8181
  ProxyPassReverse http://gitlab.domain.com/
</Location>

# Apache equivalent of nginx try files
# http://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
# http://stackoverflow.com/questions/10954516/apache2-proxypass-for-rails-app-gitlab
RewriteEngine on

# Forward all requests to gitlab-workhorse except existing files like error documents
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} ^/uploads/.* [NC,OR]
RewriteCond %{REQUEST_URI} !^.*/\.well-known/acme-challenge/.*$ [NC]
RewriteRule .* http://127.0.0.1:8181%{REQUEST_URI} [P,QSA,NE]

Alias /.well-known/acme-challenge/ /var/www/letsencrypt/
<Directory "/var/www/letsencrypt/">
     Order allow,deny
     Options Indexes FollowSymLinks MultiViews
     AllowOverride None
     Allow from all
</Directory>

# needed for downloading attachments
DocumentRoot /opt/gitlab/embedded/service/gitlab-rails/public

It worth to mention that testing my domain using https://letsdebug.net/ with HTTP-01 and DNS-01 methods return that everything is OK.

I think if I could handle HTTPS requests to guarantee access of LetsEncrypt API to http://gitlab.domain.com/.well-known/acme-challenge/ URL over HTTP and HTTPS it will be ok.


Solution

  • As far as nobody respond to my question I worked on it and finally I found the answer.

    Actually the problem was originated from two parts:

    1.When you want to point to a path which contains special characters like '.', '\' or space in a string with a "..." you have to use it in '\.' format. I insist that it is applicable just in case you have a string surrounded by the double quotation marks not every parameters you have in your config file.

    <Directory "/var/www/default/\.well-known/acme-challenge/">
    

    So the correct form of Alias/Directory part is as below:

    Alias /.well-known/acme-challenge/ /var/www/default/.well-known/acme-challenge/
    <Directory "/var/www/default/\.well-known/acme-challenge/">
        Options None
        AllowOverride None
        ForceType text/plain
        RedirectMatch 404 "^(?!/\.well-known/acme-challenge/[\w-]{43}$)"
    </Directory>
    

    You may get a "HTTP/1.1 302 Found" not a "HTTP/1.1 200 OK" when you call the URL of the test file by 'curl'. It returns 302 cause you somehow redirects request to somewhere else than you really see in the address bar. But it is OK for LetsEncrypt domain authorization.

    curl -I http://example.com/.well-known/acme-challenge/test.html
    

    2.When you call for certbot or letsencrypt command, in the webroot parameter it must point to the root of your ACME challenge directory (/var/www/default/) not the end destination of the certs (/var/www/default/.well-known/acme-challenge/) cause the acmetool itself makes directory path in every webroot you provided to it. So the correct form of certbot or letsencrypt command for above Alias/Directory should be like below:

    letsencrypt certonly --webroot -w /var/www/default/ -d example.com -d www.example.com --renew-by-default
    

    or

    certbot certonly --webroot --webroot-path=/var/www/default/ -d example.com
    

    I'm very new to the Apache configuration but as far as I searched for the problem it is a very popular problem to those who want to use LetsEncrypt over an Apache server. So forgive me if it an elementary question to most of you guys.

    Enjoy!