通过Nginx启用HTTP验证(HTTP Authentication)

在后台我经常可以看到有扫描器通过wp-login.php穷举密码登陆试图wordpress,也可以看到web应用方面的各种服务,我们始终无法防御各种各样未知的web漏洞,所以我想引入http验证是非常不错的一种手段。
通过http验证我们可以阻挡各种未经授权的访问以缓解各种漏洞。因为启用之后只有输入正确的用户密码才允许访问web内容。
首先配置HTTP认证我们需要创建认证账户密码文件。
我们可以通过openssl或者htapasswd来创建
方法1:htapasswd

方法2:使用openssl

创建了passwd文件(/etc/nginx/http_passwd)之后,我们需要修改Nginx的配置启用http验证。
Ubuntu上Nginx配置文件在/etc/nginx/sites-enabled 下面。
我们这里对应是/etc/nginx/sites-enabled/exvs
为需要保护的文件或者目录添加类似下面这样的内容

关于配置的详细信息可阅读Nginx文档:https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
最后重启Nginx
systemctl restart nginx
再次访问制定的文件或者目录则需要http验证了。

2017/01/15 记一次phpmyadmin的漏洞修复

这两天阿里云发短信提醒我的机器安装存在漏洞的phpmyadmin,上控制台一看提醒有这么个提示。

通过CVE编号CVE-2016-6617我找到了官方对于此漏洞的详细说明。
https://www.phpmyadmin.net/security/PMASA-2016-40/
官方给此漏洞的编号是:PMASA-2016-40
对此漏洞的描述是:A vulnerability was reported where a specially crafted database and/or table name can be used to trigger an SQL injection attack through the export functionality.
翻译过来就是,通过特殊的数据库,表名会导致使用导出功能的时候产生SQL注入的漏洞。
所有早于4.6.4之前的版本都会收到此漏洞影响。目前最新版4.6.5已经修复此漏洞,所以直接升级到最新版本的phpmyadmin即可。

值得注意的是,我使用的Ubuntu 16.04 LTS包版本库中提供的最新版是phpmyadmin_4.5.4.1-2ubuntu2,也就是说通过apt-get安装的phpmyadmin仍然存在此漏洞,直接apt-get upgrade并不能解决问题,这也是阿里云提示检测到漏洞的原因。

如果无法确定自己安装的包版本
可通过下列命令查询包版本

修复方案:
方案1:可以登陆phpmyadmin官网https://www.phpmyadmin.net下载最新版的包覆盖安装路径即可。
方案2:对于Ubuntu用户可以使用phpmyadmin官方提供的ppa源,这样就能直接更新到最新的包。
官方提供的安装手册链接:https://docs.phpmyadmin.net/en/latest/setup.html
具体到Ubuntu用户来说,可执行下列命令

由于我希望能尽量使用包管理器解决问题,这样能够长期保持最新版本,所以我选择了方案2。
至此phpmyadmin就更新完毕了。

Ubuntu 16.04.01 LTS 安装 Nginx PHP MYSQL环境

blog之前运行在Ubuntu 14.04上,虽然是LTS版本不过毕竟新的LTS版本16.04已经出来了这么久,得益于VPS供应商增加了16.04的镜像故找个时间把blog重新安装了一下,这里留下记录仅供参考。

之前服务器使用的apache,不过更新版本的时候考虑到http2的支持,所以服务器这次选择了nginx来作为web服务。
很多网站表示Ubuntu 16.04的nginx不支持http2需要手动编译,然而截止到目前为止仓库里最新的deb包已经默认支持http2。

那么直接apt-get一下安装nginx即可

然后安装mysql

可以运行一个mysql的安全设置向导mysql_secure_installation进行一些安全性配置。使用脚本可以做到,更改root密码、移除MySQL的匿名用户、禁止root远程登录、删除test数据库。使用上面的这些选项可以提高MySQL的安全。
由于blog的vps配置比较低,所以为了预防内存不足需要修改一下mysqld的配置。
修改/etc/mysql/mysql.conf.d/mysqld.cnf

最后安装php,Ubuntu 16.04默认已经是php7了,而不是php5,需要注意一下。

安装完成之后需要对nginx做一些配置。Ubuntu下面默认的配置目录是/etc/nginx/。
首先是/etc/nginx/nginx.conf
这里我修改了server_tokens选项为off
server_tokens的作用是隐藏Nginx的版本号,隐藏web服务的版本可以提高攻击难度,有利于提高安全性。

接着是/etc/nginx/sites-enabled,nginx启动时会读取目录下的所有配置。
我个人删除了/etc/nginx/sites-enabled/default
因为我个人的配置准备直接写在一个文件里,所以就没必要使用default了

出于安全性考虑,我选择全站强制https,所以80端口只需要做一些跳转工作就行了。配置如下。

80端口就只有一个作用,返回301跳转到https链接。关于几个常见的安全http头我们大致解释一下。
Strict-Transport-Security(HSTS)
一个网站接受一个HTTP的请求,然后跳转到HTTPS,用户可能在开始跳转前,通过没有加密的方式和服务器对话,比如,用户输入http://example.com,传统的做法是服务器返回301跳转到https://example.com。但是服务器返回301时并不是加密的,这将导致服务器返回的结果容易篡改,从而产生了劫持的现象。启用HSTS后,用户访问网站后浏览器会把网站加入HSTS列表,之后如果再次访问则强制https访问,从而尽可能的避免劫持的产生。
注意的是,一旦启用在参数时间内不能关闭https访问。
Content-Security-Policy
W3C的Content Security Policy,简称 CSP,CSP旨在减少跨站脚本攻击。这里我们配置为Content-Security-Policy: default-src ‘self’
这样可以阻止非本站的资源被浏览器加载,这样即使页面遭到篡改仍然不会加载非本站的元素。
X-Frame-Options
设置这个http头之后将会阻止浏览器通过FRAME加载你的网站页面。
X-XSS-Protection
设置此http头后,如果IE检测到了跨站脚本攻击(Cross-Site Scripting),那么IE将对页面做相应的修改以阻止攻击的发生。

80端口配置好了,那么剩下的就是配置443端口。HTTPS配置起来比较麻烦。
我们选择Nginx其中一个考虑是默认支持http2,启用http2很简单。
listen 443 ssl http2;
只要像这样配置端口即可。
出于安全性考虑,我选择放弃浏览器兼容。
SSLv2和SSLv3目前已经被证明是不安全的了,目前为止最新的TLS标准是1.2。所以我选择只支持TLS1.2。通过如下配置完成。
ssl_protocols TLSv1.2;
注意:只支持TLSv1.2代表着放弃很大部分老旧浏览器,他们将无法访问。
ssl_ciphers用来控制加密协议,放弃低强度的加密算法很显然有助于提高安全性。具体放弃或者应该启用什么样的算法我推荐直接参考https://cipherli.st
或者
https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_certificate
相信大家很熟悉了,TLS证书,我这里选择的是Let’s Encrypt的证书。个人推荐使用acme.sh签发证书。参见github的地址https://github.com/Neilpang/acme.sh
ssl_dhparam
通过DHE密钥,我们能获得更高的安全性.Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器,而且不能被中间人攻击所拦截。
我们可以通过openssl生成一个强DH密钥。

做完这些配置如下所示

之后我还需要安装phpmyadmin方便配置,一样通过apt-get就可以安装。

如果不安装php-zip那么在导入zip格式压缩后的sql数据是会提示“您正在载入不支持的压缩格式”
备注:由于Ubuntu源提供的包版本可能相对较phpmyadmin较为老旧,固推荐使用phpmyadmin官方提供的ppa源来保持更新。关于PPA源的有关信息可参见本站文章https://www.exvs.org/?p=263

剩下的就是站点的配置,包括启用PHP配合Nginx,还有配置phpmyadmin的别名,配置如下。
当然,虚拟机主机不想配置的话直接软连接一下也是可以的。

那么到此只需要导入之前wordpress的文件,恢复数据库那么blog就重新配置完成了。
配置完成后最后只需要使用
systemctl restart nginx
重启nginx即可。
配置完成后可以通过ssllabs来检测https的安全性。
https://www.ssllabs.com/ssltest/
如果按照本文进行配置的话,应该会得到A+评级。
https://www.ssllabs.com/ssltest/analyze.html?d=exvs.org