tavis nörttimaailmassa

EksisONE - artikkeleita ja ohjeita nörttimaailmasta

GeoIP-blokkaus: iptables

Saapuvaa liikennettä on rajoitettava ja seurattava. Tärkein työkalu siinä työssä on palomuuri, joka käytännössä jokaisessa linux-jakelussa tarkoittaa ohjelmaa iptables. Usein palomuuriksi mielletään ufw, mutta se on ”vain” iptablesin käyttöliittymä. Tarkkaan ottaen iptables on myös käyttöliittymä pakettien hallinnassa kernelin suuntaan, mutta se on liian pilkuntarkkaa. Ufw on helppo työkalu, mutta sillä ei käytännössä kyetä tekemään estoja valtioiden mukaan. Niin sanottu GeoIP-blokkaus täytyykin tehdä suoraan iptablesiin.

Virtuaalimaailma on hassu paikka. Ensin nähdään paljon vaivaa, että saadaan tehtyä sisältöä ihmisten käyttöön. Sitten on nähtävä vielä enemmän vaivaa, että ihmisten käyttämät työkalut, muut kuin selaimet, eivät pääsisi käsiksi samaan sisältöön. Suurin osa liikenteestä kun ei tule sisällön käyttämisestä, vaan sisällön hyödyntämisestä eli suomeksi varastamisesta. Eikä se jää siihenkään. Melkoinen osa ihmisistä ei edes halua sisältöäsi. He haluavat rikkoa paikkoja. Jokaista aitoa kävijää kohden tulee ainakin 10 pahantahtoista, jotka on estettävä.

Estotapoja on erilaisia. Voidaan estää käyttäjäagentin perusteella, jos saapuja user agent tiedon suostuu kertomaan. Fail2banin avulla estetään tekemisen perusteella. Lisäksi voidaan estää porttien mukaan, protokollan mukaan, IP-osoitteen mukaan… Kun esto tehdään maaperusteisesti sen mukaan mistä maasta IP-osoite väittää saapuvansa, tehdään maaesto, geoip-esto.

Jotta maaperusteinen estäminen onnistuisi, niin tarvitaan tietokanta, josta käydään katsomassa mihin maahan IP-osoite liittyy ja sen perusteella sitten päätetään päästetäänkö vai estetäänkö. Esto voidaan toki myös tehdä ufw:n kautta kertomalla sille kaikki estettävät IP-osoitteet, mutta se on hankala ja varsinkin hidas tapa. Jos teet GeoIP-eston ufw:llä, niin varaa aikaa vähintään viikko – ei sinun  koneella tarvitse viikkoa päivystää, mutta sitä kokoluokkaa IP-osoitteiden ajaminen sisään vie. Hyvä muistisääntö on, että yksi maa vie aikaa 12 – 24 tuntia tai jopa enemmän, kokoluokasta riippuen. Ja tuo aika käytetään joka kerta, kun haluat estää uuden maan. IP-listojen päivitystä en halua edes ajatella.

Iptables saadaan asetettua nopeammin. Ensimmäisellä kerralla, kun perusta rakennetaan, niin aikaa menee vartista tuntiin riippuen kuinka paljon joudut pohtimaan. Sen jälkeen aina uuden maaeston käyttöönotto vie aikaa pari sekuntia.

iptables ja GeoIP2

UFW on ”vain” yksinkertaistettu käyttöliittymä, joka helpottaa asioita iptablesin kanssa. Siksi kaiken voi tehdä myös suoraan iptablesiin, jos osaa. Minä en osaa ja siksi aina kopypeistaan ja yritän viimeiseen asti välttää sen suoraa käyttöä. Haluaisin aina edes periaatteellisella tasolla ymmärtää mitä olen tekemässä, vaikka nippeleitä ja vipuja en osaisikaan.

On toinenkin syy. UFW:n ja Fail2banin kautta estot saa tehtyä paljon helpommin. Ainakin yksittäisissä IP-osoitteissa. Oikeammin – minusta on saanut tehtyä helpommin, koska olen ymmärtänyt (ja muistanut) komennot paremmin. Lisäksi en ole ollenkaan vakuuttunut, että tekisin tarvittavat asiat oikein iptablesissa,

On aivan se ja sama mitä kautta lopputulokseen pyrkii, niin kaikkien blokkausten kanssa on mietittävä mitä aidosti yrittää saavuttaa ja sen jälkeen löytää oikea työkalu. Koska Fail2ban estää lähtökohtaisesti tapahtuneiden asioiden kautta ja jälkijunassa, niin ennakkoestoihin sitä ei kannattaisi käyttää. Sitä käytetään metsästämään niitä IP-osoitteita, jotka jäävät ansaan. Fail2ban siis rankaisee vasta teon jälkeen.

Jos halutaan estää ennakkoon, eikä odoteta tapahtuuko jotain, niin käytetään iptablesia, UFW:n kautta tai suoraan.

On kaksi tapaa tehdä geo-esto. Voidaan asettaa estolistalle kaikki ne IP-avaruudet, jotka on rekisteröity estettävään maahan. Silloin tarvitaan pitkä lista IP-osoitteita ja ajetaan ne iptablesiin yksi kerrallaan ufw:n kautta. Toinen tapa on käyttää tietokantaa, josta iptables mihin maahan jokin IP-osoite kuuluu ja estää pääsyn sen mukaan. On makuasia kumpaa käyttää, mutta toki muistin kannalta on hieman eroa siitä, että asetetaanko aidosti miljoona IP-osoitetta kieltolistalle, vai käydäänkä jostain katsomassa kuuluuko IP-osoite kieltää. On muistettava, että iptables on koko ajan muistissa – siksi se on niin nopea.

On myös käytännön ero. Jos blokkaus tehdään IP-avaruuden mukaan CIDR-muotoinen IP-osoite kerrallaan, niin niitä ajetaan muistiin vähintään päivä – yhtään liioittelematta. GeoIP-tietokantaa käytettäessä eston tekemiseen menee noin muutama sekunti, riippuen kuinka nopeasti osaat kirjoittaa yhden komentorotlan.

Jotta geo-blokkaus saataisiin toimimaan niin, että palomuuri eli iptables todellakin kysyy mistä maasta IP-osoite on ja blokkaa sen mukaan, niin joudutaan menemään hieman mutkaisempaa reittiä. IP-osoite kerrallaan kieltämisen asentaminen ufw:n kautta on hitaampaa, mutta helpompaa.

Ihan ensimmäiseksi

Ennenkuin teet mitään säätöjä iptablesin kanssa, niin varmista, että et sulje itseäsi ulos:

iptables -I INPUT -s <IP-osoitteesi> -j ACCEPT
  • En tiedä onko hyötyä vai ei, mutta sallin sekä virtuaaliserverin IP-osoitteen että oman koti-IP:ni. Aidosti siksi, että en oikeastaan tiedä kummalla olen liikkeellä milloinkin, mutta sivustojen toiminta kiertää serverin IP:n kautta. Jos kuitenkin saat bannattua itsesi (minulta se kerran onnistui), niin ainakin DigitalOcean päästää webliittymän konsolilla sisälle. Eiköhän muutkin palveluntarjoajat mahdollista vastaavan.

Varmuuskopiointi ei ole koskaan väärin, joten kopioidaan itablesin konfiguraatio talteen:

/sbin/iptables-save > ~/iptables-save-`date +%F`
  • käyttäjäsi kotihakemistoon kopioidaan iptablesin tiedot ja tiedoston nimeen lisätään päiväys.

Jos asiat menevät pieleen, mutta edelleenkin pääset SSH:lla, niin saat palautettua varmuuskopion:

/sbin/iptables-restore < ~/iptables-save-<päiväys>

Jossain vaiheessa voi tulla tarve siivota iptables kokonaan.

  • Palautetaan käytännöt alkutilanteeseen ja päästetään kaikki sisälle
iptables --policy INPUT ACCEPT;
iptables --policy OUTPUT ACCEPT;
iptables --policy FORWARD ACCEPT;
  • Aloitetaan tyhjältä pöydältä
iptables -Z;
iptables -F;
iptables -X;
  • Esimerkit vaikuttivat IPv4-osoitteisiin. Sama on tehtävä IPv6-osoitteille. Vaihdat jokaisessa kuudessa komennossa iptables muotoon  ip6tables
  • Tuon jälkeen ufw on poissa käytöstä, joten anna ufw enable

Olen tehnyt tuon kerran ja se varmasti poisti jotain. Mutta kun tarkistin tilanteen ufw:llä ufw status niin samat IP-osoitteet olivat estettyinä. Joten joko en ymmärrä mitä itablesin palauttaminen alkutilanteeseen tarkoittaa tai esimerkit eivät toimi – minulle niistä ei kuitenkaan ollut mitään iloa, kun yritin tyhjentää kokeilujen jälkeen turhan isoksi paisuneen kannan.

Sen sijaan UFW:n palauttaminen lähtöasetelmiin onnistuu ja samalla häviävät kaikki iptablesin säännöt:
ufw reset

Tuo todellakin tyhjentää kaiken. UFW kertoo samalla tehneensä backupit omaan hakemistoonsa – mutta jos tarvitset niitä, niin googleta, koska en ole koskaan yrittänyt palauttaa niistä mitään.

Ihan toiseksi

Varmuuskopiointi on aina suotavaa, vaikka sen tekisi käsinkin aina ennen kuin lähtee tekemään syvempiä muutoksia. Toinen asia, joka olisi mukavaa, olisi että muutokset myös säilyisivät uudeenkäynnistyksen jälkeen.

Linux on sellaisen pikkujutun kuin palomuurin kanssa jäänyt 80-luvulle. Lähtökohtaisesti iptables ei talleta yhtään mitään. Kun annat komennon reboot, niin kaikki palumuurin säännöt häviävät. Se johtuu siitä, että iptables elää ja kuolee muistissa, eikä mikään prosessi tai ohjelma kirjoita automaattisesti sääntöjä talteen. Suoraan sanottuna minulle on täysin käsittämätöntä miten asia voi olla noin.

Jos olet asentanut ufw:n, Fail2banin tai mielellään molemmat, niin olet luultavasti antanut myös komennon apt install iptables-persistent. Jos et, niin tee se nyt. Heti.

Jos et hoida asiaa kuntoon, niin on ihan se ja sama paljonko töitä teet geo-blokkauksen kanssa. Seuraavassa buutissa kaikki on mennyttä.

iptables-persistent

Netin ehtymättömän kopiosisällön mukaan iptables-persistent tallentaa buuttia varten iptablesin säännöt talteen. Paitsi että useimpien samojen ohjeiden mukaan se täytyy itseasiassa muistaa ajaa itse – eli tehdä varmuuskopiointi iptables-save ja palautus iptables-restore komennoilla. Itseasiassa molemmat väitteet pitävät paikkaansa.

Kun iptables-persistent asennetaan, niin se laittaa talteen sillä hetkellä käytössä olevat IPv4- ja IPv6-säännöt ja ne palautetaan uudelleenkäynnistyksessä. Jos muutat iptablesin sääntöjä, niin ne täytyy erikseen tallentaa käsin, että tulisivat voimaan seuraavassa bootissa. Jos et tallenna, niin ainoa mikä palautetaan, on iptables-persistent asennuksen aikainen tilanne.

Ihmiset eivät huomaa tuota, koska useimmat eivät tee koskaan muutoksia palomuuriin. Fail2ban toki tekee, koko ajan, mutta se on syylän päällä olevan syylän päällä oleva syylä. Fail2ban tallentaa kaikki estot omaan tietokantaansa ja rebootissa se palauttaa käynnistyessään kaikki sääntönsä. Sama pätee myös systemctl stop/start fail2ban kanssa. Stopin kanssa Fail2ban siivoaa sääntönsä pois iptablesista ja startissa käy kirjoittamassa ne uudestaan iptablesiin. Se ei liity mitenkään iptables-persistent toimintaan.

Sen mitä iptables-persistent oikeasti tekee, on buutissa ajaa kaksi komentoa:

  • iptables-restore < /etc/iptables/rules.v4
  • ip6tables-restore < /etc/iptables/rules.v6

Se ei tallenna olevia sääntöjä uudelleenkäynnistystä varten. Se palauttaa ne säännöt, jotka on joskus joku tallentanut. Tämä ero on pakko ymmärtää.

netfilter-persistent

iptables-persistent tarjosi kaksi uutta komentoa (oikeastaan neljä, jos IPv6 lasketaan mukaan), joilla saa (käsin) tallennettua iptablesin tiedot, jotka saadaan palautettua, jos serveri käynnistetään uudelleem tai jos muista syistä haluaa palauttaa vanhemmat tiedot. Samalla asennettiin toinenkin työkalu, netfilter-persistent. Se ei tee mitään muuta kuin yhdistää iptables-persistent komennot yhden käskyn taakse.

Komenna

netfilter-persistent

Jos sait ohjeet sen käytöstä, niin sinulla on jo se. Jos et, niin asennetaan se:

apt install netfilter-persistent

On se asennettu ennen tai nyt, niin sallitaan sen käynnistyminen buutissa ja varmistetaan, että se on käynnissä.

systemctl enable netfilter-persistent
systemctl start netfilter-persistent

Aidostihan tuota ei sinällään olisi mikään pakko asentaa. Se itseasiassa on vain käytön yksinkertaistaja iptables-persistent ohjelmalle. Ei muuta. Mutta sen voi asettaa käynnistymään automaattisesti buutissa servicenä, iptables-persistent ei pysty siihen. Mutta et voi jättää silti asentamatta iptables-persistent, koska netfilter-persistent käyttää sitä. Aika jännä ratkaisu.

On mahdollista, että saat käynnistyksessä virheen. Kun vilkaiset systemctl status netfilter-persistent, niin löytänet tämän kaltaisen rivi;

ip6tables-restore v1.8.3 (legacy): host/network `85.76.113.91' not found

Tuo oli oma IP-osoite. Koska se on IPv4-muodossa, niin ajettaessa ip6tables-restore se on tunnistamaton.  Se johtuu siitä, että rules.v6 on itseasiassa kopio IPv4-säännöistä. Silloin sinä (tai joku muu) on jo ajanut komennon iptables-save > /etc/iptables/rules.v6 mutta sillä tallennetaan IPv4 säännöt. IPv6 säännöille on käytettävä komentoa ip6tables.

Osa ohjeista myös sanoo, että tämä on ajettava, jotta netfilter-persistent itse käynnistyisi serverin käynnistyessä. Itse olen hieman epävarma moisen tarpeellisuudesta, koska systemctl enable netfilter-persistent pitäisi hoitaa asia.

invoke-rc.d netfilter-persistent save

Itseasiassa nyt tehtiin käyttöliittymän kohteen käyttöliittymälle käyttöliittymä. Kuulostaako sinustakin purkkaviritykseltä? Kun netfilter-persistent ajetaan, niin se tallentaa IPv4- ja IPv6-säännöt, joita sitten iptables-persistent voi käyttää, jotta säännöt saadaan käynnistyksessä iptablesille, joka on netfilterin käyttöliittymä. Piiri pieni pyörii.

Sääntöjen tallentaminen bootia varten

Uudelleenkäynnistyksessä palautettavat säännöt ovat tallessa kahdessa tiedostossa:

  • /etc/iptables/rules.v4
  • /etc/iptables/rules.v6

Jos et ole tehnyt suoraan noille kahdelle mitään, niin ne ovat tismalleen samat kuin iptables-persistent asennuksessa, kun kysyttiin säilytetäänkö vanhat IPv4- ja IPv6-säännöt ja toivottavasti vastasit yes. Tai sitten ne ovat samoja, jotka olivat voimassa, kun netfilter-persistent asennettiin – kumpi sitten viimeiseksi tehtiin. rules-tiedostot ovat tekstitiedostoja, joten voit huoletta vilkaista luontipäivän esimerkiksi head -2 /etc/iptables/rules.v4

Saat iptablesin säännöt tallennettua käynnistystä varten kahdella tavalla, joko/tai ja molemmat tekevät täysin saman asian:

  • iptables-save > /etc/iptables/rules.v4
    ip6tables-save > /etc/iptables/rules.v6
  • netfilter-persistent save

Fail2ban

Tässä on käsissä pieni ongelmanpoikanen ja se on Fail2ban. Koska Fail2ban kirjoittaa itse ketjunsa ja sääntönsä iptablesiin, niin myös ne tallennetaan – vaikka ei olisi tarvetta, koska Fail2ban hoitaa homman itse. Minulla tämä on aiheuttanut tilanteita, että aikoinaan Fail2banniin viedyt säännöt eivät toimikaan, vaan läpi pääsee bannattuja osoitteita. Lisäksi sääntöjä ja ketjuja on kaksin kappalein Kun ne sitten tekevät jotain kiellettyä ja Fail2ban yrittää tehdä tehtävänsä, niin saan ilmoituksen, että osoite on jo estetty. Olisi ollut ihan kiva, että se olisi huomattu jo ennenkuin yritys pääsee palomuurin läpi.

Tämä kysymys on ollut auki jo vuosia, eikä mistään löydy ketterää, saatika näppärää, ohjetta. Jos sen, että tallennetaan Fail2bannin säännöt, jotka Fail2ban yrittää sitten asettaa itse, haluaa välttää, niin ainoa vaihtoehto näyttäisi olevan Fail2bannin sammuttaminen ennenkuin kopioi iptablesin säännöt talteen. Tai sitten muokkaa käsin rules-tiedostoista Fail2bannin ketjut pois. Kummassakaan ei ole mitään järkeä vuonna 2020. Mutta niin täytyy tehdä vuonna 2020.Ja luultavasti kaikkina tulevinakin vuosina.

Jos oivallat Fail2banin sääntöjen päällekkäisyydet ja kertautumiset liian myöhään, kuten minulle kävi, niin sitten tehdään siivousoperaatio.

  • Sammutetaan Fail2ban: systemctl stop fail2ban
  • Katsotaan mitä INPUT ketjuun jäi: iptables -nL INPUT --line-number
  • Poistetaan jokainen f2b-alkuinen ketju: iptables -D INPUT <halutun-rivin-numero>
    Jos ketjua ei suostuta poistamaan, koska siellä on sääntöjä, niin tyhjennä ensin jokainen f2b-ketju: iptables -F f2b-<ketjun-nimi>
  • Tallenna iptablesin tiedot: netfilter-persistent save
  • Käynnistä Fail2ban: systemctl start fail2ban

Iptablesin palauttaminen rebootin jälkeen

Kunhan tarvittavat rules.v4 ja rules.v6 tiedostot löytyvät, niin iptables on kunnossa rebootin jälkeen. Ainakin ideaalimaailmassa. Minulla ei ole, koskaan.

Taas kerran, on useampikin vaihtoehto – eikä yksikään helpota elämää.

Periaatteessa käynnistymisen aikana ajettavan netfilter-persistent start pitäisi ladata tallennetut iptablesin tiedot käyttöön. Minulla netfilter-persistent ei saa tehtyä sitä ja kaatuu. Status kertoo tällaista:


netfilter-persistent[696]: run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables start
netfilter-persistent[696]: Another app is currently holding the xtables lock. Perhaps you want to use the -w option?

Tuossa törmätään koodin hitauteen, Siinä vaiheessa kun netfilter-persistent haluaisi ruveta töihin, niin joku muu työstää samaa asiaa ja xtablesin lock-tiedosto estää toiminnon. Silloin netfilter-persistent kaatuu, eikä mitään muuta ladata iptablesin käyttöön kuin Fail2bannin ja ufw:n tarpeet.

Tämä tulee olemaan ongelma myöhemmin, että saataisiin geo-blokkaus käyttöön, sillä se vaatii muutaman oman ketjun tekemisen – joita (kuten ei muitakaan kustom-ketjuja) ei saada rebootissa käyttöön, koska joku muu (luultavammin Fail2ban) työstää asioita liian kauan.

Ehdotus käyttää --wait vipua on kaunis. Iptables osaa sen, systemctl ei. Joten se siitä.

Ollaan taas tilanteessa. että joudutaan käsitöihin.

Kun serveri on buuttinsa jälkeen ylhäällä, niin käynnistetään netfilter-persistent:

systemctl start netfilter-persistent

Tuota voi joutua takomaan jonkun aikaakin, kunnes xtablesin lock vapautuu. Kun se onnistuu, niin netfilter-persistent lataa tallennetut rules-tiedostot käyttöön. Saamalla se jyrää Fail2banin asettamat ketjut.

Voit toki palauttaa iptablesin tiedot käyttämällä iptables-restore komentoakin, mutta se ei anna muuta lisäarvoa kuin yhden komennon lisää, koska silloin joutuu palauttamaan IPv6-säännöt erikseen. Molemmat komennot tekevät tismalleen saman asian täysin samoilla tiedostoilla.

Fail2ban on myös pakko käynnistää uudestaan, että saadaan sen haluamat ketjut paikoilleen. Jos sitä ei tee, niin Fail2ban on vakaasti käsityksessä, että kaikki jailit toimivat kuten kuuluukin, mutta sähköpostiisi alkaa virrata sekalaisia ilmoituksia virheistä ja jo kertaalleen bannatuista IP-osoitteista

fail2ban-client restart

Jos nyt vilkaiset iptables -nL INPUT niin tarvittavat ketjut ovat paikoillaan ja käytössä.

Automatisointi puuttuu

Ongelma ei ole enää serverin käynnistys. Se on nyt hoidettu ja iptables saa ne säännöt, jotka sen kuuluukin saada. Ongelma on siinä, että miten saadaan tuoreet säännöt talteen ilman manuaalitöitä, että olisi jotain ajantasaista palautettavaksi. Nyt säännöt on muistettava tallentaa ennenkuin buuttaa serverin. Ja se, että pitäisi erikseen muistaa tehdä jotain on suora oikopolku ongelmiin.

Jos joku nyt sanoo, että linuxeja ei tarvitse koskaan buutata tai sitten moinen tehdään huomattavan harvoin, niin huudan suoraa huutoa. Ainakin Ubuntu on pakko buutata päivitysten takia noin 2 -3 viikon välein. Itseasiassa paljon useammin kuin Windows 10. Toki voi jättää uudelleenkäynnistyksen vaatimat päivitykset tekemättä – mutta se on ideana yhtä hyvä kuin jättää Windows päivittämättä.

Huonot uutiset ovat, että automatisointia ei ole. Toki voi hyödyntää cronia, mutta silloin pitäisi ensin cronissa sammuttaa Fail2ban ja sitten kopioida iptablesin tiedot ja taas käynnistää Fail2ban. Oikeasti? Ainoa mihin kannattaa cronia käyttää on iptablesin varmuuskopiointiin jonnekin muualle kuin /etc/iptables hakemistoon. Kun onnistuu sekoilemaan asetusten kanssa ja sulkee itsensä sekä maailman ulos, niin ei paljoa lohduta, jos cronin tekemän kopioinnin takia rebootissa palautettava iptables on tismalleen sama kuin minkä onnistui rikkomaan. Jossain täytyy siis olla tallessa toimiva versio ja silloin on aivan se ja sama onko siellä Fail2bannin ketjut mukana – se on pelastusrengas, ei tuotantoversio.

Eräs typerimmistä perusteluista sille, että automaattia ei ole, on että iptablesin sääntöjä rukataan niin harvoin. Juuri siitä syystä automatisointia tarvitaan. Jos jotain tehdään päivittäin, niin sen muistaa. Mutta kun tehdään joskus ja harvoin, niin taatusti ei muista.

Joten on muistettava kolme asiaa:

  1. Jos et ole säätänyt iptablesia, ufw:n ketjuja tai omia ketjujasi, niin silloin ei tarvitse tehdä mitään ja pärjäät olevalla kopiolla iptablesista
  2. Jos olet säätänyt mitä tahansa noista JA sinulla on Fail2ban käytössä, niin ensin joudut pysäyttämään Fail2banin, sitten tekemään iptablesista tuoreet kopiot ja viimeiseksi käynnistämään Fail2ban. Vasta sen jälkeen voit antaa komennon reboot.
  3. Jos olet säätänyt mitä tahansa noista ja sinulle EI OLE Fail2bannia, niin tee ajantasainen kopio iptablesista ja reboottaa.

Yksinkertaisin tapa pitää huolta /etc/iptables/rules.[v4|v6] tiedostojen ajantasaisuudesta on laittaa aina jokainen kerta lisätyt säännöt myös noihin, samalla kun komentaa iptablesia. Silloin ei tarvitse murehtia Fail2banin sammuttamisesta, koska sääntöjä ei tarvitse erikseen koipioida talteen – ne pidetään koko ajan ajantasaisina käsipelillä.

MaxMind ja GeoIP2

GeoIP-palveluja on kourallinen. Ilmaisia, joissa on myös toimiva päivitys sekä tapa saada IP-tunnistus toimimaan, on vain yksi: MaxMind. Siksi käytännössä kaikki ohjeet perustuvat MaxMindin käyttöön.

Kun googletat GeoIP2-estämistä, niin saat kohtuullisen paljon neuvoja. Kun yrität saada asioita toimimaan niiden avulla, niin yksikään neuvo ei toimi. Syynä on jokin omituinen lakitekninen vääntö Kalifornian osavaltion ja MaxMindin välillä, jossa on häivähdys meikäläistä GDPR:ää. Sen takia MaxMind vaatii nykyään rekisteröitymistä, joka rikkoi neuvot ja (tätä kirjoitettaessa) netistä ei löydy ainuttakaan toimivaa ohjetta. Paitsi tämä. Varmasti moni muukin on ratkaissut asia, ja useimmat varmasti minua paremmin, mutta he eivät ole tehneet siitä julkista artikkelia.

Jokainen ennen vuotta 2019 kirjoitettu ohje perustuu mahdollisuuteen ladata Geo-tietokannat CVS-muodossa suoraan MaxMindilta. Sitten tuli muutos ja MaxMind alkoi vaatimaan API:a, jota kutsutaan salasanaksi, mutta tietokannat olivat ilmaisien suhteen silti käytössä geneerisellä salasanalla. Suurin muutos oli se, että CSV-muoto hävisi ja ladattavaksi tuli mmdb-tietokanta ja jokaiset tekstipohjaiseen CVS-kantaan perustuvat ohjeet hajosi. Vuoden 2020 aikana tuli uusi muutos, joka edellytti todellista aitoa käyttäjärekisteröintiä ja se sitten rikkoi loputkin ohjeet.

Pienellä soveltamisella asiat saa kuitenkin toimimaan, eikä tekemiseen tarvita mitään sen kummempaa teknistä osaamista. Tekstitiedostoja täytyy osata muokata ja kopioida pari tiedostoa, mutta ei sen kummallisempaa.

Ongelma on siinä, että GeoIP2-kysymys on edelleenkin muutoksessa, eikä mikään takaa, että nämäkään ohjeet toimivat enää sinun lukiessasi.

GeoIP2-tietokanta

  • Ensimmäiseksi tarvitaan GeoIP-tietokanta, joka kertoo maat ylipäätään serverille:
apt install geoip-bin geoip-database
  • Voit testata toiminnan komennolla:
geoiplookup 8.8.8.8

Jos saat vastaukseksi, että kyseessä on US, United States niin homma toimii.

Sitten tarvitset päivitykset tietokantaan, koska IP-maailma muuttuu koko ajan. Tapoja on muutama, mutta käytännössä on käytettävä MaxMindin palvelua. Sinne on pakko rekisteröityä, mutta se on urakkana helpoin ja jos/kun sinulle riittää ilmaiset, kerran viikossa päivitettävät ja vain noin 98 % oikeassa olevat tietokannat, niin rekisteröinti ei maksa mitään.

  • Aloitetaan asentamalla ensimmäiseksi GeoIP2-tietokannan päivitysohjelma:
apt install geoipupdate

geoipupdate tarvitsee oman conf-tiedoston, josta se löytää MaxMindin käyttäjätunnuksen, salasanan sekä mitkä tietokannat ladataan. Sitä varten tarvitset tunnukset. Tili on pakko tehdä, jos aikoo ylipäätään tehdä minkäänlaista geoip-estoa, joten aidosti tässä ei oikein ole valinnanvaraa. Perustietokannat ovat ilmaisia, mutta jos haluat tarkempaa, niin joudut maksamaan.

  • Luo tili MaxMindiin osoitteessa https://www.maxmind.com/en/geolite2/signup. Anna pyydetyt tiedot. Sinun täytyy täyttää myös yrityksen nimi ja jos sellaista ei ole, niin keksi jotain tai laita nimesi.
  • Saat vahvistussähköpostin. Klikkaa salasanan luonti -linkkiä. Anna salasana, päätä haluatko MaxMindin mainospostia ja klikkaa reset password -nappulaa. Kirjaudu sisään sähköpostiosoitteellasi ja luomallasi salasanalla.
  • Klikkaa valikosta My Licence Key. Klikkaa avautuneessa ikkunassa nappulaa Generate new licence key. Anna avaimelle haluamasi kuvaus tai tyydy oletukseen. Laita täppä ruutuun Yes ensimmäisessä kysymyksessä, jossa halutaan tietää tarvitaanko tietoja geoipupdatelle. Laita täppä ensimmäiseen valintaan eli uudemmalle versiolle. Klikkaa Confirm
  • Olet luonut uuden avaimen. Talleta Account/User ID sekä License key. Lisenssiavainta ei enää näytetä, joten ehkä se kannattaa varmuuden vuoksi tallentaa johonkin, vaikkakin ne saadaan talteen seuraavassa vaiheessa. Lisäksi, jos on tarve, ja vanha on kadoksissa, niin aina voi luoda uuden. Klikkaa nappulaa Download Config.
  • Sinulle ladattiin GeoIP.conf, joka pitää sisällään tarvitsemasi tietokannat (eli ne mitkä ovat sinulle sallittuja) sekä account ID:n ja license keyn.
  • Klikkaa valikosta kohtaa Download Files
  • Lataa GeoLite2 Country: CSV Format kohdasta zip-tiedosto.
  • Tee hakemisto:
mkdir /usr/local/src/GeoLite2xtables/
  • Pura zip-tiedosto ja siirrä GeoLite2-Country-Locations-en.csv tiedosto GeoLite2xtables hakemistoon.
  • Siirrä GeoIP.conf hakemistoon /etc tai luo tiedosto ja kopypeistaa sisältö:
nano /etc/GeoIP.conf

Tiedosto vaatii nämä tiedot:

AccountID <numeroita>
LicenseKey <merkkejä>
EditionIDs GeoLite2-ASN GeoLite2-City GeoLite2-Country

  • Aja SSH:ssa update: geoipupdate -v
    Vipu -v on sama kuin verbose eli kertoo mitä tapahtuu. Pääset näkemään toimiiko se vai tuleeko virheitä.
  • Tarkista cron:
nano /etc/cron.d/geoipupdate

Sinulta pitäisi löytyä tällainen sisältö:

 

Nyt päästään jatkamaan iptablesin ja GeoIP-blokkauksen naittamista.

  • Asennetaan tarvittavat lisäkilkkeet, joista varsinaisen työn tulee tekemään xtables:
apt install iptables-dev xtables-addons-common libtext-csv-xs-perl libnetaddr-ip-perl libnet-cidr-lite-perl pkg-config

En ole ihan varma, että ovatko iptables-dev, libnetaddr-ip-perl tai pkg-config aidosti tarpeellisia, mutta ne olivat vanhemmissa ohjeissa mukana. Tietysti voi koettaa ilman niitä ensin ja jos ei toimi, niin sitten asentaa. Mutta eivätpä nuo suuria haittaa, vaikka asentaisikin.

 

HUOMAA: Tätä kirjoitettaessa x-tables-addons-common asentama xt_geoip_build on näämmä päivittynyt ja etsii tiedostoa, jota ei löydy. Siksi ohjeet eivät sellaisenaan toimi. Tuo tarkoittaa myös sitä, että yksikään GeoIP-blokkauksen asennusohje ei enää toimi. Voit metsästää vanhaa versiota jostain tai sitten uskaltautua lataamaan sen tästä. Muokkaa tekstin ajantasaiseksi ehtiessäni.

Lataa “xt_geoip_build” xt_geoip_build – Ladatty 90 kertaa – 6,13 kt

Siirrä ladattu xt_geoip_build hakemistoon /usr/lib/xtables-addons/. Uudelleenimeä alkuperäinen, jotta se olisi käytössä, kun ohjeet päivittyvät.

 

  • Asennetaan MaxMindin binääritietokannat käyttökelpoiseen CSV-muotoon muuttava apuohjelma. Itse siirsin sen gitillä, koska silloin saan (ehkä) hieman helpommalla hoidettua uuden ja korjatun version, jos sellainen joskus tulee:
git clone https://github.com/mschmitt/GeoLite2xtables.git

Voit myös ladata sen zip-pakettina joko omalle koneellesi ja sitten siirtää purettuna FTP:llä tai sitten käyttämällä wget -ohjelmaa.

  • Kopioidaan gitin tiedostot paikalleen aiemmin tehtyyn GeoLite2xtables hakemistoon. Muuta repon polku sopivaksi (kuin myös, jos latasit wgetillä jonnekin muualle, kuten vaikka /tmp hakemistoon):
rsync -avh ~/repo/GeoLite2xtables/ /usr/local/src/GeoLite2xtables/
  • Tehdään pakollinengeolite2.license tiedosto, jonne tulee MaxMindin salasana:
 cp /usr/local/src/GeoLite2xtables/geolite2.license.example /usr/local/src/GeoLite2xtables/geolite2.license
  • Kurkataan GeoIP.conf tiedostosta salasana. Kopioi se.
cat /etc/GeoIP.conf
  • Laita salasanasi. Muoto on YOUR_LICENSE_KEY='salasanasi' – muuta tietoa ei tarvita:
nano /usr/local/src/GeoLite2xtables/geolite2.license
  • Tehdään xt_geoip hakemisto, jonne tulee myöhemmin maakohtaiset tiedot:
mkdir /usr/share/xt_geoip
  • Aletaan tekemään maatiedostoja. Siirry GeoLite2xtables-hakemistoon:
cd /usr/local/src/GeoLite2xtables/
  • Aja komento, joka lataa GeoLite2-Country-Blocks tiedostot  hakemistoon /tmp (tämän vaiheen olisi periaatteessa voinut ohittaa käyttämällä samoja, jotka saatiin samassa zipissä kuin  GeoLite2-Country-Locations tiedosto):
./00_download_geolite2
  • Aja komento, joka lataa Geonames-sivustolta maatiedot:
./10_download_countryinfo
  • Aja komento, joka yhdistää maatiedot vaadittavaan muotoon:
cat /tmp/GeoLite2-Country-Blocks-IPv{4,6}.csv | ./20_convert_geolite2 /tmp/CountryInfo.txt > /usr/share/xt_geoip/GeoIP-legacy.csv
  • Tässä kohtaa on seuraavassa vaiheessa ajettavassa skriptissä virhe. Country-Blocks tiedostot ovat väärässä hakemistossa. Helpoimmalla päästään, kun kopioidaan ne skriptin haluamaan hakemistoon:
cp /tmp/GeoLite2-Country-Blocks-IPv4.csv /usr/local/src/GeoLite2xtables/GeoLite2-Country-Blocks-IPv4.csv
cp /tmp/GeoLite2-Country-Blocks-IPv6.csv /usr/local/src/GeoLite2xtables/GeoLite2-Country-Blocks-IPv6.csv
  • Aja komento, joka muuttaa MaxMindin tiedot sellaiseen muotoon, että maatunnistuksen tekevä xtables osaa käyttää niitä sekä tehdään maatietojen CSV:t hakemistoon /usr/share/xt_geoip:
/usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip /usr/share/xt_geoip/GeoIP-legacy.csv

Jos saat virheitä, niin ne tulevat yleensä viimeisessä kohdassa. Silloin kannattaa ensimmäisenä avata tiedosto xt_geoip_build ja etsiä sieltä vastaava virheilmoitus, jonka mukaan sitten alkaa arpomaan mikä meni pieleen. Ensimmäiseksi kannattaa varmistaa GeoLite-tiedostojen nimi ja että ne varmasti ovat oikeassa hakemistossa.

  • Osa ohjeista käskee käynnistämään serverin uudestaan, osa ei. En tiedä tarvitaanko sitä aidosti, mutta itse käynnistin ensimmäisellä kerralla. Kokeilujen jälkeen ainakaan päivityksen jälkeen, jossa tehdään tismalleen samat vaiheet, ei tarvinnut buutata.
reboot
  • Samaten osa ohjeistaa käskee ajamaan tämän ensimmäisellä kerralla (ja vain ensimmäisellä, ei enää myöhemmin) bootin jälkeen, osa käyttää toista komentoa ja loput eivät sano mitään. Itse ajoin, eikä mikään hajonnut.
depmod

Jos selvisit kunnialla tänne asti, niin nyt pitäisi geo-tunnistus olla iptablesin käytössä. En tiedä mitään näppärää tapaa testata sitä, joten kokeillaan käytännössä. Bannataan Kiina:

iptables -I INPUT -m geoip --src-cc CN -j DROP

Jos et saanut virhettä, niin tilanne on lupaava. Tarkistetaan, että esto todellakin meni iptablesiin:

iptables -L INPUT

Sinulta pitäisi löytyä, melkoisen alusta, tällainen rivi:


DROP   all   --   anywhere   anywhere   -m geoip   --source-country CN

Jos sinulle aiemmin tuli Fail2banilta ilmoituksia kiinalaisen yrittäjän bannaamisesta, niin niiden pitäisi nyt loppua. Itselläni toimii.

Päivittäminen

IP-avaruus muuttuu koko ajan. Operaattoreita tulee ja menee, sekä osa tarvitsee enemmän tilaa. Tämä ohje käsittelee vain IPv4-osoitteita, mutta jossain vaiheessa täytyy varmaan siirtyä IPv6 käyttöön – mutta ei ihan vielä.

Sitä odotellessa pitäisi saada IPv4-tiedot pysymään ajantasalla.

geoipupdate päivittää hakemistossa /var/lib/GeoIP olevat MaxMindin mmdb-tietokannat. Niitä käytetään, jos sinulla on jokin ohjelma, joka osaa hyödyntää niitä – kuten vaikka käyttäjäseurannassa Matomo. Mutta niistä ei ole apua iptablesin geo-blokkauksessa – juurikin mmdb-muodon takia edeltävät kommervenkit jouduttiin tekemään.

Tehdään samat kommenvenkit, mutta cronilla ja kerran kuussa:

nano /etc/cron.monthly/geoip-updater

Kopioi sinne tämä:

Tuosta täytyy tehdä suoritettava skripti:

chmod +x /etc/cron.monthly/geoip-updater

Komentoriviltä ajettaessa skripti ei minulla toiminut, koska ”Building *.csv” kohta ei tee mitä kuuluu, mutta komentoriviltä erikseen ajettuna teki. Lopputulos kuitenkin on, että skriptin ajamisen jälkeen geo-blokkaus lakkaa toimimasta, koska viimeinen vaihe jää tekemättä. Ja sen saa korjattua ajamalla viimeinen komento käsin. En tiedä mitä tuolle pitäisi tehdä, joten ole hereillä. Ehkä sitä ei kuitenkaan kannattaisi laittaa croniin? Jos ehdit sen jo tekemään (etkö lue ohjeita ennen tekemistä?), niin tällä pääset eroon:

rm -f /etc/cron.monthly/geoip-updater

Järjestyksellä on väliä

Ennenkuin alat estämään maita, niin on selvitettävä yksi itablesin ehdoton perusasia: sääntöjen järjestyksellä on väliä.

Kun IP-osoite haluaa sisälle, niin siihen sovelletaan sitä sääntöä, joka tulee ensimmäiseksi vastaan. Jos olet kieltänyt vaikka kaikki USA:n IP-osoitteet ja sinulla on Goolebotin salliminen myöhemmin, niin Googlebot ei pääse koskaan sisälle. GeoIP:n avulla iptables toteaa, että tämä tulee USA:sta, pudottaa yhteyden ja siirtyy seuraavan yrittäjän pariin.

Minä sallin serverin IP-osoitteen, joka on saksalainen DigitalOceanin osoite. Sen jälkeen estin Saksan. Hetken kuluttua serverin ja sivustojen toimintaa valvova Monit ilmoitti, että sivustot eivät ole saatavilla ja samalla kaikki vastasivat lakkaamasta. Kun poistin Saksan eston, niin sivustot palasivat linjoille. Syy oli järjestys. Saksan esto oli ennen serverin oman IP:n sallimista.

Minulla kesti hetken selvittää mistä oli kyse – ja tämän takia en pidä sokkona kopypeistauksesta, sillä pitäisi aina ymmärtää edes periaatteellisella tasolla mitä on tekemässä. Ja se, että ei ymmärrä, johtuu usemmiten kiireestä ja kiimasta saada jokin asia aikaiseksi, jonka takia ei käytä esimerkiksi komennoissa edes vipua --help, saatika että vilkaisisi man-sivua. Tehtävä asia pitäisi rauhoittaa ainakin kahvikupin ajaksi ja pohtia sekä varmistaa Googlella, että mitä käytetty komento tarkoitaa oikeasti.

Kun sallin oman IP-osoitteeni tai kielsin maan, niin käytin komentoa malliin iptables -I INPUT .. koska se oli käyttämässäni esimerkissä. Tuo tarkoittaa lyhykäisyydessään, että sääntö laitetaan INPUT ketjun ensimmäiseksi. Kun annetaan uusi sääntö samalla tavalla, niin se löytyykin ketjun ensimmäisenä ja edeltävä sääntö on tipahtanut alaspäin.

Olin siis mennyt ajatuksella, että ihan ensimmäiseksi sallitaan oma IP-osoite, että ei tapahtuisi vahinkoa, ja se laitettiin vivun -I avulla INPUT-ketjun ensimmäiseksi. Sitten kielsin maat samalla -I vivulla, ja nekin laitettiin INPUT-ketjun ensimmäiseksi, jolloin se pudotti oman IP-osoitteen sallimisen alemmas ja jyräsi.

Asia selvä ja looginen, mutta miten tuosta päästä yli – eihän asiat voi mennä niin, että täytyy ensin paperilla suunnitella mitä kieltää ja mitä sallii, ja sitten sen mukaan päättää komentojärjestys. Entä myöhemmin, kun tuleekin tarve tehdä jotain muuta – täytyykö kaikki poistaa, rakentaa uusi järjestys ja syöttää uudelleen.

Onneksi ei. Apuun tulee vipu -A. Se lisää säännön oman ketjunsa viimeiseksi. Joten kun komensin oman IP-osoitteen sallimisessa iptables -I INPUT 1 .. niin se siirtyi ensimmäiseksi. Kun kielsin maat, niin käytin muotoa iptables -A INPUT .. ja maaestot painuivat viimeiseksi. Nyt sitten oma IP-osoite käsitellään aina ennen maaestoja ja kaikki on hyvin.

Paitsi että ei ollut. Annoin Fail2banin kertoa mitä bannataan ja huomasin äkkiä, että edelleen serverille tulee Fail2banin bannattavaksi Kiinaa, Irania, Ranskaa ja Saksaa, vaikka ne oli iptablesissa estetty ja niiden ei olisi koskaan pitänyt päästä Fail2banin näkyville asti. Normaalisti aloittaisin heti kiihkeän googlettamisen GeoIP:n ongelmista, koska sen täytyi olla rikki – mutta nyt, kyllästymisen takia kun mikään ei koskaan onnistu ja toimi kertalaakista, pidinkin tuumauspaussin kahvin ja tupakan parissa.

Minua nimittäin vaivasi yksi asia, jota en ymmärtänyt: ketjut, tai chains englanniksi. Laitoin omat estoni ketjuun INPUT, mutta Fail2ban käytti aina f2b-alkuisia jailin mukaan ja jos vaikka sallin tai estin jotain, niin ne ilmestyivät ufw-user-input ketjuun. Järjestyksellä on väliä, mutta niin on myös sillä mitä ketjut tekevät.

Käännän aina termin chain ketjuksi. En tiedä onko se käytössä oleva käännös, mutta yleensähän (myös) IT-maailma puhuu finglishiä, jossa termeistä käytetään niiden alkukielistä nimeä suomalaisella taivutuksella. Siksi varmaan minunkin pitäisi puhua chaineista, tableseista ja targeteista. Käytän silti mieluummin kotimaista vaihtoehtoa ja ei, en ole tuossa johdonmukainen, koska Fail2bannin kohdalla puhun jaileista, en putkasta tai vankilasta.

Ketju on ikäänkuin kategoria tai otsikko. Sillä saadaan ryhmiteltyä samantyyppiset tai samaan asiaan liittyvät säännöt. Ketjuilla on varmasti jokin oleellisempi ja tärkeämpikin merkitys, kun asioita osataan oikein ja paljon. Mutta minulle ne ovat kategorioita. Ja ketjujen takia minulla edelleenkin Fail2ban pystyi blokkaamaan maita, jotka pitivät olla suljettuina. Jokin siis toimi ja ei toiminut. Tai jokin ei toiminut kunnolla. Tai jokin oli asetettu niin, että se ei tehnyt mitä minä halusin. Miten sitten toimimattomuuden milloinkin haluaa muotoilla.

Suodattumaton maasuodatus

Annoin komennon iptables -L joka listaa ketjut. Minulla on kuitenkin jo aika paljonkin IP-osoitteita estettynä, joten tietoa tuli liikaa. Toki cntr-C katkaisee suorituksen, mutta iptables -L INPUT antoi sen minkä halusin nähdä. INPUT kun on eräällä tavalla perusketju, ensimmäinen, josta aina lähdetään liikkeelle. Kaikki muut ketjut ovat haaroja INPUT ketjusta.

Jos annat mukaan -n eli malliin iptables -nL INPUT niin jätetään tekemättä IP:n hostin selvittäminen ja IP-osoitteet esitetään numeroina. Paljon nopeampaa. Muttan joskus on vaan kiva kun hostin nimi näkyy.

 

Ensimmäisenä on sallittuina oma ja serverin IP-osoite. Sen jälkeen käsitellään Fail2banin jailit, seuraavaksi ufw:n kautta tulleet estot sekä sallitut ja viimeisenä ovat -A vivulla estetyt maat.

Ketjuissa on yksi (no, montakin…) asia, jota en ollut tiennyt. Ne eivät kohdistu pelkästään serverille tulevaan ja lähtevään liikenteeseen, vaan myös mihin ja miksi liikennettä liikkuu. Se, mistä puhutaan palomuurina, valvoo liikennettä vahvasti myös serverin sisällä. Mutta nyt kysymys oli siitä, että ufw:n säännöt päästivät liikennettä läpi omien ehtojensa mukaan. Estettävät maat jäivät estämättä, koska pyynnöt hyppäsivät muille poluille, eivätkä koskaan päässeet sääntöön asti, joka olisi estänyt ne maan mukaan.

Käytän termiä liikenne meille taviksille helppona yleisterminä. Aivan samoin kun välissä puhun kävijästä, joskus jopa IP-osoitteesta. Koko ajan kyse on kuitenkin siitä palasesta tietoa, joka sillä hetkellä liikutetaan. Paketti, eli packet englanniksi, olisi varmasti oikeampi termi.

UFW on ikäänkuin ideologisesti tarkoitettu käytettäväksi ainoana ratkaisuna, käyttäliittymänä iptablesin päällä. Siksi sen asettamat ketjut, ehdot ja säännöt ovat viimeisenä, koska käyttäjän ei olisi tarkoitus työskennellä suoraan iptablesin kanssa – vaikka se mahdollista onkin. Samasta syystä kun Fail2banissa otetaan jail käyttöön, niin sen synnyttämä ketju laitetaan aina INPUT ketjun alkuun (jotka myös aina painavat oman IP-osoitteesi sallivan säännön alaspäin, joten pidä huolta, että oma IP:si on whitelistattuna Fail2bannin jail.local tiedostossa; jos ei ole ja Fail2ban bannaa IP:si, niin se ei koskaan pääse iptablesissa niin pitkälle, että erikseen salliminen auttaisi mitään).

Ratkaisu on siis sinällään helppo. Siirretään maaestot vähintään ennen ufw:n sääntöjä. Jos ne saadaan jopa ennen Fail2bannin estoja, niin saadaan hiukan vähennettyä liikennettä niidenkin osalta, mutta sillä ei ole mitään aitoa käytännön merkitystä. Silloin tehdään ensimmäinen tappo suodatus maan perusteella, muutoin aloitetaan Fail2bannin estojen mukaan.

Järjestyksessä on kolme ehdotonta rajaa:

  • mikään sääntö ei tule voimaan, jos se on INPUT ketjussa ufw-sääntöjen jälkeen (eli lisätty vivulla -A), koska ufw hyväksuu kaiken, jos pakettia ei ole ufw:ssä erikseen estetty
  • oman IP-osoitteen salliminen täytyy olla ennen maaestoja (ja Fail2banin asetuksissa)
  • geo-blokkauksen ohitus täytyy olla ennen maaestoja (tietenkin)

Maiden estäminen

Jutussa olevat kuvakaappaukset ovat vanhempaa perua. Siksi niissä geo-estot ovat INPUT ketjussa. Ne kannattaisi kuitenkin laittaa omaan ketjuunsa, mutta toki voit asettaa ehdon suoraan INPUT ketjuun. Vaihdat vain seuraavien esimerkkien geo-stop muotoon INPUT ja jätät tekemättä ketjuun liittyvät asiat. Maaestojen laittamisessa omaan ketjuun on kuitenkin yksi etu: saat poistettua geo-blokkauksen kokonaan yhdellä komennolla.

Maiden lyhenteet ovat ISO-koodin mukaisia, tarkkaan ottaen ISO 3166 alpha-2, jos triviaalit nippelit kiinnostavat; hyvä lisä kahvipöytäkeskusteluihin.

  • Tehdään uusi ketju nimeltään geo-stop
iptables -N geo-stop

Asetetaan maaestot. Maat voi laittaa yhteen pötköön, mutta pidän asioiden ryhmittelystä. Plus lyhyemmistä riveistä on helpompi löytää estetty tai estämätön maatunnus. Jos laitat kaikki maat samaan, niin silloin on ihan se ja sama, vaikka laittaisitkin estot INPUT ketjuun.

  • Kiina, Iran, Venäjä, Romania, Vietnam:
iptables -I geo-stop -m geoip --src-cc CN,IR,RU,RO,VN -j DROP
  • Syyria, Kroatia, Irak, Turkki, Intia:
iptables -I geo-stop 2 -m geoip --src-cc SY,KR,IQ,TR,IN -j DROP
  • Sekalaisia eurooppalaisia maita:
iptables -I geo-stop 3 -m geoip --src-cc IT,ES,PL,FR,LV -j DROP
  • Sekalaisia aasialaisia maita, mukaanlukien Tyynenmeren pikkuvaltiot jne.:
iptables -I geo-stop 4 -m geoip --src-cc SA,LA,PK,SG,TH,BD,HK,MO,ID,KW,NP,TW,UA -j DROP
  • Sekalaisia afrikkalaisia maita:
iptables -I geo-stop 5 -m geoip --src-cc EG,GH,UG,LY,NA,SD,KE,TZ -j DROP
  • Sekalaisia Väli- ja Etelä-Amerikan valtioita:
iptables -I geo-stop 6 -m geoip --src-cc AR,BR,CO,MX,BO,PY,PA -j DROP
  • Kun pyyntö ei ole osunut mihinkään kiellettyyn maahan, niin sille täytyy antaa ohjeet jatkaa matkaa ja se sääntö löytyy aina viimeisenä, muutoin jatketaan itablesissa seuraavaan ketjuun. Tästä kohdasta ehtoihin osumaton – tässä: sallituista maista tuleva – käännetään takaisin ketjuun INPUT samaan paikkaan, josta poikettiin tänne:
iptables -A geo-stop -j RETURN

Vielä suodatus ei ihan toimi. Ketjuun INPUT tarvitaan hyppypaikka maaestojen tutkimiseen. Tällä näet missä järjestyksessä INPUT ketjun asiat ovat:

iptables -nL INPUT --line-numbers

Vaihda INPUT 5 itsellesi sopivaksi rivinumeroksi niin, että geo-stop tulee INPUT ketjuun ennen ufw-alkuisia ja omien IP-osoitteidesi sallimisen jälkeen:

iptables -I INPUT 5 -j geo-stop

Nyt geo-blokkaus toimii.

Logien seurantaa

Fail2bannin jaileihin kannattaa varmaan ainakin hetkeksi aikaa laittaa action = %(action_mwl)s jotta saa ilmoitukset banneista whois-tietojen kanssa. Ei se suoraan kerro mitään geo-estämisen onnistumisesta, mutta jos Fail2ban onnistuu bannaamaan Kiinaa, Irania ja mitä sitten suljitkin, niin silloin jokin on vinossa.

Tämä komento listaa Fail2banin estot per maa:

cat /var/log/fail2ban.log | grep "\] Ban" | sed 's/.*[Bb]an \(.*\)/\1/' | uniq | while read line; do geoiplookup $line; done | sort | uniq -c | sort -nr

Minulle se aiheutti geo-blokkauksen käyttöönoton jälkeen seuraavana päivänä ensimmäisellä kerralla hetkeksi hermostollisia oireita, kun estettyjen maiden joukossa oli komeilla estomäärillä Kiina, Iran, Korea, Ranska ja muut estämäni maat. Niitähän ei pitäisi löytyä ollenkaan. Syy löytyi nopeasti ja se on Fail2bannin logrotate, joka pyörähtää vain kerran viikossa. Tuo kannattaa ehkä muuttaa päiväksi.

Avaa nano /etc/logrotate.d/fail2ban ja muuta tällaiseksi:

GeoIP-esto toimii liian hyvin

Jos katsoit tarkemmin estettäviä maita, niin isoja roskaajia puuttuu. Listassa pitäisi olla myös nämä:

  • USA, Iso-Britannia, Saksa, Alankomaat, Kanada ja Australia
iptables -I geo-stop -m geoip --src-cc US,GB,DE,NL,CA,AU -j DROP

Jos estät USA:n, niin suurella todennäköisyydellä sivustosi lakkaa toimimasta. On käytännössä varmaa, että osa toiminnoista vaatii kykyä keskustella jonkun palvelimen kanssa, joka sijaitsee Yhdysvalloissa. Onko käytössä WordPress? Sen olisi syytä päästä kyselemään edes onko päivityksiä saatavilla. Käyttääkö mikä tahansa toiminnallisuus jotain API-kyselyä? Jos kyllä, niin se osuu luultavammin Amazonin, Googlen tai DigitalOceanin palvelimille, joista tarvittavista suurin osa on USA:ssa, loput Saksassa tai Briteissä.

Käytän WordPressissä erään etelä-afrikkalaisen yrityksen tekemää lisäosaa. Jos kiellän Etelä-Afrikan (AF), niin lisäosa lakkaa toimimasta. Vastaavia esimerkkejä löytyy vaikka kuinka. Ylipäätään jos joudut laittamaan jonkun tunnuksen, joka tarkistetaan, ennen kuin lisäosa alkaa toimimaan, niin kohdeserverin maata ei saisi estää.

Alankomaita ei tarvitse estää, jos et koskaan tarvitse whois-komentoa. Mutta jos milloinkaan tarvitset tietoa IP-osoitteista, edes Fail2banin ilmoituksia varten, niin Alankomaita ei voi estää, koska whois.ripe.net on siellä.

Ongelma on vielä tuotakin laajempi, koska datakeskuksia on vaikka missä. Saattaa olla, että jokin palvelu haluaa päästä Lontoon palvelimelle. Tai Frankfurtiin. Tai Hong Kongiin. Minä käytän, oikeammin se on jäänyt testien jälkeen käyttöön, Powie’s Uptime Robotia seuraamaan sivustojen uptimeä. Sen pingit tulevat Turkista, joka juuri estettiin.

whois-kyselyjen takia pitäisi sallia myös muita maita, kuten Zaire (ZA) ja Mauritania (MU) koska tiedot tarjoavan Afrinicin serverit sijaitsevat noissa valtioissa.

Esto ei toimi

Seurasin Fai2banin estoja sen jälkeen, kun otin GeoIP-bannauksen käyttöön. Se oli helpoin tapa seurata toimiiko estot. Kiina, Iran ja Venäjä hävisivät heti, Siltä osin esto teki mitä pitikin.

Silti geo-eston läpi pääsi Fail2banin bannatavaksi IP-osoitteita, joiden ei olisi pitänyt päästä läpi. Yleensä kyse oli aina länsimaista ja jonkun ison serveripalvelun IP-osoitteista. Varsinkin OVH oli sellainen (jos haluat estää käsin jonkun virtuaaliservereitä tarjoavan, niin OVH on hyvä ehdokas; ei hyötyä, pelkkää roskaa) ja kiinnijäämättömät olivat usein Ranskaan kohdistuvia osoitteita. Mutta tuli palomuurin läpäisseitä muualtakin – mutta aina länsimaista, ei koskaan ns. toisesta tai kolmannesta maasta.

Eräs palomuurin läpäisseistä oli 145.239.93.55, josta whois kertoo maaksi Puolan, mutta Puola oli estettynä. GeoIP-kannoissa sen sijaan osoite kytkettiin Ranskaan, jota ei ollut siinä vaiheessa estetty. Kun Ranska tuli mukaan, niin tuokin IP estettiin. Sillä kertaa ongelma oli käytettävien maa- ja IP-tietokantojen epätarkkuudessa. Kysymys kuuluu, että päteekö sama muihinkin eston ohittaineisiin?

Selvittelin niitä käsin, enkä löytänyt mitään ihmeellistä. Näyttäisi siltä, että osa vain läpäisee geoip-tunnistuksen. En tiedä syytä, ehkä kyselyt kestävät joskus liian kauan ja moiset pääsevätkin puolittain salamiten läpi.

Mutta niitä virhepositiivisia ja -negatiivisia löytyy. Siksi GeoIP-blokkaukseen ei saa koska luottaa täysin.

Oman maan estäminen

En päässyt serveriltä osoitteeseen geonames.org. Heidän serverinsä sijaitsee USA:ssa, jota ei ollut estetty ja silti geo-blokkaus esti pääsyni. Kannattaa muistaa, että edellä asennetut säännöt pätevät molempiin suuntiin: estetty maa ei pääse serverille, eikä serveri pääse estettyyn maahan. Aloin vapauttamaan maa kerrallaan ja syy löytyi.

Olin silloin estänyt myös Saksan. En ollut pitänyt sitä minään ongelmana, koska olin INPUT ketjun alussa sallinut kaikelle kaikkeen serverin saksalaisen IP-osoitteen – ensimmäinen sääntöhän jyrää kaiken. Kun vapautin Saksan, niin serveri pystyi keskustelemaan USA:ssa olevan osoitteen kanssa.

Omien pähkäilyjen perusteella ongelman täytyi olla nimenomaan ulospäin lähtevän saksalaisen IP-osoitteen estäminen, koska curl ja wget eivät löytäneet kohdetta. En tiedä miksi noin käy, mutta testasin asian brittiläiseltä serveriltä. Kun Saksa oli estettynä, niin kaikki toimi – tietenkin, koska yhteyksissä olivat GB ja US. Kun sallin INPUT ketjussa serverin brittiläisen IP-osoitteen ja geoip esti GB:n, niin yhteys katkesi.

Toinen omituinen tilanne tuli vastaan WordPressien päivitysten suhteen. Minulle tuli yhtä äkkiä päivityksissä Nginxiltä virheilmoitus error 504. Se on usemmiten time-out ongelma ns. upstreamin kanssa, eli keulilla oleva Nginx ei saa yhteyttä siihen serveriin, jonka kanssa se yrittää keskustella. Useimmiten se on Nginxin takana oleva palvelu, minulla siis joko Varnish tai Apache2. Nginxin error-logi kertoi, että 127.0.0.1:8080 eli Varnish, mutta käytännössä Apache, ei kertoillut headereita ajoissa. Ngingin ilmoittama error oli tällainen yhden sivuston kohdalla, mutta jokainen ilmoitti samaa:


upstream timed out (110: Connection timed out) while reading response header from upstream, client: 85.76.133.66, server: store.katiska.info, request: "POST /wp-admin/admin-ajax.php HTTP/2.0", upstream: "http://127.0.0.1:8080/wp-admin/admin-ajax.php", host: "store.katiska.info", referrer: "https://store.katiska.info/wp-admin/plugin-install.php"

Useimmiten tuo johtuu hakemisto-ongelmista, yleensä omistajuus on FTP:n käytön myötä siirtynyt rootille pois käyttäjältä www-data. Jos koskaan saat kuun vaihtumisen myötä WordPressissä mediaa siirrettäessä http-errorin, niin se johtuu lähes aina tuosta. WordPress haluaisi tedä kuukausikansion, mutta ei onnistu, koska omistajana on root.

Sama ongelma ilmenee myös error 504 ilmoituksena. Nginx jää odottamaan Apachelta lupaa aloittaa lataaminen, mutta sitä ei tule, kuin ei myöskään kieltoa, koska WordPress ei kerro ajoissa oikealla tavalla, että lataus olisi muutoin hyvä idea, mutta sitä ei saada kirjoitettua hakemistoon. Kun kaikki odottavat, niin Nginx hermostuu ensimmäisenä, lopettaa työn timeoutin takia ja antaa error 504 ilmoituksen.

Silloin homma korjaatuu yksinkertaisella komennolla

chown -R www-data:www-data /var/www/html/

Sain tuolla kaikki muut wordpress-sivustot tekemään päivityksen, mutta en yhtä verkkokauppaa. Taistelin asian kanssa kokeilemalla kaikki mahdollisen kikka kolmoset, joita Google tarjosi, mutta mikään ei auttanut. Olin jo kahden vaiheilla asentaa verkkokauppa uudestaan toiselle serverille.

Kokeilin vielä yhtä juttua. Aloin yksitellen poistamaan geo-estoista (länsi)maita. Kun Saksa – taas – vapautettiin, niin päivitys onnistui. Minä olin kuitenkin whitelistannut serverin IP-osoitteen, itseasiassa koko IP-alueen, sekä sallinut varmuuden vuoksi myös hostin download.wordpress.org, vaikka se sijaitsee Yhdysvalloissa. Saksan eston poistaminen toimi kuitenkin vain yhdellä sivustolla. Kaikissa muissa, käytännössä identtisissä asennuksissa, Saksan estäminen ei ollut mikään ongelma. Mystistä.

Minun ymmärrykseni mukaan niin wget kuin curl käyttävät samaa porttia kuin muukin liikenne, sekä samaa protokollaa. En tiedä kumpaa WordPressin päivitys käyttää, mutta veikkaisin curlia. Kokeilin kuitenkin molempia, Saksa estettynä, ja tiedostot siirtyivät aivan ongelmitta.

En tiedä miten tuo pitäisi korjata. Tilanne on kuitenkin se, että tämän jutun säännöillä geoip estää serverin ulospääsyn osassa tilanteita, kuten curlin kanssa, mutta ei kuitenkaan juttelua tavallisten webkävijöiden selaimen kanssa. Joku fiksu voisi selittää minulle mistä ihmeestä on kysymys, kommentointi on auki. Luultavasti ongelma on omassa osaamattomuudessa iptablesin kanssa, ja että estän aivan kaiken liikenteen, mutta sallin vaikka vain tcp:n, vaikka tarvittaisiin jotain muuta. Miten se liittyy curliin ja vastaaviin, niin en ymmärrä.

Kunnes asia selviää, niin pidän Saksan sallittuna – vaikka sitä kautta tuleekin roskaliikennettä turhan paljon. Jääpähän Fail2bannillekin töitä.

Hakukoneiden salliminen

Iptablesissa on kohtuullisen helppoa sallia IP-osoite. Aivan yhtä helppoa, kuin estää. Kysymys on lähinnä siitä, että missä ja miten hakukoneet sallitaan niin, että ne vain ohittavat maaeston ja jatkavat normaalina liikenteenä. Jos hakukoneet sallitaan, annetaan ACCEPT, ennen maaestoa, niin ne ohittavat myös UFW:n eli pelkän IP-osoitteen takia annetaan ohituskaista ilman mitään lisätarkistuksia. En pidä ajatuksesta, mutta koska ollaan saavuttu osaamiseni rajoille, niin en tiedä onko tuolla merkitystä.

Koska halusin, että hakukoneiden sallitut IP-osoitteet ohittavat geo-eston, mutta joutuvat silti ufw:n käsittelyyn, niin

  • teen uuden ketjun, johon siirrytään INPUT ketjusta
  • jokainen sallittu IP-osoite hyppää ufw-sääntöjen alkuun
  • muut palaavat takaisin INPUT ketjuun ja jatkavat normaalisti mm. keskustellen GeoIP-bannauksen kanssa

Jos ratkaisuni on päätön tai siinä on ongelmia, niin olet enemmän kuin tervetullut vinkkaamaan kommenteissa paremman tavan. Ongelma toteutuksessani on, että se vaatii turhan paljon käsitöitä ja sen päivittäminen on työlästä. Siksi se on enemmän purkkaa kuin aito ratkaisu.

Siinä on kylläkin vielä isompikin ongelma. Hankittavat IP-listat eivät ole kattavia ja sieltä puuttuu malliin Twitter ja vastaavat.

  • Tee lista hakukoneiden sallituista IP-osoitteista sivustolta IP2locations. Löydät ohjeet jutusta Geo-blokkaus: UFW ja IP-listat
  • Poista listasta muut rivit kuin IP-osoitteet (esim. search editorissa ensimmäisen rivin mukaan auttaa, koska haettavat riviparit ovat kaikki samanlaisia)
  • Lisätään SSH:ssa jokaisen rivien alkuun ja loppuun itablesin vaatimat tiedot sekä aivan tiedoston loppuun yksi sääntö lisää. Sinun on oltava samassa hakemistossa tiedoston kanssa tai annettava myös polku. Vaihda nimi hakukone.txt siihen millä tiedosto löytyy.
sed -i -e 's_.*_-A se-whitelist -s &_' hakukone.txt
sed -i 's/$/ -j ufw-before-input/' hakukone.txt
echo '-A se-whitelist -j RETURN' >> hakukone.txt
  • Tehdään uusi ketju iptablesiin. Sen on oltava sama kuin mitä äsken lisättiin hakukone.txt tiedostoon. Siihen tulee sallittavat IP-osoitteet.
iptables -N se-whitelist
  • Tuodaan hakukoneiden sallitut IP-osoitteet, joten kopioidaan ensin iptablesin nykyiset tiedot. Tiedosto iptables.save luodaan siihen hakemistoon, jossa olet nyt. Jos haluat sen jonnekin muualle, niin anna polku tai siirry ensin siihen hakemistoon.
/sbin/iptables-save > iptables.save
  • Avaa iptables.save ja lisää loppuun ennen COMMIT merkintää tiedoston hakukone.txt sisältö. Käytä haluamiasi työkaluja, mutta minä olen jo pitkään avannut Win10-koneessa isot tekstitiedostot muokkaukseen FTP:llä Notepad++ ohjelmaan. Eli minulla on auki PuTTY, FileZilla ja Notepad++.Nyt iptables.save tiedoston kaksi viimeistä riviä pitäisi olla:
    -A se-whitelist -j RETURN
    COMMIT
    
  • Tallenna iptables.save. Siirretään muokatut tiedot takaisin iptablesiin:
/sbin/iptables-restore < iptables-save

Huomaa: iptables-save/iptables-restore temppua voit käyttää myöhemminkin, jos sinulla on tarve muokata massana iptablesin sääntöjä.

  • Katsotaan mikä on tämän hetkinen INPUT ketjun järjestys
iptables -L INPUT --line-numbers

  • Minulla oli kuvan mukainen. Haluan hakukoneiden IP-osoitteet ennen geoip-estoja, joten minä asetan hypyn äsken tehtyyn ketjuun se-whitelist riville 4 eli heti virtuaaliserverin IP:n (minulla hostina backend) sallivan säännön jälkeen. Kaikki geo-estot tulevat sitten sen jälkeen. Toki se-whitelist voisi olla ensimmäisenäkin, mutta omaa IP:tä on turha kierrättää sen kautta.
    Fail2banin jail f2b-manual-ip on ensimmäisenä siksi, että olen aktivoinut sen jälkeenpäin. Jos sammutan Fail2banin, niin sen uudelleenkäynnistys asettaa kaikki f2b-säännöt INPUT ketjun alkuun.
iptables -I INPUT 4 -j se-whitelist

Kaikki hakukoneet ja hyödylliset botit eivät löydy tehdystä listasta. Esimerkiksi sellaiset kuin Pinterest ja Twitter puuttuvat. Niiden IP-osoitteet joutuu metsästämään itse ja sallimaan erikseen. Käytännössä tuo tulee vastaan vain jos geo-estät USA:n.

IP-osoitteiden whitelist

Jos päätät tehdä erillisen listan sallittavista IP-osoitteista, niin matki hakukoneiden se-whitelist ohjeita. Toki voit lisätä sallittavat IP-osoitteet samaankin ketjuun hakukoneiden kanssa, mutta itse haluan pitää yhdessä aina samanlaiset asiat. IP-osoitteiden sallimisella voi esimerkiksi estää Alankomaat geo-blokkauksella ja sallia Alankomaissa oleva whois.ripe.net sallimalla IP-lohko 193.0.0.0/21.

Jos et kiellä USA:ta, niin periaatteessa saatoit tehdä turhaa työtä, jos sallit hakukoneiden IP-osoitteet. Ne kun lienevät kaikki yhdysvaltalaista liikennettä. Jos jos sallit hakukoneiden IP-osoitteet, niin voit poistaa ketjun viemästä muistia. Ehkä kannattaa kuitenkin antaa sen roikkua mukana, jos kuitenkin innostut tekemään lisää säätöjä ja USA:kin menee geo-estoon.

Mutta näillä se häviää:

  • Katkaistaan hyppy se-whitelist ketjuun:
iptables -D INPUT -j se-whitelist
  • Tyhjennetään ketju se-whitelist:
iptables -F se-whitelist
  • Poistetaan ketju se-whitelist:
iptables -X se-whitelist

Päästetään osa läpi

Alankomaat ovat hieman ärsyttävä tapaus. Sieltä tulee maan koko huomioiden kohtuullisen paljon kolkutteluita, vaikkakaan se ei kokonaismittakaavassa olekaan sieltä pahimmasta päästä. Tehdään vielä yksi ketju, jossa päästetään soveliaat IP-osoitteet läpi.

Koska Fail2bannin säännöt ovat ensimmäisenä INPUT ketjussa, niin ne pysäyttävät jo kertaalleen bannatut yrittäjät. Sen jälkeen sallitaan omat IP-osoitteet, sitten tarkistetaan sallitut hakukoneiden IP-osoitteet, siirrytään geo-blokkaukseen ja tuosta selvinneet etenevät tai poistuvat ufw:n sääntöjen mukaan. Sallittavat IP-osoitteet on siis laitettava samoille paikkeilla kuin hakukoneet – ja itseasiassa aivan samalla tavalla.

Sallittavat IP-osoitteet voisi laittaa hakukoneiden kanssa samaan, mutta ei kannata. Idealistisempi syy on, että pidetään samanlaiset yhdessä. Käytännön syy taasen on se, että jos (ja kun) päivität hakukonelistan joskus, niin se on helpompi tehdä, kun ei tarvitse yrittää säästää sinne jälkeenpäin lisättyjä IP-osoitteita.

Nyt ei tarvitse muokata tiedostoja sen enempää, koska ideana on lisätä IP-osoitteet tylsällä manuaalipelillä aina tarpeen mukaan.

  • Tehdään uusi ketju:
iptables -N whitelisted-ip
  • Lisätään sen loppuun paluupiste INPUT ketjuun IP-osoitteille, jotka eivät olleet sallittuja. Yritä muistaa, että tähänkään ketjuun ei saisi koskaan lisätä mitään -A vivulla. On aivan se ja sama mitä RETURN säännön alapuolella on, koska se palauttaa takaisin INPUT ketjuun, eikä päästä mitään ohitse.
iptables -A whitelisted-ip -j RETURN
  • Tehdään INPUT ketjuun hyppypiste. Katso ensin mihin kohtaan sen haluat:
iptables -L INPUT --line-numbers

Hyvä paikka voisi olla se-whitelist ketjun yläpuolella, jolloin jo sallittujen osoitteiden ei tarvitse tehdä uutta kierrosta kokeilemassa, josko ne todellakin ovat sallittuja. Joten laita komentoon sama rivinumero kuin ketjulla se-whitelist on, minulla se olisi 7. Jos sinulla ei ole sitä käytössä, niin laita ennen geoip-estoa.

iptables -I INPUT 7 -j whitelisted-ip
  • Annetaan whois.ripe.net palvelun koko IP-avaruuden ohittaa geo-blokkaus. Kun lisäät uusia IP-osoitteita – tai -avaruuksia, niin tee ne aina samalla komennolla vaihtaen vain IP-osoitteen. Tällä tavalla lisäät jokaisen sallittavan IP-osoitteen.
iptables -I whitelisted-ip -s 193.0.0.0/21 -j ufw-before-input
  • Estetään Alankomaat:
iptables -I geo-stop -m geoip --src-cc NL -j DROP

Kokeillaan. Anna komento whois 193.0.0.0 ja sinun pitäisi saada vastaus.

whois-palvelut

Jos suljet useamman maan eri mantereilta, niin kannattaa sallia ainakin ne IP-osoitteet, jotka kertovat IP-osoitteiden tiedot.

  • AFRINIC: 196.192.115.21 (MU) | 196.216.2.20 (MU) | 196.216.2.21 (MU)
  • APNIC: 139.162.228.231 (US) | 139.162.237.51 (US)
  • ARIN: 199.5.26.46 (US) | 199.71.0.46 (US) | 199.212.0.46 (US)
  • RIPE: 193.0.6.135 (NL)

Sallittavien etsiminen

Se, miten löydät ne IP-osoitteet, jotka on sallittava, on hieman työlästä. Joudut tekemään sen käsipelin palvelu kerrallaan. Ennenkuin estät USA:n, niin etsi ensin edes tärkeimmät (tai jotka ensin mieleen tulevat) palvelut ja mieti sen jälkeen onko sallimisessa suurempi työ ja vaiva kuin kolkuttajien estämisessä per IP-osoite Fail2banin kautta.

Linuxjakelusi päivitysreitti on sallittava. Minulla se tarkoittaa, että on sallittava Ubuntun hostien IP:t Isossa-Britanniassa ja DigitalOceanin mirrorit Cloudflaren US-osoitteissa. Teen podcastejä, joten jokaisen sallimani podcast-jakelijan IP-alue on sallittava, että ne pääsevät lukemaan RSS-syötettä.

Se urakka hoidetaan käyttämällä

  • ensin host komentoa, että saadaan IP-osoite tai -osoitteet selville,
  • sitten whois komennolla saadaan selville IP-alueen ensimmäinen ja viimeinen osoite selville
  • ja hetaan ulkoisesta palvelusta tieto mikä on IP-alueen CIDR-muoto

WordPressissä on pakko sallia lisäosien ja teemojen päivitykset. Ne, jotka päivitetään wordpress.org kautta, ovat helppoja, mutta maksullisten suhteen on jokainen sallittava IP-osoite tai -avaruus selvitettävä erikseen. WordPressin hallinta ei anna mitään viitteitä mistä osoitteesta zip-paketti tulee, mutta siihen on olemassa kiertotie: asenna WP CLI. Paitsi, että saa useita elämää helpottavia työkaluja, niin tehdessäsi lisäosien päivitykset komentoriviltä, niin sinulle kerrotaan suoraan mistä urlista päivitystä haetaan tai yritetään hakea. Sen jälkeen salliminen on helppoa rutiinityötä.

Käytetään esimerkkinä wordpress.org kautta tulevia.

  • Ollaan saatu tietoon, että host on aina downloads.wordpress.org
  • IP-osoite saadaan selville: host downloads.wordpress.org
  • IP on 198.143.164.250 ja voit sallia sen, mutta koska ei ole varmaa miten wordpress.org jakaa kuormitusta, niin sallitaan varmuuden vuoksi koko IP-alue
  • Anna komento: whois 198.143.164.250
  • Sinua kiinnostaa NetRange eli IP-alueen ensimmäinen ja viimeinen osoite. Yhdysvaltalaiset whois-tiedot kertovat usein suoraan CIDR:n, joka ilmoittaa IP-alueen ja se on se, jonka haluat sallia. Tässä tapauksessa 198.143.128.0/18
  • Saat laskettua CIDR-muodon esimerkiksi sivustolla ipaddressguide.com mutta vastaavia on useita muitakin

Mihin päädyttiin?

Kiina, Iran ja kumppanit, jopa Venäjä, ovat helppoja. Ne voi estää ilman mitään ongelmia, ainakin jos ei suuntaa niiden markkinoille. Jos sivuston toiminta on riippuvainen jonkin toiminnallisuuden suhteen noista maista, niin väitän, että ongelmat ovat paljon syvempiä kuin mitä geo-blokkaukset tuomat vaivat ovat.

Sama juttu suurimman osan muunkin maailman suhteen. Kysymysmerkeiksi nousevat ainakin Britannia ja Saksa. Mahdollisesti myös Ranska ja Italia. Niistä kaikista saattaa tulla sellaista teknistä liikennettä, jonka pitää päästä läpi. Jos nuo maat estää, niin on pakko ottaa käyttöön jokin tapa sallia määrätyt IP-osoitteet.

USA:ta ei voi estää, jos sivusto tekee yhtään mitään. On täysin mahdoton urakka lähteä selvittämään jokaisen luvallisen palvelun IP-osoitteita.

Kysymys ei ole pelkästään hakukoneiden sallimisesta tai muutamasta WordPressin lisäosasta. Jos sinulla on verkkokauppa, niin on selvitettävä jokaisen maksunvälittäjän käyttämät IP-osoitteet, kuin myös pakettien välityksen. Sähköpostien täytyy liikkua, joten kun (huomaa, ei jos) sinulla on ulkoinen sähköpostinvälitys, niin sen osoitteet on sallittava. Jos käytät jotain massapostitusjärjestelmää, niin sen IP-avaruus on vapautettava. Podcastien tekeminen edellyttää, että useammankin täytyy päästä lukemaan syötettä. Jos käytät kuville ja muulle staattiselle sisällölle CDN-palvelua, niin sen IP-osoite on muistettava vapauttaa. Sivustosi käyttää luultavasti SSL-sertifikaattia ja sen uusiminen vaatii yhteyden johonkin. Mietit mitä tahansa toimintoa, niin vastapää on aina vapautettava maaestosta.

Tuossa listassa on yksi yhteinen tekijä. Noin 95 % niistä tulee serveriltä, joka ilmoittaa maakseen Yhdysvallat. Työmäärä kaikkien whitelistaamisessa on tolkuton. Se on niin suuri ja jatkuva urakka, että USA:ta ei vaan voi geo-estää.

USA:n ja vastaavien suhteen, joita ei voi kategorisesti kieltää maan perusteella, on olemassa vain kaksi ratkaisua:

  • Vaihdetaan hajonnut palvelu sellaiseen, jonka IP-osoite ei tule kielletystä maasta tai on selvitettävissä ja sallittavissa. Useimmiten tämä ei ole vaihtoehto.
  • Ei piitata ja annetaan läpipäässeiden maiden roskata, ja hoidetaan ongelmaa muilla tavoilla. Useimmiten tämä on ainoa aito vaihtoehto.

Geo-esto on houkutteleva, mutta on selvä syy miksi sitä ei kuitenkaan laajemmin käytetä ja miksi siihen vaadittavat työkalut ovat laskettavissa yhden käden yhdellä sormella, eikä sekään työkalu ole pakasta revittynä toimiva sekä vaatii kohtuullisesti vaivaa päivittyäkseen. Syy on se, että maailma on globalisoitunut (hieno ilmaisu). Mailla ei ole enää niin suurta merkitystä.

Geo-blokkaus on kuitenkin toimiva tapa vähentää roskaa ja kohinaa. Mutta se ei ole tapa estää. Tuo ero on ymmärrettävä.

Kaikista helpoin tapa on se, mistä kaikki lähti liikkeelle ja estetään vain pahimmat roskaajat:

  • asetetaan webpalvelimelle bad bot -esto
  • otetaan Fail2ban käyttöön
  • estetään GeoIP-estolla vain pahimmat (ja tarpeettomimmat) maat

Jos pystyt elämään ilman Ranskaa ja Intiaa, niin pelkästään tällä saat estettyä huomattavan ison osan yrittäjistä (säädä rivinumero sopivaksi, niin että se painuu alle oman IP:si sallivan säännön):

iptables -I INPUT 3 -m geoip --src-cc CN,IR,RU,RO,VN,FR,SY,KR,IQ,TR,IN -j DROP