Skip to content
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

adding ip restrictions to login process #849

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

icodk
Copy link

@icodk icodk commented Jan 2, 2024

This PR contains the following additions to the login process (all implemented in the py4web/utils/auth.py):

  1. Checks if client ip address is allowed (contains in a file named: host_ip_allow.txt)
  2. Checks if client ip address is denied (contains in a file named: host_ip_deny.txt)
    Notes:
  3. Both files are loaded on py4web start up only.
  4. If any of the files is not found the check is not performed.
  5. If an IP appears in both files the client is denied.
    In addition to these restrictions, in case of a failed login (because of wrong credential ), the client IP will be registered in a file name: host_ip_blocked.txt.
    After a predefined number of failures, the client IP will be blocked for predefined number of seconds. Which means that even a a login with correct credentials will be denied until the timeout period is over.
    A successful login after the timeout period will cause a removal of the ip from the host_ip_blocked.txt.
    Issues:
    The path to the host_ip_allow.txt and the host_ip_deny.txt files are not specified in the PR.
    Since the host_ip_blocked.txt file is created by the framework and not by the user, the path happened to be '/' on an ubuntu installation with the machine-setup.sh script from the py4web\deployment_tools\ubuntu

if blocked_ip['count']< BLCOKED_IP_MAX_COUNT:
blocked_ip['count']+=1
with open(FILE_BLCOKED_IP_COUNT, "w") as fp:
json.dump(host_ip_blocked, fp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately this is not thread safe.

BLCOKED_IP_MAX_COUNT=5
# timeout for blocked IP: if BLOCKED_IP_TIMEOUT=0 blocking never expired
BLOCKED_IP_TIMEOUT=5*60 # reenable blocked ip after this time in seconds
FILE_BLCOKED_IP_COUNT="host_ip_blocked.txt"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look into core.py for DatabaseErrorLogger. It creates a global database .service/service.storage. Perhaps make auth create a new "web2py_managed_ips" in there with fields "ip, allowed, blocked, counter" and use those.

try:
with open(FILE_HOST_IP_ALLOW, "r") as fp:
host_ip_allow = json.load(fp)
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pylint will not like this

client_ip=request.remote_addr
is_this_ip_allowd=True
if host_ip_blocked:
blocked_ip =host_ip_blocked[client_ip]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice. Even if reading from DB make sure all blocked ips are read at statup to minimize disk IO at every request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants