Категории

пятница, 31 августа 2012 г.

RDP Windows, перенаправленные принтеры, Easy Print Driver.

Для работы перенаправленных принтеров через RDP сессию в Windows 2008 нужно, чтобы у клиента были установлены:
1. Microsoft .NET Framework 3.5.
2. Клиент служб терминалов версии 6.1, для Windows XP (KB952155).

В этом случае принтеры имеющиеся у клиента, будут автоматически перенаправлены через RDP сессию на сервер терминалов.
ВАЖНО! Чтобы не расшаривать каждый принтер у клиента, нужно включить Брандмауэр и выбрать тип сети - "Сеть Предприятия".

P.S. Что самое замечательное, у клиентов видны только их принтеры, и они не смогут распечатать случайно на чужом принтере!
И еще больше всего мне понравилось то, надобность установки драйверов отпадает для многих принтеров - практически все заводятся через Easy Print драйвер.
Ссылки по теме:
1. Подключение к удаленному рабочему столу (клиент служб терминалов версии 6.1) для Windows XP (KB952155)
2. Microsoft .NET Framework 3.5

среда, 29 августа 2012 г.

Запуск КИАСУО 1252 на Windows Server x64, corflags.exe, NetFramework 3.5

Дело в том, что программа КИАСУО ниже версии 1280 откомпилирована с опцией "для всех архитектур", и при запуске на 64 разрядных ОС не запускается. Лечится это довольно просто, ниже описана методика.
Смотрим статус:
C:\Users\Администратор>cd "C:\Program Files (x86)\КИАСУО3\OuServer\bin\Release"
C:\Program Files (x86)\КИАСУО3\OuServer\bin\Release>CorFlags.exe OuServer.exe
Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  2.0.50727.42
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 9
ILONLY    : 1
32BIT     : 0
Signed    : 1
Видим, что флаг "32BIT : 0" не установлен.
Для запуска КИАСУО на Windows Server 2008 X64 нужно найти утилитку CorFlags.exe — 73.7 КБ, скопировать ее в папку с файлом OuServer.exe и проделать следующее:
C:\Users\Администратор>cd "C:\Program Files (x86)\КИАСУО3\OuServer\bin\Release"
C:\Program Files (x86)\КИАСУО3\OuServer\bin\Release>CorFlags.exe OuServer.exe /3
2BIT+ /Force
Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  2.0.50727.42
Copyright (c) Microsoft Corporation.  All rights reserved.

corflags : warning CF011 : The specified file is strong name signed.  Using /For
ce will invalidate the signature of this image and will require the assembly to
be resigned.
Проверяем результат:
C:\Program Files (x86)\КИАСУО3\OuServer\bin\Release>CorFlags.exe OuServer.exe
Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  2.0.50727.42
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 11
ILONLY    : 1
32BIT     : 1
Signed    : 1
Видим флаг 32BIT : 1 установлен, приятной работы!
После этого сервер запускается нормально. У меня заработал как в ручном режиме запуска, так и в режиме сервиса.
Ссылки по теме:
1. CorFlags.exe (CorFlags Conversion Tool)
2. Flipping bits on managed images to make them load with the right bitness...

понедельник, 27 августа 2012 г.

Ubuntu и DNS-Суффикс, /etc/nsswitch.conf, NetworkManager

Столкнулся с проблемой, когда Ubuntu при работе по DHCP неправильно работала с DNS-суффиксом, а именно работала только с суффиксами, а полные доменные имена не понимала, как следствие некорректно работали некоторые локальные сайты в браузерах, да и банальные пинги работали как-то не совсем правильно:
Ubuntu$ ping server
PING server.local (192.168.0.2) 56(84) bytes of data.
64 bytes from server.local (192.168.0.2): icmp_req=1 ttl=64 time=0.131 ms
^C
Ubuntu$ ping server.local
ping: unknown host server.local
При этом DNS сервер отлично обрабатывает запросы:
Ubuntu$ nslookup server
Server:  192.168.0.254
Address: 192.168.0.254#53

Name: server.local
Address: 192.168.0.2
И для доменного имени полностью:
Ubuntu$ nslookup server.local
Server:  192.168.0.254
Address: 192.168.0.254#53

Name: server.local
Address: 192.168.0.2
Погуглив немного, решил, что проблема в NetworkManager'е, на старых версиях Ubuntu он неправильно генерировал /etc/resolv.conf, проверил свой:
Ubuntu$ cat /etc/resolv.conf 
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.0.254
search local
Как оказалось, в моем случае NetworkManager вовсе не виноват! Но в чем же тогда проблема? Еще раз погуглил яндексом в рамблере и пришел к выводу, что виноват конфиг /etc/nsswitch.conf, сравнил его с FreeBSD'шным, где все работает как надо и пришел к выводу, что нужно строку hosts: привести к такому виду:
#НЕ работает!
#hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4

#работает!
hosts:          files dns
Что такое mdns4 разбираться не стал, без него все работает так, как надо и это главное.

Ссылки по теме:
1. Debian/Ubuntu - [решено] Не распознаёт имя контроллера домена

четверг, 9 августа 2012 г.

Борьба с DDoS SYN-Flood штатными средствами и nginx в Linux

Однажды мой знакомый написал мне, что его сайт перестал открываться сказал, что на сайт обрушилась DDoS атака. Полез я разбираться, в чем дело и в итоге суть проблемы была найдена - куча ip адресов с различными User Agent'ами приходили на сайт и делали очень много различных запросов...
В общем нужно было этих ботов отлавливать и блокировать им доступ к сайту, сперва подумал об iptables и ConfigServer Firewall (csf), но хостинг был внутри OpenVZ, а это означало невозможность использования более 120 правил, а так же невозможность установки модулей ядра и вообще каких либо изменений опций ядра. Потому стандартные подходы для решения проблемы сразу отпадали.
А время шло, и переписываться с тех поддежкой хостинга небыло времени, а платить огромные суммы за защиту от такой примитивной атаки небыло никакого желания.
Решение пришло в голову неожиданно, при перечитывании man ip, вспомнить зачем я его читал затрудняюсь, но решение было на редкость извращенским, но вполне рабочим :)
Решением было добавление маршрута проблемного IP в blackhole. В следствие чего пакеты от этих адресов будут молча отбрасываться (the rule prescribes to silently drop the packet.).
Сперва конфигурируем nginx:
...
worker_rlimit_nofile 200000;
events {
        worker_connections 1024;
        use epoll;
}

....

http {
        # Документ по умолчанию
        index  index.html index.htm index.php;

        ##
        # Basic Settings
        ##
        sendfile on;
        send_timeout 5;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 30 15;
        types_hash_max_size 2048;
        server_tokens off;

        client_header_timeout 15;
        client_body_timeout 15;

        #  лимитируем для зоны one 10 конектов в 1 сек.
        limit_req_zone $binary_remote_addr zone=one:16m rate=10r/s;

        #В ситуации когда сервер записал в сокет данные, но клиент не хочет
        #       их забирать, после таймаута по закрытию соединения в ядре
        #       данные будут держаться еще несколько минут. В nginx если директи                                                                             ва
        #       для принудительного сброса всех данных после закрытия по таймаут                                                                             у.
        reset_timedout_connection  on;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        gzip on;
        gzip_disable "msie6";
...
server {
        listen ip.ip.ip.ip:80;
        server_name my.site;

        open_file_cache max=100000 inactive=40s;
        open_file_cache_valid 60s;
        open_file_cache_min_uses 2;
        open_file_cache_errors on;

        #это значит что законектится с лимитом в 3 подключения за 1 сек можно 3 раза, а дальше 503 ошибка. Что и пишется в лог access.
        limit_req zone=one burst=10;

        # Default locations config.
        include conf.std;
...
}
...
}
Файлик /etc/nginx/conf.std:
####### STANDART
# redirect server error pages to the static page /50x.html
error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        root   /var/www/nginx-dist;
}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
        deny  all;
}

location ~ /\< {
        deny  all;
}
С конфигурацией nginx все, теперь скрипты.
Добавляем в файл /etc/crontab строки:
# parse nginx logs and ban bad ip via nullroute
* * * * * root /root/ddos/parse_nginx.log.sh >/root/ddos/parse_nginx.log.log 2>&1
Содержимое скрипта /root/ddos/parse_nginx.log.sh:
#!/bin/sh

ADMINS_IP='ip.ip.ip.ip'

echo $(date)
echo '--- запускаем систему парсинга nginx лога---'

echo ' ищем ботов'
cat /var/log/nginx/access.log \
        | grep -E -e 'HTTP/1.(0|1)" (400|403|405|499|503)' -e '] "-" 400 0 "-" "-"' \
        | awk '{print $1}' \
        | sort -nr | uniq -c \
        | awk '{if($1>10)print $1" "$2}' \
    > /root/ddos/banlist.txt

cat /var/log/nginx/error.log \
        | grep -E '(limiting requests|limiting connections)' \
        | awk -F"client: " '{print $2}' \
        | awk -F"," '{print $1}' \
        | sort -nr | uniq -c \
        | awk '{if($1>10)print $1" "$2}' \
    >> /root/ddos/banlist.txt

# get unique ip
cat /root/ddos/banlist.txt \
        | grep -v $ADMINS_IP \
        | uniq | sort -nr \
    > /root/ddos/banlist_uniq.txt

echo '------  очищаем tmp file бана-'
cat /dev/null > /root/ddos/banlist.txt

echo ' создаем DROP правила для 50 самых агрессивных ботов'
awk '{print $2}' /root/ddos/banlist_uniq.txt \
        | uniq | head -n 150 > /root/ddos/banlist.txt

#т.к. iptables полнейшее УГ, особенно внутри OpenVZ, баним ip вот таким извращенским методом... через nullroute
#ip route flush type blackhole
for ip in $(cat /root/ddos/banlist.txt); do
        ip route add blackhole ${ip}/32
done

#echo 'записываем злобных ботов в csf.deny'
#cat /etc/csf/csf.deny >> /root/ddos/banlist.txt
#cat /root/ddos/banlist.txt \
#       | uniq | sort -nr \
#    > /etc/csf/csf.deny

#echo 'csf релоад, внесение в iptables ботов'
#/usr/sbin/csf -r
sleep 5

echo '--  делаем ротацию лога--------'
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf

echo '=====злобные боты в списке бана====='

sleep 1
Для мониторинга состояния сервера используем такой скрипт:
#!/bin/sh

while :; do
netstat_str=$(netstat -an)
        echo -n 'SYN_RECV: '
        echo "$netstat_str" | grep 80 | grep SYN_RECV | wc -l
        echo -n 'TIME_WAIT: '
        echo "$netstat_str" | grep 80 | grep TIME_WAIT | wc -l
        echo -n 'FIN_WAIT: '
        echo "$netstat_str" | grep 80 | grep FIN_WAI1 | wc -l
        echo -n 'ESTABLISHED: '
        echo "$netstat_str" | grep 80 | grep ESTABLISHED | wc -l

        echo -n 'BLOCKED_IP to Black-route: '
        ip route list | grep blackhole | sort | wc -l

        sleep 2
        echo '------------------------- for stop this script Press Ctrl+C'
done
Еще понадобится настроить ротацию логов, приводим файл /etc/logrotate.d/nginx к такому виду:
/var/log/nginx/*.log {
        size 1M
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
}
Еще я использовал встроенные средства iptables для борьбы с DDoS:
#!/bin/sh

iptables -F
iptables -N syn_flood
iptables -A INPUT -p tcp --syn -j syn_flood
iptables -A syn_flood -m limit --limit 100/s --limit-burst 150 -j RETURN
iptables -A syn_flood -j DROP

Данный скрипт спокойно блокировал DDoS примерно в 10 000 ботов, при этом сайт был полностью доступен и атака вообще не чувствовалась.
Прошу обратить внимание на то, что скрипт запускается раз в минуту, и блокирует ip адреса по заданным критериям в скрипте /root/ddos/parse_nginx.log.sh. В моем случае атака была "вялой" и одной минуты вполне хватало для сбора ip адресов ботов. В первые минуты сайт "туго" работал, но спустя минут 10, когда список заблокированных вырос сайт начал свою штатную работу, а список блокированных с течением времени увеличивался все медленнее и в итоге совсем перестал расти - у атакующего закончились боты.

понедельник, 6 августа 2012 г.

Перенос FreeBSD 4 на VirtualBox

Заходим по ssh на машину, которую будем переносить, останавливаем все процессы, которые могут использовать hdd и писать туда важную информацию (например MySQL и т.п.) и делаем дампы всех важных разделов:
# dump -0uan -f - /usr | ssh -c blowfish user@ip.ip.ip.ip dd of=/home/user/oldsrv/var.dd
# dump -0uan -f - /var | ssh -c blowfish user@ip.ip.ip.ip dd of=/home/user/oldsrv/var.dd
Грузимся с LiveCD FreeBSD у меня уже была загрузка по сети FreeBSD 9.0 (но думаю подойдет и любой другой дистрибутив, Frenzy например). Восстанавливаем корневой раздел:
# mkdir /tmp/oldsrv
# cd /tmp/oldsrv
# scp user@ip.ip.ip.ip:/home/user/oldsrv/*.dd
# dd if=from_real_srv/rootfs.dd | restore -rf -
...
убедиться, что все необходимые каталоги, куда будем восстанавливать остальные разделы имеются:
# ls usr
# ls var
...
И начинаем восстанавливать остальные разделы:
# dd if=from_real_srv/usr.dd | (cd usr; restore -rf -)
# dd if=from_real_srv/var.dd | (cd var; restore -rf -)
...

Ссылки по теме:
1. 17.12. Основы технологии резервного копирования.
2. Перенос FreeBSD с одного жёсткого диска на другой.

четверг, 2 августа 2012 г.

Перенос Windows 7 с одного HDD на другой HDD меньшего объема. (dd + Gparted)

На работе часто бывает необходимо перенести или скопировать Windows 7 с одного HDD на другой по разным причинам, умирает HDD или нужно установить HDD с меньшим или наоборот с бОльшим объемом, в общем проблема решается довольно просто, при помощи 2 утилит dd и Gparted.
Загружаемся в Ubuntu LiveCD, у меня была загрузка по сети образа Ubuntu 12.04 LTS Desktop.
И первым делом копируем главную загрузочную запись (MBR):
dd if=/dev/sda of=/dev/sdb bs=512 count=1
После чего запускаем Ggparted и копируем разделы (она имеется в обычном ISO).
Не забываем проверить флаг boot на 100Мбайтном разделе.




P.S. Немного об утилите dd:
if=/dev/sda -- input file (входной файл, в данном случае диск с Windows 7)
of=/dev/sdb -- output file (выходной файл, в данном случае диск куда копируем)
bs=512 -- block size (Внимание! Операнд count имеет дело с блоками, а не с байтами! 512 блоков)
count=1 -- count (количество раз проведения операции копирования буфером)

MBR находится в 0 секторе первого раздела жесткого диска и занимает вместе с таблицей разделов ровно 512 байт. Поэтому и размер блока выбираем 512, а количество count единица - получаем 512 байт.
А если нам нужно не весь MBR, а только загрузочный код, который занимает первые 446 байт 0 сектора, то придется изменить размер блока:
# dd if=/dev/sda of=boot-code.mbr bs=446 count=1
Обратите внимание, на то, что сохраняем в файл, т.к. в устройство записать такой объем не получится, как уже говорилось выше, запись на устройства производится блоками по 512 байт.
Чтобы теперь записать сохраненный загрузчик, нужно получить блок размером в 512 байт, для этого сохраняем в другой файл таблицу разделов - это оставшиеся 66 байт после загрузочного кода - 446 байт.
# dd if=/dev/sdb of=part-table.mbr bs=1 count=66 skip=446
skip=n(блоков) Этот операнд пропускает n блоков от начала входного (if) файла(устройства), а затем копирует указанное количество блоков. Внимание! Операнд skip (как и count) имеет дело с блоками, а не с байтами! Поэтому размер блока следует выбирать вдумчиво.
И еще обратите внимание на то, что сейчас мы выбрали устройство /dev/sdb, т.к. нам нужна таблица разделов именно этого устройства, ведь мы туда собираемся копировать загрузчик с устройства /dev/sda :)
Теперь нужно "собрать" MBR из имеющихся кусочков:
# cat boot-code.mbr > mbr
# cat part-table.mbr >> mbr
Теперь наконец-то мы можем записать загрузочный код на устройство!
# dd if=mbr of=/dev/sdb bs=512 count=1

Ссылки по теме:
1. Команда dd и её использование.
2. Как мне скопировать загрузочную запись линуха на дискету?