Долго я искал решение как привязать правила IPFW и Squid к веб-интерфейсу, никак не мог найти готовое и подходящее для себя решение. Поставил SAMS но и он только для Squid. Задумался привязать его к IPFW, вот готовое решение, для таких как я... очень удобно если находишься вне офиса или территориально отдалён.Этот способ не является идеальным, но как вариант очень удобен и не требует больших усилий.
Система и компоненты: FreeBSD 8.0/Squid 2.6/SAMS-1.0.5/Rejik/PHP 5.3.14/Apache 2.2/Sudo Как ставить из портов думаю ясно.
И так, пишем скрипт и кладём его в /usr/local/etc/rc.d чтобы он запускался автоматом:
#! /bin/sh# PROVIDE: ipfwsams
. /etc/rc.subr
name="ipfwsams"
rcvar=`set_rcvar`
start_cmd="myscript_start"
stop_cmd=":"
load_rc_config $name
FwCMD="/sbin/ipfw"
DATE=`date`myscript_start()
{
if checkyesno ${rcvar}; thenecho > /usr/local/rejik/blocked_ipfw
grep -E -o -h '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /usr/local/rejik/_sams_banlists/default_denied/urls | tr A-Z a-z | sort | uniq >> /usr/local/rejik/blocked_ipfw
echo > /usr/local/rejik/blocked2_ipfw
grep -E -o -h '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /usr/local/rejik/_sams_banlists/4fb624a388513_denied/urls | tr A-Z a-z | sort | uniq >> /usr/local/rejik/blocked2_ipfw${FwCMD} table 1 flush
${FwCMD} table 2 flush
${FwCMD} table 3 flush
cat /usr/local/rejik/4b8bcc7c015ed.sams | awk '{ if ($1!="") {system("ipfw table 2 add "$1"")} }' > /dev/null
cat /usr/local/rejik/4fb624a388513.sams | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null
cat /usr/local/rejik/default.sams | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null
cat /usr/local/rejik/50336b692ec18.sams | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null
cat /usr/local/rejik/blocked_ipfw | awk '{ if ($1!="") {system("ipfw table 3 add "$1"")} }' > /dev/null
cat /usr/local/rejik/blocked2_ipfw | awk '{ if ($1!="") {system("ipfw table 3 add "$1"")} }' > /dev/null
echo "$DATE: IPFW to SAMS STARTED" >> /var/log/samslog
fi
}run_rc_command "$1"
Данный скрипт будет выделять нужные IP из списков Rejik-а и помещать их в таблицы IPFW (далее поясню как он работает).
Для того чтобы скрипт запускался автоматом при старте системы прописываем строчку в rc.config:ipfwsams_enable="YES"
Для запуска данного скрипта через веб-интерфейс нужно создать PHP файл, я расположил его в корне самса (/usr/local/share/sams/ipfwrestart.php):
<?php
exec ('/usr/local/share/sams/src/script/restart_ipfw');print("
<center><b>IPFW RESTARTED</b>
");
$str= file_get_contents("/var/log/samslog");
$str = nl2br($str, true);
$str = nl2br($str, false);
echo $str;
print("</center>");
?>Теперь пропишем ссылку на этот файл в Самсе, редактируем файл /usr/local/share/sams/src/squidbuttom_0_reconfig.php
Ищем строчку:
$str="<FONT color=\"BLUE\" SIZE=+1>$squidbuttom_0_reconfig_ReconfigSquid_3\n";
заменяем на:
$str="<FONT color=\"BLUE\" SIZE=+1> $squidbuttom_0_reconfig_ReconfigSquid_3<BR><BR><a href=\"ipfwrestart.php\">Restart IPFW</a></FONT><BR>\n";
для проверки лезем в самс > сквид > реконфигурировать, после того как команда отправлена должна вылезти ссылка на рестарт IPFW.
файл скрипт рестарта, это по сути команда sudo на старт скрипта от пользоватеоля с правами рута:
#! /bin/sh
sudo -u root /usr/local/etc/rc.d/ipfwsams startТак как PHP файл запустить Shell скрипт от пользователя www не может используем sudo.
Для того чтобы разрешить пользователю www запускать от рута нужно добавить в конфиг sudo строчку (/usr/local/etc/sudoers):www ALL=(ALL) NOPASSWD: /usr/local/etc/rc.d/ipfwsams start
нужные строки для IPFW (80 порт завёрнут на squid):allowedports="20,21,53,443,123,4321" (по каким портам натить)
ifout='vr0' (внешний)
ifuser='ste0' (внутренний)#TABLE1 - обычные пользователи
#TABLE2 - ADMINS
#TABLE3 - IP адреса к которым нужно заблокировать доступ (только для обычных пользователей)ipfw add divert natd all from "table(2)" to any out via ${ifout}
ipfw add deny all from "table(1)" to "table(3)"
ipfw add divert natd icmp from "table(1)" to any out via ${ifout}
ipfw add divert natd all from "table(1)" to any ${allowedports} out via ${ifout}И так, рассмотрим ранее упомянутый скрипт-граббер IP-адресов:
#! /bin/sh
# PROVIDE: ipfwsams
...echo > /usr/local/rejik/blocked_ipfw - создаём файл где будем хранить IP адреса из списков запрета SAMS
grep -E -o -h '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /usr/local/rejik/_sams_banlists/default_denied/urls | tr A-Z a-z | sort | uniq >> /usr/local/rejik/blocked_ipfw - по маске выковыриваем из файла Rejik все IP адреса, которые мы добавили в САМСЕ, в данном случае это первый созданный в самс Запрет доступа по URL.
echo > /usr/local/rejik/blocked2_ipfw - создаём файл где будем хранить IP адреса из списков запрета SAMS
grep -E -o -h '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /usr/local/rejik/_sams_banlists/4fb624a388513_denied/urls | tr A-Z a-z | sort | uniq >> /usr/local/rejik/blocked2_ipfw - по маске выковыриваем из файла Rejik все IP адреса, которые мы добавили в САМСЕ, в данном случае это какой то список имеющий идентификатор "4fb624a388513" в Запрет доступа по URL, его можно определить в таблицах MySql
${FwCMD} table 1 flush - Сбрасываем всё содержимое таблицы
${FwCMD} table 2 flush - Сбрасываем всё содержимое таблицы
${FwCMD} table 3 flush - Сбрасываем всё содержимое таблицыcat /usr/local/rejik/4b8bcc7c015ed.sams | awk '{ if ($1!="") {system("ipfw table 2 add "$1"")} }' > /dev/null - обавляем в таблицу IP адреса шаблона Админов (ID можно найти в MySql)
cat /usr/local/rejik/4fb624a388513.sams | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null - Добавляем в таблицу IP адреса входящие в шаблон обычных пользователей (ID можно найти в MySql)
cat /usr/local/rejik/50336b692ec18.sams | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null - Добавляем в таблицу IP адреса входящие в шаблон обычных пользователей, второй шаблон (ID можно найти в MySql)
cat /usr/local/rejik/default.sams | awk '{ if ($1!="") {system("ipfw table 1 add "$1"")} }' > /dev/null - Добавляем в таблицу IP адреса группы обычных пользователей, у меня 3 шаблона в САМС, разница только в доступе по 80 порту, поэтому всё остальное как у обычных пользователей (ID можно найти в MySql)
cat /usr/local/rejik/blocked_ipfw | awk '{ if ($1!="") {system("ipfw table 3 add "$1"")} }' > /dev/null - Добавляем в таблицу IP адреса к которым нужно закрыть доступ из ранее созданного файла
cat /usr/local/rejik/blocked2_ipfw | awk '{ if ($1!="") {system("ipfw table 3 add "$1"")} }' > /dev/null - Добавляем в таблицу IP адреса к которым нужно закрыть доступ из ранее созданного файла
echo "$DATE: IPFW to SAMS STARTED" >> /var/log/samslog - пишем в логе что всё удачно добавлено.
...
Проверяем, создаём новых пользователей, добавляем их к какому-либо шаблону, добавляем в списки запретов IP адреса и запускаем скрипт, проверяем таблицы, читаем логи. В логах при запуске от sudo появляется запись.
Если ничего не происходит смотрим на пути и имена файлов, скорее всего не тот файл указан.
URL:
Обсуждается: http://www.opennet.me/tips/info/2725.shtml
Толково!
> Для того чтобы разрешить пользователю www запускать от рутаНет слов. Рука лицо.
Ваше предложение, как из web-приложения выполнить ipfw, требующего рутовых прав ? И чем вам не нравится разрешение запуска через sudo одного конкретного скрипта ? Речь про настройку шлюза, на котором нет левых пользователей и на запущенном web-сервере ничего нет, кроме связанной с этим скриптом web-морды.
>Ваше предложение, как из web-приложения выполнить ipfw, требующего рутовых правоткройте для себя unix-сокеты
>>Ваше предложение, как из web-приложения выполнить ipfw, требующего рутовых прав
> откройте для себя unix-сокетыИ чем unix-сокеты в данном случае могут помочь ?
побуду капитаном: предлагается завести привелегированный процесс-демон, с которым через unix-сокет будет общаться веб-приложение.PS: сама статья полна некрофилии(8.0, natd) и костылизма.
Togda predlozite swoy variant bez ksotilizma
> Togda predlozite swoy variant bez ksotilizmaЗачем состязаться в невежестве?
выше уже написан вариант.