{"id":170,"date":"2012-01-07T16:07:29","date_gmt":"2012-01-08T00:07:29","guid":{"rendered":"http:\/\/dan.minear.name\/wordpress\/?p=170"},"modified":"2016-12-29T23:35:00","modified_gmt":"2016-12-30T07:35:00","slug":"using-modperl-to-keep-zencart-and-phpbb2-hackers-away","status":"publish","type":"post","link":"http:\/\/dan.minear.name\/wordpress\/?p=170","title":{"rendered":"Using ModPerl to Keep Zencart and phpBB2 Hackers Away"},"content":{"rendered":"<p>I&#8217;ve seen a bunch of attempts to hack at my <a title=\"Scrappin' Twins Store\" href=\"http:\/\/www.scrappintwins.com\/zencart\" target=\"_blank\">zencart<\/a> admin area and an old phpBB2 install that is no longer there. Both of these don&#8217;t work, and just return a 404 error, but it&#8217;s kind of annoying to keep spending compute cycles on this sort of behavior. Besides, now that I have installed the <a title=\"Measure Anything, Measure Everything\" href=\"http:\/\/codeascraft.etsy.com\/2011\/02\/15\/measure-anything-measure-everything\/\" target=\"_blank\">statsd<\/a> and graphite packages, I am set up to provide a graph of whatever I want. So why not track the hackers, lock them out, and provide a graph of activity at the same time? So here goes.<\/p>\n<p>2016-12-28 edit: see my github repo at <a href=\"https:\/\/github.com\/dminear\/apache_hack_check\">https:\/\/github.com\/dminear\/apache_hack_check<\/a><\/p>\n<p>I also run mod_perl in the Apache2 server, so I wanted to hook in to the PerlAccessHandler and do the work. The following is the Apache2 config lines:<\/p>\n<pre>        PerlModule ModPerl::DanHandler\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;Location \/&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 #SetHandler perl-script\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PerlAccessHandler ModPerl::DanHandler\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;\/Location&gt;<\/pre>\n<p>And the following is the Perl module that is in the \/usr\/local\/lib\/site_perl\/ModPerl directory on my Ubuntu machine:<\/p>\n<pre>package ModPerl::DanHandler;\r\nuse strict;\r\nuse warnings;\r\nuse FileHandle;\r\nuse IO::Socket::INET;\r\n\r\nuse Apache2::Log;\r\nuse Apache2::RequestRec ();\r\nuse Apache2::Connection ();\r\n\r\nuse Apache2::Const -compile =&gt; qw(FORBIDDEN OK :log);\r\n\r\nBEGIN {\r\nmkdir \"\/tmp\/bad_ips\";\r\nchmod 0777, \"\/tmp\/bad_ips\"\r\n}\r\n\r\nmy $sock = IO::Socket::INET-&gt;new(PeerPort =&gt; 8125,\r\n\t\t\t\tPeerAddr =&gt; '127.0.0.1',\r\n\t\t\t\tProto =&gt; 'udp');\r\n\r\nsub handler {\r\n\tmy $r = shift;\r\n\r\n\tmy $str = $r-&gt;connection-&gt;remote_ip();\r\n\r\n\t# if there is an attempt to access \"zencart\/admin\", then put the ip on the block list\r\n\tif ($r-&gt;unparsed_uri() =~ \/zencart\\\/admin$\/ ||\r\n\t\t$r-&gt;unparsed_uri() =~ \/zencart\\\/+admin\\\/+\/ ||\r\n\t\t$r-&gt;unparsed_uri() =~ \/phpbb2\/i ) {\r\n\t\t#$r-&gt;log_error(\"BAD IP: $str\");\r\n\t\t$sock-&gt;send( \"hacker.unparsed_uri.\" . $r-&gt;unparsed_uri() . \":1|c\\n\" ) if defined $sock;\r\n\t\tmy $fh = FileHandle-&gt;new( \"&gt; \/tmp\/bad_ips\/$str\");\r\n\t\tif (defined $fh) {\r\n\t\t\tprint $fh \"dummy\";\r\n\t\t\t$fh-&gt;close;\r\n\t\t}\r\n\t}\r\n\r\n\t# check the block list\r\n\tif (-e \"\/tmp\/bad_ips\/$str\") {\r\n\t\t$sock-&gt;send( \"request.blocked:1|c\\n\" ) if defined $sock;\r\n\t\treturn Apache2::Const::FORBIDDEN;\r\n\t} else {\r\n\t\t$sock-&gt;send( \"request.allowed:1|c\\n\" ) if defined $sock;\r\n\t\t$sock-&gt;send( \"request.hostname.\" . $r-&gt;hostname() . \":1|c\\n\" ) if defined $sock;\r\n\t\treturn Apache2::Const::OK;\r\n\t}\r\n}\r\n1;<\/pre>\n<p>So now when someone comes in and tries to access \/zencart\/admin (or some gyrations thereof), the IP address gets stored in the tmp directory as a filename. On every request, the remote IP address is checked, and if found returns a 403 Forbidden response. The nice thing is that this happens for any request thereafter.\u00a0 Because it&#8217;s early in the request stage, there&#8217;s not too much overhead. Plus I get the satisfaction of watching the banned IP addresses grow.<\/p>\n<p>Then there&#8217;s some logic to update the statsd server based on good or bad requests. Here&#8217;s a screen capture of it in action (click on the image to enlarge):<\/p>\n<figure id=\"attachment_186\" aria-describedby=\"caption-attachment-186\" style=\"width: 300px\" class=\"wp-caption alignright\"><a href=\"http:\/\/dan.minear.name\/wordpress\/wp-content\/uploads\/2012\/01\/screen.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-186\" title=\"Graphite Screen\" src=\"http:\/\/dan.minear.name\/wordpress\/wp-content\/uploads\/2012\/01\/screen-300x165.png\" alt=\"\" width=\"300\" height=\"165\" \/><\/a><figcaption id=\"caption-attachment-186\" class=\"wp-caption-text\">Monitoring Graph<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve seen a bunch of attempts to hack at my zencart admin area and an old phpBB2 install that is no longer there. Both of these don&#8217;t work, and just return a 404 error, but it&#8217;s kind of annoying to keep spending compute cycles on this sort of behavior. Besides, now that I have installed &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/dan.minear.name\/wordpress\/?p=170\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using ModPerl to Keep Zencart and phpBB2 Hackers Away&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[43,42,44],"_links":{"self":[{"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/170"}],"collection":[{"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=170"}],"version-history":[{"count":20,"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/170\/revisions"}],"predecessor-version":[{"id":213,"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/170\/revisions\/213"}],"wp:attachment":[{"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=170"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dan.minear.name\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}