我正在尝试将 IP 地址列表添加到远程服务器上的 iptables 链中。如果我通过 ssh 进入服务器并运行命令,它会按预期工作(一旦我通过 ssh 进入服务器以测试此代码,我就会手动填充数组,否则数组将填充在本地服务器上):
for IP in ${aryTEST[@]}; do sudo iptables -A test -s $IP -j DROP ; done
但是当我尝试将其作为 ssh 命令运行时,它会失败并显示错误
错误参数‘DROP’
我运行的命令是:
ssh -p <port#> <user>@<host> "for IP in ${aryTEST[@]}; do sudo iptables -A test -s $IP -j DROP ; done"
当我尝试在命令周围使用单引号时,它不会返回错误并且似乎可以工作,但是当我检查链时它是空的。
ssh -p <port#> <user>@<host> 'for IP in ${aryTEST[@]}; do sudo iptables -A test -s $IP -j DROP ; done'
已将用户添加到 sudoers,以便能够在没有密码的情况下运行 iptables 以进行测试。目前,我必须循环遍历数组并在单独的 ssh 连接上运行每个 ip 地址。有什么想法可以做到这一点吗?
答案1
$
使用反斜杠 ( ) 转义要保留的美元符号 ( ) \
。
如果你使用
ssh -p <port#> <user>@<host> "for IP in ${aryTEST[@]}; do sudo iptables -A test -s $IP -j DROP ; done"
这是它在远程服务器上的样子(在 上<host>
)——该$IP
参数已经被评估(为无),因此bad argument
iptables 提出投诉:
for IP in 192.0.2.1 192.0.2.3 192.0.2.7; do sudo iptables -A test -s -j DROP ; done
但你希望它看起来像这样:
for IP in 192.0.2.1 192.0.2.3 192.0.2.7; do sudo iptables -A test -s $IP -j DROP ; done
因此,您需要在您的终端上评估数组,而另一个变量仅在远程端进行评估:
ssh -p <port#> <user>@<host> "for IP in ${aryTEST[@]}; do sudo iptables -A test -s \$IP -j DROP ; done"
答案2
testset.ipset
首先,创建一个列出您的 IP 地址的IPSet 规则文件:
create testset hash:ip family inet hashsize 1024 maxelem 65536
add testset <IP1>
add testset <IP2>
...
然后,将文件传输到远程主机并运行以下命令:
ipset restore -! < testset.ipset
iptables -A test -p tcp -m set --match-set testset src -j DROP
这将根据您的定义创建 IPSet,然后添加防火墙规则来阻止来自该组 IP 地址的数据包。