0

I'm trying to write an iptables rule that applies to multiple interfaces based on a variable. Which of the rules is more efficient / faster ? Is there a better way to write this rule with a minimum of code ?

#Variable
Ext_INTF="eth0 usb0 tun0 tun1"

1)

for i in $Ext_INTF;
do
iptables -A FORWARD -i $i -j DROP
done

2)

iptables -A FORWARD -i $Ext_INTF -j DROP
uihdff
  • 455
  • 2
  • 7
  • 17

1 Answers1

1

Method 2 doesn't work — it produces an invalid iptables invocation. Whatever you thought it might do, it only adds one iptables rule, and you can't match an arbitrary set of interfaces in a single rule. Method 1 is the normal way and pretty much the only way.

Not that efficiency of setting iptables rules is a concern. You'd have to work very hard to do something noticeably non-optimal. The concerns here are to get the rules right, possibly the efficiency of the rules themselves, and keep the script readable so that it's easy to maintain.

Writing $Ext_INTF — a variable substitution outside double quotes — splits the value of the variable into whitespace-separated parts, and then expands each part as a wildcard pattern matching file names. Here the variable doesn't contain any wildcard character (\[*?). Thus for i in $Ext_INTF; … loops over the words in the value of the variable. In general you should only use variable substitutions inside double quotes, because $Ext_INTF means “the value of Ext_INTF” only inside double quotes, but here you want the splitting to happen, and the parts don't contain any shell wildcard characters.

Ext_INTF="eth0 usb0 tun0 tun1"
for i in $Ext_INTF; do
  iptables -A FORWARD -i "$i" -j DROP
done

In bash and ksh, but not in plain sh, you can use an array instead of a string variable. (And in zsh you must use an array or explicitly request splitting with $=Ext_INTF.) You have to type a few more characters, but this makes the intent clearer, and allows the elements to contain whitespace and wildcards if need be.

Ext_INTF=(eth0 usb0 tun0 tun1)
for i in "${Ext_INTF[@]}"; do
  iptables -A FORWARD -i "$i" -j DROP
done