本文最初发表于我的个人站点
SSH 是什么
SSH 为 Secure Shell 的缩写,由IETF的网络工作小组(Network Working Group)所制定;SSH为建立在应用层和传输层基础上的安全协议。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。SSH客户端适用于多种平台。几乎所有UNIX平台—包括HP-UX、Linux、AIX、Solaris、Digital UNIX、Irix,以及其他平台,都可运行SSH。
更详细的解释可以参考 SSH百度百科
简单来理解,就是我拥有一台服务器,我现在想要登录上去做一些事情,那就得使用ssh登录到远程的服务器上,才能在上面进行操作。
SSH 服务端以及客户端配置
启动 sshd 服务
一开始在远程服务器上面,需要查看一下他的sshd服务启动了没有,如果没有启动,任何客户端主机是连接不上来的,一般如果是自己在云厂商处购买了主机,主机启动的时候就会把sshd服务启动起来。但有可能自己在测试环境搭建机器的时候,是没有默认启动的,这时候就需要在测试机器的终端看一下,命令如下
wzy@wzt-dev2-PC:~$ ps -ef| grep sshd
root 861 1 0 7月03 ? 00:00:00 /usr/sbin/sshd -D
root 12838 861 0 18:42 ? 00:00:00 sshd: wzy [priv]
wzy 12866 12838 0 18:42 ? 00:00:00 sshd: wzy@pts/9
wzy 13158 13125 0 19:06 pts/9 00:00:00 grep --color=auto sshd
这里看到第一行,sshd已经启动起来了,进程号是 861
如果没有启动的话,那就启动一下,命令如下
root@wzt-dev2-PC:/home/wzy# service sshd start
命令执行完之后,再查看一下,这时看见已经启动起来了
在第三行 ,进程号 13293
root@wzt-dev2-PC:/home/wzy# ps -ef| grep sshd
root 12838 1 0 18:42 ? 00:00:00 sshd: wzy [priv]
wzy 12866 12838 0 18:42 ? 00:00:00 sshd: wzy@pts/9
root 13293 1 0 19:11 ? 00:00:00 /usr/sbin/sshd -D
root 13310 13224 0 19:11 pts/9 00:00:00 grep --color=auto sshd
客户端使用密码的方式登录目标主机
这里我在测试环境机器的ip是 192.168.0.187, 我在自己的电脑上想要登录这台机器,我要做的就是使用ssh命令去登录192.168.0.187这台主机
我需要告诉192.168.0.187这台主机我以谁的身份去登录, 192.168.0.187会询问密码,命令如下
➜ ~ ssh root@192.168.0.187
root@192.168.0.187's password:
敲入正确的密码之后,我们就已经成功登录了主机了
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-83-generic x86_64)
* Documentation: https://help.ubuntu.com/
318 packages can be updated.
1 update is a security update.
You have new mail.
Last login: Fri Jun 30 14:18:16 2017 from 192.168.0.159
root@wzt-dev2-PC:~#
等进去之后可以看到一些欢迎词,以及系统的信息,这些是可以自己定制的,这里就不展开了
客户端使用密匙方式登录目标主机
为什么有了密码登录,还需要密匙来登录呢?我能想到的场景大概是:
如果某个运维人员临时需要登录一台机器,但是机器的管理员并不想把密码暴露给他,所以会让这个运维人员发一个自己的公钥给自己,帮他添加进去,这个运维人员就可以顺利的登录机器了。在运维做完了自己的事情之后,机器的管理员会把他从公钥列表中删掉,这样一来整个过程,密码没有暴露,运维也在这段时间内登上了机器,很完美。
因为自己懒,不想敲密码,想直接使用ssh_config和密匙对来登录
使用ssh-keygen生成密匙对
命令 ssh-keygen -t [rsa|dsa]
这里RSA和DSA只是两种不同的加密方式,详细的区别可以看这篇博客 DSA和RSA的区别
➜ .ssh ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/zhaochao/.ssh/id_rsa):foxchao
这里看到让我输入一个文件名字来保存密匙,我这里示例就输入一个"foxchao"
➜ .ssh ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/zhaochao/.ssh/id_rsa): foxchao
Enter passphrase (empty for no passphrase):
回车以后,询问是否要输入一个密码来保护这个密匙,为了方便起见,我就不输入了,不然每次使用这个密匙文件还要输一遍密码,直接一路回车就ok,如下所示
➜ .ssh ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/zhaochao/.ssh/id_rsa): foxchao
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in foxchao.
Your public key has been saved in foxchao.pub.
The key fingerprint is:
SHA256:cIeYcSCxgUjbMN+syODAM3VYiZ5/ zchao@zxhao.local
The key's randomart image is:
+---[RSA 2048]----+
|.= oB++.. |
|o Oo+= = . |
|o=.ooo+ E|
| o+ oo|
| .o o.. o oo|
| ...o.o++ ..o+|
+----[SHA256]-----+
到了这里,可以看到我们已经创建好了密匙对
➜ .ssh ll fox*
-rw------- 1 zhaochao staff 1.6K 7 17 19:32 foxchao
-rw-r--r-- 1 zhaochao staff 418B 7 17 19:32 foxchao.pub
使用密匙对登录目标主机
将公钥文件放到目标主机上,并添加进authorized_keys中
传公钥文件
现在我们新建了自己的密匙对之后,把foxchao.pub这个文件放到目标的机器上,加入目标机器的 authorized_keys 中就可以了,以后登录的时候就可以免去输入密码的步骤。
那我们先用scp放上去 ,关于scp命令,这里不过多介绍,就是传文件的一个命令,使用也比较简单,具体想了解可以看这里Linux scp命令
➜ .ssh scp foxchao.pub root@192.168.0.187:~/
这里表示我要把foxchao.pub这个文件拷贝到192.168.0.187这台机器root用户的用户目录下
回车之后会询问密码,输入密码确认之后,文件就传上去了,如下
➜ .ssh scp foxchao.pub root@192.168.0.187:~/
root@192.168.0.187's password:
foxchao.pub 100% 418 0.4KB/s 00:00
➜ .ssh
这时候我们先用密码登上去看看传上去没有
➜ .ssh scp foxchao.pub root@192.168.0.187:~/
root@192.168.0.187's password:
foxchao.pub 100% 418 0.4KB/s 00:00
➜ .ssh ssh root@192.168.0.187
root@192.168.0.187's password:
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-83-generic x86_64)
* Documentation: https://help.ubuntu.com/
318 packages can be updated.
1 update is a security update.
You have new mail.
Last login: Mon Jul 17 19:17:33 2017 from 192.168.0.115
root@wzt-dev2-PC:~# ls
dead.letter foxchao.pub php-5.6.9 php-5.6.9.tar.gz wzyadmin
root@wzt-dev2-PC:~#
可以看到foxchao.pub这个文件已经传上来了
添加进authorized_keys
目标主机上如果没有.ssh文件夹,就自己创建一个,创建好之后,再创建一个authorized_keys文件。如果有的话就不用了。
root@wzt-dev2-PC:~/.ssh# ll
total 8
drwxr-xr-x 2 root root 4096 7月 17 19:49 ./
drwx------ 10 root root 4096 7月 17 19:49 ../
-rw-r--r-- 1 root root 0 7月 17 19:49 authorized_keys
把刚才的foxchao.pub这个文件内容写进authorized_keys
root@wzt-dev2-PC:~# cat foxchao.pub >> .ssh/authorized_keys
看一下,已经有内容了
root@wzt-dev2-PC:~# cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwR8/Clov/rRfRkvpiKHVsHEQJKdSE +r4rbWKh0ce9Hz258Td6/bjq44yxb
这里需要注意
authorized_keys 文件对权限有哟求,必须是600(-rw——-)或者644
.ssh目录 必须是700(drwx——),否则一会儿登录不成功
弄完之后检查一下权限,如果不是的话,改成响应的权限就ok了
准备就绪,在客户端上登录目标主机
在登录之前,要确认一下目标主机是否允许密匙对登录,一般都是打开的,如果没有打开就自己打开
(查看 /etc/ssh/sshd_config 文件内容 中的 PubkeyAuthentication 这一项是否为 yes,如果不是就自己修改成yes之后重启sshd服务 )
wzy@wzt-dev2-PC:~$ cat /etc/ssh/sshd_config
# Package generated configuration file
# See the sshd_config(5) manpage for details
# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 1024
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
#MaxStartups 10:30:60
#Banner /etc/issue.net
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
➜ ~ ssh -i ~/.ssh/foxchao root@192.168.0.187
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-83-generic x86_64)
* Documentation: https://help.ubuntu.com/
318 packages can be updated.
1 update is a security update.
You have new mail.
Last login: Mon Jul 17 19:46:30 2017 from 192.168.0.115
root@wzt-dev2-PC:~# exit
logout
Connection to 192.168.0.187 closed.
➜ ~ ssh -i ~/.ssh/foxchao root@192.168.0.187
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-83-generic x86_64)
* Documentation: https://help.ubuntu.com/
318 packages can be updated.
1 update is a security update.
You have new mail.
Last login: Mon Jul 17 20:01:25 2017 from 192.168.0.115
root@wzt-dev2-PC:~#
ssh 的-i用于指定私钥登录 , 这里可以看到我刚使用foxchao这个私钥成功登录了192.168.0.187这台机器,并没有让我输入密码
客户端使用ssh的config文件管理会话
为了避免繁琐的每次都敲一长串 user@host 这样的命令, 可以自己在.ssh 目录下建一个config文件,文件内容如下,想要多了解一下配置参数使用的,可以看linux ssh_config和sshd_config配置文件
Host wzy-dev-1
Hostname 192.168.0.185
User wzy
ServerAliveInterval 60
ControlMaster auto
ControlPath /tmp/master-%r@%h:%p
ControlPersist yes
Host wzy-dev-2
Hostname 192.168.0.187
User wzy
ServerAliveInterval 60
ControlMaster auto
ControlPath /tmp/master-%r@%h:%p
ControlPersist yes
- Host 代表自己取的主机别名
- Hostname 填写主机的ip地址
- User 登录的用户名
- ServerAliveInterval 60 #client每隔60秒发送一次请求给server,然后server响应,从而保持连接,避免操作一半就被服务器断开
- ControlMaster 模式,可以复用之前已经建立的连接
- ControlPath 配合ControlMaster模式使用
- ControlPersist 配合ControlMaster模式使用
- Port 服务器主机指定的ssh服务端口,不写默认就是22,可以自己填写,因为有的主机为了安全考虑换了端口
- IdentityFile ~/.ssh/identity "IdentityFile"设置读取用户的RSA安全验证标识,也就是之前说的密钥对登录方式,默认会去.ssh目录下面去找私钥,也可以自己指定
文件建立好之后,直接使用自己定义的别名登录,非常方便快捷
➜ ~ ssh wzy-dev-1
Last login: Tue Jul 18 09:48:26 2017 from 192.168.0.115
wzy@wzy--dev1-pc ~ [10:44:59]
> $
服务端使用更安全的配置
如果是自己局域网搭建的机器,倒不用在意服务器的安全问题,但如果是暴露在公网上的机器,可以通过公网ip登录的,一定要注意自己服务器的安全问题,最起码不能开放默认端口,以及密码登录
在服务器上查看一下登录的日志,可以看到很多想要尝试登陆机器的人,所以公网上面的机器一定要做好自我保护
这里只列出一小部分的日志
[root@VM_centos ~]# cat /var/log/secure | grep "Failed password for root"
Jun 1 03:45:18 localhost sshd[2766]: Failed password for root from 180.169.47.94 port 49223 ssh2
Jun 1 03:45:20 localhost sshd[2770]: Failed password for root from 180.169.47.94 port 49393 ssh2
Jun 1 03:45:23 localhost sshd[2774]: Failed password for root from 180.169.47.94 port 49533 ssh2
Jun 1 03:45:25 localhost sshd[2778]: Failed password for root from 180.169.47.94 port 49661 ssh2
Jun 1 03:45:27 localhost sshd[2782]: Failed password for root from 180.169.47.94 port 49800 ssh2
Jun 1 03:45:30 localhost sshd[2786]: Failed password for root from 180.169.47.94 port 49926 ssh2
Jun 1 03:45:32 localhost sshd[2790]: Failed password for root from 180.169.47.94 port 50092 ssh2
Jun 1 03:45:34 localhost sshd[2794]: Failed password for root from 180.169.47.94 port 50223 ssh2
Jun 1 03:45:37 localhost sshd[2798]: Failed password for root from 180.169.47.94 port 50363 ssh2
Jun 1 03:45:39 localhost sshd[2802]: Failed password for root from 180.169.47.94 port 50522 ssh2
Jun 1 03:45:42 localhost sshd[2806]: Failed password for root from 180.169.47.94 port 50656 ssh2
Jun 1 03:45:44 localhost sshd[2810]: Failed password for root from 180.169.47.94 port 50822 ssh2
Jun 1 03:45:46 localhost sshd[2814]: Failed password for root from 180.169.47.94 port 50944 ssh2
Jun 1 03:45:49 localhost sshd[2818]: Failed password for root from 180.169.47.94 port 51061 ssh2
Jun 1 03:45:51 localhost sshd[2822]: Failed password for root from 180.169.47.94 port 51246 ssh2
Jun 1 03:45:54 localhost sshd[2826]: Failed password for root from 180.169.47.94 port 51383 ssh2
Jun 1 03:45:56 localhost sshd[2830]: Failed password for root from 180.169.47.94 port 51541 ssh2
Jun 1 03:45:59 localhost sshd[2834]: Failed password for root from 180.169.47.94 port 51695 ssh2
统计一下,可以看到有29190次登录失败的记录
[root@VM_23_114_centos ~]# cat /var/log/secure | grep "authentication failure" -c
29190
我们改掉默认的端口,以及禁用密码登录,只支持密匙对登录,这样一来,提高了服务器本身的安全性,至少没那么容易被别人登录上来为所欲为。
在服务器上修改sshd的配置文件
[root@VM_centos ~]# vim /etc/ssh/sshd_config
- 找到 Port,修改为其他端口
# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options change a
# default value.
Port 12345
#AddressFamily any
# Disable legacy (protocol version 1) support in the server for new
# installations. In future the default will change to require explicit
# activation of protocol 1
Protocol 2
- 找到 PasswordAuthentication, 设置为no
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication no
- 找到 PubkeyAuthentication, 确保为yes,不然一会儿自己把自己锁在外面了
#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedKeysCommand none
#AuthorizedKeysCommandRunAs nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
保存之后,重启sshd服务
root@wzt-dev2-PC:/home/wzy# service sshd restart
使用自己定义的端口登录
➜ ~ ssh -p 12345 root@192.168.0.187 -i ~/.ssh/foxchao
-p 指定端口 -i 指定私钥文件