我正在写一个简单的脚本iptables使用 MAC 地址限制访问。首先,我检查地址是否已传递给脚本:
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)
m
from之前的连字符/破折号/减号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
我可能在复制/粘贴到这里的过程中错过了一些东西,但我希望要点在那里。
感谢您的帮助!
//安德斯