Домашний сервер «всё-в-одном» — success story

от автора

Жил да был у меня роутер одной хорошей фирмы на букву «Dead». Ну, это с ним, собственно, и случилось.
Посмотрел я на цены новых, на кучу компьютерного хлама в углу, на список подключений на домашнем компе… И понял, что не нужен мне роутер. Соберу свой, с нормальной маршрутизацией, DNS, WINS, i2p, блекджеком и так далее.

Как это было?

Покопавшись в залежах железа, на свет были извлечены:
• Процессор Intel Core 2 Duo E8400 @ 3GHz
• При нём же – материнка Asus P5Q
• 2 планки DDR2 по 2Gb
• PCI-e сетевая карта TP-Link TG-3468
• Неопознанная сетевая карта WiFi (b/g/n) на базе Ralink RT3060
• Жёсткий диск Seagate 250Gb
Вывод lshw можно посмотреть тут.
Всё это было отчищено от пыли, вмонтировано в корпус с блоком питания, запущено и проверено в memtest и mhdd. Не обнаружив дефектов, я начал установку всего мне необходимого.

Основы основ

За основу я взял дистрибутив Debian Testing, раскатанный через Debootstrap. Сверху сразу были поставлены openssh-server, firmware-ralink и pppoe/pppoeconf.
Ребутнувшись в свежепоставленную систему, я сразу перенёс SSH на 192.168.1.1 и отключил авторизацию по паролю (установив предварительно свой ключ).

Да будет сеть!

Для начала был запущен pppoeconf. К DOCSIS-модему оказалась подключена сетевая карта с именем eth1, в итоге был получен следующий конфиг /etc/ppp/peers/rt:

noipdefault defaultroute replacedefaultroute hide-password noauth persist plugin rp-pppoe.so eth1 user "ptn" usepeerdns 

Но это не всё – необходимо ещё настроить /etc/network/interfaces следующим образом:

auto rt iface rt inet ppp         pre-up /sbin/ifconfig eth1 up         provider rt 

Превращаем роутер в WiFi-AP

Изначальная задумка была в том, что бы сделать 2 WiFi-сети: одну для своих компьютеров и ноутбуков, с надёжным паролем и присоединением ко всем необходимым ресурсам, а вторую – для гостей, которым захотелось выйти в интернет, но не надо знать о том, что творится в моей сети.
В итоге на сервер был установлен hostapd с конфигом следующего вида (все названия сетей и пароли были изменены):

interface=wlan0 driver=nl80211 country_code=RU ieee80211d=1 hw_mode=g channel=9  ssid=Private bridge=br0 preamble=1 ignore_broadcast_ssid=0 wpa=3 wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP wpa_passphrase=MyVeryStrongPassword wmm_enabled=1 ieee80211n=1 ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40] internet=1  bss=wlan0_0 ssid=Guest preamble=1 ignore_broadcast_ssid=0 wpa=3 wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP CCMP rsn_pairwise=CCMP wpa_passphrase=passw0rd wmm_enabled=1 ieee80211n=1 ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40] internet=1 

Тут мы ставим ещё и bridge для eth0 и wlan0 – это позволит подключившимся к нашей сети видеть её целиком, а не беспроводной сегмент. Модифицируем networks:

auto eth0 wlan0 wlan0_0 br0  iface eth0 inet manual  allow-hotplug wlan0 allow-hotplug wlan0_0  iface wlan0 inet manual         pre-up ifconfig wlan0 hw ether f2:7d:68:6d:51:30  iface br0 inet static         bridge_ports eth0 wlan0         address 192.168.1.1         netmask 24  iface wlan0_0 inet static         address 192.168.254.1         netmask 24 

Немного о магии в pre-up для wlan0: для работы с несколькими AP нам надо использовать больше, чем один MAC-адрес. Hostapd назначает MAC для виртуальных интерфейсов (wlan0_0 в нашем случае) автоматически, но для этого адрес первой точки доступа должен иметь несколько «пустых» битов в конце. Я не стал мелочиться и освободил сразу 4 штуки. Задача на дом – посчитайте, сколько максимум AP теперь можно запустить на одной карте.

Налетай – IP всем и каждому, бесплатно!

Всем компьютерам в сети, как это ни прискорбно, надо выдать IP-адреса. Да-да, этим мы и будем заниматься.
Недолго думая, на сервере был запущен DHCP-сервер следующей конфигурации:

update-static-leases on; authoritative; allow unknown-clients; use-host-decl-names on; log-facility local7;  subnet 192.168.1.0 netmask 255.255.255.0 {         interface br0;         authoritative;         range 192.168.1.2 192.168.1.254;         option subnet-mask 255.255.255.0;         option ntp-servers 192.168.1.1;         option domain-name-servers 192.168.1.1;         option netbios-name-servers 192.168.1.1;         option routers 192.168.1.1;         option domain-name "local"; }  subnet 192.168.254.0 netmask 255.255.255.0 {         interface wlan0_0;         authoritative;         range 192.168.254.2 192.168.254.254;         option subnet-mask 255.255.255.0;         option domain-name-servers 8.8.8.8, 8.8.4.4;         option routers 192.168.254.1; }  local-address 192.168.1.1; 

Видно, что для 192.168.1.1/24 так же выдаются DNS, WINS, NTP и шлюз 192.168.1.1 – самое время их настроить.
Со шлюзом всё просто, думаю, эти команды не знает только ленивый:

sysctl net.ipv4.ip_forward=1 iptables –t nat -A POSTROUTING -o ppp0 -j MASQUERADE 

Разумеется, ставим iptables-persistent для сохранения наших настроек, а так же прописываем соответствующие параметры в /etc/sysctl.conf.
Теперь наш сервер является полноценным китайским роутером за 10$. Что? Вам кажется слабовато? Мне тоже. Едем дальше.

Как пройти в библиотеку?

Думаю, никто не забыл, что нам нужен DNS? Простейший forwarding настраивается до нелепости просто, но ведь мы делаем полноценный сервер с резолвингом и реверс-зонами… Ставим bind9, и настраиваем:

options {         directory "/var/cache/bind";         forwarders {                 8.8.8.8;                 8.8.4.4;         };         dnssec-validation auto;         auth-nxdomain no;         listen-on { 127.0.0.1; 192.168.1.1; };         allow-transfer { none; };         version none; }; zone "local" IN {         type master;         file "/var/lib/bind/db.localnet"; }; zone "1.168.192.in-addr.arpa" IN {         type master;         file "/var/lib/bind/db.localnet-rev"; }; 

Теперь нам нужны файлы прямой и обратной зоны:

/var/lib/bind/db.localnet

$ORIGIN . $TTL 86400      ; 1 day local                   IN SOA  ns.local. router.local. (                                 200216990  ; serial                                 28800      ; refresh (8 hours)                                 7200       ; retry (2 hours)                                 604800     ; expire (1 week)                                 86400      ; minimum (1 day)                                 )                         NS      ns.local. $ORIGIN local. $TTL 86400      ; 1 day ns                      A       192.168.1.1 server          A       192.168.1.1 router                  A       192.168.1.1 

/var/lib/bind/db.localnet-rev

$ORIGIN . $TTL 86400      ; 1 day 1.168.192.in-addr.arpa  IN SOA  ns.local. router.local. (                                 2001105214 ; serial                                 28800      ; refresh (8 hours)                                 14400      ; retry (4 hours)                                 3600000    ; expire (5 weeks 6 days 16 hours)                                 86400      ; minimum (1 day)                                 )                         NS      ns.local. $ORIGIN 1.168.192.in-addr.arpa. $TTL 3600       ; 1 hour 1                       PTR     router.local. 

Просто? А теперь сделаем так, что бы каждый компьютер в сети можно было видеть не по IP, а по DNS-имени.
Для этого нам нужно настроить DDNS. Эта технология позволяет связать DHCP-сервер, выдающий адреса, и DNS-сервер.
Для начала создадим ключ для нашего DDNS:

dnssec-keygen -a HMAC-MD5 -b 128 -r /dev/urandom -n USER DDNS_UPDATE 

Эта команда создаст нам 2 файлика с DDNS-ключом. Нам нужно содержимое ключа:

cat Kddns_update.+157+36693.key DDNS_UPDATE. IN KEY 0 3 157 HEyb0FU9+aOXnYFQiXfiVA== 

«HEyb0FU9+aOXnYFQiXfiVA==» и есть наш ключ.
Немного отредактируем наш конфиг DHCP, добавив в него следующие опции:

ddns-updates on; ddns-update-style interim; key rndc-key { algorithm HMAC-MD5; secret HEyb0FU9+aOXnYFQiXfiVA==; } zone local. { primary 192.168.1.1; key rndc-key; } zone 1.168.192.in-addr.arpa. { primary 192.168.1.1; key rndc-key; } subnet 192.168.1.0 netmask 255.255.255.0 {         …         ddns-domainname "local.";         ddns-rev-domainname "in-addr.arpa."; } 

Так же поступим с DNS:

key "rndc-key" {         algorithm hmac-md5;         secret "HEyb0FU9+aOXnYFQiXfiVA=="; };  zone "local" IN {         …         allow-update { key rndc-key; }; }; zone "1.168.192.in-addr.arpa" IN {         …         allow-update { key rndc-key; }; }; 

Вуаля – и эта киллер-фича работает.

Будущее всё-таки здесь. Шестая версия

Так исторически сложилось ©, что мой провайдер (презрительный взгляд в сторону Ростелекома) не выдаёт IPv6 (хотя обещал).

В настоящее время на всей протяженности сети «Ростелеком» обеспечил возможность работы по протоколу IPv6, — парирует пресс-служба оператора.

Что ж, пофиксим это недоразумение. В качестве брокера я выбрал sixxs.net – у них есть туннельные серверы в России, и их туннель прост в настройке для случая с динамическим IP.
Процесс регистрации и получения настроек туннеля/подсети я опущу – там всё довольно просто. Остановлюсь на настройке.
Настройка IPv6 на самом сервере производится в 2 этапа. Во-первых, поставим пакет aiccu – это и есть туннелирующая программа. При установке у нас будет запрошен логин и пароль от sixxs, и некоторые другие данные. После запуска у нас появится новый интерфейс:

sixxs     Link encap:IPv6-in-IPv4           inet6 addr: 2a02:578:5002:xxx::2/64 Scope:Global           UP POINTOPOINT RUNNING NOARP  MTU:1280  Metric:1 … 

Сервер теперь имеет доступ в v6-сеть – почему бы не поделиться ей с другими?
Для начала, разрешим IPv6-forwarding (не забудьте прописать в /etc/sysctl.conf):

sysctl net.ipv6.conf.all.forwarding=1

Настроек с iptables производить не надо – привет, 21 век!
Далее на сайте sixxs получаем подсеть. Её адрес будет очень похож на адрес нашего туннеля – будьте внимательны, они отличаются!
После получения адреса вида 2a02:578:5002:xxxx::2/64, приступим к его настройке. Во-первых, зададим нашему серверу адрес 2a02:578:5002:xxxx::1, добавив в interfaces следующие строки:

iface br0 inet6 static         address 2a02:578:5002:xxxx::1         netmask 64 

Во-вторых, разрешим выдачу IPv6 компьютерам в сети. Поставим пакет radvd, и настроим его следующим образом:

interface br0 {         AdvSendAdvert on;         prefix 2a02:578:5002:xxxx::/64         {                 AdvOnLink on;                 AdvAutonomous on;                 AdvRouterAddr on;         };         RDNSS 2a02:578:5002:xxxx::1 { }; }; 

Добавим IPv6 DNS в настройки нашего bind – для полного фен-шуя:

options {         forwarders {                 …                 2001:4860:4860::8888;                 2001:4860:4860::8844;         };         listen-on-v6 { ::1/128; 2a02:578:5002:xxxx::/64; };         … }; 

Это всё – теперь мы имеем доступ, например, к ipv6.google.com, или, что гораздо ценнее – к ipv6.nnm-club.me 😉

Пингвин, смотрящий в окно

Я люблю, когда у меня в сети всё красиво. А это возможно только в случае полной гармонии. Например, когда все компьютеры видят друг друга. Для рабочих станций Windows справедливо вспомнить про WINS (помните, мы даже выдавали эту настройку в DHCP).
Его настройка крайне проста: устанавливаем пакет samba. Конфиг по умолчанию надо немного изменить:

workgroup = WORKGROUP wins support = yes dns proxy = yes interfaces = lo br0 bind interfaces only = yes server role = standalone server 

Проверяем результаты… О, да тут всё хорошо!

Кстати, так как у нас есть samba, можно сразу настроить файлопомойку. Но это уже настолько избитая тема, что я оставляю её на плечах гугла. По сути, всё и так должно работать из коробки – разве что read only для homes выключить да smbpasswd -a user

Который час?

Настроим раздачу времени на сервере: установим ntp. С конфигами всё до нелепости просто:

server 0.ru.pool.ntp.org server 1.ru.pool.ntp.org server 2.ru.pool.ntp.org server 3.ru.pool.ntp.org … broadcast 192.168.1.1 

А вот и результат:

Мы уже вплотную приблизились к роутерам уровня microtik за $150-$200. Но это же не всё? Конечно нет.

Killer-feature #1: I2P

А почему бы не иметь доступа в эту сеть без каких-либо настроек, без прокси-серверов и так далее? Вот и я думаю, «почему». Для начала установим вменяемую версию Java:

echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" >> /etc/apt/sources.list apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 apt-get update apt-get install oracle-java7-installer 

И установим сам роутер:

echo "deb http://deb.i2p2.no/ unstable main" >> /etc/apt/sources.list wget "http://www.i2p2.de/_static/debian-repo.pub" -O- -q | apt-key add - apt-get update apt-get install i2p i2p-keyring 

Теперь создадим зону, направляющую все запросы к *.i2p на наш сервер. В конфиг bind:

zone "i2p" IN {         type master;         file "/etc/bind/db.i2p"; }; 

Сама зона:

$ORIGIN i2p $TTL 7200 i2p.    IN      SOA     ns.i2p. hostmaster.i2p. (                         2010020701      ; serial                         7200            ; refresh                         1800            ; retry                         7200            ; expire                         7200            ; minimum                         ) i2p.    IN      NS      ns.i2p. ns.i2p. IN      A       192.168.1.1  *.i2p.  IN      A       192.168.1.1 *.i2p.  IN      AAAA    2a02:578:5002:xxxx::1 

Отлично, но как теперь это обработать? Банально завернуть весь трафик на порт роутера у меня не получилось – прокси ругался на то, что не может так работать. Пришлось настраивать связку nginx+php5-fpm и писать небольшой скрипт. Как сделать первую часть – искать долго не надо, благо мануалов в сети полно. Вторая часть:

/etc/nginx/sites-enabled/i2p

server {         listen [2a02:578:5002:xxxx::1]:80;         listen 192.168.1.1:80;         # по этому адресу можно будет получить доступ к конфигам роутера         server_name localhost.i2p;         location / {                 proxy_pass http://127.0.0.1:7657;         } } server {         listen [2a02:578:5002:xxxx::1]:80;         listen 192.168.1.1:80;         server_name *.i2p;         location / {                 fastcgi_pass unix:/var/run/php5-fpm;                 include fastcgi_params;                 # принудительно задаём адрес скрипта                 fastcgi_param SCRIPT_FILENAME /etc/nginx/proxy.php;                 # передаём скрипту параметр с адресом HTTP proxy от i2p                 fastcgi_param PROXY_PASS 127.0.0.1:4444;         } } 

Сам скрипт можно увидеть тут.
Это всё! Теперь мы имеем доступ в i2p даже с телефона – никаких проблем.

Killer-feature #2: делаем рабочее место рабочей сетью

Так исторически сложилось ©, что я являюсь системным администратором по удалёнке сразу в нескольких фирмах. И очень полезно иметь к ним доступ с любого компьютера в сети. Настройку OpenVPN (или любого другого) для сервера осуществляем как для любого другого клиента. Например, после этих действий у нас появился интерфейс tap0 с IP 10.0.0.7/24. Но если мы обратимся из локальной сети по адресу 10.0.0.1, то трафик уйдёт в default gateway провайдера. Исправим этот недостаток:

iptables -t nat -A POSTROUTING -d 10.0.0.0/24 -o tap0 -j MASQUERADE iptables-save > /etc/iptables/rules.v4 

Аналогичным образом поступаем для всех сетей на сервере.

Вместо заключения

У нас есть полноценный сервер, который мы можем использовать по своему усмотрению. DNS, nginx, IPv6, i2p… Можно так же установить зону для локальной разработки, например, *.dev, и тестировать свои сайты с любого устройства в локальной сети. Так как каждый компьютер в сети имеет свой постоянный IPv6-адрес, можно иметь к нему доступ из любой точки мира (Security warning! Настраивайте файрволы правильно!).
И это всё – лишь вершина айсберга. То, что будет его подводной частью – решать вам.

Буду рад услышать комментарии, предложения, здравую критику и прочее. Спасибо.

ссылка на оригинал статьи http://habrahabr.ru/post/203376/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *