什么是密钥对?
使用ssh密钥对(准确地说有公钥和私钥),你可以连接一台或一群服务器,而不需要对于每一个系统输入你的密码。 你可以在生成密钥对的时候不使用“密码短句”(passphrase),但是这样是不明智的,因为假如任何人掌握了你的密钥,他就能使用它。 这个指南将告诉你如何设置你的系统,以确保你的“密码短句”被安全地记住。 (This guide describes how to setup your system so that passphrases are remembered securely. )
第一步:产生密钥
首先,如果你没有安装OpenSSH,安装它:
pacman -S openssh
接下来就可以用ssh-keygen来产生密钥对了,它只需要用一般用户权限。
[usrname@hostname ~] ssh-keygen -b 1024 -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/usrname/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/usrname/.ssh/id_dsa. Your public key has been saved in /home/usrname/.ssh/id_dsa.pub. The key fingerprint is: x6:68:xx:93:98:8x:87:95:7x:2x:4x:x9:81:xx:56:94 usrname@hostname [usrname@hostname ~]
上面我们干了个什么事情呢?
我们用 ssh-keygen
命令产生了一个1024bit长的(-b 1024
)公共/私有dsa(-t dsa
) 密钥对。你也可以创造一个rsa密钥(-t rsa
)。你可以让bit长度参数为空,对于dsa,默认的是1024bit,而rsa是2048bit。
如果你不喜欢标准的密钥的名字,你可以指定一个名字用 -f name
参数。
在这个过程中你被询问:将这些密钥存在哪(Enter file in which to save the key)?一般来说,把它放在了标准目录下的标准名字就可以了(/home/usrname/.ssh/id_rsa)。
你也会被问到“密码短句”(Enter passphrase (empty for no passphrase),passphrase,是你使用一个短语或着一句话作为密码输入,再由系统内部的加密或是散列算法生成虚拟密码后,进行下一步的认证。好处是,容易记忆,不易被破解。例如:Iseeapreetygirl)。
在这里我们先选择默认的为空的密码短句,下面合适的地方再做进一步提高。
第二步:拷贝你的公钥到远程服务器上
拷贝
在你的远程服务器上要登录的用户下建立用户目录,然后把你的公钥拷贝到它的用户目录的.ssh目录下,并改名为authorized_keys。
[usrname@hostname ~] scp .ssh/id_dsa.pub remote_usrname@remote_host:
通过scp复制公钥 (id_dsa.pub
) 到你的远程服务器 (注意在服务器主机名后面的 :
)。这种方式文件会被复制到规程主机的默认的/home/remote_usrname目录下。
改名及权限设置
接下来需要创建~/.ssh目录,如果它本来不存在的话。然后把公钥放到这个目录下,改名为authorized_keys,并且把它的用户权限设成600。
$ ssh mith@metawire.org mith@metawire.org's password: $ mkdir ~/.ssh $ mv ~/id_dsa.pub >> ~/.ssh/authorized_keys $ chmod 600 ~/.ssh/authorized_keys
另一种简单的方法
[usrname@hostname ~] ssh-copy-id -i .ssh/id_dsa.pub mith@metawire.org
完成!
如果你现在从服务器断开,然后重新连接,你可能会被要求输入“密码短语”,类似于这样的信息:
$ ssh username@remote_host Enter passphrase for key '/home/username/.ssh/id_dsa':
如果你不能用这个密码登录,应该重新检查一下你的authorized_keys的权限。 也可能要检查.ssh目录的权限。.ssh目录应该对“组用户”(group)和“其它用户”(other)没有写的权限。运行下面的命令来取消“组用户”(group)和“其它用户”(other)对于.ssh目录的写权限:
$ chmod go-w ~/.ssh
记住你的“密码短句”
现在你可以用你的密钥而不是密码来登录你的服务器了,但是这样仍然没有省什么事,你还是要输入密钥的“密码短语”。有更简单的方式么?答案就是采用SSH代理,一个用来帮你记住“密码短语”的程序。有很多工具可以用,你可以读完下面的然后自己选一个对你来说最好的。
ssh-agent
ssh-agent是OpenSSH中默认包括的(ssh代理程序)。
$ ssh-agent SSH_AUTH_SOCK=/tmp/ssh-vEGjCM2147/agent.2147; export SSH_AUTH_SOCK; SSH_AGENT_PID=2148; export SSH_AGENT_PID; echo Agent pid 2148;
当你运行ssh-agent
,它会打印出来它使用的环境和变量。要使用这些变量,运行eval
命令:
$ eval `ssh-agent` Agent pid 2157
你可以把这个加入到/etc/profile
文件中,这样它就会在你每次打开一个会话的时候自动运行了:
# echo 'eval `ssh-agent`' >> /etc/profile
注意上面的绰号,第一对是单引号,而第二对是backtick!(就是数字1左边的那个键!) 现在ssh-agent
已经在运行了,我们要告诉它我们有私钥和这个私钥在哪儿。
$ ssh-add ~/.ssh/id_dsa Enter passphrase for /home/user/.ssh/id_dsa: Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa)
输入密码短句,现在好了,你可以登录你的远程服务器而不用输入你的密码了,而且你的私钥是密码保护的。很爽是不是?
唯一的不好的就是每次打开一个新的控制台(shell)都需要创建一个新的ssh-agent
实例,这意味着你每次都要在控制台中运行 ssh-add
。 There is a workaround to that with a program or rather a script called keychain which is covered in the next section.
使用GnuPG Agent
The GnuPG agent, distributed with the gnupg2 package, has OpenSSH agent emulation. If you use GPG you might consider using its agent to take care of all of your keys. Otherwise you might like the PIN entry dialog it provides and its passphrase management, which is different from keychain.
To start using GPG agent for your SSH keys you should first start the gpg-agent with the --enable-ssh-support
option. Example (don't forget to make the file executable):
/etc/profile.d/gpg-agent.sh
#!/bin/sh envfile="${HOME}/.gnupg/gpg-agent.env" if test -f "$envfile" && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then eval "$(cat "$envfile")" else eval "$(gpg-agent --enable-ssh-support --daemon --write-env-file "$envfile")" fi
Once gpg-agent is running you can use ssh-add to approve keys, just like you did with plain ssh-agent. The list of approved keys is stored in the ~/.gnupg/sshcontrol
file. Once your key is approved you will get a PIN entry dialog every time your passphrase is needed. You can control passphrase caching in the ~/.gnupg/gpg-agent.conf
file. The following example would have gpg-agent cache your keys for 3 hours:
# Cache settings default-cache-ttl 10800 default-cache-ttl-ssh 10800
Other useful settings for this file include the PIN entry program (GTK, QT or ncurses version), keyboard grabbing and so on...:
# Environment file write-env-file /home/username/.gnupg/gpg-agent.info # Keyboard control #no-grab # PIN entry program #pinentry-program /usr/bin/pinentry-curses #pinentry-program /usr/bin/pinentry-qt4 pinentry-program /usr/bin/pinentry-gtk-2
使用密钥链(keychain)
Keychain 管理一个或更多指定的私钥。当被初始化之后,它会私钥的“短句密码”并保存。这样你的私钥是密码保护而且你不用一次又一次的输入你的密码了。
从extra repo中安装密钥链:
# pacman -S keychain
编辑你的~/.bashrc
,加入这样一行:
/usr/bin/keychain -Q -q ~/.ssh/id_dsa [[ -f $HOME/.keychain/$HOSTNAME-sh ]] && source $HOME/.keychain/$HOSTNAME-sh
如果需要, 将~/.ssh/id_dsa
替代为~/.ssh/id_rsa
. 因为这样将使用non-Bash shell, 查看帮助,使用 keychain --help
或man keychain
,以便得到更详细的关于其它shells的内容.
关掉你的shell,然后重新打开它。密钥链就会出现,如果你这是第一次运行的话它就会询问你指定私钥的“短句密码”。
使用ssh-agent和x11-ssh-askpass
你每次启动一个新的会话都要启动一次ssh-agent。ssh-agent每次将随着X会话的结束而关闭。
安装x11-ssh-askpass,它在你每次打开一个新的会话的时候询问你的“短句密码”。
sudo pacman -S x11-ssh-askpass
把这个预先加到你的 ~/.xsession
中 :
eval `/usr/bin/ssh-agent` SSH_ASKPASS=/usr/lib/openssh/x11-ssh-askpass ssh-add < /dev/null # then the end of the file with for example "exec dwm"
SSH连接控制
在 ~/.ssh/config中,加入下面的行:
host * controlmaster auto controlpath /tmp/ssh-%r@%h:%p
这样,当你开始一个SSH连接的时候,设置了"master control" 插口(socket)。The socket is named based on the controlpath
setting (%r
= username, %h
= hostname, %p
= port).
This master socket is used for each successive connection after the first, as long as one connection still exists. That is, if you connect via ssh myuser@myhost.com
, a socket named /tmp/ssh-myuser@myhost.com:22
is created. If you then ssh again to the same host, the socket is found and the remote ssh session is told to spawn a new shell. This shell does not require a login, and spawns immediately, as you're already logged in.
PuTTY
上面的过程对于使用PuTTY的用户来说将会有点复杂,因为在windows下PuTTY将不能直接用ssh-keygen。私钥需要用PuTTYgen转化,这在here可以找到。然后就按照下面的进行:
- 在Linux系统的电脑上用ssh-keygen产生密钥对(你可以通过PuTTY使用一般的username/password登录)
- 将公钥放到~/.ssh/authorized_keys
- 将私钥移到Windows机器上
- 用PuTTYgen载入私钥并点击Save private key。这将会把私钥转化成PuTTY能用的。
- 启动PuTTY,转到SSH->Auth并找到私钥。然后你就可以连接到你的Linux机器上了。你将被提示输入你的用户名和短句密码(如果你在产生密钥的时候选择了输入的话)。
注意:颠倒了这个过程,先用PuTTY产生密钥对,再用ssh-keygen转换的话,是不行的。
有用的链接和信息
- SSH with Keys HOWTO
- HOWTO: set up ssh keys
- OpenSSH key management, Part 1
- OpenSSH key management, Part 2
- OpenSSH key management, Part 3
- Getting started with SSH
- Manual Pages: ssh-keygen(1)
- Sharing SSH keys on 2 linux servers
- How to set up SSH keys: Frustration with "Server refused our key" [PuTTY]
- Securing your secure shell (SSH) service