找回密码
 立即注册
  • QQ空间
  • 回复
  • 收藏

Linux | 安全远程连接(OpenSSH)

admin 2019-10-10 10:03 106人围观 Linux相关

一次性付费进群,长期免费索取教程,没有付费教程。

进微信群回复公众号:微信群;QQ群:460500587
 教程列表 见微信公众号底部菜单 |  本文底部有推荐书籍


微信公众号:计算机与网络安全

ID:Computer-network

当在分布式计算的世界里工作时,无法访问服务器远程资源会是一个很严重的问题。因为现在的很多工作都是虚拟机承担的,而又不能走到一台虚拟服务器旁边,按下电源按钮然后登录,需要一些其他的访问路径。欢迎来到安全Shell(Secure Shell,SSH)的世界。

1、加密的重要性

最开始时,Telnet被用于在网络上以任意速率登录连接。Telnet协议速度快且可靠,而且,在由诸多更小、更简单的网络组成的单纯世界里,完美可用。在那时,Telnet会话以不加密的方式发送数据包并不是什么大事。

现在安全性已经成为一个被热烈讨论的话题。在不安全的网络上正使用Telnet以纯文本的方式传输包含密码个人信息的私有数据,那就该假定它们不再是私有的。实际上,在网络上使用诸如Wireshark等免费可用的抓包软件,任何人都可以轻松读取到您发送和接收的任何数据。

安全软件可以使用加密密钥(encryption key),即包含随机字符序列的小文件。如图1所示,密钥可用作加密算法的一部分应用,以将纯文本的、可读的数据转换为相当于完全乱码的数据。至少在该密钥被应用于相同算法的逆应用之前,这些数据看起来是乱码的。在文件的加密版本上使用密钥将把这些乱码数据恢复为最初形式。如果只有您和信任的朋友拥有该密钥,应该就没有其他人能够获取数据的含义,即使数据被拦截。



图1  使用私钥/公钥对来加密和解密纯文本消息的内容。本图展示了一个对称加密设计

当您登录到一个远程服务器时,所做的只是让包含会话信息的数据包在两台计算机之间来回地传送。安全(secure)通信的关键是在传输每个数据包之前快速地对其加密,之后,在接收端快速地将其解密。事实上,SSH网络协议可以快速且无形地进行这一处理,从而让曾经使用Telnet会话进行连接的用户感受不到任何差异。

20世纪90年代设计的SSH是面向UNIX类操作系统的、安全加密传输远程登录数据的一个简单方式。该协议的OpenSSH实现如今非常流行,以致微软公司已在Windows中提供了该协议。

2、OpenSSH入门

如果您还没有安装该软件包,在Ubuntu或Debian主机上运行apt install openssh-server命令将为您提供所需的全部软件。但Linux发行的许多版本都至少提供了现成的最小化SSH功能。要想查看您的系统中已有什么(至少在基于Debian/Ubuntu的机器上),可以使用包管理器dpkg。

dpkg命令行工具管理和查询高级包工具(Advanced Package Tool,APT)是系统中的软件包。运行带有-s标志和软件包名字的dpkg命令会返回当前安装及更新的状态。如果该软件包已被安装(就像gedit示例中软件已安装一样),输出看起来将类似如下内容:



如图2所示,当登录到一台远程计算机,本地计算机就是该远程服务器的一个客户,因此,就要使用openssh-client软件包。然而,正在登录的远程服务器操作系统就扮演了该shell会话的主操作系统,因此服务器必须运行openssh-server软件包。



图2  通过加密的SSH连接登录到一台远程服务器

可以运行dpkg-s openssh-client或dpkg-s openssh-server来确认计算机上已经安装了正确的软件包。因为这些软件包被用来承载远程shell会话,Linux容器通常会默认地安装整套软件包。

服务器版本同样包括了可在客户端软件包中找到的所有工具。这意味着,在安装了openssh-server软件包的计算机上,操作人员也可以通过SSH登录到其他服务器。因此,即使计算机上还没有安装客户端软件包,安装服务器软件包将可以完全覆盖所需要的所有功能。

另一方面,安全性最佳实践告诉我们要将基础设施中的访问路由限制在绝对必要的范围内。如果认为不需要登录到台式机或笔记本上,那么,仅需安装openssh-client软件包即可:



仅正确地安装了软件包并不意味着该软件包是立即可用的。有时候,配置文件被默认设置为不活动的。Linux程序不能正常工作可能还有另一个共同的原因——它并没有运行。可以使用systemctl status命令来检查计算机中SSH是否正在运行:



如从输出的Active行所见,一切都很好。如果确实需要自己动手进行处理,需再次使用systemctl,但这次是用start代替status。

systemctl stop命令可以快速地将其停止:



可以使用systemctl enable ssh强制系统启动时自动加载一个进程(如SSH),或者使用systemctl disable ssh来禁止自动加载。如下代码片段启用了SSH功能:





3、使用SSH登录一台远程服务器

启动远程会话要比想象的简单一些。请确保已有第二台计算机在某个地方运行,该计算机加载了openssh-server且可以通过网络进行访问。

现在,查找计算机的IP地址。如果您正在使用LXC容器,就可以通过lxc-ls--fancy命令获取任何需要的信息。如下示例中给出了一个名为test且未运行的容器,以及一个正在运行的base容器,使用的IP地址是10.0.3.144。



或者,如果您正好登录了服务器,就可以使用ip addr命令获取服务器的公有地址,该命令会乱糟糟地输出一大堆罗列本地网络接口的字符。这些字符看上去如下形式:



本例中,接口中标号为8的inet行是我们主要关注的。其给出了IP地址10.0.3.144。

拥有这些信息后,要进行连接,将需要使用登录服务器的账号名和IP地址来执行ssh命令。如果是第一次从自己的计算机登录该服务器,将会要求输入yes来确认服务器上OpenSSH程序发回的认证信息(说明一下,是yes,而不是字母y)。最后,要输入该账号的密码(例子中是ubuntu),然后登录了服务器



使用ping命令测试两台计算机是否互相可达。假定在自己的计算机上测试到IP地址为10.0.3.144的远程服务器的连通性,成功的ping操作的结果看起来应该是这样的:



失败的结果可能如下。为了便于说明,ping了一个未被使用的IP地址:



4、免密码SSH访问

密码总是让人感到有些沮丧。它们几乎从未被正确地使用过。它们要么太短、太容易被猜出,要么就是在多个账号中被过度使用。而且,人们似乎会以惊人的速度忘记它们。如果保护数据的唯一方法是密码,那么数据极有可能并未得到很好的保护。

这就是为什么当涉及安全(如Amazon Web Service,AWS)时,最可信的行业从业人员会在默认情况下完全禁用其云实例上的密码验证。如果担心未经授权的服务器访问风险,那么可能需要考虑跟随他们的步伐。以下是在亚马逊Linux实例上,/etc/ssh/sshd_config文件中关于EC2服务的设置:



Linux中的任何其他事物一样,OpenSSH在计算机中的运行方式很大程度上取决于它的纯文本配置文件。而且,和大多数其他程序一样,我们可以在/etc目录体系中找到这些配置文件。当前情况下,配置文件存放在/etc/ssh/目录中。

配置文件/etc/ssh/sshd_config中的设置参数控制远程客户(remote client)登录到计算机的方式。另一方面,/etc/ssh/sshd_config控制本机用户作为客户登录到远程主机(remote host)的方式。除了限制用户如何通过SSH登录计算机,这些文件中的设置也可被用作控制所有类型的行为,包括是否允许远程GUI访问本地程序。

代替SSH密码授权的一个方式是创建一个特定的密钥对,之后将公共部分拷贝到远程主机,即要登录的计算机。当连接两端都有加密密钥时,在主机上运行的OpenSSH现在就可以知道是哪个用户而无须要求输入密码。这并不是说在基础设施安全中密码没有积极的作用。实际上,将很快看到是什么情况。理想情况下,应该创建一个口令(passphrase)并在使用密钥对之前在本地进行授权。

类似于密码,口令是选择的加密文本串。但口令常常会包括空格,由一系列真正的单词组成。像3Kjsi&*cn@PO这样的密码是不错的,但像“fully tired cares mound”这样的口令会更好,因为其长度更长而且更易于记忆。

(1)生成新的密钥对

当然,解决问题的方法不止一种。但是,由于所有优秀的系统管理员都是经过训练的懒人,将采用按键最少的方法。该选择的一个意外但令人愉快的结果是,将介绍管道字符(|)的更复杂的用法。

从使用ssh-keygen程序在客户计算机上创建一个新的公钥/私钥对开始。将被询问密钥对的名字,但是,除非已经得到了一个名为id_rsa的密钥对,否则将按下回车键(Enter)并使用默认值。如之前所见,在提示时创建一个口令通常会更好,特别是在将计算机与他人共享的时候。请记住,如果选择增加一个口令,那么每当使用密钥时都会提示输入口令。以下给出了所有的相关信息:



现在拥有了一个崭新的基于RSA加密的密钥对。继续前进,使用ls-l命令以长格式显示.ssh/目录中的内容。注意,这里有两个名为id_rsa的文件,但只有一个文件的扩展名为.pub。这个文件是密钥对的公钥部分,也是最终要复制到会话主机远程计算机的文件:



应该使用哪种算法

除了RSA(Ron Rivest、Adi Shamir和Leonard Adleman三位研究者率先提出该算法,故以他们姓氏的首字母缩写来命名该算法),OpenSSH还支持ECDSA和ED25519签名算法。将发现默认的RSA算法与ECDSA和ED25519算法之间的技术差异非常模糊,它们都具有基于椭圆曲线的优势。它们都被认为是相当安全的。对于ECDSA和ED25519算法,要记住的是在较早的实现中它们可能并未被完全支持。

不要再假设所有的OpenSSH实现都支持DSA。鉴于对DSA源头理论的质疑,在任何情况下都要尽可能地避免使用该算法

(2)在网络上复制公钥

在将公钥复制到宿主机之前,免密码SSH访问是不能工作的。如在图3中看到的,密钥对通常在客户计算机上创建。这是因为私钥的确应该是私有的。应该尽可能地避免对其进行不必要的移动,并且将其暴露给那些不友好的眼睛。



图3  密钥对中的公钥必须被添加到宿主计算机上,私钥则保留在客户端

一旦创建了密钥对,就可以将公钥添加到宿主计算机的.ssh/authorized_keys文件中。在宿主机上运行的OpenSSH软件将可以验证在客户主机上用私钥创建的密文消息的真实性。一旦该消息得到验证,就可以开始SSH会话了。

首先要做的是确定要登录的主机上的用户账号。在给出的示例中,使用了名为ubuntu的账号。密钥需要被复制到/home/ubuntu/下的.ssh/目录中。如果该目录不存在,可以用mkdir命令创建。

不过,首先要介绍一个很酷的快捷方式:实际上不需要在远程主机上打开一个完整的SSH会话。相反,可以将命令追加到常规的SSH语法中,形式如下所示:



将仍需要为远程主机提供密码。但只要完成了这一操作,在主机的/home/ubuntu/目录下将会有一个.ssh/目录。

为了便于阅读,用反斜杠(\)将下一条命令分割为三行,反斜杠(\)会让Bash知道下一行是当前行命令的一部分。请确定在反斜杠后没有其他字符(包括空格)。这肯定会让人感到有些不舒服:



这个多行的命令将用cat读取文件id_rsa.pub中的所有内容并将其存储在内存中。之后,该命令通过登录到远程宿主计算机的SSH会话以管道方式传输文本。最后,在宿主计算机上再一次读取该文本,并将其添加到authorized_keys文件中。如果该文件不存在,>>(追加工具)会创建该文件。如果该文件已经存在,就将文本追加到该文件的末尾。

现在,当运行相同的老版本ssh命令时,不需要输入密码



(3)使用多个加密密钥

在某些情形下(如必须登录到亚马逊EC2服务上的一个虚拟主机实例),需要为给定的会话指定一个密钥对。当开始为不同的宿主机构建一个密钥集合时,这种情况肯定会发生。为了让OpenSSH知道所用的密钥,可以为命令添加-i标志,其后是关于私钥文件的名称与位置的参数:



是否注意到了本例中的.pem文件扩展?这意味着该密钥被保存为一个所有类型虚拟机共用的格式,包括亚马逊EC2实例。



5、使用SCP安全地拷贝文件

在文件系统中cp命令可以将文件和目录从一个位置拷贝到另一个位置。可以在cp命令前加上s标志以保证安全(secure)。为了传输文件,SCP程序使用SSH协议在任何位置拷贝任意类型的文件,并采用相同的密钥、密码和口令。假设在之前工作的远程宿主机上已经存在一个.ssh/目录,这里给出如何将公钥(id_rsa.pub)传输到远程宿主机并将其重命名为authorized_keys的示例:



如果在该目录下已经存在authorized_keys文件,这个操作将重写该文件,任何已有的内容都会被破坏。仅在使用的用户账号具有某些权限时,才能拷贝和保存文件。因此,如果用户没有获得根权限,请不要尝试将文件保存到远程主机的/etc/目录。以根用户登录SSH会话通常是一个安全大忌。

可以将远程文件拷贝到本地主机。下面的例子将一个文件从AWS EC2实例(由一个假的IP地址表示)拷贝到指定的本地目录:



还有第三种(官方的)方式将密钥拷贝到远程宿主机——名为ssh-copy-id的专用程序:



SSH会话的优点是不存在GUI层处理的拖累,其非常快速和高效。但如果要让远程宿主计算机上运行的程序具有图形属性,可能就会出现问题。下面将解决这个问题。

6、使用SSH连接上的远程图形程序

假设您正在尝试对一个远程位置的用户提供支持,该用户报告某款桌面软件(如LibreOffice)出错。如果认为启动和运行该程序有助于诊断和解决这个问题,那么,就可以使用SSH上的图形会话(使用Linux X Window管理器)来完成操作。

以-X标志运行ssh命令,即使采用了所谓的X11 Forwarding,将允许把基于宿主机的程序加载到客户计算机的桌面上。得到的结果可能不会满足期望,因为这取决于包括网络连接质量在内的多种因素。对于诸如LibreOffice这样的重资源程序来说尤其如此。然而,它通常是值得一试的。即使带宽稍低,但也比开两小时的车前往客户的办公室要好。

请不要在服务器上尝试。在大多数情况下,安装在服务器或虚拟机(如LXC或Docker容器)中的操作系统版本只有简单的图形功能或者没有。如果必须这样做,可以安装桌面包来升级操作系统。在Ubuntu设备上,操作类似于以下步骤:



首先,打开宿主机(要运行该程序的计算机)上的sshd_config。需要确保X11 Forwarding行的值为yes(但是,出于安全考虑,请不要将该值保持超过所需要的时间):



在客户机的ssh_config文件中也有类似的行,也需要正确地进行设置:



由于已经编辑了该配置文件,之后需要在两台计算机上重启SSH,以确保所做的配置生效:



现在,已经准备就绪。要想启动一个图形化使能的会话,请为ssh命令增加-X标志:



将看到常规的命令提示符,但是现在可以运行一个将启动图形程序的命令。尝试一些小的操作。以下命令应该会在一个Ubuntu系统上工作:



在本地桌面窗口中成功地运行了一个远程程序。

OpenSSH带来的价值远远超过了看到的核心特性。一旦获得了可以工作的SSH连接,就可以使用各种技巧了。尝试将一个本地文件系统或目录挂载到一个远程主机上,从而允许远程用户无缝地访问文件。或者,通过SSH的隧道功能,使用端口转发允许安全、私密地使用远程HTTP服务。

7、Linux进程管理

现在讨论Linux进程管理,以使您能够正确地理解OpenSSH等程序是如何被处理的。从长远看,了解工作机制可以让一般的管理和故障排查更加高效。

到底什么是systemctl,它到底在做什么?为了正确地回答这些问题,通常必须考虑 邀请

鲜花

握手

雷人

路过

鸡蛋

yafeilinux和他的朋友们微信公众号二维码

微信公众号

专注于Qt嵌入式Linux开发等。扫一扫立即关注。

Qt开源社区官方QQ群二维码

QQ交流群

欢迎加入QQ群大家庭,一起讨论学习!

我有话说......