更新于

外包或前员工走了,服务器权限怎么收回?查谁还能登录、换掉密码和密钥

外包合同到期了,或者员工离职了,而公司业务跑在一台由对方搭起来的服务器上。你不确定对方现在还能不能登录,也不知道他留下了哪些账号、密钥和定时任务。本文写给手里有一台 VPS、但没有技术背景的老板和创始人,只讲一件事:把权限收回来,而且按一个不会把自己锁在门外的顺序来做。 接手服务器后怎么摸清上面跑了什么,不在本文范围内,请看 接手别人搭的服务器,先查什么?;怀疑被入侵时怎么取证,请看 服务器被入侵了吗?。

使用前先看这几条:

1. 动服务器之前,先列出对方能碰到的所有地方

服务器只是其中一扇门。把对方有权限的地方逐个写下来,并注明是怎么进去的:他自己的账号、他知道的共用密码,还是专门给他开的密钥或 token。只记“在哪、归谁”,不要把密码本身写进去。

地方要查什么在那里要做什么
云账号(阿里云、腾讯云等的控制台、账单、AccessKey)他自己的子账号、他知道的共用登录、给他建的 AccessKey删掉他的子账号,改掉共用密码,禁用并删除他的 AccessKey,开启两步验证
域名注册商和 DNS同上同上
服务器管理面板或网页终端(比如宝塔),如果你在用面板用户、共用的面板密码删掉他的用户,或者改密码
服务器本身(SSH)账号、密钥、管理员权限下面第 2~4 步
代码仓库和发布流水线他的成员身份、部署密钥、token、流水线里的密钥移除他;更换密钥和 token(第 5 步)
数据库他自己的数据库账号、他看过的应用密码第 5 步
其他服务(邮件发送、支付、短信、对象存储、备份、监控)他的用户、他经手的 API 密钥移除他;更换密钥(第 5 步)
密码管理器、共享文档、工作群发给过他或和他共用的密码移除他;他看过的都当作已经泄露

2. 查一查:现在还有谁能登录这台服务器

【只读】 账号和管理员权限:

getent passwd | awk -F: '$7 !~ /(nologin|false|sync|shutdown|halt)$/ {print $1, $3, $6, $7}'
getent group sudo wheel admin
sudo grep -rE '^[^#]*ALL' /etc/sudoers /etc/sudoers.d/

【只读】 密码和 SSH 设置:

sudo passwd -S THEIR_USER
sudo sshd -T | grep -E '^(passwordauthentication|permitrootlogin|authorizedkeysfile) '

【只读】 SSH 密钥。密钥就像配了一把门钥匙:谁手里有对应的私钥,谁就能不输密码登录那个账号。

sudo find /root /home /srv /opt /var -path '*/.ssh/authorized_keys*' -type f -printf '\n%p  (last changed %TY-%Tm-%Td)\n' -exec ssh-keygen -lf {} \; 2>/dev/null

【只读】 最近的登录:

who
last -a -n 20 THEIR_USER
lslogins THEIR_USER

如果看到他在离职那天之后还登录过,或者现在有一个说不清的会话在线,就停下来,看后面的“看到不对劲,就停在这里”。想从日志里查完整的登录记录,看 服务器被入侵了吗? 的第 1 步。

这些命令不能说明:他能不能从别的路进来(云控制台、面板、VPN),也不能说明他手里有没有留着密码或数据的副本。它们只列出这台服务器上的门。

3. 先把自己的钥匙配好,并确认能用

这一步必须放在删除对方任何东西之前。如果你现在只能靠一个共用账号,或者靠他当初配的密钥登录,先删他的,很可能把自己也关在外面。

  1. 保持当前会话不要断开,整个过程都留着这个窗口。

  2. 在你自己的电脑上生成一把密钥(已经有的可以跳过)。这条命令在你的电脑上执行,不会改动服务器:

    ssh-keygen -t ed25519 -C "yourname-laptop"

    它会生成两个文件:一个是私钥,永远只留在你的电脑上,不要给任何人;另一个以 .pub 结尾,是公钥,放到服务器上的就是它。

  3. 【改动】把你的公钥加到服务器上你的账号里。 在你自己的电脑上执行:

    ssh-copy-id -i ~/.ssh/id_ed25519.pub YOUR_USER@SERVER_IP

    这条命令会把你的公钥追加到服务器上 YOUR_USER 的 authorized_keys 文件里。没有 ssh-copy-id 的话(比如 Windows),把 .pub 文件的内容作为新的一行粘贴进那个文件也可以。 回退: 从那个文件里删掉以 yourname-laptop 结尾的那一行(第 4 步有删除单行的方法)。

  4. 如果你一直在用共用账号(root,或者他建的某个账号),建议 【改动】给自己建一个带管理员权限的账号,再对它重复第 3 条:

    sudo adduser YOUR_NEW_USER
    sudo usermod -aG sudo YOUR_NEW_USER

    adduser 创建账号,并让你给它设密码(Debian、Ubuntu;红帽系系统用 sudo useradd -m YOUR_NEW_USER,再执行 sudo passwd YOUR_NEW_USER)。usermod -aG sudo 把它加进管理员组(红帽系系统把 sudo 换成 wheel)。 回退: sudo userdel -r YOUR_NEW_USER 会删掉这个账号和它的家目录。

  5. 开一个新窗口测试,旧窗口继续留着:

    ssh YOUR_USER@SERVER_IP
    sudo whoami

    第一条用你自己的密钥登录;第二条应该输出 root,说明你仍然有管理员权限。只要有一条不行,就先别往下做,用留着的那个会话查原因。

  6. 确认你的应急入口。 登录云厂商控制台,找到这台服务器的“远程连接”(通常叫 VNC 或救援登录)。SSH 连不上的时候,它照样能用。

4. 关掉对方的门:先备份,再锁定

先锁定,以后再删除。锁定一条命令就能恢复,删除却回不去。

【只读】 看看有什么在以他的身份运行,以及空间够不够放备份:

ps -u THEIR_USER -o pid,lstart,cmd
sudo crontab -l -u THEIR_USER
sudo du -sh /home/THEIR_USER
df -h /root

如果你的网站、应用或者备份是以他的账号在跑,下面照样锁定登录,但先不要删账号。先计划把这些工作挪到公司自己的账号下(第 6 步),需要的话找人帮忙。

【只做备份,不改别的】

sudo mkdir -p /root/offboarding-backup
sudo cp -a /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/sudoers /etc/sudoers.d /root/offboarding-backup/
sudo tar -czf /root/offboarding-backup/home-THEIR_USER.tar.gz /home/THEIR_USER

确认一切正常之前,这个目录先留着。里面有密码的哈希值,用不着了就删掉。

【改动】锁定账号:

sudo usermod -L -e 1 THEIR_USER

-L 锁住密码(和 sudo passwd -l THEIR_USER 效果一样),-e 1 把账号标记为已过期,在常规配置下这也会挡住用 SSH 密钥登录。只锁密码,挡不住密钥登录。

【改动】删掉他的密钥。 他自己账号下的密钥文件,整个挪进备份目录:

sudo mv /home/THEIR_USER/.ssh/authorized_keys /root/offboarding-backup/authorized_keys.THEIR_USER

回退: sudo mv /root/offboarding-backup/authorized_keys.THEIR_USER /home/THEIR_USER/.ssh/authorized_keys

共用账号(root、deploy 之类)里,他的密钥和你的放在同一个文件里,这时只删他那一行。下面以 root 为例;换成别的账号时,把路径改成 /home/SHARED_USER/.ssh/authorized_keys,备份文件也按账号命名。

sudo cp -a /root/.ssh/authorized_keys /root/offboarding-backup/authorized_keys.root
sudo awk 'NF && !/^#/ {print NR": "$NF}' /root/.ssh/authorized_keys
sudo sed -i '4d' /root/.ssh/authorized_keys

删完之后,再跑一遍第 2 步查密钥的命令:你的密钥应该还在,他的应该没了。再开一个新窗口登录一次,确认无误。 回退: sudo cp -a /root/offboarding-backup/authorized_keys.root /root/.ssh/authorized_keys

【改动】移走他的管理员权限文件(如果第 2 步看到 /etc/sudoers.d/ 里有专门给他的文件):

sudo mv /etc/sudoers.d/THEIR_FILE /root/offboarding-backup/
sudo visudo -c

mv 把这个文件挪走,它就不再生效;visudo -c 检查剩下的管理员权限配置是否仍然有效。千万不要用普通编辑器改 /etc/sudoers,改错了可能所有人都用不了管理员权限。如果他的规则直接写在 /etc/sudoers 里,先不用管(账号已锁定,他登录不进来),等删账号时再用 sudo visudo 删掉那一行。 回退: sudo mv /root/offboarding-backup/THEIR_FILE /etc/sudoers.d/

【改动】改掉他知道的共用账号密码:

sudo passwd root
sudo passwd SHARED_USER

每条命令给对应账号设一个新密码,要输两次,输入时屏幕上不显示任何字符,这是正常的。关掉窗口之前,先把新密码存进密码管理器;如果你平时用这个密码登录,开一个新窗口试一下。 回退: 旧密码回不去了,这正是目的。万一出问题,可以用一直开着的那个会话重新设置。

5. 换掉他看过的密码和密钥

他能看到的,就可能复制走了。只在服务器上改密码不够,应用也得用上新的。每一个密钥都按这个顺序来:先生成新的,填到用它的地方,重启应用,确认网站正常,最后才停用旧的。 旧的停用之前,随时可以切回去。

【只读】 看看有哪些密钥,只显示名字:

sudo find /root /home /srv /opt /var \( -name '.env' -o -name '.env.*' \) -type f -not -path '*/node_modules/*' 2>/dev/null
sudo grep -oE '^(export +)?[A-Za-z_][A-Za-z0-9_]*=' /path/to/app/.env
docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' YOUR_CONTAINER | cut -d= -f1
sudo find /root /home /srv /opt /var -path '*/.ssh/id_*' -not -name '*.pub' -type f 2>/dev/null

名字里带 PASSWORD、SECRET、TOKEN、KEY、URL(连接地址里经常带着密码)的,就是要换的。不要在共享屏幕上打开这些文件,也不要把内容粘贴到聊天工具或 AI 里。

【只读,数据库允许的话】 列出数据库账号(不会显示密码):

sudo mysql -e "SELECT user, host FROM mysql.user;"
sudo -u postgres psql -c '\du'

第一条用于 MySQL 或 MariaDB,第二条用于 PostgreSQL,用你有的那个。以他名字命名的账号应该删掉;host 为 % 表示这个账号可以从任何地方连接。删数据库账号、改数据库密码,都是要对照着应用配置来做的改动,最好有人帮忙。

要换什么,换完还要改哪里:

密钥在哪里换换完还要改
数据库密码数据库应用配置(.env 等),然后重启应用
应用密钥(会话密钥、签名密钥、内部 API 密钥)应用配置重启应用;换会话密钥通常会让所有用户重新登录
云账号 AccessKey云厂商控制台(子账号和 AccessKey)服务器上所有用到它的地方,比如 .env 或云命令行工具的配置
部署密钥和 token代码仓库和发布流水线的设置服务器上拉代码的配置、流水线里的密钥
第三方 API 密钥(邮件、支付、短信)各服务商后台应用配置,然后重启
他看过的你自己的密码(云、域名、面板、邮箱)各个网站开启两步验证

有些更换会带来副作用:用户被登出,新密钥没填好之前支付回调会失败。一次只换一个,挑业务少的时段,拿不准的找人帮忙。

6. 查一查他留下的定时任务和服务

【只读】

sudo crontab -l -u THEIR_USER
sudo grep -rn 'THEIR_USER' /etc/crontab /etc/cron.d /var/spool/cron 2>/dev/null
systemctl list-timers --all --no-pager
sudo grep -rl -E 'User=THEIR_USER|/home/THEIR_USER' /etc/systemd/system 2>/dev/null
ls /var/lib/systemd/linger/ 2>/dev/null
ls -la /home/THEIR_USER/.config/systemd/user/ 2>/dev/null

怎么看结果:

【改动】停掉你确认不需要的任务或服务:

sudo crontab -l -u THEIR_USER | sudo tee /root/offboarding-backup/crontab.THEIR_USER
sudo crontab -e -u THEIR_USER
sudo systemctl disable --now SERVICE_NAME

7. 过一段时间再删账号

等第 6 步处理完,再过一两周,确认什么都没坏,然后:

【改动,没有简单的回退办法】

sudo userdel THEIR_USER
sudo find / -xdev -nouser -ls 2>/dev/null | head -n 20

全部做完后,在服务器以外的地方记一笔:哪天做的,锁了什么、删了什么、换了什么,备份放在哪。

看到不对劲,就停在这里

看到下面任何一种情况,就不要再继续清理了:

锁定账号不会破坏证据,但删文件、删密钥、删任务、删账号会。先把看到的东西存到服务器以外的地方,再从第 0 步开始按 服务器被入侵了吗? 处理:先做快照,用云控制台里的防火墙规则限制流量,再找专业人员。至于前员工或外包在法律上该承担什么,要问律师,本文回答不了。

在 OpsMate 里怎么做

OpsMate 把 SSH 终端和 AI 放在同一个服务器页面。本文的命令你都可以直接手敲;大多数检查需要 sudo,自己手敲是最直接的办法。也可以用一句话问 AI,比如“总结最近 30 天有哪些账号通过 SSH 登录过、分别来自哪些 IP”。AI 会提出排查命令,除了看日志,也可以用 ps、ss、journalctl 这类命令做检查;命令跑完后,点击「需要分析」,AI 会给出结论。命令和输出都留在终端里,你可以拿原始记录核对 AI 的结论(用法见 终端里的「一句话 AI + 手敲命令」)。点击「需要分析」后,命令输出会发送给云端 AI 分析;桌面端默认保证的只是 SSH 凭证留在本机。配置文件和 .env 里装的正是你要换掉的密钥,内容绝不要发出去:用上面“只显示名字”的命令,只把脱敏后的片段交给 AI。

第 3~7 步里的改动都由你自己手敲,备份之后一条一条来。如果你用第 3 步生成的密钥连接,桌面端默认把 SSH 凭证保留在本机。

边界

说明性示例

说明性示例(不是真实客户案例):一家网店的 VPS 由外包搭建,合同上个月到期。第 2 步查到除 root 外还有两个账号:网店应用运行用的 deploy,以及在 sudo 组里的 mike。deploy 的密钥文件里有三把密钥:老板自己的、标签为 mike@macbook 的,还有一把没有标签的;root 的密钥文件里也有 mike@macbook。last 显示 mike 最后一次登录是在合同到期前三周,没有迹象表明他走后还用过。老板先把自己的密钥加到 deploy,开新窗口登录成功,sudo whoami 输出 root。ps -u mike 没有任何程序在跑,但 sudo crontab -l -u mike 里有一个每晚执行的数据库备份,写到 /home/mike/backups,而且这是网店唯一的备份。于是先请人帮忙把这个备份任务挪到 deploy 下,锁定之后它照样能跑。然后老板打包了 mike 的家目录,用 usermod -L -e 1 锁定账号,从两个密钥文件里删掉 mike@macbook;那把没标签的密钥也没人认领,一并删掉,删前都留了备份。对应用 .env 只看名字,查到 DB_PASSWORD、PAYMENT_API_KEY、SMTP_PASSWORD 和 AWS_ACCESS_KEY_ID,逐个更换:生成新值、填进去、重启、试下一单,最后停用旧的。两周后一切正常,才删掉账号。这些不能证明:外包手里没有留着网店数据的副本。新密钥能让旧的失效,但收不回已经拷走的东西。

AI 排查提示词

一位有这台服务器权限的外包已经离开,我正在收回他的权限。请先只做检查、不做任何改动:列出有登录 shell 的账号,sudo、wheel、admin 组的成员,/etc/sudoers 和 /etc/sudoers.d 里的规则,所有 authorized_keys 文件及其最后修改日期、每把密钥的指纹和标签,THEIR_USER 最近的登录记录,以 THEIR_USER 身份运行的程序,THEIR_USER 的 crontab,以及提到 THEIR_USER 或其家目录的 cron 文件、systemd 服务和 timer。对配置文件和 .env 只列配置项名字,绝不输出密钥的值。需要 sudo 的命令,请把要执行的命令原样列给我,由我来执行,不要自己运行。请区分已证实的事实和推测,并说明还缺少哪些信息。不要锁定、删除或修改任何账号、密钥、密码、crontab 或服务。如果需要改动,先给出最小步骤,以及它的备份方法、验证方法和回退方案,等我确认。如果看到滥用的迹象,直接告诉我并停下。

根据证据选择下一步

试用

每月免费 500 次 AI 调用,服务器数量不限。桌面端默认把 SSH 凭证保留在本机。

需要帮助理解排查结果?

OpsMate 帮助开发者和运维人员用 AI 辅助排查,由你核对证据。点击「需要分析」后,命令输出会发送给云端 AI 分析,请先去除敏感信息。

免费开始 本地凭证桌面端

排障指南