Заметки о работе с ОС FreeBSD. Статьи об установке и настройке ПО для FreeBSD.

30 октября 2008 г.

Создаем самоподписанный SSL-сертификат

Для начала нам нужно создать приватный ключ, который мы будем использовать для создания CSR- или CRT-сертификатов.

[root@test248 ~]# openssl genrsa -out ca.key 1024
Generating RSA private key, 1024 bit long modulus
Затем создаем CSR-сертификат:
[root@test248 ~]# openssl req -new -key ca.key -out ca.csr
После чего нам зададут несколько вопросов:
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:RU
Locality Name (eg, city) []:Saint-Petersburg
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test Co Ltd
Organizational Unit Name (eg, section) []:IT Department
Common Name (eg, YOUR name) []:test248.domain.com
Email Address []:itdepartment@domain.com

A challenge password []:Pa$$w0rd
An optional company name []:Test Co Ltd
Далее создаем самоподписанный сертификат:
[root@test248 ~]# openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
Signature ok
subject=/C=RU/ST=RU/L=Saint-Petersburg/O=Test Co Ltd/OU=IT Department/CN=test248.domain.com/emailAddress=itdepartment@domain.com
Getting Private key
Параметр: "-days 365" - количество дней, которые будет действовать сертификат

В итоге мы получили файл ca.crt, который мы можем использовать с, например, Apache или Dovecot для осуществления защищенных соединений с клиентами.

28 октября 2008 г.

Установка и настройка Exim 4.69

Задача: установить и настроить Exim 4.69 (последния в портах версия на момент написания статьи).
Итак, имеем FreeBSD 6.3:

[root@mail /var/mail]# uname -mrs
FreeBSD 6.3-RELEASE i386

Включаем/выключаем нужные опции (посмотреть весь список можно в Makefile).
.if ${.CURDIR} == ${PORTSDIR}/mail/exim
WITH_MYSQL=             yes
LOG_FILE_PATH?=         syslog
WITH_CONTENT_SCAN=      yes
WITH_DEFAULT_CHARSET?=  koi8-r
WITHOUT_IPV6=           yes
WITHOUT_NIS=            yes
.endif

[root@mail /usr/ports/mail/exim]# make install clean

В /etc/rc.conf прописываем следующие строки:
sendmail_enable="NONE"
exim_enable="YES"
Меняем файл /etc/mail/mailer.conf на следующий:
[root@cisco3 /etc/mail]# cat mailer.conf
sendmail /usr/local/sbin/exim
send-mail /usr/local/sbin/exim
mailq  /usr/local/sbin/exim -bp
newaliases /usr/local/sbin/exim -bi
hoststat  /usr/local/sbin/exim
purgestat /usr/local/sbin/exim

Файл /usr/local/etc/exim/configure:

# Основное имя хоста
primary_hostname = mx1.domain.ru

# Параметры подключения к БД в формате "хост/имя_базы/пользователь/пароль"
hide mysql_servers = db_host/exim/exim/PASSWORD

# Список локальных доменов
domainlist local_domains = ${lookup mysql{SELECT domain FROM domain WHERE domain='${domain}' AND active='1'}}

# Список доменов/хостов, для которых хост является входящим релеем
domainlist relay_to_domains = ${lookup mysql{SELECT domain FROM domain WHERE domain='${domain}' AND active='1'}}
# Список доменов/хостов, для которых хост является исходящим релеем. Т.е. без авторизации. hostlist relay_from_hosts = localhost : 127.0.0.0/8 : 192.168.0.0/16

# Включаем ограничения (будут объявлены ниже, в секции ACL)
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data

# Пусть к сокету clamd (Предполагается что clamd уже установлен и настроен)
av_scanner = clamd:/var/run/clamav/clamd.sock


# Разрешаем всем клиентам использовать TLS
tls_advertise_hosts = *


# Пути к TLS-сертификату и приватному ключу
tls_certificate = /etc/mail/ca.crt
tls_privatekey = /etc/mail/ca.key

# Список портов, которых будем слушать
daemon_smtp_ports = 25 : 465 : 587
# 465 порт нужен если хотим принимать почту с почтовых серверов Microsoft с использованием TLS.
tls_on_connect_ports = 465

# Имя домена, добавляемое ко всем адресам, идущим без "@" и имени домена. Например, для системных пользователей.
qualify_domain = mx1.domain.ru

# Запрещаем принимать почту с адресов типа user@[10.11.12.13]
allow_domain_literals = false

# Пользователь и группа, от которой работает Exim
exim_user = mailnull
exim_group = mail
never_users = root

# Эта опция заставляет делать обратный DNS-запрос для каждого входящего IP-адреса. Могут быть проблемы с некоторыми почтовыми серверами.
#host_lookup = *


# На сколько задерживаем сообщение о доставке, если его не удалось доставить :)
ignore_bounce_errors_after = 2d


# Сколько хранить "замороженные" сообщения
timeout_frozen_after = 7d


# Опция повышает производительность разбивая директорию spool на поддиректории.
split_spool_directory = true


# Почта с этих хостов/доменов будет приниматься несмотря на ошибки в HELO/EHLO
helo_accept_junk_hosts = 192.168.0.0/16


# Через какое время повторять отправку "замороженных" сообщений
auto_thaw = 1h


# Максимальное число одновременных соединений
smtp_accept_max = 100


# Максимальное число сообщений, принимаемых за одну tcp-сессию
smtp_accept_max_per_connection = 50


# Максимальное число соединений с одного хоста/домена
smtp_accept_max_per_host = 20


# Максимальное число параллельных процессов доставки
remote_max_parallel = 15


# Ограничение на размер части письма, вкладываемого в сообщение об ошибке
return_size_limit = 150k


# Максимальный размер сообщения
message_size_limit = 30M


# Не писать дату и время в логи. В нашем случае их пишет syslogd
syslog_timestamp = no


# Описание тех самых ограничений, которые объявлены выше
begin acl
acl_check_rcpt:

# Разрешаем сообщения с локалхоста не по TCP/IP 
accept  hosts = :


# Запрещаем использование нестандартных символов в адресах локальных получателей
deny message       = Restricted characters in address
domains       = +local_domains
local_parts   = ^[.] : ^.*[@%!/|]

# Запрещаем использование нестандартных символов в адресах удаленных получателей
deny message       = Restricted characters in address
domains       = !+local_domains
local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./

# Разрешаем почту на postmaster без проверок 
accept local_parts   = postmaster
domains       = +local_domains

# Включаем проверку отправителя
require verify        = sender


# Запрещаем соединения с теми, кто не предоставляет приветствие по RFC (HELO/EHLO)
deny message       = "HELO/EHLO required by RFC"
condition     = ${if eq{$sender_helo_name}{}{yes}{no}}

# Разрешаем аутентифицированные соединения
accept  authenticated = *


# Запрещаем соединения с теми, кто подставляет в приветствие IP-адрес вместо имени
deny message       = "Do not put IP address in HELO!"
hosts         =  * : !+relay_from_hosts
condition     = ${if eq{$sender_helo_name}{$sender_host_address}{true}{false}}

# Запрещаем соединения с теми, кто подставляет IP-адрес нашего сервера в приветствии
deny condition     = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
hosts         = !127.0.0.1 : !localhost : *
message       = "Do not put my IP address in HELO!"

# Запрещаем соединения с теми, у кого в приветствии только цифры
deny condition     = ${if match{$sender_helo_name}{\N^\d+$\N}{yes}{no}}
hosts         = !127.0.0.1 : !localhost : *
message       = "There is only numbers in HELO!"

# Запрещаем соединения с теми, у кого в имени хоста присутствуют adsl, dialup и т.д.
deny message       = "Bad hostname!"
condition     = ${if match{$sender_host_name}{adsl|dialup|pool|peer|dhcp}       {yes}{no}}

# Задержка установления соединения. Как один из методов борьбы со спамом.
 warn
set acl_m0 = 30s

# Убираем задержку для "своих" доменов/хостов
 warn
hosts = +relay_from_hosts
set acl_m0 = 0s

# Проверка на существование пользователей в локальных доменах
accept domains       = +local_domains
endpass
message       = "User unknown"
verify        = recipient

# Проверка на существование пользователей в релейных доменах
accept domains       = +relay_to_domains
endpass
message       = "Not routeable address"
verify        = recipient

# Если не подошло ни под одно правило - скорее всего ищут открытый релей
deny    message       = "There is no open relay"

acl_check_data:


# Запрещаем сообщения содержащие вирусы
deny malware    = *
message    = This message contains a virus ($malware_name).

# Принимаем сообщение
accept


begin routers


# Поиск маршрута к хосту в DNS
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more

# Поиск алиасов
system_aliases:
driver      = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT goto FROM alias WHERE address='${quote_mysql:$local_part@$domain}' OR address='${quote_mysql:@$domain}'}}

begin transports


# Включаем доставку по SMTP на удаленные хосты
remote_smtp:
driver = smtp

# Доставка до локальных получателей
mysql_delivery:
driver = appendfile
check_string = ""
create_directory
delivery_date_add
# Т.к. мы строим мультидоменный почтовый сервер, то и почта будет храниться в каталогах вида /var/mail/exim/domain.ru/user@domain.ru
directory = ${lookup mysql{SELECT CONCAT('/var/mail/exim/', `domain`, '/', `maildir`) FROM `mailbox` WHERE `username`='${local_part}@${domain}'}}
directory_mode = 770
envelope_to_add
group = mail
maildir_format
maildir_tag = ,S=$message_size
message_prefix = ""
message_suffix = ""
mode = 0600

address_pipe:
driver = pipe
return_output

address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add

# Транспорт для автоответов. Оставляем и надеемся в будущем настроить :)
address_reply:
driver = autoreply

begin retry

# Когда делать очередную попытку отправки недоставленных писем
*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h


begin rewrite

begin authenticators

# Описание типа аутентификации plain
PLAIN:
driver                     = plaintext
server_set_id              = $auth2
server_prompts             = :
server_condition           = ${lookup mysql{SELECT username FROM mailbox WHERE username = '${quote_mysql:$1}' AND password = '${quote_mysql:$2}'}{yes}{no}

#EOF

Далее создаем базу exim на локальном или удаленном хосте при помощи этого дампа (дамп с сайта lissyara.su):

# Не забудьте поменять занчения localhost, user, password на свои :)
-- 
-- БД: `exim`
-- 
USE mysql;
INSERT INTO `user` (`Host`, `User`, `Password`)
VALUES ('localhost','exim',password('exim'));
INSERT INTO `db` (`Host`, `Db`, `User`, `Select_priv`)
VALUES ('localhost','exim','exim','Y');
FLUSH PRIVILEGES;
GRANT USAGE ON exim.* TO exim@localhost;
GRANT SELECT, INSERT, DELETE, UPDATE ON exim.* TO exim@localhost;
CREATE DATABASE `exim`;
USE `exim`;
-- --------------------------------------------------------

-- 
-- Структура таблицы `alias`
-- 

CREATE TABLE `alias` (
  `address` varchar(255) NOT NULL default '',
  `goto` text NOT NULL,
  `domain` varchar(255) NOT NULL default '',
  `created` datetime NOT NULL default '0000-00-00 00:00:00',
  `modified` datetime NOT NULL default '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`address`),
  KEY `address` (`address`)
) TYPE=MyISAM COMMENT='Aliases';
-- --------------------------------------------------------

-- 
-- Структура таблицы `domain`
-- 

CREATE TABLE `domain` (
  `domain` varchar(255) NOT NULL default '',
  `description` varchar(255) NOT NULL default '',
  `aliases` int(10) NOT NULL default '0',
  `mailboxes` int(10) NOT NULL default '0',
  `maxquota` int(10) NOT NULL default '0',
  `transport` varchar(255) default NULL,
  `backupmx` tinyint(1) NOT NULL default '0',
  `created` datetime NOT NULL default '0000-00-00 00:00:00',
  `modified` datetime NOT NULL default '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`domain`),
  KEY `domain` (`domain`)
) TYPE=MyISAM COMMENT='Domains';
-- --------------------------------------------------------

-- 
-- Структура таблицы `mailbox`
-- 

CREATE TABLE `mailbox` (
  `username` varchar(255) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  `name` varchar(255) NOT NULL default '',
  `maildir` varchar(255) NOT NULL default '',
  `quota` int(10) NOT NULL default '0',
  `domain` varchar(255) NOT NULL default '',
  `created` datetime NOT NULL default '0000-00-00 00:00:00',
  `modified` datetime NOT NULL default '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`username`),
  KEY `username` (`username`)
) TYPE=MyISAM COMMENT='Mailboxes';




Осталось заполнить таблицы базы и можно запускать Exim:
[root@mail ~]# /usr/local/etc/rc.d/exim start 

Итог: Установлен и настроен почтовый сервер Exim 4.69 с возможностью обслуживания множества доменов одновременно. Настроена проверка сообщений на вирусы с помощью clamav. Почта сохраняется в каталоги вида domain.ru/username@domain.ru. Все домены, пользователи и алиасы хранятся в БД MySQL.

Используемая литература:
  1. Documentation and FAQ http://www.exim.org/
  2. "Связка exim и dovecot с веб интерфейсом postfixadmin" http://www.lissyara.su/?id=1173

PS: Возможно что-то недописал или забыл. В ближайшее время отредактирую.

22 октября 2008 г.

Установка и настройка cvsup-mirror

Итак, имеем FreeBSD 7. Хотим создать собственное зеркало портов и исходников для централизованного обновления своего парка серверов и для минимизирования количества трафика исходящих от серверов на внешние каналы.
[root@atlant /usr/ports]# uname -mrs
FreeBSD 7.0-RELEASE-p3 i386
Перед установкой не забывайте обновить дерево портов.

Собственно, сама установка cvsup-mirror:
[root@atlant ~]# cd /usr/ports/net/cvsup-mirror/
[root@atlant /usr/ports/net/cvsup-mirror]#
[root@atlant /usr/ports/net/cvsup-mirror]# make install clean
Во время установки Вам будут заданы несколько вопросов:
I am going to ask you a few questions so that I can set up your
FreeBSD mirror configuration.  Every question has a [default]
answer.  To accept the default, just press ENTER.

At this point, I am just gathering information.  I will not touch
your system until you type "make install".
Master site for your updates [cvsup-master.freebsd.org]? cvsup4.ru.freebsd.org
Зеркало обновлений для сервера. Я использую cvsup4.ru.freebsd.org. Определил при помощи утилиты fastest_cvsup (ports/sysutils/fastest_cvsup).
How many hours between updates of your files [1]?
Интервал в часах между обновлениями.
Do you wish to mirror the main source repository [y]? y
Хотим ли мы создать зеркало исходников?
Where would you like to put it [/home/ncvs]? /wrk/cvsup
И куда хотим разместить...
Я для этих целей создал отдельный раздел:
/dev/da2s1g on /wrk/cvsup (ufs, local, soft-updates)

размером:
/dev/da2s1g                      9.7G    4.0K    8.9G     0%    /wrk/cvsup
Далее...
Do you wish to mirror the installed World Wide Web data [y]? n
Хотим ли мы создать зеркало веб-страниц сайта freebsd.org?
Do you wish to mirror the GNATS bug tracking database [y]? n
Хотим ли мы создать зеркало базы данных баг-репортов FreeBSD?
Do you wish to mirror the mailing list archive [y]? n
Хотим ли мы создать зеркало архива списков рассылки FreeBSD?

Дальше пойдет речь о том, что в целях безопасности cvsup-клиент и -сервер должны запускаться от разных пользователей и групп. Авторы не рекомендуют использовать "nobody", "nonroot" или "nogroup".

Unique unprivileged user ID for running the client [cvsupin]?
Unique unprivileged group ID for running the client [cvsupin]?
Unique unprivileged user ID for running the server [cvsup]?
Unique unprivileged group ID for running the server [cvsup]?

Syslog facility for the server log [daemon]?
Предлагает настроить логи через syslog, чтобы логи хранились в отдельных файлах (типа cvsup.log)
Maximum simultaneous client connections [8]? 7
Максимальное количество соединений к Вашему cvsup-серверу.

You need a group "cvsup".
Would you like me to create it [y]?
You need a user "cvsup".
Would you like me to create it [y]?
You need a group "cvsupin".
Would you like me to create it [y]?
You need a user "cvsupin".
Would you like me to create it [y]?
Предлагает создать пользователей и групп в системе.

Would you like me to set up the syslog logging [y]?
Предлагает настроить syslog.
Would you like me to set up your crontab for hourly updates [y]?
Предлагает настроить crontab для обновлений раз в час.

Все!

Done.  The first update will be 5 minutes from now, at 15:40.
The cvsupd server will be started automatically after the first update,
and whenever you reboot.
You are now a FreeBSD mirror site.

Проверяем:
[root@atlant /wrk/cvsup]# ps -ax | grep cvsup
17834  ??  Is     0:00.01 /bin/sh -c /usr/local/etc/cvsup/update.sh
17838  ??  I      0:00.01 /bin/sh /usr/local/etc/cvsup/update.sh
17842  ??  I      0:00.00 lockf -t 0 /var/spool/lock/cvsup.lock /bin/sh
17844  ??  I      0:00.01 su -f -m cvsupin -c exec env HOME=/home/cvsupin cvsup -1gL 1 -b /usr/local/etc/cvsup -c sup.client  -h cvsup4.ru.freebsd.org /usr/
17845  ??  S      0:23.75 cvsup -1gL 1 -b /usr/local/etc/cvsup -c sup.client -h cvsup4.ru.freebsd.org /usr/local/etc/cvsup/supfile
17899  p0  S+     0:00.00 grep cvsup

Запустилось, работает. Синхронизирует...

В каталоге /wrk/cvsup появились каталоги и файлы:
[root@atlant /wrk/cvsup]# ls -al
total 22
drwxr-xr-x  11 cvsupin  cvsupin   512 Oct 22 15:43 .
drwxr-xr-x   5 root     wheel     512 Oct 21 14:12 ..
drwxrwxr-x   2 cvsupin  cvsupin   512 Oct 19 15:59 .snap
drwxr-xr-x   5 cvsupin  cvsupin  1024 Oct 22 15:40 CVSROOT
drwxrwxr-x   5 cvsupin  cvsupin  1536 Oct 22 15:40 CVSROOT-doc
drwxrwxr-x   5 cvsupin  cvsupin  1536 Oct 22 15:40 CVSROOT-ports
drwxrwxr-x   5 cvsupin  cvsupin  1536 Oct 22 15:40 CVSROOT-projects
drwxrwxr-x   6 cvsupin  cvsupin  2048 Oct 22 15:41 CVSROOT-src
drwxrwxr-x   3 cvsupin  cvsupin   512 Oct 22 15:41 distrib
drwxrwxr-x  13 cvsupin  cvsupin   512 Oct 22 15:43 doc
drwx------   8 cvsupin  cvsupin   512 Oct 22 15:45 ports
В логфайле cvsup.log
Updating from cvsup4.ru.freebsd.org
Connected to cvsup4.ru.freebsd.org
...
Finished successfully

Теперь к cvsupd...

Добавляем строку в rc.conf:
[root@atlant ~]# echo 'cvsupd_enable="YES"' >> /etc/rc.conf
Стартуем:
[root@atlant ~]# /usr/local/etc/rc.d/cvsupd start Starting cvsupd.
Проверяем:
[root@atlant ~]# ps -ax | grep cvsupd 18062 ?? Is 0:00.00 /usr/local/sbin/cvsupd -e -C 7 -l @daemon -b /usr/local/etc/cvsup -s sup.client
[root@atlant ~]# sockstat | grep cvsupd
cvsup cvsupd 18062 3 tcp4 *:5999 *:*