6. SSH使用与配置详解

1 SSH是什么?

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

实际使用中,我们往往使用它进行远程登录云主机。

需要注意的是,ssh是一种协议,而通常我们说的是实现了这种协议的软件,例如知名的openssh

2 安装openssh

一般linux系统都自带ssh,如果没有就可以安装一下

sudo apt update        #更新数据
sudo apt upgrade        #更新软件
sudo apt install openssh-server  #下载安装ssh服务的服务器
sudo apt install openssh-client  #下载安装ssh服务的客户端

这里给出的是ubuntu安装命令,其它系统请参考具体的安装命令

windows一般自带ssh客户端,如果没有可以参照官方文档教程进行安装

3 SSH客户端

ssh的安装位置为:

  • ubuntu 系统的位置是/usr/bin/ssh
  • Windows系统的位置是C:\Program Files\OpenSSH-Win64\ssh.exe

ssh 最常见的用途就是登录服务器,这要求服务器安装并正在运行 SSH 服务器软件。

ssh 登录服务器的命令如下:

ssh hostname

上面命令中,hostname是主机名,它可以是域名,也可能是 IP 地址或局域网内部的主机名。

不指定用户名的情况下,将使用客户端的当前用户名,作为远程服务器的登录用户名,如果要指定用户名,可以采用下面的语法:

ssh user@hostname    

上面的命令中,用户名和主机名写在一起了,之间使用@分隔。

用户名也可以使用ssh-l参数指定,这样的话,用户名和主机名就不用写在一起了。

ssh -l username host

ssh 默认连接服务器的22端口,-p参数可以指定其他端口。

ssh -p 8821 foo.com

上面命令连接服务器foo.com8821端口

3.1 连接过程

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

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

The authenticity of host 'foo.com (192.168.121.111)' can't be established.
ECDSA key fingerprint is SHA256:Vybt22mVXuNuB5unE++yowF7lgA/9/2bLSiO3qmYWBY.
Are you sure you want to continue connecting (yes/no)?

上面这段文字告诉用户,foo.com这台服务器的指纹是陌生的,让用户选择是否要继续连接(输入 yesno)。

所谓“服务器指纹”,指的是 SSH 服务器公钥的哈希值。每台 SSH 服务器都有唯一一对密钥,用于跟客户端通信,其中公钥的哈希值就可以用来识别服务器。

下面的命令可以查看某个公钥的指纹:

ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub

输出:

256 da:24:43:0b:2e:c1:3f:a1:84:13:92:01:52:b4:84:ff   (ECDSA)

上面的例子中,ssh-keygen -l -f命令会输出公钥/etc/ssh/ssh_host_ecdsa_key.pub的指纹。

ssh 会将本机连接过的所有服务器公钥的指纹,都储存在本机的~/.ssh/known_hosts文件中。每次连接服务器时,通过该文件判断是否为陌生主机(陌生公钥)。

在上面这段文字后面,输入yes,就可以将当前服务器的指纹也储存在本机~/.ssh/known_hosts文件中,并显示下面的提示。以后再连接的时候,就不会再出现警告了。

Warning: Permanently added 'foo.com (192.168.121.111)' (RSA) to the list of known hosts

然后,客户端就会跟服务器建立连接。接着,ssh 就会要求用户输入所要登录账户的密码。用户输入并验证密码正确以后,就能登录远程服务器的 Shell 了。

3.2 服务器变更

服务器指纹可以防止有人恶意冒充远程主机。如果服务器的密钥发生变更(比如重装了 SSH 服务器),客户端再次连接时,就会发生公钥指纹不吻合的情况。这时,客户端就会中断连接,并显示一段警告信息。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
77:a5:69:81:9b:eb:40:76:7b:13:04:a9:6c:f4:9c:5d.
Please contact your system administrator.
Add correct host key in /home/me/.ssh/known_hosts to get rid of this message.
Offending key in /home/me/.ssh/known_hosts:36

上面这段文字的意思是,该主机的公钥指纹跟~/.ssh/known_hosts文件储存的不一样,必须处理以后才能连接。这时,你需要确认是什么原因,使得公钥指纹发生变更,到底是恶意劫持,还是管理员变更了 SSH 服务器公钥。

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

ssh-keygen -R hostname

上面命令中,hostname是发生公钥变更的主机名。

除了使用上面的命令,你也可以手工修改known_hosts文件,将公钥指纹删除。

删除了原来的公钥指纹以后,重新执行 ssh 命令连接远程服务器,将新的指纹加入known_hosts文件,就可以顺利连接了。

3.3 参数选择

常用几个参数如下:

  • -i:指定密钥文件登录sshd服务器
  • -C:压缩数据传输
  • -F:指定配置文件

3.4 配置文件

SSH 客户端的全局配置文件是/etc/ssh/ssh_config,用户个人的配置文件在~/.ssh/config,优先级高于全局配置文件。

除了配置文件,~/.ssh目录还有一些用户个人的密钥文件和其他文件。下面是其中一些常见的文件。

  • ~/.ssh/id_ecdsa:用户的 ECDSA 私钥。
  • ~/.ssh/id_ecdsa.pub:用户的 ECDSA 公钥。
  • ~/.ssh/id_rsa:用于 SSH 协议版本2 的 RSA 私钥。
  • ~/.ssh/id_rsa.pub:用于SSH 协议版本2 的 RSA 公钥。
  • ~/.ssh/identity:用于 SSH 协议版本1 的 RSA 私钥。
  • ~/.ssh/identity.pub:用于 SSH 协议版本1 的 RSA 公钥。
  • ~/.ssh/known_hosts:包含 SSH 服务器的公钥指纹。

用户个人的配置文件~/.ssh/config,可以按照不同服务器,列出各自的连接参数,从而不必每一次登录都输入重复的参数。下面是一个例子:

Host *
     Port 2222

Host remoteserver
     HostName remote.example.com
     User neo
     Port 2112

上面代码中,Host *表示对所有主机生效,后面的Port 2222表示所有主机的默认连接端口都是2222,这样就不用在登录时特别指定端口了。

这里的缩进并不是必需的,只是为了视觉上,易于识别针对不同主机的设置。

后面的Host remoteserver表示,下面的设置只对主机remoteserver生效。remoteserver只是一个别名,具体的主机由HostName命令指定

UserPort这两项分别表示用户名和端口。这里的Port会覆盖上面Host *部分的Port设置。

以后,登录remote.example.com时,只要执行ssh remoteserver命令,就会自动套用 config 文件里面指定的参数。 单个主机的配置格式如下。

ssh remoteserver

等同于

ssh -p 2112 neo@remote.example.com

Host命令的值可以使用通配符,比如Host *表示对所有主机都有效的设置,Host *.edu表示只对一级域名为.edu的主机有效的设置。它们的设置都可以被单个主机的设置覆盖。

3.5 可选的配置选项

常用的配置选项如下:

  • AddressFamily inet:表示只使用 IPv4 协议。如果设为inet6,表示只使用 IPv6 协议。
  • CheckHostIP yes:检查 SSH 服务器的 IP 地址是否跟公钥数据库吻合。
  • Host server.example.com:指定连接的域名或 IP 地址,也可以是别名,支持通配符。Host命令后面的所有配置,都是针对该主机的,直到下一个Host命令为止。
  • HostKeyAlgorithms ssh-dss,ssh-rsa:指定密钥算法,优先级从高到低排
  • HostName myserver.example.com:在Host命令使用别名的情况下,HostName指定域名或 IP 地址。
  • IdentityFile keyfile:指定私钥文件。
  • PasswordAuthentication no:指定是否支持密码登录。不过,这里只是客户端禁止,真正的禁止需要在 SSH 服务器设置。
  • Port 2035:指定客户端连接的 SSH 服务器端口。
  • PubKeyAuthentication yes:是否支持密钥登录。这里只是客户端设置,还需要在SSH 服务器进行相应设置。

4 SSH服务器

SSH 的架构是服务器/客户端模式,两端运行的软件是不一样的。OpenSSH 的客户端软件是 ssh,服务器软件是 sshd。

sshd

上面的命令运行后,如果提示sshd re-exec requires execution with an absolute path,就需要使用绝对路径来启动。

这是为了防止有人出于各种目的,放置同名软件在$PATH变量指向的目录中,代替真正的 sshd。

可以使用以下命令查找位置

which sshd

结果:

/usr/sbin/sshd

然后进行使用:

 /usr/sbin/sshd

使用方法:

sudo service ssh start # 启用
sudo service ssh restart # 重启
sudo service ssh stop # 停止

下面的命令让 sshd 在计算机下次启动时自动运行:

sudo systemctl enable sshd.service

4.1 配置文件

sshd 的配置文件在/etc/ssh目录,主配置文件是sshd_config,此外还有一些安装时生成的密钥。

  • /etc/ssh/sshd_config:配置文件
  • /etc/ssh/ssh_host_ecdsa_key:ECDSA 私钥。
  • /etc/ssh/ssh_host_ecdsa_key.pub:ECDSA 公钥。
  • /etc/ssh/ssh_host_key:用于 SSH 1 协议版本的 RSA 私钥。
  • /etc/ssh/ssh_host_key.pub:用于 SSH 1 协议版本的 RSA 公钥。
  • /etc/ssh/ssh_host_rsa_key:用于 SSH 2 协议版本的 RSA 私钥。
  • /etc/ssh/ssh_host_rsa_key.pub:用于 SSH 2 协议版本的 RSA 公钥。
  • /etc/pam.d/sshd:PAM 配置文件。

注意,如果重装 sshd,上面这些密钥都会重新生成,导致客户端重新 ssh 连接服务器时,会跳出警告,拒绝连接。为了避免这种情况,可以在重装 sshd 时,先备份/etc/ssh目录,重装后再恢复这个目录。

配置文件sshd_config的格式是,每个命令占据一行。每行都是配置项和对应的值,配置项的大小写不敏感,与值之间使用空格分隔:

Port 2034

上面的配置命令指定,配置项Port的值是2034。Port写成port也可。

配置文件还有另一种格式,就是配置项与值之间有一个等号,等号前后的空格可选:

Port = 2034

配置文件里面,#开头的行表示注释。

# 这是一行注释

注意,注释只能放在一行的开头,不能放在一行的结尾。

Port 2034 # 此处不允许注释

上面的写法是错误的,另外,空行等同于注释。

sshd 启动时会自动读取默认的配置文件。如果希望使用其他的配置文件,可以用 sshd 命令的-f参数指定。

sshd -f /usr/local/ssh/my_config

上面的命令指定 sshd 使用另一个配置文件my_config。

修改配置文件以后,可以用 sshd 命令的-t(test)检查有没有语法错误。

 sshd -t

配置文件修改以后,并不会自动生效,必须重新启动 sshd。

sudo service ssh restart 

4.2 密钥

sshd 有自己的一对或多对密钥。它使用密钥向客户端证明自己的身份。所有密钥都是公钥和私钥成对出现,公钥的文件名一般是私钥文件名加上后缀.pub。

DSA 格式的密钥文件默认为/etc/ssh/ssh_host_dsa_key(公钥为ssh_host_dsa_key.pub),RSA 格式的密钥为/etc/ssh/ssh_host_rsa_key(公钥为ssh_host_rsa_key.pub)。

如果需要支持 SSH 1 协议,则必须有密钥/etc/ssh/ssh_host_key。

如果密钥不是默认文件,那么可以通过配置文件sshd_config的HostKey配置项指定。默认密钥的HostKey设置如下。

# 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_ke

上面命令前面的#表示这些行都是注释,因为这是默认值,有没有这几行都一样。

如果要修改密钥,就要去掉行首的#,指定其他密钥。

HostKey /usr/local/ssh/my_dsa_key
HostKey /usr/local/ssh/my_rsa_key
HostKey /usr/local/ssh/my_old_ssh1_key

以下是对原文的精要提炼,去除了不常用或版本特有(如 SSH1 专用)内容,并重新组织为结构清晰、重点突出的总结。


4.3 常用 sshd 命令参数

  • -d:打印 debug 信息,前台运行一次连接过程。
  • -D:前台运行,不转为守护进程。
  • -e:将日志输出到 stderr。
  • -f <file>:指定配置文件。
  • -h <key>:指定密钥文件。
  • -o <option=val>:临时设置配置项,可多个使用。
  • -p <port>:指定监听端口,支持多个。
  • -t:检查配置文件语法。

故障提示解决:

  • sshd re-exec requires execution with an absolute path:使用绝对路径,如 /usr/sbin/sshd
  • no hostkeys available -- exiting.:使用 sudo 启动或执行 sudo ssh-keygen -A 创建密钥。

4.4 常用配置项

配置项所在文件:/etc/ssh/sshd_config

4.4.1 认证控制

  • PasswordAuthentication no:关闭密码登录,仅使用密钥。
  • PermitRootLogin no|prohibit-password:禁用 root 登录或仅允许密钥。
  • PubkeyAuthentication yes:启用公钥认证。
  • PermitEmptyPasswords no:禁止空密码登录。
  • AllowUsers user1 user2:允许登录的用户。
  • DenyUsers userX:禁止登录的用户。
  • AllowGroups group1 / DenyGroups groupX:按用户组限制登录。

4.4.2 连接行为

  • Port 22:监听端口,可设置多个。
  • ListenAddress 0.0.0.0:监听地址,也可设定为内网 IP。
  • ClientAliveInterval 180:客户端静默多久后发送探测(秒)。
  • ClientAliveCountMax 3:探测失败几次后断开连接。
  • MaxAuthTries 3:最大认证尝试次数。
  • MaxStartups 10:50:20:控制并发连接。

4.4.3 安全与日志

  • StrictModes yes:检查用户文件权限(建议开启)。
  • LogLevel INFO|DEBUG:日志级别。
  • UseDNS no:禁用 DNS 反查,提高连接速度。

4.4.4 其他常见项

  • AuthorizedKeysFile .ssh/authorized_keys:公钥存储路径。
  • Banner /path/to/file:登录前显示公告。
  • Compression yes:启用压缩传输。
  • ChallengeResponseAuthentication no:关闭键盘交互认证。
  • X11Forwarding no:是否启用 X11 图形转发。
  • LoginGraceTime 60:登录等待超时时间(秒)。

4.5 配置调试与重启

  • 检查配置:sshd -t
  • 重启服务:sudo service ssh restart