介绍
为网站配置服务器时,可能需要执行一些常见的条件操作。 例如,也许一些文件应该由用户的浏览器缓存比其他文件更长的时间,或者网站的一些部分应该只允许通过安全连接(像任何需要用户的密码),而网站的其他部分, t。
另一个简单的常见示例是确保当发布新网页而不是旧网页时,所有旧地址都将重定向到正确的位置。 这是有用的,因为它意味着旧的链接和书签不会停止工作,它还保留了Google的缓存。
Nginx的映射模块允许您在Nginx的配置文件中创建变量,其值是有条件的 - 也就是说,它们依赖于其他变量的值。 在本指南中,我们将了解如何使用Nginx的map模块实现两个示例:如何设置从旧网站网址到新网址的重定向列表以及如何创建国家/地区白名单以控制您网站的流量。
先决条件
要遵循本教程,您需要:
其中7 CentOS的服务器设置与初始服务器设置教程 ,包括Sudo非root用户。
遵循您的服务器上安装的Nginx 如何在CentOS 7教程安装Nginx的 。
第1步 - 创建和测试示例页面
首先,我们将创建一个表示新发布的网站的测试文件。 我们将使用此文件来测试我们的配置。
让我们创建一个简单的页面, index.html
,在默认Nginx的网站目录。 这个文件将只有简单的文本描述内容:首页。
sudo sh -c 'echo "Home" > /usr/share/nginx/html/index.html'
有了这个测试文件,接下来我们会检查它被正确送达curl
。 我们不需要指定index.html
,因为该文件默认情况下,如果供应没有提供确切的文件名此命令。
curl http://localhost/
作为回应,你应该看到一个字说家就像如下:
Home
现在,让我们尝试访问一个文件中不存在/usr/share/nginx/html
,像old.html
。
curl -L http://localhost/old.html
响应将是一个系统错误消息,404未找到 ,这意味着页面不存在。
<!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索引,打印或写下,或通过任何其他方式共享。
在下一个步骤中,我们将使用map模块,以确保此旧地址将通过自动将观看者重定向到新替换来重新工作。
第2步 - 配置重定向
对于小网站只有几页纸,简单的if
条件语句可用于重定向和类似的事情。 然而,随着条件列表变得更长,这种配置不容易维持或者长期地延长。
map模块是一个更优雅,简洁的解决方案。 它允许您将Nginx变量值与条件列表进行比较,然后根据匹配将新值与变量关联。 在此示例中,我们将比较请求的网址与我们要重定向到新网站的旧网页列表。 对于每个旧地址,我们将关联新的地址。
映射模块是一个核心的Nginx模块,这意味着它不需要单独安装使用。 要建立必要的地图和重定向配置,在打开默认的服务器块Nginx的配置文件vi
(这里有一个简短的介绍vi
),或者你最喜欢的文本编辑器。
sudo vi /etc/nginx/nginx.conf
找到server
配置块,它看起来像这样:
. . .
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .
我们将添加两个新节:一个前server
块,和一个里面。
在之前的部分server
模块是一个新map
模块,它定义了旧的网址,并使用map模块新一之间的映射。 内部的部分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地址,然后确定它在大括号的条件清单。 条件列表中的每个项目都有两个部分:要匹配的值,以及如果匹配则为变量分配的新值。
行/old.html /index.html
内侧map
块意味着,如果$uri
的值是/old.html
, $new_uri
将改为/index.html
。 如果不匹配,则不会更改。 在这里,我们只定义一个条件,但您可以在地图中定义任意多个条件。
然后,使用一个条件if
语句里面server
块,我们检查$new_uri
变量的值设置。 如果是,则意味着地图中的条件很满意,我们应该使用重定向到新的网站rewrite
命令。 该permanent
关键字确保重定向将迁往永久 HTTP重定向301,这意味着旧的地址不再有效,并且不会重新联机。
保存并关闭文件退出。
要启用新配置,请重新启动Nginx。
sudo systemctl restart nginx
要测试新配置,请执行与之前相同的请求:
curl -L http://localhost/old.html
这时候会出现在输出中没有404 Not Found错误。 相反,您会看到我们在第1步中创建的简单主页。
Home
这意味着地图已正确配置,您可以通过向地图中添加更多条目来使用它重定向网址。
重定向URL是map模块的一个有用的应用程序。 另一个,我们将在下一步中探讨,基于访问者的地理位置过滤流量。
第3步 - 限制网站访问某些国家/地区
有时,服务器可能会收到过多的自动化,恶意请求。 这可能是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
找到server
的配置块,在第1步和2的修改后,看起来是这样的:
. . .
# 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
模块,它定义了默认的动作(禁止访问),以及允许访问该网站的国家代码列表。 里面的部分server
,如果该块拒绝访问的网站map
的结果是这么说的。
. . .
# 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连接关闭无反应 ,而不是服务于实际的网站。
要启用新配置,请重新启动Nginx。
sudo systemctl restart nginx
如果没有你的国家加入白名单,当您尝试访问http:// your_server_ip
,你会看到如下页面的错误信息不工作或页面没有发送任何数据 。 如果您所在的国家加入白名单,你会看到首页和以前一样。
结论
虽然它可能是一个非常简单的示例如何使用map模块,它显示了可以以许多其他不同的方式使用的机制。 映射模块不仅允许简单的比较,而且还支持允许更复杂匹配的正则表达式。 如果必须评估多个条件,这是一个伟大的方式使配置文件更清洁。
另一个非常受欢迎的map模块的用例是在非SSL环境中的网站的安全部分的条件重定向。 仅为需要密码输入的表单设置强制SSL连接是一个很好的例子,如何在现实世界的场景中应用map模块,我鼓励尝试这样的设置。
更详细的信息,可以发现Nginx的官方map模块文档中 。