DNS Blacklist lookups PHP Tutorial
- Author:
- Date:2016/07/30
If you’re hosting a website which has any sort of posting system (ie- forums, comments, etc..) then you are likely to receive a lot of spam if you leave yourself open to it. One simple way to stop spam in it’s tracks is to simply check visitors IP addresses against a DNSBL (DNS Blacklist).
Before you begin it’s important to understand how a DNSBL works. Let’s say you wanted to check if the IP address
is in a DNSBL (it is by the way), I’ll use 1
1.2.3.4
as an example. First you would need to put the octets of the IP address into reverse order (4.3.2.1) and then append the DNSBL address to it separated by a period. This will look like 1
dnsbl-1.uceprotect.net
. If you do a DNS lookup on this hostname and it returns a result, usually a localhost IP, then it’s blacklisted. Let’s see how this looks in command line:1
4.3.2.1.dnsbl-1.uceprotect.net
C:\>nslookup 4.3.2.1.dnsbl-1.uceprotect.net Server: google-public-dns-a.google.com Address: 8.8.8.8 Non-authoritative answer: Name: 4.3.2.1.dnsbl-1.uceprotect.net Address: 127.0.0.2
dig 4.3.2.1.dnsbl-1.uceprotect.net ; <<>> DiG 9.10.3-P3 <<>> 4.3.2.1.dnsbl-1.uceprotect.net ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28677 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;4.3.2.1.dnsbl-1.uceprotect.net. IN A ;; ANSWER SECTION: 4.3.2.1.dnsbl-1.uceprotect.net. 2099 IN A 127.0.0.2 ;; Query time: 89 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Fri Jul 29 17:02:00 CDT 2016 ;; MSG SIZE rcvd: 75
Now that you understand how a DNS Blacklist check works, and know the expected output, it’s time to do it in PHP. This is fairly simple. First you need to take a given IP and reverse the octets. I do this by turning the IP address into an array then reverse it and implode…
$array = explode( ".", "1.2.3.4" ); $array = array_reverse( $array ); $reverse_ip = implode( ".", $array ); /* $reverse_ip is 4.3.2.1 */
Next you need to use gethostbyname() to find out if the IP is blacklisted. If the IP address is in the DNS blacklist it will return the hostname (ip+blacklist address) instead of an IP address, so we check for that instead of checking the actual record.
$res = gethostbyname( $reverse_ip.".".$dnsbl ); if( $res == $reverse_ip.".".$dnsbl ) { /* IP is not in given DNSBL */ return false; }
If this check fails then the IP is blacklisted. The full script below includes the check function and usage.
<?php function dnsbl_check( $ip_address = NULL, $dnsbl = NULL ) { if( $ip_address == NULL ) { /* No IP address given */ return false; } if( filter_var($ip_address, FILTER_VALIDATE_IP) === false ) { /* IP address is invalid */ return false; } if( $dnsbl == NULL ) { /* No DNSBL to check against */ return false; } /* Need to reverse the IP address */ $array = explode( ".", $ip_address ); $array = array_reverse( $array ); $reverse_ip = implode( ".", $array ); /* Perform the check */ $res = gethostbyname( $reverse_ip.".".$dnsbl ); if( $res == $reverse_ip.".".$dnsbl ) { /* IP is not in given DNSBL */ return false; } /* No checks failed, hostname does not match request, IP is in DNSBL */ return true; } if( dnsbl_check( "1.2.3.4", "dnsbl-1.uceprotect.net" ) == true ) { echo "IP failed DNSBL check"; } else { echo "IP passed DNSBL check"; } ?>
If you noticed any thing wrong, or have questions/comments/concerns please leave a comment below. 🙂