
我最近在一台刚装好的 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.03cat /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把对应仓库的enabled0改成enabled1然后执行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 Toolsgit-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 gitgitee.com:xxx/repo.git里的git不是你的账号名而是 SSH 服务约定好的用户名。3.3 权限模型authorized_keys 与 .ssh 目录的严格规则这是免密配置里最容易踩的坑之一。OpenSSH 为了保证安全对密钥相关文件的权限有极其严格的要求路径要求权限说明~/.ssh目录700rwx------其他用户不能进入~/.ssh/authorized_keys600rw-------其他用户不能读取私钥文件600rw-------其他用户不能读取用户家目录不能对 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 算法不要再用 RSAssh-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 公钥 - 添加公钥GitHubSettings - SSH and GPG keys - New SSH keyGitLabPreferences - 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 gitgitee.com如果是 Gitee成功会看到类似Hi 你的用户名! Youve successfully authenticated...的提示。GitHub 是Hi username! Youve successfully authenticated...。看到这些说明 SSH 链路已经通了。然后克隆仓库测试git clone gitgitee.com:你的用户名/你的仓库.git注意这里用的是 SSH 协议的地址不是https://开头的地址。HTTPS 地址走的是账号密码或者凭证管理器和 SSH 密钥不是一回事。克隆成功后正常做开发、提交、推送。整个流程不会再问你要密码这就是免密。4.4 免密拉取失败时的排查链路我整理一下我在 openEuler 上实际遇到过的免密失败场景按排查顺序排好公钥没加对地方检查平台设置里公钥是否完整粘贴必须以ssh-ed25519开头有没有多空格、少字符。验证 SSH 连接本身运行ssh -vT gitgitee.com加-v参数看详细日志。如果Offering public key后面紧跟Authentications that can continue: publickey说明客户端在提供密钥但服务端不认。检查本地密钥路径运行ls -la ~/.ssh/看看私钥文件是否存在。注意当前登录用户root 的~/.ssh和普通用户的~/.ssh不是同一个。权限问题按第 3 节的标准检查~/.ssh700和私钥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_ed25519ssh-keygen -t ed25519 -C workgitee -f ~/.ssh/gitee ssh-keygen -t ed25519 -C personalgithub -f ~/.ssh/github ssh-keygen -t ed25519 -C admincompany-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 LFSLarge File Storage管理二进制大文件比如游戏资源、数据集、设计稿。如果你没有安装 git-lfsgit clone时会直接报错或者在 clone 过程中卡在某个大文件的下载上。openEuler 上安装 git-lfsdnf 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 gitgitee.com这个清单足够应付 openEuler 24.03 上 90% 的 Git 使用场景。如果遇到多账号就复制第 3 步多生成几把不同的密钥然后写~/.ssh/config。我在实际部署中的体会是openEuler 24.03 的 Git 环境配置并不复杂难点往往集中在 SSH 的权限模型和多账号管理上。只要理解了公钥认证的基本原理、记住~/.ssh和authorized_keys的权限红线配置过程基本就是复制粘贴的事。希望这篇实战记录能帮你少走一段弯路。