www.samag.ru
Журнал «БИТ. Бизнес&Информационные технологии»      
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Интеграция Open Source-решений  

Open Source в облачной среде

Облачные решения становятся всё более популярными в мире. Компании стремятся использовать их для

 Читать далее...

Автоматизация  

Нейросеть вам в руки! Как использовать ИИ для автоматизации задач

Использование ИИ для автоматизации задач помогает компании получить конкурентное преимущество, поскольку объединение

 Читать далее...

Рынок труда  

Специалист по этическому ИИ, инженер по квантовым вычислениям или аналитик по метавселенной?

Новые тенденции в развитии ИТ могут привести к возникновению новых специальностей в

 Читать далее...

Книжная полка  

Учитесь убеждать и побеждать

Издательство «БХВ», как всегда, порадовало своих читателей хорошими книжными новинками. Кроме популярных

 Читать далее...

Сетевая инфраструктура  

Как удаленная работа меняет подход к сетевой инфраструктуре?

С увеличением числа сотрудников, работающих из дома, организации сталкиваются с необходимостью создания

 Читать далее...

Мониторинг  

Какой мониторинг нужен сегодня?

По мнению экспертов ГК InfoWatch, действия сотрудников – самая распространенная причина инцидентов

 Читать далее...

Книжная полка  

Руководство для тех, кто увлечен ИИ, программированием. И дизайном

Накануне лета издательство «БХВ» выпустило книжные новинки, от которых любителям чтения будет

 Читать далее...

Мобильные приложения  

Искусственный интеллект в мобильных приложениях: возможности и перспективы

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

 Читать далее...

ИТ-образование  

Как сделать ИТ-образование эффективным?

Эксперты ИТ-отрасли отвечают на вопросы «СА». Обсуждаем ключевые аспекты для улучшения образовательных

 Читать далее...

Work-life balance  

Как айтишнику найти баланс между работой и личной жизнью?

Обсуждаем инструменты для эффективного управления временем, снижения уровня стресса и достижения гармонии. На

 Читать далее...

Книжная полка  

Всё самое нужное – под одной обложкой

Отличительная черта книжных новинок, выпущенных недавно издательством «БХВ» – это их универсальность. Не просто

 Читать далее...

ИТ-инфраструктура  

Системы мониторинга ИТ-инфраструктуры-2025

Без мониторинга ИТ-инфраструктуры не обходится ни одна компания, хотя бы потому, что

 Читать далее...

Открытое ПО  

Безопасность Open Source: рискуем или контролируем?

Компания «Кросс технолоджис» изучила, как используется ПО с открытым кодом в компаниях

 Читать далее...

Работа с нейросетью  

Скажи, есть ли у тебя AI, и я скажу, кто ты

Недавно сервис по поиску работы SuperJob выяснил, что каждый второй россиянин уже

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 9496
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 9720
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 7141
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 4455
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 5254
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 5250
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 7918
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 4611
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 4864
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 8879
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 12309
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 13879
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 15650
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 10513
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 8532
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 6761
Комментарии: 4
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 5906
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 4780
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 4480
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 4697
Комментарии: 1
Рецензия на книгу «MongoDB в действии»

 Читать далее...

Друзья сайта  

 Брандмауэр. Часть 2

Архив номеров / 2003 / Выпуск №2 (3) / Брандмауэр. Часть 2

Рубрика: Администрирование /  Продукты и решения

ВЛАДИМИР МЕШКОВ

Брандмауэр

Часть 2

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

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

Процесс-демон после активизации передает модулю ядра правила фильтрации и в дальнейшем занимается ведением log-файла, в котором фиксируется время запуска/останова демона и попытки доступа с запрещенного адреса.

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

Программа инициализации и запуска процесса-демона

Нижеприведенный программный код разместим в файле sfc.c. Здесь будет находиться главная функция main().

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

Нам понадобятся следующие header-файлы:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "sfc.h" 

В файле sfc.h определено имя файла, в котором хранится идентификатор процесса-демона (PID-файл). Файл имеет следующее содержание:

#define PID "daemon.pid"

Идентификатор процесса-демона определим как глобальную переменную:

static pid_t pid;

А теперь распишем главную функцию main().

int main (int argc, char *argv[])

{

void usage():

Это прототип функции для обработки неправильного ввода параметров. Данная функция имеет следующий вид:

void usage()

{

fprintf(stderr," Usage: daemon [ start / stop ] ");

return;

}

Программа при запуске принимает один параметр, определяющий режим ее работы:

  • start – запустить процесс-демон на выполнение;
  • stop – завершить выполнение процесса-демона.

Для работы нам понадобятся переменные:

  • int pid_file – дескриптор файла для хранения идентификатора демона;
  • struct stat s – структура для хранения атрибутов файла.

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

if(argc!=2) {

usage();

return (-1);

}

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

Режим запуска процесса-демона на выполнение

if(!(strcmp(argv[1],"start"))) {

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

if(stat(PID,&s)==0) {

fprintf(stderr," Daemon is allready running ! ");

return (-1);

}

Инициализируем демон:

init_daemon();

Функция инициализации будет определена ниже.

Демон запустим как дочерний процесс.

pid = fork();

if (pid < 0) {

perror("fork");

exit(1);

}

if (pid==0) {

Отсоединяемся от терминала:

setsid();

Стартуем демон:

start_daemon();

exit(1);

}

Родительский процесс создает PID-файл и записывает в него идентификатор процесса-демона:

pid_file=open(PID,O_CREAT|O_TRUNC|O_RDWR,0644);

if(pid_file < 0) {

perror(PID);

return (-1);

}

if(write(pid_file,(char *)&pid,sizeof(pid_t)) < 0) {

perror(PID);

return (-1);

}

close(pid_file);

}

Режим остановки выполнения процесса-демона

if(!(strcmp(argv[1],"stop"))) {

Для остановки процесса-демона необходимо получить значение его идентификатора.

Это значение извлекаем из PID-файла:

pid_file=open(PID,O_RDONLY);

if(pid_file<0) {

perror(PID);

return (-1);

}

if(read(pid_file,(char *)&pid,sizeof(pid_t)) < 0) {

perror(PID);

return (-1);

}

close(pid_file);

PID-файл нам больше не нужен, удаляем его:

if(unlink(PID) < 0) {

perror(PID);

return (-1);

}

Теперь останавливаем процесс-демон, послав ему сигнал SIGINT:

kill(pid,SIGINT);

}

На этом функция main() завершается:

return (0);

}

Процесс-демон

Весь код, отвечающий за запуск, функционирование и остановку процесса-демона, разместим в файле sf_daemon.c. По сути, этот файл будет представлять собой набор функций.

Заголовочные файлы и переменные

Вначале, как всегда, определимся с заголовочными файлами и переменными. Нам понадобятся:

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <time.h>

#include <signal.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <linux/in.h>

#include "sf_daemon.h"

Файл sf_daemon.h имеет следующее содержание:

#include <linux/types.h>

#include <linux/ip.h>

Имя log-файла:

#define LOG "/var/log/daemon"

struct data_log {

__u32 addr;

int action;

int ready;

};

В этом файле определено имя log-файла и структура data_log, в которой хранятся данные для заполнения log-файла. Назначение полей структуры следующее:

  • __u32 – IP-адрес хоста (в сетевом формате), от которого поступил пакет;
  • int action – выполняемое действие (1 – разрешить прохождение пакета, 0 – отбросить пакет);
  • int ready – флаг готовности данных в устройстве для считывания.

Поскольку наш демон работает с двумя файлами (файл устройства /dev/firewall и log-файл), то необходимо определить две переменные для хранения дескрипторов этих файлов:

int fddev=0; - дескриптор файла устройства;

int f; - дескриптор log-файла.

Функции

Первая функция, которую мы рассмотрим, останавливает выполнение процесса-демона. Вот что она из себя представляет:

void stop_daemon()

{

close(fddev);

stop_log(f);

exit(0);

}

Функция закрывает устройство, завершает ведение log-файла и осуществляет выход из программы.

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

void packet_loop(void)

{

Структура для информационного обмена с модулем:

struct data_log data;

Размер блока данных, считанного из модуля:

int count;

Запускаем цикл:

for (;;) {

Считываем из модуля данные, в случае ошибки завершаем выполнение:

count=read(fddev,(char *)&data,sizeof(struct data_log));

if(count<0) stop_daemon();

Если установлен флаг готовности данных для считывания и поступил пакет с запрещенного адреса, фиксируем это событие в log-файле:

if(data.ready==1) {

if(data.action==0) {

if(fill_log(f,data.action,data.addr) < 0)

stop_daemon();

}

}

}

}

Заполнением log-файла ведает функция fill_log, к ней мы еще вернемся.

Теперь подошла очередь функции инициализации. Напомню, что ее задача – передать модулю ядра правила фильтрации (т.е. IP-адрес).

void init_daemon()

{

int err;

struct iphdr ip_pack;

В структуре ip_pack, в поле saddr (адрес источника), будет находится запрещенный IP-адрес.

Обнулим эту структуру:

memset(&ip_pack,0,sizeof(struct iphdr));

и заполним поле адреса источника:

ip_pack.saddr=inet_addr("192.168.1.10");

Подготовим к работе log-файл. Если log-файл отсутствует, создаем его:

f=open(LOG,O_CREAT|O_APPEND|O_RDWR,0644);

if(f<0) {

perror(«open log»);

exit(0);

}

Теперь передадим модулю правила фильтрации. Открываем устройство в режиме чтения/записи:

fddev=open("/dev/firewall",O_RDWR);

if(fddev<0) {

perror("firewall");

exit(0);

}

Записываем в него структуру ip_pack:

err=write(fddev,&ip_pack,sizeof(struct iphdr));

if(err<0) {

perror("firewall");

stop_daemon();

}

Итак, IP-пакеты, поступившие с хоста с адресом 192.168.1.10, будут заблокированы на входе нашей системы.

Выходим из функции:

return;

}

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

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

void start_daemon()

{

Демон должен реагировать только на один сигнал – SIGINT. При получении этого сигнала демон завершает выполнение. Все остальные сигналы необходимо заблокировать.

Определим переменные:

sigset_t mask;

static struct sigaction act;

Создадим полный набор сигналов, исключив из него SIGINT:

sigfillset(&mask);

sigdelset(&mask,SIGINT);

Блокируем все сигналы:

sigprocmask(SIG_SETMASK,&mask,NULL);

Определяем новый обработчик для SIGINT:

act.sa_handler=stop_daemon;

sigaction(SIGINT,&act,NULL);

А теперь стартуем:

start_log(f);

packet_loop();

exit(1);

}

LOG-файл

Нам осталось рассмотреть функции для ведения log-файла. Их три:

  • start_log – запись о начале выполнения процесса-демона;
  • fill_log – запись информации о блокировании IP-пакета;
  • stop_log – запись об остановке выполнения процесса-демона.

Каждая из этих функций фиксирует текущее время возникновения того или иного события.

Все три функции разместим в файле sf_log.c.

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <time.h>

#include <sys/socket.h>

#include <linux/in.h>

#define BSIZE 80

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

Функция start_log

int start_log(int f)

{

char buf[BSIZE];

time_t start_t;

Обнулим буфер и получим текущее время:

bzero(buf,BSIZE);

time(&start_t);

Формируем буфер и записываем его в log-файл:

sprintf(buf,"Daemon started at %s", ctime(&start_t));

if(write(f,buf,strlen(buf)) < 0) return (-1);

return (0);

}

Функция stop_log

Функции start_log и stop_log практически не отличаются друг от друга, кроме имен переменных, поэтому привожу код без комментариев:

int stop_log(int f)

{

char buf[BSIZE];

time_t stop_t;

bzero(buf,BSIZE);

time(&stop_t);

sprintf(buf,»Daemon stoped at %s», ctime(&stop_t));

if(write(f,buf,strlen(buf)) < 0) return (-1);

close(f);

return (0);

}

Функция fill_log

Эта функция, кроме дескриптора log-файла, принимает IP-адрес пакета, который был заблокирован (u_long addr), и идентификатор выполненного действия (int action). Функция очень простая, и необходимости в комментариях я не вижу.

int fill_log(int f, int action, u_long addr)

{

char buf[BSIZE];

time_t fill_t;

bzero(buf,BSIZE);

time(&fill_t);

if(action==0) {

sprintf(buf,"Packet from %s was rejected at %s",inet_ntoa(addr), ctime(&fill_t));

if (write(f,buf,strlen(buf)) < 0)

return (-1);

return (0);

}

}

Makefile

Для сборки исполняемого модуля создадим Makefile следующего содержания:

CC = gcc

name = daemon

DAEMON = sfc.o sf_daemon.o sf_log.o

$(name): $(DAEMON)

$(CC) -g -o $(name) $(DAEMON)

sfc.o: sfc.c

$(CC) -c sfc.c

sf_daemon.o: sf_daemon.c

$(CC) -c sf_daemon.c

sf_log.o: sf_log.c

$(CC) -c sf_log.c

clean:

rm -f *.o

Здесь все должно быть вам знакомо. Ключ «-g» при успешной сборке можно будет заменить на «-s».

Запуск и остановка выполнения процесса-демона

После сборки в текущем каталоге появится исполняемый файл daemon. Для его запуска наберите команду:

./daemon start

Перед запуском процесса-демона необходимо загрузить модуль ядра.

После запуска демона в текущем каталоге появится файл daemon.pid. Не удаляйте этот файл! В нем хранится идентификатор процесса-демона для возможности его корректной остановки. Для остановки выполнения процесса-демона введите команду:

./daemon stop

Файл daemon.pid автоматически удаляется.

Информация о времени запуска и останова процесса-демона, а также о заблокированных пакетах будет зафиксирована в файле /var/log/daemon.

При подготовке статьи были использованы исходные тексты и документация брандмауэра SINUS (http://www.ifi.unizh.ch).


Комментарии отсутствуют

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

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru