I am building python p2p application like p2p instant messenger. I am communicating with other peers using TCP/IP connection. I do not want client to do port forwarding.
When application starts it should check whether port is forwarded to router if not it should forward it to router.
Is it possible to programaticaly forward the port to router. Or how can I use port 80 for p2p communication as its used by browsers.
You may find the post and files listed here helpful. This person implemented a Nat PMP library in Python.
http://blog.yimingliu.com/2008/01/07/nat-pmp-client-library-for-python/
If you want to use port 80 for p2p communication, you will simply just need to write your own protocol in HTTP and connect over port 80.
Related
I understand the upgrade handshake and then the creation of the WebSocket channel on a totally different socket, but I'm puzzled as to why this is not a problem when firewalls may block all traffic except that which is bound for 80 (or 443). It seems that the WebSocket traffic hosted at its own (non-80, non-443) port would get blocked -- but clearly WebSockets are mature and effective so I must be missing something. How does the WebSocket traffic on the non-80/non-443 port traverse firewalls? Is this related (no pun intended) to routing rules ESTABLISHED/RELATED? The following seems to come close to a solid answer:
https://stackoverflow.com/a/2291861/6100445
...that is, the WebSocket traffic is established in an outbound sense from the browser over HTTP and then established in an outbound sense from the WebSocket server over the new WebSocket port?
WebSockets are "designed to work over HTTP ports 443 and 80":
https://datatracker.ietf.org/doc/html/rfc6455
(also https://en.wikipedia.org/wiki/WebSocket)
But many tutorials launch separate WebSocket servers on totally different port numbers (e.g. 8001 is used commonly). A good example is the websockets package on PyPI, which uses port 8001 and flatly states WebSockets and HTTP servers should run on separate ports:
https://websockets.readthedocs.io/en/stable/intro/tutorial1.html
https://websockets.readthedocs.io/en/stable/faq/server.html#how-do-i-run-http-and-websocket-servers-on-the-same-port
A lot of material on the Web is hand-waving and glosses over some detail with statements like WebSockets "use the same port as HTTP and therefore get through firewalls" (I assume they mean the upgrade/handshake portion) but many other sources indicate that a WebSocket server (on the same computer as the HTTP server) should be established on a different port (I assume because the HTTP server is already bound to 80 (or 443), and this different non-80/non-443 port therefore carries the upgraded WebSocket traffic). The separate ports make sense from a TCP/IP socket binding perspective. What am I missing about how WebSockets use 80 (or 443) for the upgrade/handshake, a separate port for the WebSocket established traffic, yet still work through firewalls where the only traffic allowed is that which is destined for port 80 (or 443)?
I've setup a webhook using ngrok and flask. The port I'm using is 5000.
https://ngroksfakeaddress.ngrok.io -> http://localhost:5000
Would I need to reserve that in my Windows firewall to prevent the port from being used by another program?
If I did what paramaters would i need to put in? e.g. UDP, TCP, inbound or outbound or both?
I'm developing a simple Flask based server that can communicate with peer applications (other similar servers) on internet. The application can be behind a NAT. So I'm trying to resolve the external IP and port through a stun server by using pystun.
import stun
nat_type,external_ip,external_port=stun.get_ip_info()
The port returned is 54320. Problem is when I try http://external_ip:54320 the request is not reaching the Flask app. http://external_ip:5000 is also not working, 5000 being the internal port used (I know this should not work, but tried it anyways). There are no firewalls. I have run Flask with host="0.0.0.0".
to add.. i dont want to do explicit port mapping in the router.. is there a way flask can listen to a port that is accessible from external addresses and figure out external port through stun?
It is very difficult to host a server behind a NAT without doing an explicit port mapping. The NAT is also acting as a firewall. The node behind the NAT can make outbound TCP connections, but the NAT will block any inbound connections.
STUN doesn't help here because it only helps nodes behind NATs discover their own port mappings. To allow connection to be established after STUN, you typically have to do a hole punching step, which involves both endpoints simultaneously trying to connect to each other.
The one idea you could try is to use UPNP, which is a protocol that many NATs support for dynamically creating port mappings. There's some opens source libraries that might work.
But the easier solution is to just configure your NAT to have an explicitly port mapping. (e.g. port 50000 maps to your PC's internal IP address at a specific port).
I am using a library (ShareDB) for operational transformation, and the server and client side use a websocket-json-stream to communicate. However this ShareDB is being run on nodejs as a service (I'm using zerorpc to control my node processes), as my main web framework is Tornado (python). I understand from this thread that with a stateful protocol such as TCP, the connections are differentiated by the client port (so only one server port is required). And according to this response regarding how websockets handle multiple incoming requests, there is no difference in the underlying transport channel between tcp and websockets.
So my question is, if I create a websocket from the client to the python server, and then also from the client to my nodejs code (the ShareDB service) how can the server differentiate which socket goes with which? Is it the servers responsibility to only have a single socket 'listening' for a connection a given time (i.e. to first establish communication with the Python server and then to start listening for the second websocket?)
The simplest way to run two server processes on the same physical server box is to have each of them listen on a different port and then the client connects to the appropriate port on that server to indicate which server it is trying to connect to.
If you can only have one incoming port due to your server environment, then you can use something like a proxy. You still have your two servers listening on different ports, but neither one is listening on the port that is open to the outside world. The proxy listens on the one incoming port that is open to the outside world and then based on some characteristics of the incoming connection, the proxy directs that incoming connection to the appropriate server process.
The proxy can be configured to identify which process you are trying to connect to either via the URL or the DNS hostname.
I am hosting a http server on Python using BaseHTTPServer module.
I want to understand why it's required to specify the IP on which you are hosting the http server, like 127.0.0.1/192.168.0.1 or whatever. [might be a general http server concept, and not specific to Python]
Why can't it be like anybody who knows the IP of the machine could connect to the http server?
I face problems in case when my http server is connected to two networks at the same time, and I want to serve the http server on both the networks. And often my IP changes on-the-fly when I switch from hotspot mode on the http server machine, to connecting to another wifi router.
You must specify the IP address of the server, mainly because the underlying system calls for listening on a socket requires it. At a lower level you declare what pair (IP address, port) you want to use, listen on it and accept incoming connexions.
Another reason is that professional grade server often have multiple network interfaces and multiple IP addresses, and some services only need to listen on some interface addresses.
Hopefully, there are special addresses:
localhost or 127.0.0.1 is the loopback address, only accessible from local machine. It is currently used for tests of local services
0.0.0.0 (any) is a special address used to declare that you want to listen to all the local interfaces. I think that it is what you want here.
Try running it on 0.0.0.0, this accepts connections from all interfaces. Explicitly specifying the IP is a good practice in general (load balancing, caching servers, security, internal netwrok-only micro services, etc), but judging by your story this is not a production server, but some internal LAN application.