čtvrtek 13. října 2011

fail2ban unban IP

Mám na jednom serveru aplikaci fail2ban a potřeboval jsem odbanovat IP pro pureftpd ban.
Není to těžký, ale špatně se to dělá celé z hlavy :-)
fail2ban používá asi tu nejlepší možnost banování IP a to iptables, tam také je potřeba ban zrušit.
Nejdříve si vylistujeme iptables příkazem:
iptables -L -n --line-numbers

...dostaneme něco jako tohle:
Chain fail2ban-courierimap (1 references)
num  target     prot opt source               destination
1    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain fail2ban-courierpop3 (1 references)
num  target     prot opt source               destination
1    DROP       all  --  xxx.xxx.xxx.xxx      0.0.0.0/0
2    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain fail2ban-courierpop3s (1 references)
num  target     prot opt source               destination
1    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain fail2ban-postfix (1 references)
num  target     prot opt source               destination
1    DROP       all  --  xxx.xxx.xxx.xxx      0.0.0.0/0
2    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain fail2ban-pureftpd (1 references)
num  target     prot opt source               destination
1    DROP       all  --  xxx.xxx.xxx.xxx      0.0.0.0/0
2    RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Budu-li chtít odstranit ban IP xxx.xxx.xxx.xxx pro PureFTPd, zadáme příkaz:
iptables -D fail2ban-pureftpd -s xxx.xxx.xxx.xxx -j DROP
Důležitý je tzv. chain, vidíme ho v listu iptables "[...] Chain fail2ban-postfix (1 references) [...]" a také IP (xxx.xxx.xxx.xxx).

Po zadání příkazu je ban zrušen, ověřit si to můžeme opět prvním příkazem na list iptables.

pátek 7. října 2011

Hlášky.net - úkol č. 2

Úkol č. 2 je takový, že musím myslet na to, že mám i vlastní projekty jako jsou hlášky, páč vůbec nestihám... :-)

Starting web server: apache2(98)Address already in use: make_sock: could not bind to address [::]:80

Tohle je celkem zapeklitá chyba.
Stačí jen restartovat apache2 příkazem:
/etc/init.d/apache2 restart
...a je to v řiti.

Vyskočí vám tam pak chyba:
Starting web server: apache2(98)Address already in use: make_sock: could not bind to address [::]:80
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
Action 'start' failed.
The Apache error log may have more information.
 failed!

V tuto chvíli neběží web server a nejde ho ani jednoduše nastartovat.
Prohledal jsem celý Google o tom. Snad téměř každý s tím má problém. Já taky :-/
Jediné co mi pomohlo v případě, že už apache nenastartoval bylo killnutí procesu, ale u mě na Debian Squeeze pomohl jen tento postup:

1) zjistit PID (process id) třeba příkazem:
netstat -nlp | grep :80
Vyhodí to něco jako:
tcp6   0   0 :::80     :::*   LISTEN      2434/apache2
tcp6   0   0 :::8081   :::*   LISTEN      2434/apache2
PID je v tomto případě 2434 (pokaždé bude jiný, tak to hlavně dál nekopírujte přesně a nepište, že vám to nejde :-D)

2) Killnout proces:
kill -9 2434
Na mnoha diskuzích píšou, že máme killnout apache pomocí killall apache2, ale mě nefunguje.

3) Spustit apache
/etc/init.d/apache2 start

Teď už by měl apache normálně běžet.

Další variantou je restartovat apache příkazem:
apache2ctl graceful

btw: Musel jsem si to sem napsat, páč vždy když to řeším, tak zapomenu řešení ;o)

pondělí 12. září 2011

Total Commander - Hromadné přejmenování stáhnutých souborů

Tě pic,
normálně, znám lidi, kteří si stáhnou nějakou věc z netu a prostě si to hodí do nějaký složky, nebo co hůř, si to něchájí do konce života ve složce Stažené soubory.
U mě je to trochu jinak, vše co stáhnu si stahuju do Stažených souborů, kde si to přesunu do podsložky podle toho co to je, např. Hudba. V té složce si to pak ještě vše přejmenuju, aby to nějak vypadalo, protože soubor staženej z netu má třeba formát 01-neco_neco-neco_dalsiho__original_mix.mp3. A tohle fakt v PC nechci. Je trochu vopruz tohle přejmenovávat po jednom souboru. Proto vám ukážu jak v Total Commanderu pomocí regulárních výrazů přejmenovat tyto soubory. Pokud regulární výrazy neumíte, nesnažte se je naučit, není to těžké, ale chce to trochu logického myšlení a taky trochu teorie.
Takže postup jak přejmenovat více souborů:

1) Otevřete si Total Commander a najeďte do složky, kde máte soubory, které chcete hromadně přejmenovat. Tyto soubory označte.


2) Poté stačí stiknout CTRL+M, nebo jít přes menu na Soubor > Hromadné přejmenování. Otevře se vám pro vás možná neznámé okno.

V tomto okně bude pro vás nejdůležitější sloupec Původní název a Nový název. Dále také sekce Najít a nahradit. Ostatní věci jsou taky fajn, dá se třebas očíslovat hromadně soubory od např. 000001 až do 999999 apod.

3) Nejprve odstraníme čísla ze začátku souborů. Napište do sekce Najít toto:
^([\d\-]+)
Pole Nahradit za, nechte "Vymazat". A zaškrtněte Reg. výraz.

Pak stačí kliknout na Spustit. Tím provedeme změny, které jsme udělali.
Dál neklikejte na Zavřít, ale klikněte vlevo od tlačítka Spustit na tlačítko se zpětnou šipkou.

4) Dále, hlavně pokud se jedná o písničky, tak většinou bývá text v závorce napsaný po dvou podtržítkách a bez závorek. Toto upravíme napsáním reguláru do pole Najít:
__([\w\d\_\-]+)\.([\w\d]+)$
a do pole Nahradit za napíšeme:
($1).$2
pozn. je tam mezera na začátku


A zase klikneme na Spustit a tlačítko se šipkou zpět.

5) Nahradíme pomlčky za mezeru a pomlčku a to tak, že nejdříve napíšeme do Najít pomlčku:
([^\s]+)\-([^\s]+)
a Nahradit za:
$1 - $2
Spustit > Zpět

6) Už to vypadá lépe co? Napište do pole Najít podtržítko a do pole Nahradit za napište mezeru, zaškrtávátko Reg. výraz odškrtněte. Dejte Spustit a zase tu zpětnou šipku.

7) V posledním kroku vymažte pole Najít a Nahradit za. V sekci Velikost písmen vyberte První Písmeno Slov Velké a dejte Spustit a pak Zavřít.

Hotovo, máte soubory rychle a "snadno" přejmenované do nějakého přijatelnějšího tvaru. Používám tohle mraky let a zatím jsem nenašel nic lepšího. Můžete se to na první pohled zdát zdlouhavé, ale jakmile se to člověk naučí, tak to ušetří mnoho času a nervů.

středa 7. září 2011

[MySQL] - ORDER BY VARCHAR jako INT

Stručně a snadno.
Potřebuji řadit sloupec jako INT, ale jeho typ je VARCHAR.
Toto lze provézt pomocí funkce CAST.

ORDER BY CAST(`name` AS SIGNED)

Další možné konverze:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]

středa 31. srpna 2011

Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library)

Nedávno mi umřel systémový disk na serveru a musel jsem přeinstalovat Linux, "naštěstí" jsem neměl disky v raidu, takže stačilo vše jen přeinstalovat. Nicméně po instalaci postfixu a nastavení mailů zpět mi Thunderbird házel chybu "Filesystem notification initialization error -- contact your mail administrator (check for configuration errors with the FAM/Gamin library)". Tato chyba se zobrazila vždy jen, když jsem poprvé klikl na nějakou složku v mailu. Ve webovém rozhraní Roundcube to nic nepsalo. I když se ale zobrazovala v Thunderbirdu tato chyba, vše fungovalo jak má.
Nicméně jsem googlil, ale nic moc jsem nenašel. Řešení je tak jednoduché, že to snad ani nemělo cenu hledat a rovnou to zkusit.
Stačí nainstalovat balíček Gamin.

apt-get install gamin

To jen tak, kdyby to náhodou někdo řešil :-)

pondělí 8. srpna 2011

Jak zpracovat velké objekty v JavaScriptu...

... aniž by se zasekl prohlížeč.
V práci jsem řešil jeden velký problém. Potřeboval jsem zpracovat mnoho JavaScriptových objektů a ne zrovna malých. Doufám, že nebude vadit, když se podělím s malým know how, které vykonávám pro firmu :-) Ale třeba si to přečte někdo, kdo mi poradí jiný a lepší způsob.
Hlavní problém je v tom, že uživatel vykoná pro něj obyčejnou akci a já (JavaScript) musím na pozadí stránky provést složité zpracování. V tuto chvíli, ač se to tak nezdá, je potřeba hrát na rychlost skriptů, které se provádí pouze na straně prohlížeče.
Např. tedy, uživatel klikne na označit vše v ul>li seznamu A, který má třeba 10 elementů a v seznamu B s 5000 elementy označit ty elementy, které obsahují v atributu rel hodnotu z označeného elementu v seznamu A.
Používám pro svojí práci knihovnu jQuery a musím říct, že funkcí each cesta fakt nevede. Každá tisícina vteřiny je pak znát a to hlavně, pokud necháte vše zpracovat jak se říká "na jedno našlápnutí" :-)
On je taky rozdíl v použitém prohlížeči, protože třeba Firefox si při spuštění takových skriptů je schopný vzít i dalších 300 MB paměti a 30% navíc na procesoru.
Další nepříjemná věc je ta, že takové skripty děláme hlavně pro klienty, kterým moc nevysvětlíme, že je to normální, když kliknou na jeden "odkaz" a najednou se jim začne zahřívat procesor jak cip a k tomu jim v prohlížeči vyskočí dotaz zda počkat na zpracování skriptu nebo skript ukončit a ještě k tomu se jim zobrazí, že prohlížeč neodpovídá :-D
No takže jediný řešení, který mě napadlo je zpracovat vždy kousek a poté zpracovat další kousek. Snažil jsem se něco vygooglit, ale nenašel jsem nikoho, kdo by toto řešil.
Výsledek je několik funkcí v JS a jQuery jako takovém, ale hlavně s tím, že vždy jsem dopředu věděl jak budou zpracovávané objekty velké a kolik toho bude.
Například asi takto:

(function(){
$.selectLinks = {
  all: function(){
    this.nextObject(0); // spustíme první element seznamu
  },
  nextObject: function(objectIndex){
    // ukončíme, protože neexistuje žádný element s tímto "indexem"
    if($("ul.list li[class!='active']:eq("+objectIndex+")").length == 0){
      return false;
    }

    var thisObj = $("ul.list li[class!='active']:eq("+objectIndex+")");

    // nějaké další akce v JS

    if(objectIndex % 100 == 0){ // modulo na každý stý záznam a následné zajištění pozastavení zpracovávání v prohlížeči na půl vteřiny
      window.setTimeout(function(){
        $.selectLinks.nextObject((objectIndex+1));
      }, 500);
    }else{
      $.selectLinks.nextObject((objectIndex+1));
    }
  }
};
})(jQuery);

Neříkám, že skripty se zrychlí nebo budou méně náročné na počítač, ale důležité v tomto případě je hlavně nedát najevo klientům, že vznikla nějaká chyba s jejich draze zaplaceným systémem.
Výše uvedený kód jsem tu vyhaluzil jen tak na první našlápnutí, takže ani nemusí v podstatě fungovat, nicméně důležité na tom vidět je.
Hlavní a myslím si, že nejjednodušší je pouštět jednu funkci rekurzivně dokud je to možné s tím, že občas počkáme pomocí setTimeout na nové spuštění, k tomu klidně stačí půl vteřiny i méně.
V mém případě na projektu v práci jde o daleko složitější skripty, které zahrnují spoustu jiných věcí.
Budu rád, když někdo hodí koment a třeba mě i přiučí lepším věcem.

Ave já

PS: Jo a kdyby někdo nevěděl, spouštěl bych to $.selectLinks.all();

pátek 29. července 2011

Kopírování posledních 2 souborů do složky

cp /var/www/odkud/`ls --sort=time | head -2` /tmp/kam/

sobota 25. června 2011

Čím víc umíš, tím míň toho uděláš ...

... ale v podstatě nikdy člověk neví kolik toho umí, protože ani neví kolik toho může umět. Teď mám namysli hlavně oblast ve které se pohybuji a která mě živí, ano IT.
Pracuji jako PHP vývojář v jedné skvělé firmě (no kde asi jinde viď :-)) a svojí práci mám i jako koníček, což je v tomto oboru hodně důležitý, ale zároveň nevýhoda. Pokud mě práce baví, tak si jí často otevřu i doma nebo tam dělám něco, co přenesu i do práce a tak se v podstatě nechtěně nutím se neustále zdokonalovat. Zaměstnavatel to samozřejmě ví a proto se mě snaží využít i jinak než pro hlavní náplň mé práce.
Inu, ono to je i vcelku logický, já bych na jeho místě dělal to samé, tak to už prostě je a vždycky bude. Je třeba si k tomu uvědomit, že jsme v ČR a firmy nemají peníze navíc, aby každému zaměstnanci platili v podstatě za každý typ činnosti jiný plat.
Ovšem mě to až tak moc nevadí :-)
Pohybovat se v IT je sice každému pro smích nebo si dokonce myslí, že ajťáci sedí v kanceláři a surfují po netu. Omyl! Někdo mi řekněte, že já jen sedím na netu a jednu vám vrazím :-)
Ví někdo vůbec co obnáší třeba jen spustit na internetu pod vlastní adresou nějakou aplikaci? Jak se vytváří domény, zapisují DNS záznamy, instalují servery, nastaví emaily, napojí se web na databáze a Bůh ví co ještě všechno? To je v podstatě to o čem je titulek článku. Sám v podstatě už ani nevím, co vše umím. Všechno co jsem tu vyjmenoval, to umím, nicméně nedávno jsme v práci řešili, že by bylo dobrý mít seznam toho co ovládáme my jako vývojáři - došli jsme k závěru, že obecně to napsat nejde a detailně taky ne, protože by to byl seznam jako blázen a hlavně každý takový detail může mít další svůj detail :-)
Práce programátora není jen psát tisíce řádků nějakého kódu, protože to je vždy to poslední co programátor dělá. Nejdříve se musí seznámit s problematikou projektu, udělat analýzu, navrhnout si funkčnost. Ono jde hlavně i o to, aby vývojář věděl co klient dělá za aktivity, pokud pro něj chce něco programovat. Budu-li např. dělat systém pro správu pacientů na klinice, budu muset znát trochu i zdravotnictví jako takové.
Ono to je celkem i fajn, takhle získávám denně fakt tuny nových informací, ale... člověku z toho začne občas hrabat a musí vypustit na chvíli a dát si pauzu, ale ne na 10 minut, ale na den či dva minimálně.
Celý problém je v tom, že čím víc člověk toho umí, tím méně toho stihne udělat na jedné věci, protože se toho na něj hrne víc, než je schopný zvládnout.
Co si myslíte o tom, že po vás lidé chtějí víc než můžete a zvládnete?
Někdy by pomohlo možná jen to, kdyby si každý rozmyslel jestli nezná odpověď na svojí otázku než se zeptá.

42

středa 15. června 2011

goto v PHP

Umíte PHP dobře? Pokud ano, tak jistě nepoužíváte základy jakou je např. goto.
Osobně se přiznám, že tuto základní funkcionalitu taky nepoužívám, ale přitom jde o užitečnou věc. Příkazem goto můžete řídit snadno běh skriptu.
I když stejně jako vše, má to i své zápory a to hlavně, že se goto nedá definovat v cyklu nebo switchi.

Jednoduché užití goto:
$how_many_times = 0;

answer: {
    $how_many_times++;
    echo "Answer is 42\n";

    if($how_many_times >= 3){
        die("3 times goto");
    }
}

for($i=0; $i<=100; $i++) {
    if($i == 42) {
        goto answer;
    }
    echo "{$i}\n";
}

Takže asi tak :-)

úterý 22. března 2011

jQuery a doplněk Firefoxu?

Ano, jde to... Není to těžké narvat jQuery do doplňku Firefoxu a ukážu vám jak.
Tuto funkcionalitu jsem řešil s jQuery 1.5.1 a Firefoxem 3.6.15.
Nebudu sem rozepisovat jak se dělá celý doplněk Firefoxu, k tomu vám pomůžou jiné weby jako například How to develop a Firefox extension nebo přímo i XUL School Tutorial.

Celý kouzlo je v tom, že nelze nahrát jQuery před zavoláním spouštěcí metody v JavaScriptu, protože pak nastává kolize s Firefoxem a může se stát, že zmizí tlačítka v toolbaru nebo dokonce zmizí i jiný doplněk.

Soubor knihovny jQuery nahrajte do složky chrome/content/
Ve vašem hlavním JavaScriptovém souboru doplňku chrome/content/nazev.souboru.js použijte metodu spouštění. Tento kousek kódu vložte nebo zeměňte za starý na konci souboru:
window.addEventListener("load", function(e) {
  mujDoplnek.onLoad(e);
}, false);

Celý základní kód JavaScriptu s načtením jQuery by mohl vypadat například takto:

var mujDoplnek= function () {
var prefManager = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var jQuery;

return {
  init : function () {
    gBrowser.addEventListener("load", function () {
      var autoRun = prefManager.getBoolPref("extensions.mujdoplnek.autorun");
      if (autoRun) {
        mujDoplnek.run();
      }
    }, false);
  },

  run : function () {
    mujDoplnek.jQuery = mujDoplnek.onLoad(content.window.event);
    mujDoplnek.start();

    // zde lze použít volání jQuery jak jsme zvyklí
    // například mujDoplnek.jQuery("div").slideUp(250);
  },

  onLoad : function(e){
    return mujDoplnek.loadjQuery(content.window);
  },

  loadjQuery: function(wnd){
    var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
    loader.loadSubScript("chrome://mujdoplnek/content/jquery-1.5.1.js", wnd);
    var jQuery = wnd.jQuery.noConflict(true); // důležité nastavení, aby nenastala kolize s jinou knihovnou nebo s jiným JavasCriptem na stránkách
    return jQuery;
  },

  start : function(){
    // zde také lze použít volání jQuery jak jsme zvyklí
    // například mujDoplnek.jQuery("div").slideDown(250);

    alert(mujDoplnek.jQuery("div").length);
  }

};
}();
window.addEventListener("load", function(e) {
  mujDoplnek.onLoad(e);
}, false);

Neříkám, že je to dokonalé, spoustu věcí tam bude třeba ještě odchytat, ale postupem času to tady upravím do dokonalosti :-)

čtvrtek 10. března 2011

Jak restartovat více služeb najednou

Restart všech služeb Courier na linuxu:
find /etc/init.d/ | grep courier | while read line; do $line restart; done

sobota 5. března 2011

Hlášky.net

Rozhodl jsem se přeprogramovat můj web Hlášky.net. Hlášky, které jsou teď, jsou nedodělané a v podstatě amatérsky naprogramované, tím myslím, že jsou napůl objektové a hlavně JavaScripty, které jsem tam použil bych dnes psal daleko líp. Tak přece jenom za ty tři roky, když jsem je dělal, jsem se naučil víc než dost k tomu, abych dokázal napsat něco lepšího.

Nepočítám s tím, že bych web dostal nějak do vysokých návštěvností, ale zkusil jsem web jen trochu propojit s Facebookem a návštěvnost na něm se po pár kliknutí na tlačítko "Líbí se mi" v podstatě zdvojnásobila. Dnes je to cca 120 unikátních IP adres za den, což mě nutí web předělat a dotáhnout. Pravda je, že propojení na Facebook je dnes slušnej základ reklamy zdarma. A co si budeme povídat, lidi spíš kliknou na odkaz na zdi FB než na odkaz reklamy někde jinde.

A teď k samotnému programováni nových hlášek. V podstatě teď ani ještě nevím jakou funkčnost tam chci mít, nechci kopírovat Lamer.cz, ale takovému tomu základu jako hodnocení, komentáře apod. se stejně nevyhnu.
Jediný co vím je, že celej web chci postavit na bázi Ajaxu, což může být trochu problém, pokud bych nedělal klasické odkazy ale jen načítání obsahu do elementů. Bez pevných odkazů si neškrtnu ani moc na Googlu ve výsledcích hledání. Vymyslel jsem proto systém, který tak trochu využívá Facebook, ale jen já ho budu využívat naplno a přesněji. Pro nové hlášky jsem si vybral php framework CodeIgniter a javascriptový framework jQuery.

Takže úkol č.1 je:
Vytvořit funkcionalitu, která při kliknutí na odkaz změní adresu URL v prohlížeči, ale nerefreshne stránku. Ovšem samozřejmě, že chci změněnou adresu nějak získat a vyvolat. Toho docílím jen jednoduchým JavaScriptem a Ajaxem, který mi pošle změněnou adresu na server, od kterého obdržím zpět potřebnou stránku či jiný response. Cíl je daleko složitější než se zdá. Prozradím jen, že změnu adresy bez obnovení stránky jsem docílil voláním adresy se znakem #, který odkazuje vždy na element na stránce, takže Vám posune stránku na pozici elementu, který má parametr pojmenovaný jedinečným výrazem za znakem # v URL. Ale posunování taky nechci, tak musím jen dávat pozor, aby se nějaký element nejmenoval stejně jako část odkazu za znakem #. Samozřejmě, že nemohu poslat Ajaxem na server požadavek s tímto znakem, protože to CodeIgniter neskousne (standartně). Další problém byl, že když někdo obnoví adresu například http://hlasky.net/#/neco/dalsiho, tak mu to musí načíst kompletně vše kde se původně nacházel. Prostě stejná funkce obnovení stránky jako u jiných webu. Toto jsem také ošetřil. V podstatě celý tohle mám napsaný a provázaný s php frameworkem tak, že pro něj se nic nezměnilo a funguje stejně jako bez JavaScriptu, tedy zejména bez Ajaxu, což byl cíl. Chybí mi ošetřit ještě jednu maličkost, ale víceméně úkol č.1 ovládá celý nějakých 120 řádků v jQuery a čistého JavaScriptu + drobné úpravy na straně serveru.

Základ mám tedy hotový a teď už pomalu přecházím na samotný vývoj celého webu, momentálně mám hotovou jazykovou mutaci a napojení na šablonovací parser CodeIgniteru, takže už generuji menu s odkazy co mi načítají obsah bez refreshe stránky, ale se změnou URL v prohlížeči :-) Pokračovat budu snad zase během dnešního večera.
 
]]>