436 lines
14 KiB
Markdown
436 lines
14 KiB
Markdown
---
|
||
id: 服务器
|
||
title: 服务器
|
||
sidebar_position: 4
|
||
data: 2022年4月13日
|
||
---
|
||
## 简介
|
||
|
||
SSH 的架构是服务器/客户端模式,两端运行的软件是不一样的。OpenSSH 的客户端软件是 ssh,服务器软件是 sshd。本章介绍 sshd 的各种知识。
|
||
|
||
如果没有安装 sshd,可以用下面的命令安装。
|
||
|
||
```bash
|
||
# Debian
|
||
$ sudo aptitude install openssh-server
|
||
|
||
# Red Hat
|
||
$ sudo yum install openssh-server
|
||
```
|
||
|
||
一般来说,sshd 安装后会跟着系统一起启动。如果当前 sshd 没有启动,可以用下面的命令启动。
|
||
|
||
```bash
|
||
sshd
|
||
```
|
||
|
||
上面的命令运行后,如果提示“sshd re-exec requires execution with an absolute path”,就需要使用绝对路径来启动。这是为了防止有人出于各种目的,放置同名软件在`$PATH`变量指向的目录中,代替真正的 sshd。
|
||
|
||
```bash
|
||
# Centos、Ubuntu、OS X
|
||
$ /usr/sbin/sshd
|
||
```
|
||
|
||
上面的命令运行以后,sshd 自动进入后台,所以命令后面不需要加上`&`。
|
||
|
||
除了直接运行可执行文件,也可以通过 Systemd 启动 sshd。
|
||
|
||
```bash
|
||
# 启动
|
||
$ sudo systemctl start sshd.service
|
||
|
||
# 停止
|
||
$ sudo systemctl stop sshd.service
|
||
|
||
# 重启
|
||
$ sudo systemctl restart sshd.service
|
||
```
|
||
|
||
下面的命令让 sshd 在计算机下次启动时自动运行。
|
||
|
||
```bash
|
||
sudo systemctl enable sshd.service
|
||
```
|
||
|
||
## sshd 配置文件
|
||
|
||
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`的格式是,每个命令占据一行。每行都是配置项和对应的值,配置项的大小写不敏感,与值之间使用空格分隔。
|
||
|
||
```bash
|
||
Port 2034
|
||
```
|
||
|
||
上面的配置命令指定,配置项`Port`的值是`2034`。`Port`写成`port`也可。
|
||
|
||
配置文件还有另一种格式,就是配置项与值之间有一个等号,等号前后的空格可选。
|
||
|
||
```bash
|
||
Port = 2034
|
||
```
|
||
|
||
配置文件里面,`#`开头的行表示注释。
|
||
|
||
```bash
|
||
# 这是一行注释
|
||
```
|
||
|
||
注意,注释只能放在一行的开头,不能放在一行的结尾。
|
||
|
||
```bash
|
||
Port 2034 # 此处不允许注释
|
||
```
|
||
|
||
上面的写法是错误的。
|
||
|
||
另外,空行等同于注释。
|
||
|
||
sshd 启动时会自动读取默认的配置文件。如果希望使用其他的配置文件,可以用 sshd 命令的`-f`参数指定。
|
||
|
||
```bash
|
||
sshd -f /usr/local/ssh/my_config
|
||
```
|
||
|
||
上面的命令指定 sshd 使用另一个配置文件`my_config`。
|
||
|
||
修改配置文件以后,可以用 sshd 命令的`-t`(test)检查有没有语法错误。
|
||
|
||
```bash
|
||
sshd -t
|
||
```
|
||
|
||
配置文件修改以后,并不会自动生效,必须重新启动 sshd。
|
||
|
||
```bash
|
||
sudo systemctl restart sshd.service
|
||
```
|
||
|
||
## sshd 密钥
|
||
|
||
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`设置如下。
|
||
|
||
```bash
|
||
# 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
|
||
```
|
||
|
||
上面命令前面的`#`表示这些行都是注释,因为这是默认值,有没有这几行都一样。
|
||
|
||
如果要修改密钥,就要去掉行首的`#`,指定其他密钥。
|
||
|
||
```bash
|
||
HostKey /usr/local/ssh/my_dsa_key
|
||
HostKey /usr/local/ssh/my_rsa_key
|
||
HostKey /usr/local/ssh/my_old_ssh1_key
|
||
```
|
||
|
||
## sshd 配置项
|
||
|
||
以下是`/etc/ssh/sshd_config`文件里面的配置项。
|
||
|
||
**AcceptEnv**
|
||
|
||
`AcceptEnv`指定允许接受客户端通过`SendEnv`命令发来的哪些环境变量,即允许客户端设置服务器的环境变量清单,变量名之间使用空格分隔(`AcceptEnv PATH TERM`)。
|
||
|
||
**AllowGroups**
|
||
|
||
`AllowGroups`指定允许登录的用户组(`AllowGroups groupName`,多个组之间用空格分隔。如果不使用该项,则允许所有用户组登录。
|
||
|
||
**AllowUsers**
|
||
|
||
`AllowUsers`指定允许登录的用户,用户名之间使用空格分隔(`AllowUsers user1 user2`),也可以使用多行`AllowUsers`命令指定,用户名支持使用通配符。如果不使用该项,则允许所有用户登录。该项也可以使用`用户名@域名`的格式(比如`AllowUsers jones@example.com`)。
|
||
|
||
**AllowTcpForwarding**
|
||
|
||
`AllowTcpForwarding`指定是否允许端口转发,默认值为`yes`(`AllowTcpForwarding yes`),`local`表示只允许本地端口转发,`remote`表示只允许远程端口转发。
|
||
|
||
**AuthorizedKeysFile**
|
||
|
||
`AuthorizedKeysFile`指定储存用户公钥的目录,默认是用户主目录的`ssh/authorized_keys`目录(`AuthorizedKeysFile .ssh/authorized_keys`)。
|
||
|
||
**Banner**
|
||
|
||
`Banner`指定用户登录后,sshd 向其展示的信息文件(`Banner /usr/local/etc/warning.txt`),默认不展示任何内容。
|
||
|
||
**ChallengeResponseAuthentication**
|
||
|
||
`ChallengeResponseAuthentication`指定是否使用“键盘交互”身份验证方案,默认值为`yes`(`ChallengeResponseAuthentication yes`)。
|
||
|
||
从理论上讲,“键盘交互”身份验证方案可以向用户询问多重问题,但是实践中,通常仅询问用户密码。如果要完全禁用基于密码的身份验证,请将`PasswordAuthentication`和`ChallengeResponseAuthentication`都设置为`no`。
|
||
|
||
**Ciphers**
|
||
|
||
`Ciphers`指定 sshd 可以接受的加密算法(`Ciphers 3des-cbc`),多个算法之间使用逗号分隔。
|
||
|
||
**ClientAliveCountMax**
|
||
|
||
`ClientAliveCountMax`指定建立连接后,客户端失去响应时,服务器尝试连接的次数(`ClientAliveCountMax 8`)。
|
||
|
||
**ClientAliveInterval**
|
||
|
||
`ClientAliveInterval`指定允许客户端发呆的时间,单位为秒(`ClientAliveInterval 180`)。如果这段时间里面,客户端没有发送任何信号,SSH 连接将关闭。
|
||
|
||
**Compression**
|
||
|
||
`Compression`指定客户端与服务器之间的数据传输是否压缩。默认值为`yes`(`Compression yes`)
|
||
|
||
**DenyGroups**
|
||
|
||
`DenyGroups`指定不允许登录的用户组(`DenyGroups groupName`)。
|
||
|
||
**DenyUsers**
|
||
|
||
`DenyUsers`指定不允许登录的用户(`DenyUsers user1`),用户名之间使用空格分隔,也可以使用多行`DenyUsers`命令指定。
|
||
|
||
**FascistLogging**
|
||
|
||
SSH 1 版本专用,指定日志输出全部 Debug 信息(`FascistLogging yes`)。
|
||
|
||
**HostKey**
|
||
|
||
`HostKey`指定 sshd 服务器的密钥,详见前文。
|
||
|
||
**KeyRegenerationInterval**
|
||
|
||
`KeyRegenerationInterval`指定 SSH 1 版本的密钥重新生成时间间隔,单位为秒,默认是3600秒(`KeyRegenerationInterval 3600`)。
|
||
|
||
**ListenAddress**
|
||
|
||
`ListenAddress`指定 sshd 监听的本机 IP 地址,即 sshd 启用的 IP 地址,默认是 0.0.0.0(`ListenAddress 0.0.0.0`)表示在本机所有网络接口启用。可以改成只在某个网络接口启用(比如`ListenAddress 192.168.10.23`),也可以指定某个域名启用(比如`ListenAddress server.example.com`)。
|
||
|
||
如果要监听多个指定的 IP 地址,可以使用多行`ListenAddress`命令。
|
||
|
||
```bash
|
||
ListenAddress 172.16.1.1
|
||
ListenAddress 192.168.0.1
|
||
```
|
||
|
||
**LoginGraceTime**
|
||
|
||
`LoginGraceTime`指定允许客户端登录时发呆的最长时间,比如用户迟迟不输入密码,连接就会自动断开,单位为秒(`LoginGraceTime 60`)。如果设为`0`,就表示没有限制。
|
||
|
||
**LogLevel**
|
||
|
||
`LogLevel`指定日志的详细程度,可能的值依次为`QUIET`、`FATAL`、`ERROR`、`INFO`、`VERBOSE`、`DEBUG`、`DEBUG1`、`DEBUG2`、`DEBUG3`,默认为`INFO`(`LogLevel INFO`)。
|
||
|
||
**MACs**
|
||
|
||
`MACs`指定sshd 可以接受的数据校验算法(`MACs hmac-sha1`),多个算法之间使用逗号分隔。
|
||
|
||
**MaxAuthTries**
|
||
|
||
`MaxAuthTries`指定允许 SSH 登录的最大尝试次数(`MaxAuthTries 3`),如果密码输入错误达到指定次数,SSH 连接将关闭。
|
||
|
||
**MaxStartups**
|
||
|
||
`MaxStartups`指定允许同时并发的 SSH 连接数量(MaxStartups)。如果设为`0`,就表示没有限制。
|
||
|
||
这个属性也可以设为`A:B:C`的形式,比如`MaxStartups 10:50:20`,表示如果达到10个并发连接,后面的连接将有50%的概率被拒绝;如果达到20个并发连接,则后面的连接将100%被拒绝。
|
||
|
||
**PasswordAuthentication**
|
||
|
||
`PasswordAuthentication`指定是否允许密码登录,默认值为`yes`(`PasswordAuthentication yes`),建议改成`no`(禁止密码登录,只允许密钥登录)。
|
||
|
||
**PermitEmptyPasswords**
|
||
|
||
`PermitEmptyPasswords`指定是否允许空密码登录,即用户的密码是否可以为空,默认为`yes`(`PermitEmptyPasswords yes`),建议改成`no`(禁止无密码登录)。
|
||
|
||
**PermitRootLogin**
|
||
|
||
`PermitRootLogin`指定是否允许根用户登录,默认为`yes`(`PermitRootLogin yes`),建议改成`no`(禁止根用户登录)。
|
||
|
||
还有一种写法是写成`prohibit-password`,表示 root 用户不能用密码登录,但是可以用密钥登录。
|
||
|
||
```bash
|
||
PermitRootLogin prohibit-password
|
||
```
|
||
|
||
**PermitUserEnvironment**
|
||
|
||
`PermitUserEnvironment`指定是否允许 sshd 加载客户端的`~/.ssh/environment`文件和`~/.ssh/authorized_keys`文件里面的`environment= options`环境变量设置。默认值为`no`(`PermitUserEnvironment no`)。
|
||
|
||
**Port**
|
||
|
||
`Port`指定 sshd 监听的端口,即客户端连接的端口,默认是22(`Port 22`)。出于安全考虑,可以改掉这个端口(比如`Port 8822`)。
|
||
|
||
配置文件可以使用多个`Port`命令,同时监听多个端口。
|
||
|
||
```bash
|
||
Port 22
|
||
Port 80
|
||
Port 443
|
||
Port 8080
|
||
```
|
||
|
||
上面的示例表示同时监听4个端口。
|
||
|
||
**PrintMotd**
|
||
|
||
`PrintMotd`指定用户登录后,是否向其展示系统的 motd(Message of the day)的信息文件`/etc/motd`。该文件用于通知所有用户一些重要事项,比如系统维护时间、安全问题等等。默认值为`yes`(`PrintMotd yes`),由于 Shell 一般会展示这个信息文件,所以这里可以改为`no`。
|
||
|
||
**PrintLastLog**
|
||
|
||
`PrintLastLog`指定是否打印上一次用户登录时间,默认值为`yes`(`PrintLastLog yes`)。
|
||
|
||
**Protocol**
|
||
|
||
`Protocol`指定 sshd 使用的协议。`Protocol 1`表示使用 SSH 1 协议,建议改成`Protocol 2`(使用 SSH 2 协议)。`Protocol 2,1`表示同时支持两个版本的协议。
|
||
|
||
**PubKeyAuthentication**
|
||
|
||
`PubKeyAuthentication`指定是否允许公钥登录,默认值为`yes`(`PubKeyAuthentication yes`)。
|
||
|
||
**QuietMode**
|
||
|
||
SSH 1 版本专用,指定日志只输出致命的错误信息(`QuietMode yes`)。
|
||
|
||
**RSAAuthentication**
|
||
|
||
`RSAAuthentication`指定允许 RSA 认证,默认值为`yes`(`RSAAuthentication yes`)。
|
||
|
||
**ServerKeyBits**
|
||
|
||
`ServerKeyBits`指定 SSH 1 版本的密钥重新生成时的位数,默认是768(`ServerKeyBits 768`)。
|
||
|
||
**StrictModes**
|
||
|
||
`StrictModes`指定 sshd 是否检查用户的一些重要文件和目录的权限。默认为`yes`(`StrictModes yes`),即对于用户的 SSH 配置文件、密钥文件和所在目录,SSH 要求拥有者必须是根用户或用户本人,用户组和其他人的写权限必须关闭。
|
||
|
||
**SyslogFacility**
|
||
|
||
`SyslogFacility`指定 Syslog 如何处理 sshd 的日志,默认是 Auth(`SyslogFacility AUTH`)。
|
||
|
||
**TCPKeepAlive**
|
||
|
||
`TCPKeepAlive`指定打开 sshd 跟客户端 TCP 连接的 keepalive 参数(`TCPKeepAlive yes`)。
|
||
|
||
**UseDNS**
|
||
|
||
`UseDNS`指定用户 SSH 登录一个域名时,服务器是否使用 DNS,确认该域名对应的 IP 地址包含本机(`UseDNS yes`)。打开该选项意义不大,而且如果 DNS 更新不及时,还有可能误判,建议关闭。
|
||
|
||
**UseLogin**
|
||
|
||
`UseLogin`指定用户认证内部是否使用`/usr/bin/login`替代 SSH 工具,默认为`no`(`UseLogin no`)。
|
||
|
||
**UserPrivilegeSeparation**
|
||
|
||
`UserPrivilegeSeparation`指定用户认证通过以后,使用另一个子线程处理用户权限相关的操作,这样有利于提高安全性。默认值为`yes`(`UsePrivilegeSeparation yes`)。
|
||
|
||
**VerboseMode**
|
||
|
||
SSH 2 版本专用,指定日志输出详细的 Debug 信息(`VerboseMode yes`)。
|
||
|
||
**X11Forwarding**
|
||
|
||
`X11Forwarding`指定是否打开 X window 的转发,默认值为 no(`X11Forwarding no`)。
|
||
|
||
修改配置文件以后,可以使用下面的命令验证,配置文件是否有语法错误。
|
||
|
||
```bash
|
||
sshd -t
|
||
```
|
||
|
||
新的配置文件生效,必须重启 sshd。
|
||
|
||
```bash
|
||
sudo systemctl restart sshd
|
||
```
|
||
|
||
## sshd 的命令行配置项
|
||
|
||
sshd 命令有一些配置项。这些配置项在调用时指定,可以覆盖配置文件的设置。
|
||
|
||
(1)`-d`
|
||
|
||
`-d`参数用于显示 debug 信息。
|
||
|
||
```bash
|
||
sshd -d
|
||
```
|
||
|
||
(2)`-D`
|
||
|
||
`-D`参数指定 sshd 不作为后台守护进程运行。
|
||
|
||
```bash
|
||
sshd -D
|
||
```
|
||
|
||
(3)`-e`
|
||
|
||
`-e`参数将 sshd 写入系统日志 syslog 的内容导向标准错误(standard error)。
|
||
|
||
(4)`-f`
|
||
|
||
`-f`参数指定配置文件的位置。
|
||
|
||
(5)`-h`
|
||
|
||
`-h`参数用于指定密钥。
|
||
|
||
```bash
|
||
sshd -h /usr/local/ssh/my_rsa_key
|
||
```
|
||
|
||
(6)`-o`
|
||
|
||
`-o`参数指定配置文件的一个配置项和对应的值。
|
||
|
||
```bash
|
||
sshd -o "Port 2034"
|
||
```
|
||
|
||
配置项和对应值之间,可以使用等号。
|
||
|
||
```bash
|
||
sshd -o "Port = 2034"
|
||
```
|
||
|
||
如果省略等号前后的空格,也可以不使用引号。
|
||
|
||
```bash
|
||
sshd -o Port=2034
|
||
```
|
||
|
||
`-o`参数可以多个一起使用,用来指定多个配置关键字。
|
||
|
||
(7)`-p`
|
||
|
||
`-p`参数指定 sshd 的服务端口。
|
||
|
||
```bash
|
||
sshd -p 2034
|
||
```
|
||
|
||
上面命令指定 sshd 在`2034`端口启动。
|
||
|
||
`-p`参数可以指定多个端口。
|
||
|
||
```bash
|
||
sshd -p 2222 -p 3333
|
||
```
|
||
|
||
(8)`-t`
|
||
|
||
`-t`参数检查配置文件的语法是否正确。
|