Linux глазами хакера

Флёнов Михаил Евгеньевич

Глава 4

Управление доступом

 

 

Каждый пользователь должен работать в системе под своей учетной записью. Это позволит вам обезопасить свои файлы от чужого вмешательства и по системным журналам определить, когда и кем были произведены разрушительные действия.

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

После увольнения сотрудника вы должны удалить его учетную запись, чтобы недовольный этим фактом он не уничтожил важные данные.

Для работы с командами управления доступом вы должны обладать правами администратора. Для этого можно войти в систему как пользователь root или использовать директиву su. В разд. 4.16 мы рассмотрим еще один способ — использование утилиты sudo.

А теперь перейдем к сути проблемы.

 

4.1. Права доступа

 

Давайте вспомним команду ls -al. Она возвращает список файлов в следующем виде:

drwx------ 3 Flenov FlenovG 4096 Nov 26 16:10 .

drwxr-xr-x 5 root   root    4096 Nov 26 16:21 ..

-rwxr-xr-- 1 Flenov FlenovG   24 Nov 26 16:10 test

Как мы уже знаем, первая колонка (занимает 10 символов) — это права доступа. Давайте рассмотрим, из чего она состоит. Первый символ указывает на тип записи. Здесь может быть одно из следующих значений:

□ знак тире (—) — обычный файл;

□ буква "d" —- каталог;

□ буква "l" — символьная ссылка;

□ буква "s" — сокет;

□ буква "p" — файл FIFO (First in first out, первый вошел — первый вышел).

После этого в каждой строке идет три группы символов rwx, определяющих права доступа для различных категорий пользователей:

□ первая тройка — владельцу файла;

□ вторая — пользователям, входящим в группу владельца;

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

Каждая такая группа состоит из трех символов: r (чтение), w (запись) и x (выполнение). Установленная буква говорит о разрешении соответствующего действия. Рассмотрим несколько вариантов.

Первая строка в нашем примере drwx------. Первый символ d, а значит, это директория. Потом идут три символа rwx, т.е. хозяин файла может читать, записывать и исполнять директорию. Вместо остальных шести символов стоят знаки тире, значит, у пользователей группы FlenovG и у всех остальных нет прав.

Вторая строка — drwxr-xr-x. Это снова директория. Потом стоит комбинация rwx, а значит, владельцу разрешены все операции. Следующая тройка, соответствующая группе, равна r-х, а стало быть, возможно чтение и исполнение. В соответствии с последней тройкой всем остальным пользователем также доступно только чтение и исполнение.

Последняя строка в примере содержит права доступа -rwxr-xr-- для файла (первый символ — это знак тире). Хозяин файла имеет полный доступ к нему (первая тройка rwx). Пользователи группы могут читать и выполнять файл, но не могут его изменять (вторая тройка r-х). Все остальные могут только читать файл (последняя тройка r--).

Права можно воспринимать как последовательность нулей и единиц. Если в определенном месте стоит 1 (указан один из символов r, w или x), то операция разрешена. Если 0 (находится знак тире), то действие запрещено. Давайте попробуем записать права rwxr-xr-- в виде нулей и единиц. Установите вместо букв единицы, а вместо тире — нули. Должно получиться 111101100. Разобьем эту комбинацию на три части 111, 101 и 100. Теперь каждую тройку переведем в восьмеричную систему по следующей формуле:

Цифра1 * 4 + Цифра2 * 2 + Цифра3

У нас получатся три цифры 7, 5, и 4, которые будем рассматривать как десятичное число 754. Запомните его, оно нам пригодится при назначении прав на файлы и каталоги. Чтобы вам в дальнейшем проще было регламентировать доступ, предлагаю все возможные варианты значений для отдельного разряда числа:

□ 0 — запрещено все;

□ 1 — разрешено выполнение;

□ 2 — разрешена запись;

□ 3 — разрешена запись и выполнение;

□ 4 — разрешено чтение;

□ 5 — разрешено чтение и выполнение;

□ 6 — разрешено чтение и запись;

□ 7 — разрешено все.

Попробуйте теперь с помощью этого списка определить возможности, которые предоставляет число 754. Каждый разряд нужно рассматривать в отдельности. Сравните полученный результат с символьным представлением rwxr-xr--. Должно выйти одно и то же.

Внимание!

Для того чтобы иметь право создания или удаления файлов, необходимо иметь разрешение записи на директорию. Это немного сбивает с толку начинающих администраторов, т.к. им непонятно, почему при наличии всех прав на файл его нельзя удалять.

 

4.1.1. Назначение прав

Для изменения режима доступа на объекты файловой системы используется команда chmod. В ней можно указывать новые права на объект как в символьном (применяется для изменения относительно текущего состояния), так и в числовом виде (абсолютное задание). Для начала рассмотрим символьный режим:

chmod параметры права файл

Параметры могут включать комбинацию значений изменения прав по категориям пользователей:

□ u — владельца;

□ g — группы;

□ о — остальных пользователей;

□ a — все права (то же самое, что передать значение ugo).

Перед указанием прав можно задать режим их изменения относительно существующих:

□ + — добавить;

□ - — удалить;

□ = — заменить новыми (старые значения будут уничтожены). После этого устанавливается режим доступа:

□ r — чтение;

□ w — запись;

□ x — выполнение;

□ X — выполнение, если файл является каталогом или уже имеет аналогичные права для какого-либо пользователя;

□ s — setuid- или setgid-бит;

□ t — sticky-бит. В этом случае только владелец файла и каталога сможет выполнить удаление;

□ u — всем пользователям, как и у владельца;

□ g — всем пользователям, как и у группы;

□ o —для остальных, как у пользователей, не входящих в группу файла и не являющихся его владельцем.

В случае с числовым представлением команда выглядит следующим образом:

chmod права файл

Права передаются в виде восьмеричного числа из четырех разрядов:

□ первый — определяет дополнительный бит и может принимать одно из значений:

 • 1 — бит принадлежности;

 • 2 — setgid-бит;

 • 4 — setuid-бит;

□ второй — права пользователя. Это число может быть от 0 до 7;

□ третий — права группы. Значение в диапазоне от 0 до 7;

□ четвертый — права остальных пользователей. Это число может быть от 0 до 7.

Например, мы хотим, чтобы владелец и группа имели все права (число 7), а остальные пользователи могли только выполнять файл (число 1). Значит, команда будет выглядеть следующим образом:

chmod 771 filename

Число 771 в символьном виде соответствует правам rwxrwx--x. Следующая команда отменит возможность чтения файла группой:

chmod g-r text

После этой команды права доступа на файл станут rwx-wx--x. Теперь давайте запретим всем запуск файла. Для этого можно выполнить команду:

chmod ugo-x text

или

chmod a-x text

После наших манипуляций права доступа на файл станут rw--w----.

 

4.1.2. Владелец файла

Для изменения владельца файла существует команда chown:

chown имя файл

Через параметр имя определяется пользователь, которому нужно передать права на указанный файл. Например, давайте сделаем владельцем файла test администратора root. Для этого нужно выполнить следующую команду:

chown root test

Изменить можно и группу, к которой принадлежит файл. Для этого выполните команду chgrp:

chgrp имя файл

Здесь задается имя группы, которой предоставляются права на указанный файл. Например, для файла test укажите группу администратора root с помощью такой команды:

chgrp root test

 

4.1.3. Правила безопасности

При назначении прав на доступ к файлам и папкам вы должны следовать принципу минимализма, описанному в разд. 2.10.1. Чтобы это правило действовало, по умолчанию должно быть запрещено все. Открываем доступ только на то, что необходимо, и ничего лишнего. Если файл не должен быть виден пользователю, то нельзя разрешать даже его отображение в дереве каталогов.

Любые лишние объекты могут оказаться фатальными для безопасности системы не только с точки зрения взлома, но и утечки информации. Например, файлы бухгалтерской отчетности должны быть доступны только для тех, кто с ними работает. Если показать эти документы всем, то финансовые данные, возможно, станут достоянием общественности, и это нежелательным образом отразится на благосостоянии компании.

Самое главное для защиты вашей системы — не дать пользователям возможность изменять системные файлы. В Linux основные конфигурационные файлы находятся в каталоге /etc. Только администратор root должен иметь право их модифицировать. Производители дистрибутивов настраивают систему по умолчанию именно так, и не следует повышать статус пользователей без особой надобности.

 

4.1.4. Права по умолчанию

Когда пользователь создает новый файл или директорию, то им назначаются права по умолчанию. Давайте разберем это на примере. Для создания файла выполним команду ls и перенаправим вывод в файл:

ls -al >> testfile

Теперь проверим права на этот файл с помощью команды ls -al. Должно получиться -rw-r--r--, т.е. владелец может читать и изменять файл, а пользователи группы и все остальные — только просматривать. В старых системах и некоторых дистрибутивах права могут быть равны -rw-rw-r--, а значит, пользователи группы тоже смогут корректировать файл. Такие права нарушают главное правило безопасности. Но в любом случае все получают возможность читать файл. Это разрешено.

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

Ситуацию можно изменить, если понимать, как создаются права для нового файла. Они рассчитываются на основе маски, текущее значение которой определяется командой umask. В результате будет получено значение 0022 или 002.

Посмотрим, как маска влияет на регламентацию доступа. По умолчанию права для файлов устанавливаются в значение 666 минус маска, а для директорий — 777 минус маска.

Теперь ясно, что если маска равна 002, то для нового файла будут установлены права 666-002=664, а это соответствует -rw-rw-r--, а при значении 0022 формула изменится на 666-0022=644, что будет означать -rw-r--r--.

Для директорий расчет аналогичный, и при маске, равной 002, по умолчанию будут устанавливаться права 777-002=775 (drwxrwxr-x). В случае с маской 0022 значение определяется как 777-002=755, а это соответствует правам drwxr-xr-x, т.е. все пользователи смогут просматривать директории и увидят содержащиеся в ней файлы.

Все это не есть хорошо. Если владелец должен иметь доступ, достаточный для полноценной работы с файлами и директориями, то остальные вообще не должны иметь прав. Эту ситуацию можно исправить изменением маски. Я рекомендую установить ее в 077. В этом случае для директорий права будут определены как 777-077=700 (или drwx------), а для файлов — 666-077=600 (или -rw-------). Тогда доступ к файлу имеет только владелец. Все остальные — отдыхают.

При расчете прав на файл можно подумать, что я ошибся, ведь 666-077 далеко не равно 600. Почему же так получилось? Просто вычитание происходит поразрядно, т.е. первая цифра 6 в числе минус первая цифра 0 в маске, затем операция производится со вторыми цифрами (6-7) и т.д. Если какой-либо результат получается отрицательным, то он округляется до нуля.

Вот такое положение дел нас уже устраивает. Чтобы установить новую маску, выполните команду umask маска. В нашем случае это будет umask 077.

 

4.1.5. Права доступа к ссылкам

В разд. 3.1.3 мы рассматривали жесткие и символьные ссылки на файлы. Для начала вспомним права на жесткие ссылки:

913021 -rw-r--r-- 2 root root 0 Feb 22 12:19 1.txt

913021 -rw-r--r-- 2 root root 0 Feb 22 12:19 link.txt

Как видите, права абсолютно идентичны. Я надеюсь, что вы другого и не ожидали, ведь у ссылок дескрипторы одинаковые.

С символьными ссылками дело обстоит куда хуже. Вот пример основного файла и символьной ссылки на него из того же разд. 3.1.3:

913021 -rw-r--r-- 1 root root 519 Feb 22 12:19 link.txt

913193 lrwxrwxrwx 1 root root   8 Feb 22 12:40 symbol.txt -> link.txt

Первая строка содержит информацию о файле, а во второй — находится символьная ссылка. Как видите, у нее открыт абсолютно полный доступ. Если создать ссылку для файла /etc/shadow и не изменить ее права, то можете попрощаться с паролями, их украдут или обнулят. Помните, что любая операция по изменению файла символьной ссылки затрагивает непосредственно сам файл.

Если вы решили использовать символьные ссылки, то не забудьте об особенности формирования прав доступа на файлы. Можете даже выбить на мониторе надпись: "Ссылки на файлы создаются с полными правами!!!"

 

4.2. Управление группами

 

Начнем изучение вопроса с создания групп. Что это такое? Допустим, что в вашей сети 1000 пользователей, 500 из которых должны иметь доступ к файлам бухгалтерской отчетности. Как поступить? Можно каждому из 500 пользователей назначить права на нужный файл и забыть об этом до определенного времени. А теперь представим, что нужно отменить это разрешение. Опять выполнять 500 команд для каждого пользователя? А может быть писать собственную программу? Оба способа неудобны и требуют больших усилий.

Что если объединить этих пользователей в группу, а уже ей дать право на использование определенного файла. Впоследствии, если нужно запретить доступ, то одной командой отключаем разрешение для группы, и все 500 пользователей больше не смогут работать с файлом. Удобно? Даже очень.

В ОС Red Hat Linux все пользователи приписываются к какой-либо группе. Если при введении новой учетной записи группа не указана, то она будет создана по умолчанию под именем пользователя.

 

4.2.1. Добавление группы

Для создания новой группы используется команда groupadd. Она выглядит следующим образом:

groupadd [-g gid [-о]] [-r] [-f] имя

После имени команды можно указывать следующие параметры:

□ -g gid — идентификатор группы. Это неотрицательное число, которое должно быть уникально. Если вы ввели значение, которое уже используется в системе, то для нормальной отработки команды нужно добавить еще и ключ -o. В большинстве случаев идентификатор вообще не нужно указывать. Тогда система возьмет первое свободное значение, начиная с 500;

□ -r — этот ключ указывает на необходимость создания системной группы. Идентификаторы таких групп находятся в диапазоне от 0 до 499. Если в явном виде не указано значение параметра -g, то будет выбрано первое свободное число менее 500;

□ -f — блокирует создание групп с одинаковыми именами. Если указать этот ключ, то команда отработает, но новая группа не сформируется, а уже существующая не будет обновляться.

Если какие-либо параметры не указаны, то будут использоваться значения по умолчанию. Рассмотрим примеры создания групп (после знака "#" идет комментарий, поясняющий работу команды):

groupadd testgroup1 # Создать группу testgroup1 с ID по умолчанию

groupadd -g 506 testgroup2 # Создать группу testgroup1 с ID 506

groupadd -r testgroup3 # Создать группу testgroup1 с системным ID

                       #(менее 500) по умолчанию

Вся информация о группах добавляется в файл /etc/group. Откройте его содержимое, например, в МС или наберите в командной строке:

cat /etc/group

Эта команда выводит на экран содержимое файла, в самом конце которого вы увидите три строки с информацией о добавленных нами группах:

testgroup1:x:500:

testgroup2:x:506:

testgroup3:x:11:

Файл состоит из 4 колонок: имя группы, пароль, идентификатор, список пользователей. Колонки разделены знаком двоеточия.

В первой группе мы не указывали идентификатор, поэтому система выбрала значение по умолчанию. Во второй — в явном виде задан номер группы. В последней строке идентификатор равен 11, потому что был запрошен номер по умолчанию из системного диапазона (использовался ключ -r).

Последняя колонка (после третьего двоеточия) ничего не содержит. Здесь должен быть список пользователей группы, но он пуст, потому что мы еще его не формировали.

 

4.2.2. Редактирование группы

Для редактирования параметров группы можно напрямую изменять файл /etc/group, но я рекомендую лучше использовать команду groupmod. У этой команды такие же ключи, что и у groupadd, но она не добавляет группу, а изменяет параметры уже существующей.

 

4.2.3. Удаление групп

Теперь рассмотрим, как можно удалить группу. Для этого используется команда groupdel:

groupdel имя

При выполнении этой команды вы должны самостоятельно проверить все файлы, владельцем которых является удаляемая группа, и при необходимости изменить собственника, иначе к таким файлам сможет получить доступ только root-администратор.

Надо еще заметить, что группу нельзя удалить, если в ней есть пользователи. Сначала их нужно вывести из группы, и только потом выполнять команду groupdel.

 

4.3. Управление пользователями

 

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

Команда выглядит следующим образом:

useradd параметры имя

Параметров очень много, большинство из них вам знакомо по файлу /etc/password, который мы рассматривали в гл. 3. Рассмотрим каждый аргумент:

□ -с — простое текстовое описание, которое может быть любым;

□ -d — домашний каталог пользователя;

□ -e — дата отключения учетной записи, после которой пользователь станет неактивным, вводится в формате ГГГГ-ММ-ДД;

□ -f — количество дней до отключения. Похоже на параметр -е, только указывается период относительно текущей даты. Если запись нужно отключить сразу после создания, то используйте значение 0. По умолчанию устанавливается -1, что соответствует бесконечности, т.е. запись будет активной всегда;

□ -g — основная группа, которой будет принадлежать пользователь. Можно указывать как имя, так и идентификатор. В Red Hat каждый пользователь принадлежит какой-либо группе;

□ -G, [...] — дополнительные группы, в которых будет существовать пользователь. Имена групп перечисляются через запятую;

□ -m — ключ для создания домашнего каталога пользователя. В такую директорию будут скопированы все файлы из /etc/skel;

□ -M — не создавать домашний каталог. По умолчанию директория формируется в /home/ИмяПользователя, чтобы этого избежать, нужно явно прописать в команде запрет;

□ -r — если указать этот параметр, то в качестве идентификатора будет выбрано число из системной области;

□ -p — зашифрованный пароль, который можно получить с помощью команды crypt;

□ -s — командный интерпретатор, который будет обрабатывать директивы пользователя;

□ -u — идентификатор, который должен быть уникальным. Если его не устанавливать, то система выберет свободное значение.

Самый последний параметр — имя создаваемой учетной записи. Давайте рассмотрим, как можно добавить нового пользователя по имени robert, для которого все значения будут установлены по умолчанию:

useradd robert

cat /etc/passwd

В первой строке мы создаем нового пользователя по имени robert. Вторая строка выводит на экран содержимое файла /etc/passwd, где хранится информация о всех учетных записях. И заключительная строка в нем будет выглядеть следующим образом:

robert:x:501:501::/home/robert:/bin/bash

Вспомните формат этого файла, который мы рассматривали в разд. 3.3. Первый параметр — это имя. Затем стоит пароль, который спрятан в теневом файле, поэтому здесь x. Далее следуют идентификаторы пользователя и группы. Так получилось, что в обоих случаях свободными оказались номера, равные 501, поэтому идентификаторы одинаковы, но это далеко не всегда так. Потом идет домашний каталог пользователя. По умолчанию все директории создаются в папке /home и соответствуют имени пользователя.

Давайте посмотрим файл /etc/shadow. Обратите внимание, что в строках пользователей robert и Denver стоит два восклицательных знака, мы не указывали пароль и войти в систему не можем. Я и не советую его задавать при создании пользователя. Это лишние мучения, потому что нужно шифровать его функцией crypt, при этом нет гарантии сложности пароля. Лучше изменить его после создания пользователя с помощью команды passwd:

passwd robert

В ответ на это вы увидите приглашение ввести пароль и пояснения о необходимости делать его сложным. Сообщение, которое выдает программа, выглядит следующим образом:

Changing password for user robert.

You can now choose the new password or passphrase.

A valid password should be a mix of upper and lower case letters,

digits and other characters. You can use an 8 character long

password with characters from at least 3 of these 4 classes,

or a 7 character long password containing characters from all

the classes. Characters that form a common pattern are discarded by the check.

A passphrase should be of at least 3 words, 12 to 40 characters

long and contain enough different characters.

Alternatively, if no one else can see your terminal now, you can

pick this as your password: "trial&bullet_scare".

Что по-русски звучит примерно следующим образом:

Изменяется пароль для пользователя robert.

Сейчас вы можете выбрать новый пароль или идентификационную фразу.

Хороший пароль должен состоять из комбинации заглавных и прописных

букв, цифр и других знаков. Вы можете ввести пароль длиной в 8 символов

с использованием значений 3 и 4 типов или пароль из 7 символов,

сочетающий знаки всех классов. Символы из часто используемых шаблонов будут отвергнуты.

Идентификационная фраза должна состоять из 3 слов общей длиной от 12 до

40 символов и содержать разнообразные знаки.

В качестве альтернативы, если в данный момент никто не смотрит

на ваш терминал, можно использовать пароль trial&bullet_scare.

Как видите, команда passwd знакомит нас с основными правилами создания сложных паролей и даже предлагает пример, который достаточно длинный и содержит различные символы. Но я не стал бы его использовать, потому что он состоит из вполне читаемых слов. Злоумышленник может запустить подбор паролей по словарю, где различные слова объединяются, как это делает passwd. Такая процедура займет значительно больше времени, чем подбор пароля из одного слова, но зато намного меньше, чем для шифра типа OLhslu_9&Z435drf. Для нахождения этого пароля словарь не поможет, а полный перебор всех возможных вариантов отнимет годы.

А давайте посмотрим, что сейчас находится в домашнем каталоге нового пользователя. Вы думаете, что там ничего нет? Проверим. Перейдите в каталог /home/robert или выполните следующую команду:

ls -al /home/robert

Ключ -a заставляет отображать все файлы (в том числе и системные), а -l — выводит подробную информацию. Результат выполнения такой команды должен выглядеть примерно следующим образом:

drwx------ 3 robert robert 4096 Nov 26 16:10 .

drwxr-xr-x 5 root   root   4096 Nov 26 16:21 ..

-rw-r--r-- 1 robert robert   24 Nov 26 16:10 .bash_logout

-rw-r--r-- 1 robert robert  191 Nov 26 16:10 .bash_profile

-rw-r--r-- 1 robert robert  124 Nov 26 16:10 .bashrc

-rw-r--r-- 1 robert robert 2247 Nov 26 16:10 .emacs

-rw-r--r-- 1 robert robert  118 Nov 26 16:10 .gtkrc

drwxr-xr-x 4 robert robert 4096 Nov 26 16:10 .kde

Обратите внимание, что в директории 6 файлов и один подкаталог. Самое интересное находится в третьей и четвертой колонках, где располагаются имя и группа владельца файла соответственно. В обоих столбцах почти везде указано имя robert. Если пользователя с таким именем мы только что создали, то группу — нет. Вспомните разд. 4.2. При отсутствии параметров настройки автоматически формируется группа с таким же именем, что и учетная запись, и туда сразу же помещается все необходимое о новом пользователе.

Еще один нюанс. Папка с именем из двух точек (..), указывающая на родительский каталог, принадлежит root. Почему? Пользователь robert — владелец текущей директории /home/robert, (он здесь хозяин), но каталог выше /home вне его прав.

Все файлы и папки, которые принадлежат учетной записи robert, доступны для чтения и записи. Пользователи группы robert и все остальные могут только просматривать информацию, а разрешения на изменение у них нет.

 

4.3.1. Файлы и папки нового пользователя

Откуда берутся файлы в папке нового пользователя? При формировании учетной записи в соответствующую домашнюю папку копируются все файлы и подкаталоги из /etc/skel. Давайте создадим свой файл в этой директории и посмотрим, попадет ли он в папку нового пользователя? Чтобы ничего не выдумывать, выполним следующую директиву:

ls >> /etc/skel/text

Здесь задается команда is для просмотра содержимого текущего каталога. Потом идет два символа ">>" и имя файла "text" в папке /etc/skel. Такая запись означает, что результат выполнения команды должен быть помещен в указанный файл. Если файл не существует, то он будет создан. Таким образом, мы подготовили в нужной директории новый файл, содержимое которого нас не особо волнует.

Теперь добавляем нового пользователя и просматриваем содержимое его папки:

useradd Denver

ls -al /home/Denver

В результате вы увидите, что созданный нами в каталоге /etc/skel файл был скопирован в папку нового пользователя. В директориях уже существующих пользователей этого файла не будет.

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

Среди файлов, копируемых в каталог нового пользователя, есть bash_profile. Это профиль командного интерпретатора /bin/bash. В нем можно настраивать некоторые параметры, в том числе и маску. В разд. 4.1 мы говорили о правах, которые назначаются всем новым файлам пользователя (далеки от идеала), и научились понижать их с помощью команды umask.

Зайдите под учетной записью robert и посмотрите маску с помощью команды umask. Обратите внимание, что она равна 0002. То есть мы в разд. 4.1 изменили маску своего пользователя, a robert получил другую, которую надо изменить. Если вы забудете это сделать, то могут возникнуть проблемы. Чтобы этого не произошло, я рекомендую добавить в конец файла bash_profile строку:

umask 0077

Лучше всего это сделать в файле /etc/skel/bash_profile, потому что он копируется во все папки новых пользователей, и можно быть уверенным, что все они получат нужную маску.

Для повышения безопасности я не рекомендую присваивать директориям имена учетных записей. При добавлении пользователя robert по умолчанию для него будет создан каталог /home/robert. Такое соответствие может сыграть злую шутку. Если злоумышленник узнает директорию, то он легко сможет определить имя пользователя, которому она принадлежит, и наоборот.

При создании пользовательских директорий достаточно даже просто добавить к имени какой-либо префикс, и это уже может усложнить задачу злоумышленнику.

 

4.3.2. Изменение настроек по умолчанию

Давайте теперь посмотрим, откуда берутся значения по умолчанию. Все это хранится в файле /etc/default/useradd. Взглянем на содержимое этого файла:

# useradd defaults file

GROUP=100

HOME=/home

INACTIVE=-1

EXPIRE=

SHELL=/bin/bash SKEL=/etc/skel

Этот файл можно редактировать вручную или воспользоваться командой useradd для изменения значений по умолчанию. Как это делать, мы рассмотрим чуть позже.

Единственный комментарий, который я хочу сделать сейчас, — это параметр GROUP. Он равен 100, и но идее все новые пользователи должны попадать в эту группу. Но как мы видели в разд. 4.3, это не так. В Red Hat этот параметр игнорируется, и по умолчанию создается новая группа, именно это мы и наблюдали. В других дистрибутивах этот параметр может работать, поэтому проверьте эту возможность, чтобы не оказаться в неудобном положении.

Номер 100 присваивается пользовательской группе, у которой по умолчанию очень мало прав. Это как гостевой пароль, который позволяет только просматривать файлы.

Но созданием пользователя команда useradd не ограничивается. Дело в том, что если не указать какой-либо параметр, то ему будет присвоено значение по умолчанию. Чтобы внести изменения, нужно сразу после имени команды указать ключ -D. После этого могут идти следующие опции:

□ -g — изменить группу;

□ -b — установить домашний каталог;

□ -f — время до отключения;

□ -e — дата отключения;

□ -s — оболочка (интерпретатор команд).

Я советую вам не игнорировать возможность указания времени действия учетной записи. Допустим, что к вам пришли с инспекцией и просят дать доступ к базе данных или определенным файлам. Создайте для проверяющих нового пользователя и установите время жизни в 1 день (или более, если инспекция приехала надолго). В этом случае вам не надо напрягать память или фиксировать в блокнот, что в определенный день требуется удалить такую учетную запись, потому что она сама станет неактивной.

Некоторые администраторы плодят временных пользователей, забывая их удалить. А ведь это достаточно большая дыра в безопасности, т.к. эти учетные записи чаще всего имеют простой пароль. Действительно, зачем запоминать (на один-два дня) что-то типа opilivgdjwbe. Отключив запись (автоматически или вручную), вы закрываете один из проходов в вашу систему и сокращаете количество лазеек. Когда вы возвращаетесь домой, то обязательно закрываете за собой дверь для собственной безопасности. В случае с ОС надо поступать таким же образом, и, проводив временного гостя, нужно обязательно запереть дверь или замуровать ее (удалить из системы).

 

4.3.3. Редактирование пользователя

Для редактирования параметров учетной записи можно напрямую корректировать файл /etc/passwd, но я советую лучше использовать команду usermod. У нее такие же ключи, что и у useradd, но она не создает пользователя, а изменяет параметры уже существующего.

С помощью usermod вы можете добавлять уже имеющегося пользователя в ранее созданную группу. Давайте проделаем такую процедуру с учетной записью robert и определим ее в группу root. Это позволит пользователю robert выполнять некоторые административные функции:

usermod -G root robert

Здесь мы выполняем команду с ключом -G, который позволяет указать, членом каких групп должен быть пользователь (в данном случае root). Можно перечислить несколько групп, разделяя их запятыми. Для получения более подробной информации о команде usermod выполните man usermod.

Параметры у команды usermod такие же, как и у useradd.

 

4.3.4. Удаление пользователя

Для удаления пользователя применяется команда userdel. В качестве параметра передается только имя учетной записи, которую надо удалить, и можно распрощаться с ней навсегда. Например:

userdel Danver

Будет получено сообщение об ошибке, если пользователь в этот момент находится в системе.

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

userdel -r Danver

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

К тому же, если для пользователя была автоматически создана группа и в ней никого больше нет, то можно произвести и ее удаление, но сделать это придется командой groupdel.

 

4.3.5. Несколько замечаний

Для полного понимания процесса создания учетных записей нам нужно познакомиться еще с файлом /etc/login.defs. В нем хранятся настройки, которые будут использоваться при добавлении пользователей. Содержимое файла можно увидеть в листинге 4.1.

Листинг 4.1. Файл /etc/login.defs

#*REQUIRED*

# Directory where mailboxes reside, _or_ name of file, relative to the

# home directory. If you _do_ define both, MAIL_DIR takes precedence.

# QMAIL_DIR is for Qmail

#

#QMAIL_DIR Maildir

MAIL_DIR /var/spool/mail

#MAIL_FILE .mail

# Password aging controls:

#

#PASS_MAX_DAYS Maximum number of days a password may be used.

#PASS_MIN_DAYS Minimum number of days allowed between password changes.

#PASS_MIN_LEN Minimum acceptable password length.

#PASS_WARN_AGE Number of days warning given before a password expires. #

PASS_MAX_DAYS 99999

PASS_MIN_DAYS     0

PASS_MIN_LEN      5

PASS_WARN_AGE     7

#

# Min/max values for automatic uid selection in useradd

#

UID_MIN 500

UID MAX 60000

#

# Min/max values for automatic gid selection in groupadd #

GID_MIN 500

GID_MAX 60000

#

# If defined, this command is run when removing a user.

# It should remove any at/cron/print jobs etc. owned by

# the user to be removed (passed as the first argument).

#

#USERDEL_CMD /usr/sbin/userdel_local

#

# If useradd should create home directories for users by default

# On RH systems, we do. This option is ORed with the -m flag on

# useradd command line.

#

CREATE_HOME yes

Здесь находятся интересные установки, которые можно использовать для повышения безопасности. Рассмотрим основные параметры файла:

□ MAIL_DIR — директория, в которой будет храниться почта пользователей;

□ PASS_MAX_DAYS — максимальный срок жизни пароля;

□ PASS_MIN_DAYS — минимальный срок жизни пароля;

□ PASS_MIN_LEN — минимальная длина пароля (используется только в команде passwd и игнорируется в useradd). В большинстве дистрибутивов здесь будет стоять 5. Я рекомендую поменять его на число 8. В этом случае нельзя будет установить любимый большинством пользователей пароль типа qwerty;

□ PASS_WARN_AGE — срок (в днях) до окончания действия пароля, когда об этом нужно предупредить пользователя;

□ UID_MIN — минимальный идентификатор пользовательских учетных записей;

□ UID_MAX — максимальный идентификатор пользовательских учетных записей;

□ GID_MIN — минимальный идентификатор пользовательских групп;

□ GID_MAX — максимальный идентификатор пользовательских групп;

□ CREATE_HOME — признак создания пользовательской директории (значение параметра YES, стоит по умолчанию).

 

4.3.6. Взлом паролей

Я еще раз хочу напомнить о недопустимости использования простых паролей не только для администратора, но и для всех пользователей системы. Если проследить за уязвимостями, которые находят в Linux-системах, то очень часто можно увидеть сплоиты, которые позволяют повысить права хакера от простого пользователя до root. Если взломщик не сможет получить доступ даже в качестве простого пользователя, то и воспользоваться сплоитом будет невозможно.

Сложные пароли должны быть абсолютно у всех пользователей. Если хакер получит доступ к файлу /etc/shadow с 1000 записями, то подбор паролей весьма упрощается. Вспомните, как хранятся пароли. Они зашифрованы необратимым образом. Это значит, что при простом переборе каждый возможный вариант тоже шифруется, а потом сравнивается с результатом из файла /etc/shadow. За счет того, что кодирование отнимает достаточно много процессорного времени, сопоставление становится слишком продолжительным.

Подбирать сложно, если вы сравниваете только с одной записью. А если в системе 1000 пользователей, то достаточно один раз зашифровать возможный вариант пароля и потом соотнести его с 1000 записями в файле паролей. Вероятность попадания увеличивается в несколько раз и подбор упрощается.

Когда хакеры получают файл /etc/shadow, то первым делом запускается проверка всех записей, в которых имя пользователя и пароль одинаковы. Вы не поверите, но такое встречается очень часто, и если файл паролей большой, то с вероятностью 0,9 можно сказать, что хакер найдет такую запись.

Если это не помогло, то в ход идет перебор всех часто используемых слов. Вот тут уже вероятность попадания близка к 100%, потому что из десяти пользователей один обязательно будет новичком и установит простой пароль. Вы должны проводить обучение каждого нового пользователя (в частности, по вопросу указания пароля) и самостоятельно запускать программу сопоставления паролей с часто используемыми словами. Если вам удалось подобрать, то хакер тем более сделает это.

 

4.4. Типичные ошибки распределения прав

Строгое распределение прав может значительно обезопасить систему. При правильной регламентации доступа большинство взломов могут оказаться неэффективными. Например, однажды в Интернете появилось сообщение, что один из сервисов ОС Linux содержит ошибку. Благодаря хорошему распределению прав мой сервер оказался защищенным от проникновения через эту дыру. Злоумышленник мог пробраться на сервер, но ничего изменить или удалить нельзя, потому что внешним пользователям этого сервиса все файлы открыты только для чтения.

Итак, если у вас хорошо настроены права доступа, то это может оказаться непреодолимой преградой для злоумышленника.

Давайте рассмотрим классический пример с файлами и каталогами. Допустим, что у вас на каталог поставлены максимальные права drwxrwxrwx (или 777), а на все файлы в нем — -rw-------. По идее, только владелец файла может его модифицировать, но это не совсем так. Да, злоумышленник не сможет изменить сам файл, но список документов в директории ему доступен (разрешены чтение и корректировка). Благодаря этому взломщик просто удалит нужный файл и создаст другой с новыми правами без каких-либо преград.

Чтобы этого не произошло, вы должны ограничивать доступ не только к файлам, но и каталогам.

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

Допустим, что у вас есть каталог shared. Для того чтобы в нем могли удалять файлы только владельцы, нужно установить для него sticky-бит. Это делается командой chmod с параметром +t:

chmod +t shared

Попробуйте выполнить команду ls -al и посмотреть права доступа к каталогу. Вы должны увидеть drwxrwxrwt. Обратите внимание, что на месте символа x для всех пользователей стоит "t". Как раз он и указывает на установленный sticky-бит. Теперь попробуйте удалить из этой директории файл, принадлежащий другому пользователю. Вы увидите сообщение "rm: cannot unlink 'имя файла': Operation not permitted".

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

В Linux есть каталог /tmp, для которого как раз установлены права drwxrwxrwx, и в нем сохраняются временные данные всех пользователей. В современных дистрибутивах на этот каталог уже выставлен sticky-бит.

Проверьте, если в вашей системе это не так, то установите его самостоятельно, чтобы никто не смог удалить чужие временные файлы.

 

4.5. Привилегированные программы

В гл. 3 я уже намекал про существование еще двух битов доступа — SUID и SGID, и теперь пора с ними познакомиться поближе. Допустим, что пользователя необходимо ограничить в правах, чтобы он не натворил бед, но при этом дать возможность запускать программу, к которой требуется специальный доступ. В этом случае можно установить SUID-бит, тогда и программа сможет работать (от имени владельца), и у пользователя не будет лишних привилегий.

SUID-бит можно установить командой chmod с параметром u+s:

chmod u+s progname

Если теперь просмотреть права доступа к файлу, то они превратятся в -rwsr-xr-x. Как видите, появилась буква "s" на том месте, где должно быть разрешение на запуск (символ "x") для владельца файла.

Бит SGID похож на SUID, но он позволяет запускать программу с правами группы владельца файла. Этот бит устанавливается подобным образом командой chmod с параметром g+s:

chmod g+s progname

В этом случае права доступа к файлу будут -rwxr-sr-x. Вместо символа "x" (право на запуск для группы владельца файла) появилась буква "s".

Привилегии SUID и GUID достаточно удобны и полезны, но, с другой стороны, они таят в себе очень много проблем. Например, гость, обладающий минимальными правами, запускает программу с установленным битом SUID, владельцем которой является пользователь root. Это значит, что программа будет работать с правами root, а не гостевыми параметрами пользователя. Если в ней окажется ошибка, через которую можно выполнять команды на сервере, то эти директивы будут реализовываться от имени владельца программы, т.е. root. Таким образом, даже если взломщик сам не имеет возможности претворять в жизнь команды, то через привилегированную программу сможет получить доступ к запрещенной области.

Биты SUID и GUID нужно использовать аккуратно, и в любом случае владельцем программ не должен быть root или другой привилегированный пользователь. Лучше, если это будет специально заведенная для этой программы учетная запись, которая обладает только теми правами, которые необходимы пользователю.

Рассмотрим еще один пример. Допустим, гость не должен иметь прямого доступа к каталогу /home/someone, а для работы программы он необходим. Чтобы не открывать ему лишних возможностей, нужно завести отдельного пользователя с правами доступа на каталог /home/someone, сделать его владельцем программы и установить бит SUID. Если в программе будет найдена ошибка, то взломщик получит доступ к /home/someone, но все остальные разделы диска останутся недоступными.

Такая политика соответствует нашему основному правилу "Что не разрешено, то запрещено" и обеспечит максимальную безопасность сервера.

 

4.6. Дополнительные возможности защиты

Помимо прав доступа у любого файла есть еще и атрибуты, которые позволяют построить дополнительную стену безопасности на пути взломщика. Единственное условие — атрибуты могут использоваться только на файловых системах Ext2 и Ext3. Но ограничением это можно назвать с большой натяжкой, потому что Ext3 уже давно становится стандартом для всех дистрибутивов.

Просмотреть текущие атрибуты можно с помощью команды lsattr:

lsattr filename.txt

-------------- filename.txt

Первая строка демонстрирует использование команды, а во второй — отображается результат работы. Как видите, мы получили набор символов тире вместо атрибутов, а значит, ни один из них не определен.

Для установки атрибута применяется команда chattr:

chattr атрибуты файл

Если требуется рекурсивное изменение доступа к каталогу и всем содержащимся в нем файлам и подкаталогам, можно использовать ключ -R. В этом случае вместо имени файла укажите директорию.

Приведу перечень атрибутов, применяемых в команде chattr:

□ A — не создавать метку atime записи времени последнего обращения к файлу. С точки зрения безопасности этот атрибут несет отрицательный эффект, потому что по дате обращения можно контролировать, когда файл был модифицирован. Поэтому не рекомендую устанавливать этот флаг. Но если у вас под ОС Linux работает личный компьютер, и нет необходимости отслеживать историю изменений, то можно установить этот атрибут, тем самым уменьшить количество обращений к диску (избавитесь от лишней операции записи при сохранении файла);

□ a — позволяет открывать файл только в режиме добавления. Это значит, что уже существующие данные изменить или удалить нельзя;

□ d — игнорирует файл при копировании. Этот флаг позволяет уменьшить размер резервной копии, но устанавливать его нужно только на файлы, не имеющие ценности и важности, например, временные;

□ i — запрещает выполнение с файлом каких-либо действий по корректировке (изменение, удаление, переименование, создание ссылок);

□ s — делает невозможным восстановление файла после удаления. Все пространство на диске, где был файл, будет заполнено нулями;

□ S — во время изменения файла все действия будут фиксироваться на жестком диске.

Для установки атрибута перед ним нужно поставить знак плюс, для снятия — знак минус. Рассмотрим несколько примеров:

chattr +i test

chattr +s test

lsattr test

s--i----------- test

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

Итак, у нашего файла два взаимоисключающих атрибута. Один запрещает изменения, другой требует полного стирания с диска. Что произойдет, если мы попытаемся удалить файл. Посмотрим?

rm test

rm: remove write-protected file "test"?

В первой строке мы выполняем команду удаления файла. На это ОС просит подтвердить операцию над защищенным от записи файлом (сообщение показано во второй строке). Как видите, ОС определила наш атрибут i. Попробуйте ввести букву "Y", чтобы удостоверить действие. Вы увидите сообщение об ошибке, и файл останется на месте.

Давайте снимем атрибут i:

chattr -i test

lsattr test

s-------------- test

После отмены атрибута я использовал команду lsattr , чтобы убедиться в правильности выполнения команды. Вот теперь файл легко удалить с помощью команды rm.

 

4.7. Защита служб

 

В данной книге будет рассматриваться множество серверных служб. Безопасность их работы для системы в целом зависит не только от правильной настройки самой службы, но и от прав, которые вы ей дадите. Хакеры очень часто атакуют определенные сервисы и ищут в них изъяны, через которые можно было бы проникнуть в систему, а как мы знаем, ошибки есть всегда и везде.

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

Как произошел взлом? На сайте стоял форум phpBB. Это один из популярных движков и абсолютно бесплатный, поэтому его выбирают многие владельцы сайтов. Большинство хакеров стремятся найти ошибки в наиболее известных разработках, и иногда им это удается. Только своевременное обновление форума (в данном случае) позволяет защититься от нападения.

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

Давайте на примере абстрактного сайта www.sitename.com посмотрим, как происходило вторжение. На форуме нужно войти в просмотр какой-нибудь темы, и в строке адреса появится ссылка:

http://www.sitename.com/forum/viewtopic.php?p=5583

Если к этой ссылке добавить в конец текст

&highlight=%2527.$poster=%60команда Linux%60.%2527,

то указанная команда Linux выполнится на сервере.

Вот так, например, можно было просмотреть файлы каталога /etc на сервере:

&highlight=%2527.$poster=%60ls%09/etc%09-la%60.%2527

А вот эта команда могла удалить главную страницу сайта:

&highlight=%2527.$poster=%60rm%09index.php%60.%2527

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

А ведь опасность можно уменьшить, ограничив права Web-сервера в ОС. Для этого администраторы должны создать виртуальную среду для выполнения Web-сервиса и страницы, при этом все остальные разделы сервера становятся недоступными для злоумышленника. В этом случае и каталог /etc окажется недосягаемым, и максимальный вред, который сможет нанести злоумышленник, — уничтожить сайт и нарушить работу Web-сервиса, но все остальные будут трудиться в штатном режиме. Восстановить один сервис проще, чем налаживать абсолютно все.

После этого случая я целый день бродил по Интернету в поисках уязвимых форумов, и таких оказалось много, потому что администраторы сайтов явно не следят за обновлениями. Я думаю, что в скором времени эти администраторы пройдут через все круги ада. Рано или поздно взломщик найдет форум, и в этом случае нужно молиться, чтобы он не уничтожил всю базу, а только пошалил. Хочется еще раз напомнить о необходимости обновления всех программ, сервисов и самой ОС. Если вы сможете исправить ошибку раньше хакера, то обезопасите свою жизнь.

Во время поисков уязвимых форумов я просматривал возможность получения доступа к каталогу /etc, чтобы увидеть не только количество неопытных владельцев сайтов, но и некомпетентных администраторов. Вы не поверите, но доступ открыт, наверное, на 90% серверов. Это безграмотность администраторов или их лень? Не знаю, и точно сказать не могу. Только крупные серверы были защищены, а мелкие хостинговые компании явно экономят на заработной плате хороших администраторов.

 

4.7.1. Принцип работы

Итак, давайте рассмотрим принцип работы защиты служб. Для этого создается директория, которая является для программы корневой. В Linux для этого существует команда chroot, которая создает chroot-окружение. Получается псевдокорневая файловая система внутри существующей.

Выше этой директории программа, работающая в окружении chroot, попасть не может. Посмотрите на рис. 4.1. Здесь показана часть файловой системы Linux. Во главе всего стоит корневая директория /. В ней находятся /bin, /usr, /var, /home. В папке /home расположены каталоги пользователей системы. Мы создаем здесь новую директорию, для примера назовем ее chroot, и она станет корнем для службы. В ней есть свои каталоги /bin, /usr и т.д., и сервис должен работать с ними, а все, что выше /home/chroot, будет недоступно.

Рис. 4.1. Схема работы chroot-окружения

На рис. 4.1 в рамку обведены папки, которые видны службе. Именно в этом пространстве будет работать сервис, считая, что это и есть реальная файловая система сервера.

Если хакер проникнет в систему через защищенную службу и захочет просмотреть директорию /etc, то он увидит каталог /home/chroot/etc, но никак не системный /etc. Чтобы взломщик ничего не заподозрил, в папке /home/chroot/etc можно расположить все необходимые файлы, но содержащие некорректную информацию. Злоумышленник, запросив файл /etc/passwd через уязвимый сервис, получит доступ к /home/chroot/etc/passwd, потому что служба видит его системным.

Так, например, файл /home/chroot/etc/passwd может содержать ложную информацию. На работу системы в целом это не повлияет, потому что ОС будет брать пароли из файла /etc/passwd, а службе реальные коды доступа в систему не нужны, поэтому в файл /home/chroot/etc/passwd можно засунуть все, что угодно.

 

4.7.2. Установка jail

Встроенная в Linux-систему программа chroot для создания "Виртуальное пространство" виртуальных пространств на сервере сложна и не очень удобна для применения. Нужно выполнить слишком много операций. Именно поэтому администраторы больше любят использовать программу jail, которую можно найти в Интернете по адресу http://www.jmcresearch.com/projeсts/jail/. Скачайте ее и поместите архив в свой каталог. Для того чтобы разархивировать его, нужно выполнить следующую команду:

tar xzvf jail.tar.gz

В текущей директории появится новый каталог jail с исходным кодом программы. Да, именно с исходным, потому что она открыта и поставляется в таком виде.

Теперь нужно перейти в каталог jail/src (cd jail/src) и отредактировать файл Makefile (например, редактором МС). В самом начале файла идет множество комментариев, и их мы опустим. После этого вы сможете увидеть следующие параметры:

ARCH=__LINUX__

#ARCH=__FREEBSD__

#ARCH=__IRIX__

#ARCH=__SOLARIS__

DEBUG = 0

INSTALL_DIR = /tmp/jail

PERL = /usr/bin/perl

ROOTUSER = root

ROOTGROUP = root

Вначале задается тип ОС, по умолчанию установлен LINUX. А следующие три строки для FreeBSD, Irix и Solaris закомментированы. Оставим все, как есть. Что нужно изменить, так это директорию для установки (параметр INSTALL_DIR). В последней версии (на момент написания книги) по умолчанию используется каталог /tmp/jail. Не знаю, зачем это сделали, ведь этот каталог предназначен для временных файлов и должен быть доступен для чтения абсолютно всем. Раньше по умолчанию был /usr/local, и именно его я советую здесь указать. Больше ничего менять не надо.

Для выполнения следующих директив вам понадобятся права root, поэтому войдите в систему как администратор или получите нужные права, запустив команду su root.

Перед компиляцией и установкой убедитесь, что у файла preinstall.sh есть права на выполнение. Если нет, то воспользуйтесь следующей командой:

chmod 755 preinstall.sh

Теперь все готово к установке. Находясь в директории jail/src, выполните команды:

make

make install

Если все прошло успешно, то в каталоге /usr/local/bin должны появиться программы: addjailsw, addjailuser, jail и mkjailenv.

 

4.7.3. Работа с программой jail

Для начала создадим каталог /home/chroot, который станет корневым для программы, на которой мы будем испытывать систему. Для этого выполним команду:

mkdir /home/chroot

Теперь нужно подготовить окружение для нормальной работы будущего сервиса. Для этого выполняем команду:

/usr/local/bin/mkjailenv /home/chroot

Посмотрите, что произошло с каталогом /home/chroot. Здесь появились две директории dev и etc. Как мы знаем, в директории dev должны быть описания устройств. В данном случае программа не стала делать полную копию системного каталога /dev, а ограничилась созданием трех основных устройств null, urandom и zero.

В директории etc можно также увидеть три файла: group, passwd и shadow. Это неполные копии системных файлов. Например, если взглянуть на файл passwd, то он будет содержать только следующие строки:

root:x:0:0:Flenov,Admin:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

nobody:x:99:99:Nobody:/:/sbin/nologin

Больше ничего не будет, и нет пользователя robert, которого мы создавали раньше (см. разд. 4.3). В файле shadow находятся теневые пароли. Проверьте права на этот файл, чтобы они были не более 600 (rw-------).

Тут есть один недостаток в безопасности — в файле /home/chroot/etc/shadow находится реальный зашифрованный пароль из /etc/shadow. Лучше удалите его, иначе злоумышленник, узнав пароль на сервис, сможет проникнуть на сервер через другую дверь, которая не защищена виртуальным каталогом.

Продолжаем настройку виртуальной корневой директории. Теперь нам нужно выполнить следующую команду:

/usr/local/bin/addjailsw /home/chroot

Во время отработки этой команды побежит множество информационных строчек о выполняемых действиях, которые заключаются в том, что в каталог /home/chroot копируются основные директории и программы. Например, в папку /home/chroot/bin будут скопированы такие программы, как cat, cp, ls, rm и т.д., и сервис будет использовать именно их, а не те, что расположены в основном каталоге /bin.

Программа копирует то, что считает нужным, но далеко не все из этого потребуется будущему сервису, который будет работать в виртуальной корневой директории. Лишнее следует удалить, но лучше это делать после того, как убедитесь, что все работает.

Необходимые программы есть и окружение готово. Теперь сюда можно установить сервис:

/usr/local/bin/addjailsw /home/chroot -Р httpd

В данном примере в новое окружение устанавливается программа httpd и все необходимые ей библиотеки. Программа jail сама определит, что нужно.

Теперь в новое окружение можно добавлять пользователя. Это выполняется командой:

/usr/local/bin/addjailuser chroot home sh name

Здесь chroot — это виртуальная корневая директория, в нашем случае должно быть /home/chroot. Параметр home — это домашний каталог пользователя относительно виртуальной директории. Аргументы sh — командный интерпретатор и name — имя пользователя, которого мы хотим добавить (уже должен существовать в основном окружении ОС).

Посмотрим, как можно добавить пользователя robert (он у нас уже есть) в виртуальную систему:

/usr/local/bin/addjailuser /home/chroot \

 /home/robert /bin/bash Robert

У меня команда не уместилась в одну строку, поэтому я сделал перенос с помощью символа (обозначает, что директива не закончилась и есть продолжение в следующей строке).

Если параметры указаны верно, то вы должны увидеть уведомление "Done", иначе будет выведено сообщение об ошибке.

Для запуска сервера httpd (в Linux это сервер Apache) в виртуальном окружении должен быть пользователь apache. В реальной оболочке он есть. Давайте посмотрим его параметры и создадим такого же:

/usr/local/bin/addjailuser /home/chroot \

 /var/www /bin/false apache

Как теперь попасть в новое окружение? Выполните команду:

chroot /home/chroot

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

Чтобы убедиться, что вы находитесь в виртуальном окружении, выполните команду:

ls -al /etc

Вы увидите всего несколько файлов, которые составляют малую часть того, что доступно в реальном каталоге /etc. Можете просмотреть файл /etc/passwd, и в нем будут только пользователи виртуального окружения. Если хакер взломает его, то он получит исключительно эти данные и сможет уничтожить лишь содержимое каталога /home/chroot. Вся остальная файловая система останется целой и невредимой.

Для запуска httpd нужно выполнить в виртуальном окружении команду:

/usr/sbin/httpd

 

4.8. Получение прав root

Теперь у нас есть достаточно информации о доступе, и мы можем рассмотреть типичный метод взломщика для получения прав root и способы маскировки в системе.

Допустим, что злоумышленник приобрел возможность выполнять какие-либо системные команды от имени (с правами) root. Сидеть под этой учетной записью будет слишком опасно и вызывающе. К тому же изменять пароль root нельзя.

Как же тогда входить под другим именем и в то же время использовать максимальные права? Давайте вспомним, как Linux работает с правами. В файле /etc/passwd хранятся записи пользователей в следующем виде:

robert:x:501:501::/home/robert:/bin/bash

Третий и четвертый параметры — это идентификаторы пользователя и группы соответственно. Когда на объекты выделяются права, то система сохраняет только идентификаторы. Что это значит? Допустим, что у вас есть пользователь robert с идентификатором 501. Вы создали еще одного пользователя Dan и дали ему такой же идентификатор. Теперь обе учетные записи с одинаковыми ID будут разделять владение одними и теми же объектами.

Что это нам дает? Посмотрите на идентификатор пользователя root — он равен нулю. Именно нулевой ID, а не имя root указывает на максимальные права. Давайте попробуем учетной записи robert, которую мы создали ранее, поставить вручную идентификаторы пользователя и группы, равные 0. В файле /etc/passwd должна получиться строка:

robert:x:0:0::/home/robert:/bin/bash

Теперь войдите в систему под этой учетной записью и попробуйте снова открыть файл /etc/passwd и внести изменения или просто добавить пользователя. Все пройдет успешно, хотя файл /etc/passwd может изменять только root. Так что система проверяет наши права по идентификатору, который в данном случае нулевой и соответствует максимуму.

Так как имя пользователя ничего не значит, я рекомендую удалить пользователя root в файлах /etc/passwd и /etc/shadow, создать новую запись с другим именем, но идентификатором, равным 0. Злоумышленники, которые попытаются взломать ваш сервер, будут пытаться подобрать пароль для администратора root, но т.к. пользователя с таким именем нет, то их действия окажутся безуспешными.

С другой стороны, пользователя root можно оставить, но установить ему идентификатор больше нуля. Я иногда создаю учетную запись root с UID=501 или выше. Увидев эту запись, взломщик думает, что он обладает всеми правами, но в реальности оказывается простым пользователем.

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

Итак, злоумышленник, проникнув в систему, может не пользоваться учетной записью root, а отредактировать любую другую или добавить еще одну с нулевым идентификатором пользователя и получить максимальные права в системе. Если вы являетесь администратором сервера, то должны отслеживать подобные трансформации и останавливать любые попытки изменения идентификаторов.

Команда id позволяет узнать идентификаторы пользователя. Если она вызывается без параметров, то на экран будут выведены идентификаторы текущего пользователя. Чтобы получить информацию о конкретной учетной записи, нужно выполнить команду:

id имя

Например, давайте посмотрим параметры пользователя robert. Для этого выполним команду:

id robert

Результатом будет строка:

uid=501(robert) gid=501(robert) group=501(robert)

Таким образом в любой момент можно определить идентификатор пользователя и его реальные права.

 

4.9. Расширение прав

Регламентация доступа — достаточно сложный процесс. Это основная задача администратора и от правильности ее выполнения зависит многое. Любая ошибка может стоить вам зарплаты и благополучия. В мире, когда информация является самым дорогим продуктом, вы должны оберегать ее всеми возможными методами.

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

Честно сказать, права на основе "босс", "друзья босса" и "все остальные" устарели и не обеспечивают необходимой безопасности. Например, у вас есть две группы: бухгалтерия и экономисты. Файлы, созданные любым бухгалтером, будут иметь права -rwxrwx--- и станут доступными для всех сотрудников этого отдела, потому что в данных правах группа имеет все разрешения на файл, как и владелец.

А как быть, если теперь нужно, чтобы экономист просмотрел документы бухгалтерии? Причем не все пользователи группы экономистов, а только один, и не все файлы бухгалтерии, а выборочно! Решить эту задачу достаточно сложно. Если поставить на файлы бухгалтерии права -rwxrwxrwx, то любой пользователь сможет просмотреть бухгалтерскую отчетность, а это уже далеко от идеала безопасности.

Можно пытаться выйти из положения через ссылки или копии файлов с другими правами, но в этом случае вы просто запутаетесь, и дальнейшее управление системой станет затруднительным.

Проблему достаточно просто решить, если ввести списки ACL (Access Control List, списки контроля доступа), как это реализовано в ОС Windows. Сложность только с внедрением, т.к. ОС Linux не имеет стандарта. В принципе, это ядро, на которое любой разработчик может повесить все, что угодно, и каждый производитель ищет свои пути выхода из ситуации или вообще ничего не делает.

Я не могу привести универсальный способ, потому что все решения даются сторонними разработчиками. А это значит, что работоспособность системы можно гарантировать только в отношении определенных версий ядра Linux, которые уже существуют. Нельзя поручиться, что при обновлении версии ядра система списков продолжит функционировать и не вызовет проблем.

Именно поэтому я только предложу взглянуть на проект Linux Extended Attributes and ACLs (http://acl.bestbits.at/). Вы можете его использовать только на свой страх и риск.

Linux Extended Attributes and ACLs — продукт, который устанавливается в систему, и после этого требует перекомпиляции ядра. Работа его основана на хранении для каждого файла расширенных атрибутов. Это возможно не на всех файловых системах, поэтому убедитесь, что используемая вами система поддерживает списки ACL. Лучше всего, на мой взгляд, подходят системы ReiserFS и Ext3.

После установки патча и дополнительных программ вам становятся доступны списки ACL. С их помощью можно отдельным пользователям устанавливать режим доступа к файлу. Владельцем файла остается его создатель, и он имеет полные права. Остальные атрибуты доступа могут отсутствовать.

Например, для файла можно установить права -rwx------. Несмотря на такие жесткие требования можно указать пользователей, которые будут иметь доступ к этому файлу помимо владельца.

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

Если бы такой принцип был реализован на уровне ядра и поддерживался всеми дистрибутивами, то я назвал бы ОС Linux самой безопасной и стабильной в мире операционной системой.

 

4.10. Сетевой экран

 

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

Для защиты компьютера от вторжения по сети используется сетевой экран (Firewall). Некоторые службы Linux также имеют свои настройки прав, но их мы будем рассматривать отдельно, когда дойдем до соответствующего сервиса. И все же, я не советую сильно доверять такому управлению. Не забываем, что ошибки есть во всех программах, и если сетевой экран будет дублировать права, прописанные в сервисе, хуже от этого не будет.

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

Почему же тогда мы рассматриваем сетевой экран после прав доступа на файлы? Да потому, что Firewall защищает только от сетевых вторжений, а правильная регламентация доступа предохраняет и от локальных хакеров или недобросовестных пользователей, которые получили возможность пользоваться непосредственно терминалом. Оба уровня защиты очень важны. В сфере безопасности вообще нет ничего несущественного, вы должны уделять внимание каждой мелочи.

Сетевой экран позволяет ограничить доступ к компьютеру в целом или к отдельным портам, на которых работают сервисы, но не является 100% защитой от вторжения. Это всего лишь проверка пакетов на соответствие правилам, которая не может гарантировать, что пользователь является реальным отправителем.

Простейший способ обхода сетевого экрана — подделка IP-адреса. Например, мне приходилось работать в сети, где простым пользователям запрещалось использовать почтовые протоколы SMTP и POP3 (подключение на 25 и 110 порты соответственно). Я относился к этой категории и не мог получать или отправлять почту, но доступ был у моего начальника. Использование Web-интерфейса для работы с почтовыми сервисами также блокировалось на уровне прокси-сервера. Однажды мне очень срочно нужно было отправить письмо. Для этого я выполнил следующее:

□ дождался, когда начальник выйдет из кабинета;

□ выключил его компьютер;

□ сменил свой IP-адрес на установленный на его компьютере;

□ спокойно отправил почту и вернул свой старый IP-адрес.

Когда начальник вернулся, он подумал, что компьютер просто завис, и ничего не заподозрил, а я без проблем смог воспользоваться сервисом, который был запрещен для меня.

Есть множество способов обхода сетевых экранов (не считая ошибок в программах), и все же, правильная конфигурация сможет обеспечить спокойный сон администратора и специалиста по безопасности.

В ОС Linux в качестве Firewall выступает программа, которая фильтрует информацию на основе определенных правил, в которых должно быть четко прописано, какие пакеты могут обрабатываться или отправляться в сеть, а какие нет. Благодаря этому большинство атак могут захлебнуться уже на входе в компьютер, потому что сетевой экран не позволит сервисам даже увидеть потенциально опасные пакеты.

Сетевой экран может быть установлен на каждом компьютере в отдельности (защищать его в зависимости от выполняемых задач) или на входе в сеть (см. рис. 4.2). Во втором случае Firewall реализует общие настройки безопасности для всех компьютеров в сети.

Рис. 4.2. Firewall для защиты сети

Если в вашей сети очень много компьютеров, то управлять ими и обновлять политику безопасности становится затруднительным. Установка единого сервера с Firewall позволяет упростить эти процедуры. Лучше всего, если компьютер с сетевым экраном выступает как шлюз или как анонимный прокси- сервер для доступа в Интернет остальных участников сети. В этом случае хакер изначально будет видеть только этот компьютер, а остальные как бы прячутся за занавеской. Чтобы проникнуть на любую машину в сети, злоумышленник должен будет сначала получить доступ к компьютеру с Firewall. Таким образом, защита целой сети упрощается. Подробней о прокси-серверах вы можете узнать в гл. 9.

Но во всех сетевых экранах есть одно слабое звено — они программные и используют ресурсы сервера. Современные маршрутизаторы тоже могут решить большинство проблем, которые возлагаются на сетевые экраны Linux, С другой стороны, Linux тоже очень часто используют в качестве маршрутизатора в целях удешевления системы за счет применения старого железа.

 

4.10.1. Фильтрация пакетов

Итак, основной, но не единственной задачей сетевого экрана является фильтрация пакетов. В Linux уже встроен Firewall, и вам его не надо устанавливать отдельно. Точнее сказать, их даже два: iptables и ipchains. Они позволяют контролировать трафик, который проходит сквозь компьютер по протоколам TCP (Transmission Control Protocol, протокол управления передачей), UDP (User Data Protocol, пользовательский протокол данных) и ICMP (Internet Control Message Protocol, протокол управляющих сообщений в сети Интернет). Так как TCP является транспортом для всех основных протоколов Интернета: FTP (File Transfer Protocol, протокол передачи файлов), HTTP (Hypertext Transfer Protocol, протокол передачи гипертекстовых файлов), POP3 (Post Office Protocol, почтовый протокол) и др., то фильтрация TCP позволяет защищать все эти сервисы.

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

□ без предупреждений (deny, запрет);

□ с посылкой на компьютер отправителя сообщения об ошибке (reject, отклонение).

Я бы не выбирал последний вариант, потому что незачем направлять хакеру лишние пакеты. Лучше оставить действие без внимания, и злоумышленник будет думать, что сервис просто недоступен. Но в этом случае легальные пользователи могут ощутить неудобства при наличии просчета в конфигурировании сетевого экрана. Допустим, что вы по ошибке заблокировали доступ к 80 порту. Если пользователь обратится к Web-серверу, то программа, не получив ответа о запрете, будет находиться в состоянии ожидания до истечения Timeout. Для некоторых программ это значение может быть бесконечным, и они зависнут. Исправив ошибку в сетевом экране, вы дадите возможность пользователям работать корректно.

К тому же, отправка сообщений с ошибками идет по протоколу ICMP и увеличивает трафик. Хакер может использовать эти особенности для реализации атаки "Отказ от обслуживания" и переполнить ваш канал ненужными ответами. Атака DoS может быть направлена не только на трафик. Хакеру достаточно в цикле запускать запросы на установку соединения с запрещенным портом, а ваш компьютер будет тратить ресурсы на проверку пакетов и отправку ICMP-ответов. Если пакеты будут идти слишком часто, то сервер может не справиться с нагрузкой и перестанет отвечать на запросы авторизованных пользователей.

При настройке правил можно использовать два варианта фильтра:

1. Разрешено все, что не запрещено.

2. Запрещено все, что не разрешено.

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

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

 

4.10.2. Параметры фильтрации

Основными параметрами пакета, по которым производится фильтрация, являются номер порта источника или приемника, адрес отправителя или назначения и протокол. Как мы уже знаем, сетевым экраном поддерживаются три базовых протокола (TCP, UDP и ICMP), на основе которых строятся все сервисы — FTP, HTTP, POP3.

Обращаю ваше внимание, что фильтровать можно пакеты, идущие в обе стороны. Проверка пакетов, приходящих извне, позволяет на самом раннем этапе отсеять любые попытки взломать систему или вывести ее из строя.

А зачем фильтровать то, что уходит из сети? На первый взгляд бессмысленно, но резон есть и достаточно большой. У исходящего трафика могут быть враги, я их перечислю:

□ троянские программы, которые могут отправлять в сеть конфиденциальную информацию или соединяться с хакером или с его сервером, чтобы брать команды с какого-нибудь файла;

□ специализированные программы для обхода правил. Допустим, что вы запретили доступ к определенному порту извне. Хакер может поместить на сервере программу, которая будет перенаправлять трафик с разрешенного порта на запрещенный, наподобие туннелирования OpenSSL (Open Secure Sockets Layer, открытый протокол защищенных сокетов). Профессионалу написать такую утилиту — дело пяти минут.

Возможных лазеек для проникновения очень много, и ваша задача закрыть максимальное их количество. Для этого под контролем должен быть трафик в обоих направлениях.

Протоколы

TCP используется как базовый для передачи данных таких протоколов, как HTTP, FTP и др. Запрещать его не имеет смысла, потому что это основа, без которой вы лишитесь всех удобств, предоставляемых нам всемирной сетью. Для передачи данных сначала TCP устанавливает соединение с удаленным хостом, и только потом происходит обмен информацией. Благодаря этому подделка IP-адреса любого участника соединения усложняется, а иногда становится и невозможной.

Протокол UDP находится на одном уровне с TCP, но передает данные без установки соединения. Это значит, что пакет просто посылается в сеть на определенный адрес, и нет гарантии, что он дошел до адресата. Здесь нет никакой защиты от подделки IP-адреса, поэтому в качестве отправителя злоумышленник может указать что угодно, и наш сервер не увидит подвоха. Если нет особой надобности, то я запрещаю прохождение таких пакетов в обе стороны.

Протокол ICMP используется для обмена управляющими сообщениями. Через него команда ping проверяет соединение с компьютером, а оборудование или программы сообщают друг другу об ошибках. Если этот протокол использовать только по назначению, то он очень удобен. Но в нашей жизни все далеко от идеала, и ICMP уже не раз становился объектом для DoS-атак. Найдите любые способы, чтобы запретить этот протокол. Если обмен управляющими сообщениями необходим в вашей работе, попробуйте найти другую программу, но избавьтесь от использования ICMP.

Фильтрация портов

Первое, на что надо обратить внимание, — это, конечно же, порты. Допустим, что у вас есть Web-сервер, к которому имеют доступ все пользователи. Предположим, что на нем работают абсолютно безопасные сценарии (это фантастика, но допустим ☺), или статичные документы HTML. Помимо этого, все программы содержат самые последние обновления и не имеют уязвимостей. Получается, что сервер безопасен? Да, но до поры до времени. Для обновления содержимого необходим какой-то доступ для закачки файлов, ведь бегать с дискетами к Web-серверу никто не будет. Чаще всего для работы с файлами открывают FTP-сервис, а вот это уже дыра.

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

Таким образом, можно установить на сервер такую политику, при которой на 80 порт будут приниматься все подключения, а FTP-сервис (21 порт) будет запрещен для всех, кроме определенного IP-адреса. После этого злоумышленник может хоть годами подбирать пароль, любой его трафик будет обрезаться, если он не знает IP-адреса и не сможет его подделать.

Вы должны запретить все порты и после этого открыть только то, что необходимо. На сервере, который охраняет целую сеть, это сделать сложно, потому что разные компьютеры требуют различные сервисы. Открыть их все — значит разрешить работать со всеми портами на любой машине. Конечно же, можно помимо портов использовать в правилах IP-адреса, но дополнительным вариантом защиты будет использование сетевого экрана на каждом компьютере внутри сети. В этом случае каждый из них будет охраняться в зависимости от выполняемых задач. Если это Web-сервер, то из Интернета будет виден только 80 порт, для FTP — 21-й порт.

Фильтрация адресов

Исходя из предыдущих соображений видно, что для фильтрации можно использовать и IP-адрес, хотя максимальный эффект достигается именно в сочетании параметров (порт и адрес).

Допустим, что в вашей сети находятся два Web-сервера. Такое бывает очень часто. Один сервер делают доступным для всех посетителей из Интернета, а второй — только для своих пользователей (внутрикорпоративный сайт). Вполне логичным будет разделение информации, тогда на закрытый сервер можно пускать трафик только локальной сети вне зависимости от порта. Хакеры из Интернета вообще не должны иметь доступ к внутрикорпоративному серверу.

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

Фильтрация нежелательных адресов

Несколько лет назад сервис www.regnow.com (выступает посредником для производителей Shareware-программ, получая деньги от клиентов и обеспечивая безопасность платежей) попытался ограничить доступ с сомнительных IP-адресов. Это вполне логично. Некоторые страны кишат хакерами, и при этом число добропорядочных пользователей программ в них стремится к нулю. К таким государствам отнесли Африку и некоторые регионы восточной Европы, включая развивающуюся, но любящую халяву Россию.

Этот шаг оправдан тем, что в некоторых из этих стран очень сильно была развита технология кардинга. когда по ворованным кредитным картам заказывался в Интернете товар. Чтобы кардинг стал недосягаем, сервис запретил доступ по целым группам IP-адресов. Впоследствии выяснилось, что обойти эту систему очень просто. Достаточно воспользоваться анонимным прокси-сервером в США или Канаде, чтобы хакер мог проскочить преграду. А вот у добропорядочных пользователей возникли серьезные проблемы, и они лишились возможности использовать сервис для оплаты необходимых услуг.

Из-за серьезных недостатков данный фильтр был изъят, и разработчики regnow.com больше не пытаются его использовать. Просеивать все возможные прокси-серверы слишком затруднительно, и это дает малый эффект, а репутацию можно потерять навсегда. Так что, иногда приходится выбирать между безопасностью и удобством использования.

Фильтрация неверных адресов

Был случай, когда один сервис неправильно обрабатывал адрес получателя. Если серверу приходил неверный пакет, то он отвечал отправителю сообщением о некорректности данных. Проблема заключалась в том, что злоумышленник мог послать на сервер такой пакет, в котором в качестве отправителя стоял адрес получателя, т.е. и в том и в другом случае использовался IP- адрес сервера. Конечно же, сервис пытался отослать сообщение об ошибке, и отправлял его сам себе, и снова видел ошибочный пакет. Таким образом информация зацикливалась. Если злоумышленник направит тысячи таких пакетов, то сервер только и будет посылать сообщения об ошибках.

О подобных погрешностях я уже давно ничего не слышал, но нет гарантии, что они не появятся снова. Существует множество адресов, которые надо фильтровать и не пропускать в сеть.

Помимо этого, я советую не пропускать пакеты с адресами, которые зарезервированы или не могут использоваться в Интернете. Рассмотрим диапазоны этих адресов:

□ в качестве отправителя стоит адрес 127.0.0.1. Из Интернета пакет с таким адресом прийти не может, потому что он всегда используется для указания на локальную машину (localhost);

□ от 10.0.0.0 до 10.255.255.255 — используется для частных сетей;

□ от 172.16.0.0 до 172.31.255.255 — выделен для частных сетей;

□ от 192.168.0.0 до 192.168.255.255 — зарезервирован для частных сетей;

□ от 224.0.0.0 до 239.255.255.255 — используется для широковещательных адресов, которые не назначаются компьютерам, поэтому с них не могут приходить пакеты;

□ от 240.0.0.0 до 247.255.255.255 — зарезервирован для будущего использования в Интернете.

Все эти адреса нереальны для Интернета, и никакие пакеты с такими параметрами не должны проходить через сетевой экран.

Фильтрация в Linux

Для фильтрации пакетов по определенным вами правилам в ядро Linux уже встроены все необходимые функции. Но это только основа, а нужен еще инструмент, который в удобной форме позволит управлять этими правилами.

В ОС Linux включены сразу две программы: iptables и ipchains (вызываются одноименными командами). Какая из них лучше, — сказать сложно, потому что они схожи по своим возможностям. Но многие профессионалы останавливаются на ipchains. Выбор остается за вами. Одни любят старые и проверенные методы, а другие предпочитают все новое.

В ядре Linux находятся три основные цепочки (chain) правил:

□ Input — для входящих пакетов;

□ Output — для исходящих пакетов;

□ Forward — для пакетов, предназначенных другой системе.

Вы можете создавать свои цепочки, которые будут привязаны к определенной политике, но мы эту тему рассматривать не будем.

ОС Linux проверяет все правила из цепочки, которая выбирается в зависимости от направления передачи. Пакет последовательно обследуется на соответствие каждому правилу из цепочки. Если найдено хотя бы одно совпадение с описанием, то выполняются действия, указанные в данном правиле: DENY, REJECT или ACCEPT, т.е. система решает, пропускать пакет дальше или нет.

Цепочки несут в себе одну очень неприятную для новичков особенность. Допустим, что на вашем сервере вы хотите открыть 21 порт только для себя. Для этого можно создать два правила:

□ Запретить все входящие пакеты на 21 порт сервера.

□ Разрешить пакеты на 21 порт с компьютера с адресом 192.168.1.1.

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

Чтобы наша политика действовала верно, строки надо поменять местами. В этом случае сначала проверится запись "Разрешить пакеты на 21 порт с компьютера с адресом 192.168.1.1", контроль пройдет успешно и пакет будет пропущен. Для остальных IP-адресов это правило не выполнится, и проверка продолжится. И вот тогда сработает запрет доступа на 21 порт для всех пакетов.

Пакеты, направленные на другие порты, не соответствуют правилам, значит, над ними будут выполняться действия по умолчанию.

 

4.10.3. Firewall — не панацея

Установив Firewall, вы не получаете максимальной защиты, потому что существует множество вариантов обхода не только конкретных реализаций, а любого сетевого экрана.

Firewall — это всего лишь замок на двери парадного входа. Злоумышленник никогда не воспользуется парадным входом, он будет проникать в систему через черный или полезет в окно. Например, на рис. 4.2 показана защищенная сеть, а ее главная дверь — это выход в Интернет через сетевой кабель. А если на каком-нибудь клиентском компьютере стоит модем, то это уже черный ход, который не будет контролироваться сетевым экраном.

Я видел серверы, в которых доступ в сеть разрешен только с IP-адресов, определенных списком. Администраторы верят, что такое правило позволит защититься от хакеров. Это не так, потому что IP-адрес легко подделать.

Однажды я работал на фирме, где выход в Интернет контролировался по IP- адресу. У меня было ограничение на получение 100 Мбайт информации в месяц, а на соседнем компьютере — полный доступ. Чтобы не тратить свой трафик на получение больших файлов со своего IP-адреса, я только смотрел Web-страницы. Когда нужно было что-либо скачать, я выполнял следующие действия:

□ дожидался, когда освободится нужный компьютер, например, когда хозяин уходил на обед;

□ вытаскивал сетевой кабель на компьютере соседа, чтобы разорвать соединение;

□ спокойно менял свой IP-адрес на соседский, и по безграничному трафику быстро качал все, что требовалось:

□ после скачивания возвращал IP-адрес и кабель на место.

Таким способом я в течение месяца получал необходимую мне информацию.

Дальше стало еще проще. Я установил прокси-сервер на соседний компьютер и использовал его. После этого мы всем отделом заходили в Интернет через один IP-адрес, имеющий неограниченный трафик.

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

Сетевые экраны могут работать на компьютере с ОС (программные) или на каком-нибудь физическом устройстве (аппаратные). В любом случае это программа, а ее пишут люди, которым свойственно ошибаться. Как и ОС, так и программу сетевого экрана нужно регулярно обновлять и исправлять погрешности, которые есть всегда и везде.

Рассмотрим защиту по портам. Допустим, что у вас есть Web-сервер, который охраняется сетевым экраном с разрешенным только 80 портом. А ему больше и не надо!!! Но это не значит, что нельзя будет использовать другие протоколы. Можно создать туннель, через который данные одного протокола передаются внутри другого. Так появилась знаменитая атака Loki, которая санкционирует передачу команды на выполнение на сервер через ICMP-сообщения Echo Request (эхо-запрос) и Echo Reply (эхо-ответ), подобно команде ping.

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

Для того чтобы пройти через сетевой экран, зачастую требуется пароль или предъявление какого-нибудь устройства типа Touch Memory, Smart Card и др. Если пароль не защищен, то все затраченные на сетевой экран деньги окажутся потерянными зря. Хакер может подсмотреть пароль или подслушать его с помощью анализатора пакетов (сниффер) и предъявить подделанные параметры идентификации сетевому экрану. Таким образом было взломано немало систем.

Управление паролями должно быть четко определено. Вы должны контролировать каждую учетную запись. Например, если уволился сотрудник, у которого были большие привилегии, то все сведения, определяющие его в ОС, необходимо тут же заблокировать и изменить все известные ему пароли.

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

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

 

4.10.4. Firewall как панацея

Может сложиться впечатление, что Firewall — это пустое развлечение и трата денег. Это не так. Если он хорошо настроен, постоянно контролируется, а в системе используются защищенные пароли, то сетевой экран может предотвратить большинство проблем.

Хороший экран имеет множество уровней проверки прав доступа, и нельзя использовать только один из них. Если вы ограничиваете доступ к Интернету исключительно по IP-адресу, то приготовьтесь оплачивать большой график. Но если при проверке прав доступа используется IP-адрес в сочетании с MAC-адресом и паролем, то такую систему взломать уже намного сложнее. Да, и MAC и IP-адрес легко подделать, но можно для полной надежности подключить к системе защиты и порты на коммутаторе. В этом случае, даже если хакер будет знать пароль, то для его использования нужно сидеть именно за тем компьютером, за которым он закреплен. А это уже не просто.

Защита может и должна быть многоуровневой. Если у вас есть данные, которые нужно оградить от посторонних, то используйте максимальное количество уровней. Помните, что лишней защиты не бывает.

Представьте себе банк. У входа обязательно стоит секьюрити, который спасет от воров и мелких грабителей. Но если подъехать к такой организации на танке, то такие блюстители порядка не помогут.

Сетевой экран — это как охрана на дверях, защищает от мелких хакеров, которых подавляющее большинство. Но если банком займется профессионал, то он может добиться успеха.

Помимо охраны у входа, деньги в банке всегда хранятся в сейфе. Финансовые сбережения для банка — это как секретная информация для сервера, и они должны быть максимально защищены. Именно поэтому устанавливают сейфы со сложными механизмами защиты, и если не знать, как их обойти, вор потратит на вскрытие замка драгоценное время, и успеет приехать милиция.

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

 

4.10.5. Конфигурирование Firewall

Самый простой способ настроить сетевой экран — использовать графическую утилиту. Для этого загрузитесь в графическую оболочку и выберите из главного меню KDE строку System\Firewall Configuration. Перед вами откроется окно из двух вкладок: Rules и Options.

Первым делом советую перейти на вкладку Options. Она показана на рис. 4.3. Здесь можно указать действия по умолчанию для каждого типа пакетов (Input, Forward и Output) и ограничить прохождение пакетов ICMP.

Рис. 4.3. Вкладка Options программы конфигурирования Firewall

После этого переходим на вкладку Rules (рис. 4.4), где можно добавлять, изменять или удалять правила фильтрации. Попробуйте нажать на кнопку New, чтобы создать новое правило. Перед вами откроется окно, как на рис. 4.5.

Рис. 4.4. Вкладка Rules программы конфигурирования Firewall

Рис. 4.5. Окно добавления нового правила

Пока что не надо ничего изменять. Если вы загрузили сейчас утилиту Firewall Configuration, то советую только посмотреть на ее внешний вид и предоставляемые возможности. Настройками можно будет заняться тогда, когда вы познакомитесь с программой ipchains, которая из командной строки позволяет изменять параметры сетевого экрана. Для этого мы рассмотрим множество интересных и полезных на практике примеров, которые помогут вам разобраться и с конфигурированием Firewall.

 

4.11. ipchains

 

Наиболее распространенной программой для создания правил сетевого экрана является ipchains. В команде вызова можно указывать следующие параметры:

□ -A цепочка правило — добавить правило в конец цепочки. В качестве аргумента указывается имя цепочки input, output или forward;

□ -D цепочка номер — удалить правило с указанным номером из заданной цепочки;

□ -R цепочка номер правило — заменить правило с указанным номером в заданной цепочке;

□ -I цепочка номер правило — вставить правило в указанную первым аргументом цепочку под номером, заданным во втором параметре. Если номер равен 1, то правило станет первым в цепочке;

□ -L цепочка — просмотреть содержимое указанной цепочки;

□ -F цепочка — удалить все правила из указанной цепочки;

□ -N имя — создать новую цепочку с заданным именем;

□ -X имя — удалить цепочку с указанным именем;

□ -P цепочка правило — позволяет изменить политику по умолчанию;

□ -р протокол — определяет протокол, к которому относится правило. Значений аргумента протокол может быть четыре: tcp, udp, icmp или all (указывается, если правило действует для всех протоколов);

□ -i интерфейс — сетевой интерфейс, к которому будет привязано правило. Если этот аргумент не указан, то правило будет относиться ко всем интерфейсам;

□ -j действие — операция, которая должна быть выполнена над пакетом. В качестве аргумента можно указать ACCEPT, REJECT или DENY;

□ -s адрес порт — характеристики отправителя пакета. Первый аргумент задает IP-адрес источника, а второй (не обязательный) — порт. Будьте внимательны, у протокола ICMP нет портов;

□ -d адрес порт — атрибуты получателя пакета. Первый аргумент задает IP-адрес назначения, а второй (не обязательный) — порт.

 

4.11.1. Фильтр по умолчанию

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

ipchains -L

В результате вы должны увидеть на экране примерно следующее:

Chain input (policy ACCEPT):

Chain forward (policy ACCEPT):

Chain output (policy ACCEPT):

Chain icmp (0 references) :

В зависимости от дистрибутива настройки по умолчанию могут отсутствовать, тогда вместо правил вы увидите следующее сообщение об ошибке:

ipchains: Incompatible with this kernel (невозможно для этого ядра).

Такая фраза может появиться, если ipchains отсутствует или запущена неверно. Я уже не раз встречал это сообщение, потому что производители дистрибутивов неверно конфигурируют систему по умолчанию. А ведь лечится эта ошибка достаточно просто, и ядро тут ни при чем.

Просмотрите файл /etc/rc.d/init.d/ipchains с помощью текстового редактора программы МС или команды cat. Первое будет удобнее. Нужно найти в файле следующую строку:

IPCHAINS_CONFIG=/etс/sysconfig/ipchains

Путь к файлу в директиве IPCHAINS_CONFIG может быть другим. В современных дистрибутивах в директории /etc/sysconfig/ хранятся файлы конфигурации служб. Для сервиса ipchains это файл ipchains. Проверьте его существование следующей командой:

ls /etc/sysconfig/ipchains

Если файл не существует, то его следует создать. Для этого выполним следующую команду:

cat >> /etc/sysconfig/ipchains

Отныне все команды, вводимые в консоль, будут сохраняться в файле. Для того чтобы сервис ipchains заставить работать, достаточно ввести:

:input ACCEPT

Теперь нажмите клавиши + и перезапустите сервис ipchains следующей командой:

/etc/rc.d/init.d/ipchains restart

Обратите внимание, что нужно указать полный путь. Если этого не сделать, то будет запущена утилита ipchains, а не сценарий запуска из директории /etc/rc.d/init.d/.

Вот теперь команда должна выполниться успешно.

Для начала давайте запретим любой трафик. Но прежде, чем мы перейдем к созданию правил, сделаю еще одно замечание. Любую систему нужно начинать конфигурировать с чистого листа, потому что настройки по умолчанию могут оказаться не слишком эффективными и небезопасными. Выполните команду ipchains -F, чтобы обнулить текущие настройки. Сетевой экран — это сердце защиты, поэтому в данном случае очистка является наиболее важной.

Теперь зададим политику по умолчанию. Для этого нужно выполнить команду ipchains с параметром -P для каждой цепочки и указать политику безопасности:

ipchains -Р input DENY

ipchains -Р output REJECT

ipchains -P forward DENY

Обратите внимание, что для входящих (input) и проходящих (forward) пакетов я установил полный запрет, поэтому они будут удаляться без каких-либо предупреждений. Для исходящей информации можно поставить в правило REJECT, чтобы внутренние клиенты при попытке подключения к серверу могли получить сообщение об ошибке.

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

 

4.11.2. Примеры добавления ipchains-правил

Давайте теперь указывать права, чтобы разрешить какой-либо доступ к серверу. Только вы должны учитывать, что если добавлять правило в конец набора, то нет гарантии, что оно будет работать верно. В цепочке уже может быть запрет, поэтому доступ будет закрыт раньше, чем сработает наше правило. Чтобы не столкнуться с такой проблемой, я в примерах буду вставлять новое правило первым (указывать ключ -I и номер 1).

Если вы добавляете общее правило запрета, то его следует поместить в самый конец. Когда правило касается конкретного действия, порта или адреса, то его место в начале цепочки. Таким образом, в вашем своде сначала будут идти специфические правила, а потом глобальные.

Допустим, что у нас используется публичный Web-сервер, и нужно разрешить всем пользователям работать с 80 портом (именно его используют Web-серверы по умолчанию). Для решения этой проблемы выполняем команды:

ipchains -I input 1 -р tcp -d 192.168.77.1 80 -j ACCEPT

ipchains -I output 1 -p tcp -s 192.168.77.1 80 -j ACCEPT

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

ipchains -I input 1 -р tcp -d 192.168.77.1 web -j ACCEPT

ipchains -I output 1 -p tcp -s 192.168.77.1 web -j ACCEPT

Здесь вместо 80 порта указано его имя web, и программа ipchains корректно отработает с этим аргументом.

Рассмотрим каждый ключ первой строки в отдельности:

□ -I input 1 — ключ -I указывает на необходимость вставки правила под заданным номером. Потом показываем цепочку, в которую надо вставить правило, в данном случае это input. Цифра 1 обозначает номер, под которым вставляется правило, т.е. оно будет первым;

□ -р tcp — Web-сервер работает по протоколу HTTP, который использует в качестве транспорта TCP. С помощью ключа -р мы в явном виде указываем протокол. Не забывайте делать это. В противном случае вы откроете одновременно доступ к сервисам на двух портах (TCP и UDP). Хорошо, если на 80 порту UDP в этот момент не будет работать какая-нибудь программа;

□ -d 192.168.77.1 80 — правило проверяет, чтобы получателем был порт 80 (или его имя web) на сервере с адресом 192.168.77.1. В данном случае этот IP принадлежит моему серверу. Это значит, что я разрешил входящие пакеты на 80 порт своего компьютера. Адрес отправителя в правиле не указан, а значит, может быть любым;

□ -j ACCEPT — опция устанавливает разрешение. Если пакет соответствует правилам, заданным предыдущими ключами (в данном случае проверяется адрес и порт назначения и протокол), то он будет пропущен.

В соответствии с первой строкой посылать на сервер запросы разрешается всем. Но Web-сервер должен иметь возможность возвращать страницы на запросы клиентов. Для этого нужно открыть 80 порт моего сервера (192.168.77.1) для всех исходящих пакетов. Именно это делает вторая строка.

Выполните команду ipchains -L, и в результате вы должны увидеть следующее содержимое всех ваших цепочек:

Chain input (policy DENY):

target prot  opt  source   destination ports

ACCEPT tcp ------ anywhere flenovm.ru  any -> http

Chain forward (policy DENY):

Chain output (policy DENY):

target prot  opt  source     destination ports

ACCEPT tcp ------ flenovm.ru anywhere    http -> any

Chain icmp (0 references):

В цепочках input и output появилось по одной строке. Обратите внимание, что в колонках source и destination обеих цепочек IP-адрес заменился на доменное имя моего компьютера flenovm.ru. Если сервер может определить имя, то он делает такую подмену. Посмотрите на колонку ports, здесь номер порта 80 заменен на http.

Я советую вам внимательно проанализировать созданный нами список фильтров, чтобы вы четко понимали каждую его колонку. Рассмотрим структуру строк на примере цепочки input:

target prot opt source destination ports

ACCEPT tcp ------ anywhere flenottro.ru any -> http

Первая строка — имена столбцов, а вторая — это фильтр, содержащий реальные значения. Здесь у нас 6 колонок:

□ target — действие, которое будет выполняться, если пакет удовлетворяет фильтру. В нашем случае стоит ACCEPT, т.е. пропустить дальше, в противном случае пакет уничтожается;

□ prot — протокол, в данном случае tcp;

□ opt — дополнительные опции. Мы их не указывали, поэтому здесь стоят прочерки;

□ source — источник пакета. Слово "anywhere" указывает на то, что посылка может быть от любого компьютера;

□ destination — адресат. Здесь может быть имя компьютера или его IP-адрес;

□ ports — порт, указывается в виде источник -> назначение. В данном случае у источника может быть любой порт (используется слово any), а пункт назначения должен работать только через http (80 порт).

Как это часто бывает, Web-сервер должен кто-то обновлять, и обычно это делается через FTP-сервис. Всем доступ открывать нельзя, поэтому пропишем правило, по которому подключаться к FTP-серверу (21 порт) сможет только один компьютер с адресом 192.168.77.10. Для этого выполняем следующие команды:

ipchains -I input 1 -р tcp -d 192.168.77.1 21 \

 -s 192.168.77.10 -j ACCEPT

ipchains -I output 1 -p tcp -s 192.168.77.1 21 \

 -d 192.168.77.10 -j ACCEPT

В данном примере пропускаются пакеты, входящие на 21 порт сервера с адресом 192.168.77.1 с любого порта компьютера 192.168.77.10. Вторая строка разрешает исходящие пакеты с 21 порта сервера 192.168.77.1 на компьютер клиента с адресом 192.168.77.10.

Если у вас настроен FTP-сервер и вы сейчас к нему подключитесь, то не увидите файлов и не сможете работать. В отличие от Web-сервера протокол FTP требует для работы два порта: 21 (ftp-порт для передачи команд) и 20 (ftp-data порт для обмена данными). Поэтому нужно открыть доступ и к 20 порту:

ipchains -I input 1 -р tcp -d 192.168.77.1 20 \

 -s 192.168.77.10 -j ACCEPT

ipchains -I output 1 -p tcp -s 192.168.77.1 20 \

 -d 192.168.77.10 -j ACCEPT

Теперь компьютер с адресом 192.168.77.10 имеет полноценный доступ к FTP-сервису, а для всех остальных он недоступен. Сканирование сервера с любого компьютера вашей сети покажет открытым только 80 порт, и лишь с компьютера с IP 192.168.77.10 можно будет увидеть 21 и 80 порты.

Выполните команду ipchains -L, чтобы просмотреть текущее состояние ваших цепочек. Вы должны увидеть примерно следующий результат:

Chain input (policy DENY):

target prot opt   source        Destination ports

ACCEPT tcp ------ 192.168.77.10 flenovm.ru  any -> ftp-data

ACCEPT tcp ------ 192.168.77.10 flenovm.ru  any -> ftp

ACCEPT tcp ------ anywhere      flenovm.ru  any -> http

Chain forward (policy DENY):

Chain output (policy DENY):

target prot  opt  source     destination   ports

ACCEPT tcp ------ flenovm.ru 192.168.77.10 ftp-data -> any

ACCEPT tcp ------ flenovm.ru 192.168.77.10 ftp -> any

ACCEPT tcp ------ flenovm.ru anywhere      http -> any

Chain icmp (0 references):

Через фильтры, описанные в этом разделе, пропускаются любые пакеты, вне зависимости от интерфейса. В большинстве случаев это оправдано, но петля (loopback, всегда указывает на вашу машину), чаще всего, не нуждается в защите. Ее можно использовать только локально, и ни один хакер не сможет подключиться через этот виртуальный интерфейс удаленно. Вполне логичным будет разрешить все пакеты через loopback:

ipchains -A input -i lo -j ACCEPT

ipchains -A output -i lo -j ACCEPT

Большинство администраторов не любят открывать полный доступ через loopback, потому что политики внешнего и виртуального интерфейсов будут различаться. В этом случае тестирование сетевых программ усложняется. Проверив программу через lo, нет гарантии, что она будет функционировать с удаленными подключениями, ведь там могут помешать нормальной работе фильтры сетевого экрана.

 

4.11.3. Примеры удаления ipchains-правил

Попробуем отменить доступ к FTP на примере удаления записей из цепочки input. Я специально выбрал в качестве образца FTP-сервис, потому что он требует две строки описания, и при совершении операции нужно быть очень внимательным. На вскидку нужно выполнить следующие команды:

ipchains -D input 1

ipchains -D input 2

Пока не спешите это делать. Ключ -D свидетельствует о необходимости удаления правила. После него указана цепочка, с которой надо произвести операцию, и номер записи. Обратите внимание на последовательность удаления в данном примере (сначала 1, а потом 2 запись). Ничего не заметили?

Если выполнить первую строку и потом просмотреть содержимое цепочки input, то в результате мы получим:

Chain input (policy DENY):

target prot  opt  source        Destination ports

ACCEPT tcp ------ 192.168.77.10 flenovm.ru  any -> ftp

ACCEPT tcp ------ anywhere      flenovm.ru  any -> http

Строка для порта ftp-data отсутствует, но остальные записи сместились, и при выполнении команды ipchains -D input 2 мы удалим разрешение для http-сервера, а доступ к ftp-порту останется. Это можно пережить, когда записей только три, а что если их будет сотня? Вспомнить, какая строка была удалена, очень сложно.

Чтобы не столкнуться с такой ситуацией, удаление начинайте с последней строки. В данном случае команды надо расположить таким образом:

ipchains -D input 2

ipchains -D input 1

Есть еще один способ удаления, который понадежнее, но для его рассмотрения давайте создадим отдельную запись в цепочке forward. Выполните следующую команду:

ipchains -A forward -р icmp -j DENY

В этой строке мы используем ключ -A, который добавляет строку в конец цепочки (в нашем случае была пустая).

Внимание!

Если в вашей системе запрещена переадресация (forward), то запись будет добавлена, но на экране может появиться предупреждение. Чуть позже в разд. 4.11.7 мы поговорим о перенаправлении более подробно.

Рассмотрим, что делает это правило. Оно сработает, если пакет требует перенаправления и при этом использует ICMP-протокол. Мы установили фильтр DENY, а значит, пакет будет просто удален. Таким образом, мы заблокировали ICMP-трафик для перенаправления. Чтобы запретить ICMP-пакеты вообще, нужно добавить еще правило:

ipchains -A input -р icmp -j DENY

Теперь попробуем удалить запись. Для этого наберите команду, которую вы выполняли для добавления правила, но замените ключ -A (или -I, если вы использовали вставку) на -D. В результате должна получиться команда:

ipchains -D forward -р icmp -j DENY

Выполните ее и убедитесь, что запись удалена успешно.

 

4.11.4. Правила "все кроме"

Очень часто приходится задавать правила в виде "все кроме". Например, нужно запретить доступ к порту telnet всем пользователям, кроме компьютера с адресом 192.168.77.10. Лучше поступить следующим образом: сначала разрешить доступ для компьютера 192.168.77.10, а потом запретить всем. Тогда в цепочке input будет две записи:

□ разрешить подключение к telnet с адреса 192.168.77.10;

□ запретить подключение к telnet.

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

А ведь можно проблему решить одной строкой. Для этого нужно использовать следующее правило:

ipchains -I input 1 -р tcp -s ! 192.168.77.10 telnet -j DENY

В данной команде мы запрещаем (ключ -j DENY) подключение по протоколу TCP (-p tcp) всем пакетам, у которых адрес источника (ключ -s) не равен 192.168.77.10. Символ "!" выступает как знак неравенства, т.е. фильтру будут соответствовать все пакеты, в которых источник не равен указанному.

Такая запись эффективна, если по умолчанию все разрешено. В противном случае пакет от компьютера 192.168.77.10 будет все равно удален.

Знак "!" можно использовать и перед указанием номера порта. Например, нужно разрешить с адреса 192.168.77.12 полный доступ к серверу, .кроме порта telnet. Тогда по умолчанию делаем запрет всего и открываем доступ только компьютеру 192.168.77.12:

ipchains -I input 1 -р tcp -s 192.168.77.12 ! telnet -j ACCEPT

Данная строка разрешает подключение по протоколу TCP компьютеру с адресом 192.168.77.12 на любые порты за исключением telnet, потому что перед именем порта стоит восклицательный знак.

 

4.11.5. Ограничение сети

В крупных сетях описывать каждый компьютер очень сложно. Для облегчения этой задачи можно использовать групповые записи. Например, вам надо разрешить выход в Интернет только для сети 192.168.1.x (с маской 255.255.255.0). Это значит, что первые 24 бита (первые три октета) адреса соответствуют идентификатору сети, а последние 8 бит (последнее число) — это номер компьютера в ней. Чтобы разрешить доступ для всей сети, можно выполнить команду:

ipchains -I input 1 -р tcp -s 192.168.1.0/24 -j ACCEPT

В данном случае в качестве адреса указано значение 192.168.1.0/24. После слэша как раз идет количество бит, которые определяют адрес сети. Это значит, что все компьютеры в этой сети попадают под данный фильтр.

Существуют три основных класса сетей, которые отличаются количеством бит, отведенных под адрес. Чтобы вам было проще, приведу эту классификацию:

□ A — первые 8 бит определяют адрес сети. В такой сети используются адреса в диапазоне 01.0.0.0 до 126.0.0.0;

□ B — первые 12 бит определяют адрес сети. В такой сети используются адреса в диапазоне от 128.0.0.0 до 191.255.0.0;

□ C — первые 16 бит определяют адрес сети. В такой сети используются адреса в диапазоне от 192.0.1.0 до 223.255.255.0.

Существуют и исключения, которые мы рассматривали в разд. 4.10.2. Если вы не сталкивались раньше с TCP-протоколом, то я советую познакомиться с ним сейчас. Это поможет вам в администрировании вашей системы.

 

4.11.6. ICMP-трафик

Самым сложным для многих администраторов является управляющий протокол ICMP, который по стандарту RFC 792 требуется для работы протокола TCP/IP. Но в жизни не всегда придерживаются стандартов, и TCP/IP может работать на компьютерах, где ICMP запрещен.

Протокол TCP жестко прошивают в наши головы, и с ним сталкиваются любые пользователи, потому что TCP наиболее распространен. Протокол UDP по своим характеристикам схож с TCP, поэтому тут тоже особых проблем не возникает. А вот ICMP мало кому знаком и его даже бояться. Бытует мнение, что его проще и лучше полностью запретить, но это не так.

Протокол ICMP позволяет двум узлам в сети совместно использовать информацию об ошибках. Проходящие через него пакеты предназначены не определенной программе, а компьютеру в целом, поэтому у него нет портов. Зато есть тип и код. Эти параметры протокола можно увидеть, если выполнить команду:

ipchains -h icmp

Пакеты ICMP, чаще всего, рассылаются в ответ на нештатные ситуации. Основные типы и коды, которые доступны для управления, можно увидеть в табл. 4.1.

Таблица 4.1. Основные коды и типы ICMP-пакетов

Тип Код Описание
0 0 echo-reply — такие пакеты используются для проверки связи с компьютером через утилиту ping
3 0–7 destination-unreachable — пакеты этого типа указывают на недоступность адресата. В зависимости от кода можно получить уточненные данные: • 0 — недоступна сеть; • 1 — недоступен компьютер; • 2 — недоступен протокол; • 3 — недоступен порт; • 4 — требуется фрагментация; • 6 — неизвестная сеть; • 7 — неизвестный компьютер
8 0 echo-request — такие пакеты используются при проверке связи с компьютером через утилиту ping и запрашивают ответ от хоста
9 и 10 0 Сообщения такого типа рассылают маршрутизаторы
12 1 Неправильный IP-заголовок
12 2 Требуемые опции отсутствуют

При создании правила тип ICMP-сообщения указывается так же, как и порт для TCP-протокола, а код — помещается после ключа -d. Например, следующая строка запретит ICMP-пакеты третьего типа с кодом 1:

ipchains -I output 1 -р icmp -s 192.168.8.1 3 -d 1 -j DENY

Некоторые администраторы уделяют недостаточное внимание ICMP-протоколу. Это ошибка, потому что таким путем было совершено уже достаточно много атак, к тому же хакер может с помощью сообщений ICMP передавать даже TCP-трафик, используя туннелирование.

 

4.11.7. Перенаправление

Все правила, которые мы описывали до сих пор, относятся только к доступу к компьютеру. В случае если компьютер используется как выделенный сетевой экран, то тут настройки изменяются, и в основном вы будете работать с forward-записями.

Сетевой экран, который защищает целую сеть, состоит, как минимум, из компьютера с двумя интерфейсами. Один из них (сетевая карта или модем) направлен в Интернет, а другой — в локальную сеть. Связь с Интернетом происходит через этот компьютер, поэтому сетевой экран будет заниматься перенаправлением трафика с одного интерфейса в другой, т.е. с сетевой карты на модем и обратно. Такой компьютер называют шлюзом. Пользователи не подключаются к самому шлюзу, а только используют его как средство переадресации пакетов.

Вы можете установить какие-либо сервисы прямо на сетевой экран, но я не рекомендую этого делать. Лучше, если они будут за пределами этого компьютера. Публичные сервисы лучше ставить со стороны Интернета, а закрытые — должны быть на серверах внутри вашей локальной сети (рис. 4.6).

Рис. 4.6. Расположение серверов с публичными и закрытыми сервисами

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

Если сервер с публичным сервисом расположить внутри сети, то в сетевом экране придется прописывать разрешения на доступ к нему для всех пользователей из Интернета. Мы уже рассмотрели подобные права (см. разд. 4.11.2), но это был только пример, а в реальной жизни все доступные сервисы необходимо вынести за пределы частной сети.

Каждое лишнее разрешение в сетевом экране — это дополнительная дверь внутрь локальной сети. Предположим, что вы сами содержите Web-сервер.

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

Если вы все же решили самостоятельно обслуживать публичные серверы, то могу порекомендовать организовать сеть, как показано на рис. 4.7. Только в этом случае придется использовать дополнительный сервер для организации второго Firewall.

Рис. 4.7. Двойная защита сети

На данной схеме первый сетевой экран защищает Web-сервер. Его политика будет достаточно мягкой, потому что должна разрешить публичный доступ к некоторым портам сервера, например 80 для путешествий по Web-сайтам. Главное, чтобы фильтры открывали для всеобщего доступа исключительно адрес публичного сервера и только допустимые порты.

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

Я видел реально построенную схему, как показано на рис. 4.7, но помимо публичных серверов между двумя сетевыми экранами находились несколько компьютеров, которые создавали видимость сети. Это была бутафория из старых машин, которая должна была сбивать хакеров с толку. На этих компьютерах не было ничего ценного, зато были установлены различные средства обнаружения атак (об этом мы поговорим в гл. 12), которые сигнализировали администратору, если злоумышленник проникал в систему.

Построение сети из старых компьютеров до какой-то степени запутает хакера. На некоторых машинах можно открыть порты и накидать ненужных файлов, чтобы злоумышленник подольше искал необходимую информацию.

Есть еще один вариант — установить в компьютер три сетевые карты. Одна смотрит в Интернет, ко второй подключена приватная локальная сеть, а к третей — сеть с серверами, на которых работают открытые ресурсы (рис. 4.8). Получается защита в виде вилки. На один интерфейс мы можем перенаправлять любой трафик из Интернета, а другой интерфейс защищаем всеми возможными способами.

Рис. 4.8. Защита двух сетей одним сетевым экраном

С точки зрения безопасности схема, показанная на рис. 4.7, намного надежнее, потому что локальную сеть защищают сразу два сетевых экрана, и их легче конфигурировать. Второй вариант (рис. 4.8) проще и дешевле, т.к. не требует дополнительного компьютера для Firewall, но менее безопасен. Проникнув на компьютер с сетевым экраном, злоумышленнику потребуется меньше усилий, чтобы взломать приватную сеть.

Вернемся к самой сути перенаправления. На рис. 4.6 изображена сеть на основе витой пары с центральной точкой в виде коммутатора. Давайте проследим связи. Чтобы попасть в Интернет, любой пакет от компьютера проходит через коммутатор, входит через сетевую карту 1 (допустим, что это eth0) на машину с установленным Firewall и выходит через сетевую карту 2 (предположим, что это eth1) в Интернет.

На самом компьютере с Firewall должно быть разрешено перенаправление, которое позволит пакетам проходить из одной сетевой карты в другую. Чтобы включить эту возможность, запишите в файл /proc/sys/net/ipv4/ip_forward число 1 (по умолчанию там может быть 0) или выполните команду:

echo 1 > /proc/sys/net/ipv4/ip_forward

Для обеспечения переадресации между сетевыми интерфейсами ядро операционной системы должно быть скомпилировано с соответствующей поддержкой, потому что перенаправление происходит именно на этом уровне. Помимо этого, нужно изменить параметр net.ipv4.ip_forward в файле /etc/sysctl.conf на 1.

Более подробно о предоставлении доступа в Интернет мы поговорим в гл. 9. А сейчас затронем только темы, которые касаются настройки безопасности перенаправления трафика.

Сетевой экран может не только проверять пакеты на соответствие определенным фильтрам, но и прятать IP-адреса компьютеров сети. Это происходит следующим образом:

1. Клиент направляет пакет в сеть, и до сетевого экрана он будет идти со своим IP-адресом.

2. Сетевой экран меняет IP-адрес отправителя на свой и направляет пакет дальше от своего имени.

Таким образом, в Интернете все пакеты будут видны, как будто их отправлял Firewall, а не компьютеры внутри сети. Это позволяет скрыть от злоумышленника внутреннюю организацию сети и экономить IP-адреса. Внутри сети вы сами можете раздавать адреса из зарезервированного диапазона (мы их рассматривали в разд. 4.10.2), и только сетевой экран будет иметь реальный IP-адрес. При такой адресации из Интернета нельзя будет напрямую подключиться к компьютерам вашей сети. Это значит, что хакеру придется взламывать сначала машину с сетевым экраном и только потом компьютеры сети. Тем самым мы значительно усложняем задачу взломщика. Неопытные хакеры никогда не связываются с сетевыми экранами, потому что для такого проникновения нужны не только широкие знания принципов безопасности, но и большой опыт.

Рассмотрим пример, который разрешает переадресацию на внешний интерфейс из локальной сети:

ipchains -A forward -i eth1 -s 192.168.1.0/24 -j MASQ

Это общее правило, поэтому я добавляю его в конец цепочки forward с помощью ключа -A, чтобы оно не перекрыло фильтры, которые относятся к конкретным пользователям, но в то же время взаимосвязаны с этой записью.

Далее идет ссылка на интерфейс eth1 (сетевая карта, которая смотрит в Интернет). Диапазон адресов соответствует всей сети 192.168.1.x. В качестве разрешения (ключ -j) используется значение MASQ, что соответствует маскированию адреса, т.е. адрес клиента будет заменен на адрес компьютера, на котором работает Firewall.

Данное разрешение позволяет только передавать пакеты с адресов 192.168.1.x на сетевой интерфейс eth1. Но это еще не значит, что трафик поступит и сможет выйти в Интернет. Чтобы пакеты пользователей были приняты сетевым экраном, должно быть разрешение accept примерно следующего вида:

ipchains -A input -i eth0 -s 192.168.1.0/24 -j ACCEPT

В этом фильтре мы открыли доступ на сетевой интерфейс eth0 любым пакетам с адресов 192.168.1.x. Разрешение дано на порты, поэтому адрес отправителя пакета может быть любым из сети 192.168.1.x.

Осталось только разрешить таким же образом пакетам выходить (цепочка output) из eth1, и можно считать, что все компьютеры вашей сети уже получили доступ в Интернет. Только на всех клиентских машинах необходимо указать в качестве шлюза по умолчанию IP-адрес компьютера с сетевым интерфейсом, и все пакеты найдут своего адресата.

Если у вас структура сети напоминает рис. 4.7, то переадресация должна быть включена на обоих сетевых экранах. А вот маскировку адреса лучше всего сделать на Firewall 2. В этом случае второй сетевой экран будет скрывать локальную сеть даже от публичного сервера.

Зачастую в качестве второго сетевого устройства выступает не карта, а модем. В этом случае правило для перенаправления будет выглядеть следующим образом:

ipchains -A forward -i ppp0 -s 192.168.1.0/24 -j MASQ

Здесь перенаправление идет на интерфейс одного из модемов, имена которых имеют вид pppX.

Чаще всего необходимо, чтобы ваши клиенты имели доступ к ресурсам Интернета, а обратное подсоединение было невозможно. Когда по протоколу TCP запрашивается подключение к удаленному компьютеру, то посылается пакете установленным битом syn. В простых пакетах (ответы на наши соединения или передача данных) такого бита не должно быть. Таким образом, достаточно запретить TCP-пакеты с этим флагом, и удаленный компьютер не сможет подключиться ни к одному ресурсу нашего компьютера или сети. Это можно реализовать следующим образом:

ipchains -I input 1 -i ppp0 -р tcp --syn -j DENY

В данной строке вставляется новое правило в цепочку проверки входящих пакетов. Контролируются пакеты TCP, у которых установлен флаг syn (об этом говорит ключ --syn). Если такой пакет получен, то он удаляется.

Для использования маскировки IP-адреса ядро операционной системы должно быть скомпилировано с соответствующей поддержкой, потому что подмена адреса происходит на уровне ядра.

 

4.11.8. Сохранение фильтра

Если попробовать сейчас перезагрузить систему и просмотреть цепочки сетевого экрана, то все наши изменения исчезнут. Проблема в том, что ОС автоматически их не запоминает, и мы сами должны позаботиться о сохранении правил. Для этого существует утилита ipchain-save. Ее нужно выполнять следующим образом:

ipchain-save > файл

Когда мы только начинали рассматривать команды ipchains, то я упоминал файл /etc/sysconfig/ipchains (см. разд. 4.11.1). Это конфигурационный файл, который загружается при старте системы. Именно в этом файле я рекомендую держать все настройки:

ipchain-save > /etc/sysconfig/ipchains

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

Сохранение цепочек можно сделать автоматическим, но я не советую вам на это надеяться. Лучше сделать все вручную, так будет надежнее.

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

ipchain-restore < файл

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

 

4.12. iptables

 

Программа iptables является новой разработкой по управлению фильтрами и обеспечению безопасности, но пока еще не смогла завоевать сердца большинства пользователей. Если вы разобрались с утилитой ipchains, то понять принцип работы с iptables будет не сложнее.

С помощью iptables вы также можете редактировать цепочки правил input, output и forward.

 

4.12.1. Основные возможности iptables

Сходство между ipchains и iptables прослеживается уже при взгляде на параметры:

□ -A цепочка правило — добавить правило в конец цепочки. В качестве параметра указывается имя цепочки INPUT, OUTPUT или FORWARD;

□ -D цепочка номер — удалить правило с указанным номером из заданной цепочки;

□ -R цепочка номер правило — заменить правило с указанным номером в цепочке;

□ -I цепочка номер правило — вставить правило в указанную первым аргументом цепочку под номером, заданным во втором параметре. Если номер равен 1, то правило станет первым в цепочке;

□ -L цепочка — просмотреть содержимое указанной цепочки;

□ -F цепочка — удалить все правила из цепочки;

□ -р протокол — определяет протокол, на который воздействует правило;

□ -i интерфейс — определяет сетевой интерфейс, с которого данные были получены. Здесь можно использовать INPUT, FORWARD или PREROUTING;

□ -o интерфейс — задает интерфейс, на который направляется пакет. Здесь можно указывать OUTPUT, FORWARD или POSTROUTING;

□ -j действие — операция, которая должна быть выполнена над пакетом. В качестве аргументов можно указать следующие значения (рассмотрим только основные):

 • LOG — поместить в журнал запись о получении пакета;

 • REJECT — отправителю будет направлено сообщение об ошибке;

 • DROP — удалить пакет;

 • BLOCK — блокировать пакеты;

□ -s адрес — IP-адрес отправителя пакета. Как и в случае с iptables, после адреса можно задать маску в виде /mask и знак отрицания "!", что будет соответствовать любым адресам, кроме указанных;

□ -d адрес — адрес назначения пакета.

Как видите, большинство параметров абсолютно идентичны тем, что мы рассматривали для программы ipchains. Но есть важные и очень мощные отличия. Например, с помощью ключей -о и -i очень просто указывать, с какого на какой интерфейс направляется пакет. Из-за сходства конфигурирования сервисов ipchains и iptables в практической части мы не будем тратить драгоценное место книги, и кратко рассмотрим создание правил.

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

Настройка цепочек iptables не сильно отличается от ipchains. Начать формирование цепочки нужно с очистки всего содержимого. Двигаться необходимо от полного запрета и разрешать только то, что не нанесет вреда серверу. Сервисы, которые могут оказаться опасными, должны быть доступны только тем, кому это необходимо, или тем, кому вы доверяете. Хотя, в нашем деле полагаться ни на кого нельзя. Ваш друг может, не желая того, раскрыть секретную информацию злоумышленнику, или данные могут быть просто украдены, и тогда доверчивость сыграет с вами злую шутку.

Для сохранения изменений в iptables также надо выполнить специализированную команду:

service iptables save

 

4.12.2. Переадресация

Для разрешения переадресации с помощью iptables нужно выполнить следующую команду:

iptables -A FORWARD -o ppp0 -j MASQUERADE

В данной строке позволяется переадресация на интерфейс ppp0. С помощью параметра -j мы требуем прятать IP-адрес отправителя, т.е. включаем маскарадинг.

Если вы используете трансляцию сетевых адресов (NAT, Network Address Translation), то команда может выглядеть следующим образом:

iptables -t nat -A FORWARD -o ppp0 -j MASQUERADE

Ключ -t nat указывает на необходимость загрузить модуль iptable_nat. Если он не загружен, то это легко сделать вручную с помощью следующей команды:

modprobe iptable_nat

iptable_nat — это модуль ядра, который позволяет сетевому экрану работать с NAT.

 

4.12.3. Примеры конфигурирования iptables

Я не буду подробно останавливаться на описании различных запретов, потому что мы о них говорили при рассмотрении программы ipchains. Мы очень коротко рассмотрим создание различных правил.

Запрет любых обращений будет выглядеть следующим образом:

iptables -P INPUT DROP

Теперь все входящие пакеты будут удаляться. Как и в случае с программой ipchains, именно с этой команды нужно начинать конфигурирование iptables. Обратите внимание, что в правиле используется ключ -P, позволяющий задать значение по умолчанию для данной цепочки. Если фильтр добавить с помощью ключа -А, то вы можете запретить абсолютно любые подключения.

Некоторые специалисты по безопасности рекомендуют журналировать обращения, добавив в сетевой экран фильтр:

iptables -A INPUT -j LOG

Я бы не рекомендовал это делать. У публичных серверов за день происходит несколько сотен, а то и тысяч сканирований портов. Если обращать внимание на каждую такую попытку, вам придется устанавливать на сервер слишком большие жесткие диски для хранения журналов. А ведь если диск будет заполнен, то система выйдет из строя. Таким образом, хакер может просто направить бесконечные обращения на запрещенный порт и через некоторое время добиться удачно завершенной DoS-атаки.

Следующая команда создает фильтр, по которому запрещается принимать эхо-запросы от любых компьютеров:

iptables -A INPUT -s 0/0 -d localhost \

 -p icmp --icmp-type echo-request -j DROP

Как видите, создание фильтра с помощью iptables не сильно отличается от аналогичной процедуры в ipchains.

Следующая команда запрещает доступ к FTP-порту:

iptables -A INPUT -s 0/0 -d localhost \

 -p tcp --dport 21 -j DROP

Чтобы запретить доступ с определенного интерфейса, добавим ключ -i и укажем интерфейс eth0:

iptables -A INPUT -i eth0 -s 0/0 -d localhost \

 -p tcp --dport 21 -j DROP

Теперь запретим исходящие пакеты с 21 порта. Для этого используем команду:

iptables -A OUTPUT -i eth0 -s localhost -d 0/0 \

 -p tcp --dport 21 -j DROP

Очень мощной особенностью iptables является возможность проверки содержимого пакетов. Это очень удобно, например, для фильтрации Web-запросов.

Можно разрешить доступ к 80 порту, но контролировать, чтобы пакеты содержали только допустимые параметры. К безопасности Web-сервера мы вернемся в гл. 7 и познакомимся с разными способами защиты. А сейчас рассмотрим простой, но универсальный.

Допустим, что мы хотим разрешить доступ к FTP-серверу, но при этом быть уверенными, что пользователь не сможет обратиться к файлам /etc/passwd и /etc/shadow. Для этого можно запретить пакеты, в которых есть этот текст. Если хакер попытается послать запрос, содержащий ссылки на эти файлы, то такой пакет будет отклонен. Следующие команды запрещают доступ к этим файлам по протоколам FTP и WWW:

iptables -A INPUT -m string --string "/etc/passwd" \

 -s 0/0 -d localhost -p tcp --dport 21 -j DROP

iptables -A INPUT -m string --string "/etc/shadow" \

 -s 0/0 -d localhost -p tcp --dport 21 -j DROP

iptables -A INPUT -m string --string "/etc/passwd" \

 -s 0/0 -d localhost -p tcp --dport 80 -j DROP

iptables -A INPUT -m string --string "/etc/shadow" \

 -s 0/0 -d localhost -p tcp --dport 80 -j DROP

Надо еще учесть аспект защиты информации. Допустим, что у вас есть сервер, который принимает закодированный трафик с помощью stunnel (Security Tunnel, безопасный туннель, создающий шифрованный канал между двумя машинами, будем рассматривать в разд. 5.2), расшифровывает и передает его на другую машину. В этом случае во входящих пакетах сетевой экран не может найти такие строки. А вот исходящие пакеты идут уже декодированными и содержат открытый текст команд. В такой конфигурации необходимо контролировать оба потока.

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

 

4.13. Замечания по работе Firewall

 

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

Но даже если вы очень вдумчиво все настроили, нет гарантии, что сервер окажется в безопасности. Абсолютная неуязвимость сетевого экрана — это миф. И в данном случае проблема заключается не только в программах iptables или ipchains. Сама технология сетевого экрана не гарантирует полной безопасности. На 100% ее никто не может обеспечить, иначе я не писал бы эту книгу.

В данном разделе нам предстоит познакомиться с проблемами, с которыми вы можете встретиться во время использования сетевого экрана. Вы должны четко себе их представлять, чтобы знать, откуда может идти угроза.

 

4.13.1. Внимательное конфигурирование

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

Как вы помните, теперь у нас по три записи для цепочек input и output. А что, если вам уже не нужен больше FTP-доступ, и вы хотите его убрать. Отключив FTP-сервер, не забудьте удалить разрешающие правила из chains-цепочек.

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

Очень тяжело, если IP-адреса распределяются динамически и могут регулярно меняться. Если в вашей сети используется сервер DHCP (Dynamic Host Configuration Protocol, протокол динамической конфигурации хоста), то нужно позаботиться о том, чтобы компьютеры, которым необходим особый доступ и правила, имели жестко закрепленный адрес (например, основного шлюза). Это предотвратит случайное попадание IP-адреса в недобросовестные руки и потерю привилегий теми, кто в них нуждается.

Представьте себе, что если в нашем примере, который мы рассматривали при создании chains-цепочек (см. разд. 4.11.2), IP-адрес 192.168.8.10 случайно окажется у другого компьютера? Возникнут очень большие проблемы, потому что реальный владелец адреса потеряет доступ, а новый хозяин его получит.

Чтобы четко контролировать IP-адреса, желательно использовать DHCP-сервер и жестко фиксировать адреса тем, кто нуждается в привилегированном доступе и имеет фильтры в цепочках.

При формировании правил будьте очень внимательны. Некоторые сервисы (такие как FTP) могут требовать для своей работы более одного порта. Если вы не откроете/закроете все порты, то можете не получить необходимого результата.

При настройке сетевого экрана из графической оболочки будьте особенно осторожны. При запрете всего XWindow может зависнуть, если не найдет сетевого соединения с ядром Linux.

Я конфигурирую свой сервер через удаленное соединение по протоколу SSH. Тут тоже нужно быть аккуратным, потому что одно неверное действие может оборвать подключение и SSH-клиент теряет связь. После этого приходится идти в серверную комнату и настраивать сетевой экран прямо там.

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

Для поиска конфликтных цепочек я сохраняю конфигурацию во временный файл (любой, кроме системного /etc/sysconfig/ipchains) и распечатываю ее. На бумаге намного проще, чем на экране монитора, видеть всю картину в целом. Обращайте внимание на правильность указания параметров (адрес и порт) источника и получателя пакета. Очень часто администраторы путают, где и что прописывать.

Мысленно пройдите по каждой записи, анализируя, какие пакеты пропускаются, а какие нет. Удобней начинать обследование с цепочки input (когда пакет входит в систему). Затем проверяйте перенаправление и, наконец, выход, т.е. цепочку output. Таким образом, нужно проследить полный цикл прохождения пакета. Помните, что после первой найденной записи, соответствующей параметрам пакета, дальнейшие проверки не производятся.

При контроле записей, относящихся к TCP, помните, что этот протокол устанавливает соединение, а значит, необходимо, чтобы пакеты проходили в обе стороны. Протокол UDP не требует подключения, и пакеты можно пропускать в одну сторону — input или output. Но бывают исключения, некоторым программам нужен двусторонний обмен даже по протоколу UDP.

Если какая-либо программа не работает, то убедитесь, что существуют правила для всех необходимых портов. Некоторые протоколы требуют доступ к двум и более сетевым портам. После этого проверьте, чтобы запись с разрешением шла раньше фильтра запрещения.

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

Регулярно делайте резервную копию цепочек. Для этого можно сохранять их содержимое в отдельном файле с помощью команды ipchain-save или копировать файл /etc/sysconfig/ipchains (желательно, на другой компьютер). Тогда в случае возникновения проблем можно быстро восстановить хорошие цепочки, а тестирование сетевого экрана с новыми параметрами перенести на внерабочее время.

 

4.13.2. Обход сетевого экрана

Сетевой экран не может обеспечить абсолютной безопасности, потому что алгоритм его работы несовершенен. В нашем мире нет ничего безупречного, стопроцентно надежного, иначе жизнь была бы скучной и неинтересной.

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

На большинстве сетевых экранов очень легко реализовать атаку DoS. Когда мы рассматривали технологию этой атаки (см. разд. 1.1.6), то говорили о том, что она легко организуется в двух случаях:

1. Мощность вашего канала больше, чем у противника.

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

Сетевой экран — это сложная программная система, которой необходим значительный технический потенциал для анализа всего проходящего трафика, большая часть которого тратится на пакеты с установленным флагом syn, т.е. на запрос соединения. Параметры каждого такого пакета должны сравниваться со всеми установленными правилами.

В то же время для отправки syn-пакетов больших ресурсов и мощного канала не надо. Хакер без проблем может забросать разрешенный порт сервера sun- пакетами, в которых адрес отправителя подставляется случайным образом. Процессор атакуемой машины может не справиться с большим потоком запросов, которые надо сверять с фильтрами, и выстроится очередь, которая не позволит обрабатывать подключения добропорядочных пользователей.

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

Если клиент посылает слишком много данных, которые не могут быть помещены в один пакет, то информация разбивается на несколько блоков. Этот процесс называется фрагментацией пакетов. Большинство сетевых экранов анализируют только первые блоки в сессии, а все остальные считаются правильными. Логика такого контроля понятна, если первый пакет верен, то зачем проверять их все и тратить на это драгоценные ресурсы сервера? В противном случае от остальных не будет толка, потому что соединение не установлено и нарушена целостность информации.

Чтобы сетевой экран пропустил данные хакера, пакеты могут быть специальным образом фрагментированы. От подобной атаки можно защититься, только если Firewall осуществляет автоматическую сборку фрагментированных пакетов и просматривает их в собранном виде. В большинстве сетевых экранов такая возможность отсутствует.

Сетевой экран очень часто становится объектом атаки, и не факт, что попытка не окажется успешной. Если злоумышленнику удастся захватить Firewall, то сеть станет открытой, как на ладони. В этом случае вас смогут спасти от тотального разгрома только персональные сетевые экраны на каждом компьютере. На практике политика безопасности на персональном компьютере не такая жесткая, но может быть вполне достаточной для предотвращения дальнейшего проникновения хакера в сеть.

Атака на сетевой экран не зависит от его реализации. Ошибки бывают как в ОС Linux, так и в маршрутизирующих устройствах с возможностями фильтрации.

Основная задача, которую решает сетевой экран, — запрет доступа к заведомо закрытым ресурсам. Но существуют открытые ресурсы. Например, если необходимо, чтобы Web-сервер был доступен пользователям Интернета, то сетевой экран не сможет защитить от взлома через ошибки в сценариях на Web-сервере.

Максимальная безопасность приносит некоторые неудобства. Так, я уже говорил, что лучше всего запретить любые попытки подключения извне. Соединение может быть установлено только по инициативе клиента вашей сети, но не удаленного компьютера. В этом случае хакер останется за бортом, но и у пользователей сети могут возникнуть проблемы, например, при попытке подсоединения к FTP-серверу в активном режиме. Мы уже знаем, что этот сервис работает на двух портах: ftp и ftp-data (ftpd). Пользователь подключается к серверному порту ftp, а когда вы запрашиваете получение файла, сервер сам инициирует соединение с клиентом, а этого сетевой экран не разрешит. Для FTP-сервиса решили эту проблему, добавив возможность работы в пассивном режиме, но в других программах (например, в чатах) вопрос остается открытым.

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

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

Но на этом лень администраторов не заканчивается. Чтобы не приезжать на работу во внеурочное время в случае экстренной ситуации, им требуется доступ к консоли сервера прямо из дома. А вот это уже может стать сильной угрозой. Благо, если программа, через которую происходит управление, поддерживает шифрование (например, SSH), а если это простой telnet-клиент? Злоумышленник сможет подсмотреть параметры аутентификации с помощью утилиты сниффинга и получить такой же административный доступ к серверу.

 

4.13.3. Безопасный Интернет

Интернет не будет безопасным, пока нельзя четко установить принадлежность пакета. Любое поле IP-пакета можно подделать, и сервер никогда не сможет определить подлинность данных.

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

Что такое трассировка? В сети каждый пакет проходит по определенному пути. При необходимости перенаправления такой пакет обязательно проходит через маршрутизаторы, которые доставляют его в нужные сети. Но если в устройство, обеспечивающее межсетевую совместимость, закралась ошибка, то пакет может навечно заблудиться. Чтобы этого не произошло, в заголовке IP-пакета есть поле TTL (Time То Live, время жизни). Отправитель пакета устанавливает в это поле определенное число, а каждый маршрутизатор уменьшает счетчик ретрансляций. Если значение TTL становится равным нулю, то пакет считается потерявшимся и уничтожается, а отправителю посылается сообщение о недостижимости хоста.

Эту особенность хакеры стали использовать для диагностики сети, чтобы узнать маршрут, по которому проходит пакет. Как это работает? В 99 % случаев каждый запрос идет до адресата одним и тем же путем. На отправленный со значением TTL, равным 1, пакет первый же маршрутизатор ответит ошибкой, и по полученному отклику можно узнать его адрес. Следующая посылка идет с TTL, равным 2. В ответ на это ошибку вернет второй маршрутизатор. Таким образом можно узнать, через какие узлы проходят запросы к адресату.

Сетевой экран должен уничтожать любые пакеты с TTL, равным 1. Это защищает сеть, но явно указывает на наличие Firewall. Пакет с реальным значением TTL дойдет до адресата, а если команда traceroute выдала ошибку, то это значит, что на пути следования пакета есть Firewall, который запрещает трассировку.

Для выполнения трассировки в ОС Linux нужно выполнить команду traceroute с ключом -I, указав имя хоста. Например:

traceroute -I redhat.com

В ОС Windows есть аналогичная команда tracert, и в ней достаточно задать имя узла или IP-адрес, который нужно трассировать без использования дополнительных ключей.

Итак, на экране начнут появляться адреса промежуточных маршрутизаторов, через которые проходит пакет. Например, результат может быть следующим:

traceroute to redhat.com (xxx.xxx.xxx.xxx)? 30 hops max, 38 byte packets

1 218 ms 501 ms 219 ms RDN11-f200.101.transtelecom.net

[217.150.37.34]

2 312 ms 259 ms 259 ms sl-gw10-sto-5-2.sprintlink.net

[80.77.97.93]

...

...

17 638 ms 839 ms 479 ms 216.140.3.38

18   *      *      *    Request timed out.

Если сетевой экран допускает ICMP-пакеты, то сканирование можно провести с помощью traceroute. Возможно, появится сообщение об ошибке. В данном случае 18 строка сообщает о превышении времени ожидания ответа. Это значит, что пакет отправлен, но сервер отбросил запрос, а значит, пакет с TTL, равным 18, будет уничтожен.

Для сканирования сети за пределами Firewall достаточно выполнить команду соединения с компьютерами внутри сети с TTL, равным 19. Во время трассировки мы увидим первые 17 ответов, 18 пропадет, а 19 пройдет дальше в сеть, потому что на сетевом экране такой пакет появится с TTL=2 и не будет удален, а вот в локальной сети первый же маршрутизатор вернет ошибку.

Но в реальности ICMP-пакеты запрещены, поэтому такой метод редко приносит злоумышленнику пользу.

С другой стороны, если мы увидели полный путь к компьютеру назначения, это еще не значит, что сетевого экрана нет. Он может просто не запрещает ICMP-трафик.

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

 

4.13.4. Дополнительная защита

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

Одним из популярных методов обхода Firewall и проведения атаки является фальсификация IP-адреса отправителя. Например, у хакера может быть адрес 100.1.1.1, но с него запрещено подключаться к сервису FTP. Чтобы получить доступ, хакер может послать пакеты, в которых в качестве отправителя указан, например, 100.2.2.2.

Но это еще не все. Просто воспользовавшись чужим именем, ничего хорошего не получится. Хакер не увидит отклика сервера (рис. 4.9).

Рис. 4.9. Подмена IP-адреса

Чтобы хакер смог получить ответ на свой запрос, в IP-пакет должна быть добавлена специальная информация, по которой сервер найдет реальный адрес хакера 100.1.1.1.

Современные сетевые экраны (в том числе и поставляемые с Linux) легко определяют подделку и блокируют такие пакеты.

 

4.14. Запрет и разрешение хостов

Работа с ipchains или iptables (см. разд. 4.11 и 4.12) может показаться сложной, потому что требует знания необходимых портов, но этот способ наиболее надежный, и для построения реальной защиты рекомендуется использовать именно его. А вот для решения простых задач (например, временная защита) есть другой метод — использование файлов /etc/hosts.allow и /etc/hosts.deny. Первый файл содержит записи хостов, которым разрешен доступ в систему, а во втором прописаны запреты.

При подключении к серверу файлы проверяются следующим образом:

1. Если для компьютера нет ни одной записи в файлах, то доступ по умолчанию разрешен.

2. Если соответствие обнаружено в файле hosts.allow, то доступ разрешен и файл hosts.deny не проверяется.

3. Если в файле hosts.deny найдена запись, то доступ запрещен.

Удобство использования этих файлов заключается в том, что в них нужно указывать сервисы, требующие ограничения доступа. Это делается в виде строк следующего вида:

сервис: хост

Строка состоит из двух параметров, разделенных двоеточием. Первым указывается имя сервиса (или список, разделенный запятыми), доступ к которому нужно ограничить. Второй — это адреса (для файла /etc/hosts.allow разрешенные, а для /etc/hosts.deny — запрещенные), разделенные запятыми. В качестве параметров можно использовать ключевое слово ALL, которое соответствует любому адресу или сервису.

Рассмотрим пример конфигурирования файла. Для начала закроем любой доступ. Для этого в файле /etc/hosts.deny нужно прописать запрет для всех пользователей на любые сервисы. Для этого добавляем строку ALL: ALL. В результате ваш файл будет выглядеть следующим образом:

#

# hosts.deny This file describes the names of the hosts which are

# *not* allowed to use the local INET services, as decided

# by the '/usr/sbin/tcpd' server.

#

# The portmap line is redundant, but it is left to remind you that

# the new secure portmap uses hosts.deny and hosts.allow. In particular

# you should know that NFS uses portmap!

ALL: ALL

Теперь санкционируем только следующий доступ:

□ компьютеру с адресом 192.168.1.1 разрешено подключение ко всем сервисам;

□ с ftpd-сервисом могут работать только компьютеры с адресами 192.168.1.2 и 192.168.1.3.

#

# hosts.allow This file describes the names of the hosts

# which are allowed to use the local INET services,

# as decided by the '/usr/sbin/tcpd' server,

#

ALL:  192.168.1.1

ftpd: 192.168.1.2, 192.168.1.3

Если вам нужно целой сети позволить доступ к какому-либо сервису, то можно указать неполный адрес:

ftpd: 192.168.1.

В данной строке разрешен доступ к ftpd-сервису всем компьютерам сети 192.168.1.x (последнее число адреса не указано, значит, оно может быть любым).

Как видите, использовать файлы /etc/hosts.allow и /etc/hosts.deny намного проще, потому что не требуется прописывать правила для входящих и исходящих пакетов. Но возможности этих файлов слишком ограничены и намного меньше, чем у любого сетевого экрана.

Я рекомендую использовать файлы /etc/hosts.allow и /etc/hosts.deny для решения временных проблем безопасности. Если найдена уязвимость в каком- либо сервисе, то его легко обойти через установки в файле /etc/hosts.deny. Если вы заметили попытку атаки с какого-нибудь IP-адреса, запретите на пару часов любые подключения с него, но опять же используя файл /etc/hosts.deny.

Почему нежелательно играть с цепочками сетевого экрана? Случайное удаление или добавление ошибочной записи может нарушить работу сервера или понизить его безопасность. Именно поэтому временные правила я не рекомендую устанавливать в сетевом экране.

 

4.15. Советы по конфигурированию Firewall

Конфигурирование сетевого экрана достаточно индивидуально и зависит от конкретных задач, решаемых сервером. Но все же дам некоторые рекомендации, которым надо следовать во время настройки:

□ изначально необходимо все запретить. К хорошему быстро привыкаешь, и если открыть что-то лишнее, то потом отучить пользователей будет трудно, и процесс закрытия сервиса будет проходить с большими сложностями;

□ если есть возможность, необходимо запретить все типы ICMP-сообщений, особенно ping. Мы еще не раз будем говорить об опасности сканирования сети с помощью ICMP-пакетов;

□ запретить доступ к 111 порту. На нем работает portmapper, который необходим для удаленного вызова процедур (RPC, Remote Procedure Call) на сервере и получения результата. С помощью утилиты rpcinfo хакер может узнать, какие RPC-сервисы работают на вашем сервере. Например, выполните следующую команду:

rpcinfo -р localhost

Результатом будет примерно следующее:

Program vers proto port

Программ вер проток порт

100000 2 tcp   111 portmapper

100000 2 udp   111 portmapper

100024 1 udp 32768 status

100024 1 tcp 32768 status

391002 2 tcp 32769 sgi_fam

Как видите, одна команда может выдать достаточно много информации, поэтому 111 порт необходимо закрыть;

□ для облегчения управления доступом к портам разделите открытые ресурсы на две категории:

 • для всеобщего просмотра, в том числе и пользователями Интернета;

 • только для использования внутри сети. Например, такие сервисы, как ftp и telnet, несут в себе опасность, потому что позволяют закачивать файлы на сервер и выполнять на нем команды. Если пользователям Интернета нет необходимости в этих службах, то следует их явно запретить для внешних подключений.

 

4.16. Повышение привилегий

В заключение рассмотрения темы безопасности необходимо подробно познакомиться с командой sudo, которая позволяет выполнять программы от имени другого пользователя.

Мы уже говорили в разд. 2.7 о том, что нельзя работать в системе под учетной записью администратора. Это опасно по следующим причинам:

□ программы, запущенные вами таким образом, работают с правами администратора. При наличии уязвимости хакер сможет ею воспользоваться для получения полных прав;

□ ошибки ввода какой-либо команды могут нарушить работу всей системы. А оплошности бывают часто, потому что в ОС Linux поддерживаются достаточно мощные возможности по использованию регулярных выражений.

Если у вас в системе нет пользователя, не обладающего правами администратора, то добавьте его сейчас. Теперь войдите в систему под его учетной записью и попробуйте просмотреть файл /etc/shadow, например, с помощью следующей команды:

cat /etc/shadow

В ответ на это вы должны получить сообщение о недостатке прав доступа. Теперь выполните ту же команду через sudo:

sudo cat /etc/shadow

Вы увидите сообщение о том, что ваша учетная запись отсутствует в файле /etc/sudoers, в котором прописываются разрешения на использование команды sudo. Пример содержимого этого конфигурационного файла приведен в листинге 4.2.

Листинг 4.2. Содержимое конфигурационного файла /etc/sudoers

# sudoers file.

# Файл sudoers

# This file MUST be edited with the 'visudo' command as root.

# Этот файл должен редактироваться с помощью команды 'visudo'

# от имени root

# See the sudoers man page for the details on how to write a sudoers file.

# Смотрите страницу sudoers руководства, где имеется подробная информация по использованию sudoers-файла.

# Host alias specification

# User alias specification

# Cmnd alias specification

# Defaults specification

# User privilege specification

root ALL=(ALL) ALL

# Uncomment to allow people in group wheel to run all commands

# %wheel ALL=(ALL) ALL

# Same thing without a password

# %wheel ALL=(ALL) NOPASSWD: ALL

# Samples

# %users ALL=/sb.in/mount /cdrom,/sbin/umount /cdrom

# %users localhost=/sbin/shutdown -h now

В этом файле только одна строка без комментария:

root ALL=(ALL) ALL

Она состоит из трех параметров:

□ имя — пользователь (или группа), которому разрешено выполнять определенную команду. Я рекомендую указывать конкретных пользователей. Хакер может стать участником группы и, не обладая при этом частными привилегиями, получит доступ к выполнению опасных команд;

□ компьютер — имя машины, на которой можно выполнять команду от лица администратора;

□ команды, которые разрешено выполнять указанному пользователю (перечисляются после знака равно).

Итак, чтобы пользователь смог просмотреть файл /etc/shadow, необходимо прописать соответствующее право. В моей системе есть простой пользователь с именем robert. Для него я добавляю в файл /etc/sudoers следующую запись:

robert ALL=ALL

Теперь пользователь robert сможет выполнять с помощью sudo любые администраторские задачи. Проверьте это, повторив выполнение команды:

sudo cat /etc/shadow

На этот раз все должно пройти успешно. На экране появится приглашение ввести пароль администратора для выполнения команды.

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

Обслуживать сервер, который обрабатывает ежедневно множество подключений пользователей и на котором работают разные сервисы, в одиночку очень сложно. Чаще в этом участвуют множество людей. Один отвечает за саму систему, другой занимается поддержкой Web-сервера, третий настраивает базу данных MySQL. Давать трем администраторам полные права не имеет смысла, необходимо разрешить каждому выполнять только те команды, которые необходимы для реализации поставленных задач. Таким образом, нужно четко прописывать права для конкретного пользователя.

robert ALL=/bin/cat /etc/shadow

Обратите внимание, что я указываю полный путь к программе cat (напоминаю, его можно узнать с помощью команды which), это необходимо, иначе вместо результата, полученного по разрешенной команде, пользователь robert увидит сообщение об ошибке в конфигурации.

Допустим, вы хотите расширить права пользователя и позволить ему не только просматривать файл паролей, но и монтировать CD-ROM-диск. Для этого изменяем строку, добавляя разрешение на выполнение команды mount:

robert ALL=/bin/cat /etc/shadow, /bin/mount

Обратите внимание, что в случае с доступом к файлу /etc/shadow мы дали добро только на его просмотр, явно указав утилиту cat с параметром в виде пути к файлу с паролями. Это логично, ведь нет смысла изменять его, когда для этого существует команда passwd. Можно задать просто разрешение на выполнение команды cat:

robert ALL=/bin/cat, /bin/mount

Но в этом случае хакер сможет от имени root просматривать любые файлы в системе и даже те, которые не должны быть ему видны.

Для команды mount мы не указываем ничего, кроме самой программы. Таким образом, пользователь сам может варьировать ее параметры. Если явно указать в качестве аргумента CD-ROM, то пользователь сможет монтировать именно это устройство:

robert ALL=/bin/cat /etc/shadow, /bin/mount /dev/cdrom

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

С помощью утилиты sudo можно выполнять команды от лица различных пользователей. Для этого используется ключ -u. Например, следующая команда пытается просмотреть файл паролей от имени пользователя flenov:

sudo -u flenov cat /etc/shadow

Если пользователь не указан, то программа sudo по умолчанию запрашивает пароль root. Это не очень удобно, т.к. придется отдавать пароль администратора учетной записи robert. В этом случае теряется смысл в построении такой сложной системы безопасности, ведь зная пароль root, пользователь сможет зарегистрироваться в системе как администратор и сделать все, что угодно.

Никогда не передавайте пароль администратора. Используйте пароли других учетных записей, которым разрешена работа с необходимыми файлами и программами. В этом случае придется указывать конкретное имя пользователя, которое назначил администратор для выполнения команды.

Еще один способ сохранить пароль администратора — разрешить пользователю выполнять команды без аутентификации. Для этого необходимо между знаком равенства и списком разрешенных команд добавить ключевое слово NOPASSWD и двоеточие. Например:

robert ALL=NOPASSWD:/bin/cat /etc/shadow, /bin/mount /dev/cdrom

Теперь при выполнении команды sudo пароль вообще запрашиваться не будет. Это очень опасно, если вы не перечисляете необходимые директивы, а указываете ключевое слово ALL:

robert ALL=NOPASSWD:ALL

Если хакер получит доступ к учетной записи robert, то сможет с помощью утилиты sudo выполнять в системе любые команды. Если вы перечисляете возможные директивы, то серьезность взлома системы уменьшается в зависимости от того, насколько опасные команды вы разрешаете выполнять пользователю robert и в какой мере защищена эта учетная запись (длина и сложность пароля, прилежность владельца и т.д.).

С помощью утилиты sudo можно предоставить доступ для корректировки файлов. Никогда не делайте этого. Если текстовый редактор запустится для правки даже безобидного файла, хакер получит слишком большие возможности:

□ выполнять системные команды. Так как редактор открывается с правами root, команды также будут выполняться от имени этого пользователя, а значит, хакер получит в свое распоряжение всю систему;

□ открыть любой другой файл, пользуясь правами администратора.

Я никогда не делегирую возможность корректировки конфигурационных файлов с помощью редакторов. Если без этого не обойтись, то никогда не использую в этом случае права root. Конфигурационному файлу назначается другой владелец, и пользователь для исправлений будет запускать программу sudo только от его имени, а это значит, что редактор будет работать не с правами root.

К потенциально опасным командам, которые нежелательно предоставлять для выполнения с правами root другим пользователям, относятся:

□ редактирование файлов — позволяет злоумышленнику изменить любой конфигурационный файл, а не тот, что вы задали;

□ chmod — дает возможность хакеру понизить права доступа на конфигурационный файл и после этого редактировать его даже с правами гостя;

□ useradd — добавляет учетные записи. Если хакер создаст пользователя с ID, равным нулю, то он получит полные права в системе;

□ mount — позволяет монтировать устройства. Прописывайте в конфигурационном файле конкретные устройства и доверяйте эту команду только проверенным пользователям. Если хакер смонтирует устройство со своими программами, которые будут содержать SUID-биты или троянские программы, то он сможет получить в свое распоряжение всю систему;

□ chgrp и chown — санкционируют смену владельца файла или группы. Изменив владельца файла паролей на себя, хакер сможет легко его прочитать или даже изменить.

Напоминаю, что вы должны быть очень внимательны при работе с самой программой sudo, потому что для нее установлен SUID-бит, а значит, она будет выполняться с правами владельца, т.е. администратора системы. Версии sudo, начиная от 1.5.7 и до 1.6.5.p2, содержат ошибку выделения памяти. Хакер может воспользоваться этим для выполнения атаки переполнения стека. Проверьте вашу версию с помощью вызова команды sudo с ключом -v. Если вы являетесь администратором, то увидите на экране подробную информацию о программе, как в листинге 4.3.

Листинг 4.3. Информация о программе sudo

Sudo version 1.6.5p2 Authentication methods: 'pam'

Syslog facility if syslog is being used for logging: authpriv

Syslog priority to use when user authenticates successfully: notice

Syslog priority to use when user authenticates unsuccessfully: alert

Ignore '.' in $PATH

Send mail if the user is not in sudoers

Use a separate timestamp for each user/tty combo

Lecture user the first time they run sudo

Require users to authenticate by default

Root may run sudo

Allow some information gathering to give useful error messages

Visudo will honor the EDITOR environment variable

Set the LOGNAME and user environment variables

Length at which to wrap log file lines (0 for no wrap): 80

Authentication timestamp timeout: 5 minutes

Password prompt timeout: 5 minutes

Number of tries to enter a password: 3

Umask to use or 0777 to use user's: 022

Path to mail program: /usr/sbin/sendmail

Flags for mail program: -t

Address to send mail to: root

Subject line for mail messages: SECURITY information for %h ***

Incorrect password message: Sorry, try again.

Path to authentication timestamp dir: /var/run/sudo

Default password prompt: Password:

Default user to run commands as: root

Path to the editor for use by visudo: /bin/vi

Environment variables to check for sanity:

 LANGUAGE

 LANG

 LC_*

Environment variables to remove:

 BASH_ENV

 ENV

 TERMCAP

 ...

 ...

When to require a password for 'list' pseudocommand: any

When to require a password for 'verify' pseudocommand: all

Local IP address and netmask pairs:

 192.168.77.1 / 0xffffff00

Default table of environment variables to clear

 BASH_ENV

 ENV

 TERMCAP

 ...

 ...

Default table of environment variables to sanity check

LANGUAGE

LANG

LC_*

Я не стал полностью приводить результат выполнения команды, но основную информацию можно увидеть. Вначале нам сообщается версия программы sudo, в данном случае это 1.6.5.p2. Наиболее интересными в этом листинге являются следующие три строки:

Authentication timestamp timeout: 5 minutes

Password prompt timeout: 5 minutes

Number of tries to enter a password: 3

В первой строке задается время сохранения пароля в кэше. В данном случае это 5 минут. Если пользователь в течение этого времени снова выполнит команду sudo, то повторно аутентификация проводиться не будет.

Следующая строка указывает время ожидания ввода пароля, а последняя — количество попыток его задать. Если за этот период верный пароль не будет указан, работа программы прервется.