GitLab EE Premium 18.4.1 企业版破解方法
风险提示:仅供个人技术学习使用,禁止非法商用侵权,尊重企业劳动成果,保障知识产权合法权益!
一、环境准备
CentOS 7 安装 Ruby
参照:https://blog.csdn.net/fredricen/article/details/142205493
(1)确定系统版本
cat /etc/os-release
(2)安装RVM
RVM是一个linux下的Ruby的多版本管理工具,可以维护多个Ruby版本,切换版本。对于开发Ruby应用程序比较友好。还有个优点就是不需要梯子,对于国内用户友好。
安装GPG的key,用于身份验证
gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
安装RVM最新稳定版本
\curl -sSL https://get.rvm.io | bash -s stable
(3)安装Ruby的前置依赖—更新 gcc
yum install centos-release-scl -y
执行成功后,系统会生成:
/etc/yum.repos.d/CentOS-SCLo-scl.repo
/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
更新gcc版本,默认为4.8.5版本,最好升级到7以上版本,此处升级到9,升级gcc版需要先更新yum源
vi /etc/yum.repos.d/CentOS-SCLo-scl.repo
修改此部分的baseurl为阿里云源
[centos-sclo-sclo]
name=CentOS-7 - SCLo sclo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
# mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=7&repo=sclo-sclo
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
还有
vi /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
修改此部分的baseurl为阿里云源
[centos-sclo-rh]
name=CentOS-7 - SCLo rh
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
# mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=7&repo=sclo-rh
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
最后刷新缓存
yum repolist
yum clean all
yum makecache
正式升级gcc版本
yum install devtoolset-9-gcc* -y
启用新版gcc
scl enable devtoolset-9 bash
使当前的终端立即生效:
source /opt/rh/devtoolset-9/enable
(4)安装指定版本的Ruby
CC=/opt/rh/devtoolset-9/root/usr/bin/gcc rvm install 3.2.4
查看RVM使用的当前Ruby版本
rvm list
二、正式破解
参照:https://blog.17lai.site/posts/29a820b3/
(1)确保已安装ruby
ruby版本需要2.3或以上。
(2)生成许可证
gem install gitlab-license
(3)创建一个rb文件
nano license.rb
require "openssl"
require "gitlab/license"
key_pair = OpenSSL::PKey::RSA.generate(2048)
File.open("license_key", "w") { |f| f.write(key_pair.to_pem) }
public_key = key_pair.public_key
File.open("license_key.pub", "w") { |f| f.write(public_key.to_pem) }
private_key = OpenSSL::PKey::RSA.new File.read("license_key")
Gitlab::License.encryption_key = private_key
license = Gitlab::License.new
license.licensee = {
"Name" => "none",
"Company" => "none",
"Email" => "example@test.com",
}
license.starts_at = Date.new(2020, 1, 1) # 开始时间
license.expires_at = Date.new(2050, 1, 1) # 结束时间
license.notify_admins_at = Date.new(2049, 12, 1)
license.notify_users_at = Date.new(2049, 12, 1)
license.block_changes_at = Date.new(2050, 1, 1)
license.restrictions = {
active_user_count: 10000,
}
puts "License:"
puts license
data = license.export
puts "Exported license:"
puts data
File.open("GitLabBV.gitlab-license", "w") { |f| f.write(data) }
public_key = OpenSSL::PKey::RSA.new File.read("license_key.pub")
Gitlab::License.encryption_key = public_key
data = File.read("GitLabBV.gitlab-license")
$license = Gitlab::License.import(data)
puts "Imported license:"
puts $license
unless $license
raise "The license is invalid."
end
if $license.restricted?(:active_user_count)
active_user_count = 10000
if active_user_count > $license.restrictions[:active_user_count]
raise "The active user count exceeds the allowed amount!"
end
end
if $license.notify_admins?
puts "The license is due to expire on #{$license.expires_at}."
end
if $license.notify_users?
puts "The license is due to expire on #{$license.expires_at}."
end
module Gitlab
class GitAccess
def check(cmd, changes = nil)
if $license.block_changes?
return build_status_object(false, "License expired")
end
end
end
end
puts "This instance of GitLab Enterprise Edition is licensed to:"
$license.licensee.each do |key, value|
puts "#{key}: #{value}"
end
if $license.expired?
puts "The license expired on #{$license.expires_at}"
elsif $license.will_expire?
puts "The license will expire on #{$license.expires_at}"
else
puts "The license will never expire."
end
赋予文件执行权限
chmod +x license.rb
执行文件
ruby license.rb
执行结果如下:
[root@localhost ~]# ruby license.rb
License:
#<Gitlab::License:0x00007f63b4f04758>
Exported license:
eyJkYXRhIjoia25rRFVkZEhDZmxlMDR6dWcxcEhYdzd2ckQzVnJHZDB2YVJD
ZzY2UWZ5cDAyVkpHTUdDMFUyMzFrL2VTXG5KQ0pNQXZYUkt1ZzQ5ZEx6UytM
R0d1ak9YTU1uK1RwTzFNM21kdkxkWTFnaEJWZHNzbHpWbUZvMU5CcHJcbkYy
K3dqZEoxbzI4NlRneFpKNnJnUWNQRnQyRzQ3ODI0MEtmdVZCbDQyWXEyc2t4
bVhhM2J1Q04vb1M0c1xuZU50ZnEwdFlKaDlKbXhERHFEMElYUU5aTWhXZ2kw
ZnNYVmhXbG1wODFZTWJKdHpueWxJcHlvMlhlK1hBXG5OU2M2TEFUUk56M0V6
U2t6dkJ0cjNBcS8rMjVoZ2hXVXlJNjRwOEZsVWUrN3pPMlVzd0RsMS9CQitH
SEdcblNZdjRCNmJpeCtob0ZSSzcvVGRWYVFRR3VINCtKOWc3dUtGdnBscUdU
WW41ZThOYWw3anluUzB0M3BqTFxuc1dNTWRKNW5CVW8rTklFVzc0NFVRME9x
cys0ZklLTmo2N0ltQ0xqVzgvcWVQUGdwWU84OEk2Y3kxZzM2XG5iNjMvODRU
dHVVdVNCbmM3R09iWTFKbFBTRnd2bC91MXRrZTU2VzlFUXBCdUVvN3FlaTNE
d0VzM0dEOFNcbm1IWGRWdHBTVW9XTXA0dnprMTF5dk5Nb0JKRlBuS0dyaFJU
bXlCbVBsUGFxdlo2UEQxUHVhZ2w3YUp6U1xuekdrOTJMMEZMb2NPb0RXQzVK
TjNZMmpYMmNmbmt6SWQwbVNMN2dQSlRNMnVORmM3THFKa3ZOTjFhSE1iXG4v
bVRzblBpRWhvMUNUZHptRWJwUmFmTUgvMGdKaTl4a0dJaHlCbklGUy9yNWJa
QmhMMTFQcDFUakdqRWFcbkxFUlNqbmdtSzNjWjNVNHZpQTVUem01Z3dFQlA0
RStnY2Z5U0dTTmlQMTRLUmZVS1h0YW9TNVM0WFQ0VlxueGRpaGw5OXliejNw
VkJUcEd0UEx0ZEhrZnhTdE85SXNHMWViNEh5Wm5BcFlMVEJ1NUFkUVlUYmZV
RGFPXG5MdjFBb2pha3VRPT1cbiIsImtleSI6ImZveHkySkFSbVBYejNaSmpE
VXViSTA0Skw5dUp2UmdXYnFBMnpqOWtiaDB5Wi9Ick5EMHowclg1akIveFxu
SDVldStpeVRMbU5NYml1YWNEM0RtM0lBcUJaVGgyTDE3NG8xT2tnWUFhekli
QmNCVzN0RjhpdXhYOUFVXG5DQ01Nc1QrNXZoblJrSmY1RW50blhKOExQY1Vx
RHBhcnRHVXVDb1JvRTEyUlRWaExrYnFJcHVuUFN0Qmdcbk9qNTcvSklhVEZ0
VWVWbENVb1BnNXJiaDFkVjBDK2dRcjlKWU9jZkZ2dXczS3BMUnZ3cFd3ZGNn
N0gzVFxuSjkyelIwMWJSYkN3TEQ4U2FaQUhYdG1YRUJTRDlLUDluby9tQVEy
Z09CYTI3UnZ3c0J3NHhjdHE4WW1oXG44akFzT2NOQzkwaDhPYnhxVC9NVy9u
dGJQcDBlNUp0MnljU1ZoOVdZZXc9PVxuIiwiaXYiOiJ5ZWhhaW1qcDdhTFdo
ZUhqdnB2SkVBPT1cbiJ9
Imported license:
#<Gitlab::License:0x00007f63b5022090>
This instance of GitLab Enterprise Edition is licensed to:
Name: none
Company: none
Email: example@test.com
The license will expire on 2050-01-01
生成 GitLabBV.gitlab-license license_key license_key.pub 这三个文件。
(4)使用许可证
docker-compose restart gitlab
用 license_key.pub 文件替换 /opt/gitlab/embedded/service/gitlab-rails/.license_encryption_key.pub(容器内部地址)
相当于自己生成公钥替换原有公钥,验证自己签的许可证。
注意:替换完之后,先重启容器,然后再输入许可证(私钥)验证,不然公钥还是没替换前的,验证肯定不成功。
GitLabBV.gitlab-license 即是许可证,填入 ${address}/admin/license 地址。
也就是上面执行代码后输出的私钥秘钥,在GitLab前端root账号下,打开管理员后台设置里面填入这个秘钥验证。

Gitlab EE V18.4.1破解成功
破解版风险问题
主要涉及 Service Ping / Usage Ping / Subscription sync 【可以自己禁用】
防火墙完全阻断对外出站(尤其到 version.gitlab.com、customers.gitlab.com 等服务域名/IP)的网络流量,实例就无法发包到外网
订阅/许可证同步(license/subscription sync)【来自官网】
Your subscription data is automatically synchronized once a day between your GitLab Self-Managed instance and GitLab. 您的订阅数据每天会在您的 GitLab 自管理实例和 GitLab 之间自动同步一次。
At approximately 3:00 AM (UTC), this daily synchronization job sends subscription data to the Customers Portal. For this reason, updates and renewals might not apply immediately. 大约凌晨 3:00(UTC),此每日同步作业会发送 订阅数据已上传至客户门户。因此,更新和续订可能不会立即生效。
The data is sent securely through an encrypted HTTPS connection to customers.gitlab.com on port 443. If the job fails, it retries up to 12 times over approximately 17 hours. 数据通过加密的 HTTPS 连接安全发送到 端口 443 上的 customers.gitlab.com 。如果作业失败,它会在大约 17 小时内重试最多 12 次。
Usage / Service Ping(遥测 / 用量统计)【来自官网】
GitLab 有一套Usage Ping / Service Ping,用于收集聚合的后端使用数据(feature usage、活动计数等)
Usage statistics | GitLab Docs
破解机制—自己生成密钥对,篡改验证机制(替换公钥)
GitLab 官方许可证机制是基于 公钥签名体系 的
GitLab 的许可证系统(gitlab-license gem)使用 RSA 签名验证:
- 官方 GitLab 公司持有一对密钥:
- 私钥(保密,用来签发许可证)
- 公钥(嵌入在 GitLab EE 程序中,用来验证许可证真伪)
许可证签发流程:
- 官方用自己的私钥对许可证信息(license 内容)做签名;
- GitLab EE 在启动时,用内置的 公钥 验证签名;
- 验证通过 → 许可证合法; 验证失败 → 报 “Invalid license”。
我们是在本地生成的 license_key / license_key.pub 是 另一对新的密钥对, 并不是 GitLab 官方那一对。
为什么能“自己生成”?
因为 GitLab 的许可证验证逻辑是开源的(在 gitlab-license gem 和 EE 源码中), 你可以用相同算法生成密钥并签名,只是默认的验证用的是官方公钥。
换句话说:
- GitLab 的代码里会去
/opt/gitlab/embedded/service/gitlab-rails/.license_encryption_key.pub读取验证公钥; - 如果你替换了这个文件(用你自己生成的
license_key.pub), 那验证过程就会变成:“用你自己的公钥验证你自己签的许可证”。
于是——验证当然能通过。 这就是为什么你能“自己生成许可证”,并且 GitLab 不会报错。
会不会被官方检测发现?
🧩 一、GitLab “是否会主动上传验证数据”
答案:不会自动上报许可证文件本身。 但它确实会在默认情况下上传统计信息(Telemetry / Service Ping),其中包含许可证摘要字段。
这些数据的关键部分在:
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/usage_data.rb
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/usage_data/service_ping_report.rb
里面的逻辑会收集以下数据:
- 当前版本(Community / Enterprise)
- 激活用户数、项目数
- 许可证信息摘要(不是许可证文件内容)
- 安装域名(hostname)
license_sha(许可证文件的 SHA 校验摘要)
然后通过 HTTP(S) 上报至:
https://version.gitlab.com/
GitLab 官方称这是“Service Ping telemetry”。 默认开启,但可以在配置中禁用。
⚙️ 二、禁用 Telemetry 的配置方法(官方支持)
在 /etc/gitlab/gitlab.rb 中添加:
gitlab_rails['usage_ping_enabled'] = false
然后:
gitlab-ctl reconfigure
也可以在管理员界面关闭:
Admin → Settings → General → Metrics and profiling → “Usage statistics” → 取消勾选
这会阻止 GitLab 发送任何统计数据给官方服务器。
🧱 三、实际依据(源码与日志可验证)
你可以直接在容器内执行:
grep -R "version.gitlab.com" /opt/gitlab/embedded/service/gitlab-rails/
你会发现它确实是通过 ServicePingWorker 异步任务发送统计的。 你也可以查看计划任务:
gitlab-rake gitlab:usage_data
这个命令会输出它打算上传的所有字段。
你会看到有类似:
"license_sha": "8f9b7c8b23...",
"license_md5": "c5d...fae"
但没有原始许可证内容。
📘 结论:只要禁用 usage_ping,就不会上传任何许可证相关信息。
🧠 四、为什么 GitLab 无法“主动检测破解”
因为:
- GitLab 服务器端的许可证验证完全在本地 Ruby 逻辑中执行;
- 没有“远程验证签名”步骤;
- 只要你禁用了 usage_ping,它就没法远程知道;
- GitLab 没有像 Windows、Adobe 那样的远程激活机制。
⚠️ 所以除非:
- 你开启了 Telemetry;
- 或者你访问了官方 SaaS 服务(gitlab.com); 否则官方服务器根本无法感知你是否修改了
.license_encryption_key.pub。
🧾 五、来自实际部署经验(GitLab 社区与企业)
很多中国公司或个人自托管 GitLab EE 时, 为了避免误上传信息,都会:
- 在配置里禁用
usage_ping; - 禁止服务器访问外网(或仅限私有镜像源);
- 使用私有 DNS 或防火墙阻断
version.gitlab.com。
实际验证: 抓包 (tcpdump 或 iptables -L) 后,没有任何外发请求时,GitLab 后台是完全自循环运行的。
✅ 六、总结结论(可验证的事实)
| 检查点 | 说明 | 风险 |
|---|---|---|
| License 验证 | 本地执行 | 无远程检测 |
| License 上传 | 仅摘要随 telemetry 发送 | 可关闭 |
| Telemetry 开关 | 支持关闭(配置或后台) | 建议关闭 |
| 远程验证机制 | 不存在(未连接 GitLab SaaS) | 无风险 |
| 法律风险 | 有(违反授权协议) | ⚠️ 理论上存在 |
⚖️ 七、最终总结一句话
自托管 GitLab EE,替换验证密钥属于本地行为; 官方默认不会检测,也不会上报许可证内容; 只要禁用 usage_ping,就不会有外部网络包发送。
⚠️ 但这属于“技术可行、授权非法”行为,不建议用于企业或公网环境。
作者
fffff@xf.nn
