Giter Club home page Giter Club logo

pynat's People

Contributors

aarant avatar cscarpitta avatar nathan-muir avatar nomnom-btc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

pynat's Issues

pip install issue

When I use pip install pynat, I get an error because I don't have six installed. It's not good for me to add pynat in requirements.txt. Can the developer please fix this issue?

Can't assign requested address

pynat --source_ip <public IP>
I get the following error,

sock.bind((source_ip, source_port))
OSError: [Errno 49] Can't assign requested address

If i try with 0.0.0.0 which is the default then it works fine. I want to test this against another public ip.

Inconsistent results

Hi, thanks for reviving the old PySTUN! However I've found that the NAT detection is strange and gives results that are later not verifiable. So I would like to share my findings with you, to see if it's possible to improve PyNAT.

PyNAT detects my (consumer-grade, typical home router) NAT as Symmetric, but I don't think this is actually true. From my manual tests, the NAT seems to be Port-Restricted Cone NAT, i.e. ports allow inbound packets if they come from same IP:port than a previously outbound packet was sent, and local outbound ports are kept the same on the external side.

I feel the issue comes from using the STUN response's CHANGED-ADDRESS field, which I didn't know about until I saw it in PyNAT code. Went ahead to have a look at STUN spec: RFC 8489 but it only says that attribute 0x0005 is "Reserved; was CHANGED-ADDRESS prior to [RFC5389]"...

In RFC 5389 they still refer to an even older version of the spec, mentioning that this attribute got removed:

Removed the usage of STUN for NAT type detection and binding
lifetime discovery. These techniques have proven overly brittle
due to wider variations in the types of NAT devices than described
in this document. Removed the RESPONSE-ADDRESS, CHANGED-ADDRESS,
CHANGE-REQUEST, SOURCE-ADDRESS, and REFLECTED-FROM attributes.

I added some logs in the PyNAT code and saw this:

$ pynat 
stun_addr: ('stun.voipbuster.com', 3478)
ext_ip, ext_port: 1.2.3.4 54320  <--- External port = 54320
change_addr: ('77.72.169.213', 3479)
recv_ext_ip, recv_ext_port: 1.2.3.4 1053 <--- Mismatch, 54320 != 1053
Network type: Symmetric NAT 
Internal address: 192.168.1.2:54320 
External address: 1.2.3.4:54320

Where 1.2.3.4 is my public IP address. PySTUN performs a STUN request from internal port 54320, and that's the external port that comes in the response from voipbuster. However, the next request that is done with the change_addr claims a different external port 1053, which is why PyNAT classifies my NAT as Symmetric.

What seems strange to me is that this second port, 1053, is repeated in all tests, even though PyNAT varies the STUN server that is used for each test. If this actually was a Symmetric NAT, the external port should be changing for each different destination, shouldn't it?

Then I went ahead and did this same test on my own. For this I use 2 different cloud servers, I access them with SSH and use Netcat to perform hole-punching on my NAT and later check connectivity. This is the result:

On SERVER 1 (IP: 1.0.0.1): listen for incoming UDP on port 51000.

$ nc -vnul 51000
Listening on 0.0.0.0 51000

On SERVER 2 (IP: 2.0.0.2): listen for incoming UDP on port 52000.

$ nc -vnul 52000
Listening on 0.0.0.0 52000

On CLIENT (IP: 1.2.3.4): Send data from port 55000 to Server 1 and Server 2, i.e. hole-punch the NAT's port 55000.

$ echo "TO SERVER 1" | nc -vnu -p 55000 1.0.0.1 51000
Connected to 1.0.0.1:51000

$ echo "TO SERVER 2" | nc -vnu -p 55000 2.0.0.2 52000
Connected to 2.0.0.2:52000

Data appears on Server 1 and 2 output, confirming that it has arrived correctly:

Connection received from 1.2.3.4 55000
TO SERVER 1

Connection received from 1.2.3.4 55000
TO SERVER 2

On CLIENT: listen for incoming UDP on port 55000 which has been hole-punched in previous commands.

$ nc -vnul 55000
Listening on 0.0.0.0 55000

On SERVER 1: stop listening, and send data to Client.

(Ctrl+C)
$ echo "FROM SERVER 1" | nc -vnu -p 51000 1.2.3.4 55000
Connected to 1.2.3.4:55000

Data appears on Client output:

Connection received from 1.0.0.1 51000
FROM SERVER 1

... confirming that Server 1 can send data. This means there is connectivity to the Client through the port 55000 that was punched before.

On CLIENT: restart the listener (this is needed by Netcat).

(Ctrl+C)
$ nc -vnul 55000
Listening on 0.0.0.0 55000

On SERVER 2: stop listening, and send data to Client.

(Ctrl+C)
$ echo "FROM SERVER 2" | nc -vnu -p 52000 1.2.3.4 55000
Connected to 1.2.3.4:55000

Here is the interesting thing: data appears on Client output:

Connection received from 2.0.0.2 52000
FROM SERVER 2

... confirming that Server 2 can also send data to the same port, and also that when multiple, consecutive outbound connections are made to different servers, the external port is not randomly changed by the NAT.

In principle that reminds of the behavior of Full-Cone NAT, but in reality it is an (Address- and) Port-Restricted NAT. I know because the ports that get opened in the NAT, will only allow inbound packets from the same exact source IP and port. I tested changing the listening ports, or opening a port only for Server 1 and then trying to send data from Server 2, and it didn't work, which means it's not a Full-Cone NAT.

I believe the external port 1053 is maybe an unintended consequence of using an old and now deprecated STUN method to try and force different Address and Port on the STUN responses from the servers, but it could be causing bad detection of NAT types.

I wish I had more time to work on this and provide some code, but right now I only could get time to do this study and write this issue... but what do you think? Maybe it would be possible to use two different STUN servers for testing, like I did by hand in my tests? This would mean that CHANGED-ADDRESS is not needed any more.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.