【NGINX--6】安全控制--1

1、基于 IP 地址的访问

根据客户端的 IP 地址控制访问。

使用 HTTP 或 stream 访问模块控制对受保护资源的访问:

location /admin/ { deny 10.0.0.1; allow 10.0.0.0/20;allow 2001:0db8::/32; deny all;
}

给定的 location 代码块允许来自 10.0.0.0/20 中的任何 IPv4 地址访问(10.0.0.1 除外),允许来自 2001:0db8::/32 子网中的 IPv6 地址访问,并在收到来自其他任何地址的请求后返回 403。allow 和 deny 指令在 http、server 和 location 上下文以及 TCP/UDP 的 stream、server 上下文中有效。按顺序检查规则,直到找到与远程地址匹配的规则为止。
详解
互联网上的宝贵资源和服务必须要进行多层保护,NGINX 就是其中一层的安全卫士。deny 指令可阻止对给定上下文的访问,而 allow 指令可用来允许被阻止访问的子集。您可以使用 IP 地址、IPv4 或 IPv6、无类别域间路由(CIDR)块范围,关键字 all 和Unix 套接字。在保护资源时,通常会允许一个内部 IP 地址块,并拒绝所有访问请求。

2、允许跨域资源共享

您提供了来自另一个域的资源,需要允许跨域资源共享(CORS),以便浏览器能够利用这些资源。

根据 request 方法更改请求头,启用 CORS:

map $request_method $cors_method {OPTIONS 11;GET 1;POST 1;default 0;
}
server {# ...location / {if ($cors_method ~ '1') {add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';add_header 'Access-Control-Allow-Origin' '*.example.com';add_header 'Access-Control-Allow-Headers' 'DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';}if ($cors_method = '11') {add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=UTF-8';add_header 'Content-Length' 0;return 204;}}
}

这个示例中的内容很多,但通过使用 map 将 GET 和 POST 方法进行分组,简化了示例中的内容。OPTIONS 请求方法向客户端返回有关该服务器 CORS 规则的 preflight 请求。在 CORS 下允许使用 OPTIONS、GET 和 POST 方法。设置 Access-ControlAllow-Origin 标头,允许该服务器提供的内容也可以在与此请求头匹配的原始页面上使用。preflight 请求可以在客户端缓存 1,728,000 秒,相当于 20 天。
详解
当 JavaScript 等资源所请求的资源属于其他域时,就会发生 CORS。当请求被视为跨域的时候,浏览器就要遵守 CORS 规则。如果浏览器没有专门允许其使用资源的请求头,那么它将不会使用该资源。为了允许其他子域使用我们的资源,我们必须设置CORS 请求头,这可通过 add_header 指令完成。如果请求方法是具有标准内容类型的 GET、HEAD 或 POST,并且没有特殊的请求头,则浏览器将发出请求并且只检查来源。其他请求方法将导致浏览器发出 preflight 请求,以检查它将遵守的关于该资源的服务器条款。如果您没有正确设置这些请求头,那么浏览器会在尝试利用这些资源时出错。

3、客户端加密

在 NGINX 服务器和客户端之间加密流量。

使用一个 SSL 模块加密流量,例如 ngx_http_ssl_module 或 ngx_stream_ssl_module:

http{ # All directives used below are also valid in stream server {listen 8443 ssl;ssl_certificate /etc/nginx/ssl/example.crt; ssl_certificate_key /etc/nginx/ssl/example.key;}
}

此配置将服务器设置为侦听使用 SSL/TLS 加密的端口 8443。指令 ssl_certificate 定义了提供给客户端的证书和可选的证书链。ssl_certificate_key 指令定义了 NGINX 用来解密请求和加密响应的密钥。许多 SSL/TLS 协商配置默认为 NGINX 版本的缺省配置。
详解
安全传输层是最常见的加密传输中信息的方法。截至本文撰写之时,TLS 协议比 SSL 协议更受欢迎。这是因为现在人们认为 SSL 版本 1 至 3 不安全。尽管协议名称可能不同,但 TLS 仍然建立了安全套接字层。NGINX 能够让您的服务保护您和客户端之间的信息,进而保护客户端和您的业务。在使用 CA 签名的证书时,需要将证书与证书颁发机构链连接起来。在连接证书和证书颁发机构链时,证书应位于证书颁发机构链文件之上。如果证书颁发机构提供了多个文件作为证书颁发机构链的中间证书,则它们会按顺序进行分层。有关排序问题,请参阅证书提供商的文档。
参考资料
Mozilla SSL 配置生成器
SSL Labs 的 SSL 服务器测试

4、高级客户端加密

具有高级客户端-服务器加密配置需求。

NGINX 的 http 和 stream 模块可完全控制接受的 SSL/TLS 握手。证书和密钥可通过文件路径或可变值的方式提供给 NGINX。NGINX 根据其配置为客户端提供可接受的协议、密码和密钥类型列表。客户端与 NGINX 服务器之间的最高标准是经过协商的。NGINX 可以将客户端-服务器 SSL/TLS 的协商结果缓存一段时间。
下面的示例同时展示了许多选项,意在说明客户端-服务器协商的复杂性:

http { # All directives used below are also valid in stream server {listen 8443 ssl;# Set accepted protocol and cipherssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers HIGH:!aNULL:!MD5;# RSA certificate chain loaded from filessl_certificate /etc/nginx/ssl/example.crt;# RSA encryption key loaded from filessl_certificate_key /etc/nginx/ssl/example.pem;# Elliptic curve cert from variable valuessl_certificate $ecdsa_cert;# Elliptic curve key as file path variablessl_certificate_key data:$ecdsa_key_path;# Client-Server negotiation cachingssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;}
}

服务器接受 SSL 协议版本 TLSv1.2 和 TLSv1.3。接受的密码设置为 HIGH,这是最高标准的宏;对于 aNULL 和 MD5,显式拒绝是通过 ! 符号来表示的。使用了两组证书密钥对。传递给 NGINX 指令的值展示了提供 NGINX 证书密钥值的不同方式。变量被解释为文件的途径。当带有前缀 data: 时,变量值被解释为直接值。可提供多种证书密钥格式,以实现与客户端的反向兼容性。客户端支持的、服务器接受的最强标准将是协商的结果。

如果 SSL/TLS 密钥作为直接值变量暴露,则有可能会被配置记录或暴露。如果将密钥值暴露为变量,请确保您拥有严格的变更和访问控制措施。

SSL 会话缓存和超时允许 NGINX worker 进程在给定的时间内缓存和存储会话参数。作为单个实例化中的进程,NGINX worker 进程会相互共享此缓存(而非在机器之间共享)。还有许多其他会话缓存选项可以帮助提高所有类型的用例的性能或安全性。您可以结合使用不同的会话缓存选项。但是,指定没有默认值的缓存选项后,默认的内置会话缓存将会关闭。
详解
在上面的高级配置示例中,NGINX 为客户端提供了备受推重的密码算法 —— TLS 版本1.2 或 1.3 的 SSL/TLS 选项,以及使用 RSA 或椭圆曲线密码(ECC)格式密钥的能力。客户端所能实现的最强协议、密码和关键格式是协商的结果。该配置指示 NGINX 将协商结果缓存 10 分钟,可用内存分配为 10MB。

测试发现,ECC 证书的速度比同等强度的 RSA 证书快。密钥占用空间较小,可以提供更多的 SSL/TLS 连接及更快的握手速度。NGINX 允许您配置多个证书和密钥,然后为客户端浏览器提供最佳证书。您可以利用更新的技术,但仍然服务旧客户端。在此示例中,NGINX 正在加密它与客户端之间的流量。但是,与上游(upstream)服务器的连接也可能进行了加密。在本文第五章Upstream 加密中演示了 NGINX 与上游服务器之间的协商。
参考资料
Mozilla SSL 配置生成器
SSL Labs 的 SSL 服务器测试

5、Upstream 加密

需要加密 NGINX 和上游服务之间的流量,并为合规性法规设置特定的协商规则;或者上游(upstream)服务位于有安全防护措施的网络之外。

使用 HTTP 代理模块的 SSL 指令来指定 SSL 规则:

location / {proxy_pass https://upstream.example.com; proxy_ssl_verify on; proxy_ssl_verify_depth 2; proxy_ssl_protocols TLSv1.2;
}

这些代理指令为 NGINX 设定了需要遵守的特定 SSL 规则。配置的指令可确保 NGINX 验证上游服务上的证书和证书链是否有效,验证深度最多为两个证书。proxy_ssl_protocols 指令指定 NGINX 只使用 TLS 版本 1.2。默认情况下,NGINX 不会验证上游证书并接受所有 TLS 版本。
详解
HTTP 代理模块的配置指令非常庞大,如果您需要加密上游流量,那么至少应该启用验证。您只需更改传递给 proxy_pass 指令的值对应的协议,即可通过 HTTPS 进行代理。但是,这不会验证上游证书。其他指令(如 proxy_ssl_certificate 和 proxy_ssl_ssl_certificate_key)允许您锁定上游加密,以增强安全性。您还可以指定 proxy_ssl_crl 或证书吊销列表,该列表列出了被认为无效的证书。这些 SSL 代理指令有助于增强系统在自己的网络或跨公共互联网的通信通道。

6、保护位置

使用 secret 保护 location 代码块。

通过 secure link 模块和 secure_link_secret 指令,仅允许拥有安全链接的用户访问
资源:

location /resources {secure_link_secret mySecret;if ($secure_link = "") { return 403; }rewrite ^ /secured/$secure_link;}location /secured/ {internal;root /var/www;}

这种配置创建了一个内部和公共 location 代码块。请求 URI 需包含 md5 哈希字符串(可通过提供给 secure_link_secret 指令的 secret 进行验证),否则公共 location 代码块 /resources 将返回 403 Forbidden。URI 中的哈希值需进行验证,否则 $ secure_link 变量将是一个空字符串。
详解
使用 secret 保护资源是一种有效的文件保护方法。结合使用 secret 与 URI,然后对该字符串进行 md5 哈希计算,并在 URI 中使用这个 md5 哈希算法的十六进制摘要。将哈希值放置在链接中,并通过 NGINX 进行评估。NGINX 知道要请求的文件的路径,因为它位于哈希算法之后的 URI 中。NGINX 还知道您的 secret,因为它通过secure_link_secret 指令提供。NGINX 能够快速验证 md5 哈希算法,并将 URI 存储在$secure_link 变量中。如果无法验证哈希值,则将变量设置为空字符串。需要注意的是,传递给 secure_link_secret 的参数必须是静态字符串,不能是变量。

7、使用 secret 生成安全链接

需要使用 secret 从应用中生成安全链接。

NGINX 中的 secure link 模块接受 md5 哈希字符串的十六进制摘要,其中字符串由URI 路径和 secret 组成。在上一节的6、保护位置基础上,我们将创建一个安全链接,

 location /resources {secure_link_secret mySecret;if ($secure_link = "") { return 403; }rewrite ^ /secured/$secure_link;}location /secured/ {internal;root /var/www;}

与前面的配置示例搭配使用,因为 /var/www/secured/index.html 上有一个文件。要生成 md5 哈希算法的十六进制接要,我们可以使用 Unix openssl 命令:

$ echo -n 'index.htmlmySecret' | openssl md5 -hex 
(stdin)= a53bee08a4bf0bbea978ddf736363a12

此处展示了我们要保护的 URI index.html,它与我们的 secret mySecret 拼接在一起。该字符串被传递到 openssl 命令,输出 md5 十六进制摘要。

下面是使用 Python Standard Library 中包含的 hashlib 库在 Python 中生成相同哈希摘
要的示例:

import hashlib
hashlib.md5.(b'index.htmlmySecret').hexdigest()
'a53bee08a4bf0bbea978ddf736363a12'

现在我们得到了这个哈希摘要,并可以在 URL 中使用它了。我们的示例是 www.example.com 通过我们的 /resources 位置请求 /var/www/secured/index.html 上的文
件。我们的完整 URL 将是:

www.example.com/resources/a53bee08a4bf0bbea978ddf736363a12/index.html

详解
我们可以通过多种方式,用多种语言生成哈希摘要。请记住:URI 路径在 secret 之前;字符串中没有回车;使用 md5 哈希算法的十六进制摘要。

8、保护过期的位置

需要保护一个位置,该位置的链接将在未来某个时间过期,并且特定于某个客户端。

利用 secure link 模块中的其他指令设置过期时间,并在 secure link 中使用变量:

location /resources { root /var/www;secure_link $arg_md5,$arg_expires;secure_link_md5 "$secure_link_expires$uri$remote_addrmySecret"; if ($secure_link = "") { return 403; }if ($secure_link = "0") { return 410; }}

secure_link 指令带两个参数,这两个参数用两个逗号隔开。第一个参数是保存 md5 哈希值的变量。本例中使用了 md5 的 HTTP 参数。第二个参数是一个变量,该变量保存了以 Unix 时间戳格式显示的链接过期时间。secure_link_md5 指令带一个参数,该参数声明了用于生成 md5 哈希值的字符串的格式。与其他配置一样,如果哈希值未经验证,则 $secure_link 变量将设置为空字符串。但是,使用这种用法,如果哈希值匹配,但时间已过期,则 $secure_link 变量将设置为 0。
详解
这种保护链接的用法比上上章节6、保护位置 中所示的 secure_link_secret 更灵活、更简洁。通过这些指令,您可以在哈希字符串中使用 NGINX 可用的任意数量的变量。在哈希字符串中使用特定于用户的变量可增强安全性,因为用户无法交换到受保护资源的链接。建议使用类似于 $remote_addr 或 $http_x_forwarded_for 的变量,或者由应用生成的会话 cookie 请求头。secure_link 的参数可以来自您喜欢的任何变量,并且能够以最合适的方式命名。问题是:您拥有访问权限吗?您是否在链接有效期内访问?如果您没有访问权限,将会收到消息 Forbidden。如果您拥有访问权限,但链接却过期了,将会收到消息 Gone。HTTP 410 Gone 非常适合过期的链接,因为该条件应被视为永久性的。

9、生成过期链接

需要生成一个过期的链接。

为过期的时间生成一个 Unix 时间戳格式的时间戳。在 Unix 系统上,您可以使用如下所示的日期进行测试:

$ date -d "2030-12-31 00:00" +%s --utc 
1924905600

接下来,您需要连接哈希字符串,以匹配使用 secure_link_md5 指令配置的字符串。在本例中,我们要使用的字符串将是 1924905600/resources/index.html127.0.0.1 mySecret。md5 哈希值与十六进制摘要稍有不同。它是二进制格式的 md5 哈希值,base64 编码,加号(+)转换成了连字符(-),斜杠(/)转换成了下划线(_),删除了等号(=)。以下是在 Unix 系统上操作的一个示例:

$ echo -n '1924905600/resources/index.html127.0.0.1 mySecret' \| openssl md5 -binary \| openssl base64 \| tr +/ -_ \| tr -d = 
sqysOw5kMvQBL3j9ODCyoQ

现在我们得到了哈希值,我们可以将它和过期日期用作参数:/resources/index.html?md5=sqysOw5kMvQBL3j9ODCyoQ&expires=1924905600下面是 Python 中使用相对过期时间的更实际的示例,它将链接设置为生成后一小时过期。在撰写本文之时,此示例适用于 Python 2.7 和使用 Python 标准库的 3.x:

   from datetime import datetime, timedeltafrom base64 import b64encodeimport hashlib# 设置环境变量resource = b'/resources/index.html'remote_addr = b'127.0.0.1'host = b'www.example.com'mysecret = b'mySecret'# 生成过期时间戳now = datetime.utcnow()expire_dt = now + timedelta(hours=1)expire_epoch = str.encode(expire_dt.strftime('%s'))# 计算字符串的 md5 哈希值uncoded = expire_epoch + resource + remote_addr + mysecretmd5hashed = hashlib.md5(uncoded).digest()# 对字符串进行 base64 编码和转换b64 = b64encode(md5hashed)unpadded_b64url = b64.replace(b'+', b'-')\.replace(b'/', b'_')\.replace(b'=', b'')# 格式化并生成链接linkformat = "{}{}?md5={}?expires={}"securelink = linkformat.format(host.decode(),resource.decode(),unpadded_b64url.decode(),expire_epoch.decode())print(securelink)

详解
有了这种模式,我们能够生成具有特殊格式并能在 URL 中使用的安全链接。secret 通过使用从未发送给客户端的变量来提供安全性。您可以使用尽可能多的其他变量来保护位置的安全。md5 哈希计算和 base64 编码是通用的、轻量级的,并且支持几乎任何语言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/172575.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos 查看磁盘分区的文件系统类型

1 lsblk -f 这个命令是查看系统可以识别出的所有分区的文件系统类型 # lsblk -f NAME FSTYPE LABEL UUID MOUNTPOINT vda └─vda1 ext4 8c02a225-e14c-44a9-a9d8-4b60c4b…

百面深度学习-自然语言处理

自然语言处理 神经机器翻译模型经历了哪些主要的结构变化?分别解决了哪些问题? 神经机器翻译(Neural Machine Translation, NMT)是一种使用深度学习技术来实现自动翻译的方法。自从提出以来,NMT模型经历了几个重要的…

#Js篇:Promise

定义 Promise是异步操作解决方案,为异步操作提供统一接口。 Promise英文意思是“承诺”,表示其他手段无法改变。 返回 所有异步任务都返回一个Promise实例。 Promise实例有一个then方法,用于指定下一步的回调函数。 状态 异步操作未完…

一个简易的URL爬虫程序(java)

该程序是一个简单的Java程序,用于从指定的URL中获取网页内容并保存到本地文件。通过URL类打开指定的URL链接,并使用openStream()方法获取输入流。然后使用Scanner类读取输入流中的内容,并使用PrintWriter类将读取到的内容写入到本地文件中。 …

HTTP协议发展

HTTP 1.0 -> HTTP 1.1 -> HTTP 2.0 -> HTTP 3.0 (QUIC) 每一代HTTP解决了什么问题? 下图说明了主要功能。 HTTP 1.0 于 1996 年最终确定并完整记录。对同一服务器的每个请求都需要单独的 TCP 连接。 HTTP 1.1 于 1997 年发布。TCP 连接可以保持打开状态…

php使用Session实现简单购物车功能

一个简单的商城购物车功能。它使用了PHP的会话(Session)来存储购物车数据,通过调用不同的函数来实现添加商品、移除商品、更新商品数量以及清空购物车的功能 session_start();// 初始化购物车 if (!isset($_SESSION[cart])) {$_SESSION[cart] array(); }// 添加商品…

openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态

文章目录 openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态132.1 背景信息132.2 前提条件132.3 操作步骤132.4 参数说明132.5 示例 openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态 132.1 背景信息 openGauss支持查看整个openGauss的状态&#…

如何在Linux系统安装Nginx并启动

Nginx的介绍 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好。官网:nginx newsNginx的下载 前往…

docker基础学习笔记

文章目录 Docker简介Linux下安装DockerDocker常用命令Docker网络Docker存储docker-composedockerfile制作镜像私有仓库镜像导入导出参考 Docker简介 定义:Docker是一个开源的应用容器引擎优势: 一键部署,开箱即用:容器使用基于im…

Qt5.15.2静态编译 VS2017 with static OpenSSL

几年前编译过一次Qt静态库:VS2015编译Qt5.7.0生成支持XP的静态库,再次编译,毫无压力。 一.环境 系统:Windows 10 专业版 64位 编译器:visual studio 2017 第三方工具:perl,ruby和python python用最新的3.x.x版本也是可以的 这三个工具都需要添加到环境变量,安装时勾选…

057-第三代软件开发-文件监视器

第三代软件开发-文件监视器 文章目录 第三代软件开发-文件监视器项目介绍文件监视器实现原理关于 QFileSystemWatcher实现代码 关键字: Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML&…

在使用微信或者支付宝支付的时候,为什么微信支付或者支付宝支付的异步通知商户支付结果要进行验签?

在使用微信支付或支付宝支付等第三方支付平台时,异步通知是一种常见的机制,用于通知商户支付结果或交易状态的变化。验签(Signature Verification)是为了确保异步通知的安全性和完整性而进行的重要步骤。以下是为什么要进行验签的…

人工智能时代的内容写作

内容不再只是王道,正如俗话所说:它是一种流动的货币,推动了巨大的在线信息和影响力经济。 每个品牌都是一个故事,通过其服务和商品讲述自己。尽管如此,大多数客户还是会通过您的在线内容最了解您。 但随着我们进入人…

每日一题:LeetCode-LCR 143.子结构判断

每日一题系列(day 05) 前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &#x1f50e…

汇编:关于栈的知识

1.入栈和出栈指令 2. SS与SP 3. 入栈与出栈 3.1 执行push ax ↑↑ 3.2 执行pop ax ↓↓ 3.3 栈顶超界的问题 4. 寄存器赋值 基于8086CPU编程时,可以将一段内存当作栈来使用。一个栈段最大可以设为64KB(0-FFFFH)。 1.入栈和出栈指令…

C语言——函数

导读 : 这篇文章主要讲解一下C语言函数的一些基本知识。 前言:函数的概念 C语言中的函数又常常被称为子程序,是用来完成某项特定的工作的一段代码。就像我们生活中的模块化建造技术,类比模块化建房子的过程:整个程序…

高校大学校园后勤移动报修系统 微信小程序uniapp+vue

本文主要是针对线下校园后勤移动报修传统管理方式中管理不便与效率低的缺点,将电子商务和计算机技术结合起来,开发出管理便捷,效率高的基于app的大学校园后勤移动报修app。该系统、操作简单、界面友好、易于管理和维护;而且对后勤…

3-Python与设计模式--简单工厂模式

2-Python与设计模式–简单工厂模式 一、快餐点餐系统 想必大家一定见过类似于麦当劳自助点餐台一类的点餐系统吧。在一个大的触摸显示屏上, 有三类可以选择的上餐品: 汉堡等主餐、小食、饮料。当我们选择好自己需要的食物,支付完成后&#…

Python中类的定义和使用细讲

文章目录 前言一、定义类二、创建类的实例三、创建 _ _ init _ _() 方法四、创建类的成员并访问1. 创建实例方法并访问2. 创建数据成员并访问 五、访问限制 前言 在 Python 中,类表示具有相同属性和方法的对象的集合。在使用类时,需要先定义类&#xff0…

expdp及impdp中的exclude及include参数

expdp 及imdpd命令中,exclude及include参数还是有一些要注意的地方,特别是涉及选择性条件时。 一、通用 1、exclude及include参数不能同时使用,这两个是相互排斥的。 2、在parfile参数文件中,可以同时用多个exclude参数&#xf…