Search code examples
perlproxywhoishigh-load

How can I implement a simple WHOIS proxy in Perl?


I have several WHOIS servers for which I want to have a single proxy. The proxy should forward requests to appropriate servers based on the data in the query. How to approach this problem?


Solution

  • Step 1 read the RFC for WHOIS
    Step 2 implement a mock server with Net::Server
    Step 3 implement the proxy using your mock server and Net::Whois::Proxy or some other WHOIS module

    A quick scan of the RFC seems to say that it is just a simple text based protocol that expects one CRLF terminated line and then sends a blob of CRLF terminate lines and closes the socket.

    Yep, it really looks that simple, given this code

    #!/usr/bin/perl
    
    {
        package Whois;
        use strict;
        use warnings;
    
        use parent 'Net::Server';
    
        sub process_request {
            my $request = <>;
            print "you sent me $request";
        }
    
    }
    
    Whois->run;
    

    you can say

    whois -h localhost -p 20203 foo.com
    

    and get back

    you sent me foo.com
    

    Given the "high-load" tag, you will probably want to switch over to Net::Server::PreForkSimple personality when you are done with testing.

    And just because I was bored:

    #!/usr/bin/perl
    
    package Whois {
        use strict;
        use warnings;
    
        use parent 'Net::Server::PreFork';
    
        use Net::Whois::Raw;
    
        my %handler = (
            org => "whois.publicinterestregistry.net",
        );
    
        sub process_request {
            (my $request = <>) =~ s/[.]([^.]+)\x{0d}\x{0a}/.$1/;
    
            print exists $handler{$1} ?
                whois $request, $handler{$1} :
                "I don't know where to look for $request\r\n";
        }
    
    }
    
    Whois->run(
        user              => "nobody",
        group             => "nobody",
        port              => 43,
        min_servers       => 1,      #min number of children
        max_servers       => 10,     #max number of children
        min_spare_servers => 1,      #fork if we don't have this many waiting
        max_spare_servers => 5,      #kill if we have this many waiting
        max_requests      => 10_000, #num of requests before killing a child    
    );
    

    which when I run

    sudo perl whois.pl
    

    and then

    whois -h localhost foo.org
    

    gives us

    NOTICE: Access to .ORG WHOIS information is provided to assist persons in
    determining the contents of a domain name registration record in the Public Interest Registry
    registry database. The data in this record is provided by Public Interest Registry
    for informational purposes only, and Public Interest Registry does not guarantee its
    accuracy.  This service is intended only for query-based access.  You agree
    that you will use this data only for lawful purposes and that, under no
    circumstances will you use this data to: (a) allow, enable, or otherwise
    support the transmission by e-mail, telephone, or facsimile of mass
    unsolicited, commercial advertising or solicitations to entities other than
    the data recipient's own existing customers; or (b) enable high volume,
    automated, electronic processes that send queries or data to the systems of
    Registry Operator or any ICANN-Accredited Registrar, except as reasonably
    necessary to register domain names or modify existing registrations.  All
    rights reserved. Public Interest Registry reserves the right to modify these terms at any
    time. By submitting this query, you agree to abide by this policy.
    
    Domain ID:D1608104-LROR
    Domain Name:FOO.ORG
    Created On:10-Jan-1995 05:00:00 UTC
    Last Updated On:07-Mar-2011 00:26:43 UTC
    Expiration Date:09-Jan-2012 05:00:00 UTC
    Sponsoring Registrar:Fabulous.com Pty Ltd. (R133-LROR)
    Status:CLIENT DELETE PROHIBITED
    Status:CLIENT TRANSFER PROHIBITED
    Registrant ID:fabwpp-000700385
    Registrant Name:Domain Hostmaster, CustomerID : 85519846801225
    Registrant Organization:Whois Privacy Services Pty Ltd
    Registrant Street1:PO Box 923
    Registrant Street2:
    Registrant Street3:
    Registrant City:Fortitude Valley
    Registrant State/Province:QLD
    Registrant Postal Code:4006
    Registrant Country:AU
    Registrant Phone:+61.730070090
    Registrant Phone Ext.:
    Registrant FAX:+61.730070091
    Registrant FAX Ext.:
    Registrant Email:[email protected]
    Admin ID:fabwpp-000700385
    Admin Name:Domain Hostmaster, CustomerID : 85519846801225
    Admin Organization:Whois Privacy Services Pty Ltd
    Admin Street1:PO Box 923
    Admin Street2:
    Admin Street3:
    Admin City:Fortitude Valley
    Admin State/Province:QLD
    Admin Postal Code:4006
    Admin Country:AU
    Admin Phone:+61.730070090
    Admin Phone Ext.:
    Admin FAX:+61.730070091
    Admin FAX Ext.:
    Admin Email:[email protected]
    Tech ID:fabwpp-000700385
    Tech Name:Domain Hostmaster, CustomerID : 85519846801225
    Tech Organization:Whois Privacy Services Pty Ltd
    Tech Street1:PO Box 923
    Tech Street2:
    Tech Street3:
    Tech City:Fortitude Valley
    Tech State/Province:QLD
    Tech Postal Code:4006
    Tech Country:AU
    Tech Phone:+61.730070090
    Tech Phone Ext.:
    Tech FAX:+61.730070091
    Tech FAX Ext.:
    Tech Email:[email protected]
    Name Server:NS1.HITFARM.COM
    Name Server:NS2.HITFARM.COM
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    Name Server:
    DNSSEC:Unsigned
    
    
    whois.publicinterestregistry.net