我最近在一台刚装好的 openEuler 24.03 服务器上折腾 Git 环境,一开始以为不就是dnf install -y git一把梭的事,结果真正卡住我的不是安装,而是后面那套 SSH 免密配置。网上关于 openEuler 的资料本来就少,很多帖子还是老版本的 CentOS 思路,照着抄很容易踩坑。
这篇文章把我从零开始配置的完整过程写出来,包括为什么选包管理器安装、SSH 免密背后的认证逻辑、多账号怎么管理密钥,以及我在实际环境中遇到的几个典型故障。不管你是刚接触 openEuler 的新手,还是被 Git 免密折磨过的老手,这篇文章应该都能给你省点时间。
1. 先想明白:openEuler 24.03 上装 Git 到底有几条路
动手之前,我把安装方式捋了一遍。很多人上来就搜"源码编译最新版 Git",我觉得这个决策值得商榷。openEuler 24.03 是 RPM 系发行版,包管理器是 dnf,它自带的软件源里就有 Git,正常情况下一行命令就能装好,没必要非去源码编译。
1.1 包管理器安装:省事且够用
openEuler 24.03 的官方源分为 BaseOS、EPOL 等几个仓库,Git 就在 BaseOS 里。用 dnf 安装的好处非常明显:
- 依赖自动解决,不用手动去装 curl-devel、openssl-devel、expat-devel 这一堆东西
- 安装路径规范,
/usr/bin/git,所有用户直接用,不用改 PATH - 卸载干净,一条
dnf remove git就能撤干净 - 有安全更新时可以直接
dnf update跟进
装出来的版本号可能不是最新的,比如 2.43.x 或者 2.44.x 这样的中间版本,但对于日常使用完全够用。我个人的观点是:服务器环境求稳,除非你确实需要某个新特性(比如更快的协议、新格式的配置),否则没必要追新。
1.2 源码编译:什么情况才值得折腾
不是说源码编译完全不行,而是你得先搞清楚代价。编译 Git 前要装一堆开发库,比如:
dnf install -y gcc make autoconf libtool curl-devel openssl-devel zlib-devel expat-devel gettext-devel perl-devel然后才是下载源码、make configure、./configure --prefix=/usr/local、make -j$(nproc)、make install这一整套流程。编译过程通常要十几分钟,如果机器配置低,半小时也不是没可能。
什么场景下值得编译?我认为主要是这两类:
- 安全基线扫描要求 Git 必须高于某个 CVE 修复版本,但系统源里的版本达不到
- 你需要官方新版本里的某个特定功能,且这个功能直接影响你的工作流
否则,dnf 装完直接干活,把时间省下来。
1.3 顺手看一下 OpenSSH 版本,别让免密栽在这里
Git 免密依赖 SSH 协议,而 SSH 服务端的实现是 OpenSSH。openEuler 24.03 自带的 OpenSSH 版本通常是 9.x,比如 9.3p2 或者更高。这个版本做 Git 免密完全没问题,支持 ed25519 密钥、支持ssh-ed25519公钥格式,和 Gitee、GitHub、GitLab 这些托管平台兼容性都很好。
我见过一些人折腾免密失败,最后发现是 OpenSSH 版本太旧,不认识新生成的 ed25519 公钥。在 openEuler 24.03 上这种情况很少见,但如果你是照着网上老教程用ssh-rsa生成的密钥,那反而可能因为 8.8 以上版本的 OpenSSH 默认禁用了 SHA-1 签名算法而失败。这个细节后面细说。
2. 装 Git 前,先把 dnf 源和基础依赖捋顺
openEuler 的 dnf 源配置和 CentOS 有相似之处,但也有自己的特点。我在实际配置中遇到的一个问题就是:刚装完系统后,某些仓库默认是关闭的,直接dnf install会报"没有匹配的软件包"。所以第一步是确认源状态。
2.1 检查系统版本和源配置
先确认你手上的系统确实是 24.03:
cat /etc/openEuler-release cat /etc/os-release正常会看到类似openEuler release 24.03 (LTS)的字样。接着看仓库列表:
dnf repolist如果repo id列表里没有 EPOL 这类扩展仓库,或者某些仓库状态是 disabled,确认一下配置文件里的enabled字段:
grep -r "enabled" /etc/yum.repos.d/openEuler.repo对于安装 Git 来说,BaseOS 仓库就够了。但如果你后面要装 EPEL 或者其他第三方软件(比如 git-lfs 的源),那就得把 EPOL 打开。修改方式是编辑/etc/yum.repos.d/openEuler.repo,把对应仓库的enabled=0改成enabled=1,然后执行:
dnf makecache重新生成缓存。这一步别省,source list 没刷新的情况下装包经常会遇到 404 或者版本对不上的问题。
2.2 缺什么装什么:构建工具与依赖一览
就算用 dnf 装 Git,我仍然建议把基础开发工具组装上,因为后面编译安装一些 Git 插件、辅助脚本时很可能用得到:
dnf install -y git git-lfs vim wget curl tar unzip dnf groupinstall -y "Development Tools"git-lfs这个额外的 Git 大文件扩展,很多人在 clone 大型仓库时会遇到 "missing Git LFS" 的提示,没装就是这个原因。openEuler 的 EPOL 源里有git-lfs包,如果找不到就先确认 EPOL 仓库是否开启。
如果你确实要源码编译 Git,依赖包清单大致是:
dnf install -y gcc make autoconf libtool curl-devel openssl-devel zlib-devel expat-devel gettext-devel perl-devel perl-ExtUtils-MakeMaker这些都是编译时需要的开发库,缺一个make就会报错。我在 CentOS 时代吃过这个亏,到了 openEuler 上就老实了,先把依赖装全再干别的。
2.3 跑一遍安装并验证版本
正式安装:
dnf install -y git装完验证:
git --version git config --list如果git --version正常输出,说明安装成功。接下来做基础配置,这一步很多人跳过,但实际影响后续使用的体验:
git config --global user.name "你的名字" git config --global user.email "你的邮箱" git config --global init.defaultBranch main git config --global core.editor viminit.defaultBranch main这个是我强烈建议加的。新版 Git 已经用main作为默认分支名,但有些老版本默认还是master,提前配好能避免后续分支名不一致的混乱。
提示:
git config --global写入的是当前用户家目录下的~/.gitconfig,不是全局系统配置。换一个用户登录,这些配置不会生效,需要单独设置。
3. SSH 免密的底层逻辑:搞懂了这个,踩坑少一半
很多教程直接甩命令:ssh-keygen回车回车回车,然后把公钥贴到网页上。但一旦出问题,没有原理支撑的人就只能瞎猜。我建议花两分钟理解一下 SSH 公钥认证到底在做什么。
3.1 公钥和私钥分别扮演什么角色
SSH 密钥对是数学上成对生成的两把钥匙。简单类比:公钥像一把锁,私钥像一把钥匙。你把锁交出去(上传公钥到服务器或者托管平台),钥匙自己留着(保存在本地~/.ssh/)。别人拿着锁没法开你的锁,只有你的钥匙能对上。
实际认证过程是这样的:
- 客户端发起连接,告诉服务端自己准备用哪个密钥对
- 服务端在
authorized_keys文件里找到对应的公钥 - 服务端生成一个随机挑战(challenge),用你的公钥加密后发给客户端
- 客户端用私钥解密并签名,把结果返回
- 服务端验证签名,通过则认证成功
所以私钥必须保持私密,权限不能放开给其他用户;公钥则可以放心地分发到任意服务器和平台。
3.2 为什么 Git 托管平台要让你添加公钥而不是私钥
Gitee、GitHub、GitLab 这些平台的 SSH 设置页面都只有一个操作——添加公钥。很多人第一次用会疑惑:为什么不需要提交私钥?
道理很简单:平台方保存公钥,本身不具备伪造身份的能力;它们只是在认证时验证你是否持有对应的私钥。如果平台保存的是私钥,那平台的任何一次数据泄露都会导致所有用户的账户被接管。这是设计上最基本的取舍。
另外,Git 平台使用 SSH 协议时统一把用户名固定为git,真正的身份识别完全靠密钥对。所以git clone git@gitee.com:xxx/repo.git里的git@不是你的账号名,而是 SSH 服务约定好的用户名。
3.3 权限模型:authorized_keys 与 .ssh 目录的严格规则
这是免密配置里最容易踩的坑之一。OpenSSH 为了保证安全,对密钥相关文件的权限有极其严格的要求:
| 路径 | 要求权限 | 说明 |
|---|---|---|
~/.ssh目录 | 700(rwx------) | 其他用户不能进入 |
~/.ssh/authorized_keys | 600(rw-------) | 其他用户不能读取 |
| 私钥文件 | 600(rw-------) | 其他用户不能读取 |
| 用户家目录 | 不能对 group 或 others 可写 | 否则 OpenSSH 拒绝读取密钥 |
我在实际环境中遇到的情况是:用脚本批量初始化用户环境时,authorized_keys被创建成了 644 权限,结果怎么连都报Permission denied (publickey)。排查到最后才发现是权限太宽松,OpenSSH 直接忽略了这个文件。
如果你用ssh-copy-id自动推送公钥,通常权限会自动设置好。但如果手动创建authorized_keys,一定要手动纠正:
mkdir -p ~/.ssh chmod 700 ~/.ssh touch ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keysopenEuler 默认的 umask 是 022,这意味着新建文件的默认权限是 644,新建目录是 755。这跟 SSH 的安全要求直接冲突,所以手动配权限这一步真的不能省。
4. 免密配置全流程:从生成密钥到第一次免密 clone
理论讲完了,下面是我在 openEuler 24.03 上完整跑通的流程。每一步都标注了我在执行过程中遇到的实际情况。
4.1 生成 ed25519 密钥对
建议直接用 ed25519 算法,不要再用 RSA:
ssh-keygen -t ed25519 -C "你的备注信息" -f ~/.ssh/id_ed25519-C是注释,一般写成你的邮箱或者服务器名,方便识别是哪台机器、哪个账号的密钥。-f指定生成路径,如果不指定,默认就是~/.ssh/id_ed25519和~/.ssh/id_ed25519.pub。
执行过程中会让你输入 passphrase(口令),这个可以留空。留空的含义是:私钥以明文存在磁盘上,任何人拿到你的私钥文件就能伪装成你。如果你对安全要求高,可以设置口令,但代价是每次使用 SSH 时都要输入一次口令,需要配合ssh-agent使用(后面讲)。
生成完成后,查看公钥内容:
cat ~/.ssh/id_ed25519.pub输出是类似这样的格式:
ssh-ed25519 AAAA...一堆字符 你的备注信息4.2 把公钥交给远端:两种方式
方式一:托管平台(Gitee / GitHub / GitLab)
登录平台网页端,进入设置页面:
- Gitee:头像 -> 设置 -> SSH 公钥 -> 添加公钥
- GitHub:Settings -> SSH and GPG keys -> New SSH key
- GitLab:Preferences -> SSH Keys -> Add new key
把id_ed25519.pub里的内容完整复制粘贴进去,保存即可。
方式二:自己管理的服务器
如果是自己的 openEuler 服务器,用ssh-copy-id最省事:
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@你的服务器IP它会自动帮你创建~/.ssh目录、追加公钥到authorized_keys,并设置好权限。如果目标服务器没有ssh-copy-id,手动执行:
cat ~/.ssh/id_ed25519.pub | ssh root@你的服务器IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"这里我特意把chmod 700和chmod 600都放进去了,免得落地文件权限不对。
4.3 Git 全局配置与 clone 验证
公钥加好之后,先做本地验证,避免直接 clone 报错才到处找原因:
ssh -T git@gitee.com如果是 Gitee,成功会看到类似Hi 你的用户名! You've successfully authenticated...的提示。GitHub 是Hi username! You've successfully authenticated...。看到这些说明 SSH 链路已经通了。
然后克隆仓库测试:
git clone git@gitee.com:你的用户名/你的仓库.git注意这里用的是 SSH 协议的地址,不是https://开头的地址。HTTPS 地址走的是账号密码或者凭证管理器,和 SSH 密钥不是一回事。
克隆成功后,正常做开发、提交、推送。整个流程不会再问你要密码,这就是免密。
4.4 免密拉取失败时的排查链路
我整理一下我在 openEuler 上实际遇到过的免密失败场景,按排查顺序排好:
公钥没加对地方:检查平台设置里公钥是否完整粘贴(必须以
ssh-ed25519开头),有没有多空格、少字符。验证 SSH 连接本身:运行
ssh -vT git@gitee.com,加-v参数看详细日志。如果Offering public key后面紧跟Authentications that can continue: publickey,说明客户端在提供密钥但服务端不认。检查本地密钥路径:运行
ls -la ~/.ssh/看看私钥文件是否存在。注意当前登录用户,root 的~/.ssh和普通用户的~/.ssh不是同一个。权限问题:按第 3 节的标准检查
~/.ssh(700)和私钥(600)。多密钥干扰:如果
~/.ssh下有多把私钥,SSH 默认会挨个尝试。如果第一把被服务端拒绝,可能不会继续尝试后面的,需要用 config 文件明确指定(下一章讲)。老 RSA 算法问题:如果你用的还是
ssh-rsa签名,OpenSSH 8.8+ 默认禁用了 SHA-1 算法,会直接拒绝。解决办法是换成 ed25519,或者升级密钥。
注意:
~/.ssh/known_hosts记录的是你连接过的主机指纹。如果目标主机重装系统或者更换密钥,指纹变了,SSH 会报Host key verification failed,这时需要删除 known_hosts 里对应行再重连。
5. 一台机器管 N 个账号:config 文件与 ssh-agent 的配合
单账号场景很简单,但现实往往是:一个人同时用 Gitee、GitHub,还有公司的 GitLab,甚至要连接多台 openEuler 服务器。如果所有密钥都放在默认路径,SSH 的匹配规则会让你头疼。
5.1 多密钥对的生成与命名策略
我习惯按平台和用途给密钥命名,而不是全部用默认的id_ed25519:
ssh-keygen -t ed25519 -C "work@gitee" -f ~/.ssh/gitee ssh-keygen -t ed25519 -C "personal@github" -f ~/.ssh/github ssh-keygen -t ed25519 -C "admin@company-server" -f ~/.ssh/company-server好处是一目了然,不会出现"十几个密钥都叫 id_ed25519"的混乱局面。缺点是 SSH 默认不会自动识别非默认文件名的密钥,需要 config 文件来指定。
5.2 SSH config 的匹配规则
在~/.ssh/下新建一个配置文件config,内容如下:
Host gitee.com HostName gitee.com User git IdentityFile ~/.ssh/gitee IdentitiesOnly yes Host github.com HostName github.com User git IdentityFile ~/.ssh/github IdentitiesOnly yes Host company-server HostName 192.168.1.100 User root IdentityFile ~/.ssh/company-server IdentitiesOnly yes几点说明:
Host后面的别名可以自定义。比如Host company-server配了之后,直接ssh company-server就能连,不用敲完整 IP 和用户名User git是因为 Git 托管平台统一用git用户IdentitiesOnly yes很关键,它告诉 SSH:只使用 config 里指定的密钥,不要把所有密钥都拿去尝试。没有这一行的话,如果本地有 5 把密钥,SSH 可能会全部尝试一遍,平台那边如果设置了"每个公钥只允许一个账号",就会导致认证失败
配置文件要设置权限:
chmod 600 ~/.ssh/config5.3 ssh-agent 与加密私钥的日常使用
如果你给私钥设置了 passphrase,每次 SSH 连接都要输入一遍,很烦。解决方案是用ssh-agent把解密后的私钥缓存在内存里:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/gitee第一次ssh-add会问你 passphrase,之后在同一会话里就不再重复问了。openEuler 的 GNOME 桌面环境通常会自动启动 keyring 管理 agent,但纯命令行的服务器环境需要手动执行上面两条。
我个人的建议是:服务器上的部署密钥不要设置 passphrase,方便自动化脚本;个人工作机的密钥可以设置 passphrase,配合 agent 使用,安全性和便利性兼顾。
6. 实战中的杂症与收尾:从 Git LFS 到仓库安全
安装和免密是大头,但实际用起来还有一些零零碎碎的问题。我把这段时间在 openEuler 上遇到的几个典型场景汇总一下。
6.1 Git LFS:大文件仓库 clone 卡住的解法
有些仓库用 Git LFS(Large File Storage)管理二进制大文件,比如游戏资源、数据集、设计稿。如果你没有安装 git-lfs,git clone时会直接报错,或者在 clone 过程中卡在某个大文件的下载上。
openEuler 上安装 git-lfs:
dnf install -y git-lfs git lfs installgit lfs install会修改你的全局 Git 配置,注册 LFS 的过滤器。装完之后验证:
git lfs version再 clone 大仓库就不会卡住了。如果 clone 中途因为网络问题中断,不要反复从零开始,可以这样处理:
git clone --depth 1 仓库地址 cd 仓库目录 git lfs pull先浅克隆(--depth 1)拿到最新的文件快照,再单独拉取 LFS 对象。这种方法在带宽有限的场景下明显更稳。
6.2 别把 .git 目录变成漏洞:提交前的安全检查
.git目录是整个仓库的核心,里面包含完整的历史记录、分支引用、对象数据库。如果这个目录被无意中提交到公开仓库,或者通过 Web 服务器泄露出去,别人可以直接下载.git里的对象文件,重建你的全部源码和历史记录。
在 openEuler 服务器上部署网站或者服务时,我见过有人把整个 Git 仓库直接放到 Web 根目录,然后 Nginx 配置又没屏蔽.git路径,等于把自己的源码裸奔在公网上。
安全建议很简单:
- 确保
.gitignore里没有.git/这种条目(正常 Git 不会把自身目录算进去,但你要知道它的存在) - Web 服务器要屏蔽所有点开头的目录:
location ~ /\. { deny all; } - 敏感信息(密钥文件、密码文件、.env)坚决不进仓库,用环境变量或者密钥管理服务代替
这不算 Git 配置问题,但真的遇到一次就是事故级的,多提醒一句没坏处。
6.3 我的最终配置清单(抄作业版)
把前面所有配置平铺在这里,方便你对照检查:
# 1. 系统准备 dnf makecache dnf install -y git git-lfs git --version # 2. 全局配置 git config --global user.name "你的名字" git config --global user.email "你的邮箱" git config --global init.defaultBranch main git config --global core.editor vim # 3. 生成密钥 ssh-keygen -t ed25519 -C "你的备注" -f ~/.ssh/id_ed25519 # 4. 查看并上传公钥 cat ~/.ssh/id_ed25519.pub # 5. 验证免密 ssh -T git@gitee.com这个清单足够应付 openEuler 24.03 上 90% 的 Git 使用场景。如果遇到多账号,就复制第 3 步多生成几把不同的密钥,然后写~/.ssh/config。
我在实际部署中的体会是:openEuler 24.03 的 Git 环境配置并不复杂,难点往往集中在 SSH 的权限模型和多账号管理上。只要理解了公钥认证的基本原理、记住~/.ssh和authorized_keys的权限红线,配置过程基本就是复制粘贴的事。希望这篇实战记录能帮你少走一段弯路。