Python TCP hole punching [closed] - python

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed last year.
Improve this question
I am currently working on a little p2p basic system in python and I would like to know how do you make a TCP hole punch. I already successfully did one in UDP but I want the more organized TCP connection for the rest.
And yes, i've already googled the question but it does not seem that everybody has the same answer nor does it work.

You have to use a little trick. If you know the IP address and port of the peer you want to connect to, say 192.168.1.2:8081 , then you can punch the hole by connecting directly to it (using the same IP, of course) and telling it what your real IP is:
import socket
peer_ip = "192.168.1.2"
peer_port = 8081
my_ip = "192.168.1.1"
my_port = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((peer_ip, peer_port))
sock.send("OPEN %s:%d\n" % (my_ip, my_port))
If you connect to it then the firewall should open a port from your IP address to the peer's IP address and port that you specified in the OPEN command (this is a TCP hole punch protocol called ASYNC3 , which is described on the Async3 website).
To test this, you can use nc to connect to the peer and say hi. This should work if you are behind a NAT and have a firewall (even if it's not the same firewall that opened the hole):
$ nc 192.168.1.2 8081
hello, world!

Related

SSL/TLS find Insecure Connection in VPN Project [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed yesterday.
Improve this question
I write a custom vpn project in python using TUN/TAP interface and UDP Socket connection for my self, and its work fine and every data that comes from the tun will encrypt and will goes through the udp connection securly and in server side comes from UDP and its decrypt and then sends to TUN interface.
in both side ethernet NAT with the TUN and in client its connect to my local.
All Pings transfer completely and all NAT works fine in server and client.
but when i want to open a google website or other websites, browser says ssl/tls insecure connection.
how it can findout this? and whats the way to solve this?
I test the websites from deferent computer in my local network and its not my browser or clock problem.
I know it is the problem of my project or NAT rules, but i dont know where it is?
I test my connection and NAT rulse and all of them works fine, and ping the google website through the VPN transfer completly.
I can ping everywhere but i cannot open any website because of ssl/tls insecure connection.

Scanning Switch for IP and VLAN Details

I've got a Raspberry Pi with Raspbian.
I was hoping to be able to use it to pull a few details from a switch using one of the ports. Similar to the Fluke LinkRunner.
I'm using Python (which I've never used before) and can only get the port IP.
I've done a fair bit of reading on various forums, but can't seem to find anything about pulling VLAN details.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()
This get's me the assigned IP, and that's as far as I've got.
So, my question would be, is it actually possible to pull the Switch IP and VLAN details from a port on the switch?

Bind socket to local IP address blocks while OpenVPN client is running [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 5 years ago.
Improve this question
I have my machine set up with a running VPN client and want to connect to hosts in the internet either through the VPN tunnel or directly via the local interface by specifying the bind address on the sockets. Consider the following code sample:
import socket, subprocess, re
def get_ipv4_address():
ifc_resp = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE).communicate()
patt = re.compile(r'inet\s*\w*\S*:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
return patt.findall(ifc_resp[0])
def check_sock(addr):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((addr, 0))
s.connect(("www.google.com", 80))
s.close()
def main():
addrs = sorted(a for a in get_ipv4_address() if not a.startswith("127.0."))
print "Checking addresses " + ", ".join(addrs)
for addr in addrs:
print "Connecting via " + addr
check_sock(addr)
main()
When I run this, the connection can be set up without problems through the VPN IP address. Though the program hangs on connecting to the local network on connect:
>>> python binddemo.py
Checking addresses 10.200.195.233, 192.168.2.33
Connecting via 10.200.195.233
Connecting via 192.168.2.33
^CTraceback (most recent call last):
File "binddemo.py", line 22, in <module>
main()
File "binddemo.py", line 20, in main
check_sock(addr)
File "binddemo.py", line 12, in check_sock
s.connect(("www.google.com", 80))
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
KeyboardInterrupt
I don't understand why this is happening, as the local NIC should still have a route correctly set to reach out to the internet:
>>> ip route
default via 10.200.195.1 dev tun0 proto static metric 50
default via 192.168.2.1 dev wlan0 proto static metric 600
10.200.195.0/24 dev tun0 proto kernel scope link src 10.200.195.233 metric 50
62.113.253.4 via 192.168.2.1 dev wlan0 proto static metric 600
169.254.0.0/16 dev wlan0 scope link metric 1000
192.168.2.0/24 dev wlan0 proto kernel scope link src 192.168.2.33 metric 600
Connections specified to a plain IP address (instead of the google host) equally fail, so I suppose it's not the DNS lookup making trouble. Any ideas how to fix that or at least further investigate?
Using bind() on a client socket that is not going to listen() is not doing anything. What interface is used for outgoing connections is entirely dependent on your routing configuration.
You have setup two default gateways but the one that goes to your wlan interface has a higher metric than your tunneling device. So linux is always going to use the tuneling interface as the default gateway.
Here is a good, more in-depth explanation: https://serverfault.com/questions/648276/routing-selection-specificity-vs-metric
[Edit 1]
After looking at your routing table more closer, removing the default gateway for the tunneling device should solve your problem, because you also have a net route setup that should route all traffic to your vpn correctly. So try removing this one:
default via 10.200.195.1 dev tun0 proto static metric 50
because this one will route your vpn traffic through tun0:
10.200.195.0/24 dev tun0 proto kernel scope link src 10.200.195.233 metric 50
[Edit 2]
If you want to keep the default route via the tunneling devices, you could use network namespaces: https://superuser.com/questions/241178/how-to-use-different-network-interfaces-for-different-processes/750412#750412
You will still not be able to access both networks from a single program though.
What finally worked out:
echo "1 localwlan" >> /etc/iproute2/rt_tables
ip route add default table localwlan via 192.168.2.33 dev wlan0
ip rule add from 192.168.2.33 lookup localwlan
Thanks #Christian Eichelman for pointing me in the right direction

How to know whether a port is open/close in socket programming?

If a socket program runs on a port(say 6053) and if the rule is not added in the firewall the functions recv read and recvfrom are blocked.
How do we check this in C or python and report Port not opened error on linux machines.
Try to connect on that port using socket.connect(), if connection is not successful, then show message that Port not opened.
Tools like nmap can help in determining whether the particular port is open or closed.
TCP :
nmap uses techniques like TCP SYN scan or TCP Connect scan where the server will reply with ACK-RST packet for SYN request incase of closed port. You can notice that, it is determined at the time of 3-way handshake (connection establishment) itself.
UDP : nmap also facilitates the UDP scan, where ICMP based 'Port Unreachable' packet shall be returned in case the UDP packet arrives on a closed UDP port (This also depends on the stack in the OS). Unlike TCP, the UDP is not a connection-based protocol and ICMP is also connection-less, so you might need to send some significant number of UDP packets for a short interval and evaluate based on the responses or some similar logic.
You can arrive on similar technique/logic and determine whether the particular port is open or closed and flash appropriate message for user.

How to send a message in a specific port with python sockets ? No random ports

I have to test a broadcast with acknowledgement on localhost. So I have some text files that represent the nodes and inside there is a list of neighbors.
I use localhost as the IP and the port is the number of the node.
The problem is when I receive a message (that I sent) from a node like 7000, python replaces it with a random number for example 65724. So now my father is 65724 instead of 7000, so I cannot remove 7000 from the list of neighbors.
I cannot complete my algorithm and that is very frustrating.
I can send a message with the port number that I want, but it's not very elegant.
Could someone tell me how to not allow python to randomize the port?
rmunn saved me, the answer I was looking far is the bind before connect method. Befor sending a message you bind your own port and you connect to the other one.
This is not a Python problem, per se. You are confused about how ports work.
Each TCP communication (sending or receiving) has two IP addresses and two ports: the host IP and host port, and the destination IP and destination port.
If you're communicating with a computer "out there" on the network, your host and destination IPs will be different. In your test case, your host and destination IPs will both be 127.0.0.1 (localhost). But I'm going to go with the "different IPs" case for my example, because it makes it easier to see.
So your IP address is, say 10.1.2.3, and you're talking to a computer at 10.1.2.99. You tell the system that you want to talk to 10.1.2.99 at port 7000, and it opens up a connection. When that happens, it will randomly pick a source port that's not in use. So now there's a two-way communication channel open:
10.1.2.3:65274 <-> 10.1.2.99:7000
Note that you did not pick that host port. EDIT: I originally said "In fact, the system will not allow you to pick the host port; it will be assigned to you" here, but that is wrong. If s is a socket object, you can call s.bind() to set its source port, then call s.connect() to connect to a destination port.
Now, when you're listening for a message, then you pick the port you're listening on, and the computer that's connecting to you will have a random port. So if you were listening for a message on port 8912, the incoming connection (once established) will look like:
10.1.2.3:8912 <-> 10.1.2.99:38290
Note that 38290 was chosen at random by the operating system of the computer at the 10.1.2.99 IP address.
Now for the bit of Python. You mention sockets in your question title, so I'll assume you're using the socket module from Python's standard library. Once you've created a socket object s, use s.getpeername() to find out the address (host and port) that you've connected to, and s.getsockname() to find out the address (host and port) that you've connected from.
Since you talk about expecting the number 7000 and getting a random number, I think you're using the host socket when you should be using the destination socket.

Categories