KrzysztofDeveloper i infrastruktura Kontakt

Cześć, jestem Krzyś.

Jestem full-stack developerem z Crystal Lake w stanie Illinois. Prowadzę projekt od pierwszego szkicu aż po serwer Linux, na którym działa, a potem to ja pilnuję, żeby nie padł. Teraz prowadzę kilka platform webowych, aplikację mobilną dostępną w Google Play i parę serwerów gier, a do tego failover i zabezpieczenia, dzięki którym to wszystko działa.

Mogę pracować zdalnie i mówię po angielsku i po polsku.

Portret Krzysztofa Śliwińskiego

Czym się teraz zajmuję

  • Przebudowuję panel Oddology i portal klienta, po jednym małym etapie. Każdy etap jest sprawdzony i ma przetestowane wycofanie zmian, zanim wyjdzie.
  • Przenoszę nasze sekrety dwuskładnikowe do szyfrowanego przechowywania i podnoszę koszt hashowania haseł. Jest to przetestowane i właśnie wchodzi na produkcję.
  • Uczę się podstaw sieci do CCNA i robię coraz więcej praktycznego bezpieczeństwa.
  • Szukam pracy w inżynierii IT, backendzie albo jako developer z naciskiem na bezpieczeństwo, zdalnie lub w okolicach Chicago.

Co zbudowałem

Wszystko tutaj działa i korzystają z tego prawdziwi ludzie. Jeśli chcesz dłuższą wersję, otwórz kartę, a zobaczysz, jaki był problem, co zbudowałem, na czym to działa i jak wyszło.

Przegląd panelu Oddology na danych testowych: podsumowanie dnia, otwarte odpowiedzi, znalezione leady, faktury do opłacenia i lista zadań na dziś

Panel Oddology i portal klienta

Na tym działa moja agencja. Klienci, projekty, umowy, płatności i strony są w jednym miejscu, a klienci mają własny portal, w którym sprawdzają swoją stronę i faktury.

Problem

Praca dla klientów była rozrzucona po arkuszach, mailach i kilkunastu panelach hostingowych. Klient nie miał jednego miejsca, żeby sprawdzić swoją stronę albo faktury.

Co zbudowałem

Panel w Node i React oraz portal klienta na wspólnym backendzie. Zmiany uprawnień działają prawie od razu, także u osób, które są już zalogowane. Do tego umowy i płatności Stripe, analityka respektująca zgody z eksportem do PDF i XLSX, monitoring integralności stron, automatyczne kopie zapasowe i obsługa domen.

Na czym działa

Node.js, Express 5, React 19, SQLite, Socket.IO, Stripe, PM2, Apache

Jak wyszło

Na nim działa cała firma na co dzień i korzystają z niego płacący klienci. Redesign wchodzi teraz sprawdzonymi etapami.

Zrzut LifeLogr ze Sklepu Play z napisem Grow a plant by caring for yourself (wyhoduj roślinę, dbając o siebie), za darmo na zawsze, bez paywalla, na tle rośliny i dziennych wskaźników z ekranu głównego (dane demonstracyjne) Zrzut LifeLogr ze Sklepu Play z napisem Log meals with ease (łatwe zapisywanie posiłków), na tle dziennika jedzenia z kaloriami i makro (dane demonstracyjne)

LifeLogr

Moja aplikacja do śledzenia zdrowia i stylu życia, napisana we Flutterze i dostępna w Google Play. Jedzenie, treningi, sen, waga, dziennik, spiżarnia i zakupy są w jednej aplikacji.

Problem

Miałem dość paywalli w MyFitnessPal i tego, jak bardzo się rozrosło, a każda inna aplikacja, którą próbowałem, przytłaczała mnie pierwszego dnia. Więc postanowiłem zbudować taką, jakiej sam chciałem używać.

Co zbudowałem

Liczenie kalorii i makro, skaner kodów kreskowych, AI, które odczytuje etykiety wartości odżywczych ze zdjęcia, dziennik treningów z rekordami, wnioski i cele, spiżarnia i listy zakupów oraz powiadomienia, które dopasowują się do tego, co ktoś faktycznie zapisuje. Multimedia idą z moich własnych serwerów, z zapasową kopią.

Na czym działa

Flutter, Dart, Riverpod, Firebase, Node media server, Google Play

Jak wyszło

Jest na produkcji w Google Play, a nowe wersje dość często wypuszczam najpierw przez testy otwarte. Jestem jedynym programistą.

lifelogr.net
Panel FieldLedger na danych demonstracyjnych zmyślonej firmy: przychody, koszty, płace i zaległości, wykres przychodów i kosztów z 12 miesięcy, ostatnie zlecenia i otwarte faktury

FieldLedger

Faktury, płace i ewidencja dla klienta z branży zarządzania nieruchomościami. Zastąpiło to 50-zakładkowy arkusz Excela, na którym pracowały trzy firmy.

Problem

Wszystkie trzy firmy działały na tym jednym arkuszu. Zlecenia, faktury i płace wpisywano ręcznie, a jedna zła edycja mogła zepsuć księgowość tak, że nikt by tego nie zauważył.

Co zbudowałem

Jedno logowanie dla trzech firm. Zlecenia zapisują w terenie, faktury PDF wysyłają mailem i SMS-em, śledzą płatności, liczą płace z bieżącymi sumami dla każdego pracownika i widzą przychody i koszty w panelu. Całość jest typowana od początku do końca, dane są sprawdzane wszędzie, gdzie wchodzą, a nic nie jest kasowane na stałe, więc historii finansowej nie da się wymazać.

Na czym działa

React, TypeScript, Vite, Tailwind, Express, Drizzle, SQLite, Twilio, PDFKit

Jak wyszło

Wystartowało w kwietniu 2026. Zrobiłem to najpierw pod telefon, żeby działało z auta, i nadal to utrzymuję.

Strona Snake River Retail

Snake River Retail

Strona operatora mikromarketów. Przeniosłem ją z Wix i przebudowałem jako kod, który właściciel naprawdę posiada, z backendem w Express.

Problem

Miał stronę z kreatora, której nie mógł rozbudować, i nie miał jak zrobić głosowań klientów i konkursów, których chciał.

Co zbudowałem

Własny front plus backend w Express do głosowań i konkursów, strony z kodami QR na ekran obok lodówki, logowanie administratora z hashowanym hasłem, maile transakcyjne i panel administracyjny, który obsługuje sam.

Na czym działa

Node.js, Express, bcrypt, Nodemailer, Apache, PM2

Jak wyszło

Ponad 760 odwiedzających w pierwszym roku, a strona jest zaindeksowana i widoczna lokalnie.

snakeriverretail.com
Strona TSC PM Co.

TSC PM Co.

Strona firmy zajmującej się pielęgnacją trawników i nieruchomości, zbudowana wokół galerii zdjęć przed i po z ich prawdziwych zleceń.

Problem

Robią świetną robotę i nie mieli gdzie pokazać jej w sieci.

Co zbudowałem

Zaprojektowałem i zbudowałem ją od zera, bez szablonu. Jest w niej galeria, formularze kontaktowe, SEO i znaczniki schema, strona z ofertą najmu oraz kampanie Google i Facebook, które kierują na nią ludzi. Hostuję ją i utrzymuję na moich serwerach.

Na czym działa

HTML, CSS, JavaScript, schema.org, Apache, Google and Meta Ads

Jak wyszło

Ponad 312 odwiedzających w pierwszym roku, a strona jest zaindeksowana i widoczna lokalnie.

tscpm.com

Feudline

Feudline to serwer Minecraft z frakcjami, który prowadzę. Gracze łączą się w drużyny, zajmują teren, budują power i rajdują się nawzajem, a całą tę rozgrywkę obsługuje jeden plugin w Javie, który napisałem sam. Ma około 45 000 linii.

Wyróżnia go sezon. Nie działa według kalendarza. Każdy wykopany blok i każdy zadany cios zasila jeden licznik dla całego serwera, a świat przechodzi do kolejnego etapu, kiedy gracze włożą w niego dość pracy. Do tego na serwerze nic nie jest sprzedawane za prawdziwe pieniądze, więc nikt nie może kupić sobie przewagi.

Frakcje i teren

Frakcje z rangami i uprawnieniami dla każdej rangi, sojusze, rozejmy i wrogowie, claimy, power i rajdy, a do tego domy frakcji, warpy, bank, skarbce i ulepszenia.

Ekonomia i eventy

Waluta ze sklepem i domem aukcyjnym, nagrody za głowy graczy, walki KOTH i Envoye, czyli zrzuty zaopatrzenia o ustalonych porach.

Rozwój postaci

Umiejętności, które rozwijasz po prostu grając, każda z własnym drzewkiem cech, własne enchanty, kity, rangi i perki oraz rytuały Vein, które frakcje odblokowują swoją częścią sezonu.

Narzędzia serwera

Kanały czatu i czat frakcji, poczta, narzędzia moderacji i więzienie, kosmetyki, takie jak nicki, zwierzaki i cząsteczki, oraz framework GUI oparty na ekwipunku, na którym stoi każde menu.

Problem

Najpierw spróbowałem typowych zestawów pluginów. Ciągle gryzły się ze sobą, a ja nie mogłem ich razem zbalansować ani dopasować do gry, którą naprawdę chciałem prowadzić.

Co zbudowałem

Więc zrobiłem jeden plugin do wszystkiego, oparty na frameworku GUI z ekwipunku, który sam napisałem, żeby każde menu działało tak samo. Konfiguracja przeładowuje się na żywo, więc mogę wrzucać zmiany balansu bez wyrzucania kogokolwiek z serwera. Celowo usunąłem też system skrzynek, bo w praktyce był lootboxem.

Na czym działa

Java, Paper / Bukkit API, LuckPerms, Vault, YAML and JSON persistence, systemd on Ubuntu

Jak wyszło

Ponad 200 klas, około 45 tys. linii i ponad 20 systemów rozgrywki. Jestem jedynym programistą.

Serwery pod tym wszystkim

Każda strona i aplikacja z tej strony działa na serwerach Linux, które sam stawiam i utrzymuję. Cel jest dość prosty: jeden serwer może paść, a odwiedzający nie powinni tego zauważyć.

Architektura hostingu Odwiedzający trafiają na pływający adres przez DNS Cloudflare. Adres zwykle wskazuje główny serwer WWW. Gorąca rezerwa jest z niego cały czas synchronizowana. Osobny monitor sprawdza serwer główny co dziesięć sekund i w razie awarii przenosi adres na rezerwę. Nocne kopie zapasowe trafiają na inny serwer. Odwiedzający DNS Cloudflare Pływający IP Główny serwer WWWstrony, aplikacje, media Gorąca rezerwate same aplikacje, wstrzymane synchronizacja Monitor i kopie zapasowesprawdza co 10 s, trzyma nocne kopie
10 smiędzy kontrolami stanu
~42 sna przełączenie w prawdziwym teście, który zrobiłem
5 minmiędzy synchronizacjami plików i baz z rezerwą
Co nockopie zapasowe, wysyłane na osobny serwer

Serwer główny i gorąca rezerwa

Jeden serwer obsługuje wszystko. Rezerwa co kilka minut kopiuje jego pliki i migawki baz danych, a co godzinę certyfikaty i konfiguracje stron. Aplikacje na rezerwie są skonfigurowane, ale zatrzymane, więc nie rozjeżdżają się i nie uruchamiają zaplanowanych zadań dwa razy.

Automatyczny failover

Trzeci serwer sprawdza główny co dziesięć sekund. Jeśli ten nie przejdzie trzech kontroli z rzędu, monitor wywołuje API mojego dostawcy hostingu, przenosi pływający adres na rezerwę i uruchamia jej aplikacje. Gdy główny wraca, wszystko wraca na niego. Jeśli padnie sam monitor, rezerwa przejmuje ruch tylko wtedy, gdy nie może połączyć się z żadnym z pozostałych dwóch.

Błąd, który to ukształtował

Tego nauczyłem się na własnej skórze. Przez sześć dni dwa moje serwery odpowiadały na ten sam adres i prawie nic nie wyglądało źle. To, że strona się ładuje, nie mówi, który serwer odpowiedział. Teraz rutynowa kontrola sprawdza, że ten adres trzyma dokładnie jeden serwer.

Co dostaje każdy serwer

SSH tylko na klucze, zapory, które domyślnie wszystko blokują, fail2ban, automatyczne aktualizacje bezpieczeństwa i ograniczone logi. Każdy projekt ma też własne, ograniczone konto zamiast jednego wspólnego konta administratora.

Poprawki bezpieczeństwa, które zrobiłem

To prawdziwe problemy z bezpieczeństwem, które znalazłem i naprawiłem w systemach, które utrzymuję. Każda poprawka wyszła z testami, próbnym przebiegiem i wycofaniem, które wcześniej przećwiczyłem. Szczegóły celowo zostawiłem ogólne.

Kontrola dostępu w portalu klienta

Zanim zabrałem się za redesign portalu klienta, zrobiłem mu audyt. Znalazłem sprawdzanie dostępu do konta, które porównywało zły identyfikator, i kilka akcji, które w ogóle nie sprawdzały roli użytkownika. Jest naprawione i działa.

Co znalazłem

Izolację między kontami, która w niektórych konfiguracjach mogła zawieść, akcje kasujące i rozliczeniowe dostępne dla każdego członka, tymczasowe hasła pokazywane osobie, która wysłała zaproszenie, oraz skrypty firm trzecich ładowane z publicznych CDN bez przypiętych wersji.

Co zmieniłem

Poprawiłem sprawdzanie kont, dodałem kontrolę roli do każdej akcji kasującej i rozliczeniowej, przestałem odsyłać tymczasowe hasła, dodałem limit resetów hasła i przeniosłem portal na proces budowania z przypiętymi zależnościami, które hostuję sam. Testy regresji używają tylko fałszywych użytkowników.

Szyfrowane sekrety 2FA i mocniejsze hashowanie

Sekrety dwuskładnikowe i kody zapasowe leżały w bazie jawnym tekstem. Poprawka szyfruje je albo hashuje i nie psuje nikomu logowania. Jest przetestowana i właśnie wchodzi na produkcję.

Co znalazłem

Sekrety aplikacji uwierzytelniających zapisane jawnym tekstem, kody zapasowe z generatora losowego, który nie jest przeznaczony do zabezpieczeń, jednorazowe kody z maili zapisane dokładnie tak, jak je wpisano, i koszt hashowania haseł, który trzeba było podnieść.

Co zmieniłem

Każdy sekret 2FA dostaje szyfrowanie z uwierzytelnieniem i kluczem, który zostaje na serwerze, plus identyfikatory kluczy, żeby dało się je później zmienić. Kody zapasowe i jednorazowe idą z bezpiecznego generatora i zapisywane są tylko ich hashe. Wyższy koszt hashowania włącza się po cichu przy następnym logowaniu. Migracja ma tryb próbny i wycofanie, które odszyfrowuje wszystko z powrotem, i przetestowałem oba.

Walidacja ścieżek w wewnętrznym endpoincie

Wewnętrzny endpoint dla zespołu budował ścieżkę do pliku z parametru w adresie i go nie sprawdzał. Realne ryzyko było niskie, ale i tak to naprawiłem, a poprawka działa.

Co znalazłem

Parametr zawsze generuje serwer, ale nic tego tak naprawdę nie wymuszało, a framework dekoduje zakodowane ukośniki, zanim handler w ogóle je zobaczy.

Co zmieniłem

Teraz parametr musi mieć dokładnie wygenerowany format, każda rozwiązana ścieżka musi zostać w swoim katalogu, a testy obejmują próby przejścia katalogów zakodowane raz i dwa razy. Zapisałem też uczciwą ocenę wagi problemu z uzasadnieniem, zamiast robić z niego coś gorszego, niż był.

Maskowanie adresów IP odwiedzających

Ekran analityki maskował proste adresy IPv4, ale łańcuchy proxy i adresy IPv6 pokazywał w całości, na ekranie i w eksportach CSV. Jest naprawione i działa.

Co znalazłem

Maskowanie obsługiwało tylko jeden kształt adresu. Wszystko inne, na przykład listy przekazane przez proxy albo IPv4 zapisane jako IPv6, przechodziło bez zmian.

Co zmieniłem

Zastąpiłem je funkcją, która obsługuje każdy wpis na liście, IPv6, porty i adresy mapowane, i buduje wynik z odczytanych liczb zamiast kopiować dane wejściowe. Surowe adresy nigdy nie trafiają na ekran ani do eksportów.

Nie wymieniam tu żadnych systemów klientów i żaden opis nie zawiera szczegółów ataku. Chętnie omówię każdy z nich na rozmowie.

Rzeczy, które robię dla frajdy

Infamy

Wieloosobowa gra o piratach w Unreal Engine 5, wciąż w budowie. Ocean zbudowałem sam: fale Gerstnera pochodzą z jednego źródła prawdy, z którego czytają i fizyka, i GPU, są zsynchronizowane z czasem serwera, a statki unoszą się dzięki sondom wyporności.

C++, Unreal Engine 5.5

Horror SMP

Prywatny serwer Minecraft z modami dla moich znajomych. Ma około 46 modów, własny modpack, który sam się aktualizuje przy starcie, i generowanie świata, które stroiłem tak długo, aż ciężkie mody biomów przestały go wywracać.

Fabric 1.20.1, Linux, systemd

OddoBot

Bot na Discorda z osobnymi instancjami produkcyjną i deweloperską, własnym węzłem audio i API połączonym ze Stripe do płatnych funkcji.

Node.js, discord.js, Lavalink, Stripe, PM2

Fledgerly

Aplikacja do finansów osobistych dla mnie i kilku znajomych. Ma synchronizację z bankiem, import wyciągów, wykrywanie subskrypcji i prognozy wypłaty netto, które są sprawdzane z prawdziwymi paskami wypłat.

Next.js, TypeScript, Prisma, SQLite, Auth.js

Rooted

Aplikacja do pielęgnacji roślin, którą wciąż planuję. Jest zbudowana wokół mapy domu, bo myślę, że ludzie pamiętają swoje rośliny po tym, gdzie stoją, a nie po nazwach.

Flutter, Firebase

Ta strona

Zwykły HTML, CSS i trochę JavaScriptu, bez frameworka. Ma jasny i ciemny motyw oraz polską wersję.

HTML, CSS, JavaScript

Z czym pracuję

Języki

JavaScript i Node, TypeScript, Java, Dart, Python, C++ i C#, SQL, Bash

Frontend

React, Flutter, HTML i CSS, systemy projektowe, dostępność

Backend i dane

Express, SQLite, PostgreSQL, Firebase, Stripe, uwierzytelnianie i dostęp oparty na rolach

Infrastruktura i IT

Ubuntu, Apache, PM2, systemd, Let's Encrypt, Cloudflare, Active Directory, Okta, Microsoft 365

Gdzie pracowałem

  1. Współzałożyciel i full-stack developer, Oddology LLC

    od 2023

    Zbudowałem i prowadzę platformę agencji, strony klientów i serwery, na których stoją.

  2. Technik aktualizacji Windows, Power Construction (kontrakt)

    wrzesień do październik 2025

    Przeniosłem ponad 120 pracowników z Windows 10 na 11 w ciągu jednego miesiąca.

  3. Technik IT I, AIT Worldwide Logistics (kontrakt)

    październik 2024 do luty 2025

    Po przejęciu firmy kolejka w ServiceNow liczyła kilka tysięcy zgłoszeń. Pomogłem zejść poniżej 100, zamykając 400 do 500 zadań miesięcznie, i zajmowałem się zakładaniem i usuwaniem kont w Active Directory, Okta i Microsoft 365.

  4. Informatyka

    Southern Illinois University, McHenry County College

    Zrobiłem też podstawy testów penetracyjnych na TryHackMe i uczę się sieci Cisco do CCNA.

Pełne CV i PDF
Krzysztof stojący pod drzewem w letni wieczór

Trochę o mnie

Zainteresowałem się informatyką, bo zobaczyłem, jak mój tata programuje w Pythonie i Ruście, i pomyślałem, że wygląda to naprawdę świetnie, a od tamtej pory on wciągnął mnie na dobre. Zacząłem od budowania stron internetowych i nauki olcPixelGameEngine, i poznałem naprawdę świetną społeczność wokół olc. Potem przeszedłem na Pythona, C++, C, Javę, Reacta i inne.

Szczerze mówiąc, większości tego, co umiem, nauczyłem się, bo potrzebowałem, żeby coś działało. Zacząłem budować rzeczy, których jeszcze nie było, i z tego wyrosła firma, platforma SaaS, aplikacja mobilna, serwer gry pełen własnych systemów i mała grupa serwerów Linux, które utrzymuję online.

Lubię mieć cały projekt w swoich rękach. Czyli zrozumieć problem, zaprojektować interfejs, postawić działający backend, wdrożyć go i być tym, do kogo przychodzi alert, gdy coś się zepsuje. Praca w korporacyjnym IT nauczyła mnie nudnych, ale ważnych rzeczy, takich jak kontrola dostępu, czyste ślady audytowe i nie psucie produkcji. Na co dzień korzystam z narzędzi AI, tak samo jak z każdego innego narzędzia.

Mówię po angielsku i po polsku. Poza pracą dla klientów nadal robię rzeczy dla frajdy, na przykład grę o piratach, serwery z modami dla znajomych i narzędzia, których używam na co dzień.

Napisz do mnie

Napisz do mnie

Czy chodzi o pracę, zlecenie, czy po prostu chcesz pogadać o technologii, napisz tutaj, a wiadomość trafi prosto do mojej skrzynki. Zwykle odpowiadam w ciągu dnia lub dwóch.

Twojej wiadomości używam tylko po to, żeby odpowiedzieć. Żadnych newsletterów i żadnego śledzenia.