说实话,这篇东西我早就想写了。起因特别简单:公司从旧版Bitbucket Server往新版Cloud迁移,团队里一堆老哥们儿在新界面里找不到添加SSH Key的入口,围着我这个“用过旧版的老古董”问了一圈。我一边帮他们点,一边自己也踩了几个小坑,仔细一想,新旧版的差异还真不只是“换了个皮肤”这么简单。
Bitbucket作为代码托管平台,在国内团队里的普及度虽然比不上GitLab,但也绝对不算小众。尤其是那些从Jira生态入手的团队,基本被Atlassian全家桶绑得死死的。今天这篇,我就把新旧版Bitbucket添加SSH Key的完整流程、背后逻辑、踩坑记录全部摊开来讲,给正在迁移或者刚接触Bitbucket的朋友一个参考。
1. Bitbucket的两种形态,先搞清你自己用的是哪个
很多人在网上搜教程,搜到一半发现对不上,十有八九是版本搞混了。Bitbucket这玩意儿,名字听着是一个,实际上有两个差异巨大的“分身”。
**Bitbucket Server(旧版,也就是常说的Stash改版)**是给企业内网私有化部署用的。很多老团队的内网机房里跑的还是这个版本。它的界面风格偏“厚重”,偏向服务端渲染,菜单层级深,很多功能藏得比较隐蔽。添加SSH Key的入口虽然不算难找,但路径确实比较绕,需要点好几层菜单才能进去。
**Bitbucket Cloud(新版)**是Atlassian官方托管的SaaS服务,也是现在官方主推的方向。这几年Atlassian对Cloud版本的投入明显加大,界面做了大幅重构,整体走的是现代扁平风,左侧边栏收起了很多次级导航,操作路径比旧版短了不少。我公司现在用的就是Cloud版本,体验确实更顺手。
至于为什么Atlassian要改版,我个人的理解是:旧版是“功能堆叠”逻辑,什么功能都给你摆出来,看起来丰富,但新人上手成本高;新版是“任务引导”逻辑,把你最常做的事放到最显眼的位置,把不常用的功能折叠进更深层,添加SSH Key这种高频操作就被提到了更靠前的位置。所以,如果你是从旧版“平移”过来,会觉得“入口怎么变浅了”,第一反应是不习惯,但用顺手之后就会发现回不去了。
顺带提一句,如果你用的公司内网版是2020年之前部署的,界面可能跟我们现在看到的旧版截图还有细微差别,但总体路径逻辑是一样的,不影响参考。
2. 准备工作:SSH Key本身怎么生成,新旧版通用
不管你是用旧版还是新版,前面的准备工作是一样的。你得先在自己的电脑上生成一对密钥:一把私钥留在自己机器上,一把公钥贴到Bitbucket平台。
这一步的坑我见得太多了。很多新同事会用ssh-keygen -t rsa -b 4096 -C "邮箱"生成一个RSA密钥,但这几年我强烈建议用Ed25519。为什么?因为它的密钥长度更短,安全性相当,生成速度更快,而且GitHub、GitLab、Bitbucket这些主流平台都已经支持。用RSA 4096不是不行,但每次连接都要做一次大数运算,虽然体感差异不大,但是能明显感觉到的是:如果你有一堆Git仓库,第一次clone的时候,Ed25519的握手速度确实比RSA快一些。
bash复制# 推荐:Ed25519
ssh-keygen -t ed25519 -C "your_email@example.com"
# 如果公司老环境只认RSA,再用这个
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
生成完之后,默认会存储到~/.ssh/id_ed25519和~/.ssh/id_ed25519.pub。这里有个细节要注意:如果你之前已经生成过密钥,不想覆盖,最好指定一个新文件名。比如:
bash复制ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/bitbucket_ed25519
这样的话,之后你需要在~/.ssh/config里额外配一段“走哪个私钥”的规则。这个后面“常见问题”那节我会细聊,这里先记个引子。
公钥内容就是那个.pub文件里的内容,形如:
code复制ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIXXXX... your_email@example.com
一定要复制.pub文件里的内容,不是私钥。 这个错误我见过不下10次,有人把私钥内容贴上去,结果平台不认。私钥的头部是-----BEGIN OPENSSH PRIVATE KEY-----,公钥是ssh-ed25519开头,两者长相差异巨大,稍微瞄一眼就不会搞混。
3. 旧版Bitbucket添加SSH Key的完整流程
旧版的具体操作路径,以Bitbucket Server 7.x版本为例:
第一步:点击右上角头像,选择“个人设置”
这一步大多数人都能找到。旧版的个人设置入口写的是“Personal settings”或者“Manage account”,不同小版本英文文案略有不同。点进去之后,你会看到一个经典的“两栏布局”:左侧是一大串菜单列表,右侧是内容区。
第二步:在左侧菜单里找到“SSH Keys”
这个菜单在“安全(Security)”分组下面。旧版的菜单设计特别喜欢用分组折叠,你不展开“Security”这一组,是看不到“SSH Keys”入口的。好多人在这一步卡住,就是因为没注意这个折叠菜单。
第三步:点击“添加密钥(Add key)”,弹窗填写
旧版的添加密钥弹窗上有一个“Label(标签)”字段。很多教程说这个随便填,但我的建议是:填得规范一点。比如laptop-2024、home-desktop-mac、company-workstation这种格式。因为以后你在平台上看密钥清单,如果全部是空白或者一堆乱填的字符串,想删除某个特定设备的密钥时,根本分不清哪个是哪个。
填好标签,把公钥粘贴到下面的输入框,点击保存即可。好的,保存之后,系统会提示你“密钥添加成功”。
这时你可以顺手验证一下:
bash复制ssh -T git@bitbucket.company.com
如果你看到类似“Welcome to Bitbucket, 用户名”的字样,说明密钥已经生效。
3.1 旧版流程中我踩过的坑
旧版有个特别“反人类”的设置:它不确定你粘贴的公钥末尾是否要带换行符。如果你从终端复制公钥时不小心多带了一个换行符,点击保存后,界面显示成功,但实际上验证的时候会一直报“Permission denied (publickey)”。我排查了半天,最后把整个公钥重新复制一遍,确认末尾没有多余换行才解决。
还有一个坑是:旧版Server对Ed25519的支持取决于安装版本。如果你公司还是5.x、6.x的老版本,可能还不支持Ed25519。这时候你再怎么用ssh-keygen -t ed25519生成,平台就是不认。解决办法要么是升级Server版本,要么先用RSA顶上。判断标准很简单:如果你添加Ed25519公钥时提示格式不合法,八成就是版本太老。
4. 新版Bitbucket添加SSH Key的完整流程
新版(Bitbucket Cloud,特别是2023年之后的界面)流程短了很多,但也有些细节发生了变化,我从实际操作角度拆解一下。
第一步:点击头像,进入“Personal settings”
头像还是那个头像,但下拉菜单里的入口变了,新版现在叫“Personal settings”,不再有“Manage account”的提法。点击进入后,整个界面焕然一新:左侧菜单项精简了很多,信息密度降低,留白更多。
第二步:左侧导航点“SSH keys”
新版左侧的“SSH keys”不再藏在“Security”分组下,而是直接暴露在个人设置的一级导航里。这个改动对老用户是好事,少点一次菜单。但从另一个角度说,旧版把SSH keys和权限、审计日志等安全功能放在一起,能让用户意识到“这是一个安全相关操作”;新版把它独立出来,虽然方便,但安全意识传递上弱了一点。纯属个人感受。
第三步:点击“Add key”,填写信息并保存
新版同样有Label字段和Key输入框。不同之处在于,新版会实时检查公钥格式,如果格式不对,会直接红字报错。我实测过,Ed25519公钥和RSA公钥都能正常识别,不挑食。
保存之后,界面上会多出一行密钥记录,并且会显示密钥的指纹(fingerprint),方便你核对。新版还多了一个“Last used”字段,这个特别实用,你能看到哪个密钥最近在用,哪些是“僵尸密钥”——常年没用过的,就可以考虑清理掉了。
验证连接的命令也要改一下:
bash复制ssh -T git@bitbucket.org
新版Cloud的SSH端口走的是bitbucket.org域名,不是内网域名。返回的信息类似:
code复制authenticated via ssh key.
You can use git to connect to Bitbucket. Shell access is disabled
看到这行提示,说明一切正常。
4.1 新版流程中让我“真香”的两个细节
第一,新版支持了多密钥按域名区分。旧版Server如果遇到同一台机器需要同时连接多个Bitbucket实例的情况,基本只能靠搞~/.ssh/config去配,平台层面没什么可做的。而新版Cloud在这个场景下更灵活——你可以在一个账号下添加多个公钥,然后通过账密体系关联到不同工作区。说白了,平台本身的密钥管理颗粒度更细了。
第二是新版的页面跳转做了极简处理。添加密钥成功后,页面不会跳转刷新,而是直接在当前页异步更新列表,操作体感非常顺滑,有点像我第一次用新版GitHub Actions的界面时那种丝滑感。对比旧版“保存后刷新页面”的写法,新版明显在交互上下过功夫。
5. 新旧版添加SSH Key的核心差异对比
为了方便大家对照,我把新旧版的差异整理成表格,建议收藏:
| 对比维度 | 旧版(Server/Stash) | 新版(Cloud) |
|---|---|---|
| 个人设置入口 | Personal settings 或 Manage account | Personal settings |
| SSH Keys菜单位置 | 安全分组下,需展开折叠菜单 | 左侧一级导航,直接可见 |
| 添加密钥形式 | 弹窗式表单,无实时校验 | 页面内嵌表单,实时校验格式 |
| Ed25519支持 | 取决于Server版本,老版本可能不支持 | 原生支持 |
| 验证命令 | ssh -T git@内网域名 |
ssh -T git@bitbucket.org |
| 密钥管理能力 | Label + 公钥 | Label + 公钥 + 指纹 + 最后使用时间 |
| 保存交互 | 保存后跳转刷新 | 异步更新,无刷新 |
| 定位 | 偏内网、私有化、稳重 | 偏SaaS、云原生、轻快 |
这表里有个值得展开的点:“密钥管理能力”的差异其实比表面看起来更大。旧版虽然也能加Label,但Label只是个备注,没有实际用途;新版多出来的指纹和最后使用时间字段,能帮你做密钥生命周期管理。比如你配了CI服务器用的密钥,如果CI停了,那个密钥的“Last used”就停在某一天,过几个月一看,诶,这个密钥已经3个月没用了,说明对应任务已经停了,顺手就能删掉。这种细节对于团队安全管理很有价值。
6. 常见问题与排查技巧实录
我整理了一份高频问题速查表,全是实际工作中碰到的,不是网上抄来的。
| 问题现象 | 排查方向 | 解决办法 |
|---|---|---|
密钥添加成功,但ssh -T报Permission denied |
1. 私钥是否在正确位置 2. 是否指定了正确的私钥文件 |
ssh -i ~/.ssh/bitbucket_ed25519 -T git@bitbucket.org手动指定私钥测试 |
| 多个平台密钥混用,GitLab能连,Bitbucket连不上 | ~/.ssh/config没有为Bitbucket配置单独的IdentityFile |
在config里加Host bitbucket.org + HostName bitbucket.org + User git + IdentityFile ~/.ssh/你的私钥文件名 |
| 公司内网代理导致SSH连接超时 | SSH的22端口可能被封 | 改用HTTPS方式,或在~/.ssh/config里设置代理命令ProxyCommand |
| 复制公钥时带了换行符,保存后无法验证 | 粘贴时多了一个空行 | 重新粘贴,确认末尾只到邮箱地址即可 |
| 新版Cloud页面点“SSH keys”报权限不足 | 你的账号可能是只读权限 | 找管理员提升账号权限 |
| 旧版Server添加Ed25519密钥提示格式错误 | Server版本过低,不支持Ed25519 | 换RSA 4096,或者升级Server |
| 一觉醒来密钥提示认证失败,昨天还好好的 | 服务器上known_hosts冲突或SSH服务端重装了 | ssh-keygen -R bitbucket.org清除缓存后再连 |
6.1 多密钥场景下的~/.ssh/config配置示例
如果你想在一台机器上同时管理公司内网Bitbucket Server和云端Bitbucket Cloud,我的配置长这样:
bash复制# 云端新版
Host bitbucket.org
HostName bitbucket.org
User git
IdentityFile ~/.ssh/id_ed25519_bitbucket_cloud
# 内网旧版
Host bitbucket.company.com
HostName 192.168.1.100
User git
Port 22
IdentityFile ~/.ssh/id_ed25519_bitbucket_internal
配置完之后,连接时不需要手动指定密钥,SSH会自动根据Host匹配。而且要注意Host别名尽量写成实际域名,不然后面clone仓库时还得手动改URL,增加认知负担。
这里有个经验的“反直觉”点:SSH读取config的规则是“第一条匹配的Host生效”。如果你在config前面写了一个Host *的通用段,里面指定了某个固定的IdentityFile,那后面写再多的Host bitbucket.org都不生效,因为前面的Host *已经“吃掉”了这个匹配。我第一次配的时候就在这里栽过,后面把Host *挪到文件末尾就正常了。
6.2 从“连接不上”到“连接上”的排障思路
如果上面这些表格还不够用,我再分享一个通用的排障思路。很多新手一看到“Permission denied”就慌了,其实SSH的报错信息已经告诉了你大量信息,只是你不会看。
ssh -T git@bitbucket.org -v(verbose模式)会打印出整个SSH握手过程,重点看几行:
debug1: Offering public key: ...:看它是不是用了你预期的那个密钥文件debug1: Server accepts key: ...:服务器接受了哪把密钥Authentications that can continue: publickey:服务器只接受公钥认证,而你提供了密码,自然失败Connection closed by ...:网络层就断了,排查网络而非密钥
实战中,80%的“SSH无法连接”问题,用-v一看就明白了。练会看这个输出,你基本告别了SSH排障的“玄学”状态。
6.3 一个你可能会忽略的权限问题
还有个小坑必须提一下:~/.ssh目录和私钥文件的权限不要设得太开放。Linux/macOS下,如果私钥文件是644权限(组和其他用户可读),SSH会直接拒绝使用这把密钥,报错Permissions 0644 for 'id_ed25519' are too open。
解决办法就一条命令:
bash复制chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh
Windows的WSL环境同样适用这套规则。Windows原生CMD用SSH的话,权限模型不一样,但我也建议在文件属性的“安全”页里,把密钥文件的权限改成“当前用户完全控制,其他组用户都删掉”,避免不必要的麻烦。
这个报错我见过太多次了,尤其是从Windows迁移到macOS的同事,因为Windows下不限制文件权限,到了macOS/WSL下面,系统直接不给面子。
7. 新旧版迁移中的三个隐藏影响点
如果你公司正打算从旧版Server迁到新版Cloud,除了SSH Key的流程差异,还有三个隐藏影响点值得注意,都是我亲眼见过的“坑中坑”。
第一,历史密钥全部作废重建。 旧版Server里的SSH Key记录不会自动同步到Cloud。迁移之后,团队成员每人必须在Cloud账号下重新添加一次公钥。这个事儿看着简单,实际上项目管理成本很高。我建议迁移负责人在切换日之前一周就发通知,让大家先把公钥准备好,切换当天逐个核对,别等到所有人都在报“push不了代码”的时候才统一处理。
第二,Clone URL的域名变了。 旧版是git@内网IP:项目/key.git,新版是git@bitbucket.org:工作区/仓库.git。如果团队里有写死的构建脚本、CI配置文件,里面凡是硬编码了旧域名的地方都得一并替换。我见过有人迁移完代码托管,但Jenkins流水线里的clone地址漏改了,导致构建一直失败,排查了整整一天才发现是URL没改。
第三,密钥粒度与团队权限的挂钩。 新版Cloud里,SSH Key跟账号绑定,账号又跟工作区权限绑定。也就是说,密钥的权限范围跟着账号走,而不再像旧版Server那样,密钥本身可以额外配置一些特殊的权限控制。如果你在旧版里给某台CI服务器的密钥配了“只读”权限,迁移到新版后就只能通过为CI账号设置“只读”项目权限来实现,这个映射关系需要管理员在迁移前整理清楚。
7.1 关于旧版“全局SSH Key”概念在新版中的变化
旧版Bitbucket Server有一个“全局SSH Key”的概念,管理员可以在系统层面配置一把全局公钥,所有克隆操作默认走这把全局密钥。这个设计在当时的企业内网环境很好用,因为大家在同一个内网,不用每个人都配密钥,只要管理员配一把,所有人clone都通。
但在新版Cloud里,全局SSH Key这个功能被取消了。每个用户都必须有自己的账号和密钥。这对于习惯了“开箱即用”的团队来说,是个适应成本比较高的变化。我公司的老员工就有人吐槽“以前啥都不用配,现在居然还要生成密钥”。这个吧,你说它倒退也好,说它更规范化也好,都得接受。从安全角度看,个人密钥的粒度肯定是更合理的,但便利性的确下降了。团队迁移前,最好先在内部做一次培训,别等切换那天让大家在群里问“什么是SSH Key”。
7.2 迁移后推荐做的两件小事
趁这个机会,把之前积累的密钥债也清理一下。具体两件事:
一是重新生成更安全的密钥对。如果你之前的密钥还是2018年生成的1024位RSA,趁迁移时直接换成Ed25519,一举两得。别犯懒,旧的1024位RSA在现在硬件破解能力下,安全边界已经比较模糊了。
二是清理本地的~/.ssh目录。备份确认无用后,删掉那些已经失效的旧私钥,避免下次连其他平台时SSH逐个尝试密钥造成不必要的延迟。SSH默认会尝试~/.ssh下所有密钥,私钥文件越多,连接越慢,第一次握手时尤其明显。
8. 还是那句老话:先搞清环境,再动手
之所以把环境判断放在文章最后来强调,是因为这个问题值得用“后置重点”的方式再敲打一下。很多教程默认你是Cloud版本,结果你是Server版,照着操作自然不对。判断方法很简单:看登录后的URL。如果是bitbucket.company.com或者内网IP,那就是Server版,走旧版流程;如果是bitbucket.org,那就是Cloud版,走新版流程。
如果你自己公司改版已经有一段时间了,我建议优先用新版流程去试,因为Atlassian已经明确表示未来重心都在Cloud上,Server虽然还在维护期,但不会再有大的功能更新,最终所有团队都得迁移到Subversion式演化路径上——等等,这里用词可能不太准确,我说的是“往Cloud方向走”,别被这个口误带偏了。
我个人在实际迁移和日常使用中最大的感受是,Bitbucket的SSH Key管理不管在哪一代版本里,本质都是“本地生成密钥对 + 平台粘贴公钥 + SSH验证连接”三步走。界面和路径再怎么变,这个核心逻辑不会变。所以只要你真正理解了SSH Key的原理,换到任何一家代码托管平台(GitHub、GitLab、Bitbucket)都不会慌,无非是找一找入口在哪。
希望这篇对比能帮你少踩几个坑。如果你在迁移过程中还遇到过其他奇奇怪怪的问题,欢迎在评论区聊聊,我看到了会尽量回复。
