2

我正在寻找将 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
  }
]

我需要一个bashpython脚本来读取 json 文件并创建ACCEPTiptables 规则。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

知道最好的编码方式吗?

4

5 回答 5

2

基于提供的语法的纯

有一个更干净的纯 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以执行操作,而不仅仅是打印它)

使用工具在下处理jq

如您所知,必须在每个字段中找到名为protocol、和的值ip,您可以通过使用以下内容来确保排序和提取值:cidrportjq

i=0
while :;do
    for var in proto ip mlen port ;do
        read -r $var
        [ "${!var}" = "null" ] && break 2
    done < <(
      jq -r ".[$i].protocol,.[$i].ip,.[$i].cidr,.[$i].port" <whitelist.json
    )
    echo iptables -A INPUT -p $proto -s $ip/$mlen -dport $port -j ACCEPT
    ((i++))
done
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以执行操作,而不仅仅是打印它)

于 2012-12-25T10:15:36.247 回答
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()
于 2012-12-25T09:26:25.713 回答
1

请注意,iptables -A将规则添加到表的末尾。匹配规则时,iptables 从上到下工作,第一个匹配获胜,所以如果您之前阻止了一个地址,那么将其列入白名单-A将不起作用(例如,许多默认规则集最后都有一个 blaket reject all)在这种情况下,用于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
于 2012-12-25T09:35:55.540 回答
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
于 2012-12-25T13:15:53.510 回答
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 - 目标文件

于 2012-12-25T12:26:09.477 回答