跳到主要内容

GitLab 安全加固

GitLab 承载源代码与 CI 密钥,是攻击者的高价值目标。以下加固项按 网络 → 认证 → 权限 → 审计 顺序实施,生产环境应全部覆盖。

1. HTTPS安全

1.1 强制 HTTPS

编辑 /etc/gitlab/gitlab.rb

external_url 'https://gitlab.example.com'
nginx['redirect_http_to_https'] = true
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.example.com.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.example.com.key"
nginx['ssl_protocols'] = "TLSv1.2 TLSv1.3"
nginx['ssl_ciphers'] = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"
nginx['ssl_prefer_server_ciphers'] = "on"
nginx['hsts_max_age'] = 31536000
nginx['hsts_include_subdomains'] = false

Let's Encrypt 自动证书:

letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['ops@example.com']
sudo gitlab-ctl reconfigure
curl -vI https://gitlab.example.com 2>&1 | grep -E 'HTTP/|Strict-Transport'

1.2 安全响应头

nginx['custom_gitlab_server_config'] = "
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;
"

2. SSH安全

GitLab SSH 默认端口 22,可通过 gitlab-sshd 或系统 sshd 提供服务。

2.1 修改 SSH 端口(可选)

gitlab_rails['gitlab_shell_ssh_port'] = 2222

防火墙同步放行:

sudo ufw allow 2222/tcp

用户 clone 地址变为 ssh://git@gitlab.example.com:2222/group/project.git

2.2 SSH 密钥策略

Admin Area → Settings → General → Visibility and access controls

  • 禁止上传弱密钥(RSA < 2048)
  • 启用 Two-factor authentication 强制策略(见下文)
  • 定期审计 SSH Key:Admin → Users → 导出用户列表

禁用 DSA 密钥、限制 ed25519/RSA 4096:

gitlab_rails['gitlab_shell_git_timeout'] = 800

3. 用户权限控制

3.1 注册与可见性

Admin → Settings → General

配置项生产建议
Sign-up enabled关闭,仅 LDAP/OAuth 或 Admin 创建
Default project visibilityPrivate
Default group visibilityPrivate
Restrict group creation仅 Admin 或 Trusted 用户

3.2 最小权限原则

  • 项目级:Developer 仅给需要 push 的成员;Maintainer 控制在 2 人以内
  • 组级:Owner 仅限平台管理员
  • 使用 Group Access Token 替代共享个人账号

批量审计过期成员:

sudo gitlab-rails runner "
User.active.find_each do |u|
last = u.last_activity_on
puts \"#{u.username}\t#{last}\" if last && last < 90.days.ago.to_date
end
"

3.3 双因素认证

Admin → Settings → General → Sign-in restrictions → 勾选 Enforce two-factor authentication,Grace period 设为 7 天。

4. Token安全管理

GitLab 有多种 Token,泄露风险从高到低需分级管理。

Token 类型权限范围管理建议
Personal Access Token用户全部可访问资源设过期时间、最小 scope
Project/Group Access Token项目/组范围优先用于 CI 与自动化
Deploy Token只读/读写 registry仅 registry pull
CI/CD VariablesPipeline 内可见Mask + Protected + File type
Runner Registration Token注册 Runner改用 authentication token

4.1 强制 Token 过期

Admin → Settings → General → Account and limit → 设置 Access token expiration 上限(如 90 天)。

4.2 CI 变量安全

项目 → Settings → CI/CD → Variables

  • 敏感值勾选 Mask variable
  • 生产变量勾选 Protect variable(仅 protected 分支可用)
  • 大密钥使用 File 类型,避免出现在 job log

撤销泄露 Token:

# Admin 撤销指定用户所有 PAT
sudo gitlab-rails runner "
user = User.find_by(username: 'leaked_user')
user.personal_access_tokens.active.each(&:revoke!)
"

5. Runner安全

Runner 能执行任意 CI 脚本,等同于在目标环境获得 shell 权限。

5.1 隔离策略

Executor隔离级别适用场景
Docker中(共享 Docker daemon 有风险)通用 CI
Kubernetes高(Pod 级隔离)生产推荐
Shell仅限专用裸机

5.2 Runner 加固

# /etc/gitlab-runner/config.toml
[[runners]]
[runners.docker]
privileged = false
disable_cache = false
volumes = ["/cache"]
allowed_images = ["registry.example.com/**"]
[runners.cache]
Type = "s3"
  • 关闭 privileged = true,除非确实需要 DinD
  • 使用 Runner authentication token(GitLab 16+),废弃 registration token
  • Protected Runner 仅服务 protected 分支/tag
  • 不同安全域使用不同 Runner(如 prod-runner / dev-runner)

清理离线 Runner:

sudo gitlab-rails runner "
Ci::Runner.unscoped.where(contacted_at: ..30.days.ago).each(&:destroy!)
"

6. 审计日志

6.1 应用级审计事件

EE 提供完整 Audit Events;CE 可通过以下方式补充:

  • Admin → Monitoring → Audit log(EE)
  • 应用日志:/var/log/gitlab/gitlab-rails/production.log
  • Nginx 访问日志:/var/log/gitlab/nginx/gitlab_access.log

导出最近登录失败:

sudo grep 'Failed Login' /var/log/gitlab/gitlab-rails/production.log | tail -50

6.2 系统审计

# 配置变更追踪(/etc/gitlab/gitlab.rb 纳入 Git 管理)
sudo git log --oneline /etc/gitlab/gitlab.rb

# 谁修改了 gitlab.rb
sudo ausearch -f /etc/gitlab/gitlab.rb 2>/dev/null | tail -20

启用 auditd 监控关键路径:

sudo auditctl -w /etc/gitlab/gitlab.rb -p wa -k gitlab_config
sudo auditctl -w /var/opt/gitlab/backups -p wa -k gitlab_backup

7. 安全最佳实践

  1. 网络隔离:GitLab 置于内网或 Zero Trust 之后,Admin 面板不对公网开放
  2. 及时升级:关注 GitLab Security Releases,Critical 漏洞 48 小时内评估升级
  3. Container Registry 扫描:启用依赖扫描(SAST/Dependency Scanning)或接入 Trivy
  4. 禁用不必要服务
grafana['enable'] = false # 若使用外部 Grafana
prometheus['enable'] = true # 保留监控但限制访问 IP
gitlab_rails['impersonation_enabled'] = false # 禁止 Admin 模拟用户(按需)
  1. 定期安全巡检清单
    • 无过期/未使用的 PAT 和 Deploy Token
    • 所有 Admin 已启用 2FA
    • Runner 无 privileged 滥用
    • CI Variables 无明文密钥出现在公开项目
    • TLS 证书有效期 > 30 天
    • gitlab-rake gitlab:check 无安全相关 WARN
sudo gitlab-rake gitlab:check SANITIZE=true
sudo gitlab-ctl deploy-page status # 确认维护页可用,便于紧急下线