AI 服务器部署与权限隔离-从零搭建到生产校验完整教程

AI 服务器部署与权限隔离-从零搭建到生产校验完整教程

AI 服务器部署与权限隔离:从零搭建到生产校验完整教程

操作指南MD下载原文件
# AI 服务器部署与权限隔离:从零搭建到生产校验完整教程

本文使用一个完全虚构的案例进行讲解,不包含任何真实服务器 IP、SSH Key、用户名、项目路径或其他敏感信息。

假设我们有一个 AI 助手叫 小明,需要让它登录 Linux 服务器完成“检查”和“部署”工作,但又不能让它拥有服务器管理员权限。


01. 先确定我们的目标

假设服务器管理员叫:

serveradmin

AI 叫:

小明

服务器示例 IP:

192.0.2.10

网站项目:

demo-site

我们不允许出现这种结构:

小明
  ↓
serveradmin
  ↓
sudo
  ↓
root
  ↓
整台服务器

因为一旦 AI 执行错误命令,理论上可能影响整台服务器。

我们要做成:

                    Linux Server
                         │
             ┌───────────┴───────────┐
             │                       │
        serveradmin                 小明
             │                       │
            sudo              ┌──────┴──────┐
             │                │             │
            root        xiaoming-audit  xiaoming-deploy
                              │             │
                            只读          有限部署

核心原则只有一句:

不是禁止 AI 工作,而是只给 AI 完成当前任务所必需的权限。

这就是最小权限原则:

Least Privilege

02. 为什么要给同一个 AI 两个账号

虽然它们背后都是“小明”,但服务器不应该把“小明”当成一个万能身份。

我们把它拆成:

xiaoming-audit

负责:

查看
检查
审计
读取日志
检查待发布文件

但是:

不能修改
不能部署
不能 sudo

另一个:

xiaoming-deploy

负责:

上传部署候选文件
修改部署缓冲区
准备新版本

但是:

不能直接修改正式网站
不能 sudo
不能获得 root

于是同一个 AI:

小明
│
├── xiaoming-audit
│      └── 只读身份
│
└── xiaoming-deploy
       └── 部署身份

拿哪把 SSH Key 登录,就获得哪套权限。


03. 创建权限组

先不要创建账号。

先创建两个“角色组”。

审计组:

sudo groupadd demo-audit

部署组:

sudo groupadd demo-deploy

验证:

getent group demo-audit demo-deploy

正常会看到类似:

demo-audit:x:1001:
demo-deploy:x:1002:

这一步的思想是:

权限尽量赋予“角色”,而不是散落到某个具体用户身上。

以后再增加其他 AI,只需要把它加入对应组。


04. 创建小明的两个 Linux 身份

创建审计账号:

sudo adduser --disabled-password --gecos "" --ingroup demo-audit xiaoming-audit

创建部署账号:

sudo adduser --disabled-password --gecos "" --ingroup demo-deploy xiaoming-deploy

这里:

--disabled-password

表示不准备让这些 AI 用户使用普通 Linux 密码登录。

后面我们使用:

SSH Public Key Authentication

也就是 SSH 公钥认证。


05. 检查身份是否正确

执行:

id xiaoming-audit

应该看到类似:

uid=1001(xiaoming-audit)
gid=1001(demo-audit)
groups=1001(demo-audit)

再检查部署账号:

id xiaoming-deploy

应该类似:

uid=1002(xiaoming-deploy)
gid=1002(demo-deploy)
groups=1002(demo-deploy)

于是:

xiaoming-audit
      ↓
demo-audit

xiaoming-deploy
      ↓
demo-deploy

06. 检查 AI 有没有 sudo

这一关非常重要。

检查审计账号:

sudo -l -U xiaoming-audit

检查部署账号:

sudo -l -U xiaoming-deploy

理想结果:

User xiaoming-audit is not allowed to run sudo

以及:

User xiaoming-deploy is not allowed to run sudo

绝对不要出现:

ALL=(ALL) ALL

或者:

NOPASSWD: ALL

否则前面的身份隔离意义会大幅降低。


07. 把“上传区”和“正式网站”彻底分开

这是整套方案非常重要的一层。

不要让 AI 直接把网站上传到:

/var/www/

而是准备两个区域。

AI 部署缓冲区

/srv/demo-deploy/
└── incoming/

创建:

sudo mkdir -p /srv/demo-deploy/incoming

正式生产区

/var/www/demo-site/
└── releases/

创建:

sudo mkdir -p /var/www/demo-site/releases

于是整个过程变成:

小明
 ↓
incoming
 ↓
检查
 ↓
发布 Gate
 ↓
releases
 ↓
current
 ↓
正式网站

而不是:

小明
 ↓
直接覆盖正式网站

08. 给 Deploy 身份开放 incoming

先把部署目录组设为:

demo-deploy

执行:

sudo chown root:demo-deploy /srv/demo-deploy /srv/demo-deploy/incoming

设置上层目录:

sudo chmod 0750 /srv/demo-deploy

设置 incoming:

sudo chmod 2770 /srv/demo-deploy/incoming

检查:

sudo ls -ld /srv/demo-deploy /srv/demo-deploy/incoming

应该类似:

drwxr-x--- root demo-deploy /srv/demo-deploy
drwxrws--- root demo-deploy /srv/demo-deploy/incoming

09. 为什么 incoming 使用 2770

这里:

2770

中的:

2

表示:

setgid

它的作用是:

在这个目录中新创建的内容,会自动继承目录所属的 Group。

例如小明部署账号创建:

build.zip

最终可能是:

owner:xiaoming-deploy
group:demo-deploy

以后即使再增加另一个部署 Agent,只要也属于:

demo-deploy

就能按部署组规则协作。


10. 第一次做越权测试

千万不要只看:

chmod
chown

然后觉得“应该没问题”。

真正的权限体系一定要实际攻击一次。

让部署账号在允许位置创建文件:

sudo -u xiaoming-deploy touch /srv/demo-deploy/incoming/deploy-test.txt

这条应该:

成功

然后让它尝试直接碰生产区:

sudo -u xiaoming-deploy touch /var/www/demo-site/should-fail.txt

应该得到:

Permission denied

于是我们真正证明:

xiaoming-deploy

incoming     ✅ 可以写
production   ❌ 不可以写

11. 使用 ACL 做更细粒度权限控制

Linux 普通权限主要有:

Owner
Group
Other

对于复杂的协作场景,有时不够精细。

所以安装 ACL:

sudo apt update
sudo apt install -y acl

确认:

command -v setfacl

正常:

/usr/bin/setfacl

12. 给部署区设置默认 ACL

设置当前权限:

sudo setfacl -m g::rwx,m::rwx /srv/demo-deploy/incoming

再设置以后新内容自动继承:

sudo setfacl -d -m u::rwx,g::rwx,m::rwx,o::--- /srv/demo-deploy/incoming

检查:

sudo getfacl /srv/demo-deploy/incoming

应该类似:

user::rwx
group::rwx
mask::rwx
other::---

default:user::rwx
default:group::rwx
default:mask::rwx
default:other::---

这样部署区的新内容会自动继承部署协作权限。


13. 给 Audit 身份只读权限

现在让:

xiaoming-audit

能够检查 incoming。

但只能读。

执行:

sudo setfacl -m g:demo-audit:rx /srv/demo-deploy /srv/demo-deploy/incoming

再给未来新文件设置继承规则:

sudo setfacl -d -m g:demo-audit:rx /srv/demo-deploy/incoming

检查:

sudo getfacl /srv/demo-deploy/incoming

应该出现:

group:demo-audit:r-x

以及:

default:group:demo-audit:r-x

注意:

r = read
x = traverse / 进入目录

没有:

w

所以审计组不能写。


14. 真正验证“Audit 能看不能改”

先让部署身份创建文件:

sudo -u xiaoming-deploy sh -c 'echo "production candidate" > /srv/demo-deploy/incoming/audit-test.txt'

再让审计身份读取:

sudo -u xiaoming-audit cat /srv/demo-deploy/incoming/audit-test.txt

应该输出:

production candidate

然后尝试修改:

sudo -u xiaoming-audit sh -c 'echo "illegal change" >> /srv/demo-deploy/incoming/audit-test.txt'

必须失败:

Permission denied

再尝试创建:

sudo -u xiaoming-audit touch /srv/demo-deploy/incoming/audit-should-fail.txt

仍然必须:

Permission denied

于是:

xiaoming-audit

读取 incoming   ✅
修改 incoming   ❌
创建文件         ❌

15. 正式生产版本必须收归 root

假设 incoming 中的内容已经检查通过。

现在创建一个正式版本:

sudo mkdir -p /var/www/demo-site/releases/v1

把候选内容复制进去:

sudo cp -a /srv/demo-deploy/incoming/. /var/www/demo-site/releases/v1/

然后正式收归:

sudo chown -R root:root /var/www/demo-site/releases/v1

设置常见静态网站权限:

目录:

sudo find /var/www/demo-site/releases/v1 -type d -exec chmod 755 {} \;

文件:

sudo find /var/www/demo-site/releases/v1 -type f -exec chmod 644 {} \;

检查:

sudo ls -la /var/www/demo-site/releases/v1

生产区应该由:

root:root

控制。

这一步意味着:

AI 创建的候选内容一旦正式进入生产区,就失去了继续修改正式版本的能力。


16. 使用 releases + current 管理版本

生产目录设计成:

/var/www/demo-site/
│
├── releases/
│   ├── v1/
│   ├── v2/
│   └── v3/
│
└── current

Web Server 永远只看:

/var/www/demo-site/current

比如第一次上线:

sudo ln -s releases/v1 /var/www/demo-site/current

查看:

sudo readlink -f /var/www/demo-site/current

结果:

/var/www/demo-site/releases/v1

于是:

current → v1

17. 为什么不直接覆盖网站

假设现在发布:

v2

如果直接覆盖:

v1

一旦新版本有问题,旧版本已经被改掉了。

而 Release 模型是:

releases/
├── v1
└── v2

current → v1

准备好 v2 后:

current → v2

v2 出问题:

current → v1

旧版本从来没有被覆盖。


18. 原子切换 current

不建议:

rm current
ln -s releases/v2 current

因为删除和重建之间存在短暂空档。

更好的方法:

先准备:

sudo ln -s releases/v2 /var/www/demo-site/current.new

然后:

sudo mv -Tf /var/www/demo-site/current.new /var/www/demo-site/current

检查:

sudo readlink -f /var/www/demo-site/current

现在应该:

current → v2

19. 回滚

假设 v2 上线后发现故障。

建立:

sudo ln -s releases/v1 /var/www/demo-site/current.rollback

原子替换:

sudo mv -Tf /var/www/demo-site/current.rollback /var/www/demo-site/current

检查:

sudo readlink -f /var/www/demo-site/current

重新变成:

current → v1

这就是快速回滚。


20. 再攻击一次生产区

让部署身份尝试修改 current:

sudo -u xiaoming-deploy touch /var/www/demo-site/current/deploy-should-fail.txt

应该:

Permission denied

让部署身份直接创建 release:

sudo -u xiaoming-deploy touch /var/www/demo-site/releases/illegal-release.txt

也应该:

Permission denied

Audit:

sudo -u xiaoming-audit touch /var/www/demo-site/current/audit-should-fail.txt

仍然:

Permission denied

到这里生产边界才算真正验证完成。


21. 给 AI 准备独立 SSH 入口

建立:

sudo install -d -m 700 -o xiaoming-audit -g demo-audit /home/xiaoming-audit/.ssh

部署账号:

sudo install -d -m 700 -o xiaoming-deploy -g demo-deploy /home/xiaoming-deploy/.ssh

检查:

sudo ls -ld /home/xiaoming-audit/.ssh /home/xiaoming-deploy/.ssh

应该:

drwx------

22. 在 Windows 本地生成两把 SSH Key

注意:

私钥必须生成在本地电脑,不是在服务器上。

Windows CMD:

mkdir "%USERPROFILE%\.ssh\demo"

审计钥匙:

ssh-keygen -t ed25519 -f "%USERPROFILE%\.ssh\demo\xiaoming-audit" -C "xiaoming-audit@demo"

部署钥匙:

ssh-keygen -t ed25519 -f "%USERPROFILE%\.ssh\demo\xiaoming-deploy" -C "xiaoming-deploy@demo"

最后得到:

xiaoming-audit
xiaoming-audit.pub

xiaoming-deploy
xiaoming-deploy.pub

其中:

没有 .pub = 私钥
带 .pub   = 公钥

最重要的原则

私钥:
只留本地

公钥:
可以放服务器

不要把 AI 私钥放进 GitHub。

不要发到聊天群。

不要上传到服务器。


23. 把公钥装进服务器

Windows 查看审计公钥:

type "%USERPROFILE%\.ssh\demo\xiaoming-audit.pub"

复制整行。

服务器写入:

printf '%s\n' '这里放 xiaoming-audit 公钥' | sudo tee /home/xiaoming-audit/.ssh/authorized_keys >/dev/null

然后:

sudo chown xiaoming-audit:demo-audit /home/xiaoming-audit/.ssh/authorized_keys
sudo chmod 600 /home/xiaoming-audit/.ssh/authorized_keys

部署身份同理:

printf '%s\n' '这里放 xiaoming-deploy 公钥' | sudo tee /home/xiaoming-deploy/.ssh/authorized_keys >/dev/null

然后:

sudo chown xiaoming-deploy:demo-deploy /home/xiaoming-deploy/.ssh/authorized_keys
sudo chmod 600 /home/xiaoming-deploy/.ssh/authorized_keys

24. 从 Windows 真正登录 Audit

在 Windows:

ssh -i "%USERPROFILE%\.ssh\demo\xiaoming-audit" xiaoming-audit@192.0.2.10

登录以后:

whoami

必须:

xiaoming-audit

读候选文件:

cat /srv/demo-deploy/incoming/audit-test.txt

应该成功。

尝试修改:

echo "illegal" >> /srv/demo-deploy/incoming/audit-test.txt

应该:

Permission denied

尝试碰生产区:

touch /var/www/demo-site/current/should-fail.txt

应该:

Permission denied

25. 从 Windows 真正登录 Deploy

执行:

ssh -i "%USERPROFILE%\.ssh\demo\xiaoming-deploy" xiaoming-deploy@192.0.2.10

确认:

whoami

输出:

xiaoming-deploy

写 incoming:

echo "deploy test" > /srv/demo-deploy/incoming/real-deploy-test.txt

应该成功。

再碰生产:

touch /var/www/demo-site/releases/should-fail.txt

应该:

Permission denied

26. 管理员必须有自己的 Break-glass Key

AI 的 Key 不能当管理员 Key 使用。

管理员:

serveradmin

应该单独生成:

ssh-keygen -t ed25519 -f "%USERPROFILE%\.ssh\demo\admin-breakglass" -C "admin-breakglass@demo"

这把 Key 建议设置:

Passphrase

因为它对应:

admin-breakglass
       ↓
serveradmin
       ↓
sudo
       ↓
root

这是最高权限钥匙。


27. 安装 Break-glass 时不要覆盖旧公钥

先看:

sudo wc -l /home/serveradmin/.ssh/authorized_keys

先备份:

sudo cp -a /home/serveradmin/.ssh/authorized_keys /home/serveradmin/.ssh/authorized_keys.backup

然后添加新公钥必须使用:

tee -a

例如:

printf '%s\n' '这里放 admin-breakglass 公钥' | sudo tee -a /home/serveradmin/.ssh/authorized_keys >/dev/null

注意:

-a = append

也就是追加。

不是覆盖。

然后:

sudo chmod 700 /home/serveradmin/.ssh
sudo chmod 600 /home/serveradmin/.ssh/authorized_keys

28. 验证管理员救援链

Windows:

ssh -i "%USERPROFILE%\.ssh\demo\admin-breakglass" serveradmin@192.0.2.10

登录以后:

whoami

应该:

serveradmin

再:

sudo whoami

应该:

root

于是管理员链:

本地电脑
   ↓
admin-breakglass
   ↓
serveradmin
   ↓
sudo
   ↓
root

只有管理员拥有这一条链。


29. SSH 最终加固

注意:

一定要先验证管理员 Break-glass 能登录,再改 SSH。

查看真正生效配置:

sudo sshd -T | grep -E '^(port|permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|maxauthtries|x11forwarding|allowtcpforwarding|allowagentforwarding) '

推荐目标:

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no

30. 先备份 SSH 配置

sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

然后创建独立配置:

sudo tee /etc/ssh/sshd_config.d/00-demo-hardening.conf >/dev/null <<'EOF'
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
EOF

31. SSH 配置绝不能直接 reload

先:

sudo sshd -t

如果:

没有任何输出

说明语法通过。

再查看:

sudo sshd -T | grep -E '^(permitrootlogin|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|maxauthtries|x11forwarding|allowtcpforwarding|allowagentforwarding) '

确认正确以后才:

sudo systemctl reload ssh

检查:

sudo systemctl is-active ssh

应该:

active

32. 为什么旧 Admin 窗口不能关

修改 SSH 时最重要的安全习惯之一:

旧 admin SSH 会话
        │
        │ 保持在线
        ▼
修改 SSH
        │
        ▼
reload
        │
        ▼
新开 Windows 窗口
        │
        ▼
重新登录 admin

如果新窗口失败:

旧窗口还在

就还能修。

如果一改配置就把旧窗口也关了:

可能把自己锁服务器外面

33. SSH 加固后重新验证

管理员:

ssh -i "%USERPROFILE%\.ssh\demo\admin-breakglass" serveradmin@192.0.2.10

检查:

whoami
sudo whoami

必须:

serveradmin
root

然后重新抽查小明 Deploy:

ssh -i "%USERPROFILE%\.ssh\demo\xiaoming-deploy" xiaoming-deploy@192.0.2.10

写 incoming:

echo "post hardening test" > /srv/demo-deploy/incoming/post-hardening-test.txt

成功。

写 production:

touch /var/www/demo-site/releases/should-fail.txt

必须:

Permission denied

说明 SSH 加固没有破坏 AI 正常工作链路。


34. 最后进行重启验收

所有操作完成以后:

sudo reboot

服务器恢复后重新登录:

ssh -i "%USERPROFILE%\.ssh\demo\admin-breakglass" serveradmin@192.0.2.10

检查:

whoami
sudo whoami
sudo systemctl is-active ssh

正确:

serveradmin
root
active

再抽查一次:

xiaoming-audit

和:

xiaoming-deploy

确认权限重启以后仍然存在。


35. 最终架构

整个系统最后应该是:

                       Linux Server
                            │
            ┌───────────────┴───────────────┐
            │                               │
       serveradmin                         小明
            │                               │
   admin-breakglass                 ┌───────┴────────┐
            │                       │                │
           sudo              xiaoming-audit  xiaoming-deploy
            │                       │                │
           root                   只读             有限写入
            │                       │                │
            │                  检查 incoming    写 incoming
            │                       │                │
            │                       └──────┬─────────┘
            │                              │
            │                        部署缓冲区
            │                              │
            └────────── 发布 Gate ─────────┘
                           │
                       releases
                           │
                        root:root
                           │
                        current
                           │
                       Web Server

36. 日常真正让 AI 工作时怎么用

如果只是让小明检查:

ssh -i "%USERPROFILE%\.ssh\demo\xiaoming-audit" xiaoming-audit@192.0.2.10

此时:

能看      ✅
能检查    ✅
能改      ❌
能 sudo   ❌

如果需要部署:

ssh -i "%USERPROFILE%\.ssh\demo\xiaoming-deploy" xiaoming-deploy@192.0.2.10

此时:

写 incoming     ✅
修改 incoming   ✅

写 releases     ❌
修改 current    ❌
sudo             ❌

管理员:

ssh -i "%USERPROFILE%\.ssh\demo\admin-breakglass" serveradmin@192.0.2.10

只有管理员:

serveradmin
 ↓
sudo
 ↓
root

37. 最终校验清单

身份层

  • serveradmin 是管理员
  • xiaoming-audit 是审计身份
  • xiaoming-deploy 是部署身份
  • 三者使用不同 SSH Key
  • AI 不使用管理员 SSH Key

Audit

  • 可以 SSH 登录
  • 可以读取 incoming
  • 不可以修改 incoming
  • 不可以创建文件
  • 不可以修改 production
  • 没有 sudo

Deploy

  • 可以 SSH 登录
  • 可以写 incoming
  • ACL 正常
  • setgid 正常
  • 不可以直接写 releases
  • 不可以修改 current
  • 没有 sudo

Production

  • releases 由 root:root 控制
  • 使用独立 Release
  • current 使用软链接
  • 支持原子发布
  • 支持快速回滚

管理员

  • 独立 Break-glass Key
  • 私钥设置 Passphrase
  • 可以 SSH 登录
  • 可以 sudo → root
  • AI 不拥有管理员私钥

SSH

  • Public Key 登录正常
  • PasswordAuthentication no
  • PermitRootLogin no
  • KbdInteractiveAuthentication no
  • MaxAuthTries 已收紧
  • X11Forwarding no
  • AllowTcpForwarding no
  • AllowAgentForwarding no
  • sshd -t 通过
  • SSH 服务 active

最终验收

  • 实际使用 Audit SSH 登录测试过
  • 实际使用 Deploy SSH 登录测试过
  • 实际做过 Permission denied 越权测试
  • 管理员 Break-glass 真登录测试过
  • 整机重启后再次验证过

38. 最后理解这套系统真正解决了什么

最危险的服务器 AI 使用方式是:

AI
 ↓
管理员账号
 ↓
root

而真正合理的模型应该是:

AI
 ↓
独立身份
 ↓
独立 SSH Key
 ↓
职责角色
 ↓
最小权限
 ↓
部署缓冲区
 ↓
验证
 ↓
发布 Gate
 ↓
生产环境

假设未来:

小明执行错命令
AI 提示词失控
某一把部署私钥泄露
部署脚本发生异常

攻击者或者错误程序得到的不是:

整台服务器

而只是:

xiaoming-deploy 本来就被允许操作的范围

例如:

/srv/demo-deploy/incoming

生产区仍然由:

root

控制。

这才是整个权限隔离系统真正的价值:

不是相信 AI 永远不会犯错,而是即使它犯错,系统也不给它把错误无限扩大的权限。