mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2026-08-15 13:04:30 +00:00
116 lines
3.9 KiB
Python
116 lines
3.9 KiB
Python
# Released under the MIT License. See LICENSE for details.
|
|
#
|
|
"""My nifty ssh/mosh/rsync mishmash."""
|
|
|
|
from enum import Enum
|
|
from dataclasses import dataclass
|
|
|
|
from efro.dataclassio import ioprepped
|
|
|
|
|
|
class LockType(Enum):
|
|
"""Types of locks that can be acquired on a host."""
|
|
|
|
HOST = 'host'
|
|
WORKSPACE = 'workspace'
|
|
|
|
|
|
@ioprepped
|
|
@dataclass
|
|
class HostConfig:
|
|
"""Config for a cloud machine to run commands on.
|
|
|
|
precommand, if set, will be run before the passed commands.
|
|
Note that it is not run in interactive mode (when no command is given).
|
|
"""
|
|
|
|
address: str | None = None
|
|
user: str = 'ubuntu'
|
|
port: int = 22
|
|
mosh_port: int | None = None
|
|
mosh_port_2: int | None = None
|
|
mosh_server_path: str | None = None
|
|
mosh_shell: str = 'sh'
|
|
workspaces_root: str = '/home/${USER}/cloudshell_workspaces'
|
|
sync_perms: bool = True
|
|
precommand_noninteractive: str | None = None
|
|
precommand_interactive: str | None = None
|
|
managed: bool = False
|
|
region: str | None = None
|
|
idle_minutes: int = 5
|
|
can_sudo_reboot: bool = False
|
|
max_sessions: int = 4
|
|
reboot_wait_seconds: int = 20
|
|
reboot_attempts: int = 1
|
|
|
|
def resolved_workspaces_root(self) -> str:
|
|
"""Returns workspaces_root with standard substitutions."""
|
|
return self.workspaces_root.replace('${USER}', self.user)
|
|
|
|
|
|
def socks_proxy_ssh_args() -> list[str]:
|
|
"""Return ssh ``-oProxyCommand`` args for a SOCKS5 proxy, if one is set.
|
|
|
|
Under a network sandbox that only permits outbound traffic through its
|
|
proxy -- e.g. Claude Code's -- this returns ``['-oProxyCommand=...']`` so
|
|
ssh can reach allowed hosts via it. To use these with rsync, fold them
|
|
into ``--rsh`` with :func:`shlex.join` (``'--rsh=' + shlex.join(['ssh',
|
|
*args])``) so the multi-word proxy command survives rsync's shell
|
|
re-parse. Returns an empty list when no socks5 proxy is set, so it is
|
|
safe to splice into a command unconditionally.
|
|
|
|
We need a SOCKS5 endpoint for ssh's ``ProxyCommand``. Historically
|
|
``ALL_PROXY`` carried the ``socks5://`` url, but some sandboxes now set
|
|
``ALL_PROXY`` to an ``http://`` url for the *same* endpoint and advertise
|
|
the socks5 form only via other vars (``ftp_proxy`` / ``grpc_proxy``). So
|
|
rather than trust ``ALL_PROXY``'s scheme, scan the common proxy vars and
|
|
use the first genuine ``socks5[h]://`` url we find.
|
|
"""
|
|
import os
|
|
import shutil
|
|
|
|
from efro.error import CleanError
|
|
|
|
proxy = ''
|
|
for var in (
|
|
'SOCKS5_PROXY',
|
|
'socks5_proxy',
|
|
'SOCKS_PROXY',
|
|
'socks_proxy',
|
|
'ALL_PROXY',
|
|
'all_proxy',
|
|
'FTP_PROXY',
|
|
'ftp_proxy',
|
|
'GRPC_PROXY',
|
|
'grpc_proxy',
|
|
):
|
|
val = os.environ.get(var, '')
|
|
if val.startswith(('socks5://', 'socks5h://')):
|
|
proxy = val
|
|
break
|
|
if not proxy:
|
|
return []
|
|
|
|
netloc = proxy.split('://', 1)[1].rstrip('/')
|
|
# Peel any 'user:pass@' userinfo off the 'host:port'.
|
|
userinfo, _, host_port = netloc.rpartition('@')
|
|
if userinfo:
|
|
# An authenticating SOCKS5 proxy: macOS's stock nc can't do SOCKS5
|
|
# auth, so route through ncat (nmap), which can. -4 forces IPv4
|
|
# (the proxy listens on 127.0.0.1 but 'localhost' can resolve to
|
|
# ::1 first); --proxy-dns remote is required since local DNS may be
|
|
# unavailable behind the sandbox.
|
|
ncat = shutil.which('ncat')
|
|
if ncat is None:
|
|
raise CleanError(
|
|
'Behind an authenticating SOCKS5 proxy (ALL_PROXY) but ncat'
|
|
" is not installed; install it with 'brew install nmap'."
|
|
)
|
|
proxy_cmd = (
|
|
f'{ncat} -4 --proxy {host_port} --proxy-type socks5'
|
|
f' --proxy-auth {userinfo} --proxy-dns remote %h %p'
|
|
)
|
|
else:
|
|
# No auth required; stock nc handles plain SOCKS5.
|
|
proxy_cmd = f'nc -X 5 -x {host_port} %h %p'
|
|
return [f'-oProxyCommand={proxy_cmd}']
|