如何保护你的DNF私服:AES密钥、RSA公私钥、HTTPS网关与GeoIP白名单安全机制详解
- 游戏开发
- 云原生
- DevOps
- 运维
【免费下载链接】dnf
dnf是一款把 DNF(地下城与勇士)私服打包为 Docker 容器的开源部署项目,一条docker run即可拉起完整服务端。除了部署方便,它内置了四层开箱即用的安全防护:AES 通讯密钥、自动生成的 RSA 公私钥、HTTPS 登录网关与 GeoIP 国家白名单。本文将用通俗的方式讲清每一层防护的原理与开启方法,帮你挡住最常见的三类风险:登录流量被抓包、公开密钥被盗用、陌生地区 IP 随意连接。
一、先看懂:一次登录要经过哪些环节
从上图的进程架构可以看出,玩家客户端并不是直接连进游戏:
- 登录阶段:客户端先访问登录网关
dnf-gate-server(HTTP 端口5505,启用 HTTPS 后为5504),完成账号校验并获取频道信息; - 进频道阶段:客户端再与 Game Server(Channel,如
siroco11)建立连接,进入地图。
四层防护恰好卡在这两个阶段的要害上:
| 防护层 | 保护对象 | 对应机制 |
|---|---|---|
| AES 密钥 | 登录器 ↔ 网关的通讯内容 | GATE_AES_KEY |
| RSA 公私钥 | 登录身份与签名校验 | privatekey.pem/publickey.pem |
| HTTPS 网关 | 登录请求的传输通道 | GATE_TLS_*环境变量 |
| GeoIP 白名单 | 频道连接的来源 IP | d_taiwan.geo_allow表 |
各环境变量的完整说明见 doc/OtherDeploy.md。
二、AES 通讯密钥:给登录器与网关之间加把锁 🔐
GATE_AES_KEY是dnf-gate-server与登录器之间的对称通讯密钥,登录器用它加解密与网关交互的数据。密钥两端必须一致:
- 服务端:启动容器时通过环境变量传入(见 README.md 的快速开始章节);
- 客户端:在登录器
dnf-launcher.exe的"设置"中填写相同的值。
⚠️ 密钥必须是恰好 64 位的十六进制字符串(0-9、a-f)。强烈建议自己生成,例如在 Linux 上执行
openssl rand -hex 32。文档中的默认值属于公开信息,照抄等于不设防。
新手最常踩的两个坑(来自 README.md 常见问题 4/5):
AES key must be exactly 64 hex characters—— 密钥长度不足或多了换行符;AES key must contain only hex characters—— 混入了非十六进制字符。
两边配置完全一致后,登录器保存即可。
三、RSA 公私钥:首次部署自动生成,杜绝"公开密钥"风险
这是 dnf 项目相比老版本部署的一个关键安全设计:项目镜像里没有内置任何公开的游戏公私钥,而是在你初次部署时现场生成一对全新密钥。
初始化逻辑位于 build/dnf_data/etc/s6-overlay/scripts/init.d/init-data.sh,核心行为有三步:
- 若
/data/privatekey.pem不存在,执行openssl genrsa生成2048 位 RSA 私钥; - 用模数比对(
openssl rsa -noout -modulus)校验公钥publickey.pem是否与私钥匹配; - 匹配则保持不变,不匹配时提示并可选用私钥重新导出公钥。
随后公钥会被分发到游戏进程目录(见 init-data.sh 第 161 行),供频道侧做登录校验,私钥路径由RSA_PRIVATE_KEY_PATH(默认/data/privatekey.pem)指定。
为什么这件事很重要?官方 README.md 常见问题 19 明确警告:如果使用其他内置了公开私钥的登录器,一旦你的PUBLIC_IP泄露,攻击者无需账号密码即可游玩你服务端任意角色。所以:
- 保持使用本项目配套的 llnut 登录器 + 自动生成的密钥对;
/data目录挂载在宿主机上,privatekey.pem请妥善保管、不要外传;- 若网关与游戏服务端不在同一台机器、公钥需要重建,可设置
PUBKEY_OVERWRITE=true,详见 doc/OtherDeploy.md。
四、HTTPS 登录网关:一行环境变量开启传输加密 🔒
默认情况下登录网关只监听 HTTP(5505),账号请求是明文传输的。开启 HTTPS 只需两步:
- 把你的 TLS 证书和私钥放到挂载的
/data目录中; - 设置两个环境变量后重启容器(参考 README.md 常见问题 10):
GATE_TLS_CERT_PATH:证书路径GATE_TLS_KEY_PATH:私钥路径
两者同时设置后,网关自动在GATE_TLS_BIND_ADDRESS(默认0.0.0.0:5504)上提供 HTTPS。此时登录器中的服务器地址要由http://${PUBLIC_IP}:5505改为https://${PUBLIC_IP}:5504。
如果希望彻底拒绝明文 HTTP,再把GATE_TLS_ONLY设为true,网关将只接受 HTTPS 连接。配合云厂商免费证书(如 Let's Encrypt)即可零成本获得全站加密。
五、GeoIP 白名单:把陌生地区 IP 挡在频道门外 🌏
DNF 服务端进程df_game_r启动时会加载 GeoIP 数据库,按 IP 归属国校验每一次频道连接。启动成功的频道日志中会看到:
[09:40:23] GeoIP Allow Country Code : CN [09:40:23] GeoIP Allow Country Code : TW(CN)白名单存储在数据库表d_taiwan.geo_allow中,由容器内置定时任务自动维护(scheduler.sh 第 92-98 行):
- 默认每
GEO_ALLOW_INTERVAL(3600 秒)执行一次,把容器 IP 与网关 IP 加入白名单,启动后是否立即执行由GEO_ALLOW_RUN_ON_START控制(默认true); - 具体写入逻辑在 user-script.sh 中,你可以直接编辑该脚本追加自己的 IP,或收紧允许的国家代码。
被拦截了怎么办?若玩家连频道时网络中断,多半是 GeoIP 拦截,频道日志会打印被拦的 IP(参考 doc/OtherDeploy.md):
[16:02:51] ... [Taiwan, GeoIP] Fail Account:18000000, IP:192.168.48.1, CountryCode:把日志中的192.168.48.1写入geo_allow白名单后重启服务即可放行。这一层相当于给频道加了一道"按地域准入"的闸机,能有效减少来自陌生地区扫描器的无效连接。
六、进阶加固建议 🛡️
在四层基础防护之上,再花两分钟做三件事:
- 关闭新用户注册:
GATE_REGISTRATION_OPEN=false,网关将拒绝一切注册请求,适合只接待固定玩家的服务器; - 收紧网络暴露面:数据库外部访问走
3000端口(容器内 3306 由代理转发),非必要不要在云服务器安全组中放行它; - 开启数据库自动备份:
DB_BACKUP_ENABLE=true(默认保留DB_BACKUP_KEEP=7份),安全事件的兜底手段,配置细节见 doc/OtherDeploy.md。
七、安全配置速查表
| 配置项 | 默认值 | 建议操作 |
|---|---|---|
GATE_AES_KEY | 文档内置示例值 | 必须自行生成 64 位十六进制密钥 |
/data/privatekey.pem | 首次启动自动生成 | 妥善保管,切勿使用公开密钥 |
GATE_TLS_CERT_PATH/GATE_TLS_KEY_PATH | 未启用 | 填入证书路径开启 HTTPS |
GATE_TLS_ONLY | false | 启用 HTTPS 后建议设为true |
GATE_REGISTRATION_OPEN | true | 固定玩家后建议设为false |
d_taiwan.geo_allow | 定时任务自动维护 | 按日志追加玩家 IP / 收紧国家码 |
总结:dnf 项目把 DNF 私服的四大核心防护——AES 密钥、RSA 公私钥、HTTPS 网关、GeoIP 白名单——都做成了环境变量级的简单开关。新手只需记住顺序:换掉默认 AES 密钥 → 保持自动生成的 RSA 密钥对 → 开启 HTTPS → 按需维护 GeoIP 白名单,你的私服安全水位就会超过绝大多数同类部署。
免责声明:本项目仅供学习与研究使用,请勿用于公开商业开服。
- 游戏开发
- 云原生
- DevOps
- 运维
【免费下载链接】dnf
相关推荐
Paramiko密钥类型全解析:RSA、ECDSA、Ed25519如何选?私钥加载与密码保护教程
Paramiko密钥类型全解析:RSA、ECDSA、Ed25519如何选?私钥加载与密码保护教程 🔐 Paramiko 是 Python 生态中领先的 SSH
网络通信密码学身份认证【亲测免费】 SwiftyRSA:Swift中的RSA公钥/私钥加密库
SwiftyRSA:Swift中的RSA公钥/私钥加密库 1. 项目基础介绍和主要编程语言 SwiftyRSA 是一个开源的 Swift 库,专门用于在 iOS
cangjie_stdx keys 包密钥类全解:ECDSA、RSA、SM2 私钥/公钥的生成、编解码与签名验签实战
cangjie_stdx keys 包密钥类全解:ECDSA、RSA、SM2 私钥/公钥的生成、编解码与签名验签实战 本文档以仓颉标准库扩展模块 stdx.cr
标准库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考