将SSH密钥放入.git目录,使仓库可移植到USB设备。
Put SSH keys in .git to make repos USB-portable

原始链接: https://dansjots.github.io/posts/per-repo-ssh-key/

本指南详细介绍了一种在每个仓库基础上安全管理 SSH 部署密钥的方法,避免从错误账户意外推送。与其全局管理多个 SSH 密钥,不如将私钥存储在每个仓库的 `.git` 目录*内*。 首先,初始化一个本地仓库并配置它使用特定的 SSH 命令:`git config core.sshCommand "ssh -i .git/id_ed25519"`。 然后生成一个新的密钥对并将其存储在 `.git` 文件夹内。 相应的*公钥*作为部署密钥添加到远程仓库(例如,在 GitHub 上)。 此设置确保每个仓库使用其专用的密钥进行身份验证。它是自包含的——包含密钥的仓库可以移动或复制而无需重新配置。 这消除了不断切换 SSH 密钥的需求,并降低了使用错误身份推送更改的风险。

## Hacker News 讨论:将 SSH 密钥存储在 .git 中以实现 USB 可移植性 dansjots.github.io 上的一篇最近帖子提出将 SSH 密钥直接存储在仓库的 `.git` 目录中,以实现 USB 可移植的仓库。 这在 Hacker News 上引发了热烈的争论,主要集中在**这种方法的重大安全风险**上。 许多评论者强烈警告不要采用这种做法,强调如果 USB 驱动器丢失或被盗,密钥可能会被泄露。 担心的是,获得驱动器的人将获得对整个仓库的完全访问权限,并且难以撤销访问权限。 讨论的替代方案包括使用安全飞地、FIDO 身份验证器、密码管理器作为 SSH 代理,以及 Yubikey 等硬件密钥。 几位用户强调了密钥密码和驱动器加密作为基本的安全措施的重要性。 还有人提倡利用 `~/.ssh/config` 以及每个仓库的配置来安全地管理多个密钥。 共识强烈倾向于**避免这种方法**,因为其固有的风险,许多人表示难以置信竟然有人会提出这样的建议。 讨论强调了安全密钥管理实践的重要性以及将便利性置于安全之上所带来的危险。
相关文章

原文

My repository remotes are set up to use deploy keys exclusively, as I don’t want to inadvertently push changes from the wrong account due to forgetting to change the local machine user’s credentials.

I used to do so by keeping several subdirectories inside my .ssh directory for per-account keys and manually pasting them outside whenever I want to push a specific repo, but it’s cumbersome and still quite error-prone.

Eventually I came across this SuperUser answer and adapted it with my slight twist leveraging the fact that the .git directory’s contents are well-behaved and don’t read or modify anything that Git doesn’t recognize, so no risk of accidentally committing keys.


Assuming the filenames of your private/public keypair are respectively id_ed25519 and id_ed25519.pub:

  1. Paste the private key file id_ed25519 into the .git directory of your current repo,
    i.e. it should be located at <your-repo-name>/.git/id_ed25519 now.
  2. From your repository’s working directory, run in the terminal:
    git config core.sshCommand "ssh -i .git/id_ed25519"
    

(Since SSH don’t actually care about the key’s filename, you can rename your keyfile to a more descriptive one as long as you reconfigure the sshCommand accordingly to refer to the right file)


Now anytime you push this repository to remote, it will use that private key file instead of the one located in your machine user’s .ssh directory.

This setup is localized to that repo and is entirely self-contained, i.e. you can move the repo to a different path or place it on a thumb drive to a different machine and it will work without reconfiguring.

First, set up local repository. Within the directory that is to be your repo:

git init
git config core.sshCommand "ssh -i .git/id_ed25519"
ssh-keygen -f .git/id_ed25519

After following the keygen prompts, if you open the .git directory, you will find the id_ed25519 and id_ed25519.pub private/public key files among other entries.

Open the id_ed25519.pub public key file and copy its contents. (or you could just print it in the console by typing cat .git/id_ed25519.pub)

Next, set up remote:

  1. create a new repository on GitHub/Codeberg/etc.
  2. go to repository settings -> Deploy Keys
  3. add deploy key, and paste the contents previously copied from the id_ed25519.pub file into the entry field.

Finally, copy the SSH clone address at the main web page of the repo, which should be something like [email protected]:<username>/<reponame>, and set it as remote for your local repository:

git remote add origin <ssh clone address>
git commit --allow-empty -m "My dummy commit to initialize repository"
git push -u origin

Note that I’ve made a dummy empty commit here just for the purpose of setting the upstream, but you can also just start working and only push with the -u flag to set upstream after you’ve committed to main.

联系我们 contact @ memedata.com