技术交流QQ群:①185473046   ②190706903   ③203744115   网站地图
登录

下次自动登录
现在的位置: 首页Linux>正文
基于源 IP 白名单的 SSH 会话级 sudo 访问控制方案-实现单账号多权限安全隔离
2026年01月22日 Linux 暂无评论 ⁄ 被围观 24次+

1、场景描述

服务端ip:192.168.21.159

客户端ip:192.168.21.137、192.168.21.204

1.1 在服务端的主机上创建普通账号autoops

#登录服务端主机,创建普通账号

useradd -m -s /bin/bash autoops

passwd autoops #设置密码

1.2 设置此账号具有sudo权限

#添加普通用户到wheel组,使其具有sudo权限

gpasswd -a autoops wheel

#验证wheel组

cat /etc/group |grep wheel

id autoops

可以看到autoops用户已经是在wheel组了

#从普通用户autoops登录服务器

执行sudo cp命令验证,已经具有sudo权限

1.3 设置sudo免密权限

#设置sudo免密执行

vi /etc/sudoers #编辑

autoops ALL=(ALL) NOPASSWD: ALL

:wq! #保存退出

现在从autoops登录后执行sudo命令已经不需要再输入密码了

2、设置客户端主机

2.1 创建普通账号autoops

#登录所有客户端主机,分别创建普通账号

useradd -m -s /bin/bash autoops

passwd autoops #设置密码

2.2 配置客户端主机ssh免密登录服务端主机

#在所有客户端主机上操作

#192.168.21.137、192.168.21.204分别操作

#切换到autoops用户

ssh-keygen #输入命令,按三次回车,会生成私钥和公钥

cd /home/autoops/.ssh #进入目录,会看到生成的私钥和公钥

#拷贝公钥

ssh-copy-id autoops@192.168.21.159 #输入192.168.21.159的autoops密码

现在从192.168.21.137、192.168.21.204分别ssh登录192.168.21.159已经不需要输入密码了

ssh autoops@192.168.21.159

3、根据ip地址限制sudo权限

需求:

1、允许192.168.21.137使用autoops用户ssh登录192.168.21.159,登录之后可以执行sudo命令

2、允许192.168.21.204使用autoops用户ssh登录192.168.21.159,登录之后禁止执行sudo命令,其它操作不受限制

3.1 在服务端主机操作

登录192.168.21.159

#切换到autoops用户

cp ~/.bashrc ~/.bashrc.bak #备份

vi ~/.bashrc #在最后添加下面的代码

# ==================================================================

# Advanced IP Whitelist with CIDR Support for sudo access control

# Author: DevOps

# ==================================================================

# Function: ip_in_cidr <IP> <CIDR>

# Returns 0 if IP is in CIDR, 1 otherwise

ip_in_cidr() {

local ip="$1"

local cidr="$2"

local mask

# Extract net and bits

local net="${cidr%/*}"

local bits="${cidr#*/}"

# Validate bits

if [[ "$bits" -lt 1 || "$bits" -gt 32 ]]; then

return 1

fi

# Convert IP and net to 32-bit integers

IFS=. read -r i1 i2 i3 i4 <<< "$ip"

IFS=. read -r n1 n2 n3 n4 <<< "$net"

local ip_int=$(( (i1 << 24) + (i2 << 16) + (i3 << 8) + i4 ))

local net_int=$(( (n1 << 24) + (n2 << 16) + (n3 << 8) + n4 ))

local mask=$(( (0xFFFFFFFF << (32 - bits)) & 0xFFFFFFFF ))

# Compare network part

if (( (ip_int & mask) == (net_int & mask) )); then

return 0

else

return 1

fi

}

# Main sudo access control

if [ -n "$SSH_CONNECTION" ]; then

CLIENT_IP=$(echo "$SSH_CONNECTION" | cut -d' ' -f1)

# Define whitelist: single IPs and CIDR blocks

ALLOWED_LIST=(

"192.168.21.137"

"172.17.31.222"

"10.103.128.192/27"

)

ALLOWED=false

for item in "${ALLOWED_LIST[@]}"; do

if [[ "$item" == */* ]]; then

# It's a CIDR

if ip_in_cidr "$CLIENT_IP" "$item"; then

ALLOWED=true

break

fi

else

# It's a single IP

if [[ "$CLIENT_IP" == "$item" ]]; then

ALLOWED=true

break

fi

fi

done

if [[ "$ALLOWED" == false ]]; then

sudo() {

echo "错误:您的 IP 地址 $CLIENT_IP 无权执行 sudo 命令" >&2

echo "请联系管理员申请访问权限" >&2

return 1

}

export -f sudo

fi

fi

:wq! #保存退出

3.2 参数说明

1、$SSH_CONNECTION 环境变量

SSH 登录时由 OpenSSH 自动设置,格式为:<客户端IP> <客户端端口> <服务端IP> <服务端端口>

→ cut -d' ' -f1 可准确提取源 IP

2、纯 Bash 实现 CIDR 判断

通过位运算将 IP 和子网掩码转为整数,精确判断是否在网段内

→ 无需依赖 ipcalc、python 等外部工具,兼容所有 Linux 发行版

3、函数覆盖 sudo

在非白名单 IP 的 SSH 会话中,sudo 被重定义为一个报错函数

→ 用户输入 sudo xxx 会直接失败,无法绕过(除非修改 .bashrc)

4、不影响本地任务

cron、systemd、本地 shell 脚本 没有 $SSH_CONNECTION,所以不会触发限制

→ autoops 的全局 sudo 权限依然可用

3.3 使配置文件生效

source ~/.bashrc

4、效果验证

当从非白名单 IP 192.168.21.204 执行 sudo 时,用户将看到:

错误:您的 IP 地址 192.168.21.204 无权执行 sudo 命令。

请联系管理员申请访问权限。

当从白名单 IP 192.168.21.137 执行 sudo 时,一切正常。

#安全加固建议,root权限执行

sudo chattr +i /home/autoops/.bashrc

#如需修改,先执行:

sudo chattr -i /home/autoops/.bashrc

至此,基于源 IP 白名单的 SSH 会话级 sudo 访问控制方案完成。

     

  系统运维技术交流QQ群:①185473046 系统运维技术交流□Ⅰ ②190706903 系统运维技术交流™Ⅱ ③203744115 系统运维技术交流™Ⅲ

给我留言

您必须 [ 登录 ] 才能发表留言!



Copyright© 2011-2026 系统运维 All rights reserved
版权声明:本站所有文章均为作者原创内容,如需转载,请注明出处及原文链接
陕ICP备11001040号-3