2012. október 14., vasárnap

Távoli elérés

Eddig csak a helyi hálózatunkon értük el a gépet, de mi van akkor, ha valahonnan máshonnan, munkahelyünkről, barátoktól, vagy akár okostelefonról, bárhonnan el szeretnénk érni? Ehhez szükség lesz a gép külvilág számára történő megnyitásához, ami viszont rejt némi biztonsági kockázatot. Lássuk, mit is tehetünk ennek csökkentésére.
Először is, nézzük mit akarunk: el szeretnénk érni a gépet ssh-n keresztül, ahogy most is, de nem csak a lokális hálózaton, hanem bárhonnan. Ennek egyik akadálya, hogy a gép a külvilág számára nem létezik, csak a lokális hálózatnak van egy ip-címe, amit esetleg elérhetünk. Ez az ip-cím (az internetszolgáltatónkon keresztül) a routerünkre mutat, ha "tárcsázzuk", oda fog beérkezni. Vagyis meg kellene mondani a routernek, hogy ha egy bizonyos módon próbál valaki kapcsolódni, azt irányítsa át a lokális hálózat egyik gépére, mégpedig a raspberrinkre. A "bizonyos módon" alatt természetesen az ssh-t értem, ami egy meghatározott portot használ, az átirányítást pedig "port forward"-nak hívják, minden 1000 Ft-os kínai routernek alapszolgáltatása. De ne szaladjunk így előre, előbb állítsuk be, aztán nyissuk ki a kaput.

Arra gondoltam, hogy a klasszikus jelszavas bejelentkezés nem is elég egyszerű, nem is elég biztonságos, ezért inkább kulcspáros autentikációt alkalmazunk. Az ssh-val generálunk egy kulcspárt (ezt a saját gépünkön csináljuk):
ssh-keygen -t rsa -b 4096 -f raspiaccess
A végén a "raspiaccess" egy fájlnév, ez lesz a kulcsaink neve. Kérni fog egy jelszót, ez magának a kulcspárnak a jelszava. Ha gondoljuk, adjunk meg valamit, ha nem akarunk ilyet, csak hagyjuk üresen, enter-enter, így nem lesz jelszavas a kulcspárunk. Ez még egy plusz védelem, ugyanis ha valaki megszerzi a kulcsunkat, még nem tudja használni, ha nem tudja a jelszót is. Amint a paramétereken látszik, 4096 bites RSA kódolást választottunk. Miért is?  Úgy tudom, a 2048-as is gyakorlatilag feltörhetetlen. MÉG. :) Ki tudja, mit hoz a jövő. Ez az indokolatlanul magas bithosszúság viszont valószínűleg még jó ideig az lesz, hacsak nem sikerül valahogyan megkerülni. (a legjobb lakat sem ér semmit, ha papírdobozra tesszük) Ez természetesen csökkenti a kapcsolat sebességét, de mivel ssh-n keresztüli eléréshez használjuk, nem érdekes, nekem észrevehetetlen volt a sebességben. Akinek lassú, generálja újra a bitszám megadása nélkül, csak "-t rsa" -val. Akár egy tesztet is csinálhat, meg fogja látni hogy nincs különbség.

Rendben, megvan a kulcsunk, a privát "raspiaccess" és a publikus "raspiaccess.pub". Az eljárás az, hogy a publikust hozzáadjuk a raspi sshd szerveréhez, és beállítjuk, hogy csak azokat engedje be, akik rendelkeznek a kulcs másik felével. Ha rendben működik, letiltjuk a jelszavas bejelentkezést, és meg is van.
Figyelem! Nagyon körültekintően járjunk el a konfigurálás során, mert könnyedén kizárhatjuk magunkat a rendszerből. Ilyenkor csak a billentyűzet/monitor rádugás segít, hogy rendbe hozzuk.
Először is, másoljuk fel a kulcs egyik felét a raspberryre
ssh-copy-id -i raspiaccess.pub <user>@<raspi ip címe>
A távoli user jelszavának megadása után felmásolja a kulcsot, valami ilyesmit visszaadva:
Now try logging into the machine, with "ssh '<user>@<raspi ip címe>'", and check in:
  ~/.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.
Ez azt jelenti, hogy OK. Próbáljuk ki hogy működik-e, ha most megpróbálunk belépni a raspira úgy, hogy  megadjuk a kulcspárunkat, vagyis
ssh -i raspiaccess <user>@<raspi ip címe>
és nem adtunk meg a kulcspárnak jelszót a generáláskor, akkor azonnal be is enged, ha volt jelszó, akkor azt kell használnunk, hogy feloldjuk a kulcsot. Ha sikerül belépni, örülünk, állítsuk be a szervert. su-zzunk át rootba, vagy simán sudózzunk, ahogy jól esik.

Nyissuk meg a konfigfájlját:
vim /etc/ssh/sshd_config
Először keressük meg a
PermitRootLogin
sort és állítsuk "no"-ra, ez azért kell, hogy root-al sehogyse lehessen belépni ssh-n. Ha root-ra van szükség, lépjünk be sima felhasználóval, és su-val lépjünk át, így jobb, ssh-n ne használjuk a root-ot soha. Szóval, nézzen így ki:
PermitRootLogin no
Most keressük meg a "PasswordAuthentication", a "UsePAM", és a "ChallengeResponseAuthentication" opciókat, és állítsuk mindet "no"-ra, a "PubkeyAuthentication"-t pedig "yes"-re, bár ez alapértelmezésben is be van kapcsolva, de jobb a biztonság. Valahogy így nézzenek ki:
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
PubkeyAuthentication yes 
Ennyi volt, most már kizártuk a bejelentkezés összes módját, kivéve a kulcspárosat. Indítsuk újra az sshd-t:
systemctl restart sshd
Lépjünk ki, (ha besuztunk rootal, akkor onnan is, majd a sima usertől, hagyjuk el a gépet), és próbáljunk meg belépni a sima userrel/jelszóval. Ha nem megy, akkor minden rendben. Most próbáljunk meg a kulcspár nálunk lévő darabját megadva, ahogy az előbb. Ha sikerül, minden rendben. Ha nem, és a fájlnév is, az elérési út is, a usernév is jó, akkor sikeresen kizártuk magunkat, keressük elő a billentyűzetet. :) Lépjünk be root-al (lokális loginnál nem érdekes, ugye), és nézzük meg:
  • a <user>/.ssh/authorized_keys fájlban szerepel-e a kulcsunk publikus része (sima szövegfájl, ha a pub fájlunkat megnyitjuk, összehasonlíthatjuk a tartalmukat)
  • az /etc/ssh/sshd_config fájlban be vannak-e állítva a fenti beállítások ("PasswordAuthentication", "UsePAM" és "ChallengeResponseAuthentication" "no", "PubkeyAuthentication" pedig "yes")
  • nincs-e szintaktikai hiba a fájlban, pl. valamelyik opció nincs-e elírva, vagy a neve és a "no" (vagy "yes") között van-e szóköz
  • a beállított opciók előtt nincs-e #, megjegyzésjel, ugyanis akkor bármit is írtunk, nem számít, nem veszi figyelembe.
Ha sikerült megoldani a problémát, kezdődhet az utolsó fázis, publikáljuk ki az ip-címünket. Ehhez szükségünk lesz egy szolgáltatóra, aki a mi dinamikusan változó, a netszolgáltatónktól kapott címünket hozzárendeli egy fix domainhez. Ilyenek vannak páran, van ingyenes is, fizetős is, de akár a szolgáltatónktól is vehetünk fix ip-t (legfeleslegesebb megoldás, csak e miatt) Az ilyen szolgáltatók úgy dolgoznak, hogy van egy kis kliensprogram, ami periódikusan ellenőrzi a gép ip-jét, és elküldi a cég szerverére, hogy hozzárendelje a domainhez. Telepítsük hát fel a választott szolgáltató kliensét. Én a no-ip.org-ot mutatom be most, de a többi is hasonló. Csak keressünk rá a "free dynamic dns service"-re, és válasszunk egyet, amelyiknek van linuxos kliense, és használjuk azt.

Tehát, no-ip.org-os kliens benne van a repoba, csak telepítsük a szokásos módon:
pacman -S noip
A telepítés végén ki is írja, hogy konfigurálnod kell. Tegyük is ezt (root jog kell):
noip2 -C - Y
Írjuk be a szolgáltatónál regisztrált mailcímet, jelszót, majd állítsuk be hogy melyik domainhez szeretnénk. Aztán még rákérdez a frissítési intervallumra, ez legyen mondjuk 5 perc. Ennyi időnként frissíti a domainhez tartozó címet. A konfigurálás után még készítenünk kell neki egy service-t, hogy induláskor el is induljon:
vim /etc/systemd/system/noip2.service
Legyen ez benne:
[Unit]
Description=No-IP updater
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/noip2

[Install]
WantedBy=multi-user.target
Mentsük el, és aktiváljuk is:
systemctl start noip2.service
Ha rendben elindul (a systemctl status noip2.service nem ad hibát), engedélyezzük a bootoláskori indítást is:
systemctl enable noip2.service
Ez is megvan, most nézzük meg egy böngészőben a lokális hálózaton kívülről, hogy a regisztrált címen elérhető-e a gép, elvileg minden rendben kell legyen. Ehhez be kell állítani az elején említett port forwardot. Minden router tudja, de mindegyikben másképpen kell, ezért csak általánosságokat tudok mondani. Viszont van egy ilyen oldal, http://portforward.com/, itt bal oldalon ha kiválasztottuk a routerünket, lépésről lépésre, képekkel illusztrálják szépen, hogy kell beállítani. Ha nem találjuk a mi készülékünket, nyugodtan válasszunk egy hasonlót, nem sok különbség lesz. Vagy egyszerűen lépjünk be a routerbe, keressük meg a port forward menüpontot, és állítsuk be. A lényeg, hogy a 22-es porton érkezőcsomagokat irányítsuk a raspberry ip címére. Persze, ha a 22-est átállítottuk valami másra, akkor oda, ez egyéni dolog. Igazából mindegy, ha valaki be akar lépni, port scanner rögtön kidobja hogy hol van az ssh, ha nem a 22-esen. Annyiból praktikus, hogy ha pl.: munkahelyről akarunk belépni, és ott pl.: nincs nyitva a 22-es, hanem valami más, akkor azt kell használjuk. Az sshd-nek több portot is be lehet állítani, a konfig fájlban ott van az elején a "Port <portszám>", ha ez többször szerepel akkor azokon fog figyelni. Pl: a
Port 22
Port 222
Port 2222
Azt jelenti, hogy ezen a három porton tudunk csatlakozni. Nyilván, ilyenkor az ssh kliensnek a megfelelő portot kell beállítani, vagy a -p paraméterrel, vagy ha putty, akkor valami menüs-dialógos-kattintós módszerrel. Abban a szerencsés helyzetben vagyok, hogy munkahelyemen sem vagyok kénytelen windows-t használni, így nem kell a nyűgjeivel foglalkoznom, így a windowsos beállításokat a google fogja kifejteni, akit érdekelnek.

Ezek után, kívülről ugyanúgy ssh-zhatunk mint a lokális hálózatról, de persze a cím a publikált cím legyen.

Ennyi a történet, remélem érthető volt. A gépünkön létrehozott kulcsfájl privát részét, a kiterjesztés nélküli "raspiaccess" fájlt tartsuk nagy becsben. Külső használathoz vagy horcoljuk magunkkal egy pendrive-on, vagy pl.: küldjük el magunknak egy jelszavazott fájlban (legyen pl.: 7z vagy rar, a 7z pl.: AES-256-ot használ, az elég biztonságos), vagy egy spideroak-fiókba dobhatjuk, esetleg egy truecrypt-es voluméban... de ez már egyéni ízlés és paranoia-fok kérdése. :)

Amiket itt leírtam ne csak a raspberryre alkalmazható, gyakorlatilag minden linuxon hasonlóan kell eljárni ha ilyet szeretnénk. Amiről még írnék ezzel kapcsolatban, az az, hogy most, hogy kinyitottuk a gépet a külvilág felé, tartsuk észben, hogy az ssh-n kívül van még nyitott szolgáltatás ami támadási felület lehet. Igen, a webszerver, a rajta csücsülő rutorrent-el. Ha a port forwardnál az nginx portját is beállítjuk, akkor onnantól az is elérhető kívülről, de ezt egyelőre nem akartam. Ez már éppen elég hosszú lett, de a következő részben leírom, hogy hogyan készítsünk SSL tanúsítványt és aláírást hozzá, hogy a kapcsolat HTTPS-en keresztül legyen titkosított. (Az is kliens autentikációs lesz, de lehet írok majd a sima http-auth-ról is)

Nincsenek megjegyzések:

Megjegyzés küldése