Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 [ 207 ] 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

В системном журнале появляются заниси:

May 25 15:50:22 coprollth sniffer: Connection from 207.46.131.141 to 207,46.130.164:echo

В файл inetd.conf включается строка следующего вида:

echo stream tcp nowait nobody /usr/scrlpts/snfsqrd sniffer

Исходный текст программы приведен в примере 17.7.

Пример 17.7. backsniff

#1/usr/bin/perl -w

й backsniff - регистрация попыток подключения к определенным портам

use Sys Syslog; use Socket,

Й Идентифицировать порт и адрес

Ssockname = getsockname(STDIN)

or die "Couldnt identify myself: S\n",

(Sport, Siaddr) = sockaddr in(Ssockname);

$my address = inet ntoa($iaddr),

Й Получить имя службы

Sservice = (getservbyport (Sport, tcp))[0] ) Sport, # now identify remote address Ssockname = getpeername(STDIN)

or die Couldn t identify other end- $\n , (Sport, Siaddr) = sockaddr in(Ssocknaine); $ex address = inet ntoa(Siaddr);

Й Занести информацию в журнал

openlog( sniffer, ndelay, daemon),

syslogCnotice", "Connection from %s to %s:%s\n", $ex address,

Smyaddress, Sservice); closelogO, exit,

17.18. Программа: fwdport

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

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



17.18. Программа: fwdport 639

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

Например, командная строка может выглядеть так:

% fwdport -S nntp -1 fw.oursite com -г news.bigorg.com

Это означает, что программа выполняет функции сервера NNTP, прослушивая локальные подключения на порте NNTP компьютера fw.oursite.com. При поступлении запроса она связывается с news.bigorg.com (на том же порте) и организует обмен данными между удаленным сервером и локальным клиентом.

Рассмотрим другой пример:

% fwdport -1 myname.9191 -г news.bigorg com:nntp

На этот раз мы прослушиваем локальные подключения на порте 9191 хоста myname и связываем клиентов с удаленным сервером news.bigorg.com через порт NNTP.

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

Пример 17.8. fwdport

#1/usr/bin/perl -w

# fwdport - прокси-серэер для внешних служб

use strict, # Обязательные объявления

use Getopt::Long; # Для обработки параметров

use Net::hostent; # Именованный интерфейс для информации о хосте

use IO;:Socket; # Для создания серверных и клиентских сокетов

use POSIX ;sys wait h"; # Для уничтожения зомби

ту (

%Children, # Хэш порожденных процессов

SREMOTE, # Внешнее соединение

$LOCAL, # Для внутреннего прослушивания

SSERVICE, # Имя службы или номер порта

$proxy server, # Сокет, для которого вызывается acceptO

$МЕ, # Базовое имя программы

($МЕ = $0) =" S,.*/,,; # Сохранить базовое имя сценария



Пример 17.8 (продолжение)

check args(); # Обработать параметры

start proxy(); # Запустить наш сервер

service clients(), # Ждать входящих подключений

die "NOT REACHED"; # Сюда попасть невозможно

# Обработать командную строку с применением расширенной версии

# библиотеки getopts sub check args {

GetOptions(

remote=s" => \$REMOTE,

"local=s" => \$LOCAL,

service=s" => \$SER\/ICE, ) or die «EOUSAGE,

usage. $0 [ --remote host ] [ --local interface ] [ --service service ] EOUSAGE

die Need remote unless $REMOTE,

die "Need local or service" unless $LOCAL SSERVICE,

# Запустить наш сервер sub start proxy {

my @proxy server config = ( Proto => tcp. Reuse => 1, Listen => SOMAXCONN,

push @proxy server config, LocalPort => SSERVICE if SSERVICE, push @proxy server config, LocalAddr => SLOCAL if SLOCAL, Sproxy server = 10;-Socket;lNET->new(@proxy server config)

or die "cant create proxy server S@; print [Proxy server on ", (SLOCAL \ \ SSERVICE), initialized. ]\n;

sub service clients { my (

$local client, # Клиент, обращающийся к внешней службе

$lc info, # Имя/порт локального клиента

Sremote server, # Сокет для внешнего соединения

@rs config, # Временный массив параметров удаленного сокета

Srs info, # Имя/порт удаленного сервера

Skidpid, # Порожденный процесс для каждого подключения

SSIG{CHLD} = \&REAPER; tt Уничтожить зомби acceptingO;

# Принятое подключение означает, что внутренний клиент

# хочет выйти наружу

while (Slocal client = $proxy server->accept()) { $lc info = peerinfo($local client);



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 [ 207 ] 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242