Node http-proxy: forward traffic to external https site - crashes - javascript

I want to transfer REST requests from my front end wepp app to the API on a external Jira server.
For this I'm using node http-proxy, which has been ok for a Jira server that is http.
But now I want to create a separate server for https.
So making som changes to this example I now have this:
var path = require('path'),
fs = require('fs'),
httpProxy = require('http-proxy'),
certFolder = '/my/cert/folder';
//
// Create the HTTPS proxy server listening on port 8002
//
httpProxy.createServer({
//(placeholder address)
target: {
host: 'https://ext.jiraserver.com',
port: 443
},
// letsencrypt cert
ssl: {
key: fs.readFileSync(path.join(certFolder, 'privkey.pem'), 'utf8'),
cert: fs.readFileSync(path.join(certFolder, 'fullchain.pem'), 'utf8')
},
secure: true
}).listen(8002);
console.log('https proxy server started on port 8002');
But when I make a request to my server, https://my.domain.com:8002 it crashes the server with error message:
.../node_modules/http-proxy/lib/http-proxy/index.js:119
throw err;
^
Error: getaddrinfo ENOTFOUND https://ext.jiraserver.com
https://ext.jiraserver.com:443
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)
I can't seem to get it to work... The server is online and the address is correct, so I don't know what's wrong.
Is it my code that's wrong or what can I do to get this to work?
Thanks!

Don't include the https:// in a DNS host definition.
host: 'ext.jiraserver.com',
The error message tells you that it's a DNS resolve problem. You're trying to lookup the DNS of https://ext.jiraserver.com including the https.

Related

Connecting SOCKET.IO-client (angular) to SOCKET.IO-server (node.js) over https net::ERR_CONNECTION_CLOSED

Our website has been running on an internal test machine where it could be accessed by all computers inside the network.
Now we want to deploy this website on a webserver (Apache2) to make it available to our clients. We want to use https and this is where we encountered a problem.
The Socket.io client canĀ“t connect to the node.js server since switching to https. We are using a signed certificate from a trusted CA. I have tried every solution I could find but none seem to work for our case.
Constructor used with ngx-socket-io in angular:
constructor() {
super({url: 'https://mywebPage.com:8080',options:{secure: true, origin: '*', transport:['websocket']}})
}
Our certificate seems to be valid since it works for our angular page. We are also able to make HTTPS GET/POST requests to our API which is located on the same server.
node.js socket.io server code:
var options = {
key: fs.readFileSync('/etc/apache2/folder/certificate.com.key'),
cert: fs.readFileSync('/etc/apache2/folder/certificate.com.public.crt'),
ca: fs.readFileSync('/etc/apache2/folder/certificate-intermediate.crt'),
requestCert: true
};
let server = require('https').createServer(options);
let io = require('socket.io')(server);
server.listen(8080);
console.log("Server started on Port 8080");
the client tries to connect to the socket-Server but fails and gets the net::ERR_CONNECTION_CLOSED the rest of the web page loads fine and has a valid certificate
We have also tested to see if the port on the web server is accesible and it seems to be open in netstat and nma.
If any more information is needed I am glad to provide.
EDIT: have tested the setup with rejectUnauthorized:false on the client side but that does not change the error.
similar stack overflow questions which i have considered in solving the problem:
socket.io net::ERR_CONNECTION_CLOSED
Setup Server-Server SSL communication using socket.io in node.js
EDIT 2: added requestCert: false, rejectUnauthorized: false into my node.js options.
Now the previous Error has been resolved now:
error during WebSocket handshake: Unexpected response code: 400

How to connect from MQTT javascript client to Mosquitto Server?

error log in console browser : "WebSocket connection to 'ws://127.0.0.1:1883/mqtt' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET"
my code .js to connect mosquitto server:
var options = {
clientId: 'web-client',
connectTimeout: 5000,
hostname: '127.0.0.1',
port: 1883,
path: '/mqtt'
};
var client = mqtt.connect(options);
use library mqtt-2.9.0.js
use mosquitto v1.5.4 windows10
=========================================
By default Mosquitto listens on port 1883 and accepts connections using native MQTT
If you want to connect with MQTT over Websockets you need to configure Mosquitto to listen on a different port and specify to use the websockets transport.
You can add the following to your mosquitto.conf:
listener 8883
protocol websockets
This will cause mosquitto to listen on port 8883 for MQTT over Websockets conections.
You can then modify your code as follows:
var options = {
clientId: 'web-client',
connectTimeout: 5000,
hostname: '127.0.0.1',
port: 8883,
path: '/mqtt'
};
var client = mqtt.connect(options);
It's also worth pointing out that your clientId needs to be unique for EVERY client that connects, so you will need to make it dynamic if you are going to load the page more than once at a time.
While 1883 is the usual port for vanilla MQTT connection - the usual default for websockets is port 8883. Have you tried port 8883?
Durr edited my typo 8888 to 8883

How do I open a websocket connection to cloud from location behind corporate proxy

I have a nodejs websocket server running in the cloud to which I can make a secured web socket connection from any location outside of corporate firewall.
Now, how can I provide proxy information while creating a websocket connection from a resource behind corporate proxy (on-premise)? I am using this nodejs module from https://github.com/websockets/ws.
I get EHOSTUNREACH error when I execute following code. Please note there is no vpn connection between cloud resource and the on premise resource.
**var wss = new WebSocket('wss://cloudserver:443', {
rejectUnauthorized: false
});**
With a sample code like below, I am able to make http connection to cloud from a resource behind corporate proxy using proxy information , but can't figure out how to make it work with the web sockets.
**var Http = require('http');
var req = Http.request({
host: 'proxy',
port: 8080,
method: 'GET',
path: 'http://cnn.com/' // full URL as path
}, function (res) {
res.on('data', function (data) {
console.log(data.toString());
});
});
req.end()
**
I also looked at following http://blog.vanamco.com/proxy-requests-in-node-js/ and it seems to have what I need, but as I am new to nodejs I am somewhat lost here.
Well EHOSTUNREACH implies that no network route can be found to the IP address that DNS provides for the targeted server.
This can either be a DNS error from the local DNS server (wrong IP address) or a routing error (wrong or missing route to that IP address) or possibly there is purposely no route to the target address (private network or corp network blocking things).
You could check the DNS side of things by seeing if you get the same IP address for that host from both work and home. A simple ping hostname will show you the IP address. If the target server supports ping requests, it will also tell you if the host is reachable. You could also examine tracert hostname from both home and work and see where things get lost.
I was able to connect to my cloud instance by providing proxy information using websocket-node (https://github.com/theturtle32/WebSocket-Node/)
module as below. The actual url is replaced with 'xxx' for security reasons. Thanks everyone who tried to help.
var fs = require('fs');
var client = new WebSocketClient();
var tunnel = require('tunnel');
var net = require('net');
var tunnelingAgent = tunnel.httpsOverHttp({
rejectUnauthorized: false,
proxy: {
host: 'xxxxxxxx',
port: 8080,
}
});
var requestOptions = {
agent: tunnelingAgent,
rejectUnauthorized: false,
strictSSL: false,
requestCert: false,
};
var headers = {
};
client.connect('wss://xxxxxx',null, 'xxxxxx', headers, requestOptions);

WebSocket connection to 'wss://mydomain.com:3001/' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

em-websocket configration in rails 2.3.18 and ruby 0.9.2
The application is hosted on the https: & http: sebsocket is working on the the staging(http://) domain but when we shifted it to the https:// the websocket closed automatically after same time. And encounter the the following error in webconsole
WebSocket connection to 'wss://my_domain.com:3001/' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED
websocket.ym
production:
host: '0.0.0.0'
port: 3001
secure: true
tls_options:
private_key_file: filename.com.key
cert_chain_file: filename.com.crt
websockets-app/app.rb
em-websocet configuration file location
"application_directory/websockets-app/app.rb" and it contains the following configuration
require 'thin'
require 'em-websocket'
require 'yaml'
require 'active_support/core_ext/hash'
env = ENV['WS_ENV'] || :development
logfile = File.open('../log/websocket.log', 'a')
logfile.sync = true
WS_LOGGER = Logger.new(logfile)
CONFIG = YAML.load_file('../config/websocket.yml').with_indifferent_access[env]
EM.run do
WS_LOGGER.info("Starting WebSockets server on port #{CONFIG[:port]}")
#channel = EM::Channel.new
WS_LOGGER.info("ENV:- #{env}")
WS_LOGGER.info("CHANNEL:-----+#{#channel.inspect}")
#EM::WebSocket.start(:host => '0.0.0.0', :port => '3001') do |ws|
EM::WebSocket.start(CONFIG) do |ws|
WS_LOGGER.info("Socket started----")
WS_LOGGER.info("Socket inspect#{ws.inspect}")
ws.onopen do |handshake|
WS_LOGGER.info("HANDSHAKE:---WS open now!!")
WS_LOGGER.info("handshake.secure? ..... #{handshake.secure?}")
sid = #channel.subscribe { |msg| ws.send msg }
WS_LOGGER.info("<#{sid}> WebSocket connection open")
ws.onclose do
#channel.unsubscribe(sid)
WS_LOGGER.info("<#{sid}> Connection closed")
end
ws.onmessage do |msg|
#channel.push msg
WS_LOGGER.info("<#{sid}> Received Message: #{msg}")
end
end
end
end
Start the websocket in production mode
WS_ENV=production bundle exec thin start -R app.rb &
Check the logs
Starting WebSockets server on port 3001
I, [2015-12-03T20:50:25.588306 #4861] INFO -- : ENV:- production
I, [2015-12-03T20:50:25.588341 #4861] INFO -- : CHANNEL:-----+# <EventMachine::Channel:0x315e908 #uid=0, #subs={}>
I, [2015-12-03T20:50:53.723973 #4861] INFO -- : Socket started----
I, [2015-12-03T20:50:53.724169 #4861] INFO -- : Socket inspect#<EventMachine::WebSocket::Connection:0x315dee0 #secure=true, #tls_options=
{"private_key_file"=>"filename.com.key", "cert_chain_file"=>"filename.com.crt"}, #debug=false, #signature=4, #close_timeout=nil, #handler=nil, #secure_proxy=false, #options= {"port"=>3001, "secure"=>true, "tls_options"=>{"private_key_file"=>"filename.com.key", "cert_chain_file"=>"filename.com.crt"}, "host"=>"0.0.0.0"}>
create the instance of webSocket in Javascript ###
host = "wss://mydomain.com:3001"; socket = new WebSocket(host);
Why using SSL/TLS should fail (leave it to the proxy)
Most proxies and production application "wrappers" (i.e., Heroku Dynos) decrypt any SSL data before forwarding it to the handling application.
i.e., when using nginx as a proxy for SSL connections, the certificate and encryption is usually managed by nginx and the data is sent to the local application as clear-text.
The answer to your question should be to use clear-text for your app and have the local proxy deal with the SSL/TLS encryption.
To prove my point:
Since I don't like em-websocket (i'm biased towards my own pet project), here's a quick Plezi application with and without a self-signed SSL certificate.
Running this application in a normal production environment (i.e. nginx, apache, Heroku, etc') should show that the application is accessible both using https and http when not secure and it isn't accessible when the application itself requires an encrypted connection.
GEMFILE:
gem 'plezi'
app.rb:
#!/usr/bin/env ruby
require 'plezi'
class MyDemo
# Http demo
def index
request.ssl? ? "Hello World (SSL/TLS)" : "Hello World (clear)"
end
# Websocket echo
def on_message data
write data # writes to the websocket
end
end
route '/', MyDemo
Run the app with clear text:
./app.rb -p $PORT
# or static port, i.e.
# ./app.rb -p 3000
Run the app for encrypted connections:
./app.rb -p $PORT ssl
# or static port, i.e.
# ./app.rb -p 3000 ssl
If you setup your production proxy or Heroku Dyno (or whatever you're using) properly, the application should work for http, https, ws, and wss only when it's in clear-text mode and it should always fail when in SSL mode.
P.S.
It's possible to setup SSL keys and certificates within the app, to avoid a self-signed certificate, just in case you're wondering or think this is the issue. Add the following lines to your app:
Plezi.ssl_context.cert = IO.binread("filename.com.crt")
Plezi.ssl_context.key = IO.binread("filename.com.key")
Also, I'm Plezi's author, so I'm somewhat biased where em-websockets is concerned...

WebSocket connection on wss failed

I have purchased a certificate and installed in my node.js website.But the https at the browser shows green and is OK.Now, I am trying to establish a socket connection using wss, but it failed.
The error at the Javascript client side is like this.
WebSocket connection to 'wss://securedsitedotcom:3003/call' failed:
WebSocket opening handshake was canceled
Please help!
Code at client side (Javascript)
var ws = new WebSocket('wss://securedsitedotcom:3003/call');
Code at server side (node.js)
https = require('https');
var server = https.createServer({
key: fs.readFileSync(config.certKeyPath),
cert: fs.readFileSync(config.certCrt),
requestCert: true,
rejectUnauthorized: false
},app);
server.listen(port);
var wss = new ws.Server({
server: server,
path: '/call'
});
Error at the browser console :
WebSocket connection to 'wss://securedsitedotcom:3003/call' failed:
WebSocket opening handshake was canceled
Recent work with Chrome has revealed that if a page is served as https on Chrome, websockets must use wss. And if wss must be used, port 443 must be used (and to boot not any other secure port and so far I have not seen any way to change the port), which may be your problem since your port looks like 3003 above.
Right now I am trying to get my IT group to patch/upgrade Apache on that server so mod_proxy_wstunnel can be used to make Apache listening on 443 a reverse proxy and pass all wss traffic through to my websocket server.
Hope this helps.
I ran into a similar issue, but I was using a Self Signed Certificate. You mentioned that you bought a Certificate. I guest it is signed by the certificate authority.
Otherwise, like in my case, non-validated certificate can cause an "opening handshake was cancelled" error. A validated certificate is either validated by a third party (Certificate Authority, ie VeriSign) or explicitly authorized by the client.
In my case, VeriSign didn't sign my certificate (self signed), so I had to explicitly authorized it. To do so, I simply need to visit the https URL with the browser (in your case "https://securedsitedotcom:3003/call"). Then a "warning unauthorized host" appear. You need to authorize the exception and than you can make your WSS connection.
Your server can use any port, it is not bound to 443. 443 is the default port for https but any port can be explicitly specified like you've done.
I hope it helps someone.

Categories

Resources