Loading ...
Sorry, an error occurred while loading the content.

half-OT: own DNSBL and honeypot

Expand Messages
  • lists@rhsoft.net
    sorry for the more or less off-topic but i think here are the people with most expierience what i would like to do is: * setup whatever software listeing on
    Message 1 of 10 , May 30, 2014
    • 0 Attachment
      sorry for the more or less off-topic but i think
      here are the people with most expierience

      what i would like to do is:

      * setup whatever software listeing on port 25
      * any IP connecting to that machine feed into
      a dns-zone file for a DNSBL

      currently i have a stripped down CentOS6 listening
      on all unsued IP's in a /24 network on standard
      ports with xinedt answering to ping and response
      with a dash-script "creep away"

      assuming that only infected machines part of a botnet
      are trying to connect on random IP's to port 25 i would
      say the same machines likely are used to spread spam

      so feed any connection to a automatically maintained
      RBL may stop recent spam waves targeting the own network
      long before the big RBL's react nad if you achive to
      remove IP's on that auto-feeded RBL after 48 hours there
      should be little to no bad impact
    • lists@rhsoft.net
      ... answering myself: a tiny, secure piece of software accepting connections on a specific port and write only the IP adress in a textfile would be enough as
      Message 2 of 10 , May 30, 2014
      • 0 Attachment
        Am 30.05.2014 16:21, schrieb lists@...:
        > sorry for the more or less off-topic but i think
        > here are the people with most expierience
        >
        > what i would like to do is:
        >
        > * setup whatever software listeing on port 25
        > * any IP connecting to that machine feed into
        > a dns-zone file for a DNSBL
        >
        > currently i have a stripped down CentOS6 listening
        > on all unsued IP's in a /24 network on standard
        > ports with xinedt answering to ping and response
        > with a dash-script "creep away"
        >
        > assuming that only infected machines part of a botnet
        > are trying to connect on random IP's to port 25 i would
        > say the same machines likely are used to spread spam
        >
        > so feed any connection to a automatically maintained
        > RBL may stop recent spam waves targeting the own network
        > long before the big RBL's react nad if you achive to
        > remove IP's on that auto-feeded RBL after 48 hours there
        > should be little to no bad impact

        answering myself:

        a tiny, secure piece of software accepting connections on
        a specific port and write only the IP adress in a textfile
        would be enough as start

        the rest are some cron-scripts maintainingg a database with
        timestamp/IP, generate the PTR-zone for the RBL and reload
        whatever nameserver software using that zone file
      • lists@rhsoft.net
        ... well, that s a php service accepting a single connection at one time, store the IP and close without any answer to the client, after the socket is created
        Message 3 of 10 , May 30, 2014
        • 0 Attachment
          Am 30.05.2014 16:32, schrieb lists@...:
          > Am 30.05.2014 16:21, schrieb lists@...:
          >> sorry for the more or less off-topic but i think
          >> here are the people with most expierience
          >>
          >> what i would like to do is:
          >>
          >> * setup whatever software listeing on port 25
          >> * any IP connecting to that machine feed into
          >> a dns-zone file for a DNSBL
          >>
          >> currently i have a stripped down CentOS6 listening
          >> on all unsued IP's in a /24 network on standard
          >> ports with xinedt answering to ping and response
          >> with a dash-script "creep away"
          >>
          >> assuming that only infected machines part of a botnet
          >> are trying to connect on random IP's to port 25 i would
          >> say the same machines likely are used to spread spam
          >>
          >> so feed any connection to a automatically maintained
          >> RBL may stop recent spam waves targeting the own network
          >> long before the big RBL's react nad if you achive to
          >> remove IP's on that auto-feeded RBL after 48 hours there
          >> should be little to no bad impact
          >
          > answering myself:
          >
          > a tiny, secure piece of software accepting connections on
          > a specific port and write only the IP adress in a textfile
          > would be enough as start
          >
          > the rest are some cron-scripts maintaining a database with
          > timestamp/IP, generate the PTR-zone for the RBL and reload
          > whatever nameserver software using that zone file

          well, that's a php service accepting a single connection
          at one time, store the IP and close without any answer to
          the client, after the socket is created it drops the privileges
          to 'nobody' which is in case of Redhat uid/gid 99

          that wrapped in a tiny systemd-unit and you are done
          for collecting the relevant data and the rest should
          be not that much work since i've written a BIND backend
          for some hundret domains running 6 years now in prod

          #!/usr/bin/php
          <?php
          /** listen on all interfaces */
          $address = '0.0.0.0';
          /** tcp port to listen */
          $port = 1000;
          /** disable output buffering */
          ob_implicit_flush();
          /** create the socket */
          if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ) === false)
          {
          exit('socket_create() failed: reason: ' . socket_strerror(socket_last_error()) . "\n");
          }
          if(@socket_bind($sock, $address, $port) === false)
          {
          exit('socket_bind() failed: reason: ' . socket_strerror(socket_last_error($sock)) . "\n");
          }
          if(@socket_listen($sock, 5) === false)
          {
          exit('socket_listen() failed: reason: ' . socket_strerror(socket_last_error($sock)) . "\n");
          }
          /** drop privileges to 'nobody' */
          if(!@posix_setgid(99) || !@posix_setuid(99))
          {
          exit('Drop privileges failed' . "\n");
          }
          /** service loop */
          while(1 == 1)
          {
          /** accept connection */
          $msgsock = @socket_accept($sock);
          /** get the remote address */
          $remote_ip = '';
          @socket_getpeername($msgsock , $remote_ip);
          /** here later comes the code to feed a database with IP's connecting to the honeypot */
          if(!empty8$remote_ip)
          {
          echo $remote_ip . "\n";
          }
          /** close connection */
          @socket_close($msgsock);
          }
          ?>
        • Wietse Venema
          ... PHP, eh? You also need to drop secondary groups . On UNIX, that s done with setgroups() or initgroups(), before dropping root privileges. Wietse
          Message 4 of 10 , May 30, 2014
          • 0 Attachment
            lists@...:
            > /** drop privileges to 'nobody' */
            > if(!@posix_setgid(99) || !@posix_setuid(99))

            PHP, eh? You also need to drop "secondary groups". On UNIX, that's
            done with setgroups() or initgroups(), before dropping root privileges.

            Wietse
          • Robert Schetterer
            ... done something like this years ago, mostly doubles i.e spamhaus entries but usefull with many servers ... i thought spreading filtered syslog results from
            Message 5 of 10 , May 30, 2014
            • 0 Attachment
              Am 30.05.2014 16:32, schrieb lists@...:
              >
              > Am 30.05.2014 16:21, schrieb lists@...:
              >> sorry for the more or less off-topic but i think
              >> here are the people with most expierience
              >>
              >> what i would like to do is:
              >>
              >> * setup whatever software listeing on port 25
              >> * any IP connecting to that machine feed into
              >> a dns-zone file for a DNSBL

              done something like this years ago, mostly doubles i.e spamhaus entries
              but usefull with many servers

              >>
              >> currently i have a stripped down CentOS6 listening
              >> on all unsued IP's in a /24 network on standard
              >> ports with xinedt answering to ping and response
              >> with a dash-script "creep away"
              >>
              >> assuming that only infected machines part of a botnet
              >> are trying to connect on random IP's to port 25 i would
              >> say the same machines likely are used to spread spam
              >>
              >> so feed any connection to a automatically maintained
              >> RBL may stop recent spam waves targeting the own network
              >> long before the big RBL's react nad if you achive to
              >> remove IP's on that auto-feeded RBL after 48 hours there
              >> should be little to no bad impact
              >
              > answering myself:
              >
              > a tiny, secure piece of software accepting connections on
              > a specific port and write only the IP adress in a textfile
              > would be enough as start
              >
              > the rest are some cron-scripts maintainingg a database with
              > timestamp/IP, generate the PTR-zone for the RBL and reload
              > whatever nameserver software using that zone file
              >

              i thought spreading filtered syslog results from real servers feeding
              to other ones, i.e with/over own rbl and/or combinate with direct
              firewalling actions out of syslog i.e in/with recent module, but i
              havent got time to investigate in this yet



              Best Regards
              MfG Robert Schetterer

              --
              [*] sys4 AG

              http://sys4.de, +49 (89) 30 90 46 64
              Franziskanerstraße 15, 81669 München

              Sitz der Gesellschaft: München, Amtsgericht München: HRB 199263
              Vorstand: Patrick Ben Koetter, Marc Schiffbauer
              Aufsichtsratsvorsitzender: Florian Kirstein
            • lists@rhsoft.net
              ... yes, simply because it s the language i know to handle perfectly and the database insert / update is done within a few minutes after the next beer :-) from
              Message 6 of 10 , May 30, 2014
              • 0 Attachment
                Am 30.05.2014 18:52, schrieb Wietse Venema:
                > lists@...:
                >> /** drop privileges to 'nobody' */
                >> if(!@posix_setgid(99) || !@posix_setuid(99))
                >
                > PHP, eh?

                yes, simply because it's the language i know to handle
                perfectly and the database insert / update is done
                within a few minutes after the next beer :-)

                from that moment on, well, it can start collect
                and the decision which DNS server and how to feed
                it with the data follows later

                > You also need to drop "secondary groups". On UNIX, that's
                > done with setgroups() or initgroups(), before dropping
                > root privileges

                thanks for the hint, looks not that it's supported
                http://www.php.net/manual/en/book.posix.php

                on the other hand that machine is stripped down as well
                as the service-script don't have much code or handles
                any user input at all becaue the remote-ip don't come
                from the client and after have that in a var the connection
                is dropped
              • Wietse Venema
                ... It took me a few seconds to find that PHP has initgroups. site:php.net initgroups Wietse
                Message 7 of 10 , May 30, 2014
                • 0 Attachment
                  lists@...:
                  > > You also need to drop "secondary groups". On UNIX, that's
                  > > done with setgroups() or initgroups(), before dropping
                  > > root privileges
                  >
                  > thanks for the hint, looks not that it's supported
                  > http://www.php.net/manual/en/book.posix.php

                  It took me a few seconds to find that PHP has initgroups.

                  site:php.net initgroups

                  Wietse
                • lists@rhsoft.net
                  ... indeed - no excuse except blindness :-( implemented - thanks! in the meantime i installed and configured the mysql-server scary, my first from-scratch
                  Message 8 of 10 , May 30, 2014
                  • 0 Attachment
                    Am 30.05.2014 22:48, schrieb Wietse Venema:
                    > lists@...:
                    >>> You also need to drop "secondary groups". On UNIX, that's
                    >>> done with setgroups() or initgroups(), before dropping
                    >>> root privileges
                    >>
                    >> thanks for the hint, looks not that it's supported
                    >> http://www.php.net/manual/en/book.posix.php
                    >
                    > It took me a few seconds to find that PHP has initgroups.
                    >
                    > site:php.net initgroups

                    indeed - no excuse except blindness :-(
                    implemented - thanks!

                    in the meantime i installed and configured the mysql-server
                    scary, my first from-scratch mysql-setup after 11 years

                    most i likely wrote the code for insert/update (currently
                    untested) and also planned a 'dnsbl_auto' feature which is
                    set by the honeypot-service for auto-expires and remove
                    old entries will skip records where it is 0 to provide
                    a webinterface later to add blocked IP's manually

                    at least that parts are straight forwarded

                    well, finally i need to make a decision which DNS server
                    provides the easiest zone-handling (BIND, unbound, dnsmasq...)
                    and learn again how to start a PHP service on non-systemd-setups
                    _____________________________________________________________________

                    #!/usr/bin/php
                    <?php
                    /** listen on all interfaces */
                    $address = '0.0.0.0';
                    /** tcp port to listen */
                    settype($_SERVER['argv'], 'array');
                    settype($_SERVER['argv'][1], 'integer');
                    if(empty($_SERVER['argv'][1]))
                    {
                    $port = 25;
                    }
                    else
                    {
                    $port = $_SERVER['argv'][1];
                    }
                    /** configuration */
                    $whitelist = array();
                    $simulation = true;
                    $ttl = 3600 * 24 * 7;
                    /** database account */
                    $db_host = 'localhost';
                    $db_user = 'dnsbl';
                    $db_db = 'dnsbl';
                    $db_table = 'dnsbl';
                    $db_port = 3307;
                    $db_pwd = '***********************';
                    /** disable output buffering */
                    ob_implicit_flush();
                    /** create the socket */
                    if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ) === false)
                    {
                    exit('socket_create() failed: reason: ' . socket_strerror(socket_last_error()) . "\n");
                    }
                    if(@socket_bind($sock, $address, $port) === false)
                    {
                    exit('socket_bind() failed: reason: ' . socket_strerror(socket_last_error($sock)) . "\n");
                    }
                    if(@socket_listen($sock, 5) === false)
                    {
                    exit('socket_listen() failed: reason: ' . socket_strerror(socket_last_error($sock)) . "\n");
                    }
                    /** drop privileges to 'nobody' */
                    if(!@posix_initgroups('nobody', 99) || !@posix_setgid(99) || !@posix_setuid(99))
                    {
                    exit('Drop privileges failed' . "\n");
                    }
                    /** service loop */
                    while(1 == 1)
                    {
                    /** accept connection */
                    $msgsock = @socket_accept($sock);
                    /** get the remote address */
                    $remote_ip = '';
                    @socket_getpeername($msgsock , $remote_ip);
                    /** insert remote adress to database or update the timestamp to avoid expire if it already exists */
                    if(!empty($remote_ip) && !in_array($remote_ip, $whitelist))
                    {
                    switch($simulation)
                    {
                    /** database mode */
                    case false:
                    /** connect to database */
                    $db_conn = mysqli_init();
                    $rw = mysqli_real_connect($db_conn, $db_host, $db_user, $db_pwd, $db_db, $db_port);
                    if($rw)
                    {
                    /** try to find existing record and update only timestamp */
                    $result = mysqli_query($db_conn, 'select dns_key from ' . $db_table . ' where dnsbl_ip=\'' .
                    mysqli_real_escape_string($db_conn, $remote_ip) . '\';', MYSQLI_STORE_RESULT);
                    if(mysqli_num_rows($result))
                    {
                    $row = mysqli_fetch_row($result);
                    mysqli_free_result($result);
                    mysqli_query($db_conn, 'update ' . $db_table . ' set dnsbl_timestamp=' . time() . ' where dns_key=' .
                    intval($row[0]) . ';', MYSQLI_USE_RESULT);
                    }
                    /** insert new ip into database */
                    else
                    {
                    mysqli_free_result($result);
                    mysqli_query($db_conn, 'insert into ' . $db_table . '(dnsbl_ip, dnsbl_timestamp, dnsbl_auto) values (\'' .
                    mysqli_real_escape_string($db_conn, $remote_ip) . '\',' . time() . ', 1);', MYSQLI_USE_RESULT);
                    }
                    mysqli_close($db_conn);
                    }
                    break;
                    /** debug: echo connecting remote address on stdout */
                    case true:
                    echo $remote_ip . "\n";
                    break;
                    }
                    }
                    /** close connection */
                    @socket_close($msgsock);
                    }
                    ?>
                    _____________________________________________________________________

                    mysql> show create table dnsbl;
                    CREATE TABLE `dnsbl` (
                    `dnsbl_key` int(10) unsigned NOT NULL AUTO_INCREMENT,
                    `dnsbl_ip` varchar(255) COLLATE latin1_german1_ci NOT NULL DEFAULT '',
                    `dnsbl_timestmap` int(10) unsigned NOT NULL DEFAULT '0',
                    `dnsbl_auto` tinyint(1) unsigned NOT NULL DEFAULT '0',
                    PRIMARY KEY (`dnsbl_key`),
                    UNIQUE KEY `dnsbl_ip` (`dnsbl_ip`)
                    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;
                  • lists@rhsoft.net
                    ... well, some typos in column-names and script fixend it works, even before written the init-script the first manual start caught IP s connecting to a not as
                    Message 9 of 10 , May 30, 2014
                    • 0 Attachment
                      Am 30.05.2014 23:18, schrieb lists@...:
                      >
                      > Am 30.05.2014 22:48, schrieb Wietse Venema:
                      >> lists@...:
                      >>>> You also need to drop "secondary groups". On UNIX, that's
                      >>>> done with setgroups() or initgroups(), before dropping
                      >>>> root privileges
                      >>>
                      >>> thanks for the hint, looks not that it's supported
                      >>> http://www.php.net/manual/en/book.posix.php
                      >>
                      >> It took me a few seconds to find that PHP has initgroups.
                      >>
                      >> site:php.net initgroups
                      >
                      > indeed - no excuse except blindness :-(
                      > implemented - thanks!
                      >
                      > in the meantime i installed and configured the mysql-server
                      > scary, my first from-scratch mysql-setup after 11 years
                      >
                      > most i likely wrote the code for insert/update (currently
                      > untested) and also planned a 'dnsbl_auto' feature which is
                      > set by the honeypot-service for auto-expires and remove
                      > old entries will skip records where it is 0 to provide
                      > a webinterface later to add blocked IP's manually

                      well, some typos in column-names and script fixend

                      it works, even before written the init-script the first manual start
                      caught IP's connecting to a not as MTA anncounced machine which answers
                      the question if it's worth the work and was not clear at start

                      it took five seconds until 220.225.200.7 was caught

                      mysql> select * from dnsbl;
                      +-----------+-----------------+-----------------+------------+
                      | dnsbl_key | dnsbl_ip | dnsbl_timestamp | dnsbl_auto |
                      +-----------+-----------------+-----------------+------------+
                      | 1 | ***myip*** | 1401485331 | 1 |
                      | 2 | 220.225.200.7 | 1401485584 | 1 |
                      | 3 | 96.242.95.29 | 1401485528 | 1 |
                      | 4 | 112.120.65.223 | 1401485552 | 1 |
                      | 5 | 212.174.252.130 | 1401485693 | 1 |
                      +-----------+-----------------+-----------------+------------+
                      5 rows in set (0.00 sec)

                      CREATE TABLE `dnsbl` (
                      `dnsbl_key` int(10) unsigned NOT NULL AUTO_INCREMENT,
                      `dnsbl_ip` varchar(255) COLLATE latin1_german1_ci NOT NULL DEFAULT '',
                      `dnsbl_timestamp` int(10) unsigned NOT NULL DEFAULT '0',
                      `dnsbl_auto` tinyint(1) unsigned NOT NULL DEFAULT '0',
                      PRIMARY KEY (`dnsbl_key`),
                      UNIQUE KEY `dnsbl_ip` (`dnsbl_ip`)
                      ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci;
                      ____________________________________________________

                      #!/usr/bin/php
                      <?php
                      /** listen on all interfaces */
                      $address = '0.0.0.0';
                      /** tcp port to listen */
                      settype($_SERVER['argv'], 'array');
                      settype($_SERVER['argv'][1], 'integer');
                      if(empty($_SERVER['argv'][1]))
                      {
                      $port = 25;
                      }
                      else
                      {
                      $port = $_SERVER['argv'][1];
                      }
                      /** configuration */
                      $whitelist = array();
                      $simulation = false;
                      $ttl = 3600 * 24 * 7;
                      /** database account */
                      $db_host = 'localhost';
                      $db_user = 'dnsbl';
                      $db_db = 'dnsbl';
                      $db_table = 'dnsbl';
                      $db_port = 3307;
                      $db_pwd = '************';
                      /** disable output buffering */
                      ob_implicit_flush();
                      /** create the socket */
                      if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ) === false)
                      {
                      exit('socket_create() failed: reason: ' . socket_strerror(socket_last_error()) . "\n");
                      }
                      if(@socket_bind($sock, $address, $port) === false)
                      {
                      exit('socket_bind() failed: reason: ' . socket_strerror(socket_last_error($sock)) . "\n");
                      }
                      if(@socket_listen($sock, 5) === false)
                      {
                      exit('socket_listen() failed: reason: ' . socket_strerror(socket_last_error($sock)) . "\n");
                      }
                      /** drop privileges to 'nobody' */
                      if(!@posix_initgroups('nobody', 99) || !@posix_setgid(99) || !@posix_setuid(99))
                      {
                      exit('Drop privileges failed' . "\n");
                      }
                      /** service loop */
                      while(1 == 1)
                      {
                      /** accept connection */
                      $msgsock = @socket_accept($sock);
                      /** get the remote address */
                      $remote_ip = '';
                      @socket_getpeername($msgsock , $remote_ip);
                      /** insert remote adress to database or update the timestamp to avoid expire if it already exists */
                      if(!empty($remote_ip) && !in_array($remote_ip, $whitelist))
                      {
                      switch($simulation)
                      {
                      /** database mode */
                      case false:
                      /** connect to database */
                      $db_conn = mysqli_init();
                      $rw = mysqli_real_connect($db_conn, $db_host, $db_user, $db_pwd, $db_db, $db_port);
                      if($rw)
                      {
                      /** try to find existing record and update only timestamp */
                      $fehler = 0;
                      $result = mysqli_query($db_conn, 'select dnsbl_key from ' . $db_table . ' where dnsbl_ip=\'' .
                      mysqli_real_escape_string($db_conn, $remote_ip) . '\';', MYSQLI_STORE_RESULT) or $fehler = 1;
                      if($fehler)
                      {
                      echo 'SQL-ERROR: ' . mysqli_error($db_conn) . "\n";
                      }
                      else
                      {
                      if(mysqli_num_rows($result))
                      {
                      $row = mysqli_fetch_row($result);
                      mysqli_free_result($result);
                      $fehler = 0;
                      $result = mysqli_query($db_conn, 'update ' . $db_table . ' set dnsbl_timestamp=' . time() . ' where
                      dnsbl_key=' . intval($row[0]) . ';', MYSQLI_USE_RESULT) or $fehler = 1;
                      if($fehler)
                      {
                      echo 'SQL-ERROR: ' . mysqli_error($db_conn) . "\n";
                      }
                      }
                      /** insert new ip into database */
                      else
                      {
                      mysqli_free_result($result);
                      $fehler = 0;
                      $result = mysqli_query($db_conn, 'insert into ' . $db_table . '(dnsbl_ip, dnsbl_timestamp, dnsbl_auto)
                      values (\'' . mysqli_real_escape_string($db_conn, $remote_ip) . '\',' . time() . ', 1);', MYSQLI_USE_RESULT) or
                      $fehler = 1;
                      if($fehler)
                      {
                      echo 'SQL-ERROR: ' . mysqli_error($db_conn) . "\n";
                      }
                      }
                      }
                      mysqli_close($db_conn);
                      }
                      break;
                      /** debug: echo connecting remote address on stdout */
                      case true:
                      echo $remote_ip . "\n";
                      break;
                      }
                      }
                      /** close connection */
                      @socket_close($msgsock);
                      }
                      ?>
                    • lists@rhsoft.net
                      to close that topic with a little success story: hopefully the zip attachment with the scervice/update-script makes it through the list, free for any use and
                      Message 10 of 10 , May 31, 2014
                      • 0 Attachment
                        to close that topic with a little success story:

                        hopefully the zip attachment with the scervice/update-script
                        makes it through the list, free for any use and modification

                        * the php-service script works fine in production
                        * there are alreday 270 IP's listed
                        * port 22,23,25,80,445,5900 and 8080 are good honeypots
                        to catch infected zombies doing port-scans most likely
                        later also used for spam
                        * well, a unused domain/subdomain as MX to the honepot
                        and on some webpages hidden mail-links helps too
                        * rbldnsd is easy to handle/update and lightweight

                        [root@honeypot:~]$ cat /etc/sysconfig/rbldnsd
                        # /etc/default/rbldnsd
                        RBLDNSD="dnsbl -r/var/lib/rbldnsd -q -b 0.0.0.0 dnsbl.example.com:ip4set:dnsbl.example.com"

                        [root@honeypot:~]$ cat /var/lib/rbldnsd/dnsbl.example.com
                        :127.0.0.2: $ blacklisted
                        184.183.180.98
                        221.164.212.118

                        Am 30.05.2014 23:54, schrieb lists@...:
                        > Am 30.05.2014 23:18, schrieb lists@...:
                        >>
                        >> Am 30.05.2014 22:48, schrieb Wietse Venema:
                        >>> lists@...:
                        >>>>> You also need to drop "secondary groups". On UNIX, that's
                        >>>>> done with setgroups() or initgroups(), before dropping
                        >>>>> root privileges
                        >>>>
                        >>>> thanks for the hint, looks not that it's supported
                        >>>> http://www.php.net/manual/en/book.posix.php
                        >>>
                        >>> It took me a few seconds to find that PHP has initgroups.
                        >>>
                        >>> site:php.net initgroups
                        >>
                        >> indeed - no excuse except blindness :-(
                        >> implemented - thanks!
                        >>
                        >> in the meantime i installed and configured the mysql-server
                        >> scary, my first from-scratch mysql-setup after 11 years
                        >>
                        >> most i likely wrote the code for insert/update (currently
                        >> untested) and also planned a 'dnsbl_auto' feature which is
                        >> set by the honeypot-service for auto-expires and remove
                        >> old entries will skip records where it is 0 to provide
                        >> a webinterface later to add blocked IP's manually
                        >
                        > well, some typos in column-names and script fixend
                        >
                        > it works, even before written the init-script the first manual start
                        > caught IP's connecting to a not as MTA anncounced machine which answers
                        > the question if it's worth the work and was not clear at start
                        >
                        > it took five seconds until 220.225.200.7 was caught
                      Your message has been successfully submitted and would be delivered to recipients shortly.