The SSH (Secure Shell) protocol is used for remote logins, file transfers, and automated systems management. It is used to manage the Internet infrastructure, cloud infrastructure, enterprise IT infrastructure, and remote servers in data centers.
是的,其也在云基础设施广泛使用,SSH 早已成一个标准,各个类 Unix 或 Linux 都原生支持,SSH 运维或者如今的 DevOPS 对于其再熟悉不过了。
➜ ~ ssh test@172.22.8.204 The authenticity of host '172.22.8.204 (172.22.8.204)' can't be established. RSA key fingerprint is SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs. Are you sure you want to continue connecting (yes/no/[fingerprint])?
➜ ~ ssh -v test@172.22.8.204 OpenSSH_8.2p1 Ubuntu-4ubuntu0.1, OpenSSL 1.1.1f 31 Mar 2020 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files debug1: /etc/ssh/ssh_config line 21: Applying options for * debug1: Connecting to 172.22.8.204 [172.22.8.204] port 22. debug1: Connection established. debug1: identity file /root/.ssh/id_rsa type -1 debug1: identity file /root/.ssh/id_rsa-cert type -1 ... ... debug1: Local version string SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1 debug1: Remote protocol version 2.0, remote software version OpenSSH_8.2p1 Ubuntu-4 debug1: match: OpenSSH_8.2p1 Ubuntu-4 pat OpenSSH* compat 0x04000000 debug1: Authenticating to 172.22.8.204:22 as 'test' debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: algorithm: curve25519-sha256 debug1: kex: host key algorithm: rsa-sha2-512 debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: ssh-rsa SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs The authenticity of host '172.22.8.204 (172.22.8.204)' can't be established. RSA key fingerprint is SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs. Are you sure you want to continue connecting (yes/no/[fingerprint])?
我们可以看到:
Server host key: ssh-rsa SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs
该散列值和下面的一致:
RSA key fingerprint is SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs
我们此时可以在服务端运行debug模式,查看日志:
1 2 3 4 5 6 7 8 9 10 11
debug1: audit_event: unhandled event 12 ➜ ~ sudo /usr/sbin/sshd -d debug1: sshd version OpenSSH_8.2, OpenSSL 1.1.1f 31 Mar 2020 debug1: private host key #0: ssh-rsa SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs debug1: Unable to load host key: /etc/ssh/ssh_host_ecdsa_key debug1: Unable to load host key: /etc/ssh/ssh_host_ed25519_key debug1: rexec_argv[0]='/usr/sbin/sshd' debug1: rexec_argv[1]='-d' debug1: Set /proc/self/oom_score_adj from 0 to -1000 debug1: Bind to port 22 on 0.0.0.0. Server listening on 0.0.0.0 port 22.
这里存在一个问题:我们无法确认上面得到的指纹哈希是否真的是来自服务端,有可能在中间被人修改的,是的,这就是中间人攻击。为了确认来自于服务端,需要用额外的方式向服务端确认指纹哈希的真实性。当然使用 CA 也是常用的解决方法。
known hosts
接着上面客户端登录,直接按回车键:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
RSA key fingerprint is SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '172.22.8.204' (RSA) to the list of known hosts. debug1: rekey out after 134217728 blocks debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: rekey in after 134217728 blocks debug1: Will attempt key: /root/.ssh/id_rsa ... debug1: SSH2_MSG_EXT_INFO received debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,sk-ssh-ed25519@openssh.com,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ecdsa-sha2-nistp256@openssh.com> debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Trying private key: /root/.ssh/id_rsa ... debug1: No more authentication methods to try. test@172.22.8.204: Permission denied (publickey).
我们可以看到:
Permanently added ‘172.22.8.204’ (RSA) to the list of known hosts.
这里需要解释另外一个概念:known hosts
known hosts 是一个记录了上诉操作相关的远程服务器 host key 的公钥信息的文件。当公钥信息与来自服务器的公钥信息一致时,就证明了服务器的真实性。
当我们再次执行登录操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
➜ / ssh -v test@172.22.8.204 ... ... debug1: Server host key: ssh-rsa SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs debug1: Host '172.22.8.204' is known and matches the RSA host key. debug1: Found key in /root/.ssh/known_hosts:2 debug1: rekey out after 134217728 blocks debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: rekey in after 134217728 blocks debug1: Will attempt key: /root/.ssh/id_rsa ... ... debug1: Trying private key: /root/.ssh/id_rsa ... test@172.22.8.204: Permission denied (publickey).
可以看到多了下面两行信息:
1 2
debug1: Host '172.22.8.204' is known and matches the RSA host key. debug1: Found key in /root/.ssh/known_hosts:2
debug1: Local version string SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1 debug1: Remote protocol version 2.0, remote software version OpenSSH_8.2p1 Ubuntu-4
这一部分描述了双方支持的 SSH 协议版本,并最终匹配出了合适的版本:
1
debug1: match: OpenSSH_8.2p1 Ubuntu-4 pat OpenSSH* compat 0x04000000
Both parties agree on a large prime number, which will serve as a seed value.
Both parties agree on an encryption generator (typically AES), which will be used to manipulate the values in a predefined way.
Independently, each party comes up with another prime number which is kept secret from the other party. This number is used as the private key for this interaction (different than the private SSH key used for authentication).
The generated private key, the encryption generator, and the shared prime number are used to generate a public key that is derived from the private key, but which can be shared with the other party.
Both participants then exchange their generated public keys.
The receiving entity uses their own private key, the other party’s public key, and the original shared prime number to compute a shared secret key. Although this is independently computed by each party, using opposite private and public keys, it will result in the same shared secret key.
The shared secret is then used to encrypt all communication that follows.
debug1: rekey out after 134217728 blocks debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: rekey in after 134217728 blocks
➜ / ssh-keygen Generating public/private rsa key pair. Enter file inwhich to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa Your public key has been saved in /root/.ssh/id_rsa.pub The key fingerprint is: SHA256:ydJlYiCF4lGxeRK9gstr84WTaIokW+jWIms31xEgmyY root@39d40aba8b3e The key's randomart image is: +---[RSA 3072]----+ | .==o | | o..*.. | | . +B o.o o | | Eo+.o.= = | | .o. .. S | | .o. o o | |o.=.+ o . | |*O++ + . | |O+oo+ | +----[SHA256]-----+
这里有两个需要注意的东西:一个是密钥生成的位置。另一个是密码短语(passphrase)。
第一个我们默认就好,但是需要生成多份密钥给多台服务器使用时,需要给出单独的位置。
第二个密码短语在我们大多数时候都是直接为空,但是有多少人知道这个是来干啥的呢?
A passphrase is similar to a password. However, a password generally refers to something used to authenticate or log into a system. A password generally refers to a secret used to protect an encryption key. Commonly, an actual encryption key is derived from the passphrase and used to encrypt the protected resource.
➜ / ssh -v test@172.22.8.204 ... debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: ssh-rsa SHA256:vyZw9CtMUy3l6RWyXDgINZZvbjJxF177s0oMKYcUUqs debug1: Host '172.22.8.204' is known and matches the RSA host key. debug1: Found key in /root/.ssh/known_hosts:2 debug1: rekey out after 134217728 blocks debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: rekey in after 134217728 blocks debug1: Will attempt key: /root/.ssh/id_rsa RSA SHA256:ydJlYiCF4lGxeRK9gstr84WTaIokW+jWIms31xEgmyY ... debug1: SSH2_MSG_EXT_INFO received debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,sk-ssh-ed25519@openssh.com,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ecdsa-sha2-nistp256@openssh.com> debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering public key: /root/.ssh/id_rsa RSA SHA256:ydJlYiCF4lGxeRK9gstr84WTaIokW+jWIms31xEgmyY debug1: Authentications that can continue: publickey ... debug1: No more authentication methods to try. test@172.22.8.204: Permission denied (publickey).
可以看到现在多了公钥的指纹哈希:
1 2 3
debug1: Will attempt key: /root/.ssh/id_rsa RSA SHA256:ydJlYiCF4lGxeRK9gstr84WTaIokW+jWIms31xEgmyY # 及 debug1: Offering public key: /root/.ssh/id_rsa RSA SHA256:ydJlYiCF4lGxeRK9gstr84WTaIokW+jWIms31xEgmyY
➜ / ssh-copy-id test@172.22.8.204 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to login with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys test@172.22.8.204: Permission denied (publickey).
无法上传,这时需要修改服务端上配置(/etc/ssh/sshd_config):
1
PasswordAuthentication yes # 设为yes
再次执行:
/ ssh-copy-id test@172.21.38.72
1 2 3 4
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys test@172.22.8.204's password:
此时要求输入密码,输入即可:
1 2 3 4 5 6 7 8 9
test@172.22.8.204's password: Authenticated to 172.22.8.204 ([172.22.8.204]:22). Transferred: sent 3252, received 2832 bytes, in 0.7 seconds Bytes per second: sent 4366.1, received 3802.2 Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'test@172.22.8.204'" and check to make sure that only the key(s) you wanted were added.
此时在服务端如下命令:
1 2
➜ ~ ls /home/test/.ssh authorized_keys
这里又出现了一个新东西:authorized_keys
authorized_keys
The authorized_keys file in SSH specifies the SSH keys that can be used for logging into the user account for which the file is configured. It is a highly important configuration file, as it configures permanent access using SSH keys and needs proper management.
System information as of Sat Aug 1 11:11:24 CST 2020
System load: 0.0 Processes: 20 Usage of /: 4.6% of 250.98GB Users logged in: 0 Memory usage: 8% IPv4 address for eth0: 172.22.8.204 Swap usage: 0%
0 updates can be installed immediately. 0 of these updates are security updates.
Authenticated to github.com ([140.82.113.3]:22). Transferred: sent 3268, received 2712 bytes, in 0.9 seconds Bytes per second: sent 3810.7, received 3162.4 Already up to date. debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 debug1: channel 0: free: client-session, nchannels 1 debug1: fd 0 clearing O_NONBLOCK Transferred: sent 3260, received 4344 bytes, in 3.9 seconds Bytes per second: sent 835.1, received 1112.8 debug1: Exit status 0
ssh-agent is a program to hold private keys used for public key authentication. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using ssh(1).
➜ / ssh-agent # 使用 ssh-add 出现 Could not open a connection to your authentication agent 错误时,使用 eval `ssh-agent -s` Agent pid 801 ➜ / ssh-add ~/.ssh/id_rsa Enter passphrase for /root/.ssh/id_rsa: Identity added: /root/.ssh/id_rsa (root@39d40aba8b3e)
此时再次登录服务器就不需要再输入密码短语了。
结语
SSH 在现在信息世界中的重要不言而喻,对于其设计思想的理解也使我们在日常开发,系统设计时多了一些思路。对于其的一些使用的掌握更有利于问题的排查和自身工作的提效。总之,SSH 已和我们如影随形,是我们现在 IT 从业人员必备知识。