SSH原理与使用
一、SSH介绍
SSH是Secure Shell Protocol的简写,用于加密两台计算机之间的通信,并且支持各种身份验证机制。SSH先对联机数据包通过加密技术进行加密处理,加密后在进行数据传输。确保了传递的数据安全。
- SSH是安全的加密协议,用于远程连接linux服务器。
- SSH默认端口是22,安全协议版本SSHv2,除了2之外还有SSHv1(有漏洞)。
- SSH服务端主要包含两个服务功能SSH远程连接和SFTP服务。
- Linux SSH客户端包含ssh远程连接命令,以及远程拷贝scp命令等。
而SSH 的软件架构是服务器-客户端模式(Server - Client)。在这个架构中,SSH 软件分成两个部分:向服务器发出请求的部分,称为客户端(client),OpenSSH 的实现为 ssh;接收客户端发出的请求的部分,称为服务器(server),OpenSSH 的实现为 sshd。
二、SSH登录
1、基本用法
SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。
1 | # user指的是你远程主机的名字,host指的是ip或者局域网的主机名 |
2、口令登录
SSH之所以能够保证安全,原因在于它采用了公钥加密。整个过程是这样的:
- 远程主机收到用户的登录请求,把自己的公钥发给用户。
- 用户使用这个公钥,将登录密码加密后,发送回来。
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。
1 | ssh user@host |
第一次登录对方主机,系统会出现一个警告提示,意思是无法确认远程主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?经过用户的考虑后接受,之后进行口令的输入,如果密码正确,就可以登录了。当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts
之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
3、公钥登录
使用密码登录,每次都必须输入密码,非常麻烦。SSH还提供了公钥登录,可以省去输入密码的步骤。
所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。
这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:
1 | #程序会询问一系列问题,然后生成密钥,默认rsa算法 |
执行ssh-keygen
命令以后,会出现第一个问题,询问密钥保存的文件名,默认是~/.ssh/id_rsa
文件,这个是私钥的文件名,对应的公钥文件~/.ssh/id_rsa.pub
是自动生成的。用户的密钥一般都放在主目录的.ssh
目录里面。生成密钥以后,公钥必须上传到服务器,才能使用公钥登录。
手动上传公钥
OpenSSH 规定,用户公钥保存在服务器的~/.ssh/authorized_keys
文件。你要以哪个用户的身份登录到服务器,密钥就必须保存在该用户主目录的~/.ssh/authorized_keys
文件。只要把公钥添加到这个文件之中,就相当于公钥上传到服务器了。每个公钥占据一行。如果该文件不存在,可以手动创建。
ssh-copy-id
命令:自动上传公钥
OpenSSH 自带一个ssh-copy-id
命令,可以自动将公钥拷贝到远程服务器的~/.ssh/authorized_keys
文件。如果~/.ssh/authorized_keys
文件不存在,ssh-copy-id
命令会自动创建该文件。
1 | #需要把工作目录切换到~/.ssh/下 |
上面命令中,-i
参数用来指定公钥文件,user
是所要登录的账户名,host
是服务器地址。如果省略用户名,默认为当前的本机用户名。执行完该命令,公钥就会拷贝到服务器。
1 | #SSH 就会自动采用密钥登录,不再提示输入密码。 |
从此ssh登录,为了安全性就不需要密码登录了,具体方法就是打开服务器 sshd 的配置文件/etc/ssh/sshd_config
,将PasswordAuthentication
这一项设为no
,最后重启sshd。
三、SSH端口转发
1、动态转发
SSH会建立一个socket,去监听本地的端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果某个本地端口原来是一个不加密端口,现在将变成一个加密端口
1 | ssh -D local-port tunnel-host [-N] |
上面命令中,-D
表示动态转发,local-port
是本地端口,tunnel-host
是 SSH 服务器,-N
表示这个 SSH 连接只进行端口转发,不登录远程 Shell,不能执行远程命令,只能充当隧道。
2、本地转发
本地转发(local forwarding)指的是,SSH 服务器作为中介的跳板机,建立本地计算机与特定目标网站之间的加密连接。
本地转发是在本地计算机的 SSH 客户端建立的转发规则。它会指定一个本地端口(local-port),所有发向那个端口的请求,都会转发到 SSH 跳板机(tunnel-host),然后 SSH 跳板机作为中介,将收到的请求发到目标服务器(target-host)的目标端口(target-port)。
1 | ssh -L local-port:target-host:target-port tunnel-host [-N] [-f] |
上面命令中,-L
参数表示本地转发,local-port
是本地端口,target-host
是你想要访问的目标服务器,target-port
是目标服务器的端口,tunnel-host
是 SSH 跳板机。-N
参数表示不在 SSH 跳板机执行远程命令,让 SSH 只充当隧道。另外还有一个-f
参数表示 SSH 连接在后台运行。
举例来说,现在有一台 SSH 跳板机root@10.16.22.123
,我们可以通过本地访问http://localhost:16006
即可访问到跳板机的127.0.0.1:6006
端口
1 | #本机运行 |
3、远程端口转发
远程端口指的是在远程 SSH 服务器建立的转发规则。
这种场景比较特殊,主要针对内网的情况。本地计算机在外网,SSH 跳板机和目标服务器都在内网,而且本地计算机无法访问内网之中的 SSH 跳板机,但是 SSH 跳板机可以访问本机计算机。由于本机无法访问内网 SSH 跳板机,就无法从外网发起 SSH 隧道,建立端口转发。必须反过来,从 SSH 跳板机发起隧道,建立端口转发,这时就形成了远程端口转发。
1 | ssh -R local-port:target-host:target-port local [-N] [-f] |
上面的命令,首先需要注意,不是在本机执行的,而是在 SSH 跳板机执行的,从跳板机去连接本地计算机。-R
参数表示远程端口转发,local-port
是本地计算机的端口,target-host
和target-port
是目标服务器(内网机器)及其端口,local
是本地计算机。
举例来说,目标服务器在内网但可以访问外网,而跳板机不能直接访问内网,这时候就需要用远程端口转发,即可以直接使用跳板机访问内网
1 | #内网机器运行,将内网服务器的22端口转发到跳板机的2222端口 |
四、SSH其他命令
1、scp命令
scp
是 SSH 提供的一个客户端程序,用来在两台主机之间加密传送文件(即复制文件)。scp
主要用于以下三种复制操作:
- 本地复制到远程。
- 远程复制到本地。
- 两个远程系统之间的复制。
1 | #上传文件 |
2、sftp 命令
sftp
是 SSH 提供的一个客户端应用程序,主要用来安全地访问 FTP。因为 FTP 是不加密协议,很不安全,sftp
就相当于将 FTP 放入了 SSH。
1 | # 连接 |
3、rsync 命令
rsync 是一个常用的 Linux 应用程序,用于文件同步。
五、其他
1、ssh登录显示系统配置信息
比如以下信息,显示登录的时间,显示当前进程数,IP,内存,硬盘等一些使用情况,还能知道上次登录的时间以及IP
1 | Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-47-generic x86_64) |
安装也很简单,执行命令即可,也可以进入landscape-common下载页手动安装
1 | sudo apt-get install landscape-common |
六、SSH连接安全
1、介绍
SSH 是一种广泛使用的协议,用于安全地访问 Linux 服务器。大多数用户使用默认设置的 SSH 连接来连接到远程服务器。但是,不安全的默认配置也会带来各种安全风险。下面介绍几种提高ssh连接安全的方法,这里使用Ubuntu
1 | # 安装ssh |
- 禁用root用户登录
- 更改默认端口
- 禁止使用空白密码的用户访问
- 限制登录/访问尝试
- 使用 SSH 版本 2
- 关闭TCP端口转发和X11转发
- 使用 SSH 密钥连接
- SSH 连接的 IP 限制
2、八种保护SSH服务方法
2.1禁用root用户登录
禁用 root 用户的 SSH 访问并创建一个具有 root 权限的新用户。关闭 root 用户的服务器访问是一种防御策略,可以防止攻击者实现入侵系统的目标
- useradd创建一个新用户,并且**-m参数在您创建的用户的主**目录下创建一个文件夹
- passwd命令用于为新用户分配密码。请记住,您分配给用户的密码应该很复杂且难以猜测
- usermod -aG sudo将新创建的用户添加到管理员组
1 | useradd -m exampleroot |
在用户创建过程之后,需要对sshd_config文件进行一些更改。可以在/etc/ssh/sshd_config找到此文件,PermitRootLogin 行将阻止 root 用户使用 SSH 获得远程访问。在AllowUsers 列表中包含 exampleroot 会向用户授予必要的权限。最后重启 SSH 服务:systemctl restart sshd.service
1 | # Authentication: |
2.2 更改默认端口
默认的 SSH 连接端口是 22。当然,所有的攻击者都知道这一点,因此需要更改默认端口号以确保 SSH 安全。尽管攻击者可以通过 Nmap 扫描轻松找到新的端口号,但这里的目标是让攻击者的工作更加困难。要更改端口号,请打开/etc/ssh/sshd_config并对文件进行以下更改:
1 | Include /etc/ssh/sshd_config.d/*.conf |
重启ssh服务,另外还需要进行必要的防火墙规则更改,这里ubuntu使用sudo ufw allow 22099
,在运行netstat -tlpn
命令时,可以发现ssh端口以及被修改
2.3 禁止使用空白密码的用户访问
在您的系统上可能有您不小心创建的没有密码的用户。要防止此类用户访问服务器,您可以将sshd_config文件中的PermitEmptyPasswords行值设置为no
1 | PermitEmptyPasswords no |
2.4 限制登录/访问尝试
默认情况下,可以根据需要尝试多次输入密码来访问服务器。但是攻击者可以利用此漏洞对服务器进行暴力破解。通过指定允许的密码尝试次数以及尝试事件,我们可以在尝试一定次数后自动终止SSH 连接。为此,请更改sshd_config文件中的MaxAuthTries值和**LoginGraceTime **值
1 | LoginGraceTime 2m |
查看状态与解锁
1 | # 查看是否被锁定 |
2.5 使用 SSH 版本 2
SSH 的第二个版本发布是因为第一个版本中存在许多漏洞。默认情况下,可以通过将Protocol参数添加到sshd_config文件来启用服务器使用第二个版本。这样未来的所有连接都将使用第二个版本的 SSH。
1 | Include /etc/ssh/sshd_config.d/*.conf |
2.6 关闭TCP端口转发和X11转发
攻击者可以尝试通过 SSH 连接的端口转发来访问您的其他系统。为了防止这种情况,可以在sshd_config文件中关闭AllowTcpForwarding和X11Forwarding功能
1 | X11Forwarding no |
2.7 使用 SSH 密钥连接
连接到服务器的最安全方法之一是使用 SSH 密钥。使用 SSH 密钥时,无需密码即可访问服务器。可以通过更改sshd_config文件中与密码相关的参数来完全关闭对服务器的密码访问
2.8 SSH 连接的 IP 限制
大多数情况下,防火墙使用自己的标准框架阻止访问,旨在保护服务器。但是,这并不总是足够的,我们需要增加这种安全潜力。为此,请打开**/etc/hosts.allow文件。通过对该文件进行的添加,您可以限制 SSH 权限,允许特定 IP 块,或输入单个 IP 并使用拒绝命令阻止所有剩余的 IP 地址;当然也可以用/etc/hosts.deny**模块限制
1 | sshd:210.13.218.*:allow |
3、总结
ssh配置文件在**/etc/ssh/sshd_config**,修改完后重启服务即可
1 | # 常见SSH服务器监听 |
参考文章:
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
https://wangdoc.com/ssh/port-forwarding.html