Новости
Обзоры и тесты
Техно
Советы
Разное
Главная » Техно

Управление iptables при помощи CGI-скриптов

Добавлено на 29.05.2019 – 18:50

Использование функционала CGI, скриптов bash(равно как и на другом языке программирования), веб-сервера и авторизации по ключам ssh позволяет легко реализовать полезные в администрировании веб-приложения. Ниже представлен практический пример: удалённое управление сетевым фильтром iptables через веб-интерфейс.

Задача: при помощи веб-форм размещённых на веб-сервере, добавлять удалять и просматривать правила сетевого фильтра iptables на удалённых серверах, также запускать ping и traceroute, получать результат вывода в веб-интерфейс. Такой функциона полезен для упрощения процесса конфигурирования сетевого экрана, позволяет исключить использование консоли при конфигурировании, и соответственно не давать доступ пользователям в shell, если есть дублирующие сервера, управлять правилами сетевых фильтров на всех одновременно.
Ниже представлена общая схема работы. Данный материал не приследует цель дать полную инструкцию по реализации такой схемы, а лишь даёт идею для реализации с некоторыми техническим подробностями.

Пользователь, при помощи веб-браузера, авторизуется(при помощи встроенного в веб-сервера Apache механизма) на странице, которая сорержит CGI-скрипт, когда пользователь добавляет удаляет или просматриваем правила в iptables через веб-форму, скрипт по ssh «дёргает» другие скрипты находящиеся на удалённом сервере и возвращает в веб-браузер клиента результат выполнения скрипта с удалённого сервера.

Процесс настройки выглядит следующим образом:
1) Настройка веб-сервера Apache и его работу с CGI
2) Защита логином и паролем директорию веб-сервера где находятся скрипты
3) Создание пользователя на удалённом хосте, где будут выполняться команды от CGI скриптов
при помощи ssh
4) Добавление прав пользователю на выполнения команд требующих повышения прав при помощи sudo
5) Загрузка bash скриптов обработчиков команд по ssh от веб-сервера на удалённом хосте
6) Разрешаем авторизацию по ключам для sshd
7) Настройка авторизации по ключам ssh
8) Загрузка bash скриптов в директорию CGI назначение им прав
9) Тестирование работы

Шаг 1. Настройка веб-сервера Apache и cgi

В Linux Centos открываем /etc/httpd/conf/ httpd.conf, находим строки:

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
#
# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
#
<Directory "/var/www/cgi-bin">
    #AllowOverride None
    AllowOverride All
    Options None
    Order allow,deny
    Allow from all
</Directory>

Здесь нас интересует параметр AllowOverride, который по умолчанию установлен как None, меняем её на AllowOverride All.

Далее рестартуем Apache:

/etc/init.d/httpd restart

Тоже самое, но для Debian, здесь будет отличаться настройка Apache.

Переходим в /etc/apache2/sites-available
создаём файл firewall-web
# > firewall-web
Порт 80 на котором будет находиться виртуальный хост:

Listen *:80
<VirtualHost *:80>
ServerAdmin ignat@spb.ru

DocumentRoot /usr/lib/cgi-bin
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride All
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error-firewall-web.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access-firewall-wb.log combined
</VirtualHost>

Сохраняем.

Далее переходим в директорию /etc/apache2/sites-enabled
И создаём символическую ссылку на /etc/apache2/sites-available/firewall-web

Теперь делаем reload конфигурации Apache:

#/etc/init.d/apache2 reload

Также нужно проверить что в /etc/apache2/mods-enabled есть ссылка на файл /etc/apache2/mods-available/cgi.load
Если нет, то создать, и перечитать конфигурацию веб-сервера:
#/etc/init.d/apache2 reload
Отлично, теперь надо защитить наши скрипты от неавторизованного доступа, один из простейших вариантов добавить http аутентификацию и авторизацию.

Шаг 2. Защита логином и паролем директорию веб-сервера где находятся скрипты

Настройка простой аутентификации и авторизации в Apache

Настраивается аутентификация либо в файле httpd.conf, либо в файле .htaccess. При настройке посредством .htaccess, необходимо сначала убедиться, что директива AllowOverride в файле httpd.conf разрешает получение настроек из файла .htaccess. Директива AllowOverride может принимать следующие значения:

    — AllowOverride None — файлы .htaccess игнорируются веб-сервером. Данное значение оказывает положительное влияние на быстродействие веб-сервера.
    — AllowOverride All — обрабатываются все без исключения директивы из файлов .htaccess.
    — AllowOverride AuthConfig — разрешены директивы аутентификации-авторизации, такие как AuthName, AuthType, AuthUserFile, AuthGroupFile, Require и т.д.

Чтобы авторизация заработала, нам надо сделать следующее:

    — Разрешить аутентификацию в конфигурационном файле Apache (файл httpd.conf)
    — Прописать защищаемый ресурс в конфигурацию Apache (в файле .htaccess).
    — Создать файл с паролями .htpasswd.

Далее, предполгаем что наши скрипты лежат в директории /var/www/cgi-bin/.
Мы защищаем директорию с нашими скриптами /var/www/cgi-bin/ поэтому создаём в ней файл .htaccess с правами apache:

#> .htaccess
#chown apache:apache .htaccess
В файл .htaccess добавим:
AuthName "Authentication"
AuthType Basic
AuthUserFile /var/www/cgi-bin/.htpasswd
require valid-user

Что обозначает каждая из директив:

AuthName – текст содержащийся в данной директиве, выводится в окне ввода пароля. Он должен быть написан в одну строку и заключен в двойные кавычки.
AuthType — типы аутентификации: Basic или Digest. Рекомендуется использовать первый, т.к. второй поддерживается не всеми браузерами.
AuthUserFile — полный путь к файлу с логинами и паролями, для аутентификации пользователей. Пароли содержаться в шифрованном виде. Рекомендуется хранить данный файл в папке, к которой нет доступа для пользователей, это необходимо, чтобы предотвратить кражу паролей.
require valid-user – директива предписывает, что к URL получают доступ только, пользователи, успешно прошедшие аутентификацию.

Сохраняем. Теперь нужно создать файл .htpasswd
Это делается при помощи утилиты htpasswd
Ключи:
-cm — ключи утилиты:
-с – указывает, что необходимо создать новый файл
-m –шифрует пароли по алгоритму MD5
.htpasswd – имя файла с паролями
firewall – логин
Создаём пользователя с новом файле:

#htpasswd -cm .htpasswd firewall

Дважды вводим пароль для пользователя firewall.
Листинг содержимого получившегося файла:

# cat .htpasswd
firewall:$apr1$xMW8mAaG$259lBs0uXj.M/t1Yu7T2u1

Добавить ещё одного пользователя в существующий файл:
#htpasswd -m .htpasswd ignat

Теперь при открытии адреса http://192.168.1.252/cgi-bin/ будет появляться окно авторизации:

После успешной перезагрузки переходим в директорию /usr/lib/cgi-bin и размещаем здесь файлы CGI-скриптов.

Шаг 3. Создание пользователя на удалённом хосте, где будут выполняться команды от CGI-скриптов при помощи ssh

Добавляем авторизацию по ключам ssh. Мы поставили веб-сервер Apache на одной машине 192.168.1.252, залить туда скрипты и при помощи команд SSH удалённо выполнять команды на хосте 192.168.1.16 и анализировать из результат, например:

ssh firewall-edit @192.168.1.16 'uptime'
13:32:59 up 584 days,  1:26,  4 users,  load average: 0.41, 0.34, 0.27

Для этого нужно настроить авторизацию по ключам на ssh-клиенте(192.168.1.252) и на удалённом ssh-сервере (192.168.1.16).

Создадим пользователя на удалённом сервере, дадим ему права на выполнение без пароля команд iptables и iptables-save:

#useradd firewall-edit  --create-home --comment 'Remote firewall editor' --shell /bin/bash
#passwd firewall-edit  

Шаг. 4 Добавление прав пользователю на выполнения команд требующих повышения прав при помощи sudo

Отлично, теперь нужно добавить возможно выполнять команды iptables и iptables-save без прав root.
Пропишем в /etc/sudoers, из под root отредактируем данный файл:

#aptitiude install sudo
#sudoedit /etc/sudoers

Добавим следующие строки:

firewall-edit  ALL=(ALL) NOPASSWD:/sbin/iptables
firewall-edit  ALL=(ALL) NOPASSWD:/sbin/iptables-save

Сохраняем.

Шаг. 5 Загрузка bash скриптов обработчиков команд по ssh от веб-сервера на удалённом хосте

Конечно, можно посылать по ssh просто команды, затем обрабатывать их вывод на веб-сервере(192.168.1.252), но зачем «гонять» лишние данные? Поэтому загрузим скрипты которым будут передаваться нужные параметры, они буду их обрабатывать и выдавать результат, который мы передадим назад веб-серверу и покажем пользователю на веб-странице.

Ниже пример:

ucexpert.ru:/home/firewall-edit# cat firewall-find-ip.sh
#!/bin/bash 
sudo iptables -L CLIENTS -n -v --line-number| sed '1,1d'| grep $1 |  awk '{print "<tr><td>" $1 "</td><td>" $9 "</td></tr>"}'

Обращаю внимание что в вывод сразу же добавлена html разметка для отображении в веб-браузере клиента.
На стороне веб-сервера(192.168.1.252) этот скрипт будет вызываться так:

sudo ssh firewall-edit@192.168.1.16 "./firewall-find-ip.sh $IP"

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

ucexpert.ru:/home/firewall-edit# cat firewall-get-ip.sh
#!/bin/bash 
sudo /sbin/iptables -L CLIENTS -n -v --line-number| sed '1,1d' |  awk '{print "<tr><td>" $1 "</td><td>" $9 "</td></tr>"}'

На стороне веб-сервера(192.168.1.252) этот скрипт будет передаваться как:

sudo ssh firewall-edit@192.168.1.16 './firewall-get-ip.sh'

Второй скрипт возвращает назад все правила с номерами(--line-number) в цепочке CLIENTS, в виде html таблицы.

Команды ping и traceroute будем запускать без скриптов.

sudo ssh firewall-edit@192.168.1.16 "ping $IP -I $RTU -c 5" 
sudo ssh firewall-edit@192.168.1.16 "traceroute $IP"

Создаём окружение для скриптов на 192.168.1.16

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

/home/firewall-edit# > iptables

Копируем скрипты:

firewall-find-ip.sh
firewall-get-ip.sh
firewall.sh

Далее, назначаем необходимые права нашему пользователю, который будет удалённо выполнят команды:

#/home/firewall-edit# chown firewall-edit:firewall-edit firewall.sh
#/home/firewall-edit# chown firewall-edit:firewall-edit iptables

Скрипте на сервере запускаем при помощи sudo

#sudo /sbin/iptables -L -n -v | grep 84.84.84.84
#sudo ./firewall.sh add 84.84.84.84
#sudo ./firewall.sh del  84.84.84.84

Устанавливаем права на скрипты, пример:

#/home/firewall-edit# chown www-data:www-data firewall.sh
#/home/firewall-edit# chmod +x firewall.sh

Для отладки команд, которые передаются на удалённый сервер по SSH можно также использовать ttyrec или поставить утилиту snoopy:

ucexpert.ru:/home/firewall-edit# #aptitude install snoopy

Данная утилита логирует пользовательские команды, интерактивно смотреть их при помощи команды:

ucexpert.ru:/home/firewall-edit# #tail -f /var/log/auth
Apr 13 11:25:43 rtu4-1 sshd[3273]: Accepted publickey for firewall-edit from 192.168.1.252 port 53822 ssh2
Apr 13 11:25:43 rtu4-1 sshd[3273]: pam_unix(sshd:session): session opened for user firewall-edit by (uid=0)
Apr 13 11:25:43 rtu4-1 sudo: firewall-edit : TTY=unknown ; PWD=/home/firewall-edit ; USER=root ; COMMAND=/sbin/iptables -L CLIENTS -n -v --line-number
Apr 13 11:25:43 rtu4-1 sshd[3296]: Received disconnect from 192.168.1.252: 11: disconnected by user

Шаг 6. Разрешаем авторизацию по ключам для sshd на удалённом хосте
Открываем /etc/ssh/sshd_config
Проверяем, что следующие строки присутствуют и не закомментированы:

RSAAuthentication yes
PubkeyAuthentication yes

После чего перезапускаем sshd.

Шаг 7. Настройка авторизации по ключам ssh

На клиенте(192.168.1.16) локальной машине нужно сгенерировать пару ключей:

приватный id_rsa – хранится у клиента в файле /home/$user/.ssh/id_rsa
публичный id_rsa.pub – хранится в файле /home/$user/.ssh/id_rsa.pub

Где $user пользователь который генерирует ключ. Для root этот путь будет /root/.ssh

Мы генерируем файл из под root, соответственно чтобы подключаться по ssh веб-сервере и пользователь www-data должны запускать ssh с правами root или sudo ssh.

Сгенерируем пару ключей на клиенте (192.168.1.252) при помощи утилиты ssh-keygen (если ключ уже создан для нового хоста его генерировать не требуется)

# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:GXgitSSV+S66HjiNW9A9pcehP3WECulLpi5tuPrt2bs root@CDR-serv
The key's randomart image is:
+---[RSA 2048]----+
|    ..+o         |
|     +o+   .     |
|    . *.= . .    |
|   . + O.= .     |
|  . . O.S . .    |
|   = +.=.. .     |
|  +o=...o        |
|  o*++   .       |
|.o+*B.Eo         |
+----[SHA256]-----+

Чтобы авторизоваться на 192.168.1.16, предварительно открытый или публичный ключ должен быть загружен на сервер, для этого загрузим ключ на сервер 192.168.1.16 при помощи утилиты ssh-copy-id:

# ssh-copy-id firewall-edit@192.168.1.16
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.1.16 (192.168.1.16)' can't be established.
RSA key fingerprint is SHA256:Ma5zmprv9jGPkwdSwEgwFK2L4jyzCqc1xxoXYW5I7e0.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
firewall-edit@192.168.1.16's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'firewall-edit@192.168.1.16'"
and check to make sure that only the key(s) you wanted were added.

Таким образом ключ успешно инсталлирован.

Проверим работу авторизации по ключу:

# ssh firewall-edit@192.168.1.16 'uptime'
 18:13:03 up 582 days,  6:06,  2 users,  load average: 0.14, 0.21, 0.19

Теперь проверяем: из под пользователя firewall-edit заходим на удалённый хост по ключу и запускаем команду iptables.

# ssh firewall-edit@192.168.1.16 ' sudo /sbin/iptables -L -n -v '

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

Шаг 8. Загрузка bash скриптов в директорию CGI веб-сервера 192.168.1.252 назначение им прав

Создаём окружение для скриптов на клиенте.

Здесь есть один важный момент: скрипты запускаются из под пользователя www-data
Чтобы запускать ssh с авторизацией по ключам надо повысить уровень прав, нам поможет sudo.
Пропишем в /etc/sudoers, из под root отредактируем данный файл:

#sudoedit /etc/sudoers

Добавим следующие строки:

www-data  ALL=(ALL) NOPASSWD: /usr/bin/ssh

Сохраняем.

Теперь создаём cgi скрипт который будет выполняться при открытии и успешной авторизации в веб-браузере ссылки http://192.168.1.252/cgi-bin

Листинг скрпита index.cgi с комментариями:

root@CDR-serv:/var/www/html/cgi-bin# cat index.cgi
#!/bin/bash
echo "Content-type: text/html"
echo ""
echo '<html>'
echo '<head>'
echo '<meta http-equiv="Content-Type" application/x-www-form-urlencoded; charset=UTF-8">'
#Загружаем favicon
echo '<link rel="icon" href="http://192.168.1.252/favicon.png" sizes="32x32" />'
echo '<link rel="shortcut icon" href="http://192.168.1.252/favicon.png" />'

#Заголовок страницы
echo '<title>FIREWALL EDITOR for RTU4 </title>'
echo '</head>'
echo '<body>'
#Заголовок 3 уровня на странице
echo '<h3>' RTU 4 FIREWALL EDITOR
echo '</h3>'
echo '<p>'Проветить есть IP-адрес в списке разрешённых \(можно ввести часть, например: 84.52.\) без маски или префикса сети:
echo '</p>'
#Начало формы поиска разрешённых IP-адресов в списке
echo "<form method="POST" action="find-ip-addr.cgi">"
 echo '<table nowrap>
                  <tr><td>IP-адрес</td><td><input type="text" name="IP" pattern="^[0-9\.]{3,15}$" size="12"> </td>
                                      </tr></table>
                                      <button type="submit">Проверить</button>
                                      <input type="reset" value="Очистить"> </form>'
echo '<p>'Добавить IP-адрес и префикс сети \(опционально, например 29\):
echo '</p>'
echo "<form method="POST" action="firewall-add.cgi">"
 echo '<table nowrap>
                  <tr><td>IP-адрес</td><td><input type="text" name="IP" pattern="^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" size=12></td></tr>
                            <tr><td>Префикс сети</td><td><input type="text" pattern="[0-9]{1,2}" name="MASK" size=12 value=""></td></tr>
                                <tr><td>Комментарий: </td><td><textarea rows="5" cols="22" autocomplete="off" placeholder="Опционально" name="COMMENT" ></textarea> </td>
                                      </tr></table>
                                      <button type="submit">Добавить</button>
                                      <input type="reset" value="Очистить"> </form>'

#Конец формы поиска IP-адрес в списке разрешённых, при нажатии кнопки "Проверить" выполнится скрипт find-ip-addr.cgi причём он примет единственный аргумент IP и в браузер вернётся результат выполнения скрипта
echo '<p>'Удалить IP-адрес \(без маски или префикса сети\):
echo '</p>'

#Начало формы добавления IP-адреса или подсети в список разрешённых, тут кроме аргумента IP - адреса и MASK - маску IP которую следует удалить, может опционально передаваться комментарий
echo '<p>'Добавить IP-адрес и префикс сети \(опционально, например 29\):
echo '</p>'

echo "<form method="POST" action="firewall-add.cgi">"
 echo '<table nowrap>
                  <tr><td>IP-адрес</td><td><input type="text" name="IP" pattern="^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" size=12></td></tr>
                            <tr><td>Префикс сети</td><td><input type="text" pattern="[0-9]{1,2}" name="MASK" size=12 value=""></td></tr>
                                <tr><td>Комментарий: </td><td><textarea rows="5" cols="22" autocomplete="off" placeholder="Опционально" name="COMMENT" ></textarea> </td>
                                      </tr></table>
                                      <button type="submit">Добавить</button>
                                      <input type="reset" value="Очистить"> </form>'

#Конец формы добавления IP-адреса в списке разрешённых, при нажатии кнопки "Добавить" выполнится скрипт firewall-add.cgi, с входными аргументами - IP-адрес и маску, опционально комментарий и в браузер вернётся результат выполнения скрипта			
				
#Аналогично, начало формы удаления IP-адреса из iptables.				
echo '<p>'Удалить IP-адрес \(без маски или префикса сети\):
echo '</p>'

echo "<form method="POST" action="firewall-del.cgi">"
 echo '<table nowrap>
                  <tr><td>IP-адрес</TD><TD><input type="text" name="IP" pattern="^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" size=12></td></tr>
                 <tr><td>Комментарий: </td><td><textarea rows="5" cols="22" autocomplete="off" placeholder="Опционально" name="COMMENT" ></textarea> </td>
                                      </tr></table>
                                      <button type="submit">Удалить</button>
                                      <input type="reset" value="Очистить"> </form>'
									  
#Конец формы. При нажатии на кнопку "Удалить" выполнится скрипт firewall-del.cgi

#Форма отображения полного списка разрешённых IP-адресов
echo '<p>' Показать полный список разрешенныйх IP-адресов для транков РТУ 4
echo '</p>'
echo "<form method="POST" action="get-ip-list.cgi"> <button type="Submit"/>Показать</button></form>"
#Конец формы отображения полного списка разрешённых IP-адресов.
echo '</body>'
echo '</html>'
exit

При обращении к веб-серверу по адресу http://192.168.1.252/cgi-bin/ выполняется скрипт написанный на языке bash, а результат его выполения отдаётся веб-сервером в веб-браузер клиенту который запросил страницу, логично что это должен быть код HTML(хотя и не обязательно)
А а вот как будет выгядеть html-код страницы когда скрипт index.cgi будет выполнен и результат его работы будет возращён в веб-браузер клиента.

<html>
<head>
<meta http-equiv="Content-Type" application/x-www-form-urlencoded; charset=UTF-8">
<link rel="icon" href="http://192.168.1.252/favicon.png" sizes="32x32" />
<link rel="shortcut icon" href="http://192.168.1.252/favicon.png" />
<title>FIREWALL EDITOR for RTU4 and NET DIAGNOSTIC</title>
</head>
<body>

<h3> RTU 4 FIREWALL EDITOR
</h3>

Листинг скрпита find-ip-addr.cgi который запускается из скрпита index.cgi при использовании веб-формы поиска IP-адреса:


Проветить есть IP-адрес в списке разрешённых (можно ввести часть, например: 84.52.) без маски или префикса сети:



<form method=POST action=find-ip-addr.cgi>

<table nowrap>
                  
<tr>
<td>IP-адрес</td>
<td><input type="text" name="IP" pattern="^[0-9\.]{3,15}$" size="12"> </td>

                                      </tr>
</table>

                                      <button type="submit">Проверить</button>
                                      <input type="reset" value="Очистить"> </form>



Добавить IP-адрес и префикс сети (опционально, например 29):



<form method=POST action=firewall-add.cgi>

<table nowrap>
                  
<tr>
<td>IP-адрес</td>
<td><input type="text" name="IP" pattern="^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" size=12></td>
</tr>

                            
<tr>
<td>Префикс сети</td>
<td><input type="text" pattern="[0-9]{1,2}" name="MASK" size=12 value=""></td>
</tr>

				
<tr>
<td>Комментарий: </td>
<td><textarea rows="5" cols="22" autocomplete="off" placeholder="Опционально" name="COMMENT" ></textarea> </td>

                                      </tr>
</table>

                                      <button type="submit">Добавить</button>
                                      <input type="reset" value="Очистить"> </form>



Удалить IP-адрес (без маски или префикса сети):



<form method=POST action=firewall-del.cgi>

<table nowrap>
                  
<tr>
<td>IP-адрес</TD>
<TD><input type="text" name="IP" pattern="^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" size=12></td>
</tr>

		 
<tr>
<td>Комментарий: </td>
<td><textarea rows="5" cols="22" autocomplete="off" placeholder="Опционально" name="COMMENT" ></textarea> </td>

                                      </tr>
</table>

                                      <button type="submit">Удалить</button>
                                      <input type="reset" value="Очистить"> </form>



 Показать полный список разрешенныйх IP-адресов для транков РТУ 4



<form method=POST action=get-ip-list.cgi> <button type=Submit/>Показать</button></form>

</body>
</html>

Здесь скриптом генеририуются html формы, затем этими веб-формами может воспользоваться клиент, к каждой веб-форме привязан скрипт(например, find-ip-addr.cgi), который также выполниться при запуске веб-формы и вернет результат обработки. Этот скрипт «лезет» на удалённый сервер, запускает другой скрипт, например firewall.sh и возвращает результат назад, затем результат в виде веб-страницы возвращается пользователю.

Теперь рассмотрим файл find-ip-addr.cgi

#!/bin/bash

echo "Content-type: text/html"
echo ""
echo '<html>'

echo '<head>'

echo '
 <style type="text/css">
   TABLE {
    width: 300px; /* Ширина таблицы */
    border-collapse: collapse; /* Убираем двойные линии между ячейками */
   }
   TD, TH {
    padding: 3px; /* Поля вокруг содержимого таблицы */
    border: 1px solid black; /* Параметры рамки */
    text-align: center;
   }
   TH {
    background: #b0e0e6; /* Цвет фона */
   }
    hr {
    border: none; /* Убираем границу */
    background-color: black; /* Цвет линии */
    color: black; /* Цвет линии для IE6-7 */
    height: 2px; /* Толщина линии */
   }
}
html,
body {
  height: 100%;
}
.wrapper {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.content {
  flex: 1 0 auto;
}
.footer {
  flex: 0 0 auto;
}
  </style>'



echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'
echo '<link rel="icon" href="http://192.168.1.252/favicon.png" sizes="32x32" />'
echo '<link rel="stylesheet" href="http://www.megacorp.com/style.css" type="text/css">'

echo '<title>Firewall</title>'

echo '</head>'

echo '<body>'

echo '<h3>'Результат поиска:
echo '</h3>'
DATE=`date +%Y-%m-%d-%H:%M:%S`

if [ "$REQUEST_METHOD" = "POST" ]; then
    QUERY_STRING=`cat -`
    fi
    #echo `cat -` #Дебаг
    #echo "QUERY_STRING ==><> $QUERY_STRING </br>" #Дебаг
    IP=`echo $QUERY_STRING | sed -n 's/^.*IP=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` #Дебаг
    COMMENT=`echo $QUERY_STRING | sed -n 's/^.*COMMENT=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` #Дебаг
    REMOTE_USER=`echo $REMOTE_USER`
    REMOTE_ADDR=`echo $REMOTE_ADDR`
    HTTP_USER_AGENT=`echo $HTTP_USER_AGENT`
    #echo "IP ==> $IP </br>" #Дебаг
    echo "<b>Результат поиска для введённого IP-адреса: $IP </b></br></br>"
echo "<b>Найдены правила в таблице брандмауэра РТУ 4:</b></br></br>"
echo '<table border=1 cellpadding="4" cellspacing="0">'
echo '<td>№ Правила</td><td>IP-адрес или подсеть</td></tr>'
sudo ssh firewall-edit@192.168.1.16 "./firewall-find-ip.sh $IP"
export LANG="ru_RU.UTF-8" # Это очень важный момент, без неё скрипту insert-log.py не передаётся аргумент закодированный кириллицей
echo '</table>'
echo '<pre>'
./insert-log.py "$DATE" "ПОИСК" "$IP" "N/A" "$REMOTE_ADDR" "$REMOTE_USER" "$HTTP_USER_AGENT" "N/A" "$COMMENT"
echo '</pre>'
./get-ip-history.py "$IP"
echo "<br><br><small>Дата запроса: $DATE </small></br>"
echo "<small>Пользователь: $REMOTE_USER </small></br>"
echo "<small>Ваш адрес: $REMOTE_ADDR </small></br>"
echo '</body>'
echo '</html>'

Ниже пример листинга скрипта firewall-find-ip.sh который выполняется на 192.168.1.16 который ищет запрошенные пользователем правила iptables.

#!/bin/bash 
sudo iptables -L CLIENTS -n -v --line-number| sed '1,1d'| grep $1 |  awk '{print "<tr><td>" $1 "</td><td>" $9 "</td></tr>"}

Шаг 9. Тестирование работы

Вот как выглядет веб-странциа сгенерированная index.cgi:

Мы запускаем поиск первых трёх актетов IP адреса, например 84.52.72

и нажимаем кнопку «Проверить». Ниже результат:

Найдено несколько правил и они выведены в виде таблицы. Что произошло: пользователь загрузил страницу index.cgi с несколькими формами, передал переменную 84.52.72 в форму поиска IP-адреса, которая в свою очередь передала управление CGI-скрипту find-ip-addr.cgi данный скрипт выполняет комманду

sudo ssh firewall-edit@192.168.1.16 "./firewall-find-ip.sh $IP"

То есть, подключается к удалённому серверу выполняет на нём скрипт firewall-find-ip.sh и возвращает результат в веб-бразуер клиенту.

Автор: Игнат Кудрявцев

Оставить комментарий

Напишите Ваш комментарий ниже. Также Вы можете подписаться на комментарии к материалу через RSS

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

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

Мы поддерживаем Gravatar.

Контроль спама: *