Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Discriminating between local and remote IP's

by Avitar (Acolyte)
on Oct 04, 2004 at 18:15 UTC ( [id://396313] : perlquestion . print w/replies, xml ) Need Help??

Avitar has asked for the wisdom of the Perl Monks concerning the following question:

I have a local intranet that will not require an extensive logon, but if you are accessing it via the internet, it will require a more though logon proceder as per my bosses request. The Intranet server also has a direct connection to the internet so the box has a public and private IP. Which makes matters worse is that it is also a NAT box with DNS and DHCP in it for the local intranet. The intranet hosted via an Apache server on this box.

I know how to get IP's but i need to know how to determine if the range is on the local network, or accross the web.

For instance: Say the range of my LAN is 192.168.0/24 ... There is also a internet ip of 192.168.0.1 which would have reduced security on it.

What would be an abstract way of telling these two apart?

I was considering getting the remote MAC addresses and storing them in a database that would be cross referenced with the users IP, but that would require setting up another machine maybe to run the script, and would require manual intervention every setup.

Is there a way to force perl to look at the NIC it is using to talk to the client? I am sure this has been done somewhere in cpan, just having problems with the best approach to solve the problem.

  • Comment on Discriminating between local and remote IP's

Replies are listed 'Best First'.
Re: Discriminating between local and remote IP's
by amt (Monk) on Oct 04, 2004 at 18:29 UTC
    avitar, the address space of 192.168.0.0/16 is considered reserved address space, as well as 172.16.0.0/12 and 10.0.0.0/8 by the IANA, according to this intarweb page. Addresses that are inside this range, can be considered private, and you could reduce the need to cumbersome log in computation.

    The Net-CIDR module has functions that can check an IP address to see if it belongs to an address range, so use the remote host environmental variable with this function.

    amt.

    perlcheat
      That was only an exaple range. I realize that they are supposidly private ranges, however they will sometimes resolve, or are spoofed.

      For instance I run a trace route on 10.0.0.1 and i get something such as:


      1 15 ms 15 ms 15 ms 66.13.200.101
      2 15 ms 16 ms 15 ms 4.24.46.181
      3 15 ms 15 ms 16 ms 10.0.0.1


      Athough these are trusted servers for the most part, I do not want to give IANA any escalated privledges. Pranoid? maybe... but better safe than sorry.

      For this reason I wanted to have the server check to see if the request was received via the local area NIC or the NIC with the internet connection.
        I would never trust any IP address in the private ranges. You might have someone elses network

        You are assuming that the server has two NICs, one on a private LAN, and another on the Internet connections. This is a rare configuration. Also, it is fairly hard to determine which interface the connection came from. You can look at the incoming IP address. It isn't that reliable for scurity.

        It is better to look at the remote IP address. This can be spoofed and isn't very good security. But if you are looking at the IP address for trust, you aren't interested in good security.

        The situation I am picturing is an internet sharing situation where you have machines on a wire to the machine with two NICs. One NIC is for the ether, and the other is for the internet. Using Net::CIDR and to test if it is contained on one of these networks should still work. When you are tracerouting to 10.0.0.1, you could be going out of the Internet NIC, as the lowest eth* will be chosen if not specified, so keep that in consideration.
        If the situation is what i think it is, then those machine have one NIC and are on an internal network, that the box in question is directly connected to, so they have no choice but to be on the same network.
        amt.

        perlcheat
        For this reason I wanted to have the server check to see if the request was received via the local area NIC or the NIC with the internet connection.

        Can't be done using perl. The best you can do is look at the IPs.

        I suggest creating a whitelist of all the "trusted" IPs as a bunch of CIDR blocks (using Net::CIDR as someone else suggested), then checking connections against that.

Re: Discriminating between local and remote IP's (Apache ACLs)
by grinder (Bishop) on Oct 04, 2004 at 21:05 UTC
    I have a local intranet that will not require an extensive logon, but if you are accessing it via the internet, it will require a more though logon proceder as per my bosses request.

    This isn't really answering your question, but I can't help wondering if Perl is the right place to be solving this problem. When you talk of an intranet, I assume you are talking about a web server. If you are talking about a web server, chances are good you're talking about Apache.

    In this case, you just want to set your server up so that it's unauthenticated for local addresses, but authenticated for everyone else. Other web servers offer similar functionality

    <Location /foo> Order deny,allow Satisfy any AuthType Basic AuthName $realm AuthGroupFile /usr/local/www/auth/groups AuthUserFile /usr/local/www/auth/users Allow from 192.168.0.0/24 Require valid-user # or whatever, e.g. require group foo Deny from all </Location>

    Apache plug-ins exist to let you authenticate against an LDAP server, or a database or other such repositories.

    In other words, let Apache worry about authentication, because it's good at doing that; this will simplify your Perl code.

    - another intruder with the mooring of the heat of the Perl

      I was wondering if you could do in through Apache by <Listen>ing on both the external and internal IP then set up a virtual host for each ip address. Add Apache auth to the external host.
      Listen xxx.xxx.xxx.xxx:80 Listen 192.168.xxx.xxx:80 <VirtualHost xxx.xxx.xxx.xxx:80> <Location /> AuthType Basic ... </Location> </VirtualHost> <VirtualHost 192.168.xxx.xxx:80> <Location /> #AuthType Basic ... </Location> </VirtualHost>
      (untested and refers to Apache 2.0)
        Using virtual hosts to bypass authentication is not really a good idea as it solely relies on the assumption that someone outside won't know the internal vhost name. And as (AFAIK) this only needs to be send in the HTTP header it would make it very easy to manipulate (an attacker would only have to change his hosts file).
        Update: Silly me, above example isn't about name-based vhosts...
Re: Discriminating between local and remote IP's
by Golo (Friar) on Oct 05, 2004 at 13:12 UTC
    Which makes matters worse is that it is also a NAT box with DNS and DHCP in it for the local intranet.
    You could use this to your advantage. Make use of DDNS (dynamically assigning DNS records to DHCP clients) and then do a reverse lookup on the IP to check if it is in your private domain space.
Re: Discriminating between local and remote IP's
by zentara (Archbishop) on Oct 05, 2004 at 14:03 UTC
    I am brainstorming here, but wouldn't it be foolproof to get the remoteip, by whatever means you have, then do a "route" to it, and if the results from route show anything other than your boxes or routers, then it's a "remote address"?

    I'm not really a human, but I play one on earth. flash japh