Since I'm paranoid, I don't want Mon to accept client connections from
hosts other than those I specifically allow in advance.  So I wrote
a patch (for mon 0.99.2, but it should work on older versions)
that adds access control for Mon clients by IP address by adding the
"serverallow" parameter to mon.cf.  The description follows, and the
patch is attached.

  -- Ed
  
----------------------------------

  serverallow = IPpattern [...]

serverallow controls which IP addresses are allowed to connect
to the server port.  Each IPpattern is a slightly restricted Perl
regular expression that will match the IP number of an intended client.
The restrictions are:

* When evaluated, the regex will be anchored on both sides
(i.e. ^IPpattern$) so it must match the entire IP address.

* Periods in the regexp will be evaluated as literals, by converting
them  to "\." before evaluation.  This is to avoid ambiguity
in the regular expressions, since period normally matches
any character.  If the period is bracketed (i.e. "[.]") or already
escaped with a backslash, it will not be converted.

The default value of serverallow (\d+.\d+.\d+.\d+) will allow
all hosts to connect.

Some examples:

  # only allow localhost to connect
  serverallow = 127.0.0.1

  # only allow a single class C
  serverallow = 192.168.1.\d+

  # allow a single class B, localhost, and these three specific
  # hosts: 192.168.3.1, 192.168.3.18, and 192.168.3.34
  serverallow = 10.0.\d+.\d+ 127.0.0.1 192.168.3.(1|18|34)

--- mon 2001/11/17 01:59:40     1.3
+++ mon 2002/01/03 00:26:07
@@ -874,7 +874,8 @@
 
            } elsif ($1 eq "serverbind") {
                $new_CF{"SERVERBIND"} = $2;
-
+            } elsif ($1 eq "serverallow") {
+               $new_CF{"SERVERALLOW"}= $2;
            } elsif ($1 eq "trapbind") {
                $new_CF{"TRAPBIND"} = $2;
 
@@ -1764,8 +1765,24 @@
     }
 
     ($port, $addr) = unpack_sockaddr_in ($sock);
-    syslog ('info', "client connection from " . inet_ntoa ($addr) .
-           ":" . $port);
+    my $clientip= inet_ntoa($addr);
+   
+    syslog ('info', "client connection from $clientip:$port");
+
+    my @clientregex= split(' ', $CF{"SERVERALLOW"});
+    my $ipok= 0;
+    foreach my $ippattern (@clientregex)
+    {
+        # change all periods, except those preceded by [ or \, into \.
+        $ippattern=~ s/([^[\\])\./$1\\./g;
+        if ($clientip =~ /^${ippattern}$/) {$ipok= 1; last};
+    }
+    if (! $ipok)
+    {
+        syslog('notice', "closing unwanted client: $clientip");
+       close($CLIENT);
+       return;
+    }
 
     select ($CLIENT);
     $|=1;
@@ -4333,6 +4350,7 @@
     $CF{"CLIENT_TIMEOUT"} = 30;
     $CF{"SERVPORT"}  = getservbyname ("mon", "tcp") || 2583;
     $CF{"TRAPPORT"}  = getservbyname ("mon", "udp") || 2583;
+    $CF{"SERVERALLOW"} = '\d+.\d+.\d+.\d+';
     $CF{"MAXPROCS"}  = 0;
     $CF{"SNMP"} = 0;
     $CF{"SNMPPORT"} = 34000;

Reply via email to