I have a web page to control a thermostat on a raspberry pi, and I'm running into difficulties when trying to get websockets to work from a remote client. It seems to work fine when on LAN however. I'm obviously missing something (and likely something basic), but I can't seem to figure out what it is.
The pi's local ip is 192.168.1.134. The web page (served from apache server) has the URL http://192.168.1.134:8010/thermostat.html. The page starts up some javascript, which then tries to connect to the pi's main program using websockets via ws://192.168.1.134:9000. (the server on the pi is running libwebsockets). The websocket comes up, and it seems to work fine. I then tried to connect via a remote client (a cell phone, where wifi was turned off) from http:\\23.239.99.99:8010\thermostat.html. The html/js files load fine, but the web socket attempts to connect to uri ws:\\23.239.99.99:9000, and this fials.
As far as I can tell, the NAT seems to be configured properly:
name ext ext protocol int int ip addr interface
port port port port
start end start end
Thermostat3 8010 8010 TCP 8010 8010 192.168.1.134 eth3.1
Thermostat5 8000 8000 TCP/UDP 80 80 192.168.1.134 eth3.1
Thermostat_ws 9000 9000 TCP/UDP 9000 9000 192.168.1.134 eth3.1
I checked, and the router does not have any firewalls set up, neither does my modem. I didn't install a firewall on the pi (I checked, and there's no odd iptables rule). Does anyone know what I'm missing?
--- EDIT ---
I'm still stuck on this. I called my ISP and they assure me there are no firewalls on their servers. Is there any way to tell if port 9000 is being blocked, and by who?
Bind your apache server to 0.0.0.0 address to make it accessible from remote machines
Try this tool to determine if the port is inaccessible (use the custom port): http://www.whatsmyip.org/port-scanner/
Everything else looks fine. As a sanity check I would try putting the ws port to 8010 to see if that works. I would also recommend using a tool like Advanced Web Client to isolate networking issues.
This is interesting. I once had a similar problem. I set up a WebSocket (I was using a nodejs ws) and once I tried to access it from remote client I was not able to reach it with ws://yourip:port but instead I had to use http://yourip:port. I don't know if you have the same problem, mine was due to a proxy I was using.
I still have an advice for you how you might be able to solve your problem. I don't know how concerned you are about security but as far as I understood your idea you basically connect to your raspberry pi through a WebSocket and tell it to change the temperature.
Back when did a similar project I found it rather hard to secure my WebSocket connection. I was basically sending a password plus command through the WebSocket to my server which then checks wether the password is correct. Otherwise everyone on the internet could heat your house. Not cool...
But therefore, I had to tunnel the connection through https to prevent a middleware attack.
I quickly threw the towel and decided to go with a completely different solution. Basically I set up a nodejs express server (can easily be configured with a self signed certificate to use https or used behind a nginx/apache https server) and authenticated with username and password. When someone made a POST request to /api/thermostats?id=0 with a temperature request, the server checks if the user is authenticated and then executes a terminal command from within node.
Maybe this idea also fits your demands.
Related
im trying to setup a redirection towards an app that im writing in Java. This app opens a port 8443 on my laptop (which is a MacOS 10.10 Yosemite) and offers a HTTPS service.
The big plan is to have another device connecting to an access point that im setting up on my laptop and when it connects to any ip/domain on 443 this traffic is redirected to my local machine on port 8443.
I need to redirect traffic that im getting on 443 to 8443. I kinda might have gotten a solution for this using the following guide: http://www.abetobing.com/node/81, and changed the rule to rdr pass on lo0 inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
But this rule only works locally if im right about that. So only traffic coming from my own laptop is redirected. if im trying to open https://192.168.178.25/ on another machine it doesn't work, but https://192.168.178.25:8443/ does.
Additionally i also was able to change a domain via the /etc/hosts file. That only works for local connections and for single domains if im right. So the second step would be to redirect ALL possible domain names to my ip. I think this should be possible with kinda of a proxy service, but since i am new to this topic I haven't found a solution that is working for me.
At the moment I am using 2 Wifi devices and the MacOS Internet share. My USB wifi card is connected to a router and internet. My internal wifi card opens an access point (it says hotspot) and offers the internet connection of the other device. This is annoying, since the USB wifi connection always has to work, otherwise MacOS will shut down the access point. The best solution would be a software opening a reliable access point with the internal wifi card (haven't had any success with the Mac OS ad-hoc network)
I would be so glad if someone would be able to help me out with any of the 3 single parts. Thank you already :)
I've created a simple client/server program with the help of winsock in vb6. It perfectly works on LAN but the problem is it doesn't work on WAN. All ports are already open, Firewall is already Off, I have dynamic IP so I used No-ip to get named IP address.
One more think I want to ask is , is it important to open port on both client and server? For eg- I've created the program on port 50505 and on the client computer the port is open but is it important to open 50505 on server also??
Here is my project.
If anyone could find the problem please let me know. I would appreciate a lot
Okay, first make sure that in the client side program that the Localport is not set to anything because Windows will assign it one, but the RemotePort is set to 50505. On the server side, the RemotePort is set to nothing, and the LocalPort is set to 50505.
Next you need to make sure your server has a static IP on your network.
So if your router's LAN IP is 192.168.1.1 you need to set your server's to
something like 192.168.1.50, just make sure that it doesn't get put in the range or the
DHCP server (That's the server that gives each computer a IP address from the router).
Next you need to setup your router for "Port forwarding". Be default your router had no idea what to do with data that the internet sends to it. You have to setup the router to forward any data from port 50505 to your server on your network.
While this seams really long and drawn out, it shouldn't take more than 5-10 min's to setup.
Good luck!
You need to configure the router that the server is behind to forward connections on that port to the computer running the server.
Otherwise, the client will not be able to connect to the server.
This is part programming, part sysadmin, so please excuse me if you feel that this should be over on serverfault.
I have an application that is not SOCKS aware and that we need to use through a firewall. We cannot modify the application to have SOCKS support either.
At the moment, we do this by aliasing the IPs the application talks to the loopback adapter on the host, then creating SSH tunnels out to another host. The IP's the application uses are hardcoded. Our SSH connections look like:
ssh -L 1.2.3.4:9999:1.2.3.4:9999 user#somehost
Where 1.2.3.x are aliases on the loopback.
So the application connects to the open port on the loopback, which gets sent out to the SSH host and onto the real 1.2.3.4.
It works, but the problem is that this application connects to quite a few IPs ( 50+ ), so we end up with 50 ssh connections out from the box.
We've tried to use several 'proxifying' apps, like tsocks and others but have had alot of issues with them ( the app is running on OS X and tsocks doesn't work so well, even with the patches )
Our idea was to write a daemon that listened on all interfaces on the specified port - it would then take the incoming packets from the application, scrape the packet info ( dst IP, port, payload ), recreate the packet and proxify it through a single SSH SOCKS connection ( ssh -D 1080 user#somehost ). That way, we only have 1 SSH connection that all the ports are being proxied through.
My question is - is this feasible? Is there something that I'm missing here? I've been combing through pfctl, ipfw, iptables docs, but I don't see any option to do it through those and this doesn't seem like it'd be the most difficult thing to code. It would recreate the packet based on the original destination IP and port, connect to the local SOCKs proxy and resend the packet as if it were the original application, but now with SOCKS support.
If I'm missing something that someone knows about that already does this, please let me know. I don't know socket programming or SOCKs too well, but this doesn't seem like it'd be too big of a project to tackle, but I'd like some opinions if I'm biting off way more that I should.
Thanks
If your application could add SOCKS client support, you can simply ssh -D lock_socks_port remote_machine, which will open up the local *lock_socks_port* as a SOCKS server at localhost, which can then connect to any host accesible by the remote machine.
Example: imagine you are using an untrusted wifi network without encryption. You can simply launch ssh -D 1082 home, and then configure your web browser to use localhost:1080 as SOCKS server. Of course, you need a SOCKS-enabled client. All the traffic would appear as coming from your gateway, and the connection would be opaque to those snooping the wifi.
You can also open a single ssh client with an indefinite number of LocalForward requests, which would be tunneled on top of a single ssh session.
Moreover, you can add ssh connections to an already-established ssh connection by using the ControlMaster and ControlPath options of ssh.
I am trying to find somw Windows based tools that can help me validate TCP and UDP connection on remote machines.
My Problem (just one use case):
At work, I manage many clustered servers that I run load tests against. In order to get a rich test, I use Jmeter-Plugins which provides a Server agent that opens a TCP socket on port 4444 on a target remote machine: http://code.google.com/p/jmeter-plugins/wiki/PerfMonAgent
There are many times when I setup a new load test farm, that either the network, or the server configuration, or the ServerAgent itself can have issues and thus not allowing a Load test client to access that TCP connection.
The issue I have is that I dont know what part of the system is broken.
What I think I need:
I would like to know how I can open a TCP (not HTTP with cUrl), connection to a remote server to validate that the network allows the connection, as well as the Server firewall allows the given TCP connection to be accessed remotely.
What I have looked:
These are some of the tools I have looked at so far:
Nmap http://nmap.org
Ncat http://sourceforge.net/projects/nmap-ncat/
TCP/IP Builder http://www.drk.com.ar
Zenmap 6.01 and nmap might do the job I want, but some machines where not accessible to Zenmap when I know 100% that the server was accessible via HTTP, so that was strange.
I have looked at many tools and either they:
Dont allow remote connections
Dont seem to want to connect to a TCP socket
Or I dont understand the tools to accomplish the validation I stated above.
I would greatly appreciate all comment and suggestions to help with this re-occurring problem I face.
Mick,
Firebind.com can do what you'd like to do. Firebind is an Internet based server that can listen on any of the 65535 UDP or TCP ports. It uses a java based client to send traffic to and from the server from your machine.
Carl
www.firebind.com
If I create a c++ server/client application, the port I used to communicate does it need to be open on the router of the server and client machine
Or what other approach could I take? the client computer needs to receive information from the server but I am not able to have any ports opened because it is on a school network....
[edit]
Hmm My setup is a php page running on a server say when I press hello, the server makes a ssh connection through php and sends shell commands to the machine. The server is running off of a school server which I do have ssh access to and run all my things from there. The client computer will be my pc running off of the school wifi which is not connected to the server. The server will try to make a ssh connection to the public ip of my computer running off of the school wifi(no ports open/can ssh out but no ssh in). Will these methods you mention make this possible, in particular the connect.c since I can't run putty off of the server, and the connect.c I could call from the php.
The choice of language is highly irrelevant here.
There don't need to be ports 'open' on any router, unless your traffic must pass through it. On normal peer hosts in the same network (or subnet) there would hardly be any firewall policy, not even in schools.
Technically it is possible for the switch to block peer-2-peer traffic (meaning traffic not destined to the outgoing gateway), but that is not very usual.
Of course, if the school doesn't allow outbound (WAN) traffic on most ports, tough luck, and they're absolutely right :)
You can look at
ssh (with tunnels -L, -D and -R options, perhaps -o GatewayPorts on)
stunnel
connect.c
http-tunnel
All very readily googled
To establish a TCP/IP connection, only the server port needs to be accessible by the client. The connection is full-duplex, therefore data can flow from the client to the server and vice-versa.
If you are using UDP for your application, which is a connection-less protocol, what happens depends heavily on the firewall or router and whether it performs connection tracking for your service or not.
Unless you provide some additional information on your service and the network setup on both the client and the server side, we cannot provide more concrete information.