tavis nörttimaailmassa

EksisONE - artikkeleita ja ohjeita nörttimaailmasta

Nopean WordPressin asennus virtuaaliserverille

Cron

Cron on järjestelmän ajastettu toiminto. Oikeammin, se käynnistää sille kerrottuja toimintoja. WordPressissä on sisäinen cron, mutta sen on (surkea) hätäapuviritys varmistamaan tilanteita, jolloin aitoon croniin ei päästä tai se ei toimi. WordPressin oma cron käynnistyy aina kun joku tulee sivuille. Se tarkoittaa kahta asiaa. Jos kukaan ei tule, niin mitään ajastettua – kuten varmuuskopiointeja, ajastettujen artikkelien julkaisuja tai sähköpostien lähettämistä – ei tehdä. Jos taasen kävijöitä on paljon, niin cron liipaistaan käyttöön joka ainut kerta, kun joku avaa jonkun sivun ja silloin tehdään paljon turhaa työtä serverillä.

Servereillä on oma croninsa, joten käytetään sitä.

Useimmat ohjeet neuvovat tekemään webpalveluihin – eli esim. WordPressiin – liittyvän cronin www-data käyttäjän nimissä. Toiset neuvovat tekemään cronin omalle käyttäjätunnukselleen. Kummatkaan ohjeet eivät kerro, että jos käynnistettävän palvelun tai siihen liittyvän hakemiston (kuten vaikka wp-admin hakemisto) omistajuus onkin yli cronille käytetyn roolin, niin cron ei toimi. Esimerkiksi hakemiston omistajuus on helppo muuttaa FTP-ohjelmalla, jotka lähes järjestään toimivat root-oikeuksilla.

Ainoa oikea, ja turvallinen, ratkaisu on tehdä omalla serverillään cron root-tunnukselle.

crontab -u root -e

Jos muokkaat cronia ensimmäisen kerran, niin sinua pyydetään valitsemaan käytettävä editori. Lienee fiksua valita Nano, koska se on jo tuttu.

Nyt ei kannata nähdä vaivaa alkuperäisen varmuuskopiointiin, mutta jos halut tehdä sen, niin crontab-tiedostot löytyvät hakemistosta /var/spool/cron/crontabs ja ovat tavallisia tekstitiedostoja.

Poista kaikki. Kopioi tämä ja liitä tilalle:

Vaihda ensimmäiselle riville sähköpostiosoitteesi. Sitä käytetään oletuksena, jos sallit vaikka komennon epäonnistumisesta kerrottavan sähköpostilla.

Ei mennä nyt syvemmin cronin toimintaa ja rakennetta läpi, mutta katsotaan silti tärkeimmät asiat:

  • */1 * * * * tarkoittaa, että cron pyörähtää joka minuutti. Perusteltua esimerkiksi aktiivisille foorumeille tai verkkokaupoille. Sen voi muuttaa esimerkiksi */5 jolloin cron ajetaan joka viides minuutti – verkkokaupoissa tuo tarkoittaisi, että asiakkaan sähköpostit lähtisivät maksimissaan 5 minuuttia tilauksen jälkeen.
  • php -q /var/www/eksis.dev/public_html/wp-cron.php tarkoittaa, että PHP ajaa wordpressin oma cronin wp-cron-php ja -q tarkoittaa, että turhia höpistä työn aikana eli ilmoituksia koodin suorittamisesta ei tule – no, eikä niitä kukaan ole lukemassakaan, kun tapahtuvat taustalla.
  • >/dev/null 2>&1 ohjaa kaikki koodin suorittamisesta tulevat viestit Suureen Nimettömään eli tuhoaa ne, myös virheilmoitukset. Jos olet epävarma cronin toimivuudesta, niin tämä kannattaa poistaa. Muutoin sillä estetään turhat ilmoitukset. Sen päällä pitämistä edes virhetilojen takia kannattaa harkita kahteen kertaan. Ajattele, jos cronin käynnistämä koodi on syystä tai toisesta mennyt rikki nukkumaan mentyäsi ja päätät nukkua seuraavana aamuna pitkään – sähköpostissasi on aika monta postia, kun cron on kertonut ongelmistaan 12 tunnin aikana jokaikinen minuutti. Tarkkaan ottaen sinulla olisi 720 uutta lukematonta viestiä.

Melkoinen osa toiminnoista luottaa croniin. Esimerkissä katsotaan joka kuun 15. päivä, onko WP CLI saanut päivityksiä. Alimpana on kommentoituna geo-eston päivitykset (koska sitä ei ole asennettu, vielä).

Jokainen domain tarvitsee cronin, ainakin jos se on tehty WordPressillä (itseasiassa jokainen julkaisujärjestelmä käyttää cronia). Et pysty tekemään sääntöä, että ajetaan tämä jokaiselle domainille, tai vielä vähemmän niin, että se ajettaisiin jokaiselle WordPress-asennukselle. Joudut laittamaan cronin erikseen ja käsin. Hyvät uutiset ovat, että se täytyy tehdä vain kerran.

Esimerkissä on kaksi vaihtoehtoista tapaa ajaa cron WordPress-sivustolle, tässä /var/www/eksis.dev/public_html. Toisessa se ajetaan PHP:llä, toisessa WP CLI:n komennolla. Kummatkin ovat oikein ja molemmat toimivat. Itse en käytä WP CLI:tä siksi, että se voi mennä rikki, mutta silti kaikki muu toimisi. Sen sijaan jos PHP menee rikki, niin mikään ei toimi ja cron on viimeinen huolenaihe.

Jos googletat, niin löydät melkoisestikin esimerkkejä, joissa cron ajetaan käyttämällä komentoja wget ja curl. Niissä on pari puutetta, jostain kumman syystä niin suosittuja kuin ovatkin. Niiden ongelmat johtuvat siitä, että molemmat ajetaan webserverin läpi. Se taasen tarkoittaa kahta asiaa. Webserverin rajoitukset ovat mukana ja se saattaa tuoda hankaluuksia, kuten time-out virheitä, jos vaikka siirrät satojen megojen backuppia Amazonin serverille. Minulle, nyt myös sinulle, jos olet mennyt ohjeen mukaan, suurin este kummallekin on cache. On tehtävä erillinen sääntö, jonka kautta kutsu saadaan menemään sivustolle asti ilman cachea. Me haluamme saada cronin toimimaan, emme saada tallennettua vastausta Nginxiltä jostain, joka tehtiin kauan sitten.

Molemmat, niin PHP kuin WP CLI, ajetaan palvelimen ”sisällä” eikä webserveri liity niiden toimintaan mitenkään.

Fail2ban, asetukset

Fail2bannin asettaminen vaatii hieman enemmän kuvioita, mutta ei se mikään vaativa juttu. Ei sen kummempi mitä tähänkään asti on tehty. Tehdään Fail2banin asettaminen ilman sen suurempia kuviokellunnan teorian opskeluja. Voit lukea jutun Fail2banin asennuksesta, jos haluat ymmärtää paremmin mitä on tehty.

Kokeillaan onko sinulla sellainen apulainen, jolla saadaan siirrettyä tarvittavat Githubista, jossa on kopio omasta (toimivasta) asennuksesta:

git --version

Jos sait versionumeron, niin kaikki on hyvin. Jos et, niin asennetaan se:

apt install git

Pysäytetään Fail2ban:

systemctl stop fail2ban

Laitetaan asentamasi Fail2ban talteen:

mv -T /etc/fail2ban /etc/fail2ban.orig

Siirry hakemistoon /etc:

cd /etc

Kloonataan Githubista viritetty versio:

git clone https://github.com/eksiscloud/fail2ban.git

Muokataan asetuksia:

nano /etc/fail2ban/jail.local
  • Lisää rivin ignoreip = 127.0.0.1/8 ::1 loppuun välilyönneillä erotettuna kaksi IP-osoitetta: dropletin IP sekä koti-IP:si
  • Vaihda lohkon Actions alusta oikeiksi:
    destemail = admin@example.tld
    sender = fail2ban@example.tld

Tehdään yksi mukamas-logi:

mkdir /var/log/custom
touch /var/log/custom/manual-ip.log

Sammutetaan pari sellaista, jolla et tee mitään:

mv /etc/fail2ban/jail.d/varnish-420.conf /etc/fail2ban/jail.d/varnish-420.conf.stop
mv /etc/fail2ban/jail.d/varnish-666.conf /etc/fail2ban/jail.d/varnish-666.conf.stop

Varmistetaan, että ei ole kirjoitusvirheitä:

fail2ban-client -t

Käynnistetään Fail2ban:

systemctl start fail2ban

Katsotaan tila:

fail2ban-client status

Nyt sinulla on pari vahtikoiraa lisää.

Nginx ja botit

Botit, olivat ne sitten koputtelijoita tai sisältöä varastavia SEO-yrityksiä, aiheuttavat usein enemmän kuormaa kuin kävijät. Kun sivustolla, jolla ei ole estetty botteja, alkaa olla kuormitusongelmaa, niin ensimmäiseksi kuuluisi hoitaa ötökkäongelma pois päiväjärjestyksestä. Mutta yhdelajin fakta myös on, että kun botit ja käyttäjät alkavat yhdessä aiheuttaa ongelmia, niin ensimmäisenä päivänä siirretään kaikki virtuaaliserverillä ja toisena päivänä estetään botit.

Nginx on tehnyt bottien estämisen todella helpoksi. Lisäksi se tekee sen kustannustehokkaasti: Nginx ei kerro boteille, että pääsy on kieletty, vaan katkaisee niiltä mykkänä yhteyden ja jättää botit roikkumaan tyhjän päälle tuhlaamaan aikaansa. Kun tuo yhdistetään lisäksi Fail2banniin, niin yritettyään kerran turhaan, niin niiden IP-osoite estetään palomuurissa ja seuraavalla kerralla ne eivät pääse edes Nginxille saakka.

Ensin tarvitaan lista, josta Nginx näkee mitkä on estettävä:

nano /etc/nginx/conf.d/blockbots.conf

Kopioi sinne itse käyttämäni lista.

Muokataan virtual hostin konffia:

nano /etc/nginx/sites-available/eksis.dev

Lisää tämä ensimmäiseen server -lohkoon heti logien asettamisen jälkeen:


# Estetään pahat botit
if ($bad_bot = 1) {
return 444;
}

Jos haluat sallia jonkun kieltolistalla olevan, niin kommentoi rivi risuaidalla #.

Tuossa on yksi puute. Se estää komentojen wget ja curl käytön myös sinulta omalla serverillä. Se ei ole välttämättä haluttua. Ne saadaan vapautettua yhdellä ei-niin-tyylikkäällä tempulla. Nginxissä on nimittäin melkoisen vaikea sallia user agentia määrätyllä IP-osoitteelle (yksi syy miksi itse käytän Varnishia; toinen on se, että se on tehokkaampi cache kuin Nginx).

Kumpaankin komentoon saa liitettyä haluamansa user agentin. Joten tehdään alias:

nano ~/.bashrc

Etsi paikka, johon lisäsit wp komennon aliaksen. Lisää sen jälkeen nämä:


alias curl='curl -A \"kurl\"'
alias wget='wget -U \"vget\"'
alias wgett='wget'
alias curll='curl'

Jos sinulle tulee joskus muistikatkos, etkä enää ole varma mitä alias-komentoja sinulla on, niin komenna shellissä alias. Se kertoo.

Monit

Tarvitset järjestelmän, joka vahtii systeemiä ja sen palveluja. Olisi hyvä tietää mahdollisimman nopeasti, jos webserveri tai koko systeemi on kaatunut. Maksullisia palveluja löytyy tolkuttoman paljon, mutta pelkästä perusprosessien seurannasta on täysin turha maksaa kuussa luokkaa 20 – 200 euroa. Asia muuttuu jos ehdottomasti tarvitset niiden mukana tulevia muita analyysityökaluja. Silloin kannattaa vilkaista vaikka New Relic, mutta se ei ole halpa. Eikä helppo.

Pelkkään valvontaan löytyy simppeli työkalu, Monit. Sen asennus on… aika tuttua:

apt install monit

Siirretään koko asennus syrjään:

 mv /etc/monit /etc/monit.backup

Käydään hakemassa minulla toimiva paketti:

cd /etc
git clone https://github.com/eksiscloud/monit.git

Siirrytään hakemistoon:

cd /etc/monit && ls

Avaa Monit asetukset, sillä siellä on jonkun verrankin muutettavaa:

nano /etc/monit/monitrc

Ensimmäisellä rivillä on set daemon 60. Arvo in sekunteja ja 60 tarkoittaa, että palveluiden tila tarkistetaan kerran minuutissa. Voit muuttaa sitä halusi mukaan. Minä olen ehkä hieman hysteerinen ja aika monet käyttävät esimerkiksi arvoa 300 eli 5 minuuttia. Eräälle asiakkaalleni riittää 900 eli 15 minuuttia. Kysymys on lähinnä siitä, että kuinka nopeasti haluaa tiedon. Jos tietää, että ei pääse heti korjaustoimiin, jos jokin hajoaa, niin turhahan tilaa on silloin tolkuttoman usein tarkistaa. Lisäksi osa palveluista niiaa ihan muuten vaan tai netti hidastelee, jolloin minuutin tai lyhyemmillä ajoilla saa enemmän ilmoituksia. Pidemmällä ajalla moisia ei huomata, ellei se satu osumaan juuri sille hetkelle, kun tilaa tarkistetaan. Mutta minä haluan tietää kuinka paljon on lyhyitäkin katkoksia.

Etsi rivi from: monit@eksis.eu – se löytyy lohkosta, jossa säädellään ilmoituksena lähetettävän sähköpostin muotoa. Voit muokata sitä ja ainakin kääntää suomeksi, jos haluat, mutta lähettäjän sähköpostiosoite kannattaa laittaa kohdalleen. Mallissa oleva malliosoite tulee ”päädroplettini” hallinnasta, mutta sinä varmaan haluat siihen jonkun muun.

Hieman alempana on tämä:


set mailserver email-smtp.eu-west-1.amazonaws.com port 587 # If the region is Ireland
username "a lot of characters"
password "even longer one"

Tässä asetetaan sähköpostipalvelimen tiedot, jonka kautta ilmoituksia lähetetään sinulle. Jos sinulla on ne jo tiedossa, niin aseta vastaavat. Jos, tai kun, sähköpostin välittämistä ei ole vielä asennettu serverille, niin kommentoi rivit risuaidalla # ja palaa takaisin myöhemmin muokkaamaan ne.

Rivi set alert admin@example.tld not on { instance, action } kertoo mistä syistä ilmoitus lähetetään ja mihin osoitteeseen. Korvaa samantien osoite admin@example.tld sillä sähköpostiosoitteella, johon haluat (tulevaisuudessa) ilmoitukset lähetettävän.

Vaihda tähän allow example.com se domain, jonka alta haluat Monitin webhallinnan löytyvän. Jos sinulla ei ole kuin yksi, niin valinta on helppo. Jos haluat Monitin graafisemman liittymän näkyvän IP-osoitteella, niin voit vaikka kommentoida tämän.

Tämä rivi on syytä muokata: allow joedoe:"passwd". Siinä asetetaan käyttäjätunnus ja salasana web-hallintaan. Vaihda joedoe halumaksesi, kuin myös salasana passwd.

Vaihda riville check system 104.248.141.204 dropletisi IP-osoite.

Tallenna ja ollaan valmiita säätämään monitoreita.

Monitin käytössä olevat monitorit voivat olla kahdessa hakemistossa: conf.d ja conf-enabled. Historiallisista syistä minulla hakemistojen käyttö ei ole ehkä loogisin mahdollinen, mutta minulla on seurattavat sivustot hakemistossa conf.d ja monitoroitavat palvelut hakemistossa conf-enabled. Hakemisto conf-available on varasto.

On ihan se ja sama miten nimeät monitorit, kunhan ne ovat jommassakummassa hakemistossa. Jos halut ottaa käyttöön jonkun muun hakemiston, niin tee sellainen ja kerro sen sijanti monitrc tiedostossa ihan lopussa.

Monitoreita voi ottaa käyttöön ja poistaa käytöstä samalla tavalla kuin Nginxissä virtual hosteja eli tekemällä hakemistosta conf-available symbolisen linkin hakemistoon conf-enabled. Minusta tuo on hankalaa ja saam tehtyä saman ihan vaan raahaamalla tiedostoja FTP:ssä hakemistosta toiseen tai käyttämällä mv komentoa.

Siirry monitorien hakemistoon, jossa nyt on sivustoja:

cd /etc/monit/conf.d

Poista kaikki paitsi yksi. Minä teen sen FTP:llä mutta jos haluat poistaa komentoriviltä, niin komento on rm -f <tiedosto>. Muuta jäljelle jääneen nimi – itse tekisin sen shellissä esimerkiksi komennolla mv eksis.one eksis.dev – mutta aidosti muuttaisin nimenkin FTP:llä, koska olisin juuri poistanut turhat domainit FileZillalla.

Avaa monitori:

nano eksis.dev

Muuta ensimmäiselle riville check host eksis.one with address www.eksis.one oikea url. Minä siis vaihtaisin www.eksis.one tilalle www.eksis.dev. Tee sama muutos riveille

  • with http headers [Host: www.eksis.one, Cache-Control: no-cache]
  • and request /pong/ with content = "www.eksis.one"

Lyhyesti sanottuna tuo tarkastaa löytyykö portista 443 sivua pong (samalla tarkistetaan SSL-sertifikaatin ikä) ja jos löytyy, niin kaikki on hyvin. Porttia 80 ei tarkasteta, koska sitä kautta ei ketään päästetä sisälle, vaan tehdään uudelleenohjaus https-porttiin 443.

Nyt täytyy tehdä sivu pong. Tehdään se WordPressin sivuna, niin silloin saadaan samalla testattua, että toimiiko PHP ja WordPress – pelkkä tekstitiedosto kertoisi vain, että Nginx toimii.

Tee normaalisti sivu WordPressissä. Jos osoitemuotosi on joku muu kuin pelkkä sivun nimi, eli siihen tuleekin esim. kategoria mukaan, niin muokkaa siltä osin monitoria – nyt etsitään osoitetta https://www.eksis.dev/pong/.

Pelkkä tyhjä sivu ei riitä, vaan sieltä on löydyttävä monitorin määräämä teksti www.eksis.dev – joka asetettiin rivillä and request /pong/ with content = "www.eksis.dev".  Yleensä tavalliset kävijät eivät linkittämättömille sivuille eksy, mutta varmuuden vuoksi olen käyttänyt tämän tapaista tekstiä:

Tämä on tekninen sivu, jolla ei muuta tarkoitusta kuin sanoa: www.eksis.dev

Tee vastaavat kaikille domaineillesi, jos sinulla on useampi. Pystyt valvomaan myös muualla olevia sivustoja, joten pystyt tekemään monitoroinnin vaikka joltain toiselta dropletilta.

Siirrytään palveluiden muokkaamiseen:

cd /etc/monit/conf-enabled

Siirrä ainakin monitorit apache2 ja varnish hakemistoon /etc/monit/conf-available. Jos/kun sinulla ei ole vielä Postfixiä asennettuna, niin siirrä sekin. Palauta se kun olet asentanut sähköpostin välityksen.

Niissä ei ole sinällään mitään muokattavaa, vaan toimivat sellaisinaan – kunhan sinulla on palvelut asennettu ja otettu käyttöön systemctl enable komennolla. PHP-FPM on muokattava, jos sinulla on jokin muu PHP:n versio kuin 7.4.

Varmistetaan vielä, että tiedoston monitrc oikeudet ovat oikein.

chmod 0700 /etc/monit/monitrc

Monit tarvitsee itselleen palomuurin portin. Aukaistaan se.

ufw allow 2812

Varmistetaan, että Monitkin käynnistetään serverin käynnistyessä:

systemctl enable monit

Varmistetaan, että ei ole kirjoitusvirheitä:

monit -t

Käynnistetään Monit:

systemctl start monit

Nyt voit vilkaista tilaa

  • komentorivillä komennolla monit status
  • selaimessa osoitteessa http://<ip-osoite>:2821
Monit komentoriviltä

Jos selaimessa IP-osoitteen käyttö on tylsää, niin voit liittää sen myös domainiisi. Yksi reunaehto on: sinulla ei voi silloin olla monit-nimistä kategoriaa, artikkelia tai tagia, jos nimi on juuressa. Se johtuu siitä, että Monit näkyy osoitteessa https://example.tld/monit

Avaa virtual hostin konffi:

nano /etc/nginx/sites-available/eksis.dev

Lisää ennen cachen määrityksiä eli ennen riviä tämä. Vaihda IP-osoite dropletisi osoitteeksi:


location /monit/ {

   rewrite ^/monit/(.*) /$1 break;
   proxy_ignore_client_abort on;
   proxy_pass http://161.35.23.171:2812;
   proxy_redirect http://161.35.23.171:2812 /monit;
   proxy_cookie_path / /monit/;
}

Tarkistetaan, että ei tullut kirjoitusvirheitä:

nginx -t

Ladataa Nginx uudelleen:

systemctl reload nginx

Nyt Monitin statukset näkyvät osoitteessa https://www.eksis.dev/monit/