Subversion Repositories configs

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
34 - 1
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
2
# vi: set ft=python sts=4 ts=4 sw=4 noet :
3
 
4
# This file is part of Fail2Ban.
5
#
6
# Fail2Ban is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# Fail2Ban is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with Fail2Ban; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
 
20
import socket
21
import smtplib
22
from email.mime.text import MIMEText
23
from email.utils import formatdate, formataddr
24
 
25
from fail2ban.server.actions import ActionBase, CallingMap
26
 
27
messages = {}
28
messages['start'] = \
29
"""Hi,
30
 
31
The jail %(jailname)s has been started successfully.
32
 
33
Regards,
34
Fail2Ban"""
35
 
36
messages['stop'] = \
37
"""Hi,
38
 
39
The jail %(jailname)s has been stopped.
40
 
41
Regards,
42
Fail2Ban"""
43
 
44
messages['ban'] = {}
45
messages['ban']['head'] = \
46
"""Hi,
47
 
48
The IP %(ip)s has just been banned for %(bantime)i seconds
49
by Fail2Ban after %(failures)i attempts against %(jailname)s.
50
"""
51
messages['ban']['tail'] = \
52
"""
53
Regards,
54
Fail2Ban"""
55
messages['ban']['matches'] = \
56
"""
57
Matches for this ban:
58
%(matches)s
59
"""
60
messages['ban']['ipmatches'] = \
61
"""
62
Matches for %(ip)s:
63
%(ipmatches)s
64
"""
65
messages['ban']['ipjailmatches'] = \
66
"""
67
Matches for %(ip)s for jail %(jailname)s:
68
%(ipjailmatches)s
69
"""
70
 
71
class SMTPAction(ActionBase):
72
	"""Fail2Ban action which sends emails to inform on jail starting,
73
	stopping and bans.
74
	"""
75
 
76
	def __init__(
77
		self, jail, name, host="localhost", user=None, password=None,
78
		sendername="Fail2Ban", sender="fail2ban", dest="root", matches=None):
79
		"""Initialise action.
80
 
81
		Parameters
82
		----------
83
		jail : Jail
84
			The jail which the action belongs to.
85
		name : str
86
			Named assigned to the action.
87
		host : str, optional
88
			SMTP host, of host:port format. Default host "localhost" and
89
			port "25"
90
		user : str, optional
91
			Username used for authentication with SMTP server.
92
		password : str, optional
93
			Password used for authentication with SMTP server.
94
		sendername : str, optional
95
			Name to use for from address in email. Default "Fail2Ban".
96
		sender : str, optional
97
			Email address to use for from address in email.
98
			Default "fail2ban".
99
		dest : str, optional
100
			Email addresses of intended recipient(s) in comma space ", "
101
			delimited format. Default "root".
102
		matches : str, optional
103
			Type of matches to be included from ban in email. Can be one
104
			of "matches", "ipmatches" or "ipjailmatches". Default None
105
			(see man jail.conf.5).
106
		"""
107
 
108
		super(SMTPAction, self).__init__(jail, name)
109
 
110
		self.host = host
111
		#TODO: self.ssl = ssl
112
 
113
		self.user = user
114
		self.password =password
115
 
116
		self.fromname = sendername
117
		self.fromaddr = sender
118
		self.toaddr = dest
119
 
120
		self.matches = matches
121
 
122
		self.message_values = CallingMap(
123
			jailname = self._jail.name,
124
			hostname = socket.gethostname,
125
			bantime = self._jail.actions.getBanTime,
126
			)
127
 
128
	def _sendMessage(self, subject, text):
129
		"""Sends message based on arguments and instance's properties.
130
 
131
		Parameters
132
		----------
133
		subject : str
134
			Subject of the email.
135
		text : str
136
			Body of the email.
137
 
138
		Raises
139
		------
140
		SMTPConnectionError
141
			Error on connecting to host.
142
		SMTPAuthenticationError
143
			Error authenticating with SMTP server.
144
		SMTPException
145
			See Python `smtplib` for full list of other possible
146
			exceptions.
147
		"""
148
		msg = MIMEText(text)
149
		msg['Subject'] = subject
150
		msg['From'] = formataddr((self.fromname, self.fromaddr))
151
		msg['To'] = self.toaddr
152
		msg['Date'] = formatdate()
153
 
154
		smtp = smtplib.SMTP()
155
		try:
156
			self._logSys.debug("Connected to SMTP '%s', response: %i: %s",
157
				self.host, *smtp.connect(self.host))
158
			if self.user and self.password:
159
				smtp.login(self.user, self.password)
160
			failed_recipients = smtp.sendmail(
161
				self.fromaddr, self.toaddr.split(", "), msg.as_string())
162
		except smtplib.SMTPConnectError:
163
			self._logSys.error("Error connecting to host '%s'", self.host)
164
			raise
165
		except smtplib.SMTPAuthenticationError:
166
			self._logSys.error(
167
				"Failed to authenticate with host '%s' user '%s'",
168
				self.host, self.user)
169
			raise
170
		except smtplib.SMTPException:
171
			self._logSys.error(
172
				"Error sending mail to host '%s' from '%s' to '%s'",
173
				self.host, self.fromaddr, self.toaddr)
174
			raise
175
		else:
176
			if failed_recipients:
177
				self._logSys.warning(
178
					"Email to '%s' failed to following recipients: %r",
179
					self.toaddr, failed_recipients)
180
			self._logSys.debug("Email '%s' successfully sent", subject)
181
		finally:
182
			try:
183
				self._logSys.debug("Disconnected from '%s', response %i: %s",
184
					self.host, *smtp.quit())
185
			except smtplib.SMTPServerDisconnected:
186
				pass # Not connected
187
 
188
	def start(self):
189
		"""Sends email to recipients informing that the jail has started.
190
		"""
191
		self._sendMessage(
192
			"[Fail2Ban] %(jailname)s: started on %(hostname)s" %
193
				self.message_values,
194
			messages['start'] % self.message_values)
195
 
196
	def stop(self):
197
		"""Sends email to recipients informing that the jail has stopped.
198
		"""
199
		self._sendMessage(
200
			"[Fail2Ban] %(jailname)s: stopped on %(hostname)s" %
201
				self.message_values,
202
			messages['stop'] % self.message_values)
203
 
204
	def ban(self, aInfo):
205
		"""Sends email to recipients informing that ban has occurred.
206
 
207
		Parameters
208
		----------
209
		aInfo : dict
210
			Dictionary which includes information in relation to
211
			the ban.
212
		"""
213
		aInfo.update(self.message_values)
214
		message = "".join([
215
			messages['ban']['head'],
216
			messages['ban'].get(self.matches, ""),
217
			messages['ban']['tail']
218
			])
219
		self._sendMessage(
220
			"[Fail2Ban] %(jailname)s: banned %(ip)s from %(hostname)s" %
221
				aInfo,
222
			message % aInfo)
223
 
224
Action = SMTPAction