Linux: установка анонимного FTP сервера ftpd Печать
Добавил(а) microsin   

Описана установка стандартного сервера ftpd по шагам, на примере Red Hat Linux 4 (для других дистрибутивов процедура очень похожа). Статья основана на книге "Руководство администратора Linux" авторов Эви Немет, Гарт Снайдер, Трент Хейн.

1. Настраиваем открытие управляющего порта 21 для протокола FTP и запуск демона ftpd при подключении клиента к этому порту. В общем случае демона ftpd запускает управляющий стандартными сервисами Интернет демон inetd, либо xinetd (это зависит от дистрибутива). После того, как демон ftpd запущен, он берет на себя всю дальнейшую работу с клиентом, и работает вплоть до завершения соединения (при завершении соединения ftpd прекращает работу). Для каждого клиентского подключения запускается отдельный процесс ftpd.

На разных дистрибутивах Linux настройка делается по разному. Узнать, какой Интернет-демон у Вас используется - inetd или xinetd можно, пробуя запускать команду man inetd и man xinetd (по тому демону, который есть в системе, справка откроется). В случае с inetd нужно внести (либо проверить) записи в конфигурационных файлах /etc/inetd.conf и /etc/services. В случае с xinetd (как было у меня на RedHat) нужно создать файл /etc/xinetd.d/ftp (его будет читать демон xinetd) со следующим содержимым:
service ftp
{
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = root
        server          = /usr/kerberos/sbin/ftpd
        server_args     = -l -l -d
        disable         = no
}

Немного пояснений. Переменная server_args со значением "-l -l -d" задает подробную запись в syslog процессов подключения к серверу ftp и ошибок. Доступ через аккаунт root будет разрешен с полным доступом во все каталоги (чего не рекомендуется делать, если Вы публикуете сервер ftp в небезопасном окружении). Для более подробной справки по опциям см. man ftpd. Для отключения доступа через root можно применить опцию для ftpd -A или -a, но лучше добавить в файл /etc/ftpusers пользователя root - это гарантированно запретит доступ по ftp от имени пользователя root (у меня по умолчанию этот файл отсутствовал, и я его создал).

2. Создаем аккаунт ftp и группу ftp. Мне это не потребовалось, поскольку это они уже были сделаны:
# more /etc/passwd
..
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
..
# more /etc/group
..
ftp:x:50:
..

Немного пояснений. Пользователь ftp - это псевдопользователь для анонимного доступа. Под этим пользовтелем происходит подключение к ftp-серверу, когда логин при подключении anonymous или ftp, а пароль любой. Обычно вместо пароля предлагается вести имя почтового ящика, но это не всегда обязательное требование - иногда пароль не проверяется, и может даже отсутствовать.

3. Создаем домашний каталог пользователя ftp и стандартную систему папок в этом каталоге.

Немного пояснений. "Домашний" каталог у пользователя ftp указан в 6-м параметре строки описания пользователя ftp (файл /etc/passwd), этот же каталог будет корневым для любого пользователя, анонимно подключившегося к серверу с логином anonymous или ftp. В нашем примере это каталог /var/ftp, далее по тексту он будет фигурировать как каталог ~ftp.
# mkdir /var/ftp

Создаем дерево подкаталогов, в которых будут размещаться некоторые необходимые в работе файлы ftp.

Немного пояснений. FTP-сервер ftpd устроен так, что для навигации клиента ftp по каталогам необходим запуск программы ls. Эта программа, а также используемые ею библиотеки хранятся в критически важных для безопасности сервера местах. Однако запуск программы ls для анонимного пользователя чреват потенциальным взломом, поскольку процесс ftpd выполняется с привелегиями суперпользователя (для доступа к сетевым сокетам). Поэтому идут на специальные ухищрения - создают для анонимного пользователя ftp "песочницу" - отдельную систему каталогов, которая содержит копию программу ls и нужных для работы файлов (каталоги ~ftp/bin, ~ftp/etc, ~ftp/lib и ~ftp/pub). На эту систему каталогов настраиваются ограниченные права (об этом поговорим далее). Создадим "песочницу":
# mkdir /var/ftp/bin
# mkdir /var/ftp/etc
# mkdir /var/ftp/lib
# mkdir /var/ftp/pub

Поскольку сеанс работы с анонимным FTP-сервером выполняется в изолированной среде выполнения (chrooted environment), то каталог ~ftp становится корневым каталогом, а каталоги ~ftp/bin, ~ftp/etc, ~ftp/lib и ~ftp/pub маскируются соответственно под /bin, /etc, /lib и /pub. Таким образом, ваш сервис оказывается отрезанным от системных библиотек и прочих “опасных” программ, которые, тем не менее, ему нужны в работе и их требуется предоставить, не нарушая при этом безопасности системы. Какие именно программы и библиотеки необходимы – зависит от того, какой FTP-сервер вы будете использовать, так как у большинства из них свои специфические особенности. Некоторым, например, требуется наличие ~ftp/etc/passwd для получения имен владельцев и групп файлов.

4. Теперь скопируем команду ls в папку /var/ftp/bin (местонахождение команды ls делаем поиском find / -name ls, у меня она была по адресу /bin/ls):
# cp /bin/ls /var/ftp/bin/

Делаем жесткие ссылки на библиотеки, используемые программой ls. Тут всё не очень просто. Для этого сначала узнаем их список:
# ldd /bin/ls
        librt.so.1 => /lib/tls/librt.so.1 (0x00bbc000)
        libacl.so.1 => /lib/libacl.so.1 (0x003b1000)
        libselinux.so.1 => /lib/libselinux.so.1 (0x00518000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00284000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x004e7000)
        /lib/ld-linux.so.2 (0x00266000)
        libattr.so.1 => /lib/libattr.so.1 (0x005b7000)

Немного пояснений. Здесь в выводе одна строка соответствует библиотеке. Однако здесь только третья строка показывает на реальный файл, остальные указывают на мягкие (символические) ссылки на библиотеки:
# ls -l /lib/tls/librt.so.1
lrwxrwxrwx  1 root root 14 Ноя  2  2007 /lib/tls/librt.so.1 -> librt-2.3.4.so     # это ссылка на librt-2.3.4.so   
# ls -l /lib/libacl.so.1
lrwxrwxrwx  1 root root 15 Ноя  2  2007 /lib/libacl.so.1 -> libacl.so.1.1.0       # это тоже ссылка, но на файл libacl.so.1.1.0
# ls -l /lib/libselinux.so.1
-rwxr-xr-x  2 root root 56328 Апр 29  2006 /lib/libselinux.so.1                   # а это уже реальная библиотека /lib/libselinux.so.1
# ls -l /lib/tls/libc.so.6
lrwxrwxrwx  1 root root 13 Ноя  2  2007 /lib/tls/libc.so.6 -> libc-2.3.4.so       # это ссылка
# ls -l /lib/tls/libpthread.so.0
lrwxrwxrwx  1 root root 19 Ноя  2  2007 /lib/tls/libpthread.so.0 -> libpthread-2.3.4.so # это ссылка
# ls -l /lib/ld-linux.so.2
lrwxrwxrwx  1 root root 11 Ноя  2  2007 /lib/ld-linux.so.2 -> ld-2.3.4.so         # это ссылка
# ls -l /lib/libattr.so.1
lrwxrwxrwx  1 root root 16 Ноя  2  2007 /lib/libattr.so.1 -> libattr.so.1.1.0     # это ссылка

Нам нужно создать в песочнице жесткие ссылки на оригинальные библиотеки (командой ln без опций) с такими же именами, как прописаны в зависимостях.
Теперь узнаем, где реально лежат наши библиотеки (librt-2.3.4.so, libacl.so.1.1.0, libc-2.3.4.so, libpthread-2.3.4.so, ld-2.3.4.so, libattr.so.1.1.0). Как узнать, покажу на примере поиска оригинального файла librt-2.3.4.so (ссылка на него /lib/tls/librt.so.1).
# locate librt-2.3.4.so
/lib/tls/librt-2.3.4.so             *  47671
/lib/librt-2.3.4.so                 *  44743
/lib/i686/librt-2.3.4.so            *  44743

Имеется целых 3 файла, и каждый является двоичным... Какой выбрать? Проводим дальнейшие исследования.
[root@localhost tls]# ls -l /lib/tls/librt-2.3.4.so
-rwxr-xr-x  1 root root 47671 Июл  4  2006 /lib/tls/librt-2.3.4.so
[root@localhost tls]# ls -l /lib/librt-2.3.4.so
-rwxr-xr-x  1 root root 44743 Июл  4  2006 /lib/librt-2.3.4.so
[root@localhost tls]# ls -l /lib/i686/librt-2.3.4.so
-rwxr-xr-x  1 root root 44743 Июл  4  2006 /lib/i686/librt-2.3.4.so

Последние 2 файла имеют одинаковый размер, но это ни о чем не говорит. Поэтому лучше, наверное, взять тот файл, что лежит там же, где и ссылка на него, то есть /lib/tls/librt-2.3.4.so. Итак, делаем жесткую ссылку на файл /lib/tls/librt-2.3.4.so и размещаем её в каталоге ~ftp/lib/tls:
# ln /lib/tls/librt-2.3.4.so /var/ftp/lib/tls/librt.so.1

Эту операцию надо проделать для всех зависимостей программы ls (/lib/tls/librt.so.1, /lib/libacl.so.1, /lib/libselinux.so.1, /lib/tls/libc.so.6, /lib/tls/libpthread.so.0, /lib/ld-linux.so.2, /lib/libattr.so.1). Все операции по поиску целей для ссылок я тут пропустил:
# mkdir /var/ftp/lib/tls
..
# ln /lib/tls/librt-2.3.4.so /var/ftp/lib/tls/librt.so.1
..
# ln /lib/libacl.so.1.1.0 /var/ftp/lib/libacl.so.1
..
# ln /lib/libselinux.so.1 /var/ftp/lib/libselinux.so.1
..
# ln /lib/tls/libc-2.3.4.so /var/ftp/lib/tls/libc.so.6
..
# ln /lib/tls/libpthread-2.3.4.so /var/ftp/lib/tls/libpthread.so.0
..
# ln /lib/ld-2.3.4.so /var/ftp/lib/ld-linux.so.2                 
..
# ln /lib/libattr.so.1.1.0 /var/ftp/lib/libattr.so.1

Уффф... Готово. После этой мудреной процедуры у нас заработает наконец-то просмотр каталогов ftp-сервера при анонимном подключении (если перегрузить демон xinetd, но пока этого делать не будем).

5. Скопируем файлы /etc/passwd и /etc/group в каталог ~ftp/etc, и подправим эти копии.

Немного пояснений. Это нужно для подстраховки, чтобы не допустить чтение оригинальных файлов паролей и групп.
# cp /etc/passwd /var/ftp/etc/
# cp /etc/group /var/ftp/etc/

Отредактируйте эти копии таким образом, чтобы остались записи только для root, daemon и ftp, а зашифрованные пароли (если они есть) замените звездочками. В результате должно получиться примерно так:
# more /var/ftp/etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
# more /var/ftp/etc/group
root:x:0:root
daemon:x:2:root,bin,daemon
ftp:x:50:

6. Займемся теперь правами на файлы и каталоги папки ~ftp (напоминаю, что у нас эта папка соответствует папке /var/ftp). Владельцем каталога ~ftp будет являться пользователь root - именно он, а не ftp. Это нужно для безопасности FTP-сервера и системы в целом. Само собой, пароль пользователя root должен храниться в секрете, и доступ на ftp под пользователем root должен быть запрещен (как я уже говорил, с помощью файла /etc/ftpusers).

Для возможности записи файлов на сервер FTP создадим еще папку ~ftp/pub/incoming.  

Авторы рекомендуют на все перечисленные выше каталоги разграничить права доступа согласно таблице:
File/Dir        Owner        Mode
~ftp                root            555
~ftp/etc            root            555
~ftp/bin            root            111
~ftp/bin/ls         root            111
~ftp/lib            root            111
~ftp/etc/passwd     root            444
~ftp/etc/group      root            444
~ftp/pub            root            755
~ftp/pub/incoming   root            733

Выполним для изменения прав следующие команды: 
# chmod 555 /var/ftp
# chmod 555 /var/ftp/etc
# chmod 111 /var/ftp/bin
# chmod 111 /var/ftp/bin/ls
# chmod 111 /var/ftp/lib
# chmod 444 /var/ftp/etc/passwd
# chmod 444 /var/ftp/etc/group
# chmod 755 /var/ftp/pub
# chmod 733 /var/ftp/pub/incoming

Немного пояснений. При такой системе назначения прав все файлы и каталоги, находящиеся в каталоге ~ftp/pub, будут доступны только для чтения. Есть возможность выкачать с клиента на сервер файл в папку ~ftp/pub/incoming (и скачать его оттуда, если знать имя), но список папки ~ftp/pub/incoming будет недоступен для просмотра. Папки ~ftp/bin и ~ftp/lib будут видны, но ни список, ни содержимое недоступны для просмотра. Папка ~ftp/etc с файлами passwd и group нужны для перестраховки - чтобы маскировать настоящие файлы /etc/passwd и /etc/group.

Группу, которой принадлежит ~ftp/pub, лучше сменить с root на специальную, в которую включены пользователи, имеющие право изменения содержимого этого каталога – этим не стоит заниматься от имени root.

Совет: для предотвращения атаки на ваш сервер через ftp путём переполнения диска информацией с целью заблокировать работу всей системы создавайте каталог ~ftp/pub/incoming на отдельном разделе.

7. Перезапускаем демона xinetd (это надо сделать всегда, если внесли какие-то изменения в конфигурационные файлы этого демона, которые находятся в папке /etc/xinetd.d):
#killall -HUP xinetd