├── example.php ├── README.md └── class.dosdetector.php /example.php: -------------------------------------------------------------------------------- 1 | run(); 9 | 10 | //Default Running with Custom Landing Page for Banned IP Access 11 | //$myDosDetector->run('http://url/to/your/landing/page'); 12 | 13 | 14 | ////////////////////////////// 15 | // YOUR SITE SOURCE CODE HERE 16 | //.... 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP DosDetector Class Documentation 2 | 3 | Version: 1.0 4 | 5 | Release: June 2013 6 | 7 | Keyword: security, php, class, firewall, DoS Attack, IDS/IPS 8 | 9 | 10 | ## 1. What is this class? 11 | 12 | This PHP Class used for preventing Denial of Service (DoS) attack to your web server written by PHP. Running this script will monitoring all requests from an IP address and logged it into memory cache (PHP APC Caching). If an IP address sends too much request to your server, it will trigger the Intrustion Preventing System (IPS) and auto-ban this IP Address. 13 | 14 | 15 | ## 2. System Requirement 16 | 17 | * PHP 5.x 18 | * APC Cache ([Learn more..](http://en.wikipedia.org/wiki/List_of_PHP_accelerators#Alternative_PHP_Cache_.28APC.29)) 19 | 20 | 21 | ## 3. Installation 22 | 23 | - First, copy `class.dosdetector.php` file to your project, such as `./classes/` directory on your project. 24 | 25 | - Next, including `class.docsdetector.php` file. 26 | 27 | - Now, just create an object from this class and call `run` method before the first line of your project (usally in bootstrap, start up or index file) to start monitoring. You can pass an URL to run method in case banned IP will be redirect to passed URL. If you do not pass this parameter, banned IP will see a default message on screen. 28 | 29 | - Example code: 30 | 31 |
32 |
33 | //Put this in the beginning of your all page
34 | include_once('./classes/class.dosdetector.php');
35 | $myDosDetector = new DosDetector();
36 |
37 | //Default Running
38 | $myDosDetector->run();
39 |
40 | //Default Running with Custom Landing Page for Banned IP Access
41 | //$myDosDetector->run('http://url/to/your/landing/page');
42 |
43 | //////////////////////////////
44 | // YOUR SITE SOURCE CODE HERE
45 | //....
46 |
47 |
48 |
49 |
50 | ## 4. Editable Properties & Constants
51 |
52 | * `$ignoreIpAddress`: IP Address in this array will be ignored by this detector. Usually your Company IP...
53 | * `PHPIDS_QUOTA_IDS_TRIGGER`: if in a second, an IP Address request more than this value will be trigger method idsWorker() in this class. You can implement you code for this function (line 161 in class.dosdetector.php) to get the notification.
54 | * `PHPIDS_DURATION_IPS_TRIGGER`: The number of second to check for IPS (auto-banning) trigger.
55 | * `PHPIDS_QUOTA_IPS_TRIGGER`: if in `PHPIDS_DURATION_IPS_TRIGGER` seconds, same IP have more request than this value will be auto-banned by system.
56 |
57 | monitor.php script to monitoring. [http://codecanyon.net/item/php-dosdetector-class/4899130](http://codecanyon.net/item/php-dosdetector-class/4899130)
62 |
63 | - This package came with a standalone script to monitor the traffic (logged by DosDtector class). You can put this script anywhere on your web server (with PHP read permission), and run this script from browser to access monitor tool. Example: http://yoursite.com/monitor.php.
64 |
65 | - This page will show all the request (with IP Address, Time, User-Agent, Cookie status, Request URI, Referer URL) logged by DosDetector. Logged Accesses will be cached for 2 hours for performance.
66 |
67 | - This page will show you banned IP address (from auto-ban or manual-ban IP Address). You can manual-ban an IP Address if you see that IP request too much and have weird access. Banned IP addresses will not be clear automatically. This banned list only clear by you or by clear from APC cache.
68 |
69 | - You can detect whether a request have cookie or not, because a request without cookie is usually a search engine robot (Googlebot,..) or an automatic script crawling/flooding your website.
70 |
71 |
72 | ## Thank you!
73 |
74 | - Support me by buying this package at (http://codecanyon.net/item/php-dosdetector-class/4899130). Full package include PHP Class, Example and Standalone Monitoring & Setup Support.
75 |
--------------------------------------------------------------------------------
/class.dosdetector.php:
--------------------------------------------------------------------------------
1 | isApcEnable())
43 | {
44 | //access detail
45 | $curTime = time();
46 | $ipaddress = $this->getIpAddress();
47 | $havecookie = !empty($_COOKIE) ? 1 : 0;
48 | $useragent = strip_tags(substr($_SERVER['HTTP_USER_AGENT'], 0, 100));
49 | $uri = substr($_SERVER["REQUEST_URI"], 0, 100);
50 | $referer = isset($_SERVER['HTTP_REFERER']) ? substr($_SERVER["HTTP_REFERER"], 0, 100) : '';
51 |
52 | //Ignore Bot access
53 | if(!in_array($ipaddress, $this->ignoreIpAddress))
54 | {
55 | //////////////////////////
56 | //////////////////////////
57 | // get banned IP
58 | $bannedIpAddress = apc_fetch(self::PHPIDS_BANNEDIP_KEY);
59 | if(!$bannedIpAddress)
60 | $bannedIpAddress = array();
61 | else
62 | {
63 | if(in_array($ipaddress, $bannedIpAddress))
64 | {
65 | //YOU ARE BANNED;
66 |
67 | if($landingpage != '')
68 | header('location: ' . $landingpage);
69 | else
70 | die(self::PHPIDS_DEFAULT_BANNED_MSG);
71 | }
72 | }
73 |
74 |
75 | //thong tin access trong ngay
76 | $accessList = apc_fetch(self::PHPIDS_ACCESS_KEY . $suffix);
77 |
78 | //Update data
79 | //If not found this access before, create
80 | if(!$accessList)
81 | {
82 | $accessList = array($ipaddress => array($curTime => array(1, $havecookie, $useragent, $uri, $referer)));
83 | }
84 | else
85 | {
86 | //Neu may da truy cap
87 | if(isset($accessList[$ipaddress]))
88 | {
89 | //Vo cung khung thoi gian
90 | if(isset($accessList[$ipaddress][$curTime]))
91 | {
92 | $accessList[$ipaddress][$curTime][0]++;
93 | }
94 | else //vo o timestamp khac
95 | {
96 | $accessList[$ipaddress][$curTime] = array(1, $havecookie, $useragent, $uri, $referer);
97 | }
98 |
99 |
100 | /////////////////////
101 | /////////////////////////
102 | // IDS trigger
103 | if($accessList[$ipaddress][$curTime] > self::PHPIDS_QUOTA_IDS_TRIGGER)
104 | {
105 | $this->idsWorker();
106 | }
107 |
108 | ///////////////////////
109 | /////////////////////////
110 | // IPS Preventation
111 | $rangeToCheck = self::PHPIDS_DURATION_IPS_TRIGGER; //seconds
112 | $totalInPastRange = 0;
113 | foreach($accessList[$ipaddress] as $timestamp => $info)
114 | {
115 | //valid range to get SUM
116 | if($curTime - $timestamp < $rangeToCheck || $curTime == $timestamp)
117 | {
118 | $totalInPastRange += $info[0];
119 | }
120 | }
121 |
122 | //trigger IPS
123 | if($totalInPastRange > self::PHPIDS_QUOTA_IPS_TRIGGER)
124 | {
125 | //IPS Start
126 | //add to IPS
127 | if(!in_array($ipaddress, $bannedIpAddress))
128 | {
129 | $bannedIpAddress[] = $ipaddress;
130 | apc_store(self::PHPIDS_BANNEDIP_KEY, $bannedIpAddress);
131 | }
132 | }
133 |
134 | }
135 | else
136 | {
137 | //Neu chua truy cap, thi them vao danh sach da truy cap
138 | $accessList[$ipaddress] = array($curTime => array(1, $havecookie, $useragent, $uri, $referer));
139 | }
140 | } //end check key
141 |
142 | //Store the access info
143 | apc_store(self::PHPIDS_ACCESS_KEY . $suffix, $accessList, 3600);
144 |
145 |
146 | }//end check ignoreIpAddress
147 |
148 |
149 |
150 |
151 | }
152 | else
153 | {
154 | //APC not found.hehe.
155 | }
156 | }
157 |
158 | /*
159 | * This function will be called if the IDS trigger
160 | */
161 | private function idsWorker()
162 | {
163 |
164 | }
165 |
166 | public function isApcEnable()
167 | {
168 | return extension_loaded('apc') && ini_get('apc.enabled');
169 | }
170 |
171 | public function getAccessList()
172 | {
173 | $accessList = array();
174 | if($this->isApcEnable())
175 | {
176 | for($i = 0; $i < 24; $i++)
177 | {
178 | $listInHour = apc_fetch(self::PHPIDS_ACCESS_KEY . $i);
179 | if(!empty($listInHour))
180 | $accessList = array_merge($accessList, $listInHour);
181 | }
182 | }
183 |
184 | return $accessList;
185 | }
186 |
187 | public function getBannedIpList()
188 | {
189 | $bannedIpList = array();
190 | if($this->isApcEnable())
191 | {
192 | $list = apc_fetch(self::PHPIDS_BANNEDIP_KEY);
193 | if(!empty($list))
194 | $bannedIpList = $list;
195 | }
196 |
197 | return $bannedIpList;
198 | }
199 |
200 | public function banipInsert($ipaddress)
201 | {
202 | if($this->isApcEnable())
203 | {
204 | $list = apc_fetch(self::PHPIDS_BANNEDIP_KEY);
205 |
206 | if(!empty($list) && !in_array($ipaddress, $list))
207 | $list[] = $ipaddress;
208 | elseif(empty($list))
209 | $list = array($ipaddress);
210 |
211 | return apc_store(self::PHPIDS_BANNEDIP_KEY, $list);
212 | }
213 | else
214 | return false;
215 | }
216 |
217 | public function banipRemove($ipaddress)
218 | {
219 | if($this->isApcEnable())
220 | {
221 | $list = apc_fetch(self::PHPIDS_BANNEDIP_KEY);
222 |
223 | if(empty($list))
224 | return false;
225 | else
226 | {
227 | $newlist = array();
228 |
229 | foreach($list as $ip)
230 | {
231 | if($ip != $ipaddress)
232 | $newlist[] = $ip;
233 | }
234 |
235 | return apc_store(self::PHPIDS_BANNEDIP_KEY, $newlist);
236 | }
237 | }
238 | else
239 | return false;
240 | }
241 |
242 | /**
243 | * Get IP Address of current Access
244 | */
245 | public function getIpAddress()
246 | {
247 | $ip = '';
248 |
249 | if($_SERVER)
250 | {
251 | if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
252 | {
253 | $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
254 | }
255 | elseif(isset($_SERVER['HTTP_CLIENT_IP']))
256 | {
257 | $ip = $_SERVER['HTTP_CLIENT_IP'];
258 | }
259 | else
260 | {
261 | $ip = $_SERVER['REMOTE_ADDR'];
262 | }
263 | }
264 | else
265 | {
266 | if(getenv('HTTP_X_FORWARDED_FOR'))
267 | {
268 | $ip = getenv('HTTP_X_FORWARDED_FOR');
269 | }
270 | elseif(getenv('HTTP_CLIENT_IP'))
271 | {
272 | $ip = getenv('HTTP_CLIENT_IP');
273 | }
274 | else
275 | {
276 | $ip = getenv('remote_addr');
277 | }
278 | }
279 |
280 | return $ip;
281 | }
282 |
283 |
284 | }
285 | ?>
--------------------------------------------------------------------------------