Создаем снапшот test1 раздела /home
mount -v -u -o snapshot /home/snapshot/test1 /home
или другой метод:
mksnap_ffs /home /home/snapshot/test1
Привязываем снапшот к устройству /dev/md1:
mdconfig -a -t vnode -f /home/snapshot/test1 -u 1
При необходимости снапшот можно смонтировать и посмотреть его содержимое:
mount -o ro /dev/md1 /mnt
....
umount /mnt
Копируем содержимое раздела на второй диск:
dd if=/dev/md1 of=/dev/ad4s1f bs=16k
Отключаем снапшот
mdconfig -d -u 1
Выполняем fsck на новом разделе:
fsck -f /dev/ad4s1f
В логе smartd появились подобные свидетельства наличия нечитаемых секторов на диске:
smartd[798]: Device: /dev/ad5, 15 Currently unreadable (pending) sectors
smartd[798]: Device: /dev/ad5, 15 Offline uncorrectable sectors
SMART тестирование подтвердило подозрения:
Запускаем фоновый тест диска, не мешающий основной работе:
smartctl -t long /dev/ad5
Ждем завершения периодически просматривая статус:
smartctl -l selftest /dev/ad5
В итоге смотрим содержимое лога, в самом конце вывода:
smartctl -a /dev/ad5
Имеем:
# 1 Extended offline Completed: read failure 90% 2916 10373954
Выявляем полный список сбойных секторов, путем чтения всех данных с диска:
dd if=/dev/ad5 of=/dev/null bs=512 conv=noerror,sync
В один прекрасный момент появятся надписи вида:
dd: /dev/ad5: Input/output error
10373954+0 records in
10373954+0 records out
5311464448 bytes transferred in 2427.397393 secs (2188131 bytes/sec)
В системном логе увидим:
kernel: ad5: TIMEOUT - READ_DMA retrying (1 retry left) LBA=10373954
kernel: ad5: TIMEOUT - READ_DMA retrying (0 retries left) LBA=10373954
....
kernel: ad5: FAILURE - READ_DMA timed out LBA=10374109
kernel: ad5: TIMEOUT - READ_DMA retrying (1 retry left) LBA=10374113
Проверяем, каждый участок еще раз:
dd if=/dev/ad5 of=/dev/null bs=512 count=1 skip=10373954 conv=noerror,sync
Смотрим какой файл в ФС подпадает под этот блок.
Смотрим и примерно вычисляем номер раздела на который приходится сбойный сектор (LBA 10373954):
fdisk -s /dev/ad5
/dev/ad5: 775221 cyl 16 hd 63 sec
Part Start Size Type Flags
1: 63 398444067 0xa5 0x80
2: 398444130 382973535 0xa5 0x80
10373954 - 63 = 10373891
disklabel /dev/ad5s1
# /dev/ad5s1:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 2097152 0 4.2BSD 2048 16384 28552
b: 4194304 2097152 swap
c: 398444067 0 unused 0 0 # "raw" part
d: 2097152 6291456 4.2BSD 2048 16384 28552
e: 10485760 8388608 4.2BSD 2048 16384 28552
f: 104857600 18874368 4.2BSD 2048 16384 28552
g: 104857600 123731968 4.2BSD 2048 16384 28552
h: 162127234 228589568 4.2BSD 2048 16384 28552
Видим, что 10373891 приходится на раздел /dev/ad5s1e
Расчитываем смещение относительно начала раздела:
10373891 - 8388608 = 1985283
Находим иноду, которой принадлежит заданный блок:
fsdb -r /dev/ad5s1e
findblk 1985283
повторяем для каждого сбойного сектора
(для Linux нужно использовать debugfs - http://smartmontools.sourceforge.net/BadBlockHowTo.txt)
Пытаемся записать данные в сбойный сектор, чтобы инициировать процесс
ремапинга на диске.
sysctl kern.geom.debugflags=16 # иначе будет dd: /dev/ad5: Operation not permitted)
dd if=/dev/zero of=/dev/ad5 bs=512 count=1 skip=10373954 conv=noerror,sync
sysctl kern.geom.debugflags=0
Если после записи сектор начал читаться - все ok,
если нет - резервная область на диске уже заполнена, пробуем запретить обращещние окружающих секторов в ФС:
man badsect
/dev/ad5s1e примонтирован как /usr, создаем директорию /usr/BAD и выполняем
badsect /usr/BAD 1985283
fsck -y /dev/ad5s1e
Полезные порты:
/usr/ports/sysutils/recoverdm
/usr/ports/sysutils/diskcheckd
1. Качество исполнения, запас прочности и надежность накопителей со SCSI
интерфейсом как правило выше, чем у IDE.
2. Два подключенных к одному каналу контроллера IDE накопителя, не могут
одновременно передавать данные по шине.
3. SCSI показывают значительно лучшую производительность в загруженной
многозадачной среде, при обилии разрозненных параллельных запросов за
счет более оптимального использования шины передачи данных. (конек IDE -
линейное чтение, сильная сторона SCSI - случайный доступ).
Поясняю: Специфика IDE такова, что запросы могут передаваться по одной
шине последовательно (одна труба передачи данных, однопоточный режим).
Допустим, если 100 процессов обращаются к данным на диске, запросы в
рамках одного канала контроллера будут обрабатываться один за другим, каждый
следующий после полного выполнения предыдущего (связка: выдача
команды - получение данных).
При использовании SCSI, допускается перекрытие запросов (организуется
очередь команд), ответы при этом будут получены распараллеленно
(асинхронная передача), при этом устройство
заведомо зная подробности по командам находящимся в очереди, производит
оптимизацию самостоятельно - минимизируя движение головок.
Итак, пришло время поднять IPv4-IPv6 gateway, чтобы ходить в мир "другого интернета", коим он скоро будет.
Самым простым способом получить IPv6 адрес оказалось получить подключение от http://go6.net
Идем на этот сайт и регистрируемся http://go6.net/4105/register.asp
Тут же они предлагают скачать софт и поставить, например для Windows вида "скачай и запусти"
http://go6.net/4105/download.asp
Но это не совсем наш метод, мы будем подключать сервер на FreeBSD 7.0 к этой сети.
Ядро у нас собрано с поддержкой IPV6, т.е. с options INET6 (ядро GENERIC уже
поддерживает этот протокол и если вы его не отключали, значит, он у вас есть)
Итак, ставим клиента, то, что они предлагают скачивать - есть в портах
Port: gateway6-5.0_2
Path: /usr/ports/net/gateway6
Info: Gateway6 Tunnel Setup Protocol Client - Free IPv6 tunnel
B-deps:
R-deps:
WWW: http://www.go6.net/
Приступаем к установке:
cd /usr/ports/net/gateway6
make install clean
Буквально через несколько минут клиент будет установлен
Отредактируйте его конфигурационный файл /usr/local/etc/gw6c.conf
userid=
passwd=
Пропишите туда ваше имя и пароль которые указали при регистрации на сайте.
На этом начальная настройка закончена, для дальнейшей настройки читайте документацию.
Как я понял, выдается целая сеть и для авторизованных пользователей http://go6.net/4105/freenet.asp,
тем самым можно все компьютеры дома подключить на реальные статические IPv6 адреса.
server=broker.freenet6.net
broker.freenet6.net - это имя сервера для подключения (написано в письме при регистрации)
# Включить использование авторизации
auth_method=any
# Писать логи в syslogd
log_syslog=3
Теперь осталось запустить его
echo 'gateway6_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/gateway6 start
И смотрим
# tail -f /var/log/messages
Oct 17 18:39:38 lola gw6c: Gateway6 Client v5.0-RELEASE build Oct 17 2008-14:56:32
Oct 17 18:39:38 lola gw6c: Establishing connection to tunnel broker broker.freenet6.net using reliable UDP.
Oct 17 18:39:42 lola gw6c: Connection to broker.freenet6.net established.
Oct 17 18:39:45 lola gw6c: Authentication success.
Oct 17 18:39:45 lola gw6c: Got tunnel parameters from server. Setting up local tunnel.
Oct 17 18:39:45 lola gw6c: Executing configuration script: /bin/sh "/usr/local/share/gateway6/freebsd.sh".
Oct 17 18:39:46 lola gw6c: Script completed successfully.
Oct 17 18:39:46 lola gw6c: Your IPv6 address is 2001:05c0:8fff:fffe:0000:0000:0000:c243.
Oct 17 18:39:46 lola gw6c: The tunnel type is v6udpv4.
# ifconfig
tun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1280
inet6 2001:5c0:8fff:fffe::c243 --> 2001:5c0:8fff:fffe::c242 prefixlen 128
Opened by PID 873
# traceroute6 www.jp.freebsd.org
...
# ping6 www.jp.freebsd.org
...
Все прекрасно работает не смотря на то, что выход осуществляется в мир через
NAT на модеме.
Итак, осталось только понять, "зачем это надо", но ясно одно - за этим будущее.
А еще можно посмотреть на танцующую черепаху на http://www.kame.net/ :-)
Также рекомендую прочитать документацию (главу в
HandBook http://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/network-ipv6.html)
по поддержке протокола IPv6 в системе FreeBSD.
После переноса сервиса на новый сервер, на старом можно организовать сервис заглушку,
осуществляющий редирект следующим образом:
/etc/xinetd.d/smtp-tcp
service smtp
{
disable = no
socket_type = stream
protocol = tcp
user = nobody
wait = no
server = /bin/nc
# server = /usr/bin/netcat
server_args = -w 2 192.168.1.1 25
}
где 192.168.1.1 адрес нового сервера, nc - утилита netcat, "-w 2" - таймаут в 2 сек.
Блокируемый I/O - после вызова read/write происходит блокировка до завершения
операции, функция завершается только после принятия или передачи блока данных.
Неблокируемый I/0 - функция завершается сразу, если данные не были приняты/отправлены
возвращается код ошибки (т.е. нужно вызывать функции I/O в цикле пока не получим
положительный результат).
Мультиплексирование через select/poll - опрашиваем список состояния сокетов,
перебирая состояния определяем сокеты готовые для приема/передачи.
Главный минус - затраты на перебор, особенно при большом числе неактивных
сокетов.
select - число контролируемых сокетов ограничено лимитом FD_SETSIZE,
в некоторых случаях лимит обходится пересборкой программы, в других - пересборкой
ядра ОС.
poll - нет лимита FD_SETSIZE, но менее эффективен из за большего размера передаваемой
в ядро структуры.
Генерация сигнала SIGIO при изменении состояния сокета (ошибка, есть данные для приема,
или отправка завершена), который обрабатывает обработчик SIGIO.
В классическом виде применение ограничено и трудоемко, подходит больше для UDP.
Асинхронный I/O - описан в POSIX 1003.1b (aio_open, aio_write, aio_read...),
функция aio_* завершается мгновенно, далее процесс сигнализируется о
полном завершении операции ввода/вывода (в предыдущих пунктах процесс информировался
о готовности прочитать или передать данные, т.е. данные еще нужно было принять или отправить
через read/write, в aio_* процесс сигнализируется когда данные полностью получены и скопированы в локальный буфер).
Передача данных об изменении состояния сокета через генерацию событий. (специфичные для определенных ОС решения, малопереносимы, но эффективны).
kqueue - лучшее для FreeBSD, NetBSD. Данные о нескольких событиях могут быть переданы за раз, очень гибкое решение.
/dev/epoll - лучшее для 2.6 Linux ядра, передача нескольких событий за раз, трудоемкость поддержки /dev/epoll если параллельно в программе поддерживаются другие механизмы нотификации.
Realtime Signals (F_SETSIG) - лучшее для 2.4 Linux ядра.
/dev/poll - имеет смысл в Solaris, в Linux реализация недостаточно хороша.
Ссылки:
libevent - очень хорошая библиотека враппер для работы с kqueue, select, poll, epoll и real-time signals.
tcpdump -X -s 1500 -n -i fxp0 (tcp port 443) or (tcp port 994)
Если нужно выбрать трафик в котором не фигурируют IP 1.2.3.190 и 192.168.20.254, а также внутренние
пересылки между адресами 192.168.20 сети, можно использовать правило фильтрации:
not host 1.2.3.190 and not host 192.168.20.254 and not (dst net 192.168.20.0/24 and src net 192.168.20.0/24)
На форуме часто задается вопрос, по поводу маршрутизации сети, подключенной к двум провайдерам.
В частном случае проблема расширяется тем, что нужно осуществлять проброс соединений к сервисам,
расположенным в локальной сети. Это делается с помощью DNAT, и при этом снова возникает
проблема - по каналу какого провайдера отправлять ответ. Проблема усугубляется тем,
что обратное преобразование адресов выполняется уже после принятия
решения о маршрутизации,
т.е. примерно в районе цепочки POSTROUTING, но скрытно от пользователя.
Решить эту нерешаемую проблему поможет модуль CONNMARK. Принцип работы маршрутизатора для
решения описанной задачи будет выглядеть примерно так:
Входящие соединения маркируются определенным флажком, после чего делается их проброс в нужное назначение.
Каждый обратный пакет соединения _до принятия решения о маршрутизации_ маркируется
флажком соответствующего ему соединения (флажок восстанавливается).
На основании флажков принимается решение о маршрутизации пакета в соответствующую сеть.
В нижеописанном примере обеспечение доступности сервиса по двум каналам/провайдерам
делалось для локального сервиса маршрутизатора. В связи с этим маркировка исходящих
пакетов делается в цепочке OUTPUT таблицы mangle. Для проброса порта к серверу в локальной сети
(в DMZ) проверку и восстановление маркера надо делать в цепочке PREROUTING.
Таким образом, "обратный DNAT" будет происходить когда пакет уже будет идти по нужному маршруту.
Все не маркированные пакеты будут идти по маршруту по умолчанию. В моем случае это первый
провайдер first и айпи интерфейса first_ip. Входящие пакеты/соединения с порта второго провайдера
(destination <second_ip>) будут помечены маркером и к ним будет применен DNAT.
Все исходящие (обратные) пакеты будут промаркированы значением маркера соединения
в цепочке OUTPUT таблицы mangle.
Более корректным вариантом, не зависящим от значения шлюза по умолчанию,
является обязательная маркировка пакетов для соединений от любого провадера и
создание соответствующих правил маршрутизации.
[root@test z]# iptables -t nat -nvL PREROUTING
Chain PREROUTING (policy ACCEPT 144M packets, 9659M bytes)
pkts bytes target prot opt in out source destination
1 52 CONNMARK tcp -- * * 0.0.0.0/0 <second_ip> tcp dpt:<port> CONNMARK set 0x1
1 52 DNAT tcp -- * * 0.0.0.0/0 <second_ip> tcp dpt:<port> to:<first_ip>:<port>
[root@test z]# iptables -t mangle -nvL OUTPUT
Chain OUTPUT (policy ACCEPT 6745M packets, 7048G bytes)
pkts bytes target prot opt in out source destination
65915 8600K CONNMARK tcp -- * * <first_ip> 0.0.0.0/0 tcp spt:<port> CONNMARK restore
[root@test z]# ip ru sh
0: from all lookup local
1000: from all lookup main
3300: from all fwmark 0x1 lookup <second>
5000: from <first_ip> lookup <first>
5500: from <second_ip> lookup <second>
10000: from all lookup default
32766: from all lookup main
32767: from all lookup default
Иногда нужно узнать какому производителю принадлежит оконечное оборудование,
наблюдая только его мак на интерфейсе. А открывать браузер для этого лениво.
В таком случае удобно создать MAC-based dns лист. Пользоваться просто:
ket:/home/sva# host -t txt 001243.macl.nov.ru
001243.macl.nov.ru descriptive text "Cisco"
ket:/home/sva# host -t txt 0050ba.macl.nov.ru
0050ba.macl.nov.ru descriptive text "D-LINK"
Linux шлюз:
Нужно создать простую одноранговую ad-hoc сеть и дать статический IP-адрес сетевому беспроводному интерфейсу.
После этого делаем NAT и всё работает. Для беспроводного интерфейса eth3 и
сети с идентификатором virens команда выглядит так (от рута):
# iwconfig eth3 mode Ad-Hoc channel 1 essid virens
В /etc/network/interfaces пишем что-то вроде:
auto eth3
iface eth3 inet static
address 10.106.146.1
netmask 255.255.255.0
wireless-mode ad-hoc
wireless-channel 1
wireless-rate auto
wireless-essid virens
Теперь делаем NAT:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING --out-interface eth1 -j MASQUERADE
При этом eth1 это интерфейс, который подключён к Интернету.
Соединение не шифруется.
КПК:
Необходимо задать essid - такой же, какой дали в iwconfig.
Шифрование отсутствует, тип сети - одноранговая ad-hoc.
Снимаем галку "Получать IP-адрес автоматически" и вводим адреса:
IP-адрес: 10.106.146.2
Маска подсети: 255.255.255.0
Маршрутизатор: 10.106.146.1
Дано:
Есть hostA, который воткнут в каталист, в trunk (т.е. тегированный) порт, инкапсуляция 802.1q.
Есть hostB, который маршрут до hostA. маршрут живой, ip-пакеты между хостами безпроблемно бегают.
Задача: надо с hostA "притащить" виланы на hostB.
Решение: vtund + bridge.
описание клиента в vtund.conf
homepeer {
passwd qwerty;
type ether;
device home;
proto tcp;
compress yes;
stat yes;
persist yes;
up {
ifconfig "%% up";
program "brctl addbr br0";
program "brctl addif br0 %%";
program "brctl addif br0 eth0";
ifconfig "br0 up";
};
down {
ifconfig "%% down";
ifconfig "br0 down";
program "brctl delbr br0";
};
}
описание пира из конфига сервера
homepeer {
passwd qwerty; # Password
type ether; # Ethernet tunnel
device work; # Device tap1
proto tcp;
compress yes;
up {
ifconfig "%% up";
};
down {
ifconfig "%% down";
};
}
Теперь на той Linux машине, куда кидаем порт:
vconfig set_name_type VLAN_PLUS_VID_NO_PAD
vconfig add work 4
ifconfig vlan4 10.1.1.1 netmask 255.255.255.0 up
vconfig add vlan4 8
ifconfig vlan8 192.168.1.1 netmask 255.255.255.0 up
Замечание:
Клиент - хост, с которого мы тащим порт. Он живёт в серой сети и имеет выход в internet через NAT.
Сервер - машина с публичным ip.
Если нужно сбросить счетчики пакетов/байт, отображаемые ifconfig, то есть из /proc/net/dev,
нужно собрать драйвер сетевой карты в виде модуля (не в ядро).
Для сброса опускаем интерфейс, выгружаем драйвер, загружаем снова и поднимаем интерфейс.
Должно работать на всех картах.
Пример.
ifdown eth0
modprobe -r eepro100
modprobe eepro100
ifup eth0
Для того чтобы узнать имя драйвера обеспечивающего работу сетевого интерфейса:
ethtool -i eth1
При наличии нескольких одинаковых сетевых карт, чтобы гарантировать, что eth0, eth1,.. всегда будут
закреплены за одними и теми же картами, можно огранизовать привязку имени к MAC адресу:
В /etc/mactab добавляем:
eth0 00:23:B7:89:39:E2
eth1 00:08:A3:20:F8:29
eth2 00:50:BA:29:B7:32
Для Debian GNU/Linux создаем скрипт /etc/network/if-pre-up.d/nameif
#!/bin/sh
PATH=/sbin
nameif -c /etc/mactab
Для других Linux дистрибутивов нужно на начальном этапе инициализаци выполнить:
/sbin/nameif eth0 00:23:B7:89:39:E2
/sbin/nameif eth1 00:08:A3:20:F8:29
/sbin/nameif eth2 00:50:BA:29:B7:32
Предположим, имеется несколько сетевых интерфейсов fxp0,fxp1,fxp2,fxp3
вы хотите чтобы ваша машина выспупала в качестве сетевого моста:
Первый способ на основе if_bridge(работает в 5-STABLE и 6-ке)
# kldload if_bridge
# ifconfig bridge0 create
# ifconfig bridge0 addm fxp0 addm fxp1 addm fxp2 addm fxp3 up
# ifconfig fxp0 up
# ifconfig fxp1 up
# ifconfig fxp2 up
# ifconfig fxp3 up
Посмотреть # ifconfig bridge0
Подробнее в man if_bridge и man ifconfig
Второй способ на основе bridge:
# kldload bridge
# sysctl net.link.ether.bridge.config=fxp0,fxp1,fxp2,fxp3
# sysctl net.link.ether.bridge.enable =1
Пусть:
x.x.x.96/28 - выделенная подсеть, которую нужно распределить по машинам в локальной сети.
x.x.x.97 - IP внешнего шлюза.
Требуется поставить между шлюзом и сетью фаервол,
с одним адресом на двух интерфейсах x.x.x.98, транслируя ARP трафик используя "Proxy ARP".
(x.x.x.99 ... x.x.x.110) --- (eth1, x.x.x.98 | eth0, x.x.x.98) --- (x.x.x.97)
Удаляем маршруты созданные по умолчанию.
ip route del x.x.x.96/28 dev eth0
ip route del x.x.x.96/28 dev eth1
Пакеты для x.x.x.97 пускаем через eth0, а для x.x.x.96/28 через eth1
ip route add x.x.x.97 dev eth0
ip route add x.x.x.96/28 dev eth1
Включаем Proxy ARP
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
Превращение двух 100 мбит/c сетевых карт в одну виртуальную, с пропускной способностью 200 мбит/c.
Документация: Documentation/networking/bonding.txt в дереве исходных текстов ядра и "modinfo bonding".
Кратко:
Подгружаем модуль ядра "bonding", в /etc/modules.conf указываем
alias bond0 bonding
При желании устанавливаем опции для доп. настройки модуля, например:
options bond0 mode=2, где mode=
0 - balance-rr (Round-robin выбор интерфейса)
1 - active-backup (работает только один интерфейс, остальные в режиме горячей замены)
2 - balance-xor - для всех пересылок на MAC закрепляется один из интерфейсов
3 - broadcast - трафик идет через оба интерфейса одновременно
4 - 802.3ad - для коммутаторов с поддержкой IEEE 802.3ad Dynamic link aggregation
5 - balance-tlb, 6 - balance-alb
/sbin/ifconfig bond0 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 up
/sbin/ifenslave bond0 eth0
/sbin/ifenslave bond0 eth1
Или для дистрибутивов в которых используется пакет initscripts (http://rhlinux.redhat.com/initscripts/):
/etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
BOOTPROTO=static
BROADCAST=192.168.63.255
IPADDR=192.168.1.1
NETMASK=255.255.255.0
NETWORK=192.168.0.0
ONBOOT=yes
/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
MASTER=bond0
SLAVE=yes
USERCTL=no
/etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
ONBOOT=yes
MASTER=bond0
SLAVE=yes
USERCTL=no
Я сделал так (идею тоже нашел на этом сайте):
1. Создал файл б/д привязки IP к MAC (например /etc/ethers.local)
Пример строк из файла:
192.168.0.11 00:0c:6e:3f:cd:e5 #kasa2
192.168.0.12 00:0d:88:82:da:a2 #mobil
и т. д.
2. Написал скрипт такого содержания: (например /etc/static.arp):
#!/bin/sh
# обнуляем всю таблицу arp
arp -ad > null
# к каждому компу в локальной сети привязываем несуществующий (нулевой)
# MAC адрес
I=1
while [ $I -le 254 ]
do
arp -s 192.168.0.${I} 0:0:0:0:0:0
I=`expr $I + 1`
done
# к реально существующему компу в сети из базы данных в файле
# /etc/ethers.local привязываем
# правильный MAC адрес
arp -f /etc/ethers.local
3. Делаем этот файл исполняемым и прописываем в файл /etc/rc.local такую
строчку:
/etc/static.arp
Еще желательно, чтобы привязки имен юзерских хостов к ip-адресам были
прописаны в /etc/hosts (это ускорит их поиск). Теперь сервер не будет
рассылать широковещательные запросы о локальных MAC адресах, т. к. все они
статически жестко привязаны к ip-адресам. Этим убивается два зайца: не
рассылаются широковещательные запросы, что экономит траффик и время
на ответ сервера, и не позволяет пользователю менять свой ip-адрес,
т. к. сервер все равно пакет будет отправлять на жестко привязанный
MAC адрес.
man polling - периодических опрос состояния ядром, вместо генерации прерываний
(полезно при очень большом числе пакетов проходящих через сетевую карту),
возможен комбинированный вариант, когда polling включается при преодалении определенного порога нагрузки).
В конфигурации ядра
options DEVICE_POLLING
options HZ=1000
Далее:
sysctl kern.polling.enable=1
sysctl kern.polling.user_frac=50
Приходилось сталкиваться с проблемами согласования режимов работы карт Intel EtherExpress 100 и
Reltek RTL-8139 c коммутаторами и концентраторами различных производителей. Несогласование
проявляется, например в работе карты в режиме half-duplex, а свича в full-duplex и т.д. (в linux: /sbin/mii-tool -F 100baseTx-FD eth0)
/sbin/mii-tool -F 100baseTx-FD eth0
или ethtool -s eth0 speed 100 duplex full autoneg off
Для модуля:
В /etc/modules.conf:
options eepro100 options=0x200 full_duplex=1
alias eth0 eepro100
insmod eepro100.o debug=1 options=0x200
Для ядра в boot приглашении:
ether=0,0,0x200,eth0
PS. Для драйвера версии меньше 1.14 (mod_info -a eepro100) вместо 0x200 следует писать 0x30.
Неоднократно замечена проблема работы сетевых карт на базе RealTek 8129/8139 (машины под FreeBSD,
но с другими ОС тоже проявляется) с некоторыми концентраторами и коммутаторами.
Проявляется в замирании сессий до истечения таймаута.
Диагностика: ping -s N remote_ip, при больших N не проходят.
Решение: Смените сетевую карту, например, на Intel EtherExpress Pro.
Текущий режим работы сетевой карты можно посмотреть выполнив:
# ifconfig fxp0
Перевести сетевую карту в режим работы 10baseT/UTP half-duplex:
# ifconfig fxp0 media 10baseT/UTP mediaopt half-duplex
Автоматически выбрать режим:
# ifconfig fxp0 media autoselect
Подробнее: man 4 ed, man 4 rl, man 4 fxp
Довольно часто бывает, что пропускной способности не хватает.
Если у вас нет гигабитной сетевой карты (или порта на свиче), не расстраивайтесь.
Можно вставить в компьютер еще 1-2 сетевухи и объединить интерфейсы в один.
Данная операция называется bonding. Так как под рукой у меня только Gentoo,
то могу привести алгоритм объединения интерфейсов только для него.
Итак.
1. emerge ifenslave
2. Редактируем /etc/conf.d/net:
2.1 Комментируем текущий конфиг
2.2 Пишем следующее:
slaves_bond0="eth0 eth1"
config_bond0=( "192.168.1.101 netmask 255.255.255.0 brd 192.168.1.255" )
routes_bond0=( "default gw 192.168.1.11" )
config_bond0 и routes_bond0 берем из закомментированного конфига
(скорее всего это будет config_eth0 и routes_eth0).
То есть настраиваем bond0 как обычный интерфейс
3. Делаем симлинк из /etc/init.d/net.lo в /etc/init.d/net.bond0
4. Проверяем:
~# /etc/init.d/net.eth0 stop
~# /etc/init.d/net.bond0 start
5. Если все нормально, то добавляем старт интерфейса при загрузке
~# rc-update -d net.eth0
~# rc-update -a net.bond0 boot
Все, скорость линка должна возрасти.
Имеется два сервера - первичный и запасной. При помощи протокола VRRP (Virtual Router Redundancy Protocol)
при крахе первичного сервера, автоматически поднимаем его MAC и IP на запасном.
Устанавливаем vrrpd (http://sourceforge.net/projects/vrrpd/).
На первичном сервере выполняем:
vrrpd -i eth0 -p 25 -v 1 192.168.1.1
На запасном:
vrrpd -i eth0 -p 24 -v 1 192.168.1.1
,где
-i eth0 - имя интерфейса на котором будет установлен IP 192.168.1.1
-v 1 - (virtual router) номер VRRP связки
(в локальной сети может быть несколько резервирующих друг-друга систем)
-p N - приоритет, машина с меньшим весом будет активирована, только при недоступности системы с большим весом.
При тестировании можно использовать tcpdump -vv proto 112
arp -s ваш.ip.адрес mac.адрес.сетевой.карты pub
Пример: /usr/sbin/arp -s 192.168.0.10 0:0:e7:ac:4c:63 pub
Начиная с FreeBSD 4.10 в ifconfig доступна опция staticarp,
заставляющий интерфейс только отвечать на ARP запросы для привязанных к нему адресам.
В конфигурацию ядра добавляем:
options IPFIREWALL #firewall
options IPFIREWALL_VERBOSE #enable logging to syslogd(8)
options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default
options IPDIVERT
options IPFIREWALL_FORWARD
options DUMMYNET
options IPFIREWALL_NAT #ipfw kernel nat support
options LIBALIAS
в /etc/make.conf:
CFLAGS+= -DIPFIREWALL_NAT
Далее пересобираем систему:
cd /usr/src/ ; make builworld && make kernel KERNCONF=YourKern && make installworld
reboot
В конфигурационном файле ipfw:
NatIP="111.111.111.111"
ipfw nat 123 config ip ${NatIP} log
ipfw add 10 nat 123 ip from 192.168.0.0/16 to any
ipfw add 20 nat 123 ip from any to ${NatIP}
Наслаждаемся достоинствами kernel nat
Для работы ipnat под большой нагрузкой (много трансляций) нужно
перед сборкой ядра изменить в файле /usr/src/sys/contrib/ipfilter/netinet/ip_nat.h
#undefine LARGE_NAT
на
#define LARGE_NAT
natd -p 8668 -a ip1
natd -p 8669 -a ip2
ipfw add divert 8668 ip from any to ip1 recv if1
ipfw add divert 8669 ip from any to ip2 recv if2
ipfw add check-state
ipfw add prob 0.5 divert 8668 ip from 192.168.0.0/16 to any xmit if1 keep-state
ipfw add divert 8669 ip from 192.168.0.0/16 to any xmit if1 keep-state
ipfw add fwd gw1 ip from ip1 to any out xmit if1 (если default на if1)
ipfw add fwd gw2 ip from ip2 to any out xmit if1
Что бы поднять NAT и Firewall на FreeBSD надо:
Скомпилировать ядро:
Следующие строки нужно включить в /usr/src/sys/i386/conf/GENERIC файл конфигурации:
options IPFIREWALL
options IPDIVERT
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options DUMMYNET
options TCP_DROP_SYNFIN
Переходим в директорию /usr/src/
make buildkernel KERNCONF=GENERIC
make installkernel KERNCONF=GENERIC
Следующие строки можно к примеру включить в rc.conf файл конфигурации:
hostname="free"
ifconfig_rl0="10.0.0.1"
gateway_enable="YES"
firewall_enable="YES"
firewall_type="open"
natd_enable="YES"
natd_interface="rl0"
natd_flags="-redirect_port tcp 10.0.0.10:80 80"
tcp_extensions="NO"
tcp_drop_synfin="YES"
icmp_drop_redirect="YES"
sendmail_enable="NONE"
Для удаленного управления нужно добавить следующую строку:
sshd_enable="YES"
(возможно понадобится скопировать /etc/ssh/ssh_host_dsa_key.pub в /root/.ssh/authorized_keys
Следующие строки можно включить в rc.firewall файл конфигурации (секция "open"):
[Oo][Pp][Ee][Nn])
oif="rl0"
iif="tx0"
oip="132.5.7.172"
iip="10.0.0.1"
lan="10.0.0.0/24"
setup_loopback
# allow all for LAN
${fwcmd} add 500 pass all from ${lan} to ${iip} via ${iif}
${fwcmd} add 550 pass all from ${iip} to ${lan} via ${iif}
# download - 60K upload - 6K for all lan ip's
${fwcmd} add 600 pipe 1 ip from any to any in via ${oif}
${fwcmd} add 650 pipe 2 ip from any to any out via ${oif}
# for selected ip's only
# ${fwcmd} add 601 pipe 1 all from any to 10.0.0.10
# ${fwcmd} add 651 pipe 2 all from 10.0.0.10 to any
${fwcmd} pipe 1 config bw 512Kbit/s
${fwcmd} pipe 2 config bw 48Kbit/s
# dns setup
${fwcmd} add 770 pass tcp from any to ${oip} 53 setup
${fwcmd} add 780 pass udp from any domain to any
${fwcmd} add 790 pass udp from any to any domain
# main setup
${fwcmd} add 800 pass tcp from any http,https,20-21,989-990 to any
${fwcmd} add 810 pass tcp from any to any http,https,20-21,989-990
${fwcmd} add 830 pass tcp from any pop3,pop3s,smtp,imap,imaps,aol to any
${fwcmd} add 840 pass tcp from any to any pop3,pop3s,smtp,imap,imaps,aol
${fwcmd} add 65000 deny ip from any to any
;;
Где oip, oif - внешний интерфейс; iip, iif - внутренний; lan - внутренняя сеть.
Такая конфигурация ipfw весьма параноидальна, и здесь приведена только в качестве примера.
На практике обычно нужен более открытый фаервол.
Решение оптимизировано для шлюза на флешке (не используется perl и другие "тяжелые" решения)
-------------------------
/usr/local/etc/rc.d/openvpn.sh
-------------------------
#!/bin/sh
. /etc/rc.subr
name=openvpn
rcvar=`set_rcvar`
prefix="/usr/local"
openvpn_precmd()
{
for i in $openvpn_if ; do
# FreeBSD <= 5.4 does not know kldstat's -m option
# FreeBSD >= 6.0 does not add debug.* sysctl information
# in the default build - we check both to keep things simple
if ! sysctl debug.if_${i}_debug >/dev/null 2>&1 \
&& ! kldstat -m if_${i} >/dev/null 2>&1 ; then
if ! kldload if_${i} ; then
warn "Could not load $i module."
return 1
fi
fi
done
return 0
}
start_postcmd()
{
`/bin/cat /var/db/ukr_nets| /usr/bin/awk '{ if ($1) {system("route add "$1" 193.201.61.65 >/dev/null")} }'`
/bin/sleep 10 && pfctl -F all -f /etc/pf.conf_openvpn
}
stop_postcmd()
{
`/bin/cat /var/db/ukr_nets| /usr/bin/awk '{ if ($1) {system("route delete "$1" 193.201.61.65 >/dev/null")} }'`
pfctl -F all -f /etc/pf.conf
rm -f "$pidfile" || warn "Could not remove $pidfile."
}
extra_commands="reload"
pidfile="/var/run/${name}.pid"
command="/usr/local/sbin/${name}"
start_precmd="openvpn_precmd"
start_postcmd="start_postcmd"
stop_postcmd="stop_postcmd"
load_rc_config ${name}
: ${openvpn_enable="NO"}
: ${openvpn_flags=""}
: ${openvpn_if=""}
: ${openvpn_configfile="${prefix}/etc/openvpn/openvpn.conf"}
: ${openvpn_dir="${prefix}/etc/openvpn"}
required_files="${openvpn_configfile}"
command_args="--cd ${openvpn_dir} --daemon --config ${openvpn_configfile} --writepid ${pidfile}"
run_rc_command "$1"
-------------------------
/etc/pf.conf
-------------------------
ext_if_t="rl0"
int_if="rl1"
table <users> persist { 192.168.1.0/24 }
nat on $ext_if_t inet from <users> to any -> $ext_if_t
pass on $ext_if_t all
pass on $int_if all
-------------------------
/etc/pf.conf_openvpn
-------------------------
ext_if_o="tap0"
ext_if_t="rl0"
int_if="rl1"
table <users> persist { 192.168.1.0/24 }
table <ukr> persist file "/var/db/ukr_nets"
nat on $ext_if_t inet from <users> to <ukr> -> $ext_if_t
nat on $ext_if_o inet from <users> to !<ukr> -> $ext_if_o
pass on $ext_if_o all
pass on $ext_if_t all
pass on $int_if all
-------------------------
cron:
-------------------------
0 0 * * * /usr/bin/fetch -q -o "/var/db/ukr_nets" 'http://www.colocall.net/ua/?list'
Иногда необходимо пробросить порты с двух различных gateway GW1 и GW2 на один внутренний сервер,
у которого в качестве default GW указан GW1.
Прямой проброс и NAT невозможен, т.к. пакеты пришедшие из GW2 попытаются вернуться по маршруту через GW1.
Есть следующий выход, это двойной NAT на GW2, при котором запрос приходит не снаружи, а с внутреннего IP.
ed0 - внешний интерфейс
lnc0 - интерфейс смотрящий внутрь.
в ipnat.rules нужно прописать следующее:
map ed0 10.6.10.0/24 -> 0.0.0.0/32 мапим локалку наружу
map lnc0 0.0.0.0/0 -> 0.0.0.0/32 ремап внешних ip в локальные
rdr ed0 0.0.0.0/0 port 80 -> 10.6.10.2 port 80 tcp форвард на внутренний сервер
Стоит задача - выпустить свою сеть в инет через два разных интерфейса rl1 и rl2.
Так как адреса в локали серые, то надо поднимать NAT. С учетом того, что динамической маршрутизации
не предвидится, будем поднимать NAT на 2 интерфейса. Для этого нужно:
Скомпилировать ядро с параметрами:
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=20
options IPFIREWALL_FORWARD
options IPDIVERT
options DUMMYNET
options TCP_DROP_SYNFIN
это необходимый минимум. На все случаи жизни )))))
Далее, в rc.local пишем такие строки:
natd -p 8668 -n rl1
natd -p 8669 -n rl2
#natd -p 8671 -n rl3
#natd -p 8672 -n rl4
#natd -p 8673 -n rl5
Последние три строки - если кому надо поднимать NAT на большее количество интерфейсов.
Следующее - правила ipfw:
ipfw -f add divert 8668 all from #твоясеть# to any out via rl1
ipfw -f add divert 8668 all from any to #адрес_rl1# in via rl1
ipfw -f add divert 8669 all from #твоясеть# to any out via rl2
ipfw -f add divert 8669 all from any to #адрес_rl2# in via rl2
Теперь все, что будет выходить через внешние интерфейсы, будет правильно NATиться через них же.
Остается проверить маршрутизацию. Если маска на rl2 /24. В этом случае все просто.
Стандартный шлюз (default gateway) прописан через rl1, а все, что идет на сеть 999.888.0.0/24 будет
автоматически бежать через rl2. Если же на rl2 выделена подсетка из нескольких адресов, то тогда надо
писать жесткий марщрут на всю сеть 999.888.0.0/24 через rl2 на тот шлюз, который тебе дал провайдер N2.
Его тоже можно прописать в rc.local отдельной строкой типа:
route add 999.888.0.0/24 999.888.0.25
У Sergey2005 заработала комбинация:
${fwcmd} add 40 divert 8668 all from #моя сеть# to not #подсеть провайдера "S"# out via rl1
${fwcmd} add 45 divert 8668 all from not #подсеть провайдера "S"# to any in via rl1
${fwcmd} add 50 divert 8669 all from #моя сеть# to #подсеть провайдера "S"# out via rl2
${fwcmd} add 55 divert 8669 all from #подсеть провайдера "S"# to any in via rl2
natd -p 8668 -m -u -n rl1
natd -p 8669 -m -u -n rl2
Необходимо выпустить пользователей на ftp сайты из локальной сети, но при этом не устанавливая
дополнительного ПО, используя только возможности FreeBSD 4.10.
Этими возможностями, как ни странно, оказались ipfw и natd
вот собственно как все это прописывается.
Исходные данные, FreeBSD 4.10 + настроенный nat правила для ipfw
ipfw -q add 100 divert natd from 192.168.20.0/24 to any 20, 21 out via $oif
ipfw -q add 200 divert natd from any 20, 21 to $iip in via $oif
ipfw -q add 300 allow tcp from any to any established
ipfw -q add 400 allow tcp from any to any setup
где $oif и $iip соответственно внешний интерфейс и внешний IP
теперь запускаем natd
/sbin/natd -m -s -u -punch_fw 500:200 -n xl1
заострю внимание на параметре "-punch_fw" -этот параметр создает в фаерволе "ходы",
добавляя динамические правила. В моем случае эти правила начнутся с номера 500 и будет их добавлено
максимум 200 (понятно чем больше сеть, те больше нужно правил).
Особое спасибо A Clockwork Orange.
Вот реализация для ipfw:
if1IP="ип_смотрящий_в_инет", if1="интерфейс_смотрящий_в_инет"
ifLIP="ип_на_который хотим делать редирект"
ipfw add divert natd tcp from any to ${if1IP} 80 via ${if1}
ipfw add divert natd ip from any to ${ifLIP} to any via ${if1}
ipfw add allow tcp from any to ${if1IP} 80 via any
natd -n ${if1} -redirect_port tcp ${ifLIP}:80 80
Решение от miaso <torov@wipline.ru>:
tproxy -s 80 -r nobody -l /var/log/transparent_proxy.log [int_ip] 80
man 5 ipnat в /etc/ipnat.conf:
rdr fxp0 205.15.63.3/32 port 80 -> 192.168.1.1 port 80 tcp
# Базансировка нагрузки между 2 IP:
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp round-robin
В ipnat воспользуйтесь модулем ftp proxy:
map fxp0 0/0 -> 0/32 proxy port ftp ftp/tcp
map rl0 172.16.33.0/24 -> 212.46.231.50/32 proxy port ftp ftp/tcp
не забудьте поместить правило трансляции ftp перед общим правилом трансляции,
порядок следования правил важен.
В /etc/rc.conf:
ipnat_enable="YES"
В /etc/ipnat.rules:
Трансляция адресов (NAT):
map ppp0 172.16.1.0/24 -> 194.46.124.53/32
где, ppp0 - внешний интерфейс,
172.16.1.0/24 - внутренние IP,
194.46.124.53 - реальный IP внешнего интерфейса.
Переброс порта во внутреннюю сеть:
rdr ed0 294.16.9.6/32 port 8080 -> 192.168.0.7 port 8080 tcp
где, ed0 - внешний интерфейс,
294.16.9.6 - реальный IP внешнего интерфейса, на который нужно обращаться из вне.
192.168.0.7 - внутренний IP на который делается переброс.
8080 - номер перебрасываемого порта.
Перечитать: ipnat -CF -f /etc/ipnat.rules
Проблема:
pppd[27229]: MPPE required, but keys are not available. Possible plugin problem?
Решение:
В свойствах "remote access policy", щелкаем "edit profile", на вкладе "encryption"
убираем галку No Encryption, Apply, ok. И не верьте никому, что это влияет только на MS RRAS.
Причина:
Без этой настройки IAS начинает отдавать вот такие радиус-атрибуты:
MS-MPPE-Encryption-Policy
MS-MPPE-Encryption-Types
а с ним, включенным по-умолчанию, не отдает.
Вот такой код я использую, чтобы вести учет статистики для PPP соединений в MySQL.
Этот код помещается в скрипт /etc/ppp/ip-down.
Используются переменные окружения, устанавливаемые pppd.
#!/bin/sh
#
echo "INSERT INTO pppdstats VALUES ( `date +%Y%m%d`, `date +\'%T\'
-d\"-${CONNECT_TIME} sec\" ` , '$PEERNAME', '$IPREMOTE',
'$CONNECT_TIME', '$BYTES_SENT', '$BYTES_RCVD', '$DEVICE', `date
+\'%T\'`);" | mysql -uuser -ppassword database
Формат таблицы:
CREATE TABLE pppdstats (
c_date date,
c_start_time time,
user varchar(128),
ip_addr varchar(15),
online_time int(11),
send_bytes int(11),
recv_bytes int(11),
device varchar(15),
c_end_time time
);
PS: Естественно, что изменив перенаправление можно записывать статистику в обычный текстовый файл.
запускать
bash# ppp -ddial test
Или если мы хотим поднимать соединение при старте, в rc.conf:
ppp_enable="YES"
ppp_mode="ddial"
ppp_profile="test"
и никаких tun0!
xl0 - ethernet карта куда воткнут модем (у меня Zyxel Omni ADSL LAN EE)
Вот как у меня, /etc/ppp/ppp.conf:
default:
test:
set device PPPoE:xl0
set MTU 1492
set MRU 1492
set dial
set crtscts off
set speed sync
accept lqr
disable deflate
disable pred1
disable vjcomp
disable acfcomp
disable protocomp
set log Phase LCP IPCP CCP Warning Error Alert
set ifaddr 10.0.0.1/0 10.0.0.2/0 0.0.0.0 0.0.0.0
add default HISADDR
set login
set authname ppp0012345@mtu
set authkey your_password
set server /var/run/ppp/ppp.pid "" 0117
Точнее, частично альтернативный. Используем все тот же pptpclient из портов,
прописываем роутинг к адресу vpn-сервера (если он в другом сегменте), а потом добавляем в ppp.conf нечто подобное:
vpn:
set device "!pptp <vpn_server_address> --nolaunchpppd"
set dial
set login
set server /var/run/ppp/loop "" 0177
set timeout 3600
set reconnect 120 0
enable dns
set authname <vpn_login>
set authkey <vpn_password>
nat enable yes
enable lqr
disable ipv6cp
disable mppe
set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0 0.0.0.0
add default HISADDR
Это мой конфиг и, естественно, не все из этого (типа, таймаутов и реконнектов) нужно всем. Как видно, в данном
случае не pptp вызывает ppp, а наоборот. Главный бонус как раз в том, что можно без геморроя обеспечить
on demand'овое соединение (потому и реконнекты с таймаутами у меня стоят) и автоматическое его поднятие,
если vpn_server сдох, а потом ожил. Ну и мелкие приятности - типа включения из rc.conf без необходимости
написания дополнительных скриптов....
Необходимо использовать опцию "unit N", где N - номер ppp интерфейса.
Например, для привязки к ppp0:
/usr/sbin/pppd /dev/ttyS0 115200 noauth crtscts 192.168.1.245:192.168.1.246 local \
nodetach netmask 255.255.255.252 unit 0
Необходимо установить из портов пакет pptpclient
/etc/ppp/ppp.conf
vpn:
set authname <LOGIN>
set authkey <PASSWORD>
set timeout 0
set ifaddr 0 0
add default HISADDR
Подключение к VBN серверу:
/sbin/route add -host <IP_address_of_VPN_server> <gateway>
/usr/local/sbin/pptp <IP_address_of_VPN_server> vpn &
Имеется сервер ASPLinux 10, с установленным postfix и 3-я сетевыми интерфейсами.
Задача: корректная работа почты через один из интерфейсов, при этом в качестве default gw указан другой.
Реализация:
1) в /etc/iproute2/rt_tables добавляем:
201 T1
202 T2
2) создаём скрипт и даём права на запуск, предварительно исправив нужные параметры
IP - адреса сетевых интерфейсов
P - адреса шлюзов
#!/bin/sh
IP1=192.168.4.1
IP2=217.1.1.2
P1=192.168.4.2
P2=217.1.1.1
ip route add default via $P1 table T1
ip route add default via $P2 table T2
ip route add default via $P1
ip rule add from $IP1 table T1
ip rule add from $IP2 table T2
В результате получим, что если пакет пришёл на P2, то он не пойдёт через default gw P1,
а уйдёт через тот же интерфейс с IP1
natd -p 8668 -a ip1
natd -p 8669 -a ip2
ipfw add divert 8668 ip from any to ip1 recv if1
ipfw add divert 8669 ip from any to ip2 recv if2
ipfw add check-state
ipfw add prob 0.5 divert 8668 ip from 192.168.0.0/16 to any xmit if1 keep-state
ipfw add divert 8669 ip from 192.168.0.0/16 to any xmit if1 keep-state
ipfw add fwd gw1 ip from ip1 to any out xmit if1 (если default на if1)
ipfw add fwd gw2 ip from ip2 to any out xmit if1
Пусть:
x.x.x.96/28 - выделенная подсеть, которую нужно распределить по машинам в локальной сети.
x.x.x.97 - IP внешнего шлюза.
Требуется поставить между шлюзом и сетью фаервол,
с одним адресом на двух интерфейсах x.x.x.98, транслируя ARP трафик используя "Proxy ARP".
(x.x.x.99 ... x.x.x.110) --- (eth1, x.x.x.98 | eth0, x.x.x.98) --- (x.x.x.97)
Удаляем маршруты созданные по умолчанию.
ip route del x.x.x.96/28 dev eth0
ip route del x.x.x.96/28 dev eth1
Пакеты для x.x.x.97 пускаем через eth0, а для x.x.x.96/28 через eth1
ip route add x.x.x.97 dev eth0
ip route add x.x.x.96/28 dev eth1
Включаем Proxy ARP
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
Стоит задача - выпустить свою сеть в инет через два разных интерфейса rl1 и rl2.
Так как адреса в локали серые, то надо поднимать NAT. С учетом того, что динамической маршрутизации
не предвидится, будем поднимать NAT на 2 интерфейса. Для этого нужно:
Скомпилировать ядро с параметрами:
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=20
options IPFIREWALL_FORWARD
options IPDIVERT
options DUMMYNET
options TCP_DROP_SYNFIN
это необходимый минимум. На все случаи жизни )))))
Далее, в rc.local пишем такие строки:
natd -p 8668 -n rl1
natd -p 8669 -n rl2
#natd -p 8671 -n rl3
#natd -p 8672 -n rl4
#natd -p 8673 -n rl5
Последние три строки - если кому надо поднимать NAT на большее количество интерфейсов.
Следующее - правила ipfw:
ipfw -f add divert 8668 all from #твоясеть# to any out via rl1
ipfw -f add divert 8668 all from any to #адрес_rl1# in via rl1
ipfw -f add divert 8669 all from #твоясеть# to any out via rl2
ipfw -f add divert 8669 all from any to #адрес_rl2# in via rl2
Теперь все, что будет выходить через внешние интерфейсы, будет правильно NATиться через них же.
Остается проверить маршрутизацию. Если маска на rl2 /24. В этом случае все просто.
Стандартный шлюз (default gateway) прописан через rl1, а все, что идет на сеть 999.888.0.0/24 будет
автоматически бежать через rl2. Если же на rl2 выделена подсетка из нескольких адресов, то тогда надо
писать жесткий марщрут на всю сеть 999.888.0.0/24 через rl2 на тот шлюз, который тебе дал провайдер N2.
Его тоже можно прописать в rc.local отдельной строкой типа:
route add 999.888.0.0/24 999.888.0.25
У Sergey2005 заработала комбинация:
${fwcmd} add 40 divert 8668 all from #моя сеть# to not #подсеть провайдера "S"# out via rl1
${fwcmd} add 45 divert 8668 all from not #подсеть провайдера "S"# to any in via rl1
${fwcmd} add 50 divert 8669 all from #моя сеть# to #подсеть провайдера "S"# out via rl2
${fwcmd} add 55 divert 8669 all from #подсеть провайдера "S"# to any in via rl2
natd -p 8668 -m -u -n rl1
natd -p 8669 -m -u -n rl2
rl0 -> Первый ифайс во вне, rl1 -> Второй ифайс во вне
rc.conf:
defaultrouter="${rl1_gateway_ip}"
rc.local:
/sbin/natd -n rl0 -p 8660
/sbin/natd -n rl1 -p 8661
rc.firewall:
${fwcmd} add 1100 divert 8660 tcp from ${local_ip} to not ${rl0_ip} 22,25,53,80,110,6667
${fwcmd} add 1110 fwd ${rl0_gateway_ip} tcp from ${rl0_ip} to not ${local_ip}
${fwcmd} add 1120 divert 8660 all from not ${rl0_ip},${local_ip} to ${rl0_ip}
${fwcmd} add 1150 pass all from any to ${rl0_ip}
${fwcmd} add 1150 pass all from ${rl0_ip} to any
${fwcmd} add 1999 divert 8661 all from ${local_ip} to not ${rl1_ip}
${fwcmd} add 2000 divert 8661 all from not ${rl1_ip},${local_ip}
${fwcmd} add 2010 pass all from any to ${local_ip}
${fwcmd} add 2010 pass all from ${local_ip} to any
${fwcmd} add 2100 pass all from any to ${rl1_ip}
${fwcmd} add 2100 pass all from ${rl1_ip} to any
Правила тестировались на FreeBSD 4.7, 4.8, 4.9, 4.10, c ipfw2. Если у вас с ipfw(1) не работает, попробуйте убрать "not ${ip}"
и вместо него вставить "any". "not" нужен для того чтобы локальные адреса не дивертировались, т.к. нам это не нужно.
Порядковые номера могут быть на ваше усмотрение, рекомендую в начале разрешить трафик lo0, защититься от спуфа,
запретить некоторые типы ICMP, разрешить внутренний трафик и т.д., и т.п.
ip rule add from 10.1.10.0/24 to 0/0 table 102 pref 100
ip route add table 102 via 10.1.10.1
ip rule add from 10.1.11.0/24 to 0/0 table 103 pref 100
ip route add table 103 via 10.1.11.45
ipfw add 100 fwd 10.0.0.2 ip from 10.0.2.0/24 to any
Если нужно использовать 2 шлюза, то можно воспользоваться:
ipfw add fwd $ext_gw_ip ip from $ext_net to any out xmit $ext_int
Примеры настройки LEAP, WPA или WPA2 в Linux при помощи wpa_supplicant
(http://hostap.epitest.fi/wpa_supplicant/) В Debian пакет wpasupplicant,
также имеются пакеты с GUI интерфейсом - kwlan и wpagui.
WPA
---
Создаем файл конфигурации, например /etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
eapol_version=1
# ap_scan=2 was the one for me you may try 0 or 1 indstead of 2
ap_scan=2
fast_reauth=1
network={
ssid="SSID сети"
proto=WPA
key_mgmt=WPA-PSK
pairwise=TKIP
group=TKIP
psk="пароль доступа"
}
WPA2-Personal
-------------
Файл конфигурации:
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
network={
ssid="SSID сети"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP
psk="пароль доступа"
}
LEAP
----
Файл конфигурации:
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
eapol_version=1
ap_scan=1
fast_reauth=1
network={
scan_ssid=1
mode=0
ssid="SSID сети"
proto=WPA
key_mgmt=WPA-EAP
pairwise=TKIP
group=TKIP
eap=LEAP
priority=2
auth_alg=LEAP
eapol_flags=0
identity="идентификатор пользователя"
password="Пароль достутпа"
}
"SSID сети", "идентификатор пользователя" и "пароль достутпа" заменяем на полученные от администратора сети данными.
Далее поднимаем wifi интерфейс (Intel Pro Wireless 3945ABG/BG):
ifconfig wlan0 down
iwconfig wlan0 essid "имя сети"
ifconfig wlan0 up
Запускаем wpa_supplicant:
wpa_supplicant -iwlan0 -c /etc/wpa_supplicant.conf -Dwext -dd
Для драйвера ipw2200, интерфейс будет eth1:
wpa_supplicant -d -c /etc/wpa_supplicant.conf -ieth1 -Dwext -dd
Для madwifi - ath0:
wpa_supplicant -d -c /etc/wpa_supplicant.conf -iath0 -Dmadwifi -dd
Посмотреть состояние соедиения можно через wpa_cli или GUI интерфейс wpa_gui.
Для получения IP адреса по DHCP нужно запустить DHCP-клиент:
dhcpcd wlan0
Для настройки соединение двух машин в Ad-Hoc режиме можно использовать примерно такую комбинацию:
modprobe ipw3945
iwconfig eth1 mode Ad-Hoc
iwconfig eth1 essid "testnet"
iwconfig eth1 key restricted
iwconfig eth1 channel 1
ifconfig eth1 192.168.1.1 up
iwconfig eth1 key s:12345
где, testnet имя сети, а 12345 пароль.
После установки Ubuntu 8.04 по умолчанию не работают беспроводные карты на базе чипов Broadcom BCM43xx из-за отсутствия firmware.
Начиная с Linux ядра 2.6.24 работу данных карт в Linux обеспечивает драйвер b43,
в более ранних версиях использовался драйвер bcm43xx.
Для включения работы карты нужно установить пакет b43-fwcutter и получить firmware:
sudo apt-get install b43-fwcutter
и активировать на ноутбуке адаптер.
Также можно воспользоваться меню Menu / System / Administration / Hardware Drivers.
Драйвером b43 поддерживаются чипы:
* bcm4303 (802.11b)
* bcm4306
* bcm4309 (только 2.4GHz)
* bcm4311 rev 1 / bcm4312
* bcm4311 rev 2 / bcm4312 (с 2.6.24 ядром работает через доп. патчи)
* bcm4318
В настоящее время нет поддержки:
* 802.11a для серий 4309 и 4312;
* BCM 4328/4329
* не реализованы возможности представленные в проекте стандарта 802.11n;
Сайт разработчиков драйвера: http://wireless.kernel.org/en/users/Drivers/b43
1. Устанавливаем ndiswrapper:
sudo apt-get install ndiswrapper-common ndiswrapper-utils-1.9
2. Распаковываем куда нибудь Windows драйверы и пишем из под пользователя root такие команды:
ndiswrapper -i bcmwl5.inf
modprobe ndiswrapper
echo "blacklist bcm43xx" >> /etc/modprobe.d/blacklist
echo "ndiswrapper" >> /etc/modules
3. Перегружаемся и проверяем. Все должно работать.
Linux шлюз:
Нужно создать простую одноранговую ad-hoc сеть и дать статический IP-адрес сетевому беспроводному интерфейсу.
После этого делаем NAT и всё работает. Для беспроводного интерфейса eth3 и
сети с идентификатором virens команда выглядит так (от рута):
# iwconfig eth3 mode Ad-Hoc channel 1 essid virens
В /etc/network/interfaces пишем что-то вроде:
auto eth3
iface eth3 inet static
address 10.106.146.1
netmask 255.255.255.0
wireless-mode ad-hoc
wireless-channel 1
wireless-rate auto
wireless-essid virens
Теперь делаем NAT:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING --out-interface eth1 -j MASQUERADE
При этом eth1 это интерфейс, который подключён к Интернету.
Соединение не шифруется.
КПК:
Необходимо задать essid - такой же, какой дали в iwconfig.
Шифрование отсутствует, тип сети - одноранговая ad-hoc.
Снимаем галку "Получать IP-адрес автоматически" и вводим адреса:
IP-адрес: 10.106.146.2
Маска подсети: 255.255.255.0
Маршрутизатор: 10.106.146.1
Скрипт опробован в Debian Etch с установленными пакетами tc, iproute2 и bc.
Задача скрипта равномерное распределения пропускной способности канала среди пользователей
и повышения приоритета dns, ssh, smtp.
SOME_IMPORTANT_IP, SOME_OTHER_IMPORTANT_IP, IMPORTANT_IP - нужно заменить на IP
важного сервера во внутренней сети.
#!/bin/bash
EXT_IFACE="eth0"
INT_IFACE="eth1"
TC="tc"
UNITS="kbit"
LINE="10000" # максимальная фактическая скорость внешнего (ext) линка
LIMIT="5000" # максимально скорость, которую мы можем допустить
# Переменные определеяющие скорость для индивидуальных классов трафика
# для ограничения внутреннего трафика, проходящего через интерфейс eth0;
CLS1_RATE="200" # гарантировано 200kbit
CLS2_RATE="300" # гарантировано 300kbit
CLS3_RATE="4500" # на всех 4500kbit (низкий приоритет)
# Переменные определеяющие скорость для индивидуальных классов трафика
# для ограничения трафика, проходящего через внешний интерфейс eth1;
INT_CLS1_RATE="1000" #Priority
INT_CLS2_RATE="4000" #Bulk
# Чистим содержимое qdiscs
${TC} qdisc del dev ${INT_IFACE} root
${TC} qdisc del dev ${EXT_IFACE} root
# Создаем корневые qdiscs, используя HTB, привязываем к интерфейсу и ставим метку "1:0"
${TC} qdisc add dev ${INT_IFACE} root handle 1:0 htb
${TC} qdisc add dev ${EXT_IFACE} root handle 1:0 htb
# Создаем корневые классы и выставляем максимально-допустимый лимит скорости
# eth1
${TC} class add dev ${INT_IFACE} parent 1:0 classid 1:1 htb rate ${LIMIT}${UNITS} ceil ${LIMIT}${UNITS}
# eth0
${TC} class add dev ${EXT_IFACE} parent 1:0 classid 1:1 htb rate ${LIMIT}${UNITS} ceil ${LIMIT}${UNITS}
# Создаем дочерние классы, маркируем их меткой "1:2", "1:3", в зависимости от лимита, для eth1
${TC} class add dev ${INT_IFACE} parent 1:1 classid 1:2 htb rate ${INT_CLS1_RATE}${UNITS} ceil ${LIMIT}${UNITS}
${TC} class add dev ${INT_IFACE} parent 1:1 classid 1:3 htb rate ${INT_CLS2_RATE}${UNITS} ceil ${INT_CLS2_RATE}${UNITS}
# Привязываем лимит для eth1 (для ограничения исходящего трафика)
# Ставим для класса "1:2" гарантированную скорость 200kbit
# с возможностью подъема при свободности канала до 5000kbit
${TC} class add dev ${EXT_IFACE} parent 1:1 classid 1:2 htb rate ${CLS1_RATE}${UNITS} ceil ${LIMIT}${UNITS}
# Ставим для класса "1:3" гарантированную скорость 300kbit
# с возможностью подъема при свободности канала до 4800kbit (5000kbit - 200kbit зарезервированный для 1:2)
${TC} class add dev ${EXT_IFACE} parent 1:1 classid 1:3 htb rate \
${CLS2_RATE}${UNITS} ceil `echo ${LIMIT}-${CLS1_RATE}|bc`${UNITS}
# Ставим для менее приоритетного класса "1:4" оставшуюся скорость 4500kbit (5000kbit - 200kbit - 300kbit)
${TC} class add dev ${EXT_IFACE} parent 1:1 classid 1:4 htb rate ${CLS3_RATE}${UNITS} \
ceil `echo ${LIMIT}-${CLS1_RATE}-${CLS2_RATE}|bc`${UNITS}
# Добавляем pfifo.
${TC} qdisc add dev ${INT_IFACE} parent 1:2 handle 12: pfifo limit 10
${TC} qdisc add dev ${INT_IFACE} parent 1:3 handle 13: pfifo limit 10
${TC} qdisc add dev ${EXT_IFACE} parent 1:2 handle 12: pfifo limit 10
${TC} qdisc add dev ${EXT_IFACE} parent 1:3 handle 13: pfifo limit 10
${TC} qdisc add dev ${EXT_IFACE} parent 1:4 handle 14: pfifo limit 10
### С классами закончили, создаем правила для адресов в сети
# INT_IFACE, настраиваем скорость.
# под dst подразумевается трафик уходящий во внутренний интерфейс eth0, т.е. к локальному IP
# и определяем скорость загрузки с этих адресов.
# адрес SOME_IMPORTANT_IP привязываем к классу 1:2
${TC} filter add dev ${INT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip dst SOME_IMPORTANT_IP/32 flowid 1:2
${TC} filter add dev ${INT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip dst SOME_OTHER_IMPORTANT_IP/32 flowid 1:2
# Все остальные адреса привязываем к классу 1:3 и считаем неприоритетными
${TC} filter add dev ${INT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip dst 0.0.0.0/0 flowid 1:3
# EXT_IFACE
# Устанавливаем повышенный приоритет для DNS запросов
${TC} filter add dev ${EXT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip src IMPORTANT_IP/32 match ip sport 53 0xffff flowid 1:2
# SSH тоже считаем приоритетным
${TC} filter add dev ${EXT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip src IMPORTANT_IP/32 match ip sport 22 0xffff flowid 1:2
# SMTP отдаем остатки полосы, но приоритет по сравнению с остальным трафиком поднимаем
${TC} filter add dev ${EXT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip src IMPORTANT_IP/32 match ip sport 25 0xffff flowid 1:3
# Все остальное - в последнюю очередь, самый низкий приоритет
${TC} filter add dev ${EXT_IFACE} parent 1:0 protocol ip prio 1 u32 match ip src 0.0.0.0/0 flowid 1:4
> Работает шейпер на dummynet, наблюдается некотороая потеря
> траффика. Hавскидку проблема в дефолтных значениях размера очереди (50 пакетов)
> для pipe'ов от 32 до 512 Кбит\с. Скорее всего, поток не влезает в очередь и
> часть пакетов отбрасывается. Как правильно рассчитать размер очереди для
> каждого pipe в отдельности?
Eugene Grosbein:
Pipe и должен отбрасывать пакеты, иначе какой же это шейпер?
Ты не можешь увеличивать длину очереди бесконечно, потому что задержки
вырастут настолько, что соединение начнет рвать сам юзер :-)
Hа таких низких скоростях размер очереди надо бы, наоборот, уменьшать,
чтобы не допустить гигантских задержек типа нескольких тысяч милисекунд.
А если хочешь и рыбку съесть, и потерь иметь минимум, то читай-ка ты
про RED/GRED на unixfaq.ru и делай не просто pipe, а queue/pipe с gred.
Рекомендую делать w_q=0.002, max_p=0.1, min=q/10, max=3*min,
где q - длина очереди, q=20 для скоростей меньше 100Kbit/s,
q=30 для скоростей от 100 до 300Kbit/s и q=50 для скоростей 512Kbit/s и выше.
----------
Sergey A Yakovets:
Пол-дня игрался с параметром queue. В итоге подобрал на первый взгляд
кое-что подходящее. Алгоритм\мысли были следующие:
Дано: асинхронный спутниковый Инет. Входящий канал - 1024 Кбит\с.
Опытным путем установлено, что проблемы с потерей траффика (до 10% от
общего объема) возникают при многопотоковых http\ftp закачках, т.к. спутниковый
провайдер в этом случае может отдать поток на все 1024 Кбит\с. При серфинге все
нормально. Исходя из этого, мною были сделаны некоторые расчеты:
При максимальной пропускной способности входящего спутникового канала
в 1024 Кбит\с и размере пакета в 1500 байт, пропускная способность канала
равна ~ 87 пакетов\сек. В это же время, для канала в 128 Кбит\с пропускная
способность равна ~ 11 пакетов\сек. Гипотетическая разница, при условии что на
юзера будет идти поток в 1024 Кбит\с, а отдаваться только 128 Кбит\с, может
составить 76 пакетов\сек.
Итого, опытным путем установлено:
- (было) при дефолтной очереди в 50 пакетов на pipe 128 Кбит\с потери 10%
- при размере очереди = разница*2 = 150 пакетов потери 2%
- (стало) при размере очереди = разница*3 = 230 пакетов потери 0%
Серфинг не страдает, задержек нет. Закачка идет на скорости шейпера, потерь нет.
Пробовал другой вариант.
Hа pipe 128 Кбит\с было выставлено gred 0.002/3/6/0.1 В итоге - огромные
потери, т.к. канал практически все время работал на скорости пакетов намного
больше чем max_th*2. Изменение параметров до gred 0.002/50/150/0.1 не влияло на
результат, т.к. дефолтный размер очереди в 50 пакетов часто переполнялся и gred
не имел никакого действия.
---------
Что такое алгоритмы RED и gentle RED у ipfw?
http://unixfaq.ru/index.pl?req=qs&id=310
Ответ на этот вопрос скомпилирован из статей в конференции RU.UNIX.BSD от следующих авторов:
Valentin Ermolaev, Alexander V. Naumochkin, Jen Linkova.
Сокращение RED означает "Random Early Detection". Метод используется для выравнивания всплесков трафика.
Основным критерием метода является так называемая перегрузка.
В качестве показателя перегрузки avg используется вычисляемое среднее значение длины очереди пакетов,
принадлежащей к определенной сессии TCP. Использование усредненного,
а не мгновенного значения очереди позволяет отделить кратковременные перегрузки,
которые могут быть нормально обработаны устройством и сетью, от длительных перегрузок,
которые могут утопить сеть.
Алгоритмически это выглядит так:
В момент прихода пакета
; ; if (очередь не пуста)
; ; ; ; avg = (1 - w_q)*avg + w_q*q
; ; else
; ; ; ; m = f(time - q_time)
; ; ; ; avg = (1 - w_q)^m * avg;
где
avg -средний размер очереди
q_time - "start of queue idle time"
q - размер очереди
w_q - вес очереди (фиксированный параметр)
f() - линейная функий от времени
В /usr/src/sys/netinet/ip_dummynet.c по этому поводу написано следующее:
* RED algorithm
*
* RED calculates the average queue size (avg) using a low-pass filter
* with an exponential weighted (w_q) moving average:
* avg <- (1-w_q) * avg + w_q * q_size
* where q_size is the queue length (measured in bytes or * packets).
*
* If q_size == 0, we compute the idle time for the link, and set
* avg = (1 - w_q)^(idle/s)
* where s is the time needed for transmitting a medium-sized packet.
- что полностью согласуется с приведенными выше формулами.
Далее в алгоритме вводятся два порога уровня перегрузки: min_th и max_th.
Когда уровень перегрузки ниже первого порога min_th, то пакеты не отбрасываются.
Если уровень перегрузки находится между двумя порогами, пакеты отбрасываются с линейно
возврастающей вероятностью из диапазона от 0 до конфигурируемой величины max_p,
которая достигается при достижении второго порога max_th. Выше порога max_th
отбрасываются все пакеты.
Такой метод вычисления позволяет сглаживать всплески трафика - для сравнения в первой из статей (см. ниже)
на одном графике приводятся и изменение размера очереди q, и усредненного размера
очереди (avg) от времени. В той же статье есть выкладки на тему значений w_q.
При gentle RED ситуация выглядит чуть сложнее:
Если перегрузки лежит в интервале от min_th до max_th, то пакеты отбрасываются с линейно
возрастающей от 0 до max_p вероятностью. Когда перегрузка превышает max_th,
но не превышет 2*max_th, пакеты отбрасываются не все (как в случае RED), а с линейно возрастающей
от max_p до 1 вероятностью. Все пакеты отбрасываются только после превышения перегрузки канала значения 2*max_th.
Вот как это сделано в ip_dummynet.c:
если длина очереди > max_th, то в случае gred вероятность
отбрасывания пакета вычисляется как
; ; p_b = c_3 * avg - c_4
где c_3 = (1 - max_p) / max_th
; ; c_4 = 1 - 2 * max_p
В случае просто RED пакет отбрасывается.
При загрузке очереди, большей min_th, но меньшей max_th, функция
вероятности одинакова и выглядит след. образом:
; ; p_b = c_1 *avg - c_2
где c_1 = max_p / (max_th - min_th),
; ; c_2 = max_p * min_th / (max_th - min_th)
Полезные ссылки:
1. http://www.icir.org/floyd/papers/red/red.html
2. http://www.icir.org/floyd/red.html
3. http://www.cisco.com/warp/public/732/Tech/red/
Ограничение входящей и исходящей скорости (shaping) для клиентов на ppp интерфейсах.
#!/bin/bash
DEVICE=ppp9 UP=512 DOWN=512
/sbin/tc qdisc del dev $DEVICE root
/sbin/tc qdisc add dev $DEVICE root tbf rate ${DOWN}Kbit latency 50ms burst $[$DOWN*1024]
/sbin/tc qdisc del dev $DEVICE handle ffff: ingress
/sbin/tc qdisc add dev $DEVICE handle ffff: ingress
/sbin/tc filter add dev $DEVICE parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 \
police rate ${UP}Kbit burst $[$DOWN*1024] drop flowid :1
Сделать MARK, и загнать все такие трансферы в какой-либо класс шейпера.
Т.е. если например помеченные пакеты - все их отнести к классу 1:51 где скорость ограничена от 32К до 64К:
tc filter add dev eth1 parent 1:0 protocol ip prio 100 handle 51 fw classid 1:51
tc class add dev eth1 parent 1:2 classid 1:51 htb rate 32Kbit ceil 64Kbit
tc qdisc add dev eth1 parent 1:51 handle 51 sfq perturb 10
Собираем ядро с опциями:
options DUMMYNET
options IPFIREWALL
Ограничиваем трафик для сеток 1.1.1.0/24 и 3.3.3.0/24 на 14000 кбит/с:
ipfw add pipe 50 tcp from any to 1.1.1.0/24 via fxp0
ipfw add pipe 50 tcp from any to 3.3.3.0/24 via fxp0
ipfw pipe 50 config bw 14Kbit/s
Для внесения задержки на N ms, используйте delay N после config.
Для установки веса данного пайпа по отношению к другим пайпам используйте weight вес.
Для WF2Q ограничения трафика используйте ipfw queue
(queue N config [pipe pipe_nr] [weight weight] [queue {slots | size})
PS (комментарий от gara@mail.ru):
Если возникает необходимость организовать "канал" для каждого пользователя из данной сети то пишем:
ipfw pipe 10 config mask dst-ip 0x000000ff bw 1024bit/s queue
ipfw add pipe 10 tcp from any to 1.1.1.0/24 via fxp0
Теперь каждый хост из сети 1.1.1.0/24 имеет свой канал 1024bit/s
Запретим более 30 коннектов для 80 порта сервера 1.2.3.4.
ipfw add allow tcp from any to 1.2.3.4 80 limit src-addr 30
ipfw add allow tcp from any to 1.2.3.4 80 via fxp0 setup limit src-addr 10
Вместо src-addr можно использовать src-port, dst-addr, dst-port
Конструкция работает в последних версиях FreeBSD 4.x ветки.
Некоторые сетевые операторы, например Comcast, используют ПО Sandvine для нарушения работы BitTorrent.
Принцип действия Sandvine в отправке клиенту поддельных RST пакетов, приводящих к прерыванию соединения.
Простейший способ борьбы с подобной практикой блокирования - запретить прием пакетов с RST флагом:
iptables -A INPUT -p tcp --dport 6883 --tcp-flags RST RST -j DROP
где, 6883 - номер BitTorrent порта.
Пример скрипта, оставляющего возможность входящих соединений только для BitTorrent:
#!/bin/sh
# Номер порта BitTorrent
BT_PORT=6883
# Сброс настроек iptables
iptables -F
# Разрешаем трафик на loopback интерфейсе
iptables -A INPUT -i lo -j ACCEPT
# Молча отбрасываем RST пакеты
iptables -A INPUT -p tcp --dport $BT_PORT --tcp-flags RST RST -j DROP
# Пропускаем уже установленные входящие соединения
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешаем прием соединений для BitTorrent
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport $BT_PORT -j ACCEPT
iptables -A INPUT -m state --state NEW -m udp -p udp --dport $BT_PORT -j ACCEPT
# Все остальные входящие соединения блокируем
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited
Модуль ost был написан для использования в iptables правилах результатов пассивного определения
типа операционной системы, из которой был отправлен TCP SYN пакет.
Загружаем исходные тексты модуля или ставим из patch-o-matic:
wget http://tservice.net.ru/~s0mbre/archive/osf/osf-2008_06_14.tar.gz
В Makefile через переменную IPTABLES указываем путь к заголовочным файлам iptables (iptables.h и libiptc/).
Собираем модуль ipt_osf.ko:
make
Собираем библиотеку libipt_osf.so, после чего копируем ее в /lib/iptables или /lib64/iptables:
make lib
Собираем утилиты для загрузки сигнатур ОС и ведения лога (load, osfd, ucon_osf):
make bin
Загружаем список сигнатур:
wget http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os
Загружаем модуль ядра:
insmod ./ipt_osf.ko
Загружаем сигнатуры:
./load ./pf.os /proc/sys/net/ipv4/osf
Пример правила для принятия пакетов с Linux машин, с занесением всех остальных в лог:
iptables -I INPUT -j ACCEPT -p tcp -m osf --genre Linux --log 0 --ttl 2
При отправке с Windows в логе появится:
ipt_osf: Windows [2000:SP3:Windows XP Pro SP1, 2000 SP3]: 11.22.33.55:4024 -> 11.22.33.44:139
Описание опций можно найти здесь:
http://tservice.net.ru/~s0mbre/old/?section=projects&item=osf
Если ядро ругается "kernel: ip_conntrack: table full, dropping packet.", причину флуда
(скорее всего вирус или сканирование портов) можно найти по списку /proc/net/ip_conntrack
Если просто общая загрузка большая, увеличить размер таблицы можно через /proc/sys/net/ipv4/ip_conntrack_max
Также можно увеличить размерность хэша через параметр hashsize модуля ip_conntrack:
/etc/modules.conf:
options ip_conntrack hashsize=N
Более тонкий тюнинг можно произвести через переменные определенные в /proc/sys/net/ipv4/netfilter
Linux:
- Перед правилом блокировки нужно вставить "log" правило:
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 \
-j LOG --log-level debug --log-prefix "outgoing mail"
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 -j DROP
- Проверить запущены ли в системе klogd и syslogd.
- Настроить /etc/syslog.conf на прием kern.debug логов:
kern.=debug -/var/log/kernel/info
FreeBSD:
Добавить ключ log в ipfw, например:
ipfw add 1000 deny log tcp from any to 192.168.10.10 22 via fxp0
ipfw add 1000 deny log logamount 0 tcp from any to 192.168.10.10 80 via fxp0
Для ведения логов ядро должно быть собрано с IPFIREWALL_VERBOSE или нужно выставить "sysctl -w net.inet.ip.fw.verbose=1".
Далее проверить чтобы в /etc/syslog.conf было упоминание LOG_SECURITY:
security.* /var/log/security
Через параметр logamount передается число записей которые будет записано в лог,
после превышения записи перестанут появляться в логе, до тех пор пока не будет вызвана команда
"ipfw resetlog". Максимальное число сообщений можно также установить
через sysctl net.inet.ip.fw.verbose_limit.
Для отмены лимитирования на число записей, нужно установить атрибут в 0.
Часто недовольные пользователи приходят и просят дать им распечатку логов доступа в интернет.
Отчасти это позволяет сделать squid, но только при прозрачном проксировании, да и то логи только по http-протоколу.
На помощь приходит iptables и syslog.
Настраиваем в syslog.conf добавление сообщений от ядра уровня debug (или уровня, который вам удобнее)
в отдельный файл. Лучше всего хранить эти логи на отдельном разделе (их размер огромен!
но проблему решает gzip - сжимает логи более чем в 10 раз).
В моём syslog.conf была добавлена строка:
kern.=debug -/var/log/access/access
Желательно, что бы в уровень debug сообщений от ядра не поступало никакой другой информации,
кроме информации от iptables. У меня так и получилось по умолчанию с уровнем debug.
В rc.firewall было добавлено в самое начало:
#LOG ALL (!!!). Beware!!!
#FORWARD
iptables -A FORWARD -m state --state NEW -j LOG --log-level debug \
--log-prefix 'FRWLL_FWD_NEW ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state ESTABLISHED -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_ESTBLSHD ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state RELATED -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_RLTD ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state INVALID -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_INVLD ' # --log-tcp-options --log-ip-options
#INPUT
iptables -A INPUT -m state --state NEW -j LOG --log-level debug \
--log-prefix 'FRWLL_INPT_NEW ' # --log-tcp-options --log-ip-options
#iptables -A INPUT -m state --state ESTABLISHED -j LOG --log-level debug \
# --log-prefix 'FRWLL_INPT_ESTBLSHD ' # --log-tcp-options --log-ip-options
#iptables -A INPUT -m state --state RELATED -j LOG --log-level debug \
# --log-prefix 'FRWLL_INPT_RLTD ' # --log-tcp-options --log-ip-options
iptables -A INPUT -m state --state INVALID -j LOG --log-level debug \
--log-prefix 'FRWLL_INPT_INVLD ' # --log-tcp-options --log-ip-options
Если раскомментировать все строки, то получиться лог с полной статистикой доступа - он будет очень большим.
Поэтому в данном примере имеем лог только по установкам соединений и ошибочным соединениям в цепочках INPUT и FORWARD.
Итак. В logrotate я добавил (/etc/logrotate.d/access):
/var/log/access/access {
sharedscripts
compress
rotate 45
daily
postrotate
/bin/killall -HUP syslogd
endscript
}
Сжимаем логи каждый день. Храним статистику за последние 45 суток.
Компрессия логов в моём случае дала значительный прирост производительности, поскольку шлюз
достаточно мощный и скорость парсинга логов упиралась только в чтение с HDD.
В итоге был написан простой скрипт на perl, выдающий статистику в более-менее удобоваримой форме.
Вот и сам скрипт:
-------------------------
#!/usr/bin/perl
use CGI qw(:standard);
use PerlIO::gzip;
use Switch;
##Redefine before start:
my $LOG_DIR="/var/log/access/";
my $LOG_FILENAME="access";
##end
my $IP, $FLAG;
## Params delimeter in request: "-"
($IP, $FLAG) = split(/-/, $ARGV[0]);
## if undefine IP or file log FLAG-number or FLAG is empty - parser exit:
if(!defined($IP)||!defined($FLAG)||$FLAG==""){
print header; print start_html;
print "Valid parameters required!"; print end_html; exit(1);
}
print header;
print start_html("Stat for: $IP");
print "<h2>Stat for: $IP</h2><br/>", "\n<pre>";
switch($FLAG)
{
case "0"
{
open($FD, "<$LOG_DIR$LOG_FILENAME")
or die "Cannot open current (0) log-file!<br> File does not exist or access not permitted!<br>";
while(<$FD>)
{
chomp;
s/gw kernel://g;
if(grep(/$IP/, $_))
{
print $_, "<br>\n";
}
}
close($FD);
}
else
{
open($GZIP, "<:gzip(lazy)", "$LOG_DIR$LOG_FILENAME.$FLAG.gz")
or die "Cannot open old (", $FLAG, ") log-file!<br> File does not exist or access not permitted!<br>";
while(<$GZIP>)
{
chomp;
s/gw kernel://g;
if(grep(/$IP/, $_))
{
print $_, "<br>\n";
}
}
close($GZIP);
}
}
print "</pre>\n";
print "<br><br>Access stat parser by \"umask at yandex dot ru\"<br>";
print end_html;
-------------------------
Для работы скрипта необходимо установить модуль PerlIO-gzip. Найти ссылку на модуль можно на cpan.org.
Доступ к статистике можно получить через браузер (скрипт рассчитан для работы как CGI):
hostname.ru/cgi-bin/parse.pl?192.168.1.1-0
Аргумент понимаеться так:
192.168.1.1 - искомая подстрока.
0 - норме лог файла. В данном случае текущий (в который пока ещё записываются сообщения syslog).
1 - вчерашний,
2 - позавчерашний,
3 - 3 дня назад.
.....
и т.д.
Для меня данное решение оказалось удобным.
На разных машинах в моей локальной сети накопилась куча программ,
которым нужен был выход в интернет напрямую. У каждой свой набор портов.
Захотелось на входе иметь минимальную конфигурацию, описывающую
ресурсы, а на выходе набор разрешающих правил для iptables.
В основном были клиент-банки - поэтому и такая терминология в программе.
А так вместо банка можно указывать любой ресурс в формате определенном в
man iptables.
Ограничения, недостатки:
1. использование количества портов для одного ресурса менее 16
2. нельзя указать диапазон портов через двоеточие как в iptables
Оба легко устаняются: первое - есть пример в самом скрипте,
второе через использование другого разделителя для записей на входе,
проверку наличия ":" - использование другого формата вызова iptables. Мне это не нужно и код не хотел раздувать.
#!/bin/bash
#bkv 2005.10
#Дано:
# Два списка:
# Первый список из записей вида - банк:порты(через запятую)
# Второй список из записей вида - клиент:банки(через запятую)
#Найти:
# Набор разрешающих правил iptables для forward
#Примечания:
# политика FORWARD по умолчанию - "запрещено все, что не разрешенно"
# iptables поддерживает одновременное указание не более 15 портов
#Решение:
# Создадим отдельную цепочку, например, - CLIENTBANK
# Сгенерируем необходимые правила и поместим их в цепочку CLIENTBANK
# Обращения по всем портам из первого списка направим на обработку в CLIENTBANK
# Перед выполнением все правила связаные с цепочкой CLIENTBANK удалим, чтобы не плодить
# правила от многократного запуска
itls="/sbin/iptables"
#Подаем список на обработку awk
#признак первого списка - первое поле BankPorts
#признак второго списка - первое поле ClientBanks
echo -e "\
BankPorts:smtp.mail.ru:25\n\
BankPorts:10.24.70.0/26:22,23\n\
BankPorts:pop.mail.ru:110\n\
BankPorts:bank4.ru:9999,888\n\
BankPorts:bank5.ru:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15\n\
BankPorts:bank6.ru:21,22,23,24,25,26,27,28,29,210,211,212,213,214,215\n\
ClientBanks:192.168.9.0/16:smtp.mail.ru,pop.mail.ru,10.24.70.0/26\n\
ClientBanks:192.168.9.8:bank4.ru,bank5.ru,bank6.ru\n\
ClientBanks:192.168.9.6:bank6.ru,bank4.ru\n\
"|\
awk -v itls=$itls -F: '{
if($0~/^BankPorts/) BankPorts[$2]=$3 #создаем ассоциативный массив - индекс:банк, значение:порты через запятую
if($0~/^ClientBanks/) ClientBanks[$2]=$3 #аналогично клиент -> банки
}END{
#Cгенерируем _необходимые_ правила для цепочки CLIENTBANK
for (client in ClientBanks){
split(ClientBanks[client],bank_arr,",") #поместили в массив bank_arr адреса банков для клиента
for(i in bank_arr){
all_ports=all_ports","BankPorts[bank_arr[i]] #создаем список всех портов для дальнейшего использования
count_ports=split(BankPorts[bank_arr[i]],tmp_arr,",")
if(count_ports > 15)
print "echo Слишком много портов для "bank_arr[i]".Допиши программу.Выход&&exit 1"
else
printf("%s -A CLIENTBANK -s %s -d %s -p tcp -m multiport --dports %s -j ACCEPT\n",itls,client,bank_arr[i],BankPorts[bank_arr[i]])
}
}
#Создадим правила перенаправляющие из FORWARD на обработку в CLIENTBANK, помня про ограничение в 15 портов
sub(",","",all_ports) #отрезаем первую запятую у списка всех использующихся портов
split(all_ports,all_ports_arr,",")#поместили в массив all_ports_arr все порты какие есть
j=1;i=1
while(all_ports_arr[i]){
while(i<=(j*15)){
if (all_ports_arr[i])
tmp_all_ports=tmp_all_ports","all_ports_arr[i]
i++
}
sub(",","",tmp_all_ports) #отрезаем первую запятую
printf("%s -I FORWARD -p tcp -m multiport --ports %s -j CLIENTBANK\n",itls,tmp_all_ports)
tmp_all_ports=""
j++
}
print itls" -A CLIENTBANK -p tcp -m state --state ESTABLISHED -j ACCEPT"
print itls" -N CLIENTBANK"
print itls" -X CLIENTBANK"
print itls" -F CLIENTBANK"
#Удаляем из FORWARD все цепочки содержащие цель CLIENTBANK
del_rules_nums="'`$itls --line-numbers -L FORWARD -n|grep CLIENTBANK|cut -f1 -d" "|tr "\n" ","`'"
split(del_rules_nums,del_rules_arr,",")
cnt_rules=1
while(del_rules_arr[cnt_rules]){
printf("%s -D FORWARD %s\n",itls,del_rules_arr[cnt_rules])
cnt_rules++
}
}'|tac > gen.itls.sh
chmod 700 gen.itls.sh
echo "Команды сгенерированы в файл ./gen.itls.sh .Выход."
exit
./gen.itls.sh
rm ./gen.itls.sh
Сделать MARK, и загнать все такие трансферы в какой-либо класс шейпера.
Т.е. если например помеченные пакеты - все их отнести к классу 1:51 где скорость ограничена от 32К до 64К:
tc filter add dev eth1 parent 1:0 protocol ip prio 100 handle 51 fw classid 1:51
tc class add dev eth1 parent 1:2 classid 1:51 htb rate 32Kbit ceil 64Kbit
tc qdisc add dev eth1 parent 1:51 handle 51 sfq perturb 10
- Собираем поддержку connbytes в patch-o-matic.
- Добавляем правило в firewall, например:
iptables -A FORWARD --connbytes 100000 -j REJECT
- теперь все TCP сессии более 100 Кбайт будут "обрезаны", необходимо добавить
исключения для протоколов типа ssh, обычные "долгоживущие" чаты и т.п.
- собираем поддержку "string" в patch-o-matic.
- смотрим на протокол Kazaa, в заголовках содержится:
HTTP/1.0 503 Service Unavailable.Retry-After: 3..X-Kazaa-Username: BlazeTre
- добавляем в firewall строчку - iptables -A FORWARD -m string --string "X-Kazaa-" -j REJECT
# Максимум 10 одновременных соединений к 80 порту с одного IP
iptables -A INPUT-p tcp --dport 80 -m iplimit --iplimit-above 10 -j REJECT
# Блокируем на стадии SYN
iptables -I INPUT -p tcp --syn --dport 80 -j DROP -m iplimit --iplimit-above 10
# 20 соединений на сеть класса С
iptables -p tcp --dport 80 -m iplimit --iplimit-above 20 --iplimit-mask 24 -j REJECT
Фильтрация по MAC (mac):
--mac-source [!] XX:XX:XX:XX:XX:XX (! - "не" маска.)
Запись номеров портов (multiport):
--source-port [port[,port]]
--destination-port [port[,port]]
--port [port[,port]] (source или destination)
Установка и проверка маркера пакет (mark):
--set-mark mark
--mark value
Выборка пакетов посланных/полученных пользователем (owner):
--uid-owner userid
--gid-owner groupid
--pid-owner processid
Установка/проверка типа сервиса (TOS/tos):
--set-tos tos
--tos tos
Определение log-level для syslog (LOG):
--log-level level
Установка реального IP для работы NAT (SNAT, цепочка POSTROUTING):
--to-source <ipaddr>[-<ipaddr>][:port-port]
Изменение/проверка TTL - time to live (TTL/ttl):
--ttl-set ttl
--ttl-dec N - уменьшение на N
--ttl-dec N - увеличение на N
--ttl ttl - проверка
Для FreeBSD:
ipfw add count tcp from any to not 192.168.1.0/24 uid 231
uid user (или gid group) - под правило попадают все TCP или UDP пакеты посланный
или принятые пользователем user (группой group).
В Linux в ядрах 2.4.x в iptables можно использовать модуль owner.
Список IP адресов или подсетей находится в файле /etc/block1.txt
Например:
10.10.1.1
10.10.1.2
192.168.0.0/16
IPFW
----
Блок чтения IP в таблицу, проверка в которой будет осуществляться
не через последовательный перебор правил, а через выборки из хэша:
ipfw table 1 flush
cat /etc/block1.txt | while read ip; do
# echo ipfw table 1 add $ip 1
ipfw table 1 add $ip 1
done
Привязка таблицы к правилу блокировки:
ipfw add 100 deny ip from "table(1)" to any via em1
Просмотр содержимого таблицы:
ipfw table 1 list
PF
--
/etc/pf.conf
table <blockedips> persist file "/etc/block1.txt"
ext_if="em1"
block drop in log (all) quick on $ext_if from <blockedips> to any
Проверка корректности правил PF:
pfctl -nf /etc/pf.conf
Чтение правил PF:
pfctl -f /etc/pf.conf
Добавление и удаление адресов из таблицы на лету:
pfctl -t blockedips -T add 192.168.1.1
pfctl -t blockedips -T delete 192.168.1.1
Просмотр содержимого таблицы и более подробной статистики по каждому адресу:
pfctl -t blockedips -T show
pfctl -t blockedips -T show -v
Просмотр лога срабатываний блокировок, умолчанию сохраняемого в /var/log/pflog:
tcpdump -n -e -ttt -r /var/log/pflog
tcpdump -n -e -ttt -r /var/log/pflog port 80
tcpdump -n -e -ttt -r /var/log/pflog and host 192.168.1.1
Срабатывание блокировок в режиме реального времени:
tcpdump -n -e -ttt -i pflog0
tcpdump -n -e -ttt -i pflog0 port 80
tcpdump -n -e -ttt -i pflog0 host 192.168.1.1
В конфигурацию ядра добавляем:
options IPFIREWALL #firewall
options IPFIREWALL_VERBOSE #enable logging to syslogd(8)
options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default
options IPDIVERT
options IPFIREWALL_FORWARD
options DUMMYNET
options IPFIREWALL_NAT #ipfw kernel nat support
options LIBALIAS
в /etc/make.conf:
CFLAGS+= -DIPFIREWALL_NAT
Далее пересобираем систему:
cd /usr/src/ ; make builworld && make kernel KERNCONF=YourKern && make installworld
reboot
В конфигурационном файле ipfw:
NatIP="111.111.111.111"
ipfw nat 123 config ip ${NatIP} log
ipfw add 10 nat 123 ip from 192.168.0.0/16 to any
ipfw add 20 nat 123 ip from any to ${NatIP}
Наслаждаемся достоинствами kernel nat
Пример структурирования правил фильтра пакетов ipfw во FreeBSD
с целью упрощения их восприятия и уменьшения вероятности допущения ошибок.
Исторически так сложилось, что правила файрвола в rc.firewall написаны в плохом и труднопонимаемом стиле:
входящие и исходящие пакеты проходят один и тот же набор правил.
Многие используют этот скрипт как образец для написания собственного набора правил и
наступают на одни и те же грабли. Как минимум, с натом. На самом деле ipfw очень удобен,
если писать список правил как некую программу - с разбиением на мелкие подпрограммы (блоки)
и добавлением комментариев. При этом надо руководствоваться рядом
соглашений:
1. Весь трафик первым делом делится на входящий и исходящий.
Каждый вид трафика обрабатывается в отдельном блоке.
В качестве еще одного блока можно выделить трафик через интерфейс lo0.
Слова in и out после первоначального разделения трафика не
используются.
2. Входящий трафик делится на а) трафик, адресованный данному серверу;
б) броадкасты; в) мультикасты; г) трафик, идущий транзитом. Каждый из видов трафика
обрабатывается в отдельном блоке. Слово me после разделения трафика не используется.
3. Ветвление на блоки происходит по ip-адресам. Имена интерфейсов используются по возможности
как можно реже и только тогда, когда без них не обойтись. В частности, при написании
правил антиспуфинга. При использовании имен интерфейсов крайне не
рекомендуется
использовать слово via. В зависимости от блока (входящий или исходящий трафик) рекомендуется
использовать слова xmit или recv. Это повышает читабельность.
4. Все строки с правилами нумеруются (там где это допустимо).
Нумерация строго возрастающая. Рекомендуемый шаг между соседними номерами 100.
5. Блок занимает строго фиксированный диапазон номеров строк ipfw.
Номер строки, с которой начинается блок, указывается в комментарии в начале этого блока.
Переход на блок происходит только на его начало. Переход в середину блока недопустим.
6. Блок всегда заканчивается строкой allow ip from any to any или deny ip from any to any.
Исключение составляет ситуация, когда один блок должен выполняться следом за другим.
Даже если блок пустой (например, броадкасты или мультикасты не используются),
все равно лучше поместить в него это единственное правило, чем удалять блок целиком.
Возможно в будущем туда что-нибудь допишется.
Пример я как-то уже приводил несколько лет назад.
Приведу еще раз для трех разных серверов. Макросы, начинающиеся с %, заменятся на блоки ip-адресов.
На всех серверах дефолтное 65535 правило: allow ip from any to any.
Правила на центральном роутере/шлюзе в инет:
#!/bin/sh -e
fwcmd="echo"
# Интерфейсы, подключенные к Интернету
xmit_iface_inet="{ xmit fxp1 or xmit fxp2 }"
recv_iface_inet="{ recv fxp1 or recv fxp2 }"
# Ограничение количества ping-пакетов, уходящих на аплинка
$fwcmd pipe 10 config bw 5Kbit/s
######################################################################
## Разделение трафика в зависимости от направления (нумерация с 100)
######################################################################
# Трафик через интерфейс lo0
$fwcmd add 100 allow ip from any to any via lo0
# Исходящий трафик
$fwcmd add 200 skipto 30000 ip from any to any out
######################################################################
## Входящий трафик (нумерация с 500)
######################################################################
# Съем трафика для статистики
$fwcmd add 500 divert 18000 ip from any to any $recv_iface_inet
# NAT-трансляция входящих пакетов
$fwcmd add 700 divert 8668 ip from any to %ip.nat $recv_iface_inet
##-----------------------------------------------------------------------------
## Антиспуфинг (нумерация с 1000)
##-----------------------------------------------------------------------------
# Интерфейсы Интернета
$fwcmd add 1000 deny log ip from %global.internal to any $recv_iface_inet
##-----------------------------------------------------------------------------
## Разделение трафика в зависимости от получателя пакета (нумерация с 5000)
##-----------------------------------------------------------------------------
# Трафик, адресованный серверу
$fwcmd add 5000 skipto 10000 ip from any to me
# Броадкасты
$fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255
# Мультикасты
$fwcmd add 5200 skipto 25000 ip from any to 224.0.0.0/4
##-----------------------------------------------------------------------------
## Трафик, идущий транзитом (нумерация с 6000)
##-----------------------------------------------------------------------------
# Запрещаем трафик на закрытые адреса магистрали
$fwcmd add 6000 deny log ip from any to %global.backbone.private
# Разрешаем остальной трафик
$fwcmd add 6300 allow ip from any to any
##-----------------------------------------------------------------------------
## Трафик, адресованный серверу (нумерация с 10000)
##-----------------------------------------------------------------------------
# Разрешаем установленные TCP-соединения
$fwcmd add 10000 allow tcp from any to any established
# Разрешаем фрагменты IP-пакетов
$fwcmd add 10100 allow ip from any to any frag
# Разрешаем пакеты, удовлетворяющие динамическим правилам
$fwcmd add 10200 check-state
# Разрешаем OSPF-пакеты
$fwcmd add 10300 allow ospf from %global.backbone to any
# Разрешаем GRE-пакеты
$fwcmd add 10400 allow gre from any to any
##-----------------------------------------------------------------------------
## Службы сервера (нумерация с 12000)
##-----------------------------------------------------------------------------
# SSH
$fwcmd add 12000 deny tcp from %deny.ssh to %ip.ssh 22
$fwcmd add 12100 allow tcp from %allow.ssh to %ip.ssh 22
# BGP
$fwcmd add 12200 deny tcp from %deny.bgp to %ip.bgp 179
$fwcmd add 12300 allow tcp from %allow.bgp to %ip.bgp 179
# SNMP
$fwcmd add 12400 allow udp from %allow.snmp to %ip.snmp 161,1161
##-----------------------------------------------------------------------------
## Завершающие правила для трафика, адресованного серверу (нумерация с 18000)
##-----------------------------------------------------------------------------
# Разрешаем ICMP-пакеты
$fwcmd add 18000 allow icmp from any to any
# Разрешаем работу traceroute
$fwcmd add 18100 unreach port udp from any to any 33434-33584
# Запрещаем соединения на 113 порт (ident)
$fwcmd add 18200 reset tcp from any to any 113
# Запрещаем соединения на 1080 порт (socks check)
$fwcmd add 18300 reset tcp from any to any 1080
# Запрещаем остальной трафик
$fwcmd add 18400 deny log ip from any to any
##-----------------------------------------------------------------------------
## Броадкасты (нумерация с 20000)
##-----------------------------------------------------------------------------
# Разрешаем SNMP trap'ы от ИБП
$fwcmd add 20000 allow udp from %global.backbone to any 162
# Разрешаем NTP-пакеты
$fwcmd add 20100 allow udp from %global.backbone to %global.backbone.broadcast 123
# Запрещаем остальной трафик
$fwcmd add 20200 deny log ip from any to any
##-----------------------------------------------------------------------------
## Мультикасты (нумерация с 25000)
##-----------------------------------------------------------------------------
# Разрешаем OSPF-пакеты
$fwcmd add 25000 allow ospf from %global.backbone to 224.0.0.0/24{5,6}
# Разрешаем общие IGMP и DVMRP-пакеты
$fwcmd add 25100 allow igmp from %global.backbone to 224.0.0.0/24{1,2,4}
$fwcmd add 25200 allow igmp from %ip.link.iskranet-gw to 224.0.0.0/24{1,2}
# Разрешаем трафик TVoIP
$fwcmd add 25300 allow ip from %ip.ext.tvoip to 224.2.153.173
# Запрещаем остальной трафик
$fwcmd add 25400 deny log ip from any to any
######################################################################
## Исходящий трафик (нумерация с 30000)
######################################################################
# Запрещаем отправку пакетов, предназначенных для внутрисетевых адресов,
# на шлюз по умолчанию
$fwcmd add 30000 deny ip from any to %global.internal $xmit_iface_inet
# Запрещаем отправку в Интернет пакетов Netbios
$fwcmd add 30100 deny tcp from any to any 135,139,445 $xmit_iface_inet
# Запрещаем отправку пакетов в Интернет для клиентов, которые отключены
# от Интернета
$fwcmd add 30200 skipto 30350 ip from %allow.internet to any $xmit_iface_inet
$fwcmd add 30300 deny ip from any to any $xmit_iface_inet
# Шейпинг ping-пакетов
$fwcmd add 30350 skipto 30400 icmp from %group.ping-shaping to any icmptypes 8 $xmit_iface_inet
$fwcmd add 30351 pipe 10 icmp from any to any icmptypes 8 $xmit_iface_inet
# Съем трафика для статистики
$fwcmd add 30400 divert 18001 ip from any to any $xmit_iface_inet
# NAT-трансляция исходящих пакетов
$fwcmd add 30800 divert 8668 ip from 192.168.0.0/16 to any $xmit_iface_inet
#$fwcmd add 30900 allow ip from %ip.nat to any $xmit_iface_inet
# Направляем пакеты в нужные интерфейсы аплинков в зависимости от их src-адреса
$fwcmd add 31000 fwd %ip.link.krastelecom-gw ip from %ip.link.krastelecom to any $xmit_iface_inet
$fwcmd add 31100 fwd %ip.link.iskranet-gw ip from %ip.link.iskranet to any $xmit_iface_inet
# Динамическое правило для доступа с данного сервера к внешним службам по UDP
$fwcmd add 31200 allow udp from me to any keep-state
##-----------------------------------------------------------------------------
## Аккаунтинг трафика (нумерация с 40000)
##-----------------------------------------------------------------------------
# Трафик Интернета
$fwcmd add 40000 skipto 40200 ip from %global.internal to %group.accounting
$fwcmd add 40100 divert 17000 ip from any to %group.accounting
######################################################################
Правила на сервере доступа:
#!/bin/sh -e
fwcmd="echo"
# Интерфейс, подключенный к клиентскому сегменту
iface_clients=fxp0
# Интерфейсы VPN
iface_vpns=ng*
######################################################################
## Разделение трафика в зависимости от направления (нумерация с 100)
######################################################################
# Трафик через интерфейс lo0
$fwcmd add 100 allow ip from any to any via lo0
# Исходящий трафик
$fwcmd add 200 skipto 30000 ip from any to any out
######################################################################
## Входящий трафик (нумерация с 500)
######################################################################
# Открываем доступ к DHCP-серверу с незарегистрированных адресов, запрещаем
# с них любой другой трафик
$fwcmd add 500 allow udp from %clients.unreg to %srv.dhcp 67
$fwcmd add 600 allow udp from %clients.unreg to 255.255.255.255 67
$fwcmd add 700 deny ip from %clients.unreg to any
##-----------------------------------------------------------------------------
## Антиспуфинг (нумерация с 1000)
##-----------------------------------------------------------------------------
# Интерфейс клиентов
$fwcmd add 1000 skipto 5000 ip from 0.0.0.0 to any recv $iface_clients
$fwcmd add 1100 skipto 5000 ip from %clients to any recv $iface_clients
$fwcmd add 1200 deny log ip from any to any recv $iface_clients
# Интерфейсы VPN
$fwcmd add 1300 skipto 5000 ip from %clients to any recv $iface_vpns
$fwcmd add 1400 skipto 5000 ip from any to any verrevpath recv $iface_vpns
$fwcmd add 1500 deny log ip from any to any recv $iface_vpns
##-----------------------------------------------------------------------------
## Разделение трафика в зависимости от получателя пакета (нумерация с 5000)
##-----------------------------------------------------------------------------
# Трафик, адресованный серверу
$fwcmd add 5000 skipto 10000 ip from any to me
# Броадкасты
$fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255
$fwcmd add 5200 skipto 20000 ip from any to %global.backbone.broadcast
$fwcmd add 5300 skipto 20000 ip from any to %clients.broadcast
# Мультикасты
$fwcmd add 5400 skipto 25000 ip from any to 224.0.0.0/4
##-----------------------------------------------------------------------------
## Трафик, идущий транзитом (нумерация с 6000)
##-----------------------------------------------------------------------------
# Запрещаем трафик на закрытые адреса магистрали
$fwcmd add 6000 deny log ip from any to %global.backbone.private
# Разрешаем любой трафик, идущий c VPN-адресов клиентов, которым открыт доступ
# к услугам сети, и обратно
$fwcmd add 6100 allow ip from %access.allow to any
$fwcmd add 6200 allow ip from any to %access.allow
# Разрешаем трафик, идущий от клиентов на DNS-резолвер и обратно
$fwcmd add 6300 allow ip from any to %global.srv.resolver
$fwcmd add 6400 allow ip from %global.srv.resolver to any
# Разрешаем трафик, идущий от клиентов на веб-сервер сети и обратно
$fwcmd add 6500 allow ip from any to %global.srv.http
$fwcmd add 6600 allow ip from %global.srv.http to any
# Разрешаем эхо-запросы, идущие на локальные адреса клиентов, и эхо-ответы
# c этих адресов
$fwcmd add 6700 allow icmp from any to %clients icmptypes 8
$fwcmd add 6800 allow icmp from %clients to any icmptypes 0
# Запрещаем остальной трафик
$fwcmd add 6900 deny log ip from any to any
##-----------------------------------------------------------------------------
## Трафик, адресованный серверу (нумерация с 10000)
##-----------------------------------------------------------------------------
# Разрешаем установленные TCP-соединения
$fwcmd add 10000 allow tcp from any to any established
# Разрешаем фрагменты IP-пакетов
$fwcmd add 10100 allow ip from any to any frag
# Разрешаем пакеты, удовлетворяющие динамическим правилам
$fwcmd add 10200 check-state
# Разрешаем OSPF-пакеты
$fwcmd add 10300 allow ospf from %global.backbone to any
# Разрешаем GRE-пакеты
$fwcmd add 10400 allow gre from any to any
##-----------------------------------------------------------------------------
## Службы сервера (нумерация с 12000)
##-----------------------------------------------------------------------------
# SSH
$fwcmd add 12000 allow tcp from %srv.ssh.allow to %srv.ssh 22
# DHCP
$fwcmd add 12100 allow udp from %srv.dhcp.allow to %srv.dhcp 67
# PPTP
$fwcmd add 12200 allow tcp from %srv.pptp.allow to %srv.pptp 1723
# SNMP
$fwcmd add 12300 allow udp from %srv.snmp.allow to %srv.snmp 161,1161
##-----------------------------------------------------------------------------
## Завершающие правила для трафика, адресованного серверу (нумерация с 18000)
##-----------------------------------------------------------------------------
# Разрешаем ICMP-пакеты
$fwcmd add 18000 allow icmp from any to any
# Разрешаем работу traceroute
$fwcmd add 18100 unreach port udp from any to any 33434-33584
# Запрещаем соединения на 80 порт (samba)
$fwcmd add 18200 reset tcp from any to any 80
# Запрещаем соединения на 113 порт (ident)
$fwcmd add 18300 reset tcp from any to any 113
# Запрещаем соединения на 1080 порт (socks check)
$fwcmd add 18400 reset tcp from any to any 1080
# Запрещаем остальной трафик
$fwcmd add 18500 deny log ip from any to any
##-----------------------------------------------------------------------------
## Броадкасты (нумерация с 20000)
##-----------------------------------------------------------------------------
# Разрешаем SNMP trap'ы от ИБП
$fwcmd add 20000 allow udp from %global.backbone to any 162
# Разрешаем NTP-пакеты
$fwcmd add 20100 allow udp from %global.backbone to %global.backbone.broadcast 123
# Разрешаем поиск DHCP-сервера
$fwcmd add 20200 allow udp from %srv.dhcp.allow to any 67
# Запрещаем остальной трафик
$fwcmd add 20300 deny log ip from any to any
##-----------------------------------------------------------------------------
## Мультикасты (нумерация с 25000)
##-----------------------------------------------------------------------------
# Разрешаем OSPF-пакеты
$fwcmd add 25000 allow ospf from %global.backbone to 224.0.0.0/24{5,6}
# Разрешаем общие IGMP и DVMRP-пакеты
$fwcmd add 25100 allow igmp from %global.backbone to 224.0.0.0/24{1,2,4}
$fwcmd add 25200 allow igmp from %clients to 224.0.0.0/24{1,2}
# Разрешаем подписку на группы TVoIP
$fwcmd add 25300 allow igmp from %clients to %global.srv.tvoip.groups
# Разрешаем трафик TVoIP
$fwcmd add 25400 allow ip from %global.srv.tvoip to %global.srv.tvoip.groups
# Запрещаем остальной трафик
$fwcmd add 25500 deny log ip from any to any
######################################################################
## Исходящий трафик (нумерация с 30000)
######################################################################
# Динамическое правило для доступа с данного сервера к внешним службам по UDP
$fwcmd add 30000 allow udp from me to any keep-state
######################################################################
Правила на сервере служб:
#!/bin/sh -e
fwcmd="echo"
######################################################################
## Разделение трафика в зависимости от направления (нумерация с 100)
######################################################################
# Трафик через интерфейс lo0
$fwcmd add 100 allow ip from any to any via lo0
# Исходящий трафик
$fwcmd add 200 skipto 30000 ip from any to any out
######################################################################
## Входящий трафик (нумерация с 1000)
######################################################################
##-----------------------------------------------------------------------------
## Разделение трафика в зависимости от получателя пакета (нумерация с 5000)
##-----------------------------------------------------------------------------
# Трафик, адресованный серверу
$fwcmd add 5000 skipto 10000 ip from any to me
# Броадкасты
$fwcmd add 5100 skipto 20000 ip from any to 255.255.255.255
$fwcmd add 5150 skipto 20000 ip from any to %group.backbone_broadcast
# Мультикасты
$fwcmd add 5200 skipto 25000 ip from any to 224.0.0.0/4
##-----------------------------------------------------------------------------
## Трафик, идущий транзитом (нумерация с 6000)
##-----------------------------------------------------------------------------
# Запрещаем весь трафик
$fwcmd add 6000 deny log ip from any to any
##-----------------------------------------------------------------------------
## Трафик, адресованный серверу (нумерация с 10000)
##-----------------------------------------------------------------------------
# Преобразовываем запросы к DNS-резолверу
$fwcmd add 10000 divert 8669 ip from %allow.resolver_internet to %ip.resolver
# Разрешаем установленные TCP-соединения
$fwcmd add 10100 allow tcp from any to any established
# Разрешаем фрагменты IP-пакетов
$fwcmd add 10200 allow ip from any to any frag
# Разрешаем пакеты, удовлетворяющие динамическим правилам
$fwcmd add 10300 check-state
# Разрешаем OSPF-пакеты
$fwcmd add 10400 allow ospf from %group.backbone to any
##-----------------------------------------------------------------------------
## Службы сервера (нумерация с 12000)
##-----------------------------------------------------------------------------
# SSH
$fwcmd add 12000 deny tcp from %deny.ssh to %ip.ssh 22
$fwcmd add 12100 allow tcp from %allow.ssh to %ip.ssh 22
# DNS-резолвер
$fwcmd add 12200 deny { tcp or udp } from %deny.resolver to %ip.resolver 53
$fwcmd add 12300 allow { tcp or udp } from %allow.resolver to %ip.resolver 53
# DNS-сервер
$fwcmd add 12400 deny { tcp or udp } from %deny.dns to %ip.dns 53
$fwcmd add 12500 allow { tcp or udp } from %allow.dns to %ip.dns 53
# DNS-кэш
$fwcmd add 12600 deny { tcp or udp } from %deny.dnscache to %ip.dnscache 53
$fwcmd add 12700 allow { tcp or udp } from %allow.dnscache to %ip.dnscache 53
# NTP-сервер
$fwcmd add 12800 deny udp from %deny.ntp to %ip.ntp 123
$fwcmd add 12900 allow udp from %allow.ntp to %ip.ntp 123
# IRC
$fwcmd add 13000 deny tcp from %deny.irc to %ip.irc 6667-6669
$fwcmd add 13100 allow tcp from %allow.irc to %ip.irc 6667-6669
$fwcmd add 13200 deny icmp from any to %ip.irc icmptypes 8
# HTTP
$fwcmd add 13700 deny tcp from %deny.http to %ip.http 80,443
$fwcmd add 13800 allow tcp from %allow.http to %ip.http 80,443
# SMTP
$fwcmd add 13900 deny tcp from %deny.smtp to %ip.smtp 25
$fwcmd add 14000 allow tcp from %allow.smtp to %ip.smtp 25
$fwcmd add 14100 deny tcp from %group.internal to %ip.smtp 25
$fwcmd add 14200 allow tcp from any to %ip.smtp 25
# POP
$fwcmd add 14300 deny tcp from %deny.pop to %ip.pop 110
$fwcmd add 14400 allow tcp from %allow.pop to %ip.pop 110
# SNMP
$fwcmd add 14500 allow udp from %allow.snmp to %ip.snmp 161,1161
##-----------------------------------------------------------------------------
## Завершающие правила для трафика, адресованного серверу (нумерация с 18000)
##-----------------------------------------------------------------------------
# Разрешаем ICMP-пакеты
$fwcmd add 18000 allow icmp from any to any
# Разрешаем работу traceroute
$fwcmd add 18100 unreach port udp from any to any 33434-33584
# Запрещаем соединения на 113 порт (ident)
$fwcmd add 18200 reset tcp from any to any 113
# Запрещаем соединения на 1080 порт (socks check)
$fwcmd add 18300 reset tcp from any to any 1080
# Запрещаем остальной трафик
$fwcmd add 18400 deny log ip from any to any
##-----------------------------------------------------------------------------
## Броадкасты (нумерация с 20000)
##-----------------------------------------------------------------------------
# Разрешаем SNMP trap'ы от ИБП
$fwcmd add 20000 allow udp from %group.backbone to any 162
# Запрещаем остальной трафик
$fwcmd add 20100 deny log ip from any to any
##-----------------------------------------------------------------------------
## Мультикасты (нумерация с 25000)
##-----------------------------------------------------------------------------
# Разрешаем OSPF-пакеты
$fwcmd add 25000 allow ospf from %group.backbone to 224.0.0.0/24{5,6}
# Запрещаем остальной трафик
$fwcmd add 25100 deny log ip from any to any
######################################################################
## Исходящий трафик (нумерация с 30000)
######################################################################
# Преобразовываем ответы DNS-резолвера
$fwcmd add 30000 divert 8669 ip from %ip.dnscache to %allow.resolver_internet
# Динамическое правило для доступа с данного сервера к внешним службам по UDP
$fwcmd add 30100 allow udp from me to any keep-state
##-----------------------------------------------------------------------------
## Аккаунтинг трафика (нумерация с 40000)
##-----------------------------------------------------------------------------
# Трафик почтового сервера (POP)
$fwcmd add 40000 divert 17000 tcp from %ip.pop to %group.accounting
Порядок прохождения пакетов при одновременном использовании ipfilter, pf и ipfw:
При загрузке фильтров модулями, порядок будет определяться порядком загрузки модулей.
Причина здесь в том, что пакетные фильтры регистрируют себя в pfil(9).
При включении всех фильтров в ядро порядок будет определять SYSINIT.
Чтобы определить порядок, нужно открыть файл sys/kernel.h.
В нём определён порядок инициализации определённых подсистем. Теперь, простейшее:
# grep DECLARE_MODULE netinet/ip_fw_pfil.c
DECLARE_MODULE(ipfw, ipfwmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
# grep DECLARE_MODULE contrib/pf/net/pf_ioctl.c
DECLARE_MODULE(pf, pf_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST);
# grep DECLARE_MODULE contrib/ipfilter/netinet/mlfk_ipl.c
DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
От сюда следует: первым будет ipfilter, затем pf, затем ipfw.
Устанавливаем sshguard из портов:
cd /usr/ports/security/sshguard
make install clean WITH_PF=yes
Настраиваем перенаправление логов в sshguard
echo "auth.info;authpriv.info |exec /usr/local/sbin/sshguard" >> /etc/syslog.conf
Правила блокировки по таблице, /etc/pf.conf
internet="vlan50"
table persist
block in quick on $internet from label "ssh bruteforce"
Перечитываем измененные файлы конфигурации PF и syslogd:
pfctl -f /etc/pf.conf
/etc/rc.d/syslogd restart
Тестируем попробовав подобрать пароли:
shguard[1048576]: Started successfully [(a,p,s)=(4, 420, 1200)], now ready to scan.
sshd[1048577]: Invalid user administrador from 21.138.24.51
sshd[1048579]: Invalid user publica from 21.138.24.51
sshd[1048580]: Invalid user rbecerril from 21.138.24.51
sshd[1048581]: Invalid user rvences from 21.138.24.51
sshguard[1048582]: Blocking 21.138.24.51: 4 failures over 15 seconds.
shguard[1048583]: Releasing 21.138.24.51 after 490 seconds.
> Работает шейпер на dummynet, наблюдается некотороая потеря
> траффика. Hавскидку проблема в дефолтных значениях размера очереди (50 пакетов)
> для pipe'ов от 32 до 512 Кбит\с. Скорее всего, поток не влезает в очередь и
> часть пакетов отбрасывается. Как правильно рассчитать размер очереди для
> каждого pipe в отдельности?
Eugene Grosbein:
Pipe и должен отбрасывать пакеты, иначе какой же это шейпер?
Ты не можешь увеличивать длину очереди бесконечно, потому что задержки
вырастут настолько, что соединение начнет рвать сам юзер :-)
Hа таких низких скоростях размер очереди надо бы, наоборот, уменьшать,
чтобы не допустить гигантских задержек типа нескольких тысяч милисекунд.
А если хочешь и рыбку съесть, и потерь иметь минимум, то читай-ка ты
про RED/GRED на unixfaq.ru и делай не просто pipe, а queue/pipe с gred.
Рекомендую делать w_q=0.002, max_p=0.1, min=q/10, max=3*min,
где q - длина очереди, q=20 для скоростей меньше 100Kbit/s,
q=30 для скоростей от 100 до 300Kbit/s и q=50 для скоростей 512Kbit/s и выше.
----------
Sergey A Yakovets:
Пол-дня игрался с параметром queue. В итоге подобрал на первый взгляд
кое-что подходящее. Алгоритм\мысли были следующие:
Дано: асинхронный спутниковый Инет. Входящий канал - 1024 Кбит\с.
Опытным путем установлено, что проблемы с потерей траффика (до 10% от
общего объема) возникают при многопотоковых http\ftp закачках, т.к. спутниковый
провайдер в этом случае может отдать поток на все 1024 Кбит\с. При серфинге все
нормально. Исходя из этого, мною были сделаны некоторые расчеты:
При максимальной пропускной способности входящего спутникового канала
в 1024 Кбит\с и размере пакета в 1500 байт, пропускная способность канала
равна ~ 87 пакетов\сек. В это же время, для канала в 128 Кбит\с пропускная
способность равна ~ 11 пакетов\сек. Гипотетическая разница, при условии что на
юзера будет идти поток в 1024 Кбит\с, а отдаваться только 128 Кбит\с, может
составить 76 пакетов\сек.
Итого, опытным путем установлено:
- (было) при дефолтной очереди в 50 пакетов на pipe 128 Кбит\с потери 10%
- при размере очереди = разница*2 = 150 пакетов потери 2%
- (стало) при размере очереди = разница*3 = 230 пакетов потери 0%
Серфинг не страдает, задержек нет. Закачка идет на скорости шейпера, потерь нет.
Пробовал другой вариант.
Hа pipe 128 Кбит\с было выставлено gred 0.002/3/6/0.1 В итоге - огромные
потери, т.к. канал практически все время работал на скорости пакетов намного
больше чем max_th*2. Изменение параметров до gred 0.002/50/150/0.1 не влияло на
результат, т.к. дефолтный размер очереди в 50 пакетов часто переполнялся и gred
не имел никакого действия.
---------
Что такое алгоритмы RED и gentle RED у ipfw?
http://unixfaq.ru/index.pl?req=qs&id=310
Ответ на этот вопрос скомпилирован из статей в конференции RU.UNIX.BSD от следующих авторов:
Valentin Ermolaev, Alexander V. Naumochkin, Jen Linkova.
Сокращение RED означает "Random Early Detection". Метод используется для выравнивания всплесков трафика.
Основным критерием метода является так называемая перегрузка.
В качестве показателя перегрузки avg используется вычисляемое среднее значение длины очереди пакетов,
принадлежащей к определенной сессии TCP. Использование усредненного,
а не мгновенного значения очереди позволяет отделить кратковременные перегрузки,
которые могут быть нормально обработаны устройством и сетью, от длительных перегрузок,
которые могут утопить сеть.
Алгоритмически это выглядит так:
В момент прихода пакета
; ; if (очередь не пуста)
; ; ; ; avg = (1 - w_q)*avg + w_q*q
; ; else
; ; ; ; m = f(time - q_time)
; ; ; ; avg = (1 - w_q)^m * avg;
где
avg -средний размер очереди
q_time - "start of queue idle time"
q - размер очереди
w_q - вес очереди (фиксированный параметр)
f() - линейная функий от времени
В /usr/src/sys/netinet/ip_dummynet.c по этому поводу написано следующее:
* RED algorithm
*
* RED calculates the average queue size (avg) using a low-pass filter
* with an exponential weighted (w_q) moving average:
* avg <- (1-w_q) * avg + w_q * q_size
* where q_size is the queue length (measured in bytes or * packets).
*
* If q_size == 0, we compute the idle time for the link, and set
* avg = (1 - w_q)^(idle/s)
* where s is the time needed for transmitting a medium-sized packet.
- что полностью согласуется с приведенными выше формулами.
Далее в алгоритме вводятся два порога уровня перегрузки: min_th и max_th.
Когда уровень перегрузки ниже первого порога min_th, то пакеты не отбрасываются.
Если уровень перегрузки находится между двумя порогами, пакеты отбрасываются с линейно
возврастающей вероятностью из диапазона от 0 до конфигурируемой величины max_p,
которая достигается при достижении второго порога max_th. Выше порога max_th
отбрасываются все пакеты.
Такой метод вычисления позволяет сглаживать всплески трафика - для сравнения в первой из статей (см. ниже)
на одном графике приводятся и изменение размера очереди q, и усредненного размера
очереди (avg) от времени. В той же статье есть выкладки на тему значений w_q.
При gentle RED ситуация выглядит чуть сложнее:
Если перегрузки лежит в интервале от min_th до max_th, то пакеты отбрасываются с линейно
возрастающей от 0 до max_p вероятностью. Когда перегрузка превышает max_th,
но не превышет 2*max_th, пакеты отбрасываются не все (как в случае RED), а с линейно возрастающей
от max_p до 1 вероятностью. Все пакеты отбрасываются только после превышения перегрузки канала значения 2*max_th.
Вот как это сделано в ip_dummynet.c:
если длина очереди > max_th, то в случае gred вероятность
отбрасывания пакета вычисляется как
; ; p_b = c_3 * avg - c_4
где c_3 = (1 - max_p) / max_th
; ; c_4 = 1 - 2 * max_p
В случае просто RED пакет отбрасывается.
При загрузке очереди, большей min_th, но меньшей max_th, функция
вероятности одинакова и выглядит след. образом:
; ; p_b = c_1 *avg - c_2
где c_1 = max_p / (max_th - min_th),
; ; c_2 = max_p * min_th / (max_th - min_th)
Полезные ссылки:
1. http://www.icir.org/floyd/papers/red/red.html
2. http://www.icir.org/floyd/red.html
3. http://www.cisco.com/warp/public/732/Tech/red/
Проверяем число соединений в таблице и сравнимаем с текущим лимитом:
# pfctl -s state | wc -l
10000
# pfctl -s memory | grep states
states hard limit 10000
Таблица переполнена, поднимает лимит до 20000:
set limit states 20000
Перечитываем конфигурацию pf:
pfctl -O -f /etc/pf.conf
Ниже описано как в разрыв между внешним миром и локальной сетью поставить машину на базе OpenBSD,
на которой будет в прозрачном режиме отсеиваться спам через spamd.
fxp2 - внешний интерфейс
fxp0 - интерфейс локальной сети
Поднимаем бридж:
ifconfig fxp0 up
ifconfig fxp2 inet 172.16.5.111 netmask 255.255.255.0 up
route add default 172.16.5.1
ifconfig bridge0 create
brconfig bridge0 add fxp0 add fxp2 up
Проверяем включен ли форвадинг пакетов между интерфейсами и загружаем правила пакетного фильтра pf:
sysctl net.inet.ip.forwarding=1
pfctl -ef /etc/pf.conf
где /etc/pf.conf:
ext_if="fxp2"
table <spamd> persist
table <spamd-white> persist
rdr on $ext_if inet proto tcp from <spamd> to port smtp \
-> 127.0.0.1 port spamd
rdr on $ext_if inet proto tcp from !<spamd-white> to port smtp \
-> 127.0.0.1 port spamd
# "log" so you can watch the connections getting trapped
pass in log on $ext_if route-to lo0 inet proto tcp to 127.0.0.1 port spamd
Если используется ipfw2 и keep-state правила, то от непрерывного роста
соединений со статусом FIN_WAIT_2 помогает:
sysctl -w net.inet.ip.fw.dyn_keepalive=0
Linux:
- Перед правилом блокировки нужно вставить "log" правило:
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 \
-j LOG --log-level debug --log-prefix "outgoing mail"
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 -j DROP
- Проверить запущены ли в системе klogd и syslogd.
- Настроить /etc/syslog.conf на прием kern.debug логов:
kern.=debug -/var/log/kernel/info
FreeBSD:
Добавить ключ log в ipfw, например:
ipfw add 1000 deny log tcp from any to 192.168.10.10 22 via fxp0
ipfw add 1000 deny log logamount 0 tcp from any to 192.168.10.10 80 via fxp0
Для ведения логов ядро должно быть собрано с IPFIREWALL_VERBOSE или нужно выставить "sysctl -w net.inet.ip.fw.verbose=1".
Далее проверить чтобы в /etc/syslog.conf было упоминание LOG_SECURITY:
security.* /var/log/security
Через параметр logamount передается число записей которые будет записано в лог,
после превышения записи перестанут появляться в логе, до тех пор пока не будет вызвана команда
"ipfw resetlog". Максимальное число сообщений можно также установить
через sysctl net.inet.ip.fw.verbose_limit.
Для отмены лимитирования на число записей, нужно установить атрибут в 0.
Для безопасного редактирование правил ipfw рекомендую обратить внимание на скрипт change_rules.sh,
находящийся в /usr/share/examples/ipfw. В случае неправильных действий он вернёт старый набор правил,
а также сообщит администратору об изменениях в файрволе по почте.
Что бы поднять NAT и Firewall на FreeBSD надо:
Скомпилировать ядро:
Следующие строки нужно включить в /usr/src/sys/i386/conf/GENERIC файл конфигурации:
options IPFIREWALL
options IPDIVERT
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options DUMMYNET
options TCP_DROP_SYNFIN
Переходим в директорию /usr/src/
make buildkernel KERNCONF=GENERIC
make installkernel KERNCONF=GENERIC
Следующие строки можно к примеру включить в rc.conf файл конфигурации:
hostname="free"
ifconfig_rl0="10.0.0.1"
gateway_enable="YES"
firewall_enable="YES"
firewall_type="open"
natd_enable="YES"
natd_interface="rl0"
natd_flags="-redirect_port tcp 10.0.0.10:80 80"
tcp_extensions="NO"
tcp_drop_synfin="YES"
icmp_drop_redirect="YES"
sendmail_enable="NONE"
Для удаленного управления нужно добавить следующую строку:
sshd_enable="YES"
(возможно понадобится скопировать /etc/ssh/ssh_host_dsa_key.pub в /root/.ssh/authorized_keys
Следующие строки можно включить в rc.firewall файл конфигурации (секция "open"):
[Oo][Pp][Ee][Nn])
oif="rl0"
iif="tx0"
oip="132.5.7.172"
iip="10.0.0.1"
lan="10.0.0.0/24"
setup_loopback
# allow all for LAN
${fwcmd} add 500 pass all from ${lan} to ${iip} via ${iif}
${fwcmd} add 550 pass all from ${iip} to ${lan} via ${iif}
# download - 60K upload - 6K for all lan ip's
${fwcmd} add 600 pipe 1 ip from any to any in via ${oif}
${fwcmd} add 650 pipe 2 ip from any to any out via ${oif}
# for selected ip's only
# ${fwcmd} add 601 pipe 1 all from any to 10.0.0.10
# ${fwcmd} add 651 pipe 2 all from 10.0.0.10 to any
${fwcmd} pipe 1 config bw 512Kbit/s
${fwcmd} pipe 2 config bw 48Kbit/s
# dns setup
${fwcmd} add 770 pass tcp from any to ${oip} 53 setup
${fwcmd} add 780 pass udp from any domain to any
${fwcmd} add 790 pass udp from any to any domain
# main setup
${fwcmd} add 800 pass tcp from any http,https,20-21,989-990 to any
${fwcmd} add 810 pass tcp from any to any http,https,20-21,989-990
${fwcmd} add 830 pass tcp from any pop3,pop3s,smtp,imap,imaps,aol to any
${fwcmd} add 840 pass tcp from any to any pop3,pop3s,smtp,imap,imaps,aol
${fwcmd} add 65000 deny ip from any to any
;;
Где oip, oif - внешний интерфейс; iip, iif - внутренний; lan - внутренняя сеть.
Такая конфигурация ipfw весьма параноидальна, и здесь приведена только в качестве примера.
На практике обычно нужен более открытый фаервол.
Решение оптимизировано для шлюза на флешке (не используется perl и другие "тяжелые" решения)
-------------------------
/usr/local/etc/rc.d/openvpn.sh
-------------------------
#!/bin/sh
. /etc/rc.subr
name=openvpn
rcvar=`set_rcvar`
prefix="/usr/local"
openvpn_precmd()
{
for i in $openvpn_if ; do
# FreeBSD <= 5.4 does not know kldstat's -m option
# FreeBSD >= 6.0 does not add debug.* sysctl information
# in the default build - we check both to keep things simple
if ! sysctl debug.if_${i}_debug >/dev/null 2>&1 \
&& ! kldstat -m if_${i} >/dev/null 2>&1 ; then
if ! kldload if_${i} ; then
warn "Could not load $i module."
return 1
fi
fi
done
return 0
}
start_postcmd()
{
`/bin/cat /var/db/ukr_nets| /usr/bin/awk '{ if ($1) {system("route add "$1" 193.201.61.65 >/dev/null")} }'`
/bin/sleep 10 && pfctl -F all -f /etc/pf.conf_openvpn
}
stop_postcmd()
{
`/bin/cat /var/db/ukr_nets| /usr/bin/awk '{ if ($1) {system("route delete "$1" 193.201.61.65 >/dev/null")} }'`
pfctl -F all -f /etc/pf.conf
rm -f "$pidfile" || warn "Could not remove $pidfile."
}
extra_commands="reload"
pidfile="/var/run/${name}.pid"
command="/usr/local/sbin/${name}"
start_precmd="openvpn_precmd"
start_postcmd="start_postcmd"
stop_postcmd="stop_postcmd"
load_rc_config ${name}
: ${openvpn_enable="NO"}
: ${openvpn_flags=""}
: ${openvpn_if=""}
: ${openvpn_configfile="${prefix}/etc/openvpn/openvpn.conf"}
: ${openvpn_dir="${prefix}/etc/openvpn"}
required_files="${openvpn_configfile}"
command_args="--cd ${openvpn_dir} --daemon --config ${openvpn_configfile} --writepid ${pidfile}"
run_rc_command "$1"
-------------------------
/etc/pf.conf
-------------------------
ext_if_t="rl0"
int_if="rl1"
table <users> persist { 192.168.1.0/24 }
nat on $ext_if_t inet from <users> to any -> $ext_if_t
pass on $ext_if_t all
pass on $int_if all
-------------------------
/etc/pf.conf_openvpn
-------------------------
ext_if_o="tap0"
ext_if_t="rl0"
int_if="rl1"
table <users> persist { 192.168.1.0/24 }
table <ukr> persist file "/var/db/ukr_nets"
nat on $ext_if_t inet from <users> to <ukr> -> $ext_if_t
nat on $ext_if_o inet from <users> to !<ukr> -> $ext_if_o
pass on $ext_if_o all
pass on $ext_if_t all
pass on $int_if all
-------------------------
cron:
-------------------------
0 0 * * * /usr/bin/fetch -q -o "/var/db/ukr_nets" 'http://www.colocall.net/ua/?list'
В прежних версиях FreeBSD изменить правило по умолчанию
65535 deny ip from any to any на
allow ip from any to any
можно было включением в ядро опции
IPFIREWALL_DEFAULT_TO_ACCEPT.
В версии 5.3 это не работает. Даже собрав ядро с этой опцией, получаем правило по умолчанию
deny ip from any to any.
Если сборка производится удаленно - сюрприз может оказаться довольно неприятным.
Иногда необходимо пробросить порты с двух различных gateway GW1 и GW2 на один внутренний сервер,
у которого в качестве default GW указан GW1.
Прямой проброс и NAT невозможен, т.к. пакеты пришедшие из GW2 попытаются вернуться по маршруту через GW1.
Есть следующий выход, это двойной NAT на GW2, при котором запрос приходит не снаружи, а с внутреннего IP.
ed0 - внешний интерфейс
lnc0 - интерфейс смотрящий внутрь.
в ipnat.rules нужно прописать следующее:
map ed0 10.6.10.0/24 -> 0.0.0.0/32 мапим локалку наружу
map lnc0 0.0.0.0/0 -> 0.0.0.0/32 ремап внешних ip в локальные
rdr ed0 0.0.0.0/0 port 80 -> 10.6.10.2 port 80 tcp форвард на внутренний сервер
Мысль простая:
Аська сообщениями по 5190 и другим портам обменивается, а баннеры только с определенных
IP с 80го порта качает по HTTP ... Когда я на это наткнулся, написал скрипт такого содержания:
#!/bin/sh
# add this rule to your firewall and :
# ipfw deny tcp from 192.168.0.0/16 to table(1) out via rl0 setup dst-port 80
NETS=" 64.12.164 64.12.174 152.163.208 205.188.165 205.188.248 205.188.250 "
IPS=" 25 57 121 153 185 245 "
fwcmd=" ipfw "
tablenum=" 1 "
#Flushing table
${fwcmd} table ${tablenum} flush
#Add tables ips
for D1 in ${NETS}
do
for D2 in ${IPS}
do
${fwcmd} table ${tablenum} add ${D1}.${D2}
done
done
И в firewall воткнул правило вида
ipfw deny tcp from any to table\(1\) out via rl0 setup dst-port 80
Где rl0 - внешний интерфейс.
Правильнее, конечно настроить squid и резать банеры на нем - но так проще и быстрее. К тому же заметно меньше грузит машину.
/sbin/ipfw pipe 1 config bw 7000Kbit/s
/sbin/ipfw queue 1 config pipe 1 weight 75 mask dst-ip 0x00000000
/sbin/ipfw queue 2 config pipe 1 weight 50 mask dst-ip 0x00000000
/sbin/ipfw queue 3 config pipe 1 weight 50 mask dst-ip 0x00000000
/sbin/ipfw queue 4 config pipe 1 weight 50 mask dst-ip 0x00000000
/sbin/ipfw add queue 1 ip from any to 192.168.0.0/24
/sbin/ipfw add queue 2 ip from any to 192.168.1.0/24
/sbin/ipfw add queue 3 ip from any to 192.168.2.0/24
/sbin/ipfw add queue 4 ip from any to 192.168.3.0/24
Итого имеем: одну толстую трубу на 7К и 4 очереди в нее.
У первой приоритет 75% канала. У остальных - по 50%
Собираем библиотеки и сам IPFW:
cd /usr/src/lib/libalias
make -DIPFW2 && make install
cd /usr/src/sbin/ipfw
make -DIPFW2 && make install
Пересобираем ядро с "options IPFW2" и опциями по вкусу:
options IPFIREWALL #firewall
options IPFIREWALL_VERBOSE #enable logging to syslogd(8)
options IPFIREWALL_FORWARD #enable transparent proxy support
options IPFIREWALL_VERBOSE_LIMIT=100 #limit verbosity
options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default
options DUMMYNET
options IPFW2
Делаем reboot и проверяем например командой "ipfw show"
Вот реализация для ipfw:
if1IP="ип_смотрящий_в_инет", if1="интерфейс_смотрящий_в_инет"
ifLIP="ип_на_который хотим делать редирект"
ipfw add divert natd tcp from any to ${if1IP} 80 via ${if1}
ipfw add divert natd ip from any to ${ifLIP} to any via ${if1}
ipfw add allow tcp from any to ${if1IP} 80 via any
natd -n ${if1} -redirect_port tcp ${ifLIP}:80 80
Решение от miaso <torov@wipline.ru>:
tproxy -s 80 -r nobody -l /var/log/transparent_proxy.log [int_ip] 80
Завершить выполнение цепочки ipfw правил после попадания в pipe:
sysctl -w net.inet.ip.fw.one_pass=1
Продолжить выполнение следующих ipfw правил после попадания в pipe:
sysctl -w net.inet.ip.fw.one_pass=0
Расшифровка кодов ICMP сообщений:
echo reply (0), destination unreachable (3), source quench (4), redirect (5), echo request (8), router adver-tisement (9),
router solicitation(10), time-to-live exceeded (11), IP header bad (12), timestamp request (13), timestamp reply (14),
information request (15), information reply (16), address mask request (17) and address mask reply (18).
${fwcmd} add 00300 allow icmp from any to внешний_IP in via внешний_интерфейс icmptype 0,3,4,11,12
${fwcmd} add 00301 allow icmp from внешний_IP to any out via внешний_интерфейс icmptype 3,8,12
${fwcmd} add 00304 allow icmp from внешний_IP to any out via внешний_интерфейс frag
${fwcmd} add 00305 deny log icmp from any to any in via внешний_интерфейс
man 5 ipnat в /etc/ipnat.conf:
rdr fxp0 205.15.63.3/32 port 80 -> 192.168.1.1 port 80 tcp
# Базансировка нагрузки между 2 IP:
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp round-robin
Собираем ядро с опциями:
options DUMMYNET
options IPFIREWALL
Ограничиваем трафик для сеток 1.1.1.0/24 и 3.3.3.0/24 на 14000 кбит/с:
ipfw add pipe 50 tcp from any to 1.1.1.0/24 via fxp0
ipfw add pipe 50 tcp from any to 3.3.3.0/24 via fxp0
ipfw pipe 50 config bw 14Kbit/s
Для внесения задержки на N ms, используйте delay N после config.
Для установки веса данного пайпа по отношению к другим пайпам используйте weight вес.
Для WF2Q ограничения трафика используйте ipfw queue
(queue N config [pipe pipe_nr] [weight weight] [queue {slots | size})
PS (комментарий от gara@mail.ru):
Если возникает необходимость организовать "канал" для каждого пользователя из данной сети то пишем:
ipfw pipe 10 config mask dst-ip 0x000000ff bw 1024bit/s queue
ipfw add pipe 10 tcp from any to 1.1.1.0/24 via fxp0
Теперь каждый хост из сети 1.1.1.0/24 имеет свой канал 1024bit/s
Для FreeBSD:
ipfw add count tcp from any to not 192.168.1.0/24 uid 231
uid user (или gid group) - под правило попадают все TCP или UDP пакеты посланный
или принятые пользователем user (группой group).
В Linux в ядрах 2.4.x в iptables можно использовать модуль owner.
Запретим более 30 коннектов для 80 порта сервера 1.2.3.4.
ipfw add allow tcp from any to 1.2.3.4 80 limit src-addr 30
ipfw add allow tcp from any to 1.2.3.4 80 via fxp0 setup limit src-addr 10
Вместо src-addr можно использовать src-port, dst-addr, dst-port
Конструкция работает в последних версиях FreeBSD 4.x ветки.
В ipnat воспользуйтесь модулем ftp proxy:
map fxp0 0/0 -> 0/32 proxy port ftp ftp/tcp
map rl0 172.16.33.0/24 -> 212.46.231.50/32 proxy port ftp ftp/tcp
не забудьте поместить правило трансляции ftp перед общим правилом трансляции,
порядок следования правил важен.
В /etc/rc.conf:
ipnat_enable="YES"
В /etc/ipnat.rules:
Трансляция адресов (NAT):
map ppp0 172.16.1.0/24 -> 194.46.124.53/32
где, ppp0 - внешний интерфейс,
172.16.1.0/24 - внутренние IP,
194.46.124.53 - реальный IP внешнего интерфейса.
Переброс порта во внутреннюю сеть:
rdr ed0 294.16.9.6/32 port 8080 -> 192.168.0.7 port 8080 tcp
где, ed0 - внешний интерфейс,
294.16.9.6 - реальный IP внешнего интерфейса, на который нужно обращаться из вне.
192.168.0.7 - внутренний IP на который делается переброс.
8080 - номер перебрасываемого порта.
Перечитать: ipnat -CF -f /etc/ipnat.rules
ipfw add 100 fwd 10.0.0.2 ip from 10.0.2.0/24 to any
Если нужно использовать 2 шлюза, то можно воспользоваться:
ipfw add fwd $ext_gw_ip ip from $ext_net to any out xmit $ext_int
Для автоматической нумерации правил ipfw мы применяем следующий
несложный прием:
C=300 # начальное значение
STEP=100 # Шаг увеличения
ipfw add $C $(C=$(($C+$STEP))) allow ip from 10.128.0.0/16 to 10.128.0.0/16
ipfw add $C $(C=$(($C+$STEP))) allow ip from 195.131.31.0/24 to 195.131.31.0/24
Если ядро ругается "kernel: ip_conntrack: table full, dropping packet.", причину флуда
(скорее всего вирус или сканирование портов) можно найти по списку /proc/net/ip_conntrack
Если просто общая загрузка большая, увеличить размер таблицы можно через /proc/sys/net/ipv4/ip_conntrack_max
Также можно увеличить размерность хэша через параметр hashsize модуля ip_conntrack:
/etc/modules.conf:
options ip_conntrack hashsize=N
Более тонкий тюнинг можно произвести через переменные определенные в /proc/sys/net/ipv4/netfilter
ngrep служит для отображения проходящих сетевых пакетов удовлетворяющих заданной маске.
Как мне кажется ngrep гораздо проще и удобнее, чем tcpdump. Вот несколько примеров:
Показать содержимое всех пакетов, прошедших по 80 порту, со словом google
ngrep google port 80
Вывод пакетов удовлетворяющих маске по одному в строке, для интерфейса eth0:
ngrep -i \'game*|chat|recipe\' -W byline -d eth0
Слушать весь SMTP трафик на всех сетевых интерфейсах:
ngrep -i \'rcpt to|mail from\' -d any tcp port smtp
Показать текущее время для каждого совпадения (кто и когда заходит на машину телнетом):
ngrep -q -t -wi "login" port 23
Выход - поставить на интерфейсе туннеля MTU 1500, вместо 1476.
Проблема возникает при попытке протолкнуть пакет размером 1500 байт
с выставленным DF (don't fragment запрещена фрагментация) битом через интерфейс 1476 байт.
Другие решения:
interface ethernet0
ip policy route-map clear-df
route-map clear-df permit 10
match ip address 101
set ip df 0
access-list 101 permit tcp 10.1.3.0 0.0.0.255 any
или
interface tunnel0
ip tcp adjust-mss 1436
Linux отказывается маршрутизировать пакеты между двумя сетевыми
картами, кода пакет входит через один интерфейс и выходит через другой, если включен rp_filter (RFC1812).
Необходимо отключить rp_filter:
/sbin/sysctl -w net.ipv4.conf.default.rp_filter = 0
/sbin/sysctl -w net.ipv4.conf.all.rp_filter = 0
Для FreeBSD можно посоветовать:
в /etc/rc.conf: tcp_extensions="NO"
или sysctl -w net.inet.tcp.rfc1323=0
А так же sysctl -w net.inet.tcp.rfc1644=1 и sysctl -w net.inet.tcp.rfc1323=0
Приходилось сталкиваться с проблемами согласования режимов работы карт Intel EtherExpress 100 и
Reltek RTL-8139 c коммутаторами и концентраторами различных производителей. Несогласование
проявляется, например в работе карты в режиме half-duplex, а свича в full-duplex и т.д. (в linux: /sbin/mii-tool -F 100baseTx-FD eth0)
Неоднократно замечена проблема работы сетевых карт на базе RealTek 8129/8139 (машины под FreeBSD,
но с другими ОС тоже проявляется) с некоторыми концентраторами и коммутаторами.
Проявляется в замирании сессий до истечения таймаута.
Диагностика: ping -s N remote_ip, при больших N не проходят.
Решение: Смените сетевую карту, например, на Intel EtherExpress Pro.
Вероятные причины: Туннель, блокировка ICMP, "path MTU discovery" и ECN (Explicit Congestion Notification,
ECN проявляется в основном при доступе через Proxy).
При блокировке ICMP трафика, возможно блокируется не только echo_replay/echo_request ICMP сообщения,
но и другие важные сообщения
передаваемые по ICMP. При блокировке ICMP сообщений типа 3.4 (fragmentation needed and DF set) возможно
нарушение нормальной фрагментации пакетов, что вполне может проявляться как внезапная остановка передачи
данных большого объема и разрыв сесcии по таймауту, например, если на пути трафика встречается туннель.
Одним из путей решением проблемы, является установка на туннеле MTU > 1500 и отмена блокировки ICMP трафика.
Проблемы с ECN в Linux лечатся:
echo 0 >/proc/sys/net/ipv4/tcp_ecn
path MTU discovery:
Linux: echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc
FreeBSD: sysctl -w net.inet.tcp.rfc1323=0
1. Режим эмуляции Socks proxy в SSH
Допустим, у нас есть рабочая станция в локальной сети за firewall'ом;
также имеется ssh-доступ на сервер в Интернете. Кроме ssh, никакой связи с внешним миром не имеется,
а очень хочется, например, подключиться к какому-нибудь jabber-серверу.
На рабочей станции запускаем простую команду:
ssh -D 5555 user@remotehost -f -N
, где -D 5555 - эмуляция SOCKS сервера через порт 5555
-f - работа в фоне, после аутентификации
-N - не запускать shell на удаленном хосте.
Теперь, указав в настройках XMPP-клиента (например, Pidgin'а) в качестве SOCKS5 прокси localhost:5555,
получим желаемый результат: Pidgin соединяется с сервером через внешний сервер.
2. Туннель ssh
Дано: сервер локальной сети ourproxy.provider.ru, доступный извне.
Требуется: получить из дома доступ к ресурсам внутри локальной сети, например, к интранет-серверу 10.10.5.1:80
Решение: выполнить на домашней машине команду, пробрасывающую туннель к искомому IP-адресу через ourproxy.provider.ru:
ssh -f -N user@ourproxy.provider.ru -L 8080:10.10.5.1:80
Опция -f говорит ssh, что после соединения нужно уйти в background.
Опция -N указывает, что никаких команд выполнять не нужно
Ключ -L означает, что соединения к localhost на порт 8080 нужно перенаправлять на 80 порт IP-адреса 10.10.5.1
Таким образом, набирая в браузере адрес http://localhost:8080, попадаем на нужный сервер.
3. Обратный туннель ssh
Дано: компьютер на работе, находящийся за firewall'ом и nat'ом; компьютер дома с доступом в интернет;
сервер ourproxy.provider.ru с работающим sshd, доступный обоим компьютерам.
Но в данном случае прямой доступ с ourproxy.provider.ru к рабочей машине отсутствует.
Требуется: получить из дома доступ к сервису sshd на рабочем компьютере.
Решение: на рабочей машине выполнить команду:
ssh -f -N user@ourproxy.provider.ru -R 12345:localhost:22
Опции -f и -N описаны несколькими строчками выше.
Ключ -R означает, что подключения к порту 12345 на ourproxy.provider.ru будут перенаправляться на 22 порт рабочего компьютера.
После выполнения этой команды с рабочей машины можно будет попасть на эту машину с ourproxy.provider.ru,
выполнив команду:
ssh -p 12345 user@locahost
По этому же принципу можно получить доступ к прочим ресурсам локальной сети. Вот еще один пример.
На рабочей машине:
ssh -f -N user@ourproxy.provider.ru -R 8080:10.10.5.1:80
На домашней машине:
ssh -f -N user@ourproxy.provider.ru -L localhost:8080:localhost:8080
Теперь, набрав в адресной строке браузера на домашнем компьютере http://localhost:8080,
получаем доступ к интранет-серверу за семью замками двумя firewall-ами.
Конечно же, это приводит к серьёзной бреши в корпоративной безопасности,
поэтому крайне не рекомендуется злоупотреблять этим советом.
OpenBSD не имеет устройства tap(4), которое по своей сути является простым туннелем 2-го уровня OSI.
Вместо этого необходимо использовать tun(4), причём для последнего нужно перед запуском openvpn установить link0.
Также, при использовании --pool следует учесть, что openvpn передаёт различные параметры настройки
для TAP- и tun-соединений, из-за чего необходимо отказываться от предлагаемого выполнения ifconfig
самим OpenVPN и вместо этого юзать свой скрипт, в который в простейшем случаю жёстко прописываются
адрес удалённого конца туннеля и broadcast-адрес. В итоге получается примерно такой набор команд:
$ sudo cat /etc/hostname.tun1
up link0
!openvpn --config /etc/openvpn/mytunnel --verb 0 & sleep 5
$ sudo cat /etc/openvpn/mytunnel.conf
dev tun1
dev-type tap
pull
ifconfig-noexec
up "/etc/openvpn/mytunnel.up"
auth-user-pass "/etc/openvpn/mytunnel.pwd"
$ cat /etc/openvpn/mytunnel.up
#!/bin/sh
TUN_DEV="$1"; shift
TUN_MTU="$1"; shift
LINK_MTU="$1"; shift
LOCAL_IP="$1"; shift
NETMASK="$1"; shift
MODE="$1"; shift
ifconfig $TUN_DEV $LOCAL_IP 10.1.2.1 netmask $NETMASK broadcast 10.1.2.255 mtu $TUN_MTU
Учтите, что для того, чтобы auth-user-pass позволял указывать файл для чтения паролей,
необходимо собирать OpenVPN с опцией "--enable-password-save", которая в текущей версии
порта (openvpn-2.1_rc7) не используется. Для исправления этой проблемы лучше всего подправить
/usr/ports/net/openvpn/Makefile, добавив "--enable-password-save" в CONFIGURE_ARGS.
Разумеется, в этом нет необходимости, если не требуется обеспечить полностью автоматический запуск OpenVPN.
Была задача, сделать прозрачный переброс пользователей с одного VPN (PPTPD) сервера
на другой (PPTPD), с условием, что пользователям ничего менять в настройках VPN соединения не приедеться.
В итоге на несколько разных VPN серверов (Fedora 3,4,6, APSlinux 11) был установлен
прозрачный редирект туннеля на центральные сервер, с единой базой данных о клиентах.
Использованное ПО:
pptpproxy-2.9.tar.bz2
Пример запуска:
#./pptpproxy -p 111.111.111.111:1723,222.222.222.222:1723 -a 10.0.0.0/255.0.0.0 -l /var/log/pptp_redirect
Параметр -p
111.111.111.111:1723 какой интерфейс:порт слушать
222.222.222.222:1723 на какой адрес:порт перенаправлять
Параметр -a
10.0.0.0/255.0.0.0 acl на соединение с определенное сети
Параметр -l
/var/log/pptp_redirect куда писать лог
Таким образом избежали множества проблем с клиентами.
В первую очередь данное ПО, как следует из названия, предназначено для проброса VPN туннелей через NAT.
Использованные ОС:
APSLinux 11
CentOS 5
Fedora
Пробросить TCP порт 1604 с 192.168.25.22 на машину 172.16.1.2 во внутренней сети.
/etc/xinetd.conf
service ica
{
disable = no
port = 1604
bind = 192.168.25.22
socket_type = stream
user = root
redirect = 172.16.1.2 1604
type = UNLISTED
wait = no
}
redirect работает только для TCP.
С помощью этого маленького скрипта, можно выполнить освобождение netgraph нод,
которые оставляет за собой упавший в "корку" MPD3.
#!/bin/sh
for j in "" 1 2 3 4 5 6 7 8 9 10 11 12; do
for i in 0 1 2 3 4 5 6 7 8 9; do
echo $j$i
ngctl shutdown ng$j$i:
ngctl shutdown mpd$1-pptp$j$i:
done
done
Дано:
Есть hostA, который воткнут в каталист, в trunk (т.е. тегированный) порт, инкапсуляция 802.1q.
Есть hostB, который маршрут до hostA. маршрут живой, ip-пакеты между хостами безпроблемно бегают.
Задача: надо с hostA "притащить" виланы на hostB.
Решение: vtund + bridge.
описание клиента в vtund.conf
homepeer {
passwd qwerty;
type ether;
device home;
proto tcp;
compress yes;
stat yes;
persist yes;
up {
ifconfig "%% up";
program "brctl addbr br0";
program "brctl addif br0 %%";
program "brctl addif br0 eth0";
ifconfig "br0 up";
};
down {
ifconfig "%% down";
ifconfig "br0 down";
program "brctl delbr br0";
};
}
описание пира из конфига сервера
homepeer {
passwd qwerty; # Password
type ether; # Ethernet tunnel
device work; # Device tap1
proto tcp;
compress yes;
up {
ifconfig "%% up";
};
down {
ifconfig "%% down";
};
}
Теперь на той Linux машине, куда кидаем порт:
vconfig set_name_type VLAN_PLUS_VID_NO_PAD
vconfig add work 4
ifconfig vlan4 10.1.1.1 netmask 255.255.255.0 up
vconfig add vlan4 8
ifconfig vlan8 192.168.1.1 netmask 255.255.255.0 up
Замечание:
Клиент - хост, с которого мы тащим порт. Он живёт в серой сети и имеет выход в internet через NAT.
Сервер - машина с публичным ip.
Было дано:
- Домен на Windows2003 с поднятым Kerberos.
- FreeBSD на шлюзе, куда должны были подключаться пользователи.
- VPN-демон mpd.
Задача: заставить mpd брать пароли из домена.
Решение:
- Ставим третью самбу с поддержкой кербероса.
- Настраиваем керберос
- Подсоединяем самбу в домен.
- Оставляем от нее только winbindd
- Ставим freeradius.
- Сцепляем радиус с самбой.
- Скручиваем mpd с радиусом и настраиваем сам mpd.
Итог: управляем учетными записями VPN-пользователей через обычные средства AD,
а не пишем руками данные в файл.
Примечание1. Документация гласит, что можно связать радиус с керберосом.
То есть теоретически можно отказаться от самбы. Я так не делал,
поскольку подцепить через самбу мне лично было проще.
Примечание2. Если использовать poptop, то можно не использовать
радиус, а использовать ntlm_auth из самбы. Тоже вариант.
Файлы конфигурации: http://www.opennet.ru/base/net/mpd_win2003.txt.html
Автор: Алексей Гнедин
Редактор: Олег Сафулин
Используемое ПО: pptp-1.6.0.tgz , OpenBSD 3.8 (GENERIC)
Особенности данного подключения состоят в том ,что VPN сервер разрешает подключатся
только с авторизацией MSChapV2, и явно включённым шифрованием MPPE 128 STATELESS.
cd /etc/ppp
vi /etc/ppp/ppp.conf
Добавляем следующие строки:
default:
set log Phase Chat LCP IPCP CCP tun command
pptp1:
set device "!/usr/local/sbin/pptp IPADDR_VPN_SERVER --nolaunchpppd"
set log Phase LCP IPCP CCP tun command
disable acfcomp protocomp
deny acfcomp
enable lqr
set lqrperiod 5
set cd 5
set redial 30
set timeout 0
set authname <username>
set authkey <userpass>
set dial
set login
add! default HISADDR
enable mssfixup
disable ipv6cp
accept MSChapV2
set mppe 128 stateless
Далее:
touch /etc/hosname.tun0 ; vi /etc/hostname.tun0
Добавляем следующие строки:
!/usr/sbin/ppp -ddial pptp1 >/dev/null 2>&1
sysctl -w net.inet.gre.allow=1
reboot
После загрузки машина автоматически соединится с VPN сервером.
Пусть имеется 2 машины PC1 (FreeBSD, ip-адрес IP1, интерфейс INT1) и PC2 (Linux, IP2, INT2).
Для построения IP-IP туннеля (на стороне FreeBSD будет адрес TUN1, Linux - TUN2):
bsd# nos-tun -t /dev/tun0 -s TUN1 -d TUN2 -p 4 IP2
bsd# ifconfig tun0 mtu 1500
bsd# ifconfig tun0 up
linux# ip tunnel add tun0 mode ipip remote IP1 local IP2 dev INT2
linux# ifconfig tun0 TUN2 pointopoint TUN1
linux# ifconfig tun0 mtu 1500
linux# ifconfig tun0 up
1) Собрать ядро с "pseudo-device gif"
2) В /etc/rc.conf добавить в список сетевых интерфейсов gif0
3) В /etc создать файл под именем start_if.gif0 и сделать ему chmod +x
4) Вставить в файл примерно следующее содержание:
#!/bin/sh
/sbin/ifconfig gif0 create inet virtual-local-ip virtual-remote-ip\
netmask 255.255.255.252 tunnel source-addr remote-addr mtu 1500 up
/sbin/route add default your-default-router
/sbin/route add -net localnetwork-at-remote virtual-remote-ip
Запуск на сервере, куда будем соединятся с клиента:
washin% zebedee ╜s
Телнет сессия с клиента:
isshin% zebedee 9000:washin:telnet
telnet localhost 9000
или одной командой:
zebedee ╜e "telnet localhost %d" washin
Необходимо установить из портов пакет pptpclient
/etc/ppp/ppp.conf
vpn:
set authname <LOGIN>
set authkey <PASSWORD>
set timeout 0
set ifaddr 0 0
add default HISADDR
Подключение к VBN серверу:
/sbin/route add -host <IP_address_of_VPN_server> <gateway>
/usr/local/sbin/pptp <IP_address_of_VPN_server> vpn &
Например, для доступа к syslog UDP порту через TCP соединение (клиент):
nc -l -u -p syslog | nc localhost 2000
Обратное преобразование (сервер):
nc -l -p 2000 | nc localhost -u syslog
В итоге можно организовать TCP туннель (например через SSH) для проброса информации для syslog.
Никогда не обращал внимание на такую особенность sip.conf, случайно заметил, что если делать
------ cut ------
[100](!)
context=100
secret=cdm13m-0r9j345
type=friend
host=dynamic
nat=yes
disallow=all
allow=ulaw
[200](100)
context=200
secret=014nm015m9g-f,138n
------ cut ------
, то 200 сможет зарегистрироваться, а 100 - нет, и в sip show peers его тоже не будет,
он может использоваться только как шаблон.
Правильный вариант будет таким:
------ cut ------
[simple-template](!)
type=friend
host=dynamic
nat=yes
disallow=all
allow=ulaw
[100](simple-template)
context=100
secret=cdm13m-0r9j345
[200](simple-template)
context=200
secret=014nm015m9g-f,138n
------ cut ------
То есть отдельно создается шаблон, и отдельно пиры/френды.
// Шаблоны в Asterisk IP PBX используются не только в sip.conf, но и в других конфигурационных файлах.
См. http://www.voip-info.org/wiki/view/Asterisk+config+template и далее по ссылкам.
Не смотря на то, что в EeePС нет встроенного bluetooth адаптера,
к нему легко можно подключить внешний bluetooth брелок с USB интерфейсом.
Все необходимые консольные приложения доступны после установки пакета:
apt-get install bluez-utils
К сожалению для eeepc отсутствуют GUI хелперы для связывания устройств,
из того что есть в репозиториях debian etch и xandros (например kdebluetooth),
из-за проблем с зависимостями пакетов, подходит только bluez-gnome.
Если bluetooth устройство самостоятельно может инициировать связывание,
то все нормально, если нет - при попытке связать устройства используя только консольные
средства начинаются проблемы, в bluez 3.x был изменен механизм связывания устройств,
если ранее достаточно было создать простой скрипт для вывода PIN и прописать в options
секцию hcid.conf - "pin_helper /etc/bluetooth/feed-pin.sh;", то теперь для получения PIN
используется DBUS. В комплекте с bluez поставляется программа passkey-agent,
предназначенная для связывания устройств, в пакет bluez-utils в Debian GNU/Linux эта программа
по каким-то соображениям не была включена. Исходные тексты программы можно найти в
/usr/share/doc/bluez-utils/examples, но для сборки потребуется установка окружения для сборки программ,
что в условиях небольшого SSD диска не вполне оправдано. Запускается агент примерно так:
passkey-agent --default 1234
где, 1234 пароль для связывания.
Выход нашелся в апплете bluetooth-applet, который входит в состав пакета bluez-gnome.
Запустив который при попытке связывания появляется диалоговое окно для ввода пароля связывания.
Для настройки GPRS через сотовый телефон с Bluetooth интерфейсом можно использовать пакет 3egprs
(устанавливает иконку на десктоп и скрипт /usr/sbin/gprsconf) с сайта http://www.3eportal.com/
Другой вариант - инициирование ppp сессии из консоли. Ниже пример настройки:
Подключаем bluetooth адаптер в USB порт. Через dmesg смотрим, нашелся ли дня него драйвер.
Запускаем инициализацию bluez:
/etc/init.d/bluetooth start
Смотрим поднялся ли интерфейс:
hciconfig
Если статус down, поднимаем его:
hcicofig hci0 up
Сканируем доступные устройства:
hcitool scan
Запоминаем адрес устройства. Для примера проверяем его доступность:
l2ping 00:0A:0B:0C:0D:0E
Адрес можно посмотреть командой:
hcitool dev
а определить поддерживаем ли bluetooth устройство GPRS:
sdptool search DUN
Создаем rfcomm интерфейс:
rfcomm bind 0 [полученный адрес] 1
По идее rfcomm должен создаться автоматически, при надлежащей настройке /etc/bluetooth/rfcomm.conf,
например:
rfcomm0 {
bind yes;
device 00:0A:0B:0C:0D:0E;
channel 1;
comment "Mobile";
}
Далее создаем файл конфигурации для pppd, /etc/ppp/peers/mts:
lcp-echo-failure 0
lcp-echo-interval 0
/dev/rfcomm0
connect "/usr/sbin/chat -v -f /etc/ppp/peers/gprs"
115200
crtscts
debug
ipcp-accept-local
noauth
usepeerdns
defaultroute
noipdefault
nodetach
/etc/ppp/peers/gprs:
ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT
'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED
'' 'AT'
'OK' 'AT+CGDCONT=1,"IP","internet.mts.ru"'
'OK' 'ATDT*99***1#'
TIMEOUT 30
CONNECT
Для beeline заменяем "internet.mts.ru" на "internet.beeline.ru", для мегафона пишем просто "internet".
Подключаемся выполнив команду:
pppd call mts
Перевод wiki-страницы о настройке Bluetooth в Asus EeePC, выполненный
Сгибневым Михаилом,
можно найти на странице: http://www.opennet.ru/base/modem/bluetooth_eeepc.txt.html
0. Создание пользователя jabber из группы jabber
#adduser
1. Установка Jabber думую не вызывает проблем - в портах /usr/ports/net-im/jabberd
#make install clean
2. Настройка
Можно ниче не менять и оставить все поумолчанию,но желательно изменить в файлах
/usr/local/etc/jabberd/sm.xml
/usr/local/etc/jabberd/c2s.xml
Если сервер будет не только для локальной сети, а со связью с глобальными, то также меняем в
/usr/local/etc/jabberd/s2s.xml
/usr/local/etc/jabberd/resolver.xml
Если нет то можно закоментить в jabber.cfg эти части
меняем имя сервера, и пароль (хотя можно и не менять)
id имя сервера - это то что после @ =) может быть любое (по умолчанию localhost)
user имя для router.xml (jabberd)
pass пароль тоже для router.xml (secret)
Еще проблемы были с паролем в файле router-users.xml - если везде поменяли, то и здесь не забудьте
3. Настройка БД
по умолчанию используется MySQL, ниче менять не будем.
заходим под рутом в MySQL и запускаем скрипт (должны находиться в папке со скриптом /usr/local/share/jabberd)
mysql -u root -p
mysql>\. db-setup.mysql
добавляем пользователя (jabberd2) БД и пароль (secret) к нему
GRANT select,insert,delete,update ON jabberd2.* to jabberd2@localhost IDENTIFIED by 'secret';
если изменили, не забудьте изменить и в sm.xml
на всякий случай делаем ссылку
ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
Попробуйте запустить - заходим под jabber и набираем
>jabberd
В /var/logs/messages смотрим результат - должно быть реди
если не запустился,то гдето косяк,запускаем в отладочном режиме
>jabberd -D
смотрим на чем сервер умирает и исправляем
4. Установка users-agent
/usr/ports/net-im/jabber-users-agent
#make install clean
5. Настройка users-agent
в /usr/local/etc/ опять изменяем конфиг имя,пароль,имя БД(jud),пароль БД(jud)
6. Настройка БД
можно наверно запустить скрипт,но говорят он не работает,поэтому пишем сами
CREATE DATABASE JUD;
GRANT ALL PRIVILEGES ON JUD.* to jud@localhost IDENTIFIED BY 'jud';
CREATE TABLE JUD.jud (jid VARCHAR(100) PRIMARY KEY, name VARCHAR(100),
first VARCHAR(50), last VARCHAR(50),nick VARCHAR(50),
email VARCHAR(50), INDEX ind_name (name), INDEX ind_first (first),
INDEX ind_last (last), INDEX ind_nick (nick),
INDEX ind_email (email));
7. Все запускаем из под пользователя jabber - сначала сам джаббер-сервер
>jabberd
можно в фоновом режиме с параметром -B
Потом users-agent
в папке /usr/local/lib/jabber/users-agent
>./users-agent
Все проверяйте в PSI - создавать аккаунты и пытаться найти себя=)
Какие были у меня проблемы:
Читал всякие вики и ртфм и запутался=) :
а)Проблемы с правами доступа, так как запускать можно только от
пользователя Jabber,не забудьте для конфигов поставить права доступа
б)Исправление файла router-users.xml - нигде вроде не встречал, поэтому и не исправлял
в)Устанавливать надо jabber-users-agent, а не jabber-JUD =)
г)Перловский скрипт запускается с ./ =)
д)Если был до другой джаббер сервер все сносите деинсталом и подчищайте вручную
Вообщето все лежит на
http://jabberd.jabberstudio.org/2/docs/jabberd_guide.html
но там много и на английском.И еще помогло
http://ru.gentoo-wiki.comНастройка_JUD_на_сервере_Jabberd_версии_2.x
В /etc/hosts.allow (man hosts_access;man hosts_options):
# IP в REMOTE_ADDR
popa3d: ALL : setenv REMOTE_ADDR %a : allow
# имя хоста в REMOTE_ADDR
popa3d: ALL : setenv REMOTE_ADDR %h : allow
В программе IP адрес получаем через getenv("REMOTE_ADDR").
Иногда нужно узнать какому производителю принадлежит оконечное оборудование,
наблюдая только его мак на интерфейсе. А открывать браузер для этого лениво.
В таком случае удобно создать MAC-based dns лист. Пользоваться просто:
ket:/home/sva# host -t txt 001243.macl.nov.ru
001243.macl.nov.ru descriptive text "Cisco"
ket:/home/sva# host -t txt 0050ba.macl.nov.ru
0050ba.macl.nov.ru descriptive text "D-LINK"
Предположим, вы провайдер (provider1) и подключившийся к вам клиент (firma1) взял в пользование сеть /28
Как обеспечить ему самостоятельное управление обратными доменами в его подсети?
Можно делигировать ему неполную сеть, на примере:
У вас есть большая сеть 200.100.100.100/24, клиент из нее взял себе блок 200.100.100.176/28
В своем файле зоны прописываете:
100.100.200.in-addr.arpa IN SOA ns1.provider1.ru. hostmaster.provider1.ru. (
2005102000 ; serial
36000 ; refresh
3600 ; retry
1728000 ; expire
172800 ; minimum
)
NS ns1.provider1.ru.
NS ns2.provider1.ru.
$ORIGIN 100.100.200.in-addr.arpa.
...
173 PTR client173-gw.provider1.ru.
174 PTR client174-gw.provider1.ru.
175 PTR client175-gw.provider1.ru.
176/28 NS ns.firma1.ru.
$GENERATE 176-191 $ CNAME $.176/28
192 PTR client192-gw.provider1.ru.
193 PTR client193-gw.provider1.ru.
Админ клиента на своем NS'е (ns.firma1.ru) создает
зону "176/28.100.100.200.in-addr.arpa" , в которой спокойно
администрирует свои IP'ы, не отвлекая провайдера от работы.
Если bind 9 одновременно является переадресующим сервером ( forwarders { s.o.m.e; }; ) и авторитативным
для какой-либо зоны, при делегировании подзоны возникает проблема резолвинга хостов этой подзоны:
subzone IN NS ns.subzone.zone.tld.
ns.subzone IN A 192.168.0.1
dig @ns.zone.tld. somehost.subzone.zone.tld. a
при этом бинд будет спрашивать запись A для хоста somehost.subzone.zone.tld. вовсе не у ns.subzone.zone.tld. ,
а у тех серверов, которые прописаны форвардерами в options!
Чтобы bind резолвил хосты напрямую, через ns.subzone.zone.tld. , необходимо в конфигурации зоны zone.tld. прописать:
zone "zone.tld." {
type master;
---> forwarders { /* empty! */ };
notify no;
file "file";
allow-query { any; };
allow-transfer { s.o.m.e; };
};
Проблемы на IPv4 хостах без IPv6 коннективити, обусловлены появлением IPv6 адресов у B и A корневых NS.
Решение представлено в BIND 9.2.5 и 9.3.1, которые еще не вышли.
Другой путь - собрать bind с ./configure --disable-ipv6 или запустить с опцией -4 (для bind 9.3.0).
Генерируем ключи:
dnssec-keygen -a HMAC-MD5 -b 512 -n USER foo22.bar44.com.
Настройки сервера:
/etc/named.conf:
include "keys.conf";
......
zone "bar44.com" {
type master;
file "bar44.com.zone";
update-policy {
grant laptop.bar44.com. name laptop.bar44.com. A TXT;
grant foo22.bar44.com. subdomain bar44.com. ANY;
};
# или
#allow-update {
# key foo22.bar44.com.
#};
};
/etc/namedb/keys.conf:
key foo22.bar44.com. {
algorithm HMAC-MD5;
secret "секретный ключ";
};
Для обновления зоны:
nsupdate -k Kfoo22.bar44.com.+157+12505.private -v cmd_file.txt
Пример cmd_file.txt:
server ns.bar44.com
zone bar44.com
update delete somehost.bar44.com. A
update add somehost.bar44.com. 86400 A 10.10.10.1
show
send
В /etc/resolv.conf:
options attempts=2, timeout=2, rotate
,где attempts - число попыток посылки запроса к серверу.
timeout - таймаут запроса (по умолчанию 5 сек.)
rotate случайный выбор nameserver из списка, а не опрос по порядку.
timeout - таймаут за который сервер должен успеть ответить.
Для отладки удобно использовать "options debug"
options {
# Если "first" - то если forwarders не ответил - запрашиваем сами.
# Если "only" - сами никогда не запрашиваем, только через forwarders.
forward only;
forwarders {192.168.1.1; 192.168.2.1;};
};
Узнать версию можно через:
dig @ns.test.ru version.bind chaos txt
Чтобы запретить, нужно в options блоке named.conf прописать:
options {
...
version "0.1";
};
Цель - отделить пользователей из /etc/passwd от пользователей ftp,
но не устанавливая различных внешних средств для хранения базы пользователей.
Из целого ряда ftp-серверов я остановился на pure-ftpd.
Вариант запуска был найден быстро, но при этом сервер должен был запускаться средствами (x)inetd:
$ grep pure /etc/inetd.conf
ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/pure-ftpd-virtualchroot -4 -A -E -d -lpuredb:/etc/pure-ftpd/pureftpd.pdb
Сделал так на другом сервере и понял, что у меня там нет inetd.
Устанавливать не стал. Решил сделать сервис standalone.
# dpkg-reconfigure pure-ftpd-common
Конечно, однострочные конфиги, раскиданные по разным файлам,
могут вызвать отторжение у сторонников другого подхода, но сейчас не об этом.
# /etc/init.d/pure-ftpd restart
Restarting ftp server: Running: /usr/sbin/pure-ftpd-virtualchroot -l pam -d -4 -u 1000 -A -E -O clf:/var/log/pure-ftpd/transfer.log -B
Выключаю pam и включаю puredb
# rm /etc/pure-ftpd/conf/PAMAuthentication /etc/pure-ftpd/auth/70pam
# ln -s ../conf/PureDB /etc/pure-ftpd/auth/45puredb
Работа с учетными записями производится посредством pure-pw.
В заключение, пример рабочей конфирурации:
$ grep -r . /etc/pure-ftpd/*/
/etc/pure-ftpd/auth/45puredb:/etc/pure-ftpd/pureftpd.pdb
/etc/pure-ftpd/auth/65unix:no
/etc/pure-ftpd/conf/UnixAuthentication:no
/etc/pure-ftpd/conf/VerboseLog:Yes
/etc/pure-ftpd/conf/IPV4Only:Yes
/etc/pure-ftpd/conf/MinUID:10000
/etc/pure-ftpd/conf/ChrootEveryone:Yes
/e tc/pure-ftpd/conf/NoAnonymous:yes
/etc/pure-ftpd/conf/PureDB:/etc/pure-ftpd/pureftpd.pdb
/etc/pure-ftpd/conf/AltLog:clf:/var/log/pure-ftpd/transfer.log
На моей станции поднят ftp сервер (vsftpd). Как известно FTP cервер позволяет расшарить
определённую директорию (в нашем случае /var/ftp/)/ Часто у меня возникали ситуации
когда нужно что то расшарить по сети, а копировать это в раздел где расшаренная
директория - места нет. Да и копировать это опять же или менять кофиг сервера и перерапускать сервис.
Для себя нашёл очень простой и удобный способ как это сделать.
Монтировать нужные директории в дерево /var/ftp используя 'mount --bind '. всё просто.
[root@n100851 ~]# mkdir /var/ftp/pub/music
[root@n100851 ~]# mount --bind /home/user/media/sound/ /var/ftp/pub/music/
и всё. анонимусы могут забирать музыку с FTP сервера.
Допустим у нас есть сеть 192.168.0.0/24, с которой надо что-то разрешить, а для остальных - запретить.
Редактируем файл /etc/hosts.allow
vsftpd: 192.168.0.0/255.255.255.0, 127.0.0.1: setenv VSFTPD_LOAD_CONF / etc/vsftpd-int.conf : nice 15
vsftpd: ALL : nice 15
В результате при коннекте из нашей сети будет выполняться конфиг /etc/vsftpd-int.conf,
а при коннекте из остальных сетей - /etc/vsftpd.conf
Ну а прописать в разных конфигах разные фичи я думаю проблем не составит.
У меня так регулируется скорость:
cat /etc/vsftpd-int.conf
...тут пропущен здоровый кусок конфига
# Этот конфиг для внутренних нужд - скорость по максимуму
anon_max_rate=0
local_max_rate=0
cat /etc/vsftpd.conf
...тут пропущен здоровый кусок конфига
anon_max_rate=32000
local_max_rate=64000
/etc/vsftpd.conf:
# Запускаем как демон, а не из inetd.
listen=YES
background=YES
listen_address=192.168.1.1
# Включаем возможность использования tcpwrapper, лимиты через /etc/hosts.allow
tcp_wrappers=YES
# Пускаем только пользователей имеющих валидный shell, присутствующий в /etc/shells
check_shell=YES
# Вместо реальных владельцев файлов всегда показываем ftp:ftp
hide_ids=YES
# Общее максиамльно допустимое число коннектов.
max_clients=100
# Разрешенное число коннектов с одного IP.
max_per_ip=5
# Таймаут при ожидании команды
idle_session_timeout=300
# Таймаут при передаче данных
data_connection_timeout=60
# Непривилегированный пользователь, для того чтобы делать под ним, что можно выполнить без root.
nopriv_user=ftp
# Запрещаем рекурсивный вызов "ls -R"
ls_recurse_enable=NO
# Ограничение скорости прокачки для анонимных и локальных пользователей (байт в сек.)
anon_max_rate=50000
local_max_rate=100000
# Включаем ведение лога операций.
xferlog_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
# Расширенные логи всех команд
log_ftp_protocol=YES
# ------------ Настрйоки для анонимного сервера
# Если сервер публичный, пускающий анонимных пользователей
anonymous_enable=YES
anon_umask=077
# Корень анонимного ftp архива
anon_root=/usr/local/ftp
# Запрещаем анонимным пользователям запись данных, если нужно разрешить
# запись для локальных пользовтелей (write_enable=YES)
anon_upload_enable=NO
# Запрещаем создавать директории.
anon_mkdir_write_enable=NO
# Запрещаем переименовывать и удалять
anon_other_write_enable=NO
# Если нужно запретить доступ к определенным типам файлов по маске
# deny_file={*.mp3,*.mov, *.avi, .filelist}
# Если нужно скрыть определенные типы файлов при выводе списка,
# но дать скачать тем кто знает точное имя.
# hide_file={*.mp3,*.mov, *.avi}
# Если анонимную закачку необходимо разрешить, нужно дополнительно
# использовать chown_uploads=YES и chown_username=ftp_anon_user
# Если нужно пускать анонимных пользователей только при правильном введении
# email (аналог паролей для ограничения доступа к публичному ftp), заданного в
# файле определенном директивой email_password_file, нужно установить
# secure_email_list_enable=YES
# ------------ Настрйоки для входа локальных пользователей
# Если сервер разрешает вход локальных пользователей, присутствующих в системе
local_enable=YES
# "-rw-r--r--"
local_umask=022
# Разрешаем показ файлов начинающихся с точки (например, .htaccess) для кривых ftp-клиентов
force_dot_files=YES
# Разрешаем пользователям записывать/изменять свою информацию на сервер.
# если нужно запретить запись данных - write_enable=NO
# Более тонкий тюнинг через "cmds_allowed=PASV,RETR,QUIT"
write_enable=YES
# Для всех пользователей делаем chroot, делаем корнем их домашнюю директорию,
# Список логинов для которых не нужно делать chroot задаем в vsftpd.chroot_list
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd.chroot_list
# Активируем список пользователей которым запрещен вход по FTP (например, root)
userlist_enable=YES
userlist_file=/etc/ftpusers
Необходимо выпустить пользователей на ftp сайты из локальной сети, но при этом не устанавливая
дополнительного ПО, используя только возможности FreeBSD 4.10.
Этими возможностями, как ни странно, оказались ipfw и natd
вот собственно как все это прописывается.
Исходные данные, FreeBSD 4.10 + настроенный nat правила для ipfw
ipfw -q add 100 divert natd from 192.168.20.0/24 to any 20, 21 out via $oif
ipfw -q add 200 divert natd from any 20, 21 to $iip in via $oif
ipfw -q add 300 allow tcp from any to any established
ipfw -q add 400 allow tcp from any to any setup
где $oif и $iip соответственно внешний интерфейс и внешний IP
теперь запускаем natd
/sbin/natd -m -s -u -punch_fw 500:200 -n xl1
заострю внимание на параметре "-punch_fw" -этот параметр создает в фаерволе "ходы",
добавляя динамические правила. В моем случае эти правила начнутся с номера 500 и будет их добавлено
максимум 200 (понятно чем больше сеть, те больше нужно правил).
Особое спасибо A Clockwork Orange.
В ipnat воспользуйтесь модулем ftp proxy:
map fxp0 0/0 -> 0/32 proxy port ftp ftp/tcp
map rl0 172.16.33.0/24 -> 212.46.231.50/32 proxy port ftp ftp/tcp
не забудьте поместить правило трансляции ftp перед общим правилом трансляции,
порядок следования правил важен.
Проверка подлинности получателя сообщений
Sendmail + LDAP_ROUTING + AD + Exchange 2000/2003
Исходные данные:
AD на базе Win 2003, Exchange Server 2003 расположенный в корпоративной сети.
Канал Internet и корпоративную сеть разделяет шлюз в DMZ которого располагается
почтовый релей - сервер на базе FreeBSD + Sendmail.
Задача:
При попытке отправки письма пользователями Internet пользователям Exchange сервера,
проверять подлинность адреса получателя, тем самым сократив почтовый трафик
и избавиться от ненужных NDR (Non-Delivery Report) сообщений.
Действия:
Завести в AD служебную учётную запись, от которой будут осуществляться запросы в LDAP каталог.
Пример:
Пользователь: CN=LDAP_Searcher,OU=Service Accounts,DC=mydomain,DC=com
Пароль: password
Собрать Sendmail с поддержкой LDAP
# cd /usr/ports/mail/sendmail-ldap/
# make
# make install
Проверить корректность фильтра, соединения с сервером LDAP каталога (контроллером домена)
Фильтр:
(&(|(objectclass=user)(objectclass=group))(proxyAddresses=smtp:myname@mydomain.com))
Пример запроса:
#ldapsearch -L -x -D "CN=LDAP_Searcher,OU=Service Accounts,
DC=mydomain,DC=com" -w "password" -h "192.168.0.1" -p 389 -s sub -b
"DC=MYDOMAIN,DC=COM" -d "0" "(&(|(objectclass=user)
(objectclass=group))(proxyAddresses=smtp: myname@mydomain.com))"
Где 192.168.0.1 – IP адрес сервера LDAP каталога (контроллера домена).
Результатом работы данной команды мы должны получить полный список всех атрибутов объекта каталога
и их значения, соответствующие пользователю или группе, среди smtp
адресов которого встречается myname@mydomain.com.
Исходя из положительного результата, приступаем к конфигурации Sendmail.
Добавляем в файл sendmail.mc следующие 3 строки:
define(`confLDAP_DEFAULT_SPEC', `-h "192.168.0.1" -b "DC=MYDOMAIN,
DC=COM" -d "CN=LDAP_Searcher,OU=Service Accounts,DC=mydomain,
DC=com" -MLDAP_AUTH_SIMPLE -P/etc/mail/ldap_pass')dnl
LDAPROUTE_DOMAIN_FILE(`/etc/mail/ldap_route_domains')dnl
FEATURE(`ldap_routing', `null', `ldap -1 -T<TMPF> -v mail -k
(&(|(objectclass=user)(objectclass=group))(proxyAddresses=smtp:%0))',`bounce')dnl
Собираем sendmail.cf
/usr/bin/m4 /usr/share/sendmail/cf/m4/cf.m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
Содаём файл /etc/mail/ldap_pass, содержимым которого является пароль служебной
учётной записи LDAP_Searcher в открытом виде. В нашем случае:
password
Создаём файл /etc/mail/ldap_route_domains, содержимым которого является:
mydomain.com
Запускаем Sendmail.cf
Внимательно проверяем результат.
Ниже настройки для fetchmail для забора почты с группового почтового ящика
и распределения ее по локальным ящикам пользователей.
/usr/local/etc/fetchmailrc
set daemon 905
defaults
set logfile /var/log/fetchmail/fetchmail.log
poll mx2.yyyyyyy.od.ua
proto pop3
envelope X-Envelope-To localdomains yyyyyyy.od.ua
user "halo"
pass "qwerty"
is root
nokeep
fetchall
flush
smtpaddress smtp.xxxxx.odessa.ua
fetchdomains yyyyyyy.od.ua
is "*" = to "*"
norewrite
smtphost 127.0.0.1
##############
chmod 710 /usr/local/etc/fetchmailrc # выставляем привелегии для конфига
chown fetchmail:wheel /usr/local/etc/fetchmailrc # выставляем владельца и группу конфига
echo 'fetchmail_enable="YES"' >> /etc/rc.conf # прописываем для старта в rc.conf
/usr/local/etc/rc.d/./fetchmail start # запускаем демона
set daemon 905 - проверять ящик каждые 905 сек.
mx2.yyyyyyy.od.ua - имя сервера, откуда почту забираешь
yyyyyyy.od.ua - твой домен
halo - логин на ящике и ниже его пароль
smtp.xxxxx.odessa.ua - smtp провайдера или твой релей
Сортируется по заголовкам "X-Envelope-To"
Есть Postfix + авторизация пользователей в mysql. Так вот появилась необходимость почту,
приходящую на какой-нить адрес ещё пересылать кому-угодно. Т.е. не форвардить письмо,
а именно копию отсылать на нужный адрес. Притом хочется чтобы всё было красиво и понятно.
Решение:
Postfix ищет virtual_maps в базе mysql
virtual_maps=hash:/etc/postfix/virtual_maps.cf
virtual_maps.cf содержит запрос который по адресу email выдает alias.
Что-то типа такого:
user = postfix
password = postfix
dbname = mail
table = alias
select_field = goto
where_field = address
hosts = 127.0.0.1
На goto идет почта, которая предназначается для address. Т.е. на один физический maildir
(или другой конечный пункт) собирается почта от разных алиасов.
Проблема в том что при такой конфигурации не сделать так чтобы почта для user@domain.com
шла и на alias1@domain.com и на alias2@domain2.com
После анализа того, как механизм Postfix читает возврат от mysql получаем:
Нужно чтобы почта для локального юзера user@domain.com приходила на user@domain.com + на mail@domain2.com
и + ещё куда нить :) При этом везде должна лежать копия.
Обычно таблица alias содержит вот что:
address goto
email1 email2
email3 email2
...
email5 email_other
Надо сделать так.
address goto
email other_email1,other_email2,...
Т.е. через запятую без пробелом указываем все те адреса куда надо послать копию письма.
hash:/mysql примет строку и КОРРЕКТНО подставит её куда надо, а сам Postfix нормально
всё выставит в очередь сообщений и отправит. Там же указываем адрес локальной доставки.
И всё :) Никаких скиптов, procmail и прочей бурды.
Теперь представьте гибкость и легкость с такими вещами как redirect, forwarding, copy + mysql.
Все делалось на FreeBSD 5.4.
Ставим cyrus-sasl2:
# cd /usr/ports/security/cyrus-sasl2
# make -DWITHOUT_NTLP -DWITHOUT_OTP -DWITH_MYSQL install clean
Ставим postfix:
# cd /usr/ports/mail/postfix
# make install clean
Появится менюшка, где надо выбрать с поддержкой чего собирать, нам нужно минимум SASL2,
жмем ОК и ждем окончания сборки, после:
в файл /usr/local/lib/sasl2/smtpd.conf пишем следующее (ессно заменить информацию о mysql на свою):
pwcheck_method: auxprop
auxprop_plugin: sql
mech_list: sql plain login
sql_engine: mysql
sql_hostnames: localhost
sql_user: postfix
sql_passwd: <li><li>*
sql_database: mail
sql_select: select password from users where login='%u@%r'
sql_verbose: yes
В /usr/local/etc/postfix/main.cf дописываем:
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain =
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject
# postfix reload
После наполняем mysql и все.. авторизация проходит..
Таких статей конечно много, но при всем их количестве - ушло 2 дня что бы собрать рабочую конфигурацию..
то в одной статье опечатка, то в другой вообще уже устаревшая информация..
здесь я обобщил просто то, что получилось именно у меня в конкретном случае..
Последовательность действий для установки POP Before SMTP на popa3d + Postfix
1: cd /usr/ports/mail/popa3d
2: make
3: cd work/popa3d-popa3d-1.0
4: cp ../../files/pop-before-sendmail.patch pop-before-sendmail.patch
5: patch < pop-before-sendmail.patch
правим если нужно params.h
6: make
7: cd ../../
8: make install && make clean
9: cd /etc/mail/ && touch popauth && postmap popauth
Правим main.cf:
10: mynetworks = hash:/etc/mail/popauth
11: postfix reload
Правим inetd.conf
12: pop3 stream tcp nowait/10/5/2 root /usr/local/libexec/popa3d popa3d
перезапускаем inetd.
Иногда после изменений в конфигурации необходимо перезапустить очередь
что бы сообщения в очереди начали обрабатываться заново:
postsuper -r ALL
Для очистки очереди:
postsuper -d ALL
Для предотвращения эффекта игры в "пинг-понг" Postfix добавляет к
каждому полученному сообщению заголовок "Delivered-To:" (изменить
подобное поведение можно через директиву prepend_delivered_header, но
крайне не рекомендуется, из-за возможности появления замкнутых петель).
Если письмо обрабатывает скрипт и затем пересылает на другой email
(например, менеджер почтовых рассылок), оставив поле "Delivered-To:"
в неизменном состоянии, то ложно срабатывает защита.
В качестве решения рекомендуется вырезать заголовок "Delivered-To:"
на этапе получения письма в скрипте.
Например:
while (<STDIN>){
if (! /^delivered-to:/i){
....
}
}
- Диалап с фиксированным IP;
- MTA провайдера должен быть MX'ом для domain.com (с прописанным почтовым рутингом и "hold" спулом);
- После выхода в сеть, посылаем команду "ETRN domain.com", которая приведет к инициированию
процесса отправки сообщений из спула для domain.com:
echo -e "HELO dial.domain.com\nETRN domain.com\nQUIT\n"| nc relay.domain.com 25
postsuper -d <id> deferred (-d ALL - удалить все сообщения из очереди)
Для удаления группы писем от определенного адресата, можно использовать:
mailq|grep 'test@test.ru'|awk '{print $1}'|xargs -J{} -n1 postsuper -d {} deferred
man 5 canonical (см. canonical_map, recipient_canonical_maps, sender_canonical_maps)
main.cf:
canonical_maps = regexp:/etc/postfix/canonical_regexp
canonical_regexp:
/^.*!(.*)!(.*)$/ $2@$1
/^([^!]+)!([^@]+)@.*$/ $2@$1
Преобразуем из вида uutest6!uutest6.uucp.test.ru!user318 в вид user318@uutest.uucp.test.ru
в sendmail.cf: DSesmtp:[relay.somehost.ru]
или для m4 скриптов:
define(`SMART_HOST',`relay.somehost.ru')dnl
или для игнорирования MX значения (далее в квадратных скобках):
define(`SMART_HOST',`[relay.somehost.ru]')dnl
Для описания пути транспортировки почты (почтового роутинга) для определенных доменов:
FEATURE(`mailertable', `hash /etc/mail/mailertable')dnl
/etc/mail/mailertable
domain1 esmtp:relay1.somehost.ru
domain2 smtp:[relay2.somehost.ru]
Для отправки почты для test.ru только через relay2.test.ru в обход MX:
main.cf:
transport_maps = hash:/usr/local/etc/postfix/transport
transport:
test.ru :[relay2.test.ru]
Для того чтобы всю почты пересылать через релэй,
нужно использовать в main.cf опцию relayhost
Postfix:
luser_relay = vasia@pupkin.org
Или, для виртуального домена в virtual, перенаправим всю почту для домена test.ru на vasia@pupkin.org, в viruals :
test.ru test.ru
@test.ru vasia@pupkin.org
Sendmail, используя m4:
define(`LUSER_RELAY',`mail.somehost.ru') # перенаправление на почтовый сервер
define(`LUSER_RELAY',`local:pupkin') # перенаправление локальному пользователю.
Ситуация:есть Postfix выставленный в Интернет,который допустим выступает шлюзом для Exchange в LAN.
Задача: разрешить отправку почты в Интернет и обратно только определенным пользователям.
Выход: используем классы разрешений, Postfix restriction classes.
Создаем два класса users_out для исходящих писем,users_in соответственно для входящих.
smtpd_restriction_classes = users_out, users_in
В классах будут проверятся пользователи которым разрешено отправлять и получать почту,
именно этим и занимаются правила check_*_access
users_in = check_recipient_access hash:/etc/postfix/users, reject
users_out = check_sender_access hash:/etc/postfix/users, reject
В smtpd_*_restrictions указываем проверку на наш почтовый домен domain.ru
к которому будет применяться созданные классы.
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/senders
smtpd_recipient_restrictions = permit_mynetworks,
check_recipient_access hash:/etc/postfix/destinations,
reject_unauth_destination
Файл destinations с нашим доменом и указанием классов которые будут применятся к ним у
domain.ru users_in
Содержимое файла senders
domain.ru users_out
Файл users со списком пользователей которым разрешено отправлять и получать почту
test@domain.ru OK
boss@domain.ru OK
billy@domain.ru OK
Итог: Имеем конфигурацию с помощью которой можем разрешать пересылку определенным пользователям на определенные наши домены.
Статья о том как сделать sasl на postfix'е и убедиться в его работоспособности.
Задача:
Установить sasl и postfix и сделать авторизацию вида:
1) отправлять письма могут только пользователи системы (/etc/passwd).
2) все остальные не пропускать.
Система: FreeBSD 7.0
Установка:
1) /usr/ports/secutiry/cyrus-sasl2
[+] AUTHDAEMOND
[+] LOGIN
[+] PLAIN
make install clean
(если программы уже были установлены то повторно вызвать меню опций при установке можно командой make config)
2) /usr/ports/security/cyrus-sasl2-saslauthd
make install clean
3) создаем и редактируем /usr/local/lib/sasl2/smtpd.conf:
pwcheck_method: saslauthd
mech_list: plain login
далее добавляем в /etc/rc.conf:
saslauthd_enable="YES"
saslauthd_flags="-a pam"
4) Теперь постифкс
/usr/ports/mail/postfix
[+]SASL2
make install clean
при установке на все вопросы ответить утвердительно "y"
5) теперь мини-рабочий конфиг постфикса:
/usr/local/etc/postfix/main.cf
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
mail_owner = postfix
myhostname = host.domain.ru
mydomain = domain.ru
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
smtpd_sasl_auth_enable = yes
smtpd_security_options = noanonymous
smtpd_client_restrictions =
permit_sasl_authenticated,
reject_plaintext_session
smtpd_sender_restrictions =
permit_sasl_authenticated,
reject_plaintext_session
(!!! Внимание, господа, эта статья требует чтобы в конфиге postfix не было упоминаний mynetworks)
6) Теперь просто в консоли из под рута
newaliases
эта команда создаст файл /etc/aliases.db необходимый для постфикса
7) Для тестирования желательно иметь php на машинке потому как sasl механизм login и plain используют
технологию шифрования base64 и для обработки "руками" логина и пароля нужно будет написать скриптик:
<?php
print base64_encode("логин");
print "\n";
print base64_encode("пароль");
print "\n";
?>
P.S. (Кому интересно plain это base64_encode("логин\0логин\0пароль");)
тоже самое на Perl:
perl -e 'use MIME::Base64; print encode_base64("логин") . "\n" .encode_base64("пароль"). "\n"'
8) Перезагружаем postfix
Тестирование SASL.
1) тестирование "руками":
telnet айпиадрес 25
оно оветит:
220 host.domain.ru ESMTP Postfix
говорим ему:
ehlo host
(где host -имя машины)
оно ответит:
220 host.domain.ru ESMTP Postfix
250-host.domain.ru
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
если есть строка 250-AUTH LOGIN PLAIN - то значит есть вероятность успеха.
теперь заходим без авторизации и смотрим как наше сообщение не проходит:
mail from: user@domain.ru
оно:
250 2.1.0 Ok
мы:
rcpt to: user2@domain.ru
оно:
554 5.7.1 <user2@domain.ru>: Relay access denied
- значит все отлично нас не пустили просто так.
напечатайте
quit
и теперь идем с регистрацией:
telnet айпиадрес 25
220 host.domain.ru ESMTP Postfix
ehlo host
250-host.domain.ru
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
теперь вводим:
auth login
оно скажет нам сообщение вида:
334 VXNlcm5hbWU6
теперь запускаем, предварительно заполнив, тот скриптик который был указан выше
и вводим наш логин зашифрованный base64 в ответ на последнее сообщение.
у меня это:
cGVuc2U=
на что сервер ответил
334 UGFzc3dvcmQ6
теперь пароль в том же виде:
cnZpZGlh
на что оно нам ответит если все было правильно:
235 2.0.0 Authentication successful
вот оно - авторизация пройдена.
теперь соответственно
mail from:
rcpt to:
data
hello world
.
quit
все. письмо отправлено.
Пример введения ограничений на прием внешней почты для определенных адресов.
В конкретном примере, пользователь с адресом test@domain.com имеет право на прием и передачу сообщений
только в пределах domain.com. Ни написать на другие адреса, ни принять почту с них он не может.
Остальные пользователи спокойно пишут куда хотят и получают почту с любых адресов.
/etc/postfix/main.cf:
smtpd_recipient_restrictions = hash:/etc/postfix/protected_destinations,
check_sender_access hash:/etc/postfix/restricted_senders,
permit_sasl_authenticated, permit_auth_destination, reject
smtpd_restriction_classes = local_only, insiders_only
local_only = check_recipient_access hash:/etc/postfix/local_domains, reject
insiders_only = check_sender_access hash:/etc/postfix/local_domains, reject
В /etc/postfix/restricted_senders:
test@domain.com local_only
test@mail.domain.com local_only
В /etc/postfix/local_domains:
domain.com OK
mail.domain.com OK
В /etc/postfix/protected_destinations:
test@domain.com insiders_only
test@mail.domain.com insiders_only
И не забыть потом:
postmap /etc/postfix/restricted_senders
postmap /etc/postfix/local_domains
postmap /etc/postfix/protected_destinations
postfix reload
См. также http://www.opennet.ru/base/net/postfix_per_user_acl.txt.html
Часто ограничив cgi скрипты пользователей и доcтуп по FTP,
забывают про возможность запуска программ через "|script" опцию в .forward файле.
Запрещение выполнения скриптов через .forward в Postfix (для агента доставки local):
allow_mail_to_commands = alias
local_command_shell=/dev/null
Вообще запретить .forward, через изменение пути поиска:
forward_path = $home/.forward
В main.cf добавьте строчку:
local_recipient_maps = $alias_maps unix:passwd.byname
Без данной опции, postfix полностью принимает письмо для любого пользователя,
даже для несуществующего, и лишь потом рассылает bounce сообщение.
С local_recipient_maps ошибка генерируется сразу на этапе RCPT TO:
в sendmail.cf
O MaxRecipientsPerMessage=20
O MaxMessageSize=1000000
При использовании M4 макросов:
define('confMAX_RCPTS_PER_MESSAGE', '20')
define('confMAX_MESSAGE_SIZE', '1000000')
# Ограничиваем размер сообщения в 1 Мб.
message_size_limit = 1024000
# Ограничичиваем число CC в одном письме.
smtpd_recipient_limit = 5
# Ограничиваем размер ящика
mailbox_size_limit = 51200000
Если patch.mailbox:
# формат inbox-size-override: login макс_размер
default_mailbox_size = 5000
mailbox_size_map = hash:/etc/postfix/inbox-size-override
Проверку через "expn логин_пользователя" или "vrfy логин_пользователя",
можно заблокировать в sendmail:
В sendmail.cf добавить "O PrivacyOptions=authwarnings, noexpn, novrfy"
(можно использовать опции needexpnhelo, needvrfyhelo, которые требуют
наличия предварительного HELO для выполнения EXPN или VRFY)
или m4 макросом
define(`conf_PRIVACY_FLAGS', `authwarnings, noexpn, novrfy')
В Рostfix: disable_vrfy_command = yes
Следует отметить, что если вы используете dspam в связке с qmail+vpopmail
последний должен быть версии не ниже 5.3.7 (с опцией --enable-make-seekable, она yes по умолчанию),
иначе не работает конструкция вида:
/usr/local/dspam/bin/dspam --user local_part@domain.com \
--deliver=innocent,spam | /var/vpopmail/bin/vdelivermail '' bounce-no-mailbox
vdelivermail отваливается с ошибкой на несикабельность пайпа (errno 29).
При автоматической установке Касперского для Postfix при настроенных ограничениях для адресов
(smtpd_recipient_restrictions, sender_restrictions, etc) в логи валятся сообщения типа:
postfix/smtpd[20375]: connect from localhost.localdomain[127.0.0.1]
postfix/smtpd[20375]: warning: unknown smtpd restriction: "restricted_recipients"
postfix/smtpd[20375]: NOQUEUE: reject: RCPT from localhost.localdomain[127.0.0.1]:
451 Server configuration error; from=<user@domain.com> to=<group@domain.com>
postfix/lmtp[20197]: 00499FCF34: to=<group@domain.com>, relay=127.0.0.1[127.0.0.1], delay=10,
status=deferred (host 127.0.0.1[127.0.0.1] said: 421 <group@domain.com> Error ! (in reply to end of DATA command))
Необходимо убрать/закомментировать в /etc/postfix/master.cf параметры,
которые прописал KAV и которые конфликтуют с параметрами в /etc/postfix/main.cf.
У меня секция KAV в /etc/postfix/master.cf имеет вид:
127.0.0.1:10030 inet n n n - 20 spawn
user=kluser argv=/opt/kav/5.5/kav4mailservers/bin/smtpscanner
127.0.0.1:10031 inet n - n - 21 smtpd
-o content_filter=
# -o local_recipient_maps=
# -o relay_recipient_maps=
# -o smtpd_restriction_classes=
# -o smtpd_client_restrictions=
# -o smtpd_helo_restrictions=
# -o smtpd_sender_restrictions=
# -o mynetworks=127.0.0.0/8
-o strict_rfc821_envelopes=yes
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o myhostname=mail.domain.com
Потом
mail# postfix reload; postqueue -f
Открыл недавно несколько возможностей в Постфиксе для отсеивания нежелательной почты на этапе HELO.
Теперь у меня сервер отсеивает от 90 до 98% почты сразу. Антивирус (clamAV) и SA отдыхают.
Коэффициент SA задрал до 7.3. Все равно до него мало что доходит.
Итак в main.cf стоит:
smtpd_recipient_restrictions =
permit_mynetworks,
reject_non_fqdn_recipient,
reject_unauth_destination,
check_helo_access hash:/etc/postfix/helo_checks,
check_helo_access pcre:/etc/postfix/helo_checks_pcre,
check_sender_access hash:/etc/postfix/sender_checks,
check_client_access hash:/etc/postfix/client_checks,
check_sender_mx_access cidr:/etc/postfix/mx_access,
check_recipient_mx_access cidr:/etc/postfix/mx_access,
reject_rbl_client relays.ordb.org,
reject_rbl_client sbl.spamhaus.org,
reject_unknown_sender_domain,
reject_unknown_recipient_domain
/etc/postfix/helo_checks:
# Reject anybody that HELO's as being in our own domain(s)
# (Note that if you followed the order suggested in the main.cf
# examples, above, that machines in mynetworks will be okay.)
<Мой домен> REJECT You are not in trala.la
# Somebody HELO'ing with our IP address?
<мой IP> REJECT You are not me
Это хорошо помогает против вирус и зомби.
/etc/postfix/helo_checks.pcre:
# Initial expression
#/^[0-9]+(\.[0-9]+){3}$/ REJECT Invalid hostname (plain D)
# expression modified by Eugene 22.03.2005
/[^[] *[0-9]+((\.|-)[0-9]+){3}/ REJECT Invalid hostname (ipable)
#
/(modem|dia(l|lup)|dsl|p[cp]p|cable|catv|poo(l|les)|dhcp|client|customer|user|[0
-9]{4,})(-|\.|[0-9])/ REJECT Invalid hostname (client)
#
/[0-9]+-[0-9]+/ REJECT Invalid hostname (D-D)
Как проверить фильтры для postfix? Очень просто:
$ postmap -q "Content-Type: 1.exe" regexp:/etc/postfix/header_checks
Или просто входом с файла
$ postmap -q - regexp:/etc/postfix/body_checks < msg_file
Замечание: postmap не делает различий между header, subject и bodymessage.
Когда спам идет от адреса домена пользователю домена.
helo somehost
mail from: me@mydomain.ru
rcpt to: me@mydomain.ru
data
Т.е. когда почта принимается с любого IP адреса для $mydestination на MX.
А с внешнего адреса она к нам приходить не может. Это не есть правильно. Лечить в Postfix так (main.conf):
smtpd_recipient_restrictions =
permit_mynetworks,
check_sender_access hash:/usr/local/etc/postfix/antispam/wtf,
ограничения дальше,
...
потом, в antispam/wtf
brj.pp.ru 554 brj.pp.ru sender? What the fuck? You're not in mynetworks!
потом
makemap hash /usr/local/etc/postfix/antispam/wtf.db < /usr/local/etc/postfix/antispam/wtf
Иногда требуется ограничить прием почты для Postfix только с определенных доменов.
Пример - внутренний почтовый сервер для приема и отправки почты только в локальной сети.
В этом случае нам нужно , чтобы почта ходила только внутри некоего домена - mydomain.ru.
Делаем следующее. В main.cf:
smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/access, reject
В файле access:
#здесь перечисляем домен(ы) для которых почта разрешена почта
mydomain.ru OK
Затем
postmap access
postfix reload
Теперь будет приниматься почта только для тех, у кого в поле MAIL FROM стоит mydomain.ru.
Для всех остальных - генериться код "Acces denied".
2 способ позволяет среди всех пользователей в системе
отобрать тех, которым ДЕЙСТВИТЕЛЬНО нужна почта.
В main.cf:
local_recipient_maps = hash:/etc/postfix/users
Сюда же можно добавить $alias_maps.
В /etc/postfix/users заносим всех пользователей, для которых надо принимать почту:
user1 здесь_что-нибудь
user2 здесь_что-нибудь
"здесь_что-нибудь" - это набор все равно каких символов, чтобы выполнилась команда postmap.
Затем postmap /etc/postfix/users. И, конечно, postfix reload.
Теперь почта будет приниматься только для пользователей из файла users.
Для остальных будет генериться "User unknown in local recipient table" на этапе соединения.
smtpd_client_restrictions = ...
reject_rbl_client list.dsbl.org
check_recipient_access hash:/etc/postfix/skipcheck,
reject_unknown_client
Предпоследняя строка позволяет разрешить получение почты для некоторых получателей с unknown адресов.
только для этого необходимо указать в конфиге smtpd_delay_reject=yes
тогда даже на этапе HELO можно указывать исключения на основе адреса получателя:
smtpd_helo_restrictions = permit_mynetworks,
reject_invalid_hostname,
reject_non_fqdn_hostname,
check_recipient_access hash:/etc/postfix/skipcheck,
reject_unknown_hostname
1. В master.cf добавить строку:
backup unix - n n - - pipe flags=R user=postfix argv=/etc/postfix/script ${sender} ${recipient}
2. В /etc/postfix/script должно быть:
#!/bin/bash
/usr/sbin/sendmail -f $1 $2 backup@mydomain.ru
3.Добавить в main.cf:
smtpd_sender_restrictions = что там есть, hash:/etc/postfix/smtpd.sender
4. Создать файлик /etc/postfix/smtpd.sender такого вида (потом сделать postmap smtpd.sender):
user@mydomain.ru FILTER backup:
После строки "require verify = sender"
deny message = Access denied - $sender_host_address listed by $dnslist_domain\n$dnslist_text
dnslists = dnsbl.sorbs.net
deny message = message from $sender_host_address rejected - see http://njabl.org/
dnslists = dnsbl.njabl.org
deny message = rejected because $sender_host_address for bad WHOIS info, see http://www.rfc-ignorant.org/
dnslists = ipwhois.rfc-ignorant.org
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = dialups.mail-abuse.org
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = list.dsbl.org
deny message = Spam blocked see: http://www.spamcop.net/w3m?action=checkblock&ip=$sender_host_address
dnslists = bl.spamcop.net
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = relays.ordb.org
deny message = rejected, $sender_host_address Open Proxy, see: $dnslist_domain\n$dnslist_text
dnslists = dnsbl.void.ru
Postfix:
body_checks = regexp:/etc/postfix/body_checks
Пример для "AMER ICAN LA NGUAGE CENTER"
/etc/postfix/body_checks:
~^[[:alnum:]+/]{60,}[[:space:]]*$~ OK
/.*A.*M.*E.*R.*I.*C.*A.*N.*L.*A.*N.*G.*U.*A.*G.*E.*C.*E.*N.*T.*E.*R.*/ REJECT Body Spam Rule NN
Postfix:
maps_rbl_domains = work.drbl.caravan.ru, dul.ru, relays.ordb.org
maps_rbl_reject_code = 550
smtpd_client_restrictions = reject_maps_rbl
Sendmail (в sendmail.mc):
FEATURE('dnsbl', 'dul.ru', 'Use mail relays of your ISP')dnl
FEATURE('dnsbl', 'work.drbl.caravan.ru', `Use mail relays of your ISP')dnl
FEATURE('dnsbl', 'relays.ordb.org', 'Spam bloked from open relay.')dnl
Ссылки: http://www.drbl.ofisp.org/zones.html , http://www.dul.ru/ , http://ordb.org/faq/
Проблема. Хожу я с ноутбуком по разным местам. Разные провайдеры. Разные настройки.
Необходимо с ноутбука доставлять почту для мира. Ноутбук работает под FreeBSD. Как решить проблему?
Ответ очень простой. Нужно установить пакет msmtp. Он занимается доставкой почты от клиента к серверу.
Правильно назвать это будет MDA - Mail Delivery Agent. У меня есть почта в системе google.
Собственно через smtp gmail я и буду делать доставку. Сначала необходимо установить msmtp. Вот файл настроек:
$ cat .msmtprc
account default host smtp.gmail.com port 587
protocol smtp auth on from mylogin@gmail.com user mylogin@gmail.com
password пароль tls on tls_starttls on
metasend
В зависимости от типа файла, в качестве Content-type пишем:
application/gzip
application/zip
application/postscript
image/jpeg
image/png
audio/basic
audio/mpeg3
audio/wav
NFS сервер (FreeBSD):
/etc/rc.conf:
portmap_enable="YES"
nfs_server_enable="YES"
nfs_reserved_port_only="YES"
/etc/exports (man exports):
/usr/local/nfs -rw 192.168.1.2
/usr/local/nfs -ro -mapall=nobody -network 192.168.1 -mask 255.255.255.0
/cdrom -alldirs,quiet,ro -network 192.168.33.0 -mask 255.255.255.0
Для Linux /etc/exports будет выглядеть примерно так (запуск - service start portmap и nfs):
/usr/local/nfs 192.168.1.0/255.255.255.0(ro) 192.168.2.1(rw)
NFS клиент:
/etc/rc.conf:
portmap_enable="YES", nfs_client_enable="YES"
/etc/fstab:
192.168.1.1:/usr/local/nfs /home/nfs nfs ro 0 0
или вручную:
/sbin/mount_nfs -r 32768 -w 32768 -i noatime 192.168.1.1:/usr/local/nfs /home/nfs
Для оптимизации производительности рекомендуется при монтировании в Linux указывать параметры:
rsize=32768,wsize=32768,intr,noatime
Число запущенных клиентов и серверов под FreeBSD регулируется
через параметр "-n" в переменных rc.conf: nfs_client_flags и nfs_server_flags
В некоторых Linux дистрибутивах число серверов задается в файле /etc/sysconfig/nfs,
переменная NFSDCOUNT, значение которой передается как аргумент при запуске rpc.nfsd.
Скинуть пользователя по заданному порту (N) можно через OID:
1.3.6.1.4.1.9.9.150.1.1.3.1.5.N
snmpset as-1.test.ru private .1.3.6.1.4.1.9.9.150.1.1.3.1.5.N i 1
Соспоставить логин с номером порта можно через OID:
1.3.6.1.4.1.9.9.150.1.1.3.1.2
Или из FAQ: snmpset -v1 as-1.test.ru private .1.3.6.1.4.1.9.2.9.10.0 i $line
Полный контроль над MIBOID осуществляется с помощью команды pass.
pass MIBOID EXEC-COMMAND
Например:
pass .1.3.6.1.4.1.2021.255 /bin/sh /usr/local/local/passtest
Как писать обработчик passtest, можно найти в поставке ucd-snmp.
Если просто нужно выдать результат выполнения скрипта, можно использовать exec:
exec .1.3.6.1.4.1.2021.51 ps /bin/ps
Пример запрещения записи файлов по расширению (veto files переписать в одну строку):
[SOUND]
path = /mnt/sde/music
comment = звуковой-сервер
username = roma,vnelubin,gtcvet,eolax,mlapin,kkorobejnikov
only user = yes
public = yes
writable = yes
create mode = 0775
force create mode = 0775
directory mode = 0775
force directory mode = 0775
veto oplock files = /*.mp3/*.wav/
veto files = /*.a*/*.A*/*.b*/*.B*/*.c*/*.C*/*.D*/*.d*/*.E*/*.e*/*.F*/*.f*/*.G*/*.g*/*.H*/*.h*
/*.I*/*.i*/*.J*/*.j*/*.K*/*.k*/*.L*/*.l*/*.N*/*.n*/*.O*/*.o*/*.P*/*.p*/*.Q*/*.q*
/*.R*/*.r*/*.S*/*.s*/*.T*/*.t*/*.U*/*.u*/*.Y*/*.y*/*.V*/*.v*/*.X*/*.x*/*.Z*/*.z*
/*.1*/*.2*/*.3*/*.4*/*.5*/*.6*/*.7*/*.8*/*.9*/*.0*/*.vob/*.VOB/*.iso/*.ISO/*.nrg
/*.NRG/*.IFO/*.ifo/*.BUP/*.bup/*.zip/*.ZIP/*.rar/*.RAR/*.TXT/*.txt/*.TAR/*.tar
/*.EXE/*.exe/*.DLL/*.dll/*.CFG/*.cfg/*.HT*/*.ht*/*.aa*/*.ab*/*.ac*/*.ad*/*.ae*
/*.af*/*.ag*/*.ah*/*.ai*/*.aj*/*.ak*/*.al*/*.am*/*.an*/*.ao*/*.ap*/*.aq*/*.ar*
/*.as*/*.at*/*.au*/*.ay*/*.ax*/*.az*/*.wb*/*.wc*/*.wd*/*.we*/*.wf*/*.wg*/*.wh*
/*.wi*/*.wj*/*.wk*/*.wl*/*.wm*/*.wn*/*.wo*/*.wp*/*.wq*/*.wr*/*.ws*/*.wt*/*.wu*
/*.wy*/*.wx*/*.wz*/*.wv*/
delete veto files = yes
Для самбы версии 3 и выше регистр значения не имеет.
Для разрешения записи, но скрытия для чтения, нужно использовать:
hide veto files = yes
ещё пример:
veto oplock files = /*.xls/*.XLS/*.mdb/*.MDB/*.ldb/*.LDB/
veto files = /*.avi/*.mp*
Прозрачная авторизация пользователя через его доменную учетную запись
Использовавшие источники
http://www.lissyara.su/?id=1510&commented=1#comment_2138http://wiki.bestpractical.com/view/NtlmAuthentication
В портах появился, но не собирается как надо (на 1.10.07 г.), поэтому
cd /usr/ports/www/mod_ntlm2
Необходимо поправить файл mod_ntlm.c
make fetch && make extract
diff mod_ntlm2-0.1/mod_ntlm.c mod_ntlm2-0.1-fixed/mod_ntlm.c
590c590,596
< apr_pool_sub_make(&sp,p,NULL);
---
> /*
> * apr_pool_sub_make(&sp,p,NULL);
> *
> * This function call is not longer available with apache 2.2
> * Try replacing it with apr_pool_create_ex()
> */
> apr_pool_create_ex(&sp,p,NULL,NULL);
Теперь собираем и устанавливаем
make install
Пример настройки /usr/local/etc/apache22/Includes/nagios.conf
...
ScriptAlias /nagios/cgi-bin/ /usr/local/www/nagios/cgi-bin/
Alias /nagios/ /usr/local/www/nagios/
Alias /nagios /usr/local/www/nagios/
<Location /nagios/cgi-bin>
AuthType NTLM
NTLMAuth on
NTLMAuthoritative on
NTLMDomain NAME_DOMAIN # ИМЯ домена
NTLMServer dc1 # имя PDC
NTLMBackup dc2 # имя BDC
Require valid-user
</Location>
...
Если обращаться из IE - все работает, IE отдает данные авторизации любому.
Если обращаться из Mozilla Firefox не будет работать - FF не отдает
данные авторизации кому попало, сначала надо определить кому можно
отдавать. Для этого в FF(about:config) в параметре network.automatic-
ntlm-auth.trusted-uris установить имя сервера которому можно отдавать
данные авторизации.
В squid.conf
#Здесь описываем внешие ACL
external_acl_type InetGroup-proxy-08-20ww %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
# accesse in internet in work week from 08-00 to 20-00
external_acl_type InetGroup-proxy-08-20aw %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
# accesse in internet in all week from 08-00 to 20-00
external_acl_type InetGroup-proxy-00-24all %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
# accesse in internet in all week from 00-00 to 24-00
# Проверь свои пути
auth_param ntlm children 20
auth_param ntlm program /usr/local/samba/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 2 minutes
auth_param basic children 20
auth_param basic program /usr/local/samba/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
# Говорим, что нужна авторизация
acl you_domain proxy_auth REQUIRED
# Разграничиваем доступ по времени
acl work-week time MTWHF 08:00-20:00 # Доступ с 08-00 до 20-00 с понедельника по пятницу
acl all-week time SMTWHFA 08:00-20:00 # Доступ с 08-00 до 20-00 всю неделю
acl all-time time SMTWHFA 00:00-24:00 # Доступ круглосуточно всю неделю
# Осуществляем проверку на принадлежность к нужно группе
acl InetAccess-proxy-08-20ww external InetGroup-proxy-08-20ww proxy-08-20ww
acl InetAccess-proxy-08-20aw external InetGroup-proxy-08-20aw proxy-08-20aw
acl InetAccess-proxy-00-24all external InetGroup-proxy-00-24all proxy-00-24all
# Собираем все в кучу и проверяем на предмет получения дуступа к ИНТЕРНЕТ
http_access allow you_domain work-week InetAccess-proxy-08-20ww
http_access allow you_domain all-week InetAccess-proxy-08-20aw
http_access allow you_domain all-time InetAccess-proxy-00-24all
----------------------
proxy-08-20ww, proxy-08-20aw, proxy-00-24all - Группы в домене. В них заносишь тех юзеров, которым разрешен доступ.
wbinfo_group.pl - Используй именно этот скрипт. В том, что идет в комплекте со squid имеется ошибка.
Здесь она исправлена.
#!/usr/bin/perl -w
#
# external_acl helper to Squid to verify NT Domain group
# membership using /usr/local/samba/bin/wbinfo
#
# This program is put in the public domain by Jerry Murdock
# <jmurdock@itraktech.com>. It is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Author:
# Jerry Murdock <jmurdock@itraktech.com>
#
# Version history:
# 2002-07-05 Jerry Murdock <jmurdock@itraktech.com>
# Initial release
#
# external_acl uses shell style lines in it's protocol
require 'shellwords.pl';
# Disable output buffering
$|=1;
sub debug {
# Uncomment this to enable debugging
print STDERR "@_\n";
}
#
# Check if a user belongs to a group
#
sub check {
local($user, $group) = @_;
$groupSID = `/usr/local/samba/bin/wbinfo -n "$group"`;
# chop $groupSID;
# because wbinfo -n also returns the group number
$groupSID = substr($groupSID,0,index($groupSID," ",0));
$groupGID = `/usr/local/samba/bin/wbinfo -Y "$groupSID"`;
chop $groupGID;
# &debug( "User: -$user-\nGroup: -$group-\nSID: -$groupSID-\nGID: -$groupGID-");
return 'OK' if(`/usr/local/samba/bin/wbinfo -r \Q$user\E` =~ /^$groupGID$/m);
return 'ERR';
}
#
# Main loop
#
while (<STDIN>) {
chop;
&debug ("Got $_ from squid");
($user, $group) = &shellwords;
$ans = &check($user, $group);
&debug ("Sending $ans to squid");
print "$ans\n";
}
----------------------------------------------------------------------------------------------------------
smb.conf
[global]
workgroup = YOU-DOMAIN
realm = YOU-DOMAIN.RU
netbios name = demon
server string = Proxy Server
hosts allow = 10. 127.
winbind separator = \\ # Обрати на это внимание
winbind use default domain = yes
winbind uid = 10000-20000
winbind gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
template homedir = /home/winnt/%D/%U
template shell = /usr/local/bin/bash
max log size = 50
security = domain
password server = srv1 srv3
encrypt passwords = yes
srv1 и srv3 - PRIMARY and BACKUP контроллеры домена
----------------------------------------------------------------------------------------------------------
root@demon#tail -f /usr/local/squid/var/logs/cache.log
Got YOU-DOMAIN\\user1 proxy-08-20ww from squid
Sending ERR to squid
Got YOU-DOMAIN\\user1 proxy-08-20aw from squid
Sending ERR to squid
Got YOU-DOMAIN\\user1 proxy-00-24all from squid
Sending OK to squid
# Тут явно видно, что пользователя user1 нашли в группе proxy-00-24all и squid'у передано OK
Got YOU-DOMAIN\\user2 proxy-08-20ww from squid
Sending OK to squid
Got YOU-DOMAIN\\user3 proxy-08-20ww from squid
Sending OK to squid
root@demon#tail -f /usr/local/squid/var/logs/access.log
1147851551.270 20 10.66.107.56 TCP_IMS_HIT/304 251 GET http://img.mail.ru/mail/ru/css/mail-main1.css YOU-DOMAIN\user1 NONE/- text/css
Небольшое дополнение:
Информация о членстве в группе хранится в кеше squida (по умолчанию) 1 час, а в кеше Winbinda - 300 сек.
Чтобы не ждать столько времени при перемещении пользователя из одной группы в другую
советую добавить в squid.conf при описании внешиx ACL опцию ttl,примерно так:
external_acl_type InetGroup-proxy-08-20ww ttl=0 %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
а в smb.conf:
[global]
winbind cache time = 0
Было дано:
- Домен на Windows2003 с поднятым Kerberos.
- FreeBSD на шлюзе, куда должны были подключаться пользователи.
- VPN-демон mpd.
Задача: заставить mpd брать пароли из домена.
Решение:
- Ставим третью самбу с поддержкой кербероса.
- Настраиваем керберос
- Подсоединяем самбу в домен.
- Оставляем от нее только winbindd
- Ставим freeradius.
- Сцепляем радиус с самбой.
- Скручиваем mpd с радиусом и настраиваем сам mpd.
Итог: управляем учетными записями VPN-пользователей через обычные средства AD,
а не пишем руками данные в файл.
Примечание1. Документация гласит, что можно связать радиус с керберосом.
То есть теоретически можно отказаться от самбы. Я так не делал,
поскольку подцепить через самбу мне лично было проще.
Примечание2. Если использовать poptop, то можно не использовать
радиус, а использовать ntlm_auth из самбы. Тоже вариант.
Файлы конфигурации: http://www.opennet.ru/base/net/mpd_win2003.txt.html
1.Программные пакеты которые пригодятся при установке и настройке PDC.
samba-client-3.0.23-0.1.14rc2 или любая другая версия не ниже третьей.
samba-3.0.23-0.1.14rc2 или любая другая версия не ниже третьей.
webmin-1.270-1 для администрирования через веб-интерфейс.
Пакет Samba последней версии можно скачать с сайта разработчика http://www.samba.org
и программу для администрирования через веб-интерфейс по адресу http://www.opencountry.com
Для начала устанавливаем Samba и Webmin.
После того как установили Samba нам потребуется отредактировать файл smb.conf
который находится в директории /etc/samba.
Пример рабочего файла который можно не править.
# smb.conf is the main Samba configuration file. You find a full commented
# version at /usr/share/doc/packages/samba/examples/smb.conf.SUSE if the
# samba-doc package is installed.
# Date: 2006-05-02
[global]
workgroup = univer.local
printing = cups
printcap name = cups
printcap cache time = 750
cups options = raw
map to guest = Bad User
include = /etc/samba/dhcp.conf
logon path = \\%L\profiles\.msprofile
logon home = \\%L\%U\.9xprofile
logon drive = P:
add machine script = /usr/sbin/useradd -c Machine -d /var/lib/nobody -s /bin/false %m$
domain logons = Yes
domain master = Yes
local master = Yes
netbios name = netserv1
os level = 65
preferred master = Yes
security = user
idmap gid = 10000-20000
idmap uid = 10000-20000
[homes]
comment = Home Directories
valid users = %S, %D%w%S
browseable = No
read only = No
inherit acls = Yes
[profiles]
comment = Network Profiles Service
path = %H
read only = No
store dos attributes = Yes
create mask = 0600
directory mask = 0700
[users]
comment = All users
path = /home
read only = No
inherit acls = Yes
veto files = /aquota.user/groups/shares/
[groups]
comment = All groups
path = /home/groups
read only = No
inherit acls = Yes
[printers]
comment = All Printers
path = /var/tmp
printable = Yes
create mask = 0600
browseable = No
[print$]
comment = Printer Drivers
path = /var/lib/samba/drivers
write list = @ntadmin root
force group = ntadmin
create mask = 0664
directory mask = 0775
[netlogon]
comment = Network Logon Service
path = /var/lib/samba/netlogon
write list = root
Для того что бы администрировать сервер придется поставить
программу удаленного администрирования через веб-интерфейс – Webmin.
После установки к серверу можно подключится через веб интерфейс по адресу https://localhost:10000
и там в службах есть настройка SMB-сервера, где можно Linux-пользователей копировать в SMB-пользователей.
Решил рассказать про проблемы с которыми я столкнулся при сборке самбы:
В самбе 3.14a наблюдается некорректная запись в логи даже при правильной настройке.
Были проблемы при сборке с heimdal. Команда id не выводила пользователей доменов при правильных конфигах, хотя всё работало.
Чтобы керберос работал по tcp надо писать
tcp/имя сервера:порт, а не kdc = tcp/server !
Пока не обновил порты и не пересобрал базу портов ( смотрите статью "хитрости работы с портами") 5 керберос не собирался.
После того как я решил переджойнить машину в домен, билет не хотел обновляться ни в какую. Пришлось ждать 10 часов пока он умрёт. Желающие могут поразвлекаться с утилитой управления билетами, которая входит в 2003 recourse kit и называется kutil.
Решение - сразу обновить порты собирать только новое ! 3.0.22 на данный момент + 5 kerberos . Сразу включать его работу через tcp .
После того как всё завелось ничего не переджойнивать и преспокойно раздавать шары.
Без обновлений портов работала связка 3.0.14a + krb4 но ошибка в логи валилась и на живой домен я так и не смог это поднять , только на виртуальной машине.
Имеем:
1. Учетные записи пользователей и групп в LDAP
2. Поднят домен на SAMBA-3.
На стороне сервера SQUID конфигурируем:
1. /etc/ldap.conf и /etc/nsswith.conf в результате getent passwd и getent group выдает список пользователей и групп
2. минимальный /etc/smb.conf:
[global]
workgroup = domain
netbios name = squid
load printers = no
printcap name = /dev/null
security = domain
password server = sambaserver
local master = no
os level = 33
domain master = no
preferred master = no
wins support = no
winbind use default domain = yes
winbind cache time = 1200
3. Заводим в домен net -Uadministrator join
4. Запускаем winbind, но при этом в /etc/nsswith.conf его _не_прописываем_
5. разрешаем чтение pipe winbindd процессу squid любым доступным способом,
например: setfacl -g:squid:rx /var/lib/samba/winbindd_privileged
6. samba в дальнейшем не нужна
7. далее в squid.conf:
# стандартные опции авторизации
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 5
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 2 minutes
auth_param ntlm use_ntlm_negotiate off
auth_param basic program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive off
# авторизация обязательна
acl NTLMauth proxy_auth REQUIRED
# определяем типы ACL
external_acl_type type_ldap_group1 ttl=60 children=1 %LOGIN
/usr/lib/squid/ squid_ldap_group.pl -b "cn=group1,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
external_acl_type type_ldap_group2 ttl=60 children=1 %LOGIN
/usr/lib/squid/squid_ldap_group.pl -b "cn=group2,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
external_acl_type type_ldap_group3 ttl=60 children=1 %LOGIN
/usr/lib/squid/squid_ldap_group.pl -b "cn=group3,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
# и сами ACL
acl acl_group1 external type_ldap_group1
acl acl_group2 external type_ldap_group2
acl acl_group3 external type_ldap_group3
ВСЕ. Дальше с ними можно работать как с обычными ACL, начиная от простого
http_access allow acl_group1
и заканчивая в вариантах пула и по времени.
При изменении информации в группе LDAP, squid примет изменения только через
время определенное в ttl, таким образом перезапускать его как -kreconfigure нет необходимости, что уже плюс!
Да вот еще, сам скрипт /usr/lib/squid/squid_ldap_group.pl очень прост:
#!/usr/bin/perl
#
# squid ldap group
# mailto:afletdinov\@dc.baikal.ru
#
use Getopt::Long qw(:config no_ignore_case);
use Net::LDAP;
use strict;
# const
my $VERSION = '20051122';
# variables
my $ldap;
my $user;
my $result;
#my $pass;
my $opt_groupdn = '';
my $opt_binddn = '';
my $opt_bindpasswd = '';
my $opt_secretfile = '';
my $opt_uri = '';
GetOptions(
'b=s' => \$opt_groupdn,
'D=s' => \$opt_binddn,
'w=s' => \$opt_bindpasswd,
'W=s' => \$opt_secretfile,
'H=s' => \$opt_uri );
# check: requires param
&usage unless($opt_groupdn and $opt_uri);
#connect
$ldap = Net::LDAP->new($opt_uri) or die("connect $opt_uri failed!");
# bind
if($opt_binddn){
# check: secretfile
if($opt_secretfile){
open(FILE, "<$opt_secretfile") or die("error read $opt_secretfile");
$opt_bindpasswd = <FILE>;
close(FILE); }
$result = $ldap->bind($opt_binddn, password=>$opt_bindpasswd);
# anonymous bind
}else{ $result = $ldap->bind(); }
$result->code and die($result->error);
# use buffers off
$| = 1;
# BASIC
while(<STDIN>){
chomp;
# format: user password
unless(/^(\S+)\s*(\S*)$/){ print "ERR\n"; next; }
$user = $1;
#$pass = $2;
# check: valid group
$result = $ldap->search(base=>$opt_groupdn, , filter=>"(memberUid=$user)");
# not found
unless($result->count){ print "ERR\n"; next; }
# auth: OK group: OK
print "OK\n";
}
exit;
sub usage(){
print <<EOF;
squid_ldap_group.pl version $VERSION
Usage: squid_ldap_group.pl -b "cn=www-access,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
-b GroupBaseDN (REQUIRED)
-H LdapURI (REQUIRED)
-D BindDN
-w BindPasswd
-W SecretFile
EOF
exit;
}
Group policy работают по схеме NT4.
Для этого необходим poledit.exe winnt.adm common.adm.
Запускаем poledit, загружаем необходимые шаблоны, редактируем default user либо отдельного пользователя,
либо группу пользователей потом сохраняем в файл ntconfig.pol
Почти все настройки определены в одном файле 1_ALLinONE.adm
Только одно отличие, для win2k и winxp(win2k3) необходимы разные шаблоны. Его можно найти здесь.
Сам файл ntconfig.pol необходимо разместить в параметре самбы netlogon path.
Различия типов операционных систем решается просто через самбу в параметре netlogon path необходимо добавить параметр %a (тип клиентской системы), и в создать папки Win2K WinXP Win2K3, где и будут размещаться необходимый файлы ntconfig.pol
Мне удалось запустить Samba 3.0.11 в jail на FreeBSD 4.10 только после того,
как в smb.conf были вписаны следующие строчки:
interfaces = 192.168.1.123/32
bind interfaces only = yes
Пишем скрипт /etc/auto.smbfs примерно такой:
#!/bin/sh
a="${1/@//}"
a="${a//\ /\\ }"
echo -fstype=smbfs,username=guest,password=fmask=666,iocharset=cp1251,codepage=cp866 :"//$a"
Параметры - по вкусу. automount как-то небрежно относится к пробелам в имени, но так работает.
Ставим на файл бит исполнения:
chmod +x /etc/auto.smbfs
Далее в /etc/auto.master добавляется строка
/var/autofs/smb /etc/auto.smbfs
где /var/autofs/smb - точка монтирования.
Стартуем:
/etc/init.d/autofs restart
Для удобства:
ln -s /var/autofs/smb /smb
Теперь можно обращатся к шаре "share" на хосте "host" вот так:
cd /smb/host@share
по IP тоже работать должно.
Всё написанное верно для дистрибутива debian sarge. Нужны пакеты autofs и smbfs.
Желающие могут расширить фунциональность, прикрутив к скрипту передачу логина\пароля через путь.
Если подключиться к шаре bin на сервере samba, и пользователь bin не заведен в smbpasswd,
то получим доступ к / под freebsd и к /bin под linux. Причем доступ получаем от имени пользователя,
под которым залогонились. Т.е., в большинстве случаев, пользователь может получить доступ,
как минимум по чтению, даже если шара от него закрыта, используя шару bin.
Решается, путем добавления пользователя bin в smbpasswd или созданием и направлением шары bin на /dev/null
%S Имя текущей службы
%P Корневой каталог текущей службы
%u Пользователь текущей службы
%g Основная группа %u
%U Имя пользователя для сеанса (может отличаться от имени,запрошенного клиентом)
%G Основная группа %U
%H Домашний каталог пользователя
%v Версия Samba
%h Имя хоста, на котором работает Samba
%m NetBIOS-имя компьютера-клиента
%L NetBIOS имя сервера
%M Имя хоста для компьютера-клиента
%N Имя NIS-сервера домашних каталогов. Значение определяется при помощи файла настройки системы NIS auto map.
Если вы скомпилировали Samba без automount, то значение совпадает с установленным для сервера NetBIOS именем
%p Путь к домашнему каталогу службы. Определяется при помощи файла настройки системы NIS auto map, как %N:%p
%R Выбранный после установления соединения уровень протокола
%d Номер текущего серверного процесса
%a Операционная система клиента (значение может быть неверным)
%I IP-адрес клиентской машины
%T Текущие дата и время
1. Режим эмуляции Socks proxy в SSH
Допустим, у нас есть рабочая станция в локальной сети за firewall'ом;
также имеется ssh-доступ на сервер в Интернете. Кроме ssh, никакой связи с внешним миром не имеется,
а очень хочется, например, подключиться к какому-нибудь jabber-серверу.
На рабочей станции запускаем простую команду:
ssh -D 5555 user@remotehost -f -N
, где -D 5555 - эмуляция SOCKS сервера через порт 5555
-f - работа в фоне, после аутентификации
-N - не запускать shell на удаленном хосте.
Теперь, указав в настройках XMPP-клиента (например, Pidgin'а) в качестве SOCKS5 прокси localhost:5555,
получим желаемый результат: Pidgin соединяется с сервером через внешний сервер.
2. Туннель ssh
Дано: сервер локальной сети ourproxy.provider.ru, доступный извне.
Требуется: получить из дома доступ к ресурсам внутри локальной сети, например, к интранет-серверу 10.10.5.1:80
Решение: выполнить на домашней машине команду, пробрасывающую туннель к искомому IP-адресу через ourproxy.provider.ru:
ssh -f -N user@ourproxy.provider.ru -L 8080:10.10.5.1:80
Опция -f говорит ssh, что после соединения нужно уйти в background.
Опция -N указывает, что никаких команд выполнять не нужно
Ключ -L означает, что соединения к localhost на порт 8080 нужно перенаправлять на 80 порт IP-адреса 10.10.5.1
Таким образом, набирая в браузере адрес http://localhost:8080, попадаем на нужный сервер.
3. Обратный туннель ssh
Дано: компьютер на работе, находящийся за firewall'ом и nat'ом; компьютер дома с доступом в интернет;
сервер ourproxy.provider.ru с работающим sshd, доступный обоим компьютерам.
Но в данном случае прямой доступ с ourproxy.provider.ru к рабочей машине отсутствует.
Требуется: получить из дома доступ к сервису sshd на рабочем компьютере.
Решение: на рабочей машине выполнить команду:
ssh -f -N user@ourproxy.provider.ru -R 12345:localhost:22
Опции -f и -N описаны несколькими строчками выше.
Ключ -R означает, что подключения к порту 12345 на ourproxy.provider.ru будут перенаправляться на 22 порт рабочего компьютера.
После выполнения этой команды с рабочей машины можно будет попасть на эту машину с ourproxy.provider.ru,
выполнив команду:
ssh -p 12345 user@locahost
По этому же принципу можно получить доступ к прочим ресурсам локальной сети. Вот еще один пример.
На рабочей машине:
ssh -f -N user@ourproxy.provider.ru -R 8080:10.10.5.1:80
На домашней машине:
ssh -f -N user@ourproxy.provider.ru -L localhost:8080:localhost:8080
Теперь, набрав в адресной строке браузера на домашнем компьютере http://localhost:8080,
получаем доступ к интранет-серверу за семью замками двумя firewall-ами.
Конечно же, это приводит к серьёзной бреши в корпоративной безопасности,
поэтому крайне не рекомендуется злоупотреблять этим советом.
Ниже пример как заставить ICQ клиента, например http://kopete.kde.org, работать через HTTP прокси.
Суть метода: icq_client => socks => http_proxy
Ставим пакет dante-client - пользователям debian это сделать можно так:
sudo apt-get install dante-client
Затем залазим в настройки ( в debian'e - /etc/dante.conf)
В конце файла прописываем:
route {
from: 0.0.0.0/0 to: 0.0.0.0/0 via: proxy.testhost.ru port = 3128
proxyprotocol: http_v1.0
}
Где proxy.testhost.ru - адрес http прокси, 3128 - порт прокси. П
Дальше запускаем kopete... следующим образом:
socksify kopete
Пробрасывать весь трафик приложения через socks v.4 или v.5 сервер можно также используя http://tsocks.sourceforge.net/
1. в ~/.xinitrc пишем (именно сюда а не в /etc/profiles потому как
системная консоль FreeBSD не поддерживает юникод, посему локаль сия
будет использоваться только в иксах):
export LANG='ru_RU.UTF-8'
export LC_ALL='ru_RU.UTF-8'
2. выполняем конвертацию содержимого файловой системы из koi8-r в
UTF-8 (необходим порт converters/convmv):
%convmv -f koi8-r -t UTF-8 путь_к_разделу/* --notest -r
3. далее все зависит от терминала, если у вас что-то вроде
gnome-terminal, то достаточно будет сменить кодировку в опциях на
UTF-8, если же у вас что-то вроде xterm'а, тогда в ~/.Xresources
необходимо будет поменять шрифт, например так (для этого шрифта
необходим пакет x11-fonts/terminus-font):
XTerm*font: -*-terminus-medium-*-*-*-*-*-*-*-*-iso10646-1
для syscons(4) на i386:
1. ставим sysutils/jfbterm и textproc/uim-m17nlib
2. меняем стандартную переключалку языка с Shift+Space на Ctrl+\
добавлением в ~/.uim
(define-key generic-on-key? "<Control>\\")
(define-key generic-off-key? "<Control>\\")
3. ставим локаль и добавляем запуск uim-fep и jfbterm в ~/.profile
export LANG=ru_RU.UTF-8
exec jfbterm -e uim-fep
или в ~/.login (для tcsh)
setenv LANG ru_RU.UTF-8
exec jfbterm -e uim-fep
В комплекте socks сервера dante (http://www.inet.no/dante/) есть скрипт socksify, который позволяет
прозрачно пробрасывать весь трафик приложения через socks сервер.
Например:
socksify ssh
Предварительно, в /etc/socks.conf нужно прописать параметры сервера, например:
route {
from: 0.0.0.0/0 to: 0.0.0.0/0 via: 192.168.1.1 port = 1080
protocol: tcp udp
proxyprotocol: socks_v5
}
где, 192.168.1.1 - адрес прокси сервера.
Другой вариант socks-враппера - tsocks (http://tsocks.sourceforge.net/)
Для переброса трафика через HTTP прокси (используя метод CONNECT), подходит библиотека libconnect
(http://libconnect.sourceforge.net/). Пример скрипта:
#!/bin/sh
export LD_PRELOAD=/usr/lib/libconnect.so
прграмма
Адрес прокси прописывается в /etc/libconnect.conf:
p:192.168.1.1/3128
Можно использовать враппер из комплекта:
libconnect telnet 111.222.123.234 23
Для отправки запроса с другого IP, привязанного к сетевому интерфейсу (алиаса), можно использовать libsis
(http://www.palfrader.org/libsis/). Пример:
#!/bin/sh
export LD_PRELOAD=/usr/local/lib/libsis.so
export SIS_SOURCE=192.168.10.99
программа
/etc/sockd.conf:
# Куда пишем логи.
logoutput: /var/log/socks/socks.log
# На каком сетевом интерфейсе и порту обслуживаем socks клиентов.
internal: rl0 port = 1080 # или можно указать IP: internal: 10.1.1.1 port = 1080
# С какого IP или интерфейса выходим во внешний мир.
external: ed0 # или external: 1.2.3.4
# Используемый метод авторизации клиентов. none - без авторизации.
method: username none #rfc931
# Разрешаем клиенту 192.168.0.2 выход через socks.
client pass {
from: 192.168.0.2/32 to: 0.0.0.0/0
log: connect disconnect iooperation
}
#Пример, как разрешить соединения от сервера.
pass {
from: 0.0.0.0/0 to: 0.0.0.0/0
command: connect udpassociate
log: connect disconnect iooperation
}
# Пример, как запретить соединения от сервера
block {
from: 0.0.0.0/0 to: 0.0.0.0/0
log: connect error
}
Web-сервер apache наверное самый лучший web-сервер, но при настройке web-интерфейса для nagios
можно обойтись и без него, что сейчас и будет описано.
Применительно к FreeBSD:
portinstall /usr/ports/www/nginx
В /etc/rc.conf.local
# nginx
nginx_enable=YES
nginx не может выполнять php и cgi скрипты. Для этого можно использовать backend серверы.
Схема получается следующая:
mini_httpd
---*.cgi---> 192.168.0.200:1081
/
nginx / lighttpd
192.168.0.200:80------*.php---> 192.168.0.200:1082
\
\ Каталог
---*.html--> /usr/local/www/...
В этой схеме nginx слущает на порту запросы, производит авторизацию, статические файлы отдает сам,
cgi-скрипты перенаправляет к запущенному на внутреннем порту 127.0.0.1:1081
mini_httpd (/usr/ports/www/mini_httpd), который в свою очередь и выполняет эти скрипты.
Схема может показатся сложной, но в моём случае переход на нее оправдался:
опрос nagios производится 1 раз в минуту из Firefox (спец.плагин), и машина с nagios
испытывала некоторые трудности с производительностью. После запуска данной схемы
нагрузка на машину значительно снизилась.
Если используется pnp4nagios (http://www.pnp4nagios.org/pnp/install) для построения графиков
производительности сервисов, то выполнение php-скриптов возможно с помощью запущенного
на внутреннем порту 127.0.0.1:1082 lighttpd (/usr/ports/www/lighttpd).
Конфигурационные файлы nginx хранятся по умолчанию в /usr/local/etc/nginx/.
/usr/local/etc/nginx/nginx.conf
user www www;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run//nginx.pid;
worker_rlimit_nofile 8192;
events {
worker_connections 4096;
}
http {
include mime.types;
include proxy.conf;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
## интранет
server {
listen 192.168.0.200:80;
server_name 192.168.0.200 ns.contora.local;
access_log /var/log/nginx/access.log;
include nagios.conf;
include nagios-pnp.conf;
location / {
root /usr/local/www/apache22/data/;
}
include error-pages.conf;
}
}
/usr/local/etc/nginx/nagios.conf
location /nagios/ {
auth_basic "Nagios ";
auth_basic_user_file /usr/local/www/nagios/.htpasswd;
alias /usr/local/www/nagios/;
}
location /nagios/cgi-bin/ {
auth_basic "Nagios ";
auth_basic_user_file /usr/local/www/nagios/.htpasswd;
proxy_pass http://localhost:1081;
proxy_redirect http://localhost:1081/nagios/cgi-bin/ /nagios/cgi-bin/;
set $referer $http_referer;
proxy_set_header Referer $referer;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host localhost:1081;
proxy_set_header REQUEST_METHOD $request_method;
proxy_set_header REMOTE_USER $remote_user;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header SERVER_NAME localhost;
proxy_set_header SERVER_PORT 1081;
proxy_set_header HTTP_COOKIE $http_cookie;
}
/usr/local/etc/nginx/nagios-pnp.conf
location ~* /pnp/.*\.php$ {
root /usr/local/share/;
fastcgi_pass 127.0.0.1:1082;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nagios/share/$fastcgi_script_name;
include fastcgi_params;
}
location ~* /pnp/ {
root /usr/local/nagios/share/;
index index.php index.html index.htm;
}
/usr/local/etc/nginx/error-pages.conf
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/nginx-dist;
}
error_page 401 /401.html;
location = /401.html {
root /usr/local/www/nginx-dist;
}
error_page 404 /404.html;
location = /404.html {
root /usr/local/www/nginx-dist;
}
Ссылки:
http://sysoev.ru/nginx/http://www.lighttpd.net/http://www.acme.com/software/mini_httpd/http://www.lissyara.su/?id=1532
Суть проблемы заключалось в том, что надо было запустить несколько вебсерверов с разной конфигурацией,
например с разными модулями и на разных ip адресах. Для этого не нужно компилировать
и устанавливать несколько апачей, а достаточно запускать один и тот же установленный в системе,
со своим конфигурационным файлом.
Решение
Допустим нужно запустить два апача на разных ip, назовем их apache_v1 и apache_v2.
apache_v1 будет висеть на ip 192.168.0.1,
apache_v2 на 192.168.0.2
Будем считать, что установлен Apache2.
# cp /etc/conf.d/apache2 /etc/conf.d/apache2_apache_v1
# cp /etc/conf.d/apache2 /etc/conf.d/apache2_apache_v2
# vi /etc/conf.d/apache2_apache_v1
Добавляем строку:
CONFIGFILE=/etc/apache2/httpd_apache_v1.conf
# vi /etc/conf.d/apache2_apache_v2
Добавляем строку:
CONFIGFILE=/etc/apache2/httpd_apache_v2.conf
# cp /etc/apache2/httpd.conf /etc/apache2/httpd_apache_v1.conf
# cp /etc/apache2/httpd.conf /etc/apache2/httpd_apache_v2.conf
Правим *.conf фалы по вашему усмотрению.
# vi /etc/apache2/httpd_apache_v1.conf
Заменяем директивы на следующие:
Listen 192.168.0.1:80
PidFile "/var/run/apache2_apache_v1.pid"
Аналогично и для apache_v2
# vi /etc/apache2/httpd_apache_v2.conf
Listen 192.168.0.2:80
PidFile "/var/run/apache2_apache_v2.pid"
# cp /etc/init.d/apache2 /etc/init.d/apache2_apache_v1
# cp /etc/init.d/apache2 /etc/init.d/apache2_apache_v2
Добавляем их в автозагрузку:
# rc-update -a apache2_apache_v1 default
# rc-update -a apache2_apache_v2 default
Запускаем:
# /etc/init.d/apache2_apache_v1 start
# /etc/init.d/apache2_apache_v2 start
Материал предоставлен http://www.inode.ru/
Простенький скриптик для автосборки Apache 1.3.x + openssl+mod_ssl + php5+mysql
был написан из-за беспробудной лени автора
Для работы требуются (минимум):
- FreeBSD 4.8 (проверено) и наверное выше
- FreeBSD 5.1,5.2.1 (проверено) и наверное выше
- установленные пакеты
libxml2-2.6.2_1.tbz
mm-1.3.0.tbz
python-2.3.2_3.tbz
unzip-5.50_2.tbz
zip-2.3_1.tbz
и связанные с ними пакеты, возможно для удобства еще надо мс
Кроме того необходимо чтобы версия Apache совпадала с версией mod_ssl
#!/bin/sh
#
#Apache 1.x.y compile!!!
#
#
####################################
# -=April (c)=- ###-=2005=-#
####################################
SRC=`pwd`
DST=/usr/local/server
ln -s $DST /server
HTTPD_SRC=$SRC/apache
HTTPD_DST=$DST/apache
PHP_SRC=$SRC/php
PHP_DST=$DST/php
MYSQL_DST=$DST/mysql
MYSQL_SRC=$SRC/mysql
OPENSSL_SRC=$SRC/openssl
OPENSSL_DST=$DST/openssl
MODSSL_SRC=$SRC/mod_ssl
MODSSL_DST=$DST/mod_ssl
#prepare configuring APACHE
cd $HTTPD_SRC
./configure --prefix=$HTTPD_DST
prepare configuring MySQL
cd $MYSQL_SRC
./configure --prefix=$MYSQL_DST
make
make install
cd $PHP_SRC
./configure --prefix=$PHP_DST --with-apache=$HTTPD_SRC --with-mysql=$MYSQL_DST \
--enable-force-cgi-redirect --enable-sockets --with-mod_charset --with-xml
make
make install
cd $OPENSSL_SRC
./Configure
make
make test
make certificate
make install
cp $PHP_SRC/.libs/libphp5.a $HTTPD_SRC/src/modules/php5
cd $MODSSL_SRC
./configure --prefix=$HTTPD_DST --with-apache=$HTTPD_SRC --with-ssl=$OPENSSL_SRC \
--activate-module=src/modules/php5/libphp5.a --enable-module=ssl --server-uid=www --server-gid=www
cd $HTTPD_SRC
#./configure --prefix=$HTTPD_DST --activate-module=src/modules/php4/libphp4.a --enable-module=ssl \
#--server-uid=www --server-gid=www
./configure --prefix=$HTTPD_DST --enable-module=rewrite --enable-shared=rewrite \
--activate-module=src/modules/php5/libphp5.a --server-uid=www --server-gid=www
make
make certificate TYPE=custom
make install
Если используется русский apache и после закачки через форму файл приходит битый:
CharsetRecodeMultipartForms Off
Если пользователь скачивает битый файл (например, rar-архив):
- Убедитесь, что для типа вашего файла присутствует корректная запись вmime.types;
- Проверьте, какой тип по умолчанию установлен в httpd.conf, лучше поставить
DefaultType application/octet-stream
Если PHP скрипт выдает битую информацию:
См. заметку "В чем может быть причина битых бинарных файлов на выходе PHP"
http://www.opennet.ruhttp://www.opennet.ru/tips/info/740.shtml
Итак, при построении jdk 1.4.2 из портов необходимо иметь разрешение
эмуляции Linux в ядре и монтированную файловую систему linprocfs.
Для этого в файле /etc/rc.conf необходимо указать
# linux_enable="YES"
а в файле /etc/fstab
# linprocfs /compat/linux/proc linprocfs rw 0 0
По завершении установки необходимо установить переменную окружения
JAVA_HOME, которая указывает на каталог с установленным jdk
Соответственно, в файле .cshrc необходимо добавить
# setenv JAVA_HOME /usr/local/jdk1.4.2
а в файле .profile
# export JAVA_HOME=/usr/local/jdk1.4.2
Установка Tomcat 5.0 из портов проблем не вызвала, но запуск программы
постоянно срывался. Изучение логов показало, что Tomcat пытался
работать с протоколом IPv6, который не был установлен в моей системе.
В соответствии с рекомендацией, данной в логах, делаем запрет на IPv6
# sysctl net.inet6.ip6.v6only=0
теперь все работает.
Как вариант, можно внести соответствующие изменения в catalina.sh
и сделать запуск java с ключем -Djava.net.preferIPv4Stack=true,
но через sysctl мне показалось проще.
В состав дистрибутива openssl входят скрипты CA.sh и CA.pl (/usr/local/openssl/misc)
создаем корневой сертификат
./CA.sh -newca
генерируем личный ключ и сертификационный запрос сервера
./CA.sh -newreq
и подписываем его своим корневым сертификатом.
./CA.sh -sign
переписываем ключ и сертификат сервера в служебный каталог Apache
cp newreq.pem /usr/local/etc/apache/sslkey/server.key
cp newcert.pem /usr/local/etc/apache/ssl.crt/server.crt
Файл корневого сертификата ./demoCA/cacert.pem необходимо
распространить по клиентским компьютерам.
mod_bandwidth должен быть размещен вначале списка AddModule/LoadModule, т.е. до остальных модулей.
Если mod_bandwidth врезается в httpd, то при сборке нужно:
./configure --add-module=mod_bandwidth.c --permute-module=BEGIN:bandwidth
По умолчанию русский apache всегда выдает "Vary: accept-charset" и в случае
получения от пользователя заголовка Accept-Charset перекодирует в указанную в нем кодировку.
Решается проблема добавлением директивы:
CharsetDisableAcceptCharset On
Для файлов неизвестного типа (например, .rar) используется MIME тип определеный через DefaultType,
как правило это text/plain, который может быть перекодирован russian-apache.
Существует два решения проблемы:
1. DefaultType application/octet-stream в httpd.conf
2. Явно определить MIME тип вашего файла в mime.types
1. В chroot окружении обязательно должен быть /etc/passwd с пользователями для которых используется suexec.
2. Помещена ли в bin директорию программа suexec ?
3. Установлен ли suid root флаг для программы suexec ? (при копировании suid флаг исчезает).
4. Все ли динамические библиотеки присутствуют:
chroot /hst /usr/local/apache/bin/ldd /usr/local/apache/bin/httpd
chroot /hst /usr/local/apache/bin/ldd /usr/local/apache/bin/suexec
предварительно положив ldd в /hst/usr/local/apache/bin/
1. Добавляем в mime.types в конфигурации Apache строку:
image/x-icon ico
(Если не добавить, при использовании Russian Apache иконка
отображаться не будет !!)
2. Помещаем на html страницу код:
<link rel="SHORTCUT ICON" href="/favicon.ico">
3. Создаем иконку 16x16 в любом графическом редакторе в формате PNG.
4. Выкачиваем конвертер ftp://ftp.kernel.org/pub/software/graphics/pngtoico/ и преобразуем png в ico:
pngtoico favicon.png > favicon.ico
5. Копируем favicon.ico в корень сайта.
Напрмер, нужно чтобы все html файлы выдавались при их запросе после прохождения через
скрипт-фильтр parser.cgi
В .htaccess:
AddType parsed-html .html
Action parsed-html /cgi-bin/parser.cgi
В .htaccess пишем:
ExpiresActive On
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresDefault "access plus 1 month"
Проблема: при постинге в форму сообщений на русском языки иногда вываливается ошибка скрипта
insludes/function_search.php
Решение:
запустить psql
>ALTER TABLE phpbb_search_wordlist DROP CONSTRAINT phpbb_search_wordlist_pkey;
>CREATE INDEX phpbb_search_wordlist_pkey ON phpbb_search_wordlist (word_text);
Небольшой дайджест по обеспечению безопасности WordPress и других PHP OpenSource приложений.
Рассмотрено, что можно сделать на среднестатистическом хостинге.
В общем, safe_mode включать нельзя. Это урежет все до безобразия. Вместо этого мы:
1. Включим open_basedir
2. Подтюним некоторые настройки php
3. Выключим шелл вызовы
4. Выставим нужные права на директории
5. Для особых извращенцев, включим mod_security
Так же не стоит брезговать базовыми правилами безопасности WordPress (http://www.awmpage.com/2008/10/bezopasnost-wordpress/).
Включаем open_basedir
---------------------
Тут все просто. Три настройки в виртуалхосте:
php_admin_value open_basedir "/home/blogs/blog1.foobar.com"
php_admin_value upload_tmp_dir "/home/blogs/blog1.foobar.com/wp-tmp"
php_admin_value session.save_path "/home/blogs/blog1.foobar.com/wp-tmp"
Где "/home/blogs/blog1.foobar.com" - корень домена блога. Там необходимо создать директорию
"wp-tmp", дать ей права 777 и желательно в эту директорию в том же виртуалхосте запретить доступ:
<Directory /home/blogs/blog1.foobar.com/wp-tmp>
Order Deny,Allow
Deny from All
</Directory>
Мало-ли, может кто то туда сможет чего то записать. И чтобы это что то не было доступно из веба.
Так же как и ваши сессии.
Некоторые дополнительные ограничения PHP5
-----------------------------------------
Эти настройки внесут дополнительный плюс к безопасности
php_admin_flag track_vars on
php_admin_flag allow_url_fopen off
php_admin_flag allow_url_include off
php_admin_value memory_limit 30M
php_admin_flag enable_dl off
Думаю, это не все, что можно сделать с настройками - пожелания приветствуются.
Выключаем шелл вызовы
---------------------
open_basedir не распространяется на шелл вызовы php: system,exec,popen,passthru.
С другой стороны, зачем вордпрессу эти вызовы? Ну вот и отключим их с помощью disable_functions.
disable_functions="exec,system,passthru,popen"
Далее возникает желание добавить в конфигурацию virtual host такие строки:
php_admin_value "disable_functions" "exec,system,passthru,popen"
Но это не сработает, т.к. disable_functions работает только когда включен в глобальном php.ini.
Конечно, в phpinfo() вы увидите правильное значение disable_functions,
однако "отключенные" функции будут продолжать действовать.
Разработчики объяснили это тем, что отключать функции на уровне конфигурации
апача очень накладно, гораздо проще выключить их вообще из php.ini
Но с другой стороны, шелл вызовы достаточно часто используются в CLI скриптах,
в то время как в веб скриптах в большинстве случаев их можно отключить.
Значит нужно разделить конфиги CLI и Web. В первом конфиге оставить шелл вызовы,
а во втором, более подверженном хаку, их отключить.
Предположим, что дефолтный конфиг php.ini лежит в /usr/local/lib (стандартное место на FreeBSD).
Скопируем его в /usr/local/etc/apache2. И на новом месте пропишем нужные disable_functions.
Далее, в httpd.conf пишем:
PHPIniDir /usr/local/etc/apache2/conf
И рестартуем апач. Все, теперь CLI и Web версии PHP имеют независимые конфиги и в последнем отключены шелл вызовы.
Выставляем нужные права на директории
-------------------------------------
Даже если злоумышленник каким то образом проник внутрь через дырку вордпресса,
он начнет сканировать директории в поисках куда бы запихнуть iframe.
Что же, давайте сделаем его слепым. Предполагается, что директории будут сканироваться из под юзера апача.
Предполагается, что директории блогов находятся в /home/blogs/{blog}.domain.com
Значит, на директории /home,/home/blogs,/home/blogs/{blog}.domain.com ставим права 711.
На директорию конфигов апача и ниже - так же ставим 711. Все файлы внутри будут иметь аттрибуты 600.
Все директории и файлы в конфигах апача должны иметь овнера root.
Рекомендуется проделать эти телодвижения со всеми местами, где злоумышленник может найти полные пути к блогам.
Включаем mod_security
---------------------
Это тяжелая артилерия. Для тех, кто не в курсе, mod_security это модуль,
который мониторит входящие GET/POST/HEAD запросы и исходящие text/* ответы сервера
на предмет наиболее распространенных атак, инъекций и прочей ереси.
Здесь будет описываться mod_security2 для Apache v2.
Конечно, эта штука немного отяжелит апач, но по опыту скажу, что не фатально и оно того стоит.
Как ставить mod_security можно узнать в гугле. В простейшем случае на FreeBSD это прекрасно
ставится из портов. На CentOS mod_security ставится из репозитория http://www.jasonlitka.com/yum-repository/ .
После прописывания репозитория просто набрать команду
# yum install mod_security
Сразу скажу, mod_security рубит на корню phpmyadmin. По этому в тех приложениях,
где mod_security явно вредит, можно его выключить опцией httpd.conf:
SecRuleEngine Off
Так же mod_security откажется работать без модуля mod_unique_id.
Поговорим о том, как паранойю mod_security сделать здоровой :) Этот модуль хорош,
когда правильно настроены правила. По умолчанию он идет с параноидальным набором правил.
Многие из них вообще ни к чему и их можно свободно отключить.
В файле modsecurity_crs_10_config.conf, думаю, стоит понизить значение SecDebugLogLevel до 0-2.
Следующие файлы с наборами правил стоит вообще либо закомментировать, либо удалить:
modsecurity_crs_20_protocol_violations.conf
modsecurity_crs_21_protocol_anomalies.conf
modsecurity_crs_30_http_policy.conf
modsecurity_crs_35_bad_robots.conf
modsecurity_crs_55_marketing.conf
Остальные файлы нужно чуток подредактировать.
modsecurity_crs_40_generic_attacks.conf
Следующие секции я не нашел полезными:
* Session fixation
* Coldfusion injection
* LDAP injection
* HTTP Response Splitting
modsecurity_crs_45_trojans.conf - тут все впорядке
modsecurity_crs_50_outbound.conf - правила для исходящей информации.
Я бы здесь оставил только SQL Errors leakage
Рассмотрим поведение Apache при принудительном закрытии клиентом окна браузера, в котором отображался вывод еще не завершенного PHP скрипта. Например, скрипт зациклился или пользователь устал ждать конца операции.
Особенность в том, что скрипт будет принудительно завершен, только в момент физического вывода данных, т.е. после сброса буфера, например после отправки большого числа данных или вызова функций ob_flush() и flush(). Если вывода данных клиенту не производится или буфер вывода остается несброшенным, то скрипт так и будет выполняться до истечении времени заданного через параметр настройки PHP - max_execution_time. При этом не важно, в какое значение в конфигурации PHP установлен параметр ignore_user_abort.
В качестве обходного пути для прерывания скриптов в течение длительного времени не производящих вывод данных, например, вследствие выполнения длительного SQL запроса, можно использовать расширение pcntl, вызывая функцию pcntl_alarm(таймаут). В отличие от max_execution_time/set_time_limit, определяющих максимальное время утилизации CPU (при выполнении запросов к SQL серверу процессорное время расходуется минимально и скрипт может оставаться висеть днями), функция pcntl_alarm оперирует секундами реального времени.
Прозрачная авторизация пользователя через его доменную учетную запись
Использовавшие источники
http://www.lissyara.su/?id=1510&commented=1#comment_2138http://wiki.bestpractical.com/view/NtlmAuthentication
В портах появился, но не собирается как надо (на 1.10.07 г.), поэтому
cd /usr/ports/www/mod_ntlm2
Необходимо поправить файл mod_ntlm.c
make fetch && make extract
diff mod_ntlm2-0.1/mod_ntlm.c mod_ntlm2-0.1-fixed/mod_ntlm.c
590c590,596
< apr_pool_sub_make(&sp,p,NULL);
---
> /*
> * apr_pool_sub_make(&sp,p,NULL);
> *
> * This function call is not longer available with apache 2.2
> * Try replacing it with apr_pool_create_ex()
> */
> apr_pool_create_ex(&sp,p,NULL,NULL);
Теперь собираем и устанавливаем
make install
Пример настройки /usr/local/etc/apache22/Includes/nagios.conf
...
ScriptAlias /nagios/cgi-bin/ /usr/local/www/nagios/cgi-bin/
Alias /nagios/ /usr/local/www/nagios/
Alias /nagios /usr/local/www/nagios/
<Location /nagios/cgi-bin>
AuthType NTLM
NTLMAuth on
NTLMAuthoritative on
NTLMDomain NAME_DOMAIN # ИМЯ домена
NTLMServer dc1 # имя PDC
NTLMBackup dc2 # имя BDC
Require valid-user
</Location>
...
Если обращаться из IE - все работает, IE отдает данные авторизации любому.
Если обращаться из Mozilla Firefox не будет работать - FF не отдает
данные авторизации кому попало, сначала надо определить кому можно
отдавать. Для этого в FF(about:config) в параметре network.automatic-
ntlm-auth.trusted-uris установить имя сервера которому можно отдавать
данные авторизации.
В некоторые моменты чувствую себя очень неуютно из-за того, что нет возможности посмотреть, что конкретно делают с моим сервером некоторые персоны. Я долго искал возможность логгировать все, в том числе и POST запросы клиентов и нашел способ - через mod_security.
Устанавливается он элементарно apxs -cia mod_security.c (см документацию, правда, для его работы в наиболее удобном, "Concurrent", режиме логгирования, нужен модуль unique_id. После установи модуля следует добавить следующую секцию в httpd.conf:
<IfModule mod_security.c>
SecAuditEngine On
# У mod_security есть два механизма логгирования, Concurrent - более быстрый и продвинутый.
SecAuditLogType Concurrent
# Здесь будет храниться индекс - файл, по структуре похожий на access_log + идентификаторы,
# по которым можно найти полную информацию в StorageDir
SecAuditLog /var/log/www/audit/index
# Тут хранятся все данные запросов. Каждый запрос в отдельном файле.
# Запросы разнесены по каталогам (вместе все запросы одной транзакции, вместе все транзакции одного дня)
SecAuditLogStorageDir /var/log/www/audit/data/
# Наиболее полное логгирование (man)
SecAuditLogParts ABCDEFGHZ
# Добавить обработку POST данных.
SecFilterScanPOST On
SecFilterEngine On
# Следующие строки нужны для сохранения загруженных на сервер файлов:
SecUploadDir /var/log/www/audit/upload
SecUploadKeepFiles On
</IfModule>
Включать это имеет смысл при подозрении, что кто-то пытается использовать вашу систему не по назначению, теперь любой шаг проходимца будет записан.
p.s. Работоспособность конфига проверялась в apache 1.3.37, mod_security 1.9.4, но работать должно и в 2.0/2.0
Нижеприведенные настройки ограничат скорость для виртуального хоста в 1024kbps, с возможностью обслуживания не больше 10 запросов в секунду и максимумом в 30 открытых коннектов. Каждый посетитель может установить не больше трех одновременных соединений и получить данные на скорости не выше 20kb/s . Кроме того, виртуальный хост может за 4 недели израсходовать не более 100 Мб трафика, если лимит будет превышен скорость будет ограничена в 128kbps.
По умолчанию будет использоваться SuPHP.
В httpd.conf:
LoadModule suphp_module modules/mod_suphp.so
LoadModule php4_module modules/libphp4.so
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
AddHandler x-httpd-php .php
suPHP_Engine on
php_admin_flag engine off
Для избранных хостов активируем mod_php:
<VirtualHost ..>
suPHP_Engine off
RemoveHandler .php
php_admin_flag engine on
...
</VirtualHost>
Авторизация в Apache2 из стандартной группы Ldap (objectClass=posixGroup)
В .htaccess прописать параметры модуля mod_auth_ldap
AuthType Basic
AuthName "For Administrators only!"
AuthLDAPURL ldap://ldap.local/dc=local
AuthLDAPRemoteUserIsDN off
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
require group cn=admins_group,ou=group,dc=local
Для поддержки протокола ldaps:// необходимо в файле
/etc/httpd/conf.d/ldap.conf определить параметры:
LDAPTrustedCA /etc/pki/tls/certs/ca.cert
LDAPTrustedCAType BASE64_FILE
ca.cert это публичный сертификат которым подписан сертификат сервиса ldaps.
Ограничим память в 32 Мб, процессорное время 30 сек., одновременно может быть запущено не более 60 пользовательских CGI скриптов.
В <VirtualHost ...>:
RLimitMEM 32000000 32000000
RLimitCPU 10 30
RLimitNPROC 60 60
Запретим доступ к .txt файлам:
<Files ~ "\.txt">
Order allow,deny
Deny from all
</Files>
Доступа к .cgi и только с IP 1.2.3.4 через пароль, остальным нет доступа.
<Files ~ "\.cgi">
Order allow,deny
Allow from 123.123.123.123
AuthType Basic
AuthName "ENTER PASSWORD"
AuthUserFile /home/user/.htpasswd
<Limit GET POST PUT>
require valid-user
</Limit>
Deny from all
</Files>
в .htaccess:
AuthType Basic
AuthName "Private block"
AuthUserFile путь к файлу с паролями
require valid-user
или require user user1 user2...
Создать файл паролей: htpasswd -c .passwd user
добавить нового пользователя: htpasswd .passwd user
- В FreeBSD использование "accept filter" (нет реакции от accept() пока не поступят первые данные запроса):
- ядро собираем с "options ACCEPT_FILTER_HTTP" или "options ACCEPT_FILTER_DATA"
или kldload accf_http/accf_data
или accf_data_load="YES" / accf_http_load="YES в /boot/loader.conf
- в конфигурацию Apache добавляем "AcceptFilter on"
- Значительное уменьшение величины keepalive, или вообще его запрещение (KeepAlive Off);
- Использовать mod_accell или squid в режиме акселератора для кэширования.
thttpd - нет keep-alive, при нагрузке достаточно большие задержки между запросом и отдачей.
mathoptd - отличная производительность, небольшие запросы к ОЗУ, загрузка CPU примерно на 30%
выше чем при аналогичной нагрузке на сервер при использовании thttpd.
TUX и khttpd - эксперементальный код, замечательная производительность за счет выноса в linux ядро процедур отдачи статики.
Если тяжелый апач и много соединений, контент долго генерируется, но может кэшироваться, или наличие большого
процента "медленных клиентов" - то значительного прироста производительности можно достигнуть используя mod_accel.
Если в CGI скриптах используются SQL запросы: оптимизация базы, оптимизация запросов (EXPLAIN для pgsql),
использование индексов, частые vacuum для pgsql и прежде всего кэширование типовых запросов.
Если просто запускается много мелких скриптов: mod_perl или fast_cgi.
Плюс, вынесение из apache лишних модулей, отдельный web-сервер для раздачи статики и картинок.
Для начала, следует прочитать о директивах модуля ngx_http_geo_module:
http://sysoev.ru/nginx/docs/http/ngx_http_geo_module.html
Во вторую очередь нам нужно получить список сетей в нужном формате.
Так как мне нужно отделить только российские IP, у меня делается так:
curl -f -o - http://noc.masterhost.ru/allrunet/runet \
http://noc.zenon.net/nets/current | grep -v "0.0.0.0/0" | \
grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\/[0-9]\+" | \
sort | uniq | sed 's/$/ ru;/' > /etc/nginx/rugeo.conf;
/etc/init.d/nginx reload
Одно из условий - пользователи из любых стран с установленной cookie ALLOWIMAGES
не должны подвергаться дискриминации по географическому признаку.
Соответственно составляем файл конфигурации nginx.
Определяем страну (в контексте http):
geo $country {
default en;
include /etc/nginx/rugeo.conf;
}
В блоке конфигурации интересующего нас server пишем:
location = /spacer.gif {
empty_gif;
}
location ~* \.(jpg|jpeg|gif|png)$ {
set $allow_images 1;
if ($country = 'en') {
set $allow_images 0;
}
if ($http_cookie ~* ALLOWIMAGES) {
set $allow_images 1;
}
if ($allow_images != 1) {
rewrite ^/images/.*$ /spacer.gif break;
}
expires 7d;
root /home/www/htdocs;
if (!-f $request_filename) {
proxy_pass http://backend;
}
}
Таким образом всем посторонним иностранцам вместо фотографий будет видна пустота,
а всем своим фотографии будут видны откуда бы они не заходили.
Для ситуаций, когда блокировка обусловлена экономией трафика, http://sergeyx.livejournal.com/ в комментарии
советует использовать бесплатную сеть доставки контента CoralCDN (http://www.coralcdn.org):
Руководство по настройке: http://wiki.coralcdn.org/wiki.php?n=Main.Servers
Например, запросив http://www.test.ru.nyud.net:8080/img/test.gif сеть CoralCDN выступит
в роли кэшируюшего прокси для доставки нужного файла.
Пример для организации отдачи трафика через CoralCDN для посетителей с некорректным referer:
location /i/ {
...
# Избегаем зацикливания для запросов от CoralCDN
if ($http_user_agent ~ CoralWebPrx) {
break;
}
if ($query_string ~ coral-no-serve) {
break;
}
# Перенаправляем запросы только на существующие файлы
if (!-f $request_filename) {
break;
}
# Для посетителей с некорректным referer делаем редирект в CoralCDN
# корректность определяем через встроенную переменную nginx $invalid_referer
# вместо SITE нужно подставить имя хоста.
if ($invalid_referer) {
rewrite ^(.+)$ http://SITE.nyud.net$1;
}
...
}
Пример для Apache с mod_rewrite:
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} !^CoralWebPrx
RewriteCond %{QUERY_STRING} !(^|&)coral-no-serve$
RewriteRule ^/images/foo(.*)$ http://foo.bar.nyud.net:8080/images/foo$1 [R,L]
или можно сразу подставить HTTP_HOST
RewriteRule ^/images/foo(.*)$ http://%{HTTP_HOST}.nyud.net:8080/images/foo$1 [R,L]
Для автоматической замены, при отдаче html страниц, одного блока на другой
можно использовать mod_substitute (http://httpd.apache.org/docs/2.2/mod/mod_substitute.html).
Маска замены задается в виде регулярного выражения.
Примеры:
<Location /private>
AddOutputFilterByType SUBSTITUTE text/html
Substitute s/SECRET/XXXXX/ni
</Location>
<Location />
AddOutputFilterByType SUBSTITUTE text/html
Substitute s/foo/bar/ni
</Location>
<Location />
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|<BR */?>|<br />|i"
</Location>
Опции:
i - совпадение без учета регистра;
n - строчное совпадение, без использования регулярных выражений;
f - позволяет результаты текущей замены использовать в других заменах,
заданных в других mod_substitute правилах.
Есть скрипт http://domain.ru/art, для того чтобы запрос http://domain.ru/art/something
не вызывал ошибки и приводил к запуску этого скрипта в настройках Apache 2 нужно прописать:
<FilesMatch "^art">
AcceptPathInfo On
</Files>
Для Apache 1.3, можно воспользоваться
ErrorDocument 404 /cgi-bin/art.cgi
Или
<Location /art>
SetHandler cgi-script
</Location>
Или
RewriteEngine on
RewriteRule ^/art/(.*)$ /home/user/cgi-bin/art.cgi?$1 [T=application/x-httpd-cgi,L]
При наличии IP в blacklist.txt, посетителю показывается sorry.html:
RewriteEngine on
Rewritemap ipmap txt:/path/to/blacklist.txt
RewriteCond ${ipmap:%{REMOTE_ADDR}} =b
RewriteCond %{request_uri} !=/sorry.html
RewriteCond %{request_uri} !=/stylesheet.css
RewriteRule .* /sorry.html [R,L]
/path/to/blacklist.txt
11.22.33.44 b
22.33.44.55 b
33.44.55.66 b
Существует множество файлов вида http://www.host.ru/test/dirN/M.html и http://www.host.ru/test/dirN/new/M.html (N=1,2..., M=1,2..)
Необходимо, если установлена cookie shownew=on и присутствует файл /test/dirN/new/M.html прозрачно отображать
его содержимое, а не файла /test/dirN/M.html, который показываем если /test/dirN/new/M.html отсутствует.
RewriteEngine on
RewriteCond %{HTTP_COOKIE} ^.*shownew=on.*$
RewriteCond %{REQUEST_URI} ^/test/([a-z]+[0-9]+)/([0-9]+\.html)$
RewriteCond /home/host/htdocs/test/%1/new/%2 -f
RewriteRule ^/test/([a-z]+[0-9]+)/([0-9]+\.html)$ /home/host/htdocs/test/$1/new/$2 [L]
есть диры:
sub_host1/ru
sub_host1/en
sub_host2/ru
sub_host2/en
при обращении к www.somehost.ru/sub_host1 (и 2) должнен быть переход в дир со своим языком.
-- cgi-bin/redir.pl --
#!/usr/bin/perl
use CGI qw/:standard/;
($lang) = $ENV{HTTP_ACCEPT_LANGUAGE} =~ /(.?.?)/;
($redirurl) = param('redirurl');
$lang='en' if !( -d $ENV{DOCUMENT_ROOT}.$redirurl.$lang);
print redirect(-url=>$redirurl.$lang.'/');
-- httpd.conf --
RewriteEngine On
RewriteRule ^(/sub_host1/)$ /cgi-bin/redir.pl?redirurl=$1 [R,NE]
RewriteRule ^(/sub_host2/)$ /cgi-bin/redir.pl?redirurl=$1 [R,NE]
</VirtualHost>
Если у Вас есть SQUID и Вы используете NTLM авторизацию и хотите знать какой сейчас
(по крайней мере в последний раз авторизовался) у клиента IP адрес или какому клиенту он присвоен,
то воспользуйтесь следующей командой:
awk '{user[tolower($8)]=$3} END {for(i in user) {print user[i] " " i}}' access.log | sort
Будет выведено примерно следующее:
192.168.132.200 e_scher
192.168.132.202 v_lit
192.168.132.203 a_volob
192.168.132.204 a_kuch
192.168.132.210 e_utsum
192.168.132.211 v_nik
192.168.132.212 s_maz
Как видите, это удобно использовать в случае squid и NAT.
Чтобы анализаторы логов прокси сервера squid отображали данные о пересылках в обход прокси,
например данные по почтовому или ssh трафику, можно сохранить данные о таких пересылках в логе squid.
Настройки ipcad:
capture-ports enable;
interface ppp* filter "ip and not dst net 192.168.0.0/16";
aggregate 0.0.0.0/0 strip 32; /* Считаем все адреса */
/* Теперь укажем какие порты как отображать */
aggregate 1-19 into 65535;
aggregate 20-21 into 21;
aggregate 22-23 into 22;
aggregate 25 into 25;
aggregate 24 into 65535;
aggregate 26-79 into 65535;
aggregate 80-81 into 0;
aggregate 82-109 into 65535;
aggregate 110 into 110;
aggregate 111-442 into 65535;
aggregate 443 into 443;
aggregate 444-3127 into 65535;
aggregate 3128 into 0;
aggregate 3129-65535 into 65535;
Сам файл обработки ipcad и записи в сквидовский лог:
#!/bin/sh
net="192.168"
ttime=`/usr/bin/rsh localhost sh ip acco|/bin/grep 'Accounting data saved'| /bin/awk '{print ($4)}'`
/usr/bin/rsh localhost clear ip accounting
/usr/bin/rsh localhost show ip accounting checkpoint|/bin/grep $net|/bin/awk -v vtime=$ttime '{print (vtime".000",1,$1,"TCP_MISS/200",$4,"CONNECT",$2":"$6,"-","DIRECT/"$2,"-")}' >>/var/log/squid/access.log
Вместо 192.168 Вы можете указать свою сеть, которую брать с ipcad'а и заносить в лог прокси сервера Squid.
Таким образом весь трафик, указанный в настройках ipcad'а будет отображен в access.log сквида,
который в данном примере находится в папке /var/log/squid.
Все тестировалось на FreeBSD 6.2.
Вначале добавляем необходимые опции в ядро:
IPFIREWALL
IPFIREWALL_FORWARD
Далее добавляем правила на разворот трафика на Squid:
ipfw add 49 fwd 127.0.0.1,3128 tcp from any to any 80
Затем правка собственно squid.conf :
http_port 3128
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
Чтобы заставить эту связку работать необходимо в конфиге squid'a поставить "wccp_version 4",
а на cisco - "ip wccp version 1" иначе не работает.
Ядро 2.4.x собирается с включенным GRE, потом собирается и подгружается модуль ip_wccp.o
Никаких iptunnel руками делать не надо. Все работает и без них.
1. собрать сквид (2.5s1 или s2) с поддержкой аутентификации
--enable-auth=basic,ntlm --enable-auth-modules=SMB --enable-basic-helpers=SMB --enable-ntlm-modules=SMB
2. поставить ntlm_auth из /helpers/ntlm_auth/smb/
3. поставить smb_auth (для клиентов не поддерживающих ntlm аутентификацию) из /helpers/basic_auth/smb/
4. в сквиде аутентификацию делать через ACL proxu_auth.
basic аутентификацию через smb_auth (см. сайт разработчиков), для ntlm_auth встроенный хелп.
Для самбы стандартные настройки для контроллера домена.
Для принудительного проксирования, на прокси-сервере следует ввести
правила Firewall:
01000 fwd 127.0.0.1,3128 tcp from 10.128.0.0/16 to any 80,8080,8101
В squid.conf нужно добавить:
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
На маршрутизаторе "развернуть" Веб-трафик на ПРОКСИ-сервер:
ipfw add 10 fwd ip_прокси tcp from 10.128.0.0/16 to any 80,8080 out
xmit lnc1
Сервер:
stunnel -p /usr/local/etc/stunnel.pem -r 127.0.0.1:80 -d 443
Клиент:
stunnel -c -d 2.2.2.2:2323 -r proxy.host.ru:3128 -Z 3.3.3.3:443
Организуется туннель: user -> 2.2.2.2:2323 -> proxy.host.ru:3128 -> 3.3.3.3:443 -> 127.0.0.1:80
127.0.0.1:80 - ip и порт на удаленной машине, куда пробрасывается туннель.
2.2.2.2:2323 - ip и порт локальной машины, "вход в туннель"
proxy.host.ru:3128 - proxy сервер с поддержкой CONNECT
3.3.3.3:443 - удаленная машина, ожидающая сторона туннеля.
В /etc/ipnat.rules заносим:
rdr rl0 0/0 port 80 -> 127.0.0.1 port 3128 tcp
В squid.conf:
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
Используйте метод доступа к хранилищу DISKD.
Параметры сборки: ./configure --enable-storeio=diskd,ufs
(также можно указать --enable-async-io --enable-poll)
В файле конфигурации:
cache_dir diskd /cache1 1024 16 256 Q1=72 Q2=64
Очередное решение на наболевшую тему.
Задача: имея squid с настроенной авторизацией пользователей и сбором статистики
сделать ограничение на используемый трафик (квоты).
Лично мне от sams пришлось отказаться т.к. он прикручивается к авторизации пользователей,
а для меня это неприемлемо.
Решение подойдет для тех, кому не сильно критично точное лимитирование.
Я сильно не хотел менять устоявшуюся систему авторизации пользователей.
итак.
1. настраиваем сквид (статей много, описывать не буду)
В squid.conf , желательно перед остальными ACL, надо будет добавить следующее
# блокировка пользователей которые превысили лимит (файл user-deny),
# и разрешение этим пользователям только тех IP и сайтов, которые перечислины в файле host.acl
acl no_quota url_regex -i "/etc/squid/no_quota_url.txt"
acl banusers proxy_auth_regex -i "/etc/squid/user_deny.txt"
http_access allow no_quota banusers allowedhost
deny_info ERR_QUOTA all
http_access deny banusers allowedhost all
по порядку что к чему с файлами:
no_quota_url.txt - ведется руками.
текст:
# файд содержит сайты, который открываются, даже если превышена квота и пользователь попал в users_deny.txt
test.ru
icq.com
205.188.
user_deny.txt - в дальнейшем создастся сам, но без него перечитать настройки squid не получиться
# файл содержит пользователей превысивших квоту.
# автоматически переписывается скриптом traf_limit.pl
dolzhen_bit_odin_user
user1
user2
ERR_QUOTA создадим по образу и подобию всех остальных страниц с ошибками.
Я поставил что-бы получать другой текст. вот так получилось:
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=koi8-r">
<TITLE>Превышен лимит</TITLE>
</HEAD><BODY>
<H1><font color="FF0000">ПРЕВЫШЕН ЛИМИТ</font></H1>
<H2>
</H2>
<HR>
<P>Заблокированный URL:
<A HREF="%U">%U</A>
<P>
<UL>
<LI>
<STRONG> Вы превысили месячный лимит на интеренет.
<br> Если Вы считаете это неправильным, свяжитесь с отделом АСУ по телефонам
1013 или 1066
<br>
<br>Если этот сайт необходим для работы, то он может быть открыт по служебной записке.
</STRONG>
<P>
</UL>
<P>С Уважением отдел АСУ.
</BODY></HTML>
allowedhost - мое правило проверки пользователей.
2. LightSquid абсолютно штатный. вот официальный сайт http://lightsquid.sourceforge.net/
Ставится и настраивается минут 5-10. Собственно вся настройка у меня заключалась в том,
что-бы рассортировать пользователей по группам. Для тех у кого еще есть http сервер
дополнительно будет красивая статистика. ;)
3. в /etc/squid создадим папку traf_limit
4. в /etc/squid/traf_limit создаем два файла
traf_limit.pl
#!/usr/bin/perl
#
# Довесок на LightSquid Project (c) 2004-2005 Sergey Erokhin aka ESL
#
# Скрипт создает файлик user_deny для ограничения инета по трафику
# Автор: Иван Лонин loninia@apksouz.ru 2008 год.
use File::Basename;
# коряво конечно напрямую писать путь к конфигу, но лениво было sh файлик для крона делать :)
require "/etc/squid/traf_limit/config";
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
@dat=localtime(time);
$year =1900+$dat[5];
$month=1 + $dat[4];
$filter="$year$month";
#print "$log_path/$filter*\n";
@daylist=glob("$log_path/$filter*");
foreach $daypath (sort @daylist) {
open FF,"<$daypath/.total";
$totaluser=<FF>;chomp $totaluser;$totaluser=~s/^user: //;
$totalsize=<FF>;chomp $totalsize;$totalsize=~s/^size: //;
while (<FF>) {
($user,$size,$hit)=split;
$h{$user}{size}+=$size;
$h{$user}{hit}+=$hit;
}
close FF;
}
#
$cummulative=0;
open RES,">$res_file";
print RES "# файл содержит юзеров превысивших квоту.\n
# автоматически переписывается скриптом traf_limit.pl\ndolzhen_bit_odin_user\n";
foreach $user (sort {$h{$b}{size}<=>$h{$a}{size}} keys %h) {
$all4user=$h{$user}{size}/1024/1024;
if ($vip_user{$user}{size} > 0) {
$limit=$vip_user{$user}{size};
}else{
$limit=$all_limit;
}
if ($all4user >= $limit) {
print RES "$user\n";
# print "$h{$user}{size}\n";
};
}
__END__
и файлик config
#!/usr/bin/perl
# конфигурационный файл для скрипта traf_limit.pl
#
# путь к логам lightsquid
$log_path="/www/lightsquid/report";
# файл в который пушутся пользователи превысившие лимит
$res_file="/etc/squid/user_deny.txt";
# лимит инета в мегабайтах
$all_limit=150;
# привелигированные пользователи с повышенным или пониженным лимитом
# для каждого пользователя строка формата:
#$vip_user={<имя_юзера}{size}=<лимит_в_мегабайтах>;
$vip_user{user1}{size}=5;
$vip_user{qwe}{size}=50;
назначим файликам нужного владельца и права на запуск
5. осталось в только в cron добавить запуск. Я сделал раз в сутки в 5-00.
делать вечером в 20 с чем нибудь категорически не рекомендую т.к. скрипт работает
на текущую дату (первого числа будут использоваться прошломесячные данные)
делаем
crontab -e
и добавляем для скрипта строчку вида
45 04 * * * /etc/squid/traf_limit/traf_limit.pl
и для сквида
0 05 * * * /etc/init.d/squid reload
собственно все :). естественно, что правильно оно начнет работать только с 1 числа следующего за установкой месяца.
Удачи.
Если есть вопросы пишите на loninia@apksouz.ru
В squid.conf
#Здесь описываем внешие ACL
external_acl_type InetGroup-proxy-08-20ww %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
# accesse in internet in work week from 08-00 to 20-00
external_acl_type InetGroup-proxy-08-20aw %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
# accesse in internet in all week from 08-00 to 20-00
external_acl_type InetGroup-proxy-00-24all %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
# accesse in internet in all week from 00-00 to 24-00
# Проверь свои пути
auth_param ntlm children 20
auth_param ntlm program /usr/local/samba/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 2 minutes
auth_param basic children 20
auth_param basic program /usr/local/samba/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
# Говорим, что нужна авторизация
acl you_domain proxy_auth REQUIRED
# Разграничиваем доступ по времени
acl work-week time MTWHF 08:00-20:00 # Доступ с 08-00 до 20-00 с понедельника по пятницу
acl all-week time SMTWHFA 08:00-20:00 # Доступ с 08-00 до 20-00 всю неделю
acl all-time time SMTWHFA 00:00-24:00 # Доступ круглосуточно всю неделю
# Осуществляем проверку на принадлежность к нужно группе
acl InetAccess-proxy-08-20ww external InetGroup-proxy-08-20ww proxy-08-20ww
acl InetAccess-proxy-08-20aw external InetGroup-proxy-08-20aw proxy-08-20aw
acl InetAccess-proxy-00-24all external InetGroup-proxy-00-24all proxy-00-24all
# Собираем все в кучу и проверяем на предмет получения дуступа к ИНТЕРНЕТ
http_access allow you_domain work-week InetAccess-proxy-08-20ww
http_access allow you_domain all-week InetAccess-proxy-08-20aw
http_access allow you_domain all-time InetAccess-proxy-00-24all
----------------------
proxy-08-20ww, proxy-08-20aw, proxy-00-24all - Группы в домене. В них заносишь тех юзеров, которым разрешен доступ.
wbinfo_group.pl - Используй именно этот скрипт. В том, что идет в комплекте со squid имеется ошибка.
Здесь она исправлена.
#!/usr/bin/perl -w
#
# external_acl helper to Squid to verify NT Domain group
# membership using /usr/local/samba/bin/wbinfo
#
# This program is put in the public domain by Jerry Murdock
# <jmurdock@itraktech.com>. It is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Author:
# Jerry Murdock <jmurdock@itraktech.com>
#
# Version history:
# 2002-07-05 Jerry Murdock <jmurdock@itraktech.com>
# Initial release
#
# external_acl uses shell style lines in it's protocol
require 'shellwords.pl';
# Disable output buffering
$|=1;
sub debug {
# Uncomment this to enable debugging
print STDERR "@_\n";
}
#
# Check if a user belongs to a group
#
sub check {
local($user, $group) = @_;
$groupSID = `/usr/local/samba/bin/wbinfo -n "$group"`;
# chop $groupSID;
# because wbinfo -n also returns the group number
$groupSID = substr($groupSID,0,index($groupSID," ",0));
$groupGID = `/usr/local/samba/bin/wbinfo -Y "$groupSID"`;
chop $groupGID;
# &debug( "User: -$user-\nGroup: -$group-\nSID: -$groupSID-\nGID: -$groupGID-");
return 'OK' if(`/usr/local/samba/bin/wbinfo -r \Q$user\E` =~ /^$groupGID$/m);
return 'ERR';
}
#
# Main loop
#
while (<STDIN>) {
chop;
&debug ("Got $_ from squid");
($user, $group) = &shellwords;
$ans = &check($user, $group);
&debug ("Sending $ans to squid");
print "$ans\n";
}
----------------------------------------------------------------------------------------------------------
smb.conf
[global]
workgroup = YOU-DOMAIN
realm = YOU-DOMAIN.RU
netbios name = demon
server string = Proxy Server
hosts allow = 10. 127.
winbind separator = \\ # Обрати на это внимание
winbind use default domain = yes
winbind uid = 10000-20000
winbind gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
template homedir = /home/winnt/%D/%U
template shell = /usr/local/bin/bash
max log size = 50
security = domain
password server = srv1 srv3
encrypt passwords = yes
srv1 и srv3 - PRIMARY and BACKUP контроллеры домена
----------------------------------------------------------------------------------------------------------
root@demon#tail -f /usr/local/squid/var/logs/cache.log
Got YOU-DOMAIN\\user1 proxy-08-20ww from squid
Sending ERR to squid
Got YOU-DOMAIN\\user1 proxy-08-20aw from squid
Sending ERR to squid
Got YOU-DOMAIN\\user1 proxy-00-24all from squid
Sending OK to squid
# Тут явно видно, что пользователя user1 нашли в группе proxy-00-24all и squid'у передано OK
Got YOU-DOMAIN\\user2 proxy-08-20ww from squid
Sending OK to squid
Got YOU-DOMAIN\\user3 proxy-08-20ww from squid
Sending OK to squid
root@demon#tail -f /usr/local/squid/var/logs/access.log
1147851551.270 20 10.66.107.56 TCP_IMS_HIT/304 251 GET http://img.mail.ru/mail/ru/css/mail-main1.css YOU-DOMAIN\user1 NONE/- text/css
Небольшое дополнение:
Информация о членстве в группе хранится в кеше squida (по умолчанию) 1 час, а в кеше Winbinda - 300 сек.
Чтобы не ждать столько времени при перемещении пользователя из одной группы в другую
советую добавить в squid.conf при описании внешиx ACL опцию ttl,примерно так:
external_acl_type InetGroup-proxy-08-20ww ttl=0 %LOGIN /usr/local/squid/libexec/wbinfo_group.pl
а в smb.conf:
[global]
winbind cache time = 0
Возникла необходимость разделять доступ пользователей сквид по группам AD.
Утилита wbinfo_group.pl, идущая со сквидом при большом числе запросов валила сквид
и были проблемы с кешированием данных. Возникла идея написать скрипт,
который через rpc запрос забирал членов необходимых доменных групп и скидывал их в текстовые файлы
на сервере, одновременно определяя изменения в них и при необходимости перегружая squid.
#!/usr/bin/perl -w
use Text::Diff;
$login="testlogin";
$password="secret_password";
$domain="MYDOMAIN";
$dc="dc.domain.ru";
$path="/usr/local/etc/squid/acl";
$reload_squid_cmd="/usr/local/sbin/squid -k reconfigure";
@ADgroups = ("inet_users","inet_vip","inet_sluz","inet_block");
foreach $group (@ADgroups)
{
@group_check= sort `/usr/local/bin/net rpc group MEMBERS $group -U $login%$password -S $dc`;
@group_check = grep {/^$domain\\/} @group_check;
$col=@group_check;
my $diff = diff \@group_check, "$path/$group.acl";
if ($diff and $col) {
open (GROUPFILE, ">$path/$group.acl") or die "Can't create $group.acl: $!";
print GROUPFILE @group_check;
$reconfigure++;
}
close GROUPFILE;
}
system("$reload_squid_cmd") if ($reconfigure);
Данный скрипт вешается в cron и запускается раз в 5 минут
Доработанная версия, изменения:
-поддержка пользователей и групп из доверенных доменов
-поддержка вложенных груп(т.е групп, содержащих в себе другие группы)
-возможность указания более одного контроллера домена
-отправка уведомлений по почте администратору о изменениях в группах
#!/usr/bin/perl -w
use Text::Diff;
$login="mylogin";
$password="cool_password";
$samba_prefix="/usr/local";
$winbind_separator="\\";
@group_domain = ("DOMAIN1\\inet_users","DOMAIN1\\inet_vip","DOMAIN2\\inet_sluz");
%domain_dc = (
'DOMAIN1' => [ 'dc.domain1.ru','bdc.domain1.ru' ],
'DOMAIN2' => [ 'ad1.domain2.ru','ad2.domain2.ru' ]
);
$acl_path="/usr/local/etc/squid/acl";
$reload_squid_cmd="/usr/local/sbin/squid -k reconfigure";
sub IsGroup
{
my $item = shift;
foreach $dc_group (@dc_groups) {
return 1 if ($item =~ /^\Q$dc_group\E$/i);
}
# print "$item\n";
return 0;
}
sub extractusers
{
my $group = shift;
my @group_sostav;
(my $domain, $group) = split(/\Q$winbind_separator\E/, uc($group), 2);
# print "$domain $group\n";
foreach $dc (@{ $domain_dc{$domain} }) {
# print "$dc\n";
@group_sostav = `$samba_prefix/bin/net rpc group MEMBERS "$group" -U $login%$password -S $dc`;
chomp(@group_sostav);
@group_sostav = grep { /^\w+\\.+/i } @group_sostav;
@group_sostav = grep { !/.+\$$/i } @group_sostav;
# print "@group_sostav\n";
last if @group_sostav;
}
foreach my $login (@group_sostav) {
$login =~ s/(\w+)\\(.+)/\L$1$winbind_separator$2\E/o;
my $isgroup = IsGroup($login);
extractusers($login) if $isgroup;
push (@users,"$login\n") if !$isgroup;
}
}
@dc_groups = `$samba_prefix/bin/wbinfo -g`;
chomp(@dc_groups);
foreach $group (@group_domain)
{
local @users;
extractusers($group);
my %Users = ();
my @unique = sort {uc($a) cmp uc($b)} grep{!$Users{$_}++}@users;
my $count = @unique;
my $diff = diff "$acl_path/$group.acl", \@unique;
if ($diff and $count) {
print "Internet acl group <$group> change:\n";
print "$diff\n" if $diff;;
open (GROUPFILE, ">$acl_path/$group.acl") or die "Can't create $group.acl: $!";
print GROUPFILE @unique;
close GROUPFILE;
$reconfigure++;
}
}
system("$reload_squid_cmd") if ($reconfigure);
Типичная задача: Разрешить доступ пользователю к списку сетей (например UA-IX)
и запретить мир, и наоборот, запретить доступ пользователя к списку сетей и разрешить все остальное
acl UAIXLIST dst "/usr/local/etc/squid/access_list/ua-ix.cfg" #Список сетей
acl host_alfa src 10.0.38.1 # первый хост
acl host_luna src 10.0.38.2 # второй хост
http_access allow host_alfa UAIXLIST # Разрешаем доступ к UAIXLIST
http_access deny host_alfa all # Запрещаем ко всему остальному
http_access deny host_luna UAIXLIST # Запрещаем доступ к UAIXLIST
http_access allow host_luna all # разрешаем ко всему остальному
В последних двух правилах возможна альтернатива:
http_access allow host_luna !UAIXLIST
содержимое /usr/local/etc/squid/access_list/ua-ix.cfg
62.16.0.0/19
62.64.64.0/18
62.80.160.0/19
62.149.0.0/19
62.221.32.0/24
62.221.33.0/24
62.221.34.0/24
62.221.37.0/24
......
Знаки комментариев # нежелательны, возможны ошибки(по крайней мере в squid-2.5.x). Повторы сетей из разряда
62.64.64.0/18
62.64.64.0/24
вызовут предупреждения о дублировании адресов сетей
Использовался сервер FreeBSD 4.11-p13
squid/2.5.STABLE9 также тестировалось на squid/2.5.STABLE12
acl stream rep_mime_type -i ^application/x-mms-framed$
http_reply_access deny stream
http_reply_access allow all
Имеем:
1. Учетные записи пользователей и групп в LDAP
2. Поднят домен на SAMBA-3.
На стороне сервера SQUID конфигурируем:
1. /etc/ldap.conf и /etc/nsswith.conf в результате getent passwd и getent group выдает список пользователей и групп
2. минимальный /etc/smb.conf:
[global]
workgroup = domain
netbios name = squid
load printers = no
printcap name = /dev/null
security = domain
password server = sambaserver
local master = no
os level = 33
domain master = no
preferred master = no
wins support = no
winbind use default domain = yes
winbind cache time = 1200
3. Заводим в домен net -Uadministrator join
4. Запускаем winbind, но при этом в /etc/nsswith.conf его _не_прописываем_
5. разрешаем чтение pipe winbindd процессу squid любым доступным способом,
например: setfacl -g:squid:rx /var/lib/samba/winbindd_privileged
6. samba в дальнейшем не нужна
7. далее в squid.conf:
# стандартные опции авторизации
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 5
auth_param ntlm max_challenge_reuses 0
auth_param ntlm max_challenge_lifetime 2 minutes
auth_param ntlm use_ntlm_negotiate off
auth_param basic program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-basic
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive off
# авторизация обязательна
acl NTLMauth proxy_auth REQUIRED
# определяем типы ACL
external_acl_type type_ldap_group1 ttl=60 children=1 %LOGIN
/usr/lib/squid/ squid_ldap_group.pl -b "cn=group1,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
external_acl_type type_ldap_group2 ttl=60 children=1 %LOGIN
/usr/lib/squid/squid_ldap_group.pl -b "cn=group2,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
external_acl_type type_ldap_group3 ttl=60 children=1 %LOGIN
/usr/lib/squid/squid_ldap_group.pl -b "cn=group3,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
# и сами ACL
acl acl_group1 external type_ldap_group1
acl acl_group2 external type_ldap_group2
acl acl_group3 external type_ldap_group3
ВСЕ. Дальше с ними можно работать как с обычными ACL, начиная от простого
http_access allow acl_group1
и заканчивая в вариантах пула и по времени.
При изменении информации в группе LDAP, squid примет изменения только через
время определенное в ttl, таким образом перезапускать его как -kreconfigure нет необходимости, что уже плюс!
Да вот еще, сам скрипт /usr/lib/squid/squid_ldap_group.pl очень прост:
#!/usr/bin/perl
#
# squid ldap group
# mailto:afletdinov\@dc.baikal.ru
#
use Getopt::Long qw(:config no_ignore_case);
use Net::LDAP;
use strict;
# const
my $VERSION = '20051122';
# variables
my $ldap;
my $user;
my $result;
#my $pass;
my $opt_groupdn = '';
my $opt_binddn = '';
my $opt_bindpasswd = '';
my $opt_secretfile = '';
my $opt_uri = '';
GetOptions(
'b=s' => \$opt_groupdn,
'D=s' => \$opt_binddn,
'w=s' => \$opt_bindpasswd,
'W=s' => \$opt_secretfile,
'H=s' => \$opt_uri );
# check: requires param
&usage unless($opt_groupdn and $opt_uri);
#connect
$ldap = Net::LDAP->new($opt_uri) or die("connect $opt_uri failed!");
# bind
if($opt_binddn){
# check: secretfile
if($opt_secretfile){
open(FILE, "<$opt_secretfile") or die("error read $opt_secretfile");
$opt_bindpasswd = <FILE>;
close(FILE); }
$result = $ldap->bind($opt_binddn, password=>$opt_bindpasswd);
# anonymous bind
}else{ $result = $ldap->bind(); }
$result->code and die($result->error);
# use buffers off
$| = 1;
# BASIC
while(<STDIN>){
chomp;
# format: user password
unless(/^(\S+)\s*(\S*)$/){ print "ERR\n"; next; }
$user = $1;
#$pass = $2;
# check: valid group
$result = $ldap->search(base=>$opt_groupdn, , filter=>"(memberUid=$user)");
# not found
unless($result->count){ print "ERR\n"; next; }
# auth: OK group: OK
print "OK\n";
}
exit;
sub usage(){
print <<EOF;
squid_ldap_group.pl version $VERSION
Usage: squid_ldap_group.pl -b "cn=www-access,ou=group,dc=ldap,dc=local" -H ldaps://ldap.local
-b GroupBaseDN (REQUIRED)
-H LdapURI (REQUIRED)
-D BindDN
-w BindPasswd
-W SecretFile
EOF
exit;
}
Squid должен быть собран с ./configure --enable-arp-acl
Далее в файле прописываем ACL'и формата:
acl aclname arp mac_address
Например:
acl test1 arp 11:43:67:F5:65:23
http_access allow test1
http_access deny all
При сборке не забыть configure --enable-delay-pools
В файле конфигурации:
acl all src 0.0.0.0/0.0.0.0
delay_pools 1
delay_class 1 1
delay_access 1 allow all
delay_parameters 1 64000/64000 # 512 kbits == 64 kbytes per second
Нередко из-за отсутствия обработчика сигнала SIGCHLD в родительском процессе,
после завершения дочерней программы, остаются "<defunct>" или zombie процессы.
Zombie процессы не занимают системные ресурсы, кроме записи в таблице процессов,
что может вызвать ее переполнение и как следствие блокировку запуска новых процессов,
при большой интенсивности появления zombie. Zombie исчезают после завершения работы
родительского процесса, но записи в таблице также можно очистить принудительным путем.
Получаем список zombie процессов:
ps -ecl |grep "Z"
F S UID PID PPID CLS PRI ADDR SZ WCHAN TTY TIME CMD
0 Z 100 27841 27840 - 0 - 0 - ? 0:00 <defunct>
"kill" и "kill -9" в случае zombie использовать бесполезно. В Solaris для эмуляции вызова wait()
для чтения кода возврата из таблицы процессов существует утилита preap:
preap 27841
27841: exited with status 0
Daylight Saving Time Rule на закладке Regional у SPA9хх, PAP2 и пр. в России устанавливается в
start=3/-1/5/02:0:0;end=10/-1/4/02:0:0;save=1
Time Zone GMT +03:00 (в Москве), и указываются работающие NTP сервера.
Вышеприведенная строка прибавляет 1 час к времени с 02:00 последнего воскресенья марта,
и перестает его добавлять в 02:00 в последнее воскресенье октября.
Если набитые данные в форме случайно необратимо потеряны, например, в opera ошибочный клик
может привести с загрузке нового URL в текущем окне с невозможностью возврата к предыдущему,
можно попытаться их восстановить следующим образом.
Находим PID процесса:
ps aux | grep firefox-bin
ps aux | grep opera
Делаем дамп:
gdb -p 2408
(gdb) gcore
Ищем текст:
strings core.* | less
Если браузер рухнул, то данные можно попробовать найти в /dev/mem, например:
dd if=/dev/mem of=./mem.dump
strings ./mem.dump > mem.txt
В очень многих howto по настройки dial-in рекомендуют
в /etc/mgetty+sendfax/login.config прописывать строки
/AutoPPP/ - a_ppp /usr/sbin/pppd auth -chap +pap login
* - - /bin/login @
что есть не совсем правильно, если требуется только ppp (или emsi и т.д.), ибо
при такой конфигурации любой дозвонившийся голосом может завесить
dial-in. Если не класть трубку
хотя бы минуту, то на той стороне mgetty успевает запустить /bin/login, и, естественно,
на последующие звонки модем не отвечает.
Не прописывать строчку строчку
* - - /bin/login @
не является выходом - mgetty всё равно запускает /bin/login если не удалось
распознать ppp. Проблему можно решить, заменив в конфиге /bin/login на
/sbin/nologin:
* - - /sbin/nologin @
FreeBSD (%U.%N.%P=user.имя_процесса.pid, подробнее - man core):
sysctl -w kern.corefile=/tmp/%U.%N.%P.core
Linux (последние ядра):
sysctl -w kernel.core_pattern=/tmp/%e.%p.core (строка не больше 64 байт)
или через /proc/sys/kernel/core_pattern
Максимальный размер core файла задается через:
ulimit -c 100
Нужно использовать не команду adduser, а команду pw (man pw, pw useradd help). Например:
pw useradd -n логин -c 'комментарий, фио' -d /home/логин -m -s /bin/true
1. Монтируем новый жесткий диск.
2. Создаем разделы на новом диске с помощью fdisk (для freebsd /stand/sysintall или /usr/sbin/sysinstall). Создаем файловую систему.
3. Копируем файлы на новый диск (кроме каталога /mnt, не допускаем рекурсии !!!)
find / -xdev | cpio -pdumv /mnt/new - на каждый раздел.
или tar cf - /bin /usr /etc д.р.| tar xf - -C /mnt/new
или cd /mnt/new; dump -0u -f - /директории| restore -r -f -
или cp -Raxv / /mnt/new - на каждый раздел.
или pax -r -w -p e / /mnt (говорят копирует гораздо быстрее чем dump/restore)
или просто копируем в Midnight Commander'е (не рекомендуется).
Лучший способ - dump/restore или rsync, иначе можно потерять расширенные атрибуты и ACL.
4. Редактируем /mnt/new/etc/fstab
5. Создаем с помощью /dev/MAKEDEV недостающие устройства (для нового типа диска).
6. mkdir /mnt/new/proc /mnt/new/mnt
7a. Только для Linux: правка /etc/lilo.conf и запуск lilo -r /mnt/new -b /dev/hdb
При возникновении ошибки при загрузке:
Было:
boot=/dev/sda
default=linux-up
image=/boot/vmlinuz-up
label=linux-up
root=/dev/sda2
initrd=/boot/initrd-up.img
Предположим, что дубликат размещен на /dev/sdb, тогда меняем boot=/dev/sda на boot=/dev/sdb
и добавляем:
disk=/dev/sdb
bios=0x80
Выполняем lilo -r /mnt/new и не забываем убирать исправления из lilo.conf.
7b. Для freebsd загрузчик устанавливается после разбиения диска на разделы через sysintall.
PS. Если диски одинаковые можно использовать dd if=/dev/hda of=/dev/hdb,
если разделы одинаковые: dd if=/dev/hda1 of=/dev/hdb1
Итак, пришло время поднять IPv4-IPv6 gateway, чтобы ходить в мир "другого интернета", коим он скоро будет.
Самым простым способом получить IPv6 адрес оказалось получить подключение от http://go6.net
Идем на этот сайт и регистрируемся http://go6.net/4105/register.asp
Тут же они предлагают скачать софт и поставить, например для Windows вида "скачай и запусти"
http://go6.net/4105/download.asp
Но это не совсем наш метод, мы будем подключать сервер на FreeBSD 7.0 к этой сети.
Ядро у нас собрано с поддержкой IPV6, т.е. с options INET6 (ядро GENERIC уже
поддерживает этот протокол и если вы его не отключали, значит, он у вас есть)
Итак, ставим клиента, то, что они предлагают скачивать - есть в портах
Port: gateway6-5.0_2
Path: /usr/ports/net/gateway6
Info: Gateway6 Tunnel Setup Protocol Client - Free IPv6 tunnel
B-deps:
R-deps:
WWW: http://www.go6.net/
Приступаем к установке:
cd /usr/ports/net/gateway6
make install clean
Буквально через несколько минут клиент будет установлен
Отредактируйте его конфигурационный файл /usr/local/etc/gw6c.conf
userid=
passwd=
Пропишите туда ваше имя и пароль которые указали при регистрации на сайте.
На этом начальная настройка закончена, для дальнейшей настройки читайте документацию.
Как я понял, выдается целая сеть и для авторизованных пользователей http://go6.net/4105/freenet.asp,
тем самым можно все компьютеры дома подключить на реальные статические IPv6 адреса.
server=broker.freenet6.net
broker.freenet6.net - это имя сервера для подключения (написано в письме при регистрации)
# Включить использование авторизации
auth_method=any
# Писать логи в syslogd
log_syslog=3
Теперь осталось запустить его
echo 'gateway6_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/gateway6 start
И смотрим
# tail -f /var/log/messages
Oct 17 18:39:38 lola gw6c: Gateway6 Client v5.0-RELEASE build Oct 17 2008-14:56:32
Oct 17 18:39:38 lola gw6c: Establishing connection to tunnel broker broker.freenet6.net using reliable UDP.
Oct 17 18:39:42 lola gw6c: Connection to broker.freenet6.net established.
Oct 17 18:39:45 lola gw6c: Authentication success.
Oct 17 18:39:45 lola gw6c: Got tunnel parameters from server. Setting up local tunnel.
Oct 17 18:39:45 lola gw6c: Executing configuration script: /bin/sh "/usr/local/share/gateway6/freebsd.sh".
Oct 17 18:39:46 lola gw6c: Script completed successfully.
Oct 17 18:39:46 lola gw6c: Your IPv6 address is 2001:05c0:8fff:fffe:0000:0000:0000:c243.
Oct 17 18:39:46 lola gw6c: The tunnel type is v6udpv4.
# ifconfig
tun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1280
inet6 2001:5c0:8fff:fffe::c243 --> 2001:5c0:8fff:fffe::c242 prefixlen 128
Opened by PID 873
# traceroute6 www.jp.freebsd.org
...
# ping6 www.jp.freebsd.org
...
Все прекрасно работает не смотря на то, что выход осуществляется в мир через
NAT на модеме.
Итак, осталось только понять, "зачем это надо", но ясно одно - за этим будущее.
А еще можно посмотреть на танцующую черепаху на http://www.kame.net/ :-)
Также рекомендую прочитать документацию (главу в
HandBook http://www.freebsd.org/doc/ru_RU.KOI8-R/books/handbook/network-ipv6.html)
по поддержке протокола IPv6 в системе FreeBSD.
Создаем снапшот test1 раздела /home
mount -v -u -o snapshot /home/snapshot/test1 /home
или другой метод:
mksnap_ffs /home /home/snapshot/test1
Привязываем снапшот к устройству /dev/md1:
mdconfig -a -t vnode -f /home/snapshot/test1 -u 1
При необходимости снапшот можно смонтировать и посмотреть его содержимое:
mount -o ro /dev/md1 /mnt
....
umount /mnt
Копируем содержимое раздела на второй диск:
dd if=/dev/md1 of=/dev/ad4s1f bs=16k
Отключаем снапшот
mdconfig -d -u 1
Выполняем fsck на новом разделе:
fsck -f /dev/ad4s1f
Есть компьютер с FreeBSD 7.0 (но должно работать и для остальных версий)
Подключение к интернету производится через pppoe. Провайдер раз в сутки обрывает подключение,
соответственно при смене ip (он динамический) ntpd клинит - по команде ntpq -c pe
в колонке refid для всех серверов будет .INIT.
Когда искал решение, наткнулся на следующий скрипт (немного модифицировал для FreeBSD):
#!/bin/sh
#
# reconfigNtpd, written by Jan Ceuleers, March 2003, revised October 2003
#
# Purpose: ntpd running on a machine that has intermittent connectivity to
# the Internet, and that does not have a static public IP address,
# loses its associations with public NTP servers, even after the
# connection to the Internet has been restored.
# Restarting the ntpd daemon is a possibility, but the downside
# is that this causes time not to be served to local clients until
# ntpd has regained synchronisation.
# A better way is to configure at least one local clock (the local
# clock 127.127.1.0 at high stratum and/or a refclock), to cover
# for the periods when there is no Internet connectivity, and to
# use this script to unconfig/add{server,peer} all public time
# servers at runtime (i.e. without restarting the daemon)
#
# Usage: reconfigNtpd | ntpdc
#
# Bugs: * This script only generates unconfig/addpeer and unconfig/addserver
# pairs. Any relevant fudge statements or iburst options etc. are
# ignored.
#
# * Location of keys file is hard-coded rather than being derived from
# ntp.conf
#
###
#
# Get keyid and password from /etc/ntp/keys
#
###
set -- $(grep "^15" < /etc/ntp.keys)
echo keyid $1
echo passwd $3
###
#
# Derive unconfig commands from ntpdc output
#
###
ntpdc -n -p | awk '!/==/ && !/^ / { if (substr($1,2) !~ /^127.127./)
print "unconfig " substr($1,2) }'
###
#
# Derive addserver commands from /etc/ntp.conf
#
###
awk '/^server[[:blank:]]/ { if ($2 !~ /^127.127./) print "addserver " $2
}' /etc/ntp.conf
###
#
# Derive addpeer commands from /etc/ntp.conf
#
###
awk '/^peer[[:blank:]]/ { print "addpeer " $2 }' /etc/ntp.conf
echo quit
(источник - http://www.arda.homeunix.net/ntpsetup.html)
Записываем куда-нибудь, где не потеряется.
Конфиг ntpd следующего вида:
/etc/ntp.conf
server <сервер>
server <сервер>
logfile /var/log/ntp.log
driftfile /var/db/ntp.drift
statsdir /var/db/ntpstats/
keys /etc/ntp.keys
trustedkey 1 2 15
controlkey 15 # ntpq
requestkey 15 # ntpdc
Теперь надо сгенерить ключи для управления.
env RANDFILE=/dev/random ntp-keygen
В директории, где запускали ntp-keygen будет файл
с ключами и симлинк ntpkey_MD5key_<название хоста>
В нём будут записаны 16 ключей надо взять содержимое этого файла и запихнуть его в /etc/ntp.keys
теперь (пере)запускаем ntpd
Для проверки делаем ./reconfigNtpd | ntpdc
Если про ошибки ничего не будет написано, значит всё хорошо.
Теперь цепляем это на ppp
Для этого пишем в файл /etc/ppp/ppp.linkup такое:
<название подключения>:
!bg sh -c "sleep 5; <путь>/reconfigNtpd | ntpdc"
Задержку в 5 секунд сделал для того, чтобы ntpdc запустился после прописывания маршрута.
Q. Как я могу установить и настроить службу iSCSI на сервере FreeBSD ?
A. FreeBSD 7.x полностью поддерживает iSCSI. Старые версии, такие как FreeBSD 6.3 требуют обратного
портирования для поддержки iSCSI. Следущие инструкции приведены для настройки iSCSI только под FreeBSD 7.0.
FreeBSD iscsi_initiator driver
iscsi_initiator в ядре FreeBSD реализует страндарт сетевого протокола Internet SCSI (iSCSI),
взаимодействует с пользовательским окружением iscontrol и обеспечивает доступ к удаленным виртуальным SCSI устройствам.
Компилирование драйвера
обратите внимание на то, что FreeBSD 7.x поставляется с уже скомпилированным драйвером.
Вы можете пропустить этот шаг, если драйвер /boot/kernel/iscsi_initiator.ko
уже присутствует в вашей системе.
Для компиляции ядра с драйвером, выполните следущее:
# cd /usr/src/sys/i386/conf
# cp GENERIC ISCSIKERNEL
# vi ISCSIKERNEL
Вставьте строку:
device iscsi_initiator
Сохраните и закройте файл конфигурации. Соберите ядро:
# cd /usr/src
# make buildkernel KERNCONF=ISCSIKERNEL
Установите ядро:
# make installkernel KERNCONF=ISCSIKERNEL
Перезагрузите систему:
# reboot
Установка драйвера iSCSI в FreeBSD
Нам необходим драйвер ядра FreeBSD для протокола iSCSI, который называется /boot/kernel/iscsi_initiator.ko.
Загрузите его можно с правами пользователя root следующей командой:
# kldload -v iscsi_initiator.ko
Вывод:
Loaded iscsi_initiator.ko, id=6
Для загрузки драйвера во время начальной загрузки, поместите слудующую строку в /boot/loader.conf:
# vi /boot/loader.conf
# Beginning of the iSCSI block added by Vivek
iscsi_initiator_load="YES"
# End of the block added by Vivek
Сохраните и закройте файл.
Команда iscontrol для подключения, предоставления и контроля сессии iSCSI initiator.
Теперь нам необходимо использовать команду iscontrol. Сперва просмотрим сессии:
# iscontrol -d targetaddress=iSCSI-SERVER-IP-ADDRESS initiatorname=nxl
# iscontrol -v -d targetaddress=192.168.1.100 initiatorname=nxl
Пожалуйста, запишите список доступных targetnames/targetadresses. Как только будет известно targetname,
отредактируйте файл /etc/iscsi.conf:
# vi /etc/iscsi.conf
Укажите директивы подобным образом:
officeiscsi {
authmethod = CHAP
chapIName = YOUR-ISCSI-USERNAME
chapSecret = YOUR-ISCSI-PASSWORD
initiatorname = nxl
TargetName = iqn.XYZZZZZZZZZZZZZ # whatever "iscontrol -v -d " gives you
TargetAddress = 192.168.1.100:3260,1 # your iscsi server IP
}
Сохраните и закройте файл.
Где:
officeiscsi { : Начало конфигурации iSCSI.
authmethod : Установить в качестве метода аутентификации chap
chapIName : Имя
chapSecret : Пароль
initiatorname : Если не указано другое, то iqn.2005-01.il.ac.huji.cs:<hostname>
TargetName : Имя, под которым будет изветен target. Не путайте его с target address,
который назначается администратором или через поиск устройств.
TargetAddress : Имеет вид domainname[:port][,portal-group-tag] согласно RFC:
domainname может быть определен как имя DNS, адрес IPv4 в десятичном представлении
или IPv6 адрес, как указано в [RFC2732].
} : Конец конфигурации
Старт сессии iSCSI
Следущие команды читают опции из /etc/iscsi.conf, используя targetaddress в блоке,
называемом officeiscsi, и запускают сессию iscsi.
# iscontrol -c /etc/iscsi.conf -n officeiscsi
Как только вы выполните команду iscontrol, должно создаться новое устройство в каталоге /dev.
Для проверки выполним команду dmesg:
# dmesg
Форматируем диск iSCSI
Запустим sysinstall для форматирования обнаруженного устройства iSCSI:
# sysinstall
Выбираем Custom > 3 Partition > Выбираем устройство iSCSI по имени da1. После форматирования вводим:
# mkdir /iscsi
# mount /dev/da1s1 /iscsi
Возможно вам понадобится обновить файл /etc/fstab:
/dev/ad1s1 /iscsi ufs rw 3 3
В логе smartd появились подобные свидетельства наличия нечитаемых секторов на диске:
smartd[798]: Device: /dev/ad5, 15 Currently unreadable (pending) sectors
smartd[798]: Device: /dev/ad5, 15 Offline uncorrectable sectors
SMART тестирование подтвердило подозрения:
Запускаем фоновый тест диска, не мешающий основной работе:
smartctl -t long /dev/ad5
Ждем завершения периодически просматривая статус:
smartctl -l selftest /dev/ad5
В итоге смотрим содержимое лога, в самом конце вывода:
smartctl -a /dev/ad5
Имеем:
# 1 Extended offline Completed: read failure 90% 2916 10373954
Выявляем полный список сбойных секторов, путем чтения всех данных с диска:
dd if=/dev/ad5 of=/dev/null bs=512 conv=noerror,sync
В один прекрасный момент появятся надписи вида:
dd: /dev/ad5: Input/output error
10373954+0 records in
10373954+0 records out
5311464448 bytes transferred in 2427.397393 secs (2188131 bytes/sec)
В системном логе увидим:
kernel: ad5: TIMEOUT - READ_DMA retrying (1 retry left) LBA=10373954
kernel: ad5: TIMEOUT - READ_DMA retrying (0 retries left) LBA=10373954
....
kernel: ad5: FAILURE - READ_DMA timed out LBA=10374109
kernel: ad5: TIMEOUT - READ_DMA retrying (1 retry left) LBA=10374113
Проверяем, каждый участок еще раз:
dd if=/dev/ad5 of=/dev/null bs=512 count=1 skip=10373954 conv=noerror,sync
Смотрим какой файл в ФС подпадает под этот блок.
Смотрим и примерно вычисляем номер раздела на который приходится сбойный сектор (LBA 10373954):
fdisk -s /dev/ad5
/dev/ad5: 775221 cyl 16 hd 63 sec
Part Start Size Type Flags
1: 63 398444067 0xa5 0x80
2: 398444130 382973535 0xa5 0x80
10373954 - 63 = 10373891
disklabel /dev/ad5s1
# /dev/ad5s1:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 2097152 0 4.2BSD 2048 16384 28552
b: 4194304 2097152 swap
c: 398444067 0 unused 0 0 # "raw" part
d: 2097152 6291456 4.2BSD 2048 16384 28552
e: 10485760 8388608 4.2BSD 2048 16384 28552
f: 104857600 18874368 4.2BSD 2048 16384 28552
g: 104857600 123731968 4.2BSD 2048 16384 28552
h: 162127234 228589568 4.2BSD 2048 16384 28552
Видим, что 10373891 приходится на раздел /dev/ad5s1e
Расчитываем смещение относительно начала раздела:
10373891 - 8388608 = 1985283
Находим иноду, которой принадлежит заданный блок:
fsdb -r /dev/ad5s1e
findblk 1985283
повторяем для каждого сбойного сектора
(для Linux нужно использовать debugfs - http://smartmontools.sourceforge.net/BadBlockHowTo.txt)
Пытаемся записать данные в сбойный сектор, чтобы инициировать процесс
ремапинга на диске.
sysctl kern.geom.debugflags=16 # иначе будет dd: /dev/ad5: Operation not permitted)
dd if=/dev/zero of=/dev/ad5 bs=512 count=1 skip=10373954 conv=noerror,sync
sysctl kern.geom.debugflags=0
Если после записи сектор начал читаться - все ok,
если нет - резервная область на диске уже заполнена, пробуем запретить обращещние окружающих секторов в ФС:
man badsect
/dev/ad5s1e примонтирован как /usr, создаем директорию /usr/BAD и выполняем
badsect /usr/BAD 1985283
fsck -y /dev/ad5s1e
Полезные порты:
/usr/ports/sysutils/recoverdm
/usr/ports/sysutils/diskcheckd
Драйвера для данного беспроводного адаптера в ядре FreeBSD на данный (март 2008) не существует,
но я расскажу как сконвертировать windows-драйвера в ko-модуль.
1. качаем официальный драйвер:
http://www.x-drivers.ru/component/option,com_remository/itemid,36/func,fileinfo/id,28277/
2. конвертируем его:
%ndisgen bcmwl5.inf bcmwl5.sys
3. подгружаем полученный модуль:
%kldload bcmwl5_sys.ko
Пожалуйста:
% ifconfig -l
em0 lo0 ndis0
ndis0 - появившийся wifi-интерфейс.
Пытаясь добавить библиотеку libnsl запустил следующее:
ldconfig -m /usr/compat/linux/lib/
теперь на любой ввод машина выдаёт:
/libexec/ld-elf.so.1: Undefined symbol "__stdinp" referenced from COPY relocation in
Для того чтобы вернуться к нормальной работе:
1. грузимся в однопользовательский режим
2. монтируем Var #>mount -rw /var
3. правим хинты #>ldconfig /lib
4. монтируем Usr #>mount -rw /usr
5. добавляем для начального комплекта #>ldconfig -m /usr/lib и дальше по списку
/var/run/ld-elf.so.hints:
search directories: /lib:/usr/lib:/usr/lib/compat:/usr/X11R6/lib:/usr/local/lib:/usr/local/lib/compat:\
/usr/local/lib/compat/pkg:/usr/local/lib/mysql:/usr/local/lib/apache2
6. перегружаемся
Если необходимо загрузить библиотеки имеющие права записи для
группы или с владельцом отличным от root, установите в YES для
отключения проверок безопасности ldconfig (опция -i).
ldconfig_insecure="NO"
Пути, по которым ищутся разделяемые библиотеки
ldconfig_paths="/usr/lib/compat /usr/X11R6/lib /usr/local/lib \
/usr/local/lib/compat/pkg /usr/compat/linux/lib"
Пути, по которым ищутся разделяемые библиотеки a.out
ldconfig_paths_aout="/usr/lib/compat/aout /usr/X11R6/lib/aout /usr/local/lib/aout"
Пример того как можно ограничить скорость на интерфейсе:
#!/bin/sh
kldload ng_ether
kldload ng_car
ngctl -f- <<-EOF
mkpeer re0: car lower lower
name re0:lower re0_car
connect re0: re0_car: upper upper
msg re0_car: setconf { upstream={ cbs=8192 ebs=65535 cir=100000 greenAction=1 yellowAction=1 redAction=2 mode=2 } downstream={ cbs=8192 ebs=65535 cir=1000000 greenAction=1 yellowAction=1 redAction=2 mode=2 } }
EOF
Если считать что к re0 у нас подключен клиент, то upstream это трафик от клиента в инет,
downstream - трафик из инета к клиенту.
cir - скорость в битах в секунду (в мане опечатка)
mode=2 - это RED
цифры для cbs/ebs взяты с потолка. Рекомендации по поводу этих
параметров можно поискать в инете по ключевым словам random early detection
можно тут посмотреть например
http://www.icir.org/floyd/REDparameters.txt
С помощью этого маленького скрипта, можно выполнить освобождение netgraph нод,
которые оставляет за собой упавший в "корку" MPD3.
#!/bin/sh
for j in "" 1 2 3 4 5 6 7 8 9 10 11 12; do
for i in 0 1 2 3 4 5 6 7 8 9; do
echo $j$i
ngctl shutdown ng$j$i:
ngctl shutdown mpd$1-pptp$j$i:
done
done
При установке сетевой карточки Asus NX1001, я не смог обнаружить её при наборе
команды ifconfig. А также в sysinstall->Configure->Networking.
Первое, что мне пришло в голову конфликт с ACPI, после отключения в БИОСе ACPI -
результатов никаких не дало. Поэтому пришлось заняться поисками решения
этой проблемы копаясь в интернете, особо на сайте freebsd.org. Найдя похожую
проблему работы с сетевой картой Asus NX1001 в FreeBSD 6.2, вот что в итоге
необходимо было сделать.
Набрав команду pciconf -lv и найдя среди результатов вывода
"Sundance ST201 10/100BaseTX".
Мне пришлось дописать в файлах:
/usr/src/sys/pci/if_ste.c
/usr/src/sys/pci/if_stereg.h
нижеследующее (строка AS_VENDORID...), в файле if_ste.c:
static struct ste_type ste_devs[]={
{ST_VENDORID, ST_DEVICEID_ST201,"Sundance ST201 10/100BaseTX"},
{AS_VENDORID, AS_DEVICEID_NX1001,"ASUS NX1001 10/100BaseTX"},
{DL_VENDORID, DL_DEVICEID_DL100050,"D-Link DL10050 10/100BaseTX"},
{0,0,NULL}
};
в файле if_stereg.h:
#define AS_VENDORID 0x13F0
#define AS_DEVICEID_NX1001 0x0200
После этого мы обязаны пересобрать наше старое ядро:
cd /usr/src/sys/i386/conf/
cp GENERIC GATEWAY
ee GATEWAY
config GATEWAY
cd ../compile/GATEWAY
make depend
make
make install
shutdown -r now
В итоге в нашем случае появляется сетевая карточка в устройствах как sto0.
Копируем в текущую директорию passwd и shadow файлы из Linux. Запускаем:
./mkpasswd.pl > new.master.passwd
Открываем файл new.master.passwd в текстовом редакторе и заменяем строки с описанием системных аккаунтов из /etc/master.passwd
Копируем new.master.passwd в /etc. Делаем бэкап /etc/master.passwd.
Перестраиваем хэши через запуск команды
pwd_mkdb -p /etc/new.master.passwd
Если всплыли ошибки повторяем запуск pwd_mkdb на бэкап файле, для отката изменений.
Скрипт mkpasswd.pl
#!/usr/local/bin/perl
# Listing 21.1. Sample Perl Script to Convert
# a Linux User Database for Use in FreeBSD
# Set the following to the location of bash on your FreeBSD
#machine (if installed),
# or to /bin/csh to switch /bin/bash users to csh
$newshell = "/bin/sh";
open ( PASS, '< ./passwd' );
@passwd = <PASS>; # Read in the passwd file
close PASS;
open ( SHAD, '< ./shadow' );
@shadow = <SHAD>; # Read in the shadow file
close SHAD;
foreach $user (@shadow) {
@sdata = split(/:/,$user);
$passhash{$sdata[0]} = $sdata[1]; # Make a lookup table based on usernames
}
foreach $user (@passwd) {
@pdata = split(/:/,$user);
$pdata[6] = $newshell."n" if ($pdata[6] eq "/bin/bashn");
$pdata[1] = $passhash{$pdata[0]}; # Replace the "x" with the password hash
splice (@pdata,4,0,undef,"0","0"); # Splice in extra blank fields
foreach (@pdata) { # Print the combined output line
print "$_";
print ":" unless ($_ =~ /n/);
}
}
откуда взял скрипт непомню :(
1. в ~/.xinitrc пишем (именно сюда а не в /etc/profiles потому как
системная консоль FreeBSD не поддерживает юникод, посему локаль сия
будет использоваться только в иксах):
export LANG='ru_RU.UTF-8'
export LC_ALL='ru_RU.UTF-8'
2. выполняем конвертацию содержимого файловой системы из koi8-r в
UTF-8 (необходим порт converters/convmv):
%convmv -f koi8-r -t UTF-8 путь_к_разделу/* --notest -r
3. далее все зависит от терминала, если у вас что-то вроде
gnome-terminal, то достаточно будет сменить кодировку в опциях на
UTF-8, если же у вас что-то вроде xterm'а, тогда в ~/.Xresources
необходимо будет поменять шрифт, например так (для этого шрифта
необходим пакет x11-fonts/terminus-font):
XTerm*font: -*-terminus-medium-*-*-*-*-*-*-*-*-iso10646-1
для syscons(4) на i386:
1. ставим sysutils/jfbterm и textproc/uim-m17nlib
2. меняем стандартную переключалку языка с Shift+Space на Ctrl+\
добавлением в ~/.uim
(define-key generic-on-key? "<Control>\\")
(define-key generic-off-key? "<Control>\\")
3. ставим локаль и добавляем запуск uim-fep и jfbterm в ~/.profile
export LANG=ru_RU.UTF-8
exec jfbterm -e uim-fep
или в ~/.login (для tcsh)
setenv LANG ru_RU.UTF-8
exec jfbterm -e uim-fep
Что надо сделать на FreeBSD сервере:
1. Подключаем COM1 кабель
2. Заходим под root и пишем:
echo "-Dh" > /boot.config
3. В файле /etc/ttys заменяем строчку
ttyd0 "/usr/libexec/getty std.9600" dialup off secure
на
ttyd0 "/usr/libexec/getty std.9600" vt100 on secure
4. Перезагружаем FreeBSD.
Что надо сделать на Windows XP машине (клиент):
1. Start -> All Programs -> Accessories -> Communications -> HyperTerminal
2. В открывшемся окне New Connections в поле Name пишем что нить типа freebsd-serial
3. В окне Connect To выбираем номер ком-порта (к примеру COM1)
4. В окне COMx Properties на вкладке Port Settings надо выставить следующие значения:
Bits per second: 9600
Data bits: 8
Parity: None
Stop bits: 1
Flow control: Xon / Xoff
и на жать на кнопку ОК
5. Соединение установиться. Далее можно сохранить File -> Save.
6. Можно работать.
Что нужно сделать если в место Windows XP для управления используется соседняя FreeBSD машина:
в зависимости от версии FreeBSD:
cu -s 9600 -l /dev/cuad0
cu -s 9600 -l /dev/cuaa0
где cuaaX/cuaaX устройства ком порта
sudo - для настройки рутовых привилегий, выдаваемых другим пользователям без необходимости сообщать рутовый пароль.
vim (vim-lite) - редактор. Совмещает удобства vi и привычки с "обычных" редакторов
yawho - показывает, кто сидит, откуда и что запущено и т.п. Напоминает "w", но поудобнее.
whowatch - очень удобная утилитка для просмотра в реальном времени процессов других залогиненных пользователей и элементарных операций (посылка сигналов kill, разлогинивание и т.д.)
mtr - утилита, обьединяющая наподобии виндового "pathping" команды traceroute и ping. Весьма удобна для проверки сети.
lynx-ssl - браузер с поддержкой ssl, работающий в текстовом режиме. Удобен. Полезен при проверке корректности html кода.
elinks - продвинутая версия lynx. Встроенный менеджер закачек, готовность к работе на русском языке без дополнительных телодвижений
ipcalc - Сетевой калькулятор. Противопоказан людям, готовящимся к сдачи CCNA и рассчитывающим все сети вручную ;-)
В ОС FreeBSD иногда появляется проблема, когда rcNG-скрипт запускает процесс
(процесс запускается нормально, pid-файл создается, с правами все в порядке),
но не хочет его останавливать. Например, SpamAssassin:
# /usr/local/etc/rc.d/sa-spamd start
Starting spamd.
# ls -l /var/run/spamd/spamd.pid
-rw-r--r-- 1 root spamd 6 1 авг 08:37 spamd.pid
# /usr/local/etc/rc.d/sa-spamd stop
spamd not running? (check /var/run/spamd/spamd.pid)
Причина проблемы не очевидна, решение находится из man ps:
если длина аргументов больше значения переменной ядра kern.
ps_arg_cache_limit, то ps показывает не полную строку запуска процесса,
а лишь само имя процесса в квадратных скобках. И бывают случаи (как в SpamAssassin),
когда имя процесса не совпадает с именем в rcNG-скрипте (переменная name).
Поэтому rcNG-скрипт не обнаруживает запущенного ним процесса в выводе ps.
Решение - увеличить значение переменной ядра kern.ps_arg_cache_limit в sysctl.conf.
Замечание:
Если в rc.conf в spamd_flags присутствует --debug, то rcNG-скрипт работать не будет,
потому что в этом случае вывод ps axww меняется.
Например вместо:
68514 ?? Ss 0:11,27 /usr/local/bin/spamd --siteconfigpath=/usr/local/etc/mail/spamassassin
-x -d -l --max-conn-per-child=128 --timeout-tcp=10 --timeout-child=300
--pidfile=/var/run/spamd/spamd.pid --syslog=local0 --username=spamd --groupname=spamd
--allowed-ips=127.0.0.0/8 --listen-ip=127.0.0.1 -d -r /var/run/spamd/spamd.pid (perl5.8.8)
получаем
68514 ?? Ss 0:11,27 /usr/local/bin/perl -T -w /usr/local/bin/spamd
--siteconfigpath=/usr/local/etc/mail/spamassassin -x -d -l --max-conn-per-child=128
--timeout-tcp=10 --timeout-child=300 --pidfile=/var/run/spamd/spamd.pid --syslog=local0
--username=spamd --groupname=spamd --allowed-ips=127.0.0.0/8 --listen-ip=127.0.0.1 --debug
received-header -d -r /var/run/spamd/spamd.pid
Решение этой проблемы - правка rc.subr, что есть дело нелегкое. И проще помнить про этот нюанс.
Требуется создать журналируемую файловую систему UFS2 объемом более 1 Гб на FreeBSD 6.1-STABLE.
Для начала необходимо обновить дерево исходных текстов (/usr/src) до стабильной версии.
После чего переходим в каталог /usr/src и создаем там необходимые директории:
# cd /usr/src
# mkdir {sbin/geom/class/journal,sys/geom/journal,sys/modules/geom/geom_journal}
Теперь качаем сам патч:
# fetch http://people.freebsd.org/%7Epjd/patches/gjournal6.patch
Накладываем его на исходные тексты:
# patch < gjournal6.patch
Компилируем и ставим geom_journal (возможно имеет смысл пересобрать весь мир):
Далее есть два пути - пересобрать весь "мир" (см. файл /usr/src/UPDATING), либо пересобрать только то, что было модифицировано.
Предпочтительней первый путь, однако можно обойтись и без него. Для этого пересоберите следующие утилиты
(зайдя в нижеперечисленные каталоги и выполнив в каждом из них 'make; make install; make clean'):
/usr/src/include/
/usr/src/sbin/geom/class/
/usr/src/sbin/mount/
После чего добавляем в конфиг ядра строчку:
options UFS_GJOURNAL
Компилируем ядро, ставим, перезагружаемся...
После перезагрузки подгружаем необходимый модуль командой
# gjournal load
либо:
# kldload geom_journal.ko
(команды эквивалентны)
Далее нам необходимо размонтировать раздел, на который мы собираемся поставить журнал.
Пусть это будет '/dev/ad0s3d' и точка монтирования '/mnt/work':
# umount -f /mnt/work
Теперь собстенно "прикручиваем" журнал:
# gjournal label /dev/ad0s3d
Монтируем командой:
# mount -o async,gjournal /dev/ad0s3d.journal /mnt/work
NB! префикс '.journal' появляется при наличии в памяти модуля geom_journal.ko.
Поэтому, если вы захотите чтобы система автоматически монтировала раздел с поддержкой журнала:
пропишите в файл /boot/loader.conf строчку:
geom_journal_load="YES"
и соответствующую запись в fstab. Для данного примера она будет выглядеть так:
/dev/ad0s3d.journal /mnt/work ufs rw,async,journal 2 2
Все, готово!
(C) 2006 Sokolov Alexey <nullbsd at gmail.com>
Все статьи на opennet описывают создание модуля NDIS для FreeBSD старым методом:
ndiscvt -i *.inf -s *.sys -o ndis_driver_data.h
Данный способ уже давно устарел и теперь нужно использовать программу ndisgen.
Например. Имеем файлы из комплекта Windows драйверов:
Fw1130.bin - Network interface firmware.
FwRad16.bin - Radio firmware.
TNET1130.INF - Driver information file.
tnet1130.sys - Driver binary.
Старый способ:
cd /sys/modules/ndis
make depend
make
make install
cd ../if_ndis
ndiscvt -i TNET1130.INF -s tnet1130.sys -f Fw1130.bin -o ndis_driver_data.h
make depend
make
make install
ndiscvt -f FwRad16.bin
cp FwRad16.bin.ko /boot/kernel
kldload FwRad16.bin
kldload if_ndis
Для автоматизации загрузки помещаем в /boot/loader.conf
FwRad16.bin_load="YES"
if_ndis_load="YES"
Новый способ (не требует установки исходных текстов ядра):
ndisgen
... отвечаем на интерактивные вопросы, на выходе получаем tnet1130_sys.ko
cp tnet1130_sys.ko /boot/kernel/
kldload ndis
kldload if_ndis
kldload tnet1130_sys
Для автоматизации загрузки помещаем в /boot/loader.conf
ndis_load="YES"
if_ndis_load="YES"
tnet1130_sys_load="YES"
Что бы поднять NAT и Firewall на FreeBSD надо:
Скомпилировать ядро:
Следующие строки нужно включить в /usr/src/sys/i386/conf/GENERIC файл конфигурации:
options IPFIREWALL
options IPDIVERT
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options DUMMYNET
options TCP_DROP_SYNFIN
Переходим в директорию /usr/src/
make buildkernel KERNCONF=GENERIC
make installkernel KERNCONF=GENERIC
Следующие строки можно к примеру включить в rc.conf файл конфигурации:
hostname="free"
ifconfig_rl0="10.0.0.1"
gateway_enable="YES"
firewall_enable="YES"
firewall_type="open"
natd_enable="YES"
natd_interface="rl0"
natd_flags="-redirect_port tcp 10.0.0.10:80 80"
tcp_extensions="NO"
tcp_drop_synfin="YES"
icmp_drop_redirect="YES"
sendmail_enable="NONE"
Для удаленного управления нужно добавить следующую строку:
sshd_enable="YES"
(возможно понадобится скопировать /etc/ssh/ssh_host_dsa_key.pub в /root/.ssh/authorized_keys
Следующие строки можно включить в rc.firewall файл конфигурации (секция "open"):
[Oo][Pp][Ee][Nn])
oif="rl0"
iif="tx0"
oip="132.5.7.172"
iip="10.0.0.1"
lan="10.0.0.0/24"
setup_loopback
# allow all for LAN
${fwcmd} add 500 pass all from ${lan} to ${iip} via ${iif}
${fwcmd} add 550 pass all from ${iip} to ${lan} via ${iif}
# download - 60K upload - 6K for all lan ip's
${fwcmd} add 600 pipe 1 ip from any to any in via ${oif}
${fwcmd} add 650 pipe 2 ip from any to any out via ${oif}
# for selected ip's only
# ${fwcmd} add 601 pipe 1 all from any to 10.0.0.10
# ${fwcmd} add 651 pipe 2 all from 10.0.0.10 to any
${fwcmd} pipe 1 config bw 512Kbit/s
${fwcmd} pipe 2 config bw 48Kbit/s
# dns setup
${fwcmd} add 770 pass tcp from any to ${oip} 53 setup
${fwcmd} add 780 pass udp from any domain to any
${fwcmd} add 790 pass udp from any to any domain
# main setup
${fwcmd} add 800 pass tcp from any http,https,20-21,989-990 to any
${fwcmd} add 810 pass tcp from any to any http,https,20-21,989-990
${fwcmd} add 830 pass tcp from any pop3,pop3s,smtp,imap,imaps,aol to any
${fwcmd} add 840 pass tcp from any to any pop3,pop3s,smtp,imap,imaps,aol
${fwcmd} add 65000 deny ip from any to any
;;
Где oip, oif - внешний интерфейс; iip, iif - внутренний; lan - внутренняя сеть.
Такая конфигурация ipfw весьма параноидальна, и здесь приведена только в качестве примера.
На практике обычно нужен более открытый фаервол.
Решение такое:
1. сборка и инсталляция ядра с устройствами:
device scbus
device atapicam
device cd
device pass
2. создание файлов устройств cd0, cd1 с помощью /dev/MAKEDEV
3. disklabel -rw cd1c auto
4. newfs cd1c
4.1. Можно включить softupdates: tunefs -n enable cd1
5. mount /dev/cd1c /mnt/dvdram
Все. Скорость записи ~ 1.2 Mb/s.
Решение проблем с "лаганием", "залипанием", "подергиванием" звука для FreeBSD 5.x при сильных нагрузках на ata систему:
в /boot/loader.conf добавить строку
hint.pcm.0.buffersize="16384".
Работает не со всеми звуковыми картами. Карточка с MediaForte чипом стала играть звук в 4 раза быстрее,
на SoundBlaster 5.1 live все играет замечательно.
mount -u -o snapshot ./snapshot_image /var
mdconfig -a -t vnode -f ./snapshot_image -u 1
mount -o ro /dev/md1 /mnt/snap
...
umount /mnt/snap
mdconfig -d -u 1
Также можно использовать специализированную утилиту snapshot,
представляющую собой фронтенд к mount и mdconfig.
Создание специальной учетной записи пользователя для отключения компьютера.
Задача:
Создать учетную запись пользователя, которому разрешено только отключать компьютер. ОС FreeBSD 5.2
создать в папке /bin скрипт poweroff-shell со следующим содержанием:
#!/bin/sh
shutdown -p +2 Turn off by user $LOGNAME
logger Turn off by user $LOGNAME
exit 0
установить разрешения:
chmod 750 /bin/poweroff-shell
сменить группу и владельца:
chown root /bin/poweroff-shell
chgrp operator /bin/poweroff-shell
добавить в файл /etc/shells строчку:
/bin/poweroff-shell
создать пользователя poweroff:
c шелом /bin/poweroff-shell, домашней директорией /nonexistent,
сделать пользователя poweroff членом группы operator, с паролем по вкусу.
Для одновременного воспроизведения звука от разных приложений
нужно создать несколько виртуальных звуковых каналов:
sysctl hw.snd.pcm0.vchans=4
sysctl hw.snd.maxautovchans=4
Если devfs не используется, в приложении нужно обращаться к устройствам /dev/dsp0.N
, где N - номер свободного канала.
Для установки громкости звука по умолчанию в FreeBSD 5.3 в /boot/device.hints добавляем:
hint.pcm.0.vol="100"
Для работы со встроенным кодеком не надо загружать драйверов с сайта Avance Logic, достаточно:
- в boot/loader.conf в разделе Sound modules включить загрузку
snd_ich_load="YES" # Intel ICH
после этого убедиться, что все определилось:
dmesg | grep pcm0
В single mode: "/sbin/tunefs -a enable /fs"
Пересобираем ядро с "options UFS_ACL"
getfacl - просмотр ACL
setfacl - установка ACL
Например: setfacl -m user:nobody:rw-,group:wheel:rw- acl-test
man umass
Конфигурация ядра (FreeBSD 4.8 можно не пересобирать):
device usb
device ohci (OR device uhci)
device umass
device scbus
device da
device pass
В логе смотрим подобное сообщение "da0 at umass-sim0 bus 0 target 0 lun 0"
Монтируем:
mount -t msdos /dev/da0s1 /mnt
- в конфигурации ядра включаем "options QUOTA" и пересобираем ядро.
- в /etc/rc.conf прописываем enable_quotas="YES" и check_quotas="YES"
- указываем в fstab файловые системы, для которых будет включаться
поддержка квот, например:
/dev/da0s1e /home ufs rw,userquota 2 2
/dev/ad0s1h /new_home ufs rw,groupquota 2 2
- устанавливаем квоты для пользователей при помощи edquota, напр. "edquota user1"
- если нужно установить одинаковые квоты для нескольких пользователей как у user1:
edquota -p user1 user2 user3 user4 user5
cd /usr/ports/sysutils/cd9660_unicode
make && make install
грузить модуль через
kldload /lib/cd9660_unicode/cd9660_[unicode|koi8-r|iso-8859-5|cp866].ko
Нужно использовать не команду adduser, а команду pw (man pw, pw useradd help). Например:
pw useradd -n логин -c 'комментарий, фио' -d /home/логин -m -s /bin/true
Для того чтобы на загруженный без PS/2 клавиатуры сервер, можно было в любой момент подключить клавиатуру
без перезагрузки, нужно в конфигурации ядра заменить строку:
device atkbd0 at atkbdc? irq 1 flags 0x1
на
device atkbd0 at atkbdc? irq 1
Т.е. убрать 'flags 0x1' и тем самым разрешить загружать драйвер клавиатуры
при отключенной в момент загрузки клавиатуре.
Текущий режим работы сетевой карты можно посмотреть выполнив:
# ifconfig fxp0
Перевести сетевую карту в режим работы 10baseT/UTP half-duplex:
# ifconfig fxp0 media 10baseT/UTP mediaopt half-duplex
Автоматически выбрать режим:
# ifconfig fxp0 media autoselect
Подробнее: man 4 ed, man 4 rl, man 4 fxp
/dev/acd0c /mnt/cdrom cd9660 ro,noauto,-W=koi2dos,
-L=ru_RU.KOI8-R 0 0
/dev/fd0 /mnt/flop msdos rw,noauto,-W=koi2dos,
-L=ru_RU.KOI8-R 0 0
/dev/ad0s2 /mnt/store msdos rw,-W=koi2dos,
-L=ru_RU.KOI8-R,noexec,nosuid,nosymfollow,
-u0,-g0,-m 660 0 0
Еще для удобства можно создать симлинки типа:
ln -sf /dev/acd0c /dev/cdrom
ln -sf /dev/acd1c /dev/cdrom1 (если есть второй cdrom)
ln -sf /dev/fd0 /dev/flop
прописать изменения в fstab,
и монтировать диски командой mount /dev/cdrom а не
mount /dev/acd0c =).
Такой вопрос обычно возникает вслед за желанием оптимизировать распределение памяти в ядре.
Для начала стоит понять, как в общем выглядит виртуальное адресное пространство FreeBSD. В его нижней части расположен текущий процесс,
а верхнюю всегда занимает ядро. Отрезок виртуального адресного
пространства, занятый ядром, -- kernel virtual memory (KVM) он же kernel
virtual address space (KVA) -- ограничен адресами KERNBASE снизу и
VM_MAX_KERNEL_ADDRESS сверху. Эти величины меняются только от
платформы к платформе, а vm.kvm_size возвращает их разность:
vm.kvm_size = VM_MAX_KERNEL_ADDRESS - KERNBASE
На живой машине ядро фиксирует конец используемой части KVM в
переменной ядра kernel_vm_end. Отрезок от kernel_vm_end до
VM_MAX_KERNEL_ADDRESS и есть свободная часть KVM:
vm.kvm_free = VM_MAX_KERNEL_ADDRESS - kernel_vm_end
Очевидно, что переменные vm.kvm_size и vm.kvm_free чисто
информационные, настраивать их нельзя.
В KVM есть участок, который ядро использует для динамического
распределения памяти посредством malloc(9) и zone(9). Длина этого
участка вычисляется при загрузке системы по формуле:
vm.kmem_size = min(max(max(VM_KMEM_SIZE, Physical_memory /
VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX)
Выглядит жутковато, но суть простая: vm.kmem_size_{min,max} задает
диапазон для автонастройки, которая сводится к выбору большего из
VM_KMEM_SIZE (это #define) и ОЗУ / vm.kmem_size_scale.
Также можно жестко указать vm.kmem_size из loader.conf. Наконец, при
любых настройках kmem_size не может быть более двух размеров ОЗУ.
Обратите внимание, что kmem -- это участок виртуального адресного
пространства, а не физической памяти. Именно поэтому ядро может
упасть в панику "kmem_map too small", хотя ОЗУ еще в избытке, если
какая-то из подсистем ядра пытается выделить слишком много памяти
для своих нужд. Типичный пример этого -- виртуальный диск, созданный с
помощью "mdmfs -M".
Во FreeBSD 5 был добавлен TCP Hostcache - кэш, в котором сохраняются характеристики удаленных хостов
от предыдущих соединений, для предварительной настройки новых подключений к этому же хосту.
Это позволяет увеличить скорость работы HTTP (и других протоколов с большим числом
котороткоживущих TCP соединений).
Иногда бывает полезно посмотреть его содержимое.
Увидеть его можно через sysctl net.inet.tcp.hostcache.list Просмотр информации по заданному хосту:
sysctl net.inet.tcp.hostcache.list | egrep '(IP|192.168.1.70)'
Например если MTU в кеше не равно нулю, то с помощью Path MTU
Discovery для данного хоста было определено MTU меньшее чем у данного хоста.
Просмотр состояние и параметров hostcache:
sysctl net.inet.tcp.hostcache
При тестировании производительности бывает нужно очищать этот кэш, между различными итерациями теста,
чтоб он не искажал результаты. Сделать это можно так:
sysctl net.inet.tcp.hostcache.purge=1
Потом подождать до тех пор, пока net.inet.tcp.hostcache.purge снова не будет показывать ноль.
Во FreeBSD 6.2 с 4Гб ОЗУ, процесс python'a виснет когда занимает более 512Мб.
Решение:
В /boot/loader.conf добавляем
kern.maxdsiz="2610612736"
kern.dfldsiz="2610612736"
kern.maxssiz="2610612736"
После чего процесс начинает работать в штатном режиме.
Если используется ipfw2 и keep-state правила, то от непрерывного роста
соединений со статусом FIN_WAIT_2 помогает:
sysctl -w net.inet.ip.fw.dyn_keepalive=0
Под FreeBSD наблюдаются проблемы производительности при работе
memcached с объектами размером больше чем несколько килобайт.
Переходим в порт memcached
cd /usr/ports/databases/memcached/
make configure
Редактируем файл memcached.c
vi work/memcached-1.1.12/memcached.c
Находим строку #include "memcached.h" и после нее прописываем TCPNOPUSH
(заставляет использовать TCPNODELAY):
#undef TCP_NOPUSH
Устанавливаем и запускаем:
make install
echo "memcached_enable=\"YES\"" >> /etc/rc.conf
/usr/local/etc/rc.d/memcached.sh start
security.bsd.see_other_uids, security.bsd.see_other_gids - если 1, то пользователи (группы) могут видеть чужие процессы, сокеты и т.д. через ps, netstat, procfs;
security.bsd.conservative_signals - если 1, то некоторые сигналы запрещается посылать setuid/setgid процессам;
security.bsd.unprivileged_proc_debug - если 1, то пользовательский процесс можно отлаживать через ptrace, procfs, ktrace и т.д..
security.bsd.unprivileged_read_msgbuf - если 1, то пользовательский процесс может читать из системного консольного буфера сообщений;
security.bsd.hardlink_check_uid, security.bsd.hardlink_check_gid - если 1, то пользователи могут делать hardlink только на собственные файлы;
security.bsd.unprivileged_get_quota - если 1, пользователи могут просматривать информацию по установленным для них квотам.
vfs.usermount - если 1, то непривилегированный пользователь может монтировать и размонтировать FS, если для устройства выставлены "rw" права и пользователь является владельцем точки монтирования;
security.jail.* - ограничения для jail
security.jail.set_hostname_allowed - если 1, то внутри jail можно поменять имя хоста;
security.jail.socket_unixiproute_only - если 1 , то сокет в jail можно создать только для доменов PF_LOCAL, PF_INET или PF_ROUTE, иначе, возвращается ошибка;
security.jail.sysvipc_allowed - если 1, то то в jail можно получить доступ к глобальному System V IPC;
security.jail.getfsstatroot_only - если 1, то в jail можно получить информацию (df)только о той файловой системе на которой создан jail;
security.jail.allow_raw_sockets - если 1, то в jail можно создавать raw sockets;
security.jail.chflags_allow - если 1, то процессы в jail могут модифицировать флаги ФС.
IPFW
net.link.ether.bridge_ipfw - если 1 и ядро собрано с опциями IPFIREWALL и BRIDGE, то позволяет использовать ipfw для трафика внутри бриджа;
net.link.ether.ipfw - если 1, то ipfw2 позволяет фильтровать по MAC адресам;
net.inet.ip.fw.autoinc_step - задается число на которое увеличивается счетчик при добавления нового ipfw правила, когда явно не указан его номер;
net.inet.ip.fw.debug - если 1, то в логи помещается дополнительная отладочная информация по работе ipfw;
net.inet.ip.fw.verbose - если 0, то не отображать работу "log" правил в syslog;
net.inet.ip.fw.one_pass - если 1, то просмотр правил ipfw прекращается сразу после подпадание под queue или pipe правило. Если 0, то продолжается обработка далее идущих правил;
ICMP, соединение.
net.inet.icmp.icmplim - задается максимальное число ICMP "Unreachable" и TCP RST пакетов, которое может быть отправлено в секунду, net.inet.icmp.icmplim_output=0 позволяет не отражать в логах факты превышения лимита;
net.inet.tcp.icmp_may_rst, если 1, то TCP соединения со статусом SYN_SENT, могут быть оборваны посредством сообщения "ICMP unreachable";
net.inet.ip.redirect - если 0, то нет реакции на ICMP REDIRECT пакеты;
net.inet.icmp.log_redirect - если 1, то все ICMP REDIRECT пакеты отражаются в логе;
net.inet.icmp.drop_redirect - если 1, то ICMP REDIRECT пакеты игнорируются;
net.inet.tcp.icmp_may_rst - если 1, то игнорируются ICMP сообщения от блокировки пакета по пути;
net.inet.icmp.bmcastecho - для защиты от SMURF атак (ICMP echo request на broadcast адрес) нудно поставить 0;
Тюнинг сетевой подсистемы, борьба с DoS атаками
net.inet.tcp.log_in_vain, net.inet.udp.log_in_vain - если 1, отражаем в логе попытки соединения к портам, для которых нет активных сервисов;
net.inet.tcp.blackhole - если 1, то SYN пакеты пришедшие на порты для которых нет активных сервисов, остаются без RST ответа, если 2, то на любые пакеты нет ответа (затрудняет сканирования портов);
kern.ipc.nmbclusters - если по "netstat -m" mbufs в "peak" приближается к "max", то число сетевых буферов нужно увеличить (kern.ipc.nmbclusters=N в /boot/locader.conf);
net.inet.ip.forwarding - если 1, то машина может форвадить пакеты между интерфейсами;
net.inet.tcp.sack.enable - если 1, то включен TCP Selective Acknowledgements (SACK, RFC 2018) позволяющий увеличить производительность системы в ситуации большой потери пакетов;
net.link.ether.inet.max_age - время жизни записи в IP route кэше, рекомендуется уменьшить для ослабления эффекта от DoS атак через ARP флуд;
Оборудование и системная информация
dev.cpu.0.freq_levels - выдает список поддерживаемых частот, на которые можно переключить CPU, путем указание нужной частоты через dev.cpu.0.freq;
hw.snd.maxautovchans, hw.snd.pcm0.vchans - задается число виртуальных звуковых каналов, для каждого из которых может быть отдельный источник звука (на выходе они будут смикшированы);
kern.boottime - время последней загрузки системы;
kern.disks - список дисков в системе;
kern.geom.debugflags, для работы boot0cfg и подобных утилит нужно установить в 16;
Изменение и тюнинг системных ограничений
kern.coredump - если 0, то при крахе приложения не будут создаваться core файлы, формат имени и путь для которых задается через kern.corefile (например: /tmp/%U.%N.core). kern.sugid_coredump=0 позволяет запретить генерацию core suid/sgid процессами;
kern.maxfiles - максимально допустимое число открытых файлов (файловых дескрипторов), текущее число открытых файлов можно посмотреть через kern.openfiles;
kern.maxprocperuid - максимально допустимое число процессов, которое может быть запущено из-под одного пользователя;
kern.maxvnodes - максимальное число vnode для кеширования дисковых операций, текущее значение можно посмотреть через vfs.numvnodes или debug.numvnodes/debug.freevnodes;
SMP (FreeBSD 5)
kern.smp.maxcpus (machdep.smp_cpus) - максимальное число процессоров, поддерживаемое текущей сборкой ядра;
kern.smp.active, kern.smp.disabled - число активных и выключенных CPU;
kern.smp.cpus (machdep.smp_active) - сколько CPU в online;
kern.smp.forward_signal_enabled - включить возможность мгновенной пересылки сигнала для процессов выполняемых в данный момент времени на разных CPU;
kern.smp.forward_roundrobin_enabled;
ARP
net.link.ether.inet.log_arp_movements - отражать в логе все широковещательные ARP пакеты с хостов MAC адрес которых отсутствует в локальном ARP кэше;
net.link.ether.inet.log_arp_wrong_iface - отражать в логе все ARP пакеты пришедшие с неправильного интерфейса;
man polling - периодических опрос состояния ядром, вместо генерации прерываний
(полезно при очень большом числе пакетов проходящих через сетевую карту),
возможен комбинированный вариант, когда polling включается при преодалении определенного порога нагрузки).
В конфигурации ядра
options DEVICE_POLLING
options HZ=1000
Далее:
sysctl kern.polling.enable=1
sysctl kern.polling.user_frac=50
По умолчанию запись на диски в FreeBSD производится в синхронном режиме, значительно увеличить скорость записи
можно активировав асинхронный режим: В /etc/fstab в поле Options добавить async (например rw,async).
Или для примонтированного раздела: mount -u -o async /home
Для увеличения производительности IDE дисков, в файле конфигурации ядра можно указать для wdc устройств
flags 0xa0ffa0ff или 0x80ff80ff (подробнее man wd, man ad).
Для ad: sysctl hw.atamodes; sysctl hw.ata
Например: sysctl hw.atamodes=pio,pio,---,dma,pio,---,dma,---,
См. также man atacontrol
Третий вариант - активировать в настройках ядра SOFTUPDATES и запустить
tunefs -n enable /usr в single-user на размонтированном разделе.
Нам понадобится первый установочный диск FreeBSD 6.2 и немного свободного времени.
Предполагается что наша jail-машина будет размещена в директории /var/jail.
Список действий:
1. Создать директорию /var/jail/machine для jail-машины;
2. Смонтировать установочный диск и распаковать базовые файлы в директорию jail-машины:
# mount /cdrom
для bash:
# DESTDIR=/var/jail/machine /cdrom/6.2-RELEASE/base/install.sh
для csh:
# env DESTDIR=/var/jail/machine /cdrom/6.2-RELEASE/base/install.sh
3. Создать пустой файл /var/jail/machine/etc/fstab:
# touch /var/jail/machine/etc/fstab
4. Создать файл /var/jail/machine/etc/rc.conf со следующим содержанием:
# Запускаем sshd
sshd_enable="YES"
sendmail_enable="NONE"
syslogd_flags="-ss"
rpcbind_enable="NO"
network_interfaces=""
5. Теперь требуется создать непривилегированного пользователя и изменить пароль пользователя root.
Входим в каталог jail-машины
# chroot /var/jail/machine /bin/csh
Создаем пользователя
# adduser
Меняем пароль пользователя root
# passwd
# exit
6. В файл /etc/rc.conf основной системы добавить:
# Разрешаем запуск jail-машин
jail_enable="YES"
# Запрещаем им менять свое имя jail_set_hostname_allow="NO"
# Перечисляем jail-машины в системе.
jail_list="machine"
# Jail-машина "machine"
# Корневая директория jail_machine_rootdir="/var/jail/machine"
# Имя jail_machine_hostname="machine.local"
# IP-адрес jail_machine_ip="192.168.0.10"
# На какой сетевой интерфейс будет цепляться jail-машина
jail_machine_interface="ed0"
# монтируем файловую систему devfs внутри jail-машины.
jail_machine_devfs_enable="YES"
# Скрипты запуска и останова
jail_machine_exec_start="/bin/sh /etc/rc"
jail_machine_exec_stop="/bin/sh /etc/rc.shutdown"
7. Кроме того требуется все запускаемые сервисы основной системы привязать к его ip-адресам
(не должны слушаться порты на ip-адресах jail-машин).
Например, в rc.conf:
# Супер-сервер inetd
inetd_enable="YES"
# Слушает порт только на 192.168.0.1
inetd_flags="-wW -a 192.168.0.1"
# Syslogd
syslogd_enable="YES"
# Не слушать порты
syslogd_flags="-ss"
8. Запускаем созданную jail-машину:
# /etc/rc.d/jail start
В FreBSD есть прекрасная возможность разрешать логинится конкретным пользователям
только с определённых терминалов или адресов. Делается это посредством модуля pam_acct_mgmt.
Для этого редактируем файл /etc/login.access:
-:root:ALL #запрещаем любые логины root
-:ALL:ttyv0 # первая консоль только для логов
+:dm:ttyv1 ttyv2 ttyv3 ttyv4 ttyv5 ttyv6 ttyv7 ttyv8 # доступ с консоли
+:dm:10.1.1.1 192.168.6.100 # доступ по сети(тут указывать либо ip, либо
# доменное имя. Для ssh рекомендую UseDNS no в /etc/ssh/sshd_config)
-:ALL:ALL # всё остальное запрещено
ВАЖНО! начиная с версии 5.2 su стал проверять "target user" по login.access, те при таких настройках
можно будет залогинится, но su не будет работать - pam_login_access:
pam_sm_acct_mgmt: root is not allowed to log in on /dev/ttyp3 su: Sorry.
Для исправления надо редактировать /etc/pam.d/su:
account
#account include system #закомментировать
account required pam_unix.so # добавить
* "sysctl -w net.inet.tcp.msl=7500" - время ожидания ACK в ответ на SYN-ACK или FIN-ACK в миллисекундах;
* "sysctl -w net.inet.tcp.blackhole=2" - все пакеты на закрытый порт отбрасываются без отсылки RST;
* "sysctl -w net.inet.udp.blackhole=1" - отбрасывать пакеты для закрытых портов;
* "sysctl -w net.inet.icmp.icmplim=50" - защита от генерирование потока ответных пакетов,
максимальное количество ICMP Unreachable и TCP RST пакетов в секунду;
* "sysctl -w kern.ipc.somaxconn=32768" - увеличение числа одновременно открытых сокетов;
* Сборка ядра с опцией DEVICE_POLLING (далее: sysctl kern.polling.enable=1; sysctl kern.polling.user_frac=50);
При установке ОС с диска во время определения дисков появляется ошибка
"BTX halted".
Для ее устранения нужно отключить в BIOS опцию Virtual install disk.
Для i386 и amd64 сборок FreeBSD для бинарного обновления можно использовать утилиту freebsd-update.
Обновляем FreeBSD 6.3 до 6.4-RC2
Проверяем файл конфигурации /etc/freebsd-update.conf, можно изменить сервер для загрузки обновлений
и обновляемые компоненты, например, исключить src.
Загружаем обновления, которые будут сохранены в /var/db/freebsd-update
(в /var необходимо наличие как минимум 400Мб свободного места):
freebsd-update upgrade -r 6.4-RC2
Устанавливаем обновления, попутно отвечая на вопросы,
касающиеся решения конфликтов
при обновлении файлов конфигурации:
freebsd-update install
Перезагружаем систему:
shutdown -r now
Деинсталировать установленные обновления можно при помощи команды "rollback".
Утилита freebsd-update входит в состав FreeBSD, начиная с версии 6.2.
Инструкция по обновлению FreeBSD 6.x до FreeBSD 7.0
Загружаем скрипт обновления, проверяем его целостность и разархивируем:
fetch http://people.freebsd.org/~cperciva/freebsd-update-upgrade.tgz
fetch http://people.freebsd.org/~cperciva/freebsd-update-upgrade.tgz.asc
gpg --verify freebsd-update-upgrade.tgz.asc freebsd-update-upgrade.tgz
tar -xf freebsd-update-upgrade.tgz
Загружаем файлы обновлений и производим первичную подготовку:
sh freebsd-update.sh -f freebsd-update.conf -r 7.0-RELEASE upgrade
Устанавливаем обновления (устанавливаем новое ядро):
sh freebsd-update.sh -f freebsd-update.conf install
Перезагружаем систему:
shutdown -r now
Второй раз запускаем установку обновлений (при первом запуске было обновлено только ядро,
при повторном запуске выполняется обновление базового окружения):
sh freebsd-update.sh -f freebsd-update.conf install
Пересобираем установленные дополнительные приложения (порты),
так как они могут ссылаться на старые библиотеки.
portupgrade -faP
Третий раз запускаем процесс обновления, теперь для удаления старых библиотек:
sh freebsd-update.sh -f freebsd-update.conf install
Выполняем перезагрузку:
shutdown -r now
Иногда возникает необходимость создать установочный Flash-диск с FreeBSD,
но без переформатирования FAT-раздела на Flash, при сохранении размещенных там данных.
Загружаем с ftp.freebsd.org минимальный установочный образ 6.3-RELEASE-i386-bootonly.iso
ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/6.3/6.3-RELEASE-i386-bootonly.iso
Создаем на его основе ram-диск. Операции выполняются на FreeBSD системе,
при необходимости временно FreeBSD можно поставить в KVM, VmWare или VirtualBox.
Создаем образ RAM-диска размером чуть больше bootonly.iso:
dd if=/dev/zero of=boot.img bs=1k count=26000
Подключаем ram-диск:
mdconfig -a -t vnode -f boot.img -u 0
Устанавливаем загрузочный сектор и размечаем по умолчанию:
bsdlabel -w -B md0 auto
Создаем файловую систему:
newfs -m 0 md0a
Монтируем созданную ФС ram-диска:
mkdir /mnt/img
mount /dev/md0a /mnt/img
Монтируем iso-образ и переносим с него данные на ram-диск:
mkdir /mnt/iso
mdconfig -a -t vnode -f 6.3-RELEASE-i386-bootonly.iso -u 1
mount_cd9660 /dev/md1 /mnt/iso
cd /mnt/img/
cp -r /mnt/iso/* .
Размонтируем:
cd
umount /mnt/img /mnt/iso
mdconfig -d -u 0
mdconfig -d -u 1
Загружаем Linux, можно LiveCD.
Копируем boot.img на Flash диск.
Копируем на Flash файл memdisk из комплекта syslinux (http://syslinux.zytor.com).
Ставим syslinux на Flash (/dev/sdb1):
syslinux -s /dev/sdb1
Создаем в корне файл syslinux.cfg:
label freebsd
kernel /memdisk
append initrd=/boot.img harddisk
Если не грузится, ругаясь на MBR, заменяем MBR на содержимое файла mbr.bin из комплекта syslinux:
dd if=/dev/sdb of=mbr_backup.bin bs=1 count=512
cat mbr.bin > /dev/sdb
Проверить можно через QEMU:
qemu -hda /dev/sdb1 -std-vga
При установке выбираем метод получения установочных файлов по FTP или копируем их на Flash
(директорию 6.3-RELEASE из 6.3-RELEASE-i386-disc1.iso).
--------------------
В случае когда USB Flash не жалко отформатировать, можно можно создать
загрузочный
USB Flash следующим образом:
fdisk -BI /dev/da2
bsdlabel -w -B /dev/da2s1
newfs /dev/da2s1a
mount /dev/da2s1a /mnt
Копируем в /mnt содержимое содержимое 6.3-RELEASE-i386-bootonly.iso
--------------------
Установка загрузчика FreeBSD на Flash из Linux:
Делаем бэкап текущего MBR USB диска:
dd if=/dev/sdb of=mbr_sdb.bin bs=1 count=512
Берем boot0 из комплекта FreeBSD и копируем в него данные о таблицах разделов текущего диска:
dd if=mbr_sdb.bin of=boot0 bs=1 count=66 skip=446 seek=446
Копируем загрузчик в MBR USB диска:
dd if=boot0 of=/dev/sdb bs=1 count=512
Инструкцию по созданию установочного образа FreeBSD, загружаемого по сети
можно найти здесь http://wiki.opennet.ru/NetworkBoot
---------------------
Полезный скрипт для преобразования ISO в UFS-образ (http://docs.FreeBSD.org/cgi/mid.cgi?4420AF56.60106)
Запускается ./fbsd-install-iso2img.sh iso-path img-path
#!/bin/sh
# You can set some variables here. Edit them to fit your needs.
# Set serial variable to 0 if you don't want serial console at all,
# 1 if you want comconsole and 2 if you want comconsole and vidconsole
serial=3D0
set -u
if [ $# -lt 2 ]; then
echo "Usage: $0 source-iso-path output-img-path"
exit 1
fi
isoimage=3D$1; shift
imgoutfile=3D$1; shift
export tmpdir=3D$(mktemp -d -t fbsdmount)
# Temp file and directory to be used later
export tmpfile=3D$(mktemp -t bsdmount)
export isodev=3D$(mdconfig -a -t vnode -f ${isoimage})
echo "#### Building bootable UFS image ####"
ISOSIZE=3D$(du -k ${isoimage} | awk '{print $1}')
SECTS=3D$((($ISOSIZE + ($ISOSIZE/5))*2))
# Root partition size
echo "Initializing image..."
dd if=3D/dev/zero of=3D${imgoutfile} count=3D${SECTS}
ls -l ${imgoutfile}
export imgdev=3D$(mdconfig -a -t vnode -f ${imgoutfile})
bsdlabel -w -B ${imgdev}
newfs -O1 /dev/${imgdev}a
mkdir -p ${tmpdir}/iso ${tmpdir}/img
mount -t cd9660 /dev/${isodev} ${tmpdir}/iso
mount /dev/${imgdev}a ${tmpdir}/img
echo "Copying files to the image..."
( cd ${tmpdir}/iso && find . -print -depth | cpio -dump ${tmpdir}/img )
#bzcat ${tmpdir}/iso/dist/root.dist.bz2 | mtree -PUr -p ${tmpdir}/img 2>&=
1 > /dev/null
#echo "/dev/ufs/${UFS_LABEL} / ufs ro 1 1" > ${tmpdir}/img/etc/fstab
if [ ${serial} -eq 2 ]; then
echo "-D" > ${tmpdir}/img/boot.config
echo 'console=3D"comconsole, vidconsole"' >> ${tmpdir}/img/boot/l=
oader.conf
elif [ ${serial} -eq 1 ]; then
echo "-h" > ${tmpdir}/img/boot.config
echo 'console=3D"comconsole"' >> ${tmpdir}/img/boot/loader.conf
fi
cleanup() {
umount ${tmpdir}/iso
mdconfig -d -u ${isodev}
umount ${tmpdir}/img
mdconfig -d -u ${imgdev}
rm -rf ${tmpdir} ${tmpfile}
}
cleanup
ls -lh ${imgoutfile}
Имеем загруженные iso образы:
7.0-RELEASE-i386-disc1.iso
7.0-RELEASE-i386-disc2.iso
7.0-RELEASE-i386-disc3.iso
7.0-RELEASE-i386-docs.iso
Создаем в домашнем каталоге директорию dvd-freebsd7 и копируем туда содержимое iso образов.
cd ~
mkdir dvd-freebsd7
cd dvd-freebsd7/
mdconfig -a -t vnode -f ../7.0-RELEASE-i386-disc1.iso -u 0
mount -t cd9660 /dev/md0 /mnt
tar -C /mnt -cf - . | tar -xf -
umount /mnt
mdconfig -a -t vnode -f ../7.0-RELEASE-i386-disc2.iso -u 1
mount -t cd9660 /dev/md1 /mnt
tar -C /mnt -cf - . | tar -xf -
umount /mnt
mdconfig -a -t vnode -f ../7.0-RELEASE-i386-disc3.iso -u 2
mount -t cd9660 /dev/md2 /mnt
tar -C /mnt -cf - . | tar -xf -
umount /mnt
mdconfig -a -t vnode -f ../7.0-RELEASE-i386-docs.iso -u 3
mount -t cd9660 /dev/md3 /mnt
tar -C /mnt -cf - . | tar -xf -
umount /mnt
Используя sed или обычный текстовый редактор удаляем упоминание привязки к номеру диска ("||1", "||2" и "||3") в файле packages/INDEX
В файл cdrom.inf добавляем:
CD_VOLUME = 0
CD_VOLUME = 1
CD_VOLUME = 2
CD_VOLUME = 3
Удаляем директорию rr_moved
(иначе при создании iso образа в формате Rock Ridge будет выдана ошибка):
rm -Rf rr_moved
Для записи DVD на лету:
growisofs -Z /dev/cd0 -J -R -no-emul-boot -b boot/cdboot -iso-level 3 .
Для создания ISO образа DVD диска:
mkisofs -V FreeBSD7 -J -R -b boot/cdboot -no-emul-boot -o freebsd7.iso .
Для записи созданного iso:
growisofs -dvd-compat -Z /dev/cd0=freebsd7.iso
Практически любой системный администратор, который сталкивался с FreeBSD,
компилировал ядро под себя, выбрасывая оттуда лишние "детали" или вставляя недостающие.
Между тем выброшенная из ядра "деталька" никуда не девается и при повторной компиляции
превращается в модуль (за редким исключением), который всегда можно подгрузить.
Бороться с этим можно с помощью опций в файле make.conf:
# не компилировать все модули
NO_MODULES="YES"
# компилировать только указанные модули
# названия модулей пишутся через пробел
MODULES_OVERRIDE=acpi ipfw
# компилировать все модули, за исключением указанных
WITHOUT_MODULES=pf ntfs_iconv
Прежде чем что-либо делать с портами в FreeBSD их необходимо обновить:
# cat >> /etc/make.conf
SUP_UPDATE=yes
SUP=/usr/local/bin/cvsup
SUPFLAGS=-g -L 2
SUPHOST=cvsup.uk.FreeBSD.org
SUPFILE=/usr/share/examples/cvsup/standard-supfile
PORTSSUPFILE=/usr/share/examples/cvsup/ports-supfile
DOCSUPFILE=/usr/share/examples/cvsup/doc-supfile
Ctrl + D
# cd /usr/ports
# make update
Найти в портах (/usr/ports) порт portupgrade (/usr/ports/ports-mgmt/portupgrade), установить его
cd /usr/ports/ports-mgmt/portupgrade
make && make install
После этого можно с помощью утилиты portupgrade уже возможно обновлять
установленные порты (ключ -R говорит о том, что нужно обновить не только порт, но и все его зависимости)
portupgrade -R имя_порта
Чтобы узнать список портов, нуждающихся в обновлении, существует команда
pkg_version -v
Для наведения порядка (удаление неиспользуемых портов, дубликатов версий)
в реестре установленных портов (/var/db/pkg) можно воспользоваться командой
pkgdb -F
Ссылки:
1. "Системный администратор" (2007.01)
2. Очистка портов во FreeBSD
http://www.opennet.ru/base/sys/cleaning_up_ports.txt.html
3. portupgrade - `обновлялка` установленных портов
http://www.lissyara.su/?id=1153
Удаленное бинарное обновление 4.11 до 6.2-RELEASE,
без доступа с консоли с двумя перезагрузками и
минимальным downtime, безопасное настолько, насколько
это возможно при обновлении "по месту".
Требуется доступность первого инсталляционного CD
из дистрибутива 6.2-RELEASE, либо нужно будет
скачать с десяток мегабайт из него для пункта 3 ниже.
1. Подготовить новое содержимое для /boot
Скопировать с дистрибутивного CD 6.2-RELEASE
каталог boot в /boot6, loader.conf оставить старый
(если дистрибутив машине недоступен, сначала скачать
/boot с него по сети в каталог /cdrom/boot):
cd /
CDROM=/cdrom
cp -r $CDROM/boot boot6
cd boot6
mv loader.conf loader.conf6
cp ../boot/loader.conf . || true
mv kernel kernel6
mkdir kernel
ln ../kernel kernel
2. Меняем местами старый и новый loader:
cd ..
mv boot boot4
mv boot6 boot
Теперь у нас новый loader, который грузит старое ядро
из файла /boot/kernel/kernel (это хардлинк на /kernel),
и старые модули из /modules. Система пока работает по-старому,
при перезагрузке ничего не поломается.
3. Подготовка mfsroot.
Если дистрибутива на четверке нет, этот пункт можно полностью
выполнять на другой машине, и готовый mfsroot.gz (5.5Mb)
потом скачать в /boot/mfsroot.gz. Если выполняется на свежей
FreeBSD, заменить vnconfig на mdconfig и disklabel
на bsdlabel (убрать слово auto):
TMPDIR=/var/tmp # можно и другое место
cd $TMPDIR
# быстрый и простой способ требует mfsroot на 14Mb
# создаём файл образа на основе такого же
# из дистрибутива
dd if=/dev/zero of=mfsroot bs=1m count=14
dev=vn0c
vnconfig -c -s labels $dev mfsroot
disklabel -w -B -b $CDROM/boot/boot $dev auto
newfs -m 0 -o space -b 4096 -f 512 $dev
# Монтируем оригинальный и новый mfsroot
mkdir /mnt/omfs /mnt/mfs
gzcat $CDROM/boot/mfsroot.gz > mfsroot.orig
odev=vn1c
vnconfig -c -s labels $odev mfsroot.orig
mount -o ro /dev/$odev /mnt/omfs
mount /dev/$dev /mnt/mfs
# Для начала копируем оригинальный в новый
cd /mnt/omfs
tar -cf - * | tar -C /mnt/mfs -xf -
# Оригинальный mfsroot больше не нужен
cd /mnt/mfs
umount /mnt/omfs
vnconfig -d $odev
rm $TMPDIR/mfsroot.orig
# Затачиваем новый mfsroot под неинтерактивную загрузку
rm -r etc bin sbin var stand/etc stand/help
ln -s stand bin
ln -s stand sbin
mkdir -p tmp
# В тестовой системе /usr и /var - отдельные от рута fs,
# при промежуточной загрузке будут смонтированы так:
# /mnt - рут
# /mnt/usr - /usr
# /mnt/var - /var
# Таким образом, chroot /mnt при желании
# после загрузки даст нам оригинальный расклад
# и позволит воспользоваться новым sysinstall-ом
ln -s mnt/usr usr
ln -s mnt/var var
# Hовые бинарники используются новым ядром
# при загрузке с md0
cd $CDROM
# игнорировать ошибки касательно "File exists"
tar cf - bin etc lib libexec sbin | tar -C /mnt/mfs -xkf -
# Минимально необходимый набор файлов со старой системы для успешного
удаленного
# входа в систему; nsswitch.conf берем с новой системы
cd /etc
cp -rp fstab host.conf rc.conf ssh passwd group master.passwd pwd.db spwd.db
/mnt/mfs/etc
cat <<EON > /mnt/mfs/etc/nsswitch.conf
group: files
hosts: files dns
networks: files
passwd: files
shells: files
EON
Теперь нужно привести /mnt/mfs/etc/fstab к примерно следующему виду:
# Device Mountpoint FStype Options Dump Pass#
/dev/md0 / ufs rw 1 1
/dev/ad0s1b none swap sw 0 0
/dev/ad0s1a /mnt ufs rw 2 2
/dev/ad0s1f /mnt/usr ufs rw 2 2
/dev/ad0s1e /mnt/var ufs rw 2 2
Первая строка обязательно такая, остальные - из оригинального fstab,
точку монтирования для рута заменяем на /mnt,
/usr и /var тоже смещаем внутрь /mnt, остальные файловые системы
(если есть) намеренно не упоминаем.
В /mnt/mfs/etc/fstab желательно отключить все сервисы, кроме
sshd и каналообразующих (учитывать, что грузиться будет GENERIC),
что-то типа этого:
ifconfig_rl0="inet x.x.x.x netmask 255.255.255.0"
hostname="host.domain.ru"
sendmail_enable="NONE"
firewall_enable="NO"
inetd_enable="NO"
sshd_enable="YES"
fsck_y_enable="YES"
background_fsck="NO"
# EOF
Закрываем и запаковываем mfsroot:
cd $TMPDIR
umount /mnt/mfs
vnconfig -d $dev
gzip -1 < mfsroot > /boot/mfsroot.gz
4. Подгрузка полученного mfsroot:
cd /boot
cat loader.conf6 >> loader.conf
Это добавляет в loader.conf следующие команды:
mfsroot_load="YES"
mfsroot_type="mfs_root"
mfsroot_name="/boot/mfsroot"
Hа работу четвертой версии не влияет никак, пока по-прежнему
используется старая корневая файловая система, только увеличивается
размер оперативной памяти, зарезервированной ядром. Hа машине с 48M памяти
изменение составило те самые 14M, avail memory вместо 44316K стала 30140K.
5. Решающий момент. Для загрузки нового ядра с новым рутом посредством
nextboot:
cat <<EOF > nextboot.conf
nextboot_enable="YES"
kernel="kernel6"
vfs.root.mountfrom="ufs:md0"
EOF
Если новое ядро, скажем, зависнет на этапе определения оборудования
до перехода в multiuser, достаточно дернуть питание и машина
загрузит старое ядро и четвертую версию и у вас есть возможность
спокойно разобраться, система тем временем работает. При следующей
попытке этот пункт нужно повторить, nextboot.conf будет удалён
при перезагрузке.
При использовании cut-n-paste команд из этого пункта проверьте,
что в конце строк nextboot.conf нет лишних пробелов - загрузчик
этого не любит и может проигнорировать конфигурацию nextboot.
Перезагружаемся!
6. При успешной загрузке запускается старый /usr/sbin/sshd,
через него заходим в систему. Авторизация через keyboard-interactive
не срабатывает, зато срабатывает через password, то есть в систему
пустит после четвертой попытки набора пароля. Эту косметическую
проблему править не стал, всё равно на это один только раз
наталкиваемся.
Переименовываем /mnt/stand в /mnt/stand4,
создаём новый /mnt/stand, копируем /stand/sysinstall в
/mnt/stand/sysinstall, делаем chroot /mnt.
7. Это - точка, после которой нет возврата, кроме восстановления
из бекапа с консоли. Сейчас пока можно ещё перегрузиться обратно
в четверку и работать по-старому. Дальше уже нет.
# если не сделать этой правки loader.conf, система не поднимется
echo 'kernel="GENERIC"' >> /boot/loader.conf
/stand/sysinstall
Выбираем Upgrade. Я делал бинарное обновление по FTP,
из дистрибьюшнов ставил только base и kernels (меню Custom).
Во время обновления в терминал выдавалось куча мусора от распаковщика,
но это косметическое неудобство. Апгрейд прошел совершенно
гладко, система перезагрузилась уже в шестерку с винта
и доступна (теперь уже через свежий) sshd.
Убираем строки mfsroot_* из /boot/loader.conf
Hе забываем разгрести /etc/upgrade или сделать
обновление из исходников, mergemaster позаботится о /etc.
В любом случае перезагружаемся опять, теперь уже
это будет не из mfsroot.
#!/usr/bin/perl
#
# Interactive script for deinstalling 'leaf' FreeBSD packages.
#
# Copyright (c) 2007 Artem A. Kolpakov <artem.kolpakov at gmail.com>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
$dbdir="/var/db/pkg";
die "Usage: pkg_deinstall.pl \'package_name\' or \'$dbdir/package_name\'.\n" if(!defined($ARGV[0]));
$pkg=$ARGV[0];
if(map /$dbdir/, $pkg) {
$pkg=~/$dbdir\/(\S+[^\/])/; $pkg=$1;
}
die "$pkg is not installed!\n" if((!map /\S+\d/, $pkg)||(!-e "$dbdir/$pkg"));
if(-w $dbdir) { $rw=1; } else { $rw=0; }
if(-s "$dbdir/$pkg/+REQUIRED_BY") {
open(REQ, "$dbdir/$pkg/+REQUIRED_BY");
while(<REQ>) { print "Found required dependence: $_"; $req_sum++; }
close(REQ);
}
die "Required dependencies: $req_sum. Remove is impossible.\n" if($req_sum);
open(DEP, "$dbdir/$pkg/+CONTENTS");
while(<DEP>) {
if(/\@pkgdep\s(\S+)\n/) {
$pkg_depends{$1}=1; print "Dependence: $1\n";
}
}
close(DEP);
die "You have not privilegies to complete operation.\n" if(!$rw);
$dep_sum=(keys %pkg_depends);
if($dep_sum) {
print "Total dependencies: $dep_sum. Removing package.\n";
}
else {
system "pkg_delete $pkg";
die "The package has been removed.\n";
}
system "pkg_delete $pkg";
print "Done, processing...\n";
while(scalar(keys %pkg_depends)) {
$level++;
if($level > 1) {
for $pkg_depends (keys %pkg_depends) {
if($pkg_depends{$pkg_depends} == $level-1) {
if(-e "$dbdir/$pkg_depends/+CONTENTS") {
open(DEP, "$dbdir/$pkg_depends/+CONTENTS");
while(<DEP>) {
if(/\@pkgdep\s(\S+)\n/) {
$pkg_depends{$1}=$level;
}
}
close(DEP);
open(COMMENT, "$dbdir/$pkg_depends/+COMMENT");
chomp($comment=<COMMENT>); close(COMMENT);
dialog:
print "Are you sure want to remove \'$pkg_depends\'? \- \'$comment\' [Y/n]: ";
chomp($in=<STDIN>);
if(($in eq "y")||($in eq "Y")||($in eq '')) {
system "pkg_delete $pkg_depends";
delete $pkg_depends{$pkg_depends}; $rm_dep_sum++;
}
elsif(($in eq "n")||($in eq "N")) {
delete $pkg_depends{$pkg_depends};
}
else { goto dialog; }
}
else {
delete $pkg_depends{$pkg_depends};
}
}
}
}
for $pkg_depends (keys %pkg_depends) {
if($pkg_depends{$pkg_depends} == $level) {
if(-s "$dbdir/$pkg_depends/+REQUIRED_BY") {
delete $pkg_depends{$pkg_depends};
}
}
}
}
if($rm_dep_sum) {
print "Removed $rm_dep_sum dependencies.\n";
}
else { print "No dependencies removed.\n"; }
Для запуска/остановки сервиса с помощью стартового скрипта вручную
без внесения записи в /etc/rc.conf найдено такое решение (FreeBSD 6.*, csh):
env samba_enable=YES /usr/local/etc/rc.d/samba start
env samba_enable=YES /usr/local/etc/rc.d/samba stop
По сути, выполняет действия, аналогичные pkg_create с ключём -R, который появился только в FreeBSD 6.x.
Однако данный скрипт позволяет указывать короткое имя порта и каталог,
в котором создавать пакеты. А главное, он работает и на тех системах,
где pkg_create не поддерживает ключ -R.
#!/bin/sh
#
# pkg_depend
# Create all packages (with dependence) needed by some port for FreeBSD 5.x+
#
# Version: 1.4
# Copyright (c) 2005,2006 Alexey Tsvetnov, vorakl@fbsd.kiev.ua
#
# Path to packages directory
pkgpath="/usr/ports/packages/All"
# Command for get package's version
pkgvercmd="pkg_version -v"
#pkgvercmd="portversion -v" # more faster than pkg_version
getdepend()
{
[ ! -d $2 ] && echo -n "Creating directory ($2)..." && mkdir -p $2 && echo "Done."
cd ${pkgpath}
if [ ! -f ${pkgpath}/$1.tbz ]; then
echo -n "Creating package ($1)..."
pkg_create -yb $1
echo "Done."
fi
echo -n "Copying package ($1)..."
cp -f ${pkgpath}/$1.tbz $2
echo "Done."
for LINE in `pkg_info -r $1 | grep Dependency\: | awk '{print $2}'`
do
if [ ! -f ${pkgpath}/${LINE}.tbz ]; then
echo -n "Creating package (${LINE})..."
pkg_create -yb ${LINE}
echo "Done."
fi
echo -n "Copying package (${LINE})..."
cp -f ${pkgpath}/${LINE}.tbz $2
echo "Done."
done
}
gethelp()
{
echo ""
echo "Usage: `basename $0` <Full/Short pkg_name> <Directory>"
echo ""
echo "If specify short package name script will get first find entry"
echo ""
echo "Example: `basename $0` dia-gnome-0.94_4,1 /tmp/pkg/"
echo " `basename $0` dia-gnome /tmp/pkg/"
echo ""
exit 1
}
main()
{
if [ "$2" = "" ]; then gethelp
else
echo -n "Checking package name ($1)..."
if [ "`echo $1 | grep '\-[0-9]'`" = "" ]; then
pkgname=`${pkgvercmd} | grep -E '^'$1'-[0-9].*' | awk '{print $1}' | head -1`
else
pkgname=`${pkgvercmd} | grep $1 | awk '{print $1}' | head -1`
fi
echo "Done."
if [ "${pkgname}" = "" ]; then
echo "Package '$1' not found! Exit."
exit 2
else
getdepend ${pkgname} $2
fi
fi
}
main $1 $2
exit 0
Вот тут надоело шаманство со сменой СD при инсталляции очередной FreeBSD 5.4 и было решено создать инсталляционный DVD - быстро и все в одном. Сразу оговорюсь - все манипуляции с ISO-образами проводились с помощью UltaISO 7.2.3.906.
Все началось с того что я сравнил файлы INDEX в папках /packages на обоих CD и нашел их полную идентичность. Позже, изучив их содержимое, определил что за номер диска на котором находится установочный пакет отвечает последняя цифра в строке, которую честно поменял на 1.
После чего все файлы с CD 2 (кроме cdrom.inf) были полностью перенесены в ISO образ CD 1 и в /packages записан патченный (см. выше) файл INDEX.
Записываем ISO и получаем то что нам нужно - инсталяционный DVD.
Я пошел дальше. С папки /5.4-STABLE-SNAP006/ports (я на этом снепшопе делал) достал архив (tar/gz) ports.tgz, распаковал его и в директорию /ports/distfiles закинул последние скачанные порты (кидал самое необходимое при установке без доступа в Инет - например, Midnight Commander), опять сжал архив и положил его на место в ISO-образе. Теперь порты распаковываются при установке вместе с моими distfiles...
По ссылке приведён удачный метод переноса FreeBSD на новый жёсткий диск произвольного размера.
Вкратце это делается так:
1. Подключаем новый жёсткий диск в систему с FreeBSD (/dev/ad1s1)
2. С помощью /stand/sysinstall разбиваем новый диск на разделы так же как это сделано на старом.
То есть чтобы /dev/ad0s1a соответствовал /dev/ad1s1a - размер /dev/ad1s1a может быть большем чем на /dev/ad0s1a.
3. Создаём временные папку и подпапки:
mkdir /backup
mkdir /backup/root
mkdir /backup/usr
mkdir /backup/var
mkdir /backup/tmp
4. Загружаемся в single user
5. Монтируем разделы:
mount /dev/ad1s1a /backup/root
mount /dev/ad1s1e /backup/var
mount /dev/ad1s1f /backup/usr
(тут указываем свои)
6. Переносим систему:
( dump -0f - / ) | ( cd /backup/root ; restore -rf - )
( dump -0f - /var ) | ( cd /backup/var ; restore -rf - )
( dump -0f - /usr ) | ( cd /backup/usr ; restore -rf - )
7. Размонтируем
umount /backup/root
umount /backup/var
umount /backup/usr
8. Включаем Soft Updates
tunefs -n enable /dev/ad1s1a
tunefs -n enable /dev/ad1s1e
tunefs -n enable /dev/ad1s1f
Всё теперь можно с чистой совестью убрать из системы старый жёсткий диск, а на его место поставить новый.
Во FreeBSD 5.3 используется GCC-3.4.2, некоторые программы в портах в связи с этим перестали нормально собираться.
В некоторых портах появились соответсвующие записи:
BROKEN="Does not compile with gcc 3.4.2"
Для решения проблемы можно попробовать откомпилировать другой версией gcc,
например, lang/gcc295. Исправить Makefile, закомментировав BROCKEN и устанавливать:
csh: # setenv CC /usr/local/bin/gcc295 && make install clean
bash: # export CC=/usr/local/bin/gcc295 && make install clean
Итак, при построении jdk 1.4.2 из портов необходимо иметь разрешение
эмуляции Linux в ядре и монтированную файловую систему linprocfs.
Для этого в файле /etc/rc.conf необходимо указать
# linux_enable="YES"
а в файле /etc/fstab
# linprocfs /compat/linux/proc linprocfs rw 0 0
По завершении установки необходимо установить переменную окружения
JAVA_HOME, которая указывает на каталог с установленным jdk
Соответственно, в файле .cshrc необходимо добавить
# setenv JAVA_HOME /usr/local/jdk1.4.2
а в файле .profile
# export JAVA_HOME=/usr/local/jdk1.4.2
Установка Tomcat 5.0 из портов проблем не вызвала, но запуск программы
постоянно срывался. Изучение логов показало, что Tomcat пытался
работать с протоколом IPv6, который не был установлен в моей системе.
В соответствии с рекомендацией, данной в логах, делаем запрет на IPv6
# sysctl net.inet6.ip6.v6only=0
теперь все работает.
Как вариант, можно внести соответствующие изменения в catalina.sh
и сделать запуск java с ключем -Djava.net.preferIPv4Stack=true,
но через sysctl мне показалось проще.
Например для устранения ошибки:
/usr/libexec/ld-elf.so.1: /usr/lib/libm.so.2: Undefined symbol: "__stderrp"
В /etc/make.conf добавьте
COMPAT3X=YES
COMPAT4X=YES
cd /usr/src/lib/compat
make && make install
По ссылке можно найти скрипт, который просматривает список установленных портов
и их зависимостей, очищает distfiles от старых версий, оставшихся после обновления портов и запуска portupgrade.
Комментарий к заметке: В portupgrade есть специальная утилита для чистки мусора - portsclean.
Правим /etc/make.conf пользуясь /etc/defaults/make.conf
CPUTYPE=i686
CFLAGS=-O2 -pipe
COPTFLAGS=-O -pipe
На SMP системах собираем через make -j2 buildworld
man sysctl.conf; man sysctl
man loader.conf; man loader
На основе параметров в /boot/defaults/loader.conf, формируем /boot/loader.conf,
где можем указать какие модули подгружать и какие значения системных констант использовать.
Например, безе пересборки можно использовать GENERIC с /boot/loader.conf:
kern.maxusers="512"
kern.ipc.nmbclusters="16384"
null_load="YES" # Грузим модуль для Null filesystem
vinum_load="YES"
accf_http_load="YES" # HTTP request accept filter
/etc/sysctl.conf
kern.maxfiles=32000
kern.ipc.somaxconn=1024
net.inet.ip.portrange.last=30000
net.inet.tcp.sendspace=32768
net.inet.tcp.recvspace=32768
Например для 4.6.1: tag=RELENG_4_6_1_RELEASE
для всех RELEASE, к RELENG_X_Y добавляется _RELEASE - это чистый RELEASE
для каждого РЕЛИЗА, после установки или upgrade via CVS/CTM, впоследствии можно использовать
tag=RELENG_X_Y - который будет вытягивать только security patches для
заданного в теге RELEASE
для STABLE всегда tag=RELENG_4 , stable всегда изменяется
для CURRENT tag=.
Bash: $HOME/.inputrc
set convert-meta off
set input-meta on
set output-meta on
$HOME/.bash_profile
export CHARSET=KOI8-R
export MM_CHARSET=KOI8-R
export LANG=ru_RU.KOI8-R
Tcsh[Csh] $HOME/.login
setenv CHARSET KOI8-R
setenv MM_CHARSET KOI8-R
setenv LANG ru_RU.KOI8-R
Апргейд коллекции портов:
Редактируем /usr/share/examples/cvsup/ports-supfile и запускаем:
cvsup -g -L 2 ports-supfile
Поиск:
make search key="строка" - поиск пакета по ключевому слову.
make search name="строка" - поиск пакета по названию пакета.
Установка портов:
cd /usr/ports/порт; make; make install
Другие команды:
make deinstall - деинсталлировать приложение.
make fetch - скачать приложение из сети.
make checksum - проверить контрольные суммы.
make depends - перестроить зависимости.
make extract - разархивировать исходные тексты в work директорию.
make patch - применить патчи к приложению.
make build - собрать приложение из исходных тестов.
make clean - "почистить" исходники после сборки.
make reinstall - переустановить приложение после удаления.
make package - построить из порта package.
Для автоматической установки достаточно создать профайл инсталляции
install.cfg, скопировать его на дискету, а в sysinstall при установке
выбрать пункт меню "Load Config".
Пример install.cfg можно найти в /usr/src/release/sysinstall/install.cfg
1. cd /usr/src/; cvsup -g -L2 /etc/cvsupfile # cvsupfile составляем опираясь на /usr/share/examples/cvsup/stable-supfile
2. make buildworld
3. make buildkernel KERNCONF=имя_конфига_ядра
4. make installkernel KERNCONF=имя_конфига_ядра
5. make installworld
6. mergemaster
Для пересборки ядра после make installworld: config MYKERNEL; make depend; make; make install
Я столкнулся с тем, что при установке FreeBSD 4.7 перестал работать отладчик kdbg.
Проблема решилась заменой отладчика dbg из дистрибутива на GNU dbg 5.2 (есть в пакаджах)
Пакет inotify-tools содержит две полезные утилиты:
inotifywait - ожидать наступления определенного события в файле или дирекотории.
inotifywatch - слежение за статистикой изменений и вывод суммарных данных.
Утилиту inotifywait удобно использовать в скриптах, например, когда нужно дождаться
завершения внешней операции с файлом и мгновенно среагировать на изменения.
Напрмер, запустим:
inotifywait /tmp
При попытке создать файл в /tmp утилита завершит работу, выдав:
/tmp/ CREATE,ISDIR v31549
При попытке создать директорию:
/tmp/ CREATE,ISDIR 0
Если необходимо следить за изменением во всех директориях в пределах /tmp,
следует использовать флаг рекурсивного контроля "-r".
Для больших директорий может понадобиться расширить лимит /proc/sys/fs/inotify/max_user_watches.
Используя опцию "--fromfile" можно загрузить список контролируемых файлов и директорий из файла.
Опция "-e" позволяет реагировать только на определенный тип события, например, на удаление файла, игнорируя создание и открытие.
Опция '-m' отменяет мгновенный выход после наступления события, что позволяет организовать
визуальное наблюдение или обработку в цикле.
Пример, скрипта для обработки изменения файла:
#!/bin/sh
inotifywait -e delete -m /tmp/lock/ | while read dir events file; do
echo "Removed $dir$file"
done
При выполнении:
inotifywatch /tmp
и последующем завершении выполнения через задание таймаута или нажатия ctrl+c,
будет выведена суммарная информация по каждому из классов событий, напрмер:
total modify close_write close_nowrite open create delete filename
22 3 4 1 5 4 5 /tmp/
Или
inotifywatch -v -e access -e modify -t 60 -r /var/log
через 60 секунд выдаст:
14 14 /var/log/
2 2 /var/log/apache2
4 4 /var/log/postgresql
Что касается кроссплатформенного решения, которое работает, не только в Linux, но и во FreeBSD,
можно привести пример слежения за изменением файла используя Perl модуль EV (http://search.cpan.org/dist/EV/),
использующий универсальную библиотеку-враппер libev:
#!/usr/bin/perl
use strict;
use EV;
# Следим за изменениями в директории /tmp/watch
# 0 - интервал опроса по умолчанию
my $w = EV::stat "/tmp/watch", 0,
sub {
my ($w, $revents) = @_;
warn $w->path, " has changed somehow.".$w->attr."\n";
$w->stop;
# На время обработки события, прекращаем прием нотификаций.
.....
$w->start;
};
EV::loop;
Администрирование Debian: How To по миграции на файловую систему LVM с поддержкой шифрования
Целью данного документа является описание пути перехода на полностью шифрованную файловую
систему LVM (корневая файловая система и пользовательские данные, кроме загрузочного раздела).
Миграция возможна как с обычной LVM, так и с ext3. Все, что вам понадобится - наличие внешнего хранилища.
Отдельно стоит отметить, что данная операция должна проводиться человеком, имеющим некоторый опыт.
ЧАСТЬ 1. Установка необходимого ПО и сохранение текущей системы.
Есть два способа реализации Full Encrypted LVM (далее - FELVM).
a) Debian way (TM), где LVM размещаетя на зашифрованном виртуальном устройстве (cryptsetup).
b) Другой путь, когда LVM создается на физическом устройстве, а затем шифруются логические разделы.
Конечно, я выбираю debian way, хотя никаких определенных причин для этого нет.
В качестве исходных данных у меня имеется /dev/hda1 типа Windows NTFS и несколько других разделов,
тип которых не важен, так как их скоро не останется.
Перед тем, как мы начнем, рекомендую сделать полную копию ваших данных на внешний носитель с помощью CloneZilla,
чтобы потом не иметь бледный вид.
Для начала установим 'cryptsetup'. Также ядро должно ключать образ initrd для загрузки. Если это не так,
установите пакет initramfs-tools. Затем создайте следующий файл в каталоге /etc/initramfs-tools/conf.d:
filename: cryptroot
contents:
target=lukspace,source=/dev/hda3,key=none,lvm=vg-root
Затем выполните команду:
# update-initramfs -u
Она создаст образ initrd, который будет знать, где находятся шифрованные разделы после создания.
Создадим, и это обязательно, tar архив вашей системы на внешний носитель:
# tar cSjf /my/external/storage/sysbackup.tar.bz2 /bin/ /boot/ \
/etc/ /home/ /lib/ /opt/ /root/ /sbin/ /selinux/ /srv/ /usr/ /var/
Если вы хотите повысить скорость выполнения данной операции, уберите флаг 'j' и расширение bz2.
Это позволит сохранить все права доступа, файлы, владельцев файлов и т.д.
Как вы можете заметить, я пропустил каталоги /dev/, /media, /mnt, /proc, /sys, /tmp,
так как они будут вновь созданы на новой системе (кроме /media).
Я подразумеваю, что никаких действий в системе после сохранения не производится -
не открываются консоли и сессии X window, кроме корневой.
Настало время получить данные с внешних хранилищ. Будем считать, что оно примонтировано
в /media/abyss. Конечно, /media так же содержит cdrom и прочие полезные вещи.
# tar cSjf /my/external/storage/databackup.tar.bz2 /media/cdrom /media/whatever /media/...
Все ЗА ИСКЛЮЧЕНИЕМ точки монтирования внешнего хранилища!
Теперь мы защищены от любых ошибок при конфигурировании.
ЧАСТЬ 2. Переформатирование диска и создание структуры FELVM.
Помните: если дела приняли дурной оборот - вы всегда можете восстановиться с помощью clonezilla.
Я использую clonezilla CD для большинства работ, где мне нужен live CD.
Загружаем Clonezilla, настраиваем сеть. Затем в консоли (sudo su) выполняем команды:
# aptitude update && aptitude dist-upgrade
Возможно перед этим вам понадобится выполнить что-то подобное:
# ifconfig eth0 up
# dhclient eth0
После того, как live CD обновит ПО нужно установить следущее:
# aptitude install cryptsetup joe
Joe - мой любимый редактор, поэтому далее мы будем считать, что и ваш тоже.
Очищаем диск!
# cfdisk /dev/hda
и удаляем все разделы за исключением /dev/hda1 (NTFS).
Создаем раздел, с которого будет осуществляться загрузка: /dev/hda2 размером 200 MB.
Затем создаем другой раздел, занимающий все свободное пространство(/dev/hda3).
Его в последствии будет занимать rootfs и данные.
Записываем таблицу разделов на диск и выходим.
Мы все поломали, но не стоит волноваться, все будет восстановлено с tar архивов.
Окончательно удаляем наши данные, заполняя все случайными последовательностями,
заодно проверяя наличие badblock:
# badblocks -s -w -t random -v /dev/hda2
# badblocks -s -w -t random -v /dev/hda3
На выполнение этих команд требуется время, так что будьте терпеливы.
Создаем файловую систему на загрузочном разделе:
# mkfs.ext3 /dev/hda2
Используя cryptsetup создадим большой раздел как устройство dm-crypt. Это очень просто:
# cryptsetup -y -s 256 -c aes-cbc-essiv:sha256 luksFormat /dev/hda3
Я не буду приводить объяснение всех опций, если хотите - посмотрите сами.
Обязательно выберите хорошее ключевое слово, которое вы сможете запомнить.
Позже вы сможете сменить его или сделать несколько ключевых слов.
Подошло время использовать инициализированное пространство:
# cryptsetup luksOpen /dev/hda3 lukspace
Эта команда спросит у вас ранее введенное ключевое слово и сделает доступным /dev/mapper/lukspace.
Это может быть расценено как устройство, готовое принять любой вид данных.
Вы можете форматировать его в ext3 или построить LVM, чем мы сейчас и займемся.
Создаем LVM:
# pvcreate /dev/mapper/lukspace
# vgcreate vg /dev/mapper/lukspace
# lvcreate -L10G -nroot vg
# lvcreate -l 100%FREE -nmyspace vg
Так мы получим логический том LVM /dev/vg/root для корневой файловой системы и /dev/vg/myspace для наших данных.
Это было несложно, не так ли?
Дальше еще проще:
# mkfs.ext3 /dev/vg/root
# mkfs.ext3 /dev/vg/myspace
ЧАСТЬ 3. Восстановление системных файлов и загрузка новой системы.
После того, как вы создадите место для корневой файловой системы, настанет
пора разархивировать туда наши данные.
Сперва создадим точку монтирования, которую назовем /media/rootfs и затем:
# mount /dev/vg/root /media/rootfs
а теперь:
# cd /media/rootfs
# tar xSjf /external_storage/sysbackup.tar.bz2
После чего ждем завершения процесса.
Создаем каталоги, которые не были сархивированы:
# mkdir proc sys media dev tmp mnt
# chmod 1777 tmp
Теперь создаем точку монтирования bootfs и монтируем к ней будущий загрузочный раздел:
# mkdir bootfs
# mount /dev/hda2 bootfs
Затем перемещаем загрузочные файлы из rootfs/boot в bootfs. Теперь /dev/hda2
содержит все необходимые для загрузки файлы. И последнее - изменим файл fstab в rootfs/etc
таким образом, чтобы указать новое устройство /dev/vg/root.
Перезагружаемся. После загрузки grub нажимаем 'e' для редактирования опций ядра и
указания правильного root=..., чтобы машина могла загрузиться.
Хочется надеяться, что LUKS спросит у вас кодовое слово, и все пойдет хорошо!
После того, как вы наиграетесь с вашей зашифрованной системой, отредактируйте /boot/grub/menu.lst
для указания корректного устройства root=... и запустите update-grub.
Giorgos Pallas
Решение представлено для Gentoo, но возможно проблема актуальна и для других дистрибутивов.
При обновлении hal до версии 0.5.10 перестает нормально работать
клавиатура. По множественным отзывам в Сети, у всех перестает
работать преключатель раскладки, у меня еще были глюки с другими
клавишами (например кнопка "вверх" работала как PrtScr и др.)
Для начала приведу часть xorg.conf который у меня работал испокон веков:
Section "InputDevice"
Identifier "Chicony"
Driver "kbd"
Option "Protocol" "Standard"
Option "XkbModel" "pc105"
Option "XkbRules" "xorg"
Option "XkbLayout" "us,ru,ua"
Option "XkbVariant" ",winkeys"
Option "XkbOptions" "grp:lwin_toggle,grp_led:scroll"
Option "AutoRepeat" "250 30"
EndSection
Причина того, что эта конфигурация отвалилась, состоит в том, что новая
версия hal просто игнорирует конфиг xorg.conf.
Нашел два метода решения проблемы.
Первый метод:
http://ru.gentoo-wiki.com/HOWTO_hal_и_устройства_ввода
Смысл в том, что создается файл политики hal, который содержит конфигурацию клавиатуры:
/usr/share/hal/fdi/policy/20thirdparty/10russian-layout.fdi
Учитывая, что в статье есть небольшие ошибки, приведу свой файл
конфигурации. Рекомендую сопоставлять с приведенным выше xorg.conf
<?xml version="1.0" encoding="ISO-8859-1"?><!-- -*- SGML -*- -->
<match key="info.capabilities" contains="input.keyboard">
<merge key="input.x11_driver" type="string">kbd</merge>
<merge key="input.xkb.model" type="string">pc105</merge>
<merge key="input.xkb.rules" type="string">xorg</merge>
<merge key="input.xkb.layout" type="string">us,ru</merge>
<merge key="input.xkb.variant" type="string">,winkeys</merge>
<merge key="input.xkb.options" type="strlist">grp:lwin_toggle,grp_led:scroll</merge>
</match>
Думаю смысл понятен.
После создания файла следует пергрузить hald и перегрузить иксы.
Недостаток этого метода состоит в том, что я так и не смог настроить переключение трех языков.
Второй метод:
Второй метод состоит в том, что мы отключаем автоопределение
устройств. Для этого в xorg.conf в секцию ServerLayout дописываем
Option "AutoAddDevices" "False". После перегрузки иксов настройки
клавиатуры берутся из xorg.conf.
Подозреваю, что у второго метода есть свои недостатки, но я их пока не обнаружил.
Иногда возникает ситуация, когда удаленно, по ssh например, нужно перезагрузить linux сервер.
Команды reboot, shutdown не работают так как нужно, то есть просто висят в процессах, но машина не уходит в перезагрузку.
Такое часто бывает, когда отказывает диск, или начинаются проблемы с RAID массивом.
Для форсирования перезагрузки сервера нам подойдет sysrq.
Для начала включаем sysrq через proc:
echo 1 > /proc/sys/kernel/sysrq
Далее посылаем нужную команду в sysrq триггер:
echo b > /proc/sysrq-trigger
Как показывает практика, машина мгновенно уходит в reboot.
Задача ужать стандартный GNOME-LiveCD Fedora7 до 400 Мб.
Ниже журнал действий.
1. Извлекаем из iso образа LiveCD squashfs.img.
mount -o loop ./Fedora-7-Live-i686.iso /mnt/cdrom
копируем все в отдельную директорию директорию /mnt/disk/LiveCD/newcd
umount /mnt/cdrom
2. Монтируем squashfs.img и извлекаем из него os.img
mount -o loop -t squashfs /mnt/disk/LiveCD/newcd/squashfs.img /mnt/cdrom
копируем содержимое в /mnt/disk/LiveCD/new_ext3
umount /mnt/cdrom
3. Монтируем ext3 образ /mnt/disk/LiveCD/new_ext3/os.img
mount -o loop /mnt/disk/LiveCD/new_ext3/os.img /mnt/disk/LiveCD/new_ext3/sysroot
4. Удаляем лишнее и устанавливаем недостающее.
chroot /mnt/disk/LiveCD/new_ext3/sysroot /bin/sh
su -
mount /proc
mount /sys
rm -rf /usr/share/doc
в /usr/share/locale/ - оставляем только русские и английские локали
cd /usr/share/icons; rm -rf Bluecurve gnome
В /usr/share/pixmaps заменяем недостающее, чистим pixmaps/backgrounds/
копируем свою фоновую картинку
cp background.jpg /usr/share/gdm/themes/FedoraFlyingHigh
cp background.jpg /usr/share/backgrounds/images/default.jpg
Чистим /usr/share/backgrounds
Удаляем пакеты с китайскими шрифтами:
rpm -e fonts-chinese fonts-arabic fonts-korean fonts-japanese
Если rpm ругается, делаем "rpm --rebuilddb"
Если нужно создать какие-то директории или произвести действия в момент старта livecd
правим fedora-live в /etc/rc.d/init.d
Ставим желаемые пакеты, например, конфигуратор PPTP:
rpm -Uvh http://pptpclient.sourceforge.net/yum/stable/fc7/pptp-release-current.noarch.rpm
yum --enablerepo=pptp-stable install pptpconfig
....
umount /proc
umount /sys
5. После приведения os.img в нужный вид, создаем новый пустой os.img и
копируем содержимое старого (нужно забить образ нулями, чтобы он лучше сжался,
иначе изменения будут только в метаданных и итоговый образ squashfs после сжатия получиться больше чем начальный).
cd mnt/disk/LiveCD/new_ext3
dd if=/dev/zero of=new_os.img bs=1k count=4096k
/sbin/mkfs.ext3 -F -L "LiveCD" -m 1 new_os.img
/sbin/tune2fs -c0 -i0 -Odir_index -ouser_xattr,acl new_os.img
Монтируем новый образ
mkdir /mnt/disk/LiveCD/new_ext3/new_sysroot
mount -o loop ./new_os.img /mnt/disk/LiveCD/new_ext3/new_sysroot
Копируем содержимое старого через rsync, чтобы сохранить расширенные атрибуты файлов.
rsync -a -v --acls --xattrs --hard-links /mnt/disk/LiveCD/new_ext3/sysroot /mnt/disk/LiveCD/new_ext3/new_sysroot
незабываем размонтировать и переименовать новый образ
umount /mnt/disk/LiveCD/new_ext3/sysroot
umount /mnt/disk/LiveCD/new_ext3/new_sysroot
rm /mnt/disk/LiveCD/new_ext3/new_sysroot
mv /mnt/disk/LiveCD/new_ext3/new_os.img /mnt/disk/LiveCD/new_ext3/os.img
6. Сжимаем ext3 образ
rm /mnt/disk/LiveCD/newcd/squashfs.img
cd /mnt/disk/LiveCD/new_ext3/
/sbin/mksquashfs os.img sysroot /mnt/disk/LiveCD/newcd/squashfs.img
7. Создаем iso образ для записи на CD:
mkisofs -o ./live.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
-boot-info-table -J -r -hide-rr-moved -V "Fedora-7-Live-i386" /mnt/disk/LiveCD/newcd/
Если появится желание изменить метку диска Fedora-7-Live-i386, не забудьте поменять ее в isolinux/isolinux.cfg
Недавно была добавлена интересная особенность в Workstation 6.0, которая делает WS6 отличным средством
для отладки ядра Linux. Теперь можно с легкостью отлаживать Linux VM на хосте при помощи gdb
без каких-либо изменений в Guest VM. Ни каких kdb, перекомпиляций или еще одной машины не требуется.
Все что вам потребуется, так это всего одна строчка в VM'шном конфигурационном файле.
Чтобы использовать новую особенность, необходимо достать последний билд WS6:
http://www.vmware.com/products/beta/ws/
Разместить в вашем Linux VM конфигурационном файле строчку:
debugStub.listen.guest32=1
Теперь, всякий раз, когда вы запускаете виртуальную машину, Вы будете видеть на хост консоле:
VMware Workstation is listening for debug connection on port 8832.
Запустите gdb на хосте, ссылаясь на ядро, для которого у Вас есть System.map и присоедините его к виртуальной машине:
% gdb
(gdb) file vmlinux-2.4.21-27.EL.debug
(gdb) target remote localhost:8832
Модуль Linux ядра netconsole позволяет экспортировать консоль на другую машину по сети,
что полезно для отладки ситуации зависания Linux без вывода диагностики в лог и на экран (например, X-ы зависли).
В /etc/modprobe.d/ создаем файл или добавляем в /etc/modules.conf:
options netconsole netconsole=32769@192.168.1.1/eth1,32769@192.168.1.6/01:23:34:56:78:9A
где,
192.168.1.1:32769 сетевой адрес и порт на eth1 интерфейсе локальной машины, с которого будет производится отправка пакетов.
192.168.1.6:32769 сетевой адрес, порт и MAC адрес удаленной машины куда будет экспортирована консоль.
На удаленной машине 192.168.1.6, для доступа к консоли используем netcat:
nc -l -p 32769 -u
Подгружаем модуль netconsole:
modprobe netconsole
Если консоль зависла, машина работает, но не откликается на CTRL-ALT-BKSPC, ALT-CTRL-F1, CTRL-ALT-DEL
и по сети зайти на машину тоже нет возможности.
"ALT + SysReq + r" - перевести клавиатуру в Raw режим.
"ALT + SysReq + s" - сбросить буферы FS на диск (может занять много времени, если система сильно загружена).
"ALT + SysReq + e" - отправить сигнал завершения работы процессам.
"ALT + SysReq + i" - принудительно убить процессы не желающие завершить работу по сигналу KILL.
'ALT + SysReq + u' - отмонтировать дисковые разделы.
'ALT + SysReq + b' - перезагрузить машину.
PS. Клавиша SysReq совпадает с Print Screen.
Необходимо загрузить образ DOS по сети.
1. создаем образ:
dd if=/dev/zero of=floppy288.img bs=1024 count=2880
mkdosfs floppy288.img
ms-sys -1 -f floppy288.img
mount -o loop floppy288.img /mnt/floppy
cp msdos.sys /mnt/floppy
cp io.sys /mnt/floppy
cp command.com /mnt/floppy
umount /mnt/floppy
2. создаем файл загрузчика PXE:
label linux
kernel dos/memdisk
append initrd=dos/floppy288.img
Все, далее можно грузиться по сети, и предварительно скопировать в образ утилиты для обновления биос.
Файл memdisk bp из пакета syslinux, из дистрибутива.
Утилита ms-sys на sourceforge.net
Чтобы собрать только один модуль входящий в комплект ядра, но отключенный в конфигурации,
без пересборки остальных частей (на примере ntfs):
make CONFIG_NTFS_FS=m CONFIG_NTFS_DEBUG=n CONFIG_NTFS_RW=n M=fs/ntfs
Цель - организовать аутентификацию пользователя в Linux системе, не через ввод пароля,
а через вставку USB флэша или CDROM, содержащего DSA ключ.
1. Устанавливаем pam_usb (http://pamusb.sourceforge.net/);
2. В /etc/pam.d/login, /etc/pam.d/xdm и т.д. прописываем, в зависимости от режима:
2.1. Вход только при вставке Flash с ключем:
auth required pam_usb.so
#auth required pam_unix.so # комментируем строку.
2.2. Можем войти просто вставив Flash или набрав пароль:
auth sufficient pam_usb.so # ставим перед "auth required pam_unix.so"
2.3. Режим входа только при вставке Flash с ключем одновременно с вводом пароля:
auth required pam_usb.so # ставим перед "auth required pam_unix.so"
3. Монтируем Flash в /mnt/usb и генерируем для пользователя ключ:
usbadm keygen /mnt/usb логин 1024
Есть два способа как заставить MPX200 работать с Linux: IrDA и wince-usb.
1. Подключение через IrDA (SIR):
Устанавливаем параметры для SiR порта
/bin/setserial /dev/ttyS1 port 0x6f8 irq 3 uart 8250 baud_base 115200
irattach /dev/ttyS1 -s
Для RedHat-based Linux дистрибутивов делаем проще:
В /etc/sysconfig/irda
IRDA=yes
DEVICE=/dev/ttyS1
DISCOVERY=yes
# service irda start
Запускем демон синхронизации (не из под root). Качаем с http://synce.sourceforge.net
$ dccm
Если используется пароль запускаем как "dccm -p пароль"
Один раз указываем используемый порт.
# synce-serial-config ircomm0
Стартуем pppd (про hotplug, ниже)
# synce-serial-start
Проверяем.
$ pstatus
Version
=======
Version: 4.20.0 (Microsoft Windows Mobile 2003 for Pocket PC Phone Edition (?))
Platform: 3 (Windows CE)
.....
Завершаем сеанс
# synce-serial-abort
2. Подключение по USB. Для 2.4.x ядра используем user space драйвер wince-usb
http://cvs.sourceforge.net/viewcvs.py/synce/wince-usb/ + http://libusb.sourceforge.net
(последние 2.6.x ядра должны работать с модулями ipaq и usb-serial из коробки).
Патчим. В самом начале ipaqd.c меняем значения IPAQ_ENDPOINT на
#define IPAQ_ENDPOINT_IN 0x82
#define IPAQ_ENDPOINT_OUT 0x02
Далее в devlist[] добавляем
{ 0x045e, 0x00ce, "Motorola MPX200" },
Создаем /usr/local/bin/cebox.sh взяв пример из README к wince-usb, например:
#!/bin/sh
/usr/sbin/pppd nocrtscts local debug passive silent 192.168.1.1:192.168.1.2 ms-dns 192.168.1.1 noauth proxyarp
$ dccm
Подключаем телефон и сразу запускаем
# rmmod ipaq (пока не поправили hotplug)
# ipaqd 2>/var/log/ipaqd.log
Далее запускаем synce-serial-* как в предыдущем шаге.
3. Настройка HotPlug (чтобы все запускалось автоматически).
В /etc/hotplug/usb.agent добавляем после блока с "LABEL="USB product $PRODUCT":
if [ "$PRODUCT" = "45e/ce/0" ]; then
/etc/hotplug/usb/ipaq
exit 0
fi
Создаем /etc/hotplug/usb/ipaq
#!/bin/bash
killall -9 ipaqd
killall dccm
su -c /usr/bin/dccm /user/
/usr/local/bin/ipaqd 2>/var/log/ipaq.log
4. Стандартные команды synce:
pcp - копирование файлов (аналог cp)
pls - список файлов в директории (аналог ls)
pmkdir - создание директории (аналог mkdir)
pmv - перенос/переименование файлов (аналог mv)
prm - удаление файлов (аналог rm)
prmdir - удаление директорий
prun - запуск программы на устройстве
pstatus - статус устройства
synce-install-cab - установка на устройство .cab файла
orange - позволяет выдрать .cab из .exe инсталлера;
В Modnight Commander удобно использовать VFS понимающую команды
"cd #synce" и "cd #synceroot",
правда модуль раздаваемый на сайте synce у меня не заработал, пришлось его переписать:
ftp://ftp.opennet.ru/pub/sys/shell/synce-mcfs-patched/
Для работы, копируем файлы synce и synceroot в /usr/lib/mc/extfs
К extfs.ini добавляем:
synce
synceroot
Хорошая графическая оболочка для синхронизации календаря и адресной книги - MultiSync (http://multisync.sourceforge.net/)
Превращение двух 100 мбит/c сетевых карт в одну виртуальную, с пропускной способностью 200 мбит/c.
Документация: Documentation/networking/bonding.txt в дереве исходных текстов ядра и "modinfo bonding".
Кратко:
Подгружаем модуль ядра "bonding", в /etc/modules.conf указываем
alias bond0 bonding
При желании устанавливаем опции для доп. настройки модуля, например:
options bond0 mode=2, где mode=
0 - balance-rr (Round-robin выбор интерфейса)
1 - active-backup (работает только один интерфейс, остальные в режиме горячей замены)
2 - balance-xor - для всех пересылок на MAC закрепляется один из интерфейсов
3 - broadcast - трафик идет через оба интерфейса одновременно
4 - 802.3ad - для коммутаторов с поддержкой IEEE 802.3ad Dynamic link aggregation
5 - balance-tlb, 6 - balance-alb
/sbin/ifconfig bond0 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 up
/sbin/ifenslave bond0 eth0
/sbin/ifenslave bond0 eth1
Или для дистрибутивов в которых используется пакет initscripts (http://rhlinux.redhat.com/initscripts/):
/etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
BOOTPROTO=static
BROADCAST=192.168.63.255
IPADDR=192.168.1.1
NETMASK=255.255.255.0
NETWORK=192.168.0.0
ONBOOT=yes
/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
MASTER=bond0
SLAVE=yes
USERCTL=no
/etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
ONBOOT=yes
MASTER=bond0
SLAVE=yes
USERCTL=no
initrd - RAM-диск, инициализируемый загрузчиком, требуется для подключения модулей ядра, необходимых
на этапе до монтирования root-раздела, (например, до монтирования нужно подгрузить - ext2/ext3/scsi модули).
1) man initrd - все изумительно описано;
2) после сборки ядра создаем новый initrd:
mkinitrd /boot/initrd-2.4.21 2.4.21;
3) в /etc/lilo.conf:
initrd=/boot/initrd-2.4.21
В mkinitrd сам initrd можно назвать как угодно, но второй параметр обязательно версия ядра.
Добавьте в /etc/rc.d/rc.local:
echo 1 > /proc/sys/kernel/panic
Т.е. перезагрузка будет выполнена через 1 сек. после panic, если 0 - то не перезагружать а ждать.
Если добавление в lilo append="mem=1536M" не помогает:
Необходимо пересобрать 2.2.x ядро с опцией CONFIG_2GB=y
Processor type and features -> Maximum Physical Memory -> 2Gb
Если проблема проявляется в ядре 2.4.x - CONFIG_HIGHMEM, CONFIG_HIGHMEM4G или CONFIG_HIGHMEM64G
- Включаем поддержку Reiserfs в ядре.
- Устанавливаем reiserfsprogs-3.x.0j.tar.gz
- Cоздаем бут дискету (mkbootdisk --device /dev/fd0 2.4.13;
lilo -C /etc/lilo.flop)
- Грузимся с дискеты указав в Lilo приглашении "linux root=/dev/hd init=/bin/bash"
- mkreiserfs /dev/hda1
- mount -t reiserfs /dev/had1 /
Если при наборе /sbin/poweroff отключение питания не срабатывает, то:
/sbin/modprobe ospm_busmgr
/sbin/modprobe ospm_system
или в /etc/modules.conf:
alias ospm-busmgr ospm_busmgr
alias ospm-busmgr ospm_system
/sbin/mii-tool -F 100baseTx-FD eth0
или ethtool -s eth0 speed 100 duplex full autoneg off
Для модуля:
В /etc/modules.conf:
options eepro100 options=0x200 full_duplex=1
alias eth0 eepro100
insmod eepro100.o debug=1 options=0x200
Для ядра в boot приглашении:
ether=0,0,0x200,eth0
PS. Для драйвера версии меньше 1.14 (mod_info -a eepro100) вместо 0x200 следует писать 0x30.
Выкачиваем и накладываем ext3 патчи (ftp://ftp.kernel.org/pub/linux/kernel/people/sct/ext3/) и
утилиты (ftp://download.sourceforge.net/pub/sourceforge/e2fsprogs/).
Преобразуем ext2 FS в ext3 (для отмонтированного раздела hda1):
tune2fs -j /dev/hda1
Обратное преобразование (из ext3 в ext2):
tune2fs -O ^has_journal /dev/hda1
fsck.ext2 -f /dev/hdaX
Для форматирование нового ext3 раздела:
mke2fs -j /dev/hda1
Как обновить версию журнала:
mount /dev/hdaX /mnt -o journal=update
1. Уменьшение таймаута в grub,
vi /boot/grub/menu.lst
timeout=0
или через GUI System -> Administration -> StartUp-Manager
2. Отключаем ненужные сервисы:
Меню System -> Preferences -> Sessions (Сеансы)
Например, можно отключить:
Bluetooth Manager (Менеджер устройств Bluetooth)
Check for new hardware drivers
Evolution Alarm Notifier
Print Queue Applet (Апплет очереди печати)
Tracker (служба поиска и индексирования)
Меню System -> Administration -> Services (Службы)
или через консольную утилиту sysv-rc-conf
Можно отключить загрузку редко используемых служб, например, RPC, NFS, avahi-daemon, cupsys, apport, ssh.
3. Оптимизация монтирования файловых систем:
в /etc/fstab добавляем опции "noatime,nodiratime",
4. Уменьшение интенсивности работы с свопом
в /etc/sysctl.conf добавляем vm.swappiness=10
5. Включение возможности параллельного старта сервисов на этапе загрузки:
в /etc/init.d/rc меняем CONCURRENCY=none на CONCURRENCY=shell
6. Кэширование программ и библиотек используемых на этапе инициализации.
Единоразово загружаем Ubuntu с передачей ядру параметра profile, на этапе работы grub,
который включает режим профилирования. Грузиться с этим флагом будет заведомо медленнее,
но при загрузке с флагом профилирования в Ubunti активируется сервис readahead,
который обновляет информацию о всех используемых на этапе загрузки библиотеках и утилитах
в файле /etc/readahead/boot, а в /etc/readahead/desktop - информацию о загрузке десктоп окружения.
При следующей загрузке сервис readahead, при помощи программы /sbin/readahead-list,
загрузит библиотеки и программы,
упоминающиеся в индексе, в page cache, что немного уменьшит время загрузки.
7. Отключаем IPv6
в /etc/modprobe.d/aliases заменяем строку "alias net-pf-10 ipv6" на
"alias net-pf-10 off #ipv6".
7. Устанавливаем preload
sudo apt-get install preload
в установке prelink нет необходимости, так как в Ubuntu задейстован
альтернативный механизм линковки DT_GNU_HASH (http://lwn.net/Articles/192624/),
поддерживаемый в Glibc 2.5.
Подробнее о включении prelink и preload см. http://www.opennet.ruhttp://www.opennet.ru/tips/info/1695.shtml
Prelink позволяет уменьшить время загрузки приложений, слинкованных со множеством динамических библиотек,
путем оптимизации на уровне структуры ELF файла.
aptitude install prelink
/etc/cron.daily/prelink
Preload - другое средство уменьшения времени запуска, основанное на предварительной
загрузке в память наиболее интенсивно используемых данных, не дожидаясь непосредственного
запуска программы (эффективно для повторных запусков).
aptitude install preload
Как правило конфигурация по умолчанию (/etc/preload.conf) не требует изменений,
но при желании можно обратить внимание на опции:
model.cycle (по умолчанию 20 сек) - как часто будет инициирован анализ состояния системы и обновление кэша;
model.halflife ( по умолчанию 168 часов) - через какое время данные в кэше будут считаться устаревшими
(каждый halflife степень актуальности данных в кэше будет уменьшена на 50%);
model.minsize (по умолчанию 2000000 байт) - минимальный объем данных прошедший через системные вызовы,
необходимый для начала оптимизации приложения. Позволяет использовать preload только для крупных приложений.
model.memtotal (-10%), model.memfree (100%), model.memcached (30%) - директивы определяющие степень использования ОЗУ для хранения кэша.
Размер кэша рассчитывается по формуле:
model.memtotal * размер ОЗУ
+ model.memfree * размер свободной памяти во время запуска preload
+ model.memcached * размер памяти отведенной под системный кэш (Cached).
Состояние работы preload можно оценить через файл /var/lib/preload/preload.state
Если prelink, как правило, запускается раз в день и модифицирует ELF файлы,
то preload оформлен в виде программы-демона,
постоянно наблюдающего за интенсивностью запуска программ и на основании
собранной статистики загружающего компоненты в память.
Выигрыш от использования prelink для OpenOffice.org и Firefox около 15-20%, для preload - 50%.
Задача сделать так, чтобы выполнение скрипта для бэкапа не сказывалось на производительности приложений
с интенсивными дисковыми операциями.
Решение - понижение приоритета скрипта в планировщике ввода/вывода CFQ, который включен в Linux ядро,
начиная с версии 2.6.13, и используется по умолчанию начиная с 2.6.18.
Проверяем, что активный планировщик у нас CFQ:
for d in /sys/block/sd[a-z]/queue/scheduler; do echo "$d => $(cat $d)" ; done
Видим: /sys/block/sda/queue/scheduler => noop anticipatory deadline [cfq]
Запускаем скрипт бэкапа с пониженным приоритетом:
nice -n 19 ionice -c2 -n7 backup.sh
утилитой nice с самым низким приоритетом вызываем утилиту ionice cо 2 классом планировки (
1 - real time, 2 - нормальный режим, 3 - работа только в моменты простоя (idle))
и самым низким уровнем приоритета (7).
Если процесс все равно мешает, можем на лету перевести его в idle режим:
ionice -c3 -p 1004
или изменить приоритет планировщика:
renice 19 -p 1004
Где 1004 - PID процесса.
При необходимости увеличить производительность определенного процесса в системе,
можно жестко привязать его к определенному CPU (CPU affinity), исключив
ситуацию мигрирования между процессорами, а также изменить для него алгоритм работы
планировщика задач и увеличить приоритет.
Привязка к CPU осуществляется командой taskset, а изменение параметров real-time
планирования командой chrt. Обе команды можно использовать каскадно, вызывая
одну в качестве аргумента другой.
Например:
taskset -c 2-3 chrt -f 1 <command>
привяжет выполнение команды к CPU со 2 по 3 ("-c 2-3", можно перечислять
процессоры через запятую, например, "-c 2,3"), а также задействует политику
планирования SCHED_FIFO ("-f") и установит приоритет 1 уровня.
Политики планирования (описание - man sched_setscheduler):
-b SCHED_BATCH
-f SCHED_FIFO
-o SCHED_OTHER
-r SCHED_RR
Изменение параметров для уже запущенного процесса производится при помощи опции "-p".
Например, изменение параметров процесса с PID 123:
taskset -c 2-3 -p 123
chrt -f 1 -p 123
Опция "-D" утилиты e2fsck позволяет выполнить переиндексацию при использовании dir_index (tune2fs -O +dir_index),
иначе выполнить перекомпановку с сортировкой (когда было создано или удалено
большое количество директорий) и сокращением размера (когда в
директории было много файлов, а потом их удалили).
Пример запуска (/dev/sdb1 должен быть отмонтирован или переведен в режим только для чтения):
# e2fsck -D -f /dev/sdb1
Если привязать прерывание от сетевой карты на один CPU, то пропускная способность Fast Ethernet
возрастает примерно на 15% (измерения проводились на 2.4 ядре, но справедливо и для ядер 2.6).
Определяем прерывание сетевой карты:
cat /proc/interrupts
Привязываем к определенному CPU:
echo 2 > /proc/irq/NNN/smp_affinity
где NNN -- прерывание от сетевухи, 2 - битовая маска для выборка CPU.
если сетевухи две, для второй
echo 4 > /proc/irq/MMM/smp_affinity
Битовые маски: 1 - CPU1, 2 - CPU2, 4 - CPU3 и т.д.
Подробнее см. Documentation/IRQ-affinity.txt
При включении демона irqbalance значения smp_affinity выбираются динамически.
Приоритеты для использования Disk I/O
С выходом CFQ v3 в Linux 2.6.13 появилась возможность выставлять
приоритеты использования дисковой подсистемы для процессов, чего
раньше так не хватало. Подобно утилите nice для назначение
приоритетов использования процессора появилась утилита ionice.
Синтаксис команды прост:
ionice -c класс -n приоритет -p PID
Класс:
3 - Idle - Получает приоритет на использование жесткого диска только
когда другие программы ничего не пишут. Приоритеты не используются.
2 - Best Effort - Класс по-умолчанию. Доступные приоритеты [0-7].
1 - Real Time - Дает преимущественный доступ к диску процессу, не
смотря на другие процессы. Доступные приоритеты [0-7].
Начиная с Linux ядра 2.6.16 появилась возможность принудительной очистки системных кэшей:
Чистим pagecache:
echo 1 > /proc/sys/vm/drop_caches
Чистим dentrie и inode кэши:
echo 2 > /proc/sys/vm/drop_caches
Чистим pagecache, dentrie и inode кэши:
echo 3 > /proc/sys/vm/drop_caches
Перед выполнением операции необходимо запустить команду sync
Увеличиваем максимальный размер памяти отводимой для TCP буферов:
(16Мб на порядок больше, чем нужно, следует экспериментальным путем подобрать
оптимальные значения, понеменогу увеличивая параметры заданные по умолчанию)
sysctl -w net.core.rmem_max = 16777216
sysctl -w net.core.wmem_max = 16777216
Увеличиваем лимиты автотюнинга (min, default, max bytes)
sysctl -w net.ipv4.tcp_rmem = "4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem = "4096 65536 16777216"
Увеличиваем размер очереди пакетов на сетевом интерфейсе, особенно полезно для Gigabit Ethernet:
ifconfig eth0 txqueuelen 1000
Особенности Linux ядра 2.4.x:
Для предотвращения особенности при уменьшении размера окна, из-за повторов передеачи пакетов,
для одного соединения, уменьшать на 10 минут размер окна для всех остальных соединений к тому же хосту:
sysctl -w net.ipv4.route.flush=1
Особенности Linux ядра 2.6.x:
Запрещаем кеширование статуса ssthresh (были ретрансмиты) для других соединений
sysctl -w net.ipv4.tcp_no_metrics_save = 1
Рекомендуется увеличить размер backlog до 1000 или выше
(для 10Gb линка можно поставить 30000):
sysctl -w net.core.netdev_max_backlog = 2500
Начиная с ядра 2.6.13 можно менять алгоритм обработки ситуации перегрузки:
sysctl -w net.ipv4.tcp_congestion_control=htcp
reno: традиционный TCP
bic: BIC-TCP (для высокоскоростных сетей, быстрое восстановление после потери)
highspeed: HighSpeed TCP: Sally Floyd's suggested algorithm
htcp: Hamilton TCP (для высокоскоростных сетей)
hybla: для спутниковых линков
scalable: Scalable TCP
vegas: TCP Vegas
westwood: для сетей с большой потерей пакетов
Когда стандартный reno не устраивает рекомендуется попробовать bic или htcp.
Значения параметров тюнинга подробно описаны в документе ip-sysctl.txt в комплекте ядра:
http://www-didc.lbl.gov/TCP-tuning/ip-sysctl-2.6.txt
Пример использования жесткой привязки процесса к определенному процессору (CPU affinity).
Устанавливаем пакет schedutils
(Debian: apt-get install schedutils, Red Hat: up2date schedutils или rpm -ivh schedutils*)
Привязка процесса с pid 13545 к первому CPU (#0):
taskset -c 1 -p 13545
к 3 и 4 CPU (#2 и #3):
taskset -c 3,4 -p 13545
Загрузку процессоров в SMP системе удобно оценивать через утилиту mpstat из пакета sysstat.
mpstat -P ALL
Утилизацию подсистемы ввода/вывода можно посмотреть через команду iostat
LVM - позволяет гибко создавать, удалять и изменять размеры разделов без потери данных.
ext3 - расширение ext2 для журналирования. Поддерживает журналирование данных, а не только метаданных (при data=journal).
reiserfs - высокая скорость работы с каталогами с большим числом файлов, компактно хранит хвосты от файлов,
поддерживает увеличение размера раздела без остановки сервера.
xfs - быстрая работа с файлами большого размера, великолепная надёжность, поддержка ACL.
Linux поддерживает Hyper-Threading начиная с ядра 2.4.17.
Ядро должно быть собрано как SMP,
При загрузке, передаем параметр acpismp=force (в lilo: append=" acpismp=force")
проверка работы:
cat /proc/cpuinfo, если среди flags есть "ht", то Hyper-Threading активирован.
/usr/src/linux/Documenation/filesystems/proc.txt
/usr/src/linux/Documenation/networking/ip-sysctl.txt
Далее в скобках указаны значения по умолчанию для 2.2.x/2.4.x ядер.
Если ядро собрано с CONFIG_SYNCOOKIES для защиты от syn флуда (net.ipv4.tcpsyn_cookies)
echo 1 > /proc/sys/net/ipv4/tcp_syncookies #(0/0)
Увеличиваем размер backlog очереди (аналог sysctl net.ipv4.tcp_max_syn_backlog).
echo 1280 > /proc/sys/net/ipv4/tcp_max_syn_backlog #(128/1024)
Число начальных SYN и SYNACK пересылок для TCP соединения (лучше не трогать).
echo 4 > /proc/sys/net/ipv4/tcp_synack_retries #(x/5)
echo 4 > /proc/sys/net/ipv4/tcp_syn_retries #(10/5)
Какие порты использовать в качестве локальных TCP и UDP портов (sysctl net.ipv4.ip_local_port_range).
echo "16384 61000" > /proc/sys/net/ipv4/ip_local_port_range #(1024 4999/32768 61000)
Сколько секунд ожидать приема FIN до полного закрытия сокета.
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout #(180/60)
Как часто посылать сообщение о поддержании keep alive соединения.
echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time #(7200/7200)
Сколько пакетов проверки keepalive посылать, прежде чем соединение будет закрыто.
echo 2 > /proc/sys/net/ipv4/tcp_keepalive_probes #(9/9)
Запрещаем TCP window scaling (net.ipv4.tcp_window_scaling)
echo 0 > /proc/sys/net/ipv4/tcp_window_scaling #(1/1)
Запрещаем selective acknowledgements, RFC2018 (net.ipv4.tcp_sack).
echo 0 > /proc/sys/net/ipv4/tcp_sack #(1/1)
Запрещаем TCP timestamps, RFC1323 (net.ipv4.tcp_timestamps)
echo 0 > /proc/sys/net/ipv4/tcp_timestamps #(1/1)
Увеличиваем размер буфера для приема и отправки данных через сокеты.
echo 1048576 > /proc/sys/net/core/rmem_max #(65535/autotune)
echo 1048576 > /proc/sys/net/core/rmem_default #(65535/autotune)
echo 1048576 > /proc/sys/net/core/wmem_max #(65535/autotune)
echo 1048576 > /proc/sys/net/core/wmem_default #(65535/autotune)
Если не требуется форвадинг пакетов (машина не рутер) выключаем.
(net.ipv4.ip_forward и net.ipv4.conf.all.forwarding)
echo 0 /proc/sys/net/ipv4/ip_forward #(0/0)
echo 0 /proc/sys/net/ipv4/conf/all/forwarding #(0/0)
Через какое время убивать соединеие закрытое на нашей стороне (net.ipv4.tcp_orphan_retries)
echo 1 > /proc/sys/net/ipv4/tcp_orphan_retries #(x/7)
man hdparm (например: /sbin/hdparm -c3 -d1 -X34 /dev/hda)
man elvtune
man tune2fs
echo 128000 > /proc/sys/fs/inode-max # def 16384
echo 64000 > /proc/sys/fs/file-max # def 4096 Число одновременно открытых файлов.
cd /proc/sys/fs/ (в 2.4.x работает автотюнинг)
/usr/src/linux/Documentation/sysctl/fs.txt
/usr/src/linux/Documentation/filesystems/proc.txt
Советую использовать tmpfs или ramfs
(разница в том, что данные tmpfs подвержены своппингу, ramfs создана для тестов, а ramdisk всегда хранится в ОЗУ)
/usr/src/linux/Documentation/filesystems/tmpfs.txt
mount -t tmpfs -osize=256M /dev/shm1 /mnt1
Для ramfs:
mount -t ramfs -omaxsize=256M none /mnt1
Если желание использовать ramdisk осталось, читаем
/usr/src/linux/Documentation/ramdisk.txt
mkdir /ramdisk
Для 256Мб ramdisk в lilo.conf добавляем:
append="ramdisk_size=256000"
Запускаем lilo и перезагружаем машину.
mke2fs /dev/ram0
mount -t -ext2 /dev/ram0 /ramdisk
В будущих версиях RHEL и Fedora Linux появится возможность
использования для хэширования паролей алгоритмов SHA-256 и SHA-512
В Kickstart режиме:
DES
authconfig --enableshadow --passalgo=descrypt
MD5
authconfig --enableshadow --enablemd5
или
authconfig --enableshadow --passalgo=md5
SHA-256
authconfig --enableshadow --passalgo=sha256
SHA-512
authconfig --enableshadow --passalgo=sha512
Тип хэша также можно задать через /etc/logis.desf, присвоив переменной
ENCRYPT_METHOD значение DES, MD5, SHA256 или SHA512
Устанавливаем пакеты необходимые для сборки системы fprint:
aptitude install libpam0g-dev libusb-dev libmagick9-dev libglib2.0-dev libssl-dev
aptitude install libgtk2.0-dev libx11-dev libxv-dev # если будет сборка с поддержкой x11
Загружаем libfprint и pam_fprint с сайта http://www.reactivated.net/fprint
Собираем стандартно через:
./configure
make
make install
Или пересобираем готовые Debian пакеты:
---
Качаем .dsc, tar.gz и diff.gz со страниц
http://packages.debian.org/experimental/libfprint0http://packages.debian.org/experimental/libpam-fprint
Устанавливаем доп. пакеты необходимые для сборки:
aptitude install fakeroot autotools-dev debhelper dpkg-dev
dpkg-source -x libfprint_0.0.5-2.dsc
cd libfprint-0.0.5
dpkg-buildpackage -rfakeroot
Пакет libpam-fprint создается по аналогии
---
Генерируем слепок отпечатка указательного пальца
(запускаем под логином для которого сохраняем отпечаток):
pam_fprint_enroll --enroll-finger 7
Для опциональной аутентификации по отпечатку (возможность ввести пароль остается),
в /etc/pam.d/common-auth первой строкой ставим:
auth sufficient pam_fprint.so
Если пускать в систему нужно только после сверки отпечатка, "sufficient" заменяем на "required".
PS. В Gentoo Linux добавляем в /etc/pam.d/system-auth перед строкой c pam_unix.so
Команда chattr позволяет изменять параметры ФС для отдельного файла или директории:
chattr +a - только добавление данных (append-only), удаление и переименование запрещено;
chattr +i - запрещено удаление, изменение или переименование (immutable);
chattr +A - запретить сохранение данных о каждом обращении к файлу (no atime)
chattr +S - синхронное изменение всех данных на диск, без кэширования;
chattr +c - файл будет хранится на диске в сжатом виде (нужен отдельный патч для ядра);
chattr +s - после удаления файла, место на диске забивается нулями (внешний патч);
chattr +u - резервирование данных файла после удаления (внешний патч);
Пример:
chattr -R +i /bin /sbin /usr/bin /usr/sbin - запрещаем изменение бинарников
chattr +a /var/log/secure - предотвращаем модификацию лога злоумышленником
Для просмотра расширенных атрибутов используется утилита lsattr.
Для FreeBSD см. man chflags и man security
После обновления ОС и установки gnome столкнулся с проблемой:
dpkg: ../../src/packages.c:191: process_queue: Assertion 'dependtry <= 4' failed
Соотвественно пакеты больше не ставились и не обновлялись. Погуглив решил проблему следующим образом:
sudo dpkg -l | grep -v ^ii
dpkg -l выводит список установленных пакетов,
grep -v ^ii - оставляет в выводе только неправильно установленные пакеты.
После получения списка таких пакетов, удалил первый из списка неправильно установленный пакет командой
sudo dpkg -purge remove имя_пакета
После вышеуказанных манипуляций проблема ушла.
Найти заданный пакет по имени:
zypper se banshee-1
zypper se bans*
По умолчанию в результатах поиска отображается имя, описание и тип. Для промотора
дополнительных параметров, например, номера версии и имени репозитория, можно использовать:
zypper se -s пакет
Вывод краткой справки по пакету:
zypper if пакет
Удаление пакетов по маске:
zypper rm gtk*devel*
Установка пакетов по маске:
zypper in gtk-sharp?
Удаление пакета с версией старше заданной:
zypper rm пакет>1.2.3
Установка и удаление одной командой:
zypper in пакет_для_установки -пакет_для_удаления +пакет_для_установки
Принудительная установка уже присутствующего в системе пакета:
zypper in --force пакет
Установка RPM пакетов из файла, а не из репозитория:
zypper in ./file.rpm
zypper in http://<url>/file.rpm
Обновить все установленные в системе пакеты (исправления проблем безопасности и критических ошибок):
zypper up
Обновить систему до более новой версии openSUSE:
zypper dup
Установить программы, необходимые для пересборки заданного пакета из исходных текстов:
zypper si -d пакет
Посмотреть список мета-пакетов (сгруппированных наборов):
zypper pt
Установить мета-пакет:
zypper in -t pattern xfce
Найти мета-пакет по маске:
zypper se -t pattern media
Посмотреть список доступных репозиториев пакетов:
zypper lr
Добавить новый репозиторий:
zypper ar <url> <name>
Временно отключить первый репозиторий в списке:
zypper mr -d 1
Временно отключить репозиторий по имени:
zypper mr -d repo-oss
Удалить первый репозиторий из списка:
zypper rr 1
Выполнение действия в тестовом режиме, без фактического выполнения операции:
zypper in --dry-run пакет
Заморозить состояние пакета в текущем виде, для предотвращения случайной установки или удаления:
zypper addlock пакет
Снятие блокировки:
zypper removelock пакет
На машине, на которой планируется установка, загружаем ядро и образ ram-диска:
cd /tmp
wget http://mirrors.kernel.org/opensuse/distribution/11.0/repo/oss/boot/i386/loader/linux
wget http://mirrors.kernel.org/opensuse/distribution/11.0/repo/oss/boot/i386/loader/initrd
cp linux /boot/vmlinuz.install
cp initrd /boot/initrd.install
Модифицируем настройки Grub, /boot/grub/menu.lst (параметры kernel нужно переписать в одну строку)
title Boot -- openSUSE 11.0
root (hd0,0)
kernel /boot/vmlinuz.install noapic usessh=1 sshpassword="12345645"
install=http://mirrors.kernel.org/opensuse/distribution/11.0/repo/oss/
hostip=192.168.42.2 gateway=192.168.42.1 nameserver=192.168.42.1
initrd /boot/initrd.install
Где
192.168.42.2 - IP машины на которую производится установка,
192.168.42.1 - DNS и шлюз
12345645 - пароль по которому будет осуществлен вход на устанавливаемую машину по SSH
Скрипт для автоматизации вышеприведенных действий можно загрузить по ссылке
http://www.suse.de/~lnussel/setupgrubfornfsinstall.html
После перезагрузки, заходим c паролем 12345645:
ssh -X root@192.168.42.2
и начинаем процесс установки запустив yast (текстовый режим) или yast2 (графический режим).
В случае обрыва процесса установки его можно продолжить, повторив настройки grub
и выполнив после входа по SSH:
/usr/lib/YaST2/startup/YaST2.ssh
При наличии "чистой" машины образ ядра можно загрузить по сети при помощи PXE.
Пример можно найти в материале: http://wiki.opennet.ru/NetworkBoot
Конфигурация pxelinux будет выглядеть примерно так:
default pxelinux
prompt 1
timeout 600
label pxelinux.install
kernel vmlinuz
append initrd=initrd.install noapic usessh=1 sshpassword="12345645"
install=http://mirrors.kernel.org/opensuse/distribution/11.0/repo/oss/
hostip=192.168.42.2 gateway=192.168.42.1 nameserver=192.168.42.1
Подготовка загрузочного Flash для установки Ubuntu Linux.
Устанавливаем syslinux:
sudo apt-get install syslinux
Устанавливаем загрузчик на Flash (/dev/sdb1 - определить можно из вывода mount или dmesg):
syslinux -s /dev/sdb1
Копируем полностью содержимое стандартного установочного LiveCD диска с Ubuntu Linux на Flash.
Копируем из директории casper два файла vmlinuz и initrd.gz в корень Flash,
а также все файлы из деректорий isolinux и install.
Переименовываем файл isolinux.cfg в syslinux.cfg.
Другой вариант - создание LiveUSB через специальный GUI интерфейс:
В /etc/apt/sources.list добавляем репозиторий:
deb http://ppa.launchpad.net/probono/ubuntu hardy main
Ставим пакет liveusb:
sudo apt-get update
sudo apt-get install liveusb
Монтируем образ загрузочного диска:
sudo mount -o loop -tiso9660 ubuntu-8.04.1-desktop-i386.iso /cdrom
Запускаем программу из "Система" - "Администрирование" - "Установить Live USB".
Для создания установочного USB диска с OpenSUSE выполняем.
Устанавливаем syslinux:
zypper install syslinux
Монтируем установочный ISO образ в директорию /mnt
mount -o loop ./openSUSE-11.0-DVD-i386.iso /mnt/cdrom
Вставляем usb flash и находим устройство к которому она подключена, анализируя вывод команд:
fdisk -l
cat /proc/partitions
mount
dmesg
После того как определили искомый /dev/sdb, монтируем Flash:
mount /dev/sdb /mnt/flash
Копируем на Flash содержимое установочного диска, отдельно перенеся загрузчик в корень:
cp /mnt/cdrom/boot/i386/loader/* /mnt/flash
и переименовав файл конфигурации:
mv /mnt/flash/isolinux.cfg /mnt/flash/syslinux.cfg
Отмонтируем flash и устанавливаем загрузчик:
umount /mnt/flash
syslinux /dev/sdb
В графическом интерфейсе synaptic есть возможность сгенерировать скрипт для загрузки выбранных пакетов
с их последующей установкой: "генерировать скрипт закачки пакетов" и "добавить закаченные пакеты".
Там где synaptic недоступен, можно поступить иначе:
При указании опции --print-uris в apt-get, вместо установки будет выведен список адресов
для загрузки выбранных пакетов с учетом зависимостей.
apt-get -y --print-uris install список_пакетов
посмотреть какие пакеты нужно загрузить для обновления:
apt-get -y --print-uris upgrade
apt-get -y --print-uris dist-upgrade
посмотреть какие индексы нужно загрузить:
apt-get --print-uris update
Эти пакеты можно загрузить отдельно и скопировать в /var/cache/apt/archives, например:
apt-get -qq -y --print-uris upgrade | cut -f1 -d' ' | tr -d "'" > packet_list.txt
cd /var/cache/apt/archives
wget --input-file packet_list.txt
затем повторить команду "apt-get install список_пакетов", пакеты будут установлены из кэша
Вместо /var/cache/apt/archives можно указать и другую директорию:
apt-get -o dir::cache::archives="/download" install список_пакетов
Для обновления дистрибутива ubuntu до новейшего необходимо выполнить:
$ sudo update-manager -d
Если сообщения о новом дистрибутиве почему-то нет, но оно должно быть, необходимо настроить "Сервис прокси".
Пример:
$ http_proxy='http://proxy.test.ru:3128/' sudo update-manager -d
Апдейт менеджер можно заменить на do-release-upgrade
Работа apt-get и некоторых других консольных приложений через прокси осуществляется аналогичным образом:
export http_proxy=http://username:password@host:port/
export ftp_proxy=http://username:password@host:port/
Еще один способ конфигурирования работы apt через прокси:
Создаем /etc/apt/apt.conf.d/01proxy:
Acquire {
http::Proxy "http://username:password@host:port/";
}
Перекомпиляция пакета может понадобиться например, для упаковки более новой версии программы,
наложения определенного патча или пересборки с особенными опциями.
Устанавливаем программы, необходимые для сборки пакетов:
apt-get install devscripts
apt-get install build-essential
В /etc/apt/sources.list раскомментируем строки с deb-src для нужного репозитория, например:
deb-src http://ftp.us.debian.org/debian/ etch main non-free contrib
Загружаем пакет с исходными текстами в текущую директорию:
apt-get source имя_пакета
Если под рукой уже есть .dsc, tar.gz и diff.gz файлы, раскрываем их командой:
dpkg-source -x имя_пакета.dsc
Устанавливаем зависимые пакеты (библиотеки, заголовочные файлы и т.д.), требуемые для сборки:
apt-get build-dep имя_пакета
Вносим изменения в появившейся директории "имя_пакета-версия".
Если собрались импортировать в пакет более новую версию программы, то воспользуемся утилитой uupdate:
uupdate -u путь_к_tar_gz_архиву_c_более_новой_версией_программы
При этом в автоматическом режиме будут адаптированы патчи от старой версии,
в случае несостыковок придется исправлять патчи руками.
Собираем пакет:
cd имя_пакета-версия
debuild -us -uc
"-us" и "-uc" указываем так как не являемся мантейнером пакета и не можем создать цифровую подпись для пакета.
Вместо враппера debuild можем напрямую использовать:
dpkg-buildpackage -rfakeroot
После сборки готовый пакет появится в родительской директории, устанавливаем его:
cd ..
dpkg -i <package_file.deb>
Пример для пакета с MySQL:
mkdir build
cd build
apt-get source mysql-server-5.0
apt-get build-dep mysql-server-5.0
cd mysql-dfsg-5.0-5.0.32
debuild -us -uc
cd ..
dpkg -i *.deb
Для того чтобы заставить apt обновить систему используя только пакеты из кэша /var/cache/apt/archives,
а не лезть за ними в интернет, нужно выполнить:
apt-get -no-download -ignore-missing upgrade
Если пакета нет в кэше, он не будет поставлен.
Постоянное обновление системы - одно из важнейших мероприятий по обеспечению безопасности.
Можно следить за обновлениями посредством GLSA, для этого не обходимо
чтобы в системе был установлен пакет app-portage/gentoolkit.
в составе пакета идет утилита glsa-check, с которой нам и предстоит работать.
Итак преступим.
Сначала можно посмотреть все доступные выпуски GLSA
# glsa-check -l
Все строки, содержащие [A] и [U], можно проигнорировать, т.к. они неприменимы для данной системы.
Теперь проверим подвержена ли наша система GLSA
# glsa-check -t all
Или можно просмотреть пакеты которые необходимо переустановить
# glsa-check -p $(glsa-check -t all)
И применить их...
# glsa-check -f $(glsa-check -t all)
И конечно перезапускаем те демоны, которые подверглись переустановке.
Устанавливаем пакет apt-build:
apt-get install apt-build
Настраиваем его командой dpkg-reconfigure apt-build, тут нам надо будет ответить
на вопросы об уровне оптимизации и об архитектуре вашего процессора.
Далее надо убедится, что у нас раскоментированы репозитарии исходников в /etc/apt/sources.list
(эти строки начинаются с deb-src). Обновляем список репозитариев apt-get update.
Ну и всё, дальше вместо apt-get используем apt-build. Ключи и опции apt-build такие же как и у apt-get:
apt-build update - обновление списка репозитариев и софта в них,
apt-build upgrade - апгрейд установленных пакетов,
apt-build install - устанавливаем программу,
apt-build world - а это перекомпилит всю вашу систему! Тут всё на ваш страх и риск!
При первом запуске apt-build вы увидите следующее сообщение об ошибке:
-----Rebuilding the world!-----
-----Building package list-----
Please read README.Debian first.
Просто apt-build не знает какой софт у вас установлен.
Для того чтобы побороть эту ошибку достаточно ввести команду:
dpkg --get-selections | awk '{if ($2 == "install") print $1}'> /etc/apt/apt-build.list
Ну а дальше работаем с apt-build как с apt-get.
Рекомендую вставлять ключи --yes and --force-yes для того чтобы весь процесс проходил на автомате.
Список полезных шаблонов, которые можно использовать в aptitude search
~nимя - в имени встречается текст "имя" (можно использовать
регулярные выражения, например, ~n^lib отбирает только имена начинающиеся с lib)
~dтекст - в описании пакета встречается "текст" (очень полезно, если название программы
неизвестно, но известно, что она должна делать)
~i - отбирает только уже установленные пакеты
~N - отбирает только новые пакеты (которых раньше не было в репозитории)
~U - отбирает пакеты, которые можно обновить
~Dтребование - отбирает пакеты, которые зависят от "требования"
(можно использовать регулярные выражения)
~Rзависимый - отбирает пакеты, которые необходимы для "зависимого"
(можно использовать регулярные выражения)
| - логическое "ИЛИ"
! - логическое отрицание
Например:
Найти пакеты в имени которого встречается kde:
aptitude search ~nkde
Найти пакеты в описании к которым встречается HDR и image:
aptitude search ~dHDR~dimage
Найти пакеты в названии которых встречается aptitude. но в системе они не установлены:
aptitude search '!~i~naptitude'
Найти установленные пакеты в названии которых встречается firefox или iceweasel:
aptitude search '~i(~nfirefox|~niceweasel)'
Задача добавить модуль ядра usb-storage в "initrd.img" от Fedora Linux
для загрузки с диска с USB интерфейсом.
mkdir ./initrd
mv ./initrd.img ./initrd.img.gz
gunzip ./initrd.img
Метод 1. initrd.img в виде сжатого образа файловой системы
mount -o loop ./initrd.img ./initrd
Метод 2. initrd.img в виде сжатого cpio архива
cd ./initrd
cpio -ic < ../initrd.img
Копируем в ./initrd/lib модуль usb-storage.ko
(следим, чтобы уже были модули scsi_mod.ko, (o|e|u)hci-hcd.ko, usbcore.ko)
Прописываем "insmod /lib/usb-storage.ko" в конец списка загрузки модулей ./initrd/init
Может потребоваться скопировать команду sleep и прописать после
загрузки модуля usb-storage задержку, необходимую на обнаружения накопителя.
umount ./initrd # для метода 1.
cd ./initrd
find . -print| cpio -oc |gzip -9 -c > ../initrd_new.img # для метода 2.
Другой вариант упаковки (для Fedora 8):
find . -print| cpio -H newc -o |gzip -9 -c > ../initrd_new.img
При загрузке с USB диска большого объема (250Гб) при установке ОС в
разделе в центре диска не удалось использовать Lilo и Grub. Lilo при
загрузке ругался на несоответствие текущей геометрии диска той что
была в момент его установки. Установка Grub привела к зависанию
ноутбука в момент опроса USB диска (проблема BIOS). Выход нашелся в
установке загрузчика от FreeBSD:
1. Делаем бэкап текущего MBR USB диска:
dd if=/dev/sda of=mbr_sda.bin bs=1 count=512
2. Берем boot0 из комплекта FreeBSD и копируем в него данные о таблицах разделов текущего диска:
dd if=mbr_sda.bin of=boot0 bs=1 count=66 skip=446 seek=446
3. Копируем загрузчик в MBR USB диска:
dd if=boot0 of=/dev/sda bs=1 count=512
4. В текущий раздел Linux устанавливаем Grub:
# grub
grub> find /boot/grub/stage1
(hd0,1) раздел /dev/sda2
grub> root (hd0,1)
grub> setup (hd0,1)
После обновления до Etch в APT появилось много изменений. Одно из них - защита от подмены доменной записи.
# apt-get update
W: GPG error: http://deb.opera.com stable Release:
The following signatures couldn't be verified because the public key is not available:
+NO_PUBKEY 033431536A423791
W: You may want to run apt-get update to correct these problems
Для решения проблемы с "apt-get update" предлагается запустить "apt-get update". Не будем зацикливаться.
Получим публичный ключ и сохраним его в пользовательской базе:
$ sudo gpg --keyserver subkeys.pgp.net --recv-keys 033431536A423791
gpg: requesting key 6A423791 from hkp server subkeys.pgp.net
gpg: key 6A423791: public key "Opera Software Archive Automatic Signing Key <hostmaster@opera.com>" imported
gpg: no ultimately trusted keys found gpg: Total number processed: 1
gpg: imported: 1
Теперь отдадим нашему apt ключ:
$ gpg --armor --export 033431536A423791 | sudo apt-key add -
OK
Что-то произошло.
$ ls -l /etc/apt
total 40
-rw-r--r-- 1 root root 2524 Nov 14 2006 apt-file.conf
drwxr-xr-x 2 root root 112 May 27 02:54 apt.conf.d
-rw-r--r-- 1 root root 98 May 27 02:54 listchanges.conf
-rw------- 1 root root 0 May 25 10:08 secring.gpg
-rw-r--r-- 1 root root 1059 May 25 02:15 sources.list
-rw-r--r-- 1 root root 812 May 24 00:19 sources.list-sarge
drwxr-xr-x 2 root root 48 Feb 27 00:21 sources.list.d
-rw-r--r-- 1 root root 632 Nov 12 2005 sources.list~
-rw------- 1 root root 1200 May 30 10:26 trustdb.gpg
-rw-r--r-- 1 root root 4473 May 30 10:26 trusted.gpg
-rw-r--r-- 1 root root 4473 May 30 10:26 trusted.gpg~
Сегодня - May 30. Не знаю, что там в trust*, но это нравится нашему apt:
$ sudo apt-get update
Ign file: stable Release.gpg Ign file: stable Release.gpg
Ign file: stable Release.gpg Get:1 file: stable Release [802B]
Get:2 file: stable Release [627B] Get:3 file: stable Release [627B]
Ign file: stable/main Packages
Ign file: stable/main Packages
Ign file: stable/main Packages
Get:4 http://deb.opera.com stable Release.gpg [189B] Hit http://deb.opera.com stable Release
Ign http://deb.opera.com stable/non-free Packages/DiffIndex
Ign http://deb.opera.com stable/non-free Packages
Hit http://deb.opera.com stable/non-free Packages Fetched 189B in 0s (227B/s)
Reading package lists... Done
На всякий случай, посмотрим, что еще изменилось за сегодня в системе:
$ locate gpg > 1
# updatedb && locate gpg > 2 && diff 1 2
56a60,65
> /home/hec/.gnupg/pubring.gpg
> /home/hec/.gnupg/pubring.gpg~
> /home/hec/.gnupg/secring.gpg
> /home/hec/.gnupg/trustdb.gpg
> /home/hec/.local/share/applications/menu-xdg/X-Debian-Apps-Tools-kgpg.desktop
390c404
< /var/lib/apt/lists/partial/deb.opera.com_opera_dists_stable_Release.gpg
---
> /var/lib/apt/lists/deb.opera.com_opera_dists_stable_Release.gpg
Создались и изменились файлы в ~/.gnupg и deb.opera.
com_opera_dists_stable_Release.gpg перешел из /var/lib/apt/lists/partial/ в /var/lib/apt/lists/
Ссылки по теме:
http://strugglers.net/wiki/The_following_signatures_couldn't_be_verified
http://www.osp.ru/lan/1997/07/132968/ - Атака и защита DNS
Установка одного пакета:
dpkg -i <.deb file name>
Пример: dpkg -i avg71flm_r28-1_i386.deb
Рекурсивная установка группы пакетов помещенных в директорию:
dpkg -R
Пример: dpkg -R /usr/local/src
Распаковать пакет, но не переходить на стадию конфигурации:
dpkg --unpack package_file
Пример: dpkg --unpack avg71flm_r28-1_i386.deb
Выполнить стадию конфигурирования для ранее распакованного пакета:
dpkg --configure package
Пример: dpkg --configure avg71flm_r28-1_i386.deb
Удаление ранее установленного пакета, с сохранением файлов конфигурации:
dpkg -r
Пример: dpkg -r avg71flm_r28-1_i386.deb
Удаление ранее установленного пакета, с удалением файлов конфигурации:
dpkg -P
Пример: dpkg -P avg71flm
Обновление информации о доступных для установки пакетах из файла "Packages.dpkg"
dpkg --update-avail <Packages-file>
Добавление (комбинирование) информации о дополнительных пакетах из файла "Packages.dpkg"
dpkg --merge-avail <Packages-file>
Обновление информации о пакете непосредственно из пакета:
dpkg -A package_file
Удалить информацию о ранее установленных, но удаленных, и теперь недоступных, пакетах:
dpkg --forget-old-unavail
Удалить информацию о доступности пакетов:
dpkg --clear-avail
Найти частично установленные пакеты:
dpkg -C
Отобразить различия в двух наборах пакетов:
dpkg --compare-versions ver1 op ver2
Построить deb пакет:
dpkg -b directory [filename]
Показать содержимое пакета:
dpkg -c filename
Показать информацию о пакете:
dpkg -I filename [control-file]
Показать список пакетов удовлетворяющих маске:
dpkg -l package-name-pattern
Пример: dpkg -l vim
Показать список всех установленных пакетов:
dpkg -l
dpkg --get-selections
Отобразить состояние пакета
dpkg -s package-name
Пример: dpkg -s ssh
Показать список файлов в системе, добавленных из указанного пакета.
dpkg -L package-Name
Пример: dpkg -L apache2
Поиск пакета по входящему в его состав файлу:
dpkg -S filename-search-pattern
Пример: dpkg -S /sbin/ifconfig
Вывод детальной информации о пакете:
dpkg -p package-name
Пример: dpkg -p cacti
Установка CentOS 4.4 (RHEL AS 4.4) и FC 6 на материнские платы с чипсетом Intel P965 & Intel ICH8R с IDE-CDROM'a.
1.Установить в BIOS режим AHCI для Intel ICH8R и Jmicron JMB363
2.На подсказке
boot:linux all-generic-ide pci=nommconf
3. Cпецифицировать во время графической установки
Kernel boot options :
all-generic-ide pci=nommconf
При установке GRUB в /boot partition выполнить:
boot:linux all-generic-ide pci=nommconf rescue
...................
# chroot /mnt/sysimage
# df -h
/dev/sdaX ....... /boot
.............................
# dd if=/dev/sdaX of=linux.bin bs=512 count=1
# mcopy linux.bin a:
Такой стиль установки позволяет системам успешно определять
IDE-CDROM не только при установке , но и в рабочем режиме.
Инсталлятор Debian можно заставить использовать файл ответов на вопросы установки (pre-seeding).
Установите пакет debconf-utils
apt-get install debconf-utils
Создайте pre-seeding файл для повторения начальной установки:
debconf-get-selections --installer > preseed.cfg
Добавьте последующие изменения:
debconf-get-selections >> preseed.cfg
При необходимости отредактируйте preseed.cfg на свой вкус и скопируйте на дискету.
В момент загрузки передайте в качестве параметра путь к preseed.cfg файлу (как опции загрузки ядра):
preseed/file=/floppy/preseed.cfg debconf/priority=critical
Что касается Fedora, то создать файл автоустановки можно использовав пакет system-config-kickstart:
yum -y install system-config-kickstart
/usr/sbin/system-config-kickstart
После запуска в диалоговом режиме будет сформировано содержание файла ks.cfg,
информацию о котором нужно передать как параметр при загрузке:
linux ks=/floppy/ks.cfg
Копируем обновления на локальную машину
http://download.fedora.redhat.com/pub/fedora/linux/core/updates/5/i386/
Создаем директорию, в которой будем создавать новый образ диска.
mkdir -p /opt/FC_2006.4/i386
cd /opt/FC_2006.4
Монтируем оригинальный установочный диск
mount -o loop /full/path/FC-5-i386-DVD.iso /mnt
и синхронизируем его содержимое, за исключением rpm пакетов, в созданную ранее директорию.
rsync --archive --exclude 'Fedora/RPMS/*.rpm' /mnt/ i386
Копируем только актуальные rpm пакеты для которых не было обновлений.
Наличие обновлений отслеживаем при помощи утилиры novi.
for fn in `novi path/to/updates /mnt/Fedora/RPMS/ | awk '{print $2}'`; do
cp $fn i386/Fedora/RPMS/
done
Обновляем индексные файлы
cd i386
createrepo -u "media://1142397575.182477#1" -g Fedora/base/comps.xml .
cd ..
Создаем ISO образ и md5 слепок.
mkisofs -R -J -T -v -no-emul-boot -boot-load-size 4 -boot-info-table \
-V "Fedora Core 5 (Patched.0406)" -b isolinux/isolinux.bin \
-c isolinux/boot.cat -x "lost+found" -o FC5-i386-dvd-patched.iso i386
/usr/lib/anaconda-runtime/implantisomd5 FC5-i386-dvd-patched.iso
DHCP.
dhcpd.conf:
# расскоментировать для DHCPD 3.0
# ddns-update-style none;
group {
# IP address of TFTP/NFS server
next-server 10.0.0.3;
# The name of the file to be downloaded by the ROM
filename "/tftpboot/pxelinux.0";
# A default server directory to be used as / by the clients
#option root-path "/clients/shared/root";
# IP addresses of DNS servers
#option domain-name-servers XX.XX.XX.XX, YY.YY.YY.YY;
# IP addresses of routers
#option routers AA.AA.AA.AA, BB.BB.BB.BB;
# An entry for one specific client
host sample-client {
# Ethernet address of the client machine
hardware ethernet EE:EE:EE:EE:EE:EE;
# IP address to assign
fixed-address 10.0.1.1;
# Override root-path option for this machine
# Our initial configuration will use separate
# root directories for each client.
option root-path "/clients/10.0.1.1/root";
}
}
NFS.
/etc/exports на сервере:
/clients/10.0.1.1/root 10.0.1.1/255.255.255.255(rw,no_root_squash)
/clients/10.0.1.1/usr 10.0.1.1/255.255.255.255(rw,no_root_squash)
/clients/10.0.1.1/var 10.0.1.1/255.255.255.255(rw,no_root_squash)
/clients/10.0.1.1/tmp 10.0.1.1/255.255.255.255(rw,no_root_squash)
/home 10.0.0.0/255.0.0.0(rw)
/etc/fstab для клиента:
10.0.0.3:/clients/10.0.1.1/root / nfs rw,hard,intr,nolock 0 0
10.0.0.3:/clients/10.0.1.1/usr /usr nfs rw,hard,intr,nolock 0 0
10.0.0.3:/clients/10.0.1.1/var /var nfs rw,hard,intr,nolock 0 0
10.0.0.3:/clients/10.0.1.1/tmp /tmp nfs rw,hard,intr,nolock 0 0
10.0.0.3:/home /home nfs rw,hard,intr,nolock 0 0
Проверка NFS:
mount 127.0.0.1:/clients/10.0.1.1/root /mnt
/clients/shared/root/etc/init.d/netboot-dirs - скрпит монтирование разделов по NFS загрузке для клиента:
#!/bin/sh
IP=`ifconfig eth0 | grep inet | sed 's/.*inet //;s/ netmask.*//'`
/bin/mount 10.0.0.3:/clients/$IP/var /var
/bin/mount 10.0.0.3:/clients/$IP/tmp /tmp
etc/init.d/netboot-dirs создание /var и /tmp разделов в ОЗУ для клиента:
#!/bin/sh
# File: etc/init.d/netboot-dirs
# Initialize a 1MB /var
/sbin/mke2fs -q /dev/ram12 1024
/bin/mount /dev/ram12 /var
/bin/chown 0:0 /var
/bin/chmod 755 /var
# Create some needed dirs
cd /var
/bin/mkdir -p --mode=755 run lib log/news spool/cron/crontabs
/bin/mkdir -p --mode=1777 tmp lock
# Initialize a 4MB /tmp
# -N option tunes this for small files
/sbin/mke2fs -q -N 2048 /dev/ram11 4096
/bin/mount /dev/ram11 /tmp
/bin/chown 0:0 /tmp
/bin/chmod 1777 /tmp
Для инсталляци Domino R6.5 необходимо в файле .bashrc, который находиться в директории юзера "notes" сделать такую запись:
export LD_ASSUME_KERNEL = 2.2.5
initrd - RAM-диск, инициализируемый загрузчиком, требуется для подключения модулей ядра, необходимых
на этапе до монтирования root-раздела, (например, до монтирования нужно подгрузить - ext2/ext3/scsi модули).
1) man initrd - все изумительно описано;
2) после сборки ядра создаем новый initrd:
mkinitrd /boot/initrd-2.4.21 2.4.21;
3) в /etc/lilo.conf:
initrd=/boot/initrd-2.4.21
В mkinitrd сам initrd можно назвать как угодно, но второй параметр обязательно версия ядра.
Перезапуск сервисов:
service имя start
service имя stop
service имя restart
Добавление или удаление сервисов (удобнее использовать утилиту ntsysv, sysvconfig или rcconf):
chkconfig --list
chkconfig --add имя
chkconfig --del имя
chkconfig [--level уровень] имя <on|off|reset>
Установка пакетов: rpm -i <пакеты>
Деинсталляция пакета: rpm -e <пакеты>
Обновление или установка пакетов: rpm -U <пакеты>
Только обновление пакетов если они ранее установлены: rpm -F <пакеты>
Полезно: --force -установить несмотря ни на что, --nodeps - без проверки зависимости, -vh - приятный вывод, --test - проверка.
Информация о пакете: rpm -q <пакет>
Список всех пакетов в системе: rpm -q -a
Узнать какому пакету принадлежит файл: rpm -q -f <файл>
Полезно: -i - более полное описание пакета, -R - список зависимостей пакета, -l - список файлов в пакете,
-c - список конфигов в пакете, -d - список документации.
Установка из исходников: rpm --recompile <srpm> , собрать бинарный пакет: rpm --rebuild <srpm>.
Перестроить базу: rpm --rebuilddb
Думаю, практически все понимают преимущества пакетных менеджеров над установкой при помощи
./configure && make && make install.
На примере недавно появившегося патча для Pidgin я хочу показать,
как легко пересобирать пакеты в deb-based дистрибутивах.
Подготовка.
Нам понадобятся следующие пакты: devscripts build-essential fakeroot
sudo apt-get install devscripts build-essential fakeroot
Скачиваем исходники.
Для этого должны быть подключены соответствующие репозитории.
Нам нужен libpurple0, т.к. патч относится к этой библиотеке.
На самом же деле libpurple, pidgin и pidgin-data имеют общий исходник, там что мы можем написать как
apt-get source libpurple0
так и
apt-get source pidgin
Обратите внимание, что apt-get source надо делать не из под sudo.
Исходники скачиваются в текущую директорию.
Патчим.
wget http://launchpadlibrarian.net/15741199/pidgin-2.4.2-icq.patch
cd pidgin-2.4.1
patch -p0 < ../pidgin-2.4.2-icq.patch
Устанавливаем зависимости, необходимые для сборки:
sudo apt-get build-dep libpurple0
Пересобираем пакет (из той же директории)
debuild -us -uc
Получившийся пакет устанавливаем:
cd ..
sudo dpkg -i libpurple0_2.4.1-1ubuntu2_amd64.deb
Если у вас i386-дистрибутив, то пакет будет называться libpurple0_2.4.1-1ubuntu2_i386.deb.
1. Скачать ati-driver-installer-8-5-x86.x86_64.run
2. В консоли выполнить для синхронизации списка пакетов, доступных в репозиториях:
sudo apt-get update
Затем, установить пакеты, необходимые для сборки модуля ядра из исходных текстов и создания deb пакета:
sudo apt-get install build-essential fakeroot dh-make debhelper debconf libstdc++5 dkms linux-headers-$(uname -r)
3. В консоли запускаем инсталлятор драйвера в режиме создания пакетов:
sudo sh ati-driver-installer-8-5-x86.x86_64.run --buildpkg Ubuntu/8.04
4. Теперь нужно занести в черный список драйвер fglrx из репозитория Ubuntu, выполняем
sudo gedit /etc/default/linux-restricted-modules-common
и в строке "DISABLED_MODULES" добавляем "fglrx"
получаем строку:
DISABLED_MODULES="fglrx"
сохраняем файл
5. далее в консоли устанавливаем подготовленные пакеты с драйвером:
sudo dpkg -i xorg-driver-fglrx_8.493*.deb fglrx-kernel-source_8.493*.deb fglrx-amdcccle_8.493*.deb
6. Перезагружаем X сервер.
7. проверяем:
$ fglrxinfo
display: :0.0 screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: Radeon X1900 Series
OpenGL version string: 2.1.7537 Release
PS: все вышесказанное проверялось на i386 конфигурации с видеокартой X1900,
для amd64 возможны небольшие отличая в установке.
Оригинал: http://pronix.isgreat.org/news.php?item.86.5
Автор: Алексей Гнедин
Редактор: Олег Сафулин
Используемое ПО: pptp-1.6.0.tgz , OpenBSD 3.8 (GENERIC)
Особенности данного подключения состоят в том ,что VPN сервер разрешает подключатся
только с авторизацией MSChapV2, и явно включённым шифрованием MPPE 128 STATELESS.
cd /etc/ppp
vi /etc/ppp/ppp.conf
Добавляем следующие строки:
default:
set log Phase Chat LCP IPCP CCP tun command
pptp1:
set device "!/usr/local/sbin/pptp IPADDR_VPN_SERVER --nolaunchpppd"
set log Phase LCP IPCP CCP tun command
disable acfcomp protocomp
deny acfcomp
enable lqr
set lqrperiod 5
set cd 5
set redial 30
set timeout 0
set authname <username>
set authkey <userpass>
set dial
set login
add! default HISADDR
enable mssfixup
disable ipv6cp
accept MSChapV2
set mppe 128 stateless
Далее:
touch /etc/hosname.tun0 ; vi /etc/hostname.tun0
Добавляем следующие строки:
!/usr/sbin/ppp -ddial pptp1 >/dev/null 2>&1
sysctl -w net.inet.gre.allow=1
reboot
После загрузки машина автоматически соединится с VPN сервером.
Подключение русской раскладки:
echo ru > /etc/kbdtype
После чего добавляем в /etc/rc.local такое:
wsfontload /usr/share/misc/pcvtfonts/koi8-r-8x16
for cons in `jot 6 1 6`; do wsconscfg -dF $cons; wsconscfg -t 80x25bf $cons; done
unset cons
wsconsctl -w keyboard.map+="keycode 157=Mode_Lock"
Вместо koi8-r-8x16 можно указать koi8-u-8x16.
В качестве переключателя раскладки используется правый CTRL
Замечание: Экран ttyC0 создаётся всегда и не может быть удалён, поэтому не может отображать кириллицу.
Нередко из-за отсутствия обработчика сигнала SIGCHLD в родительском процессе,
после завершения дочерней программы, остаются "<defunct>" или zombie процессы.
Zombie процессы не занимают системные ресурсы, кроме записи в таблице процессов,
что может вызвать ее переполнение и как следствие блокировку запуска новых процессов,
при большой интенсивности появления zombie. Zombie исчезают после завершения работы
родительского процесса, но записи в таблице также можно очистить принудительным путем.
Получаем список zombie процессов:
ps -ecl |grep "Z"
F S UID PID PPID CLS PRI ADDR SZ WCHAN TTY TIME CMD
0 Z 100 27841 27840 - 0 - 0 - ? 0:00 <defunct>
"kill" и "kill -9" в случае zombie использовать бесполезно. В Solaris для эмуляции вызова wait()
для чтения кода возврата из таблицы процессов существует утилита preap:
preap 27841
27841: exited with status 0
Чтобы добавить нестандартный путь к библиотекам (например /usr/local/ssl/lib/) в линкер в Solaris вместо отсутствующей в этой ОС команды ldconfig нужно использовать команду crle:
crle -u -l /usr/local/ssl/lib
Если при установке пакета на Solaris 8 через pkgadd -d package он ругается что такой пакет уже установлен -
Current administration requires that a unique instance of the <pkg>
package be created. However, the maximum number of instances of the
package that may be supported at one time on the same system has already been met.
No changes were made to the system.
нужно отредактировать /var/sadm/install/admin/default
instance=unique
заменить на
instance=overwrite
На официальном сайте Oracle присутствует небольшое руководство по установке в Solaris
без использования графического интерфейса, при этом оно сводится к тому,
что нужно запустить скрипт под графическим интерфейсом с дополнительными параметрами.
/directory_path/runInstaller -record -destinationFile response_filename
В итоге получаем файл, который может быть использован при установке,
но установка графического интерфейса была не приемлема,
поэтому пришлось разбираться самому с файлом ответов.
Для установки нужно скачать клиента с оф. сайта Oracle.
скачать можно по адресу:
http://download-llnw.oracle.com/otn/solaris/oracle10g/10201/sol64/10gr2_client_sol.cpio.gz
создайте пользователя и группу для клиента
например:
useradd oracle
groupadd oracle
usermod -g oracle oracle
passwd oracle
Создайте папку распакуйте полученный архив в эту папку и дайте команду
chown -R oracle:oracle /directory_path/
Теперь нужно править или создать свой фаил ответов
версию можем не трогать
RESPONSEFILE_VERSION=2.2.1.0.0
имя группы которую создали для оракла
UNIX_GROUP_NAME="oracle"
если вы брали стандартый дистрибутив с сайта менять не надо
FROM_LOCATION="../stage/products.xml"
имя и путь к следующему фаилу ответов
NEXT_SESSION_RESPONSE=""
Куда устанавливаем
ORACLE_HOME="/export/home/oracle/client"
ORACLE_HOME_NAME="OraClient"
эти значения нужно оставить по молчанию. Беруться из примеров файлов ответов в дистрибутиве
TOPLEVEL_COMPONENT={"oracle.client","10.2.0.1.0"}
DEINSTALL_LIST={"oracle.client","10.2.0.1.0"}
т.к. у нас тихая инсталяция а эти параметры требуют графический интерфейс скидываем их все в false
SHOW_SPLASH_SCREEN=false
SHOW_WELCOME_PAGE=false
SHOW_CUSTOM_TREE_PAGE=false
SHOW_SUMMARY_PAGE=false
SHOW_INSTALL_PROGRESS_PAGE=false
SHOW_CONFIG_TOOL_PAGE=false
SHOW_XML_PREREQ_PAGE=false
SHOW_ROOTSH_CONFIRMATION=true
SHOW_END_SESSION_PAGE=false
SHOW_EXIT_CONFIRMATION=false
SHOW_DEINSTALL_CONFIRMATION=false
SHOW_DEINSTALL_PROGRESS=false
следующая сессия нам не нужна поэтому скидываем параметры в false
NEXT_SESSION=false
NEXT_SESSION_ON_FAIL=false
CLUSTER_NODES={}
какую папку удалить после установки
REMOVE_HOMES=""
выбор поддержки языка
COMPONENT_LANGUAGES={"en"}
тип исталяции
INSTALL_TYPE="Administrator"
если используется тип инсталяции Custom нужно добавить еще один параметр,
где перечисляются нужные компоненты
DEPENDENCY_LIST={"oracle.sqlj:10.2.0.1.0","oracle.rdbms.util:10.2.0.1.0",
"oracle.javavm.client:10.2.0.1.0","oracle.sqlplus:10.2.0.1.0",
"oracle.dbjava.jdbc:10.2.0.1.0","oracle.ldap.client:10.2.0.1.0",
"oracle.rdbms.oci:10.2.0.1.0","oracle.precomp:10.2.0.1.0","oracle.xdk:10.2.0.1.0",
"oracle.swd.opatch:10.2.0.1.0","oracle.network.aso:10.2.0.1.0","oracle.oem.client:10.2.0.1.0",
"oracle.oraolap.mgmt:10.2.0.1.0","oracle.network.client:10.2.0.1.0","oracle.ordim.client:10.2.0.1.0",
"oracle.ons:10.1.0.3.0","oracle.has.client:10.2.0.1.0"}
после того как готов файл, залогиниваемся под пользователем клиента и запускаем команду
/directory_path/runInstaller -silent -responseFile responsefilename
снова перелогиниваемся под рутом и запускаем скрипт root.sh, который лежит в папке с установленным клиентом
Установка прошла успешно
А дальше пользуемся готовыми статьями по настройке подключений.
P.S. возможны проблемы, когда некоторые фалы копируются битыми, просто перезапустите скрипт утановки.
Solaris 10 - наиболее стабильный на данный момент выпуск Solaris, предназначенный для промышленного использования в продуктивных окружениях. Свободно доступен для скачивания на сайте Sun Microsystems. Для него осуществляется всесторонняя поддержка, выпускаются патчи исправляющие ошибки и проблемы безопасности. С момента выхода первой версии Solaris 10 вышло несколько обновлений, содержащих новую функциональность и исправления ошибок, список которых и краткое описание изменений можно найти здесь. Эти обновления выходят в среднем раз в полгода и именуются по номерам а также по дате их выпуска (к примеру на текущий момент последним является обновление 4 - оно-же 08/07).
Solaris Express Community Edition (SXCE) - также называемый Nevada, это дистрибутив основанный на последних разработках, который в будущем превратится в Solaris 11. Новые версии выходят достаточно часто и именуются по номеру сборки (на данный момент последняя - 81). Основная цель Solaris Nevada - разработка и тестирование новой функциональности. Свободно доступен для скачивания на сайте opensolaris.org
Solaris Express Developer Edition (SXDE) - бинарный дистрибутив основанный на SXCE, прошедший этап тестирования и обеспеченный поддержкой. Предназначен в первую очередь для разработчиков. Релизы происходят значительно реже SXCE и именуются по дате выхода - последний на данный момент - 1/08. Свободно доступен для скачивания на сайте Sun Microsystems.
Open Solaris - не является полноценным дистрибутивом, а представляет из себя открытое ядро ОС и набор базовых утилит. Не содержит многих компонентов системы, необходимых для работы, и инсталлятора, поэтому может быть установлен только поверх SXCE/SXDE (которые сами построены на основе OpenSolaris). Достаточно часто появляются бинарные сборки. Доступен для свободного скачивания на opensolaris.org и сайте Sun Microsystems. Стоит отметить что постоянно идет процесс портирования новых возможностей из Open Solaris в Solaris 10.
Solaris Indiana - дистрибутив основанный на OpenSolaris и направленный на использование в качестве десктопа. На данный момент последняя версия - Developer Preview 2, выполненная в виде LiveCD. Доступен для свободного скачивания на opensolaris.org. Возможно в будущем Indiana заменит Developer Edition.
Чтобы анализаторы логов прокси сервера squid отображали данные о пересылках в обход прокси,
например данные по почтовому или ssh трафику, можно сохранить данные о таких пересылках в логе squid.
Настройки ipcad:
capture-ports enable;
interface ppp* filter "ip and not dst net 192.168.0.0/16";
aggregate 0.0.0.0/0 strip 32; /* Считаем все адреса */
/* Теперь укажем какие порты как отображать */
aggregate 1-19 into 65535;
aggregate 20-21 into 21;
aggregate 22-23 into 22;
aggregate 25 into 25;
aggregate 24 into 65535;
aggregate 26-79 into 65535;
aggregate 80-81 into 0;
aggregate 82-109 into 65535;
aggregate 110 into 110;
aggregate 111-442 into 65535;
aggregate 443 into 443;
aggregate 444-3127 into 65535;
aggregate 3128 into 0;
aggregate 3129-65535 into 65535;
Сам файл обработки ipcad и записи в сквидовский лог:
#!/bin/sh
net="192.168"
ttime=`/usr/bin/rsh localhost sh ip acco|/bin/grep 'Accounting data saved'| /bin/awk '{print ($4)}'`
/usr/bin/rsh localhost clear ip accounting
/usr/bin/rsh localhost show ip accounting checkpoint|/bin/grep $net|/bin/awk -v vtime=$ttime '{print (vtime".000",1,$1,"TCP_MISS/200",$4,"CONNECT",$2":"$6,"-","DIRECT/"$2,"-")}' >>/var/log/squid/access.log
Вместо 192.168 Вы можете указать свою сеть, которую брать с ipcad'а и заносить в лог прокси сервера Squid.
Таким образом весь трафик, указанный в настройках ipcad'а будет отображен в access.log сквида,
который в данном примере находится в папке /var/log/squid.
Наверняка, каждый сталкивался с задачей переноса лог-файлов из текстовых файлов в различные БД.
И, наверняка, каждый столкнувшийся начинал писать собственные скрипты под это дело.
Причем большинство виденных мной скриптов основывались на построчном чтении/переносе данных.
Данный способ, конечно, хорош и имеет право на существование, но, к сожалению не очень быстр.
Но в MySQL существует способ перенести данные из обычных текстовых файлов в БД
очень и очень быстро при помощи директивы LOAD DATA INFILE
Пример такого скрипта:
#!/bin/bash
nld='/var/log/squid3' # Путь к лог-файлам
nbd='/opt/backup/squid3' # Путь к папке резервного хранения лог-файлов
nrc=`squid3 -k rotate` # Команда ротации лог-файлов для данного сервиса
nlf='/var/log/logs2mysql/squid.log' # На всякий случай пишем что и когда делали
mh='localhost' # Mysql host
mu='root' # Пользователь mysql
mp='secret' # Его пароль
mb='logs' # База данных
mt='squid' # Таблица
echo `date +"%F %T"` "Начало выгрузки" >> $nlf && \
$nrc && \
for i in `ls $nld | grep access.log.`;
do
year=`date +"%Y"`
month=`date +"%m"`
day=`date +"%d"`
prefix=`date +"%F-%H"`
test -d $nbd/$year/$month/$day || mkdir -p $nbd/$year/$month/$day && \
cat $nld/$i | sed -e 's/\"/\\\"/g' | sed -e "s/\'/\\\'/g" | \
awk ' {print strftime("%F",$1),strftime("%T",$1),$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11} ' | \
sed -e "s/ /\t/g" > $nld/prepare.log && \
chmod 0777 $nld/prepare.log && \
mysql -h $mh -u $mu -p$mp -e "LOAD DATA INFILE \"$nld/prepare.log\" REPLACE INTO TABLE $mb.$mt;" && \
cat $nld/$i >> $nbd/$year/$month/$day/$prefix.log && rm $nld/$i && rm $nld/prepare.log
done
echo `date +"%F %T"` "Конец выгрузки" >> $nlf
Поля для таблицы ('Поле'-тип)
'date'-date
'time'-time
'timestamp'-varchar(16)(разные сервисы пишут по разному.Кто-то с милисекундами, кто-то без)
'elapsed'-int(20)
'ip'-varchar(15)
'code'-varchar(20)
'size'-int(20)
'method'-varchar(10)
'url'-varchar(255)
'user'-varchar(255)
'direct'-varchar(25)
'mime'-varchar(25)
'hash'-varchar(255)unique
C небольшими изменениями данный скрипт можно приспособить для обработки
лог-файлов не только squid, но и других сервисов. Необходимое условие:
четкое разграничение полей (можно, поиграться с указанием разграничителей полей
в директиве LOAD DATA INFILE).
К преимуществам данного скрипта можно отнести огромное быстродействие
(п4-3,2 1024Мб ОЗУ 4млн. строк за 10-12 сек.).Также по последнему полю "hash" мы можем уникальным
образом идентифицировать строку (при анализе логов за год по squid и net-acct я не обнаружил
одинаковых строк).А также гарантированное попадание всех строк в БД
(т.к. данные не удаляются при сбое mysql).
В некоторые моменты чувствую себя очень неуютно из-за того, что нет возможности посмотреть, что конкретно делают с моим сервером некоторые персоны. Я долго искал возможность логгировать все, в том числе и POST запросы клиентов и нашел способ - через mod_security.
Устанавливается он элементарно apxs -cia mod_security.c (см документацию, правда, для его работы в наиболее удобном, "Concurrent", режиме логгирования, нужен модуль unique_id. После установи модуля следует добавить следующую секцию в httpd.conf:
<IfModule mod_security.c>
SecAuditEngine On
# У mod_security есть два механизма логгирования, Concurrent - более быстрый и продвинутый.
SecAuditLogType Concurrent
# Здесь будет храниться индекс - файл, по структуре похожий на access_log + идентификаторы,
# по которым можно найти полную информацию в StorageDir
SecAuditLog /var/log/www/audit/index
# Тут хранятся все данные запросов. Каждый запрос в отдельном файле.
# Запросы разнесены по каталогам (вместе все запросы одной транзакции, вместе все транзакции одного дня)
SecAuditLogStorageDir /var/log/www/audit/data/
# Наиболее полное логгирование (man)
SecAuditLogParts ABCDEFGHZ
# Добавить обработку POST данных.
SecFilterScanPOST On
SecFilterEngine On
# Следующие строки нужны для сохранения загруженных на сервер файлов:
SecUploadDir /var/log/www/audit/upload
SecUploadKeepFiles On
</IfModule>
Включать это имеет смысл при подозрении, что кто-то пытается использовать вашу систему не по назначению, теперь любой шаг проходимца будет записан.
p.s. Работоспособность конфига проверялась в apache 1.3.37, mod_security 1.9.4, но работать должно и в 2.0/2.0
Система управления версиями RCS пригодилась для сохранения резервных копий
файлов конфигурации и нескольких Perl модулей, активная разработка которых уже завершена,
но мелкие исправления и переделки еще бывают.
Итак, для работы с RCS используются следующие команды -
ci (импорт файлов в репозиторий),
co (экспорт),
rcs (манипулирование флагами файлов и проч.),
rcsdiff,
rlog.
Пусть file - файл, который требуется передать в управление RCS.
ls -la > file
Первым делом нужно создать каталог для репозитория
mkdir RCS
Затем импортировать файл. В общем случае это делается так:
ci file
Исходный файл _перемещается_ в репозиторий (если он там уже есть, то под новой версией).
Извлечь файл из репозитория можно командой:
co file
(файл будет иметь права доступа 444)
Чтобы изменить файл, нужно установить его блокировку и установить права доступа, разрешающие запись
rcs -l file
chmod o+w file
Чтобы записать изменения нужно снова выполнить
ci file
Итак, это все, что нужно для того чтобы начать работать.
Теперь пара команд, для того, чтобы работать было удобно :)
co -l file - синоним co file; rcs -l file; chmod 644 file - извлечь, заблокировать файл, разрешить запись.
ci -u file - синоним ci file; co file - сохранить файл и извлечь рабочую копию
ci -l file - синоним ci file; co -l file - сохранить файл, сделать co -l
В случае, если с файлом работает один пользователь, то в блокировках нет никакого смысла, и от них можно отказаться:
ci -l file (первоначальный импорт)
rcs -U file (установка перманентной блокировки)
vi file
ci -l file (файл сохранится в RCS и будет готов к дальнейшей работе)
Далее, самые распространненые задачи:
Извлечь файл из репозитория
co file
co -l file (синоним co file, rsc -l file -- извлечение и блокировка)
co -r1.2 file (извлечение определенной версии файла)
Посмотреть различия между текущей (=рабочей) версией и последней, сохраненной в RCS
rcsdiff file
Посмотреть различия между произвольными двумя версиями
rcsdiff -r1.1 -r1.2 file
Посмотреть логи редактирования файла
rlog file
Дальнейшее чтение: rcsintro(1), rcs(1), co(1), ci(1).
Linux:
- Перед правилом блокировки нужно вставить "log" правило:
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 \
-j LOG --log-level debug --log-prefix "outgoing mail"
iptables -A FORWARD -p tcp -m tcp -s 192.168.0.0/16 --dport 25 -j DROP
- Проверить запущены ли в системе klogd и syslogd.
- Настроить /etc/syslog.conf на прием kern.debug логов:
kern.=debug -/var/log/kernel/info
FreeBSD:
Добавить ключ log в ipfw, например:
ipfw add 1000 deny log tcp from any to 192.168.10.10 22 via fxp0
ipfw add 1000 deny log logamount 0 tcp from any to 192.168.10.10 80 via fxp0
Для ведения логов ядро должно быть собрано с IPFIREWALL_VERBOSE или нужно выставить "sysctl -w net.inet.ip.fw.verbose=1".
Далее проверить чтобы в /etc/syslog.conf было упоминание LOG_SECURITY:
security.* /var/log/security
Через параметр logamount передается число записей которые будет записано в лог,
после превышения записи перестанут появляться в логе, до тех пор пока не будет вызвана команда
"ipfw resetlog". Максимальное число сообщений можно также установить
через sysctl net.inet.ip.fw.verbose_limit.
Для отмены лимитирования на число записей, нужно установить атрибут в 0.
Часто недовольные пользователи приходят и просят дать им распечатку логов доступа в интернет.
Отчасти это позволяет сделать squid, но только при прозрачном проксировании, да и то логи только по http-протоколу.
На помощь приходит iptables и syslog.
Настраиваем в syslog.conf добавление сообщений от ядра уровня debug (или уровня, который вам удобнее)
в отдельный файл. Лучше всего хранить эти логи на отдельном разделе (их размер огромен!
но проблему решает gzip - сжимает логи более чем в 10 раз).
В моём syslog.conf была добавлена строка:
kern.=debug -/var/log/access/access
Желательно, что бы в уровень debug сообщений от ядра не поступало никакой другой информации,
кроме информации от iptables. У меня так и получилось по умолчанию с уровнем debug.
В rc.firewall было добавлено в самое начало:
#LOG ALL (!!!). Beware!!!
#FORWARD
iptables -A FORWARD -m state --state NEW -j LOG --log-level debug \
--log-prefix 'FRWLL_FWD_NEW ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state ESTABLISHED -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_ESTBLSHD ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state RELATED -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_RLTD ' # --log-tcp-options --log-ip-options
#iptables -A FORWARD -m state --state INVALID -j LOG --log-level debug \
# --log-prefix 'FRWLL_FWD_INVLD ' # --log-tcp-options --log-ip-options
#INPUT
iptables -A INPUT -m state --state NEW -j LOG --log-level debug \
--log-prefix 'FRWLL_INPT_NEW ' # --log-tcp-options --log-ip-options
#iptables -A INPUT -m state --state ESTABLISHED -j LOG --log-level debug \
# --log-prefix 'FRWLL_INPT_ESTBLSHD ' # --log-tcp-options --log-ip-options
#iptables -A INPUT -m state --state RELATED -j LOG --log-level debug \
# --log-prefix 'FRWLL_INPT_RLTD ' # --log-tcp-options --log-ip-options
iptables -A INPUT -m state --state INVALID -j LOG --log-level debug \
--log-prefix 'FRWLL_INPT_INVLD ' # --log-tcp-options --log-ip-options
Если раскомментировать все строки, то получиться лог с полной статистикой доступа - он будет очень большим.
Поэтому в данном примере имеем лог только по установкам соединений и ошибочным соединениям в цепочках INPUT и FORWARD.
Итак. В logrotate я добавил (/etc/logrotate.d/access):
/var/log/access/access {
sharedscripts
compress
rotate 45
daily
postrotate
/bin/killall -HUP syslogd
endscript
}
Сжимаем логи каждый день. Храним статистику за последние 45 суток.
Компрессия логов в моём случае дала значительный прирост производительности, поскольку шлюз
достаточно мощный и скорость парсинга логов упиралась только в чтение с HDD.
В итоге был написан простой скрипт на perl, выдающий статистику в более-менее удобоваримой форме.
Вот и сам скрипт:
-------------------------
#!/usr/bin/perl
use CGI qw(:standard);
use PerlIO::gzip;
use Switch;
##Redefine before start:
my $LOG_DIR="/var/log/access/";
my $LOG_FILENAME="access";
##end
my $IP, $FLAG;
## Params delimeter in request: "-"
($IP, $FLAG) = split(/-/, $ARGV[0]);
## if undefine IP or file log FLAG-number or FLAG is empty - parser exit:
if(!defined($IP)||!defined($FLAG)||$FLAG==""){
print header; print start_html;
print "Valid parameters required!"; print end_html; exit(1);
}
print header;
print start_html("Stat for: $IP");
print "<h2>Stat for: $IP</h2><br/>", "\n<pre>";
switch($FLAG)
{
case "0"
{
open($FD, "<$LOG_DIR$LOG_FILENAME")
or die "Cannot open current (0) log-file!<br> File does not exist or access not permitted!<br>";
while(<$FD>)
{
chomp;
s/gw kernel://g;
if(grep(/$IP/, $_))
{
print $_, "<br>\n";
}
}
close($FD);
}
else
{
open($GZIP, "<:gzip(lazy)", "$LOG_DIR$LOG_FILENAME.$FLAG.gz")
or die "Cannot open old (", $FLAG, ") log-file!<br> File does not exist or access not permitted!<br>";
while(<$GZIP>)
{
chomp;
s/gw kernel://g;
if(grep(/$IP/, $_))
{
print $_, "<br>\n";
}
}
close($GZIP);
}
}
print "</pre>\n";
print "<br><br>Access stat parser by \"umask at yandex dot ru\"<br>";
print end_html;
-------------------------
Для работы скрипта необходимо установить модуль PerlIO-gzip. Найти ссылку на модуль можно на cpan.org.
Доступ к статистике можно получить через браузер (скрипт рассчитан для работы как CGI):
hostname.ru/cgi-bin/parse.pl?192.168.1.1-0
Аргумент понимаеться так:
192.168.1.1 - искомая подстрока.
0 - норме лог файла. В данном случае текущий (в который пока ещё записываются сообщения syslog).
1 - вчерашний,
2 - позавчерашний,
3 - 3 дня назад.
.....
и т.д.
Для меня данное решение оказалось удобным.
После долгого копания глюков sarg с ISA 2004 Server logs, были найдены следующие решения:
- формат файла должен быть w3c
- необходимые для анализа поля:
c-ip
cs-username
date
time
time-taken
sc-bytes
cs-uri
sc-status
- поле cs-status не должно быть последним, после него нужно включить еще какое-нибудь поле.
Глюк связан с кривым разбором строки :(
- формат даты в конфиге должен быть "e".
- на поле миллисекунды внимания обращать не советую, чревато нервным срывом :)
- для выгрузки логов на конкретную дату нужно
приложить нижеследующий патчик.
--- util.c.orig Fri May 13 17:05:57 2005
+++ util.c Fri May 13 17:06:09 2005
@@ -239,7 +239,7 @@
void builddia(char *dia, char *mes, char *ano, char *df, char *wdata)
{
- char ndia[9];
+ char ndia[11];
char nmes[3];
int x;
@@ -253,15 +253,15 @@
}
}
- snprintf(wdata,6,"%s%s%s",ano,nmes,dia);
+ snprintf(wdata,9,"%s%s%s",ano,nmes,dia);
if(strncmp(df,"u",1) != 0)
snprintf(ndia,sizeof(ndia),"%s/%s/%s",dia,nmes,ano);
else
snprintf(ndia,sizeof(ndia),"%s/%s/%s",nmes,dia,ano);
- strncpy(dia,ndia,sizeof(dia)-1);
- dia[sizeof(dia)-1]=0;
+ strcpy(dia,ndia);
+// dia[sizeof(dia)-1]=0;
return;
Например, в postfix запущенном в chroot, через настройки в master.cf, при перезапуске syslogd
перестают писаться логи qmgr, тем временем все остальные логи пишутся нормально.
Решение - необходимо создать дополнительный log сокет в chroot окружении:
FreeBSD: "syslogd -l /var/spool/postfix/dev/log"
Linux: "syslogd -a /var/spool/postfix/dev/log"
Для сохранности логов syslogd при записи каждой строки в лог выполняет вызов fsync() для синхронизации
данных на диск. Например, при интенсивной записи почтовых логов syslog может съесть половину времени CPU.
Отключить синхронизацию можно добавив "-" перед файлом лога, например:
mail.* -/var/log/maillog
При экспорте логов на удаленный сервер, рекомендуется вместо доменного имени хоста использовать IP.
Сначала создаем pipe:
mkfifo /path/to/pipe
Затем в /etc/syslog.conf пишем строчку типа:
*.info |/path/to/pipe
Перезапускаем syslogd:
kill -1 'cat /var/run/syslogd.pid'
И запускаем свою программу, которая будет читать с пайпа данные.
На сервере с которого поытаем логи (/etc/syslog.conf):
mail.* /var/log/maillog
mail.* @loger.host.ru
На удаленном FreeBSD сервере, принимающем логи syslog должен запускаться без опции -s
(для некоторых версий нужно указать опцию -r),
удаленные хоcты ограничиваем через "-a ip1 -a ip2", рекомендую прикрыть доступ к 514 UDP порту пакетным фильтром.
Пример /etc/syslog.conf:
mail.* /var/log/maillog_all # логи со всех серверов
+@ # +@ - выборка только для локального хоста
mail.* /var/log/maillog
+relay1.host.ru
mail.* /var/log/maillog_relay1
+relay2.host.ru
mail.* /var/log/maillog_relay2
+* # +* - отмена привязки к хосту
!popa3d # далее по логи по масте программы.
*.* /var/log/pop3log
Возможность работы с блочным устройством другой машины по сети может быть оправдана
при наличии на второй машине новой версии fsck, поддержки файловой системы
(например, тестирование нового драйвера FS, или экспорт на другую программную платформу,
диск можно подключить к Windows машине и примонтировать на компьютере с Linux) или
специализированного устройства (например, raid-контроллера), отсутствующих
на первой машине. NBD также можно использовать в целях упрощения ограничения
интенсивности операций ввода/вывода (клиент и сервер одна машина, регулировка
через iptables), хранилище можно примонтировать на нескольких машинах в read-only
режиме и использовать unionfs для сохранения изменений на локальный диск.
Загружаем исходные тексты NBD с сайта http://nbd.sourceforge.net/
или устанавливаем пакеты в Debian/Ubuntu (nbd-server на сервере, nbd-client на клиенте):
apt-get install nbd-server
apt-get install nbd-client
Экспортируем устройство /dev/sdb1 на сервере:
nbd-server 2000 /dev/sdb1
или nbd-server 192.168.1.1:2000 /dev/sdb1 -r -l /etc/nbd.allow
где, 2000 - номер порта для приема соединений от клиента,
для привязки к IP можно использовать "192.168.1.1:2000"
Для экспорта в режиме только для чтения нужно указать опцию "-r"
Таймаут можно задать через опцию "-a"
Через опцию "-l" можно указать файл со списком IP, которым разрешен доступ.
Через опцию "-c" можно организовать доступ в режиме фиктивной записи, когда все изменения
не будут записываться в экспортируемое устройство, а будут отражаться во временном файле,
доступном только для данной сессии.
Вместо устройства можно экспортировать содержимое файла:
dd if=/dev/zero of=/tmp/test.img count=256 bs=1024k
mkfs.ext3 /tmp/test.img
nbd-server 2000 /tmp/test.img
На стороне клиента выполняем:
modprobe nbd
nbd-client IP_сервера 2000 /dev/nbd0
Устройство /dev/sdb1 сервера будет доступно через /dev/nbd0 на стороне клиента.
Монтируем файловую систему на стороне клиента:
mount /dev/nbd0 /mnt
Пакет inotify-tools содержит две полезные утилиты:
inotifywait - ожидать наступления определенного события в файле или дирекотории.
inotifywatch - слежение за статистикой изменений и вывод суммарных данных.
Утилиту inotifywait удобно использовать в скриптах, например, когда нужно дождаться
завершения внешней операции с файлом и мгновенно среагировать на изменения.
Напрмер, запустим:
inotifywait /tmp
При попытке создать файл в /tmp утилита завершит работу, выдав:
/tmp/ CREATE,ISDIR v31549
При попытке создать директорию:
/tmp/ CREATE,ISDIR 0
Если необходимо следить за изменением во всех директориях в пределах /tmp,
следует использовать флаг рекурсивного контроля "-r".
Для больших директорий может понадобиться расширить лимит /proc/sys/fs/inotify/max_user_watches.
Используя опцию "--fromfile" можно загрузить список контролируемых файлов и директорий из файла.
Опция "-e" позволяет реагировать только на определенный тип события, например, на удаление файла, игнорируя создание и открытие.
Опция '-m' отменяет мгновенный выход после наступления события, что позволяет организовать
визуальное наблюдение или обработку в цикле.
Пример, скрипта для обработки изменения файла:
#!/bin/sh
inotifywait -e delete -m /tmp/lock/ | while read dir events file; do
echo "Removed $dir$file"
done
При выполнении:
inotifywatch /tmp
и последующем завершении выполнения через задание таймаута или нажатия ctrl+c,
будет выведена суммарная информация по каждому из классов событий, напрмер:
total modify close_write close_nowrite open create delete filename
22 3 4 1 5 4 5 /tmp/
Или
inotifywatch -v -e access -e modify -t 60 -r /var/log
через 60 секунд выдаст:
14 14 /var/log/
2 2 /var/log/apache2
4 4 /var/log/postgresql
Что касается кроссплатформенного решения, которое работает, не только в Linux, но и во FreeBSD,
можно привести пример слежения за изменением файла используя Perl модуль EV (http://search.cpan.org/dist/EV/),
использующий универсальную библиотеку-враппер libev:
#!/usr/bin/perl
use strict;
use EV;
# Следим за изменениями в директории /tmp/watch
# 0 - интервал опроса по умолчанию
my $w = EV::stat "/tmp/watch", 0,
sub {
my ($w, $revents) = @_;
warn $w->path, " has changed somehow.".$w->attr."\n";
$w->stop;
# На время обработки события, прекращаем прием нотификаций.
.....
$w->start;
};
EV::loop;
Администрирование Debian: How To по миграции на файловую систему LVM с поддержкой шифрования
Целью данного документа является описание пути перехода на полностью шифрованную файловую
систему LVM (корневая файловая система и пользовательские данные, кроме загрузочного раздела).
Миграция возможна как с обычной LVM, так и с ext3. Все, что вам понадобится - наличие внешнего хранилища.
Отдельно стоит отметить, что данная операция должна проводиться человеком, имеющим некоторый опыт.
ЧАСТЬ 1. Установка необходимого ПО и сохранение текущей системы.
Есть два способа реализации Full Encrypted LVM (далее - FELVM).
a) Debian way (TM), где LVM размещаетя на зашифрованном виртуальном устройстве (cryptsetup).
b) Другой путь, когда LVM создается на физическом устройстве, а затем шифруются логические разделы.
Конечно, я выбираю debian way, хотя никаких определенных причин для этого нет.
В качестве исходных данных у меня имеется /dev/hda1 типа Windows NTFS и несколько других разделов,
тип которых не важен, так как их скоро не останется.
Перед тем, как мы начнем, рекомендую сделать полную копию ваших данных на внешний носитель с помощью CloneZilla,
чтобы потом не иметь бледный вид.
Для начала установим 'cryptsetup'. Также ядро должно ключать образ initrd для загрузки. Если это не так,
установите пакет initramfs-tools. Затем создайте следующий файл в каталоге /etc/initramfs-tools/conf.d:
filename: cryptroot
contents:
target=lukspace,source=/dev/hda3,key=none,lvm=vg-root
Затем выполните команду:
# update-initramfs -u
Она создаст образ initrd, который будет знать, где находятся шифрованные разделы после создания.
Создадим, и это обязательно, tar архив вашей системы на внешний носитель:
# tar cSjf /my/external/storage/sysbackup.tar.bz2 /bin/ /boot/ \
/etc/ /home/ /lib/ /opt/ /root/ /sbin/ /selinux/ /srv/ /usr/ /var/
Если вы хотите повысить скорость выполнения данной операции, уберите флаг 'j' и расширение bz2.
Это позволит сохранить все права доступа, файлы, владельцев файлов и т.д.
Как вы можете заметить, я пропустил каталоги /dev/, /media, /mnt, /proc, /sys, /tmp,
так как они будут вновь созданы на новой системе (кроме /media).
Я подразумеваю, что никаких действий в системе после сохранения не производится -
не открываются консоли и сессии X window, кроме корневой.
Настало время получить данные с внешних хранилищ. Будем считать, что оно примонтировано
в /media/abyss. Конечно, /media так же содержит cdrom и прочие полезные вещи.
# tar cSjf /my/external/storage/databackup.tar.bz2 /media/cdrom /media/whatever /media/...
Все ЗА ИСКЛЮЧЕНИЕМ точки монтирования внешнего хранилища!
Теперь мы защищены от любых ошибок при конфигурировании.
ЧАСТЬ 2. Переформатирование диска и создание структуры FELVM.
Помните: если дела приняли дурной оборот - вы всегда можете восстановиться с помощью clonezilla.
Я использую clonezilla CD для большинства работ, где мне нужен live CD.
Загружаем Clonezilla, настраиваем сеть. Затем в консоли (sudo su) выполняем команды:
# aptitude update && aptitude dist-upgrade
Возможно перед этим вам понадобится выполнить что-то подобное:
# ifconfig eth0 up
# dhclient eth0
После того, как live CD обновит ПО нужно установить следущее:
# aptitude install cryptsetup joe
Joe - мой любимый редактор, поэтому далее мы будем считать, что и ваш тоже.
Очищаем диск!
# cfdisk /dev/hda
и удаляем все разделы за исключением /dev/hda1 (NTFS).
Создаем раздел, с которого будет осуществляться загрузка: /dev/hda2 размером 200 MB.
Затем создаем другой раздел, занимающий все свободное пространство(/dev/hda3).
Его в последствии будет занимать rootfs и данные.
Записываем таблицу разделов на диск и выходим.
Мы все поломали, но не стоит волноваться, все будет восстановлено с tar архивов.
Окончательно удаляем наши данные, заполняя все случайными последовательностями,
заодно проверяя наличие badblock:
# badblocks -s -w -t random -v /dev/hda2
# badblocks -s -w -t random -v /dev/hda3
На выполнение этих команд требуется время, так что будьте терпеливы.
Создаем файловую систему на загрузочном разделе:
# mkfs.ext3 /dev/hda2
Используя cryptsetup создадим большой раздел как устройство dm-crypt. Это очень просто:
# cryptsetup -y -s 256 -c aes-cbc-essiv:sha256 luksFormat /dev/hda3
Я не буду приводить объяснение всех опций, если хотите - посмотрите сами.
Обязательно выберите хорошее ключевое слово, которое вы сможете запомнить.
Позже вы сможете сменить его или сделать несколько ключевых слов.
Подошло время использовать инициализированное пространство:
# cryptsetup luksOpen /dev/hda3 lukspace
Эта команда спросит у вас ранее введенное ключевое слово и сделает доступным /dev/mapper/lukspace.
Это может быть расценено как устройство, готовое принять любой вид данных.
Вы можете форматировать его в ext3 или построить LVM, чем мы сейчас и займемся.
Создаем LVM:
# pvcreate /dev/mapper/lukspace
# vgcreate vg /dev/mapper/lukspace
# lvcreate -L10G -nroot vg
# lvcreate -l 100%FREE -nmyspace vg
Так мы получим логический том LVM /dev/vg/root для корневой файловой системы и /dev/vg/myspace для наших данных.
Это было несложно, не так ли?
Дальше еще проще:
# mkfs.ext3 /dev/vg/root
# mkfs.ext3 /dev/vg/myspace
ЧАСТЬ 3. Восстановление системных файлов и загрузка новой системы.
После того, как вы создадите место для корневой файловой системы, настанет
пора разархивировать туда наши данные.
Сперва создадим точку монтирования, которую назовем /media/rootfs и затем:
# mount /dev/vg/root /media/rootfs
а теперь:
# cd /media/rootfs
# tar xSjf /external_storage/sysbackup.tar.bz2
После чего ждем завершения процесса.
Создаем каталоги, которые не были сархивированы:
# mkdir proc sys media dev tmp mnt
# chmod 1777 tmp
Теперь создаем точку монтирования bootfs и монтируем к ней будущий загрузочный раздел:
# mkdir bootfs
# mount /dev/hda2 bootfs
Затем перемещаем загрузочные файлы из rootfs/boot в bootfs. Теперь /dev/hda2
содержит все необходимые для загрузки файлы. И последнее - изменим файл fstab в rootfs/etc
таким образом, чтобы указать новое устройство /dev/vg/root.
Перезагружаемся. После загрузки grub нажимаем 'e' для редактирования опций ядра и
указания правильного root=..., чтобы машина могла загрузиться.
Хочется надеяться, что LUKS спросит у вас кодовое слово, и все пойдет хорошо!
После того, как вы наиграетесь с вашей зашифрованной системой, отредактируйте /boot/grub/menu.lst
для указания корректного устройства root=... и запустите update-grub.
Giorgos Pallas
Q. Как я могу установить и настроить службу iSCSI на сервере FreeBSD ?
A. FreeBSD 7.x полностью поддерживает iSCSI. Старые версии, такие как FreeBSD 6.3 требуют обратного
портирования для поддержки iSCSI. Следущие инструкции приведены для настройки iSCSI только под FreeBSD 7.0.
FreeBSD iscsi_initiator driver
iscsi_initiator в ядре FreeBSD реализует страндарт сетевого протокола Internet SCSI (iSCSI),
взаимодействует с пользовательским окружением iscontrol и обеспечивает доступ к удаленным виртуальным SCSI устройствам.
Компилирование драйвера
обратите внимание на то, что FreeBSD 7.x поставляется с уже скомпилированным драйвером.
Вы можете пропустить этот шаг, если драйвер /boot/kernel/iscsi_initiator.ko
уже присутствует в вашей системе.
Для компиляции ядра с драйвером, выполните следущее:
# cd /usr/src/sys/i386/conf
# cp GENERIC ISCSIKERNEL
# vi ISCSIKERNEL
Вставьте строку:
device iscsi_initiator
Сохраните и закройте файл конфигурации. Соберите ядро:
# cd /usr/src
# make buildkernel KERNCONF=ISCSIKERNEL
Установите ядро:
# make installkernel KERNCONF=ISCSIKERNEL
Перезагрузите систему:
# reboot
Установка драйвера iSCSI в FreeBSD
Нам необходим драйвер ядра FreeBSD для протокола iSCSI, который называется /boot/kernel/iscsi_initiator.ko.
Загрузите его можно с правами пользователя root следующей командой:
# kldload -v iscsi_initiator.ko
Вывод:
Loaded iscsi_initiator.ko, id=6
Для загрузки драйвера во время начальной загрузки, поместите слудующую строку в /boot/loader.conf:
# vi /boot/loader.conf
# Beginning of the iSCSI block added by Vivek
iscsi_initiator_load="YES"
# End of the block added by Vivek
Сохраните и закройте файл.
Команда iscontrol для подключения, предоставления и контроля сессии iSCSI initiator.
Теперь нам необходимо использовать команду iscontrol. Сперва просмотрим сессии:
# iscontrol -d targetaddress=iSCSI-SERVER-IP-ADDRESS initiatorname=nxl
# iscontrol -v -d targetaddress=192.168.1.100 initiatorname=nxl
Пожалуйста, запишите список доступных targetnames/targetadresses. Как только будет известно targetname,
отредактируйте файл /etc/iscsi.conf:
# vi /etc/iscsi.conf
Укажите директивы подобным образом:
officeiscsi {
authmethod = CHAP
chapIName = YOUR-ISCSI-USERNAME
chapSecret = YOUR-ISCSI-PASSWORD
initiatorname = nxl
TargetName = iqn.XYZZZZZZZZZZZZZ # whatever "iscontrol -v -d " gives you
TargetAddress = 192.168.1.100:3260,1 # your iscsi server IP
}
Сохраните и закройте файл.
Где:
officeiscsi { : Начало конфигурации iSCSI.
authmethod : Установить в качестве метода аутентификации chap
chapIName : Имя
chapSecret : Пароль
initiatorname : Если не указано другое, то iqn.2005-01.il.ac.huji.cs:<hostname>
TargetName : Имя, под которым будет изветен target. Не путайте его с target address,
который назначается администратором или через поиск устройств.
TargetAddress : Имеет вид domainname[:port][,portal-group-tag] согласно RFC:
domainname может быть определен как имя DNS, адрес IPv4 в десятичном представлении
или IPv6 адрес, как указано в [RFC2732].
} : Конец конфигурации
Старт сессии iSCSI
Следущие команды читают опции из /etc/iscsi.conf, используя targetaddress в блоке,
называемом officeiscsi, и запускают сессию iscsi.
# iscontrol -c /etc/iscsi.conf -n officeiscsi
Как только вы выполните команду iscontrol, должно создаться новое устройство в каталоге /dev.
Для проверки выполним команду dmesg:
# dmesg
Форматируем диск iSCSI
Запустим sysinstall для форматирования обнаруженного устройства iSCSI:
# sysinstall
Выбираем Custom > 3 Partition > Выбираем устройство iSCSI по имени da1. После форматирования вводим:
# mkdir /iscsi
# mount /dev/da1s1 /iscsi
Возможно вам понадобится обновить файл /etc/fstab:
/dev/ad1s1 /iscsi ufs rw 3 3
Находим файлы символических ссылок, которые никуда не указывают.
find / -noleaf -type l -print | perl -nle '-e || print'
Эта команда выведет все мертвые ссылки на стандартные вывод.
Можно перевести вывод в файл, для изучения и исправления.
Или просто удалить, добавив конвейер: "| xargs rm", то есть так:
find / -noleaf -type l -print |perl -nle '-e || print' | xargs rm
PS. В BSD системах нужно отбросить опцию -noleaf, которая реализована только в GNU find.
Задача сделать так, чтобы выполнение скрипта для бэкапа не сказывалось на производительности приложений
с интенсивными дисковыми операциями.
Решение - понижение приоритета скрипта в планировщике ввода/вывода CFQ, который включен в Linux ядро,
начиная с версии 2.6.13, и используется по умолчанию начиная с 2.6.18.
Проверяем, что активный планировщик у нас CFQ:
for d in /sys/block/sd[a-z]/queue/scheduler; do echo "$d => $(cat $d)" ; done
Видим: /sys/block/sda/queue/scheduler => noop anticipatory deadline [cfq]
Запускаем скрипт бэкапа с пониженным приоритетом:
nice -n 19 ionice -c2 -n7 backup.sh
утилитой nice с самым низким приоритетом вызываем утилиту ionice cо 2 классом планировки (
1 - real time, 2 - нормальный режим, 3 - работа только в моменты простоя (idle))
и самым низким уровнем приоритета (7).
Если процесс все равно мешает, можем на лету перевести его в idle режим:
ionice -c3 -p 1004
или изменить приоритет планировщика:
renice 19 -p 1004
Где 1004 - PID процесса.
Исходные данные:
Motherboard: GA-965P-DS3 rev. 1.0
Motherboard BIOS: BIOS F1
HDD: Samsung HD103UJ (1 Терабайт)
HDD: Western Digital WD10EACS (1 Терабайт)
OS: Gentoo Linux
hdparm v8.6
Проблема:
Недавно я приобрёл два SATA HDD размером в 1000Мб (1Тб): Samsung HD103UJ и Western Digital WD10EACS.
Я подключил их оба к материнке и к моему удивлению в BIOS один из них (Samsung) определился как 32Мб.
Манипуляции со шлейфами (портами SATA) биосом, операционкой и другие танцы с бубном не помогали.
Samsung был реанимирован с помощью HDD Capacity Restore под Windows у товарища.
Дома диск определился правильно. Предполагая, что проблема была с Samsung'ом я продолжил
манипуляции с дисками дома. К моему удивлению я через некоторое время обнаружил,
что Western Digital тоже стал определяться как 32Мб.
Причина:
Причина в том, что материнская плата (BIOS) резервировала некоторое место под свои нужды.
Это зовется HPA (Host Protected Area). После данной манипуляции по каким-то причинам диск
начинал определяться неправильно. Насколько мне известно, такое происходит только
с терабайтными жесткими дисками, если объем меньше, то активизация HPA не повлияет
на определение размера BIOS'ом. Активизация данной функции (области) происходила при подключении
к определённому SATA порту. На моей материнке есть два типа SATA портов: т. н. SATA-II 0/1/2/3
(желтые, от контроллера Intel ICH8) и т. н. GSATA-II 0/1 (красные, от контроллера J-Micron).
Данный эффект происходил на порту SATA-II 0 (возможно и на других портах SATA-II; по крайней
мере HDD на GSATA-II 0/1 не затрагивались). Соответственно в первом случае я подключал
Samsung к SATA-II, а WD к GSATA-II, во втором случае, я их поменял (естественно, я не придавал этому значения).
Решение:
Под Windows данная проблема решается программой HDD Capacity Restore
http://www.bestvistadownloads.com/download/t-free-hdd-capacity-restore-download-aqauycgh.html
Во FreeBSD 8 это делается путём установки : hw.ata.setmax="1" в loader.conf
Под Linux это решается стандартными средствами - командой hdparm.
Вот пример:
Диск без HPA:
$ hdparm -N /dev/sdd
/dev/sdd:
max sectors = 1953525168/1953525168, HPA is disabled
Диск с HPA:
$ hdparm -N /dev/sdc
/dev/sdc:
max sectors = 586070255/586072368, HPA is enabled
Для отключения HPA для второго случая используем комманду
$ hdparm -N p586072368 /dev/sdc
То есть мы приравниваем количество секторов, доступных пользователю, к максимальном количеству секторов на диске.
Буква 'p' необходима для того, чтобы настройки сохранились в flash жесткого диска
(то есть чтобы после выключения питания они сохранились). Менять параметр с ключем 'p'
можно только один раз за сессию жесткого диска (сессия - промежуток времени между включениям и выключением).
После изменения параметра необходимо выключить и включить винчестер (по факту - компьютер).
Что касается решения корня проблемы - есть мнение, что прошивка F7 материнской платы ее устраняет, но я не пробовал.
Дополнительная информация:
http://en.wikipedia.org/wiki/Host_Protected_Areahttp://www.linux.gr/cgi-bin/man/man2html?hdparm+8http://www.gigabyte.ru/forum/viewtopic.php?f=23&t=25076&p=142923http://www.gigabyte.com.tw/Products/Motherboard/Products_Spec.aspx?ProductID=2361
Создание загрузочного USB Flash на базе ISO образа, без форматирования
и потери сохраненных на Flash данных (ставится прямо в VFAT, используя свободное место)
Устанавливаем пакет livecd-tools
yum install livecd-tools
Создаем загрузочный USB Flash (устройство /dev/sdb1)
livecd-iso-to-disk livecd.iso /dev/sdb1
Возможные проблемы и их решения:
Если программа выдала сообщение "Partition isn't marked bootable!", запускаем:
parted /dev/sdb
Выполняем команду print и смотрим номер раздела (если раздел один, то будет 1)
Выполняем команду: toggle 1 boot
Выходим из parted: quit
Или в fdisk используем команду "a".
Если программа выдала сообщение "Need to have a filesystem label or UUID for your USB device":
dosfslabel /dev/sdb1 usbdisk
вместо usbdisk можно указать любое имя, на ваше усмотрение.
Если программа выдала сообщение "MBR appears to be blank", копируем образ MBR:
cat /usr/lib/syslinux/mbr.bin > /dev/sdb
Если fdisk -l /dev/sdb выдает "Partition has different physical/logical endings!" - нужно переформатировать Flash:
Создаем в fdisk один primary раздел типа 6 (FAT)
Форматируем: mkdosfs -n usbdisk /dev/sdb1
Тестируем подготовленный загрузочный Flash:
qemu -hda /dev/sdb1 -m 256 -std-vga
Если при загрузке пишет: "SYSLINUX 3.xx ... EBIOS Load error - Boot error",
нужно обновить пакет syslinux до версии 3.50 или выше.
После изменения таблицы разделов стандартный fdisk предлагает перезагрузиться,
чтобы ядро восприняло изменения.
Для того, чтобы обойтись без перезагрузки можно использовать утилиту
partprobe (просто запустить без параметров). partprobe входит в состав пакета parted.
Вариант без использования partprobe (подсказал Andrey Mitrofanov):
blockdev --rereadpt
Для ускорения работы ext2/ext3 в пакете e2fsprogs начиная с версии 1.39 появилась
возможность использования технологии "directory indexing", или "HTree".
Чтобы включить dir_index в /dev/hdb1, для отмонтированного раздела нужно выполнить команду:
tune2fs -O +dir_index /dev/hdb1
Далее нужно перестроить индекс директорий:
e2fsck -Df /dev/hdb1
Предполагается что в полном распоряжении есть FreeBSD 5.X
Разборки "что ставить на сервер: 4.X или 5.X" не обсуждаются.
В случае использования FreeBSD 4.X необходимо вместо mdconfig использовать vnconfig
и вместо gbde использовать vncrypt.
Компилируем ядро с
options GEOM_BDE # поддержка шифрованых дисков
device md # Memory "disks"
Создаем директорию, где все будет валяться
mkdir /usr/cert/
Создаем файл, где будет файловая система (размером 100 мегабайт)
dd if=/dev/zero of=fimage bs=1m count=100
создаем девайс на основании этого файла и создем там таблицу разделов на весь диск
mdconfig -a -t vnode -f /usr/cert/fimage -u 0
disklabel -r -w md0 auto
Инициируем gbde патишен
gbde init /dev/md0c -i -L /usr/cert/fimage.lock
В текстовом редакторе откроется конфиг файл для этого шифрованого раздела.
Если используется UFS 1 или2 то рекомендуется изменить параметр sector_size с 512 на 2048.
Сохраняемся, вводим два раза пароль, который будет использоваться для доступа к этому шифрованому разделу.
Подключаем шифрованый раздел (будет запрошен пароль для подключения).
gbde attach /dev/md0c -l /usr/cert/fimage.lock
Создаем на полученном разделе файловую систему.
newfs -U /dev/md0c.bde
Создаем директорию, куда будем маунтить:
mkdir /usr/cert/sslcert
Монтируем
mount /dev/md0c.bde /usr/cert/sslcert
Типа все работает. Теперь создадим скрит для удобства монтирования/размонтирования с таким содержанием:
#!/bin/sh
case "$1" in
start)
/sbin/mdconfig -a -t vnode -f /usr/cert/fimage -u 0
/sbin/gbde attach /dev/md0c -l /usr/cert/fimage.lock
/sbin/mount /dev/md0c.bde /usr/cert/sslcert
;;
stop)
/sbin/umount /usr/cert/sslcert
/sbin/gbde detach /dev/md0c
/sbin/mdconfig -d -u 0
;;
*)
echo ""
echo "Usage: `basename $0` { start | stop }"
echo ""
exit 64
;;
esac
Все, пользуемся в свое удовольствие.
При подготовке использованы источники: FreeBSD Handbook , mdconfig(8), gbde(8)
В 5'ке из-за GEOM'а есть защита от изменений в таблице партиций
на уже установленной системе.
Например, ругается:
ERROR: Unable to write data to disk amrd3
Вот из-за этого и нельзя записать информацию в таблицу партиций.
Решение:
вариант 1:
- смотрим переменную ядра: sysctl kern.geom.debugflags
- устанавливаем в следующее значение для разрешения записи в таблицу партиций:
sysctl kern.geom.debugflags=16
- теперь можем вручную конфигурить диски, массив и писать в таблицу
партиций
тонкость: не используй sysinstall - даже при установленной переменной
kern.geom.debugflags=16 эта утилита не позволит записать в таблицу.
вариант 2:
- если хочешь использовать именно sysinstall - грузись с CD
и используй sysinstall
Если вы создавали разделы начиная с конца диска к началу, в выводе команды
# fdisk -l /dev/hda
(здесь и далее, hda - заменить на ваше устройство) скорее всего, будет присутствовать следующая фраза:
Partition table entries are not in disk order
по причине того, что разделы пронумерованы не в порядке следования, а в порядке создания.
Исправить нумерацию разделов на диске можно следующим образом:
Загружаемся с live-cd либо (если этот диск не не содержит необходимых для функциоирования системы разделов)
отмонтируем все его разделы. Далее:
# fdisk /dev/hda
после приглашения ввода команды жмем клавишу 'x' для перехода в режим раширенной функциональности,
после чего клавишу 'f' для исправления таблицы разделов, и клавишу 'w' для записи изменений.
После чего, можно завершать работу с fdisk, проверять расположение разделов на диске и,
при необходимости, не забыть исправить записи в fstab.
Наименования используемых пунктов fdisk (можно напомнить себе прочитав help после нажатия клавиши 'm'):
x extra functionality (experts only)
f fix partition order
w write table to disk and exit
q quit without saving changes
Что делать если под рукой нет tripwire или osec, а кривой aide вы пользоваться не хотите.
Часть функций , таких как проверка прав доступа и изменение файлов, можно реализовать штатными стедствами.
Вот маленький скрипт который помещается в crontab и позволяет это реализовать.
При желании его функции можно легко расширить.
#!/bin/bash
ulimit -t 20
checkdir="/bin /sbin"
filedb="/var/tmp/permsecdb"
email="test@test.ru"
out=$(
exec 2>&1
umask 266
find $checkdir -type f -printf "%m\t" -exec md5sum {} \; >$filedb.tmp
diff $filedb $filedb.tmp
mv -f $filedb.tmp $filedb
)
if [ "$out" ];then
(date; echo; echo "$out") |mail -s "Change permsec `hostname`" $email
fi
- ulimit лучше выставить не случай не предвиденных ситуаций.
- checkdir соответственно проверяемые директории
- filedb текстовой файл базы
- email куда посылать мыло
Если изменений в системе не было, то сообщения посылаться не будут.
Сообщение бывает 4 видов
1 - ошибки
2 - добавлен файл "> 644 d41d8cd98f00b204e9800998ecf8427e /bin/12"
3 - удален файл "< 755 c1a0ff878c603dd91f603059e9c1a0a1 /bin/12"
4 - изменен файл "
< 755 ce367ef1e2cca19e6216874cb8c09d96 /bin/12
---
> 755 c1a0ff878c603dd91f603059e9c1a0a1 /bin/12"
Успешного контроля.
Linux:
fdisk -l /dev/hda > partitions.txt
cat /proc/partitions
BSD:
disklabel da0s1 > partitions.txt
Для восстановления или клонирования:
fdisk -BI -v -b /boot/mbr da1 # Слайс на весь диск.
disklabel -R -B -r da1s1 partitions.txt
Параметры FS, без ее реального создания можно посмотреть через:
newfs -N /dev/da0s1e
Для визуального создания или редактирования разделов удобно
использовать /stand/sysinstall (Configure/Fdisk иди Label),
в качестве точки монтирования не забыть добавить перед именем "/mnt"
и создать директорию для монтирования.
Команда chattr позволяет изменять параметры ФС для отдельного файла или директории:
chattr +a - только добавление данных (append-only), удаление и переименование запрещено;
chattr +i - запрещено удаление, изменение или переименование (immutable);
chattr +A - запретить сохранение данных о каждом обращении к файлу (no atime)
chattr +S - синхронное изменение всех данных на диск, без кэширования;
chattr +c - файл будет хранится на диске в сжатом виде (нужен отдельный патч для ядра);
chattr +s - после удаления файла, место на диске забивается нулями (внешний патч);
chattr +u - резервирование данных файла после удаления (внешний патч);
Пример:
chattr -R +i /bin /sbin /usr/bin /usr/sbin - запрещаем изменение бинарников
chattr +a /var/log/secure - предотвращаем модификацию лога злоумышленником
Для просмотра расширенных атрибутов используется утилита lsattr.
Для FreeBSD см. man chflags и man security
Резервный диск монтируем как /backup в read-only режиме.
По крону еженощно запускаем скрипт следующего содержания:
/sbin/mount -u -w /backup # пепреводим раздел в rw режим, mount "-o remount,rw /backup" для Linux
/usr/bin/rsync -a --delete --delete-excluded --max-delete=200 \
--exclude-from=/etc/ex_files_list.txt / /backup
RETCODE=$?
if [ $RETCODE -ne 0 ]; then
echo "Err code=$RETCODE"| mail -s "RSYNC BACKUP ERROR" alert@test.ru
fi
/sbin/mount -u -r /backup # раздел обратно в ro, mount "-o remount,ro /backup" для Linux
Если backup-диск большой, лучше вести две полные копии, на случай краха во время бэкапа (или см. опцию --backup);
При бэкапе на другой сревер:
rsync [...опции как выше] --compress --bwlimit=100 --timeout=120 \
-e ssh source/ login@backuphost:/backup/node1
Список файлов для исключения из бэкапа (ex_files_list.txt):
/backup
/mnt
/proc
/tmp
/var/log
/usr/obj
/usr/src
/usr/tmp
/usr/ports
/usr/local/apache/logs
1. Качество исполнения, запас прочности и надежность накопителей со SCSI
интерфейсом как правило выше, чем у IDE.
2. Два подключенных к одному каналу контроллера IDE накопителя, не могут
одновременно передавать данные по шине.
3. SCSI показывают значительно лучшую производительность в загруженной
многозадачной среде, при обилии разрозненных параллельных запросов за
счет более оптимального использования шины передачи данных. (конек IDE -
линейное чтение, сильная сторона SCSI - случайный доступ).
Поясняю: Специфика IDE такова, что запросы могут передаваться по одной
шине последовательно (одна труба передачи данных, однопоточный режим).
Допустим, если 100 процессов обращаются к данным на диске, запросы в
рамках одного канала контроллера будут обрабатываться один за другим, каждый
следующий после полного выполнения предыдущего (связка: выдача
команды - получение данных).
При использовании SCSI, допускается перекрытие запросов (организуется
очередь команд), ответы при этом будут получены распараллеленно
(асинхронная передача), при этом устройство
заведомо зная подробности по командам находящимся в очереди, производит
оптимизацию самостоятельно - минимизируя движение головок.
Linux IDE # Linux SCSI # FreeBSD 4
mknod /dev/hda b 3 0 # /dev/sda b 8 0 # /dev/ad0 b 116 0x00010002
mknod /dev/hda1 b 3 1 # /dev/sda1 b 8 1 # /dev/ad0s1 b 116 0x00020002
mknod /dev/hda2 b 3 2 # /dev/sda2 b 8 2 # /dev/ad0s1a b 116 0x00020000
mknod /dev/hdb b 3 64 # /dev/sdb b 8 16 # /dev/ad0s1b b 116 0x00020001
mknod /dev/hdb1 b 3 65 # /dev/sdb1 b 8 17 # /dev/ad0s1c b 116 0x00020002
mknod /dev/hdc b 22 0 # /dev/sdc b 8 32 # /dev/ad1s1a b 116 0x00020008
mknod /dev/hdd b 22 64 # /dev/sdd b 8 48 # /dev/da1s1a b 13 0x00020000
man chflags; man 2 chflags
Флаги (chflags флаг файл):
sappnd - все, кроме root или владельца (uppnd), могут лишь добавлять информацию в конец файла;
schg - только root или владелец файла (uchg) может изменить, перенести или удалить файл;
sunlnk - только root или владелец файла (uunlink) может удалить или переименовать файл;
Чтобы убрать установленный флаг, нужно использовать префикс "no", т.е. nouchg, nuschg и т.д.
man hdparm (например: /sbin/hdparm -c3 -d1 -X34 /dev/hda)
man elvtune
man tune2fs
echo 128000 > /proc/sys/fs/inode-max # def 16384
echo 64000 > /proc/sys/fs/file-max # def 4096 Число одновременно открытых файлов.
cd /proc/sys/fs/ (в 2.4.x работает автотюнинг)
/usr/src/linux/Documentation/sysctl/fs.txt
/usr/src/linux/Documentation/filesystems/proc.txt
Для решения проблем с русскими именами файлов в Linux для CDROM,
дискеты и Windows раздела следует прописать в /etc/fstab:
/dev/cdrom /mnt/cdrom iso9660 ro,nosuid,noauto,exec,user,nodev 0 0
/dev/fd0 /mnt/floppy vfat iocharset=koi8-r,sync,nosuid,codepage=866,user,--,noauto,nodev,unhide 0 0
/dev/hda1 /mnt/windows vfat user,exec,umask=0,codepage=866,iocharset=koi8-r 0 0
По умолчанию запись на диски в FreeBSD производится в синхронном режиме, значительно увеличить скорость записи
можно активировав асинхронный режим: В /etc/fstab в поле Options добавить async (например rw,async).
Или для примонтированного раздела: mount -u -o async /home
Для увеличения производительности IDE дисков, в файле конфигурации ядра можно указать для wdc устройств
flags 0xa0ffa0ff или 0x80ff80ff (подробнее man wd, man ad).
Для ad: sysctl hw.atamodes; sysctl hw.ata
Например: sysctl hw.atamodes=pio,pio,---,dma,pio,---,dma,---,
См. также man atacontrol
Третий вариант - активировать в настройках ядра SOFTUPDATES и запустить
tunefs -n enable /usr в single-user на размонтированном разделе.
1. Монтируем новый жесткий диск.
2. Создаем разделы на новом диске с помощью fdisk (для freebsd /stand/sysintall или /usr/sbin/sysinstall). Создаем файловую систему.
3. Копируем файлы на новый диск (кроме каталога /mnt, не допускаем рекурсии !!!)
find / -xdev | cpio -pdumv /mnt/new - на каждый раздел.
или tar cf - /bin /usr /etc д.р.| tar xf - -C /mnt/new
или cd /mnt/new; dump -0u -f - /директории| restore -r -f -
или cp -Raxv / /mnt/new - на каждый раздел.
или pax -r -w -p e / /mnt (говорят копирует гораздо быстрее чем dump/restore)
или просто копируем в Midnight Commander'е (не рекомендуется).
Лучший способ - dump/restore или rsync, иначе можно потерять расширенные атрибуты и ACL.
4. Редактируем /mnt/new/etc/fstab
5. Создаем с помощью /dev/MAKEDEV недостающие устройства (для нового типа диска).
6. mkdir /mnt/new/proc /mnt/new/mnt
7a. Только для Linux: правка /etc/lilo.conf и запуск lilo -r /mnt/new -b /dev/hdb
При возникновении ошибки при загрузке:
Было:
boot=/dev/sda
default=linux-up
image=/boot/vmlinuz-up
label=linux-up
root=/dev/sda2
initrd=/boot/initrd-up.img
Предположим, что дубликат размещен на /dev/sdb, тогда меняем boot=/dev/sda на boot=/dev/sdb
и добавляем:
disk=/dev/sdb
bios=0x80
Выполняем lilo -r /mnt/new и не забываем убирать исправления из lilo.conf.
7b. Для freebsd загрузчик устанавливается после разбиения диска на разделы через sysintall.
PS. Если диски одинаковые можно использовать dd if=/dev/hda of=/dev/hdb,
если разделы одинаковые: dd if=/dev/hda1 of=/dev/hdb1
Имеем 3 диска: /dev/sda,/dev/sdb, /dev/sdc
Создаем RAID5:
mdadm --create /dev/md0 --chunk=64 --level=5 --raid-devices=3 /dev/sda1 /dev/sdb1 /dev/sdc1
Со временем докупили еще диск и решили использовать его как запасной,
который автоматически включается в работу при сбое одного из дисков.
Подключаем /dev/sdd1, как "spare":
mdadm --manage /dev/md0 --add /dev/sdd1
Позже места в RAID5 стало нехватать и мы решили включить spare диск в состав RAID5.
Перестраиваем массив:
mdadm --grow /dev/md0 --raid-devices=4
Через несколько часов, когда операция будет завершена (следим через /proc/mdstat),
расширяем файловую систему:
fsck.ext3 /dev/md0
resize2fs /dev/md0
Имеет 4 диска: /dev/sd[abcd], на каждом из которых создано по одному разделу.
Хотим получить RAID10, как комбинацию из двух raid1, объединенных в raid0 (striping).
Создаем два RAID1, /dev/md0 и /dev/md1
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1
mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sdc1 /dev/sdd1
Объединяем их в RAID10 (1+0):
mdadm --create /dev/md2 --chunk=64 --level=0 --raid-devices=2 /dev/md0 /dev/md1
Тоже самое можно проделать одной командой
mdadm --create /dev/md0 --level=10 --raid-devices=4 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1
Смотрим, что получилось в итоге:
mdadm --detail /dev/md2
cat /proc/mdstat
Программный RAID1 /dev/md0 включает в себя разделы /dev/sda1 и /dev/sdb1.
Задача заменить диск /dev/sdb.
Диагностику смотрим через (если вместо [UU] видим [U_], то целостность одного из дисков нарушена):
cat /proc/mdstat
Помечаем раздел как сбойный:
mdadm --manage /dev/md0 --fail /dev/sdb1
Отключаем раздел (удаляем из RAID1)
mdadm --manage /dev/md0 --remove /dev/sdb1
Выключаем машину, меняем диск.
Создаем через fdisk идентичные разделы, или копируем структуру первого диска /dev/sda:
sfdisk -d /dev/sda | sfdisk /dev/sdb
Добавляем раздел в RAID1 массив:
mdadm --manage /dev/md0 --add /dev/sdb1
Имеем два диска /dev/ad4 и /dev/ad6, на /dev/ad4 установлена рабочая система.
Создаем RAID1 /dev/mirror/gm0 и подключаем к нему диск /dev/ad4 (текущий):
gmirror label -v -b round-robin gm0 /dev/ad4
В случае появления ошибки "Can't store metadata on /dev/ad4: Operation not permitted" делаем:
sysctl kern.geom.debugflags=16
Включаем загрузку модуля ядра geom_mirror.ko:
echo geom_mirror_load=YES >> /boot/loader.conf
В /etc/fstab меняем /dev/ad4 на /dev/mirror/gm0
Перезагружаемся и проверяем все ли нормально.
Подключаем в RAID1 второй диск:
gmirror insert gm0 /dev/ad6
В логе /var/log/messages должно появиться:
GEOM_MIRROR: Device gm0: provider ad6 detected.
GEOM_MIRROR: Device gm0: rebuilding provider ad6.
Дожидаемся окончания перестроения RAID, периодически запуская:
gmirror status
или
gmirror list
После завершения перестроения, скорость чтения должна возрасти почти в два раза.
В случае выхода из строя диска /dev/ad6, вставляем новый и делаем:
gmirror forget gm0
gmirror insert gm0 /dev/ad6
При создании RAID1 например:
# atacontrol create RAID1 ad0 ad2
система создает raid массив но на него пока ничего не пишеться. Но статус у него READY:
# atacontrol status ar0
ar0: ATA RAID1 subdisks: ad4 ad6 status: READY
Система считает что после создания raid, на нем создадут слайсы,
и партиции, после чего на них запишут данные.(что и происходит при установке системы на ar0)
при этом все данные не будут нарушать целостность raid.
Но систему можно обмануть.
# atacontrol list
ATA channel 0:
Master: ad0 <ST380011A/3.06> ATA/ATAPI revision 6 //живая система
Slave: no device present
ATA channel 1:
Master: ad2 <ST380011A/3.06> ATA/ATAPI revision 6 //новый диск
Slave: no device present
# atacontrol detach 1
Теперь мы имеем целостный RAID1 состоящий из одного диска с системой.
# atacontrol status ar0
ar0: ATA RAID1 subdisks: ad0 DOWN status: DEGRADED
Прописываем ar0 в fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/ar0s1b none swap sw 0 0
/dev/ar0s1a / ufs rw 1 1
/dev/ar0s1e /tmp ufs rw 2 2
/dev/ar0s1f /usr ufs rw 2 2
/dev/ar0s1d /var ufs rw 2 2
перегружаем систему (!!!должна нормально смонтировать все файловые системы, внимательно смотрите лог загрузки)
после перезагрузки:
# atacontrol status ar0
ar0: ATA RAID1 subdisks: ad0 DOWN status: DEGRADED
# atacontrol addspare ar0 ad2
# atacontrol rebuild ar0
# atacontrol status ar0
ar0: ATA RAID1 subdisks: ad0 ad1 status: REBUILDING 1% completed
После окончания rebuild система готова к использованию.
/dev/sda - диск с установленной ОС
/dev/sdb - новый диск для зеркала
Клонируем информацию о разделах на новый диск:
sfdisk -d /dev/sda | sfdisk /dev/sdb
Создаем RAID1, но первый диск пока не трогаем, пометив его отсутствующим:
mdadm --create /dev/md0 --level 1 --raid-devices=2 missing /dev/sdb1
mdadm --create /dev/md1 --level 1 --raid-devices=2 missing /dev/sdb2
и т.д. для всех существующих разделов.
Создаем ФС:
mkfs.ext3 /dev/md0
mkfs.ext3 /dev/md1
...
Монтируем и копируем данные в RAID:
mount /dev/md0 /mnt
cp -dpRx / /mnt
mount /dev/md1 /mnt/var
cp -dpRx /var /mnt
...
Меняем устройство для загрузки, для Grub в /mnt/boot/grub/menu.lst:
title Custom Kernel 2.6.11.7
root (hd0,0)
kernel /boot/vmlinuz-2.6.11.7 root=/dev/md0 md=0,/dev/sda1,/dev/sdb1 ro
boot
title Custom Kernel 2.6.11.7 (RAID Recovery)
root (hd1,0)
kernel /boot/vmlinuz-2.6.11.7 root=/dev/md0 md=0,/dev/sdb1 ro
boot
Устанавливаем Grub на второй диск:
grub-install /dev/sda
Если при установке выдается ошибка:
/dev/sda does not have any corresponding BIOS drive.
Нужно выполнить
grub-install --recheck /dev/sda
Или установить вручную:
grub
grub: device (hd0) /dev/sdb
grub: root (hd0,0)
grub: setup (hd0)
grub: quit
cp -dp /mnt/etc/fstab /etc/fstab
cp -dp /mnt/boot/grub/menu.lst /boot/grub
Перезагружаемся (второй диск) и проверяем все ли работает, если да - подключаем старый диск в RAID:
mdadm --add /dev/md0 /dev/sda1
mdadm --add /dev/md1 /dev/sda2
...
cat /proc/mdstat
Управление программными RAID1-массивами в RHEL
Мониторинг состояния
Информация о всех RAID-массивах:
# more /proc/mdstat
или
# cat /proc/mdstat
или
# watch -n .1 cat /proc/mdstat
Информация о конкретном дисковом разделе:
# mdadm -E /dev/sd<a-b><1-10>
например:
# mdadm -E /dev/sdb2
Восстановление функционирования
Восстановление функционирования (rebuild) разделов диска по одному после однократного "несмертельного" сбоя:
# mdadm -a /dev/md<0-6> /dev/sd<a-b><1-10>
например:
# mdadm -a /dev/md0 /dev/sdb1
Нужно быть аккуратным с номерами разделов
В случае ошибки, удалить компонент из RAID командой:
# mdadm -r /dev/md0 /dev/sdb1
получается не всегда - устройство может быть занято.
Замена диска
1. Выключить компьютер и заменить диск
2. Включить компьютер и определить имеющиеся на обоих дисках разделы:
# fdisk /dev/sd<a-b> -l
3. С помощью fdisk создать на новом диске разделы, идентичные оригиналу
Необходимо пометить нужный раздел нового диска (sda1 или sdb1) как загрузочный до включения в зеркало.
Swap-разделы не подлежат зеркалированию в программном RAID
4. Выполнить Мониторинг состояния и Восстановление функционирования
Настройка оповещения
Мониторинг выполняется с помощью crond ежечасно.
В папку /etc/cron.haurly помещен файл mdRAIDmon, содержащий команду:
# mdadm --monitor --scan -1 --mail=postmaster@domain.name.ru
Для проверки рассылки сообщения добавляется ключ --test:
# mdadm --monitor --scan -1 --mail=postmaster@domain.name.ru --test
Помещая файл задания в папку, необходимо установить права доступа на выполнение
Если нужно чаще, самое простое, добавьте в /etc/crontab строку, используя нотацию с "/", например:
*/5 * * * * root run-parts /etc/cron.my5min
Конечно, можно попробовать и другие варианты планирования заданий с atd или batch.
Создайте папку /etc/cron.my5min и поместите туда файл mdRAIDmon
C имитацией отказа диска мне было проще - сервер SR1425BK1 - с корзиной HotSwap
CCD (Concatenated Disk Driver) - поддерживает RAID-0 (Striping) и RAID-1 (Mirroring), под FreeBSD 5 подогнана под работу через GEOM, но возможностей меньше чем в GEOM gmirror. При сбое одного из дисков, для продолжения работы нужно восстановить утраченный диск;
Vinum - очень богатые возможности, но сложен и непрозрачен в настройке, под FreeBSD 5 работает нестабильно. При сбое диска, система продолжит работу;
GEOM Vinum - порт Vinum для работы через GEOM, еще не достаточно отлажен и документирован;
GEOM Mirror - специальный GEOM класс для создания RAID-1 зеркал, прост и понятен в настройке, в FreeBSD 5.3 говорят о хорошей стабильности. Поддерживает зеркалирования как дисков в целом, так и отдельных разделов. Доступно несколько режимов балансировки нагрузки на диски в мирроре (round-robin, использование менее загруженного диска и т.д.). После сбоя система продолжает работу, имеется функция автосинхронизации на новый пустой диск.
Советую использовать tmpfs или ramfs
(разница в том, что данные tmpfs подвержены своппингу, ramfs создана для тестов, а ramdisk всегда хранится в ОЗУ)
/usr/src/linux/Documentation/filesystems/tmpfs.txt
mount -t tmpfs -osize=256M /dev/shm1 /mnt1
Для ramfs:
mount -t ramfs -omaxsize=256M none /mnt1
Если желание использовать ramdisk осталось, читаем
/usr/src/linux/Documentation/ramdisk.txt
mkdir /ramdisk
Для 256Мб ramdisk в lilo.conf добавляем:
append="ramdisk_size=256000"
Запускаем lilo и перезагружаем машину.
mke2fs /dev/ram0
mount -t -ext2 /dev/ram0 /ramdisk
В логе smartd появились подобные свидетельства наличия нечитаемых секторов на диске:
smartd[798]: Device: /dev/ad5, 15 Currently unreadable (pending) sectors
smartd[798]: Device: /dev/ad5, 15 Offline uncorrectable sectors
SMART тестирование подтвердило подозрения:
Запускаем фоновый тест диска, не мешающий основной работе:
smartctl -t long /dev/ad5
Ждем завершения периодически просматривая статус:
smartctl -l selftest /dev/ad5
В итоге смотрим содержимое лога, в самом конце вывода:
smartctl -a /dev/ad5
Имеем:
# 1 Extended offline Completed: read failure 90% 2916 10373954
Выявляем полный список сбойных секторов, путем чтения всех данных с диска:
dd if=/dev/ad5 of=/dev/null bs=512 conv=noerror,sync
В один прекрасный момент появятся надписи вида:
dd: /dev/ad5: Input/output error
10373954+0 records in
10373954+0 records out
5311464448 bytes transferred in 2427.397393 secs (2188131 bytes/sec)
В системном логе увидим:
kernel: ad5: TIMEOUT - READ_DMA retrying (1 retry left) LBA=10373954
kernel: ad5: TIMEOUT - READ_DMA retrying (0 retries left) LBA=10373954
....
kernel: ad5: FAILURE - READ_DMA timed out LBA=10374109
kernel: ad5: TIMEOUT - READ_DMA retrying (1 retry left) LBA=10374113
Проверяем, каждый участок еще раз:
dd if=/dev/ad5 of=/dev/null bs=512 count=1 skip=10373954 conv=noerror,sync
Смотрим какой файл в ФС подпадает под этот блок.
Смотрим и примерно вычисляем номер раздела на который приходится сбойный сектор (LBA 10373954):
fdisk -s /dev/ad5
/dev/ad5: 775221 cyl 16 hd 63 sec
Part Start Size Type Flags
1: 63 398444067 0xa5 0x80
2: 398444130 382973535 0xa5 0x80
10373954 - 63 = 10373891
disklabel /dev/ad5s1
# /dev/ad5s1:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 2097152 0 4.2BSD 2048 16384 28552
b: 4194304 2097152 swap
c: 398444067 0 unused 0 0 # "raw" part
d: 2097152 6291456 4.2BSD 2048 16384 28552
e: 10485760 8388608 4.2BSD 2048 16384 28552
f: 104857600 18874368 4.2BSD 2048 16384 28552
g: 104857600 123731968 4.2BSD 2048 16384 28552
h: 162127234 228589568 4.2BSD 2048 16384 28552
Видим, что 10373891 приходится на раздел /dev/ad5s1e
Расчитываем смещение относительно начала раздела:
10373891 - 8388608 = 1985283
Находим иноду, которой принадлежит заданный блок:
fsdb -r /dev/ad5s1e
findblk 1985283
повторяем для каждого сбойного сектора
(для Linux нужно использовать debugfs - http://smartmontools.sourceforge.net/BadBlockHowTo.txt)
Пытаемся записать данные в сбойный сектор, чтобы инициировать процесс
ремапинга на диске.
sysctl kern.geom.debugflags=16 # иначе будет dd: /dev/ad5: Operation not permitted)
dd if=/dev/zero of=/dev/ad5 bs=512 count=1 skip=10373954 conv=noerror,sync
sysctl kern.geom.debugflags=0
Если после записи сектор начал читаться - все ok,
если нет - резервная область на диске уже заполнена, пробуем запретить обращещние окружающих секторов в ФС:
man badsect
/dev/ad5s1e примонтирован как /usr, создаем директорию /usr/BAD и выполняем
badsect /usr/BAD 1985283
fsck -y /dev/ad5s1e
Полезные порты:
/usr/ports/sysutils/recoverdm
/usr/ports/sysutils/diskcheckd
Утилита par2 позволяет добавлять к файлам информацию для восстановления по алгоритму Рида-Соломона.
Это позволяет восстанавливать исходный файл в случае небольших (или даже серьезных) повреждений.
Делается это следующим образом:
$ sudo aptitude install par2 #(cd /usr/ports/archivers/parchive; make instal)
$ ls
dump.sql.gz
$ par2 create -v -r10 -n1 -m500 dump.sql.gz
$ ls
dump.sql.gz dump.sql.gz.par2 dump.sql.gz.vol000+100.par2
Эта команда добавит 10% (-r10) избыточной информации к данным, запишет все это в один файл (-n1),
при этом программе par2 разрешено использовать 500 мегабайт оперативной памяти (-m500).
Файлы *.par2 следует записать на диск вместе с дампом.
Восстановить поврежденный файл можно командой
$ par2 repair dump.sql.gz.par2
Подробнее о par2 и чтении данных с битых CD:
http://alexey.sveshnikov.ru/blog/2008/04/10/broken-cd-parchive/
Подробнее про о коде Рида-Соломона:
http://www.insidepro.com/kk/027/027r.shtml
В данном примере показано восстановление образа снятого с "криво" записанного диска FreeBSD 6.0.
1. Находим при помощи гугла rsync-зеркала с интересующими нас образами. Для задачи из примера их список можно увидеть здесь.
Выбираем ближайшие зеркала с отметкой rsync напротив адреса:
ftp2.ru.freebsd.org и ftp5.ru.freebsd.org.
2. Узнаем какие "модули" доступны у выбранных rsync-серверов при помощи команды:
rsync -n -vv ftp2.ru.freebsd.org::
Ответ - два слова FreeBSD, откуда заключаем, что имя интересующего нас модуля - FreeBSD. Для сервера ftp5.ru.freebsd.org узнать имя модуля таким способом не удастся - этот сервер возвращает в ответ только информацию "рекламного" характера. Пояснения к команде: ключ -n не позволяет утилите rsync загружать ничего; ключ -vv позволяет увидеть на экране больше информации о происходящем; два двоеточия после имени сервера обязательны (можно использовать вместо них rsync:// перед именем сервера, но это длиннее).
3. Изучаем расположение каталогов и файлов на сервере:
rsync -n -vv ftp2.ru.freebsd.org::FreeBSD/
К предыдущей команде добавлено имя модуля и следующий за ним слэш (/). Слэш нужен для указания того, что необходимо отобразить листинг директории, а не ее саму. В результате выполнения команды можно увидеть, что файловая структура (в данном случае) повторяет расположение файлов на FTP-сервере. После чего определяем где лежат искомые образы (листаем интересующие нас каталоги) и продолжаем. К сожалению, у меня не получилось заставить работать ключик --list-only из man rsync и пришлось находить вышеописанный способ методом научного тыка.
4. Предположим, что образ диска уже снят, например так:
Пояснения к команде: -z желателен для сжатия передаваемой информации (действенность не проверял); --stats выводит после окончания подробную информацию о сделанном; --progress отображает процент выполнения текущей задачи.
6. Убеждаемся, что сумма восстановленного образа совпадает с суммой образа с официального сайта.
Данным методом я восстановил образы дисков с FreeBSD 6.0, записанных при помощи программы Nero добрым человеком с толстым каналом. readcd ругался на эти диски в самом конце каждого из них. Входящий трафик, в моем случае, для обоих дисков составил меньше 1 Mb.
Наткнулся на днях на грабли. Оказывается ядро 2.6.14, а я уверен и не только оно,
не понимает автоматом OnTrack на диске и прочие ему подобные "изменятели геометрии диска".
Если к примеру ядро 2.4.29 без проблем грузится на с таким диском и при загрузке пишет что-то типа:
hdc: hdc1[DM6:DD0] hdc2 <hdc5 hdc6>
то 2.6.14 пишет:
hdc: hdc1[DM6] hdc2
и продолжает грузиться, при этом обратиться к hdc разделам нельзя, но fdisk с ними работает.
проблема решилась установкой ключа hdc=remap64 в параметрах ядра.
к примеру в lilo.conf так:
append="hdc=remap63"
и при загрузке ядро на ура всё определит.
О более подробном списке ключей можно почитать тут: /usr/src/linux/Documentation/ide.txt строка 214
Устанавливаем утилиту http://smartmontools.sourceforge.net/
Выводим информацию, поддерживает ли диск SMART.
$ smartctl -i /dev/rdsk/c0t0d0s0
Включаем SMART, если выключен.
$ smartctl -s on /dev/rdsk/c0t0d0s0
Проверяем какие возможности SMART поддерживает диск и какие установлены параметры.
$ smartctl -c /dev/rdsk/c0t0d0s0
Статус состояния диска и список атрибутов проверок.
$ smartctl -H /dev/rdsk/c0t0d0s0
$ smartctl -A /dev/rdsk/c0t0d0s0
Запускаем offline тест
$ smartctl -t offline /dev/rdsk/c0t0d0s0
Смотрим, есть ли ошибки
$ smartctl -l selftest /dev/rdsk/c0t0d0s0
Смотрим более детально
$ smartctl -r ioctl -i /dev/rdsk/c0t0d0s0
Выводим общую статистику
$ smartctl -a /dev/rdsk/c0t0d0s0
Управление программными RAID1-массивами в RHEL
Мониторинг состояния
Информация о всех RAID-массивах:
# more /proc/mdstat
или
# cat /proc/mdstat
или
# watch -n .1 cat /proc/mdstat
Информация о конкретном дисковом разделе:
# mdadm -E /dev/sd<a-b><1-10>
например:
# mdadm -E /dev/sdb2
Восстановление функционирования
Восстановление функционирования (rebuild) разделов диска по одному после однократного "несмертельного" сбоя:
# mdadm -a /dev/md<0-6> /dev/sd<a-b><1-10>
например:
# mdadm -a /dev/md0 /dev/sdb1
Нужно быть аккуратным с номерами разделов
В случае ошибки, удалить компонент из RAID командой:
# mdadm -r /dev/md0 /dev/sdb1
получается не всегда - устройство может быть занято.
Замена диска
1. Выключить компьютер и заменить диск
2. Включить компьютер и определить имеющиеся на обоих дисках разделы:
# fdisk /dev/sd<a-b> -l
3. С помощью fdisk создать на новом диске разделы, идентичные оригиналу
Необходимо пометить нужный раздел нового диска (sda1 или sdb1) как загрузочный до включения в зеркало.
Swap-разделы не подлежат зеркалированию в программном RAID
4. Выполнить Мониторинг состояния и Восстановление функционирования
Настройка оповещения
Мониторинг выполняется с помощью crond ежечасно.
В папку /etc/cron.haurly помещен файл mdRAIDmon, содержащий команду:
# mdadm --monitor --scan -1 --mail=postmaster@domain.name.ru
Для проверки рассылки сообщения добавляется ключ --test:
# mdadm --monitor --scan -1 --mail=postmaster@domain.name.ru --test
Помещая файл задания в папку, необходимо установить права доступа на выполнение
Если нужно чаще, самое простое, добавьте в /etc/crontab строку, используя нотацию с "/", например:
*/5 * * * * root run-parts /etc/cron.my5min
Конечно, можно попробовать и другие варианты планирования заданий с atd или batch.
Создайте папку /etc/cron.my5min и поместите туда файл mdRAIDmon
C имитацией отказа диска мне было проще - сервер SR1425BK1 - с корзиной HotSwap
При загрузке ядра LILO запоминает данные о назначении номеров BIOS для
дисков, и потом при установке
загрузчика использует эти данные. При смене устройства для загрузки в настройках BIOS номера дисков
меняются (выбранный для загрузки диск получает номер 0x80), поэтому сохранённая lilo информация
перестаёт соответствовать реальной конфигурации.
Нужно явно указать номера дисков в /etc/lilo.conf:
disk=/dev/hda
bios=0x80
disk=/dev/hdb
bios=0x81
Скачать smartmontools (http://smartmontools.sourceforge.net/)
Выполнить:
smartctl -a /dev/hda # Посмотреть состояние
smartctl -t long /dev/hda # Провести тест
smartctl -l selftest /dev/hda # Дождаться окончания теста и посмотреть результат
При необходимости воспользоваться debugfs как написано в статье по ссылке.
Бэкап MBR:
dd if=/dev/hda of=mbr_backup.bin bs=1 count=512
Для восстановления всего MBR поменять if/of местами.
Таблица разделов находится в MBR по смещению 0x01BE (446) и состоит
из 4 записей по 16 байт.
Для восстановления только таблицы разделов:
dd if=mbr_backup.bin of=/dev/устройство bs=1 count=64 skip=446 seek=446
(Во FreeBSD и Solaris)
Можно удалить дефектный inode с помощью команды clri:
clri <файловая-система> <номер-inode>
и запустить снова fsck. При этом, к сожалению, файл теряется, но остальное спасется.
Нужно вставить диск в заведомо рабочую машину (так как проблемы не обязательно в диске, контроллер может
быть виной) с достаточным свободным местом на диске чтобы вместить весть объем сбойного диска и сделать:
dd if=/dev/hdb1 of=/usr/local/tmp/root_fs.img conv=noerror,sync bs=1024
fsck -y /usr/local/tmp/root_fs.img
mount -o loop /usr/local/tmp/root_fs.img /mnt (в Linux)
Далее смотреть в /mnt, что удалось спасти.
Монтирование файла как раздела в FreeBSD:
vnconfig -r labels -c vn0 root_fs.img
mount /dev/vn0 /mnt
В FreeBSD для восстановления можно использовать утилиту ffsrecov из портов.
Если fsck не находит superblock, то можно задать альтернативное размещение:
"fsck -b [16|32] .." для FreeBSD, fsck -b [8193|32768|16384]" - для Linux.
Каждую базу MySQL хранит в отдельном каталоге внутри datadir.
MySQL работает под своим пользователем и соответственно создает файлы баз под им же. Соответственно квотирование в данном случае не возможно. Необходимо заставить его создавать файлы баз, влaдельцем которых будет конкретный квотируемый пользователь. Сделать это можно выставив бит SUID (4000) на каталог базы.
Для начала:
в ядре:
options SUIDDIR
в /etc/fstab:
добавляем в список опций suiddir
В MySQL создаем базу. Находим каталог базы в datadir. По умолчанию он будет mysql:mysql.
Меняем владельца:
chown sql-user databasedir
теперь наш каталог sql-user:mysql
Меняем права:
chmod 4070 databasedir
Такая настройка заставит систему создавать файлы от имени владельца каталога (sql-user) причем сам пользователь не будет иметь к нему доступа. К нему будет иметь полный доступ MySQL (от группы mysql).
Теперь мы можем использовать квоты как для обычных файлов.
При превышении квот MySQL будет генерить ошибку full disk что является нормальным явлением и корректно отрабатывается MySQL, хотя сопровождается некоторыми проблемами: при запросе на добавление в базу, превысившую квоты, запрос повисает, повисают также последующие запросы, которые можно снять только их убийством или освобождением дополнительного места на диске. При дефолтных настройках это сразу вызовет проблему, так как такие запросы займут все сетевые соединения. Поэтому необходимо ОБЯЗАТЕЛЬНО
ограничить максимальное количество подключений одного пользователя MySQL. В /etc/my.cnf:
max_connections = 500 (всего коннектов)
max_user_connections = 30 (максимум для одного пользователя)
Также возможно следующие - MySQL может пометить как поврежденные при останове сервера или когда временные файлы займут слишком много места на диске (второе судя по мануалам, не проверял). Лечится репаиром соотвествующих таблиц.
Убить повисшие процессы может только root базы если они достигли max_user_connections.
Не работает с таблицами innodb, так последние хранятся в одном месте независимо от базы.
В single mode: "/sbin/tunefs -a enable /fs"
Пересобираем ядро с "options UFS_ACL"
getfacl - просмотр ACL
setfacl - установка ACL
Например: setfacl -m user:nobody:rw-,group:wheel:rw- acl-test
- в конфигурации ядра включаем "options QUOTA" и пересобираем ядро.
- в /etc/rc.conf прописываем enable_quotas="YES" и check_quotas="YES"
- указываем в fstab файловые системы, для которых будет включаться
поддержка квот, например:
/dev/da0s1e /home ufs rw,userquota 2 2
/dev/ad0s1h /new_home ufs rw,groupquota 2 2
- устанавливаем квоты для пользователей при помощи edquota, напр. "edquota user1"
- если нужно установить одинаковые квоты для нескольких пользователей как у user1:
edquota -p user1 user2 user3 user4 user5
Ситуация: после подключения USB-стика при копировании на него информации в особо крупных размерах
наблюдается скорость около 10-200 килобайт/сек., что есть не очень хорошо, даже просто ужасно.
Кто виноват?
Виноват HAL. Внешние накопители (USB-флешки) он монтирует в режиме синхронной записи данных.
Что делать?
Нужно изменить настройку одного из файлов конфигурации HAL:
/etc/hal/fdi/policy/preferences.fdi
отредактируем его, изначально было так (обычно в этот файл мало что вносится):
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
<!--
<device>
<match key="storage.hotpluggable" bool="false">
<match key="storage.removable" bool="false">
<merge key="storage.automount_enabled_hint" type="bool">false</merge>
</match>
</match>
</device>
-->
как видно, всё закомментировано, никаких настроек нет. а сделаем так:
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
<device>
<!-- disable sync for mount -->
<match key="block.is_volume" bool="true">
<match key="volume.fsusage" string="filesystem">
<match key="@info.parent:storage.bus" string="usb">
<merge key="volume.policy.mount_option.sync" type="bool">false</merge>
</match>
</match>
</match>
</device>
</deviceinfo>
Вытаскиваем железки и перезапустим HAL, с привилегиями суперпользователя выполним:
/etc/init.d/hal restart
Подключаем железку, получаем, к примеру, на моём стике разность в скорости возросла с 120-200kB/s до 2.4-12 MB/s.
Зависит от характеристик самой флешки.
Настройки опций монтирования также могут быть найдены внутри директории /usr/share/hal/fdi/
Опции с отключением синхронизации требуют обязательного отмонтирования накопителя!
Возможность работы с блочным устройством другой машины по сети может быть оправдана
при наличии на второй машине новой версии fsck, поддержки файловой системы
(например, тестирование нового драйвера FS, или экспорт на другую программную платформу,
диск можно подключить к Windows машине и примонтировать на компьютере с Linux) или
специализированного устройства (например, raid-контроллера), отсутствующих
на первой машине. NBD также можно использовать в целях упрощения ограничения
интенсивности операций ввода/вывода (клиент и сервер одна машина, регулировка
через iptables), хранилище можно примонтировать на нескольких машинах в read-only
режиме и использовать unionfs для сохранения изменений на локальный диск.
Загружаем исходные тексты NBD с сайта http://nbd.sourceforge.net/
или устанавливаем пакеты в Debian/Ubuntu (nbd-server на сервере, nbd-client на клиенте):
apt-get install nbd-server
apt-get install nbd-client
Экспортируем устройство /dev/sdb1 на сервере:
nbd-server 2000 /dev/sdb1
или nbd-server 192.168.1.1:2000 /dev/sdb1 -r -l /etc/nbd.allow
где, 2000 - номер порта для приема соединений от клиента,
для привязки к IP можно использовать "192.168.1.1:2000"
Для экспорта в режиме только для чтения нужно указать опцию "-r"
Таймаут можно задать через опцию "-a"
Через опцию "-l" можно указать файл со списком IP, которым разрешен доступ.
Через опцию "-c" можно организовать доступ в режиме фиктивной записи, когда все изменения
не будут записываться в экспортируемое устройство, а будут отражаться во временном файле,
доступном только для данной сессии.
Вместо устройства можно экспортировать содержимое файла:
dd if=/dev/zero of=/tmp/test.img count=256 bs=1024k
mkfs.ext3 /tmp/test.img
nbd-server 2000 /tmp/test.img
На стороне клиента выполняем:
modprobe nbd
nbd-client IP_сервера 2000 /dev/nbd0
Устройство /dev/sdb1 сервера будет доступно через /dev/nbd0 на стороне клиента.
Монтируем файловую систему на стороне клиента:
mount /dev/nbd0 /mnt
Имеем полный образ USB Flash, полученный после
dd if=/dev/sdb of=usb.img
Перед монтированием, необходимо выяснить смещение относительно начала образа:
fdisk usb.img
Command (m for help): p
Disk usb.img: 0 MB, 0 bytes
63 heads, 62 sectors/track, 0 cylinders
Units = cylinders of 3906 * 512 = 1999872 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
usb.img1 1 701 1369022 6 FAT16
Смещение будет = число секторов на дорожке * размер сектора * начальная дорожка раздела
Итого: 62 * 512 * 1 = 31744
Монтируем в директорию ./0
mount -o loop,offset=31744 usb.img ./0
Добавлено из комментариев:
[root@host /]# kpartx -av `losetup -sf /tmp/sdb.img`
add map loop2p1 : 0 401562 linear /dev/loop2 63
add map loop2p2 : 0 7984305 linear /dev/loop2 401625
[root@host /]# mount /dev/mapper/loop2p2 ./0
Стоит отметить что данный способ гораздо проще в использовании, но требует поддержки ядром loopback, devicemapper и наличия kpartx.
Но зато не надо ничего вычислять в уме.
Вы можете использовать обычную команду mount для монтирования раздела. mount автоматически не определяет тип файловой системы UFS.
Вы должны указать тип UFS используя опции команды mount:
* old: Старый формат UFS, по умолчанию, только чтение. (Не забудьте указать опцию -r .)
* 44bsd: Для файловых систем созданных на BSD-подобных системах как NetBSD, FreeBSD и OpenBSD
* sun: Для файловых систем созданных на SunOS или Solaris для процессора Sparc.
* sunx86: Для файловых систем созданных на Solaris для процессоров x86.
* hp: Для файловых систем созданных на HP-UX, только чтение.
* nextstep: Для файловых систем созданных на NeXTStep (только чтение).
* nextstep-cd: Для файловых систем созданных на NextStep компакт-дисках
( размер блока - block_size == 2048)
* openstep: Для файловых систем созданных на только чтение. OpenStep (пока только чтение).
Такой же тип файловой системы используется в Mac OS X.
Внимание! Примеры могут потребовать перекомпиляции ядра Linux для поддержки файловой системы UFS.
По умолчанию поддержка файловой системы UFS не включена.
Вы должны скомпилировать ядро с поддержкой для файловой системы UFS.
(см. CONFIG_UFS_FS=m и CONFIG_UFS_FS_WRITE=y параметры).
Первое, создайте директорию монтирования.
# mkdir /mnt/solaris
Теперь, используя команду mount, на подобии:
# mount -t ufs -o ro,ufstype=sunx86 /dev/sdXY /mnt/solaris
# mount -t ufs -o ro,ufstype=sunx86 /dev/sdb1 /mnt/solaris
Так будет примонтирован первый раздел /dev/sda1
Для дополнительной информации читайте руководство к команде mount:
$ man mount
Имеем: неизменную базовую /home директорию.
Хотим: отдельно держать изменения внесенные пользователями, чтобы они не влияли на базовую /home.
изменения держать в рамдиске, так чтобы они не сохранялись при следующем входе
Решение:
- unionfs - для отделения данных пользователя от read-only основы.
- tmpfs - для создания /tmp директории с временными файлами, хранимой в ОЗУ.
- pam-mount (http://pam-mount.sourceforge.net/) - PAM модуль для автоматического
монтирования разделов в момент входа пользователя в систему.
Устанавливаем пакеты (пример для Debian и Ubuntu):
apt-get install unionfs-modules-`uname -r`
apt-get install libpam-mount
Настраиваем pam_mount (/etc/security/pam_mount.conf)
volume debiosk tmpfs - tmpfs /tmp/tmpfs "size=15M,uid=debiosk,gid=debiosk,mode=0700" - -
volume debiosk unionfs - unionfs /home/debiosk "dirs=/tmp/tmpfs:/home/debiosk=ro" - -
где
"volume" - ключевое слово, сигнализирующее об описании раздела;
"debiosk" - имя пользователя, для которого определены правила монтирования;
"tmpfs" - тип файловой системы;
" - " - сигнализирует о неиспользовании монтирования с удаленного сервера;
"/tmp/tmpfs" - точка монтирования;
"size=15M,uid=debiosk,gid=debiosk,mode=0700" - параметры монтирования tmpfs:
"size=15m," - размер;
"uid=debiosk,gid=debiosk," - владелец;
"mode=0700" - права доступа;
"dirs=/tmp/tmpfs:/home/debiosk=ro" - параметры монтирования unionfs:
указывают отобразить изменения /home/debiosk в директории /tmp/tmpfs
Добавляем строку "@include common-pammount" в /etc/pam.d/login, /etc/pam.d/su и /etc/pam.d/xdm
Теперь пользователь debiosk каждый раз будет получать исходную домашнюю директорию,
а изменения будут действовать только в пределах сессии.
Получаем уникальный идентификатор устройства:
# blkid /dev/hda6
/dev/hda6: UUID="3e6be9de-8139-11d1-9106-a43f08d823a6" TYPE="ext2"
В качестве устройства монитрования в /etc/fstab указываем:
UUID=3e6be9de-8139-11d1-9106-a43f08d823a6
Также для монитрования без привязки к блочному устрйству можно использовать метки:
Ставим метку:
e2label /dev/hda6 BACKUPDISK
В /etc/fstab указываем:
LABEL=BACKUPDISK
Посмотреть метку для заданного устройства можно командой:
blkid -s LABEL /dev/hda6
Задача ужать стандартный GNOME-LiveCD Fedora7 до 400 Мб.
Ниже журнал действий.
1. Извлекаем из iso образа LiveCD squashfs.img.
mount -o loop ./Fedora-7-Live-i686.iso /mnt/cdrom
копируем все в отдельную директорию директорию /mnt/disk/LiveCD/newcd
umount /mnt/cdrom
2. Монтируем squashfs.img и извлекаем из него os.img
mount -o loop -t squashfs /mnt/disk/LiveCD/newcd/squashfs.img /mnt/cdrom
копируем содержимое в /mnt/disk/LiveCD/new_ext3
umount /mnt/cdrom
3. Монтируем ext3 образ /mnt/disk/LiveCD/new_ext3/os.img
mount -o loop /mnt/disk/LiveCD/new_ext3/os.img /mnt/disk/LiveCD/new_ext3/sysroot
4. Удаляем лишнее и устанавливаем недостающее.
chroot /mnt/disk/LiveCD/new_ext3/sysroot /bin/sh
su -
mount /proc
mount /sys
rm -rf /usr/share/doc
в /usr/share/locale/ - оставляем только русские и английские локали
cd /usr/share/icons; rm -rf Bluecurve gnome
В /usr/share/pixmaps заменяем недостающее, чистим pixmaps/backgrounds/
копируем свою фоновую картинку
cp background.jpg /usr/share/gdm/themes/FedoraFlyingHigh
cp background.jpg /usr/share/backgrounds/images/default.jpg
Чистим /usr/share/backgrounds
Удаляем пакеты с китайскими шрифтами:
rpm -e fonts-chinese fonts-arabic fonts-korean fonts-japanese
Если rpm ругается, делаем "rpm --rebuilddb"
Если нужно создать какие-то директории или произвести действия в момент старта livecd
правим fedora-live в /etc/rc.d/init.d
Ставим желаемые пакеты, например, конфигуратор PPTP:
rpm -Uvh http://pptpclient.sourceforge.net/yum/stable/fc7/pptp-release-current.noarch.rpm
yum --enablerepo=pptp-stable install pptpconfig
....
umount /proc
umount /sys
5. После приведения os.img в нужный вид, создаем новый пустой os.img и
копируем содержимое старого (нужно забить образ нулями, чтобы он лучше сжался,
иначе изменения будут только в метаданных и итоговый образ squashfs после сжатия получиться больше чем начальный).
cd mnt/disk/LiveCD/new_ext3
dd if=/dev/zero of=new_os.img bs=1k count=4096k
/sbin/mkfs.ext3 -F -L "LiveCD" -m 1 new_os.img
/sbin/tune2fs -c0 -i0 -Odir_index -ouser_xattr,acl new_os.img
Монтируем новый образ
mkdir /mnt/disk/LiveCD/new_ext3/new_sysroot
mount -o loop ./new_os.img /mnt/disk/LiveCD/new_ext3/new_sysroot
Копируем содержимое старого через rsync, чтобы сохранить расширенные атрибуты файлов.
rsync -a -v --acls --xattrs --hard-links /mnt/disk/LiveCD/new_ext3/sysroot /mnt/disk/LiveCD/new_ext3/new_sysroot
незабываем размонтировать и переименовать новый образ
umount /mnt/disk/LiveCD/new_ext3/sysroot
umount /mnt/disk/LiveCD/new_ext3/new_sysroot
rm /mnt/disk/LiveCD/new_ext3/new_sysroot
mv /mnt/disk/LiveCD/new_ext3/new_os.img /mnt/disk/LiveCD/new_ext3/os.img
6. Сжимаем ext3 образ
rm /mnt/disk/LiveCD/newcd/squashfs.img
cd /mnt/disk/LiveCD/new_ext3/
/sbin/mksquashfs os.img sysroot /mnt/disk/LiveCD/newcd/squashfs.img
7. Создаем iso образ для записи на CD:
mkisofs -o ./live.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
-boot-info-table -J -r -hide-rr-moved -V "Fedora-7-Live-i386" /mnt/disk/LiveCD/newcd/
Если появится желание изменить метку диска Fedora-7-Live-i386, не забудьте поменять ее в isolinux/isolinux.cfg
На моей станции поднят ftp сервер (vsftpd). Как известно FTP cервер позволяет расшарить
определённую директорию (в нашем случае /var/ftp/)/ Часто у меня возникали ситуации
когда нужно что то расшарить по сети, а копировать это в раздел где расшаренная
директория - места нет. Да и копировать это опять же или менять кофиг сервера и перерапускать сервис.
Для себя нашёл очень простой и удобный способ как это сделать.
Монтировать нужные директории в дерево /var/ftp используя 'mount --bind '. всё просто.
[root@n100851 ~]# mkdir /var/ftp/pub/music
[root@n100851 ~]# mount --bind /home/user/media/sound/ /var/ftp/pub/music/
и всё. анонимусы могут забирать музыку с FTP сервера.
После удачно завершившейся разборки с "multiple LUN support" для доступа к девайсам карт-ридеров
(MAUSB-300 производства OLYMPUS и безымянный "11 in 1" Тайваньского производства) оказалось,
что карты xd-Picture (OLYMPUS) и SD (Transcedent), отформатированные в соответствующих аппаратах
(фотокамера CAMEDIA C55ZOOM, и наладонник PalmOne Tungsten E2) монтироваться всё-таки не хотят.
По выяснении обстоятельств оказалось что монтировать их нужно с указанием параметра offset:
xd 16Mb - 20992 (0x5200)
xd 128Mb - 24064 (0x5E00)
xd 256Mb - 25088 (0x6200)
sd 128Mb - 49664 (0xC200)
sd 256Mb - 51712 (0xCA00)
т.е., например, вот так:
> mount -t vfat -o loop,offset=20992 /dev/sda /mnt/ttt
После модификации содержимого карт (добавления/удаления файлов),
смонтированных таким образом соответствующие аппараты не высказывают к этому самому содержимому
(и к файловой системе карт) никаких претензий, т.е. читают его и понимают правильно.
Если необходимо экспортировать каталог, имя которого очень длинное (например, большая вложенность),
то для удобства клиента можно сделать символическую ссылку на этот каталог с более коротким именем.
На клиенте же монтировать не сам экспортируемый каталог, а ссылку на него.
Пример:
На сервере есть каталог:
/usr/home/ftp/anonftp/distrib/unix/FreeBSD/distfiles
Создаём ссылку на него:
# ln -s /usr/home/ftp/anonftp/distrib/unix/FreeBSD/distfiles /home/distfiles
В файле /etc/exports помещаем такую строку:
/usr/home/ftp/anonftp/distrib/unix/FreeBSD/distfiles -ro -mapall=nobody
Теперь на клиенте можно монтировать этот каталог таким образом:
# mount_nfs server:/home/distfiles /usr/ports/distfiles
Пишем скрипт /etc/auto.smbfs примерно такой:
#!/bin/sh
a="${1/@//}"
a="${a//\ /\\ }"
echo -fstype=smbfs,username=guest,password=fmask=666,iocharset=cp1251,codepage=cp866 :"//$a"
Параметры - по вкусу. automount как-то небрежно относится к пробелам в имени, но так работает.
Ставим на файл бит исполнения:
chmod +x /etc/auto.smbfs
Далее в /etc/auto.master добавляется строка
/var/autofs/smb /etc/auto.smbfs
где /var/autofs/smb - точка монтирования.
Стартуем:
/etc/init.d/autofs restart
Для удобства:
ln -s /var/autofs/smb /smb
Теперь можно обращатся к шаре "share" на хосте "host" вот так:
cd /smb/host@share
по IP тоже работать должно.
Всё написанное верно для дистрибутива debian sarge. Нужны пакеты autofs и smbfs.
Желающие могут расширить фунциональность, прикрутив к скрипту передачу логина\пароля через путь.
Для начала:
mdconfig -a -t vnode -u0 -f /share/iso/slackware-9.0-install.iso
затем
mount -t cd9660 /dev/md0 /mnt/iso
Обратный процесс:
umount /dev/md0
mdconfig -d -u0
p.s. Может не работать если в ядре нет "device md"
cd /usr/ports/sysutils/cd9660_unicode
make && make install
грузить модуль через
kldload /lib/cd9660_unicode/cd9660_[unicode|koi8-r|iso-8859-5|cp866].ko
В Joliet файлы хранятся в unicode, соответственно codepage=unicode.
Если файлы записаны в 866 кодировке нужно добавить ",codepage=866"
mount -t iso9660 -o iocharset=koi8-r,ro,noexec,mode=0444 /dev/cdrom /mnt/cdrom
или в /etc/fstab:
/dev/cdrom /mnt/cdrom iso9660 noauto,user,ro,noexec,mode=0444,iocharset=koi8-r
а затем: mount /mnt/cdrom
/dev/acd0c /mnt/cdrom cd9660 ro,noauto,-W=koi2dos,
-L=ru_RU.KOI8-R 0 0
/dev/fd0 /mnt/flop msdos rw,noauto,-W=koi2dos,
-L=ru_RU.KOI8-R 0 0
/dev/ad0s2 /mnt/store msdos rw,-W=koi2dos,
-L=ru_RU.KOI8-R,noexec,nosuid,nosymfollow,
-u0,-g0,-m 660 0 0
Еще для удобства можно создать симлинки типа:
ln -sf /dev/acd0c /dev/cdrom
ln -sf /dev/acd1c /dev/cdrom1 (если есть второй cdrom)
ln -sf /dev/fd0 /dev/flop
прописать изменения в fstab,
и монтировать диски командой mount /dev/cdrom а не
mount /dev/acd0c =).
1. Если копируемая директория заканчивается слэшем, то файлы будут скопированы
в каталог назначения относительно корня изначально заданной директории. Пример:
rsync -a /dir1/dir2 /dir3 - будет создана иерархия /dir3/dir2/файлы
rsync -a /dir1/dir2/ /dir3 - будет создана иерархия /dir3/файлы
2. При транзитном переносе файлов через дополнительную машину не нужно забывать,
что опция "-a" подразумевает трансляцию имен пользователей и групп в локальные uid/gid,
т.е. скопировав данные с первой машины на вторую, а потом со второй на локально подключенный
жесткий диск, предназначенный для третьей машины, получим на третьей машины совершенно иных
владельцев каталогов и файлов. Не тех которые были в /etc/password первой машины,
а тех, которые в данным момент в /etc/password второй машины (изменятся типовые пользователи,
например, web, ftp, dhcp, номера uid/gid которых отличаются на двух машинах).
Чтобы этого не произошло нужно испольщовать опцию "--numeric-ids".
3. Особенности задания файлов исключений ("--exclude-from=файл" или " --exclude маска1 --exclude маска2").
Для того чтобы исключить из бэкапа содержимое директории, но саму директорию оставить,
нужно указать в "exclude" файле "/dir/*", а не "/dir/"
(под "/dir" подпадет и /dir123, и файл /dir.txt, для директорий указание "/" в конце обязательно).
Звездочка ("*") в шаблоне действует только на имя файла/каталога, чтобы маской охватывалась
часть пусти, включая "/", нужно писать "**".
Шаблон не начинающийся с '/' проверяется с конца строки. Например "/dir/test" будет
проверен c начала пути, а "dir/test.txt" или "*.log" с конца.
Если необходимо исключить все поддиректории в /dir, кроме /dir/best, в список исключений нужно поместить:
+ /dir/best/
- /dir/*
При переборе содержимого "exclude" файла, срабатывает первое правило под которое подпадает текущий путь,
не важно исключающие или нет. В качестве корня выступает директория назначения,
т.е. "/" в "exclude" файле = "/dir3/dir2" или "/dir3" из первого совета.
4. Запрещение двойного сжатия при передаче данных по SSH.
rsync при задании опции "-z" более оптимально сжимает передаваемые данные,
поэтому сжатие средствами ssh можно отключить:
export RSYNC_RSH="ssh -c arcfour -o Compression=no -x"
rsync -a -z -v --bwlimit=16 /dir1 /dir2 user@test.ru:/dir3/
где, --bwlimit=16 ограничивает пропускную способность при копировании бэкапа в 16 Кбайт в сек.
5. Изменение уровня точности при сравнении локального и удаленного времени модификации файлов.
Например, для того чтобы считать идентичными файлы время модификации которых отличается
на 1 секунду необходимо указать: "--modify-window=1".
6. Пример сохранения истории изменения данных. При этом старые измененные или удаленные
файлы не теряются а перемещаются в директорию /snapshot/дата.
#!/bin/sh
snapshot_dir="/snapshot/`date \+\%Y_\%m_\%d`"
mkdir $snapshot_dir
rsync -a -v --delete --max-delete=1000 --hard-links \
--delete-excluded --exclude-from=/etc/rsync_backup.exclude \
--backup --backup-dir=$snapshot_dir \
/ /backup
RETCODE=$?
if [ $RETCODE -ne 0 ]; then
echo "Err code=$RETCODE"| mail -s "FATAL RSYNC BACKUP" admin@test.ru
fi
echo RET: $RETCODE
/bin/chmod 0700 /backup
/bin/chmod 0700 /snapshot
7. Некоторые полезные опции.
-v - говорливость, выводит имена обрабатываемых файлов;
-a - работа в режиме архивирования, сохраняются права доступа и информация о владельцах;
-H - сохранять жесткие ссылки, оставляя их на другом конце бэкапа;
-x - не выходить за пределы текущей точки монтирования;
--progress - показывать сколько процентов осталось до завершения и скорость передачи;
--delete - удалять из бэкапа файлы, которых уже нет на стороне источника.
--delete отличается от --delete-after тем, что удаление производится вначале,
а не на завершающей стадии процесса бэкапа. --delete-after работает быстрее,
так как не требует лишней стадии обхода списка файлов, но требует использования опции --force
для обработки таких ситуаций как удаление файла и появление диретории с тем же именем;
--delete-excluded - удалять части которые уже есть на стороне бэкапа, но появились в списке исключения;
-n - режим тестирования, реально никаких действий по копированию не производится, только эмуляция;
-c - использование сверки по контрольным суммам, а не по времени изменения и размеру;
--compare-dest=DIR - сохранять новые и измененные файлы в отдельной директории,
не трогая на время копирования основную директорию назначения, в конце - разом,
путем переименования, обновить содержимое бэкапа;
--link-dest=DIR - использовать жесткие ссылки на файлы в DIR, например, для создания подобия снапшотов;
--ignore-errors - продолжать копирование и удаление после появления ошибок;
--max-delete - ограничение максимально числа удаляемых за один раз файлов и каталогов;
-A - сохранять не только права доступа, но и ACL;
--files-from=FILE - задать список директорий и файлов для бэкапа в файле;
Есть два сервера под Linux/FreeBSD: СУБД MySQL + некое приложение,
задача - синхронизировать БД и данные.
За синхронизацию данных MySQL отвечает mysql replication, данные синхронизируются с мастера на слейв.
Делаем на мастере:
в my.cnf добавляем строки
log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db=databasename
server-id=1
перезагружаем MySQL, добавляем пользователя для репликации:
GRANT ALL PRIVILEGES ON databasename.* TO 'slave_user'@'%' IDENTIFIED BY 'slave_password';
FLUSH PRIVILEGES;
далее выполняем команду:
USE databasename;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
и вывод этой команды для нас важен, надо его куда-нибудь записать:
| File | Position | Binlog_do_db | Binlog_ignore_db |
| mysql-bin.001 | 10 | databasename | |
теперь делаем дамп базы:
mysqldump -u slave_user -pslave_password --opt databasename > databasename.dump
и наконец убираем лок с базы в MySQL:
UNLOCK TABLES;
Теперь на слейве:
Создаём базу:
mysqladmin create databasename -p
Востанавливаем базу из дампа:
mysql -u slave_user -pslave_password databasename < databasename.dump
в my.cnf добавляем строки:
server-id=2
master-host=XX.XX.XX.XX # IP адрес мастер-сервера
master-user=slave_user
master-password=slave_password
master-connect-retry=60
replicate-do-db=databasename
перегружаем MySQL и добавляем чудесные данные из волшебной комманды:
SLAVE STOP;
CHANGE MASTER TO MASTER_HOST='XX.XX.XX.XX',
MASTER_USER='slave_user', MASTER_PASSWORD='slave_password',
MASTER_LOG_FILE='mysql-bin.001', MASTER_LOG_POS=10;
START SLAVE;
готово, теперь проверяем, добавляем запись в мастер, на слейве она должны отреплицироваться.
Понятно, что изменять данные можно только на мастере, слейв работает только на чтение.
Для синхронизации данных имеет смысл использовать rsync, очень интересный протокол/приложение.
Может синхронизировать инкрементально и с сжатием.
На мастер сервере в rsyncd.conf добавляем:
read only = yes # во избежание ;-)
hosts allow = YY.YY.YY.YY # IP адрес слэйв-сервера
[somelabel]
path = /path/to/apllication/folder # где лежит приложение
auth users = replica_user # юзер только для репликации в rsync, не системный пользователь
secrets file = /path/to/rsync/rsync.secret # где лежит файл с паролем для replica_user,
# только пароль и ничего больше
на слейве - команда для синхронизации, можно добавить в cron с нужной периодичностью:
/path/to/rsync -avz --exclude-from=/path/to/rsync.exclude \
--password-file /path/to/rsync.secret \
rsync://replica_user@XX.XX.XX.XX:873/somelabel /path/to/application
где:
rsync.exclude - файл в котором перечислены, какие файлы (конкретно или по маске) не синхронизировать
rsync.secret - файл с секретным паролем для replica_user
ХХ.ХХ.ХХ.ХХ - IP мастер-сервера, 873 - дефолтный порт для демона
somelabel - метка из rsyncd.conf с мастера
/path/to/application - путь куда класть данные.
mysqldump лочит таблицы на запись и во время дампа база фактически простаивает.
Решения:
1. Репликация и бэкап со слейва;
2. mysqlhotcopy, делает "read lock" на и копируются файлы баз, т.е.:
FLUSH TABLES WITH READ LOCK;
// копировать файлы MyISAM таблиц
UNLOCK TABLES;
FLUSH TABLES WITH READ LOCK может занять много времени т.к. он будет ждать окончания выполнений всех запущенных запросов.
3. Минимизация блокировки через использование снапшотов ФС:
FLUSH TABLES WITH READ LOCK;
Делаем снэпшот ФС, где лежат базы мускула
UNLOCK TABLES;
Копируем директории с базой или отдельные таблицы
Отцепляем снэпшот
Скрипт для Linux (использует LVM снапшот): http://lenz.homelinux.org/mylvmbackup/
Cкрипт для FreeBSD:
(echo "FLUSH TABLES WITH READ LOCK;"; echo "\! ${MOUNT} -u -o snapshot /${SNAPPART}/.snap/backup /${SNAPPART}"; echo "UNLOCK TABLES;" ) |
${MYSQL} --user=root --password=`${CAT} ${MYSQLROOTPW}`
Linux:
fdisk -l /dev/hda > partitions.txt
cat /proc/partitions
BSD:
disklabel da0s1 > partitions.txt
Для восстановления или клонирования:
fdisk -BI -v -b /boot/mbr da1 # Слайс на весь диск.
disklabel -R -B -r da1s1 partitions.txt
Параметры FS, без ее реального создания можно посмотреть через:
newfs -N /dev/da0s1e
Для визуального создания или редактирования разделов удобно
использовать /stand/sysinstall (Configure/Fdisk иди Label),
в качестве точки монтирования не забыть добавить перед именем "/mnt"
и создать директорию для монтирования.
Бэкап MBR:
dd if=/dev/hda of=mbr_backup.bin bs=1 count=512
Для восстановления всего MBR поменять if/of местами.
Таблица разделов находится в MBR по смещению 0x01BE (446) и состоит
из 4 записей по 16 байт.
Для восстановления только таблицы разделов:
dd if=mbr_backup.bin of=/dev/устройство bs=1 count=64 skip=446 seek=446
Резервный диск монтируем как /backup в read-only режиме.
По крону еженощно запускаем скрипт следующего содержания:
/sbin/mount -u -w /backup # пепреводим раздел в rw режим, mount "-o remount,rw /backup" для Linux
/usr/bin/rsync -a --delete --delete-excluded --max-delete=200 \
--exclude-from=/etc/ex_files_list.txt / /backup
RETCODE=$?
if [ $RETCODE -ne 0 ]; then
echo "Err code=$RETCODE"| mail -s "RSYNC BACKUP ERROR" alert@test.ru
fi
/sbin/mount -u -r /backup # раздел обратно в ro, mount "-o remount,ro /backup" для Linux
Если backup-диск большой, лучше вести две полные копии, на случай краха во время бэкапа (или см. опцию --backup);
При бэкапе на другой сревер:
rsync [...опции как выше] --compress --bwlimit=100 --timeout=120 \
-e ssh source/ login@backuphost:/backup/node1
Список файлов для исключения из бэкапа (ex_files_list.txt):
/backup
/mnt
/proc
/tmp
/var/log
/usr/obj
/usr/src
/usr/tmp
/usr/ports
/usr/local/apache/logs
Полный бэкап всех баз:
pg_dumpall [-s] [-D] > backup_file
Выборочный бэкап:
pg_dump [-s] [-D] [-t table] db > backup_file
-s - записывается только информация о структуре базы, без данных.
-D - формируется бэкап данных в виде INSERT команд.
-t table - бэкап выборочных таблиц.
Бэкап структуры:
mysqldump --all --add-drop-table [--all-databases] --force [--no-data] [-c] \
--password=password --user=user [база] [таблицы] > backup_file
( -c - формировать в виде полных INSERT.
--all-databases - бэкап всех баз, --no-data - бэкап только структуры таблиц в базах, [таблицы] - бэкапить только указанные таблицы.)
Восстановление: mysql < backupfile
(для прямой вставки из текстового файла можно воспользоваться mysqlimport)
(для анализа структуры базы, например, списка таблиц: mysqlshow <база>)
Создаем снапшот test1 раздела /home
mount -v -u -o snapshot /home/snapshot/test1 /home
или другой метод:
mksnap_ffs /home /home/snapshot/test1
Привязываем снапшот к устройству /dev/md1:
mdconfig -a -t vnode -f /home/snapshot/test1 -u 1
При необходимости снапшот можно смонтировать и посмотреть его содержимое:
mount -o ro /dev/md1 /mnt
....
umount /mnt
Копируем содержимое раздела на второй диск:
dd if=/dev/md1 of=/dev/ad4s1f bs=16k
Отключаем снапшот
mdconfig -d -u 1
Выполняем fsck на новом разделе:
fsck -f /dev/ad4s1f
Опция "-D" утилиты e2fsck позволяет выполнить переиндексацию при использовании dir_index (tune2fs -O +dir_index),
иначе выполнить перекомпановку с сортировкой (когда было создано или удалено
большое количество директорий) и сокращением размера (когда в
директории было много файлов, а потом их удалили).
Пример запуска (/dev/sdb1 должен быть отмонтирован или переведен в режим только для чтения):
# e2fsck -D -f /dev/sdb1
Если подробнее - то AFS относится примерно к тому классу, в котором сидят NFS, SMB, и win2K3 DFS. Основная их задача - качественный доступ к различным (раскиданным по сети) ресурсам, с соблюдением блокировок и напором на контроль доступа и централизованное управление. Здесь четко прослеживается модель "клиент-сервер" - большинство участников сетовой ФС являются клиентами, а под шары выделяются чаще отдельные серваки. С точки зрения производительности для такой ФС критериями являются пропускная способность сервер-клиент и количество поддерживаемых коннектов. Масштабируется такая ФС вертикально - более шустрым железом. Надежность тоже поддерживается на уровнях ниже сетевой ФС (RAID, репликация средствами ОС и администратором 24/7 на мобильном =)
Кластерных ФС известно негусто - навскидку Lustre, Google FS (+Hadoop), что-то было у IBM.
Отличительная особенность - все участники ФС унифицированы и являются и серверами и клиентами ФС (это именно особенности реализации, конечно же можно и настроить для работы как "несколько серверов - много клиентов", но преимуществ в этом случае не получите, скорее наоборот)
Обычный принцип действия - работа на уровне блоков: разбитый на блоки файл "размазывается" по нескольким серверам, при его чтении клиент сам собирает блоки в файл. (Комментарий Алексея: Это Google FS & RedHat GFS.. в люстре оперируют понятием объект).
Критерии оценки таких ФС - общая пропускная способность ФС кластера (то есть сколько гб/с крутится в пределах кластера) и латентность (задержка между запросом файла и его получением). Также тут важна надежность - все блоки реплицируются на уровне ФС, вылет нода не сказывается на работе кластера.
ФС этого класса очень разные. Lustre заточена под hiperf вычисления с низкой латентностью, посему пользуют что-нить типа InfiniBand и нестандартные MPI. Lustre замонтированая представляет из себя слегка урезaную ext3 для 2.4 ядер, для 2.6 используется ldiskfs которая значительно ближе к ext4.
Google FS и Hadoop - вообще с классической точки зрения не ФС, ибо ничего не монтируют а предоставляют RPC API для разработчиков. Рассчитаны они на гигантские объемы информации, работу в основном на чтение большими блоками (в мегабайтах, стандартный блок такой ФС - 32-64Мб) и в очень больших количествах.
Также есть shared storage FS - эти нужны при работе нескольких (многих) серверов с внешними дисковыми массивами. Основная задача - обеспечить быструю и правильную блокировку совместного доступа (via SAN, iSCSI, SCSI). Без них фактически каждый сервер должен работать со своим личным выделенным на массиве разделом. Из известных - GFS от RedHat, Oracle Cluster File System, PolyServe и Veritas CFS.
RedHat GFS - раздает raw девайс и пытается управлять блокировками на уровне блоков, без учета логической организации.
gfarm изначально позиционирует себя для таковой модели использования: есть много данных, распределенных по нодам,
нужно их все параллельно обработать. В случае люстры и подобных - compute node сначала фетчит себе данные из кластерной фс, обрабатывает и возвращает обратно (отсюда требования к пропускной способности и латентности). В случае gfarm - задание по обработке для compute нода попадает благодаря gfarm именно на тот нод, где локально лежит одна из реплик требуемых данных. Соответственно по сети происходит трансфер задания на обработку данных , а не самих данных. (например, здесь, да и вообще тут- большинство тем именно parallel computing, а не distributed fs).
Требуется создать журналируемую файловую систему UFS2 объемом более 1 Гб на FreeBSD 6.1-STABLE.
Для начала необходимо обновить дерево исходных текстов (/usr/src) до стабильной версии.
После чего переходим в каталог /usr/src и создаем там необходимые директории:
# cd /usr/src
# mkdir {sbin/geom/class/journal,sys/geom/journal,sys/modules/geom/geom_journal}
Теперь качаем сам патч:
# fetch http://people.freebsd.org/%7Epjd/patches/gjournal6.patch
Накладываем его на исходные тексты:
# patch < gjournal6.patch
Компилируем и ставим geom_journal (возможно имеет смысл пересобрать весь мир):
Далее есть два пути - пересобрать весь "мир" (см. файл /usr/src/UPDATING), либо пересобрать только то, что было модифицировано.
Предпочтительней первый путь, однако можно обойтись и без него. Для этого пересоберите следующие утилиты
(зайдя в нижеперечисленные каталоги и выполнив в каждом из них 'make; make install; make clean'):
/usr/src/include/
/usr/src/sbin/geom/class/
/usr/src/sbin/mount/
После чего добавляем в конфиг ядра строчку:
options UFS_GJOURNAL
Компилируем ядро, ставим, перезагружаемся...
После перезагрузки подгружаем необходимый модуль командой
# gjournal load
либо:
# kldload geom_journal.ko
(команды эквивалентны)
Далее нам необходимо размонтировать раздел, на который мы собираемся поставить журнал.
Пусть это будет '/dev/ad0s3d' и точка монтирования '/mnt/work':
# umount -f /mnt/work
Теперь собстенно "прикручиваем" журнал:
# gjournal label /dev/ad0s3d
Монтируем командой:
# mount -o async,gjournal /dev/ad0s3d.journal /mnt/work
NB! префикс '.journal' появляется при наличии в памяти модуля geom_journal.ko.
Поэтому, если вы захотите чтобы система автоматически монтировала раздел с поддержкой журнала:
пропишите в файл /boot/loader.conf строчку:
geom_journal_load="YES"
и соответствующую запись в fstab. Для данного примера она будет выглядеть так:
/dev/ad0s3d.journal /mnt/work ufs rw,async,journal 2 2
Все, готово!
(C) 2006 Sokolov Alexey <nullbsd at gmail.com>
mount -u -o snapshot ./snapshot_image /var
mdconfig -a -t vnode -f ./snapshot_image -u 1
mount -o ro /dev/md1 /mnt/snap
...
umount /mnt/snap
mdconfig -d -u 1
Также можно использовать специализированную утилиту snapshot,
представляющую собой фронтенд к mount и mdconfig.
В single mode: "/sbin/tunefs -a enable /fs"
Пересобираем ядро с "options UFS_ACL"
getfacl - просмотр ACL
setfacl - установка ACL
Например: setfacl -m user:nobody:rw-,group:wheel:rw- acl-test
LVM - позволяет гибко создавать, удалять и изменять размеры разделов без потери данных.
ext3 - расширение ext2 для журналирования. Поддерживает журналирование данных, а не только метаданных (при data=journal).
reiserfs - высокая скорость работы с каталогами с большим числом файлов, компактно хранит хвосты от файлов,
поддерживает увеличение размера раздела без остановки сервера.
xfs - быстрая работа с файлами большого размера, великолепная надёжность, поддержка ACL.
- Включаем поддержку Reiserfs в ядре.
- Устанавливаем reiserfsprogs-3.x.0j.tar.gz
- Cоздаем бут дискету (mkbootdisk --device /dev/fd0 2.4.13;
lilo -C /etc/lilo.flop)
- Грузимся с дискеты указав в Lilo приглашении "linux root=/dev/hd init=/bin/bash"
- mkreiserfs /dev/hda1
- mount -t reiserfs /dev/had1 /
Выкачиваем и накладываем ext3 патчи (ftp://ftp.kernel.org/pub/linux/kernel/people/sct/ext3/) и
утилиты (ftp://download.sourceforge.net/pub/sourceforge/e2fsprogs/).
Преобразуем ext2 FS в ext3 (для отмонтированного раздела hda1):
tune2fs -j /dev/hda1
Обратное преобразование (из ext3 в ext2):
tune2fs -O ^has_journal /dev/hda1
fsck.ext2 -f /dev/hdaX
Для форматирование нового ext3 раздела:
mke2fs -j /dev/hda1
Как обновить версию журнала:
mount /dev/hdaX /mnt -o journal=update
FreeBSD:
boot -s
Solaris:
stop+a
bo: boot -s
Linux:
left-alt для lilo
boot: linux -b rw sushell=/sbin/sash single
(можно init=/bin/sh)
UnixWare:
Во время загрузки пробел
[boot] INITSTATE=s
go
Если консоль зависла, машина работает, но не откликается на CTRL-ALT-BKSPC, ALT-CTRL-F1, CTRL-ALT-DEL
и по сети зайти на машину тоже нет возможности.
"ALT + SysReq + r" - перевести клавиатуру в Raw режим.
"ALT + SysReq + s" - сбросить буферы FS на диск (может занять много времени, если система сильно загружена).
"ALT + SysReq + e" - отправить сигнал завершения работы процессам.
"ALT + SysReq + i" - принудительно убить процессы не желающие завершить работу по сигналу KILL.
'ALT + SysReq + u' - отмонтировать дисковые разделы.
'ALT + SysReq + b' - перезагрузить машину.
PS. Клавиша SysReq совпадает с Print Screen.
initrd - RAM-диск, инициализируемый загрузчиком, требуется для подключения модулей ядра, необходимых
на этапе до монтирования root-раздела, (например, до монтирования нужно подгрузить - ext2/ext3/scsi модули).
1) man initrd - все изумительно описано;
2) после сборки ядра создаем новый initrd:
mkinitrd /boot/initrd-2.4.21 2.4.21;
3) в /etc/lilo.conf:
initrd=/boot/initrd-2.4.21
В mkinitrd сам initrd можно назвать как угодно, но второй параметр обязательно версия ядра.
Linux IDE # Linux SCSI # FreeBSD 4
mknod /dev/hda b 3 0 # /dev/sda b 8 0 # /dev/ad0 b 116 0x00010002
mknod /dev/hda1 b 3 1 # /dev/sda1 b 8 1 # /dev/ad0s1 b 116 0x00020002
mknod /dev/hda2 b 3 2 # /dev/sda2 b 8 2 # /dev/ad0s1a b 116 0x00020000
mknod /dev/hdb b 3 64 # /dev/sdb b 8 16 # /dev/ad0s1b b 116 0x00020001
mknod /dev/hdb1 b 3 65 # /dev/sdb1 b 8 17 # /dev/ad0s1c b 116 0x00020002
mknod /dev/hdc b 22 0 # /dev/sdc b 8 32 # /dev/ad1s1a b 116 0x00020008
mknod /dev/hdd b 22 64 # /dev/sdd b 8 48 # /dev/da1s1a b 13 0x00020000
Добавьте в /etc/rc.d/rc.local:
echo 1 > /proc/sys/kernel/panic
Т.е. перезагрузка будет выполнена через 1 сек. после panic, если 0 - то не перезагружать а ждать.
Расскажу о двух возможностях, которые можно реализовать на роутере
с прошивкой DD-WRT на примере роутера Linksys WRT54GL.
1) Файловая система JFFS.
На роутере можно без труда организовать небольшое энергонезависимое хранилище файлов.
Для этого в веб-интерфейсе включаем поддержку jffs (по туториолу из официального вики dd-wrt):
1. Откройте вкладку "Administration".
2. Перейдите к секции "JFFS2 Support".
3. Кликаем "Enable JFFS".
4. Затем жмём "Save".
5. Ждём несколько секунд и жмём "Apply".
6. Опять ждём. Идём обратно к опции "Enable JFFS", кликаем "Clean JFFS".
7. Не кликая "Save", жмём вместо этого "Apply".
Теперь если мы приконнектимся к роутеру по ssh команда "df -h" расскажет нам о наличие новой файловой системы,
смонтированной в каталоге /jffs/, и её размере (размер очень сильно зависит от типа вашей прошивки,
для получения хоть сколько-нибудь полезного свободного пространства для jffs рекомендуется установить mini-версию dd-wrt).
2) Индикация активности wifi по лампе на корпусе роутера.
Теперь используем возможности jffs - разместим на ней скрипт (с того же вики dd-wrt), который заставляет
гореть лампу янтарным светом при подключенных wifi-клиентах и мигать белым при трансфере данных через WLAN.
Для установки скрипта:
1. Коннектимся по ssh.
2. Переходим в каталог /jffs/ и создаем директорию bin:
# cd /jffs/
# mkdir ./bin
3. Как видно /jffs/bin уже прописан в переменной поиска команд PATH:
# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/jffs/sbin:/jffs/bin:/jffs/usr/sbin:/jffs/usr/bin
4. Создаем файл скрипта (# vi ./wlan.sh) со следующим содержанием:
#!/bin/sh
I=`nvram get wl0_ifname`
while sleep 1; do
if [ "`wl assoclist`" != "" ]; then
XFER=`ifconfig $I|grep bytes`
if [ "$XFER" != "$PXFER" ]; then
LED='gpio disable 3 ; gpio disable 2'
PXFER=$XFER
else
LED='gpio disable 3 ; gpio enable 2'
fi
else
LED='gpio enable 3 ; gpio enable 2'
fi
if [ "$LED" != "$PLED" ]; then
eval $LED
PLED=$LED
fi
done
5. Делаем скрипт исполняемым:
# chmod +x ./wlan.sh
Готово!
Скрипт теперь можно запускать командой wlan.sh или прописать в автозагрузку.
Оригинал в блоге по ссылке: http://damnsmallblog.blogspot.com/2008/03/jffs-wifi-linksys-wrt54gl.html
Не смотря на то, что в EeePС нет встроенного bluetooth адаптера,
к нему легко можно подключить внешний bluetooth брелок с USB интерфейсом.
Все необходимые консольные приложения доступны после установки пакета:
apt-get install bluez-utils
К сожалению для eeepc отсутствуют GUI хелперы для связывания устройств,
из того что есть в репозиториях debian etch и xandros (например kdebluetooth),
из-за проблем с зависимостями пакетов, подходит только bluez-gnome.
Если bluetooth устройство самостоятельно может инициировать связывание,
то все нормально, если нет - при попытке связать устройства используя только консольные
средства начинаются проблемы, в bluez 3.x был изменен механизм связывания устройств,
если ранее достаточно было создать простой скрипт для вывода PIN и прописать в options
секцию hcid.conf - "pin_helper /etc/bluetooth/feed-pin.sh;", то теперь для получения PIN
используется DBUS. В комплекте с bluez поставляется программа passkey-agent,
предназначенная для связывания устройств, в пакет bluez-utils в Debian GNU/Linux эта программа
по каким-то соображениям не была включена. Исходные тексты программы можно найти в
/usr/share/doc/bluez-utils/examples, но для сборки потребуется установка окружения для сборки программ,
что в условиях небольшого SSD диска не вполне оправдано. Запускается агент примерно так:
passkey-agent --default 1234
где, 1234 пароль для связывания.
Выход нашелся в апплете bluetooth-applet, который входит в состав пакета bluez-gnome.
Запустив который при попытке связывания появляется диалоговое окно для ввода пароля связывания.
Для настройки GPRS через сотовый телефон с Bluetooth интерфейсом можно использовать пакет 3egprs
(устанавливает иконку на десктоп и скрипт /usr/sbin/gprsconf) с сайта http://www.3eportal.com/
Другой вариант - инициирование ppp сессии из консоли. Ниже пример настройки:
Подключаем bluetooth адаптер в USB порт. Через dmesg смотрим, нашелся ли дня него драйвер.
Запускаем инициализацию bluez:
/etc/init.d/bluetooth start
Смотрим поднялся ли интерфейс:
hciconfig
Если статус down, поднимаем его:
hcicofig hci0 up
Сканируем доступные устройства:
hcitool scan
Запоминаем адрес устройства. Для примера проверяем его доступность:
l2ping 00:0A:0B:0C:0D:0E
Адрес можно посмотреть командой:
hcitool dev
а определить поддерживаем ли bluetooth устройство GPRS:
sdptool search DUN
Создаем rfcomm интерфейс:
rfcomm bind 0 [полученный адрес] 1
По идее rfcomm должен создаться автоматически, при надлежащей настройке /etc/bluetooth/rfcomm.conf,
например:
rfcomm0 {
bind yes;
device 00:0A:0B:0C:0D:0E;
channel 1;
comment "Mobile";
}
Далее создаем файл конфигурации для pppd, /etc/ppp/peers/mts:
lcp-echo-failure 0
lcp-echo-interval 0
/dev/rfcomm0
connect "/usr/sbin/chat -v -f /etc/ppp/peers/gprs"
115200
crtscts
debug
ipcp-accept-local
noauth
usepeerdns
defaultroute
noipdefault
nodetach
/etc/ppp/peers/gprs:
ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT
'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED
'' 'AT'
'OK' 'AT+CGDCONT=1,"IP","internet.mts.ru"'
'OK' 'ATDT*99***1#'
TIMEOUT 30
CONNECT
Для beeline заменяем "internet.mts.ru" на "internet.beeline.ru", для мегафона пишем просто "internet".
Подключаемся выполнив команду:
pppd call mts
Перевод wiki-страницы о настройке Bluetooth в Asus EeePC, выполненный
Сгибневым Михаилом,
можно найти на странице: http://www.opennet.ru/base/modem/bluetooth_eeepc.txt.html
идем в
cd /usr/src/linux-*/drivers/media/dvb/dvb-core
открываем файл dvb_frontend.c
находим строчку static int dvb_powerdown_on_sleep = 1;
изменяем на static int dvb_powerdown_on_sleep = 0;
компилируем и ставим ;)
теперь не нужно модуль dvb-core загружать с параметром
dvb_shutdown_timeout=0
После установки Ubuntu 8.04 по умолчанию не работают беспроводные карты на базе чипов Broadcom BCM43xx из-за отсутствия firmware.
Начиная с Linux ядра 2.6.24 работу данных карт в Linux обеспечивает драйвер b43,
в более ранних версиях использовался драйвер bcm43xx.
Для включения работы карты нужно установить пакет b43-fwcutter и получить firmware:
sudo apt-get install b43-fwcutter
и активировать на ноутбуке адаптер.
Также можно воспользоваться меню Menu / System / Administration / Hardware Drivers.
Драйвером b43 поддерживаются чипы:
* bcm4303 (802.11b)
* bcm4306
* bcm4309 (только 2.4GHz)
* bcm4311 rev 1 / bcm4312
* bcm4311 rev 2 / bcm4312 (с 2.6.24 ядром работает через доп. патчи)
* bcm4318
В настоящее время нет поддержки:
* 802.11a для серий 4309 и 4312;
* BCM 4328/4329
* не реализованы возможности представленные в проекте стандарта 802.11n;
Сайт разработчиков драйвера: http://wireless.kernel.org/en/users/Drivers/b43
Решение представлено для Gentoo, но возможно проблема актуальна и для других дистрибутивов.
При обновлении hal до версии 0.5.10 перестает нормально работать
клавиатура. По множественным отзывам в Сети, у всех перестает
работать преключатель раскладки, у меня еще были глюки с другими
клавишами (например кнопка "вверх" работала как PrtScr и др.)
Для начала приведу часть xorg.conf который у меня работал испокон веков:
Section "InputDevice"
Identifier "Chicony"
Driver "kbd"
Option "Protocol" "Standard"
Option "XkbModel" "pc105"
Option "XkbRules" "xorg"
Option "XkbLayout" "us,ru,ua"
Option "XkbVariant" ",winkeys"
Option "XkbOptions" "grp:lwin_toggle,grp_led:scroll"
Option "AutoRepeat" "250 30"
EndSection
Причина того, что эта конфигурация отвалилась, состоит в том, что новая
версия hal просто игнорирует конфиг xorg.conf.
Нашел два метода решения проблемы.
Первый метод:
http://ru.gentoo-wiki.com/HOWTO_hal_и_устройства_ввода
Смысл в том, что создается файл политики hal, который содержит конфигурацию клавиатуры:
/usr/share/hal/fdi/policy/20thirdparty/10russian-layout.fdi
Учитывая, что в статье есть небольшие ошибки, приведу свой файл
конфигурации. Рекомендую сопоставлять с приведенным выше xorg.conf
<?xml version="1.0" encoding="ISO-8859-1"?><!-- -*- SGML -*- -->
<match key="info.capabilities" contains="input.keyboard">
<merge key="input.x11_driver" type="string">kbd</merge>
<merge key="input.xkb.model" type="string">pc105</merge>
<merge key="input.xkb.rules" type="string">xorg</merge>
<merge key="input.xkb.layout" type="string">us,ru</merge>
<merge key="input.xkb.variant" type="string">,winkeys</merge>
<merge key="input.xkb.options" type="strlist">grp:lwin_toggle,grp_led:scroll</merge>
</match>
Думаю смысл понятен.
После создания файла следует пергрузить hald и перегрузить иксы.
Недостаток этого метода состоит в том, что я так и не смог настроить переключение трех языков.
Второй метод:
Второй метод состоит в том, что мы отключаем автоопределение
устройств. Для этого в xorg.conf в секцию ServerLayout дописываем
Option "AutoAddDevices" "False". После перегрузки иксов настройки
клавиатуры берутся из xorg.conf.
Подозреваю, что у второго метода есть свои недостатки, но я их пока не обнаружил.
1. Устанавливаем ndiswrapper:
sudo apt-get install ndiswrapper-common ndiswrapper-utils-1.9
2. Распаковываем куда нибудь Windows драйверы и пишем из под пользователя root такие команды:
ndiswrapper -i bcmwl5.inf
modprobe ndiswrapper
echo "blacklist bcm43xx" >> /etc/modprobe.d/blacklist
echo "ndiswrapper" >> /etc/modules
3. Перегружаемся и проверяем. Все должно работать.
При установке сетевой карточки Asus NX1001, я не смог обнаружить её при наборе
команды ifconfig. А также в sysinstall->Configure->Networking.
Первое, что мне пришло в голову конфликт с ACPI, после отключения в БИОСе ACPI -
результатов никаких не дало. Поэтому пришлось заняться поисками решения
этой проблемы копаясь в интернете, особо на сайте freebsd.org. Найдя похожую
проблему работы с сетевой картой Asus NX1001 в FreeBSD 6.2, вот что в итоге
необходимо было сделать.
Набрав команду pciconf -lv и найдя среди результатов вывода
"Sundance ST201 10/100BaseTX".
Мне пришлось дописать в файлах:
/usr/src/sys/pci/if_ste.c
/usr/src/sys/pci/if_stereg.h
нижеследующее (строка AS_VENDORID...), в файле if_ste.c:
static struct ste_type ste_devs[]={
{ST_VENDORID, ST_DEVICEID_ST201,"Sundance ST201 10/100BaseTX"},
{AS_VENDORID, AS_DEVICEID_NX1001,"ASUS NX1001 10/100BaseTX"},
{DL_VENDORID, DL_DEVICEID_DL100050,"D-Link DL10050 10/100BaseTX"},
{0,0,NULL}
};
в файле if_stereg.h:
#define AS_VENDORID 0x13F0
#define AS_DEVICEID_NX1001 0x0200
После этого мы обязаны пересобрать наше старое ядро:
cd /usr/src/sys/i386/conf/
cp GENERIC GATEWAY
ee GATEWAY
config GATEWAY
cd ../compile/GATEWAY
make depend
make
make install
shutdown -r now
В итоге в нашем случае появляется сетевая карточка в устройствах как sto0.
Настройка линукса для работы с телефоном Nokia, подключеным к системе через USB кабель.
В этой статье будем настраивать линукс для работы с вашим телефоном Nokia,
подключеным к системе через USB кабель. Система Ubuntu Feisty Linux 7.04,
хотя аналогичным образом можно настроить в любом другом дистрибутиве.
1) Ставим необходимый софт:
apt-get install obexftp openobex-apps
2) Далее в консоли:
lsusb
на выходе получаем:
Bus 003 Device 003: ID 0421:043a Nokia Mobile Phones
из этого узнаем VendorID и ProductID:
VendorID = 0421
ProductID = 043a
3) Прописываем эти данные в /etc/udev/rules.d/040-permissions.rules:
sudo vim /etc/udev/rules.d/040-permissions.rules
в конец файла вписываем:
BUS=="usb", SYSFS{idVendor}=="VendorID", SYSFS{idProduct}=="ProductID", GROUP="plugdev", USER="yourUserNname"
VendorID и ProductID заменяем нашими данными полученными выводом команды lsusb
USER="имя пользователя под которым вы работаете в системе"
4) Создаём кнопку запуска на рабочем столе. В её свойствах прописываем:
java -jar /home/YOURUSERNAME/obexftp-frontend-0.6.1-bin/OBEXFTPFrontend.jar
YOURUSERNAME меняем на вашу домашнюю папку
5) Запускаем /usr/bin/obexftp
В вкладке Transport выбираем USB, Value 1
Далее OK.
Всё, настройка закончена. Запускаем программу через созданную нами на рабочем столе кнопку запуска.
В появившемся окошке видим drive c: - это наша memory card. Процесс закачки и выгрузки файлов понятен интуитивно.
Удачной работы!:)
Как ни странно, но в ноутбуках с аудио чипсетом 82801G от Intel (фирмы с которой обычно нет проблемм)
под линуксом не работает звук. Причём проблемма существует на любых дистрибутивах
(проверено при прочтении форумов с аналогичной проблеммой) и на ноутах самых разных производителей.
ОС на которых мы пытались завести звук: Ubuntu 7.04 Feisty, Ubuntu 7.10 Gutsy, Fedore Core 7.
Ноутбуки на которых люди столкнулись с проблеммой отсутствия звука на 82801G: Acer aspire 5310,
Acer Aspire 3682, Acer TravelMate 2490, Toshiba L40-13G, Sony Vaio SZ110,
Compaq nx7400, IBM Thinkpad Z61m и многие другие...
Во всех системах признаки одни и те же: если звук появляется, то тихий и из левой колонки слышен пронзительный "свист".
Если переместить ползунок регулировки громкости - звук пропадает совсем.
Данное решение проблеммы описано на модели Toshiba L40-13G
И так,
$lspci |grep Audio
выдаёт нам следующее:
00:1b.0 Audio device: Intel Corporation 82801G (ICH7 Family) High Definition Audio Controller (rev 02)
Решение давольно простое:
В Ubuntu:
$sudo vim /etc/modprobe.d/alsa-base
добавить в конце файла строку
options snd-hda-intel model=3stack
в FedoraCore $sudo vim /etc/modprobe.conf
там где options snd-hda-intel ... в конце строки добавить model=3stack
в других дистрибутивах делать аналогично
далее $sudo update-modules или перезагрузка и должно всё работать:)
Выбор.
Меня интересовала не просто работа микрофона и динамика, но и как минимум клавиатуры.
Выбор пал на Skypemate p1K (в девичестве Yealink), как не на очень дорогой апппарат,
при этом имеющий как полноценную клавиатуру ("как у мобильника"), так и простенький ЖК-дисплей.
Ко всему прочему поддержка именно этого девайса в linux наиболее развита.
Настройка.
Поддержка собственно звука не требует практически никакой настройки.
Девайс определяется как новая звуковая карта:
-bash-2.05b# cat /proc/asound/cards
....
USB-Audio - VOIP USB Phone
Yealink Network Technology Ltd. VOIP USB Phone at usb-0000:00:03.0-3
В SIP-клиенте достаточно выбрать например "/dev/dsp2" в качеcтве динамика/микрофона.
Что касается клавиатуры, то с этим ситуация несколько сложней.
Есть несколько проектов разной степени работоспособности:
1. SkypeMate (http://skypemate.ru/support/docs/) - официальный драйвер.
Бинарный, только для FedoraCore 3 (требует старый dbus-0.23).
Плюс ко всему только для Skype. Отдельные джидаи запускали его на современных дистрибутивах
с подменой либы dbus, с периодическими сегфолтами, я с этим заморачиваться не стал.
2. USBB2K-API (http://savannah.nongnu.org/projects/usbb2k-api/) - неофициальный драйвер. По отзывам пользователей - работает,
однако у меня он не завелся. Девайс определялся, команды на телефон шли,
однако обратной связи не наблюдалось. При этом на форумах отписывали пользователи с аналогичной
проблемой, разработчики пытались им даже помочь, но дело там так и не сдвинулось с мертвой точки.
3. yealink-module (http://savannah.nongnu.org/forum/forum.php?forum_id=4319) - как видно из названия модуль для ядра.
Последняя версия из CVS у меня собралась лишь после жесткой правки исходников и
после этого кончено нормально не работала, однако релиз за номером 0861 собрался сразу и
без проблем был установлен. Замечу, что поддержка клавиатуры в нем реализована просто и универсально:
клавиши телефона дублируют клавиши клавиатуры (цифровые, backspace, enter и т.д.)
Оригинал статьи (со ссылками) здесь: http://damnsmallblog.blogspot.com/2007/07/usb-linux.html
Принтеры HP LaserJet 1000,1005,1018,1020 после включения должны загрузить бинарный firmware драйвер.
Если прошивка по каким-то причинам не загружена
(загрузка обычно устанавливается в автомате через hotplug),
то вывод usb_printerid будет примерно таким
nik@linuxdvr:~$ usb_printerid /dev/usb/lp0
GET_DEVICE_ID string:
MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CMD:ACL;CLS:PRINTER;DES:HP LaserJet 1020;
без упоминания версии прошивки в конце строки (FWVER:20041129;)
Устанавливаем штатный deb-пакет foo2zjs
он ставит все что нужно, за исключением самой прошивки
и в логе tail -n 20 /var/log/messages вы увидите что-то подобное
Mar 20 12:35:34 linuxdvr kernel: usbcore: registered new driver usblp
Mar 20 12:35:34 linuxdvr kernel: drivers/usb/class/usblp.c: v0.13: USB Printer Device Class driver
Mar 20 12:35:35 linuxdvr /usr/bin/hplj1020: Missing HP LaserJet 1020 firmware file /usr/share/foo2zjs/firmware/sihp1020.dl
Mar 20 12:35:35 linuxdvr /usr/bin/hplj1020: ...read foo2zjs installation instructions and run ./getweb 1020
Выполняю:
nik@linuxdvr:~$ getweb 1020
в итоге c инета сайта foo2zjs качается прошивка и сохраняется как sihp1020.img
конвертируем этот бинарник в нужный формат
nik@linuxdvr:~$ arm2hpdl sihp1020.img > sihp1020.dl
далее копируем куда нужно
nik@linuxdvr:~$ sudo mv sihp1020.dl /usr/share/foo2zjs/firmware/
и корректируем владельца группу
nik@linuxdvr:~$ sudo chown root:root /usr/share/foo2zjs/firmware/sihp1020.dl
Включаем и выключаем принтер и в логе tail -n 20 /var/log/messages видим
Mar 20 12:57:18 linuxdvr /usr/bin/hplj1020: loading HP LaserJet 1020
firmware /usr/share/foo2zjs/firmware/sihp1020.dl to /dev/usb/lp0 ...
Mar 20 12:57:19 linuxdvr /usr/bin/hplj1020: ... download successful.
Проверяем:
nik@linuxdvr:~$ usb_printerid /dev/usb/lp0
GET_DEVICE_ID string:
MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CMD:ACL;CLS:PRINTER;DES:HP LaserJet 1020;FWVER:20041129;
FWVER:20041129; - это версия успешно загруженной прошивки
Все, теперь идем в KDE, GNOME или ... и запускаем ОТ ROOT-а гуёвые мастера для добавления принтера.
На всякий случай, привожу установленные в Debian Etch пакеты для печати на HP1020 через CUPS.
nik@linuxdvr:~$ aptitude search "foo|cups|foo2" | grep "^i"
i cupsys - Common UNIX Printing System(tm) - server
i cupsys-bsd - Common UNIX Printing System(tm) - BSD comm
i cupsys-client - Common UNIX Printing System(tm) - client p
i A cupsys-common - Common UNIX Printing System(tm) - common f
i cupsys-driver-gutenprint - printer drivers for CUPS
id foo2zjs - Support for printing to ZjStream-based pri
i A foomatic-db - linuxprinting.org printer support - databa
i foomatic-db-engine - linuxprinting.org printer support - progra
i foomatic-db-gutenprint - linuxprinting.org printer support - databa
i foomatic-db-hpijs - linuxprinting.org printer support - databa
i A foomatic-filters - linuxprinting.org printer support - filter
i foomatic-filters-ppds - linuxprinting.org printer support - prebui
i foomatic-gui - GNOME interface for configuring the Foomat
i gnome-cups-manager - CUPS printer admin tool for GNOME
i A libcupsimage2 - Common UNIX Printing System(tm) - image li
i A libcupsys2 - Common UNIX Printing System(tm) - libs
i A libgnomecups1.0-1 - GNOME library for CUPS interaction
i A libgnomecupsui1.0-1c2a - UI extensions to libgnomecups
i A python-foomatic - Python interface to the Foomatic printer d
(С) Андрей Никитин, 2007
Перепечатка и цитирование допускаются только с разрешения автора.
Установка CentOS 4.4 (RHEL AS 4.4) и FC 6 на материнские платы с чипсетом Intel P965 & Intel ICH8R с IDE-CDROM'a.
1.Установить в BIOS режим AHCI для Intel ICH8R и Jmicron JMB363
2.На подсказке
boot:linux all-generic-ide pci=nommconf
3. Cпецифицировать во время графической установки
Kernel boot options :
all-generic-ide pci=nommconf
При установке GRUB в /boot partition выполнить:
boot:linux all-generic-ide pci=nommconf rescue
...................
# chroot /mnt/sysimage
# df -h
/dev/sdaX ....... /boot
.............................
# dd if=/dev/sdaX of=linux.bin bs=512 count=1
# mcopy linux.bin a:
Такой стиль установки позволяет системам успешно определять
IDE-CDROM не только при установке , но и в рабочем режиме.
Все статьи на opennet описывают создание модуля NDIS для FreeBSD старым методом:
ndiscvt -i *.inf -s *.sys -o ndis_driver_data.h
Данный способ уже давно устарел и теперь нужно использовать программу ndisgen.
Например. Имеем файлы из комплекта Windows драйверов:
Fw1130.bin - Network interface firmware.
FwRad16.bin - Radio firmware.
TNET1130.INF - Driver information file.
tnet1130.sys - Driver binary.
Старый способ:
cd /sys/modules/ndis
make depend
make
make install
cd ../if_ndis
ndiscvt -i TNET1130.INF -s tnet1130.sys -f Fw1130.bin -o ndis_driver_data.h
make depend
make
make install
ndiscvt -f FwRad16.bin
cp FwRad16.bin.ko /boot/kernel
kldload FwRad16.bin
kldload if_ndis
Для автоматизации загрузки помещаем в /boot/loader.conf
FwRad16.bin_load="YES"
if_ndis_load="YES"
Новый способ (не требует установки исходных текстов ядра):
ndisgen
... отвечаем на интерактивные вопросы, на выходе получаем tnet1130_sys.ko
cp tnet1130_sys.ko /boot/kernel/
kldload ndis
kldload if_ndis
kldload tnet1130_sys
Для автоматизации загрузки помещаем в /boot/loader.conf
ndis_load="YES"
if_ndis_load="YES"
tnet1130_sys_load="YES"
cat /proc/acpi/sleep
S0 S3 S4 S4bios S5
Первым делом попробовать:
echo 4b > /proc/acpi/sleep
Если не получилось, ядро нужно грузить с параметрами "noapic acpi_sleep=s3_bios"
Далее если в ядро входят патчи swsusp
(/dev/hda5 - swap раздел, который должен быть раза в два больше ОЗУ):
append=" resume=/dev/hda5"
или для swsusp2: append=" resume2=swap:/dev/hda5"
Если swsusp перестал вообще грузить систему,
используйте параметр ядра "noresume" для игнорирования resume образа.
# Сохраняем статус видеокарты (http://www.srcf.ucam.org/~mjg59/vbetool/)
vbetool vbestate save > ~/VBESTATE
# Засыпаем.
echo 3 > /proc/acpi/sleep
# Восстанавливаем статус видеокарты после просыпания.
vbetool post
vbetool vbestate restore < ~/VBESTATE
Другой вариант засыпания:
echo "mem" >> /sys/power/state
echo "disk" >> /sys/power/state
После просыпания лучше перезапустить hotplug:
service hotplug restart
Еще лучше до засыпания остановить, а после просыпания загрузить сервисы:
usb acpid sound irda pcmcia
Можно скачать готовый скрипт hibernate с http://www.suspend2.net/downloads/all/
Для засыпания по закрытию крышки, создаем /etc/acpi/events/lid
event=button[ /]lid.*
action=echo "3" > /proc/acpi/sleep
При нажатии на кнопку питания, создаем /etc/acpi/events/powerbtn
event=button[ /]power.*
action=echo "3" > /proc/acpi/sleep
Советы по экономии батареи для ноутбуков на базе Pentium Mobile Centrino:
http://wiki.teuwen.org/DebianLaptop
Устанавливаем поддержку bluetooth (проект Bluez):
yum install bluez-libs bluez-pin bluez-utils bluez-hcidump bluez-utils-cup
Устанавливаем утилиты звуковой подсистемы ALSA:
yum install alsa-tools alsa-lib alsa-utils alsa-lib-devel
Устанавливаем automake (понадобится для сборки BTSCO)
yum install automake
Проверяем на сайте http://bluetooth-alsa.sourceforge.net/ поддерживается ли наша гарнитура (Jabra BT200 поддерживается).
Запускам hcitool и смотрим активна ли bluetooth подсистема.
Подключаем гарнитуру и запускаем "hcitool scan", смотрим MAC адрес в результатах вывода.
Далее, подключаем через:
hcitool cc MAC
Все должно работать, но на случай проблем, пример некоторый файлов из /etc/bluetooth:
hcid.conf
options {
autoinit yes;
security user;
pairing multi;
# PIN helper
pin_helper /etc/bluetooth/feed-pin.sh;
# D-Bus PIN helper
#dbus_pin_helper;
}
device {
name "%h-%d";
# Local device class
class 0x120104;
# Inquiry and Page scan
iscan enable; pscan enable;
lm accept;
lp rswitch,hold,sniff,park;
# Authentication and Encryption (Security Mode 3)
auth enable;
encrypt enable;
}
rfcomm.conf
rfcomm0 {
# Automatically bind the device at startup
bind no;
# Bluetooth address of the device
device 11:11:11:11:11:11;
# RFCOMM channel for the connection
channel 1;
# Description of the connection
comment "Bluetooth Device
}
/etc/bluetooth/feed-pin.sh
#!/bin/sh
echo "PIN:0000"
Установка BTSCO из исходных текстов.
Получаем исходные тексты из CVS:
cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/bluetooth-alsa log
cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/bluetooth-alsa co btsco
Собираем утилиты:
./bootstrap
./configure
make
make install
make maintainer-clean
Собираем модуль ядра:
cd kernel
make
make install
depmod -e
make clean
Подгружаем модуль ядра:
modprobe snd-bt-sco
Подключаемся к гарнитуре:
btsco -v MAC
Небольшой скрипт для автоматизации запуска skype:
#!/bin/sh
modprobe modprobe snd-bt-sco
btsco MACofHeadset
skype
После удачно завершившейся разборки с "multiple LUN support" для доступа к девайсам карт-ридеров
(MAUSB-300 производства OLYMPUS и безымянный "11 in 1" Тайваньского производства) оказалось,
что карты xd-Picture (OLYMPUS) и SD (Transcedent), отформатированные в соответствующих аппаратах
(фотокамера CAMEDIA C55ZOOM, и наладонник PalmOne Tungsten E2) монтироваться всё-таки не хотят.
По выяснении обстоятельств оказалось что монтировать их нужно с указанием параметра offset:
xd 16Mb - 20992 (0x5200)
xd 128Mb - 24064 (0x5E00)
xd 256Mb - 25088 (0x6200)
sd 128Mb - 49664 (0xC200)
sd 256Mb - 51712 (0xCA00)
т.е., например, вот так:
> mount -t vfat -o loop,offset=20992 /dev/sda /mnt/ttt
После модификации содержимого карт (добавления/удаления файлов),
смонтированных таким образом соответствующие аппараты не высказывают к этому самому содержимому
(и к файловой системе карт) никаких претензий, т.е. читают его и понимают правильно.
FreeBSD:
/boot/kernel.conf (для карты на 0x300 порту, прерывание 10, IO адрес 0xd8000):
en ed0
po ed0 0x300
ir ed0 10
iom ed0 0xd8000
f ed0 0
q
Linux:
modprobe 3c501 io=0x300 irq=10
или в /etc/modules.conf
alias eth0 3c501
options 3c501 io=0x300 irq=10
Если карта PNP (пакет isapnptools), параметры смотрим через pnpdump и помещаем в /etc/isapnp.conf.
получим кучу несжимаемых данных
dd if=/dev/urandom of=random.dat bs=1M count=БОЛЬШЕРАЗМЕРАОЗУ
bzip2 -c < random.dat > random2.dat.bz2
распакуем в /dev/null (можно и на диск конечно)
bzip2 -dc < random2.dat.bz2 > /dev/null
Сбой обычно выглядит так:
bzcat: Data integrity error when decompressing.
Есть два способа как заставить MPX200 работать с Linux: IrDA и wince-usb.
1. Подключение через IrDA (SIR):
Устанавливаем параметры для SiR порта
/bin/setserial /dev/ttyS1 port 0x6f8 irq 3 uart 8250 baud_base 115200
irattach /dev/ttyS1 -s
Для RedHat-based Linux дистрибутивов делаем проще:
В /etc/sysconfig/irda
IRDA=yes
DEVICE=/dev/ttyS1
DISCOVERY=yes
# service irda start
Запускем демон синхронизации (не из под root). Качаем с http://synce.sourceforge.net
$ dccm
Если используется пароль запускаем как "dccm -p пароль"
Один раз указываем используемый порт.
# synce-serial-config ircomm0
Стартуем pppd (про hotplug, ниже)
# synce-serial-start
Проверяем.
$ pstatus
Version
=======
Version: 4.20.0 (Microsoft Windows Mobile 2003 for Pocket PC Phone Edition (?))
Platform: 3 (Windows CE)
.....
Завершаем сеанс
# synce-serial-abort
2. Подключение по USB. Для 2.4.x ядра используем user space драйвер wince-usb
http://cvs.sourceforge.net/viewcvs.py/synce/wince-usb/ + http://libusb.sourceforge.net
(последние 2.6.x ядра должны работать с модулями ipaq и usb-serial из коробки).
Патчим. В самом начале ipaqd.c меняем значения IPAQ_ENDPOINT на
#define IPAQ_ENDPOINT_IN 0x82
#define IPAQ_ENDPOINT_OUT 0x02
Далее в devlist[] добавляем
{ 0x045e, 0x00ce, "Motorola MPX200" },
Создаем /usr/local/bin/cebox.sh взяв пример из README к wince-usb, например:
#!/bin/sh
/usr/sbin/pppd nocrtscts local debug passive silent 192.168.1.1:192.168.1.2 ms-dns 192.168.1.1 noauth proxyarp
$ dccm
Подключаем телефон и сразу запускаем
# rmmod ipaq (пока не поправили hotplug)
# ipaqd 2>/var/log/ipaqd.log
Далее запускаем synce-serial-* как в предыдущем шаге.
3. Настройка HotPlug (чтобы все запускалось автоматически).
В /etc/hotplug/usb.agent добавляем после блока с "LABEL="USB product $PRODUCT":
if [ "$PRODUCT" = "45e/ce/0" ]; then
/etc/hotplug/usb/ipaq
exit 0
fi
Создаем /etc/hotplug/usb/ipaq
#!/bin/bash
killall -9 ipaqd
killall dccm
su -c /usr/bin/dccm /user/
/usr/local/bin/ipaqd 2>/var/log/ipaq.log
4. Стандартные команды synce:
pcp - копирование файлов (аналог cp)
pls - список файлов в директории (аналог ls)
pmkdir - создание директории (аналог mkdir)
pmv - перенос/переименование файлов (аналог mv)
prm - удаление файлов (аналог rm)
prmdir - удаление директорий
prun - запуск программы на устройстве
pstatus - статус устройства
synce-install-cab - установка на устройство .cab файла
orange - позволяет выдрать .cab из .exe инсталлера;
В Modnight Commander удобно использовать VFS понимающую команды
"cd #synce" и "cd #synceroot",
правда модуль раздаваемый на сайте synce у меня не заработал, пришлось его переписать:
ftp://ftp.opennet.ru/pub/sys/shell/synce-mcfs-patched/
Для работы, копируем файлы synce и synceroot в /usr/lib/mc/extfs
К extfs.ini добавляем:
synce
synceroot
Хорошая графическая оболочка для синхронизации календаря и адресной книги - MultiSync (http://multisync.sourceforge.net/)
Для работы с многокарточными кардридерами необходимо чтобы ядро было
собрано с опцией CONFIG_SCSI_MULTI_LUN=y или подгрузить модуль mod_scsi
с параметром max_scsi_luns=N, иначе Linux будет воспринимать только
первый слот кардридера.
Проверить можно, например, так:
zcat /proc/config.gz | grep CONFIG_SCSI_MULTI_LUN
Решение 1.
При использовании mod_scsi добавить в /etc/modules.conf:
options scsi_mod max_scsi_luns=4294967295
Решение 2.
Заставить ядро опрашивать больше одного LUN у одного устройства.
cat /proc/scsi/scsi и находим первый LUN нашего кардридера.
Host: scsi1 Channel: 00 Id: 00 Lun: 00
выбор цифр ^ ^ ^
Далее:
echo "scsi add-single-device 1 0 0 1" > /proc/scsi/scsi
echo "scsi add-single-device 1 0 0 2" > /proc/scsi/scsi
echo "scsi add-single-device 1 0 0 3" > /proc/scsi/scsi
...
Для удобства монтирования можно прописать в /etc/fstab:
/dev/sda1 /mnt/smcard auto user,noauto,noexec,mode=0444,rw,sync,codepage=866,iocharset=koi8-r 0 0
/dev/sdb1 /mnt/cfcard auto user,noauto,noexec,mode=0444,rw,sync,codepage=866,iocharset=koi8-r 0 0
/dev/sdc1 /mnt/sdcard auto user,noauto,noexec,mode=0444,rw,sync,codepage=866,iocharset=koi8-r 0 0
/dev/sdd1 /mnt/mscard auto user,noauto,noexec,mode=0444,rw,sync,codepage=866,iocharset=koi8-r 0 0
PS. Для 2.6.x ядра:
echo 8 > /sys/module/scsi_mod/parameters/max_luns
1. Просмотреть содержимое BIOS (проверял под Linux и FreeBSD)
dd if=/dev/mem bs=64k skip=15 count=1 | strings | less
в первых строчках обычно упоминается название материнской платы.
2. Воспользоваться утилитой dmidecode
pnpdump -c > isapnp.conf - дамп isa/pnp параметров
isapnp isapnp.conf - установить параметры после изменения isapnp.conf
lspci, lspci -v, lspci -vvv - список pci устройств.
scanpci или lspcidrake - найдет модули Linux ядра соответствующие устройствам (пакеты libhw-tools и ldetect).
lshw - покажет исчерпывающую информацию о USB и PCI устройствах.
setpci - поменять параметры pci устройства
cat /proc/iomem
cat /proc/ioports
cat /proc/interrupts
cu -s 2400 -e -o -h -l /dev/cuaa0 # 2400 Baud, 8 Data Bits, 1 Stop Bit, No Parity
Команды:
Y - переход в командный режим, только после Y будут выполняться остальные команды;
K - выключение UPS через 15-30 сек. (K, задержка 1 сек, К, задержка 1 сек, <CR>);
A, X, U и W - самотестироание;
R - окончание сессии;
L - Напряжение на входе;
O - Напряжение на выходе;
B - Вольтаж батареи;
F - Частота в сети, Hz;
M, N - максимальное и минимальное заргистрированное напряжение в сети;
P - потребление энергии в %;
C - температура.
Когда нет питания UPS шлет '!' каждые 5 секунд, если питание появилось - шлет '$'.
man umass
Конфигурация ядра (FreeBSD 4.8 можно не пересобирать):
device usb
device ohci (OR device uhci)
device umass
device scbus
device da
device pass
В логе смотрим подобное сообщение "da0 at umass-sim0 bus 0 target 0 lun 0"
Монтируем:
mount -t msdos /dev/da0s1 /mnt
Если добавление в lilo append="mem=1536M" не помогает:
Необходимо пересобрать 2.2.x ядро с опцией CONFIG_2GB=y
Processor type and features -> Maximum Physical Memory -> 2Gb
Если проблема проявляется в ядре 2.4.x - CONFIG_HIGHMEM, CONFIG_HIGHMEM4G или CONFIG_HIGHMEM64G
Linux поддерживает Hyper-Threading начиная с ядра 2.4.17.
Ядро должно быть собрано как SMP,
При загрузке, передаем параметр acpismp=force (в lilo: append=" acpismp=force")
проверка работы:
cat /proc/cpuinfo, если среди flags есть "ht", то Hyper-Threading активирован.
Для того чтобы на загруженный без PS/2 клавиатуры сервер, можно было в любой момент подключить клавиатуру
без перезагрузки, нужно в конфигурации ядра заменить строку:
device atkbd0 at atkbdc? irq 1 flags 0x1
на
device atkbd0 at atkbdc? irq 1
Т.е. убрать 'flags 0x1' и тем самым разрешить загружать драйвер клавиатуры
при отключенной в момент загрузки клавиатуре.
1. Скачать ati-driver-installer-8-5-x86.x86_64.run
2. В консоли выполнить для синхронизации списка пакетов, доступных в репозиториях:
sudo apt-get update
Затем, установить пакеты, необходимые для сборки модуля ядра из исходных текстов и создания deb пакета:
sudo apt-get install build-essential fakeroot dh-make debhelper debconf libstdc++5 dkms linux-headers-$(uname -r)
3. В консоли запускаем инсталлятор драйвера в режиме создания пакетов:
sudo sh ati-driver-installer-8-5-x86.x86_64.run --buildpkg Ubuntu/8.04
4. Теперь нужно занести в черный список драйвер fglrx из репозитория Ubuntu, выполняем
sudo gedit /etc/default/linux-restricted-modules-common
и в строке "DISABLED_MODULES" добавляем "fglrx"
получаем строку:
DISABLED_MODULES="fglrx"
сохраняем файл
5. далее в консоли устанавливаем подготовленные пакеты с драйвером:
sudo dpkg -i xorg-driver-fglrx_8.493*.deb fglrx-kernel-source_8.493*.deb fglrx-amdcccle_8.493*.deb
6. Перезагружаем X сервер.
7. проверяем:
$ fglrxinfo
display: :0.0 screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: Radeon X1900 Series
OpenGL version string: 2.1.7537 Release
PS: все вышесказанное проверялось на i386 конфигурации с видеокартой X1900,
для amd64 возможны небольшие отличая в установке.
Оригинал: http://pronix.isgreat.org/news.php?item.86.5
Простое решение для нотификации работы серверов при помощи ICQ:
1) Ставим vicq клиент. Регистрируем для него UIN. Из примера конфигурационного файла
создаем работающий конфиг. Обязательные параметры uin и password.
2) Настраиваем nagios для отсылки сообщений о проблемах:
а) Задаем для своего контакта параметр pager равный номеру вашего ICQ.
б) Задаем 2-е дополнительне комманды в commands.cfg
# ICQ Notification
define command{
command_name notify-host-by-icq
command_line /usr/bin/printf "%b" "msg $CONTACTPAGER$\n***** Nagios <li>**\n\nNotification Type: $NOTIFICATIONTYPE$\nHost:
$HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo:
$HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n.\n" |
/usr/local/bin/vicq -c /usr/local/etc/vicq.conf -b -o -t 5
}
define command {
command_name notify-service-by-icq
command_line /usr/bin/printf "msg $CONTACTPAGER$\n***** Nagios<li>**\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService:
$SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState:
$SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$\n.\n" |
/usr/local/bin/vicq -c /usr/local/etc/vicq.conf -b -o -t 5
}
в) В шаблоне описывающем generic-contact задаем следующие параметры:
service_notification_commands notify-service-by-email,notify-service-by-icq
host_notification_commands notify-host-by-email,notify-host-by-icq
После всех манипуляций - перезагружаем Nagios и "роняем" какой-нибудь сервис. Все должно работать.
Сообщения будут приходить такими:
<li>** Nagios *****
Notification Type: PROBLEM
Service: AMAVIS
Host: localhost
Address: 127.0.0.1
State: CRITICAL
Date/Time: Sun Nov 2 01:22:37 MSK 2008
Additional Info:
Connection refused
Кстати, с vicq есть 1 баг при запуске его нагиосом. Так как клиент использует Term::Readline,
то возникает ошибка при запуске:
Cannot open /dev/tty for read at ...
Решается проблема просто, надо подредактировать файл vicq. Перед 1063 строкой вставить следующий кусок кода:
open (FH, "/dev/tty" )
or eval 'sub Term::ReadLine::findConsole { ("&STDIN", "&STDERR") }';
die $@ if $@;
close (FH);
Все будет работать без проблем.
Утилита memstat сканирует содержимое /proc и генерирует список запущенных программ, используемых
разделяемых библиотек и прочих объектов находящихся в памяти (например, шрифты, области разделяемой памяти, файлы локали),
отображает занимаемую ими память, позволяет оценить степень
совместного использования библиотек.
Программа в Debian и Ubuntu находится в пакете memstat.
При запуске, чтобы вывод не обрезался по границе экрана, нужно использовать опцию '-w'.
Вывод с группировкой по библиотекам:
memstat -w|grep PID|sort -k 4|less
Вывод с сортировкой по размеру:
memstat -w|sort -r -n -k 1|less
Вывод с сортировкой по числу использующих объект процессов:
memstat -w|grep -v PID| perl -ne '$a=$_;s/\d+/|/g;s/[^|]//g; print length($_)-1 . " $a";' \
|awk '{print $1 "\t" $2 "\t" $3}'|sort -n -r -k 1|less
Пакет inotify-tools содержит две полезные утилиты:
inotifywait - ожидать наступления определенного события в файле или дирекотории.
inotifywatch - слежение за статистикой изменений и вывод суммарных данных.
Утилиту inotifywait удобно использовать в скриптах, например, когда нужно дождаться
завершения внешней операции с файлом и мгновенно среагировать на изменения.
Напрмер, запустим:
inotifywait /tmp
При попытке создать файл в /tmp утилита завершит работу, выдав:
/tmp/ CREATE,ISDIR v31549
При попытке создать директорию:
/tmp/ CREATE,ISDIR 0
Если необходимо следить за изменением во всех директориях в пределах /tmp,
следует использовать флаг рекурсивного контроля "-r".
Для больших директорий может понадобиться расширить лимит /proc/sys/fs/inotify/max_user_watches.
Используя опцию "--fromfile" можно загрузить список контролируемых файлов и директорий из файла.
Опция "-e" позволяет реагировать только на определенный тип события, например, на удаление файла, игнорируя создание и открытие.
Опция '-m' отменяет мгновенный выход после наступления события, что позволяет организовать
визуальное наблюдение или обработку в цикле.
Пример, скрипта для обработки изменения файла:
#!/bin/sh
inotifywait -e delete -m /tmp/lock/ | while read dir events file; do
echo "Removed $dir$file"
done
При выполнении:
inotifywatch /tmp
и последующем завершении выполнения через задание таймаута или нажатия ctrl+c,
будет выведена суммарная информация по каждому из классов событий, напрмер:
total modify close_write close_nowrite open create delete filename
22 3 4 1 5 4 5 /tmp/
Или
inotifywatch -v -e access -e modify -t 60 -r /var/log
через 60 секунд выдаст:
14 14 /var/log/
2 2 /var/log/apache2
4 4 /var/log/postgresql
Что касается кроссплатформенного решения, которое работает, не только в Linux, но и во FreeBSD,
можно привести пример слежения за изменением файла используя Perl модуль EV (http://search.cpan.org/dist/EV/),
использующий универсальную библиотеку-враппер libev:
#!/usr/bin/perl
use strict;
use EV;
# Следим за изменениями в директории /tmp/watch
# 0 - интервал опроса по умолчанию
my $w = EV::stat "/tmp/watch", 0,
sub {
my ($w, $revents) = @_;
warn $w->path, " has changed somehow.".$w->attr."\n";
$w->stop;
# На время обработки события, прекращаем прием нотификаций.
.....
$w->start;
};
EV::loop;
Наверное, все встречались, когда на том или ином разделе жесткого диска места уже нет. А
иногда и просто забываешь проконтролировать место на диске.
Данный скрипт написан по принципу настроил и забыл.
#!/bin/sh
address="root@localhost";
cicl="2 3 4 5 6";
# выставляем в процентах порог заполненного места для каждого раздела,
# при котором отсылается сообщение
predel[2]=80; # /
predel[3]=80; # /usr
predel[4]=60; # /var
predel[5]=80; # /tmp
predel[6]=80; # /home
varning="0";
count=0;
df -h > /tmp/tmp_df;
while read -r FS S Ud A U MO; do
let count+=1;
FileSystem[$count]=$FS;
Size[$count]=$S;
Used[$count]=$Ud;
Avail[$count]=$A;
Use[$count]=$U;
MountedOn[$count]=$MO;
NUse[$count]=${Use[$count]%"%"};
done < /tmp/tmp_df;
table="";
for c in $cicl; do
if [[ ${NUse[$c]} -ge ${predel[c]} ]]; then
varning="1";
table=$table"\n${FileSystem[$c]} \t${Size[$c]} \t${Used[$c]} \t${Avail[$c]} \t${Use[$c]} \t${MountedOn[$c]}";
fi
done
shapka="\nFileSystem \tSize \tUsed \tAvail \tUse \tMounted On";
body="Regard admin, please check, place on disk:"$shapka$table;
#echo -e $body;
if [ $varning -eq "1" ];
then
echo -e $body | mail -s"Warning on server" $address;
logger -i -p cron.warn -t dfmonitor "Send warning to $address";
else
logger -i -p cron.info -t dfmonitor " Place on disk in rate";
fi
P.S. записать в cron строчку:
20 5 * * * /sbin/dfmonitor,
с утра приходим и получаем отчет :-)
При отображении строк в RRD используется кодировка UTF-16, в которой есть таблица русских символов,
соответствующая таблице CP1251, только со смещением.
Чтобы rrdgraph смог отображать русские символы на графиках
необходимо внести изменения в файл src/rrd_afm.h. Находим в нем строчку
#define afm_fix_osx_charset(x) (x)
и заменяем на
#define afm_fix_osx_charset(x) \
( (x) >= 128 && (x) <= 255 ? (x) + 0x0350 : (x))
Таким образом, если в строке встречается символ с кодом между 127 и 256, то к нему применяется смещение 0x0350.
Строки необходимо записывать в CP1251 (я использую vim с libiconv).
Для работы с KOI8 необходима еще таблица перестановок из KOI8 в CP1251
Для этого в файл src/rrd_afm.c добавляем описание таблицы
const unsigned char afm_koi2win[128] = {128,129,130,131,132,133,134,135,136,
137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,
156,157,158,159,160,161,162,184,164,165,166,167,168,169,170,171,172,173,174,
175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,254,224,
225,246,228,229,244,227,245,232,233,234,235,236,237,238,239,255,240,241,242,
243,230,226,252,251,231,248,253,249,247,250,222,192,193,214,196,197,212,195,
213,200,201,202,203,204,205,206,207,223,208,209,210,211,198,194,220,219,199,
216,221,217,215,218};
а в src/rrd_afm.h такие строки
extern const unsigned char afm_koi2win[128];
#define afm_fix_osx_charset(c) \
( (c) >= 128 && (c) <= 255 ? afm_koi2win[(c) - 128] + 0x0350 : (c))
Модуль Linux ядра netconsole позволяет экспортировать консоль на другую машину по сети,
что полезно для отладки ситуации зависания Linux без вывода диагностики в лог и на экран (например, X-ы зависли).
В /etc/modprobe.d/ создаем файл или добавляем в /etc/modules.conf:
options netconsole netconsole=32769@192.168.1.1/eth1,32769@192.168.1.6/01:23:34:56:78:9A
где,
192.168.1.1:32769 сетевой адрес и порт на eth1 интерфейсе локальной машины, с которого будет производится отправка пакетов.
192.168.1.6:32769 сетевой адрес, порт и MAC адрес удаленной машины куда будет экспортирована консоль.
На удаленной машине 192.168.1.6, для доступа к консоли используем netcat:
nc -l -p 32769 -u
Подгружаем модуль netconsole:
modprobe netconsole
Пример использования жесткой привязки процесса к определенному процессору (CPU affinity).
Устанавливаем пакет schedutils
(Debian: apt-get install schedutils, Red Hat: up2date schedutils или rpm -ivh schedutils*)
Привязка процесса с pid 13545 к первому CPU (#0):
taskset -c 1 -p 13545
к 3 и 4 CPU (#2 и #3):
taskset -c 3,4 -p 13545
Загрузку процессоров в SMP системе удобно оценивать через утилиту mpstat из пакета sysstat.
mpstat -P ALL
Утилизацию подсистемы ввода/вывода можно посмотреть через команду iostat
% snmpwalk -c communitystring -v 1 10.0.0.254
Ключ -c указывает строку community (обычно public)
-v задаёт версию протокола (1)
Если хотите просмотреть только часть дерева то можно задать вот так:
% snmpwalk -c community -v 1 -m iso.3.6.1.2.1.6.13.1.2 10.0.0.254
Пусть имеется созданная rrd база в файле /path/to/file.rrd (man rrdcreate),
в которой содержатся 2 столбца данных ifinoctets и ifoutoctets
(число входящих и исходящих пакетов на интерфейсе за минуту). Как обновлять man rrdupdate.
Задача: требуется отобразить это графически с подписью данных, а так же суммарным трафиком
и средней загрузкой канала.
Создаётся график следующим образом:
#!/bin/sh
/usr/local/bin/rrdtool graph /tmp/picture.png --end now --start -1d \
--width 500 --height 600 --imgformat PNG \
--title "title" --rigid --color BACK#FAFAFA \
DEF:ifino=/path/to/file.rrd:ifinoctets:AVERAGE \
DEF:ifouto=/path/to/file.rrd:ifoutoctets:AVERAGE \
CDEF:ifino1=ifino,60,/ \
CDEF:ifouto1=ifouto,60,/ \
VDEF:sumin=ifino1,TOTAL \
VDEF:sumout=ifouto1,TOTAL \
VDEF:maxin=ifino1,MAXIMUM \
VDEF:maxout=ifouto1,MAXIMUM \
VDEF:avgin=ifino1,AVERAGE \
VDEF:avgout=ifouto1,AVERAGE \
AREA:ifino1#00FF00:"In" \
GPRINT:maxin:"Max=%lf%s" \
GPRINT:avgin:"Avg=%lf%s" \
GPRINT:sumin:"Sum=%lf%sl" \
LINE1:ifouto1#0000FF:"Out" \
GPRINT:maxout:"Max=%lf%s" \
GPRINT:avgout:"Avg=%lf%s" \
GPRINT:sumout:"Sum=%lf%s\l"
Результатом работы данного скрипта будет создание графика входящих и сходящих пакетов
на интерейсе(в байт/сек), а так же будут отражены на графике средняя загрузка,
пиковые значения и суммарный трафик через интрефейс.
подробнее об параметрах в man rrdgraph,man rrdgraph_rpn,man rrdgraph_graph
Общая информация о BMC и поддержке IPMI:
# bmc-info
Состояние сенсоров (температура, вольтаж, проблемы):
# sensors
Более детально:
# sensors -vv
Состояние лога событий (почему сервер начал пищать):
# sel
Чистка лога событий (чтобы не пищал):
# sel -c
1. Просмотреть содержимое BIOS (проверял под Linux и FreeBSD)
dd if=/dev/mem bs=64k skip=15 count=1 | strings | less
в первых строчках обычно упоминается название материнской платы.
2. Воспользоваться утилитой dmidecode
Включение контроля выполняемых процессов в FreeBSD:
rc.conf
accounting_enable="YES"
periodic.conf
daily_accounting_enable="YES" # Rotate acct files
daily_accounting_compress="NO" # Gzip rotated files
daily_accounting_flags=-q # Flags to /usr/sbin/sa
daily_accounting_save=3 # How many files to save
monthly_accounting_enable="YES" # Login accounting
В Linux (пакет acct или psacct):
service acct start
или руками
/sbin/accton /var/log/pacct
Просмотр статистики через команды sa, lastcomm, last-acct, dump-acct, ac (ac -p, sa -u, sa -m, sa -f). Например:
Загрузка системы пользователями
ac -p|awk '{print $2 "\t" $1}'|sort -r -n
/usr/sbin/sa -m| perl -n -e 's/[\t ]+/\t/g;print $_;'
Топ загрузки системы скриптами пользователей
/usr/sbin/sa -u|awk '{print $8 "\t\t(" $1 ")"}'|sort| uniq -c|sort -n -r
Загрузка системы всеми программами
/usr/sbin/sa -f
R - Процесс выполняется в данный момент
S - Процесс ожидает выполнение (спит)
D - Процесс в полной (непрерываемой) спячке, например, ожидает ввода/вывода
Z - zombie или defunct процесс, т.е. процесс у которого нет родителя.
T - Процесс остановлен.
W - процесс в свопе
< - процесс в приоритетном режиме.
N - процесс в режиме низкого приоритета
L - real-time процесс, имеются страницы заблокированные в памяти.
Сколько CPU времени использовал каждый юзер в системе
ac -p
Какие команды запускал каждый пользователь и сколько CPU и памяти
было использовано при их выполнении:
sa -u
Ключи:
-U - unix socket
-i inet формат:
tcp_или_udp@host:port, например: tcp:25, @192.168.1.1
Примеры:
Список всех открытых файлов: lsof
Все процессы использующие файл: lsof file
Какие процессы используют internet и unix domain сокеты: lsof -i -U
Все открытые файлы для юзера: lsof -l user
...для процесса 12: lsof -p 12
Для unix:
в раз в час запускать через крон: ntpdate 194.186.254.22 195.2.64.5
Для Cisco IOS:
ntp clock-period 17180070
ntp server 195.2.64.5 version 2
ntp server 194.186.254.22 version 2
Скопировать в аппаратные часы текущее системное время под Linux можно командой:
hwclock --systohc
В FreeBSD достаточно изменить время используя команду date.
В будущих версиях RHEL и Fedora Linux появится возможность
использования для хэширования паролей алгоритмов SHA-256 и SHA-512
В Kickstart режиме:
DES
authconfig --enableshadow --passalgo=descrypt
MD5
authconfig --enableshadow --enablemd5
или
authconfig --enableshadow --passalgo=md5
SHA-256
authconfig --enableshadow --passalgo=sha256
SHA-512
authconfig --enableshadow --passalgo=sha512
Тип хэша также можно задать через /etc/logis.desf, присвоив переменной
ENCRYPT_METHOD значение DES, MD5, SHA256 или SHA512
Устанавливаем пакеты необходимые для сборки системы fprint:
aptitude install libpam0g-dev libusb-dev libmagick9-dev libglib2.0-dev libssl-dev
aptitude install libgtk2.0-dev libx11-dev libxv-dev # если будет сборка с поддержкой x11
Загружаем libfprint и pam_fprint с сайта http://www.reactivated.net/fprint
Собираем стандартно через:
./configure
make
make install
Или пересобираем готовые Debian пакеты:
---
Качаем .dsc, tar.gz и diff.gz со страниц
http://packages.debian.org/experimental/libfprint0http://packages.debian.org/experimental/libpam-fprint
Устанавливаем доп. пакеты необходимые для сборки:
aptitude install fakeroot autotools-dev debhelper dpkg-dev
dpkg-source -x libfprint_0.0.5-2.dsc
cd libfprint-0.0.5
dpkg-buildpackage -rfakeroot
Пакет libpam-fprint создается по аналогии
---
Генерируем слепок отпечатка указательного пальца
(запускаем под логином для которого сохраняем отпечаток):
pam_fprint_enroll --enroll-finger 7
Для опциональной аутентификации по отпечатку (возможность ввести пароль остается),
в /etc/pam.d/common-auth первой строкой ставим:
auth sufficient pam_fprint.so
Если пускать в систему нужно только после сверки отпечатка, "sufficient" заменяем на "required".
PS. В Gentoo Linux добавляем в /etc/pam.d/system-auth перед строкой c pam_unix.so
В FreBSD есть прекрасная возможность разрешать логинится конкретным пользователям
только с определённых терминалов или адресов. Делается это посредством модуля pam_acct_mgmt.
Для этого редактируем файл /etc/login.access:
-:root:ALL #запрещаем любые логины root
-:ALL:ttyv0 # первая консоль только для логов
+:dm:ttyv1 ttyv2 ttyv3 ttyv4 ttyv5 ttyv6 ttyv7 ttyv8 # доступ с консоли
+:dm:10.1.1.1 192.168.6.100 # доступ по сети(тут указывать либо ip, либо
# доменное имя. Для ssh рекомендую UseDNS no в /etc/ssh/sshd_config)
-:ALL:ALL # всё остальное запрещено
ВАЖНО! начиная с версии 5.2 su стал проверять "target user" по login.access, те при таких настройках
можно будет залогинится, но su не будет работать - pam_login_access:
pam_sm_acct_mgmt: root is not allowed to log in on /dev/ttyp3 su: Sorry.
Для исправления надо редактировать /etc/pam.d/su:
account
#account include system #закомментировать
account required pam_unix.so # добавить
1. Режим эмуляции Socks proxy в SSH
Допустим, у нас есть рабочая станция в локальной сети за firewall'ом;
также имеется ssh-доступ на сервер в Интернете. Кроме ssh, никакой связи с внешним миром не имеется,
а очень хочется, например, подключиться к какому-нибудь jabber-серверу.
На рабочей станции запускаем простую команду:
ssh -D 5555 user@remotehost -f -N
, где -D 5555 - эмуляция SOCKS сервера через порт 5555
-f - работа в фоне, после аутентификации
-N - не запускать shell на удаленном хосте.
Теперь, указав в настройках XMPP-клиента (например, Pidgin'а) в качестве SOCKS5 прокси localhost:5555,
получим желаемый результат: Pidgin соединяется с сервером через внешний сервер.
2. Туннель ssh
Дано: сервер локальной сети ourproxy.provider.ru, доступный извне.
Требуется: получить из дома доступ к ресурсам внутри локальной сети, например, к интранет-серверу 10.10.5.1:80
Решение: выполнить на домашней машине команду, пробрасывающую туннель к искомому IP-адресу через ourproxy.provider.ru:
ssh -f -N user@ourproxy.provider.ru -L 8080:10.10.5.1:80
Опция -f говорит ssh, что после соединения нужно уйти в background.
Опция -N указывает, что никаких команд выполнять не нужно
Ключ -L означает, что соединения к localhost на порт 8080 нужно перенаправлять на 80 порт IP-адреса 10.10.5.1
Таким образом, набирая в браузере адрес http://localhost:8080, попадаем на нужный сервер.
3. Обратный туннель ssh
Дано: компьютер на работе, находящийся за firewall'ом и nat'ом; компьютер дома с доступом в интернет;
сервер ourproxy.provider.ru с работающим sshd, доступный обоим компьютерам.
Но в данном случае прямой доступ с ourproxy.provider.ru к рабочей машине отсутствует.
Требуется: получить из дома доступ к сервису sshd на рабочем компьютере.
Решение: на рабочей машине выполнить команду:
ssh -f -N user@ourproxy.provider.ru -R 12345:localhost:22
Опции -f и -N описаны несколькими строчками выше.
Ключ -R означает, что подключения к порту 12345 на ourproxy.provider.ru будут перенаправляться на 22 порт рабочего компьютера.
После выполнения этой команды с рабочей машины можно будет попасть на эту машину с ourproxy.provider.ru,
выполнив команду:
ssh -p 12345 user@locahost
По этому же принципу можно получить доступ к прочим ресурсам локальной сети. Вот еще один пример.
На рабочей машине:
ssh -f -N user@ourproxy.provider.ru -R 8080:10.10.5.1:80
На домашней машине:
ssh -f -N user@ourproxy.provider.ru -L localhost:8080:localhost:8080
Теперь, набрав в адресной строке браузера на домашнем компьютере http://localhost:8080,
получаем доступ к интранет-серверу за семью замками двумя firewall-ами.
Конечно же, это приводит к серьёзной бреши в корпоративной безопасности,
поэтому крайне не рекомендуется злоупотреблять этим советом.
Опция "command" файла authorized_keys позволяет указать команду, которая будет выполняться при каждом подключении пользователя по ssh.
Это удобно, когда стоит задача копировать файлы на бэкап-сервер.
Например, если необходимо предоставить доступ только к файлу backup.tgz,
то допишите строку "command='cat backup.tgz'" в самое начало строки с нужным ключом файла authorized_keys.
Указанная команда будет выполняться автоматически при каждом подключении,
вам остается только перенаправить вывод в файл. Если дампов несколько,
то можно написать небольшой скрипт, вида:
#!/bin/sh
read file
case "$file" in
"foo") cat foo.tgz ;;
"bar") cat bar.tgz ;;
esac
Кроме command, в таких случаях не лишним было бы добавить также опции no-port-forwarding, no-pty и все прочие no-*
Кроме как для бэкапов, такое же решение может подойти и для мониторинга.
Когда nagios соединяется к удаленному серверу, чтобы собрать какую-либо статистику, полный ssh-доступ ему не нужен.
В OpenSSH 4.9 появилась возможность помещать отдельных пользователей в изолированное окружение.
Помещение в chroot управляется через директиву ChrootDirectory, задаваемую в конфигурационном файле sshd_config.
Также в sshd был встроен sftp-server и теперь не требует запуска отдельного процесса,
что идеально подходит для использования совместно с директивами ChrootDirectory и ForceCommand internal-sftp.
Например, для ограничения работы пользователя backup только по sftp в пределах директории /chroot:
Match user backup
ForceCommand internal-sftp
ChrootDirectory /chroot
...
#Subsystem sftp /usr/libexec/sftp-server
Subsystem sftp internal-sftp
Пример копирования:
echo "PUT backup.tgz" | sftp backup@backupserver.ru:/backup/
В настоящий момент в sshd не произведена интеграция scp, т.е. при использовании scp,
по-прежнему требуется копирование библиотек в chroot окружение.
Устанавливаем sshguard из портов:
cd /usr/ports/security/sshguard
make install clean WITH_PF=yes
Настраиваем перенаправление логов в sshguard
echo "auth.info;authpriv.info |exec /usr/local/sbin/sshguard" >> /etc/syslog.conf
Правила блокировки по таблице, /etc/pf.conf
internet="vlan50"
table persist
block in quick on $internet from label "ssh bruteforce"
Перечитываем измененные файлы конфигурации PF и syslogd:
pfctl -f /etc/pf.conf
/etc/rc.d/syslogd restart
Тестируем попробовав подобрать пароли:
shguard[1048576]: Started successfully [(a,p,s)=(4, 420, 1200)], now ready to scan.
sshd[1048577]: Invalid user administrador from 21.138.24.51
sshd[1048579]: Invalid user publica from 21.138.24.51
sshd[1048580]: Invalid user rbecerril from 21.138.24.51
sshd[1048581]: Invalid user rvences from 21.138.24.51
sshguard[1048582]: Blocking 21.138.24.51: 4 failures over 15 seconds.
shguard[1048583]: Releasing 21.138.24.51 after 490 seconds.
Для OpenSSH из FreeBSD, в /usr/src/crypto/openssh/version.h меняем, например, на это:
#define SSH_VERSION_BASE "OpenSSH"
#define SSH_VERSION_ADDENDUM "Beastie"
пересобираем:
cd /usr/src/secure/usr.sbin/sshd
make obj && make depend && make all install
и имеем SSH-2.0-OpenSSH Beastie вместо SSH-2.0-OpenSSH_3.6.1p1 FreeBSD-200xxxxx.
Некоторые пакеты с OpenSSH (например в AltLinux) включают в себя патч от http://openwall.com,
добавляющий директиву SshVersion:
SshVersion OpenSSH-1.2.3
В /etc/ssh/sshd_config проверяем активна ли опция "PubkeyAuthentication yes".
Запускаем на локальной машине программу ssh-keygen (ssh-keygen -t rsa),
на все задаваемые вопросы принимаем значения по умолчанию (поле passphrase оставляем пустым).
Далее, запускаем программу ssh-copy-id -i ~/.ssh/id_rsa.pub user@remotehost, где
user - пользователь удаленной машины
remotehost - адрес удаленной машины,
( или вручную, на удаленной машине в директории ~/.ssh, создаем файл authorized_keys,
куда копируем содержимое файла identity.pub (id_rsa.pub) с локальной машины).
Для увеличения безопасности в файл ~/.ssh/authorized_keys на удаленной машине
добавляем перед ключом (разделив пробелом) строку:
from="localhost", где localhost - адрес локальной машины (from="localhost" 1024 23 1343.....).
В /etc/ssh/sshd_config:
AllowUsers user1 user2 user3@host.ru
ChallengeResponseAuthentication no
PermitEmptyPasswords no
PermitRootLogin no
Protocol 2
UseLogin no
X11Forwarding no
UsePrivilegeSeparation yes
# убрать все Subsystem
Ограничить вход только с определенных IP через /etc/hosts.allow
С локальной на удаленную:
tar czvf - список_файлов_и_директорий | ssh remote.test.ru tar xzf - -C /home/user/куда_копировать
Скопировать группу файлов с удаленной машины на локальную.
ssh remote.test.ru tar czf - -C стартовая_директория какие_файлы_копировать |tar xzf - -C директория_куда_копировать.
Имеется машина с Ubuntu Linux, имеющая один сетевой интерфейс. При помощи гипервизора KVM создано
два гостевых окружения - debian01 и debian02. Задача организовать сетевую связь (виртуальная LAN) между
гостевыми системами и корневой системой и обеспечить выход в интернет, через сетевой интерфейс корневой системы.
Настройка корневой системы.
Первым делом нужно создать виртуальный Ethernet коммутатор на базе пакета VDE,
при помощи которого будет создан виртуальный интерфейс tap0, через который будет организована связь
между гостевыми окружениями.
Создаем интерфейс:
sudo vde_switch -tap tap0 -daemon
Проверяем:
ifconfig tap0
tap0 Link encap:Ethernet direcciónHW 00:ff:1b:e7:76:46
DIFUSIÓN MULTICAST MTU:1500 Métrica:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
colisiones:0 txqueuelen:500
RX bytes:53 (53.0 B) TX bytes:0 (0.0 B)
Привязываем адреса виртуальной сети (192.168.254.0/255):
ifconfig tap0 192.168.254.254 netmask 255.255.255.0
для гостевых окружений, адрес 192.168.254.254 будет использоваться в роли шлюза.
Настройка гостевых систем.
Настраиваем в гостевом окружении сетевой интерфейс eth0 (выделяем первому - IP 192.168.254.1,
второму - 192.168.254.2 и т.д.)
Содержимое /etc/network/interfaces
# loopback
auto lo
iface lo inet loopback
allow-hotplug eth0
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.254.1
netmask 255.255.255.0
network 192.168.254.0
broadcast 192.168.254.255
gateway 192.168.254.254
Для предотвращения виртуальных окружений под одним MAC адресом, меняем MAC виртуальных карт:
sudo aptitude install macchanger
Создаем скрипт /etc/network/if-pre-up.d/macchange, меняющий MAC
#!/bin/sh
if [ ! -x /usr/bin/macchanger ]; then
exit 0
fi
/usr/bin/macchanger -a eth0
Перезапускаем гостевые окружения (вместо $IMAGE подставляем путь к окружению):
sudo /usr/bin/vdeq /usr/bin/kvm $IMAGE -m 512 -localtime -k es
Настройка выхода гостевых систем в интернет.
Проверяем на корневой системе, включен ли форвардинг пакетов между интерфейсами:
sysctl net.ipv4.ip_forward
Если выдало 0, то форвардинг отключен, включаем:
sudo -w sysctl net.ipv4.ip_forward=1
и сохраняем в /etc/sysctl.conf строку
net.ipv4.ip_forward = 1
В скрипте инициализации, после поднятия tap0 интерфейса, включаем трансляцию адресов:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Недавно понадобилось посмотреть на NetBSD. Сходу в сети не нашлось описания как это можно сделать,
поэтому может кому то пригодится описание того, как это получилось у меня.
1. Создаем образ, на который будет установлена система:
qemu-img create -f qcow2 netbsd.img 4G
2. Подгружаем модуль aio
sudo kldload aio
3. Скачиваем iso-шку с дистрибутивом и загружаем с неё виртуальную машинку:
qemu -m 256 -curses -hda netbsd.img -cdrom i386cd-4.0.iso -boot d
Далее netbsd устанавливается так же как на обычный PC.
4. Для работы сети внутри виртуальной машины можно сделать бридж между физическим интерфейсом и tap:
sudo ifconfig tap create
sudo ifconfig bridge create
sudo ifconfig bridge0 addm tap0 addm re0 up
sudo sysctl net.link.tap.up_on_open=1
sudo sysctl net.link.tap.user_open=1
Чтобы запускать qemu из под пользователя надо дать ему права на /dev/tap0
4. Без отключения ACPI NetBSD не захотела видеть ни одну из сетевух, которые эмулирует qemu,
поэтому ACPI пришлось отключить:
qemu -m 256 -curses -hda netbsd.img -no-acpi -net nic -net tap
Бывает, виртуальная машина отказывается загружаться со следующей ошибкой:
Unable to restore the virtual machine's saved state from
'M:\VM\Machines\Windows Xp Sviluppo\Snapshots\{ce28664d-45f3-46dd8468-9ba91a689e7b}.sav'.
It may be damaged or from an older version of VirtualBox. Please discard the
saved state before starting the virtual machine. VBox status code: -1829 (VERR_SSM_UNEXPECTED_DATA).
Для решения проблемы требуется восстановить условия, в которых находилась виртуальная машина:
сетевые папки (в моем случае, это каталог /media/ в линуксе и всё дерево каталогов,
доступных виртуальной машине на тот момент), компакт-диски, Flash и прочее съемное.
FreeBSD 6.3 в Virtualbox 1.6 и 2.0 (сборка для Ubuntu Linux 7.10) запустить не удалось
(были испробованы всевозможные комбинации конфигурации VirtualBox),
наблюдается крах в процессе загрузки ядра.
FreeBSD 7.0 был удачно установлен и использован в Virtualbox 1.6.x, но в VirtualBox 2.0
перестал работать режим аппаратной виртуализации VT-x/AMD-V, при включении данной
опции bootloader вываливается в бесконечную демонстрацию регистровых дампов.
Пришлось откатиться обратно до Virtualbox 1.6.6.
Далее, привожу особенности установки FreeBSD 7.0 в Virtualbox.
Во время установки FreeBSD в виртуальном окружении Virtualbox, процесс зависает
во время отображения меню bootloader'а.
Чтобы зависания не произошло нужно в параметрах VirtualBox запретить использование VT-x/AMD-V.
В форумах также можно найти жалобы на зависание в процессе загрузки ядра, решаемые выключением ACPI в VirtualBox.
После завершения установки, загрузившись в новую гостевую систему, меняем /boot/loader.conf:
kern.hz="50"
beastie_disable="YES"
Т.е. уменьшаем частоту генерации прерываний от таймера, чтобы виртуальная машина
не грузила CPU хост-системы и запрещаем отображение меню загрузчика, на котором
система повисает при включении VT-x/AMD-V.
Включаем в настройках VT-x/AMD-V. Тип эмулируемого сетевого адаптера нужно выбрать PCNet-PCI II,
тот что ставится по умолчанию (PCNet-Fast III) не работает во FreeBSD.
Тип эмуляции сетевого интерфейса выбираем NAT, а в FreeBSD получаем адрес по DHCP или
устанавливаем IP из диапазона 10.0.2.0/24, шлюз 10.0.2.2, DNS 10.0.2.3.
Внимание, ping в NAT режиме не работает, проверять приходится через telnet.
Для того чтобы в гостевую систему можно было зайти по SSH, нужно перебросить 22 порт из вне.
Запускаем в консоли хост-системы:
VBoxManage setextradata "freebsd" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/Protocol" TCP
VBoxManage setextradata "freebsd" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/GuestPort" 22
VBoxManage setextradata "freebsd" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/HostPort" 2222
где, "freebsd" - это имя виртуальной машины, а pcnet тип эмулируемой карты.
После перезапуска гостевого окружения, заходя на 2222 порт хостовой машины мы будем
переброшены на 22 порт виртуального окружения.
ssh -p2222 localhost
В форумах советуют создать для FreeBSD образ диска фиксированного размера,
но я использую динамически расширяемый образ и проблем не наблюдаю.
В CentOS 5, при установке пакета kernel-xen с ядром, по умолчанию создается initrd образ для Dom0.
Для использования данного ядра в гостевом окружении необходимо создать initrd
с поддержкой сетевого и блочного xen модулей, иначе ядро в гостевой ФС не сможет
смонтировать корневую ФС на дисковом разделе.
Имеем ядро kernel-xen-2.6.18-53.1.13.el5
Создаем initrd:
/sbin/mkinitrd --with=xennet --preload=xenblk /boot/initrd-centos5-xen.img 2.6.18-53.1.13.el5xen
Пример xen профайла vps3:
kernel = "/boot/vmlinuz-2.6.18-53.1.21.el5xen"
ramdisk = "/boot/initrd-centos5-xen.img"
memory = 1024
name = "vps3"
cpus = "0" # all vcpus run on CPU0
vcpus = 1
vif = [ '', 'mac=00:16:3E:00:00:02, bridge=virbr1, vifname=eth2, ip=192.168.122.2' ]
disk = [ 'phy:/dev/mapper/sil_ahajbjcdabeip7,sda1,w' ]
root = "/dev/sda1 ro"
extra = "4"
Добавляем в /etc/apt/sources.list репозиторий с OpenVZ:
deb http://download.openvz.org/debian-systs etch openvz
Далее:
wget -q http://download.openvz.org/debian-systs/dso_archiv_signing_key.asc -O- | apt-key add -
apt-get update
Устанавливаем ядро с OpenVZ.
В репозитории доступны ядра версий 2.6.18 и 2.6.24 в сборках 486, 686, 686-bigmem (до 63 Гб ОЗУ) и amd64.
apt-get install fzakernel-2.6.18-686-bigmem
update-grub
Устанавливаем утилиты и минимальный образ гостевой системы:
apt-get install vzctl vzquota vzprocps vzdump
apt-get install vzctl-ostmpl-debian
Для работы сети в VPS проверяем настройки /etc/sysctl.conf:
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.forwarding=1
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.ip_forward=1
Перечитываем настойки: sysctl -p
Если IP виртуальной машины находится вне подсети, используемой на хост-машине:
В /etc/vz/vz.conf ставим:
NEIGHBOUR_DEVS=all
Перезагружаем машину с новым OpenVZ ядром и приступаем к поднятию виртуального окружения.
Создаем виртуальную машину с ID 101 на основе ранее загруженного шаблона (vzctl-ostmpl-debian):
vzctl create 101 --ostemplate debian-4.0-i386-minimal --config vps.basic
Включаем автоматиеческий запуск созданного VPS на стадии загрузки системы:
vzctl set 101 --onboot yes --save
Назначаем VPS имя хоста и IP:
vzctl set 101 --hostname test.example.com --save
vzctl set 101 --ipadd 1.2.3.101 --save
Ограничиваем число открытых сокетов, число процессов и объем памяти:
vzctl set 101 --numothersock 100 --save
vzctl set 101 --numtcpsock 100 --save
vzctl set 101 --numproc 150 --save
vzctl set 101 --vmguarpages 65536 --save # гарантированный объем 256Мб, в блоках по 4Кб
vzctl set 101 --privvmpages 131072 --save # максимальный объем 512Мб, в блоках по 4Кб
Список возможных ограничений - http://wiki.openvz.org/UBC_parameters_table
Прописываем DNS серверы для VPS:
vzctl set 101 --nameserver 213.133.98.98 --nameserver 213.133.99.99 \
--nameserver 213.133.100.100 --nameserver 145.253.2.75 --save
Можно вместо вызова vzctl напрямую отредактировать файл конфигурации /etc/vz/conf/101.conf
Запускаем созданную VPS:
vzctl start 101
Устанавливаем пароль суперпользователя VPS, запустив внутри команду passwd:
vzctl exec 101 passwd
Входим в shell VPS (можно сразу зайти по SSH):
vzctl enter 101
Останавливаем VPS:
vzctl stop 101
Удаляем VPS с жесткого диска:
vzctl destroy 101
Просматриваем список VPS и их статус:
vzlist -a
Просмотр ресурсов доступных внутри VPS:
vzctl exec 101 cat /proc/user_beancounters
Подробнее см. http://wiki.openvz.org/
Имеем: неизменную базовую /home директорию.
Хотим: отдельно держать изменения внесенные пользователями, чтобы они не влияли на базовую /home.
изменения держать в рамдиске, так чтобы они не сохранялись при следующем входе
Решение:
- unionfs - для отделения данных пользователя от read-only основы.
- tmpfs - для создания /tmp директории с временными файлами, хранимой в ОЗУ.
- pam-mount (http://pam-mount.sourceforge.net/) - PAM модуль для автоматического
монтирования разделов в момент входа пользователя в систему.
Устанавливаем пакеты (пример для Debian и Ubuntu):
apt-get install unionfs-modules-`uname -r`
apt-get install libpam-mount
Настраиваем pam_mount (/etc/security/pam_mount.conf)
volume debiosk tmpfs - tmpfs /tmp/tmpfs "size=15M,uid=debiosk,gid=debiosk,mode=0700" - -
volume debiosk unionfs - unionfs /home/debiosk "dirs=/tmp/tmpfs:/home/debiosk=ro" - -
где
"volume" - ключевое слово, сигнализирующее об описании раздела;
"debiosk" - имя пользователя, для которого определены правила монтирования;
"tmpfs" - тип файловой системы;
" - " - сигнализирует о неиспользовании монтирования с удаленного сервера;
"/tmp/tmpfs" - точка монтирования;
"size=15M,uid=debiosk,gid=debiosk,mode=0700" - параметры монтирования tmpfs:
"size=15m," - размер;
"uid=debiosk,gid=debiosk," - владелец;
"mode=0700" - права доступа;
"dirs=/tmp/tmpfs:/home/debiosk=ro" - параметры монтирования unionfs:
указывают отобразить изменения /home/debiosk в директории /tmp/tmpfs
Добавляем строку "@include common-pammount" в /etc/pam.d/login, /etc/pam.d/su и /etc/pam.d/xdm
Теперь пользователь debiosk каждый раз будет получать исходную домашнюю директорию,
а изменения будут действовать только в пределах сессии.
Нам понадобится первый установочный диск FreeBSD 6.2 и немного свободного времени.
Предполагается что наша jail-машина будет размещена в директории /var/jail.
Список действий:
1. Создать директорию /var/jail/machine для jail-машины;
2. Смонтировать установочный диск и распаковать базовые файлы в директорию jail-машины:
# mount /cdrom
для bash:
# DESTDIR=/var/jail/machine /cdrom/6.2-RELEASE/base/install.sh
для csh:
# env DESTDIR=/var/jail/machine /cdrom/6.2-RELEASE/base/install.sh
3. Создать пустой файл /var/jail/machine/etc/fstab:
# touch /var/jail/machine/etc/fstab
4. Создать файл /var/jail/machine/etc/rc.conf со следующим содержанием:
# Запускаем sshd
sshd_enable="YES"
sendmail_enable="NONE"
syslogd_flags="-ss"
rpcbind_enable="NO"
network_interfaces=""
5. Теперь требуется создать непривилегированного пользователя и изменить пароль пользователя root.
Входим в каталог jail-машины
# chroot /var/jail/machine /bin/csh
Создаем пользователя
# adduser
Меняем пароль пользователя root
# passwd
# exit
6. В файл /etc/rc.conf основной системы добавить:
# Разрешаем запуск jail-машин
jail_enable="YES"
# Запрещаем им менять свое имя jail_set_hostname_allow="NO"
# Перечисляем jail-машины в системе.
jail_list="machine"
# Jail-машина "machine"
# Корневая директория jail_machine_rootdir="/var/jail/machine"
# Имя jail_machine_hostname="machine.local"
# IP-адрес jail_machine_ip="192.168.0.10"
# На какой сетевой интерфейс будет цепляться jail-машина
jail_machine_interface="ed0"
# монтируем файловую систему devfs внутри jail-машины.
jail_machine_devfs_enable="YES"
# Скрипты запуска и останова
jail_machine_exec_start="/bin/sh /etc/rc"
jail_machine_exec_stop="/bin/sh /etc/rc.shutdown"
7. Кроме того требуется все запускаемые сервисы основной системы привязать к его ip-адресам
(не должны слушаться порты на ip-адресах jail-машин).
Например, в rc.conf:
# Супер-сервер inetd
inetd_enable="YES"
# Слушает порт только на 192.168.0.1
inetd_flags="-wW -a 192.168.0.1"
# Syslogd
syslogd_enable="YES"
# Не слушать порты
syslogd_flags="-ss"
8. Запускаем созданную jail-машину:
# /etc/rc.d/jail start
Ниже пример организации 32-битного chroot окружения в 64-битной системе.
Устанавливаем пакет schroot
aptitude install schroot
Создаем файл конфигурации /etc/schroot/schroot.conf:
[sid]
description=Debian sid (unstable)
location=/srv/chroot/sid
priority=3
users=YOUR_USER
groups=SOME_GROUP_LIKE_users
root-groups=YOUR_ADMIN_USER
Формируем chroot окружение:
debootstrap --arch i386 sid /srv/chroot/sid http://ftp.br.debian.org/debian
Установка программ в chroot:
schroot -c sid -p aptitude install wengophone
Монтируем /proc и /dev основной системы в chroot:
mount /dev /srv/chroot/sid/dev -o bind
mount /proc /srv/chroot/sid/proc -o bind
Разрешаем запуск графических приложений из chroot на основном X сервере:
xhost +
Запускаем приложения wengophone и skype:
schroot -c sid -p wengophone
schroot -c sid -p skype
Закрываем полный доступ к X серверу.
xhost -
Например, в postfix запущенном в chroot, через настройки в master.cf, при перезапуске syslogd
перестают писаться логи qmgr, тем временем все остальные логи пишутся нормально.
Решение - необходимо создать дополнительный log сокет в chroot окружении:
FreeBSD: "syslogd -l /var/spool/postfix/dev/log"
Linux: "syslogd -a /var/spool/postfix/dev/log"
1. В chroot окружении обязательно должен быть /etc/passwd с пользователями для которых используется suexec.
2. Помещена ли в bin директорию программа suexec ?
3. Установлен ли suid root флаг для программы suexec ? (при копировании suid флаг исчезает).
4. Все ли динамические библиотеки присутствуют:
chroot /hst /usr/local/apache/bin/ldd /usr/local/apache/bin/httpd
chroot /hst /usr/local/apache/bin/ldd /usr/local/apache/bin/suexec
предварительно положив ldd в /hst/usr/local/apache/bin/
Предполагается что в полном распоряжении есть FreeBSD 5.X
Разборки "что ставить на сервер: 4.X или 5.X" не обсуждаются.
В случае использования FreeBSD 4.X необходимо вместо mdconfig использовать vnconfig
и вместо gbde использовать vncrypt.
Компилируем ядро с
options GEOM_BDE # поддержка шифрованых дисков
device md # Memory "disks"
Создаем директорию, где все будет валяться
mkdir /usr/cert/
Создаем файл, где будет файловая система (размером 100 мегабайт)
dd if=/dev/zero of=fimage bs=1m count=100
создаем девайс на основании этого файла и создем там таблицу разделов на весь диск
mdconfig -a -t vnode -f /usr/cert/fimage -u 0
disklabel -r -w md0 auto
Инициируем gbde патишен
gbde init /dev/md0c -i -L /usr/cert/fimage.lock
В текстовом редакторе откроется конфиг файл для этого шифрованого раздела.
Если используется UFS 1 или2 то рекомендуется изменить параметр sector_size с 512 на 2048.
Сохраняемся, вводим два раза пароль, который будет использоваться для доступа к этому шифрованому разделу.
Подключаем шифрованый раздел (будет запрошен пароль для подключения).
gbde attach /dev/md0c -l /usr/cert/fimage.lock
Создаем на полученном разделе файловую систему.
newfs -U /dev/md0c.bde
Создаем директорию, куда будем маунтить:
mkdir /usr/cert/sslcert
Монтируем
mount /dev/md0c.bde /usr/cert/sslcert
Типа все работает. Теперь создадим скрит для удобства монтирования/размонтирования с таким содержанием:
#!/bin/sh
case "$1" in
start)
/sbin/mdconfig -a -t vnode -f /usr/cert/fimage -u 0
/sbin/gbde attach /dev/md0c -l /usr/cert/fimage.lock
/sbin/mount /dev/md0c.bde /usr/cert/sslcert
;;
stop)
/sbin/umount /usr/cert/sslcert
/sbin/gbde detach /dev/md0c
/sbin/mdconfig -d -u 0
;;
*)
echo ""
echo "Usage: `basename $0` { start | stop }"
echo ""
exit 64
;;
esac
Все, пользуемся в свое удовольствие.
При подготовке использованы источники: FreeBSD Handbook , mdconfig(8), gbde(8)
Цель - организовать аутентификацию пользователя в Linux системе, не через ввод пароля,
а через вставку USB флэша или CDROM, содержащего DSA ключ.
1. Устанавливаем pam_usb (http://pamusb.sourceforge.net/);
2. В /etc/pam.d/login, /etc/pam.d/xdm и т.д. прописываем, в зависимости от режима:
2.1. Вход только при вставке Flash с ключем:
auth required pam_usb.so
#auth required pam_unix.so # комментируем строку.
2.2. Можем войти просто вставив Flash или набрав пароль:
auth sufficient pam_usb.so # ставим перед "auth required pam_unix.so"
2.3. Режим входа только при вставке Flash с ключем одновременно с вводом пароля:
auth required pam_usb.so # ставим перед "auth required pam_unix.so"
3. Монтируем Flash в /mnt/usb и генерируем для пользователя ключ:
usbadm keygen /mnt/usb логин 1024
В состав дистрибутива openssl входят скрипты CA.sh и CA.pl (/usr/local/openssl/misc)
создаем корневой сертификат
./CA.sh -newca
генерируем личный ключ и сертификационный запрос сервера
./CA.sh -newreq
и подписываем его своим корневым сертификатом.
./CA.sh -sign
переписываем ключ и сертификат сервера в служебный каталог Apache
cp newreq.pem /usr/local/etc/apache/sslkey/server.key
cp newcert.pem /usr/local/etc/apache/ssl.crt/server.crt
Файл корневого сертификата ./demoCA/cacert.pem необходимо
распространить по клиентским компьютерам.
use Crypt::Blowfish;
use Crypt::CBC;
my $cipher = new Crypt::CBC("Секретный ключ для шифрования",'Blowfish');
my $crypted_block = $cipher->encrypt_hex($text);
my $text = $cipher->decrypt_hex($crypted_block);
$cipher->finish();
pgp2.6>pgp -ka <файл с ключом с удаленной машины>
pgp5.0>pgpk -a <файл с ключом с удаленной машины>
gnupg>gpg --import <файл куда будет записан ключ>
# Для pgupg необходимо заверить ключ:
gnupg>gpg --sign-key <имя ключа>
pgp2.6> pgp -akx <UserID> <файл куда будет записан ключ>
pgp5.0> pgpk -ax <UserID> <файл куда будет записан ключ>
gnupg> gpg --export -a <UserID> > <файл куда будет записан ключ>
--verify source-name.asc
Проверить по сигнатуре
--gen-key
Сгенерировать новый PGP ключ (--quick-random - быстрая но не безопасная генерация)
--gen-revoke uid
Сгенерировать сертификат на случай забытия пароля.
-s file
Создать сигнатуру для файла (-sa - в .asc формате)
-e -r user file
Зашифровать файл
-se -r encuser -u siguser
Шифрование и подпись зашифрованного
--export
Экспортировать публичные ключи
--import file
Импортировать публичный ключ
--edit-key user
Операции по редактированию keyring
--batch
Автоматическая обработка, без интерактивных диалогов
Расскажу о двух возможностях, которые можно реализовать на роутере
с прошивкой DD-WRT на примере роутера Linksys WRT54GL.
1) Файловая система JFFS.
На роутере можно без труда организовать небольшое энергонезависимое хранилище файлов.
Для этого в веб-интерфейсе включаем поддержку jffs (по туториолу из официального вики dd-wrt):
1. Откройте вкладку "Administration".
2. Перейдите к секции "JFFS2 Support".
3. Кликаем "Enable JFFS".
4. Затем жмём "Save".
5. Ждём несколько секунд и жмём "Apply".
6. Опять ждём. Идём обратно к опции "Enable JFFS", кликаем "Clean JFFS".
7. Не кликая "Save", жмём вместо этого "Apply".
Теперь если мы приконнектимся к роутеру по ssh команда "df -h" расскажет нам о наличие новой файловой системы,
смонтированной в каталоге /jffs/, и её размере (размер очень сильно зависит от типа вашей прошивки,
для получения хоть сколько-нибудь полезного свободного пространства для jffs рекомендуется установить mini-версию dd-wrt).
2) Индикация активности wifi по лампе на корпусе роутера.
Теперь используем возможности jffs - разместим на ней скрипт (с того же вики dd-wrt), который заставляет
гореть лампу янтарным светом при подключенных wifi-клиентах и мигать белым при трансфере данных через WLAN.
Для установки скрипта:
1. Коннектимся по ssh.
2. Переходим в каталог /jffs/ и создаем директорию bin:
# cd /jffs/
# mkdir ./bin
3. Как видно /jffs/bin уже прописан в переменной поиска команд PATH:
# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/jffs/sbin:/jffs/bin:/jffs/usr/sbin:/jffs/usr/bin
4. Создаем файл скрипта (# vi ./wlan.sh) со следующим содержанием:
#!/bin/sh
I=`nvram get wl0_ifname`
while sleep 1; do
if [ "`wl assoclist`" != "" ]; then
XFER=`ifconfig $I|grep bytes`
if [ "$XFER" != "$PXFER" ]; then
LED='gpio disable 3 ; gpio disable 2'
PXFER=$XFER
else
LED='gpio disable 3 ; gpio enable 2'
fi
else
LED='gpio enable 3 ; gpio enable 2'
fi
if [ "$LED" != "$PLED" ]; then
eval $LED
PLED=$LED
fi
done
5. Делаем скрипт исполняемым:
# chmod +x ./wlan.sh
Готово!
Скрипт теперь можно запускать командой wlan.sh или прописать в автозагрузку.
Оригинал в блоге по ссылке: http://damnsmallblog.blogspot.com/2008/03/jffs-wifi-linksys-wrt54gl.html
Довольно часто требуется посмотреть информацию, которая не умещается на экране.
Например, конфигруация или поднятые Virtual интерфейсы. Гораздо удобнее посмотреть это в браузере.
Базовая страница: https://xxx.xxx.xxx.xxx/level/15/exec/-
Чтобы вывести текущую конфигурацию, добавляем к базовой странице "/show/running-config", получаем:
https://xxx.xxx.xxx.xxx/level/15/exec/-/show/running-config/CR
где xxx.xxx.xxx.xxx - IP адрес Cisco, 15 - уровень доступа.
На этой страничке вы можете ввести любую команду консоли.
Причем, если вы введете, например, "show processes cpu ?" - Cisco вам выдаст список доступных команд с описанием.
HTTPS доступ можно включить через глобальную опцию конфигурации:
ip http secure-server
Провайдер по тем или иным причинам отдает мне 802.1Q ethernet транк с несколькими вланами.
Естественно, что план нумерации vlan у провайдера и у меня не совпадает.
Пример преобразования соответствующих vlan на коммутаторе:
interface GigabitEthernet1/5
description bla-bla-bla
switchport
switchport trunk encapsulation dot1q
switchport trunk allowed vlan 1264-1266
switchport trunk allowed vlan add 1356,1360-1364
switchport mode trunk
switchport nonegotiate
switchport vlan mapping enable
switchport vlan mapping 1362 1264
switchport vlan mapping 1363 1265
После многократного передергивания интерфейс перестает работать.
show interface FastEthernet0/15
показывает причину (err-disabled):
FastEthernet0/15 is down, line protocol is down (err-disabled)
Более подробную информацию смотрим:
show interfaces status err-disabled
show log | include FastEthernet0/15
Видим, например: link-flap или loopback.
Для того чтобы интерфейс вновь заработал достаточно выполнить:
conf
interface FastEthernet0/15
shutdown
no shutdown
Для отключения err-disabled:
no errdisable detect cause loopback
Ниже приведен вариант организации слежения за изменением конфигурации,
в лог сохраняется информация о том, кто и какие именно команды вводил.
Как это выглядело раньше?
Кто-то зашел на железяку и внес какие-то изменения. Об этом в логе останется информация следующая информация:
Mar 1 00:12:15.675: %SYS-5-CONFIG_I: Configured from console by one on vty0 (10.10.10.1)
И всё!
С некоторой версии ios появилась возможность посмотреть кто и что конкретно сделал.
Для этого необходимо добавить в конфигурацию следующие строки:
archive
log config
logging enable
notify syslog
hidekeys
logging enable - писать лог. По умолчанию выключено.
notify syslog - писать лог локально или посылать также на syslog сервер
hidekeys - не записывать в лог пароли
Теперь процесс логина и изменения отобразится примерно следующим образом
(Легко определить что в гости заходил пользователь one и настроил интерфейс FastEthernet1/0):
Mar 1 00:18:18.839: %PARSER-5-CFGLOG_LOGGEDCMD: User:one logged command:!exec: enable
Mar 1 00:18:58.003: %PARSER-5-CFGLOG_LOGGEDCMD: User:one logged command:interface FastEthernet1/0
Mar 1 00:19:11.023: %PARSER-5-CFGLOG_LOGGEDCMD: User:one logged command:ip address 192.168.1.1 255.255.255.0
Mar 1 00:19:13.715: %PARSER-5-CFGLOG_LOGGEDCMD: User:one logged command:no shutdown
Mar 1 00:19:15.687: %LINK-3-UPDOWN: Interface FastEthernet1/0, changed state to up
Mar 1 00:19:16.687: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet1/0, changed state to up
1. в IOS'е: в конфигурации интерфейса дается командочка:
(config-if)# port group номер [distribution source|destination]
где номер - это номер группы портов или номер etherchnnel'а, а значение дистрибьюшна - это метод
распределения трафика по хвостам - значение XOR-функции от MAC-адресов источника либо назначения;
2. в set-based свичах: собственно, etherchannel включается командой
(enable) set port channel mod/ports mode {on|off|desirable|auto}
где порты задаются в виде, например, 3/1-4 (третий модуль, порты с первого по четвертый),
а моды - это, собственно, режимы портов для распознавания их специальным протоколом
объединения портов; если ты уверен, что тебе нужен etherchannel, задай мод on и не заморачивайся;
метод распределения трафика задается командой:
(enalble) set port channel all distributoin {ip|mac} [source|destination|both]
all - в том смысле, что для всех etherchannel'ов
both - значит, что XOR'иться будут и адреса источника, и назначения,
ip|mac - выбор, по каким адресам распределять трафик.
Примеры EtherChannel соединения двух коммутаторов Catalyst:
http://www.cisco.com/warp/public/473/89.htmlhttp://www.ciscosystems.cd/warp/public/473/135.html
Во-первых, приготовьтесь к тому, что про ISL можно забыть. Да-да! Cisco в новых коммутаторах 2950 отказалась
от своего-же детища. Так что для тех, у кого есть Cisco 19хх (там как-раз из транков только ISL) - это проблема,
связать 19хх и 2950 транком можно только при наличии между ними устройства понимающего dot1q и ISL.
На 2950 с версией Cisco IOS Release 12.1(14)EA1 есть проблемы при работе транка dot1q в умолчательной
конфигурации, а так как там это единственно возможный транк, то это большие проблемы.
Первым делом на Cisco 2950 IOS Release 12.1(14)EA1 нужно выполнить
такую команду:
#dot1x system-auth-control
Перезагрузить Cisco и настроить транки с vlan'ами...
Радоваться жизни.
Да, можно ещё IOS поменять :)
Если на cisco невозможно зайти telnet'ом, ssh или rsh и "clear line" и "clear line vty" не помогает.
(Telnet DoS: http://www.opennet.ru/base/fire/1093711089_1345.txt.html)
Найти tcb (tcp control block) этого соединения и почистить его на
уровне tcp-соединения:
#show tcp brief
TCB Local Address Foreign Address (state)
447236F0 192.168.10.131.23 remote.host.removed.32781 ESTAB
#clear tcp tcb 447236F0
[confirm]Connection closed by foreign host.
ip rcmd rsh-enable
ip rcmd remote-host test 192.168.1.1 test
ip rcmd remote-host admin 192.168.1.2 admin enable
ip rcmd remote-host local_username remote_addr remote_username enable
Для unix:
в раз в час запускать через крон: ntpdate 194.186.254.22 195.2.64.5
Для Cisco IOS:
ntp clock-period 17180070
ntp server 195.2.64.5 version 2
ntp server 194.186.254.22 version 2
Просмотреть текущий рабочий файл конфигурации:
show running-config
Посмотреть файл конфигурации устанавливаемый после перезагрузки:
show startup-config
Запустить систему автоматического интерактивного конфигурирования:setup
Сохранить текущий рабочий конфиг в NVRAM (чтобы изменения восстановились после перезагрузки):
copy running-config startup-config
Загрузить конфиг загружаемый по умолчанию:
copy startup-config running-config
Скопировать рабочий конфиг на tftp сервер:
copy running-config tftp
Загрузить IOS с удаленного tftp сервера, а не из флэша:
boot system tftp
Скопировать содержимое флэша на удаленный tftp сервер:
copy flash tftp
Обновить содержимое флэша с tftp сервера:
copy tftp flash
show catalyst [Catalyst 6000 info]
show cwan [Catalyst WAN info]
show diagnostic result [Diagnostics]
show diagnostic result [Diagnostics]
show fabric [Crossbar switching data]
show fm interface <interface-id> [Feature Manager]
show ibc br [Traffic to CPU]
show inventory [Equipment inventory]
show idprom module n [IDPROM info]
show mac-address-table [MAC]
show mls [Multilayer switching]
show mls statistics
show mls netflow ip nowrap
show mls status [undocumented]
show module [Linecard info]
show platform [hardware]
show power [Power info]
show platform hardware pfc mode
show tcam [TCAM info]
show tcam detail
show upgrade fpd [Field Programmable Device upgrade]
attach n [Connect to SUP]
hw-module [Reset of power-cycle specific module]
remote command switch sho xxxx [Connect to SUP]
ipc-cons n [Connect to Flexwan - undocumented]
сделано на Cisco 7507, коммутатор Catalyst 5000 все интерфейсы FE
Помимо предоставления фиктивных адресов через Radius, создан VLAN с реальными адресами для тех клиентов, которым в силу определенных причин необходимы реальные адреса.
Первым делом разрешите на cisco Radius:
aaa authentication login default local
aaa authentication ppp default group radius
aaa authorization exec default local !запрет использования Radius для exec
aaa authorization network default group radius
aaa accounting network default start-stop group radius
Разрешите VPN:
vpdn enable
Создайте группу:
vpdn-group 1
accept-dialin
protocol pppoe
virtual-template 1
Создайте сабинтерфейсы для VLAN на внутреннем Ethernet интерфейсе:
interface FastEthernet0/0.1
description PPTP clients
encapsulation dot1Q 2
ip address 192.168.0.1 255.255.255.0
no ip redirects
ip nat inside
pppoe enable
interface FastEthernet0/0.2
encapsulation dot1Q 2
ip address 81.ххх.ххх.ххх 255.255.255.240
Добавьте ip nat outside на Internet интерфейсе
Создайте Virtual-Template1
interface Virtual-Template1
ip unnumbered FastEthernet0/0.1
ip nat inside
ppp authentication chap pap callin
Добавьте использование функции NAT overload на Internet интерфейсе для адресов из access-list 1
ip nat inside source list 1 interface FastEthernet1/0 overload
access-list 1 permit 192.168.2.0 0.0.0.255 !для этих адресов разрешить NAT
На этом интерфейсе живет Radius сервер:
ip radius source-interface FastEthernet0/0.2
Это его настройки:
radius-server configure-nas
radius-server host 81.ххх.ххх.ххх auth-port 1812 acct-port 1813
radius-server retransmit 3
radius-server timeout 30
radius-server key xxxxxxxxxxxxxxxxx
P.S. Radius у меня сам выдает IP вида 192.168.2.ххх по имени пользователя. Если вам это не подходит то сделайте:
ip local pool PPPoE 192.168.2.2 192.168.2.254
Скинуть пользователя по заданному порту (N) можно через OID:
1.3.6.1.4.1.9.9.150.1.1.3.1.5.N
snmpset as-1.test.ru private .1.3.6.1.4.1.9.9.150.1.1.3.1.5.N i 1
Соспоставить логин с номером порта можно через OID:
1.3.6.1.4.1.9.9.150.1.1.3.1.2
Или из FAQ: snmpset -v1 as-1.test.ru private .1.3.6.1.4.1.9.2.9.10.0 i $line
На Cisco:
radius-server optional passwords
Если необходимо организовать переброс UUCP пользователей, то лучше остановиться на схеме
Login/Password/Password, т.е. авторизируем на Cisco и пробрасываем через rlogin на UUCP сервер.
Схемы Login/Password можно добиться добавив IP Cisco в /etc/hosts.equiv, но делать это
крайне не рекомендуется.
Часто firewall представляется неким черным ящиком который просто фильтрует проходящие пакеты. Данная заметка поможет понять, что именно происходит при фильтрации и в какой последовательности.
Что происходит с пакетом попадающим внутрь PIX/ASA firewall, по каким параметрам принимается решение пропускать пакет дальше или нет?
Прежде всего, замечу, что минимальными требованиями к пакету являются:
настроенная трансляция адресов между интерфейсами. Конечно, это требование можно отключить с помощью команды no nat-control, однако поведение по умолчанию именно такое;
политика доступа (access-list) разрешающая доступ.
Минимальные условия это конечно здорово, но жизнь была бы слишком скучна, правда? :)
Попробуем разобраться, что происходит на каждом шаге.
К сожалению я не нашел подобной информации на сайте производителя. Зато под рукой оказалась замечательная книга "Cisco ASA PIX and FWSM Handbook" из которой и почерпнута это информация.
1. Initial Checking
Базовые проверки на целостность пакета, допустимые опции и прочее.
Именно на этом этапе проводится проверка Reverse Path Forwarding про которую я уже рассказывал.
Отмечу, что RPF будет полноценно работать только в случае спуфинга адресов между интерфейсами. В классическом случае outside - ASA - inside спуфинг на outside интерфейсе определить он не сможет.
2. Xlate lookup (outbound)
Именно сейчас проверяется одно из минимальных условий - трансляция адресов между интерфейсами.
Совершенно неважно будет это статическая трансляция one to one или динамическая с применением overload.
Сначала firewall попытается найти уже существующую трансляцию (можно посмотреть по show xlate), в случае неудачи пытается создать, если конечно политика это предусматривает.
Этот шаг происходит на разных этапах в случае входящего/исходящего соединения.
Проверка осуществляется на втором шаге в случае исходящего соединения.
Этому есть логичное объясниение - адрес источника будет переписан и именно он должен фигурировать в дальнейших проверках (acl).
Повторюсь. Это поведение можно выключить используя no nat-control. Однако, до версии прошивки 7.1 этого сделать было нельзя.
Также именно здесь firewall проверяет такие параметры как:
лимиты на количество активных соединений;
лимиты на количество полу-открытых соединений (embryonic);
таймауты на соединение.
3. Connection lookup
Поскольку firewall у нас "умный" и знает, что такое stateful фильтрация, ему необходимо когда-то проверять состояние соединения. Почему бы не на этом этапе? :)
Литературы по stateful фильтрации достаточно, описывать еще раз не буду.
4. ACL lookup
Именно на этом этапе происходит что-то знакомое. Как видно из названия проверяется политика доступа - поиск соответствующего access-list
По умолчанию никаких acl не применено. Трафик разрешен с более безопасного интерфейса на менее безопасный. Уровень безопасности определяется значением security level.
5. Xlate lookup (inbound)
Происходит та же проверка, что и на шаге 2. Но только для входящего трафика.
6. Uauth lookup
В случае если firewall используется как cut-through authentication proxy на этом шаге проверяются логин/пароль пользователя для его аутентификации.
Если это не первое соединение инициируемое пользователем проверяется таймер аутентификации.
7. Inspection
На последнем шаге осуществляется инспекция протокола. Конкретные действия выполняемые в этом случае очень сильно зависят от инспектируемого протокола.
Про самые интересные постараюсь рассказать в следующих заметках.
Резюме статьи <a href="http://www.informit.com/articles/article.asp?p=345618">http://www.informit.com/articles/article.asp?p=345618</a>
Диагностика:
Оценка загрузки CPU
show processes cpu
show processes cpu history
sh int switching
Слежения за счетчиками на ACL
clear access-list counters N
show access-list N
Сброс статистики срабатываний ACL в syslog:
access-list 100 deny icmp any any echo reply log-input
Netflow
interface N
ip route-cache flow или ip route-cache distributed
ip flow-export IP UDP_port
show ip cache flow
Code Red Worms
show ip cache flow | include 0050
Smurf Attacks
show ip cache flow | include 0000
clear ip flow stats
TCP SYN Flood Attacks
access-list 100 tcp permit tcp any any
ip tcp intercept list 100
ip tcp intercept mode {intercept | watch}
ip tcp intercept watch-timeout {seconds}
ip tcp intercept finrst-timeout {seconds}
ip tcp intercept connection-timeout {seconds}
ip tcp intercept max-incomplete high {N}
ip tcp intercept max-incomplete low {N}
ip tcp intercept drop-mode {oldest | random}
show tcp intercept statistics
show tcp intercept connections
debug ip tcp intercept
Защита:
Cisco Express Forwarding (CEF) Switching:
scheduler interval Num_of_milliseconds
scheduler allocate Num_of_milliseconds_of_interrupts Num_of_milliseconds_of_no_interrupts
TCP SYN Flood Attacks
Синтаксис
access-list N tcp permit tcp any any
ip tcp intercept list N
ip tcp intercept mode {intercept | watch}
ip tcp intercept watch-timeout {seconds}
ip tcp intercept finrst-timeout {seconds}
ip tcp intercept connection-timeout {seconds}
ip tcp intercept max-incomplete high {N}
ip tcp intercept max-incomplete low {N}
ip tcp intercept drop-mode {oldest | random}
show tcp intercept statistics
show tcp intercept connections
debug ip tcp intercept
Пример:
access-list 100 tcp permit tcp any host 192.1.1.1 eq 80
access-list 100 tcp permit tcp any host 192.1.1.2 eq 25
ip tcp intercept list 100
ip tcp intercept mode watch
ip tcp intercept watch-timeout 20
ip tcp intercept connection-timeout 120
ip tcp intercept max-incomplete high 600
ip tcp intercept min-incomplete low 500
ip tcp intercept one-minute high 800
ip tcp intercept one-minute low 600
CBAC (Context-Based Access Control) и DoS атаки
Синтаксис:
ip inspect tcp synwait-time {seconds}
ip inspect tcp finwait-time {seconds}
ip inspect tcp idle-time {seconds}
ip inspect udp idle-time {seconds}
ip inspect dns-timeout {seconds}
ip inspect max-incomplete high {number}
ip inspect max-incomplete low {number}
ip inspect one-minute high {number}
ip inspect one-minute low {number}
ip inspect tcp max-incomplete host {number} block-time {minutes}
Пример:
ip inspect tcp synwait-time 20
ip inspect tcp idle-time 60
ip inspect udp idle-time 20
ip inspect max-incomplete high 400
ip inspect max-incomplete low 300
ip inspect one-minute high 600
ip inspect one-minute low 500
ip inspect tcp max-incomplete host 300 block-time 0
Rate Limit:
interface N
no ip unreachables
ip icmp rate-limit unreachable [df] {milliseconds}
Например: ip icmp rate-limit unreachable 1000
interface N
rate-limit {input | output} [access-group [rate-limit] acl-index] {bps} {burst_normal}
{burst_max} conform-action {action} exceed-action {action}
Пример 1:
interface serial0
rate-limit output access-group 100 64000 4000 4000 conform-action transmit exceed-action drop
access-list 100 permit icmp any any echo
access-list 100 permit icmp any any echo-reply
Пример 2:
access-list 100 permit tcp any host eq www established
access-list 101 permit tcp any host eq www
interface serial0
rate-limit output access-group 100 1544000 64000 64000
conform-action transmit exceed-action drop
rate-limit output access-group 101 64000 16000 16000
conform-action transmit exceed-action drop
Мелочи:
no ip directed-broadcast
no service tcp-small-servers
no service udp small-servers
ip cef
class-map match-any http-hacks
match protocol http url "*default.ida*"
match protocol http url "*x.ida*"
match protocol http url "*cmd.exe*"
match protocol http url "*root.exe*"
policy-map mark-inbound-http-hacks
Router(config-pmap)#class http-hacks
Router(config-pmap)#set ip dscp 1
access-list 101 deny ip any any dscp 1 log
access-list 101 permit ip any any
Внешний интерфейс:
interface Ethernet1/0
service-policy input mark-inbound-http-hacks
Внутренний интерфейс:
interface Ethernet1/1
ip access-group 105 out
Проверка:
show policy-map interface e1/0
no ip source-route
no cdp run
no ip unreachables
no ip proxy-arp
no ip redirects
no ip directed-broadcast - Защита от Smurf атак
Настроить Anti-spoofing ACL.
Установка шифрованного пароля для входа в привелегированный режим:
enable secret <пароль>
Установка пароля для доступа с консоли:
(config)#line console 0
(config-line)#login
(config-line)#password [пароль]
Установка пароля для входа через telnet:
(config)#line vty 0 4
(config-line)#login
(config-line)#password [пароль]
Установка oreka ( http://sourceforge.net/projects/oreka/ ) записи разговоров на Debian lenny.
Oreka представляет собой систему для записи аудио потоков VoIP SIP, Cisco Skinny (SCCP),
raw RTP или принимаемых через звуковую карту. Есть web-интерфейс для поиска и прослушивания записей из базы.
apt-get install subversion
apt-get install sox g++ libtool libxml2-dev liblog4cxx9-dev libace-dev \
libboost-dev libpcap0.8-dev libxerces-c2-dev libsndfile1-dev automake
svn co https://oreka.svn.sourceforge.net/svnroot/oreka/trunk oreka
cd oreka/orkbasecxx/
cat /usr/share/aclocal/libtool.m4 >>aclocal.m4
automake -a
libtoolize --force
make -f Makefile.cvs
На ошибки не обращаем внимание и повторяем последние две команды.
automake -a
make -f Makefile.cvs
Ну вот, теперь можно собирать
./configure
make
make install
cd ../orkaudio/
cat /usr/share/aclocal/libtool.m4 >>aclocal.m4
libtoolize --force
automake -a
make -f Makefile.cvs
Повторяем последние две команды
automake -a
make -f Makefile.cvs
./configure
make
make install
orkaudio debug
Эта заметка, возможно, окажется полезной начинающим. Настраивая шлюз 5350,
столкнулся со следующей проблемой - звонок отлично проходил во все стороны,
но если при звонках с ТФОП в пакете АОН отсутствовал идентификатор абонента А,
звонок заворачивался на модемный пул CISCO 5350.
Такая ситуация встречалась например, при звонках с сотового телефона у которого включена услуга анти-АОН,
а так же при звонках с некоторых АТС, в частности из Горно-Алтайска.
Решение вопроса оказалось очень простым - для пропуска таких звонков,
необходимо во входящем диал-пире установить answer-address T:
dial-peer voice 20 pots
description #Incoming from POTS
huntstop
answer-address T
incoming called-number .T
direct-inward-dial
port 3/0:D
forward-digits all
В случае отсутствия answer-address T, звонок без АОН проключается на модемный пул.
Регулярное выражение Т подразумевает любое количество цифр, включая 0,
что соответствует и случаю отсутствия идентификатора вызывающей стороны.
Выход - поставить на интерфейсе туннеля MTU 1500, вместо 1476.
Проблема возникает при попытке протолкнуть пакет размером 1500 байт
с выставленным DF (don't fragment запрещена фрагментация) битом через интерфейс 1476 байт.
Другие решения:
interface ethernet0
ip policy route-map clear-df
route-map clear-df permit 10
match ip address 101
set ip df 0
access-list 101 permit tcp 10.1.3.0 0.0.0.255 any
или
interface tunnel0
ip tcp adjust-mss 1436
Задача: урезать входящий траффик для клиента 192.168.0.1 до 128Kbit/s на маршрутизаторе cisco.
Решение:
На маршрутизаторе вводим следующие команды
в режиме conf t
access-list 145 permit ip any host 192.168.0.1
далее врежиме конфигурации интерфейса
traffic-shape group 145 128000 7936 7936 1000
теперь все режется.
На cisco выполнить следующие команды в режиме configure terminal:
ip rcmd rsh-enable
ip rcmd remote-host hellman 192.168.0.1 hellman2 enable
где hellman имя пользователя на циске,
hellman2 имя пользователя на машине 192.168.0.1 с которой забирается статистика.
Настройка статистики:
в режиме конфигурации интерфейса с которого хотим снимать статистику
ip accounting output-packets
Для сбора и обработки на машине 192.168.0.1 из-под пользователя hellman2 выполнить:
/usr/bin/rsh -l hellman cisco clear ip accounting checkpoint
/usr/bin/rsh -l hellman cisco clear ip accounting
/usr/bin/rsh -l hellman cisco sh ip accounting checkpoint
output этих команд будет статистика ip accounting.
1. Cisco PIX/ASA
ciscoasa(config)#access-list inside_test permit icmp any host 192.168.1.1
ciscoasa(config)#capture inside_interface access-list inside_test interface inside
The user pings the inside interface of the ASA (ping 192.168.1.1). This output is displayed.
ciscoasa#show capture inside_interface
1: 13:04:06.284897 192.168.1.50 > 192.168.1.1: icmp: echo request
2. Cisco router
Создаем ip access-list которым будем "ловить" интересующий нас трафик.
routerA(conf)# access-list 111 permit ip 10.10.10.0 0.0.0.255 10.10.15.0 0.0.0.255
routerA(conf)# access-list 111 permit ip 10.10.15.0 0.0.0.255 10.10.10.0 0.0.0.255
Запускаем команду на выполнение и смотрим результат:
routerA# debug ip packet 111 detail
IP packet debugging is on (detailed) for access list 111
Mar 1 00:10:32.975: IP: tableid=0, s=10.10.10.5 (FastEthernet0/0), d=10.10.15.1 (Serial2/0), routed via FIB
Это решение не работает с fast-switching (ip route-cache).
interface FastEthernet0/2
port security max-mac-count 1
port security action shutdown
!
interface FastEthernet0/3
port security max-mac-count 3
port security action shutdown
!
Маки запоминаются сами. Чтоб почистить то что киска запомнила нужно
сделать clear port-security насколько помню.
conf t
Switch(config)# monitor session session source interface1 both
Switch(config)# monitor session session destination interface2
где interface1 это "реальный порт"
interface2 это "порт для мониторинга"
both значит что будет прослушиваться весь трафик (и туда и обратно), но можно поставить и rx или tx.
После установки OpenSuse 10.3 или 11 внимательный пользователь может заметить,
что установленный по умолчанию beagle (приложение для организации поиска на десктопе,
написанное на C# и использующее Mono:
1) Потребляет ресурсы CPU (beagled), (powertop: несет ответственность за ~10% cpu wakeups,
что уменьшает время проводимое процессором в sleep режиме).
2) Создает несанкционированный пользователем дубль его личных данных (таковы установки по умолчанию)
3) Постепенно забивает все больше и больше места на диске под свою базу.
Удалить beagle вместе со всеми плагинами к другим программам, можно 1-2 командами:
rpm -ev `rpm -qa | grep beagle | grep -v libbeagle` `rpm -qa | grep kerry`
rm -rf /var/cache/beagle/
killall beagled
Иногда требуется в Linux записать на диск или получить доступ к содержимому
дисковых образов в формате Nero (*.nrg), без установки проприетарного ПО.
Существует утилита nrg2iso, но её искать не обязательно, т.к. можно обойтись системной утилитой dd
Применяем утилиту dd (программа для конвертирования и копирования файлов).
Единственное отличие формата Nero от ISO заключается в наличии "шапки" в 300 килобайт,
которая приклеивается Nero к ISO файлу.
Преобразование формата сводится к вызову команды:
dd bs=1k if=image.nrg of=image.iso skip=300
описание параметров:
bs=1k : block size = 1kbyte / размер блока
if=image.nrg : input file / файл-источник
of=image.iso : output file / файл-результат
skip=300 : пропустить 300 блоков
Также, возможно смонтировать образ диска в формате Nero:
mount image.nrg /path -o offset=$((1024*300))
Ставим порт /usr/ports/sysutils/cdrtools
Пишем CD или DVD:
mkisofs -RJD -jcharset=koi8-r /path/to/files | burncd -f /dev/acd0 -s 8 -e data - fixate
Предварительно RW диск, для перезаписи, можно почистить командой:
burncd -f /dev/acd0 blank
Ключи mkisofs
- R - создать Rock Ridge - расширение файловой системы ISO 9660, разработанное
для хранения файловых атрибутов, используемых в операционных системах POSIX
-J - создать файловую систему Joliet (имена файлов длиннее 8.3, национальные символы в них и т.п.)
-D - убрать ограничение на глубину вложенных директорий
-jcharset=koi8-r - указываем кодировку имен файлов на диске, чтобы корректно
перекодировались в UCS-2 используемый в Joliet
Ключи burncd
-s 8 - скорость записи на диск (по умолчанию 4)
-e - извлечь диск после записи
data - тип данных
- - получение данных с stdin
fixate - закрыть сессию после записи.
Для записи DVD+RW/-RW дисков ставим порт /usr/ports/sysutils/dvd+rw-tools
Пишем:
growisofs -Z /dev/acd0 -r -J -speed=8 /path/to/files
Добавляем дополнительные файлы:
growisofs -M /dev/acd0 -r -J -speed=8 /path/to/more_files
Перекодирование DVD в DivX:
Ставим порты:
/usr/ports/sysutils/vobcopy
/usr/ports/multimedia/mplayer
Грабим содержимое DVD:
mount /cdrom
vobcopy /cdrom
Перекодируем *.vob в DivX 4/5:
cat *.vob | mencoder -o mymovie.avi \
-oac mp3lame -lameopts br=192:vbr=2 \
-ovc lavc -lavcopts vcodec=mpeg4:vhq:keyint=250 -vop pp lb -
Для кодирования в DivX 3 в поле vcodec можно указать msmpeg4.
Создание загрузочного USB Flash на базе ISO образа, без форматирования
и потери сохраненных на Flash данных (ставится прямо в VFAT, используя свободное место)
Устанавливаем пакет livecd-tools
yum install livecd-tools
Создаем загрузочный USB Flash (устройство /dev/sdb1)
livecd-iso-to-disk livecd.iso /dev/sdb1
Возможные проблемы и их решения:
Если программа выдала сообщение "Partition isn't marked bootable!", запускаем:
parted /dev/sdb
Выполняем команду print и смотрим номер раздела (если раздел один, то будет 1)
Выполняем команду: toggle 1 boot
Выходим из parted: quit
Или в fdisk используем команду "a".
Если программа выдала сообщение "Need to have a filesystem label or UUID for your USB device":
dosfslabel /dev/sdb1 usbdisk
вместо usbdisk можно указать любое имя, на ваше усмотрение.
Если программа выдала сообщение "MBR appears to be blank", копируем образ MBR:
cat /usr/lib/syslinux/mbr.bin > /dev/sdb
Если fdisk -l /dev/sdb выдает "Partition has different physical/logical endings!" - нужно переформатировать Flash:
Создаем в fdisk один primary раздел типа 6 (FAT)
Форматируем: mkdosfs -n usbdisk /dev/sdb1
Тестируем подготовленный загрузочный Flash:
qemu -hda /dev/sdb1 -m 256 -std-vga
Если при загрузке пишет: "SYSLINUX 3.xx ... EBIOS Load error - Boot error",
нужно обновить пакет syslinux до версии 3.50 или выше.
Я не касаюсь качества кодирования, тем более что в архиве есть заметка про двухпроходное кодирование.
Берем DVD, монтируем его как файловую систему, и переносим содержимое
как файлы на диск. Очень удобно, если DVD невысокого качества и у него
время от времени возникают ошибки чтения. Если по несколько раз
монтировать/размонтировать плохой диск, то по частям удается скопировать
его полностью.
mount /dev/dv /mnt/dvd
cp /mnt/dvd /home/DVDrip
В итоге, в файле /home/DVDrip появятся директории VIDEO_TS и AUDIO_TS.
После этого DVD можно проигрывать с жесткого диска командой:
mplayer dvd:// -dvd-device /home/DVDrip
Предположим, у диска есть несколько звуковых дорожек (с дубляжом и без)
и несколько субтитров (русские-английские). Задача - разодрать DVD на
два avi (с разными звуковыми дорожками, поскольку контейнер avi не
позволяет иметь одновременно несколько дорожек) и отдельно иметь русские
и английские субтитры.
В первую очередь выясним размер черной рамки на DVD.
Для этого запустим DVD с середины и запустим автоматическое определение полей:
mplayer dvd://1 -dvd-device ./ -vf cropdetect -ss 50:00
Кодирование самого видео можно сделать с помощью двухпроходного
кодирования два раза для каждого из языков. При этом первый проход можно
сделать всего один раз (в итоге получится трёхпроходное кодирование):
mencoder dvd:// -dvd-device /home/DVDrip -vf crop=688:320:24:130 -oac lavc -ovc lavc \
-lavcopts vcodec=mpeg4:vhq:vqmin=2:autoaspect:v4mv:mbd=2:trell:vpass=1 -o /dev/null
(единственный результат сего действа файл divx.log , используемый при
вторых проходах)
mencoder dvd:// -dvd-device /home/DVDrip -alang=ru \
-vf crop=688:320:24:130 -oac lavc -ovc lavc \
-lavcopts vcodec=mpeg4:vhq:vqmin=2:autoaspect:v4mv:mbd=2:trell:vpass=1 -o out[ru].avi
mencoder dvd:// -dvd-device /home/DVDrip -alang=en \
-vf crop=688:320:24:130 -oac lavc -ovc lavc \
-lavcopts vcodec=mpeg4:vhq:vqmin=2:autoaspect:v4mv:mbd=2:trell:vpass=2 -o out[en].avi
(качества звука и видео я не касаюсь, пусть они будут на вашей совести)
Т.е. теперь есть две авишки (out[ru].avi/out[en].avi) - с дубляжом и
без.
Я люблю смотреть заграничные фильмы без дубляжа, но поскольку не
слишком хорошо знаю язык,
то предпочитаю иметь перед глазами субтитры.
Субтитры в формате vobsub выдрать из DVD легко, но они будут храниться в
виде картинок, а не текста. Их размер примерно 4-2 МБ. Если для вас это
некритично,
то можно остановится на этом, иначе можно попробовать их OCR-ить, что не слишком
легко организовать под Линуксом.
Итак:
mencoder -alang en -slang en -dvd-device /home/DVDrip dvd:// -ovc copy \
-oac copy -o /dev/null -vobsubout subtitles-en
mencoder -alang en -slang ru -dvd-device /home/DVDrip dvd:// -ovc copy \
-oac copy -o /dev/null -vobsubout subtitles-ru
В итоге получится по паре файлов с расширениями .sub и .idx
Вообщем-то, не каждый медиа-проигрыватель понимает это формат, но с mplayer-ом в этом смысле всё в порядке:
mplayer out[en].avi -vobsub subtitles-ru -spuaa 4
Заметьте, что в параметре vobsub субтитры должны быть указаны без расширения,
а spuaa включает интенсивное сглаживание субтитров.
Как писать UDF в режиме пакетной записи, при помощи программы udftools.
1) В файле /etc/default/udftools раскомментировать
DEVICES="/dev/hd?" (у меня /dev/hdb)
2) Вставляем диск.
3) Форматируем RW.
#dvd+rw-format -f /dev/hdb
4) Создаем на диске UDF fs
#mkudffs /dev/hdb
5) Запускам пакетную запись:
#/etc/init.d/udftools start
6) Создать папку для монтирования:
# md /mnt/udf
7) Монтируем диск (через пакетное устройство)
#mount -t udf -o utf8,noatime /dev/pktcdvd/0 /mnt/udf
8) Используем диск как дискету
9) Отмонтируем диск
#umount /mnt/udf
10) Останавливаем пакетную запись:
#/etc/init.d/udftools stop
11) eject
После попыток записать файл более 1 Гб - он не прочитался.
Эта ошибка решается компиляция нового ядра - последнее на данный момент 2.6.23.
Для этого при конфигурировании включаем поддержку UDF и поддержку пакетной записи.
Обновив ядро мы смело копируем диск UDF с файлом более 4 Гб.
Задача ужать стандартный GNOME-LiveCD Fedora7 до 400 Мб.
Ниже журнал действий.
1. Извлекаем из iso образа LiveCD squashfs.img.
mount -o loop ./Fedora-7-Live-i686.iso /mnt/cdrom
копируем все в отдельную директорию директорию /mnt/disk/LiveCD/newcd
umount /mnt/cdrom
2. Монтируем squashfs.img и извлекаем из него os.img
mount -o loop -t squashfs /mnt/disk/LiveCD/newcd/squashfs.img /mnt/cdrom
копируем содержимое в /mnt/disk/LiveCD/new_ext3
umount /mnt/cdrom
3. Монтируем ext3 образ /mnt/disk/LiveCD/new_ext3/os.img
mount -o loop /mnt/disk/LiveCD/new_ext3/os.img /mnt/disk/LiveCD/new_ext3/sysroot
4. Удаляем лишнее и устанавливаем недостающее.
chroot /mnt/disk/LiveCD/new_ext3/sysroot /bin/sh
su -
mount /proc
mount /sys
rm -rf /usr/share/doc
в /usr/share/locale/ - оставляем только русские и английские локали
cd /usr/share/icons; rm -rf Bluecurve gnome
В /usr/share/pixmaps заменяем недостающее, чистим pixmaps/backgrounds/
копируем свою фоновую картинку
cp background.jpg /usr/share/gdm/themes/FedoraFlyingHigh
cp background.jpg /usr/share/backgrounds/images/default.jpg
Чистим /usr/share/backgrounds
Удаляем пакеты с китайскими шрифтами:
rpm -e fonts-chinese fonts-arabic fonts-korean fonts-japanese
Если rpm ругается, делаем "rpm --rebuilddb"
Если нужно создать какие-то директории или произвести действия в момент старта livecd
правим fedora-live в /etc/rc.d/init.d
Ставим желаемые пакеты, например, конфигуратор PPTP:
rpm -Uvh http://pptpclient.sourceforge.net/yum/stable/fc7/pptp-release-current.noarch.rpm
yum --enablerepo=pptp-stable install pptpconfig
....
umount /proc
umount /sys
5. После приведения os.img в нужный вид, создаем новый пустой os.img и
копируем содержимое старого (нужно забить образ нулями, чтобы он лучше сжался,
иначе изменения будут только в метаданных и итоговый образ squashfs после сжатия получиться больше чем начальный).
cd mnt/disk/LiveCD/new_ext3
dd if=/dev/zero of=new_os.img bs=1k count=4096k
/sbin/mkfs.ext3 -F -L "LiveCD" -m 1 new_os.img
/sbin/tune2fs -c0 -i0 -Odir_index -ouser_xattr,acl new_os.img
Монтируем новый образ
mkdir /mnt/disk/LiveCD/new_ext3/new_sysroot
mount -o loop ./new_os.img /mnt/disk/LiveCD/new_ext3/new_sysroot
Копируем содержимое старого через rsync, чтобы сохранить расширенные атрибуты файлов.
rsync -a -v --acls --xattrs --hard-links /mnt/disk/LiveCD/new_ext3/sysroot /mnt/disk/LiveCD/new_ext3/new_sysroot
незабываем размонтировать и переименовать новый образ
umount /mnt/disk/LiveCD/new_ext3/sysroot
umount /mnt/disk/LiveCD/new_ext3/new_sysroot
rm /mnt/disk/LiveCD/new_ext3/new_sysroot
mv /mnt/disk/LiveCD/new_ext3/new_os.img /mnt/disk/LiveCD/new_ext3/os.img
6. Сжимаем ext3 образ
rm /mnt/disk/LiveCD/newcd/squashfs.img
cd /mnt/disk/LiveCD/new_ext3/
/sbin/mksquashfs os.img sysroot /mnt/disk/LiveCD/newcd/squashfs.img
7. Создаем iso образ для записи на CD:
mkisofs -o ./live.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
-boot-info-table -J -r -hide-rr-moved -V "Fedora-7-Live-i386" /mnt/disk/LiveCD/newcd/
Если появится желание изменить метку диска Fedora-7-Live-i386, не забудьте поменять ее в isolinux/isolinux.cfg
ISO9660 не позволяет писать файлы 4Gb и более. Потому про mkisofs можно забыть.
Используется файловая система UDF. Замечательно читается в более-менее последних версиях Windows.
Для этого нам нужны udftools: http://sourceforge.net/projects/linux-udf/
Алгоритм таков: создаем образ на жестком диске, копируем туда файл, записываем образ на DVD.
Берем размер образа (в секторах) по следующей таблице:
DVD-R/DL = 4,171,712
DVD+R/DL = 4,173,824
DVD-R/SL = 2,298,496
DVD+R/SL = 2,295,104
Размер сектора 2048 байт
Возмем DVD+R/single layer для примера.
Делаем образ:
$ dd if=/dev/zero of=/mnt/data/image.udf bs=2048 count=2295104
Создаем файловую систему:
mkudffs --lvid=Volume\ name /mnt/data/image.udf
Монтируем образ:
sudo mount -o loop /mnt/data/image.udf /mnt/dvdimage
Аналогичная запись в fstab:
/mnt/data/image.udf /mnt/dvdimage udf noauto,rw,users,loop=/dev/loop0 0 0
Копируем файлы. Размонтируем образ.
Записываем образ на диск:
growisofs -dvd-compat -Z /dev/dvd=/mnt/data/image.udf
Примечания:
- Если не ошибаюсь, опиция -dvd-compat нужна только на DVD-R и не нужна на DVD+R.
Но проблем замечено не было, даже когда писалось с -dvd-compat на DVD+R.
- Образ замечательно пишется каким-нибудь k3b, вот только проверить его неудастся (поскольку это не ISO 9660)
- UDF поддерживает пользователей, права, хардлинки, и по-моему симлинки.
Так что можно использовать для бекапа. Вот только в Windows XP такие вещи интересно читаются:
хардлинки - просто файл копируется, а симлинки - создается файл нулевой длины
- в Линуксе работа с udf (например просмотр директорий) происходит чуть медленнее,
с ISO9660, особенно если там хардлинки и симлинки.
- САМОЕ ВАЖНОЕ: В ядрах 2.6.17 и выше, вы не сможете записать на UDF файл более 1Gb.
Поддержку больших файлов из UDF убрали мотивируя тем, что драйвер как-то портит что-то в памяти в ядре.
Лично я глюков не заметил. Хоть у меня стоит 2.6.20, я держу 2.6.16.19 именно для того,
чтобы записывать большие файлы. Поскольку каждый раз перегружаться неудобно,
смотрю в сторону lguest http://www.opennet.ru/opennews/art.shtml?num=9698http://lwn.net/Articles/218766/
- используя UDF вы можете писать на DVD как на обычную дискету. См сюда: http://www.opennet.ru/base/sys/udf_cdrom.txt.html . Сам пробовал - получалось :)
Примечание: вообще IMHO замечательная файловая система. И почему разработку udftools прекратили?
Может найдется кто-то из глубокоуважаемого Linux- общества, который продолжит благородное дело?
Предположим, на CD/DVD был записан образ sep2006.iso.
Вычисляем для него контрольную сумму:
$ cat sep2006.iso | md5sum
cc363de222ba6fe7455258e72b6c26ca -
Определяем число записанных в iso 2048 блоков:
$ echo $(( $(ls -l sep2006.iso | awk '{ print $5 }') / 2048 ))
169383
или после выполнения mkisofs запоминаем цифру в строке "169383 extents written (330 MB)"
Вычисляем контрольную сумму записанного диска:
$ dd if=/dev/hdc bs=2048 count=169383 | md5sum
cc363de222ba6fe7455258e72b6c26ca -
В данном примере показано восстановление образа снятого с "криво" записанного диска FreeBSD 6.0.
1. Находим при помощи гугла rsync-зеркала с интересующими нас образами. Для задачи из примера их список можно увидеть здесь.
Выбираем ближайшие зеркала с отметкой rsync напротив адреса:
ftp2.ru.freebsd.org и ftp5.ru.freebsd.org.
2. Узнаем какие "модули" доступны у выбранных rsync-серверов при помощи команды:
rsync -n -vv ftp2.ru.freebsd.org::
Ответ - два слова FreeBSD, откуда заключаем, что имя интересующего нас модуля - FreeBSD. Для сервера ftp5.ru.freebsd.org узнать имя модуля таким способом не удастся - этот сервер возвращает в ответ только информацию "рекламного" характера. Пояснения к команде: ключ -n не позволяет утилите rsync загружать ничего; ключ -vv позволяет увидеть на экране больше информации о происходящем; два двоеточия после имени сервера обязательны (можно использовать вместо них rsync:// перед именем сервера, но это длиннее).
3. Изучаем расположение каталогов и файлов на сервере:
rsync -n -vv ftp2.ru.freebsd.org::FreeBSD/
К предыдущей команде добавлено имя модуля и следующий за ним слэш (/). Слэш нужен для указания того, что необходимо отобразить листинг директории, а не ее саму. В результате выполнения команды можно увидеть, что файловая структура (в данном случае) повторяет расположение файлов на FTP-сервере. После чего определяем где лежат искомые образы (листаем интересующие нас каталоги) и продолжаем. К сожалению, у меня не получилось заставить работать ключик --list-only из man rsync и пришлось находить вышеописанный способ методом научного тыка.
4. Предположим, что образ диска уже снят, например так:
Пояснения к команде: -z желателен для сжатия передаваемой информации (действенность не проверял); --stats выводит после окончания подробную информацию о сделанном; --progress отображает процент выполнения текущей задачи.
6. Убеждаемся, что сумма восстановленного образа совпадает с суммой образа с официального сайта.
Данным методом я восстановил образы дисков с FreeBSD 6.0, записанных при помощи программы Nero добрым человеком с толстым каналом. readcd ругался на эти диски в самом конце каждого из них. Входящий трафик, в моем случае, для обоих дисков составил меньше 1 Mb.
Вот такой простой скрипт:
#!/bin/sh
retval=`/sbin/mount | grep /mnt/cdrom`
if [ -n "$retval" ];
then /sbin/umount /mnt/cdrom 1> /dev/null 2> /dev/null
if [ "$?" -ne 0 ];
then echo "Не могу размонтировать CDROM"
else echo "Размонтировал CDROM"
eject /dev/cdrom
fi
else /sbin/mount /dev/cdrom 1> /dev/null 2> /dev/null
if [ "$?" -ne 0 ];
then echo "Не могу смонтировать CDROM"
else echo "Примонтировал CDROM"
fi
fi
П.С. копируем в каталог /sbin под именем cdm. Сам определяет состояние
Решение такое:
1. сборка и инсталляция ядра с устройствами:
device scbus
device atapicam
device cd
device pass
2. создание файлов устройств cd0, cd1 с помощью /dev/MAKEDEV
3. disklabel -rw cd1c auto
4. newfs cd1c
4.1. Можно включить softupdates: tunefs -n enable cd1
5. mount /dev/cd1c /mnt/dvdram
Все. Скорость записи ~ 1.2 Mb/s.
-наклейки на диски вредны
-для длительного хранения CD-R и DVD╠R лучше чем CD-RW и DVD+-RW;
-диски хранить в Jewel-Cases стоймя (как книги) а не лёжа или в "шпинделях";
-в темном, прохладном(4 C-20 C) и сухом месте.
Для начала:
mdconfig -a -t vnode -u0 -f /share/iso/slackware-9.0-install.iso
затем
mount -t cd9660 /dev/md0 /mnt/iso
Обратный процесс:
umount /dev/md0
mdconfig -d -u0
p.s. Может не работать если в ядре нет "device md"
man atapicam, если FreeBSD старая, то см. ссылку.
Ядро нужно пересобрать с
device ata
device atapicd # or atapifd or atapist
device atapicam
device scbus
device pass
device cd # or sa or da
cd /usr/ports/sysutils/cd9660_unicode
make && make install
грузить модуль через
kldload /lib/cd9660_unicode/cd9660_[unicode|koi8-r|iso-8859-5|cp866].ko
Перед записью первой сессии на CD-RW его нужно очистить:
cdrecord -dev 0,0,0 blank=fast или blank=full
Запись первой сессии
создаем iso первой сессии:
mkisofs -V "volume_ID" -D -l -L -N -R -J -v -o 1.iso dir1
cdrecord -v speed=4 -dev=0,0,0 -multi 1.iso
Записываем последующие сессии:
Получаем информацию о предыдущей сессии (для -C в mkisofs):
cdrecord -msinfo -dev=0,0,0
Создаем вторую директорию dir2 как dir1/dir2.
Создаем образ второй сессии:
mkisofs -M /dev/scd1 -C start_rec,end_rec -D -l -L -N -R -J -v -o cdrom.iso dir1
Записываем на CD вторую сессию:
cdrecord -v speed=4 dev=0,0,0 -multi 2.iso
PS. для некоторых приводов нужно писать cdrecord -multi -data
Создание ISO образа:
mkisofs -V "volume_ID" -D -l -L -N -J -R -v -o cdrom.iso директория
Пример записи образа на CD-R/RW диск:
cdrecord -dev=0,1,0 -speed=4 -v cdrom.iso
cdrecord dev=ATAPI:0,0,0 -v cdrom.iso
wodim -dev=/dev/cdrw -speed=16 -eject -v cdrom.iso
где,
-speed=4 - скорость записи,
-v - вывод информации о процессе записи
-dev=0,1,0 - записывающее устройство, определяется через cdrecord -scanbus, можно сразу указывать устройство, например, /dev/cdrw
wodim - название модифицированной команды cdrecord в Debian/Ubuntu
Чистка CD-RW перед записью:
cdrecord -dev=/dev/cdrw -v blank=fast
Для подключения IDE накопителя в старых Linux ядрах нужно было добавить в linux lilo
append="hdc=ide-scsi"
и включить в ядре поддержку эмуляции SCSI.
Некоторые полезные опции.
-toc -atip -prcap - выдать полную информацию о накопителе.
-scanbus - определить параметры для -dev (можно /proc/scsi/scsi)
-dummy - запись в режие тестирования (без реального прожигания диска).
-fix - исправить недописавшийся диск.
-eject - после записи вытащить CD
-blank=all очистить CR-RW перед записью.
-checkdrive - найти подходящий драйвер устройства, затем можно прописать в -driver=?
-audio - запись аудио диска (см. cdda2wav).
mkisofs -print-size - расчитать скролько потребуется места для записи директории.
Создание ISO образа с CD/DVD диска (readom - вариант readcd в Debian/Ubuntu):
readcd dev=0,0,0 f=cdimage.raw
readom dev=/dev/cdrw f=cdimage.raw
Создание wav-файлов из звукового CD:
cdda2wav -S 32 -D /dev/cdrom -v 255 -B
Создание звукового CD из mp3:
find . -name "*.mp3" -exec mpg123 --cdr {}.cdr {} \;
cdrecord -v speed=4 dev=0,0,0 -pad -audio *.cdr
В Joliet файлы хранятся в unicode, соответственно codepage=unicode.
Если файлы записаны в 866 кодировке нужно добавить ",codepage=866"
mount -t iso9660 -o iocharset=koi8-r,ro,noexec,mode=0444 /dev/cdrom /mnt/cdrom
или в /etc/fstab:
/dev/cdrom /mnt/cdrom iso9660 noauto,user,ro,noexec,mode=0444,iocharset=koi8-r
а затем: mount /mnt/cdrom
Если в момент запуска приложения в wine получаем ошибку:
preloader: Warning: failed to reserve range 00000000-60000000
err:dosmem:setup_dos_mem Cannot use first megabyte for DOS address space, please report
Решить проблему можно убрав нижнюю границу маппинга адресов:
sysctl -w vm.mmap_min_addr=0
Для изменения системных установок правим содержимое файла /etc/sysctl.conf
заменив "vm.mmap_min_addr = 65536" на "vm.mmap_min_addr = 0"
Если Вы хотите установить Internet Explorer автоматически используйте IEs4linux.
Это руководство для тех пользователей которые не хотят использовать IEs4linux.
1.Создаем новую конфигурацию wine в другой директории с помощью wineprefix.
wineprefixcreate --prefix ~/.wineIE6
2. Следующим шагом установим в переменной путь к каталогу для IE6, выполняем
export WINEPREFIX="$HOME/.wineIE6"
3.Необходимо удалит или переместить следующие файлы, иначе wine не даст при установке IE обновить эти файлы
Program Files/Internet Explorer/iexplore.exe
в каталоге ~/.wineIE6/windows/system32
mshtml.dll
shdoclc.dll
shdocvw.dll
shlwapi.dll
urlmon.dll
wininet.dll
4.Запускаем winecfg, переходим на закладку Библиотеки(Libraries ) и добавляем следующее приложение и библиотеки:
iexplore.exe
mshtml
shdoclc
shdocvw
shlwapi
urlmon
wininet
mlang
И устанавливаем их в Сторонняя, встроенная (native, builtin.)
5.Устанавливаем версию эмуляции 2000 в winecfg.
6.В реестре надо указать версию IE ниже чем 6.
7. HKEY_LOCAL_MACHINE->Software->Microsoft->Internet Explorer->Version Например 5.0.
8.Запускаем IE6SETUP.EXE. Он должен установиться без ошибок.
(можно использовать параметр /q чтобы он не задавал вопросов при инсталляции)
9.Теперь нужно зарегистрировать все библиотеки (dll) в каталоге ~/.wineIE6/windows/system32 .
Открываем любую консоль переходим в каталог и выполняем команду дважды:
for i in *.dll *.ocx; do regsvr32 /i $i; done
10.С этого момента IE6 будет запускаться но не будет ничего отображать.
Чтобы исправить эту проблему надо скачать файл msls31.dll
(используйте google) и поместить его в ~/.wineIE6/windows/system32.
Можно взять с машины с Windows.
11.Теперь Вы можете запускать IE6.
WINEPREFIX="$HOME/.wineIE6" wine iexplore.exe
Первоисточник текста на английском: http://appdb.winehq.org/appview.php?versionId=469
Автор: Artem Tashkinov, перевод: Spike.
1. Качаем wine с http://www.winehq.org я использую wine 0.9.13 в сборке для
Debian.
2. Запускаем wine, пусть создаст папку ~/.wine/
3. Качаем Dcom98 с
http://download.microsoft.com/msdownload/d...6/en/dcom98.exe , или с
http://dalcom.kha.ru/dcom98.exe. Копируем Dcom98 в ~/.wine/drive_c/
4. Запускаем winecfg и настраиваем wine по своему вкусу. Особо отмечаю: на
вкладке "Графика"
убираем галочку с "Разрешить менеджеру окон управлять окнами".
5. Стартуем wine DCOM98.EXE /C /T:c:\\temp /Q (из папочки ~/.wine/drive_c/).
6. Копируем все из папки ~/.wine/drive_c/temp/ в ~/.wine/drive_c/WINDOWS/system/
7. Опять стартуем winecfg, добавляем приложение Dcom98.exe,
и для него в соседней вкладке прописываем библиотеку ole32=Родная (windows).
8. Запускаем wine DCOM98.EXE /Q (у меня оно тут, правда, выругалось, что у
меня система 2000, но ничего - дальше все нормально).
9. Копируем из установленной винды библиотеку msvcrt40.dll (входит в состав MS Office, например).
10. Стартуем winefile (можно и ручками через wine, но привыкайте к
удобствам ;-)), ставим 1С (v77).
11. Еще раз стартуем winecfg, добавляем приложение 1CV7.exe (у меня 1CV7s.exe),
для него прописываем исключительно нативные библиотеки rpcrt4, ole32, olepro32, oleaut32, msvcrt40.
12. Совет, который я не делал (у меня и так все нормально): чтобы в программе был русский шрифт
надо просто из компьютера где установлен Windows взять из папки fonts все шрифты и
скопировать их в папку ~/.wine/drive_c/windows/fonts.
Далее в файле настройки wine изменить в разделе [fonts]:
"Default" = "arial"
"DefaultFixed" = "fixed"
"DefaultSerif" = "Serif"
"DefaultSansSerif" = "SansSerif"
13. Стартуем 1С, добавляем базы. Для каждой базы делаем следующее: открываем в конфигураторе,
выбираем в меню "Администрирование" пункт "Кодовая страница таблиц ИБ".
Устанавливаем кодовую страницу в "+Текущая системная установка".
14. Обязательно надо снять галочку "Окна->Панель окон->показать".
15. Создаем ярлыки запуска, устало дышим, радуемся и благодарим г-на Нуралиева
(директор 1С) за классный продукт.
Ниже рассказ о том как запустить приложения в wine (например, D2GS)
без необходимости запуска X Window сервера:
- собираем wine с ключами --without-x --without-opengl;
- в ~/.wine/config меняем "GraphicsDriver" = "x11drv" на "GraphicsDriver" = "ttydrv".
Для изменения клавиш быстрого вызова в GTK2 приложениях на лету:
Для Gnome:
Проверяем не включено ли:
gconftool -g /desktop/gnome/interface/can_change_accels
Если false:
gconftool -t boolean -s /desktop/gnome/interface/can_change_accels true
Для других оконных менеджеров и приложений (не использующих gconf2):
echo gtk-can-change-accels = 1 >> ~/.gtkrc-2.0
Если не работает, например в SUSE, нужно создать пустой файл ~/.no-qtrc-to-gtkrc-mapping и перезайти в X-ы.
После того как горячее назначение клавиш включено, достаточно подвести курсор мыши
к нужному пункту меню приложения и нажать удобное сочетание клавиш, оно запоминается.
Для копирования данных в буфер обмена X Window из консоли следует использовать утилиты xclip и xsel.
Устанавливаем в Debian/Ubuntu:
sudo apt-get install xclip
в Fedora/RHEL/CentOS:
yum install xclip
Копируем вывод команды в буфер обмена:
sort file.txt | xclip
Выводим содержимое буфера обмена в стандартный поток, который записываем в файл:
xclip -o > file.txt
Например, так можно отсортировать данные в буфере обмена:
xclip -o | sort | xclip
посчитать число строк:
xclip -o | wc | xclip
или перекодировать текст:
xclip -o | iconv -f cp1251 -t utf-8 | xclip
Компана xsel, выполняет аналогичные действия:
pwd | xsel
xsel -o |less
Первым делом нужно проверить собрана ли библиотека freetype2 с опцией
TT_CONFIG_OPTION_BYTECODE_INTERPRETER,
как правило отключаемой в дистрибтуивах из-за лицензионных ограничений
Для владельцев ноутбуков внимание также можно обратить на сборку с опцией WITH_LCD_FILTERING,
но это может потребовать обновления и пересборки cairo и libXft.
В основанный на RPM дистрибутивах Linux, загружаем src.rpm пакет и пересобираем.
Разворачиваем исходные тексты:
rpm -i ~/rpmbuild/SRPMS/freetype-2.3.5-3.fc8.src.rpm
Пересобираем
rpmbuild -bb --with bytecode_interpreter ~/rpmbuild/SPECS/freetype.spec
или, если в spec файле определено %define without_bytecode_interpreter 1
rpmbuild -bb --with withhout_bytecode_interpreter=0 ~/rpmbuild/SPECS/freetype.spec
или перед сборкой редактируем spec файл и раскомментируем строчки связанные с bytecode
например для OpenSUSE - "%%patch100 -p 1 -b .bytecode"
Устанавливаем собранный пакет:
rpm -Uvh --force ~/rpmbuild/RPMS/freetype-2.1.4-2.fc7.x86_64.rpm
В последних версиях Debian/Ubuntu достаточно выбрать Bytecode interpreter и Subpixel rendering
настройки при выполнении
sudo dpkg-reconfigure fontconfig
Во FreeBSD при сборке порта по умолчанию включается TTF_BYTECODE_ENABLED:
cd /usr/ports/print/freetype2/
make WITH_LCD_FILTERING=yes
make install
Копируем Windows шрифты в ~/.fonts
Если загрузка шрифтов из этой директории в дистрибутиве не настроена, то
переходим в данную директорию и запускаем "mkfontdir" и "fc-cache ./"
В Debian/Ubuntu/Fedora можно поставить пакет msttcorefonts или msttcore-fonts.
Проводим тюнинг параметров fontconfig, создав ~/.fonts.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match target="font" >
<edit mode="assign" name="antialias" >
<bool>true</bool>
</edit>
</match>
<match target="font" >
<edit mode="assign" name="autohint" >
<bool>true</bool>
</edit>
</match>
<match target="font" >
<edit mode="assign" name="hinting" >
<bool>true</bool>
</edit>
</match>
<match target="font" >
<edit mode="assign" name="hintstyle" >
<const>hintfull</const>
</edit>
</match>
<match target="font" >
<edit mode="assign" name="rgba" >
<const>none</const>
</edit>
</match>
</fontconfig>
Описание по параметрам можно посмотреть на странице
http://fontconfig.org/fontconfig-user.html
Кратко о параметрах:
autohint - метод исправления дефектов растеризации,
следует поэкспериментировать включением/выключением в сочетании с установкой antialias.
antialias - антиалиасинг, сглаживание начертаний.
hinting - уточнение, шрифт с хинтингом получается тоньше;
hintstyle - стиль уточнения, при hinting =true можно попробовать в hintstyle - hintfull и hintnone
rgba - если none, то используется субпиксельное сглаживание.
В "System \ Preferences \ Preferred Applications" в качестве почтового клиента нужно прописать скрипт
/home/имя/open_mailto.sh %s
, содержащий:
#!/bin/sh
firefox https://mail.google.com/mail?view=cm&tf=0&to=`echo $1 | sed 's/mailto://'`
Если нужно открывать gmail не в новом окне, а в новом табе:
#!/bin/sh
firefox -remote "openurl(https://mail.google.com/mail?view=cm&tf=0&to=`echo $1 | sed 's/mailto://'`,new-tab)"")
Для уведомления о появлении почты в Gmail можно использовать программы:
gmail-notify - http://gmail-notify.sourceforge.net/
KGmailNotifier - http://www.kde-apps.org/content/show.php/KGmailNotifier?content=55375
gnome-gmail-notifier - http://code.google.com/p/gnome-gmail-notifier/
Утилита notify-send, входящая в состав пакета libnotify-bin, позволяет отправить через D-BUS уведомление,
которое будет отражено в GNOME в виде всплывающего окошка.
Пример:
notify-send -c info -t 1800000 "заголовок окна" "текст внутри окна"
где, "-t 1800000" - таймаут висения окна в милисекундах.
"-c info" - категория оповещения, список можно найти здесь:
http://www.galago-project.org/specs/notification/0.9/x211.html
В тексте можно использовать тэги: <b>жирный шрифт</b>, <i>наклонный</i>, <u>с подчеркиванием</u>,
<a href="...">ссылки</a>, <img src="..." alt="...">картинки, размером до 200x100</img>.
Интересные возможности по управлению оконным менеджером из командной строки предоставляет утилита wmctrl:
Получить список открытых окон:
wmctrl -l
Получить список открытых окон с отображением PID-процесса и инфрмацией о размере окна:
wmctrl -p -G -l
Сделать активным окно в названии которого есть слово licq:
wmctrl -a licq
Свернуть окно в названии которого есть слово 'mozilla':
wmctrl -r mozilla -b add,shaded
Закрыть окно по его имени:
wmctrl -F -c 'Debian bug tracking system - Mozilla'
Изменить заголовок окна для окна выбранного курсором мыши:
wmctrl -r :SELECT: -T "Selected Window"
Развернуть окно со словом video в заголовке на полный экран
wmctrl -r "video" -b toggle,fullscreen
Утилита x2x (http://x2x.dottedmag.net/) предназначена для контроля X дисплея одной машины,
клавиатурой и мышью с другой, т.е. позволяет одновременно работать с двумя X-серверами.
Активный дисплей выбирается в зависимости от установки фокуса мышью.
На обеих машинах создается единый буфер обмена.
Например, удобно принести ноутбук на работу, поставить рядом с рабочей машиной и работать одной клавиатурой и мышью.
Подключаемся с локальной машины на удаленную:
ssh -X хост x2x -east -to :0
где, "-X" - включение перенаправление X-протокола,
"-east" - относительная позиция управляющего окна (другой вариант "-west").
При перемещении курсора мыши на окно вторичной системы, команды клавиатуры и мыши будут переданы удаленному X-серверу.
Второй вариант запуска, при котором, в отличии от первого варианта,
будет создан единый буфер обмена.
На удаленной системе разрешаем подключение к X-серверу с локальной машины:
xhost +локальная_машина
На локальной системе выполняем:
x2x -to хост:0.0 -east
Где хост:0.0 определяет удаленный X-сервер к которому следует подключиться.
Для запуска x2x под Windows необходимо установить пакет Cygwin,
не забыв выбрать x2x в списке устанавливаемых программ.
При этом Windows может быть использована только в роли первичной управляющей системы,
к которой непосредственно подключена клавиатура и мышь.
Для подключения к удаленному Linux хосту выполняем в shell приглашении Cygwin:
x2x -fromwin -to адрес_linux_машины:0.0 -east
В библиотеке libx11 имеется поддержка кэширования символьных таблиц (compose-table-cache),
получаемых в результате парсинга "/usr/share/X11/locale/имя_локали/Compose" файлов локали (парсинг более 5000 строк при каждом запуске),
что позволяет сократить время запуска некоторых приложений (например, использующих Qt или Gtk) на 40-200 мс.
и уменьшить потребление памяти каждым приложением примерно на 240Кб (данные для UTF8 локали).
Для включения кэша достаточно в домашней директории создать каталог .compose-cache
mkdir $HOME/.compose-cache
В SUSE Linux данный механизм задействован по умолчанию, кэш находится в директории /var/cache/libx11/compose.
Для того чтобы убрать надоевший коричневый цвет, возникающий на несколько секунд
в процессе загрузки Ubuntu:
sudo gedit /etc/gdm/PreSession/Default
находим строки
# Default value
if [ "x$BACKCOLOR" = "x" ]; then
BACKCOLOR="#dab082"
fi
и меняем цвет на любой другой, например на чёрный:
# Default value
if [ "x$BACKCOLOR" = "x" ]; then
BACKCOLOR="#000000"
fi
Для запрещения кнопок перезагрузки и выключения в /etc/X11/gdm/gdm.conf нужно
исправить "SystemMenu=true" на "SystemMenu=false".
Затем перезапустить X-ы комбинацией клавиш Ctrl + Alt + Backspace.
Команды вызываемые для перезагрузки, выключения и засыпания, можно поменять
через переменные RebootCommand, HaltCommand и SuspendCommand.
Другие полезные настройки:
AutomaticLogin - логин для автоматического входа в систему.
AlwaysRestartServer - gdm будет при каждом входе перезапускать X сервер.
PostLoginScriptDir, PreSessionScriptDir, PostSessionScriptDir - пути к директории
со скриптами запускаемыми на разных этапах входа пользователя в систему.
SessionDesktopDir - директория с описанием вариантов сессий (/etc/X11/sessions/).
DefaultSession - сессия всегда выбираемая по умолчанию;
AllowRoot - запретить или разрешить входа под логином root;
GtkTheme, GraphicalTheme, GraphicalThemeDir - определение визуальной темы;
Browser - можно отключить показ пиктограмм для пользователей;
GlobalFaceDir - где хранятся пиктограммы (/usr/share/faces/)
Logo - путь к логотипу;
BackgroundColor - цвет фона;
BackgroundProgram - можно привязать хранитель экрана для формирования фона;
ShowLastSession -
Для kdm похожие настройки можно найти в файле /etc/X11/kdm/kdmrc
Также для настройки gdm можно использовать GUI интерфейс /usr/sbin/gdmsetup, для kdm - kdm_config
Ниже пример организации 32-битного chroot окружения в 64-битной системе.
Устанавливаем пакет schroot
aptitude install schroot
Создаем файл конфигурации /etc/schroot/schroot.conf:
[sid]
description=Debian sid (unstable)
location=/srv/chroot/sid
priority=3
users=YOUR_USER
groups=SOME_GROUP_LIKE_users
root-groups=YOUR_ADMIN_USER
Формируем chroot окружение:
debootstrap --arch i386 sid /srv/chroot/sid http://ftp.br.debian.org/debian
Установка программ в chroot:
schroot -c sid -p aptitude install wengophone
Монтируем /proc и /dev основной системы в chroot:
mount /dev /srv/chroot/sid/dev -o bind
mount /proc /srv/chroot/sid/proc -o bind
Разрешаем запуск графических приложений из chroot на основном X сервере:
xhost +
Запускаем приложения wengophone и skype:
schroot -c sid -p wengophone
schroot -c sid -p skype
Закрываем полный доступ к X серверу.
xhost -
Для обращения к буферу обмена из командной строки нужно использовать утилиту xclip (http://sourceforge.net/projects/xclip),
которая помещает в буфер обмена то что приходит через STDIN и выталкивает из буфера обмена в STDOUT.
Скопировать в буфер обмена: echo "test" | xclip
Вывести содержимое буфера обмена: xclip -o
Через опцию -sel можно выбрать буфер обмена:
clipboard (Ctrl+C,Ctrl+X, Ctrl+V или меню Copy/Paste в приложениях),
primary (средняя кнопка мыши), secondary.
Для вывода содержимого буфера обмена по Ctrl-v в bash, можно использовать .bashrc:
if [ -n "$DISPLAY" ] && [ -x /usr/bin/xclip ] ; then
# Work around a bash bug: \C-@ does not work in a key binding
bind '"\C-x\C-m": set-mark'
# The '#' characters ensure that kill commands have text to work on; if
# not, this binding would malfunction at the start or end of a line.
bind 'Control-v: "#\C-b\C-k#\C-x\C-?\"$(xclip -o -selection c)\"\e\C-e\C-x\C-m\C-a\C-y\C-?\C-e\C-y\ey\C-x\C-x\C-d"'
fi
Почему-то нигде нет информации о том, как во FreeBSD настраивается GDM/KDM
на предмет выбора загрузки оконных менеджеров.
Поэтому я решил написать короткое руководство.
1. Заходим в каталог '/usr/local/etc/dm/Sessions', создаем там текстовый файл с
расширением .desktop, например ion3.desktop:
%cd /usr/local/etc/dm/Sessions; touch ion3.desktop
2. Открываем файл в текстовом редакторе и пишем туда следующее:
[Desktop Entry]
Encoding=UTF-8
Name=Ion3
Exec=/usr/local/bin/ion3
Icon=
Type=Application
3. Ставим права доступа 0555:
%chmod 0555 ion3.desktop
Аналогичные файлы создаем для запуска других WM.
4. Перезапускаем наш DM.
Можно воспользоваться xvfb (X window virtual framebuffer, http://en.wikipedia.org/wiki/Xvfb),
X-сервером эмулирующим работу frame-buffer в памяти.
Установка в Debian Linux:
# apt-get install xvfb
Запуск X-сервера.
# Xvfb -shmem -screen 0 1280x1024x24
Запуск приложения, которому обязательно нужен X Сервер.
# DISPLAY=:0 xdpyinfo
Одна из неприятных особенностей тачпадов - срабатывание клика при случайном касании (tap-to-click).
Для отключения данной функции в Synaptic Touchpad, в xorg.conf необходимо добавить в секции Input Device:
Option "MaxTapTime" "0"
или
Option "SHMConfig" "on"
плюс запуск syndaemon -t -d (опция -t запрещает tapping и scrolling)
или настройка через gsynaptics
Проще всего установить готовые RPM пакеты из репозитория livna.org.
Подключаемся к репозиторию Livna:
rpm -Uhv http://rpm.livna.org/livna-release-6.rpm
rpm --import http://rpm.livna.org/RPM-LIVNA-GPG-KEY
Проверяем его доступность:
yum info kmod-nvidia
Для упрощения работы с пакетами устанавливаем дополнение Yum Extender:
yum install yumex
возможности которого доступны через утилиту yumex или меню Kmenu / System / Yum Extender.
Обновление ядра собранного для архитектуры i586 до i686 сборки (не обязательно).
Проверьте присутствие репозитория Livna в списке, зайдите в секцию Remove
и выберите текущее Linux ядро и пакет kernel-devel, нажмите "add to queue" и
перейдите в секцию Install. Найдя список ядер (Kernel), выберите ядро и пакет
kernel-devel для i686 архитектуры и нажмите добавить в очередь (add to queue).
Войдите в секцию Queue и нажмите "Process Queue". Перезапуситите компьютер.
Установка nVIDIA драйверов:
yum install kmod-nvidia
Установка ATi драйверов:
yum install xorg-x11-drv-fglrx kmod-fglrx glx-utils
Проверяем после рестарта X сервера:
glxinfo | grep direct
direct rendering: Yes
Для AMD64 процессора нужно добавить опцию iommu=off при загрузке Linux ядра.
В /etc/grub.conf вносим подобную правку:
kernel /vmlinuz-2.6.18-1.2798.fc6 ro root=LABEL=/ rhgb quiet iommu=off
Для материнских плат на базе чипсета Intel имеет смысл добавить в /etc/X11/xorg.conf после секции Driver "fglrx":
Option "UseInternalAGPGART" "no"
Ниже приводится лог действий инсталляции Beryl и сопутствующих программ/библиотек на моем компьютере.
К сожалению этот лог не полный, но правильный на 99% . Формат записей, я надеюсь, будет понятен без объяснений.
Моя ОС: Slackware 10.2
Инсталляция производилась преимущественно сборкой из исходников (за некоторым исключением)
Действия производились на основании материала по ссылке:
http://wiki.beryl-project.org/wiki/Install_Beryl_on_Slackware
Рекомендую пользоваться ссылкой, а мой лог использовать как помощь во избежание
следующих подводных камней: зависимости, версии (я ставил последние версии софта, но некоторые не собрались,
поэтому приходилось брать не последние версии).
Лог не описывает инсталляцию последнего Xorg и dbus.
Ценность данного материала предоставляю определить модератору и публике.
Но лично я был бы рад найти что-то подобное перед тем как я начал инсталляцию.
-----------------------------
Beryl> Install DBus
Beryl> Install DBus-glibc
Beryl> Install beryl-core
Beryl>beryl-core> tar -jxvf beryl-core-0.1.99.2.tar.bz2
Beryl>beryl-core> cd beryl-core-0.1.99.2
Beryl>beryl-core> ./configure --prefix=/usr --with-x
Beryl>beryl-core> make all
Beryl>beryl-core> sudo make install
Beryl>beryl-core> cd ..
Beryl> Install beryl-plugins
Beryl>Beryl-plugins> Install librsvg
Beryl>Beryl-plugins>librsvg> Install FreeType
Beryl>Beryl-plugins>librsvg>FreeType> tar -jxvf freetype-2.1.10.tar.bz2
Beryl>Beryl-plugins>librsvg>FreeType> cd freetype-2.1.10
Beryl>Beryl-plugins>librsvg>FreeType> vi include/freetype/config/ftoption.h
Beryl>Beryl-plugins>librsvg>FreeType> Uncomment '#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER'
Beryl>Beryl-plugins>librsvg>FreeType> ./configure --prefix=/usr
Beryl>Beryl-plugins>librsvg>FreeType> make all
Beryl>Beryl-plugins>librsvg>FreeType> sudo make install
Beryl>Beryl-plugins>librsvg>FreeType> cd ..
Beryl>Beryl-plugins>librsvg> tar-jxvf librsvg-2.14.4.tar.bz2
Beryl>Beryl-plugins>librsvg> cd librsvg-2.14.4
Beryl>Beryl-plugins>librsvg> ./configure --prefix=/usr --with-x
Beryl>Beryl-plugins>librsvg> make all
Beryl>Beryl-plugins>librsvg> sudo install
Beryl>Beryl-plugins>librsvg> cd ..
Beryl>Beryl-plugins> tar -zxvf beryl-plugins-0.1.99.2.tar.bz2
Beryl>Beryl-plugins> cd beryl-plugins-0.1.99.2
Beryl>Beryl-plugins> ./configure --prefix=/usr
Beryl>Beryl-plugins> make all
Beryl>Beryl-plugins> sudo make install
Beryl>Beryl-plugins> cd ..
Beryl> Install Beryl-manager
Beryl>beryl-manager> tar -jxvf beryl-manager-0.1.99.2.tar.bz2
Beryl>beryl-manager> cd beryl-manager-0.1.99.2
Beryl>beryl-manager> ./configure --prefix=/usr
Beryl>beryl-manager> make all
Beryl>beryl-manager> sudo make install
Beryl>beryl-manager> cd ..
Beryl> Install beryl-settings-simple
Beryl>beryl-settings-simple> tar -jxvf beryl-settings-simple-0.1.99.2.tar.bz2
Beryl>beryl-settings-simple> cd beryl-settings-simple-0.1.99.2
Beryl>beryl-settings-simple> ./configure --prefix=/usr
Beryl>beryl-settings-simple> make all
Beryl>beryl-settings-simple> sudo make install
Beryl>beryl-settings-simple> cd ..
Beryl>Install beryl-settings
Beryl>beryl-settings> tar -jxvf beryl-settings-0.1.99.2.tar.bz2
Beryl>beryl-settings> cd beryl-settings-0.1.991.2
Beryl>beryl-settings> ./configure --prefix=/usr
Beryl>beryl-settings> make all
Beryl>beryl-settings> sudo make install
Beryl>beryl-settings> cd ..
Beryl> Install beryl-vidcap
Beryl>beryl-vidcap> Install seom
Beryl>beryl-vidcap>seom> Install yasm
Beryl>beryl-vidcap>seom>yasm> tar -zxvf yasm-0.5.0.tar.gz
Beryl>beryl-vidcap>seom>yasm> cd yasm-0.5.0
Beryl>beryl-vidcap>seom>yasm> ./configure --prefix=/usr
Beryl>beryl-vidcap>seom>yasm> make all
Beryl>beryl-vidcap>seom>yasm> sudo make install
Beryl>beryl-vidcap>seom>yasm> cd ..
Beryl>beryl-vidcap>seom> !!! Note: following way does not work. Seom was actually installed from TGZ package.
Beryl>beryl-vidcap>seom> svn co svn://dbservice.com/big/svn/seom/trunk seom1
Beryl>beryl-vidcap>seom> cd seom
Beryl>beryl-vidcap>seom> ./configure --prefix=/usr
Beryl>beryl-vidcap>seom> make all
Beryl>beryl-vidcap>seom> sudo make install
Beryl>beryl-vidcap>seom> cd ..
Beryl>beryl-vidcap> tar -jxvg beryl-vidcap-0.1.99.2.tar.bz2
Beryl>beryl-vidcap> cd beryl-vidcap-0.1.99.2
Beryl>beryl-vidcap> In Makefile make PREFIX=/usr
Beryl>beryl-vidcap> make all
Beryl>beryl-vidcap> sudo make install
Beryl>beryl-vidcap> cd ..
Beryl> Install beryl-settings-bindings
Beryl>beryl-settings-bindings> Install Pyrex
Beryl>beryl-settings-bindings/Pyrex> tar -xvf Pyrex-0.9.5.tar.gz
Beryl>beryl-settings-bindings/Pyrex> cd Pyrex-0.9.5
Beryl>beryl-settings-bindings/Pyrex> sudo python setup.py install
Beryl>beryl-settings-bindings/Pyrex> cd ..
Beryl>beryl-settings-bindings> tar -jxvf beryl-settings-bindings-0.1.99.2.tar.bz2
Beryl>beryl-settings-bindings> cd beryl-settings-bindings-0.1.99.2
Beryl>beryl-settings-bindings> ./configure --prefix=/usr
Beryl>beryl-settings-bindings> make all
Beryl>beryl-settings-bindings> sudo make install
Beryl>beryl-settings-bindings> cd ..
Beryl> Install pygtk
Beryl>pygtk> Install pygobject
Beryl>pygtk>pygobject> tar -xvf pygobject-2.12.3.tar.bz2
Beryl>pygtk>pygobject> cd pygobject-2.12.3
Beryl>pygtk>pygobject> ./configure --prefix=/usr
Beryl>pygtk>pygobject> make all
Beryl>pygtk>pygobject> sudo make install
Beryl>pygtk>pygobject> cd ..
Beryl>pygtk> tar -jxvf pygtk-2.10.3.tar.bz2
Beryl>pygtk> cd pygtk-2.10.3
Beryl>pygtk> ./configure --prefix=/usr
Beryl>pygtk> make all
Beryl>pygtk> sudo make install
Beryl>pygtk> cd ..
Beryl> Install pycairo
Beryl>pycairo> Install cairo
Beryl>pycairo>cairo> Install cairo PNG backend (libpng)
Beryl>pycairo>cairo>libpng> tar -xvf libpng-1.2.15.tar.bz2
Beryl>pycairo>cairo>libpng> cd libpng-1.2.15
Beryl>pycairo>cairo>libpng> ./configure --prefix=/usr
Beryl>pycairo>cairo>libpng> make all
Beryl>pycairo>cairo>libpng> sudo make install
Beryl>pycairo>cairo>libpng> cd ..
Beryl>pycairo>cairo>tar -xvf cairo-1.2.4.tar.gz
Beryl>pycairo>cairo>cd cairo-1.2.4
Beryl>pycairo>cairo>./configure --prefix=/usr --with-x
Beryl>pycairo>cairo>make all
Beryl>pycairo>cairo>sudo make install
Beryl>pycairo>cairo>cd ..
Beryl>pycairo>tar -xvf pycairo-1.2.2.tar.bz2
Beryl>pycairo>cd pycairo-1.2.2
Beryl>pycairo>./configure --prefix=/usr
Beryl>pycairo>make all
Beryl>pycairo>sudo make install
Beryl> Install emerald
Beryl>emerald> Install libwnck
Beryl>emerald>libwnck> tar -jxvf libwnck-2.14.3.tar.bz2
Beryl>emerald>libwnck> cd libwnck-2.14.3
Beryl>emerald>libwnck> ./configure --prefix=/usr --with-x
Beryl>emerald>libwnck> make all
Beryl>emerald>libwnck> sudo make install
Beryl>emerald>libwnck> cd ..
Beryl>emerald> tar -jxvf emerald-0.1.99.2.tar.bz2
Beryl>emerald> cd emerald-0.1.99.2
Beryl>emerald> ./configure --prefix=/usr
Beryl>emerald> make all
Beryl>emerald> sudo make install
Beryl>emerald> cd ..
Beryl> Install emerald-plugins
Beryl>emerald-plugins> tar -jxvf emerald-themes-0.1.99.2.tar.bz2
Beryl>emerald-plugins> cd emerald-themes-0.1.99.2
Beryl>emerald-plugins> ./configure --prefix=/usr
Beryl>emerald-plugins> make all
Beryl>emerald-plugins> sudo make install
Beryl>emerald-plugins> cd ..
Beryl> Install aquamarine
Beryl>aquamarine> tar -jxvf aquamarine-0.1.99.2.tar.bz2
Beryl>aquamarine> cd aquamarine-0.1.99.2
Beryl>aquamarine> ./configure --prefix=/usr
Beryl>aquamarine> make all
Beryl>aquamarine> sudo make install
Beryl>aquamarine> cd ..
В любом оконном менеджере достаточно прописать запуск программы в ~/.xinitrc
например, дописать в конец:
/usr/bin/xawtv &
В KDE:
Для автозапуска достаточно создать символическую ссылку в директории ~/.kde/Autostart
Например:
$ cd ~/.kde/Autostart
$ ln -s $(which xawtv) .
$ ln -s $(which mozilla-thunderbird) .
В GNOME:
Меню "Open control center - Sessions - Startup Programs."
Или добавить программу в файл ~/.gnome2/session-manual
При включенном в ядре ACPI:
xset dpms force off
(включится после нажатия любой клавиши)
Для выключения по таймауту:
/etc/X11/xorg.conf
Section "Monitor"
Option "DPMS"
# Option "DPMS" "TRUE" # для закрытого nvidia драйвера
Section "ServerLayout"
Option "OffTime" "20" # таймаут 20 минут
Часто вижу на разных форумах вопрос, а как сделать автоматическую загрузку blackbox/windowmaker/etc
из менеджера дисплеев разряда xdm потипу kde из kdm:
xdm -session /usr/X11R6/bin/blackbox
И тогда каждому авторизированному пользователю будет запущен после входа blackbox
ля старта xdm при загрузке машины:
[/etc/ttys]
root@fbsd1 /root :less /etc/ttys | grep xdm
.....
ttyv8 "/usr/X11R6/bin/xdm -nodaemon -session /usr/X11R6/bin/blackbox" xterm off secure
.....
или при помощи скрипта помещенного либо в
/usr/local/etc/rc.d/
либо в
/usr/X11R6/etc/rc.d/
вида:
[xdm.sh]
#!/bin/sh
X=Xorg
case $1 in
start)
echo "XDM starting now... "
/usr/X11R6/bin/xdm -session /usr/X11R6/bin/blackbox
echo "XDM started!"
;;
stop)
echo -n "XDM stopping now... "
killall -9 xdm
killall -9 $X
echo -n "XDM stopped!"
;;
*)
echo -n "Use start|stop parametrs! Error!"
exit 64
;;
esac
Чтобы при наборе русских символов, при нажатии на клавишу с вопросом, рядом с правым Shift,
печатались точка и запятая, вместо вопроса и слэша, в Section "InputDevice" файла конфигурации XOrg или XFree86
меняем:
Option "XkbLayout" "us,ru"
на
Option "XkbLayout" "us,ru(winkeys)"
или просто добавляем (запятую не пропустите):
Option "XkbVariant" ",winkeys"
Создаем файл .Xkbmap и кладем его в свою домашнюю директорию (например: /home/mitya ).
Внутри файла пишем, например:
-option grp:ctrl_shift_toggle,grp:switch,grp_led:scroll us,ru
- Копируем ttf шрифты ~/.font, переходим в директорию ~/.font
- Запускаем: ttmkfdir > fonts.scale
- Запускаем: mkfontdir
- Запускаем: fc-cache ./
- Прописываем ~/.font в /etc/X11/fs/config (список "catalogue") или запускаем:
/usr/sbin/chkfontpath --add ~/.font
- Запускаем: xset fp rehash
- Запускаем: service xfs restart
- Проверяем, новые шрифты должны быть показаны в выводе утилит fc-list, xlsfonts, xfontsel, kcharselect, gfontsel и chkfontpath;
В KDE можно использовать: "Control Center/System/Font Installer".
В OpenOffice для добавления шрифтов нужно использовать утилиту spadmin.
Для AbiWord шрифты нужно скопировать в /usr/share/abisuite/AbiSuite/fonts и запустить
mkfontdir; ttmkfdir > fonts.scale
При наличии проблем с антиалиасингом, необходимо пересобрать библиотеку FreeType, активировав
"#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER" в include/freetype/config/ftoption.h
В AltLinux рекомендуется поставить пакеты freefont-fonts-ttf, freetype и ms-fonts-ttf.
Другой способ добавления шрифтов:
Копируем шрифты например в директорию, ~/fonts
В ~/.xinitrc добавляем
xset fp+ $HOME/fonts/
Пример как повысить частоту для режима 1152х864 с 75 до 100 Hz
И так для начала запустим утилиту входящую в состав xorg:
gtf 1152 864 100
Она выдаст строчку, которую на скопировать в /etc/X11/xorg.conf в section monitor:
Section "Monitor"
Identifier "iiyama"
VendorName "1152x864_100.00"
ModelName "1152x864@100.00 Hz"
# 1152x864 @ 100.00 Hz (GTF) hsync: 91.50 kHz; pclk: 143.47 MHz
Modeline "1152x864_100.00" 143.47 1152 1232 1360 1568 864 865 868 915 -HSync +Vsync
Option "DPMS"
EndSection
Теперь идем в section "Screen" и редактируем:
Section "Screen"
Identifier "Screen0"
Device "Card0"
Monitor "iiyama" # Монитор, который определили выше
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 24
Modes "1152x864_100.00" # Режим определенный выше строчкой Modeline EndSubSection
EndSection
Рестартуем "иксы".
Собираем по умолчанию:
readelf -d /usr/local/bin/gnome-terminal |grep NEEDED | wc -l
52 - требуется 52 библиотеки.
Устанавливаем флаг --as-needed:
export CFLAGS = "-Os -s -Wl,--as-needed"
После пересборки, требуется 21 реально необходимая для работы библиотека.
Пишем в адресной строке 'about:config', в полученном списке находим следующие параметры
(можно воспользоваться поиском):
network.http.pipelining
network.http.proxy.pipelining
И выставляем их в 'true'. По умолчанию браузер делает запросы к серверу последовательно,
а при включении pipelining все запросы будут выполнены параллельно.
Затем параметр:
network.http.pipelining.maxrequests
Выставляем его например в '32'. Это число - максимальное кол-во параллельно выполняемых запросов.
И последний:
nglayout.initialpaint.delay
Выставляем в '0'. (Скорей всего такого параметра ещё не существует, - нажимаем правую кнопку мышки и
выбираем в меню 'New'=>'Integer'. Вводим имя - 'nglayout.initialpaint.delay' и
присваиваем значение '0'). Это число определяет задержку перед отображением полученных данных.
Вооружаемся man xev и man xmodmap и привязываем действия к cпецклавишам:
* Fn+F2 - mute
* Fn+F3 - Уменьшить звук
* Fn+F4 - Прибавить звук
* Кнопка слева от кнопки питания - запустить gnome-terminal
* Кнопка справа от кнопки питания - запустить xfmail
Определяем коды символов, запустив xev:
* Fn+F2 - 160
* Fn+F3 - 174
* Fn+F4 - 176
* кн. слева - 178
* кн. справа - 236
Прописываем имена комбинаций через xmodmap ("setxkbmap `cat file`" или "xmodmap file"):
vi /.xmodmaprc (/.Xmodmap, /etc/X11/xinit/Xmodmap, /.Xkbmap, /etc/X11/xinit/Xkbmap)
keycode 160 = XF86AudioMute
keycode 174 = XF86AudioLowerVolume
keycode 176 = XF86AudioRaiseVolume
keycode 178 = XF86HomePage
keycode 236 = XF86Mail
Настраиваем WM для запуска программ при нажатии на клавиши (на примере icewm):
vi ~/.icewm/keys
key "XF86AudioLowerVolume" aumix -v -5
key "XF86AudioRaiseVolume" aumix -v +5
key "XF86AudioMute" aumix -v 0
key "XF86HomePage" gnome-terminal
key "XF86Mail" xfmail
From: Roman Blyshchyk (2:450/206.9)
> Modeline "mode_name" D H1 H2 H3 H4 V1 V2 V3 V4 Flags
Запускаешь утилитку xvidtune, котоpая должна быть в иксах. Далее, пишешь в XF86Config-4 в pазделе монитоp
стpочку моделайн, где mode_name = 1280x1024, под D оставляешь пока место.
H1 - 1280, H2 - HSyncStart, H3 - HSyncEnd, H4 - HTotal
V1 - 1024, V2 - VSyncStart, V3 - VSyncEnd, V4 - VTotal
, где всякие синки беpуться из xvidtune.
А D считается так 100(тpебуемая частота)*H4*V4/100000(миллион), окpугляешь до сотых.
Flags - +hsync +vsync
xterm -geometry 60x40 +sb -bg black -fg white -fn -*-*-medium-r-*--14-*-*-*-*-*-koi8-r
xterm -bg black -cr green -fg white -C -fn 9x15 -sl 500
xterm rxvt -bg black -cr green -fg white -C -fn 9x15 -sl 500 -tn xterm -geometry 90x45
xterm -T "Запуск приложения в xterm" -e /usr/bin/prog
Мне нравится использовать rxvt и gnome-terminal
Назначение собственных "горячих клавиш" для выполнения каких-либо команд в GNOME.
Есть небольшой апплет, доступный через меню GNOME
"Система" > "Параметры" > "Комбинации клавиш клавиатуры"
"Desktop" > "Preferences" > "Keyboard Shortcuts"
который позволяет назначить горячие клавиши для некоего набора предопределенных действий.
Используя этот апплет вы можете, например, назначить сочетание "Ctrl - Alt - t" для запуска эмулятора терминала.
Но поскольку список фиксирован, вы не сможете добавить в него новое действие.
А вы хотите, к примеру, назначить сочетание "Ctrl - Alt - e" для запуска Emacs.
Назначить произвольные горячие клавиши, можно воспользовавшись gconf-editor
Откройте терминал и наберите:
user@desktop:~$ gconf-editor
Откроется редактор настроек GNOME. С его помощью мы должны сделать две вещи:
* Определить новую команду
* Определить сочетание клавиш для выполнения этой команды
Перейдите в раздел
"apps" > "metacity" > "keybinding_commands"
В правой панели выберите пункт "command_1" и измените его значение на /usr/bin/emacs
Теперь нам необходимо задать клавиатурную комбинацию для этой команды.
Перейдите в раздел
"apps" > "metacity" > "global_keybindings".
Выберите пункт "run_command_1" и измените его значение на <control><alt>e.
Вуаля! Нажимаем Ctrl - Alt -e и запускается Emacs
1. Скачать ati-driver-installer-8-5-x86.x86_64.run
2. В консоли выполнить для синхронизации списка пакетов, доступных в репозиториях:
sudo apt-get update
Затем, установить пакеты, необходимые для сборки модуля ядра из исходных текстов и создания deb пакета:
sudo apt-get install build-essential fakeroot dh-make debhelper debconf libstdc++5 dkms linux-headers-$(uname -r)
3. В консоли запускаем инсталлятор драйвера в режиме создания пакетов:
sudo sh ati-driver-installer-8-5-x86.x86_64.run --buildpkg Ubuntu/8.04
4. Теперь нужно занести в черный список драйвер fglrx из репозитория Ubuntu, выполняем
sudo gedit /etc/default/linux-restricted-modules-common
и в строке "DISABLED_MODULES" добавляем "fglrx"
получаем строку:
DISABLED_MODULES="fglrx"
сохраняем файл
5. далее в консоли устанавливаем подготовленные пакеты с драйвером:
sudo dpkg -i xorg-driver-fglrx_8.493*.deb fglrx-kernel-source_8.493*.deb fglrx-amdcccle_8.493*.deb
6. Перезагружаем X сервер.
7. проверяем:
$ fglrxinfo
display: :0.0 screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: Radeon X1900 Series
OpenGL version string: 2.1.7537 Release
PS: все вышесказанное проверялось на i386 конфигурации с видеокартой X1900,
для amd64 возможны небольшие отличая в установке.
Оригинал: http://pronix.isgreat.org/news.php?item.86.5
Проблема:
Если запускаем XDM то все работает нормально,
но если запускаем startx то X-Server стартует но KDE не загружается (висит),
если убить X-Server (Ctrl+Alt+BackSpace) то остаются висеть процессы кkde*,
если теперь запустить чистый X-Server (X) то продолжается загрузка Kde
Решение в моем случае:
в файле /etc/X11/xinit/xinitrc.kde строку
startkde
заменить на
exec startkde >& ~/kde.error.log
после этого работает нормально
Объяснение:
когда стартует X-Server то видимо блокируется стандартный поток ошибок и если какая-то
программа хочет в него чего-то вывести она просто подвисает (наверно это глюк)
Устанавливаем поддержку bluetooth (проект Bluez):
yum install bluez-libs bluez-pin bluez-utils bluez-hcidump bluez-utils-cup
Устанавливаем утилиты звуковой подсистемы ALSA:
yum install alsa-tools alsa-lib alsa-utils alsa-lib-devel
Устанавливаем automake (понадобится для сборки BTSCO)
yum install automake
Проверяем на сайте http://bluetooth-alsa.sourceforge.net/ поддерживается ли наша гарнитура (Jabra BT200 поддерживается).
Запускам hcitool и смотрим активна ли bluetooth подсистема.
Подключаем гарнитуру и запускаем "hcitool scan", смотрим MAC адрес в результатах вывода.
Далее, подключаем через:
hcitool cc MAC
Все должно работать, но на случай проблем, пример некоторый файлов из /etc/bluetooth:
hcid.conf
options {
autoinit yes;
security user;
pairing multi;
# PIN helper
pin_helper /etc/bluetooth/feed-pin.sh;
# D-Bus PIN helper
#dbus_pin_helper;
}
device {
name "%h-%d";
# Local device class
class 0x120104;
# Inquiry and Page scan
iscan enable; pscan enable;
lm accept;
lp rswitch,hold,sniff,park;
# Authentication and Encryption (Security Mode 3)
auth enable;
encrypt enable;
}
rfcomm.conf
rfcomm0 {
# Automatically bind the device at startup
bind no;
# Bluetooth address of the device
device 11:11:11:11:11:11;
# RFCOMM channel for the connection
channel 1;
# Description of the connection
comment "Bluetooth Device
}
/etc/bluetooth/feed-pin.sh
#!/bin/sh
echo "PIN:0000"
Установка BTSCO из исходных текстов.
Получаем исходные тексты из CVS:
cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/bluetooth-alsa log
cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/bluetooth-alsa co btsco
Собираем утилиты:
./bootstrap
./configure
make
make install
make maintainer-clean
Собираем модуль ядра:
cd kernel
make
make install
depmod -e
make clean
Подгружаем модуль ядра:
modprobe snd-bt-sco
Подключаемся к гарнитуре:
btsco -v MAC
Небольшой скрипт для автоматизации запуска skype:
#!/bin/sh
modprobe modprobe snd-bt-sco
btsco MACofHeadset
skype
Решение проблем с "лаганием", "залипанием", "подергиванием" звука для FreeBSD 5.x при сильных нагрузках на ata систему:
в /boot/loader.conf добавить строку
hint.pcm.0.buffersize="16384".
Работает не со всеми звуковыми картами. Карточка с MediaForte чипом стала играть звук в 4 раза быстрее,
на SoundBlaster 5.1 live все играет замечательно.
Для одновременного воспроизведения звука от разных приложений
нужно создать несколько виртуальных звуковых каналов:
sysctl hw.snd.pcm0.vchans=4
sysctl hw.snd.maxautovchans=4
Если devfs не используется, в приложении нужно обращаться к устройствам /dev/dsp0.N
, где N - номер свободного канала.
Для установки громкости звука по умолчанию в FreeBSD 5.3 в /boot/device.hints добавляем:
hint.pcm.0.vol="100"
rec -c 2 -r 44100 -s w -t WAV - | lame -q 9 - linein-out-realtime.mp3
подробнее - man rec и man lame, единственное что надо сказать `-s w` - это 16bit.
Проблема: В свежеустановленном редхате (8 или 9 версии) не получается слушать mp3-файлы.
XMMS их не играет, хотя в старых дистрибутивах все работало.
Причина: В связи с неуемной жадностью патентодержателей формата MP3 его поддержка
(плееры либо их соответствующие компоненты) исключена из дистрибутива.
Решение: Пойти на сайт http://www.xmms.org и скачать нужные плагины для своей версии редхата.
Инструкция по установке FTP сервера на iPhone, для обмена файлами с внешними миром.
1. В инсталлере (http://www.ru-iphone.com/installer)
ставятся такие программы - Pure-FTPd, BossPrefs, BossPrefs PureFTPD Control.
2. Перегрузить полностью iPhone
3. В меню программ появится значок BossPrefs с его помощью можно либо включать либо выключать сервис ftp
(собственно там еще есть SSH, WiFi, EDGE, Bluetooth, что очень удобно в случае с SSH - ибо можно,
при не надобности, отключать, что повысит защищенность)
4. Подключится из любого компьютера на телефон, для прошивки 1.1.4: login\password: mobile\alpine либо login\password: root\alpine
(ftp://mobile:alpine@ip_adress)
------------------------
Для поднятия Web сервера я использовал Lighttpd, ибо с Apache возникли проблемы с биндингом порта.
Итак приступим:
1) Из инсталера ставим Community Sources, BSD Subsystem
2) Ставим PHP. Как сказано после установки нужно добавить в пути /opt/iphone/bin/ ,
но для начале мы перенесем папку opt чтобы незахламлять первый раздел, который ограничен 300мб.
Для этого:
mv /opt /private/var/opt
ln -s /private/var/opt/ /opt
Далее прописываем сам путь:
PATH=/opt/iphone/bin/:$PATH
3) Ставим Lighttpd и BossPrefs Lighttpd Control
4) Конектемся по ssh на iphone и редактируем /usr/local/etc/lighttp.conf
server.document-root = "/private/var/root/Sites/" - директория где будет находится сам сайт.
В строку index-file.names добавляем "index.php"
В строку static-file.exclude-extensions добавляем ".php"
В строку cgi.assign добавляем ".php" => "/opt/iphone/bin/php"
В строку mimetype.assign добавляем ".php" => "application/x-httpd-php",
4) Далее заходим в BossPrefs и активируем Lighttpd
5) Заливаем тестовый test.php в /private/var/root/Sites/, например
с таким содержанием:
<?php
phpinfo();
?>
6) Все теперь можете наслаждаться результатом: http://ip_adress/test.php
------------------------
Уж если кому понадобилась смена пароля на iPhome - значит как минимум ssh уже стоит...
Всем кто попробует сменить пароль через команду passwd искренней сочувствую,
ибо после такой смены - у вас сразу же слетит SpringBoard.
Итак приступим....
1) Для начала не помешало бы сделать бекап файлов, что хранят наши пароли:
mkdir /etc/backup
cp /etc/passwd /etc/backup/
cp /etc/master.passwd etc/backup/
2) Генерируем новый пароль используя ssl:
openssl passwd -crypt -salt /s NewPassword
Пароль должен быть не больше 8 символов, ибо все остальные символы игнорируются.
Например для пароля "NewPass" - команда будет
"openssl passwd -crypt -salt /s NewPass" и на выходе мы получим "/sJnipZ7EmJ.M"
3) Правим файлы /etc/passwd и /etc/master.passwd
Выглядят они примерно так:
nobody:*:-2:-2::0:0:Unprivileged User:/var/empty:/usr/bin/false
root:/smx7MYTQIi2M:0:0::0:0:System Administrator:/var/root:/bin/sh
mobile:/smx7MYTQIi2M:501:501::0:0:Mobile User:/var/mobile:/bin/sh
daemon:*:1:1::0:0:System Services:/var/root:/usr/bin/false
unknown:*:99:99::0:0:Unknown User:/var/empty:/usr/bin/false
_securityd:*:64:64::0:0:securityd:/var/empty:/usr/bin/false
Пароль тут для root и mobile - alpine, в закодированном виде /smx7MYTQIi2M, его и меняем на наш:
root:/sJnipZ7EmJ.M:0:0::0:0:System Administrator:/var/root:/bin/sh
mobile:/sJnipZ7EmJ.M:501:501::0:0:Mobile User:/var/mobile:/bin/sh
Перегружаем iphone и радуемся новым паролям..
Настройка линукса для работы с телефоном Nokia, подключеным к системе через USB кабель.
В этой статье будем настраивать линукс для работы с вашим телефоном Nokia,
подключеным к системе через USB кабель. Система Ubuntu Feisty Linux 7.04,
хотя аналогичным образом можно настроить в любом другом дистрибутиве.
1) Ставим необходимый софт:
apt-get install obexftp openobex-apps
2) Далее в консоли:
lsusb
на выходе получаем:
Bus 003 Device 003: ID 0421:043a Nokia Mobile Phones
из этого узнаем VendorID и ProductID:
VendorID = 0421
ProductID = 043a
3) Прописываем эти данные в /etc/udev/rules.d/040-permissions.rules:
sudo vim /etc/udev/rules.d/040-permissions.rules
в конец файла вписываем:
BUS=="usb", SYSFS{idVendor}=="VendorID", SYSFS{idProduct}=="ProductID", GROUP="plugdev", USER="yourUserNname"
VendorID и ProductID заменяем нашими данными полученными выводом команды lsusb
USER="имя пользователя под которым вы работаете в системе"
4) Создаём кнопку запуска на рабочем столе. В её свойствах прописываем:
java -jar /home/YOURUSERNAME/obexftp-frontend-0.6.1-bin/OBEXFTPFrontend.jar
YOURUSERNAME меняем на вашу домашнюю папку
5) Запускаем /usr/bin/obexftp
В вкладке Transport выбираем USB, Value 1
Далее OK.
Всё, настройка закончена. Запускаем программу через созданную нами на рабочем столе кнопку запуска.
В появившемся окошке видим drive c: - это наша memory card. Процесс закачки и выгрузки файлов понятен интуитивно.
Удачной работы!:)
Perlce удалось запустить на Motorola MPx200, работающем на базе Windows Mobile 2003 Smartphone edition.
Процесс установки:
- Качаем пакеты celib-3.13-dll-bin-all-platforms.tar.gz и perl-wince-arm-pocket-wce300.tar.gz
(http://www.rainer-keuchel.de/wince/dirlist.html)
- Содержимое директории lib из пакета perl-wince-arm-pocket-wce300.tar.gz копируем в \Mounted Volume\lib\perl5
- Все остальное, плюс celib.dll из директории wince-arm-pocket-wce300-release,копируем в \Mounted Volume\bin
- В реестре создаем раздел HKLM\Environment и заводим там ключи:
PERL5LIB="\Mounted Volume\lib\perl5"
UNIXROOTDIR= "/Mounted Volume"
- Создаем ассоциацию для выполнения .pl файлов программой perl.exe, через файловый менеджер RESCO Explorer
или через правку реестра. Обязательно не забываем заключить аргумент в кавычки,
т.е. в HKCR\perlfile\Shell\open\command должно быть \Mounted Volume\bin\perl.exe "%1",
RESCO создает без кавычек.
- Закачиваем и выполняем test.pl с print "Hello World!\n";
- Смотрим, и используем в дальнейшем, файлы: /perl-stdin.txt, /perl-stdout.txt и /perl-stderr.txt
Есть два способа как заставить MPX200 работать с Linux: IrDA и wince-usb.
1. Подключение через IrDA (SIR):
Устанавливаем параметры для SiR порта
/bin/setserial /dev/ttyS1 port 0x6f8 irq 3 uart 8250 baud_base 115200
irattach /dev/ttyS1 -s
Для RedHat-based Linux дистрибутивов делаем проще:
В /etc/sysconfig/irda
IRDA=yes
DEVICE=/dev/ttyS1
DISCOVERY=yes
# service irda start
Запускем демон синхронизации (не из под root). Качаем с http://synce.sourceforge.net
$ dccm
Если используется пароль запускаем как "dccm -p пароль"
Один раз указываем используемый порт.
# synce-serial-config ircomm0
Стартуем pppd (про hotplug, ниже)
# synce-serial-start
Проверяем.
$ pstatus
Version
=======
Version: 4.20.0 (Microsoft Windows Mobile 2003 for Pocket PC Phone Edition (?))
Platform: 3 (Windows CE)
.....
Завершаем сеанс
# synce-serial-abort
2. Подключение по USB. Для 2.4.x ядра используем user space драйвер wince-usb
http://cvs.sourceforge.net/viewcvs.py/synce/wince-usb/ + http://libusb.sourceforge.net
(последние 2.6.x ядра должны работать с модулями ipaq и usb-serial из коробки).
Патчим. В самом начале ipaqd.c меняем значения IPAQ_ENDPOINT на
#define IPAQ_ENDPOINT_IN 0x82
#define IPAQ_ENDPOINT_OUT 0x02
Далее в devlist[] добавляем
{ 0x045e, 0x00ce, "Motorola MPX200" },
Создаем /usr/local/bin/cebox.sh взяв пример из README к wince-usb, например:
#!/bin/sh
/usr/sbin/pppd nocrtscts local debug passive silent 192.168.1.1:192.168.1.2 ms-dns 192.168.1.1 noauth proxyarp
$ dccm
Подключаем телефон и сразу запускаем
# rmmod ipaq (пока не поправили hotplug)
# ipaqd 2>/var/log/ipaqd.log
Далее запускаем synce-serial-* как в предыдущем шаге.
3. Настройка HotPlug (чтобы все запускалось автоматически).
В /etc/hotplug/usb.agent добавляем после блока с "LABEL="USB product $PRODUCT":
if [ "$PRODUCT" = "45e/ce/0" ]; then
/etc/hotplug/usb/ipaq
exit 0
fi
Создаем /etc/hotplug/usb/ipaq
#!/bin/bash
killall -9 ipaqd
killall dccm
su -c /usr/bin/dccm /user/
/usr/local/bin/ipaqd 2>/var/log/ipaq.log
4. Стандартные команды synce:
pcp - копирование файлов (аналог cp)
pls - список файлов в директории (аналог ls)
pmkdir - создание директории (аналог mkdir)
pmv - перенос/переименование файлов (аналог mv)
prm - удаление файлов (аналог rm)
prmdir - удаление директорий
prun - запуск программы на устройстве
pstatus - статус устройства
synce-install-cab - установка на устройство .cab файла
orange - позволяет выдрать .cab из .exe инсталлера;
В Modnight Commander удобно использовать VFS понимающую команды
"cd #synce" и "cd #synceroot",
правда модуль раздаваемый на сайте synce у меня не заработал, пришлось его переписать:
ftp://ftp.opennet.ru/pub/sys/shell/synce-mcfs-patched/
Для работы, копируем файлы synce и synceroot в /usr/lib/mc/extfs
К extfs.ini добавляем:
synce
synceroot
Хорошая графическая оболочка для синхронизации календаря и адресной книги - MultiSync (http://multisync.sourceforge.net/)
Использование mplayer и gimp для создания gif-анимации на основе видеофрагментов.
1. Устанавливаем gimp и mplayer:
sudo apt-get install gimp mplayer
или
yum install gimp mplayer
2. Методом тыка выбираем интервал для экспорта:
mplayer -ao null -loop 0 -ss 0:11:22 -endpos 5 file.avi
loop означает, что фрагмент будет проигрываться, пока пользователь не нажмёт Ctrl+C,
таким образом можно увидеть, на что будет похож конечный файл.
3. Экспортируем фрагмент в jpg:
mplayer -ao null -ss 0:11:22 -endpos 5 file.avi -vo jpeg:outdir=moviedirectory
4. Сводим полученные jpeg'и в gimp, ("File / Open As Layers", "Файл / Открыть как слои"),
сохраняем как анимированный gif.
Дополнение от pavlinux:
mplayer video.avi -ss hh:mm:ss.lll -endpos hh:mm:ss.lll -vf \
scale=160:120 -vo gif89a:fps=3:output=out.gif -nosound
hh:mm:ss:lll - часы:минуты:секунды:миллисекунды
Сохранить потоковое аудио в файл можно при помощи пакета streamripper
(http://streamripper.sourceforge.net/):
streamripper http://адрес-mp3-потока-радиостанции -a radio.mp3 -M 50 -t
Команда сохранит всё в один файл radio.mp3
Без опции "-a radio.mp3" каждый трек будет записан в отдельный файл
"-M 50" - ограничение размера в мегабайтах;
"-t" - при разрыве соединения временные файлы не перезаписывать.
С недавних времён в ffmpeg появилась поддержка кодирования в qtrle.
Apple Quicktime Animation (RLE) это кодек без потерь, идеально подходящий
для снятия и кодирования скринкастов на лету, а самое главное,
что полученный mov файл ещё и сжимается в несколько раз 7zip'ом. В итоге
qtrle выигрывает по размеру у таких платных кодеков, как
TechSmith Screen Capture Codec.
Если ffmpeg у вас уже имеется, то смотрим есть ли в нём поддержка
x11grab и кодека qtrle
#ffmpeg -formats 2> /dev/null | egrep '(x11grab|qtrle)'
D x11grab X11grab
DEV D qtrle
"DEV" значит есть поддержка декодирования и кодирования, если у вас только
"D V", то нужно обновить ffmpeg.
Cнимаем скринкаст с параметрами:
60 кадров в секунду, ключевой кадр каждые 600 кадров(10 с.) и
разрешение 1280x1024 в файл screencast.mov
#ffmpeg -r 60 -g 600 -s 1280x1024 -f x11grab -i :0.0 -vcodec qtrle screencast.mov
Небольшой список клавиатурных сокращений, используемых в графическом редакторе GIMP,
начиная с версии 2.0:
Файл:
Ctr+N - Создать файл
Ctrl+О - Открыть файл
Ctrl+W - Закрыть файл
Ctrl+S - Сохранить файл
Shift+Ctrl+S - Сохранить файл как
Ctrl+Q - Выход
Редактирование изображения:
Ctrl+Z - отменить последнее действие
Ctrl+R - повторить последнее действие
Ctrl+X - вырезать выделение
Ctrl+C - копировать выделение
Ctrl+V - вставить выделение
Ctrl+K - очистить изображение/выделение до фона
Ctrl+","(запятая) - залить изображение/выделение цветом фона
Ctrl+"."(точка) - залить изображение/выделение цветом переднего плана
Shift+Ctrl+C - копировать изображение/выделение в буфер с именем...
Shift+Ctrl+V - вставить изображение/выделение из буфера с именем...
Выделение изображениями:
Ctrl+A - выделить все
Ctrl+I - инвертировать выдление
Shift+Ctrl+A - отменить выделение
Shift+Ctrl+L - создать "плавающее" выделение
Просмотр изображения:
Shift+"+"(плюс) - увеличение размера
Shift+"-"(минус) - уменьшение размера
Shift+1 - просмотр 1:1
Ctrl+E - подгонка окна под размер изображения
Ctrl+Т - показать/скрыть выделение
Shift+Ctrl+I - просмотр информации об изображении
Shift+Ctrl+N - открытие окна навигации
Shift+Ctrl+Т - показать направляющие
Shift+Ctrl+R - включить/выключить линейки
Обработка изображения или слоя:
Ctrl+D - создание копии изображения
Ctrl+M - объединить слои
Ctrl+H - прикрепить “плавающее” выделение
Shift+Ctrl+O - смещение слоя
Инструменты:
D - сбросить цвета
Х - поменять цвет переднего плана и фона
Выделение:
R - выделение прямоугольных областей
E - выделение эллиптических областей
F - выделение произвольных областей
Z - выделение связанных областей или "Волшебная палочка"
Shift+О - выделение по цвету
Контуры:
В - создание и редактирование контуров.
Вспомогательные инструменты:
О - получение цвета из изображения или пипетка.
М - перемещение слоев и выделенных областей.
Модификация изображения:
Shift+С - кадрирование или изменение размеров изображения - "скальпель"
Shift+R - поворот слоев или выделенных областей.
Shift+Т - масштабирование слоев или выделенных областей.
Shift+S - искривление слоев или выделенных областей .
Shift+P - изменение перспективы или выделенных областей.
Shift+F - отражение слоев или выделенных областей.
Инструменты для рисования:
Т - текст.
Shift+В - заливка цветом или шаблоном.
L - заливка цветным градиентом .
N - рисование резкими линиями или "карандаш".
Р - рисование мягкими линиями или "кисть".
Shift+Е - стирание до фона или прозрачности или "ластик"
L - аэрограф.
К - рисование пером.
С - рисование с использованием шаблона или участка изображения - "штамп".
V - резкость или размытость.
S - "размазывание" изображения.
Shift+D - осветление или затемнение штрихов.
Диалоги
Ctrl+L - диалог слоев
Ctrl+G - диалог градиентов
Ctrl+Р - диалог палитр
Shift+Ctrl+В - диалог кистей
Shift+Ctrl+Р - диалог шаблонов
Многие современные мобильные телефоны поддерживают проигрывание и запись1) файлов в формате 3GP.
Этот формат разработан специально для применения в портативных устройствах с небольшим разрешением экрана.
К счастью у нас есть свободный кросплатформенный конвертер видеоформатов ffmpeg
В Debian GNU/Linux или Ubuntu поставить ffmpeg можно из репозитория.
Версию для windows можно скачать по адресу http://ffdshow.faireal.net/mirror/ffmpeg/
Теперь перейдём собственно к конвертации:
ffmpeg -i input.avi -s qcif -r 12 -ac 1 -ar 8000 -b 30 -ab 12 output.3gp
Здесь ключи определяют:
-i input.avi - имя входного файла;
-s qcif -r 12 - кодировать видео с разрешением 176×144 и 12 кадров в секунду;
-ac 1 -ar 8000 - кодировать звук в один канал (моно) с частотой
дискретизации 8000 (это даст максимальную воспроизводимую частоту в 4000 Гц);
-b 30 -ab 12 - установить видео битрейт 30 кбит/с и аудио битрейт 12 кбит/с;
output.3gp - результирующий файл.
Кодирование идёт достаточно быстро и по окончании результирующий файл готов к отправке на телефон.
Как перенести файл на телефон это уже личное дело Вас и телефона. На свой Siemens CX75
я переношу файлы с помощью кардридера и RS-MMC карты на 512Mb.
Хочу предостеречь от создания роликов большого размера. К примеру попытка проиграть
на моём телефоне ролик в 17Mb (~50мин.) привела к зависанию и выключению тела.
В mplayer нет поддержки DVD меню, поэтому приходится использовать:
mplayer dvd://номер_видеоматериала
например, mplayer dvd://1
Для отображения субтитров нужно использовать опцию "-sub имя_файла_с_субтитрами".
При просмотре DVD можно явно указать язык субтитров, через опцию "-slang язык1,язык2,..".
Например: mplayer dvd://1 -slang en
При проигрывании битого файла, чтобы работала смена позиции нужно использовать:
mplayer -idx test.avi
или
mplayer -forceidx test.avi
При рассинхронизации звука и видео можно попробовать:
mplayer -autosync 30 -mc 2.0 test.avi
или
mplayer -autosync 0 -mc 0 test.avi
Для прослушивания потокового интернет-радио по плейлисту:
mplayer -playlist файл или url
При провалах можно увеличить размер кэша, например "-cache 8192" для задания кэша в 8Мб.
Для преобразования mp3 в wav:
mplayer -ao pcm:file=файл.wav файл.mp3
Полезные комбинации клавиш:
* Стрелки влево и вправо: переход на 10 секунд назад и вперед.
* Стрелки вниз и вверх: переход на 1 минуту назад и вперед.
* Клавиши Page down и Page up: переход на 10 минут назад и вперед.
* f - переход в полноэкранный режим и обратно.
* o - отображение времени просмотра и общей продолжительности;
* Пробел - пауза;
* q - выход
* / и * (или "9" и "0") - уменьшение или увеличение громкости.
* m - временное выключение звука.
* T - режим отображения окна поверх других окон.
* b и j - выбор субтитров
* x и z - управление синхронизацией субтитров;
* I - отображение имени проигрываемого файла;
* 1 и 2 - изменение контраста
* 3 и 4 - изменение яркости;
* 5 и 6 - изменение цветности;
* 7 и 8 - изменение насыщенности;
Речь пойдет о перекодировке dvd в avi при помощи mplayer во FreeBSD и Debian.
Кратко:
Для перекодировки видео я использую два продукта lame (сжатие звука в mp3) и mplayer (сжатие видео).
http://www.mp3dev.orghttp://www.mplayerhq.hu/homepage/dload.html
FreeBSD:
lame:
% cd /fooroot
% ./configure
% make
# make install
mplayer:
% cd /fooroot
% ./configure
// послу установки lame проверка на библиотеки lame должна прийти
// удачно (Checking for libmp3lame (for mencoder) ... yes) , обычно я так же
// использую параметр --with-codecsdir=DIR для того чтобы указать
// расположение бинарных win кодеков.
% ./make
# ./make install
проверить можно просто
mplayer ./foo.avi
Debian:
lame:
# apt-get install fakeroot
# apt-get install dh-make
$ cd /fooroot
$ fakeroot debian/rules
$ fakeroot debian/rules build
$ fakeroot debian/rules build install
$ fakeroot debian/rules binary-indep binary-arch
если появляется что то типа:
cp: невозможно выполнить stat для `PRESETS.draft': No such file or directory
dh_installdocs: command returned error code 256
make: <li> [binary-arch] Ошибка 1
рекомендую отредактировать вайл rules в подкаталоге debian в секции
binary-arch: build install закоментируйте строчку dh_installdocs и у вас
соберутся 3 замечательных пакета.
# cd ../
# dpkg -i ./*lame*
mplayer:
Cобирается точно так же как в FreeBSD.
Перекодирование фильмов:
mencoder dvd://1 -o xxxxxx.avi -dvd-device /mnt/pink/serpent/video/5/\
-vf scale=720:480 -oac mp3lame -lameopts vbr=0:q=0 -ovc lavc -lavcopts\
vcodec=mpeg4:mbd=1:vbitrate=1200
по порядку:
mencoder | утилита специально написанная для перекодировки видео,
она будет установлена автоматически во время установки mplayer.
dvd://1 | трек
-o xxxxxx.avi | выходной файл
-dvd-device /cdrom | путь до устройства dvd
-vf scale=720:480 | изменяет размер на указанный
-oac mp3lame | указывает какой аудио кодер использовать
-lameopts vbr=0:q=0 | параметры передоверяемые аудио кодеру (в
данном случаи переменный битрайт высшего качества)
-ovc lavc | указывает какой видео кодер использовать
-lavcopts vcodec=mpeg4:mbd=1:vbitrate=1200 | параметры
передоверяемые видео кодеру (думаю интуитивно понятно)
хочу еще порекомендовать заглянуть в официальную документацию
"man mplayer",
а так же я обнаружил, что в последней версии есть русско-язычная html документация.
Часто требуется вырезать небольшой фрагмент из фильма.
Для этого сначала необходимо определить с какой позиции начать вырезать
(при просмотре в mplayer обычно клавишей O включается табло времени ), и длину фрагмента.
START_TIME="16:10"
LENGTH_IN_FRAMES="1500" # обычно число требуемых секунд помноженное на частоту кадров в секунду (обычно 24 или 25)
mencoder FILM.AVI -ss $START_TIME -frames $LENGTH_IN_FRAMES -oac pcm -channels 2 \
-ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=600 -o FRAGMENT.AVI -mc 0 -noskip
Осветление блока:
- Выделить область используя "волшебную палочку" (Click+Ctrl - исключить, Click_shift - добавить);
- Меню: Слой/ Цвета/ Уровни.
- На верхнем графике чуть сдвинуть влево белый и серый маркеры;
- На нижнем уровне серого немного сдвинуть вправо черный маркер;
- Меню: Слой/ Цвета/ Яркость-Контрастность.
- Сбалансировать потерянный контраст сдвинув вправо полоску контраста.
Эффект красных глаз:
- Под увеличением выделить красную область на всех глазах на фотографии;
- Меню: Слой/ Цвета/ Тонирование
- Тон - на минимум (влево);
- Насыщенность чуть уменьшить;
- Осветление - прибавить и добиться почти черного цвета с коричневым отливом.
Достаточно скопировать любой TTF шрифт в ~/.mplayer/subfont.ttf,например:
$ cp /usr/local/lib/X11/fonts/msttcorefonts/verdana.ttf ~/. mplayer/subfont.ttf
и добавить в файл ~/.mplayer/config:
subcp=cp1251
Вариант 2 от Константина Мартынова:
~/.mplayer/config
font = /usr/X11R6/lib/X11/fonts/TTF/tahoma.ttf
subcp = "cp1251"
subfont-text-scale = "3"
subfont-blur = "8"
subfont-outline = "8"
задержка субтитров регулируется клавишами z/x.
кодировку субтитров можно задать при запуске ключем -subcp cp1251
Изменение размера картинки с помощью утилиты pnmscale (y до 150, x - соразмерно):
djpeg -pnm -dct float SRC_IMAGE.JPG | pnmscale -ysize 150 |
cjpeg -quality 70 -optimize -progressive -dct float > tumb_IMAGE.JPG
# Преобразуем tiff картинку в PostScript документ формата A4
convert -page A4+0+0 image.tiff document.ps
# надпись начиная от точки 100x100, синим цветом шрифтом helvetic
convert -font helvetica -pen blue -draw "text 100,100 TEST" test.jpg test2.jpg
# Создадим изображение размером 640x480 и заполним его повторяющимися картинками bumps.jpg
convert -size 640x480 tile:bumps.jpg tiled.png
# Создадим анимированный gif из группы файлов dna.* с задержкой 20/100 сек.
convert -delay 20 dna.* dna.gif
# Изменим размер картинки до 100x50 и запишем в tumb.jpg
convert -geometry 100x50 test.jpg tumb.jpg
# Уменьшим размер картинки на 50% и запишем в tumb.jpg
convert -geometry 50% test.jpg tumb.jpg
# Вырежем кусок размером 100x50 из файла test.jpg начиная с позиции 200x200
convert -crop 100x50+200+200 test.jpg tumb.jpg
Принтеры HP LaserJet 1000,1005,1018,1020 после включения должны загрузить бинарный firmware драйвер.
Если прошивка по каким-то причинам не загружена
(загрузка обычно устанавливается в автомате через hotplug),
то вывод usb_printerid будет примерно таким
nik@linuxdvr:~$ usb_printerid /dev/usb/lp0
GET_DEVICE_ID string:
MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CMD:ACL;CLS:PRINTER;DES:HP LaserJet 1020;
без упоминания версии прошивки в конце строки (FWVER:20041129;)
Устанавливаем штатный deb-пакет foo2zjs
он ставит все что нужно, за исключением самой прошивки
и в логе tail -n 20 /var/log/messages вы увидите что-то подобное
Mar 20 12:35:34 linuxdvr kernel: usbcore: registered new driver usblp
Mar 20 12:35:34 linuxdvr kernel: drivers/usb/class/usblp.c: v0.13: USB Printer Device Class driver
Mar 20 12:35:35 linuxdvr /usr/bin/hplj1020: Missing HP LaserJet 1020 firmware file /usr/share/foo2zjs/firmware/sihp1020.dl
Mar 20 12:35:35 linuxdvr /usr/bin/hplj1020: ...read foo2zjs installation instructions and run ./getweb 1020
Выполняю:
nik@linuxdvr:~$ getweb 1020
в итоге c инета сайта foo2zjs качается прошивка и сохраняется как sihp1020.img
конвертируем этот бинарник в нужный формат
nik@linuxdvr:~$ arm2hpdl sihp1020.img > sihp1020.dl
далее копируем куда нужно
nik@linuxdvr:~$ sudo mv sihp1020.dl /usr/share/foo2zjs/firmware/
и корректируем владельца группу
nik@linuxdvr:~$ sudo chown root:root /usr/share/foo2zjs/firmware/sihp1020.dl
Включаем и выключаем принтер и в логе tail -n 20 /var/log/messages видим
Mar 20 12:57:18 linuxdvr /usr/bin/hplj1020: loading HP LaserJet 1020
firmware /usr/share/foo2zjs/firmware/sihp1020.dl to /dev/usb/lp0 ...
Mar 20 12:57:19 linuxdvr /usr/bin/hplj1020: ... download successful.
Проверяем:
nik@linuxdvr:~$ usb_printerid /dev/usb/lp0
GET_DEVICE_ID string:
MFG:Hewlett-Packard;MDL:HP LaserJet 1020;CMD:ACL;CLS:PRINTER;DES:HP LaserJet 1020;FWVER:20041129;
FWVER:20041129; - это версия успешно загруженной прошивки
Все, теперь идем в KDE, GNOME или ... и запускаем ОТ ROOT-а гуёвые мастера для добавления принтера.
На всякий случай, привожу установленные в Debian Etch пакеты для печати на HP1020 через CUPS.
nik@linuxdvr:~$ aptitude search "foo|cups|foo2" | grep "^i"
i cupsys - Common UNIX Printing System(tm) - server
i cupsys-bsd - Common UNIX Printing System(tm) - BSD comm
i cupsys-client - Common UNIX Printing System(tm) - client p
i A cupsys-common - Common UNIX Printing System(tm) - common f
i cupsys-driver-gutenprint - printer drivers for CUPS
id foo2zjs - Support for printing to ZjStream-based pri
i A foomatic-db - linuxprinting.org printer support - databa
i foomatic-db-engine - linuxprinting.org printer support - progra
i foomatic-db-gutenprint - linuxprinting.org printer support - databa
i foomatic-db-hpijs - linuxprinting.org printer support - databa
i A foomatic-filters - linuxprinting.org printer support - filter
i foomatic-filters-ppds - linuxprinting.org printer support - prebui
i foomatic-gui - GNOME interface for configuring the Foomat
i gnome-cups-manager - CUPS printer admin tool for GNOME
i A libcupsimage2 - Common UNIX Printing System(tm) - image li
i A libcupsys2 - Common UNIX Printing System(tm) - libs
i A libgnomecups1.0-1 - GNOME library for CUPS interaction
i A libgnomecupsui1.0-1c2a - UI extensions to libgnomecups
i A python-foomatic - Python interface to the Foomatic printer d
(С) Андрей Никитин, 2007
Перепечатка и цитирование допускаются только с разрешения автора.
Формирование PostScript:
a2ps -2 --encoding=latin1 --pretty-print -s1 --no-header --borders=no -o file.ps file.txt
-2 - печать в две колонки (-1 - одна колонка на весь лист)
-s1 - односторонняя печать (-s2 - печать с обоих сторон)
--pretty-prin - подсветка синтаксиса (--pretty-print=plain - отмена)
Преобразование в RAW формат:
gs -q -dNOPLATFONTS -dSAFER -sDEVICE=ljet4 -dNOPAUSE -dBATCH -sOutputFile=file.raw file.ps
Отправка на печать:
cat file.raw | smbclient //192.168.10.19/HPLaserJ -N -c "print -"
Печатать HTML документы удобно преобразовав их в текстовый файл через
lynx -dump -nolist -with_backspaces URL
и затем поправив в любом текстовом редакторе.
Если при печати из CUPS на принтер на Windows машине при использовании SMB протокола пишет:
Connection failed with error NT_STATUS_ACCESS_DENIED
Или при печати через IPP:
Unable to connect to SAMBA host, will retry in 60 seconds...
foomatic-rip version $Revision$ running...
Добавляем в веб-форме CUPS принтер и выбираем способ подключения Windows printer via Samba.
Далее в строке адреса пишем:
smb://guest@192.168.1.1/HPLaserJ
В приложениях KDE нужно выставить адрес службы печати на локальный: 127.0.0.1:631.
В поставке vim присутствует сценарий /usr/share/vim/vim71/macros/less.sh:
#!/bin/sh
if test $# = 0; then
vim --cmd 'let no_plugin_maps = 1' -c 'runtime! macros/less.vim' -
else
vim --cmd 'let no_plugin_maps = 1' -c 'runtime! macros/less.vim' "$@"
fi
Который можно использовать для замены less с подсветкой синтаксиса.
В .bashrc добавляем:
alias less=/usr/share/vim/vim71/macros/less.sh
Быстрый поиск PID идентификатора запущенного процесса по имени:
pgrep ssh
Выполнение последней выполненной команды в Bash:
!!
Выполнение последней выполненной команды в Bash, начинающейся с заданных символов
Например, с символа "s":
!s
!ssh
Для того, чтобы перед выполнением посмотреть, что за команда отвечает маске !ssh нужно добавить :p
!ssh:p
Периодический перезапуск команды с перерисовкой экрана:
Например, для отображения изменений содержимого директории:
watch -d ls -l
Быстрое сохранение файла и выход, в VI/VIM
Вне режима вставки нужно нажать ZZ (два раза нажать z с нажатым Shift).
Быстрый выход из терминала:
CTRL+D
Возврат в прошлую директорию в shell:
cd -
Создание директории с недостающими промежуточными директориями:
mkdir -p /tmp/dir1/dir2/dir3
что эквивалентно
mkdir /tmp/dir1
mkdir /tmp/dir1/dir2
mkdir /tmp/dir1/dir2/dir3
Удаление введенной строки в shell:
CTRL+U
Изменение времени модификации файла (2008-01-01 8:00 = 0801010800 (YYMMDDhhmm)):
touch -c -t 0801010800 filename.c
Для обращения к аргументу прошлой команды можно использовать !$
ls /usr/lib
cd !$
Исправление ошибки в последней команде при помощи оператора "^ключ^замена":
$ cd /usr/loxal/bin
bash: cd: /usr/loxal/bin: No such file or directory
$ ^loxal^local
cd /usr/local/bin
По умолчанию bash, а точнее утилита history, не сохраняет в .bash_history
время исполнения каждой команды.
Почитал маны и оказалось, что в баше трейтье версии сделать это можно и весьма просто.
Если объявить глобальную переменную HISTTIMEFORMAT с форматом выводимых данных,
то утилита history будет сохранять и выводить эту дату.
Итак, пишем в ~/.bashrc строчку
export HISTTIMEFORMAT='%h %d %H:%M:%S '
После этого в .bash_history перед каждой командой появится коментарий
с цифрой - временем выполнения этой команды в формате timestamp:
#1198068550
history
#1198139874
ьс
#1198139876
mc
#1198148168
ssh teletrade.ru
#1198148217
ssh teletrade.ru
А команда history будет выдавать историю данных с датой в формате,
который мы переменной задали (в похожем формате выдают дату и время утилита ls):
995 Дек 19 15:49:10 history
996 Дек 20 11:37:54 ьс
997 Дек 20 11:37:56 mc
998 Дек 20 13:55:49 ssh teletrade.ru
Но можно сделать и по ГОСТУ, в приятном русскому глазу виде "ДД.ММ.ГГГГ"
export HISTTIMEFORMAT='%d.%m.%Y %H:%M:%S '
А можно и на американский манер "YYYY-MM-DD"
export HISTTIMEFORMAT='%Y-%m-%d %H:%M:%S '
Чтобы поместить в отдельный лог команды выполненные в режиме su:
.bash_profile
export HISTSIZE=3000
export HISTFILESIZE=99999
export HISTFILE=/root/.bash_hist-$(who am i|awk '{print $1}';exit)
Получим два файла истории: .bash_hist-user и .bash_hist-root
Установка времени гашения консоли Linux:
setterm -blank <минуты>
Или чтоб экран не гас совсем:
setterm -blank 0
Для FreeBSD в /etc/rc.conf: blanktime="NO", saver="NO" или blanktime="секунды"
Команда:
vidcontrol -t секунды < /dev/ttyv0
или
vidcontrol -t off < /dev/ttyv0
Для дублирования двух screen сессий, например, для удаленной демонстрации каких-то консольных операций:
Создать сессию
screen -S имя_сессий
или посмотреть уже открытую через
screen -list
Присоединиться к активной сессии:
screen -x имя_сессий
Два окна будут отображаться синхронно.
Также можно позволить другому пользователю подключиться к чужой screen сессий.
Но, для этого на бинарный файл screen необходимо установить suid бит,
чтобы он всегда запускался с привилегиями суперпользователя, что не рекомендуется делать из соображений безопасности.
sudo chmod u+s /usr/bin/screen
В активной сессии включаем многопользовательский режим:
ctrl-a :multiuser on
Добавляем в список доступа нужного пользователя:
ctrl-a :acladd имя_пользователя
Другой пользователь подключается командой:
screen -x имя_пользователя_запустившего_screen/имя_сессии
Пользователю можно открыть доступ в режиме только для просмотра (http://aperiodic.net/screen/multiuser):
ctrl-a :writelock on
Настройка bootsplash для AltLinux (темы берутся с http://bootsplash.de/)
В качестве примера взята тема AquaMatrix для разрешения 1024x768).
1. Установить пакеты:
apt-get install bootsplash design-bootloader-AquaMatrix
2. Перегенерировать inird-образ:
mkinitrd -f /boot/initrd-`uname -r`.img `uname -r`
3. Добавить в конец образа собственно splash:
splash -s -f /etc/bootsplash/themes/AquaMatrix/config/bootsplash-1024x768.cfg >>
/boot/initrd-`uname -r`.img
4. В /etc/lilo.conf (или /boot/grub/menu.lst) дописать к параметрам ядра и запустить lilo.
vga=791 splash=silent
5. В /etc/sysconfig/bootsplash укажите название темы и включите её.
SPLASH="yes"
THEME="AquaMatrix"
Для изменения фонового изображения на первой консоли:
splash -s -u 1 путь_к_splash.cfg
Пример, выделения слова Reject при просмотре хвоста почтового лога:
tail -f /var/log/maillog |perl -p -e 's/Reject/\033\[46;1mReject\033[0m/gi;'
Если нужно не только выделять цветом, но и подавать звуковой сигнал при появлении test@test.ru:
tail -f /var/log/maillog |perl -p -e 's/(test\@test.ru)/\033\[46;1m$1\033[0m\007/gi;'
Иногда приложения перестают запускаться из-под screen в FreeBSD.
Например, midc ругается "subshell.c: read (subshell_pty...): Unknown error: 0".
Для решения проблемы достаточно выполнить "killall -CONT <your shell>", например:
killall -CONT bash
Жестко разбить по 60 символов в строке: fold -w 60 test.txt
Разбивать только по пробелам, не разбивая слова на части: fold -s -w 60 test.txt
Для форматирования текста программы на Си можно воспользоваться утилитой indent.
Разбить на параграфы поможет fmt из textutils.
Ctrl-\ - возможность ведения списка часто используемых директорий, включая FTP.
Сtrl-s или Meta-s - интерактивный поиск файла в панели.
Meta-Tab - дополнение имени файла в любом диалоге.
Ctrl-q - вставить в редакторе непечатный символ по коду.
F1...F10 эмулируются ESC-1...ESC-0
F11..F12..F13.. эмулируются нажатием Shift-F1..Shift-F2..Shift-F3..
Meta-! - запустить программу и посмотреть ее вывод во встроенном просмотрщике.
Meta-c - быстрый переход в директорию
Meta-t - изменить тип отображения файлов в панели.
В редакторе: Shift-! - выход в командную строку на время, ctrl+T - перекодировка.
Выделить только директории можно добавив / после * в блоке пометки.
midc -s - для работы на медленных терминалах.
Ctrl+A,Esc
Подвести курсор к нужной позиции (можно использовать для просмотра предыдущих страниц)
и нажать Enter.
Отметить нужный фрагмент и нажать Enter.
Для вставки сохраненного блока необходимо нажать Ctrl+A,].
Включаем режим совместимости с Linux и linprocfs.
Добавляем в /etc/rc.conf
linux_enable="YES"
В /etc/sysctl.conf
compat.linux.osrelease=2.6.16
В /etc/fstab:
linproc /usr/compat/linux/proc linprocfs rw 0 0
Выполняем команды:
mkdir -p /usr/compat/linux/proc
mount /usr/compat/linux/proc
/etc/rc.d/abi start
/etc/rc.d/sysctl start
Устанавливаем Linux библиотеки, Flash плагин и nspluginwrapper из портов:
cd /usr/ports/emulators/linux_base-f8 && make install clean
cd /usr/ports/www/linux-flashplugin9 && make install clean
cd /usr/ports/www/nspluginwrapper && make install clean
Активируем плагин в nspluginwrapper:
nspluginwrapper -v -a -i
Auto-install plugins from /usr/X11R6/lib/browser_plugins
Looking for plugins in /usr/X11R6/lib/browser_plugins
Auto-install plugins from /usr/local/lib/npapi/linux-flashplugin
Looking for plugins in /usr/local/lib/npapi/linux-flashplugin
Install plugin /usr/local/lib/npapi/linux-flashplugin /libflashplayer.so
into /usr/local/lib/browser_plugins/npwrapper.libflashplayer.so
Auto-install plugins from /root/.mozilla/plugins
Looking for plugins in /root/.mozilla/plugins
Перезапускаем Firefox 3 и проверяем активность плагина, введя в адресном поле about:plugins.
Если Flash плагин не обнаружен, можно создать симлинк:
ln -s /usr/local/lib/browser_plugins/npwrapper.libflashplayer.so \
/usr/local/lib/firefox3/plugins/npwrapper.libflashplayer.so
Ставим плагин FlashBlock (http://addons.mozilla.org/en-US/firefox/addon/433)
или NoScript (http://addons.mozilla.org/en-US/firefox/addon/722).
Иногда требуется вручную последовательно установить несколько пропущенных обновлений к Firefox.
Делается это следующим образом.
Загружаем "mar" архив с обновлением из директории update нужного релиза Firefox
с сайта ftp://ftp.mozilla.org/pub/firefox/releases
Создаем директорию, допустим /tmp/update, копируем туда "mar" файл и переименовываем в update.mar
mkdir /tmp/update
wget ftp://ftp.mozilla.org/pub/firefox/releases/2.0.0.17/update/linux-i686/ru/firefox-2.0.0.16-2.0.0.17.partial.mar
mv firefox-2.0.0.16-2.0.0.17.partial.mar update.mar
Далее копируем программу updater из директории в которую установлен firefox, например /usr/local/firefox
cp /usr/local/firefox/updater /tmp/update/
Переходим в установочную директорию Firefox и запускаем updater, передав
в качестве параметра директорию в которой лежит update.mar
cd /usr/local/firefox/
/tmp/update/updater /tmp/update 0
где вместо 0, можно указать PID запущенного в данное время firefox (если не запущен ставим 0)
После выполнения программы смотрим образовавшиеся в директории /tmp/update логи,
если в файле update.status написано "succeeded", значит все обновилось нормально.
Как известно, английский словарь должен быть одноязычным. Самый лучший из одноязычных
словарей - Longman (Longman Dictionary Of Contemporary English, http://www.ldoceonline.com/).
Хотя имеющаяся электронная версия работает и под linux (GTK 1.2),
лучше сделать возможность поиска слов прямо в Firefox (добавить новый Search Engine).
Создайте каталог:
~/.mozilla/firefox/profile/searchplugins
И в нём файл longman.xml со следующим содержимым:
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<os:ShortName>Longman Dictionary</os:ShortName>
<os:Description>Longman Dictionary of Contemporary English Online</os:Description>
<os:InputEncoding>iso-8859-1</os:InputEncoding>
<SearchForm>http://www.ldoceonline.com/search/</SearchForm>
<os:Url type="text/html" method="GET"
template="http://www.ldoceonline.com/search/?q={searchTerms}"/>
</SearchPlugin>
Перезапустите firefox и выберете в меню поисковиков Longman Dictionary.
Теперь вы всегда можете получить необходимое толкование слова, кликнув
средней кнопкой по увеличительному стеклу (словарь откроется в новом табе).
Зайдите на Sun Download Center (SDLC - http://cds.sun.com) под вашим именем.
Для загрузки из командной строки можно использвать нижепредставленный скрипт:
./wget_from_cds username 'URL' filename.ext
где,
username - имя пользователя, под которым вы недавно зашли в SDLC, после запуска скрипта, нужно ввести пароль.
URL - адрес загружаемого файла
filename.ext - файл в который необходимо сохранить результат
Скрипт http://wikis.sun.com/download/attachments/28448383/wget-from-cds_v1
#! /bin/sh
# wget user download-url filename
if [ $# -ne 3 ]; then
echo "Usage: $0 user_name download_url file_name"
echo " user_name Use your Sun Online Account Username"
echo " download_url The download link from the SDLC Download Page. Must be enclosed in single quotes ('http://cds.sun.com/...')"
echo " file_name Save the download using this file name"
exit 1
fi
user=$1
dlurl=`echo $2 | sed -e 's/\?/%3f/g' -e 's/&/%26/g'`
filename=$3
stty -echo
echo "Password for ${user}: \c"; read password;
stty echo
#echo $dlurl
touch /tmp/wget-url-$$.txt
chmod 600 /tmp/wget-url-$$.txt
echo "https://identity.sun.com/amserver/UI/Login?program=cds&org=self_registered_users&IDToken1=${user}&IDToken2=${password}&goto=${dlurl}" >> /tmp/wget-url-$$.txt
wget --no-check-certificate --keep-session-cookies -O "${filename}" -i /tmp/wget-url-$$.txt
rm /tmp/wget-url-$$.txt
Дублирование табов. Если нажать Ctrl в процессе перетаскивания таба, то его содержимое будет продублировано в новом табе;
Перетаскивание табов между окнами.
Изменение размера строки поиска, когда она размещена на одной линии со строкой ввода адреса. Достаточно подвести курсор мыши к разделителю между полями и можно будет изменить ширину;
Поиск по ключевым словам. В меню поиска нажмите на "Управление поисковыми плагинами/Manage Search Engine" и выберите "Изменить/Edit Keyword" для заданной поисковой системы. Далее можно ввести краткое имя (Keyword), набрав которое после произвольного набора слов в строке адреса, будет осуществлен поиск через задуманную поисковую систему.
Прерывистое выделение блоков текста. Отметив текст мышью, можно нажать Ctrl и продолжить выделение в другой части документа;
В браузер интегрировано средство для поиска дополнений на странице addons.mozilla.org (меню Дополнения/Поиск дополнения);
Возможность временного отключения плагинов (например, Flash) через менеджер дополнений;
Набрав about:crashes можно просмотреть историю крахов браузера, по которым разработчикам были отправлены уведомления о проблемах.
Официальная сборка Firefox 3 требует GTK+2.10, в то время как в Debian Etch только 2.8.
Нужную версию gtk можно установить из бэкпортов:
Разархивируем firefox 3 в директорию /opt/firefox3
Загружаем http://apt.linex.org/linex/gtk-2.10/libgtk2.0-0_2.10.13-2%7Ebpo.1_i386.deb
Ставим libgtk 2.10 в директорию gtk2-10:
dpkg-deb -x libgtk2.0-0_2.10.13-2~bpo.1_i386.deb gtk2-10
Перемещаем содержимое gtk2-10 в /opt/firefox3
В начало скрипта /opt/firefox3/firefox дописываем:
export LD_LIBRARY_PATH=" /opt/firefox3/gtk2-10/usr/lib"
Для других дистрибутивов, при отсутствии бэкпорта, можно собрать gtk+ 2.10 из исходных текстов:
cd /usr/local/src
wget http://ftp.gnome.org/pub/GNOME/sources/gtk+/2.10/gtk+-2.10.14.tar.bz2
tar xjf gtk+-2.10.14.tar.bz2
mkdir gtk210
cd gtk+-2.10.14
./configure --prefix=/opt/firefox3/gtk2-10
make
make install
Чтобы браузер firefox/seamonkey работал со шрифтами на порядок быстрее,
перед запуском браузера поменяйте значение переменной MOZ_DISABLE_PANGO на 1.
Выглядеть все должно приблизительно так:
%export MOZ_DISABLE_PANGO=1; firefox (для bash/zsh)
%setenv MOZ_DISABLE_PANGO 1; firefox (для csh-подобных)
Либо в /etc/profile, чтобы каждый раз не менять.
Задача - скачать ISO образ линукса за короткое время.
Самое простое это:
wget ftp://ftp.rediris.es/sites/releases.ubuntu.com/releases/feisty/ubuntu-7.04-desktop-i386.iso
Но на зеркалах стоят лимиты на ширину канала для каждого подключения,
а так как нам важно время, мы будем использовать несколько зеркал одноврменно.
В первую очередь устанавливаем программу CURL:
sudo apt-get install curl
Далее, ISO образ имеет объём 700Мб. Мысленно режем его на несколько частей по 100Мб и выбираем 4 зеркала с этим образом.
создаём файл ubuntu.sh:
vim ubuntu.sh
в него вписываем:
#!/bin/sh
url1=http://ubuntu.intergenia.de/releases/feisty/ubuntu-7.04-desktop-i386.iso
url2=http://ubuntu.virginmedia.com/releases/7.04/ubuntu-7.04-desktop-i386.iso
url3=http://es.releases.ubuntu.com/7.04/ubuntu-7.04-desktop-i386.iso
url4=http://ftp-mirror.internap.com/pub/ubuntu-releases/7.04/ubuntu-7.04-desktop-i386.iso
curl --range 0-199999999 -o ubuntu-iso.part1 $url1 &
curl --range 200000000-399999999 -o ubuntu-iso.part2 $url2 &
curl --range 400000000-599999999 -o ubuntu-iso.part3 $url3 &
curl --range 600000000- -o ubuntu-iso.part4 $url4 &
url1, url2, url3, url4 - переменные содержащие в себе ссылки на iso образ на разных зеркалах.
аргумен --range указывает с какого по какой байт надо скачать. --range 600000000- указывает что надо скачать
начиная с 600000000 и до конца.
ubuntu-iso.part1 и т.д. - названия файлов под которыми будут сохранены скачанные части iso образа
делаем скрипт исполняемым:
$chmod u+x ubuntu.sh
и запускаем его:
$./ubuntu.sh
в конечном итоге получаем 4 файла:
ubuntu-iso.part1 ubuntu-iso.part2 ubuntu-iso.part3 ubuntu-iso.part4
склеиваем их в один iso образ:
cat ubuntu-iso.part? > ubuntu-7.04-desktop-i386.iso
Получили готовый образ системы за относительно короткое время.
Для использования Linux версии Flash плагина с Firefox собранным под FreeBSD
(с linux-firefox под FreeBSD работает без проблем):
cd /usr/src/libexec/rtld-elf
fetch http://www.jail.se/freebsd/rtld_dlsym_hack.diff
patch < rtld_dlsym_hack.diff
make clean all install
portinstall linux-flashplugin7 linuxthreads linuxpluginwrapper
cd /usr/X11R6/lib/browser_plugins
rm libflashplayer.so flashplayer.xpt
ln -s ../linux-flashplugin7/flashplayer.xpt
ln -s ../linux-flashplugin7/libflashplayer.so
В /etc/libmap.conf добавляем (http://www.jail.se/freebsd/libmap.conf):
[/usr/X11R6/lib/linux-flashplugin7/libflashplayer.so]
libpthread.so.0 pluginwrapper/flash7.so
libdl.so.2 pluginwrapper/flash7.so
libz.so.1 libz.so.3
libstdc++-libc6.2-2.so.3 libstdc++.so.4
libm.so.6 libm.so.4
libc.so.6 pluginwrapper/flash7.so
Mozilla:
Открыть URL в окне: mozilla -remote "openurl(URL)"
Открыть файл в окне: mozilla -remote "openFile(путь)"
Можно указать: openURL (URL, new-window), openURL (URL, new-tab)
Проверка запущен ли браузер: mozilla -remote "ping()"
Galeon:
Открыть в новом листе: galeon-bin --new-tab URL
Открыть в новом окне: galeon-bin --new-window URL
- Редактирование файла на другой машине по сети: vim scp://user@host.ru:/home/user/file
- Поиск слова как под курсором: "*" - вперед, "#" - назад.
- Поиск парных скобок - "%".
- Автодополнение недописанных слов: Ctrl-N
- Замена регистра букв в линии: "guu", "gUU"
- Переход на строку (позицию) где было последнее изменение: "'." ("`.")
- Трассировка пути курсора по файлу: Ctrl-O, Ctrl-I.
- Выделение в визуальном режиме:
v - начало блока (V линия, Ctrl-V - вертикальный блок), выделив блок нажать d или y (удалить, скопировать).
Открытие двух или трех файлов в разных окнах vim.
С горизонтальной разбивкой окон на экране:
vim -o /etc/passwd /etc/hosts
vim -o /etc/passwd -o /etc/group /etc/hosts
С вертикальной разбивкой окон на экране:
vim -O /etc/passwd /etc/hosts
vim -O /etc/passwd -O /etc/group /etc/hosts
Наглядный просмотр отличий нескольких файлов
vim -d файл1 файл2
vim -d файл1 -d файл2 файл3
Команды переключения между окнами:
"CTRL-w w" - быстрое переключение на следующее окно
"CTRL-w влево" - активация левого окна
"CTRL-w вправо" - активация правого окна
"CTRL-w вверх" - активация верхнего окна
"CTRL-w вниз" - активация нижнего окна
"CTRL-w n" - создать новое окно (":new файл" - открыть заданный файл)
"CTRL-w q" - закрыть текущее окно
(":qall" - закрыть все окна разом, ":qall!" - без сохранения, ":write" - записать данные во всех окнах)
"CTRL-w s" - разбить текущее окно на 2 части для синхронного редактирования разных частей
(в каждом окне будет содержимое одного и того же файла).
"CTRL-w +", "CTRL-w -" - увеличение или уменьшение текущего размера окна
"ESC 5 CTRL-w -", "ESC 5 CTRL-w +" - изменение размера сразу на 5 строк/столбцов
"CTRL-w h" - переместить окно влево
"CTRL-w j" - переместить окно ниже
"CTRL-w k" - переместить окно выше
"CTRL-w l" - переместить окно вправо
"CTRL-w t" - переместить окно на самый верх
"CTRL-w b" - переместить окно в самый низ
Совет как уменьшить расход памяти при работе с open office
или как решается проблема right buttom click на слове с ошибкой.
Как оказалось, в большинстве конфигураций open offica которые я увидел, грузятся абсолютно ВСЕ доступные офису словари.
Как для проверки орфографии так и для других нужд (аля синонимы, переносы ect.)
А это дикий расход памяти, плюс критическое снижение производительности (в некоторых случаях) при проверке документа.
Итак идем в
/usr/lib/ooo-1.1/share/dict/ooo
Ищем файл
dictionary.lst
И удаляем оттуда все ссылки на словари которые нам сейчас не нужны.
Фактически мы удаляем только указатели - какие словари использовать,
сами словари остаются на месте и при необходимости могут быть снова добавлены.
В моем случае расход памяти снижался с 300 метров до 50.
Для ввода команд без переключения раскладки достаточно прописать в ~/.vimrc:
set langmap=йq,цw,уe,кr,еt,нy,гu,шi,щo,зp,х[,ъ],фa,ыs,вd,аf,пg,рh,оj,\
лk,дl,э',яz,чx,сc,мv,иb,тn,ьm,б\,,ю.,ё`
Удаление комментариев и пустых строк
sed '/ *#/d; /^ *$/d'
Объединение строк разделенных символом \
sed ':a; /\\$/N; s/\\\n//; ta'
Удаление граничных пробелов и табуляций
sed 's/[ \t]*$//'
Вывести список слов с ошибками:
cat file.txt | ispell -d russian -l
Детальный разбор ошибок с вариантами замены:
echo file.txt | ispell -d russian -a
Для скриптов на perl рекомендую использовать модуль Lingua::Ispell.
Жестко разбить по 60 символов в строке: fold -w 60 test.txt
Разбивать только по пробелам, не разбивая слова на части: fold -s -w 60 test.txt
Для форматирования текста программы на Си можно воспользоваться утилитой indent.
Разбить на параграфы поможет fmt из textutils.
:set ic|noic - установить|снять игнорирование различия больших и маленьких букв.
/web *master - поиск по маске
/ - продолжение поиска вперед, ? - назад.
V - выделение в vim с подсветкой (визуальный режим отметки блока)
:.,$s/Windows/Linux/gс - заменить Windows на Linux с текущей позиции до конца,
при каждой замене спрашивать подтверждение.
:set ai|noai - включить|выключить автоматическое выравнивание.
:syntax on|off - включить|выключить подцветку синтаксиса.
:set syntax=perl|c|java|html - выбрать язык для подцветки.
Собрал себе OpenOffice 2 версии и столкнулся с проблемой - не хочет проверять русский язык. Ниже описание как была решена проблема.
Когда OO способен проверять орфографию, он выставляет синию галочку у названия языка в соответсвующей менюхе. В FreeBSD это по умолчанию не происходит, что грустно.
Для того, чтоб OO начал проверять орфографию русских слов в FreeBSD нужно ему скормить русский модуль. Сам модуль доступен на сайте OO по адресу [1].
Скачав модуль и сохранив его в любом удобном месте, идём в меню Файл > Мастер > Установить новые словари. Там выбираем абсолютно любой словарь и жмём кнопку. В открывшемся мастере преключаем язык на английский (ниспадающая менюшка внизу) - выбираем пункт Current user setup, затем савим галку у Off-line language pack installation и прописываем путь к скачанному фалу (в моём случае это ru_RU-pack.zip).
Далее отвечаем на вопросы мастера, выбирая все словари с помошью Control (о чём там и говориться). Закрываем OO, открываем OO :)
Всё, словари стоят, идём в Сервис > Параметры - Натсройка языка > Лингвистика и выбираем там проверку орфографии и всё что нам нужно.
Настройка KOI8-R:
vi /etc/rc.conf
keymap="ru.koi8-r"
font8x8="cp866-8x8"
font8x14="cp866-8x14"
font8x16="cp866b-8x16"
scrnmap="koi8-r2cp866"
cursor="destructive"
Заменить все cons25 на cons25r в /etc/ttys:
vi /etc/ttys
:%s/cons25/cons25r/g
kill -HUP 1
(чтобы перечитался /etc/ttys)
/etc/rc.d/syscons restart
pw usermod root -L russian
(выполнить для всех имен пользователей кому нужен русский, если вы ходите
на сервер только удаленно по ssh/telnet, то можно выполнить только этот шаг для настройки
поддержки русского языка KOI8-R в системе)
Настройка UTF-8 (для работы с удаленного терминала):
В /etc/login.conf добавляем:
russian-utf8|Russian Users Accounts:\
:charset=UTF-8:\
:lang=ru_RU.UTF-8:\
:lc_all=ru_RU.UTF-8:\
:tc=default:
Перестраиваем БД:
cap_mkdb /etc/login.conf
Прикрепляем пользователя:
pw usermod логин -L russian-utf8
Добавляем в /etc/profile
MM_CHARSET=UTF-8; export MM_CHARSET
Алексей Гуськов представил (http://kvasdopil.livejournal.com/31964.html) инструкцию
по установке UTF-8 в физической консоли, при помощи утилиты jfbterm:
Jfbterm работает через framebuffer, поддерживает VESA-разрешения и 256 цветов,
позволяет поставить в фон терминала картинку, работает с мышью и т.д.
В общем, качаем, ставим и компилим. (Если не скомпилялось, ставим последний autoconf и automake)
fetch http://www.ac.auone-net.jp/~baba/jfbterm/jfbterm-FreeBSD-0.5.1.tar.gz
tar xvzf jfbterm-FreeBSD-0.5.1.tar.gz
cd jfbterm-FreeBSD-0.5.1
./configure CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib --prefix=/usr/local --mandir=/usr/local/man
/usr/local/bin/gmake
sudo /usr/local/bin/gmake install
Выставляем параметры терминала
cat /usr/local/share/jfbterm/termcap.jfbterm >> /usr/share/misc/termcap
cap_mkdb /usr/share/misc/termcap
Создаём конфиг
cp /usr/local/etc/jfbterm.conf.sample /etc/jfbterm.conf
Качаем и ставим уникодный шрифт
fetch http://www.ac.auone-net.jp/~baba/gnu-unifont/unifont.pcf.gz
mkdir -p /usr/local/lib/X11/fonts/local/
cp unifont.pcf.gz /usr/local/lib/X11/fonts/local/
Запускам (в терминале)
jfbterm
Если UTF не отображается, то меняем в конфиге /etc/jfbterm.conf строчку
encoding: locale
на
encoding: UTF-8
Прикрутить ввод русских букв можно через uim-m17nlib.
В системе с UTF-8 не совсем удобно по ssh ходить по серверам на которых установлена локаль ru_RU.KOI8-R.
gnome-terminal позволяет выбрать кодировку только через меню.
Решить проблему, можно создав ярлык запускающий gnome-terminal, как:
sh -c "export LANG=ru_RU.KOI8-R; gnome-terminal --disable-factory"
При этом в терминале будет локаль ru_RU.KOI8-R,
будет работать копирование русского текста через буфер обмена из UTF-8 системы.
Midnight Commander в пакетах пропатчен на предмет utf-8 и не позволяет работать с текстом в других кодировках,
решить проблему можно пересобрав его из пакета с исходными текстами, отключив наложении unicode патча.
PS. В комментарии подсказали, что можно использовать: luit -encoding "KOI8-R" ssh ip
Скрипт, использующий dcop для упрощения процесса смены кодировки в konsole при подключении к ssh.
Как и всякая программа KDE, konsole использует DCOP для внутрисистемных коммуникаций.
Это означает, что запущенной программой можно управлять из командной строки
командами типа "dcop konsole-2115 konsole setFullScreen true".
Здесь konsole-2115 - название программы + её pid, все остальные
аргументы - это, говоря языком ООП, объект, методы и параметры.
Список программ, которыми можно рулить подобным образом, и их
объектов с методами можно получить, выполняя последовательно
команды dcop, dcop konsole-2115, dcop konsole-2115 konsole и т.д.
Konsole при запуске устанавливает две переменные окружения:
KONSOLE_DCOP, в которой хранится ссылка на текущий экземпляр программы, и
KONSOLE_DCOP_SESSION - ссылка на текущий сеанс.
Для установки кодировки текущего сеанса нужно использовать такую команду:
dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R
Собственно, на этом задачу можно считать решённой, осталось правильно оформить ответ :)
В качестве быстрого решения подойдёт прописывание в .bashrc alias'ов для всех интересующих хостов:
alias 01='dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R;\
ssh bpp@192.168.0.1 $*;dcop $KONSOLE_DCOP_SESSION setEncoding UTF8;'
alias 02='dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R;\
ssh bpp@192.168.0.2 $*;dcop $KONSOLE_DCOP_SESSION setEncoding UTF8;'
alias 03='dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R;\
ssh bpp@192.168.0.3 $*;dcop $KONSOLE_DCOP_SESSION setEncoding UTF8;'
Более правильное решение - оформить это в виде небольшого скрипта ~/bin/ssh-launcher.sh,
который умеет переименовывать сеанс и проверять, выполняется ли команда в konsole,
а не, например, в xterme, который dcop не поддерживает. Кроме того,
скрипт можно расширять, добавляя установку различных параметров konsole в зависимости от хоста назначения.
#!/bin/bash
if !([[ "$1" ]] && [[ "$2" ]]) ; then
echo Usage: $0 username hostname \[ ssh parameters \]
exit 1
fi
ssh_params=( $* )
ssh_user=${ssh_params[0]}
ssh_host=${ssh_params[1]}
unset ssh_params[0]
unset ssh_params[1]
ssh_parameters=${ssh_params[*]}
if [[ x"$KONSOLE_DCOP" != "x" ]] ; then # если мы в konsole
dcop $KONSOLE_DCOP_SESSION setEncoding KOI8-R
dcop $KONSOLE_DCOP_SESSION renameSession $ssh_user@$ssh_host
ssh $ssh_user@$ssh_host $ssh_parameters
dcop $KONSOLE_DCOP_SESSION renameSession `whoami`@`hostname`
dcop $KONSOLE_DCOP_SESSION setEncoding UTF8
else
kdialog -text "run this from konsole"
fi
Теперь в ~/.bashrc можно прописать alias'ы длы вызова этого скрипта:
alias 01='ssh-launcher bpp@192.168.0.1 $*'
alias 02='ssh-launcher bpp@192.168.0.1 $*'
alias 03='ssh-launcher bpp@192.168.0.1 $*'
...
alias bpp='ssh-launcher bappoy@bappoy.pp.ru $*'
P.S. Обратите внимание на $* в конце alias'а - благодаря этой переменной
можно очень быстро выполнять команды на указанном сервере:
01 ps -ax\|grep httpd\|wc -l
Ссылки про DCOP:
KDE DIY - Building Your Own Tools
http://docs.kde.org/userguide/kde-diy.html
Using DCOP from the command line (Linux Gazette #97)
http://linuxgazette.mirrors.org.ua/issue97/oregan2.html
DCOP @Wikipedia
http://en.wikipedia.org/wiki/Dcop
1. в ~/.xinitrc пишем (именно сюда а не в /etc/profiles потому как
системная консоль FreeBSD не поддерживает юникод, посему локаль сия
будет использоваться только в иксах):
export LANG='ru_RU.UTF-8'
export LC_ALL='ru_RU.UTF-8'
2. выполняем конвертацию содержимого файловой системы из koi8-r в
UTF-8 (необходим порт converters/convmv):
%convmv -f koi8-r -t UTF-8 путь_к_разделу/* --notest -r
3. далее все зависит от терминала, если у вас что-то вроде
gnome-terminal, то достаточно будет сменить кодировку в опциях на
UTF-8, если же у вас что-то вроде xterm'а, тогда в ~/.Xresources
необходимо будет поменять шрифт, например так (для этого шрифта
необходим пакет x11-fonts/terminus-font):
XTerm*font: -*-terminus-medium-*-*-*-*-*-*-*-*-iso10646-1
для syscons(4) на i386:
1. ставим sysutils/jfbterm и textproc/uim-m17nlib
2. меняем стандартную переключалку языка с Shift+Space на Ctrl+\
добавлением в ~/.uim
(define-key generic-on-key? "<Control>\\")
(define-key generic-off-key? "<Control>\\")
3. ставим локаль и добавляем запуск uim-fep и jfbterm в ~/.profile
export LANG=ru_RU.UTF-8
exec jfbterm -e uim-fep
или в ~/.login (для tcsh)
setenv LANG ru_RU.UTF-8
exec jfbterm -e uim-fep
При отображении строк в RRD используется кодировка UTF-16, в которой есть таблица русских символов,
соответствующая таблице CP1251, только со смещением.
Чтобы rrdgraph смог отображать русские символы на графиках
необходимо внести изменения в файл src/rrd_afm.h. Находим в нем строчку
#define afm_fix_osx_charset(x) (x)
и заменяем на
#define afm_fix_osx_charset(x) \
( (x) >= 128 && (x) <= 255 ? (x) + 0x0350 : (x))
Таким образом, если в строке встречается символ с кодом между 127 и 256, то к нему применяется смещение 0x0350.
Строки необходимо записывать в CP1251 (я использую vim с libiconv).
Для работы с KOI8 необходима еще таблица перестановок из KOI8 в CP1251
Для этого в файл src/rrd_afm.c добавляем описание таблицы
const unsigned char afm_koi2win[128] = {128,129,130,131,132,133,134,135,136,
137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,
156,157,158,159,160,161,162,184,164,165,166,167,168,169,170,171,172,173,174,
175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,254,224,
225,246,228,229,244,227,245,232,233,234,235,236,237,238,239,255,240,241,242,
243,230,226,252,251,231,248,253,249,247,250,222,192,193,214,196,197,212,195,
213,200,201,202,203,204,205,206,207,223,208,209,210,211,198,194,220,219,199,
216,221,217,215,218};
а в src/rrd_afm.h такие строки
extern const unsigned char afm_koi2win[128];
#define afm_fix_osx_charset(c) \
( (c) >= 128 && (c) <= 255 ? afm_koi2win[(c) - 128] + 0x0350 : (c))
Для того, чтобы вернуться к родной для многих KOI8-R локали вместо дефолтной UTF8 нужно сделать следующее:
а) Для начала необходимо сгенерировать локаль ru_RU-KOI8-R, делается это командой locale-gen.
В качестве парамета ей целесообразно указать язык (ru), иначе она будет генерировать
локали всех языков (/usr/share/i18n/locales/*), но только для кодировки UTF-8.
Для языка ru будут сгенерированы следующие локали:
#cat /var/lib/locales/supported.d/ru
ru_RU.UTF-8 UTF-8
ru_UA.UTF-8 UTF-8
Следующими командами можно заставить сгенерировать ее локаль для кодировки KOI8-R:
#sudo echo "ru_RU.KOI8-R KOI8-R" >> /var/lib/locales/supported.d/ru
#sudo locale-gen ru
Generating locales...
ru_RU.KOI8-R... done
ru_RU.UTF-8... done
ru_UA.UTF-8... done
Generation complete.
б) Далее, обновляем переменные окружения:
sudo vim /etc/environment
Пишем:
LANG="ru_RU.KOI8-R"
LANGUAGE="ru_RU:ru:en_GB:en"
С русификацией иксов покончено
в) Приступаем к консоли. Пишем:
apt-get install console-cyrillic
В файл .profile добавляем:
loadkeys /usr/share/console-cyrillic/ru-koi8-r.kmap
consolechars -f /usr/share/console-cyrillic/UniCyr_8x14.psf -m \
/usr/share/ console-cyrillic/koi8-r.acm.gz
Готово.
У меня заработало все, кроме mcedit, который пришлось пересобрать.
Для исправления ситуации, когда для некоторых сайтов
(например всех англоязычных) Opera отображает шрифты без сглаживания (anti-aliasing),
нужно в секцию "[User Prefs]" файла ~/.opera/opera6.ini поместить строку:
Enable Core X Fonts=0
Если не помогло, можно попробовать запустить Opera установив переменную окружения "QT_XFT=true".
В /etc/menu-methods/lang.h или /etc/menu-methods/menu.h
для lang() и languages() прописать кодировку, например:
function lang()=ru_RU.KOI8-R""
function languages()="ru_RU.KOI8-R"
Из-под root запустить:
update-menus
Подключение русской раскладки:
echo ru > /etc/kbdtype
После чего добавляем в /etc/rc.local такое:
wsfontload /usr/share/misc/pcvtfonts/koi8-r-8x16
for cons in `jot 6 1 6`; do wsconscfg -dF $cons; wsconscfg -t 80x25bf $cons; done
unset cons
wsconsctl -w keyboard.map+="keycode 157=Mode_Lock"
Вместо koi8-r-8x16 можно указать koi8-u-8x16.
В качестве переключателя раскладки используется правый CTRL
Замечание: Экран ttyC0 создаётся всегда и не может быть удалён, поэтому не может отображать кириллицу.
Чтобы при наборе русских символов, при нажатии на клавишу с вопросом, рядом с правым Shift,
печатались точка и запятая, вместо вопроса и слэша, в Section "InputDevice" файла конфигурации XOrg или XFree86
меняем:
Option "XkbLayout" "us,ru"
на
Option "XkbLayout" "us,ru(winkeys)"
или просто добавляем (запятую не пропустите):
Option "XkbVariant" ",winkeys"
- Копируем ttf шрифты ~/.font, переходим в директорию ~/.font
- Запускаем: ttmkfdir > fonts.scale
- Запускаем: mkfontdir
- Запускаем: fc-cache ./
- Прописываем ~/.font в /etc/X11/fs/config (список "catalogue") или запускаем:
/usr/sbin/chkfontpath --add ~/.font
- Запускаем: xset fp rehash
- Запускаем: service xfs restart
- Проверяем, новые шрифты должны быть показаны в выводе утилит fc-list, xlsfonts, xfontsel, kcharselect, gfontsel и chkfontpath;
В KDE можно использовать: "Control Center/System/Font Installer".
В OpenOffice для добавления шрифтов нужно использовать утилиту spadmin.
Для AbiWord шрифты нужно скопировать в /usr/share/abisuite/AbiSuite/fonts и запустить
mkfontdir; ttmkfdir > fonts.scale
При наличии проблем с антиалиасингом, необходимо пересобрать библиотеку FreeType, активировав
"#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER" в include/freetype/config/ftoption.h
В AltLinux рекомендуется поставить пакеты freefont-fonts-ttf, freetype и ms-fonts-ttf.
Другой способ добавления шрифтов:
Копируем шрифты например в директорию, ~/fonts
В ~/.xinitrc добавляем
xset fp+ $HOME/fonts/
Я работаю в юникоде. Чтобы xmms мне корректно отображал русские имена файлов я его запускаю вот так:
env LC_MESSAGES=en_US.UTF-8 LANG=ru_RU.UTF-8 xmms
Русские теги xmms отображает криво потому, что они в кодировке cp1251.
Чтобы решить этот вопрос я ставлю шрифты для плейлиста и главного окна с кодировкой cp1251.
У меня такой шрифт:
-adobe_windows_1251-helvetica-medium-r-normal-*-*-100-*-*-p-*-microsoft-cp1251
А взял я эти шрифты адресу http://www.inp.nsk.su/~bolkhov/files/fonts/cyr-rfx/
В принципе, можно взять любые, в которых есть поддержка кодировки cp1251.
Чтобы GTK приложения могли корректно отображать имена файлов, в которых встречаются русские символы
нужно определить переменную окружения G_BROKEN_FILENAMES=1
для csh, можно поместить её в ~/.cshrc:
setenv G_BROKEN_FILENAMES 1
для bash, sh:
export G_BROKEN_FILENAMES=1
Единственное нормальное средство для конвертации в текст из PDF или PS с кириллицей внутри,
утилита pdftotex из комплекта xpdf:
pdftotext -enc KOI8-R test.pdf
pdftotext -raw -enc KOI8-R test.pdf
Mozilla должна быть собрана с поддержкой FreeType2 (http://www.freetype.org/),
проверка:
ldd /usr/lib/mozilla/mozilla-bin| grep libfreetype
Редактируем файл unix.js:
$ locate unix.js
/usr/lib/mozilla/defaults/pref/unix.js
Активируем TrueType шрифты, заменяем
pref("font.FreeType2.enable", false);
на
pref("font.FreeType2.enable", true);
Прописываем версию установленной библиотеки FreeType2:
pref("font.freetype2.shared-library", "libfreetype.so.6");
Определяем шрифты, добавляем в unix.js:
pref("font.directory.truetype.1", "/usr/X11R6/lib/X11/fonts/TrueType");
Устанавливаем TrueType шрифты как активные:
Edit->Preferences...->Appearance->Fonts
как обычно /etc/x11/XF86Config, секция Section "InputDevice" добавляем:
Option "XkbLayout" "us,ru"
Option "XkbModel" "pc104"
Option "XkbRules" "xfree86"
Option "XkbVariant" ",winkeys"
Option "XkbOptions" "grp:ctrl_shift_toggle,grp_led:scroll"
и переключение раскладки роботает, теперь в /etc/SUSEconfig/profile ремим
# LANG="en_US"
# export LANG
и добавляем
export LANG=ru_RU
export LC_ALL=ru_RU
Потом добавляем через controlcenter шрифты от Windows.
Из каталога /usr/X11R6/share/themes/Default/gtk
нужно полностью скопировать содержимое файла gtkrc.ru в конец файла .gtkrc-kde.
Это позволит "говорить" русскими буквами GTK-приложениям под KDE.
Столкнулся с проблемой русификации liece(1.4.10) под Xemacs(21.4.12).
Кириллица корректно отображалась в VM, Gnus но liece показывал абракадабру.
Установка process-coding-system-alist network-coding-system-alist на koi8-r не помогла.
Проблема была решена с помощью:
(setq liece-mime-charset-for-write 'koi8-r)
(setq liece-mime-charset-for-read 'koi8-r)
cd /usr/ports/sysutils/cd9660_unicode
make && make install
грузить модуль через
kldload /lib/cd9660_unicode/cd9660_[unicode|koi8-r|iso-8859-5|cp866].ko
Bash: $HOME/.inputrc
set convert-meta off
set input-meta on
set output-meta on
$HOME/.bash_profile
export CHARSET=KOI8-R
export MM_CHARSET=KOI8-R
export LANG=ru_RU.KOI8-R
Tcsh[Csh] $HOME/.login
setenv CHARSET KOI8-R
setenv MM_CHARSET KOI8-R
setenv LANG ru_RU.KOI8-R
В Joliet файлы хранятся в unicode, соответственно codepage=unicode.
Если файлы записаны в 866 кодировке нужно добавить ",codepage=866"
mount -t iso9660 -o iocharset=koi8-r,ro,noexec,mode=0444 /dev/cdrom /mnt/cdrom
или в /etc/fstab:
/dev/cdrom /mnt/cdrom iso9660 noauto,user,ro,noexec,mode=0444,iocharset=koi8-r
а затем: mount /mnt/cdrom
/dev/acd0c /mnt/cdrom cd9660 ro,noauto,-W=koi2dos,
-L=ru_RU.KOI8-R 0 0
/dev/fd0 /mnt/flop msdos rw,noauto,-W=koi2dos,
-L=ru_RU.KOI8-R 0 0
/dev/ad0s2 /mnt/store msdos rw,-W=koi2dos,
-L=ru_RU.KOI8-R,noexec,nosuid,nosymfollow,
-u0,-g0,-m 660 0 0
Еще для удобства можно создать симлинки типа:
ln -sf /dev/acd0c /dev/cdrom
ln -sf /dev/acd1c /dev/cdrom1 (если есть второй cdrom)
ln -sf /dev/fd0 /dev/flop
прописать изменения в fstab,
и монтировать диски командой mount /dev/cdrom а не
mount /dev/acd0c =).
Находим файлы символических ссылок, которые никуда не указывают.
find / -noleaf -type l -print | perl -nle '-e || print'
Эта команда выведет все мертвые ссылки на стандартные вывод.
Можно перевести вывод в файл, для изучения и исправления.
Или просто удалить, добавив конвейер: "| xargs rm", то есть так:
find / -noleaf -type l -print |perl -nle '-e || print' | xargs rm
PS. В BSD системах нужно отбросить опцию -noleaf, которая реализована только в GNU find.
Утилита par2 позволяет добавлять к файлам информацию для восстановления по алгоритму Рида-Соломона.
Это позволяет восстанавливать исходный файл в случае небольших (или даже серьезных) повреждений.
Делается это следующим образом:
$ sudo aptitude install par2 #(cd /usr/ports/archivers/parchive; make instal)
$ ls
dump.sql.gz
$ par2 create -v -r10 -n1 -m500 dump.sql.gz
$ ls
dump.sql.gz dump.sql.gz.par2 dump.sql.gz.vol000+100.par2
Эта команда добавит 10% (-r10) избыточной информации к данным, запишет все это в один файл (-n1),
при этом программе par2 разрешено использовать 500 мегабайт оперативной памяти (-m500).
Файлы *.par2 следует записать на диск вместе с дампом.
Восстановить поврежденный файл можно командой
$ par2 repair dump.sql.gz.par2
Подробнее о par2 и чтении данных с битых CD:
http://alexey.sveshnikov.ru/blog/2008/04/10/broken-cd-parchive/
Подробнее про о коде Рида-Соломона:
http://www.insidepro.com/kk/027/027r.shtml
Для переименования группы директорий первого уровня вложенности с перекодированием из cp1251 в koi8-r:
find . -type d -maxdepth 1 -exec sh -c 'np=`echo {}|iconv -t koi8-r -f cp1251`; mv "{}" "$np"' \;
Для переименования иерархии файлов:
find . -type f -exec sh -c 'dn=`dirname "{}"`;bn=`basename "{}"`; np=`echo $bn|iconv -t koi8-r -f cp1251`; mv "{}" "$dn/$np"' \;
Когда есть необходимость передать файл с одной машины на другую,
а под рукой нет общедоступных ресурсов, можно сделать так:
nc -l -p 8080 < file
или
netcat -l 8080 < file
на клиенте достаточно в браузере набрать http://192.168.0.123:8080
Собственно, все. Впрочем, если получатель - блондинка, которая не знает команды File-Save, можно написать так:
(echo -e "HTTP/1.1 200\nContent-Disposition: attachment;
filename=gena_na.png\nContent-Type: application/octet-
stream\nConnection: close\n"; cat vim_mrxvt.png ) | nc -vv -l -p 8080
Но это еще не все. Можно дать доступ к целой директории, написав простой HTTP сервер в одной строке:
while true; do nc -vv -l -p 8080 -c '( read a b c; file=`echo $b | sed 's/[^a-z0-9.]//g'`;
if [ a$file = "a" ]; then ( ls | (while read f; do echo "<a href=$f>$f</a><br>"; done) );
else cat $PWD/$file; fi )'; sleep 1; done
Этот скрипт отдает все файлы, которые есть в текущем каталоге и не позволяет его сменить.
В случае, если запрашивается корневая директория, то управление передается
своеобразному mod_index - т.е. выводится список файлов-ссылок. В конце добавлена задержка в 1 сек
для того, чтобы была возможность убить его нажатием Ctrl-C.
См. подробнее http://alexey.sveshnikov.ru/blog/2006/12/23/http-сервер-размером-в-222-байта/
Что делать если под рукой нет tripwire или osec, а кривой aide вы пользоваться не хотите.
Часть функций , таких как проверка прав доступа и изменение файлов, можно реализовать штатными стедствами.
Вот маленький скрипт который помещается в crontab и позволяет это реализовать.
При желании его функции можно легко расширить.
#!/bin/bash
ulimit -t 20
checkdir="/bin /sbin"
filedb="/var/tmp/permsecdb"
email="test@test.ru"
out=$(
exec 2>&1
umask 266
find $checkdir -type f -printf "%m\t" -exec md5sum {} \; >$filedb.tmp
diff $filedb $filedb.tmp
mv -f $filedb.tmp $filedb
)
if [ "$out" ];then
(date; echo; echo "$out") |mail -s "Change permsec `hostname`" $email
fi
- ulimit лучше выставить не случай не предвиденных ситуаций.
- checkdir соответственно проверяемые директории
- filedb текстовой файл базы
- email куда посылать мыло
Если изменений в системе не было, то сообщения посылаться не будут.
Сообщение бывает 4 видов
1 - ошибки
2 - добавлен файл "> 644 d41d8cd98f00b204e9800998ecf8427e /bin/12"
3 - удален файл "< 755 c1a0ff878c603dd91f603059e9c1a0a1 /bin/12"
4 - изменен файл "
< 755 ce367ef1e2cca19e6216874cb8c09d96 /bin/12
---
> 755 c1a0ff878c603dd91f603059e9c1a0a1 /bin/12"
Успешного контроля.
Найти все файлы размером более 10 Мб.
find / -size +10240k
Более 500 Кб, но менее 600 Кб
find . -size +500k -a -size -600k
Файлы менее 128 байт, модифицированные последние 10 мин.
find . -type f -a -size -128c -a -mmin -10
Резервный диск монтируем как /backup в read-only режиме.
По крону еженощно запускаем скрипт следующего содержания:
/sbin/mount -u -w /backup # пепреводим раздел в rw режим, mount "-o remount,rw /backup" для Linux
/usr/bin/rsync -a --delete --delete-excluded --max-delete=200 \
--exclude-from=/etc/ex_files_list.txt / /backup
RETCODE=$?
if [ $RETCODE -ne 0 ]; then
echo "Err code=$RETCODE"| mail -s "RSYNC BACKUP ERROR" alert@test.ru
fi
/sbin/mount -u -r /backup # раздел обратно в ro, mount "-o remount,ro /backup" для Linux
Если backup-диск большой, лучше вести две полные копии, на случай краха во время бэкапа (или см. опцию --backup);
При бэкапе на другой сревер:
rsync [...опции как выше] --compress --bwlimit=100 --timeout=120 \
-e ssh source/ login@backuphost:/backup/node1
Список файлов для исключения из бэкапа (ex_files_list.txt):
/backup
/mnt
/proc
/tmp
/var/log
/usr/obj
/usr/src
/usr/tmp
/usr/ports
/usr/local/apache/logs
> На одной машине создается файл с правами -rw-rw-r--, а на другой -rw-r--r--.
man 2 umask
В первом случае используется umask 002, а во втором umask 022.
764 является комбинацией из цифр UserGroupOther.
В 90% случаев нужно всего три цифры запомнить 7 - rwx, 6 - rw, 4 - r, (1 - x, 5 - rx и т.д. ).
Можно писать сразу: chmod u=rw file; chmod g=rx,o=rx file, chmod o-w file и т.д.
С локальной на удаленную:
tar czvf - список_файлов_и_директорий | ssh remote.test.ru tar xzf - -C /home/user/куда_копировать
Скопировать группу файлов с удаленной машины на локальную.
ssh remote.test.ru tar czf - -C стартовая_директория какие_файлы_копировать |tar xzf - -C директория_куда_копировать.
MySQL:
Посмотреть список глобального и локального часового пояса:
SHOW VARIABLES LIKE '%time_zone%';
Конвертация в запросе времени из одной временной зоны в другую:
SELECT CONVERT_TZ('2008-10-24 5:00:00','UTC','MSK');
Изменить текущую зону для локального соединения:
SET time_zone = 'MSK'
или
SET time_zone = '+03:00';
Для всего MySQL сервера часовой пояс можно поменять установив в файле конфигурации:
default-time-zone='MSK'
или под привилегированным пользователем выполнить запрос:
SET GLOBAL time_zone ='MSK'
PostgreSQL:
Для текущей сессии зона задается через:
SET TIME ZONE 'MSK'
или
SET TIME ZONE '-3'
Для клиентов использующих libpq часовой пояс может быть определен в переменной окружения PGTZ.
Если часовой пояс для всей СУБД не определен (параметр timezone) в postgresql.conf, он берется из
стандартной переменной окружения TZ
в shell:
export TZ=GMT-3
в perl:
$ENV{"TZ"}="GMT-3";
в PHP:
putenv("TZ=GMT-3");
Иногда пользовательские скрипты или зависают, или хотят соединиться с чем-то запрещенным в файрволе,
или интерпретатор неожиданно вылетает, не передав заголовок Content-type, что приводит к ошибке 500.
Для того, чтобы разобраться в причине, попробуем отладить скрипты со стороны сервера,
не залезая в код php. Сначала придется изменить конфигурацию apache, чтобы php работало через suphp,
а не через модуль mod_php5. Я не буду рассказывать, как это делается. Главное, кроме обычного,
"неотладочного", надо добавить свой обработчик в suphp.conf:
x-httpd-php_debug=php:/usr/local/bin/php-cgi.sh
А вот содержимое этого скрипта /usr/local/bin/php-cgi.sh. Поставьте ему права 755.
Видно, что он запускает отладчиком php с перенаправлением отладочной информации в файл.
#!/bin/bash
/usr/bin/strace /usr/bin/php5-cgi $@ 2>/tmp/debug
Не забудьте добавить этот обработчик в конфиг apache , это делается строкой
suPHP_AddHandler x-httpd-php_debug
Затем в .htaccess нужного сайта допишите
AddHandler x-httpd-php_debug .php
В результате после повторной загрузки сайта появится файл /tmp/debug, в который будет добавляться
отладочная информация о работе php нужного сайта. В это время лучше ограничить посещение сайта,
разрешив только 1 IP адрес, чтобы отладочной информации не было чрезмерно.
Обычно будет достаточно имени системного вызова, который приводит к прекращению выполнения скрипта.
Можно поиграться с параметрами strace.
В наличии два ПК, на которых установлен Gentoo Linux с одинаковой версией gcc (4.3.1).
Так как компиляция из исходников в Gentoo необходима и компиляция отнимает некоторое время,
хотелось бы сократить время сборки. На помощь приходит distcc и ccache.
Всё описанное ниже нужно проделать на обоих ПК.
emerge distcc ccache #установим distcc и ccache
Две данные строчки появились в данной статье при помощи метода профессора Копи-Пастера:
mv /root/.ccache /root/snafu.ccache
ln -s /var/tmp/ccache /root/.ccache
distcc-config --set-hosts "192.168.0.1 192.168.0.2" #перечислим ip адреса серверов distcc
rc-update add distccd #
/etc/init.d/distccd restart
ccache -M 4G
/etc/conf.d/distccd
DISTCCD_OPTS="${DISTCCD_OPTS} -allow 192.168.0.0/24" #разрешим доступ для подсети
настроим make.conf
FEATURES="ccache distcc"
CCACHE_DIR="/var/tmp/ccache"
CCACHE_SIZE="4G"
DISTCC_HOSTS="192.168.0.1 192.168.0.2"
DISTCC_DIR="/tmp/.distcc"
#DISTCC_VERBOSE="1" #раз комментировать при желании лицезреть подробный отчет о проделанной работе distcc
Источник http://wildarcher7.wordpress.com/
Недавно была добавлена интересная особенность в Workstation 6.0, которая делает WS6 отличным средством
для отладки ядра Linux. Теперь можно с легкостью отлаживать Linux VM на хосте при помощи gdb
без каких-либо изменений в Guest VM. Ни каких kdb, перекомпиляций или еще одной машины не требуется.
Все что вам потребуется, так это всего одна строчка в VM'шном конфигурационном файле.
Чтобы использовать новую особенность, необходимо достать последний билд WS6:
http://www.vmware.com/products/beta/ws/
Разместить в вашем Linux VM конфигурационном файле строчку:
debugStub.listen.guest32=1
Теперь, всякий раз, когда вы запускаете виртуальную машину, Вы будете видеть на хост консоле:
VMware Workstation is listening for debug connection on port 8832.
Запустите gdb на хосте, ссылаясь на ядро, для которого у Вас есть System.map и присоедините его к виртуальной машине:
% gdb
(gdb) file vmlinux-2.4.21-27.EL.debug
(gdb) target remote localhost:8832
программа - файл рухнувшей программы, собранной с включением отладочной информации
core - файл с core
$ gdb
Указываем файл рухнувшей программы, собранной с включением отладочной информации
(gdb) программа
Указываем файл с core, будет показана присина и строка на которой приложение рухнуло
(gdb) core core
(gdb) info thread
(gdb) info shared
(gdb) info locals
(gdb) info files
(gdb) info variables
(gdb) help info
Смотрим состояние стека до падения
(gdb) backtrace 1
(gdb) backtrace 2
или просто (gdb) backtrace
Указываем номер фрейма который будем смотреть подробнее (показан как #N)
(gdb) frame 0
Смотрим состояние переменных (в примере - result)
(gdb) info locals
(gdb) print result
(gdb) whatis result
Полезно также посомотреть на выполнении какого системного вызова происходит сбой используя программы
strace (http://strace.sourceforge.net), ltrace (для Linux) или ktrace и truss (входят в состав FreeBSD).
Собираем по умолчанию:
readelf -d /usr/local/bin/gnome-terminal |grep NEEDED | wc -l
52 - требуется 52 библиотеки.
Устанавливаем флаг --as-needed:
export CFLAGS = "-Os -s -Wl,--as-needed"
После пересборки, требуется 21 реально необходимая для работы библиотека.
Блокируемый I/O - после вызова read/write происходит блокировка до завершения
операции, функция завершается только после принятия или передачи блока данных.
Неблокируемый I/0 - функция завершается сразу, если данные не были приняты/отправлены
возвращается код ошибки (т.е. нужно вызывать функции I/O в цикле пока не получим
положительный результат).
Мультиплексирование через select/poll - опрашиваем список состояния сокетов,
перебирая состояния определяем сокеты готовые для приема/передачи.
Главный минус - затраты на перебор, особенно при большом числе неактивных
сокетов.
select - число контролируемых сокетов ограничено лимитом FD_SETSIZE,
в некоторых случаях лимит обходится пересборкой программы, в других - пересборкой
ядра ОС.
poll - нет лимита FD_SETSIZE, но менее эффективен из за большего размера передаваемой
в ядро структуры.
Генерация сигнала SIGIO при изменении состояния сокета (ошибка, есть данные для приема,
или отправка завершена), который обрабатывает обработчик SIGIO.
В классическом виде применение ограничено и трудоемко, подходит больше для UDP.
Асинхронный I/O - описан в POSIX 1003.1b (aio_open, aio_write, aio_read...),
функция aio_* завершается мгновенно, далее процесс сигнализируется о
полном завершении операции ввода/вывода (в предыдущих пунктах процесс информировался
о готовности прочитать или передать данные, т.е. данные еще нужно было принять или отправить
через read/write, в aio_* процесс сигнализируется когда данные полностью получены и скопированы в локальный буфер).
Передача данных об изменении состояния сокета через генерацию событий. (специфичные для определенных ОС решения, малопереносимы, но эффективны).
kqueue - лучшее для FreeBSD, NetBSD. Данные о нескольких событиях могут быть переданы за раз, очень гибкое решение.
/dev/epoll - лучшее для 2.6 Linux ядра, передача нескольких событий за раз, трудоемкость поддержки /dev/epoll если параллельно в программе поддерживаются другие механизмы нотификации.
Realtime Signals (F_SETSIG) - лучшее для 2.4 Linux ядра.
/dev/poll - имеет смысл в Solaris, в Linux реализация недостаточно хороша.
Ссылки:
libevent - очень хорошая библиотека враппер для работы с kqueue, select, poll, epoll и real-time signals.
-O6 - полная оптимизация (по умолчанию часто стоит -O2).
-fomit-frame-pointer -использовать стек для доступа к переменным.
-march=i686 -mcpu=i686 -DARCH=k6 -DCPU=k6 - оптимизация под CPU (586, 686,k5,k6,k7,athlon,pentiumpro).
-ffast-math -funroll-loops
Система управления версиями RCS пригодилась для сохранения резервных копий
файлов конфигурации и нескольких Perl модулей, активная разработка которых уже завершена,
но мелкие исправления и переделки еще бывают.
Итак, для работы с RCS используются следующие команды -
ci (импорт файлов в репозиторий),
co (экспорт),
rcs (манипулирование флагами файлов и проч.),
rcsdiff,
rlog.
Пусть file - файл, который требуется передать в управление RCS.
ls -la > file
Первым делом нужно создать каталог для репозитория
mkdir RCS
Затем импортировать файл. В общем случае это делается так:
ci file
Исходный файл _перемещается_ в репозиторий (если он там уже есть, то под новой версией).
Извлечь файл из репозитория можно командой:
co file
(файл будет иметь права доступа 444)
Чтобы изменить файл, нужно установить его блокировку и установить права доступа, разрешающие запись
rcs -l file
chmod o+w file
Чтобы записать изменения нужно снова выполнить
ci file
Итак, это все, что нужно для того чтобы начать работать.
Теперь пара команд, для того, чтобы работать было удобно :)
co -l file - синоним co file; rcs -l file; chmod 644 file - извлечь, заблокировать файл, разрешить запись.
ci -u file - синоним ci file; co file - сохранить файл и извлечь рабочую копию
ci -l file - синоним ci file; co -l file - сохранить файл, сделать co -l
В случае, если с файлом работает один пользователь, то в блокировках нет никакого смысла, и от них можно отказаться:
ci -l file (первоначальный импорт)
rcs -U file (установка перманентной блокировки)
vi file
ci -l file (файл сохранится в RCS и будет готов к дальнейшей работе)
Далее, самые распространненые задачи:
Извлечь файл из репозитория
co file
co -l file (синоним co file, rsc -l file -- извлечение и блокировка)
co -r1.2 file (извлечение определенной версии файла)
Посмотреть различия между текущей (=рабочей) версией и последней, сохраненной в RCS
rcsdiff file
Посмотреть различия между произвольными двумя версиями
rcsdiff -r1.1 -r1.2 file
Посмотреть логи редактирования файла
rlog file
Дальнейшее чтение: rcsintro(1), rcs(1), co(1), ci(1).
Процедура установки довольно проста, но, как часто бывает, предварительное прочтение инструкции экономит вам кучу времени. Здесь я рассматриваю простейший случай: репозиторий доступен только по HTTP/HTTPS (настройку SSL приводить не буду), разработчиков немного, поэтому персональных разрешений на директории мы не выставляем.
Сначала нужно установить Apache (я использую версию 2.2):
cd /usr/ports/www/apache22
make WITH_BERKELEYDB=db42 install
либо, если он у вас уже установлен, пересобрать его с поддержкой Berkeley DB:
Чтобы проверить, как работает наш репозиторий, можно поставить графический клиент (например, TortoiseSVN) или выполнить от имени пользователя user команду:
Сервер:
> svnadmin create /path/to/repos # создание репозитория
> cat /path/to/repos/conf/svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = passwd
realm = My First Repository
> cat /path/to/repos/conf/passwd
[users]
user = PaSsW0Rd
> cat /etc/xinetd.d/svn
service svn
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/bin/svnserve
server_args = -i -r /path/to/repos
log_on_failure += USERID
disable = no
}
> /etc/rc.d/xinetd start
Клиент:
# создаем временный каталог с проектом
> mv /path/to/project /tmp
# импортируем его в svn
> svn import /tmp/project svn://SERVER/project
# восстанавливаем проект для работы
> cd /path/to
> svn checkout svn://SERVER/project
# запись изменений на сервер
> cd /path/to
> svn commit -m "что-то тут я изменил"
# получить последнюю версию с сервера
> cd /path/to
> svn update
В документации сказано, что надо в /path/to/project создать каталоги
branches tags trunk и файлы проекта поместить в trunk.
Однако, у меня работает и так.
На сколько я знаю, нет способа 100%. Можно попробовать так, пример для gnumric'а:
Сначала нужно скачать один из файлов дистрибутива:
cvs -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome login
cvs -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome co gnumeric/ChangeLog
cvs -d:pserver:anonymous@anoncvs.gnome.org:/cvs/gnome status -v gnumeric/ChangeLog
Добавление нового файла/директории
cvs add filename
Удаление файла из репозитория
cvs remove filename
Обновление версии файла в репозитории
cvs commit filename
Обновление рабочей ветки из репозитория
cvs update
Создание рабочей ветки из репозитория
cvs checkout module_name
Создание репозитория
cvs -d /home/cvsroot init
Импорт модулей в репозиторий
cvs -d /home/cvsroot import example example_project ver_0-1
Использование тэгов
cvs tag release-1-0, cvs checkout -r tagname
Ветвление
cvs tag -b branchtag
Блокировка файлов
cvs watch add|remove -a edit|unedit|commit|all files
Настройка доступа к CVS репозиторию по сети
cvs -d :ext:cvs.example.com.au:/usr/local/cvsroot checkout sample
Решение по кэшированию повторяющихся запросов к MySQL, для оптимизации работы форума phpBB.
Устанавливаем memcached под Debian или Ubuntu:
apt-get install memcached php5-memcached
После установки не забываем перезагрузить apache или php-cgi. Чтобы php увидел новые модули.
Включаем лог медленных запросов у mysql:
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 3
и ждем с часик, после чего смотрим лог. У меня в лог попало порядка 4000 запросов -
из них легко было выделить запросы типа:
SELECT COUNT(user_id) AS total FROM phpbb_users WHERE user_id <> -1
Запрос постоянно подсчитывал количество пользователей форума на phpBB.
Понятно, что это число не особо важно - это просто статистика. Значит данные по этому запросу можно закешировать часа на 2.
Для этого открываем файл includes/functions.php ищем функцию get_db_stat()
находим код:
if ( !($result = $db->sql_query($sql)) )
{
return false;
}
$row = $db->sql_fetchrow($result);
изменяем на
$memcached = new Memcache;
$memcached->connect('localhost', 11211);
if(!$row = $memcached->get($sql))
{
if ( !($result = $db->sql_query($sql)) )
{
return false;
}
$row = $db->sql_fetchrow($result);
$memcached->set($sql, $row, MEMCACHE_COMPRESSED, time() + 7200);
}
$memcached->close();
Смысл изменения состоит в том, что в memcached данные хранятся парами (ключ, значение).
Ключом служит SQL запрос - он уникальный. Алгоритм приведенного кода состоит в следующем:
соединяемся с memcached, смотрим если такие данные по ключу, если нет только тогда дергаем базу,
если есть - то идем дальше - не посылая на базу никаких запросов. Надеюсь экономия всем понятна.
Немного о грустном - модов для phpBB + memcache я не нашел. Зато в phpbb3 эта поддержка заявлена.
А для phpBB2 придется самому выискивать такие запросы для кеширования,
а ведь еще есть моды - они тоже генерируют тяжелые запросы.
Если все сделать правильно - тормоза базы можно сократить в 2-3 раза.
Избавится от автоматического поста и не напрягать посетителя с вводом
графического кода позволит следующий алгоритм:
# Антиробот - против автопостов #
function antibot($text)
{
$text = substr($text, 1, -4);
$sear = array("'1'i","'2'i","'3'i","'4'i","'5'i","'6'i","'7'i","'8'i","'9'i","'0'i");
$repl = array("a","b","c","d","e","f","g","h","i","j");
$text = preg_replace ($sear, $repl, $text);
return $text;
}
/*
// вставляем анти-робоспам
$antitime = time();
$antiname = antibot($antitime);
echo '<input name="'.$antiname.'" type="hidden" value="'.$antitime.'">';
#----------
// проверяем анти-робоспам
$ver1time = time();
$ver2time = time()-'9999';
$ver1name = antibot($ver1time);
$ver2name = antibot($ver2time);
if ((strip_tags($_POST[$ver1name])<$ver1time and strip_tags($_POST[$ver1name])>$ver2time) or
(strip_tags($_POST[$ver2name])<$ver1time and strip_tags($_POST[$ver2name])>$ver2time))
{
$antibot = '1'; // антибот даёт добро на post
} else {
$antibot = '-1'; // антибот запрещает этот post
}
*/
PS: в функции "замена цифры на буквы" обязательно замените a-j на что-нибудь своё.
PPS: Код успешно работает около двух лет на нескольких сайтах.
Например, если в результате выполнения функции (например,
base64_encode($buffer)) на выходе получается битый файл (кавычки, \ и
символ с нулевым кодом экранированы символом \), то проблема в
использовании директив автоматического экранирования magic_quotes_gpc
(get, post, cookie) или magic_quotes_runtime (автоэкранирования в
некоторых функциях) в php.ini. Для решения проблемы нужно использовать
функцию stripslashes, например: base64_encode(stripslashes($buffer))
В PHP есть очень удобная для разного рода статистики машин функция - get_browser().
Она возвращает по юзерагенту объект, содержащий отфильтрованный набор информации
о браузере и его системе, как то имя, платформа, версия и т.п. "Т.п." - это набор информации,
о поддержке кук, дотнета и еще кучи всего, мне не нужного.
Недавно заметил, что при большом количестве обращений эта функция довольно медленная и ресурсоемкая.
Как положено, полез на http://www.php.net/get_browser читать, что пишут в комментариях.
Первое, что попробовал, перейти на облегченную версию browscap.ini...
Помогло... процентов на 5 frown.gif
В коментах нашел Browser Capabilities PHP Project. По заявлениям автора одни из основных фитч
- быстрота и полная совместимость с get_browser().
Мне так-же понравилось автоматическое обновление browscap.ini.
С совместимостью оказалось не все гладко. Если у get_browser() все свойства написаны строчными,
то у данного проекта их названия пишутся с большой буквы,
следовательно совместимость не полная. Но, это не самая большая проблема и легко обходится.
Но вот со скоростью всплыли неожиданные проблемы.
Даже после накопления кеша производительность не увеличилась и осталась на уровне get_browser()
Для себя решил эту проблему след. образом:
таблица в mysql:
CREATE TABLE `bc_cache` (
`cache_id` bigint(16) unsigned NOT NULL auto_increment,
`hash` char(32) NOT NULL default '',
`browser` char(32) NOT NULL default '',
`version` char(32) NOT NULL default '',
`platform` char(32) NOT NULL default '',
PRIMARY KEY (`cache_id`),
UNIQUE KEY `hash` (`hash`)
)
Код в PHP примерно такой:
$ua_hash = bin2hex(mhash(MHASH_MD5,$_SERVER['HTTP_USER_AGENT']));
$query = sprintf("select browser,version,platform from bc_cache where hash='%s'",$ua_hash);
$data = mysql_query($query,$res);
if (mysql_num_rows($data)) {
$browser = mysql_result($data,0,'browser');
$version = mysql_result($data,0,'version');
$platform = mysql_result($data,0,'platform');
} else {
$bc = get_browser($useragent);
$browser = $bc->browser;
$version = $bc->version;
$platform = $bc->platform;
$query = sprintf("insert into bc_cache (hash,browser,version,platform) values ('%s','%s','%s','%s')",
$ua_hash,
$browser,
$version,
$platform);
mysql_unbuffered_query($query);
}
В дальнейшем пользуюсь переменными $browser,$version и $platform как мне заблагорассудится.
Результат - повышение производительности, на глаз, раза в 4-8.
Почему? За счет того, что $_SERVER['HTTP_USER_AGENT'] хоть и может сильно различаться,
но всё-таки, вещь не самая уникальная. А select по уникальному индексу по char(32) отрабатывает очень быстро!
Иногда пользовательские скрипты или зависают, или хотят соединиться с чем-то запрещенным в файрволе,
или интерпретатор неожиданно вылетает, не передав заголовок Content-type, что приводит к ошибке 500.
Для того, чтобы разобраться в причине, попробуем отладить скрипты со стороны сервера,
не залезая в код php. Сначала придется изменить конфигурацию apache, чтобы php работало через suphp,
а не через модуль mod_php5. Я не буду рассказывать, как это делается. Главное, кроме обычного,
"неотладочного", надо добавить свой обработчик в suphp.conf:
x-httpd-php_debug=php:/usr/local/bin/php-cgi.sh
А вот содержимое этого скрипта /usr/local/bin/php-cgi.sh. Поставьте ему права 755.
Видно, что он запускает отладчиком php с перенаправлением отладочной информации в файл.
#!/bin/bash
/usr/bin/strace /usr/bin/php5-cgi $@ 2>/tmp/debug
Не забудьте добавить этот обработчик в конфиг apache , это делается строкой
suPHP_AddHandler x-httpd-php_debug
Затем в .htaccess нужного сайта допишите
AddHandler x-httpd-php_debug .php
В результате после повторной загрузки сайта появится файл /tmp/debug, в который будет добавляться
отладочная информация о работе php нужного сайта. В это время лучше ограничить посещение сайта,
разрешив только 1 IP адрес, чтобы отладочной информации не было чрезмерно.
Обычно будет достаточно имени системного вызова, который приводит к прекращению выполнения скрипта.
Можно поиграться с параметрами strace.
По умолчанию будет использоваться SuPHP.
В httpd.conf:
LoadModule suphp_module modules/mod_suphp.so
LoadModule php4_module modules/libphp4.so
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
AddHandler x-httpd-php .php
suPHP_Engine on
php_admin_flag engine off
Для избранных хостов активируем mod_php:
<VirtualHost ..>
suPHP_Engine off
RemoveHandler .php
php_admin_flag engine on
...
</VirtualHost>
Мы взяли 2 абсолютно одинаковых по-железу компьютера, один сделали
точной копией настроек "живого" сервера (пускай будет машина А), а второй пытались тюнить (Машина Б).
Каждый текст проводился отдельно (за раз - одна оптимизация, без наложения).
1. На Б было проставлен весь новый софт с настройками по-умолчанию:
А - 86 ответов/секунда
Б - 72 ответов/секунда
2. Выключен режим апача KeepAlive=off, добавлено количество одновременных запросов в MySQL:
А - 86 о/с
Б - 81 о/с
3.1 Добален модуль php accelerator (http://www.php-accelerator.co.uk/)
А - 87 о/с
Б - 93 о/с
3.2 Код скомпилен с помощью Zend, и подгружен Zend Optimizer
(http://www.zend.com/store/products/zend-optimizer.php):
A - 86 о/с
Б - 140 о/с
3.3 Код скомпилен MMcache (лучший результат)
(http://turck-mmcache.sourceforge.net/index_old.html)
A - 86 о/с
Б - 215 о/с
Тест проводился с помощью родного бэнчмарка апача. Мы были слегка удивлены тем что
Зенд не оправдал надежды + при компилировании Zend'ом, в админке не отображаются картинки.
mod_php должен быть собран с опцией --with-zlib.
Метод 1:
output_buffering = On
output_handler = ob_gzhandler
zlib.output_compression = Off
Метод 2:
output_buffering = Off
output_handler =
zlib.output_compression = On
В php.ini (в httpd.conf не работает, только в php.ini):
disable_functions=system,exec,passthru,shell_exec,mysql_pconnect, pgsql_pconnect,
proc_open,proc_close,dl,show_source
Метод 1. Собираем PHP с --enable-force-cgi-redirect, кладем php.cgi в cgi-bin, в httpd.conf:
AddType application/x-httpd-php .php
Action application/x-httpd-php /cgi-bin/php.cgi
Метод 2. Собираем PHP c --enable-discard-path, в начало php скриптов добавляем #!/usr/bin/php
В httpd.conf: AddHandler cgi-script .php
и в параметры директории где php скрипты к Options добавляем ExecCGI.
Пример, выделения слова Reject при просмотре хвоста почтового лога:
tail -f /var/log/maillog |perl -p -e 's/Reject/\033\[46;1mReject\033[0m/gi;'
Если нужно не только выделять цветом, но и подавать звуковой сигнал при появлении test@test.ru:
tail -f /var/log/maillog |perl -p -e 's/(test\@test.ru)/\033\[46;1m$1\033[0m\007/gi;'
- Главное правило - всегда явно проверять все переменные полученные из внешних источников
(cgi-параметры, cookie, переменные окружения, имя файла и путь (при листинге директории по readdir));
- Вырезать спецсимволы в переменных используемых в сис. функциях (open(), system(), ``) и обращениях к sql.
вырезание: s/[^\w\d_\-.]//g или tr/;<>*|?`&$!#{}[]:'\/\n\r\0// для open(), system(), ``.
не забывать про \0 (передают %00, который воспринимается как конец стоки)
Пример: $var="../../etc/passwd|\0"; open(F, "/home/test/$var.txt")
- при открытии файла на чтение в open() всегда указывать "<$file";
- Осторожность при использовании переменной внутри eval() и regex (/\Q$var\E/ иначе можно подставить ?{код}).
- Нельзя проверять числовые параметры через "if ($var > 0)", так как может пройти $var="123;somecode";
use constant TIMEOUT => 1;
eval {
local $SIG{ALRM} = sub { die "timeout during sysread\n"; };
alarm(TIMEOUT);
$read_flag = sysread($filehandle, $c, 1);
alarm(0);
};
perlcc script.pl
Подробнее, man perlcc
Если perlcc выдаст ошибку, что невозможно найти DynaLoader.a,
впишите в начало компилируемого файла "use DynaLoader;".
Метод 2:
В байткод:
perl -MO=Bytecode,-H,-o out_file.bin in_file.pl
В исполняесый файл (с промежуточной генерацией кода на Си)
perl -MO=C,-ofoo.c foo.pl
perl cc_harness -o foo foo.c
или
perl -MO=C,-v,-DcA,-l2048 bar.pl > /dev/null
или
perl -MO=CC,-O2,-ofoo.c foo.pl
perl cc_harness -o foo foo.c
или
perl -MO=CC,-mFoo,-oFoo.c Foo.pm
perl cc_harness -shared -c -o Foo.so Foo.c
Также см. проект PAR (<a href="http://par.perl.org/">http://par.perl.org/</a>).
В связи с участившимися случаями появления web-роботов занимающихся сабмитом форм, рекомендую:
if ( ($ENV{"HTTP_REFERER"} !~ /sitename\.ru/i) ||
($ENV{"HTTP_USER_AGENT"} !~ /(netscape|mozilla|links|lynx|opera|msie|konqueror)/i) ){
die "Несанкционированный запрос !";
}
1. Ограничение на максимально возможное число кук или размер куки, у каждого браузера свой предел (лучше не больше 20).
2. Ошибка в указании (или не указание) времени жизни Cookie.
3. В параметрах указан неправильный domain (например не текущий).
4. Запуск .cgi скрипта не напрямую, а через SSI (из .shtml), соответственно cookie
в заголовке воспринята не будет, выставлять нужно используя JavaScript.
При установки хэдера из cgi (Location,Content-Type, etc) многие пишут
(print "Location: http://test.com\n\n";), но данную запись(\n\n) могут
не понять некоторые системы типа Mac и т.д.
Правильней отправлять хэдер как:
print "Location: http://test.com\r\n\r\n";
Обратите внимание на (\r\n\r\n)
my $a="ttttest"; # Нужно определить 4 подряд идущих символа
if ($a =~ /([a-z])\1{3}/ ){
print "4 совпало.\n";
}
где, \1 - обратная ссылка на совпадение в скобках, {3} - повтор 3 раза.
Задача: выбрать запись с ключем большим или равным искомому, т.е. организовать выборку по промежутку значений:
#!/usr/bin/perl
use strict;
use BerkeleyDB;
use constant DB_DEF_CACHE_SIZE => 5000000;
my %hash;
my $dbobj = tie(%hash, 'BerkeleyDB::Btree',
-Filename => "test.db",
-Cachesize => DB_DEF_CACHE_SIZE,
-Flags => DB_CREATE,
-Compare => sub { $_[0] <=> $_[1] }
) or die "Can't create or open DB File!\n";
# Тестовые значения
$hash{5}="0-5";
$hash{8}="6-8";
$hash{20}="9-20";
$hash{80}="21-80";
my ($key, $val);
my $cursor = $dbobj->db_cursor();
# Выборка.
$key=3;
$cursor->c_get($key, $val, DB_SET_RANGE);
print "3=$val\n";
$key=25;
$cursor->c_get($key, $val, DB_SET_RANGE);
print "25=$val\n";
$key=80;
$cursor->c_get($key, $val, DB_SET_RANGE);
print "80=$val\n";
untie %hash;
use Storable;
Запись/чтение дампа в файл.
store (\%table, 'file'); $hashref = retrieve('file');
lock_store (\%table, 'file'); $hashref = lock_retrieve('file');
Запись/чтение дампа в ранее открытый файл.
store_fd (\%table, \*FILE); $hashref = fd_retrieve(\*FILE);
Запись/чтение дампа в скалярную переменную
(удобно для использования для привязки сложной структуры к ключу в DB_File или BerkeleyDB).
$hash_dump = freeze (\%table); $hash_ref = thaw($hash_dump);
Если нужно получить дамп в символьном "perl sources"-виде для использования в eval или print: use Data::Dumper;
use DB_File;
$db_hashinfo = new DB_File::HASHINFO;
$db_hashinfo->{'cachesize'} = 100000;
$dbobj = tie(%hash, "DB_File", "somefile.db", O_RDWR|O_CREAT, 0644, $db_hashinfo ))||die "Error";
$dbobj->del($key);
$dbobj->sync();
untie %hash;
Для доступа к хранилищам Berkeley DB версии 2,3 и 4 нужно использовать модуль BerkeleyDB.
Сортировка по ключу:
foreach $key (sort keys %hash){ }
Сортировка по данным сопоставленым с ключом:
foreach $key (sort { $hash{$a} cmp $hash{$b} } keys %hash){ }
Если сортировка осуществляется над строковыми данными используем "cmp", если над цифровыми - "<=>".
Для сортировки в обратном порядке пишем "reverse sort".
@array=();
$n = $#array; # это номер последнего индекса, число записей - scalar @array;
Если $n = -1 - то массив пустой, если $n = 0 - в массиве 1 элемент и т.д.
perldoc Devel::DProf
Запускаем программу как perl -d:DProf prog.pl
Затем смотрим в сгенерированный файл tmon.out, или используем специальную программу для его разбора, например dprofpp -T
Иногда нужно узнать на массив, хэш или скаляр указывает ссылка.
ref возвращает строковый идентификатор типа ссылки (SCALAR, ARRAY, HASH, CODE, REF, GLOB, LVALUE)
или пустое значение для обычных переменных. Например:
if (ref($r) eq "HASH") {
print "Хэш\n";
} elsif (ref($r) eq "ARRAY"){
print "Массив\n";
}
Пример хранение дескрипторов в хэше:
my %user_fd = ();
if (! defined $user_fd{$cur_login}){
open($user_fd{$cur_login}, ">$cur_file") or return -1;
}
print {$user_fd{$cur_login}} "TEST\n";
close($user_fd{$cur_login});
Пример передачи дескриптора из функции:
# Для perl 5.6 и старше
open (my $fh, $file_name);
print $fh "Hello World!\n";
process_file( $fh );
open (FILE, "> $filename)";
process_typeglob( *FILE );
process_reference( \*FILE );
sub process_typeglob { local *FH = shift; print FH "Typeglob!" }
sub process_reference { local $fh = shift; print $fh "Reference!" }
my $fh = myopen("file_path");
while (<$fh>) {
....
}
close $fh;
sub myopen {
my $path = shift;
local *FH;
open (FH, $path) || return undef;
return *FH;
}
При работе с большими строками нужно избегать внутреннего копирования строк,
которое происходит при использоании регулярных выражений или оператора split.
Для разбиеная строки вида "small_begin:big_end" на две подстроки используем:
my $pos=index($str, ':');
my $begin_str = substr($str, 0, $pos,"");
# в $str остается только big_end часть, в $begin_str - "small_begin:"
Соответсвенно, для замены символов удобно использовать:
substr(строка, начало замены, число заменяемых символов, блок на который заменяем);
Как-то пришлось столкнуться с обработкой иерархически связанной структуры на perl.
В инете есть куча разрозненной информации по этому поводу.
Можно, например, воспользоваться пакетами с сайта CPAN. Но с одной
стороны
стрелять из пушки по воробьям ... не дело.. а с другой надо чтобы и в мозгах что-то осталось.
Вообщем, задачка решилась и заодно родился вот такой скриптик, не претендующий
на уникальность, тем более, что на perl (как и на других мощных языках) одну и ту же задачу
можно решить многими способами. Хотя, эффективность этих способов - это уже другой вопрос.
Итак, скрипт.
#!/usr/bin/perl
# Рассмотрим принцип работы рекурсивных функций и построения
# связанных структур (в данном случае анонимных хэшей) на
# примере скрипта для иерархического (в виде дерева)
# отображения подкаталогов, содержашихся в заданном каталоге.
#
# Сначала необходимо провернуть некоторые подготовительные
# операции. Например, определиться какой каталог будем печатать.
print "Directory to print [.]: ";
# Считываем каталог и удаляем символ конца строки.
chop (my $d = <>);
# По умолчанию берем текущий каталог.
if (!$d) {$d="."};
# Проверяем, является ли $d каталогом...?
(-d $d) or die "Error: $d isn\'t directory.\n";
# Теперь создаем дерево вложенных хэшей с помощью
# функции MakeTree, которая возвращает указатель
# на корневой хэш.
my $root = MakeTree($d);
# И печатаем. Первый параметр - уровень вложенности
# текущего каталога - $d.
PrintTree(0,$root);
# Рассмотрим подробнее рекурсивные функции MakeTree и PrintTree
sub MakeTree {
# Берем первый параметр - каталог для обработки
my $path_to_dir = shift;
# Инициализируем хэш, в котором будем сохранять
# результат обработки каталога $path_to_dir.
my %branches;
# Читаем содержимое каталога в массив @content.
# Причем выбрасываем из рассмотрения каталоги
# "." (текущий), ".." (уровнем выше) и файлы.
opendir DIR, $path_to_dir;
my @content = grep { !/^\.{1,2}$/
&& !(-f $path_to_dir."/".$_) } readdir DIR;
closedir DIR;
# В итоге в @content содержится список каталогов,
# находящихся в $path_to_dir. Теперь для каждого
foreach my $dir (@content) {
# каталога из этого списка рекурсивно запускаем
# эту же функцию - MakeTree, в аргументе которой
# уже новый путь - путь к каталогу $dir.
$branches{$dir} = MakeTree($path_to_dir."/".$dir);
# В результате в хэш %branches по ключу $dir заносится
# значение, возвращаемое функцией MakeTree. А это значение
}
# ничто иное, как указатель на хэш, поскольку функция
# MakeTree возврашает указатель на хэш %branches, как мы
# видим ниже. Ключи этого хэша - каталоги, содержащиеся
# в $dir, а значения по этим ключам - опять же указатели на
#хэши...и т.д.
return \%branches;
# Но ведь %branches обьявлен с ключевым словом my и ограничен
# областью видимости функции (в данном случае)?!..Это означает,
# что сборщик мусора perl должен уничтожить %branches при
# выходе из функции. Оказывается, нет. Дело в том, что пока для
# переменной (в данном случае - хэш), объявленной с оператором
# my внутри блока { } существует указатель вне этого блока, то
# perl не уничтожает переменную, и мы приходим к понятию
# анонимная переменная (хэш). Т.е. мы обращаемся к переменной
# не $имя_переменной, а через указатель.
}
# Таким образом, в результате создаются ссылающиеся друг
# на друга анонимные хэши, которые существуют до тех пор,
# пока существует указатель $root.
# Печатаем результат.
sub PrintTree {
# Первый параметр - уровень вложенности каталога.
my $level = shift;
# Второй - хэш, содержащий имена каталогов, через указатель.
my %top = %{(shift)};
# Далее для каждого ключа из хэша %top
foreach $key (keys %top) {
# печатаем сам ключ (на самом деле ключ - имя каталога),
# причем с отступом 4*$level.
printf ("%${\(4*$level)}s$key\n","|");
# Необходимо заметить, что в %top по ключу $key содержится
# хэш с именами каталогов, которые тоже было бы неплохо
# распечатать. Поэтому увеличиваем уровень вложенности
$level++;
# и опять вызываем PrintTree.
PrintTree($level,$top{$key});
# После чего надо вернуть уровень вложенности на место.
$level--;
}
}
Для защиты от одновременного запуска нескольких процессов, можно сделать так:
use Fcntl qw(:flock :DEFAULT);
my $cfg_glob_lock="/var/run/myprog/test.pid";
# Проверяем лок.
if (-f $cfg_glob_lock){
# Лок присутствует. Проверяем не дохлый ли процесс.
my $lock_pid = 0;
open(LOCK,"<$cfg_glob_lock");
# Если удалось заблокировать, значит процесс мертв.
my $zombie_lock_flag = flock(LOCK, LOCK_EX|LOCK_NB);
$lock_pid = <LOCK>;
close (LOCK);
chomp ($lock_pid);
if ($lock_pid > 0 && $zombie_lock_flag == 0){
# Реакция на зависший процесс.
die "Proccess locked (pid=$lock_pid)";
} else {
# Лок от мертвого процесса.
unlink("$cfg_glob_lock");
warn("DeadLock detected ($lock_pid)");
}
}
# Записываем pid в новый лок файл.
sysopen(LOCK, $cfg_glob_lock, O_CREAT|O_EXCL|O_WRONLY) or die 'Race condition';
print LOCK "$$\n";
close(LOCK);
# Открываем лок.
open(GLOB_LOCK,"<$cfg_glob_lock");
flock(GLOB_LOCK, LOCK_EX);
.... рабочий код скрипта
# Закрываем и удаляем лок
flock(GLOB_LOCK, LOCK_UN);
close(GLOB_LOCK);
unlink("$cfg_glob_lock");
Преобразование из UTF-8 в KOI8-R:
use Unicode::Map8;
use Unicode::String qw(utf8);
my $koi8 = Unicode::Map8->new("koi8-r");
$koi8_string = $koi8->to8(utf8($utf8_string)->utf16);
Обратное преобразование
use Unicode::Map8;
use Unicode::String qw(utf16);
my $koi8 = Unicode::Map8->new("koi8-r");
$utf8_string = utf16($koi8->to16($koi8_string ))->utf8;
Другой метод:
use Encode;
$koi8_text = from_to($utf8_text, "utf8", "koi8-r");
$utf8_text = from_to($koi8_text, "koi8-r", "utf8");
use Crypt::Blowfish;
use Crypt::CBC;
my $cipher = new Crypt::CBC("Секретный ключ для шифрования",'Blowfish');
my $crypted_block = $cipher->encrypt_hex($text);
my $text = $cipher->decrypt_hex($crypted_block);
$cipher->finish();
Вывести список слов с ошибками:
cat file.txt | ispell -d russian -l
Детальный разбор ошибок с вариантами замены:
echo file.txt | ispell -d russian -a
Для скриптов на perl рекомендую использовать модуль Lingua::Ispell.
sub sys_true_rand {
my ($num_char) = @_; # Число символов в качестве параметра.
my $dev_line;
my $rand_line = "";
open(UR,"</dev/urandom") || die "Cam't open /dev/urandom"";
do {
read (UR, $dev_line, 4096);
$dev_line =~ s/[^\w\d]//g;
$rand_line .= $dev_line;
} until (length($rand_line) >= $num_char);
close(UR);
return substr($rand_line,0, $num_char);
}
Для экранирования спец. символов в строке подставляемой в регуларное
выражение, строку нужно разместить между модификаторами \Q и \E,
при этом все спецсимволы не будут интерпретироваться как операторы рег. выражения.
Например: /\Q$str\E/
Или можно использовать функцию index():
$pos = index($строка, $подстрока);
if ($pos < 0){
# Подстрока не найдена.
} else {
# В $pos - позиция первой совпавшей позиции подстроки.
}
Для рисования русских букв, слов на графиках, построенных модулем perl GD::Graph необходимо все
переменные с русским тексом перевести в кодировку utf8.
Например модулем Unicode::Map8:
my $unicoded_txt = Unicode::Map8->new("cp1251");
Дополнительно нужно указать ttf шрифт, поддерживающий unicode. Например виндовый arial.ttf:
$graph->set_value_font('/usr/share/fonts/arial.ttf', 9);
Опробовано с p5-GD-Graph-1.43 и p5-Unicode-Map8-0.12.
use Image::Magick;
my $image = Image::Magick->new; #новый проект
my $x = $image->Read("photo.jpg"); #открываем файл jpg
$x = $image->Write("photo.png"); #Сохраняем изображение png.
use Image::Magick;
my $image = Image::Magick->new; #новый проект
my $x = $image->Read("photo.jpg"); #открываем файл
$image->Contrast(); #Контрастность
$image->Normalize(); #Нормализуем цвета
$x = $image->Write("photo.jpg"); #Сохраняем изображение.
use Image::Magick;
my $image = Image::Magick->new; #новый проект
my $x = $image->Read("photo.jpg"); #открываем файл
my ($ox,$oy)=$image->Get('base-columns','base-rows'); #определяем ширину и высоту изображения
my $nx=int(($ox/$oy)*150); #вычисляем ширину, если высоту сделать 150
$image->Resize(geometry=>geometry, width=>$nx, height=>150); #Делаем resize (изменения размера)
if($nx > 200) { #Если ширина получилась больше 200
my $nnx = int(($nx-200)/2); #Вычисляем откуда нам резать
$image->Crop(x=>$nnx, y=>0); #Задаем откуда будем резать
$image->Crop('200x150'); #С того места вырезаем 200х150
}
$x = $image->Write("photo.jpg"); #Сохраняем изображение.
use HTML::TokeParser;
my $p = HTML::TokeParser->new("index.html");
if ($p->get_tag("title")){
my $title = $p->get_trimmed_text; # Содержимое <title>
}
while (my $token = $p->get_tag("a")) { # перибираем все <a href>
my $url = $token->[1]{href} || "";
my $text = $p->get_trimmed_text("/a"); # Текст между <a ...> и </a>
}
Из IP в имя:
use Socket;
my $host = gethostbyaddr(inet_aton("192.168.1.1"), AF_INET);
Из хоста в IP:
use Socket;
my $ip = inet_ntoa((gethostbyname("www.test.ru"))[4]);
$ftp = Net::FTP->new("ftp сервер", Timeout => 30, Debug => 0) || die "Can't connect to ftp server.\n";
$ftp->login("логин", "пароль") || die "Can't login to ftp server.\n";
$ftp->cwd("переход в директорию") || die "Path $cfg_remote_path not found on ftp server.\n";
$ftp->binary();
$size = $ftp->size("файл для которого нужно узнать размер");
$time = $ftp->mdtm("файл для которого нужно узнать время изменения");
$ftp->delete("директория для удаления");
$ftp->mkdir("директория для создания");
$ftp->rename("старое имя для переименования","новое имя");
$ftp->put("имя файла на локальном диске для закачки", "имя файла на ftp");
$ftp->put(*FD, "имя файла на ftp"); # Все что идет в FD будет сохранено.
$ftp->get("удаленный файл", "локальный файл");
$ftp->quit();
$find_net = '123.123.45.4/30';
$some_ip = '123.123.45.5';
my ($net_ip, $net_mask) = split(/\//, $find_net);
my ($ip1, $ip2, $ip3, $ip4) = split(/\./, $find_net);
my $net_ip_raw = pack ('CCCC', $ip1, $ip2, $ip3, $ip4);
my $net_mask_raw = pack ('B32', (1 x $net_mask), (1 x (32 - $net_mask)));
# $some_ip_raw вычисляем по аналогии с $net_ip_raw
if (($some_ip_raw & $net_mask_raw) eq $net_ip_raw){
# $some_ip_raw входит в подсеть $find_net
}
При указании маски вида $find_net = '123.123.45.4/255.255.255.224'
вместо pack можно преобразовать IP и маску в число по алгоритму:
$net_ip_raw = ($ip1<<24) + ($ip2<<16) + ($ip3<<8) + $ip4;
Тоже проделать с маской и проверяемым IP, вхождение в подсеть будет проверяться условием:
if ($some_ip_raw & $net_mask_raw) == $net_ip_raw){
# $some_ip_raw входит в подсеть $find_net
}
Другой вариант:
use Socket;
sub isinsubnet {
my ($subnethost, $subnetmask, $testhost) = @_;
$subnethost = inet_aton($subnethost);
$subnetmask = inet_aton($subnetmask);
$testhost = inet_aton($testhost);
return (($subnethost & $subnetmask) eq ($testhost & $subnetmask));
}
Пример хранение дескрипторов в хэше:
my %user_fd = ();
if (! defined $user_fd{$cur_login}){
open($user_fd{$cur_login}, ">$cur_file") or return -1;
}
print {$user_fd{$cur_login}} "TEST\n";
close($user_fd{$cur_login});
Пример передачи дескриптора из функции:
# Для perl 5.6 и старше
open (my $fh, $file_name);
print $fh "Hello World!\n";
process_file( $fh );
open (FILE, "> $filename)";
process_typeglob( *FILE );
process_reference( \*FILE );
sub process_typeglob { local *FH = shift; print FH "Typeglob!" }
sub process_reference { local $fh = shift; print $fh "Reference!" }
my $fh = myopen("file_path");
while (<$fh>) {
....
}
close $fh;
sub myopen {
my $path = shift;
local *FH;
open (FH, $path) || return undef;
return *FH;
}
use File::Find;
sub get_file{
my ($file_name) = $_;
my $file_fullpath = $File::Find::name;
my $file_dir = $File::Find::dir;
}
find (\&get_file, "/usr/some/dir");
use MIME::Base64 qw(encode_base64);
my $sendmail = '/usr/sbin/sendmail';
my $to = 'linux@domain1.ru';
my $from = 'my@domain2.ru';
my $attachment = '/path_to/file.tar.gz';
my $buf;
my $subject = MIME::Base64::encode_base64('Здесь размещаем тему письма.');
$subject =~ s/\n//g;
my $data;
$data = MIME::Base64::encode_base64("<p>Здесь<br>Можно разместить текст сообщения.<br></p>");
my $boundary = 'simple boundary';
open(MAIL, "| $sendmail -t -oi") or die("$!");
print MAIL <<EOF;
To: $email_to
From: $email_from
Subject: =?UTF-8?B?$subject?=
Content-Type: multipart/mixed; boundary="$boundary"
This is a multi-part message in MIME format.
--$boundary
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64
$data
--$boundary
Content-Type: application/octet-stream; name="$attachment"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="$attachment"
EOF
open(FILE, "<$attachment") or die "$!";
while (read(FILE, $buf, 60*57)) { print MAIL encode_base64($buf); }
close FILE;
close MAIL;
my $dofw = (localtime())[6];
my $time = time();
my $inday = 86400;
Начало недели $time - $inday * $dofw или localtime($time - $inday * $dofw)
Конец недели $time + $inday * (6 - $dofw) или localtime($time + $inday * (6 - $dofw))
perldoc Time::Local;
$time = timelocal($sec,$min,$hours,$mday,$mon,$year);
С помощью Time::Local можно посчитать число секунд, дней, месяцев и т.д. относительно какой-либо даты.
Если в скрипте используется свой обработчик $SIG{__DIE__}, то он отработает и для die() внутри eval блока.
Чтобы этого не произошло, нужно вначале eval блока переключиться на старый обработчик:
eval { local $SIG{__DIE__} = 'DEFAULT';
local $SIG{__ALRM__} = sub { die 'timeout!' };
alarm(1);
....
};
Простейший вариант, проверка $^S, устанавливается в 1 при вызове из eval блока:
local $SIG{'__DIE__'} = sub {
die @_ if $^S;
.....
}
Усложненный вариант:
sub _evalling { # Определение типа текущей подпрограммы
my $i = 0; my $sub;
while (defined($sub = (caller($i++))[3])){
if ($sub =~ /^\(eval( \d+)?\)$/){
return 1;
}
}
return 0;
}
$::SIG{'__DIE__'} = sub { # Перехват die()
&{$self->{callback}}(@_ ? @_ : $@) unless _evalling;
die @_;
};
print join("\n",&get_sub_list);
sub go{}
sub test1{}
package sublist;
sub main::get_sub_list{
no warnings;
my ($code,@fn);
foreach (keys(%main::)){
next unless /^[\w_]/;
push(@fn,$_) if eval("defined(*main::$_"."{CODE})");
}
use warnings;
@fn
}
sub my_die{
.....
}
local ($SIG{__DIE__}) = \&my_die;
local ($SIG{__WARN__}) = \&my_warn;
local ($SIG{INT}) = \&my_kill;
local ($SIG{TERM}) = \&my_kill;
die "test";
MySQL:
Посмотреть список глобального и локального часового пояса:
SHOW VARIABLES LIKE '%time_zone%';
Конвертация в запросе времени из одной временной зоны в другую:
SELECT CONVERT_TZ('2008-10-24 5:00:00','UTC','MSK');
Изменить текущую зону для локального соединения:
SET time_zone = 'MSK'
или
SET time_zone = '+03:00';
Для всего MySQL сервера часовой пояс можно поменять установив в файле конфигурации:
default-time-zone='MSK'
или под привилегированным пользователем выполнить запрос:
SET GLOBAL time_zone ='MSK'
PostgreSQL:
Для текущей сессии зона задается через:
SET TIME ZONE 'MSK'
или
SET TIME ZONE '-3'
Для клиентов использующих libpq часовой пояс может быть определен в переменной окружения PGTZ.
Если часовой пояс для всей СУБД не определен (параметр timezone) в postgresql.conf, он берется из
стандартной переменной окружения TZ
в shell:
export TZ=GMT-3
в perl:
$ENV{"TZ"}="GMT-3";
в PHP:
putenv("TZ=GMT-3");
На официальном сайте Oracle присутствует небольшое руководство по установке в Solaris
без использования графического интерфейса, при этом оно сводится к тому,
что нужно запустить скрипт под графическим интерфейсом с дополнительными параметрами.
/directory_path/runInstaller -record -destinationFile response_filename
В итоге получаем файл, который может быть использован при установке,
но установка графического интерфейса была не приемлема,
поэтому пришлось разбираться самому с файлом ответов.
Для установки нужно скачать клиента с оф. сайта Oracle.
скачать можно по адресу:
http://download-llnw.oracle.com/otn/solaris/oracle10g/10201/sol64/10gr2_client_sol.cpio.gz
создайте пользователя и группу для клиента
например:
useradd oracle
groupadd oracle
usermod -g oracle oracle
passwd oracle
Создайте папку распакуйте полученный архив в эту папку и дайте команду
chown -R oracle:oracle /directory_path/
Теперь нужно править или создать свой фаил ответов
версию можем не трогать
RESPONSEFILE_VERSION=2.2.1.0.0
имя группы которую создали для оракла
UNIX_GROUP_NAME="oracle"
если вы брали стандартый дистрибутив с сайта менять не надо
FROM_LOCATION="../stage/products.xml"
имя и путь к следующему фаилу ответов
NEXT_SESSION_RESPONSE=""
Куда устанавливаем
ORACLE_HOME="/export/home/oracle/client"
ORACLE_HOME_NAME="OraClient"
эти значения нужно оставить по молчанию. Беруться из примеров файлов ответов в дистрибутиве
TOPLEVEL_COMPONENT={"oracle.client","10.2.0.1.0"}
DEINSTALL_LIST={"oracle.client","10.2.0.1.0"}
т.к. у нас тихая инсталяция а эти параметры требуют графический интерфейс скидываем их все в false
SHOW_SPLASH_SCREEN=false
SHOW_WELCOME_PAGE=false
SHOW_CUSTOM_TREE_PAGE=false
SHOW_SUMMARY_PAGE=false
SHOW_INSTALL_PROGRESS_PAGE=false
SHOW_CONFIG_TOOL_PAGE=false
SHOW_XML_PREREQ_PAGE=false
SHOW_ROOTSH_CONFIRMATION=true
SHOW_END_SESSION_PAGE=false
SHOW_EXIT_CONFIRMATION=false
SHOW_DEINSTALL_CONFIRMATION=false
SHOW_DEINSTALL_PROGRESS=false
следующая сессия нам не нужна поэтому скидываем параметры в false
NEXT_SESSION=false
NEXT_SESSION_ON_FAIL=false
CLUSTER_NODES={}
какую папку удалить после установки
REMOVE_HOMES=""
выбор поддержки языка
COMPONENT_LANGUAGES={"en"}
тип исталяции
INSTALL_TYPE="Administrator"
если используется тип инсталяции Custom нужно добавить еще один параметр,
где перечисляются нужные компоненты
DEPENDENCY_LIST={"oracle.sqlj:10.2.0.1.0","oracle.rdbms.util:10.2.0.1.0",
"oracle.javavm.client:10.2.0.1.0","oracle.sqlplus:10.2.0.1.0",
"oracle.dbjava.jdbc:10.2.0.1.0","oracle.ldap.client:10.2.0.1.0",
"oracle.rdbms.oci:10.2.0.1.0","oracle.precomp:10.2.0.1.0","oracle.xdk:10.2.0.1.0",
"oracle.swd.opatch:10.2.0.1.0","oracle.network.aso:10.2.0.1.0","oracle.oem.client:10.2.0.1.0",
"oracle.oraolap.mgmt:10.2.0.1.0","oracle.network.client:10.2.0.1.0","oracle.ordim.client:10.2.0.1.0",
"oracle.ons:10.1.0.3.0","oracle.has.client:10.2.0.1.0"}
после того как готов файл, залогиниваемся под пользователем клиента и запускаем команду
/directory_path/runInstaller -silent -responseFile responsefilename
снова перелогиниваемся под рутом и запускаем скрипт root.sh, который лежит в папке с установленным клиентом
Установка прошла успешно
А дальше пользуемся готовыми статьями по настройке подключений.
P.S. возможны проблемы, когда некоторые фалы копируются битыми, просто перезапустите скрипт утановки.
Задача: выбрать запись с ключем большим или равным искомому, т.е. организовать выборку по промежутку значений:
#!/usr/bin/perl
use strict;
use BerkeleyDB;
use constant DB_DEF_CACHE_SIZE => 5000000;
my %hash;
my $dbobj = tie(%hash, 'BerkeleyDB::Btree',
-Filename => "test.db",
-Cachesize => DB_DEF_CACHE_SIZE,
-Flags => DB_CREATE,
-Compare => sub { $_[0] <=> $_[1] }
) or die "Can't create or open DB File!\n";
# Тестовые значения
$hash{5}="0-5";
$hash{8}="6-8";
$hash{20}="9-20";
$hash{80}="21-80";
my ($key, $val);
my $cursor = $dbobj->db_cursor();
# Выборка.
$key=3;
$cursor->c_get($key, $val, DB_SET_RANGE);
print "3=$val\n";
$key=25;
$cursor->c_get($key, $val, DB_SET_RANGE);
print "25=$val\n";
$key=80;
$cursor->c_get($key, $val, DB_SET_RANGE);
print "80=$val\n";
untie %hash;
Для MySQL есть утилита myisampack или самое простое, своими силами данные,
перед помещением в базу, сжимать и разжимать (функции COMPRESS() и UNCOMPRESS()).
В PostgreSQL для хранения текстовой информации в сжатом виде предусмотрен тип данных "lztext".
Можно сжатие данных возложить на плечи файловой системы, для linux и freebsd
есть возможности для прозрачного сжатия.
Berkeley DB позволяет эффективно организовать хранилище пар вида ключ/значение.
Типы хранилища:
Hash - хэш, выборка по точному значению
Btree - сбалансированное дерево, выборка по точному значению или >=.
Recno - для хранения индексированных массивов.
Queue - оптимизировано для очередей, где чаще всего запрашивают элементы верхушки или низа.
В версиях от 2 и выше, поддерживаются средства одновременного апдейта базы, локов,
транзакций, "курсоров", восстановления поврежденного хранилища.
Есть два сервера под Linux/FreeBSD: СУБД MySQL + некое приложение,
задача - синхронизировать БД и данные.
За синхронизацию данных MySQL отвечает mysql replication, данные синхронизируются с мастера на слейв.
Делаем на мастере:
в my.cnf добавляем строки
log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db=databasename
server-id=1
перезагружаем MySQL, добавляем пользователя для репликации:
GRANT ALL PRIVILEGES ON databasename.* TO 'slave_user'@'%' IDENTIFIED BY 'slave_password';
FLUSH PRIVILEGES;
далее выполняем команду:
USE databasename;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
и вывод этой команды для нас важен, надо его куда-нибудь записать:
| File | Position | Binlog_do_db | Binlog_ignore_db |
| mysql-bin.001 | 10 | databasename | |
теперь делаем дамп базы:
mysqldump -u slave_user -pslave_password --opt databasename > databasename.dump
и наконец убираем лок с базы в MySQL:
UNLOCK TABLES;
Теперь на слейве:
Создаём базу:
mysqladmin create databasename -p
Востанавливаем базу из дампа:
mysql -u slave_user -pslave_password databasename < databasename.dump
в my.cnf добавляем строки:
server-id=2
master-host=XX.XX.XX.XX # IP адрес мастер-сервера
master-user=slave_user
master-password=slave_password
master-connect-retry=60
replicate-do-db=databasename
перегружаем MySQL и добавляем чудесные данные из волшебной комманды:
SLAVE STOP;
CHANGE MASTER TO MASTER_HOST='XX.XX.XX.XX',
MASTER_USER='slave_user', MASTER_PASSWORD='slave_password',
MASTER_LOG_FILE='mysql-bin.001', MASTER_LOG_POS=10;
START SLAVE;
готово, теперь проверяем, добавляем запись в мастер, на слейве она должны отреплицироваться.
Понятно, что изменять данные можно только на мастере, слейв работает только на чтение.
Для синхронизации данных имеет смысл использовать rsync, очень интересный протокол/приложение.
Может синхронизировать инкрементально и с сжатием.
На мастер сервере в rsyncd.conf добавляем:
read only = yes # во избежание ;-)
hosts allow = YY.YY.YY.YY # IP адрес слэйв-сервера
[somelabel]
path = /path/to/apllication/folder # где лежит приложение
auth users = replica_user # юзер только для репликации в rsync, не системный пользователь
secrets file = /path/to/rsync/rsync.secret # где лежит файл с паролем для replica_user,
# только пароль и ничего больше
на слейве - команда для синхронизации, можно добавить в cron с нужной периодичностью:
/path/to/rsync -avz --exclude-from=/path/to/rsync.exclude \
--password-file /path/to/rsync.secret \
rsync://replica_user@XX.XX.XX.XX:873/somelabel /path/to/application
где:
rsync.exclude - файл в котором перечислены, какие файлы (конкретно или по маске) не синхронизировать
rsync.secret - файл с секретным паролем для replica_user
ХХ.ХХ.ХХ.ХХ - IP мастер-сервера, 873 - дефолтный порт для демона
somelabel - метка из rsyncd.conf с мастера
/path/to/application - путь куда класть данные.
Наверняка, каждый сталкивался с задачей переноса лог-файлов из текстовых файлов в различные БД.
И, наверняка, каждый столкнувшийся начинал писать собственные скрипты под это дело.
Причем большинство виденных мной скриптов основывались на построчном чтении/переносе данных.
Данный способ, конечно, хорош и имеет право на существование, но, к сожалению не очень быстр.
Но в MySQL существует способ перенести данные из обычных текстовых файлов в БД
очень и очень быстро при помощи директивы LOAD DATA INFILE
Пример такого скрипта:
#!/bin/bash
nld='/var/log/squid3' # Путь к лог-файлам
nbd='/opt/backup/squid3' # Путь к папке резервного хранения лог-файлов
nrc=`squid3 -k rotate` # Команда ротации лог-файлов для данного сервиса
nlf='/var/log/logs2mysql/squid.log' # На всякий случай пишем что и когда делали
mh='localhost' # Mysql host
mu='root' # Пользователь mysql
mp='secret' # Его пароль
mb='logs' # База данных
mt='squid' # Таблица
echo `date +"%F %T"` "Начало выгрузки" >> $nlf && \
$nrc && \
for i in `ls $nld | grep access.log.`;
do
year=`date +"%Y"`
month=`date +"%m"`
day=`date +"%d"`
prefix=`date +"%F-%H"`
test -d $nbd/$year/$month/$day || mkdir -p $nbd/$year/$month/$day && \
cat $nld/$i | sed -e 's/\"/\\\"/g' | sed -e "s/\'/\\\'/g" | \
awk ' {print strftime("%F",$1),strftime("%T",$1),$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11} ' | \
sed -e "s/ /\t/g" > $nld/prepare.log && \
chmod 0777 $nld/prepare.log && \
mysql -h $mh -u $mu -p$mp -e "LOAD DATA INFILE \"$nld/prepare.log\" REPLACE INTO TABLE $mb.$mt;" && \
cat $nld/$i >> $nbd/$year/$month/$day/$prefix.log && rm $nld/$i && rm $nld/prepare.log
done
echo `date +"%F %T"` "Конец выгрузки" >> $nlf
Поля для таблицы ('Поле'-тип)
'date'-date
'time'-time
'timestamp'-varchar(16)(разные сервисы пишут по разному.Кто-то с милисекундами, кто-то без)
'elapsed'-int(20)
'ip'-varchar(15)
'code'-varchar(20)
'size'-int(20)
'method'-varchar(10)
'url'-varchar(255)
'user'-varchar(255)
'direct'-varchar(25)
'mime'-varchar(25)
'hash'-varchar(255)unique
C небольшими изменениями данный скрипт можно приспособить для обработки
лог-файлов не только squid, но и других сервисов. Необходимое условие:
четкое разграничение полей (можно, поиграться с указанием разграничителей полей
в директиве LOAD DATA INFILE).
К преимуществам данного скрипта можно отнести огромное быстродействие
(п4-3,2 1024Мб ОЗУ 4млн. строк за 10-12 сек.).Также по последнему полю "hash" мы можем уникальным
образом идентифицировать строку (при анализе логов за год по squid и net-acct я не обнаружил
одинаковых строк).А также гарантированное попадание всех строк в БД
(т.к. данные не удаляются при сбое mysql).
Столкнулся с тем, что система отказалась проапгрейдиться посредством apt,
так как не удается завершить демон mysql.
Оказалось, что запуск и остановку демона делает пользователь базы данных debian-sys-maint.
Пароль у него был заменен на что-то уже неизвестное, поэтому неоходимо было найти debian-way.
В файле /etc/mysql/debian.cnf находится какой-то страшный набор символов.
Корректируем его, если есть желание, далее меняем пароль в базе.
Например, так:
# killall mysqld
# mysqld_safe --skip-grant-table
^Z
# bg
# mysql -u root
> UPDATE mysql.user SET Password = PASSWORD( 'новый пароль' )
WHERE user.Host = 'localhost'
AND user.User = 'debian-sys-maint';
> exit
# fg
^C
# /etc/init.d/mysql start
Теперь демон легко стартует, завершается, перезапускается.
Автоматическое обновление системы снова может беречь мой сон.
При дампе больших (10 Gb) InnoDB таблиц в MySQL через mysqldump
на время операции таблица оказывается заблокированной.
Для того чтобы избежать блокировки и нарушения целостности нужно использовать ключ --single-transaction:
mysqldump --single-transaction --quick very_large_db > bakup_of_db.sql
Пример1:
password='Your_MySQL_Password'
MYSQL_RESULT=`mysql -e "SELECT tables_col FROM table_name" --
password="$password" database_name|grep -v tables_col|xargs|sed "s/ /\n/g"`
for i in $MYSQL_RESULT; do
echo $i
done;
Пример2:
mysql -sse "SELECT col FROM table" -p"$password" database | while read i
do
echo $i
done
Комментарий 1: Пароль лучше передавать через переменную окружения MYSQL_PWD, чтобы он не светился в выводе ps.
Комментарий 2 (от myhand):
Другой вариант передача пароля через локальный файл конфигурации .my.cnf, размещенный в корне домашней директории пользователя:
Пример .my.cnf:
[client]
user = имя_пользователя
password = пароль
host = хост_БД
[mysql]
database = имя_бд
CREATE TABLE table (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
column TEXT,
FULLTEXT (column)
);
SELECT * FROM table WHERE MATCH (column) AGAINST ('информация');
AGAINST ('форма содержание') - все выражения, содержащие хотя бы одно из слов.
AGAINST ('+форма +содержание') - оба слова.
AGAINST ('+форма содержание') - искать "форма", при "содержание" больший релевант.
AGAINST ('+форма -содержание') - "форма" без "содержание".
AGAINST ('форма*') - "форма", "формат", "формация"
AGAINST ('"форма или содержание"') - жестко по фразе
MySQL должен быть собран с ключами:
./configure --with-charset=koi8_ru --with-extra-charsets=all
Далее, сразу после каждого соединения с базой нужно использовать оператор:
SET CHARACTER SET cp1251_koi8
Если данные в cp1251 уже в базе, их нужно поместить в базу вновь.
параметры limit действуют с точностью до наоборот.
первый параметр с какой записи, а второй сколько.
По крайней мере для mysql.
MC: Интересно, для PostgreSQL: "LIMIT { count | ALL } [ { OFFSET | , } start ]]"
MySQLTuner (http://rackerhacker.com/mysqltuner/) представляет собой Perl скрипт,
анализирующий статистику работы MySQL сервера и на ее основе дающий рекомендации по оптимизации настойки СУБД.
Загружаем и выполняем скрипт:
wget http://mysqltuner.com/mysqltuner.pl
chmod +x mysqltuner.pl
./mysqltuner.pl
Вводим логин и пароль для подключения к MySQL, после чего скрипт выводит наиболее интересные
параметры статистики работы СУБД и рекомендации по тюнингу настроек, примерно в таком виде:
General recommendations:
Add skip-innodb to MySQL configuration to disable InnoDB
Add skip-isam to MySQL configuration to disable ISAM
Run OPTIMIZE TABLE to defragment tables for better performance
Enable the slow query log to troubleshoot bad queries
When making adjustments, make tmp_table_size/max_heap_table_size equal
Reduce your SELECT DISTINCT queries without LIMIT clauses
Increase table_cache gradually to avoid file descriptor limits
Your applications are not closing MySQL connections properly
Variables to adjust:
query_cache_size (> 16M)
tmp_table_size (> 32M)
max_heap_table_size (> 16M)
table_cache (> 64)
Иногда возникает необходимость догнать мастер несмотря на конфликтные запросы из relay-лога.
Вместо того чтобы, для разрешения конфликтов, вручную выполнять 2 команды
можно в крайних ситуациях использовать скрипт:
#!/bin/sh
n=1
until [ $n = "0" ];do
n=`mysql -Be 'show slave status \G' | grep Seconds_Behind_Master| cut -f2 -d: | tr -d " "`
echo $n;
if [ $n = "NULL" ]; then
mysql -Be ' SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; start slave;'
fi;
sleep 1
done
Для быстрой и полной синхронизации небольшой таблицы:
(http://www.mysqlperformanceblog.com/2008/06/29/resyncing-table-on-mysql-slave/)
LOCK TABLE tbl WRITE;
SELECT * FROM table INTO OUTFILE '/tmp/tbl.txt';
DELETE FROM tbl;
LOAD DATA INFILE 'tmp/tbl.txt' INTO TABLE tbl;
UNLOCK TABLES;
Другой вариант:
RENAME TABLE rep TO rep_maint;
SELECT * FROM rep_maint INTO OUTFILE '/tmp/rep.txt';
CREATE TABLE rep_new LIKE rep_maint;
LOAD DATA INFILE '/tmp/rep.txt' INTO TABLE rep_new;
RENAME TABLE rep_maint TO rep_old, rep_new TO rep;
Для восстановления случайно удаленной таблицы можно использовать для резервного копирования пакет
Zmanda Recovery Manager (http://mysqlbackup.zmanda.com/), имеющий поддержку восстановления
недостающей в бэкапе информации из бинарного лога изменений (MySQL binary log).
Ведение лога транзакций включается в секции "[mysqld]" файла конфигурации:
log-bin = /var/log/mysql/bin.log
Определяем время удаления (DROP TABLE):
mysql-zrm --action parse-binlogs --source-directory=/var/lib/mysql /sugarcrm/20060915101613
/var/lib/mysql/my-bin.000015 | 11013 | 06-09-12 06:20:03 | Xid = 4413 | COMMIT;
/var/lib/mysql/my-bin.000015 | 11159 | 06-09-12 06:20:03 | Query | DROP TABLE IF EXISTS `accounts`;
Имея инкрементальный бэкап binary log от 15 сентября, восстанавливаем из него данные, пропуская удаление таблицы:
# mysql-zrm --action restore --backup-set sugarcrm \
--source-directory=/var/lib/mysql/ sugarcrm/20060915101613/ \
--stop-position 11014
# mysql-zrm --action restore --backup-set sugarcrm \
--source-directory=/var/lib/mysql/ sugarcrm/20060915101613/ \
--start-position 11160
Для получения данных из binary log также можно использовать стандартную программу mysqlbinlog.
Предположим, что у нас есть бэкап от 5 мая.
Переводим сервер в изолированный режим работы:
mysqld --socket=/tmp/mysql_restore.sock --skip-networking
Восстанавливаем данные из бэкапа:
cat /backup/20080505.sql | mysql --socket=/tmp/mysql_restore.sock
Делаем дамп данных из бинарного лога:
mysqlbinlog /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
Можно использовать выборку по дате или номеру позиции:
mysqlbinlog --stop-date="2008-05-06 9:59:59" --start-date="2008-05-05 10:01:00" \
/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
mysqlbinlog --stop-position="5647324" --start-position="5634521" \
/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
Вручную удаляем лишнее и загружаем недостающие данные:
cat /tmp/mysql_restore.sql| mysql --socket=/tmp/mysql_restore.sock
Иногда возникают ситуации требующие предварительной проверки корректности
файла конфигурации MySQL, что-то похожее на "configtest" в apache.
Анализ файла конфигурации на наличие синтаксических ошибок производится при выполнении
mysqld --help
innodb_buffer_pool_size - чем больше, тем лучне, например 70-80% от размера ОЗУ,
но нет смысла устанавливать значение превышающее размер базы более чем на 10%.
По идее нужно экспериментально вычислить сколько требуется памяти для системы,
и отдать остальное под буферизацию с небольшим запасом, чтобы не допустить своппинг.
innodb_log_file_size - зависит от требований к скорости восстановления после сбоя,
256Мб - хороший баланс между скоростью восстановления и производительностью системы;
innodb_log_buffer_size=4M, 4Мб подходит для большинства ситуаций,
за исключением случая работы с большими блоками данных, хранимых в Innodb таблицах;
innodb_flush_logs_at_trx_commit=2 - если не важен ACID и после краха системы
допустимо потерять транзакции за последние 1-2 секунды;
innodb_thread_concurrency=8, значение по умолчанию вполне адекватно,
можно попробовать уменьшить или увеличить и посмотреть на изменение производительности.
innodb_flush_method=O_DIRECT - исключает двойную буферизацию и уменьшает воздействие
на файл подкачки. Но следует соблюдать осторожность, если ваш RAID без аварийной батарейки.
innodb_file_per_table - можно использовать, если число таблиц невелико.
При разработке приложения можно обратить внимание на использование режиме READ-COMMITED (transaction-isolation=READ-COMITTED).
mysqldump лочит таблицы на запись и во время дампа база фактически простаивает.
Решения:
1. Репликация и бэкап со слейва;
2. mysqlhotcopy, делает "read lock" на и копируются файлы баз, т.е.:
FLUSH TABLES WITH READ LOCK;
// копировать файлы MyISAM таблиц
UNLOCK TABLES;
FLUSH TABLES WITH READ LOCK может занять много времени т.к. он будет ждать окончания выполнений всех запущенных запросов.
3. Минимизация блокировки через использование снапшотов ФС:
FLUSH TABLES WITH READ LOCK;
Делаем снэпшот ФС, где лежат базы мускула
UNLOCK TABLES;
Копируем директории с базой или отдельные таблицы
Отцепляем снэпшот
Скрипт для Linux (использует LVM снапшот): http://lenz.homelinux.org/mylvmbackup/
Cкрипт для FreeBSD:
(echo "FLUSH TABLES WITH READ LOCK;"; echo "\! ${MOUNT} -u -o snapshot /${SNAPPART}/.snap/backup /${SNAPPART}"; echo "UNLOCK TABLES;" ) |
${MYSQL} --user=root --password=`${CAT} ${MYSQLROOTPW}`
в [mysqld] секции my.cnf:
# Минимальное время запроса, которое не будет помещено в лог.
long_query_time=10
# Файл в котором будут отображаться слишком долгие запросы.
# можно использовать опцию -mysqld -log-slow-queries=file
log-slow-queries=/var/log/mysqld/slowquery.log
Для ведения полного лога всех запросов, нужно использовать опцию mysqld --log=allquery.log
В debian/testing (и наверное не только) mysqld собран с default charset latin1,
что приводит к потере данных при загрузке дампов в utf8 независимо от настроек конкретной базы.
Лекарство:
в разделе [mysqld] в /etc/mysql/my.cnf
character_set_server = utf8
collation_server = utf8_general_ci
Вариант 2:
Если база данных в utf8 и в дампе с ней нет SET NAMES utf8; делаю так
cat mysql_dump.sql | mysql -u user -p dbname --default-character-set=utf8
Шаг 1. Устанавливаем MySQL на два сервера:
Master 1/Slave 2 ip: 192.168.16.4
Master 2/Slave 1 ip : 192.168.16.5
Шаг 2. Содержимое my.cnf сервера Master 1, являющегося верущим по умолчанию:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
old_passwords=1
log-bin
binlog-do-db=<database name> # input the database which should be replicated
binlog-ignore-db=mysql # input the database that should be ignored for replication
binlog-ignore-db=test
server-id=1
[mysql.server]
user=mysql
basedir=/var/lib
[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
Шаг 3. На сервере Master 1, создаем аккакнт для slave сервера (затем перезапускаем mysql):
mysql> grant replication slave on *.* to 'replication'@192.168.10.5 \
identified by 'slave';
Шаг 4. Содержимое my.cnf сервера Master 2, являющегося ведомым по умолчанию (slave):
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
old_passwords=1
server-id=2
master-host = 192.168.16.4
master-user = replication
master-password = slave
master-port = 3306
[mysql.server]
user=mysql
basedir=/var/lib
[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
Шаг 5. Активируем ведомый сервер:
mysql> start slave;
mysql> show slave status\G;
В отображенных параметрах поля Slave_IO_Running и Slave_SQL_Running должны содержать "YES".
Шаг 6. На сервере Master 1 проверяем статус бинарного лога:
mysql> show master status;
+------------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------------+----------+--------------+------------------+
|MysqlMYSQL01-bin.000008 | 410 | adam | |
+------------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
Сценарий master-slave реализован, переходим к настройке master-master.
Шаг 7. На сервере Master2/Slave 1 редактируем my.cnf:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1
server-id=2
master-host = 192.168.16.4
master-user = replication
master-password = slave
master-port = 3306
log-bin #information for becoming master added
binlog-do-db=adam
[mysql.server]
user=mysql
basedir=/var/lib
[mysqld_safe]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
Шаг 8. Создаем slave аккаунт на Master 2 для Master 1:
mysql> grant replication slave on *.* to 'replication'@192.168.16.4 identified by 'slave2';
Шаг 9. Редактируем my.cnf на сервере Master 1, определив, что он является slave для Master 2:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1
log-bin
binlog-do-db=adam
binlog-ignore-db=mysql
binlog-ignore-db=test
server-id=1
#information for becoming slave.
master-host = 192.168.16.5
master-user = replication
master-password = slave2
master-port = 3306
[mysql.server]user=mysqlbasedir=/var/lib
Шаг 10. Перезапускаем оба MySQL сервера. Для Master 1 выполняем
mysql> start slave;
Для Master 2:
mysql > show master status;
Для Master 1:
mysql> show slave status\G;
В отображенных параметрах поля Slave_IO_Running и Slave_SQL_Running должны содержать "YES".
Останавливаем MySQL:
/etc/init.d/mysql stop
Запускаем в режиме без проверки прав доступа:
/usr/bin/mysqld_safe --skip-grant-tables &
Соединяемся как root без пароля:
mysql --user=root mysql
Обновляем пароль:
mysql> update user set Password=PASSWORD('новый пароль') WHERE User='root';
mysql> flush privileges;
Завершаем работу mysqld_safe:
fg
"Ctrl+c"
Запускаем MySQL в обычном режиме.
/etc/init.d/mysql start
#!/bin/sh
#
# mysql-after-setup
# Copyright (c) 2006 Alexey Tsvetnov, vorakl@fbsd.kiev.ua
# Version: 1.4
#
# Run script after install MySQL to do:
# 1. Drop database 'test'
# 2. Set MySQL root password
# 3. Delete all users and access except root@localhost
#
# tty echo off
stty -echo
# enter correct password
while true
do
echo -n "Enter password: " && read pass1 && echo
echo -n "Re-enter password: " && read pass2 && echo
[ "${pass1}" = "${pass2}" ] && break
echo " *** Error!"
done
# tty echo on
stty echo
echo "drop database test; delete from db where db like '%test%';\
update user set password=PASSWORD('$pass1') where user='root' and host='localhost';\
delete from user where password='';\
flush privileges;" | mysql -h 127.0.0.1 -u root mysql && echo "Done successfuly."
exit 0
Каждую базу MySQL хранит в отдельном каталоге внутри datadir.
MySQL работает под своим пользователем и соответственно создает файлы баз под им же. Соответственно квотирование в данном случае не возможно. Необходимо заставить его создавать файлы баз, влaдельцем которых будет конкретный квотируемый пользователь. Сделать это можно выставив бит SUID (4000) на каталог базы.
Для начала:
в ядре:
options SUIDDIR
в /etc/fstab:
добавляем в список опций suiddir
В MySQL создаем базу. Находим каталог базы в datadir. По умолчанию он будет mysql:mysql.
Меняем владельца:
chown sql-user databasedir
теперь наш каталог sql-user:mysql
Меняем права:
chmod 4070 databasedir
Такая настройка заставит систему создавать файлы от имени владельца каталога (sql-user) причем сам пользователь не будет иметь к нему доступа. К нему будет иметь полный доступ MySQL (от группы mysql).
Теперь мы можем использовать квоты как для обычных файлов.
При превышении квот MySQL будет генерить ошибку full disk что является нормальным явлением и корректно отрабатывается MySQL, хотя сопровождается некоторыми проблемами: при запросе на добавление в базу, превысившую квоты, запрос повисает, повисают также последующие запросы, которые можно снять только их убийством или освобождением дополнительного места на диске. При дефолтных настройках это сразу вызовет проблему, так как такие запросы займут все сетевые соединения. Поэтому необходимо ОБЯЗАТЕЛЬНО
ограничить максимальное количество подключений одного пользователя MySQL. В /etc/my.cnf:
max_connections = 500 (всего коннектов)
max_user_connections = 30 (максимум для одного пользователя)
Также возможно следующие - MySQL может пометить как поврежденные при останове сервера или когда временные файлы займут слишком много места на диске (второе судя по мануалам, не проверял). Лечится репаиром соотвествующих таблиц.
Убить повисшие процессы может только root базы если они достигли max_user_connections.
Не работает с таблицами innodb, так последние хранятся в одном месте независимо от базы.
Итак, ситуация:
- новый db-сервер, с mysql 4.1.7
- необходимость проапгрейдить клиентскую библиотеку на тех серверах которые к нему будут обращаться.
- необходимость миграции данных с других mysql, которые 4.0
- базы все в cp1251
В качестве эксперимента апгрейдим mysql-client до 4.1.7 на первом db-сервере,
где стоит 4.0.20 и отпадание mysql-client'а на, пусть даже час, ни к чему фатальному не приведет...
На первый взгляд все гладко заапгрейдилось.
Вечером апгрейдим Mysql-client где надо, чего надо пересобираем... пока все гладко.
Начинаем миграцию данных, с того сервера где мы обновили Mysql-client в первую очередь.
Маленькая ремарка: mysql-(client|server) были собраны из портов с
WITH_LINUXTHREADS=yes
BUILD_STATIC=yes
BUILD_OPTIMIZED=yes
, т.е. с чарсетами по-умолчанию
- делаем дамп командой mysqldump --opt database > database.sql
- копируем дамп на новый сервер
- там в /etc/my.cnf уже прописано в [mysqld] default-character-set=cp1251.
- говорим create database db_name
- потом \. database.sql
- дамп разворачивается, но... с матами на дублирование ключа и с вопросиками в место русских буковок.
- пробуем set names cp1251 и снова развернуть дамп - та же история.
Потом пол-дня пробуем всякие разные комбинации с пересборкой mysql-server и всякими
настройками charset/collation, в результате удосуживаемся присмотреться к дампу
и увидеть там 'SET NAMES utf8' в самом начале. После замены оного на 'set names cp1251',
все встало на свои места.
Этот "set names utf8" появился когда новый mysqldump из mysql-client-4.1.7 взялся дампить
базу с cp1251 и, не получив информацию о collation/charset выставил то, что считал разумным - utf8.
Лечится созданием дампа с --skip-set-charset.
MySQL 3.23.x, /etc/my.cnf, блок " [mysqld]":
set-variable = max_connections=20 # Максимальное число одновременных коннектов к серверу
set-variable = max_user_connections=5 # Макс. число одновременных коннектов от одного пользователя
set-variable = connect_timeout=2
Для MySQL 4.x для простых баз имеет смысл использовать опцию skip-innodb для существенной экономии памяти.
В MySQL 4.x для конкретного пользователя можно установить следующие лимиты:
GRANT ... WITH MAX_QUERIES_PER_HOUR N1
MAX_UPDATES_PER_HOUR N2
MAX_CONNECTIONS_PER_HOUR N3;
, где:
N1 - Количество всех запросов в час;
N2 - Количество всех обновлений/изменений в час;
N3 - Количество соединений, сделанных за час.
Для просмотра содержимого бинарного лога запросов нужно использовать утилиту mysqlbinlog.
SHOW DATABASES; - список баз данных
SHOW TABLES [FROM db_name]; - список таблиц в базе
SHOW COLUMNS FROM таблица [FROM db_name]; - список столбцов в таблице
SHOW CREATE TABLE table_name; - показать структуру таблицы в формате "CREATE TABLE"
SHOW INDEX FROM tbl_name; - список индексов
SHOW GRANTS FOR user [FROM db_name]; - привилегии для пользователя.
SHOW VARIABLES; - значения системных переменных
SHOW [FULL] PROCESSLIST; - статистика по mysqld процессам
SHOW STATUS; - общая статистика
SHOW TABLE STATUS [FROM db_name]; - статистика по всем таблицам в базе
Свой пароль можно поменять через:
SET PASSWORD = PASSWORD('пароль')
Пароль определенного пользователя можно поменять через:
SET PASSWORD FOR логин@localhost = PASSWORD('пароль');
SET PASSWORD FOR логин@"%" = PASSWORD('пароль');
тоже самое делают:
UPDATE mysql.user SET Password=PASSWORD('пароль') WHERE User='логин' AND Host='localhost';
FLUSH PRIVILEGES;
или GRANT USAGE ON БД.* TO логин@localhost IDENTIFIED BY 'пароль';
или mysqladmin -u логин password пароль
Для того чтобы INSERT операции не влияли на производительность SELECT запросов используют конструкции:
"INSERT DELAYED" и "INSERT LOW_PRIORITY" (UPDATE LOW_PRIORITY)
Позволяют отложить включение данных до тех пор, пока не завершаться текущие операции чтения из базы,
при том, что если накопилось несколько "DELAYED", то данные будут добавлены одним блоком.
При DELAYED управление возвращается сразу, LOW_PRIORITY возвращает управление только после завершения записи.
Для увеличения скорости выполнения большого числа INSERT/UPDATE/DELETE
рекомендуется группировать несколько операторов в рамках одного лока или транзакции:
LOCK TABLES table WRITE; (BEGIN;)
INSERT'ы ...... (но не много, чтобы не столкнуться с deadlock)
UNLOCK TABLES; (COMMIT;)
Чем сейчас занимается SQL сервер:
MySQL: mysqladmin processlist
PostgreSQL: select * from pg_stat_activity;
select * from pg_stat_database;
Общая статистика по работе сервера:
MySQL: mysqladmin extended-status; mysqladmin status
PostgreSQL: select * from pg_stats;
Для тестирования повреждений рекомендуется выполнять:
myisamchk tables[.MYI]
Параметры уровня проверки:
--medium-check - средний
--extend-check - расширенный
В crontab:
35 0 * * 0 /usr/local/mysql/bin/myisamchk --fast --silent /path/to/datadir/*/*.MYI
Внимание, myisamchk нужно запускать при _не_ запущенном mysqld, иначе нужно использовать утилиту mysqlcheck
(mysqlcheck --repair --analyze --optimize --all-databases --auto-repair)
Восстановление таблицы:
REPAIR TABLE tbl_name или myisamchk -r table_name или myisamchk --safe-recover table_name
Бэкап структуры:
mysqldump --all --add-drop-table [--all-databases] --force [--no-data] [-c] \
--password=password --user=user [база] [таблицы] > backup_file
( -c - формировать в виде полных INSERT.
--all-databases - бэкап всех баз, --no-data - бэкап только структуры таблиц в базах, [таблицы] - бэкапить только указанные таблицы.)
Восстановление: mysql < backupfile
(для прямой вставки из текстового файла можно воспользоваться mysqlimport)
(для анализа структуры базы, например, списка таблиц: mysqlshow <база>)
В /etc/my.cnf вписать в блоке [mysqld]:
default-character-set=koi8_ru (или cp1251)
При работе с базой можно выставить рабочую кодировку через:
SET CHARACTER SET koi8_ru
GRANT ALL PRIVILEGES ON БД.* TO пользователь@localhost IDENTIFIED BY 'пароль';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP PRIVILEGES ON БД.таблица TO пользователь@'%.domain.ru' IDENTIFIED BY 'пароль';
или
insert into user (host,user,password) values ('localhost', 'пользователь', password('пароль'));
insert into db
(Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,
Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv)
values ('localhost','БД','пользователь','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
flush privileges;
или воспользоваться скриптом mysql_setpermission
Способ перекодирования выборочных записей в MySQL, содержащих данные в битой кодировке.
Перекодирование ошибочно добавленных нескольких записей с UTF-8 текстом
в таблицу в которой данные находятся в кодировке cp1251 (DEFAULT CHARSET cp1251).
UPDATE table SET column=CONVERT(CONVERT(CONVERT(column USING binary) USING utf8) USING cp1251) WHERE id=123;
Сокращенный вариант, внешний CONVERT можно убрать, MySQL знает, что данные в таблице в cp1251:
UPDATE table SET column=CONVERT(CONVERT(column USING binary) USING utf8) WHERE id=123;
Из-за сложности и многообразия locale в постгресе запрещено использовать индекс
для запросов вида LIKE 'что%' для всех locale кроме 'C'. А что делать если хочется ?
В 8.01 стало возможным использовать operator class [1] ! Мы будем использовать varchar_pattern_ops, B-tree индекс
в этом случае, будет строиться без использования collation правил из locale, а на основе сравнения буквы с буквой.
test=# \d ru_words
w | text |
Indexes:
"w_idx" btree (lower(w) varchar_pattern_ops)
test=# create index w_idx on ru_words (lower(w) varchar_pattern_ops);
CREATE INDEX
test=# vacuum analyze test;
test=# explain analyze select w from ru_words where lower(w) like 'что%';
Index Scan using w_idx on ru_words...
Index Cond: ((lower(w) ~>=~ 'что'::character varying) AND (lower(w) ~<~ 'чтп'::character varying))
Filter: (lower(w) ~~ 'что%'::text)
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 1109796233 * INTERVAL '1 second';
CREATE OR REPLACE FUNCTION ts2int(timestamp without time zone) RETURNS int AS
$$
select extract('epoch' from $1)::integer;
$$ LANGUAGE SQL STRICT STABLE;
CREATE OR REPLACE FUNCTION int2ts(integer) RETURNS timestamp AS
$$
SELECT ( TIMESTAMP WITH TIME ZONE 'epoch' + $1 * INTERVAL '1second')::timestamp without time zone;
$$ LANGUAGE SQL STRICT STABLE;
ALTER TABLE companies
ADD COLUMN fti_business tsvector;
UPDATE companies SET fti_business = to_tsvector('default',business_model);
VACUUM FULL ANALYZE companies;
CREATE INDEX idx_fti_business ON companies USING gist(fti_business);
CREATE TRIGGER tg_fti_companies
BEFORE UPDATE OR INSERT ON companies
FOR EACH ROW EXECUTE PROCEDURE
tsearch2(fti_business, business_model);
SELECT company_name, business_model
FROM companies
WHERE fti_business @@
to_tsquery('default','bushing | engine');
Для просмотра всего содержимого таблицы оптимальнее использовать COPY TO, вместо SELECT.
$conn->exec('COPY table (in, out) TO stdout');
die $conn->errorMessage if($conn->errorMessage);
$conn->getline($cur_line, 512);
while ($cur_line ne '\\.'){
my ($in, $out) = split(/\t/, $cur_line);
....
$conn->getline($cur_line, 512);
}
$conn->endcopy;
COPY FROM вместо INSERT позволяет значительно оптимизировать помещение данных в базу.
$conn->exec('COPY traffic (src_ip, dst_ip, in_octets, out_octets) FROM stdin;');
die $conn->errorMessage if($conn->errorMessage);
while(...) {
$conn->putline("$src\t$dst\t$in\t$out\n");
}
$conn->putline("\\.\n");
$conn->endcopy;
SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a
WHERE c.relname ='имя таблицы' AND a.attnum > 0 AND a.attrelid = c.oid ORDER BY a.attnum;
Если значение поля vendor = 1,2 или 3 суммируем только значения sales для этих номеров.
SELECT product,
SUM(CASE vendor WHEN 1 THEN sales ELSE 0 END) AS "pink ",
SUM(CASE vendor WHEN 2 THEN sales ELSE 0 END) AS "brown",
SUM(CASE vendor WHEN 3 THEN sales ELSE 0 END) AS "green",
SUM(sales) AS "sum of sales"
FROM sales GROUP BY product;
Если необходимо сделать выборку по промежутку, то нужно использовать:
CASE WHEN vendor > 1 AND vendor < 5 THEN sales ELSE 0 END
COMMENT ON test IS 'Это тестовая таблица.';
COMMENT ON DATABASE test IS 'Тестовая БД';
COMMENT ON INDEX test_index IS 'Индекс тестовой базы по id';
COMMENT ON COLUMN test.id IS 'Ключевое поле';
Список баз:
psql -A -q -t -c "select datname from pg_database" template1 | grep -v '^template1$'
Список таблиц в базе db_name :
echo '\d'| psql -A -q -t db_name |cut -d'|' -f1
Для запрещения нулевых значений в поле id в CREATE TABLE:
CONSTRAINT "test_tab_id" CHECK (id > 0)
Или если таблица уже существует:
ALTER TABLE test_tab ADD CONSTRAINT "test_tab_id" CHECK (id > 0);
Сопоставление имен директорий с названиями баз:
select oid,datname from pg_database;
Сопоставление имен таблиц в текущей базе к именам файлов:
select relname, relfilenode from pg_class;
Из еpoch в timestamp:
'epoch'::timestamptz + '$epoch_time sec'::interval
или $epoch_time::int4::abstime::timestamptz
или timestamptz 'epoch' + '$epoch_time second'
Из timestamp в epoch:
date_part('epoch', timestamp_field)
Создадим индекс для двух полей login и price в таблице item.
При использовании операций больше или меньше нужно использовать btree индексы,
hash для операций '='. Несколько полей для индексирования можно указывать только
для btree.
Например:
CREATE UNIQUE INDEX "index_item" on "item" using btree ( "login" "varchar_ops", "price" "integer_ops");
CREATE INDEX "index_item2" on "item" using hash ( "login" );
Использовать директиву "LIMIT сколько_записей_выводить OFFSET с_какой_записи_начинать_вывод":
Например, вывести 10 записей удовлетворяющих запросу, начиная с 50:
SELECT * FROM table LIMIT 10 OFFSET 50;
CREATE OR REPLACE FUNCTION reset_counter() RETURNS INT AS $$
$_SHARED{counter} = 0;
return 0;
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION counter() RETURNS INT AS $$
return $_SHARED{counter}++;
$$ LANGUAGE plperl;
Функции написанные на pl/perl и даже pl/pgsql будут работать только в том случае если у вас установлен данный язык к вашей базе.
Посмотреть какие языки установлены можно командой
'select * from pg_language;`
Обычно стоят только
С,SQL и internal(что такое объяснять не буду).
Для установке pl/perl вам нужно выполнить следующую команду.
createlang plperl <dbname>
Если же вы хотите чтоб pl/perl или pl/pgsql устанавливался автоматически на все создаваемые базы, то
cratelang plperl template1
CREATE FUNCTION login2contract(varchar)
RETURNS int4
AS 'select contract_id from profile where login = $1'
LANGUAGE 'SQL';
CREATE FUNCTION time_minus_int(timestamp, integer)
RETURNS timestamp
AS 'select $1 - interval ($2) AS RESULT'
LANGUAGE 'SQL';
Некоторые базы данных, такие как MSSQL и MySQL5, имеют специальные механизмы для разграничения доступа
пользователей к различным ресурсам БД вплоть до ячеек таблиц. PostgreSQL не нуждается в таких излишествах.
На практике обычно требуется разграничить доступ на уровне строк. Для того, что бы сделать это, есть простой способ,
основанный на использовании представлений, правил и функции current_user() или эквивалентного ей
ключевого слова user.
Создадим любую таблицу от имени 'postgres', в которой обязательно должно присутствовать поле
для хранения логина:
CREATE TABLE table1
(
fio text NOT NULL,
name text,
something integer,
login text,
CONSTRAINT table1_pkey PRIMARY KEY (fio)
)
WITHOUT OIDS;
ALTER TABLE table1 OWNER TO postgres;
Ни один пользователь не имеет никаких привилегий на эту таблицу.
Создадим представление, и дадим необходимым пользователям некоторые привилегии:
CREATE OR REPLACE VIEW table1v AS
SELECT table1.fio, table1.name, table1.something
FROM table1
WHERE table1.login = user;
ALTER TABLE table1v OWNER TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE table1v TO math_user;
Создадим три правила - для вставки, обновления и удаления строк из представления:
CREATE OR REPLACE RULE add AS
ON INSERT TO table1v DO INSTEAD INSERT INTO table1 (fio, name, something, login)
VALUES (new.fio, new.name, new.something, user);
CREATE OR REPLACE RULE upd AS
ON UPDATE TO table1v DO INSTEAD UPDATE table1 SET fio = new.fio, name = new.name, something = new.something, login = user
WHERE table1.login = user;
CREATE OR REPLACE RULE del AS
ON DELETE TO table1v DO INSTEAD DELETE FROM table1 where login=user;
Готово! Теперь пользователь math_user может просматривать или удалять только свои записи
и вставлять или изменять записи только под своим именем.
Начиная с PostgreSQL 8.1 появилась возможность ограничения числа соединений к серверу
для отдельного пользователя и базы:
ALTER ROLE имя_пользователя CONNECTION LIMIT число;
ALTER DATABASE имя_базы CONNECTION LIMIT число;
Можно указать лимит при создании базы или пользователя:
CREATE USER имя_пользователя CONNECTION LIMIT число ENCRYPTED PASSWORD 'пароль';
CREATE DATABASE имя_базы OWNER имя_пользователя CONNECTION LIMIT число;
Для сопоставления OID номеров и имен баз и таблиц в contrib есть утилита oid2name.
Для просмотра размера таблиц для текущей базы:
SELECT relname AS name, relfilenode AS oid, (relpages * 8192 / (1024*1024))::int as size_mb, reltuples as count
FROM pg_class
WHERE relname NOT LIKE 'pg%'
ORDER BY relpages DESC;
Для просмотра общего размера баз можно использовать скрипт:
#!/bin/sh
oid2name=/usr/local/pgsql/bin/oid2name
pg_data_path=/usr/local/pgsql/data/base
{
$oid2name| grep '='| while read oid delim name; do
size=`du -s $pg_data_path/$oid|cut -f1`
echo "$size $name"
done
}|sort -rn
Другой вариант просмотра размера базы:
select pg_database_size('имя базы');
Размер таблицы:
select select pg_relation_size('имя таблицы');
Полный размер таблицы с сопутствующих индексов.
select pg_total_relation_size('имя таблицы');
Размер столбцов
select pg_column_size('имя стобца') from 'имя таблицы';
Состояние всех настроек можно посмотреть через функцию pg_show_all_settings().
Создаем view:
CREATE OR REPLACE VIEW funcsource as
SELECT '--\012create or replace function ' ||
n.nspname::text || '.'::text || p.proname::text ||
'('::text || oidvectortypes(p.proargtypes) || ')\012'::text ||
'returns ' || t.typname || ' as \'\012' ||
p.prosrc || ' \'\012' ||
'language \'' || l.lanname || ' \';\012' as func_source,
proname as function, nspname as schema, t.typname as rettype,
oidvectortypes(p.proargtypes) as args, l.lanname as language
FROM pg_proc p, pg_type t, pg_namespace n, pg_language l
WHERE p.prorettype = t.oid AND p.pronamespace = n.oid AND p.prolang = l.oid
AND l.lanname <> 'c' AND l.lanname <> 'internal' ;
Сохраняем исходные коды функций в файл:
psql -Atc "select func_source from funcsource;" > functions.out
Восстановление из резервной template1:
postgres template1
create database template0 with template template1
update pg_database set datallowconn = false where datname='template0';
vacuum full;
vacuum freeze;
Выключить:
UPDATE "pg_class" SET "reltriggers" = 0 WHERE "relname"='tablename';
Включить:
UPDATE pg_class SET reltriggers = (
SELECT count(*) FROM pg_trigger where pg_class.oid = tgrelid)
WHERE relname = 'table name';
Для увеличения скорости помещения большого числа INSERT запросов (например, дамп в формате pg_dump -D):
SET autocommit TO 'off';
строки с INSERT
COMMIT;
SET autocommit TO 'on';
Или заключить набор INSERT'ов в одну транзакцию:
BEGIN;
INSERT....
COMMIT;
Вместо INSERT лучше использовать "COPY таблица (список полей) FROM stdin;"
Чем сейчас занимается SQL сервер:
MySQL: mysqladmin processlist
PostgreSQL: select * from pg_stat_activity;
select * from pg_stat_database;
Общая статистика по работе сервера:
MySQL: mysqladmin extended-status; mysqladmin status
PostgreSQL: select * from pg_stats;
Иногда, особенно для интенсивно обновляемых таблиц, начинают сыпаться deadlock'и и VACUUM
выполняется нереально долгое время. Часто проблема из-за поврежденного индекса. Решение:
REINDEX TABLE таблица;
REINDEX INDEX индекс;
- Скопируйте содержимое директории pgsql/data
- Если postmaster не загрузился - попробуйте удалить файлы
rm -f /tmp/.s.PGSQL.* /usr/local/pgsql/data/postmaster.pid
и попытаться запустить PostgreSQL.
- Если postmaster загрузился, но ни один запрос, включая vacuum, не выполняется,
попробуйте использовать утилиту contrib/pg_resetxlog.
- После всего выполните полный бэкап базы (pg_dumpall) и vacuumdb --all --full --analyze
Полный бэкап всех баз:
pg_dumpall [-s] [-D] > backup_file
Выборочный бэкап:
pg_dump [-s] [-D] [-t table] db > backup_file
-s - записывается только информация о структуре базы, без данных.
-D - формируется бэкап данных в виде INSERT команд.
-t table - бэкап выборочных таблиц.
В PostgreSQL 7.2 полностью изменился механизм работы VACUUM. Теперь для реальной перестройки содержимого таблицы
и реального освобождения пустых блоков необходимо запускать VACUUM FULL ANALYZE. Иначе при интенсивном апдейте,
небольшая таблица может превратится в огромного монстра. Во время работы VACUUM FULL - текущая таблица блокируется.
EXPLAIN SELECT num FROM news WHERE enter_date < (now() - '30 days'::interval);
По умолчанию используется Seq Scan, несмотря на наличие индекса по
enter_date, для использования индекса нужно использовать:
EXPLAIN SELECT num FROM news WHERE enter_date < (SELECT now() - '30 days'::interval);
или
set enable_seqscan to off;
Список пользователей:
select * from pg_shadow;
Список баз данных:
select * from pg_database;
Из командной строки:
psql -A -q -t -c "select datname from pg_database" template1
Если у вас уже установлен postgresql и вы решили добавить поддержку --enable-multibyte,
то при компиляции возможно возникнет ошибка и компиляция прекратится. Ошибка связана с функцией pg_encoding_to_char в libpq.
(Компилятор лезет за библиотекой в старый libpq)
Решение:
1. make clean
2. удалить старые библиотеки постгреса или удалить путь к библиотекам из ldconfig.
По умолчанию элемент таблицы не может превышать 8Кб.
в src/include/config.h измените значение BLCKSZ
PS. В PostgreSQL 7.1.x ограничение на размер снято.
Использование сокращений.
Конструкцию, используемую для вывода строк соответствующих заданной маске:
awk '{if ($0 ~ /pattern/) print $0}'
можно сократить до
awk '/pattern/'
Условие в awk может быть задано вне скобок, т.е. получаем:
awk '$0 ~ /pattern/ {print $0}'
По умолчанию, действия производятся со всей строкой, $0 можно не указывать:
awk '/pattern/ {print}'
print - является действием по умолчанию, его тоже можно не указывать.
awk '/pattern/'
Для вывода значения первого столбца строки, в которой присутствует маска LEGO:
awk '/LEGO/ {print $1}'
Для вывода значения первого столбца строки, во втором столбце которой присутствует маска LEGO:
awk '$2 ~ /LEGO/ {print $1}'
Для замены слова LIGO на LEGO и вывода только измененных строк можно использовать:
awk '{if(sub(/LIGO/,"LEGO")){print}}'
Но есть нужно выводить все строки (как sed 's/LIGO/LEGO/'), конструкцию можно упростить
(1 - true для всех строк):
awk '{sub(/LIGO/,"LEGO")}1'
Вывести все строки, за исключением каждой шестой:
awk 'NR % 6'
Вывести строки, начиная с 6 (как tail -n +6 или sed '1,5d'):
awk 'NR > 5'
Вывести строки, в которых значение второго столбца равно foo:
awk '$2 == "foo"'
Вывести строки, в которых 6 и более столбцов:
awk 'NF >= 6'
Вывести строки, в которых есть слова foo и bar:
awk '/foo/ && /bar/'
Вывести строки, в которых есть слово foo, но нет bar:
awk '/foo/ && !/bar/'
Вывести строки, в которых есть слова foo или bar (как grep -e 'foo' -e 'bar'):
awk '/foo/ || /bar/'
Вывести все непустые строки:
awk 'NF'
Вывести все строки, удалив содержимое последнего столбца:
awk 'NF--'
Вывести номера строк перед содержимым:
awk '$0 = NR" "$0'
Заменим команды (пропускаем 1 строку, фильтруем строки с foo и заменяем foo на bar,
затем переводим в верхний регистр и выводим значение второго столбца)
cat test.txt | head -n +1 | grep foo | sed 's/foo/bar/' | tr '[a-z]' '[A-Z]' | cut -d ' ' -f 2
аналогичной конструкцией на awk:
cat test.txt | awk 'NR>1 && /foo/{sub(/foo/,"bar"); print toupper($2)}'
Использование диапазонов.
Вывести группу строк, начиная со строки, в которой есть foo, и заканчивая строкой, в которой есть bar:
awk '/foo/,/bar/'
Исключив из вывода строки с вхождением заданных масок:
awk '/foo/,/bar/{if (!/foo/ && !/bar/)print}'
Более оптимальный вариант:
awk '/bar/{p=0};p;/foo/{p=1}'
Исключить только строку с завершающим вхождением (bar)
awk '/bar/{p=0} /foo/{p=1} p'
Исключить только строку с начальным вхождением (foo)
awk 'p; /bar/{p=0} /foo/{p=1}'
Разбиение файла по шаблонам.
Имеется файл (file), в котором группы строк разделены шаблонами FOO1,FOO2 и т.д.
Необходимо записать данные, находящиеся между метками FOO в разные файлы,
соответствующие указанным в FOO номерам.
awk -v n=1 '/^FOO[0-9]*/{close("out"n);n++;next} {print > "out"n}' file
В GNU Awk можно сделать так:
LC_ALL=C gawk -v RS='FOO[0-9]*\n' -v ORS= '{print > "out"NR}' file
Парсинг CSV.
По умолчанию в качестве разделителя используются пробел и табуляция.
Чтобы определить иной разделитель, например запятую, нужно использовать FS=',' или опцию "-F".
В качестве параметра может быть задано регулярное выражение, например, FS='^ *| *, *| *$'
Но для разбора CSV это не подойдет, так как пробелы могут присутствовать и внутри трок,
поэтому проще вырезать лидирующие пробелы перед и после запятой:
FS=','
for(i=1;i<=NF;i++){
gsub(/^ *| *$/,"",$i);
print "Field " i " is " $i;
}
Если в CSV данные помещены в кавычки, например "field1","field2", то подойдет такой скрипт:
FS=','
for(i=1;i<=NF;i++){
gsub(/^ *"|" *$/,"",$i);
print "Field " i " is " $i;
}
Но скрипт придется усовершенствовать для разбора полей вида:
field1, "field2,with,commas" , field3 , "field4,foo"
$0=$0",";
while($0) {
match($0,/[^,]*,| *"[^"]*" *,/);
sf=f=substr($0,RSTART,RLENGTH);
gsub(/^ *"?|"? *,$/,"",f);
print "Field " ++c " is " f;
sub(sf,"");
}
Проверка IPv4 адреса.
awk -F '[.]' 'function ok(n) {
return (n ~ /^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/)
}
{exit (ok($1) && ok($2) && ok($3) && ok($4))}'
Сравнение двух файлов.
Вывод всех дублирующихся строк из двух неотсортированных файлах file1 и file2:
awk '!($0 in a) {c++;a[$0]} END {exit(c==NR/2?0:1)}' file1 file2
Вывод только выделенных блоков текста.
Например, чтобы показать из файла с текстом только текст, отмеченный как =текст=
можно использовать:
awk -v RS='=' '!(NR%2)'
с форматированием переносов строк:
awk -v RS='=' '!(NR%2){gsub(/\n/," ");print}'
По умолчанию bash, а точнее утилита history, не сохраняет в .bash_history
время исполнения каждой команды.
Почитал маны и оказалось, что в баше трейтье версии сделать это можно и весьма просто.
Если объявить глобальную переменную HISTTIMEFORMAT с форматом выводимых данных,
то утилита history будет сохранять и выводить эту дату.
Итак, пишем в ~/.bashrc строчку
export HISTTIMEFORMAT='%h %d %H:%M:%S '
После этого в .bash_history перед каждой командой появится коментарий
с цифрой - временем выполнения этой команды в формате timestamp:
#1198068550
history
#1198139874
ьс
#1198139876
mc
#1198148168
ssh teletrade.ru
#1198148217
ssh teletrade.ru
А команда history будет выдавать историю данных с датой в формате,
который мы переменной задали (в похожем формате выдают дату и время утилита ls):
995 Дек 19 15:49:10 history
996 Дек 20 11:37:54 ьс
997 Дек 20 11:37:56 mc
998 Дек 20 13:55:49 ssh teletrade.ru
Но можно сделать и по ГОСТУ, в приятном русскому глазу виде "ДД.ММ.ГГГГ"
export HISTTIMEFORMAT='%d.%m.%Y %H:%M:%S '
А можно и на американский манер "YYYY-MM-DD"
export HISTTIMEFORMAT='%Y-%m-%d %H:%M:%S '
Чтобы поместить в отдельный лог команды выполненные в режиме su:
.bash_profile
export HISTSIZE=3000
export HISTFILESIZE=99999
export HISTFILE=/root/.bash_hist-$(who am i|awk '{print $1}';exit)
Получим два файла истории: .bash_hist-user и .bash_hist-root
.bash_profile загружается только при входе пользователя в систему (консольный вход, ssh),
в то время как .bashrc запускается для интерактивных сервисов выполняемых без логина (запуск xterm).
Пример1:
password='Your_MySQL_Password'
MYSQL_RESULT=`mysql -e "SELECT tables_col FROM table_name" --
password="$password" database_name|grep -v tables_col|xargs|sed "s/ /\n/g"`
for i in $MYSQL_RESULT; do
echo $i
done;
Пример2:
mysql -sse "SELECT col FROM table" -p"$password" database | while read i
do
echo $i
done
Комментарий 1: Пароль лучше передавать через переменную окружения MYSQL_PWD, чтобы он не светился в выводе ps.
Комментарий 2 (от myhand):
Другой вариант передача пароля через локальный файл конфигурации .my.cnf, размещенный в корне домашней директории пользователя:
Пример .my.cnf:
[client]
user = имя_пользователя
password = пароль
host = хост_БД
[mysql]
database = имя_бд
a \text - Добавить "text" после указанной строки (вывести), потом считать следующую.
b label - Перейти на метку, устанавливаемую, с помощью функции ":" , если label пуст, то перейти в конец скрипта.
c \text - Удалить pattern space и вывести "text" на output .
d - Удалить pattern space .
D - Удалить pattern space до вставленной newline .
g - Заместить содержимое pattern space содержимым буфера hold space .
G - Добавить к содержимому pattern space содержимое буфера hold space .
h - Заместить содержимое буфера hold space на содержимое pattern space .
H - Добавить к содержимому буфера hold space содержимое pattern space .
i \text - Вывести текст на output перед указанной строкой.
n - Вывести pattern space на output и считать следующую строку.
N - Добавить следующую строку к pattern space , разделяя строки вставленным newline .
p - Скопировать pattern space на output .
P - Скопировать pattern space до первой вставленной newline на output .
q - Переход на конец input . Вывести указанную строку, (если нет флага -n ) и завершить работу SED
r rfile - Читать содержимое rfile и вывести его на output прежде чтения следующей строки.
t label - Перейти на метку, устанавливаемую с помощью функции ":" , если для этой строки была
осуществлена замена с помощью функции "s" . Флаг осуществления замены восстанавливается
при чтении следующей строки или при выполнении функции "s" .
w wfile - Добавить pattern space к концу файла wfile . (Максимально можно использовать до 10 открытых файлов.)
x - Поменять местами содержимое pattern space и буфера hold space .
! func - Применять функцию func (или группу функций в {} ) к стокам НЕ попадающим в указанные адреса.
: label - Устанавливает метку для перехода по "b" и "t" командам.
= - Выводит номер строки на output как строку.
{ - Выполняет функции до "}" , только когда выбрано pattern space . Группировка функций.
# - Комментарий.
"#n" в скрипте равносильно установке флага -n
Примеры:
Выдираем ссылки из документа
cat index.html | sed -n 'H;${x;s/\n//g;s/ [hH][rR][eE][fF]=/\n/g;p}' |
# делаем ссылки в начале строки
sed 's/[ >].*//;s/"//g'# обрубаем концы и легкая косметика
Аналог dos2unix
$ sed -i 's/\r//' file
Убрать переводы строк в тексте
$ sed -ni 'H;${x;s/\n//g;p}' file
{#string} - Длина строки
Извлечение подстроки
${string:position} - с position до конца
${string:position:length} - с position длиной length символов
${string: -length} - последние length символов
Удаление части строки
${string#substring} - до первого с начала
${string##substring} - до последнего с начала
${string%substring} - до первого с конца
${string%%substring} - до последнего с конца
Замена подстроки
${string/substring/replacement} - первое вхождение
${string//substring/replacement} - все вхождения
${var/#Pattern/Replacement} - Если в переменной var найдено совпадение с Pattern,
причем совпадающая подстрока расположена в начале строки (префикс),
то оно заменяется на Replacement. Поиск ведется с начала строки
${var/%Pattern/Replacement} - Если в переменной var найдено совпадение с Pattern,
причем совпадающая подстрока расположена в конце строки (суффикс),
то оно заменяется на Replacement. Поиск ведется с конца строки
Пример:
a="12345"; echo "${a}"; echo "${a:3}"; echo "${a#12}"; echo "${a/12/21}"
Пригодится, например, для создания временных файлов:
FreeBSD: head -c 15 /dev/random | md5 | tail -c 10
Linux: head -c 15 /dev/random | md5sum | head -c 10
fileschanged -r /shared/source/tree | while read fd; do
stat -format="%n modified by %U at %y" $fc
done
fileschanged - http://fileschanged.sourceforge.net
min_num=2
max_num=10
i=$min_num
while [ $i -le $max_num ]; do
echo "$i"
i=$[i+1] # в зависимости от shell также подходит i=$(($i + 1)) или i=`expr $i + 1`
done
В FreeBSD sh и bash:
test="string"
len=${#test} ##Длина строки test
char1='t' ##Первый символ для поиска
pos1='echo $test | awk -vs=${char1} '{print index($0,s);}'' ##pos1=2 - найден
function math_minus {
num1_point=$(echo $1|sed 's/.*\..*/true/');
num2_point=$(echo $2|sed 's/.*\..*/true/');
if [ $num1_point = "true" ]; then
num1_1=$(echo $1|sed 's/\..*$//');
num1_2=$(echo $1|sed 's/^.*\.//');
else
num1_1=$1;num1_2=0;
fi; if [ $num2_point == "true" ]; then
num2_1=$(echo $2|sed 's/\..*$//');
num2_2=$(echo $2|sed 's/^.*\.//');
else
num2_1=$2;num2_2=0;
fi
num1_2_len=${#num1_2}
num2_2_len=${#num2_2}
if [ $num1_2_len -lt $num2_2_len ]; then
len_diff=$((num2_2_len-num1_2_len))
for i in `seq 1 $len_diff`; do
diff_nulls="${diff_nulls}0"
done
num1_2="${num1_2}$diff_nulls"
fi; if [ $num1_2_len -gt $num2_2_len ]; then
len_diff=$((num1_2_len-num2_2_len))
for i in `seq 1 $len_diff`; do
diff_nulls="${diff_nulls}0"
done
num2_2="${num2_2}$diff_nulls"
fi
if [ $num1_1 -gt $num2_1 ]; then
num1=$((num1_1-num2_1));
fi
if [ $num2_1 -gt $num1_1 ]; then
num1=$((num2_1-num1_1));
fi
num1_len=${#num1}
num2_len=$((num1_len+1))
num1="${num1}${num1_2}"
num2="${num2}${num2_2}"
if [ $num1 -gt $num2 ]; then
result=$((num1-num2))
else
result=$((num2-num1))
fi
num1=${result:0:num1_len}
num2=${result:num2_len}
result="${num1}.${num2}"
if [ "$result" == "." ]; then
result=0
fi
echo "$result"
}
Выше превиденный пример является концептуальной демонстрацией,
в скриптах для выполнения сложных матеметических операций более подходит bc:
echo "scale=5; a=4.1; (a+80)*3 - a^2 + l(a)" | bc -l
где через scale задается точность в знаках после запятой,
l() - натуральный логарифм, "^" - возведение в степень.
Возможности языка bc очень широки, поддерживаются циклы, условия, функции
Другая форма использования:
var1=2; var2=$(echo "scale=5; $var2 / 2" | bc)
Для преобразования формата представления чисел удобно использовать утилиту dc
Перевод числа 11 в шестнадцатеричную форму:
echo "11 16 o p" | dc
в двоичную
echo "11 2 o p" | dc
Выполнения простых целочисленных операций:
echo $(( 20 / 2 ))
var1=2; var2=$(( $var1 + 1 ))
Наверняка, каждый сталкивался с задачей переноса лог-файлов из текстовых файлов в различные БД.
И, наверняка, каждый столкнувшийся начинал писать собственные скрипты под это дело.
Причем большинство виденных мной скриптов основывались на построчном чтении/переносе данных.
Данный способ, конечно, хорош и имеет право на существование, но, к сожалению не очень быстр.
Но в MySQL существует способ перенести данные из обычных текстовых файлов в БД
очень и очень быстро при помощи директивы LOAD DATA INFILE
Пример такого скрипта:
#!/bin/bash
nld='/var/log/squid3' # Путь к лог-файлам
nbd='/opt/backup/squid3' # Путь к папке резервного хранения лог-файлов
nrc=`squid3 -k rotate` # Команда ротации лог-файлов для данного сервиса
nlf='/var/log/logs2mysql/squid.log' # На всякий случай пишем что и когда делали
mh='localhost' # Mysql host
mu='root' # Пользователь mysql
mp='secret' # Его пароль
mb='logs' # База данных
mt='squid' # Таблица
echo `date +"%F %T"` "Начало выгрузки" >> $nlf && \
$nrc && \
for i in `ls $nld | grep access.log.`;
do
year=`date +"%Y"`
month=`date +"%m"`
day=`date +"%d"`
prefix=`date +"%F-%H"`
test -d $nbd/$year/$month/$day || mkdir -p $nbd/$year/$month/$day && \
cat $nld/$i | sed -e 's/\"/\\\"/g' | sed -e "s/\'/\\\'/g" | \
awk ' {print strftime("%F",$1),strftime("%T",$1),$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11} ' | \
sed -e "s/ /\t/g" > $nld/prepare.log && \
chmod 0777 $nld/prepare.log && \
mysql -h $mh -u $mu -p$mp -e "LOAD DATA INFILE \"$nld/prepare.log\" REPLACE INTO TABLE $mb.$mt;" && \
cat $nld/$i >> $nbd/$year/$month/$day/$prefix.log && rm $nld/$i && rm $nld/prepare.log
done
echo `date +"%F %T"` "Конец выгрузки" >> $nlf
Поля для таблицы ('Поле'-тип)
'date'-date
'time'-time
'timestamp'-varchar(16)(разные сервисы пишут по разному.Кто-то с милисекундами, кто-то без)
'elapsed'-int(20)
'ip'-varchar(15)
'code'-varchar(20)
'size'-int(20)
'method'-varchar(10)
'url'-varchar(255)
'user'-varchar(255)
'direct'-varchar(25)
'mime'-varchar(25)
'hash'-varchar(255)unique
C небольшими изменениями данный скрипт можно приспособить для обработки
лог-файлов не только squid, но и других сервисов. Необходимое условие:
четкое разграничение полей (можно, поиграться с указанием разграничителей полей
в директиве LOAD DATA INFILE).
К преимуществам данного скрипта можно отнести огромное быстродействие
(п4-3,2 1024Мб ОЗУ 4млн. строк за 10-12 сек.).Также по последнему полю "hash" мы можем уникальным
образом идентифицировать строку (при анализе логов за год по squid и net-acct я не обнаружил
одинаковых строк).А также гарантированное попадание всех строк в БД
(т.к. данные не удаляются при сбое mysql).
1001-й способ поделиться файлом с коллегами: с помощью простенького HTTP-сервера,
код которого умещается в одной строке:
:;while [ $? -eq 0 ];do nc -vlp 8080 -c'(r=read;e=echo;$r a b c;z=$r;while [ ${#z} -gt 2 ];do $r z;done;
f=`$e $b|sed 's/[^a-z0-9_.-]//gi'`;h="HTTP/1.0";o="$h 200 OK\r\n";c="Content";if [ -z $f ];then($e $o;ls|(while $r n; do if [ -f "$n" ];
then $e "<a href=\"/$n\">`ls -gh $n`</a><br>";fi;done););elif [ -f $f ];
then $e -e "$o$c-Type: `file -ib $f`\n$c-Length: `stat -c%s $f`\n";cat $f;
else $e -e "$h 404 Not Found\n\n404\n";fi)';done
Этот сервер заработает на Linux, bash и с хоббитовским netcat с патчем sh-c (добавляющим опцию -c,
такой netcat есть во многих дистрибутивах, как минимум: в ubuntu, debian и fedora core).
После запуска следует зайти по адресу http://ваш_ip:8080.
При запросе корневой директории будет выведен список файлов, при запросе файла
будут отданы корректные заголовки Content-Length и Content-Type. Также сервер корректно
обрабатывает ошибку 404. Просматривать можно содержимой только текущей директории
и сменить ее никак нельзя.
Подробнее про него можно почитать на http://alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/
Наверное, все встречались, когда на том или ином разделе жесткого диска места уже нет. А
иногда и просто забываешь проконтролировать место на диске.
Данный скрипт написан по принципу настроил и забыл.
#!/bin/sh
address="root@localhost";
cicl="2 3 4 5 6";
# выставляем в процентах порог заполненного места для каждого раздела,
# при котором отсылается сообщение
predel[2]=80; # /
predel[3]=80; # /usr
predel[4]=60; # /var
predel[5]=80; # /tmp
predel[6]=80; # /home
varning="0";
count=0;
df -h > /tmp/tmp_df;
while read -r FS S Ud A U MO; do
let count+=1;
FileSystem[$count]=$FS;
Size[$count]=$S;
Used[$count]=$Ud;
Avail[$count]=$A;
Use[$count]=$U;
MountedOn[$count]=$MO;
NUse[$count]=${Use[$count]%"%"};
done < /tmp/tmp_df;
table="";
for c in $cicl; do
if [[ ${NUse[$c]} -ge ${predel[c]} ]]; then
varning="1";
table=$table"\n${FileSystem[$c]} \t${Size[$c]} \t${Used[$c]} \t${Avail[$c]} \t${Use[$c]} \t${MountedOn[$c]}";
fi
done
shapka="\nFileSystem \tSize \tUsed \tAvail \tUse \tMounted On";
body="Regard admin, please check, place on disk:"$shapka$table;
#echo -e $body;
if [ $varning -eq "1" ];
then
echo -e $body | mail -s"Warning on server" $address;
logger -i -p cron.warn -t dfmonitor "Send warning to $address";
else
logger -i -p cron.info -t dfmonitor " Place on disk in rate";
fi
P.S. записать в cron строчку:
20 5 * * * /sbin/dfmonitor,
с утра приходим и получаем отчет :-)
Когда есть необходимость передать файл с одной машины на другую,
а под рукой нет общедоступных ресурсов, можно сделать так:
nc -l -p 8080 < file
или
netcat -l 8080 < file
на клиенте достаточно в браузере набрать http://192.168.0.123:8080
Собственно, все. Впрочем, если получатель - блондинка, которая не знает команды File-Save, можно написать так:
(echo -e "HTTP/1.1 200\nContent-Disposition: attachment;
filename=gena_na.png\nContent-Type: application/octet-
stream\nConnection: close\n"; cat vim_mrxvt.png ) | nc -vv -l -p 8080
Но это еще не все. Можно дать доступ к целой директории, написав простой HTTP сервер в одной строке:
while true; do nc -vv -l -p 8080 -c '( read a b c; file=`echo $b | sed 's/[^a-z0-9.]//g'`;
if [ a$file = "a" ]; then ( ls | (while read f; do echo "<a href=$f>$f</a><br>"; done) );
else cat $PWD/$file; fi )'; sleep 1; done
Этот скрипт отдает все файлы, которые есть в текущем каталоге и не позволяет его сменить.
В случае, если запрашивается корневая директория, то управление передается
своеобразному mod_index - т.е. выводится список файлов-ссылок. В конце добавлена задержка в 1 сек
для того, чтобы была возможность убить его нажатием Ctrl-C.
См. подробнее http://alexey.sveshnikov.ru/blog/2006/12/23/http-сервер-размером-в-222-байта/
Возможно поможет кому-то. Разместив в кроне, можно забыть о ручном обновлении,
скрипт проверит базы, при необходимости загрузит и соберет обновленную
версию и обновит демоны.
#!/bin/bash
#
# ClamAV auto update routine
#
# Define system variables
#
DESTPATH="/usr/src"
TOREPORT="root"
OK="Ok"
NO="Failed"
echo >> /var/log/`basename $0`.log
#
# Functions library: logger stores all the events in a log file,
# reporter emails error events to admin
#
function logger () {
if [ "$1" != "n" ]; then
DATA="$1"
CMD=""
else
DATA=`date +"%b %d %H:%M:%S $2"`
CMD="-ne"
fi
echo $CMD "$DATA" >> /var/log/`basename $0`.log
}
function reporter () {
echo "Error $1 in `basename $0`" | mail -s "`basename $0` reporting error" $TOREPORT
quit
}
#
# Check for presence of a link to internet, need to prevent dns errors reporting by syslogd
#
logger n "Check for link to clamav.net: "
IPADDR=`host clamav.net | grep address | cut -d " " -f 4`
if [ "$IPADDR" != "" ]; then
#
# Check availability of the node
#
PINGER=`ping -c 1 $IPADDR | grep received | cut -d " " -f 4`
if [ $PINGER == 1 ]; then
logger "$OK"
else
logger "$NO"
reporter 1
fi
else
logger "$NO"
reporter 2
fi
#
# Run database updater:
#
VERSION=`freshclam | grep "WARNING: Local" | cut -d " " -f 7`
#
# If warning message present, check for presence of tarball
#
if [ "$VERSION" != "" ]; then
logger n "Checking presence of tarball: "
if [ ! -e $DESTPATH/clamav-$VERSION.tar.gz ]; then
logger "$NO"
logger n "Fetching mirrors list: "
#
# No tarball found, start fetching subroutine
# First of all, get the mirrors list
#
MIRROR=( $(wget -q http://prdownloads.sourceforge.net/clamav/clamav-$VERSION.tar.gz?download \
-O /dev/stdout | grep "use_mirror" | cut -d "=" -f 3 | sed -r "s/<[^>]*>//g" | cut -d "\"" -f 1))
if [ $? != 0 ]; then
logger "$NO"
reporter 3
else
logger "${#MIRROR[@]} nodes available"
fi
#
# To prevent overloading of the first node in a mirrors list, select random from the list
#
NODE=$RANDOM
let "NODE %= ${#MIRROR[@]}"
logger n "Downloading v$VERSION from ${MIRROR[$NODE]} ($NODE): "
wget -q -c -t 5 http://${MIRROR[$NODE]}.dl.sourceforge.net/sourceforge/clamav/clamav-$VERSION.tar.gz \
-O $DESTPATH/clamav-$VERSION.tar.gz >/dev/null 2>&1
if [ $? != 0 ]; then
logger "$NO"
reporter 4
else
logger "$OK"
fi
else
logger "$OK"
fi
#
# Now tarball must be present, and we have to check it's condition
#
logger n "Checking tarball condition: "
gzip -l $DESTPATH/clamav-$VERSION.tar.gz > /dev/null 2>&1
if [ $? != 0 ]; then
logger "$NO"
#
# If we got an error message in checking of a tarball,
# erase it, and next time try to download fresh one
#
rm -f $DESTPATH/clamav-$VERSION.tar.gz
reporter 5
else
logger "$OK"
cd $DESTPATH/
logger n "Unpacking: "
#
# Ok, gzip reported that's tarball is ok, now unpacking it
#
tar -xzf clamav-$VERSION.tar.gz >/dev/null 2>&1
if [ $? != 0 ]; then
logger "$NO"
reporter 6
else
logger "$OK"
fi
logger n "Configuring: "
cd $DESTPATH/clamav-$VERSION
#
# Below are standard procedures of configuring, assembling and installing of the package
#
./configure > /dev/null 2>&1
if [ $? != 0 ]; then
logger "$NO"
reporter 7
else
logger "$OK"
fi
logger n "Compiling: "
make > /dev/null
if [ $? != 0 ]; then
logger "$NO"
reporter 8
else
logger "$OK"
fi
logger n "Installing: "
make install > /dev/null 2>&1
if [ $? != 0 ]; then
logger "$NO"
reporter 9
else
logger "$OK"
fi
logger n "Check old daemon: "
#
# Now we have to swap old smtpd daemon to new
# If old daemon is preset - kill'em
#
PID=`ps -eo pid,comm | grep clamd | sed -r "s/^\ //" | cut -d " " -f 1`
if [ "$PID" != "" ]; then
logger "$OK"
logger n "Killing old daemon ($PID): "
kill -9 $PID
if [ $? != 0 ]; then
logger "$NO"
reporter 10
else
logger "$OK"
fi
else
logger "$NO"
fi
logger n "Starting new daemon: "
#
# Now memory is clear from old daemon and we're running the new one
#
/usr/local/sbin/clamd & > /dev/null 2>&1
if [ $? != 0 ]; then
logger "$NO"
reporter 11
else
logger "$OK"
fi
#
# Arter all of these, we have to run database updater again
#
logger n "Checking for newer database: "
freshclam > /dev/null 2>&1
if [ $? != 1 ]; then
logger "$NO"
reporter 12
else
logger "$OK"
fi
#
# At this stage, we have new antivirus installed, databases are up to date
# and ready to protect our system
#
fi
else
logger n "ClamAV is up to date"
logger ""
fi
#
# I did not find any benefits to run freshclam in a daemon mode using switch -d.
# Running once for a 4, 6 or whatever hours, it takes system resources for 24 hours, 7 days
# I think better is to use this script and run it with cron daemon (crontab) as a foreground process
# within the same time range
#
# Dima.
#!/bin/sh
#
# mysql-after-setup
# Copyright (c) 2006 Alexey Tsvetnov, vorakl@fbsd.kiev.ua
# Version: 1.4
#
# Run script after install MySQL to do:
# 1. Drop database 'test'
# 2. Set MySQL root password
# 3. Delete all users and access except root@localhost
#
# tty echo off
stty -echo
# enter correct password
while true
do
echo -n "Enter password: " && read pass1 && echo
echo -n "Re-enter password: " && read pass2 && echo
[ "${pass1}" = "${pass2}" ] && break
echo " *** Error!"
done
# tty echo on
stty echo
echo "drop database test; delete from db where db like '%test%';\
update user set password=PASSWORD('$pass1') where user='root' and host='localhost';\
delete from user where password='';\
flush privileges;" | mysql -h 127.0.0.1 -u root mysql && echo "Done successfuly."
exit 0
По сути, выполняет действия, аналогичные pkg_create с ключём -R, который появился только в FreeBSD 6.x.
Однако данный скрипт позволяет указывать короткое имя порта и каталог,
в котором создавать пакеты. А главное, он работает и на тех системах,
где pkg_create не поддерживает ключ -R.
#!/bin/sh
#
# pkg_depend
# Create all packages (with dependence) needed by some port for FreeBSD 5.x+
#
# Version: 1.4
# Copyright (c) 2005,2006 Alexey Tsvetnov, vorakl@fbsd.kiev.ua
#
# Path to packages directory
pkgpath="/usr/ports/packages/All"
# Command for get package's version
pkgvercmd="pkg_version -v"
#pkgvercmd="portversion -v" # more faster than pkg_version
getdepend()
{
[ ! -d $2 ] && echo -n "Creating directory ($2)..." && mkdir -p $2 && echo "Done."
cd ${pkgpath}
if [ ! -f ${pkgpath}/$1.tbz ]; then
echo -n "Creating package ($1)..."
pkg_create -yb $1
echo "Done."
fi
echo -n "Copying package ($1)..."
cp -f ${pkgpath}/$1.tbz $2
echo "Done."
for LINE in `pkg_info -r $1 | grep Dependency\: | awk '{print $2}'`
do
if [ ! -f ${pkgpath}/${LINE}.tbz ]; then
echo -n "Creating package (${LINE})..."
pkg_create -yb ${LINE}
echo "Done."
fi
echo -n "Copying package (${LINE})..."
cp -f ${pkgpath}/${LINE}.tbz $2
echo "Done."
done
}
gethelp()
{
echo ""
echo "Usage: `basename $0` <Full/Short pkg_name> <Directory>"
echo ""
echo "If specify short package name script will get first find entry"
echo ""
echo "Example: `basename $0` dia-gnome-0.94_4,1 /tmp/pkg/"
echo " `basename $0` dia-gnome /tmp/pkg/"
echo ""
exit 1
}
main()
{
if [ "$2" = "" ]; then gethelp
else
echo -n "Checking package name ($1)..."
if [ "`echo $1 | grep '\-[0-9]'`" = "" ]; then
pkgname=`${pkgvercmd} | grep -E '^'$1'-[0-9].*' | awk '{print $1}' | head -1`
else
pkgname=`${pkgvercmd} | grep $1 | awk '{print $1}' | head -1`
fi
echo "Done."
if [ "${pkgname}" = "" ]; then
echo "Package '$1' not found! Exit."
exit 2
else
getdepend ${pkgname} $2
fi
fi
}
main $1 $2
exit 0
Вот такой простой скрипт:
#!/bin/sh
retval=`/sbin/mount | grep /mnt/cdrom`
if [ -n "$retval" ];
then /sbin/umount /mnt/cdrom 1> /dev/null 2> /dev/null
if [ "$?" -ne 0 ];
then echo "Не могу размонтировать CDROM"
else echo "Размонтировал CDROM"
eject /dev/cdrom
fi
else /sbin/mount /dev/cdrom 1> /dev/null 2> /dev/null
if [ "$?" -ne 0 ];
then echo "Не могу смонтировать CDROM"
else echo "Примонтировал CDROM"
fi
fi
П.С. копируем в каталог /sbin под именем cdm. Сам определяет состояние
На разных машинах в моей локальной сети накопилась куча программ,
которым нужен был выход в интернет напрямую. У каждой свой набор портов.
Захотелось на входе иметь минимальную конфигурацию, описывающую
ресурсы, а на выходе набор разрешающих правил для iptables.
В основном были клиент-банки - поэтому и такая терминология в программе.
А так вместо банка можно указывать любой ресурс в формате определенном в
man iptables.
Ограничения, недостатки:
1. использование количества портов для одного ресурса менее 16
2. нельзя указать диапазон портов через двоеточие как в iptables
Оба легко устаняются: первое - есть пример в самом скрипте,
второе через использование другого разделителя для записей на входе,
проверку наличия ":" - использование другого формата вызова iptables. Мне это не нужно и код не хотел раздувать.
#!/bin/bash
#bkv 2005.10
#Дано:
# Два списка:
# Первый список из записей вида - банк:порты(через запятую)
# Второй список из записей вида - клиент:банки(через запятую)
#Найти:
# Набор разрешающих правил iptables для forward
#Примечания:
# политика FORWARD по умолчанию - "запрещено все, что не разрешенно"
# iptables поддерживает одновременное указание не более 15 портов
#Решение:
# Создадим отдельную цепочку, например, - CLIENTBANK
# Сгенерируем необходимые правила и поместим их в цепочку CLIENTBANK
# Обращения по всем портам из первого списка направим на обработку в CLIENTBANK
# Перед выполнением все правила связаные с цепочкой CLIENTBANK удалим, чтобы не плодить
# правила от многократного запуска
itls="/sbin/iptables"
#Подаем список на обработку awk
#признак первого списка - первое поле BankPorts
#признак второго списка - первое поле ClientBanks
echo -e "\
BankPorts:smtp.mail.ru:25\n\
BankPorts:10.24.70.0/26:22,23\n\
BankPorts:pop.mail.ru:110\n\
BankPorts:bank4.ru:9999,888\n\
BankPorts:bank5.ru:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15\n\
BankPorts:bank6.ru:21,22,23,24,25,26,27,28,29,210,211,212,213,214,215\n\
ClientBanks:192.168.9.0/16:smtp.mail.ru,pop.mail.ru,10.24.70.0/26\n\
ClientBanks:192.168.9.8:bank4.ru,bank5.ru,bank6.ru\n\
ClientBanks:192.168.9.6:bank6.ru,bank4.ru\n\
"|\
awk -v itls=$itls -F: '{
if($0~/^BankPorts/) BankPorts[$2]=$3 #создаем ассоциативный массив - индекс:банк, значение:порты через запятую
if($0~/^ClientBanks/) ClientBanks[$2]=$3 #аналогично клиент -> банки
}END{
#Cгенерируем _необходимые_ правила для цепочки CLIENTBANK
for (client in ClientBanks){
split(ClientBanks[client],bank_arr,",") #поместили в массив bank_arr адреса банков для клиента
for(i in bank_arr){
all_ports=all_ports","BankPorts[bank_arr[i]] #создаем список всех портов для дальнейшего использования
count_ports=split(BankPorts[bank_arr[i]],tmp_arr,",")
if(count_ports > 15)
print "echo Слишком много портов для "bank_arr[i]".Допиши программу.Выход&&exit 1"
else
printf("%s -A CLIENTBANK -s %s -d %s -p tcp -m multiport --dports %s -j ACCEPT\n",itls,client,bank_arr[i],BankPorts[bank_arr[i]])
}
}
#Создадим правила перенаправляющие из FORWARD на обработку в CLIENTBANK, помня про ограничение в 15 портов
sub(",","",all_ports) #отрезаем первую запятую у списка всех использующихся портов
split(all_ports,all_ports_arr,",")#поместили в массив all_ports_arr все порты какие есть
j=1;i=1
while(all_ports_arr[i]){
while(i<=(j*15)){
if (all_ports_arr[i])
tmp_all_ports=tmp_all_ports","all_ports_arr[i]
i++
}
sub(",","",tmp_all_ports) #отрезаем первую запятую
printf("%s -I FORWARD -p tcp -m multiport --ports %s -j CLIENTBANK\n",itls,tmp_all_ports)
tmp_all_ports=""
j++
}
print itls" -A CLIENTBANK -p tcp -m state --state ESTABLISHED -j ACCEPT"
print itls" -N CLIENTBANK"
print itls" -X CLIENTBANK"
print itls" -F CLIENTBANK"
#Удаляем из FORWARD все цепочки содержащие цель CLIENTBANK
del_rules_nums="'`$itls --line-numbers -L FORWARD -n|grep CLIENTBANK|cut -f1 -d" "|tr "\n" ","`'"
split(del_rules_nums,del_rules_arr,",")
cnt_rules=1
while(del_rules_arr[cnt_rules]){
printf("%s -D FORWARD %s\n",itls,del_rules_arr[cnt_rules])
cnt_rules++
}
}'|tac > gen.itls.sh
chmod 700 gen.itls.sh
echo "Команды сгенерированы в файл ./gen.itls.sh .Выход."
exit
./gen.itls.sh
rm ./gen.itls.sh
Иногда случается, что при сбое (например при большой нагрузке или при временном отсутствии
каналов связи) важные демоны самостоятельно завершают свою работу.
Например может случаться вот такая ошибка
squid[703]: Exiting due to repeated, frequent failures
Такое же может иногда случаться с IPA (/usr/ports/sysutils/ipa) и Apache.
Чтобы автоматизировать отслеживание таких процессов можно создать
`crontab -e` задание (на примере Squid)
5,35 * * * * /usr/local/etc/rc.d/checksquid
./checksquid:
proc="squid"
PIDFILE=/var/run/${proc}.pid
if [ -f $PIDFILE ] ; then
PID=`head $PIDFILE`
if [ "x$PID" != "x" ] && kill -0 $PID 2>/dev/null ; then
RUNNING=1
else
RUNNING=0
fi
else
RUNNING=0
fi
if [ $RUNNING -eq 0 ]; then
echo "Starting $proc again..."
/usr/local/etc/rc.d/${proc}.sh start
continue
else
echo "$proc already running"
fi
Нужно только убедиться что нужные PID файлы хранятся в /var/run.
Директивы pid_filename в squid.conf, PidFile в httpd.conf
Что делать если под рукой нет tripwire или osec, а кривой aide вы пользоваться не хотите.
Часть функций , таких как проверка прав доступа и изменение файлов, можно реализовать штатными стедствами.
Вот маленький скрипт который помещается в crontab и позволяет это реализовать.
При желании его функции можно легко расширить.
#!/bin/bash
ulimit -t 20
checkdir="/bin /sbin"
filedb="/var/tmp/permsecdb"
email="test@test.ru"
out=$(
exec 2>&1
umask 266
find $checkdir -type f -printf "%m\t" -exec md5sum {} \; >$filedb.tmp
diff $filedb $filedb.tmp
mv -f $filedb.tmp $filedb
)
if [ "$out" ];then
(date; echo; echo "$out") |mail -s "Change permsec `hostname`" $email
fi
- ulimit лучше выставить не случай не предвиденных ситуаций.
- checkdir соответственно проверяемые директории
- filedb текстовой файл базы
- email куда посылать мыло
Если изменений в системе не было, то сообщения посылаться не будут.
Сообщение бывает 4 видов
1 - ошибки
2 - добавлен файл "> 644 d41d8cd98f00b204e9800998ecf8427e /bin/12"
3 - удален файл "< 755 c1a0ff878c603dd91f603059e9c1a0a1 /bin/12"
4 - изменен файл "
< 755 ce367ef1e2cca19e6216874cb8c09d96 /bin/12
---
> 755 c1a0ff878c603dd91f603059e9c1a0a1 /bin/12"
Успешного контроля.
Воспользоваться услугами сетей доставки контента (Content Delivery Network), например Akamai;
Не пренебрегать HTTP заголовком "Expires" или "Cache-control";
Отдавать страницы в сжатом виде (например, mod_gzip);
Указывать ссылки на файлы с таблицами стилей (link href) в начале документа;
Указывать ссылки на JavaScript файлы (script src) в конце документа;
Не использовать вычислимые выражения (expression) в CSS;
Хранить JavaScript и CSS вставки в виде отдельных файлов;
Уменьшить число обращений к другим доменам на странице (например, когда картинки или iframe грузятся с другого сервера, в идеале не больше 3 доменов);
Минимизировать размер JavaScript и CSS (например, при помощи JSMin или YUI compressor, которые убирают лишние пробелы, комментарии и сокращают переменные);
Избегать редиректов (HTTP Redirect);
Исключить дублирование JavaScript кода (например, IE повторно грузит повторяющиеся "script src" вставки);
Настроить ETags ("FileETag None" в Apache);
Кэшировать Ajax запросы;
Сбрасывать буфер в на начальном этапе генерации страницы (например, через периодический вызов flush() в PHP, для того чтобы клиент получил ссылки на CSS файлы и успел начать их загрузку);
Использовать для Ajax запросов HTTP метод GET (вмещается в 1 TCP пакет, в то время как POST отправляется в два этапа - заголовки и данные);
Выделение контента, который можно загрузить в последнюю очередь (например, отложенная загрузка картинок и JavaScript блоков, после того как загрузится основная часть);
Выделение скриптов, который нужно загрузить в первую очередь;
Уменьшение числа элементов в дереве DOM (минимизация числа HTML тэгов на странице);
Разделение контента по разным доменам: статика через отдельный static.domain.com (браузер будет загружать данные параллельно);
Минимизировать число iframe'ов, не использовать в iframe и script src ссылки на чужие ресурсы (блокирует загрузку остальной части страницы);
Недопускать появление 404 ошибки (страница не найдена);
Уменьшить размер Cookie (убрать лишнее, сократить имена, привязать только к необходимым доменам, определить время жизни);
Для вспомогательных страниц исключить установку Cookie (вынос картинок, CSS и скриптов на static.domain.com);
В JavaScript минимизировать обращения к DOM (очень медленная операция), исключить повторяющиеся запросы к DOM через кэширование;
Оптимизировать обработку событий в JavaScript (вместо "onload" использовать DOMContentLoaded, с осторожностью использовать onresize, провести аудит при помощи утилиты YUI Event);
Загружать CSS через "link" вначале страницы, не использовать @import (в IE он приводит к загрузке CSS в самом конце);
Избегать использования фильтров в CSS, они поддерживаются только в IE, лучше использовать PNG8;
Оптимизировать изображения (минимизация размера палитры, переход на PNG, оптимизация через утилиты pngcrush, optipng или pngoptimizer, удаления комментариев в картинках, оптимизация JPEG через jpegtran);
Оптимизация CSS спрайтов (css sprite) для создания фоновых изображений;
Фактический размер изображения должен совпадать с указанным в параметрах width и height (для того чтобы избежать масштабирования);
favicon.ico должен быть небольшим (менее 1 Кб) и кэшируемым (должен выставляться Expires, 9% всех запросов в Yahoo Search приходится на favicon.ico !);
При использовании Flash нужно определить crossdomain.xml;
Страницы, предназначенные для просмотра на мобильных устройствах, не должны превышать 25Кб (иначе не попадают в кэш iPhone);
Для мобильных устройств можно использовать multipart блоки, когда дополнения к странице (css, картинки) упаковываются в самой странице в виде приложений;
Воспользуйтесь системами для проведения авторизации и процессинга платежей,
совершаемых при помощи кредитных карт или с лицевых счетов клиентов:
http://www.assist.ru/ или http://www.paymentgate.ru/
В IE JavaScript функция escape() кодирует в utf8, вместо %XX.
Последовательности закодированные в виде %uXXX (utf8) рекомендуется раскодировать
посредством модулей Unicode::String и Unicode::Map8.
Другим выходом является принудительное кодирование параметров внутри
документа средствами JavaScript.
Для того чтобы разбить в нужных местах большой HTML документ на страницы
и выделить их полоской при просмотре в браузере, которая не будет видна в печатном варианте,
можно использовать код:
<table style="width: 100%; padding: 0; border: none; border-collapse: collapse;">
<tr><td style="background-color: #B0B0B0; height: 1; padding: 0;" nowrap></td></tr>
</table>
<br style="page-break-after: always">
<span style="background-color: #d8d8ff; color: #400000;">test</span>
или просто указав стиль в тэге:
<li style="background-color: #d8d8ff; color: #400000;">test</li>
blockquote { margin-top: 3px; margin-bottom: 3px; margin-left: 2em; margin-right: 0em; background: #red }
В этом случае блок отступит на 3 пикселя сверху и снизу, на 2 символа слева и закрасит фон красным.
Вместо <hr noshade size=1> можно использовать:
<tr><td height="1" bgcolor="#8F0000">
<spacer type="block" width="450" height="1">
</td></tr>
или еще одно решение:
<td height="1" bgcolor="#8F0000" nowrap></td>
"MARGINHEIGHT" добавляет пустое поле между верхней границей фрейма и началом текста или графики. Измеряется в пикселах.
"MARGINWIDTH" аналогично "MARGINHEIGHT", только применяется к левой границе.
Для добавления отступа между таблицами удобно использовать:
<table ... style="margin-bottom: 5px;">
или
<table ... style="margin-top: 5px;">
Хэши:
var hash = {
color: "red",
artefact: "pill",
actors: {
supplier: "Morpheus",
consumer: "Neo"
}
}
var hash = new Object();
hash.color = "blue";
hash.element = "pill";
var element1 = hash.element;
var element2 = hash['element'];
Массивы - это обыкновенные хэши с числовыми ключами, а также ключом length, содержащим их длину.
var arr = [100, 200, 300];
for (var k in arr) alert(k + "=>" + arr[k]);
function GetCookie (name) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var endstr = 0;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg){
endstr = document.cookie.indexOf (";", j);
if (endstr == -1){
endstr = document.cookie.length;
}
return unescape(document.cookie.substring(j, endstr));
}
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) { break; }
}
return null;
}
var cook_uname = GetCookie('uname');