Posts Tagged ‘bash’

Can't fork?

Saturday, May 29th, 2010

Can't fork but need to see what's going on? Hint: a box that can't fork can often `exec'.

Here are a pair of slick bash functions that can be lifesavers in dire situations:

`ls':

$ myls() { while [ $# -ne 0 ] ; do echo "$1" ; shift ; done ; }
$ myls /etc/s*
/etc/services
/etc/shells
/etc/syslog.conf

`cat':

$ mycat() { while IFS="" read l ; do echo "$l" ; done < $1 ; }
$ mycat /etc/shells

Auto-iptables off IPs with high connection counts

Saturday, August 29th, 2009

via Paul (lovepig.org):

netstat -npa --inet | grep :80 | sed 's/:/ /g' | awk '{print $6}' | sort | uniq -c | sort -n | while read line; do one=`echo $line | awk '{print $1}'`; two=`echo $line | awk '{print $2}'`; if [ $one -gt 100 ];
then iptables -I INPUT -s $two -j DROP; fi; done; iptables-save | grep -P '^-A INPUT' | sort | uniq -c | sort -n | while read line; do oneIp=`echo $line | awk '{print $1}'`; twoIp=`echo $line | awk '{print $5}'`; if [ $oneIp -gt 1 ]; then iptables -D INPUT -s $twoIp -j DROP; fi; done

This one-liner is quite effective when tossed into a file and run as a cronjob once per minute. Any IP with more than 100 concurrent connections — which, quite honestly, is far more than any one IP should ever have on a standard webserver — will be blocked via iptables. This script as a cronjob is extremely effective dealing with small-to-midsize DDoSes (too much traffic for Apache/whatever service to handle, but not saturating the pipe).

Combining text files as columns

Friday, June 19th, 2009

To combine two (or more) text files as individual columns in the same file, such as:

file1:

foo
foo1
foo2
foo3

file2:

foobar
foobar1
foobar2
foobar3

into:

foo foobar
foo1 foobar1
foo2 foobar2
foo3 foobar3

rather than using an ugly combination of sed and awk, you can use the `paste' command:

paste file1 file2

Extend bash functionality

Saturday, April 11th, 2009
# make bash autocomplete with up arrow
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'

# make tab cycle through commands instead of listing
bind '"\t":menu-complete'

Intercepting "command not found" in bash

Friday, March 6th, 2009

On Debian, bash is patched with an interesting new function: command_not_found_handle. This intercepts exit code 127 ("command not found") and allows you to do neat things. Debian uses it to pass it through the apt database, letting you know if a command you tried to invoke is not available, but can be found in the apt repos, and how to install it. Pretty spiffy.

This, of course, can be modified. Where I work, we use numbers to identify servers. I have a script that grabs login credentials from our internal systems and auto-logs me into servers based on their number. For example, I'd run `connect 12345′ to connect to server 12345.

By adding the following to my .bashrc:

function command_not_found_handle {
    /home/kale/bin/command-not-found $1
}

And creating the following script, with regex in place to only care about numbers, placed in /home/kale/bin/command-not-found:

#!/bin/bash

MYBOOL=`echo $1 | awk '$1 ~ /^[0-9]+-*[0-9]*$/ {print $0}' | wc -l | awk '{print $1}'`

if [ "$MYBOOL" == "1″ ]; then
        /home/kale/bin/connect $1
else
        exit 127
fi

(where `connect' is the path to my connect script, previously written)

This now allows me to do this awesome deal:

kale@bastion:~$ 12345
Connecting to server 12345
root@12345:~#
 

If you didn't catch it, I don't need to specify a command — just the argument. As there's no application in my $PATH named `12345′, it falls through to the command_not_found_handle function, which then launches my connect script.

Who needs commands? I just saved hundreds of wasted seconds per night on typing "connect"!