SSH-add脚本化载入带密码(passphrase)的私钥

来自三线的随记

aka: load private rsa key with passphrase automatically

在一些安全要求场景下需要对ssh-keygen生成的私钥设置密码保护

但是又不想每次使用私钥时都交互式输入一次密码

ssh 127.0.0.1 ~/.ssh/id_rsa2
Enter passphrase for /root/.ssh/id_rsa2:

这时候可以通过 ssh-agentssh-add 将带密码的私钥临时载入到当前会话内存中

ssh-add : adds private key identities to the authentication agent

eval `ssh-agent`  # you might have agent already running so this might not be needed
ssh-add ~/.ssh/id_rsa # If the private key is password protected, you will be prompted to enter the password

同时ssh-agent可以通过传入相关参数控制载入的私钥的超时时间

使用命令 ssh-add -l 可以列出当前已经载入到会话内存中的私钥


但是又有一些特殊场景需要在上述基础之上,实现自动从某个地方获取私钥密码然后载入私钥(例如一个包含了节点认证私钥的docker image)

而ssh-add大多数发行版系统中都不支持从stdin中读入密码,sshpass 也不起作用, 如果也不想借助except之类的工具的话 ⬇️

经过一轮测试以后找到方法:


"Depending on your distribution and on the version of ssh-add you may be able to use the -p option of ssh-add that reads the passphrase from stdin in this way":

cat passfile | ssh-add -p keyfile

但是centos及很多发行版ssh-add都不带有 -p 参数

遂参考另外的方法:

"Similar to the answer by kenorb, but doesn't save the secret in a file"

$ DISPLAY=:0 SSH_ASKPASS=/path/to/ssh_give_pass.sh ssh-add $KEYFILE <<< "$KEYPASS"

"where ssh_give_pass.sh is:"

#!/bin/bash
# Parameter $1 passed to the script is the prompt text
# READ Secret from STDIN and echo it

read SECRET
echo $SECRET

"If you have you secret in a $KEYPASSFILE, read it into a variable first with"

KEYPASS=`cat $KEYPASSFILE`

"Also make sure that ssh_give_pass.sh is not editable by unauthorized users - it will be easy to log all secrets passed through the script."

即可。

同时man ssh-add 中也有提及

DISPLAY and SSH_ASKPASS:
    If ssh-add needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal.  
    If ssh-add does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS (by default “ssh-askpass”) and open an X11 window to read the passphrase.  
    This is particularly useful when calling ssh-add from a .xsession or related script.  
    (Note that on some machines it may be necessary to redirect the input from /dev/null to make this work.)

参考出处: https://stackoverflow.com/questions/13033799/how-to-make-ssh-add-read-passphrase-from-a-file

额外抛砖引玉型延伸

用Dockerfile一键制作一个带ssh认证公私钥(密码保护)的容器镜像

# cat Dockerfile
FROM 10.10.217.241/library/centos:7.7.1908
ARG ssh_key_pass="test123"
RUN echo $ssh_key_pass && \
    ssh-keygen -f /root/.ssh/id_rsa -P "${ssh_key_pass}" -o -ted25519


扩展阅读:

Fish shell或bash shell下的ssh-agent现有会话探测脚本

ssh转发代理:ssh-agent用法详解