kaixin
Published on 2023-07-23 / 52 Visits
0

SSH服务

SSH协议

是什么:

  • 是一种网络协议,用于加密方式远程登录服务器,在服务器之间安全的传输数据。
  • SSH 或 Secure Shell 协议是一种远程管理协议,允许用户通过 Internet 访问、控制和修改其远程服务器。
  • SSH 服务是作为未加密 Telnet 的安全替代品而创建的,它使用加密技术来确保进出远程服务器的所有通信都以加密方式进行。
  • 它提供了一种用于验证远程用户、将输入从客户端传输到主机以及将输出转发回客户端的机制。
  • 最早的时候,互联网通信都是明文通信,一旦被截获,内容就暴露无疑。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的标准配置,通过openssh加密算法进行对用户加密从操作。

有什么作用:

  1. 加密通信,通过加密保护数据传输过程中的安全性,防止被窃取篡改。
  2. 身份登录验证,通过密钥,密码,公钥增加了安全性。
  3. 远程登录,用户可以通过ssh协议远程登录,这样就不需要接触物理服务器。
  4. 端口转发,可以设置端口转发,将本地端口的数据转发到远程服务器的特定端口,实现安全的数据传输。
  5. 隧道服务,可以创建隧道,将网络流量通过加密的ssh链接传输保护数据的安全。
  6. 文件传输,与sftp,scp,ssh也可以进行安全创数文件。
  7. 命令执行,可以在本地通过ssh进行远程执行命令。
  8. 安全性,对比传统的非对称加密telnet,安全性高。
  9. 兼容性好,可以在linux,windows,unix使用。
  10. 自动化脚本,可以通过ssh实现自动化脚本和任务。

为什么使用:

  1. 使用ssh协议登录到远程服务器,由于登录时ssh时采用非对称加密形式的,密码不是明文,并且登录后本地与服务器传输数据也是使用对称加密,数据也是加密的。
  2. 前使用FTP或telnet登录服务器,都是以明文的形式在网络中发送账号密码,很容易被黑客截取到数据,篡改后威胁服务器数据安全。

1.客户端

MobaXterm
Xshell
Termius
PuTTY
Terminal
Finalshell
linux提供的ssh命令
等等

2.链接方式

1. 去机房,拿上键盘、显示器直接连接
2. 使用telnet命令连接(明文数据,密码未加密)
3. 使用ssh安全可靠的远程登录(密码被加密)

Telnet登录

由于telnet登录不提供任何加密方式,属于不安全登录的方式容易被黑客或者不法分子截取服务器或者其他的密码信息,这样容易导致数据泄露等安全问题。telnet是早期的登录方式,登录的密码账户都是明文显示的,已经被禁用。

默认端口:23

1.开启windows的telnet

在控制面版中搜索"功能",选中telnet,在cmd输入 telent 测试。

image-20241125164148671


2.在linux启动telnet服务端

1.修改配置
    修改pam的auth认证。/etc/pam.d/remote,允许root用户登录,不注释只能使用普通的用户登录telnet
    auth       required     pam_securetty.so # 添加 # 号注释

2.安装软件
    yum install telnet-server telnet -y

3.启动服务
    systemctl start telnet

4.在window中进行登录
    telnet 服务器地址

image-20241125170358583


3.关于安装telnet的坑

在安装后启动会出现:
    [root@shell xinetd.d]# systemctl status telnet-server
    Unit telnet-server.service could not be found.

解决方式:
    1.安装 xinetd
        yum install xinetd -y
    
    2.在/etc/xinetd.d/添加一个文件
        vim /etc/xinetd.d/telnet
        # 添加内容如下
        service telnet

        {

        disable=yes

        socket_type=stream

        wait=no

        user=root

        server=/usr/sbin/in.telnetd #telnet的启动位置

        nice=10

        }
        
     3.重启xinetd,启动telnet.socket
         systemctl restart xinetd
         systemctl restart telnet.socket

4.使用Wireshark抓取telnet登录

image-20241126231741658


5.使用Wireshark抓取ssht登录

image-20241126233316560


SSH服务

ssh采用了对称加密与非对称加密的方式:
    对称加密:登录后数据之间交互采用的。
    非对称加密:登录时使用的。

数据加密标准(英语:Data Encryption Standard,缩写为 DES)是一种对称密钥加密块密码算法:
    https://zh.wikipedia.org/wiki/%E8%B3%87%E6%96%99%E5%8A%A0%E5%AF%86%E6%A8%99%E6%BA%96

对称加密:
    https://baike.baidu.com/item/%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/211953

非对称加密(公钥加密):
    https://zh.wikipedia.org/wiki/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86

ssh服务官方网址:
    https://www.openssh.com/

1.对称加密

简单理解:

  • A端与B端有一个秘钥(只有它俩知道),A端传输数据到B端,通过这个秘钥进行加密与解密。

缺点:

  • 如果密钥被泄露,那么加密的数据就可能被未授权的第三方解密和访问。

优点:

  • 比较与非对称加密来说,效率比较高,因为需要计算的资源较少。

图解:

image-20241126235023535

2.非对称加密

理解:

  • A端发送数据给B端时生成一个公钥与私钥(密钥对),将数据与公钥发送给B端,B端向A端发送数据时通过公钥加密,A端通过私钥解密,同理A端发送数据给B端也是如此。

缺点:

  • 效率比对称加密钥低,计算的资源较多。

优点:

  • 使用公钥加密后的密文,只能使用对应的私钥才能解开,破解的可能性很低。

图解:

image-20241127000348055

3.非对称加密与对称加密区别

对称加密:
    1.使用同一个秘钥进行加密解密,秘钥容易泄露。
    2.速度快,效率高,数据传输快,安全性低。

非对称加密:
    1.使用不同的公钥进行加密,在使用私钥解密。
    2.速度要比对称加密的慢,效率低,安全性高。

# ssh登录使用的时非对称加密方式
# 登录后的命令传输使用的对称加密方式

4.SSH服务登录过程

首次登录时,会出现一个指纹验证的操作
目的:
    确认链接的是不是当前的服务器,进行指纹对比。

image-20241127222023607


4-1.指纹验证过程

image-20241127222628319

#注意:为什么会出现指纹验证操作:
    因为,第一次登录时没有目标服务器的公钥存储到本地机器上,所以需要确认指纹操作,确认链接的是当前目标服务器,只要确认后,目标服务器就会将公钥发送给本地机器上
    /etc/ssh/ssh_host_ed25519_key.pub # 目标服务器的公钥存放文件路径
    ~/.ssh/known_hosts # 本地存放目标服务器公钥的文件路径

    
1.当首次登录会出现指纹验证操作
    ssh root@192.168.85.133
    
2.指纹信息
    SHA256:Unb0Gno5xCrVfwEc+S0phTJrpoFy3WI5LuT7vZepiWs.

3.当确认指纹后
    本地机器会记录192.168.85.133的公钥到 ~/.ssh/known_hosts 文件中

4.验证指纹的正确性
    # 先查看 ~/.ssh/known_hosts 当前机器的公钥,根据当前机器的公钥信息(公钥 算法)从 /etc/ssh/ 目录下找到对应的文件
    
    # 通过ssh-keygen 命令 + SHA256 算法 + 机器公钥进行 = 指纹
    ssh-keygen -E SHA256 -lf /etc/ssh/ssh_host_ed25519_key.pub

# 注意:
    不管那台机器来到192.168.85.133它公钥都不会发生变化,那么就意味着他的指纹也是相同
    为什么不会变化,因为只要变化了,那么其它'机器存储的公钥信息就会失效'。

image-20241127225144212


5.SSH服务生成的文件解释

本地机器 ---链接--- 目标机器192.168.85.133

1.本地机器会在 ~/.ssh/  生成文件
     ~/.ssh/known_hosts
     	作用:
     		存放ssh链接目标机器的公钥信息
     ~/.ssh/known_hosts.old
        作用:
            是~/.ssh/known_hosts文件的备份,只存储正在使用的公钥信息,如果~/.ssh/known_hosts公钥文件被错误地修改或损坏,或者如果需要恢复到之前的公钥信息


2.目标机器192.168.85.133
    私钥与公钥主要在:/etc/ssh/
    ssh_host_ecdsa_key  # 私钥
    ssh_host_ecdsa_key.pub # 公钥
    ssh_host_ed25519_key  # 私钥
    ssh_host_ed25519_key.pub # 公钥
    ssh_host_rsa_key # 私钥
    ssh_host_rsa_key.pub # 公钥
    
    # 为什么会存在3中类型算法的公私钥对:
        服务器上存在多个公私钥对是为了确保灵活性、兼容性和安全性,同时为管理员提供配置的灵活性,以适应不同的客户端、安全需求和性能要求

image-20241127231737983


6.SSH服务配置文件

配置文件 作用
/etc/ssh/ssh_config 这是SSH客户端的配置文件,它定义了客户端的默认行为。带#号就是默认使用
/etc/ssh/sshd_config 这是SSH服务器的配置文件,它定义了SSH服务的运行参数,包括允许的密钥类型、端口、认证方式等。带#号就是默认使用
/etc/ssh/moduli 这个文件包含了一些用于Diffie-Hellman密钥交换的参数

SSH操作

1.安装

yum install openssh-server openssh -y

openssh # 客户端,提供加密命令
openssh-server # 服务端

sshd参数配置文档官方网站:
    https://man.openbsd.org/sshd_config

2.基于安全配置

  • 修改配置前注意防火墙filewall与selinux。

2-1.修改端口操作

1.打开配置文件
    vim /etc/ssh/sshd_config

2.修改端口参数
    Port 22 -> Port 2299

3.重启ssh
    systemctl restart sshd

image-20241127234502919


2-2.加速SSH链接

修改参数:
    GSSAPIAuthentication no # 禁止gssqpi认证
    UseDNS no # 禁止域名dns解析

GSSAPIAuthentication作用:
    使用使用GSSAPI用户认证,GSSAPI一种应用于网络的安全认证机制,客户端在登录时会尝试使用GSSAPI进行认证,这可能会增加登录时间,特别是当涉及到域名解析时。

UseDNS作用:
    这个参数指定SSH守护进程是否应该对远程主机名进行反向解析,以检查此主机名是否与其IP地址真实对应。开启状态服务器会根据dns地址反向的去查询客户端机器的域名(这可以作为一种安全措施,以防止客户端欺骗),增加了连接延迟。

2-3.修改绑定地址

修改参数:默认是绑定到全部的网卡上
    # ListenAddress 0.0.0.0
    # ListenAddress ::

可以修改带绑定到指定的网卡上:
    比如
        网卡A:172.168.19.255
        网卡B:192.168.85.133
     ListenAddress 0.0.0.0 # 绑定到了全部的网卡使用 网卡A也可以使用网卡B也可以
     
     ListenAddress 192.168.85.133 # 只能通过 192.168.85.133 ip 进行ssh登录

image-20241127234518324


2-4.禁止密码登录

修改 /etc/ssh/sshd.conf 配置参数如下:
1.PasswordAuthentication
    PasswordAuthentication no # 作用:禁止使用密码登录

2.PubkeyAuthentication
    PubkeyAuthentication yes # 作用:使用公钥登录

image-20241128215216632


2-5.禁止root登录

/etc/ssh/sshd_config找到PermitRootLogin参数修改为NO
PermitRootLogin yes # 原
PermitRootLogin no	# 修改后

image-20241128214804167


3.其他配置

3-1.AddressFamily

作用:
    指令用于指定 SSH 守护进程(sshd)应该监听的地址族,以什么方式ipv4还是ipv6,那么 SSH 服务器将能够接受这两种协议的连接请求。

AddressFamily any # 默认 支持 IPv4 和 IPv6。
AddressFamily inet # 支持 IPv4
AddressFamily inet6 # 支持 IPv6

image-20241127235542845


3-2.HostKey

作用:
    HostKey指令用于指定服务器的私钥文件位置,这些私钥用于服务器的身份认证。
    
HostKey /etc/ssh/ssh_host_rsa_key
# HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# 注意:SSH服务可能不会自动生成密钥文件,除非你明确要求生成。
    ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key # 生成私钥,同时也会生成公钥

image-20241128100557093


3-3.RekeyLimit

作用:
    选项仅适用于协议版本 2,指定'会话密钥'传输或者接受最大的数据量,最长持续时间。
    default none 默认值解释:
        不会对'会话密钥'数据使用量和时间进行限制。
    
    数据量单位:
        K 千字节 
        M 兆字节
        G 千兆字节
        
    时间单位:默认单位秒,不指定的情况下就是S(秒)
        S 秒
        M 分钟
        H 小时
        D 天
        W 星期
默认值:
    # RekeyLimit default none
    RekeyLimit 数据量 时间
    
    RekeyLimit 1G 1h
        解释:
            SSH连接传输了1GB数据或连接持续了1小时后,将会自动进行重新密钥交换(重新生成信息的会话密钥)

3-4.SyslogFacility

作用:
     将日志消息通过哪个日志子系统(facility)发送,ssh服务的日志信息会被分类的记录系统日志的文件中 /var/log/ # 存储到系统日志中。
    
有效值:
    AUTH:认证和授权消息。
    AUTHPRIV:与AUTH类似,但用于更敏感的认证消息。
    CRON:Cron守护进程的消息。
    DAEMON:其他系统守护进程的消息。
    KERN:内核消息。
    LOCAL0 到 LOCAL7:为本地使用保留的设施,可以自定义用途。

3-5.LogLevel

作用:
    日志级别

日志其他级别:
    QUIET、FATAL、ERROR、INFO、VERBOSE、DEBUG、DEBUG1、DEBUG2 和 DEBUG3

默认日志:
    LogLevel INFO

3-6.身份验证参数

LoginGraceTime参数:
    作用:
        在输入密码节点,需要多久才能只能完成密码输入操作(在输入密码阶段无操作),如果超过这个时间就会退出链接。
    默认值:
        #LoginGraceTime 2m
        如果值为 0,则没有时间限制,默认2分钟 120秒,s m h d w


PermitRootLogin参数:
    作用:
        是否禁止root用户使用密码登录,yes允许 no不允许
    默认值:
        #PermitRootLogin yes


StrictModes参数:
    作用:
        检查文件模式以及用户文件和 home 目录的所有权(权限),yes开启,no关闭,建议开启。
    默认:
        #StrictModes yes

MaxAuthTries参数:
    作用:
        登录时输入免密错误次数,达到一半就直接就会记录其他失败,计算方式:6/2 = 3
    默认值:
        #MaxAuthTries 6


AuthorizedKeysFile参数:
    作用:
        存放用户身份验证的公钥文件路径,authorized_keys文件存储客户端的公钥信息 # 使用密钥登录时存储 
    默认:
         #AuthorizedKeysFile      .ssh/authorized_keys

AuthorizedPrincipalsFile参数:
    作用:
        指定一个文件,该文件列出 接受的主体名称 证书身份验证
    默认:
        #AuthorizedPrincipalsFile none

AuthorizedKeysCommand参数:
    作用:
        指定要用于查找用户公钥的'程序 or 脚本'。程序必须为root所有,不能被组或其他人写入,并由绝对路径指定。
    默认:
        #AuthorizedKeysCommand none

AuthorizedKeysCommandUser参数:
    作用:
        配合AuthorizedKeysCommand指令使用,需要指定一个用户名,该用户在主机上除了执行授权密钥命令外,不具有其他角色。
    默认:
        #AuthorizedKeysCommandUser nobody

# AuthorizedKeysCommandUser + AuthorizedKeysCommand 组合
    用于动态地从外部数据源检索公钥
    
UsePAM参数
    作用:
        控制是否使用 PAM(可插拔认证模块)来处理 SSH 登录认证。建议您使用 UsePAM 且 ChallengeResponseAuthentication 设定为 no
    默认:
        UsePAM yes

UseLogin参数:
    作用:
        是否登录使用login认证登录,也就是决定是否使用传统的 login 程序
    默认:
        #UseLogin no

3-7.MaxSessions

MaxSessions参数:
    作用:
        打开ssh 会话的最大数量(SSH 会话连接到服务器),超出的数量就无法在打开,除非关闭一个会话,才能打开。也就是同一个账户可以被多少台电脑链接。
    默认:
        #MaxSessions 10

image-20241128145024032


3-8.PubkeyAuthentication

PubkeyAuthentication参数:
    作用:
        是否允许公钥认证,默认yes,如果设置no就无法使用公钥登录
    默认:
        #PubkeyAuthentication yes

image-20241128153328050


3-8.密码相关参数

PasswordAuthentication参数:
    作用:
        是否可以密码登录,yes是,no否
    默认:
        #PasswordAuthentication yes

PermitEmptyPasswords参数:
    作用:
        允许密码的用户登录,需要配合PasswordAuthentication参数使用。
        如果开启了yes还是无法进行空密码登录,可能 PAM 模块 限制,可以 UsePAM no
    默认:
        #PermitEmptyPasswords no

ChallengeResponseAuthentication参数:
    作用:
         允许任何的密码认证!所以,任何 login.conf 规定的认证方式,均可适用!
         默认是no,一版使用PAM进行认证
    默认:
        #ChallengeResponseAuthentication no

3-9.GSSAPI

GSSAPIAuthentication参数:
    作用:
        指定是否允许基于 GSSAPI 的用户验证
    默认:
        #GSSAPIAuthentication no

GSSAPICleanupCredentials参数:
    作用:
        指定是否在注销时自动销毁用户的凭据缓存。
    默认:
        #GSSAPICleanupCredentials yes
        
GSSAPIStrictAcceptorCheck参数:
    作用:
        会强制 SSH 服务器在 GSSAPI 认证过程中执行更严格的安全检查。这包括验证客户端提供的票证(ticket)是否有效,以及票证中的服务主体(service principal)是否与服务器的主体匹配。
    默认:
        #GSSAPIStrictAcceptorCheck yes

3-10.Kerberos

不用 Kerberos 主机,不设置
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

3-11.X-Window

图形化使用的参数,不设置
#X11Forwarding yes
#AllowTcpForwarding no
#PermitTTY no
#ForceCommand cvs server
# X11DisplayOffset 10
# X11UseLocalhost no

3-12.参数

HostbasedAuthentication参数:
    作用:
        指定是否允许rhosts或/etc/hosts.equiv身份验证以及成功的公钥客户端主机身份验证(基于主机的身份验证)
    默认:
        #HostbasedAuthentication no


IgnoreUserKnownHosts参数:
    作用:
        是否在 RhostsRSAAuthentication 或 HostbasedAuthentication 过程中忽略用户的 ~/.ssh/known_hosts 文件。
    默认:
        #IgnoreUserKnownHosts no


IgnoreRhosts参数:
    作用:
         指定在HostbasedAuthentication期间是否忽略每个用户的.rhosts和.shosts文件。无论此设置如何,系统范围内的/etc/hosts.equiv和/etc/shosts.equiv仍然被使用。
    默认:
        #IgnoreRhosts yes


AllowAgentForwarding参数:
    作用:
        指定是否允许ssh代理(1)转发。默认值为yes。请注意,禁用代理转发并不能提高安全性,除非用户也被拒绝shell访问。
    默认:
        #AllowAgentForwarding yes


AllowTcpForwarding参数:
    作用:
        指定是否允许TCP转发。可用的选项是yes(默认)或all以允许TCP转发,no以阻止所有TCP转发,local以仅允许本地(从ssh(1)的角度来看)转发或remote以仅允许远程转发。请注意,禁用TCP转发并不能提高安全性,除非用户也被拒绝shell访问。
    默认:
        #AllowTcpForwarding yes

TCPKeepAlive参数:
    作用:
        指定系统是否应向另一端发送TCP保活消息。确保另外一端是否正常。
    默认:
        #TCPKeepAlive yes


UsePrivilegeSeparation参数:
    作用:
        是否让通过创建非特权子进程处理接入请求的方法来进行权限分离,认证成功后,将以该认证用户的身份创建另一个子进程。
             这样做的目的是为了防止通过有缺陷的子进程提升权限,从而使系统更加安全。
    默认:
        #UsePrivilegeSeparation sandbox

PermitUserEnvironment参数:
    作用:
        是否处理~/.ssh/authorized_keys中的~/.ssh/environment和environment=选项。如果设为"yes"可能会导致用户有机会使用某些机制(比如 LD_PRELOAD)绕过访问控制,造成安全漏洞。
    默认:	
        #PermitUserEnvironment no
 
Compression参数:
作用:
    用户成功通过身份验证后是否启用压缩 delayed(是yes的遗留同义词) 或者 no。
默认:
    #Compression delayed
    
    
ClientAliveInterval参数
    作用:
         设置一个以秒记的时长,如果超过这么长时间没有收到客户端的任何数据,将通过安全通道向客户端发送一个"alive"消息,并等候应答。默认值 0 表示不发送"alive"消息。这个选项仅对SSH-2有效。
    默认值:
        #ClientAliveInterval 0

ClientAliveCountMax参数:
    作用:
        在未收到任何客户端回应前最多允许发送多少个"alive"消息。默认值是 3 。到达这个上限后将强制断开连接、关闭会话。只有ClientAliveInterval设置后才会有效。"alive"消息与 TCPKeepAlive 有很大差异。 "alive"消息是通过加密连接发送的,因此不会被欺骗;而 TCPKeepAlive 却是可以被欺骗的。
    默认值:
        #ClientAliveCountMax 3

PidFile参数:
    作用:
        sshd服务的pid存储文件位置
    默认
        #PidFile /var/run/sshd.pid
        
#MaxStartups 10:30:100

PermitTunnel参数:
    作用:
        是否允许设备转发,来指定是否允许客户端建立 VPN 隧道。
    默认:		
        #PermitTunnel no
    指定值:
        "yes":允许使用所有类型的隧道,包括点对点(layer 3)和以太网(layer 2)隧道。
        "point-to-point"(layer 3):允许建立点对点的虚拟专用线路,这种类型的隧道需要路由才能使用,通常是 SSH VPN 的最佳隧道类型。
        "ethernet"(layer 2):允许传输第 2 层流量,使得两个不同位置可以共享其本地局域网。如果可能的话,不建议通过 SSH 隧道传输以太网,因为 VPN 一侧的本地网络问题可能会在链路上传播,并使你的外部带宽饱和。
        "no"(默认值):禁止使用隧道。

ChrootDirectory参数:
    作用:
        用于指定一个目录,该目录将在用户通过 SSH 登录后成为他们的根目录(chroot 环境)。这意味着用户将被限制在该目录内,无法访问系统的其他部分。
    默认:
        #ChrootDirectory none
        
VersionAddendum参数:
    作用:
        可选地指定附加文本,以附加到服务器在连接时发送的SSH协议横幅上。
    默认:
        #VersionAddendum none

Banner参数:
    作用:
        将这个指令指定的文件中的内容在用户进行认证前显示给远程用户
    默认:
        #Banner none

3-13.GatewayPorts

GatewayPorts参数:
    作用:
        它用来控制 SSH 服务器是否允许通过 SSH 连接转发端口到客户端的非本地地址。这个选项决定了你能否通过 SSH 隧道将远程服务器上的服务“暴露”到你的本地机器上,以便在本地访问远程服务。
    默认:
        #GatewayPorts no
    可指定参数:
        no 不设置
        clientspecified 允许客户端'指定端口'转发的目标地址。
        yes 允许任何客户端进行端口转发,无论其连接地址是什么。


# 当参数 GatewayPorts clientspecified 会出现什么样的效果
    你家里的计算机,IP 地址是 192.168.0.100。
    公司的服务器,IP 地址是 10.0.0.1,数据库服务运行在端口 5432 上。
    
    想要将 公司服务器 10.0.0.1:5432 映射到家里的计算机 127.0.0.1:5432
    
    1.需要设置sshd参数 
        GatewayPorts clientspecified
    
    2.在家里的电脑中设置 SSH 客户端发起连接,并指定端口转发
        ssh -L 5432:localhost:5432 user@10.0.0.1
    
    这样操作就等同于将公司服务器的5432端口映射到家里电脑的5432端口。
    也就说,通过家里电脑的localhost:5432端口就可以转发到10.0.0.1:5432

# 当参数 GatewayPorts yes 会出现什么样的效果
    你可以让 SSH 服务器接受来自互联网上任何地方的连接到这些转发端口的请求
    当 GatewayPorts 设置为 yes 时,任何能够访问 SSH 服务器的远程主机都可以通过 SSH 服务器的80端口连接到远程服务器的5538端口,而不仅仅是发起 SSH 连接的本地机器。
    ssh -L 80:localhost:5538 user@remote_server_ip ,原本应该是 我的电脑的127.0.0.1:5538 可以转发到ssh服务80,设置了yes后,其他只要能链接服务器的电脑(知道密码或者秘钥)都可以使用(127.0.0.1:5538)。

3-14.PermitTTY

PermitTTY参数:
    作用:
        指定是否允许pty(4)分配。默认值为yes(简单解释:是否可以进行命令交互)。
    默认:
        #PermitTTY yes

当参数变为 no 时出现下面的情况。没有伪终端就无法实现命令的交互,直接影响着命令的交互。

image-20241128223313924


3-15.PrintMotd

PrintMotd参数:
    作用:
        指定当用户以交互方式登录时,是否应打印/etc/motd。用户成功登录后,SSH 服务会显示 /etc/motd 文件中的内容。
    默认:
        #PrintMotd yes

image-20241128224042371


3-16.PrintLastLog

PrintLastLog参数:
    作用:
        用于指定是否在每一次交互式登录时打印最后一位用户的登录时间。这个功能通过查看 /var/log/lastlog 文件来实现,该文件记录了系统中每个用户的最后登录时间。
    默认:
        #PrintLastLog yes

4.免密登录

A机器需要免密登录到B机器:
A机器:
    1.执行 ssh-keygen 生成秘钥对
    2.执行ssh-copy-id B机器ip
    3.初次验证需要输入'账户密码'
    4.将公钥发送给B

B机器验证:
    1.拿到账户去/etc/passwd中验证账户
    2.拿到密码去/etc/shadow中验证密码
    3.验证通过将A机器的公钥写入到

比如登录到时root账户,那么公钥就会存储到root的家目录下
    ~/.ssh/authorized_keys

~/.ssh/authorized_keys 文件很重要,只要记录有机器的公钥,那么这台机器就可以免密登录

image-20241129093610517


4-1.免密登录过程

A机器免密登录B机器的过程

1.A机器发送登录请求(比如登录root用户)
2.B机器验证当前root家目录下 ~/.ssh/authorized_keys 是否存在A机器的公钥信息
3.B机器生成一个随机字符串通过公钥(A机器的公钥)加密,发送给A机器。
4.A机器接收到后,通过私钥进行解密,将解密的字符串发送给B机器
5.B机器进行验证,验证成功后,A机器登录。

image-20241129101038087


4-2.免密登录操作

1.A机器执行命令生成密钥对
    ssh-keygen # 不指定默认生成的SHA256算法密钥对
    ssh-keygen -t rsa -b 4096 # 也可以指定 rsa ,4096指定的位数

    生成的位置默认在 ~/.ssh/ 目录下,生成两个文件,一个是公钥一个私钥


2.A机器执行命令发送公钥到B机器
    ssh-copy-id root@192.168.88.129 # 需要进行密码验证


3.需要在sshd配置文件中开启秘钥登录认证 (不开启还是使用密码登录)
    PubkeyAuthentication no --> yes
    systemctl restart sshd

image-20241129103552364


4-3.免密登录验证

4-3-1.查看日志

journalctl -u sshd

image-20241129104756361


4-3-2.使用参数进行调试查看

ssh -v root@B机器的IP地址 查看整个过程。 # -v 进入debug模式查看
ssh -i ~/.ssh/id_rsa root@B机器的IP地址 # 使用-i参数 指定私钥文件进行连接,来测试密钥交换过程

4-4.清除免密登录

# 删除或者清空远程服务的~/.ssh/authorized_keys
rm -f ~/.ssh/authorized_keys

4-5.pwden生成随机密码

可以生成密码,然后在配合shell脚本 + crontab定时功能实现密码定时更新功能

命令:
    pwgen

参数:
    -c 在密码中至少包含一个大写字母
    -A 密码中不要包含大写字母
    -n 密码中至少包含一个数字
    -0 不在密码中包含数字
    -r 字符 # 从生成密码的中删除指定的字符
    -s 完全随机密码
    -B 密码中不要包含有歧义的字符
    
安装:
    yum install pwgen


# 生成随机密码操作
    pwgen | head 1 | passwd 用户名 --stdin

4-6.sshpass命令非交互

作用:
    非交互式密码,可以用于ssh链接自动提供密码,不进行交互式输入密码,自动执行ssh链接。

安装:
    yum install sshpass -y
    
命令:
    sshpass

参数:
    -f filename # 从filename获取密码
    -p 密码 # 指定密码

例如:
    sshpass -p 123123 ssh it-21@192.168.88.130

# 注意:
    使用sshpass链接时,需要先将指纹通过。

image-20241129143633226


5.SSH操作

5-1.远程命令执行

# 建议使用密钥方式,如果是密码还要输入密码。
语法:
    ssh root@ip  执行命令

例如:
    ssh root@192.168.88.129 touch /opt/123.log

image-20241129114528898


5-2.文件传输

# 建议使用密钥方式,如果是密码还要输入密码。

命令:
    sftp username@server

put 文件 # 上传
get 文件 # 下载

cd path # 将远程目录修改为path 
lcd path # 将本地目录修改为path ,windows系统将路径加上''引号

mkdir path # 在远程目录创建
lmkdir path # 在本地目录创建

ls # 查看远程目录列表
lls # 查看本地目录列表

pwd # 查看远程目录
lpwd # 查看本地目录

quit # 退出

5-3.端口转发(隧道)

1.本地端口转发:
    ssh -L 本地端口:目标主机:目标端口 用户名@远程服务器
    
    本地端口:你希望在本地机器上监听的端口。
    目标主机:目标服务的实际主机地址。
    目标端口:目标服务的端口。
    用户名:远程服务器上的用户名。
    远程服务器:远程服务器的地址。


2.远程端口转发:
    ssh -R 远程端口:目标主机:目标端口 用户名@远程服务器
    
    远程端口:你希望在远程服务器上监听的端口。
    目标主机:目标服务的实际主机地址。
    目标端口:目标服务的端口。
    用户名:远程服务器上的用户名。
    远程服务器:远程服务器的地址。


3.需要开启配置
    AllowTcpForwarding yes # 允许tcp端口转发
    GatewayPorts yes # 允许远程端口转发接受来自非本地连接的连接
    
3.动态端口转发
    ssh -D 本地端口 用户名@远程服务器
    本地端口:本地机器上用于监听 SOCKS 代理的端口。
    用户名:远程服务器上的用户名。
    远程服务器:远程服务器的地址。
    
    如果想要通过 SSH 连接访问 Web 代理,你可以使用 -D 选项创建一个 SOCKS 代理,然后在浏览器中配置使用该代理。

5-4.脚本批量分发密钥

#! /bin/bash
# 1.生成密钥对
if [ ! -f ~/.ssh/id_rsa ];then
    ssh-keygen -N '' -f ~/.ssh/id_rsa > /dev/null
fi

# -o StrictHostKeyChecking=no 不需要用户确认公钥发送,默认时需要用户确认
# 2.发送密钥
for i in '$@'
do
    sshpass -p 123123 ssh-copy-id root@${i} -o StrictHostKeyChecking=no > /dev/null
    # 3.修改配置,开启公钥登录,禁止密码登录,修改端口
    sshpass -p 123123 ssh root@${i} "sed -i '/^PasswordAuthentication/c PasswordAuthentication no' /etc/ssh/sshd_config"
    sshpass -p 123123 ssh root@${i}  "sed -i  '/PubkeyAuthentication/c PubkeyAuthentication yes'  /etc/ssh/sshd_config"
    sshpass -p 123123 ssh root@${i} "sed -i '/Port 22/c Port 22999' /etc/ssh/sshd_config"
    sshpass -p 123123 ssh root@${i} systemctl restart sshd
done