fix bug loader fw SSH, update doc, update scan ip ( scan nhanh hơn )
This commit is contained in:
@@ -12,15 +12,22 @@ import os
|
||||
import time
|
||||
import paramiko
|
||||
from scp import SCPClient
|
||||
import random
|
||||
|
||||
|
||||
def _create_ssh_client(ip, user, password, timeout=10):
|
||||
"""Create an SSH client with auto-accept host key policy."""
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(ip, username=user, password=password, timeout=timeout,
|
||||
look_for_keys=False, allow_agent=False)
|
||||
return client
|
||||
def _create_ssh_client(ip, user, password, timeout=15):
|
||||
"""Create an SSH client with auto-accept host key policy, including retries."""
|
||||
for attempt in range(3):
|
||||
try:
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(ip, username=user, password=password, timeout=timeout,
|
||||
look_for_keys=False, allow_agent=False)
|
||||
return client
|
||||
except Exception as e:
|
||||
if attempt == 2:
|
||||
raise e
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
import telnetlib
|
||||
@@ -30,6 +37,9 @@ def set_device_password(ip, user="root", old_password="", new_password="admin123
|
||||
"""
|
||||
Set device password via Telnet (if raw/reset) or SSH.
|
||||
"""
|
||||
# Jitter to avoid hammering the network with many concurrent connections
|
||||
time.sleep(random.uniform(0.1, 1.5))
|
||||
|
||||
if status_cb:
|
||||
status_cb("Checking Telnet port for raw device...")
|
||||
|
||||
@@ -63,53 +73,63 @@ def set_device_password(ip, user="root", old_password="", new_password="admin123
|
||||
time.sleep(3)
|
||||
return "DONE"
|
||||
|
||||
except ConnectionRefusedError:
|
||||
# Port 23 đóng -> Tức là thiết bị đã có Pass và đã bật SSH, chuyển qua luồng mồi mật khẩu cũ
|
||||
pass
|
||||
except Exception as e:
|
||||
# Các lỗi timeout khác có thể do ping không tới
|
||||
return f"FAIL: Telnet check -> {e}"
|
||||
# Bất kỳ lỗi Telnet nào (ConnectionRefused, Timeout, BrokenPipe...)
|
||||
# đều có nghĩa là Telnet không truy cập được hoặc bị đóng ngang.
|
||||
# Chuyển qua luồng kết nối SSH.
|
||||
pass
|
||||
|
||||
# 2. Rơi xuống luồng SSH nếu thiết bị cũ (cổng Telnet đóng)
|
||||
# 2. Rơi xuống luồng SSH nếu thiết bị cũ (cổng Telnet đóng hoặc lỗi)
|
||||
if status_cb:
|
||||
status_cb("Connecting SSH for password update...")
|
||||
|
||||
try:
|
||||
client = _create_ssh_client(ip, user, old_password, timeout=5)
|
||||
except Exception as e:
|
||||
return f"FAIL: Cannot connect SSH (Old pass incorrect?) — {e}"
|
||||
last_error = None
|
||||
for attempt in range(3):
|
||||
try:
|
||||
client = _create_ssh_client(ip, user, old_password, timeout=10)
|
||||
|
||||
if status_cb:
|
||||
status_cb("Setting password via SSH...")
|
||||
|
||||
try:
|
||||
if status_cb:
|
||||
status_cb("Setting password via SSH...")
|
||||
shell = client.invoke_shell()
|
||||
time.sleep(1)
|
||||
if shell.recv_ready():
|
||||
shell.recv(65535)
|
||||
|
||||
shell = client.invoke_shell()
|
||||
time.sleep(1)
|
||||
if shell.recv_ready():
|
||||
shell.recv(65535)
|
||||
shell.send("passwd\n")
|
||||
time.sleep(2)
|
||||
shell.send(f"{new_password}\n")
|
||||
time.sleep(1)
|
||||
shell.send(f"{new_password}\n")
|
||||
time.sleep(2)
|
||||
|
||||
shell.send("passwd\n")
|
||||
time.sleep(2)
|
||||
shell.send(f"{new_password}\n")
|
||||
time.sleep(1)
|
||||
shell.send(f"{new_password}\n")
|
||||
time.sleep(2)
|
||||
if shell.recv_ready():
|
||||
shell.recv(65535)
|
||||
|
||||
if shell.recv_ready():
|
||||
shell.recv(65535)
|
||||
shell.send("exit\n")
|
||||
time.sleep(0.5)
|
||||
shell.close()
|
||||
client.close()
|
||||
|
||||
shell.send("exit\n")
|
||||
time.sleep(0.5)
|
||||
shell.close()
|
||||
|
||||
if status_cb:
|
||||
status_cb("Password set ✓")
|
||||
return "DONE"
|
||||
|
||||
except Exception as e:
|
||||
return f"FAIL: {e}"
|
||||
finally:
|
||||
client.close()
|
||||
if status_cb:
|
||||
status_cb("Password set ✓")
|
||||
return "DONE"
|
||||
|
||||
except paramiko.AuthenticationException as e:
|
||||
# Authentication means wrong password, retrying won't help here
|
||||
if 'client' in locals() and client:
|
||||
client.close()
|
||||
return f"FAIL: Cannot connect SSH (Old pass incorrect?) — {e}"
|
||||
except Exception as e:
|
||||
last_error = e
|
||||
if 'client' in locals() and client:
|
||||
try: client.close()
|
||||
except: pass
|
||||
# Errno 64 or 113 usually means 'Host is down' or 'No route to host'.
|
||||
# It can be a transient switch issue. Wait a bit and retry.
|
||||
time.sleep(2)
|
||||
|
||||
return f"FAIL: Cannot connect SSH after 3 attempts — {last_error}"
|
||||
|
||||
|
||||
def flash_device_ssh(ip, firmware_path, user="root", password="admin123a",
|
||||
@@ -131,6 +151,10 @@ def flash_device_ssh(ip, firmware_path, user="root", password="admin123a",
|
||||
# ═══════════════════════════════════════════
|
||||
# STEP 0: Set password (optional)
|
||||
# ═══════════════════════════════════════════
|
||||
if not set_passwd:
|
||||
# Jitter here if we skip set_passwd
|
||||
time.sleep(random.uniform(0.1, 1.5))
|
||||
|
||||
if set_passwd:
|
||||
result = set_device_password(ip, user, "", password, status_cb)
|
||||
if result.startswith("FAIL"):
|
||||
@@ -170,12 +194,21 @@ def flash_device_ssh(ip, firmware_path, user="root", password="admin123a",
|
||||
filename = os.path.basename(firmware_path)
|
||||
remote_path = f"/tmp/{filename}"
|
||||
|
||||
try:
|
||||
scp_client = SCPClient(client.get_transport(), socket_timeout=300)
|
||||
scp_client.put(firmware_path, remote_path)
|
||||
scp_client.close()
|
||||
except Exception as e:
|
||||
return f"FAIL: SCP upload failed — {e}"
|
||||
upload_success = False
|
||||
last_error = None
|
||||
for attempt in range(3):
|
||||
try:
|
||||
scp_client = SCPClient(client.get_transport(), socket_timeout=350)
|
||||
scp_client.put(firmware_path, remote_path)
|
||||
scp_client.close()
|
||||
upload_success = True
|
||||
break
|
||||
except Exception as e:
|
||||
last_error = e
|
||||
time.sleep(1.5)
|
||||
|
||||
if not upload_success:
|
||||
return f"FAIL: SCP upload failed (Check Network) — {last_error}"
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user