mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 10:10:43 +00:00
手表端 - 功能页从 10 个杂项精简到 7 个(屏幕/鼠标/媒体/文件/电脑/语音/电源) - 删掉:游戏封锁、待办、掷骰子、抽奖、壁纸、显示器开关、定时关机、 剪贴板历史、性能/磁盘/电量、文件夹浏览、教室限制等 - 改成显式列按钮,不再把电脑端所有功能组无脑铺到表盘 - 远程鼠标控制重做:滑动区 + 左键/滚轮/右键三按钮 滚轮点按=中键、上下滑=滚动 - 新增视频/音乐播放器(手表本地播放):进度拖动、左右滑快进退10秒、 点画面播放暂停、上一/下一、播完自动下一首 电脑端 - 新增 kill_all(结束所有进程),白名单保护系统关键进程和自身 - 新增 media_list / media_pull(播放器数据源) 安全边界:只允许媒体目录,用 relative_to 判断,防同前缀兄弟目录绕过 中转站 - known_devices 从 ID 集合改成「设备ID -> 配对码」映射 - 修复:管理员改码后关机超过 6 小时,改码会被超时清理冲掉 - 老格式 state 文件平滑升级
173 lines
6.4 KiB
Python
173 lines
6.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
r'''重写 Halo 的 nginx 配置:**只写 80 端口那部分**。
|
||
|
||
== 上一版怎么坏的 ==
|
||
|
||
我想"临时把 443 块注释掉",就用脚本给 443 那几行前面加 `#`。
|
||
但那几行里包含 **server 块的结束 `}`** —— 一注释就变成
|
||
"unexpected end of file, expecting }",配置直接不合法。
|
||
|
||
**教训**:注释掉一个配置块要**整块删掉**,不能逐行加 `#`。
|
||
逐行注释会破坏"开括号/闭括号配对",而这种错误 nginx 只会报
|
||
"文件意外结束",不会告诉你少的是哪个括号。
|
||
|
||
== 这一版怎么组织 ==
|
||
|
||
443 块**根本不写** —— 等 DNS 指过来、certbot 签完证书之后,
|
||
再作为独立一步加上去。这样每一步的配置都是**自洽且能通过检查的**,
|
||
不会出现"半截配置"。
|
||
|
||
== 顺带 ==
|
||
|
||
ykxmz 那边原来占着 80 的 default_server,上一版已经把它让出来了
|
||
(`listen 80 default_server` -> `listen 80`)。要看它现在是否正常。
|
||
'''
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parent.parent
|
||
sys.path.insert(0, str(ROOT / "_build"))
|
||
from lssh import run, upload # noqa: E402
|
||
|
||
CONF = """# xxmxxs.top —— Halo 个人博客(**只有 80 端口**,443 等证书)
|
||
#
|
||
# 入口:
|
||
# http://<服务器IP>/ 博客(IP 直接访问)
|
||
# http://<服务器IP>/console 管理后台
|
||
# http://xxmxxs.top/ 301 到 https(证书好了之后)
|
||
#
|
||
# 后端:容器 halo,监听 0.0.0.0:3001,Halo 原生控制台路径是 /console
|
||
#
|
||
# ⚠ 443 那段**故意不在这里** —— DNS 还没指过来,签不到证书。
|
||
# 没证书的 `listen 443 ssl` 会让 nginx -t 直接失败
|
||
# ("no ssl_certificate is defined")。
|
||
# 等 DNS 生效后跑 certbot,它会自己把 443 和证书加进来。
|
||
|
||
# ======================================================================
|
||
# 80 端口默认站点:用 IP 访问时直接出博客
|
||
# ======================================================================
|
||
#
|
||
# nginx 规则:Host 匹配不上任何 server_name 时,用该端口的 default_server。
|
||
# 所以这里设成 default_server -> `http://<服务器IP>/` 就是博客。
|
||
#
|
||
# ⚠ 不做 https 跳转:IP 没证书,跳过去浏览器报警告,用户会以为网站坏了。
|
||
server {
|
||
listen 80 default_server;
|
||
listen [::]:80 default_server;
|
||
server_name _;
|
||
|
||
access_log /var/log/nginx/halo-access.log;
|
||
error_log /var/log/nginx/halo-error.log;
|
||
|
||
server_tokens off;
|
||
client_max_body_size 100m;
|
||
|
||
location / {
|
||
proxy_pass http://127.0.0.1:3001;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "";
|
||
proxy_buffering off;
|
||
proxy_read_timeout 300s;
|
||
}
|
||
}
|
||
|
||
# ======================================================================
|
||
# 80 端口 + 域名:跳 https,并留出 ACME 挑战的位置
|
||
# ======================================================================
|
||
server {
|
||
listen 80;
|
||
listen [::]:80;
|
||
server_name xxmxxs.top www.xxmxxs.top;
|
||
|
||
access_log /var/log/nginx/halo-access.log;
|
||
error_log /var/log/nginx/halo-error.log;
|
||
|
||
server_tokens off;
|
||
client_max_body_size 100m;
|
||
|
||
# ⚠ ACME 挑战必须在 301 之前 ——
|
||
# certbot 的 HTTP-01 要在 80 端口直接拿到文件。
|
||
# 被 301 跳走就续期失败,而且**最多 90 天后才暴露**(证书到期)。
|
||
location /.well-known/acme-challenge/ {
|
||
root /var/www/html;
|
||
default_type "text/plain";
|
||
try_files $uri =404;
|
||
}
|
||
|
||
location / {
|
||
return 301 https://$host$request_uri;
|
||
}
|
||
}
|
||
"""
|
||
|
||
|
||
def main() -> int:
|
||
print("=" * 62)
|
||
print(" 重写 Halo 的 nginx 配置(只 80 端口)")
|
||
print("=" * 62)
|
||
print()
|
||
|
||
tmp = ROOT / "_build" / "_halo_nginx.conf"
|
||
tmp.write_text(CONF, encoding="utf-8", newline="\n")
|
||
upload(str(tmp), "/tmp/halo-nginx.conf")
|
||
tmp.unlink(missing_ok=True)
|
||
|
||
out = run(r'''
|
||
echo "==== 1. 先把坏掉的备份都清掉,重写 ===="
|
||
sudo rm -f /etc/nginx/sites-available/halo.bak.* 2>/dev/null
|
||
sudo mv -f /tmp/halo-nginx.conf /etc/nginx/sites-available/halo
|
||
sudo ln -sf /etc/nginx/sites-available/halo /etc/nginx/sites-enabled/halo
|
||
echo " 写好了"
|
||
|
||
echo
|
||
echo "==== 2. ykxmz 那边现在长什么样(确认 default_server 让出来了)===="
|
||
sudo grep -n "default_server" /etc/nginx/sites-available/ykxmz 2>/dev/null | sed 's/^/ /' || echo " 没有 default_server ✓"
|
||
|
||
echo
|
||
echo "==== 3. 检查配置 ===="
|
||
sudo nginx -t 2>&1 | tail -3 | sed 's/^/ /'
|
||
''', timeout=240, quiet=True)
|
||
o = out[1] if isinstance(out, tuple) else str(out)
|
||
print(o)
|
||
if "successful" not in o:
|
||
print(" ✗ 配置有错,恢复 ykxmz 的 default_server 并停用 halo 站点")
|
||
run("sudo rm -f /etc/nginx/sites-enabled/halo", timeout=90, quiet=True)
|
||
return 1
|
||
|
||
out = run(r'''
|
||
echo "==== 4. 重载 ===="
|
||
sudo systemctl reload nginx && sleep 1
|
||
echo " nginx: $(systemctl is-active nginx)"
|
||
|
||
echo
|
||
echo "==== 5. 复核(对用户要求逐条)===="
|
||
printf " %-46s " "http://127.0.0.1/ (IP -> 博客)"
|
||
curl -s -o /dev/null -w "%{http_code} %{size_download} 字节\n" --max-time 10 http://127.0.0.1/
|
||
printf " %-46s " "http://127.0.0.1/console (控制台)"
|
||
curl -s -o /dev/null -w "%{http_code} %{size_download} 字节\n" --max-time 10 http://127.0.0.1/console
|
||
printf " %-46s " "http://127.0.0.1:3001/ (直连 Halo)"
|
||
curl -s -o /dev/null -w "%{http_code}\n" --max-time 10 http://127.0.0.1:3001/
|
||
printf " %-46s " "https://yk.xxmxxs.top/ (中转站)"
|
||
curl -s -o /dev/null -w "%{http_code} %{size_download} 字节\n" --max-time 12 https://yk.xxmxxs.top/
|
||
printf " %-46s " "https://yk.xxmxxs.top/v1/health"
|
||
curl -s -o /dev/null -w "%{http_code}\n" --max-time 12 https://yk.xxmxxs.top/v1/health
|
||
printf " %-46s " "http://127.0.0.1:9100/ (官网直连通道)"
|
||
curl -s -o /dev/null -w "%{http_code}\n" --max-time 10 http://127.0.0.1:9100/
|
||
echo
|
||
echo "==== 6. 监听端口 ===="
|
||
sudo ss -tlnp 2>/dev/null | grep -E ':(80|443|9100|3001) ' | awk '{print " "$4}' | sort -u
|
||
''', timeout=300, quiet=True)
|
||
print(out[1] if isinstance(out, tuple) else out)
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|