Pages

Showing posts with label multilog. Show all posts
Showing posts with label multilog. Show all posts

Wednesday, November 14, 2012

Как работи DNS, част 3 - инсталация на DNS cache сървър.

Преди да прочетете тази статия, би било добре първо да се запознаете със статията: "Как работи DNS, част 1 - Resolvers и Cache сървъри" - линк към блога ми или линк към linux-bg.org.

Преди инсталацията, трябва да решим кой dns сървър да инсталираме. Ето кратък списък с най-разпространените dns сървъри: BIND, djbdns, PowerDNS, MaraDNS, Windows DNS  (Изследване за DNS софтуера ползван в България).

В примерите ще използвам паралелно инсталация и конфигурация на  най-разпространеният dns сървър - BIND, както и този, който използвам и препоръчвам аз - djbdns под Debian.

Инсталация на BIND като cache сървър

В Debian stable (6.x, squeeze в момента) BIND го има на пакет. Инсталираме го:

# apt-get install bind9

Конфигурацията на bind се намира в /etc/bind/ - директорията, като файла се казва named.conf. В Debian този файл е разделен на няколко файла, като във всеки от тях се конфигурират отделни неща. Ето:

# cat named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

Както се вижда, настройките се правят в няколко отделни файла. Тъй като ние искаме да конфигурираме само cache сървър, файлът който ни интересува е named.conf.options.

# cat /etc/bind/named.conf.options
options {
        directory "/var/cache/bind";

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See http://www.kb.cert.org/vuls/id/800113

        // If your ISP provided one or more IP addresses for stable
        // nameservers, you probably want to use them as forwarders.
        // Uncomment the following block, and insert the addresses replacing
        // the all-0's placeholder.

        // forwarders {
        //      0.0.0.0;
        // };

        auth-nxdomain no;    # conform to RFC1035
        listen-on-v6 { any; };
    allow-recursion { 172.20.20.0/24; 172.20.30.3; };
};

С този ред разрешяваме recursive запитвания към dns cache сървъра от мрежата 172.20.20.0/255.255.255.0 както и от IP адреса 172.20.30.3. Съответно - променяте ги на ip/мрежите които ще го ползват като dns cache сървър.

# /etc/init.d/bind9 restart

Вече имате работещ BIND dns cache сървър.


Инсталация на djbdns cache сървър

В Debian stable (6.x, squeeze в момента) djbdns не е включен, но го има в testing/unstable. Ако искате, можете да си направите пакет (http://geroyblog.blogspot.com/2012/09/how-to-install-djbdns-in-debian-squeeze.html), или да го инсталирате от http://cr.yp.to/djbdns.html. Ще разгледаме втория вариант. За целта е нужно да имате следните пакети инсталирани - daemontools (как се инсталира), ucspi-tcp. Следваме инструкциите за инсталация на djb:

# wget http://cr.yp.to/djbdns/djbdns-1.05.tar.gz
# zcat djbdns-1.05.tar.gz|tar xvf -
# cd djbdns-1.05
# echo gcc -O2 -include /usr/include/errno.h > conf-cc
# make
# make setup check


Djbdns пакета съдържа няколко програми, като всяка от която върши определена работа:

tinydns - authoritative dns сървър - udp
axfrdns - authoritative dns сървър - tcp
dnscache - dns cache сървър
както и няколко други които в случая няма да бъдат разяснявани.

Тъй като ще инсталираме dns cache сървър, ще разгледаме dnscache и програмата за конфигуриране, която върви към него - dnscache-conf. Синтаксиса на програмата е следния:


dnscache-conf: usage: dnscache-conf acct logacct /dnscache [ myip ]

където:
acct - нужен е да се създаде потребителски акаунт, с който ще се стартира dnscache;
logacct - нужен е да се създаде потребителски акаунт, с който ще се стартира multilog, който ще записва log - файловете на dnscache;
/directory - в коя директория да бъдат създадени стартиращите/log - файлове на dnscache
myip - на кое IP ще "слуша" dnscache.


# useradd dnscache
# useradd dnslog
# dnscache-conf dnscache dnslog /etc/dnscache 172.20.20.1

Остава да укажем от кои ip/мрежи е разрешен да се ползва dns cache сървърът. Това се прави в директорията /etc/dnscache/root/ip/, като в нея се създават празни файлове с имената на мрежи/ip адреси от които може да се ползва сървъра.


# touch /etc/dnscache/root/ip/127.0.0.1
# touch /etc/dnscache/root/ip/172.20.20

Както следва, dnscache може да се използва от 127.0.0.1 ip адреса и от мрежата 172.20.20.0/24
Остава само да стартираме dnscache. Това става, като направим symbolic link към /etc/services директорията:

# ln -s /etc/dnscache /etc/service/dnscache
# svstat /etc/service/dnscache /etc/service/dnscache/log
/etc/service/dnscache: up (pid 1273) 3 seconds
/etc/service/dnscache/log: up (pid 1277) 3 seconds

Конфигурационната директория на djbdns се намира в /etc/dnscache/env, като всички променливи са в отделни файлове.


# ls -l /etc/dnscache/env/
-rw-r--r-- 1 root root    8 Sep  9  2008 CACHESIZE
-rw-r--r-- 1 root root    8 Sep  9  2008 DATALIMIT
-rw-r--r-- 1 root root   15 Sep  9  2008 IP
-rw-r--r-- 1 root root    8 Sep  9  2008 IPSEND
-rw-r--r-- 1 root root   23 Sep  9  2008 ROOT

По подразбиране CACHESIZE е 1000000 байта, което е твърде малко и трябва да бъде променено на по-голяма стойност в зависимост от свободната памет с която разполагате.
DATALIMIT се използва от програмата softlimit, която ограничава dnscache да използва определен ресурс памет. DATASIZE трябва да е по-голям от CACHESIZE.
ROOT указва в коя директория се намират dns root hints.
IP указва на кой IP адрес ще отговаря dnscache при запитвания.
IPSEND указва от кой адрес да се изпращат рекурсивните заявки.


# echo 134217728 > /etc/dnscache/env/CACHESIZE
# echo 154000000 > /etc/dnscache/env/DATALIMIT

Тези стойности указват 128mb за cache на dns запитванията и 154mb като цяло заделена памет за програмата dnscache. Ако по някакви причини самата програма се опита да заеме повече от тази памет, програмата softlimit ще върне грешка "out of memory".

Остава да конфигурирате PC-то си да използва този DNS, и това е всичко. Вече имаме работещ dns cache сървър.

Кеширането става само в паметта, тоест нищо не се пише по диска, от което следва, че при всяко рестартиране на dns cache сървъра кешираните данни се губят.

Ако искате dnscache сървъра ви да поддържа DNSCurve протокола (предложен от Dan Bernstein), използвайте ето този patch и инструкциите към него: http://shinobi.dempsky.org/~matthew/patches/djbdns-dnscurve-20090602.patch

Thursday, April 19, 2012

Въведение в daemontools (DJB Way)

Софтуера, написан от професор Daniel J. Bernstein е трудно разбираем за много хора и може би за това не е толкова популярен. В тази статия ще се опитам да обясня концепията, стояща зад неговите програми.

Bernstein е приел модела на UNIX, тоест програмите да са колкото се може по-малки, да вършат строго определена работа, да комуникират посредством unix pipes. Ето пример, който всеки администратор използва:

# ps ax|grep httpd|wc -l
      12
Типичен pipeline, където изхода от програмата ps се подава на входа на програмата grep, която пък отбира редовете които съдържат httpd, като след това се подава на програмата wc, която преброява колко реда съдържат httpd и отпечатва стойността. В случая - в момента имаме 12 активни процеса на httpd.

Кодът на програмите му е написан на ANSI C, компилира се на всякакви OS поддържащи POSIX модела.

Ще започнем с daemontools, които са основата на неговият тип софтуер. Daemontools представлява пакет от малки полезни програмки, които следят и поддържат даден процес да бъде активен. Добър аналог на тази система е Services в Windows XP/7.

Инсталацията е опростена максимално:

# wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
# zcat daemontools-0.76.tar.gz|tar xvf -
# cd admin/daemontools-0.76
# package/install

 Програмата добавя ред в /etc/inittab:

SV:123456:respawn:/usr/bin/svscanboot

който указва, че ако процесът svscanboot завърши по някакъв начин, трябва да се стартира наново.
Всъщност svscanboot е просто един скрипт:

#!/bin/sh
# WARNING: This file was auto-generated. Do not edit!

PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin

exec </dev/null
exec >/dev/null
exec 2>/dev/null

svc -dx /service/* /service/*/log

env - PATH=$PATH svscan /service 2>&1 | \
env - PATH=$PATH readproctitle service errors: ........................................................................................................
.......................................................................................................................................................
.................................................................................................................................................

Скриптът изпълнява svscan, с опция директорията с /services, като изхода на svscan  е пренасочен към друга програмка - readproctitle. Ако има грешки при стартирането на някой service, то съобщението за грешка ще го получи readproctitle, който  от своя старна ще го отпечата на мястото на точките. Това ни дава възможността да проследим грешките от /service ето така:

`--# ps ax|grep readproc
  173 ttyE0- IW    0:00.01 readproctitle service errors: ..................................................................................................................................................
Както се вижда - грешки няма. Ето пример - когато има грешки (промених нарочно run файла в който се стартира multilog -> multilog_proba_za_error) :

`--# ps aux|grep readproc
root       172  0.0  0.0    16   500 ttyE0- S     2Mar12  0:00.02 readproctitle service errors: ...s not exist\nsetuidgid: fatal: unable to run multilog_proba_za_error: file does not exist\nsetuidgid: fatal: unable to run multilog_proba_za_error: file does not exist\nsetuidgid: fatal: unable to run multilog_proba_za_error: file does not exist\nsetuidgid: fatal: unable to run multilog_proba_za_error: file does not exist\nsetuidgid: fatal: unable to run multilog_proba_za_error: file does not exist\n

Структура на директориите при daemontools. Всеки отделен service се пуска от отделна поддиректория на основната за daemontools - /service (при Debian например е /etc/service).


Да кажем, че искате да пуснете програма през daemontools, като целта е програмата да се следи дали не е приключила, и ако е - да се пусне наново. За целта създаваме директория в удобно за нас място (Примера е пускане на sshd през daemontools).


mkdir -p /etc/svc/sshd
mkdir -p /etc/svc/sshd/log

Всяка една от тези 2 директории трябва да съдържа по един run - файл, в който се осъществява самото стартиране на програмата. Изискването е програмата да НЕ се пуска във фонов режим (background/daemon).
Daemontools ще се погрижи тя да си отиде във фонов режим. Ако програмата записва в логовете през syslog - системата, трябва да потърсите опция която указва грешките, и логовете да се пишат в stderr или stdout. Ако не направите това, то multilog - програмката няма да може да прихване и запише логовете в log - директорията.

/etc/svc/sshd/run - файла, в който стартираме самия процес.
#!/bin/sh
exec 2>&1
exec /usr/local/sbin/sshd -D -e
 
Забележка:
Опциите на sshd са, за да се спазят изискванията на daemontools (текста отдолу е изваден от man страницата на sshd).

-D When this option is specified, sshd will not detach and does not become a daemon. This allows easy monitoring of sshd.
-e When this option is specified, sshd will send the output to the standard error instead of the system log.
exec 2>&1 - указва всички грешки отпечатани на stderr (2) да се пренасочат към stdout (1)

/etc/programa1/sshd/log/run - файла, в който стартираме процеса, който запазва логовете на sshd
#!/bin/sh
exec setuidgid root multilog t /var/log/sshd
В случаят програмката multilog се пуска с правата на потребител root, t означава да добави timestamp (във формат tai64 който ще бъде обяснен по-долу) в началото на всеки ред, и накрая се указва директорията, в която ще се съхраняват логовете. Multilog има още няколко допълнителни опции, които са полезни като например: n (брой log файлове) и s (размер на log файловете). Ако променим реда ето така:
exec setuidgid root multilog t s500000 n50 /var/log/sshd
то всеки log файл ще има размер 500,000 bytes и максималния брой на log - файловете ще е 50. Когато се запълнят всичките 50 файла с по 500 000 bytes, се изтрива най-старият файл и се създава нов.

Логовете се записват под формата на timestamp като име на файл освен текущият, който е current. Ето извадка от списък с логове:
-rwxr--r-- 1 qmaill nogroup 16775307 Mar 14 06:13 @400000004f601b0c36890194.s
-rwxr--r-- 1 qmaill nogroup 16775283 Mar 17 22:00 @400000004f64ed533284f5e4.s
-rwxr--r-- 1 qmaill nogroup 16775332 Mar 21 16:57 @400000004f69ec6132814c64.s
-rwxr--r-- 1 qmaill nogroup 16775234 Mar 26 16:32 @400000004f706ffb12df90dc.s
-rwxr--r-- 1 qmaill nogroup 16775255 Mar 30 07:42 @400000004f7539d52ef51c4c.s
-rwxr--r-- 1 qmaill nogroup 16775226 Apr  2 17:13 @400000004f79b3fb24fd9cb4.s
-rwxr--r-- 1 qmaill nogroup 16775247 Apr  4 12:27 @400000004f7c140f3760cbc4.s
-rw-r--r-- 1 qmaill nogroup 10108940 Apr 18 15:42 current
Единственото, което остана за да стартираме ssh service през daemontools е да направим symbolic link на директорията, която създадохме (/etc/svc/sshd/) към /service/. Ето така:
# ln -s /etc/svc/sshd/ /services/sshd
след което този новосъздаден от нас service ще се стартира автоматично.

Може би забелязахте, че пропуснах да обясня някои от използваните програмки като setuidgid или пък svc. Нека обърнем малко внимание и на допълнителните програмки, които идват с daemontools.

svc - служи за контрол на services за които се грижи supervise. С тази програмка на практика изпращате различни сигнали към даденият service.

-u (up) Стартира service. Ако не е стартиран - го стартира. Ако процесът по някаква причина завърши - процесът се рестартира.
-d (down) Спира service. Ако е стартиран, му изпраща сигнал TERM. След като е спрян, service не се рестартира.
-o (once) Стартира се само веднъж. При спиране на service не се рестартира.
-p (pause) Изпраща сигнал STOP..
-t (terminate) Изпраща сигнал TERM. На практика с тази опция се рестартира даден service. Процесът получава TERM - сигнал който би трябвало да го спре и след няколко секунди supervise ще го вдигне отново.
-k (kill) Изпраща сигнал KILL.
Има и още опции, и за повече информация погледнете man - страницата, или на http://cr.yp.to/daemontools/svc.html. Примери:

svc -t /service/* - рестартира всички services.
svc -d /service/qmail-send/ - спира даденият service.
svc -u /service/qmail-send/ - стартира даденият service.

svok - проверява дали даден service е стартиран. Връща стойност 0 ако service е активен, и 100  - ако service не е активен. Може да се използва в скритове.

svstat - показва текущия статус на даден service(s). Може да съдържа произволен брой аргументи, като всеки от тях е път към даден service. Поддържа и wildcards. Пример:

# svstat /service/qmail-send/ /service/qmail-smtpd/
/service/qmail-send/: up (pid 3540) 1891374 seconds
/service/qmail-smtpd/: up (pid 3539) 1891374 seconds

или

# svstat /service/*/log
/service/qmail-send/log: up (pid 7695) 6134915 seconds
/service/qmail-smtpd/log: up (pid 15281) 3457319 seconds

setuidgid - Стартира процес с права на друг потребител. Ако даден service не са му нужни root права, можем да го пуснем с друг потребител с ограничени права. Примерът от по-горе:

#!/bin/sh
exec setuidgid root multilog t /var/log/sshd

стартира multilog с правата на потребител root. Както се вижда, не е нужно multilog да се стартира с root права, и за целта можем да направим следното: създаваме нов потребител (примерно sshlog), променяме притежателя на директорията /var/log/sshd на sshlog (chown sshlog /var/log/sshd), и след това променяме и реда ,с който се стартира multilog, за да стане така:

#!/bin/sh
exec setuidgid sshlog multilog t /var/log/sshd

Така процесът за log - файловете ще е стартиран с ограничените права на потребителя sshlog.

envuidgid - Стартира процес с обкръжението на даден акаунт.

softlimit - Стартира процес с ограничени ресурси като максимална памет която може да заема, големина на създадените файлове и т.н. (аналог на ulimit). Пример:

# softlimit -m 2000000 /bin/sh
# mc
mc: error while loading shared libraries: libslang.so.2: failed to map segment from shared object: Cannot allocate memory

стартира /bin/sh с ограничено използване на памет от 2 000 000 bytes. При опит да се стартира нещо, което заема памет (като midnight commander) се вижда какъв е резултата.
Тази опция я използвам при qmail за лимитиране на големината на получените съобщения.

tai64nlocal - Чете от stdin, търси редове, които започват с @ и след тях има tai64 timestamp, като ги преобразува във формат: YYYY-MM-DD HH:MM:SS.SSSSSSSSS. Пример:

оригинален timestamp от log файл на multilog
@400000004eef68ef060b533c status: local 0/10 remote 2/20

# echo "@400000004eef68ef060b533c status: local 0/10 remote 2/20"|tai64nlocal
2011-12-19 18:40:05.101405500 status: local 0/10 remote 2/20
TAI (Temps Atomique International) е международен стандарт за измерване на време, който за момента не се използва в масовите операционни системи (http://cr.yp.to/proto/utctai.html).
Tai64 е имплементация, направена от Dan Bernstein, която се използва в неговите програми (http://cr.yp.to/proto/tai64.txt).

fghack - anti-backgrounding tool. Ако имате програма, която винаги се старира във фонов режим (background/daemon), с тази програмка можете да "излъжете" тя да се стартира във foreground режим. (не съм го пробвал а и DJB казва, че не работи във всички случаи)

pgrphack - понякога има програми, които при изход изпращат TERM - сигнал не до процес - ID (pid), а до груповия ID (gid), при което сигналът се получава и от svscan, от което последствията не са много приятни. За пример е даден pppd програмата, която трябва да се пуска точно с pgrphack. (това лично аз не съм го тествал).

Ползвани ресурси: http://cr.yp.to/daemontools.html