tavis nörttimaailmassa

EksisONE - artikkeleita ja ohjeita nörttimaailmasta

GeoIP-blokkaus: UFW ja IP-listat

Maantieteellinen esto, maasto yai geo-blokkaus, on tapa estää kaikki saapujat määrätystä maasta. Luultavasti yleisin tapa tehdä geo-blokkaus on hankkia lista IP-osoitteita, jotka kohdustuvat määrättyyn maahan ja sitten ufw:n kautta kieltää yhteydet. En tiedä onko tuo yleisin tapa, mutta se on varmasti neuvotuin tapa. Mutta kuten aina netissä, varsinkin IT-maailman kopiointiin perustuvassa sisällöntuotossa, yleisin ei välttämättä tarkoita samaa kuin toimivin tai fiksuin tapa.

Fiksuus on suhteellinen käsite. Pitäisi aina määritellä mitä sillä tarkoitetaan – oikeammin, miten sillä päästään tavoitteeseen.

Geo-blokkaus sulkemalla IP-alue kerrallaan on toimiva tapa. Se mitä ohjeet eivät kerro on että se on hidas tapa. Kun suljin sivustoiltani pahiten roskaavat Kiinan, Iranin, Vietnamin ja Venäjän, niin operaatioon meni 19 tuntia ja SSH-yhteyden on pysyttävä auki sen ajan. Kun liitin mukaan pelkästään Saksan, niin aikaa meni noin vuorokausi. Toinen samanmoinen, niin olisi saanut suljettua Ranskan. Silti olisi vielä ollut koskematta koputtajien kaksi muuta suurta keskittymää: USA ja Iso-Britannia – niihin olisi saanut laskea aikaa lisää kaksi päivää.

Eikä se olisi jäänyt siihen. Jos sulkee Saksan, USA:n ja Iso-Britannian, niin on pakko erikseen sallia myös hakukoneet. Ongelmaksi tulee taas aika. Pitäisi uhrata aikaa Googlen, Bingin, Facebookin, Twitterin jne. sallimiseen, johon menee helposti vähintään päivä, ennenkuin voi tuhlata 2 – 4 päivää maiden estämiseen.

Hitaus syntyy siksi, että skripti, on se bashilla tai muulla, suorittaa rivi kerrallaan saman komenninb kuin mitä itse tekisi. Sen saisi paljon nopeammaksi, jos IP-osoitteet voisi viedä suoraan itablesiin. Silloin aikaa kuluisi luokkaa minutti tai kaksi, riippun kuinka nopea olet kirjoittamaan puolen tusinaa komentoa. Hassuus on siinä, että tuon voi todellakin tehdä. UFW:tä ei sinällään tarvita mihinkään.

Varsinainen kysymysmerkki tulee kuitenkin riveistä. Jokainen IP-alue on oma ehtorivinsä iptablesissa. Kiina, Iran, Vietnam ja Venäjä tuottivat noin 23 000 riviä. Voit miettiä paljonko muistia alkaa palamaan kun estetään lisää isoja maita.

Aidosti muistin kulutus ei ole varsinainen aito ongelma. Ongelmaksi nousee noin ison IP-listan hallinta palomuurissa. Siksi IP-osoitteita kannattaa käyttää vain kahdessa tapauksessa:

  • kun estetään vain muutama maa; Kiinan, Iranin ja Ranskan sulkeminen vähentää roskaliikennettä huomattavasti. Uskallan väittää, että luokkaa 80 % haittaliikenteestä poistuu noiden kolmen maan mukana. Mutta jos estettäväksi tulee muita, niin IP-alueiden kautta ei enää ehkä kannattaisikaan estää ja siirtyminen ratkaisusta toiseen on vaivaalloista ja vie aikaa.
  • kun sallitaan hakukoneet; iptables-komennolla voidaan käsitellä vain maita, mutta ufw:n kautta sulkemalla löytyy valmiit neuvot miten siirtää IP-osoitteiden listoja ja listat saa hankittua per hakukone

Ihan ensimmäiseksi

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

iptables -I INPUT 1 -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 konfiguraatio 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>

Iptablesin tyhjentäminen

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.

IP-listat

Saat haettua määrättyä maata koskevan IP-listauksen osoitteesta https://www.ip2location.com/free/visitor-blocker

Jos haluat ladata yhden listan useammasta maasta (maksimissaan 30 maata), niin sinun täytyy luoda sivustolle käyttäjätunnus – muutoin voit ottaa vain yhden maan kerrallaan. Hyöty on hieman kyseenalainen. Jos tarvitset IP2Locatios-sivuston maksullisia palveluita johonkin, niin silloin tilin luonti on itsestäänselvyys. Sen sijaan vain perustason listojen lataamiseen tili ei näyttäisi antavan mitään ekstraa.

Kirjautumisen jälkeen pääset takaisin IP-listojen lataukseen menemällä alatunnisteen Free tools kohdan alta linkistä Firewall IP list.

Jos lataat useamman maan kerralla, niin saat yhden tiedoston. Silloin mahdollisissa ongelmatilanteissa et pysty vapauttamaan maa kerraan, vaan joudut vapauttamaan kaikki samassa tiedostossa olevat maat kerralla. Siksi ainakin itse koen turvallisemmaksi ratkaisuksi ladata jokainen estettävä maa erikseen, joten en tarvitse käyttäjätiliä.

Listaus on oikein noin 98 prosenttisesti, joten on mahdollista, että osa estetyistä maista ei olekaan kieltolistalla tai että sinne joutuu maita, joita ei olisi tarvetta estää.

Muista myös, että IP-avaruus muuttuu koko ajan, joten jokin päivitysstrategia kannattaa suunnitella.

Se, missä muodossa IP-listan otat, riippuu missä ja miten Geo-blokkauksen teet:

  • CIDR, jos estät iptables tietojen kautta eli palomuurin päällä on ufw
  • Apache .htaccess allow, jos määrität sallitut maat .htaccess tiedostossa tai Apache2:ssa virtual hostissa
  • Apache .htaccess deny, jos määrität estetyt maat .htaccess tiedostossa tai Apache2:ssa virtual hostissa
  • Nginx allow, jos määrität sallitut maat Nginxissä
  • Nginx deny, jos määrität estetyt maat Nginxissä

Nginxissä ja Apachessa kopypeistaat tiedot oikeaan paikkaan. Googleta, jos et tiedä. Edetään tästä eteenpäin oletuksella, että käytetään ufw:tä ja iptables tietoja.

Teen kaiken SSH:ssa root-oikeuksilla, joten jos kirjaudut käyttäjänä, niin muista sudo tai su sopivissa paikoissa. Järjestelmänä on Ubuntu 19.01, mutta sillä ei ymmärtääkseni pitäisi olla mitään merkitystä.

  • Lataa haluamasi maan IP-osoitteet CIDR-muodossa. Valitsin (esimerkinomaisesti) neljä maata: China, Viet nam, Iran ja Russia.
  •  Tiedostojen nimet ovat muotoa cidr-<hash>.txt. Nimet kannattaa muuttaa hieman informatiivisemmiksi, kuten esim. cidr-china.txt
  • Siirrä tiedostot serverille haluamaasi hakemistoon. Itse tallennan ne hakemistoon /etc/fail2ban/ip-lists, mutta paikka on oma valinta
  • Siirry SSH:lla hakemistoon, jossa IP-listat ovat
  • Yhdistetään kaikki IP-listat siirtoa varten yhteen tiedostoon:
cat *.txt > all.txt

Tarkkaan ottaen IP2Location sivuston käyttäjäehtojen mukaan tuota ei saisi tehdä, vaan ”koostelistat” saisi tehdä ainoastaan rekisteröidyn käyttäjätilin kautta. Itseasiassa moinen ehto on pätemätön, mutta toki sivustolla on oikeus poistaa käyttäjätili moisesta syystä. Itse en piittaa asiasta, koska kyse on kuitenkin vain IP2Location sivuston resursseista, joita en käytä tuolla yhdistämisellä. Tämä ei ole maailmassa aivan ensimmäinen kerta kun sivustot tekevät idioottimaisia ehtoja yrittäessään pakottaa maksullisiin palveluihin – joita tuo ehto ei edes koske.

UFW ja miten nettiyhteisö neuvoo

Ennenkuin aloitat, niin ota talteen komennolla ufw status > ufw.status palomuurin lähtötilanne. Ihan siksi, että jos homma valahtaakin reisille, niin ainakin on joku muistiinpano mitä on auki ja mitä kiinni.

Kuten aina, niin saman asian saa tehtyä useammalla eri tavalla. Mutta itse käytän näitä SSH:ssa annettavia komentoja:

HUOMAA: insert 1 tarkoittaa, että IP-osoite laitetaan listan ensimmäiseksi, jolloin se käsitellään ensimmäiseksi

  • Asettaa eston kaikkiin serverin palveluihin:
while read line; do sudo ufw insert 1 deny from $line to any; done < all.txt

tai

while read line; do sudo ufw deny from $line; done < all.txt

tai

cat all.txt | awk '/^[^#]/ { print $1 }' | sudo xargs -I {} ufw deny from {} to any
  • Toki voit ajaa jokaisen maan erikseenkin. Jos sinulla on kiire, niin se voi olla jopa järkevää. Jokainen IP-osoite käsitellään erikseen aivan kuin antaisit ne käsin, ja se vie aikaa. Kiina, Iran, Vietnam ja Venäjä yhdessä sisälsivät lähemmäs 23000 riviä ja niiden prosessointi vei 4 CPU/8 GB virtuaaliserverillä aika tarkkaan 19 tuntia. Saksa vei vuorokauden.
  • Saattaa olla järkevää sammuttaa Fail2ban siksi aikaa. Sain muutaman oudon lock-virheen, enkä keksi muuta syytä kuin että Fail2ban asetti samaan aikaan bannia.

Joskus on tarve estää vain yksittäinen osoite tai IP-avaruus.

  • Yksittäisen IP-osoitteen saa estettyä komennolla:
ufw insert 1 deny from 192.0.0.1 to any

Hakukoneiden vapauttaminen

Hakukoneet pystyy sallimaan aivan samalla tavalla kuin mitä estäminen tehdään. Haetaan IP2Location sivustolta IP-listat hakukoneista ja periaatteessa vain vaihdetaan deny muotoon allow. Mutta koska hakukoneet eivät käytä muuta kuin portteja 80 ja 443, niin tehdään täsmäsäätö. Eräällä tavalla varmistetaan, että joku pahantahtoinen ei jollain hassulla tempulla (tai IP-listan virheen takia) saa ohituskaistaa muualle kuin websivuille.

Muutetaan komentoa hieman ja käytetään samaa sovelluksen, appin, ”pikavalintaa”, jolla olet saattanut alunperinkin ufw:n kautta ottaa portit käyttöön. Tilanteen näet komennolla ufw status. Minulla on portit 80 ja 443 avattu appsille ”Nginx Full”.

while read line; do ufw insert 1 allow from $line to any app 'Nginx Full'; done < hakukone.txt

tai jos haluat vapauttaa per portti, niin malli, jota itse en ole kokeillut, on tämä:

while read line; do ufw allow from $line to any port 80 proto tcp; done < hakukone.txt

Maan tai IP-osoitteen vapauttaminen

Jos huomaatkin, että olet tehnyt virheen, niin asioita voi perua. Vaikka IP-osoitteita voikin tuoda massana, niin peruuttamisen takia kannattaa pitää tallella maa- tai hakukonekohtaiset listat.

Yksikertaistetusti nyt vain poistetaan deny sääntö listan IP-osoitteiden mukaan:

while read line; do sudo ufw delete deny from $line; done < maa.txt

tai

cat maa.txt | awk '/^[^#]/ { print $1 }' | sudo xargs -I {} ufw delete deny from {}
  • Voit tehdä saman erikseen sallituille osoitteille. Vaihdat vaan komennon deny muotoon allow. Ja ei, en tiedä toimiiko tuo todella, koska en ole koskaan koittanut, mutta pitäisi.

Voit käyttää säännön poistamiseen myös UFW:n perustoiminnallisuutta. IP-osoitteen saa vapautettua esimerkiksi katsomalla ufw status numbered ja etsimällä eston numero, jonka jälkeen sääntö poistetaan sen avulla:

ufw delete <numero>

Hankala tapa, jos kiellettyjä IP-osoitteita on tuhansia.

Iptables ja miten esto kuuluisi tehdä

UFW on siis vain käyttöliittymä iptablesin päällä. Se on tehty helpottamaan ihmiskäyttäjän elämää yksittäisissä palomuurisäädöissä. Kun aletaan asettamaan kymmeniä tuhansia sääntöjä, niin ufw:tä ei käytetä. Asiat tehdään suoraan iptablesiin.

Nämä ohjeet ovat käytännössä samat kuin mitä tehtäisiin jutussa GeoIP-blokkaus: iptables parilla pienellä muutoksella. Ensinnäkin jätetään asentamatta geo-tunnistus. Sitä ei tarvita, koska tunnistuksen on jo tehnyt IP2Location sivusto. Toiseksi suljettavat IP-osoitteet laitetaan hieman eri paikkaan. Ne voisi asettaa ennen ufw:n tekemiä sääntöjä, mutta laitetaan ne ufw:n haluamaan paikkaan vain siksi, että silloin IP-osoitteita saa hallittua ufw:ssä.

Tuo kuulostaa kylläkin hienommalta kuin mitä se aidosti on. Ei kymmeniä tuhansia rivejä pysty edes selailemaan jollain ufw status numbered komennolla, kuten netin ohjeet niin yltiöpositiivisesti ehdottavatkin.

Käytät samoja IP-listoja kuin edellisessäkin vinkissä.

IP-listan muokkaus

Poista listasta muut rivit kuin IP-osoitteet (esim. search-toiminto 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. Sinun on oltava samassa hakemistossa tiedoston kanssa tai annettava myös polku. Vaihda nimi kielletyt.txt siihen millä tiedosto löytyy.
sed -i -e 's_.*_-A ufw-user-input -s &_' kielletyt.txt
sed -i 's/$/ -p tcp -m multiport --dports 80,443 -j DROP/' hakukone.txt
  • Jos laitat hakukoneet sallituiksi, niin lisätään siihen myös vaaditut asiat. Tässäkin olisi oltava samassa hakemistossa hakukone.txt tiedoston kanssa tai sitten sen alkuun on lisättävä polku. Muokkaa hakukone.txt siihen millä nimellä se oikeasti löytyy.
sed -i -e 's_.*_-A ufw-user-input -s &_' hakukone.txt
sed -i 's/$/ -p tcp -m multiport --dports 80,443 -j ACCEPT/' hakukone.txt
  • Molemmat listat on vielä yhdistettävä. Ei se pakko ole. Jos et yhdistä, niin sitten lisäät ne erikseen iptablesin muokkauksessa. Liitetään lista kielletyt.txt listan hakukone.txt loppuun. Järjestys on oltava ehdottomasti tuo: ensin sallitut, sitten kielletyt. Jos se on päinvastoin, niin salliminen ei toimi – rivit suoritetaan järjestyksessä ja loppuu ensimmäiseen sopivaan.
cat kielletyt.txt > hakukone.txt

Tästä eteenpäin käytetään tiedostoa

  • hakukone.txt, jos viet sallitut ja kielletyt
  • kielletyt.txt, jos viet vain kielletyt IP-osoitteet

Itablesin muokkaus

iptablesin käyttämät asiat ovat kernelin käytössä muistissa. Siksi ne täytyy tuoda muokkaukseen selväkielisenä. Kyseessä on ihan sama temppu kuin iptablesin varmuuskopioinnissa ja palauttamisessa – paitsi että tehdään ensin muokkaukset kopioon ja vasta sitten palautetaan.

  • Tuo iptablesin tiedot siihen hakemistoon, jossa juuri nyt olet. Kohdetiedoston saa nimetä miten haluaa.
/sbin/iptables-save > iptables.save
  • Avaa iptables.save haluamaasi editoriiin. Asiat saa tehtyä shellissäkin, mutta avaamalla tiedosto FTP:llä, kuten FileZilla, suoraan johonkin käyttökelpoiseen editoriin, kuten Notepad++, tekeminen on paljon helpompaa. Jos avaat ulkoiseen editoriin, niin Windowsin Muistiota, Writeriä tai Wordiä ei voi käyttää. Jos muokkaat noilla, niin mukaan tulee luvattomia näkymättömiä merkkejä, eikä tiedosto enää toimi.
  • Etsi ensimmäinen rivi. joka alkaa -A ufw-user-input – löydät sen lähes tiedoston lopusta.
  • Kopypastea tiedoston hakukone.txt (tai kielletyt.txt) sisältö löytämäsi ufw-user-input rivin yläpuolelle. Tuomasi säännöt täytyy olla ennen jo olevia. Tallenna.
  • Siirretään iptablesin uudet säännöt käyttöön. Sinun tulee olla samassa hakemistossa missä äsken muokattu iptables.save tiedosto on tai sitten laitat siihen polun.
/sbin/iptables-restore < iptables.save

Se on siinä. Ei uudelleenkäynnistyksiä, ei mitään. Nyt on käytössä niiden maiden estäminen, joiden IP-osoitteet toit, ja hakukoneiden IP-osoitteet ovat sallittuna. Komento ufw status näyttää paljon mielenkiintoisemmalta estojen kanssa.

Jos teit tuon miettien, niin aikaa kului ehkä vartti. Näppärä tekee koko homman viidessä minuutissa. Melkoinen aikasäästö verrattuna ensimmäiseen neuvoon.

Maan lisääminen, vapauttaminen ja IP-tietojen päivitys

Jos yhtäkkiä päätät lisätä estolistalle uuden maan, niin joudut

  • hakemaan IP-osoitteiden listan IP2Locations sivustolta
  • tekemään jokaisen rivin vaatimat muutokset
  • hakemaan iptablesin tiedot
  • lisäämään uudet IP-osoiteet
  • palauttamaan iptablesin tiedot

Sillä mihin kohtaan iptablesin tietoja uudet IP-osoitteet lisäät, on kaksi ehtoa:

  • tiedot lisätään samaan paikkaan missä ovat muutkin ufw-user-input säännöt
  • DROP ja ACCEPT rivit täytyy olla erikseen

Kieltävien DROP- ja ACCEPT-sääntöjen keskinäisillä järjestyksillä ei ole mitään väliä. Mutta uudet tiedot kannattaa aina lisätä oman ryhmän ensimmäiseksi tai viimeiseksi. Jos ripottelet niitä sinne sun tänne, niin maan vapauttaminen kieltolistalta muuttuu huomattavan vaikeaksi. Niin vaikeaksi, että kannattaa melkein ennemmin aloittaa kokonaan uudelleen alusta.

Maan vapauttaminen estolistalta on sama kuin että poistetaan kaikki maahan liittyvät DROP-ehdot.

  • Avaa maan IP-osoitteet sisältävä lista
  • Katso ensimmäinen ja viimeinen osoite
  • Hae iptablesin tiedot
  • Etsi ufw-user-input riveistä maalistan ensimmäinen ja viimeinen osoite
  • Poista kaikki niiden välistä
  • palauta iptablesin tiedot

Päivittäminen tarkoittaa samaa kuin tekisi kaiken uudestaan alusta asti, mutta tuoreilla tiedoilla. Oikotietä ei ole.

GeoIP vai IP-osoitteilla suodatus?

Ensimmäisellä kerralla GeoIP-suodatuksen tekeminen on hieman työläämpää. IP-osoitteiden listoilla saman saa tehtyä hieman nopeammin ja vähemmällä vaivalla. Mutta kun aletaan keskustelemaan yllpidosta, niin IP-osoitteiden käyttö on jo aika tuskaa.

GeoIP-suodatuksella lisään tai poistan maita yhdellä komennolla. Mitään muuta ei tarvita. Aikaa menee noin kaksi sekuntia.

IP-listoja käytettäessä

  • ensimmäisellä ohjeella maan lisääminen tai poistaminen on jotain luokkaa 12 – 48 tuntia maa, mutta tiedostomuokkauksia ei tarvitse tehdä
  • toisella ohjeella maan lisääminen ta poistaminen vie joitain minuutteja, mutta vaatii kohtuullisesti käsitöitä

Valitse itse.