{"id":20204194,"url":"https://github.com/openbridge/ob_proftpd_autoban","last_synced_at":"2026-06-06T12:31:47.078Z","repository":{"id":73272241,"uuid":"53894606","full_name":"openbridge/ob_proftpd_autoban","owner":"openbridge","description":"Proftpd Autoban - Blocking Malicious Users","archived":false,"fork":false,"pushed_at":"2018-11-20T18:24:55.000Z","size":32,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-13T20:30:47.591Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.openbridge.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openbridge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-14T21:53:50.000Z","updated_at":"2023-12-12T15:22:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"cd473a0a-285a-437a-bb1b-acc8e501bd35","html_url":"https://github.com/openbridge/ob_proftpd_autoban","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openbridge%2Fob_proftpd_autoban","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openbridge%2Fob_proftpd_autoban/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openbridge%2Fob_proftpd_autoban/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openbridge%2Fob_proftpd_autoban/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openbridge","download_url":"https://codeload.github.com/openbridge/ob_proftpd_autoban/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241637595,"owners_count":19995004,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T05:09:04.491Z","updated_at":"2026-06-06T12:31:47.025Z","avatar_url":"https://github.com/openbridge.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003eProftpd Autoban\u003c/h1\u003e\n\nThe purpose of this application is to detect malicious login attempts and ban them. This is similar to what Fail2Ban accomplishes. However, Fail2Ban was not working as expected in a Docker context. This was largely due to the fact Fail2ban wants to run on the host, not inside a container, where it has access to different parts of the networking stack like Iptables. This not to say Fail2Ban can't work, it was simply quicker to create this application. The application, while lightweight, gets the job done. Also, I wanted something that was able to work with the Proftpd mod_wrap2 module.\n\nProftpd: \u003curl\u003ehttp://www.proftpd.org/\u003c/url\u003e\u003cbr\u003e\nProftpd mod_wrap2: \u003curl\u003ehttp://www.proftpd.org/docs/contrib/mod_wrap2.html\u003c/url\u003e\u003cbr\u003e\n\n\n## Manifest of files\nHere are the files included.\n```\n/usr/local/bin/ban.py\n/usr/local/bin/ban.sh\n/usr/local/bin/logging\n/etc/ban/config.cfg\n/etc/ban/whitelist.txt\n\n```\n\n# ban.sh\nThis script controls the operation of the \u003ccode\u003eban.py\u003c/code\u003e application. This is what orchestrates various processes for running \u003ccode\u003eban.py\u003c/code\u003e and file sync activities.\n\n#### Using AWS S3 to share the hosts.deny and whitelist.txt\nS3 is used as a simple method to share the \u003ccode\u003ehosts.deny\u003c/code\u003e and \u003ccode\u003ewhitelist.txt\u003c/code\u003e across Proftpd hosts. This is especially useful in clustered environments.\n\nYou will need to make sure you edit the script and put in your S3 bucket location. Make sure that Proftpd will have access to this bucket. Also, adjust your subdirectories where you will store both files. The config follows the normal OS path (/etc/..) for the config fiile. Change this however you feel most appropriate.\n\n```\ns3_whitelist=\"s3://bucket/etc/ban/\"\ns3_hostsdeny=\"s3://bucket/etc/\"\n```\n#### Sync Operation\nThe script will make sure that \u003ccode\u003ehosts.deny\u003c/code\u003e and \u003ccode\u003ewhitelist.txt\u003c/code\u003e are synced first from S3. This is to ensure it has any updates from other nodes. Next, it will run \u003ccode\u003eban.py\u003c/code\u003e to scan the \u003ccode\u003eAUTH\u003c/code\u003e log for suspicious behaviors as defined in the config. If it finds any, those IPs will be appended to the hosts.deny file. Once \u003ccode\u003eban.py\u003c/code\u003e is complete, the script will push an update back to S3. While the use of S3 was intended for a cluster it will work for standalone servers as well. It just means your standalone server is the only one reading and writing to those files.\n\n#### Note\nYou will notice a random \u003ccode\u003esleeptime\u003c/code\u003e generated each time the script is run. That is to reduce the possibility that a different node in the cluster may conflict perform the same operation as other nodes.\n\n#### context=\"aws\"\nIn its current form, everything wants to be run in an AWS context. This is what context=\"aws\" does. Everything will run off of AWS. Just use something like context=\"local\" for testing purposes. You can also replace the S3 commands with something else assuming your want to store those files to a NAS/SAN location.\n\n# ban.py\nYou  need to edit \u003ccode\u003e/usr/local/bin/ban.py\u003c/code\u003e to reference the location of your \u003ccode\u003eAUTH\u003c/code\u003e log. In this example the log is located here: \u003ccode\u003e/ebs/logs/proftpd/proftpd_auth.log\u003c/code\u003e. Change this to where ever you happen to keep your log.\n\n#### config.cfg\n\nYou can control the behavior of the application with the config. For example, you can set the user names, attempts and periods that the application will use to qualify a malicious user to ban.\n\nExample:\n```\n[DEFAULT]\nsuspicious_users = root admin administrator\nsuspicious_users_attempts_threshold = 2\nlogin_attempts_threshold = 5\nlogin_attempts_period = 300\nwhitelist = /etc/ban/whitelist.txt\n```\n#### whitelist.txt\nAny IP listed here will not be included in the hosts.deny file\n\nExample:\n```\n0.0.0.0\n8.8.8.8\n```\n\n#### hosts.deny\n\nIn the hosts deny file you will start seeing entries like this:\n\n```\nALL: 222.186.15.104\nALL: 222.186.15.200\nALL: 222.186.34.94\nALL: 222.186.58.136\nALL: 222.187.222.220\nALL: 222.187.224.222\n```\nThese are all from China Telecom.\n\n# mod_wrap2\nThis requires the use of mod_wrap2. It is responsible for reading the hosts.deny file and blocking access.\n\nhttp://www.proftpd.org/docs/contrib/mod_wrap2.html\n\nExample configuration statement for mod_wrap2\n\n```\n\n\u003cIfModule mod_wrap2.c\u003e\n   WrapEngine           on\n   WrapOptions          CheckOnConnect\n   WrapDenyMsg          \"User '%u' denied by access rules\"\n   WrapTables           file:/etc/hosts.allow file:/etc/hosts.deny\n\n   \u003cIfClass !localhost\u003e\n       WrapLog           /ebs/logs/proftpd/proftpd_wrap.log\n   \u003c/IfClass\u003e\n\n\u003c/IfModule\u003e\n\n```\nWe are focused on the \u003ccode\u003efile:/etc/hosts.deny\u003c/code\u003e aspect of the config vs \u003ccode\u003efile:/etc/hosts.allow\u003c/code\u003e. The hosts.deny file is where we will be storing the banned IPs\n\n## Running\n\nYou can do something simple like use CRON. This would be the preferred approach.\n```\n*/15 * * * * /usr/bin/bash -c '/usr/local/bin/ban.sh' \u003e\u003e /ebs/logs/cron/ban.log 2\u003e\u00261\n```\nYou can also use a monitoring application. For example, this is a Monit configuration to run whenever someone accesses the server.\n\n```\n# Trigger the check of the access log to verify if there are hacking attempts happening\ncheck file ban-logs with path /ebs/logs/proftpd/proftpd_auth.log\n      if changed timestamp then exec /usr/bin/bash -c \"/usr/local/bin/ban.sh\"\n```\n\nif logs are rotated frequently and you have light traffic then this option might be ok. However, if you have large log files this can be a bad idea.\n\nYou can have Monit run it on a schedule to (vs timestamp checks). This would be similar to CRON.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenbridge%2Fob_proftpd_autoban","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenbridge%2Fob_proftpd_autoban","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenbridge%2Fob_proftpd_autoban/lists"}