This repository has been archived by the owner on Mar 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfail2ban-p2p-client.py
executable file
·151 lines (130 loc) · 4.58 KB
/
fail2ban-p2p-client.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/python2
# Copyright 2013 Johannes Fuermann <johannes at fuermann.cc>
# Copyright 2013 Manuel Munz <manu at somakoma.de>
#
# This file is part of fail2ban-p2p.
#
# Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. For details
# see the file COPYING or http://www.gnu.org/licenses/gpl-3.0.en.html.
"""
This script can be used to send a ban message to the own node.
To do this it will use the ip address and port given in the configfile
for this node.
"""
import sys
sys.path.insert(1, "./fail2ban-p2p")
sys.path.insert(2, "/usr/share/fail2ban-p2p/fail2ban-p2p")
import config
import hashlib
import os
import argparse
import crypto
import socket
import M2Crypto
from time import time
import json
import util
import version
# Parse arguments
parser = argparse.ArgumentParser(description='fail2ban-p2p-client help.')
parser.add_argument('-b', help='IP address to ban', metavar='IP')
parser.add_argument('-c', default='/etc/fail2ban-p2p/', help='Read configuration from DIR.',
metavar='DIR')
parser.add_argument('-d', help='Dump table of blocked hosts in the format <FORMAT> (table, json or count).',
metavar='FORMAT')
parser.add_argument('-t', help='The list of blocked hosts should go back that many seconds.',
metavar='SECONDS')
parser.add_argument('-q', action='store_true', help='Quiet, no output')
parser.add_argument('-v', action='store_true', help='Verbose output')
args = parser.parse_args()
c = config.Config()
c.configPath = args.c or "/etc/fail2ban-p2p"
c.privkey = os.path.join(c.configPath, 'private.pem')
c.pubkey = os.path.join(c.configPath, 'public.pem')
if c.loadConfig() == False:
exit()
if not args.d and not args.b:
print "Please use the -b argument to specify an IP to ban or -d to request information about banned nodes."
exit()
dump = False
if args.d:
dump = True;
if not args.d == "table" and not args.d == "json" and not args.d == "count":
print("invalid value for -d argument!")
exit()
timeframe = 3600
if args.t:
try:
timeframe = int(args.t)
except ValueError as e:
print("Invalid Timeframe specified, only use integers! Using default value of 3600 instead")
timeframe = 3600
quiet = False
if args.q:
quiet = True
if dump:
# Generate a message of type 2 (request to dump list of banned hosts)
unordered_dict = {
"msgType": 2,
"parameter": { "TimeFrame": timeframe},
"hops": ['local']
}
serializable_dict = util.sort_recursive(unordered_dict)
if args.b:
# Generate a ban message (Type 1)
unordered_dict = {
"msgType": 1,
"parameter": { "Timestamp": int(time()), "AttackerIP": args.b, "Trustlevel": 100 },
"hops": ['local']
}
serializable_dict = util.sort_recursive(unordered_dict)
if args.b or dump:
signed_message = json.dumps(serializable_dict)
SignEVP = M2Crypto.EVP.load_key(c.privkey)
SignEVP.sign_init()
SignEVP.sign_update(signed_message)
StringSignature = SignEVP.sign_final().encode('hex')
signed_dict = {
#"protocolVersion": version.protocol,
"msg": serializable_dict,
"signature": StringSignature,
"protocolVersion": version.protocolVersion
}
cmdsigned = json.dumps(signed_dict)
ret = None
# send message
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
s.connect((c.addresses[0], int(c.port)))
s.send(cmdsigned)
ret = s.recv(1048576) # we need about 50 Bytes per banned node
if not quiet and args.v:
print ("Message sent: " + cmdsigned)
except:
if not quiet:
print ("could not connect to "+c.name+" ("+c.addresses[0]+":"+str(c.port)+")")
finally:
s.close()
if ret:
if args.d:
if "ERROR" in ret:
print("An error occured:\n")
print(ret)
elif args.d == "json":
print(ret)
elif args.d == "count":
print(len(json.loads(ret)))
else:
banList = json.loads(ret)
if len(banList) > 0:
print("IP".ljust(15, ' ') + "\tTimestamp\t\tBantime\t\tTrustlevel\tStatus")
for ban in banList:
status = "PENDING"
if int(c.threshold) <= int(ban['Trustlevel']):
status = "BANNED"
print(ban['AttackerIP'].ljust(15, ' ') + "\t" + str(ban['Timestamp']) + "\t\t" + str(ban['BanTime']) + "\t\t" + str(ban['Trustlevel'])) + "\t\t" + status
else:
print("No hosts in banlist")
else:
print("Answer: " + ret)