[FIX] base: log failed/successful logins with ip

We used to only log failed logins, and did not include the IP, which
makes it much less useful for intrusion detections systems (e.g. fail2ban)

For example, the following fail2ban filter definition should match a
failed login (in /etc/fail2ban/filter.d/odoo-login.local):

    [Definition]
    failregex = ^ \d+ INFO \S+ \S+ Login failed for db:\S+ login:\S+ from <HOST>
    ignoreregex =

This could be used with a jail definition to block the IP on HTTP(S).

Here is what it could look like for blocking the IP for 15 minutes when
10 failed login attempts are detected from the same IP within 1 minute:

    [odoo-login]
    enabled = true
    port = http,https
    bantime = 900  ; 15 min ban
    maxretry = 10  ; if 10 attempts
    findtime = 60  ; within 1 min
    logpath = /var/log/odoo.log  ;  set the actual odoo log path here
This commit is contained in:
Olivier Dony
2018-05-16 17:39:32 +02:00
parent 19fb650863
commit 86ffb549bf
+6 -1
View File
@@ -14,6 +14,7 @@ from hashlib import sha256
from odoo import api, fields, models, tools, SUPERUSER_ID, _
from odoo.exceptions import AccessDenied, AccessError, UserError, ValidationError
from odoo.http import request
from odoo.osv import expression
from odoo.service.db import check_super
from odoo.tools import partition, pycompat
@@ -467,8 +468,12 @@ class Users(models.Model):
user.sudo(user_id).check_credentials(password)
user.sudo(user_id)._update_last_login()
except AccessDenied:
_logger.info("Login failed for db:%s login:%s", db, login)
user_id = False
status = "successful" if user_id else "failed"
ip = request.httprequest.environ['REMOTE_ADDR'] if request else 'n/a'
_logger.info("Login %s for db:%s login:%s from %s", status, db, login, ip)
return user_id
@classmethod