Przejdź do głównej zawartości

2. Podstawowa pułapka

Mając już przygotowany folder ze źródłem definicji pułapki, możemy rozpocząć pracę nad właściwą logiką pułapki.

Nasza pułapka będzie napisana w języku Python z wykorzystaniem biblioteki Flask, i zakładana jest tutaj podstawowa znajomość tego języka.

wskazówka

Przygotowując odpowiedni Dockerfile, możemy pisać naszą pułapkę w dowolnym języku programowania - jak np. JavaScript, C# czy PHP.

requirements.txt

Na początku musimy utworzyć plik requirements.txt, w którym zapiszemy wszystkie wymagane do działania pakiety Python. Nasz Dockerfile korzysta z tego pliku, aby zainstalować te zależności w obrazie pułapki.

Możemy go wygenerować następującymi komendami (wymagany jest zainstalowany Python 3.10):


# Tworzymy venv i wchodzimy do niego
$ python -m venv env
$ source ./env/bin/activate
# Instalujemy Flask
$ pip install Flask
# Zapisujemy requirements.txt
$ pip freeze > requirements.txt

Jeśli nie mamy zainstalowanego Python'a, możemy ręcznie utworzyć plik requirements.txt z następującą zawartością:

click==8.1.3
Flask==2.2.2
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.2
Werkzeug==2.2.2

Podstawowy kod źródłowy pułapki

Następnie, możemy napisać minimalny kod pułapki. Będzie on uruchamiał serwer HTTP i zwracał tekst po wejściu na ten serwer.

Utwórz w folderze plik app.py z następującą zawartością:


from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return "Hello world! The trap is working :)"

if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0', port=80)

Testowe uruchomienie pułapki

Mając już kod źródłowy pułapki, możemy testowo uruchomić ją za pomocą docker compose. Pułapka tak uruchomiona nie będzie poprawnie komunikowała się z panelem TrapInit (ponieważ nie posiada odpowiedniej konfiguracji ustawianej przez TrapInit), ale takie uruchomianie jest pomocne w trakcie pisania pułapki, aby uniknąć czasochłonnego budowania i wysyłania pułapki aby uruchomić ją w TrapInit.

Aby poprawnie uruchomić pułapkę w taki sposób, musimy pamiętać o ustawieniu zmiennej środowiskowej TRAP_EXPOSE_PORT na port, na którym ma się uruchomić pułapka. Ta zmienna jest automatycznie ustawiana podczas uruchamiania poprzez TrapInit, ale przy uruchamianiu z docker compose musimy ją ustawić ręcznie.


TRAP_EXPOSE_PORT=8080 docker compose up --build

Po wykonaniu powyższej komendy możemy wejść w przeglądarce na adres http://localhost:8080 i zobaczyć odpowiedź od naszej pułapki.

Odpowiedź od pułapki

Budowanie definicji

Aby zbudować definicję którą możemy uruchomić w TrapInit, na początku musimy zbudować i wyeksportować obrazy używane przez nasza pułapkę. W naszym przypadku jest to jeden obraz - my-tutorial-trap, ale należy pamiętać że eksport obrazów musi zawierać wszystkie obrazy używane w docker-compose.yml - także te pobierane z Docker Hub lub innych rejestrów.

Na początku, budujemy nasze obrazy zdefiniowane w docker-compose.yml


docker compose build

Następnie, zapisujemy wszystkie zdefiniowane w docker-compose.yml obrazy do images.tar:


docker save -o images.tar my-tutorial-trap

Powyższa komenda tworzy plik images.tar, który jest określony w polu imagesPath w trapdef.json. Obrazy z tego pliku będą ładowane do sensora przez TrapInit w trakcie uruchamiania pułapki.

Mamy już wszystkie pliki potrzebne do utworzenia definicji pułapki. Tworzymy więc końcową definicję za pomocą zip:


zip my-trap.zip trapdef.json images.tar docker-compose.yml

wskazówka

Aby zbudować definicję od nowa, musimy wykonać powyższe komendy ponownie. Możemy ułatwić sobie pracę, tworząc skrypt wykonujący te komendy.

Uruchomienie pułapki w TrapInit

Utworzony plik zip dodajemy jako definicję pułapki w panelu TrapInit, za pomocą przycisku "+":

Adding definition

Adding definition

Adding definition

Po dodaniu naszej definicji, możemy ją uruchomić jak każdą inną pułapkę:

Running definition