我正在寻找将白名单IP地址自动化为iptables
的最佳方法。 IP地址和端口列表来自JSON文件/accept-rules.json
,其格式如下:
[
{
"ip": "1.2.3.4",
"cidr": 32,
"protocol": "tcp",
"port": 3306
},
{
"ip": "2.4.5.6",
"cidr": 32,
"protocol": "tcp",
"port": 80
},
{
"ip": "5.6.7.8",
"cidr": 32,
"protocol": "tcp",
"port": 443
},
{
"ip": "6.8.3.1",
"cidr": 32,
"protocol": "tcp",
"port": 53
}
]
我需要一个bash
或python
脚本来读取json文件并创建ACCEPT
iptables规则。基于上面ACCEPT
的示例json
规则应如下所示:
iptables -A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 3306 -j ACCEPT
iptables -A INPUT -s 2.4.5.6/32 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -s 5.6.7.8/32 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -s 6.8.3.1/32 -p tcp -m tcp --dport 53 -j ACCEPT
对这个代码进行编码的最佳方法有什么想法吗?
答案 0 :(得分:1)
这是一个python代码:
这将生成一个包含所有iptable条目的bash脚本文件'accept.sh'。
# accept.py
fp = open("accept-rules.json", "r")
data = fp.readlines()
fp1 = open("accept.sh", "w")
for line in data:
if "{" in line:
datum = {}
elif "}" in line:
s = "iptables -A INPUT -s " + datum["ip"] + "/" + datum["cidr"] + " -p " + datum["protocol"] + " -m " + datum["protocol"] + " --dport " + datum["port"] + " -j ACCEPT\n"
fp1.write(s)
elif "[" in line or "]" in line:
continue
else:
datum[line.split(":")[0].strip().strip('"')] = line.split(":")[1].strip().strip(",").strip('"')
fp1.close()
fp.close()
答案 1 :(得分:1)
请注意iptables -A
将规则添加到表的末尾。匹配规则时,iptables从上到下工作,第一个匹配获胜,如果您之前已阻止某个地址,那么使用-A
将其列为白色将无法正常工作(许多默认规则集都有一个blaket拒绝全部为示例)在这种情况下,最好使用iptables -I
在开头插入规则。
#!/bin/bash
function getval {
set -- $1
RET=${2//[\",]/}
}
while read line
do
set -- $line
if [[ "$1" == '"ip":' ]]
then
getval "$line"
IPADDRESS=$RET
read line
getval "$line"
CIDR=$RET
read line
getval "$line"
PROTOCOL=$RET
read line
getval "$line"
PORT=$RET
/sbin/iptables -I INPUT -s "$IPADDRESS"/"$CIDR" -p "$PROTOCOL" -m "$PROTOCOL" --dport "$PORT" -j ACCEPT
fi
done <file.json
答案 2 :(得分:1)
有一个更干净的纯bash 版本。 (没有eval
)
declare -A iptArray
iptArray[action]='A'
getval() {
[[ "$@" =~ \"([^\*]*)\"\ *:\ *\"?([^\",]*)\"?[,\ ]*$ ]] && \
iptArray[${BASH_REMATCH[1]}]=${BASH_REMATCH[2]}
}
while read line;do
getval $line
[[ "$line" =~ } ]] && \
echo iptables -${iptArray[action]} INPUT -p ${iptArray[protocol]} \
-s ${iptArray[ip]}/${iptArray[cidr]} \
--dport ${iptArray[port]} -j ACCEPT
done < ipt_whitelist.json
iptables -A INPUT -p tcp -s 1.2.3.4/32 --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp -s 2.4.5.6/32 --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -s 5.6.7.8/32 --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -s 6.8.3.1/32 --dport 53 -j ACCEPT
(删除echo
以执行操作而不是仅打印它)
答案 3 :(得分:1)
更简洁的Python版本:
#!/usr/bin/env python
import json
import sys
for rule in json.load(sys.stdin):
print("iptables -I INPUT -s {ip}/{cidr} -p {protocol} "
"-m {protocol} --dport {port} -j ACCEPT".format(**rule))
注意:它使用-I
在开头插入规则。
$ json2iptables < accept-rules.json
iptables -I INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 3306 -j ACCEPT
iptables -I INPUT -s 2.4.5.6/32 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -s 5.6.7.8/32 -p tcp -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -s 6.8.3.1/32 -p tcp -m tcp --dport 53 -j ACCEPT
答案 4 :(得分:0)
Python实现:
import json
rules_file = open('accept-rules.json', 'r')
rules = json.load(rules_file)
rules_file.close()
iptables = open('iptavles.sh', 'w')
for rule in rules:
rule_str = 'iptables -A INPUT -s %s/%s -p tcp -m %s --dport %s -j ACCEPT\n' % (rule['ip'], rule['cidr'], rule['protocol'], rule['port'])
iptables.write(rule_str)
iptables.close()
accept-rules.json - 启动json文件, iptables.sh - 目标文件