Другие
Интеграция SQUID
Задача: Составить таблицу, через которую возможно управление файлом конфигурации squid. В настройки входит возможность управления скоростью доступа к сайтам, либо их запрет.
Так как нам надо редактировать только часть настроек определим внутри файла squid.conf начало и конец возможных настроек, вписав на отельной строке кодовые фразы, которые определим сами. Например:
# --------- START CONF ---------
# --------- STOP CONF ---------
Создадим таблицу настроек в клиентской базе, имеющую 4 поля:
1. «Включено» тип «список» с возможными значениями:
Да
Нет
2. «Тип» тип «список» с возможными значениями:
медленные
быстрые
запрещенные
3. «Сравнение» тип «список» с возможными значениями:
домен равен
адрес содержит
4. «Значение» тип «строка»
Теперь создадим в этой таблице доп.действие, которое позволит просматривать файл настройки squid.conf
Код:
<?
define(START_CONF, "# --------- START CONF ---------"); // начало блока настроек
define(END_CONF, "# --------- STOP CONF ---------"); // конец блока настроек
define(FILE, "/etc/squid3/squid.conf"); // расположение файла
if (is_readable(FILE)) {
$file = file_get_contents(FILE);
$startPosition = strpos($file, START_CONF);
$endPosition = strpos($file, END_CONF);
$output = "";
if ($endPosition>$startPosition && $startPosition!==false && $endPosition!==false) {
$startFile = substr($file, 0, $startPosition);
$currentConfig = substr($file, $startPosition, $endPosition + strlen(END_CONF) - $startPosition);
$endFile = substr($file, $endPosition + strlen(END_CONF), -1);
$output = nl2br(htmlspecialchars($startFile))."<div id='kbconfig' style='background-color:#ACE2AC;'>".nl2br(htmlspecialchars($currentConfig))."</div>".nl2br(htmlspecialchars($endFile));
}
else {
$output = $file;
}
}
else {
echo "<script type='text/javascript'>alert('Файл не существует или недоступен для чтения!')</script>";
}
header("Content-type: text/html; charset=utf-8");
?><!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><?=FILE?></title>
<style>
#linkToConf {
position: fixed;
right: 0;
top: 0;
background-color: #ACE2AC;
border: 1px solid black;
width: 100px;
height: 25px;
padding: 2px;
text-align: center;
}
</style>
</head>
<body>
<div id="linkToConf"><a href="#kbconfig">К настройке</a></div>
<?=$output?>
</body>
</html>
После установки доп.действия, создаем в таблице строку с любыми данными и в просмотре строки нажимаем на доп.действие. Откроется новое окно, где зеленым цветом будет подсвечен блок настроек.
Теперь создадим доп.действие, которое будет выгружать имеющиеся настройки в блоке. В коде предварительно задайте номера полей из таблицы в блоке под расположением файла
Код
<?
define(START_CONF, "# --------- START CONF ---------"); // начало блока настроек
define(END_CONF, "# --------- STOP CONF ---------"); // конец блока настроек
define(FILE, "/etc/squid3/squid.conf"); // расположение файла
//поля
define("STATUS","f4740"); // "включено"
define("TYPE","f4750"); // "тип"
define("COMPARING","f4760"); // "сравнение"
define("VALUE","f4770"); // "значение"
// если это задание для крона, надо указать id таблицы
// table_id = ?
if (is_readable(FILE)) {
$siteTypes = array(
"медленные" => array(
"домен равен" => "acl\\s+media_domain\\s+dstdomain\\s+",
"адрес содержит" => "acl\\s+media_url\\s+urlpath_regex\\s+-i\\s+"
),
"быстрые" => array(
"домен равен" => "acl\\s+fast_domain\\s+dstdomain\\s+",
"адрес содержит" => "acl\\s+fast_domain\\s+urlpath_regex\\s+-i\\s+"
),
"запрещенные" => array(
"домен равен" => "acl\\s+blacklist\\s+dstdomain\\s+",
"адрес содержит" => "acl\\s+blacklist\\s+urlpath_regex\\s+-i\\s+"
),
);
// получаем содержимое
$file = file_get_contents(FILE);
// проверяем наличие меток "начало настройки" и "конец настройки"
$startPosition = strpos($file, START_CONF);
$endPosition = strpos($file, END_CONF);
if ($endPosition>$startPosition && $startPosition!==false && $endPosition!==false) {
// сохраняем начало и конец файла не входящие в настройки
$currentConfig = substr($file, $startPosition + strlen(START_CONF), $endPosition-$startPosition-strlen(END_CONF)-2);
// удаляем текущие настройки
sql_query("TRUNCATE TABLE `".DATA_TABLE.$table_id."`");
// разбиваем полученные данные построчно
$lines = explode("\n", $currentConfig);
foreach ($lines as $text) {
$trimmedText = trim($text);
if ($text) {
if (preg_match("/^(\\s|#)*acl/Ui",$text)!==0) {
if (strpos($text, "#")===0)
$status = "Нет";
else
$status = "Да";
foreach ($siteTypes as $type=>$typeArray) {
foreach ($typeArray as $comparing=>$pattern) {
$pattern = '/'.$pattern.'(.*)$/Ui';
if (preg_match($pattern,$text,$result)!==0) {
$value = $result[1];
if ($comparing=="адрес содержит")
$value = str_replace("\\","",$value);
data_insert($table_id,array(STATUS=>$status,TYPE=>$type,COMPARING=>$comparing,VALUE=>$value));
}
}
}
}
}
}
}
else {
echo "<script type='text/javascript'>alert('Некорректное расположение меток начала и конца конфигурации')</script>";
}
}
else {
echo "<script type='text/javascript'>alert('Файл не существует или недоступен для чтения!')</script>";
}
Теперь вставим в squid.conf произвольные настройки для проверки
# --------- START CONF ---------
acl media_domain dstdomain .dropbox.com
#acl media_domain dstdomain .ubuntu.com
acl media_domain dstdomain .canonical.com
acl media_domain dstdomain .windowsupdate.com
acl media_domain dstdomain .microsoft.com
acl media_domain dstdomain .youtube.com
acl media_domain dstdomain .ntv.ru
# --------- STOP CONF ---------
Выполним в таблице доп.действие, в результате настройки должны считаться из файла и записаться в таблицу.
Теперь создадим доп.действие для записи из таблицы в файл.
Код:
<?
define(START_CONF, "# --------- START CONF ---------"); // начало блока настроек
define(END_CONF, "# --------- STOP CONF ---------"); // конец блока настроек
define(FILE, "/etc/squid3/squid.conf"); // расположение файла
//поля
define("STATUS","f4740"); // "включено"
define("TYPE","f4750"); // "тип"
define("COMPARING","f4760"); // "сравнение"
define("VALUE","f4770"); // "значение"
// не изменяемые параметры
$exception = "";
if (is_writable(FILE))
{
$siteTypes = array(
"медленные" => array(
"домен равен" => "acl media_domain dstdomain",
"адрес содержит" => "acl media_url urlpath_regex -i"
),
"быстрые" => array(
"домен равен" => "acl fast_domain dstdomain",
"адрес содержит" => "acl fast_domain urlpath_regex -i"
),
"запрещенные" => array(
"домен равен" => "acl blacklist dstdomain",
"адрес содержит" => "acl blacklist urlpath_regex -i"
),
);
// получаем содержимое
$file = file_get_contents(FILE);
// проверяем наличие меток "начало настройки" и "конец настройки"
$startPosition = strpos($file, START_CONF);
$endPosition = strrpos($file, END_CONF);
if ($endPosition>$startPosition && $startPosition!==false && $endPosition!==false) {
// сохраняем начало и конец файла не входящие в настройки
$startFile = substr($file, 0, $startPosition);
$endFile = substr($file, $endPosition + strlen(END_CONF), -1);
$text = "";
$result = sql_select_field(DATA_TABLE.$table_id,"*","`status`=0");
while ($row = sql_fetch_assoc($result)) {
if ($row[STATUS]!="Да")
$text .= "#";
$value = $row[VALUE];
if ($row[COMPARING]=="адрес содержит")
$value = preg_quote($value);
$text .= $siteTypes[$row[TYPE]][$row[COMPARING]]." ".$value."\n";
}
// соединяем части настроек
$finalConfig = $startFile.START_CONF."\n".$text."\n".END_CONF.$endFile;
// запись
file_put_contents(FILE,$finalConfig);
}
else {
echo "<script type='text/javascript'>alert('Некорректное расположение меток начала и конца конфигурации')</script>";
}
}
else {
echo "<script type='text/javascript'>alert('Файл не существует или недоступен для записи!')</script>";
}
Чтобы записывать значения в файл сразу при изменении в таблице создадим вычисление и вставим туда код из доп.действия «Обновить файл» .
Чтобы подтягивать в таблицу значения из файла раз в час, создадим задание в cron. В код скопируем код из доп.действия «обновить из файла» предварительно задав в нем идентификатор таблицы.
В итоге мы получаем возможность управления скоростью доступа к сайтам прямо из таблицы. Вычисление будет записывать изменения в squid.conf сразу после изменения значений в таблице. А с помощью доп.действий мы сможем контролировать операции вручную.