If you use a CGI to determine $ENV{'REMOTE_HOST'} make sure you're not using a proxy cache, either by configuring your script to do so or by being routed through one transparently.
Some proxy servers send an X-Forwarded-For HTTP header, which you can retrieve using $ENV{'HTTP_X_FORWARDED_FOR'}, but the address contained within this variable may not be publicly accessible and is not guaranteed to be correct.
It might be worth checking both these values, also checking for RFC 1918 IP addresses as a failsafe mechanism.
This might be overkill, depending on your situation, but it's worth noting that the CGI approach isn't foolproof either.
Also, you can't tell if anyone else is calling your CGI - you're relying on security through obscurity to ensure nobody else accesses your script.
| [reply] |
A more adaptable approach might be to rewrite
this as a client-server application, though there is the risk
of creeping-featurism if this is not handled carefully.
Essentially, if you can store a "secret key" on both the
client and the server in a pseudo-secure manner (i.e.
both machines are trusted, or trusted enough), you can
use a simple MD5-style hash to authenticate with a
challenge-response system. The MD5 "secret key" is really
just some stuff you made up, like a whole pile of random
letters.
The "server" part is a CGI program that asks a "question",
presenting a series of random characters that are to be
encrypted by the remote client. The "client" is the program
that uses LWP to access the server. It downloads the
question ($response->content()), encrypts it with the key,
and sends it back for verification. If the crypt() passes
the muster, the server records the address that the request
originated from, plus any other data you might have sent
with it (i.e. your "real" address, should it be different,
or what have you).
If you're feeling extra lazy, you can use LWP::Simple
instead of going whole hog. Also, forget sending HTML
back and forth, just use HTTP to mule your data raw.
Client/server package is probably only about 20 lines of
code, when you get right down to it.
| [reply] |