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

Support using https requests with an http proxy #28

Merged
merged 10 commits into from
Mar 19, 2020
Merged

Conversation

davidfestal
Copy link
Contributor

@davidfestal davidfestal commented Mar 18, 2020

The goal of this PR is to fix issue eclipse-che/che#16356

The error was coming from the fact that axios implementation of https requests through a http proxy is limited. In particular, it seems it doesn't correctly use the CONNECT method that allows tunneling a https request inside a http proxy.
A consequence of this is that the underlying socket connection opened to finally reach the target endpoint is not a ssl socket. This finally results in an error from the Proxy, especially with self-signed certificates.

The fix configures axios to override either http or https agent (according to whether TLS is used) with agents created by the tunnel module.

This PR was tested on a disconnected environment with an HTTP proxy, and TLS enabled with self-signed certificates.

vinokurig and others added 3 commits March 13, 2020 19:49
src/index.ts Outdated Show resolved Hide resolved
Signed-off-by: David Festal <[email protected]>
@davidfestal davidfestal changed the title Make it more production-ready WIP: Make it more production-ready Mar 18, 2020
Conflicts:
	src/index.ts
@davidfestal davidfestal changed the base branch from proxyTest to master March 18, 2020 18:12
@davidfestal davidfestal changed the title WIP: Make it more production-ready WIP: Support using https requests with an http proxy Mar 18, 2020
@davidfestal
Copy link
Contributor Author

davidfestal commented Mar 18, 2020

So in order to have the PR ready to merge we still need to:

  • only add the logging interceptors to the axios instance when some environment variable is setup (and possibly extend this logging mechanism to all returned axios instances)
  • extract some logic into small methods as @sleshchenko pointed in this comment: Support using https requests with an http proxy #28 (comment)
  • continue testing it (== integration tests in the context of che-theia on an operator-based install) carefully in a variety of cases (mainly without proxy but with/without TLS, with/without self-signedcerts)
  • Finally change the package name to switch back to the @eclise-che namespace

@davidfestal
Copy link
Contributor Author

@vinokurig Do you plan to work on those remaining tasks ?

cc @ericwill

src/index.ts Outdated Show resolved Hide resolved
@vinokurig
Copy link
Contributor

I'll handle this PR

@vinokurig vinokurig self-assigned this Mar 19, 2020
src/index.ts Outdated Show resolved Hide resolved
src/index.ts Outdated Show resolved Hide resolved
src/index.ts Outdated Show resolved Hide resolved
@vinokurig vinokurig changed the title WIP: Support using https requests with an http proxy Support using https requests with an http proxy Mar 19, 2020
@vinokurig
Copy link
Contributor

@sleshchenko @olexii4 @akurinnoy The PR is ready for review

Copy link
Contributor

@akurinnoy akurinnoy left a comment

Choose a reason for hiding this comment

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

LGTM

src/index.ts Outdated
});
return axios.create({httpsAgent: agent});
if (!this.isItNode()) {
this.addLogInterceptorsIfEnabled(axios);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure this makes sense to add interceptor in the browser case, since the process object will not be available ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I removed the reading of the env variable instead I added a new property to config, so the logging can be controlled by the API

@davidfestal
Copy link
Contributor Author

So last tests results:

  • without a proxy:
    • without TLS : OK
    • with TLS and self-signed certs: OK
  • with a proxy
    • without TLS : NOK impossible to join the API server
    • with TLS and self-signed certs: OK

So it seems now we lost the access to the the API server with proxies when TLS in not enabled

Additionally, changing the configuration of the request/response logging to push to the che-theia makes it quite difficult to to test the real cause of this failure: the real http error object is hidden from the logs:

2020-03-19 16:03:13.569 root INFO [object Object] 
2020-03-19 16:03:13.573 root ERROR Security problem: Unable to configure separate webviews domain:  Params: Error: Unable to get workspace containers. Cause: Cannot create Che API REST Client
    at CheApiServiceImpl.<anonymous> (/home/theia/node_modules/@eclipse-che/theia-plugin-ext/lib/node/che-api-service.js:292:31)
    at step (/home/theia/node_modules/@eclipse-che/theia-plugin-ext/lib/node/che-api-service.js:38:23)
    at Object.throw (/home/theia/node_modules/@eclipse-che/theia-plugin-ext/lib/node/che-api-service.js:19:53)
    at rejected (/home/theia/node_modules/@eclipse-che/theia-plugin-ext/lib/node/che-api-service.js:11:65)
    at process._tickCallback (internal/process/next_tick.js:68:7)
2020-03-19 16:03:13.590 root ERROR Uncaught Exception:  Params: [object Object]
2020-03-19 16:03:16.234 root INFO PluginTheiaDirectoryHandler: accepting plugin with path Params: /tmp/theia-unpacked/eclipse_che_github_auth_plugin.theia

src/index.ts Outdated
});
}
} else {
axiosRequestConfig.httpAgent = proxyIsHttps ? httpsOverHttpsAgent : httpOverHttpsAgent;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

afaict here it should be:

axiosRequestConfig.httpAgent = proxyIsHttps ? httpOverHttpsAgent : httpOverHttpAgent,

Of course you would have to define them just above.

TBH I'd rather define all the const just above as you did for httpOverHttpsAgent. To me it would make the logic much clearer and voir this type of errors

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed

src/index.ts Outdated
proxy: mainProxyOptions,
ca: certificateAuthority ? [certificateAuthority] : undefined
});
const httpsOverHttpsAgent = tunnel.httpsOverHttps(httpsProxyOptions);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I fear that here you will have to also add the ca at the top level, besides the proxyargument.
(that's a case we cannot test for now, but that's how tunnel docs shows in the examples).

ca at the top-level, when target URL is https
ca in the proxy settings, when the proxy itself is https

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants