20

只需将一堆 json 数据上传到 elasticsearch 服务器即可拥有一个基本的查询 api,并且有很多选项,这真的很容易

我只是想知道是否有简单的方法来发布它,以防止人们修改它

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

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

(我是弹性搜索新手)

4

7 回答 7

23

如果你想把 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 的代理,请参阅此示例。

于 2013-01-02T10:23:37.987 回答
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/

于 2013-09-12T15:05:24.813 回答
6

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

在我的情况下,Kibana 需要的唯一来自 ES 的请求是“url_public/_all/_search”。

所以我允许它进入我的 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;
    }
}

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

于 2014-10-22T19:12:03.143 回答
6

我使用这个弹性搜索插件:

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

它非常简单,易于安装和配置。GitHub 项目页面有一个配置示例,显示了如何将请求限制为仅 HTTP GET 方法;这不会改变弹性搜索中的任何数据。如果您只需要列入白名单的 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
于 2015-03-05T12:41:36.323 回答
5

Elasticsearch 旨在用于受信任的环境中,它本身没有任何访问控制机制。因此,部署 elasticsearch 的最佳方式是在其前面使用一个 Web 服务器,该服务器将负责控制可以到达 elasticsearch 的查询的访问和类型。也就是说,可以通过使用elasticsearch-jetty插件来限制对 elasticsearch 的访问。

于 2013-01-02T00:15:10.013 回答
3

无论是 Elastic 还是 Solr,依靠搜索引擎来确保您的安全都不是一个好主意。你应该在你的容器中使用安全性,或者甚至将容器放在像 Apache HTTPD 这样真正防弹的东西后面,然后设置安全性来禁止你想要禁止的东西。

于 2013-01-02T00:12:55.787 回答
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;
    }
于 2020-11-20T21:58:36.173 回答