为什么SSH能向多个用户提供连接,而TCP、UDP连接只能对一个用户提供?
SSH如何向多个用户提供服务?
0x00 SSH协议的组成
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 连接。
0x01 结论
由此可见每一个被连接的用户都是通过22端口进行转发的,而不是直接与22端口进行通信。那么与用户通信的是哪个进程?
用户登录linux的本质是开启一个shell进程,例如bash进程,且每个bash进程的ID随机分配。因此只要PID不会重复,结合连接转发技术就可以为多个用户提供服务。
而SSH本身就是一种特殊的协议,通过隧道转发和TCP连接转发来处理多个请求,当请求到来的时候SSH守护进程会产生一个子进程,该子进程进行这次的连接处理,因此看似ssh监听的22端口能够同时为多个用户同时提供服务,但其实只是通过总服务进程管理转发多个子进程。
0x02 实验验证
这里搭建一个小的实验环境,用来验证每一次用户登录都会重新创建一个bash进程。
实验环境为:
终端 | 系统 | IP | 备注 |
---|---|---|---|
虚拟机1 | kali_2018 | 192.168.40.130 | 提供SSH服务 |
虚拟机2 | Ubuntu | 192.168.40.128 | 连接SSH服务 |
物理机 | Win_10 | 192.168.40.1 | 连接SSH服务 |
首先在kali中开启ssh服务:
/etc/init.d/sshd start
使用命令ps -e | grep ssh
查看是否成功开启。
并将/etc/ssh/sshd_config
文件中的PermitRootLogin
值改为yes
后去掉注释,允许root用户通过远程访问ssh。
首先在kali中查看目前bash
的进程情况,可以看到只有当前打开的bash
和grep
两个进程,终端只有pts/1
.
ps -aux | grep bash
分别用物理机和Ubuntu连接kali 的ssh服务。
ssh root@192.168.40.130
连接后使用netstat -an | grep :22
分别查看对应的端口与连接。
可以看到此时除了一开始的6380
和6476
又多出了两个bash
,分别为6494
和6510
,两个虚拟终端分别为pts/0
和pts/2
,这里grep是新开的,因此与上一次的PID也不同。
使用who
命令查看当前连接的SSH用户,pts/0
和pts/2
就是上面我们远程开启的两个bash
进程,由此可见每一个ssh用户都占用了一个bash进程。
普通连接能否创建多个?
0x00 验证两个TCP连接
上面提到ssh是使用连接转发技术每一次都创建新的连接,而TCP是实打实的互相连接,且通过三次握手之后建立的连接两个端口之间有且仅有一条连接在活动。
我们使用上面的环境进行测试。
在kali中监听一个tcp连接nc -lp 8888
首先在Ubuntu中连接他,发送一条hell消息,此时连接建立。
在win_10中继续连接这个端口。
所以同一个监听的端口无法连接两个TCP连接。
0x01 验证两个udp连接
使用命令nc -lup 8888
监听kali上的udp端口,分别用两台电脑使用udp协议前后连接8888端口,可以发现只会接受先连接的那个终端,另一个终端发送消息也不会被接受。
nc -u 192.168.40.130
0x02 验证一个TCP连接一个UDP连接
在kali中分别监听两个协议类型的8888端口。
nc -lp 8888
nc -lup 8888
分别使用两台终端连接这两个端口。
都连接成功.
0x03 结论
端口是一个逻辑上的产物,因此一个端口无法对TCP开启两条连接。 但对每一个不同协议的连接来讲都是相互独立的,因此可以对同一个端口建立两个不同协议的连接。