LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

[patch] Re: ldirectord and DNS

To: lvs-users@xxxxxxxxxxxxxxxxxxxxxx
Subject: [patch] Re: ldirectord and DNS
From: Tim Hasson <tim@xxxxxxxxxxxxxxx>
Date: Tue, 27 Jan 2004 23:32:53 -0800
Hi,

The attached patch gets around the problem with ldirectord not doing any udp 
checks, by using Net::DNS to test if the DNS server is resolving.

You cannot simply just do a udp connect check, as udp is connectionless :)
That is why ldirectord will always keep all real servers on any udp service, 
regardless of the service status.

So, you just basically install Net::DNS from cpan, and apply the attached 
patch to /usr/sbin/ldirectord

You can change www.test.com in the patch or in ldirectord after you applied 
the patch if you need to specify an internal domain or something else.

The patch applied to several ldirectord versions cleanly, including the latest 
from ultramonkey heartbeat-ldirectord-1.0.4.rpm (I believe it was ldirectord 
1.76)


Respectfully,
Tim Hasson


Quoting Joseph Mack <mack.joseph@xxxxxxx>:

> Tim Hasson wrote:
> 
> > It's possible. But I already use ssh w/ rsa for other administration
> purposes,
> > so I don't want to stress out sshd on the real servers. I wouldn't trust
> rsh
> > for security.
> 
> I have a similar problem. I have ssh for admin with a passphrase coming in
> on
> a separate NIC. I also need scripts to run remotely for failover and
> currently 
> I'm using rsh under xinetd with hosts.allow|deny. It seems crazy with all the
> 
> effort I've put into making the machines bullet proof otherwise, but I can't
> 
> think of any other solution. Let me know if you come up with anything
> better.
> 
> > So does this mean that ldirectord UDP checks don't work? Or is it just not
> > designed to handle UDP services?
> 
> don't know anything about ldirectord, bopefully someone else will know
> 
> Joe
> 
> -- 
> Joseph Mack PhD, High Performance Computing & Scientific Visualization
> SAIC, Supporting the EPA Research Triangle Park, NC 919-541-0007
> Federal Contact - John B. Smith 919-541-1087 - smith.johnb@xxxxxxx
> _______________________________________________
> LinuxVirtualServer.org mailing list - lvs-users@xxxxxxxxxxxxxxxxxxxxxx
> Send requests to lvs-users-request@xxxxxxxxxxxxxxxxxxxxxx
> or go to http://www.in-addr.de/mailman/listinfo/lvs-users
> 




--- ldirectord  2003-08-06 01:13:02.000000000 -0700
+++ ldirectord  2004-01-20 17:09:29.000000000 -0800
@@ -202,7 +202,7 @@
 means no checking will take place and no real or fallback servers will be
 activated. Default is I<negotiate>.
 
-B<service = 
ftp>|B<smtp>|B<http>|B<pop>|B<nntp>|B<imap>|B<ldap>|B<https>|B<none>
+B<service = 
ftp>|B<smtp>|B<http>|B<pop>|B<nntp>|B<imap>|B<ldap>|B<https>|B<dns>|B<none>
 
 The type of service to monitor when using checktype=negotiate. None denotes
 a service that will not be monitored. If the port specfied for the virtual
@@ -609,6 +609,9 @@
                        if ($ip_port) {
                                $vsrv{checktype} = "negotiate";
                                $vsrv{protocol} = "tcp";
+                               if ($ip_port =~ /:53/) {
+                                       $vsrv{protocol} = "udp";
+                               }
                        } else {
                                $vsrv{fwm} = $fwm;
                                $vsrv{checktype} = "negotiate";
@@ -715,8 +718,8 @@
                                } elsif ($rcmd =~ /^service\s*=\s*(.*)/) {
                                        lc($1);
                                        $1 =~ /(\w+)/ && ($1 eq "http" || $1 
eq "https" || $1 eq "ldap"
-                                           || $1 eq "ftp" || $1 eq "none" || 
$1 eq "smtp" || $1 eq "pop" || $1 eq "imap" || $1 eq "nntp")
-                                           or &config_error($line, "service 
must be http, https, ftp, smtp, pop, imap, ldap, nntp or none");
+                                           || $1 eq "ftp" || $1 eq "none" || 
$1 eq "smtp" || $1 eq "pop" || $1 eq "imap" || $1 eq "nntp" || $1 eq "dns")
+                                           or &config_error($line, "service 
must be http, https, ftp, smtp, pop, imap, ldap, nntp, dns or none");
                                        $vsrv{service} = $1;
                                        if($vsrv{service} eq "ftp" and 
                                                        $vsrv{login} eq "") {
@@ -882,6 +885,9 @@
                        } 
                        elsif ($vsrv->{port} eq "389") {
                                $vsrv->{service} = "ldap";
+                       }
+                       elsif ($vsrv->{port} eq "53") {
+                               $vsrv->{service} = "dns";
                        } 
                        else {
                                $vsrv->{service} = "none";
@@ -1454,6 +1460,8 @@
                                                $$r{num_connects} = 0 if 
(check_ldap($v, $r));
                                        } elsif ($$v{service} eq "nntp") {
                                                $$r{num_connects} = 0 if 
(check_nntp($v, $r));
+                                       } elsif ($$v{service} eq "dns") {
+                                               $$r{num_connects} = 0 if 
(check_dns($v, $r));
                                        } else {
                                                $$r{num_connects} = 0 if 
(check_none($v, $r));
                                        }
@@ -1796,6 +1804,42 @@
 }
 
 
+sub check_dns
+{
+       my $res;
+       my $query;
+       my $rr;
+       my ($v,$r) = @_;
+       use Net::DNS;
+       $res = new Net::DNS::Resolver;
+
+       eval {
+               local $SIG{'__DIE__'} = "DEFAULT";
+               local $SIG{'ALRM'} = sub { die "timeout\n"; };
+               alarm($$v{checktimeout});
+               $res->nameservers($$r{server});
+               $query = $res->search("www.test.com"); ## my test domain...
+               alarm(0);
+       };
+ 
+       if (@$ eq "timeout\n") {
+               service_set($v,$r,"down");
+               return 0;
+       }
+ 
+       if ($query) {
+               foreach $rr ($query->answer) {
+                       next unless $rr->type eq "A";
+                       service_set($v,$r,"up");
+                       return 1;
+               }
+       }
+ 
+       service_set($v,$r,"down");
+       return 0;
+}
+
+
 # check_none
 # Dummy function to check service if service type is none.
 # Just activates the real server

<Prev in Thread] Current Thread [Next in Thread>