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,只要一条简单命令就可以了。
# user指的是你远程主机的名字,host指的是ip或者局域网的主机名
ssh user@host
# 如果本地用户名与远程用户名一致,登录时可以省略用户名。
ssh host
#SSH的默认端口是22,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口,注意端口开放。
ssh -p 2222 user@hostSSH
2、口令登录
SSH之所以能够保证安全,原因在于它采用了公钥加密。整个过程是这样的:
- 远程主机收到用户的登录请求,把自己的公钥发给用户。
- 用户使用这个公钥,将登录密码加密后,发送回来。
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
这个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。
ssh user@host
第一次登录对方主机,系统会出现一个警告提示,意思是无法确认远程主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?经过用户的考虑后接受,之后进行口令的输入,如果密码正确,就可以登录了。当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts
之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
3、公钥登录
使用密码登录,每次都必须输入密码,非常麻烦。SSH还提供了公钥登录,可以省去输入密码的步骤。
所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。
这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个:
#程序会询问一系列问题,然后生成密钥,默认rsa算法
ssh-keygen
#通常做法是使用-t参数,指定密钥的加密算法
ssh-keygen -t dsa
执行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
命令会自动创建该文件。
#需要把工作目录切换到~/.ssh/下
ssh-copy-id -i id_rsa user@host
上面命令中,-i
参数用来指定公钥文件,user
是所要登录的账户名,host
是服务器地址。如果省略用户名,默认为当前的本机用户名。执行完该命令,公钥就会拷贝到服务器。
#SSH 就会自动采用密钥登录,不再提示输入密码。
ssh user@host
从此ssh登录,为了安全性就不需要密码登录了,具体方法就是打开服务器 sshd 的配置文件/etc/ssh/sshd_config
,将PasswordAuthentication
这一项设为no
,最后重启sshd。
三、SSH端口转发
1、动态转发
SSH会建立一个socket,去监听本地的端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果某个本地端口原来是一个不加密端口,现在将变成一个加密端口
ssh -D local-port tunnel-host [-N]
#举例
ssh -D 8080 user@host
上面命令中,-D
表示动态转发,local-port
是本地端口,tunnel-host
是 SSH 服务器,-N
表示这个 SSH 连接只进行端口转发,不登录远程 Shell,不能执行远程命令,只能充当隧道。
2、本地转发
本地转发(local forwarding)指的是,SSH 服务器作为中介的跳板机,建立本地计算机与特定目标网站之间的加密连接。
本地转发是在本地计算机的 SSH 客户端建立的转发规则。它会指定一个本地端口(local-port),所有发向那个端口的请求,都会转发到 SSH 跳板机(tunnel-host),然后 SSH 跳板机作为中介,将收到的请求发到目标服务器(target-host)的目标端口(target-port)。
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
端口
#本机运行
ssh -L 16006:127.0.0.1:6006 root@10.16.22.123
3、远程端口转发
远程端口指的是在远程 SSH 服务器建立的转发规则。
这种场景比较特殊,主要针对内网的情况。本地计算机在外网,SSH 跳板机和目标服务器都在内网,而且本地计算机无法访问内网之中的 SSH 跳板机,但是 SSH 跳板机可以访问本机计算机。由于本机无法访问内网 SSH 跳板机,就无法从外网发起 SSH 隧道,建立端口转发。必须反过来,从 SSH 跳板机发起隧道,建立端口转发,这时就形成了远程端口转发。
ssh -R local-port:target-host:target-port local [-N] [-f]
上面的命令,首先需要注意,不是在本机执行的,而是在 SSH 跳板机执行的,从跳板机去连接本地计算机。-R
参数表示远程端口转发,local-port
是本地计算机的端口,target-host
和target-port
是目标服务器(内网机器)及其端口,local
是本地计算机。
举例来说,目标服务器在内网但可以访问外网,而跳板机不能直接访问内网,这时候就需要用远程端口转发,即可以直接使用跳板机访问内网
#内网机器运行,将内网服务器的22端口转发到跳板机的2222端口
ssh -R 2222:localhost:22 root@114.215.200.71 -N -f
#在跳板机进行登录,即可访问内网目标服务器,注意端口开放,以及用户名的修改,localhost不变,其中若因为网络问题断线,可以下载autossh
ssh shawn@localhost -p 2222
四、SSH其他命令
1、scp命令
scp
是 SSH 提供的一个客户端程序,用来在两台主机之间加密传送文件(即复制文件)。scp
主要用于以下三种复制操作:
- 本地复制到远程。
- 远程复制到本地。
- 两个远程系统之间的复制。
#上传文件
scp source destination
#上传design.tar.gz到服务器/shawn目录下,也可以反过来
scp design.tar.gz root@114.215.200.70:/shawn
#上传目录
scp -r 目录 用户名@ip:服务器绝对路径目录
2、sftp 命令
sftp
是 SSH 提供的一个客户端应用程序,主要用来安全地访问 FTP。因为 FTP 是不加密协议,很不安全,sftp
就相当于将 FTP 放入了 SSH。
# 连接
sftp username@hostname
# 本地文件传输到远程主机。
put localfile
# 远程文件传输到本地。
get remotefile
3、rsync 命令
rsync 是一个常用的 Linux 应用程序,用于文件同步。
五、其他
1、ssh登录显示系统配置信息
比如以下信息,显示登录的时间,显示当前进程数,IP,内存,硬盘等一些使用情况,还能知道上次登录的时间以及IP
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-47-generic x86_64)
- Documentation: [https://help.ubuntu.com](https://help.ubuntu.com)
- Management: [https://landscape.canonical.com](https://landscape.canonical.com)
- Support: [https://ubuntu.com/advantage](https://ubuntu.com/advantage)
System information as of Wed 11 May 2022 10:12:28 AM CST
System load: 0.29
Usage of /: 32.2% of 78.62GB
Memory usage: 33%
Swap usage: 0%
Processes: 148
Users logged in: 0
IPv4 address for br-2aa214d6db7a: 172.27.0.1
IPv4 address for br-3801d35d4bc6: 172.18.0.1
IPv4 address for br-90313e36abad: 172.24.0.1
IPv4 address for docker0: 172.17.0.1
IPv4 address for eth0: 172.26.4.1
Welcome to Alibaba Cloud Elastic Compute Service !
Last login: Wed May 11 10:09:36 2022 from 221.13.170.101
安装也很简单,执行命令即可,也可以进入landscape-common下载页手动安装
sudo apt-get install landscape-common
六、SSH连接安全
1、介绍
SSH 是一种广泛使用的协议,用于安全地访问 Linux 服务器。大多数用户使用默认设置的 SSH 连接来连接到远程服务器。但是,不安全的默认配置也会带来各种安全风险。下面介绍几种提高ssh连接安全的方法,这里使用Ubuntu
# 安装ssh
sudo apt install openssh-server
- 禁用root用户登录
- 更改默认端口
- 禁止使用空白密码的用户访问
- 限制登录/访问尝试
- 使用 SSH 版本 2
- 关闭TCP端口转发和X11转发
- 使用 SSH 密钥连接
- SSH 连接的 IP 限制
2、八种保护SSH服务方法
2.1禁用root用户登录
禁用 root 用户的 SSH 访问并创建一个具有 root 权限的新用户。关闭 root 用户的服务器访问是一种防御策略,可以防止攻击者实现入侵系统的目标
- useradd创建一个新用户,并且**-m参数在您创建的用户的主**目录下创建一个文件夹
- passwd命令用于为新用户分配密码。请记住,您分配给用户的密码应该很复杂且难以猜测
- usermod -aG sudo将新创建的用户添加到管理员组
useradd -m exampleroot
passwd exampleroot
usermod -aG sudo exampleroot
在用户创建过程之后,需要对sshd_config文件进行一些更改。可以在/etc/ssh/sshd_config找到此文件,PermitRootLogin 行将阻止 root 用户使用 SSH 获得远程访问。在AllowUsers 列表中包含 exampleroot 会向用户授予必要的权限。最后重启 SSH 服务:systemctl restart sshd.service
# Authentication:
# LoginGraceTime 2m
PermitRootLogin no
AllowUsers exampleroot
2.2 更改默认端口
默认的 SSH 连接端口是 22。当然,所有的攻击者都知道这一点,因此需要更改默认端口号以确保 SSH 安全。尽管攻击者可以通过 Nmap 扫描轻松找到新的端口号,但这里的目标是让攻击者的工作更加困难。要更改端口号,请打开/etc/ssh/sshd_config并对文件进行以下更改:
Include /etc/ssh/sshd_config.d/*.conf
Port 22099
重启ssh服务,另外还需要进行必要的防火墙规则更改,这里ubuntu使用sudo ufw allow 22099
,在运行netstat -tlpn
命令时,可以发现ssh端口以及被修改
2.3 禁止使用空白密码的用户访问
在您的系统上可能有您不小心创建的没有密码的用户。要防止此类用户访问服务器,您可以将sshd_config文件中的PermitEmptyPasswords行值设置为no
PermitEmptyPasswords no
2.4 限制登录/访问尝试
默认情况下,可以根据需要尝试多次输入密码来访问服务器。但是攻击者可以利用此漏洞对服务器进行暴力破解。通过指定允许的密码尝试次数以及尝试事件,我们可以在尝试一定次数后自动终止SSH 连接。为此,请更改sshd_config文件中的MaxAuthTries值和**LoginGraceTime **值
LoginGraceTime 2m
MaxAuthTries 5
查看状态与解锁
# 查看是否被锁定
sudo pam_tally2 --user=root
sudo pam_tally2 --user root
# 解锁
sudo pam_tally2 -u root -r --reset
2.5 使用 SSH 版本 2
SSH 的第二个版本发布是因为第一个版本中存在许多漏洞。默认情况下,可以通过将Protocol参数添加到sshd_config文件来启用服务器使用第二个版本。这样未来的所有连接都将使用第二个版本的 SSH。
Include /etc/ssh/sshd_config.d/*.conf
Protocol 2
2.6 关闭TCP端口转发和X11转发
攻击者可以尝试通过 SSH 连接的端口转发来访问您的其他系统。为了防止这种情况,可以在sshd_config文件中关闭AllowTcpForwarding和X11Forwarding功能
X11Forwarding no
AllowTcpForwarding no
2.7 使用 SSH 密钥连接
连接到服务器的最安全方法之一是使用 SSH 密钥。使用 SSH 密钥时,无需密码即可访问服务器。可以通过更改sshd_config文件中与密码相关的参数来完全关闭对服务器的密码访问
2.8 SSH 连接的 IP 限制
大多数情况下,防火墙使用自己的标准框架阻止访问,旨在保护服务器。但是,这并不总是足够的,我们需要增加这种安全潜力。为此,请打开**/etc/hosts.allow文件。通过对该文件进行的添加,您可以限制 SSH 权限,允许特定 IP 块,或输入单个 IP 并使用拒绝命令阻止所有剩余的 IP 地址;当然也可以用/etc/hosts.deny**模块限制
sshd:210.13.218.*:allow
sshd:192.168.1.0/24:ALLOW
3、总结
ssh配置文件在**/etc/ssh/sshd_config**,修改完后重启服务即可
# 常见SSH服务器监听
Port 22 #监听的端口为22
Protocol 2 #使用SSH V2协议
ListenAdderss 0.0.0.0 #监听的地址为所有地址
UseDNS no #禁止DNS反向解析
#常见用户登录控制
PermitRootLogin no #禁止root用户登录
PermitEmptyPasswords no #禁止空密码用户登录
LoginGraceTime 2m #登录验证时间为2分钟=
MaxAuthTries 6 #最大重试次数为6
AllowUsers user #只允许user用户登录,与DenyUsers选项相反
#常见登录验证方式
PasswordAuthentication yes #启用密码验证
PubkeyAuthentication yes #启用秘钥验证
AuthorsizedKeysFile .ssh/authorized_keys #指定公钥数据库文件
参考文章:
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html
https://wangdoc.com/ssh/port-forwarding.html