zoukankan      html  css  js  c++  java
  • ubunto python + vnstat 限制每天流量使用 使用iptables

    上次想使用 iptables 转发80 端口,试了一段时间,没有成功。哪位知道是什么原因,还麻烦告诉我。

    这次使用 iptables 禁用 80 443 出站,经过试验可以成功。

    通过 iptables -A OUTPUT -p tcp --dport 80  -j REJECT 和 iptables -A OUTPUT -p tcp --dport 443  -j REJECT 来禁止出站

    通过 iptables -F 来恢复

    bash shell 不太熟悉,使用 python 2.7 来实现 (python3 未测试也许可以)

    通过 os.system("iptables -A OUTPUT -p tcp --dport 80  -j REJECT") 来添加 iptables rule

    读取 vnstat 的显示结果通过 commands.getstatusoutput("vnstat -i eth0 -d")  或 subprocess.check_output(["vnstat", "-i", "eth0", "-d"])

    但经过测试发现 commands.getstatusoutput("vnstat -i eth0 -d") 结果,只可以 print 输入,不可以在使用 正则 来拆分出想要的结果。

    所以本文使用 subprocess.check_output(["vnstat", "-i", "eth0", "-d"])

    vnstat -i eth0 -d 结果执行如下

    eth0  /  daily
    
                 day         rx      |     tx      |    total    |   avg. rate
             ------------------------+-------------+-------------+---------------
             01/01/2018    10.00 MiB |   10.00 MiB |   20.00 MiB |    6.58 kbit/s
             01/02/2018    10.00 MiB |   20.00 MiB |   30.00 MiB |   10.36 kbit/s
             ------------------------+-------------+-------------+---------------
             estimated        --     |      --     |      --     |

    正则是 [d|/]{10})s+([w.s]+)[^d]+([w.s]+)[^d]+([w.s]+)

    匹配出 结果[('01/01/2018', '10.00 MiB ', '10.00 MiB ', '20.00 MiB '), ('01/02/2018', '10.00 MiB ', '20.00 MiB ', '30.00 MiB ')]

    本文使用 python 实现,不使用 crontab ,使用简单 通过,在 python 中一个 while 来定时读取 vnstat 的结果,当流量超出后,能调整 定时sleep 时间,以节省cpu 。

     1 #!/usr/bin/python
     2 #coding:utf-8
     3 '''
     4 author:ningci dev
     5 date:2017-04-30 05:54
     6 此python 脚本检测网卡流量使用情况,当达到设定值时,就会使用 iptables 关闭 80 443 
     7 '''
     8 import time
     9 import os
    10 import re
    11 import string
    12 import subprocess
    13 
    14 #每天限制流量使用450M
    15 DAY_LIMIT_OF_MB = 450
    16 #流量未超时每5分钟检查一次
    17 INTVAL_NORMAL   = 300
    18 #流量超出后每1小时检查一次
    19 INTVAL_SLEEP    = 3600
    20 
    21 class NetLimit:
    22 
    23     def __net_up(self):
    24         os.system("iptables -F")
    25         self.inteval = INTVAL_NORMAL
    26 
    27     def __net_down(self):
    28         os.system("iptables -A OUTPUT -p tcp --dport 80  -j REJECT")
    29         os.system("iptables -A OUTPUT -p tcp --dport 443 -j REJECT")
    30         self.inteval = INTVAL_SLEEP
    31 
    32     def __check_flow(self):
    33         vnstat_days = subprocess.check_output(["vnstat", "-i", "eth0", "-d"])
    34         #使用正则匹配每行匹配当前日期
    35         vnstat_rows = re.findall(r"([d|/]{10})s+([w.s]+)[^d]+([w.s]+)[^d]+([w.s]+)", vnstat_days)
    36         #输出格式 [('01/01/2018', '10.00 MiB ', '10.00 MiB ', '20.00 MiB '), ('01/02/2018', '10.00 MiB ', '20.00 MiB ', '30.00 MiB ')]
    37         for vnstat_row in vnstat_rows:
    38             #比较当前日期
    39             if time.strftime("%m/%d/%Y", time.localtime(time.time())) == vnstat_row[0]:
    40                 total_day = vnstat_row[3]
    41                 #查询 流量单位 MiB , KiB 忽略不计
    42                 if 0 < total_day.find("MiB"):
    43                     #果然是不如 PHP 方便,PHP 可以直接转为 int 
    44                     #使用 空格拆分取数字
    45                     total_day = string.atof(total_day.split(" ")[0])
    46                     if total_day > DAY_LIMIT_OF_MB:
    47                         return True
    48         return False
    49     
    50     def __init__(self):
    51         self.__net_up()
    52         #设定每5分钟执行一次
    53         self.inteval = INTVAL_NORMAL
    54 
    55     def run(self):
    56         while True:
    57             self.__net_down() if self.__check_flow() else self.__net_up()
    58             print("run ..")
    59             time.sleep(self.intval)
    60 
    61 NetLimit().run()

    使用方法,sudo python2.7 NetLimit.py &

  • 相关阅读:
    小白重装系统步骤总结
    【bzoj3680】平衡点 模拟退火
    【洛谷P4513】小白逛公园
    【POJ3666】Making the Grade 离散化+DP
    【codevs1690】开关灯 线段树
    【POJ2182】Lost Cows 树状数组+二分
    【POJ2676】sudoku 搜索
    【UVA】11400 照明系统设计 排序+dp
    关于二分答案输出误差问题的看法
    Java programming language does not use call by reference for objects!
  • 原文地址:https://www.cnblogs.com/ningci/p/6789062.html
Copyright © 2011-2022 走看看