群辉Nas部署GitServer随笔

群辉Nas部署GitServer随笔
目的:在群晖上搭建一个 Git 服务器用来管理代码版本让团队协作更方便以下内容为我自己研究的,仅供学习参考,生产环境慎用一.环境搭建一台群晖 NAS已联网能正常访问 DSM 桌面,同时安装了群辉自带的GitServer套件群晖账号管理员账号用于后续操作电脑Windows/Mac/Linux 均可已安装 Git 客户端局域网环境电脑和 NAS 在同一网络下我使用的是群辉自带的Git套件,当然你可以使用Docker部署其他Git服务(不在本文讨论范围内)注意:如果某个账号没法操作仓库,可能是你这里忘记勾选了管理员账号权限太大用来日常 Git 操作不安全Git 专用账号被git-shell锁在“笼子”里只能执行 Git 命令即使私钥泄露破坏范围也仅限于仓库。下面是群辉的文档,先查看一下这里提到一个SSH,可能你不熟悉什么是SSHSSH 是一种安全的远程操作协议你可以把它理解成一条“加密的管道”——你在电脑上敲的命令通过这条管道安全地传到群晖上执行中间传输的内容都是加密的不怕被偷听。我们后面所有对群晖的远程操作创建仓库、改权限等都要通过 SSH 来完成。我们需要在群辉桌面启动SSH功能然后在个人电脑打开powershell常见的三种登录,你能登录上即可二.如何创建一对SSH 公钥私钥对为什么需要这个SSH 免密登录的核心就是把“密码”换成“钥匙”私钥id_rsa_synology放在你电脑上绝不给任何人公钥id_rsa_synology.pub放到群晖上让服务器“记住”你操作步骤第 1 步打开终端Windows 用 PowerShellMac/Linux 用 Terminal。第 2 步执行生成命令bashssh-keygen -t rsa -f ~/.ssh/id_rsa_synology -C Synology参数说明参数含义-t rsa指定使用 RSA 算法最通用-f ~/.ssh/id_rsa_synology指定生成的文件名自己取方便识别-C Synology加个注释方便以后辨认这把钥匙是干什么的第 3 步一路回车执行后会提示你输入密码Passphrase——直接按两次回车跳过这样就是完全免密的。第 4 步确认生成成功ls ~/.ssh/你会看到两个新文件id_rsa_synology ← 私钥自己藏好 id_rsa_synology.pub ← 公钥放到服务器上第 5 步查看公钥内容cat ~/.ssh/id_rsa_synology.pub会输出类似这样的内容ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDF... Synology直接查看也发现确实生成了, .pub是公钥,需要放到你群辉的home/.ssh复制里面的内容下一步要贴到群晖上去。公钥要放到你的home/.ssh目录下的authorized_keys公钥的文件名字必须是这个私钥的文件名不重要你取什么都行。id_rsa_synology只是我们为了方便识别取的名字。关键是~/.ssh/config里IdentityFile要指向正确的私钥文件服务器上authorized_keys里要放对应的公钥内容最后要注意的是,如果公钥不是账户拥有者自己创建的,而是别的账号直接复制进去的,那么文件所有权会导致你的公钥没法生效,将所有权改为自己SSH Config 配置文件这个文件是干什么的~/.ssh/config是 SSH 客户端的配置文件用来给常用的 SSH 连接设置“快捷方式”。不用 config 时每次都要输完整信息ssh -i ~/.ssh/id_rsa_synology 你的用户名你的ip地址 -p 22用了 config 后只需要ssh nas我的配置文件内容Host nas HostName 你的ip地址 User 你的用户名(管理员账号) Port 22 IdentityFile ~/.ssh/id_rsa_synology Host nas-git HostName 你的ip地址 User 你的用户名(git账号) Port 22 IdentityFile ~/.ssh/id_rsa_synology各字段含义字段含义我的值Host别名快捷方式名nas/nas-gitHostName服务器 IP 地址地址User登录用户名用户名PortSSH 端口22默认IdentityFile指定用哪把私钥~/.ssh/id_rsa_synology用不同的 Host 区分不同用途命令实际连接用途ssh nas管理员账号IP地址:22管理员登录创建仓库、改权限ssh nas-gitgit专用账号IP地址:22Git 专用账号但无法交互登录git clone ssh://nas-git/...用git专用账号身份克隆日常 Git 操作存放位置操作系统路径WindowsC:\Users\你的用户名\.ssh\configMac / Linux~/.ssh/config⚠️注意文件名是config没有后缀名不是config.txt好处命令短ssh nas代替一长串参数统一管理所有连接的账号、IP、私钥都集中在一个文件里Git 也能用git clone ssh://nas-git/...会自动读取 config 里的配置SSH一种“安全的远程操作通道”让你在电脑上能连接群晖nas工作公钥 vs 私钥私钥像你的“指纹”绝不给别人公钥像“指纹锁模板”放到服务器上Git 裸仓库没有“工作区”的仓库只存版本历史是远程协作的标准形态git-shell群晖把 Git 用户锁在一个“笼子”里只能执行 Git 命令防止乱搞系统账号类型角色能做什么不能做什么Tom管理员维护者创建仓库、修改权限不建议日常 Git 操作Git_Tom我的Git 工作账号Git 机器人推送/拉取代码SSH 登录终端Jerry普通账号开发者推送/拉取代码SSH 登录终端三.创建Git仓库管理员只负责创建仓库,先查看群辉的文档很简单,前面你ssh处理好后登录后,按部就班即可这里我创建了一个测试仓库然后我需要转换所有权,把仓库给我的Git专用账号sudo chown -R Git_Jerry:users .sudo以管理员root身份运行。因为修改文件/文件夹的“拥有者”属于系统级操作即便是管理员用户没权限必须提权chownChangeOwner修改拥有者的核心命令-RRecursive递归。意思是把TestProject文件夹本身以及它里面所有的子文件和子文件夹的所有权一起改掉。如果不加-R就只会改TestProject这个目录本身里面的文件还是属于原来的用户Git_Jerry新的拥有者Owner。你要把文件夹交给谁交给这个 Git 专用账号:users新的用户组Group。冒号后面是用户组名users是群晖默认的普通用户组。意思是把文件夹的“组”也改成usersTestProject要操作的目标文件夹名,因为我已经在该目录下,所以我要改成.以管理员身份递归地将TestProject文件夹及其内部所有文件和子文件夹的拥有者改为Git专用账号所属用户组改为users。使用我的git账号克隆该仓库,但是还是提醒我使用密码,虽然我已经将公钥配置到~/ssh/authorized_keys但是我们还没有配置私钥的使用,我们将私钥配置给Git使用很简单,配置环境变量将私钥给Git使用就行了GIT_SSH_COMMANDssh -i C:\Users\Windows\.ssh\id_rsa_synology如果你使用小乌龟可能需要配置一下使用的ssh客户端,最好使用微软的ssh客户端,我测试git自带的ssh客户端有些不支持,有些资料说Git For Windows内置的SSH客户端比较新,而群辉自带的SSH服务端比较旧,而微软的SSH客户端设计比较保守,所以二者能通讯还有一个要注意的是我发现小乌龟配置的调用Git For Windows的SSH客户端的路径是写死的四.文件夹权限处理首先我们主要关注这三个组,users和admin两个组是群辉自带的,有一个规则就是所有账户默认都必须处于users组,这迫使我的管理员账号也处于这个组,导致我没法很好的把管理员和用户完全隔离开,所以我再创建一个basic组,将所有非管理员都放进去,而uses组不进行任何权限配置这样在GitFile文件处我就可以细粒的控制权限,让我的Git账号有可读写权限,而其他普通用户则无法访问GitFile如果你觉得权限管理没必要这么精细,那么可以直接这样是省事,不需要给每个仓库分配权限,坏处是每个开发都可以看到所有的仓库,即使他没用参与某个项目,更进一步的是因为是可读写所以有删库的风险,尽量避免这种情况,这种方式过于粗放将用得到Git服务的成员归到开发组,配置这个组,然后再根据项目实际情况,配置某个仓库的具体权限五.那么如果新入职一个同事如果新入职一个开发,需要用到Git,将会有哪些工作处理?假定已经为该同事分配了群辉账号,同时分配到了开发组1.勾选Git Server套件2.创建私钥/公钥对该同事自行创建一对私钥公钥,将公钥放到他的home/.ssh可能还需要配置客户端的~/.ssh/Config如果使用小乌龟Git则最好修改SSH客户端为微软的OpenSSH六.创建脚本自动化创建Git空仓库回顾一下我都干了什么步骤命令你做的事情为什么这么做1ssh nas通过SSH连接到群晖远程操作群晖的唯一安全通道2cd /volume1/GitFile进入存放所有Git仓库的根目录所有仓库集中管理方便维护和备份3mkdir MyProject创建一个以项目命名的文件夹每个项目独立一个文件夹互不干扰4cd MyProject进入这个新文件夹要在文件夹内部执行初始化5git init --bare初始化为裸仓库--bare表示这个仓库只有版本历史没有工作区专门作为服务端供多人推送如果不转移所有权仓库的所有者是管理员账号 。日常 Git 操作push/pull使用的是权限受限的Git账号如果仓库不属于它推送会失败6sudo chown -R Git_***:users .把文件夹所有权转给Git专用账号管理员创建仓库但日常操作由权限受限的Git账号执行更安全7ls -la查看文件夹内容确认所有文件的所有者已经变成Git_***这挺麻烦的,写一个脚本来把这些步骤封装起来保存位置/usr/local/bin/目录下文件名create-git-repo文件内容就是你手动敲的那几条命令按顺序写好文件权限需要加上“可执行”权限chmod x/usr/local/bin/是 Linux 系统里专门存放“用户自己安装的可执行程序”的目录。把这个目录设置成“可执行”后你在任何位置输入create-git-repo系统都能找到并执行它。如果不放这个目录你就必须输入完整路径比如/volume1/scripts/create-git-repo那样会麻烦很多。先介绍一些概念1.1 什么是 ShellShell是 Linux 系统的命令行解释器是用户与操作系统内核之间的桥梁。你在终端里输入的每一个命令都是由 Shell 读取、解析并执行的。1.2 /bin/bash 是什么/bin/bash是一个可执行程序文件是 Linux 系统中最常用的 Shell 解释器。当你在脚本第一行写#!/bin/bash时就是在告诉系统请用/bin/bash这个程序来执行这个脚本。类比你可以把/bin/bash想象成一台打印机你的脚本就是打印纸上的内容系统执行脚本的过程就是打印机把纸上的内容逐行打印出来1.3 什么是脚本脚本是一个纯文本文件里面按顺序写着要执行的命令。它和编译型程序如 C# 编译生成的.exe的区别在于对比编译型程序C#脚本Shell形式二进制文件机器码文本文件人类可读执行方式CPU 直接执行由解释器如 bash代为执行修改后需重新编译直接生效无需编译依赖独立的可执行文件依赖解释器如 /bin/bash1.4 Linux 的 bin 目录体系Linux 系统中有多个bin目录它们的分工不同目录用途优先级/bin系统启动必需的基础命令如 ls、cp高/usr/bin用户日常使用的程序如 git、python中/usr/local/bin管理员自己安装的程序你的脚本放这里低关于优先级当系统查找一个命令时会按PATH环境变量中的顺序依次搜索找到第一个匹配的就停止。查看 PATH 环境变量bashecho $PATH在我的群晖上输出text/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin规则冒号:是分隔符从左到右优先级递减。1.5脚本内容#!/bin/bash # # 功能一键创建 Git 裸仓库 # 用法create-git-repo 仓库名 # 示例create-git-repo myproject # # $1 是脚本的第一个参数即用户传入的仓库名 # -z 检查 $1 是否为空字符串如果为空则提示正确用法并退出 if [ -z $1 ]; then echo 用法: create-git-repo 仓库名 echo 示例: create-git-repo myproject exit 1 fi # 定义变量仓库名、根目录、Git专用账号 REPO_NAME$1 BASE_DIR/volume1/GitFile GIT_USERgit_user # 替换为你的 Git 专用账号名 # -d 检查目录是否已存在防止重复创建覆盖已有仓库 if [ -d $BASE_DIR/$REPO_NAME ]; then echo 仓库 $REPO_NAME 已存在退出 exit 1 fi echo 正在创建仓库: $REPO_NAME # 以 Git 账号身份创建目录-p 确保父目录存在 sudo -u $GIT_USER mkdir -p $BASE_DIR/$REPO_NAME cd $BASE_DIR/$REPO_NAME # 初始化裸仓库丢弃所有输出信息保持屏幕整洁 sudo -u $GIT_USER git init --bare /dev/null 21 # 递归修改仓库所有权给 Git 账号 sudo chown -R $GIT_USER:users $BASE_DIR/$REPO_NAME echo 仓库创建成功 echo 名称: $REPO_NAME echo 路径: $BASE_DIR/$REPO_NAME echo 克隆地址: ssh://$GIT_USER你的群晖IP:/volume1/GitFile/$REPO_NAME1.6 关键语法解析语法含义#!/bin/bashShebang指定解释器[ -z $1 ]检查第一个参数是否为空[ -d $path ]检查路径是否为已存在的目录$变量名引用变量的值sudo -u 用户以指定用户的身份执行命令 /dev/null 21丢弃所有输出包括错误exit 1退出脚本并返回错误码1.7关于 /dev/null 21部分含义重定向输出/dev/null系统黑洞任何写往它的数据都会被丢弃21把标准错误2重定向到标准输出1作用让git init --bare不输出任何信息保持屏幕整洁。1.8部署脚本bashsudo vi /usr/local/bin/create-git-repo选择/usr/local/bin的原因它在PATH中放在这里的脚本可以在任何目录下直接调用。vi 编辑器快速上手操作按键进入编辑模式按i退出编辑模式按Esc保存并退出:wq Enter不保存退出:q! Enter删除全部内容ggdG命令模式下赋予执行权限bashsudo chmod 755 /usr/local/bin/create-git-repo755 的含义数字权限作用对象7读写执行所有者root5读执行所在组5读执行其他用户限制仅管理员可执行如果你希望只有管理员administrators组能执行这个脚本bashsudo chown root:administrators /usr/local/bin/create-git-repo sudo chmod 750 /usr/local/bin/create-git-repo验证bashls -l /usr/local/bin/create-git-repo输出text-rwxr-x--- 1 root administrators 1417 Jun 28 14:57 create-git-repo