每日下载限制

我正在寻找一种方法来为我的Ubuntu服务器创建每日互联网限制。 所有出站交通都离开了Eth2,这是一个usb加密狗,这是预付费的,孩子们很快吃掉它。 我需要将预付款通常12Gb分成每日分配,并在达到此金额后的第二天停止流量。 也许有一个网页抛出说超过每日限制。

最好来自CLI。 这是一个只有SSH访问的无头野兽。

VNSTAT似乎做了我需要的东西,我只是没有脚本技能让它驱动ifdown命令。

谢谢。

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

当流量(收入+结果)等于或大于限制时,脚本将禁用目标接口并退出。 禁用接口的实际值与限制值之间的最大差异将等于5s x 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 

笔记:

  • 更新和升级系统时禁用脚本! 缺乏互联网可能导致包装破损。

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

     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 user@host.or.ip tail -n3 /tmp/traffic-watch-eth0.log 

    感谢@Dessert这个想法! (将eth0替换为正在使用的实际接口。)

  • 要恢复网络接口UP:首先是ifconfig -a以查找其名称。 然后sudo ifconfig INTERFACE up

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

  • 该脚本可在以下url获得GitHub存储库: https : //github.com/pa4080/traffic-watch

  • 此处提供了另一个基于当前的脚本,它只能获得一段时间的流量: 如何通过命令行以简单格式获取当前网络流量 。

参考文献:

  • 如何重置ifconfig计数器?
  • 网络接口启动时执行脚本
  • 更多关于计算的内容
  • 如何在没有ifconfig情况下获取TX / RX字节