# Linux 认证机制详解 - 用户身份验证与访问控制

URL: https://caijiao.org/linux/security/authentication
Source: docs/linux/security/authentication.md
Description: 深入探讨 Linux 系统中的认证机制，包括密码认证、SSH 密钥认证、PAM 模块、双因素认证及相关配置最佳实践。

## 1. 认证基础概念

### 1.1 认证、授权与审计 (AAA)

Linux 安全模型基于三个核心概念：

- **认证（Authentication）**：验证用户身份的过程
- **授权（Authorization）**：确定已认证用户可以执行哪些操作的过程
- **审计（Accounting）**：记录用户活动和系统事件的过程

这三个概念共同构成了 AAA 安全框架，是 Linux 安全系统的基础。

### 1.2 认证因素类型

Linux 支持多种认证因素类型：

- **知识因素**：用户知道的信息（如密码、PIN码）
- **所有权因素**：用户拥有的物品（如密钥、证书、安全令牌）
- **固有因素**：用户本身的特征（如生物识别信息）
- **位置因素**：基于用户位置的认证
- **时间因素**：基于时间的访问控制

多因素认证（MFA）结合了两种或更多不同类型的因素，提供更强的安全性。

## 2. 密码认证机制

### 2.1 密码存储机制

Linux 系统中的密码存储经历了从明文到加盐哈希的演进：

- **早期系统**：密码存储在 `/etc/passwd` 文件中（明文或简单加密）
- **现代系统**：密码哈希值存储在 `/etc/shadow` 文件中，受严格权限保护（600）

### 2.2 密码哈希算法

Linux 支持多种密码哈希算法：

- **MD5**（较旧，不安全）
- **SHA-256/512**
- **Blowfish**（bcrypt）
- **Argon2**（现代安全算法，在较新的发行版中使用）

密码哈希通常以特定格式存储在 `/etc/shadow` 文件中：
```
$id$salt$hash
```

其中 `id` 表示使用的哈希算法：
- `$1$`：MD5
- `$2a$`, `$2b$`, `$2y$`：Blowfish
- `$5$`：SHA-256
- `$6$`：SHA-512
- `$argon2i$`, `$argon2id$`：Argon2

### 2.3 密码策略配置

在 Linux 中，可以通过以下方式配置密码策略：

- **`/etc/login.defs`**：全局密码策略配置文件
- **`chage` 命令**：管理用户密码过期信息
- **`pam_pwquality`/`pam_cracklib`**：密码强度检查模块

**示例：login.defs 配置**
```bash
# 密码最长有效期（天）
PASS_MAX_DAYS   90

# 密码最短有效期（天）
PASS_MIN_DAYS   7

# 密码过期前警告天数
PASS_WARN_AGE   14

# 密码最小长度
PASS_MIN_LEN    12

# 密码重试次数
LOGIN_RETRIES   3
```

### 2.4 密码强度控制

使用 PAM 模块加强密码强度要求：

**安装密码质量检查模块**
```bash
# Debian/Ubuntu
sudo apt install libpam-pwquality

# CentOS/RHEL
sudo yum install pam_pwquality
```

**配置密码强度要求**（编辑 `/etc/security/pwquality.conf`）
```bash
# 最小密码长度
minlen = 12

# 最少需要的大写字母数
ucredit = -1

# 最少需要的小写字母数
lcredit = -1

# 最少需要的数字数
dcredit = -1

# 最少需要的特殊字符数
ocredit = -1

# 与旧密码不同的字符数
difok = 3

# 禁止使用的用户名相关部分
enforce_for_root
```

## 3. PAM (Pluggable Authentication Modules)

### 3.1 PAM 概述

PAM（可插拔认证模块）是 Linux 系统中的一个灵活的认证框架，允许系统管理员为各种应用程序和服务配置不同的认证方式，而无需修改应用程序本身。

### 3.2 PAM 配置文件

PAM 配置主要包括：

- **主配置目录**：`/etc/pam.d/`
  - 每个服务一个配置文件，如 `/etc/pam.d/sshd`, `/etc/pam.d/sudo`
- **模块配置目录**：`/etc/security/`
- **核心配置文件**：`/etc/pam.conf`（旧式，现代系统较少使用）

### 3.3 PAM 配置语法

PAM 配置文件中的每行格式为：

```
类型 控制标志 模块路径 [模块选项]
```

**类型（管理组）**：
- `auth`：认证管理
- `account`：账户管理
- `password`：密码管理
- `session`：会话管理

**控制标志**：
- `required`：模块必须成功，失败会在所有模块执行后才返回
- `requisite`：模块必须成功，失败立即返回
- `sufficient`：如果成功且之前没有 `required` 失败，则成功；失败被忽略
- `optional`：模块结果被忽略，除非它是唯一的模块
- `include`：包含其他 PAM 配置文件
- `substack`：包含其他 PAM 配置文件，但作为子栈处理

### 3.4 常用 PAM 模块

**认证模块**：
- `pam_unix.so`：标准 Unix 认证
- `pam_ldap.so`：LDAP 认证
- `pam_google_authenticator.so`：Google Authenticator 双因素认证
- `pam_ssh.so`：SSH 密钥认证

**账户管理模块**：
- `pam_access.so`：基于登录访问控制表的账户管理
- `pam_time.so`：基于时间的访问控制
- `pam_tally2.so`：登录失败计数和锁定

**密码管理模块**：
- `pam_unix.so`：密码更新
- `pam_pwquality.so`：密码强度检查
- `pam_passwdqc.so`：密码复杂度策略

**会话管理模块**：
- `pam_unix.so`：标准会话管理
- `pam_limits.so`：资源限制设置
- `pam_mkhomedir.so`：自动创建用户主目录

### 3.5 PAM 配置示例

**示例 1：配置登录失败锁定**（编辑 `/etc/pam.d/system-auth` 或 `/etc/pam.d/common-auth`）
```bash
auth required pam_tally2.so deny=5 unlock_time=1800 even_deny_root root_unlock_time=1800
```

**示例 2：配置会话资源限制**（编辑 `/etc/pam.d/common-session`）
```bash
session required pam_limits.so
```

**示例 3：自动创建用户主目录**（编辑 `/etc/pam.d/common-session`）
```bash
session optional pam_mkhomedir.so skel=/etc/skel/ umask=0022
```

## 4. SSH 密钥认证

### 4.1 SSH 认证方式

SSH（Secure Shell）支持多种认证方式：

- **密码认证**：基于用户名和密码
- **公钥认证**：基于非对称密钥对
- **主机基于认证**：基于客户端主机密钥
- **键盘交互式认证**：基于一次性密码或挑战-响应
- **GSSAPI 认证**：用于 Kerberos 等企业环境

### 4.2 SSH 公钥认证设置

**客户端设置**：
```bash
# 生成 SSH 密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
# 或使用 RSA（兼容性更好但安全性较低）
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 将公钥复制到服务器
ssh-copy-id user@server_ip
```

**服务器端配置**（编辑 `/etc/ssh/sshd_config`）：
```bash
# 禁用密码认证
PasswordAuthentication no

# 启用公钥认证
PubkeyAuthentication yes

# 指定授权密钥文件
AuthorizedKeysFile      .ssh/authorized_keys

# 禁用 root 登录
PermitRootLogin no
```

**重启 SSH 服务**：
```bash
# Debian/Ubuntu
sudo systemctl restart sshd

# CentOS/RHEL
sudo systemctl restart sshd
```

### 4.3 SSH 密钥安全最佳实践

- 使用强加密算法（ed25519 或至少 RSA 4096 位）
- 为 SSH 密钥设置强密码
- 使用 ssh-agent 管理密钥
- 定期轮换密钥
- 限制 SSH 访问的来源 IP
- 监控 SSH 登录尝试

## 5. 双因素认证 (2FA)

### 5.1 双因素认证概述

双因素认证结合了两种不同类型的认证因素，大幅提高了账户安全性。常见的 Linux 双因素认证实现包括：

- **基于时间的一次性密码（TOTP）**：如 Google Authenticator
- **硬件安全密钥**：如 YubiKey
- **短信或电子邮件验证码**

### 5.2 Google Authenticator 配置

**安装依赖**：
```bash
# Debian/Ubuntu
sudo apt install libpam-google-authenticator

# CentOS/RHEL
sudo yum install google-authenticator
```

**为用户配置**：
```bash
# 以需要使用 2FA 的用户身份运行
google-authenticator
```

按照提示进行配置，记录生成的二维码和备份码。

**配置 SSH 使用 Google Authenticator**（编辑 `/etc/pam.d/sshd`）：
```bash
auth required pam_google_authenticator.so
```

**修改 SSH 配置**（编辑 `/etc/ssh/sshd_config`）：
```bash
# 启用挑战响应认证
ChallengeResponseAuthentication yes

# 禁用密码认证（如果只使用密钥+2FA）
PasswordAuthentication no

# 配置认证方法顺序
AuthenticationMethods publickey,keyboard-interactive
```

**重启 SSH 服务**：
```bash
sudo systemctl restart sshd
```

### 5.3 YubiKey 配置

**安装 YubiKey PAM 模块**：
```bash
# Debian/Ubuntu
sudo apt install libpam-yubico

# CentOS/RHEL
sudo yum install pam_yubico
```

**配置 PAM**（编辑 `/etc/pam.d/sshd`）：
```bash
# 使用 YubiCloud 验证
auth required pam_yubico.so id=16 debug

# 或使用本地验证
auth required pam_yubico.so mode=client chalresp_path=/usr/local/lib/yubico
```

**配置 SSH** 类似于 Google Authenticator 设置。

## 6. 集中式认证系统

### 6.1 LDAP 认证

LDAP（轻量级目录访问协议）提供了集中式用户管理和认证服务，适用于企业环境。

**安装 LDAP 客户端**：
```bash
# Debian/Ubuntu
sudo apt install libpam-ldap libnss-ldap ldap-utils

# CentOS/RHEL
sudo yum install openldap-clients nss-pam-ldapd
```

**配置 PAM 模块**（编辑 `/etc/pam.d/common-auth` 和 `/etc/pam.d/common-account`）：
```bash
# 认证
auth sufficient pam_ldap.so

# 账户管理
account sufficient pam_ldap.so
```

### 6.2 Kerberos 认证

Kerberos 是一种网络认证协议，使用票据系统进行安全认证。

**安装 Kerberos 客户端**：
```bash
# Debian/Ubuntu
sudo apt install krb5-user libpam-krb5

# CentOS/RHEL
sudo yum install krb5-workstation pam_krb5
```

**配置 PAM 模块**（编辑 `/etc/pam.d/common-auth`）：
```bash
auth sufficient pam_krb5.so use_first_pass
```

### 6.3 Active Directory 集成

在企业环境中，Linux 系统可以集成到 Microsoft Active Directory 中：

**使用 Samba Winbind**：
```bash
# Debian/Ubuntu
sudo apt install samba winbind libpam-winbind

# CentOS/RHEL
sudo yum install samba-winbind samba-winbind-clients pam_krb5
```

**配置 Winbind**（编辑 `/etc/samba/smb.conf`）：
```ini
[global]
   workgroup = EXAMPLE
   realm = EXAMPLE.COM
   security = ads
   winbind enum users = yes
   winbind enum groups = yes
   template homedir = /home/%D/%U
   template shell = /bin/bash
   winbind use default domain = yes
   kerberos method = secrets and keytab
```

**加入域**：
```bash
sudo net ads join -U administrator
```

## 7. 单点登录 (SSO) 解决方案

### 7.1 SSO 概述

单点登录允许用户使用一组凭据访问多个系统和应用程序，提高了安全性和用户体验。

### 7.2 使用 SSSD 的 SSO

SSSD（System Security Services Daemon）提供了一种灵活的方式来集成各种身份源：

**安装 SSSD**：
```bash
# Debian/Ubuntu
sudo apt install sssd sssd-tools

# CentOS/RHEL
sudo yum install sssd sssd-tools
```

**配置 SSSD**（编辑 `/etc/sssd/sssd.conf`）：
```ini
[sssd]
domains = example.com
config_file_version = 2
services = nss, pam

[domain/example.com]
ad_server = dc.example.com
krb5_realm = EXAMPLE.COM
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
homedir = /home/%u@%d
ad_domain = example.com
use_fully_qualified_names = True
fallback_homedir = /home/%d/%u
access_provider = ad
```

**重启 SSSD 服务**：
```bash
sudo systemctl restart sssd
```

### 7.3 OAuth 2.0 和 OpenID Connect

对于 Web 应用程序，可以使用 OAuth 2.0 和 OpenID Connect 实现 SSO：

- **Keycloak**：开源的身份和访问管理解决方案
- **Auth0**：商业身份即服务平台
- **Okta**：企业身份管理服务

## 8. 登录安全增强

### 8.1 使用 Fail2ban 防止暴力破解

**安装 Fail2ban**：
```bash
# Debian/Ubuntu
sudo apt install fail2ban

# CentOS/RHEL
sudo yum install fail2ban
```

**配置 Fail2ban**（创建 `/etc/fail2ban/jail.local`）：
```ini
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600
```

**启动 Fail2ban 服务**：
```bash
sudo systemctl enable --now fail2ban
```

### 8.2 限制登录尝试次数

使用 PAM 模块限制登录尝试次数：

**编辑 `/etc/pam.d/system-auth`**：
```bash
auth required pam_tally2.so deny=3 unlock_time=1800
```

**查看和管理失败计数**：
```bash
# 查看所有用户的失败计数
sudo pam_tally2

# 查看特定用户的失败计数
sudo pam_tally2 -u username

# 重置用户的失败计数
sudo pam_tally2 -u username -r
```

### 8.3 基于时间和位置的访问控制

**基于时间的访问控制**（编辑 `/etc/security/time.conf`）：
```
login;*;*;!Wd0000-2400
sshd;*;*;!Wk0800-1800
```

**配置 PAM 使用时间规则**（编辑 `/etc/pam.d/sshd`）：
```bash
auth required pam_time.so
```

**基于 IP 的访问控制**（编辑 `/etc/hosts.allow` 和 `/etc/hosts.deny`）：
```bash
# /etc/hosts.allow
sshd: 192.168.1.

# /etc/hosts.deny
sshd: ALL
```

## 9. 安全最佳实践

### 9.1 密码管理最佳实践

- 使用密码管理器生成和存储强密码
- 实施定期密码轮换策略
- 禁止重复使用之前的密码
- 为特权账户使用更长、更复杂的密码
- 考虑使用密码短语而不是单个密码

### 9.2 认证系统审计

定期审计认证系统：

- 检查 `/etc/shadow` 文件中的弱密码哈希
- 审查 PAM 配置是否符合安全标准
- 检查 SSH 配置的安全性
- 验证认证日志中的异常活动
- 检查未使用的账户和过期凭据

### 9.3 安全强化建议

- 实施最小权限原则
- 定期更新系统和应用程序
- 使用多因素认证保护所有关键系统
- 禁用不必要的认证方法
- 限制特权账户的远程访问
- 加密存储敏感凭据
- 监控认证尝试和失败

## 10. 总结

Linux 提供了丰富而灵活的认证机制，可以根据不同的安全需求和环境进行配置。从基本的密码认证到高级的双因素认证和集中式认证系统，Linux 认证框架能够满足从个人用户到大型企业的各种安全需求。

通过正确配置和结合使用这些认证机制，组织可以显著提高系统安全性，防止未授权访问，保护敏感数据和资源。定期的安全审计和最佳实践的实施对于维护强大的认证系统至关重要。

在当今复杂的网络安全环境中，单一的认证方式往往不足以提供足够的保护。采用多层防御策略，结合强密码策略、双因素认证、访问控制和安全监控，是构建健壮的 Linux 认证系统的关键。
