April 2005 by SunirShah
Blocking open proxies will help reduce the problem of WikiSpam, and other abusive editing on your wiki. However it is a controversial technique, which can potentially block out legitimate users. See MeatBall:OpenProxy for a discussion.
This patch requires the /SelfBan patch to be installed first.
It uses a fork command which is not compatible with mod_perl. An alternative is to simply send a page before the edit page that informs the user that they are being port scanned. When they are successfully port scanned, they will automatically be redirected to the edit page. You can set the timeframe to recheck IPs. You can even set it to never rechecking an IP. That's probably fine. --
Add this function:
sub BanOpenProxy { my ($force) = @_; my $ip = $ENV{REMOTE_ADDR}; # Only check each IP address once a month my $checked = ReadFile("$DataDir/openproxy"); if( $checked =~ s/^$ip (\d+)\n//mg ) { return $Now - $1 < 60*60*24*30; } $checked .= "$ip $Now\n"; return if !$force && fork; require LWP::UserAgent; my @ports = qw/23 80 81 1080 3128 8080 8081 scx-proxy dproxy sdproxy funkproxy dpi-proxy proxy-gateway ace-proxy plgproxy csvr-proxy flamenco-proxy awg-proxy trnsprntproxy castorproxy ttlpriceproxy privoxy ezproxy ezproxy-2/; my $browser = LWP::UserAgent->new( timeout =>10, max_size =>2048, requests_redirectable => [] ); foreach my $port (@ports) { $browser->proxy("http","http://$ip:".$port); my $response = $browser->head("$SiteBase$ScriptName?action=$SelfBan"); last unless defined $response; last unless $response->is_error; } WriteStringToFile("$DataDir/openproxy", $checked); exit unless $force; }
And BanOpenProxy? to DoEdit, as follows:
sub DoEdit { my ($id, $isConflict, $oldTime, $newText, $preview, $rateWarn) = @_; my ($header, $editRows, $editCols, $userName, $revision, $oldText); my ($summary, $isEdit, $pageTime); if (!&UserCanEdit($id, 1)) { print &GetHeader("", T('Editing Denied'), ""); if (&UserIsBanned()) { print T('Editing not allowed: user, ip, or network is blocked.'); print "<p>"; print T('Contact the wiki administrator for more information.'); } else { print Ts('Editing not allowed: %s is read-only.', $SiteName); } print &GetCommonFooter(); return; } &BanOpenProxy;
Add BanOpenProxy? to DoPost? as follows:
sub DoPost { my ($editDiff, $old, $newAuthor, $pgtime, $oldrev, $preview, $user); my $string = &GetParam("text", undef); my $id = &GetParam("title", ""); my $summary = &GetParam("summary", ""); my $oldtime = &GetParam("oldtime", ""); my $oldconflict = &GetParam("oldconflict", ""); my $isEdit = 0; my $editTime = $Now; my $authorAddr = $ENV{REMOTE_ADDR}; my ($limitStatus, $limitText, $limitStats, $rateWarn); if (!&UserCanEdit($id, 1)) { # This is an internal interface--we don't need to explain &ReportError(Ts('Editing not allowed for %s.', $id)); return; } &BanOpenProxy('nofork');
Here are the /SelfBan and /OpenProxy patches together as a unified diff versus UseMod 1.0:
--- wiki.pl 2005-05-14 11:56:11.370742256 -0400 +++ wiki-open-proxy-self-ban.pl 2005-05-14 12:59:27.234683224 -0400 @@ -53,7 +53,7 @@ @IsbnNames @IsbnPre @IsbnPost $EmailFile $FavIcon $RssDays $UserHeader $UserBody $StartUID $ParseParas $AuthorFooter $UseUpload $AllUpload $UploadDir $UploadUrl $LimitFileUrl $MaintTrimRc $SearchButton - $EditNameLink $UseMetaWiki @ImageSites $BracketImg ); + $EditNameLink $UseMetaWiki @ImageSites $BracketImg $SelfBan ); # Note: $NotifyDefault is kept because it was a config variable in 0.90 # Other global variables: use vars qw(%Page %Section %Text %InterSite %SaveUrl %SaveNumUrl @@ -3128,6 +3128,8 @@ &DoConvert(); } elsif ($action eq "trimusers") { &DoTrimUsers(); + } elsif( $action eq $SelfBan ) { + &DoSelfBan(); } else { &ReportError(Ts('Invalid action parameter %s', $action)); } @@ -3193,6 +3195,9 @@ print &GetCommonFooter(); return; } + + &BanOpenProxy; + # Consider sending a new user-ID cookie if user does not have one &OpenPage($id); &OpenDefaultText(); @@ -3901,6 +3906,9 @@ &ReportError(Ts('Editing not allowed for %s.', $id)); return; } + + &BanOpenProxy; + if (($id eq 'SampleUndefinedPage') || ($id eq T('SampleUndefinedPage')) || ($id eq 'Sample_Undefined_Page') || @@ -5089,6 +5097,57 @@ print Ts('Recommended $StartUID setting is %s.', $maxID + 100) . '<br>'; print &GetCommonFooter(); } + +sub DoSelfBan { + print "Content-type: text/plain\n\n"; + print "Congratulations, you have banned your own IP!"; + + my $banlist = ReadFile("$DataDir/banlist"); + my $date = &TimeToText($Now); + + $banlist .= "# self-ban on $date\n^$ENV{REMOTE_ADDR}\n\n"; + + WriteStringToFile("$DataDir/banlist", $banlist ); +} + +sub BanOpenProxy { + my ($force) = @_; + + my $ip = $ENV{REMOTE_ADDR}; + + # Only check each IP address once a month + my $checked = ReadFile("$DataDir/openproxy"); + if ( $checked =~ s/^$ip (\d+)\n//mg ) { + return $Now - $1 < 60*60*24*30; + } + $checked .= "$ip $Now\n"; + + return if !$force && fork; + + require LWP::UserAgent; + my @ports = qw/23 80 81 1080 3128 8080 8081 scx-proxy dproxy sdproxy + funkproxy dpi-proxy proxy-gateway ace-proxy plgproxy + csvr-proxy flamenco-proxy awg-proxy trnsprntproxy + castorproxy ttlpriceproxy privoxy ezproxy ezproxy-2/; + + my $browser = LWP::UserAgent->new( + timeout =>10, + max_size =>2048, + requests_redirectable => [] + ); + + foreach my $port (@ports) { + $browser->proxy("http","http://$ip:".$port); + my $response = $browser->head("$SiteBase$ScriptName?action=$SelfBan"); + last unless defined $response; + last unless $response->is_error; + } + + WriteStringToFile("$DataDir/openproxy", $checked); + + exit unless $force; +} + #END_OF_OTHER_CODE &DoWikiRequest() if ($RunCGI && ($_ ne 'nocgi')); # Do everything.