如何在Ubuntu 16.04上使用Nginx的地图模块
介绍
为网站配置服务器时,可能需要执行一些常见的条件操作。例如,某些文件可能会被用户的浏览器缓存比其他文件更长,或者网站的某些部分应该只允许通过安全连接(例如需要用户密码的任何内容),而网站的其他部分则不应该吨。
另一个简单的常见示例是确保在发布新网页而不是旧网页时,所有旧地址都将重定向到正确的位置。这很有用,因为它意味着旧的链接和书签不会停止工作,它也会保留Google的缓存。
Nginx的地图模块允许您在Nginx的配置文件中创建变量,其值是有条件的 - 也就是说,它们依赖于其他变量的值。在本指南中,我们将了解如何使用Nginx的地图模块实现两个示例:如何设置从旧网站网址到新网站的重定向列表,以及如何创建国家/地区的白名单来控制您网站的流量。
准备
要学习本教程,您需要:
- 一个Ubuntu 16.04服务器,包括一个sudo非root用户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。
- 按照如何在Ubuntu 16.04上安装Nginx,在服务器上安装Nginx。
第1步 - 创建和测试示例网页
首先,我们将创建一个代表新发布网站的测试文件。我们将使用此文件来测试我们的配置。
让我们在默认的Nginx网站目录中创建一个简单的页面index.html
。这个文件只有简单的文字描述里面的内容:主页。
sudo sh -c 'echo "Home" > /var/www/html/index.html'
有了这个测试文件,接下来我们将用 curl
检查它是否正确使用。我们不需要index.html
来为此命令指定,因为如果没有提供确切的文件名,则默认提供该文件。
curl http://localhost/
作为回应,你应该会看到一个字说家就像如下:
Home
现在让我们尝试访问一个/var/www/html/
中不存在的文件,比如old.html
。
curl -L http://localhost/old.html
响应将是系统错误消息,404 Not Found,表示该页面不存在。
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.0 (Ubuntu)</center>
</body>
</html>
我们在本教程中只是使用虚拟网站,但如果old.html
是真实网站上曾经存在并被删除的页面,则返回404将意味着该页面的所有链接都被破坏。这不太理想,因为这些链接可能已被Google编入索引,打印或记录,或通过任何其他方式共享。
在下一步中,我们将利用地图模块通过将查看器自动重定向到新的替换来确保此旧地址再次起作用。
第2步 - 配置重定向
对于只有几页的小型网站,简单的if
条件语句可用于重定向和类似的事情。然而,随着条件列表变长,这种配置从长远来看不易维护或扩展。
地图模块是一个更优雅,简洁的解决方案。它允许您将Nginx变量值与条件列表进行比较,然后根据匹配将新值与变量相关联。在此示例中,我们将比较请求的URL与我们要重定向到新对应的旧页面列表。对于每个旧地址,我们将关联新地址。
映射模块是核心Nginx模块,这意味着它不需要单独安装即可使用。要创建必要的映射和重定向配置,请用nano
或你喜欢的文本编辑器中打开默认服务器块Nginx配置文件。
sudo nano /etc/nginx/sites-available/default
找到server
配置块,如下所示:
. . .
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .
我们将添加两个新部分:一个在server
块之前,一个在其中。
server
块前面的部分是一个新map
块,它使用map模块定义旧URL和新URL之间的映射。server
块内的部分是重定向。
. . .
# Default server configuration
#
# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# 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
。如果不匹配,则不会更改。在这里,我们只定义一个条件,但您可以在地图中定义任意数量的条件。
然后,使用server
块内的另外的if
条件语句,检查$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是地图模块的一个有用的应用程序。另一个,我们将在下一步探讨,根据访问者的地理位置过滤流量。
第3步 - 限制网站访问某些国家/地区
有时,服务器可能会收到过多的自动恶意请求。这可能是DDoS攻击,企图对网站管理面板强制密码,或试图利用软件中的已知漏洞攻击网站并使用它来发送垃圾邮件或修改网站内容。
此类自动攻击可能来自许多不同国家/地区的许多不同分布式服务器,因此很难阻止。减轻此类攻击影响的一种解决方案是创建可以访问该网站的国家/地区的白名单。
这不是一个完美的解决方案,但在根据访问者的地理位置限制访问网站是一个明智的选择并且不限制网站的受众的情况下,该解决方案具有快速且不易出错的优点。
在服务器级别进行过滤比在网站级别进行过滤更快,并且还涵盖所有请求(包括静态文件,如图像)。这种过滤也可以防止请求到达网站软件,这使得漏洞更难以利用。
要使用地理过滤,我们首先创建一个新的配置文件。
sudo nano /etc/nginx/conf.d/geoip.conf
将以下内容粘贴到文件中。这告诉Nginx在哪里可以找到包含访问者IP地址与其各自国家/地区之间映射的GeoIP数据库。此数据库预装了Ubuntu 16.04。
. . .
# GeoIP database path
#
geoip_country /usr/share/GeoIP/GeoIP.dat;
下一步是创建必要的映射和限制配置。打开默认服务器块Nginx配置。
sudo nano /etc/nginx/sites-available/default
找到server
配置块,在步骤1和2中的修改后,如下所示:
. . .
# Default server configuration
#
# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
# Old website redirect
if ($new_uri) {
rewrite ^ $new_uri permanent;
}
. . .
我们将添加两个新部分:一个在server
块之前,一个在其中。
server
块前面的部分是一个新map
块,它定义了默认操作(不允许访问)以及允许访问网站的国家/地区代码列表。如果map
结果如此,则server
块内的部分拒绝访问网站。
. . .
# Default server configuration
#
# 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的官方地图模块文档中找到。
想要了解更多关于使用Nginx的地图模块的相关教程,请前往腾讯云+社区学习更多知识。
参考文献:《How to Use Nginx's map Module on Ubuntu 16.04》
- AI造的AI,比人造的还厉害,该喜还是该忧?
- Mono 3.2 测试NPinyin 中文转换拼音代码
- Reactive Extensions介绍
- Reactive Extensions(Rx) 学习
- 发布一个日期选择控件(ASPNET2.0)
- 做程序员压力山大,很多人都快疯了
- 小程序让交通出行变得如此简化,看看这些微信小程序你有在用了吗?
- 中小企业如何选择DDoS防御方案?
- “熊医生”出诊正确率超九成 医院:人工智能更多是辅助
- PLC编程优化方法,让程序运行提速!
- 这是硅谷狂人马斯克对未来做出的11个大胆预测,人工智能比核武器更危险
- 在腾讯云上使用自建DNS
- Spring 4.0.2 学习笔记(1) - 最基本的注入
- 关于女神SQLite的疑惑(2)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- codeforces 1420C1
- codeforces 1417D(思维,构造)
- Servlet基础入门学习2
- codeforces 1426D(思维)
- codeforces 1324E(dp)
- OpenCV4.4 CUDA编译与加速全解析
- codeforces 1077D(二分)
- codeforces 1077F1(dp)
- Servlet基础入门学习1
- Lombok,你的开发效率神器!
- codeforces 1272E(反向建边+多源bfs)
- Tomcat在Java开发中的使用笔记
- codeforces 1423K(数学+差分数组预处理)
- 基于Quartz的定时任务及crond表达式入门学习
- Flutter 渲染引擎详解 - iOS GL 篇