Thursday, December 31, 2009

Using a 32-bits program in a 64-bits Linux environment

When Slackware released its first test version of Slackware64, I installed it on a separate partition to try it out. I was immediately impressed by the performance boost of some programs, especially some graphic programs I use.

Since I compile most programs that are not available on a standard Slackware installation from source, I didn't have too much trouble switching completely from 32-bits to 64-bits when the official release came out.
But for some programs the source code is not available. The original author / site may have disappeared, or it might simply be "closed" software.
I had this problem with some older programs I still used and they simply would not run on Slackware64. The error they normally return is:

<program_name>: No such file or directory

This error actually means that the binary file is looking for some (32-bits) library it cannot find, simply because they do not exist on pure 64-bits Linux installations.

One option was to go "multi-lib" - install the 32-bits libraries on my Slackware64 box. But I did not want to go that way, as I preferred to keep my installation as "pure" as possible.

So I started looking for another solution, and on the LinuxQuestions.org forum someone pointed me to statifier.

Statifier simply combines the binary executable with all the libraries it needs into one (big!) executable "semi-static" file. I won't go into the details how it does that (because I also do not understand all the details...), so if you want to know more, check out the site of the author.

The only problem is that you will need a 32-bits machine where your binary works fine, to "statify" it. I still had my 32-bits Slackware partition, so no problem for me here.

Statifier is open source software, so you can build it yourself, or get my package for Slackware on my site.

After installing or building Statifier on your 32-bits machine, you can use it to "statify" your 32-bits binary like this:

$ statifier <binary> <new_binary>

Remember that the result will be a lot bigger than the original, as it includes all the libraries that are normally loaded dynamically. As an example, I used it on "l3p", a small program to convert LDraw files to POV-Ray files, only available in a 32-bits version.
The original file was 140K, the statified version is 2.7M :)
But it solved my problem and I can use l3p on my 64-bits Slackware64 installation!

If you want to use l3p on Slackware64 as well but this is all too technical for you, you can get the statified version of l3p as a Slackware package from my site.

Labels: ,

"lgeo" Slackware package available

After some requests, I created a Slackware package with the lgeo parts library. It can be downloaded from my site.

If you prefer, you can download the library from the author's website and use the SlackBuild to create your own package.

Labels: , ,

Friday, December 25, 2009

Updated LDraw_data package available

I created an updated package with the LDRAW Library of Lego pieces that includes all parts up to September, 16th, 2009.

The "unix-complete" file from ldraw.org has not been updated for years, so this package was based on the Windows file "complete.zip" but can be used without any problems under Slackware.

As always, the package can be downloaded from my site.

Labels: ,

Thursday, December 24, 2009

Lego & POV-Ray on Linux

Some time ago I promised to give some basic instructions on how to create nice images of Lego constructions with POV-Ray on Linux. Now that Christmas is arriving, I finally found some time to convert my own instructions into something that can almost be called a "tutorial" :)

What will you need:
  1. LeoCAD - to "build" your constrution

  2. (optional) a viewer program, like LDView or ldglite

  3. l3p - to convert the .ldr (LDRaw) file to .pov (POV-Ray)

  4. (optional) The "lgeo" parts collection

  5. POV-Ray - the "Ray-Tracer program"

If you use Slackware, you can find packages for all of these on my site and SlackBuilds for all except 3 on www.slackbuilds.org. For many other Linux distributions packages are available in their repositories.

First step - Build something!

If you do not have any LDraw file yet with a Lego creation, then now is the time to make one.
As an example for this tutorial, I built a little penguin, based on the instructions here, with LeoCAD:


Save your creation with LeoCAD as a ".ldr" file ("File" - "Save as" from the menu). The resulting file in my case was:
0 Model exported from LeoCAD
0 Original name: Penguin.lcd

1 14 -50.00 -0.00 -60.00 -0.00 0.00 1.00 -0.00 1.00 -0.00 -1.00 -0.00 -0.00 3002.DAT
1 15 -50.00 -24.00 -60.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3004.DAT
1 15 -50.00 -48.00 -60.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3004.DAT
1 0 -50.00 -24.00 -40.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3004.DAT
1 0 -70.00 -48.00 -40.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3004.DAT
1 0 -30.00 -48.00 -40.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3004.DAT
1 0 -50.00 -72.00 -40.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3004.DAT
1 14 -50.00 -72.00 -70.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3003.DAT
1 0 -50.00 -96.00 -50.00 -1.00 0.00 -0.00 0.00 1.00 -0.00 0.00 -0.00 -1.00 3003.DAT
0


Second step - View your model with ldglite or LDView

This step can be skipped, but it is a nice test to check if the programs can find all the LDRAW parts on your computer. LeoCAD uses its own parts library, so being able to view it there does not necessarily mean that the LDRAW library is accessible.

This is how the penguin looks like in ldglite, a simple but very fast program to visualize your creations:


A second option is to use LDView, a very nice and very complete program to visualize your creations. It creates a more realistic view of the model, with some shading effects:



Third step - Ray-Tracing

So the images created by LDView are nice. But we want something even better! Enter POV-Ray, a very professional Ray-Tracing program that is completely free.
It "traces" light-rays, by tracing paths of "light particles" from one or more light sources, bouncing off surfaces and reflecting into the lens of a camera.

So we define the position and colors of the light sources, the position and angle of the camera, the types of surfaces (smooth, reflective, rough, etc.), etc.

Sounds complicated? Well, there is a very nice utility called l3p that tries to do most if it automatically to help us get started. l3p reads an "ldr" file, guesses the best position and angle for the camera so that the whole creation will fit in the image, and sets up three light sources around the model. Then it creates a .pov file that can be read by POV-Ray.

l3p needs to know where the LDRAW library is stored on your computer. This can be set by the LDRAWDIR environment variable like:
$ export LDRAWDIR=/usr/share/LDRAW

Put this in your start-up script like ~/.bash_profile (if you use bash for a shell).

Enough theory, let's create our first .pov file:
$ l3p -o Penguin.ldr

This reads the "Penguin.ldr" file we created and writes a "Penguin.pov" file in the current directory.
I used just one option - "-o" - which instructs l3p to overwrite Penguin.pov if it already exists, since we'll perform various tests before we get the final result.

Now let's run POV-Ray to transform the .pov file into an image:
$ povray +OPenguin.png +FN +P Penguin.pov

The options here mean:
  • +OPenguin.png - Output will be Penguin.png

  • +FN - Format will be a PNG file

  • +P - Pause after creating the image, showing the result on the screen

The result should look like this:


For a first test, it's just about "OK"... But we can do better than this!

Since in most tests we'll run l3p and povray as a sequence, we'll put both commands on one line like this:
$ l3p <options> && povray <options>

The "&&" means that the next command is only executed if the previous terminated without error.

So let's try:
$ l3p -b -o Penguin.ldr && povray +OPenguin.png +FN +W640 +H480 +P Penguin.pov

What did we add:
  • -b - add a standard blue background to replace the black void

  • +W640 - Create the image with a width of 640 pixels instead of the standard 320

  • +H480 - and a height of 480 pixels instead of 240

The result should look like this:


Let's improve the image a bit more:
$ l3p -b -q4 -bu -o Penguin.ldr && povray +OPenguin.png +FN +W640 +H480 +A +P Penguin.pov

The new options are:
  • -q4 - Quality level 4, this includes the "Lego" name on the studs

  • -bu - Create "bumps", this makes the surfaces more "uneven", or more realistic

  • +A - Anti-aliasing, this prevents those "jagged edges"

This should be the result:



Advanced options

As I wrote in the beginning, l3p automatically guesses the best position and angle for the camera and light sources. But we can change them as we please.
Let's try something:
$ l3p -b -q4 -bu -cg40,45 -cpct10 -f -o Penguin.ldr && povray +OPenguin.png +FN +W640 +H480 +A +P Penguin.pov

I included two new options:
  • -cg40,45 - Put the camera at "globe" positions 40° latitude and 45° longitude (the default is 30,45 so we put it a bit "higher")

  • -cpct10 - move the camera back 10%, so that the object is not so close to the edges of the image

  • -f - put a "floor" under the penguin instead of letting it float in the sky, so that we can see the shadows of the light sources

Here is the result:


You can play around with the position of the light sources using the "-lg" option. I'll leave this as an exercise! :)

There are many more advanced options to try. Type "l3p" without any options to see the complete list! If you have a good tip, feel free to post a comment so that I can learn something new.

Using the lgeo library

The images we created with the standard l3p + povray combination look quite good, but when we enlarge the images, the pieces look a bit unrealistic, with edges that are too sharp, etc.

Enter the "lgeo" library of pieces...

The lgeo pieces are specially designed for use with POV-Ray, with more realistic edges, surfaces, etc. l3p can automatically replace all LDRAW pieces with lgeo pieces if a substitute is available (any many are available, at least for the more "standard" pieces).

We just need to include the "-lgeo" parameter (and have the lgeo library installed and "readable" by povray - this needs some configuration...).
This created a nice image of our Penguin at a larger size:
$ l3p -b -q4 -bu -cg40,45 -cpct10 -f -lgeo -o Penguin.ldr && povray +OPenguin.png +FN +W1280 +H960 +A +P Penguin.pov

And this is the result (click on the image to see the full-scale picture):


As you can see, the studs and the edges look more realistic in this picture.

Have fun!

Labels: , , ,

Monday, December 21, 2009

LDView error "libboost_thread-mt.so"

For those who use LDView on Slackware-current and noticed that it suddenly stopped working: the problem is in the latest update of the "boost" library:

+--------------------------+
Thu Dec 17 20:51:37 UTC 2009
...
l/boost-1.41.0-x86_64-1.txz: Upgraded.


This latest update does not include the *-mt (=multi-thread) libraries, as the "normal" version is already multi-threaded.

The solution to get LDView working again is simply rebuild it from the SlackBuild:
- Download the SlackBuild script & untar it
- Download the source for LDView
- run the SlackBuild as:
   # BUILD=2 ./LDView.SlackBuild
- use upgradepkg to upgrade your LDView

Labels: ,

Monday, November 30, 2009

QComicBook 0.5.0 released

Today (*) a new version of QComicBook was released - 0.5.0. The release announcement can be read on freshmeat.

I submitted a new SlackBuild script to SlackBuilds.org. The previous one, for version 0.4.4, won't work as the author has changed to using cmake.

If you can't wait for the SlackBuild to be approved, you can download complete packages from my site - both for Slackware 32 & 64 bits.

* Actually, today or yesterday, depending on your timezone! :)

Labels: ,

Sunday, November 29, 2009

Monitoring your network and servers

I've been busy over the last few weeks evaluating some software to monitor servers, network utilization, etc. I have tested several programs and ended up using three: nagios, cacti, and ntop.

All of these are free & open software. For nagios and cacti you can download SlackBuild scripts from slackbuilds.org maintained by me. For cacti, if you prefer a complete package, you can download one for Slackware here.

For ntop, I adapted a SlackBuild originally written by Michiel van Wessem to install the newer 3.3.10 version. The ntop authors decided to automatically download & install some dependencies (Lua + GeoIP), even if you already have those installed. Since this is a very bad idea (they install it the way they like, while with Slackware YOU are supposed to be in control), I adapted their 'configure.in' and 'Makefile.am' scripts to simply check if those programs are installed and exit if they are not.
Then you can install them the way you like (and following the normal standards) and install ntop afterwards.

With Michiel's permission, I submitted a new SlackBuild script for ntop so SlackBuilds.org that is currently in the pending queue.

Over the next few days / weeks I hope to have some time to elaborate on these three packages and write some hints on how to install and configure them.

Labels: , , , , ,

Thursday, October 15, 2009

Reading Comics on your screen...

If you like to read comic books you might know about the enormous collections of digitalized copies that float around the internet. Normally they are in '.cbr' or '.cbz' format, actually simple rar'd or zipped collections of images.

To read them on your computer, you can either unpack the file and use a standard image viewer, or find a special program to open the .cbr or .cbz files and display the "pages" of the comic.

For Linux you can use QComicBook, a very nice program that uses the qt4 library of KDE4 (but qt4 can also be installed on systems based on Gnome, Xfce, etc. - you do not need the complete KDE environment):


You'll get various zoom modes (page, 2-pages, japanese, rotate, full-screen, etc) to enjoy your comics wherever you are. I like to take some with me on my trips, so that I can read them at night in the hotel, etc.

If you use Slackware, you can get packages for both the 32 & 64 bits versions on my site.

Labels: , ,

Sunday, October 11, 2009

Lego and Linux (part 5)

After exchanging a few e-mails with the author, I have managed to build Slackware packages for LeoCAD, both 32 and 64-bits versions.
LeoCAD is a wonderful piece of software to create your own Lego constructions virtually on your computer - with an unlimited amount of pieces :-)
It can import and export LDR (LDraw) files, and export to POV-Ray for creating fantastic images (see my previous post about POV-Ray).
Here is a screenshot of LeoCAD running on my 64-bit desktop:


The packages can be downloaded from my site, where more screenshots can be seen as well.

Labels: , , ,

Tuesday, October 6, 2009

Lego and Linux (part 4)

Today I finished the Slackware packages for POV-Ray, the Persistence of Vision Raytracer, a fantastic free tool for creating stunning 3D images.
It can be used also for creating beautiful images of your Lego creations. In a future post I might write a small "how-to" with step-by-step instructions, but here is a small example:


As always, the packages can be downloaded from my site.

Labels: , , ,

Sunday, October 4, 2009

Lego and Linux (part 3)

LeoCAD is not so simple as I thought... The 64-bit version compiles after some patching, but it crashes horribly with some basic things.
While sorting this out, I built packages for ldglite, a little program to view and edit LDraw files. It can be called from the command line also to create images of your drawings.
Here is an example of my elevator:


The Slackware packages can be downloaded from my site.

Labels: , ,

Saturday, October 3, 2009

Lego and Linux (part 2)

I finished building the Slackware packages for LDView 4.1 (Beta 1).

There are just two dependencies:
- tinyxml
- LDraw_data (the files with all the different Lego parts)

All packages can be downloaded from my site.

As the original meaning of Lego says: Play well!

Next challenge: building LeoCad...

Labels: , ,

Tuesday, September 29, 2009

Lego and Linux

I am currently in the process of building some software on Linux for viewing and building Lego projects.
The first program I have been successful with is LDView, a very nice tool to visualize LDraw files.
I have it working on Slackware 13.0, both 32-bits and 64-bits. It is still a bit of a "hacked" installation, as it requires some fiddling with parameters and recompiling packages. But I plan to put a package on my site as soon as it is in a decent state and submit a SlackBuild for those who prefer to build their own version.

Here are two screen shots, one from the included model and another from my Lego Elevator:


Labels: , ,

Saturday, September 26, 2009

New TRS-80 emulator for Linux

Mark Grebe released sdltrs, a new emulator for the TRS-80 Model I/III/4/4p for Macintosh, Windows and Linux. It is based on xtrs, but uses the portable sdl library. It has on-screen options to change disks, cassettes, etc.

Packages for Slackware 13.0 are available on my site:

As always, have fun!

Labels: , ,

Monday, September 7, 2009

GUI for Hercules on Linux

Today Jakob Dekel released the first beta version of Hercules Studio, a GUI front-end for Hercules - the System/370, ESA/390 and z/Architecture emulator.

On his site you can find pre-built packages in RPM and DEB format.
For us Slackware users, I created Slackware packages as well, after getting some extra information from a very friendly Jacob Dekel.

The packages for Slackware, both 32 & 64 bits versions, can be downloaded from my site here.
The stable 3.06 version of Hercules is not prepared for a Linux GUI, so you will need the latest svn snapshot, also available as a Slackware package on the same page.

The result can be seen here:

Labels: , , ,

Sunday, September 6, 2009

Slackware packages for Hercules

I have received a few requests for pre-built Slackware packages for the Hercules System/370, ESA/390 and z/Architecture emulator.

I have used Hercules for some time now to run Slack/390 and had already created my own package, but it was not really up to the right standards to be published.

But, with the release of Slackware 13.0 I have reorganized some of my packages and built new ones following the guidelines of SlackBuilds.org.

The result can be downloaded from my site:

Labels: , , ,

Saturday, September 5, 2009

xtrs (TRS-80 emulator) on Slackware

My first professional work with computers was done on a Tandy / Radio Shack TRS-80 Model I. I still have that machine but have not powered it up for at least ten years, since I do not have a working monitor anymore.
But thanks to the various emulators that are available, I can still run the old programs whenever I need or want to.

Since my desktop runs Slackware Linux, the emulator I use is xtrs. It is small, fast and emulates the Model I, III, 4 and 4p. I have had all these models and still have a Model 4p in reasonable condition.

As every good Linux program, xtrs is distributed as open source, for the end-user to compile.
This has never been a problem to me, but not every TRS-80 fan might be happy about this.

So, after the newest release of xtrs in June, I put on my to-do list to make a 'Slackware-package', so that at least Slackware users can run xtrs installing a simple package without any compiling.
Since my to-do list is quite extensive, it took some time for this task to arrive at the top, but today I finally managed to get it done.

The result is available on my homepage, in two versions:


Both have been tested with Slackware 13.0 but should work fine on 12.x as well, and probably some older versions.

For those who prefer to compile their own software, I submitted a SlackBuild to SlackBuilds.org but it is pending for approval at the moment.

Here is a screenshot of xtrs emulating a Model III running NEWDOS/80:


And this is the Model I running the famous Dancing Demon:

Labels: , , ,

Saturday, August 29, 2009

Overview of all Slackware versions

With the release of Slackware 13 this week, I updated my page with all the versions that have ever been released of Slackware.
All information has been retrieved from official sources, like the ChangeLogs from the original versions I have.

The list includes the official release dates, versions of the included kernel, desktop environments, etc.

I you find anything inaccurate, please tell me, stating your sources!

Labels: ,

Thursday, July 23, 2009

Flexible scheduling

As explained in my previous post, I needed a flexible way to schedule a small script to run, with variable parameters.

The basic requirements were:
  • simple to configure (no messing in crontabs)

  • flexible enough to have different schedules on different weekdays (on Sundays a job should be started at another time than on Mondays, for example)

  • should offer the possibility to start different jobs at different times

  • I want a log of all commands executed


For instance, I need the command "foo start 1234" to run every day except Sunday at 23:00h, and "foo stop 1234" always at 01:00h.
I also need "bar load 1 2 3" to run every Wednesday at noon and "bar load 4" every other weekday at noon.

And, as I am a Slackware fan, I want to do all configuration by changing a text file. No graphical interface please, as my servers do not even have X installed.

So the challenge was there :)

Using cron
Now I thought of a solution how these scripts should be started or controlled.
The standard crontab (in /var/spool/cron/crontabs/root) could probably control everything I needed, but it would be a cumbersome task to change it every time. But - on the other hand - I did not want to substitute cron, as it does a nice job scheduling simple daily or monthly tasks.

So I decided to use cron to start my own scheduler. As an interval I choose a five minute period, as that would be accurate enough for me. I don't need any job to start at 12:42 exactly, 12:40 or 12:45 if good enough for me.

My script to check all schedules was named "sched5" and I added the following lines to the crontab:

# Special 5-minute-interval job
0 * * * * /usr/local/sbin/sched5 1> /dev/null
5 * * * * /usr/local/sbin/sched5 1> /dev/null
10 * * * * /usr/local/sbin/sched5 1> /dev/null
15 * * * * /usr/local/sbin/sched5 1> /dev/null
20 * * * * /usr/local/sbin/sched5 1> /dev/null
25 * * * * /usr/local/sbin/sched5 1> /dev/null
30 * * * * /usr/local/sbin/sched5 1> /dev/null
35 * * * * /usr/local/sbin/sched5 1> /dev/null
40 * * * * /usr/local/sbin/sched5 1> /dev/null
45 * * * * /usr/local/sbin/sched5 1> /dev/null
50 * * * * /usr/local/sbin/sched5 1> /dev/null
55 * * * * /usr/local/sbin/sched5 1> /dev/null

As can be seen, the script is stored in /usr/local/sbin, in the path for root - as normal users do not need to access it.

The script
The complete script is copied here:

#!/bin/bash
#
# sched5 Check every 5 minutes /etc/sched5.conf
# for possible jobs to run
# Needs to be started every 5 minutes from cron
# Definition of schedules in /etc/sched5.conf
#
# Version: 0.0.1 - Thursday, Jul 23, 2009
#
# Author: Niels Horn (niels.horn@gmail.com)


###################
## Configuration ##
###################

# Standard interval
SCHED5_INTERVAL=5

# Default log
SCHED5_LOG=/var/log/sched5.log

# Default log level:
# 0 = no logging
# 1 = log execution of jobs
# 2 = log everything
SCHED5_LL=1

# Read configuration from /etc/sched5.conf
. /etc/sched5.conf


####################
## Get DAY / TIME ##
####################
DAY=`date +%u`
TIME=`date +%H:%M`
[ $SCHED5_LL -ge 2 ] && \
   echo "Started: Day=$DAY Time=$TIME" >> $SCHED5_LOG


####################################
## Main loop: check all schedules ##
####################################

for sched in `seq $SCHED_NUM`; do

   sched_name=SCHED${sched}_NAME
   eval sched_name=\$$sched_name

   [ $SCHED5_LL -ge 2 ] && \
      echo "-- Schedule $sched = $sched_name" >> $SCHED5_LOG

   # get rules for this schedule
   sched_rules=SCHED${sched}_RULES
   eval sched_rules=\$$sched_rules

   # loop through all rules for this schedule
   cmd_found=0
   for rule in $sched_rules; do

      [ $SCHED5_LL -ge 2 ] && \
         echo " -- Rule $rule " >> $SCHED5_LOG

      # dissect rule
      rule_day=`echo $rule | cut -f1 -d,`
      rule_tim=`echo $rule | cut -f2 -d,`
      rule_cmd=`echo $rule | cut -f3 -d,`
      # calculate time+interval
      timh=${rule_tim:0:2}
      timm=${rule_tim:3}
      [ "${timm:0:1}" == "0" ] && timm=${timm:1}
      let timm=$timm+$SCHED5_INTERVAL
      [ ${#timm} -eq 1 ] && timm="0"$timm
      tim2=$timh":"$timm

      [ $SCHED5_LL -ge 2 ] && \
         echo " -- Rule: $rule_day $rule_tim-$tim2 -> $rule_cmd" >> $SCHED5_LOG

      # Check if rule is valid for this day
      if [ "$rule_day" == "*" -o "$rule_day" == "$DAY" ] ; then

         [ $SCHED5_LL -ge 2 ] && \
            echo " -- day ok" >> $SCHED5_LOG

         # Current time => time of rule?
         if [ "$TIME" == "$rule_tim" -o "$TIME" \> "$rule_tim" ] ; then

            [ $SCHED5_LL -ge 2 ] && \
               echo " -- time start ok" >> $SCHED5_LOG

            # Current time < time of rule + interval?
            if [ "$TIME" \< "$tim2" ] ; then

               [ $SCHED5_LL -ge 2 ] && \
                  echo " -- time end ok" >> $SCHED5_LOG
               # ok, we found a command to execute!
               cmd_found=$rule_cmd
            fi
         fi
      fi
   done # all rules for this schedule

   # Did we find a command to execute?
   if [ "$cmd_found" != "0" ] ; then

      [ $SCHED5_LL -ge 2 ] && \
         echo " -- Starting command $cmd_found" >> $SCHED5_LOG

      # Get command to execute
      cmd=SCHED${sched}_CMD_$cmd_found
      eval cmd=\$$cmd

      [ $SCHED5_LL -ge 1 ] && \
         echo "$TIME Schedule $sched / $sched_name: Starting command \"${cmd}\"" >> $SCHED5_LOG

      # Execute command
      . $cmd

   fi

done # all schedules

[ $SCHED5_LL -ge 2 ] && \
   echo "Finished" >> $SCHED5_LOG

# all done!

Save this script as /usr/local/sbin/sched5 and chmod it to 700, as only root needs to read and execute it. It can also be downloaded from my site.

The configuration file
The configuration file is saved as /etc/sched5.conf and is a simple text file.
To explain to options, I put the examples I gave in the beginning of this post in this configuration:

#!/bin/bash
### Configuration for 'sched5' ##############################################
##
## requires sched5 to be started every 5 minutes from crontab
##

#########################
## Standard Parameters ##
#########################

### Location of log
# Default = /var/log/sched5.log
#SCHED5_LOG=/var/log/sched5.log

### Logging Level
# 0 = log nothing
# 1 = log execution of jobs
# 2 = log everything
# Default = 1
#SCHED5_LL=2


###############
## Schedules ##
###############

# Number of defined schedules
SCHED_NUM=2

##
## Start of Schedule 1 (SCHED1)
## Repeat following lines for each schedule
## Changing the variables from 'SCHED1' to 'SCHED2', 'SCHED3', etc.
##

# Name of schedule, only used in log
SCHED1_NAME=foo_schedule

# Commands to execute
# valid commands are SCHEDx_CMD_1 to SCHEDx_CMD_9
SCHED1_CMD_1='foo start 1234'
SCHED1_CMD_2='foo stop 1234'

# Rules for execution: day,time,cmd
# where day = day to execute (1=Mo,2=Tu,...7=Su, *=all)
# time = time to execute command
# cmd = # of command to execute (1-9, 0=do nothing)
# Separate rules with space, later rule has preference over earlier rule,
# so you can start with a general rule for all days (*), then alter for
# specific days (like 7=Sunday)
# Use cmd=0 to cancel a more general rule (like day=*)
SCHED1_RULES="\
*,23:00,1 \
7,23:00,0 \
*,01:00,2"

##
## End of Schedule 1 (SCHED1)
##

SCHED2_NAME=bar_schedule
SCHED2_CMD_1='bar load 1 2 3'
SCHED2_CMD_2='bar load 4'
SCHED2_RULES="\
*,12:00,2 \
3,12:00,1"


Dissecting the configuration file
The first lines define the level of logging and where the log should be saved.
The defaults are explained in the text.

In this example we have two different schedules:

# Number of defined schedules
SCHED_NUM=2


The first schedule has more comments, to explain all options.

First we see the name of the schedule, only used in the log:

# Name of schedule, only used in log
SCHED1_NAME=foo_schedule


Then we'll find the several commands we can schedule:

# Commands to execute
# valid commands are SCHEDx_CMD_1 to SCHEDx_CMD_9
SCHED1_CMD_1='foo start 1234'
SCHED1_CMD_2='foo stop 1234'

All commands must be executable from the command line by root to function.
We can actually have several different commands, and to be exact, names can also end in words, like "SCHED1_CMD_start" - just change the code from "1" to "start" in the rules below.

We now go to the rules of this schedule:

# Rules for execution: day,time,cmd
# where day = day to execute (1=Mo,2=Tu,...7=Su, *=all)
# time = time to execute command
# cmd = # of command to execute (1-9, 0=do nothing)
# Separate rules with space, later rule has preference over earlier rule,
# so you can start with a general rule for all days (*), then alter for
# specific days (like 7=Sunday)
# Use cmd=0 to cancel a more general rule (like day=*)
SCHED1_RULES="\
*,23:00,1 \
7,23:00,0 \
*,01:00,2"

As you can see, the special command "0" cancels a previous rule. So in this example, we always run command 1 (foo start 1234) at 23:00h, except on Sundays (day=7).
The second rule is simpler: start command 2 every day at 01:00h.

The second schedule has no comments, to show how simple it is to add extra schedules:

SCHED2_NAME=bar_schedule
SCHED2_CMD_1='bar load 1 2 3'
SCHED2_CMD_2='bar load 4'
SCHED2_RULES="\
*,12:00,2 \
3,12:00,1"


Starting it all
After changing the crontab, saving the script and setting up the configuration, make sure that everything is scheduled by restarting crond:

killall crond
/usr/sbin/crond -l10 >>/var/log/cron 2>&1

This last line comes from /etc/rc.d/rc.M

As the configuration file is re-read every time the script starts, you can just edit the /etc/sched5.conf file and the changes will be in effect immediately.


As always, feel free to comment on this post with questions or suggestions!

Labels: , , ,

Firewall - Blocking a specific IP

This week I needed a solution to block and unblock certain IPs from accessing the internet at certain times.
I didn't want to change my firewall script too much and didn't want to change it every time the rules changed (which change a lot due to variable circumstances).

So I created a two-part solution. In this post I will describe how I changed my firewall and show a simple script that can block or unblock a specific IP address.

In a following post I will describe how I created a script with a configuration file where I can define when to do what.

iptables and chains
Firewalls in Linux are built with iptables and "chains". Check this article for some basics about writing your own firewall script.

In a chain you can put several rules to filter network packets. It is possible to call a chain from another chain. If the called chain does not filter the packet, it automatically returns to the calling chain.

For instance, we have the standard "FORWARD" chain in a firewall.
In the beginning of this chain, we can always call a user-defined chain called "f_ip".

We create the user-defined chain with:

iptables -N f_ip

And pass all forwarded packets through this chain by including this line as one of our first rules in the FORWARD chain:

iptables -A FORWARD -j f_ip


If the "f_ip" chain is empty, or none of the rules filter the packet to be forwarded, the "FORWARD" chain takes over again:



Now I also want to know if a blocked IP address tried to use the internet, so I created another user-defined chain to log & drop packets:

iptables -N f_ip_drop
iptables -A f_ip_drop -j LOG --log-level 6 --log-prefix "FW: ip: "
iptables -A f_ip_drop -j DROP

Take note that for the time being, nothing goes to the f_ip_drop chain!

But now I can use an external script to add rules to the f_ip chain to filter a specific address without having to change my firewall script.
This external script could contain something like:

iptables -A f_ip -s a.b.c.d -j f_ip_drop

(where "a.b.c.d" is substituted by a real IP address of course)

This part of the firewall then works as follows:



The external script
So now I had my firewall altered and I was ready to write my script to block and unblock specific IP addresses.

The result is here:

#!/bin/bash
#
# fw_ipfilt Filter specific IP addresses
# Needs rc.firewall 0.2.3 or newer
#
# Version: 0.0.1 - Thursday, Jul 23, 2009
#
# Author: Niels Horn (niels.horn@gmail.com)


###################
## Configuration ##
###################

IPT=iptables


######################
## Clear IP filters ##
######################
ip_clear() {
  # flush f_ip chain
  $IPT -F f_ip
}


######################
## Add IP to filter ##
######################
ip_addip() {
  ip=$1
  # send all packets from or to $ip to f_ip_drop chain
  $IPT -A f_ip -s $ip -j f_ip_drop
  $IPT -A f_ip -d $ip -j f_ip_drop
}


###########################
## Remove IP from filter ##
###########################
ip_delip() {
  ip=$1
  # delete rules for $ip from f_ip chain
  $IPT -D f_ip -s $ip -j f_ip_drop
  $IPT -D f_ip -d $ip -j f_ip_drop
}


###################
## Check Command ##
###################

case "$1" in
  'add')
    ip_addip $2
    ;;
  'clear')
    ip_clear
    ;;
  'del')
    ip_delip $2
    ;;
  *)
    echo "use $0 add|del <ip> or $0 clear"
esac

I saved this script as /usr/local/sbin/fw_ipfilt and made it executable and readable only for root (chmod 700).
Now I can block an IP address at any time with:

fw_ipfilt add 192.168.1.123

and unblock it with>

fw_ipfilt del 192.168.1.123

To unblock all previously blocked addresses use:

fw_ipfilt clear



As always, if you have any questions or suggestions, feel free to comment on this post!

Labels: , , ,