diff --git a/README.md b/README.md index 7ded1a2..43d04c6 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ PhishFlood is a python tool that uses playwright to automate the process of fill ## Demo -Example gif: -![](./output.gif) +Example page interaction: +![](images/output.gif) Example output: ```json @@ -111,10 +111,17 @@ PhishFlood will launch a Playwright browser instance in the background and start To start the API and all required componets (RabbitMQ, PostgreSQL and the workers) you can run: ```bash -docker compose -f docker/docker-compose.yml up --build +docker compose -f docker/docker-compose.yml --compatibility up --build ``` -The API will be running in `localhost:8000` and you can start exploring the different endpoints through the web UI. +The API will be running in `localhost:8000` and you can start exploring the different endpoints through the web UI: + +![Alt text](images/api_root.png) + +And here is a sample of one of the endpoints + +![Alt text](images/action_list.png) + ## Testing diff --git a/api/settings.py b/api/settings.py index d89b32f..94d8b2d 100644 --- a/api/settings.py +++ b/api/settings.py @@ -112,6 +112,7 @@ # https://docs.djangoproject.com/en/5.0/howto/static-files/ STATIC_URL = "static/" +STATIC_ROOT = BASE_DIR / "static" # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field diff --git a/api/urls.py b/api/urls.py index 3a83a15..2886e1e 100644 --- a/api/urls.py +++ b/api/urls.py @@ -1,8 +1,9 @@ from django.contrib import admin from django.urls import include, path from rest_framework import routers - +from api import settings from phishings import views +from django.conf.urls.static import static router = routers.DefaultRouter() @@ -23,6 +24,6 @@ path("", include(router.urls)), path("admin/", admin.site.urls), path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), -] +] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += router.urls diff --git a/config/nginx.conf b/config/nginx.conf new file mode 100644 index 0000000..4871122 --- /dev/null +++ b/config/nginx.conf @@ -0,0 +1,20 @@ +client_max_body_size 30m; + +upstream phishflood { + server api:8000; +} + +server { + listen 80; + + location /static/ { + alias /home/nonroot/api/static/; + } + + location / { + proxy_pass http://phishflood; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + } +} \ No newline at end of file diff --git a/docker/Dockerfile.nginx b/docker/Dockerfile.nginx new file mode 100644 index 0000000..0488c8f --- /dev/null +++ b/docker/Dockerfile.nginx @@ -0,0 +1,4 @@ +FROM nginx + +RUN rm /etc/nginx/conf.d/default.conf +COPY ./config/nginx.conf /etc/nginx/conf.d \ No newline at end of file diff --git a/docker/Dockerfile.worker b/docker/Dockerfile.worker index a43984f..b4fc409 100644 --- a/docker/Dockerfile.worker +++ b/docker/Dockerfile.worker @@ -40,4 +40,4 @@ RUN poetry run playwright install COPY --chown=nonroot:nonroot . /home/nonroot/$PROJECT_NAME # Entrypoint -CMD poetry run python -m phishflood \ No newline at end of file +CMD poetry run python -m phishflood worker \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 0dcd2a3..e00e785 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,27 +1,31 @@ version: '3.8' services: - # api: - # image: phishflood-api:latest - # build: - # context: ../ - # dockerfile: docker/Dockerfile.api - # depends_on: - # - rabbitmq - # - psql + api: + image: phishflood-api:latest + build: + context: ../ + dockerfile: docker/Dockerfile.api + depends_on: + - rabbitmq + - psql + ports: + - "127.0.0.1:8000:8000" - # worker: - # image: phishflood-worker:latest - # build: - # context: ../ - # dockerfile: docker/Dockerfile.worker - # cap_add: - # - NET_ADMIN - # devices: - # - /dev/net/tun - # depends_on: - # - rabbitmq - # - psql + worker: + image: phishflood-worker:latest + build: + context: ../ + dockerfile: docker/Dockerfile.worker + deploy: + replicas: 6 + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun + depends_on: + - rabbitmq + - psql rabbitmq: image: rabbitmq:3-management-alpine diff --git a/entrypoint.sh b/entrypoint.sh index 845dcfb..ede93e9 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -13,4 +13,4 @@ echo "Creating admin user..." echo "from django.contrib.auth.models import User; User.objects.filter(email='admin@phishflood.com').delete(); User.objects.create_superuser('admin', 'admin@phishflood.com', 'phishflood')" | poetry run python manage.py shell echo "Runnning gunicorn..." -poetry run gunicorn phishing_analyzer.wsgi:application -w 8 --bind 0.0.0.0:8000 \ No newline at end of file +poetry run gunicorn api.wsgi:application -w 8 --bind 0.0.0.0:8000 \ No newline at end of file diff --git a/images/action_list.png b/images/action_list.png new file mode 100644 index 0000000..528100c Binary files /dev/null and b/images/action_list.png differ diff --git a/images/api_root.png b/images/api_root.png new file mode 100644 index 0000000..8b3311a Binary files /dev/null and b/images/api_root.png differ diff --git a/output.gif b/images/output.gif similarity index 100% rename from output.gif rename to images/output.gif diff --git a/phishings/models.py b/phishings/models.py index 1b6de1b..97ad34a 100644 --- a/phishings/models.py +++ b/phishings/models.py @@ -6,7 +6,7 @@ class Phishing(models.Model): id = models.CharField( max_length=255, primary_key=True, default=None, editable=False ) - url = models.URLField() + url = models.URLField(max_length=512) created_at = models.DateTimeField(auto_now_add=True) def save(self, *args, **kwargs):