Managing IPTables via GoLang

Hello, i have an bash script :
firewall=$( iptables --list OUTPUT --line-number )
if ! (echo “$firewall” | grep ‘DROP all – color.centos.com’ > /dev/null); then
iptables -A OUTPUT -s color.centos.com -j DROP
fi
if ! (echo “$firewall” | grep ‘DROP all – color.centos.com’ > /dev/null); then
iptables -A OUTPUT -s color.centos.com -j DROP
fi
I have thought but as per my experience i am unable to do this -_- is there any one who can help me ?

You have a 7 line <1KB shell script that’s going to turn into a 50+ line >2MB Go program. What is your reason for rewriting this in Go?

Sir actually we’re making an program. But if we make in bash then user can see codes in file or via process.
We want an compiled file and our code shouldn’t be leaked

2mb isn’t issue. If it is 7-10mb then also it is not an issue.
We want to submit project in college, nothing matters there -- only work should be done --
In bash script we can do it easily but the work should be done in a compiled language. We chosen golang, but i have searched a lot didn’t find any solution

Bro is it possible?

Sure, it’s possible. What have you tried so far?

I’m beginner bro -_-
I didn’t found solution for it like how to do .
if ! (echo “$firewall” | grep ‘DROP all – color.centos.com’ > /dev/null);
I’m not on pc now , but i have tried doing it with exec.Command but that is not working

if is available in go as well.

echo "$firewall" | grep '…' > /dev/null searches for a given pattern () in an input string stored in $firewall.

There is no need to shell out here…

sir can you explain a little bit that how can i use grep ?

I explained to you what the shell snippet does, hoping you would realise that you can do it within go, I even said, that for that snippet there is “no need to shell out”.

You can use strings.Contains.

Then you can use exec.Cmd/exec.Command to orchestrate all the iptables runs, or use your favored search engine to find a library that abstracts it away for you. A shallow research gave me a plentora of hits.

Ohk got it , thanks.
Now one more question -_-

output

ProccessID=$( iptables --list OUTPUT --line-number | grep -E '*.centos.com'  )
SAVEIFS=$IFS   # Save current IFS
IFS=$'\n'      # Change IFS to new line
ProccessID=($ProccessID) # split to array $names
IFS=$SAVEIFS   # Restore IFS
for (( i=0; i<${#ProccessID[@]}; i++ ))
do
    currentID=$( echo "$ProccessID[$i]" |  head -n1 | awk '{print $1;}' )
    iptables -D OUTPUT $currentID
done
## input
ProccessID=$( iptables --list INPUT --line-number | grep -E '*.centos.com'  )
SAVEIFS=$IFS   # Save current IFS
IFS=$'\n'      # Change IFS to new line
ProccessID=($ProccessID) # split to array $names
IFS=$SAVEIFS   # Restore IFS
for (( i=0; i<${#ProccessID[@]}; i++ ))
do
    currentID=$( echo "$ProccessID[$i]" |  head -n1 | awk '{print $1;}' )
    iptables -D INPUT $currentID
done

is it also possible in golang?

Yes, it is also possible in golang.

Everything you do in bash is possible in go as well. You do not need to provide examples and ask if it is possible, the answer will always be “yes”.

The question you really want to ask is “how can I achieve this in golang”.

And then we can give you an actual helpful answer.

Definitely you’ll do it differently.

In golang you’ll use a lot less pipes, instead you do equivalent string manipulation and filtering in golang itself.

Eg. You’d fetch the output of iptables in full, iterate over it by line applying the regex, and pass each matching line to a function which the does what you currently do in your loop. In general you wouldn’t use exec.* for anything but iptables, as you can do it in go directly without using bash.

How can i do it without using exec ? is there any library or documentation for this?

I’ve told you already about the strings package. There are a lot of string manipulation things in there.

What else do you need specifically right now?

Sir i understand what you’re saying, but as you have more experience and better knowledge can you tell me how can i do this? means like any example

In bash, it is easy. But in golang it is hard.
The thing i want to do is , find all IPTables OUTPUT rules which contains *.CentOS.com
and then get rule number of every rule and delete the rule one by one.

For example, if i run iptables --list OUTPUT --line-number | grep -E ‘*.centos.com’
Then i get this output :
3 DROP all – color1.centos.com anywhere
4 DROP all – color2.centos.com anywhere
5 DROP all – color3.centos.com anywhere
6 DROP all – color4.centos.com anywhere
7 DROP all – color5.centos.com anywhere
8 DROP all – color6.centos.com anywhere

here you can see, 3 4 5 6 7 8 are rule numbers. i want to delete these rules but suppose if we delete rule 3 then rule 4 becomes rule 3 and rule 5 becomes rule 4 and so on
in bash it is so easy to do, but in golang i’m getting confused -_-
i came from PHP , Bash so i don’t have more experience in golang so guys please help me to do it

  1. get the output of iptables --list OUTPUT --line-number into a string
  2. split that string by \n into a slice of lines.
  3. iterate those lines backwards
  4. check if the line contains the pattern
    • If pattern is contained, remove the rule
    • If pattern is not contained, just do nothing

With which of these do you have problems? You said its for college, and I won’t do your homework.

Sir , what do you mean by iterating those line backwards :neutral_face:

sir how do we get rule number

var1 := "iptables"
var2 := "--list"
var3 := "OUTPUT"
var4 := "--line-number"
out, _ := exec.Command(var1, var2, var3, var4).Output()
s := regexp.MustCompile("\n").Split(string(out), -1)
for i := len(s); i <= 0; i-- {
fmt.Println(s[i])
}
}

i have written these codes, but in fmt.Println(s[i]) i’m not getting any output

Iterate them, back to front. That way you can remove from the end, without affecting indexes you will iterate later on.

As far as I can see in all your examples, the “rule number” is everything up to the first space. So split the line at spaces and take the first element of the result.

What you do is not different from bash, but you do it using Gos functions.

Instead of modifying IFS you use strings.Split or strings.SplitN instead.

Also, as I have linked documentation a couple of times now, I expect you to at least shallowly read what got linked and accompany future questions with some code that showed what you tried and what you do not understand there.

What might be of some interest for this topic: