欢迎光临散文网 会员登陆 & 注册

关于ssh

2023-01-15 12:46 作者:rambo_王炸  | 我要投稿

ssh概述

  • SSH基本

SSH 是 Linux 系统的登录工具,现在广泛用于服务器登录和各种加密通信。

SSH(Secure Shell)是一种网络协议,用于加密两台计算机之间的通信,并且支持各种身份验证机制。

它主要用于保证远程登录和远程通信的安全,任何网络服务都可以用这个协议来加密。

它还能对操作者进行认证(authentication)和授权(authorization)。明文的网络协议可以套用在它里面,从而实现加密。



SSH 的软件架构是服务器-客户端模式(Server - Client):

向服务器发出请求的部分称为客户端,OpenSSH 的实现为ssh

接收客户端发出的请求的部分称为服务器,OpenSSH 的实现为sshd

OpenSSH 还提供一些辅助工具软件(比如 ssh-keygen 、ssh-agent)和专门的客户端工具(比如 scp 和 sftp)
  • SSH发展进程

1995年,芬兰赫尔辛基工业大学的研究员 Tatu Ylönen 设计了 SSH 协议的第一个版本 SSH 1,同时写出了第一个实现 SSH1。

1996年,又提出了 SSH 2 协议,这个协议与1.0版不兼容,1998年推出了软件实现 SSH2。但是,官方的 SSH2 软件是一个专有软件,不能免费使用。

1999年,OpenBSD 的开发人员写了一个 SSH 2 协议的开源实现,这就是 OpenSSH 项目。目前,Linux 的所有发行版几乎都自带 OpenSSH。


SSH 客户端

OpenSSH的客户端是二进制程序ssh。Linux一般都自带ssh,如果没有就需要安装

# 在 Ubuntu 或 Debian 上安装 ssh 客户端
~]# sudo apt install openssh-client

# 在 Ubuntu 或 Debian 上安装 ssh 服务端
~]# sudo apt install openssh-server

~]# sudo systemctl enable ssh --now


# 在 CentOS 或 RedHat 上安装 ssh 服务端/客户端
~]# sudo yum -y install openssh-server openssh-clients
~]# sudo systemctl enable ssh --now


  • ssh连接流程

~]# ssh host              # 不指定用户名时则将使用客户端的当前用户名($USER)作为远程服务器的登录用户名

~]# ssh -p 8821 host        # 指定服务器端口,不指定时默认连接服务器的22端口
~]# ssh -T git@github.com   # 测试连接服务器



ssh 连接远程服务器后,首先有一个验证过程,验证远程服务器是否为陌生地址

如果是第一次连接某一台服务器,命令行会显示一段文字,表示不认识这台机器,提醒用户确认是否需要连接

The authenticity of host 'github.com (20.205.243.166)' cannot be established 确定的.
ECDSA key fingerprint is SHA256:p2QAMCFYO1TJYWeIOtKOPG98/R1DMMQu3/LiFFTUQM.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

注1:上述中20.205.243.166是github.com的IP
注2:其中的 fingerprint 指的是 SSH 服务器公钥的哈希值。每台 SSH 服务器都有唯一一对密钥,用于跟客户端通信,其中公钥的哈希值就可以用来识别服务器



在上面这段文字后面输入yes,就可以将当前服务器的指纹也储存在本机~/.ssh/known_hosts文件中,每次连接服务器时,通过该文件判断是否为陌生主机(陌生公钥),并显示下面的提示。以后再连接的时候就不会再出现警告

Warning: Permanently added 'github.com,20.205.243.166' (ECDSA) to the list of known hosts.
Hi baiqiantao! You have successfully authenticated 认证, but GitHub does not provide shell access.



# 查看公钥的指纹
~]# ssh-keygen -l -f ~/.ssh/id_rsa.pub           # 查看公钥的指纹
  • 服务器密钥变更

如果服务器的密钥发生变更(比如重装了SSH服务器),客户端再次连接时,就会发生公钥指纹不吻合的情况。此时客户端就会中断连接并显示一段警告信息

这时你需要确认是什么原因使得公钥指纹发生变更,到底是恶意劫持还是管理员变更了 SSH 服务器公钥

如果新的公钥确认可以信任,你可以执行下面的命令,将原来的公钥指纹从~/.ssh/known_hosts文件删除

~]# ssh-keygen -R github.com         # 删除 known_hosts 中指定主机公钥的指纹,也可以手动修改此文件

# 查看-R的释义

~]# man ssh-keygen

     -R hostname

             Removes all keys belonging to hostname from a known_hosts file.  This

             option is useful to delete hashed hosts (see the -H option above).

释义:从known_hosts文件中删除属于主机名的所有密钥。 此选项对于删除散列主机很有用(请参阅上面的 -H 选项)


删除了原来的公钥指纹以后,重新执行ssh连接远程服务器,将新的指纹加入known_hosts文件即可顺利连接
  • 参数集

SSH 连接的握手阶段,客户端必须跟服务端约定 加密参数集(cipher suite)
加密参数集格式

加密参数集包含了若干不同的加密参数,它们之间使用下划线连接在一起
例如:TLS_RSA_WITH_AES_128_CBC_SHA
TLS:加密通信协议
RSA:密钥交换算法
AES:加密算法
128:加密算法的强度
CBC:加密算法的模式
SHA:数字签名的 Hash 函数
  • ssh配置文件config

/etc/ssh/ssh_config:全局对 SSH 客户端的配置文件
~/.ssh/config:用户个人对 SSH 客户端的配置文件,优先级高于全局配置文件
~/.ssh/known_hosts:用户信任的 SSH 服务器的公钥指纹
~/.ssh/id_rsa 和 xxx.pub:用于 SSH 2 协议默认的 RSA 私钥/公钥
~/.ssh/id_dsa 和 xxx.pub:用于 SSH 2 协议默认的 DSA 私钥/公钥
~/.ssh/identity 和 xxx.pub:用于 SSH 1 协议默认的 RSA 私钥/公钥
~/.ssh/id_ecdsa 和 xxx.pub:ECDSA 私钥/公钥
  • 配置文件的语法

用户个人的配置文件~/.ssh/config,可以按照不同服务器,列出各自的连接参数,从而不必每一次登录都输入重复的参数
# Host 的值可以使用通配符,【*.edu】表示下面的设置只对一级域名为 .edu 的主机有效
# Host 命令后面的所有配置都是针对该主机的,直到下一个Host命令为止
~]# vim ~/.ssh/config
....
    ....
Host *                 # 表示下面的配置对所有的主机都有效,值可以被单个主机的设置覆盖
  Port 7022            # 表示所有主机的默认连接端口都是8022,这里的缩进并不是必需的
  User = zhangsan      # 配置命令与值之间,可以使用空格或等号(等号前后的空格是可选的)

Host github            # 表示下面的设置只对主机 github(这只是一个别名) 生效
  HostName github.com  # 具体的主机由 HostName 指定
  User git             # 像 github、gitlab、gitee 等 git 系统,用户名都是 git
  Port 22              # 指定端口,会覆盖上面的设置
  IdentityFile ~/.ssh/id_rsa_github   # 指定私钥文件


以后登录github.com时,只要执行ssh github命令就会自动套用 config 文件里面指定的参数。
~]# ssh github      # 等同于ssh -p 22 -i ~/.ssh/id_rsa_github git@github.com
  • 配置文件的配置项

以下是客户端 ssh 配置文件 ~/.ssh/config 的一些主要配置命令,及它们的范例值

AddressFamily inet:表示只使用 IPv4 协议。如果设为inet6,表示只使用 IPv6 协议
BindAddress 192.168.1.25:指定本机的 IP 地址(如果本机有多个 IP 地址)
CheckHostIP yes:检查 SSH 服务器的 IP 地址是否跟公钥数据库吻合
Ciphers blowfish,3des:指定加密算法
Compression yes:是否压缩传输信号
ConnectionAttempts 10:客户端进行连接时,最大的尝试次数
ConnectTimeout 60:客户端进行连接时,服务器在指定秒数内没有回复,则中断连接尝试
DynamicForward 1080:指定动态转发端口
GlobalKnownHostsFile /users/smith/.ssh/my_global_hosts_file:指定全局的公钥数据库文件的位置
Host host:指定连接的域名或 IP 地址,也可以是别名,支持通配符
HostKeyAlgorithms ssh-dss,ssh-rsa:指定密钥算法,优先级从高到低排列。
HostName myhost:在Host命令使用别名的情况下,HostName指定域名或 IP 地址
IdentityFile keyfile:指定私钥文件
LocalForward 2001 localhost:143:指定本地端口转发
LogLevel QUIET:指定日志详细程度。如果设为QUIET,将不输出大部分的警告和提示
MACs hmac-sha1,hmac-md5:指定数据校验算法
NumberOfPasswordPrompts 2:密码登录时,用户输错密码的最大尝试次数。
PasswordAuthentication no:指定是否支持密码登录。这里只是客户端禁止,真正的禁止需要在 SSH 服务器设置
Port 2035:指定客户端连接的 SSH 服务器端口
PreferredAuthentications publickey,hostbased,password:指定各种登录方法的优先级
Protocol 2:支持的 SSH 协议版本,多个版本之间使用逗号分隔
PubKeyAuthentication yes:是否支持密钥登录。这里只是客户端设置,还需要在 SSH 服务器进行相应设置
RemoteForward 2001 server:143:指定远程端口转发
SendEnv COLOR:SSH 客户端向服务器发送的环境变量名,多个环境变量之间使用空格分隔。环境变量的值从客户端当前环境中拷贝
ServerAliveCountMax 3:如果没有收到服务器的回应,客户端连续发送多少次keepalive信号才断开连接。默认值为3
ServerAliveInterval 300:客户端建立连接后,如果在给定秒数内,没有收到服务器发来的消息,客户端向服务器发送keepalive消息。如果不希望客户端发送,这一项设为0
StrictHostKeyChecking yes:yes表示严格检查,服务器公钥为未知或发生变化,则拒绝连接。no表示如果服务器公钥未知,则加入客户端公钥数据库,如果公钥发生变化,不改变客户端公钥数据库,输出一条警告,依然允许连接继续进行。ask(默认值)表示询问用户是否继续进行
TCPKeepAlive yes:客户端是否定期向服务器发送keepalive信息
User userName:指定远程登录的账户名
UserKnownHostsFile /users/smith/.ssh/my_local_hosts_file:指定当前用户的known_hosts文件(服务器公钥指纹列表)的位置。
VerifyHostKeyDNS yes:是否通过检查 SSH 服务器的 DNS 记录,确认公钥指纹是否与known_hosts文件保存的一致
  • ssh 命令行配置项

ssh 命令有一些配置项。这些配置项在调用时指定,可以覆盖配置文件的设置
# 配置项解释
-c:指定加密算法
-C:表示压缩数据传输
-D:指定本机的 Socks 监听端口,该端口收到的请求,都将转发到远程的 SSH 主机,又称动态端口转发
-f:表示 SSH 连接在后台运行
-F:指定配置文件
-i:指定私钥,默认值为~/.ssh/id_dsa和~/.ssh/id_rsa,对应的公钥必须存放到服务器
-l:指定远程登录的账户名
-L:设置本地端口转发
-m:指定校验数据完整性的算法(MAC,message authentication code)
-N:表示建立的 SSH 只用于端口转发,不能执行远程命令,这样可以提供安全性
-o:用来指定一个配置命令
-p:指定 SSH 客户端连接的服务器端口
-q:表示安静模式(quiet),不向用户输出任何警告信息
-R:指定远程端口转发
-t:在 ssh 直接运行远端命令时,提供一个互动式 Shell
-v:显示详细信息
-V:输出 ssh 客户端的版本
-X:表示打开 X 窗口转发
  • 配置项示例

ssh -c xx,yy host   # 指定使用加密算法 xx 或 yy,等同于ssh -c xx -c yy host
ssh -C host         # 压缩数据传输
ssh -F ~/.ssh/xx    # 使用指定的配置文件
ssh -i my-key host  # 指定私钥
ssh -l user host    # 指定远程登录的账户名,等同于ssh user@host
ssh -m xx,yy host   # 指定数据校验算法(MAC)为xx 或 yy
ssh -o "Key Value"  # 指定一个配置命令,等同于ssh -o Key=Value,等号前后不能有空格
ssh -p 2035 host    # 指定连接服务器的2035端口
ssh –q host         # 安静模式,不向用户输出任何警告信息
ssh -t host cmd     # 在 ssh 直接运行远端命令时,提供一个互动式 Shell
ssh -v host         # 可以重复多次,表示信息的详细程度,比如【-vv】和【-vvv】
ssh -V              # 输出 ssh 客户端的版本:OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
ssh -X host         # 打开 X 窗口转发
ssh -2 host         # -1 参数指定使用 SSH 1 协议,-2 参数指定使用 SSH 2 协议
ssh -4 host         # -4 指定使用 IPv4 协议(默认值),-6 指定使用 IPv6 协议
  • 端口转发相关

ssh -N host                     # 表示建立的 SSH 只用于端口转发,不能执行远程命令,这样可以提供安全性
ssh -D 1080 host                # 动态端口转发:将本机 1080 端口收到的请求,都转发到服务器 host

ssh -L 9639:server:80 user@host # 本地端口转发所有发向本地 9639 端口的请求,都会经过 host 发往 server 的 80 端口,相当于直接连上了 server 的 80 端口

ssh -R 9639:server:605 local    # 远程端口转发,需在跳板服务器(即 local)执行此命令指定本地计算机 local 监听自己的 9639 端口,所有发向这个端口的请求,都会转向 server 的 9605 端口


SSH 服务器

OpenSSH 的客户端软件是 ssh,服务器软件是 sshd
# 在 Ubuntu 或 Debian 上安装 ssh 客户端
~]# sudo apt install openssh-client                        

# 在 Ubuntu 或 Debian 上安装 ssh 服务端
~]# sudo apt install openssh-server                        
~]# sudo systemctl enable ssh --now


# 在 CentOS 或 RedHat 上安装 ssh 服务端/客户端
~]# sudo yum -y install openssh-server openssh-clients     
~]# sudo systemctl enable ssh --now
  • sshd 密钥 ssh_host_xx_key

sshd 有自己的一对或多对密钥。它使用密钥向客户端证明自己的身份。所有密钥都是公钥和私钥成对出现,公钥的文件名一般是私钥文件名加上后缀.pub。
/etc/ssh/ssh_host_key 和 xxx.pub:用于 SSH 1 协议默认的 RSA 私钥/公钥
/etc/ssh/ssh_host_rsa_key 和 xxx.pub:用于 SSH 2 协议默认的 RSA 私钥/公钥
/etc/ssh/ssh_host_dsa_key 和 xxx.pub:用于 SSH 2 协议默认的 DSA 私钥/公钥
/etc/ssh/ssh_host_ecdsa_key 和 xxx.pub:ECDSA 私钥/公钥

注:
重装sshd后上面这些密钥都会重新生成,导致客户端重新连接ssh服务器时跳出警告,拒绝连接。为了避免这种情况可在重装sshd前先备份/etc/ssh目录,重装后再恢复这个目录
  • 如密钥不是默认文件可通过配置文件sshd_config的HostKey配置项指定

~]# vim /etc/ssh/sshd_config
## HostKey for protocol version 1
HostKey /etc/ssh/ssh_host_key             # 指定密钥文件的路径及名字 

## HostKeys for protocol version 2 
HostKey /etc/ssh/ssh_host_rsa_key         # 指定密钥文件的路径及名字 
HostKey /etc/ssh/ssh_host_dsa_key         # 指定密钥文件的路径及名字 
  • sshd配置文件sshd_config

配置文件的语法
配置文件的语法如下:
~]# vim /etc/ssh/sshd_config
每个命令占据一行,每行都是配置项和对应的值
配置项对大小写不敏感
配置项与值之间可以使用空格或等号分隔,等号前后的空格可选
以 # 开头的行表示注释,注释只能放在一行的开头
空行等同于注释


sshd 启动时会自动读取默认的配置文件,可以用-f参数使用指定的配置文件
sshd -f /usr/local/ssh/my_config # 启动 sshd 后使用指定的配置文件
sshd -t                          # 检查配置文件有没有语法错误
sudo systemctl restart sshd      # 修改配置文件以后,必须重启 sshd 才会生效
  • 配置文件的配置项

服务端 sshd 配置文件 /etc/ssh/sshd_config 的一些主要配置命令及它们的范例值

~]# vim /etc/ssh/sshd_config
AcceptEnv PATH TERM:指定允许接受客户端通过SendEnv命令发来的哪些环境变量,即允许客户端设置服务器的环境变量清单。变量名之间使用空格分隔

AllowGroups groupName:指定允许登录的用户组,多个组之间用空格分隔。如果不使用该项,则允许所有用户组登录

AllowUsers user:指定允许登录的用户,用户名之间使用空格分隔,也可以使用多行AllowUsers命令指定,用户名支持使用通配符。如果不使用该项,则允许所有用户登录。也可以使用用户名@域名的格式。

AllowTcpForwarding yes:指定是否允许端口转发,默认值为yes,local表示只允许本地端口转发,remote表示只允许远程端口转发
AuthorizedKeysFile .ssh/authorized_keys:指定储存用户公钥的目录,默认是用户主目录的ssh/authorized_keys目录
Banner /usr/local/etc/warning.txt:指定用户登录后,sshd 向其展示的信息文件,默认不展示任何内容
ChallengeResponseAuthentication yes:指定是否使用键盘交互身份验证方案,默认值为yes
Ciphers 3des-cbc:指定 sshd 可以接受的加密算法,多个算法之间使用逗号分隔。
ClientAliveCountMax 8:指定建立连接后,客户端失去响应时,服务器尝试连接的次数
ClientAliveInterval 180:指定允许客户端发呆的时间,单位为秒。如果这段时间里面,客户端没有发送任何信号,SSH 连接将关闭
Compression yes:指定客户端与服务器之间的数据传输是否压缩。默认值为yes
DenyGroups groupName:指定不允许登录的用户组
DenyUsers user1:指定不允许登录的用户,用户名之间使用空格分隔,也可以使用多行DenyUsers命令指定
FascistLogging yes:指定日志输出全部 Debug 信息。SSH 1 版本专用
HostKey /etc/ssh/ssh_host_rsa_key:指定 sshd 服务器的密钥,详见前文
KeyRegenerationInterval 3600:指定 SSH 1 版本的密钥重新生成时间间隔,单位为秒,默认是3600秒

ListenAddress 0.0.0.0:指定 sshd 监听的本机 IP 地址,即 sshd 启用的 IP 地址,默认是 0.0.0.0,表示在本机所有网络接口启用。可以改成只在某个网络接口或某个域名启用。如果要监听多个指定的 IP 地址,可以使用多行ListenAddress命令

LoginGraceTime 60:指定允许客户端登录时发呆的最长时间,比如用户迟迟不输入密码,连接就会自动断开,单位为秒。如果设为0,就表示没有限制
LogLevel INFO:指定日志的详细程度,可能的值依次为QUIET、FATAL、ERROR、INFO、VERBOSE、DEBUG、DEBUG1、DEBUG2、DEBUG3,默认为INFO
MACs hmac-sha1:指定 sshd 可以接受的数据校验算法,多个算法之间使用逗号分隔
MaxAuthTries 3:指定允许 SSH 登录的最大尝试次数,如果密码输入错误达到指定次数,SSH 连接将关闭
MaxStartups 0:指定允许同时并发的 SSH 连接数量。设为0表示没有限制。

PasswordAuthentication yes:指定是否允许密码登录,默认值为yes,建议改成no,即禁止密码登录,只允许密钥登录

PermitEmptyPasswords yes:指定是否允许空密码登录,即用户的密码是否可以为空,默认为yes,建议改成no,即禁止无密码登录

PermitRootLogin yes:指定是否允许根用户登录,默认为yes,建议改成no,即禁止根用户登录。还有一种写法是写成PermitRootLogin prohibit-password,表示 root 用户不能用密码登录,但是可以用密钥登录

PermitUserEnvironment no:指定是否允许 sshd 加载客户端的~/.ssh/environment文件和~/.ssh/authorized_keys文件里面的environment= options环境变量设置。默认值为no。
Port 22:指定 sshd 监听的端口,即客户端连接的端口,默认是22。配置文件可以使用多个Port命令,同时监听多个端口
PrintMotd yes:指定用户登录后,是否向其展示系统的 motd(Message of the day)的信息文件/etc/motd。默认值为yes
PrintLastLog yes:指定是否打印上一次用户登录时间,默认值为yes
Protocol 2:指定 sshd 使用的协议。1表示使用 SSH 1 协议,Protocol 2,1表示同时支持两个版本的协议
PubKeyAuthentication yes:指定是否允许公钥登录,默认值为yes
QuietMode yes:指定日志只输出致命的错误信息。SSH 1 版本专用

RSAAuthentication yes:指定允许 RSA 认证,默认值为yes
ServerKeyBits 768:指定 SSH 1 版本的密钥重新生成时的位数,默认是768

StrictModes yes:指定 sshd 是否检查用户的一些重要文件和目录的权限。默认为yes,即对于用户的 SSH 配置文件、密钥文件和所在目录,SSH 要求拥有者必须是根用户或用户本人,用户组和其他人的写权限必须关闭

SyslogFacility AUTH:指定 Syslog 如何处理 sshd 的日志,默认是 Auth
TCPKeepAlive yes:指定打开 sshd 跟客户端 TCP 连接的 keepalive 参数
UseDNS yes:指定用户 SSH 登录一个域名时,服务器是否使用 DNS,确认该域名对应的 IP 地址包含本机。建议关闭
UseLogin no:指定用户认证内部是否使用/usr/bin/login替代 SSH 工具,默认为no
UsePrivilegeSeparation yes:指定用户认证通过以后,使用另一个子线程处理用户权限相关的操作,这样有利于提高安全性。默认值为yes
VerboseMode yes:指定日志输出详细的 Debug 信息。SSH 2 版本专用
X11Forwarding no:指定是否打开 X window 的转发,默认值为 no
  • sshd 命令行配置项


sshd 命令有一些配置项。这些配置项在调用时指定,可以覆盖配置文件的设置
-d:显示 debug 信息
-D:指定 sshd 不作为后台守护进程运行
-e:将 sshd 写入 syslog 的内容,输出到 standard error
-f:使用指定的配置文件
-h:使用指定的密钥
-o:指定配置文件的一个配置项和对应的值,可以多个一起使用
-p:指定 sshd 的服务端口,可以指定多个端口
-t:检查配置文件的语法是否正确


sshd -o "Port 2222"    # 配置项和对应值之间,可以使用空格或等号
sshd -o Port=2222      # 如果省略等号前后的空格,也可以不使用引号
sshd -p 22 -p 2222     # 指定 sshd 的服务端口,可以指定多个端口


只讲对的    不讲废的    

点关注不迷路    我们下期见~

关于ssh的评论 (共 条)

分享到微博请遵守国家法律