Ubuntu 自动加载 ssh 私钥

使用 gnome 里面有个叫 gnome keyring 的东西,专门用来管理用户的登录等认证过程,默认集成了一个 ssh agent。
gnome 启动后,ssh agent 会自动的加载 ~/.ssh/ 下面跟 *.pub 匹配的私钥文件,如果仅仅有一个私钥而没有公钥,则不会加载。当然,由于某些原因,我们可能需要禁用掉该机制。有如下几种方式。

1.在 gnome-session-properties 中禁用 SSH Key Agent 开始选项

2.编译 gnome-keyring 时候禁用 ssh-agent:
$ ./configure --disable-ssh-agent

3.手动开启 gnome-keyring,通过 –components 选项禁用跟 ssh 相关的支持:
$ gnome-keyring-daemon --components keyring,pkcs11

ref:
https://live.gnome.org/GnomeKeyring/Ssh
 

ssh 使用 sudo 执行一条命令后退出

正常情况下,如果想用 ssh 在远程主机上执行一条命令就退出,这样就可以了:
# for i in {1..10};do ssh host${i} cp /home/user/hosts /tmp/;done

现在想将 ~/hosts 文件覆盖 /etc/hosts。如果仅仅加上 sudo 是不行的:
# for i in 1 2 3;do ssh host${i} sudo cp /home/user/hosts /etc/hosts;done
sudo: sorry, you must have a tty to run sudo

加上 -t 参数即可,表示强制分配一个 pseudo-tty 给该 shell:
# for i in 1 2 3;do ssh -t host${i} sudo cp /home/user/hosts /etc/hosts;done

如何在各个主机之间免密码登录

这篇记录源自于我在 Twitter 上这样的一个问题
现在有一个集群,每个机器都有其余机器的公钥,这样可以实现免密码登陆,但是一台机器被入侵其余机器不就悲剧了么,有啥办法可以防范的?

不考虑安全性,最简单的办法是在其中的一台主机上生成一套密钥以及一个 authorized_keys 文件,然后分发到其余的主机上就可以了,但是这样显然是不合理的。 @tifan 给出了一个不错的方案,简单的说就是一个 -A,也就是启动 ssh 的认证转发。

local ---> server-1 ---> server-2 --> server-3

local 上启动 ssh-agent:
$ exec ssh-agent /bin/bash
添加密钥,并查看:
$ ssh-add  .ssh/id_rsa_jw
Identity added: .ssh/id_rsa_jw (.ssh/id_rsa_jw)
$ ssh-add -l
2048 33:b8:33:33:1w:8w:67:81:aw:wq:ca:a8:3a:13:28:c0 .ssh/id_rsa_jw (RSA)
登录 server-1:
$ ssh -A [email protected]

现在就可以免密码登录 server-2 了:
$ ssh [email protected]

如果想要继续登录 server-3,则需要在登录 server-2 时加上 -A:
$ ssh -A [email protected]

注意:在执行 ssh-agent 时,记得加上 exec,不然会出现下面的错误:
Could not open a connection to your authentication agent

上面的 -A 参数就是 ~/.ssh/config 或者 /etc/ssh/ssh_config 中的 ForwardAgent,开启就不必每次都要手动输入 -A 了:
ForwardAgent yes

安全永远是相对的,本套方案同样,@czbug 同学这里记录了一篇 ssh-agent 的安全隐患。要解决此问题,还得靠人,在 man ssh 里面说的很清楚:

"Agent forwarding should be enabled with caution.  Users with the ability to bypass file permissions on the remote host (for the agent's  UNIX-domain  socket)  can  access  the  local  agent through  the forwarded connection.  An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent."

以后完事后记得注销。

ssh 连接缓慢的另一个原因

某台客户机连接 ssh 到服务器特别慢,经常是 1min 的时间才能登上,服务端的 UseDNS 已经关闭,-v 开启 debug 模式:
$ ssh [email protected] -v
OpenSSH_5.8p1 Debian-7ubuntu1, OpenSSL 1.0.0e 6 Sep 2011
debug1: Reading configuration data /home/user/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to x.x.x.x [x.x.x.x] port 22.
debug1: Connection established.
debug1: identity file /home/user/.ssh/id_rsa type 1
debug1: Checking blacklist file /usr/share/ssh/blacklist.RSA-2048
debug1: Checking blacklist file /etc/ssh/blacklist.RSA-2048
debug1: identity file /home/user/.ssh/id_rsa-cert type -1
debug1: identity file /home/user/.ssh/id_dsa type -1
debug1: identity file /home/user/.ssh/id_dsa-cert type -1
debug1: identity file /home/user/.ssh/id_ecdsa type -1
debug1: identity file /home/user/.ssh/id_ecdsa-cert type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_4.3
debug1: match: OpenSSH_4.3 pat OpenSSH_4*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.8p1 Debian-7ubuntu1
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: RSA 52:45:r7:2r:16:45:aa:6c:3a:64:10:e6:ac:30:9d:b0
debug1: Host '[x.x.x.x]:22' is known and matches the RSA host key.
debug1: Found key in /home/user/.ssh/known_hosts:23
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: gssapi-with-mic
debug1: An invalid name was supplied
Cannot determine realm for numeric host address

debug1: An invalid name was supplied
Cannot determine realm for numeric host address

debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/user/.ssh/id_rsa
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Trying private key: /home/user/.ssh/id_dsa
debug1: Trying private key: /home/user/.ssh/id_ecdsa
debug1: Next authentication method: password
[email protected]'s password:

可以很清楚的看到,时间慢出现在 gssapi-with-mic(Kerberos) 认证这个步骤,经过了多次的失败,到 public key 方式失败,最后才到了 passwd 的方式。要解决起来就很简单了,关闭 gssapi-with-mac 认证就可以了:
$ ssh -o GSSAPIAuthentication=no [email protected]

要想永久生效,/etc/ssh/ssh_config 或者 ~/.ssh/config 加上:
GSSAPIAuthentication no

ssh 和 scp 的端口指定

sshd 默认使用的是 22 端口,如果需要指定端口,使用 -p(小写 p)参数;但是在 scp 中,使用的 -P(大写 P)来指定端口问题。在 scp 上,如果使用 -p 来指定端口,会出现如下的错误:

ssh: connect to host 10.10.10.10 port 10000: Connection refused

在scp 中,p 表示:

Preserves modification times, access times, and modes from the original file.

而 P 表示:

Specifies  the  port  to  connect to on the remote host.  Note that this option is written with a capital `P', because -p is already reserved for preserving the times and modes of the file in rcp(1).

前者是用来修改时间的,后者才是用来指定端口的。