fix bug loader fw SSH, update doc, update scan ip ( scan nhanh hơn )
This commit is contained in:
@@ -1,58 +1,60 @@
|
||||
# Tài liệu Kỹ thuật: Nạp Mới Firmware (LoadFW bằng SSH)
|
||||
# Tài liệu Kỹ thuật: Nạp Firmware qua SSH (`core/ssh_flasher.py`)
|
||||
|
||||
Tính năng **Nạp Mới FW** trong module `ssh_flasher.py` được thiết kế để cấp cứu và cài đặt lại Firmware cho các thiết bị OpenWrt trắng (mới xuất xưởng) hoặc vừa trải qua Hardware Factory Reset.
|
||||
Module `ssh_flasher.py` chịu trách nhiệm nạp Firmware lên các thiết bị OpenWrt nạp mới hoặc nạp lại thông qua hai giao thức Telnet và SSH. Nó được thiết kế với độ an toàn cao để xử lý đa luồng (ví dụ: quét và nạp hàng loạt thiết bị cùng lúc), có cơ chế tự động thử lại (Retry) và cơ chế dự phòng mật khẩu khi thiết bị bị kẹt mật khẩu cũ.
|
||||
|
||||
---
|
||||
## 1. Sơ đồ Luồng Hoạt Động (Operational Flow)
|
||||
|
||||
## 🚀 Tính năng Báo Cáo Tiến Độ Lên UI
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Bắt đầu Flash SSH] -->|Jitter Delay 0.1s - 1.5s| B{Có yêu cầu Set Password?}
|
||||
B -- Không --> F[Bước 1: Kết nối SSH]
|
||||
B -- Có --> C[Thử kết nối Telnet port 23]
|
||||
|
||||
Tính năng này được thiết kế theo chuẩn hướng sự kiện (Callback). Module liên tục báo cáo dữ liệu thời gian thực lên cột Status của bảng thiết bị:
|
||||
C -- Thành công --> C1[Gửi lệnh `passwd` > admin123a] --> F
|
||||
C -- Lỗi / Timeout / Bị từ chối --> D[Thử SSH với mật khẩu rỗng]
|
||||
|
||||
1. `Checking Telnet port for raw device...` (Nếu thiết bị mới bị khóa SSH)
|
||||
2. `Setting password via SSH...` / `Password set via Telnet...`
|
||||
3. `Uploading firmware via SCP...` (Đẩy file vào RAM Disk)
|
||||
4. `Verifying firmware...`
|
||||
5. `Syncing filesystem...`
|
||||
6. `Flashing firmware (sysupgrade)...`
|
||||
7. `Rebooting...`
|
||||
D -- Thành công --> D1[Gửi lệnh `passwd` > admin123a] --> F
|
||||
D -- Lỗi 'Authentication Failed' --> E[Thử SSH với Backup Password]
|
||||
|
||||
---
|
||||
E -- Thành công --> E1[Gửi lệnh `passwd` > admin123a] --> F
|
||||
E -- Thất bại --> E2[Thử SSH với Password cấu hình]
|
||||
|
||||
## 🛠 Flow Hoạt Động Mạch Trắng (Workflows)
|
||||
E2 -- Thành công --> F
|
||||
E2 -- Thất bại --> Z[DỪNG LẠI - Báo Lỗi]
|
||||
|
||||
Tính năng Flash qua luồng này hoạt động theo một quy trình 5 bước cực kỳ nghiêm ngặt:
|
||||
F -->|Kết nối SSH thành công sau Retry 3 lần| G[Bước 2: Push Firmware SCP vào /tmp/]
|
||||
G -->|Tối đa 3 lần Retry| H[Bước 3: Xác minh File `test -f`]
|
||||
H --> I[Bước 4: Đồng bộ bộ nhớ `sync`]
|
||||
I --> J[Bước 5: Gọi `sysupgrade -F -v -n /tmp/...`]
|
||||
J --> K{Kết nối bị đứt?}
|
||||
K -- Có --> L[Khởi động lại thành công - Báo DONE]
|
||||
K -- Không --> M[Báo lỗi Sysupgrade]
|
||||
```
|
||||
|
||||
### Bước 0: Thiết lập Mật khẩu Đa Kênh qua Cổng 23 (Fallback Mechanism)
|
||||
## 2. Phân Tích Logic Cốt Lõi
|
||||
|
||||
- **Vấn đề của OpenWrt:** Router OpenWrt vừa xuất xưởng (chưa có pass) sẽ **CẤM đăng nhập SSH** cho tài khoản `root`. Lúc này, chỉ cổng cục bộ Telnet (Port 23) là mở.
|
||||
- **Cách Tool vượt qua:**
|
||||
1. Tool tiên phong chọc thẳng bằng **Giao thức Telnet (Port 23)**.
|
||||
2. Dùng chuỗi lệnh `passwd` để thiết lập mật khẩu thành `admin123a` 2 lần. Đợi 3s để OpenWrt kịp đánh thức Server Dropbear (Mở cổng 22 SSH).
|
||||
3. Nếu thiết bị đã có Pass, Tool sẽ mượt mà Rơi xuống nhánh SSH (`old_password` -> `admin123a`).
|
||||
### 2.1 Cơ Chế Dự Phòng Mật Khẩu Đa Tầng (Fallback Mechanism)
|
||||
|
||||
### Bước 1: Khởi tạo Kết nối SSH
|
||||
Điểm mạnh của thuật toán là khả năng "lì lợm" lấy được quyền Root để đặt mật khẩu cho thiết bị. Các lớp dự phòng bao gồm:
|
||||
|
||||
- Sử dụng cờ `AutoAddPolicy` của Python `paramiko` ép kết nối âm thầm chấp nhận mọi Host Certificate mà không bật popup cảnh báo.
|
||||
1. **Telnet (Port 23):** Router OpenWrt khi mới xuất xưởng hoặc ngay sau khi Factory Reset sẽ chặn kết nối SSH bằng tài khoản `root` mất gốc, nhưng lại mở Telnet không có mật khẩu. Script sẽ luôn thử bẻ khóa qua đường này đầu tiên. Bất kỳ ngoại lệ nào phát sinh ở luồng này (Refused, Timeout, Broken Pipe) cũng sẽ kích hoạt fallback.
|
||||
2. **SSH (Mật khẩu rỗng):** Nếu Telnet bị đóng cửa (chứng tỏ thiết bị đã được kích hoạt sơ), phần mềm thử mở cổng 22 với User `root` và mật khẩu rỗng `""`.
|
||||
3. **SSH (Backup Password):** Nếu mật khẩu rỗng bị từ chối bằng `AuthenticationException`, script định nhận diện máy đã bị kẹt một pass được cài đặt trước đó và chèn `backup_password` ra thử nghiệm.
|
||||
4. **SSH (Target Password):** Nếu trượt tới lớp thứ 3, script thử nốt với chính mật khẩu mục tiêu của dự án (mặc định: `admin123a`) để chặn trường hợp thiết bị đã đổi Pass thành công từ lần trước nhưng quá trình nạp Firmware chưa diễn ra.
|
||||
|
||||
### Bước 2: Truyền File bảo mật (SCP vào RAM)
|
||||
### 2.2 Xử Lý Đa Luồng Chống Nghẽn (Concurrency Limits)
|
||||
|
||||
- Thực hiện SCP đẩy BIN firmware (`tim_uImage` hoặc `.bin`) vào phân vùng ảo: `/tmp/<tên_file>.bin`. Đây là khu vực RAM Disk (Ghi siêu tốc, không làm mòn chip nhớ).
|
||||
Thư viện `paramiko` thường dễ đổ vỡ cấu trúc và báo lỗi `[Errno 64] Host is down` hoặc `[Errno 32] Broken Pipe` khi có vài chục luồng (threads) cùng mở port đập vào Network Stack OS (hoặc Switch/Router) ở đúng một chớp mắt. Lỗi này là dạng Transient (có tính tạm thời). Do đó hệ thống được nâng cấp:
|
||||
|
||||
### Bước 3 & 4: Xác thực và Đồng bộ (Verify & Sync)
|
||||
- **Jitter (Độ trễ ngẫu nhiên):** Sử dụng `time.sleep(random.uniform(0.1, 1.5))` trước khi chọc vào thiết bị. Sự sai lệch mili-giây này phân tán chùm yêu cầu dội vào mạng, tránh tự gây ra một cuộc tấn công từ chối dịch vụ (DDoS) nội bộ.
|
||||
- **Vòng lặp (Retry Hooks):** Quá trình đăng nhập (`_create_ssh_client`) cũng như upload payload (`SCPClient.put`) đều được bọc trong bộ đếm thử lại cực đỉnh (thử lại 3 lần sau mỗi 1-2 giây nghỉ). Việc này triệt hạ 99% các lỗi truyền TCP/IP và Timeout.
|
||||
|
||||
- Gửi lệnh `test -f /tmp/...` để xác nhận file.
|
||||
- Gọi lệnh `sync` ép File System đẩy transaction xuống vùng nhớ cứng.
|
||||
### 2.3 Cơ Chế Khôi Phục File (RAM Disk SCP)
|
||||
|
||||
### Bước 5: Sysupgrade (Cài Đặt Lõm)
|
||||
- Firmware được tống thẳng tới phân vùng ảo RAM cục bộ đích (ví dụ: `/tmp/<tên_file>.bin`) thông qua giao thức SCP. Ghi file trực tiếp vào RAM cho phép đạt tốc độ tuyệt đối nhanh và tránh gây hao mòn sinh học lên FlashNOR của router.
|
||||
- Gửi lệnh `sync` qua kênh Shell để ép thiết bị lưu transaction xuống vùng nhớ cứng, chuẩn bị môi trường ổn định nhất.
|
||||
|
||||
- Chạy lệnh ngầm: `sysupgrade -F -v -n /tmp/<tên_file>`.
|
||||
- Cờ `-n`: Clean Flash sạch trơn, không giữ Configuration.
|
||||
- Cờ `-F` (Force): Bỏ qua bộ kiểm tra Image Metadata cho những File thiếu hụt Metadata (uImage).
|
||||
- **Đứt Kết Nối Đột Ngột** khi script đang đợi (sau khoảng 4s trở đi) sẽ mặc định được coi là tín hiệu Thành Công (Server SSH sập nguồn để Reboot).
|
||||
### 2.4 Thủ Thuật Gọi `sysupgrade -F`
|
||||
|
||||
---
|
||||
|
||||
## 🔎 Trình Gỡ Lỗi (Debugging)
|
||||
|
||||
Chạy file `debug_ssh.py` độc lập trên Terminal ở cấp độ TCP Verbose để soi quá trình nạp mới:
|
||||
`./venv/bin/python debug_ssh.py <IP> <DUONG_DAN_FIRMWARE> <PASS>`
|
||||
- OpenWrt đời mới khá kén phần Metadata của Firmware Image. Cờ `-F` cởi trói kiểm duyệt đó và ép hệ điều hành nạp đè File bất chấp sự vắng mặt của metadata uImage. Cờ `-n` khiến hệ thống mất sách cấu hình cũ (Clean Flash).
|
||||
- Lệnh `sysupgrade` sẽ cắn xén cả phần OS dưới lõi máy sau đó Tắt mạng đột ngột. Do đó, script được lập trình để xử lý Exception: Sự kiện **MẤT KẾT NỐI CHỦ ĐỘNG** trong khu vực này là dấu hiệu ăn mừng của việc cài đặt thành công thay vì báo hỏng kết nối.
|
||||
|
||||
Reference in New Issue
Block a user