http-proxy-middleware
http-proxy-middleware copied to clipboard
Failure to handle HTTPS requests
Expected behavior
Expect successful SSL connection and response from the api server. Even though ssl object is being set in the options, it doesn't appear that the configuration is taking that into account. If ssl object is set, http requests are successfully proxied, but https requests are not. The same certificates and client configuration do work using http-proxy, rather than http-proxy-middleware.
Using http-proxy:
var fs = require('fs'),
httpProxy = require('http-proxy');
httpProxy.createServer({
ssl: {
key: fs.readFileSync('./ssl.key'),
cert: fs.readFileSync('./ssl.crt')
},
target: 'http://localhost:9000',
secure: false
}).listen(3000);
$ curl -k https://localhost:3000/api -v
- Trying 127.0.0.1...
- Connected to localhost (127.0.0.1) port 3000 (#0)
- ALPN, offering http/1.1
- Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
- error setting certificate verify locations, continuing anyway:
- CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none
- TLSv1.2 (OUT), TLS header, Certificate Status (22):
- TLSv1.2 (OUT), TLS handshake, Client hello (1):
- TLSv1.2 (IN), TLS handshake, Server hello (2):
- NPN, negotiated HTTP1.1
- TLSv1.2 (IN), TLS handshake, Certificate (11):
- TLSv1.2 (IN), TLS handshake, Server key exchange (12):
- TLSv1.2 (IN), TLS handshake, Server finished (14):
- TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
- TLSv1.2 (OUT), TLS change cipher, Client hello (1):
- TLSv1.2 (OUT), TLS handshake, Unknown (67):
- TLSv1.2 (OUT), TLS handshake, Finished (20):
- TLSv1.2 (IN), TLS change cipher, Client hello (1):
- TLSv1.2 (IN), TLS handshake, Finished (20):
- SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
- ALPN, server did not agree to a protocol
- Server certificate:
- subject: C=US; ST=VA; O=Internet Widgits Pty Ltd; CN=PWL
- start date: Oct 29 15:47:22 2016 GMT
- expire date: Oct 27 15:47:22 2026 GMT
- issuer: C=US; ST=VA; O=Internet Widgits Pty Ltd; CN=PWL
- SSL certificate verify result: self signed certificate (18), continuing anyway.
GET /api HTTP/1.1 Host: localhost:3000 User-Agent: curl/7.45.0 Accept: /
< HTTP/1.1 200 OK < content-type: text/plain < date: Fri, 09 Dec 2016 12:42:57 GMT < connection: close < transfer-encoding: chunked < request successfully proxied!
- Closing connection 0
- TLSv1.2 (OUT), TLS alert, Client hello (1):
Using http-proxy-middleware:
Actual behavior
$ curl -k https://localhost:3000/api -v
- Trying 127.0.0.1...
- Connected to localhost (127.0.0.1) port 3000 (#0)
- ALPN, offering http/1.1
- Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
- error setting certificate verify locations, continuing anyway:
- CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none
- TLSv1.2 (OUT), TLS header, Certificate Status (22):
- TLSv1.2 (OUT), TLS handshake, Client hello (1):
- Unknown SSL protocol error in connection to localhost:3000
- Closing connection 0 curl: (35) Unknown SSL protocol error in connection to localhost:3000
Setup
var fs = require('fs');
var express = require('express');
var proxy = require('http-proxy-middleware');
var apiProxy = proxy('/api', {
ssl: {
cert: fs.readFileSync('./ssl.crt'),
key: fs.readFileSync('./ssl.key')
},
target: 'http://localhost:9000',
changeOrigin: true,
logLevel: 'info'
});
var app = express();
app.use(apiProxy);
app.listen(3000);
In your http-proxy
setup secure: false
option is set.
In the http-proxy-middleware
setup this option is missing.
Can you check again if you set the same options?
Hi! I have a similar problem: here is my config with http-proxy-middleware
apiProxy = proxy('/',{
target:'http://127.0.0.1:3000',
ws:true,
ssl: {
key: fs.readFileSync('privkey.pem'),
cert: fs.readFileSync('fullchain.pem')
}
});
app.use(apiProxy);
app.listen(443);
and here is my config with http-proxy
:
httpProxy.createServer({
target: 'http://127.0.0.1:3000',
ws:true,
ssl: {
key: fs.readFileSync('privkey.pem'),
cert: fs.readFileSync('fullchain.pem')
}
}).listen(443);
With http-proxy-middleware
, I get the following error: gnutls_handshake() failed: The TLS connection was non-properly terminated.
Not working with secure : false also ! Here is my config
const fs = require('fs');
const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();
//running the app by serving the static files
//from dist folder
app.use(express.static(__dirname + '/dist'));
// Add middleware for http proxying
const PRODUCTION_BACKEND_SERVER = 'http://10.98.4.122:8080';
const LOCAL_BACKEND_SERVER = 'http://localhost:8080';
//app.use('/mppkvvcl/nextgenbilling/', proxy({target: '', changeOrigin: true}));
app.use('/mppkvvcl/nextgenbilling/', proxy({
ssl: {
cert: fs.readFileSync('./ssl/ngbmpwincoin.jks'),
key: fs.readFileSync('./ssl/KEY.txt')
},
target: PRODUCTION_BACKEND_SERVER,
secure : false,
changeOrigin: true,
logLevel: 'info'
}));
//for local testing
//app.use('/mppkvvcl/nextgenbilling/', proxy({target: LOCAL_BACKEND_SERVER, changeOrigin: true}));
const path = require('path');
// For all GET requests, send back index.html
// so that PathLocationStrategy can be used
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname + '/dist/index.html'));
});
//starting app on default port or on heroku port
console.log("Starting Node Server with ngb frontend application");
let port = process.env.PORT || 443;
app.listen(port, () => {
console.log("Started Server at port " + port);
});
I run into this issue too. As I could verify, the plugin http-proxy-middleware initializes the http-proxy with a empty object [link]
var proxy = httpProxy.createProxyServer({})
Looking at the http-proxy source code, it expects a ssl field to be present in the options object to make a switch between http and https connections link. I could not figure out how http-proxy-middleware is handling https connections since it seems to ignore the ssl field.
the ssl
field is not ignored.
with every request, a configuration object is constructed and passed to proxy.web
https://github.com/chimurai/http-proxy-middleware/blob/952c1afb7045179417659cf45c111f51b9339d2e/lib/index.js#L41
your ssl
configuration should be present:
https://github.com/chimurai/http-proxy-middleware/blob/952c1afb7045179417659cf45c111f51b9339d2e/lib/index.js#L100
I'm having the same issues. This is my index.js
:
const express = require('@feathersjs/express')
const proxy = require('http-proxy-middleware')
const fs = require('fs')
const server = express()
const proxied = proxy({
target: 'http://localhost:3000',
ws: true,
loglevel: 'debug',
router: {
'api.server.io': 'http://localhost:3000',
'web.server.io': 'http://localhost:8080',
},
secure: false,
ssl: {
key: fs.readFileSync('../ssl/key.pem', 'utf8'),
cert: fs.readFileSync('../ssl/cert.pem', 'utf8')
}
})
server.on('upgrade', proxied.upgrade)
server.use('*', proxied)
server.listen(443)
The response has an issue with the SSL:
$ curl -k https://web.server.io -v
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to web.server.io (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* error:1408F10B:SSL routines:ssl3_get_record:wrong version number
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
* Closing connection 0
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number
The certificates have been generated with:
openssl req -x509 -nodes -days 730 -newkey rsa:4096 -keyout key.pem -out cert.pem -config san.config -sha256
The san.config
file:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = IE
ST = My State
L = My City
O = MyCompany
OU = My Division
CN = web.server.io
[v3_req]
keyUsage = keyEncipherment, dataEncipherment, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = web.server.io
DNS.2 = api.server.io
Please try this: https://github.com/antonymarion/node-http-proxy/blob/master/examples/http/proxy-https-to-https-chimurai.js
you were missing the express https server init.
https.createServer(httpsOpts, app) httpServer.listen(8010); // 8010 port in my test case
instead
const server = express() server.listen(443)
Please try this: https://github.com/antonymarion/node-http-proxy/blob/master/examples/http/proxy-https-to-https-chimurai.js
you were missing the express https server init.
https.createServer(httpsOpts, app) httpServer.listen(8010); // 8010 port in my test case
instead
const server = express() server.listen(443)
It works for me
https://github.com/antonymarion/node-http-proxy/blob/master/examples/http/proxy-https-to-https-chimurai.js
This doesn't work for me, but you can pass your own https agent so I did that.