TheThingsArchive / node-app-sdk

The Things Network Application SDK for Node.JS
https://www.thethingsnetwork.org/docs/node-js/
MIT License
41 stars 28 forks source link

How to set fixed port on connection between node app and ttn server? #98

Closed rgrygiel closed 3 years ago

rgrygiel commented 5 years ago

Hello! i'm trying to forward port on my firewall where the node js is running behind. Port seems to be always different (based on netstat info) and sdk can't connect to the TTN server. Funny thing is that if i run this locally on my laptop (using cellural internet connection app is working as expected - that's why i'm excluding code issue).

App is running on node instance on Centos 7. I'll add that i'm running Node Red on the same server and when i forward it's default port on the same firewall (pfSense) it's working without issues so i can also exclude server side config issue.

johanstokking commented 5 years ago

@rawian which port are you referring to exactly? If you mean the source port, yes, that is always different. But for a firewall you need the destination port, which is fixed.

rgrygiel commented 5 years ago

@johanstokking thanks for Your answer! My issue is that i don’t know which port should be forwarded on my firewall to make this simple node app work. I’ve tried poeta: 80,443,1900 & 1884 but nothing seems to help. As above when I’ll go „outside” the firewall it’s working

johanstokking commented 5 years ago

this simple node app work

Which node app?

rgrygiel commented 5 years ago

@johanstokking I've created simple API based on express for node (my simple app) and it's accessible when i'll forward specified port in the code, but sdk itself can't connect to TTN.

Let's consider example code below;

app.listen(appPort, () => {
  console.log("App launched on port: " + appPort);

  ttn.application(appID, accessKey)
    .then(function (res: any) {
      // import routes
      require('./Router/routes')(app, res);
      console.log("Routes included");
    })
    .catch(function (error: any) {
      console.error("Error", error);
      process.exit(1);
    });
});

where the appPort is let's say 14123. If i'll forward port 14123 on my firewall express server is achievable, but i can't see the console.log("Routes included"); which would indicate that tth sdk have a connection to ttn srv.

johanstokking commented 5 years ago

Hmm. Do you see anything else in the logs?

rgrygiel commented 5 years ago

Not at all. Only first console.log entry shows that „App launched on port: ...”. When i’ll check netstat connection status i got FIN-WAIT

johanstokking commented 5 years ago

OK. For debugging I think it's best to dissect the webserver from the TTN connection. Can you try the example code in this repository and see if that works?

rgrygiel commented 5 years ago

So i've used es5 example like below:

"use strict";
//let App = require("ttn");

var ttn = require("ttn")

// set TTN variables
const appID = "some-app-test";
const accessKey = "ttn-account-v2.XXXXXXXXXXXXXXXXXXXXXXXXXXX";

console.log("App started");
ttn.application(appID, accessKey)
  .then(function (client: any) {
    console.log("Step 1");
    return client.get()
  })
  .then(function (app: any) {
    console.log("Step 2");
    console.log(app)
  })
  .catch(function (err: any) {
    console.error(err)
    process.exit(1)
  })

and i can see none of two console.log("Step...");

johanstokking commented 5 years ago

Do you have an outgoing firewall blocking port 1900?

rgrygiel commented 5 years ago

Nope. The one and only is TTN sdk tring to connect to the TTN network. See the netstat output below

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      4550/smbd           
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      4550/smbd           
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      862/sshd            
tcp        0      0 0.0.0.0:1880            0.0.0.0:*               LISTEN      1096/node-red       
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1263/master         
tcp        0      0 10.1.0.101:22           10.1.0.90:52519         ESTABLISHED 11859/sshd: root@pt 
tcp        0      0 10.1.0.101:22           10.1.0.90:52370         ESTABLISHED 11617/sshd: root@pt 
tcp        0      0 10.1.0.101:22           10.1.0.90:52371         ESTABLISHED 11640/sshd: root@pt 
tcp        0      0 10.1.0.101:445          10.1.0.90:50123         ESTABLISHED 4576/smbd           
tcp        0      0 10.1.0.101:56570        52.178.215.58:1900      FIN_WAIT2   12115/node          
tcp6       0      0 :::445                  :::*                    LISTEN      4550/smbd           
tcp6       0      0 :::33060                :::*                    LISTEN      1108/mysqld         
tcp6       0      0 :::3306                 :::*                    LISTEN      1108/mysqld         
tcp6       0      0 :::139                  :::*                    LISTEN      4550/smbd           
tcp6       0      0 :::22                   :::*                    LISTEN      862/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      1263/master 
rgrygiel commented 5 years ago

I've also disabled firewall-cmd at all to avoid any kind of issues. And still nothing. Quite interesting, isn't it?

johanstokking commented 5 years ago

I tested this, and for me it works fine;

Simply installed dependency with yarn add ttn; current version is 2.3.1.

"use strict";

var ttn = require("ttn")

// set TTN variables
const appID = "johan-dev";
const accessKey = "ttn-account-v2.XXXX";

console.log("App started");
ttn.application(appID, accessKey)
  .then(function (client) {
    console.log("Step 1");
    return client.get()
  })
  .then(function (app) {
    console.log("Step 2");
    console.log(app)
  })
  .catch(function (err) {
    console.error(err)
    process.exit(1)
  })

Output:

App started
Step 1
Step 2
{ appId: 'johan-dev',
  payloadFormat: 'custom',
  decoder:
   'function Decoder(bytes, port) {\n  var colors = ["red", "green", "blue", "yellow", "cyan", "magenta", "white", "black"];\n  var decoded = {\n    light: (bytes[0] << 8) | bytes[1],\n    temperature: ((bytes[2] << 8) | bytes[3]) / 100,\n    state: {\n      color: colors[bytes[4]]\n    }\n  };\n\n  return decoded;\n}',
  converter: '',
  validator: '',
  encoder:
   'function Encoder(object, port) {\n  var bytes = [];\n\n  if (object.state && object.state.color) {\n    var colors = ["red", "green", "blue", "yellow", "cyan", "magenta", "white", "black"];\n    bytes.push(colors.indexOf(object.state.color));\n  }\n\n  return bytes;\n}',
  registerOnJoinAccessKey: '' }

I still suspect your provider's firewall for blocking 1900.

rgrygiel commented 5 years ago

What is Your working station? I've just discovered that on port 1900 can be also SSDP running. What i'm reading it can't be disabled on linux machine just like on windows, but can be only blocked by firewall which leads to making circles in my case... any ideas or experience in this case?

johanstokking commented 5 years ago

Port 1900 is used for the outgoing connection so that shouldn't matter.

My environment is macOS Mojave 10.14, node 10.11, yarn 1.10.1, npm 6.4.1, but that shouldn't be related.