Nginx – WebDAV uzivatelske adresare

Po dlouhe dobe jsem se opet vratil k tematu WebDAV disku pro uzivatele. WebDAV ma totiz velkou vyhodu – jeho klient je a to v sifrovane verzi (https) dostupny ve vetsine verzi Windows. Pouzitelny od XP a vyse.

Jak presne nastavit Windows, aby se dokazaly pripojit k WebDAV popisu nekdy jindy. Neni to totiz vubec snadne. Dnes ukazu jednochuchy funkcni config nginx v Debianu 8.

Instalace a nastaveni

Nejdriv nainstalujeme nginx a to balicek extras:

pote vytvorime soubor s nastavenim:

Server posloucha nesifrovane na portu 80 a vsechny pozadavky presmeruje na sifrovanou verzi.

WebDAV pouzivame pouze pres sifrovane https spojeni. Na zacatku je definice SSL a aktualne bezpecnych algoritmu. Pote nasleduje document root.

Nejdulezitejsi je direktiva location. Pod / zamkneme uzivatele dle jeho uzivatelskeho jmena ($remote_user) do adresare stejneho jmena. Config je dost samovysvetlujici.

Dulezite je vytvorit soubor s uzivatelskymi jmeny a hesly. Ja jsem pro par uzivatelu pouzil obycejny htpasswd znamy z Apache. Bylo by uzitecne vyresit integraci na PAM, pripadne tahat uzivatele z SQL.

Nginx pouziva stejny format souboru htpasswd, jako Apache. Nema vsak nastroj na jeho vytvoreni. Takze mame nekolik moznosti. Generovani online webovymi nastroji je nepohodlne a neni bezpecne posilat nekomu neznamemu heslo. Druhou moznosti je nainstalovat balicek s apache nastroji – ale to zni, jako urazka nginx 😉
Ja pouzivam ke generovani htpasswd zaznamu nasledujici prikaz, vystaci si s OpenSSL:

pote staci vytvorit adresare pouzite v configu, nastavit prava a restartovat nginx:

Diskove kvoty

Vse je jednoduche az na diskove kvoty. U klasickych protokolu pro pristup k linuxovemu filesystemu jde bez problemu pouzit kvoty na ext4 filesystemu. Nging+WebDAV ale tyto kvoty ignoruje (mozna s PAM uzivateli by sly, nevim).
Stackoverflow je plny reseni problemu s kvotami – prakticky nevyreseno.
Nejcasteji se doporucuje pomoci dd udelat image s ext4 a ten primountovat nekam do filesystemu a nasledne pouzit pro WebDAV uzivatele prave tento mountpoint. Cele je to sice funkcni, ale hodne neefektivni. Dochazi k obrimu plytvani mistem na disku kvuli zbytecne velkym alokovanym obrazum.

2016-10-30-235623_1366x768_scrot

 

 

Spousteni prikazu uvnitr kvm qemu virtualu

Potreboval jsem jednoduche testovaci prostredi. Ve virtualu kvm/qemu mit nastaveny Debian a v libovolne jine distribuci na pc si ho spustit a snadno pouzivat. Chtel jsem vse automatizovane, abych mohl psat v textovem editoru prikazy a ty se po ulozeni ihned provedly ve virtualu.

Dnes uz bych asi pouzil tty0 a virtualni seriovy port do virtualu, avsak nize popsane reseni je taky funkcni – a napr. propojeni Samby je zajimave.

Ukazka

Instalace

Nyni je potreba do virutalu nainstalovat Debian s SSH serverem.

Po instalaci Debianu do virtualu se do nej prihlasit a vytvorit soubor /usr/local/bin/asdf s obsahem:
Dalsi potrebny kroky:
do /etc/rc.local pridat pred radek exit 0:
do /etc/fstab pridat (nakonec dat prazdny radek):
Pridat do virtualu svuj SSH klic:

 

Pouzivani

Spustit virtual

a do souboru /home/martin/qemu/data/cmd.sh pridat libovolne prikazy:
ihned po ulozeni souboru se prikazy ve virtualu vykonaji (posilaji se pres rouru do bashe pod rootem).
 
Do virtualu se da prihlasit pres ssh: ssh -p 2222 root@localhost (bez hesla, prihlasovani klicem).
 

Odkaz na puvodni gist – je to tam lepe formatovane 🙂

Zvetseni ext4 oddilu ze skriptu

Tentokrat si ukazeme rychle expandovani EXT4 oddilu na SD karte a to ze skriptu, neni potreba zadny interaktivni uzivateluv vstup.

Nejcasteji je potreba expandovat filesystem na obrazech pro Raspberry Pi a ostatni SBC. Vetsinou maji ke stazeni 4GB image SD karty, ktery jde ale bez problemu nahrat treba na 16GB kartu. Oddil je vasak stale 4GB velky a z anim je volne misto. Zpusobu zvetseni je hodne. Ukazeme si relativne malo znamy program sfdisk.

Jak rika manual: „sfdisk is a script-oriented tool for partitioning any block device„. Umi sposutu veci, viz treba example, a jeho syntaxe je dosti zvlastni.

Nyni uz konecne ukazka zvetseni. Mame 16GB SD kartu, kterou system vidi jako /dev/sdb. Karta ma dva oddily, kde ext4 oddil je druhy, tedy /dev/sdb2. Jeho pocatecni velikost je 3,6GB. Na konci bude roztazeny do konce karty.
Postup:
  1. Pomoci fdisk -l overime, zda pracujeme se spravnym diskem. Neni zde zadne tlacitko zpet…
  2. Pote provedeme fsck daneho oddilu.
  3. Odpojime vsechny oddily SD karty.
  4. Zvetsime oddil.
  5. Zvetsime ext4.
  6. A zkontrolujeme vysledek.

Vse samozrejmne delame pod rootem. Ke zvetseni slouzi prikaz echo „, +“ | sfdisk -N 2 /dev/sdb. Kde parametr N udava druhy oddil. Text v uvozovkach popisuje operaci.
+ zvetsi oddil na maximalni moznou velikost. Pokud bychom chteli zvetsit treba o 50MB, pouzili bychom echo „, +50M“ | sfdisk -N 2 /dev/sdb

 
 
 

SSH Remote Port Forwarding – vzdaleny pristup na PC za NATem

Casto se potrebujeme pripojit na pocitac, ktery je za NATem. Obvykle se vyuziva VPN. Pokud vsak potrebujeme zpristupnit pouze nekolik malo, nebo jeden port, je nejpohodlnejsi a nejrychlejsi pouzit SSH.

Princip presmerovani SSH portu je videt na nasledujcim obrazku:


(obrazek prevzaty z http://www.dirk-loss.de/ssh-port-forwarding.png)

Nas zajima remote port forwarding. Pokud se nekdo pripoji na port X na serveru, dojde k presmerovani na ip:port na klientovi.

Nastaveni serveru

V zakladu OpenSSH nepovoluje remote port forwarding. Zapneme ho jednoduse pridanim

do /etc/ssh/sshd_config a restartovanim ssh systemctl restart ssh.service
nasledne je dobre si overit, zda opravdu k restartu doslo pomoci journalctl -n 5
Na serveru musime samozrejmne otevrit prislusny port ve firewallu, ktery se bude forwardovat!:

Pripojeni z klienta

Na PC, kde se budeme pripojovat spustime:

Pokud se nekdo pripoji na server.com na port 2222, tak se spojeni presmeruje skrz tunel na localhost 22. Server musi poslouchat na 0.0.0.0!

Pokud nyni spustime prikaz na svem PC, tunel se bude smerovat na IP 10.20.30.40 – libovolna IP dostupna z LAN, ve ktere je PC.

Jestlize nepotrebujeme terminal, ale samotny ssh tunel, pridame parametr -nnT :

 

Kdyz nebude fungovat, overime, zda server na danem portu posloucha:

dulezite je *:2222musi poslouchat na vsech IP!
 
Pripojeni na protunelovany PC je pak nasledujici:

 
Ukazka:

„Uzivatelsky PC“ si vytvori tunel na „PC n“ prikazem spustenym na „PC 1“.

 

Zjisteni aktualni verejne IP z terminalu a skriptu

Casto je potreba znat verejnou IP adresu, za kterou se PC schovava. Hodne znamy je web http://www.mojeip.cz/ ktery vsak jde pouzit jenom pres webovy prohlizec. Pokud potrebujeme zjistit IP v terminalu, nebo ve skriptu, museli bychom si napsat parser webove stranky. Z lenosti jsem si napsal vlastni skript na zjistovani adresy. Zde je jednoduchy skript na zjistovani IP v Pythonu:

Ktery nasledne muzeme zkompilovat pomoci cythonu a spustit:

Automaticke spusteni

Na automaticke spusteni po startu systemu pouzivam /usr/local/bin/getip_start

a ten se spousti z /etc/rc.local :

Pouziti je nasledujici

nc (netcat)

Busybox telnet client (OpenWrt, Ubiquity)

wget

Ubuntu telnet client

Jak je videt, klasicky telnet klient je nepouzitelne ukecany. Wget funguje dobre, ale kdo si ma pamatovat vsechny jeho parametry? Idealni je netcat (nc), ten vsak zvlast v embedded systemech neni.

Jak to funguje

Po spusteni zacne skript poslouchat na TCP 0.0.0.0:1234. Kdyz se nekdo pripoji, vrati mu IP a ukonci spojeni. U telnetu to tak funguje, webove prohlizece Firefox/Chrome take nemaji problem.

Pokud se vsak zkusime pripojit wgetem, wget vypise hromadu chybovych hlasek o chybejicih HTTP hlavickach. Proto jsem udelal maly hack. Skript po navazani spojeni ceka 2s. Pokud behem teto doby prijme nejake HTTP hlavicky, posle odpoved jako validni HTTP odpoved. Kdyz hlavicky neprijdou, posle jenom plain text adresu a zalomeni radku.

Odkaz na Gist, kde bude vzdy aktualni verze.

Odeslani JSONu pres HTTP pomoci busyboxu

Casto po vyreseni nejakeho mensiho problemu davam jeho reseni na GitHub GIST.
Na klasicky clanek to byva kratke, ale i tak je skoda se nepodelit. Proto budu postupne, jak cas dovoli prochazet stare gisty, trochu vic je komentovat a tvorit z nich kratke clanky.
Dnes zacnu posilanim HTTP POST pozadavku pomoci busybox telnetu.

K cemu je to dobre? Casto je potreba z pc odeslat data ke zpracovani na server. Pokud jde o bezny „stolni pc“, muzeme vyuzit nejaky pohodlny Python/Java framework, obetovat par desitek MB RAM a vse bude krasne fungovat 🙂
Ja ale potreboval posilat data z OpenWrt routeru, ktery mel 4MB flash a 16MB RAM. Proto jsem hledal reseni s nejmensimi naroky na zdroje.
 
Vetsinou se stejne pouzivaji HTTP pozadavky. Protoze jde o plain-text protokol, je mozne jednoduse pouzit telnet klienta. Bezni telnet klienti v Debianu/Ubuntu maji trochu jinou syntax, nez busybox klient.
Pro vetsi univerzalnost pouziti jsem pouzil prave busybox telnet.
 
Zde je ukazka na poslani JSONu pres HTTP GET. Na zacatku se vola program, jehoz vystupem je validni JSON.
 
Protoze program neumi zpracovat HTTP odpoved ani pokracovat v posilani pozadavku, posila se hlavicka „Connection: close„.
Data se poislaji vzdy aktualni, proto hlavicky na zakazani cache.
Po posledni hlavicce musi podle RFC popisujici HTTP nasledovat prazdny radek a pote samotna data.
Dost pravdepodobne bude mit server problem kvuli chybejici hlavicce Content-Length.
Ukazka nefunguje s busybox telnetem, pouze s plnohodnotnym telnetem v Debianu/Ubuntu.
 
Vyse uvedeny kod ma nekolik problemu:
  1. Pohodlnejsi je posilani vytupu do telnetu pres rouru.
  2. Chybejici hlavicka Content-Length.
  3. Pokud je vystup prikazu hodne velky, nevejde se do promenne a cast se zahodi.
  4. Nepouziva kompresi, zbytecne plytvani pri prenosu.
  5. Nejde pres nej posilat binarni data.
 

Ad 1 & 2

 
Bez spatne, nebo zadne hlavicky Content-Length bude mit hodne serveru pravdepodobne problem se zpracovanim! Pri mem testovani tomu tak bylo.
 
 

Ad 3

resenim je pouzit docasny soubor. Jeho nazev bychom si meli nechat pridelit od systemu, aby nedoslo ke kolizi:
 
Na zaver po sobe uklidime temp soubor.
 
 

Ad 4 & 5

body 4 a 5 spolu dost souvisi. Na komperesi pouzijeme standardni gzip, protoze je snad vzdy v busyboxu. Serveru proste http hlavickou oznamime jenom podporu gzipu.
Protoze gzip data jsou binarni, bude problem s odeslanim. Temer ve 100% pripadu telnet klient v binarnich datech rozpozna nejake ridici prikazy a spadne.
Resenim je zagzipovat data a pak je prevest do base64. I tak je uspora oproti plain-textu znacna. Pro srovnani pri mem testu: cisty text zabiral 10580 bajtu a base64-gzip 3056 bajtu – 3,46x mene.
 
Nyni prichazi dalsi problem 🙂
V beznych distribucich mame utilitu „base64“. Busybox ji take obsahuje, ale dost casto je kompilovan bez ni. Takze si musime base64 generovat samy, idealne v shellu – opet cisty POSIX sh shell. 
Teoreticky to jde, ale nejde vubec o snadny ukol. Nastesti jsem nasel uz hotovou implementaci, jako bonus je pod public domain licenci.
Ze skriptu nas zajima pouze funkce encode(). Pro ukazku cast te magie:
 

Kompletni funkcni kod:

Vezme data, zkomprimuje gzipem a prevede do base64. Na zacatku souboru je mozne pomoci promenne GZIP urcit, zda se posle plain-text, nebo gzip+base64.
 
 
 
 

SSH dvoufazove overeni vcetne vynechani z LAN

Z duvodu pozadavku na vysokou bezpecnost se stale casteji pouziva dvoufazove overeni. Prikladem jsou napriklad banky se svymi autorizacnimi SMS v Internetovem bankovnictvi.
Princip je jednoduchy: pokud utocnik ziska heslo, je mu k nicemu. Potrebuje totiz jeste jednorazove heslo. V Linuxu jde skvele pouzit Google Authenticator, jako modul pro PAM.

Dvoufazova hesla muzeme generovat dvema zpusoby:

  • Nove heslo se generuje z predchoziho,
  • heslo se generuje na zaklade casu.

Na generovani z predchozi hesla slouzi S/KEY. Podle meho nazoru neni nejvyhodnejsi, viz clanek v odkazu.

Druhou moznosti je generovani na zaklade casu – OTP. Nove heslo se vygeneruje kazdy X (nejcasteji 30 sekund) a stare prestane platit. Jednoduche na pouziti. Je vsak potreba mit synchronizovany cas mezi zarizenimi, pouzit NTP.

Nize si popiseme instalaci Google Authenticator PAM modulu a nastaveni SSH na Debianu 8.

Nejprve je potreba nainstalovat balicek:

Pote pod uzivatelem, ktery se bude pomoci OTP prihlasovat spustime prikaz google-authenticator. Pruvodce nas provede nastavenim. Dulezite je pouzit OTP.
Zaroven se nam vygeneruji zalozni kody. Ty muzeme nosit treba na papirku v penezence. Pokud nebudeme mit mobil (a tedy moznost generovat kody), pouzijeme tyto zalozni. Kazdy z nich jde pouzit pouze jednou.

Nasleduje nastaveni mobilu na generovani kodu. Pro Android si z Google Play stahneme aplikaci Google Authenticator. Aplikace na generovani existuji pro vetsinu OS. Aplikaci sparujeme pomoci QR kodu, nebo prepsanim klice.

Pote muzeme pristoupit k nastaveni Linuxu.

Zeditujeme soubor /etc/pam.d/sshd a na jeho konec pridame:

Dale v konfiguraku SSH serveru /etc/ssh/sshd_config najdeme a upravime nasledujici volby:

a restartujeme SSHD:

Pote se muzeme prihlasit pomoci OTP.

 

Casto by se nam hodilo vynechat OTP. Napr. v LAN je to zbytecne. Ja pouzivam nasledujici konfiguraci:

  • Pri prihlasovani z IP z LAN a VPN staci samotne heslo,
  • pri prihlasovani ze vsech ostatnich IP je potreba heslo + OTP kod,
  • pri prihlasovani SSH klicem ze vsech IP neni potreba heslo, ani OTP kod.

Upravime soubor /etc/pam.d/sshd. Smazemeauth required pam_google_authenticator.so“ a misto nej na konec pridame:

A vytvorime soubor /etc/security/access-local.conf :

syntaxe je nasledujici:

  • +/- na zacatku povoli/zamitne pristup
  • druhe pole je uzivatelske jmeno,
  • treti je hostname/IP.

Podrobnejsi popis nalezeneme na zacatku souboru /etc/security/access.conf .

V mem prikladu povolim vsem uzivatelum prihlasovani bez OTP ze site 10.123.0.0/16 a localhostu. Jinak musi pouzit heslo+otp, nebo klic.

 

Pouzite zdroje:

 

NGINX – overovani uzivatele klientskymi SSL certifikaty

Na autentizaci uzivatele v prohlizeci se nejcasteji pouziva nejaky zpusob primo nad webserverem, nebo si aplikace resi autentizaci sama. Pokud se overeni deje primo nad webserverem, pouziva se nejcasteji http basic, nebo http digest autentizace.
Protoze se cim dal casteji prosazuje sifrovane HTTPS otevira se nam nova moznsot overeni – klientske SSL certifikaty.

Misto klasickeho dialogu pro zadani jmena a hesla k http basic auth se prohlizec overi svym klientskym ssl certifikatem. Server certifikat overi a uzivateli pristup povoli, nebo zamitne.

Oproti heslu je zde nesrovnatelne vetsi bezpecnost. Heslo typu „nbusr123“ a 4096 bitovy RSA klic se proste neda srovnavat…
Nelze opomenout i nevyhodu – certifikaty. Kazdy klient musi mit vygenerovany svuj certifikat a mit ho naiportovany ve svem prohlizeci. Soukrome klice je dobre chranit heslem, jinak odcizeni klice = ztrata hesla. Certifiakty je v pripade kompromitace mozne pomoci CA revokovat.

Dost nudneho uvodu – jdeme nastavovat!

Na ukazku pouzijeme nginx webserver. Zvolil jsem ho hlavne pro jeho rychle a jednoduche nastaveni ve srovnani s obrim Apachem.

Na serveru bezi Ubuntu 15.10 64b s distribucnim nginx. 

Nejdrive naistalujeme nginx:

a pote vytvorime soubor /etc/nginx/nginx.conf s timto obsahem:

a mame funkcni nginx server s podporou SSL/TLS. Server posloucha jen na TCP 443, na TCP 80 ne! Neni definovane presmerovani, takze je nutne pristupovat pres HTTPS!
Podle potreby je vhodne nastavit pouzite protokoly a sifry. Aktualne nebezpecne vypnout a nove pridat.
If v sekci location overi klientuv certifikat oproti certifikatu CA. Pokud neprojde, vrati chybu 403.

Aby mohlo vyse uvedene fungovat, musime mit certifikacni autoritu. Idealne je jednoducha autorita easy-rsa, o kterem jsem psal v souvislosti s OpenVPN.
Jmena typu localhost v certifiaktech jsou pouze ne ukazku!

Po otevreni https://ADRESA-SERVERU/ (a odsouhlaseni neduveryhodneho certifikatu) v Chrome dostaneme:

 

Overeni podle „jmena“ klienta

Konfigurak vyse povolil pristup vsem klientum, jejichz certifikat podepsala nase CA. Co kdyz ale potrebujeme, jako u http basic auth podle jmena/certifikatu klientovi pridelit urcita prava?

Jde to jednoduse pomoci analyzy atributu certifikatu. V certifikatu je dulezite DN, neboli „Distinguished Name (DName)“. Vypada nasledovne:

na overeni uzivatele potrebujeme CN (CommonName). Nginx umoznuje jednoduche parsovani CN z DN. Konfigurak nginx serveru vymenime za:

Funkce map nam zpristupni v promenne $ssl_client_s_dn_cn CN z certifikatu.

Zajimave jsou dva if-y v sekci location. Prvni overi klientuv certifikat a pokud je neplatny(vuci CA), vrati 403.
Druhy porovna CN z certifiaktu. Pokud je CN rovno „client2“, provode neco. Zde presmerovani na google. Pri porovnavani se opravdu pouziva jen jedno rovna se!

 

Nastaveni Google Chrome

Google Chrome vyzaduje certifikat ve formatu PFX, ve kterem je klientuv certifikat a soukromy klic. Ostatni prohlizece to budou mit asi stejne, nezkousel jsem.

Standardni crt a key soubory prevedeme na pfx pomoci openssl:

 

Popsal jsem pouze jednoduchou, ale funkcni ukazku. Generovani a sprava certifikatu je v odkazovanem clanku o OpenVPN. Pro pokrocilejsi nastaveni staci googlit.

 

 

Zvetseni pisma v XTERM terminalu

Xterm je emulator terminalu pro X windows system. Vznikl v roce 1984, puvodne dokonce nebyl soucasti X. Pokud ho dnes spustite, vetsinou uvidite hodne male a obtizne citelne pismo. Ano, da se pouzit jiny terminal – ale resenim je zvetsit pismo 🙂

Xterm pouziva X Logical Font Description, neboli fixed pisma. Pismo se da zmenit docasne, nebo trvale.


  Vychozi velikost pisma v xtermu – 6×13 fixed.

Pro docasnou zmenu zavolame xterm s parametrem fn, nebo fa. Vychozi velikost pisma xtermu je 6×13:

Prvni prikaz zvetsi vychozi pismo. Druhy pouzije bezne pismo, ktere pouzivame treba v LibreOffice.


  Zvetsene fixed pismo v xtermu – 8×13 fixed.

Pro pouziti pisma Terminus je potreba nejdrive nainstalovat patricne balicky:

Pro zjisteni dostupnych pisem v systemu pouzijeme prikaz fc-list. Seznam je hodne dlouhy, proto doporucuji vygrepovat pozadovane pismo. I tak se zobrazi vicekrat. Na ukazce je moje nejoblibenejsi terminalove pismo Terminus:

Z vypisu vidime dostupne pismo Terminus ve variantach: Oblique, Regular, Bold a Bold Oblique.


  Terminus pismo s vyhlazovanim v xtermu.

Pro trvale nastaveni je potreba vlozit konfiguraci do souboru .Xresources v domovskem adresari. Prvni ukazka nastavi fixed pismo velikosti 18:

Druha nastavi systemove pismo:

Aby se nastaveni projevilo, muzeme restartovat X, nebo pridat zmeny k exitujicimu nastaveni:

 

Pouzite zdroje: Xterm – ArchWiki