You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu系统下限制SSH用户总流量使用量的方法咨询

Ubuntu系统下限制SSH用户总流量使用量的方法咨询

你好!确实SSH本身没有内置的总流量限制功能,不过在Ubuntu上我们可以通过一些工具组合来实现这个需求,下面给你几个可行的方案:

方案一:利用iptables+流量统计脚本

这个思路是通过iptables针对特定用户的SSH流量做统计,然后配合脚本定期检查流量使用情况,达到阈值就断开用户连接或者阻止后续流量。

  1. 首先,为目标用户(比如User1)的SSH流量添加iptables规则,统计上传和下载流量:

    # 统计User1的SSH下载流量(从服务器到用户)
    iptables -A OUTPUT -p tcp --sport 22 -m owner --uid-owner User1 -j ACCEPT -m comment --comment "User1 SSH download"
    iptables -A OUTPUT -p tcp --sport 22 -m owner --uid-owner User1 -j RETURN -m comment --comment "Count User1 SSH download"
    # 统计User1的SSH上传流量(从用户到服务器)
    iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner User1 -j ACCEPT -m comment --comment "User1 SSH upload"
    iptables -A INPUT -p tcp --dport 22 -m owner --uid-owner User1 -j RETURN -m comment --comment "Count User1 SSH upload"
    

    这里可以直接用用户UID代替用户名(比如--uid-owner 1001),匹配会更准确。

  2. 编写一个简单的bash脚本,定期检查iptables的流量统计:

    #!/bin/bash
    USER="User1"
    LIMIT_GB=1
    LIMIT_BYTES=$((LIMIT_GB * 1024 * 1024 * 1024))
    
    # 获取下载流量(单位:字节)
    DOWNLOAD=$(iptables -L OUTPUT -v -n -x | grep "$USER SSH download" | awk '{print $2}')
    # 获取上传流量
    UPLOAD=$(iptables -L INPUT -v -n -x | grep "$USER SSH upload" | awk '{print $2}')
    TOTAL=$((DOWNLOAD + UPLOAD))
    
    if [ $TOTAL -ge $LIMIT_BYTES ]; then
        # 阻止该用户的SSH流量
        iptables -I INPUT -p tcp --dport 22 -m owner --uid-owner $USER -j DROP
        iptables -I OUTPUT -p tcp --sport 22 -m owner --uid-owner $USER -j DROP
        # 断开现有连接并记录日志
        pkill -u $USER sshd
        echo "User $USER has exceeded $LIMIT_GB GB SSH traffic limit." >> /var/log/ssh_traffic_limit.log
    fi
    
  3. 给脚本添加执行权限并保存到系统目录:

    chmod +x /usr/local/bin/ssh_traffic_check.sh
    
  4. 用crontab设置定期执行,比如每分钟检查一次:

    crontab -e
    

    添加一行定时任务:

    * * * * * /usr/local/bin/ssh_traffic_check.sh
    

    另外记得用iptables-save > /etc/iptables/rules.v4保存规则,避免重启后丢失。

方案二:使用cgroup v2限制进程总流量

Ubuntu 21.04及以上版本默认支持cgroup v2,我们可以为特定用户的SSH进程创建专属控制组,设置流量配额。

  1. 先确认cgroup v2已启用:

    mount | grep cgroup2
    

    如果没有输出,需要编辑/etc/default/grub,修改GRUB_CMDLINE_LINUX为:

    GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"
    

    执行update-grub后重启系统即可启用。

  2. 为User1创建cgroup目录:

    USER_UID=$(id -u User1)
    mkdir -p /sys/fs/cgroup/user.slice/user-${USER_UID}.slice/ssh-traffic-limit
    
  3. 设置总流量限制(这里是1GB,单位为字节):

    # 统一限制上传+下载总流量
    echo $((1 * 1024 * 1024 * 1024)) > /sys/fs/cgroup/user.slice/user-${USER_UID}.slice/ssh-traffic-limit/io.max
    # 若要分别限制上传下载,可指定设备(替换/dev/sda为你的网卡对应设备)
    # echo "/dev/sda:rbytes=1073741824,wbytes=1073741824" > /sys/fs/cgroup/user.slice/user-${USER_UID}.slice/ssh-traffic-limit/io.max
    
  4. 将User1的现有SSH进程加入控制组:

    for pid in $(pgrep -u User1 sshd); do
        echo $pid > /sys/fs/cgroup/user.slice/user-${USER_UID}.slice/ssh-traffic-limit/cgroup.procs
    done
    

    想要让新登录的SSH进程自动加入控制组,可以编写PAM规则或者修改sshd配置,实现登录时自动移入cgroup。

方案三:使用专门的流量配额工具

可以尝试系统自带的第三方工具,比如bwctl,安装后通过配置文件快速设置用户流量配额:

apt update && apt install bwctl

这类工具会帮你处理流量统计和限制的逻辑,不需要自己编写脚本,适合不想折腾的场景。

方案对比

  • 方案一灵活度高,无需额外安装工具,但需要维护脚本和规则,适合临时需求或自定义场景。
  • 方案二更偏向系统级管控,稳定性强,适合长期固定的流量限制需求。
  • 方案三操作最简单,但需要学习工具的配置逻辑。

备注:内容来源于stack exchange,提问作者shayan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 07:48:06