Strona główna » Informatyka

Kategoria: Informatyka

Zamiast SMTP można użyć API

Konfiguracja SMTP z różnych przyczyn nie zawsze jest łatwa i przyjemna a serwery linuksowe, które zwykle służą za fundament zapewniający pewne usługi, kryją wiele niespodzianek. Ostatnio zdecydowałem się nie walczyć więcej ze starymi rozwiązaniami tylko spróbować czegoś nowego i podpiąć kilka WordPressów pod zewnętrzne usługi mailowe obsługiwane poprzez dedykowane API. Dla wielu takich usługi istnieją gotowe wtyczki, ja użyłem WP Mail SMTP od WPForms, która w swojej darmowej wersji ma obsługę usługi Sendinblue. A znowuż a usługa w swojej darmowej wersji zapewnia 300 emaili dziennie, co jest wystarczające do potrzeb tych konkretnych WordPressów, a dodatkowo oferuje multum funkcjonalności związanych z np. analityką czy prowadzeniem kampanii. Jeżeli jest potrzeba, można wygodnie przejść na płatne subskrypcje lub wykupić za niewielkie pieniądze zwiększenie limitu maili.

Podłączenie Sendinblue za pomocą wskazanej wtyczki okazało się być banalne – wkleja się tylko klucz API i koniec. WordPress po prostu wysyła maile beż żadnych problemów. W samej usłudze można ewentualnie dokonfigurować domeny, nadawców, adresy IP, jeżeli jest taka potrzeba – i dzieje się to przez bardzo przyjazny interfejs.

Praca konfiguracyjna jest nieporównywalnie mniejsza, niż borykanie się z fochami linuxów, firewalli, urządzeń brzegowych, SELinuxa itp. a zyskuje się mnóstwo dodatkowych funkcjonalności.

Polecam.

Proszę nie szkalować PHP

Ten wpis jest kopią archiwalną z moich postów i komentarzy na pewnym wyjątkowym forum dla społeczności IT, na którym publikuję żarty, urządzam prowokacje, dzielę się refleksjami. Generalnie dokuczam kolegom i koleżankom z branży, inspiruję dyskusje i kłótnie.

Gdy ktoś szkaluje PHP wklej mu tzw. tarczę PHP:

Nieracjonalni i zabobonni informatycy

Ten wpis jest kopią archiwalną z moich postów i komentarzy na pewnym wyjątkowym forum dla społeczności IT, na którym publikuję żarty, urządzam prowokacje, dzielę się refleksjami. Generalnie dokuczam kolegom i koleżankom z branży, inspiruję dyskusje i kłótnie.

#1

Wiele razy o tym wspominałem, ale chyba nikt tego nie brał na poważne: informatycy są BARDZO zabobonnymi ludźmi którzy dodatkowo mają skłonności do mocnego konformizmu. Jakby tego było mało, świat tworzenia oprogramowania takiego konformizmu oczekuje i go wspiera i buduje się na mitach, zabobonach, dziwacznych poglądach. Wręcz podstawowa różnica między seniorem a juniorem jest taka, że ten pierwszy posiadł zdolność odnalezienia się w każdym dziwnym zestawie mitów i na bagnistym podłożu irracjonalności jest w stanie skutecznie budować software. Istotny jest konformizm, bo ten zapewnia sukces teamu. Jeżeli team ma wspólne bożki technologiczne, rytuały, konwencje, to odniesie sukces choćby nawet miał pisać w BASICu używając polecenia COME FROM. No i gdy dodamy do tego wysokie zarobki to informatycy zaczynają wierzyć, że oni posiedli jakąś zdolność „wygrywania życia” i że można rozciągać to ich wadliwe postrzeganie na wszystko, na całe życie i całą ludzkość. Otoczenie często to widzi zupełnie jasno, że to jakiś rodzaj zwichrowania osobowości, którego jednak lepiej nie leczyć bo przynosi złote jaja do domu.

To komiczne, gdy spotyka się takiego buńczucznego informatyka, że co to nie on i w ogóle indywidualista i wszystko zna i wie, a tu nagle zaczyna gadać głupoty że tylko taki standard, taka konwencja, uznane praktyki, jedynie słuszne rozumienie xD a potem w tym samym duchu zacznie mówić o polityce, życiu, sporcie, diecie xD najgorsi są chyba fizycy-informatycy, moje zdanie na ich temat niektórzy mogli poznać z komentarzy z ostatniego tygodnia.

#2

Intro: (…) wszyscy się boją napisać cokolwiek nietypowego bo że niby ktoś się na nich się krzywo spojrzy. Ale jak trzeba się kłócić o zabobony typu SOLID, DRY, KISS, jakieś konwencje i pseudo-standardy to do gardła by się rzucili.

Intro 2: (…) branża IT to jest takiego, co każdemu może namieszać w głowie. Spójrz na programistów – niektórzy zaczynają wierzyć w zupełnie irracjonalne zabobony tylu SOLID, DRY, KISS i inne. Albo przedkładają jakieś języczki programowania typu Pajton, Rdzewiej czy Idź ponad inne. No jak dzieci po prostu. No więc IT ma w sobie cos takiego, co ludziom w głowach po prostu miesza i zatracają rzeczywistość. Nie trzeba się wówczas złościć tylko delikatnie, empatycznie takie osób wysłuchać, rozmawiać z nimi, pomóc im odnaleźć prawdziwe przyczyny ich odczuć, wierzeń, skłonności. Nie należy odrzucać albo traktować złością, albo traktować suchą racjonalnością. Rozmowy warto zacząć od wyrażenia tego jak bardzo doceniamy wrażliwość drugiej osoby, jej zapał, jej zaangażowanie, przejęcie.

Intro 3: (…) niektórzy ludzie zamiast akceptować lub odrzucać jakieś zjawiska w sposób irracjonalny – jak Ty to robisz – wolą wykonywać eksperymenty, pomiary itp. Nie każdy opiera się na zdaniu innych czy kieruje konformizmem. Naturalnie, takie cechy nie są pożądane w IT, więc nie jestem zaskoczony, że ich nie posiadasz. IT to siedlisko wielu zabobonów: SOLID, DRY, KISS, separation of concerns i wiele, wiele innych, które nigdy nie przeszły rygorystycznych eksperymentów. Liczy się jednakże nie to, co jest prawdą, ale to, co jest spójne z działaniem danego programistycznego teamu. Zgrany team zrealizuje projekty informatycznie sprawnie choćby nie wiem jak dziwaczne przyjął konwencje i kultywował poglądy.

Otóż te moje odwołania do SOLID, KISS, DRY oraz innych praktyk w wielu moich komentarzach dotyczą tego, że pewne standardy, dobre praktyki i konwencje egzystują w informatyce od lat a czasami dekad, lecz nie wynikają one z niczego innego niż wiary. Nigdy nie udowodniono ich skuteczności w sensie rygorystyczno-naukowym. Dopiero ostatnie lata sprawiły, że zaczęto robić rygorystyczne eksperymenty, prowadzić pomiary i inne takie, aby zrobić z software developmentu dyscyplinę naukową opartą o dowody, evidence-based. I okazało się, że nic nie trzyma się kupy. Wedle mojej wiedzy nie udało się konkluzywnie potwierdzić skuteczności ŻADNEGO z informatycznych przekonań. Gdy piszę „konkluzywnie” to mam na myśli, że kolejne badania przynosiły sprzeczne rezultaty. Czasami eksperyment wykazał, że jakaś praktyka jest super-skuteczna, aby po chwili ten sam eksperyment przeprowadzony gdzie indziej wykazał, że ona w ogóle nie działa. Zaczęto to analizować, w wielu przypadkach zaproponowano interesujące hipotezy. No ale jeżeli jesteś tego ciekawy to punktem wyjścia jest Google Scholar a najlepiej dostęp do płatnych naukowych baz danych.

Wiem, że to co opisuje, może szokować. Ja sam byłem tym ogromnie zaskoczony, w ogóle się tego nie spodziewałem. W swojej osobistej praktyce programistycznej stosuje rozmaite podejścia, których się wyuczyłem przez lata, które weszły mi w krew i miałem je dobrze zracjonalizowane, wyjaśnione, cały światopogląd ułożony od A do Z. Jestem przy tym dosyć skutecznym programistą, więc mógłbym zapytać: czy byłbym tak skuteczny gdyby nie to, że stosuje te skuteczne podejścia?

Jeżeli badania były do czegoś zgodne, to do tego, że cechą charakterystyczną doświadczonych programistów w odróżnieniu od początkujących jest to, że przez lata nauczyli się był skuteczni niezależnie od swoich przekonań, praktyk, konwencji. Czasami nawet wtedy, gdy cos jest niezgodne z tym jak funkcjonuje mózg – przykładem jest stosowanie konwencji nazewniczej camelCase. Ona aktualnie UTRUDNIA sprawne działanie mózgu, co można bardzo obrazowo i łatwo wykazać w eksperymentach z eye trackingiem, nie trzeba do tego robić żadnych wielkich teorii. Okazuje się jednak, że mózgi seniorów programowania dostosowały się do pracy w takich warunkach i są równie skuteczni jak juniorzy na zgodnej z działaniem mózgu konwencji snake_case.

Takich dziwnych doniesień trochę jest i będzie więcej, bo dopiero teraz się rozwija ten obszar badań i stosowane są coraz lepsze narzędzia pomiarowe.

Albo weźmy DRY. Częstą miarą jakości kodu jest istnienie w nim najmniejszej ilości duplikatów. Kod, który ma ich wiele nazywany jest WET i od dekad zaleca się walkę z nim poprzez stosowanie zasady DRY podając szereg powodów dla których tak jest lepiej. Badania jednakże nie wykazały tego, aby było „lepiej” cokolwiek to „lepiej” miałoby znaczyć. Badano gigantyczne zbiory kodu, wielkie repozytoria, wieloletnie historie commitów i nie wykazano jakoby DRY przynosiło mniej bugów, mniej modyfikacji, podnosiło jakość czegokolwiek. Za to zwiększało liczbę późniejszych działań odwrotnych: duplikowania kodu, aby tworzyć jego specjalizowane warianty. Czyli że DRY tak naprawdę bywa zwodniczą przedwczesną optymalizacją i stratą czasu. Badano też repozytoria osób, które nie stosowały DRY i nie odnaleziono niczego, co by wskazywało, że tam było gorzej lub lepiej niż z DRY. Zaproponowano wiele hipotez czemu tak jest, polecam szukać w literaturze.

Ten motyw powtarza się. Badacze biorą pod lupę praktykę X i okazuje się zazwyczaj, że:

  1. To w ogóle działa ALBO
  2. To działa, ale w 95% tylko wtedy gdy stosuje to senior, którego mózg przez lata na przekór wszystkiemu się sam przeprogramował ALBO
  3. To działa, ale tylko w mikroprojekcikach o niewielkim albo żadnym skomplikowaniu.

Ale bardziej istotne jest co innego. Sukcesy ZESPOŁÓW programistów okazują się w ogóle nie zależeć od przyjętych przez nich praktyk i konwencji a jedynie od zgrania i lojalności wobec tych praktyk. Zwycięstwo nie jest więc w prawdziwości tego w co wierzycie, ale w tym, że wierzycie razem, co czyni Wam skuteczną platformę współdziałania umysłów.

Zmierzam do tego, że deweloperzy często gorliwie wyznają fałszywe bożki i paradoksalnie największe mohery-seniory są skuteczni MIMO trwania w fałszu. Można przejść na życie w prawdzie i rozpoznać, że bożki to tylko fikcja, która może być użyteczna jako pewien fundament komunikacyjny, ale nic ponadto. I coraz więcej osób tak robi.

Prawda o skutecznym software developmencie prawdopodobnie do nas dopiero nadejdzie wraz z rozwojem inżynierii oprogramowania bazowanej na dowodach. Najpewniej z jej zdobyczy najmocniej skorzystają nasze dzieci, które nie będą musiały sobie wykrzywiać mózgu, ale będą programować w zgodzie z jego naturalnym ukształtowaniem. Na tę chwilę jednak społeczność IT generalnie brodzi w ciemnocie, którą ma za oświecenie.

Programowanie a oderwanie od podstaw

Niedawno czytałem wątek na Facebooku, w którym ktoś zapytał specjalistów od informatyki czy byliby w stanie sami zbudować od podstaw te różne urządzenia, z którymi pracują. Odpowiedzi były różne. Poczyniliśmy tak duży postęp techniczny, że niektórym się wydaje, że owszem, zrobią hurtownię danych, ale już pojedynczy tranzystor to kosmiczna technologia. Innymi słowy, specjalizacja, abstrakcja i miniaturyzacja oderwały niektórych profesjonalistów od źródeł ich zawodów. I nie ma w tym nic dziwnego, taki jest porządek rzeczy.

W programowaniu też widać zjawisko pewnego oderwania od podstaw, ale ma ono związek z dopasowaniem narzędzi pracy do umysłu pracującego. Weźmy na przykład kolorowanie składni. Jest tak powszechne i tak pomocne, że jej wyłączenie wprawić niektórych może w zakłopotanie, może wywołać poczucie zagubienia. Tymczasem dawniej często tak się pisało kod. I w dalszym ciągu w wielu przypadkach kod przychodzi pisać po dawnemu, gdy trzeba coś na szybko zmienić na serwerze z linii poleceń a tam czeka nas niedokonfigurowany edytor vi o niecodziennych skrótach klawiszowych.

Warto chyba przypomnieć, że programowanie nie tylko jest możliwe, ale jest całkiem wydajne w takich warunkach jak zwykły notepad. Czarno-białe litery, brak obsługi tabulatorów, brak podpowiedzi, brak podręcznego drzewa plików. To tylko przyzwyczajenia się zmieniły.

Jest to ważne także i dlatego, że wiele osób bardzo poważnie taktuje dzisiaj temat doboru narzędzi. Preferują pewne określone IDE czy określony program do administracji bazą danych oraz mają wyobrażenie takie, że te programy są niebywale złożone i koniecznie trzeba stosować te szczególnie wybrane.

Tymczasem ani nie ma takiej konieczności, ani te programy nie są szczytem złożoności. Wiele z nich można napisać samemu i w życiu programisty przychodzi taki moment, że zmuszony okolicznościami tworzy on np.:

  • Własne IDE
  • Własne webowe IDE
  • Własnego klienta SQL do administacji bazą
  • Własnego klienta GIT
  • Własnego klienta SSH, SCP, FTP
  • Własnego shella

Ze zdumieniem można wówczas odkryć, że podstawowe funkcjonalności tego oprogramowania da się wykonać w zaskakująco małych ilościach linii kodu. Te zaś przyrastają dopiero wtedy, gdy chce się wygładzić i wyspecjalizować określone obszary.

(W dawniejszych czasach nie było to rzadkością chcieć pisać własny system operacyjny, bo ludzie dzięki powszechności dyskietek i możliwości podglądu kodu BIOS-u mieli wiedzę o bootsectorach, systemach plików, zarządzaniu pamięcią. Dzisiaj to już jest wiedza nieco zapomniana.)

Użycie certyfikatów Let’s Encrypt do wielu serwisów na zwykłym hostingu

Wprowadzenie

Kiedyś pisałem o tym jak można dla serwisów umieszczonych na zwykłych hostingach WWW używać darmowych certyfikatów Let’s Encrypt. Procedura jest jednak żmudna, nudna i trzeba ją powtarzać co kilka miesięcy, co dla kogoś, kto utrzymuje wiele serwisów a nie tylko jeden, jest dosyć nużące. Jeżeli jednak wciąż nie chcemy iść w kierunku zakupu płatnych certyfikatów, to rozwiązaniem jest uruchomienie tzw. reverse proxy na tanim serwerze wirtualnym. Wyjaśnijmy sobie to po kolei.

Najtańsze płatne certyfikaty są obecnie na rynku za około 10 zł. Jeżeli ktoś opiekuje się 10 serwisami internetowymi, które są umiejscowione ma zwykłym hostingu na którym nie można w sposób zautomatyzowany korzystać z darmowych certyfikatów, to musi wydać 100 zł rocznie na certyfikaty. Nie jest to duża kwota a kłopotu jest troszeczkę mniej.

Innym rozwiązaniem jest wykupienie na rok taniego serwera wirtualnego. Ich oferta w Internecie jest spora a mówimy tutaj o wersji naprawdę bardzo ubogiej, bo wymagającej 1 procesora wirtualnego, około 5 GB miejsca dyskowego, od 512 do 1024 MB RAM. Można takie kupić płacąc za rok około 110 zł, czyli wiele więcej niż za certyfikaty – a stajemy się bogatsi o serwer VPS!

Przygotowanie VPSa

W moim przypadku zamówiłem serwer z systemem operacyjnym CentOS 8, aby móc na nim uruchomić skrypt konfiguracyjny, który rozwijam i którego kod jest w repozytorium na GitHub:

curl -s -L http://grzegorzkowalski.pl/install/ | bash

Skrypt będzie wykonywał wiele działań i zada kilka pytań. Odpowiedź „Y” należy udzielić na te:

  • Enable Apache [default port 80 and 443] ? [y/N]
  • Change timezone to Europe/Warsaw? [y/N]
  • Enable FirewallD ? [y/N]

Po tym wszystkim dostaniemy serwer z Apache’m i mnogością różnych użytecznych narzędzi (m.in. PHP 7.4, Python 2/3, NPM, Node.js, Composer, Certbot, wget, GIT). Nas interesuje głównie Apache, którego możemy skonfigurować w tryb reverse proxy.

Tworzymy sobie nowy plik konfiguracyjny do tego celu i jeżeli nasz hosting ma adres 123.123.123.123 to piszemy tak.:

vi /etc/httpd/conf.d/moje_proxy.conf

Wypełniamy go treścią:

<VirtualHost *:80>
ServerName grzegorzkowalski.pl
ServerAlias www.grzegorzkowalski.pl
ServerAlias kolejnyserwis.pl
ServerAlias innyserwis.pl
ServerAlias jeszczeinny.pl
ServerAlias itakdalej.pl
# ...
ServerAlias az_do_ostateniego.pl

DocumentRoot "/var/www/html/proxy"
ServerAdmin grzegorz.adam.kowalski@outlook.com

<Directory "/var/www/html/proxy">
DirectoryIndex index.php
AllowOverride All
Require all granted
</Directory>

ProxyPreserveHost On
ProxyPass / http://123.123.123.123:80/
ProxyPassReverse / http://123.123.123.123:80/
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RequestHeader set X-Forwarded-SSL expr=%{HTTPS}
</VirtualHost>

W pliku konfiguracyjnym odwołujemy się do folderu, którego jeszcze nie ma, więc warto go stworzyć:

mkdir /var/www/html/proxy

Teraz w panelu konfiguracyjnym hostingu znajdźmy edycję stref DNS i zmieńmy we wszystkich domenach wskazanych w powyższym pliku konfiguracyjnym numer IP przypisany do tzw. rekordu „A” na adres IP naszego serwera VPS.

Gdy to wszystko jest gotowe, zresetujmy Apache na serwerze wirtualnym, aby nowa konfiguracja weszła w życie. W zależności od systemu może to wymagać trochę innego polecenia, na moim CentOS wygląda to tak:

service httpd restart

No i teraz przed nami zagadnienie wygenerowania certyfikatów. W systemie powinien już być zainstalowany i gotowy do użycia skrypt:

certbot-auto

Należy postępować zgodnie z pytaniami, które będą pojawiać się na ekranie a wynikiem będą wygenerowane certyfikaty, lekko rozszerzony plik konfiguracyjny Apache, który wcześniej stworzyliśmy oraz dodatkowo zostanie stworzony drugi plik konfiguracyjny przeznaczony tylko dla ruchu szyfrowanego na porcie 443.

Gdy WordPress odmawia współpracy

Teraz proxy jest już sprawne, certyfikaty również są zrobione. To,co jeszcze może nas spotkać to zaskoczenie, gdy np. nasz serwis oparty o WordPress odmówi posłuszeństwa a przeglądarka internetowa zwróci komunikat „Too many redirects” czyli „zbyt wiele przekierowań”.

Jak się okazuje, twórcy WordPressa zaszyli jedną ważną informację w instrukcji do tego systemu. W pliku wp-config.php należy ręcznie dopisać w dowolnym miejscu dwie linie kodu:

if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';

Debugowanie zbyt wielu przekierowań

Jeżeli problem „Too many redirects” pojawia się pomimo odpowiedniej konfiguracji takiego czy innego systemu, warto zbadać zjawisko pomocniczym skryptem (jest to zmodyfikowana wersja tego skryptu):

#!/bin/bash
echo
for domain in $@; do
  echo --------------------
  echo $domain
  echo --------------------
  curl -sILk $domain | egrep 'HTTP|Loc|X-Redirect-By: ' | sed 's/Loc/ -> Loc/g'
  echo
done

Skrypt używamy np. tak:

skrypt-do-przekierowan.sh grzegorzkowalski.pl

W wyniku skryptu zobaczymy serię nagłówków HTTP wskazujących na typ przekierowania, docelowe miejsce przekierowania oraz kto zlecił przekierowanie. W przypadku np. WordPressa wyświetli się np. „WordPress 7.4.3”. Jest to informacja, że przyczyna problemu leży nie w konfiguracji Apache, nie w jakimś zabłąkanym pliku .htaccess na hostingu, ale np. w pluginie WordPressowym do obsługi HTTPS albo właśnie w braku wpisu w wp-config.php.

Dekodowanie base64 o zmienionym alfabecie

Serwis pewnej znanej państwowej instytucji zwraca sam dla siebie dane za pomocą interfejsu typu API REST, ale zwraca jest w postaci kodowanej. Wynik zaczyna się mniej więcej tak:

{"d":"enc!331aa1bb!45!3!!49!32!50!381ab1a7!45y25!45yy91b9y23yy4y1y1a1y231a2!391a1y...."}

No i zagadaka – co to jest i jak to odczytać? Skoro przeglądarka potrafi, to znaczy to, że gdzieś w skryptach strony jest dekoder. No rzeczywiście znajdujemy skrypt, który jednakże zdaje się być sam sobie również zaszyfrowany, jego początek wygląda tak:

eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c])}}return p}('o a=["\b\d\b","\b\b\i","\b\b\j","\b\b\l","\b\b\s","\b\b\N","\b\b\m","\b\b\D","\b\b\z","\b\i\B","\b\i\b","\b\i\i","\b\i\j","\b\i\l","\b\i\s","\b\i\N","\b\i\m","\b\i\D","\b\i\z","\b\j\B","\e\j\e","\e\j\i","\e\j\j","\e\j\l","\e\j\s","\e\j\N","\e\j\m","\e\j\D","\e\j\z","\e\l\B","\e\l\e"

Początek „function packed” jest charakterystyczny dla standardowych zaciemniaczy kodu. Da się to względnie odszyfrować, jest wiele deszyfratorów online, np. https://freeseotool.org/javascript-unpacker.

Po deszyfracji wciąż nie jest łatwo. Zmienne mają dziwaczne nazwy, a tablice mają zwartości zapisane za pomocą kodów szesnastkowych. To ostatnie to drobiazg, bo jeżeli mam taką dziwną tablicę…

var _0xeae2=["\x79\x31\x79","\x79\x79\x32","\x79\x79\x33","\x79\x79\x34","\x79\x79\x35","\x79\x79\x36","\x79\x79\x37","\x79\x79\x38","\x79\x79\x39","\x79\x32\x30","\x79\x32\x79","\x79\x32\x32","\x79\x32\x33","\x79\x32\x34","\x79\x32\x35","\x79\x32\x36","\x79\x32\x37","\x79\x32\x38","\x79\x32\x39","\x79\x33\x30","\x21\x33\x21","\x21\x33\x32","\x21\x33\x33","\x21\x33\x34","\x21\x33\x35","\x21\x33\x36","\x21\x33\x37","\x21\x33\x38"

…to wystarczy są wrzucić w przeglądarkowy console.log i dostanę zwrot danych w ludzkiej postaci:

["y1y", "yy2", "yy3", "yy4", "yy5", "yy6", "yy7", "yy8", "yy9", "y20", "y2y", "y22", "y23", "y24", "y25", "y26", "y27", "y28", "y29", "y30", "!3!", "!32", "!33",

Hmm, znowu jakiś kod? Może, aczkolwiek jeżeli wrócimy do pierwotnej zaszyfrowanej wiadomości, to dostrzeżemy, że składała się właśnie z takich elementów. Wygląda więc to na jakiegoś rodzaju alfabet. W alfabecie nie ma jedynie początkowego trzyliterowego „enc”, które widać w danych zawracanych przez API, więc pewnie to jakiś taki rozpoznawczy ciąg znaków (zapewne pochodzący od „encoded” – zakodowany).

Wróćmy jednak na chwilę do nazw. Nazwy zmiennych są kodowane, ale nazwy funkcji nie – są takie jak kiedyś były. Znajdujemy w skrypcie cztery:

  • tajemnicza funkcja „bd”,
  • pospolicie brzmiąca „getIndex”,
  • pospolicie brzmiąca „addslashes”,
  • i pozornie pospolicie brzmiąca „_ut8_decode” – pozornie, bo ten underscore na początku jest nietypowy.

Wykorzystując ów nietypowy underscore możemy poszukać w Google, czy to nie jest jakaś znana funkcja. Jak się okazuje, istnieje tylko jeden skrypt, który zawiera tę funkcję oraz „addSlashes” i „getIndex” – to pochodzący z http://www.webtoolkit.info skrypt JS realizujący dekodowanie znaków „zakodowanych” algorytmem Base64.

No i faktycznie wydaje się, że to jest nasz skrypt, ale coś się nie zgadza. W oryginalnym skrypcie w jednym miejscu jest coś zupełnie inaczej. Zamiast tego dziwnego alfabetu wskazanego wcześniej jest zwyczajny alfabet o taki:

_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

Hmm, czyżby więc programiści z państwowej naszej instytucji jedynie podmienili alfabety?

Sprawdźmy! Fragment zakodowanego tekstu bez początkowego „enc” wrzucamy w zmienną „test”, podmieniamy alfabety i dekodujemy base64…

<?php
// fragment kodowanej wiadomości bez początkowego 'enc'
$test = '!331aa1bb!45!3!!49!32!50!381ab1a7!45y25!45yy91b9y23yy4y1y1a1y231a2!391a1y25y30!39!45y22yy3y20y29!36!33!401b8!38!471a0!52!38!491bb!45y25!45yy9171!35y29yy2!5!!39!49!32!49y26y29!40!53!35!34!36!44!391aby241a1!37!34yy21a3y25!49y28!44!38!49!32y27!381aby20!52!36!34y201a9!3!yy7!321bb!38!50!48y29!35!34yy21b8!39!50y27!5!!34yy3yy91b9y23yy4y1y1a1y231a2!391a1y25y30!40!39yy9!451a0!39yy9!47y28!44!38!49!32y29!35!34yy21b8!39!50y28y27!39!49yy61aa!38!49yy6y27!40!33y201bb!34yy3yy91bbyy9yy4y1y!52y251a1!39173y23yy4y1y1b9y23!46y231aay23!46!471aay26yy61b91b8!35y301a7!45y22yy3y20!3!!4!!34y1y!45y25!45y20y27yy9!451b9!45y30!49yy61a9!401abyy5!45y25!45y20y27!32!3!y20y23y29!3!y24!37y30!47yy5!43!3!1a4!52y22y30171!33yy2y27y29yy2y27y301a3y28y30!32yy5yy6!34y301a4!40yy2yy9yy51a8y29y22!46yy9!43y29!3!1a31b7y30!3!!48y22y30171!33yy2y27!3!!52yy2yy9yy51bay26!3!yy5!32y29y30!47!48y22y27y29yy2!34yy9yy6y24!37!33!3!y30yy6!43!3!172!34y271a4!3!!45y22yy3y20!34!381ab!52!48!401ab172!47!4!!50y281aa!381a1yy91a9yy9!471a4yy2!33!47172!34y29!3!!32yy4y291a3!48yy6yy9!451b9!45!3!yy71721aa!37!33yy61a3yy9!46!5!!45!391aa!521a8!36y23!33yy3!381aa!40!52!36!33y241b4!37y29yy91bbyy9!47!401ba!37!331a8!44yy9!46!5!!45!3!1aa!521a8!36y23!33yy3!381aa!40!52!36!33y23!45y22yy3y20y22!381aby28y27!381aby241a9!40yy71721aa!4!y29yy91a9yy9!46yy91aby22y30!3!1b9y23yy3yy91bbyy9';

$key = ["y1y", "yy2", "yy3", "yy4", "yy5", "yy6", "yy7", "yy8", "yy9", "y20", "y2y", "y22", "y23", "y24", "y25", "y26", "y27", "y28", "y29", "y30", "!3!", "!32", "!33", "!34", "!35", "!36", "!37", "!38", "!39", "!40", "!4!", "!42", "!43", "!44", "!45", "!46", "!47", "!48", "!49", "!50", "!5!", "!52", "!53", "1b4", "1bb", "1ba", "1b7", "1b8", "1b9", "1a0", "1a1", "1a2", "1a3", "1a4", "1ab", "1aa", "1a7", "1a8", "1a9", "170", "171", "172", "173", "174", "17b", "71a"];

$original = str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");

$pairs = [];

for ($i = 0; $i < 65; $i++) {
    $pairs[$key[$i]] = $original[$i];
}

echo base64_decode(strtr($test, $pairs));

…sprawdźcie sami, że wynik wygląda tak:

[{"Regon":"000237297","RegonLink":"<a href='javascript:danePobierzPelnyRaport(\"000237297\",\"DaneRaportPrawnaPubl\", 0);'>000237297<\/a>","Typ":"P","Nazwa":"PUBLICZNA SZKOŁA PODSTAWOWA NR.2 IM.MIKOŁAJA KOPERNIKA W SZYDŁOWCU","Wojewodztwo":"MAZOWIECKIE","Powiat":"szydłowiecki","Gmina":"Szydłowiec","KodPocztowy":"26-500",

Czyli sukces! 🙂

Przy okazji wyjaśnia się nazwa jednej z funkcji w skrypcie: „bd” to po prostu „base64_decode”.

Na koniec kilka pytań: po co właściwie te dane są kodowane? Przecież owa instytucja udostępnia informację publiczną. Jaki jest sens utrudniania korzystania z API? Tu nie ma żadnych tajemnic przecież. Mogą pojawić się dane osobowe, ale zwyczajnie podlegają pod RODO jeżeli ktoś chciałby na nich zbijać pieniądze.

Nie wiem po co takie dziwne utrudnienia. Dodatkowo, dane zwracane powyższym kodowaniem są objętościowo większe. Nie tylko dlatego, że base64 standardowo zwiększa objętość, ale i dlatego, że użyto alfabet o „literach” złożonych z wielu znaków.

Prosta metoda blokowania SPAMu z formularza kontaktowego

W jednym z projektów, w których brałem udział, jeden z formularzy kontaktowych był źródłem licznego SPAM-u pochodzącego od internetowych botów. Z różnych przyczyn nie chcieliśmy instalować żadnych dodatkowych modułów czy wtyczek ani też nie chcieliśmy komplikować formularza stosując CAPTCHA czy coś podobnego. Postanowiliśmy wypróbować pewne proste rozwiązanie. Po wielu miesiącach stosowania mogę powiedzieć, że nasza prosta metoda się bardzo dobrze sprawdziła.

W formularzu dodałem dwa pola typu „hidden” o nazwach „fullname” oraz „password”. Fullname jest polem pustym i niewidocznym – żywy użytkownik nigdy nie wprowadzi tu żadnej wartości. Wiele botów wpisze tutaj jednak wygenerowane imię i nazwisko. Na tej podstawie już można wyciąć trochę ruchu. Prosta pułapka.

Pole „password” ma jednak wartość: to zakodowany timestamp. Zakodowany odwracalnie, bo w kontrolerze jego wartość jest odzyskiwana i porównywana z czasem na serwerze. Jeżeli różnica jest większa niż pewien ustalony czas, system zakłada, ze wiadomość pochodzi od człowieka, bo ten – w odróżnieniu od komputerowego bota – potrzebuje czasu, aby napisać wiadomość.

Innymi słowy, cały ów antyspamowy filtr składa się z:

  • dwóch ukrytych pól input,
  • jednego większego IFa w kontrolerze.

Co zaskakujące, ten banalny system zdaje się działać niemal w stu procentach. Sytuacje, w których coś zostało przepuszczone (albo niesłusznie zatrzymane) są jednostkowe.

Dostęp do wyszukanych osób w planie bezpłatnym MyHeritage

MyHeritage, zgodnie z prawem, nie chroni danych osób zmarłych. Natomiast w wynikach wyszukiwania („zbadaj osobę”) po kliknięciu na link do profilu osoby zmarłej wyświetlony zostanie monit o zakup płatnego abonamentu i nie ma sposobu, aby go ominąć – brak jakiegoś przycisku „Pomiń”, „Zamknij” czy „Przejdź do osoby”. Taki sposób MyHeritage ma na zdobywanie części klientów. Kto jednak używał MyHeritage przez dłuższy czas, ten wie, że do tych profili istnieje link dostępowy, bo różnymi drogami można do tych osób dotrzeć i czasami sam serwis go podpowiada. Taki link można również wytworzyć bazując na wynikach wyszukiwania. Poprawnie skonstruowany będzie miał on postać taką:

https://www.myheritage.pl/person-X_Y_Z/

Gdzie X to numer osoby, a Y i Z to numer witryny oraz drzewa (zazwyczaj często ten sam, nie zajmowałem się ustaleniem który jest który).

Tymczasem w wynikach wyszukiwania są linki typu:

https://www.myheritage.pl/FP/search-plans.php?s=103900133&colId=1&itemId=385852852-1-500030&indId=individual-103900133-7500002&rfr=tree

W powyższym linku interesujące nas dane są zawarte w „itemID”, czyli „385852852-1-500030”. Pierwsza liczba to jest nasze Y i/lub Z. Druga i trzecia liczba razem złączone dają X. Czyli działający link do osoby będzie taki:

https://www.myheritage.pl/person-1500030_385852852_385852852/

Zmienianie linków można sobie zautomatyzować do tzw. bookmarkletu, czy do postaci zakładki na pasku przeglądarki, której naciśnięcie przepisze wszystkie widoczne linki „search-plans” do „person”. Przykładowo, w przeglądarce Chrome należy z menu wybrać „Zakładki” i później „Menedżer zakładek”. W nowym widoku należy z menu wybrać „Dodaj zakładkę”. Można jej nadać jakąś nazwę, np. „Przepisz linki MyHeritage” i następnie w polu URL zamiast adresu WWW należy wprowadzić poniższy kod JavaScript (jest to jedna linia tekstu):

javascript:(function() { $('.record_link.recordTitle').each(function (i) { var result = /itemId=(\d+)-(\d+)-(\d+)/.exec(this.href); if (result) this.href = 'https://www.myheritage.pl/person-' + result[2] + result[3] + '_' + result[1] + '_' + result[1] +'/'; }) })();

Od tej pory kliknięcie w zakładkę w widoku wyszukiwania przepisze linki na prowadzące do osoby.

Powyższe to tylko przykład przepisujący linki do osób z drzew genealogicznych. MyHeritage wyświetla wyniki też i z innych źródeł i tam przepisywanie linku musiałoby działać inaczej.

Czasopisma policyjne w głębokiej sieci

Głęboka sieć to część Internetu, która nie jest indeksowana przez wyszukiwarki internetowe i tym samym pozostaje poza zasięgiem typowego Internauty. Niektóre czasopisma policyjne są elementem głębokiej sieci z przyczyn technologicznych – z jednej strony są one publicznie dostępne dla każdego poprzez oficjalną stronę Policji http://www.gazeta.policja.pl/ , ale z drugiej strony zakodowano je w formacie PDF z istotnymi utrudnieniami dla wyszukiwarek:

  • Te PDFy, które zawierają w sobie przeszukiwalny tekst, stosują bardzo dziwne kodowania znaków i rozbicia lub połączenia wyrazów, które są niewidoczne dla człowieka, ale skutecznie utrudniają pracę robotom wyszukiwarek;
  • Wiele PDFów zawiera po prostu skany starych czasopism a wyszukiwarki obecnie nie radzą sobie dobrze z taki treściami graficznymi (chociaż kiedyś sobie poradzą);

W związku z tym, chcąc przeszukiwać treść takich czasopism Internauta ma poważny problem – musi przeglądać wszystkie ręcznie. Do przeglądu ma 800+ numerów od 12 do 50 stron każde wydanie. Chodzi tutaj o czasopisma:

  • Policja 997,
  • Policja 997 wydanie specjalne,
  • Gazeta Policyjna,
  • Magazyn Kryminalny,
  • Patrol,
  • Wiadomości Sekcji Polskiej IPA,
  • Policja Łódzkie,
  • Przegląd Prewencyjny,
  • Stołeczny Magazyn Policyjny,
  • Kwartalnik Prawno-Kryminalistyczny,
  • Kwartalnik policyjny.

Częściowo można sobie z tym problemem poradzić i zbudować lokalną wyszukiwarkę lub wykorzystać jakiś dostępny mechanizm wyszukujący. Najpierw jednak trzeba wszystkie PDFy pobrać a następnie przetworzyć ich zawartość programem do optycznego rozpoznawania znaków (OCR) na poprawną tekstowo postać. Aby wspomóc pobieranie PDF-ów przygotowałem odpowiedni skrypt i zamieściłem w serwisie GitHub:

https://github.com/gakowalski/czasopisma-policyjne

Do pobrania skryptem jest 9+ GB danych.

Do OCR polecam NAPS2, które to oprogramowanie jest darmowe, obsługuje język polski i z tego, co sobie testowo uruchamiałem, to względnie radzi sobie z tymi PDFami. Do przetworzenia jest sporo, więc radzę uzbroić się w cierpliwość.

Wynik przetworzenia polecam zawrzeć również w pliki PDF, aby móc skorzystać z „Wyszukiwania zaawansowanego” w darmowym oprogramowaniu Adobe Reader.

Dlaczego nie przejmuję się wirusami komputerowymi

Wiele lat temu porzuciłem stosowanie programów antywirusowych i przejmowanie się wirusami. Było to jeszcze zanim nastała era systemów komputerowych z domyślnym podstawowym antywirusem takich jak współczesne Windowsy. Dlaczego od tego odszedłem? Powody były dwa:

  1. Zrozumiałem dobrze którędy wirusy mogą dostać się do mojego komputera i przyjąłem takie reguły pracy, aby nigdy nie stworzyć możliwości zarażenia.
  2. Zaobserwowałem, że programy antywirusowe są bardzo obciążające dla pracy komputera i bardzo często przeszkadzają w sprawnym działaniu systemu.

Warto zauważyć, że w pewnym momencie niektóre antywirusy same stały się „wirusowe” – obciążały komputer znacząco a instalowały się niemalże potajemnie (np. McAffee dołączany cichcem do Flasha). Pojawiły się też w pewnym momencie programy szpiegujące, które udawały narzędzia do usuwania tzw. malware i adware, czyli „złośliwego oprogramowania”.

Wszystkiemu temu postanowiłem powiedzieć: nie.

Jakie są podstawowe zasady, które przyjąłem, aby chronić się przed wirusami? Oto one:

  1. W systemie operacyjnym należy wyłączyć tzw. autoodtwarzanie, czyli automatyczne uruchamianie programów z dysków CD, USB, kart pamięci i innych.
  2. Nie używać nielegalnego oprogramowania albo oprogramowania z podejrzanego źródła. Kiedyś nielegalne oprogramowanie było dosyć powszechne, bo jakoś mentalnie my w Polsce nie mogliśmy się szybko przestawić na legalność. Dzisiaj w zasadzie do każdego zadania można znaleźć legalny, darmowy software i to jeszcze open-source. Ważne jest jednak to, aby pobierać taki software z sensownego źródła, czyli np. strony internetowej autora czy producenta a nie z jakieś dziwacznej domeny „pobieram24h-programooosy.pl”. Swoją drogą, gro wirusów dawniej przenosiło się w crackach do gier. Dzisiaj szczęśliwie świat się zmienił i ludzie nie chcą nawet legalnej gry, jeżeli nie jest podłączona do platformy typu Steam czy podobnej. Legalne i płatne oprogramowanie znalazło sposób na bycie atrakcyjniejszym niż nielegalne.
  3. Należy utrzymywać aktualne wersje oprogramowania. Nie tylko przeglądarek internetowych, ale też każdego, które ma związek z danymi pochodzącymi z sieci. Czyli: czytnik PDF-ów, arkusz kalkulacyjny, edytor tekstu.
  4. Należy mieć włączone wyświetlanie na rozszerzeń plików w systemie Windows. Jest to ważne, bo jeżeli szukamy dokumentu PDF albo Word a dostajemy plik z rozszerzeniem EXE, BAT, COM czy CMD, to od razu powinno to wzbudzić niepokój – rzekłbym nawet, że zwykły użytkownik powinien taki plik usunąć natychmiast. Znajomość rozszerzeń plików to istotna wiedza, warto ją nabyć i nie polegać na uproszczeniach, które w tym zakresie oferują niektóre systemy operacyjne i aplikacje.
  5. Należy pilnować się w Internecie. W szczególności dotyczy to chyba poczty elektronicznej i jej rozmaitych załączników. Po pierwsze, musimy widzieć rozszerzenia załączników i je oceniać tak jak przy zwykłych plikach. Po drugie, musimy ocenić źródło maila i samego maila. Czy źródło jest znane, podejrzane? Czy mail jest jakiś niespodziewany, niezamówiony, sensacyjny, nawołujący do podjęcia jakieś akcji typu „kliknij w link”, „otwórz załącznik”? Jeżeli tak, to należy mieć się na baczności.

To powyżej to są podstawowe zasady. Oprócz nich mam kilka bardziej technicznych trików polegających na wyłączaniu lub blokowaniu pewnych zaawansowanych możliwości systemu operacyjnego, aby utrudnić działanie takiego wirusowi-spryciarzowi, który by się jednak przedostał. Wydaje mi się jednak, że powyższe pięć zasad na czasy współczesne zupełnie wystarcza.

Kiedy być może warto mieć antywirusa? Gdy współdzielisz komputer z użytkownikami, którym nie można zaufać, którzy nie stosują się do wskazanych reguł bezpieczeństwa. Zamiast antywirusa można próbować ograniczyć uprawnienia tych osób, ale nie wydaje mi się, aby to było wystarczalne.