每日下载限制

每日下载限制

我正在寻找一种方法来为我的 Ubuntu 服务器设置每日互联网限制。所有出站流量都离开 Eth2,这是一个 USB 加密狗,这是预付费的,孩子们很快就会用完。我需要将我的预付费金额(通常为 12GB)分成每日配额,并在达到此金额后停止当天的流量。也许会有一个网页显示超出每日限制。

最好是来自 CLI 的某些东西。它是一个只有 SSH 访问权限的无头野兽。

VNSTAT 似乎可以满足我的需要,我只是没有脚本技能让它驱动 ifdown 命令。

谢谢。

答案1

我的建议是使用以下脚本,它将获取传入和传出流量的数据ifconfig interface-name,并将总和与预定义的限制值进行比较。此操作将每 5 秒重复一次(例如)。

当流量(收入+输出)等于或大于限制时,脚本将禁用目标接口并退出。禁用接口的实际值与限制值之间的最大差异将等于5sx MaxSpeed

该脚本可以通过 Cron 作业执行。因此,您可以为每周的每一天设置不同的作业,等等。此外,当达到限制时,您可以使用额外的流量手动运行脚本。

脚本名称应为traffic-watch,否则你应该更改它的第 5 行。我的建议是将其放在 中/usr/local/bin,这样它就可以用作 shell 命令了。别忘了让它可执行:chmod +x /usr/local/bin/traffic-watch

该脚本应以 root 身份执行 ( sudo)。它会创建一个日志文件:/tmp/traffic-watch-interface-name.log,您可以在其中检查最后一个操作。该脚本有两个输入变量:

  • $1= $LIMIT- 流量限制的值(以 MB 为单位)- 默认值为400
  • $2= $IFACE——目标网络接口的名称——默认值为eth0
  • 如果您想在脚本执行期间覆盖这些值,请使用以下格式:

    traffic-watch "250" "enp0s25"
    traffic-watch "250"
    traffic-watch "" "enp0s25"
    

将“traffic-watch”与“crontab”一起使用。如果您想要每天早上运行该脚本6:30,请打开 root 的 Crontab ( sudo crontab -e) 并添加以下行:

30 6 * * * /usr/local/bin/traffic-watch 2>/dev/null

手动使用‘traffic-watch’。要以 root 身份运行脚本并将其推送到后台,我们将使用sudo -b

sudo -b traffic-watch "150" 2>/dev/null

脚本‘traffic-watch’的内容是:

#!/bin/bash

# Initialize
[ -z "${1}" ] && LIMIT="400"  || LIMIT="$1" # Set the total traffic daily limit in MB
[ -z "${2}" ] && IFACE="eth0" || IFACE="$2" # Set the name of the target interface
LOG="/tmp/traffic-watch-$IFACE.log"         # Set the log file name
LANG=C                                      # Set envvar $LANG to `C` due to grep, awk, etc.
IPPT='[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'       # Set IP address match pattern #IPPT='[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

NIC="$(/sbin/ethtool -i "$IFACE" | awk 'FS=": " {print $2; exit}')" # Get the $IFACE (NIC) driver

# Function: Get the current traffic
get_traffic(){
    RX="$(/sbin/ifconfig "$IFACE" | grep -Po "RX bytes:[0-9]+" | sed 's/RX bytes://')" # Get the incoming traffic
    TX="$(/sbin/ifconfig "$IFACE" | grep -Po "TX bytes:[0-9]+" | sed 's/TX bytes://')" # Get the outgoing traffic
    XB=$(( RX + TX ))                                                            # Calculate the total traffic
    XM=$(( XB / ( 1000 * 1000 ) ))                                               # Convert the total traffic in MB
}

# Functions: Disable the interface
interface_down(){ /sbin/ifconfig "$IFACE" down 2>/dev/null && exit; }

# Function: Reset the traffic and enable the interface
reset_traffic_interface_up(){ /sbin/modprobe -r "$NIC" 2>/dev/null && /sbin/modprobe "$NIC" 2>/dev/null && /sbin/ifconfig "$IFACE" up 2>/dev/null; }

# Function: Get the IP address
get_ip(){ /sbin/ifconfig "$IFACE" 2>/dev/null | grep -Po "${IPPT}" | head -1; }

# --- The main program ---

reset_traffic_interface_up

# Wait until the IP address is obtained
until [[ "$(get_ip)" =~ ${IPPT} ]]; do sleep 1; done

# While the interface has IP address == while it is up; check if it is up on every 5 seconds (the `time` of the cycle is about 75 ms)
while [[ "$(get_ip)" =~ ${IPPT} ]]; do

    get_traffic

    # Start logging
    printf '\n%s\n\nI-face:\t%s\nDriver:\t%s\nIP:\t%s\n' "$(date)" "$IFACE" "$NIC" "$(get_ip)" > "$LOG"
    printf '\nRX:\t%s\nTX:\t%s\nXB:\t%s\nXM:\t%s\n' "$RX" "$TX" "$XB" "$XM" >> "$LOG"

    if (( XM >= LIMIT )); then
        printf '\nThe daily limit of %s MB was reached.' "$LIMIT" >> "$LOG"
        printf '  The interface %s was disabled!\n\n' "$IFACE" >> "$LOG"
        interface_down
    else
            printf '\n%s MB remains on %s.\n\n' "$(( LIMIT - XM ))" "$IFACE" >> "$LOG"
    fi

    # Debug:    cat "$LOG"

    sleep 5 ## *Adjust this value* ##

done; interface_down

笔记:

  • 更新升级系统时请禁用该脚本!缺少互联网可能是导致包裹损坏的原因。

  • 在运行新脚本之前尝试终止前一个脚本实例(以防其限制未达到)是一个好主意:

    sudo pkill traffic-watch
    sudo -b traffic-watch "150" 2>/dev/null
    
    29 6 * * * /usr/bin/pkill traffic-watch 2>/dev/null 
    30 6 * * * /usr/local/bin/traffic-watch 2>/dev/null 
    
  • 可能2>/dev/null不是必须的,因为我认为所有错误都由/dev/null脚本本身重定向。

  • 要远程检查剩余流量,您可以使用以下命令:

    ssh [email protected] tail -n3 /tmp/traffic-watch-eth0.log
    

    感谢@Dessert 提出这个想法!(请eth0用实际使用的接口替换。)

  • 要恢复网络接口正常运行:首先ifconfig -a找到其名称。然后sudo ifconfig INTERFACE up

  • 可以重新创建此脚本来iptables代替ifconfig - up/down。这将是一个强大的解决方案。

  • 该脚本可在 GitHub 存储库中获取:https://github.com/pa4080/traffic-watch

  • 这里提供了另一个基于当前的脚本,该脚本只会获取一段时间内的流量:如何以简单的格式通过命令行获取当前网络流量

参考:

相关内容