I'm running a node app inside a dokku container on an Ubuntu server, which also runs bind9 for DNS. In the node app, I'm running express. On the node app, I'm running a DNS reverse lookup on the client's IP like this (simplified):
const dns = require('dns');
const app = require('express')();
app.get('/myhostname', (req, res) => {
dns.reverse(req.headers['x-forwarded-for'], (err, hostnames) => {
res.json({ hostname: hostnames[0] });
});
});
This works fine locally, but once deployed to the dokku container, fails with an ENOTFOUND error. Presumably this is because the app isn't set to use the Ubuntu server as its DNS server. So I tried this right after require('dns'):
dns.setServers([process.env.DNS_SERVERS])
where DNS_SERVERS is set to either the local LAN ip of the server, or its docker internal IP. Either of those addresses results in a delay and eventual timeout trying to get the address.
How should I go about this?
The solution was this:
Set DNS_SERVERS=172.17.0.1
Allow requests through the firewall on the docker0 interface
Make sure bind is listening on 172.17.0.1 and that it is set to allow requests from the 172.17.0.0/16 range
The second item on the list is what I wasn't considering...
Related
I am playing with a small node server application.I have hosted it in AWS Lightsail's ubuntu instance. It is reachable from local browser like http://localhost:4201/
but when I try to access it from remote, it is unreachable.
In aws instance's network config I have opened traffic for all ports
I have cleared all rules from iptables as well. I am able to reach http port 80 and ping successfully. But no luck with node server, what am I missing? Is there a special way to enable traffic to node server?
I debugged it, basically in server.ts
I had bound it to localhost so it won't accept request from outside
app.listen(4201, '127.0.0.1', function () {
console.log('Server Listening on 0.0.0.0:4201');
});
changed it to 0.0.0.0
app.listen(4201, '0.0.0.0', function () {
console.log('Server Listening on 0.0.0.0:4201');
});
And now it is accessible from everywhere.
For testing purposes, I've created a Google Cloud Compute Engine VM (Debian 9).
I installed nodejs and created a small script. When navigating to the external ip address through my browser, nothing happens.
const express = require('express')()
express.get('/', (req, res) => {
console.log('browser access')
}
express.listen(8000, () => console.log('server is running'))
When navigating to http://[EXTERNAL_IP_ADDRESS]:8000, nothing happens.
I have SSH access through the external IP, it works
I can ping to the external IP address, this works too
When doing 'node app.js' through the terminal (SSH access), I see 'server is running'
I have set a firewall rule to accept all incoming trafic on tcp=8000 (IP range 0.0.0.0/0)
I have the firewall rules default-allow-http (tcp: 80) and default-allow-https (tcp: 443)
I have a static IP address
Is there something I'm missing?
Edit:
When I visit the server (with :8000) through my browser, the page keeps loading. But the message 'browser access' is not send to the console. After let's say 30 seconds, I get an ERR_CONNECTION_TIME_OUT in the browser.
Express version is 4.17.1. I also changed 'express' to 'app'.
When I open a terminal window and do 'curl EXTERNAL_IP_ADDRESS:8000', nothing happens. It seems like it keeps loading.
I changed listen(8000) to listen(8000, '0.0.0.0'). No differences are observed.
Problem solved:
I got it working. I installed ufw on the VM and opened up port 8000. That was the solution for me.
Solution:
Not only did I need to add a firewall rule to my VPC (0.0.0./0 tcp:8000, incoming), I also needed to open the port 8000 on my VM itself. I installed ufw and opened port 8000. It's working now.
I am running my Nodejs application on port 9000. I want the application to be accessible from a public IP address.
I went to my router config and did:
My Nodejs application is still running on localhost:9000 but when I go to
mypublicipaddress:9000
I get this site cannot be reached.
I also tried the netsh command:
netsh interface portproxy add v4tov4 listenport=9000 connectport=9000 connectaddress=192.168.1.12
This did not throw any error message but this also did not work.
I went to my router config and did: [...]
My Nodejs application is still running on localhost:9000
This implies that you've bound your Node.js server to your loopback interface on your machine and are trying to reach it from your router which is impossible. Try to bind the server to an IP address that is reachable by the router or bind it to all IP addresses on your local machine (ie. 0.0.0.0 or ::).
For example:
const http = require('http');
const server = http.createServer((req, res) => { res.end('It works') });
server.listen(9000, '0.0.0.0');
As for the netsh command, I think you should also set the listenaddress to your machine address on your network (or 0.0.0.0). Also, connectaddress must be set to 127.0.0.1:
netsh interface portproxy add v4tov4 listenport=9000 connectport=9000 connectaddress=127.0.0.1 listenaddress=192.168.1.12
I have a nodejs project running in ubuntu. so I access it this way:
http://localhost:9000/login
now I am trying to access this server from a guest windows7 which I am running on virtual box.
My ubuntu IP is 192.168.1.13 and my VM network configuration is Bridged Adapter so I am trying
http://192.168.1.13:9000/login
But it does not work
However, when I run in the cmd 'ping 192.168.1.13' It replies successfully.
Could someone tell me what else I have to do to access my server from the guest?
For what you want to achieve, your Node.js application should listen on the specified IP address and port which is accessible from other systems.
You just can't expect the user from outside world(OS) to access your web-application which is running in your system's localhost.
Change your code to something like this for allowing it to listen on APP_PRIVATE_IP_ADDRESS(substitute your IP, which is 192.168.1.13 in this case) :
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
// your code
}).listen(8080, 'APP_PRIVATE_IP_ADDRESS');
console.log('Server running at http://APP_PRIVATE_IP_ADDRESS:8080/');
Also, for further accessibility, check How To Set Up a Node.js Application for Production on Ubuntu 14.04.
Look at file /etc/hosts and check how localhost is mapped. Surely it is set to 127.0.0.1 . If you make your nodejs application listen on IP:port 192.168.1.13:9000 you will be able to connect. Or change the mapping of localhost which I don't recommend.
I have a Node.JS server that works fine on localhost. Now I want it accessible from the internet, hosted by my machine. My public IP address (the one that Google tells me I have) does not seem to be "accessible":
https.createServer({
key: privateKey,
cert: certificate
}, server).listen(80, '86.151.23.17');
fails with the following Node.JS error:
Error: listen EADDRNOTAVAIL
at errnoException (net.js:770:11)
at Server._listen2 (net.js:893:19)
at listen (net.js:937:10)
at Server.listen (net.js:994:9)
at dns.js:71:18
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
How can I publish my Node.JS server to my public IP address?
[Note: I do not have another webserver running. Also, I have tried various different ports as suggested here.]
You are most likely behind a router so your public IP is not available anywhere but on the router itself. What you need to do is listening on your private IP (usually somehing in the 192.168.* range) and setup a port forward on your router.
In case you are on Linux you'll also want to use a port >1024 instead of 80 so you don't have to run node as root. When setting up the port forwarding you can simply forward port 80 to whatever port your node server is running on.
const http = require("http");
const hostname = '0.0.0.0';
const port = 80;
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
using 0.0.0.0 will start listing to the public internet I have tested it.
I have experienced the cases that the ISP given router is intercepting default 80 and 443 ports. Even though the ports are opened. So better check server first using a port like 8080 etc.
And also configure port forwarding to a static local address (ipconfig /all assumed your host is windows) then assigned that IP address to your host using host's MAC address.
for a better experience, if you don't have a static IP, use noip.com dynamic domain names to access your server at any time (without knowing IP address).
Your app should listen on other ip address, example
app.listen(3000,'0.0.0.0');
or just
app.listen(3000);
Then you must open port forwarding in your modem. Like this http://www.dlink.com/uk/en/support/faq/routers/wireless-routers/dkt-series/how-do-i-open-up-ports-to-my-computer-port-forwarding-on-this-router
Finally you can see your app at ip address in here https://whatismyipaddress.com/