Update ocixjj.sh

This commit is contained in:
振振君子 authored and GitHub committed 2026-09-09 19:28:19 +08:00
1 parent 1327b69f49
commit 1bfc6a2efb
1 file changed
+27 -9
+27 -9
View File
@@ -24,6 +24,16 @@
# 不放行这条,本机端口再怎么开都连不进来,是两道独立的墙。
# (跑 init 时脚本会打印出本机公网IP,方便你去控制台核对)
#
# ---------------------------------------------------------------------------
# 关于端口转发方式(重要变更说明):
# 旧版每个端口用 incus proxy device 走用户态转发(forkproxy 进程),
# 每台小鸡 20 端口(tcp+udp)= 40 个常驻进程,台数一多内存/句柄容易爆炸。
#
# 本版改为 proxy device 加 nat=true,由内核态 iptables/nftables 直接做
# DNAT 转发,不再为每个端口 fork 进程,几乎零额外常驻内存开销。
# 代价:nat=true 模式下宿主机不会真的 listen 该端口(是DNAT不是accept),
# 所以 check 命令改用查 iptables NAT 规则 + 实际连接测试来验证,而不是 ss -tln。
# ---------------------------------------------------------------------------
set -e
@@ -157,6 +167,9 @@ cmd_create() {
}
# 端口段是否与本机已在监听的端口冲突(比如80/443/其他服务),冲突则跳过整段往后找
# 注意: nat=true 模式下,已分配给其他小鸡的端口不会出现在 ss -tln 里(是DNAT不是listen),
# 所以这里只能防真实占用(比如宿主机自己跑的服务),防不了"跟其他小鸡端口段重叠"。
# 重叠问题由 STATE_FILE 递增分配来保证,不依赖 ss 检测。
find_free_port_start() {
local candidate=$1
while true; do
@@ -220,18 +233,23 @@ cmd_create() {
incus exec "$NAME" -- sh -c "echo 'root:${PASSWORD}' | chpasswd"
incus exec "$NAME" -- sh -c "rc-update add sshd default && (rc-service sshd restart || rc-service sshd start)"
# ---- 端口转发: 全部走 nat=true 内核态转发,不再 fork 用户态进程 ----
# 注意 connect 目标必须是容器的真实IP(不能用127.0.0.1),因为是内核DNAT。
SSH_PORT=$PORT_START
incus config device add "$NAME" sshport proxy \
listen=tcp:0.0.0.0:${SSH_PORT} \
connect=tcp:127.0.0.1:22 >/dev/null
connect=tcp:${IP}:22 \
nat=true >/dev/null
for p in $(seq $((PORT_START+1)) $PORT_END); do
incus config device add "$NAME" "tcp-$p" proxy \
listen=tcp:0.0.0.0:${p} \
connect=tcp:127.0.0.1:${p} >/dev/null
connect=tcp:${IP}:${p} \
nat=true >/dev/null
incus config device add "$NAME" "udp-$p" proxy \
listen=udp:0.0.0.0:${p} \
connect=udp:127.0.0.1:${p} >/dev/null
connect=udp:${IP}:${p} \
nat=true >/dev/null
done
echo -e "${NAME}\t${IP}\t${SSH_PORT}\t${PORT_START}-${PORT_END}\t${PASSWORD}\t${CPU}\t${MEM}\t${DISK}" >> "$LOG_FILE"
@@ -322,7 +340,7 @@ cmd_delete() {
exit 1
fi
echo "删除容器 $NAME(会自动清理其端口转发规则)..."
echo "删除容器 $NAME(会自动清理其端口转发规则,包括nat=true下发的iptables规则)..."
incus delete "$NAME" --force
if [ -f "$LOG_FILE" ]; then
@@ -357,11 +375,11 @@ cmd_check() {
PASSWORD=$(echo "$ROW" | cut -f5)
echo "===== 自检 $NAME (本机SSH端口 ${SSH_PORT}) ====="
echo "1) 端口本机是否在监听:"
if ss -tln 2>/dev/null | grep -q ":${SSH_PORT} "; then
echo " OK - 本机确实在监听 ${SSH_PORT}"
echo "1) NAT转发规则是否已下发(nat=true模式下宿主机不会listen该端口,查iptables NAT表):"
if iptables -t nat -L PREROUTING -n 2>/dev/null | grep -q "dpt:${SSH_PORT}[^0-9]"; then
echo " OK - 找到 ${SSH_PORT} 的DNAT规则"
else
echo " !! 本机没有监听 ${SSH_PORT},proxy device 可能没生效,检查: incus config device list ${NAME}"
echo " !! 没找到 ${SSH_PORT} 的DNAT规则,proxy device 可能没生效,检查: incus config device list ${NAME}"
return
fi
@@ -372,7 +390,7 @@ cmd_check() {
if sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 \
root@127.0.0.1 -p "$SSH_PORT" 'echo 本机内部连接成功' 2>/dev/null; then
echo " OK - 本机内部能连通,说明 Incus 转发链路没问题"
echo " OK - 本机内部能连通,说明 Incus NAT 转发链路没问题"
echo " 若外部(比如你自己电脑)连不上,问题基本可以定位在: OCI控制台Security List 没放行"
else
echo " !! 本机内部都连不上,问题在 Incus/容器内sshd本身,检查: incus exec ${NAME} -- rc-service sshd status"