Friday, November 4, 2011

Sshguard needs a test run

After posting about Fail2ban yester day I remembered that there is one more cool tool. The tool is Sshguard and is similar to Fail2ban. However, Sshguard is implemented in C and not a scripting language like Fail2ban (python). Sshguard also increases the ban time exponentially ... and that is nice.

I have not tested Sshguard yet but one of my friends highly recommends it.

Thursday, November 3, 2011

Fail2ban is good stuff

Fail2ban is a handy little script for anyone who wants to protect them self from hackers brute force attacks. Fail2ban scans log files like /var/log/pwdfail or /var/log/apache/error_log and bans IP that makes too many password failures. It updates firewall rules to reject the IP address. It works with SSH, HTTP, FTP, Mail services etc.

Wednesday, November 2, 2011

Note to self - remember how run-parts work

A couple weeks ago I wrote a bash script and tested it and the script worked. I copied the bash script to the daily cron jobs (/etc/cron.daily) and after a couple of days I noted that it had never been run. After 2 hours of debuging I syill could not get it to run. However, then I rembered that the cron jobs are executed by run-parts. I opened the man page and what did I find:

If neither the --lsbsysinit option nor the --regex option is given then the
names must consist entirely of upper and lower case letters, digits,
underscores, and hyphens.

The filename of my bash script had a dot in it (scriptname.sh) and crontab does not use run-parts with the --lsbsysinit option nor the --regex option. This is the second time I have screwed up a cron script name like this.

The simple solution was to remove the suffix from the filename of the script.

Tuesday, November 1, 2011

Makefiles for building many binary flavors

If you want to share code for several binaries you would normally organize this code as a shared or static library. This is usually how I do it, but recently I came across a situation where this actually became a clumsy way of doing it.

The real life scenario is the following. We have a binary that make a lot of syntactical and type checks for a configuration file format. If the configuration file is ok the binary starts to generate system configuration files. We will label this binary as tool. Additional to the tool binary we want a binary that only do the checks and is not able to generate files and that binary is labeled tool-simple. The code base is a huge directory tree with many Makefiles, like this:

|-Makefile
|-pkg/
|-src/
| |-proj1/
| | |-Makefile
| | |-main.c
| |
| |-proj2/
| | |-Makefile 
. . .
. . .
. . .

In this case proj1 contains the source code for the binary called tool. However, proj1 needs to be built in two binary different flavors from the exact same source files but with different define arguments to gcc. This could have easily been done by running make twice (traverse the build tree twice) in the normal case. However, because the binaries will be packaged in the same tgz file we can only traverse the build tree once if we want to make a sane build environment. The solution is to create a structure for project q that look like this:

|-src/
| |-proj1/
| | |-Makefile
| | |-tool/
| | | |-Makefile
| | | |-cmd.c
| | | |-cmd.h
| | | |-common.inc
| | | |-main.c
| | |
| | |-tool-simple/
| | | |-Makefile

Lets consentrate on the files in the project1 dirextory tree.

proj1/Makefile
1
2
3
4
5
6
7
8
9
all:
    make -C tool all
    make -C tool-simple all

clean:
    make -C tool clean
    make -C tool-simple clean

#eof

There is nothing special about this Makefile and that is the nice thing about it. Lets keep things simple and clean where we can and all the special cases isolated.

proj1/tool/cmd.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include "cmd.h"
#include <stdio.h>

void tool_func() {
    printf("Do tool stuff\n");
}

void simple_func() {
    printf("Do simple stuff\n");
}

void common_end(){
#ifdef SIMPLE
    printf("Simple end\n");
#else
    printf("Tool end\n");
#endif
}
//eof
proj1/tool/cmd.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#ifndef CMD_H
#define CMD_H

void tool_func();

void simple_func();

void common_end();

#endif
//eof
proj1/tool/main.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include "cmd.h"
#include <stdio.h>

int main(int argc, char** argv) {

simple_func();

#ifndef SIMPLE
    printf("Tool working ...\n");
    tool_func();
#endif

common_end();

return 0;
}
//eof

The only thing interesting in these 3 C files (main.c, cmd.c and cmd.h) are the ifdefs and ifndefs that are used to include and exclude code depending on the build. From the real scenario the shared code for the binaries are rather 80% than the few percent that are used in these files.

proj1/tool/common.inc
1
2
3
4
5
6
CC=gcc

OBJ = main.o \
    cmd.o

#eof

The file common.inc mainly contains the list of all object files that should be produced. In this case we have also included the common definition of CC.

proj1/tool/Makefile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
include common.inc

TARGET=tool

all: $(TARGET)

$(TARGET): $(OBJ)
    $(CC) -o $@ $^

%.o: %.c
    $(CC) -Wall -c -o $@ $<

clean:
    rm -f $(TARGET) $(OBJ)

#eof

The Makefile in the tool directory is a very normal Makefile with the include of common.inc as the only deviation.

proj1/tool-simple/Makefile
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
include ../tool/common.inc

vpath %.h ../tool
vpath %.c ../tool

TARGET=tool-simple

all: $(TARGET)

$(TARGET): $(OBJ)
    $(CC) -o $@ $^

%.o: %.c
    $(CC) -Wall -c -o $@ $< -DSIMPLE

clean:
    rm -f $(TARGET) $(OBJ)
#eof

The interesting stuff is found in the Makefile contained in the tool-simple directory In this Makefile we also include the common.inc file from the tools directory. The tools-simple directory does not contain any C files that can be compiled to the object files declared in common.inc though. We will compile the .c and .h files from the tools directory in to the tools-simple directory with the help of the vpath directive. Note the lower case of the directive vpath because vpath and VPATH are two different directives. VPATH specifies a list of directories that make should search. Similar to the VPATH directive, but more selective, is the vpath directive , which allows you to specify a search path for a particular class of file names: those that match a particular pattern. Also note that we define SIMPLE in this Makefile with the argument -DSIMPLE when we build our object files for tool-simple By defining SIMPLE we will not compile some code as you can see from the C files above.

Go and have fun with some Makefiles!