这篇Nginx安全加固文章,我们将讨论如何让Nginx变得更安全
SSL加固
尽管你的网站被配置为只处理HTTPS流量,但它仍然允许客户端尝试进一步的HTTP连接。在服务器响应中添加Strict-Transport-Security头将确保所有未来的连接都执行HTTPS。
打开Nginx的主配置文件。
sudo nano /etc/nginx/nginx.conf
在http块中添加以下代码
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
你可能想知道,如果这个标头自动执行HTTPS流量,为什么还需要301重定向:不幸的是,IE10及以下版本不支持这个标头。
测试一下你的Nginx配置,如果没有问题,重新加载。
sudo nginx -t
sudo service nginx reload
现在,如果你使用Qualys SSL测试工具进行扫描,你应该得到一个A+的等级。
SSL性能
HTTPS连接比普通HTTP连接更耗费资源。这是由于建立连接时需要额外的握手程序。然而,可以对SSL会话参数进行缓存,这将完全避免后续连接的SSL握手过程。
打开Nginx的主配置文件。
sudo nano /etc/nginx/nginx.conf
在http块中添加以下代码
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
测试Nginx的配置,如果成功则重新加载。
sudo nginx -t
sudo service nginx reload
跨站脚本(XSS)
处理XSS的最有效的方法是确保你正确地验证和净化你的代码中的所有用户输入,包括WordPress管理区域内的输入。但是,当你考虑第三方主题和插件时,大多数输入验证是你无法控制的。但是,你可以通过配置Nginx来提供一些额外的响应头来减少XSS攻击的风险。
让我们假设一个攻击者设法将一个恶意的JS文件嵌入到网站的源代码中,也许是通过一个评论表单或类似的东西。默认情况下,浏览器会在不知情的情况下加载这个外部文件并允许其内容执行。进入内容安全策略,它允许你定义一个被批准加载资产(JS、CSS等)的来源白名单。如果脚本不在批准的名单上,它就不会被加载。
创建一个内容安全策略可能需要一些尝试和错误,因为你需要小心不要阻止应该被加载的资产,如谷歌或其他第三方供应商。这个样本政策将允许当前的域名和一些来自谷歌和WordPress.org的资源。
default-src 'self' https://*.google-analytics.com https://*.googleapis.com https://*.gstatic.com https://*.gravatar.com https://*.w.org data: 'unsafe-inline' 'unsafe-eval';
另外,有些人选择只封锁非HTTPS资产,虽然安全性较差,但管理起来却容易得多。
default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';
你可以把这个指令添加到nginx.conf或每个站点的单独配置文件中,这取决于你是否想在所有站点之间共享策略。就我个人而言,我在全局配置文件中指定一个通用策略,然后根据需要在每个站点上覆盖它。
sudo nano /etc/nginx/nginx.conf
在http块中添加以下代码。
##
# Security
##
add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';" always;
你们中的一些人可能已经发现,这只涉及到外部资源,但内联脚本呢?有两种方法可以处理这个问题。
- 通过从 “内容安全策略 “中删除 “无安全内联 “和 “无安全评价”,完全禁止内联脚本。然而,这种方法会破坏一些第三方插件或主题,所以要小心。
- 启用X-XSS保护,这将指示浏览器过滤用户输入,确保可疑代码不会直接输出到HTML。虽然不是无懈可击,但这是一个相对简单的应对措施,可以实现。
要启用X-Xss-Protection过滤器,请在 “内容-安全-政策 “条目下添加以下指令。
add_header X-Xss-Protection "1; mode=block" always;
这些头文件不能替代正确的验证或净化,但它们确实提供了另一道非常强大的防线,以防止常见的XSS攻击。只安装来自可信来源的高质量插件和主题是你最好的第一道防线。
点击劫持
点击劫持是一种欺骗用户执行他们无意的行动的攻击,通常是通过使用iframe实现的。特洛伊-亨特的一篇文章对点击劫持作了详尽的解释。
打击这种攻击媒介的最有效方法是完全禁用第三方域名的框架嵌入。要做到这一点,请在X-Xss-Protection标头下面添加以下指令。
add_header X-Frame-Options "SAMEORIGIN" always;
这将防止所有外部域通过使用iframe标签将你的网站直接嵌入他们的网站。
<iframe src="http://mydomain.com"</iframe>
MIME 嗅探
MIME嗅探可以使你的网站受到攻击,如 “偷渡式下载”。X-Content-Type-Options头通过确保只遵守服务器提供的MIME类型来对抗这种威胁。微软的一篇文章详细解释了MIME嗅探的情况。
要禁用MIME嗅探,请添加以下指令。
add_header X-Content-Type-Options "nosniff" always;
推荐人政策
Referrer-Policy头允许你控制当从你的网站上的页面导航时,哪些信息被包含在Referrer头中。虽然推荐人信息很有用,但在有些情况下,你可能不希望把完整的URL传递给目标服务器,例如,当导航离开私人内容时(想想会员网站)。
事实上,自从WordPress 4.9以来,任何来自WordPress仪表板的请求都会自动向任何外部目的地发送一个空白的referrer标头。这样做使得在导航离开你的网站时(从WordPress仪表板内)无法跟踪这些请求,这有助于防止通过不向外部域传递/wp-admin来广播你的网站在WordPress上运行的事实。
我们可以更进一步,限制我们网站上所有页面的referrer信息,而不仅仅是WordPress的仪表板。一个常见的方法是只把域名传给目标服务器,所以不要用:
https://myawesomesite.com/top-secret-url
目的地将收到。
https://myawesomesite.com
你可以使用下面的策略来实现这一点。
add_header Referrer-Policy "origin-when-cross-origin" always;
这就是所有建议的安全头的实现。在重新加载Nginx配置之前,确保没有任何语法错误,保存并关闭该文件。
sudo nginx -t
sudo service nginx reload