Real Needs#
Bypassing record detection to make self-hosted Gitlab URL without a port number.
Problem#
Accessing a URL with a port number that is reverse proxied by Nginx will be redirected to a URL without a port number.
Cause#
Nginx redirects users to the external_url based on the configuration in gitlab.rb. Changing this configuration to include a port number will also cause issues (excessive redirects leading to errors in modern browsers).
Solution#
Use Argo Tunnel to take over the built-in Nginx and directly connect to Gitlab Workhorse.
Principle#
By analyzing the Gitlab-CE source code, we can understand how the built-in Nginx works.
https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/support/nginx/gitlab-ssl
# Ignoring the beginning
upstream gitlab-workhorse {
# GitLab socket file,
# for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket
server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;
}
# Ignoring the middle
server {
# Ignoring the middle
location / {
client_max_body_size 0;
gzip off;
## https://github.com/gitlabhq/gitlabhq/issues/694
## Some requests take more than 30 seconds.
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade_gitlab_ssl;
proxy_pass http://gitlab-workhorse;
}
}
# Ignoring the end
It can be seen that the traffic is almost directly handed over to Gitlab Workhorse, and Nginx is only responsible for redirection and providing static resources, with a connection through a socket.
Argo Tunnel can map local services to the public network and also act as a gateway for traffic forwarding.
Therefore, using Argo Tunnel instead of Nginx is feasible.
Steps#
Step 1. Register a Cloudflare account, transfer the domain to Cloudflare, and then open Zero Trust -> Access -> Tunnels.
Step 2. Install cloudflared on the Gitlab host and configure the connection according to Cloudflare's instructions.
Step 3. Modify gitlab.rb
external_url 'https://git.targetdomain.com'
# Modify to the final displayed URL
gitlab_rails['trusted_proxies'] = ['0.0.0.0/0']
# Allow the target IP to establish a connection with Gitlab Workhorse
# Warning: Because the remote host IP of Argo Tunnel is not fixed, and I haven't tested all IP ranges (too many), so here I allow all hosts to establish a connection.
# For security reasons, you need to configure the local firewall to block external connections (close the corresponding port, that is, the port listened to by Gitlab Workhorse), which will not affect the connection establishment of Argo Tunnel (naturally established locally).
gitlab_workhorse['listen_network'] = "tcp"
gitlab_workhorse['listen_addr'] = "0.0.0.0:10080"
# Let Workhorse listen on 10080
# Following the previous text, you need to block all external hosts from connecting to port 10080
# You can also use Unix Socket
# gitlab_workhorse['listen_network'] = "unix"
# gitlab_workhorse['listen_addr'] = "...omitted/socket"
# Using Socket does not require configuring the firewall
nginx['enable'] = false
# Disable the built-in Nginx in Gitlab
Step 4. Configure the Tunnel
In the Tunnel management interface -> Public Hostname, create a new hostname.
Fill in the Subdomain and Domain as needed, which should match the configuration in gitlab.rb.
In the example configuration, the URL is https://git.targetdomain.com, so set the Subdomain to "git" and the Domain (which needs to be connected to Cloudflare) to "targetdomain.com". Leave the Path empty.
Choose TCP as the Service Type and enter "localhost:10080" in the URL, which should match the configuration in gitlab.rb. In the example configuration, it is port 10080.
Notice: If you are using Unix Socket, the Service Type should be UNIX, and the URL should be filled with the absolute path.
Step 5. Now access your Gitlab, it should be working properly and all URLs and redirects should be correct.