运维安全06 - 服务安全

发布于:2025-09-14 ⋅ 阅读:(14) ⋅ 点赞:(0)

云计算服务安全

在当今数字化时代,各种服务(如网络应用、云计算平台、数据库系统等)已成为我们日常生活和工作中不可或缺的一部分。

然而,随着服务的广泛应用,其安全性问题也日益凸显。

一、服务安全

服务安全是一系列技术和管理措施的集合,旨在保障服务系统的正常运行和数据的安全。

它涵盖了从物理层面到软件层面的多个方面,包括但不限于:

  1. 访问控制:通过身份验证和授权机制,确保只有合法用户或进程能够访问特定的服务资源。

  2. 数据加密:对传输和存储的数据进行加密处理,防止数据在传输过程中被窃取或篡改。

  3. 安全审计:记录和分析系统操作日志,及时发现并应对潜在的安全威胁。

  4. 漏洞管理:定期检查和修复系统中的安全漏洞,减少被攻击的风险。

  5. 灾难恢复:制定应急响应计划和备份策略,确保在发生安全事件时能够迅速恢复服务。

服务安全是指保护这些服务免受未经授权的访问、数据泄露、恶意攻击等威胁,确保服务的可用性、完整性和保密性。

1.1 SELinux

SELinux(Security-Enhanced Linux)是 Linux 内核的一个安全模块,提供 强制访问控制(MAC)机制 ,通过预定义的安全策略来限制进程和资源之间的访问行为。

在当今数字化时代,服务如网络应用、云计算平台和数据库系统等已经成为日常生活和工作中不可或缺的一部分。随着这些技术的广泛应用,其安全性问题也日益凸显。

为了确保这些服务的安全性,采用多层次的安全策略变得尤为重要。

将云计算平台的安全需求与SELinux(Security-Enhanced Linux)所提供的强大安全功能相结合,以增强整体的服务安全性。

selinux与云平台的结合

1. 云计算环境中的多租户挑战

在云计算环境中,多租户架构是常见模式,这意味着多个用户或组织共享相同的物理资源,但各自拥有独立的虚拟环境。这种设置带来了独特的安全挑战,因为必须确保一个租户的操作不会影响到另一个租户的数据安全性和隐私。通过实施SELinux,可以基于细粒度的访问控制来隔离不同租户的工作负载,从而有效地防止潜在的安全威胁跨越租户边界。

2. 强化数据保护

无论是存储在云中的敏感数据还是通过网络传输的信息,都需要得到妥善保护。SELinux通过其灵活且强大的强制访问控制(MAC)机制,能够为文件、目录以及网络端口定义详细的访问规则。这意味着即使是操作系统级别的漏洞被利用,攻击者也无法轻易获取对关键数据的访问权限,极大地增强了数据的安全性。

3. 提升应用层防护

除了基础架构层面的安全措施外,针对运行于云端的应用程序本身也需要采取额外的安全防护措施。借助SELinux,开发者可以为特定应用程序定制安全策略,限制它们只能执行预期的行为,减少因代码缺陷导致的安全风险。这对于维护云上部署的应用程序的安全性至关重要。

4. 应对新兴威胁

随着技术的发展,新的安全威胁不断涌现。SELinux提供了一种动态调整安全策略的能力,允许管理员快速响应新出现的威胁。这使得无论是在公有云、私有云还是混合云环境中,都能够保持高水平的安全态势,保障业务连续性和数据完整性。

1.2 访问控制

访问控制是计算机安全领域的一个核心概念,旨在保护系统资源免受未经授权的访问。

主要存在两种类型的访问控制模型:自主访问控制(DAC)和强制访问控制(MAC)。

自主访问控制(DAC)
  • 自主性:在DAC中,资源的所有者有权决定谁可以访问这些资源以及访问的权限级别。

  • 基于用户身份验证:DAC依赖于用户的身份来分配权限,通常通过文件或目录的读、写、执行权限体现出来。

  • 灵活性高:由于权限是由资源所有者自行设置的,因此DAC提供了很高的灵活性,允许细粒度的权限管理。

在一个Linux系统中,有一个名为/home/user1/project的目录,属于用户user1

用户user1可以通过命令chmod 750 /home/user1/project设置该目录的权限为:

  • rwx(读、写、执行)对于所有者user1

  • r-x(读、执行)对于同组用户

  • ---(无权限)对于其他用户

这样,只有user1和他的组成员能够访问这个项目目录,而其他人则无法访问。

优缺点分析:

  • 优点:易于使用和配置,适合小规模环境。

  • 缺点:安全性较低,因为权限是由普通用户设置的,容易发生错误配置导致的安全漏洞。

强制访问控制(MAC)
  • 强制性:MAC是一种更严格的访问控制形式,它不依赖于用户的个人决策,而是根据预定义的安全策略来控制访问权限。

  • 基于安全标签:每个主体(如用户或进程)和客体(如文件或网络端口)都被赋予一个安0全标签,系统根据这些标签和安全策略决定是否允许访问。

  • 适用于高安全性需求场景:MAC通常用于需要高度安全保障的环境。

管理员配置了一个策略,规定Web服务器只能访问特定的网页内容目录,并且不能访问数据库文件。

即使以root用户身份运行,如果尝试访问未授权的资源,也将被拒绝。

在SELinux中,可以通过以下命令查看当前目录的安全上下文:

ls -Z /var/www/html

然后,管理员可以根据安全需求调整相关文件的安全标签,确保它们只被适当的进程访问。

优缺点分析:

  • 优点:提供了更高的安全性和更细粒度的控制,防止了权限滥用。

  • 缺点:配置复杂,不适合对安全性要求不高的普通用户。

1.2.1核心概念

名称 含义
主体(Subject) 如用户、进程
客体(Object) 文件、目录、端口等系统资源
安全上下文(Security Context) 格式:user:role:type[:level],标识主体或客体的身份
策略(Policy) 控制谁可以对哪些资源执行哪些操作
主体(Subject)

主体是指 发起操作的一方 ,通常是运行中的 进程或用户 。它是请求访问资源的“行为者”。

  • 当在终端中执行 cat /etc/passwd 命令时,这个命令对应的 bash 进程 就是主体。

  • Web 服务器(如 Nginx 或 Apache)运行的 nginx 进程 是一个典型的主体。

  • SSH 登录的用户通过 sshd 进程 发起操作,此时该进程就是主体。

主体 = “谁” 在做某件事(例如读取、写入、执行)。

客体(Object)

客体是 被访问的目标资源 ,可以是文件、目录、网络端口、设备等系统中的任何对象。

  • /etc/shadow 文件是一个客体,它保存了系统的密码信息。

  • /var/www/html/index.html 是一个网页文件,也是客体。

  • TCP 端口 80(HTTP)也是一个客体,Nginx 需要绑定它来提供服务。

客体 = “什么” 被访问或操作。

安全上下文(Security Context)

安全上下文是 SELinux 给每个 主体和客体 打上的“身份标签”,用于标识它们属于哪个用户、角色、类型和安全级别。

安全上下文 = “是谁?能做什么?” 的身份标签。

user:role:type[:level]
字段 说明
user SELinux 用户身份(不同于 Linux 操作系统用户)
role 角色,定义用户可以扮演哪些角色(如 sysadm_r 表示系统管理员角色)
type 类型,是最关键的部分,决定了访问权限
level 可选字段,用于多级安全策略(MLS),表示敏感级别(如 s0, s1:c0.c2)
ls -Z /etc/passwd
​
system_u:object_r:shadow_t:s0 /etc/passwd
  • system_u:SELinux 用户为系统用户

  • object_r:角色为对象角色

  • shadow_t:类型为 shadow 类型,只允许特定进程访问

  • s0:安全级别

在 SELinux 中,用户身份(User Identity)是安全上下文的一部分,用于标识系统中的主体(如进程、用户)。

尽管它被称为“用户”,但它与传统的 Linux 系统用户不同。

SELinux 用户身份主要用于定义哪些角色(Roles)和类型(Types)可以被分配给特定的用户或进程。

SELinux 用户 描述
system_u 用于系统进程和服务,默认适用于大多数后台服务。
root 特殊的 SELinux 用户,通常用于超级用户操作。
user_u 普通非特权用户的默认 SELinux 用户身份。
staff_u 提供给需要额外权限的管理员使用。

配置一个 Web 服务器(比如 Nginx),并且希望确保其运行在一个受限制的环境中:

系统服务使用system_u` :这里的system_u` 表明这是一个系统级别的进程,它只能承担系统级别的角色,并且只能访问与其类型匹配的资源。

普通用户使用user_u` :这意味着他们不能访问那些只允许system_u` 或其他特定类型访问的资源。

SELinux 使用角色来实现 用户到类型的映射 ,也就是说:

  • 某个用户(如 user_u)只能进入某些角色(如 user_r

  • 每个角色又允许使用某些类型(domain),也就是进程可以运行的上下文

通过定义不同的角色,SELinux 实现了 基于角色的访问控制(RBAC) ,不同角色有不同的权限范围。

角色名 描述
system_r 系统服务角色,适用于后台守护进程(如 Nginx、Apache)
object_r 对象角色,适用于文件、目录等资源对象
user_r 普通用户角色,限制较为严格
sysadm_r 系统管理员角色,具有更高的权限,适合执行系统管理任务
staff_r 高级用户角色,介于普通用户和管理员之间
unconfined_r 非受限角色,在宽松模式下使用

如果一个普通用户的安全上下文是:

user_u:user_r:user_t:s0

那么他只能运行属于 user_t 类型的程序,并且不能执行需要更高权限的操作,比如启动网络服务或访问 /etc/shadow 文件,即使 Linux 权限允许。

这是因为 SELinux 策略中没有为 user_r 角色分配这些权限。

在 SELinux 中,类型(Type) 是安全上下文中最重要的部分之一。

它决定了主体(如进程)和客体(如文件、目录、端口等)之间的访问权限。

通过定义哪些类型的主体可以访问哪些类型的客体,SELinux 实现了细粒度的强制访问控制(MAC)。

类型 描述
httpd_t Web 服务进程类型(Nginx/Apache)
httpd_sys_content_t Web 服务器内容文件类型
httpd_log_t Web 服务器日志文件类型
sshd_t SSH 服务进程类型
mysqld_t MySQL 数据库进程类型
user_t 普通用户进程类型

level 是可选的,表示 敏感级别或分类信息 。它主要用于实现更高级别的数据隔离和访问控制。

system_u:object_r:httpd_sys_content_t:s0

这里的 s0 就是 level 字段,表示最低的安全级别。

staff_u:staff_r:staff_t:s0:c0,c2

这里 s0:c0,c2 表示该对象/用户属于 s0 级别,并具有类别 c0c2

多级安全策略(MLS)

MLS 是一种经典的安全模型,将信息分为多个等级(Sensitivity Level) ,例如:

等级 描述
s0 非密级
s1 秘密
s2 机密
s3 绝密

MLS 规则:

  • 用户只能读取 等于或低于自己安全等级 的资源。

  • 用户只能写入 等于或高于自己安全等级 的资源。

这种方式保证了高安全等级的信息不会被低权限用户修改或泄露。

在大多数系统中,只用到了 s0 (最多支持到 s15),除非启用了 MLS(多级安全策略)并做了特殊配置。

多类别安全策略(MCS)

MCS 是 MLS 的一个轻量级变体,通常用于 Linux 桌面环境和容器中,比如 Docker。

MCS 使用“类别”(Categories)来对数据进行分类,而不是严格的等级划分。

s0:c0.c5 或 s0:c0,c2,c4

其中:

  • s0:统一使用最低等级

  • c0, c1, ..., c1023:最多支持 1024 个类别编号

MCS 规则:

  • 某个进程只能访问与其类别集合完全匹配或包含其类别的资源

  • 类似于标签机制,用于隔离不同用户的资源。

当运行一个 Docker 容器时,它可能会被自动赋予类似这样的上下文:

system_u:system_r:container_t:s0:c0,c2

这表示:

  • 这个容器进程属于:

    • SELinux 用户 system_u

    • 角色 system_r

    • 类型 container_t

    • 安全级别为 s0

    • 属于类别 c0c2

同时,它的文件系统也会被打上相同的标签。这样做的目的是:

让这个容器只能访问带有 c0,c2 类别的资源,不能访问其他容器的数据。

SELinux 中的 level 字段有以下几种形式:

格式 含义 示例
s0 单一层级(适用于 MLS 或 MCS) system_u:object_r:httpd_t:s0
s0-s15 层级范围(最小到最大) user_u:user_r:user_t:s0-s15
s0:c0.c1023 包含所有类别(常见于 MCS) staff_u:staff_r:staff_t:s0:c0.c1023
s0:c0,c2,c5 指定具体类别 root:sysadm_r:sysadm_t:s0:c0,c2,c5

使用 MCS 实现 Docker 容器隔离

当运行两个 Docker 容器时,它们会被自动分配不同的 MCS 标签,例如:

  • 容器 A:system_u:object_r:container_file_t:s0:c1,c2

  • 容器 B:system_u:object_r:container_file_t:s0:c3,c4

这确保了两个容器无法互相访问对方的文件系统,即使它们运行在同一台主机上。

问: 如果两个容器的 SELinux 标签都是 c1,那它们之间可以互相访问吗?

不一定能互相访问。

但至少在 SELinux 的 MCS(多类别安全)机制上,它们具备“可能被允许访问”的前提条件。

策略(Policy)

策略是 SELinux 的“规则本”,它是一组预定义的 访问控制规则 ,决定某个主体是否可以对某个客体执行某种操作。

  • 某个进程(如 httpd_t)是否可以读取 /var/www/html/ 下的文件(httpd_sys_content_t

  • 是否允许 nginx 访问非标准端口(如 8080)

  • 是否允许普通用户启动某些服务

策略 = “谁可以对什么做什么”的规则集合。

SELinux 策略包含了一系列 允许规则(allow rules) ,这些规则定义了哪些类型的主体可以对哪些类型的客体执行哪些操作。

allow httpd_t httpd_sys_content_t:file { read };

这条规则表示:

  • 主体类型 httpd_t(Web 服务器进程)

  • 可以对客体类型 httpd_sys_content_t(Web 服务器内容文件)

  • 执行 read 操作

实例分析

我们以 Nginx 为例,演示 SELinux 如何使用上述四个概念进行访问控制。

场景描述:

主体:nginx 进程(类型为 httpd_t

在 SELinux 中,每个运行中的进程都有一个 安全上下文(Security Context) ,其中包含它的 类型(type)

它是由 SELinux 策略模块(如 httpd.pp)中定义的,用于标识 Web 服务器进程的标准类型。

  • httpd_t:Web 服务进程本身

  • httpd_sys_content_t:网页文件

  • httpd_log_t:日志文件

  • httpd_port_t:允许绑定的端口

ps -Z -C nginx
​
LABEL                              PID TTY          TIME CMD
system_u:system_r:httpd_t:s0      5918 ?        00:00:00 nginx

客体:网页文件 /var/www/html/index.html(类型为 httpd_sys_content_t

ls -Z /usr/share/nginx/html/index.html
system_u:object_r:httpd_sys_content_t:s0 /usr/share/nginx/html/index.html

安全上下文:

  • 进程:system_u:system_r:httpd_t:s0

  • 文件:system_u:object_r:httpd_sys_content_t:s0

策略规则:

allow httpd_t httpd_sys_content_t : file { read };

由于策略允许 httpd_t 类型的进程读取 httpd_sys_content_t 类型的文件,所以 Nginx 成功加载页面内容。

如果文件的安全上下文不是 httpd_sys_content_t,比如是 user_t,那么即使权限正确,SELinux 也会阻止访问,并记录 AVC 日志。

1.3 运行模式

SELinux 是 Linux 系统中的一个 强制访问控制机制(MAC),它的行为取决于当前所处的运行模式。

可以通过以下命令查看当前 SELinux 模式:

SELinux 是 Linux 系统中的一个 强制访问控制机制(MAC),它的行为取决于当前所处的运行模式。

可以通过以下命令查看当前 SELinux 模式:

getenforce

输出可能是:

Enforcing

Permissive

Disabled
enforcing(强制模式)

这是 SELinux 的正常工作模式,也是最安全的模式。

在这个模式下,SELinux 不仅记录违规行为,还会实际阻止非法访问。

特性 描述
是否执行策略
是否阻止非法访问
是否记录日志 是(记录在 /var/log/audit/audit.log 中)
  • 生产环境必须启用此模式以保障系统安全

  • 所有服务和应用都已正确配置 SELinux 上下文和策略

如果运行了一个 Web 服务器(如 Nginx),但它试图访问一个没有被标记为 httpd_sys_content_t 的文件,SELinux 将直接拒绝访问,并记录到日志中。

permissive(宽容模式)

在这个模式下,SELinux 只记录违规行为,不会真正阻止任何操作。

特性 描述
是否执行策略
是否阻止非法访问
是否记录日志
  • 调试新服务时,避免因 SELinux 阻止导致服务启动失败

  • 排查 AVC(Access Vector Cache)拒绝日志

  • 测试自定义策略模块是否有效

如果服务因为 SELinux 标签错误而无法读取某个文件,在 permissive 模式下仍然可以运行,但会在日志中看到一条“AVC denied”信息。

disabled(禁用模式)

这个模式表示 完全关闭 SELinux,它不再加载策略、不记录、也不干预任何操作。

特性 描述
是否执行策略
是否阻止非法访问
是否记录日志
  • 在安装或调试阶段,为了快速排除 SELinux 干扰

  • 不需要 SELinux 提供额外安全保护的测试环境

注意:强烈不建议在生产环境中长期使用此模式,因为它会带来严重的安全风险。

模式 是否执行策略 是否阻止非法访问 是否记录日志 安全级别 推荐用途
enforcing 生产环境
permissive 调试、排错
disabled 完全不需要 SELinux 的环境

状态与模式管理

查看 SELinux 当前状态

sestatus

查看当前运行模式

getenforce

临时切换 SELinux 模式(无需重启)

setenforce 只能在 SELinux 未被永久禁用 的情况下使用。

# 切换到宽容模式
setenforce 0
​
# 切换回强制模式
setenforce 1

永久更改 SELinux 模式(需修改配置文件)

编辑配置文件:

sudo vi /etc/selinux/config

设置以下参数之一:

SELINUX=enforcing   # 推荐生产环境使用
# 或
SELINUX=permissive  # 调试时使用
# 或
SELINUX=disabled    # 不推荐,除非特殊需求

保存后重启系统生效:

reboot

1.4 安全上下文管理

查看文件/目录的 SELinux 上下文

ls -Z /usr/share/nginx/html/

输出格式:

system_u:object_r:httpd_sys_content_t:s0 index.html

修改文件类型(Type)

chcon -t httpd_sys_content_t /path/to/file
chcon -R -t httpd_sys_content_t /var/www/mynginx

让 Web 服务进程(如 Nginx 或 Apache)能够访问 /var/www/mynginx 目录下的内容。

因为 SELinux 默认策略中规定:

  • Web 服务进程运行在 httpd_t 类型下

  • 它只能访问具有 httpd_sys_content_t 类型的文件或目录

如果把网页文件放在一个没有正确打上 SELinux 标签的目录里(比如默认不是 /var/www/html),Nginx/Apache 可能会被 SELinux 拒绝访问,即使 Linux 文件权限是 755 也不行。

  1. 把网页文件放在了 /var/www/mynginx/index.html

  2. 启动了 Nginx

  3. 浏览器访问时出现 403 Forbidden 错误

检查 SELinux 日志(/var/log/audit/audit.log)可能会看到类似这样的 AVC 拒绝:

type=AVC msg=audit(1234567890.123:456): apparmor="DENIED" ...

或者:

type=AVC msg=audit(...): avc: denied { read } for pid=... comm="nginx" name="index.html" dev="..." ino=...

这说明 SELinux 阻止了 Nginx 对这个文件的访问。

此时运行:

chcon -R -t httpd_sys_content_t /var/www/mynginx

就能解决这个问题 —— 让 Nginx 正常读取这些文件。

使用 chcon 设置的是临时标签,重启后会丢失。

持久化设置

添加持久化规则

sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/mynginx(/.*)?"

应用更改

restorecon -Rv /var/www/mynginx

1.5 日志分析与调试

当 SELinux 阻止某个操作时(比如 Nginx 无法读取某个网页文件),就会生成一条 AVC denied 日志

这条日志会被记录到 /var/log/audit/audit.log

使用 ausearch -m avc 就可以查看这些“被拒绝的访问”记录

查看 SELinux 拒绝日志(AVC)

sudo ausearch -m avc -ts recent
​
查看最近发生的 SELinux 访问被拒绝事件

运行命令后,可能会看到类似这样的输出:

type=AVC msg=audit(1723456789.123:456): avc: denied { read } for pid=1234 comm="nginx" name="index.html" dev="sda1" ino=123456 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file
字段 含义
pid=1234 被拒绝的进程 PID
comm="nginx" 是哪个程序被拒绝(这里是 nginx)
name="index.html" 被访问的文件名
scontext=... 主体的安全上下文(即 nginx 进程的身份)
tcontext=... 客体的安全上下文(即 index.html 文件的身份)
tclass=file 被访问的目标类型是文件
{ read } 被拒绝的操作是“读取”

分析拒绝原因

sudo ausearch -m avc -ts recent | audit2why
​
Was caused by:
The type httpd_t is not allowed to read files of type default_t.

1.6 实战案例

正在部署一个基于 Nginx 的网站,并希望使用 SELinux 来保护该服务,防止未经授权的访问。

安装 Nginx 和 SELinux 工具

正在部署一个基于 Nginx 的网站,并希望使用 SELinux 来保护该服务,防止未经授权的访问。

安装 Nginx 和 SELinux 工具

sudo yum install -y nginx policycoreutils-python-utils setools setools-console

创建自定义网页目录并设置权限

sudo mkdir -p /var/www/mynginx
sudo echo "Hello from SELinux Protected Nginx" > /var/www/mynginx/index.html
sudo chown -R nginx:nginx /var/www/mynginx

步骤 3:设置正确的 SELinux 上下文

-- 设置SELinux规则
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/mynginx(/.*)?"
​
-- 重新加载规则
sudo restorecon -Rv /var/www/mynginx

步骤 4:配置 Nginx 使用新目录

编辑默认站点配置:

sudo vi /etc/nginx/nginx.conf

修改内容如下:

server {
    listen       80;
    server_name  localhost;
​
    location / {
        root   /var/www/mynginx;
        index  index.html index.htm;
        try_files $uri $uri/ =404;
    }
}

步骤 5:启动 Nginx 并测试访问

systemctl restart nginx

curl localhost

步骤 6:模拟 SELinux 拒绝并修复

将网页目录改为 /opt/mynginx,但未设置 SELinux 上下文,此时访问可能失败。

检查日志:

sudo ausearch -m avc -ts recent | audit2why

输出可能提示:

Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.

二、 加密技术介绍

随着云计算的广泛应用,数据在共享和传输过程中的安全性面临严峻挑战。

加密技术作为保障信息安全的核心手段,在云计算环境中发挥着至关重要的作用。

对称加密(Symmetric Encryption)

使用同一把密钥进行加密和解密。

想象有一个保险箱,用一把钥匙把它锁上,别人拿到这个保险箱后,也需要用同一把钥匙才能打开。

明文
  ↓
[ 加密 ] —— 使用 密钥 K
  ↓
密文
  ↓
[ 解密 ] —— 使用 相同的密钥 K
  ↓
明文

关键点:

  • 发送方和接收方必须提前共享同一个密钥。

  • 如果密钥泄露,数据就不再安全。

  • 优点是速度快,适合大量数据加密。

非对称加密(Asymmetric Encryption)

使用一对密钥:公钥(Public Key) 和 私钥(Private Key)

  • 公钥:所有人都可以知道,用于加密

  • 私钥:只有自己持有,用于解密

想象有一把锁,任何人都可以用它来锁一个箱子(用的公钥加密),但只有能打开这个箱子(用的私钥解密)。

明文
  ↓
[ 加密 ] —— 使用 接收方的公钥 PK
  ↓
密文
  ↓
[ 解密 ] —— 使用 接收方的私钥 SK
  ↓
明文

关键点:

  • 不需要提前共享密钥

  • 更安全,但速度较慢

  • 适用于身份验证、数字签名等场景

混合加密系统(Hybrid Encryption)

结合对称加密和非对称加密的优点:

  • 用非对称加密传输对称密钥(确保安全)

  • 然后用对称加密处理大量数据(确保效率)

[客户端] 想发送大量数据给 [服务器]

1. 客户端生成一个随机对称密钥 K

2. 客户端使用服务器的公钥 PK 加密 K:
   K_encrypted = Encrypt(K, PK)

3. 客户端发送 K_encrypted 给服务器

4. 服务器用自己的私钥 SK 解密:
   K = Decrypt(K_encrypted, SK)

5. 后续所有通信都使用 K 进行对称加密:
   [客户端] ←加密数据→ [服务器]

优势:

  • 安全性高(非对称加密保护密钥)

  • 效率高(对称加密处理数据)

三、CA

CA是Certificate Authority的缩写,通常翻译成认证权威或者认证中心。

其主要用途是为用户发放数字证书,并管理证书的生命周期,包括证书的发布、更新、撤销和验证。

  • 证书发布:向申请者发放经过验证的数字证书。

  • 证书更新:在证书即将过期或信息变更时,提供更新服务。

  • 证书撤销:当证书不再有效或被滥用时,将其从信任列表中移除。

  • 证书验证:确保证书的有效性和真实性。

作用

  • 身份认证:通过数字证书确认实体的身份,防止假冒和欺诈行为。

  • 数据的不可否认性:确保通信双方无法否认已发送或接收的信息,增强交易的安全性和可靠性。

每个主流操作系统(如Windows、macOS、Linux发行版)以及大多数现代浏览器都内置了一组受信任的证书颁发机构(Certificate Authorities, CA)的根证书。

这些预装的根证书构成了所谓的“信任链”,允许操作系统或浏览器验证网站提供的SSL/TLS证书的真实性。

当访问一个HTTPS网站时,如果该网站使用的是由已知且受信任的CA签发的证书,则浏览器会自动完成以下步骤:

  1. 下载服务器证书:当客户端(比如浏览器)尝试建立与服务器的安全连接时,服务器会发送它的SSL/TLS证书给客户端。

  2. 构建信任链:这个证书通常不是直接由根CA签发的,而是由中间CA签发的。因此,服务器还会提供一个或多个中间证书,以便客户端可以构建从服务器证书到某个已知根证书的信任链。

  3. 验证证书:客户端检查证书的有效性(包括但不限于是否过期、域名是否匹配),并且确保证书是由一个它信任的根CA签发的。

  4. 显示安全标志:如果所有检查都通过了,浏览器地址栏会显示锁图标或其他形式的安全标识,表示连接是安全的。

由于大部分公共网站都会使用知名CA(例如DigiCert、GlobalSign、Let's Encrypt等)提供的证书,并且这些CA的根证书已经被预先安装在操作系统和浏览器中,所以用户不需要进行任何额外的操作即可享受加密通信带来的安全保障。

3.1 证书请求文件(CSR)

CSR是Certificate Signing Request的英文缩写,即证书请求文件。

它是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成的文件。

生成过程

  1. 生成私钥:证书申请者首先生成一个私钥,用于后续的加密操作。

  2. 生成CSR文件:使用私钥生成包含申请者信息的CSR文件,这些信息包括但不限于组织名称、域名等。

  3. 提交CSR文件:将CSR文件提交给证书颁发机构(CA)进行审核。

签发过程

  • CA审核:CA对CSR文件中的信息进行审核,确认申请者的身份和信息的真实性。

  • 签名证书:审核通过后,CA使用其根证书的私钥对CSR文件进行签名,生成最终的数字证书并颁发给申请者。

自签名证书是指由其自身而非受信任的证书颁发机构(CA)签发的数字证书。

通常用于开发环境、内部网络或测试目的,因为它不需要支付费用给第三方CA,且可以快速生成。

然而,由于它们不是由浏览器或操作系统信任的CA签发的,使用自签名证书时会遇到一些特定的问题和限制。

3.2 HTTPS

HTTPS(Hyper Text Transfer Protocol Secure)是HTTP的安全版本,通过SSL(Secure Sockets Layer)或其后续技术TLS(Transport Layer Security)为数据传输提供加密。

工作流程

客户端(浏览器)                        服务器

     |                                    |
     |---(1) 发送HTTPS请求--------------->|
     |                                    |
     |<---(2) 返回数字证书(含公钥)------|
     |                                    |
     |--(3) 验证证书有效性               |
     |   (确认未过期、CA可信等)           |
     |                                    |
     |---(4) 使用公钥加密对称密钥-------->|
     |                                    |
     |                                    |-(5) 使用私钥解密得到对称密钥
     |                                    |
     |<--(6) 确认安全通道建立成功--------|
     |                                    |
     |---(7) 开始通过HTTPS传输数据(加密)|
     |                                    |
     |<---(8) 接收加密数据并解密----------|
     |                                    |

图示说明

  • 步骤1:客户端发起HTTPS连接请求。

  • 步骤2:服务器响应请求,返回其数字证书(包含服务器的公钥)。

  • 步骤3:客户端验证服务器提供的证书是否有效且由可信赖的CA签发。

  • 步骤4:如果证书验证成功,客户端生成一个随机的对称密钥,并使用服务器提供的公钥对其进行加密后发送给服务器。

  • 步骤5:服务器接收到加密的对称密钥后,使用自己的私钥进行解密,从而获取到对称密钥。

  • 步骤6:双方确认已成功建立了一个安全的通信通道。

  • 步骤7:客户端和服务器开始使用之前协商好的对称密钥加密所有后续的数据交换。

  • 步骤8:任何一方发送的数据都会被加密,另一方接收时则会解密这些信息。

3.3 应用证书

安装必要的软件包

yum install -y httpd mod_ssl openssl

mod_ssl 是 Apache 的 SSL/TLS 支持模块

openssl 是用于生成密钥、证书的核心工具

搭建私有CA

我们先创建一个本地CA来签发服务器证书,模拟正式CA的工作流程。

  1. 创建CA目录结构

mkdir -p ~/myCA/{certs,crl,private,newcerts}
​
cd ~/myCA
  • certs/:存放已签发的证书

  • crl/:吊销列表

  • private/:CA私钥存储

  • newcerts/:新证书存放目录

  • 还需要两个辅助文件:

echo '01' > serial      # 下一个证书编号
​
touch index.txt         # 证书数据库
  1. 生成CA私钥

openssl genrsa -out private/ca.key.pem 4096
​
chmod 400 private/ca.key.pem
  • -out private/ca.key.pem:输出文件名

  • 4096:密钥长度(推荐至少2048位)

  • chmod 400:保护私钥权限,防止泄露

  1. 生成CA自签名证书

openssl req -x509 -new -key private/ca.key.pem -sha256 -days 3650 -out certs/ca.cert.pem
  • -x509:直接生成X.509证书(不是CSR)

  • -new:新建请求

  • -sha256:哈希算法

  • -days 3650:有效期10年

  • 系统会提示输入一些信息,如国家、组织名称等(这些信息将显示在证书中)

Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:guangzhou
Locality Name (eg, city) [Default City]:shenzhen
Organization Name (eg, company) [Default Company Ltd]:alibaba
Organizational Unit Name (eg, section) []:ops team
Common Name (eg, your name or your server's hostname) []:www.zking.com
Email Address []:123@qq.com

证书签发后,只有当客户端(如浏览器)访问的域名与证书中的 Common Name 匹配时,才不会提示“证书不安全”。

生产环境下不能随便填

在正式部署 HTTPS 的时候,Common Name 必须是真实拥有的域名,并且由正规 CA 签发证书。

此时已经有了一个私有CA,其证书是 certs/ca.cert.pem,私钥是 private/ca.key.pem

[root@localhost myCA]# tree
.
├── certs
│   └── ca.cert.pem
├── crl
├── index.txt
├── newcerts
├── private
│   └── ca.key.pem
└── serial

生成SSL密钥和证书请求

假设要为域名 zking 配置HTTPS。

生成服务器私钥
openssl genrsa -out /etc/pki/tls/private/zking.key 2048

chmod 400 /etc/pki/tls/private/zking.key

注意路径 /etc/pki/tls/private/ 是 Red Hat 系统标准位置

  1. 生成证书签名请求(CSR)

openssl req -new -key /etc/pki/tls/private/zking.key -out /tmp/zking.csr

系统会再次提示填写相关信息,其中 Common Name 应该填的域名,比如:

Common Name (e.g. server FQDN or YOUR name) []: www.zking.com

A challenge password []: zking为证书申请过程增加一层额外的身份验证zking。

当向某些 CA(证书颁发机构)提交 CSR 以申请证书时,CA 可能会要求提供这个“挑战密码”来确认是 CSR 的创建者。

签发服务器证书

现在我们用之前创建的CA来签发服务器证书。

openssl x509 -req -in /tmp/zking.csr \
    -CA certs/ca.cert.pem \
    -CAkey private/ca.key.pem \
    -CAcreateserial \
    -out /etc/pki/tls/certs/zking.crt \
    -days 365 \
    -sha256
  • -CA:指定CA证书

  • -CAkey:指定CA私钥

  • -CAcreateserial:自动创建serial文件

  • -out:输出最终的服务器证书

  • -days 365:证书有效期1年

此时已经拥有了完整的服务器证书链:

  • 私钥:/etc/pki/tls/private/zking.key

  • 证书:/etc/pki/tls/certs/zking.crt

  • CA证书:~/myCA/certs/ca.cert.pem

配置Apache启用HTTPS

编辑 Apache 的 SSL 虚拟主机配置文件(/etc/httpd/conf.d/ssl.conf

sudo vi /etc/httpd/conf.d/ssl.conf

找到如下配置并修改为:

<VirtualHost *:443>
    ServerName www.zking.com
    SSLEngine on
    SSLCertificateFile "/etc/pki/tls/certs/zking.crt"
    SSLCertificateKeyFile /etc/pki/tls/private/zking.key
</VirtualHost>
配置项 说明
SSLEngine on 启用SSL
SSLCertificateFile 服务器证书路径
SSLCertificateKeyFile 服务器私钥路径

重启Apache服务

sudo systemctl restart httpd

sudo systemctl enable httpd --now

检查是否监听了443端口:

ss -tuln | grep 443

测试访问

在浏览器中访问:

https://www.zking.com

由于使用的是自签名CA证书,浏览器会提示“不安全连接”或“证书不受信任”。

可以手动将 ca.cert.pem 导入浏览器或操作系统信任库中解决此问题。

# 步骤1:确认的 CA 证书存在
ls -l /root/myCA/certs/ca.cert.pem
​
# 步骤2:复制 CA 证书到系统信任目录(推荐使用 .crt 后缀)
sudo cp /root/myCA/certs/ca.cert.pem /etc/pki/ca-trust/source/anchors/myCA.crt
​
# 步骤3:更新系统信任库
sudo update-ca-trust
​
# 步骤4:验证是否生效
curl -v https://www.zking.com

如果以后想删除这个证书:

sudo rm /etc/pki/ca-trust/source/anchors/myCA.crt
sudo update-ca-trust
文件路径 内容
/etc/pki/tls/private/zking.key 服务器私钥
/etc/pki/tls/certs/zking.crt 服务器证书
~/myCA/certs/ca.cert.pem 自签名CA证书
~/myCA/private/ca.key.pem CA私钥(非常重要,不能泄露)
步骤 目标
搭建CA 创建自己的证书颁发机构
生成私钥 & CSR 为服务器生成密钥和证书请求
签署证书 使用CA签发服务器证书
配置Apache 修改 ssl.conf 文件启用HTTPS
浏览器测试 访问 https://zking 并验证安全性

3.4 Nginx 启用证书

  1. 打开或创建 Nginx 的站点配置文件

sudo vi /etc/nginx/nginx.conf

2. 修改内容

server {
    listen 80;
    server_name www.zking.com;

    # 强制跳转到 HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name www.zking.com;

    # 指定 SSL 证书和私钥路径
    ssl_certificate     /etc/pki/tls/certs/zking.crt;
    ssl_certificate_key /etc/pki/tls/private/zking.key;

    # 推荐的安全协议和加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 根目录设置(根据的实际需求修改)
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ =404;
    }

}

重启 Nginx 生效配置

重启 Nginx 生效配置

可以通过浏览器访问:

https://www.zking.com

如果使用的是 自签名证书,浏览器会提示“不安全”,需要手动信任证书。