Get caller's IP in Pyro4 application - python

To cut the story short: is there any way to get IP of untrusted client calling remote proxy object, using Pyro4?
So person A is calling my object from IP 123.123.123.123 and person B from IP 111.111.111.111 is there any way to distinguish them in Pyro4, assuming that they cannot be trusted enough to submit their own IP.

I ran across your question when looking for the same thing. If I understand, on the server side you want to know the IP address the client's socket is connected from, right? If so, this'll do it:
Pyro4.current_context.client.sock.getpeername()[0]
Found that in this section of the Pyro4 user's guide

Here is my solution to my problem: since I didn't really need to get specific addresses of clients using pyro, just to distinguish clients in specific subnet (in my classrom) from other ips (students working from home). I just started two pyro clients on two ports and then filtered traffic using a firewall.

Related

What is the purpose of bindaddress in scrapy?

In documentation we can read:
"The IP of the outgoing IP address to use for the performing the request."
That is not clear for me. Anyone can explain with more details what is the purpose of bindaddress ?
The computer where Scrapy is running might have multiple network connections, each with their own unique IP network address (or addresses, plural). For example, a laptop might have a WiFi connection and a wired Ethernet connection. A larger server-class system might have several Ethernet connections. Even a system that has a single network connection might have multiple IP addresses, some for IPv4 and others for IPv6.
The bindaddress option can be used to tell Scrapy which one of those local IP addresses should be used as the source address on its outgoing requests.
If you don't specify which local address you want Scrapy to use, then Scrapy will let the system choose the address. That choice is usually the local address that the system thinks is "closest" to the destination address of the request. This would be the usual situation. Unless you have a particular need to use a specific source address, there's no reason to use the bindaddress option.

Python 3: how to get nic from which will be sent packets to certain ip?

I have machine with multiple NICs that can be connected to one net, to different nets or every other possible way. Python script that uses requests module to send POST/GET requests to the server is ran on that machine.
So, the question is next: how can I know in python script from which interface requests will be sent?
Here there are two different answers. The one is for the case where you want to specify the NIC to send the request and the other is for what you're asking: find the correct NIC.
For the second answer, I can only say that it depends. Are these NICs on the same network / subnet? Are they bonded?
If they are on a different network then you can know the host IP Address and use the computer's routing table to see which NIC the packet will go through. If they are bonded on the same network then the request will leave from the bond interface since it is (normally) the one with an IP Address. If they are on the same network and have a different IP on the same subnet then it depends. Can you provide some more information in that case?

Can sockets be used to connect multiple computers on different networks in python? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have been looking all over the internet for an answer but haven't been able to find one as of now. I am extremely new to networking so please do accept that I hardly know anything about it. I am able to send data to and from computers on a LAN network using sockets but I want to know if it is possible to connect to a computer at my friends house per say and send data to and from our computers solely using sockets (no telnet or netcat servers). Or is this impossible and should I be looking at a different python library or should I set up some sort of server which both machines would connect to?
Any help would be greatly appreciated and please take into account that I am new to this...
Sockets should work, but there are some caveats:
If the server (assuming you are using TCP sockets) is behind a firewall or NAT (typically if you have a router) you will need it to be configured to redirect the port on the public interface (visible from the Internet) to the local port.
You will need to know your friend's public IP or hostname to connect to them.
If your networks look like this:
+---------------+ +-----------+ +--------+ +---------------+ +------------------+
| Your computer |-->|Your router|-->|Internet|-->|Friend's router|-->|Friends's computer|
+---------------+ +-----------+ +--------+ +---------------+ +------------------+
192.168.0.5 host.isp.com friend.isp.com 192.168.2.55
And your friend is running the server on his local network, on port 9000 (for example), then you'd connect to friend.isp.com:9000. If their router is configured to redirect traffic on port 9000 on the friend.isp.com interface (internet) to 192.168.2.55 (local machine) then a connection should be established correctly.
It is possible but it will require some configuration on the router of your friend. The reason is that nowadays everybody has a public IP address that is provided by your service provider. This IP address is not fixed per se, but it is easy to lookup what is the current IP# https://www.whatismyip.com/
Now sending is not going to be a problem, but receiving is. Some service providers like here in Belgium Telenet don't allow just any port to be used and you have to find out which ports are allowed. The well known ports are most likely not allowed. That for instance makes it impossible to host a webserver without first contacting your ISP. Port 10000 for instance will work. Contact your ISP to find out these kind of limitations.
Next problem is that your both have a router and a private network with private IP# behind a NAT/PAT enabled router. For instance if I do ipconfig on my pc I get following IP# 192.168.1.99. This IP# is unique behind my router, but it is not unique on the whole internet so these IP# cannot be used directly when communicating over the internet. So the router is going to use NAT/PAT and some lookup table that is filled based on the outgoing packets. You send something, the nat/pat table is build, your private IP# is replaced with the public one and an allocated port. When a reply comes to you the port is used to change it back to the IP# of the original request. For this reason sending is not a problem but receiving is.
To solve this problem your friend has to setup port forwarding or put a pc in a demiliterized zone, it depends on the router in question. Port forwarding is like manually filling the NAT/PAT table with an entry. If something arrives on this port, send it to that private IP# using that port.
Next problem on both sending and receiving machines is the firewall. The firewall has to be switched off or configured to allow outgoing and incoming traffic on the ports that you are planning on using.
If you understand all that then you can make it work. But if this is all Chineze to you, then you will have a lot of difficulties to make it work.
So conclusion is that it is possible but there are quite some caveats to tackle.
There are many questions of people that are trying to do exactly what you describe here and have a lot of trouble making it work. If you are really a novice I would try to find somebody with experience or you will lose your hair trying.(by pulling it out yourself from frustration)
The fact that you are using python or any other programming language is not relevant in this discussion. It is pure a networking question.
More about NAT/PAT : http://www.webopedia.com/DidYouKnow/Computer_Science/NAT_and_PAT.asp
The major (abstract) idea is simple. You have two node (computers) in a network (this time internet), so you should be able to connect both of them together.
You can establish a tcp connection between them.
Sockets are just fine for your case, all you need is a public IP for each one of them and a free port in each node. You can select your ports from this range.
Python provides a socket module , check it, it is very simple and easy. You may have a look at some examples as well.
However practically speaking, you would need the open these ports in the firewall, and also do some configuration depending on your operating system to allow this kind of communication.
Yes it is possible.
All you need is the hostname or IP address and port number of the computer that you want to connect to. As long as a route can be established to the remote machine, a connection can be made.
Look at the socket module. Here's a simple example:
import socket
s = socket.socket()
s.connect(('123.123.123.123', 10000))
This will attempt to establish a TCP connection to the remote machine with IP address 123.123.123.123 on port 10000. The remote machine will need to have port 10000 open, i.e. a service listening for connection on that port, as well as port 10000 being open in any firewall device.
Instead of the IP address, you can also use a host name:
s.connect(('remote.host.com', 10000))

Python port forwarding

I'm developing a client-server game in python and I want to know more about port forwarding.
What I'm doing for instance is going to my router (192.168.0.1) and configure it to allow request for my real IP-adress to be redirected to my local adress 192.168.0.X. It works really well. But I'm wondering if I can do it by coding something automatically ?
I think skype works like a kind of p2p and I can see in my router that skype is automatically port forwarded to my pc adress. Can I do it in Python too?
There are different solutions here, but most are not trivial, and you'll have to do some reading, and you'll need some kind of fallback.
UPnP/IGD is the simplest. If your router supports it, and is configured to allow it, and you know how to write either low-level networking code or old-fashioned SOAP web service code, you can ask the router to assign you a port. If it responds with success, start using that port and you're basically done.
If you can run a (very low-bandwidth) server with a public address for all of your users, Hole punching may solve the problem.
Think about how a behind-the-NAT client talks to a public server. You make a request to some IP and port, but the server is seeing your router's IP, not yours (which is a good thing, because yours isn't accessible). When it replies, your router has to know to forward it to you—which it does just by remembering that you're the behind-the-NAT client that just sent a request to that server.
What if, instead of talking to a public server, you talk to some other peer behind his own separate NAT? Well, Your router doesn't know the difference; as long as you get a response from the same place, it'll get through. But how do you get a response, when your message isn't going to get through his NAT? He does the same thing, of course. One of the messages may get lost, but the other one will get through, and then you're both set and can communicate. You will need to send keep-alives regularly so the router doesn't forget you were communicating, but other than that, there's really nothing tricky.
The only problem is that you need to know the public IP address for the other peer, and the port that he's expecting you to come from, and he needs to know the same about you. That's why you need a server—to act as an introducer between peers.
Hole punching will work with UDP from most home networks. It won't work with TCP from many home networks, or with either UDP or TCP from many corporate networks. (Also, in corporate networks, you may have multiple layers of NATs, which means you need introducers at every interface rather than just one on the internet, or symmetric NATs, which can't be punched.)
You can use STUN (or similar) services like ICE or TURN. This only works if there is an ICE, TURN, etc. service to use—which is generally not the case for two peers on different home NATs, unless you deploy your own server and build an introducer to help out, and if you're going to do that, you can just use hole punching. But in a corporate environment, this can be the best way to provide connectivity for P2P apps.
Finally, you can make the user configure port-forwarding manually and enter the forwarded port number into your problem. This is not ideal, but you should always provide it as a fallback (except maybe for apps meant only for corporate deployment), because nothing else is going to work for all of your users.
I believe Skype uses all of these. If you enable UPnP, it tries to IGD your router. Or you can configure it to use a TURN server. Or you can just enter a specific port that you've forwarded manually. If you do none of the above, it tries to use UDP hole punching, with an introducer that Skype runs.
So your application needs to do TCP/UDP networking if I understand correctly. That means that at least one of the connecting clients needs a properly open port, and if both of them is behind NAT (a router) and have no configured open ports, your clients cannot connect.
There are several possible solutions for this, but not all are reliable: UPnP, as suggested here, can open ports on demand but isn't supported (or enabled) on all routers (and it is a security threat), and P2P solutions are complex and still require open ports on some clients.
The only reliable solution is to have a dedicated server that all clients can connect to that will negotiate the connections, and possibly proxy between them.
You could look at something like this (assuming your router supports it): http://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal
For implementing port forwarding using python, there's a fantastic ActriveState recipe that does asynchronous port forwarding server using only Python standard library (socket, syncope). Look at
http://code.activestate.com/recipes/483732-asynchronous-port-forwarding/

Python socket chat problems

I've found a code for a chat app in Python, but I can't find anything about the author or anyone on the site to help me with it..
this is a link to the whole code:
http://files.myopera.com/manojsheokand666/blog/chat.py
I'm getting a feeling something is missing.. and I need this, I want to modify it and try to learn something more
I did some reading and this is my third time editing this post..
NOW, I'm able to stay connected without getting any error, but when I try to send(type in) something it's not sending nor receiving. But whenever I try to run a second app as another "person", I am getting a message on the first running app that "person" has connected, and the first app crashes with this error:
KeyError: ('127.0.0.1',62833) - note, the port is always diferent
While, the second app stays but it's not receiving anything or crashes if I run the app again.
What I did:
host = gethostbyname(gethostname()) #this actually gets 192.168.0.101 (my local IP to the router)
s.setsockopt(SOL_IP,IP_ADD_MEMBERSHIP,\
inet_aton(addr)+inet_aton(host)) #i write 225.0.0.1 as 'addr'
Is there other way to get this working? I can run a simple server/chat using telnet but this GUI(tkinter) think makes it complicated for me, and I want to learn how this works..
Thanks!
From the definition of the IP_ADD_MEMBERSHIP option, the first address is a multicast group address and the second is an interface address.
You are using 127.0.0.1 as the first address. This is not a multicast address.
Multicast addresses are in the range 224.0.0.0/4 (i.e. 224.0.0.1 to 239.255.255.254, not including network and broadcast addresses).
For example, using the first (all hosts on same network segment) multicast address works just fine:
>>> s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
>>> s.setsockopt(socket.SOL_IP,socket.IP_ADD_MEMBERSHIP,
socket.inet_aton('224.0.0.1')+socket.inet_aton('0.0.0.0'))
Check this reference for more information about multicast addresses.
So you need to choose an unassigned multicast address in 224/4 for your application and use that (e.g. anything in the ad-hoc range, like 244.0.2.0). Note the multicast address has nothing to do with the interface address (using '0.0.0.0', you associate all local interfaces with the multicast address, meaning all interfaces can be used to receive/send multicast packets for that group).

Categories

Resources