This commit is contained in:
Scott Kuhl 2025-04-08 09:42:23 +05:30 committed by GitHub
commit c48ea512f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 3 deletions

View File

@ -50,4 +50,4 @@ from sshuttle.server import main # noqa: E402
main(options.latency_control, options.latency_buffer_size, main(options.latency_control, options.latency_buffer_size,
options.auto_hosts, options.to_nameserver, options.auto_hosts, options.to_nameserver,
options.auto_nets) options.auto_nets, options.localhost_detector)

View File

@ -7,6 +7,7 @@ import os
import sys import sys
import base64 import base64
import platform import platform
import tempfile
import sshuttle.helpers as helpers import sshuttle.helpers as helpers
import sshuttle.ssnet as ssnet import sshuttle.ssnet as ssnet
@ -602,6 +603,14 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
handlers = [] handlers = []
debug1('Connecting to server...') debug1('Connecting to server...')
# The client creates this file. If the server sees the file, it
# will delete it before writing SSHUTTLE0001 back to the client.
# If the server sees the file, then the server can deduce that it
# is running on the same host as the client. If the client sees
# that the server deleted the file, then the client can deduce
# that it is running on the same host as the server.
(_, localhost_detector) = tempfile.mkstemp(prefix="sshuttle-localhost-")
try: try:
(serverproc, rfile, wfile) = ssh.connect( (serverproc, rfile, wfile) = ssh.connect(
ssh_cmd, remotename, python, ssh_cmd, remotename, python,
@ -612,7 +621,8 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
latency_buffer_size=latency_buffer_size, latency_buffer_size=latency_buffer_size,
auto_hosts=auto_hosts, auto_hosts=auto_hosts,
to_nameserver=to_nameserver, to_nameserver=to_nameserver,
auto_nets=auto_nets)) auto_nets=auto_nets,
localhost_detector=localhost_detector))
except socket.error as e: except socket.error as e:
if e.args[0] == errno.EPIPE: if e.args[0] == errno.EPIPE:
debug3('Error: EPIPE: ' + repr(e)) debug3('Error: EPIPE: ' + repr(e))
@ -724,6 +734,25 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
log('Connected to server.') log('Connected to server.')
sys.stdout.flush() sys.stdout.flush()
# If the server couldn't delete our localhost_detector file, then
# the server is running on a different machine.
if os.path.exists(localhost_detector):
debug3("Client and server appear to be running on different machines.")
os.remove(localhost_detector) # cleanup
else:
# The client and server can't run on the same machine because
# the firewall rules can't distinguish between data the
# sshuttle server sends (which shouldn't be redirected through
# sshuttle) and the different connections applications make
# (which perhaps should be redirected through sshuttle).
# Previously we set the TTL of the packets the server sent to
# distinguish between the two, but this feature was removed
# since running the client and server on the same machine is
# only useful for debugging.
raise Fatal("Exiting because sshuttle client and server are "
"running on the same machine. The host specified "
"with the -r option must be a remote host.")
if daemon: if daemon:
daemonize() daemonize()
log('daemonizing (%s).' % _pidname) log('daemonizing (%s).' % _pidname)

View File

@ -285,7 +285,7 @@ class UdpProxy(Handler):
def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver, def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver,
auto_nets): auto_nets, localhost_detector):
try: try:
helpers.logprefix = ' s: ' helpers.logprefix = ' s: '
@ -294,6 +294,14 @@ def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver,
import sshuttle.ssnet as ssnet import sshuttle.ssnet as ssnet
ssnet.LATENCY_BUFFER_SIZE = latency_buffer_size ssnet.LATENCY_BUFFER_SIZE = latency_buffer_size
# The client writes this file to the local machine. If we can see
# it, we delete it prior to send the synchronization header. The
# client can then determine if the server and client are running
# on the same machine by checking for the presence of the file.
if os.path.exists(localhost_detector):
debug3("Deleted the localhost_detector created by the client.\n")
os.remove(localhost_detector)
# synchronization header # synchronization header
sys.stdout.write('\0\0SSHUTTLE0001') sys.stdout.write('\0\0SSHUTTLE0001')
sys.stdout.flush() sys.stdout.flush()