Initial commit: MyBlog full stack blog

This commit is contained in:
2026-08-22 22:28:41 +08:00
commit c61193f2af
64 changed files with 7290 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
# MyBlog IP 白名单自动更新(家庭端)
## 这是什么
家庭宽带的公网 IP 会不定期变化。阿里云安全组 22 端口如果只放行固定 IP,
换 IP 后你就会被自己挡在门外。
这套方案让家庭电脑定时检测自己的公网 IP,一旦变化就通知服务器,
服务器自动调用阿里云 API 把安全组 22 端口白名单更新为最新 IP。
流程:
1. report.ps1 请求 博客/myip 获取当前公网 IP
2. 与上次记录比较,有变化时 POST /api/ipwatch/report
3. 服务器调用阿里云 API 更新安全组(先加新规则、后删旧规则)
## 家庭端配置步骤(Windows
1. 复制 ipwatch.conf.example 为 ipwatch.conf,填写:
- SERVER:博客地址(默认 https://guzhujushi.cn
- SECRET:与服务器 .env 中 IPWATCH_SECRET 相同
2. 运行安装脚本(注册每 30 分钟的计划任务并立即执行一次):
powershell -ExecutionPolicy Bypass -File .\install.ps1
3. 查看日志确认成功:
Get-Content .\ipwatch.log
正常会看到:白名单更新成功:你的公网IP(服务器:白名单更新成功)
或:公网 IP 未变化:xxx(表示无需更新,正常)。
## 手动运行 / 卸载
powershell -ExecutionPolicy Bypass -File .\report.ps1
powershell -ExecutionPolicy Bypass -File .\uninstall.ps1
## 安全说明
- 家庭端只保存 IPWATCH_SECRET(随机字符串);阿里云 AccessKey 只存在服务器
.env 中,不要复制到家庭端或提交到 git。
- 如果 IPWATCH_SECRET 泄露:登录服务器改 .env 里的值,再同步修改本目录
ipwatch.conf,最后重启后端服务即可。
- 服务器端每次上报限流 60 秒一次,且只增删 22 端口 /32 单 IP 规则。
+33
View File
@@ -0,0 +1,33 @@
# ============================================================
# 安装 MyBlog IP 白名单定时任务(家庭 Windows 电脑)
# 作用:注册 Windows 计划任务,每 30 分钟自动运行 report.ps1
# 前置:已复制 ipwatch.conf.example 为 ipwatch.conf 并填写
# 用法:powershell -ExecutionPolicy Bypass -File .\install.ps1
# 说明:计划任务在“当前登录用户”下运行;如需开机无登录也运行,
# 请右键任务 -> 属性勾选“不管用户是否登录都要运行”
# ============================================================
$ErrorActionPreference = "Stop"
$ScriptDir = $PSScriptRoot
$Report = Join-Path $ScriptDir "report.ps1"
$ConfFile = Join-Path $ScriptDir "ipwatch.conf"
if (-not (Test-Path -LiteralPath $ConfFile)) {
Write-Host "缺少 ipwatch.conf:请先复制 ipwatch.conf.example 并填写 SERVER / SECRET" -ForegroundColor Red
exit 1
}
$TaskName = "MyBlogIPWatch"
# /TR 里对带空格的脚本路径加引号,PowerShell 会整体作为一个参数传给 schtasks
$Action = "powershell.exe -NoProfile -ExecutionPolicy Bypass -File `"$Report`""
& schtasks /Create /F /TN $TaskName /SC MINUTE /MO 30 /TR $Action | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host "创建计划任务失败,请确认以管理员身份运行或检查 schtasks 输出" -ForegroundColor Red
exit 1
}
# 创建后立即运行一次,马上验证配置是否正确
& schtasks /Run /TN $TaskName | Out-Null
Write-Host "计划任务 $TaskName 已创建:每 30 分钟自动检查公网 IP。"
Write-Host "日志文件:$(Join-Path $ScriptDir 'ipwatch.log')"
Write-Host "(首次运行结果可在日志中查看;卸载请运行 uninstall.ps1"
+7
View File
@@ -0,0 +1,7 @@
# MyBlog IP 白名单自动上报配置(家庭 Windows 电脑)
# 用法:复制本文件为 ipwatch.conf 并填写下面两项,再运行 install.ps1
#
# SERVER:博客地址(必须能访问 /myip 与 /api/ipwatch/report),一般填域名
# SECRET:必须与服务器 .env 里的 IPWATCH_SECRET 完全一致
SERVER=https://guzhujushi.cn
SECRET=请填写与服务器 IPWATCH_SECRET 相同的值
+77
View File
@@ -0,0 +1,77 @@
# ============================================================
# MyBlog IP 白名单自动上报脚本(在家庭 Windows 电脑上运行)
# 作用:读取当前公网 IP -> 与上次记录比较 -> 有变化就通知服务器
# 更新阿里云安全组 22 端口白名单(避免换 IP 后 SSH 连不上)
# 用法:
# 手动运行: powershell -ExecutionPolicy Bypass -File .\report.ps1
# 定时运行: 先运行 install.ps1(注册每 30 分钟执行一次的计划任务)
# 退出码:0=成功(含无需更新) 1=配置错误 2=取IP失败 3=IP不合法 4=服务器拒绝 5=网络错误
# ============================================================
$ErrorActionPreference = "Stop"
$ScriptDir = $PSScriptRoot
$ConfFile = Join-Path $ScriptDir "ipwatch.conf"
$LastFile = Join-Path $ScriptDir "lastip.txt"
$LogFile = Join-Path $ScriptDir "ipwatch.log"
# ---------- 1. 读取配置 ----------
$Server = ""
$Secret = ""
if (Test-Path -LiteralPath $ConfFile) {
Get-Content -LiteralPath $ConfFile -Encoding UTF8 | ForEach-Object {
$line = $_.Trim()
if ($line -match '^SERVER\s*=\s*(.+)$') { $Server = $Matches[1].Trim().Trim('"') }
elseif ($line -match '^SECRET\s*=\s*(.+)$') { $Secret = $Matches[1].Trim().Trim('"') }
}
}
if (-not $Server -or -not $Secret) {
Write-Host "配置不完整:请复制 ipwatch.conf.example 为 ipwatch.conf,并填写 SERVER 与 SECRET" -ForegroundColor Red
exit 1
}
# ---------- 2. 日志工具 ----------
function Write-Log([string]$message) {
$line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') $message"
try { Add-Content -LiteralPath $LogFile -Value $line -Encoding UTF8 } catch { }
Write-Host $line
}
# ---------- 3. 获取当前公网 IP(走博客的 /myip 接口) ----------
# 旧系统默认不启用 TLS1.2,先强制开启,否则 HTTPS 请求会失败
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
try {
$current = (Invoke-RestMethod -Uri "$Server/myip" -TimeoutSec 20).ToString().Trim()
} catch {
Write-Log "获取公网 IP 失败:$($_.Exception.Message)"
exit 2
}
if ($current -notmatch '^\d{1,3}(\.\d{1,3}){3}$') {
Write-Log "服务器返回的不是合法 IP$current"
exit 3
}
# ---------- 4. 与上次记录比较,没变化就不打扰服务器 ----------
$last = ""
if (Test-Path -LiteralPath $LastFile) {
$last = (Get-Content -LiteralPath $LastFile -Raw -Encoding UTF8).Trim()
}
if ($current -eq $last) {
Write-Host "公网 IP 未变化:$current"
exit 0
}
# ---------- 5. IP 有变化:上报给服务器,由服务器更新安全组 ----------
try {
$body = @{ secret = $Secret; ip = $current } | ConvertTo-Json
$resp = Invoke-RestMethod -Uri "$Server/api/ipwatch/report" -Method Post -Body $body -ContentType "application/json; charset=utf-8" -TimeoutSec 40
if ($resp.success) {
Set-Content -LiteralPath $LastFile -Value $current -Encoding UTF8
Write-Log "白名单更新成功:$current(服务器:$($resp.message)"
exit 0
} else {
Write-Log "服务器返回失败:$($resp.message)"
exit 4
}
} catch {
Write-Log "上报失败:$($_.Exception.Message)"
exit 5
}
+4
View File
@@ -0,0 +1,4 @@
# 卸载 MyBlog IP 白名单定时任务
$ErrorActionPreference = "Stop"
& schtasks /Delete /F /TN "MyBlogIPWatch" | Out-Null
if ($LASTEXITCODE -eq 0) { Write-Host "计划任务 MyBlogIPWatch 已删除" }