结论: 服务器数据加密要分成三层来做:传输层用 TLS 1.2/1.3 与外部签发的正式证书保护数据在网络上的流动;存储层用 LUKS/dm-crypt 或云平台提供的云盘加密保护落盘数据;备份层用 GPG 或 OpenSSL 加密后再异地存放。三层之外必须单独解决密钥管理的归属问题,否则加密只是形式。
数据加密常被误认为是"安全等级很高才有必要做的事"。事实上它往往由最朴素的需求驱动:客户要求《个人信息保护法》下的加密存储义务、等保三级要求"重要数据在存储和传输过程中应加密"、数据库备份要放到对象存储上不得不加密、一台笔记本或一块退役硬盘被搬走时不希望数据能被读出来。
数据加密分哪几层?先分清三种状态
数据在任何时刻都处于三种状态之一:传输中(Data in Transit)、静态(Data at Rest)、使用中(Data in Use)。前两种是服务器运维者的常规职责范围,第三种(内存加密、机密计算)截至 2026 年主要依赖 SGX / TEE 等硬件能力,普通业务较少涉及。
| 状态 | 典型位置 | 推荐技术 | 性能开销 | 落地难度 |
|---|---|---|---|---|
| 传输中 | 浏览器↔Nginx、服务间调用 | TLS 1.3、mTLS 双向认证 | 握手阶段微增,后续对称加密几乎无感 | 低,配证书即可 |
| 静态(整盘) | 系统盘、数据盘 | LUKS/dm-crypt、云盘加密 | 现代 CPU AES-NI 下 3%~8% | 中,需处理开机解锁 |
| 静态(数据库) | MySQL/PostgreSQL 数据文件 | TDE 透明数据加密、列级加密 | 5%~15% | 中高,依赖商业/企业版功能 |
| 静态(文件级) | 单个敏感文件 | GPG、age、openssl enc | 一次性,无持续开销 | 低 |
| 静态(备份) | 备份包、对象存储 | GPG 公钥加密、rclone crypt | 压缩加密时一次性开销 | 低 |
| 使用中 | 内存、CPU 处理过程 | 机密计算 / TEE | 视方案而定 | 高 |
一个容易被忽略的判断准则:加密解决的是"介质失控",不解决"权限失控"。如果攻击者已经拿到了 root shell,任何自动挂载的加密盘对他都是透明的。因此加密永远要和权限收敛、审计日志配合使用。
传输加密:TLS 证书怎么配到最优
传输加密最常见、性价比最高。目标是:全站 HTTPS、只保留 TLS 1.2 与 1.3、启用 HSTS、优先使用前向安全(Forward Secrecy)的加密套件。
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 只保留现代协议,TLS 1.0/1.1 已于 2021 年被主流浏览器废弃
ssl_protocols TLSv1.2 TLSv1.3;
# 优先使用服务端套件顺序,启用前向安全
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
# 会话缓存,减少重复握手
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling,加速证书状态校验
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
# HSTS:强制浏览器一年内只用 HTTPS(确认全站 HTTPS 后再启用)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff always;
}
# HTTP 全量跳转 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}证书获取建议直接用 Let's Encrypt(90 天有效期,自动续期),配合 certbot 一条命令搞定;对内网服务可用私有 CA 自签并以 Ansible 统一下发信任。
# 签发证书(Nginx 插件模式)
apt install -y certbot python3-certbot-nginx
certbot --nginx -d example.com -d www.example.com
# 自动续期已经写进 systemd timer / crontab,可用 dry-run 验证
certbot renew --dry-run
systemctl list-timers | grep certbot
# 校验当前证书链与协议支持
openssl s_client -connect example.com:443 -servername example.com -tls1_3 /dev/null | grep -E "Protocol|Cipher|Verify"
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates -subject服务间的内部调用(如 API 网关到微服务)建议升级到双向 TLS(mTLS),即客户端也提供证书。这是零信任架构里"永不信任网络、始终验证身份"的基础能力。证书的安装与续期细节见 服务器怎么配置SSL证书,过期处理见 服务器证书过期怎么处理。
存储加密一:LUKS / dm-crypt 整盘加密
LUKS(Linux Unified Key Setup)是 Linux 上标准的块设备加密方案,底层使用 dm-crypt 与内核 crypto API。它在 CPU 支持 AES-NI 的机器上性能损耗极小。
# 1. 安装工具并确认内核支持
apt install -y cryptsetup
modprobe dm_crypt
cat /proc/crypto | grep -i aes
# 2. 对一块【全新且无数据】的数据盘做加密(会销毁全部数据!)
cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 \
--hash sha512 --iter-time 5000 /dev/vdb
# 3. 打开加密卷(映射为 /dev/mapper/secure_data)
cryptsetup luksOpen /dev/vdb secure_data
# 4. 在映射设备上建文件系统并挂载
mkfs.ext4 /dev/mapper/secure_data
mkdir -p /mnt/secure_data
mount /dev/mapper/secure_data /mnt/secure_data
df -h /mnt/secure_data
# 5. 查看加密卷状态与使用的算法
cryptsetup luksDump /dev/vdb | head -30
cryptsetup status secure_data开机自动解锁是运维的最大痛点。方案有两种:用密钥文件(适合数据盘,密钥文件放在 root 只读的目录),或用 Clevis + Tang 做网络绑定自动解锁(适合数据中心环境,机器能连到 Tang 服务器才解锁)。
# 生成随机密钥文件并加入 LUKS 的密钥槽(slot)
dd if=/dev/urandom of=/root/.luks_key bs=4096 count=1
chmod 400 /root/.luks_key
cryptsetup luksAddKey /dev/vdb /root/.luks_key
# /etc/crypttab:<映射名> <设备UUID> <密钥文件> <选项>
UUID=$(blkid -s UUID -o value /dev/vdb)
echo "secure_data UUID=${UUID} /root/.luks_key luks,discard" >> /etc/crypttab
# /etc/fstab 自动挂载
echo "/dev/mapper/secure_data /mnt/secure_data ext4 defaults,nofail 0 2" >> /etc/fstab
# 测试:重启后确认自动解锁成功
# cryptsetup luksClose secure_data # 关闭卷的命令,先卸载文件系统注意密钥文件绝不能放在被加密的那个卷里,也必须异地备份——丢了密钥文件而 slot 0 的口令也忘了,数据就永久无法恢复。
存储加密二:云盘加密与数据库 TDE
如果你用的是云主机,最省事的方案是直接使用云厂商提供的云盘加密能力:在创建云盘时勾选加密,密钥由 KMS(密钥管理服务)托管,主机侧零性能损耗、零运维负担,且快照与从快照创建的云盘自动继承加密属性。缺点是无法防护"宿主机被攻破"这一层,但对绝大多数合规场景已足够。
数据库层的选择更复杂:
| 数据库 | 方案 | 版本要求 | 说明 |
|---|---|---|---|
| MySQL | Keyring 插件 + InnoDB 表空间加密 | MySQL 5.7+/8.0 社区版 | 逐表空间加密,ALTER TABLE t ENCRYPTION='Y' |
| MySQL | TDE 全量 | 企业版 / Percona / 云 RDS | 商业版才支持 redo/undo 日志完整加密 |
| PostgreSQL | pgcrypto 扩展(列级) | 所有版本 | 灵活但需改应用 SQL |
| PostgreSQL | 云 RDS TDE | 云厂商托管版 | 一键开启,最省事 |
| SQL Server | 原生 TDE + Always Encrypted | 全版本 | 功能最完整 |
| Redis | 无原生 TDE | —— | 靠磁盘加密 + TLS + 网络隔离替代 |
-- MySQL 8.0 社区版:加载 keyring 插件并对表启用加密
INSTALL PLUGIN keyring_file SONAME 'keyring_file.so';
SET GLOBAL keyring_file_data = '/var/lib/mysql-keyring/keyring';
-- 对已有表开启加密
ALTER TABLE user_profiles ENCRYPTION = 'Y';
-- 验证
SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS
FROM information_schema.TABLES
WHERE CREATE_OPTIONS LIKE '%ENCRYPTION%';# /etc/mysql/mysql.conf.d/mysqld.cnf 持久化配置
[mysqld]
early-plugin-load = keyring_file.so
keyring_file_data = /var/lib/mysql-keyring/keyring
default_table_encryption = ON备份加密:GPG 与 OpenSSL 怎么选
备份是最容易泄露的环节——它带着全量数据离开了生产环境,落到对象存储、移动硬盘或异地机房。备份必须加密,且推荐用非对称加密:本地只用公钥,私钥离线保管,即使备份被人拖走也解不开。
# ===== 方案 A:GPG 公钥加密(推荐)=====
# 生成密钥对(私钥务必导出到离线介质)
gpg --full-generate-key --expert
gpg --export -a "backup@company" > /root/backup-pubkey.asc
# 加密一个数据库备份
mysqldump -uroot -p --single-transaction --routines appdb | gzip > /tmp/appdb.sql.gz
gpg --trust-model always -r "backup@company" --encrypt --output /backup/appdb.sql.gz.gpg /tmp/appdb.sql.gz
# 恢复时用私钥解密
gpg --decrypt /backup/appdb.sql.gz.gpg | gunzip | mysql -uroot -p appdb
# ===== 方案 B:OpenSSL 对称加密(简单,但密码只在打包时用到)=====
tar czf - /var/www/html | openssl enc -aes-256-cbc -pbkdf2 -salt -out /backup/web-$(date +%F).tar.gz.enc
# 解密
openssl enc -d -aes-256-cbc -pbkdf2 -in /backup/web-2026-01-01.tar.gz.enc | tar xzf -上传对象存储时推荐 rclone 的 crypt 远端:它在客户端完成加密后再上传,云服务提供商只看到密文,兼顾了便宜的对象存储与数据自主权。备份策略的整体设计见 服务器数据怎么定时备份。
密钥管理:加密不是终点,密钥放哪儿才是
所有加密方案的价值最终取决于密钥。以下是必须遵守的四条底线:
- 密钥绝不与密文存放同处。 备份数据的密码写在备份脚本里、密钥文件放在加密盘里,等于没加密。
- 用 KMS 而非明文配置文件。 云厂商的 KMS(或开源的 HashiCorp Vault)提供密钥托管、访问鉴权、轮换与审计,避免了密钥散落在各台机器上。
- 定期轮换。 TLS 证书建议 90 天,数据加密主密钥建议 1 年一次(通过 re-encrypt 或 key rotation slot 完成)。
- 至少两人持有恢复凭据。 避免出现"唯一知道密码的人离职了,备份永远打不开"这类事故。
# LUKS 密钥轮换:新增 key slot → 验证能用 → 删除旧 slot
cryptsetup luksAddKey /dev/vdb --key-file /root/.luks_key_old
cryptsetup luksOpen --test-passphrase --key-slot 1 /dev/vdb && echo "new key OK"
cryptsetup luksKillSlot /dev/vdb 0
# 检查还剩几个可用密钥槽(Slots)
cryptsetup luksDump /dev/vdb | grep -A8 "Key Slot"常见误区 / 排错提示
- 以为启用了 HTTPS 就等于数据都加密了。 HTTPS 只保护链路;日志里明文打印身份证号、数据库裸存密码摘要、备份包不加密,加密依然是失败的。
- 把加密轮的口令写进
/etc/rc.local或备份脚本明文参数。 明文口令出现在进程列表(ps aux)里任何人可读,应使用 stdin 或--key-file。 - LUKS 格式化命令打错设备名,把系统盘清空了。 执行
luksFormat前务必用lsblk/blkid三次确认设备名,且务必先做快照。 - 加密后忘了测恢复。 没有演练过的备份等于没有备份。每季度必须做一次"从加密备份完整还原到新机器"的演练并记录耗时。
- 保留 TLS 1.0/1.1 "兼容老客户"。 截至 2026 年,主流浏览器早已废弃旧协议,保留它们只会拉低整体安全评级(PCI DSS 与等保测评都会扣分)。
- 数据库开了 TDE 就不再做应用层脱敏。 TDE 防的是文件层面的泄露,运维人员或有权限的应用依然能读到明文,敏感字段仍需应用层加密或脱敏展示。
企业QQ咨询




