为网站配置服务器时,可能需要执行一些常见的条件操作。例如,某些文件可能会被用户的浏览器缓存比其他文件更长,或者网站的某些部分应该只允许通过安全连接(例如需要用户密码的任何内容),而网站的其他部分则不需要。
另一个简单的常见示例是确保在发布新网页而不是旧网页时,所有旧地址都将重定向到正确的位置。这很有用,因为它意味着旧的链接和书签不会停止工作,它也会保留Google的缓存。
Nginx的地图模块允许您在Nginx的配置文件中创建变量,其值是有条件的 - 也就是说,它们依赖于其他变量的值。在本指南中,我们将了解如何使用Nginx的地图模块实现两个示例:如何设置从旧网站网址到新网站的重定向列表,以及如何创建国家/地区的白名单来控制您网站的流量。
要学习本教程,您需要:
首先,我们将创建一个代表新发布网站的测试文件。我们将使用此文件来测试我们的配置。
让我们在默认的Nginx网站目录中创建一个简单的页面index.html
。这个文件将只有纯文本来描述内部的内容:主页。
sudo sh -c 'echo "Home" > /usr/share/nginx/html/index.html'
有了这个测试文件,接下来我们将检查curl
是否正确服务它。我们不需要为此命令指定index.html
,因为如果没有提供确切的文件名,则默认提供该文件。
curl http://localhost/
作为回应,你应该会看到一个字说Home就像如下:
Home
现在让我们尝试访问一个不存在的文件/usr/share/nginx/html
,比如old.html
。
curl -L http://localhost/old.html
响应将是系统错误消息,404 Not Found,表示该页面不存在。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>The page is not found</title>
. . .
</html>
我们在本教程中只是使用虚拟网站,但如果old.html
是真实网站上曾经存在并被删除的页面,则返回404将意味着该页面的所有链接都被破坏。这不太理想,因为这些链接可能已被Google编入索引,打印或记录,或通过任何其他方式共享。
在下一步中,我们将利用地图模块通过将查看器自动重定向到新的替换来确保此旧地址再次起作用。
对于只有几页的小型网站,简单的if
条件语句可用于重定向和类似的事情。然而,随着条件列表变长,这种配置从长远来看不易维护或扩展。
地图模块是一个更优雅,简洁的解决方案。它允许您将Nginx变量值与条件列表进行比较,然后根据匹配将新值与变量相关联。在此示例中,我们将比较请求的URL与我们要重定向到新对应的旧页面列表。对于每个旧地址,我们将关联新地址。
映射模块是核心Nginx模块,这意味着它不需要单独安装即可使用。要创建必要的映射和重定向配置,请在vi
或您喜欢的文本编辑器中打开默认服务器块Nginx配置文件。
sudo vi /etc/nginx/nginx.conf
找到server
配置块,如下所示:
. . .
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .
我们将添加两个新部分:一个在server
块之前,一个在其中。
server
块前面的部分是一个新map
块,它使用map模块定义旧URL和新URL之间的映射。server
块内的部分是重定向。
. . .
# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Old website redirect
if ($new_uri) {
rewrite ^ $new_uri permanent;
}
. . .
该map $uri $new_uri
指令获取系统变量$uri
的内容,该变量包含所请求页面的URL地址,然后将其与大括号中的条件列表进行比较。条件列表中的每个项目都有两个部分:要匹配的值,以及如果匹配,则分配给变量的新值。
map
块内的/old.html /index.html
行意味着如果$uri
值为/old.html
,则将$new_uri
更改为/index.html
。如果不匹配,则不会更改。在这里,我们只定义一个条件,但您可以在地图中定义任意数量的条件。
然后,使用块if
内的条件语句server
,检查变量$new_uri
的值是否已设置。如果是,则表示地图中的条件已满足,我们应该使用该rewrite
命令重定向到新网站。该关键字permanent
确保重定向将是一个301 Moved Permanently HTTP重定向,这意味着旧地址不再有效且不会重新联机。
保存并关闭文件以退出。
要启用新配置,请重新启动Nginx。
sudo systemctl restart nginx
要测试新配置,请执行与以前相同的请求:
curl -L http://localhost/old.html
这次输出中不会出现404 Not Found错误。相反,您将看到我们在步骤1中创建的简单主页。
Home
这意味着地图已正确配置,您可以通过向地图添加更多条目来使用它来重定向URL。
重定向URL是地图模块的一个有用的应用程序。另一个,我们将在下一步探讨,根据访问者的地理位置过滤流量。
有时,服务器可能会收到过多的自动恶意请求。这可能是DDoS攻击,企图对网站管理面板强制密码,或试图利用软件中的已知漏洞攻击网站并使用它来发送垃圾邮件或修改网站内容。
此类自动攻击可能来自许多不同国家/地区的许多不同分布式服务器,因此很难阻止。减轻此类攻击影响的一种解决方案是创建可以访问该网站的国家/地区的白名单。
这不是一个完美的解决方案,但在根据访问者的地理位置限制访问网站是一个明智的选择并且不限制网站的受众的情况下,该解决方案具有快速且不易出错的优点。
在服务器级别进行过滤比在网站级别进行过滤更快,并且还涵盖所有请求(包括静态文件,如图像)。这种过滤也可以防止请求到达网站软件,这使得漏洞更难以利用。
要使用地理过滤,我们首先创建一个新的配置文件。
sudo vi /etc/nginx/conf.d/geoip.conf
将以下内容粘贴到文件中。这告诉Nginx在哪里可以找到包含访问者IP地址与其各自国家/地区之间映射的GeoIP数据库。此数据库预装了Ubuntu 16.04。
# GeoIP database path
#
geoip_country /usr/share/GeoIP/GeoIP.dat;
下一步是创建必要的映射和限制配置。打开默认服务器块Nginx配置。
sudo vi /etc/nginx/nginx.conf
在步骤1和2中的修改后,找到server
配置块,如下所示:
. . .
# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Old website redirect
if ($new_uri) {
rewrite ^ $new_uri permanent;
}
. . .
我们将添加两个新部分:一个在server
块之前,一个在其中。
server
块前面的部分是一个新map
块,它定义了默认操作(不允许访问)以及允许访问网站的国家/地区代码列表。如果map
表示结果如此,则server
块内的部分拒绝访问网站。
. . .
# Allowed countries
#
map $geoip_country_code $allowed_country {
default no;
country_code_1 yes;
country_code_2 yes;
}
# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Disallow access based on GeoIP
if ($allowed_country = no) {
return 444;
}
# Old website redirect
if ($new_uri) {
rewrite ^ $new_uri permanent;
}
. . .
保存并关闭文件以退出。
在这里,我们将country_code_1
和country_code_2
作为占位符。将这些变量替换为要列入白名单的国家/地区的两个字符国家/地区代码。您可以使用ISO的完整,可搜索的所有国家/地区代码列表进行查找。例如,美国的两个字符代码是US
。
与第一个示例不同,在此map
块中,变量$allowed_country
将始终设置为某个值。默认情况下,它设置为no
; 如果$geoip_country_code
变量与块中的某个国家/地区代码匹配,则将其设置为yes
。如果$allowed_country
变量是no
,我们将返回444 Connection Closed Without Response而不是为实际网站提供服务。
要启用新配置,请重新启动Nginx。
sudo systemctl restart nginx
如果您没有将国家/地区添加到白名单,当您尝试访问http://your_server_ip
时,您会看到一条错误消息,例如页面无效或页面未发送任何数据。如果您确实将国家/地区添加到白名单,则会像以前一样看到Home。
虽然它可能是一个关于如何使用地图模块的非常简单的示例,但它显示了可以以许多其他不同方式使用的机制。map模块不仅允许简单的比较,还支持允许更复杂匹配的正则表达式。如果必须评估多个条件,这是使配置文件更清晰的好方法。
地图模块的另一个非常流行的用例是在非SSL环境中对网站的安全部分进行条件重定向。仅为需要密码输入的表单设置强制SSL连接是一个很好的例子,如何在现实世界场景中应用地图模块,我鼓励尝试这样的设置。
更多详细信息可以在Nginx的官方地图模块文档中找到。
更多CentOS教程请前往腾讯云+社区学习更多知识。
参考文献:《How to Use Nginx's map Module on CentO
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。