Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Технологии сетевых коммуникаций. Учебно-методическое пособие

.pdf
Скачиваний:
0
Добавлен:
15.08.2026
Размер:
1 Мб
Скачать

 

Продолжение табл. П4

 

-i, --in-interface

Критерий

Пример

iptables -A INPUT -i eth0

Описание

Интерфейс, с которого был получен пакет. Допускается только в

 

цепочках INPUT, FORWARD и PREROUTING. Если имя интер-

 

фейса завершается символом +, то критерий задает все интерфей-

 

сы, начинающиеся с заданной строки, например -i PPP+ обознача-

 

ет любой PPP интерфейс, а запись -i ! eth+ -- любой интерфейс,

 

кроме любого eth

Критерий

-o, --out-interface

Пример

iptables -A FORWARD -o eth0

 

Задает имя выходного интерфейса

Описание

 

-f, --fragment

Критерий

Пример

iptables -A INPUT -f

Описание

Правило распространяется на все фрагменты фрагментированного

 

пакета, кроме первого

Критерий

--sport, --source-port

 

iptables -A INPUT -p tcp --sport 22

Пример

 

Исходный порт, с которого был отправлен пакет. В качестве па-

Описание

 

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

 

службы, а также интервал: 22:80

Критерий

--dport, --destination-port

 

Порт назначения

Описание

 

iptables -p tcp --syn

Критерий

 

Распространяется на пакеты попыток соединений ( установлен

Описание

 

флаг tcp –syn)

Критерий

--tcp-option

 

iptables -p tcp --tcp-option 16

Пример

 

Опции пакета

Описание

 

--sport, --source-port

Критерий

 

iptables -A INPUT -p udp --sport 53

Пример

 

Исходный порт, с которого был отправлен пакет. В качестве па-

Описание

 

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

 

службы, а также интервал: 22:

 

Инверсия разрешена

 

41

 

Окончание табл. П4

 

--dport, --destination-port

Критерий

 

Порт назначения

Описание

 

--icmp-type

Критерий

 

iptables -A INPUT -p icmp --icmp-type 8

Пример

 

Тип сообщения ICMP Тип сообщения ICMP определяется номе-

Описание

 

ром или именем. Числовые значения определяются в RFC 792.

 

Чтобы получить список имен ICMP значений выполните команду

 

iptables --protocol icmp --help

 

 

Действие:

ACCEPT – принять

DROP – сбросить

REJECT – отклонить LOG – запротоколировать

Gnupg – утилита PGP шифрования и создания электронных подписей

Генерация ключа:

[user@mdk]$ gpg --gen-key

Экспорт ключа:

gpg -armor –export –i UID > myopen.asc

Импорт ключа

Открытый ключ может быть добавлен к вашей связке при помощи команды import:

gpg --import newkey.asc

Проверка отпечатка

Достоверность импортированного ключа должна быть подтверждена при помощи отпечатка:

gpg –fingerprint

42

Экспорт ключа на сервер ключей

Отпечатки ключа проверяются его владельцем. Можно сразу поместить ключ на сервер:

gpg --send-keys --keyserver wwwkeys.pgp.net

Подписывание ключа

gpg --edit-key -i UID (переходит в командный режим) sign

Посмотреть цепочку подписей: gpg --list-sigs.

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

UUID (–u)

Создание электронной подписи:

gpg --clearsign -a test.file - создает подпись

Проверка электронной подписи gpg --verify test.file.asc

Шифрование файла

gpg -ea –r email@ngs.ru test.file - зашифровать

Дешифрование файла

gpg -d test.file.asc >test.file расшифровать

Список литературы

1.Руководство по Iptables Iptables Tutorial 1.1.14 http://www.linuxsecurity.com/resource_files/firewalls/IPTables- Tutorial/iptables-tutorial.html

2.Шнайер Б. Прикладная криптография. Протоколы, алгоритмы, исход-

ные тексты на языке Си. – М.: Изд-во ТРИУМФ, 2002. – 816 с.: ил.

3.Салома А. Криптография с открытым ключом. – М.: Мир, 1995. – 318 с.

4.http://help.ubuntu.ru/wiki/iptables.

43

ЛАБОРАТОРНАЯ РАБОТА № 4

Разработка сетевого приложения на языке Си

Цель работы: знакомство с методами обмена данными при помощи классических сокетов. Разработка приложения, способного обмениваться данными по UDP в сетях IPv4 и IPv6. Знакомство с программированием на языке Си в системе Linux.

1. Краткие теоретические сведения

Сокет – конечная точка сетевых соединений в стеке протоколов TCP-IP. Процесс любого обмена данными по сети в многозадачной операционной системе сводится к тем или иным операциям с сокетами. Сокет – это точка входа в приложение, осуществляющее обмен данными в сети. Так, если пара IP адрес/ маска (или только адрес в сетях IPV6) однозначно определяет узел в сети, то сокет – приложение, которое готово обмениваться данными. Существует три режима операций с сокетами:

блокирующиеся сокеты;

асинхронные сокеты;

низкоуровневые сокеты.

Операции, которые потребуются для объявления сокета и привязки его к процессу, зависят от типа протокола, с помощью которого предполагается организовать соединение. Так, протокол TCP, как наиболее сложный, потребует создания соединения «точка-точка», в котором будут активно участвовать две оконечные точки, способные работать в двух режимах:

режим сервера;

режим клиента.

Для создания TCP сокета на языке Си потребуется следующее.

Выполнить инициализацию объекта «Сокет»

44

#include <sys/types.h> #include <sys/socket.h>

int socket(int domain, int type, int protocol);

Domain — пространство имен и протоколов:

IPV,4 IPV6, loopback.

Наиболее часто используются:

AF_UNIX(AF_LOCAL) — Фс ОS Unix- «локальный сокет» - обмен данными через специальный объект ФС

AF_INET — обмен данными через сетевой стек (в т.ч. Через loopback)

AF_PACKET — низкоуровневый обмен

Выполнить объявление сокета

int socket(int domain, int type, int protocol);

Type — указывает способ обмена данными по сети SOCK_STREAM — протокол TCP, требуется установка соедине-

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

SOCK_DGRAM — протокол UDP, не требует соединения, допус-

кает multicast, brodcast,network адреса

SOCK_RAW — низкоуровневое формирование ip. Возможна обработка icmp.

Дополнительно через ||

SOCK_NONBLOCK – неблокирующий сокет – точка для обслуживания нескольких клиентов из одного треда

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

та к IP адресу и порту

#include <sys/types.h> #include <sys/socket.h>

int bind(int sockfd, struct sockaddr *addr, int addrlen);

Sockfd – дескриптор сокета, то,что вернула команда socket на предыдущем шаге.

45

struct sockaddr {

unsigned short sa_family; // Семейство адресов, AF_xxx char sa_data[14]; // 14 байтов для хранения адреса

};

sa_family – идентификатор домена, аналогичный первому параметру функции socket.

Адрес sa_data -> – указатель на структуру

struct sockaddr_in {

 

short int

sin_family; // Семейство адресов

unsigned short int sin_port;

// Номер порта

struct in_addr

sin_addr;

// IP-адрес

unsigned char

sin_zero[8]; // "Дополнение" до размера струк-

туры sockaddr };

Адрес перевернут младшим «вперед», struct in_addr {

unsigned long s_addr;

};

Следовательно, потребуются преобразование порядка следования байт в словах.

Существует два формата представления адреса: порядок «хо-

ста» (host byte order) и «сетевой»(net byte order), отличающиеся по-

рядком следования старших/младших байт в слове. В сокете API используется сетевой порядок следования, поэтому требуется преобразование.

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);

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

создать очередь запросов на соединение. Сокет прослушивает порт и ожидает нового соединения:

int listen(int sockfd, int sizeoflisten);

sockfd – знакомый нам дескриптор сокета

46

int sizeoflisten – длина очереди. 1 – всего один клиент сможет подключиться параллельно к сокету

0 – все в порядке – новое соединение готово принимать данные. -1 произошла ошибка.

Сервер готов обслужить сокет — выполняется функция accept

#include <sys/socket.h>

int accept(int sockfd, void *addr, int *addrlen);

В структуру void *addr будет записан адрес клиента, который установил соединение.

int accept(int sockfd, null, null); – нам совершенно не интересно

«кто». Возврат — дескриптор, с которым можно делать send и receive или -1

На стороне клиентского сокета потребуется:

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

где все структуры и параметры нам уже знакомы. Возврат – дескриптор для read и wrire или -1.

Если не связывать по bind — клиентский сокет автоматически получит номер из пространства 1024-65535. Однако можно привязать и его, если это необходимо.

Обмен данными с сокетами

Отправка данных

int send(int sockfd, const void *msg, int len, int flags);

flags – манипулирование флагами пакета (например, TOS). Может быть NULL

Возврат – количество байт, или -1.

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

Пример функции, которая корректно отправляет данные в сокет: int sendallbuf(int s, char *buf, int len, int flags)

{

47

int total = 0; int n;

while(total < len)

{

n = send(s, buf+total, len-total, flags); if(n == -1) { break; }

total += n;

}

If(n==-1) return -1; else return total;

}

Получение данных

int recv(int sockfd, void *buf, int len, int flags);

Возврат: -1, если ошибка Возврат: 0, если соединение завершено

Возврат: количество прочитанных байт

Особенность recv – программа «останавливается» на этом операторе и ожидает получения «len» байт из сокет.

while(1)

{

bytes_read = recv(sock, buf, 1024, 0); if(bytes_read <= 0) break; send(sock, buf, bytes_read, 0);

}

В случае работы в режиме «сырого сокета» для обмена данными используется:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

48

Реализация сокета, соответсвующего стандарту IPv6, потребует изменений:

Структура sockaddr превращается в sockaddr_in6: struct in6_addr {

union {

uint8_t u6_addr8[16]; uint16_t u6_addr16[8]; uint32_t u6_addr32[4];

} in6_u;

#define s6_addr

in6_u.u6_addr8

#define s6_addr16

in6_u.u6_addr16

#define s6_addr32

in6_u.u6_addr32

};

 

struct sockaddr_in6 {

 

sa_family_t sin6_family;

/* AF_INET6 */

in_port_t sin6_port;

/* Порт транспортного уровня # */

uint32_t sin6_flowinfo;

/* IPv6 flow information */

struct in6_addr sin6_addr; /* IPv6 address */

uint32_t sin6_scope_id;

/* IPv6 scope-id */

};

 

Фактически при разработке кода можно подменить все элементы структур, характерных для IPv4 на IPv6. Однако для разработки совместимых на уровне кода приложений в будущем рекомендуется использовать универсальную структуру sockaddr_storage,

/* Structure large enough to hold any socket address (with the historical exception of

AF_UNIX). 128 bytes reserved. */

#if ULONG_MAX > 0xffffffff

#define __ss_aligntype __uint64_t #else

#define __ss_aligntype __uint32_t #endif

#define _SS_SIZE

128

#define _SS_PADSIZE

(_SS_SIZE - (2 * sizeof (__ss_aligntype)))

 

49

struct sockaddr_storage

 

{

 

sa_family_t ss_family;

/* Address family */

__ss_aligntype __ss_align; /* Force desired alignment. */ char __ss_padding[_SS_PADSIZE];

};

2. Методические указания для выполнения работы

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

Откомпилируйте программу при помощи компилятора GNU

GCC:

gcc ./yourprog.c -o ./yourprog.bin

Выполните отладку программы.

Запротоколируйте сетевой обмен (tcpdump) и приведите его в

отчет.

В процессе выполнения работы пользуйтесь справкой man <функция>.

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

3. Варианты задания

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

0-й байт: фиксирован и равен 129

1-й байт: день месяца

2-й байт: месяц

3-й байт: номер вашей бригады 4-й–40-й байт: латинскими буквами фамилия 1-го члена бригады

(sprintf(&buf[6], "…") )

41-й–60-й байт: латинскими буквами фамилия 2-го члена бригады 61-й–80-й байт: латинскими буквами фамилия 3-го члена бригады 81-й байт: сумма по «исключающему или» всех байт посылки

50

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]