一、OpenSSH介绍
OpenSSH是SSH(Secure SHell)协议的免费开源实现。SSH协议族可以用来进行远程控制, 或在计算机之间传送文件。而实现此功能的传统方式,如:ftp、pop和telnet在本质上都是不安全的,因为它们在网络上用明文传送口令和数据,别有用心的人非常容易就可以截获这些口令和数据。而且,这些服务程序的安全验证方式也是有其弱点的, 就是很容易受到“中间人”(man-in-the-middle)这种方式的攻击。OpenSSH提供了服务端后台程序和客户端工具,用来加密远程控件和文件传输过程中的数据,并由此来代替原来的类似服务。
二、SSH协议介绍
SSH(secure shell)属于应用程协议,工作在TCP的22号端口上,其保证了通信过程是加密的。目前版本有两版SSH v1和SSH v2,其中SSH v1已经被破解。SSH为建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。
SSH协议为什么比其他传输协议更安全呢?原因是 SSH透过计算机网络加密通讯的实现。也就是SSH使用了前面我们讲过的非对称密钥机制才得以保证其传输安全性。使用过SSH的都知道,当你第一次使用ssh 登录远程主机时,你会看到和下面相仿的消息:
1 2 3 4 5 |
The authenticity of host '58.83.167.2 (58.83.167.2)' can't be established. RSA key fingerprint is 56:6a:57:21:cd:84:7d:c7:e6:e6:5e:5c:8a:86:1e:0f. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '58.83.167.2' (RSA) to the list of known hosts. root@58.83.167.2's password: |
这是在干吗呢?这就是SSH为什么是安全传输的协议,当你第一次连接远程主机时,远程主机会给你发来自己的公钥指纹信息,所谓“公钥指纹“,是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是94:68:3a:3a:bc:f3:9a:9b:01:5d:b3:07:38:e2:11:0c,再进行比较,就容易多了。当接收到“公钥指纹”后,就会询问你是否还要继续连接,假定经过风险衡量以后,用户决定接受这个远程主机的公钥。然后会对公钥进行“公钥指纹计算”并跟接收到的“公钥指纹作对比”看看此公钥是否正确。这个中间会停顿一会,如果公钥正确就会把公钥信息及远程主机的IP地址追加保存在/root/.ssh/known_hosts文件中,并出现密码输入行,之后就会使用此公钥建立安全密码传输,并且下次用户在登录时会先检查此文件然后再连接。整个过程是这样的:
1)远程主机收到用户的登录请求,把自己的公钥发给用户。
2)用户使用这个公钥,将登录密码加密后,发送回来。
3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像HTTPS协议有一个CA中心来担保公钥的可靠性,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的“中间人攻击“。
SSH主要由三部分组成:
1)传输层协议 [SSH-TRANS]
提供了服务器认证,保密性及完整性。此外它有时还提供压缩功能。 SSH-TRANS 通常运行在TCP/IP连接上,也可能用于其它可靠数据流上。 SSH-TRANS 提供了强力的加密技术、密码主机认证及完整性保护。该协议中的认证基于主机,并且该协议不执行用户认证。更高层的用户认证协议可以设计为在此协议之上。
2)用户认证协议 [SSH-USERAUTH]
用于向服务器提供客户端用户鉴别功能。它运行在传输层协议 SSH-TRANS 上面。当SSH-USERAUTH 开始后,它从低层协议那里接收会话标识符(从第一次密钥交换中的交换哈希H )。会话标识符唯一标识此会话并且适用于标记以证明私钥的所有权。 SSH-USERAUTH 也需要知道低层协议是否提供保密性保护。
3)连接协议 [SSH-CONNECT]
将多个加密隧道分成逻辑通道。它运行在用户认证协议上。它提供了交互式登录话路、远程命令执行、转发 TCP/IP 连接和转发 X11 连接。
三、SSH认证模式
从客户端来看,SSH提供两种级别的安全验证。
第一种级别(基于口令的安全验证)
只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。
第二种级别(基于密匙的安全验证)
需要依靠密匙,也就是你必须为自己创建一对密匙,并把公用密匙放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致,服务器就用公用密匙加密“质询”并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私人密匙解密,再把它发送给服务器。用这种方式,你必须知道自己密匙的口令。但是,与第一种级别相比,第二种级别不需要在网络上传送口令。第二种级别不仅加密所有传送的数据,而且“中间人”这种攻击方式也是不可能的(因为他没有你的私人密匙)。但是整个登录的过程可能需要10秒。
四、配置OpenSSH服务
SSH只是协议规范,要想真正的实现安全连接,还需要服务器端和客户端。在Linux系统上OpenSSH提供了服务端后台程序和客户端工具,默认发行版系统都会安装OpenSSH服务。其服务器端为SSHD(SSHD默认配置文件在/etc/ssh/sshd_config),客户端为SSH(SSH配置文件在/etc/ssh/ssh_config)。不仅如此OpenSSH还提供了一些其它客户端,如:
“ssh-keygen”命令,是非对称秘钥生成器。
“ssh-copy-id”命令,可以将公钥传输至远程服务器用户的家目录下的特定位置。
“scp”命令,跨主机安全复制工具。
五、OpenSSH提供RPM包
1 2 3 4 5 6 7 8 9 10 |
$ rpm -qa | grep openssh # 服务器端; openssh-server-5.3p1-94.el6.x86_64 # 客户端; openssh-clients-5.3p1-94.el6.x86_64 # 通用组件库; openssh-5.3p1-94.el6.x86_64 # 建立会话时使用; openssh-askpass-5.3p1-94.el6.x86_64 # 重启sshd服务; |
六、OpenSSH配置文件
1 |
$ cat /etc/ssh/sshd_config |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# 监听端口22; Port 22 # 使用ssh v2协议; Protocol 2 # 监听地址为本地; ListenAddress 192.168.10.1 # 禁止dns反向解析,默认为yes; UseDNS no # 禁止root用户登录; PermitRootLogin no # 禁止空密码用户登录; PermitEmptyPasswords no # 登录验证时间为2分钟; LoginGraceTime 2m # 最大重复次数为6; MaxAuthTries 6 # 仅允许登录用户; AllowUsers jerry admin@172.16.16.1 # 仅拒绝登录用户; DenyUsers eric # 启用密码验证; PasswordAuthentication yes; # 启用秘钥对验证; PubkeyAuthentication yes # 是否允许使用基于GSSAPI的用户认证; GSSAPIAuthentication yes # 当有人使用SSH登入系统的时候,SSH会记录资讯; SyslogFacility AUTHPRIV # 记录登录系统日志等级; LogLevel INFO # 指定公钥库数据文件(./ssh指所户); AuthorizedKeysFile ./ssh/authorized_keys # 开启PAM认证; UsePAM yes # 给用户打印ssh登录信息; banner /some/path # 启动sftp服务器; Subsystem sftp /usr/libexec/openssh/sftp-server |
通过关闭UseDNS和GSSAPIAuthentication选项加速SSH登录。
通常情况下我们在连接OpenSSH服务器的时候假如UseDNS选项是打开的话,服务器会先根据客户端的IP地址进行DNS PTR反向查询出客户端的主机名,然后根据查询出的客户端主机名进行DNS正向A记录查询,并验证是否与原始 IP地址一致,通过此种措施来防止客户端欺骗。平时我们都是动态IP不会有PTR记录,所以打开此选项也没有太多作用。并且如果你设置了DNS并且无法连接,那么此时SSH连接会非常慢,直到超时。我们可以通过关闭此功能来提高连接OpenSSH服务器的速度。
另一个导致ssh登录慢的原因,仍然是因为DNS解析的问题。系统默认情况下sshd_config的配置里,GSSAPIAuthentication选项是no ,系统自动升级变成了yes,并且在ssh_config里也添加了此选项,于是登录过程中便多了GSSAPIAuthentication的尝试。
七、OpenSSH客户端使用介绍
连接客户端 (SSH)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 登录远程主机,默认以当前系统用户和22号端口; $ ssh 172.16.10.1 # 指定登录远程主机的用户名; $ ssh root@172.16.10.1 # 执行远程主机命令; $ ssh root@172.16.10.1 'ifconfig' # 指定登录远程主机的用户名和端口号; $ ssh root@172.16.10.1 -p 22 # 指定本地私钥文件; $ ssh -i /root/.ssh/id_rsa root@172.16.10.1 -p 22 |
复制客户端(SCP)
1 2 3 4 5 6 7 8 9 10 |
# 复制远程文件到本地; $ scp root@172.16.10.1:/path/to/somefile /local # 复制本地文件到远程; $ scp /local/file root@172.16.10.1:/path/to/dir/ # 复制本地目录到远程; $ scp -r /loca/dir root@172.16.10.1:/path/to/dir/ -p #保持目录权限; -i /root/.ssh/id_rsa #指定本地私钥文件; |
秘钥生成器(SSH-KEYGEN)
1 2 3 4 5 6 |
$ ssh-keygen -b 2048 -t rsa Enter file in which to save the key(/home/jerry/.ssh/id_rsa) Created directory /home/jerry/.ssh #默认秘钥目录; Enter passphrase (empty for no passphrase): #可设置私钥短语; ~/.ssh/id_rsa #生成的私钥; ~/.ssh/id_rsa.pub #生成的公钥; |
-b:指定密钥长度。
-t:指定公钥算法rsa最常用。
八、SSH基于秘钥登录远程主机
一、本地产生密钥对
1 |
$ ssh-keygen -b 2048 -t rsa |
二、本地上传公钥到远程主机
1 |
$ scp /root/.ssh/id_rsa.pub root@172.16.10.1:/root/ |
三、查看远程主机是否允许密钥登录
1 2 3 4 5 6 7 |
# 登录到远程主机,需要用户密码; $ ssh root@172.16.10.1 # 默认已启用秘钥对验证,指定公钥库数据文件; $ cat /etc/ssh/sshd_conf PubkeyAuthentication yes AuthorizedKeysFile ./ssh/authorized_keys |
四、配置远程主机SSH
1 2 3 4 5 6 7 8 9 10 11 |
# 在目标主机上创建.ssh目录,这里都是以root用户为准的; $ mkdir /root/.ssh # 此目录权限必须是700; $ chmod 700 /root/.ssh # 把公钥信息追加到authorized_keys文件,authorized_keys文件最好不要改名,如果想改文件名就需要同时把配置文件中的文件名也修改; $ cat /root/id_rsa.pub >> /root/.ssh/authorized_keys # 文件权限600; $ chmod 600 /root/.ssh/authorized_keys |
五、本地验证密钥登录
1 |
$ ssh root@172.16.10.1 |
也可以使用ssh-copy-id命令复制公钥文件,此命令复制时会自动把公钥追加到远程主机的~/.ssh/authorized.keys文件中,就减少了很多操作,命令操作方式如下:
1 |
$ ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.10.1 |
PS:这里需要说明一下,以上操作双方主机都是使用root用户进行连接的,而在实际操作中,一般都是使用普通用户进行无密码传输文件。所以要注意,如果本地主机使用redis用户连接远程主机的hadoop用户,那么就需要在本地的私钥文件需要放在redis用户家目录下的.ssh目录中;而公钥文件就需要传到远程主机hadoop用户的家目录下.ssh目录下的authorized.keys文件中。
九、SFTP服务
FTP(文件传输协议)是一种使用非常广泛的在网络中传输文件的方式,但是,它也同样存在被网络窃听的危险,因为它也是以明文传送用户认证信息。其实在SSH软件包中,已经包含了一个叫作SFTP(Secure FTP)的安全文件传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多。如果您对网络安全性要求更高时,可以使用SFTP代替FTP,由于自己确实用到过SFTP,SFTP灵活性配置起来要比FTP麻烦很多,特别在用户权限控制方面,个人感觉不是特别好。
简单那的sftp使用配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ setenforce 0 $ useradd -s /bin/false test $ chown root.root /home/test $ chmod 755 /home/test $ cat /etc/ssh/sshd_config # 注释这条语句; #Subsystem sftp /usr/libexec/openssh/sftp-server subsystem sftp internal-sftp Match user test #Match group test ChrootDirectory /home/test #ChrootDirectory /home/%u X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp $ service sshd restart |
OpenSSH服务器默认开启了SFTP服务端和客户端,所以可以直接连接使用,命令如下:
1 |
$ sftp USERNAME@IP |
SFTP基本操作指令:
help:帮助。
put:上传文件。
get:下载文件。
ls:列出文件。
pwd:显示当前路径。
exit:退出。