Daemonize Perl - or howto create a daemon in Perl
Perl have never been something I've looked in to as it is not as easy (I think as) as what I'm used to, which is C/C++, PHP, Shell scripts, etc. But I've found out that there are a few things where nothing beats Perl, and one of them is to create small deamons (and also programs) which only exist because I got an "excelent" idea.
Having my own server, one of the most anoying things I see everyday is people who is trying to login to my server with SSH, so I get my log filled up with stuff like "Aug 17 01:54:22 blabla sshd[9821]: Invalid user blabla from ::ffff:123.456.789.123", and in some cases hundreds of them every day. So looking into how syslog works, it turned out that one can actually have multible log facilities pointing to diffrent targets. But more about that later, read another blog entry
The problem is that a daemon is require in an enviroment where one wants to monitor events which happens now. Writing deamon's is possible in almost every programming language, but Perl *) is good at one thing, it have everything, and then a bit. Especially the way one can use regular expressions directly in the language helps.
*) Yes I could do it in C or C++ (which probably would make more sense), but I could not be bothered, and this was a good excercise in learning Perl.
So I set up trying to figure out how to do this, and found that it is not too difficult (I'm a great believer in cut 'n paste), and a skeleton would look like this:
#!/bin/perl
#
use strict;
use POSIX qw(setsid);
use LWP::Simple;
# flush the buffer
$| = 1;
# daemonize the program
&daemonize;
while(1) {
#
# Do interesting stuff here.......
#
}
# here is where we make ourself a daemon
sub daemonize {
chdir '/' or die "Can't chdir to /: $!";
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
umask 0;
}
See that is not to difficult, I will continue my saga about how to stop idiots trying to access my box.
Having my own server, one of the most anoying things I see everyday is people who is trying to login to my server with SSH, so I get my log filled up with stuff like "Aug 17 01:54:22 blabla sshd[9821]: Invalid user blabla from ::ffff:123.456.789.123", and in some cases hundreds of them every day. So looking into how syslog works, it turned out that one can actually have multible log facilities pointing to diffrent targets. But more about that later, read another blog entry
The problem is that a daemon is require in an enviroment where one wants to monitor events which happens now. Writing deamon's is possible in almost every programming language, but Perl *) is good at one thing, it have everything, and then a bit. Especially the way one can use regular expressions directly in the language helps.
*) Yes I could do it in C or C++ (which probably would make more sense), but I could not be bothered, and this was a good excercise in learning Perl.
So I set up trying to figure out how to do this, and found that it is not too difficult (I'm a great believer in cut 'n paste), and a skeleton would look like this:
#!/bin/perl
#
use strict;
use POSIX qw(setsid);
use LWP::Simple;
# flush the buffer
$| = 1;
# daemonize the program
&daemonize;
while(1) {
#
# Do interesting stuff here.......
#
}
# here is where we make ourself a daemon
sub daemonize {
chdir '/' or die "Can't chdir to /: $!";
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
umask 0;
}
See that is not to difficult, I will continue my saga about how to stop idiots trying to access my box.
Comments
Just one hint to avoid idiots accessing your box: make sshd listen a non standard port (random idea: 15487), so only you and trusted friends know how to access it, it's also nice to only allow trusted hosts via config file. And of course: use a firewall properly configured !