02 ноября 2014

Ни один браузер не работает

Если страницы перестали открываться сразу во всех браузерах и вы везде получаете сообщение "невозможно отобразить страницу". Но подключение к интернету при этом присутствует. Тогда перво наперво попробуйте сбросить стек Winsock. 

В командной строке выполняете 
C:\ netsh winsock reset

После перезагрузки должно помочь!

ZFS FreeBSD

Это учебная статья посвященная ZFS, из которой вы узнаете, что это такое, как использовать и как лучше настроить.
Для тех, кто не в курсе это локально-распределенная файловая система нового поколения, которая объединяет отдельные диски в пулы с возможностью создания RAID 0, 1, 10, 5. Это 128-битная файловая система с переменным размером блока (или кластера, как в терминологии fat) до 128 КБ. Таким образом каждый пул может адресовать огромный массив данных, в идеале (2^128)*128 КБ. В качестве полезных функций имеются встроенные механизмы квотирования, резервирования, контроля целостности данных и некоторые др. Отличительные черты - быстродействие, надежность и удобство.

Сразу стоит сказать, что ZFS требовательна к ресурсам, минимально для комфортной работы ей нужно не менее 1 Гб оперативной памяти на любой архитектуре, но чем больше тем лучше. Поэтому 64-битные системы предпочтительней, у них нет жестких ограничений адресного пространства.

Журналируемость, транзакционность и контрольные суммы каждого блока в совокупности с основным приемуществом ZFS - методом записи "Copy On Write" обеспечивают уверенную отказоустойчивость при нештатных отключениях питания.

По технологии "CoW" новые данные не перезаписывают старые, а пишутся в свободное пространство и меняется только указатель. Правда у нее есть и обратная сторона медали, при чрезмерном заполнении пула происходит падение производительности. Поэтому  рекомендуется активно пользоваться квотированием и не допускать заполнения больше, чем на 80%.

Учитывая, такие факторы, как распределение нагрузки между всеми дисками, входящими в пул, использование быстрого кэша и блока с переменным размером, можно ожидать от ZFS порядочного быстродействия. 

И ради любопытства я провел дилетантское сравнение быстродействия с UFS (журнал + soft update) при операции записи. Я выполнял копирование с помощью dd if=/dev/zero of=file bs=1M count=2000. Как и следовало ожидать на моем слабом железе ZFS оказался медлительней.

Действительно, что ZFS может сделать на стареньком P4 3Гц, c 2ГБ памяти и одним жестким диском SATA.  Хотя в процессе тестирования я и пытался настраивать разные параметры производительности ZFS (их мы рассмотрим чуть ниже), но лучшие результаты все равно оказались следующими ZFS - 26, 35 сек против UFS - 19,67 сек.

Поэтому отдаем себе отчет, что ZFS предназначена для достаточно мощного и современного оборудования с 64-битной архитектурой и с не менее, чем 4 Гб памяти. Но на старом железе конечно тоже будет работает, проверено лично. Но какой результат и зачем мучить свой старенький комп?

И так, приступим к препарированию.
 
B ZFS нет понятий томов и слайсов, как в традиционных ФС. Есть пул, внутри которого создаются файловые системы или как их еще называют датасеты. Размер файловых систем не фиксируется и может быть легко увеличен в результате присоединения нового диска к пулу. Поэтому здесь не может наступить критической ситуации полного заполнения диска.

Уменьшить размер ZFS пула уже не возможно! К примеру нельзя изъять диск, если это не зеркало. Это сразу приведет в выходу из строя всего пула! Заменить диск на другой, большего размера, всегда пожалуйста. Поэтому единственное, как можно уменьшить пул, это сохранить все данные на внешнем носителе, разрушить пул и создать новый.

Установка FreeBSD на ZFS
Нужно загрузиться с CD-диска или USB Memstick и начать установку как обычно. В FreeBSD 10 установка на ZFS уже полностью автоматизирована через bsdinstaller. На этапе разметки дисков достаточно выбрать пункт ZFS и система все сделает за вас. Ну а если хотите сделать это руками, то заходите в shell.
Здесь следует обратить внимание на следующие настройки: тип пула (stripe, mirror или raidz1, raidz2, raidz3), далее выбрать нужные диски для его создания. Пункт "forse 4k sectors" устанавливает выравнивание по 4К для каждого созданного раздела. Это важно, если у вас новые жесткие диски большого объема с размером сектора 4K, а не 512Б. Если нет, то укажите NO.
Давайте разберем, какие шаги выполняет установщик и заодно научимся работать с пулами. Описанные команды так же можно выполнять в ручном режиме, результат будет одинаковый.

Установщик автоматически создает три раздела GPT: один для загрузчика, раздел swap и основной раздел под пул.
Посмотрим для начала на структуру диска
# gpart show ada0 
Так удаляется старая таблица разделов
# gpart destroy ada0
Создается новая таблица GPT
# gpart create -s GPT ada0
Добавляются три раздела
# gpart add -s 512 -a 4k -t freebsd-boot -l boot0 ada0 
# gpart add -s 4g -a 4k -t freebsd-swap -l swap0 ada0 
# gpart add -a 4k -t freebsd-zfs -l disk0 ada0
Здесь с помощью опции -a задается выравнивание разделов по 4Кб. Если у вас старые винты с физическим сектором 512б, то опцию пропускаем.

Устанавливается загрузчик
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
Здесь используются два загрузчика, первый pmbr в области Protective MBR перед GPT, он передает управление второму gptzfsboot, он на первом секторе раздела freebsd-boot. А уже на третьем этапе вызывается loader.

Если вдруг вы решите не использовать ZFS, а вернетесь к UFS, то надо использовать другой загрузчик
# gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 da0
Для работы с ZFS загружаем модуль
# kldload zfs
При использовании дисков с сектором 4К важно задать размер блока ZFS.  Поскольку диск для совместимости рапортует о секторе 512Б. И по умолчанию такой размер выбирается автоматически для блока при создании пула.  Поэтому обязательно перед созданием пула нужно сделать следующее!

Поверх диска создается устройство gnop с размером сектора 4К
# gnop create –S 4096 /dev/gpt/disk0
Создается пул
# zpool create -o altroot=/mnt -O canmount=off -m none zroot /dev/gpt/disk0.nop
Отсоединяется пул
# zpool export zroot
Удаляется устройство gnop
# gnop destroy /dev/gpt/disk0.nop
Снова присоединяется пул
# zpool import zroot
Проверяем, если ashift=12, то блок установлен правильно 2^12=4К. Если 9, то 2^9=512Б.
# zdb –C tank | grep ashift
Так же в FreeBSD 10  размер блока ZFS можно задать проще, с помощью 
# sysctl vfs.zfs.min_auto_ashift=12 
Сделать это нужно так же перед созданием пула и добавить в /etc/sysctl.conf, что бы не делать это вручную каждый раз в будущем.

Задаем алгоритм проверки контрольных сумм fletcher4, по умолчанию используется fletcher2.
# zfs set checksum=fletcher4 zroot
Запрещаем обновление времени доступа при каждом обращении к файлу.  
# zfs set atime=off zroot
Создаем файловые системы
# zfs create -o mountpoint=none zroot/ROOT 
# zfs create -o mountpoint=/ zroot/ROOT/default 
# zfs create -o mountpoint=/tmp -o compression=lzjb -o setuid=off zroot/tmp 
# chmod 1777 /mnt/tmp
# zfs create -o mountpoint=/usr zroot/usr zfs create zroot/usr/local
# zfs create -o mountpoint=/home -o setuid=off zroot/home
# zfs create -o compression=lzjb -o setuid=off zroot/usr/ports

# zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/distfiles 

# zfs create -o compression=off -o exec=off -o setuid=off zroot/usr/ports/packages
# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/usr/src 

# zfs create zroot/usr/obj
# zfs create -o mountpoint=/var zroot/var 

# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/crash 
# zfs create -o exec=off -o setuid=off zroot/var/db 
# zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/db/pkg 
# zfs create -o exec=off -o setuid=off zroot/var/empty 
# zfs create -o compression=lzjb -o exec=off -o setuid=off zroot/var/log 
# zfs create -o compression=gzip -o exec=off -o setuid=off zroot/var/mail 
# zfs create -o exec=off -o setuid=off zroot/var/run 
# zfs create -o compression=lzjb -o exec=on -o setuid=off zroot/var/tmp 
# chmod 1777 /mnt/var/tmp
Указываем корневую ФС.
# zpool set bootfs=zroot/ROOT/default zroot
Добавляем swap раздел в fstab
# vi /tmp/bsdinstall_etc/fstab
--# Device        Mountpoint FStype Options Dump Pass# 

/dev/gpt/swap0  none       swap   sw      0    0
После того как будут созданы все файловые системы, если выполняли в ручном режиме, то нужно выйти из shell, пишем exit. Далее установка продолжается, как обычно.

Так же для ручного режима, перед перезагрузкой нужно еще раз зайти в shell и прописать автоматическое монтирование файловых систем.
# mount -t devfs devfs /dev 
# echo 'zfs_enable="YES"' >> /etc/rc.conf 
# echo 'zfs_load="YES"' >> /boot/loader.conf
Для порядка зададим только чтение для /var/empty, поскольку она всегда должна быть пустой.
# zfs set readonly=on zroot/var/empty 
На этом установка завершена.  Но, если вам хочется добиться лучшей производительности можно настроить еще некоторые параметры.

Способы оптимизации сильно зависят от назначения вашей системы и будут отличаться для БД, вэб-сервера и файлового сервера. В числе основных рекомендаций, можно найти такие, отключение обновления времени доступа при каждом обращении atime (мы уже это сделали), иметь как можно меньше снимков состояний,  использовать для ZIL и L2ARC отельные SSD диски. Использовать для файловых систем разные recordsize, соразмерно хранимым на них файлам. Если много мелких файлов, то recordsize лучше сделать 16Кб, а по умолчанию он 128Кб.
# zfs create -o recordsize=8k tank/mysql
Есть конечно и параметры, влияющие работу в целом. Рассмотрим их.

Как вы знаете на i386 архитектуре ядро FreeBSD по умолчанию  резервирует под все свои нужды всего 1Гб адресного пространства из 4 возможных, а остальное оставляет процессам. Но, если в ядре есть такой большой потребитель оперативной памяти, как ZFS, то его может и не хватить!  Поэтому нужно увеличить это значение хотя бы до 2Гб, добавив в ядро опцию.
options KVA_PAGES=512 
(размер страницы — 4 Кб)*512=2Гб.
Но после пересборки ядра, во время загрузки, у меня начались "double fault panic". Как оказалось, проблема распространенная и многие пользователи ZFS на i386 архитектуре наблюдают переполнение стека ядра. Это начало происходить с того момента, как Clang сделали компилятором по умолчанию. Для того, что бы этого избежать нужно добавить еще одну опцию.
options KSTACK_PAGES=4
Или задать в /etc/sysctl.conf параметр
kern.kstack_pages=4
На amd64 проблем с нехваткой адресного пространства нет. Там по умолчанию отвели ядру 512 Гб  виртуальных адресов, поэтому вышеописанное не потребуется.

Теперь, когда виртуальное адресное пространство ядра KVА (Kernel Virtual Address space) увеличено, надо этим поделиться с ZFS. В /boot/loader.conf добавляем параметры
vm.kmem_size="1G" 
vm.kmem_size_max="1G"
kmem - это участок KVA, который используется для динамического выделения памяти malloc, и соответственно он будет использоватьcя ZFS.

ARC
Еще одним важным параметром влияющим на быстродействие ZFS является размер кэша адаптивной замены ARC (Adjustable Replacement Cache). Это очень быстрый кэш, расположенный в ОЗУ, построенный на двух алгоритмах MRU им MFU. Общий смысл его заключается в том, что бы обеспечить доступ к наиболее часто используемым данным прямо из памяти, а не с медленного диска. И поэтому, чем у вас больше оперативной паями, тем лучше для ZFS. 

По умолчанию ARC разрешается использовать всю свободную память по необходимости, кроме 1Гб зарезервированного ядром. Но если если у вас категорическая не хватка паями и ее обязательно надо оставить для других важных задач, то имеет смысл ограничивать размер кэша
vfs.zfs.arc_max="512M"
Если этого не сделать, то может произойти kernel panic по причине отсутствия свободного пространства. Поэтому проверяйте
# sysctl vm.kvm_free
Так же есть дешевый способ увеличить размер кэша при помощи обычной флешки. Изначально для этого задумано использовать SATA SSD-диски. Это называется вторым уровнем кэша L2ARC. В этой статье человек делится опытом подключения флешки 1G в качестве L2ARC.
# zpool add pool cache device
# zpool remove pool device
Но в виду того, что пропускная способность шины USB 2.0 ниже, чем у механических жестких дисков: 30 против 100 Мбайт/сек, то в качестве полноценного кэша старая флешка не годиться. Да и быстро выйдет из строя из-за постоянной перезаписи и отсутствия механизма выравнивания износа. Тем не менее сгодится для домашнего использования при малой нагрузке. Ведь время поиска (seek time) y флешек гораздо меньше, чем у дисков и составляет от 1 до 3 мсек, против 12 мсек. Поэтому прирост скорости можно получить только на произвольном (не последовательном) чтении данных. И лучше хранить на ней только метаданные, это позволит прослужить ей дольше.
# zfs set secondarycache=metadata pool
Что касается usb 3.0, то там полезная скорость возросла до 500 Мбайт/с и возможно такие флешки уже пригодны, но надо тестировать.

ZIL
На случай потери данных при сбоях и отключении питания некоторые приложения (например, NFS и БД) используют синхронную запись данных. Для этих целей у ZFS имеется целевой журнал ZIL (ZFS Intent log). Когда приложение хочет записать данные на диск, оно отправляет запрос ОС и ждет ответа. ОС сначала кэширует данные в ROM,  затем сохраняет их в ZIL и только после этого возвращает управление приложению. При этом ZIL обязательно должен находиться в энергонезависимой памяти и по умолчанию располагается на диске внутри пула. Вот это и является узким местом при увеличении производительности. Но ZFS позволяет использовать в качестве log-устройства отдельные диски или даже несколько дисков одновременно.  Поэтому обязательно обзаведитесь  быстрым  SSD-диском.
# zpool add pool log c2d0
В особых случаях, если нет SSD, то ZIL лучше отключить, производительность возрастет, но появится опасность потери данных при записях во время сбоев.
В /boot/loader.conf добавляем
vfs.zfs.zil_disable="1"
Еще можно отключать zil отдельно для каждой файловой системы.
# zfs set sync=disabled pool/name

Теперь рассмотрим функциональность и познакомимся с основными командами для управления ZFS.

Здесь все просто, для работы с пулами используется утилита zpool, а с файловыми системами - zfs. Они имеют смысловые команды типа create, desptoy, attach, deattach и т.д.

Работа с пулами
Пулы создается командой 
# zpool create pool /dev/ada0
Если пул не загрузочный, то можно использовать весь диск целиком без GPT разбивки.
Удаляется пул командой 
# zpool destroy pool
Вывести список подключенных пулов
# zpool list
Узнать состояние
# zpool status pool
Отсоединить пул
# zpool export pool
Присоединить
# zpool import pool
Если использовать команду import без параметров, то получите список доступных пулов.

Добавить дополнительный диск к пулу
# zpool add pool ada3
Присоединяем зеркало. Диски должны быть одинакового размера, иначе по меньшему. После этого начнется resilvering, процесс синхронизации.
# zpool attach pool /disk /new-disk
Отсоединяем зеркало
# zpool detach pool /disk
Замена одного устройства на другое
# zpool replace pool /disk /new-disk
После завершения выполнения команды диск отключается от конфигурации и может быть удален из системы.

Посмотреть все  параметры пула можно так
# zpool get all
Файловые системы
Создание файловой системы в пуле осуществляется командой
# zfs create pool/name
По умолчанию каждая созданная ФС монтируется в одноименный каталог. Но точку монтирования можно указать и другую.
# zfs set mountpoint=/new/puth pool/name
Все созданные файловые системы монтируюся автоматически при присоединении пула, поэтому их не надо прописывать в fstab.

Монтирование файловой системы в пул
# zfs mount myzfs/bob
# zfs unmount myzfs/bob
Файловая система созданная внутри другой наследует ее свойства. К ним относится алгоритм сжатия и алгоритм вычисления контрольных сумм, размер блока, квота и мн. др. Посмотреть все свойства  можно по команде
# zfs get all
Зарезервировать место для файловой системы
# zfs set reservation=100G pool/name
Задать квоту
# zfs set quota=50G pool/name
Квоты можно задавать отдельно для групп и пользователей
# zfs set userquota@user=5G pool/name
# zfs set groupquota@group=10G pool/name 
Смотреть общую информацию по использованию квот можно так
# zfs userspace pool/name
# zfs groupspace pool/name
или конкретно для каждого
# zfs get userused@user pool/name
# zfs get groupused@group pool/name
ZFS предлагает  очень удобный механизм резервного копирования. Для этого используются снимки и клоны.

Снимок - это копия состояния ФС, хранящаяся прямо в пуле и по началу совсем не занимающая места. Но по мере изменения данных снимок начинает расти, поскольку продолжает ссылаться на старые данные и препятствует их удалению. Поэтому рекомендуется хранить минимальное число снимков.

Получить прямой доступ к снимкам нельзя. Их можно только клонировать, создавать резервные копии, выполнять откат и др. Создается снимок так
# zfs snapshot pool/name@snap_name
если указать параметр рекурсии -r, то создаются снимки всех дочерних ФС. Располагаются в директории .zfs/snapshot в корне каждой файловой системы.
# zfs snapshot -r pool/name@now
Удалить снимок 
# zfs destroy pool/name@snap_name
Можно переименовывать снимки
# zfs rename pool/name@old_name new_name
Вывести список всех снимков 
# zfs list -t snapshot
Выполнить откат к снимку
# zfs rollback pool/name@snap_name
ФС предварительно должна быть размонтирована. Все изменения, а так же созданные снимки после будут удалены и система вернется к состоянию на момент снимка.

На основе снимков можно создавать клоны.
# zfs clone pool/name@yesterday pool/clone
Уничтожить клон
# zfs destroy pool/clone
Можно выполнить замену исходной файловой системы на клон.
# zfs promote pool/clone
NFS
Есть удобный механизм добавления ресурсов в NFS. Для этого сперва нужно убедиться, что у вас запущены службы NFS. В /etc/rc.conf пишем

nfs_server_enable="YES"
nfs_server_flags="-u -t -n 4"
rpcbind_enable="YES"
mountd_enable="YES"
mountd_flags="-r"
Что бы добавить общий ресурс используется следующий синтаксис.
# zfs set sharenfs=on pool/name
Ресурс будет доступен всем для записи и чтения и свойства автоматически наследуются для всех дочерних файловых систем. В качесте параметров sharenfs можно использовать все опции доступные в exports.

Что бы задачть только для чение, то указывается опция ro
# zfs set sharenfs=ro pool/name 
Если у ресурса установлен признак sharenfs, то его можно включать и отключать командами share и unshare.
# zfs share -a
# zfs unshare pool/name
# zfs unshare -a
Как только опция sharenfs меняется, служба mountd перезагружается автоматически.

Если нужно разрешить доступ только конкретным сетям или адресам, то так


# zfs set sharenfs="-maproot=root -alldir -network 10.0.0.0 -mask 255.255.255.0 192.168.15.2 192.168.10.5" zroot/share
Посмотеть все расшаренные ресурсы
# zfs get sharenfs 
На стороне клиента ресурс монтируется следующим образом
# mount -t nfs server_ip:/pool/name /mnt
Для втоматического монтирования в /etc/fstab нужно добавить
server_ip:/pool/name /mnt nfs rw 2 2
Еще бывает полезно посмотреть активность дисков в реальном времени.
# gstat -a 

22 октября 2014

SFTP, FTPЕS и тонкая настройка ProFTPD

    Традиционный способ передачи файлов по протоколу FTP уже считается устаревшим и небезопасным. Есть более совершенные альтернативы, например, SFTP, SCP, FTPS и WebDAV.  Но тем не менее для анонимного доступа обычный FTP вполне сгодится. Еще одна причина, по которой отказаться от FTP полностью пока нельзя, отсутствие в windows встроенной поддержки безопасных FTP. 

В этой статье описываются принципы правильной настройки сервера ProFTPD с виртуальными пользователями, перекодировкой в cp1251 и поддержкой протоколов FTPS (FTP Secure) и SFTP (Secure File Transfer Protocol). Как вы можете видеть из названий, один - безопасность протокола, а другой - безопасный протокол. В этом их кардинальное отличие!

FTPS является обычным FTP поверх SSL/TLS, как HTTPS. Есть две его разновидности: Implicit FTPS - соединение устанавливается через дополнительный порт SSL 990 и Explicit FTPS или сокращенно FTPES, это уже более новая версиякоторый сейчас всеми и ипользуется, соединение и управление по одному стандартному порту 21.

А вот SFTP это абсолютно новый протокол, разработан с нуля, основан на SSH2 и не имеет с FTP ничего общего. У него больше возможностей, например есть докачка файлов после разрыва соединения. В рамках SSH шифруется все. Конечно скорость передачи у SFTP будет меньше чем у чистого FTP или FTPS.

Я провел сравнение на 100 Мбитной сетке: FTP ~ 10 МБ/с, SFTP ~ 3 МБ/с. У FTPS такая же скорость, как и у обычного FTP. Еще для сравнения я проверил SFTP, встроенный в openssh, там скорость оказалась порядка 7 МБ/с. Почему такая разница по сравнению с proftp сказать сложно, видимо в самой реализации sftp. Попробуйте сравнить у себя, будет интересно узнать, как у вас.

Поэтому, наверно все таки, есть смысл использовать sftp-server от OpenSSH. 

Имеем FreeBSD 10, что бы сэкономить время устанавливаем из пакета.
# pkg install proftpd

proftpd.conf
Конфигурационный файл находится в /usr/local/etc/proftpd.conf. Откройте и редактируйте его под себя по ходу чтения статьи.
 
Сервер запускается через inetd или автономно.
ServerType standalone
Рекомендуется создать специального пользователя и группу FTP для запуска службы. Пароль можно сделать пустым.
# adduser ftp
и изменить в конфиге
User ftp
Group ftp
По умолчанию сервер слушает все интерфейсы, что бы указать только заданные адреса, используются директивы
DefaultAddress 192.168.20.1 192.168.30.1
SocketBindTight on
По желанию в виртуальных хостах можно переопределить другой адрес.
  
Для того, что бы включить перекодировку с UTF-8 на CP1251 нужно обязательно задать LangPath
LangEngine   on
LangPath     /usr/share/locale
UseEncoding  UTF-8 WINDOWS-1251
Что бы задать пользователю корневую директорию, за пределы, которой он не должен выходить, используется
DefaultRoot ~ 
знак "~" сообщает, что  будет использоваться домашняя директория пользователя.

Если нужно сделать исключение из правил и дать некоторым пользователям полный доступ к chroot директории, то создаете группу, например admins и пишете
DefaultRoot ~ !admins
Для управления анонимным доступом в конфигурациооном файле есть секция
<Anonymous ~ftp>
  User ftp
  Group ftp
  UserAlias anonymous ftp
  <Limit WRITE>
    DenyAll
  </Limit>
</Anonymous>
Если у вас используются виртуальные хосты, то эту секцию лучше вынести в <Global>, что бы анонимный вход был доступен на всех ip, а не только на основном!

Виртуальные пользователи
По умолчанию для аутентификации пользователей proftp смотрит файл /etc/passwd.  Но использование виртуальных пользователей безопаснее, поскольку это не позволяет злоумышленнику перехватить системные аккаунты, которые передаются в открытом виде! Для этого используются директивы AuthUserFile и AuthGroupFile в конфигурационном файле.
AuthUserFile /usr/local/etc/proftpd/ftpd.passwd
AuthUserFile используется в дополнение к passwd и не исключает его. Но если все таки нужно его запретить, то используйте AuthOrder.
AuthOrder mod_auth_file.c
Форматы файлов AuthUserFile и AuthGroupFile такие же, как /etc/passwd и /etc/group соответственно.
username:password:uid:gid:gecos:homedir:shell
groupname:grouppasswd:gid:member1,member2,...memberN
Для создания и изменения этих файлов используется специальный скрипт ftpasswd. Первый параметр, который надо задать, это --passwd или --group. Потом --name, --uid, --home и --shell. Например,
# ftpasswd --passwd --name=bob --uid=1001 --home=/home/bob --shell=/bin/false
Uid должен быть от реального пользователя, например от ftp, таким образом из одного реального пользователя создается много виртуальных.

После выполнения ftpasswd создается файл ftpd.passwd. Для создания файла с другим именем и расположением используется опция --file.

Аналогично для групп
# ftpasswd --group --name=group-name --gid=group-id --member=user-member1 \ --member=user-member2 ... --member=user-memberN
Так же можно использовать параметр --hash для вычисления хэша либо пароля.
По умолчанию proftp не пускает пользователей у которых шел не перечислен в файле /etc/shell. Поэтому, если вы используете недействительный шел, например /usr/sbin/nologin, то обязательно задайте директику RequireValidShell off. 

Ограничение доступа
У proftpd есть удобный механизм ограничения доступа. Создаются различные правила для клиента на выполнение FTP команд. Это может быть запрет на переименование, удаление, запись файлов в определенную папку и др. (полный список можно посмотреть на сайте).

Для создания правил в конфигурационном файле указывается секция <Limits>... </Limits> с нужными командами. Их можно просто перечислить или использовать группы ALL, DIRS, LOGIN, READ и WRITE.

Затем внутри секции определяется действие: разрешить или запретить: DenyAll, AllowAll, AllowUser, AllowGroup, Deny from, Allow from. Их порядок играет имеет значение, если порядок "Allow,Deny", то разрешающее правило важнее, если наоборот "Deny,Allow", то запрет.

Например,  следующие команды разрешают смену директории и загрузку файлов в эту директорию, при условии, что файловая система так же имеет соответствующие разрешения.
<Limit ALL>
  DenyAll
</Limit>
<Limit CDUP CWD PWD XCWD XCUP>
  AllowAll
</Limit>
<Limit STOR STOU>
  AllowAll
</Limit>  
Для этой цели можно использовать группу WRITE, но тогда пользователь сможет так же создавать и удалять поддиректории.

Или еще один пример, разрешается авторизация только двум пользователям и группе.
<Limit LOGIN>
  AllowUser barb
  AllowUser dave
  AllowGroup ftpuser
  DenyAll
</Limit>
Поскольку активный режим работы FTP-сервера не безопасен, это когда сервер должен сам подключиться к клиенту. То его можно отключить средствами <Limits>.
<Limit EPRT PORT>
  DenyAll
</Limit>
Обычно <Limits> удобно использовать внутри секции <Directory>, тогда все вложенные поддиректории будут наследовать свойства. Следующий пример описывает папку, у которой нельзя увидеть содержимое, но можно загружать и скачивать файлы.
<Directory /path/to/dir>
  <Limit LIST NLST MLSD MLST STAT>
   DenyAll
  </Limit>
</Directory>
Если в пути вы указываете  суффикс /*, то это означает, что конфигурация применяется только для содержимого, но не для самой папки.

Пример, назначается папка для загрузок для анонимного доступа.
<Anonymous ~ftp>
 User ftp
 Group ftp
 UserAlias anonymous ftp
 <Limit WRITE>
  DenyAll
 </Limit>
 <Directory upload/*>
  <Limit STOR>
    AllowAll
  </Limit>
 </Directory>
</Anonymous>
В ftp протоколе команда STOR служит для аплоада файлов клиентом.

Еще можно использовать классы для группировки пользователей.
<Class internal>
  From 192.168.0.0/16
  From *.example.com
</Class>
А потом назначить действия сразу целым классам с помощью AllowClass и DenyClass.
<Limit ALL>
  AllowClass internal
  DenyAll
</Limit>
По умолчанию proftpd слушает все интерфейсы, но если надо только один, то используйте параметр DefaultAddress.

Сервер за NAT
Особый случай, если ваш ftp-сервер находится за NAT и вы хотите предоставить к нему доступ извне. Для этого вам надо задать опцию MasqueradeAddress с ip-адресом nat-сервера. А на NAT-сервере настроить форвардинг порта 21 и диапазона портов для пассивного режимакоторые задаются в конфиге PassivePorts 40000-45535. 

Но как только вы зададите опцию MasqueradeAddress, пользователи из локальной сети не смогут больше подключаться! Выходом из этой ситуации будет использование данной опции не в глобальных настройках, а на виртуальном хосте.
<VirtualHost your_local_ip>
  MasqueradeAddress nat_ip
  Port 1121
</VirtualHost>

Теперь FTP-сервер, кроме 21, еще будет работать на 1121 порту. На NAT-сервере настраиваем перенаправление портов. В моем случае это ядерный NAT.
nat 1 config log if rl0 reset same_ports deny_in redirect_port tcp 192.168.15.2:1121 21 redirect_port tcp 192.168.15.2:40000-45535 40000-45535
add 1085 nat 1 ip from any to any via rl0
Один важный момент, в списке правил перед строкой nat не должно быть явно разрешающих правил для используемых портов, т.е. таких
1030 allow tcp from any to me 21, 20, 40000-45535 
Иначе пакеты не дойдут до nat и соответственно не будут перенаправляться. Была у меня такая проблема, долго не мог понять почему не работает ftp через nat, а они просто напросто не доходили до редиректа.

Еще, если вы пытаетесь таким же способом редиректить штатный фряшный ftpd через ipfw, то ничего не получится! У него нет такой замечательной опции MasqueradeAddress. В этом случае надо использовать ftp-proxy.

Теперь внутри локальной сети FTP сервер будет работать, как обычно на 21 порту. Из вне доступ так же будет по 21 порту через nat-сервер, благодаря форвардингу  redirect_port tcp 192.168.15.2:1121 21.

Виртуальные хосты
Это возможность организовать одновременно несколько ftp-серверов на одном. Они называются виртуальными. Но имейте в виду, что протокол FTP не поддерживает виртуальные хосты на основе имен. Например, нельзя создать soft.server.ru и video.server.ru, как в Apache. FTP виртуальные хосты могут быть основаны только на уникальности пары IP/порт.

Поэтому, если ваш сервер имеет несколько ip-адресов, например, локальная сеть и внешняя, то для каждой из них нужно настроить виртуальные хосты. Это делается с помощью секции  <VirtualHost>.

<VirtualHost 10.0.0.1>
   ServerName "My local FTP server"
</VirtualHost>
<VirtualHost 1.2.3.4>
   ServerName "My
external FTP server"
</VirtualHost>
 
Так же можно использовать виртуальные хоcты с одинаковым ip-адресом, но на разных портах.
<VirtualHost myhost.mydomain.com>
  Port 2001
  ...
</VirtualHost>
  
 
Все глобально установленные параметры в конфигурационном файле не относятся к виртуальным хостам, их нужно задавать отдельно для каждого! Поэтому ради удобства, что бы не дублировать общие параметры в каждом виртуальном хосте, их можно вынести в секцию  <Global>, тогда они будут доступны для всех.

В <Global> так же следует вынести секцию <Anonimous ~>

Таким образом, с помощью виртуальных хостов, мы одновременно запустим ftp, sftp и ftps на разных портах.

Но для этого сначала нужно перекомпилировать ptoftpd с дополнительными модулями.
#./configure --with-modules=mod_sftp:mod_tls:mod_sql:mod_sql_mysql \
--with-includes=/usr/local/include/mysql \
--with-libraries=/usr/local/lib/mysql
# make
# make install
Выяснилось, что в портах Freebsd, начиная c версии 1.3.4 Proftpd стал использовать динамически подключаемые модули. Поэтому пересборка не требуется, достаточно указать директиву LoadModul в proftpd.conf.

Выносим общие параметры в секцию
<Global>
   PassivePorts 40000 45535
   AuthUserFile /usr/local/etc/proftpd/ftpd.passwd
   RequireValidShell no
   MaxLoginAttempts 6
   LangEngine on
   UseEncoding UTF-8 WINDOWS-1251
   DefaultRoot ~ !admins
</Global>
Подгружаем SFTP модуль
LoadModule mod_sftp.c
И добавляем виртуальный хост
<VirtualHost 192.168.10.1>
  MasqueradeAddress myhost.mydomain.com
  SFTPEngine on
  Port 8022
  SFTPHostKey /etc/ssh/ssh_host_dsa_key
  SFTPHostKey /etc/ssh/ssh_host_rsa_key
  SFTPHostKey /etc/ssh/ssh_host_ecdsa_key
  SFTPLog /var/log/sftp.log
  SFTPCompression off
</VirtualHost>
Подгружаем TLS модуль
LoadModule mod_tls.c
Добавляем виртуальный хост
<VirtualHost 192.168.10.1>
MasqueradeAddress
myhost.mydomain.com
TLSEngine on
Port 1021
TLSLog /var/log/tls.log
TLSProtocol SSLv23
TLSRequired auth
TLSOptions NoCertRequest
TLSRSACertificateFile /usr/local/etc/proftpd/ssl/cert.pem
TLSRSACertificateKeyFile /usr/local/etc/proftpd/ssl/key.pem
TLSVerifyClient off

</VirtualHost>
Параметр TLSRequired определяет политику безопасности, когда использовать SSL/TLS и может иметь несколько значений:
  • off - Клиенты могут подключаться, как по обычному FTP, так и используя шифрование,
  • ctrl - шифруется только управляющий канал, поэтому пароли будут спрятаны,
  • data - шифруются только данные (не рекомендуется),
  • on - шифруются оба канала,
  • auth - шифрование управляющего канала, но только в момент авторизации,
  • auth+data - шифрование авторизации и данных, клиенту разрешается использовать команду CCC (Clear Command Channel), что позволяет лучше работать через фаервол.

Для FTPS еще нужно сгенерировать сертификат OpenSSL и положить в /usr/local/etc/proftpd/ssl/
# openssl req -new -x509 -days 365 -nodes -out /usr/local/etc/proftpd/ssl/cert.pem -keyout /usr/local/etc/proftpd/ssl/key.pem
Добавим автозапуск в rc.conf 
# echo 'proftpd_enable="YES"' >> /etc/rc.conf
Не забываем про ротацию логов
# vi /etc/newsyslog.conf
/var/log/proftpd.log 600 7 * @T00 JC
Чтобы запустить Proftpd используем команду
# service proftpd start
По умолчанию сервер пытается связать ip-адрес и имя хоста. Поэтому, если они не соответствуют действительности,  вы получите следующее сообщение при старте.
warning: unable to determine IP address of 'hostname'
Тут либо правильно настройте DNS, либо добавьте имя в файл /etc/hosts.
# vi /etc/hosts
192.168.10.5 your_domain_name 
Проверим, что слушаются 21, 1021 и 8022 порты.
# sockstat
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
ftp proftpd 87980 0 tcp4 *:21 *:*
ftp proftpd 87980 1 tcp4 *:8022 *:*
ftp proftpd 87980 2 tcp4 *:1021 *:*
Теперь можно подключаться любым клиентом, например, Filezilla, он понимает ftps, ftpes и sftp. Так же удобно использовать ftps/ftpes через Total Commander, но к нему еще нужно скачать OpenSSL библиотеки. Их можно взять тут, просто запустите установщик и он сам скопирует нуждные dll в системную папку. После этого в свойствах ftp-соединения станет доступной галочка SSL/TLS.

Что бы  посмотреть активных пользователей есть команда ftpwho.

Mysql
Кто хочет можно хранить пользователей в базе mysql. Для этого нужно поставить порт proftpd-mod_sql_mysql. Он автоматически установит mysql-client. Но mysql-server вам надо поставить самим.Кстати хороший мануал на русском языке есть на сайте mysql.ru. После установки нужно создать конфигурациооный файл my.cnf и положить его в /var/db/mysql/my.cnf. Шаблоны лежат тут /usr/local/share/mysql/. Можно восползоваться, например my-medium.cnf. В него я добавил такие параметры.
[client]
character_set_client=utf8

[mysqld]
character-set-server=utf8
init-connect="SET NAMES utf8"
skip-networking
#log-bin=mysql-bin
#binlog_format=mixed
Еще необходимо проинициализировать таблицы привилегий. 
# cd /usr/local
# ./bin/mysql_install_db
# chown -R mysql:mysql /var/db/mysql
Скрипт mysql_install_dbсоздает две базы данных: одна mysql, она обеспечивает привилегии доступа и другая test для тестирования.  Для пользователя root устанавливается  пустой пароль.
Добавляем в rc.conf строчку
# echo 'mysql_enable="YES"' >> /etc/rc.conf
Запускаем MySQL сервер
# service mysql-server start
Убеждаемся, что он запустился
# ps ax | grep mysql
15840 - Is 0:00,17 /bin/sh /usr/local/bin/mysqld_safe --defaults-extra-file
16374 - I 0:01,01 /usr/local/libexec/mysqld --defaults-extra-file=/var/db/
Устанавливаем пароль для пользователя root.
# /usr/local/bin/mysqladmin -uroot password 'password'
Заходим
# mysql -uroot -p'pasword'
Позднее пароль можно поменять так
mysql> use mysql;
mysql> update user set password=PASSWORD('my_password') where user='root' and host='localhost';
mysql> flush privileges;
mysql> quit
Чтобы каждый раз не вводить пароль его можно сохранить в файле .my.cnf
# touch /root/.my.cnf
# chmod 0600 /root/.my.cnf
# vi /root/.my.cnf
  [client]
  password=passwd
И для входа просто писать из под руда # mysql

Теперь нужно создать таблицы users и groups, где будут храниться пользователи. Но сначала создадим базу данных proftpd и пользователся ftp для подключения к базе.
mysql> CREATE DATABASE proftpd;
mysql> grant select,insert,update,delete on proftpd.* to ftp@localhost identified by 'password';
mysql> USE proftpd;
mysql> CREATE TABLE users (
userid VARCHAR(30) NOT NULL UNIQUE,
passwd VARCHAR(80) NOT NULL,
uid INTEGER,
gid INTEGER,
homedir VARCHAR(255),
shell VARCHAR(255) );
mysql> CREATE TABLE groups (
groupname VARCHAR(30) NOT NULL,
gid INTEGER NOT NULL,
members VARCHAR(255) );
Добавим нового пользователя для доступа к ptoftpd
mysql> insert into users values('new_user',ENCRYPT('passwd'),'5001','5001','/home/new_user','/sbin/nologin');
mysql> exit;
Изменить можно так
mysql> UPDATE users SET passwd=ENCRYPT('new_pass'), gid=14 WHERE userid='user';
Удалить так
mysql> DELETE FROM users WHERE userid='user';
Создаем домашний каталог пользователя
# mkdir /home/new_user 
# chown 5001:5001 /home/new_user
Настраиваем proftpd для авторизации через mysql
AuthOrder mod_sql.c
SQLConnectInfo proftpd@localhost:3306 ftp password
SQLAuthTypes Crypt
SQLUserInfo users userid passwd uid gid homedir shell
DefaultRoot ~
RequireValidShell off
SQLGroupInfo groups groupname gid members
SQLAuthenticate users groups

SQLLogFile /var/log/proftpd.log
Опцию SQLLogFile включается только на момент отладки, потом не забудьте ее закомментировать! 

Логирование
Еще, что касается логов. По умолчанию proftpd ведет логирование используя  syslog. Размещение определяется согласно /etc/syslog.conf в /var/log/xferlog.

Можно настраивать различные уровни логирования: err, notice, warn, info и debug, но они распространяются только на syslog.
SyslogLevel notice
Если хочется иметь отдельные файлы логов, то можно прописать:
TransferLog /var/log/proftpd-transfer.log
SystemLog /var/log/proftpd-error.log
ExtendedLog /var/log/proftpd-extended.log
Детализация варьируется от 0 до 9 - самая подробная.

DebugLevel 9
Можно перезагружать proftpd и проверять.
# service proftpd restart
Удачных, Вам, настроек!

15 октября 2014

Кодировка UTF-8



На вопрос какую кодировку лучше использовать? Ответ простой - выбирайте unicode, не ошибетесь! Это универсальный стандарт, символы выглядят одинаково везде и вы навсегда избавитесь от проблемы подбора правильной кодовой страницы и кракозябр.

А для совместимости со старыми однобайтовыми кодировками придуман формат UTF-8 (Unicode transformation format). 

По сути это ничто иное, как 8-битная форма записи юникода. Но позвольте, скажете вы, как же так? В юникоде около 110 000 разных символов, как они кодируются одним байтом? Давайте разбираться.

На самом деле не одним байтом. Здесь разные символы кодируются разным числом байтов, в зависимости от их кода или порядкового номера.  Как мы знаем, символы ASCII, кодируется всего 7 битами. И в юникоде они располагаются первыми. Поэтому, если байт начинается с 0, то это является признаком ASCII и символ кодируется только одним байтом.
0aaa aaaa
Но если символ имеет код больше 7 битов (128), то для его кодирования приходится использовать второй байт. Для этого в начале первого байта ставится признак "110" - две единицы, это значит два байта и ноль, как признак завершения кода размера. Второй байт обязательно начинается с "10" - это признак продолжения.
110x xxxx 10xx xxxx
Пример, имеем двухбайтовый символ  [11010000] [10011110], отбрасывая признаки, получаем 10000011110 = 0x41E, это символ большая кирилическая О.

Если код символа занимает больше 11 бит (2048), то ставится признак "1110" и используют третий байт, в начале которого так же ставят признак продолжения "10".
1110 xxxx 10xx xxxx 10xx xxxx
И так далее до 6 байт.
Вот такой простой принцип кодирования.

Но на Freebsd почему то все еще используется KOI8-R. Поэтому после того, как вы осознали пользу от Unicoda, давайте установим ее в качестве локали.  Но пользоваться ею нормально можно будет только в удаленной консоли, например по ssh. В системной это не будет работать!

Если вы используете шелл по умолчанию, то для обычных пользователей это sh, а для root - csh.

Что бы узнать свое окружение дайте команду
# echo $shell
или посмотрите в /etc/passwd

Для смены кодировки csh достаточно в файле /etc/csh.cshrc прописать переменные
setenv LANG ru_RU.UTF-8
setenv LC_CTYPE ru_RU.UTF-8
setenv LC_COLLATE POSIX
setenv LC_ALL ru_RU.UTF-8
Для  bash в файле /etc/profile дописываем

LANG="ru_RU.UTF-8"; export LANG
LC_CTYPE="ru_RU.UTF-8"; export LC_CTYPE
LC_COLLATE="POSIX"; export LC_COLLATE
LC_ALL="ru_RU.UTF-8"; export LC_ALL'
 Переподключайтесь и любуйтесь русскими символами!

23 сентября 2014

АОН и Caller ID

Имеется у меня старенький аон (определитель номера) в виде специальной приставки для телефона, называется ЛАРТ-Евро. Приобретался он относительно давно и предназначался для адаптации зарубежных телефонов с функцией Caller ID к российским импульсным телефонным линиям. Сейчас, в свете последних достижений телефонии, дело с этим обстоит иначе и я озадачился вопросом, а нужен ли он вообще?

Для определения номеров входящих вызовов на стационарных телефонах в России используются два стандарта: аналоговый "русский АОН" и цифровой "Caller ID". Естественно они отличаются алгоритмом работы и способом кодирования информации.

Первый является элементом советского наследия. В то время передача номера вызывающего абонента использовалась чисто для служебных целей, для тарификации междугородних вызовов и спецслужб.  И до 2001 года применение АОН вообще было нелегальным.
Тем не менее такие устройства все еще работают, но определяют уже все меньшее количество номеров. Поскольку они зависит от технической возможности АТС выдавать такую информацию. А многие из них уже отказываются от аналогового и полностью переходят на цифровой стандарт.

Стандарт Caller ID специально разрабатывался, что бы предоставлять абонентам услугу по получению входящего номера. И большинство современных импортных телефонов поддерживают этот стандарт де факто. На сегодняшний день все цифровые АТС уже предоставляют такую услугу за отельную плату.

Caller ID несомненно удобнее: 
  1. Он показывает полностью все цифры номера в международном 10-значном формате. Отечественный АОН максимально только 7 цифр. 
  2. Абонент идентифицируется до установления соединения,  между первым и вторым сигналами вызова. Для АОН необходимо снятие трубки или автоматическая имитация этого с фиктивными длинными гудками. И в этом случае идет оплата за звонок.
  3. Точность определения номера составляет 100%. У АОН это сильно зависит от линии связи и часто номера определяются с ошибками.
Таким образом можно сделать вывод, что отечественный АОН является устаревшим стандартом, как и импульсный набор номера. Поэтому, если ваша АТС поддерживает цифровой режим, то использование ЛАРТ-Евро не целесообразно. Поскольку он определяет номер звонящего по технологии аналогового АОН и преобразовывает в стандарт Caller ID.
Пожалуй единственным оправданием использования будет отсутствие дополнительной платы.

Обратите внимание, что в отличии от ЛАРТ-202, у которого имеется перемычка для задания 6 или 7-значных номеров, ЛАРТ-Евро полностью программируемое устройство и никаких перемычек у него нет.
Его можно настраивать на работу в АТС с номерами от 4 до 7 цифр, отображение даты и времени звонков, срабатывание после определенного числа звонков. Адаптер питается он телефонной линии и при отключении все параметры стираются и требуется повторная настройка!
Поэтому для тех, кто все еще продолжает его использовать, выкладываю инструкцию, возможно у кого-то она уже потерялась (нажмите, чтобы увеличить).

17 сентября 2014

Контакты Google на iPhone


Большинство пользователей айфонов послушно синхронизируют свои контакты с iCloud. Но  у активных пользователей Google есть потребность использовать их сервис Контакты. Ведь с тех пор, как они добавили поддержку протокола CardDAV, синхронизация стала более универсальной. С его помощью вы так же можете обмениваться контактами и с другими не яблочными устройствами. 

Теперь главный вопрос, как перенести контакты с iphone на google?

Если в Настройках в разделе "Почта, адреса, календари" вы добавите новую учетную запись Google, то увидите, что там есть возможность синхронизировать Контакты.

Еще в разделе "Почта, адреса, календари" есть пункт "Стандартная уч. зап.", нужно выбрать Google.

Вот теперь синхронизация заработает в полную силу. И когда вы будете создавать новые контакты, они автоматом появятся в контактах гугл.

Но только уже существующие контакты автоматически не добавятся! Айфон упорно разделяет их на разные группы: Все Gmail и Все iCloud и не хочет объединять.

Поэтому перенести контакты из iCloud в Google придется вручную с помощью vCard.

Для этого вам нужно зайти на сайт icloud.com под своей учетной записью, в левом нижнем углу выбрать все контакты и нажать экспорт vCard.
Затем зайти на сайт gmail.com, на панели справа переключиться в режим Контакты и выбрать импорт контактов.
И в предложенном окне загрузить сохраненный файл из icloud.
Поздравляю вы перенесли все контакты из icloud в google.
Теперь чтобы не путаться, контакты icloud лучше отключить. Поскольку синхронизация сразу на двух сервисах  пока не возможна
Еще один момент, фотографии в карточках vCard не хранятся,  их придется добавлять по новой.

К сведению обратная процедура переноса контактов из google в icloud с помощью vcard тоже возможна.