This is a class that maintain a blacklist or white list. Using it with SecurityPolicy, its easy to lock out spamers and other bad guys from editing pages or allow only few ips out of your network, or whatever you like.
Note that this is the first release, and its tested very lightly, only with moin 1.1.
Whats new
- The blacklist now supports subnets or netblocks using both CIDR notation 127.0.0.0/24 and old style 127.0.0.0 255.255.255.0
- Address ranges are not supported any more
- Code simplified
- Better error checking
Usage
Note this blocks ips and not bad links. Before you use IP BlackList, please check AntiSpamGlobalSolution, which might be more effective against LinkSpam, and is auto updating from BadContent. This black list is useful to ban IP's or whole networks. Be careful not to block the good guys.
Install
Download the package: blacklist-2004-07-22.tgz
Before you try to use it - run the test to see that it works on your system - run make test from the release directory.
Copy the package blacklist into the moin config directory or anywhere in Python sys.path (you can add to the path in moin.cgi). I use this scheme because I need it to admin a wiki with ftp access to the wiki directory.
Addresses file or wiki page
First put the address or netblocks to block in a text file, using common text format or a nice wiki formated list as you like:
= Blocked addresses in this wiki = A nice touch would be to add the ip of anyone (probably a robot) who tries to edit this page without having admin ACL rights (this text is ignored by the blacklist reader). * 127.0.0.1 # single address * 192.114.128.0/20 # netblock using CIDR notation * 192.114.128.0 255.255.240.0 # netblock using old style format 10.0.0.1 # You dont have to use wiki list format if you don't like to # 10.0.0.2 this address is ignored And so is this line and the next ...
moin_config.py stuff
How to use in moin_config.py - tested with moin 1.1 only:
1 # Add to moin config
2
3 # Security policy
4 # Tested only with moin 1.1
5 try:
6 import cPickle as pickle
7 except ImportError:
8 import pickle
9 from blacklist import blacklist
10 from MoinMoin import security
11
12
13 class SecurityPolicy(security.Default):
14 def __init__(self, user):
15 security.Default.__init__(self, user)
16 self.loadBlacklist()
17
18 def edit(self, pagename, **kw):
19 """ Extend the default edit permissions """
20
21 # blacklist only non users
22 if not self.user.valid and hasattr(self, 'blacklist'):
23 # Needed for moin 1.1 compatibility
24 if not hasattr(self.user._request, 'remote_addr'):
25 import os
26 self.user._request.remote_addr = os.environ.get('REMOTE_ADDR', '')
27 # Blacklist
28 if self.user._request.remote_addr in self.blacklist:
29 return 0
30
31 # Use standard permissions
32 return security.Default.edit(self, pagename, **kw)
33
34 def loadBlacklist(self):
35 """ Load data from file or wiki page """
36 import sys
37 blacklistFile = 'blacklist.cache'
38 try:
39 self.blacklist = pickle.load(file(blacklistFile))
40 except (IOError, OSError, pickle.UnpicklingError), why:
41 # Read the data from a text file, or better from
42 # a wiki page.
43 sys.stderr.write('load blacklist failed %s:' % str(why))
44 text = file('blacklist.txt').read()
45 self.blacklist = blacklist.BlackList(text)
46 try:
47 pickle.dump(self.blacklist, file(blacklistFile, 'w'))
48 except (IOError, pickle.PicklingError), why:
49 sys.stderr.write('cache blacklist failed: %s' % str(why))
Note that in moin 1.2 you should print through the request object, and not through print or sys.stderr.write . I still did not test this code with 1.2.
Problems
- The cached blacklist is not updated after you edit the blacklist.txt file. You have to manually delete the cache file.
- Maybe we can use wikidicts for caching, but they are not available on moin 1.1
Planning
- Update the cache whenever the text file changes
- Save the blacklist on a wiki page, and update the cache when this page is saved
- If both wiki page and text file are avaiable, which one to use?
- What about a wiki with ACL disabled? a wiki page with no ACL is not good
This can be done by using SecurityPolicy save method, and checking for the page named BlackList
- How to merge this with moin code:
- ipv4 module could go into util package
- blacklist module could go into the security package (need to create one, maybe with ACL?)
SecurityPolicy class should have built-in hook for blacklist loading, this code is currently in moin_config.
Extend the class to do content filtering/blackisting when saving pages. Both text and address can be saved in one file/wiki page or in too different files. The current code use if '127.0.0.1' in blacklist, but we can make address matching method and text matching method like:
1 #This can be built in in SecurityPolicy: 2 3 if hasattr(blacklist, addresses) and self.request.remote_addr in blacklist.addresses: 4 # prevent edit/read etc. 5 6 if hasattr(blacklist, text) and pagetext in blacklist.text: 7 # prevent save or filter out bad text etc. 8 9 class AddressFilter: 10 def __contains__(self, address): 11 # basicly what BlackList.__contains__ does now... 12 13 class TextFilter: 14 def __contains__(self, text): 15 return self.regex.search(text) 16 17 # And BlackList will be a composite of these classes and will feed them with data from 18 # text file/ wiki page etc. Then we can add more filter types if needed, and from the admin 19 # point of view its just a `blacklist = BlackList(page='BlackList')` and fill that page 20 # with data.
- A way to update the blacklist from a blacklist server
- A way to update the server with new bad texts or addresses - so one moin wiki that spammed will notify all other moin wikis automatically.
- An automated message to search engines about link spammers.