首页
留言
导航
统计
Search
1
追番推荐!免费看动漫的网站 - 支持在线观看和磁力下载
2,508 阅读
2
推荐31个docker应用,每一个都很实用
1,311 阅读
3
PVE自动启动 虚拟机 | 容器 顺序设置及参数说明
931 阅读
4
一条命令,永久激活!Office 2024!
618 阅读
5
优选 Cloudflare 官方 / 中转 IP
489 阅读
默认分类
服务器
宝塔
VPS
Docker
OpenWRT
Nginx
群晖
前端编程
Vue
React
Angular
NodeJS
uni-app
后端编程
Java
Python
SpringBoot
SpringCloud
流程引擎
检索引擎
Linux
CentOS
Ubuntu
Debian
数据库
Redis
MySQL
Oracle
虚拟机
VMware
VirtualBox
PVE
Hyper-V
计算机
网络技术
网站源码
主题模板
登录
Search
标签搜索
Java
小程序
Redis
SpringBoot
docker
Typecho
Cloudflare
docker部署
虚拟机
WordPress
群晖
uni-app
CentOS
Vue
Java类库
Linux命令
防火墙配置
Mysql
脚本
Nginx
微醺
累计撰写
264
篇文章
累计收到
11
条评论
首页
栏目
默认分类
服务器
宝塔
VPS
Docker
OpenWRT
Nginx
群晖
前端编程
Vue
React
Angular
NodeJS
uni-app
后端编程
Java
Python
SpringBoot
SpringCloud
流程引擎
检索引擎
Linux
CentOS
Ubuntu
Debian
数据库
Redis
MySQL
Oracle
虚拟机
VMware
VirtualBox
PVE
Hyper-V
计算机
网络技术
网站源码
主题模板
页面
留言
导航
统计
搜索到
55
篇与
的结果
2026-01-22
Docker 一键部署 WireGuard VPN,支持可视化管理与监控
🌟 引言随着远程办公、跨地域访问与隐私保护需求的不断增长,VPN(虚拟专用网络) 正在成为个人与企业必备的基础设施之一。而传统的 WireGuard VPN 配置流程对于普通用户而言存在一定门槛,需要大量命令行操作与手动配置。WG-Easy 正是在这种背景下应运而生的高效解决方案,它将 WireGuard 的强大性能与可视化管理相结合,大大降低部署和维护难度。💡 项目简介WG-Easy(WireGuard Easy) 是一个将 WireGuard VPN 核心服务与 Web 可视化管理界面深度集成的开源项目。它通过直观的浏览器操作界面,让用户无需掌握复杂的命令行知识,即可快速完成 VPN 的部署、配置与监控。设计理念:📦 开箱即用:基于 Docker 容器化部署,一条命令即可启动🖱️ 可视化优先:所有操作均可在 Web 界面完成,告别配置文件🚀 性能卓越:基于 WireGuard 协议,提供媲美直连的网络速度🔒 安全可靠:采用现代密码学套件,代码简洁易审计🎯 核心特性WireGuard Easy 提供了一套完整的 VPN 管理功能,主要特性包括:🧩 一体化架构:将 WireGuard 核心 VPN 与 Web 管理界面整合在一起。🚀 快速部署:基于 Docker 容器化,一条命令即可启动完整 VPN 服务。🖥️ 可视化管理面板:客户端创建、编辑、禁用、删除全部图形化完成。📱 二维码一键接入:自动生成配置二维码,便于移动设备一键连接。🔗 一次性分享链接:生成临时配置链接,分享后自动失效,提升安全性📊 实时连接与流量监控:显示每个客户端的在线状态、上传 / 下载流量。🌗 多语言 & 深浅色模式:自动适配浏览器语言,支持暗黑模式。📈Prometheus 监控支持:原生支持 Prometheus,便于接入 Grafana 统一监控体系。🔑 双因素认证(2FA):支持 TOTP 双因素认证,提升账户安全。🔐 继承 WireGuard 的安全模型:公钥认证、现代加密算法,无密码、无证书链复杂度。ℹ️ 环境信息🔍 WireGuard 内核支持检查在部署前,请确认服务器内核已支持 WireGuard:uname -r加载 WireGuard 内核模块:modprobe wireguard验证是否成功:lsmod | grep wireguard说明:Linux Kernel ≥ 5.6 已内置 WireGuardUbuntu 20.04+ / 22.04 LTS 默认支持若加载失败,请检查内核版本或云厂商是否裁剪模块基础环境云服务器(VPS / 轻量云 / 物理机)操作系统:Ubuntu 22.04 LTS(推荐)具有域名 或 公网 IP已安装 Docker / Docker Compose网络与安全组要求UDP 51820(WireGuard 通信端口)TCP 51821(wg-easy Web 管理界面)出口网络允许访问公网(用于 VPN 转发)🔥 配置防火墙规则# Ubuntu/Debian (使用 ufw) sudo ufw allow 51820/udp comment 'WireGuard VPN' sudo ufw allow 51821/tcp comment 'WG-Easy Web UI'⚠️ 若云厂商启用防火墙 / 安全组,务必同步放行端口。📦 部署教程🚀 方式一:Docker 命令行部署(快速上手)1️⃣ 创建网络docker network create \ -d bridge --ipv6 \ --subnet 10.42.42.0/24 \ --subnet fdcc:ad94:bacf:61a3::/64 \ wg2️⃣ 启动容器docker run -d \ --net wg \ -e INSECURE=true \ --name wg-easy \ --ip6 fdcc:ad94:bacf:61a3::2a \ --ip 10.42.42.42 \ -v ~/.wg-easy:/etc/wireguard \ -v /lib/modules:/lib/modules:ro \ -p 51820:51820/udp \ -p 51821:51821/tcp \ --cap-add NET_ADMIN \ --cap-add SYS_MODULE \ --sysctl net.ipv4.ip_forward=1 \ --sysctl net.ipv4.conf.all.src_valid_mark=1 \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --sysctl net.ipv6.conf.all.forwarding=1 \ --sysctl net.ipv6.conf.default.forwarding=1 \ --restart unless-stopped \ ghcr.io/wg-easy/wg-easy:153️⃣ 访问 Web 界面访问浏览器 http://服务器IP:51821 即可进入界面。🐳 方式二:Docker Compose 部署(推荐)1️⃣ 安装 Docker Compose# Ubuntu/Debian # sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo apt install -y docker-compose-plugin2️⃣ 创建配置目录mkdir ~/wg-easy/ && mkdir ~/wg-easy/3️⃣ 下载 Docker Compose 文件sudo curl -o /etc/docker/containers/wg-easy/docker-compose.yml https://raw.githubusercontent.com/wg-easy/wg-easy/master/docker-compose.yml4️⃣ 修改配置编辑docker-compose.yml文件并取消environment注释INSECURE设置INSECURE为true允许通过非安全http连接访问 Web UI。完整 docker-compose.yml 文件如下:volumes: etc_wireguard: services: wg-easy: volumes: etc_wireguard: services: wg-easy: environment: - INSECURE=true image: ghcr.nju.edu.cn/wg-easy/wg-easy:15 container_name: wg-easy networks: wg: ipv4_address: 10.42.42.42 ipv6_address: fdcc:ad94:bacf:61a3::2a volumes: - etc_wireguard:/etc/wireguard - /lib/modules:/lib/modules:ro ports: - "51820:51820/udp" - "51821:51821/tcp" restart: unless-stopped cap_add: - NET_ADMIN - SYS_MODULE sysctls: - net.ipv4.ip_forward=1 - net.ipv4.conf.all.src_valid_mark=1 - net.ipv6.conf.all.disable_ipv6=0 - net.ipv6.conf.all.forwarding=1 - net.ipv6.conf.default.forwarding=1 networks: wg: driver: bridge enable_ipv6: true ipam: driver: default config: - subnet: 10.42.42.0/24 - subnet: fdcc:ad94:bacf:61a3::/645️⃣ 启动服务# 启动容器 docker compose up -d # 查看日志 docker compose logs -f wg-easy # 查看容器状态 docker compose ps访问浏览器 http://服务器IP:51821 即可进入界面。⚙️ 初始配置🔐 创建管理员账号📱 创建客户端配置🔀 配置路由规则(重要)修改客户端配置,添加允许的 IP ,决定哪些流量走 VPN:# 全局代理(所有流量走 VPN) 0.0.0.0/0, ::/0 # 仅访问特定网段(分流模式,推荐) 10.42.42.0/24 # WireGuard 内网 10.7.0.0/22 # 服务器内网 172.17.0.0/24 # docker 192.168.1.0/24 # 家庭网络💡 分流模式的优势:✅ 仅内网流量走 VPN,外网直连✅ 节省 VPN 服务器带宽✅ 访问国内网站速度更快保存后即可通过扫描二维码或下载配置文件连接📊 启用 Prometheus 监控1️⃣ 在 WG-Easy 中启用进入 管理面板 > 通用设置 > Prometheus,启用监控并设置密码。 2️⃣ 配置 Prometheus在 Prometheus 配置文件中添加:以下是一个示例:scrape_configs: - job_name: 'wg-easy' scrape_interval: 30s metrics_path: /metrics/prometheus static_configs: - targets: - '服务器IP:51821' authorization: type: Bearer credentials: '上一步设置的密码'导入 Grafana 仪表盘Grafana Dashboard ID:21733🖥️ 项目界面预览📊 仪表盘💻 客户端连接Windows客户端 iPhone客户端 🎯 适用场景WG-Easy 适用于多种实际应用场景,从个人隐私保护到企业级远程访问,都能提供高效的解决方案:🧑💻 远程办公 / 内网访问安全访问公司内网服务(Git、Jenkins、数据库、K8s 等)。🌍 跨地域统一出口网络多终端统一出口 IP,便于访问特定区域网络资源。🏡 家庭网络远程访问安全访问家中 NAS、路由器、智能家居设备、监控摄像头、内网服务。👥 小型团队 VPN 管理无需专业网络运维即可维护团队 VPN。🧪 测试 / 沙箱 / 运维环境快速搭建临时 VPN,随用随删,配置可追溯。🔗 相关链接📖 官方文档官方网站:https://wg-easy.github.io/wg-easy/latest/GitHub 仓库:https://github.com/wg-easy/wg-easy快速开始:https://wg-easy.github.io/wg-easy/latest/getting-started/部署示例:https://wg-easy.github.io/wg-easy/latest/examples/tutorials/basic-installation/🔧 高级配置Caddy 反向代理:https://wg-easy.github.io/wg-easy/latest/examples/tutorials/caddy/Traefik 反向代理:https://wg-easy.github.io/wg-easy/latest/examples/tutorials/traefik/可选配置项:https://wg-easy.github.io/wg-easy/latest/advanced/config/optional-config/API 接口文档:https://wg-easy.github.io/wg-easy/latest/advanced/api/📱 客户端下载平台下载地址Windowshttps://download.wireguard.com/windows-client/🍎 macOShttps://apps.apple.com/app/wireguard/id1451685025🤖 Androidhttps://play.google.com/store/apps/details?id=com.wireguard.android📱 iOShttps://apps.apple.com/app/wireguard/id1441195209🐧 Linuxsudo apt install wireguard 或各发行版包管理器💬 社区支持问题反馈:https://github.com/wg-easy/wg-easy/issues讨论区:https://github.com/wg-easy/wg-easy/discussions贡献指南:https://wg-easy.github.io/wg-easy/latest/contributing/general/WireGuard vs IPsec vs OpenVPN 核心对比选择 WireGuard,如果你需要:✅ 极致性能:低延迟、高吞吐量的网络体验✅ 移动场景:频繁切换网络(4G/5G ↔ WiFi)✅ 简单部署:快速上手,无需复杂配置✅ 物联网/嵌入式:资源受限的设备🎯 适用场景:个人 VPN、移动办公、物联网、云原生环境选择 IPsec,如果你需要:✅ 企业合规:满足 FIPS、CC 等安全认证要求✅ 站点互联:分支机构与总部的网络互联✅ 原生集成:操作系统内置支持,无需额外客户端✅ 传统设备:需要与老旧设备兼容🎯 适用场景:企业站点互联、合规要求高的场景、金融行业选择 OpenVPN,如果你需要:✅ 最大兼容性:严格的防火墙环境(可伪装 HTTPS)✅ 灵活认证:用户名密码、双因素认证等✅ 成熟生态:丰富的第三方工具和管理系统✅ 细粒度控制:复杂的访问控制和策略路由🎯 适用场景:企业远程访问、严格防火墙环境、需要灵活认证的场景🎉 总结WG-Easy 以其实用性和易用性,将传统 WireGuard VPN 的部署门槛大幅降低,使得 VPN 架构不仅对开发者友好,同时对非专业用户亦极易上手。无论是个人搭建,还是企业内网 VPN 管理,WG-Easy 都能提供简洁、高效、安全的解决方案,是值得推荐的开源 VPN 工具。
2026年01月22日
3 阅读
0 评论
0 点赞
2025-11-20
境外IP天天扫你网站?3步彻底封杀,还不用编译Nginx!
你的服务器是否每天被 /admin、/wp-login.php、/.env 扫描刷屏?这些攻击 90% 来自境外。如果你的业务只服务中国大陆用户,那完全没必要开放全球访问!更重要的是:你不需要编译 Nginx,不需要 MaxMind 账号,甚至不用装额外模块只需利用 亚太网络信息中心(APNIC)公开的官方 IP 数据,配合 Nginx 原生功能,3步实现精准拦截!为什么推荐 APNIC 方案?APNIC 官方方案 ✅ 完全公开免费✅ 原生支持,不需要重新编译Nginx✅ 亚太官方机构发布(数据权威性)✅ 所有 Linux + 任意 Nginx 版本实战:3 步实现“仅限中国大陆访问”📌 本方案适用于:任何 Linux 系统 + 任何来源的 Nginx(官方源、宝塔、LNMP、手动编译等)第一步:获取中国大陆 IP 段(来自 APNIC 官方)APNIC 每天更新各国 IP 分配清单,地址永久免费开放:http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest# 下载到文件 wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest # 直接输出到终端 curl -sSL https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest创建自动转换脚本(保存为 /usr/local/bin/gen-cn-allow.sh):#!/bin/bash # 从 APNIC 官方数据生成 Nginx allow 规则 # 适用于任意 Linux 系统(CentOS/Ubuntu/Debian/Alma/Rocky 等) OUTPUT_DIR="/etc/nginx/conf.d" mkdir -p "$OUTPUT_DIR" echo "正在下载 APNIC 最新数据..." wget -qO- http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest | \ awk -F'|' ' $2 == "CN" && $3 == "ipv4" { prefix = $4; len = 32 - log($5) / log(2); print "allow " prefix "/" len ";"; } $2 == "CN" && $3 == "ipv6" { print "allow " $4 "/" $5 ";"; } ' > /tmp/cn_allow.list # 分离 IPv4 和 IPv6(避免混合导致 Nginx 报错) grep -E 'allow [0-9]+\.' /tmp/cn_allow.list > "$OUTPUT_DIR/china-ipv4.conf" grep -E 'allow [0-9a-fA-F:]+' /tmp/cn_allow.list > "$OUTPUT_DIR/china-ipv6.conf" # 添加注释头 sed -i "1i# Auto-generated from APNIC — $(date)" "$OUTPUT_DIR/china-ipv4.conf" sed -i "1i# Auto-generated from APNIC — $(date)" "$OUTPUT_DIR/china-ipv6.conf" rm -f /tmp/cn_allow.list echo "✅ 中国 IP 白名单已生成:" echo " IPv4: $OUTPUT_DIR/china-ipv4.conf" echo " IPv6: $OUTPUT_DIR/china-ipv6.conf"赋权并运行:chmod +x /usr/local/bin/gen-cn-allow.sh sudo /usr/local/bin/gen-cn-allow.sh🕒 建议每日自动更新(防止新 IP 段遗漏):echo "0 3 * * * root /usr/local/bin/gen-cn-allow.sh >/dev/null 2>&1" | sudo tee /etc/cron.d/update-cn-ip第二步:配置 Nginx 仅放行中国 IP编辑你的站点配置文件(如 /etc/nginx/conf.d/your-site.conf):server { listen 80; listen [::]:80; server_name your-domain.com; # 引入中国 IP 白名单(顺序很重要!) include /etc/nginx/conf.d/china-ipv4.conf; include /etc/nginx/conf.d/china-ipv6.conf; # 可选:放行本地回环(避免自己被拦) allow 127.0.0.1; allow ::1; # 拒绝所有未匹配的请求 deny all; location / { root /var/www/html; index index.html; # 你的其他配置... } }⚠️ 关键规则:Nginx 按顺序匹配 allow/deny,必须先写 allow,再写 deny all!第三步:重载生效 & 验证# 检查语法 nginx -t # 重载配置(平滑生效,不影响在线用户) nginx -s reload # 或 systemctl reload nginx验证方法: 国内手机 4G 访问 → 应正常打开;使用境外代理或 VPS 访问 → 应返回 403 Forbidden;查看日志:tail -f /var/log/nginx/access.log | grep '403'⚠️ 重要注意事项CDN 用户请特别注意!如果你使用了 Cloudflare、阿里云 CDN、腾讯云 CDN 等:用户真实 IP 被隐藏,Nginx 看到的是 CDN 节点 IP(多为境外);直接启用此规则会导致 所有用户被拦截!✅ 解决方案:在 CDN 后台开启 “回源携带真实IP”(如 Cloudflare 的 CF-Connecting-IP);或改用 CDN 自带的地域封禁功能(更简单可靠)。IPv6 支持按需启用若服务器未启用IPv6,可删除listen [::]:80;和china-ipv6.conf引用。性能影响极小中国大陆IP段约6000+条,Nginx 使用高效前缀匹配,实测无明显延迟。写在最后:屏蔽境外访问,不等于“技术复杂”。用官方数据 + Nginx 原生能力,就能构建一道高效、透明、低成本的“数字国境线”。你试过哪种防境外攻击的方法?有没有因为 CDN 导致误拦的经历?欢迎评论区分享!
2025年11月20日
32 阅读
0 评论
0 点赞
2025-11-15
还在手动封 IP?这 3 种 Nginx 动态封禁方案
还在靠 vim 手动加 deny 1.2.3.4 ;,然后 nginx -s reload ?不仅效率低,还容易误操作、漏封、重启抖动……别担心!本文为你带来三种真正 “动态”、无需复杂开发、生产可用的 Nginx 封 IP 方案,全部附带 完整配置 + 一行命令操作,让你的防护能力秒级生效,运维效率直接翻倍!方案一:OpenResty + Redis 毫秒级动态封禁实时生效|无需 reload|支持自动解封1. 安装 OpenResty + Redis# Ubuntu 示例 sudo apt install redis-server -y wget -O - https://openresty.org/package/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/openresty-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/openresty-archive-keyring.gpg] http://openresty.org/package/debian $(lsb_release -sc) openresty" | sudo tee /etc/apt/sources.list.d/openresty.list sudo apt update && sudo apt install -y openresty2. 配置 /etc/openresty/nginx.confworker_processes auto; events { worker_connections 1024; } http { server { listen 80; location / { access_by_lua_block { local redis = require "resty.redis" local red = redis:new() red:set_timeout(1000) local ok, err = red:connect("127.0.0.1", 6379) if not ok then return end local ip = ngx.var.remote_addr if red:get("blacklist:" .. ip) ~= ngx.null then ngx.exit(403) end red:close() } proxy_pass http://127.0.0.1:8080; } } }3. 动态封/解 IP(一行命令)# 封 1 小时 redis-cli SETEX blacklist:1.2.3.4 3600 "abuse" # 解封 redis-cli DEL blacklist:1.2.3.4方案二:fail2ban + Nginx 日志 —— 自动分析恶意行为自动封|防爆破|开箱即用1. 安装 fail2bansudo apt install fail2ban -y2. 创建过滤器 /etc/fail2ban/filter.d/nginx-bad.conf[Definition] failregex = ^<HOST>.*"(GET|POST).*" (400|403|444|404) .* ignoreregex =3. 配置 jail /etc/fail2ban/jail.local[nginx-bad] enabled = true port = http,https filter = nginx-bad logpath = /var/log/nginx/access.log maxretry = 5 findtime = 600 bantime = 3600 action = iptables-multiport[name=nginx, port="80,443"]4. 启动sudo systemctl restart fail2ban注:默认用 iptables 封 IP。如坚持只用 Nginx ,请看方案三。方案三:纯 Shell + 文件驱动 —— 最简原生 Nginx 封禁零依赖|只用 Nginx|运维只需写文件核心思想: 维护一个纯文本黑名单文件:/etc/nginx/blacklist.txt(每行一个 IP)用一个 Shell 脚本自动转成 deny 配置并 reload通过 inotifywait 监听文件变化,改完即生效第一步:安装 inotify-tools(监听文件变动)sudo apt install inotify-tools -y第二步:创建黑名单目录和初始文件sudo mkdir -p /etc/nginx/dynamic echo "# 黑名单IP,每行一个,如:1.2.3.4" | sudo tee /etc/nginx/blacklist.txt sudo touch /etc/nginx/dynamic/blacklist.conf第三步:编写转换脚本 /usr/local/bin/gen_nginx_blacklist.sh#!/bin/bash INPUT="/etc/nginx/blacklist.txt" OUTPUT="/etc/nginx/dynamic/blacklist.conf" # 清空输出文件 echo "# Auto-generated from blacklist.txt. DO NOT EDIT." > "$OUTPUT" # 读取 blacklist.txt,跳过注释和空行,生成 deny 规则 while IFS= read -r line; do line=$(echo "$line" | xargs) # 去除前后空格 if [[ -n "$line" && "$line" != \#* ]]; then echo "deny $line;" >> "$OUTPUT" fi done < "$INPUT" #测试配置 & 重载 nginx -t && systemctl reload nginx赋予执行权限:sudo chmod +x /usr/local/bin/gen_nginx_blacklist.sh第四步:在 Nginx 配置中引入黑名单server { listen 80; include /etc/nginx/dynamic/blacklist.conf; # ← 关键! location / { proxy_pass http://127.0.0.1:8080; } }第五步:启动监听服务(后台运行)# 创建 systemd 服务(推荐)或直接运行: nohup inotifywait -m -e modify,move,create,delete /etc/nginx/blacklist.txt \ --format '%f' | while read file; do echo "[$(date)] blacklist.txt changed, regenerating..." /usr/local/bin/gen_nginx_blacklist.sh done &更优雅做法:写成 systemd 服务使用方式 运维只需编辑 /etc/nginx/blacklist.txt# 示例内容 1.2.3.4 5.6.7.8 192.168.100.50保存文件后,3 秒内自动封禁!无需任何命令!优点: 只需一个文本文件 + 一个 Shell 脚本完全兼容原生 Nginx三大方案怎么选?场景推荐方案高并发、API 网关、需要毫秒响应✅ 方案一(OpenResty + Redis)防暴力破解、WordPress、中小站点✅ 方案二(fail2ban)不想装新软件、只要原生 Nginx、运维习惯改文件✅✅✅ 方案三(Shell + 文件监听)写在最后:封 IP 不该是体力活!无论你是技术大牛还是初级运维,总有一款方案让你 告别手动 reload ,把时间留给更有价值的事。
2025年11月15日
12 阅读
0 评论
0 点赞
2025-11-01
从 0 搭建 Nginx 安全网关:堵住 90% 的 Web 漏洞!
你的网站是否曾被扫描出以下高危问题?🔸 Host 头注入:攻击者伪造 Host 头,窃取密码重置链接🔸 敏感文件泄露:.git、.env、backup.zip 被直接下载🔸 目录遍历:访问 /static/../../../etc/passwd🔸 Nginx 版本号暴露:让黑客精准利用已知漏洞别再依赖“防火墙万能”了!Nginx本身就是一个强大的安全网关 ,只需几行配置,就能实现企业级防护。✅ 无需额外软件✅ 零成本加固✅ 符合等保 2.0 要求今天,手把手教你从 0 搭建一个安全、干净、合规的 Nginx 网关!🛡️ 第一步:隐藏身份 —— 隐藏 Nginx 版本号攻击者第一步就是探测你的服务版本。暴露版本 = 送漏洞地图!🔧 配置方法在 nginx.conf 的 http 块中添加:server_tokens off;✅ 效果: 原响应头:Server: nginx/1.24.0 优化后:Server: nginx📌 额外建议如果使用了 error_page 自定义错误页,确保页面中也不包含版本信息!🚫 第二步:封堵入口 —— 禁止敏感文件与目录访问很多数据泄露,都是因为一个 .env 或 .git 文件被公开下载!通用防护配置(推荐放在 http 或 server 块)# 禁止访问隐藏文件(以 . 开头) location ~ /\. { deny all; return 404; } # 禁止访问特定敏感文件 location ~* \.(env|git|svn|htaccess|htpasswd|bak|log|sql|zip|tar\.gz)$ { deny all; return 403; } # 禁止访问备份文件(如 config.php.bak) location ~* \.bak$ { deny all; return 403; } # 禁止目录遍历(Nginx 默认已防,但显式加固更安全) location ~ \.\./ { deny all; return 403; }原理说明: ~ 表示正则匹配 ~* 表示不区分大小写 deny all 直接拒绝访问,不返回文件内容🌐 第三步:锁定身份 —— 防 Host 头攻击(关键!)什么是 Host 头攻击?当 Nginx 配置了宽松的 server_name(如 server_name _; 或未设置默认拒绝 server)时,攻击者可构造恶意 Host 头:GET /password-reset HTTP/1.1 Host: attacker.com如果后端代码使用 Host 头生成重置链接(如 https://attacker.com/reset?token=xxx),攻击者就能窃取用户凭证!安全配置方案1. 设置默认拒绝的 server 块在所有 server 块之前,添加一个“兜底”配置:server { listen 80 default_server; listen 443 ssl default_server; server_name _ ""; return 403; } 此配置会拒绝所有未明确匹配的域名请求。2. 明确指定合法域名在你的业务 server 块中,只允许真实域名:server { listen 80; server_name www.yourdomain.com yourdomain.com; # 你的业务配置... }3. (可选)在应用层二次校验即使 Nginx 层做了防护,后端也应校验 Host 是否在白名单内,形成纵深防御。🛠️ 第四步:添加安全响应头(提升浏览器防护)现代浏览器支持多种安全策略,通过响应头启用:add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:" always;说明: X-Frame-Options: DENY:防点击劫持 X-Content-Type-Options: nosniff:防 MIME 嗅探 always:确保错误页面也携带这些头🧪 验证是否生效1. 检查版本是否隐藏curl -I http://your-domain.com→ 确保 Server 字段不含版本号。2. 测试敏感文件访问curl -I http://your-domain.com/.env→ 应返回 403 或 404,不能返回 200。3. 测试 Host 头攻击curl -H "Host: evil.com" http://your-server-ip/→ 应返回 403,而非业务页面。📋 完整安全配置模板(推荐收藏)# /etc/nginx/nginx.conf 或站点配置 # 隐藏版本 server_tokens off; # 默认拒绝 server(放在最前面!) server { listen 80 default_server; listen 443 ssl default_server; server_name _ ""; return 403; } # 业务 server server { listen 80; server_name yourdomain.com www.yourdomain.com; # 安全响应头 add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "DENY" always; add_header X-XSS-Protection "1; mode=block" always; # 敏感文件防护(可放 http 块全局生效) location ~ /\. { deny all; return 404; } location ~* \.(env|git|bak|log|sql|zip)$ { deny all; return 403; } # 你的业务 location... location / { proxy_pass http://backend; } }🌟 总结:安全网关 4 大核心原则原则配置要点最小暴露隐藏版本、关闭无用模块最小权限只允许合法域名、拒绝未知 Host纵深防御Nginx + 应用层双重校验主动防护添加安全头、阻断敏感路径一个配置完善的 Nginx,胜过十台 WAF!
2025年11月01日
34 阅读
0 评论
0 点赞
2025-09-28
用lucky解决飞牛、群晖等各种nas、家里云安全远程访问教程!
用 nas 一定会有远程访问的需求,这个需求有数不清的解决方法,我们今天从 “看看,摸摸,玩玩” 这三个层次来聊聊远程访问这件事,最终要为大家呈现的是用 Lucky 这个神器。很多时候,我们的在外面打开 nas 的需求就是 “看看” ,并不是针对性的要做什么, 这时候 nas 官方中继就够用;想 “摸摸” 就得用 异地组网 或者 IPv6+DDNS 这些;最终要“玩玩”时候,就得顾及安全,速度,便捷等,目前能兼顾这些需求,只能是 lucky ,别无二选。一、准备工作:1、域名:最省心的还是推荐 spaceship 去找6数字以上的xyz域名,先买1年4.77元,再续9年42.96元,总共不超过50元。为了验证,我刚才又购买了一个,确定价格没变,记住买了立马去修改DNS为Cloudflare的两条DNS记录,减少后面的等待时间。2、IPv6网络:各家情况有不同,我这是移动宽带,本来就有IPv6,我把NAS网线直接插光猫上(老光猫有路由和Wi-Fi功能)就能用IPv6网络了。很多人推荐桥接,你搞不定直接找运营商客服找人帮你弄。3、服务商:推荐使用赛博菩萨Cloudflare+国内ip优选。提前在Cloudflare添加域名,并修改域名的DNS,然后从左上角头像那里点击后进入“配置文件”,点左侧“API令牌”,以此“创建令牌”,点击第一行“编辑区域DNS”后面的使用模版,区域资源这里选择生效的域名,然后点“继续以提示摘要”,最后完成创建令牌。把这个Token复制保存,一会要用两次。二、飞牛nas安装lucky和升级飞牛nas的应用商店搜索 “lucky” 就有,直接安装即可。自己刷的armbian用casaos或者1panel应用商店也有,哪怕你装的黑群晖的机器,添加了矿神套件后,也有lucky,并且都是一键安装,这没难度。不过飞牛nas应用商店的 lucky 版本是 v2.18.2,进入应用界面并登录后会有提示Github版本是 v2.18.6,而官网官网版本是 v2.19.4。你可以按指引从官网下载文件,并上传,如果你从应用商店安装,不建议这种方式操作升级,你应用商店的lucky会变成已安装,未启用,点击会提示端口被占用,因为真正的lucky已经在正常运行,并且飞牛系统升级时候会清除这个手动升级的版本。三、Lucky的设置1、lucky安全设置进入lucky应用后,有两个安全设置,我会优先设置。第一是安全入口,原本是IP:端口的访问格式,我们自定义一个/nicai,以后访问就是IP:端口/nicai这个格式,少了安全入口只会看到“Are you ok?”的亲切问候,如果有接触过bt面板,1panel面板等网站服务器管理面板,对安全入口肯定很熟,一定程度上能提高安全性。第二个是账号和强密码,不过lucky要强密码,所有nas上你安装的第三方应用,Docker容器牵扯到访问密码的都建议强密码,能减少很多麻烦。2、lucky设置DDNS前面都是铺垫,但是对安全性很重要。这里才进入 lucky 设置的正题,按顺序进行,更容易理解它的运作机制。先到动态域名里添加 “添加任务” ,任务名称随意,托管服务商我用Cloudflare我就选它,然后在Token那里填写Cloudflare复制来的Token。再点亮IPv6这一行,其他不动,提交任务即可。多说一句, Token 的作用和你账号密码一样,你账号密码能进行所有操作,Token进去能进行特定操作,刚使用的这个Token就只是能编辑这个域名的解析记录。然后再去添加记录,就是我们指定哪些域名通过对IPv6的解析能访问到这个nas。注意,此时只是能访问nas,还没有去具体划分某个域名能访问哪个应用。这是第三步才要做的事情。现在演示,我只添加两个,我要让fn这个二级域名访问主页,想要so这个二级域名访问pansou这个Docker这个应用。如果不放心,去Cloudflare那看看,正常情况下已经自动添加的两条解析记录。3、lucky设置SSL第二步我选择先设置好SSL,因为lucky的SSL可以一键申请,自动续签,并且支持泛域名证书,所以备受推崇。在 SSL/TLS 这里点击添加证书,选择 ACME ,再选择 “Let's Encrypt” 验证方式选择 “Cloudflare” ,填写一开始我们获取的 Token (其他域名商同理)。域名列表这里填写 “*.ami.gg” 这样的格式,好处是 A.ami 和 B.ami 等所有二级域名都能用到这个证书。其他都不用填,直接提交就行。有时候2分钟就申请成功了,有时候得快10分钟,甚至有报错,那就再试一次。4、lucky设置Web规则第三步要设置的叫“反向代理”,通俗地说,“反向代理”相当于一个集团公司的总部前台。你是访客,你无法直接去拜访某一个部门负责人,你得找前台,前台内部联系这个负责人出来和你对接。“反向代理”是隐藏了真正的受访者,“正向代理”是隐藏了真正的访问者,你这会要是趴在梯子上吃外面的瓜,你用的就是“正向代理”。现在我们给这个“前台”创建规则,告诉她从这个门口(端口)进来的人,我们才接待。不是这个端口来的不归我们管。要把TLS打开,前面我们申请的SSL证书就自动起效了。都不用去操心怎么部署,这个便捷程度别家可没有。如果 so 进来了,我们把 8282 这个端口的 Docker 服务交给它,如果 fn 进来了,我们把https的 5667 入口给它。127和192的地址在这里都管用。同理,你可以为所有你的第三方应用和Docker创建这些子规则。每一个服务都能独立访问,还是自定义的地址,并且你只要把前台这个门口(端口)把好关就行。这样安全性就提高非常多了。四、测试成果访问带 8998 端口的 fn 二级域名和 so 的二级域名,可以正常访问,浏览器没有“不安全”的提示,证书信息一切正常。但是注意,我是在演示的机器,所以把端口,二级域名都展示给大家,演示完毕,这个机器就关机了所以没关系。你自己使用的nas,一定要把这个端口绝对保密,API令牌的Token绝对保密,安全入口绝对保密,二级域名保密,你也可以使用三级域名,其实用到nas的域名本身也建议你保密,不让其他人知道最好。教程到此结束,其实我们只用到 lucky 的三个主要功能,还有五六个功能我们当前不设计涉及,所以没碰它。而如果你正在用飞牛nas本身的 DDNS ,或者 DDNS-GO 这个应用,它只是实现了三个功能里的第一个动态域名的解析。最后你要是勤快点,可以凑合从飞牛nas的证书那里上传,每三个月去手动上传一次,每次上传你都得去找个地方申请,再下载,然后区分三个文件该传哪一行,这就有点劳心费神了。哪怕你用群晖,它都能让你一键搞定https访问。用lucky,就有点一劳永逸的韵味了。如果你只用DDNS,忽略SSL和端口隐患,就好似你回家推开了大门,进去歇着了,你可知道有多少人跟着你也发现了这个敞开的门,以后发生的事,就是你的故事了。
2025年09月28日
82 阅读
0 评论
0 点赞
2025-08-13
搭建私有 Linux 镜像仓库:从零到生产的完整指南(ubuntu,centos,docker)
概述为什么需要私有镜像仓库?在企业环境中,搭建私有Linux镜像仓库具有以下优势:网络优化:减少外网带宽消耗,提升下载速度安全控制:内网环境下的安全软件分发版本管理:统一管理软件包版本,确保环境一致性离线部署:支持无外网环境的软件安装成本节约:减少重复下载,节省带宽成本架构设计环境准备硬件要求组件最低配置推荐配置生产环境CPU2核4核8核+内存4GB8GB16GB+存储500GB2TB10TB+网络100Mbps1Gbps10Gbps软件环境# 操作系统:Ubuntu 22.04 LTS 或 CentOS 8 # Web服务器:Nginx # 同步工具:rsync, apt-mirror, reposync # 监控:Prometheus + Grafana目录规划# 创建目录结构 sudomkdir -p /data/mirrors/{ubuntu,centos,docker,alpine} sudomkdir -p /data/mirrors/logs sudomkdir -p /data/mirrors/scripts sudomkdir -p /etc/mirrors搭建APT私有镜像源安装apt-mirror# Ubuntu/Debian系统 sudo apt update sudo apt install -y apt-mirror nginx # 创建镜像用户 sudo useradd -r -s /bin/false -d /data/mirrors aptmirror sudochown -R aptmirror:aptmirror /data/mirrors配置apt-mirror# 编辑配置文件 sudo nano /etc/apt/mirror.list# /etc/apt/mirror.list ############# config ################## set base_path /data/mirrors/ubuntu set mirror_path $base_path/mirror set skel_path $base_path/skel set var_path $base_path/var set cleanscript $var_path/clean.sh set defaultarch amd64 set postmirror_script $var_path/postmirror.sh set run_postmirror 0 set nthreads 20 set _tilde 0 ############# end config ############## # Ubuntu 22.04 LTS (Jammy) deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu jammy-updates main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu jammy-backports main restricted universe multiverse deb http://security.ubuntu.com/ubuntu jammy-security main restricted universe multiverse # Ubuntu 20.04 LTS (Focal) deb http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu focal-backports main restricted universe multiverse deb http://security.ubuntu.com/ubuntu focal-security main restricted universe multiverse # 源码包(可选) # deb-src http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse # 清理脚本 clean http://archive.ubuntu.com/ubuntu clean http://security.ubuntu.com/ubuntu创建同步脚本# 创建同步脚本 sudo nano /data/mirrors/scripts/sync-ubuntu.sh#!/bin/bash # Ubuntu镜像同步脚本 set -e LOGFILE="/data/mirrors/logs/ubuntu-sync-$(date +%Y%m%d-%H%M%S).log" LOCKFILE="/var/run/ubuntu-mirror.lock" # 检查锁文件 if [ -f "$LOCKFILE" ]; then echo"同步进程已在运行,退出..." exit 1 fi # 创建锁文件 echo $$ > "$LOCKFILE" # 清理函数 cleanup() { rm -f "$LOCKFILE" } trap cleanup EXIT echo"开始Ubuntu镜像同步: $(date)" | tee -a "$LOGFILE" # 执行同步 sudo -u aptmirror apt-mirror /etc/apt/mirror.list 2>&1 | tee -a "$LOGFILE" # 更新时间戳 echo"$(date)" > /data/mirrors/ubuntu/last_update echo"Ubuntu镜像同步完成: $(date)" | tee -a "$LOGFILE" # 清理旧日志(保留30天) find /data/mirrors/logs -name "ubuntu-sync-*.log" -mtime +30 -delete # 发送通知(可选) # curl -X POST -H 'Content-type: application/json' \ # --data '{"text":"Ubuntu镜像同步完成"}' \ # YOUR_WEBHOOK_URL# 设置执行权限 sudochmod +x /data/mirrors/scripts/sync-ubuntu.sh配置Nginx# 创建Nginx配置 sudo nano /etc/nginx/sites-available/ubuntu-mirrorserver { listen80; server_name ubuntu-mirror.example.com; root /data/mirrors/ubuntu/mirror; index index.html; # 访问日志 access_log /var/log/nginx/ubuntu-mirror.access.log; error_log /var/log/nginx/ubuntu-mirror.error.log; # 基本配置 location / { autoindexon; autoindex_exact_sizeoff; autoindex_localtimeon; # 缓存配置 expires1d; add_header Cache-Control "public, immutable"; # 安全头 add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; } # 包文件缓存 location~* \.(deb|udeb|tar\.gz|tar\.xz|tar\.bz2)$ { expires7d; add_header Cache-Control "public, immutable"; } # 元数据文件 location~* (Release|Packages|Sources)$ { expires1h; add_header Cache-Control "public, must-revalidate"; } # 状态页面 location /status { alias /data/mirrors/ubuntu/; try_files /last_update =404; add_header Content-Type text/plain; } # 禁止访问隐藏文件 location~ /\. { deny all; } }# 启用站点 sudoln -s /etc/nginx/sites-available/ubuntu-mirror /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx搭建YUM私有镜像源安装reposync# CentOS/RHEL系统 sudo yum install -y yum-utils createrepo nginx # 或者在Ubuntu上安装 sudo apt install -y yum-utils createrepo-c nginx配置YUM仓库同步# 创建CentOS 8同步脚本 sudo nano /data/mirrors/scripts/sync-centos.sh#!/bin/bash # CentOS镜像同步脚本 set -e MIRROR_BASE="/data/mirrors/centos" LOGFILE="/data/mirrors/logs/centos-sync-$(date +%Y%m%d-%H%M%S).log" LOCKFILE="/var/run/centos-mirror.lock" # 检查锁文件 if [ -f "$LOCKFILE" ]; then echo"同步进程已在运行,退出..." exit 1 fi echo $$ > "$LOCKFILE" cleanup() { rm -f "$LOCKFILE" } trap cleanup EXIT echo"开始CentOS镜像同步: $(date)" | tee -a "$LOGFILE" # 同步CentOS 8 Stream sync_centos_stream() { local version=$1 local repo_dir="$MIRROR_BASE/$version" mkdir -p "$repo_dir" # 同步各个仓库 for repo in baseos appstream extras powertools; do echo"同步 CentOS $version$repo..." | tee -a "$LOGFILE" reposync \ --download-path="$repo_dir" \ --repo="$repo" \ --arch=x86_64 \ --newest-only \ --delete \ 2>&1 | tee -a "$LOGFILE" # 创建仓库元数据 createrepo_c "$repo_dir/$repo/" 2>&1 | tee -a "$LOGFILE" done } # 同步不同版本 sync_centos_stream "8-stream" sync_centos_stream "9-stream" # 更新时间戳 echo"$(date)" > "$MIRROR_BASE/last_update" echo"CentOS镜像同步完成: $(date)" | tee -a "$LOGFILE" # 清理旧日志 find /data/mirrors/logs -name "centos-sync-*.log" -mtime +30 -delete配置YUM仓库文件# 创建仓库配置模板 sudo nano /data/mirrors/centos/centos8-stream.repo[baseos] name=CentOS Stream $releasever - BaseOS baseurl=http://your-mirror.example.com/centos/8-stream/baseos/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial [appstream] name=CentOS Stream $releasever - AppStream baseurl=http://your-mirror.example.com/centos/8-stream/appstream/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial [extras] name=CentOS Stream $releasever - Extras baseurl=http://your-mirror.example.com/centos/8-stream/extras/ gpgcheck=1 enabled=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial [powertools] name=CentOS Stream $releasever - PowerTools baseurl=http://your-mirror.example.com/centos/8-stream/powertools/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialNginx配置(CentOS)server { listen80; server_name centos-mirror.example.com; root /data/mirrors/centos; index index.html; access_log /var/log/nginx/centos-mirror.access.log; error_log /var/log/nginx/centos-mirror.error.log; location / { autoindexon; autoindex_exact_sizeoff; autoindex_localtimeon; expires1d; add_header Cache-Control "public, immutable"; } # RPM包缓存 location~* \.rpm$ { expires7d; add_header Cache-Control "public, immutable"; } # 元数据缓存 location~* (repomd\.xml|primary\.xml|filelists\.xml|other\.xml)$ { expires1h; add_header Cache-Control "public, must-revalidate"; } # 仓库配置文件下载 location /repo-files/ { alias /data/mirrors/centos/; try_files$uri$uri.repo =404; add_header Content-Type text/plain; } }搭建Docker私有镜像仓库安装Docker Registry# 安装Docker curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # 创建Registry目录 sudomkdir -p /data/mirrors/docker/{registry,auth,certs}配置Registry# 创建Registry配置文件 sudo nano /data/mirrors/docker/config.ymlversion:0.1 log: accesslog: disabled:false level:info formatter:text fields: service:registry storage: cache: blobdescriptor:inmemory filesystem: rootdirectory:/var/lib/registry delete: enabled:true http: addr::5000 headers: X-Content-Type-Options: [nosniff] Access-Control-Allow-Origin: ['*'] Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE'] Access-Control-Allow-Headers: ['Authorization', 'Accept', 'Cache-Control'] health: storagedriver: enabled:true interval:10s threshold:3 proxy: remoteurl:https://registry-1.docker.io username:your-dockerhub-username password:your-dockerhub-password启动Registry服务# 创建docker-compose文件 sudo nano /data/mirrors/docker/docker-compose.ymlversion:'3.8' services: registry: image:registry:2.8 container_name:docker-registry restart:unless-stopped ports: -"5000:5000" environment: REGISTRY_CONFIG_PATH:/etc/docker/registry/config.yml REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY:/var/lib/registry volumes: -/data/mirrors/docker/registry:/var/lib/registry -/data/mirrors/docker/config.yml:/etc/docker/registry/config.yml:ro networks: -registry-net registry-ui: image:joxit/docker-registry-ui:latest container_name:registry-ui restart:unless-stopped ports: -"8080:80" environment: REGISTRY_TITLE:"Private Docker Registry" REGISTRY_URL:http://registry:5000 DELETE_IMAGES:"true" SHOW_CONTENT_DIGEST:"true" depends_on: -registry networks: -registry-net networks: registry-net: driver:bridge# 启动服务 cd /data/mirrors/docker sudo docker-compose up -d配置Registry代理# Docker Registry Nginx配置 server { listen80; server_name docker-registry.example.com; client_max_body_size0; chunked_transfer_encodingon; location /v2/ { proxy_pass http://localhost:5000; proxy_set_header Host $http_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_read_timeout900; } location / { proxy_pass http://localhost:8080; proxy_set_header Host $http_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; } }自动化同步与更新创建统一同步脚本# 创建主同步脚本 sudo nano /data/mirrors/scripts/sync-all.sh#!/bin/bash # 统一镜像同步脚本 set -e SCRIPT_DIR="/data/mirrors/scripts" LOG_DIR="/data/mirrors/logs" NOTIFICATION_URL="${WEBHOOK_URL:-}" # 日志函数 log() { echo"[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_DIR/sync-all.log" } # 通知函数 notify() { local message="$1" local status="$2" log"$message" if [ -n "$NOTIFICATION_URL" ]; then curl -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"$message\", \"status\":\"$status\"}" \ "$NOTIFICATION_URL" || true fi } # 执行同步任务 run_sync() { local script="$1" local name="$2" if [ -f "$script" ]; then log"开始同步 $name" if"$script"; then notify "$name 同步成功""success" else notify "$name 同步失败""error" return 1 fi else log"同步脚本不存在: $script" return 1 fi } # 主执行流程 main() { log"开始镜像同步任务" local failed=0 # 同步Ubuntu run_sync "$SCRIPT_DIR/sync-ubuntu.sh""Ubuntu" || ((failed++)) # 同步CentOS run_sync "$SCRIPT_DIR/sync-centos.sh""CentOS" || ((failed++)) # 清理旧日志 find "$LOG_DIR" -name "*.log" -mtime +30 -delete if [ $failed -eq 0 ]; then notify "所有镜像同步完成""success" else notify "有 $failed 个镜像同步失败""warning" fi log"镜像同步任务结束" } main "$@"配置定时任务# 编辑crontab sudo crontab -e # 添加定时任务 # 每天凌晨2点同步 0 2 * * * /data/mirrors/scripts/sync-all.sh # 每周日凌晨1点清理Docker Registry 0 1 * * 0 /data/mirrors/scripts/cleanup-docker.sh # 每小时检查服务状态 0 * * * * /data/mirrors/scripts/health-check.sh健康检查脚本# 创建健康检查脚本 sudo nano /data/mirrors/scripts/health-check.sh#!/bin/bash # 服务健康检查脚本 SERVICES=("nginx""docker") LOG_FILE="/data/mirrors/logs/health-check.log" log() { echo"[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" } check_service() { local service="$1" if systemctl is-active --quiet "$service"; then log"$service 服务正常运行" return 0 else log"$service 服务异常,尝试重启" systemctl restart "$service" sleep 5 if systemctl is-active --quiet "$service"; then log"$service 服务重启成功" return 0 else log"$service 服务重启失败" return 1 fi fi } check_disk_space() { local usage=$(df /data/mirrors | awk 'NR==2 {print $5}' | sed 's/%//') if [ "$usage" -gt 85 ]; then log"磁盘空间不足: ${usage}%" # 发送告警 return 1 else log"磁盘空间正常: ${usage}%" return 0 fi } # 主检查流程 main() { local failed=0 # 检查服务状态 for service in"${SERVICES[@]}"; do check_service "$service" || ((failed++)) done # 检查磁盘空间 check_disk_space || ((failed++)) # 检查网络连通性 if ! curl -s --max-time 10 http://localhost/status > /dev/null; then log"Web服务访问异常" ((failed++)) fi if [ $failed -eq 0 ]; then log"所有检查项正常" else log"发现 $failed 个异常项" fi } main "$@"高可用与负载均衡配置HAProxy负载均衡# 安装HAProxy sudo apt install -y haproxy # 配置HAProxy sudo nano /etc/haproxy/haproxy.cfgglobal daemon chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms option httplog option dontlognull errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend mirror_frontend bind *:80 bind *:443 ssl crt /etc/ssl/certs/mirror.pem redirect scheme https if !{ ssl_fc } # 根据域名分发 acl is_ubuntu hdr(host) -i ubuntu-mirror.example.com acl is_centos hdr(host) -i centos-mirror.example.com acl is_docker hdr(host) -i docker-registry.example.com use_backend ubuntu_backend if is_ubuntu use_backend centos_backend if is_centos use_backend docker_backend if is_docker default_backend ubuntu_backend backend ubuntu_backend balance roundrobin option httpchk GET /status server ubuntu1 192.168.1.10:80 check server ubuntu2 192.168.1.11:80 check backup backend centos_backend balance roundrobin option httpchk GET /status server centos1 192.168.1.10:80 check server centos2 192.168.1.11:80 check backup backend docker_backend balance roundrobin option httpchk GET /v2/ server docker1 192.168.1.10:5000 check server docker2 192.168.1.11:5000 check backup listen stats bind *:8404 stats enable stats uri /stats stats refresh 30s stats admin if TRUE配置Keepalived高可用# 安装Keepalived sudo apt install -y keepalived # 主节点配置 sudo nano /etc/keepalived/keepalived.conf# 主节点配置 vrrp_script chk_haproxy { script "/bin/kill -0 `cat /var/run/haproxy.pid`" interval 2 weight 2 fall 3 rise 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 101 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.100 } track_script { chk_haproxy } }监控与维护配置Prometheus监控# 创建Prometheus配置 sudo nano /etc/prometheus/prometheus.ymlglobal: scrape_interval:15s evaluation_interval:15s rule_files: -"mirror_rules.yml" scrape_configs: -job_name:'prometheus' static_configs: -targets: ['localhost:9090'] -job_name:'node-exporter' static_configs: -targets: ['localhost:9100'] -job_name:'nginx' static_configs: -targets: ['localhost:9113'] -job_name:'haproxy' static_configs: -targets: ['localhost:8404'] alerting: alertmanagers: -static_configs: -targets: -alertmanager:9093创建告警规则# 创建告警规则 sudo nano /etc/prometheus/mirror_rules.ymlgroups: -name:mirror_alerts rules: -alert:HighDiskUsage expr:(node_filesystem_size_bytes{mountpoint="/data"}-node_filesystem_free_bytes{mountpoint="/data"})/node_filesystem_size_bytes{mountpoint="/data"}*100>85 for:5m labels: severity:warning annotations: summary:"磁盘使用率过高" description:"镜像存储磁盘使用率超过85%" -alert:ServiceDown expr:up==0 for:2m labels: severity:critical annotations: summary:"服务不可用" description:"{{ $labels.instance }} 服务已停止" -alert:HighMemoryUsage expr:(1-(node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes))*100>90 for:5m labels: severity:warning annotations: summary:"内存使用率过高" description:"内存使用率超过90%" -alert:SyncJobFailed expr:increase(sync_job_failures_total[1h])>0 for:0m labels: severity:critical annotations: summary:"镜像同步失败" description:"镜像同步任务执行失败"Grafana仪表板{ "dashboard":{ "id":null, "title":"Linux Mirror Repository Dashboard", "tags":["mirror","linux"], "timezone":"browser", "panels":[ { "title":"磁盘使用率", "type":"stat", "targets":[ { "expr":"(node_filesystem_size_bytes{mountpoint=\"/data\"} - node_filesystem_free_bytes{mountpoint=\"/data\"}) / node_filesystem_size_bytes{mountpoint=\"/data\"} * 100", "legendFormat":"磁盘使用率" } ], "fieldConfig":{ "defaults":{ "unit":"percent", "thresholds":{ "steps":[ {"color":"green","value":null}, {"color":"yellow","value":70}, {"color":"red","value":85} ] } } } }, { "title":"网络流量", "type":"graph", "targets":[ { "expr":"rate(node_network_receive_bytes_total{device=\"eth0\"}[5m])", "legendFormat":"接收" }, { "expr":"rate(node_network_transmit_bytes_total{device=\"eth0\"}[5m])", "legendFormat":"发送" } ] }, { "title":"同步状态", "type":"table", "targets":[ { "expr":"sync_last_success_timestamp_seconds", "legendFormat":"最后同步时间" } ] } ], "time":{ "from":"now-1h", "to":"now" }, "refresh":"30s" } }安全配置SSL/TLS配置# 生成SSL证书 sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/ssl/private/mirror.key \ -out /etc/ssl/certs/mirror.crt \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/CN=mirror.example.com" # 合并证书文件(HAProxy使用) sudocat /etc/ssl/certs/mirror.crt /etc/ssl/private/mirror.key > /etc/ssl/certs/mirror.pem访问控制# IP白名单配置 geo$allowed_ip { default0; 192.168.0.0/16 1; 10.0.0.0/8 1; 172.16.0.0/12 1; } server { listen80; server_name mirror.example.com; # IP访问控制 if ($allowed_ip = 0) { return403; } # 限制连接数 limit_conn_zone$binary_remote_addr zone=conn_limit_per_ip:10m; limit_conn conn_limit_per_ip 10; # 限制请求频率 limit_req_zone$binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s; limit_req zone=req_limit_per_ip burst=20 nodelay; location / { # 基本认证(可选) auth_basic"Private Mirror"; auth_basic_user_file /etc/nginx/.htpasswd; # 其他配置... } }防火墙配置# UFW防火墙配置 sudo ufw default deny incoming sudo ufw default allow outgoing # 允许SSH sudo ufw allow ssh # 允许HTTP/HTTPS sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 允许内网访问 sudo ufw allow from 192.168.0.0/16 to any port 80 sudo ufw allow from 10.0.0.0/8 to any port 80 # 启用防火墙 sudo ufw enable故障排除常见问题诊断1. 同步失败问题# 检查网络连通性 curl -I http://archive.ubuntu.com/ubuntu/ # 检查磁盘空间 df -h /data/mirrors # 检查权限 ls -la /data/mirrors/ # 查看同步日志 tail -f /data/mirrors/logs/ubuntu-sync-*.log2. 服务访问问题# 检查Nginx状态 sudo systemctl status nginx sudo nginx -t # 检查端口监听 sudo netstat -tlnp | grep :80 # 检查防火墙 sudo ufw status # 测试本地访问 curl -I http://localhost/3. 性能问题# 检查系统负载 top htop iotop # 检查网络流量 iftop nethogs # 检查磁盘IO iostat -x 1故障恢复脚本# 创建故障恢复脚本 sudo nano /data/mirrors/scripts/recovery.sh#!/bin/bash # 故障恢复脚本 SERVICES=("nginx""docker""haproxy") BACKUP_DIR="/data/backup" # 服务恢复 recover_services() { for service in"${SERVICES[@]}"; do if ! systemctl is-active --quiet "$service"; then echo"恢复服务: $service" systemctl restart "$service" sleep 5 if systemctl is-active --quiet "$service"; then echo"$service 恢复成功" else echo"$service 恢复失败" fi fi done } # 配置文件恢复 recover_configs() { if [ -d "$BACKUP_DIR" ]; then echo"恢复配置文件..." # 恢复Nginx配置 if [ -f "$BACKUP_DIR/nginx.conf" ]; then cp"$BACKUP_DIR/nginx.conf" /etc/nginx/nginx.conf nginx -t && systemctl reload nginx fi # 恢复HAProxy配置 if [ -f "$BACKUP_DIR/haproxy.cfg" ]; then cp"$BACKUP_DIR/haproxy.cfg" /etc/haproxy/haproxy.cfg systemctl reload haproxy fi fi } # 数据完整性检查 check_data_integrity() { echo"检查数据完整性..." # 检查Ubuntu镜像 if [ -f "/data/mirrors/ubuntu/mirror/dists/jammy/Release" ]; then echo"Ubuntu镜像完整" else echo"Ubuntu镜像损坏,需要重新同步" /data/mirrors/scripts/sync-ubuntu.sh fi # 检查CentOS镜像 if [ -f "/data/mirrors/centos/8-stream/baseos/repodata/repomd.xml" ]; then echo"CentOS镜像完整" else echo"CentOS镜像损坏,需要重新同步" /data/mirrors/scripts/sync-centos.sh fi } # 主恢复流程 main() { echo"开始故障恢复..." recover_services recover_configs check_data_integrity echo"故障恢复完成" } main "$@"监控脚本# 创建监控脚本 sudo nano /data/mirrors/scripts/monitor.sh#!/bin/bash # 实时监控脚本 ALERT_EMAIL="admin@example.com" WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" send_alert() { local message="$1" local severity="$2" echo"[$(date)] ALERT [$severity]: $message" # 发送邮件告警 echo"$message" | mail -s "Mirror Alert [$severity]""$ALERT_EMAIL" # 发送Webhook通知 curl -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"$message\", \"severity\":\"$severity\"}" \ "$WEBHOOK_URL" } # 检查磁盘空间 check_disk() { local usage=$(df /data/mirrors | awk 'NR==2 {print $5}' | sed 's/%//') if [ "$usage" -gt 90 ]; then send_alert "磁盘空间严重不足: ${usage}%""CRITICAL" elif [ "$usage" -gt 80 ]; then send_alert "磁盘空间不足: ${usage}%""WARNING" fi } # 检查同步状态 check_sync() { local last_sync=$(stat -c %Y /data/mirrors/ubuntu/last_update 2>/dev/null || echo 0) local current_time=$(date +%s) local diff=$((current_time - last_sync)) # 如果超过24小时未同步 if [ $diff -gt 86400 ]; then send_alert "Ubuntu镜像同步超时: $((diff/3600))小时""WARNING" fi } # 检查服务状态 check_services() { local services=("nginx""docker") for service in"${services[@]}"; do if ! systemctl is-active --quiet "$service"; then send_alert "$service 服务异常""CRITICAL" fi done } # 主监控循环 main() { whiletrue; do check_disk check_sync check_services sleep 300 # 5分钟检查一次 done } main "$@"总结通过本文的详细指南,我们成功搭建了一个完整的私有 Linux 镜像仓库系统,包括:核心功能• 多发行版支持:Ubuntu、CentOS、Docker镜像• 自动化同步:定时同步上游镜像源• 负载均衡:HAProxy + Keepalived高可用方案• 监控告警:Prometheus + Grafana监控体系运维特性• 安全加固:SSL/TLS、访问控制、防火墙配置• 故障恢复:自动化故障检测和恢复机制• 性能优化:缓存策略、并发控制• 日志管理:完整的日志记录和轮转最佳实践定期备份:配置文件和关键数据的定期备份容量规划:根据使用情况合理规划存储容量网络优化:配置适当的缓存和CDN策略安全更新:及时更新系统和软件包这套方案可以满足企业级的私有镜像仓库需求,提供稳定、高效、安全的软件包分发服务。
2025年08月13日
29 阅读
0 评论
1 点赞
2025-07-05
用虚拟IP扩容服务器端口池
最近遇到一个棘手的问题:服务器的 WebSocket 服务在高并发场景下,客户端连接数达到一万多时,服务器的端口资源被耗尽了。导致后面的任何请求都没响应。通过 netstat 查看连接情况,发现所有连接的本地端口都是从 32768 开始的,即使我已经将系统的端口范围设置为 1024-65535[root@server ~]# cat /proc/sys/net/ipv4/ip_local_port_range 1024 65535但实际分配的端口还是从32768开始,导致高位端口很快被耗尽,新连接无法建立。问题分析经过一番调研,发现这个问题在 Linux 系统中很常见。虽然设置了 ip_local_port_range 为 1024-65535,但实际上如下:glibc的默认行为:很多Linux发行版的glibc硬编码了临时端口分配的起始值为32768内核版本限制:老版本内核(如3.10)没有 ip_unprivileged_port_start 参数历史遗留问题:这是Linux系统的"正常"行为,不是配置错误我的服务器环境: 内核:3.10.0-1127.19.1.el7.x86_64glibc:2.17系统:CentOS 7.6解决方案探索方案一:升级系统(不推荐)升级glibc和内核到新版本可以支持更灵活的端口分配,但在生产环境中风险极高,容易导致系统崩溃。方案二:虚拟IP扩容(推荐)通过在同一台服务器上添加多个虚拟IP,每个IP都拥有独立的端口池,从而成倍扩容端口资源。虚拟IP方案实施第一步:查看网络环境首先确认服务器的网卡和IP配置:[root@server ~]# ip addr show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:16:3e:1f:ee:09 brd ff:ff:ff:ff:ff:ff inet 1.2.3.17/20 brd 11.22.33.255 scope global dynamic eth0可以看到主IP是 1.2.3.17/20 ,子网掩码是 /20。第二步:添加虚拟IP根据主IP的网段,添加几个虚拟IP:ip addr add 1.2.3.100/20 dev eth0 ip addr add 1.2.3.101/20 dev eth0 ip addr add 1.2.3.102/20 dev eth0这里的ip后三位可以随便写。ip个数最好是100个以内,多了会影响性能。验证添加成功:ip addr show eth0显示出刚才添加的ip就是没问题的第三步:配置Nginx负载均衡修改Nginx配置,将流量分发到不同的虚拟IP:upstream websocket_backend { server 1.2.3.100:38088; server 1.2.3.101:38088; server 1.2.3.102:38088; } server { listen 80; server_name xx.com; location /请求上下文 { proxy_pass http://websocket_backend/请求上下文; proxy_redirect default; proxy_pass_header Server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; } }第四步:重启服务重启 WebSocket服务端 和 Nginx ,让配置生效:nginx -t nginx -s reload效果验证查看连接分布使用 ss 命令查看连接是否被正确分发到不同虚拟IP:ss -tnp | grep 38088输出显示连接确实被分发到了不同IP:CLOSE-WAIT 1 0 1.2.3.100:38088 169.24.13.2:36294 CLOSE-WAIT 1 0 1.2.3.101:38088 169.24.13.2:57430 CLOSE-WAIT 1 0 1.2.3.102:38088 169.24.13.2:37558这里的169.24.13.2不用管,这是我的nginx用的docker镜像的原因端口资源扩容效果之前:所有连接都占用 1.2.3.17 的端口池(32768~65535)现在:连接分散到3个虚拟IP,每个IP都有独立的端口池效果:端口资源扩容3倍,极大缓解端口耗尽问题注意事项1. 子网掩码的确定添加虚拟IP时,子网掩码必须和主IP一致。查看方法很简单:ip addr show eth0看输出中的 inet 1.2.3.17/20,直接使用 /20 即可。2. 虚拟IP的持久化临时添加的虚拟IP重启后会失效,需要写入启动脚本:# 编辑 /etc/rc.local ip addr add 1.2.3.100/20 dev eth0 ip addr add 1.2.3.101/20 dev eth0 ip addr add 1.2.3.102/20 dev eth0 # 赋予执行权限 chmod +x /etc/rc.d/rc.local3. 网络架构要求Nginx 和 WebSocket服务端 必须在同一台服务器虚拟IP必须在同一网段内,不能和其他机器冲突如果是云服务器,可能需要先在控制台申请辅助私网IP总结通过 虚拟IP + Nginx 负载均衡的方案,成功将端口资源扩容了 3倍,有效解决了高并发 WebSocket 场景下的端口耗尽问题。这个方案的优势:实施简单:只需添加虚拟IP和配置Nginx风险较低:不需要升级系统内核效果显著:端口资源成倍扩容扩展性好:可以根据需要继续添加虚拟IP对于高并发WebSocket、短连接等场景,这是一个非常实用的解决方案。
2025年07月05日
32 阅读
0 评论
0 点赞
2025-05-16
远程桌面控制软件-rustdesk-附docker部署脚本
客户端程序 1.4.0 版本官网地址:https://github.com/rustdesk/rustdesk/releases/tag/1.4.0{cloud title="rustdesk-1.4.0" type="lz" url="https://wwtt.lanzouy.com/b02djvq20f" password="9dwl"/}自建中继服务器Docker脚本试过很多远程软件,最后还是觉得 rustdesk 最适合,如果家里有nas,那就更完美了,可以自建中继服务器,不过官方的不带账号功能,需要配合rustdesk-api才能实现账号管理,有大神整合了API功能,以下yaml文件直接实现,IPV6也是可以的,要双方都有IPV6,我域名绑定的IP6地址,没有卡顿,画质清晰。networks: rustdesk-net: external: false services: rustdesk: ports: - 21114:21114 - 21115:21115 - 21116:21116 - 21116:21116/udp - 21117:21117 - 21118:21118 - 21119:21119 image: lejianwen/rustdesk-server-s6:latest environment: - RELAY=<server[:21117]> - ENCRYPTED_ONLY=1 - MUST_LOGIN=Y #是否必须登录 - TZ=Asia/Shanghai - RUSTDESK_API_RUSTDESK_ID_SERVER=<server[:21116]> #21116 - RUSTDESK_API_RUSTDESK_RELAY_SERVER=<server[:21117]> #21117 - RUSTDESK_API_RUSTDESK_API_SERVER=http://<server[:21114]> #21114 - RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub - RUSTDESK_API_JWT_KEY=xxxxxx # jwt key volumes: - /data/rustdesk/server:/data #将server的key挂载出来 - /data/rustdesk/api:/app/data #将数据库挂载 networks: - rustdesk-net restart: unless-stoppedkey 在 Docker 运行后在 日志 中查看将自己的IP或者域名替换以上<>,如: - RELAY=<server[:21117]> 替换成 - RELAY=8.8.8.8:21117 或者 - RELAY=http://baidu.com:21117客户端设置客户端只需要配置网络,有4个设置项,其中3个必填,如果需要登录就需要设置API服务器ID服务器:域名或者IP:21116中继服务器:域名或者IP:21117API服务器:http://域名orIP:21114key,从日志中查看实测公网IPV6绑定域名,只要双方都有IPV6也能流畅访问。
2025年05月16日
84 阅读
0 评论
0 点赞
2025-03-06
PVE重装后恢复虚拟机
在 PVE(Proxmox Virtual Environment) 重装后,恢复虚拟机的关键在于提前备份好虚拟机的配置文件和磁盘映像。备份虚拟机配置文件首先,备份虚拟机配置文件,这些文件通常位于 /etc/pve/qemu-server/ 目录下。每个虚拟机都有一个独立的配置文件,文件名格式为 .conf 。手动备份cp /etc/pve/qemu-server/<VMID>.conf /path/to/backup/自动备份脚本#!/bin/bash BACKUP_DIR=/path/to/backup/ mkdir -p $BACKUP_DIR cp /etc/pve/qemu-server/*.conf $BACKUP_DIR恢复虚拟机配置文件将备份的配置文件复制回PVE服务器的对应目录。手动恢复cp /path/to/backup/<VMID>.conf /etc/pve/qemu-server/自动恢复脚本#!/bin/bash BACKUP_DIR=/path/to/backup/ cp $BACKUP_DIR/*.conf /etc/pve/qemu-server/备份和恢复虚拟机磁盘映像磁盘映像通常存储在PVE的存储池中,位于 /var/lib/vz/images/ 目录下。手动备份磁盘映像cp /var/lib/vz/images/<VMID>/*.qcow2 /path/to/backup/自动备份脚本#!/bin/bash BACKUP_DIR=/path/to/backup/ mkdir -p $BACKUP_DIR cp /var/lib/vz/images/*/*.qcow2 $BACKUP_DIR手动恢复磁盘映像cp /path/to/backup/*.qcow2 /var/lib/vz/images/<VMID>/自动恢复脚本#!/bin/bash BACKUP_DIR=/path/to/backup/ cp $BACKUP_DIR/*.qcow2 /var/lib/vz/images/<VMID>/使用CLI工具进行恢复使用 qmrestore 命令从备份中恢复虚拟机。恢复虚拟机磁盘映像qmrestore /path/to/backup/<VMID>.qcow2 <VMID>检查并启动虚拟机qm list # 查看所有虚拟机状态 qm start <VMID> # 启动恢复的虚拟机通过以上步骤,可以确保在 PVE 重装后,虚拟机能够正常恢复和运行。
2025年03月06日
152 阅读
0 评论
0 点赞
2025-03-06
推荐31个docker应用,每一个都很实用
推荐的这些 docker 应用都是我自己常用的,同时也有自己的一些偏好在里面,每个人的需求不同,对应用的要求也不同。还有很多优秀的 docker 应用我没有用过,所有没有推荐的并不代表不优秀。所有的 docker 应用布署都比较简单,只有少量的会需要在数据库和权限的配置上研究一下。排名不分先后Memos 笔记记事功能强大的笔记应用,支持多用户,笔记支持私有,工作区和公开https://github.com/usememos/memosWbo-Boards 共享白板非常好的白板应用,支持多人共享,一人在白板上画图写字,其他在线用户可以实时看到https://github.com/lovasoa/whitebophirVaultWard 密码管理BitWard的轻量版,密码管理,可以在电脑和手机上自动填写用户和密码,实现自动登陆注意:此应用不支持IP:Port访问,安全原因,只支持https连接https://github.com/dani-garcia/vaultwardenMoments 极简朋友圈微信朋友圈风格,支持多用户,可以发贴和记事,比起各博客应用更简单易用https://github.com/kingwrcy/momentsGhost 博客本人最喜欢的博客应用,轻松发博,只是对中文版支持不是太好https://github.com/TryGhost/GhostTypecho 博客简单的博客,发博时稍烦所,不如Ghost强大,简单易用不如极简朋友圈,看个人的需求https://github.com/typecho/typechoEasyImage 图床本人自用的主力图床https://hub.docker.com/r/ddsderek/easyimageLsky-pro 图床图床不多说了,感觉功能易用性和EasyImage差不多https://hub.docker.com/r/dko0/lsky-pro/Lychee 相册漂亮且功能强大的相册,支持多用户和相册分享注意:如果不能上传图片,检查一下目录的权限https://github.com/LycheeOrg/LycheeFileBrowser 网盘简单易用,适合个人自用,当然也支持多用户和文件分享https://github.com/filebrowser/filebrowserCloudreve 网盘强大的网盘,虽不如Nextcloud强大,但是速度更快更好用,支持多用户和文件分享https://github.com/cloudreve/CloudreveFileCodeBox 文件文字加密分享简单易用,支持访客分享,让小白分享文件更简单更安全用户通过简单的方式分享文本和文件,接收者只需要一个提取码就可以取得文件,就像从快递柜取出快递一样简单https://github.com/vastsa/FileCodeBoxJellyfin 视频流媒体服务器不用多说了,和Emby一样的功能,但这个是开源免费的https://github.com/jellyfin/jellyfinAllinOne IPtv可以在线看央视和其他地方卫视。https://www.nodeseek.com/post-176265-1Navidrome 音乐服务器音乐收藏和流媒体服务器,里面没有音乐,要自己上传音乐文件https://github.com/navidrome/navidromeMeTube 视频网站下载器可以从YouTube下载视频,或直接下载音频,支持视频列表下载。同时还支持从其他上百个视频网站下载https://github.com/alexta69/metubeqBittorrent 下载工具大家都应该用过吧https://github.com/qbittorrent/qBittorrentDosGame DOS老游戏Dos游戏中文版,可以用浏览器在线玩dos游戏,包含40几个经典游戏https://hub.docker.com/r/oldiy/dosgame-web-docker/LinkAce 书签管理网址网页收藏管理,支持多用户,书签支持私有,内部和公开https://github.com/Kovah/LinkAceOneNav 书签管理强大且简洁高效的浏览器书签管理器,个人单用户适用https://github.com/helloxz/onenavSlash 短域名跳转如果自己拥有短域名,可以设置短域名跳转服务注意:开源版有些限制,码佬可以自己改一下https://github.com/yourselfhosted/slashActualBudet 记账应用功能不错,但本人只用过一些简单功能,好像暂时没有中文版本https://github.com/actualbudget/actual-serverTimeTagger 时间记录时间记录打卡,很适合小朋友练琴和学习的时间记录,支持标签https://github.com/almarklein/timetaggerStirling-PDF PDF编辑转换PDF编辑转换工具,功能超级强大,再也不用花钱买PDF软件了https://github.com/Stirling-Tools/Stirling-PDFit-tools IT常用工具各种IT常用工具。https://github.com/CorentinTh/it-toolsSpeedTest 网速测试网速测试应用,简单易用,也可以用作docker测试应用https://github.com/librespeed/speedtestUptime-Kuma 监测工具实时监测工具,可以对IP,网站,DNS等服务进行实时监测,并可发送警报信息https://github.com/louislam/uptime-kumaSmokeping 网络延迟监测自定义IP点,监测网络延迟,并可以显示延迟图https://github.com/linuxserver/docker-smokepingServerStatus 探针本人的主力探针,简单易用,支持一键脚本布署https://github.com/cppla/ServerStatusMyNodeQuery 探针本人的备用探针,简单易用,支持一键脚本布署https://hub.docker.com/r/jaydenlee2019/mynodequery/Adminer 数据库管理工具强大易用的数据库管理工具,支持MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, MongoDB等各种数据库。本人原来一直用phpmyadmin管理MySQL数据库,现在已改用Adminer了。https://github.com/vrana/adminer
2025年03月06日
1,311 阅读
0 评论
0 点赞
1
2
...
6