Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix plugin installer proxy for HTTPS #15588

Merged
merged 1 commit into from
Mar 7, 2018
Merged

Conversation

timroes
Copy link
Contributor

@timroes timroes commented Dec 13, 2017

This PR fixes #15581 and now correctly create a correct HttpsProxyAgent when trying to connect to HTTPS URLs to download plugins. If you try to load a HTTP URL using HttpProxyAgent you will get a socket hang up as described in the above issue.

Testing this is a bit tricky, since a HTTPS proxy request, only starts a CONNECT request against the proxy and relies on it to establish a HTTPS connection between the client and the upstream server. Thus we never get the calls we used in testing for the actual requests. Instead I intercepted the CONNECT request. But we have nothing reasonable to forward, without setting up a proper SSL server, which I consider a lot of overhead for this single test. We cannot use nock to simulate this SSL server, since it will intercept all requests (even before any proxy handling could be done) and destroy the test altogether.

Thus I created the HTTPS proxy in a way, that will cause the client request to fail, but still log, that the client tried to connect to the server, so we can check for this in the test. Since the request actually failed we need to except inside the reject function of the promise instead the resolve one.

/cc @marius-dr

@timroes timroes added Team:Operations Team label for Operations Team bug Fixes for quality problems that affect the customer experience release_note:fix v6.1.1 v6.2.0 v7.0.0 labels Dec 13, 2017
@epixa epixa added v6.1.2 and removed v6.1.1 labels Dec 17, 2017
@jbudz
Copy link
Member

jbudz commented Jan 11, 2018

The request didn't fail for me, it appears to use the proxy over http with the proxy downloading over https. What I did:

  1. mini hack to allow self signed certs

    diff --git a/src/cli_plugin/install/downloaders/http.js b/src/cli_plugin/install/downloaders/http.js
    index acd02e81f4..7507c5016c 100644
    --- a/src/cli_plugin/install/downloaders/http.js
    +++ b/src/cli_plugin/install/downloaders/http.js
    @@ -5,6 +5,7 @@ import { createWriteStream } from 'fs';
    import HttpProxyAgent from 'http-proxy-agent';
    import HttpsProxyAgent from 'https-proxy-agent';
    import { getProxyForUrl } from 'proxy-from-env';
    +const url = require('url')
    
    function getProxyAgent(sourceUrl, logger) {
      const proxy = getProxyForUrl(sourceUrl);
    @@ -15,10 +16,14 @@ function getProxyAgent(sourceUrl, logger) {
    
      logger.log(`Picked up proxy ${proxy} from environment variable.`);
    
    +  const proxyObj = Object.assign({
    +    rejectUnauthorized: false
    +  }, url.parse(proxy))
    +
      if (/^https/.test(sourceUrl)) {
    -    return new HttpsProxyAgent(proxy);
    +    return new HttpsProxyAgent(proxyObj);
      } else {
    -    return new HttpProxyAgent(proxy);
    +    return new HttpProxyAgent(proxyObj);
      }
    }
    
  2. brew install squid

  3. generate self signed certs

  4. https_port 3129 cert=/usr/local/etc/tmp/squid.crt key=/usr/local/etc/tmp/squid.key >> /usr/local/etc/squid.conf

I have an http proxy on 3128, https on 3129:

>> https_proxy=127.0.0.1:3129 node scripts/kibana-plugin install https://artifacts.elastic.co/downloads
/kibana-plugins/x-pack/x-pack-6.1.0.zip
Attempting to transfer from https://artifacts.elastic.co/downloads/kibana-plugins/x-pack/x-pack-6.1.0.zip
Picked up proxy https://127.0.0.1:3129 from environment variable.
Transferring 269804219 bytes....................
Transfer complete

>> https_proxy=http://127.0.0.1:3128 node scripts/kibana-plugin install https://artifacts.elastic.co/downloads/kibana-plugins/x-pack/x-pack-6.1.0.zip
Found previous install attempt. Deleting...
Attempting to transfer from https://artifacts.elastic.co/downloads/kibana-plugins/x-pack/x-pack-6.1.0.zip
Picked up proxy http://127.0.0.1:3128 from environment variable.
Transferring 269804219 bytes....................
Transfer complete

>> http_proxy=127.0.0.1:3128 node scripts/kibana-plugin install https://artifacts.elastic.co/downloads/kibana-plugins/x-pack/x-pack-6.1.0.zip
Attempting to transfer from https://artifacts.elastic.co/downloads/kibana-plugins/x-pack/x-pack-6.1.0.zip
Transferring 269804219 bytes....................
Transfer complete

@jimgoodwin jimgoodwin added v6.1.3 and removed v6.1.2 labels Jan 16, 2018
Copy link
Member

@jbudz jbudz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. ^ can be configured at the proxy level.

@ebuildy
Copy link
Contributor

ebuildy commented Jan 18, 2018

This is why:

env https_proxy=http://X.X.X.X no_proxy=127.0.0.1,localhost  kibana-plugin install https://github.com/sirensolutions/sentinl/releases/download/tag-5.5/sentinl-v5.5.1.zip

Dont work?

@tylersmalley
Copy link
Contributor

The test I had used in the original PR no longer works with this. Should we be testing if the proxy is https and not the sourceUrl?

nginx proxy:

worker_processes  1;
daemon off;

events {
  worker_connections  1024;
}

http {
  access_log  /dev/stdout;
  error_log /dev/stdout debug;

  server {
    listen 8200;

    location /downloads/kibana-plugins/x-pack/x-pack-7.0.0-alpha1.zip {
      alias /Users/tyler/Downloads/x-pack-7.0.0-alpha1.zip;
    }
  }
}

env HTTPS_PROXY=http://localhost:8200 node scripts/kibana-plugin.js install x-pack

@timroes
Copy link
Contributor Author

timroes commented Jan 19, 2018

@tylersmalley The source url needs to be HTTPS. Whether the proxy is or not, doesn't actually matter, important is the way that the proxy, does the HTTPS proxying. So using nginx would not work at all in this case, since it basically answers your request in your above scenario, and doesn't do the common CONNECT forwarding, in which case it just forwards the CONNECT to the real server, but doesn't do any actual HTTP interception on the traffic. I don't think you can simulate that with nginx. Maybe @marius-dr can share how he tested it!

@timroes
Copy link
Contributor Author

timroes commented Mar 7, 2018

As discussed with Tyler offline, I will merge this in now.

@timroes timroes added v6.3.0 and removed v6.2.3 labels Mar 7, 2018
@timroes timroes merged commit a346e35 into elastic:master Mar 7, 2018
@timroes timroes deleted the fix-https-proxy branch March 7, 2018 02:02
@elasticmachine
Copy link
Contributor

💔 Build Failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Fixes for quality problems that affect the customer experience release_note:fix Team:Operations Team label for Operations Team v6.3.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Plugin installer proxy not working properly for HTTPS URLs
7 participants