Skip to content

Commit 293de74

Browse files
committed
fix two small bugs related to ssh key auth
Signed-off-by: ashiven <nevisha@pm.me>
1 parent bcbbb0c commit 293de74

File tree

2 files changed

+51
-20
lines changed

2 files changed

+51
-20
lines changed

embark/workers/tasks.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -724,17 +724,22 @@ def _update_or_create_worker(config: Configuration, ip_address: str):
724724
)
725725
worker.save()
726726
worker.configurations.set([config])
727-
finally:
728727
try:
729728
init_sudoers_file(config, worker)
730729
setup_ssh_key(config, worker)
730+
except BaseException:
731+
logger.error("Failed to setup SSH key or sudoers file for worker %s", worker.name)
732+
worker.delete()
733+
return
734+
finally:
735+
try:
731736
update_system_info(worker)
732737
update_dependencies_info(worker)
733738
except BaseException:
734739
pass
735740

736741

737-
def _scan_for_worker(config: Configuration, ip_address: str, port: int = 22, timeout: int = 1) -> str:
742+
def _scan_for_worker(config: Configuration, ip_address: str, port: int = 22, timeout: int = 1, ssh_auth_check: bool = True) -> str:
738743
"""
739744
Checks if a host is reachable, has valid SSH creds, and sudo perms.
740745
Updates the DB accordingly.
@@ -743,6 +748,7 @@ def _scan_for_worker(config: Configuration, ip_address: str, port: int = 22, tim
743748
:param ip_address: Host's IP address
744749
:param port: SSH port (default: 22)
745750
:param timeout: Connection timeout in seconds
751+
:param ssh_auth_check: If True, tries to connect to the ip address with the config's ssh credentials and checks whether the user has sudo privileges
746752
:return: ip_address on success, None otherwise
747753
"""
748754
try: # Check TCP socket first before trying SSH
@@ -756,23 +762,26 @@ def _scan_for_worker(config: Configuration, ip_address: str, port: int = 22, tim
756762

757763
client = None
758764
try:
759-
client = new_autoadd_client()
760-
client.connect(
761-
ip_address, port=port,
762-
username=config.ssh_user, password=config.ssh_password,
763-
timeout=timeout
764-
)
765-
766-
logger.info("[%s@%s] Connected via SSH. Now testing for sudo privileges.", config.ssh_user, ip_address)
767-
768-
stdin, stdout, _ = client.exec_command("sudo -v", get_pty=True) # nosec
769-
stdin.write(config.ssh_password + "\n")
770-
stdin.flush()
771-
if stdout.channel.recv_exit_status():
772-
logger.info("[%s@%s] Can't register worker: No sudo permission.", config.ssh_user, ip_address)
773-
# Delete worker if SSH configuration changed
774-
Worker.objects.filter(ip_address=ip_address).delete()
775-
return None
765+
# We only want to perform this check for newly created configs, not for scans of existing configs
766+
# (ssh pw auth would have been disabled for workers belonging to existing configs)
767+
if ssh_auth_check:
768+
client = new_autoadd_client()
769+
client.connect(
770+
ip_address, port=port,
771+
username=config.ssh_user, password=config.ssh_password,
772+
timeout=timeout
773+
)
774+
775+
logger.info("[%s@%s] Connected via SSH. Now testing for sudo privileges.", config.ssh_user, ip_address)
776+
777+
stdin, stdout, _ = client.exec_command("sudo -v", get_pty=True) # nosec
778+
stdin.write(config.ssh_password + "\n")
779+
stdin.flush()
780+
if stdout.channel.recv_exit_status():
781+
logger.info("[%s@%s] Can't register worker: No sudo permission.", config.ssh_user, ip_address)
782+
# Delete worker if SSH configuration changed
783+
Worker.objects.filter(ip_address=ip_address).delete()
784+
return None
776785

777786
_update_or_create_worker(config, ip_address)
778787
logger.info("[%s@%s] Worker is reachable via SSH.", config.ssh_user, ip_address)
@@ -795,13 +804,14 @@ def config_worker_scan_task(configuration_id: int):
795804
"""
796805
try:
797806
config = Configuration.objects.get(id=configuration_id)
807+
ssh_auth_check = not config.scan_status == Configuration.ScanStatus.FINISHED
798808
config.scan_status = Configuration.ScanStatus.SCANNING
799809
config.save()
800810

801811
ip_network = ipaddress.ip_network(config.ip_range, strict=False)
802812
ip_addresses = [str(ip) for ip in ip_network.hosts()]
803813
with ThreadPoolExecutor(max_workers=50) as executor:
804-
results = executor.map(partial(_scan_for_worker, config), ip_addresses)
814+
results = executor.map(partial(_scan_for_worker, config, ssh_auth_check=ssh_auth_check), ip_addresses)
805815
reachable = set(results) - {None}
806816

807817
unreachable_workers = [worker for worker in config.workers.all() if worker.ip_address not in reachable]

embark/workers/update/update.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,33 @@ def undo_sudoers_file(configuration: Configuration, worker: Worker):
263263
client.close()
264264

265265

266+
def _create_ssh_config_dir(configuration: Configuration, worker: Worker):
267+
"""
268+
Connects to the worker and creates the .ssh directory if it does not exist.
269+
If this is not done before calling ssh-copy-id, the command may fail.
270+
:params configuration: The worker configuration that includes the ssh credentials for the worker
271+
:params worker: The worker on which to create the SSH config directory
272+
"""
273+
client = None
274+
try:
275+
client = worker.ssh_connect(use_password=True)
276+
homedir = f"/home/{configuration.ssh_user}" if configuration.ssh_user != "root" else "/root"
277+
exec_blocking_ssh(client, f"sudo mkdir -p {homedir}/.ssh && sudo chown {configuration.ssh_user}:{configuration.ssh_user} {homedir}/.ssh")
278+
logger.info("_create_ssh_config_dir: SSH config directory created for user %s on worker %s", configuration.ssh_user, worker.ip_address)
279+
except paramiko.SSHException as ssh_error:
280+
logger.error("_create_ssh_config_dir: Failed to create SSH config directory on worker %s: %s", worker.ip_address, ssh_error)
281+
finally:
282+
if client:
283+
client.close()
284+
285+
266286
def setup_ssh_key(configuration: Configuration, worker: Worker):
267287
"""
268288
Install SSH key on provided worker and disable PW auth
269289
:params configuration: The SSH keys
270290
:params worker: The worker to update
271291
"""
292+
_create_ssh_config_dir(configuration, worker)
272293
_, public_key = configuration.ensure_ssh_keys()
273294

274295
logger.info("setup_ssh_key: Starting ssh-copy-id on worker %s", worker.ip_address)

0 commit comments

Comments
 (0)