GitLab教程(19): 安全最佳实践

安全是GitLab运维的重要方面。本文将介绍GitLab的安全配置和最佳实践。

访问控制

# 禁用公开注册
# Admin Area > Settings > General > Sign-up restrictions
# 取消勾选 "Sign-up enabled"

# 或通过配置文件
# /etc/gitlab/gitlab.rb
gitlab_rails['gitlab_signup_enabled'] = false

# 限制允许注册的邮箱域名
gitlab_rails['domain_allowlist'] = ['company.com', 'partner.com']

# 禁止用户更改用户名
gitlab_rails['username_changing_enabled'] = false

# 要求邮箱确认
gitlab_rails['send_user_confirmation_email'] = true

# 配置最小密码长度
gitlab_rails['minimum_password_length'] = 12

# 应用配置
sudo gitlab-ctl reconfigure

双因素认证 (2FA)

# 强制所有用户启用2FA
# Admin Area > Settings > General > Sign-in restrictions
# 勾选 "Two-factor authentication"
# 设置宽限期: 3 days (给用户时间设置)

# 或通过配置文件
# /etc/gitlab/gitlab.rb
gitlab_rails['require_two_factor_authentication'] = true
gitlab_rails['two_factor_grace_period'] = 72  # 小时

# 对特定组强制2FA
# Group > Settings > General > Permissions and group features
# 勾选 "Require all users in this group to set up two-factor authentication"

# 用户设置2FA
# User Settings > Account > Two-Factor Authentication
# 1. 使用TOTP应用扫描二维码 (Google Authenticator等)
# 2. 输入验证码确认
# 3. 保存恢复码

# 支持的2FA方式
# - TOTP (时间验证码)
# - WebAuthn (硬件密钥如YubiKey)
# - 恢复码

SSH密钥安全

# 推荐的SSH密钥类型
# Ed25519 (推荐) 或 RSA 4096位

# 生成Ed25519密钥
ssh-keygen -t ed25519 -C "your-email@company.com"

# 限制允许的SSH密钥类型
# Admin Area > Settings > General > Visibility and access controls
# Allowed SSH key types:
# [x] ED25519
# [x] RSA
# [ ] DSA (不推荐)
# [ ] ECDSA (可选)

# 配置SSH密钥过期
# 用户添加SSH密钥时可设置过期日期
# User Settings > SSH Keys > Expiration date

# 定期审计SSH密钥
# Admin Area > Credentials
# 查看所有用户的SSH密钥

# SSH密钥API
curl --header "PRIVATE-TOKEN: $TOKEN" \
  "https://gitlab.example.com/api/v4/users/5/keys"

令牌安全

# 设置令牌最大有效期
# Admin Area > Settings > General > Account and limit
# Maximum allowable lifetime for access tokens: 90 (天)

# 或通过配置文件
gitlab_rails['max_personal_access_token_lifetime'] = 90

# 令牌最佳实践
# 1. 始终设置过期时间
# 2. 使用最小权限范围
# 3. 为不同用途创建不同令牌
# 4. 定期轮换令牌
# 5. 不要在代码中硬编码令牌

# 审计令牌使用
# Admin Area > Credentials > Personal Access Tokens
# 查看所有用户的令牌

# 撤销可疑令牌
# 选择令牌 > Revoke

# 项目/组访问令牌
# 用于CI/CD,比个人令牌更安全
# Project > Settings > Access Tokens

分支保护

# 配置分支保护
# Project > Settings > Repository > Protected branches

# 保护main分支
Branch: main
Allowed to merge: Maintainers
Allowed to push: No one
Allowed to force push: No
Require approval from code owners: Yes

# 保护release分支
Branch: release/*
Allowed to merge: Maintainers
Allowed to push: Maintainers

# 推送规则 (Premium)
# Project > Settings > Repository > Push rules

# 禁止推送密钥
Prevent pushing secret files: Yes

# 要求签名提交
Require verified commits: Yes

# 限制提交作者邮箱
Commit author's email: @company\.com$

# 禁止推送敏感文件
File name not allowed: 
  *.pem, *.key, id_rsa, .env, credentials.json

审计日志

# 查看审计事件
# Admin Area > Monitoring > Audit Events

# 记录的事件类型
- 用户登录/登出
- 失败的登录尝试
- 项目/组创建、删除
- 成员添加、移除
- 权限变更
- 分支保护变更
- 仓库下载
- 2FA变更

# 审计日志示例
┌─────────────────────────────────────────────────────────────┐
│ Audit Events                                                │
├─────────────────────────────────────────────────────────────┤
│ 10 min ago  zhangsan  Added user lisi to group devops      │
│ 1 hour ago  admin     Changed project visibility to public │
│ 2 hours ago lisi      Failed login from 192.168.1.100     │
│ 3 hours ago zhangsan  Created project new-api              │
└─────────────────────────────────────────────────────────────┘

# 导出审计日志
# API方式
curl --header "PRIVATE-TOKEN: $TOKEN" \
  "https://gitlab.example.com/api/v4/audit_events?created_after=2026-01-01"

# 流式传输到外部系统
# /etc/gitlab/gitlab.rb
gitlab_rails['audit_events_streaming'] = [
  {
    'destination_url' => 'https://siem.example.com/gitlab-audit'
  }
]

网络安全

# HTTPS配置
# /etc/gitlab/gitlab.rb
external_url 'https://gitlab.example.com'
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['admin@example.com']

# 强制HTTPS
nginx['redirect_http_to_https'] = true

# HSTS
nginx['hsts_max_age'] = 31536000
nginx['hsts_include_subdomains'] = true

# 安全头
nginx['custom_gitlab_server_config'] = "
  add_header X-Content-Type-Options nosniff;
  add_header X-XSS-Protection \"1; mode=block\";
  add_header X-Frame-Options DENY;
  add_header Content-Security-Policy \"default-src 'self'\";
"

# IP白名单
# Admin Area > Settings > Network > Outbound requests
# 限制Webhook和集成可以访问的IP范围

# 限制Git操作的IP
# /etc/gitlab/gitlab.rb
gitlab_rails['rack_attack_git_basic_auth'] = {
  'enabled' => true,
  'ip_whitelist' => ['192.168.1.0/24'],
  'maxretry' => 10,
  'findtime' => 60,
  'bantime' => 3600
}

Runner安全

# Runner安全配置

# 使用Docker executor而非Shell
[[runners]]
  executor = "docker"
  [runners.docker]
    privileged = false  # 除非需要DinD
    cap_drop = ["ALL"]
    security_opt = ["no-new-privileges:true"]

# 限制Runner可运行的项目
# 注册时锁定到特定项目
--locked=true

# 使用保护标签
# Runner只运行保护分支的Job
# Project > Settings > CI/CD > Runners
# Protected: Yes

# 限制并发数
# /etc/gitlab-runner/config.toml
concurrent = 4

# 清理策略
[[runners]]
  [runners.docker]
    pull_policy = ["if-not-present"]
    disable_cache = false
    volumes = ["/cache"]
    cleanup = true

# 使用专用Runner处理敏感任务
deploy-prod:
  tags:
    - protected
    - production
  script:
    - ./deploy.sh

密钥管理

# CI/CD变量安全

# 设置变量为受保护
# Project > Settings > CI/CD > Variables
# Protected: Yes (只在保护分支可用)
# Masked: Yes (日志中隐藏)

# 组级别变量
# Group > Settings > CI/CD > Variables
# 子项目继承,减少重复配置

# 使用Vault集成
# .gitlab-ci.yml
job:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.example.com
  secrets:
    DATABASE_PASSWORD:
      vault: secret/data/production/db@password
      token: $VAULT_ID_TOKEN

# 文件类型变量
# 用于证书、配置文件等
# Type: File
# 在Job中作为文件路径使用
job:
  script:
    - cat $KUBECONFIG  # 自动创建临时文件

安全检查清单

# GitLab安全检查清单

## 访问控制
[ ] 禁用公开注册
[ ] 强制使用双因素认证
[ ] 设置密码最小长度(12+)
[ ] 限制允许的邮箱域名
[ ] 定期审查用户权限

## 认证
[ ] 使用SSO/LDAP认证
[ ] 设置访问令牌过期时间
[ ] 禁用不安全的SSH密钥类型
[ ] 定期轮换服务账户密码

## 网络
[ ] 启用HTTPS
[ ] 配置HSTS
[ ] 设置安全头
[ ] 限制出站请求
[ ] 配置防火墙

## 代码安全
[ ] 保护主分支
[ ] 要求代码审查
[ ] 启用安全扫描
[ ] 禁止推送密钥文件

## 运维
[ ] 启用审计日志
[ ] 定期备份
[ ] 保持GitLab更新
[ ] 监控异常活动

总结

本文介绍了GitLab的安全最佳实践,包括访问控制、认证、网络安全和审计。遵循这些实践可以显著提高GitLab的安全性。

下一篇(最后一篇)我们将总结GitLab最佳实践。

发表回复

后才能评论