Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I’m exhausted. I just spent the last two hours chasing a goose that I have been after on-and-off for the past year. Here is the goal, put as succinctly as possible.

Step 1: HOSTS File:

127.0.0.5 NastyAdServer.com
127.0.0.5 xssServer.com
127.0.0.5 SQLInjector.com
127.0.0.5 PornAds.com
127.0.0.5 OtherBadSites.com
…

Step 2: Apache httpd.conf

<VirtualHost 127.0.0.5:80>
    ServerName BlackHole
    DocumentRoot "X:\Docs\…\BlackHole"
    RewriteEngine On
    RewriteRule (\.(gif|jpg|png|jpeg)$) /p.png [L]
    RewriteRule (.*) /ad.htm [L]
</VirtualHost>

So basically what happens is that the HOSTS file redirects designated domains to the localhost, but to a specific loopback IP address. Apache listens for any requests on this address and serves either a transparent pixel graphic, or else an empty HTML file. Thus, any page or graphic on any of the bad sites is replaced with nothing (in other words an ad/malware/porn/etc. blocker).


This works great as is (and has been for me for years now). The problem is that these bad things are no longer limited to just HTTP traffic. For example:

<script src="http://NastyAdServer.com:99">
or
<iframe src="https://PornAds.com/ad.html">
or a Trojan using
ftp://spammaster.com/id=goodaddr@foo.bar;myemail@baz.com;harvested@email.addr
or an app “phoning home” with private info in a crafted ICMP packet by pinging
CardStealer.ru:99

Handling HTTPS is a relatively minor bump. I can create a separate VirtualHost just like the one above, replacing port 80 with 443, and adding in SSL directives. This leaves the other ports to be dealt with.

I tried using * for the port, but then I get overlap errors. I tried redirecting all request to the HTTPS server and visa-versa but neither worked; either the SSL requests wouldn’t redirect correctly or else the HTTP requests gave the You’re speaking plain HTTP to an SSL-enabled server port… error. Further, I cannot figure out a way to test if other ports are being successfully redirected (I could try using a browser, but what about FTP, ICMP, etc.?)


I realize that I could just use a port-blocker (eg ProtoWall, PeerBlock, etc.), but there’s two issues with that. First, I am blocking domains with this method, not IP addresses, so to use a port-blocker, I would have to get each and every domain’s IP, and update theme frequently. Second, using this method, I can have Apache keep logs of all the ad/malware/spam/etc. requests for future analysis (my current BlackHole logs are already 466MB right now).

I appreciate any help in successfully setting up an Apache VirtualHost blackhole. Thanks.

share|improve this question
    
You must really hate ads. Out of curiosity, is this setup for use on your individual workstation, on a proxy server for an organization, or something else. –  tomjedrz May 8 '10 at 19:08
    
@tomjedrz, it’s not just for ads, but yes, yes I do. Besides, lots of security software adds various sites to the HOSTS file already, so I just made it more useful than just blocking it. –  Synetech May 9 '10 at 16:24
add comment

2 Answers

Interesting solution .. I like it! You should use an address other than localhost, however.

Bind another IP onto the NIC (or use a second NIC) on the box, and setup Apache to listen on that address, for whatever ports you want. Wildcard (*) should work. Then, the only traffic to that address is directed by the HOSTS file "spoof", and that traffic won't interfere with other (legit) services that may access localhost.

Also, you may choose to do this with DNS rather than with the HOSTS file. This is IMHO a better long term solution. Finally, the easiest solution is most likely to block traffic at your firewall to these domains.


UPDATE - based on comments. I suggest that you use TWO different IP addresses, one for HTTP and one for HTTPS. Have each one listen on all ports and direct traffic to the appropriate port. Then, when you add the domain for blocking to the HOSTS file, set it to the SSL/vanilla IP based on the the type of request that triggered the adding of the entry.

share|improve this answer
    
I am using a different address. For example, ServerName is BlackHole on IP 127.1.2.3 as opposed to localhost on 127.0.0.1. –  Synetech May 10 '10 at 10:55
    
Blocking via the firewall won’t work because just like port-blockers, it takes forever for a connection to time out. So for example, a page with ads won’t finish loading; the throbber continues to spin while the browser tries to connect to the bad domain. With this method however, Apache returns a page or picture, albeit empty, immediately (especially fast since its local), so the page not only loads quickly, but instead of having a 404 page in the iframe/etc., it has a blank (or whatever else I choose). Same goes for Trojans, etc. (at least in theory; I can only test web pages right now). –  Synetech May 10 '10 at 10:58
add comment

You could really simplify things by redirecting all of the ErrorDocument codes and wildcaard image types to the same blank pages/images as in the below. It tries to match a dead-on first, then allows the error document routunes as a fall-through. (you could do it all in error routines i suppose, but i think it's a mite slower, as an error routine?) At the end of your http.conf whatever, and on a SEPARATE ip address (use Listen 192.168.1.9:80 for example in my setup, which it on the 192.168.1 network, and the main server is on .10)

<VirtualHost 192.168.1.9:80>

ServerName adware
DocumentRoot /usr/local/httpsd/adware
CustomLog /dev/null common
ErrorLog /dev/null

<Directory "/usr/local/httpsd/adware">
AllowOverride none
Order allow,deny
Allow from all
</Directory>

AliasMatch /*.php /usr/local/httpsd/adware/no.html
AliasMatch /*.sql /usr/local/httpsd/adware/no.html
AliasMatch /*.html /usr/local/httpsd/adware/no.html
AliasMatch /*.htm /usr/local/httpsd/adware/no.html
AliasMatch /*.gif /usr/local/httpsd/adware/no.gif
AliasMatch /*.jpg /usr/local/httpsd/adware/no.jpg
AliasMatch /*.png /usr/local/httpsd/adware/no.png

ErrorDocument  400  /usr/local/httpsd/adware/no.html
ErrorDocument  401  /usr/local/httpsd/adware/no.html
ErrorDocument  403  /usr/local/httpsd/adware/no.html
ErrorDocument  404  /usr/local/httpsd/adware/no.html
ErrorDocument  405  /usr/local/httpsd/adware/no.html
ErrorDocument  414  /usr/local/httpsd/adware/no.html
ErrorDocument  500  /usr/local/httpsd/adware/no.html

</VirtualHost>

-works a treat for us. The no.html file is a Figlet text of:

 _______     __
|   _   |.--|  |.-----.
|       ||  _  ||__ --|__ __
|___|___||_____||_____|__|__|

And the images are all 1x1 respective empty images, colour palette of 2.

And I have the hosts file to bind converted ad-block site list in our main dns which catches it all on a network-level. So DHCP visitors, workers get the same courteous protection.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.