DevOps] 详细分析:SSH 协议工作原理、安全配置和实用技巧
目录
一、SSH的关键特性
二、SSH 原理
三、SSH 工具和命令
四、安装 SSH
Debian/Ubuntu 系统
CentOS/RHEL 系统
Fedora 系统
五、配置 SSH
六、设置密钥认证
七、防火墙设置
使用 ufw (Ubuntu/Debian)
使用 firewalld (CentOS/RHEL/Fedora)
八、总结
SSH(Secure Shell)是一种网络协议,用于在不安全的网络中提供安全的远程登录和其他安全网络服务。SSH 允许加密传输数据,防止数据在传输过程中被截取和篡改,从而提供了一个安全的远程操作方式。
一、SSH的关键特性
1、加密:SSH 使用强加密算法(如 AES、ChaCha20、Blowfish)来加密整个会话,确保数据传输的安全性和隐私。
2、认证:SSH 支持多种认证方式,包括基于密码的认证和基于公钥的认证。其中,基于公钥的认证更为安全,因为它依赖于非对称密钥对。
3、完整性保护:SSH 使用 MAC(Message Authentication Code)算法来保护数据的完整性,防止数据在传输过程中被篡改。
4、信道复用:SSH 支持在一个加密连接上同时传输多个逻辑通信通道,使得用户可以通过一个 SSH 连接实现多种数据传输任务,如命令行Shell访问、端口转发和文件传输。
5、端口转发:SSH 可以将任意的 TCP 端口通过 SSH 连接转发,分为本地端口转发、远程端口转发和动态端口转发,这提高了网络通信的安全性。
6、代理功能:SSH 可以配置为 SOCKS 代理,允许用户通过 SSH 客户端转发浏览器等应用的网络请求,从而实现安全浏览。
7、会话管理:SSH 提供了会话层管理,用户可以在不同的会话中执行命令,支持会话暂停、断点续传等操作。
二、SSH 原理
SSH 通信过程分为三个主要阶段:
1、协议协商:SSH 客户端和服务器端首先协商使用的 SSH 协议版本,然后选择加密算法、压缩算法、MAC 算法等。
2、密钥交换:通过密钥交换算法(如 Diffie-Hellman)安全地协商出一个共享密钥,用于之后的会话加密。这个阶段也包括服务器的身份验证,通常通过比较服务器的公钥指纹来完成。
3、用户认证:客户端使用选定的认证方法(密码、公钥等)向服务器证明其身份。
三、SSH 工具和命令
1、ssh:最常用的 SSH 客户端命令,用于启动一个加密的 Shell 会话到远程服务器。
ssh username@hostname
2、scp:基于 SSH 的安全文件复制工具。
scp source_file username@hostname:destination_folder
scp username@hostname:source_file destination_folder
3、sftp:安全文件传输协议,提供了一个交互式的文件传输会话。
sftp username@hostname
4、ssh-keygen:用于生成 SSH 密钥对的工具。
ssh-keygen -t rsa -b 4096
5、ssh-copy-id:用于将本地的 SSH 公钥复制到远程服务器的 ~/.ssh/authorized_keys
文件,简化公钥认证的设置。
ssh-copy-id username@hostname
6、ssh-agent 和 ssh-add:ssh-agent
是一个密钥管理器,ssh-add
是用于将私钥加入到 ssh-agent
的工具,用于管理 SSH 私钥和自动化密码输入。
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
四、安装 SSH
在 Linux 系统中,最常见的 SSH 实现是 OpenSSH。以下是在不同 Linux 发行版上安装 OpenSSH 服务端和客户端的方法:
Debian/Ubuntu 系统
1、安装 OpenSSH 服务器和客户端:
sudo apt update
sudo apt install openssh-server openssh-client
2、启动 SSH 服务:
sudo systemctl start ssh
3、设置 SSH 服务开机自启:
sudo systemctl enable ssh
4、检查 SSH 服务状态:
sudo systemctl status ssh
CentOS/RHEL 系统
1、安装 OpenSSH 服务器和客户端:
sudo yum install openssh-server openssh-clients
2、启动 SSH 服务:
sudo systemctl start sshd
3、设置 SSH 服务开机自启:
sudo systemctl enable sshd
4、检查 SSH 服务状态:
sudo systemctl status sshd
Fedora 系统
1、安装 OpenSSH 服务器和客户端:
sudo dnf install openssh-server openssh-clients
2、启动 SSH 服务:
sudo systemctl start sshd
3、设置 SSH 服务开机自启:
sudo systemctl enable sshd
4、检查 SSH 服务状态:
sudo systemctl status sshd
五、配置 SSH
SSH 的配置文件位于 /etc/ssh/sshd_config
。以下是一些常见的配置项:
1、Port: 指定 SSH 服务器监听的端口,默认为 22。
Port 22
2、PermitRootLogin: 控制是否允许 root 用户登录。推荐设置为 no
,使用普通用户登录后再切换到 root。
PermitRootLogin no
3、PasswordAuthentication: 是否允许基于密码的登录。为了安全,可以设置为 no
,使用密钥登录。
PasswordAuthentication yes
4、PubkeyAuthentication: 是否允许基于公钥的登录。
PubkeyAuthentication yes
5、AllowUsers: 指定允许远程登录的用户。
AllowUsers username
6、UsePAM: 是否使用 PAM(Pluggable Authentication Modules)。
UsePAM yes
六、设置密钥认证
1、在客户端生成密钥对:
ssh-keygen -t rsa -b 4096
2、将公钥复制到服务器:
ssh-copy-id username@server_ip
3、确保服务器的 ~/.ssh/authorized_keys
包含客户端的公钥。
-
测试密钥登录:
ssh username@server_ip
七、防火墙设置
确保防火墙允许 SSH 端口 (默认为 22) 的流量。
使用 ufw (Ubuntu/Debian)
sudo ufw allow 22/tcp
sudo ufw enable
sudo ufw status
使用 firewalld (CentOS/RHEL/Fedora)
sudo firewall-cmd --permanent --add-port=22/tcp
sudo firewall-cmd --reload
八、总结
通过上述步骤,你可以在 Linux 系统上安装和配置 SSH,使用更安全的密钥认证方式登录。这些步骤提供了基本的安全配置,但根据具体需要,你可能需要调整更多的高级配置选项。
上一篇: Linux SSH:安全远程访问和管理
下一篇: hydra
推荐阅读
-
go语言Socket编程-Socket编程 什么是Socket Socket,英文含义是插座、插孔,一般称之为套接字,用于描述IP地址和端口。可以实现不同程序间的数据通信。 Socket起源于Unix,而Unix基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现,网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用:Socket,该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。 套接字的内核实现较为复杂,不宜在学习初期深入学习,了解到如下结构足矣。 套接字通讯原理示意 在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程。“IP地址+端口号”就对应一个socket。欲建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接。因此可以用Socket来描述网络连接的一对一关系。 常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。 网络应用程序设计模式 C/S模式 传统的网络应用设计模式,客户机(client)/服务器(server)模式。需要在通讯两端各自部署客户机和服务器来完成数据通信。 B/S模式 浏览器(Browser)/服务器(Server)模式。只需在一端部署服务器,而另外一端使用每台PC都默认配置的浏览器即可完成数据的传输。 优缺点 对于C/S模式来说,其优点明显。客户端位于目标主机上可以保证性能,将数据缓存至客户端本地,从而提高数据传输效率。且,一般来说客户端和服务器程序由一个开发团队创作,所以他们之间所采用的协议相对灵活。可以在标准协议的基础上根据需求裁剪及定制。例如,腾讯所采用的通信协议,即为ftp协议的修改剪裁版。 因此,传统的网络应用程序及较大型的网络应用程序都首选C/S模式进行开发。如,知名的网络游戏魔兽世界。3D画面,数据量庞大,使用C/S模式可以提前在本地进行大量数据的缓存处理,从而提高观感。 C/S模式的缺点也较突出。由于客户端和服务器都需要有一个开发团队来完成开发。工作量将成倍提升,开发周期较长。另外,从用户角度出发,需要将客户端安插至用户主机上,对用户主机的安全性构成威胁。这也是很多用户不愿使用C/S模式应用程序的重要原因。 B/S模式相比C/S模式而言,由于它没有独立的客户端,使用标准浏览器作为客户端,其工作开发量较小。只需开发服务器端即可。另外由于其采用浏览器显示数据,因此移植性非常好,不受平台限制。如早期的偷菜游戏,在各个平台上都可以完美运行。 B/S模式的缺点也较明显。由于使用第三方浏览器,因此网络应用支持受限。另外,没有客户端放到对方主机上,缓存数据不尽如人意,从而传输数据量受到限制。应用的观感大打折扣。第三,必须与浏览器一样,采用标准http协议进行通信,协议选择不灵活。 因此在开发过程中,模式的选择由上述各自的特点决定。根据实际需求选择应用程序设计模式。 简单的C/S模型通信 Server端:Listen函数 func Listen(network, address string) (Listener, error) network:选用的协议:TCP、UDP, 如:“tcp”或 “udp” address:IP地址+端口号, 如:“127.0.0.1:8000”或 “:8000” Listener 接口: type Listener interface { Accept (Conn, error) Close error Addr Addr } Conn 接口: type Conn interface { Read(b byte) (n int, err error) Write(b byte) (n int, err error) Close error LocalAddr Addr RemoteAddr Addr SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error } 参看 [<u>https://studygolang.com/pkgdoc</u>](https://studygolang.com/pkgdoc) 中文帮助文档中的demo: 示例代码:TCP服务器.go package main import ( "net" "fmt" ) func main { // 创建监听 listener, err:= net.Listen("tcp", ":8000") if err != nil { fmt.Println("listen err:", err) return } defer listener.Close // 主协程结束时,关闭listener fmt.Println("服务器等待客户端建立连接...") // 等待客户端连接请求 conn, err := listener.Accept if err != nil { fmt.Println("accept err:", err) return } defer conn.Close // 使用结束,断开与客户端链接 fmt.Println("客户端与服务器连接建立成功...") // 接收客户端数据 buf := make(byte, 1024) // 创建1024大小的缓冲区,用于read n, err := conn.Read(buf) if err != nil { fmt.Println("read err:", err) return } fmt.Println("服务器读到:", string(buf[:n])) // 读多少,打印多少。 }
-
ssh工作流程及原理-SSH(Secure Shell Protocol,安全的壳程序协议),它可以通过数据包加密技术将等待传输的数据包加密后再传输到网络上。ssh协议本身提供两个服务器功能:一个是类似telnet的远程连接使用shell的服务器;另一个就是类似ftp服务的sftp-server,提供更安全的ftp服务。 连接加密技术简介 目前常见的网络数据包加密技术通常是通过“非对称密钥系统”来处理的。主要通过两把不一样的公钥与私钥来进行加密与解密的过程。 公钥(public key):提供给远程主机进行数据加密的行为,所有人都可获得你的公钥来将数据加密。 私钥(private key):远程主机使用你的公钥加密的数据,在本地端就能够使用私钥来进行解密。私钥只有自己拥有。 SSH工作过程:在整个通讯过程中,为实现SSH的安全连接,服务端与客户端要经历如下五个阶段: 版本号协商阶段 SSH目前包括SSH1和SSH2两个版本,双方通过版本协商确定使用的版本 密钥和算法协商阶段 SSH支持多种加密算法,双方根据本端和对端支持的算法,协商出最终使用的算法 认证阶段 SSH客户端向服务器端发起认证请求,服务器端对客户端进行认证 会话请求阶段 认证通过后,客户端向服务器端发送会话请求 交互会话阶段 会话请求通过后,服务器端和客户端进行信息的交互 一、版本协商阶段 服务器端打开端口22,等待客户端连接; 客户端向服务器端发起TCP初始连接请求,TCP连接建立后,服务器向客户端发送第一个报文,包括版本标志字符串,格式为“SSH-<主协议版本号>.<次协议版本号>.<软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要是为调试使用。 客户端收到报文后,解析该数据包,如果服务器的协议版本号比自己的低,且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使用自己的协议版本号。 客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比较客户端发来的版本号,决定是否能同客户端一起工作。如果协商成功,则进入密钥和算法协商阶段,否则服务器断开TCP连接。 说明:上述报文都是采用明文方式传输。 二、密钥和算法协商阶段 服务器端和客户端分别发送算法协商报文给对端,报文中包含自己支持的公钥算法列表、加密算法列表、MAC(Message Authentication Code,消息验证码)算法列表、压缩算法列表等等。 服务器端和客户端根据对端和本端支持的算法列表得出最终使用的算法。 服务器端和客户端利用DH交换(Diffie-Hellman Exchange)算法、主机密钥对等参数,生成会话密钥和会话ID。 由此,服务器端和客户端就取得了相同的会话密钥和会话ID。对于后续传输的数据,两端都会使用会话密钥进行加密和解密,保证了数据传送的安全。在认证阶段,两端会使用会话用于认证过程。 会话密钥的生成: 客户端需要使用适当的客户端程序来请求连接服务器,服务器将服务器的公钥发送给客户端。(服务器的公钥产生过程:服务器每次启动sshd服务时,该服务会主动去找/etc/ssh/ssh_host*文件,若系统刚装完,由于没有这些公钥文件,因此sshd会主动去计算出这些需要的公钥文件,同时也会计算出服务器自己所需要的私钥文件。) 服务器生成会话ID,并将会话ID发给客户端。 若客户端第一次连接到此服务器,则会将服务器的公钥数据记录到客户端的用户主目录内的~/.ssh/known_hosts。若是已经记录过该服务器的公钥数据,则客户端会去比对此次接收到的与之前的记录是否有差异。客户端生成会话密钥,并用服务器的公钥加密后,发送给服务器。 ****服务器用自己的私钥将收到的数据解密,获得会话密钥。 服务器和客户端都知道了会话密钥,以后的传输都将被会话密钥加密。 三、认证阶段 SSH提供两种认证方法: 基于口令的认证(password认证):客户端向服务器发出password认证请求,将用户名和密码加密后发送给服务器,服务器将该信息解密后得到用户名和密码的明文,与设备上保存的用户名和密码进行比较,并返回认证成功或失败消息。 基于密钥的认证(publickey认证):客户端产生一对公共密钥,将公钥保存到将要登录的服务器上的那个账号的家目录的.ssh/authorized_keys文件中。认证阶段:客户端首先将公钥传给服务器端。服务器端收到公钥后会与本地该账号家目录下的authorized_keys中的公钥进行对比,如果不相同,则认证失败;否则服务端生成一段随机字符串,并先后用客户端公钥和会话密钥对其加密,发送给客户端。客户端收到后将解密后的随机字符串用会话密钥发送给服务器。如果发回的字符串与服务器端之前生成的一样,则认证通过,否则,认证失败。 注:服务器端对客户端进行认证,如果认证失败,则向客户端发送认证失败消息,其中包含可以再次认证的方法列表。客户端从认证方法列表中选取一种认证方法再次进行认证,该过程反复进行。直到认证成功或者认证次数达到上限,服务器关闭连接为止。实例
-
DevOps] 详细分析:SSH 协议工作原理、安全配置和实用技巧