Javascript从https服务器获取请求到localhost:port并使用自签名SSL

时间:2017-03-06 09:11:53

标签: ajax ssl elasticsearch https ssl-certificate

我配置了两台服务器并运行我的Debian服务器。一个主服务器和一个Elasticsearch(搜索引擎)服务器。

主服务器在具有NGINX代理和购买的SSL证书的https节点服务器上运行。 Elasticsearch服务器正在http服务器上运行。我添加了一个新的NGINX代理服务器,使用自签名SSL证书将https://localhost:9999重定向到http://localhost:9200。此外,还在Elasticsearch服务器上配置了用户名和密码的身份验证。

所有内容似乎都已正确配置,因为当我从服务器终端向https://localhost:9999进行使用 -k 选项的卷曲时,我可以从服务器获得成功的响应绕过自签名证书的验证,没有它,它不起作用。

我无法从我的https主服务器向我的http localhost服务器发出跨域请求。因此,我需要在我的localhost服务器上配置https。

没有 -k 选项:

curl: (60) SSL certificate problem: self signed certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

使用 -k 选项:

{
  "name" : "server-name",
  "cluster_name" : "name",
  "cluster_uuid" : "uuid",
  "version" : {
    "number" : "x.x.x",
    "build_hash" : "abc123",
    "build_date" : "Timestamp",
    "build_snapshot" : false,
    "lucene_version" : "x.x.x"
  },
  "tagline" : "You Know, for Search"
}

这是一个成功的Elasticsearch服务器响应。

因此完整的卷曲请求看起来像curl -k https://localhost:9999/ --user username:password

  

所以,实际的问题是:

我希望能够对此服务器执行简单的jQuery AJAX请求。我尝试使用以下请求$.get('https://username:password@localhost:9999/'),但我收到ERR_CONNECTION_REFUSED

我的猜测是,AJAX请求不会绕过自签名证书验证,因此拒绝连接。

是否有任何简单的方法可以使用请求标头或类似的东西来解决这个问题?或者我是否需要购买CA证书才能使其与AJAX一起使用?

1 个答案:

答案 0 :(得分:1)

你是对的问题是自签名证书。如果你尝试相同的请求,但作为http它将起作用。

以下是使ElasticSearch与https一起使用的解决方法:

您需要实现自己的Http连接器:

var HttpConnector = require('elasticsearch/src/lib/connectors/http');
var inherits = require('util').inherits;
var qs = require('querystring');
var fs = require('fs');

function CustomHttpConnector(host, config) {
  HttpConnector.call(this, host, config);
}

inherits(CustomHttpConnector, HttpConnector);

// This function is copied and modified from elasticsearch-js/src/lib/connectors/http.js
CustomHttpConnector.prototype.makeReqParams = function (params) {
  params = params || {};
  var host = this.host;

  var reqParams = {
    method: params.method || 'GET',
    protocol: host.protocol + ':',
    auth: host.auth,
    hostname: host.host,
    port: host.port,
    path: (host.path || '') + (params.path || ''),
    headers: host.getHeaders(params.headers),
    agent: this.agent,
    rejectUnauthorized: true,
    ca: fs.readFileSync('publicCertificate.crt', 'utf8')
  };

  if (!reqParams.path) {
    reqParams.path = '/';
  }

  var query = host.getQuery(params.query);
  if (query) {
    reqParams.path = reqParams.path + '?' + qs.stringify(query);
  }

  return reqParams;
};

module.exports = CustomHttpConnector;

然后像这样注册:

var elasticsearch = require('elasticsearch');
var CustomHttpConnector = require('./customHttpConnector');

    var Elasticsearch = function() {
      this.client = new elasticsearch.Client({
        host: {
          host: 'my.server.com',
          port: '443',
          protocol: 'https',
          auth: 'user:passwd'
        },
        keepAlive: true,
        apiVerison: "1.3",
        connectionClass: CustomHttpConnector
      });
    }

https://gist.github.com/fractalf/d08de3b59c32197ccd65

如果您想进行简单的不使用ES的ajax调用,您唯一能做的就是提示用户访问该页面并在请求被拒绝时自行接受证书。

另见:https://stackoverflow.com/a/4566055/5758328