研发gitlab CI/CD时,需要编辑一个整个代码仓库统一的CI/CD流程,用于流程与权限的控制。众所周知,Gitlab的CI/CD流程是通过.gitlab-ci.yml文件配置的。通常,如果用户拉出自己的开发分支,那么该yaml文件也会被用户修改,也就是说用户可以完全不用当前的CI/CD流程而重新自定义自己的流程,越权部署代码,存在极大的安全风险。

2、适用场景

需要利用Gitlab的CI/CD功能,保护.gitlab-ci.yml不被普通用户修改;保护其他CI/CD调用到的相关文件不被用户修改。或推广到保护代码仓库中任意文件。

3、方法论

Gitlab目前并没有直接提供锁定或者保护文件相关的功能,经过充分思考与研究后,采用通过配置服务端钩子(Hook onServer),来检查特定文件是否被修改,如有发生,就拒绝接受用户推到远端的代码以保护文件。

4、开发与实践

  • 代码仓库位置
    可能位置1:/home/git/repositories//.git
    可能位置2:/var/opt/gitlab/git-data/repositories//.git
    注意: 代码仓库名称与路径可能被哈希处理了,例如当前测试的gitlab机器上就是这种情况,需要进入@hashed目录,
sh-4.2$ pwd
/var/opt/gitlab/git-data/repositories
sh-4.2$ ls
+gitaly  @hashed
sh-4.2$ cd \@hashed/
sh-4.2$ tree
`-- d4
    `-- 73
        |-- d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git
        |   |-- branches
        |   |-- config
        |   |-- custom_hooks
        |   |   `-- pre-receive
        |   |-- description
        |   |-- HEAD
        |   |-- hooks
        |   |   |-- applypatch-msg.sample
        |   |   |-- commit-msg.sample
        |   |   |-- fsmonitor-watchman.sample
        |   |   |-- post-update.sample
        |   |   |-- pre-applypatch.sample
        |   |   |-- pre-commit.sample
        |   |   |-- pre-merge-commit.sample
        |   |   |-- prepare-commit-msg.sample
        |   |   |-- pre-push.sample
        |   |   |-- pre-rebase.sample
        |   |   |-- pre-receive.sample
        |   |   `-- update.sample
        |   |-- info
        |   |   |-- exclude
        |   |   `-- refs
        |   |-- language-stats.cache
        |   |-- objects
        |   |   |-- 47
        |   |   |   `-- 81462ff2e83f3130effecea404514a8ef7382
        |   |   |-- info
        |   |   |   `-- packs
        |   |   `-- pack
        |   |       |-- pack-00634d576da38a59c654603dbb72a9e12d647124.bitmap
        |   |       |-- pack-00634d576da38a59c654603dbb72a9e12d647124.idx
        |   |       |-- pack-00634d576da38a59c654603dbb72a9e12d647124.pac
        |   |-- packed-refs
        |   `-- refs
        |       |-- heads
        |       |   `-- daliang_test_branch
        |       |-- keep-around
        |       |   `-- f37f13e889088502c18715e974299e3aafe0ff7a
        |       |-- merge-requests
        |       `-- pipelines

找到要配置的代码仓库,上图同时也展示仓库的目录与文件结构。

  • 配置服务端钩子

服务器端的钩子主要为:
pre-receive:
在有人用git push向仓库推送代码时被执行
post-receive:
post-receive钩子在成功推送后被调用,适合用于发送通知。对很多工作流来说,这是一个比post-commit更好的发送通知的地方,因为这些更改在公共的服务器而不是用户的本地机器上。给其他开发者发送邮件或者触发一个持续集成系统都是post-receive常用的操作。这个脚本没有参数,但和pre-receive一样通过标准输入读取
update:
update钩子在pre-receive之后被调用,用法也差不多。它也是在实际更新前被调用的,但它可以分别被每个推送上来的引用分别调用。也就是说如果用户尝试推送到4个分支,update会被执行4次。和pre-receive不一样,这个钩子不需要读取标准输入。
事实上,它接受三个参数:
更新的引用名称
引用中存放的旧的对象名称
引用中存放的新的对象名称

因此,我们这里用pre-receive。

sh-4.2$ cd \@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git/
sh-4.2$ mkdir custom_hooks
vim pre-receive

该文件为:

#!/bin/bash
echo "I'm a hooked file on server"
z40=0000000000000000000000000000000000000000
echo $GL_USERNAME
while read oldrev newrev refname; do
 if [ $oldrev == $z40 ]; then
   # Commit being pushed is for a new branch
   oldrev=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 yaml_file_name=".gitlab-ci.yml"
 approval_user="root"
 file_name=$(git diff --name-only $oldrev $newrev)
 if [ "$yaml_file_name" == "$file_name" ] && [ $GL_USERNAME != "$approval_user" ]; then
         echo "No permission to modify ${yaml_file_name}"
         exit 1
echo "I'm a hooked file on server"
  • 测试结果
    当时用户修改.gitlab-ci.yml之后push,会被服务端拒绝,从而保护了该文件及CI/CD流程不被篡改。
17:41:54.577: [b2c-airflow-poc] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false push --progress --porcelain origin refs/heads/daliang_test_branch:daliang_test_branch
Authenticated to 3.86.51.69 ([3.86.51.69]:22).
Enumerating objects: 5, done.
Delta compression using up to 12 threads
Total 3 (delta 2), reused 0 (delta 0)
remote: I'm a hooked file on server        
remote: No permission to modify .gitlab-ci.yml        
Transferred: sent 3368, received 3948 bytes, in 1.2 seconds
Bytes per second: sent 2789.3, received 3269.7
error: failed to push some refs to 'git@3.86.51.69:root/b2c-airflow-poc.git'
To 3.86.51.69:root/b2c-airflow-poc.git
!	refs/heads/daliang_test_branch:refs/heads/daliang_test_branch	[remote rejected] (pre-receive hook declined)
                    Gitlab 利用Server端Hook来锁定文件不被修改1、背景研发gitlab CI/CD时,需要编辑一个整个代码仓库统一的CI/CD流程,用于流程与权限的控制。众所周知,Gitlab的CI/CD流程是通过.gitlab-ci.yml文件配置的。通常,如果用户拉出自己的开发分支,那么该yaml文件也会被用户修改,也就是说用户可以完全不用当前的CI/CD流程而重新自定义自己的流程,越权部署代码,存在极大的安全风险。2、适用场景需要利用Gitlab的CI/CD功能,保护.gitlab-ci.yml不
				
4,Service Hook解析 Service/ContentProvider由于没有Activity那么复杂的启动过程,并且Activity的生命周期是由用户交互决定的, 而Service的声明周期是主动通过代码调用的。因此虽然也有替换/还原过程,但是有点不同,是采用代理分发技术。 就是启动宿主的Service/ContentProvider对象,然后管理插件的Service/Conte
GitLab保护器 一个,用于在自托管GitLab实例上的git存储库中添加对用户/组管理的文件保护支持。 如果已向试图推送新更改的用户授予许可,则GitLab Protector仅允许对某些文件进行修改,从而有助于保护git存储库。 自托管的GitLab实例(CE或EE) 可能是root访问权限,才能安装钩子 这个怎么运作 您将为每个git存储库定义规则,并定义一个仅由GitLab Protector知道和使用的组(全局)列表。 每个规则都是一个正则表达式,该正则表达式指定应保护哪些文件(和/或包含文件的目录)以防止在存储库中进行修改。 受保护的文件意味着从现在开始,仅允许特定的
提交之后的文件已被git追踪 这时需要清除git缓存 忽略文件 git rm --cached ./src/main/resources/velocity.properties 忽略文件git rm --cached -r **/res/js 再次添加文件gitignore 生效 提交会删除 git 上的文件 不更新指定文件 执行命令之前需要保持该文件为已同步状态 否则执行失败 git update-ind gitlab仓库一般位于为:/var/opt/gitlab/git-data/repositories; repositories该目录下的文件夹对应gitlab的组; 组文件夹下的对应的是gitlab上相应的代码库; 进入xxxx.git目录,目录结构大致如下:
Android系统通过Binder机制给应用程序提供了一系列的系统服务,诸如ActivityManagerService,ClipboardManager, AudioManager等;这些广泛存在系统服务给应用程序提供了诸如任务管理,音频,视频等异常强大的功能。 插件框架作为各个插件的管理者,为了使得插件能够无缝地使用这些系统服务,自然会对这些系统服务做出一定的改造(Hook),使得插件的
好的,下面是详细的设置步骤: 1. 在 GitLab 的服务器上,找到 GitLab 的仓库目录。通常情况下,该目录会位于 `/var/opt/gitlab/git-data/repositories`。 2. 进入要设置的仓库目录,依次进入 `.git` -> `hooks` 目录。 3. 在 `hooks` 目录中,可以看到一些示例 hook 脚本,例如 `pre-receive.sample`、`update.sample` 等。这些示例脚本可以供参考,但我们需要创建一个新的 hook 脚本。 4. 在 `hooks` 目录中,创建一个新的文件文件名为 `pre-receive`,并添加可执行权限。例如,可以执行以下命令: touch pre-receive chmod +x pre-receive 5. 编辑 `pre-receive` 文件,添加以下内容: #!/bin/bash while read oldrev newrev refname for rev in $(git rev-list $oldrev..$newrev) author="$(git show -s --pretty=format:'%an <%ae>' $rev)" if [[ ! "$author" =~ ^YourUserNameHere\ <YourEmailAddressHere\>$ ]]; then echo "Commit $rev rejected: wrong author name or email address." exit 1 exit 0 注意:将 `YourUserNameHere` 和 `YourEmailAddressHere` 替换为你的 Git 用户名和邮箱地址。 6. 保存并退出 `pre-receive` 文件。 7. 最后,在 GitLab 上,进入要设置的仓库的设置页面,选择 Hooks,点击添加一个新的 Hook,选择类型为“Pre-receive”,并将 URL 设置为 `http://localhost:8080`(这里假设你的 GitLab 服务器在本地,并使用默认的 HTTP 口 8080)。保存设置即可。 现在,当有人提交代码时,GitLab 将会执行 `pre-receive` hook 脚本,在校验每个提交的作者名和邮箱地址是否正确。如果不正确,提交将会被拒绝,并且 GitLab 将会输出错误信息。