一.什么是SSH?
简单说,SSH(Secure Shell)是一种网络协议,用于计算机之间的加密登录。如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露。最早的时候,互联网通信都是明文通信(比如Telnet、FTP都是明文的方式),一旦被截获,内容就暴露无疑。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的标准配置。
SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。本文的内容都是基于OpenSSH,它是是 SSH 协议的免费开源实现,应用非常广泛.Linux中一般自带的都是OpenSSH,使用ssh -V
可以查看系统正在使用的SSH客户端及版本信息,默认的SSH服务端口号为 22。
[hadoop@server04 ~]$ ssh -V
OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 Feb 2013
使用rpm -qa | grep ssh
,可以查看机器上是否已经安装了SSH,如果返回的结果如下图所示,包含了 SSH client 跟 SSH server,则不需要再安装。
若需要安装,则可以通过 yum 进行安装(安装过程中会让你输入 [y/N],输入 y 即可):
sudo yum install openssh-clients
sudo yum install openssh-server
如果要在Windows系统中使用SSH,有SecureCRT, Putty, SSH Secure Shell,XShell等多种客户端可选择。
1.中间人攻击
SSH之所以能够保证安全,原因在于它采用了公钥加密。
整个过程是这样的:
- 远程主机收到用户的登录请求,把自己的公钥发给用户。
- 用户使用这个公钥,将登录密码加密后,发送回来。
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的”中间人攻击“(Man-in-the-middle attack)。
2.SSH服务的开启
只有在SSH服务开启的状态下,才能远程登录,连接和管理服务器。如果关闭SSH服务,则远程连接客户端无法再连接服务器,但是已连接的客户端可以继续使用。
默认情况下,Linux系统是会启动时开启SSH服务(类似于mysql安装后也会有一个开机时启动的服务)。以 CentOS 7_64位系统为例,可以通过以下一些命令来启动关闭SSH服务。
执行命令
systemctl start sshd.service
或者
service sshd status
可以查看SSH服务是否启动。(centOS 5 中可以使用命令 /etc/init.d/ssh status )
active表示SSH服务是启动的。
inactive表示SSH服务已关闭
执行命令 systemctl start sshd.service
或者 service sshd start
启动SSH服务。
执行命令 systemctl stop sshd.service
或者 service sshd stop
启动SSH服务。
执行命令 systemctl restart sshd.service
或者 service sshd restart
重启SSH服务。
执行命令 systemctl enable sshd.service
或者 service sshd enable
设置服务开机自启。
二.SSH远程登录
ssh远程登录的安全外壳协议有两种身份验证机制:
- 口令验证
- 公钥验证
1.口令验证
假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。
$ ssh user@host 如:ssh hadoop@192.168.0.10
如果本地用户名与远程用户名一致,登录时可以省略用户名。
$ ssh host
SSH的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口。
$ ssh -p 2222 user@host
上面这条命令表示,ssh直接连接远程主机的2222端口。
如果你是第一次登录对方主机,系统会出现下面的提示:
$ ssh user@host
The authenticity of host ‘host (12.18.429.21)’ can’t be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?
所谓”公钥指纹”,是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。
很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。
假定经过风险衡量以后,用户决定接受这个远程主机的公钥。
Are you sure you want to continue connecting (yes/no)? yes
系统会出现一句提示,表示host主机已经得到认可。
Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
然后,会要求输入密码。
Password: (enter password)
如果密码正确,就可以登录了。
当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts
之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts
,保存一些对所有用户都可信赖的远程主机的公钥。
2.密钥验证
使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。
关于这种免密登录的原理,在 https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys 上有一段解释:
To authenticate using SSH keys, a user must have an SSH key pair on their local computer. On the remote server, the public key must be copied to a file within the user’s home directory at ~/.ssh/authorized_keys. This file contains a list of public keys, one-per-line, that are authorized to log into this account.
When a client connects to the host, wishing to use SSH key authentication, it will inform the server of this intent and will tell the server which public key to use. The server then check its authorized_keys file for the public key, generate a random string and encrypts it using the public key. This encrypted message can only be decrypted with the associated private key. The server will send this encrypted message to the client to test whether they actually have the associated private key.
Upon receipt of this message, the client will decrypt it using the private key and combine the random string that is revealed with a previously negotiated session ID. It then generates an MD5 hash of this value and transmits it back to the server. The server already had the original message and the session ID, so it can compare an MD5 hash generated by those values and determine that the client must have the private key.
大致的过程是:
当客户端希望通过SSH KEY 鉴权登录时,它会告诉服务端,并附带上自己的公钥KEY信息。服务端检查它的KEY文件,同时生成一个随机串,并且用公钥加密。加密过的随机串,只有客户端用自己的私钥才可以解。
一旦收到消息,客户端将用自己的私钥解密,获取到随机串,同时,将先前跟服务端商定的SESSIONID一起,再次做MD5一致性HASH(md5(randomKey,sessionId),发回给服务端。服务端也按同样的方式生成摘要,如果两者一致,则验证通过。
假设现在有两台Linux服务器 A 和 B,如何配置主机之间的免密ssh登陆?
第一步:在 A 的$HOME/.ssh/目录下,有两个文件:id_rsa.pub和id_rsa。前者是当前服务器当前用户的公钥,后者是当前服务器当前用户的私钥。如果没有,则使用如下命令生成密钥对:
`ssh-keygen -t rsa` 或者 `ssh-keygen` (默认就是ras加密算法)
运行上面的命令以后,系统会出现一系列提示,可以一路回车。
再输入下面的命令,将公钥传送到远程主机host上面:
ssh-copy-id
此后从A登录到,就不需要输密码了。
关于ssh-copy-id
命令
- 作用:可以把本地主机的公钥复制到远程主机的authorized_keys文件上,也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh/authorized_keys设置合适的权限。
- 语法:
ssh-copy-id [-i [identity_file]] [user@]machine
- 实例:
1
2ssh-copy-id server02
ssh-copy-id -i ~/.ssh/id_rsa.pub user@server
三.SCP进行跨机器拷贝
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system时,用scp可以帮你把文件移出来。另外,scp还非常不占资源,不会提高多少系统负荷,在这一点上,rsync就远远不及它了。虽然 rsync比scp会快一点,但当小文件众多的情况下,rsync会导致硬盘I/O非常高,而scp基本不影响系统正常使用。
1.命令格式:
scp [参数] [原路径] [目标路径]
2.命令功能:
scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令。linux的scp命令可以在linux服务器之间复制文件和目录。
3.使用实例:
scp命令的实际应用概述:
从本地服务器复制到远程服务器:
复制文件:
命令格式:
- scp local_file remote_username@remote_ip:remote_folder
- scp local_file remote_username@remote_ip:remote_file
- scp local_file remote_ip:remote_folder
- scp local_file remote_ip:remote_file
第1,2个指定了用户名,命令执行后需要输入用户密码,第1个仅指定了远程的目录,文件名字不变,第2个指定了文件名
第3,4个没有指定用户名,命令执行后需要输入用户名和密码,第3个仅指定了远程的目录,文件名字不变,第4个指定了文件名
复制目录:
命令格式:
- scp -r local_folder remote_username@remote_ip:remote_folder
- scp -r local_folder remote_ip:remote_folder
第1个指定了用户名,命令执行后需要输入用户密码;
第2个没有指定用户名,命令执行后需要输入用户名和密码;
注意:remote_folder是一个远程主机上已经存在的文件夹,如果不存在则报错,remote_file是本地文件复制到远程主机上的后新文件名,可以和原文件名不一样。
从远程服务器复制到本地服务器:
从远程复制到本地的scp命令与上面的命令雷同,只要将从本地复制到远程的命令后面2个参数互换顺序就行了。
例如:
scp root@server01:/home/root/data/abc.txt /home/space/data/123.txt
scp -r server01:/home/root/data/ /home/space/data/
四.SFTP
sftp是Secure File TransferProtocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的加密方法。sftp与 ftp有着几乎一样的语法和功能。SFTP为 SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。
1.连接方式
常用的方式有两种,一种直接采用sftp连接远端服务器IP,另一种则先登录远程服务器,在开启sftp功能
sftp [remotehost IP ]
通过sftp连接[host],端口为默认的22,用户为Linux当前登录用户。
sftp -oPort=[port][remotehost IP]
通过sftp连接远程服务器,指定端口[port],用户为Linux当前登录用户。
sftp[user]@[remotehost IP]
通过sftp连接远程服务器,端口为默认的22,指定用户[user]。
sftp -oPort=[port][user]@[ remotehost IP]
通过sftp连接[remotehost IP],端口为[port],用户为[user]。
通过Xshell5与linux建立连接后,在图形用户面板上可以直接打开一个图形化sftp窗口
2.基本操作命令
首先可以查询该FTP给我们提供了那些基本命令,就输入:help命令,就帮我们显示
该FTP提供所有的命令
- pwd:查询linux主机所在目录(也就是远程主机目录)
- lpwd:查询本地目录
- ls:查询连接到当前linux主机所在目录有哪些文件
- lls:查询当前本地上传目录有哪些文件
- lcd:改变本地上传目录的路径
- cd:改变远程上传目录
- get:将远程目录中文件下载到本地目录
- put:将本地目录中文件上传到远程主机(linux)
- put:后面可以接本地文件的绝对路径,也可以回车后弹出选择文件的窗口。
- quit:断开FTP连接
- rename:搬移或重命名一个的远程服务器文件
- rm:删除一个文件
- rmdir:在远程服务器上删除一个目录删除一个目录
sftp 还是 scp 来传输?如果ssh没有配置免登陆,scp会经常要输入密码比较麻烦,所以sftp更方便点。
本文参考:
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html