作者选择了 Apache Software Foundation作为 Write for Donations计划的一部分接受捐款。
介绍
攻击计数是一个应用程序,记录并表示您的网页接收的访问次数. 计数从1开始,每次访问网页时增加一次。
为了跟踪访问,攻击计数应用程序需要一种形式的数据库。虽然基于磁盘的数据库管理系统如MySQL可以工作,但内存数据库在速度,性能,可扩展性,简单性和易用性方面更好。
要跟踪您的网站访问,您需要一个 Redis 哈希地图. 这是一个数据结构,实现一个关键值对。 哈希地图提供了一个哈希表,将密钥绘制为值。 一旦用户访问了您的网页,您将基于他们的公共 IP 地址或用户名创建一个密钥(对于已验证的用户),然后将他们的访问总数初始化为 值 1。
在本指南中,您将在 Ubuntu 20.04 服务器上设置 Redis 和 PHP 的网站攻击计,本指南中的 PHP 脚本使用访问者的公共 IP 地址来跟踪访问。
前提条件
要跟随这个指南,请确保您有以下内容:
使用Ubuntu 20.04 的初始服务器设置(
)指南。 具有sudo
特权的非根用户。 遵循我们的 [How To Create a New Sudo-enabled User on Ubuntu 20.04 Quickstart指南来设置一个非根 sudo 用户。
- Apache 和 PHP. 要设置这些,请使用我们的 How To Install Linux, Apache, MySQL, PHP (LAMP) server stack on Ubuntu 20.04教程。 您可以跳过 步骤 2 — 安装我的SQL和 **步骤 4 — 创建一个虚拟
步骤1:安装 PHP Redis 扩展
在此步骤中,您将安装一个Redis扩展,允许PHP与Redis服务器交谈,您还将创建一个测试网页,该网页实现Redis哈希地图来跟踪网页访问。
在安装 Redis 扩展之前,请更新您的 Ubuntu 包信息索引:
1sudo apt update
然后运行以下命令来安装php-redis. 该扩展提供了与 Redis 服务器密钥值存储进行通信的 API:
1sudo apt install -y php-redis
重新启动 Apache 以加载新扩展:
1sudo systemctl restart apache2
您现在已经安装了一个PHP扩展,它会与您的Redis服务器进行交谈。接下来,您将创建一个test.php
网页,在Apache网页服务器的根目录下。这只是访问者在使用浏览器访问您的网站时请求的样本文件。在封面下,test.php
网页文件将加载一个hit_counter.php
脚本,您将后来创建以跟踪使用Redis服务器的网页访问。
在真实情况下,您的网站可能有数十个甚至数百个网页,对于本指南,您将为演示目的设置一个单一网页。
在您的终端窗口中,使用nano
创建一个新的test.php
文件,在您的 Web 服务器的 root 目录中:
1sudo nano /var/www/html/test.php
然后,在test.php
文件中输入以下信息:
1[label /var/www/html/test.php]
2<?php
3 require_once 'hit_counter.php';
4?>
5
6<!DOCTYPE html>
7<html>
8
9 <head>
10 <title>Sample Test Page</title>
11 </head>
12
13 <body>
14 <h1>Sample test page</h1>
15 <p>This is a sample test page.</p>
16 </body>
17
18</html>
当你完成编辑时,保存并关闭文件. 在这个步骤中,你创建了一个简单的HTML网页,在访问时加载一个hit_counter.php
文件。
步骤 2 — 创建一个 Redis 打击反对脚本
在生产环境中工作时,分离可重复使用的PHP文件非常常见,这允许您将这些文件中的逻辑应用于项目的不同部分,只需将它们的路径列入,而不是复制代码。
您将创建一个单一的hit_counter.php
文件,您可以在任何需要访问者跟踪的网页上添加。
在此文件中,您将使用php-redis
库连接到PHP的Redis服务器,然后,您将创建一个Redis哈希地图,以存储访问者访问您的网站的次数。
在您的终端窗口中,打开一个新的 hit_counter.php
文件,使用 nano
进行编辑:
1sudo nano /var/www/html/hit_counter.php
使用现在创建的 hit_counter.php
文件,打开一个新的 PHP 标签 <?php
. 然后,在一个 try {
块中输入以下代码以连接到您的本地 Redis 服务器在端口 6379
. 用 Redis 服务器的身份验证密码代替 `EXAMPLE_PASSWORD:
1[label /var/www/html/hit_counter.php]
2
3<?php
4
5 try {
6
7 $redis = new Redis();
8 $redis->connect('127.0.0.1', 6379);
9 $redis->auth('EXAMPLE_PASSWORD');
接下来,给 Redis 哈希地图(‘$siteVisitsMap’)一个你选择的名称.本指南使用‘siteStats’进行演示:
1[label /var/www/html/hit_counter.php]
2
3 $siteVisitsMap = 'siteStats';
定义 Redis 哈希地图后,您现在将初始化一个空的 Redis 密钥 (‘$visitorHashKey’)。
1[label /var/www/html/hit_counter.php]
2
3 $visitorHashKey = '';
4
5 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
6
7 $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];
8
9 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
10
11 $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];
12
13 } else {
14
15 $visitorHashKey = $_SERVER['REMOTE_ADDR'];
16 }
在此代码中,您正在使用PHP的如果
语句来确定访问者的IP地址,通过检查$_SERVER[‘HTTP_CLIENT_IP’]
、$_SERVER[‘HTTP_X_FORWARDED_FOR’]
或$_SERVER[‘REMOTE_ADDR’]
变量是否包含。
接下来,初始化一个$totalVisits
变量来存储每个IP地址的总访问量,并为其分配一个值 0。然后,使用PHPif (...) {...} else {...}
和$redis->hExists($siteVisitsMap, $visitorHashKey)
的陈述来检查IP地址是否在Redis服务器中有任何条目。
您将使用if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {...}
语句来检查在名为$siteVisitsMap
的地图上是否存在$visitorHashKey
。
如果在 Redis 服务器中存在名为 IP 地址的地图和密钥,请以声明 $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
和使用 $totalVisits = $visitorData[$visitorHashKey] + 1;
来增加 $totalVisits
变量。您正在使用 $redis->hMget
声明来获取与 IP 地址相关的击数数据。 hMget
函数接受您的地图($siteVisitsMap
)的名称和您想要从 Redis 服务器中获取的密钥的数组。在这种情况下,您只有一个密钥(`$visitorHashKey
如果您的脚本第一次遇到 IP 地址,请将$totalVisits
变量设置为 1. 最后,使用$redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
以根据前面的if (...) {...} else {...}
声明的结果设置$visitorHashKey
值。
接下来,通过回响总参观,欢迎访问者,并关闭捕获 (...) {...}
块:
1[label /var/www/html/hit_counter.php]
2
3 $totalVisits = 0;
4
5 if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {
6
7 $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
8 $totalVisits = $visitorData[$visitorHashKey] + 1;
9
10 } else {
11
12 $totalVisits = 1;
13
14 }
15
16 $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
17
18 echo "Welcome, you've visited this page " . $totalVisits . " times\n";
19
20 } catch (Exception $e) {
21 echo $e->getMessage();
22 }
一旦完成,您的 /var/www/html/hit_counter.php
文件应该与以下代码相似:
1[label /var/www/html/hit_counter.php]
2
3<?php
4
5 try {
6
7 $redis = new Redis();
8 $redis->connect('127.0.0.1', 6379);
9 $redis->auth('EXAMPLE_PASSWORD');
10
11 $siteVisitsMap = 'siteStats';
12 $visitorHashKey = '';
13
14 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
15
16 $visitorHashKey = $_SERVER['HTTP_CLIENT_IP'];
17
18 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
19
20 $visitorHashKey = $_SERVER['HTTP_X_FORWARDED_FOR'];
21
22 } else {
23
24 $visitorHashKey = $_SERVER['REMOTE_ADDR'];
25 }
26
27 $totalVisits = 0;
28
29 if ($redis->hExists($siteVisitsMap, $visitorHashKey)) {
30
31 $visitorData = $redis->hMget($siteVisitsMap, array($visitorHashKey));
32 $totalVisits = $visitorData[$visitorHashKey] + 1;
33
34 } else {
35
36 $totalVisits = 1;
37
38 }
39
40 $redis->hSet($siteVisitsMap, $visitorHashKey, $totalVisits);
41
42 echo "Welcome, you've visited this page " . $totalVisits . " times\n";
43
44 } catch (Exception $e) {
45 echo $e->getMessage();
46 }
当你完成编辑时,保存并关闭文件. 你现在编码了一个hit_counter.php
脚本. 接下来,你将创建另一个PHP脚本,从Redis哈希地图中收集的数据中生成报告。
步骤 3 — 创建网站统计报告脚本
一旦您在 Redis 哈希地图中收集了数据,如果您无法在报告中获取和表示信息,则可能没有任何意义。
要创建日志报告脚本,在终端窗口运行nano
,并创建一个新的/var/www/html/log_report.php
文件:
1sudo nano /var/www/html/log_report.php
然后,将下面的信息输入到文件中,以对 Redis 服务器的正确密码代替 EXAMPLE_PASSWORD
:
1[label /var/www/html/log.php]
2
3<!DOCTYPE html>
4<html>
5
6 <head>
7 <title>Site Visits Report</title>
8 </head>
9
10 <body>
11
12 <h1>Site Visits Report</h1>
13
14 <table border = '1'>
15 <tr>
16 <th>No.</th>
17 <th>Visitor</th>
18 <th>Total Visits</th>
19 </tr>
20
21 <?php
22
23 try {
24
25 $redis = new Redis();
26 $redis->connect('127.0.0.1', 6379);
27 $redis->auth('EXAMPLE_PASSWORD');
28
29 $siteVisitsMap = 'siteStats';
30
31 $siteStats = $redis->HGETALL($siteVisitsMap);
32
33 $i = 1;
34
35 foreach ($siteStats as $visitor => $totalVisits) {
36
37 echo "<tr>";
38 echo "<td align = 'left'>" . $i . "." . "</td>";
39 echo "<td align = 'left'>" . $visitor . "</td>";
40 echo "<td align = 'right'>" . $totalVisits . "</td>";
41 echo "</tr>";
42
43 $i++;
44 }
45
46 } catch (Exception $e) {
47 echo $e->getMessage();
48 }
49
50 ?>
51
52 </table>
53 </body>
54
55</html>
在上面的脚本中,你正在连接到Redis服务器,你正在使用声明$redis->HGETALL($siteVisitsMap);
来获取你的网页访问的哈希地图。然后,你正在使用PHPforeach($siteStats as $visitor => $totalVisits) {
声明来环绕和显示访问者的IP地址和他们对你的网站的访问数量。你正在使用RedisHGETALL
命令来获取所有字段(IP地址)和值(每个IP地址的总访问)从网站VisitsMap
地图。
你现在有一个测试页面,一个攻击计数脚本和一个报告页面来检查你的网站统计数据,接下来,你会测试你的攻击计数的功能,看看一切是否奏效。
步骤 4 – 测试 Redis 打击计数器
在此步骤中,您将测试您的打击计的整个逻辑。在您的 Web 浏览器上导航到下面的 URL。用您的服务器的公共 IP 地址或域名替换您的服务器-IP
。
1http://your-server-IP/test.php
使用不同的设备更新页面几次,以生成足够的统计数据. 每次访问后,您应该收到以下输出。
接下来,访问以下URL,以在HTML表中显示您的网站访问报告
1http://your-server-IP/log_report.php
您现在应该看到类似于下面的输出的报告。
您的打击计现在按预期运作。
结论
在本指南中,您已在 Ubuntu 20.04 服务器上设置了使用 Redis 和 PHP 的网站攻击计数。
正如您可以从本指南的样本源代码中看到的,Redis为创建和更新哈希地图提供了更清洁的方法。
正如本指南开始时所提到的,使用关系式数据库管理系统可能仍然可以工作,但您将编写大量代码来插入和更新底层表中的数据。
有关使用 Redis 内存数据库的更多信息,请遵循下面的指南: