-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathnet2banctl.py
executable file
·133 lines (117 loc) · 4.85 KB
/
net2banctl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
#
# Net2BanCtl
#
# Written by Chema Garcia (aka sch3m4)
# [email protected] || http://safetybits.net
# @sch3m4
#
import sys
sys.path.insert(1, "/usr/share/net2ban")
import os
import json
import time
import base64
import binascii
import ConfigParser
import net2ban
import hmac
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
def get_client ( config ):
client = sys.argv[2]
if not config.has_section ( client ):
print "Client not found: %s" % client
return
for item in ['global','keygen',client]:
glob = config.options ( item )
print "[%s]" % item
for i in glob:
if i == 'mode':
print "mode = client"
else:
print "%s = %s" % (i , config.get ( item , i ) )
print ""
def gen_random ( config ):
len = int ( config.get ( 'keygen' , 'keylen' ) )
return binascii.hexlify ( Random.new().read ( len / 2 ) )
def main():
if len(sys.argv) < 2:
print "Usage: %s COMMAND" % sys.argv[0]
print "Commands available:"
print "\tget_client client_name ------------> Get the config for the client client_name"
print "\tupdate client_name /path/to/file --> Create/update the fail2ban actions file in all clients"
print "\tlist_clients ----------------------> List all client names"
print "\tgen_random ------------------------> Generate a random string to be used as client key or shared secret"
print ""
sys.exit(-1)
n2b = net2ban.Net2Ban()
config = ConfigParser.ConfigParser()
config.read ( n2b.get_config_file() )
if len(sys.argv) == 2 and sys.argv[1] == 'gen_random':
print gen_random ( config )
return
if len(sys.argv) == 3 and sys.argv[1] == 'get_client':
get_client ( config )
return
if len(sys.argv) == 2 and sys.argv[1] == 'list_clients':
clients = config.sections()
for c in ['global','server','keygen']:
if c in clients:
clients.remove(c)
if len ( clients ) > 0:
print '\n'.join(clients)
return
if len(sys.argv) == 4 and sys.argv[1] == 'update':
file = sys.argv[3]
content = ''
with open(file) as f:
for line in f:
line = line.split('#', 1)[0]
line = line.rstrip()
if len(line) > 0:
content += line + '\n'
content = base64.b64encode ( content )
file = ''.join(os.path.basename(sys.argv[3]).split('.')[:-1])
data = { 'cmd': sys.argv[1] , 'file': file , 'content': content , 'client': sys.argv[2] }
elif len(sys.argv) > 3 and sys.argv[1] == 'exec':
data = { 'cmd': sys.argv[1] , 'file': sys.argv[2] , 'action': sys.argv[3]}
vars = {}
for v in sys.argv[4:]:
name = v.split('=')[0]
val = v.split('=')[1]
vars[name] = val
data['params'] = vars
else:
print "Invalid parameters"
return
data['timestamp'] = time.time()
msg = json.JSONEncoder().encode ( data )
param = {}
for i in ['server','rounds','secret','input','key','authkey']:
section = None
for j in ['server','global']:
if config.has_option ( j , i ):
section = j
break
if section is None:
print "Cannot find '%s' value" % i
return
param[i] = config.get ( section , i )
client = net2ban.Client()
client.set_parameters ( host = param['server'] , secret = param['secret'] , key = param['key'] , queue = param['input'] , rounds = param['rounds'] , auth_key = param['authkey'] )
client.connect()
key = client.get_session_key()
iv = Random.new().read ( AES.block_size )
cipher = AES.new ( key , AES.MODE_CBC , iv)
total = len(msg)
padlen = AES.block_size - ( total % AES.block_size )
for i in range(0,padlen):
msg += chr(padlen)
encrypted = iv + cipher.encrypt ( msg )
mhmac = hmac.new ( client.get_auth_key() , encrypted , hashlib.sha256 ).hexdigest()
client.write ( encrypted + mhmac )
client.disconnect()
if __name__ == "__main__":
main()