HTTP Blacklist - Http:BL PHP Code - Generic

This is a generic PHP script that can be used with Http:BL. Http:BL can be used to block requests to a web site based on the IP address. There are several configuration settings that allow you to adjust the performance. In the code below, any IP address identified as suspicious by Project Honey Pot, active within the past 30 days, or with a threat score 100 or greater is blocked.

The easiest way to use it is to include it into the top level of the application, for example:

require_once 'bl.php';

This code just logs the requests and the scores. Once you’re comfortable with it, you can use it to redirect unwanted visitors to a 403 page, or down the rabbit hole.


<?php
/*
abcdefghijkl.2.1.9.127.dnsbl.httpbl.org

Response:
Octet 1: 127 or indicates error
Octet 2: # of days since last activity
Octet 3: Threat score (0=No threat, 255=Extreme threat)
Octet 4: Visitor type
*/

define ('httpBL_API_key','!-- YOUR KEY HERE --!');
define ('httpBL_URL','dnsbl.httpbl.org');
 
/* These are the settings which control which visitors are blocked */
define ('DAYS_SINCE_LAST_ACTIVITY',30);  /* Active within this many days prior will be blocked */
define ('MAX_THREAT_SCORE',100);         /* Anything over this threat score will be blocked */
define ('MAX_TYPE_VALUE',1);             /* Type of visitor - this isn't really bitmapped */
define ('VISITOR_MAP',3);
 
$aOctetMap=array(
'127'=>0,
'DAYS_SINCE_LAST_ACTIVITY'=>1,
'MAX_THREAT_SCORE'=>2,
'VISITOR_MAP'=>3
);
 
$aVisitorType=array(
0=>'Search Engine',
1=>'Suspicious',
2=>'Harvester',
4=>'Comment Spammer',
8=>'[Reserved for Future Use]',
16=>'[Reserved for Future Use]',
32=>'[Reserved for Future Use]',
64=>'[Reserved for Future Use]',
128=>'[Reserved for Future Use]'
);
         
$aSearchEngineSerials=array(
0=>'Undocumented',
1=>'AltaVista',
2=>'Ask',
3=>'Baidu',
4=>'Excite',
5=>'Google',
6=>'Looksmart',
7=>'Lycos',
8=>'MSN',
9=>'Yahoo',
10=>'Cuil',
11=>'InfoSeek',
12=>'Miscellaneous'
);
$sBL=httpBL($_SERVER['REMOTE_ADDR']);
if ($sBL!==null) 
        /* Write out the information to a text file so you can see what is happening */
        file_put_contents('output.txt',$_SERVER['REMOTE_ADDR'].' '.$sBL.PHP_EOL,FILE_APPEND);
        /* Once you are comfortable with your code and settings, you can redirect unwanted visitors elsewhere */
         
function httpBL($sIP)
{
        global $aOctetMap;

        $sOctets=implode('.',array_reverse(explode('.',$sIP)));
        $sURL=httpBL_API_key.'.'.$sOctets.'.'.httpBL_URL;
        $aResult=dns_get_record($sURL,DNS_A);
        if (isset($aResult[0]) && isset($aResult[0]['ip']))
        {
                $aResultOctet=explode('.',$sResult=$aResult[0]['ip']);
                if ((int)$aResultOctet[$aOctetMap['VISITOR_MAP']]<MAX_TYPE_VALUE) return null;
                if ((int)$aResultOctet[$aOctetMap['MAX_THREAT_SCORE']]>=MAX_THREAT_SCORE) return $sResult;
                if ((int)$aResultOctet[$aOctetMap['DAYS_SINCE_LAST_ACTIVITY']]<=DAYS_SINCE_LAST_ACTIVITY) return $sResult;
        }
        return null;
}

The advantage of this approach is that after an IP address has been cleared or cleaned up, access is restored without admin action, so blocked addresses aren’t blocked forever, only for a month or so while they are potentially harmful. The .htaccess Allow,Deny configuration can also be used, but it must be manually maintained, by checking the stats frequently and determining the owner and extent of the IP address block.

eZ publish - Disable ezinfo with .htaccess

The ezinfo module exposes the version number and other key information about an eZ publish installation.

It can be disabled through the eZ publish settings by adding these lines to override/site.ini.append.php:

[SiteAccessRules]
Rules[]=access;disable
Rules[]=module;ezinfo

An additional level of protection can be achieved using a RewriteRule, like so:

RewriteRule ^ezinfo.* http://domain.com/ [L]

In this case, requests for ezinfo will redirect to the home page, in effect they will appear to be ignored.

Other endpoints which may be used:

  • A server level 403 (access denied) or 404 (page not found) page. If this is the only page that gets these errors, people will still know it is an eZ site.
  • The ‘Error kernel (20)’ page, if it has been customized to act as a 404 page. Ending on this page, without customizing it doesn’t achieve much, since people familiar with eZ will be able to identify it as an eZ system by the message text.
  • A redirect off the server, strictly to frustrate the requester.
  • A bogus page with false information, which may be helpful in identifying harvesters.

Adding a jQuery MP3 Player in to eZ publish

I’ve been wanting to add a cross-browser audio player into a site for a while and I finally found a few minutes to find a solution and apply it.

A quick Google found the link above, which includes good demos and examples.

Files:

http://www.sean-o.com/files/singlemp3player.zip
http://www.sean-o.com/jquery/jmp3/jquery.jmp3.js

Download the files and place them in the design/site/javascript/mp3 directory, where site is the name of the siteaccess. Unzip the zip file.

Edit jquery.jmp3.js and ensure the path names match. The site will probably have to change.


var playerpath = "/design/site/javascript/mp3/";  

Update design.ini.append.php to add the jQuery MP3 code in.

settings/siteaccess/site/design.ini.append.php

[JavaScriptSettings]
JavaScriptList[]=mp3/jquery.jmp3.js

I updated design/site/override/templates/page_layout.tpl to use jQuery from the jQuery CDN.


<script type="text/javascript" src="http://code.jquery.com/jquery-1.5.1.min.js"></script>

I also added the player load code directly into page_layout.tpl, since it was compact. A better approach is probably to add it in as a footer script using the admin interface.

<script type="text/javascript">
$(document).ready(function(){
$(".mp3").jmp3({
/*backcolor: "000000",
forecolor: "22ff22",*/
width: 400,
showdownload: "false",
showfilename: "false"
});
});
</script>

Finally, I override the line/file template, testing to see if the filename ended in .mp3. If the file is an .mp3, the player code is added. In hindsight, a more graceful solution would be to create a custom class for .mp3s, but this works fine.

design/site/override/templates/line_file.tpl

{def $attr=$node.data_map.file}
        {def $fileurl=concat( 'content/download/', $attr.contentobject_id, '/', $attr.id,'/version/', $attr.version , '/file/', $attr.content.original_filename|urlencode )}
        {if $fileurl|ends_with('.mp3')}<span class="mp3">{$fileurl|ezurl('no','full')}</span>{/if}
        {undef $attr}{undef $fileurl}

Many thanks to ’sean-o’ - see the link above.

I tested it on Windows and CentOS, with FireFox 3+, it works really nicely.

As a side note, while working on this, I needed to add the http:// to the URL, and it could not be encapsulated in double quotes, since the name is not assigned in an href or src attribute. eZ has two nice optional parameters for the ezurl function, the first indicating what type of quotes to use (in this case none), and whether to create a full URL or relative (in this case full).

Label with Every Font - ImageMagick

The goal of this adventure was to find the font that looked the best on a Massachusetts license plate, using ImageMagick.

I got the list of fonts using -list type fonts. This was run on two servers with different versions of ImageMagick, so there are two different ways to get the font list. Pick the one that works for you, or make your own.

The license plate blank came from R.T’s Blank Plates.

# This isn't worth automating, you will need to edit the font_list to strip out extra lines
#convert -list type fonts | cut -f1 -d ' ' | sort | uniq > font_list
# If the above won't work, try the next line
#convert -list font | grep 'Font:' | cut -f 2 -d ':' | tr -d ' ' > font_list
for f in $(cat font_list); do
echo $f
convert  ma1987.jpg -compose srcOver -gravity center \( -background transparent -fill "#7c2128" -strokewidth 1 -stroke "#777777" -font "$f" -pointsize "72" label:TAGLNZ -resize 230x -trim -sharpen 0x1.0 \) +composite MA-$f.png
done

This is one of the 270+ images that were created:

MA - Helvetica-Narrow

This is a good example of centering a label. The command line begins with the convert command, followed by the blank plate. ‘compose srcOver’ and ‘gravity center’ position the image labeled in parenthesis over the plate, and ‘+composite’ assembles the image.

Many thanks to the ImageMagick examples.

You can create your own license plate avatar at taglinez.com.

Quick Sprite Builder

Sprites allow you to combine many images into a single file, reducing both the number of requests and bandwidth required to deliver pages.

I had 51 images, each was about 10K, so the total was about 510K.

These images had dimensions of about 250px width and 125px height.

I wanted to combine them all into a single image, and generate the CSS to compute the offsets into the sprite.


#!/bin/bash

# Remove the prior appended image
rm appended.jpg

# Create a list of all the original jpg files
ls *.jpg > jpg_files

# Resize all the images to ensure they have the same height and width
for f in $(cat jpg_files); do
        convert "$f" -resize 250x125! +repage "$f";
done

# Break the list into rows of 10 images
split -l 10 jpg_files jpg_row.

# Generate the ImageMagick command to append the images into rows 
c=convert
for f in $(ls jpg_row.*); do 
        h=`cat "$f" | tr '\n' ' '`
        c="$c"' ( '"$h"' +append ) '
done
# Combine the rows into the appended image, reduce the quality to save space
c="$c"' -background transparent -append -quality 70  appended.jpg'
`$c`

echo '.tag{height:125px;width:250px;overflow:hidden;background-color:transparent;background-image:url("appended.jpg");}' > ap.css

# Generate the CSS
r=0
for f in $(ls jpg_row.*); do 
        c=0
        for g in $(cut -f 1 -d '.' "$f"); do
                echo ."$g"'{background-position:-'$((c*250))'px -'$((r*125))'px;}' >> ap.css
                c=$((c+1))
        done
        r=$((r+1))
done

The final image was about 260K, still large, but the quality is good. Compressed for transfer, this image will serve well.

This code isn’t generalized, if you would like to use it, you’ll need to adjust the image dimensions and the number used to calculate the offsets.