How to fix SSL wrong version number error in NuxtJS? - https

I'm using nuxt.js to Server Side Rendering. I have to apply HTTPS onto my nuxt application, so I applied SSL certificate which is generated by Certbot. However, my Nuxt application generates an error which is like the below.
ERROR write EPROTO 140118450071360:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:252:
My server is AWS EC2. and I'm using Ubuntu 16.04, Nginx, and Express. I've tried to change my nginx proxy policy, but it doesn't work.
The below is my code which runs a server.
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('server:server');
var http = require('http');
var fs = require('fs');
var https = require('https');
var tls = require("tls");
var db = require('../models');
/**
* Get port from environment and store in Express.
*/
tls.DEFAULT_ECDH_CURVE = "auto";
const serverAddress = require('../config').serverAddress
const port = 3000
if (serverAddress === '') {
console.log("deploy enter #####");
// Certificate
const privateKey = fs.readFileSync("", "utf8");
const certificate = fs.readFileSync("", "utf8");
const ca = fs.readFileSync("", "utf8");
const credentials = {
key: privateKey,
cert: certificate
};
/**
* Create HTTPS server.
*/
https.createServer(credentials, app).listen(port, function() {
db.sequelize
.authenticate().then(() => {
console.log('Connection has been established successfully.');
db.sequelize.sync();
}).catch((err) => {
console.error('Unable to connect to the database:', err);
})
});
} else {
console.log("local enter #####");
/**
* Listen on provided port, on all network interfaces.
*/
var http = require('http')
var server = http.createServer(app);
app.set('port', port);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
}
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
and the below is my Nginx Configuration.
server {
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name mysterico.com; # managed by Certbot
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080;
}
listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
gzip off;
ssl_certificate /etc/letsencrypt/live/.../fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/.../privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = mysterico.com) {
return 301 https://$host$request_uri;
}
listen 80;
listen [::]:80;
server_name mysterico.com;
return 404;
}

The error ssl3_get_record:wrong version number is sometimes caused by Nuxt doing its server-side rendering over https without valid certificates (or with self-signed certificates).
In case you are using nuxt-axios to do the API requests, you can tell axios to use https if it is run from within the browser, and use http if it is run on the server.
In your nuxt.config.js add this:
publicRuntimeConfig: {
axios: {
// this is the url used on the server:
baseURL: "http://localhost:8080/api/v1",
// this is the url used in the browser:
browserBaseURL: "https://localhost:8443/api/v1",
},
},
Then you can use axios in your .vue or .js files like this:
methods: {
getSomeData() {
const $axios = this.$nuxt.$axios
return $axios.$post('/my/data').then((result) => {
// do something with the data
})
},
}

Related

Socket IO forbidden 403

I have a simple socket.io app and it works just fine on local and also it's installed successfully on AWS server using plesk admin dashboard but when I connect to the app I always get forbidden {"code":4,"message":"Forbidden"} .. the entry point seems to work great http://messages.entermeme.com .. any idea what could be wrong with it ?
Frontend code
import io from 'socket.io-client'
const socket = io('https://messages.entermeme.com', {
transports: ['polling'],
})
socket.emit('SUBSCRIBE')
Backend code
const cors = require('cors')
const app = require('express')()
const server = require('http').Server(app)
const io = require('socket.io')(server)
server.listen(9000)
app.use(cors())
io.set('transports', [
'polling'
])
io.origins([
'http://localhost:8000',
'https://entermeme.com',
])
io.on('connection', (socket) => {
socket.on('SUBSCRIBE', () => {
//
})
})
had a similar issue but when using nginx. So in case you still need some help:
In the end it turned out to be the URL I specified as socket origins. I didn't specify the port since the origin for me was also running on port 80 (443 for SSL) like in your example above:
io.origins([
'http://localhost:8000',
'https://entermeme.com', // <--- No port specified
])
I updated my config and added the port. So for you it would be:
io.origins([
'http://localhost:8000',
'https://entermeme.com:80', // <--- With port (or 443 for SSL)
])

Cannot hit simple node web server hosted on EC2 instance

Not able to hit my simple node web server hosted on an ubuntu EC2 in AWS. But I can't see I've missed anything! I've provided screen shots below within AWS - What am I missing? Please help!.
Many thanks,
Node code
const http = require('http');
const hostname = '127.0.0.1';
const port = 8080;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Command prompt
$ node index.js
Command prompt response
Server running at http://127.0.0.1:8080/
EC2 instance
Security settings
Elastic IP settings
Browser
http://"Public DNS (IPv4) value":8080/
Update
When you select the type, select "Custom TCP Rule":
and enter 8080 in the port range field.
EDIT
However, that only gets you part of the way. If you notice, your server is listening on the IP address 127.0.0.1. That means that it's not listen to the outside world, only localhost. To access it outside of the server machine you'll need to change your code to:
const http = require('http');
const hostname = '0.0.0.0';
const port = 8080;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
The change is that you're now listening on "all interfaces" as compared to just localhost.

Error using socket.io along with webpack-dev-server

Quick question guys, I am trying to use webpack-dev-server with socketio, but after trying different things, i figured both of the clients are listening to the same port '3000' and I end up with some kind of handshake error that goes away if I dont use webpack-dev-server on the same port.. here is my server config
const PORT = process.env.PORT || 3000;
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
setup(app) {
const server = require('http').Server(app);
let onlineUsers = 0;
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log(`A client is connected:${socket.id}`);
onlineUsers++;
io.sockets.emit('onlineUsers', {
onlineUsers
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
}
}).listen(PORT, 'localhost', (err) => {
if (err) {
console.log(err);
}
console.log(`Listening at localhost: ${PORT}`);
});
and webpack config
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./src/app.js'
],
these are the error(s)
WebSocket connection to 'ws://localhost:3000/sockjs-
node/608/jsbr0a0r/websocket' failed: Connection closed
before receiving a handshake response
T http://localhost:3000/sockjs-node/225/qvolyk2n/eventsource
iframe.js?ea3f:102 GET http://localhost:3000/sockjs-node/iframe.html 404 (Not Found)
createIframe # iframe.js?ea3f:102
IframeTransport # iframe.js?7dcb:42
IframeWrapTransport # iframe-wrap.js?7e29:11
SockJS._connect # main.js?45b8:219
SockJS._transportClose # main.js?45b8:299
g # emitter.js?927b:30
EventEmitter.emit # emitter.js?927b:50
(anonymous) # sender-receiver.js?620a:28
g # emitter.js?927b:30
EventEmitter.emit # emitter.js?927b:50
(anonymous) # polling.js?97d6:41
g # emitter.js?927b:30
EventEmitter.emit # emitter.js?927b:50
(anonymous) # eventsource.js?d407:58
VM776:66[HMR] Waiting for update signal from WDS...
VM1157:49Warning: [react-router] Location "/sockjs-node/225/ucoowxum/htmlfile?c=_jp.alfvbqm" did not match any routes
I was trying is to proxy the request to a different port
proxy: {
"http://localhost:3000": "http://localhost:4000"
}
and then listen to that in the configurations
entry: [
'webpack-dev-server/client?http://localhost:4000',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./src/app.js'
],
but I don't know if that is the way to go, anyone know how to fix this?
The issue is your proxy is not correctly configured. By default when you call the socket.io constructor, this line
const io = require('socket.io')(server);
All socket.io requests will go to your webpack dev server http://localhost:3000/socket.io (note the end of the URL - important) in your case. You want to proxy those requests to http://localhost:4000/socket.io, not every request that hits http://localhost:3000. You're also missing the ws: true line. So actually the correct configuration is the following:
proxy: {
'/api': {
target: 'http://localhost:4000',
pathRewrite: {"^/api": ""}
},
'/socket.io': {
target: 'http://localhost:4000',
ws: true
}
}
You don't need the first '/api' part if you don't have have a backend API that is listening to other requests. I'm just assuming you do. It's possible you just have all sockets in which case you can ignore that line. In most cases, people will have sockets and other http requests.
Hope this helps anyone trying to set up webpack-dev-server and socket.io with a proxy.
just to be thorough, here's the full nodejs implementation of it.
nodejs:
const http = require("http").createServer(app);
const io = require('socket.io')(http);
io.set('transports', ['websocket']);
http.listen(3002, () => console.log(`socket: http://${ip.address()}:3002`, "Time:", moment(new Date().getTime()).format("DD日 h:mm:ss")));
frontend:
var server = "/";
var connectionOptions = {
"force new connection": true,
"reconnectionAttempts": "Infinity", //avoid having user reconnect manually in order to prevent dead clients after a server restart
"timeout": 10000, //before connect_error and connect_timeout are emitted.
"transports": ["websocket"]
};
store.state.socket = io(server, connectionOptions);
store.state.socket.on('connect', () => {
console.log('socket connected ----');
});
webpack:
const target = "http://" + "localhost" + ":" + "3001";
const socket = "http://" + "localhost" + ":" + "3002";
module.exports = {
devServer: {
https: true,
key: fs.readFileSync('./src/localhostcert/key.pem'),
cert: fs.readFileSync('./src/localhostcert/cert.pem'),
host: 'localhost',
hot: true,
compress: true,
port: 8080,
proxy: {
"/socket.io": {
target: socket,
ws: true
}
}
}
}

proxy with hapi.js and h2o2, connection close

I try to configure hapi.js to proxy requests from /{params*} path to http://localhost:3000. It works fine for root '/' but when I try call /login I receive Cannot GET /login and on request I can see 'GET /login HTTP/1.1\r\nHost: localhost:3000\r\nConnection: close\r\n\r\n'. On my UI server http://localhost:3000/login works fine.
this is my proxy configuration
proxy: {
mapUri: (request, callback) => {
//loaded from a configuration file
let url = `http://localhost:3000${request.path}`;
callback(null, url);
}
}
Anyone know how to configure hapi proxy to pass custom routes?
Acctually it started to work. This is my current route
{
method: 'GET',
path: '/{param*}',
config: {
handler: {
proxy: {
mapUri: (request, callback) => {
let tls = conf.ui.tls;
let host = conf.ui.host;
let port = conf.ui.port;
let url = `${tls ? 'https://' : 'http://'}${host}:${port}${request.path}`;
callback(null, url);
}
}
}
}
}

http to https node proxy

I would like to know the easiest way to set up a proxy where I can make HTTP requests in (i.e.) localhost:8011 and the proxy makes a HTTPS request in localhost:443 (the HTTPS answer from the server should be translated to HTTP by the proxy as well)
I'm using node.js
I've tried http-proxy like this:
var httpProxy = require('http-proxy');
var options = {
changeOrigin: true,
target: {
https: true
}
}
httpProxy.createServer(443, 'localhost', options).listen(8011);
I have also tried this:
httpProxy.createProxyServer({
target: {
host:'https://development.beigebracht.com',
rejectUnauthorized: false,
https: true,
}
}).listen(port);
But when I'm trying to connect I'm getting this error
/Users/adrian/Development/beigebracht-v2/app/webroot/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js:103
var proxyReq = (options.target.protocol === 'https:' ? https : http).reque
^
TypeError: Cannot read property 'protocol' of undefined
I would like to do it with node, but, other solutions can be valid.
(The proxy will be used in localhost just with testing purposes so security is not a problem)
I needed a HTTP->HTTPS node proxy for unit testing. What I ended up doing was creating the HTTP proxy and then have it listen for and handle the connect event. When the server receives the CONNECT request, it sets up a tunnel to the HTTPS target URL and forwards all packets from the client socket to the target socket and vice versa.
Sample code:
var httpProxy = require('http-proxy');
var net = require('net');
var url = require('url');
var options = {
host: 'localhost',
port: 3002
};
var proxy = httpProxy.createProxyServer();
proxy.http = http.createServer(function(req, res) {
var target = url.parse(req.url);
// The `path` attribute would cause problems later.
target.path = undefined;
proxy.web(req, res, {
target: target
});
}).listen(options.port, options.host);
// This allows the HTTP proxy server to handle CONNECT requests.
proxy.http.on('connect', function connectTunnel(req, cltSocket, head) {
// Bind local address of proxy server.
var srvSocket = new net.Socket({
handle: net._createServerHandle(options.host)
});
// Connect to an origin server.
var srvUrl = url.parse('http://' + req.url);
srvSocket.connect(srvUrl.port, srvUrl.hostname, function() {
cltSocket.write(
'HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node.js-Proxy\r\n' +
'\r\n'
);
srvSocket.write(head);
srvSocket.pipe(cltSocket);
cltSocket.pipe(srvSocket);
});
});

Resources