I have an incoming request for mydomain.com which I want to proxy on the private network to 10.0.10.5.
return function (req, res, next) {
var proxy = httpProxy.createProxyServer();
proxy.web(req, res, {
target: {
protocol: 'https:'
, hostname: '10.0.10.5'
, port: '8443'
, ca: caArr
}
// for testing only
//, secure: false
});
};
It fails with this error:
[Error: Hostname/IP doesn't match certificate's altnames]
I find that a little weird because the certificate _does_ match _mydomain.com_. But for some reason it doesn't like that I'm accessing it as 10.0.10.5. I would have thought that the fact that the Host header is set correctly to _mydomain.com_ would have made addressing it directly by IP not an issue.
However, if I manually edit /etc/hosts on the web-facing mydomain.com so that it sees mydomain.com as 10.0.10.5 like this, it works:
```javascript
javascript
return function (req, res, next) {
var proxy = httpProxy.createProxyServer();
proxy.web(req, res, {
target: {
protocol: 'https:'
, hostname: 'mydomain.com'
, port: '8443'
, ca: caArr
}
});
};
``````
The best thing I can think of to do (aside from secure: false, which I do not want to do) is to give a subdomain proxyable.mydomain.com and on the server that receives the request I just strip out proxyable before the vhost middleware gets a chance to handle it (otherwise the json api might return strings with _proxyable.mydomain.com_ back out to the user and cause api problems in the web interface).
Is there an option that can be passed to tell it to verify against the Host header instead of the hostname?
I'm having same issue with node.js 0.12, it works fine on 0.10.33 and 35. I'm just proxy-ing http to https, without certs.
Check out ssl-root-cas. That along with including your intermediate CA in the ca array as an option to your server will probably work just fine.
Having the same issue. Using Node.js 0.12.2
Please try to use
var proxy = httpProxy.createProxyServer({secure:false});
Any more thoughts on how to resolve this? We just ran into this today after upgrading from 0.10 to 0.12. :(
This issue is also causing me trouble. It seems the DNS name of my NodeJS application is being checked in the list of altnames in the upstream's certificate. This is a defect introduced between NodeJS 0.10 and 0.12.x
@indutny any idea what could have caused this? Would love to know if its a bug in http-proxy that im not accounting for based on a node core change.
@jcrugzz there are two options for tls.connect: hostname and host. Former one specifies TLS hostname, and the latter one DNS host to connect to. I suppose that hostname should be mydomain.com and host should be that IP address.
Thanks for the quick reply @indutny :), that makes a lot of sense. I'm guessing this check wasn't happening in 0.10 for whatever reason. I know you were optimizing a lot of TLS between then. Does this fix the issue you all are seeing? cc @coolaj86 @russellballestrini
The issue we saw was:
Error: Hostname/IP doesn't match certificate's altnames: "Host: some.domain.com. is not in the cert's altnames: DNS:*.some.other-domain.com, DNS:some.other-domain.com"
at Object.checkServerIdentity (tls.js:210:15)
at TLSSocket.<anonymous> (_tls_wrap.js:941:31)
at TLSSocket.emit (events.js:104:17)
at TLSSocket._finishInit (_tls_wrap.js:467:8)
The issue only appears when switching to node v0.12.x and up. We only use http-proxy to proxy HTTPS->HTTPS websocket connections and we don't see this issue for the other portions of the application that use hapi and h2o2.
So is the suggestion to define the proxy target using the host parameter instead of the hostname?
Relevant parameters to the WS proxy call:
Request Headers:
{ host: 'some.domain.com',
connection: 'Upgrade',
pragma: 'no-cache',
'cache-control': 'no-cache',
upgrade: 'websocket',
origin: 'https://some.domain.com',
'sec-websocket-version': '13',
'user-agent': '<agent info>',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8,he;q=0.6',
cookie: '<cookie data>',
'sec-websocket-key': '<key>',
'sec-websocket-extensions': 'permessage-deflate; client_max_window_bits' }
Proxy options:
{ target: 'wss://some.other-domain.com:443' }
@dhm116 The suggestion is that you may want to use the object form of target so you can specify the specific host as well as the hostname since the mismatch has to do with the hostname. When you url.parse() a string target, the host and hostname are derived from each other.
If this does not work I would follow the suggestion of making sure you have the entire chain of ca's necessary
Thanks @jcrugzz, we'll try that out in the morning and follow up!
@jcrugzz We were able to confirm that modifying the original request Host header value fixed our issue - changes to the target seemed to have no impact. :+1: Thanks!
I came across this same issue in a different way. We needed to specify our root CA in the outgoing requests because we had some new certificates whose root didn't appear to be in the Node.js default. We ended up creating a new https.Agent with the ca set, and then passed it in the createProxyServer options, as we couldn't find any other place to specify the ca that would actually work. We then started getting the Hostname/IP matching error until we set changeOrigin: true in the createProxyServer options
We never had any Hostname/IP matching issues before we started passing an agent in the options. Anyone have an idea why that might be?
I'm having the same issue with http-proxy 1.14.0 and nodejs 6.3.1. It appears to be checking the hostname of the proxy (localhost) against the certificate of the proxy target (secure.gravatar.com)
var proxy = httpProxy.createProxyServer({
target: {
protocol: 'https:',
host: 'secure.gravatar.com',
hostname: 'secure.gravatar.com',
port: '443'
}
});
Hostname/IP doesn't match certificate's altnames: "Host: localhost. is not in the cert's altnames: DNS:*.gravatar.com, DNS:gravatar.com"
Any ideas?
@russellballestrini
@indutny
@jcrugzz
Much appreciated :)
@aianus - sorry you are having trouble - @jplock and I opt'd to terminate TLS on our reverse proxy instead (nginx). Thus we no longer have this issue because we are no longer using NodeJS to deal with TLS.
As a result we were also able to gain an A+ on some TLS checkers.
For anyone running into this in the future:
The fix was to set the changeOrigin: true flag in the proxy options.
Thanks @aianus - That did it for me
I'm getting the same issue, and setting changeOrigin: true doesn't seem to fix the issue for me.
const proxy = httpProxy.createProxyServer({
changeOrigin: true
});
proxy.web(req, res, {
changeOrigin: true,
target: {
protocol: 'https:',
host: properties.dest.host,
port: properties.dest.port,
hostname: properties.dest.host
}
});
Any idea?
@anhvutnu Try to remove target object eg.:
const proxy = httpProxy.createProxyServer();
proxy.web(req, res, {
changeOrigin: true,
target: https://example.com:3000,
});
Most helpful comment
For anyone running into this in the future:
The fix was to set the
changeOrigin: trueflag in the proxy options.