前言

这篇文章是https://www.elastic.co/blog/playing-http-tricks-nginx的部分翻译,对像我这样的小白学习nginx和elasticsearch有些许帮助,ps:翻译好难。。。e文好的同学还是去看原文吧。。。

正文

Elasticsearch默认是完全暴露在互联网上的RESTful服务接口。
这样做的好处是:web开发人员可以很快熟悉它的API,很容易使用curl命令或者浏览器来查询数据。也非常容易使用各种编程语言封装对应的接口。
Elasticsearch的RESTful接口是基于http开发的,所以它与现有的网络架构兼容性很好。

使用RESTful作为软件架构

现在很多软件使用RESTful服务作为基础架构,这样做的一大好处是你可以很容易插入新功能和修改已有功能。

Nginx

Nginx是一个高性能的反向代理服务。许多大型PHP项目也会使用nginx为静态文件加速。这篇文章使用基础的nginx配置为elasticsearch加上验证和授权功能。
运行Nginx为Elasticsearch做一个端口映射,我们可以非常简单的这样配置:

当访问http://localhost:8080的时候,相当于访问http://localhost:9200
这种配置当然没什么大用,聪明的读者会发现了nginx其实已经做了些工作,比如记录了每次请求的日志。

连接持久化

使用nginx保持elasticsearch连接。这么做可以减少elasticsearch因每次请求都需要连接~断开的压力,节省资源。
更多配置请参考https://gist.github.com/karmi/b0a9b4c111ed3023a52d

启动nginx

没有持久化连接的时候,每次请求elasticsearch数据opened connections都会增加:

使用nginx持久化连接后,opened connections每回都一样:

简单的负载均衡

对这个配置做一个非常小的改动,我们就可以分配requests到不同的elasticsearch节点上:

这里我们添加了两个节点在upstream中。Nginx会自动分配(轮询)request到不同的节点中。

这么做可以将请求分散给所有节点,增加节点只需在upstream中增加url,然后重启nginx
关于更高级的负载均衡功能,请参考Load Balancing with NGINX and NGINX Plus
(注意,elasticsearch本身有负载均衡机制。)

基本的用户认证

默认情况下,elasticsearch不采取认证机制,因为它不是设计在开放的网络环境当中,当你打开9200端口,你的数据,集群都不是安全的。
通常保护elasticsearch集群是通过VPN,防火墙等手段限制。但是如果你希望在外网连接elasticsearch集群,就只能通过用户密码来加以认证了。
可以使用nginx来实现用户认证:

可以使用很多工具来生成密码,这里使用openssl:

运行nginx:

普通请求会被拒绝:

输入帐号密码后,就可以建立连接了:

现在可以关闭9200端口,只留8080端口对外开放了,想要连接集群必须得通过验证。

简单授权

如果没有授权机制,只要登录,就可以对集群中任何事情,更改或删除数据,查看内部数据,甚至关闭集群。
通过非常小的改动,我们就可以拒绝通过RESTful命令关闭集群。

重启nginx:

尝试调用关闭集群,将会返回拒绝信息:

也可以配置允许某些请求,拒绝其余的请求,通过两个location来实现:

这样,请求/_cluster 和 /_nodes将通过,其他的会被拒绝:

选择性认证

现在我们想用基本认证保护elasticsearch但是允许ping命令发送HEAD请求到/起到监视集群状态的作用。

首先,我们定义两个状态代码:590-不需要验证,595-需要验证,使用nginx的location功能,两个location都指向同一个集群,但是其中一个需要认证。
然后我们设置一个变量\$ok,默认值0,当进入请求是/,\$ok变成01.如果请求是HEAD\$ok变成012。
如果\$ok是012,返回590状态码,换句话说,不需验证,其他情况返回595,需要验证。

多角色授权

到这里,我们已经有了一个简单的认证机制。如果我们需要一个更宽泛的认证机制,基于角色的,不如说像下面这样的:

  • 没有认证的用户只能使用ping命令,ping指定的URL(/);
  • 认证过的user用户可以执行_search与_analyze请求;
  • 认证过的admin用户可以执行任何请求。
    我们使用不同的端口为不同的角色服务:

点用openssl命令生成认证文件:

现在,所有用户都能ping集群,但是做不了其他操作:

user用户可以执行search,analyze请求,其他的不可以:

admin用户可以做任何操作:

这样轻松解决了基于多角色的授权,这么做的代价是:每一种角色都使用不同的端口。