{"id":16421721,"url":"https://github.com/peppelinux/django-audit-wazuh","last_synced_at":"2025-03-23T07:32:07.959Z","repository":{"id":52909812,"uuid":"257288443","full_name":"peppelinux/django-audit-wazuh","owner":"peppelinux","description":"Django middleware and signals for handling security events ","archived":false,"fork":false,"pushed_at":"2021-04-14T16:17:50.000Z","size":67,"stargazers_count":12,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-18T18:26:24.237Z","etag":null,"topics":["django","loganalysis","ossec","ossec-wazuh","security","siem","wazuh"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peppelinux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"auditing/__init__.py","citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-20T13:24:14.000Z","updated_at":"2024-09-29T12:52:11.000Z","dependencies_parsed_at":"2022-08-23T18:40:37.283Z","dependency_job_id":null,"html_url":"https://github.com/peppelinux/django-audit-wazuh","commit_stats":null,"previous_names":["peppelinux/django-audit"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2Fdjango-audit-wazuh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2Fdjango-audit-wazuh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2Fdjango-audit-wazuh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peppelinux%2Fdjango-audit-wazuh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peppelinux","download_url":"https://codeload.github.com/peppelinux/django-audit-wazuh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245072086,"owners_count":20556352,"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":["django","loganalysis","ossec","ossec-wazuh","security","siem","wazuh"],"created_at":"2024-10-11T07:34:31.283Z","updated_at":"2025-03-23T07:32:07.695Z","avatar_url":"https://github.com/peppelinux.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Django Audit Wazuh\n------------------\n\n![CI build](https://github.com/peppelinux/django-audit-wazuh/workflows/django-audit-wazuh/badge.svg)\n[![codecov](https://codecov.io/gh/peppelinux/django-audit-wazuh/branch/main/graph/badge.svg)](https://codecov.io/gh/peppelinux/django-audit-wazuh)\n![pypi](https://img.shields.io/pypi/v/django-audit-wazuh.svg)\n![Python version](https://img.shields.io/badge/license-Apache%202-blue.svg)\n![Django versions](https://img.shields.io/pypi/djversions/django-audit-wazuh)\n![License](https://img.shields.io/badge/python-3.7%20%7C%203.8%20%7C%203.9-blue.svg)\n\nAuditing app, simple as possible, to have a good logging system for security purpose.\nYou'll have a json file able to be processed by a SIEM like Wazuh or OSSEC.\n\nFeatures\n- Login, logout and bruteforce attempts.\n\nTodo\n- Other critical django.security messages, needs more testing with sane unit tests.\n\nSetup\n-----\n\n````\npip install django-audit-wazuh\n# or\npip install git+https://github.com/peppelinux/django-audit-wazuh.git\n````\n\nConfiguration\n-------------\n\nIn `settings.py`:\n\n1. add 'auditing' in `INSTALLED_APPS`\n2. add a Middleware as follows (not mandatory!)\n3. configure a logging as follows\n\n````\n# requests headers auditing\nif 'auditing' in INSTALLED_APPS:\n    MIDDLEWARE.append('auditing.middlewares.HttpHeadersLoggingMiddleware')\n#\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'formatters': {\n        'default': {\n            # exact format is not important, this is the minimum information\n            'format': '%(asctime)s %(name)-12s %(levelname)-8s %(message)s',\n        },\n        'detailed': {\n            'format': '[%(asctime)s] %(message)s [(%(levelname)s)] %(args)s %(name)s %(filename)s.%(funcName)s:%(lineno)s]'\n        },\n        'json': {\n            'format': '{\"timestamp\": \"%(asctime)s\", \"msg\": %(message)s, \"level\": \"%(levelname)s\",  \"name\": \"%(name)s\", \"path\": \"%(filename)s.%(funcName)s:%(lineno)s\", \"@source\":\"django-audit\"}'\n        },\n    },\n    'filters': {\n        'require_debug_false': {\n            '()': 'django.utils.log.RequireDebugFalse'\n        }\n    },\n    'handlers': {\n        'mail_admins': {\n            'level': 'ERROR',\n            'filters': ['require_debug_false'],\n            'class': 'django.utils.log.AdminEmailHandler'\n        },\n        'file': {\n            'formatter': 'json',\n            'level': 'DEBUG',\n            'class': 'logging.handlers.RotatingFileHandler',\n            'filename': './django_siem.log',\n            'maxBytes': 1024000,\n            'backupCount': 3,\n        },\n        'console': {\n            'formatter': 'detailed',\n            'level': 'DEBUG',\n            'class': 'logging.StreamHandler',\n        },\n    },\n    'loggers': {\n        'django.security': {\n                'handlers': ['console', 'file'],\n                'level': 'DEBUG',\n                'propagate': False,\n        },\n        'django.request': {\n            'handlers': ['console', 'file'],\n            'level': 'DEBUG',\n            'propagate': True,\n        },\n        'django.contrib.auth': {\n            'handlers': ['console', 'file'],\n            'level': 'DEBUG',\n            'propagate': True,\n        },\n        'django.db.backends': {\n            'level': 'ERROR',\n            'handlers': ['console', 'file'],\n            'propagate': True,\n        },\n        'auditing': {\n            'handlers': ['console', 'file'],\n            'level': 'INFO',\n            'propagate': True,\n        },\n    }\n}\n\n````\n\nResults\n-------\n\nYou'll get a file with all the relevant events in json format, like\n\n````\n{\"timestamp\": \"2020-04-21 13:05:01,238\", \"msg\": \"Django Login failed\", \"username\": \"dsfsdf\", \"url\": \"http://localhost:8000/gestionelogin/?next=/gestione\", \"data.srcip\": \"127.0.0.1\", \"path\": \"/gestionelogin/?next=/gestione\", \"Content-Length\": \"132\", \"Content-Type\": \"application/x-www-form-urlencoded\", \"Host\": \"localhost:8000\", \"User-Agent\": \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0\", \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\", \"Accept-Language\": \"en-US,en;q=0.5\", \"Accept-Encoding\": \"gzip, deflate\", \"Origin\": \"http://localhost:8000\", \"Connection\": \"keep-alive\", \"Referer\": \"http://localhost:8000/gestionelogin/?next=/gestione\", \"Cookie\": \"csrftoken=pTG3UCHtiE0q4PNectVIH4hbezbqL2O2tvWx97rY8zwOxigSzG9unl2tqELzMhpM; cookieconsent_status=dismiss\", \"Upgrade-Insecure-Requests\": \"1\", \"level\": \"WARNING\",  \"name\": \"auditing\", \"path\": \"__init__.py.login_failed_logger:23\", \"@source\":\"django-audit\"}\n{\"timestamp\": \"2020-04-21 13:05:33,521\", \"msg\": \"Django Login successful\", \"username\": \"wert\", \"url\": \"http://localhost:8000/gestionelogin/?next=/gestione\", \"data.srcip\": \"127.0.0.1\", \"path\": \"/gestionelogin/?next=/gestione\", \"Content-Length\": \"131\", \"Content-Type\": \"application/x-www-form-urlencoded\", \"Host\": \"localhost:8000\", \"User-Agent\": \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0\", \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\", \"Accept-Language\": \"en-US,en;q=0.5\", \"Accept-Encoding\": \"gzip, deflate\", \"Origin\": \"http://localhost:8000\", \"Connection\": \"keep-alive\", \"Referer\": \"http://localhost:8000/gestionelogin/?next=/gestione\", \"Cookie\": \"csrftoken=pTG3UCHtiE0q4PNectVIH4hbezbqL2O2tvWx97rY8zwOxigSzG9unl2tqELzMhpM; cookieconsent_status=dismiss\", \"Upgrade-Insecure-Requests\": \"1\", \"level\": \"INFO\",  \"name\": \"auditing\", \"path\": \"__init__.py.login_logger:16\", \"@source\":\"django-audit\"}\n{\"timestamp\": \"2020-04-21 13:05:36,582\", \"msg\": \"Django Logout successful\", \"username\": \"wert\", \"url\": \"http://localhost:8000/gestionelogout/\", \"data.srcip\": \"127.0.0.1\", \"path\": \"/gestionelogout/\", \"Content-Type\": \"text/plain\", \"Host\": \"localhost:8000\", \"User-Agent\": \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0\", \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\", \"Accept-Language\": \"en-US,en;q=0.5\", \"Accept-Encoding\": \"gzip, deflate\", \"Connection\": \"keep-alive\", \"Referer\": \"http://localhost:8000/gestione\", \"Cookie\": \"csrftoken=e50mIQ4NWKYjDKBKA9a1iFufQuRv2W8LKAWnIjm4meXhiCSWPHzxfkrllMeNVqDR; cookieconsent_status=dismiss; sessionid=cxu3hfono6t6p1dl70q80836pe292ri3\", \"Upgrade-Insecure-Requests\": \"1\", \"level\": \"INFO\",  \"name\": \"auditing\", \"path\": \"__init__.py.logout_logger:30\", \"@source\":\"django-audit\"}\n````\n\nTuning\n------\n\nAuditing Middleware can log everything between a http request and its following response.\nThese are the overloadable settings variables\n\n````\n# for i in http.HTTPStatus: print(i, i.value)\nAUDIT_RESPONSE_HTTPCODES = getattr(settings,\n                                   'AUDIT_RESPONSE_HTTPCODES',\n                                   [i.value for i in http.HTTPStatus if i not in (200,201,202,301,302)])\n\n# prevents to read the password in clear\nAUDIT_REQUEST_POST_IGNORED = ('password', )\n````\n\n\nWazuh configuration\n-------------------\n\n1. Copy the content of `wazuh-ruleset/27081-django_decoders.xml` in `/var/ossec/etc/decoders/local_decoder.xml`\n\n2. Copy the content of `wazuh-ruleset/27081-django_rules.xml` in `/var/ossec/etc/rules/local_rules.xml`.\n\n3. Test the triggers with `/var/ossec/bin/ossec-logtest`, copy a log line in stdin and see events.\n\n4. Create an agent group called `django`\n   ````\n   /var/ossec/bin/agent_groups -a -g django\n   ````\n5. Edit agent group configuration `/var/ossec/etc/shared/django/agent.conf` this way\n   ````\n   \u003clocalfile\u003e\n        \u003clocation\u003eABSOLUTE_PATH_TO_YOUR_DJANGO_AUDIT_LOG.json\u003c/location\u003e\n        \u003clog_format\u003ejson\u003c/log_format\u003e\n        \u003clabel key=\"@source\"\u003edjango-audit\u003c/label\u003e\n   \u003c/localfile\u003e\n   ````\n6. Add agents to this group\n   ````\n   /var/ossec/bin/agent_groups -a -i 014 -g django\n   ````\n7. Control when they are synced\n   ````\n   /var/ossec/bin/agent_groups -S -i 014\n   ````\n8. Restart Wazuh-manager to reload rulesets `service wazuh-manager restart`\n\n\nGeoIP\n-----\n\nOn wazuh-manager, edit /usr/share/filebeat/module/wazuh/alerts/ingest/pipeline.json adding the new IP field inside processors, along the other Geolocation fields:\n````\n    {\n      \"geoip\": {\n        \"field\": \"srcip\",\n        \"target_field\": \"GeoLocation\",\n        \"properties\": [\"city_name\", \"country_name\", \"region_name\", \"location\"],\n        \"ignore_missing\": true,\n        \"ignore_failure\": true\n      }\n    },\n````\n\nWe now need to delete the current pipeline. In Kibana, go to Dev Tools clicking on the Wrench icon. Then execute the following:\n````\nDELETE _ingest/pipeline/filebeat-7.6.2-wazuh-alerts-pipeline\n````\n\nWe restart Filebeat in wazuh-manager:\n````\nsystemctl restart filebeat\n````\n\nLicense\n-------\n\nApache 2.0\n\n\nAuthors\n-------\n\nGiuseppe De Marco \u003cgiuseppe.demarco@unical.it\u003e\n\n\nCredits\n-------\n\nGarrlab Wazuh SIEM crew\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeppelinux%2Fdjango-audit-wazuh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeppelinux%2Fdjango-audit-wazuh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeppelinux%2Fdjango-audit-wazuh/lists"}