-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add fail2ban sensor #9975
Add fail2ban sensor #9975
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use regex, that will be faster than you complex parse.
@pvizeli I don't believe that's true Source. I'm also not entirely certain of which part of the parse you're referring to, though. The only parse I do is check if a string exists within a line. Could you elaborate on your request a bit? I had thought about using regex initially, but given the linked thread and the hit to readability, I don't think it is the correct choice here. EDIT - maybe I see where you're thinking there can be improvement: lines 97 to 114? Simplify that |
@pvizeli I removed the for loop from the |
- also was missing return False in timer for default behavior
That had a simple reason, you don't optimize the regex with compile. |
vol.All(cv.ensure_list, vol.Length(min=1)), | ||
vol.Optional(CONF_FILE_PATH, default=DEFAULT_LOG): cv.isfile, | ||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, | ||
vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is already inside PLATFORM_SCHEMA
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok. I figured I needed to overload it to set the default scan interval, so is there a different way to do that? Or should I just remove the default and force the user to decide how often to open the fail2ban log for reading?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set SCAN_INTERVAL on top of you platform and you have set the default interval
Oh, that makes total sense now. Thanks for that information 👍 |
- renamed DEFAULT_SCAN_INTERVAL to SCAN_INTERVAL
@@ -26,7 +26,7 @@ | |||
|
|||
DEFAULT_NAME = 'fail2ban' | |||
DEFAULT_LOG = '/var/log/fail2ban.log' | |||
DEFAULT_SCAN_INTERVAL = 120 | |||
SCAN_INTERVAL = 120 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timedelta
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, whoops. Fixed.
try: | ||
with open(self.log_file, 'r', encoding='utf-8') as file_data: | ||
self.data = re.findall( | ||
r'\[' + re.escape(jail) + r'\].(Ban|Unban) ([\w+\.]{3,})', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compile the regex into a dict and use the jail as key. Use also this syntax: r"...{}...".format()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like the following?
self.data[jail] = re.findall(r"...{}...".format(jail), ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, like self.xy[jail] = re.compile(r"...{}...".format(jail))
@pvizeli OK, I think I implemented what you requested. Let me know if there are any more changes you'd like to see |
Description:
I was looking for an easy way to display active and historical bans on my system within home-assistant, and decided to add this platform as a solution. Please let me know if you think there is a better way to implement this.
What it does
Each 'jail' set up within fail2ban can be added as a sensor within homeassistant. This component will access the fail2ban log (which you provide via the config) and scan it for any IPs that have been banned within each specified jail. Any IP that is found will be added to a list within
sensor.state_attributes
to keep a running tab on each IP currently banned. Each uniquely banned IP will also be added to a permanent list to keep track of all IPs banned for that jail, up to a total of 10 (any more and the oldest banned IP is removed, to prevent the list from becoming too long). Thestate
displayed within home-assistant is the most recently banned IP for the given jail.Tested platforms
I've tested this with the following setups:
For both those platforms, fail2ban still needs to be manually configured to work correctly. For the docker in unRAID behind nginx, there were some extra steps needed but it's working great for me right now. I plan on adding the latter to the documentation when I get to it.
Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#3679
Example entry for
configuration.yaml
(if applicable):Checklist:
If user exposed functionality or configuration variables are added/changed:
tox
run successfully. Your PR cannot be merged unless tests pass