Простое решение для предотвращения DDoS — атак на PHP

👁 39 просмотров

DDoStop — это модифицированная версия проекта DDoS-Shield. Загрузить проект DDoStop можно здесь.

Описание

DDoStop — это набор скриптов с минимальным кодом для быстрой конфигурации и развертывания защиты PHP — страниц сайта от DDoS — атак. Конечно, проект не претендует на профессиональный подход к решению данной проблемы, но для простой защиты от ботов и мелких DDoS — атак вполне годен.

Техническая сторона

DDoStop работает по модели различного временного доступа реальных посетителей и ботов. Есть возможность сконфигурировать проект на  минимальное среднее время между визитами одного посетителя и максимальных посещений за минимальное время — это главный пункт конфигурации.  Реальные посетители физически не могут посетить одну страницу 90 в течении 30 секунд, но боты, которые являются основными DDoS — вредителями, могут себе такое позволить. Когда боты начинают атаковать, то они сразу попадают под запрет на доступ к сайту с выдачей ошибки в заголовке 503, как ниже на рисунке

ddos-atack-message

Если бот удалился, то через некоторое время его IP разблокируется, а это время можно задать в конфигурационном файле conf_ddos.php(об этом будет рассказано ниже). IP каждого бота , после блокировки, попадает в log-файл AttackersIPs.Log, расположенный в папке ddos/log.  В зависимости от степени безопасности могут выходить различные информационные сообщения. После каждой атаки ботов на адрес, записанный в конфигурационном файле отправляет сообщение на уведомление о том, что пойман очередной бот. Данная защита имеет большую значимость, когда требуется быстро защитить страницы сайта, чтобы предотвратить отток большого трафика и нагрузку на CPU от наплыва большого количества запросов DDoS — ботов.

Файлы проекта и включение в сайт

Проект состоит из 2 скриптов php: ddos/index.php и conf_ddos.php, иконки бана в папке ddos/images/cross.gif, файла лога ddos/log/AttackersIPs.Log.

  • index.php — ядро защиты. Весь процесс с операциями с IP выполняется здесь;
  • conf_ddos.php — файл конфигурации для начальной настройки проекта;
  • AttackersIPs.Log — файл, в которую будут записаны блокированные IP — адреса ботов.

Для включения сайта достаточно разархивировать проект с GitHub в корневую папку сайта, как ниже на рисунке

ddos-sec-add-in-site

 

И теперь, для того чтобы защитить ту или иную страницу достаточно подключить файл conf_ddos.php при помощи php функции require(«./conf_ddos.php»)  первой строчкой

include("conf_ddos.php"); //Защишаем страницу от DDoS - атак

Конфигурация/настройка защиты

Вся конфигурация и настройка управляется через conf_ddos.php, который имеет следующий вид

  $crlf=chr(13).chr(10);
  $itime=3;  // Минимальное число секунд между визитами
  $imaxvisit=10;  // Максимальное число визитов в $itime x $imaxvisits секундах
  $ipenalty=($itime * $imaxvisit);  // Минуты ожидания
  $iplogdir="./ddos/logs/";// Папка хранения логов с IP
  $iplogfile="./AttackersIPs.Log"; //Имя файла лога
  
  // Время
  $today = date("Y-m-j,G");
  $min = date("i");
  $sec = date("s");
  $r = substr(date("i"),0,1);
  $m =  substr(date("i"),1,1);
  $minute = 0;
  
  // установка данных для администратора
  $to      = 'support@voting.ru';   //Адрес админа
  $headers = 'From: voting.ru support@voting.ru' . "\r\n" .   // 	   
    		 'X-Mailer: voting.ru защишен от DDoS';
  $subject = "Предупреждение на возможные DDOS атаки @ $today:$min:$sec";
  

  //Сообщение при бане:
  $message1='<span style="color: red;">Временный интенсивный траффик или распознена как DDOS атака!!!</span>
';
  $message2='Пожалуйста, подождите ... ';
  $message3=' секунд или повторите попытку входа через несколько минут.
';
  $message4='<span style="color: blue;">Защита призведена DDOS скриптом на PHP!!!</span>
Если вы человек, то смените IP и вы свободны.
Мы временно забанили ваш IP <b>'.$_SERVER["REMOTE_ADDR"].' </b>из-за DDOS атаки.';
  $message5=' Ваш сайт был атакован или боты захотели зайти через IP - адресов: '.$_SERVER["REMOTE_ADDR"];
  $message6='
<img src="./ddos/images/cross.gif" alt="" border="0" />';
include("ddos/index.php");//Включаем главный файл DDOS - защиты из диерктории ddos

Проверка

Для проверки заходим на страницу с включенной DDoS защитой и жмем F5 для имитации обновления страницы в режиме DDoS — атаки и видим страницу

ddos-atack-message

Статья о том, как использовать IndexedDB в HTML5

👁 220 просмотров

IndexedDB — это API для хранения данных в браузере пользователя. Можно также использовать куки(cookie) и локальное хранилище(Local Storage), но они не предоставляют желаемый юзабилити, который предоставляет IndexedDB. Данные, хранимые в IndexedDB устойчивы. Данный способ хранения предоставляет богатые возможности запросов и доступны как в онлайн так и в оффлайн режимах. Также IndexedDB способен сохранять большие объемы данных. Увидеть состояние доступных хранилищ браузера можно через инструменты WEB — разработчика на панели Resources
IndexedDB-show-storage-img

 

IndexedDB — это текущий и рекомендованный кондидат для хранения локальных данных и доступный только в современных браузерах для Desctop.

IndexedDB сохраняет данные в форме объектов через индексные ключи. Всякая операция, которая происходит в IndexedDB происходит через транзакции. Объекты группированы внутри объектов хранения. IndexedDB содержит объектные хранилища и эти хранилища содержат объекты с уникальными keyPath.

IndexedDB vs LocalStorage

Хотя оба были спроектированы на предоставление клиентской стороне, как хранилища данных, но оба имеют различные цели и должны быть использованы согласно требованиям. LocalStorage хранит данные в key-value парах, но в отличии от IndexedDB, они не могут храниться в форме объектов. Вместо этого, они хранятся только в виде строковых key-value парах. Простой трюк хранения объектов с использованием LocalStorage — это использование объекта JSON.parse(). Но это не лучшее решение для хранения большого объема данных и сложных объектов. Тем не менее, LocalStorage был спроектирован для хранения мелких данных и предоставляет синхронный API доступа к ним. IndexedDB — это отличное решение для манипуляции больших объемов данных и предоставляет асинхронный API. Он использует индексацию на хранение данных и транзакции на выполнение операций. Он даже поддерживает простые типы данных. IndexedDB может казаться лучше, чем LocalStorage, но его API сложен для использования и на данный момент только последние версии современных браузеров поддерживают его. Для базового простого хранения можно продолжать использовать LocalStorage, но если вы хотите хранить большой объем данных, то IndexedDB — лучшее решение для этого, который, помимо всего позволяет вам выполнять комплексные сложные запросы на поиск данных.

IndexedDB vs Web SQL

WebSQL был также WEB — хранилищем с собственным API для хранения хранения данных на клиентской стороне. В отличии от IndexedDB, который является NoSQL базой данных, WebSQL использует SQL — запросы для операций с данными. W3C больше не поддерживает эту спецификацию, согласно http://www.w3.org/TR/webdatabase/

Предостережение. Эта спецификация больше не активна в поддержке и Web Applications Working Group не включила его в будущее развитие.

С этого момента, оно не поддерживается и его нельзя использовать в своих проектах.

IndexedDB vs Cookies

Cookies(печенки) — это может звучать вкусно, но это не так. Cookies могут отправлять и получать с каждым запросом http запросом данные в результируя в дополнительном трафике. Для примера, если у вас 10 кБ куков каждый и делаете 10 запросов, то сможете передать 100 кБ данных. Также, данные в куках имеют только строковый тип и следовательно их из строки необходимо парсировать. Также, область хранения куков лимитирован и многие пользователи могут блокировать поддержку куков в своих браузерах. Следовательно Cookies(куки) можно использовать для хранения очень мелких и не критичных данных.

Использование IndexedDB

1. Открытие БД IndexedDB.

В первую очередь вы должны быть уверены, ваш браузер поддерживает IndexedDB. Как упоминалось раннее, данный стиль хранения зареколмендован к сипользованию и следовательно не поддерживается во всех браузерах, в особенности в малоизвестных и тем более в мобильных.

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
 
if(!window.indexedDB)
{
    console.log("Your Browser does not support IndexedDB");
}

Раз мы знаем, что IndexedDb поддерживается, то мы можем открыть базу данных. Вы не можете поросто открыть базу данных, скорее IndexedDb потребует от вас запроса на окрытие базы данных.

var request = window.indexedDB.open("testDB", 2);

Здесь первый параметр — это имя базы данных, а второй — версия базы данных. Версия БД позволит вам представить схему текущей вашей БД в тех или иных режимах,т.е. предатсавит хранилища объектов, сохраненные в них и их структуры. Если вы обновите вашу БД до новой версии, то придется создать/удалить несколько объектов в хранилище, чем создать/удалить все объекты в хранилище.
Когда вы захотите увеличить версиб БД, то происходит событие onupgradeneeded. Вместе с onupgradeneeded имеются также события success, error и blocked, которые информируют об результатах запроса.

var db;
request.onerror = function(event){
    console.log("Error opening DB", event);
}
request.onupgradeneeded   = function(event){
    console.log("Upgrading");
    db = event.target.result;
    var objectStore = db.createObjectStore("students", { keyPath : "rollNo" });
};
request.onsuccess  = function(event){
    console.log("Success opening DB");
    db = event.target.result;
}

Событие onupgradeneeded должно вызываться каждый раз, когда WEB — страница выпадает в первые секунды открытия на пользовательских браузерах или, если, версии их БД были обновлены. Следовательно, вы можете создавать объекты хранения только при событии onupgradeneeded. Если не имеются обновления в версия и страница открыта предварительно, то вы можете получить событие onsuccess. onerror — событие происходит когда в процессе были допущены какие-либо ошибки. onblocked — происходит, когда предыдущее соединение не было закрыто. Выше в коде мы создаем объект хранения под именем «student» с индексным ключом “roll no”.

 

2. Добавление объекта в ObjectStore

Чтобы добавить данные в базу данных IndexedDB, мы , впервую очередь, должны создать транзакцию с правами чтения и записи на нашем объекте хранения. Выполнять то или иное действие на объете хранения требует создания транзакции. Следующий код показывает доступ к нашему объекту хранения и добавление в него данных.

var transaction = db.transaction(["students"],"readwrite");
transaction.oncomplete = function(event) {
    console.log("Success");
};

transaction.onerror = function(event) {
    console.log("Error");
};  
var objectStore = transaction.objectStore("students");

objectStore.add({rollNo: rollNo, name: name});

3. Удаление данных из ObjectStore

Удаление аналогично добавление. Для этого вам необходимо создать транзакцию и вызвать функцию удаления с ключом, удаляемого объекта

db.transaction(["students"],"readwrite").objectStore("students").delete(rollNo);

4. Доступ к объекту данных через ключ ObjectStore

Необходимо использовать get() функцию для получения данных объекта через ключ

var request = db.transaction(["students"],"readwrite").objectStore("students").get(rollNo);
request.onsuccess = function(event){
    console.log("Name : "+request.result.name);    
};

5. Обновление(редактирование данных) объекта

Для изменения объекта, сначала получаем объект, а затем после обновления содержимого обратно кладем в хранилище объектов.

var transaction = db.transaction(["students"],"readwrite");
var objectStore = transaction.objectStore("students");
var request = objectStore.get(rollNo);
request.onsuccess = function(event){
    console.log("Updating : "+request.result.name + " to " + name);
    request.result.name = name;
    objectStore.put(request.result);
};

 

Связь между JavaScript и PHP через JSON и XMLHttpRequest

👁 132 просмотров

JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript и обычно используемый именно с этим языком. Как и многие другие текстовые форматы, JSON легко читается людьми. Формат JSON был разработан и впервые использован Дугласом Крокфордом.
Несмотря на происхождение от JavaScript, формат считается языконезависимым и может использоваться практически с любым языком программирования. Для многих языков существует готовые методы для создания и обработки данных в формате JSON.

Предисловие

В данной статье расматриватся способы взаимодействия между сервером на языке PHP и клиентом на JavaSript.  Связующим звеном между двумя языками может выступать очень удобный формат обмена — JSON. Рассмотрим основные методы и принцип передачи.

Передача данных в формате JSON

Для передачи данных из JavaScript в PHP можно использовать 2 подхода:

  1. реализовать весь код на «голом» JavaScript при помощи объекта XMLHttpRequest;
  2. использовать готовую JavaScript — библиотеку, к примеру jQuery.

1. Реализация запроса на XMLHttpRequest. «Голый» подход

При использовании подхода на голом JavaScript необходимо использовать объект XMLHttpRequest.

Объект XMLHttpRequest (или, сокращенно, XHR) дает возможность браузеру делать HTTP-запросы к серверу без перезагрузки страницы. Несмотря на слово XML в названии, XMLHttpRequest может работать с данными в любом текстовом формате, и даже c бинарными данными. Использовать его очень просто. Различают два использования XmlHttpRequest: синхронное и асинхронное.

Кросбраузерный код для получения объекта XMLHTTPRequest. Хоть сейчас и решены большинство не стыковок совместимости одного и того же кода между разными браузерами, но все же остается проблема и главная причина этому Internet Explorer, который «плывет своим течением». Для решения данной проблемы можно создать кроссбраузерный код, который может выглядеть как:

   function getXmlHttpObject(){
        var xmlHttpObject;
        try {
          xmlHttpObject = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
          try {
            xmlHttpObject = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (e) {
            xmlHttpObject = false;
          }
        }
        if (!xmlHttpObject && typeof XMLHttpRequest!=='undefined') {
          xmlHttpObject = new XMLHttpRequest();
        }
        return xmlHttpObject;
    }

Выше приведенный код возвратит объект XMLHttpRequest, соответствующий текущему браузеру.
Синхронный режим. Выше мы привели пример функции, который получает объект XMLHttpRequest, теперь давайте будем использовать ее. Синхронный режим означает, что каждая последующая конструкция кода не будет выполнена, до тех пор, пока текущая не будет закончена. Синхронная передача — это false в 3-м параметре метода open(METHOD, URL, false). В этом примере через XMLHTTPRequest с сервера запрашивается страница example.php, и текст ответа сервера показывается через alert():

    var xmlhttp = getXmlHttpObject();
    var getData = "message=Hello! it is my message!&result=ok";
    xmlhttp.open('GET', 'example.php?'+getData, false);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.send(null);//Используется только для передачи методом POST
    if(xmlhttp.status >= 200 && xmlhttp.status < 400) {
        var data = JSON.parse(xmlhttp.responseText);//Переводим из JSON в Object
        alert(data.message);//Выводим второй параметр
        alert(data.result);//Выводим первый параметр
    }else
    {
       alert("Error!");//Если ошибка
    }

Следующий способ передачи данных и приема — это использование метода get. Использование get — это простейший способ передачи несложного запроса GET на сервер без необходимости использовать более сложную функцию $.ajax. Он допускает возможность использования одной функции, которая может быть вызвана после окончания запроса (только удачного запроса).

  var jsonData = {"message":"Hello! it is my message!", "result":"ok"};
   var jqxhr = $.get( "example.php", jsonData);
        jqxhr.done(function(responseText) {
        var data = JSON.parse(responseText);//Переводим из JSON в Object
        alert(data.message);//Выводим второй параметр
        alert(data.result);//Выводим первый параметр
    });
    jqxhr.fail(function() {
         alert( "Error!" );//Ошибка
    });
    jqxhr.always(function() {
         alert( "Finished!" );//Сеанс закончен
    });

Наиболее гибкий подход передачи данных методом GET и синхронным способом позволяет метод ajax

   var jsonData = {"message":"Hello! it is my message!", "result":"ok"};
   var getData = "message=Hello! it is my message!&result=ok";
   $.ajax({ url: "example.php", 
        method:"GET",
        async: false,
        data: getData,//или jsonData
        success: function(responseText) {
                var data = JSON.parse(responseText);//Переводим из JSON в Object
                alert(data.message);//Выводим второй параметр
                alert(data.result);//Выводим первый параметр
            },
        error:function(){
               alert( "Error!" );//Ошибка 
           },
        complete:function(){
               alert( "Finished!" );//Сеанс закончен
           }
        });

Серверный PHP код принимает GET — данные от клиента и пересылает обратно клиенту в формате JSON:

//Получаем GET - данные
$message = filter_input(INPUT_GET, "message");//$message = $_REQUEST["message"];
$result = filter_input(INPUT_GET, "result");//$message = $_REQUEST["result"];
//Пересылаем данные в формате JSON
echo json_encode(array("result"=>$result, "message"=>$message));