为什么 Gitlab 配置项 allowed_hosts
不能使用通配符 ["*"]
1. 问题发现与背景
用户上传头像报错 Request failed with status code 403
2. 排查
2.1. 对比正常使用的GitLab实例配置
2.2. 确定是 allowed_hosts
参数问题
在配置文件里进行注释掉后,重启服务。上传头像恢复正常。
3. 找寻原因
3.1. 是否是nginx配置
发现并没有对 host
相关参数的要求。
/var/opt/gitlab/nginx/
root@gitlab:/var/opt/gitlab/nginx# ll
total 48
drwxr-x--- 10 root gitlab-www 4096 Apr 15 19:04 ./
drwxr-xr-x 16 root root 4096 Apr 15 19:03 ../
drwx------ 2 gitlab-www root 4096 Apr 18 15:20 client_body_temp/
drwxr-x--- 2 root gitlab-www 4096 Apr 15 19:04 conf/
drwx------ 2 gitlab-www root 4096 Jan 6 19:18 fastcgi_temp/
lrwxrwxrwx 1 root root 21 Jan 6 19:17 logs -> /var/log/gitlab/nginx/
-rw-r--r-- 1 root root 8 Apr 7 10:01 nginx.pid
drwx------ 2 gitlab-www root 4096 Jan 6 19:18 proxy_cache/
drwx------ 12 gitlab-www root 4096 Feb 21 09:57 proxy_temp/
drwx------ 2 gitlab-www root 4096 Jan 6 19:18 scgi_temp/
drwx------ 2 gitlab-www root 4096 Jan 6 19:18 uwsgi_temp/
-rw-r--r-- 1 root root 28 Mar 16 11:38 VERSION
drwxr-xr-x 3 root root 4096 Jan 6 19:18 www/
conf/nginx.conf
# This file is managed by gitlab-ctl. Manual changes will be
# erased! To change the contents below, edit /etc/gitlab/gitlab.rb
# and run `sudo gitlab-ctl reconfigure`.
user gitlab-www gitlab-www;
worker_processes 4;
error_log stderr;
pid nginx.pid;
daemon off;
events {
worker_connections 10240;
}
http {
log_format gitlab_access '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent" $gzip_ratio';
log_format gitlab_mattermost_access '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent" $gzip_ratio';
hide_server_tokens off;
server_names_hash_bucket_size 64;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_time 1h;
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_proxied no-cache no-store private expired auth;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json;
include /opt/gitlab/embedded/conf/mime.types;
proxy_cache_path proxy_cache keys_zone=gitlab:10m max_size=1g levels=1:2;
proxy_cache gitlab;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Remove private_token from the request URI
# In: /foo?private_token=unfiltered&authenticity_token=unfiltered&rss_token=unfiltered&...
# Out: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
map $request_uri $temp_request_uri_1 {
default $request_uri;
~(?i)^(?<start>.*)(?<temp>[\?&]private[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
}
# Remove authenticity_token from the request URI
# In: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
map $temp_request_uri_1 $temp_request_uri_2 {
default $temp_request_uri_1;
~(?i)^(?<start>.*)(?<temp>[\?&]authenticity[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
}
# Remove rss_token from the request URI
# In: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=[FILTERED]&...
map $temp_request_uri_2 $filtered_request_uri {
default $temp_request_uri_2;
~(?i)^(?<start>.*)(?<temp>[\?&]rss[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
}
# A version of the referer without the query string
map $http_referer $filtered_http_referer {
default $http_referer;
~^(?<temp>.*)\? $temp;
}
# Enable vts status module.
vhost_traffic_status_zone;
upstream gitlab-workhorse {
server unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket;
}
include /var/opt/gitlab/nginx/conf/gitlab-http.conf;
include /var/opt/gitlab/nginx/conf/nginx-status.conf;
}
conf/gitlab-http.conf
# This file is managed by gitlab-ctl. Manual changes will be
# erased! To change the contents below, edit /etc/gitlab/gitlab.rb
# and run `sudo gitlab-ctl reconfigure`.
## GitLab
## Modified from https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/support/nginx/gitlab-ssl & https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/support/nginx/gitlab
##
## Lines starting with two hashes (##) are comments with information.
## Lines starting with one hash (#) are configuration parameters that can be uncommented.
##
##################################
## CHUNKED TRANSFER ##
##################################
##
## It is a known issue that Git-over-HTTP requires chunked transfer encoding [0]
## which is not supported by Nginx < 1.3.9 [1]. As a result, pushing a large object
## with Git (i.e. a single large file) can lead to a 411 error. In theory you can get
## around this by tweaking this configuration file and either:
## - installing an old version of Nginx with the chunkin module [2] compiled in, or
## - using a newer version of Nginx.
##
## At the time of writing we do not know if either of these theoretical solutions works.
## As a workaround users can use Git over SSH to push large files.
##
## [0] https://git.kernel.org/cgit/git/git.git/tree/Documentation/technical/http-protocol.txt#n99
## [1] https://github.com/agentzh/chunkin-nginx-module#status
## [2] https://github.com/agentzh/chunkin-nginx-module
##
###################################
## configuration ##
###################################
server { ## HTTPS server
listen *:443 ssl http2;
server_name gitlab-lovelink.qiu-ai.com;
server_tokens off; ## Don't show the nginx version number, a security best practice
## Increase this if you want to upload large attachments
## Or if you want to accept large git objects over http
client_max_body_size 25000m;
## Strong SSL Security
## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
ssl_certificate /etc/gitlab/ssl/gitlab-lovelink.qiu-ai.com.crt;
ssl_certificate_key /etc/gitlab/ssl/gitlab-lovelink.qiu-ai.com.key;
# GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_session_timeout 1d;
## Real IP Module Config
## http://nginx.org/en/docs/http/ngx_http_realip_module.html
## HSTS Config
## https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
add_header Strict-Transport-Security "max-age=63072000" always;
# Rails sets a default policy of strict-origin-when-cross-origin, so
# hide that and just send the one we've configured for nginx
proxy_hide_header Referrer-Policy;
add_header Referrer-Policy strict-origin-when-cross-origin;
## Individual nginx logs for this GitLab vhost
access_log /var/log/gitlab/nginx/gitlab_access.log gitlab_access;
error_log /var/log/gitlab/nginx/gitlab_error.log error;
if ($http_host = "") {
set $http_host_with_default "gitlab-lovelink.qiu-ai.com";
}
if ($http_host != "") {
set $http_host_with_default $http_host;
}
gzip on;
gzip_static on;
gzip_comp_level 2;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "msie6";
gzip_min_length 250;
gzip_proxied no-cache no-store private expired auth;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json;
## https://github.com/gitlabhq/gitlabhq/issues/694
## Some requests take more than 30 seconds.
proxy_read_timeout 3600;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host_with_default;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Proto https;
location ~ (/api/v\d/jobs/\d+/artifacts$|/import/gitlab_project$|\.git/git-receive-pack$|\.git/ssh-receive-pack$|\.git/ssh-upload-pack$|\.git/gitlab-lfs/objects|\.git/info/lfs/objects/batch$) {
proxy_cache off;
proxy_pass http://gitlab-workhorse;
proxy_request_buffering off;
}
location ~ ^/api/v\d {
proxy_cache off;
proxy_pass http://gitlab-workhorse;
proxy_intercept_errors off;
}
location = /-/kubernetes-agent/ {
proxy_pass http://localhost:8150/;
proxy_intercept_errors off;
}
location /-/kubernetes-agent/k8s-proxy/ {
proxy_pass http://localhost:8154/;
proxy_buffering off;
proxy_intercept_errors off;
}
# health checks configuration
include /var/opt/gitlab/nginx/conf/gitlab-health.conf;
location / {
proxy_cache off;
proxy_pass http://gitlab-workhorse;
}
location /assets {
add_header X-Content-Type-Options nosniff;
proxy_cache gitlab;
proxy_pass http://gitlab-workhorse;
}
error_page 404 /404.html;
error_page 500 /500.html;
error_page 502 /502.html;
location ~ ^/(404|500|502)(-custom)?\.html$ {
root /opt/gitlab/embedded/service/gitlab-rails/public;
internal;
}
} ## end HTTPS server
3.2. 源代码
3.2.1. 源代码仓库搜索
config/initializers/1_settings.rb | |
---|---|
config/initializers/rails_host_authorization.rb | |
---|---|
3.2.2. 发现与 Ruby on Rails
框架配置有关
🎯 找到返回 403
的原因:当请求发送到未经授权的主机时,默认的 Rack 应用程序将运行并响应 403 Forbidden (不支持使用 *
)。
更多详情请参考:3.5.1. ActionDispatch::HostAuthorization
4. 总结
- 后端 Ruby on Rails 框架延续使用了
gitlab_rails['allowed_hosts']
配置的值 - Ruby on Rails 框架不支持使用
["*"]