news 2026/10/3 7:21:56

运维平台安全设计实战:从 AES 加密到 SSH 指纹校验的 5 道防线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
运维平台安全设计实战:从 AES 加密到 SSH 指纹校验的 5 道防线

运维平台安全设计实战:从 AES 加密到 SSH 指纹校验的 5 道防线

本文属于「码动四季·开源同行」秋季征稿 —— 技术经验体系化沉淀赛道。
以开源项目 AtomOps 为例,分享运维平台建设中 5 层安全防线的工程实现。

为什么运维平台的安全特别难做

运维平台天然持有大量敏感凭据:服务器 root 密码、数据库连接串、SSH 私钥。一旦平台被攻破,攻击者获得的是所有被管服务器的 root 权限——这是典型的"权限放大"场景。

普通 Web 应用被攻破:泄露用户数据。
运维平台被攻破:泄露所有服务器的控制权。

所以 AtomOps 在设计之初就把安全作为第一优先级,构建了 5 道防线:

用户请求 → ① 认证Cookie → ② CSRF校验 → ③ 权限检查 → ④ 凭据加密 → ⑤ SSH指纹校验 → 执行

防线一:httpOnly Cookie + 双 Token 机制

问题

传统方案把 JWT 存在localStorage,前端每次请求带上Authorization: Bearer xxx。问题在于:

  • localStorage可被 JavaScript 读取 →XSS 攻击可窃取 token
  • token 有效期内无法主动失效

解决方案

双 Token 机制:access_token(短期)+ refresh_token(长期)

# 登录时设置 httpOnly cookieresponse.set_cookie(key="access_token",value=access_token,httponly=True,# JS 不可读,防 XSSsamesite="lax",# 防 CSRFsecure=False,# HTTP 部署时 False,HTTPS 时 Truemax_age=3600,# 1 小过期path="/",)

关键点:

  • httponly=True:JavaScriptdocument.cookie读不到,XSS 偷不走
  • samesite=lax:跨站请求不自动携带 cookie,防 CSRF
  • 前端用withCredentials: true让 axios 自动携带 cookie

踩坑:Secure cookie + HTTP = 闪退

生产环境ENV=production导致secure=True,但 HTTP 部署下浏览器静默丢弃Secure cookie。用户登录后所有 API 返回 401,页面闪退回登录页。

教训:secure标志只适用于 HTTPS。HTTP 部署必须设为False,且没有任何浏览器错误提示,极难排查。


防线二:CSRF 双重提交防护

问题

httpOnly cookie 防了 XSS 窃取,但 cookie 会被自动发送到同源请求。攻击者构造一个恶意表单,用户点击后浏览器自动带上 auth cookie 发起 POST 请求——这就是 CSRF。

解决方案

Double Submit Cookie 模式:

1. GET /api/coc/auth/csrf-token → 后端下发 csrf_token cookie 2. 前端读 cookie,放入 X-CSRF-Token 请求头 3. POST 请求 → 后端校验 header token == cookie token
classCSRFMiddleware(BaseHTTPMiddleware):SAFE_METHODS={"GET","HEAD","OPTIONS"}asyncdefdispatch(self,request,call_next):ifrequest.methodinself.SAFE_METHODS:returnawaitcall_next(request)# 安全方法放行ifnotrequest.headers.get("Authorization")and\notrequest.cookies.get("access_token"):returnawaitcall_next(request)# 未认证请求交给 401header_token=request.headers.get("X-CSRF-Token","")cookie_token=request.cookies.get("csrf_token","")ifnotheader_tokenornotcookie_token:returnJSONResponse(status_code=403,content={"message":"缺少 CSRF Token"})ifnotsecrets.compare_digest(header_token,cookie_token):returnJSONResponse(status_code=403,content={"message":"CSRF Token 校验失败"})returnawaitcall_next(request)

前端配合:axios 拦截器自动在写操作前获取 CSRF token:

asyncfunctionensureCsrfToken(){if(csrfToken)returncsrfTokenconstres=awaitaxios.get('/api/coc/auth/csrf-token')csrfToken=res.data?.csrf_token||readCsrfCookie()returncsrfToken}// 请求拦截器:POST/PUT/DELETE 自动附加 X-CSRF-Tokenif(['post','put','delete'].includes(method)){if(!csrfToken)awaitensureCsrfToken()config.headers['X-CSRF-Token']=csrfToken}

为什么不用 SameSite cookie 替代?SameSite=Strict会阻止所有跨站请求,包括从邮件链接打开的合法请求。SameSite=Lax允许 GET 但阻止 POST,需要配合 CSRF token 才能完整防护。


防线三:RBAC 权限控制

实现

# 依赖注入:要求管理员权限asyncdefrequire_admin(user:User=Depends(get_current_user)):ifuser.role!="admin":raiseHTTPException(status_code=403,detail="需要管理员权限")returnuser# 路由使用@router.post("/scripts/{id}/execute")asyncdefexecute_script(user:User=Depends(require_admin)):...

前端路由守卫:

constadminOnlyPaths=['/coc/security/key','/audit']if(adminOnlyPaths.some(p=>to.path.startsWith(p))&&role!=='admin'){feedback.error('需要管理员权限')next(from.path||'/')return}

防线四:AES 加密存储凭据

问题

主机密码、SSH 私钥如果明文存数据库,DBA 或拖库攻击者直接拿到所有服务器凭据。

解决方案

Fernet 对称加密(AES-128-CBC + HMAC):

fromcryptography.fernetimportFernetdef_derive_key()->bytes:ifsettings.ENCRYPTION_KEY:raw=settings.ENCRYPTION_KEY.encode()returnbase64.urlsafe_b64encode(raw[:32])# 从 SECRET_KEY 派生derived=hashlib.pbkdf2_hmac("sha256",settings.SECRET_KEY.encode(),b"atomops-salt",iterations=100_000,dklen=32)returnbase64.urlsafe_b64encode(derived)_CIPHER=Fernet(_derive_key())defencrypt(text:str)->str:return_CIPHER.encrypt(text.encode()).decode()defdecrypt(cipher_text:str)->str:return_CIPHER.decrypt(cipher_text.encode()).decode()

使用方式:

# 创建主机时加密密码host=Host(hostname="web-01",password=encrypt("1qaz@WSX"))db.add(host)# 执行时解密password=decrypt(host.password)ssh.connect(hostname=host.ip,password=password)

敏感字段自动加密:后端build_crud_router支持sensitive_fields参数,写入时自动加密,读取时自动脱敏(返回***):

router.include_router(build_crud_router("/api/v1/hosts",Host,"host",sensitive_fields=["password","private_key"],))

防线五:SSH 指纹白名单校验

问题

paramiko.AutoAddPolicy()会自动接受任何未知主机密钥——第一次连接时不校验,容易受中间人攻击。RejectPolicy()则拒绝所有未知主机,部署时需要预加载 known_hosts,不够灵活。

解决方案

白名单 + 后置指纹校验:

def_get_client(host:dict)->paramiko.SSHClient:# 1. 白名单检查:主机 IP 必须预先注册指纹known={h["ip"]:h["fingerprint"]forhinlist_known_hosts()}ifhost["ip"]notinknown:raiseSSHException(f"主机{host['ip']}未在 known_hosts 中注册")# 2. AutoAddPolicy 建立连接(不依赖系统 ~/.ssh/known_hosts)client=paramiko.SSHClient()client.set_missing_host_key_policy(paramiko.AutoAddPolicy())client.connect(hostname=host["ip"],password=decrypt(host.password))# 3. 后置校验:实际指纹 vs 记录指纹fingerprint=_get_fingerprint(client.get_transport())ifknown[host["ip"]]!=fingerprint:client.close()raiseSSHException(f"指纹不匹配!期望{known[host['ip']]},实际{fingerprint}")returnclient

三层防护逻辑:

  1. 白名单:未注册的主机直接拒绝,防止连到未知服务器
  2. AutoAddPolicy:不依赖系统 known_hosts,避免部署环境差异
  3. 指纹校验:连接后验证服务器身份,防止 DNS 劫持/中间人攻击

部署时自动注册:

# 通过公网 IP 获取指纹,用内网 IP 注册(后端通过内网 SSH)forprivate_ip,public_ipinservers:ssh=paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect(public_ip,username='root',password=password)fp=_get_fingerprint(ssh.get_transport())add_known_host(private_ip,fp)

五道防线的协作关系

XSS 攻击 │ ┌────────▼─────────┐ │ ① httpOnly Cookie │ ← JS 读不到 token └────────┬─────────┘ │ CSRF 攻击 │ ┌────────▼─────────┐ │ ② CSRF 双重提交 │ ← 跨站请求无 token └────────┬─────────┘ │ 越权访问 │ ┌────────▼─────────┐ │ ③ RBAC 权限控制 │ ← 非管理员被拦截 └────────┬─────────┘ │ 数据库拖库 │ ┌────────▼─────────┐ │ ④ AES 凭据加密 │ ← 密文不可直接使用 └────────┬─────────┘ │ 中间人攻击 │ ┌────────▼─────────┐ │ ⑤ SSH 指纹校验 │ ← 指纹不匹配则断开 └──────────────────┘

每道防线针对不同攻击向量,缺一不可。例如:

  • 没有 ①,XSS 可窃取 token 绕过 ②③
  • 没有 ④,拖库后攻击者直接拿到所有密码
  • 没有 ⑤,DNS 劫持可劫持 SSH 连接

总结

防线防御目标实现方式踩坑经验
httpOnly CookieXSS 窃取 tokenhttponly=TrueSecure+HTTP 会闪退
CSRF 双重提交CSRF 跨站请求header+cookie 校验前端需自动获取 token
RBAC越权访问依赖注入检查角色前端路由守卫配合
AES 加密数据库拖库Fernet 对称加密密钥派生要加 salt
SSH 指纹中间人攻击白名单+后置校验新主机需自动注册

安全没有银弹,每多一道防线,攻击者的成本就高一个数量级。这 5 道防线让 AtomOps 在被攻破单点时,仍能保护最核心的资产——被管服务器的控制权。


项目仓库:https://gitcode.com/cpyaxjq/AtomOps

本文为 AtomGit「码动四季·开源同行」秋季征稿投稿。如果觉得有帮助,欢迎到仓库点个 Star ⭐

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 7:21:37

金叉买死叉卖,11年只赚了2262块

前两期复现了海龟和均值回归:一个靠低胜率跑赢躺平,一个胜率75%却输给躺平。 这期来复现最出名的那个——双均线。金叉买、死叉卖,几乎是每个股民学会的第一个技术指标。 11年真实数据跑完,结果有点尴尬:95次买卖&…

作者头像 李华
网站建设 2026/10/3 7:21:36

物联网毕设必过方向帮助

【单片机毕业设计项目分享系列】 🔥 这里是DD学长,单片机毕业设计及享100例系列的第一篇,目的是分享高质量的毕设作品给大家。 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的单片机项目缺少创新和亮点…

作者头像 李华
网站建设 2026/10/3 7:20:33

千笔AI解答:论文AIGC检测与AI降重高频疑问汇总

论文aigc率多少算正常 目前不同高校、期刊对论文AIGC率的合格标准没有统一的规定,主流的要求区间通常控制在10%-30%以内。千笔AI平台结合大量高校送检案例整理了常见的标准参考如下: 场景合理AIGC率区间说明本科毕业论文≤20%部分宽松院校可放宽至30%硕士…

作者头像 李华
网站建设 2026/10/3 7:19:44

【333期】开源输入法,打字顺便学英语,天才思路!

如果你每天都要打字,为什么不能顺便学英语?能想到这个思路的真是个天才。这个开源项目真的是把输入法玩出了新花样。 边打字边记单词 它不是普通的拼音输入法,最大的特点就是你每输入一个中文词,它会在候选词旁边顺手显示对应的英…

作者头像 李华