工作记录
Todo
Process
继续设计更安全的 vps 部署方式:
- 部署内容,全部放到 /work 下;/work owner 是 deployer:work; www-data, www-service 都在 work group 下
- nginx + 资源文件:用 www-data 用户和目录; www-data 家目录具体在 /work/www-data;nginx 的 log 依然放到标准位置
- Gunicorn + Python, 用 www-service 用户和目录; www-service 加目录在 /work/www-service
- github action deploy 还是用 ssh, 但是用一个单独的
deployer+ ssh-key. 涉及的 root 操作,用 sudo + 允许的脚本来控制权限。脚本需要是 root 权限,也就是当前用户不能去修改脚本内容,避免被攻破后执行新的内容 - xray, sing-box 改用 proxy-service 用户和目录;放到 work group 下
- 停用 root 用户;建自己的用户名
- grafana 接收全部的 log, 不要在意这么点流量
- secrets 这块,目前的想法:
- conf/secrets 分开
- secrets 仓库就只放 secrets, 保证每次部署后 pull 下来就删掉; pull 仓库的 key 由内存环境变量注入(prod 上就是 github action 里;绝对不在 prod 里去手动 export env 然后触发;最好永远用 action 触发;调试用 staging/本地 ubuntu 机器)
- 隐私风险不高的 private conf, 如果比较大,就还是放到 root 账户下,通过 git 同步;不再软链接,全部 copy + 改权限。反正部署的时候全都用脚本,所以还好;
- 部署服务,都用 root 用户(自有名字);通过脚本方式完成,方便后续被入侵后重装再部署。
把 Latest snapshot 备份回 vps 上 [done]
- rsync 3 批次
- TTS 音频依旧不完整;调用 update-cached-tts 完成新增 68 个
我靠,有发现 /home/user 这个目录了,幸好暂时没有 service 这个目录;是通过看 nft 端口发现的异常,而且是有 c2 通信的?出口是阿里巴巴云。
还有一个启动的 qemu 程序,先删除了。新的部署迫在眉睫了! 不知道是哪里中的东西。
这是 SSH 的一个非常强大且隐蔽的特性,叫做 ForceCommand(强制指令)。
秘诀不在你的 GitHub Action 命令里,而是在 VPS 的 .ssh/authorized_keys 文件里。
原理解析:它是如何工作的?
当你执行 rsync ... deployer@vps:/path 时,底层其实是 SSH 连接到 VPS 并尝试运行一段类似 rsync --server ... 的指令。
SSH 握手:GitHub Action 用 deployer 的私钥连接 VPS。
触发强制指令:VPS 的 SSH 服务端在 authorized_keys 里找到了这个公钥。因为你在这个公钥前面写了 command="/usr/local/bin/deploy-gatekeeper.sh",SSH 会无视 GitHub 传过来的任何指令,强行先运行这个脚本。
捕获原始意图:虽然 SSH 拦截了原始指令,但它并没把它丢掉,而是把它存到了一个环境变量里:$SSH_ORIGINAL_COMMAND。
脚本接管:
如果 GitHub 发起的是 rsync,$SSH_ORIGINAL_COMMAND 的内容大概是 rsync --server -vnlogDtpre.iLsfxC . /work/www-data/。
如果 GitHub 发起的是 ssh deployer@vps "deploy-finish-api",$SSH_ORIGINAL_COMMAND 的内容就是 deploy-finish-api。
脚本分发:我们的 gatekeeper.sh 检查这个环境变量,发现是 rsync 且路径正确,就通过 exec sudo -u www-data rsync ... 把活儿接过来干完。
你需要做的配置
你需要在 VPS 上修改 deployer 用户的 authorized_keys 文件。
文件路径:/home/deployer/.ssh/authorized_keys
内容格式:
code
Text
download
content_copy
expand_less
command="/usr/local/bin/deploy-gatekeeper.sh",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA....你的公钥....
为什么在 GitHub Action 里看起来是“正常写”?
在 GitHub Action 侧,你不需要做任何特殊改动:
code
Yaml
download
content_copy
expand_less
- name: Sync API
run: |
# 这一行发出去后,VPS 的 SSH 发现是这个特定 Key 登录,
# 就会自动把这行命令塞进环境变量,并运行 gatekeeper.sh
rsync -avz ./dist/ deployer@your-vps-ip:/work/www-service/api/
这种方式的妙处:
完全透明:你本地的部署脚本、IDE 的部署插件、甚至 GitHub Action 的官方 rsync-action 都不需要修改,它们都以为自己在和一个普通的 SSH 用户通信。
绝对安全:即使黑客绕过了 GitHub Action,拿到了你的私钥,他执行 ssh deployer@vps。由于 authorized_keys 锁死了 command,他一登录就会运行 gatekeeper.sh。因为他没提供任何预设指令,脚本会直接报错退出,他连 Shell 的边都摸不到。
参数过滤:我们在 gatekeeper.sh 里检查 $SSH_ORIGINAL_COMMAND,如果黑客想玩花样(比如执行 rsync --server ; rm -rf /),我们可以在脚本里用正则表达式直接把它杀掉。
总结流程:
GitHub 发送命令:rsync ...
VPS SSHD 拦截并改运行:/usr/local/bin/deploy-gatekeeper.sh
gatekeeper.sh 读取环境变量:SSH_ORIGINAL_COMMAND="rsync ..."
gatekeeper.sh 验证无误,执行:sudo -u www-data rsync ...
这就是为什么你不需要在 rsync 命令里显式调用脚本的原因——SSH 服务器已经帮你“劫持”并路由好了。
生活记录
5 点左右黄车车醒来,要起来;起来后就不愿意躺着了;最后好好抱着在沙发上睡着了。 扭着身子,看着都心疼啊。
不知道今晚会怎么睡觉觉呢?一直躺着不能动确实很难受,毕竟自己以前做肾穿刺的时候躺了半天就不行了,一个成人无痛的情况下尚且如此, 一个娃娃锁骨断了就更加痛苦了。
情绪记录
Good
Bad
Reflect
妈妈让我把数据再恢复到被 hack 前的最新状态。我一开始有点不愿意,但想想,自己确实应该做到啊。