Настройка FreeBSD в качестве Интернет-шлюза


== Введение ==

Кратенько хотелось бы накидать план, которому стоит следовать, чтобы курс на
Интернет для офиса был правильным и в сторону никого не вильнуло. Сразу отмечу,
что шлюз в юниксе - это не одна программа, а целый десяток программ, каждая из
которых выполняет свое действие и имеет свои собственные настройки. Мы
используем:

* FreeBSD 7
* natd 
* named, routed
* ipfw
* squid
* squidGuard
* apache
* dhcpd

Мой тестовый сервер уже находится в рамках локальной сети, поэтому я считаю,
что внешняя сеть у меня это 192.168.0.0/24, а внутреняя - 172.16.0.0/16. Числа,
в конце концов, не имеют значения - главное, смысл. Я поставил FreeBSD в
минимальной комплектации и мой rc.conf содержит только:

hostname="vm=freepro.local"
ifconfig_em0="DHCP"
linux_enable="YES"
sshd_enable="YES"


== Настройка NAT ==

Мой внешний интерфейс - em0 - по умолчанию получает свой IP-адрес по DHCP от
обычного роутера с адресом 192.168.1.1. Очевидно, что этот же роутер выполняет
роль DNS-сервера. На первом этапе я делаю NAT (всегда на внешнем интерфейсе!)
и модифицирую файл /etc/rc.conf таким образом:

hostname="vm=freepro.local"
defaultrouter="192.168.1.1"
ifconfig_em0="inet 192.168.1.10 netmask 255.255.255.0"
linux_enable="YES"
sshd_enable="YES"
# Интернет-шлюз
ifconfig_em1="inet 172.16.0.1 netmask 255.255.0.0"
gateway_enable="YES"
natd_enable="YES"
natd_interface="em0"
#natd_flags="-f /etc/redirect.conf"
firewall_enable="YES"
firewall_type="open"
#firewall_script="/etc/firewall.conf"
router_enable="YES"
router="/sbin/routed"
router_flags="-q"

Я зафиксировал внешний адрес и задал внутренний.
Теперь поправим DNS в файле /etc/resolv.conf:

nameserver 192.168.1.1

Это всё! Стартуем службы: 

# /etc/rc.d/ipfw start
# /etc/rc.d/natd start
# /etc/rc.d/routed start
# /etc/rc.d/named start

И интернет работает! Клиенту, разумеется, руками прописываем:

IP: 172.16.0.2
MASK: 255.255.0.0
GATE: 172.16.0.1
DNS1: 192.168.1.1

Конечно, это очень плохой шлюз. Во-первых, он вообще не защищен, во-вторых,
он совсем не кешируется, в-третьих, все DNS-запросы он перенаправляет "наверх",
ну и в нем напрочь отсутствует возможность получать какую-либо статистику и
чем-либо управлять. Но зато это очень легкий и быстрый шлюз и от дальнейших
настроек его производительность будет только увеличиваться, а не уменьшаться.

Кстати, обратите внимание, что в новом rc.conf уже закомментированы две строки.
Первый комментарий - поможет мне в будущем "пробросить" некоторые порты снаружи
- внутрь сети. Т.е. к примеру, если я хочу получить доступ по ssh к клиентскому
компьютеру 172.16.0.2 - то я должен буду сделать такой файл: 

# Файл /etc/redirect.conf
redirect_port tcp 172.16.0.2:22 2222

Это означает, что соединяясь с сервером снаружи по порту 2222 я попаду на
машину в локальной сети как раз по 22 порту (ssh).
Второй комментарий - это моя персональная конфигурация фаервола, заточенная
и проверенная. 


== Настройка ipfw ==

Моя конфигурация для ipfw на данном этапе она выглядит так:

#!/bin/sh

# Конфигурация IPFW для простого NAT-сервера /etc/firewall.conf

cmd="/sbin/ipfw -q"

IfOut="em0"
IpOut="192.168.1.10"
NetOut="192.168.1.0/24"

IfIn="em1"
IpIn="172.16.0.1"
NetIn="172.16.0.0/16"

##################################################
# Clear
##################################################
${cmd} -f flush
${cmd} table 0 flush
${cmd} table 1 flush

##################################################
# Whitelist / Blacklist
##################################################
${cmd} table 0 add 172.16.0.12
${cmd} table 1 add 172.16.0.13

##################################################
# Loopback
##################################################
${cmd} add allow ip from any to any via lo0

##################################################
# Block world to private
##################################################
${cmd} add deny ip from any to 127.0.0.0/8
${cmd} add deny ip from 127.0.0.0/8 to any

#${cmd} add deny ip from 172.16.0.0/16 to any via ${IfOut}
#${cmd} add deny ip from 192.168.1.0/24 to any via ${IfOut}

${cmd} add deny ip from any to 10.0.0.0/8 via ${IfOut}
#${cmd} add deny ip from any to 172.16.0.0/12 via ${IfOut}
#${cmd} add deny ip from any to 192.168.0.0/16 via ${IfOut}
${cmd} add deny ip from any to 0.0.0.0/8 via ${IfOut}
${cmd} add deny ip from any to 169.254.0.0/16 via ${IfOut}
${cmd} add deny ip from any to 192.0.2.0/24 via ${IfOut}
${cmd} add deny ip from any to 224.0.0.0/4 via ${IfOut}
${cmd} add deny ip from any to 240.0.0.0/4 via ${IfOut}

##################################################
# ICMP
##################################################
${cmd} add deny icmp from any to any frag
${cmd} add deny log icmp from any to 255.255.255.255 in via ${IfOut}
${cmd} add deny log icmp from any to 255.255.255.255 out via ${IfOut}

##################################################
# NAT
##################################################
${cmd} add divert 8668 ip from ${NetIn} to any via ${IfOut}
${cmd} add divert 8668 ip from any to ${IpOut} via ${IfOut}
#${cmd} add divert 8668 ip from any to any via ${IfOut}

##################################################
# Block private to world
##################################################
${cmd} add deny ip from 10.0.0.0/8 to any via ${IfOut}
#${cmd} add deny ip from 172.16.0.0/12 to any via ${IfOut}
#${cmd} add deny ip from 192.168.0.0/16 to any via ${IfOut}
${cmd} add deny ip from 0.0.0.0/8 to any via ${IfOut}
${cmd} add deny ip from 169.254.0.0/16 to any via ${IfOut}
${cmd} add deny ip from 192.0.2.0/24 to any via ${IfOut}
${cmd} add deny ip from 224.0.0.0/4 to any via ${IfOut}
${cmd} add deny ip from 240.0.0.0/4 to any via ${IfOut}

##################################################
# Whitelist
##################################################
${cmd} add allow all from "table(0)" to any
${cmd} add allow all from any to "table(0)"

##################################################
# Blacklist
##################################################
${cmd} add deny all from "table(1)" to any

##################################################
# Keep established
##################################################
${cmd} add allow tcp from any to me established

##################################################
# Main
##################################################
${cmd} add allow ip from any to any frag
${cmd} add allow icmp from any to ${IpOut} icmptypes 0,8,11
# dns
${cmd} add allow tcp from any to ${IpOut} dst-port 53 setup
${cmd} add allow udp from any to ${IpOut} dst-port 53
${cmd} add allow udp from ${IpOut} 53 to any
${cmd} add allow udp from ${IpOut} to any dst-port 53 keep-state
# dns-client
${cmd} add allow tcp from any to ${NetIn} dst-port 53 setup
${cmd} add allow udp from any to ${NetIn} dst-port 53
${cmd} add allow udp from ${NetIn} 53 to any
${cmd} add allow udp from ${NetIn} to any dst-port 53 keep-state
# time
${cmd} add allow udp from ${IpOut} to any dst-port 123 keep-state
# time-client
${cmd} add allow udp from ${NetIn} to any dst-port 123 keep-state
# ssh-in
${cmd} add allow tcp from any to ${IpOut} 22
${cmd} add allow tcp from ${IpOut} 22 to any
# ssh-out
${cmd} add allow tcp from ${IpOut} to any 22
${cmd} add allow tcp from any 22 to ${IpOut}
# http
${cmd} add allow tcp from ${IpOut} to any dst-port 80
# http-client
${cmd} add allow tcp from ${NetIn} to any dst-port 80
${cmd} add allow tcp from any 80 to ${NetIn}
# smtp
${cmd} add allow tcp from any to ${IpOut} dst-port 25 setup
# forward 8080 to 81
${cmd} add allow tcp from any to ${IpOut} dst-port 8080
${cmd} add allow tcp from ${IpOut} 8080 to any
${cmd} add allow tcp from any to ${NetIn} dst-port 81
${cmd} add allow tcp from ${NetIn} 81 to any
# out
${cmd} add deny log tcp from any to any in via ${IfOut} setup
#${cmd} add allow tcp from any to any setup

##################################################
# Local network
##################################################
${cmd} add allow all from any to any via ${IfIn}

##################################################
# Deny All
##################################################
${cmd} add deny all from any to any

Я специально закомментировал некоторые строки, которые прибивают пакеты из
локальных сетей 192, 172 на внешнем интерфейсе, поскольку мой внешний интерфейс
и есть локальный. В реальности эти строки нужны. Едем дальше. 


== Настройка squid ==

Теперь мне нужен squid - кеширующий прокси-сервер, способный грамотно раздавать
интернет всем пользователям по правилам, которые задает системный администратор.

pkg_add -r squid

Примечание: конечно, более правильный вариант - собирать ПО из свежих и
обновленных портов, но мы экономим на времени, поэтому ставим пакетами.
Когда-нибудь потом обновимся с помощью portupgrade. Для squid делаем самую
простую настройку - правим файл /usr/local/etc/squid/squid.conf

# Минимальная конфигурация SQUID

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl localnet src 172.16.0.0/255.255.0.0
acl SSL_ports port 443
acl CONNECT method CONNECT

http_access allow manager localhost
http_access allow localnet
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all
icp_access allow all
http_port 3128 transparent

hierarchy_stoplist cgi-bin ?

acl QUERY urlpath_regex cgi-bin \?
cache deny QUERY

cache_dir ufs /usr/local/squid/cache 100 16 256
access_log /usr/local/squid/logs/access.log squid
cache_log /usr/local/squid/logs/cache.log
cache_store_log /usr/local/squid/logs/store.log

refresh_pattern ^ftp:		1440	20%	10080
refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern .		0	20%	4320
acl apache rep_header Server ^Apache
broken_vary_encoding allow apache
cache_effective_user squid
cache_effective_group squid
visible_hostname vm-freepro.local

icp_port 0

error_directory /usr/local/etc/squid/errors/English
coredump_dir /usr/local/squid/cache

Комментарии из файла конфигурации я намеренно убрал, потому что там их не много,
а очень много. Не забываем поправить /etc/rc.conf, добавив строку:

squid_enable="YES"

Далее - перестраиваем кэш и стартуем сквид:

# squid -z
# /usr/local/etc/rc.d/squid start

Первое, что мы делаем после установки squid - запрещаем локальным пользователям
ходить в интернет через 80 порт. Порт 80 перебрасываем на 3128 - т.е.
заставляем всех пользователей ходить только через squid. Здесь есть большая
маленькая загвоздка. Такую операцию можно сделать, только внедрив поддержку
IPFW в ядро, иначе форвардинг не работает. Да, это означает, что сейчас нам
придется собрать своё ядро! Дело непростое, но полезное - после сборки своего
ядра скорость его работы должна возрасти, а объем - заметно уменьшиться.
Сначала с помощью sysinstall ставим исходники ядра:

# sysinstall
Переходим в /Configure/Distributions
Отмечаем внутри раздела [ ] src
[X] base
[X] sys

Теперь в папке /usr/src у нас есть исходники ядра. Далее копируем конфигурацию
GENERIC в "свою" MYKERNEL, и правим MYKERNEL:

# cd /usr/src/sys/i386/conf
# cp GENERIC MYKERNEL
# mcedit MYKERNEL

При правке конфига обязательно нужно указать следующие опции:

# Включение фаервола в ядро
options         IPFIREWALL
# Включение механизма логирования 'log'
options         IPFIREWALL_VERBOSE
# Ограничение логов - защита от переполнения
options         IPFIREWALL_VERBOSE_LIMIT=50
# Включение механизма перенаправления пакетов
options         IPFIREWALL_FORWARD
# Включение механизма трансляции адресов NAT
options         IPDIVERT
# Включение механизма ограничения скорости канала
options         DUMMYNET

А также убрать все лишнее "железо", которого в реальности у вас нет.

Теперь выполняем сборку ядра. Данная операция может немного затянуться, и может
оборваться с ошибкой, потребовав установки дополнительных исходников из
sysinstall в зависимости от того, что вы написали в конфигурации. Надеемся, что
там нет ничего лишнего.

# cd /usr/src
# make buildkernel KERNCONF=MYKERNEL
# make installkernel KERNCONF=MYKERNEL

Теперь нужно перегрузиться, но перед перезагрузкой обязательно прочитайте
мануал на тот случай, если перезагрузиться не получится. Хотелось бы, чтобы
этого, конечно, не произошло. Итак, перегружаемся и снова правим
/etc/firewall.conf. 

#!/bin/sh

# Конфигурация IPFW для NAT-сервера и SQUID-прокси

cmd="/sbin/ipfw -q"

IfOut="em0"
IpOut="192.168.1.10"
NetOut="192.168.1.0/24"

IfIn="em1"
IpIn="172.16.0.1"
NetIn="172.16.0.0/16"


##################################################
# Clear
##################################################
${cmd} -f flush
${cmd} table 0 flush
${cmd} table 1 flush

##################################################
# Whitelist / Blacklist
##################################################
${cmd} table 0 add 172.16.0.2
${cmd} table 1 add 172.16.0.13

##################################################
# Loopback
##################################################
${cmd} add allow ip from any to any via lo0


##################################################
# Block world to private
##################################################
${cmd} add deny ip from any to 127.0.0.0/8
${cmd} add deny ip from 127.0.0.0/8 to any

#${cmd} add deny ip from 172.16.0.0/16 to any via ${IfOut}
#${cmd} add deny ip from 192.168.1.0/24 to any via ${IfOut}

${cmd} add deny ip from any to 10.0.0.0/8 via ${IfOut}
#${cmd} add deny ip from any to 172.16.0.0/12 via ${IfOut}
#${cmd} add deny ip from any to 192.168.0.0/16 via ${IfOut}
${cmd} add deny ip from any to 0.0.0.0/8 via ${IfOut}
${cmd} add deny ip from any to 169.254.0.0/16 via ${IfOut}
${cmd} add deny ip from any to 192.0.2.0/24 via ${IfOut}
${cmd} add deny ip from any to 224.0.0.0/4 via ${IfOut}
${cmd} add deny ip from any to 240.0.0.0/4 via ${IfOut}

##################################################
# ICMP
##################################################
${cmd} add deny icmp from any to any frag
${cmd} add deny log icmp from any to 255.255.255.255 in via ${IfOut}
${cmd} add deny log icmp from any to 255.255.255.255 out via ${IfOut}

##################################################
# NAT
##################################################
${cmd} add divert 8668 ip from ${NetIn} to any via ${IfOut}
${cmd} add divert 8668 ip from any to ${IpOut} via ${IfOut}
#${cmd} add divert 8668 ip from any to any via ${IfOut}


##################################################
# Block private to world
##################################################
${cmd} add deny ip from 10.0.0.0/8 to any via ${IfOut}
#${cmd} add deny ip from 172.16.0.0/12 to any via ${IfOut}
#${cmd} add deny ip from 192.168.0.0/16 to any via ${IfOut}
${cmd} add deny ip from 0.0.0.0/8 to any via ${IfOut}
${cmd} add deny ip from 169.254.0.0/16 to any via ${IfOut}
${cmd} add deny ip from 192.0.2.0/24 to any via ${IfOut}
${cmd} add deny ip from 224.0.0.0/4 to any via ${IfOut}
${cmd} add deny ip from 240.0.0.0/4 to any via ${IfOut}

##################################################
# Whitelist
##################################################
${cmd} add allow all from "table(0)" to any
${cmd} add allow all from any to "table(0)"

##################################################
# Blacklist
##################################################
${cmd} add deny all from "table(1)" to any

##################################################
# Keep established
##################################################
${cmd} add allow tcp from any to me established

##################################################
# Main
##################################################
${cmd} add allow ip from any to any frag
${cmd} add allow icmp from any to ${IpOut} icmptypes 0,8,11
# dns
${cmd} add allow tcp from any to ${IpOut} dst-port 53 setup
${cmd} add allow udp from any to ${IpOut} dst-port 53
${cmd} add allow udp from ${IpOut} 53 to any
${cmd} add allow udp from ${IpOut} to any dst-port 53 keep-state
# dns-client
${cmd} add allow tcp from any to ${NetIn} dst-port 53 setup
${cmd} add allow udp from any to ${NetIn} dst-port 53
${cmd} add allow udp from ${NetIn} 53 to any
${cmd} add allow udp from ${NetIn} to any dst-port 53 keep-state
# time
${cmd} add allow udp from ${IpOut} to any dst-port 123 keep-state
# time-client
${cmd} add allow udp from ${NetIn} to any dst-port 123 keep-state
# ssh-in
${cmd} add allow tcp from any to ${IpOut} 22
${cmd} add allow tcp from ${IpOut} 22 to any
# ssh-out
${cmd} add allow tcp from ${IpOut} to any 22
${cmd} add allow tcp from any 22 to ${IpOut}
# http
${cmd} add allow tcp from ${IpOut} to any dst-port 80
# http-client
#${cmd} add allow tcp from ${NetIn} to any dst-port 80
#${cmd} add allow tcp from any 80 to ${NetIn}
# squid
${cmd} add allow all from ${NetIn} to ${IpIn} 3128 via ${IfIn}
${cmd} add fwd ${IpIn},3128 tcp from ${NetIn} to any 80
# smtp
${cmd} add allow tcp from any to ${IpOut} dst-port 25 setup
# out
${cmd} add deny log tcp from any to any in via ${IfOut} setup
#${cmd} add allow tcp from any to any setup

##################################################
# Local network
##################################################
${cmd} add allow all from any to any via ${IfIn}

##################################################
# Deny All
##################################################
${cmd} add deny all from any to any

Перезапускаем сервисы и проверяем - всё работает, и клиенты незаметно для самих
себя проходят через систему контроля. Настройку контроля доступа пока отложим,
и решим еще один важный вопрос: получение DNS. 


== Настройка DNS ==

Сейчас в наших клиентах прописан DNS адрес 192.168.1.1 - внешний по отношению
к внутренней сети 172.16.0.0/16. Можно сказать, что клиенты тысячи раз за день
лезут выше сервера в поисках адресов. Сделаем систему лучше - настроим
кеширующий DNS-сервер, который бы позволял избежать сквозных коннектов наружу,
экономил нам трафик и ускорял работу. Не забываем перед этим запретить доступ
по порту 53 наружу для всех клиентов.

В файле /etc/namedb/named.conf правим параметры listen-on, forwarders:

options {
	directory	"/etc/namedb";
	pid-file	"/var/run/named/pid";
	dump-file	"/var/dump/named_dump.db";
	statistics-file	"/var/stats/named.stats";
	listen-on	{ 127.0.0.1; 172.16.0.1; };

	disable-empty-zone "255.255.255.255.IN-ADDR.ARPA";
	disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
	disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";

	forwarders {
		192.168.1.1;
	};
        // query-source address * port 53;
};

В файле /etc/resolv.conf делаем первым локальный DNS:

nameserver 127.0.0.1
nameserver 192.168.1.1

В /etc/firewall.conf запрещаем клиентам использовать внешние DNS
(правим секции с комментарием dns-client)

# dns-client
# Запрещаем внешние DNS
#${cmd} add allow tcp from any to ${NetIn} dst-port 53 setup
#${cmd} add allow udp from any to ${NetIn} dst-port 53
#${cmd} add allow udp from ${NetIn} 53 to any
#${cmd} add allow udp from ${NetIn} to any dst-port 53 keep-state

# Разрешаем только локальные DNS
${cmd} add allow tcp from ${NetIn} to ${IpIn} dst-port 53 setup
${cmd} add allow udp from ${NetIn} to ${IpIn} dst-port 53

Рестартуем:

# /etc/rc.d/named restart
# /etc/rc.d/ipfw restart

Теперь вернемся к вопросу контроля доступа в интернет. Решений - сразу два.
Во-первых - настроить acl-политики в squid. Во-вторых - установить и настроить
squidGuard - специальное приложение для контроля доступа. Начнем по порядку.

== Настройка squid acl ==

acl - это правила в конфигурации squid, которые достаточно эффективно позволяют
ограничивать информационный поток, проходящий через прокси-сервер. Если кратко -
с acl в два счета можно убить всякую левоту, которая мешает работать. Все acl-
настройки по умолчанию пишутся в файле squid.conf, но также могут быть вынесены
во внешние файлы. Для примера приведу часть конфига:

# Запрещаем всем файлопомойки
acl shares dstdomain .rapidshare.com .webfile.ru
http_access deny shares

# Запрещаем всем запрашивать сайты по IP
acl ip_urls  url_regex http://[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[:/]
http_access deny ip_urls

# Ограничения по группам
src group_strict {
        ip      172.16.0.20-172.16.0.25
}
src group_allow {
        ip      172.16.0.26-172.16.0.30
}
acl {
    group_allow {
        pass    any
    }
    group_strict {
        pass    local none
    }
}

Получается замечательно. Но очевидно, что в хорошем прокси таких правил должно
быть много - по правилу на каждую "дыру". Выяснять "дыры" и прописывать их
поштучно - утомительно, но, как всегда, есть готовое решение - squidGuard -
приложение-фильтр с огромным набором правил, пополнять которые, в принципе,
можно даже по расписанию cron. Изучаем вопрос.


== Настройка squidGuard ==

Теперь попробуем поставить и настроить squidGuard. Делается это не сложно,
но нужно быть внимательным. Итак:

# pkg_add -r squidGuard
# cp /usr/local/etc/squid/squidGuard.conf.sample /usr/local/etc/squid/squidGuard.conf

В файле squidGuard.conf хранятся все настройки, некоторые из которых придется
поправить сразу же, а именно:

# Файл squidGuard.conf
...
source sample-clients {
    ip 172.16.0.0/16
}
...

Сделаем привязку squidGuard к squid - добавим 3 строки в файл squid.conf:

redirector_bypass on
redirect_program /usr/local/bin/squidGuard -c /usr/local/etc/squid/squidGuard.conf
redirect_children 10

squidGuard хранит свою конфигурационную базу в /var/db/squidGuard. Перед первым
запуском или после внесения изменений ее необходимо перестроить:

# rehash
# squidGuard -C all
# chown -R squid:squid /var/db/squidGuard
# /usr/local/etc/rc.d/squid restart

Все хорошо, вот только при попытке клиента зайти на запрещенный сайт, к
примеру, http://3warez.com/, мы наблюдаем тормоза. А хотелось бы получать
какое-то вразумительное сообщение. Для этого нам потребуется apache.


== Настройка apache ==

Как уже говорилось, apache нужен нам для отображения информации о
заблокированных адресах и причинах блокировок. Делаем как обычно:

# pkg_add -r apache22
# echo 'apache22_enable="YES"' >> /etc/rc.conf

Настройки apache лежат в файле /usr/local/etc/apache22/httpd.conf. Перед запуском необходимо проверить директивы DocumentRoot, ServerName - подробности
опущу, т.к. в интернете масса статей по настройке этого сервера. Делается
за 1 сек. Запускаем:

# echo "Access denied" > /usr/local/www/apache22/data/index.html
# /usr/local/etc/rc.d/apache22 start

Поправим немного конфиг squidGuard.conf:

# В самом конце файла
acl {
   .....
   default {
       redirect http://172.16.0.1/index.html
   }
}


== Настройка dhcpd ==

И вот мы близимся к завершению. Сеть настроена и работает чудесно. Все под
контролем, все строго ограничено. Но после кнута клиентам пора предложить и
пряник - в виде раздачи автоматической DHCP-адресов. Хороший администратор,
конечно, и тут смухлюет - будет раздавать адреса только по MAC, но мы просто
наведём изюм.

# pkg_add -r isc-dhcp3-server
# cp /usr/local/etc/dhcpd.conf.sample /usr/local/etc/dhcpd.conf

В файл /etc/rc.conf добавляем строки:

dhcpd_enable="YES"
dhcpd_flags="-q"
dhcpd_ifaces="em1"

Еще нужно поправить самый главный конфиг /usr/local/etc/dhcpd.conf:

option domain-name "example.com";
option domain-name-servers 172.16.0.1;
option subnet-mask 255.255.255.0;

default-lease-time 3600;
max-lease-time 86400;
ddns-update-style none;

subnet 172.16.0.0 netmask 255.255.0.0 {
  range 192.16.0.11 172.16.0.15;
  option routers 172.16.0.1;
}

Включаем электричество:

# /usr/local/etc/rc.d/isc-dhcpd start

Вот, пожалуй, и всё, самое главное. Данная статья не претендует на абсолютную
полноту и содержательность, но вкратце описывает этапы, которые необходимо
пройти, чтобы довести сервер до рабочего состояния. Дальше - только тюнинг и
еще раз тюнинг. Не забывайте также, что это не единственный путь настройки
сервера - в unix всегда есть альтернатива и вы можете использовать совсем
другие приложения.