写在前面
Nginx 的使用可以为小型 Elasticsearch (下文简称 ES)集群提供负载均衡,同时也能使用 auth_basic
为 ES 较为开放的 REST API 提供一层安全保障
如果是较为大型的 ES 集群,可以划分更详细的角色(可参考官方文档),包括主节点、数据节点、Ingest 节点(功能上来说就是预处理节点)、协调节点等,这里暂不细说(因为 ES 5.* / 6.* / 7.* 各个版本还是有一些出入的,所以先挖个坑看看什么时候填),其中的协调节点的作用正是负载均衡(在小型集群中可以不指定专门的角色,每个节点都是主节点、数据节点,连接哪个节点都一样)
环境说明
-
Linux 2.6.32
-
Nginx 1.14.0
-
Elasticsearch 6.4.0
步骤
0. 使用 htpasswd 生成密码文件
使用命令生成可以参考 Apache 的官方文档
因为有些服务器没有 Apache 服务,所以现在也有很多在线生成,比如开源中国的在线工具里就有,输入用户名密码,选择适合自己服务器系统的加密算法,生成加密结果串,然后到服务器上新建一个密码文件,保存这个加密结果串就行了
1. 配置 Nginx 负载均衡
Nginx 的安装使用这里就不再赘述,在之前的《Nginx学习总结》中有简单的介绍编译安装步骤
编辑 nginx.conf,配置 ES 集群的各主机地址
# 配置上游服务器集群信息
upstream es-cluster {
server 10.0.0.100:9200 weight=1;
server 10.0.0.101:9200 weight=1;
server 10.0.0.102:9200 weight=1;
keepalive 1000;
}
# 配置代理服务器信息
server {
listen 19200;
server_name localhost;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://es-cluster;
}
location /nginx-status {
stub_status on;
}
}
2. 配置 auth_basic
同样,编辑 nginx.conf,在 location 配置中补充 auth_basic,指定步骤 0 中新建的密码文件路径
location / {
auth_basic "login";
auth_basic_user_file /path/to/htpasswd;
}
引入安全控制后如何使用
按上述三步的操作,就可以实现负载均衡和安全控制,安全方面的细节还有例如配置服务器的防火墙,限制 IP 和端口等等
多了一层身份验证后,在使用的时候就需要用户名密码,比如用 elasticsearch-head 时,改为连接 Nginx 地址后,网页就会弹出输入用户名密码的窗口
这里再介绍下如何用 Postman 和 Java 客户端
0. Postman
如图所示,在使用 REST API 时,在 Authorization 中选择加密类型,并输入用户名密码即可
1. Java Rest Client
ES 的 Java 客户端现在大都是用 RestClient,不过官方有两种,一个是 RestClient
一个是 RestHighLevelClient
,两者的初始化方式类似
// RestClient
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")).build();
// RestHighLevelClient
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
而需要进行用户名密码认证时,就变成了这样:
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("user", "password"));
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}));
更详细的 REST Client 使用可以参考官方的介绍文档 Java REST Client