# Help for bash script



## leboeuf (Mar 28, 2011)

Hi everybody,

I found a bash script against ddos attacks type SYN flood but I have one problem, It is make for Linux OS (with iptables). There is the script:

```
#!/bin/bash

while true;
do
for i in ` netstat -tanpu | grep "SYN_RECV" | awk {'print $5'} | cut -f 1 -d ":" | sort | uniq -c | sort -n | awk {'if ($1 > 5) print $2'}` ;
do
echo $i;
iptables -A INPUT -s $i/24 -j DROP && /etc/init.d/httpd restart;
sleep 1;
done;
netstat -tanpu | grep "0.0.0.0:80" | grep LISTEN || /etc/init.d/httpd restart;
sleep 5;
done
```

I try to adapt it for Packet filter but I'm not sure it will works, there is my script:

```
#!/bin/bash

while true;
do
for i in ` netstat -tanpu | grep "SYN_RECV" | awk {'print $5'} | cut -f 1 -d ":" | sort | uniq -c | sort -n | awk {'if ($1 > 5) print $2'}` ;
do
echo $i;
pfctl -t flooders -T add $i && /etc/init.d/httpd restart;
sleep 1;
done;
netstat -tanpu | grep "0.0.0.0:80" | grep LISTEN || /etc/init.d/httpd restart;
sleep 5;
done
```

Does it seems correct ? The line which is the problem is:

```
iptables -A INPUT -s $i/24 -j DROP && /etc/init.d/httpd restart;
```
I put this for packet filter:

```
pfctl -t flooders -T add $i && /etc/init.d/httpd restart;
```

It is not exactly the same thing, this part found the ips which attacks my server on SYN flood:

```
for i in ` netstat -tanpu | grep "SYN_RECV" | awk {'print $5'} | cut -f 1 -d ":" | sort | uniq -c | sort -n | awk {'if ($1 > 5) print $2'}` ;
```

I want ban those ips, so I want add them in the table flooders which I block in my Packet filter rules. Will it works ? And if not could you help me ?


----------



## silverglade00 (Mar 29, 2011)

I have no idea how to read pf or iptables, but the correct command to restart apache is [CMD=""]/usr/local/etc/rc.d/httpd restart[/CMD]


----------



## leboeuf (Mar 29, 2011)

Thank you, I do not make attention about this but you're right, with the little correction:

```
#!/bin/bash

while true;
do
for i in ` netstat -tanpu | grep "SYN_RECV" | awk {'print $5'} | cut -f 1 -d ":" | sort | uniq -c | sort -n | awk {'if ($1 > 5) print $2'}` ;
do
echo $i;
pfctl -t flooders -T add $i && /etc/init.d/httpd restart;
sleep 1;
done;
netstat -tanpu | grep "0.0.0.0:80" | grep LISTEN || /usr/local/etc/rc.d/httpd restart;
sleep 5;
done
```

But there is still a problem, those two parts doesn't works on freebsd system:

```
for i in ` netstat -tanpu | grep "SYN_RECV" | awk {'print $5'} | cut -f 1 -d ":" | sort | uniq -c | sort -n | awk {'if ($1 > 5) print $2'}` ;
```


```
netstat -tanpu | grep "0.0.0.0:80"
```
Does someone know how to translate those linux commands for freebsd ?


----------



## gordon@ (Mar 29, 2011)

There is no reason to restart your apache server.


```
#! /bin/sh

while sleep 5; do
  for i in `netstat -n -f inet | grep "ESTAB" | awk '{print $5}' | sed -E 's/\.[0-9]+$//' | sort | uniq -c | awk '($1 > 5){print $2}'`; do
    echo $i
    pfctl -t flooders -T add $i
    pfctl -k $i
  done
done
```

That said, I think this is overkill. In fact, you can do this exact same functionality entirely inside of pf(4).

Here's how I limit people connecting to my ssh server:

```
block quick from <bad_hosts>
pass in quick proto tcp from any to any port 22 keep state\
        (max-src-conn-rate 3/180, overload <bad_hosts> flush global)
```

Basically, you only get to connect to my server 3 time in 3 minutes, otherwise your IP gets blackholed.


----------



## DutchDaemon (Mar 29, 2011)

silverglade00 said:
			
		

> I have no idea how to read pf or iptables, but the correct command to restart apache is [CMD=""]/usr/local/etc/rc.d/httpd restart[/CMD]



It's
[cmd=]/usr/local/etc/rc.d/apache22 restart[/cmd]
actually. It varies with apache version, but this is the most common.


----------



## leboeuf (Mar 29, 2011)

Thank you for your answer.



			
				gordon@ said:
			
		

> Here's how I limit people connecting to my ssh server:
> 
> ```
> block quick from <bad_hosts>
> ...



I have almost the same rules 

What is the difference between the script I presented, here:

```
#!/bin/bash

while true;
do
for i in ` netstat -tanpu | grep "SYN_RECV" | awk {'print $5'} | cut -f 1 -d ":" | sort | uniq -c | sort -n | awk {'if ($1 > 5) print $2'}` ;
do
echo $i;
iptables -A INPUT -s $i/24 -j DROP && /etc/init.d/httpd restart;
sleep 1;
done;
netstat -tanpu | grep "0.0.0.0:80" | grep LISTEN || /etc/init.d/httpd restart;
sleep 5;
done
```

And you're script :

```
#! /bin/sh

while sleep 5; do
  for i in `netstat -n -f inet | grep "ESTAB" | awk '{print $5}' | sed -E 's/\.[0-9]+$//' | sort | uniq -c | awk '($1 > 5){print $2}'`; do
    echo $i
    pfctl -t flooders -T add $i
    pfctl -k $i
  done
done
```

I know the first one works on Linux OS but not on FreeBSD but I would know why /bin/sh and not /bin/bash (the langage bash doesn't work ?) and what make your script ? It protects against SYN flood ? How many are maximum SYN's packet allowed ?

And I think reboot apache22 is in case of the web server is stopped.


----------



## phoenix (Mar 29, 2011)

Or, on 8.1+ systems, it's even simpler:
`# service httpd restart`

See the service(8) man page for details.


----------



## leboeuf (Mar 29, 2011)

phoenix said:
			
		

> Or, on 8.1+ systems, it's even simpler:
> `# service httpd restart`
> 
> See the service(8) man page for details.


Thank you. I know how to restart apache. I would just have answers for my previous post because I don't understant very well what his script is doing.


----------



## DutchDaemon (Mar 29, 2011)

```
# service httpd restart
httpd does not exist in /etc/rc.d or the local startup
directories (/usr/local/etc/rc.d)
```


```
# service apache22 restart                                                                                                                  
Performing sanity check on apache22 configuration:
Syntax OK
Stopping apache22.
Waiting for PIDS: 84998.
Performing sanity check on apache22 configuration:
Syntax OK
Starting apache22.
```


----------



## leboeuf (Mar 29, 2011)

I spoke about those questions(I undestand know how to restart apache):


			
				leboeuf said:
			
		

> Thank you for your answer.
> 
> 
> 
> ...


----------



## silverglade00 (Mar 29, 2011)

DutchDaemon said:
			
		

> It's
> [cmd=]/usr/local/etc/rc.d/apache22 restart[/cmd]
> actually. It varies with apache version, but this is the most common.



This, kids, is why you do not respond to forum questions before your morning coffee.


----------



## gordon@ (Mar 29, 2011)

leboeuf said:
			
		

> What is the difference between the script I presented, here:
> _<snip>_
> And you're script :
> _<snip>_
> ...



Well, bash is not installed by default on a FreeBSD system. /bin/sh is and since you are not using any bash specific syntax in your script, it would be better practice to use /bin/sh.

I'm not sure what you mean by "what make your script". Assuming you mean what makes my script work, I just blindly ported the syntax from what you had to FreeBSD. I did test it a bit (not that I SYN flooded myself).



			
				leboeuf said:
			
		

> It protects against SYN flood ? How many are maximum SYN's packet allowed ?



I don't know if it protects against a SYN flood. I think you would be better implementing it in your firewall (see pf.conf(5)):


```
pass in quick proto tcp from any to any port 80 flags S/SA [b]synproxy state[/b]
```

Then you wouldn't need this script at all.


----------



## leboeuf (Mar 30, 2011)

Ok, my packet filter configuration protects against that I think (synproxy state). I heard about floodmon and Jamd. Do you think they works to protect better (I'm not sure Floodmon run on FreeBSD, I think yes).
And also HAPROXY against slowloris attacks. Do you think it is better to install those protections ?

And have you got any advices for configuring the TCP/IP stack ?


----------

