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.
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!