[Megoldva] /etc/hosts változásának aktualizálása

Néhány ismerősöm gépét ssh-n keresztül érem el, ha valami gond van. Egy erre a célra fenntartott mailboxomba küldik a gépek a publikus IP-címeiket.

Mivel meguntam copy-paste-elni a címeket, az alábbit csináltam.

Az incrond-t triggereli a beérkező e-mail. A levélből a script kiszedi a távoli gép hostnevét és IP-címét, majd ha ez már szerepel a /etc/hosts file-ban, úgy lecseréli az IP-címet az aktuálisra, ha nem, akkor pedig a file végéhez írja az új bejegyzést.

Az elképzelés működik is, csak kicsit későn eszméltem arra, hogy a hálózatot illene újraindítani.

Van valami hatékony megoldás a névfeloldás aktualizálására? Nem szeretném, ha efféle e-mail érkezését követően elakadna a hálózatom akár egy pillanatra is.

Update

Megoldás a caching nameserver - ebben az esetben dnsmasq - újraindítása:

systemctl reload-or-try-restart dnsmasq

Hozzászólások

Már miért kéne újraindítani a networkinget?

Azért nem, mert az ingyenes dyndns-ek jellemzően két címet engednek regisztrálni, továbbá nyűgös megcsinálni, aztán idővel lehet, elmúlik vagy fizetőssé válik a szolgáltatás, s kezdhetek mindent elölről. Így viszont megoldom magamnak, s ami szép, ezek a hostnevek rövidek, nem kell hosszasan gépelni, vagy bash history-ban keresni Ctrl-r-rel. Egész egyszerűen

ssh -p<port> <host>

ahol a <host> egy kellemesen rövid név, és meg is vagyok.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Elvileg azonnal ervenyesul a valtoztatas, nem kell semmit csinalni. Viszont sajnos ha egy service vagy alkalmazas cache-eli a nevfeloldast, akkor ha nem tudod ertesiteni a valtozasrol, ujra kell inditani.

Megtaláltam a probléma gyökerét. Használok dnsmasq caching nameservert, így aztán kell neki egy ilyen:

systemctl reload-or-try-restart dnsmasq

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A kérdés az, hogy miért használsz dnsmasq-ot... (jó/rossz ez neked, akarod-e tényleg, s ha igen, akkor miért nem :D)

Én eddig akárhányszor belefutottam (jellemzően OpenWrt-s cuccokon), előbb-utóbb csinált valamit, amitől a hajam égnek állt, és letöröltem onnan a 'csába. Tisztább, szárazabb érzés nélküle.

Bár valóban ezt teszi, viszont az a kifele menő kommunikációra vonatkozik. Bár explicit nincs leírva, hogy maga a dnsmasq cachelné a hosts filet, ellenben a man notes részében le van írva, hogy sighupra újraolvassa, szóval kell neki szólni, hogy változás van a fileban.

Miben írtad? Shell ragasztás? :) Remélem valami normálisabb script nyelv ;)

Egyébként megsz..atott az awk, tudniillik az exit utasítás után még lefut az END rule, amiről én nem tudtam. Nyilván az END rule-ba lehet írni egy if-et, ha erről tudok. Na jó, most már tudok. :)

https://www.gnu.org/software/gawk/manual/html_node/Exit-Statement.html

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ha a hosts fájban módosítasz, akkor egyből érvényes lesz. Kivétel, ha a dnsmasq-nak megmondod, hogy ne nézze ezt a fájlt (talán -h kapcsoló).

Miert hosts? Miert nem ~/.ssh/config?

Azon gondolkodtam, hogy lehet érdemes lenne összedobni valami nagyon egyszerű protokollt egy magasabb script nyelven, amely adott porton figyel és pl. csak pár karaktert fogad el (US ASCII-ből természetesen, erősen szűrve az inputot) és ekkor letárolnád ezt a nevet a kérés forrás IP-jével együtt.

Így nem kellene email-lel szórakozni. Kliens oldalon meg elég lenne egy netcat-et futtatni, vagy éppen írni egy aprócska kliens oldali scriptet is. Lehet van már rá egy rakás megoldás. Nekem az email része nem tetszik a tiédnek, főleg azért is, mert macera beállítani a mail küldés lehetőségét kliens oldalon. Ha nincs cím, akkor csinálni, plusz belőni egy működő postfix-et gmail-el vagy egyéb.

Lehet összedobok egy megoldást. Nekem is kellene.

Szerk.: közben eszembe jutott, hogy az emailnek van annyi előnye, hogy nem kell hogy fix ip-jű legyen a te géped és így bárhol megkapod ezt az infót.

Bizony. Meg ez nem új fejlesztés részemről, néhány ismerősöm gépe küld minden bekapcsoláskor nekem egy e-mailt benne időpont, hosztnév, IP-cím, filerendszerek telítettsége. Így látom, ha teleszaladt a HDD, s szólnom kell a gazdinak, hogy takarítson, vagy megteszem én, illetve látom az IP-címet, így be tudok ssh-zni. Ez eddig is így volt, csak mindig az e-mailből copy-paste-eltem az IP-címet, s meguntam, ezért írtam most ezt a hosts upgrade-elő scriptet, ami egyébként kitűnően működik, automatikus, mert az incrond-t triggereli a beérkező levél.

Szóval ez ilyen szegény ember kényelmi szolgáltatása. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Hamar összecsaptam egy memóriából dolgozó saját DNS kiszolgálót szerver és kliens oldali scripttel.

Ha van kedve valakinek, tesztelhetné több platformról és Ruby verzióval.

Lényeg, hogy a server script fusson egy fix IP-vel rendelkező szerverünkön állandóan, pl. boot-kor indítva (crontab, @reboot).

Az elérendő munkaállomásokról pedig periódikusan futtatni, pl. szintén cron-ból.

Az IP lekérdezéshez pedig egy kérdőjel kell a domain név elé a kliens oldali script futtatásakor.

https://github.com/log69/mydns

Szerk.: betettem saját blogomba is, itt: http://hup.hu/node/143402

bevallom, hülye vagy ruby-hoz, de ez a kombó igazából bármely nyelven egyértelmű:

Thread.start(s.accept) do |c|
name = c.gets[/[\?]*[\.\-_a-zA-Z0-9]+/][0..100]

Ha jól értelemezem, sock accept-nél új threadet indít, majd bekéri a nevet. Itt viszont van egy bökkenő. Ha nem küldök adatot, akkor az új szál ott meg fog állni. Ha szép csöndben "elbaszom" a socketet kliens oldalról, akkor az oda kőkeményen beragad. Így egy laza ciklusban "mélyfagyasztást" tudok okozni a szerveren.

// Happy debugging, suckers
#define true (rand() > 10)

Szerintem ez a get egyébként egy alap recv-ben fog végződni, ezek a dolgok pedig nem timeout-olnak, erre van a select (es ahogy lattam van ruby alatt is lehetoseg a select hasznalatara, szoval igy inkabb szinte biztos hogy nem timeoutol).

Itt van ra pelda (io.select neven fut): https://gist.github.com/sandro/1192557

Ez igy single thread lesz, de mivel nincs eroforras igenyes dolog a forrasodban, igazabol ez a legjobb megoldas. Raadaskent ha valaki le ddosolja, akkor nem fogja elrantani az egesz gepet, csupan a ddos-olo sajat maga elol csokkenti a eroforrast az adott appon belul

// Happy debugging, suckers
#define true (rand() > 10)

A Thread használatával látszott hogy DOS-olható, de igazad van hogy nem kell ide több szál. Megcsináltam egyszálúra, jobb lesz így.

A sleep-et meg visszateszem mindenképp a brute force akadályozásához.

Gyakorlatilag a thread-ek használatánál nem sokat lehet csinálni szerintem a DDOS kivédésére. Azt értem hogy az előző verziómnál egyetlen kliensről is le lehet térdeltetni a szervert, mert fork bombát lehet okozni. Jelenleg 1 kliensről nem lehet, mert várnia kell az előző művelet befejezésére.

Köszi a segítséget.

Nincs nagy baj a user/thread felállással, csak óvatosan kell vele bánni. Ezt a gyakorlatban egyébként úgy szokták megoldani hogy egy main thread van, amelyik acceptolja a klienseket és még mielőtt egy új thread születne az adott connectionnek, átesik az ellenőrzéseken (és akkor ide jön a connection/ip limit, blacklist, throotling, total user limit etc., így még a main threadben el lehet b@szni)

// Happy debugging, suckers
#define true (rand() > 10)