Описана установка стандартного сервера 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
|