说明:本文中的密码
如无特殊说明,均指的是口令
。
在前面的两个方法中,我们登录都是需要使用密码来进行认证,今天介绍一种ssh无需输入密码的登录方式,免去了记忆、保存密码(口令)的不便。当有密码的时候,会存在着一些严重的问题:
- 你需要去记住一个密码,而且为了安全,你的密码必须很长并且最好是随机的,但是这个记忆(保存)需要成本
- 如果远程主机被攻陷,对方修改ssh程序,可以截获你的密码
- 多人(多处)使用同一个帐号,存在修改密码,需要周知到很多人(修改代码中的密码)
但是如果使用ssh的密钥(公钥、私钥)认证,那么以上都不是问题。
使用ssh-keygen生成密钥对
要使用这种认证方式,我们需要先生成密钥对。一个私钥,这个放在我们的客户端机器上;公钥,这个可以放在我们想登录的服务器上。
本文以openSSH来说明,目前大部分的Linux/unix都在使用这个程序。 默认情况下,openSSH的ssh-keygen
使用的SSH2协议,并且生成RSA密钥对。
user@ubuntu:~/.ssh$ ssh-keygen -C " this is comment " Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_rsa. Your public key has been saved in /home/user/.ssh/id_rsa.pub. The key fingerprint is: ff:9e:ef:ad:4f:c6:e8:92:d0:6d:4e:ab:5d:9a:ad:66 this is comment The key's randomart image is: +--[ RSA 2048]----+ | | | | | | | | | S . . | | .. . +o | | .. =..=| | .o+EO | | .=BX++| +-----------------+
使用ssh-keygen
这个程序,就可以生成ssh的公钥和私钥了。参数-C
代表注释,可以没有这个参数。
第3行是询问将生成的密钥对存放在哪里,直接回车存放在默认的位置就可以了。
第4行、第5行是让你输入口令短语,这个用于加密私钥的。如果你输入了,会使用它对私钥加密,这意味着你以后每次使用私钥,都要输入这个口令,用来解密私钥。无特殊要求下,这里留空。
查看一下id_rsa
user@ubuntu:~/.ssh$ cat id_rsa -----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAnDA2NChF2G5oIc8DjSajFoAeDeUazmdCMiSVHR+SuGYr3Nqn 1QdD7JIZjvXePN0oaFhR/9rfKztcHJA93+SGnLieGIcUDnvKnfScLYTYoR53wyRO howVNtf10l/hFb7SWBv14zvXZNSBy53tvv7dJM871RmZXFVnAMIirDkMz1C9qjXf b30eBjsXwIl8eHTZdhy75J0q+hFehCHvyO1ZrX8WNsWnQDMlIndDg+XAC7U8+tZR swtCyVZ5YqH1WrcWvrQxJRS3Z4NsjuZXgFTT6NQnJqemVjd8At1EZb/Ja4qAp8Fx zMFfjqUMMmOUOeqRBMsehsiavtNP97sKH4eZHQIDAQABAoIBAQCVpN+aE2fwGMAu fFBTwcwJ99BT0clgLrDOqBwyHhkOEd4+qUSaJ27dz5ErVsiKGf7oEo7mC4c8vY/g UhbmV+bda0kWCP2fbt3PfxjPx/NiU3W9gyC1aqu8syd0W6allgGkp41sHN6fXbfK JdMu5rNs3BzgbLlyLOUWZeqghbyPN7ZLOGv53U/Lg4Ru8F/P9EGx9R1tKsPDy+D4 +tmAS/lahl0MuPdnA65yPI7EXQVx2f7Z34OWc5mE1AS2JfUqIWPZUN/a4uqFIMHR FTfuzRFVKJ0IcOUsaWECkmvwAgzi2DdiZJqEOqdhgoJZc53BInt03O1Ofla2pEKj KCidn/8lAoGBAM70qglt6Rz2FhueKy/ngPhjFK2O4xf2NLEjhXoIatTcO0Als/xp +WPCKx+B5LkFSq3nvvqFilKlKlYJE1FXV35Vlxe35cf+6mmsWwLlBzS7IQ0Cnw8V EdwDCCV1x7ybjMtRXZhfhVgN70YstGKY5GYAyBgBAftYoHdC3ossECgfAoGBAMEz p1OUyje3WIO4xTMveZcqUOs8E9rEKgX2oTx8UNJHW2Dt9jVGrn+3VFoMjEyUWgtK IzgWKGwLUAnA7mqsdAZ+zwDb/2Mpv9U19LBPmNmx7Phzv2jyS5J41SGJaWAQym5G 0eilmkZ1m9ktGuyT28K0Kntu8zlw9T3cEyx4Q8dDAoGAaZRT8r+Jv2aj3K8SZTv7 hbw2XlyY6i6Grx/qBlmo9rLr30vcyJbfzc7O5SIFJ4bVlGa3/WKHMKZmNMIogsTG NANCM61zolYgDI0LWSyyQmp88AA4WR9snwtE6qdtoIDSkR8PWp7Qjh19xhUkaXCK hKc9bVGGS03pfy40DlgKXg0CgYEAkb+F22fDpYSLIdOh8Js//unNYahQ0hhqG1WT DS47SmbKaLUbp9VKjs6es9ADh0HjK+Eh8I3GsLtYBgOl2JOAc+X2A4/zebtlHFM3 5Eon5RJ00nl/TIx8tmKxZjtjYzVHgSmr8PX9DGpsx8lfJlnkz11bLwLkOdEdMS10 yXdwqkECgYEApZtZmAJLMUEuFFmgGzmVRwPW2DnztxOVmen4NYVjGnQ2Bb0ERmGc a/b+3V9GCewDO8wjdQVvt2p6+Y1wdAlWBNggFejB0I4kHqI6fBuyiglbWYOz1jQD wrxiAWkW0PvLvzy/hLxcv/HO/4/El2hHB2N5wGTcg/KZgzNoJtMeXJE= -----END RSA PRIVATE KEY-----
查看公钥内容,注意它是在一行里面的。
user@ubuntu:~/.ssh$ cat id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCcMDY0KEXYbmghzwONJqMWgB4N5RrOZ0IyJJUdH5K4Zivc2qfVB0PskhmO9d483ShoWFH/2t8rO1wckD3f5IacuJ4YhxQOe8qd9JwthNihHnfDJE6GjBU21/XSX+EVvtJYG/XjO9dk1IHLne2+/t0kzzvVGZlcVWcAwiKsOQzPUL2qNd9vfR4GOxfAiXx4dNl2HLvknSr6EV6EIe/I7VmtfxY2xadAMyUid0OD5cALtTz61lGzC0LJVnliofVatxa+tDElFLdng2yO5leAVNPo1Ccmp6ZWN3wC3URlv8lrioCnwXHMwV+OpQwyY5Q56pEEyx6GyJq+00/3uwofh5kd this is comment user@ubuntu:~/.ssh$ clip < id_rsa.pub # 复制到粘贴板
本篇不多说ssh-keygen的相关参数,如果需要,可以访问http://linux.die.net/man/1/ssh-keygen进行查阅。
到远程服务器部署公钥
需要让服务器知道是我们去连接服务器的,那么我就就需要手工的将公钥添加到远程服务器上,这样去连接服务器的时候,通过验证后,就可以连接上服务器了。
可以手工的rz公钥到服务器上,或者scp到服务器上。
对于OpenSSH来说,我们需要将公钥加入到~/.ssh/authorized_keys
中。每个公钥一行,千万注意不要换行,否则可能不能正常工作。
user@ubuntu:~/.ssh$ scp id_rsa.pub username@remotehost:~/.ssh/ username@remotehost's password: ## 远程服务器上 username@remotehost:~/.ssh$ cat id_rsa.pub >> authorized_keys # 修改一下权限。 username@remotehost:~/.ssh$ chmod 600 authorized_keys
注意一下权限,不要让别人把公钥写入这个文件中。
这样,我们就可以直接ssh、scp访问到远程服务器了,不用再输入密码了。
默认情况下,我们使用ssh去访问远程服务器,默认会去读取一些私钥的文件名,我们可以使用ssh -v localost查看一下连接过程。
user@ubuntu:~/.ssh$ ssh -v localhost OpenSSH_6.2p2 Ubuntu-6ubuntu0.1, OpenSSL 1.0.1e 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 19: Applying options for * debug1: Connecting to localhost [127.0.0.1] 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: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.2p2 Ubuntu-6ubuntu0.1 debug1: Remote protocol version 2.0, remote software version OpenSSH_6.2p2 Ubuntu-6ubuntu0.1 debug1: match: OpenSSH_6.2p2 Ubuntu-6ubuntu0.1 pat OpenSSH* debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-ctr hmac-md5-etm@openssh.com none debug1: kex: client->server aes128-ctr hmac-md5-etm@openssh.com none debug1: sending SSH2_MSG_KEX_ECDH_INIT debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: ECDSA ec:71:86:f6:6f:12:cd:8f:fd:5a:69:c3:bb:ef:a2:70 debug1: Host 'localhost' is known and matches the ECDSA host key. debug1: Found key in /home/user/.ssh/known_hosts:3 debug1: ssh_ecdsa_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,password debug1: Next authentication method: publickey debug1: Offering RSA public key: /home/user/.ssh/id_rsa debug1: Server accepts key: pkalg ssh-rsa blen 279 debug1: read PEM private key done: type RSA debug1: Authentication succeeded (publickey). Authenticated to localhost ([127.0.0.1]:22). debug1: channel 0: new [client-session] debug1: Requesting no-more-sessions@openssh.com debug1: Entering interactive session. debug1: Sending environment. debug1: Sending env LANG = en_US.UTF-8
通过连接过程,我们可以看到ssh会去读取一下默认的文件,和私钥文件。因此私钥的文件名不能随便改名。另外也可以生成多个私钥,但是这个时候就需要添加到文件中了。
多个私钥
我们在使用密钥的时候,肯定不会只使用一个密钥,我们有许多个不同的服务器,帐号不同,用户名不同,我们有多个私钥,因此我们需要管理这些密钥。
通过~/.ssh/config
这个文件可以配置特定的主机,使用特定的私钥、用户名。
如果没有这个文件,那么创建它,并添加下面的内容,注意设置一下权限。
user@ubuntu:~/.ssh$ chmod 600 ~/.ssh/config user@ubuntu:~/.ssh$ cat ~/.ssh/config Host github.com *.github.com ProxyCommand connect -H web-proxy.oa.com:8080 %h %p IdentityFile ~/.ssh/privatekey/id_rsa.github User git
这里可能会有connect程序没有安装的问题出现`/bin/bash: line 0: exec: connect: not found`。执行`apt-get install connect-proxy`安装
我们配置文件,
- 第一行
Host
指定了目标主机。 - 第二行
ProxyCommand
说明要使用代理去访问这个主机。 - 第三行
IdentityFile
指定私钥的路径,通过这个关键字这样就可以保存多个私钥了。 - 第四行
User
指明了用户。
另外,如果你不想写这个配置文件,那么可以在ssh命令中使用-i
参数指定私钥的路径。
-i identity_file Selects a file from which the identity (private key) for RSA or DSA authentication is read. The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file. It is possible to have multiple -i options (and multiple identities specified in configuration files).
ssh -i ~/.ssh/privatekey/id_rsa.github -T git@github.com
以下是连接github.com的一个过程,连接普通的ssh服务器也是差不多的(上面有连接普通的ssh服务器)。可以看到ssh命令会首先读取config
的里面的配置。然后会尝试使用我的私钥。
$ ssh -vt git@github.com OpenSSH_4.6p1, OpenSSL 0.9.8e 23 Feb 2007 debug1: Reading configuration data /c/Users/user/.ssh/config debug1: Applying options for github.com debug1: Executing proxy command: exec connect -H web-proxy.oa.com:8080 github.co m 22 debug1: permanently_drop_suid: 500 debug1: identity file /c/Users/user/.ssh/privatekey/id_rsa.github type -1 debug1: Remote protocol version 2.0, remote software version OpenSSH_5.9p1 Debia n-5ubuntu1+github5 debug1: match: OpenSSH_5.9p1 Debian-5ubuntu1+github5 pat OpenSSH* debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_4.6 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server->client aes128-cbc hmac-md5 none debug1: kex: client->server aes128-cbc hmac-md5 none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug1: Host 'github.com' is known and matches the RSA host key. debug1: Found key in /c/Users/user/.ssh/known_hosts:3 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Trying private key: /c/Users/user/.ssh/privatekey/id_rsa.github debug1: read PEM private key done: type RSA debug1: Authentication succeeded (publickey). debug1: channel 0: new [client-session] debug1: Entering interactive session. debug1: Remote: Forced command. debug1: Remote: Port forwarding disabled. debug1: Remote: X11 forwarding disabled. debug1: Remote: Agent forwarding disabled. debug1: Remote: Pty allocation disabled. debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 Hi username! You've successfully authenticated, but GitHub does not provide shell access. debug1: channel 0: free: client-session, nchannels 1 Connection to github.com closed. debug1: Transferred: stdin 0, stdout 0, stderr 34 bytes in 0.7 seconds debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 47.6 debug1: Exit status 1
如果你有多台的服务器,那么就需要将公钥复制到那么多的远程服务器上,这个会比较麻烦些了,但是免去输入密码的步骤,在开发非交互程序,那可是省下了很多的步骤了。
声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客
近期评论