Skip to content

Instantly share code, notes, and snippets.

@Erutan409
Last active August 2, 2024 19:12
Show Gist options
  • Save Erutan409/86d3ddd7f26d4d9cacb8011e4bd14b96 to your computer and use it in GitHub Desktop.
Save Erutan409/86d3ddd7f26d4d9cacb8011e4bd14b96 to your computer and use it in GitHub Desktop.
Gitlab Nginx Reverse Proxy Configuration (with Let's Encrypt SSL)
# These are fragments of the configuration that will need to be updated
# ---
## GitLab URL
##! URL on which GitLab will be reachable.
##! For more details on configuring external_url see:
##! https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab
external_url 'https://gitlab.your-fqdn.com'
#external_url 'http://gitlab.internal.lan'
# ---
### Trusted proxies
###! Customize if you have GitLab behind a reverse proxy which is running on a
###! different machine.
###! **Add the IP address for your reverse proxy to the list, otherwise users
###! will appear signed in from that address.**
gitlab_rails['trusted_proxies'] = ['10.100.0.0/15']
# ---
################################################################################
## GitLab NGINX
##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html
################################################################################
# nginx['enable'] = true
# nginx['client_max_body_size'] = '250m'
# nginx['redirect_http_to_https'] = false
# nginx['redirect_http_to_https_port'] = 80
##! Most root CA's are included by default
# nginx['ssl_client_certificate'] = "/etc/gitlab/ssl/ca.crt"
##! enable/disable 2-way SSL client authentication
# nginx['ssl_verify_client'] = "off"
##! if ssl_verify_client on, verification depth in the client certificates chain
# nginx['ssl_verify_depth'] = "1"
# nginx['ssl_certificate'] = "/etc/gitlab/ssl/#{node['fqdn']}.crt"
# nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/#{node['fqdn']}.key"
# nginx['ssl_ciphers'] = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
# nginx['ssl_prefer_server_ciphers'] = "on"
##! **Recommended by: https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
##! https://cipherli.st/**
# nginx['ssl_protocols'] = "TLSv1.1 TLSv1.2"
##! **Recommended in: https://nginx.org/en/docs/http/ngx_http_ssl_module.html**
# nginx['ssl_session_cache'] = "builtin:1000 shared:SSL:10m"
##! **Default according to https://nginx.org/en/docs/http/ngx_http_ssl_module.html**
# nginx['ssl_session_timeout'] = "5m"
# nginx['ssl_dhparam'] = nil # Path to dhparams.pem, eg. /etc/gitlab/ssl/dhparams.pem
# nginx['listen_addresses'] = ['*', '[::]']
##! **Defaults to forcing web browsers to always communicate using only HTTPS**
##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#setting-http-strict-transport-security
# nginx['hsts_max_age'] = 31536000
# nginx['hsts_include_subdomains'] = false
##! **Docs: http://nginx.org/en/docs/http/ngx_http_gzip_module.html**
# nginx['gzip_enabled'] = true
##! **Override only if you use a reverse proxy**
##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-port
nginx['listen_port'] = 80
##! **Override only if your reverse proxy internally communicates over HTTP**
##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl
nginx['listen_https'] = false
# nginx['custom_gitlab_server_config'] = "location ^~ /foo-namespace/bar-project/raw/ {\n deny all;\n}\n"
# nginx['custom_nginx_config'] = "include /etc/nginx/conf.d/example.conf;"
# nginx['proxy_read_timeout'] = 3600
# nginx['proxy_connect_timeout'] = 300
nginx['proxy_set_headers'] = {
"Host" => "$http_host_with_default",
#"X-Real-IP" => "$remote_addr",
"X-Forwarded-For" => "$proxy_add_x_forwarded_for",
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on",
#"Upgrade" => "$http_upgrade",
#"Connection" => "$connection_upgrade"
}
# nginx['proxy_cache_path'] = 'proxy_cache keys_zone=gitlab:10m max_size=1g levels=1:2'
# nginx['proxy_cache'] = 'gitlab'
# nginx['http2_enabled'] = true
nginx['real_ip_trusted_addresses'] = ['10.100.0.0/15']
nginx['real_ip_header'] = 'X-Real-IP'
nginx['real_ip_recursive'] = 'on'
# nginx['custom_error_pages'] = {
# '404' => {
# 'title' => 'Example title',
# 'header' => 'Example header',
# 'message' => 'Example message'
# }
# }
### Advanced settings
# nginx['dir'] = "/var/opt/gitlab/nginx"
# nginx['log_directory'] = "/var/log/gitlab/nginx"
# nginx['worker_processes'] = 4
# nginx['worker_connections'] = 10240
# nginx['log_format'] = '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'
# nginx['sendfile'] = 'on'
# nginx['tcp_nopush'] = 'on'
# nginx['tcp_nodelay'] = 'on'
# nginx['gzip'] = "on"
# nginx['gzip_http_version'] = "1.0"
# nginx['gzip_comp_level'] = "2"
# nginx['gzip_proxied'] = "any"
# nginx['gzip_types'] = [ "text/plain", "text/css", "application/x-javascript", "text/xml", "application/xml", "application/xml+rss", "text/javascript", "application/json" ]
# nginx['keepalive_timeout'] = 65
# nginx['cache_max_size'] = '5000m'
# nginx['server_names_hash_bucket_size'] = 64
### Nginx status
# nginx['status'] = {
# "enable" => true,
# "listen_addresses" => ["127.0.0.1"],
# "fqdn" => "dev.example.com",
# "port" => 9999,
# "options" => {
# "stub_status" => "on", # Turn on stats
# "server_tokens" => "off", # Don't show the version of NGINX
# "access_log" => "off", # Disable logs for stats
# "allow" => "127.0.0.1", # Only allow access from localhost
# "deny" => "all" # Deny access to anyone else
# }
# }
# See the following links for getting Gitlab up and running with this configuration:
# https://gitlab.com/gitlab-org/gitlab-ce/issues/32937 Gitlab should not require X-Forwarded-Ssl: on if behind the HTTPS enabled reverse proxy when X-Forwarded-Proto: https is set
# https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md#supporting-proxied-ssl
# https://docs.gitlab.com/omnibus/settings/nginx.html#change-the-default-proxy-headers
# https://gitlab.com/gitlab-org/gitlab-ce/issues/3538 Search for 'trusted_proxies' in the gitlab configuration file
server {
server_name gitlab.your-fqdn.com;
server_tokens off;
# In global config (not needed)
set $allowed 0;
if ($us_country = yes) {
set $allowed 1;
}
if ($local_redirect = yes) {
set $allowed 1;
}
if ($allowed = 0) {
return 444;
}
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;
# Internal host name/FQDN
proxy_pass http://gitlab.internal.lan;
proxy_set_header Host $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_buffering off;
proxy_http_version 1.1;
}
access_log /home/webmaster-data/www/gitlab/logs/access.log;
error_log /home/webmaster-data/www/gitlab/logs/error.log;
# Following configuration is maintained by Let's Encrypt/Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/gitlab.your-fqdn.com-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/gitlab.your-fqdn.com-0001/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = gitlab.your-fqdn.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name gitlab.your-fqdn.com;
listen 80;
return 404; # managed by Certbot
}
@cakiem8x
Copy link

Thanks for your prompt reply. I implemented the configuration you provided and I did obtain a valid letsencrypt certificate however, still could not get the Gitlab sign-in page to load. The url to the nginx reverse proxy server was secure (showing the locked symbol) but the page only returned a 503 Bad Gateway or 504 Timeout instead of loading the Gitlab site.

You can change: proxy_pass http://gitlab.internal.lan; to proxy_pass https://[IP LAN]:443/; it working for me :)

@Erutan409
Copy link
Author

Thanks for your prompt reply. I implemented the configuration you provided and I did obtain a valid letsencrypt certificate however, still could not get the Gitlab sign-in page to load. The url to the nginx reverse proxy server was secure (showing the locked symbol) but the page only returned a 503 Bad Gateway or 504 Timeout instead of loading the Gitlab site.

You can change: proxy_pass http://gitlab.internal.lan; to proxy_pass https://[IP LAN]:443/; it working for me :)

You could do that, but I'm not sure why you wouldn't configure your Gitlab instance to listen to traffic on port 80, internally. I'd suspect that opens up possibilities of troubleshooting woes if something changes with future updates.

I also can't speak to how that might affect the forwarding of headers when logging activity from clients, correctly.

@khurshid-alam
Copy link

@Erutan409

I use haproxy with similar setup. It works. But fot git clone works only over https (after adding access token ex: https://gitlab-ci-token:@gitlab.example.com/repo/project). But it does not work over ssh. There is a method to forward port 22 from haproxy to gitlab server (https://www.haproxy.com/blog/route-ssh-connections-with-haproxy/)

So can it be done that way ? (I also didn't check, email url, email reply, upload attachment from clipboard to wiki.)

@Erutan409
Copy link
Author

@khurshid-alam Yeah, I struggled with this, too. I ended up using a different port (766) for all SSH related connections to Gitlab. I have this port directly forward to that server, since you can't do similar reverse proxying with SSH. It doesn't support SNI like HTTP requests do; which is unfortunate. Anyway, this is what I did and it works.

I don't have a write-up on this as it's a little out-of-scope of what I meant for the gist to serve. Be careful and read up on how to properly set this up. It's mostly straight-forward, but just do your due diligence to make sure it's as secure as you can possibly make it. Don't expose the default SSH to the DMZ. You should be able to allow your server to respond to one SSH user on that alternate port, which is specifically used by Gitlab for using that protocol for Git.

@KazaiMazai
Copy link

Thanks for sharing, it helped me to solve my configuration issue.
Have you tested this configuration with gitlab pages?

@Erutan409
Copy link
Author

@KazaiMazai No, I haven't. I didn't even know that was a thing until you asked. I'd imagine it would work, without requiring much deviation; if at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment