Check if client and server are running on same machine.

This patch checks to see if the client and the server are running on
the same machine. The client creates a temporary file that the server
then looks for. If the server finds the file, it knows it is on the
same machine as the client and it deletes the file. Next, if the
client detects that the file has been deleted by the server, it
assumes that it is running on the same machine as the server.

This check is necessary since a user may specify a remote host with
"-r" that actually points back to the same machine the client is on.

This commit uses tempfile.mkstemp() which was added in Python 2.3.

Functionally, this commit does nothing except add a debug message
about if the client and server are on the same machine. It also sets a
variable which contains this information for potential future use.

Potential future uses include...

1) If the TTL hack is removed, this can be used to print a error
message since running the client and server on the same machine would
no longer be supported.

2) If the TTL hack is continued, we could disable the hack when the
client and the server are on different machines.
This commit is contained in:
Scott Kuhl 2021-03-10 13:52:46 -05:00
parent d6d11b24c8
commit 0d460c0264
3 changed files with 43 additions and 3 deletions

View File

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

View File

@ -6,6 +6,7 @@ import subprocess as ssubprocess
import os
import sys
import platform
import tempfile
import psutil
import sshuttle.helpers as helpers
@ -47,6 +48,10 @@ def got_signal(signum, frame):
_pidname = None
# This variable is set to true if the client and the server appear to
# be running on the same host.
_client_server_samehost = False
def check_daemon(pidfile):
global _pidname
@ -467,6 +472,16 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
handlers = []
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. The
# _client_server_samehost variable is set to true when they are on
# the same machine.
(_, localhost_detector) = tempfile.mkstemp(prefix="sshuttle-localhost-")
try:
(serverproc, serversock) = ssh.connect(
ssh_cmd, remotename, python,
@ -476,7 +491,8 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
auto_hosts=auto_hosts,
to_nameserver=to_nameserver,
auto_nets=auto_nets,
ttl=ttl))
ttl=ttl,
localhost_detector=localhost_detector))
except socket.error as e:
if e.args[0] == errno.EPIPE:
raise Fatal("failed to establish ssh session (1)")
@ -586,6 +602,18 @@ def _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename,
% (expected, initstring))
log('Connected to server.')
sys.stdout.flush()
# If the server couldn't delete our localhost_detector file, then
# the server is running on a different machine.
global _client_server_samehost
if os.path.exists(localhost_detector):
debug2("Client and server appear to be running on different machines.")
_client_server_samehost = False
os.remove(localhost_detector) # cleanup
else:
debug1("Client and server are running on the same machine.")
_client_server_samehost = True
if daemon:
daemonize()
log('daemonizing (%s).' % _pidname)

View File

@ -16,6 +16,8 @@ from sshuttle.ssnet import Handler, Proxy, Mux, MuxWrapper
from sshuttle.helpers import b, log, debug1, debug2, debug3, Fatal, \
resolvconf_random_nameserver, which, get_env
_client_server_samehost = False
def _ipmatch(ipstr):
# FIXME: IPv4 only
@ -273,7 +275,7 @@ class UdpProxy(Handler):
def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver,
auto_nets, ttl):
auto_nets, ttl, localhost_detector):
try:
helpers.logprefix = ' s: '
debug1('Starting server with Python version %s'
@ -284,6 +286,16 @@ def main(latency_control, latency_buffer_size, auto_hosts, to_nameserver,
import sshuttle.ssnet as ssnet
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.
global _client_server_samehost
if os.path.exists(localhost_detector):
debug3("Deleted the localhost_detector created by the client.\n")
os.remove(localhost_detector)
_client_server_samehost = True
# synchronization header
sys.stdout.write('\0\0SSHUTTLE0001')
sys.stdout.flush()