Google, he knows me

Dostałem maila od Google. Na stronie wykryto błędy, kod błędu 403. Sprawa mnie zaintrygowała. Co prawda chodziło tylko o jeden URL, ale czemu 403? Błędy 5xx czy 404 bym zrozumiał jeszcze, zwłaszcza na blogu, ale 403? Coś się tu zdecydowanie nie zgadza.

Rozpocząłem dochodzenie i zrobiło się dziwniej. Bowiem chodziło o zupełnie egzotyczny URL ( hxxps://zakr.es/tststs/ ). Na oko poprawny, ale ewidentnie tymczasowy i testowy. I zdecydowanie nie należący do bloga. W ogóle byłem zdziwiony, że Google o nim wie.

And he knows I’m right

Pierwsze co przyszło mi do głowy to robots.txt. Może dlatego, że sugerują sprawdzenie, czy dostęp nie jest tam blokowany? W każdym razie pudło. Zresztą nawet gdyby tam URL był, to raczej jako wykluczenie dla botów. A wtedy zgłaszanie braku dostępu byłoby sporą bezczelnością.

Zajrzałem do katalogu na serwerze i przypomniało mi się, że testowałem pewną rzecz. Powiedzmy, że okolice bug bounty. Tak, robienie tego na podstawowej domenie to zwykle kiepski pomysł, ale tym razem kluczowa miała być obecność naturalnego ruchu. Tak czy inaczej nic z tego nie wyszło, tj. nie udało mi się wykorzystać w planowany sposób. A katalog pozostał, choć już niewykorzystany. I nielinkowany.

Analiza

Google webmaster tools[1] pokazuje, skąd jest linkowana dana strona. W tym przypadku podał dwie strony na blogu. Jedną z konkretnym wpisem, drugą zbiorczą.

Strona odsyłająca
https://zakr.es/blog/author/rozie/page/6/
https://zakr.es/blog/2015/10/spis-wyborcow-a-rejestr-wyborcow/

Tyle, że w podglądzie źródła tego ostatniego wpisu to ja tego URLa w żaden sposób nie widzę.

Jak to wygląda czasowo? Kolejna ciekawostka to kolejne dwie daty w Google webmaster tools:

Data pierwszego wykrycia: 31.08.2022

Zapewne wtedy się bawiłem. Daty utworzenia plików potwierdzają – wszystkie pliki mają 03.08.2022. Ma to jakiś sens, tylko musiałbym zostawić pliki podlinkowane na miesiąc? Raczej niemożliwe, bo wtedy zostałyby na stałe. A nie ma. No i skąd by się wzięły w tak starym wpisie?

Ostatnie skanowanie 5 maj 2023, 11:47:16

To oczywiście możliwe, tym bardziej, że Google zauważyło błąd 403 dokładnie 3 maja 2023. Po ponad pół roku?

I’ve been talking to Google all my life

Jeśli chodzi o Google, to mamy love hate relationship. Z jednej strony doceniam firmę za GCTF, czy zabezpieczenia poczty i kont. Z drugiej strony to, co robią z prywatnością userów, nachalność reklam, tragiczny, scamerski content części reklam bąbelkowanie w wyszukiwarce i wreszcie samo bycie globalną korporacją mocno mnie odstręczają.

Ostatecznie jest tak, że umiarkowanie korzystam z ich usług. Trochę, bo wygodne, trochę, bo wypada znać. Mam webmaster tools, mam reklamy AdSense, ale tylko w wybranych miejscach. Pozwalam indeksować blog. Raczej nie korzystam z ich wyszukiwarki, tj. sięgam do niej tylko, jeśli nie znajdę wyników w podstawowej, czyli rzadko. Inne usługi Google, czyli np. Maps, Waze, translate, calendar, drive, docs – różnie, raczej korzystam, choć w ograniczonym stopniu.

Częściowe wyjaśnienie

Spojrzenie w logi serwera mówi nieco więcej:

66.249.65.223 - - [28/Aug/2022:20:35:53 +0200] "GET /tststs/ HTTP/1.1" 403 187 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
66.249.70.63 - - [30/Aug/2022:20:53:52 +0200] "GET /tststs/ HTTP/1.1" 403 187 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
66.249.64.227 - - [30/Apr/2023:22:32:01 +0200] "GET /tststs/ HTTP/1.1" 403 187 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.142 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
66.249.64.231 - - [03/May/2023:10:44:18 +0200] "GET /tststs/ HTTP/1.1" 403 187 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.142 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
66.249.64.229 - - [05/May/2023:11:47:16 +0200] "GET /tststs/ HTTP/1.1" 403 187 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.142 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

Część rzeczy się zgadza, np. wizyty kiedy Google zauważyło i zaindeksowało URL, po miesiącu od zamieszczenia plików. Widać też wizyty 03.05, kiedy sobie o nim ni stąd ni zowąd przypomniało. Mogło się też zdarzyć, że do testów wziąłem jakiś stary wpis z 2015.

Nadal nie zgadza się – albo nie mogę sobie przypomnieć – jak to się stało, że URL został na miesiąc, a nie został na stałe. I słodką tajemnicą Google pozostanie, czemu zapomniało o tym URLu na bite osiem miesięcy.

Usunąłem katalog z serwera. Może teraz Google, gdy dostanie 404, zapomni o nim na dobre?

[1] Obecnie Google Search Console, ale przywykłem do starej nazwy, więc przy niej zostanę, przynajmniej w tym wpisie.

Google Authenticator ma backup

Piekło zamarzło. Przedwczoraj na blogu ogłoszono, że Google Authenticator dorobił się backupu kodów na koncie Google. Wersja oferująca tę funkcjonalność jest już do pobrania z Google Play. To duża i ważna zmiana i okazja do notki. Przy okazji zmieniła się niestety ikona programu.

Jak działa TOTP?

Zasada działania TOTP (Time-based One-Time Passwords) jest bardzo prosta, a implementacja w większości języków to kilka-kilkanaście linii kodu. W skrócie: najpierw, przy włączaniu tej metody uwierzytelniania, serwer generuje i zapisuje sekret. Dzieli się nim z użytkownikiem, zwykle przy pomocy QRcode.

Od tej pory kody są generowane na podstawie bieżącego czasu (unix timestamp), zaokrąglonego do 30 lub 60 sekund, oraz ww. sekretu. Najpierw są hashowane, następnie hash jest przekształcany na sześciocyfrowy kod. I już.

Jak widać, do generowania kodów dla danego użytkownika wystarczy poznać sekret. Natomiast z uwagi na użycie funkcji skrótu, odtworzenie sekretu z kodu jest bardzo trudne. Sprytne.

Znaczenie

Czemu to takie ważne? Brak jasnego, prostego sposobu backupów był dla mnie ogromnym argumentem przeciw korzystaniu z TOTP. Stosunkowo łatwo było stracić dostęp do kodów, czyli odciąć się od serwisu. A dostępność jest przecież składową bezpieczeństwa. Dlatego wolałem jako 2FA wykorzystywać kody SMS. Mocno niedoskonałe: drogie, niewygodne, zawodne, podatne na ataki. Oczywiście koszt jest po stronie serwisu, który musi wysyłać kody. Wygoda to rzecz dyskusyjna, niektórzy dostawcy nawet nie mieli dużego opóźnienia w dostarczaniu SMSów. Awarie operatorów nie zdarzały się często, a SIM swap nie jest tanim czy łatwym atakiem.

Oczywiście istniały alternatywne aplikacje, które oferowały backup sekretów. Tylko jakoś bardziej ufam dostawcy systemu operacyjnego na moje urządzenie, niż losowej appce. Podejrzewam, że ludzi takich jak ja było więcej.

Jak było wcześniej?

Wcześniej było… słabo. Z backupem Google Authenticator można było sobie radzić na kilka sposobów. Pierwszym było zdjęcie/screenshot QRcode przy włączaniu TOTP. Średnio wygodne w przechowywaniu (bitmapa/wydruk), zajmujące dużo miejsca, żeby wyszukiwać trzeba dobrze opisać.

Kolejny sposób to zapisanie kodów ratunkowych. Większość serwisów w momencie generowania sekretu TOTP podaje kody ratunkowe do wydrukowania/zapisania. Niezłe, o ile ktoś korzysta z managera haseł.

Ostatni sposób to… drugie urządzenie z Google Authenticator i utrzymywanie kodów na obu urządzeniach. Dość drogie z uwagi na koszt kolejnego urządzenia, niezbyt wygodne z uwagi na konieczność ręcznej synchronizacji.

Jak widać, powyższe sposoby są niezbyt wygodne, albo działają dla osób, które mają dobrze poukładane backupy. Dla osób, które po prostu chcą mieć zabezpieczone konta przez 2FA, a niekoniecznie chcą projektować system backupów, uwzględniając jego dostępność – bardzo średnie. Bo właśnie, fajnie, że masz wydrukowane QRcode’y czy kody ratunkowe przechowywane w sejfie. Ale co jesteś właśnie na wakacjach i tracisz telefon, wraz z dostępem do wszystkich serwisów?

Wady

Obecne rozwiązanie nie jest idealne. Nadal będziemy uzależnieni od Google w kwestii backupu kodów i ich odzyskania. Dla większości ludzi będzie to zapewne akceptowalne ryzyko, tym bardziej, że ma znaczenie wyłącznie przy odzyskiwaniu, czyli bardzo rzadko.

Kolejną wadą jest trzymanie wszystkich jajek w jednym miejscu. Konto Google staje się SPOF. Szczególnie, jeśli ktoś korzysta także z zapamiętywania haseł przy pomocy Google.

Jeszcze osobną sprawą jest kwestia zaufania do samego Google. Nie napisałem tego pierwotnie i wprost, ale uznałem, że jeśli mamy OS od Google, zintegrowany z ich sklepem i konto w ich serwisie, to z jakiegoś powodu ufamy Google. Zależy oczywiście od modelu zagrożeń.

Zaufanie do Google jest tym istotniejsze, że backup kodów trafia do Google w postaci niezaszyfrowanej. Czy Google udostępni np. służbom kody 2FA? Nie wiem, ale się domyślam. Po raz kolejny, kwestia modelu zagrożeń. Szczęśliwie Google zapowiedziało dodanie szyfrowania.

Podsumowanie

Uważam tę zmianę za bardzo dobrą, z punktu widzenia przeciętnego użytkownika i mam nadzieję, że przyczyni się do popularyzacji 2FA. W ogóle ostatnio mamy dobry klimat dla 2FA opartych o TOTP. Najpierw wyłączenie 2FA przy pomocy SMSów w Twitterze, teraz backupy w Google Authenticator.

Paradoksalnie jednak, po tej zmianie może się okazać, że… lepiej zmienić dostawcę appki do 2FA, niż włączać backup do chmury Google w Google Authenticator. W sugerowanych pojawiły się FreeOTP, FreeOTP+, 2FAS.

UPDATE: Dodane info o zaufaniu do Google. Dodane info o braku szyfrowania i zapowiedź dodania. Zaktualizowane podsumowanie.

Pretekst

Od jakiegoś czasu szukałem pretekstu, żeby pobawić się maszynkami z Ampere A1 od Oracle. Poza tym, w zadaniach przetestowanie Cloudflare na blogu wisiało… prawie 5 lat. I jeszcze na dodatek gorącym tematem jest AI, często reprezentowana ostatnio przez ChatGPT. Ale jakoś na nic nie było czasu i potrzeby.

Zatem wpadłem na pomysł, żeby postawić bloga, który będzie WordPressem, stojącym na VMce z arm64, za Cloudflare, a treść dostarczać będzie głównie AI. Trzy pieczenie na jednym ogniu. W sumie cztery, bo jeszcze sprawdzę indeksowanie tego tworu i zarobię miliony na reklamach. Poznajcie blog everything about coffee.

Przyznam, że było trudniej, niż się spodziewałem. Najpierw był problem z wyborem domeny. Stwierdziłem bowiem, że taki eksperyment wymaga stosownej separacji. W domenach raczej nie siedzę, więc znalezienie czegoś sensownego w niewielkich pieniądzach było trudne. Stanęło na tym, że analogicznie jak na głównej domenie niech się składa w jedno słowo. I tak powstał coffee express. Bez es. W sumie także bez e w środku, bo byłyby aż trzy kolejno, ale to już wybór, nie ograniczenie techniczne.

Domena

Wydawać by się mogło, że kupno domeny w 2023 jest proste, szybkie i przyjemne. Sprostuję, nie jest. A przynajmniej nie jest, jeśli korzysta się z TLD .es a kupuje w OVH. Rejestrator ma teraz dziwne wymagania, panel OVH ma dziwne pola i komunikaty. Ostatecznie udało się, po kontakcie z supportem OVH. Dwukrotnym.

Hosting

Jeśli chodzi o Ampere A1, to ostatecznie odpuściłem instalację Debiana, którego Oracle nie dostarcza i użyłem gotowca w postaci Ubuntu. Przynajmniej na podstawce AKA hypervisorze, bo sam blog stoi już w kontenerze LXC z Debianem. Za wiele się tam nie dzieje, ale – po krótkim obcowaniu – maszynka wygląda na wydajną i generalnie śmiga.

Cloudflare

Przepięcie domeny na Cloudflare – szybkie, łatwe i przyjemne. Podpowiadają co mają podpowiadać, autouzupełnianie działa. Panel przejrzysty, ustawienia domyślne sensowne. Opcji w wersji darmowej niewiele, ale wystarczają.

Oczywiście jest tricky part związana z certyfikatami SSL czy ustawieniami DNS, jeśli chce się mieć coś dostępne bezpośrednio, ale da się. No i wypada zablokować ruch HTTP(S) do serwera spoza Cloudflare. Jest wiele sposobów, wybrałem prawdopodobnie najprostszy i najgorszy, czyli iptables z wyjątkami na klasy adresowe Cloudflare na maszynie. Może kiedyś zmienię.

WordPress

Stawianie WordPressa także okazało się pewnym wyzwaniem. Może nie tyle samo postawienie, co doprowadzenie do działania. W każdym jakby ktoś wybrał wariant z ruchem nieszyfrowanym między blogiem a Cloudflare, czyli teoretycznie najprostszą opcję, to może się naciąć. W praktyce chyba prościej uruchomić to jako szyfrowane, z certyfikatem self signed. Nie obyło się bez grzebania w wp-config.php. Poza tym, raczej było prosto. Najwięcej czasu zeszło na wybór grafiki i ręczną instalację i konfigurację wszystkich wtyczek do WordPressa, których używam.

ChatGPT

No i na koniec część związana z AI. Jak łatwo można się domyślić, bawiłem się chatGPT przy porannej kawie i wtedy powstał pomysł na bloga generowanego przy pomocy AI. No właśnie nie przez AI, a przy pomocy. Co to znaczy? Ano to, że może się zdarzyć, że ingeruję w odpowiedzi zwrócone przez chatGPT. Łączę je, przycinam, albo dodaję coś od siebie. Ale nie jest to regułą i zwykle po prostu przeklejam wprost. Bez korekty, sprawdzania faktów itd. Błędy się zdarzają, o czym można przeczytać choćby w komentarzach do tego wpisu. Poza tym, nie podaję prompta i sam, ręcznie wybieram tytuł. Ot, powiedzmy taki asystent leniwego copywrightera w postaci AI. Co do zasady muszę zmieścić się z utworzeniem wpisu od początku do końca przy paru łykach porannej kawy.

Projekt nie jest skończony. Marzy mi się dorzucanie powiązanych obrazków do każdego wpisu. Najchętniej automatyczne. Brakuje detali typu favicona czy optymalizacja szybkości. Choć ten w zasadzie goły WordPress za Cloudflare działa wg GTmetrix podobnie szybko, co ten blog. Nad wyświetlaniem reklam nadal pracuję – chwilę to trwa już po stronie Google No i oczywiście wpisów na razie jest mało, a chciałbym dodawać około dwóch tygodniowo, przynajmniej przez najbliższych parę miesięcy.

DeepL

UPDATE: Do gromady dołączył jeszcze DeepL, a dokładnie Write. Coraz częściej zdarza mi się dodać coś od siebie, poza tym ChatGPT pisze dość sucho i encyklopedycznie. Nie używam domyślnie, raczej sporadycznie póki co. I uwzględniam tylko niektóre sugestie, ale warto wspomnieć i o tym narzędziu.