update at 2026-03-15 14:54:51
This commit is contained in:
128
scripts/connect-kindle-usbnet-mac.sh
Executable file
128
scripts/connect-kindle-usbnet-mac.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# 这个脚本用于在 Mac 上给 Kindle 的 USBNetwork 网卡补一个 192.168.15.x 地址,
|
||||
# 然后立刻验证 22 端口和 SSH 公钥登录是否可用。
|
||||
#
|
||||
# 默认值适配当前这台 Kindle:
|
||||
# - Kindle USB IP: 192.168.15.244
|
||||
# - 本机别名 IP: 192.168.15.201
|
||||
# - 默认网卡: en8
|
||||
#
|
||||
# 用法:
|
||||
# sh scripts/connect-kindle-usbnet-mac.sh
|
||||
# sh scripts/connect-kindle-usbnet-mac.sh auto 192.168.15.244 192.168.15.201
|
||||
# sh scripts/connect-kindle-usbnet-mac.sh en8 192.168.15.244 192.168.15.201
|
||||
#
|
||||
# 参数说明:
|
||||
# $1: Mac 上的 USB 网卡名,默认 auto(自动尝试 en8/en11)
|
||||
# $2: Kindle 在 usbnet 模式下的 IP,默认 192.168.15.244
|
||||
# $3: Mac 要补的别名 IP,默认 192.168.15.201
|
||||
|
||||
USB_IFACE="${1:-auto}"
|
||||
KINDLE_IP="${2:-192.168.15.244}"
|
||||
HOST_IP="${3:-192.168.15.201}"
|
||||
|
||||
KEY1="${HOME}/.ssh/id_ed25519"
|
||||
KEY2="${HOME}/.ssh/id_ed25519_git"
|
||||
|
||||
pick_iface() {
|
||||
if [ "${USB_IFACE}" != "auto" ]; then
|
||||
echo "${USB_IFACE}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 当前这台 Mac 在 Kindle 插入后会出现多个活动的 USB 相关接口,
|
||||
# 实测常见候选是 en8 和 en11。这里按顺序轮询,哪个能打通 22 端口就用哪个。
|
||||
for iface in en8 en11; do
|
||||
if ! ifconfig "${iface}" >/dev/null 2>&1; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo >&2
|
||||
echo "== 尝试接口 ${iface} ==" >&2
|
||||
sudo ifconfig "${iface}" inet "${HOST_IP}" netmask 255.255.255.0 alias >/dev/null 2>&1 || true
|
||||
sudo arp -d "${KINDLE_IP}" >/dev/null 2>&1 || true
|
||||
|
||||
echo "当前网卡状态:" >&2
|
||||
ifconfig "${iface}" >&2
|
||||
|
||||
echo >&2
|
||||
echo "路由检查:" >&2
|
||||
route -n get "${KINDLE_IP}" >&2 || true
|
||||
|
||||
echo >&2
|
||||
echo "22 端口探测:" >&2
|
||||
if nc -vz -G 5 "${KINDLE_IP}" 22; then
|
||||
echo "${iface}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "接口 ${iface} 未打通,清理别名后继续尝试下一个。" >&2
|
||||
sudo ifconfig "${iface}" -alias "${HOST_IP}" >/dev/null 2>&1 || true
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
echo "== 配置 USB 网卡 =="
|
||||
echo "接口参数: ${USB_IFACE}"
|
||||
echo "Kindle IP: ${KINDLE_IP}"
|
||||
echo "本机别名 IP: ${HOST_IP}"
|
||||
|
||||
FOUND_IFACE="$(pick_iface)" || {
|
||||
echo
|
||||
echo "未能在候选 USB 网卡上打通 ${KINDLE_IP}:22。"
|
||||
echo "通常说明 Kindle 端的 sshd/dropbear 没有在跑,或者 USBNetwork 链路本身还没真正连起来。"
|
||||
exit 1
|
||||
}
|
||||
|
||||
USB_IFACE="${FOUND_IFACE}"
|
||||
|
||||
echo
|
||||
echo "== 选中的接口 =="
|
||||
echo "${USB_IFACE}"
|
||||
|
||||
echo
|
||||
echo "== 尝试使用第一把密钥登录 =="
|
||||
if [ -f "${KEY1}" ]; then
|
||||
if ssh -i "${KEY1}" \
|
||||
-o BatchMode=yes \
|
||||
-o IdentitiesOnly=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/tmp/kindle_usbnet_known_hosts_1 \
|
||||
root@"${KINDLE_IP}" true; then
|
||||
echo "第一把密钥验证成功,进入交互登录。"
|
||||
exec ssh -i "${KEY1}" \
|
||||
-o IdentitiesOnly=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/tmp/kindle_usbnet_known_hosts_1 \
|
||||
root@"${KINDLE_IP}"
|
||||
fi
|
||||
else
|
||||
echo "未找到密钥: ${KEY1}"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "== 尝试使用第二把密钥登录 =="
|
||||
if [ -f "${KEY2}" ]; then
|
||||
if ssh -i "${KEY2}" \
|
||||
-o BatchMode=yes \
|
||||
-o IdentitiesOnly=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/tmp/kindle_usbnet_known_hosts_2 \
|
||||
root@"${KINDLE_IP}" true; then
|
||||
echo "第二把密钥验证成功,进入交互登录。"
|
||||
exec ssh -i "${KEY2}" \
|
||||
-o IdentitiesOnly=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/tmp/kindle_usbnet_known_hosts_2 \
|
||||
root@"${KINDLE_IP}"
|
||||
fi
|
||||
else
|
||||
echo "未找到密钥: ${KEY2}"
|
||||
fi
|
||||
|
||||
echo "两把密钥都未登录成功。"
|
||||
exit 1
|
||||
87
scripts/kindle/ssh-collect.sh
Normal file
87
scripts/kindle/ssh-collect.sh
Normal file
@@ -0,0 +1,87 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# 采集 Kindle 当前 SSH、网络、进程、配置等诊断信息。
|
||||
# 输出目录会落在 /mnt/us/ssh-debug/<时间戳>/collect.log。
|
||||
|
||||
TS="$(date +%Y%m%d-%H%M%S 2>/dev/null || echo now)"
|
||||
OUT_DIR="/mnt/us/ssh-debug/${TS}"
|
||||
LOG_FILE="${OUT_DIR}/collect.log"
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
exec >"${LOG_FILE}" 2>&1
|
||||
|
||||
echo "=== BASIC ==="
|
||||
date 2>/dev/null || true
|
||||
id 2>/dev/null || true
|
||||
uname -a 2>/dev/null || true
|
||||
echo "HOME=${HOME:-}"
|
||||
|
||||
echo
|
||||
echo "=== ROOT PASSWD ENTRY ==="
|
||||
grep '^root:' /etc/passwd 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== SSH BINARIES ==="
|
||||
ls -l /usr/sbin/sshd /mnt/us/usbnet/sbin/sshd /usr/bin/dropbear /mnt/us/usbnet/bin/dropbearmulti 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== PROCESS LIST ==="
|
||||
ps -ef 2>/dev/null || ps 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== LSOF TCP:22 ==="
|
||||
if [ -x /mnt/us/usbnet/bin/lsof ]; then
|
||||
/mnt/us/usbnet/bin/lsof -n -P -iTCP:22 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== LSOF ALL TCP LISTENERS ==="
|
||||
if [ -x /mnt/us/usbnet/bin/lsof ]; then
|
||||
/mnt/us/usbnet/bin/lsof -n -P -iTCP -sTCP:LISTEN 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== /PROC/NET/TCP ==="
|
||||
cat /proc/net/tcp 2>/dev/null || true
|
||||
cat /proc/net/tcp6 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== NETWORK ==="
|
||||
ifconfig -a 2>/dev/null || ifconfig 2>/dev/null || true
|
||||
route -n 2>/dev/null || netstat -rn 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== IPTABLES ==="
|
||||
iptables -S 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== USBNET RUN DIR ==="
|
||||
ls -la /mnt/us/usbnet/run 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== USBNET CONFIG FILES ==="
|
||||
for f in /mnt/us/usbnet/etc/config /mnt/us/usbnet/etc/sshd_config /mnt/us/usbnet/etc/authorized_keys; do
|
||||
echo "--- ${f} ---"
|
||||
sed -n '1,200p' "${f}" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo
|
||||
echo "=== SYSTEM SSHD -T ==="
|
||||
/usr/sbin/sshd -T 2>&1 || true
|
||||
|
||||
echo
|
||||
echo "=== USBNET SSHD -T ==="
|
||||
/mnt/us/usbnet/sbin/sshd -T -f /mnt/us/usbnet/etc/sshd_config 2>&1 || true
|
||||
|
||||
echo
|
||||
echo "=== COMMON SSH DIRS ==="
|
||||
for d in /root/.ssh /var/local/root/.ssh "${HOME:-/root}/.ssh" /mnt/us/usbnet/etc/dot.ssh; do
|
||||
echo "--- ${d} ---"
|
||||
ls -la "${d}" 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo
|
||||
echo "=== DONE ==="
|
||||
echo "${OUT_DIR}"
|
||||
38
scripts/kindle/ssh-fix-all-keys.sh
Normal file
38
scripts/kindle/ssh-fix-all-keys.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# 把 usbnet 共用的 authorized_keys 同步到几处常见 root SSH 目录,
|
||||
# 避免不同 sshd/dropbear 读取路径不一致。
|
||||
|
||||
TS="$(date +%Y%m%d-%H%M%S 2>/dev/null || echo now)"
|
||||
OUT_DIR="/mnt/us/ssh-debug/${TS}"
|
||||
LOG_FILE="${OUT_DIR}/fix-all-keys.log"
|
||||
SOURCE_KEYS="/mnt/us/usbnet/etc/authorized_keys"
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
exec >"${LOG_FILE}" 2>&1
|
||||
|
||||
ROOT_HOME="$(awk -F: '/^root:/{print $6}' /etc/passwd 2>/dev/null || true)"
|
||||
[ -n "${ROOT_HOME}" ] || ROOT_HOME="/tmp/root"
|
||||
|
||||
echo "Root home: ${ROOT_HOME}"
|
||||
echo "Source keys: ${SOURCE_KEYS}"
|
||||
|
||||
for target_dir in "${ROOT_HOME}/.ssh" /root/.ssh /var/local/root/.ssh /mnt/us/usbnet/etc/dot.ssh; do
|
||||
echo "--- target: ${target_dir} ---"
|
||||
mkdir -p "${target_dir}"
|
||||
if [ -f "${target_dir}/authorized_keys" ]; then
|
||||
cp "${target_dir}/authorized_keys" "${target_dir}/authorized_keys.bak.${TS}" || true
|
||||
fi
|
||||
cp "${SOURCE_KEYS}" "${target_dir}/authorized_keys"
|
||||
chmod 700 "${target_dir}" 2>/dev/null || true
|
||||
chmod 600 "${target_dir}/authorized_keys" 2>/dev/null || true
|
||||
ls -ld "${target_dir}" "${target_dir}/authorized_keys" 2>/dev/null || true
|
||||
done
|
||||
|
||||
killall -HUP sshd 2>/dev/null || true
|
||||
|
||||
echo
|
||||
echo "=== DONE ==="
|
||||
echo "${OUT_DIR}"
|
||||
44
scripts/kindle/ssh-force-dropbear-22.sh
Normal file
44
scripts/kindle/ssh-force-dropbear-22.sh
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# 强制清理残留 SSH 进程,然后在 22 端口拉起一份 usbnet 自带的 DropBear。
|
||||
# 这里使用 Kindle hack 里的 -n,让其不走密码检查,方便恢复公钥访问。
|
||||
|
||||
TS="$(date +%Y%m%d-%H%M%S 2>/dev/null || echo now)"
|
||||
OUT_DIR="/mnt/us/ssh-debug/${TS}"
|
||||
LOG_FILE="${OUT_DIR}/force-dropbear-22.log"
|
||||
PID_FILE="/mnt/us/usbnet/run/dropbear-force-22.pid"
|
||||
|
||||
mkdir -p "${OUT_DIR}" /mnt/us/usbnet/run
|
||||
exec >"${LOG_FILE}" 2>&1
|
||||
|
||||
echo "=== FORCE DROPBEAR 22 ==="
|
||||
date 2>/dev/null || true
|
||||
id 2>/dev/null || true
|
||||
|
||||
killall sshd 2>/dev/null || true
|
||||
killall dropbear 2>/dev/null || true
|
||||
killall dropbearmulti 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
rm -f "${PID_FILE}" 2>/dev/null || true
|
||||
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT 2>/dev/null || true
|
||||
|
||||
(
|
||||
cd /mnt/us/usbnet
|
||||
exec bin/dropbearmulti dropbear -F -E -p 22 -P "${PID_FILE}" -n
|
||||
) &
|
||||
|
||||
LAUNCHER_PID="$!"
|
||||
echo "${LAUNCHER_PID}" > "${OUT_DIR}/launcher.pid"
|
||||
sleep 1
|
||||
|
||||
echo "launcher pid: ${LAUNCHER_PID}"
|
||||
echo "pid file: ${PID_FILE}"
|
||||
if [ -x /mnt/us/usbnet/bin/lsof ]; then
|
||||
/mnt/us/usbnet/bin/lsof -n -P -iTCP:22 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "=== DONE ==="
|
||||
echo "${OUT_DIR}"
|
||||
63
scripts/kindle/ssh-force-openssh-22.sh
Normal file
63
scripts/kindle/ssh-force-openssh-22.sh
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# 强制清理残留 SSH 进程,然后在 22 端口拉起一份 usbnet 自带的 OpenSSH。
|
||||
# 这份 sshd 会优先读取 /mnt/us/usbnet/etc/dot.ssh/authorized_keys。
|
||||
|
||||
TS="$(date +%Y%m%d-%H%M%S 2>/dev/null || echo now)"
|
||||
OUT_DIR="/mnt/us/ssh-debug/${TS}"
|
||||
LOG_FILE="${OUT_DIR}/force-openssh-22.log"
|
||||
PID_FILE="/mnt/us/usbnet/run/sshd-force-22.pid"
|
||||
SOURCE_KEYS="/mnt/us/usbnet/etc/authorized_keys"
|
||||
TARGET_KEYS="/mnt/us/usbnet/etc/dot.ssh/authorized_keys"
|
||||
|
||||
mkdir -p "${OUT_DIR}" /mnt/us/usbnet/run /mnt/us/usbnet/etc/dot.ssh
|
||||
exec >"${LOG_FILE}" 2>&1
|
||||
|
||||
echo "=== FORCE OPENSSH 22 ==="
|
||||
date 2>/dev/null || true
|
||||
id 2>/dev/null || true
|
||||
|
||||
if [ -f "${SOURCE_KEYS}" ]; then
|
||||
cp "${SOURCE_KEYS}" "${TARGET_KEYS}"
|
||||
chmod 600 "${TARGET_KEYS}" 2>/dev/null || true
|
||||
fi
|
||||
chmod 755 /mnt/us/usbnet/etc/dot.ssh 2>/dev/null || true
|
||||
|
||||
killall sshd 2>/dev/null || true
|
||||
killall dropbear 2>/dev/null || true
|
||||
killall dropbearmulti 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
rm -f "${PID_FILE}" 2>/dev/null || true
|
||||
iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT 2>/dev/null || true
|
||||
|
||||
(
|
||||
exec /mnt/us/usbnet/sbin/sshd -D -e \
|
||||
-f /mnt/us/usbnet/etc/sshd_config \
|
||||
-o ListenAddress=0.0.0.0 \
|
||||
-o Port=22 \
|
||||
-o PidFile="${PID_FILE}" \
|
||||
-o AuthorizedKeysFile="${TARGET_KEYS}" \
|
||||
-o PasswordAuthentication=no \
|
||||
-o KbdInteractiveAuthentication=no \
|
||||
-o PubkeyAuthentication=yes \
|
||||
-o PermitRootLogin=yes \
|
||||
-o HostKey=/mnt/us/usbnet/etc/ssh_host_rsa_key \
|
||||
-o HostKey=/mnt/us/usbnet/etc/ssh_host_ecdsa_key \
|
||||
-o HostKey=/mnt/us/usbnet/etc/ssh_host_ed25519_key
|
||||
) &
|
||||
|
||||
LAUNCHER_PID="$!"
|
||||
echo "${LAUNCHER_PID}" > "${OUT_DIR}/launcher.pid"
|
||||
sleep 1
|
||||
|
||||
echo "launcher pid: ${LAUNCHER_PID}"
|
||||
echo "pid file: ${PID_FILE}"
|
||||
if [ -x /mnt/us/usbnet/bin/lsof ]; then
|
||||
/mnt/us/usbnet/bin/lsof -n -P -iTCP:22 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "=== DONE ==="
|
||||
echo "${OUT_DIR}"
|
||||
28
scripts/kindle/ssh-stop-all.sh
Normal file
28
scripts/kindle/ssh-stop-all.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# 停掉常见 SSH 进程,并清理掉常见 pid 文件。
|
||||
|
||||
TS="$(date +%Y%m%d-%H%M%S 2>/dev/null || echo now)"
|
||||
OUT_DIR="/mnt/us/ssh-debug/${TS}"
|
||||
LOG_FILE="${OUT_DIR}/stop-all.log"
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
exec >"${LOG_FILE}" 2>&1
|
||||
|
||||
echo "=== STOP ALL SSH DAEMONS ==="
|
||||
date 2>/dev/null || true
|
||||
id 2>/dev/null || true
|
||||
|
||||
killall sshd 2>/dev/null || true
|
||||
killall dropbear 2>/dev/null || true
|
||||
killall dropbearmulti 2>/dev/null || true
|
||||
|
||||
rm -f /mnt/us/usbnet/run/sshd.pid 2>/dev/null || true
|
||||
rm -f /mnt/us/usbnet/run/sshd-force-22.pid 2>/dev/null || true
|
||||
rm -f /mnt/us/usbnet/run/dropbear-2222.pid 2>/dev/null || true
|
||||
rm -f /mnt/us/usbnet/run/dropbear-force-22.pid 2>/dev/null || true
|
||||
|
||||
echo "=== DONE ==="
|
||||
echo "${OUT_DIR}"
|
||||
Reference in New Issue
Block a user