変数値のハイフン

変数値のハイフン

簡単なスクリプトを書いています。iptablesMACアドレスを使用してアクセスを制限します。まず、アドレスがスクリプトに渡されたことを確認します。

ALLOWED_MAC=$5
MAC_STRING=""
if [ -n "$ALLOWED_MAC" ] ; then
    MAC_STRING="-m mac --mac-source ${ALLOWED_MAC}"
fi

その後、MAC_STRING変数iptables:

iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPT

(もちろん)全体に対してif / elseを実行できますが、このソリューションはよりきれいに見えます。ユーザがMACアドレスを指定すると、そのアドレスは次に転送されます。iptables、そうでない場合は空の文字列を渡します。

ただし、このスクリプトを実行するとエラーが発生します。iptables:

iptables v1.4.9.1: Invalid match name " mac --mac-source 00:11:22:33:44:55" (28 chars max)

mfromの前のハイフン/ダッシュ/マイナス記号がMAC_STRING消えます。しかし、予想されるコマンドをエコーすると、すべてが正しく表示されます。

iptables -A INPUT -p tcp --sport 80  -m mac --mac-source 00:11:22:33:44:55 -m state --state ESTABLISHED -j ACCEPT

また、同じ結果で別のコマンドを試しました。ハイフンで始まる変数値がある場合、プログラムに引数として渡されるとその値が飲み込まれます。

答え1

さて、@Gillesのおかげでついに見つけました、そして彼は私に正しい方向を教えました。

iptables/mac スニペットは関数の内部にあります。私のスクリプトでは、与えられた一連のファイルを繰り返し解析し、(各ファイルごとに)iptables関数を呼び出します。

IFSわかりましたので、スクリプトの上部を変更し(ファイルの解析を簡素化するため)、スクリプトの残りの部分も変更するようにしました。ただし、以前の値を最初に保存してから、各IFS呼び出しの前にこの(以前の値)にリセットすると、すべてが期待どおりに機能します!

だからこれいいえ働く:

#!/bin/bash

function allow()
{
    [variable defs] 

    if [ -n "$ALLOWED_MAC" ] ; then
        MAC_STRING="-m mac --mac-source $ALLOWED_MAC"
    fi

    iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPT
}

#Set the Internal Field Separator to the token used in the files.
IFS=";"

[variable defs]

#Iterate over all the port files.
for file in $FILES
do

#Read the first (and only) line from the current file and split the tokens into an array.
LINE="$(cat $file)"
set -- "$LINE" 
declare -a Tokens=($*) 

[parse tokens]

#Call 'allow' for each port definition.
allow $PROTOCOL $PORT $DIRECTION $ALLOWED_MAC

done

しかし、これはうまくいきます:

#!/bin/bash

function allow()
{
    [variable defs]

    if [ -n "$ALLOWED_MAC" ] ; then
        MAC_STRING="-m mac --mac-source $ALLOWED_MAC"
    fi

    iptables -A INPUT -p $PROTOCOL --dport $PORT $MAC_STRING -m state --state NEW,ESTABLISHED -j ACCEPT
}

#Save the "original" IFS
OLD_IFS=$IFS

[variable defs]

#Iterate over all the port files.
for file in $FILES
do

#Set the Internal Field Separator to the token used in the files.
IFS=";"

#Read the first (and only) line from the current file and split the tokens into an array.
LINE="$(cat $file)"
set -- "$LINE" 
declare -a Tokens=($*) 

[parse tokens]

#Reset IFS before invoking the function.
IFS=$OLD_IFS

#Call 'allow' for each port definition.
allow $PROTOCOL $PORT $DIRECTION $ALLOWED_MAC

done

ここでコピー/貼り付けの過程で何かを逃したかもしれませんが、ポイントはそこにあったらいいです。

ご協力ありがとうございます!

//アンダース

関連情報