среда, 20 января 2010 г.

NFS на Ubuntu под защитой iptables и с portknock авторизацией.

Как это принято начну с того, что статья не претендует на полноценный man, это скорее quick install. Дело в том, что мне так и не удалось найти полностью рабочего варианта настройки NFS сервера, поэтому побрав необходимую информацию и покрутив сервер получилось довольно неплохо.

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

Хоть NFS и может фильтровать подключения по ip адресам, но на нормальную авторизацию это претендовать не может. Решение, которое пришло мне в голову заключалось в том что бы закрыть доступ средствами iptables и открывать порты только по специальному запросу. Таким образом даже при подмене ip адреса без необходимой информации подключиться к серверу не удастся.

Настройка сервера.


Установка NFS server.


Оговорюсь сразу, что т.к. я буду заниматься исключительно поднятием сервиса, то и работать буду из-под рута. Поэтому "sudo su" и вперед.

Установка как всегда проще простого
apt-get install nfs-kernel-server

остальное подтянется автоматом.

Дальше нужно создать директорию, которую будем шарить
mkdir /share
chmod 777 /share

и добавить конфиг /etc/exports
nano /etc/exports

строчку следующего вида
<папка которую нужно расшарить> <ip кому можно подключаться>(<опции>) [<другой ip>(<опции для него>)]

например
/share 192.168.1.10(rw,async,no_subtree_check) 192.168.2.0/24(rw,async,no_subtree_check)

Перезапуск nfs демона
/etc/init.d/nfs-kernel-server restart

далее при внесении изменений в /etc/exports можно будет запускать
exportfs -arv

Готово.

Защита брандмауэром.


Про первоначальную настройку iptables читайте тут.

Тут только выложу листинг файла iptables.rules:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT

Установка portknockd.


И снова ничего сложного

apt-get install portknockd

Теперь настроим его. Сложность заключается в том, что mountd, который используется NFS-ом при запуске случайным образом открывает порты. Поэтому пойдем на хитрость. Создадим файл например /scripts/ipopenclose.sh со следующим содержимым
#!/bin/sh
if [ "$1" = "open" ]; then
/sbin/iptables -I INPUT 4 -s $2 -p tcp --dport `rpcinfo -p localhost|grep "mountd"|grep "tcp"|tr ' ' '\n'|grep -v "mountd"|tail -n $
/sbin/iptables -I INPUT 4 -s $2 -p udp --dport `rpcinfo -p localhost|grep "mountd"|grep "tcp"|tr ' ' '\n'|grep -v "mountd"|tail -n $
/sbin/iptables -I INPUT 4 -s $2 -p tcp --dport 111 -j ACCEPT
/sbin/iptables -I INPUT 4 -s $2 -p udp --dport 111 -j ACCEPT
/sbin/iptables -I INPUT 4 -s $2 -p tcp --dport 2049 -j ACCEPT
/sbin/iptables -I INPUT 4 -s $2 -p udp --dport 2049 -j ACCEPT
else
if [ "$1" = "close" ]; then
/sbin/iptables -D INPUT -s $2 -p tcp --dport `rpcinfo -p localhost|grep "mountd"|grep "tcp"|tr ' ' '\n'|grep -v "mountd"|tail -n $
/sbin/iptables -D INPUT -s $2 -p udp --dport `rpcinfo -p localhost|grep "mountd"|grep "tcp"|tr ' ' '\n'|grep -v "mountd"|tail -n $
/sbin/iptables -D INPUT -s $2 -p tcp --dport 111 -j ACCEPT
/sbin/iptables -D INPUT -s $2 -p udp --dport 111 -j ACCEPT
/sbin/iptables -D INPUT -s $2 -p tcp --dport 2049 -j ACCEPT
/sbin/iptables -D INPUT -s $2 -p udp --dport 2049 -j ACCEPT
fi
fi

Делаем его запускаемым
chmod +x /scripts/ipopenclose.sh

Осталось настроить knockd. Для этого содержимое файла /etc/knockd.conf заменить на
[opencloseNFS]
sequence = <порт1>:<tcp/udp>,...,<порт n>:<tcp/udp>
seq_timeout = 5
tcpflags = syn
start_command = /scripts/ipopenclose.sh open %IP%
cmd_timeout = 10
stop_command = /scripts/ipopenclose.sh close %IP%

<порт1>:<tcp/udp> и др. тут нужно указать любые свободные порты и протокол на которые будет стучаться клиент.

Я сделал примерно так
sequence = 10345:tcp,25001:udp,34448:tcp,44321:tcp,25150:udp

И последний штрих. В фале /etc/default/knockd запись
START_KNOCKD=0

заменить на
START_KNOCKD=1

Далее
service knockd start

и сервер готов принимать входящие запросы.

Настройка клиента


Первым делом определимся с точкой монтирования NFS
mkdir /mnt/nfs

и подготовим клиента к подключению.
apt-get install nfs-common knockd

Добавим в fstab точку монтирования
<ip сервера>:/share /mnt/nfs nfs rw,noauto,user,soft 0 0

Я сделал для себя скрипт для подключения и отключения шары
#!/bin/sh
if [ "$1" = "open" ]; then
knock 10345:tcp 25001:udp 34448:tcp 44321:tcp 25150:udp
mount /mnt/backup/
else
if [ "$1" = "close" ]; then
umount /mnt/backup/
fi
fi

Порты нужно указывать те, которые мы придумывали для конфига knockd (/etc/knockd.conf) на сервере.

Теперь я запускаю скрипт с параметром open или close подключаясь или отключаясь таким образом к серверу NFS.