2

1. ファイル

ファイルには、次の/etc/ssh/ipblockような行が含まれています。

2012-01-01 12:00 192.0.2.201
2012-01-01 14:15 198.51.100.123
2012-02-15 09:45 192.0.2.15
2012-03-12 21:45 192.0.2.14
2012-04-25 00:15 203.0.113.243

2.コマンド

コマンドの出力はiptables -nL somechain次のようになります。

Chain somechain (2 参考文献)
ターゲット プロト オプト ソース デスティネーション
すべてドロップ -- 172.18.1.4 どこでも
すべてドロップ -- 198.51.100.123 どこでも
すべてドロップ -- 172.20.4.16 どこでも
すべてドロップ -- 192.0.2.125 どこでも
すべてドロップ -- 172.21.1.2 どこでも

3. 当面の課題

  1. 最初に、iptables チェーン (フィールド 4) には存在するがファイルには存在しない IP アドレスのリスト A を取得したいと思います。
  2. 次に、ファイルには存在するが iptables チェーンには存在しない IP アドレスのリスト B を取得したいと思います。
  3. リスト A の IP アドレスは、同じスタイル (日付、時刻、IP) でファイルに追加する必要があります。
  4. 次に、リスト B の IP アドレスを iptables チェーンに追加する必要があります。
    iptables -A somechain -d IP -j DROP

4. 背景

私は awk-fu を拡張したいと思っていたので、引数なしで実行できる awk スクリプトでこれを機能させようとしました。しかし、私は失敗しました。

コマンドを使用してコマンドから出力を取得できることを知っているgetlineので、その方法で時刻と日付を取得できました。また、を使用してファイルを読み取ることができることも知っていますgetline foo < file。しかし、これをすべて組み合わせて awk スクリプトを実行しようとして失敗したことはたくさんあります。

これを他のプログラミング言語やシェルスクリプトで動作させることができることに気づきました。しかし、これは引数なしで実行できる awk スクリプトで実行できますか?

4

2 に答える 2

3

これはあなたが探していたものとほぼ同じだと思います。仕事はすべて1つのファイルで行われ、コードはほとんど一目瞭然だと思います...
簡単に適応可能で、拡張可能です...

利用方法:
./foo.awk CHAIN ip.file

foo.awk:

#!/usr/bin/awk -f
BEGIN {
    CHAIN= ARGV[1]
    IPBLOCKFILE = ARGV[2]

    while((getline < IPBLOCKFILE) > 0) {
        IPBLOCK[$3] = 1
    }

    command = "iptables -nL " CHAIN
    command |getline
    command |getline
    while((command |getline) > 0) {
        IPTABLES[$4] = 1
    }
    close(command)

    print "not in IPBLOCK (will be appended):"
    command = "date +'%Y-%m-%d %H:%M'"
    command |getline DATE
    close(command)
    for(ip in IPTABLES) {
        if(!IPBLOCK[ip]) {
            print ip
            print DATE,ip >> IPBLOCKFILE
        }
    }

    print "not in IPTABLES (will be appended):"
    # command = "echo iptables -A " CHAIN " -s " //use for testing 
    command = "iptables -A " CHAIN " -s "
    for(ip in IPBLOCK) {
        if(!IPTABLES[ip]) {
            print ip
            system(command ip " -j DROP")
        }
    }
    exit
}
于 2012-08-04T17:08:44.397 に答える
1

1&3を行う:

comm -13 <(awk '{print $3}' /etc/ssh/ipblock | sort) <(iptables -nL somechain | awk '/\./{print $4}' | sort) | xargs -n 1 echo `date '+%y-%m-%d %H:%M'` >> /etc/ipblock

2&4 を行う:

comm -13 <(awk '{print $3}' /etc/ssh/ipblock | sort) <(iptables -nL somechain | awk '/\./{print $4}' | sort) | xargs -n 1 iptables -A somechain -d IP -j DROP

このコマンドは、次のビルディング ブロックで構成されています。

  1. Bash プロセス置換機能: パイプ機能と多少似ていますが、プログラムが引数/オプションで 2 つ以上の入力ファイルを必要とする場合によく使用されます。Bash はfifo、基本的に特定のコマンドの出力を「含む」ファイルを作成します。この場合、出力は ip アドレスになります。
  2. 次に、スクリプトの出力がプログラムにawk渡されます。comm両方awkのスクリプトは非常に単純です。IP アドレスを出力するだけです。最初のケースではすべての IP が 3 番目の列に含まれており (したがって$3)、2 番目のケースではすべての IP が 4 番目の列に含まれていますが、列ヘッダー (「宛先」文字列) を取り除く必要があるため、単純な正規表現が使用されます。/\./: ドットを含まないすべての文字列を除外します。
  3. commは両方の入力をソートする必要があるため、 の出力はawk次を使用してソートされますsort
  4. commこれで、プログラムは IP アドレスの両方のリストを受け取ります。オプションが指定されていない場合、FILE1 に固有の行、FILE2 に固有の行、両方のファイルの行の 3 つの列が出力されます。それに渡す-23ことで、FILE1 に固有の行のみを取得します。同様に、渡す-13と、FILE2 に固有の行が出力されます。
  5. xargsは基本的にbashの「foreach」ループであり、各入力行ごとに指定されたコマンドを実行します(おかげで-n 1)。2 つ目は非常に明白です (これが目的のiptables呼び出しです)。2 番目のものも複雑ではありませんdate。現在の時刻を適切な形式で出力するだけです。
于 2012-08-04T16:16:38.533 に答える