2

IP アドレスのホワイトリストへの登録を自動化する最良の方法を探していますiptables。IP アドレスとポートのリストは、次の/accept-rules.jsonような形式の 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
  }
]

json ファイルを読み取り、iptables ルールを作成するbashorスクリプトが必要です。上記に基づくルールの例は次のようになります。pythonACCEPTACCEPTjson

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(単に印刷するのではなく、アクションを実行するために削除します)

ツールを使用して、の下でjsonを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ません (たとえば、多くのデフォルト ルールセットには、最後にすべてを拒否するブロックがあります)。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 に答える