首页 > 代码库 > ubunto python + vnstat 限制每天流量使用 使用iptables
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.intval = 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.intval = 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.intval = 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 &
ubunto python + vnstat 限制每天流量使用 使用iptables