I have a bash script for initializing iptables.

#!/bin/sh

EXTIF="eth0"
INTIF="eth1"

INTIP="192.168.0.1/32"
EXTIP=$(/sbin/ip addr show dev "$EXTIF" | perl -lne 'if(/inet (\S+)/){print$1;last}');

UNIVERSE="0.0.0.0/0"
INTNET="192.168.0.1/24"

/sbin/iptables-restore -v < iptables.rules

I have iptables.rules file containing something like this:

-A OUTPUT -o $EXTIF -s $UNIVERSE -d $INTNET -j REJECT

How can I pass those variables from bash script to iptables.rules or evaluate them?

link|improve this question

53% accept rate
Cross-posted from here. – Dennis Williamson Mar 14 '11 at 4:18
feedback

3 Answers

up vote 2 down vote accepted

Something like this:

while read line; do eval "echo ${line}"; done < iptables.rules | /sbin/iptables-restore -v

or more nicely formatted:

while read line
  do eval "echo ${line}"
done < iptables.rules | /sbin/iptables-restore -v

This forces the variable expansion stuff. You definitely need to be sure you understand what's in those variables; I suspect that if somebody could set a variable to an arbitrary value they could use it to execute arbitrary code.

link|improve this answer
This works well for me – Michael Mar 14 '11 at 8:28
feedback

I would not want to trust this in general execution without a lot of content tests, at which point it becomes easier to feed it through a macro processor instead of trying to substitute shell variables into it. I strongly recommend going that way instead. That said, something like this should work:

f="$(mktemp)" || exit 1
{echo '/sbin/iptables-restore <<__EOF'; cat iptables.rules; echo '__EOF'} >"$f"
. "$f"
rm "$f"
link|improve this answer
In Bash (note that the question is tagged [bash], but the shebang is #!/bin/sh), you can source something on the fly without a temporary file: source <(echo '...'; echo "$(<iptables.rules)"; echo '...') – Dennis Williamson Mar 14 '11 at 4:26
feedback

If iptables.rules contains:

RULES="-A OUTPUT -o $EXTIF -s $UNIVERSE -d $INTNET -j REJECT"

And your script sources that file, then the variables will be evaluated.

#!/bin/sh

EXTIF="eth0"
INTIF="eth1"

INTIP="192.168.0.1/32"
EXTIP=$(/sbin/ip addr show dev "$EXTIF" | perl -lne 'if(/inet (\S+)/){print$1;last}');

UNIVERSE="0.0.0.0/0"
INTNET="192.168.0.1/24"
. iptables.rules

/sbin/iptables-restore -v < $RULES
link|improve this answer
no, unfortunately... – Michael Mar 14 '11 at 2:23
That wouldn't work anyway: $RULES isn't the name of a file. echo "$RULES" | /sbin/iptables-restore -v would work if iptables.rules were set up correctly. – geekosaur Mar 14 '11 at 3:22
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.