将elasticsearch服务器设置为只读的简便方法

时间:2013-01-02 00:09:13

标签: elasticsearch

将一堆json数据上传到elasticsearch服务器以获得具有大量选项的基本查询api非常容易

我只是想知道是否有简单的方式将其全部发布,阻止人们对其进行修改

从默认设置开始,服务器处于打开状态,不会收到可修改数据的DELETE或PUT http消息。

是否有某种设置将其配置为只读?或者我应该配置某种http代理来实现它?

(我是一名弹性研究新手)

7 个答案:

答案 0 :(得分:20)

如果您想将Elasticsearch API公开为只读,我认为最好的方法是将Nginx放在它前面,并拒绝除GET之外的所有请求。示例配置如下所示:

# Run me with:
#
#     $ nginx -c path/to/this/file
#
# All requests except GET are denied.

worker_processes  1;
pid               nginx.pid;

events {
    worker_connections  1024;
}

http {

  server {

    listen       8080;
    server_name  search.example.com;

    error_log   elasticsearch-errors.log;
    access_log  elasticsearch.log;

    location / {
      if ($request_method !~ "GET") {
        return 403;
        break;
      }

      proxy_pass http://localhost:9200;
      proxy_redirect off;

      proxy_set_header  X-Real-IP  $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header  Host $http_host;
    }

  }

}

然后:

curl -i -X GET http://localhost:8080/_search -d '{"query":{"match_all":{}}}'
HTTP/1.1 200 OK

curl -i -X POST http://localhost:8080/test/test/1 -d '{"foo":"bar"}'
HTTP/1.1 403 Forbidden

curl -i -X DELETE http://localhost:8080/test/
HTTP/1.1 403 Forbidden

请注意,恶意用户仍然可能弄乱您的服务器,例如发送不正确的脚本有效负载,这会使Elasticsearch卡住,但对于大多数用途,这种方法会没问题。

如果您需要更多关于代理的控制,您可以使用更复杂的Nginx配置,或者编写专用代理,例如。在Ruby或Node.js。

有关更复杂的基于Ruby的代理,请参阅此example

答案 1 :(得分:8)

你可以在你的索引上设置一个只读标志,这确实限制了一些操作,所以你需要看看它是否可以接受。

curl -XPUT http://<ip-address>:9200/<index name>/_settings -d'
{
    "index":{
        "blocks":{
            "read_only":true
        }
    }
}'

正如其他一个答案中所提到的,实际上你应该让ES在受信任的环境中运行,在那里你可以控制对它的访问。

有关索引设置的更多信息,请访问:http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings/

答案 2 :(得分:6)

我使用这个elasticsearch插件:

https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin

它非常简单,易于安装和安装。配置。 GitHub项目页面有一个配置示例,显示如何仅限制对HTTP GET方法的请求;这不会改变elasticsearch中的任何数据。如果你只需要列入白名单的IP#(或者没有)来使用可以改变数据的其他方法(PUT / DELETE / etc),那么它也可以让你了解。

这样的东西进入你的elasticsearch配置文件(/etc/elasticsearch/elasticsearch.yml或等价物),改编自GitHub页面:

readonlyrest:
    enable: true
    response_if_req_forbidden: Sorry, your request is forbidden
    # Default policy is to forbid everything, let's define a whitelist
    access_control_rules:

    # from these IP addresses, accept any method, any URI, any HTTP body
    #- name: full access to internal servers
    #  type: allow
    #  hosts: [127.0.0.1, 10.0.0.10]

    # From external hosts, accept only GET and OPTION methods only if the HTTP request body is empty
    - name: restricted access to all other hosts
      type: allow
      methods: [OPTIONS,GET]
      maxBodyLength: 0

答案 3 :(得分:5)

Elasticsearch旨在用于受信任的环境,并且本身没有任何访问控制机制。因此,部署elasticsearch的最佳方法是在其前面安装一个Web服务器,负责控制可以访问elasticsearch的查询的访问和类型。这样说,可以使用elasticsearch-jetty插件限制对elasticsearch的访问。

答案 4 :(得分:5)

我知道这是一个古老的话题。我遇到了同样的问题,把ES放在Nginx后面,以使它只读,但允许kibana访问它。

在我的案例中,Kibana需要ES的唯一要求是&#34; url_public / _all / _search&#34;。

所以我允许它进入我的Nginx conf。

这是我的conf文件:

server {

    listen port_es;
    server_name ip_es;

    rewrite ^/(.*) /$1 break;
    proxy_ignore_client_abort on;
    proxy_redirect url_es url_public;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  Host $http_host;

    location ~ ^/(_all/_search) {
        limit_except GET POST OPTIONS {
                deny  all;
        }
        proxy_pass url_es;
    }

    location / {

        limit_except GET {
                deny  all;
        }
        proxy_pass url_es;
    }
}

因此,除非请求是_all / _search,否则只允许GET请求。如果需要,添加其他请求很简单。

答案 5 :(得分:3)

使用Elastic或Solr,依靠搜索引擎确保安全性并不是一个好主意。您应该在容器中使用安全性,或者甚至将容器放在真正防弹的地方,如Apache HTTPD,然后设置安全性以禁止您想要禁止的内容。

答案 6 :(得分:0)

如果您在nginx后面有一个面向公众的ES实例,该实例在内部进行了更新,则这些块应仅使其准备就绪,并且仅允许_search端点

    limit_except GET POST OPTIONS {
        allow 127.0.0.1;
        deny  all;
    }
    if ($request_uri !~ .*search.*) {
        set $sc fail;
    }
    if ($remote_addr = 127.0.0.1) {
        set $sc pass;
    }
    if ($sc = fail) {
        return 404;
    }