Elasticsearch 通过  x-pack 作为认证模块供用户使用,但是在 7.0 以下版本需要购买 licence 才能使用。Elasticsearch 7.0 以上版本 x-pack 作为基本的功能模块供使用,不用购买 licence。

    这里以7.0 以下版本来通过 nginx 反向代理的方式对 Elasticsearch 未授权访问漏洞进行安全加固。简述访问逻辑:

(1)服务器的 9201 对外开放访问,且需要认证

(2)实际流量转发到服务器的 9200 提供 Elasticsearch 服务,9200 不直接对外提供访问。

1,安装 http-tools 工具和 nginx

# yum install -y httpd-tools
# yum -y install nginx

2,生成密码文件

# htpasswd -c /etc/nginx/elkauth elkdmin
New password:
Re-type new password:
Adding password for user kiadmin

elkadmin 将会是登录认证时候使用的帐号,密码这里需要重复输入两次来确认,且保证密码强度:

(1)静态口令必须长度大于等于 14 位。

(2)静态口令必须包含数字、大写字母、小写字母、特殊符号 4 种中至少 3 种。

3,安装 nginx 并修改 nginx 文件,一般是 /etc/nginx/nginx.conf

# vim /etc/nginx/nginx.conf
server {
    listen       9201 default_server;
    listen       [::]:9201 default_server;
    server_name  _;
    #root         /usr/share/nginx/html;
 
    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
 
    location / {
 
        auth_basic "ELK Auth";
        auth_basic_user_file /etc/nginx/elkauth;
        proxy_pass http://localhost:9200/;
        proxy_set_header Host $host:9200;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
    }
 
    error_page 404 /404.html;
        location = /40x.html {
    }
 
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

这部分的重点是三个:

(1)修改掉端口,elasticsearch 默认使用的是 9200 端口,我们使用 9201 来作为帐号认证端口。

(2)注释掉 index ,不然请求不会跳转

(3)配置反代和认证,默认的 location 配置为空,所以这里直接添加就可以了。

依次解释这些配置的作用:

auth_basic "ELK Auth"; //帐号认证弹框的 banner 信息,说明服务名称
auth_basic_user_file /etc/nginx/elkauth; //认证的帐号密码文件,也就是我们 htpasswd 创建的密码文件
proxy_pass http://localhost:9200/; //重定向目标,
proxy_set_header Host $host:9200; //重定向后的请求会增加一个名为 Host 的 header 包含目标IP:端口
proxy_set_header X-Real-IP $remote_addr; //重定向后的请求会增加一个名为 X-Real-IP 的 header 说明请求源IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; //重定向后的请求会增加一个名为 X-Forwarded-For 的 header 记录 X-Forwarded-For 信息

4,重启服务

service nginx restart

5,访问测试:

输入用户名密码之后可以正常访问:

6,WEB API 访问

到目前为止实现了为 Elasticsearch 的访问添加认证,但是实际上针对 9200 的访问都是 api 调用,所以不能像浏览器访问一样手工输入密码。可以在 http 请求中加上 Authorization 头部来通过认证:

# curl -H 'Authorization: Basic a2lhZG1pbjpraWFkbWlu' http://192.168.1.1:9201/
{
  "name" : "VM_0_3_centos",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "lVG6IylMSpOmU1WRukgi0Q",
  "version" : {
    "number" : "7.6.1",
    "build_flavor" : "default",
    "build_type" : "rpm",
    "build_hash" : "aa751e09be0a5072e8570670309b1f12348f023b",
    "build_date" : "2020-02-29T00:15:25.529771Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

其中 a2lhZG1pbjpraWFkbWlu 是[用户:密码]经过 base64 编码之后的字符串,当然也可以在浏览器手工输入用户名密码之后,通过浏览器的 F12 功能直接获取到这个值:

7,配置 Elasticsearch 绑定 localhost

避免外部用户通过网络访问到 Elasticsearch 的 9200 端口服务,需要将 Elasticsearch 服务绑定 localhost 。

vim /etc/elasticsearch/elasticsearch.yml

修改 network.host 为 localhost

network.host: localhost

重启 Elasticsearch  服务

文章来源于腾讯云开发者社区,点击查看原文