So I have a python script that needs to send a packet to my server 'x.x.x.x'. I've been able to successfully initialise Tor through Python by setting up the SOCKS5 proxy, but upon trying to send a packet to my server I get the error:
Traceback (most recent call last):
File "test.py", line 18, in <module>
sock.sendto(bytes, ("x.x.x.x", 6000))
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 338, in sendto
self.bind(("", 0))
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 325, in bind
_, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst)
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 494, in _SOCKS5_request
raise SOCKS5Error("{0:#04x}: {1}".format(status, error))
socks.SOCKS5Error: 0x07: Command not supported, or protocol error
From what I've seen, socket/SOCKS5 doesn't support connectionless UDP, so I attempted connecting to the port and then sending the packet once connected. I still get the same error as seen above, output can be seen below.
Traceback (most recent call last):
File "test.py", line 18, in <module>
sock.connect(("x.x.x.x", 6000))
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 698, in connect
self.bind(("", 0))
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 325, in bind
_, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst)
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 494, in _SOCKS5_request
raise SOCKS5Error("{0:#04x}: {1}".format(status, error))
socks.SOCKS5Error: 0x07: Command not supported, or protocol error
Seeing as a UDP connection does not work either, I would prefer to stay connectionless as this makes my intended use simpler as the port is not necessarily active/open at any given time. The script I'm using to attempt to send the packet can be seen below. I've added but commented out the connectionless and connection methods I was using. Ignore all the extra imports at the top, these are for use later in the script development.
import socks
import socket
import requests
from TorCtl import TorCtl
import urllib2
import random
import math
import time
socks.setdefaultproxy(proxy_type=socks.PROXY_TYPE_SOCKS5, addr="127.0.0.1", port=9050)
socket.socket = socks.socksocket
print requests.get("http://icanhazip.com").text
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
bytes=random._urandom(1024)
# UDP CONNECTION METHOD
#sock.connect(("x.x.x.x", 6000))
#sock.send(bytes)
# UDP CONNECTIONLESS METHOD
#sock.sendto(bytes, ("x.x.x.x", 6000))
Which brings me to my question - is there any way to send UDP packets via a connectionless method through a SOCKS5 proxy in python?
UPDATE
I originally had SocksiPy installed instead of PySocks, so I've replaced the modules and removed the monkeypatch in the original script. But now, I'm instead getting 'Broken Pipe' errors, as seen below.
Traceback (most recent call last):
File "test.py", line 19, in <module>
s.sendto(bytes, ("x.x.x.x", 6000))
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 336, in sendto
return _BaseSocket.sendto(self, bytes, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/socks.py", line 223, in <lambda>
return lambda self, *pos, **kw: self._savedmethods[name](*pos, **kw)
socket.error: [Errno 32] Broken pipe
I've double checked to make sure Tor is actually working and the proxy is up, which it is as I can receive HTTP requests and responses through the Tor proxy - the responses to sites like http://icanhazip.com/ return a different IP that my actual IP, which suggests that Tor is indeed functioning. I also figured that removing the monkeypatch might make it work with better compatibility, seeing as with the new PySocks module on the OLD script it still fails with the original errors seen above.
The new script:
import socks
import socket
import random
import math
s = socks.socksocket()
s.set_proxy(socks.SOCKS5, "localhost", 9050)
bytes=random._urandom(1024)
# UDP CONNECTION METHOD
#sock.connect(("x.x.x.x", 6000))
#sock.send(bytes)
# UDP CONNECTIONLESS METHOD
#s.sendto(bytes, ("x.x.x.x", 6000))
The errors I'm describing above are with the connectionless method - using the connection method seems to possibly work, however it hangs when connecting to the port (which is the be expected, as the port isn't open).
As #gwyn pointed out, Tor only supports TCP streams, as specified on their website. Using UDP over Tor will not work, only TCP connections.
Related
I have a gRPC project that works correctly running server and client on the same machine, but when I try it using different machines in a same wifi network using IPV4, it occurs the following error on client:
Traceback (most recent call last):
File "client.py", line 29, in <module>
run()
File "client.py", line 25, in run
add_reply = stub.Add(add_request)
File "/home/caio/dev/laboratorio/mygrpc/.env/lib/python3.8/site-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/caio/dev/laboratorio/mygrpc/.env/lib/python3.8/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "failed to connect to all addresses; last error: UNKNOWN: ipv4:192.168.100.9:50051: tcp handshaker shutdown"
debug_error_string = "UNKNOWN:failed to connect to all addresses; last error: UNKNOWN: ipv4:192.168.100.9:50051: tcp handshaker shutdown {grpc_status:14, created_time:"2022-12-10T15:21:32.619696358-03:00"}"
>
I've seem people reporting that it worked for them, but it's seemed not be much different, so I have no idea what's missing.
server code:
from os import system
system('clear')
from concurrent import futures
import time
import grpc
from grpc import _server
import sum_pb2
import sum_pb2_grpc
PORT = 50051
HOST = "localhost"
class Servicer(sum_pb2_grpc.SumNumbersServicer):
def Add(self, request, context):
print(request)
add_reply = sum_pb2.AddReply()
add_reply.r = request.a + request.b
# return super().Add(request, context)
return add_reply
def serve():
server:_server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
sum_pb2_grpc.add_SumNumbersServicer_to_server(Servicer(), server)
# serve._add_insecure_port(f"localhost:{PORT}")
server.add_insecure_port(f"{HOST}:{PORT}")
server.start()
print(f"Listenning on port {PORT}")
try:
server.wait_for_termination()
except KeyboardInterrupt:
server.stop(0)
if __name__ == "__main__":
serve()
client code:
from os import system
system('clear')
from concurrent import futures
import time
from random import randint
import grpc
from grpc import _server
import sum_pb2
import sum_pb2_grpc
PORT = 50051
HOST = "localhost"
HOST = "192.168.100.9"
min = 0
max = 100
def run():
with grpc.insecure_channel(f"{HOST}:{PORT}") as channel:
stub = sum_pb2_grpc.SumNumbersStub(channel)
a = randint(min, max)
b = randint(min, max)
add_request = sum_pb2.AddRequest(a= a, b= b)
add_reply = stub.Add(add_request)
print(f"{a} + {b} = {add_reply}")
if __name__ == "__main__":
run()
EDIT:
When using "0.0.0.0" as host in server.py it prints the following error (differently from last time, this time I'm using ethernet cable on both machines, idk if it makes difference ):
Traceback (most recent call last):
File "client.py", line 29, in <module>
run()
File "client.py", line 25, in run
add_reply = stub.Add(add_request)
File "/home/estagiarioti/dev/laboratorio/mygrpc/.env/lib/python3.8/site-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/estagiarioti/dev/laboratorio/mygrpc/.env/lib/python3.8/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "failed to connect to all addresses; last error: UNKNOWN: ipv4:192.168.10.6:50051: Failed to connect to remote host: No route to host"
debug_error_string = "UNKNOWN:failed to connect to all addresses; last error: UNKNOWN: ipv4:192.168.10.6:50051: Failed to connect to remote host: No route to host {grpc_status:14, created_time:"2022-12-12T13:58:15.049856347-03:00"}"
>
Error message when running both machines in an wifi network and "0.0.0.0" ip in host:
Traceback (most recent call last):
File "client.py", line 29, in <module>
run()
File "client.py", line 25, in run
add_reply = stub.Add(add_request)
File "/home/caio/dev/laboratorio/mygrpc/.env/lib/python3.8/site-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/caio/dev/laboratorio/mygrpc/.env/lib/python3.8/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "failed to connect to all addresses; last error: UNKNOWN: ipv4:192.168.100.9:50051: tcp handshaker shutdown"
debug_error_string = "UNKNOWN:failed to connect to all addresses; last error: UNKNOWN: ipv4:192.168.100.9:50051: tcp handshaker shutdown {created_time:"2022-12-12T19:12:13.762636131-03:00", grpc_status:14}"
>
ps: Sometimes i use WSL, sometimes i don't, maybe this is important to know.
localhost usually resolves to 127.0.0.1 which is a special so-called loopback network address. It is used when you know that you don't need external (to the host) connectivity because it generally doesn't use the host's network stack.
You will generally want to bind the server to 0.0.0.0 instead. This binds the server to all the host's network interfaces and is a simple way to ensure that your service is available to external hosts.
Also, you will need to be confident that the server's host's network address is 192.168.100.9 to ensure that the client tries to communicate with the correct host.
I don't know what I was doing wrong in WSL, but it worked when I used pure Windows and in the Firewall settings I allowed all the pythons in the list to have access in public and private networks. This with both machines on the same Wifi network
I can't afford to send UDP packets through SOCKS5 proxy. I'm using PySocks. Here is my code :
import socks
proxyIP = "whatever.proxy"
proxyPort = 8080
s = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM)
s.set_proxy(socks.SOCKS5, proxyIP, proxyPort)
a = s.sendto(b"GET / HTTP/1.1", ("example.com",80))
In my test, the destination is my nginx web server. The proxy is not mine, I only know it's a socks5 proxy.
Here is the error I get :
Traceback (most recent call last):
File "test.py", line 35, in <module>
a = s.sendto(b"GET / HTTP/1.1", ("example.com",80))
File "C:\Python38\lib\site-packages\socks.py", line 367, in sendto
self.bind(("", 0))
File "C:\Python38\lib\site-packages\socks.py", line 353, in bind
_, relay = self._SOCKS5_request(self._proxyconn, UDP_ASSOCIATE, dst)
File "C:\Python38\lib\site-packages\socks.py", line 524, in _SOCKS5_request
resp = self._readall(reader, 3)
File "C:\Python38\lib\site-packages\socks.py", line 278, in _readall
raise GeneralProxyError("Connection closed unexpectedly")
socks.GeneralProxyError: Connection closed unexpectedly
I also tested with s.connect/s.sendall and I have exactly the same error.
Finally, I must say it works perfectly with TCP (SOCK_STREAM).
I have come across a corner in socket in Python3.5. When running the code below something is wrong and an error is thrown.
import socket
print(socket.create_connection(('www.baidu.com', 80), source_address=('127.0.0.1', 8998)))
Error:
Traceback (most recent call last):
File "demo.py", line 4, in <module>
print(socket.create_connection(('www.baidu.com', 80), source_address=('127.0.0.1', 8998)))
File "/usr/local/lib/python3.5/socket.py", line 707, in create_connection
raise err
File "/usr/local/lib/python3.5/socket.py", line 698, in create_connection
sock.connect(sa)
OSError: [Errno 22] Invalid argument
Short answer is don't!
You can't play with low level Python sockets not knowing how BSD TCP stack is working and how to use BSD sockets.
The source_address is - as it clearly states - source address and port for you connection. You MUST NOT make connection from loopback interface address to the address in the outside world.
So, the invalid argument error is correct.
Do you really need to set source_address? Why don't let that to the operating system?
You can't use the source address 127.0.0.1. The server can't reach you on this address, its just locally on your computer. This is your local loopback address. You have to use your public IP address.
So best is let the system set the source address like the other answer says.
socket.create_connection(('www.baidu.com', 80))
So first off, let me show you my code and the error it returns:
print "before import"
from twisted.internet import protocol # imports
print "after protocol"
from twisted.internet import reactor
print "after reactor"
from twisted.internet.endpoints import TCP4ServerEndpoint
print "after import"
class Echo(protocol.Protocol):
"""docstring for Echo"""
def connectionMade(self):
cADDR = self.clnt = self.transport.getPeer().host
print "...Connection made with {0}".format(cADDR)
def dataReceived(self, data):
self.transport.write(data)
class EchoFactory(protocol.Factory):
"""docstring for EchoFactory"""
def buildProtocol(self, addr):
return Echo()
server = TCP4ServerEndpoint(reactor, 45002)
server.listen(EchoFactory())
reactor.run()
As you can see, I created some print statements to debug exactly which import is causing the issue. Now for the error:
before import
after protocol
Traceback (most recent call last):
File "C:\Users\Sa'id\Documents\Learning Programming\Python\Core Python Application Programming\Chapter 2 - Network Programming\Twisted\twisted_intro.py", line 9, in <module>
from twisted.internet import reactor
File "C:\Python27\lib\site-packages\twisted\internet\reactor.py", line 39, in <module>
default.install()
File "C:\Python27\lib\site-packages\twisted\internet\selectreactor.py", line 196, in install
reactor = SelectReactor()
File "C:\Python27\lib\site-packages\twisted\internet\selectreactor.py", line 72, in __init__
posixbase.PosixReactorBase.__init__(self)
File "C:\Python27\lib\site-packages\twisted\internet\base.py", line 499, in __init__
self.installWaker()
File "C:\Python27\lib\site-packages\twisted\internet\posixbase.py", line 286, in installWaker
self.waker = self._wakerFactory(self)
File "C:\Python27\lib\site-packages\twisted\internet\posixbase.py", line 81, in __init__
client.connect(server.getsockname())
File "C:\Python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 10061] No connection could be made because the target machine actively refused it
>>>
For some reason, my Twisted server is trying to make connections, when in reality, it should be the one waiting for the connections, not making them. And as you can see from the error, it prints right before the reactor import, but not after it, so the reactor is really the issue here. I've posted this on another website without much success, but the replier said that, it was because the reactor was trying to setup a _SocketWaker and something was blocking it from setting it up. He said that turning off your firewall would make it work, but after trying it, the same error was returned. Just a note, the port I am hosting this Echo() server on is port forwarded, so the port is probably not the issue. Any input would be much appreciated.
Thanks.
On UNIX, Twisted sets up a thread-waker file descriptor using a pipe. However, on Windows, anonymous pipes have several implementation issues and discrepancies between different Windows versions, so it uses a socket pair. Creating this socket pair involves connecting back to localhost, so, certain overly-aggressive firewall configurations can trigger this area.
Here is a python code snippet that uses paramiko:
import paramiko
sshClient = paramiko.SSHClient()
sshClient.set_missing_host_key_policy(paramiko.AutoAddPolicy)
sshClient.connect(_peerIp, username=_username, password=_password, timeout=3.0)
As soon as I run the script, I also unplug _peerIp's network cable. And connect() method hangs. Even though the timeout is 3.0, it has been 10 minutes and it still hangs.
(I think the TCP connection was established in a split second and I unplugged the cable during the ssh establishment)
So, do you know any workaround for this? My script will run at a manufacturing factory and it must not hang in such a scenario and handle it properly.
EDIT:
It just gave an exception:
No handlers could be found for logger "paramiko.transport"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/pymodules/python2.6/paramiko/client.py", line 327, in connect
self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
File "/usr/lib/pymodules/python2.6/paramiko/client.py", line 438, in _auth
self._transport.auth_publickey(username, key)
File "/usr/lib/pymodules/python2.6/paramiko/transport.py", line 1234, in auth_publickey
return self.auth_handler.wait_for_response(my_event)
File "/usr/lib/pymodules/python2.6/paramiko/auth_handler.py", line 163, in wait_for_response
raise e
socket.error: [Errno 113] No route to host
Ok, at least it eventually raised an exception but I believe this is not the expected behaviour. If the timeout is 3.0, connect() method should return something after timeout expires.