forked from HMS-2025/HMS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConfig.py
More file actions
94 lines (79 loc) · 3.42 KB
/
Config.py
File metadata and controls
94 lines (79 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#-------------DEPENDENCIES----------------#
import paramiko
import yaml
import os
import socket
import subprocess
#-------------UTILITY FUNCTIONS-----------------#
# Load configuration from the YAML file
def load_config(yaml_file):
try:
with open(yaml_file, "r") as file:
config = yaml.safe_load(file)
return config.get("ssh", {})
except Exception as e:
print(f"Error loading YAML file: {e}")
return {}
# Check if the host is reachable via ping
def is_host_reachable(hostname):
try:
# Ping command adapted to OS
ping_cmd = ["ping", "-c", "1", "-W", "1", hostname] if os.name != "nt" else ["ping", "-n", "1", hostname]
result = subprocess.run(ping_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result.returncode == 0
except Exception as e:
print(f"Error checking host reachability: {e}")
return False
# Check if the port is open
def is_port_open(hostname, port, timeout=3):
try:
with socket.create_connection((hostname, port), timeout=timeout):
return True
except (socket.timeout, ConnectionRefusedError, OSError):
return False
# Connect to SSH
def ssh_connect(hostname, port, username, key_path, passphrase=None):
if not key_path or not os.path.isfile(key_path):
print(f"Error: SSH key not found at the specified path: {key_path}")
return None
if not isinstance(port, int) or not (1 <= port <= 65535):
print("Error: The port must be an integer between 1 and 65535.")
return None
if not is_host_reachable(hostname):
print(f"Error: Host {hostname} is unreachable.")
return None
if not is_port_open(hostname, port):
print(f"Error: Port {port} on {hostname} is closed or unreachable.")
return None
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
key = None
key_classes = [paramiko.RSAKey, paramiko.DSSKey, paramiko.ECDSAKey, paramiko.Ed25519Key]
for key_class in key_classes:
try:
key = key_class.from_private_key_file(key_path, password=passphrase)
break
except paramiko.ssh_exception.SSHException:
continue
if key is None:
raise ValueError("Unsupported SSH key format or invalid file.")
key_size = key.get_bits()
print(f"SSH key size used: {key_size} bits")
# Check minimum security standards for the key size
if isinstance(key, paramiko.RSAKey) and key_size < 2048:
print("Warning: The RSA key used is smaller than 2048 bits, which is considered insecure.")
elif isinstance(key, paramiko.ECDSAKey) and key_size < 256:
print("Warning: The ECDSA key used is smaller than 256 bits, which is considered insecure.")
elif isinstance(key, paramiko.DSSKey) and key_size < 1024:
print("Warning: The DSS key used is smaller than 1024 bits, which is considered insecure.")
client.connect(hostname, port=port, username=username, pkey=key)
print("SSH connection successful!")
return client
except paramiko.AuthenticationException:
print("Error: Authentication failed. Check your credentials.")
except paramiko.SSHException as e:
print(f"SSH error: {e}")
except Exception as e:
print(f"SSH connection error: {e}")
return None