[{"content":"本文记录在 CentOS 7 环境下编译安装 Transmission 2.94, 并通过修改源码添加 跳过校验 (Skip Hash Check) 功能的相关步骤。适用于 已有完整数据 需要快速做种, 或迁移数据后避免长时间 Hash 校验的场景。\n安装编译环境及依赖\r安装编译 Transmission 所需的基础环境及依赖库, 包括 libevent、curl、zlib 与 OpenSSL 等组件\nyum install -y automake libtool libcurl-devel libevent-devel zlib-devel openssl11 openssl11-devel intltool 下载 Transmission 源码\rTransmission 官方发布仓库。下载并解压 Transmission 2.94 源码, 后续修改与编译操作均在源码目录中进行\nwget https://github.com/transmission/transmission-releases/raw/master/transmission-2.94.tar.xz tar xf transmission-2.94.tar.xz cd transmission-2.94 使用 OpenSSL 1.1\rCentOS 7 默认 OpenSSL 版本较低, Transmission 2.94 编译时需手动指定 OpenSSL 1.1 的头文件与库文件路径\nexport OPENSSL_CFLAGS=$(pkg-config --cflags openssl11) export OPENSSL_LIBS=$(pkg-config --libs openssl11) 添加跳过校验检查功能\r通过修改 Transmission 源码, 可在添加种子后选择跳过 Hash 校验, 适用于 本地已存在完整数据、迁移做种数据或大体积种子快速做种等场景。\n手动修改源码\r参考 transmission-2.92_skiphashcheck 项目。该修改方案原用于 Transmission 2.92, 经测试同样适用于 Transmission 2.94\n编辑 libtransmission/rpcimpl.c 文件, 在 388 行位置调用 skiphash() 函数\n386 387 assert (idle_data == NULL); 388 389+ skiphash(); 390 torrents = getTorrents (session, args_in, \u0026amp;torrentCount); 391 for (i=0; i\u0026lt;torrentCount; ++i) 392 { 编辑 libtransmission/verify.c 文件, 在 41 行位置新增全局变量和函数定义\n39 MSEC_TO_SLEEP_PER_SECOND_DURING_VERIFY = 100 40 }; 41 42+static bool skiphashcheck=false; 43+void skiphash(){ 44+ skiphashcheck=true; 45+} 46+ 47 static bool 48 verifyTorrent (tr_torrent * tor, bool * stopFlag) 49 { 修改约 81 行附近代码, 在文件打开判断前增加 !skiphashcheck \u0026amp;\u0026amp; 条件\n78 hadPiece = tr_torrentPieceIsComplete (tor, pieceIndex); 79 80 /* if we\u0026#39;re starting a new file... */ 81- if (filePos == 0 \u0026amp;\u0026amp; fd == TR_BAD_SYS_FILE \u0026amp;\u0026amp; fileIndex != prevFileIndex) 82+ if (!skiphashcheck \u0026amp;\u0026amp; filePos == 0 \u0026amp;\u0026amp; fd == TR_BAD_SYS_FILE \u0026amp;\u0026amp; fileIndex != prevFileIndex) 83 { 84 char * filename = tr_torrentFindFile (tor, fileIndex); 85 fd = filename == NULL ? TR_BAD_SYS_FILE : tr_sys_file_open (filename, 修改约 100 行附近代码, 在文件读取时增加 !skiphashcheck \u0026amp;\u0026amp; 条件\n97 if (fd != TR_BAD_SYS_FILE) 98 { 99 uint64_t numRead; 100- if (tr_sys_file_read_at (fd, buffer, bytesThisPass, filePos, \u0026amp;numRead, NULL) \u0026amp;\u0026amp; numRead \u0026gt; 0) 101+ if (!skiphashcheck \u0026amp;\u0026amp; tr_sys_file_read_at (fd, buffer, bytesThisPass, filePos, \u0026amp;numRead, NULL) \u0026amp;\u0026amp; numRead \u0026gt; 0) 102 { 103 bytesThisPass = numRead; 104 tr_sha1_update (sha, buffer, bytesThisPass); 修改约 124 行附近代码, 使校验逻辑直接返回成功\n121 uint8_t hash[SHA_DIGEST_LENGTH]; 122 123 tr_sha1_final (sha, hash); 124- hasPiece = !memcmp (hash, tor-\u0026gt;info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH); 125+ hasPiece = skiphashcheck || !memcmp (hash, tor-\u0026gt;info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH); 126 127 if (hasPiece || hadPiece) 128 { 最后在约 162 行位置增加日志输出及状态重置\n159 } 160 } 161 162+ if(skiphashcheck){ 163+ skiphashcheck=false; 164+ tr_logAddTorInfo (tor, \u0026#34;%s\u0026#34;, _(\u0026#34;skip hash check\u0026#34;)); 165+ } 166 /* cleanup */ 167 if (fd != TR_BAD_SYS_FILE) 168 tr_sys_file_close (fd, NULL); 修改完成后, 可参考下图查看完整差异\n使用 Patch 一键修改源码\r如果不希望手动修改源码, 可以直接应用现成的 Patch 文件\n# 下载 Patch wget https://github.com/superlukia/transmission-2.92_skiphashcheck/commit/56e327d1dacb5b3453954b76a6d0edd30edb7a34.patch # 使用 patch 命令应用 patch -p 1 \u0026lt; 56e327d1dacb5b3453954b76a6d0edd30edb7a34.patch # 或者使用 Git 的 Patch 应用方式 git apply 56e327d1dacb5b3453954b76a6d0edd30edb7a34.patch 应用完成后即可继续编译 Transmission\n编译安装 Transmission\rTransmission 2.94 依赖较新的 GCC 版本进行编译, 而 CentOS 7 默认提供的 GCC 4.8 版本过低, 因此需要先安装 Software Collections (SCL) 中的 GCC 9 编译工具链\n安装 GCC 9\nyum install epel-release centos-release-scl -y yum install devtoolset-9-gcc* -y 使用 GCC 9 生成编译配置并编译源码\nscl enable devtoolset-9 \u0026#34;./autogen.sh --prefix=/usr\u0026#34; scl enable devtoolset-9 \u0026#34;make -j\u0026#34; make install 编译完成后, 可通过以下命令确认版本信息\ntransmission-daemon --version 使用方式\r完成编译安装后, 即可使用跳过校验功能\n在 Transmission Web 界面添加种子后, 当任务进入校验状态时, 右键点击对应种子, 选择\nAsk tracker for more peers 获取更多 Peer 此时 Transmission 会跳过 Hash 校验过程, 直接将种子标记为已完成并开始做种\n该功能 仅适用于本地已存在完整数据 的场景, 例如 迁移做种数据、重装系统后恢复种子 或 快速重新做种 等\n创建 systemd 服务\rTransmission 编译安装完成后, 可以创建 systemd 服务实现开机自启动\n由于本文编译过程中 未启用 libsystemd-devel 支持, 因此 service 文件建议使用 Type=simple 而不是 Type=notify, 否则可能出现 systemctl start transmission 后服务长时间处于 activating 状态的问题。\n编辑服务文件\nvim /etc/systemd/system/transmission.service 写入以下内容\n[Unit] Description=Transmission Service After=network.target [Service] User=acesheep # 修改为实际运行 Transmission 的用户 Group=acesheep # 修改为实际运行 Transmission 的用户 Type=simple ExecStart=/usr/bin/transmission-daemon --log-error -f ExecStop=/bin/kill -s TERM $MAINPID ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=666666 [Install] WantedBy=multi-user.target 加载并启动服务\nsystemctl daemon-reload systemctl start transmission systemctl enable transmission systemctl status transmission # Transmission 在不中断下载任务的情况下重新加载配置 # - 重新加载配置文件 # - 重新打开日志文件 # - 不会中断当前下载和做种任务 # - 不会退出进程 systemctl reload transmission 配置防火墙 firewalld\rTransmission 默认需要监听 BT 通信端口。如果系统启用了 firewalld, 则需要放行对应端口, 否则可能影响 Peer 连接数量以及下载、上传效率\n本文以 52333 端口为例, 通过自定义 Firewalld Service 的方式放行 Transmission 使用的 TCP 和 UDP 端口\n创建服务配置文件\nvim /usr/lib/firewalld/services/transmission-client.xml 写入以下内容\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;service\u0026gt; \u0026lt;short\u0026gt;Transmission\u0026lt;/short\u0026gt; \u0026lt;description\u0026gt;Transmission is a lightweight BitTorrent client.\u0026lt;/description\u0026gt; \u0026lt;port protocol=\u0026#34;tcp\u0026#34; port=\u0026#34;52333\u0026#34;/\u0026gt; \u0026lt;port protocol=\u0026#34;udp\u0026#34; port=\u0026#34;52333\u0026#34;/\u0026gt; \u0026lt;/service\u0026gt; 加载并启用防火墙规则\nfirewall-cmd --add-service=transmission-client --permanent firewall-cmd --reload 验证规则是否生效。如果输出结果中包含 transmission-client 则表示防火墙规则已成功加载\nfirewall-cmd --list-services 如果 Transmission 使用的不是 52333 端口, 请根据实际配置修改 XML 文件中的端口号, 然后重新加载 firewalld 配置\n设置文件打开数量\r当 Transmission 管理大量种子或建立大量 Peer 连接时, 系统默认的文件描述符 (File Descriptor) 限制可能不足, 从而导致出现 Too many open files 错误。因此建议适当提高系统和用户的文件打开数量限制\n首先查看当前系统和用户的限制值\ncat /proc/sys/fs/file-max ulimit -Hn ulimit -Sn 其中\nfile-max: 系统级最大文件句柄数量 ulimit -Hn: 当前用户硬限制 (Hard Limit) ulimit -Sn: 当前用户软限制 (Soft Limit) 编辑 limits.conf 配置文件\nvim /etc/security/limits.conf 添加以下内容\nroot hard nofile 1048573\rroot soft nofile 1048573\racesheep hard nofile 1048573\racesheep soft nofile 1048573 说明\nroot 为系统管理员账户 acesheep 为运行 Transmission 的用户, 请根据实际情况修改 hard 为硬限制 soft 为软限制 nofile 表示允许打开的最大文件数量 修改完成后, 重新登录用户会话或重启系统使配置生效\n验证当前限制\nulimit -a 如果 Transmission 通过 systemd 启动, 还建议在 service 文件中增加\nLimitNOFILE=666666 这是因为 systemd 启动的服务不一定会继承 limits.conf 中配置的文件描述符限制。对于大量种子、高并发连接或长期做种的场景, 建议同时配置 limits.conf 和 LimitNOFILE, 以确保 Transmission 能获得足够的文件句柄资源\n原文\nubuntu18.04编译使用transmission2.92/2.94/3.0跳过校验\n","date":"2026-05-19T11:20:45+08:00","permalink":"https://blog.acesheep.com/p/centos-7-transmission-2.94-skip-hash-check-feature/","title":"CentOS 7 编译安装 Transmission 2.94 添加跳过校验检查功能"},{"content":"在 SELinux 配置过程中, 如果你尝试使用 semanage 命令来修改安全策略, 可能会遇到如下错误\n# semanage fcontext -a -t samba_share_t \u0026#34;/finance(/.*)?\u0026#34; -bash: semanage: command not found 什么是 semanage\rsemanage 是 SELinux 提供的一个管理工具, 用于在 不直接修改或重新编译策略源码 的情况下, 对 SELinux 的各种配置项进行管理。\n它可以用于:\nLinux 用户与 SELinux 用户身份映射 文件和目录安全上下文 (file context) 网络端口类型映射 接口和主机标签 布尔值 (booleans) 管理 常见用途包括:\n修改 Samba 共享目录的 SELinux 标签 允许 Apache HTTP Server 使用自定义端口 配置 OpenSSH 使用非标准端口 如何查找哪个软件包提供了 semanage?\r可以使用以下命令查询:\nyum provides /usr/sbin/semanage 系统将返回类似信息:\n[root@server ~]# yum provides /usr/sbin/semanage Last metadata expiration check: 1:47:23 ago on Thu 14 May 2026 08:22:52 PM CST. policycoreutils-python-utils-2.9-25.el8.noarch : SELinux policy core python utilities Repo : baseos Matched from: Filename : /usr/sbin/semanage policycoreutils-python-utils-2.9-26.el8_10.noarch : SELinux policy core python utilities Repo : @System Matched from: Filename : /usr/sbin/semanage policycoreutils-python-utils-2.9-26.el8_10.noarch : SELinux policy core python utilities Repo : baseos Matched from: Filename : /usr/sbin/semanage 从上面的示例输出可以看出, 我们需要安装 policycoreutils-python-utils 软件包才能使用 semanage 命令\n安装 semanage\rsemanage 是 SELinux 的高级管理工具, 而 \u0026ldquo;command not found\u0026rdquo; 的根本原因通常只是系统未安装 policycoreutils-python-utils 软件包。\nRocky 8 / 9\nyum install policycoreutils-python-utils CentOS 7\nyum install policycoreutils-python 常用 semanage 命令\r查看文件上下文规则\rsemanage fcontext -l 查看端口规则\rsemanage port -l 查看布尔值\rgetsebool -a 实例\rsemanage 最重要的用途, 就是在 不关闭 SELinux 的情况下, 告诉系统 \u0026ldquo;哪些目录可以被某个服务访问\u0026rdquo;、\u0026ldquo;哪些端口可以被某个服务使用\u0026rdquo;。它并不会直接修改文件本身, 而是向 SELinux 的策略数据库中添加永久规则。这样, 当系统重新启动、执行 restorecon, 或者进行完整的文件系统 relabel 时, 这些规则仍然有效。\n为 Samba 共享目录设置 SELinux 上下文\r当我们配置 Samba 共享目录时, 经常会遇到一种情况: 目录权限看起来完全正确, smb.conf 配置也没有问题, 但客户端仍然提示 \u0026ldquo;Access Denied\u0026rdquo; 或 \u0026ldquo;Permission Denied\u0026rdquo;\n例如, 我们创建一个共享目录:\nmkdir /finance chmod 777 /finance 并在 Samba 配置中定义:\n[finance] path = /finance read only = no guest ok = yes 从传统 Linux 权限的角度看, 这个目录已经允许任何人读写, 但 SELinux 并不仅仅检查 rwx 权限, 它还会检查文件的 安全上下文 (Security Context)\n可以使用以下命令查看目录当前的 SELinux 标签:\nls -Zd /finance 可能看到类似:\nunconfined_u:object_r:default_t:s0 /finance 其中最关键的是 default_t。这表示该目录只是普通的默认类型, 而 Samba 进程 (smbd) 默认不允许访问这种类型的目录。\nSELinux 为 Samba 预定义了一个专门的类型:\nsamba_share_t 这个类型的含义就是: \u0026ldquo;这是一个合法的 Samba 共享目录\u0026rdquo;\n因此, 我们需要执行:\nsemanage fcontext -a -t samba_share_t \u0026#34;/finance(/.*)?\u0026#34; 这条命令的含义是:\nfcontext: 管理文件路径对应的 SELinux 标签规则 -a: 添加新规则 -t samba_share_t: 指定目录应使用的类型 \u0026quot;/finance(/.*)?\u0026quot;: 使用正则表达式匹配 /finance 及其所有子目录和文件 这里的正则表达式非常重要:\n/finance(/.*)? 它表示:\n/finance /finance/file.txt /finance/subdir /finance/subdir/report.pdf 也就是说, 整个目录树都会使用 samba_share_t 类型\n需要注意的是, 执行 semanage 之后, 只是把规则写入了 SELinux 数据库, 并不会立刻修改磁盘上的文件标签。要真正应用规则, 还需要执行:\nrestorecon -Rv /finance 其中:\n-R 表示递归处理 -v 表示显示详细过程 完成后再次查看:\nls -Zd /finance # 你将看到 system_u:object_r:samba_share_t:s0 /finance 这意味着 SELinux 已经明确知道: 这个目录是供 Samba 使用的, smbd 可以安全访问它。\n从本质上说, 这相当于告诉 SELinux:\n/finance 是一个正式授权给 Samba 使用的共享目录, 请允许 Samba 访问其中的所有文件\n为 Apache 添加自定义端口\rApache HTTP Server (httpd) 默认只能监听 SELinux 预先允许的端口, 例如 80 和 443\n假设你在 Apache 配置中写入:\nListen 8080 然后执行:\nsystemctl restart httpd 可能会启动失败。原因并不是 Apache 配置错误, 而是 SELinux 认为 8080 并不是一个被授权给 Web 服务使用的端口。\n可以查看当前允许的 HTTP 端口:\nsemanage port -l | grep http_port_t 通常会显示:\nhttp_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 可以看到, 8080 并不在列表中\n此时需要执行:\nsemanage port -a -t http_port_t -p tcp 8080 这条命令的含义是:\nport: 管理端口规则 -a: 添加新规则 -t http_port_t: 将该端口归类为 HTTP 服务端口 -p tcp: 指定 TCP 协议 8080: 要开放的端口号 执行后, 再次查看:\nsemanage port -l | grep http_port_t 你将看到 8080 已经被加入列表\n之后重新启动 Apache:\nsystemctl restart httpd 就可以成功监听 8080\n这实际上是在告诉 SELinux:\n8080 是一个合法的 Web 服务端口, 请允许 Apache 在此端口上提供服务\n这两个例子详细的说明了 semanage 的核心作用。\n对目录而言, 它建立的是 \u0026ldquo;路径 → SELinux 类型\u0026rdquo; 的映射 对端口而言, 它建立的是 \u0026ldquo;端口号 → 服务类型\u0026rdquo; 的映射 服务进程只有在访问与自己类型匹配的资源时, SELinux 才会允许操作。\n因此, semanage 的本质可以概括为:\n向 SELinux 的永久白名单中添加规则, 使你的自定义目录和端口获得正式授权\n这也是在生产环境中推荐的做法, 因为它既保持了 SELinux 的安全保护, 又允许服务按照你的需求运行, 而无需通过关闭 SELinux 来规避安全机制。\n原文\nHow to Fix ‘semanage command’ Not Found Error in CentOS/RHEL\n","date":"2026-05-13T17:36:54+08:00","permalink":"https://blog.acesheep.com/p/fix-semanage-command-not-found-in-centos-rhel/","title":"如何在 CentOS/RHEL 中修复 \"semanage: command not found\" 错误"},{"content":"\r本文列出了 RHEL 9 与 RHEL 8 各版本之间的主要差异，以及 RHEL 9 中引入的关键特性。虽然默认文件系统保持不变，但内核版本有显著提升并带来了大量改进。RHEL 9 是 Red Hat 首个基于 CentOS Stream 构建的企业级发行版。\n功能 RHEL 9 RHEL 8 默认文件系统 XFS XFS 内核版本 5.14.0-x 4.18.0-x 内核代号 Plow Ootpa 首个正式版本发布日期 2022-05-17 (内核 5.14.0-70.13.1) 2019-05-07 (内核 4.18.0-80) 最大逻辑 CPU 数 (x86_64) 1792 (最大 8192) 768 (最大 8192) 最大支持内存 (x86_64) 48 TB (最大 64 TB) 24 TB (最大 64 TB) 编译器/工具链 GCC 11.2.1 GCC 8.2.1 默认数据库 MySQL 8.0、MariaDB 10.5、PostgreSQL 13、Redis 6.2 MySQL 8.0、MariaDB 10.3、PostgreSQL 10/9.6、Redis 5.0 支持的硬件架构 AMD/Intel 64 位 (x86-64-v2)；ARM 64 位 (ARMv8.0-A)；IBM Power (POWER9，小端)；IBM Z (z14) AMD/Intel 64 位；ARM 64 位；IBM Power (小端)；IBM Z SCP 变更 SCP 已弃用，默认使用 SFTP (SSH 文件传输协议) 使用 OpenSSH 提供的 SCP 网络配置文件 使用 NetworkManager，配置文件位于 /etc/NetworkManager/system-connections/，采用 key-file 格式 (如: enp0s3-nmconnection) 使用 /etc/sysconfig/network-scripts/，ifcfg-xxxx 格式 浏览器版本 Firefox 91.8.0 Firefox 60.5.11 启动配置文件 GRUB 配置统一在 /boot/grub2/；UEFI 下 /boot/efi/EFI/redhat/grub.cfg 为符号链接，统一 BIOS/UEFI BIOS 使用 /boot/grub2/grub.cfg，UEFI 使用 /boot/efi/EFI/redhat/grub.cfg 网络团队 (teaming) teamd 和 libteam 已弃用，建议使用 bonding 同时支持 bonding 和 teaming 桌面 GUI 与图形 默认仍为 Wayland，GNOME 升级至 40，X.org 已被弃用 (Wayland 1.19) 默认 Wayland (GDM)，Wayland 1.15 RHEL 9 额外特性 (Extras)\n额外变更 说明 更强的 OpenSSL 框架 OpenSSL 升级至 3.0.1，引入 Provider (提供者) 架构、新的版本管理机制、改进的 HTTP(S) 客户端，并支持更多协议、格式和加密算法 OpenSSH 改进 OpenSSH 升级到 8.7p1，相较于 RHEL 8 的 8.0p1，提供更多功能增强、错误修复和安全改进。默认使用 SFTP 取代 SCP/RCP 协议 原地升级支持 支持从 RHEL 8.6 原地升级到 RHEL 9，适用于 Intel/AMD 64 位、ARM 64 位、IBM POWER9 和 IBM Z (不含 z13)。不支持从 RHEL 7 直接升级到 RHEL 9，建议先升级到 RHEL 8，再升级到 RHEL 9 新增 Root 账户控制选项 在安装界面中新增选项，可直接锁定 root 账户，并允许通过 SSH 使用密码登录 root 安装后初始化配置默认禁用 默认禁用 gnome-initial-setup 之前的许可协议、订阅管理和用户设置步骤，以简化首次启动体验 OpenShift Fence Agent 新增 fence_kubevirt，可在 RHEL 高可用 (HA) 环境中与 Red Hat OpenShift Virtualization 配合使用 Python 版本更新 默认 Python 版本为 3.9，采用非模块化 RPM 包形式，位于 BaseOS 仓库中 Java 实现更新 AppStream 仓库提供并支持 OpenJDK 17、OpenJDK 11 和 OpenJDK 8，均包含完整的 JRE 和 JDK Kdump 更加稳定 修复 SELinux 权限问题，避免 kdump 无法启动或产生 AVC 拒绝日志，提升系统崩溃转储可靠性 device-mapper-multipath 升级 升级到 0.8.7，修复内存泄漏和 socket 触发问题，并增强对 DELL、EMC 等存储阵列的自动识别与配置能力 WireGuard VPN (技术预览) 提供轻量高性能 VPN，运行于 Linux 内核，使用现代加密算法，配置简单，但仍属于 Technology Preview，不提供正式支持 Stratis (技术预览) 本地存储管理框架，可管理存储池并根据需要自动扩展文件系统，同时集成到 Cockpit Web 控制台 virt-manager 与 libvirt 变化 默认通过 Cockpit 管理虚拟机。单体式 libvirtd 守护进程已弃用，将在未来 RHEL 主版本中移除 原生 NVMe 多路径默认启用 RHEL 9 默认启用 Native NVMe Multipathing。使用 NVMe/TCP 时建议不要再配合 device-mapper-multipath BIOS VGA 安装兼容性 在 Legacy BIOS 模式下安装到 VGA 图形系统时可能无法显示安装界面，可通过添加 nomodeset 启动参数解决 SHA-1 加密用途已弃用 SHA-1 摘要算法不再推荐用于密码学用途，以提升整体系统安全性 以上内容整理自 Red Hat 官方文档\n原文\nRHEL9 v/s 8 Differences\n原文备份\n","date":"2026-04-19T10:44:38+08:00","permalink":"https://blog.acesheep.com/p/rhel-9-vs-8-differences/","title":"RHEL 9 vs 8 的主要区别"},{"content":"\r本文列出了 RHEL 8 与 RHEL 7 各发行版本之间的主要差异, 以及 RHEL 8 中引入的关键特性。Red Hat 的 RHEL 8 已正式 (GA, General Availability) 发布。\n功能 RHEL 8 RHEL 7 默认文件系统 XFS XFS 内核版本 4.18.0-x 3.10.0-x 内核代号 Ootpa Maipo 首个正式版本发布日期 2019-05-07 (内核 4.18.0-80) 2014-06-09 (内核 3.10.0-123) 默认/标准仓库 Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs); Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs) Red Hat Enterprise Linux 7 Server (RPMs) 时间同步 仅支持 chronyd, 不再支持 ntp 支持 ntp 或 chronyd 最大支持文件大小 XFS 文件系统最大 1024 TiB (仅 64 位架构) 单文件最大 500 TiB, 文件系统最大 500 TiB 软件包管理 使用 DNF (YUM v4), yum 为 dnf 的兼容符号链接 使用 YUM v3 最大支持内存 24 TB (x86_64 架构) 12 TB 默认防火墙/包过滤 默认使用 nftables, firewalld 以 nftables 为后端, 统一 IPv4/IPv6 firewalld 默认使用 iptables 默认数据库 MySQL 8.0、MariaDB 10.3、PostgreSQL 10/9.6、Redis 5.0 MariaDB 作为 MySQL 默认实现 支持的硬件架构 AMD/Intel 64 位；ARM 64 位；IBM Power (小端)；IBM Z AMD/Intel 64 位；IBM POWER7；IBM System z Cockpit Web 控制台 默认安装 (非最小化安装), 自动开放防火墙端口, 访问 http://\u0026lt;hostname\u0026gt;:9090 默认未安装, 需要启用 extras/optional 仓库 虚拟机管理 默认通过 Cockpit 管理, 可选安装 virt-manager 使用 virt-manager (KVM) RPM 版本 RPM 4.14 (完整包校验、弱依赖、布尔依赖、\u0026gt;4GB 文件、SHA-256 等) RPM 4.11 (仅在解包时校验单个文件) CUPS 日志 统一记录在 systemd-journald, 可使用 journalctl -u cups 位于 /var/log/cups nobody 用户变更 合并 nobody 与 nfsnobody, 统一 UID/GID 为 65534 nobody 为 99, nfsnobody 为 65534 版本控制系统 Git 2.18、Mercurial 4.8、Subversion 1.10 (不再提供 CVS、RCS) Git、SVN、CVS 编程语言版本 Python 3、PHP 7.2、Ruby 2.5、Node.js 10 Python 2.7、PHP 5.4、Ruby 2.0 容器技术 不再提供 Docker, 改用 podman、buildah、skopeo、runc Docker 和 Docker Registry 位于 Extras 仓库 开发工具 OpenJDK 11、OpenJDK 8、IcedTea-Web、Ant、Maven、Scala 默认 OpenJDK 8 NFS 变化 配置文件在 /etc/nfs.conf；升级时自动迁移；不再支持 UDP 配置文件在 /etc/sysconfig/nfs 默认显示服务器 Wayland (GDM) X.Org 默认 IO 调度器 mq-deadline (可选 kyber、bfq、none) deadline RHEL 8 额外特性 (Extras)\n额外变更 说明 elevator 内核参数已废弃 早期 RHEL 使用 elevator 参数设置磁盘调度器。RHEL 8 中该参数已被上游移除, 仅为兼容性保留 network-scripts 已废弃 默认不再提供传统 network-scripts。新的 ifup/ifdown 基于 NetworkManager, 并使用 nmcli 后端。如需旧脚本需手动安装 network-scripts 包 新内核支持 5 级页表 从 4 级页表 (48/46 位地址, 64TB 物理内存) 升级到 5 级页表 (57/52 位地址), 支持 128 PiB 虚拟地址空间和 4 PB 物理内存 Anaconda 支持 System Purpose 安装阶段即可设置系统用途 (System Purpose), 并传递给 Subscription Manager (支持 Kickstart) CodeReady Linux Builder 仓库 所有 RHEL 订阅可用, 为开发者提供额外构建依赖, 但不支持生产环境使用 OpenSSH 大幅升级 OpenSSH 7.8p1: 不支持 SSH v1；UseDNS 默认关闭；最小 RSA 1024 位；移除弱加密算法；禁用 DSA 不再支持纯数字用户名/组名 useradd、groupadd 禁止纯数字名称 (RHEL7 中已弃用) securetty 默认禁用 /etc/securetty 文件被移除, securetty PAM 模块默认关闭 TCP 网络栈改进 基于 4.18 内核, 提升高并发 TCP 服务性能；新增 BBR、NV 拥塞控制算法, 通常比 cubic 具有更低延迟和更高吞吐 高可用 (HA) 改进 pcs 完全支持 Corosync 3 与 knet；不支持从 RHEL7 原地升级到 RHEL8 的集群节点 lvmlockd 替代 clvmd clvmd 被移除, 改用 lvmlockd 管理共享存储逻辑卷 以上内容整理自 Red Hat 官方文档\n原文\nRHEL 8 v/s 7 Differences\n原文备份\n","date":"2026-01-27T14:46:35+08:00","permalink":"https://blog.acesheep.com/p/rhel-8-vs-7-differences/","title":"RHEL 8 vs 7 的主要区别"},{"content":"你是否见过这样的场景:\n评论区里, IP 归属地来自一些极其小众的国家或地区, 比如朝鲜、南极洲, 或加勒比地区那些人口只有几万人的海岛国家 又或者, 同一个评论区中, 短短几分钟内就 \u0026ldquo;横跨半个地球\u0026rdquo;, 上一条显示来自瑞士, 下一条却来自乌克兰 难道大家都是隐藏多年的富豪, 终于摊牌了？\n是他手持 oneworld Emerald (寰宇一家绿宝石) 在世界各地飞?\n当你开始思考这个问题时, 实际上已经触及到了网络最罕见、也是最核心的部分。你触及到了网络组成的本质\n我先给你一个结论, 不带情绪, 不带滤镜, 稳稳的接住你的问题 ( ChatGPT 5.2 风味\n通过修改 IP 定位, 你可以实现:\n在各类平台显示一些离谱的 IP 归属地 几乎没有互联网基础设施的南极洲 没接入互联网的朝鲜 ✋😭🤚 某些从没听过的, 人口一共几万人的海岛小国家 可以解锁各地流媒体, 参考 DIY任意地区流媒体解锁IPv6 用一台 VPS 获得全球各地的 IP 地址, 挂探针装逼点亮全球, 实现另类的 All In One (怎么这也 All In One) 开 oneman IDC 卖各种地区的 VPS 本篇主要讲述修改 IP 定位的原理以及套 WARP 后得到一个对应地区的 IPv4 地址\nIP 定位原理\r在互联网中, IP 并不存在一个物理意义上精确的位置。\n我们日常看到的 IP 归属地, 本质上是各类 IP 数据库 基于多种信息来源所做出的综合判断, 其中包括:\nIP 注册机构 (RIR) 中的登记信息 路由与 BGP 宣告情况 网络测量结果 (延迟、路径等) 这种判断并非绝对准确, 也会随着网络结构、广播方式和数据库策略的变化而不断调整。\n当然也有一些例外。美团所使用的 IP 定位, 会结合用户的外卖配送地址等业务数据进行校正, 因此在特定场景下非常精准, 但这已经超出了传统 IP 数据库的范畴。\n理解 IP 定位的运作方式, 是理解 \u0026ldquo;为什么能出现朝鲜 / 南极洲 IP\u0026rdquo; 的前提。\nIP 数据库\r要查询 IP 的归属地, 需要依赖 IP 数据库。这些数据库会记录各个 IP 段被认为的使用位置。\n有些大型公司会维护自己的私有 IP 数据库, 例如 Google、Netflix、淘宝、美团。而 B 站、小红书、抖音 这类平台, 一般会直接使用第三方提供的 IP 定位服务。\n常见的 IP 数据库有: Maxmind、IPInfo、DB-IP、Digital Element 等, 有些小数据库, 会直接从这些主流数据库同步或二次加工数据。\nIP 数据库 の 数据来源\rIP 数据库本身并不是权威机构, 而是一个整合者。它们会从多个渠道收集信息, 并对不同来源赋予不同权重, 主要包括:\nRIR (如 RIPE、APNIC、ARIN) 数据库中的注册信息 公网路由表与 BGP 宣告分析 基于探测节点的网络测量结果 网络运营商或用户主动提交的定位修正请求 历史数据与行为特征分析 在此基础上, 数据库会整理出 IP → 地理位置 的映射关系, 并附加更多维度的信息, 例如:\nIP 类型 (家庭宽带 / 数据中心 / VPN) ASN 与运营商信息 风险与威胁评分 这些数据被出售给网站或平台使用, 网站后端直接查询数据库结果, 用于归属地展示和风控判断。\n顺便推荐一个可以同时查询多个 IP 数据库的网站: iplark.com\nIP 数据库 の 探测节点与定位修正\r为了判断 IP 段的实际部署位置, IP 数据库会在全球各地的数据中心部署探测节点。\nProbe network - how we make sure our IP data is accurate\n这些探测节点主要用于:\n从公网路由表中收集已宣告的 IP 前缀 进行 ICMP Ping 延迟测量 推测 IP 段的实际部署区域 由于已分配但未使用的 IP 段数量极其庞大, 大多数 IP 数据库只会收录已经广播到公网的 IP 段。截至目前, 全球已广播的前缀数量: IPv4 前缀为: 1016978、IPv6 前缀为: 225354\n基于这种测量机制, 如果你在美国广播一个在 RIR 注册信息中标注为南极洲的 IP 段, IP 数据库会认为\n探测到的实际部署位置 \u0026gt; 注册信息 从而将该 IP 的归属地直接修正为美国\n但需要注意的是, 这种基于网络测量的方式本身也存在误差。例如在香港广播的地址段, 有时会被粗略归属为深圳\nIP 位置 の 模糊性\r事实上, IP 的位置本来就是一个模糊的概念。\n以 2a14:67c0::/29 为例, 这是一段整体分配给英国的原生 IPv6 地址, 在 RIPE 数据库中, 它在注册层面被视为英国 IP\n大善人 Alice 免费提供了其中的一小段子网 2a14:67c3:660::/44, 我从中进一步划分出 2a14:67c3:666::/48\n作为该 IP 段的持有者, 我可以在 RIPE 数据库中随意修改该网段的 Whois 信息, 例如将 country 字段填写为 AQ (南极洲)\n这类注册信息会被部分 IP 数据库直接采纳, 作为 IP 定位判断的重要参考依据之一\n我将 2a14:67c3:666::/48 在德国法兰克福、美国洛杉矶、美国纽约、新加坡、日本东京五地的 VPS 上进行了 Anycast 广播。同时, 在五台服务器上绑定了相同的 IP 地址 2a14:67c3:666::1, 用户访问该 IP 时, 会自动连接到距离最近的服务器。\n说人话就是, 同一个 IP 地址, 可以同时出现在多个国家的不同服务器上。这时候探测节点的定位就会不准确了\n这最常见的应用场景就是公共 DNS 服务, 例如 1.1.1.1 和 8.8.8.8 它们的 IP 地址本身就是通过 Anycast 方式在全球范围内提供服务的。\n正是由于以下因素的共同存在:\nAnycast 等复杂的路由结构 IP 注册信息与实际部署位置不一致 不同数据库采用不同的数据来源和权重 在这种情况下, 很难通过某一种技术手段准确判断 IP 的真实位置。\n因此, 几乎所有主流 IP 数据库都允许公众或网络持有者主动提交 IP 定位修正请求。\n修改 IP 定位\r在理解了 IP 定位原理之后, 修改 IP 定位就会 从从容容, 游刃有余。先从注册信息入手, 再影响 IP 数据库, 最后避免被探测节点纠正。\n整体流程可以概括为三步:\n修改 RIPE 数据库中的注册信息 向各大 IP 数据库提交定位修正 (手动提交或通过 Geofeed 批量提交) 避免探测节点对定位进行修正 需要注意的是, 如果将 2a14:67c3:660::/44 整个地址段直接广播出去, 而没有在 RIPE 数据库中提前划分更小的子网, 这并不利于 IP 数据库进行精细化收录。整个地址段都会被统一归属为同一个国家, 后续再对 /48 子网进行单独定位修正, 生效会非常缓慢, 往往需要 1～2 个月\n如果你拥有该 IP 段在 RIPE 数据库中的编辑权限, 建议在广播之前, 先将对应子网的 country 字段修改为目标国家, 再进行广播, 否则更新定位会非常慢。\n分配最小子网\r在修改 IP 定位之前, 需要先将 IP 段拆分为最小广播单位\nIPv4: 最小广播子网为 /24 IPv6: 最小广播子网为 /48 如果你只获得了一个 /48 的 IPv6 网段, 则无法再继续拆分, 只能编辑 LIR 分配给你的网段。\n登录 RIPE Database 后, 依次进入 My Resources -\u0026gt; IPv6 -\u0026gt; Create assignment\n进入创建 inet6num 的表单, 按照如下方式填写\ninet6num: 2a14:67c3:660::/48 # 填写要分配的子网段 netname: AceSheep-Network-North-Korea # 网段名称, 取一个喜欢的名字 descr: AceSheep Network North Korea # (可选) 网段介绍 country: KP # 选择希望定位到的国家 / 地区 admin-c: JD12053-RIPE # 联系人对象, 选择之前创建的即可 tech-c: JD12053-RIPE # 联系人对象, 选择之前创建的即可 status: ASSIGNED # ASSIGNED 表示该地址段已分配 mnt-by: ACESHEEPTEST-MNT source: RIPE 完成创建后, 该子网在 RIPE 数据库中的注册信息, 将成为后续 IP 数据库定位判断的重要参考依据。\n单个提交修正\r在完成 RIPE 数据库修改并广播 IP 段后, 下一步就是向各大 IP 数据库提交定位更正请求。\n提交方式的选择\n修正数量 ≤ 5 个 IP / 网段\n👉 可以通过各数据库提供的 在线表单, 逐个提交 IP 定位修正。 修正数量较多 (\u0026gt; 5) 或经常变更\n👉 用在线表单简直是坐牢, 建议使用 Geofeed 方式进行批量提交 许多大型网络和运营商, 都会通过 Geofeed 来维护和发布 IP 地址的地理位置信息。\n如果你是搭配 Cloudflare WARP 使用, 其实只需要确保 IPInfo 的定位正确即可。Cloudflare 早期使用 MaxMind 作为定位服务商, 但已于 2025 年 6 月 11 号正式切换为 IPInfo\nIPinfo is the IP geolocation data provider of Cloudflare\n值得注意的是, MaxMind 的 Geofeed 功能目前仅针对付费用户开放。这也是 Cloudflare 最终放弃 MaxMind 转向 IPInfo 的重要原因之一\n常见 IP 数据库的修正入口\r可以向以下主流 IP 数据库提交定位修正请求\nMaxmind 使用最广泛的商业 IP 数据库之一, 许多网站和安全产品仍在使用, 但免费用户的修正生效较慢或者不予修正 IPInfo Cloudflare 当前使用的 IP 数据库, 对网络运营者提交的修正响应积极 Google 主要影响 Google 搜索与相关服务中的 IP 定位展示 不同 IP 数据库都有各自的维护流程, 部分数据库还会进行人工审核, 定位修正通常需要 3 天到 2 周 才会生效。\n我自己的测试中\nIPInfo 大约 1 周内接受并生效 Maxmind 两个月无任何回应 即使 IP 实际广播位置真实, 也不会主动修正 IP 定位 免费用户屁都不是 如果多次提交都没人受理再联系, 可以选择硬刚通过 MaxMind 的表单联系他们\n如果需要填写修正理由, 建议使用和业务影响有关的描述, 避免涉及匿名代理等敏感用途。例如 \u0026ldquo;因为 IP 定位错误, 我的客户无法访问部分地区限制的网站\u0026rdquo; (用英文写)\n以下是一段真实沟通案例, 仅供参考 (请自行组织措辞):\nHello,\nI am the network operator and owner of \u0026lt;ASN 号码\u0026gt;.\nI have noticed that my IPv6 address block \u0026lt;IPv6 网段\u0026gt; is incorrectly geolocated to the \u0026lt;国家\u0026gt; in the MaxMind database. This issue affects all /48 subnets under this /40 prefix, which are also being incorrectly localized. As a result, some of my customers are denied access to certain websites and services due to geolocation-based restrictions.\nI have submitted multiple data correction requests through the MaxMind correction form, but unfortunately have not received any response so far.\nTo ensure the accuracy of the authoritative data, I have already corrected the country information for this prefix in the RIPE NCC database. Other geolocation providers, such as ipinfo.io, have since synchronized this update and now show the correct location. However, MaxMind continues to locate this entire prefix (including all /48 subnets) in the \u0026lt;国家\u0026gt;.\nI would like to politely ask if you could let me know why my previous correction requests have not received a response, and whether there is any additional information required from my side to facilitate the update.\nThank you very much for your time and assistance. I would appreciate any guidance on how this issue can be resolved.\nKind regards,\nAceSheep\nNetwork Operator, \u0026lt;ASN 号码\u0026gt;\nGeofeed 批量提交修正\r对于拥有分布在全球各地 IP 地址的 ISP 来说, 一个一个手动提交 IP 定位修正请求显然不现实。因此, 业界制定了一种名为 Geofeed 的规范, 用于批量发布和维护 IP 地址的地理位置信息\n什么是 Geofeed\rGeofeed 是目前业界公认的 IP 地理位置共享标准, 相关规范在 RFC 8805 中有详细定义。\n原文参考: Publishing a Geofeed\nGeofeed 其实就是一个 CSV 文件, 格式如下\nnetwork, iso_country code, iso_region_code, city_name, postal_code 下面是一个有效且完整的 Geofeed 示例\n8.8.8.0/24,US,US-CA,Mountain View,\r2001:4860:4860::/46,US,US-CA,Mountain View, 这是目前最规范、也是各大 IP 数据库厂商普遍接受的 IP 定位信息发布方式。\n托管与提交 Geofeed\r你需要将 geofeed.csv 文件托管在一个可公开访问的 URL 上, 例如:\nhttps://example.com/geofeed.csv https://geofeed.example.com/geofeed.csv 托管位置可以是\n自己的网站 对外可访问的对象存储 甚至是托管在 Google Sheets 并导出为 CSV 完成后, 可以通过以下两种方式让 IP 数据库使用你的 Geofeed\n通过联系网站 Support, 将 Geofeed 链接提交给各大 IP 数据库厂商 在 RIPE 数据库的 inet6num (或 inetnum) 对象中填写 geofeed 字段, 让数据库厂商自动抓取并定期更新你的 IP 定位信息 于是, 你就可以拥有来自全球各地、稀奇古怪的 IP 地址, 通过挂探针的方式实现「点亮全球」\n防止 IP 被拉回\r需要注意的是, IP 定位修正并非一劳永逸。各大 IP 数据库仍会结合其他技术手段来判断 IP 的实际部署位置, 定位信息有可能被重新修正 (拉回)。\n常见的应对措施:\n在服务器防火墙中禁止 ICMP (Ping) 及常见端口的探测, 降低被主动扫描的概率 尽量避免直接使用服务器自身的 IPv6 地址访问网站 对外访问时优先使用通过 WARP 获得的 IPv4 地址 此外, 部分厂商 (例如 Google) 还可能结合手机的 Google Maps 的定位数据, 对 IP 归属地进行纠正, 这类行为已经超出了传统 IP 数据库和 Geofeed 所能控制的范围。\nPatience Is Key in Life\r在提交定位修正请求后, 通常需要等待几周, IP 数据库才会陆续完成更新。这时可以使用 iplark.com 这类工具, 批量查询各大 IP 数据库中你的 IP 定位信息, 确认数据是否已经生效。\n多数 IP 数据库也提供了在线查询方式, 例如 Maxmind、IPInfo。在等待期间, 可以通过这些工具手动查询, 用于确认当前 IP 的归属地状态。\n需要注意的是, Cloudflare 同步 IPInfo 数据本身也可能存在延迟, 通常在一到两周左右。如果在线查询显示 IPInfo 的定位已经正确, 但 Cloudflare 没更新的话, 只需要再耐心等待一段时间即可。\n检查 IP 在 Cloudflare 中的定位结果\r在前面的步骤中, 我们已经将 2a14:67c3:666::/48 的定位修改为 南极洲, 接下来需要确认 Cloudflare 是否已经同步了这一变更。\n可以通过 Cloudflare 提供的 /cdn-cgi/trace 接口进行测试 (任何接入 Cloudflare 的网站都支持该接口)\ncurl -s -6 --max-time 10 www.cloudflare.com/cdn-cgi/trace --interface 2a14:67c3:666::1 如果 IPInfo 中的定位已经修改完成, 但返回结果中仍显示 loc=US, 说明 Cloudflare 尚未同步最新的 IPInfo 数据, 此时仍需要继续等待。其中, colo=SEA 使用的是 IATA 机场代码\n此时返回结果如下\nfl=561f233 h=www.cloudflare.com ip=2a14:67c3:666::1 # 当前使用的 IPv6 地址 ts=1769417304.89 visit_scheme=http uag=curl/7.76.1 colo=SEA # 请求命中的 Cloudflare 数据中心为 SEA (西雅图-塔科马国际机场) sliver=none http=http/1.1 loc=US # Cloudflare 当前识别的 IP 定位为 US / 美国 tls=off sni=off warp=off # 当前未启用 WARP gateway=off rbi=off kex=none 又过了十几天后, Cloudflare WARP 使用的 IP 数据库终于完成了！更新相比 Cloudflare 的其他服务, WARP 的更新速度还慢了十天。此时, 距离 IPInfo 更新已经过去了半个月, 距离第一次提交 IP 定位修正请求过了一个月。\n再次执行相同的测试命令, 返回结果变为\nfl=20f788 h=www.cloudflare.com ip=2a14:67c3:666::1 # 当前使用的 IPv6 地址 ts=1769419002.274 visit_scheme=http uag=curl/7.76.1 colo=SEA sliver=none http=http/1.1 loc=AQ # Cloudflare 已正确识别该 IP 的定位为 AQ / 南极洲 tls=off sni=off warp=off # 当前未启用 WARP gateway=off rbi=off kex=none 当你直接使用修改定位后的 IP 访问 Cloudflare, 且 loc 字段返回正确结果时, 就可以进入下一步操作了。\n使用 WARP 获得对应地区 IPv4\r由于我们目前只有 IPv6, 因此无法访问大部分 IPv4-only 的网站。这时就需要借助 Cloudflare WARP 来帮忙了。\nWARP 有一个非常重要的特性: 它会根据用户的连接 IP 来分配对应归属地的 IP, 而不是按照 WARP 接入节点所在的地理位置来分配。例如, 大陆用户连接 WARP 时, 实际接入的是美国节点, 但最终分配到的 IP 定位在大陆。\n正是利用这一特性, 我们可以用已经被修改为南极洲定位的 IPv6, 通过 WARP 获得一个定位同样在南极洲的 IPv4\nWARP 会根据当前 IPv6 的定位, 为我们分配一组对应地区的 IPv4 + IPv6 地址。其中, WARP 分配的 IPv4 地址不仅可以用于访问 IPv4-only 的网站, 其定位信息还由 Cloudflare 统一维护, 在各大 IP 数据库中的准确性都非常高, 比手动向多个数据库提交修正请求要省心得多。\n获取 WARP 连接配置\r需要注意的是, 如果直接通过 Linux 内核提供的 WireGuard 连接 WARP 会修改系统的默认路由表, 将所有流量进行全局代理, 而这并不是我们当前的需求。\n因此我们不使用内核 WireGuard, 而是通过 ViRb3/wgcf 获取 Cloudflare WARP 的配置文件, 再使用 whyvl/wireproxy 将 WARP 导出为一个 SOCKS5 代理。这种方式可以避免修改系统路由表, 也更方便后续进行 IP 定位验证与测试。\n后续, 你也可以使用 Xray 实现 WireGuard 出站, 并结合自定义路由规则进行精细化分流。\n如果你需要使用 WARP+, Telegram 上有些频道会分享免费的 WARP+ 密钥, 例如 Warp Plus\n使用以下命令快速获取 WARP 的连接配置\nmkdir ~/wgcf cd ~/wgcf wget -O wgcf https://github.com/ViRb3/wgcf/releases/download/v2.2.30/wgcf_2.2.30_linux_amd64 chmod u+x wgcf alias wgcf=~/wgcf/wgcf wgcf register --accept-tos wgcf generate wgcf status cat wgcf-profile.conf 生成的配置文件如下\n[Interface] PrivateKey = yN0tzPQtrM/tlUmzAceSheepRTWGp/JF6zlL4/kQ02I= Address = 172.16.0.2/32, 2606:4700:110:8c98:cefb:abcd:1234:498c/128 DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111, 2606:4700:4700::1001 MTU = 1280 [Peer] PublicKey = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = engage.cloudflareclient.com:2408 接下来需要修改连接的 Endpoint, 手动指定为 IPv6 地址, 以避免域名解析到 IPv4 地址。\n由于我们当前是通过 IPv6 出口 连接 WARP, 如果 Endpoint 解析为 IPv4 地址, 将导致连接无法建立, 因此必须显式指定 WARP 的 IPv6 Endpoint\n[2606:4700:d0::a29f:c001]:2408 安装并配置 WireProxy\r这里我们需要使用修改版的 xiahuaijia/wireproxy。该版本支持在多 IP 的服务器上手动指定出站 IP, 这样就可以使用我们通过 BGP 广播并绑定在 dummy1 网卡上的 IPv6 地址 进行测试。\n通过这种方式, WARP 的连接将使用南极洲定位的 IPv6 作为出口, 从而获得对应地区的 WARP IPv4/IPv6 地址。\n下载支持多出站 IP 的修改版 wireproxy\nwget https://github.com/xiahuaijia/wireproxy/releases/download/v1.1.0/wireproxy_1.1.0_linux_amd64.tar.gz tar xzvf wireproxy_1.1.0_linux_amd64.tar.gz 编辑配置文件\nvim wireproxy.conf 内容如下\nWGConfig = wgcf-profile.conf [Socks5] BindAddress = 127.0.0.1:1080 启动 wireproxy, 并指定南极洲定位的 IPv6 作为出站 IP\n./wireproxy --config wireproxy.conf --interface 2a14:67c3:666::1 验证 IP 定位结果\r完成 WARP 配置后, 我们来实际测试一下获取到的是不是 南极洲 (AQ) 的 IPv4 地址\n使用 IPInfo 验证\r通过 SOCKS5 代理访问 IPInfo\ncurl -s --max-time 10 -x socks5://127.0.0.1:1080 ipinfo.io 返回结果如下\n{ \u0026#34;ip\u0026#34;: \u0026#34;104.28.244.152\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;McMurdo Station\u0026#34;, \u0026#34;region\u0026#34;: \u0026#34;Antarctica\u0026#34;, \u0026#34;country\u0026#34;: \u0026#34;AQ\u0026#34;, \u0026#34;loc\u0026#34;: \u0026#34;-77.8463,166.6682\u0026#34;, \u0026#34;org\u0026#34;: \u0026#34;AS13335 Cloudflare, Inc.\u0026#34;, \u0026#34;timezone\u0026#34;: \u0026#34;Antarctica/McMurdo\u0026#34;, \u0026#34;readme\u0026#34;: \u0026#34;https://ipinfo.io/missingauth\u0026#34; } 可以看到, 此时已经成功获得由 WARP 分配的 南极洲 IPv4 地址\n使用 Cloudflare 验证\r通过 Cloudflare 的 /cdn-cgi/trace 接口测试一下\ncurl -s --max-time 10 -x socks5://127.0.0.1:1080 www.cloudflare.com/cdn-cgi/trace 关键字段如下\nip=104.28.212.152 colo=SEA loc=AQ warp=on 其中 loc=AQ 表示 Cloudflare 已正确识别该 IP 的定位为 南极洲, 且当前流量确实通过 WARP\n使用 B 站接口验证\r最后, 使用 B 站供的 IP 查询接口进行验证\ncurl -s --max-time 10 -x socks5://127.0.0.1:1080 https://api.live.bilibili.com/ip_service/v1/ip_service/get_ip_addr 返回结果\n{ \u0026#34;code\u0026#34;: 0, \u0026#34;msg\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;message\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;data\u0026#34;: { \u0026#34;addr\u0026#34;: \u0026#34;104.28.212.152\u0026#34;, \u0026#34;country\u0026#34;: \u0026#34;南极洲\u0026#34;, \u0026#34;province\u0026#34;: \u0026#34;南极洲\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;isp\u0026#34;: \u0026#34;cloudflare.com\u0026#34;, \u0026#34;latitude\u0026#34;: \u0026#34;-81.5\u0026#34;, \u0026#34;longitude\u0026#34;: \u0026#34;0\u0026#34; } } 可以看到, 不同平台和数据库对 WARP 分配的 IPv4 地址给出了高度一致的定位结果\n至此, 已经成功获得了 南极洲定位的 WARP IPv4 地址\nThe End\r此时只需在这台 VPS 上配置一个代理, 你就可以使用南极洲的 IP 到各大网站上炫耀了\n最后附上一张实际在 B 站评论区显示定位的截图, 作为成果展示。\n终于啊终于……本文从 2024 年 10 月开始筹划, 到最终完全生效, 期间经历了多次修正与漫长等待, 前后历时 15 个月, 终于在反复折腾中圆满结束。\n原文\n教你如何获得一个南极ip\n自己在家开运营商 Part.5 - 如何得到一个朝鲜/南极洲 VPS (新概念点亮全球)\nDIY任意地区流媒体解锁IPv6 - 图片备份\n","date":"2026-01-16T22:31:09+08:00","permalink":"https://blog.acesheep.com/p/bgplayer-beginner-guide-how-to-get-north-korea-or-antarctica-ip/","title":"BGPlayer 从零开始速成指北 - 如何获得一个朝鲜/南极洲 IP"},{"content":"blackbox_exporter\rblackbox_exporter 是 Prometheus 官方提供的黑盒监控组件, 用于通过 HTTP / HTTPS / TCP / ICMP / DNS 等方式, 对外部服务和网络连通性进行探测。常用于 API 接口可用性检测、端口连通性测试以及三网 (电信 / 联通 / 移动) 延迟监测。\n创建普通用户\r使用独立普通用户运行 blackbox_exporter\nuseradd -M -s /sbin/nologin blackbox 建立专属文件夹\r创建安装目录\nmkdir -p /opt/blackbox 下载安装 blackbox\rblackbox_exporter 0.28.0 版本存在严重缺陷: 无论探测结果是否符合预期, 都会以 ERROR 级别记录探测失败日志, 且无法关闭该错误日志, 从而产生大量无效日志, 不仅占用磁盘空间, 还会对告警判断造成干扰。\n相关问题说明: Version 0.28.0 always logs probe failures (as \u0026lsquo;ERROR\u0026rsquo; level failures) with no way to turn it off\n不建议在生产环境中使用 0.28.0 版本, 建议选择 0.27.0 或官方已明确修复该问题的后续版本。\n# 下载 wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.27.0/blackbox_exporter-0.27.0.linux-amd64.tar.gz # 解压文件 tar zxvf blackbox_exporter-0.27.0.linux-amd64.tar.gz # 拷贝文件到安装目录 cd blackbox_exporter-0.27.0.linux-amd64 cp blackbox_exporter /opt/blackbox/ cp blackbox.yml /opt/blackbox/ 设置文件权限\rchown -R blackbox:blackbox /opt/blackbox chmod 550 /opt/blackbox/blackbox_exporter chmod 440 /opt/blackbox/blackbox.yml 如果系统启用了 SELinux, 需额外设置上下文\nsemanage fcontext -a -t bin_t \u0026#34;/opt/blackbox/blackbox_exporter\u0026#34; semanage fcontext -a -t etc_t \u0026#34;/opt/blackbox/blackbox.yml\u0026#34; restorecon -Rv /opt/blackbox 创建 systemd 服务\r编辑服务文件\nvim /etc/systemd/system/blackbox.service 写入以下内容\n[Unit] Description=Blackbox Exporter Service After=network.target [Service] User=blackbox Group=blackbox WorkingDirectory=/opt/blackbox ExecStart=/opt/blackbox/blackbox_exporter \\ --config.file=blackbox.yml \\ --web.listen-address=127.0.0.1:59115 Restart=always RestartSec=5 # Privileges NoNewPrivileges=true AmbientCapabilities=CAP_NET_RAW CapabilityBoundingSet=CAP_NET_RAW # Filesystem ProtectSystem=strict ProtectHome=true ReadOnlyPaths=/opt/blackbox # Kernel \u0026amp; devices ProtectKernelTunables=true ProtectKernelModules=true ProtectKernelLogs=true ProtectControlGroups=true PrivateDevices=true PrivateTmp=true # Memory \u0026amp; process hardening MemoryDenyWriteExecute=true RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX [Install] WantedBy=multi-user.target 启动与管理服务\nsystemctl daemon-reload systemctl start blackbox systemctl enable blackbox systemctl status blackbox # 重启与日志查看 systemctl restart blackbox journalctl -f --output cat -u blackbox 手动启动 (调试用)\r在调试或排错时, 可直接前台启动\n./blackbox_exporter --config.file=blackbox.yml --web.listen-address=127.0.0.1:59115 功能测试\r通过 ICMP 探测验证 blackbox_exporter 是否正常工作\ncurl \u0026#34;http://127.0.0.1:59115/probe?module=icmp\u0026amp;target=1.1.1.1\u0026#34; 返回结果中 probe_success 1, 说明探测正常\nnode_exporter\rnode_exporter 用于采集主机的运行指标, 如 CPU、内存、磁盘、网络等, 是 Prometheus 监控体系中最基础、最常用的节点指标采集组件。\n创建普通用户\r使用独立普通用户运行 node_exporter\nuseradd -M -s /sbin/nologin promnode 建立专属文件夹\r创建安装目录及 textfile collector 使用的目录\nmkdir -p /opt/promnode/textfile 下载安装 node_exporter\r# 下载 wget https://github.com/prometheus/node_exporter/releases/download/v1.10.2/node_exporter-1.10.2.linux-amd64.tar.gz # 解压文件 tar zxvf node_exporter-1.10.2.linux-amd64.tar.gz # 拷贝文件到安装目录 cd node_exporter-1.10.2.linux-amd64 cp node_exporter /opt/promnode/ 生成 textfile collector 指标, 用于记录主机的默认出口网卡名称, 以便在 Prometheus 中筛选和统计默认网卡的流量相关指标\necho \u0026#34;default_interface{device=\\\u0026#34;$(ip route | grep default | awk \u0026#39;{print $5}\u0026#39;)\\\u0026#34;} 1\u0026#34; \u0026gt; /opt/promnode/textfile/default_interface.prom 设置文件权限\rchown -R promnode:promnode /opt/promnode chmod 750 /opt/promnode/node_exporter 如果系统启用了 SELinux, 需额外设置上下文\nsemanage fcontext -a -t bin_t \u0026#34;/opt/promnode/node_exporter\u0026#34; restorecon -Rv /opt/promnode 创建 systemd 服务\r编辑服务文件\nvim /etc/systemd/system/node.service 写入以下内容\n[Unit] Description=Node Exporter Service After=network.target [Service] User=promnode Group=promnode WorkingDirectory=/opt/promnode ExecStart=/opt/promnode/node_exporter \\ --web.disable-exporter-metrics \\ --web.listen-address=127.0.0.1:59100 \\ --collector.disable-defaults \\ --collector.stat \\ --collector.cpu \\ --collector.filesystem \\ --collector.filesystem.fs-types-exclude=\u0026#39;^(tmpfs)$\u0026#39; \\ --collector.netdev \\ --collector.netdev.device-exclude=\u0026#39;lo\u0026#39; \\ --collector.textfile \\ --collector.textfile.directory=textfile Restart=always RestartSec=5 # Privileges NoNewPrivileges=true # Filesystem ProtectHome=true ReadWritePaths=/opt/promnode/textfile ReadOnlyPaths=/opt/promnode # Kernel \u0026amp; devices ProtectKernelTunables=true ProtectControlGroups=true PrivateDevices=true # Memory \u0026amp; process hardening MemoryDenyWriteExecute=true RestrictAddressFamilies=AF_INET AF_NETLINK AF_PACKET [Install] WantedBy=multi-user.target 启动与管理服务\nsystemctl daemon-reload systemctl start node systemctl enable node systemctl status node # 重启与日志查看 systemctl restart node journalctl -f --output cat -u node 手动启动 (调试用)\r在调试或排错时, 可直接前台启动\n./node_exporter --web.disable-exporter-metrics --web.listen-address=127.0.0.1:59100 --collector.disable-defaults --collector.stat --collector.cpu --collector.filesystem --collector.filesystem.fs-types-exclude=\u0026#39;^(tmpfs)$\u0026#39; --collector.netdev --collector.netdev.device-exclude=\u0026#39;lo\u0026#39; --collector.textfile --collector.textfile.directory=textfile vmagent\rvmagent 是 VictoriaMetrics 提供的轻量级指标采集与转发组件, 功能上类似于 Prometheus 的 scrape + remote_write 组合, 但在资源占用、可靠性和高并发场景下表现更优。\n本部署方案中, vmagent 采用 主动上报 (remote_write) 模式:\n本地定期抓取 node_exporter、blackbox_exporter 等指标 将数据主动推送到远端 Prometheus 接口 当网络短暂中断时, 数据会先缓存在本地磁盘, 网络恢复后自动补传, 避免因网络抖动导致指标丢失 该模式非常适合服务器分布在不同地域、网络质量不稳定或跨公网部署的监控场景。\n创建普通用户\r使用独立普通用户运行 vmagent\nuseradd -M -s /sbin/nologin vmagent 建立专属文件夹\r创建安装目录及缓存目录\nmkdir -p /opt/vmagent/cache 下载安装 vmagent\r# 下载 wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.133.0/vmutils-linux-amd64-v1.133.0.tar.gz # 创建临时文件夹 mkdir /tmp/vm_temp # 解压文件 tar -C /tmp/vm_temp -zxvf vmutils-linux-amd64-v1.133.0.tar.gz # 拷贝文件到安装目录 cp /tmp/vm_temp/vmagent-prod /opt/vmagent/vmagent # 清理临时文件夹 rm -rf /tmp/vm_temp 编辑 scrape.yml 配置文件\r配置 vmagent 的指标采集规则, 用于定义需要抓取的目标和采集方式。\nvim /opt/vmagent/scrape.yml 写入以下内容, 用于采集主机的运行指标, 数据来源为 node_exporter。如有需要, 也可以在此基础上添加 blackbox_exporter 的三网 TCP 或 ICMP 延迟监测采集任务。\nscrape_configs: - job_name: \u0026#34;linux_servers\u0026#34; scrape_interval: 10s scrape_timeout: 5s static_configs: - targets: [\u0026#34;127.0.0.1:59100\u0026#34;] (可选) remote_write 安全配置\r配置 vmagent 向远端 Prometheus / VictoriaMetrics 接口进行 remote_write 时的安全认证方式。可根据实际环境选择 mTLS、用户名密码 (Basic Auth), 也可以同时启用。\n设置 mTLS\r启用 mTLS (双向 TLS) 后, vmagent 将使用客户端证书与远端服务器进行双向身份验证, 适用于对通信安全性要求较高的场景。\n在启用前需注意以下事项\n需提前准备好客户端证书 (vmagent.crt / vmagent.key), 可使用自签证书, 并放置在 /opt/vmagent/ 目录下 远端服务器需已正确配置, 并信任用于签发客户端证书的自签 Root CA, 否则连接将无法建立 chmod 440 /opt/vmagent/vmagent.crt chmod 440 /opt/vmagent/vmagent.key 启用 mTLS 后, vmagent 启动时需额外指定客户端证书参数 (见下文说明)\n设置用户名密码验证 (Basic Auth)\r当远端写入接口启用了 HTTP Basic Authentication 时, 可通过文件方式为 vmagent 提供认证信息, 避免在命令行或 systemd 文件中明文暴露密码。\n用户名可直接写在启动参数中, 密码推荐通过 passwordFile 方式读取\necho \u0026#39;your_password_here\u0026#39; \u0026gt; /opt/vmagent/remote_pass chmod 640 /opt/vmagent/remote_pass chown root:vmagent /opt/vmagent/remote_pass 设置文件权限\r创建空环境变量文件\ntouch /opt/vmagent/env 设置权限\nchown -R vmagent:vmagent /opt/vmagent chmod 750 /opt/vmagent/vmagent chmod 750 /opt/vmagent/cache chmod 640 /opt/vmagent/scrape.yml chown root:vmagent /opt/vmagent/env chmod 640 /opt/vmagent/env 如果系统启用了 SELinux, 需额外设置上下文\nsemanage fcontext -a -t bin_t \u0026#34;/opt/vmagent/vmagent\u0026#34; semanage fcontext -a -t etc_t \u0026#34;/opt/vmagent/scrape.yml\u0026#34; semanage fcontext -a -t etc_t \u0026#34;/opt/vmagent/env\u0026#34; restorecon -Rv /opt/vmagent 创建 systemd 服务\r编辑环境变量\nvim /opt/vmagent/env 填入远端采集服务器地址以及用于区分节点的服务器标签\nVM_REMOTE_URL=https://status.acesheep.com/collect/target VM_SERVER_LABEL=1.1.1.1 编辑服务文件\nvim /etc/systemd/system/vmagent.service 写入以下内容\n[Unit] Description=vmagent - VictoriaMetrics data collector After=network-online.target Wants=network-online.target [Service] User=vmagent Group=vmagent WorkingDirectory=/opt/vmagent EnvironmentFile=/opt/vmagent/env ExecStart=/opt/vmagent/vmagent \\ -promscrape.config=scrape.yml \\ -httpListenAddr=\u0026#39;\u0026#39; \\ -remoteWrite.forcePromProto \\ -remoteWrite.maxDiskUsagePerURL=50MB \\ -remoteWrite.tmpDataPath=cache \\ -remoteWrite.label=server=${VM_SERVER_LABEL} \\ -remoteWrite.url=${VM_REMOTE_URL} \\ -remoteWrite.queues=10 Restart=always RestartSec=5 # Privileges NoNewPrivileges=true # Filesystem ProtectSystem=strict ProtectHome=true ReadWritePaths=/opt/vmagent/cache # Kernel \u0026amp; devices PrivateTmp=true [Install] WantedBy=multi-user.target (可选) 启用 mTLS 时, 需要在 ExecStart 中添加以下参数, 用于指定客户端证书与私钥\n-remoteWrite.tlsCertFile=vmagent.crt \\ -remoteWrite.tlsKeyFile=vmagent.key (可选) 远端写入接口启用了 Basic Auth 时, 可在 ExecStart 中追加以下参数\n-remoteWrite.basicAuth.username=your_user \\ -remoteWrite.basicAuth.passwordFile=remote_pass 启动与管理服务\nsystemctl daemon-reload systemctl start vmagent systemctl enable vmagent systemctl status vmagent # 重启与日志查看 systemctl restart vmagent journalctl -f --output cat -u vmagent 手动启动 (调试用)\r在调试或排错时, 可直接前台启动\n./vmagent -promscrape.config=scrape.yml -httpListenAddr=\u0026#39;\u0026#39; -remoteWrite.forcePromProto -remoteWrite.maxDiskUsagePerURL=100MB -remoteWrite.tmpDataPath=cache -remoteWrite.label=\u0026#39;server=1.1.1.1\u0026#39; -remoteWrite.url=http://11.22.33.44:9090/api/v1/write -remoteWrite.queues=10 -remoteWrite.basicAuth.username=your_user -remoteWrite.basicAuth.passwordFile=remote_pass 一键安装脚本\r通过一条命令即可完成整个安装流程, 可自动完成 node_exporter 和 blackbox_exporter 的下载、安装、权限设置以及 systemd 服务配置, 适合在大规模服务器环境中快速部署并上线监控。\nbash \u0026lt;(curl -sL shell.puka.cc/tz) --node bash \u0026lt;(curl -sL shell.puka.cc/tz) --blackbox bash \u0026lt;(curl -sL shell.puka.cc/tz) --vmagent ","date":"2026-01-13T23:22:16+08:00","permalink":"https://blog.acesheep.com/p/prometheus-node-metrics-blackbox-node-exporter-vmagent/","title":"Prometheus 采集节点指标: blackbox_exporter、node_exporter 与 vmagent"},{"content":"Grafana 12.3.1\rGrafana 是一款流行的可视化监控平台, 支持通过 iframe 的方式将仪表盘嵌入到网页中, 常用于监控数据的展示与分析。\n安装 Grafana\r官方为 RHEL / Rocky 系列提供了 RPM 仓库, 通过仓库方式安装不仅流程简单, 也便于后续的版本升级和维护。完整说明可参考官方文档\n首先, 需要在系统中添加 Grafana 的 yum 仓库配置。创建仓库文件\nvim /etc/yum.repos.d/grafana.repo 填入以下内容\n[grafana] name=grafana baseurl=https://rpm.grafana.com repo_gpgcheck=1 enabled=1 gpgcheck=1 gpgkey=https://rpm.grafana.com/gpg.key sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt 使用 yum 安装 Grafana\nyum install grafana 配置 Grafana\r在正式对外提供访问之前, 需要对 Grafana 做一些基础配置, 并不直接暴露到公网, 而是通过 Nginx 转发请求, 因此这里主要需要调整监听地址、对外访问的域名以及子路径配置, 同时启用匿名用户访问权限。\n编辑 Grafana 配置文件\nvim /etc/grafana/grafana.ini Server 配置\n#################################### Server #################################### [server] # Protocol (http, https, h2, socket) protocol = http # The ip address to bind to, empty will bind to all interfaces http_addr = 127.0.0.1 # The http port to use http_port = 53000 # The public facing domain name used to access grafana from a browser domain = status.acesheep.com # The full public facing url you use in browser, used for redirects and emails # If you use reverse proxy and sub path specify full url (with sub path) root_url = https://%(domain)s/grafana/ # Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. serve_from_sub_path = true 匿名访问配置\n#################################### Anonymous Auth ###################### [auth.anonymous] # enable anonymous access enabled = true # specify organization name that should be used for unauthenticated users org_name = Main Org. # specify role for unauthenticated users org_role = Viewer # mask the Grafana version number for unauthenticated users hide_version = true # number of devices in total device_limit = 10 启动 Grafana\r安装完成好之后, 可以通过 systemd 启动服务, 确保服务器重启后 Grafana 能够自动恢复运行。\nsystemctl start grafana-server systemctl enable grafana-server systemctl status grafana-server 验证 Grafana 是否正常运行\r在配置反向代理之前, 可以先通过直接访问 Grafana 端口的方式, 确认是否已经正常运行。这里仅作为临时验证使用, 生产环境中不建议暴露该端口。\n临时放行 Grafana 的默认端口\nfirewall-cmd --add-port=3000/tcp 在浏览器输入\nhttp://你的服务器IP:3000 如果能够看到 Grafana 的 Web 界面, 说明服务运行正常。\nGrafana 默认的登录用户名和密码为 admin, 首次登录后系统会提示修改初始密码。完成验证后, 即可关闭该端口, 并通过 Nginx 反向代理对外提供访问。\nPrometheus 3.8.1\rPrometheus 是一款时序数据库与监控系统, 主要负责采集、存储和查询各类运行指标, 通常与 Grafana 搭配使用。\n下载 Prometheus\r从 Prometheus 官网获取最新版本的链接\nwget https://github.com/prometheus/prometheus/releases/download/v3.8.1/prometheus-3.8.1.linux-amd64.tar.gz 创建系统运行用户\r不建议使用 root 用户运行 Prometheus, 创建一个专用的普通用户\nuseradd -M -s /sbin/nologin prometheus 建立专属文件夹\r建立独立的目录, 并完成解压与权限设置\n# 创建目录 mkdir -p /opt/prometheus mkdir -p /opt/prometheus/data # 解压程序文件 tar -xvf prometheus-3.8.1.linux-amd64.tar.gz -C /opt/prometheus --strip-components=1 # 设置权限: prometheus 用户需要读写权限 chown -R prometheus:prometheus /opt/prometheus # 移除 other 用户的权限 find /opt/prometheus -type f -exec chmod o-rx {} + 配置 Prometheus\rPrometheus 通过配置文件来定义指标的抓取规则。本例主要用于采集 Chihaya Tracker 对外暴露的监控指标, 其他配置项可参考官方文档\n如果仅用于验证 Prometheus 是否能够正常启动, 也可以先创建一个空的配置文件\ntouch /opt/prometheus/prometheus.yml 在需要采集 Chihaya 的运行指标时, 可以在配置文件中加入以下抓取规则配置\nscrape_configs: - job_name: chihaya_tracker scrape_interval: 5s scrape_timeout: 5s metrics_path: /metrics scheme: https basic_auth: username: tracker.acesheep.com password: blog.acesheep.com static_configs: - targets: [\u0026#34;tracker.acesheep.com\u0026#34;] labels: app: chihaya 上述配置通过 basic_auth 进行访问认证, 并明确了抓取路径、协议和目标地址。可根据实际部署环境, 对抓取频率和目标列表进行相应调整。\n创建 systemd 服务\r创建服务文件, 用于管理进程并配置运行参数与安全限制。\nvim /etc/systemd/system/prometheus.service 内容如下\n[Unit] Description=Prometheus Wants=network-online.target After=network-online.target [Service] User=prometheus Group=prometheus Type=simple WorkingDirectory=/opt/prometheus ExecStart=/opt/prometheus/prometheus \\ --config.file=prometheus.yml \\ --web.listen-address=127.0.0.1:59090 \\ --web.enable-remote-write-receiver \\ --web.enable-lifecycle \\ --web.enable-admin-api Restart=always RestartSec=5 # Privileges NoNewPrivileges=true # Filesystem ProtectSystem=strict ProtectHome=true ReadWritePaths=/opt/prometheus/data # Kernel \u0026amp; devices ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true PrivateTmp=true # Memory \u0026amp; process hardening RestrictAddressFamilies=AF_INET AF_INET6 SystemCallArchitectures=native SystemCallFilter=@system-service [Install] WantedBy=multi-user.target 加载并启动服务\nsystemctl daemon-reload systemctl enable --now prometheus systemctl status prometheus # 重启与日志查看 systemctl restart prometheus journalctl -f --output cat -u prometheus 验证 Prometheus 是否正常运行\rPrometheus 监听在本地地址 127.0.0.1:59090, 不直接对外提供访问, 因此可以通过检查端口监听状态来验证服务是否正常运行。\n使用以下命令查看 Prometheus 是否已成功监听对应端口\nnetstat -nlptu | grep 59090 如果输出中可以看到 Prometheus 进程正在监听 127.0.0.1:59090, 说明服务已正常启动, 配置也已生效。\n在需要通过浏览器访问 Prometheus Web UI 时, 可通过 Nginx 或 SSH 端口转发进行访问, 生产环境中不建议直接暴露该端口。\nPrometheus 维护命令\r在日常运维过程中常用的查询、配置热加载以及数据清理相关操作, 便于排查问题和维护存储空间。\n查询当前已收集的指标\r用于查看 Prometheus 中所有已存在的时间序列指标名称\n{__name__!=\u0026#34;\u0026#34;} 重载 Prometheus 配置文件\r在不重启 Prometheus 进程的情况下, 重新加载 prometheus.yml 配置文件。Prometheus 启动时需开启 --web.enable-lifecycle 参数\ncurl -X POST http://127.0.0.1:59090/-/reload 删除匹配的指标\r删除指定匹配条件下的所有时间序列数据。Prometheus 启动时需开启 --web.enable-admin-api 参数\n# 该操作只会标记数据为 \u0026#34;已删除\u0026#34; (生成 tombstones), 并不会立即释放磁盘空间 curl -X POST -g \u0026#39;http://127.0.0.1:59090/api/v1/admin/tsdb/delete_series?match[]={app=\u0026#34;chihaya\u0026#34;}\u0026#39; # 清理磁盘上的旧数据 (墓碑清理) # 在执行 delete_series 后, 手动清理 tombstones, 真正释放磁盘空间 curl -X POST http://127.0.0.1:59090/api/v1/admin/tsdb/clean_tombstones nginx 反向代理\r通过 Nginx 将 Grafana 与 Prometheus 的接口安全地暴露到公网, 并提供 HTTPS 与路径隔离。\n配置说明\n提供 TLS (HTTPS) 支持, 并启用 HTTP/2 Grafana 反向代理 Prometheus Remote Write 接口 为 Grafana 和 Prometheus 分别配置独立日志, 便于排错与审计 server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name status.acesheep.com; # SSL 相关配置 (已省略) # 日志相关配置 (已省略) location / { try_files $uri /index.html; } location /grafana/ { access_log /var/log/nginx/grafana.log main; error_log /var/log/nginx/grafana.error; proxy_pass http://127.0.0.1:53000/grafana/; # 标准 Header 传递 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; # 支持 WebSocket (Grafana Live 功能需要) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \u0026#34;upgrade\u0026#34;; # 避免文件上传或大数据量请求被 Nginx 拦截 client_max_body_size 10m; } location = /collect/target { access_log /var/log/nginx/prometheus_remote_write.log main; error_log /var/log/nginx/prometheus_remote_write.error; limit_except POST { deny all; } proxy_pass http://127.0.0.1:59090/api/v1/write; 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_buffering off; proxy_request_buffering off; proxy_cache off; add_header Cache-Control \u0026#34;no-store, no-cache, must-revalidate, proxy-revalidate\u0026#34;; add_header Pragma \u0026#34;no-cache\u0026#34;; add_header Expires \u0026#34;0\u0026#34;; } } 至此, Grafana、Prometheus 及 Nginx 反向代理已完成部署。后续只需根据实际需求完善监控数据采集以及仪表盘配置即可。\n","date":"2026-01-05T15:24:51+08:00","permalink":"https://blog.acesheep.com/p/rocky-9-monitoring-with-grafana-prometheus/","title":"Rocky 9 搭建 Grafana + Prometheus 可视化监控"},{"content":"虽然可以直接使用公共 Tracker 服务器, 但一旦这些公共服务关闭或失效, 就需要通知所有用户手动更新 Tracker 地址, 维护成本非常高。因此, 搭建一个私有 Tracker 服务器是更稳妥的选择。\n本次搭建的目标主要有:\n在内部分享文件, 不希望被第三方 Tracker 统计或记录 避免公共 Tracker 被滥用, 影响正常上传与带宽资源 目前, 许多公开 Tracker 已被大量 PCDN 滥用。这些节点通常使用魔改客户端, 通过伪造下载行为来对冲上传量, 以规避因上传远大于下载流量而被运营商限速或封禁宽带。\n只要开启做种, 上传带宽几乎会被持续占满, 对方满速吸血, 还会伪造下载进度, 导致服务端和普通用户都难以进行有效识别与防御。如今, 不少公开种子在连接公开 Tracker 后, 都会出现长期满速上传的情况。\n这种行为对私有分享和小规模分发场景极为不友好, 也正是选择放弃公开 Tracker、转而自建私有 Tracker 的重要原因之一。\nTracker 服务端方案选择\r目前主流的 Tracker 服务端实现主要有三种:\nOpenTracker (C 语言) Ocelot (C++) Chihaya (Go 语言) 在实际使用过程中, OpenTracker 暴露出不少维护和扩展方面的问题\n无法正确识别由 Nginx 反向代理传递的 X-Real-IP 和 X-Forwarded-For 头 每次新增或调整功能, 都需要修改编译参数并重新编译, 维护成本较高 构建体系非常陈旧, 甚至仍依赖 CVS 才能获取核心网络库 libowfat 综合可维护性、扩展性等因素考虑, 在 2026 年, 选择 Chihaya 作为 Tracker 服务端更加合理。\n配置 Go 语言环境\r虽然 Chihaya 的 Releases 页面中有几个版本, 但整个社区普遍使用 HEAD 分支自行构建, 项目组懒得自己定时发布版本。\n由于 Chihaya 使用 Go 编写, 首先需要在系统中配置 Go 编译环境。\n安装 Go\r下载并解压 Go 官方发行版\nwget https://go.dev/dl/go1.25.5.linux-amd64.tar.gz rm -rf /usr/local/go tar -C /usr/local -xzf go1.25.5.linux-amd64.tar.gz 配置环境变量\r将 Go 的二进制路径加入系统 PATH, 这里采用全局方式配置。\n创建 profile 脚本\necho \u0026#39;export PATH=$PATH:/usr/local/go/bin\u0026#39; \u0026gt; /etc/profile.d/go.sh 使配置立即生效\nsource /etc/profile.d/go.sh 验证安装\r运行以下命令检查是否安装成功\ngo version 如果看到类似 go version go1.25.5 linux/amd64 的输出, 说明安装成功！\n手动安装 Chihaya\r编译 Chihaya\rChihaya 的编译过程很简单\ngit clone https://github.com/chihaya/chihaya.git cd chihaya go build ./cmd/chihaya 如果希望得到更小的二进制文件, 可以使用以下方式\ngo build -trimpath -ldflags \u0026#34;-s -w\u0026#34; ./cmd/chihaya 编译完成后, 会生成一个名为 chihaya 的可执行文件\n可以通过以下命令验证程序是否正常\n./chihaya --help 创建系统运行用户\r不建议直接使用 root 运行服务, 应创建独立的用户运行 Chihaya\n该用户不允许登录, 也不自动创建家目录, 适合用于后台服务\nuseradd -M -s /sbin/nologin chihaya 建立专属文件夹\r遵循 FHS (Filesystem Hierarchy Standard) 与 SELinux 安全策略, 手动安装的第三方服务推荐放置在 /opt 目录下\n# 创建目录 mkdir -p /opt/chihaya # 将二进制文件和配置放入其中 cp chihaya /opt/chihaya/ cp dist/example_config.yaml /opt/chihaya/chihaya.yaml # 设置权限: chihaya 用户需要读取权限, 如果程序需要写日志则需要写权限 chown -R chihaya:chihaya /opt/chihaya # 先把所有东西设为目录 755, 文件 644 的基准 (常用技巧) chmod -R 644 /opt/chihaya find /opt/chihaya -type d -exec chmod 755 {} + # 单独给二进制程序增加执行权限 chmod 750 /opt/chihaya/chihaya # 限制配置文件的访问, 仅限 chihaya 用户和组 chmod 640 /opt/chihaya/chihaya.yaml 配置 Chihaya\r打开并根据需要编辑其中的配置选项, 相关配置都有英文说明\nvim /opt/chihaya/chihaya.yaml 配置要点\n删除 UDP 相关配置 (仅使用 HTTP) 监听地址使用内网 127.0.0.1, 由反向代理对外提供服务 默认已支持 IPv4 / IPv6 双栈, 其余配置可保持默认 配置 SELinux 规则\r在 Rocky 9 中, 如果可执行文件不在 /usr/bin 等标准系统路径下, SELinux 默认会阻止 systemd 直接执行该二进制文件。\n因此, 需要显式告知 SELinux: /opt/chihaya 目录中的程序属于可执行的服务程序。最简单且符合逻辑的做法, 是将该二进制文件的安全上下文标记为 bin_t 类型, 使其被视为合法的可执行文件。\n需要为 Chihaya 显式设置安全上下文\n# 给二进制文件赋予执行标签 semanage fcontext -a -t bin_t \u0026#34;/opt/chihaya/chihaya\u0026#34; # 给配置文件赋予通用的、由 systemd 读取的标签 (如 etc_t) semanage fcontext -a -t etc_t \u0026#34;/opt/chihaya/chihaya.yaml\u0026#34; # 应用修改到文件系统 restorecon -Rv /opt/chihaya 创建 systemd 服务\r创建服务单元文件\nvim /etc/systemd/system/chihaya.service 内容如下\n[Unit] Description=Chihaya Service After=network.target [Service] User=chihaya Group=chihaya WorkingDirectory=/opt/chihaya ExecStart=/opt/chihaya/chihaya --config chihaya.yaml Restart=always RestartSec=5 [Install] WantedBy=multi-user.target 加载并启动服务\nsystemctl daemon-reload systemctl start chihaya systemctl enable chihaya systemctl status chihaya 验证 Chihaya 是否正常运行\r在服务启动完成后, 可以通过以下方式确认 Chihaya 是否已经正常运行。\n检查端口监听状态\rnetstat -nlptu | grep chihaya 如果能看到 chihaya 进程正在监听该端口, 说明服务已成功启动\n查看服务状态与运行指标\rChihaya 内置了调试与监控接口, 可用于确认服务运行状态\n# 用于查看运行状态和性能分析信息 http://127.0.0.1:56880/debug/pprof/ # 用于暴露运行指标, 方便接入监控系统 http://127.0.0.1:56880/metrics nginx 反向代理与访问控制\r使用 nginx 反向代理的方式对外提供 Tracker 服务, 通过路径中携带 Token 的方式进行简单鉴权, 以减少被脚本扫描和滥用的风险。同时, 由 nginx 统一提供 https 支持。\n整体架构如下:\nChihaya 仅监听本地端口, 不直接对公网暴露 Nginx 负责以下功能: 提供 TLS (HTTPS) 支持 IPv4 / IPv6 双栈访问 访问控制 (基于 Token) HTTP/2 支持 upstream chihaya_tracker { server 127.0.0.1:56969; keepalive 16; } # 根据 URL 中提取的 key 判断是否授权 map $captured_key $is_authorized { default 0; \u0026#34;0s6mbzbcp4grlq9a4nay93ozlzadueis\u0026#34; 1; # key 1 \u0026#34;ev2x3pmghcag5btekctdnz3eh16kbjbz\u0026#34; 1; # key 2 \u0026#34;4ii67b78adbrccj0zu49h8fvrefkqnoi\u0026#34; 1; # key 3 } server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name tracker.acesheep.com; # SSL 相关配置 (已省略) # 日志相关配置 (已省略) location / { try_files $uri /index.html; } # 同时匹配 /\u0026lt;TOKEN\u0026gt;/announce 和 /\u0026lt;TOKEN\u0026gt;/scrape location ~ \u0026#34;^/(?\u0026lt;captured_key\u0026gt;[a-z0-9]{32})/(announce|scrape)$\u0026#34; { access_log /var/log/nginx/tracker_chihaya.log main; error_log /var/log/nginx/tracker_chihaya.error; # 鉴权失败直接拒绝 if ($is_authorized = 0) { return 403; } # 将 /\u0026lt;TOKEN\u0026gt;/announce 内部重写为 /announce # break 表示停止后续匹配, 直接在当前 location 处理 rewrite ^/[^/]+/(.*)$ /$1 break; # 转发至后端 Chihaya proxy_pass http://chihaya_tracker; # 保持长连接 proxy_http_version 1.1; proxy_set_header Connection \u0026#34;\u0026#34;; # 向 Chihaya 传递真实客户端 IP proxy_set_header X-Real-IP $remote_addr; } # 精确匹配 /metrics 路径 location = /metrics { access_log /var/log/nginx/tracker_metrics.log main; error_log /var/log/nginx/tracker_metrics.error; # 由于 metrics 涉及服务器采样, 建议启用基本认证 auth_basic \u0026#34;Restricted Access\u0026#34;; auth_basic_user_file /home/SSL/tracker.acesheep.com.htpasswd; proxy_pass http://127.0.0.1:56880; } } Tracker 地址测试\r可以将以下地址添加到客户端的 Tracker 列表中进行测试\nhttps://tracker.acesheep.com/0s6mbzbcp4grlq9a4nay93ozlzadueis/announce 如果客户端能够正常连接并开始汇报状态, 说明:\nNginx 反向代理工作正常 Token 鉴权生效 Chihaya 运行正常 (可选) 配置 Prometheus 监控\rChihaya 提供了符合 Prometheus 规范的 /metrics 接口, 可以通过 Prometheus 定期采集运行指标, 用于监控 Tracker 的运行状态和性能情况。最终可以通过 Grafana 对采集的数据进行可视化展示。\n编辑 Prometheus 配置文件\nvim /opt/prometheus/prometheus.yml 在配置文件中添加如下内容\nscrape_configs: - job_name: chihaya_tracker scrape_interval: 5s scrape_timeout: 5s metrics_path: /metrics scheme: https basic_auth: username: tracker.acesheep.com password: blog.acesheep.com static_configs: - targets: [\u0026#34;tracker.acesheep.com\u0026#34;] labels: app: chihaya 配置完成并重载 Prometheus 后, 即可在 Prometheus 中看到 Chihaya 的相关指标数据\n原文\nchihaya/chihaya: A customizable, multi-protocol BitTorrent Tracker\ncentos7搭建带鉴权私有Tracker教程\n","date":"2025-12-30T05:48:16+08:00","permalink":"https://blog.acesheep.com/p/rocky-9-build-chihaya-private-tracker-with-auth/","title":"Rocky 9 搭建带鉴权的 Chihaya 私有 Tracker 服务器"},{"content":"在 Go 语言中, 经常需要将字节数 (byte) 转换为更加直观、易读的字符串形式, 例如将文件大小或内存占用显示为 KB、MB、GB 等。\n常见的转换方式主要有两种标准:\n十进制 (SI 标准): 以 1000 为单位 (kB、MB、GB) 二进制 (IEC 标准): 以 1024 为单位 (KiB、MiB、GiB) 十进制 (SI) 格式化函数\r使用 1000 作为单位, 常见于硬盘容量、网络带宽等场景\nfunc ByteCountDecimal(b int64) string { const unit = 1000 if b \u0026lt; unit { return fmt.Sprintf(\u0026#34;%d B\u0026#34;, b) } div, exp := int64(unit), 0 for n := b / unit; n \u0026gt;= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf(\u0026#34;%.1f %cB\u0026#34;, float64(b)/float64(div), \u0026#34;kMGTPE\u0026#34;[exp]) } 二进制 (IEC) 格式化函数\r使用 1024 作为单位, 更符合操作系统、内存、文件系统的实际计算方式\nfunc ByteCountBinary(b int64) string { const unit = 1024 if b \u0026lt; unit { return fmt.Sprintf(\u0026#34;%d B\u0026#34;, b) } div, exp := int64(unit), 0 for n := b / unit; n \u0026gt;= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf(\u0026#34;%.1f %ciB\u0026#34;, float64(b)/float64(div), \u0026#34;KMGTPE\u0026#34;[exp]) } 示例输入与输出对照\nInput Decimal (SI) Binary (IEC) 0 \u0026#34;0 B\u0026#34; \u0026#34;0 B\u0026#34; 27 \u0026#34;27 B\u0026#34; \u0026#34;27 B\u0026#34; 999 \u0026#34;999 B\u0026#34; \u0026#34;999 B\u0026#34; 1000 \u0026#34;1.0 kB\u0026#34; \u0026#34;1000 B\u0026#34; 1023 \u0026#34;1.0 kB\u0026#34; \u0026#34;1023 B\u0026#34; 1024 \u0026#34;1.0 kB\u0026#34; \u0026#34;1.0 KiB\u0026#34; 1728 \u0026#34;1.7 kB\u0026#34; \u0026#34;1.7 KiB\u0026#34; 1855425871872 \u0026#34;1.9 TB\u0026#34; \u0026#34;1.7 TiB\u0026#34; math.MaxInt64 \u0026#34;9.2 EB\u0026#34; \u0026#34;8.0 EiB\u0026#34; 原文\nGo: Format byte size to human readable format\n","date":"2025-12-28T04:11:18+08:00","permalink":"https://blog.acesheep.com/p/go-formatting-byte-size-to-human-readable-format/","title":"Go: 将 byte 字节转为 KB / MB / GB 单位"},{"content":"Cloudflare 在 Free Plan 中目前支持四种边缘证书颁发机构 (CA)\nLet’s Encrypt Google Trust Services SSL.com Sectigo (仅作为备用, 无法手动指定) 这些证书在控制台内是随机分配的, 无法主动选择证书颁发机构。\n不过, 在查阅 Cloudflare API 文档并进行实际测试后, 发现有一个文档中未明确提及但可用的参数 certificate_authority 通过该参数, 可以成功切换 Cloudflare 边缘证书的颁发机构。\n为啥要更换证书提供者\r主要原因是 Let’s Encrypt 在 2025 年关闭 OCSP 验证服务 Ending OCSP Support in 2025\n对于依赖 OCSP Stapling 或对证书吊销检查较为敏感的客户端环境, 更换证书颁发机构是一个更稳妥的选择。\n切换边缘证书\r前期准备\r在操作前, 需要准备以下信息:\nCloudflare Zone ID Cloudflare 账户邮箱 Cloudflare Global API Key Zone ID 获取方法\r进入 Cloudflare 控制台, 打开对应域名, 在页面右下角可以看到 Zone ID, 复制即可。\nCloudflare 账户邮箱\r就是你登录 Cloudflare 所使用的邮箱地址。如不确定, 可访问以下页面查看\nGlobal API Key 获取\r访问 https://dash.cloudflare.com/profile/api-tokens\n在 API 密钥区域中查看并获取 Global API Key\n证书颁发机构标识说明\r在 API 中, 不同证书颁发机构使用以下标识\n证书颁发机构 API 标识 备注说明 DigiCert digicert 已过期失效 Let’s Encrypt lets_encrypt Google Trust Services google SSL.com ssl_com Sectigo sectigo 仅作为备用证书, 不支持手动切换 切换方法\r通过 Cloudflare API, 对 Universal SSL 设置发起 PATCH 请求即可。\n# Zone ID (区域 ID) ZONEID=\u0026#39;\u0026#39; # Cloudflare 登录邮箱 EMAIL=\u0026#39;\u0026#39; # Global API Key APIKEY=\u0026#39;\u0026#39; # 证书颁发机构标识 CERTCODE=\u0026#39;ssl_com\u0026#39; curl -X PATCH \u0026#34;https://api.cloudflare.com/client/v4/zones/${ZONEID}/ssl/universal/settings\u0026#34; \\ -H \u0026#34;X-Auth-Email: ${EMAIL}\u0026#34; \\ -H \u0026#34;X-Auth-Key: ${APIKEY}\u0026#34; \\ -H \u0026#34;Content-Type: application/json\u0026#34; \\ --data \u0026#34;{\\\u0026#34;enabled\\\u0026#34;:true,\\\u0026#34;certificate_authority\\\u0026#34;:\\\u0026#34;${CERTCODE}\\\u0026#34;}\u0026#34; # 示例 (直接写死证书提供者) # --data \u0026#39;{\u0026#34;enabled\u0026#34;:true,\u0026#34;certificate_authority\u0026#34;:\u0026#34;digicert\u0026#34;}\u0026#39; 将其中的变量替换为你自己的实际值即可。\n如果请求成功, 会返回类似如下的 JSON 数据\n{ \u0026#34;result\u0026#34;: { \u0026#34;enabled\u0026#34;: true, \u0026#34;certificate_authority\u0026#34;: \u0026#34;ssl_com\u0026#34; }, \u0026#34;success\u0026#34;: true, \u0026#34;errors\u0026#34;: [], \u0026#34;messages\u0026#34;: [] } 接口返回成功后, Cloudflare 会自动重新签发并部署新的边缘证书。\n生效说明\r此时进入 Cloudflare 控制台的 SSL/TLS -\u0026gt; Edge Certificates 页面, 也可以看到新的证书已经生效。\n注意事项\r如果发现证书颁发机构没有发生变化, 通常表示当前证书仍在有效期内, Cloudflare 不会立即重新签发。\n此时可以通过关闭并重新开启 Universal SSL 来强制刷新证书。\n操作方法如下:\n将 enabled 设置为 false, 提交一次请求 等待约 2 分钟 再将 enabled 设置为 true, 提交一次请求 这样可以触发 Cloudflare 重新签发边缘证书。\n原文\nHow to get a .ip6.arpa TLS certificate for $0\n用api切换cf的证书\nCloudflare使用api更换证书颁发机构\nCloudflare切换SSL证书颁发者\n","date":"2025-12-11T07:58:58+08:00","permalink":"https://blog.acesheep.com/p/cloudflare-switch-edge-certificate-authority/","title":"Cloudflare 切换边缘证书颁发机构"},{"content":"在内地使用外汇、跨境收款或海外投资时, 你是否遇到过账户风控频繁、应用无法注册、资金进出不便等问题？其实, 这些问题往往可以通过开立一张香港银行账户得到有效解决。\n但很多人会担心香港开户门槛高、流程复杂、需要高额存款。本文将结合我一次赴港成功开通 3 张香港银行卡的真实经历, 详细分享开户前的准备事项、银行选择逻辑以及常见避坑经验, 帮助你用最低成本、高效率完成香港银行开户。\n为什么要在香港开立银行账户？\r在香港开立一张离岸账户, 可以解决许多内地用户在实际使用中遇到的问题, 例如:\n全球收付款: 将电汇款项直接汇入离岸账户, 通常无需频繁提供外汇来源说明 海外应用注册与使用: 如 PayPal、AlipayHK、GlobalPay、Tap \u0026amp; Go 等 投资港股与美股: 相比内地账户只能投资 A 股, 香港账户几乎没有市场限制 本次计划开通的 0 门槛香港银行卡\r此次赴港, 我计划一次性办理几张 0 门槛 (0 存款、无年费) 的银行卡:\n银行 类型 是否推荐 中银香港 (BOCHK) 实体银行 👍 汇丰银行 (HSBC) 实体银行 👍 众安银行 (ZA) 虚拟银行 👍 理惠银行 (livi) 虚拟银行 香港银行开户需要准备哪些资料？\r赴港前, 务必提前准备好以下材料。建议全部携带纸质原件, 避免因材料问题反复往返\n基础身份证明材料\r内地身份证 港澳通行证 护照 部分银行在开立投资账户时会要求提供 以上证件均需提供原件, 银行会现场复印存档\n永久地址证明\r永久地址证明主要用于邮寄银行卡, 也是内地客户最容易被拒的环节之一\n地址与身份证一致的情况, 可提供以下任一材料 (原件)\n户口本 房产证 居住证 地址与身份证不一致的情况, 可提供以下任一材料 (纸质版) 最近三个月内的\n水费账单 电费账单 储蓄卡账单 信用卡账单 ⚠️ 注意: 禁止电子账单或自行打印的电子版\n常见被拒原因说明\r香港银行目前仍以纸质材料为主。如果客户经理看到电子印章、PDF 打印件或截图, 很可能会直接拒绝受理。\n不要抱侥幸心理。 提前去一趟供电局、银行打印账单, 远比在香港被拒后来回跑要省事得多。\n其实取得这些材料并不难, 建议提前备齐, 避免客户经理刁难。此外, 部分材料具有时效性, 而内地每次出入境签注通常需要等待一周, 频繁往返会导致反复准备材料, 非常浪费时间。\n通关小票 (小白条)\r通关后, 边检人员会发放一张小白色通关小票, 请务必妥善保管\n实体银行在开户时必须提供, 用于确认你是否合法在香港停留。一旦遗失, 几乎无法补办, 直接影响开户\n出入境记录 (虚拟银行必备)\r虚拟银行 (如 ZA Bank、livi) 开户需要。主要是确认你申请开户时、本人在香港境内, 避免伪造定位开户\n查询方式在微信搜索小程序「移民局」-\u0026gt;「出入境记录查询」\n赴港开户前的准备事项\r提前开通国际漫游功能\r在办理香港银行开户时, 银行通常会要求绑定一个手机号码, 用于接收短信验证码, 因此所使用的手机号必须能够正常接收来自香港的短信。\n如果你使用的是内地手机号码, 务必在赴港前开通国际漫游服务。受监管原因影响, 内地三大运营商默认关闭国际漫游功能, 在未开通的情况下, 手机到达境外后直接无服务, 电话和短信均无法接收。此时再尝试远程开通国际漫游会非常麻烦, 甚至无法操作。\n如不确定是否已开通国际漫游, 可通过运营商客服或在线营业厅进行查询和办理。提前处理好这一项, 可以避免在银行现场因收不到验证码而被迫中断开户流程。\n提前下载银行 APP\r我办理的是中国银行 (香港)、汇丰银行 (香港) 以及众安银行, 所以提前在内地下载好了这几个银行app。其他银行以此类推\n准备港币现金\r在中银香港开户时, 通常会要求当场向账户内存入 1 万港币。这笔资金在完成开户后可以自行取出, 账户本身并不存在最低存款门槛, 因此只需提前准备好用于入账的现金即可。\n此外, 汇丰银行 (HSBC) 在开户时会要求存入 100 港币于激活账户。\n在香港, 大多数 ATM 都支持银联卡, 可以直接使用内地的储蓄卡在当地取现, 再将取出的港币存入中银账户, 操作相对方便快捷。如果不熟悉取现流程, 建议出发前向银行咨询, 确认每日取现额度及手续费情况。\n此外, 也可以选择在内地提前兑换好港币现钞, 赴港后直接存入银行账户, 以此减少境外取现所产生的手续费。\n赴港开户: 理由比资料更重要\r需要明确一点, 香港银行和大陆银行不同, 香港银行客户经理开户没有业绩考核。因此, 如果你无法给出一个让银行觉得有利可图的理由, 客户经理会认为帮你开户是浪费时间, 完全可以找理由拒绝给你开户。\n因此, 在开户前, 一定要提前准备好合理、可验证的开户理由, 让客户经理觉得你是一个有价值的客户。并且只说一个, 不要多说。\n可以考虑自己的职业、财务状况、投资计划等方面, 并尽可能准确、清晰地表达。\n以下为常见开户理由在实际操作中的通过情况, 仅供参考, 具体以分行及客户经理审核为准。\n理由 是否成立 说明 大额储蓄 ✅ 成立 能提供 50 万以上的境外资金证明, 并明确表示开户后会存入, 银行风险低、收益明确, 开户流程非常丝滑 小额储蓄 ❌ 不成立 内地居民不在香港长期居住, 小额资金对银行吸引力有限, 难以覆盖合规与维护成本 理财 ❌ 不成立 理财规模通常与资金量挂钩, 小额资金无法形成有效业务, 银行往往不予受理 办信用卡顺便开户 ❌ 不成立 香港信用卡不强制绑定借记卡, 且对非本地居民审核严格, 开户理由不充分 兑换外币旅游 ❌ 不成立 外币兑换可直接在柜台办理, 大额兑换提前预约即可, 银行没有必要为此开立账户 收外汇 ❌ 不成立 涉及资金来源与用途合规审查, 若存在商业或频繁收款情形, 反而会提高银行的风控成本 买香港保险 ✅ 成立 用于保费缴纳及续保, 需提前准备保单或投保证明 收香港工资 ✅ 成立 适用于在港合法受雇人员, 需提供香港公司出具的工作及薪酬证明 本人或孩子在港读书 ✅ 成立 用于缴纳学费及生活开支, 提供学校录取或在读证明即可 投资港股 ✅ 成立 需证明具备证券投资经验, 通常通过近一个月的 A 股交易记录进行佐证 在香港开立银行账户本身并不违法, 因此无需过度紧张。只要你能够按照银行要求, 提供相应的资料, 并说明自己的开户用途, 客户经理通常只是依照流程进行审核, 并不存在额外的个人判断空间。\n需要注意的是, 客户经理在沟通中不会引导你阐述开户理由, 通常只会依据你第一个提出的理由进行判断。因此, 开户时不宜表达过多想法, 更不要反复更换说辞, 以免前后不一致而引发额外质疑。一旦说错或说漏, 后续解释很难起到挽回作用。\n基于以上原因, 建议在前往银行办理开户之前, 就提前准备好开户理由以及对应的资料, 并在现场保持简洁、克制的表达。只要材料齐全、理由合理, 多数情况下都可以顺利完成开户申请。\n以「投资港股」作为开户理由\r对于内地居民而言, 赴港开立香港银行账户时, 「投资港股」是最常被认可、也最容易说明的开户理由之一。因此, 客户经理通常会在现场要求查看你的过往投资记录。而由于内地居民一般只能参与 A 股交易, A 股的历史交易流水就成为最直接、也是最常用的佐证材料。\n基于这一点, 建议在计划赴港开户前至少一个月, 提前准备好一份相对完整的 A 股交易记录。\n准备可被认可的 A 股交易记录\r下载一家证券公司的 APP, 并注册一个证券投资账户, 用于获取交易流水。\n如果你并不真正想炒股, 证券公司的选择并不重要。这里可以选择体量较大、知名度较高的平台, 例如 中信证券 (也可选择东方财富、富途牛牛等), 主要目的是让交易记录看起来更规范、可信。\n证券账户开通后, 存入约 500 元人民币即可。随后在股票列表中按价格升序排序, 找到价格靠后的尾部股票进行交易。A 股的最小交易单位为 100 股, 尾部股票的价格通常在 1 元左右, 购买 3～4 只股票即可满足刷交易流水的需求。\n为了刷交易流水, 买入的股票无需过度关注涨跌。而且尾部股票通常被视为垃圾股, 99% 的情况下都会亏损, 即便出现盈利, 也无法抵消交易手续费。建议在买入股票后, 持有两天再卖出 (A 股实行 T+1, 当天买入无法卖出), 随后再更换其他股票继续交易。\n按照上述方式持续操作一个月左右, 交易记录会显得相对完整且有连续性。实际开户时, 只需在现场打开证券 APP, 让客户经理查看最近一个月的历史交易流水, 即可用于证明你的投资行为和交易活跃度。\n口岸过关与入境注意事项\r抵达香港国际机场后, 使用港澳通行证无需填写入境卡, 直接前往人工窗口排队办理入境手续。\n在人工窗口, 工作人员会询问此次来港的目的, 你可以回答 \u0026ldquo;旅游\u0026rdquo;。入境时, 工作人员会发放一张 小白条 (通关小票), 如下图所示。\n这张小白纸非常重要: 在办理香港银行卡时, 银行业务员会要求出示它以核实入境记录, 因此务必妥善保管, 切勿丢失。\n香港银行卡开户流程实录\r中国银行 (香港) 开户流程\r我选择的是中港城分行, 这是内地客户中非常热门的开户网点之一, 竞争程度相当高。\n我当天提前 2 小时到达分行门口排队, 只拿到了 3 号。据现场观察, 第一个人早上 6 点就已经在排队, 而银行 9 点才正式开门, 实在是太卷了。\n需要特别注意的是, 中港城内的中国银行有不止一个入口, 不同入口对应不同业务。如果排错了门, 等到快开门才发现走错位置, 基本算是白排了。建议提前确认好具体的开户入口, 不要看到有人排队就盲目跟随, 不然就糗大了。\n扫码预填资料与取号\r中港城分行办理开户时, 需要先扫码进行线上预填。现场会要求你打开中银香港 APP, 扫描二维码并在线填写开户资料。\n现场会先发放排队号码, 同时可扫码填写开户资料。拿到号码后即可在等候区就座, 一边填写资料, 一边等待叫号办理。资料填写完成的先后决定办理顺序, 谁先填完, 谁就先被叫号。\n当天仅有两个窗口办理开户业务。我拿到的是 3 号, 实际等待时间大约 40 分钟。\n实际开户沟通情况\r轮到我办理时, 整体流程非常机械化, 几乎没有交流。这家分行明显每天都处理大量内地客户开户, 工作人员以效率为主, 班味很重。\n我只说明了开户用途是投资港股, 没有被要求出示 A 股交易记录, 也没有被进一步追问。\nBOCHK: 请问您开户是用作什么？ ME: 投资港股 BOCHK: (低头开始录入信息) 中间基本没有交流 空调直吹座位, 33 度的夏天快冻死我了, 建议带件薄外套 BOCHK: 请脱下口罩, 需要核实是否为本人 BOCHK: (叫来另一位经理进行授权) 授权过程又等了一段时间 银行系统似乎很老旧, 整个办理流程大约持续 40 分钟。不过, 整个过程中没有出现什么问题。\n现场存款与账户激活\r客户经理递给我一封 开户信, 并要求我到分行外的 ATM 使用账户号码进行无卡存款, 存入 1 万港币。\n完成存款后, 才能继续后续开户流程。我在 ATM 操作了一会儿, 顺利存入 1 万港币后返回柜台。\n工作人员确认:\n账户已成功开通 现场发放预制提款卡 办理完成后, 我同时拿到了开户信和实体卡片。至此, 开户基本完成。\n开户完成后的账户结构说明\r开户信上会列出 4 个账号, 用途分别如下\n网银账号: 用于登录中银香港手机 APP 港元账户 (主账户): 用于存放港币 外汇宝账户: 用于存放非港币外汇 证券账户: 用于后续投资操作 可以立即使用网银功能。需要注意的是第一次转账需要对限额进行调整。这在其他银行也是一样的, 在 APP 内操作即可。\n经验补充\r在填写资料过程中截图保存, 因为提交后, 客户经理可能在电脑端找不到你提交的资料, 需要重新录入。有截图的话, 直接给他抄就能节省不少时间 (我没有遇到这个问题)\n当天我下午又回到中港城分行办理流动安保码, 期间看到一位内地客户因为只带了电子发票, 而银行坚持要求纸质材料, 在大厅大吵大闹, 最终也没有解决问题。\n如果遇到不给办理的业务员, 就不要浪费时间了, 可以直接换一家分行。在香港, 中国银行遍地都是。\n汇丰银行 (香港) One 开户流程\r汇丰是我这次赴港最主要、也是最终使用的银行账户。整体账户结构规划如下:\n中国银行 -\u0026gt; 中银香港\n内地中行向中银香港通过 Swift 汇入港币 免手续费 中银香港 -\u0026gt; 汇丰银行 (香港)\n通过转数快 (FPS) 转账, 同样免手续费 汇丰账户\n作为日常消费、刷卡、资金沉淀与后续投资操作的主账户 也正因为汇丰是整个资金链路中的最后一环的核心账户, 我在开户前对资料准备、预约流程和现场细节都格外谨慎, 避免出现被拒或需要二次补材料的情况。\n预约与前期沟通\r在赴港前, 我先通过香港汇丰银行官网咨询开户所需资料。官网右下角提供在线客服, 回复 \u0026ldquo;转人工\u0026rdquo; 即可直接与客服沟通, 问题基本都能当场确认。\n按照客服指引, 我在线预约了线下面谈分行。\n一般情况下, 预约提交后的几个工作日内, 汇丰会进行 两次电话回访\n第一次由总行工作人员联系, 确认姓名 (中英文)、期望会面分行及时间。若没有英文名, 可直接使用拼音。客服人员会将你的资料发送给对应的分行, 分行再协调会面时间。 第二次由具体分行回访, 确认最终会面时间, 并再次核对开户所需材料, 要求必须准时到达, 不能提前或迟到。 不过, 我的实际只接到了总行的电话, 一直没有接到分行的回访。\n需要说明的是, 如果行程紧张、当天计划跑多家银行, 不预约也可以。但如果时间允许, 仍然建议提前预约, 银行通常会为预约客户预留专门的办理时间, 整体体验更稳定一些。\n预约失效与现场排队\r我的行程安排是第一天办理中银, 第二天办理汇丰。中银开户完成后, 我提前前往预约的尖沙咀汇丰分行, 现场确认第二天的预约是否成功。\n该分行人流量非常大。前台查询后告知: 系统中未查到我的预约记录。同时工作人员说明, 该分行每天仅向未预约客户开放 3 个现场名额, 建议我第二天尽量早点到场排队。\n在经历过中银开户有多卷后, 我第二天直接提前 2 小时到达汇丰分行门口排队。\n相比中银, 汇丰的排队强度明显低很多。直到 7:45 才出现第二位排队的老哥, 对方甚至是直接从机场杀到尖沙咀开户, 行李都带在身上。\n汇丰对预约客户与现场客户的叫号规则区分非常明确\nB 开头: 预约号 A 开头: 现场排队号 我排在第一位, 成功拿到 A1。分行开门后, 工作人员先连续叫了 3 个 B 号, 大约 20 分钟后, 才轮到现场排队的 A1\n实际开户沟通过程\r整体来看, 汇丰的开户审核明显比中银严格。客户经理会非常认真地逐项核对你提交的材料, 问题也问得更细, 整个流程偏向标准化合规审核。\nME: 你好, 我想开户 HSBCHK: 请提供身份证和其他资料 (所有客户经理都默认你已经了解开户所需材料) ME: (递交材料) 内地身份证、港澳通行证、通关小票、 最近三个月的信用卡账单、通信账单、电费发票 HSBCHK: (逐项检查材料) HSBCHK: 开户的目的是什么？ ME: 投资港股 HSBCHK: 有投资经验吗? ME: 没有 HSBCHK: 你是什么职业? ME: mjj HSBCHK: 年收入多少? ME: (在外面身份都是自己给的) HSBCHK: 资金来源是哪里？ ME: 薪金 HSBCHK: 计划投入多少资金用于美股投资? ME: 3000 美元 HSBCHK: 开户后准备存入多少钱? ME: 20 万港币 HSBCHK: (明显犹豫了一下) HSBCHK: 开户后一共准备存入多少钱? ME: (立刻补充) 20 万港币用于储蓄, 3000 美元单独用于美股投资, 合计大约 25 万港币 HSBCHK: 来香港的频率有多少? ME: 距离较远, 一年大约两次 HSBCHK: 护照给我一下, 用于开美股投资账户 问答结束后, 客户经理起身去复印材料, 并取来了预制的 One 提款卡, 随后开始在系统中手动录入信息。\n资料录入完成后, 工作人员确认\nHSBCHK: 账户已经开通, 需要存入 100 港币用于激活账户 整个开户流程大约持续 50 分钟。虽然审核严格、问得很细, 但过程整体顺畅, 没有出现被卡或反复解释的情况。\n众安银行 (ZA Bank) 开户流程\r如果说中银香港和汇丰是主力账户, 那么众安银行 (ZA Bank) 更像是一个保底方案。即使实体银行当天没开成功, ZA Bank 则是点击就送。\nZA Bank 的一大优势是与 Wise 合作, 跨境汇款路径成熟, 手续费相对较低, 非常适合作为备用账户或中转账户使用。\n开户基本要求\r虚拟银行的开户条件相比实体银行要宽松得多, 核心要求只有一个。开户时必须身处香港市区 (偏远郊区不行)。除此之外, 资料要求简单, 不需要预约, 也不存在排队问题。\n建议选择一个安静、人少的地方进行开户。整个流程需要设置密码、进行人脸识别, 涉及隐私操作, 不太适合在公共场所或人多的地方进行。\n实际开户体验\r整个开户流程完全通过 ZA Bank APP 完成, 按照引导一步步操作即可, 整体耗时大约 30 分钟左右。\n我是在抵达香港、入住酒店后, 直接打开众安银行 (ZA Bank) APP 进行线上开户。需要注意以下几点\n必须连接香港本地网络\n使用酒店 WiFi 即可, 漫游网络无法通过定位校验 需准备好出入境记录的 PDF 文件 (到达香港后即可下载) 开户过程中主要包括填写个人资料、拍摄证件照片以及完成人脸识别, 流程非常顺畅, 没有遇到反复提交的情况。\n实体卡申请\r收到开户成功通知后, 我第一时间在 APP 内申请了 ZA Bank 实体卡, 支持自选卡号 (靓号), 整体体验相当不错。\n只要人在香港市区, 拥有一部手机和香港本地网络, 就可以快速完成 ZA Bank 开户, 完全避开实体银行的排队、被拒或反复沟通问题。\n写在最后\r这次赴港前, 我对开户流程和所需资料做了较为充分的准备, 目标是成功开通中国银行 (香港) 和汇丰银行的账户, 同时也预留了众安银行 (ZA Bank) 作为保底方案。\n期间我也尝试了渣打银行和花旗银行。实际体验并不理想:\n渣打银行在两个分行都以推销保险为主, 不购买保险产品无法开户 花旗银行则要求账户资产达到 150 万港币, 门槛较高 整体来看, 本次开户过程还算顺利, 最终成功开通了计划中的账户。需要注意的是, 不同银行、不同分行的审核尺度确实存在差异, 其中汇丰的要求明显比中银更严格。\n如果现场遇到被拒的情况, 不要纠缠, 也不要争论, 直接更换分行或银行往往效率更高。提前准备、心态放平, 总能找到愿意为你办理开户的网点。\n常见问题\r为什么一定要提供地址证明？\r提供地址证明主要是为了确保银行能够将银行卡寄送到正确地址, 并在必要时联系到客户。有些客户经理告诉我, 有很多内地客户在办完开户手续后失联, 直到账户被冻结也无法联系, 因此银行需要可靠的地址证明以防类似情况发生。\n为什么一定要提供纸质材料, 不能使用电子版？\r香港银行的无纸化程度不高, 仍然偏好使用纸质材料存档客户资料。相比之下, 电子版的地址可以伪造, 而纸质材料由政府机构提供, 至少在印章等方面无法被篡改或伪造, 因此更具可信度。\n为什么身份证不能证明地址？\r内地身份证虽印有地址, 但在香港开户时不被视为完整地址凭证。因此, 需要户口本、房产证、居住证或居住合同等辅助材料来佐证地址。\n为什么内地人在香港开户会遇到困难？\r大多数客户经理并非刻意刁难客户, 他们的沟通风格可能较直接, 对本地人也是如此。我见过大部分客户经理的态度都很友好, 有些客户经理甚至尽量使用普通话沟通, 这表明他们没有恶意。\n真正可能遇到刁难的情况非常少, 通常是客户经理在听到普通话后刻意切换为英文。我在香港全程使用普通话开户, 并未遇到任何刁难。\n你有没有推荐的顺利开户的分行？\r我不提供具体分行推荐。相比盲目跟风网红分行, 自己在地图上搜索一些偏远分行更可靠, 例如北角以东或旺角以北的分行。提前到场通常比预约更容易。\n网红分行可能机会很少, 要么一大早就排队 (每天最多放 20 个号), 要么与中介合作, 容易浪费时间。相反, 选择偏远分行并在 8:30 前到达, 更容易顺利开户。\n如果要在多个银行开户, 是否需要准备多份材料？\r不需要。银行一般只会复印你的原件材料存档, 而不会要求多份原件。\n原文\n内地赴港办理香港银行开户攻略：一次性开通5张银行卡的经验分享\n","date":"2025-11-06T16:57:18+08:00","permalink":"https://blog.acesheep.com/p/open-hk-bank-account-guide/","title":"内地赴港办理香港银行开户攻略"},{"content":"Hotlink 是马来西亚电信运营商 Maxis 旗下的预付费品牌。这意味着它使用 Maxis 自有的网络基础设施提供移动通信服务, 而非虚拟运营商。\n马来西亚的主要实体运营商包括 CelcomDigi (由 Celcom 与 Digi 合并, 覆盖最广)、Maxis (网络质量领先)、U Mobile (以灵活套餐和高性价比著称) 以及 UniFi Mobile (隶属 Telekom Malaysia, 主打宽带与移动融合服务)\n套餐内容\r官网: Prepaid Plan with 5G Unlimited Internet | Hotlink Malaysia\n官方 APP: App Store、Google Play\n套餐名称: 10GB (4G/5G) and 10GB (5G) valid for 7 days\n月租: RM 10\n项目 内容 本地通话 无限量本地通话 本地短信 RM 0.15/条 数据流量 每月 20 GB, 超出降至 512 kbps 有效期 7 天 服务条款\n漫游费用\r官网: 5G International Data Roaming Plans For Prepaid Or Postpaid | Hotlink Malaysia\n支持语音、短信、流量漫游, 不支持 WiFi Calling\n在中国漫游时, 合作运营商为 中国移动 (5G) / 中国联通 (4G)\n需确保账户余额 不少于 RM 10, 否则漫游时只能使用 2G 网络\n项目 漫游 (中国大陆) 接收短信 免费 发送短信 RM 1/条 接听来电 RM 3/分钟 拨打电话 (中国境内直拨) RM 4/分钟 拨打马来西亚 (直拨) RM 9/分钟 拨打马来西亚 (Roam 120 前缀) RM 3/分钟 注: Roam 120 为优惠拨号前缀, 从中国拨打回马来西亚时享受 RM 3/分钟价。拨号格式为\n*120*\u0026lt;country code\u0026gt;\u0026lt;area code/mobile prefix\u0026gt;\u0026lt;phone no.\u0026gt;# 例如, 拨打 +44 75766688888 *120*4475766688888# 可选漫游套餐 (Roaming Pass)\n套餐 有效期 流量 价格 1 Day DataRoam Pass 1 天 1 GB RM 20 7 Days ASIA Pacific DataRoam Pass 7 天 15 GB RM 55 15 Days Multi-Country DataRoam Pass 15 天 25 GB RM 75 30 Days Multi-Country DataRoam Pass 30 天 40 GB RM 100 说明: 达到流量额度后, 网速将被降速直至套餐到期, 无需额外费用。\n保号规则\r打开 Hotlink App, 在首页依次点击 Change Plan -\u0026gt; Pantas Plan, 更换套餐需额外支付 RM 2\n随后回到首页, 点击 Buy Passes -\u0026gt; Others, 选择并购买 RM 30 / 365 天 的长期有效套餐\n到期后再次购买相同的 365 天套餐即可续期保号\n激活使用\r购买方式\r可在 Family Mart、7-Eleven 等连锁便利店购买 Hotlink 预付费卡\n在结账柜台通常可以看到售价 RM 10 的套餐, 包含 7 天流量 和 无限通话分钟数\n购买后激活时需完成 实名登记\n实名认证\r选择 Passport (护照) 作为证件进行实名认证, 按提示扫描证件并拍摄三张自拍即可完成。完成后需填写邮箱、地址等个人信息即可完成注册。\n⚠️ 自拍要求为 正面、左侧、右侧 各一张, 仅需年满 12 周岁即可完成实名。\n充值\r支持 银行卡、银行账户 及 eWallet 支付。银行卡需为马来西亚或新加坡发行的卡, 推荐使用 eWallet 或马来卡 BIN 虚拟卡进行充值。\n使用 护照注册 的手机卡会被自动收取 6% SST (消费税), 所有 非马来西亚国籍用户 均需缴纳此税。\n如果希望到账 RM 32, 需至少充值 RM 34.05 (含 6% SST)\n充值方式\r通过 Wise 转账 在 Wise 中将资金转换为马来西亚林吉特 (MYR) 后, 充值到 Touch ‘n Go (TNG) eWallet, 再从 eWallet 为 Hotlink 充值 直接银行卡充值 在 Hotlink App 中使用 HSBC SG 或 OCBC SG 的银行卡直接为 Hotlink 充值 推荐使用 银行卡直接充值, 相较于通过 Wise 转账, 货币转换费用更低, 更划算。\n原文\n马来西亚🇲🇾Hotlink保号ESIM开卡教程\n","date":"2025-10-19T23:29:57+08:00","permalink":"https://blog.acesheep.com/p/sim-card-my-hotlink/","title":"马来西亚 Hotlink 保号卡"},{"content":"Lebara Australia 是一家澳大利亚虚拟运营商 (MVNO), 这意味着它不拥有自己的网络基础设施, 而是租用 Vodafone Australia (沃达丰澳大利亚) 的网络提供服务。\n澳大利亚的三大实体运营商分别是 Telstra (覆盖最广)、Optus (性价比高) 和 TPG Telecom (旗下拥有 Vodafone 品牌, 在国际通话方面具有优势)。\n套餐内容\r官网: Standard Plan or PAYG | Lebara Australia\n官方 APP: App Store、Google Play\n套餐名称: Pay As You Go\n月租: AUD 0\n项目 资费 本地通话 AUD 0.15/分钟 Lebara 号码当地互打 免费 13/1300 号码 AUD 0.15/分钟 1800 号码 免费 (不限量) 号码查询 1223 AUD 0.50/次 国内及国际短信 (SMS) AUD 0.15/条 国内及国际彩信 (MMS) AUD 0.25/条 数据流量 AUD 0.03/MB 漫游费用\r官网: International Roaming - Lebara\n支持语音、短信、流量漫游, 不支持漫游 WiFi Calling\n项目 漫游 (中国大陆) 接收短信 免费 发送短信 (至号码 126172 / 126122) 免费 发送短信 AUD 1.00/条 发送彩信 AUD 1.00/条 接听来电 AUD 1.00/分钟 拨打电话 AUD 1.00/分钟 呼叫转移 AUD 1.00/分钟 漫游流量 AUD 1.00/MB 可选漫游套餐 (Roaming Add-ons)\n套餐 有效期 流量 语音分钟 短信 价格 Economy Class Add-on 2 天 500 MB 50 分钟 50 条 AUD 15 First Class Add-on 10 天 3 GB 150 分钟 150 条 AUD 45 保号规则\rLebara AU 的 PAYG 套餐需要定期充值以防号码被注销。查看条款\n该规则与新西兰 Skinny 的保号规则类似\n自激活之日或最近一次充值起, 有效期为 365 天 套餐到期后有 80 天宽限期, 如果在宽限期内未充值, 服务将被停用；此后需重新申请新 SIM 卡, 原号码与账号将被清除 任意一次充值即可将有效期 重新补满 365 天。建议在到期前完成充值, 避免进入 80 天宽限期。\n激活使用\r开通 PAYG 套餐\r在超市购买 2 澳元的空卡后, 需要在 网页端 激活 Pay As You Go 套餐 (手机 App 中无法选择该套餐)\n激活过程中, 在选择套餐的步骤中找到 PAY AS YOU GO, 选择后系统会要求 最低充值 10 澳元\n成功开通后, 可在账户页面查看套餐的有效期\nUSSD 查询\r查询余额: 拨打 *#1345# 查询剩余流量: 拨打 *#137# 此外, 也可以编辑短信 BAL 发送至 126172, 系统会回复一条包含当前余额及账户详情的短信。\n","date":"2025-10-18T22:46:43+08:00","permalink":"https://blog.acesheep.com/p/sim-card-au-lebara/","title":"澳大利亚 Lebara 保号卡"},{"content":"CMLink JP 是日本的虚拟移动运营商 (MVNO), 由 中国移动 提供支持, 使用 NTT docomo 的网络。日本本土主要运营商包括 NTT docomo、au 和 SoftBank\nCMLink JP 主要面向留学生及短期访日用户, 网络覆盖广, 信号稳定。这手机卡非常适合用于演唱会抢票, 它无需 日本居留卡 即可办理, 并且是市面上 唯一 支持 语音、短信和海外漫游 功能的手机卡。\n套餐内容\r官网: 日本语音流量包月套餐 | 中国移动CMLink\n套餐名称: 语音数据卡 10GB 超值套餐\n月租: JPY 1700\n项目 内容 高速流量 10GB 高速流量, 达量限速至 128 Kbps 本地短信 每月含 10 条, 超出 JPY 3.3/条 本地通话 (主叫) JPY 22/30 秒 来电接听 免费 入网手续费 (一次性) 免收 JPY 3300 SIM卡费 (一次性) 免收 JPY 440 漫游费用\r官网: 中国でのスマホ・携帯電話の利用料金を調べる | NTTドコモ\n支持语音、短信; 不支持流量漫游、WiFi Calling\n项目 漫游 (中国大陆) 接收短信 免费 发送短信 JPY 100/条 接听来电 JPY 145/分钟 拨打电话 (拨打中国本地) JPY 75/分钟 拨打电话 (拨打日本) JPY 175/分钟 拨打电话 (拨打其他国家) JPY 265/分钟 漫游流量 不支持 保号规则\r绑定信用卡后, 每月会自动扣费 JPY 1700, 全年保号成本为 JPY 20400, 约合人民币 1020 元, 保号成本比较高。\n激活使用\rCMLink JP 只能在 日本当地插卡激活。收到激活邮件后, 需要联系客服开通 国际漫游服务\n开通国际漫游\r如果购卡实名使用 非日本有效证件 (如中国内地身份证或护照), 开通国际漫游功能时需提供以下资料:\n证件信息 日本在留卡正面、反面及手持自拍照片各一张 护照首页 + 日本驻中国领事馆签发的签证页 (含探亲签或旅游签) 开通国际漫游的理由说明 将以上资料发送至客服邮箱 csjp@cmlink.com 进行审核。审核通过后, 需要绑定 本人的信用卡\n","date":"2025-10-18T07:07:36+08:00","permalink":"https://blog.acesheep.com/p/sim-card-jp-cmlink/","title":"日本 CMLink 支持打电话和发短信"},{"content":"在德国, 主要的移动运营商有 德国电信 (Deutsche Telekom)、Vodafone 和 O2\n三者在网络覆盖、价格与服务定位上各有特色:\nTelekom: 网络覆盖与稳定性最佳, 但价格最高 Vodafone: 虽然在覆盖范围和速度上略逊于德国电信, 但价格适中 O2: 以低廉的价格和较多的门店为优势, 但信号覆盖与网速相对较差 Vodafone 作为德国第二大运营商, 其 CallYa Classic 预付费套餐 以 零月租、无合约 著称, 非常适合 数字游民、短期访客、跨境用户 等灵活需求人群。\n更令人惊喜的是, 配合 欧盟 IBAN 银行账户 可以轻松实现自动保号。折合人民币约 4 毛钱/年, 堪称最低成本的德国手机号解决方案\n主要特点\n✅ 实体运营商, 非虚拟运营商\n✅ 0 月租、无合约、余额不过期\n✅ 支持 eSIM 在线开卡\n✅ 漫游支持覆盖欧洲及中国境内\n✅ 支持 WiFi Calling\n✅ 保号成本极低\n自 2017 年 7 月 起, 德国所有新的预付费 (Prepaid) 用户都必须进行实名验证。\n如果有条件, 更推荐 O2 DE 保号卡, 但是这张卡只有实体卡, 且只配送德国私人地址\n套餐内容\r官网: Tarifdetails \u0026amp; Optionen zu CallYa Classic | Vodafone\n官方 APP: App Store、Google Play\n资费详情\r套餐名称: Prepaid: CallYa Classic\n月租: EUR 0\nVodafone 的 Prepaid 手机卡不会被上报至德国征信系统 (Schufa), 因此不会影响个人信用记录。该卡支持 eSIM 新开卡, 无需等待实体卡寄送, 可在境外直接激活使用, 详细操作可参考 官方帮助文档。eSIM 的二维码在更换手机时可重复使用, 无需重新申请。\n此外, Vodafone 支持 WiFi Calling 功能, 即使信号较弱也能通过网络稳定通话。官方说明\n如果卡片遗失, 可通过官方网站在线申请补卡。用户还可在两个不同的 Vodafone 号码之间自由转移余额, 并支持携号转入 (原运营商收取 EUR 6.82 手续费)。\n项目 资费 语音 (德国本地) 拨打 Vodafone (含语音信箱) EUR 0.09/分钟 语音 (德国本地) 拨打固话 EUR 0.09/分钟 语音 (德国本地) 拨打其他移动网络 EUR 0.09/分钟 语音 (拨打至 EU 国家) EUR 0.09/分钟 短信 (至 Vodafone 德国) EUR 0.09/条 短信 (至其他德国移动网络) EUR 0.09/条 短信 (至 EU 国家) EUR 0.07/条 短信 (至其他国家/地区) EUR 0.29/条 可选额外套餐\r按需叠加数据/语音等选项。订阅型选项默认到期自动续订, 可在到期前随时取消。\nDayFlats (24 小时)\r套餐 有效期 流量 价格 DayFlat 10 GB 1 天 10 GB EUR 4.99 Unlimited DayFlat 1 天 无限流量 EUR 6.99 一次性数据选项 (7 天)\r套餐 有效期 流量 价格 一次性包 500 MB 7 天 500 MB EUR 2.99 一次性包 1 GB 7 天 1 GB EUR 4.99 一次性包 4 GB 7 天 4 GB EUR 9.99 数据订阅包 (28 天, 自动续订)\r套餐 有效期 流量 价格 订阅包 500 MB 28 天 500 MB EUR 2.99 订阅包 1 GB 28 天 1 GB EUR 4.99 订阅包 4 GB 28 天 4 GB EUR 9.99 订阅包 10 GB 28 天 10 GB EUR 19.99 国际数据包\r套餐 有效期 流量 适用地区 价格 瑞士数据包 1 GB 2 周 1 GB 瑞士 EUR 9.99 土耳其数据包 500 MB 4 周 500 MB 土耳其 EUR 9.99 语音 / 短信包 (28 天)\r套餐 有效期 内容 价格 100 单位 (分钟或短信) 28 天 100 分钟或短信 (共享配额) EUR 4.99 400 单位 (分钟或短信) 28 天 400 分钟或短信 (共享配额) EUR 9.99 说明: 语音/短信包为共享配额, 无需预先选择 \u0026ldquo;通话\u0026rdquo; 或 \u0026ldquo;短信\u0026rdquo;, 且可用于德国境内、拨打至欧盟国家以及拨打土耳其固话。\n漫游费用\r官网: Mit CallYa im Ausland telefonieren \u0026amp; surfen\n支持语音、短信、流量漫游\n漫游 (中国大陆) 接收短信 免费 发送短信 EUR 0.84/条 (EUR 0.49/条 中国移动网络) 接听来电 EUR 2.19/条 拨打电话 EUR 4.32/分钟 (EUR 3.65/分钟 中国移动网络) 漫游流量 EUR 0.94/50 KB Vodafone 的 CallYa 预付费卡可在国外正常使用, 支持在全球 155 个国家和地区拨打电话与发送短信。目前官方未对国际漫游的使用时长作出限制说明。具体资费可参考 官方费率表\n保号规则\rVodafone DE 的 CallYa 预付费卡需定期保持账户活跃防止号码被注销。查看条款\n每 90 天 账户需有余额变动 (消费或充值) 以保持号码有效 如果 90 天内无任何余额变动, Vodafone 将通过短信通知, 提示号码即将停用 在收到短信后的 4 周内 未作出回应, 号码将被永久注销 被停用或注销后, 仍可联系 Vodafone 客服申请提取剩余余额。同一账户下的多个号码之间也可免费互相转移余额。\n可以在官网每 90 天手动充值一次以保持号码有效, 最低充值金额为 5 欧元, 支持信用卡或 PayPal 支付, 无需 IBAN 账户。相较其他方式, 保号成本略高。\n此外, 在关闭漫游和关闭移动数据的情况下, 还会出现 偷跑流量 的情况, 在 iOS 和 Android 系统上都遇到了, 充值的 5 欧元 3 天就被跑没了。可联系 Vodafone 客服彻底关闭移动数据功能, 以避免不必要的流量消耗。\nIBAN 保号法\r💡 德国 Vodafone 电话卡独有功能 IBAN 转账充值。\nCallYa 预付费卡支持通过 IBAN 转账充值, 这在运营商中极为罕见。如果你拥有 iFast、Wise、N26 或 Revolut 等具备欧盟 IBAN 的银行账户, 可设置定期转账来保持账户活跃, 从而实现 自动保号\n最低充值金额仅需 EUR 0.01 / 季度, 全年保号成本约 人民币 4 毛钱, 是目前成本最低、最便捷的保号方式。\nVodafone IBAN 转账信息 (来自官网)\nName: Vodafone GmbH Deutsche Bank AG Düsseldorf IBAN: DE68 3007 0010 0250 8000 00 BIC: DEUTDEDDXXX Reference: 016xxxxxxxx (需填写完整的德国沃达丰手机号, 包含开头的 0) 使用 Wise 或 N26 的自动定期转账功能, 每月或每季度自动汇入 EUR 0.01 至 Vodafone 账户, 即可满足余额变动要求。\n经实测, 转账备注 (Reference) 填写手机号或客户编号均可成功到账, 推荐填写手机号, 相较于客户编号更加有辨识度。通常需等待约 1～2 天 到账\n汇款时, 收款方名称填写 DE26ZZZ00000006194 也可成功。\n最后, 虽然没有最低转账金额限制, 但建议不要长期使用 0.01 这样极小的金额, 以免触发系统异常或人工审核。推荐每次充值 1 欧元 更为稳妥。\nVodafone eSIM 申请攻略\r德国 Vodafone 已于 2025 年 4 月 正式下架 CallYa Classic 套餐, 并以全新的 CallYa One 套餐取代\n目前, 饱受大家所推崇的 CallYa Classic 已无法通过官方渠道直接申请, 但仍可偷渡办理。先开通 CallYa One 套餐, 再把套餐更改为 CallYa Classic。以下是详细操作流程。\n前置条件\r本人有效护照 支持 eSIM 的手机 任意德国地址 (仅作注册用途, eSIM 无需收件或地址验证) 建议使用 德国 IP 访问官网以提高申请成功率 购买方式\r前往 Vodafone 官网 查看 Prepaid (预付费) 套餐\n选择 CallYa One 套餐。页面为德文, 可参照下图逐步填写。\n选择 eSIM 版本\n是否需要携号转网。如果从其他运营商转入, 原运营商将收取 EUR 6.82 手续费, Vodafone 会返还 EUR 10 欧元 话费余额\n是否为 Vodafone 或 Otelo 的现有客户。如果是已使用 3 个月以上的现有客户, 可免去实名验证流程。\n填写个人信息 (稍后视频实名验证会用到)。地址找个真实的德国住宅地址, 视频验证时可能需要你用德语或英语读出来。\n填写邮箱获取验证码, 同时用于接收 eSIM 激活信息邮件\n创建一个 PDF 密码, 用来访问包含 eSIM 信息的 PDF 文档\n仅允许使用 大写字母和数字 长度 6～20 位 不含特殊符号 例如: CALLYA1 实名认证\r自 2017 年 7 月 起, 德国所有新的预付费 (Prepaid) 用户都必须进行实名验证。\n官方说明详见: Vodafone CallYa 实名注册流程\nVodafone 提供以下四种实名认证方式 (任选其一)\nAutoID 自拍验证 在线 eID 验证 (德国身份证或电子居留证) 视频通话验证 (Online via video call) 邮局现场验证 (In a post office) 在下单购买时, 建议选择 AutoID 验证方式。验证成功后, Vodafone 才会发送 eSIM 二维码。\n提交订单后将进入实名认证流程, 可选择 AutoID 或 Video chat 方式\nAutoID: 全程自助完成, 无需与人工互动, 也不需要英语或德语口语能力 Video chat: 需要与真人客服进行视频通话, 要求具备一定口语能力, 且不得使用翻译软件 视频认证 (Video chat) 通常包括以下步骤\n验证员会首先确认你是否是该账户的本人, 你需要回答 Yes 回答个人信息, 需与申请时填写内容一致 姓名 (Your full name) 生日 (Date of birth / Birthday) 护照号 (Passport Number) 年龄 (How old are you) 可能会让你 念出自己的德国地址 (Address), 请用英文 准确无误地读出 你在申请时填写的地址 护照验证 使用前置摄像头 手持护照首页, 在镜头前上下左右晃动, 确保光线反射清晰 按要求用两根手指遮挡护照照片区域, 再次晃动展示 切换到后置摄像头 (back camera / another camera / rear camera) 将镜头对准护照信息页, 等待拍照, 确保画面完整、无手指遮挡 拍摄完护照信息页后, 他会让你继续拍摄护照正面外观, 同样需要注意不能有遮挡 自拍人脸识别 按照提示, 切换回前置摄像头 (front camera) 系统或工作人员会要求你进行人脸自拍验证, 确保面部光线充足、五官清晰 这一步通常用于比对你本人与护照照片是否一致 确认与提交 所有照片拍摄完成后, 他会提示你稍候等待 随后将显示你填写的个人信息 (护照与地址等) 验证员会询问你信息是否正确 (关键词 correct), 回答 Yes, correct. 即可 确认无误后, 视频认证流程正式完成 Vodafone DE、O2 DE、N26 DE、AmEx DE 的视频验证步骤和问题都差不多\n手机下载 Postident 应用 App Store、Google Play\n打开应用后, 扫描二维码或手动输入编号进入验证流程\n按照提示依次完成以下操作, 完成认证\neSIM 激活\r实名认证通过后, Vodafone 会发送 3 封邮件, 其中一封邮件包含一个 PDF 附件。使用你在申请时设置的 PDF 密码打开该文件\nPDF 文件中包含手机号码、PIN 码、PUK 码、ePIN 确认码 (6 位数字)\n在支持 eSIM 的设备上扫描邮件里的二维码进行添加, 在激活过程中会要求输入 PDF 中的 ePIN 确认码以完成激活。\n注册 Vodafone 账户绑定号码\r前往 Vodafone 注册页面 按提示创建新账户 注册完成后, 进入 添加合同和手机号码 页面, 将号码绑定至账户 输入手机号码 (需以 0 开头) 及申请时设置的 PDF 密码, 随后进行短信验证码验证 绑定成功后即可查看账户信息 更改套餐为 CallYa Classic\r前往 套餐更改页面, 点击 Tarif ändern (更改套餐)\n在可选套餐列表中选择 CallYa Classic, 确认更改\n提交后, 新套餐将于当日生效\nUSSD 查询\r查询余额: 拨打 *100# 常见问题\r为什么会激活后额外扣除 0.29 欧元?\r激活后如果发现被额外扣除 0.29 欧元, 通常是由于 iMessag 触发了国际短信验证。\n如果使用 非国行 iPhone, 系统会自动尝试激活 iMessage, 并发送一条国际短信, 每条短信将扣除 0.29 欧元\n建议在扫描 eSIM 二维码前关闭 iMessage 和 FaceTime 功能。这样可以有效防止系统自动发送激活短信, 避免产生不必要的费用。\n原文\nVodafone DE CallYa 德国保号卡\n德国手机卡及运营商全攻略！和国内竟然有这么多不同？！\n高含金量德国eSIM手机卡：沃达丰CallYa免费开卡，0月租保号！\n德国沃达丰IBAN转账充值信息\n德国沃达丰 0.01 欧元自动保号方式\n充值可以直接用欧元转账\n","date":"2025-10-15T20:38:01+08:00","image":"https://blog.acesheep.com/p/sim-card-de-vodafone/cover_hu756276353410739675.png","permalink":"https://blog.acesheep.com/p/sim-card-de-vodafone/","title":"德国 Vodafone CallYa 保号卡"},{"content":"Vodafone Ireland 是爱尔兰三大实体移动网络运营商之一 (另外两家为 eir 和 Three Ireland)。其信号覆盖广泛、网络稳定, 在爱尔兰本地提供不限量的 5G 流量服务。\n作为欧洲旅行中最受欢迎的流量卡之一, Vodafone Ireland 仅需 20 欧元即可在 58 个欧洲国家和地区使用漫游服务, 其中包含非欧盟国家瑞士、挪威、列支敦士登、冰岛、英国 (以及海峡群岛、马恩岛)。套餐提供 40GB 的欧洲漫游流量, 非常适合跨国旅行者。\n套餐内容\r官网: Pay As You Go Plans | Sim Only | Vodafone Ireland\n官方 APP: App Store、Google Play\n套餐名称: Data Unlimited 5G\n月租: EUR 20\n项目 内容 本地语音 100 分钟 网内通话/短信 Vodafone 网内互打与短信无限量 本地短信 100 条 国际通话 100 分钟 本地数据 爱尔兰境内无限 5G 数据 欧盟/欧洲区漫游 40 GB 数据 + 本地套餐内的通话/短信额度可在欧洲区使用 eSIM 支持 有效期 4 周 单次充值大于等于 EUR 20 即激活/续期 (有效期 4 周)。到期前再次充值大于等于 EUR 20 立即重置, 未使用的剩余额度不会结转。\n当没有续费套餐的时候, 进入保号状态, 无其它费用\n漫游费用\r中国大陆漫游\r官网: Roaming in Europe\n支持语音、短信、流量漫游, 但官方不支持漫游状态使用 WiFi Calling\n漫游 (中国大陆) 接收短信 免费 发送短信 EUR 0.3/条 接听来电 EUR 2.02/分钟 拨打电话 EUR 2.02/分钟 漫游流量 EUR 4.99/天 可选漫游套餐\n套餐 有效期 流量 语音分钟 短信 价格 Red Roaming 1 天 500 MB (超出后 EUR 0.12/MB) 无限 无限 EUR 4.99/天 Global Explorer 500 1 天 500 MB 无 无 EUR 5/天 Roaming Weekly Data Pack 7 天 2.5 GB (2560 MB) 无 无 EUR 25/周 自 2017 年 7 月起, 新加入的 PAYG 用户默认启用 RED Roaming, 如果未开通 RED Roaming, 在欧洲以外地区将按 Rest of World 资费计费\nRed Roaming 开通与退订说明:\n更多信息: Red Roaming 官方页面\n开通: 发送 RED 至 50020 退订: 发送 STOP RED 至 50020 使用条件: 当用户在漫游时产生费用且余额充足时, 会自动订购 RED Roaming。退订后不会自动恢复, 需手动重新开通 WiFi Calling 说明\n官方参考: WiFi Calling 支持说明\n仅支持语音, 不支持短信 官方不支持漫游状态下的 WiFi Calling 实测仅检测手机地区, 不限制 IP, 可在飞行模式下使用 iRingo 或 Surge 修改以下地址返回值为 IE 后启用 https://gspe1-ssl.ls.apple.com/pep/gcc 欧洲漫游\rVodafone Ireland 的 Pay As You Go 用户在欧洲地区 (EU/EEA 成员国及指定区域) 可享受与本地相同的资费政策, 即 Roam Like at Home\n主要条款\n在欧盟及欧洲经济区 (EEA) 国家漫游时, 可使用与在爱尔兰境内相同的语音、短信及流量套餐 漫游期间拨打当地电话、发短信或访问互联网, 与在爱尔兰境内使用相同套餐额度, 不额外收费 可拨打: 漫游所在国的本地号码 其他欧盟/EEA 国家号码 爱尔兰号码 接听电话和接收短信均为免费 套餐内流量在欧洲漫游时可使用, 如果超过套餐包含的漫游流量上限 (通常为 40GB), 将按标准超额费率计费 如果超出套餐有效期或余额不足以续订套餐, 则无法继续使用漫游服务 限制说明\n欧洲漫游仅适用于短期旅行用途；如果检测到长期或主要在欧盟境外使用, Vodafone 有权限制漫游或收取额外费用 漫游流量可能会受到公平使用政策 (Fair Usage Policy) 限制, 以防止滥用 WiFi Calling 在漫游状态下官方不支持, 但本地网络通话与短信服务不受影响 适用国家/地区列表\r欧洲国家 (32 个)\n国家 (英文) 中文 国家 (英文) 中文 Austria 奥地利 Liechtenstein 列支敦士登 Belgium 比利时 Lithuania 立陶宛 Bulgaria 保加利亚 Luxembourg 卢森堡 Croatia 克罗地亚 Malta 马耳他 Cyprus 塞浦路斯 Netherlands 荷兰 Czech Republic 捷克 Norway 挪威 Denmark 丹麦 Poland 波兰 Estonia 爱沙尼亚 Portugal 葡萄牙 Finland 芬兰 Romania 罗马尼亚 France 法国 Slovakia 斯洛伐克 Germany 德国 Slovenia 斯洛文尼亚 Greece 希腊 Spain 西班牙 Hungary 匈牙利 Sweden 瑞典 Iceland 冰岛 Switzerland 瑞士 Italy 意大利 United Kingdom 英国 Latvia 拉脱维亚 Vatican State 梵蒂冈 欧洲海外领地与岛屿地区 (26 个)\n名称 所属国家 中文名 Azores 葡萄牙 亚速尔群岛 Madeira 葡萄牙 马德拉群岛 Canary Islands 西班牙 加那利群岛 Ceuta 西班牙 休达 (西属北非领地) Melilla 西班牙 梅利利亚 (西属北非领地) Guernsey 英国 根西岛 Jersey 英国 泽西岛 Isle of Man 英国 曼岛 Gibraltar 英国 直布罗陀 Aland Islands 芬兰 奥兰群岛 Mayotte 法国 马约特 (法属海外省) Reunion 法国 留尼汪 (法属海外省) French Guyana 法国 法属圭亚那 (法属南美洲) French West Indies 法国 法属西印度群岛 (加勒比地区) Guadeloupe 法国 瓜德罗普 (法属加勒比) Martinique 法国 马提尼克 (法属加勒比) Saint Barthelemy 法国 圣巴泰勒米 (法属加勒比) Saint Martin 法国 法属圣马丁 (法属加勒比) Désirade 法国 德西拉德岛 (法属加勒比) Saint Maarten 荷兰 荷属圣马丁 (荷属加勒比) Saint Eustatius 荷兰 圣尤斯特歇斯 (荷属加勒比) Saba 荷兰 萨巴 (荷属加勒比) Bonaire 荷兰 博奈尔 (荷属加勒比) Curacao 荷兰 库拉索 (荷属加勒比) Saint Kitts and Nevis 独立国家 圣基茨和尼维斯 Suriname 独立国家 苏里南 (南美独立国家, 前荷属) 保号规则\rVodafone Ireland 的 PAYG (预付费) 号码需定期充值以保持活跃状态 查看条款\n套餐有效期为 28 天 到期后如果账户余额不足以续订套餐, 号码将进入保号状态 (可维持 6 个月) 超过 6 个月未充值后, 号码将进入 Inactive 状态 (停用期 2 个月) 在 Inactive 状态下充值至少 EUR 5 可立即恢复号码, 并重新获得 6+2 个月的保号周期 如果 8 个月 (6 个月保号期 + 2 个月停用期) 内仍未充值, 号码将被永久停用 其他说明:\n如果一次性充值金额超过套餐月费, 将自动续订套餐 最低充值金额: EUR 5 激活使用\r购买方式\r官网免费邮寄 SIM 卡: Pay as you go SIM only 线下购买: 与英国不同, 爱尔兰的手机卡需在运营商门店购买。首次购买时需同时开通首月套餐, 实体卡免费且无需实名登记 注册账号与激活\r购买成功后, 可使用邮箱在 Vodafone Ireland 官网注册账户。完成邮箱验证后即可设置密码并登录账户\nUSSD 查询\r查询余额: 拨打 *174# 原文\nVodafone IE PayGo 爱尔兰保号卡\n","date":"2025-10-14T11:31:49+08:00","image":"https://blog.acesheep.com/p/sim-card-ie-vodafone/cover_hu1143089378019768182.png","permalink":"https://blog.acesheep.com/p/sim-card-ie-vodafone/","title":"爱尔兰 Vodafone PayGo 欧洲流量卡"},{"content":"EE (原名 Everything Everywhere) 是英国四大实体运营商之一, 由 T-Mobile UK 和 Orange UK 于 2010 年合并成立, 现为英国电信集团 (BT Group) 旗下品牌, 另外三家分别是 O2、Vodafone 和 Three UK\nEE 拥有英国覆盖最广、速度最快的移动网络, 是用户数量最多的运营商之一, 以优质的网络服务著称, 但资费相对较高。\n套餐内容\r官网: Best Pay As You Go SIM Deals \u0026amp; Offers | EE\n官方 APP: App Store、Google Play\n套餐名称: 20GB SIM £10\n月租: GBP 10\n项目 内容 本地通话 500 分钟 本地短信 无限量 本地数据 20 GB (前 6 个月含 12 GB 额外流量), 之后为 8 GB/月。速率上限 25 Mbps 流量结转 支持 Data Rollover (未用完流量可结转) 有效期 30 天 特点\n首次使用需购买套餐进行激活 保号状态, 月租为零 漫游费用\r官网: Roaming Costs | EE\n支持语音、短信、流量漫游, 不支持漫游 WiFi Calling\n漫游 (中国大陆) 接收短信 免费 发送短信 (文字) GBP 0.60/条 发送短信 (图片) GBP 0.48/条 接听来电 GBP 1.80/分钟 拨打电话 GBP 1.80/分钟 漫游流量 需购买 Roaming Pass 方可使用 (否则不可用) 可选漫游套餐 (Roaming Pass)\n流量 有效期 价格 50 MB 24 小时 GBP 5.22 150 MB 24 小时 GBP 10.45 300 MB 7 天 GBP 26.12 900 MB 7 天 GBP 52.25 保号规则\r至少每 180 天进行一次 \u0026ldquo;连接行为\u0026rdquo; (Connection action), 否则 SIM 卡将从网络中注销, 服务不可用, 手机号将被回收, 账户内剩余余额也会作废。\n计作连接行为的操作包括:\n拨打一次计费外呼电话 发送一条短信 为账户充值 购买任一个附加包 (Add-On) 查询官方保号规则路径:\n打开 EE 官网页面底部的 Terms and conditions 选择 Price Plans 选择 Pay as you go 找到 Currently available plans 在 PDF 文件中查找保号要求 激活使用\rEE 的手机卡需要先在英国本地连接基站信号完成激活, 之后才能在国外使用漫游服务\n充值\r充值要求\n官网快速充值 My EE - Anonymous Top up 最低充值 GBP 5 ","date":"2025-10-14T03:36:15+08:00","permalink":"https://blog.acesheep.com/p/sim-card-uk-ee/","title":"英国 EE 保号卡"},{"content":"Vodafone UK 是英国第三大运营商 (其余为 EE、O2 和 Three UK), 在国际漫游方面表现良好。为扩大市场份额, Vodafone UK 已收购 Three UK, 合并后将成为英国最大的移动通信运营商之一。\n相比 Giffgaff 和 CTExcel 等虚拟运营商 (MVNO, Mobile Virtual Network Operator), Vodafone UK 作为实体运营商具有一定优势, 也是目前已知唯一可偷跑转 eSIM 的英国预付费保号卡。\n套餐内容\r官网: Pay As You Go Plus | Vodafone UK\n官方 APP: App Store、Google Play\n套餐名称: Pay as you go 1\n月租: GBP 0\n项目 内容 本地通话 无限量 本地短信 无限量 本地数据 27 GB (前 3 个月含 19 GB 额外流量), 之后为 8 GB/月 价格 GBP 10 有效期 30 天 特点\n月租为零, 不使用不扣费；但 只要有任何使用 (不含接收免费短信), 将按 GBP 1/天 收费。查看条款 漫游状态下使用不扣费 支持 eSIM, 可自由转移至其他设备, 查看 eSIM 支持说明 必须在有信号的前提下才能删除本机 eSIM 删除后, 系统会自动发送新的 eSIM 二维码至邮箱 漫游费用\r官网: Roaming charge checker\n支持语音、短信、流量漫游, 不支持漫游 WiFi Calling\n漫游 (中国大陆) 接收短信 免费 发送短信 (文字) GBP 0.08/条 发送短信 (图片) GBP 0.66/条 接听来电 GBP 0.36/分钟 拨打电话 GBP 0.60/分钟 漫游流量 GBP 0.12/MB 可选漫游套餐 (Around the World Extra)\n套餐 有效期 流量 语音分钟 短信 价格 8 天 (数据包) 8 天 2 GB — — GBP 12.75 8 天 (组合包) 8 天 2 GB 100 分钟 100 条 GBP 18.00 15 天 (组合包) 15 天 4 GB 200 分钟 200 条 GBP 28.75 保号规则\r查看条款\n连续 90 天 未使用将收到提醒短信 180 天 内无任何余额变动, 号码将被停止服务 漫游使用限制 查看条款\n如果 漫游超过 62 天 且漫游使用量高于英国境内使用, 将被收取额外费用 (两周前通知) 通话: GBP 0.033/分钟 短信: GBP 0.01/条 数据: GBP 3.58/GB 激活使用\rVodafone UK 的手机卡需要先在英国本地连接基站信号完成激活, 之后才能在国外使用漫游服务\n购买方式\r官网免费邮寄 SIM 卡: Order a Free SIM Card 线下购买: 英国各大超市均有销售预付费空卡, 价格约为 GBP 1/张 其他购买渠道注意事项\n自 2024 年起, Vodafone UK 实体卡统一为绿色卡板, 需警惕商家以旧版红色卡板冒充 购买前务必询问卖家是否更换过号码。每位用户每年可免费更换号码 3 次, 之后每次需支付 GBP 25 如果卡号被更换过, 不建议购买 获取号码\r插入 SIM 卡后, 拨打 *#100#, 即可在手机上显示以 07 开头的 11 位英国手机号\niPhone 用户可在「设置 -\u0026gt; 蜂窝网络 -\u0026gt; SIM 卡」中查看号码\n充值\r充值要求\n官网充值 Vodafone Top Up, 点击 Top up online, 可使用大陆信用卡支付 网页最低充值 GBP 10, APP 内最低充值 GBP 5 可通过此链接为其他号码充值: Vodafone Top Up, 最低可充 GBP 5 💡 注意: 如果首次充值金额大于等于 GBP 10, 系统可能会自动购买套餐包。建议充值后联系客服要求退款, 并关闭自动购买功能。\nUSSD 查询\r查询余额: 拨打 *#1345# 查询套餐: 拨打 *#135# 常见问题\r(可选) 转为 eSIM\r先在官网注册账号: Vodafone 注册账号 激活实体 SIM 卡后等待约 24 小时 前往 SIM Swap 页面 申请转换为 eSIM 页面显示 SIM update successful 后, 约 5 分钟内邮箱会收到新的 eSIM 二维码 建议充值后再操作, 否则可能失败 提交转移申请后, 转移完成前不要刷新或关闭网页, 否则可能导致号码丢失 由于该功能属于偷跑, 联系客服可能只会得到 \u0026ldquo;暂不支持预付卡转 eSIM\u0026rdquo; 的回复 联系客服更换手机号码\r可在 My Vodafone APP 内联系客服申请更换号码 完成身份验证后, 客服可能会要求提供一个带邮编的英国地址以完善账户信息 每位客户每年可 免费更换号码 3 次, 超过次数后每次需支付 GBP 25 取消套餐\r联系客服说明不需要 Bundle 套餐包, 可申请退款至账户余额, 并要求关闭自动购买功能。\n原文\nVodafone UK PayGo 英国保号卡\n","date":"2025-10-12T20:45:58+08:00","image":"https://blog.acesheep.com/p/sim-card-uk-vodafone/cover_hu14781345499982310453.png","permalink":"https://blog.acesheep.com/p/sim-card-uk-vodafone/","title":"英国 Vodafone PayGo 保号卡"},{"content":" 卡片 大陆接打电话 大陆收短信 漫游流量 eSIM 最低年维护成本 hahaSIM ✅ ✅ ✅ ❌ 10 HKD Clubsim ❌ ✅ ✅ ✅ 6 HKD 3HK DIY 储值卡 ✅ ✅ ✅ ✅ 268 HKD 适合人群\nhahaSIM: 需要语音 + 收短信、低成本长期保号的人群 Clubsim: 仅需收短信、想要最便宜保号的人群 3HK DIY: 需要漫游流量、兼顾语音短信的人群 香港预付卡实名登记政策以运营商与监管公告为准\nhahaSIM\rhahaSIM 是由香港 3HK 与 丰泽 合作推出的旅游卡, 无合约, 无月租, 可在全球 100 多个国家漫游使用。在大陆使用中国联通信号, 不在香港使用无需实名。每年充值 20 HKD 并消费一次可延长一年有效期, 最低消费金额仅 10 HKD, 可长期使用。\n本地套餐: 33 HKD/月, 60 GB 流量 + 5000 分钟通话\n漫游套餐: 138 HKD/月, 15 GB 流量, 超出限速\n漫游套餐: 10 HKD/天, 超 500 MB 流量限速至 256 Kbps\n年费: 10 HKD\n运营商: 3HK、中国联通\n内含: 50 HKD 账户余额\n最低起充: 20 HKD\n大陆功能: 接打电话、收发短信、漫游上网\n实名方式: 护照、港澳通行证、香港身份证\n付款方式: VISA、Mastercard、AlipayHK、Apple Pay\n携号转网: 不支持\neSIM: 不支持\nClubsim\rClubsim 是香港 CSL 推出的子品牌, 无合约, 无月租, 但需实名认证。在大陆使用中国联通信号, 每年消费一次可延长一年有效期, 最低消费金额仅 6 HKD, 可长期保号。价格相对便宜, 但不可在大陆接打电话, 只能收短信。\n本地套餐: 20 GB 香港本地流量、20 HKD 7-Eleven 现金券、短信组合、流量漫游 2 天\n漫游套餐: 78 HKD/周, 超 500 MB 流量限速至 256 Kbps\n漫游套餐: 15 HKD/天, 超 500 MB 流量限速至 256 Kbps\n年费: 6 HKD\n运营商: CSL、中国联通\n最低起充: 6 HKD\n大陆功能: 收短信、漫游上网\n实名方式: 护照、港澳通行证、香港身份证\n付款方式: VISA、Mastercard、AlipayHK、微信、银联\n携号转网: 支持\neSIM: 支持\n3HK DIY 储值卡\r3HK DIY 储值卡 无合约, 无月租, 漫游流量可在中国大陆、香港、澳门使用, 在大陆使用中国联通信号, 不在香港使用无需实名。最低充值 20 HKD, 有效期按充值金额延长, 可长期使用, 适合需要在大陆漫游上网的用户。\n漫游套餐: 40 GB 通用漫游流量 + 5 GB 社交软件漫游流量 (Facebook、Instagram、WhatsApp、LINE、WeChat、Signal)\n漫游流量可用于: 内地, 香港, 澳门\n有效期: 一年\n年费: 268 HKD\n运营商: 3HK、中国联通\n最低起充: 20 HKD\n大陆功能: 接打电话、收发短信、漫游上网\n实名方式: 护照、港澳通行证、香港身份证\n付款方式: VISA、Mastercard、AlipayHK、支付宝、银联\n携号转网: 支持\neSIM: 支持\n如何延长储值卡有效期?\r如想延长储值卡有效期, 须以线上付款方式购买指定金额的服务或者充值, 如下\n金额 延长天数 HKD 20 至 49.9 30 天 HKD 50 至 99.9 90 天 HKD 100 至 199.9 180 天 HKD 200 或以上 365 天 储值卡有效期会由付款后起计自动延长。\n原文\n香港手机卡攻略！ hahaSIM、Clubsim、3HK 大湾区\n","date":"2025-10-11T04:00:40+08:00","permalink":"https://blog.acesheep.com/p/sim-card-hk/","title":"香港手机卡"},{"content":"\rSkinny 是新西兰的一家实体运营商, 隶属于老牌电信公司 Spark New Zealand Limited\nSpark 是新西兰第二大移动运营商 (第一大为沃达丰, 改名为 One NZ), 同时也是全国最大的宽带服务提供商。为了吸引年轻用户, Spark 于 2012 年 1 月推出了 Skinny 品牌, 主打价格实惠、服务灵活, 类似于中国移动当年的动感地带套餐。\n为什么选择 Skinny 电话卡？\rSkinny 是实体号段, 具有 无月租、收短信免费、保号便宜还简单 等优点, 非常适合用于注册 WhatsApp、Telegram、WeChat、Google、Twitter、ChatGPT、TikTok、Discord 等海外平台。\n与传统套餐不同, Skinny 电话卡激活后即可使用, 漫游免费, 无需实名或使用 Wi-Fi Calling, 也不用担心偷跑流量或语音信箱扣费的问题, 十分适合长期保号或国际用途。\n主要特点\n✅ 实体运营商, 非虚拟运营商\n✅ 0 月租, 激活后一年内免充值\n✅ 支持注册国外多数服务, 实体卡号段\n✅ 无需实名, 中国漫游免费, 收短信免费\n✅ 官网可付费换号, 每次 5 NZD 可选择 3A/4A 号码\n✅ 余额变动自动续期一年, 只需充值 5 NZD 或账户互转 1 NZD 即可保号 (互转余额 0 成本保号)\n漫游费用\r官网: Skinny Overseas Roaming 支持语音、短信、流量漫游 不支持漫游 WiFi Calling 漫游 (中国大陆) 接收短信 免费 发送短信 NZD 0.8/条 拨打漫游地内 NZD 2.3/分钟 拨打新西兰/语音信箱 NZD 1.15/分钟 拨打国际其他国家 NZD 2.3/分钟 接听来电 NZD 1.15/分钟 保号规则\rSkinny 电话卡激活后有效期为 一年, 在此期间无需充值即可免费接收短信。\n例如: 若于 2023 年 2 月 1 日 激活, 则有效期至 2024 年 2 月 1 日\n要继续使用, 只需在到期前充值 5 新西兰元, 或接收来自其他 Skinny 用户的 1 新西兰元余额转账, 即可将有效期 补满一年\n互转余额保号法\r💡 新西兰 Skinny 电话卡独有功能支持账户间余额互转。只要账户余额发生变动 (收款), 有效期会从当天起 自动顺延 12 个月\n如果你持有两个 Skinny 号码, 或你的朋友也在使用 Skinny, 那么可以通过 互转余额 的方式实现保号续期, 无需额外充值。\n举例说明\n手机号以 0 开头, 中间不要空格, 例如 0204338888\n当 手机号 A 转任意金额给 手机号 B 时, 手机号 B 的有效期将从转账日期起重新计算 12 个月\n⚠️ 注意事项\n有效期是 从转账当天重新计算 12 个月, 并非在 手机号 B 的原有效期基础上叠加。连续转账两次也不会延长至 24 个月\n网页操作\r打开 Skinny 官网 并登录账户 点击 Transfer Credit 输入对方手机号与转账金额 检查手机号是否输入正确 确认转账 手机 App 操作\r打开 Skinny App 并登录 点击底部导航栏的 More 然后选择 Send Gift 选择 Credit 输入对方手机号 点击减号修改金额后, 点 Confirm 完成转账 激活使用\riPhone 用户必看\r如果你使用的是 国行 iPhone, 在插入 SIM 卡时, 系统会弹出提示, 询问是否将该号码用于接收 iMessage\n建议选择 \u0026ldquo;不同意\u0026rdquo;, 以避免被扣费\n如果使用的是 非国行 iPhone, 通常不会出现此提示。需要注意的是, 每次插入 SIM 卡时, 系统都会自动尝试激活 iMessage, 并发送一条国际短信, 每条短信将扣除 0.8 新西兰元\n建议在插入 SIM 卡前关闭 iMessage 和 FaceTime 功能。这样可以有效防止系统自动发送激活短信, 避免产生不必要的费用。\n如何激活\r打开包装封贴, 取出 SIM 卡并插入手机。插卡后等待几分钟, 手机会自动搜索网络并显示信号, 显示任意运营商名称都属于正常现象。\n如遇无信号情况: 请耐心等待几分钟后重试。如果仍无信号, 可多次开关飞行模式或更换其他手机重新尝试。根据用户反馈, 经过多次尝试后均能成功激活。\nSkinny 电话卡有两种激活方式, 任选其一即可\n方式一: 官网激活\n打开浏览器访问 Skinny 注册账号 使用邮箱注册并登录账户 登录后点击 ACTIVATE ACCOUNT 输入卡片上的手机号码 (印在包装上) 输入收到的短信验证码后, 即可完成激活 方式二: APP 激活\n在 iOS 或安卓应用商店搜索并下载 Skinny Mobile 打开 App 输入手机号码并完成短信验证, 即可激活 📌 注意事项\nSkinny 电话卡激活不需要实名 电话卡的号码印在外包装上, 标记为 Your mobile number, 是以数字 0 开头的一串数字 外包装上包含 PUK 码 和 序列号, 请妥善保存或拍照备份 激活后, 卡片有效期为 一年, 无需充值即可使用 如何充值\rSkinny 电话卡最低支持充值 5 新西兰元, 可通过官网或手机 App 自助完成。仅支持 VISA、MasterCard 等外币信用卡\n如果没有信用卡, 也可以 联系我代充 或 互转余额 的方式完成充值。\n在 Skinny 官网或 Skinny App 使用外币信用卡充值 无信用卡用户可选择 代充 或 互转余额 📌 注意事项\n充值后, 卡片有效期将 从充值日期起重新计算 12 个月, 而不是在原有效期上叠加延长 即使连续充值两次, 也不会将有效期延长至 24 个月 如何查看有效期和余额\r你可以通过 Skinny 官网 或 手机 App 查询卡片的当前余额与有效期\n登录 Skinny 官网账户后, 页面中\nRemaining Credit: 显示当前账户余额 Expiry Date: 显示卡片有效期 打开 Skinny 手机 App\n右上角的 Credit 代表当前余额 点击右上角的小箭头可查看上次充值时间, 将该日期加上 12 个月即为有效期 更换手机号码\r需要先激活 Skinny 电话卡, 才可以在线选号。每次换号费用为 5 新西兰元 (NZD), 需使用信用卡在线支付 (不支持账户余额支付)\n打开并登录 Skinny 官网\n点击左侧菜单中的 Phone, SIM \u0026amp; Number\n点击 Pick a new number\n输入 2 到 6 位数字 (可作为你想要的靓号片段), 然后点击 Search for numbers 搜索可选号码\n选中喜欢的号码后, 用信用卡支付 5 NZD 完成选号\n支付成功后, 请关闭手机, 等待约 5 分钟再重新开机, 即可生效\n常见问题\r卡丢了怎么办？\r如果卡片意外损坏或丢失, 可以购买一张新卡, 然后联系 Skinny 官方客服将原号码转移到新卡上。\n在转移过程中, 需要向客服提供 旧卡的 PUK 码 和 序列号, 这些信息通常印刷在卡片外包装上。建议在收到卡片后 妥善保存外包装 或拍照留存, 以备后续使用。\n为什么拨打这个号码是空号？\r出现空号提示通常有以下几种原因\n卡片余额不足\n使用 Skinny 电话卡在漫游状态下接听电话会产生额外费用。如果账户余额不足, 来电将无法接通。请先确保电话卡已充值, 然后再次测试。如果来电未接听, 则不会产生任何费用。 拨号格式错误\n拨打国际号码时, 需添加新西兰的国家区号 +64, 并去掉号码前面的 0\n例如: 本地号码: 0204 xxx xxx 国际拨号格式: +64 204 xxx xxx 国内手机卡未开通国际通话或短信功能\n请确认你所使用的国内运营商已开通国际通信权限, 否则无法拨打或发送短信至海外号码 🌍 关于国际区号格式的热知识\r所有电话卡的号码都是面向本国, 优先在本国发售。在出厂时都以本地格式显示, 一般不会包含国际区号。\n如果你在 新西兰以外的国家 向新西兰号码发送短信或拨打电话, 需要将开头的 0 替换为 +64, 正确格式: +64 204 xxx xxx\n🎄 长按数字键 0 通常可打出 + 号, 如果设备不支持 +, 可使用 00 代替, +64 与 0064 效果相同\nVoicemail 语音信箱需要关吗, 会不会扣费？\r不需要关闭, 也不会自动扣费。\nSkinny 的语音信箱只有在你 主动拨打并收听语音留言时 才会产生费用, 如果你不收听, 则 不会扣费\n能注册 WeChat 吗？\rSkinny 电话卡可以正常注册 WeChat, 注册请求会经过新加坡服务器。不过, 新注册账号需要养号, 否则大概率会被风控从而封号。\n为降低风险, 建议遵循以下做法\n安卓用户请使用 Google Play 商店版 WeChat 将手机系统语言设置为英文 注册与使用过程中保持 同一地区的 IP, 避免频繁切换 (如中国、美国、香港之间反复切换) 初期尽量只添加同一地区 IP 下的老 WeChat 账号, 避免频繁添加不同地区的好友 总之, 要尽量模仿一个正常外国人的行为, 避免异常。新账号需要养号多久目前暂无明确标准。\n收不到 LINE 短信验证码怎么办？\rSkinny 可以注册 LINE, 已有许多用户成功验证。如果你收不到验证码, 通常是因为 当前网络 IP 的质量不佳, 被判定为高风险或代理 IP\n你可以使用以下两个网站检测你的 IP 质量\nScamalytics - 欺诈风险检测 IPQualityScore - 代理与风险检测 请注意, 这两个工具的检测算法不同, 可能出现一个显示 \u0026ldquo;低风险\u0026rdquo; 而另一个显示 \u0026ldquo;高风险\u0026rdquo; 的情况。建议分别检测并综合判断 IP 质量后再尝试重新获取验证码。\n收不到 TIKTOK短信验证码怎么办？\r如果收不到 TikTok 的短信验证码, 可以尝试以下方法:\n仅插入 Skinny 电话卡 (不要双卡同时使用) 关闭手机定位功能 重新下载 TikTok 应用 (建议从官方应用商店获取) 如果仍未收到验证码, 可尝试 更换网络节点 后再次验证 ","date":"2025-10-09T23:27:47+08:00","permalink":"https://blog.acesheep.com/p/sim-card-nz-skinny/","title":"新西兰 Skinny 保号卡"},{"content":"M1 卡种类说明\rIC (Integrated Circuit) 卡由法国人 Roland Moreno 于 1970 年发明。他首次把可编程的集成电路芯片封装到卡片中, 使卡片具备更多功能。\n术语 \u0026ldquo;IC 卡\u0026rdquo; 和 \u0026ldquo;磁卡\u0026rdquo; 属于技术分类, 不应与按用途命名的 \u0026ldquo;信用卡\u0026rdquo; \u0026ldquo;电话卡\u0026rdquo; 等混淆。\n国际上对 IC 卡有多种称呼: 英文中常见 Smart Card、IC Card; 在亚洲地区 (尤其是香港、台湾), 常称为 聪明卡、智慧卡、智能卡; 而在中国大陆, 一般简称为 IC 卡\n普通 IC 卡的 0 扇区不可修改, 其他扇区则可反复擦写。我们日常使用的电梯卡、门禁卡等, 发卡方通常采用被称为 M1 卡 的普通 IC 卡 (可理解为物业提供的母卡)\n下面介绍常见的 IC/ID 卡种类与特点。其他类型的 IC 卡都是后门卡, 可通过特殊写入方式修改 0 扇区, 从而实现对母卡的复制。\n卡类型 芯片名称 / 示例 频率 是否可重复擦写 备注说明 IC卡 M1 卡 13.56 MHz ✘ 普通授权卡, 0 扇区出厂被锁定, 不能用于复制, 只能作为授权卡 (物业等发放的母卡) IC卡 UID 卡 13.56 MHz ✔ 经典可擦写复制卡；遇到带防火墙的读卡器时会失效 IC卡 CUID 卡 13.56 MHz ✔ 可穿透读卡器防火墙的可擦写复制卡；在 UID 卡复制但刷卡无效时可作为替代 IC卡 FUID 卡 13.56 MHz ✘ 一次性写入并穿透防火墙的卡: 0 扇区只能写入一次, 写入后会变为普通 M1 卡 (不可逆) IC卡 UFUID 卡 13.56 MHz ✘ 兼具 UID 与 FUID 特性: 未锁卡时表现为可写的 UID, 手动锁卡后变成不可擦写的普通卡 (锁定不可逆) IC卡 GTU 卡 13.56 MHz ✔ 支持数据自动复位的复制卡, 用于对抗滚动码防复制系统；上电后能恢复预设数据, 支持反复擦写与调试 IC卡 GDMIC 卡 13.56 MHz ✔ 与 GTU 功能类似的滚动码复制卡 (厂商不同) ；用于绕过滚动码保护, 支持自动复位与重复擦写 ID卡 T5577 / EM4305 / 5200 等 125 kHz ✔ 常见的可擦写 ID 卡, 便于复制与仿写, 广泛用于考勤、门禁等低频场景 ID卡 F8268 卡 125 kHz ✔ 能穿透 ID 卡读卡器防护的复制卡；在普通复制后刷卡无效的情况下可尝试使用 各卡类型详解\rUID 卡 (国外称 GEN1)\rUID 卡是常见的可复制卡。遇到带防火墙的读卡器就会失效。此类读卡器在刷卡时会默认向卡发送后门指令修改卡号, 导致复制卡只能使用一次, 刷过一次后便无法再次被使用。通过比对卡片在刷卡前后的 UID 是否被修改, 可以判断读卡器是否带防火墙。\n另外, 只有读卡器能够发出这些后门指令, 因此 UID 卡的卡号和免密写操作只能由读卡器完成, 无法通过手机直接修改。如果写入时数据出现错误, 支持后门指令的读卡器还可以通过后门指令强行格式化卡片, 将其救活\nCUID 卡 (国外称 GEN2)\rCUID 卡是一种可擦写且能防屏蔽的复制卡, 支持对所有扇区的重复擦写。当门禁读卡器带有防火墙时, 就可以使用 CUID 绕过防火墙；CUID 无需执行锁卡操作即可防屏蔽 (不同于需要锁卡才生效的 FUID 或 UFUID)\nCUID 卡不响应读卡器的后门指令, 卡号可直接用常规指令修改, 因此也可以通过手机写卡。但正因不响应后门指令, 一旦写入过程中发生数据错误, 卡片将直接报废。\nFUID 卡 (国外称 GEN2)\r不可擦写防屏蔽卡, 此卡的特点是 0 扇区只能写入一次, 写入一次后FUID就变成普通 M1 卡, CUID卡绕过防火墙失败的话可以使用FUID尝试。\nUFUID 卡\r高级复制卡, UFUID 可视为 UID 与 FUID 的结合体: 在未执行 锁卡 操作前表现为 UID 卡；执行锁卡后便永久变为普通 M1 卡, 该过程不可逆。\nGTU / GUID / GDMIC 卡\r这类卡用于对抗滚动码 (rolling code) 机制的门禁/电梯系统。GTU 卡在锁卡后数据不再改变, 每次上电都会恢复到锁卡前的数据, 从而干扰滚动码系统的正常滚动逻辑, 实现对滚动码系统的破解。GTU 卡可解锁, 解锁后可通过专用指令修改数据。\n知识延伸\rIC 卡中 0 扇区 0 块 的第 6 字节通常用于表示芯片类型。常见 SAK (Select Acknowledge) 类型示例\n普通 IC 卡 SAK 类型: 08 CPU 模拟卡: 28 纯 CPU 卡: 20 原文\nID卡IC卡的复制卡种类介绍\n","date":"2025-10-09T05:18:24+08:00","permalink":"https://blog.acesheep.com/p/rfid-smartcard-overview/","title":"ID 卡 IC 卡的种类介绍"},{"content":"用别人的 DD 镜像, 重装完了还要自己手动安装软件、配置系统, 我觉得很麻烦。更糟的是, 如果向这些脚本作者提意见, 他们脾气比驴还倔, 甚至会骂你一顿。在 GitHub 上提建议往往没有回复, 作者直接就把问题关掉了。\n我曾经常用的 DD 脚本已停止维护, 在许多 VPS 上经常失联。于是, 我决定自己制作 DD 镜像和重装脚本, 目前支持 CentOS 7 和 Rocky 9\n为什么需要重装纯净系统？\r服务商提供的模板可能预装软件, 甚至与目标环境冲突 并非所有服务商都提供 ISO 挂载功能, 而通过 VNC / IPMI 安装速度往往过慢, 效率低下 长期使用过程中, Linux 系统可能出现一些难以排查的莫名错误 ⚠️ 注意事项\r数据会被清空, 请提前备份 仅支持 x86_64 架构 + GRUB2 引导 建议准备 VNC / IPMI 以便应急 支持通过 Web 页面实时查看安装进度, 开始安装后在 8080 端口 支持 512 MB 内存的小主机 ⚠️ 安装完成后, 根目录空间不会自动扩展\n请务必执行以下命令扩展系统磁盘\n# 扩展系统磁盘 bash \u0026lt;(curl -sL shell.puka.cc/lvm-disk-extend) 如果不放心我做的包怕里面藏了后门的话我也写了制作教程\n制作属于自己的 Linux DD 包: Rocky 9\n已测试成功的系统\r其他基于 RHEL / Debian 的系统理论上也可使用, 但未经过完整验证\nOpenCloudOS: 8、9 CentOS: 7.6、Stream 9 Ubuntu: 18.04.1 LTS、20.04 LTS、22.04 LTS、24.04 LTS Debian: 10.2、11.1、12.0 Rocky Linux: 9.4 默认配置\r安装完成后的系统默认配置:\n用户账户: root 默认密码: blog.acesheep.com 网络配置: 默认 DHCP, 静态 IP 需通过 VNC 手动配置 防火墙: 默认开启, 仅放行 22 端口 时区: Asia/Shanghai 使用方法\r进入选择菜单 (推荐)\nbash \u0026lt;(curl -sL shell.puka.cc/network-reinstall) 一键安装\n# 安装最新版 Rocky Linux 9 bash \u0026lt;(curl -sL shell.puka.cc/network-reinstall) --rocky-9 # 安装 CentOS 7 bash \u0026lt;(curl -sL shell.puka.cc/network-reinstall) --centos7 # 使用自定义镜像 URL bash \u0026lt;(curl -sL shell.puka.cc/network-reinstall) -dd \u0026#34;https://example.com/custom-image.xz\u0026#34; 常见问题\rQ: 安装过程中网络中断怎么办？\r自动重试 5 次, 仍失败则进入救援模式, 可手动执行 dd\nQ: 是否支持自定义镜像？\r支持。使用 -dd 参数指定镜像 URL (需为 XZ/GZ 格式原始磁盘镜像)\nQ: 安装失败如何恢复？\r执行 dd 后系统数据已被清空。若安装失败, 机器会进入救援环境, 此时可在该环境下手动执行 dd 进行安装\ncurl -L \u0026lt;url\u0026gt; | xz -dc | dd of=\u0026lt;disk\u0026gt; bs=4M curl -L \u0026lt;url\u0026gt; | gzip -dc | dd of=\u0026lt;disk\u0026gt; bs=4M Q: 是否支持 UEFI 启动？\r当前主要支持 BIOS/Legacy, UEFI 正在开发中\n","date":"2025-09-28T22:15:15+08:00","permalink":"https://blog.acesheep.com/p/network-reinstall/","title":"一键网络重装系统"},{"content":"在 Linux 系统下通过 LVM (Logical Volume Manager, 逻辑卷管理器) 扩展磁盘空间, 适用于常见的云服务器和虚拟机环境。\nLVM 是一种灵活的磁盘管理机制, 允许用户动态调整分区大小、合并或拆分存储空间, 极大提升了磁盘管理的灵活性。\n查看当前磁盘与分区信息\r说明:\nVultr 等 VPS 常用 virtio 驱动, 磁盘设备为 /dev/vda 如果是 IDE 驱动, 则为 /dev/sda DD 完的 Rocky 9 磁盘使用空间。硬盘总空间为 50 GiB, 但系统初始仅能用 3.0G\n[root@server ~]# fdisk -l Disk /dev/vda: 50 GiB, 53687091200 bytes, 104857600 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xac55217a Device Boot Start End Sectors Size Id Type /dev/vda1 * 2048 1050623 1048576 512M 83 Linux /dev/vda2 1050624 7340031 6289408 3G 8e Linux LVM [root@server ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 4.0M 0 4.0M 0% /dev tmpfs 982M 0 982M 0% /dev/shm tmpfs 393M 5.4M 388M 2% /run /dev/mapper/rl_server-root 3.0G 1.7G 1.3G 57% / /dev/vda1 448M 231M 218M 52% /boot tmpfs 197M 0 197M 0% /run/user/0 扩展 LVM 磁盘\r操作步骤:\n使用 fdisk 创建新分区 (vda3), 重启系统使分区表生效 将新分区初始化为物理卷 (pvcreate) 将其加入现有卷组 (vgextend), 实现卷组空间扩展。 扩展逻辑卷 (lvextend) 扩容文件系统 (resize2fs 或 xfs_growfs) 使用 fdisk 创建新分区\r使用 fdisk 在已有磁盘上创建一个新的主分区 vda3, 并占用磁盘所有剩余空间, 为后续 LVM 扩容做准备。\n完成分区操作后, 建议重启系统以使新分区表生效。重启后再继续进行 LVM 的后续操作。\n查看逻辑卷与卷组信息\r查看系统中的逻辑卷 (LV) 和卷组 (VG) 信息, 便于确认扩容目标。\nlvdisplay 记下根目录的逻辑卷名。这里是 root\n[root@server ~]# lvdisplay --- Logical volume --- LV Path /dev/rl_server/root LV Name root VG Name rl_server LV UUID oi22tV-mRCx-3HAD-GLQI-HzjU-wH8Z-86Gnl3 LV Write Access read/write LV Creation host, time server, 2025-09-24 00:01:11 +0800 LV Status available # open 1 LV Size \u0026lt;3.00 GiB Current LE 767 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:0 查看卷组 (VG) 信息\nvgdisplay 记下 root 所使用的卷组名, 这里使用的是 rl_server\n[root@server ~]# vgdisplay --- Volume group --- VG Name rl_server System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 2 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 1 Act PV 1 VG Size \u0026lt;3.00 GiB PE Size 4.00 MiB Total PE 767 Alloc PE / Size 767 / \u0026lt;3.00 GiB Free PE / Size 0 / 0 VG UUID IqoFnK-lWT3-jLmP-4a0j-iRbS-6sRj-eRRAsr 创建物理卷\r将 vda3 分区初始化为 LVM 可用的物理卷。\n[root@server ~]# pvcreate /dev/vda3 Physical volume \u0026#34;/dev/vda3\u0026#34; successfully created. 扩展卷组\r将新建的物理卷 vda3 加入到目标卷组 rl_server 中, 扩展卷组容量。\n[root@server ~]# vgextend rl_server /dev/vda3 Volume group \u0026#34;rl_server\u0026#34; successfully extended 查看卷组剩余空间\r确认卷组扩容后剩余的可用空间。\n[root@server ~]# vgdisplay --- Volume group --- VG Name rl_server System ID Format lvm2 Metadata Areas 2 Metadata Sequence No 3 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 2 Act PV 2 VG Size 49.49 GiB PE Size 4.00 MiB Total PE 12670 Alloc PE / Size 767 / \u0026lt;3.00 GiB Free PE / Size 11903 / \u0026lt;46.50 GiB VG UUID IqoFnK-lWT3-jLmP-4a0j-iRbS-6sRj-eRRAsr 可以看到现在 rl_server 多出了 46.50 GiB 的可使用空间\n此时卷组已拥有全部新空间, 可以选择全部分配给根分区, 也可以预留部分空间用于新建 swap 分区等。\n扩展逻辑卷与文件系统\r扩展逻辑卷 (LV) 并扩容文件系统, 使新增空间可被操作系统使用。\n扩展逻辑卷\r将卷组中的空闲空间分配给目标逻辑卷。\n# lvextend -L 扩展后逻辑卷该有的大小 /dev/卷组名/逻辑卷名 [-r] [root@server ~]# lvextend -l +100%FREE /dev/rl_server/root Size of logical volume rl_server/root changed from \u0026lt;3.00 GiB (767 extents) to 49.49 GiB (12670 extents). Logical volume rl_server/root successfully resized. 扩展文件系统\r扩展文件系统以识别并使用逻辑卷新增的空间。\n提示: 部分发行版支持在 lvextend 时直接加 -r 参数自动扩容文件系统。\next4 文件系统\rresize2fs -p /dev/rl_server/root xfs 文件系统\rxfs 文件系统, 扩容命令如下:\nxfs_growfs /dev/rl_server/root 本镜像使用 xfs 文件系统, 扩容命令如下\n[root@server ~]# xfs_growfs /dev/rl_server/root meta-data=/dev/mapper/rl_server-root isize=512 agcount=4, agsize=196352 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 bigtime=1 inobtcount=1 nrext64=0 data = bsize=4096 blocks=785408, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=16384, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 data blocks changed from 785408 to 12974080 至此, 系统分区已成功扩容\n验证扩容结果\r你可以通过 df -h 命令确认根分区已成功扩容。\n[root@server ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 4.0M 0 4.0M 0% /dev tmpfs 982M 0 982M 0% /dev/shm tmpfs 393M 5.4M 388M 2% /run /dev/mapper/rl_server-root 50G 2.0G 48G 5% / /dev/vda1 448M 231M 218M 52% /boot tmpfs 197M 0 197M 0% /run/user/0 一键自动扩容脚本\r如需自动化操作, 可直接使用如下脚本一键扩展, 无需手动执行上述所有步骤。\n# 扩展系统磁盘 bash \u0026lt;(curl -sL shell.puka.cc/lvm-disk-extend) 原文\n扩充DD后linux的使用空间\nLinux LVM的基本使用\n","date":"2025-09-28T01:22:55+08:00","permalink":"https://blog.acesheep.com/p/linux-extend-lvm-disk/","title":"Linux LVM 分区扩展磁盘空间"},{"content":"CentOS 7 陪伴了我 11 年, 稳定可靠, 但也终于走到了生命周期的尽头。原本打算升级到 CentOS 8, 却被 RHEL 的背刺劝退。于是出现了 AlmaLinux 和 Rocky Linux 两个继任者。经过一番对比, 我选择了 Rocky Linux, 并且已经用上 Rocky 9 两年了。最大的感受就是\n平滑迁移, 几乎没有大改动 系统依旧稳定, 延续了 CentOS 的传统 不过, 缺点也很明显: CentOS 的用户群体大量流失, 相关教程和资源少了许多。我常用的 DD 脚本也早已停止维护, 在很多 vps 上使用经常会造成失联。于是, 我决定自己动手制作 DD 包和自己的 DD 脚本。\n简单来说, 就是在 VirtualBox 创建个虚拟机, 装上 virtio 驱动, 配置好系统, 然后导出镜像, 再压缩打包成 DD 包。\n准备环境\r准备 VirtualBox\r下载 VirtualBox 并安装: VirtualBox 官方下载\n我们需要先用 VirtualBox 创建一个虚拟机, 并选择 VHD 作为硬盘格式。\n点击新建, 按提示设置虚拟机\n设置名称和 ISO 镜像位置 取消勾选 Proceed with Unattended Installation 这里保持默认即可\n为了提升安装和制作镜像的速度, 内存和 CPU 可以尽量分配多一些\n同时要取消勾选 Use EFI\n为了保证兼容性, 硬盘容量尽量越小越好\nCentOS 7 最小安装需要 3.5GB Rocky 9 最小安装需要 3.5GB 磁盘格式选择 VHD, 并勾选 Pre-allocate Full Size (固定大小 / 预先分配全部空间)\n完成后, 就可以启动虚拟机并进入系统安装流程\n安装并配置系统\r安装时, 网络建议选择 DHCP, 其他选项保持默认即可。\n硬盘分区\r分区建议如下\nsda1: /boot 分区, 大小 512MiB, 文件系统随意 (如 xfs) sda2: Linux LVM 物理卷, 使用剩余所有空间 (方便后续扩展磁盘) 在卷组 rl_server 上创建一个逻辑卷 root (名称可自定义), 挂载到 / 作为系统盘, 文件系统推荐 xfs\n完成分区后即可开始安装\n驱动支持\r安装完成后, 以 root 身份登录, 开始做最后的准备工作\n安装系统时生成的 initramfs 可能缺少虚拟化相关驱动, 这会导致某些 VPS 无法识别硬盘。因此, 在安装完成后, 需要确保系统中包含常见的 SCSI/虚拟化驱动, 以保证能够正常启动。\n编辑 /etc/dracut.conf, 加入以下内容\n# additional kernel modules to the default\radd_drivers+=\u0026#34;virtio virtio_scsi virtio_blk xen_blkfront xenfs xen_privcmd hv_storvsc hv_vmbus hv_utils mptspi scsi_transport_spi mptscsih mptbase\u0026#34; 说明:\nKVM: virtio、virtio_scsi、virtio_blk Xen: xen_blkfront、xenfs、xen_privcmd Hyper-V: hv_storvsc、hv_vmbus、hv_utils VMware: mptspi、scsi_transport_spi、mptscsih、mptbase 重新生成 initramfs\ndracut -f 验证是否成功, 有输出就行\nlsinitrd /boot/initramfs-$(uname -r).img | grep virtio 清理与优化\r在打包前, 需要清理系统, 避免冗余文件和隐私信息残留\n清理软件包缓存\nyum autoremove yum clean all 删除系统随机种子文件, 以避免镜像重复使用时生成相同随机序列\nrm -f /var/lib/systemd/random-seed 删除已有的 SSH 主机密钥 (避免镜像重复使用时冲突)\nrm -f /etc/ssh/ssh_host_* ll /etc/ssh/ 清理日志、历史记录和临时文件\nrm -rf /var/log/* rm -rf /tmp/* /var/tmp/* rm -f /root/.bash_history rm -rf .ssh .pki .viminfo anaconda-ks.cfg 清理磁盘以便压缩\ndd if=/dev/zero of=zero.tmp bs=1M status=progress sync rm -f zero.tmp sync 打包 DD 镜像\r关机后, 找到虚拟机的 .VHD 硬盘文件, 然后进行压缩打包。\n常见做法是使用 gzip 压缩为 .gz 格式, 但它是单线程的, 效率非常低。\n以 Rocky 9.6 系统盘 (3.5GB) 为例\n使用 gzip 压缩: 约 34 分钟, 生成文件大小 1.37GB 使用 xz 压缩: 仅 30 秒, 生成文件大小 1.22GB 因此, 推荐使用 7-Zip 压缩为 .xz 格式\n扩展磁盘空间\rDD 安装完成后, 磁盘空间并不会自动扩展, 可以参考 Linux LVM 分区扩展磁盘空间 手动执行\n或者使用脚本一键扩展磁盘\n# 重新生成 machine-id rm -f /etc/machine-id systemd-machine-id-setup # 扩展系统磁盘 bash \u0026lt;(curl -sL shell.puka.cc/lvm-disk-extend) 原文\n[教程]制作Linux的DD包\n","date":"2025-09-25T22:35:11+08:00","permalink":"https://blog.acesheep.com/p/create-linux-dd-image/","title":"制作属于自己的 Linux DD 包: Rocky 9"},{"content":"虽然现在已经有不少工具能实现接收短信并转发至 Telegram, 但总感觉差点意思。毕竟别人写的东西再怎么万能, 也不如自己写的顺手。很多奇思妙想, 只有自己亲手造轮子才能实现。\n网上常见的 Python 示例其实并不算完整\n只会监听新短信, 在脚本启动前收到的短信它不会去处理 对于分段短信 (长短信被拆成几条的那种), 它不会自动拼接, 还会乱序打印 所以, 干脆自己写一个: 既能支持多分段短信, 也能读取历史短信, 并在第一时间转发到 Telegram\n安装依赖\r不要使用 python-gsmmodem, 它已经不再维护。使用新的 python-gsmmodem-new\npip install python-gsmmodem-new pip install python-telegram-bot Python 文件部分\r收到短信后会自动转发至 Telegram\n文件名: python-gsmmodem-advanced-read.py\n#!/usr/bin/env python3 # -*- coding: utf-8 -*- from datetime import datetime from gsmmodem.modem import GsmModem, Sms from gsmmodem.pdu import Concatenation from telegram import Bot # ========== 配置区 ========== PORT = \u0026#39;/dev/ttyUSB0\u0026#39; BAUDRATE = 115200 PIN = None # SIM 卡 PIN (如果有的话) # Telegram Bot 配置 TELEGRAM_BOT_TOKEN = \u0026#39;你的 BotToken\u0026#39; TELEGRAM_CHAT_ID = \u0026#39;你的 ChatID\u0026#39; # 可以是个人 ID 或群 ID # SOCKS5 代理配置 request_kwargs = { \u0026#39;proxy_url\u0026#39;: \u0026#39;socks5://127.0.0.1:1080\u0026#39;, # 代理地址 \u0026#39;urllib3_proxy_kwargs\u0026#39;: { # 如果代理需要用户名密码, 填写这两个 # \u0026#39;username\u0026#39;: \u0026#39;proxyuser\u0026#39;, # \u0026#39;password\u0026#39;: \u0026#39;proxypass\u0026#39;, } } # ============================ concat_sms = {} bot = Bot(token=TELEGRAM_BOT_TOKEN, request_kwargs=request_kwargs) # 转发消息到 Telegram def send_to_telegram(text: str): try: bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=text) print(\u0026#34;Forwarded to Telegram\u0026#34;) except Exception as e: print(f\u0026#34;Telegram send failed: {e}\u0026#34;) # 处理单条短信, 包括长短信拼接 def handleSms(sms: Sms): concat = None message = None # 检查是否是长短信的一部分 if sms.udh: for i in sms.udh: if isinstance(i, Concatenation): concat = i break if concat: ref = concat.reference if ref not in concat_sms: concat_sms[ref] = {} concat_sms[ref][concat.number] = sms.text print(u\u0026#39;== Partial message received ==\\n[{0}/{1}] ref={2}\\n\u0026#39;.format( len(concat_sms[ref]), concat.parts, ref)) # 如果所有分段都收齐了 → 拼接 if len(concat_sms[ref]) == concat.parts: sortedParts = [concat_sms[ref][i] for i in sorted(concat_sms[ref])] message = \u0026#34;\u0026#34;.join(sortedParts) del concat_sms[ref] else: message = sms.text if message: out = (u\u0026#39;== SMS message received ==\\nFrom: {0}\\nTime: {1}\\nMessage:\\n{2}\\n\u0026#39; .format(sms.number, sms.time, message)) print(out) # 转发到 Telegram tg_text = f\u0026#34;📩 新短信\\n\\n来自: {sms.number}\\n时间: {sms.time}\\n\\n{message}\u0026#34; send_to_telegram(tg_text) # 可选: 保存到文件 # date = datetime.today().strftime(\u0026#39;%Y%m%d%H%M%S%f\u0026#39;) # with open(f\u0026#39;/path/to/messages/{date}.txt\u0026#39;, \u0026#39;w\u0026#39;) as f: # f.write(out) def main(): print(\u0026#39;Initializing modem...\u0026#39;) modem = GsmModem(PORT, BAUDRATE, smsReceivedCallbackFunc=handleSms) modem.smsTextMode = False modem.connect(PIN) # 启动时读取并删除存量短信 modem.processStoredSms(delete=True) print(\u0026#39;Waiting for new SMS message...\u0026#39;) try: # 无限等待, 但能响应 Ctrl+C modem.rxThread.join(2**31) except KeyboardInterrupt: print(\u0026#34;\\nProgram terminated by user (Ctrl+C)\u0026#34;) finally: print(\u0026#34;Closing modem...\u0026#34;) modem.close() if __name__ == \u0026#39;__main__\u0026#39;: main() 启动监听\r运行以下命令\n$\u0026gt; python3.6 python-gsmmodem-advanced-read.py Initializing modem... Waiting for new SMS message... 保持此进程在后台运行即可, 例如使用 screen\n原文\n接收短信并转发至 Telegram\nRead long SMS with python-gsmmodem (and send SMS with same running script)\n","date":"2025-09-14T16:32:45+08:00","permalink":"https://blog.acesheep.com/p/forward-sms-to-telegram/","title":"接收短信并转发至 Telegram"},{"content":"在常规的 TLS in TLS 代理中, 数据虽然被多层加密, 但每一层都会引入额外的包头。这种 \u0026ldquo;套娃加密\u0026rdquo; 带来的数据增量虽小, 却可能形成某些统计特征, 从而被防火墙识别。\n为了解决这一问题, XTLS 曾尝试通过减少额外加密来改善特征。而在 Xray 1.8.0 中推出的 Vision 流控, 则让绝大多数数据包保持原始特征, 几乎无可区分, 从而显著提升了隐蔽性。\n然而, 仅靠 TLS 并不能彻底避免端口封禁与指纹识别。为解决这一问题, Xray 在 2023 年 3 月推出了 REALITY 协议, 用来取代传统 TLS 服务。REALITY 能够有效消除服务端的 TLS 指纹, 保持前向保密性, 并且无需域名、证书或 443 端口, 即可伪装成任意目标网站。相比传统 TLS, REALITY 在安全性、便捷性和抗封锁能力上都更进一步。\n如果想了解更多详细信息, 请点击 Vision 查看\n各协议 2023 年现状\r内容来源 各协议 2023 现状\n协议 封禁情况 特点与备注 Shadowsocks (SS) 全随机数类流量几乎秒封 IP IPv6 封锁情况不稳定, 有一定几率可用 Trojan / WSS 一般隔天封端口；通过 Cloudflare 等 CDN 转发不封但干扰严重, 稳定性因地区而异 Trojan 和 WSS (WebSocket over TLS) 是常见的流量伪装技术, 但容易被检测到端口。使用 Cloudflare 可以隐藏真实 IP, 但可能面临运营商的干扰, 影响连接稳定性 TLS in TLS 单连接握手特征容易进黑名单 这种 \u0026ldquo;套娃加密\u0026rdquo; 在建立连接时, 其 TLS 握手特征容易被网络检测设备识别并加入黑名单。可以通过使用 Vision 实现 强制 padding 或 开启 mux 来缓解, 但需注意避免客户端配置错误导致 \u0026ldquo;猪队友\u0026rdquo; (即错误配置的客户端) 暴露特征 REALITY 即使有 TLS 握手特征, 如果 \u0026ldquo;偷白名单域名\u0026rdquo;, 通常不会被封 REALITY 协议通过伪装成访问白名单网站的流量, 来规避检测。但部分 IP 段 (如甲骨文云) 由于本身 IP 信誉较低, 即使采用此方法, 也可能连接不稳定或失败 Hysteria / TUIC 封禁与否因配置、地区不同；可能遭遇 QoS 限速 这些新协议的封禁情况 因人而异, 很大程度上取决于具体的配置和用户所在的网络环境。用户可能会遇到运营商的 QoS (Quality of Service) 限速, 导致使用体验差异较大, 稳定性不够 准备工作\r搭建最新的 VLESS Reality, 防止 VPS 端口被封, 需要准备以下条件\n一台可用的 VPS 一个符合条件的目标网站 (用来伪装) 在服务器上正确配置 Xray 获取 Reality 目标网站的方法\rReality 不需要你自己购买域名和证书, 因为它可以偷别人的域名。但并非所有域名都能用, 目标网站的选择会直接影响速度、连通性和稳定性。\n目标网站的标准\r目标网站最低标准是支持 TLSv1.3 和 H2 的国外网站, 域名非跳转使用 (有的主域名可能被用于跳转到 www)\n目标网站必须满足的条件:\n支持 TLS 1.3 协议 使用 X25519 签名算法 支持 HTTP/2 (H2) 协议 不使用 CDN 如果 Reality 目标网站使用 CDN, 数据将转发到 CDN 节点, 使你的 Reality 节点成为别人的反向代理加速节点 国外网站, 在中国境内不依赖任何代理可以可直连访问 加分项:\nIP 相近: 延迟更低, 流量特征更自然 支持 OCSP Stapling 合理的服务端配置 禁止回国流量 TCP/80 与 UDP/443 也进行转发 (Reality 对外表现为端口转发) 目标 IP 选用较冷门的更佳 ⚠️ 注意: 大家代理出现问题, 第一个需要检查的是目标网站是否存在问题\n方式 推荐等级 特点 风险 适用场景 偷自己的域名 ⭐⭐⭐⭐⭐ 自己控制域名和服务器, TLS 指纹完全可控, 最稳定 几乎无风险 有自己域名和网站时首选 偷邻居的域名 ⭐⭐⭐⭐ 同 ASN 下的域名, 速度和延迟几乎不受影响 有一定被识别风险 无自己域名时的次优选择 偷服务器所在地的大学/图书馆/旅游局等域名 ⭐⭐⭐ 本地公共机构域名, 可信度高 若网站被重点检测风险较大 特殊地区/无邻居可用时 偷测试站点测试出来的域名 ⭐⭐ 随机找到的 HTTPS 站点, 可临时使用 不稳定, 易失效 临时调试、过渡使用 偷大厂域名 ⭐ 各类互联网大厂 (如 Google、AWS、微软) 高风险, 极易被识别和封锁 不推荐 偷自己的域名\r如果你拥有自己的域名, 可以在服务器上部署一个 HTTPS 网站, 并将域名解析到这台服务器。这种方式是最佳选择, 速度、稳定性和可控性都最高。\n例如: 你的服务器在美国, 部署了你自己的网站 https://aaa.example.com, 那么直接使用 aaa.example.com 作为 Reality 的目标域名, 就是最佳选择。\n偷邻居的域名\r这种方法利用 bgp.tools 快速查找与你服务器处于同一网段 (或 ASN) 并解析到相近 IP 的网站, 因网络接近, 延迟通常很低 (延迟都在 1ms 内), 便于做快速验证证书。\n操作步骤\n打开 bgp.tools 在搜索框输入你的 VPS 的公网 IP, 回车 切换到 DNS 选项卡, 选择 Show Forward DNS (显示正向 DNS) 浏览列出的域名, 这是该网段或相邻 IP 当前解析到的域名列表 在搜索结果中, 然后挑几个域名, 并按照上面的 5 个条件逐一核对, 全都符合即可将此网站域名记录下来, 以供后续使用 偷服务器所在地大学、图书馆、旅游局的域名\r假设你的 VPS 在美国, 可以按照以下思路去找\n搜索美国比较有名的大学官网, 检查是否符合上述 5 个条件 搜索美国的图书馆官网 搜索美国的旅游局官网 这些网站通常稳定且长期可用\n偷测试过的域名\r可以利用第三方 SSL 测试平台的公开榜单来寻找域名。这种方法操作最简单, 但缺点是无法控制服务器位置, 速度和延迟大概率不理想。\nSSL Labs Security Headers 在这些平台找到 A+ 评级 的网站, 然后按照前面提到的 5 个条件逐一核对, 全部符合即可将该域名记录下来备用。\n偷大厂的网站\r有时可以使用苹果、微软等大厂的域名, 但并不适合所有人, 具体效果要看 IP 和地区。\n⚠️ 注意: 根据长期反馈, REALITY 出现问题往往有两个原因\nIP 太黑 (例如甲骨文的 IP 段) 目标域名选择不当 (如微软、苹果等大厂域名并不适合所有情况) # Apple gateway.icloud.com itunes.apple.com swdist.apple.com swcdn.apple.com updates.cdn-apple.com mensura.cdn-apple.com osxapps.itunes.apple.com aod.itunes.apple.com www.icloud.com # Mozilla download-installer.cdn.mozilla.net addons.mozilla.org # CDN / 云服务商 s0.awsstatic.com d1.awsstatic.com cdn-dynmedia-1.microsoft.com # Amazon images-na.ssl-images-amazon.com m.media-amazon.com # Google dl.google.com www.google-analytics.com # Airbnb www.airbnb.co.uk www.airbnb.ca www.airbnb.com.sg www.airbnb.com.au www.airbnb.co.in # 游戏 / 动漫 player.live-video.net # Amazon 直播 one-piece.com # 海贼王官网 lol.secure.dyn.riotcdn.net # 英雄联盟 www.lovelive-anime.jp # LoveLive 动漫 # 大厂 / 科技公司 www.microsoft.com software.download.prss.microsoft.com www.tesla.com www.swift.com www.nvidia.com academy.nvidia.com www.cisco.com www.samsung.com www.amd.com www.sap.com # 其他 wareval.com 如何检查目标网站\r在选择目标域名时, 需要确保其满足 5 个标准。那我怎么检查一个网站域名是否符合这 5 个标准呢？\n检查 TLS 1.3 支持\r打开目标网站, 按 F12 打开开发者工具 切换到 隐私与安全 选项卡 在「网络连接」信息中, 应显示 TLS 1.3、X25519 和 AES_xxx_xxx, 如下图所示 检查 HTTP/2 支持\r在开发者工具的控制台输入下面内容, 返回值应为 h2\nwindow.chrome.loadTimes()?.npnNegotiatedProtocol 检查 OCSP Stapling 支持\r你可以通过这个网站进行检测: ocsp stapling检测\n输入目标网站后, 即可查看其是否支持 OCSP Stapling\n💡 这只是一个加分项, 即使不支持, 对 Reality 的使用影响也不大。\n检查是否使用 Cloudflare CDN\r判断网站是否使用了 Cloudflare CDN, 只需在域名末尾添加 /cdn-cgi/trace 进行访问\n例如, 你要检查的域名是 https://codepen.io, 那么可以访问\nhttps://codepen.io/cdn-cgi/trace 如果页面显示 Cloudflare 相关的信息, 就说明该站点正在使用 Cloudflare CDN, 因此不能作为 Reality 的目标域名。\n检查中国境内连通性\r打开 ITDOG 在线 TCP Ping\n输入目标域名并指定端口 443, 然后点击「持续测试」\n等待测试结果, 不必等满 100 个包, 大致观察即可\n绿色: 网络质量非常好 绿色 / 黄色: 网络质量良好 只有红色: 100% 丢包, 代表这个省份无法访问这个网站 (被墙) 测试结果中, 只要中国境内没有任何省份出现 100% 丢包、网络质量全是红色情况, 就可以用\n💡 建议: 最佳情况是中国所有省份都可连通。但如果某些省份无法访问 (例如上海可访问而江苏不可访问), 而你确定不会在这些地区使用该节点, 那也没问题可以接受。\n使用工具批量检测\r手动逐个网站检查是否符合条件既繁琐又耗时。为了快速筛选, 可以借助小工具进行批量检测。\n例如, 使用 tls-checker, 运行后会自动检查目标站点是否满足 Reality 的各项要求, 并给出结果\n./tls-checker www.nvidia.cn:443 在服务器上搭建节点\r开启 BBR 加速\recho \u0026#34;net.core.default_qdisc=fq\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf echo \u0026#34;net.ipv4.tcp_congestion_control=bbr\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf sysctl -p 服务端配置\r{ \u0026#34;inbounds\u0026#34;: [ // 服务端入站配置 { \u0026#34;listen\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;port\u0026#34;: 443, \u0026#34;protocol\u0026#34;: \u0026#34;vless\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;\u0026#34;, // 必填, 执行 ./xray uuid 生成, 或 1-30 字节的字符串 \u0026#34;flow\u0026#34;: \u0026#34;xtls-rprx-vision\u0026#34; // 选填, 若有, 客户端必须启用 XTLS } ], \u0026#34;decryption\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;raw\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;reality\u0026#34;, \u0026#34;realitySettings\u0026#34;: { \u0026#34;show\u0026#34;: false, // 选填, 若为 true, 输出调试信息 \u0026#34;target\u0026#34;: \u0026#34;example.com:443\u0026#34;, // 必填, 格式同 VLESS fallbacks 的 dest \u0026#34;xver\u0026#34;: 0, // 选填, 格式同 VLESS fallbacks 的 xver \u0026#34;serverNames\u0026#34;: [ // 必填, 客户端可用的 serverName 列表, 暂不支持 * 通配符 \u0026#34;example.com\u0026#34;, \u0026#34;www.example.com\u0026#34; ], \u0026#34;privateKey\u0026#34;: \u0026#34;\u0026#34;, // 必填, 执行 ./xray x25519 生成 \u0026#34;minClientVer\u0026#34;: \u0026#34;\u0026#34;, // 选填, 客户端 Xray 最低版本, 格式为 x.y.z \u0026#34;maxClientVer\u0026#34;: \u0026#34;\u0026#34;, // 选填, 客户端 Xray 最高版本, 格式为 x.y.z \u0026#34;maxTimeDiff\u0026#34;: 0, // 选填, 允许的最大时间差, 单位为毫秒 \u0026#34;shortIds\u0026#34;: [ // 必填, 客户端可用的 shortId 列表, 可用于区分不同的客户端 \u0026#34;\u0026#34;, // 若有此项, 客户端 shortId 可为空 \u0026#34;0123456789abcdef\u0026#34; // 0 到 f, 长度为 2 的倍数, 长度上限为 16 ], \u0026#34;mldsa65Seed\u0026#34;: \u0026#34;\u0026#34;, // 选填, 执行 ./xray mldsa65 生成, 对证书进行抗量子的额外签名 // 下列两个 limit 为选填, 可对未通过验证的回落连接限速, bytesPerSec 默认为 0 即不启用 // 回落限速是一种特征, 不建议启用, 如果你是面板/一键脚本开发者, 务必让这些参数随机化 \u0026#34;limitFallbackUpload\u0026#34;: { \u0026#34;afterBytes\u0026#34;: 0, // 传输指定字节后开始限速 \u0026#34;bytesPerSec\u0026#34;: 0, // 基准速率 (字节/秒) \u0026#34;burstBytesPerSec\u0026#34;: 0 // 突发速率 (字节/秒), 大于 bytesPerSec 时生效 }, \u0026#34;limitFallbackDownload\u0026#34;: { \u0026#34;afterBytes\u0026#34;: 0, // 传输指定字节后开始限速 \u0026#34;bytesPerSec\u0026#34;: 0, // 基准速率 (字节/秒) \u0026#34;burstBytesPerSec\u0026#34;: 0 // 突发速率 (字节/秒), 大于 bytesPerSec 时生效 } } } } ] } 客户端配置\r{ \u0026#34;outbounds\u0026#34;: [ // 客户端出站配置 { \u0026#34;protocol\u0026#34;: \u0026#34;vless\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;vnext\u0026#34;: [ { \u0026#34;address\u0026#34;: \u0026#34;\u0026#34;, // 服务端的域名或 IP \u0026#34;port\u0026#34;: 443, \u0026#34;users\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;\u0026#34;, // 与服务端一致 \u0026#34;flow\u0026#34;: \u0026#34;xtls-rprx-vision\u0026#34;, // 与服务端一致 \u0026#34;encryption\u0026#34;: \u0026#34;none\u0026#34; } ] } ] }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;raw\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;reality\u0026#34;, \u0026#34;realitySettings\u0026#34;: { \u0026#34;show\u0026#34;: false, // 选填, 若为 true, 输出调试信息 \u0026#34;fingerprint\u0026#34;: \u0026#34;chrome\u0026#34;, // 选填, 使用 uTLS 库模拟客户端 TLS 指纹, 默认 chrome \u0026#34;serverName\u0026#34;: \u0026#34;\u0026#34;, // 服务端 serverNames 之一 \u0026#34;password\u0026#34;: \u0026#34;\u0026#34;, // 服务端私钥生成的公钥, 对客户端来说就是密码 \u0026#34;shortId\u0026#34;: \u0026#34;\u0026#34;, // 服务端 shortIds 之一 \u0026#34;mldsa65Verify\u0026#34;: \u0026#34;\u0026#34;, // 选填, 服务端 mldsa65Seed 生成的公钥, 对证书进行抗量子的额外验证 \u0026#34;spiderX\u0026#34;: \u0026#34;\u0026#34; // 爬虫初始路径与参数, 建议每个客户端不同 } } } ] } 注意事项\r内容来源\n如果你特别不想被封, 建议优先选择一个干净的 IP, 并且正确配置和使用 XTLS Vision\n不过, 即使这样做, 也无法保证 100% 不会被封。从去年底开始, 很多人的未知流量会导致 IP 秒封, 而 TLS in TLS 流量则常常在隔天被封端口。相比之下, XTLS Vision 并非未知流量, 并且完整处理了 TLS in TLS 的特征, 目前效果显著。但这并不代表它能确保绝对安全。认识到这一点非常重要, 不要因为偶然被封就大惊小怪。\n因为除了协议本身, 还有很多角度能封你。以 IP 为例, 你无法保证 IP 真的干净, 无法避免被邻居波及, 无法避免整个 IP 段可能被重点标记。某些地区的 GFW 判定标准不同, 比如某个 IP 只有少量用户访问, 却承载了大量流量, 也可能触发封禁。\n因此, 如果你的 XTLS Vision 节点被封, 而没有出现类似去年底那样的大规模被封报告, 建议依次尝试换端口、换 IP、换服务商。\n原文\n搭建最新的VLESS Vision和VLESS Reality防止VPS端口封禁\n无敌的 Xray – Reality 协议！Vless + Reality协议 + Vision流控，是否能够摆平一切顾虑！\nReality自建教程\nXTLS/REALITY: THE NEXT FUTURE\n","date":"2025-09-07T17:11:00+08:00","permalink":"https://blog.acesheep.com/p/xray-reality-protocol/","title":"Xray Reality 自建教程"},{"content":"先说结论\n在大阪难波爱电王总店入手 Tiger 虎牌电饭煲 JRX-G100WG (5.5合), 最终到手价 3802 元人民币\n电饭煲怎么买？\r本地版 vs 国际版\r日本的电饭煲主要分为国际版和本地版:\n国际版: 出口用, 电压支持 110-220V 宽电压, 看似方便, 但通常有减配, 性能和用料比不上给自己人用的 本地版: 最好, 没有缩水, 就是电压只支持 100V。解决方案也很简单——配个变压器就行 变压器的选择:\n2000W 铝芯款, 大概 200 人民币, 只给电饭煲用就够 3000W 纯铜款, 大概 550 人民币, 稍贵, 但后续有其他美国、日本电器也能共用, 一步到位 既然都来日本买电饭煲了, 那当然要买本地版顶配\n虎牌 vs 印象\r电饭锅有两个品牌的旗舰型号可选:\n虎牌 Tiger JRX-G100 象印 NW-FC10 两台都只支持 100V 电压。最后我选择了虎牌, 原因很现实: 体积\n象印那台实在太大, 28 寸的箱子根本塞不进去, 带不回国；虎牌刚刚好能放下, 而且是连原包装都没拆开直接塞进去的, 大概 11kg 重。顺手又买了点大米和矿泉水, 把行李撑到 22.3kg, 刚好卡在托运行李额度里。\n微信支付 vs 信用卡\r来之前稍微做了点支付功课, 结果笑出了声\n做过一点攻略的朋友可能知道微信的 5 星汇率, 某些博主只会抄文案, 还一本正经写着:\n\u0026ldquo;我一下飞机就去便利店分 5 次结账刷微信 5 星汇率！再去结账买东西省了 xxx 万元\u0026rdquo;\n实际情况呢？我特地在同一时间对比了一下\n微信 5 星汇率: 4.9771 银联信用卡汇率: 4.91 (更低！), 更别提信用卡还有 2-3% 返现 结论: 用微信反而更亏, 还被当枪手给他们打广告, 简直 \u0026ldquo;花钱帮微信做推广\u0026rdquo;\n虎牌 JRX-G100 到手价怎么算\r先去 Bic Camera 或 爱电王 的官网查看你想要的电饭煲官网价格, 心里有数后再去线下\n大阪难波这边, Bic Camera 对面就是爱电王, 可以直接对比\n线下店的价格\n银联优惠汇率 4.91, 到手价格如下\n店铺 含税标价 (日元) 免税优惠 额外优惠 返现 最终价格 (约人民币) 爱电王 99,800 -10% 家电产品优惠 -7% + 携程返现 -5% 信用卡返现 -3% 3802 元 Bic Camera 113,540 -10% 店内优惠 -5% 信用卡返现 -3% 4572 元 算下来, 爱电王明显更便宜, 比 Bic Camera 足足便宜了 770 人民币。不过价格每天都会波动, 所以买之前最好还是先查一下最新价。\n日本大米\r日本大米, 这个不得不说一下。\n起初只是在中部国际机场随便吃了一份鳗鱼饭, 结果被米饭的口感狠狠震撼到——又软又糯, 还带回甜。于是心想, 回国前要不要顺手带点日本大米试试。没想到一查资料, 又被震撼了一次: 小小的日本, 居然有 73 种大米品种\n他们甚至把大米的口感做了分类: 按照 \u0026ldquo;硬朗/软糯\u0026rdquo; \u0026ldquo;甘甜/清爽\u0026rdquo; 划分风味坐标。\n这么多品种的米不是都给家里煮饭的, 有的主要用于超市饭团, 有的用在便当, 还有的专门做寿司。不同用途配不同大米品种, 这样口感不一样, 日本人真是贼讲究。\n电饭煲除了煮白米饭以外还支持其他米\n所以如果只考虑家里吃饭, 选择范围就没那么夸张了。\n问了几位留学生, 大家一致推荐的首选就是「鱼沼产越光」。它也是日本经常缺货、限购的明星品种。\n日本大米推荐品种\r品种 (日文名) 中文名/产地 特点与口感 推荐理由 魚沼産コシヒカリ 鱼沼越光米 (新潟) 软糯香甜、黏性强、口感圆润 日本米之王, 殿堂级代表, 必试 ゆめぴりか 梦美人 (北海道) 光泽好、黏润顺滑、甜味柔和 北海道代表米, 口感媲美越光 つや姫 光姬 (山形) 粒粒分明、口感清爽、米粒漂亮 高颜值, 清爽弹性, 近年人气很高 あきたこまち 秋田小町 (秋田) 甜味明显、黏性适中、耐冷性强 东北经典, 好吃又耐煮 ミルキークイーン Milky Queen (关东/关西) 黏性极高, 比越光更糯, 饭粒柔软 特色口感, 喜欢软糯必选 青天の霹靂 青天霹雳 (青森) 米粒大、香气清爽、口感平衡 新兴高端品种, 清爽不腻 雪若丸 雪若丸 (山形) 饭粒硬挺、颗粒感强、咀嚼感好 山形新一代品牌米, 适合爱偏硬口感 因为是第一次尝试日本大米, 就随便选了几个品种回去体验, 算是有个初步印象\nつや姫 (光泽姬, 山形县产): 口感没有特别明显的区别 ゆめぴりか (梦美人, 北海道产): 口感同样没有特别明显的区别 コシヒカリ (越光, 滋贺县产): 买到的不是鱼沼产, 在包装正面没标注产地 (其他几款的产地标注在了正面)。口感和国内大米挺像, 算是找到了平替 ミルキークイーン (米露皇后, 富山县产): 非常软糯, 有点像糯米的口感, 但不会黏到那种程度, 很特别 在写总结时才发现, 自己居然和 魚沼産コシヒカリ 错过了\n小科普: こしひかり vs コシヒカリ\r很多人会注意到包装上有时写「こしひかり」, 有时写「コシヒカリ」\n其实它们指的都是同一个品种——越光米 (Koshihikari)\n区别只在写法:\nこしひかり: 平假名, 显得柔和、亲切, 常见于超市包装。 コシヒカリ: 片假名, 更正式, 常见于品种名或农协标识。 在日本, 很多农产品名、品牌名会同时存在 \u0026ldquo;假名不同写法\u0026rdquo; 的情况, 意思完全一样, 没有本质区别。\n当然, 文章里展示的超市米价相对偏贵。实际上, 在米店里购买会便宜很多。比如我在大阪 Life 京桥店看到的价格, 就比超市明显实惠。\n原文\n好みやシーンに合わせて炊き分け | 炊飯器 | Panasonic\n","date":"2025-05-18T19:35:49+08:00","permalink":"https://blog.acesheep.com/p/how-to-buy-japan-rice-cooker-and-rice/","title":"从日本买电饭锅和大米"},{"content":"在某些场景下, 我们可能不希望系统占用额外内存用于 kdump (Crashkernel), 例如在内存受限的虚拟机中。\n为什么要禁用 kdump\r开启 kdump 后在 1024MB 内存的虚拟机中只剩下 765 MB 的可用内存, 浪费系统内存 安装系统时禁用 kdump, 但更新内核时又会重新启用 (这是一个 RHEL 上游的 bug) 检查当前 crashkernel 状态\r使用 dmesg 命令检查当前内核启动参数和 crashkernel 预留内存\n[root@rocky9 ~]# dmesg | grep -i crash [ 0.000000] Command line: BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.14.0-570.17.1.el9_6.x86_64 root=/dev/mapper/rl-root ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rl-swap rd.lvm.lv=rl/root rd.lvm.lv=rl/swap [ 0.003027] crashkernel reserved: 0x0000000027000000 - 0x0000000033000000 (192 MB) [ 0.007620] Kernel command line: BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.14.0-570.17.1.el9_6.x86_64 root=/dev/mapper/rl-root ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rl-swap rd.lvm.lv=rl/root rd.lvm.lv=rl/swap 从输出可以看到, 系统默认预留了部分内存用于 crashkernel\n使用 grubby 禁用 crashkernel\rRocky Linux 9 使用 grubby 管理内核启动参数。可以通过以下命令将 crashkernel 设置为 no\n[root@rocky9 ~]# grubby --update-kernel=ALL --args=\u0026#34;crashkernel=no\u0026#34; 然后可以验证内核参数是否生效\n[root@rocky9 ~]# grubby --info /boot/vmlinuz-$(uname -r) index=1 kernel=\u0026#34;/boot/vmlinuz-5.14.0-570.17.1.el9_6.x86_64\u0026#34; args=\u0026#34;ro resume=/dev/mapper/rl-swap rd.lvm.lv=rl/root rd.lvm.lv=rl/swap crashkernel=no\u0026#34; root=\u0026#34;/dev/mapper/rl-root\u0026#34; initrd=\u0026#34;/boot/initramfs-5.14.0-570.17.1.el9_6.x86_64.img\u0026#34; title=\u0026#34;Rocky Linux (5.14.0-570.17.1.el9_6.x86_64) 9.6 (Blue Onyx)\u0026#34; id=\u0026#34;6b59b1d289ec44c4bb346a1add32b8c9-5.14.0-570.17.1.el9_6.x86_64\u0026#34; 可以看到 args 中已包含 crashkernel=no\n重启并验证\r重启系统后, 再次查看内核启动参数\n[root@rocky9 ~]# dmesg | grep -i crash [ 0.000000] Command line: BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.14.0-570.33.2.el9_6.x86_64 root=/dev/mapper/rl-root ro resume=/dev/mapper/rl-swap rd.lvm.lv=rl/root rd.lvm.lv=rl/swap crashkernel=no [ 0.011807] crashkernel: memory value expected [ 0.026396] Kernel command line: BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.14.0-570.33.2.el9_6.x86_64 root=/dev/mapper/rl-root ro resume=/dev/mapper/rl-swap rd.lvm.lv=rl/root rd.lvm.lv=rl/swap crashkernel=no 从输出可以看到, 系统不再为 crashkernel 预留内存\n恢复默认设置 (可选)\r如果未来需要恢复 crashkernel 设置, 可以使用\ngrubby --remove-args=\u0026#34;crashkernel=no\u0026#34; --update=ALL 原文\nHow do I remove crashkernel from cmdline?\n","date":"2025-03-12T21:44:24+08:00","permalink":"https://blog.acesheep.com/p/rocky-9-disable-kdump/","title":"Rocky 9 禁用 kdump (Crashkernel)"},{"content":"在某些情况下, 我们希望将 SFTP 用户限制在某个特定目录内, 出于安全考虑。OpenSSH 提供了 Chroot Jail 机制来实现这一功能。\n⚠️ 需要注意。在 chroot 环境下, SFTP 用户不能直接写入 /。因此要么强制他们进入一个可写的子目录, 要么提前建立合适的目录结构。\n实现方式有两种:\n针对多个用户, 可以将他们限制在各自的 home 目录, 并把 home 目录设置到自定义路径 针对单个用户, 可以在 sshd_config 中直接指定目录 本文主要介绍如何为多个用户设置\n如何为多个用户进行设置\r创建用户组\r首先, 创建一个专门的 sftp 用户组\ngroupadd sftprestricted 创建目录\r创建存放用户目录的路径\nmkdir /location/to/your/HomeFolder 创建用户\r创建新用户并将其直接加入 sftprestricted 组, 同时指定 home 目录为刚才创建的目录, 并禁用 shell 登录\nuseradd -d /location/to/your/HomeFolder -m USERNAME -g sftprestricted -s /sbin/nologin 说明\n-s /bin/false 或 /sbin/nologin 用于禁止用户直接通过 SSH 获取 shell 在禁用 shell 之前不要使用 ssh-copy-id 来复制公钥, 因为 chroot 权限限制会导致 authorized_keys 无法使用 设置权限\r由于 OpenSSH 对 chroot jail 有严格要求:\n用户 home 目录必须归 root 所有 用户不能对其 home 根目录直接写入 因此, 需要调整目录权限\nchown root:root /location/to/your/HomeFolder chmod 755 /location/to/your/HomeFolder 如果要允许用户写入, 需要在其 home 目录下再创建一个子目录, 例如 /location/to/your/HomeFolder/data, 并设置权限\n子目录权限可根据需要设置为 755 或 750\nmkdir /location/to/your/HomeFolder/data chown USERNAME:sftprestricted /location/to/your/HomeFolder/data chmod 755 /ftpusers/HomeFolder/data 这样, 用户登录后只能在 data 子目录中进行读写\n启用 internal-sftp\r编辑 /etc/ssh/sshd_config, 将 sftp-server 替换为 internal-sftp\n# override default of no subsystems # Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp UsePAM yes 这样, sftp 服务会作为 SSH 内置子系统运行, 而不会再启动独立的 sftp 进程。\n从功能上看, sftp-server 与 internal-sftp 基本相同, 且由同一份源码构建。\n设置 Chroot Jail\r编辑 /etc/ssh/sshd_config, 在末尾添加\n# SFTP Chroot Jail Match Group sftprestricted ChrootDirectory %h ForceCommand internal-sftp PasswordAuthentication no PubkeyAuthentication yes PermitTunnel no AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no 说明\nChrootDirectory %h: 将用户限制在其 home 目录 ForceCommand internal-sftp: 确保用户只能使用 SFTP, 不会执行 .bashrc 或其他命令 同时禁止隧道、转发、X11 等, 强制使用公钥认证 配置密钥认证 (推荐)\r最佳实践是使用 密钥认证 来进行 SSH/SFTP 连接\n默认情况下, OpenSSH 会检查 /home/%u/.ssh/authorized_keys 来读取公钥\n由于 home 目录权限限制, ~/.ssh/authorized_keys 在 chroot jail 中无法正常使用, 因此需要为 SFTP 用户指定一个独立的密钥存放目录, 例如 /etc/ssh/user_keys/\n创建目录和密钥文件\r先创建存放密钥的目录, 并为用户生成对应的 authorized_keys 文件, 并将户名附加到文件名中\nmkdir /etc/ssh/user_keys vim /etc/ssh/user_keys/authorized_keys_USERNAME 修改权限\r为文件设置适当权限, 确保只有目标用户可以读取密钥\nchown USERNAME:sftprestricted /etc/ssh/user_keys/authorized_keys_USERNAME chmod 640 /etc/ssh/user_keys/authorized_keys_USERNAME 为用户组指定密钥文件位置\r编辑 /etc/ssh/sshd_config, 在末尾添加以下配置, 指定自定义密钥文件路径\n# SSH Key authentication for SFTP users using chroot Match Group sftprestricted AuthorizedKeysFile /etc/ssh/user_keys/authorized_keys_%u 为特定用户指定密钥文件位置\r如果需要针对单个用户设置, 可以使用 Match User\nMatch User USERNAME AuthorizedKeysFile /etc/ssh/user_keys/authorized_keys_%u 允许用户写入根目录 (可选)\r如果希望用户直接写入 chroot 的根目录, 可以通过 -d 强制他们进入某个子目录\n# SFTP Chroot Jail Match Group sftprestricted ChrootDirectory %h ForceCommand internal-sftp -d /subdirectory PasswordAuthentication no PubkeyAuthentication yes PermitTunnel no AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no 其中 /subdirectory 必须归用户所有, 并设置正确权限\n重启 SSH 服务\r配置完成后, 重启 SSH 服务并检查状态。在保持当前终端会话不关闭的情况下, 建议再开一个新终端测试 SSH 登录是否正常。\nsystemctl restart sshd systemctl status sshd 调试与问题排查\r首先, 仔细检查权限设置, 因为权限问题是最常见的原因。\nchroot 根目录必须由 root 拥有, 并且不可写 用户写入目录必须是子目录 使用详细模式调试 SFTP\rsftp -vvv username@host.local 查看 SSH 日志\r可以在 /etc/ssh/sshd_config 中临时开启调试日志, 调试完成后记得恢复默认配置\n# Logging # SyslogFacility AUTH SyslogFacility AUTHPRIV LogLevel DEBUG 修改后重启 SSH 服务并检查状态\nsystemctl restart sshd systemctl status sshd 然后查看 sshd 服务日志, 确认是否有权限或其他错误。日志文件路径因系统而异, 一般在 /var/log/secure 或 /var/log/auth.log\ntail -f /var/log/secure 原文\nRestrict SFTP user to a specific folder\nLimit SFTP user access to specified directory\n","date":"2025-03-04T18:52:45+08:00","permalink":"https://blog.acesheep.com/p/sftp-restrict-user-directory/","title":"限制 SFTP 用户只能访问特定文件夹"},{"content":"在一台设备上同时启用 IPv4 和 IPv6 时, 系统和浏览器通常会默认 IPv6 优先。\n这意味着: 只要目标站点支持 IPv6, 系统就会优先通过 IPv6 访问, 只有在 IPv6 不可用时才会回退到 IPv4。\n但在某些应用场景下, 我们可能希望 IPv4 优先, 例如\n大部分运营商的 IPv6 网络路由没有优化, 会出现 IPv6 绕路、跳数更多, 而 IPv4 路由更优, 访问速度更快 某些网站、API、CDN 节点在 IPv6 上不可用或不稳定 开发调试时希望默认走 IPv4, 有助于排查网络问题 默认情况测试\r如果系统支持 IPv6, 且安装了 curl, 可以直接执行\ncurl ifconfig.co 默认情况下返回的是 IPv6 地址, 例如\n[root@localhost 1]# curl ifconfig.co 2605:6400::2 说明当前访问优先走 IPv6\n修改 IPv4 / IPv6 优先级\rLinux 系统通过 /etc/gai.conf 文件控制 getaddrinfo 调用的地址选择策略。\n默认设置下, IPv6 优先级高于 IPv4。在不禁用 IPv6 的情况下优先使用 IPv4\n编辑配置文件\nvim /etc/gai.conf 在文件中添加\nprecedence ::ffff:0:0/96 100 这条规则的含义是\n::ffff:0:0/96 表示 IPv4 映射地址段 100 表示提升该段的优先级, 使 IPv4 优先于 IPv6 修改后测试\r此时再使用 curl ifconfig.co 测试\n[root@localhost 1]# curl ifconfig.co 107.1.2.3 此时返回 IPv4 地址, 说明已经成功将 IPv4 设置为优先\n一键修改\r注意 cat 命令后的 \u0026gt;\u0026gt; 即为添加文件内容, 如果使用 \u0026gt; 则是覆盖文件内容\ncat \u0026gt;\u0026gt; /etc/gai.conf \u0026lt;\u0026lt; EOF precedence ::ffff:0:0/96 100 EOF 原文\n各位大佬 怎样才能使CENTOS7的IPV4优先\nDebian 双栈网络时开启 IPv4 优先\n","date":"2025-02-22T00:05:40+08:00","permalink":"https://blog.acesheep.com/p/linux-dualstack-ipv4-preferred/","title":"Linux 下修改 IPv4/IPv6 优先级, 让 IPv4 优先访问"},{"content":"本方法在 V3.04.15711U03 固件上测试成功, 不知道新版固件会不会封堵\n已验证可用地区: 北京联通 不可用地区: 上海联通、山西联通 其他地区请自行测试\n获取配置文件\r友华 PT1570-R10 光猫存在 FTP 根目录限制不严格的问题, 用户可通过开启 FTP 服务进入配置文件目录, 读取和修改配置文件, 从而实现开启 Telnet、获取超管密码、查询固话密码等操作。\n工具准备\rFTP 工具: FlashFXP 文本编辑器: Visual Studio Code 开启 FTP 服务\r使用光猫背面标签上的 user 密码登录普通用户界面 进入: 应用 -\u0026gt; FTP 配置 启用 FTP, 用户名密码都设为 user 保存后, 点击右上角 退出 管理界面 (此步骤很重要) 使用 FlashFXP 登录光猫\r输入光猫 IP 192.168.1.1, 用户名和密码均为 user\n登录后默认进入 /mnt 目录 (挂载 U 盘存储路径)\n在地址栏输入以下路径, 回车即可强行进入配置文件目录, 并且具有写入权限\n/var/config ⚠️ 不要先进入 /var 再尝试进入 config, 会提示权限不足\n编辑配置文件\r找到 config.xml 文件 可以直接右键 -\u0026gt; 编辑 -\u0026gt; 使用 VSCode 打开 如果没有安装, 也可以把 config.xml 下载到本地, 改完后覆盖回去。\n启用 telnet\r搜索 MIB_TELNET_ENABLE, 把后面的值改成 1, 即可开启 Telnet\n下面的 TELNET_USER 和 TELNET_PASSWD 分别是默认的 Telnet 用户名和密码 (yhtcAdmin / Cuc@YHfw)\n\u0026lt;Value Name=\u0026#34;MIB_TELNET_ENABLE\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Value Name=\u0026#34;TELNET_USER\u0026#34; Value=\u0026#34;yhtcAdmin\u0026#34;/\u0026gt; \u0026lt;Value Name=\u0026#34;TELNET_PASSWD\u0026#34; Value=\u0026#34;Cuc@YHfw\u0026#34;/\u0026gt; 搜索 PROVINCE_TELNETCLI_ENABLE, 把值改成 1\n\u0026lt;Value Name=\u0026#34;PROVINCE_TELNETCLI_ENABLE\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; 设置 su 权限\r搜索 telnet, 把值改成 3, 这样 Telnet 登录后会直接进入 su 权限\n\u0026lt;Value Name=\u0026#34;telnet\u0026#34; Value=\u0026#34;3\u0026#34;/\u0026gt; TTL 默认账号密码 (串口登录)\r搜索 MIB_SERIAL_USERNAME, 这里的用户名和 MIB_SERIAL_PASSWD 即为 TTL 串口登录的默认用户名和密码 (admin / yhtc)\n\u0026lt;Value Name=\u0026#34;MIB_SERIAL_USERNAME\u0026#34; Value=\u0026#34;admin\u0026#34;/\u0026gt; \u0026lt;Value Name=\u0026#34;MIB_SERIAL_PASSWD\u0026#34; Value=\u0026#34;yhtc\u0026#34;/\u0026gt; 保存并重启\r修改完成后保存退出, 此时 FTP 工具会提示文件已修改、是否上传, 选择 \u0026ldquo;是\u0026rdquo; 即可直接上传覆盖。\n覆盖后不要重新进入管理界面, 而是直接 断电重启光猫, 重启后新配置才会生效。\n获取超管密码\r北京固件对超管账号做了限制, 需要先解除管理界面的屏蔽。非北京版直接看下一步。\n搜索 PROVINCE_BEIJING_ACCOUNT_ADMIN_DISABLE, 把值改为 0\n\u0026lt;Value Name=\u0026#34;PROVINCE_BEIJING_ACCOUNT_ADMIN_DISABLE\u0026#34; Value=\u0026#34;0\u0026#34;/\u0026gt; 搜索 SUSER_PASSWORD, 其对应的值就是当前超管密码\n\u0026lt;Value Name=\u0026#34;SUSER_PASSWORD\u0026#34; Value=\u0026#34;CUAdmin\u0026#34;/\u0026gt; 保存并重启\r修改完成后, 直接上传覆盖。断电重启光猫, 重启后新配置才会生效。\n进入超管界面\r重启后可通过以下地址进入超管界面, 并使用默认密码 CUAdmin 登录\nhttp://192.168.1.1/admin/login_admin.asp\n获取固话密码\r搜索 PROXY_PASSWORD, 后面的值即为固话的 SIP 密码\n\u0026lt;Value Name=\u0026#34;PROXY_PASSWORD\u0026#34; Value=\u0026#34;1kK9c7qp\u0026#34;/\u0026gt; IPTV 设置\r搜索 pppUser, 通常会看到多个\n第一个是 TR069 管理连接的账号 第二个是 宽带账号 (对应的 pppPasswd 就是宽带密码) 在宽带账号与密码的配置下面, 可以找到一行 enableIGMP, 将其值改为 1, 即可在 WAN 拨号连接上启用 IGMP 代理 (北京版白嫖 IPTV 的必要条件)\n\u0026lt;Value Name=\u0026#34;enableIGMP\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; 注意事项\r维护完成后务必 关闭 TR069 远程管理, 以防止远程配置下发连接被运营商覆盖掉修改内容 操作结束后记得 关闭 FTP 功能, 避免安全风险 原文\n联通版友华PT1570-R10开telnet、查超管、查固话密码\n","date":"2025-01-11T13:37:01+08:00","permalink":"https://blog.acesheep.com/p/beijing-unicom-crack-pt1570r10-superadmin-voip-password/","title":"北京联通友华 PT1570-R10 查超管密码"},{"content":"在传统的 SysV init (早期 Linux/Unix 使用的传统启动和服务管理系统) 系统中, Linux 管理员和开发者常通过 /etc/rc.local 脚本在系统进入多用户运行级别 (multi-user runlevel) 时执行自定义命令。然而, 在使用 systemd 的现代 Linux 发行版中, /etc/rc.local 默认被禁用。\n本文介绍如何在 systemd 中启用并执行 /etc/rc.local\n在 systemd 中启用 rc.local 脚本的方法\rsystemd 提供了一个特殊的单元 (unit) rc-local.service, 它会在多用户目标 (multi-user.target) 时自动调用 /etc/rc.local, 前提是该文件存在并且可执行。\n创建和配置 /etc/rc.local\r编辑 /etc/rc.local 文件 (不同发行版路径可能略有不同)\n# Debian / Ubuntu vim /etc/rc.local # RHEL / CentOS / Fedora vim /etc/rc.d/rc.local 添加需要的命令, 例如\n#!/bin/bash # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES # # It is highly advisable to create own systemd services or udev rules # to run scripts during boot instead of using this file. # # In contrast to previous versions due to parallel execution during boot # this script will NOT be run after all other services. # # Please note that you must run \u0026#39;chmod +x /etc/rc.d/rc.local\u0026#39; to ensure # that this script will be executed during boot. # 设置 Wi-Fi 唤醒 /sbin/iw phy0 wowlan enable magic-packet disconnect 使用 :wq 保存文件并赋予可执行权限\nchmod +x /etc/rc.d/rc.local 启用 rc.local 服务\r首先检查 rc-local 服务是否已启用\nsystemctl is-enabled rc-local.service 如果结果为 disabled 或 static, 说明服务未启用, 需要手动开启\nsystemctl enable rc-local.service 然后重启系统, 并验证服务状态\nsystemctl status rc-local.service 正常情况下会显示服务已启动并退出 active (exited)\n查看 rc-local.service 配置\r使用以下命令可查看完整配置\nsystemctl cat rc-local.service 典型配置示例\n# /usr/lib/systemd/system/rc-local.service # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # This unit gets pulled automatically into multi-user.target by # systemd-rc-local-generator if /etc/rc.d/rc.local is executable. [Unit] Description=/etc/rc.d/rc.local Compatibility ConditionFileIsExecutable=/etc/rc.d/rc.local After=network.target [Service] Type=forking ExecStart=/etc/rc.d/rc.local start TimeoutSec=0 RemainAfterExit=yes 关于运行级别 (Runlevel)\r在 SysV init 时代, 常见 运行级别 如下\n运行级别 含义 0 关机 1 单用户模式 (在紧急模式下恢复 Linux 系统) 2 to 5 多用户模式 (支持 CLI/GUI/网络) 6 重启 /etc/rc.local 通常在进入多用户运行级别 (2–5) 时执行。随着大多数 Linux 发行版切换到 systemd, 该机制已被弃用, 如需使用需通过前述方法手动启用。\n使用自定义 systemd 服务 (推荐做法)\r相比 rc.local, 直接编写 systemd 服务单元更符合现代 Linux 习惯。\n示例模板, /etc/systemd/system/my-service.service\n[Unit] Before=network.target [Service] Type=oneshot ExecStart=/path/to/command ExecStart=/path/to/script arg1 arg2 RemainAfterExit=yes [Install] WantedBy=multi-user.target 启用服务\nsystemctl enable my-service.service systemctl start my-service.service 原文\nHow to enable rc.local shell script on systemd while booting Linux system\n","date":"2024-12-05T10:45:22+08:00","permalink":"https://blog.acesheep.com/p/enable-rc-local-systemd/","title":"启用 rc.local 脚本开机自启动"},{"content":"阿里云虚拟主机支持 一个主机绑定多个域名。域名绑定后, 需要先完成解析并备案成功, 网站才能正常访问。\n因此, 理论上我们可以在一台虚拟主机上搭建多个网站。\n域名绑定\r首先, 在阿里云虚拟主机控制台中绑定需要使用的域名。绑定完成并生效后, 便可以通过 .htaccess 文件对不同域名进行目录解析。\n解析两个静态网站\r阿里云虚拟主机底层使用 Apache 提供网站服务, 因此可以通过 .htaccess 文件来实现灵活的域名解析。\n网站 类型 目录 www.aaa.com 静态文件 htdocs/www.aaa.com www.bbb.com Hugo 纯静态 htdocs/www.bbb.com 网站源码存放在虚拟主机 htdocs 目录下的子目录\n. └── htdocs ├── .htaccess ├── logreport ├── www.aaa.com └── www.bbb.com 在 htdocs 目录下建立一个 .htaccess 文件, 内容如下:\n# 开启 Rewrite 功能 RewriteEngine On # 将 www.aaa.com 解析到 /www.aaa.com 目录 RewriteCond %{HTTP_HOST} ^(www.)?aaa.com$ RewriteCond %{REQUEST_URI} !^/www.aaa.com/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /www.aaa.com/$1 RewriteCond %{HTTP_HOST} ^(www.)?aaa.com$ RewriteRule ^(/)?$ www.aaa.com/ [L] # 将 www.bbb.com 解析到 /www.bbb.com 目录 RewriteCond %{HTTP_HOST} ^(www.)?bbb.com$ RewriteCond %{REQUEST_URI} !^/www.bbb.com/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /www.bbb.com/$1 RewriteCond %{HTTP_HOST} ^(www.)?bbb.com$ RewriteRule ^(/)?$ www.bbb.com/ [L] 这样就能实现:\nwww.aaa.com 访问 /www.aaa.com 目录 www.bbb.com 访问 /www.bbb.com 目录 PHP 伪静态与静态网站共存\r实际生产环境中, 可能需要同时运行 动态网站 (PHP) 和 静态网站 (Hugo 等)\n例如, 虚拟主机目录结构如下:\n网站 类型 目录 www.aaa.com PHP (支持伪静态) htdocs/www.aaa.com www.bbb.com Hugo 纯静态 htdocs/www.bbb.com htdocs/.htaccess\nRewriteEngine On RewriteBase / # 将 www.aaa.com 解析到 /www.aaa.com 目录 RewriteCond %{HTTP_HOST} ^www\\.aaa\\.com$ [NC] RewriteCond %{REQUEST_URI} !^/www\\.aaa\\.com/ RewriteRule ^(.*)$ /www.aaa.com/$1 [L,QSA] # 将www.bbb.com 解析到 /www.bbb.com 目录 RewriteCond %{HTTP_HOST} ^www\\.bbb\\.com$ [NC] RewriteCond %{REQUEST_URI} !^/www\\.bbb\\.com/ RewriteRule ^(.*)$ /www.bbb.com/$1 [L,QSA] 接着, 在每个子目录中分别建立 .htaccess 文件, 内容如下:\nhtdocs/www.aaa.com/.htaccess\nRewriteEngine On RewriteBase /www.aaa.com # PHP 伪静态, 把所有非真实文件/目录请求交给 index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /www.aaa.com/index.php [L] htdocs/www.bbb.com/.htaccess\nRewriteEngine On RewriteBase /www.bbb.com RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /www.bbb.com/index.html [L] 通过这样的配置, 就可以完美的处理 PHP 伪静态规则 和 Hugo 纯静态网站\n原文\n阿里云虚拟主机搭建多个网站\n","date":"2024-10-26T14:21:46+08:00","permalink":"https://blog.acesheep.com/p/aliyun-web-hosting-multi-website/","title":"阿里云虚拟主机搭建多个网站"},{"content":"Hugo 是一个用 Go 编写的开源静态网站生成器 (SSG, Static Site Generator)。它非常适合那些想要自己硬编码网站, 但又不想折腾复杂运行环境、依赖和数据库的人。\n不过, 静态网站嘛, 很多朋友第一反应就是: 那还能像以前用 PHP 插件一样, 自动给图片加水印吗？\n兄弟！有的兄弟, 有的！ 😎\n让我们了解一下基础知识\r从 Hugo v0.80.0 开始, 官方加入了图片叠加 (overlay) 功能, 我们就能用它来实现水印效果。所以, 首先要确保你安装的是 v0.80 或更高版本。\n你可以在终端或命令行输入 hugo version, 来检查你本地的 Hugo 版本。\n本文会带你实现一个简单的水印功能, 主要针对博客文章正文里的图片 (in-post images)。如果是主题里的封面图、标题图片等, 思路类似, 但代码需要稍微调整。\n为了示范, 我们会把水印加在图片的右下角\n关于 Page Bundles\r要实现本文的方案, 我们需要使用 Page Bundles\nHugo 有一个叫 Page Resources 的概念, 它们只能在 Page Bundles 中使用。这一点非常关键, 因为我们想要给图片添加水印, 就必须先能获取到图片资源。\nPage Resources 可以包含图片、文档等, 并带有页面相对路径和元数据。\n因此, 要让 \u0026ldquo;Page Bundling\u0026rdquo; 生效, 你的 content 文件夹结构应该类似这样\n* (site-root) ├── content │ ├── post-one │ │ ├── index.md │ │ └── images │ │ ├── image_one.jpeg │ │ ├── image_two.jpeg │ │ └── image_three.jpeg │ └── post-two │ ├── index.md │ └── images │ └── image_one.jpeg └── themes 也就是说, post-one 目录下包含 index.md 以及 images 文件夹里的所有图片, 这些文件都属于该页面的资源 (Page Resources)。\n因此我们可以借助 Hugo 的资源系统, 把这些资源按需获取并处理, 比如在图片上添加水印。\n关于水印图片\r目前 Hugo 只能将一张图片覆盖到另一张图片上, 还不支持直接在图像上添加文本。\n所以我们需要先准备好一个作为水印的 logo 图片, 并把它放在 assets 目录下, 以便 Hugo 的资源处理器能够访问。\n本文我们把 logo 放在 ./assets/images/logo.png\n关于 Markdown 渲染钩子\rHugo 提供了 Markdown 渲染钩子 (Markdown Render Hooks), 这些钩子允许通过自定义模板来覆盖默认的 Markdown 渲染方式。\n在这里, 我们将使用 render-image 钩子来处理文章中的图片。\n挂钩 render-image 文件需要放在如下所示的位置\n* (site root) ├── layouts │ └── _default │ └── _markup │ └── render-image.html └── themes 代码示例\r在 render-image.html 中添加以下代码, 将 ./assets/images/logo.png 作为水印覆盖到原图右下角\n\u0026lt;!-- contents of render-image.html --\u0026gt; {{- $link := split .Destination \u0026#34;#\u0026#34; }} {{- $image := (.Page.Resources.ByType \u0026#34;image\u0026#34;).GetMatch (printf \u0026#34;*%s*\u0026#34; (index $link 0)) }} {{- $logo := (resources.Get \u0026#34;images/logo.png\u0026#34;) }} {{- if and $image $logo }} {{- $size := math.Round (mul $image.Height 0.25) }} {{- $size := cond (ge $size 80) ($size) (80.0) }} {{- $logo := $logo.Resize (printf \u0026#34;%.0fx jpg\u0026#34; $size) }} {{- $image := $image.Filter (images.Overlay $logo (sub $image.Width $logo.Width) (sub $image.Height $logo.Height) ) }} {{- $finalUrl := cond (isset $link 1) (printf \u0026#34;%s#%s\u0026#34; ($image.Permalink) (index $link 1)) ($image.Permalink) -}} \u0026lt;img src=\u0026#34;{{ $finalUrl | safeURL }}\u0026#34; alt=\u0026#34;{{ .Text }}\u0026#34; {{ with .Title}} title=\u0026#34;{{ . }}\u0026#34; {{ end }} /\u0026gt; {{- else }} \u0026lt;img src=\u0026#34;{{ .Destination | safeURL }}\u0026#34; alt=\u0026#34;{{ .Text }}\u0026#34; {{ with .Title}} title=\u0026#34;{{ . }}\u0026#34; {{ end }} /\u0026gt; {{- end }} 代码解释\rrender-image markdown-hook 拥有 这些变量, 其中 .Destination 变量提供了资源的 路径 (在我们的例子中是图片)\n\u0026lt;!-- render-image.html --\u0026gt; {{/* 我们使用 # 作为分隔符, 把图片路径拆分成两部分, 这样可以确保资源路径中没有额外的参数 */}} {{/* 然后获取实际的图片资源, 并存储在 $image 中 */}} {{- $link := split .Destination \u0026#34;#\u0026#34; }} {{- $image := (.Page.Resources.ByType \u0026#34;image\u0026#34;).GetMatch (printf \u0026#34;*%s*\u0026#34; (index $link 0)) }} {{/* 接着我们获取要作为水印的图片, 并存储在 $logo 中 */}} {{- $logo := (resources.Get \u0026#34;images/logo.png\u0026#34;) }} {{/* 检查 $image 和 $logo 是否都存在, 如果都存在则继续水印处理 */}} {{/* 否则, 就直接显示原始图片 */}} {{- if and $image $logo }} {{/* 接下来对 logo 的大小进行调整, 使其与原图尺寸相匹配, 既不太大也不太小 */}} {{/* 计算水印 logo 的大小, 按原图高度的 30% 缩放, 但最小值限制为 80px */}} {{- $size := math.Round (mul $image.Height 0.30) }} {{- $size := cond (ge $size 80) ($size) (80.0) }} {{/* 调整水印 logo 大小 */}} {{- $logo := $logo.Resize (printf \u0026#34;%.0fx jpg\u0026#34; $size) }} {{/* 下面这行代码告诉 HUGO 在图片上添加水印 ($logo) */}} {{/* 使用 Filter + Overlay 把 logo 叠加到原图右下角 */}} {{/* images.Overlay 需要 3 个参数: 水印图片、X 轴位置、Y 轴位置 */}} {{/* 将水印放到右下角: */}} {{/* X 坐标 (右边对齐) = 图片宽度 - 水印宽度 */}} {{/* Y 坐标 (底部对齐) = 图片高度 - 水印高度 */}} {{- $image := $image.Filter ( images.Overlay $logo (sub $image.Width $logo.Width) (sub $image.Height $logo.Height) ) }} {{/* 最后, 我们把之前 URL 中的参数 (通过 # 分割的部分) 加回来, 生成最终的图片地址 */}} {{/* 保存为 $finalUrl */}} {{- $finalUrl := cond (isset $link 1) (printf \u0026#34;%s#%s\u0026#34; ($image.Permalink) (index $link 1)) ($image.Permalink) -}} {{/* 输出最终带水印的图片 */}} \u0026lt;img src=\u0026#34;{{ $finalUrl | safeURL }}\u0026#34; alt=\u0026#34;{{ .Text }}\u0026#34; {{ with .Title}} title=\u0026#34;{{ . }}\u0026#34; {{ end }} /\u0026gt; {{- else }} {{/* 如果 $image 或 $logo 为空, 则直接显示原始图片 */}} \u0026lt;img src=\u0026#34;{{ .Destination | safeURL }}\u0026#34; alt=\u0026#34;{{ .Text }}\u0026#34; {{ with .Title}} title=\u0026#34;{{ . }}\u0026#34; {{ end }} /\u0026gt; {{- end }} 关键语句是下面这一行代码, 告诉 Hugo 把水印 $logo 叠加到图片上\n{{- $image := $image.Filter (images.Overlay $logo (sub $image.Width $logo.Width) (sub $image.Height $logo.Height) ) }} images.Overlay 接收 3 个参数: 水印图片、X 轴位置、Y 轴位置\n然后我们使用 Filter 函数, 把水印叠加到原始图片上。\n实际效果\r只要用普通的 Markdown 语法写图片\n![Sample Results](media/images/sample.jpg#center \u0026#34;Sample Result with a watermark\u0026#34;) 就会自动渲染成带水印的图片\n原文\nWatermarking images with HUGO\n","date":"2024-10-06T15:15:52+08:00","permalink":"https://blog.acesheep.com/p/hugo-watermarking-images/","title":"使用 HUGO 给图片添加水印"},{"content":"很多朋友最近在使用 CentOS 7 时遇到了无法通过 yum 安装软件包的问题。\n这是因为 CentOS 7 已在 2024 年 6 月 30 日正式停止维护 (EOL), 官方不再提供更新和支持, 原有的官方 yum 源也随之下线, 因此会出现如下报错:\nLoaded plugins: fastestmirror Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7\u0026amp;arch=x86_64\u0026amp;repo=os\u0026amp;infra=stock error was 14: curl#6 - \u0026#34;Could not resolve host: mirrorlist.centos.org; Unknown error\u0026#34; Could not retrieve mirrorlist http://mirrors.elrepo.org/mirrors-elrepo.el7 error was 12: Timeout on http://mirrors.elrepo.org/mirrors-elrepo.el7: (28, \u0026#39;Connection timed out after 30000 milliseconds\u0026#39;) Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7\u0026amp;arch=x86_64\u0026amp;repo=extras\u0026amp;infra=stock error was 14: curl#6 - \u0026#34;Could not resolve host: mirrorlist.centos.org; Unknown error\u0026#34; Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7\u0026amp;arch=x86_64\u0026amp;repo=updates\u0026amp;infra=stock error was 14: curl#6 - \u0026#34;Could not resolve host: mirrorlist.centos.org; Unknown error\u0026#34; 解决方法就是更换第三方提供的 yum 镜像源, 例如阿里云开源镜像站。\n更换 yum 源\r备份当前 yum 源\r在修改之前, 建议先备份原有的 yum 源配置文件, 以防万一, 以便后续恢复\nmv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 这一步会将原来的配置文件重命名为 CentOS-Base.repo.backup\n下载新的 yum 源配置文件\r这里以阿里云镜像源为例\nwget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 清理并生成缓存\r# 清理旧的缓存文件 yum clean all # 生成新的缓存 yum makecache 验证是否生效\r现在可以尝试安装一个软件包, 例如\nyum install vim 如果能够正常安装, 说明新的 yum 源已经生效\n脚本\r使用脚本快速替换\nbash \u0026lt;(curl -sL shell.puka.cc/replace-repo) 原文\ncentos7停止维护后更换yum源教程\nmirrorlist.centos.org no longer resolve?\n阿里巴巴开源镜像站-OPSX镜像站\nEpel 镜像 - 阿里巴巴开源镜像站\n","date":"2024-09-24T14:16:20+08:00","permalink":"https://blog.acesheep.com/p/centos7-end-of-life-change-yum-repo/","title":"CentOS 7 停止维护后更换 yum 源"},{"content":"AT+COPS 选择营运商\r模块在默认情况下通常会自动搜索并注册到可用的网络, 例如在中国, 移动卡会注册到中国移动网络, 联通卡会注册到中国联通网络。\n但在国外使用漫游服务时, 根据所属运营商的漫游协议, 通常会有多家本地运营商可供选择。此时, 如果启用了自动搜网功能, 模块可能会连接到信号较弱或服务质量较差的运营商, 从而导致例如短信到达延迟较高等问题。\n在这种情况下, 可以通过手动搜网的方式, 选择并强制注册到信号质量更好的指定运营商。\n命令语法\rAT+COPS 命令用于查询当前网络运营商的状态, 并允许你选择自动或手动的网络注册模式。\n最大响应时间: 180 秒, 通常为网络搜索和注册所需时间。\n格式 目的与作用 AT+COPS=? 查询可用网络: 返回设备当前可检测到的所有运营商的完整列表及其支持的接入技术 (如 GSM, UTRAN 等) 和选择模式 AT+COPS? 查询当前状态: 返回设备当前使用的网络选择模式和已注册的运营商名称 (如果已注册) AT+COPS=\u0026lt;mode\u0026gt;[,\u0026lt;format\u0026gt;[,\u0026lt;oper\u0026gt;[,\u0026lt;Act\u0026gt;]]] 设置网络选择: 命令设备进入指定的选择模式 (自动、手动), 并尝试在指定的运营商上进行注册 命令返回格式\r# AT+COPS=? +COPS: (list of supported \u0026lt;stat\u0026gt;,long alphanumeric \u0026lt;oper\u0026gt;,short alphanumeric \u0026lt;oper\u0026gt;,numeric \u0026lt;oper\u0026gt;s)[,\u0026lt;Act\u0026gt;])s][,,(list of supported \u0026lt;mode\u0026gt;s),(list of supported \u0026lt;format\u0026gt;s)] # AT+COPS? +COPS: \u0026lt;mode\u0026gt;[,\u0026lt;format\u0026gt;[,\u0026lt;oper\u0026gt;][,\u0026lt;Act\u0026gt;]] 参数详解\r这些参数决定了网络选择方式及运营商名称的显示格式。\n\u0026lt;stat\u0026gt; 参数 (运营商状态)\n值 含义 0 无法确定该运营商的状态 1 可接入的运营商, 可选择并注册 2 当前设备已注册或正在尝试注册的运营商 3 被禁止接入的运营商 (通常由于 SIM 卡或服务限制导致) \u0026lt;mode\u0026gt; (网络选择模式)\n值 描述 关键点 0 自动选择 模块自动搜索并尝试注册到首选网络, \u0026lt;oper\u0026gt; 字段将被忽略 1 手动选择 你必须指定 \u0026lt;oper\u0026gt; (运营商名称) 和 \u0026lt;format\u0026gt;。模块只尝试注册到这个特定网络 2 注销网络 手动从网络上注销 3 仅设置读取格式 不进行注册或注销操作, 仅用于设置 AT+COPS? 读取命令时返回的运营商名称显示格式 4 手动, 回落到自动选择 你指定一个网络, 模块会首先尝试注册。如果失败, 它将自动回退到模式 0 (自动选择) \u0026lt;format\u0026gt; (运营商名称格式)\n值 描述 示例 0 长字母数字 \u0026ldquo;China Mobile\u0026rdquo; (最长 16 个字符) 1 短字母数字 \u0026ldquo;CMCC\u0026rdquo; 2 数字 \u0026ldquo;46000\u0026rdquo; (MCC+MNC, 即移动国家码+移动网络码) \u0026lt;oper\u0026gt; (运营商名称)\n这是你在 \u0026lt;format\u0026gt; 指定的格式下的具体运营商名称或代码 (例如, 如果你选择格式 2, 此处应填写 46000)\n\u0026lt;Act\u0026gt; (接入技术/网络制式)\n该参数为只读, 表示当前使用或可用的接入技术 (即网络制式, 如 2G、3G、4G 等)\n值 描述 网络级别 / 说明 0 GSM 2G 2 UTRAN 3G 3 GSM w/EGPRS 增强型 2G (2.5G/2.75G), 带 EGPRS (EDGE) 功能 4 UTRAN w/HSDPA 3G 增强 (3.5G), 支持高速下行 (HSDPA) 5 UTRAN w/HSUPA 3G 增强, 支持高速上行 (HSUPA) 6 UTRAN w/HSDPA and HSUPA 3G 增强 (HSPA), 支持高速上下行 (HSDPA + HSUPA) 7 E-UTRAN 4G / LTE 100 CDMA 另一种 2G/3G 技术, 主要用于北美及部分亚洲地区 简单来说\r要看哪些网络可用, 使用 AT+COPS=? 要看当前连接状态, 使用 AT+COPS? 要选一个网络, 使用 AT+COPS=\u0026lt;mode\u0026gt;... 要切换到手动并选择中国移动 (数字代码 46000): AT+COPS=1,2,\u0026quot;46000\u0026quot; 要切换回自动选择: AT+COPS=0 重要提醒\r在大多数情况下, 不建议使用 AT+COPS=0 或 AT+COPS=2 命令来手动连接或断开网络。\n这些操作可能会导致与预期相反的结果, 因为重复启用或强制切换网络功能, 可能干扰模块的正常网络管理机制。\n需要特别注意的是:\n执行断开操作意味着你不希望下次再使用当前网络。模块会在下次建立连接时重新搜索并选择其他可用网络。\n当设备重新上电后, 它会根据标准流程自动扫描并选择合适的网络进行注册。\nAT+CFUN 开启 / 关闭飞行模式\r可以通过以下 AT 命令来开启或关闭飞行模式\n命令 功能说明 0 最低功能模式 1 启用全部功能 (正常工作模式) —— 飞行模式关闭 2 关闭移动发射功能, 仅保留接收功能 (Tx off, Rx on) 3 关闭移动接收功能, 仅保留发射功能 (Rx off, Tx on) 4 关闭移动发射与接收功能 (Tx/Rx off) —— 飞行模式开启 无服务与处理指南\r排查设备在网络注册、信号连接、SIM 卡识别等方面常见问题\n连接到非签约运营商导致无法上网\r在国外或多网络环境下, 模块有时会错误地注册到非签约运营商, 从而无法上网。请按照以下步骤进行确认与处理。\n状况确认\r项目 命令 说明 APN 设置确认 AT+QICSGP=\u0026lt;contextID\u0026gt; 确认网络接入所需的 APN、用户名及密码是否正确设置 周边网络搜索 AT+COPS=? 查看可用运营商列表 当前注册状态 AT+COPS? 查看当前连接到的运营商 信号强度检查 AT+CSQ 检查信号质量 (建议 ≥ 20) 网络扫描模式 AT+QCFG=\u0026quot;nwscanmode\u0026quot; 确认扫描模式 (0: 自动 / 1: GSM / 2: WCDMA / 3: LTE) 扫描顺序 AT+QCFG=\u0026quot;nwscanseq\u0026quot; 查看网络扫描顺序 (如 BGxx: 00自动, 01 GSM, 02 M1, 03 NB) 当前小区详情 AT+QENG=\u0026quot;servingcell\u0026quot; 查看小区 ID、状态、RSSI、RSRP、RSRQ、SINR 等详细信息 处理方法\r方法 命令示例 说明 指定运营商 AT+COPS=\u0026lt;mode\u0026gt;[,\u0026lt;format\u0026gt;[,\u0026lt;oper\u0026gt;[,\u0026lt;Act\u0026gt;]]] 手动选择签约运营商 指定频段 AT+QCFG=\u0026quot;band\u0026quot; 限定可使用的频段 (Band) 示例:\n若签约运营商为 NTT DOCOMO: AT+COPS=1,2,\u0026quot;44010\u0026quot;,8\n指定频段:\nBGxx 系列 → AT+QCFG=\u0026quot;band\u0026quot;,0,40005,0 (Band1 + Band3 + Band19) EC2x 系列 → AT+QCFG=\u0026quot;band\u0026quot;,0,40005,0 (Band1 + Band3 + Band19) 实际示例\rAT+COPS=? +COPS: (3,\u0026#34;SoftBank\u0026#34;,\u0026#34;SoftBank\u0026#34;,\u0026#34;44020\u0026#34;,9),(3,\u0026#34;SoftBank\u0026#34;,\u0026#34;SoftBank\u0026#34;,\u0026#34;44020\u0026#34;,8), (3,\u0026#34;44011\u0026#34;,\u0026#34;440 11\u0026#34;,\u0026#34;44011\u0026#34;,9),(2,\u0026#34;NTT DOCOMO\u0026#34;,\u0026#34;DOCOMO\u0026#34;,\u0026#34;44010\u0026#34;,8),(0,1,2,3,4),(0,1,2) AT+COPS? +COPS: 0,0,\u0026#34;NTT DOCOMO\u0026#34;,8 AT+CSQ +CSQ: 24,99 AT+QENG=\u0026#34;servingcell\u0026#34; +QENG:\u0026#34;servingcell\u0026#34;,\u0026#34;NOCONN\u0026#34;,\u0026#34;eMTC\u0026#34;,\u0026#34;FDD\u0026#34;,440,10,6525713,18,6100,19,3,3,6354,-84,-6,-64,19,45 网络连接失败时的基础检查\r若模块无法注册网络, 请依次确认以下项目\n网络注册状态\r命令: AT+CEREG?\n返回值 含义 +CEREG: 0,1 已成功注册网络 +CEREG: 0,2 正在搜索网络, 请检查天线连接 +CEREG: 0,3 注册被拒, 请确认 SIM 卡已激活或联系运营商 +CEREG: 0,4 未知错误, 请进一步咨询 +CEREG: 0,5 已通过漫游注册网络 SIM 卡识别状态\r命令: AT+CPIN?\n返回值 说明 +CME ERROR: 10 SIM 识别失败 +CPIN: READY SIM 识别成功 模块功能状态\r命令: AT+CFUN?\n返回值 说明 +CFUN: 1 模块功能正常 +CFUN: 0 无线功能关闭, 请执行 AT+CFUN=1 后重试 +CFUN: 4 飞行模式开启, 请执行 AT+CFUN=1 后重试 +CFUN: 5 / 7 可能存在故障, 请联系技术支持 网络选择模式\r建议使用自动模式, 执行 AT+COPS=0\n命令: AT+COPS?\n返回值 说明 +COPS: 0 自动搜索网络 (推荐) +COPS: 1 手动选择网络 +COPS: 2 手动注销网络 (不推荐) 频段设置确认 (以 EC25-J 为例)\r请确认 \u0026lt;ltebandval\u0026gt; 包含对应运营商使用的 LTE 频段\n# 命令 AT+QCFG=\u0026#34;band\u0026#34;? # 返回示例 +QCFG: \u0026#34;band\u0026#34;,\u0026lt;bandval\u0026gt;,\u0026lt;ltebandval\u0026gt;,\u0026lt;tdsbandval\u0026gt; 网络扫描模式确认\r建议恢复为自动扫描模式\nAT+QCFG=\u0026#34;nwscanmode\u0026#34;,0,1 查询命令: AT+QCFG=\u0026quot;nwscanmode\u0026quot;?\n返回值 说明 +QCFG: \u0026quot;nwscanmode\u0026quot;,0 自动模式 (推荐) +QCFG: \u0026quot;nwscanmode\u0026quot;,3 仅搜索 LTE 网络 其他值 表示其他 RAT 类型 当前小区状态检查\r# 命令 AT+QENG=\u0026#34;servingcell\u0026#34; # 示例输出 +QENG:\u0026#34;servingcell\u0026#34;,\u0026#34;NOCONN\u0026#34;,\u0026#34;LTE\u0026#34;,\u0026#34;FDD\u0026#34;,460,01,5A29C0B,465,1650,3,5,5,DE10,-69,-5,-65,21,51 含义\n参数 含义 说明 RSRP 基准信号接收功率 -105 以下: 无法注册；-85~-95: 正常；-65 以上: 信号极佳 SINR 信号干扰噪声比 -20~30 dB, 数值越高越好 AT+CUSD 短代码 USSD\rAT+CUSD 命令用于控制 USSD (Unstructured Supplementary Service Data) 功能, 使终端设备 (TE) 能够发起或响应 USSD 操作。\n该命令支持 网络发起 与 终端发起 的 USSD 会话\n命令语法\r最大响应时间: 120 秒 (由网络决定)\n格式 说明 AT+CUSD=? 查询模块支持的 \u0026lt;mode\u0026gt; 列表 AT+CUSD? 查询当前 \u0026lt;mode\u0026gt; 设置 AT+CUSD=[\u0026lt;mode\u0026gt;[,\u0026lt;reqstr\u0026gt;[,\u0026lt;dcs\u0026gt;]]] 设置 USSD 功能模式, 或发起 / 响应 USSD 会话 参数说明\r\u0026lt;mode\u0026gt; USSD 结果代码显示与会话控制\n该参数用于设置结果代码 (USSD 响应) 的显示状态及控制会话行为\n值 说明 0 不将 USSD 结果代码显示给终端设备 (TE) 1 将 USSD 结果代码显示给终端设备 (TE) 2 终止当前正在进行的 USSD 会话 (不适用于查询模式) \u0026lt;reqstr\u0026gt; 请求字符串\n要发送给网络的 USSD 请求字符串\n如果未提供此参数, 则不会向网络发起查询\n示例\nAT+CUSD=1,*#1345#,15 \u0026lt;dcs\u0026gt; 数据编码方案\n指定 USSD 数据的编码方式\n若省略, 则默认使用 15 (GSM 7-bit 默认编码)\nUSSD 响应格式 (URC)\r当发起或接收 USSD 操作时, 网络会返回一个 非请求结果代码 (URC) 给终端设备, 格式如下\n+CUSD: \u0026lt;status\u0026gt;[,\u0026lt;rspstr\u0026gt;[,\u0026lt;dcs\u0026gt;]] \u0026lt;status\u0026gt; USSD 响应状态\n该参数指示 USSD 响应来自网络或网络发起的操作的状态:\n值 描述 0 不需要进一步用户操作: 网络发起的通知, 或用户发起的请求已完成 1 需要进一步用户操作: 网络请求用户输入 (会话仍在进行中) 2 USSD 会话已终止: 会话由网络主动关闭 3 其他客户端已响应: 该命令被忽略或由其他应用接管 4 不支持该操作: 网络不支持此类 USSD 请求 5 网络超时: 网络在超时时间内未返回响应 USSD 命令实际操作示例\n# 查询支持的响应类型 AT+CUSD=? +CUSD: (0-2) # 发送短码 USSD 请求 # 请先确认你的网络支持哪些短码 # 15 表示 GSM 3.38 编码方案 # 如果发送的是支持的短码, 应该能收到网络返回的响应 # 例如, 下面的短码在 Vodafone (UK) 可用于查询预付费账户余额 AT+CUSD=1,*#1345#,15 OK +CUSD: 0,\u0026#34;Your balance is #84.16. To check any remaining allowances please call 1345 , for free. Thank you\u0026#34;,1 原文\nWhy you shouldn’t tell IoT modems to detach/attach\nAT command: Airplan mode ON/OFF\nよくある質問\nUSSD – How to send USSD short codes with AT command?\n","date":"2024-09-01T04:17:24+08:00","permalink":"https://blog.acesheep.com/p/lte-module-at-command-notes/","title":"4G 模块 AT 命令笔记"},{"content":"Telegram 号称拥有 5 个数据中心 (DC, Data Center), 在其代码和文档中被称为 DC1 ~ DC5\nDC1 与 DC3: 位于美国迈阿密 (Miami, USA) DC2 与 DC4: 位于荷兰阿姆斯特丹 (Amsterdam, NL) DC5: 位于新加坡 (Singapore) 每个账号在注册时会关联到某个 DC, 之后无论更换手机号或地理位置, 都不会迁移至其他 DC。用户也无法手动选择 DC。如果客户端误连到错误的 DC, 服务端会返回错误信息, 要求重新连接到该账号所归属的 DC\nDC5: 中文圈最知名的数据中心\r在这 5 个 DC 中, DC5 在 Telegram 中文圈格外知名。原因并不是因为它默默无闻服务了大量的中文用户, 而是因为它经常宕机。\n当 DC5 宕机时, 属于 DC5 的用户会陷入「不断重连」的状态, 无法使用 Telegram。于是, 群友们的热门话题往往变成「DC5 怎么又挂啦」。DC5 用户只能等待「重连中」的客户端恢复后, 再与其他 DC 的群友们一起批判 DC5\n为了满足群友们的好奇心, 有人开发了一个 bot (机器人), 可以查询用户所在的 DC。于是群友们开始查起了自己的 DC\n使用 +86 手机号注册的用户, 发现自己在 DC5 (新加坡), 即将体验下一次宕机 使用 +1 手机号注册的用户, 则会在 DC1 (美国迈阿密), 可以兼顾连接速度与稳定性 使用 欧洲手机号注册的用户, 会发现自己在 DC4 (荷兰阿姆斯特丹), 成为了中文圈中最稀有的存在 咦？等等… Telegram 号称共有 5 个数据中心, 但查询结果里却始终见不到 DC2 与 DC3 的用户\nTelegram DC 的分配规则 (截至 2022-05)\r我们生成了上万个来自全球各地的号码, 并通过 方法 1: 登录法 测试了 Telegram 的 DC 分配规则。\n在测试过程中, 我们尽量让每个号码都连接到错误的 DC, 以便通过返回的 PHONE_MIGRATE_X 错误来确定该号码实际归属的 DC。同时, 这样也能避免产生大量垃圾短信, 减少骚扰, 更不会让 Pavel Durov 因短信费用而「破产」。\n在测试结束后, 我们先剔除了已确认为 DC4 的号码, 再将剩余号码连接至 DC4 进行二次判断, 以确保不会遗漏可能分配到 DC3 的号码。\n根据测试结果, Telegram 的 DC 分配规则如下\nDC1、DC2、DC4、DC5: 根据用户注册时填写的手机号的国家代码进行分配, 这四个数据中心都在正常接收新用户, 并且拥有大量存量用户 DC3: 曾经有用户, 但在 2020 年左右, 其存量用户可能已被迁移至 DC1。目前 DC3 仍在运行, 目前可能没有用户, 也不再接受新用户注册 也就是说, DC2 其实并不是空的。它依然在正常运行, 并且拥有大量用户, 只是中文圈里较少遇到。和其他数据中心一样, 只要用户注册时所用手机号的国家代码落在 DC2 负责的范围内 (如 +49 德国), 该用户就会被分配到 DC2\n相比之下, DC3 虽然仍在运行, 但已经没有关联用户, 可能已经「消失」了。\n如果你想让账号归属到指定的 DC, 从而避开 DC5 的宕机风险, 只需参考上图, 选择对应国家代码的号码进行注册即可。\n我到底在哪个 DC？\r既然有大量用户位于 DC2 , 为何上文提到的 bot 从未发现过来自 DC2 的用户呢？\n目前常见的 DC 获取方法有 3 种。下面我们注册一个位于 DC2 的新账号为例, 实际测试这 3 种方法。\n方法 1: 登录法\r使用会被分配到 DC2 的手机号, 通过 Telegram MTProto 协议 (官方客户端同样使用该协议) 连接到 DC1, 并调用 auth.sendCode 接口尝试发送验证码。\n此时, 服务端会返回 PHONE_MIGRATE_2 错误, 提示客户端应当连接到 DC2。如果改为连接 DC2 再执行相同操作, 验证码就会被直接发送。\n由此可以确认, 该账号属于 DC2\n这种方法, 前提是必须知道用户的手机号, 因此不适合用来查询群友的 DC\n方法 2: 头像/文件法\r当用户上传头像或文件时, Telegram 会将数据存储在账号所属的 DC。\n以刚刚注册的 DC2 账号为例, 如果直接查询, 是无法看到它的 DC 信息的；只有当新号上传头像后, 才能在头像信息中确认其归属于 DC2\n这是因为在下载头像时, MTProto 协议中的 userProfilePhoto 结构体会返回 dc_id 字段, 可以通过该字段来判断用户所在的 DC\n换句话说, 这种方法是 通过用户上传的头像或文件所在的 DC, 来确定账号所属的 DC\n这种方法相对准确, 但需要用户主动上传头像或文件。\n方法 3: Web CDN 法\r有些人会疑惑: 明明这个新号属于 DC2, 为什么 bot 却说是 DC4？\n这是因为 bot 是通过 Telegram Web CDN 的文件域名来判断用户的 DC, 例如当头像域名以 cdn4 开头时, 就会被误认为是 DC4\n我们在访问 https://t.me/\u0026lt;用户名\u0026gt; 并查看源码时, 可以发现新号的头像链接确实是 cdn4 开头的。\n造成这种情况的原因是: DC2 与 DC3 的 Web CDN, 会 借用 同地点的 DC4 与 DC1 的域名来提供服务。因此, DC2 用户的头像常常出现在 cdn4 域名下, 最终被误判为 DC4 用户, 导致长期「查无此人」\n由于 Telegram 的服务端实现与部分运行机制未开源, 本文的许多结论基于推理与实测结果。如发现文中的错误或掌握新线索, 欢迎在评论中指正与分享。\n原文\nTelegram DC 之都市传说\n","date":"2024-08-30T15:10:40+08:00","permalink":"https://blog.acesheep.com/p/telegram-dc-urban-legends/","title":"Telegram DC 之都市传说"},{"content":"一直以来我都在用美区的 Apple One 中杯套餐, 家庭共享价格为 $19.95/月, 折合下来一个人只需 $3.4/月\n不过最近 Apple One 中杯价格上涨到 $25.95/月, 而其中的 Apple TV+ 和 Arcade 用不到, 这样算下来就显得很不划算。\n正好听说 iCloud 在土耳其区的订阅价格非常便宜\n2TB 存储空间仅需 ₺64.99/月, 折合约 25 人民币 (当前汇率 1TRY≈0.38CNY), 约等于 3.5 美元\n再加上 Apple Music 家庭版只需 $16.99/月, 两项合计 $20.49/月, 算下来一个人 $4.1/月, 依然很划算。\n好家伙, 直接开冲！\n注册土耳其 Apple ID\r注册土区 Apple ID 的步骤非常简单, 甚至不需要切换到土耳其 IP\n直接注册一个新的 Apple ID, 地区选择 土耳其 支付方式选择「无」 注册完成后, 在 Apple ID 网页端管理界面里, 把账单地址随便填写一个在 Google Maps 上找到的土耳其地址即可 这样, 土耳其地区的 Apple ID 就准备好啦。\n土耳其支付方式\r为什么注册时选择 \u0026ldquo;无支付方式\u0026rdquo;?\n因为 App Store 绑定银行卡时必须是当地发行的卡片, 而要申请土耳其银行卡对大多数人来说比较困难。\n更常见的做法是使用 土耳其 App Store 礼品卡\n需要注意的是, 苹果官网土区并不直接售卖礼品卡, 只能通过第三方平台购买, 这也带来了一定的风险, 无法完全保证来源的安全。\n我对比了不少评价, 最终选择了 OyunFOR。这个平台支持信用卡支付, 会收取 1.5% 的手续费, 但同时返还 1% 的积分可在下次抵扣, 所以整体算下来相当于原价。如果再叠加一些带有 cashback 的信用卡, 价格甚至更低。\n唯一的不足是, OyunFOR 售卖的礼品卡最高面额只有 ₺100。考虑到土耳其里拉持续贬值, 这种小额充值反而更灵活, 用多少买多少即可。购买完成后, 将礼品卡余额充值到土区 Apple ID, 就能顺利支付 iCloud 订阅了。\n组建家庭组\r我的主号一直是美区账号, 长期使用下来, 换区十分麻烦。好在经过查找资料发现, iCloud 家庭共享早已支持跨区。于是, 我选择继续使用美区账号作为家庭组的创建者, 再邀请土区账号加入。\n具体操作是:\n用美区账号作为家庭组织者 通过 iMessage 邀请土区账号加入家庭组 其他方式也有人成功, 邀请方式不行可以换一种试试 订阅 iCloud 的土区账号加入后, 就能共享 2TB 容量给家庭成员 需要注意 如果和他人拼车, 土区账号本身会占用一个家庭组名额。不过考虑到价格优势, 即便 5 人分摊下来, 人均每月只需 $4.1, 就能获得 400 GB iCloud 空间, 性价比极高。\n此外, 我还邀请了一位使用国区账号 (iCloud 由云上贵州运营) 的车友加入家庭组, 也能够正常使用 iCloud 空间。唯一的区别是, 家庭组的容量统计显示不准确, 不会计算国区 iCloud 所使用的容量。\n跨区共享的限制\r需要注意的是, 跨区家庭共享并不是对所有服务都有效。例如 Apple Music, 由于各个地区的版权不同, 就算土区账号开通了订阅, 美区账号依然无法使用。\n不仅如此, 第三方 APP 的订阅, 比如 Infuse Pro, 也无法通过 iCloud 家庭组来跨区共享的。\n那这样的话, 土耳其账号是不是只能用来开 iCloud 呢？其实并不是。如果某些服务支持通过第三方账号登录, 而不是绑定 Apple ID 地区, 就能正常享受土区的低价订阅。比如:\nDisney+ Microsoft 365 Duolingo 1Password LastPass 这些在土区的订阅价格便宜很多, 性价比相当高。\n价格变动提醒\r需要注意, 土耳其 Apple Store 内购的价格也在不断调整\n2023-02-03: 微信读书会员从 ₺15.99 涨到 ₺69.99/月 2023-02-01: Telegram 会员两次涨价, 从 ₺13.99 ➝ ₺69.99 ➝ ₺74.99/月 微软 365 年付价格已调整, 但月付仍未涨, 可以在 OneDrive App 内订阅 国内 App (如 QQ 音乐、百度网盘) 的内购早就在上个月进行了调整 提醒: 已经订阅的用户续期时不会涨价 (除非开发者强制修改), 所以没有上车的需要尽快上车以免价格调整。\n原文\n土耳其 iCloud 上车指南\n","date":"2024-08-28T17:26:18+08:00","permalink":"https://blog.acesheep.com/p/icloud-turkey-tutorial/","title":"土耳其 iCloud 上车指南"},{"content":"由于 Typecho 有后门漏洞博客遭遇删库勒索, 导致丢失 2 年的博客数据。\n使用 Typecho 8 年感受, 缺点:\n文章有字数上线, 遇到两次文章超过字数上限被迫拆分为两篇文章 Typecho 有漏洞, 导致数据库被清空, 遭比特币勒索 附件文件名不能保留原文件名, 会被替换成数字 自带 Markdown 编辑器和 Typora 相比过于智障 文章标题使用 ---, 而不是 # 引用链接被归类在文章最底部 ![lost1.png][1], [1]: /2169320020.png 编辑器没有语法检查 写文章添加图片时不够丝滑, 总是打断创作连续性 PHP 已过气 部署上的缺点:\n博客部署在 nas 上, 使用 frp 内网穿透. 访客 ip 没有被正确的传递给博客程序 http 不可访问, 只有 https 才能访问博客 计划弃用 Typecho 博客程序, 新博客使用 Hugo 静态页面 + 自研评论系统\n注意: 丢失文章不在 Typecho 程序中补档, 在新博客上线后 丢失将内容迁移到新博客程序上\n新博客将于 10月份上线, 新评论系统预计在今年年底完成 希望在今年年底完成\n24 年 10 月: 新博客已上线, 正在迁移博客文章\n24 年 11 月: 仍然正在迁移博客文章\n24 年 12 月: 仍然正在迁移博客文章\n25 年 01 月: 迁移博客文章已完成, 旧文章连接重定向到新连接。正在补档\n25 年 02 月: 正在补档\n25 年 03 月: 正在补档\n25 年 04 月: 地球 Online 环球旅行\n25 年 05 月: 地球 Online 环球旅行\n25 年 06 月: 地球 Online 环球旅行\n25 年 07 月: 地球 Online 环球旅行\n25 年 08 月: 补档完成, 新评论系统仍在计划\n","date":"2024-08-26T04:45:00+08:00","permalink":"https://blog.acesheep.com/p/3e2c3cff3b2abc574966db86c1313306/","title":"2024 博客补档"},{"content":"在 多线接入 (电信、联通) 的网络环境下, 如何科学地进行分流一直是个令人头疼的问题。\n各种方案都有各自的优缺点, 并不存在 \u0026ldquo;完美\u0026rdquo; 的解决方案。这里我分享一种更贴合国内环境、相对实用的方案。\n常见家用分流方案\r静态路由表分流 Layer 3\r最常见的做法是导入 ChinaIP 地址列表, 采用 \u0026ldquo;取反\u0026rdquo; 的方式: 国内流量直连 (电信走电信、联通走联通), 其余海外流量走隧道。这也被称为大陆白名单模式。\n常见方式包括:\n直接导入 ChinaIP.txt\n做法: 下载并导入 ChinaIP.txt 地址列表 缺点: 需要不定期手动更新路由表 项目死的快, 容易失效 主路由定时更新 ChinaIP.txt\n做法: 在主路由上定时执行脚本, 下载并更新 ChinaIP.txt 缺点: 更新时需全量删除并重新加载地址表, 过程较慢 更新过程中连接会短暂中断 旁路由 + OSPF 热更新 + 脚本每日更新\n做法: 在旁路由上通过 OSPF 协议实现路由表热更新, 并用脚本每天自动更新 ChinaIP.txt 优点: 在三种方式中相对最佳, 能自动化热更新 缺点: OSPF 仅适用于局域网, 若直接与 VPS 建立 Peer, 会导致严重卡顿 域名表分流 Layer 7\r通过域名表来分流, 仅代理特定域名的流量。\n优点: 逻辑清晰, 直接按域名分流 缺点: 每个设备都需要部署客户端 (如 V2Ray、Clash、Shadowrocket 等), 而一些设备 (如 Apple TV、HomePod) 不支持安装应用, 设备多了之后维护很麻烦 传统方案的三大通病\r无论是基于 静态路由表 还是 域名表, 都有以下共同缺陷:\n没人维护\n路由表、域名表都需要维护。通常做这类免费项目的人大多都是 \u0026ldquo;三分钟热度\u0026rdquo;, 后续更新是个问题 更新延迟\nISP \u0026amp; IDC 的 IP 段调整不会实时同步 即使是最勤快的项目, 用脚本从 bgp.he.net 抓取数据, 也只能做到 1 天 1 更, 而 HE 的数据本身就有约 24 小时延后。 分类粗糙\n路由表通常只能细化到 \u0026ldquo;国家级别\u0026rdquo; 少部分项目会提供主流 ASN 的 IP Range, 但很难保证每日更新全部 ASN 最终会造成流量浪费, 甚至让 \u0026ldquo;加速器\u0026rdquo; 变成 \u0026ldquo;减速器\u0026rdquo;, 这样的 Debuff 效果。\nBGP Take Me Home: BGP 路由表分流\r在前文中我们分析了基于静态路由和域名嗅探的分流方案, 它们虽然常见, 但在更新延迟、分类粗糙、没人维护 等方面存在硬伤。\n为了解决这些问题, 可以采用 BGP 路由表 分流。\n优势: 可通过上游实时获取最新的路由表。一旦某个 ASN 的 IP 宣告发生变化, 几秒钟内即可同步更新。 精度: 基于 ASN 的分流比基于国家或域名的方式精确得多。 拓展玩法: 一些丧心病狂的 BGPlayer 甚至会在同一 ASN 内, 根据 GeoIP 打上 Community 标签, 实现更细粒度的 \u0026ldquo;二次分流\u0026rdquo; 这次打算做成 白名单出海 模式:\n从上游收到全表 (IPv4 约 98 万条) 家里的 RouterOS 建立 BGP Peering 基于 ASN 与特定 IP 段过滤得到「要出海的 IP」列表 改写网关指向海外网关, 并将其导入主路由表。 前提条件: 如何收表\r说了那么多\u0026hellip; 既然要基于 BGP 分流, 首先需要把 \u0026ldquo;表\u0026rdquo; 收回家。常见方法有两类\n方法一: 自己动手丰衣足食\r如果你愿意自己折腾, 可以直接从 VPS 厂商获取 BGP session。\n最方便、门槛最低的选择是 Vultr:\n创建一个 VPS, 然后提交工单开通能收全表 BGP session 使用 Bird 2 收全表, 即使是最低配置的 1 核 0.5GB VPS 也能胜任 如果没有 RIR 分配的 ASN, 可以直接使用 Private ASN 建立会话 具体步骤:\n租一个 /48 的 IPv6 段 (约 5-10 欧元/月) 找 Vultr 代广播这个 IPv6 段, 并开通 BGP session 功能 部署 BGP 路由软件收表: RouterOS v7 CHR: 收 IPv4+IPv6 全表时, CPU 使用率长期占用 68% (6 美元/月) Bird 2: 最低配置 VPS (3.5 美元/月) 即可轻松收下 IPv4+IPv6 全表 没错开通 BGP session 后, 你可以直接从 Vultr 收到完整的 IPv4 和 IPv6 路由表。不需要自己拥有 ASN, 只需把 IP 挂靠在 Vultr 的 ASN 下即可。\n方法二: 抱大腿\r如果不想自己折腾, 也可以走 \u0026ldquo;社交路线\u0026rdquo;:\n在 Telegram 群里寻找愿意互联的玩家, 建立 Peer\n屁股里夹着 5 毛硬币, 在 TG 群里高声呼喊\n\u0026ldquo;我就是那个要和你们 Peer 的网友！\u0026rdquo; 🤣 或者直接和作者 PY, 请求分享路由表\n收表其实并不难, 只需要使用 BGP 保留的 私有 ASN:\n16 位: 64512 - 65534 32 位: 4200000000 - 4294967294 这类 ASN 就像内网保留 IP 段一样, 可以在私下尽情使用。把上游收来的全表重分布到本地私有 ASN 就可以了。\n收表与配置\r首先, 在 VPS 上使用 CentOS 7 + Bird 2 搭建环境。先与 Vultr 建立 IPv4 的 BGP 会话, 从 Vultr 接收完整的路由表。由于 Vultr 自带路由过滤策略, 因此不必担心会收到 bogon 地址或异常路由条目。\n同时, 在 VPS 上再建立一个 BGP 会话, 用于连接家里的 RouterOS, 并将接收到的完整路由表导出给本地路由器。这样, 家里的 RouterOS 就能通过 VPS 获得全表, 而无需直接与上游运营商建立会话。\n示例 Bird 2 配置\nlog syslog all;\rrouter id 100.101.102.103;\ripv4 table bgp4;\rprotocol device {}\rprotocol direct {}\rprotocol static {}\rprotocol bgp TRANSIT_V4 {\rdescription \u0026#34;AceSheep BGP New Jersey\u0026#34;;\rlocal as 123456;\rhold time 90;\rgraceful restart;\rmultihop 2;\rpassword \u0026#34;1522zzwlwlbb\u0026#34;;\rsource address 100.101.102.103;\rneighbor 169.254.169.254 as 64515;\ripv4 {\rtable bgp4;\rimport all;\rexport none;\r};\r}\rprotocol bgp PEER_HOME {\rdescription \u0026#34;Country Road Take Me Home\u0026#34;;\rlocal as 65500;\rgraceful restart;\rmultihop 2;\rpassword \u0026#34;1522zzwlwlbb\u0026#34;;\rsource address 172.16.0.1;\rneighbor 172.16.0.2 as 65500;\ripv4 {\rtable bgp4;\rimport none;\rexport all;\r};\r} 建立隧道\r由于家宽公网 IP 大多是动态的, 而 BGP 需要固定 IP, 所以通常不能直接和 Vultr 建立 BGP。更重要的是, GFW 会拦截 BGP 协议。\n因此需要先建立一个隧道, 把家里的 ROS 和 VPS 拉到同一个 \u0026ldquo;虚拟局域网\u0026rdquo; 里, 常见选择:\nIPSec GRE WireGuard ZeroTier 隧道建立好后, 再通过隧道连接 BGP\nRouterOS 配置流程\r在 VPS 上成功收取全表并准备好 BGP 转发后, 接下来需要让家里的 RouterOS 与 VPS 建立 BGP 会话, 通过 VPS 中转, 将完整的 IPv4 路由表同步到家里的路由器。\n建立过滤规则\r在配置 BGP 时, 合理的过滤规则非常重要。它不仅可以避免无用路由的引入, 也能防止错误的路由被发布出去, 从而确保网络的稳定与安全。\n我们采用 默认拒绝、逐步放行 的过滤思路。默认情况下导入和导出均不允许任何路由, 然后再根据需要逐步放行。这样可以避免误操作导致的全表泛滥。\n进入 Routing -\u0026gt; Filters 界面, 新建导入与导出规则。\n因此我们先新建两个空规则: BGP-HOME-IN (导入规则) 和 BGP-HOME-OUT (导出规则)。初始状态下, 两者都直接丢弃所有路由, 确保没有未经过滤的路由被引入或发布。\n新建导入规则, BGP-HOME-IN\n新建导出规则, BGP-HOME-OUT\n这样一来, 可以建立 BGP 会话了, 不会立即交换任何路由。\n建立 BGP 实例\r在 RouterOS 中, 所有的 BGP 会话都基于实例运行, 因此首先需要新建一个实例\n进入 Routing -\u0026gt; BGP, 在 Instances 选项卡中添加一个新的模板。\n配置示例\nName: Country Road Take Me Home AS: 这里使用私有 AS 号, 范围为 64512 - 65535, 可以根据实际情况自选一个。例如本文使用 65500 Router ID: 通常填写路由器的 IPv4 地址, 用于在 BGP 网络中唯一标识 # 默认情况下, 如果一个路由器同时作为多个 BGP Client 的 Route Reflector (RR), 它会在客户端之间转发路由。 # 但在我们的场景中, 路由器只是单纯作为边缘设备, 与上游或下游建立 BGP 会话, 不承担 \u0026#34;路由反射器 (Route Reflector)\u0026#34; 的角色, 那么就不需要在客户端之间反射路由。 # 这样路由器只会处理自己与对等体之间的路由, 不会产生多余的转发。 Client To Client Reflection: 取消勾选 建立 BGP 会话\r完成实例配置后, 接下来在 Peers 选项卡中新建一个与 VPS 的 BGP 会话。\n进入 Routing -\u0026gt; BGP -\u0026gt; Peers\n配置示例\nName: PEER_HOME Instances: Country Road Take Me Home Remote address: 172.16.0.2 # 对端 VPS 的隧道内网地址 Remote AS: 65500 # VPS 使用的私有 AS 号, 需要和之前配置一致 TCP MD5 Key: 1522zzwlwlbb # 可选项, 如果双方配置了密码, 这里要保持一致 Hold Time 240 Keepalive: 60 In Filter: BGP-HOME-IN Out Filter: BGP-HOME-OUT 其中 In Filter 和 Out Filter 的配置非常关键, 避免因为配置失误造成网络环路或路由污染。\nBGP-HOME-IN: 主要作用是决定接收到的路由如何处理 BGP-HOME-OUT: 主要作用是决定向外部广播哪些路由, 避免把无关或错误的路由扩散到外部 配置完成后, RouterOS 会尝试与 VPS 建立 BGP 会话。一旦邻居关系成功建立, 就能从 VPS 获取完整的 IPv4 路由表, 并根据过滤策略导入到本地路由表中。\n策略路由: 分流\r一套简单的分流逻辑可以定义为:\n国内流量 联通: 默认网关, 走联通 电信 (China Telecom / CHINANET): 电信的流量走电信线路 海外流量 海外 CDN 服务 (Fastly、Amazon、Cloudflare、Akamai 等): 走 \u0026ldquo;留学\u0026rdquo; 通道 海外大公司 (Google、Telegram、Netflix、Facebook、Wikipedia、GitHub): 走 \u0026ldquo;留学\u0026rdquo; 通道 通过这种方式, 就能把电信和联通两条线路融合起来, 对国内的访问尽量走本地运营商, 减少跨网访问带来的延迟和丢包；同时对海外常用服务进行优化, 让出国流量更顺畅。\n分流规则\r接下来, 我们需要在 BGP-HOME-IN 过滤器中逐步放行需要的路由。\n这里导入的规则作用主要是决定接收到的路由如何处理:\n是否放行或丢弃特定前缀 是否修改下一跳 (Next Hop) 是否添加路由注释 (例如标识路由来源) 是否检查网关的可达性 在 Route Filter 的 Action 选项卡中, 可以对接收到的路由进行进一步处理:\nSet in Nexthop: 指定下一跳地址 (适用于静态 IP 场景) Set in Nexthop Direct: 直接指定出口接口 (如 PPPoE 拨号) Set Route Comment: 为路由增加注释, 方便管理 Set Check Gateway: 启用网关检测, 避免链路异常导致黑洞路由 Set Routing Mark: 将路由导入到指定的路由表, 然后配合 ip route rule 或 mangle 实现策略路由 (例如不同设备/子网走不同出口)。若不设置, 默认 BGP 学到的路由会进入 main 表 BGP AS Path 匹配\r通过 AS Path 规则可以对特定来源的路由进行精细化控制。\n示例规则\n含义: 匹配所有以 AS16509 或 AS14618 结尾的路由\n_16509$|14618$ 编写 AS Path 规则时, 只需要记住几个要点:\n以 _ 开头, 表示匹配 ASN 的边界 ASN 后面加 $ 表示匹配结尾 多个 ASN 之间用 | 分隔 这样就能灵活定义需要留学/跨境的海外流量\n常用 ASN 参考\r为了方便大家快速上手, 我也整理了一份常用 ASN 列表, 覆盖了大部分国内运营商、海外 CDN 以及常见互联网巨头。\n# Google 15169 # Google Extra ASNs 396982, 395973, 36492, 36411, 36383, 36040, 19527 # Telegram 62041, 62014, 59930 # Netflix 55095, 40027, 2906 # Akamai 49846, 43639, 393560, 393234, 36183, 35994, 35204, 34164, 33905, 32787, 31984, 31108, 26008, 24319, 21342, 213120, 20940, 200005, 18717, 18680, 17204, 16625, 12222 # Facebook 32934, 63293, 54115 # Wikipedia 14907 # GitHub 36459 # Twitter 13414, 35995, 63179 # Equinix Services 54825 # Fastly 54113 # Amazon (AWS) 16509, 14618 # EdgeCast 15133 # Cloudflare 13335 # ChinaNet / CHINANET (骨干网 / 电信 CN2 等) 4810, 4811, 4812, 4816, 4835, 4134, 44218, 17998, 36678, 63810 - 63825, 59300 - 59391, 59223 - 59299, 58769 - 58776, 58563 - 58574, 58466, 58461, 58517, 58518, 58539 - 58543, 136188 - 136200, 134756 - 134775, 134238, 133774 - 133776, 132225, 132437, 132833, 131325, 139015, 139587, 139586, 139585, 139767, 140083, 140527, 140636, 140638, 140903, 141006, 141025, 141679, 141739, 141771, 141998, 142404, 142608, 146966, 147038, 148969, 148981, 149178, 149837, 149839, 149979, 150145, 151058, 151185, 151397, 151628, 151823 需要注意的是, RouterOS 的 Route Filter Chain 是从上往下依次执行的, 遇到匹配规则后就会生效, 因此要合理安排规则顺序。\nBGP Take Me Home, 让分流真正做到科学、实时、个性化\n科普\r路由器的选路原则\r在路由器中, 路由表 (Main 表) 里可能会同时存在多种来源的路由, 比如直连路由、静态路由、BGP、OSPF 等。\n当多条路由指向同一个目标网段时, 路由器就需要进行 \u0026ldquo;选路\u0026rdquo;。\n不同路由协议的优先级由 distance (管理距离) 来决定, 常见的默认值如下\n协议 distance 直连路由 0 静态路由 1 eBGP 20 OSPF 110 RIP 120 MME 130 iBGP 200 路由器的具体选路逻辑\r路由器在选择路由时, 通常遵循以下规则:\n最长前缀优先 子网掩码越大 (网络范围越小), 路由越 \u0026ldquo;精确\u0026rdquo;, 优先级就越高。 比如同时存在 1.1.1.0/24 和 1.1.1.0/25, 无论 distance 设置多少, 都会优先选择更具体的 /25 路由。 比较 distance 如果前缀长度相同, 才会比较各路由的 distance 值, 数值越小越优先。 例如静态路由 (distance 1) 会覆盖 eBGP (distance 20) 的路径。 负载均衡/ECMP 当多条路由前缀与 distance 都一致时, 路由器可能会启用 ECMP (等价多路径), 把流量分摊到多条路径上。 举个例子\r假设你通过 iBGP 收到了一条 1.1.1.0/24 的路由, 并且在 Filter 中统一设置了它的出口走 电信链路\n但是, 你希望这条流量改走另一个出口 (比如联通), 该怎么做呢？\n解决办法就是添加一条静态路由:\n指定 1.1.1.0/24 的下一跳为联通出口 由于静态路由的 distance 默认为 1, 比 iBGP 的 200 更优先 最终路由器会选择你配置的静态路由来转发数据 这样就能 \u0026ldquo;强制\u0026rdquo; 覆盖 BGP 下发的路径, 实现更灵活的路由控制。\n原文\nMikrotik 通过ASN分流\n在家也要玩BGP 之 Mikrotik Fan Boy版\n在家也要玩BGP（1）：简单的多运营商接入策略路由配置\n家用垃圾网络 · 软路由启动\n在家也要玩BGP（1.5）：我的双线分流规则\n","date":"2024-03-23T17:46:22+08:00","permalink":"https://blog.acesheep.com/p/bgplayer-beginner-guide-asn-routing-with-bgp-on-routeros-v6/","title":"BGPlayer 从零开始速成指北 - 在家用 MikroTik RouterOS v6 通过 BGP 按照 ASN 分流"},{"content":"WireGuard 是一个在 Linux 内核中运行的高性能 VPN 协议, 与 OpenVPN 相比, 它的配置更加简洁、运行速度更快, 并且安全性设计更为现代。\n自 Linux 内核 5.6 起, WireGuard 已被直接合并进内核, 这意味着系统可原生支持 WireGuard, 无需额外安装内核模块。\n更新内核\rCentOS 7 默认内核版本为 3.10.0, 版本过低无法直接使用 WireGuard。这里提供一个简单的更新内核示例, 更新完需重启系统。\nrpm -ivh kernel-ml-6.9.7-1.el7.elrepo.x86_64.rpm rpm -ivh kernel-ml-devel-6.9.7-1.el7.elrepo.x86_64.rpm rpm -ivh kernel-ml-headers-6.9.7-1.el7.elrepo.x86_64.rpm reboot # 验证更新是否成功 uname -r NAT 转发规则\r如果仅需通过 WireGuard 建立内网隧道, 可以跳过本节。\n若需要让客户端通过 VPN 访问外网, 则必须配置 NAT 转发, 否则会出现 \u0026ldquo;VPN 已连接但无法上网\u0026rdquo; 的问题。\n首先, 启用 Linux 的 IPv4 转发功能\necho \u0026#34;net.ipv4.ip_forward = 1\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf echo \u0026#34;net.ipv4.conf.all.proxy_arp = 1\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf echo \u0026#34;net.ipv6.conf.all.forwarding = 1\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf sysctl -p 执行以上命令后, 系统会允许数据包在不同网卡之间转发, 从而实现 VPN 客户端访问外网。\n安装 WireGuard\r安装方式有多种, 由于我们已更新到支持 WireGuard 的内核版本, 因此直接安装内核模块与工具\nyum install epel-release elrepo-release -y yum install yum-plugin-elrepo -y yum install kmod-wireguard wireguard-tools -y 检查内核模块\n# 加载内核模块 modprobe wireguard # 检查 WireGuard 模块是否加载成功 lsmod | grep wireguard 生成密钥\r创建配置文件目录\nmkdir -p /etc/wireguard/ cd /etc/wireguard 生成服务端和客户端的公私钥\n# 服务端密钥 wg genkey | tee server_private.key | wg pubkey | tee server_public.key # 客户端密钥 wg genkey | tee client_private.key | wg pubkey | tee client_public.key 创建配置文件\r编辑服务端配置文件 (示例文件名: wg-ibgp-home.conf)\nvim /etc/wireguard/wg-ibgp-home.conf 示例配置\n[Interface]\rAddress = 172.16.0.1/24\r# SaveConfig = true\rListenPort = 52346\rPrivateKey = EP3ZQgmMTsKpxQufh7bwDFPtdD6cyXMCiyhr/VXVulI=\r[Peer]\rPublicKey = d0F1bEFFSgkapZtXu6UlZ0zQNroLtaq51qASL3mKwBY=\rAllowedIPs = 172.16.0.2/32\r[Peer]\rPublicKey = d0F1bEFFSgkapZtXu6UlZ0zQNroLtaq51qASL3mKwBY=\rAllowedIPs = 172.16.0.3/32 配置说明\n# 服务端配置块 [Interface] Address # 服务端内网地址 (需与现有网络不冲突) # 可选范围: # 10.0.0.0 - 10.255.255.255 (10/8 prefix) # 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) # 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) # 格式示例: 172.16.0.1/24 表示内网地址及子网掩码 SaveConfig # 是否在服务停止时自动保存当前运行时配置到文件 (true/false) # 建议调试阶段设为 false, 避免修改原始配置文件 ListenPort # WireGuard 监听端口 (UDP), 需在防火墙或路由器中开放 # 默认端口 51820, 可自定义, 例如 52346 PrivateKey # 服务端私钥 (通过 wg genkey 生成), 必须与公钥配对 DNS # 分配给客户端的 DNS 服务器地址, 可填写多个 (用逗号分隔) # 示例: 8.8.8.8, 1.1.1.1 PostUp # 启动 VPN 时执行的命令, 如配置 NAT 转发、iptables 规则等 PostDown # 关闭 VPN 时执行的命令, 用于清理 PostUp 添加的规则 # 客户端配置块 (可添加多个客户端) [Peer] PublicKey # 客户端的公钥 (通过 wg pubkey 生成) AllowedIPs # 客户端允许访问的 IP 地址范围, 通常填写客户端分配的内网 IP # 示例: 172.16.0.2/32 表示分配单个固定 IP 设置权限\rchmod -R 600 /etc/wireguard/ 配置防火墙\r方法一\rfirewall-cmd --permanent --add-port=52346/udp firewall-cmd --reload firewall-cmd --list-all netstat -nlptu 方法二\r编辑配置文件\nvim /etc/firewalld/services/wireguard.xml 填写以下内容\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;service\u0026gt; \u0026lt;short\u0026gt;wireguard\u0026lt;/short\u0026gt; \u0026lt;description\u0026gt;WireGuard (wg) custom installation\u0026lt;/description\u0026gt; \u0026lt;port protocol=\u0026#34;udp\u0026#34; port=\u0026#34;51820\u0026#34;/\u0026gt; \u0026lt;/service\u0026gt; 执行命令\nfirewall-cmd --add-service=wireguard --permanent firewall-cmd --add-masquerade --permanent # 需要 NAT 转发时才需要执行这个 firewall-cmd --reload firewall-cmd --list-all 启动与管理 WireGuard\r启动 VPN\nwg-quick up /etc/wireguard/wg-ibgp-home.conf 停止 VPN\nwg-quick down /etc/wireguard/wg-ibgp-home.conf 设置开机启动\nsystemctl enable wg-quick@wg-ibgp-home 不中断连接的情况下重新加载配置\n这里的 wg-ibgp-home 是接口名, 来自配置文件名 wg-ibgp-home.conf (去掉路径和 .conf 后的部分)\nwg syncconf wg-ibgp-home \u0026lt;(wg-quick strip /etc/wireguard/wg-ibgp-home.conf) 查看当前状态\n[root@BGP-US-LV ~]# wg interface: wg0 public key: sIPp+stGXBz private key: (hidden) listening port: 51820 peer: zy3IkHgq6Sd allowed ips: 10.10.0.2/32 peer: t6ab6f6j2Rw allowed ips: 10.10.0.3/32 原文\nWireGuard - Installation\nCentOS 7 Wireguard 实践小记\nCentos 7 下安装 Wireguard\n在CentOS7上安装部署WireGuard\nHow To Set Up WireGuard on Ubuntu 20.04\n","date":"2024-03-12T20:33:40+08:00","image":"https://blog.acesheep.com/p/centos7-wireguard-setup/cover_hu10945283551226129095.png","permalink":"https://blog.acesheep.com/p/centos7-wireguard-setup/","title":"Centos 7 搭建 WireGuard 服务器"},{"content":"接着上一篇《使用 MikroTik RouterOS v7 广播你的 IP》, 我们来说说为什么还要换成 Bird 2 广播 IP 呢。\n虽然 MikroTik RouterOS v7 是专为路由器打造的系统, 但它也有一些缺点:\n收费限制: 这是收费软件, 只有 60 天试用期, 过期后限速 1 Mbit/s。\n功能单一: 作为一个定制系统, 只能用来做路由器, 无法运行其它程序。\n资源占用高: 在 Vultr AMD High Performance 1 核 1GB 内存 ($6/月) 上, 30 天平均 CPU 占用 68%, 内存占用 563 MiB。\n性价比问题: Bird 可以在 Vultr Regular Cloud Compute 1 核 512 MB 内存 ($3.5/月) 上同时接收 IPv4 和 IPv6 全表, 30 天平均 CPU 占用不到 2%, 内存占用低于 300 MiB。\n综上所诉, 使用 Linux 发行版系统搭配 Bird 2 (Internet Routing Daemon) 不仅免费, 还可以运行其他程序, 可玩性更高。\n安装 BIRD 2.14\rBird 1.6.x 和 Bird 2.x 的最大区别是:\nv1 版本 IPv4 和 IPv6 分别是 bird 和 bird6 两个程序 v2 版本合并成了一个 bird, 同时支持 IPv4 和 IPv6 官方文档: BIRD 2.14 User\u0026rsquo;s Guide\n本文使用 Cnetos 7 系统, BIRD version 2.14\nyum install bird2 -y 建立 BGP 连接并广播你的 IP\r如果你之前用过 RouterOS v7 配置 BGP, 那么换到 BIRD 会简单很多。\nBird 的配置文件路径为 /etc/bird.conf\n我们要建立 IPv4 和 IPv6 的 Peer, 并在 IPv6 的 Peer 上广播 2a0a:6000:1::/48\n查看 Vultr 提供的 BGP 信息\r在 Vultr VPS 面板的 BGP 选项卡可以找到以下参数\nInstance Vultr ASN 66666 64515 IPv4 100.101.102.103 169.254.169.254 IPv6 2a05::1 2001:19f0:ffff::1 BGP Password 51522zzwlwlbb Multihop 2 添加全局配置\r打开 /etc/bird.conf 文件后里面有很多默认配置和注释, 我们把所有内容都注释掉从头开始配置\n# 日志\rlog stderr all;\rlog \u0026#34;/var/log/bird.log\u0026#34; all;\r# Router ID (只不过是个名字, 通常用路由器公网 IPv4 地址)\rrouter id 100.101.102.103;\r# 监控网卡状态\r# This pseudo-protocol watches all interface up/down events.\rprotocol device {\r} 创建 BGP 模板\r新建一个 BGP Template\ntemplate bgp template_ebgp {\rdescription \u0026#34;AceSheep BGP Test\u0026#34;; # 自己起一个, 便于自己识别即可\rlocal as 66666; # 你的 ASN\rhold time 90; # 默认 240\rmultihop 2; # 如果上游告诉你 Multihop 是 2 这里就要加上\rpassword \u0026#34;51522zzwlwlbb\u0026#34;; # 由上游提供\r} 配置 IPv4 Peer\r建立 IPv4 Peer 并设置过滤\nprotocol bgp TO_PEER_VULTR_V4 from template_ebgp {\rsource address 100.101.102.103; # 实例 IPv4\rneighbor 169.254.169.254 as 64515; # 上游 IPv4 和 ASN\ripv4 {\rimport all; # 接受所有上游给我们的路由表\rexport none; # 丢弃所有发送到上游路由表\r};\r} 配置 IPv6 Peer 并允许广播前缀\r建立 IPv6 Peer, 设置过滤, 并允许要广播 IPv6 前缀\nprotocol bgp TO_PEER_VULTR_V6 from template_ebgp {\rsource address 2a05::1; # 实例 IPv6\rneighbor 2001:19f0:ffff::1 as 64515; # 上游 IPv6 和 ASN\ripv6 {\rimport all; # 接受所有上游给我们的路由表\rexport filter {\rif net = 2a0a:6000:1::/48 then accept; # 如果前缀为 2a0a:6000:1::/48 则允许发送到上游路由表\rreject; # 拒绝所有发送到上游路由表\r};\r};\r} 至此 IPv4 和 IPv6 的 Peer 就设置好了\n宣告要广播的 IPv6 前缀\r设置要广播的 IPv6 前缀, IPv4 最小 /24, IPv6 最小 /48\nprotocol static {\r# route [要广播的 IPv6 前缀] via [实例的 IPv6];\rroute 2a0a:6000:1::/48 via 2a05::1;\r} 完整配置文件\r可用于在 Vultr、BuyVM、iFog 上广播, 最基础的广播配置\n# 日志\rlog stderr all;\rlog \u0026#34;/var/log/bird.log\u0026#34; all;\r# Router ID (只不过是个名字, 通常用路由器公网 IPv4 地址)\rrouter id 100.101.102.103;\ripv4 table bgp4;\ripv6 table bgp6;\rprotocol device {\rscan time 10;\r}\rprotocol kernel {}\rprotocol direct {\ripv6;\rinterface \u0026#34;dummy*\u0026#34;;\r}\rprotocol static {\ripv6 {\rtable bgp6;\r};\r# route [要广播的 IPv6 前缀] via [实例的 IPv6];\rroute 2605:6400:ffff::2/128 via 2605:6400:30::1;\r}\rtemplate bgp template_ebgp {\rdescription \u0026#34;AceSheep BGP Test\u0026#34;;\rlocal as 66666;\rhold time 90;\rmultihop 2;\rpassword \u0026#34;51522zzwlwlbb\u0026#34;;\rgraceful restart on;\r}\rprotocol bgp TO_PEER_VULTR_V4 from template_ebgp {\rsource address 100.101.102.103;\rneighbor 169.254.169.254 as 64515;\ripv4 {\rtable bgp4;\rimport all;\rexport none;\r};\r}\rprotocol bgp TO_PEER_VULTR_V6 from template_ebgp {\rsource address 2a05::1;\rneighbor 2001:19f0:ffff::1 as 64515;\ripv6 {\rtable bgp6;\rimport all;\rexport filter {\rif net = 2a0a:6000:1::/48 then accept;\rreject;\r};\rexport limit 25;\r};\r} 启动 Bird\r接下来启用调试消息并在前台运行 bird\nbird -d 或者设置为开机启动\nsystemctl enable bird systemctl start bird systemctl status bird 检查 BGP 会话状态\r现在检查一下 Peer 建立的状态\n# 查看 BGP 会话状态 birdc show proto birdc s p # 等效命令 # 查看路由表里现在有多少前缀 birdc show route count 如果 TO_PEER_VULTR_V4 和 TO_PEER_VULTR_V6 的状态都是 Established 说明连接成功, 并接收到了全表。\nIPv4 有 951576 条前缀, IPv6 有 197619 条前缀\n[root@BGP ~]# birdc s p BIRD 2.14 ready. Name Proto Table State Since Info device1 Device --- up 2024-02-29 direct1 Direct --- up 2024-02-29 static1 Static --- up 2024-02-29 TO_PEER_VULTR_V4 BGP --- up 2024-02-29 Established TO_PEER_VULTR_V6 BGP --- up 2024-02-29 Established # 显示路由前缀数量 [root@BGP ~]# birdc show route count BIRD 2.14 ready. 951576 of 951576 routes for 951576 networks in table master4 197619 of 197619 routes for 197619 networks in table master6 Total: 1149195 of 1149195 routes for 1149195 networks in 2 tables 至此, 已经完成建立 BGP 连接并广播你的 IP\n如果想在 bgp.he.net 上查询到自己的前缀, 则需要等待 24 小时才能看到\n添加一个自己广播的 IP 并测试连通性\r目前我们已经成功地把 2a0a:6000:1::/48 宣告出去了\n此时全球访问 2a0a:6000:1::/48 的流量就已经被路由到我们这台 vps 上了, 不过我们的 vps 现在被配置为 \u0026ldquo;什么都不做\u0026rdquo;, 会直接返回 unreachable. 我们现在只需要在 vps 上做一些小小的配置就能为全球提供服务了\n添加 Direct 协议\r编辑配置文件 /etc/bird.conf, 添加以下内容\nprotocol direct {\ripv6;\rinterface \u0026#34;dummy*\u0026#34;;\r} :wq 保存文件\n热重载配置\r使用命令热重载配置文件\nbirdc configure 添加虚拟网卡和 IPv6 地址\r配置虚拟网卡以及 IPv6 地址\n# 添加虚拟网卡 ip link add dev dummy1 type dummy # 启用虚拟网卡 ip link set dummy1 up # 添加地址 # 例如随便从 `2a0a:6000:1::/48` 前缀内任意选一个地址使用, 以 /128 结尾 ip addr add dev dummy1 2a0a:6000:1::1/128 完成后, 我们就可以从自己的电脑上 ping 通 2a0a:6000:1::1 这个地址了\n注意: 这种方式在重启后网卡会失效, 需要重新配置网卡。\n测试 Ping\r添加好之后用另一台 VPS Ping 这个 IPv6 地址\n此时我们已经可以在 vps 上架设任何需要的服务, 并让别人通过 2a0a:6000:1::1 访问, 我这里使用 python3 启动一个简单的 HTTP 服务器\npython3 -m http.server -b :: 80 实名上网\r在 vps 上我们也可以使用 2a0a:6000:1::1 去访问别的网站 实现实名上网\n[root@BGP-LUX ~]# curl -6 www.cloudflare.com/cdn-cgi/trace --interface 2a0a:6000:1::1 fl=64f75 h=www.cloudflare.com ip=2a0a:6000:1::1 ts=1754996299.004 visit_scheme=http uag=curl/7.29.0 colo=ZRH sliver=none http=http/1.1 loc=LU tls=off sni=off warp=off gateway=off rbi=off kex=none [root@BGP-LUX ~]# curl -6 ip.sb --interface 2a0a:6000:1::1 2a0a:6000:1::1 [root@BGP-LUX ~]# curl -6 ifconfig.co --interface 2a0a:6000:1::1 2a0a:6000:1::1 原文\n年轻人的第一个私人BGP(二) - 广播你的IP\nBIRD 与 BGP 的新手开场\n自己在家开运营商 Part.2 - 向世界宣告 IP 段 (BGP Session \u0026amp; BIRD)\nBGP_example_1\nBGP_filtering\nIPv4/IPv6 CIDR 地址计算器\nIPv6子网计算器\nIPv6 Address Expander\nIPv6 Address Shortener\n","date":"2024-03-07T18:35:03+08:00","permalink":"https://blog.acesheep.com/p/bgplayer-beginner-guide-announce-prefix-with-bird2/","title":"BGPlayer 从零开始速成指北 - 使用 Bird 2 广播你的 IP"},{"content":"ASN 和前缀都已经在 Vultr 上开通好了, 现在终于可以把自己的 IP 广播出去了。\n大多数教程用的都是 Bird 2, 虽然功能强大, 但这些对于新手来说都太难了。所谓的 BGPlayer, 就是要把 BGP 当作一款可以 \u0026ldquo;玩\u0026rdquo; 的游戏, 而不是死磕命令行的苦差事。\n如果能用一个可视化的操控界面来管理 BGP, 那学习过程就会 Fun and Joy 多了。这里我们选择 Mikrotik RouterOS v7 CHR 来做 BGP 实验, 它提供了友好的图形化配置界面 Winbox, 让你不用敲一行命令就能上手。\n刷入 RouterOS CHR 并连接 Winbox\r首先, 将你的 VPS 安装成 Mikrotik RouterOS v7 CHR 系统。\n安装完成后, 使用 Winbox 连接到 VPS, 就能开始图形化配置 BGP。\n创建路由表过滤规则 (Routing Filters)\rBGP 广播之前, 第一件事就是确保不漏路由, 防止把全网乱七八糟的前缀发给上游。官方文档\n在 routing -\u0026gt; filters 菜单中新建规则。\n创建一个名为 BGP-IN 的 Chain, 规则内容填写 accept, 这表示接受所有来自上游的路由。\n再创建一个名为 BGP-OUT 的 Chain, 规则内容填写 reject, 这表示默认拒绝对外发布的所有路由。\n新建一条同样属于 BGP-OUT Chain 的规则, 内容填写\nif (dst == 2a0a:6000:1::/48) { accept; } 意思是: 如果目标网段是你的 IPv6 前缀 (这里示例是 2a0a:6000:1::/48), 则允许广播。\n然后 务必将这条规则拖到 reject 规则的上方, 因为 Mikrotik 的过滤器是 从上到下顺序执行 的。\n这样配置后, 你的路由器只会把自己的前缀发给上游, 其它一律丢弃, 实现了 \u0026ldquo;先放行自己、再全面封锁\u0026rdquo; 的安全策略。\n获取 Vultr 上游信息\r在 Vultr 控制台的 BGP 页面, 可以查看到上游的 IP、ASN、BGP 会话信息等, 这些都是配置 RouterOS BGP 所需的参数。\n创建 BGP 会话\r创建 BGP 模板\r在 RouterOS 中先创建一个 BGP Template, 填写自己的 ASN 和 Router ID 等基础信息。\n设置需要广播的前缀\r将你的前缀加入 IPv6 Firewall Address List, 这样 RouterOS 就知道哪些是要广播的网络。\n新建 BGP 会话\r使用刚才的模板导入配置, 然后为 IPv4 和 IPv6 分别创建 BGP 会话, 填入 Vultr 提供的上游 IP 地址。\n按照图片上的参数设置\n检查会话状态\r成功建立连接后, 你会在 BGP 的 Sessions 选项卡中看到前缀数量, 这意味着已经从上游获取到了 Full Table 的路由。\n给本机分配 IP\r最后一步, 在 IPv6 Addresses 菜单中给 VPS 分配一个属于自己前缀的 IPv6 地址。这样, 你的服务器就能用自己广播出去的 IP 上网了。\n原文\nBGPlayer in 1hour 绝赞速成班\nRoute Selection and Filters\n","date":"2024-02-26T17:18:50+08:00","permalink":"https://blog.acesheep.com/p/bgplayer-beginner-guide-advertise-prefix-using-mikrotik-routeros-v7/","title":"BGPlayer 从零开始速成指北 - 使用 MikroTik RouterOS v7 广播你的 IP"},{"content":"Vultr 的 BGP 广播功能可以称得上是对「新手友好」的了。它内置了良好的路由过滤系统, 即使你不小心发布了错误的路由表, 通常也不会泄漏到公网去, 因此不必担心 \u0026ldquo;搞炸网络\u0026rdquo;, 对于想学习 BGP 的人来说, 这是一个很安全的环境。\n拆分 IPv6 地址段\r如果 LIR 分配给你的是一个 /40 的 IPv6 段, 这个地址数量非常庞大。\n由于 IPv6 地址一般是缩写, 无法直观的看出 IP 数量。我们可以使用 IPv4/IPv6 CIDR 地址计算器 计算出 /40 对应的实际 IP 数量。\n这个数量显然用不完, 因此我们需要将它拆分为 /48 的子网后再使用。\n可以使用 IPv6 子网计算器 快速计算出所有的 /48 子网段, 再从里面挑一段使用。\n在 RIPE 数据库添加子网对象\rVultr 在广播你的 IP 前, 需要你在 RIR 数据库 (这里以 RIPE 为例) 添加相应的子网对象。\n进入 RIPE 数据库, 创建一个 inet6num 对象, 为每个 /48 子网设置:\ninet6num (子网地址) netname (子网名称) descr (介绍) country (广播国家) 进入 BGP 开通页面\r首先访问 https://my.vultr.com/bgp/, 即可进入 Vultr 的 BGP 功能开通页面。\n在页面上点击 Get Started 进入申请流程。\n填写 Vultr BGP 申请表\r按照下图填写申请表。\n将 I have my own IP space 和 I have my own ASN 都设置为 YES 在 My ASN 填写你的 ASN (不含 AS 前缀, 例如 23456) 在 BGP Password 填写你想要设定的 BGP 会话密码 在 IP Prefixes 填写你的 IP 前缀 (CIDR 格式) Routes we shoule send you 选择 Full Table LOA (授权信) 可参考以下模板填写 AUTHORIZATION LETTER [日期, 如 Feb 27, 2021] To whom it may concern, This letter serves as authorization for [服务商公司名, 如 Vultr] with [ASN, 如 AS2333] to announce the following IP address blocks: [IP SPACE / ASN / SUBNET] [IP SPACE / ASN / SUBNET] [...] As a representative of the company [公司名称] that is the owner of the subnet and/or ASN, I hereby declare that I\u0026#39;m authorized to represent and sign for this LOA. Should you have questions about this request, email me at [邮箱], or call: [电话号码] From, [姓名] [公司名称] [职位, 如 Network Administrator] [电话号码] 电子邮件验证\r提交完毕之后, Vultr 会提示进入验证流程, 点击 Start 即可开始验证进程。\n选择要接收验证邮件的邮箱, 点击 Send 发送。\n提示 BGP 验证邮件已发送至指定邮箱, 等待验证\n到邮箱中查收验证邮件。邮件里会有两个链接:\n第一个是 允许 (Approve) 第二个是 拒绝 (Deny) 点击第一个即可完成验证。\n打开网页后还需再点一次 Approve Announcement\n验证成功后的提示\n等待开通\r通常 1-3 小时内, 客服会完成 BGP 功能开通。开通后, 你就可以在 Vultr 控制台看到 BGP 会话状态了。\n其他服务商开通方式\r原文\n年轻人的第一个 ASN\n年轻人的第一个私人BGP(二) - 广播你的IP\n","date":"2024-02-25T04:32:19+08:00","permalink":"https://blog.acesheep.com/p/bgplayer-beginner-guide-activate-vultr-bgp-function/","title":"BGPlayer 从零开始速成指北 - 开通 Vultr 的 BGP 广播功能"},{"content":"RIPE 是什么\rRIPE (Réseaux IP Européens Network Coordination Centre) 是 欧洲、中东及部分中亚地区 的区域互联网注册管理机构 (RIR, Regional Internet Registry)。\n互联网的地址分配遵循一个自上而下的层级结构。最顶层是 IANA (Internet Assigned Numbers Authority, 互联网号码分配局), 它负责全球 IP 地址与 ASN (自治系统号) 的顶层分配。IANA 将大块的 IP 地址分配给五个区域互联网注册机构 (RIR), 其中就包括了 RIPE。\n每个 RIR 再将地址空间分配给其负责区域内的 NIR (National Internet Registries, 国家互联网注册机构) 或 LIR (Local Internet Registries, 本地互联网注册机构)。最终, LIR 将这些地址分配给 ISP (Internet Service Providers, 互联网服务提供商) 或其终端客户使用。\nRIPE 账号注册步骤\r创建 Person 与 Maintainer 对象\r字段介绍:\nPerson: 记录你的个人联系信息。 Maintainer (mntner): 用来控制谁有权限修改或删除数据库中的对象, 相当于管理账号权限的 \u0026ldquo;钥匙\u0026rdquo;。 首先, 在 RIPE Database 中选择 Role and Maintainer 选项, 进入对象创建页面。\n将对象类型切换为 person, 以便填写具体的个人信息。\n在表单中输入 姓名、地址、电话 个人信息\n确认信息无误后提交, 完成 person 与 maintainer 对象的创建\n创建 Role 对象\r字段介绍:\nRole 用于代表一个部门或团队的联系信息, 比如技术支持组、网络安全组。 通常在 Abuse (滥用投诉) 邮箱中使用 role 对象而不是个人信息。 在 RIPE Database 中新建一个 role 对象。\n填写角色的基本信息, 例如部门名称、地址、邮箱等。\n点击页面右侧的 加号 添加额外字段。\n添加 abuse-mailbox 字段, 用于接收网络滥用或安全相关的投诉邮件。\n确认所有必填和可选字段都已填写, 并检查引用的维护者 (mntner) 是否正确。\n提交表单, 完成 role 对象的创建。\n创建 Organisation 对象\r字段介绍:\nOrganisation 用于在 RIPE 数据库中标识你的组织, 是分配 IP 或 ASN 的必要条件。 必须绑定到之前创建的 Role 和 Maintainer。 选择 Organisation 对象类型进入创建页面。\n填写组织名称、地址、邮箱, 并在 abuse-c 中填写前面创建的 role 名称, mnt-ref 填写 LIR 提供的字段。\n提交确认后, 完成 organisation 对象的创建。\n原文\n一文搞懂全网上线的 IP 属地功能\n[HowTo] Create RIPE Account - Route48\n[HowTo] Create RIPE MNT,ROLE \u0026amp; Abuse Contact\n[HowTo] Create RIPE ORG-ID\n成为互联网自治系统之一\n","date":"2024-02-23T09:25:53+08:00","permalink":"https://blog.acesheep.com/p/bgplayer-beginner-guide-ripe-account-registration-and-basic-fields/","title":"BGPlayer 从零开始速成指北 - RIPE 账号注册与基本字段创建"},{"content":"突然看到 Steam 好友列表都在玩 Palworld。这到底是个啥游戏这么火, 打开 Steam 商店统计一看哦豁热销、游玩都是第一名。\n离游戏发布短短 16 天 43 个好友已拥有??? 什么游戏这么热门!?\n下载启动, 逐渐入迷下机的时候一看时间 7 天过去了。一直都是单机玩的如果可以和小伙伴一起联机该多好啊。但是使用游戏自带的邀请码加入游戏, 需要房主在线才能其他人才能加入游戏。对于这种 RPG 游戏存档很重要, 但是它保存在房主的电脑上, 非常不方便。\n不如我们用云服务器搭建一个游戏服务器, 这样随时都可以加入游戏, 我们睡觉的时候帕鲁也会继续工作。压榨帕鲁让他们 007 的工作\n搭建步骤\r目前, Palworld 服务端存在内存泄漏问题。为了保证能够 24 小时稳定运行, 内存最低为 32 或 64GB\n规格 数值 备注 系统 CentOS 7 也可以使用 Ubuntu 等系统 CPU 4 个虚拟 CPU 官方建议为 4 核以上 内存 16 GB 官方建议为 16GB 以上, 为了稳定运行建议使用 32GB 硬盘 100 GB 截至 2024 年 1 月, 服务器文件总容量为 4.8 GB 公开端口 8211 (UDP) 默认端口 SELinux 已禁用 如果内存很小, 比如在 VPS 中, 可以创建 swap 虚拟内存, 即使物理内存小于官方推荐值也能稳定运行。不过, 这取决于磁盘 I/O 性能。\n禁用 SELinux\rsed -i \u0026#39;s/^SELINUX=enforcing/SELINUX=disabled/\u0026#39; /etc/selinux/config setenforce 0 安装 SteamCMD\r为了安全起见, 使用非 root 用户运行游戏服务端。首先, 以 root 用户身份登录到服务器, 创建一个名为 steam 的用户, 并切换到该用户的环境下\n# 安装 32 位运行依赖 yum install glibc.i686 libstdc++.i686 -y # 创建 steam 用户 useradd -m steam # 切换为 steam 用户 su - steam # 下载 SteamCMD wget http://media.steampowered.com/installer/steamcmd_linux.tar.gz tar -xf steamcmd_linux.tar.gz ./steamcmd.sh 安装 Palworld 服务端\r# 创建安装目录 mkdir PalServer # 进入 steam 命令行 ./steamcmd.sh Steam\u0026gt;force_install_dir ./PalServer # 指定安装目录 Steam\u0026gt;login anonymous # 以匿名身份登录 Steam\u0026gt;app_update 2394010 validate # Palworld 的 App ID 是 2394010 Steam\u0026gt;quit # 退出 steamcmd 启动 Palworld 服务端\rcd PalServer/ ./PalServer.sh 如果遇到找不到 steamclient.so 文件的错误需要按照下面步骤修复\nsteamclient.so: cannot open shared object file: No such file or directory\rdlopen failed trying to load:\r/home/steam/.steam/sdk64/steamclient.so\rwith error:\r/home/steam/.steam/sdk64/steamclient.so: cannot open shared object file: No such file or directory\r[S_API] SteamAPI_Init(): Sys_LoadModule failed to load: /home/steam/.steam/sdk64/steamclient.so\r^CFUnixPlatformMisc::RequestExitWithStatus\rFUnixPlatformMisc::RequestExit\rExiting abnormally (error code: 130)\rShutdown handler: cleanup. 修复步骤\n# 创建依赖文件路径 mkdir -p .steam/sdk64/ # 创建软连接 ln -s /home/steam/linux64/steamclient.so /home/steam/.steam/sdk64/steamclient.so # 检查文件 [steam@server ~]$ ls -al /home/steam/.steam/sdk64/steamclient.so lrwxrwxrwx 1 steam steam 34 Feb 4 2024 /home/steam/.steam/sdk64/steamclient.so -\u0026gt; /home/steam/linux64/steamclient.so 再次启动服务端\n[steam@server PalServer]$ ./PalServer.sh Shutdown handler: initalize. Increasing per-process limit of core file size to infinity. sh: xdg-user-dir: command not found dlopen failed trying to load: steamclient.so with error: steamclient.so: cannot open shared object file: No such file or directory [S_API] SteamAPI_Init(): Loaded \u0026#39;/home/steam/.steam/sdk64/steamclient.so\u0026#39; OK. (First tried local \u0026#39;steamclient.so\u0026#39;) CAppInfoCacheReadFromDiskThread took 3 milliseconds to initialize dlmopen steamservice.so failed: steamservice.so: cannot open shared object file: No such file or directory Setting breakpad minidump AppID = 2394010 [S_API FAIL] Tried to access Steam interface SteamUser021 before SteamAPI_Init succeeded. [S_API FAIL] Tried to access Steam interface SteamFriends017 before SteamAPI_Init succeeded. [S_API FAIL] Tried to access Steam interface STEAMAPPS_INTERFACE_VERSION008 before SteamAPI_Init succeeded. [S_API FAIL] Tried to access Steam interface SteamNetworkingUtils004 before SteamAPI_Init succeeded. 检查是否可以正常启动, 没有其他错误后可以按 Ctrl+C 停止服务器。\n设置 systemd 服务\r使用 systemd 管理 Palworld 服务端\nvim /etc/systemd/system/palworld.service 输入以下内容并使用 :wq 保存\n[Unit] Description=Palworld Dedicated Server Wants=network-online.target After=syslog.target network.target nss-lookup.target network-online.target [Service] User=steam Group=steam ExecStart=/home/steam/PalServer/PalServer.sh EpicApp=PalServer -useperfthreads -NoAsyncLoadingThread -UseMultithreadForDS ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s INT $MAINPID LimitNOFILE=100000 Restart=always TimeoutStartSec=300 [Install] WantedBy=multi-user.target 启动参数\rPalServer.sh 选项 意义 port=8211 服务器监听的端口号 players=32 服务器上的最大玩家数量 EpicApp=PalServer 设置为社区服务器, 在列表中可见 -useperfthreads -NoAsyncLoadingThread -UseMultithreadForDS 提高多核 CPU 环境中的性能。它最多可有效处理 4 个线程, 分配超过该数量的线程就没有什么意义了 服务器启动命令\r# 重载 systemd 配置文件 systemctl daemon-reload # 开机自动启动 systemctl enable palworld.service # 启动 palworld systemctl start palworld.service # 停止 palworld systemctl stop palworld.service # 检查运行状态 systemctl status palworld.service 配置防火墙\r游戏使用 UDP 8211 端口\nfirewall-cmd --add-port=8211/udp --permanent firewall-cmd --reload 进阶游戏设置\r默认的幻兽帕鲁服务器设置可能无法满足所有玩家或服务器主的需求。例如, 你希望提升昼夜速度、限制掉落物数量、或是设置更高的玩家上限。此时, 就需要通过自定义游戏设置, 来创建符合自己玩法风格的服务器。\n本节将介绍如何修改和管理服务器的配置文件, 深入掌握游戏的各项参数, 并处理那些无法直接通过 .ini 文件配置的高级选项。无论你是要打造休闲服或者是养老服, 还是硬核PVP挑战服, 这部分内容都将完美解决你的问题。\n配置文件介绍\rPalworld 的服务器配置文件默认位于\n/home/steam/PalServer/DefaultPalWorldSettings.ini 该文件定义了游戏的基础规则和服务器参数。需要注意的是, 当前版本中只有在该文件中明确列出的参数才会被游戏引擎识别和生效。如果你尝试添加未支持的选项, 即使格式正确, 也不会产生任何效果。\n对于那些未在配置文件中公开支持的高级参数 (例如每个公会的基地数量上限、每个基地的最大工作帕鲁数量、每个基地人数上限等), 则需要通过修改存档目录下的 WorldOption.sav 文件来实现。这种修改方式需要借助专门的工具, 例如开源项目 palworld-worldoptions\n复制默认配置文件\r直接修改 DefaultPalWorldSettings.ini 不会生效, 游戏启动时并不会读取该文件的更改。正确的做法是复制默认模板到 PalWorldSettings.ini, 并在其中修改参数以启用自定义设置\ncp PalServer/DefaultPalWorldSettings.ini PalServer/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini 配置文件中的常见选项\rPalWorldSettings.ini 允许配置以下内容:\n[/Script/Pal.PalGameWorldSettings] OptionSettings=(ServerPlayerMaxNum=32,DayTimeSpeedRate=2.0,DropItemMaxNum=3000) 配置项说明 (来源于 0.5.0 版本):\n注意格式, 括号内为结构体字段, 大小写与逗号分隔必须准确。\n配置项 作用 AdminPassword 管理员密码, 获得管理员权限 AllowConnectPlatform 指定连接平台, 🚫 当前版本无效, 使用 CrossplayPlatforms 代替 BaseCampMaxNumInGuild 每个公会最大营地数量, 默认 4, 最大 10, 值越大负载越高 BaseCampWorkerMaxNum 每个营地最大帕鲁数, 最大 50, 值越大负载越高 bAllowGlobalPalboxExport 允许导出至全球帕鲁盒 bAllowGlobalPalboxImport 允许从全球帕鲁盒导入 bBuildAreaLimit 限制建筑靠近特定设施, 禁止在快速移动点等附近建造 bCharacterRecreateInHardcore 重生功能 (硬核模式), 🚫 保留字段 bEnableFastTravel 开启快速移动 bEnableInvaderEnemy 开启敌人入侵事件 bHardcore 硬核模式, 死亡后无法复活 bInvisibleOtherGuildBaseCampAreaFX 显示其他公会营地区域特效 bIsRandomizerPalLevelRandom 帕鲁等级完全随机 bIsUseBackupSaveData 启用世界备份功能, 会增加磁盘 I/O bPalLost 死亡时永久失去帕鲁 bShowPlayerList 显示 ESC 菜单下的玩家列表 BuildObjectDamageRate 建筑受伤倍率 BuildObjectDeteriorationDamageRate 建筑老化速度 ChatPostLimitPerMinute 每分钟可发言次数限制 CollectionDropRate 采集物掉落倍率 CollectionObjectHpRate 采集物生命值倍率 CollectionObjectRespawnSpeedRate 采集物刷新间隔倍率 CrossplayPlatforms 跨平台连接支持, 默认: (Steam,Xbox,PS5,Mac) DayTimeSpeedRate 白天流逝速度 DeathPenalty 死亡惩罚类型, 支持: None / Item / ItemAndEquipment / All EnemyDropItemRate 怪物掉落倍率 ExpRate 经验获取倍率 GuildPlayerMaxNum 每个公会最大玩家数 ItemWeightRate 道具重量倍率 LogFormatType 日志格式类型, 可选 Text 或 Json MaxBuildingLimitNum 每位玩家建筑上限, 0 表示无限制 NightTimeSpeedRate 夜晚流逝速度 PalAutoHPRegeneRate 帕鲁自动回血速度 PalAutoHpRegeneRateInSleep 帕鲁休息回血速度 (帕鲁盒中) PalCaptureRate 帕鲁捕获倍率 PalDamageRateAttack 帕鲁造成的伤害倍率 PalDamageRateDefense 帕鲁受到的伤害倍率 PalEggDefaultHatchingTime 巨型蛋孵化时间 (小时), 所有蛋通用 PalSpawnNumRate 帕鲁出现数量倍率, 增大会影响性能 PalStaminaDecreaceRate 帕鲁体力消耗速度 PalStomachDecreaceRate 帕鲁饥饿消耗速度 PlayerAutoHPRegeneRate 玩家自动回血速度 PlayerAutoHpRegeneRateInSleep 玩家睡觉回血速度 PlayerDamageRateAttack 玩家造成的伤害倍率 PlayerDamageRateDefense 玩家受到的伤害倍率 PlayerStaminaDecreaceRate 玩家体力消耗速度 PlayerStomachDecreaceRate 玩家饥饿消耗速度 PublicIP 指定外部 IP (社区服务器) PublicPort 指定外部端口 (社区服务器), 不影响监听端口 RCONEnabled 启用 RCON 控制台 RCONPort RCON 控制台端口 RESTAPIEnabled 启用 REST API RESTAPIPort REST API 监听端口 ServerDescription 服务器描述 ServerName 服务器名称 ServerPassword 加入服务器所需密码 ServerPlayerMaxNum 服务器最大玩家数 ServerReplicatePawnCullDistance 帕鲁同步距离 (cm), 最小值: 5000, 最大值: 15000 SupplyDropSpan 空投间隔 (分钟) 使用 WorldOption.sav 修改高级设置 (进阶)\r并非所有设置都可以在 .ini 文件中修改, 一些选项并不会在该配置文件中列出, 即使手动添加也不会生效。\n这些选项实际上是保存在保存档目录中 WorldOption.sav 文件里, 必须使用工具修改。\nPalServer/Pal/Saved/SaveGames/0/\u0026lt;世界 UUID\u0026gt;/WorldOption.sav 推荐使用社区项目: legoduded/palworld-worldoptions 进行生成\n安装示例\r环境要求\nPython 3.10 或更高版本 Linux 用户还需额外安装 trumank/uesave-rs (用于解析和编辑 Unreal Engine 的 .sav 文件) # 克隆项目源码 git clone https://github.com/legoduded/palworld-worldoptions.git cd palworld-worldoptions # (Linux 用户专属) 安装 uesave 模块 wget https://github.com/trumank/uesave-rs/releases/download/v0.6.2/uesave_cli-x86_64-unknown-linux-gnu.tar.xz tar -xf uesave_cli-x86_64-unknown-linux-gnu.tar.xz mv uesave_cli-x86_64-unknown-linux-gnu/uesave /usr/local/bin/uesave chmod +x /usr/local/bin/uesave # 测试是否安装成功 uesave --help 使用方式\nlegoduded@desktop:~/palworld-worldoptions/src$ python3 main.py /mnt/g/PalServer/Pal/Saved/Config/WindowsServer/PalWorldSettings.ini --uesave /usr/local/bin/uesave --output /mnt/g/PalServer/Pal/Saved/SaveGames/0/8FAEE1FC44A4A5032BC92F8BCFD43AE3 Found settings Found uesave Converting JSON Converted /mnt/g/pal/steamcmd/steamapps/common/PalServer/Pal/Saved/SaveGames/0/8FAEE1FC44A4A5032BC92F8BCFD43AE3/WorldOption.sav.json to /mnt/g/pal/steamcmd/steamapps/common/PalServer/Pal/Saved/SaveGames/0/8FAEE1FC44A4A5032BC92F8BCFD43AE3/WorldOption.sav Complete! Restart your palworld server to apply the changes 更新 Palworld 服务端\r游戏推出新版本后服务端也需要更新\n手动更新\r使用 steamcmd 命令更新\n# 运行 steamcmd.sh ./steamcmd.sh # 以匿名身份登录 \u0026gt; login anonymous # 指定 ./PalServer 为安装目录 \u0026gt; force_install_dir ./PalServer # Palworld 的 App ID 是 2394010 并验证完整性 \u0026gt; app_update 2394010 validate # 等待进度达到 100 # 退出 steamcmd \u0026gt; quit 可以使用 + 号将命令连接起来, 拼接为一行命令\n./steamcmd.sh +force_install_dir ./PalServer +login anonymous +app_update 2394010 validate +quit 使用脚本自动更新\r使用 api.steamcmd.net 来获取最新的 Build ID, 避免对 Steam 服务器造成过重的负载。脚本运行间隔时间很短影响也不大, 间隔推荐设置为每 30 分钟执行一次\n定期检查服务端版本, 如果版本不同, 则进行更新, 服务端将自动更新并重新启动。\n创建更新脚本\n# 安装 jq 命令来处理 json yum install jq -y # 创建更新脚本 vim update-palworld.sh 写入以下内容\n#!/bin/bash # 字体颜色定义 Font_Black=\u0026#34;\\033[30m\u0026#34; Font_Red=\u0026#34;\\033[31m\u0026#34; Font_Green=\u0026#34;\\033[32m\u0026#34; Font_Yellow=\u0026#34;\\033[33m\u0026#34; Font_Blue=\u0026#34;\\033[34m\u0026#34; Font_Purple=\u0026#34;\\033[35m\u0026#34; Font_SkyBlue=\u0026#34;\\033[36m\u0026#34; Font_White=\u0026#34;\\033[37m\u0026#34; Font_Suffix=\u0026#34;\\033[0m\u0026#34; # 消息提示定义 Msg_Info=\u0026#34;${Font_Blue}[Info] ${Font_Suffix}\u0026#34; Msg_Warning=\u0026#34;${Font_Yellow}[Warning] ${Font_Suffix}\u0026#34; Msg_Debug=\u0026#34;${Font_Yellow}[Debug] ${Font_Suffix}\u0026#34; Msg_Error=\u0026#34;${Font_Red}[Error] ${Font_Suffix}\u0026#34; Msg_Success=\u0026#34;${Font_Green}[Success] ${Font_Suffix}\u0026#34; Msg_Fail=\u0026#34;${Font_Red}[Failed] ${Font_Suffix}\u0026#34; # Paths STEAMCMD=\u0026#34;/home/steam/steamcmd.sh\u0026#34; INSTALL_DIR=\u0026#34;/home/steam/PalServer\u0026#34; SERVICE_NAME=\u0026#34;palworld.service\u0026#34; echo -e \u0026#34;${Msg_Info}Environment Check\u0026#34; echo -e \u0026#34;${Msg_Info}$(date \u0026#39;+%Y-%m-%d %H:%M:%S %Z\u0026#39;)\u0026#34; # Retrieve the current Build ID OLD_Build=`$STEAMCMD +force_install_dir $INSTALL_DIR +login anonymous +app_status 2394010 +quit | grep -e \u0026#34;BuildID\u0026#34; | awk \u0026#39;{print $8}\u0026#39;` echo -e \u0026#34;${Msg_Info}Current BuildID: ${Font_Yellow}$OLD_Build${Font_Suffix}\u0026#34; # Attempt to fetch the New Build ID using curl NEW_Build=$(curl -s https://api.steamcmd.net/v1/info/2394010 | jq -r \u0026#39;.data[\u0026#34;2394010\u0026#34;].depots.branches.public.buildid\u0026#39;) # Fallback to SteamCMD method if curl fails to retrieve data if [ -z \u0026#34;$NEW_Build\u0026#34; ] || [ \u0026#34;$NEW_Build\u0026#34; = \u0026#34;null\u0026#34; ]; then echo -e \u0026#34;${Msg_Fail}Failed to fetch New BuildID with curl. EXIT\u0026#34; exit 1 # echo \u0026#34;Failed to fetch New BuildID with curl. Resorting to SteamCMD.\u0026#34; # $STEAMCMD +force_install_dir $INSTALL_DIR +login anonymous +app_update 2394010 validate +quit \u0026gt; /dev/null # NEW_Build=`$STEAMCMD +force_install_dir $INSTALL_DIR +login anonymous +app_status 2394010 +quit | grep -e \u0026#34;BuildID\u0026#34; | awk \u0026#39;{print $8}\u0026#39;` fi echo -e \u0026#34;${Msg_Info}Fetched New BuildID: ${Font_Yellow}$NEW_Build${Font_Suffix}\u0026#34; # Update the server if the Build IDs do not match if [ \u0026#34;$OLD_Build\u0026#34; = \u0026#34;$NEW_Build\u0026#34; ]; then echo -e \u0026#34;${Msg_Warning}No update required. Build numbers are equal.\u0026#34; else echo -e \u0026#34;${Msg_Info}Stopping ${SERVICE_NAME} ready for update.\u0026#34; systemctl stop $SERVICE_NAME echo -e \u0026#34;${Msg_Info}Updating the game server...\u0026#34; # \u0026gt; /dev/null $STEAMCMD +force_install_dir $INSTALL_DIR +login anonymous +app_update 2394010 validate +quit echo -e \u0026#34;${Msg_Success}Game server updated successfully to BuildID: ${Font_Yellow}$NEW_Build${Font_Suffix}\u0026#34; echo -e \u0026#34;${Msg_Info}Restart ${SERVICE_NAME} after update.\u0026#34; systemctl start $SERVICE_NAME echo -e \u0026#34;${Msg_Info}Update complete. New BuildID: $NEW_Build\u0026#34; systemctl status $SERVICE_NAME fi 赋予执行权限\nchmod +x /home/steam/update-palworld.sh 运行测试\n# 在主目录里 ./update-palworld.sh # 完整路径 /home/steam/update-palworld.sh 如果没有问题, 可以使用 cron 定期运行它。每 30 分钟检查一次是否有更新, 如果有, 则执行更新并重新启动服务器。\ncrontab -e */30 * * * * /home/steam/update-palworld.sh 内存不足时自动重启 Palworld\rPalworld 服务端持续运行 2 天左右, 占用的内存大的离谱。人物经过的地图会被加载到内存里, 但在人物离开后不会释放内存。\n创建内存检查脚本。如果内存使用率超过80%, 服务器将重新启动。\nvim check-palworld-memory.sh 写入以下内容\n#!/bin/bash # Palworld Service Name SERVICE_NAME=\u0026#34;palworld.service\u0026#34; # 当服务器内存使用率 (%) 超过此阈值时, 重启服务 THRESHOLD=80 # 是否检查 SWAP 空间 (设置为 True 表示检查, False 表示不检查) CHECK_SWAP=False # 获取当前内存使用率 (%) mem_usage=$(free -b | awk \u0026#39;/Mem:/ {print int($3/$2 * 100.0)}\u0026#39;) # 获取总内存大小 (GB) mem_total_gb=$(free -b | awk \u0026#39;/Mem:/ {printf \u0026#34;%.1f\u0026#34;, $2/1024^3}\u0026#39;) # 获取已使用内存大小 (GB) mem_used_gb=$(free -b | awk \u0026#39;/Mem:/ {printf \u0026#34;%.1f\u0026#34;, $3/1024^3}\u0026#39;) # 获取 SWAP 总大小 (byte) swap_total=$(free -b | awk \u0026#39;/Swap:/ {print $2}\u0026#39;) # 获取 SWAP 使用率 (%) swap_usage=$(free -b | awk \u0026#39;/Swap:/ {if($2 \u0026gt; 0) print int($3/$2 * 100.0); else print 0;}\u0026#39;) # 获取 SWAP 总大小 (GB) swap_total_gb=$(free -b | awk \u0026#39;/Swap:/ {printf \u0026#34;%.1f\u0026#34;, $2/1024^3}\u0026#39;) # 获取已使用 SWAP 大小 (GB) swap_used_gb=$(free -b | awk \u0026#39;/Swap:/ {printf \u0026#34;%.1f\u0026#34;, $3/1024^3}\u0026#39;) current_time=$(date +\u0026#34;%Y-%m-%d %H:%M:%S\u0026#34;) # 如果启用了 SWAP 检查并且系统有 SWAP 空间, 则检查 SWAP 使用率 if [ \u0026#34;$CHECK_SWAP\u0026#34; = True ] \u0026amp;\u0026amp; [ $swap_total -gt 0 ]; then if [ $swap_usage -gt $THRESHOLD ]; then # 如果 SWAP 使用率超过阈值, 则重启服务 sudo systemctl stop $SERVICE_NAME sudo systemctl start $SERVICE_NAME echo \u0026#34;The $SERVICE_NAME has been restarted.\u0026#34; echo \u0026#34;[$current_time] Restarted $SERVICE_NAME due to high swap usage: $swap_usage% (${swap_used_gb}GB/${swap_total_gb}GB)\u0026#34; exit 0 fi elif [ $mem_usage -gt $THRESHOLD ]; then # 如果内存使用率超过阈值, 则重启服务 sudo systemctl stop $SERVICE_NAME sudo systemctl start $SERVICE_NAME echo \u0026#34;The $SERVICE_NAME has been restarted.\u0026#34; echo \u0026#34;[$current_time] Restarted $SERVICE_NAME due to high memory usage: $mem_usage% (${mem_used_gb}GB/${mem_total_gb}GB)\u0026#34; exit 0 fi # 打印当前内存和 SWAP 使用情况 echo \u0026#34;[$current_time] Current memory usage: $mem_usage% (${mem_used_gb}GB/${mem_total_gb}GB)\u0026#34; if [ $swap_total -gt 0 ]; then echo \u0026#34;[$current_time] Current swap usage: $swap_usage% (${swap_used_gb}GB/${swap_total_gb}GB)\u0026#34; fi 赋予执行权限\nchmod +x /home/steam/check-palworld-memory.sh 运行测试\n./check-palworld-memory.sh 使用 cron 定期运行。每 30 分钟检查一次内存使用率, 如果超过阈值, 则重新启动服务。\ncrontab -e */30 * * * * /home/steam/check-palworld-memory.sh 备份游戏存档指南\r对于 RPG 类型的游戏来说, 存档数据至关重要。定期备份可以帮助我们在以下情况中快速回档、减少损失\n游戏出现严重 BUG, 导致无法进入游戏 队友误操作, 例如拆家 挂狗破坏基地 在离线时遇到入侵事件 孵蛋或配种失败, 导致优秀父代遗失 📦 备份存档\r手动完整备份\r在更新升级服务器时使用, 将 /home/steam/PalServer 目录完整打包压缩为 tar.xz 文件, 保存在 save_backup 目录下。\ntar -Jcf save_backup/palworld_server_v3.10.tar.xz -C /home/steam PalServer 自动备份配置 (Cron 任务)\r每 30 分钟自动备份一次 SaveGames 文件夹, 并带上时间戳命名 每天凌晨 1 点清理超过 30 小时以上的旧备份, 避免硬盘占满 备份脚本\nvim backup-palworld.sh 填入以下内容\n#!/bin/bash # Define source directory and backup directory SOURCE_DIR=\u0026#34;/home/steam/PalServer/Pal/Saved\u0026#34; BACKUP_DIR=\u0026#34;/home/steam/save_backup\u0026#34; DATE=$(date +\\%F_\\%H-\\%M-\\%S) # Create a xz compressed tarball # /usr/bin/tar -Jcf /home/steam/save_backup/auto_palworld_$(date +\\%F_\\%H-\\%M-\\%S).tar.xz -C /home/steam/PalServer/Pal/Saved SaveGames tar -Jcf \u0026#34;${BACKUP_DIR}/auto_palworld_${DATE}.tar.xz\u0026#34; -C \u0026#34;${SOURCE_DIR}\u0026#34; SaveGames echo \u0026#34;Backup of ${SOURCE_DIR} completed at ${BACKUP_DIR}/auto_palworld_${DATE}.tar.xz\u0026#34; 赋予执行权限\nchmod +x /home/steam/backup-palworld.sh 运行测试\n./backup-palworld.sh 设置定时执行\ncrontab -e */30 * * * * /home/steam/backup-palworld.sh 0 1 * * * find /home/steam/save_backup/ -name \u0026#34;auto_palworld*.tar.xz\u0026#34; -mmin +1800 -exec rm -f {} \\; 🔄 恢复存档\r完整备份恢复。解压备份文件到 /home/steam 目录, 恢复原始存档结构。\n# 恢复备份前, 先停止服务器 systemctl stop palworld tar -xJvf save_backup/palworld_server_v3.10.tar.xz -C /home/steam systemctl restart palworld 原文\n最大32人 パルワールド Linux 専用サーバの立て方\nDeploy dedicated server\nPalworld Server Guide - Configuration file\nGithub - palworld-worldoptions\n","date":"2024-02-09T20:36:49+08:00","permalink":"https://blog.acesheep.com/p/centos7-palworld-dedicated-server/","title":"CentOS 7 搭建 Palworld (幻兽帕鲁) 服务器"},{"content":"MikroTik RouterOS 是基于 Linux 内核的操作系统, 可将计算机变为网络路由器\n上传 ISO 镜像并创建实例\r上传 SystemRescueCD ISO\r访问 Vultr 的 Add ISO 页面\n将链接复制并粘贴到 Remote URL 文本字段内, 使用 SystemRescueCD 镜像\nhttps://fastly-cdn.system-rescue.org/releases/12.02/systemrescue-12.02-amd64.iso 点击 Upload 按钮, ISO 镜像将被添加到你的账户中\n创建 VPS 实例\r在 Vultr 上按照常规方式创建 VPS, 但在选择 Server Image 时选择 Upload ISO\n选择 iPXE, 并填入以下引导 URL\nhttp://boot.ipxe.org/demo/boot.php 等待 VPS 创建完成\n进入 VPS -\u0026gt; Settings -\u0026gt; Custom ISO, 在 My ISOs 中选择 systemrescue-12.02-amd64.iso, 然后点击 Attach ISO and Reboot\n启动服务器实例, 进入 SystemRescueCD\n下载并安装 MikroTik RouterOS\r打开浏览器, 访问 MikroTik RouterOS 下载页面\n滚动到 Cloud Hosted Router (CHR) 部分\n选择 Raw disk image 对应的 长期支持版 (Long-term) 或 最新稳定版 (Stable)\n右键保存图标, 在菜单上选择 Copy link address。镜像 URL 将复制到剪贴板中\n在 \u0026ldquo;Vultr 服务器实例\u0026rdquo; 页面上, 单击 View Console 访问正在运行的 SystemRescueCD 实例的命令行\n进系统后重置一个 root 密码，方便远程 ssh 操作\n关闭防火墙 systemctl stop iptables, 然后使用 SSH 连接\n在 SystemRescueCD 控制台中使用 wget 命令下载\nwget https://download.mikrotik.com/routeros/7.19.4/chr-7.19.4.img.zip 使用 unzip 命令解压磁盘映像\nunzip chr-7.19.4.img.zip 使用 dd 命令将 MikroTik RouterOS 写入 Vultr 磁盘\ndd if=chr-7.19.4.img of=/dev/vda 在 dd 时设置 MikroTik 初始配置\r在 dd 写入磁盘后, 可以直接在 SystemRescueCD 环境中 设置初始网络配置, 避免首次启动后手动配置。\n该脚本将在 RouterOS 首次启动时自动运行, 包括:\n设置 IPv4 地址 (45.76.100.108/22) 配置默认网关 (45.76.100.1) 禁用不必要的远程服务 (Telnet、FTP、SSH、API) 设置 DNS 服务器 (Google 8.8.8.8 \u0026amp; Cloudflare 1.1.1.1) [root@sysresccd ~]# dd if=chr-7.19.4.img of=/dev/vda [root@sysresccd ~]# mount /dev/vda2 /mnt/ [root@sysresccd ~]# cat \u0026gt; /mnt/rw/autorun.scr\u0026lt;\u0026lt;\\EOF # Auto configure script on RouterOS first boot # feel free to customize it if you really need /ip address add address=45.76.100.108/22 interface=ether1 network=45.76.100.0 /ip route add distance=1 gateway=45.76.100.1 /ip service set telnet disabled=yes set ftp disabled=yes set ssh disabled=yes set api disabled=yes set api-ssl disabled=yes /ip dns set servers=8.8.8.8,1.1.1.1 EOF [root@sysresccd ~]# umount /mnt/ 移除 ISO 并启动 MikroTik\r进入 VPS -\u0026gt; Settings -\u0026gt; Custom ISO, 点击 Remove ISO 选项\nVPS 将自动重启, 并进入 MikroTik RouterOS\n刷新 View Console 窗口, 使用默认登录凭据登录。按回车键进入系统\n用户名: admin 密码: (空) Mikrotik RouterOS 配置 IPV6\r获取 Vultr 分配的 IPv6\r在 Vultr 控制台找到服务器分配的 IPv6 地址段\n配置 IPv6\r使用 WinBox 连接到 MikroTik 进行 IPv6 配置\n/ipv6 settings set forward=no\r/ipv6 address add interface=WAN address=2001:19f0:7001:3290:5400:02ff:fe22:f3f7/64\r/ipv6 route add dst-address=::/0 gateway=fe80::fc00:ff:fe60:fff%ether1\r/ipv6 nd set [ find default=yes ] hop-limit=64 interface=ether1 managed-address-configuration=yes other-configuration=yes 测试 IPv6 连接\r如果 ping IPv6 地址成功, 则表示 IPv6 配置成功\n[admin@MikroTik] \u0026gt; /ping count=3 2001:4860:4860::8888\rSEQ HOST SIZE TTL TIME STATUS 0 2001:4860:4860::8888 56 119 1ms293us echo reply\r1 2001:4860:4860::8888 56 119 1ms687us echo reply\r2 2001:4860:4860::8888 56 119 1ms313us echo reply\rsent=3 received=3 packet-loss=0% min-rtt=1ms293us avg-rtt=1ms431us\rmax-rtt=1ms687us\r[admin@MikroTik] \u0026gt; 原文\nVultr 安装Mikrotik RouterOS后配置IPV6和IPV6 BGP\n","date":"2024-02-03T18:34:00+08:00","permalink":"https://blog.acesheep.com/p/vultr-vps-mikrotik-routeros-setup/","title":"在 Vultr VPS 上安装 MikroTik RouterOS"},{"content":"什么是透明代理\r透明代理的核心理念是让被代理的设备 无感知 地使用代理服务。也就是说, 被代理的设备无需运行任何代理软件 (如 Clash、V2RayNG、Shadowrocket 等),只要连接到网络, 流量就会自动经过代理。\n这意味着, 代理软件运行在其他设备上, 比如路由器中。这样, 所有通过该路由器上网的设备都会被自动代理。\n在本文中, 我们需要一台 Linux 主机 连接到 路由器的 LAN 口, 使其作为局域网中的透明代理网关, 为局域网内的所有设备提供透明代理功能。\n为什么需要透明代理？\r透明代理适用于以下情况:\n局域网设备较多: 例如 办公室、实验室、大型家庭等, 不想手动为每台设备配置代理 设备无法设置代理: 例如 Chromecast、电视盒子、Apple TV、HomePod 等智能设备 哪些设备可以作为透明代理网关？\r任何能够运行 Linux 的设备或者 24 小时开机的设备都可以充当透明代理网关, 例如:\n路由器: (软路由、OpenWrt、LEDE、爱快等) 开发板: (树莓派、香橙派等) 个人电脑: (Linux 虚拟机、J1900 软路由、普通 PC、笔记本电脑) NAS 设备 电视盒子: (Apple TV) 至于到底用什么？具体选择取决于需求。\n如果只是 随便折腾 学习技术, ARM 架构的树莓派是个不错的选择 如果追求 长期稳定运行, 建议使用 x86 软路由 当然, 到底怎么选择还是得看自己。\n透明代理的实现原理 (iptables)\rLinux 使用 Netfilter 来管理网络流量, 进行数据包过滤和路由管理, 其数据包处理流程如下:\n数据包流向解析\r假设使用主路由器作为网关 (即我们平时的上网方式), 数据包的流向如下:\n局域网设备访问互联网 (正常上网流量):\nPREROUTING 链 -\u0026gt; FORWARD 链 -\u0026gt; POSTROUTING 链 局域网设备访问路由器本身 (如登录 Web 管理界面、SSH、DNS 请求):\nPREROUTING 链 -\u0026gt; INPUT 链 -\u0026gt; 网关系统 路由器本身访问互联网 (例如网关自身的 DNS 查询、系统更新、路由器安装软件包等):\n网关系统 -\u0026gt; OUTPUT 链 -\u0026gt; POSTROUTING 链 如何实现透明代理？\r我们可以使用 firewall-cmd 来控制 PREROUTING 和 OUTPUT 链, 将匹配的数据包转发至 V2Ray。这样, 局域网设备和网关本身的数据包都可以通过 V2Ray 进行处理。\n准备条件\r在搭建透明代理前, 你需要具备以下条件:\n正常运行的主路由, 可以使用 RouterOS 等 抗污染 DNS, 如 DoH、DoT、DNSCrypt, 避免域名解析被污染 已经安装好 CentOS 7 系统的设备, 用于搭建透明代理网关 静态 IP 配置, 网关设备 IP 必须是固定的 使用 Firewalld 管理 Netfilter (本文不直接使用 iptables 或 nftables) 了解基础的 TCP/IP 知识 (如 TCP/IP、DNS、NAT、路由) 能手动编辑 V2Ray JSON 配置文件 (至少能看懂配置逻辑) 有解决问题的能力, 遇到问题时能自行根据实际情况解决问题。不可使用预制人 主路由分流策略\r主路由使用 BGP 协议按照 ASN (自治系统编号) 进行流量分流。进入透明代理网关的流量全部走代理, 网关本身不再做 IP 级别的分流或域名分流。\n旁路由系统选择\rOpenWrt / LEDE 作为路由器系统, 拥有易用的 Web 管理界面 (LuCI) 和丰富的生态, 使其广受好评。但另一方面, 也许它也只能作为「路由器系统」了, 对于旁路由或 x86 软路由, 它的局限性较大, 与标准的 Linux 发行版功能上相比差距太大了。\n为什么我之前选择 LEDE 呢？当时讨论的最多的就是 爱快 (iKuai) 主路由 + LEDE 旁路由 方案。考虑到它是专门打造的路由器系统, 界面美观还有丰富的软件中心, 和原版 OpenWrt 内核优化上或许有些许不同, 所以当时选择了 LEDE。然而, 随着时间推移, 软件长期缺乏维护, bug 越来越多, 甚至很多软件因不可抗力被下架, 已经无法正常使用。\n因此, 搭建旁路由, 建议使用 CentOS / Ubuntu / Debian 等标准的 Linux 发行版, 适合在软路由、工控机、虚拟机等设备上作为透明代理网关, 长期运行也更加稳定。\n透明代理的核心难点\r透明代理的最大难点在于 路由, 即如何正确分流:\n哪些流量应直连？ 哪些流量应走代理？ 如何避免数据包在网关内无限循环？ 透明代理的搭建阶段\r我们可以把路由分流, 由易到难分为以下几个阶段:\n第一阶段: 代理所有进入网关的流量 (最简单) 第二阶段: 在 1 的基础上, 优化路由 局域网 IP、组播地址、E 类地址、广播地址, 直连 其他流量走代理 第三阶段: 在 2 的基础上, 优化网关自身的流量 让网关自身流量也能走代理 V2Ray 出站流量不再进入代理 (避免回环) 第四阶段: 在 3 的基础上, 二次分流优化代理 根据域名将流量分配到不同出口 设置网关\r连接网络\n将透明代理网关 (准备运行 V2Ray 的设备) 连接到主路由器的 LAN 口 手动分配静态 IP, 假设网关设备的 IP 地址为 192.168.2.2 开启 IP 转发\n需要开启 IP 转发才能作为网关, 我们这里仅开启 Linux 的 IPv4 转发 功能\necho \u0026#34;net.ipv4.ip_forward=1\u0026#34;\u0026gt;\u0026gt; /etc/sysctl.conf sysctl -p 执行后应出现以下提示, 表示成功开启 IP 转发\nnet.ipv4.ip_forward = 1 配置防火墙规则\n由于 firewalld 防火墙默认可能会阻止转发流量, 我们需要手动添加规则\n# 其中 ens192 为你的网卡名称, 请根据实际情况更改 (使用 ip a 查看网卡名称) firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 1 -o ens192 -j ACCEPT 执行完毕后, 重新加载防火墙配置, 使规则生效\n# 因为有 --permanent 参数, 需要重新加载配置才能生效 firewall-cmd --reload 验证规则是否已生效\n# 可以使用这个命令查看已经生效的规则 firewall-cmd --direct --get-all-rules 手动配置局域网设备网络\n在局域网中的设备上手动设置网关, 网关地址: 192.168.2.2 (即透明代理网关的 IP)\n配置完成后, 局域网设备应当可以正常上网, 但由于还没设置代理, \u0026ldquo;正常\u0026rdquo; 是指可以访问国内网站。访问外网仍不可用, 后续需要进一步配置透明代理规则, 使国际流量走 V2Ray 代理。\n安装配置 V2Ray\r启用 TProxy 监听 12345 端口\nV2Ray 需要在透明代理模式 (TProxy) 下工作, 因此首先要开启 dokodemo-door 监听 12345 端口, 用于接收 TCP / UDP 流量并进行代理转发 启用 SOCKS5 代理, 监听 1080 端口\n为了测试 V2Ray 是否正常运行, 我们在 1080 端口开启一个 SOCKS5 代理。此端口仅用于测试, 后续可以删除 我们由易到难, 不写路由 (routing), 写两个入站 (inbound) 但只写一个出站 (outbound)\n{ \u0026#34;log\u0026#34;: { \u0026#34;loglevel\u0026#34;: \u0026#34;info\u0026#34;, \u0026#34;access\u0026#34;: \u0026#34;/home/v2ray/log_access.log\u0026#34;, \u0026#34;error\u0026#34;: \u0026#34;/home/v2ray/log_error.log\u0026#34; }, \u0026#34;inbounds\u0026#34;: [ { \u0026#34;port\u0026#34;: 12345, \u0026#34;protocol\u0026#34;: \u0026#34;dokodemo-door\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;tcp,udp\u0026#34;, \u0026#34;followRedirect\u0026#34;: true }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;sockopt\u0026#34;: { \u0026#34;tproxy\u0026#34;: \u0026#34;tproxy\u0026#34; } } }, { \u0026#34;port\u0026#34;: 1080, \u0026#34;protocol\u0026#34;: \u0026#34;socks\u0026#34;, \u0026#34;listen\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;auth\u0026#34;: \u0026#34;noauth\u0026#34;, \u0026#34;udp\u0026#34;: true, \u0026#34;ip\u0026#34;: null } } ], \u0026#34;outbounds\u0026#34;: [ { // 你的服务器配置 } ] } 测试 V2Ray 是否正常运行\r配置完成后, 启动 V2Ray 并执行以下命令, 检查是否可以正常访问外网\ncurl -so /dev/null -w \u0026#34;%{http_code}\\n\u0026#34; --connect-timeout 10 google.com -x socks5://127.0.0.1:1080 测试结果\n结果返回 301 或 200: 表示 V2Ray 代理正常工作, 可以访问外网 长时间无响应或返回 000: 表示 V2Ray 配置可能有问题, 无法访问外网 第一阶段: 代理所有进入网关的流量\r配置防火墙规则。首先, 将所有 PREROUTING 链的流量转发到 v2ray 中\nip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 # 创建自定义 V2RAY 链 firewall-cmd --direct --add-chain ipv4 mangle V2RAY # mark 只有设置为 1, 数据包才能被 v2ray 任意门接受 # 给 TCP 打标记 1, 转发至 12345 端口 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 # 给 UDP 打标记 1, 转发至 12345 端口 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 # 将 PREROUTING 数据包转发到 V2RAY 链 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY 执行完上述命令后, 透明代理无法正常上网。如果使用 SSH 连接到网关, 你会发现 SSH 连接被断开了 (不用紧张)\n可以通过以下方法恢复:\n直接断电重启, 系统重启后规则会被清除\n重启防火墙, 会移除所有临时规则\nsystemctl restart firewalld 手动删除 PREROUTING 规则\nfirewall-cmd --direct --remove-rule ipv4 mangle PREROUTING 1 -j V2RAY 无法访问互联网的异常情况分析\rV2Ray 的日志 (access.log) 可能会出现许多源地址为网关 (192.168.2.1) 请求目标地址为透明网关 LAN 口 IP (192.168.2.2) 的异常回环请求。\n2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:56276 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:35645 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:32808 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:60001 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:38648 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:40134 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:44284 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:39017 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:59267 [blocked]\r2024/02/03 00:52:55 192.168.2.1:53 accepted udp:192.168.2.2:45138 [blocked]\r2024/02/03 00:52:56 192.168.2.1:53 accepted udp:192.168.2.2:44694 [blocked]\r2024/02/03 00:52:56 192.168.2.1:53 accepted udp:192.168.2.2:33505 [blocked]\r2024/02/03 00:53:12 192.168.2.100:63890 accepted tcp:17.248.216.65:443 [us4]\r2024/02/03 00:53:26 192.168.2.100:63892 accepted tcp:17.57.145.151:443 [us4]\r2024/02/03 00:54:06 192.168.2.100:63894 accepted tcp:17.57.145.137:443 [us4] 这些异常回环请求被我设置的 v2ray 路由规则拦截了, 如果没有拦截则会出现 CPU 负载增高\n{ \u0026#34;outboundTag\u0026#34;: \u0026#34;blocked\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;ip\u0026#34;: [ \u0026#34;geoip:private\u0026#34; ] } 从理论上讲, 网关自身访问互联网只会经过 OUTPUT 链和 POSTROUTING 链, 为什么操控 PREROUTING 链会导致透明网关无法上网呢？\n这是因为网络通讯是双向的, 虽然网关自身访问互联网不需要经过 PREROUTING 链, 但被访问的服务器返回的响应数据时需要经过 PREROUTING 链, 而这部分流量被转发到 v2ray 了, 因此出现了日志中的回环请求, 导致连接异常。\n例如, DNS 请求和回复流程如下\n# 网关自身向互联网请求 DNS 解析 192.168.2.2:44284 -\u0026gt; 192.168.2.1:53 # DNS 解析结果被错误地转发到 v2ray 192.168.2.1:53 -\u0026gt; 192.168.2.2:44284 优化规则\r为避免上述问题, 我们修改一下防火墙规则, 使源 IP 不是来自局域网的请求则返回 (不转发至 v2ray)\n重启防火墙, 临时规则就被清空了, 执行以下指令:\n[root@gateway ~]# systemctl restart firewalld [root@gateway ~]# firewall-cmd --direct --get-all-rules ipv4 filter FORWARD 1 -o ens192 -j ACCEPT 修改后的防火墙规则\nip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 # 创建自定义 V2RAY 链 firewall-cmd --direct --add-chain ipv4 mangle V2RAY # \u0026#34;网关LAN_IP地址段\u0026#34; 通过运行命令 \u0026#34;ip address | grep -w \u0026#34;inet\u0026#34; | awk \u0026#39;{print $2}\u0026#39;\u0026#34; 获得, 是其中的一个 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 ! -s 网关LAN_IP地址段 -j RETURN # 标记 TCP 和 UDP 流量 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 3 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 # 将 PREROUTING 数据包转发到 V2RAY 链 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY 执行完上述命令后, SSH 仍然会断开, 但透明代理已经可用。为了让网关正常上网, 我们需要手动修改透明网关系统 DNS (/etc/resolv.conf), 设置为公共 DNS (如 119.29.29.29)。因为现在主路由网关访问不了, 所以 DNS 设置为主路由网关是不行的。\n至此, 第一阶段就完成了。\n第二阶段: 使主路由网关流量直连\r目前仍然无法访问主路由网关。原因是防火墙规则代理了全部流量, 包括访问本地主路由网关的流量。试想在 VPS 上访问你本地的主路由网关, 肯定是访问不了的, 所以我们要对这部分流量直连。为了让本地主路由网关直连, 需进一步修改防火墙规则。\n重启防火墙后, 执行以下指令:\nip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 # 创建自定义 V2RAY 链 firewall-cmd --direct --add-chain ipv4 mangle V2RAY # 直连所有目标地址属于网关所在网段的流量 # 通过运行命令 \u0026#34;ip address | grep -w \u0026#34;inet\u0026#34; | awk \u0026#39;{print $2}\u0026#39;\u0026#34; 获取网关网段, 一般来说有多个 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -d 网关所在网段2 -j RETURN ... # 允许组播地址 / E 类地址 / 广播地址直连 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 3 -d 224.0.0.0/3 -j RETURN # 标记 TCP 和 UDP 流量 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 4 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 5 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 # 将 PREROUTING 数据包转发到 V2RAY 链 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY 使用第二阶段的规则后, 第一阶段中的以下规则便成为了多余规则, 可以删去:\nfirewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 ! -s 网关LAN_IP地址段 -j RETURN 主路由器网关已经可以正常访问, SSH 连接不会断开, 同时透明代理也能正常工作。\n至此, 第二阶段完成。\n第三阶段: 网关自身的透明代理\r通常, 我们的 DNS 解析来源于主路由器, 但当前的防火墙规则仅代理了局域网中的设备, 并未代理透明网关自身。\n这会导致:\nDNS 查询返回错误或受到污染 在透明网关自身下载 GitHub 文件资源时会下载失败 访问国际互联网时返回错误 这有两个解决方案:\n搭建抗污染 DNS, 如 DoH、DoT、DNSCrypt, 避免域名解析被污染 使用策略路由代理透明网关自身 策略路由\r由于 iptables-tproxy 不支持直接操作 OUTPUT 链, 我们可以通过 策略路由 的方式, 将 OUTPUT 链中的相关数据包重新路由至 PREROUTING 链, 从而实现网关自身的透明代理。\n# 添加策略路由: 标记为 1 的包, 走路由表 100 ip rule add fwmark 1 table 100 # 添加路由表 100 的路由条目, 使所有包路由到本地 ip route add local 0.0.0.0/0 dev lo table 100 上述配置完成后, 我们只需要在 OUTPUT 链上给需要代理的包标记为 1, 由于 Netfilter 的特性, 在 OUTPUT 链上打标记会使这些数据包被重路由到 PREROUTING 链上, 从而被现有的透明代理规则处理。\n给 OUTPUT 链的流量打标记\nfirewall-cmd --direct --add-chain ipv4 mangle GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 5 -j MARK --set-mark 1 firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 1 -p tcp -j GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 2 -p udp -j GATEWAY_ITSELF 这样, OUTPUT 链上的 TCP 和 UDP 数据包都会被标记为 1, 并通过策略路由重新进入 PREROUTING 链, 从而实现网关自身流量的透明代理。\n解决代理自身的回环问题\r如果代理透明网关自身发出的全部请求, 就会引入一个新问题。由于透明网关自身运行着代理软件 (如 v2ray),如果不进行特殊处理, v2ray 向代理服务器发送的请求会被再次代理, 形成回环。因此, 我们需要在代理规则中排除 v2ray 的流量。\n方案一: 直连 VPS 流量\r最简单的方法是直连目标地址为 VPS 的流量, 避免它被代理。\nip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 firewall-cmd --direct --add-chain ipv4 mangle V2RAY firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 3 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 4 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 5 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 # 将 PREROUTING 数据包转发到 V2RAY 链 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY # 代理透明网关自身 firewall-cmd --direct --add-chain ipv4 mangle GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 3 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 4 -d VPS公网ip/32 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 5 -j MARK --set-mark 1 firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 1 -p tcp -j GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 2 -p udp -j GATEWAY_ITSELF 但是这样配置有个缺点, 如果出站的域名使用了 CDN 或者 VPS 很多的话, 就需要手动维护大量规则, 不够灵活。\n方案二: 基于 mark 规则排除 v2ray 出站数据包\r在 v2ray 配置文件中, 为出站 (outbound) 的 streamSettings 添加 SO_MARK, 使其数据包可以被 netfilter 识别并绕过代理。\n方案二也有 缺点\n可能会有未知流量进入 PREROUTING 链, 导致 tproxy 负载过高。tproxy 透明代理占用大量 CPU 该方案在安卓系统上不可用, 因为安卓有自己的 mark 机制 v2ray 配置示例。在所有 outbound 的 streamSettings 中添加 SO_MARK\n{ \u0026#34;inbounds\u0026#34;: [], \u0026#34;outbounds\u0026#34;: [ { \u0026#34;tag\u0026#34;: \u0026#34;proxy\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;vmess\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;vnext\u0026#34;: [ // 你的服务器配置 ] }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;sockopt\u0026#34;: { // 这里是 SO_MARK, 用于 netfilter 识别, 每个 outbound 都要配置 // 255 可以改成其他数值, 但要与下面的 firewalld 规则对应 // 如果有多个 outbound, 最好将所有 outbound 的 SO_MARK 都设置成一样的数值 \u0026#34;mark\u0026#34;: 255 } }, \u0026#34;mux\u0026#34;: { \u0026#34;enabled\u0026#34;: true } }, { \u0026#34;tag\u0026#34;: \u0026#34;direct\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34;, \u0026#34;settings\u0026#34;: {}, \u0026#34;streamSettings\u0026#34;: { \u0026#34;sockopt\u0026#34;: { // 这里是 SO_MARK, 用于 netfilter 识别, 每个 outbound 都要配置 // 255 可以改成其他数值, 但要与下面的 firewalld 规则对应 // 如果有多个 outbound, 最好将所有 outbound 的 SO_MARK 都设置成一样的数值 \u0026#34;mark\u0026#34;: 255 } } }, { \u0026#34;tag\u0026#34;: \u0026#34;blocked\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;blackhole\u0026#34;, \u0026#34;settings\u0026#34;: {} } ], \u0026#34;routing\u0026#34;: {} } 防火墙规则\nip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 firewall-cmd --direct --add-chain ipv4 mangle V2RAY firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 3 -d 224.0.0.0/3 -j RETURN # 直连 SO_MARK 为 0xff (255) 的流量, 防止 v2ray 进入代理回环 # 0xff 是 16 进制数, 数值上等同与上面 v2ray 配置的 255 # 此规则目的是解决 v2ray 占用大量 CPU (https://github.com/v2ray/v2ray-core/issues/2621) firewall-cmd --direct --add-rule ipv4 mangle V2RAY 4 -m mark --mark 0xff -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 5 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 6 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 # 将 PREROUTING 数据包转发到 V2RAY 链 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY # 代理透明网关自身 firewall-cmd --direct --add-chain ipv4 mangle GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 3 -d 224.0.0.0/3 -j RETURN # 直连 SO_MARK 为 0xff (255) 的流量, 防止 v2ray 进入代理回环 # 0xff 是 16 进制数, 数值上等同与上面 v2ray 配置的 255 # 此规则目的是避免透明网关自身流量出站回环问题 firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 4 -m mark --mark 0xff -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 5 -j MARK --set-mark 1 firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 1 -p tcp -j GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 2 -p udp -j GATEWAY_ITSELF 方案三: 基于 UID/GID 规避代理 (推荐)\rtproxy 流量只能被 root (uid=0) 权限用户或具备 CAP_NET_ADMIN 权限的用户接收, 在使用 v2ray 用户运行 v2ray 时需要保证分配了 CAP_NET_ADMIN 权限。\n只需要在 v2ray.service 中加入以下内容\n[Service] User=v2ray Group=v2ray PIDFile=/run/v2ray.pid CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE NoNewPrivileges=true ExecStart=/home/v2ray/bin/v2ray run -config /home/v2ray/v2ray.json Restart=on-failure # Don\u0026#39;t restart in the case of configuration error RestartPreventExitStatus=23 我们可以通过 uid 或 gid 排除 v2ray 进程的流量:\n-m owner --gid-owner overseas 所有 overseas 分组运行的程序流量 -m owner --uid-owner v2ray 所有 v2ray 用户运行的程序流量 ip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 firewall-cmd --direct --add-chain ipv4 mangle V2RAY firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 3 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 4 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 5 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 # 将 PREROUTING 数据包转发到 V2RAY 链 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY # 代理透明网关自身 firewall-cmd --direct --add-chain ipv4 mangle GATEWAY_ITSELF # 用户 v2ray 的流量直连 firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 1 -m owner --uid-owner v2ray -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 2 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 3 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 4 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 5 -j MARK --set-mark 1 firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 1 -p tcp -j GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 2 -p udp -j GATEWAY_ITSELF 这样就成功实现了 网关自身的透明代理, 也就是平时说的全局代理。但需要注意将透明网关的 DNS 服务器设置为国外的 DNS 服务器, 否则依然会返回被污染的解析结果。\n至此, 第三阶段完成。\n第四阶段: 二次分流优化代理\r对于大多数用户来说, 第三阶段的全局代理已经能够满足日常需求, 并不是所有人都需要实现第四阶段。\n第四阶段是在主路由已经完成了海外 IP 的分流, 透明网关还可以 二次分流, 可以根据不同应用的需求, 将流量更精准地路由到最佳的代理服务器, 从而提升可用性、访问速度和稳定性。\n通过 Sniffing 进行多出口分流\r开启 sniffing 功能后, V2Ray 可以根据域名进行智能分流、负载均衡等。例如\n域名 服务器 Netflix 香港 大流量 Disney+ 美国 解锁 Star 频道 OpenAI / ChatGPT 美国 ChatGPT 解锁线路 Telegram 日本 低延迟 CN2 GIA 套 Cloudflare 的 PT 域名 直连 替换默认路由规则文件\r为了获得更好的分流体验, 应使用 Loyalsoldier/v2ray-rules-dat 作为路由规则文件。否则, V2Ray 将无法加载此配置文件。\n下载最新的 geoip.dat 和 geosite.dat 规则文件\nwget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat -O /home/v2ray/bin/geoip.dat wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat -O /home/v2ray/bin/geosite.dat 配置 v2ray.json 进行域名和 IP 分流\r修改 V2Ray 配置文件 /home/v2ray/v2ray.json, 在 routing 部分添加相应的分流规则\n{ \u0026#34;inbounds\u0026#34;: [], \u0026#34;outbounds\u0026#34;: [], \u0026#34;routing\u0026#34;: { \u0026#34;domainMatcher\u0026#34;: \u0026#34;mph\u0026#34;, \u0026#34;domainStrategy\u0026#34;: \u0026#34;IpIfNonMatch\u0026#34;, \u0026#34;rules\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;hk\u0026#34;, \u0026#34;domains\u0026#34;: [ \u0026#34;geosite:netflix\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;us1\u0026#34;, \u0026#34;domains\u0026#34;: [ \u0026#34;geosite:disney\u0026#34;, \u0026#34;geosite:reddit\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;balancerTag\u0026#34;: \u0026#34;us2\u0026#34;, \u0026#34;domains\u0026#34;: [ \u0026#34;geosite:spotify\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;us3\u0026#34;, \u0026#34;domains\u0026#34;: [ \u0026#34;geosite:openai\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;jp1\u0026#34;, \u0026#34;ip\u0026#34;: [ \u0026#34;geoip:telegram\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;direct\u0026#34;, \u0026#34;domains\u0026#34;: [ // 套 Cloudflare 的 PT 域名 ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;direct\u0026#34;, \u0026#34;ip\u0026#34;: [ // 其它 Cloudflare IP 直连 \u0026#34;geoip:cloudflare\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;ip\u0026#34;: [ \u0026#34;geoip:private\u0026#34; ], \u0026#34;outboundTag\u0026#34;: \u0026#34;blocked\u0026#34; } ] } } 测试 V2Ray 配置是否正确\r完成配置后, 运行以下命令检查配置文件是否正确\n[root@gateway ~]# /home/v2ray/bin/v2ray test -config /home/v2ray/v2ray.json V2Ray 5.12.1 (V2Fly, a community-driven edition of V2Ray.) Custom (go1.21.4 linux/amd64) A unified platform for anti-censorship. Configuration OK. 如果显示 Configuration OK., 说明配置文件正确, 可以正常启动。\n至此, 第四阶段完成。\n开机自动运行透明代理规则\r在测试配置没有问题后, 我们可以让路由规则添加删除自动化, 使用 systemd 来管理路由规则脚本, 使其在开机时自动添加, 并在需要维护规则时可以自动清除。\n创建 systemd 服务文件\r该配置的作用是确保 tproxy-rule.sh 在网络启动后执行, 并在关闭时清除相应的规则\n新建 /etc/systemd/system/tproxy-rule.service 文件, 并添加以下内容\n[Unit] Description=V2Ray Tproxy Rule After=network.target Wants=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/home/v2ray/tproxy-rule.sh start ExecStop=/home/v2ray/tproxy-rule.sh stop [Install] WantedBy=multi-user.target 创建 tproxy-rule.sh 路由脚本\rtproxy-rule.sh 脚本负责添加和删除 TProxy 相关规则, 以确保透明代理的正常工作。\n新建 /home/v2ray/tproxy-rule.sh 并添加以下内容\n#!/bin/bash do_start() { ip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 firewall-cmd --direct --add-chain ipv4 mangle V2RAY firewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 3 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle V2RAY 4 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle V2RAY 5 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -j V2RAY # 代理透明网关自身 firewall-cmd --direct --add-chain ipv4 mangle GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 1 -m owner --uid-owner v2ray -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 2 -d 网关所在网段1 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 3 -d 网关所在网段2 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 4 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --add-rule ipv4 mangle GATEWAY_ITSELF 5 -j MARK --set-mark 1 firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 1 -p tcp -j GATEWAY_ITSELF firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 2 -p udp -j GATEWAY_ITSELF } do_stop() { ip rule del fwmark 1 table 100 ip route del local 0.0.0.0/0 dev lo table 100 firewall-cmd --direct --remove-rule ipv4 mangle V2RAY 1 -d 网关所在网段1 -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle V2RAY 2 -d 网关所在网段2 -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle V2RAY 3 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle V2RAY 4 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --remove-rule ipv4 mangle V2RAY 5 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1 firewall-cmd --direct --remove-rule ipv4 mangle PREROUTING 1 -j V2RAY firewall-cmd --direct --remove-chain ipv4 mangle V2RAY # 代理透明网关自身 firewall-cmd --direct --remove-rule ipv4 mangle GATEWAY_ITSELF 1 -m owner --uid-owner v2ray -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle GATEWAY_ITSELF 2 -d 网关所在网段1 -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle GATEWAY_ITSELF 3 -d 网关所在网段2 -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle GATEWAY_ITSELF 4 -d 224.0.0.0/3 -j RETURN firewall-cmd --direct --remove-rule ipv4 mangle GATEWAY_ITSELF 5 -j MARK --set-mark 1 firewall-cmd --direct --remove-rule ipv4 mangle OUTPUT 1 -p tcp -j GATEWAY_ITSELF firewall-cmd --direct --remove-rule ipv4 mangle OUTPUT 2 -p udp -j GATEWAY_ITSELF firewall-cmd --direct --remove-chain ipv4 mangle GATEWAY_ITSELF } case \u0026#34;$1\u0026#34; in start) do_start exit $? ;; stop) do_stop exit $? ;; *) echo \u0026#34;Usage: ${0} {start|stop}\u0026#34; exit 2 ;; esac 设置脚本权限\nchmod +x /home/v2ray/tproxy-rule.sh 设置开机启动并检查运行状态\nsystemctl enable tproxy-rule systemctl start tproxy-rule systemctl status tproxy-rule firewall-cmd --direct --get-all-rules 常见问题\r透明代理的其它注意事项\r如果 透明网关 作为 主路由, 需要在 PREROUTING 链的规则中额外添加一条规则, 即在第一阶段使用, 第二阶段删除的命令。避免被其他人蹭用你的代理。\nfirewall-cmd --direct --add-rule ipv4 mangle V2RAY 1 ! -s 网关LAN_IP地址段 -j RETURN 如果不添加此规则, WAN 口中 同网段的其他设备 可以将网关填写成你的 WAN IP, 从而蹭用你的透明代理, 甚至可能带来一定的危险性。\n解决 too many open files 问题\r对于 UDP 透明代理, 比较容易出现 \u0026ldquo;卡住\u0026rdquo; 的情况。这个时候细心的朋友可能会在 日志 中发现大量 too many open files 相关错误信息, 这说明受到了 最大文件描述符 数值的限制。把这个数值往大调就好了。\n修改 systemd 服务配置\r编辑 /etc/systemd/system/v2ray.service 文件, 在 [Service] 下添加\nLimitNPROC=500 LimitNOFILE=500000 修改后的配置如下\n[Unit] Description=V2Ray Service Documentation=https://www.v2fly.org/ After=network.target nss-lookup.target [Service] User=v2ray Group=v2ray PIDFile=/run/v2ray.pid CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE NoNewPrivileges=true ExecStart=/home/v2ray/bin/v2ray run -config /home/v2ray/v2ray.json Restart=on-failure # Don\u0026#39;t restart in the case of configuration error RestartPreventExitStatus=23 LimitNPROC=500 LimitNOFILE=500000 [Install] WantedBy=multi-user.target 重载配置后重启 v2ray\nsystemctl daemon-reload systemctl restart v2ray 检查文件描述符限制是否生效\r检查 V2Ray 进程的 最大文件打开数 是否设置成功, 服务端和客户端都要检查\n在服务端和客户端分别执行以下命令\ncat /proc/$(pgrep -u v2ray v2ray)/limits 或者手动替换 V2Ray 进程的 PID 进行查询\n# cat /proc/v2ray的pid/limits cat /proc/3812/limits 找到 Max open files 应该显示 500000, 表示文件描述符限制已成功提升。\n[root@gateway ~]# cat /proc/3812/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 500 500 processes Max open files 500000 500000 files Max locked memory 8388608 8388608 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 15612 15612 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us 原文\n透明代理入门\n透明代理(TPROXY)\n透明代理通过 gid 规避 Xray 流量\n透明代理\nUnable to get iptables owner module (gid-owner) to work\nRed Hat Linux 8.0: The Official Red Hat Linux Reference Guide - Chapter 13. Firewalls and iptables\nLinux Netfilter and Traffic Control\nFirewalld\nsystemd.service — Service unit configuration\nsystemd - archlinux: RemainAfterExit\nSystemd: how to start service after another service started\n第一篇万字长文: 围绕透明代理的又一次探究\n","date":"2024-02-03T16:22:00+08:00","permalink":"https://blog.acesheep.com/p/firewalld-tproxy-transparent-gateway/","title":"从零开始一步步实现基于 TProxy 的透明网关 | Firewalld 版"},{"content":"网上那么多人发了教程, 你们不会还以为我会说 revoke 这个关键字吗?\n那我就没必要再发一遍了。实际上, 使用 x32dbg/x64dbg 搜索 IM.dll 文件, 搜索 revoke 关键字后, 会出现一大堆结果, 能找到十几个相关的字符串, 这还能叫做关键字吗？\n经过我反复确认:\n好友防撤回 bytes_reserved 群消息防撤回 bytes_userdef 软件版本\n准备操作\r首先, 启动 QQ 并使用 x32dbg 调试工具分析 IM.DLL 文件。\n将 QQ 运行起来\n打开 x32dbg\n选择 文件 -\u0026gt; 附加, 然后选择 QQ 进程\n点击 符号 -\u0026gt; 搜索, 输入 im.dll, 找到 IM.dll 模块并双击进入代码空间\n好友防撤回\r在调试中, 搜索 bytes_reserved 字符串, 来找到与好友防撤回相关的代码。\n右键点击, 选择 搜索 -\u0026gt; 当前模块 -\u0026gt; 字符串, 然后输入 bytes_reserved\n根据多次经验总结, 通常第三个结果是我们要找的\n修改代码如下\n6D23D28A | 897D F4 | mov dword ptr ss:[ebp-C],edi |\r6D23D28D | 8B06 | mov eax,dword ptr ds:[esi] |\r6D23D28F | 51 | push ecx | # 从此处开始修改\r6D23D290 | 68 58975B6D | push im.6D5B9758 | 6D5B9758:\u0026#34;bytes_reserved\u0026#34;\r6D23D295 | 56 | push esi |\r6D23D296 | FF50 78 | call dword ptr ds:[eax+78] | [eax+78]:\u0026amp;L\u0026#34;诠焕贀焊慭湩\u0026#34;\r6D23D299 | 85C0 | test eax,eax | # jmp 到这里\r6D23D29B | 79 39 | jns im.6D23D2D6 |\r6D23D29D | 8D45 0C | lea eax,dword ptr ss:[ebp+C] | 修改前的代码\n修改步骤\n修改后的代码\n群消息防撤回\r接下来, 搜索 bytes_userdef 字符串来找到与群消息防撤回相关的代码。\n点击 引用 搜索字符串 bytes_userdef\n修改群消息防撤回的代码\n6D23D0D7 | 8B45 F0 | mov eax,dword ptr ss:[ebp-10] |\r6D23D0DA | 8D55 EC | lea edx,dword ptr ss:[ebp-14] |\r6D23D0DD | 52 | push edx |\r6D23D0DE | 895D EC | mov dword ptr ss:[ebp-14],ebx |\r6D23D0E1 | 68 E89A5B6D | push im.6D5B9AE8 | 6D5B9AE8:\u0026#34;bytes_userdef\u0026#34; # 从此处开始修改\r6D23D0E6 | 8B08 | mov ecx,dword ptr ds:[eax] |\r6D23D0E8 | 50 | push eax |\r6D23D0E9 | FF51 78 | call dword ptr ds:[ecx+78] |\r6D23D0EC | 85C0 | test eax,eax | # jmp 到这里\r6D23D0EE | 79 2D | jns im.6D23D11D |\r6D23D0F0 | 8D45 0C | lea eax,dword ptr ss:[ebp+C] | 修改前的代码\n修改步骤\n修改后的代码\n保存修改并应用补丁\r找到任意位置保存补丁文件, 然后手动将其复制到原文件所在目录, 替换掉原始文件。\n点击 文件 -\u0026gt; 补丁, 然后选择 修补文件\n效果验证\r修改后, 别人撤回消息时, 你不会收到撤回提示, 但消息仍然会保留\n原文\n实现简单的QQ消息防撤回功能\n关于XX和TXX的防撤回，直接搜索关键字，一步到位！\n","date":"2023-04-01T07:22:00+08:00","permalink":"https://blog.acesheep.com/p/tencent-qq-anti-message-recall/","title":"Tencent QQ 防撤回, 直接搜索关键字, 一步到位!"},{"content":"刚刚看到一篇帖子, 通过 User-Agent 禁止机器人并返回炸弹\n可以通过 User-Agent 字段来识别并禁止恶意爬虫, 甚至可以返回特定的数据给恶意程序。返回 404/403 瞬间不香了, 以前只知道直接禁了垃圾 bot, 现在我们可以直接返回一个特定的\u0026quot;炸弹\u0026quot;文件, 达到更强的反爬效果。\n例如, 实际 1GB 文件压缩成 1MB 大小的 gzip 文件 (炸弹) 来干扰恶意程序的正常采集行为。对于服务器来说, 实际上发送了 1MB 的数据, 但解压后的内容可能会达到 1GB, 恶意程序在请求后会自动解包 (如果程序支持), 可以对恶意程序造成很大的压力 (消耗大量服务器资源)。\n蜘蛛会分析页面, 这种方法可以恶心一下蜘蛛, 还可以在一定程度上消耗其读取文件所需的内存。\n使用 PHP 返回炸弹\r你可以将下面的 PHP 代码保存为 bomb.php 文件, 并放在网站目录中, 供恶意爬虫访问时使用\n\u0026lt;?php header(\u0026#39;Content-Encoding: gzip\u0026#39;); echo file_get_contents(\u0026#39;1G.gzip\u0026#39;); 如何制造炸弹文件\r插件中未提供炸弹, 因此你必须自己创建一个炸弹。在 Linux 系统中, 创建炸弹文件很容易, 你可以使用以下命令生成一个压缩的炸弹文件。以下是如何创建不同大小的 .gzip 文件\n# 创建 1GB 的压缩文件 dd if=/dev/zero bs=1M count=1024 | gzip \u0026gt; 1G.gzip # 创建 10GB 的压缩文件 dd if=/dev/zero bs=1M count=10240 | gzip \u0026gt; 10G.gzip # 创建 1TB 的压缩文件 dd if=/dev/zero bs=1M count=1048576 | gzip \u0026gt; 1T.gzip 为了进一步优化最终的炸弹文件, 你可以对其进行多次压缩\n# 压缩 10GB 文件两次 cat 10G.gzip | gzip \u0026gt; 10G.gzipx2 # 压缩 1TB 文件四次 cat 1T.gzip | gzip | gzip | gzip \u0026gt; 1T.gzipx4 注意: .gzipx2 或 .gzipx4 的扩展名只是突出显示文件被压缩了多少次\n将生成的炸弹文件 1G.gzip 和 bomb.php 放在同一目录中\n在 Nginx 中添加配置\r你可以通过修改 Nginx 配置来针对特定的 User-Agent 返回炸弹文件。示例如下\nlocation / { # 根据 User-Agent 返回炸弹文件 if ($http_user_agent ~* \u0026#34;(zhadan|bomb)\u0026#34;) { rewrite ^/.* /bomb.php last; } } 在这里, (zhadan|bomb) 是恶意 User-Agent 列表, 你可以根据需要替换为其他常见的恶意爬虫或机器人的 User-Agent。修改 /bomb.php 为你的炸弹 PHP 文件路径\n原文\n学到了, 通过User-Agent禁止机器人并返回炸弹\nNginx通过User-Agent禁止机器人并返回炸弹\nNginx通过User-Agent禁止采集机器人并返回炸弹 博客地址\n","date":"2023-01-10T16:55:40+08:00","permalink":"https://blog.acesheep.com/p/nginx-block-bots-user-agent-with-bomb/","title":"Nginx 通过 User-Agent 禁止采集机器人并返回炸弹"},{"content":"16:9 分辨率列表\r分辨率 (宽 x 高) 总像素数 设计名称 备注 7680 × 4320 33,177,600 8K 8K UHD 3840 × 2160 8,294,400 2160p 4K UHD 2560 × 1440 3,686,400 1440p QHD 1920 × 1080 2,073,600 1080p Full HD 1280 × 720 921,600 720p HD 854 × 480 410,112 480p SD 640 × 360 230,400 360p Low Res 426 × 240 102,240 240p Very Low Res 256 × 144 36,864 144p Ultra low Res 4:3 分辨率列表\r分辨率 (宽 x 高) 总像素数 设计名称 备注 160 x 120 19,200 QQVGA 256 x 192 49,152 0.05M3 任天堂 DS (每个屏幕) 320 x 240 76,800 QVGA 640 x 480 307,200 VGA 800 x 600 480,000 SVGA 960 x 720 691,200 0.69M3 1024 x 768 786,432 XGA 1152 x 864 995,328 XGA+ 1280 x 960 1,228,800 SXGA− 720P 1400 x 1050 1,470,000 SXGA+ 1440 x 1080 1,555,200 1.56M3 1600 x 1200 1,920,000 UXGA 1856 x 1392 2,583,552 2.58M3 1920 x 1440 2,764,800 2.76M3 1080P 2048 x 1536 3,145,728 QXGA 2K 2560 x 1920 4,915,200 4.92M3 2880 x 2160 6,220,800 3K UHD 3072 x 2304 7,077,888 3K 3840 x 2880 11,059,200 4K UHD 4096 x 3072 12,582,912 HXGA 4K 5120 x 3840 19,660,800 5K 6144 x 4608 28,311,552 6K 7680 x 5760 44,236,800 8K UHD 8192 x 6144 50,331,648 8K 原文\nComplete list of 16:9 resolutions\nWhat Are the Resolutions of 4:3 Aspect Ratio\n","date":"2023-01-08T17:36:00+08:00","permalink":"https://blog.acesheep.com/p/frequently-used-display-resolutions/","title":"常用分辨率 16:9 | 4:3"},{"content":"解决 Hugo 报错: /lib64/libstdc++.so.6: version 'GLIBCXX_3.4.20' not found 问题\nSolution to errors like /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20\u0026rsquo; not found\n使用 Hugo 时遇到以下错误\nhugo: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20\u0026#39; not found (required by hugo) hugo: /lib64/libstdc++.so.6: version `CXXABI_1.3.8\u0026#39; not found (required by hugo) hugo: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21\u0026#39; not found (required by hugo) 在经过一些测试后, 确认安装最新版本的 GCC 可以解决此问题, 适用于 CentOS 7.9\n解决方案\r检查 libstdc++ 版本\r首先检查现有的 libstdc++ 库版本\n[root@localhost lib64]# ll libstdc++.so.6* lrwxrwxrwx. 1 root root 19 Jan 8 10:09 libstdc++.so.6 -\u0026gt; libstdc++.so.6.0.19 -rwxr-xr-x. 1 root root 995840 Sep 30 2020 libstdc++.so.6.0.19 [root@server ~]# strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.4.3 GLIBCXX_3.4.4 GLIBCXX_3.4.5 GLIBCXX_3.4.6 GLIBCXX_3.4.7 GLIBCXX_3.4.8 GLIBCXX_3.4.9 GLIBCXX_3.4.10 GLIBCXX_3.4.11 GLIBCXX_3.4.12 GLIBCXX_3.4.13 GLIBCXX_3.4.14 GLIBCXX_3.4.15 GLIBCXX_3.4.16 GLIBCXX_3.4.17 GLIBCXX_3.4.18 GLIBCXX_3.4.19 GLIBCXX_DEBUG_MESSAGE_LENGTH 安装新版本的 GCC\r可以通过使用 Ghettoforge 仓库来安装新版本的 GCC\nyum install https://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm yum install gcc10-libstdc++ 你可以在 Ghettoforge 软件包仓库地址中找到 gcc10-libstdc++-10.2.1-7.gf.el7.x86_64.rpm, 可以直接使用链接进行安装。备份下载\nyum install http://mirror.ghettoforge.org/distributions/gf/el/7/gf/x86_64/gcc10-libstdc++-10.2.1-7.gf.el7.x86_64.rpm 查找并更新 libstdc++ 库\r查找 libstdc++ 文件位置\n[root@localhost ~]# find / -type f -name \u0026#34;libstdc++.so.6*\u0026#34; /usr/lib64/libstdc++.so.6.0.19 /usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.19-gdb.py /usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.19-gdb.pyc /usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.19-gdb.pyo /opt/gcc-10.2.1/usr/lib64/libstdc++.so.6.0.28 /opt/gcc-10.2.1/usr/share/gdb/auto-load/opt/gcc-10.2.1/usr/lib64/__pycache__/libstdc++.so.6.0.28-gdb.cpython-36.opt-1.pyc /opt/gcc-10.2.1/usr/share/gdb/auto-load/opt/gcc-10.2.1/usr/lib64/__pycache__/libstdc++.so.6.0.28-gdb.cpython-36.pyc /opt/gcc-10.2.1/usr/share/gdb/auto-load/opt/gcc-10.2.1/usr/lib64/libstdc++.so.6.0.28-gdb.py /opt/gcc-10.2.1/usr/share/gdb/auto-load/opt/gcc-10.2.1/usr/lib64/libstdc++.so.6.0.28-gdb.pyc /opt/gcc-10.2.1/usr/share/gdb/auto-load/opt/gcc-10.2.1/usr/lib64/libstdc++.so.6.0.28-gdb.pyo 将新版本的 libstdc++ 文件复制到 /usr/lib64/ 目录\n[root@localhost ~]# cp /opt/gcc-10.2.1/usr/lib64/libstdc++.so.6.0.28 /usr/lib64/ 更新符号链接\r删除旧的符号链接, 并创建指向新版本库的符号链接\n[root@localhost ~]# cd /usr/lib64 [root@localhost lib64]# rm -f libstdc++.so.6 [root@localhost lib64]# ln -s libstdc++.so.6.0.28 libstdc++.so.6 [root@localhost lib64]# ll libstdc++.so.6* lrwxrwxrwx 1 root root 19 Jan 8 10:34 libstdc++.so.6 -\u0026gt; libstdc++.so.6.0.28 -rwxr-xr-x. 1 root root 995840 Sep 30 2020 libstdc++.so.6.0.19 -rwxr-xr-x 1 root root 17104448 Jan 8 10:31 libstdc++.so.6.0.28 检查更新后的库版本\r确认库已更新到所需的版本\n[root@localhost ~]# strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.4.3 GLIBCXX_3.4.4 GLIBCXX_3.4.5 GLIBCXX_3.4.6 GLIBCXX_3.4.7 GLIBCXX_3.4.8 GLIBCXX_3.4.9 GLIBCXX_3.4.10 GLIBCXX_3.4.11 GLIBCXX_3.4.12 GLIBCXX_3.4.13 GLIBCXX_3.4.14 GLIBCXX_3.4.15 GLIBCXX_3.4.16 GLIBCXX_3.4.17 GLIBCXX_3.4.18 GLIBCXX_3.4.19 GLIBCXX_3.4.20 GLIBCXX_3.4.21 GLIBCXX_3.4.22 GLIBCXX_3.4.23 GLIBCXX_3.4.24 GLIBCXX_3.4.25 GLIBCXX_3.4.26 GLIBCXX_3.4.27 GLIBCXX_3.4.28 通过以上步骤, 成功解决了 Hugo 对 libstdc++.so.6 库版本的依赖问题\n原文\nSolution to errors like /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20\u0026rsquo; not found\n","date":"2023-01-08T09:18:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7.9-libstdc-upgrade/","title":"CentOS 7.9 libstdc++ 版本过低问题"},{"content":"给 JiJiDown 2 更新 FFmpeg 版本, 在 Ubuntu 22.04.1 LTS 中编译 32/64 位 FFmpeg\n安装编译工具\r使用 mingw-w64 进行交叉编译\nsudo apt-get -y install mingw-w64-tools gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 make yasm 编译 libmp3lame\rLAME MP3 编码器是一个根据 LGPL 许可发布的高质量 MPEG 音频第三层 (MP3) 编码器\n32 位\r查找交叉编译头文件目录位置\nffmpeg@ffmpeg:~/lame-3.100$ sudo find / -type d -name \u0026#34;*i686-w64-mingw32\u0026#34; /usr/i686-w64-mingw32 /usr/lib/gcc/i686-w64-mingw32 ffmpeg@ffmpeg:~$ tree -L 1 /usr/i686-w64-mingw32 /usr/i686-w64-mingw32 ├── bin ├── include ├── lib └── share 4 directories, 0 files 编译参数\n./configure --prefix=/usr/i686-w64-mingw32 --host=i686-w64-mingw32 --enable-shared=no make -j sudo make install 64 位\r查找交叉编译头文件目录位置\nffmpeg@ffmpeg:~/lame-3.100$ sudo find / -type d -name \u0026#34;*x86_64-w64-mingw32*\u0026#34; /usr/x86_64-w64-mingw32 /usr/lib/gcc/x86_64-w64-mingw32 ffmpeg@ffmpeg:~$ tree -L 1 /usr/x86_64-w64-mingw32 /usr/x86_64-w64-mingw32 ├── bin ├── include ├── lib └── share 4 directories, 0 files 编译参数\nmake clean ./configure --prefix=/usr/x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-shared=no make -j sudo make install 编译 FFmpeg\r下载 FFmpeg 源代码\nwget https://ffmpeg.org/releases/ffmpeg-5.1.2.tar.xz tar xf ffmpeg-5.1.2.tar.xz cd ffmpeg-5.1.2/ configure 中的参数判断规则\ni[3-6]86*|i86pc|BePC|x86pc|x86_64|x86_32|amd64) arch=\u0026#34;x86\u0026#34; mingw32*|mingw64*) target_os=mingw32 32 位\r./configure \\ --arch=x86 \\ --target-os=mingw32 \\ --cross-prefix=i686-w64-mingw32- \\ --enable-small \\ --disable-autodetect \\ --disable-debug \\ --disable-network \\ --disable-pthreads \\ --disable-w32threads \\ --disable-doc \\ --disable-ffplay \\ --disable-ffprobe \\ --disable-decoders \\ --enable-decoder=\u0026#39;aac,aac_fixed\u0026#39; \\ --disable-encoders \\ --enable-libmp3lame \\ --enable-encoder=\u0026#39;libmp3lame\u0026#39; \\ --disable-hwaccels \\ --disable-parsers \\ --disable-demuxers \\ --enable-demuxer=\u0026#39;mov\u0026#39; \\ --disable-muxers \\ --enable-muxer=\u0026#39;mp4,mp3\u0026#39; \\ --disable-protocols \\ --enable-protocol=\u0026#39;file\u0026#39; \\ --disable-filters \\ --disable-bsfs \\ --disable-indevs \\ --disable-outdevs make -j 64 位\rmake clean ./configure \\ --arch=x86 \\ --target-os=mingw32 \\ --cross-prefix=x86_64-w64-mingw32- \\ --enable-small \\ --disable-autodetect \\ --disable-debug \\ --disable-network \\ --disable-pthreads \\ --disable-w32threads \\ --disable-doc \\ --disable-ffplay \\ --disable-ffprobe \\ --disable-decoders \\ --enable-decoder=\u0026#39;aac,aac_fixed\u0026#39; \\ --disable-encoders \\ --enable-libmp3lame \\ --enable-encoder=\u0026#39;libmp3lame\u0026#39; \\ --disable-hwaccels \\ --disable-parsers \\ --disable-demuxers \\ --enable-demuxer=\u0026#39;mov\u0026#39; \\ --disable-muxers \\ --enable-muxer=\u0026#39;mp4,mp3\u0026#39; \\ --disable-protocols \\ --enable-protocol=\u0026#39;file\u0026#39; \\ --disable-filters \\ --disable-bsfs \\ --disable-indevs \\ --disable-outdevs make -j ","date":"2023-01-07T12:20:00+08:00","permalink":"https://blog.acesheep.com/p/cross-compile-ffmpeg-5.1.2-for-windows-in-ubuntu/","title":"Ubuntu 22.04.1 LTS 交叉编译 FFmpeg 5.1.2 For Windows"},{"content":"在 Telegram Premium 中, 可以使用 Animated Profile Pictures 功能来设置动态头像。但如果直接上传 GIF 图片, 头像会变成静态的。因此, 我们需要将 GIF 转换为 MP4 视频文件, 以便作为头像上传。同时, 这样还可以调整播放速度\n检查 GIF 图像信息\r确认 GIF 图层总数\r使用 Photoshop 打开 input.gif, 并计算图层的数量。例如, input.gif 有 1-22 图层, 总计 22 个图层\n设置循环次数和图层总数\r[loop]loop=loop=3:size=22:start=0[speed]; ^ ^ 循环次数 GIF 图层总数 控制播放速度\r大于 1.0 是减速, 相当于拉长视频\n小于 1.0 是加速, 相当于缩短视频\n[speed]setpts=1.2*PTS[fps] 设置输出视频的帧数 (fps)\r帧率不会影响视频的长度或速度。常见的帧率有 30、60、90 或 120\n[fps]fps=30[v] 转换命令\r最终拼接参数得到命令\nffmpeg -i input.gif -filter_complex \u0026#34;[0:v]scale=trunc(iw/2)*2:trunc(ih/2)*2[loop];[loop]loop=loop=3:size=22:start=0[speed];[speed]setpts=1.2*PTS[fps];[fps]fps=30[v]\u0026#34; -map \u0026#34;[v]\u0026#34; -movflags faststart -pix_fmt yuv420p output.mp4 其他例子\r如果 input.gif 只有 4 个图层, 且希望视频时长变长, 可以多循环几次。例如, 循环 40 次\nffmpeg -i input.gif -filter_complex \u0026#34;[0:v]scale=trunc(iw/2)*2:trunc(ih/2)*2[loop];[loop]loop=loop=40:size=4:start=0[speed];[speed]setpts=1.0*PTS[fps];[fps]fps=30[v]\u0026#34; -map \u0026#34;[v]\u0026#34; -movflags faststart -pix_fmt yuv420p output.mp4 -y 原文\nGIF to MP4 by ffmpeg\nHow to speed up/slow down a video\nHow to connect filter complex in ffmpeg?\n","date":"2022-12-13T06:17:00+08:00","permalink":"https://blog.acesheep.com/p/ffmpeg-convert-gif-to-mp4/","title":"使用 FFmpeg Gif to mp4"},{"content":"在 DIY 音频项目中, 你可能需要一种方式将音频输入到电路中。最常见的方式之一是使用 3.5 毫米立体声音频插孔。这些插孔可以从旧的便携音频耳机中回收。如果切断耳塞, 就可以将插孔插入音频源, 并将导线直接连接到电路上。\n在本教程中, 我将向你展示如何连接两种常见的音频插孔类型 - TRS 和 TRRS\nT 代表 tip, R 代表 ring, S 代表 sleeve\nTRS 音频插孔\rTRS 音频插头通常出现在没有麦克风的标准立体声耳机中。剪断耳机线后, 你可能会发现以下三种常见的接线方式之一:\n铜线接地护套包裹着两根绝缘的音频信号线 两根独立的绝缘线, 每根都有自己的信号线和一根接地线 一根电缆内有独立的接地、右音频和左音频绝缘线 通常, 红线是右声道, 蓝线是左声道。请查看下图, 了解在最常见的 TRS 接线方案中, 哪些导线是音频信号线, 哪些是地线\n电线连接到 TRS 插头的方式如下所示\n根据插头的类型, 你可能可以接触到连接器外壳内的针脚。电线连接到插头的针脚如下所示\n如果只需要单声道输入, 可以将左右声道线连接在一起。\n确定电线后, 只需将它们焊接到电路中的正确输入通道, 或通过引脚连接器连接, 以便将它们用于面包板。\nTRRS 音频插孔\rTRRS 音频插孔可以在 iPhone 耳机和其他带麦克风的耳机上找到。切开塑料绝缘套后, 你会发现 5 根单独的导线:\n实心红色导线: 右声道信号 红色和铜绞线: 右声道地线 实心绿色导线: 左声道信号 绿色和铜绞线: 左声道地线 红绿色护套内带有铜线: 内层铜线为麦克风信号, 外部护套是麦克风地线 此外, 你还会发现一根塑料绳, 用于加强耳机电缆的强度:\nTRRS 插头的连接方式如下所示:\n如果你能接触到插头外壳内的针脚, TRRS 插头的针脚连接如下所示:\n如果你只需要 TRRS 连接器的单声道音频输入, 可以将红色和绿色导线合并为一根单声道音频线, 并将地线合并为一根地线。\n每根导线外面都有一层非常薄的绝缘涂层, 因此可以在没有塑料绝缘的情况下将它们捆绑在一起。在焊接或连接到任何导电体之前, 你可以用火快速烧掉绝缘材料, 然后擦拭干净。\n完成后, 可以将导线直接焊接到 PCB 上的输入端, 或将其连接到跳线针上, 方便插入面包板。\n原文\nHow to Hack a Headphone Jack\n","date":"2022-12-13T06:12:00+08:00","permalink":"https://blog.acesheep.com/p/headphone-jack-pinout/","title":"耳机接口引脚定义"},{"content":"USB 引脚定义\rUSB 是一种串行总线, 它使用四根屏蔽导线: 两根用于供电 (+5V 和 GND), 另外两根用于差分数据信号 (在排针中标记为 D+ 和 D-)。在 USB 数据线中, Data+ 和 Data- 信号通过双绞线传输, 无需端接。半双工差分信号有助于减少电磁噪声对较长线路的影响。D+ 和 D- 一起工作, 而不是单独的简单连接。\nUSB 支持四种数据速率:\n低速 (Low Speed): 每秒 1.5 Mbit, 主要用于人体输入设备 (HID), 如键盘、鼠标、游戏手柄, 通常也用于打印机或扫描仪等设备 全速 (Full Speed): 每秒 12 Mbit, USB 集线器广泛支持全速 高速 (Hi-Speed): 每秒 480 Mbit, 在 USB 2.0 规范中添加。并非所有的 USB 2.0 设备都支持高速 超高速 (SuperSpeed): USB 3.0 的速率为 4800 Mbit/s (约 572 MB/s) USB 设备必须通过将 D+ 或 D- 线拉高至 3.3 伏特来指示其速度。设备端的这些上拉电阻将被主机或集线器用来检测连接到端口的设备。如果没有上拉电阻, USB 会假定总线上没有连接任何设备。\n各种连接器的引出线如下所示\rPin Name Cable color Description 1 VCC Red +5 VDC 2 D- White Data - 3 D+ Green Data + 4 GND Black Ground USB Micro-B 连接器\rMicro-B 连接器在小型设备上越来越受欢迎。以下是从插头末端显示的引出线\nPin Name Cable color Description 1 VCC Red +5 VDC 2 D- White Data - 3 D+ Green Data + 4 ID n/a USB OTG ID 5 GND Black Ground 原文\nUSB Connector Pinouts\n","date":"2022-12-13T05:52:00+08:00","permalink":"https://blog.acesheep.com/p/usb-connector-pinout/","title":"USB 引脚定义"},{"content":"在本教程中, 我们将学习如何在 CentOS 7 上挂载 Samba 共享。Samba 通常用于与 Windows 计算机共享文件, 但通过 SMB/CIFS 协议, 我们也可以在 Linux 上挂载 Samba 共享。\n安装 cifs-utils 包\r要在 CentOS 7 上挂载 Samba 共享, 我们需要安装 cifs-utils 包。cifs-utils 包含了使用 SMB/CIFS 协议挂载共享所需的工具和实用程序。\nyum install cifs-utils 使用 mount 命令挂载 Samba 共享\r现在, 我们可以使用 mount 命令在 CentOS 7 上挂载 smb 共享。文件系统类型应该是 cifs\nmount -t cifs -o username=username //server-name/share-name /mount-point 执行命令后, mount 命令将提示输入 Samba 密码。\n例如, 假设我的网络中有一台 Samba 共享服务器, IP 地址为 192.168.1.10, 共享名称为 Documents, 用户名为 sambauser, 我将使用 /mnt 目录作为挂载点。\nmount -t cifs -o username=sambauser //192.168.1.10/documents /mnt 如果需要, 也可以将密码作为命令选项提供\nmount -t cifs -o username=sambauser,password=pass //192.168.1.10/documents /mnt 使用 fstab 挂载 Samba 共享\r如果需要自动挂载 Samba 共享, 可以将条目添加到 /etc/fstab 中。例如\n//192.168.1.10/documents /mnt cifs username=sambauser,password=pass 0 0 然后运行 mount -a 命令来挂载文件系统\n使用凭据文件进行身份验证\r除了将用户名和密码作为命令选项提供外, 我们还可以使用凭据文件, 其中包含用于访问 Samba 共享的用户名和密码。\n首先, 创建一个凭据文件, 并将用户名和密码添加到该文件中\nvim /var/smbcredentials 在文件中添加以下内容\nusername=sambauser password=pass 然后, 使用凭据文件作为选项, 使用 mount 命令挂载 Samba 共享\nmount -t cifs -o credentials=/var/smbcredentials //192.168.1.10/documents /mnt 在 /etc/fstab 中, 条目应如下所示\n//192.168.1.10/documents /mnt cifs credentials=/var/smbcredentials 0 0 原文\nHow to Mount Samba Share on CentOS 7\n","date":"2022-12-11T08:17:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-mount-smb-network-drive/","title":"CentOS 7 挂载 SMB 网络磁盘"},{"content":"虽然目前已有支持 Mod 的高版本 (1.15.1) 服务器实现 (如 Fabric), 但 Sponge 服务器的搭建仍然具有重要意义, 因为它是唯一一种可以同时支持高版本、Mod、和插件的服务端, 而 Fabric 仅支持 Mod。\n本文将详细介绍如何安装 Sponge, 并部署一个支持 Mod 和插件的 Minecraft 1.12.2 服务器。\n介绍\rSponge 是一个为 Minecraft 提供插件支持的开源项目, 作为服务端的核心, 有三个分支, 分别是\nSpongeVanilla: 基于原版 Minecraft, 适合需要插件但不需要 Mod 的服务器 SpongeForge: 基于 Minecraft Forge, 适合同时运行 Forge Mod 和插件的服务器 SpongeNeo: 基于 NeoForge, 适合同时运行 NeoForge Mod 和插件的服务器 在这里, 为了能够安装 Mod, 我们选择 SpongeForge 分支\n在服务器中, Sponge 作为一个 Mod 放置在 mods 文件夹中, 与插件、Mod 并列存放\nSponge 的工作原理是通过提供统一的 API, 使插件和 Mod 能够共存并相互协作。\n也就是说, 支持插件和 Mod 的服务器是由一个基础的 Forge 服务器 (原版服务端 + Forge) 与 Sponge API 组成的。Sponge 的作用是为其他 Forge Mod 提供 API, 使它们能够无缝协作。\n其原理与高版本 Fabric 中的 Optifine Loader 类似。由于 Optifine 无法直接与高版本的 Fabric (甚至 Forge) 兼容, 一些开发者创建了 Optifine Loader, 它将为 Optifine 提供了适配 Fabric 的接口。\n总的来说, Sponge 的部署步骤与一般的 Forge 服务器类似, 唯一的区别就是需要额外添加 Sponge API 模组。\n搭建步骤\r下载所需文件\rSponge 对 Forge 的版本有一定要求, 因此在选择 Sponge 时, 需要注意其支持的 Forge 版本号。\n例如, Forge 版本号为 1.12.2-14.23.5.2838, 对应的 Sponge 版本号为 1.12.2-2838-7.4.7, 这表示它们是兼容的版本。如果这两个版本不一致, Forge 版本较高 (Sponge 版本较低), 可能会导致运行不稳定, 而如果 Forge 版本较低 (Sponge 版本较高), 则可能会导致部分插件无法正常运行。\n首先我们需要下载必要的文件, 包括:\nMinecraft 原版服务器端 1.12.2 - 备份下载 minecraft_server.1.12.2.jar Minecraft Forge 1.12.2 - 备份下载 forge-1.12.2-14.23.5.2859-installer.jar Sponge Forge 1.12.2 - 备份下载 spongeforge-1.12.2-2838-7.4.7.jar 创建服务器文件夹\r创建一个名为 sponge-server 的文件夹\nmkdir sponge-server cd sponge-server 将 Minecraft 原版服务端文件放入, 并重命名为 minecraft_server.1.12.2.jar\n重命名文件是为了避免 Forge 安装器下载官方服务端时失败。Forge 安装过程中会尝试下载官方服务端, 但实际上它无法成功下载 (即使使用科学上网, Java 默认不会使用系统的代理设置)。因此, 我们需要通过其它途径提前下载服务端文件, 并将其命名为 Forge 所预期的文件名。这样, Forge 安装器就会跳过服务端下载, 直接开始下载所需的库文件。\n安装 Forge\r双击打开或使用以下命令打开 Forge 安装器\njava -jar forge-1.12.2-14.23.5.2859-installer.jar 选择 Install server, 并指定 sponge-server 文件夹。若提示 There are already files at the target directory, 可以忽略并继续安装。\n在安装过程中, 如果出现错误 (如下载失败), 无需担心。只需重复上述步骤, Forge 会自动跳过已下载的文件, 继续从上次进度开始。\n大概 20 秒左右安装完成后, 你会发现 sponge-server 文件夹中多出了一个 libraries 文件夹, 这就是我们所需要的库文件。\n此时, 一个基本的 Forge 服务器已经搭建完成。位于 sponge-server 文件夹中的 Forge universal 文件即为服务器核心, 以后启动服务器时需要使用这个文件。\n启动服务器\r现在, 我们可以启动服务器来生成一些必要的文件\njava -jar forge-1.12.2-14.23.5.2859-universal.jar 启动后, 服务器会生成 eula.txt 文件。将文件中的内容修改为 eula=true, 然后重新启动服务器。这时, 服务器将生成基础文件夹和文件, 如 logs、world、server.properties, 以及最重要的 mods 文件夹。\n当服务器启动完成后, 输入以下命令关闭服务器\n\u0026gt; stop 添加 Sponge\r将之前下载的 Sponge 文件 (spongeforge-1.12.2-2838-7.4.7.jar) 放入 mods 文件夹中, 然后启动服务器。你就会发现: 哇, 启动速度慢了一大截呢 就成功了！\n这个时候, 启动带 Forge 的客户端, 可以直接进入服务器\n插件管理\rSponge 插件和 Mod 都放在 mods 文件夹中, 这一点与 Bukkit 完全不同。它们的配置文件位于 config 文件夹中。服务器的插件和 Mod 结构如下\nsponge-server ├── config │ ├── plugin1 │ │ └── main.conf │ ├── plugin2 │ │ └── config.conf │ └── simpleplugin.conf └── mods ├── plugin1.jar ├── plugin2.jar └── simpleplugin.jar 每个插件或 Mod 都有相应的配置项, 这些配置文件通常位于 config 文件夹中。大多数插件的配置会放在与插件名称相同的文件夹里, 少数简单的插件则直接放在 config 文件夹中。通过修改这些配置文件, 你可以调整插件或 Mod 的设置, 类似于 Bukkit 中的 config.yml\n与 Mod 不同, 插件不需要在本地客户端安装 (插件无需安装在客户端, 仅需安装服务器所需的 Mod)。这意味着你只需要安装那些可以玩的 Mod, 而无需安装服务器上的插件 (例如领地、经济等)。对于像 World Edit 这种既有插件版本也有 Mod 版本的, 建议选择插件版本, 因为它更适合服务器使用。\nSponge 插件的兼容性是通过 API 来判断的。目前, 1.12.2 版本的 Sponge 使用的是 API7, 因此任何使用 API7 接口开发的插件都可以在该版本的 Sponge 服务器上运行。少数为 API6、API5 或更低版本开发的插件 (例如 World Edit) 也能正常运行, 但稳定性较差。部分插件则可能完全不能运行。\n这也告诉我们在更新 Sponge 时要慎重, 如果更新版本过高, 一些不再维护的插件就会失效。\n插件推荐\rSponge 服务端构建出了一种独立于 Bukkit 插件的体系, 因此它们的主流插件也都不一样了。在这里给出 Sponge 服务端中常用的一些 Mod\n经济 TotalEconomy EconomyLite 👍 商店 AmberShop - A QuickShop-like trading plugin 权限管理 LuckPerms 👍 PermissionsEx 领地 RedProtect Anti-Grief | Server Protection | Region Management [1.7-1.18+] 👍 GriefPrevention 不支持 Residence！ 登录 FlexibleLogin 👍 基础管理 Nucleus 或 ore.spongepowered.org/Nucleus/Nucleus 👍 不支持 Essentials！ 皮肤 CustomSkinLoader - Mods - Minecraft - CurseForge 👍 杂项 JoinTitle - 登录标题 SpongeLoginFix - [安全|修正] 海绵修复登入插件影分身刷东西 BUG [1.12.2] GiftCode - 兑换码 SendItems v0.1 - 发送物品 常见问题\r进入服务器后无法破坏东西?\r可能是出生点保护。将 server.properties 中的 spawn-protection 项设置为 0\nOP 无效?\r在 Sponge 中没有 OP 的概念, 取而代之的是更复杂且灵活的权限组管理。你需要依赖权限管理插件来实现这一功能, 推荐使用 LuckPerms。需要注意的是, Sponge 的权限节点与 EssentialsX 等插件的权限节点不通用, 具体可以参考相关文档。\n/help 无权限?\r/help 命令的权限在 sponge.commands.help, 确保为玩家赋予此权限。同时, OP 应该拥有 sponge.commands 权限。\n/gamerule、/gamemode 等无权限?\r这些命令属于原版指令, 其权限在 minecraft.commands 里。OP 需要拥有 minecraft.commands 权限才能使用这些命令。\n在一次性给予所有权限 (* 权限) 以后, 发生很多奇怪的事情?\r建议重置权限组。不推荐一次性授予 * 权限, 因为这样会给玩家一些不必要的权限。例如, nucleus.vanish.onlogin 会导致玩家每次登录时自动隐身, 除了聊天以外没有任何办法发现此人 (Tab 菜单也不可见)。\nNucleus 如何设置玩家家的数量以及称号?\r可以通过与 LuckPerms 配合使用来方便地设置这些选项。使用权限组来区分不同设置。\n将 default 组的最大 home 数量设置为 5 个\n\u0026gt; /lp group default meta set home-count 5 为 default 组的玩家添加一个绿色昵称前缀, 其中 addprefix 后面需要跟上一个表示权重的数字\n\u0026gt; /lp group default meta addprefix 1 [\u0026amp;a玩家\u0026amp;r] 原文\nSponge 搭建 1.12.2 Mod + 插件服务器\n","date":"2022-12-11T05:27:00+08:00","permalink":"https://blog.acesheep.com/p/sponge-minecraft-1.12.2-mod-and-plugin-server/","title":"Sponge 搭建 Minecraft 1.12.2 Mod + 插件服务器"},{"content":"主播带女水友, 使用国内完美世界联机限制非常多。比如下需要载第三方客户端、进行实名认证、改名需要改名卡、设置自定义房间需要 10 人才能开始游戏、Steam 原版启动无法连接完美世界的服务器, 且组队匹配需要完成 10 场定级赛, 如此恶心人的服务不惯着它。\n自建! 自建! 如果不想忍受这些繁琐的限制, 自建服务器是一个不错的选择。通过自建服务器, 不仅能够方便的一起游戏, 还可以自由定义插件等内容, 玩得更加爽歪歪!\n搭建步骤\r安装 SteamCMD\r首先, 以 root 用户身份登录到服务器, 创建一个名为 steam 的用户, 并切换到该用户的环境下\n# 安装 32 位运行依赖 yum install glibc.i686 libstdc++.i686 -y # 新建用户 useradd steam su - steam # 下载 SteamCMD wget http://media.steampowered.com/installer/steamcmd_linux.tar.gz tar -xf steamcmd_linux.tar.gz ./steamcmd.sh 安装 CS:GO 服务端\r通过 SteamCMD 安装 CS:GO 服务端。确保已经运行 ./steamcmd.sh, 进入 Steam\u0026gt; 命令行后, 执行以下命令安装 CS:GO 服务端。注意, 安装需要至少 31G 的磁盘空间\nSteam\u0026gt;force_install_dir ./csgo_server Steam\u0026gt;login anonymous Steam\u0026gt;app_update 740 validate Steam\u0026gt;quit 服务端更新脚本 (可选)\r为了方便每次更新时, 可以创建一个更新脚本\ncat\u0026gt;\u0026gt;/home/steam/update.txt\u0026lt;\u0026lt;\\EOF force_install_dir ./csgo_server login anonymous app_update 740 quit EOF 运行脚本\n./steamcmd.sh +runscript /home/steam/update.txt 注册 CS:GO 服务端\r为了让互联网用户能够加入你的 CS:GO 服务器, 你需要先在 Steam 游戏服务器帐户管理 页面注册你的服务器\n创建配置文件\r编辑服务器的配置文件\nvim csgo_server/csgo/cfg/server.cfg 在 server.cfg 中配置以下内容\n// 基础设置 sv_setsteamaccount 4F6815C************************ // 服务器的 Steam 帐户密钥 hostname \u0026#34;一只小苏念的 CS:GO 服务器\u0026#34; // 服务器在社区服务器浏览器上显示的名称 rcon_password 51522zzwlwlbb // CS:GO 远程控制台密码, 修改为自己定义的密码 sv_maxrate 128000 // 服务器最大带宽使用量, 默认值非常小, 因此会造成 choke 值异常, 此处建议改为 128000 sv_minrate 80000 // 服务器最小带宽使用量, 建议设置为 80000 // 游戏模式设置 // game_type 0 // game_mode 1 // map de_inferno // 游戏规则设置 mp_friendlyfire 0 // 禁用队友伤害 mp_autokick 0 // 禁用自动踢出挂机或误伤玩家 mp_tkpunish 0 // 禁用队友误伤惩罚 mp_spectators_max 9 // 允许最多有 9 个观察者 mp_drop_knife_enable 1 // 启用丢刀 mp_warmuptime 1200 // 热身时间, 单位为秒 mp_autoteambalance 0 // 禁用自动平衡队伍 mp_limit_teams 0 // 禁用队伍人数限制 sv_allow_lobby_connect_only 0 // 允许直接连接服务器, 如果设置为 1, 则只允许匹配进入游戏, 而不允许直接连接 // 启用录制 demo tv_enable 1 // 启用录制 demo tv_autorecord 1 // 启用自动录制 tv_maxclients 0 // 禁用 TV 客户端连接 // 机器人设置 bot_difficulty 3 // 机器人难度: 0=简单, 1=普通, 2=困难, 3=专家 bot_chatter off // 禁用机器人语音 bot_join_after_player 1 // 玩家加入后再加入机器人 bot_quota 10 // 总机器人数量 bot_quota_mode normal // 机器人配额模式: normal=正常, fill=填充, match=匹配 // 盾牌设置 // sv_shield_bash_damage_to_nonplayer 90 // 盾牌击打对非玩家造成伤害 // sv_shield_bash_damage_to_players 90 // 盾牌击打伤害对玩家造成伤害 sv_shield_hitpoints 10000 // 盾牌耐久度 // FastDL sv_downloadurl \u0026#34;https://example.com/csgo\u0026#34; // 设置 FastDL 下载地址 sv_allowdownload 1 // 启用文件下载 sv_allowupload 0 // 禁用文件上传 防止服务器配置被游戏模式覆盖\n由于 server_last.cfg 通常是服务器启动过程中最后加载的配置文件, 其设置会覆盖之前加载的任何配置文件中的设置, 例如 server.cfg 或其他模式专用的配置文件\nvim csgo_server/csgo/cfg/server_last.cfg 在 server_last.cfg 中添加以下内容\nmp_friendlyfire 0 游戏模式设置\r// 游戏模式设置 休闲模式 +game_type 0 +game_mode 0 竞技模式 +game_type 0 +game_mode 1 搭档模式 +game_type 0 +game_mode 2 军备竞赛 +game_type 1 +game_mode 0 爆破模式 +game_type 1 +game_mode 1 死亡竞赛 +game_type 1 +game_mode 2 练习模式 +game_type 2 +game_mode 0 自定义模式 +game_type 3 +game_mode 0 例如: 进入炼狱小镇的竞技模式\n在启动服务器时的命令行后添加, 命令行指定可以不重启换模式\n+game_type 0 +game_mode 1 +map de_inferno 在游戏中的控制台执行\n# 进入炼狱小镇的竞技模式 game_type 0;game_mode 1;map de_inferno # 进入炼狱小镇的搭档模式 game_type 0;game_mode 2;map de_inferno 在配置文件中指定, 需要修改配置文件后重启游戏\ngame_type 0 game_mode 1 map de_inferno 所有地图组\rmg_active 服役生涯地图组 mg_armsrace 军备竞赛地图组 mg_bomb 拆除地图组 mg_casualdelta 炸弹拆除地图组 II 号 mg_casualsigma 炸弹拆除地图组 I 号 mg_deathmatch 经典地图组 mg_demolition 爆破地图组 mg_hostage 人质解救地图组 mg_lowgravity 低重力地图组 mg_reserves 后备生涯地图组 mg_skirmish_stabstabzap 戳戳乐 mg_skirmish_flyingscoutsman 跳狙飞人 mg_skirmish_triggerdiscipline 弹无虚发 mg_skirmish_headshots 砰! 爆头! mg_skirmish_huntergatherers 采猎者 mg_skirmish_heavyassaultsuit 重型突击套装 mg_skirmish_armsrace 军备竞赛(战争游戏) mg_skirmish_demolition 爆破模式(战争游戏) // 地图组: 服役生涯地图组, 启动后首张地图 mirage +mapgroup mg_active +map de_mirage 设置防火墙\r打开防火墙端口\nfirewall-cmd --add-port=27015/udp --permanent firewall-cmd --reload 启动 CS:GO 服务器\r启动竞技模式\n[steam@server csgo_server]$ ./srcds_run -debug -game csgo -console -port 27015 -nomaster -insecure -autoupdate -steam_dir /home/steam/ -steamcmd_script /home/steam/update.txt -tickrate 128 +game_type 0 +game_mode 1 +map de_inferno 启动死亡竞技模式\n[steam@server csgo_server]$ ./srcds_run -debug -game csgo -console -port 27015 -nomaster -insecure -autoupdate -steam_dir /home/steam/ -steamcmd_script /home/steam/update.txt -tickrate 128 +game_type 1 +game_mode 2 +map de_inferno -maxplayers_override 20 参数说明\n参数 说明 -debug 开启调试模式 -game 指定游戏, 此处为 CS:GO -console 打开游戏控制台 -insecure 关闭 VAC -port 游戏服务器端口, 默认为 27015 -autoupdate 启用自动更新 -steam_dir Steam 安装目录 -steamcmd_script 执行 SteamCMD 更新脚本的路径 -tickrate 设置服务器 Tickrate, 推荐 128 -maxplayers_override 最大玩家数 (比如设置为 20) -usercon 允许用户控制台直接管理服务器 -nomaster 在社区浏览器中隐藏 -authkey 下载创意工坊地图, 注册 Steam Web API 密钥 +game_type 游戏类型 +game_mode 游戏模式, 命令行指定可以不重启换模式 +map 游戏默认地图 (例如: 炼狱小镇 (de_inferno)) 连接 CS:GO 服务器\rconnect 1.1.1.1 # 一般情况下连接服务器 connect 1.1.1.1:27015 # 带端口号连接 connect 1.1.1.1;password 123456 # 服务器有密码 RCON 管理\rRCON 是 CS:GO 提供的远程控制台命令, 允许管理员远程管理游戏服务器。一般情况下, 建议使用插件 sm_rcon 来管理服务器, 而不是直接使用 CS:GO 的 RCON。要启用 RCON 管理, 需要首先开启防火墙端口\nfirewall-cmd --add-port=27015/tcp --permanent firewall-cmd --reload 管理员可以通过客户端控制台远程管理服务器, 在客户端控制台中输入以下命令就可以顺利的控制游戏了\n注意: RCON 权限有时间限制, 权限可能会在一定时间后失效, 或者在地图更换后需要重新输入密码\n# 输入 RCON 密码 rcon password 51522zzwlwlbb 在需要执行的命令前加上 rcon 前缀即可。例如\n# 重启游戏 rcon mp_restartgame 1 # 启用友军伤害 rcon mp_friendlyfire 1 CS:GO 服务器安装 SourceMod 和 Metamod:Source 插件\rSourceMod 和 Metamod:Source 是 CS:GO 服务器常用的插件框架, 提供强大的扩展功能和管理工具。以下是安装和使用这些插件的详细步骤。\n下载插件\rSourceMOD 下载地址 MetaMod 下载地址 安装步骤\r下载并解压 Metamod 和 SourceMod 文件\n将 Metamod 文件夹放入 SourceMod 文件夹\n将合并后的文件夹上传至服务器的 csgo 目录\n启动 CS:GO 服务器, 输入以下命令验证安装, 检查插件版本\nsm version 命令行安装方法\n在服务器上使用以下命令下载并安装\nwget https://sm.alliedmods.net/smdrop/1.10/sourcemod-1.10.0-git6536-linux.tar.gz wget https://mms.alliedmods.net/mmsdrop/1.11/mmsource-1.11.0-git1145-linux.tar.gz tar -xf sourcemod-1.10.0-git6536-linux.tar.gz -C csgo_server/csgo/ tar -xf mmsource-1.11.0-git1145-linux.tar.gz -C csgo_server/csgo/ 安装完成后, 重启服务器以加载插件\n设置 SourceMod 管理员\r获取 SteamID\r访问 steamid.io 输入你的 Steam 主页 URL, 查询并记录你的 SteamID (如红框部分 STEAM_0:0:11101) 添加管理员\r编辑管理员配置文件\nvim csgo_server/csgo/addons/sourcemod/configs/admins_simple.ini 在文件末尾添加管理员和权限\n\u0026#34;STEAM_0:0:11101\u0026#34; \u0026#34;99:z\u0026#34; 保存文件并重启服务器\n启用管理员菜单\r进入游戏后, 打开控制台并输入以下命令以启用管理员菜单\nsm_admin SourceMod 编译插件\r插件文件类型\n.smx 文件是插件编译完成的二进制文件 .sp 文件是插件源代码文件 # 进入插件编译目录 [steam@server ~]$ cd csgo_server/csgo/addons/sourcemod/scripting/ # 下载插件源代码 kento_giveweapons.sp # 编译 kento_giveweapons.sp 插件 [steam@server scripting]$ ./compile.sh kento_giveweapons.sp Compiling kento_giveweapons.sp... SourcePawn Compiler 1.10.0.6536 Copyright (c) 1997-2006 ITB CompuPhase Copyright (c) 2004-2018 AlliedModders LLC Code size: 5004 bytes Data size: 4120 bytes Stack/heap size: 16384 bytes Total requirements: 25508 bytes # 把编译后的 .smx 移动到 plugins 文件夹 [steam@server scripting]$ mv compiled/kento_giveweapons.smx ../plugins/ 重启服务器后, 插件即可生效\n服务器控制台命令\r武器、装备\r手枪 give weapon_glock 格洛克 18 型 give weapon_hkp2000 P2000 give weapon_usp_silencer USP 消音版 give weapon_elite 双持贝瑞塔 give weapon_p250 P250 give weapon_fiveseven FN57 give weapon_tec9 TEC-9 give weapon_cz75a CZ75 自动手枪 give weapon_deagle 沙漠之鹰 give weapon_revolver R8 左轮手枪 重型武器 give weapon_nova 新星 give weapon_xm1014 XM1014 give weapon_mag7 MGA-7 give weapon_sawedoff 截短霰弹枪 give weapon_m249 M249 give weapon_negev 内格夫 微型冲锋枪 give weapon_mp9 MP9 give weapon_mac10 MAC-10 give weapon_mp7 MP7 give weapon_mp5sd MP5-SD give weapon_ump45 UMP-45 give weapon_p90 P90 give weapon_bizon PP-野牛 步枪 give weapon_galilar 加利尔 AR give weapon_famas 法玛斯 give weapon_ak47 AK-47 give weapon_m4a1 M4A4 give weapon_m4a1_silencer M4A1 消音型 give weapon_sg556 SG 553 give weapon_aug AUG 狙击步枪 give weapon_ssg08 SSG 08 give weapon_awp AWP give weapon_g3sg1 G3SG1 give weapon_scar20 SCAR-20 手雷 / 投掷物 give weapon_molotov 燃烧瓶 give weapon_incgrenade 燃烧弹 give weapon_decoy 诱饵手雷 give weapon_flashbang 闪光震撼弹 give weapon_hegrenade 高爆手雷 give weapon_smokegrenade 烟雾弹 装备 give item_kevlar 防弹背心 give item_assaultsuit 防弹背心+头盔 give weapon_taser 宙斯 X27 电击枪 give item_defuser 拆弹器 give item_cutters 营救工具包 头号特训道具 give weapon_healthshot 医疗针 give weapon_breachcharge 遥控 C4 give item_cash 钱 (50金) give weapon_tablet 特训助手 give weapon_bumpmine 弹射地雷 give weapon_shield 防爆盾 Exo 跳跃: exojump 降落伞: give parachute 锤子: give weapon_hammer;ent_fire weapon_melee addoutput \u0026#34;classname weapon_knifegg 斧头: give weapon_axe;ent_fire weapon_melee addoutput \u0026#34;classname weapon_knifegg 扳手: give weapon_spanner;ent_fire weapon_melee addoutput \u0026#34;classname weapon_knifegg 徒手/拳头: give weapon_fists; ent_fire weapon_fists addoutput \u0026#34;classname weapon_knifegg 自动哨兵: give dronegun 其他 give weapon_tagrenade 战术探测手雷 give weapon_snowball 雪球 夜视仪: give item_nvgs; nightvision (再输入 nightvision 关闭) 重型突击套装: mp_weapons_allow_heavyassaultsuit 1;give item_heavyassaultsuit 排斥装置: give weapon_zone_repulsor 鸡: give chicken C4: give weapon_c4 地图代码\rdz_vineyard // 葡萄园 dz_sirocco // 西罗科 dz_ember // 余烬战场 dz_blacksite // 黑色禁区 # 炸弹拆除地图 de_vertigo // 摩天大楼/殒命大厦 de_train // 列车停放站 de_sugarcane // 蔗糖工厂 de_stmarc // 圣马克镇 de_shortnuke // 短核基地 de_shortdust // 短沙城 de_safehouse // 安全处所 de_overpass // 下水道/死亡游乐园 de_nuke // 导弹基地 de_mirage // 沙漠迷城 de_lake // 湖畔激战 de_iris // 彩虹岛 de_inferno // 炼狱小镇 de_hive // 蜂巢基地 de_dust2 // 炙热沙城2 de_crete // 克里特岛 de_cbble // 遗迹堡垒 de_canals // 运河水城 de_cache // 死城之谜 de_bank // 金库危机 de_ancient // 古迹废墟 # 人质解救地图 cs_office // 办公室 cs_militia // 民兵基地 cs_italy // 意大利小镇 cs_climb // 攀岩基地 cs_assault // 突击仓库 cs_agency // 特工总部 # 军备竞赛地图 ar_shoots // 山林小寨 ar_monastery // 修道院 ar_lunacy // 疯狂基地 ar_dizzy // 眩晕大厦 ar_baggage // 行李仓库 常用指令\r# 设置热身时间为 99999 秒 # 开始热身阶段 mp_warmuptime 99999;mp_warmup_start; # 结束热身阶段 mp_warmup_end # 开启派对模式 (例如, 所有玩家友善) # 设置冻结时间为 0 (即回合开始时不冻结) # 设置解救人质模式的回合时间为 60 秒 # 重启游戏 # 结束热身阶段 sv_party_mode 1;mp_freezetime 0;mp_roundtime_hostage 60;mp_restartgame 1;mp_warmup_end; # 启用连跳 (bunny hop) # 启用自动连跳 # 设置空中加速为最大值 # 跳跃消耗的耐力为 0 # 着陆消耗的耐力为 0 # 设置耐力上限为 0 (无耐力限制) # 设置耐力恢复速率为 0 # 不使用武器速度来加速 # 设置最大速度为 9999 sv_enablebunnyhopping 1;sv_autobunnyhopping 1;sv_airaccelerate 999;sv_staminajumpcost 0;sv_staminalandcost 0;sv_staminamax 0;sv_staminarecoveryrate 0;sv_accelerate_use_weapon_speed 0;sv_maxvelocity 9999; # 禁止队友互伤 # 设置每回合时间为 15 秒 # 重启游戏 # 结束热身阶段 mp_teammates_are_enemies 0;mp_roundtime 15;mp_restartgame 1;mp_warmup_end; # 添加 6 个机器人 bot_add;bot_add;bot_add;bot_add;bot_add;bot_add; 跑图服务器配置\r修改 gamemodes_server.txt\r在配置文件中, 将 casual 模式下的 exec 配置修改为 paotu.cfg\n///////////////////////////////////////// // CASUAL ///////////////////////////////////////// \u0026#34;casual\u0026#34;{ \u0026#34;maxplayers\u0026#34;\t\u0026#34;30\u0026#34; \u0026#34;exec\u0026#34; { \u0026#34;exec\u0026#34;\t\u0026#34;paotu.cfg\u0026#34; } \u0026#34;mapgroupsMP\u0026#34;\t// List of mapgroups valid for this game mode ( casual ) { \u0026#34;mg_bomb_se\u0026#34;\t\u0026#34;\u0026#34; } 创建跑图服务器配置\r创建并编辑 paotu.cfg 文件, 设置跑图服务器的具体参数\nvim csgo_server/csgo/cfg/paotu.cfg 内容如下\nsv_cheats 1 // 允许作弊 ammo_grenade_limit_total 6 // 玩家可携带的总手雷数量上限 (包括所有类型的手雷) ammo_grenade_limit_breachcharge 2 // 玩家可携带的破门炸药 (Breach Charge) 数量上限 ammo_grenade_limit_bumpmine 2 // 玩家可携带的弹跳地雷 (Bump Mine) 数量上限 ammo_grenade_limit_default 6 // 玩家可携带的默认手雷 (如高爆手雷、燃烧弹等) 数量上限 ammo_grenade_limit_flashbang 2 // 玩家可携带的闪光弹 (Flashbang) 数量上限 ammo_grenade_limit_snowballs 10 // 玩家可携带的雪球 (Snowball) 数量上限 (冬季活动专用) mp_afterroundmoney 65535 // 每回合结束后增加的金额 mp_maxmoney 65535 // 最大金额 mp_startmoney 65535 // 初始金额 mp_autoteambalance 0 // 关闭自动进行人数平衡 mp_buytime 99999 // 购买时间 mp_buy_anywhere 1 // 允许在任何地方购买 mp_weapons_allow_typecount -1 // 同一种武器可以购买更多数量 mp_death_drop_defuser 1 // 玩家死后不掉落拆弹器 mp_death_drop_grenade 1 // 玩家死后不掉落手雷 mp_death_drop_gun 1 // 玩家死后不掉落枪支 mp_spectators_max 9 // 允许最多有 9 个观察者 mp_forcecamera 0 // 不限制观察者所观看的队伍 mp_free_armor 0 // 免费给予防弹衣和头盔 (1=防弹衣, 2=防弹衣和头盔) mp_warmuptime 0 // 热身时间为 0 秒 mp_freezetime 0 // 冻结时间 mp_respawn_immunitytime 0 // 重生保护时间设置为 0 mp_friendlyfire 1 // 开启友伤 mp_ignore_round_win_conditions 1 // 忽略胜利条件 mp_limitteams 0 // 不限制队伍 mp_respawn_on_death_ct 1 // 反恐精英死后即刻复活 mp_respawn_on_death_t 1 // 恐怖分子死后即刻复活 mp_roundtime 60.00 // 每回合时间 mp_roundtime_hostage 60.00 // 解救人质地图每回合时间 mp_roundtime_defuse 60.00 // 拆除炸弹地图每回合时间 mp_teammates_are_enemies 1 // 任何人都为目标 sv_enablebunnyhopping 1 // 允许连跳 //sv_autobunnyhopping 1 // 开启自动连跳 sv_grenade_trajectory 1 // 显示投掷物轨迹 (丢出显示轨迹) sv_grenade_trajectory_dash 1 // 手雷抛物线的形状 sv_grenade_trajectory_thickness 1 // 手雷抛物线的厚度 sv_grenade_trajectory_time 20 // 手雷抛物线的显示时间 sv_infinite_ammo 2 // 无限备用弹夹 cl_grenadepreview 1 // 显示投掷物轨迹 (拿着投掷物按住显示轨迹, 平时自己练习投掷物必备) sv_showimpacts 1 // 显示弹道 (红色为客户端, 蓝色为服务器) sv_showimpacts_time 20 // 弹道的显示时间 // bot_stop 1 // BOT 为静止状态 bot_dont_shoot 1 // 禁止 bot 开枪射击 mp_c4timer 99999 // C4 引爆时间 安装 NadeTails 插件\rNadeTails 插件用于显示所有玩家的投掷物轨迹\n编辑配置文件 plugin.NadeTails.cfg\nvim csgo_server/csgo/cfg/sourcemod/plugin.NadeTails.cfg 内容如下\n// This file was auto-generated by SourceMod (v1.10.0.6536) // ConVars for plugin \u0026#34;NadeTails.smx\u0026#34; // Allow players to use nade tails with !tails (0/1) // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_allowplayers \u0026#34;1\u0026#34; // Enables Nade Tails on Decoy Grenades (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_decoy \u0026#34;1\u0026#34; // Tail color on Decoy Grenades. (use named colors like \u0026#34;Aqua\u0026#34; or \u0026#34;Black\u0026#34; or use RGBA like \u0026#34;255 20,147 225\u0026#34; // - // Default: \u0026#34;random\u0026#34; sm_tails_decoycolor \u0026#34;Lime\u0026#34; // Default alpha for trails (0 is invisible, 255 is solid). // - // Default: \u0026#34;255\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;255.000000\u0026#34; sm_tails_defaultalpha \u0026#34;255\u0026#34; // Tails on for all users, Set to 0 to require user to type !tails to use // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_defaulton \u0026#34;1\u0026#34; // 启用 NadeTails (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_enabled \u0026#34;1\u0026#34; // 启用闪光弹轨迹 (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_flashbang \u0026#34;1\u0026#34; // 闪光弹轨迹颜色 (use named colors like \u0026#34;Aqua\u0026#34; or \u0026#34;Black\u0026#34; or use RGBA like \u0026#34;255 20 147 225\u0026#34; // - // Default: \u0026#34;random\u0026#34; sm_tails_flashcolor \u0026#34;Red\u0026#34; // HE 手雷轨迹颜色 (use named colors like \u0026#34;Aqua\u0026#34; or \u0026#34;Black\u0026#34; or use RGBA like \u0026#34;255 20 147 225\u0026#34; // - // Default: \u0026#34;random\u0026#34; sm_tails_hecolor \u0026#34;Purple\u0026#34; // 启用 HE 手雷轨迹 (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_hegrenade \u0026#34;1\u0026#34; // 燃烧弹轨迹颜色 (use named colors like \u0026#34;Aqua\u0026#34; or \u0026#34;Black\u0026#34; or use RGBA like \u0026#34;255 20 147 225\u0026#34; // - // Default: \u0026#34;random\u0026#34; sm_tails_inccolor \u0026#34;Green\u0026#34; // 启用燃烧弹轨迹 (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_incendiary \u0026#34;1\u0026#34; // 启用燃烧瓶轨迹 (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_molotov \u0026#34;1\u0026#34; // 燃烧瓶轨迹颜色 (use named colors like \u0026#34;Aqua\u0026#34; or \u0026#34;Black\u0026#34; or use RGBA like \u0026#34;255 20 147 225\u0026#34; // - // Default: \u0026#34;random\u0026#34; sm_tails_molotovcolor \u0026#34;Green\u0026#34; // 启用烟雾弹轨迹 (0/1). // - // Default: \u0026#34;1\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;1.000000\u0026#34; sm_tails_smoke \u0026#34;1\u0026#34; // 烟雾弹轨迹颜色 (use named colors like \u0026#34;Aqua\u0026#34; or \u0026#34;Black\u0026#34; or use RGBA like \u0026#34;255 20 147 225\u0026#34; // - // Default: \u0026#34;random\u0026#34; sm_tails_smokecolor \u0026#34;Yellow\u0026#34; // Time for tail to fade over. // - // Default: \u0026#34;1\u0026#34; sm_tails_tailfadetime \u0026#34;0\u0026#34; // 轨迹显示时间 // - // Default: \u0026#34;20.0\u0026#34; // Minimum: \u0026#34;0.000000\u0026#34; // Maximum: \u0026#34;25.000000\u0026#34; sm_tails_tailtime \u0026#34;20.0\u0026#34; // 轨迹宽度 // - // Default: \u0026#34;1.0\u0026#34; sm_tails_tailwidth \u0026#34;1.0\u0026#34; 完成配置后, 重启服务器即可生效\n一键跳投\r将以下跳投配置保存为 t.cfg 文件, 并放入游戏目录下的 Counter-Strike Global Offensive\\csgo\\cfg 文件夹中\nalias +jumpthrow +jump;-attack alias -jumpthrow -jump bind c +jumpthrow 按键绑定为 C, 用于执行跳投操作\n每次启动游戏后, 需要在控制台输入以下命令加载配置\nexec t exec t.cfg 或者在游戏属性启动参数中加入, 每次启动后会自动执行, 无需手动执行\n+exec t 按键绑定\r按键代码 对应按键 mouse1 鼠标左键 mouse2 鼠标右键 mouse3 鼠标中键 (滚轮按下去) mouse4 鼠标侧键 mouse5 鼠标侧键 mwheelup 滚轮向上 mwheeldown 滚轮向下 a-z 字母键 0-9 数字键 f1-f12 功能键 tab Tab enter 回车键 escape ESC space 空格踺 backspace 回车键 uparrow ↑方向键 downarrow ↓方向键 leftarrow ←方向键 rightarrow →方向键 alt ALT ctrl CTRL shift SHIFT ins INS del . pgup PGUP pgdn PGDN home HOME end END capslock 大小写锁定 pause 暂停键 joy1-4 手柄按键 auxl-31 手柄按键 NUMLOCK 数锁 (小踺盘) kp_slash / (小键盘) kp_multiply * (小键盘) kp_minus - (小键盘) kp_plus + (小键盘) kp_del . (小键盘) kp_enter 回车 (小键盘) kp_ins 0 (小键盘) kp_end 1 (小键盘) kp_downarrow 2 (小键盘) kp_pgdn 3 (小键盘) kp_leftarrow 4 (小键盘) kp_5 5 (小键盘) kp_rightarrow 6 (小键盘) kp_home 7 (小键盘) kp_uparrow 8 (小键盘) kp_pgup 9 (小键盘) //=====================================================// // Num | / | * | - // // Lock | DECOY | SMOKE | FLASH // //-------------|-------------|-------------|-----------// // 7 | 8 | 9 | + // // SCOUT | AWP | AUTO SNIPER | NADES // //-------------|-------------|-------------| HE // // 4 | 5 | 6 | INCEND // // FAMAS/GALIL | M4A1/AK | AUG/SG556 | MOLOTOV // //-------------|-------------|-------------|-----------// // 1 | 2 | 3 | Enter // // SHOTGUN | AUTO SHOTGN | MP7 | ARMOR // //-------------|-------------|-------------| DEFUSE // // 0 | . | RESCUE // // DEAGLE | P90 | KIT // //=====================================================// // Aliases (Abbreviations for weapon combinations) alias \u0026#34;m4a1/ak47\u0026#34; \u0026#34;buy m4a1;buy ak47\u0026#34; alias \u0026#34;aug/sg556\u0026#34; \u0026#34;buy aug;buy sg556\u0026#34; alias \u0026#34;galilar/famas\u0026#34; \u0026#34;buy galilar;buy famas\u0026#34; alias \u0026#34;g3sg1/scar20\u0026#34; \u0026#34;buy g3sg1;buy scar20\u0026#34; alias \u0026#34;vesthelm/vest\u0026#34; \u0026#34;buy vesthelm;buy vest\u0026#34; alias \u0026#34;incgrenade/molotov\u0026#34; \u0026#34;buy incgrenade;buy molotov\u0026#34; // Key bindings (Aliases are used here) bind \u0026#34;KP_HOME\u0026#34; \u0026#34;buy ssg08; vesthelm/vest\u0026#34; bind \u0026#34;KP_UPARROW\u0026#34; \u0026#34;buy awp; vesthelm/vest\u0026#34; bind \u0026#34;KP_PGUP\u0026#34; \u0026#34;g3sg1/scar20; vesthelm/vest\u0026#34; bind \u0026#34;KP_LEFTARROW\u0026#34; \u0026#34;galilar/famas; vesthelm/vest\u0026#34; bind \u0026#34;KP_5\u0026#34; \u0026#34;m4a1/ak47; vesthelm/vest\u0026#34; bind \u0026#34;KP_RIGHTARROW\u0026#34; \u0026#34;aug/sg556; vesthelm/vest\u0026#34; bind \u0026#34;KP_END\u0026#34; \u0026#34;buy nova; vesthelm/vest\u0026#34; bind \u0026#34;KP_DOWNARROW\u0026#34; \u0026#34;buy xm1014; vesthelm/vest\u0026#34; bind \u0026#34;KP_PGDN\u0026#34; \u0026#34;buy mp7; vesthelm/vest\u0026#34; bind \u0026#34;KP_INS\u0026#34; \u0026#34;buy deagle\u0026#34; bind \u0026#34;KP_DEL\u0026#34; \u0026#34;buy p90; vesthelm/vest\u0026#34; bind \u0026#34;KP_SLASH\u0026#34; \u0026#34;buy decoy\u0026#34; bind \u0026#34;KP_MULTIPLY\u0026#34; \u0026#34;buy smokegrenade\u0026#34; bind \u0026#34;KP_MINUS\u0026#34; \u0026#34;buy flashbang\u0026#34; bind \u0026#34;KP_PLUS\u0026#34; \u0026#34;buy hegrenade; incgrenade/molotov\u0026#34; bind \u0026#34;KP_ENTER\u0026#34; \u0026#34;vesthelm/vest; buy defuser\u0026#34; 原文\nInstalling SteamCMD on CentOS 7\n[服务器]搭建CSGO服务器\nCSGO Server Command Line Options\nCS:GO NUMPAD Keys Binded to Buy Scripts\n","date":"2022-04-10T11:26:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-deploy-csgo-server/","title":"Centos 7 搭建 CS:GO 服务器"},{"content":"在日常使用中, 常见的压缩格式如 rar、zip、tar 和 7z 以 仅存档 模式保存文件。这些文件在使用时需要先解压才能访问。而将文件打包成 ISO 镜像后, 可以直接挂载使用, 无需解压, 从而节省了解压时间和硬盘空间。\n制作 ISO 镜像的工具\r制作 ISO 镜像时, 可能会接触到两个工具名称: mkisofs 和 genisoimage\n实际上, 最初 Linux 系统使用的是 cdrtools 工具套件来管理 ISO 和光盘, 其中 mkisofs 是 cdrtools 的一个组件。后来, 由于 cdrtools 将授权许可从 GPL 修改为 CDDL, 开源社区又推出了基于 GPL 的工具套件 cdrkit, 其中 genisoimage 替代了 mkisofs。目前大多数系统中的 mkisofs 实际上是 genisoimage 的软链接\n以下是验证过程的示例\n[root@server ~]# whereis mkisofs mkisofs: /usr/bin/mkisofs /usr/share/man/man1/mkisofs.1.gz [root@server ~]# ls -l /usr/bin/mkisofs lrwxrwxrwx. 1 root root 25 Mar 29 05:32 /usr/bin/mkisofs -\u0026gt; /etc/alternatives/mkisofs [root@server ~]# ls -l /etc/alternatives/mkisofs lrwxrwxrwx. 1 root root 20 Mar 29 05:32 /etc/alternatives/mkisofs -\u0026gt; /usr/bin/genisoimage [root@server ~]# whereis genisoimage genisoimage: /usr/bin/genisoimage /usr/share/man/man1/genisoimage.1.gz [root@server ~]# ls -l /usr/bin/genisoimage -rwxr-xr-x. 1 root root 521240 Oct 31 2018 /usr/bin/genisoimage 安装工具\r在基于 CentOS 的系统中, 可以通过以下命令安装 genisoimage\nyum install genisoimage -y 制作 ISO 镜像\r使用 genisoimage 制作镜像时, 通常需要添加 -lJR 参数。如果未添加这些参数, 文件名可能会被裁剪并转为全大写格式, 以符合 ISO-9660 标准。例如\ngenisoimage -lJR -o output_image.iso directory_name 常用参数说明\n参数 说明 -l 允许完整的 31 个字符文件名 -J 生成 Joliet 目录记录, 支持长文件名 -R 使用 Rock Ridge 协议生成共享协议和扩展记录 -allow-multidot 允许文件名中包含多个 . -o 指定输出文件名 使用 7z 解压 ISO 镜像\r使用 7z 查看 ISO 文件内容\n7z l acesheep.iso 通过 7z 解压镜像文件, 并设置解压位置\n7z x acesheep.iso -oAceSheep-Folder 完整帮助\r手册页: mkisofs\n手册页备份: mkisofs.8.html.zip\n[root@server ~]# genisoimage --help Usage: genisoimage [options] file... Options: -nobak Do not include backup files -no-bak Do not include backup files -abstract FILE Set Abstract filename -A ID, -appid ID Set Application ID -biblio FILE Set Bibliographic filename -cache-inodes Cache inodes (needed to detect hard links) -no-cache-inodes Do not cache inodes (if filesystem has no unique unides) -check-oldnames Check all imported ISO9660 names from old session -check-session FILE Check all ISO9660 names from previous session -copyright FILE Set Copyright filename -debug Set debug flag -b FILE, -eltorito-boot FILE Set El Torito boot image name -e FILE, -efi-boot FILE Set EFI boot image name -eltorito-alt-boot Start specifying alternative El Torito boot parameters -B FILES, -sparc-boot FILES Set sparc boot image names -sunx86-boot FILES Set sunx86 boot image names -G FILE, -generic-boot FILE Set generic boot image name -jigdo-template-compress ALGORITHM Choose to use gzip or bzip2 compression for template data; default is gzip -checksum_algorithm_iso alg1,alg2,... Specify the checksum types desired for the output image -checksum_algorithm_template alg1,alg2,... Specify the checksum types desired for the output jigdo template -sort FILE Sort file content locations according to rules in FILE -split-output Split output into files of approx. 1GB size -stream-file-name FILE_NAME Set the stream file ISO9660 name (incl. version) -stream-media-size # Set the size of your CD media in sectors -sysid ID Set System ID -T, -translation-table Generate translation tables for systems that don\u0026#39;t understand long filenames -table-name TABLE_NAME Translation table file name -ucs-level LEVEL Set Joliet UCS level (1..3) -udf Generate UDF file system -dvd-video Generate DVD-Video compliant UDF file system -uid uid Make the owner of all files this uid. -U, -untranslated-filenames Allow Untranslated filenames (for HPUX \u0026amp; AIX - violates ISO9660). Forces -l, -d, -N, -allow-leading-dots, -relaxed-filenames, -allow-lowercase, -allow-multidot -relaxed-filenames Allow 7 bit ASCII except lower case characters (violates ISO9660) -no-iso-translate Do not translate illegal ISO characters \u0026#39;~\u0026#39;, \u0026#39;-\u0026#39; and \u0026#39;#\u0026#39; (violates ISO9660) -allow-lowercase Allow lower case characters in addition to the current character set (violates ISO9660) -allow-multidot Allow more than one dot in filenames (e.g. .tar.gz) (violates ISO9660) -use-fileversion LEVEL Use file version # from filesystem -v, -verbose Verbose -version Print the current version -V ID, -volid ID Set Volume ID -volset ID Set Volume set ID -volset-size # Set Volume set size -volset-seqno # Set Volume set sequence number -x FILE, -old-exclude FILE Exclude file name(depreciated) -hard-disk-boot Boot image is a hard disk image -no-emul-boot Boot image is \u0026#39;no emulation\u0026#39; image -no-boot Boot image is not bootable -boot-load-seg # Set load segment for boot image -boot-load-size # Set numbers of load sectors -boot-info-table Patch boot image with info table -XA Generate XA directory attruibutes -xa Generate rationalized XA directory attruibutes -z, -transparent-compression Enable transparent compression of files -hfs-type TYPE Set HFS default TYPE -hfs-creator CREATOR Set HFS default CREATOR -g, -apple Add Apple ISO9660 extensions -h, -hfs Create ISO9660/HFS hybrid -map MAPPING_FILE Map file extensions to HFS TYPE/CREATOR -H MAPPING_FILE, -map MAPPING_FILE Map file extensions to HFS TYPE/CREATOR -magic FILE Magic file for HFS TYPE/CREATOR -probe Probe all files for Apple/Unix file types -mac-name Use Macintosh name for ISO9660/Joliet/RockRidge file name -no-mac-files Do not look for Unix/Mac files (depreciated) -boot-hfs-file FILE Set HFS boot image name -part Generate HFS partition table -cluster-size SIZE Cluster size for PC Exchange Macintosh files -auto FILE Set HFS AutoStart file name -no-desktop Do not create the HFS (empty) Desktop files -hide-hfs GLOBFILE Hide HFS file -hide-hfs-list FILE List of HFS files to hide -hfs-volid HFS_VOLID Volume name for the HFS partition -icon-position Keep HFS icon position -root-info FILE finderinfo for root folder -input-hfs-charset CHARSET Local input charset for HFS file name conversion -output-hfs-charset CHARSET Output charset for HFS file name conversion -hfs-unlock Leave HFS Volume unlocked -hfs-bless FOLDER_NAME Name of Folder to be blessed -hfs-parms PARAMETERS Comma separated list of HFS parameters -prep-boot FILE PReP boot image file -- up to 4 are allowed -chrp-boot Add CHRP boot header --cap Look for AUFS CAP Macintosh files --netatalk Look for NETATALK Macintosh files --double Look for AppleDouble Macintosh files --ethershare Look for Helios EtherShare Macintosh files --exchange Look for PC Exchange Macintosh files --sgi Look for SGI Macintosh files --macbin Look for MacBinary Macintosh files --single Look for AppleSingle Macintosh files --ushare Look for IPT UShare Macintosh files --xinet Look for XINET Macintosh files --dave Look for DAVE Macintosh files --sfm Look for SFM Macintosh files --osx-double Look for MacOS X AppleDouble Macintosh files --osx-hfs Look for MacOS X HFS Macintosh files Report problems to debburn-devel@lists.alioth.debian.org. 原文\nCreate iso image from folder via terminal commands\n制作CentOS7的ISO镜像\n","date":"2022-03-30T11:04:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-make-iso-file/","title":"Centos 7 制作 ISO 镜像文件"},{"content":"在 Windows 10 中, 有一些快捷键可以显著提高工作效率, 特别是对于高级用户和桌面专业人士。以下是 10 个你可能不知道的有用快捷键\n在 Alt+Tab 中关闭窗口\r大多数用户都知道 Alt+Tab 快捷键, 但我觉得很少有人知道你可以通过按 Delete 键 来关闭当前在 Alt+Tab 窗口中突出显示的窗口。这样, 你无需移动鼠标即可快速关闭程序\n让任何 Windows Store app (UWP) 全屏显示\r在任何 Windows Store app (UWP) 中, 选中窗口时按 Win+Shift+Enter 即可进入全屏模式。这几乎适用于所有 UWP 应用, 除非开发人员专门禁用了此快捷键。虽然它不是很有用, 但全屏 \u0026ldquo;计算器\u0026rdquo; 或 \u0026ldquo;闹钟\u0026rdquo; 只是一个快捷键的事情\n在 Windows Store app (UWP) 中 \u0026ldquo;返回\u0026rdquo;\r仅适用于 Windows Store app (UWP) 的一个快捷键。如果你使用的 Windows Store 应用 (UWP) 在标题栏中有全局 \u0026ldquo;返回\u0026rdquo; 按钮, 可以随时按 Win+Backspace 返回上一个界面。可以在内置的 \u0026ldquo;设置\u0026rdquo; 或 \u0026ldquo;照片\u0026rdquo; 应用中试试这个快捷键。\n以管理员权限启动程序\r通过按住 Ctrl+Shift 并单击应用图标, 你可以快速以管理员身份启动程序。这适用于开始菜单的快捷方式和固定在任务栏上的图标, 比右键单击并选择 \u0026ldquo;以管理员身份运行\u0026rdquo; 要快得多\n关闭虚拟桌面\r你可以使用 Win+Ctrl+Left 或 Win+Ctrl+Right 在虚拟桌面之间切换。要关闭当前桌面, 使用 Win+Ctrl+F4, 打开的程序将移至上一个桌面。使用 Win+Ctrl+D 可以创建新的虚拟桌面\n打开资源管理器中属性菜单\r使用 Alt+Space 可以打开当前资源管理器窗口的属性菜单, 包含最小化、最大化、移动或关闭窗口的选项。菜单中的选项可以通过带下划线的字母快速访问。例如, 最大化使用 Alt+Space x, 还原窗口使用 Alt+Space r\n逐单词而不是逐字母选择文本\r注意: 这个功能仅适用于包含空格的文本\n使用方向键, 你可以在文本中的字母之间移动。如果按住 Ctrl 键, 可以让光标按单词移动。这对于纠正错误时可以更快地到达当前单词的开头或结尾。它还可以与 Shift 键一起使用来选择文本, 按住 Ctrl+Shift+方向键 可以一次选择整个单词\n快速启动固定到任务栏的程序 (new instance)\r你可以使用 Win+Shift+1 启动任务栏上固定在第一位的程序新实例, 而不是切换到该程序。数字 1 代表任务栏上程序的位置 (从左到右排序)。这适用于固定到任务栏的前 10 个程序, 对于其他位置的程序, 使用 Win+Shift+2、Win+Shift+3 等等\n如果要以管理员身份启动程序, 可以使用 Win+Ctrl+Shift+1 (详见上文)。使用 Win+1 切换到程序的现有窗口\n快速复制错误对话框详细信息\r这个快捷键在特殊情况下非常有用。如果你遇到一个错误对话框并需要查看详细信息, 通常你可能会将描述手动输入到 Google 中搜索。使用 Ctrl+C, Windows 会自动将错误描述整齐地复制到剪贴板。这样, 你无需手动输入, 节省了大量时间。你可以将其粘贴到文件中保存, 或者直接用于搜索, 方便日后参考。\n重启显卡驱动程序\r如果你遇到显示器或显卡问题, 可以按 Ctrl+Shift+Win+B 强制 Windows 重新启动图形驱动程序, 这可能会修复任何显示问题, 而无需重新启动计算机\n原文\n10 helpful Windows 10 hotkeys you might not know about\nWhat does CTRL+WIN+SHIFT+B do in Windows?\n","date":"2022-03-16T19:43:00+08:00","permalink":"https://blog.acesheep.com/p/10-helpful-windows-10-hotkeys-you-might-not-know-about/","title":"你可能不知道的 10 个超有用的 Windows 10 快捷键"},{"content":"Google Chrome (谷歌浏览器) 是由谷歌公司开发的一款网页浏览器, 以其稳定性、速度和安全性成为全球使用最广泛的浏览器之一。\n不过, 从 Chrome 官网下载时, 通常只会得到在线安装程序 (需要联网下载安装), 而且不提供历史版本, 这对部分用户来说并不方便。\n那么, 如何下载各版本的 Chrome 离线安装包呢？\nChrome 离线安装包下载链接\r最新版本通道\n稳定版 (Stable)\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\n测试版 (Beta)\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\u0026amp;extra=betachannel\n开发版 (Dev)\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\u0026amp;extra=devchannel\n金丝雀版 (Canary)\n无直接离线安装包, 需通过 Chrome Canary 官网 下载\n指定操作系统版本\rWindows 64 位\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\u0026amp;platform=win64 Windows 32 位\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\u0026amp;platform=win Mac\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\u0026amp;platform=mac Linux\nhttps://www.google.com/intl/zh-CN/chrome/browser/?standalone=1\u0026amp;platform=linux URL 参数说明\rChrome 离线安装包 URL 参数说明\nstandalone=1 # 下载最新的完整离线安装包 platform=win64 # Windows 64 位 platform=win # Windows 32 位 platform=mac # macOS platform=linux # Linux extra=stablechannel # 稳定版 extra=betachannel # 测试版 extra=devchannel # 开发版 extra=canarychannel # 金丝雀版 installdataindex=defaultbrowser # 安装后设置为默认浏览器 installdataindex=empty # 不设置为默认浏览器 Chrome 版本分支介绍\rGoogle Chrome 共分为四个版本通道:\nStable Channel (稳定版)\n面向普通用户 版本稳定, 更新较慢 适合追求稳定的用户 Beta Channel (测试版)\n新功能的公开测试阶段 安全性测试为主, 较少改动 稳定性比开发版好, 适合喜欢尝鲜的用户 Dev Channel (开发版)\n功能性测试为主 更新频率通常为一周一次 可能存在较多 bug, 主要供开发人员使用 Canary Build (金丝雀版)\n于 2010 年 7 月加入 Chrome 分支 更新最快 (每天更新) 稳定性最低, 实验性功能最多 可独立安装, 不会覆盖已有的 Chrome 稳定版, 统中可同时存在两套 Chrome 主要面向开发人员 XP 系统最终版下载\rGoogle Chrome 49.0.2623.112 XP 系统最终版下载\n从 Chrome 50 版本开始, 谷歌已停止对 Windows XP 系统 的支持, 因此 49.0.2623.112 成为 XP 系统最后一个可用的官方版本, XP 用户如需继续使用 Chrome, 只能下载并安装 49 版本或更低版本。\nGoogle Chrome 38.0.2125.122 Google Chrome 47.0.2526.80 (64bit) Google Chrome 49.0.2623.112 ","date":"2022-03-14T19:47:00+08:00","permalink":"https://blog.acesheep.com/p/how-to-download-chrome-offline-installer/","title":"如何下载 Chrome 离线安装包"},{"content":"代码签名证书 (Code Signing Certificate) 是为软件开发者提供的一种数字证书, 用于对二进制文件、VB 脚本等进行数字签名。它的主要作用是验证开发者的身份真实性, 并保护代码的完整性。用户在下载软件时, 能够通过数字签名验证软件来源是否可信, 并确认软件没有被非法篡改。\n代码签名证书类型\r代码签名证书分为两种类型: OV (Organization Validation) 和 EV (Extended Validation)\nEV 证书: 仅限企业购买, 私钥存储在USB 密钥中, 支持驱动程序签名。EV 证书的优势是, Microsoft SmartScreen 会直接信任使用 EV 签名的软件 OV 证书: 个人也可以申请, 私钥可以存储为文件, 但不支持驱动程序签名。使用 OV 证书的软件会通过累计下载数量逐渐获得 Microsoft SmartScreen 的信任 软件信誉与杀毒软件\r证书主要用于身份识别, 各家杀毒软件有自己的数据库和病毒算法, 因此, 证书并不能成为免杀的 \u0026ldquo;金牌\u0026rdquo;。目前流行的安装方式是在线安装, 在这种情况下, 在线安装的 EXE 文件哈希值 (hash) 通常是固定不变的。再通过这个 EXE 下载安装程序, 可以绕过浏览器和 Microsoft SmartScreen 的拦截。\n注意: Microsoft SmartScreen 与杀毒软件无关, 它只是用于检测下载的软件是否为可信的\n没有证书的软件通常依赖于软件的 hash 值来积累信誉, 缺点是这种信誉会随着软件更新而改变, 因为更新后的 hash 值不同需要重新累计信誉 有证书签名的软件, 其信誉是累计在证书上的, 即使更新软件 hash 变动后任然可信 不同的杀毒软件有自己的数据库和病毒检测算法, 因此它们的信任标准不同。例如\n360 毒瘤: 360 会在自己的数据库中通过 hash 值判断软件是否在白名单中 (交保护费), 如果不在白名单中, 就会报毒 卡巴斯基: 通过证书信誉来判断软件是否可信, 某些未签名但使用人数多的软件也会被卡巴斯基信任 以卡巴斯基为例, 以下两个软件都没有签名\nffmpeg.exe 虽然没有签名, 但因使用人数众多, 已经达到了卡巴斯基的信任门槛, 因此被认为是可信的\nJiJiDownForWPF.exe 没没有签名且发布时间较短, 用户数量少, 因此未能获得杀毒软件的信任\n当没有进行混淆加密时, 未签名的程序通常不会被报毒。以下两个软件在开启混淆加密和加壳后进行签名\naria2c.exe 使用人数较少, 而且使用 UPX 压缩。对其进行签名后, 卡巴斯基则显示为信任\nN2NGUILauncher.exe 进行了混淆拉满、字符串加密、NecroBit 和防反汇编开启, 对其进行签名后卡巴斯基信任了, 而微软和 360 仍然会报毒。更新后的 360 版本不再报毒, 而旧版 360 则会报毒。\n总的来说, OV 签名并不会直接绕过所有杀毒软件的检测, 具体结果还要根据各家杀毒软件的数据库。它的好处在于, 一旦证书被杀毒软件信任, 后续软件更新就不再容易被误报\n购买代码签名证书\rComodo Code Signing Certificates 这家的代码签名证书是目前最便宜的。证书链由 Sectigo 提供, Sectigo 是 Comodo CA 的新名称\nSectigo (AAA) └──Sectigo Public Code Signing Root R46 └──Sectigo Public Code Signing CA R36 └── 证书名字 你可以使用 OpenSSL 手动生成 ECC 的代码签名 CSR 文件, 具体步骤可参考 使用 OpenSSL 手动生成 CSR 文件\n签名工具\r你可以使用 signtool.exe 进行代码签名。常用的签名方式包括\nSHA1 签名 (已淘汰, 如果需要支持 Windows 7 以下版本的系统, 程序需要 sha1 签名)\n\u0026#34;C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce\\SignTool\\signtool.exe\u0026#34; sign /t http://timestamp.comodoca.com/authenticode file.exe SHA256 签名 (2022 年当前推荐方式)\n\u0026#34;C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce\\SignTool\\signtool.exe\u0026#34; sign /tr http://timestamp.sectigo.com?td=sha256 /td sha256 /fd sha256 /as file.exe SHA384 签名\n\u0026#34;C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce\\SignTool\\signtool.exe\u0026#34; sign /tr http://timestamp.sectigo.com?td=sha384 /td sha384 /fd sha384 /as file.exe SHA1 和 SHA256 双签名\r只需要先执行 SHA1 签名, 然后再执行 SHA256 签名, 就实现双重签名了\n# 先 SHA1 签名 \u0026#34;C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce\\SignTool\\signtool.exe\u0026#34; sign /t http://timestamp.comodoca.com/authenticode file.exe # 再 SHA256 签名 \u0026#34;C:\\Program Files (x86)\\Microsoft SDKs\\ClickOnce\\SignTool\\signtool.exe\u0026#34; sign /tr http://timestamp.sectigo.com?td=sha256 /td sha256 /fd sha256 /as file.exe 时间戳服务器 (time-stamping server)\r代码签名时, 需要使用到时间戳服务器, 它为签名提供时间戳, 即使证书过期了, 在证书有效期内签名的程序仍然有效。\n时间戳服务器地址不用和颁发证书的机构对应, 常见的时间戳服务器包括\nhttp://timestamp.globalsign.com/scripts/timstamp.dll # 不稳定 http://timestamp.comodoca.com/authenticode http://timestamp.sectigo.com http://timestamp.sectigo.com?td=sha256 http://timestamp.sectigo.com?td=sha384 http://www.startssl.com/timestamp http://timestamp.digicert.com?alg=sha1 http://timestamp.digicert.com?alg=sha256 验证数字签名\r你可以右键单击应用程序并选择 \u0026ldquo;属性\u0026rdquo; 来验证应用程序是否已签名。如果签名存在, 你可以在 \u0026ldquo;数字签名\u0026rdquo; 选项卡中查看签名证书和时间戳\n这样, 你可以确保下载的软件是可信的, 并且未被篡改\n原文\nAuthenticode Code Signing with Microsoft SignTool\nSignTool 微软文档\nsigntool failing to dual sign SHA2 and SHA1 with timestamps\nTime Stamp Server \u0026amp; Stamping Protocols for Digital Signatures/Code Signing\nRFC3161 compliant Time Stamp Authority (TSA) server\nAlternative timestamping services for Authenticode\n","date":"2022-03-10T22:24:00+08:00","permalink":"https://blog.acesheep.com/p/signtool-code-signing-certificate-guide/","title":"使用 SignTool 进行代码签名"},{"content":"Tmux 是一个强大的终端复用器 (Terminal Multiplexer), 可以在一个终端窗口中管理多个会话、窗口和窗格。它广泛用于服务器开发、远程调试和多任务处理场景。\nTmux 概念和使用\r为什么要使用 tmux ?\r多窗口管理: 在一个终端中打开多个窗口, 无需频繁切换标签或新建终端 会话持久化: 即使网络连接断开, Tmux 会话仍然保持, 重新连接后可以继续工作 分屏操作: 支持在一个窗口中分割多个区域, 每个区域独立运行命令 快捷键高效操作: 丰富的快捷键大幅提升工作效率 可定制性强: 通过配置文件 (如 ~/.tmux.conf) 调整功能和键位 核心概念\r会话 (Session)\n一个 Tmux 会话包含多个窗口 会话可以长期存在, 即使与服务器的连接断开, 会话依然会在后台运行 可以随时分离会话, 并在以后通过 tmux attach 命令重新连接, 恢复工作区的状态 支持同时管理多个会话, 可以轻松切换和重命名会话 窗口 (Window)\n每个会话可以包含多个窗口, 类似于标签页 窗格 (Pane)\n窗口内可以划分为多个窗格, 每个窗格独立运行各种命令 查看 tmux 版本\rCentOS 7 中版本是 1.8\n$ tmux -V tmux 1.8 前缀键\rTmux 中有大量的快捷键, 这些快捷键都需要通过前缀键唤起。默认的前缀键是 Ctrl+b, 即按下 Ctrl+b 后, 接着按下相应的快捷键才能执行操作。\n举例来说, 帮助命令的快捷键是 Ctrl+b ?。它的用法是, 在 Tmux 窗口中, 先按下 Ctrl+b , 再按下 ? , 就会显示帮助信息。然后, 按下 ESC 键或 q 键, 就可以退出帮助。\n如果你更喜欢使用 Ctrl+a 作为前缀键, 可以通过修改 ~/.tmux.conf 配置文件来实现\n# remap prefix to Control + a set -g prefix C-a # bind \u0026#39;C-a C-a\u0026#39; to type \u0026#39;C-a\u0026#39; bind C-a send-prefix unbind C-b 常用快捷键\r快捷键 功能 Ctrl+b c 新建窗口 Ctrl+b % 窗口左右分割 Ctrl+b \u0026quot; 窗口上下分割 Ctrl+b d 分离当前会话 Ctrl+b s 列出所有会话 Ctrl+b w 列出所有窗口 Ctrl+b [方向键] 在窗格间切换 Ctrl+b x 关闭当前窗格 Ctrl+b z 当前窗格全屏/恢复 Ctrl+b ? 查看所有快捷键 会话管理\r新建会话\r在 Tmux 中, 第一个启动的会话编号为 0, 第二个为 1, 以此类推。\n使用编号区分会话, 不太直观, 为了更方便区分不同的会话, 可以为会话指定名称。\ntmux # 新建一个指定名称的会话 tmux new -s \u0026lt;session-name\u0026gt; # 启动新会话 Ctrl+b :new\u0026lt;回车\u0026gt; 列出所有会话\r快捷键\nCtrl+b s: 列出所有会话 查看当前所有的 Tmux 会话\ntmux ls # or tmux list-session 分离会话\r快捷键\nCtrl+b d: 分离当前会话 或者输入 tmux detach 命令, 就会将当前会话与窗口分离。分离后, 当前 Tmux 窗口会退出, 但会话和其中的进程仍然在后台运行。\ntmux detach 恢复会话\rtmux attach 命令用于重新接入某个已存在的会话。你可以通过会话编号或会话名称来恢复会话。\n# 使用会话编号 tmux attach -t 0 # 使用会话名称 tmux attach -t \u0026lt;session-name\u0026gt; # 简写方式 tmux a -t \u0026lt;session-name\u0026gt; 结束会话\rtmux kill-session 命令用于结束某个会话。你可以使用会话编号或会话名称来指定需要结束的会话。\n# 使用会话编号 tmux kill-session -t 0 # 使用会话名称 tmux kill-session -t \u0026lt;session-name\u0026gt; # 关闭所有会话 tmux ls | grep : | cut -d. -f1 | awk \u0026#39;{print substr($1, 0, length($1)-1)}\u0026#39; | xargs kill 切换会话\r快捷键\nCtrl+b (: 切换到上一个会话 Ctrl+b ) : 切换到下一个会话 Ctrl+b L : 切换到上一次使用过的会话 Ctrl+b s: 从会话列表中选择会话 tmux switch 命令用于切换会话\n# 使用会话编号 tmux switch -t 0 # 使用会话名称 tmux switch -t \u0026lt;session-name\u0026gt; 重命名会话\r快捷键\nCtrl+b $: 重命名当前会话 tmux rename-session 命令用于重命名会话。\ntmux rename-session -t 0 \u0026lt;new-name\u0026gt; 上面的命令将 0 号会话重命名为 \u0026lt;new-name\u0026gt;\n窗口管理\rTmux 允许在每个会话中创建多个窗口 (window)\n新建窗口\r快捷键\nCtrl+b c: 创建一个新窗口, 状态栏会显示多个窗口的信息 tmux new-window 命令用来创建新窗口\ntmux new-window # 新建一个指定名称的窗口 tmux new-window -n \u0026lt;window-name\u0026gt; 切换窗口\r快捷键\nCtrl+b w: 从列表中选择窗口 Ctrl+b p: 切换到上一个窗口 (按照状态栏上的顺序) Ctrl+b n: 切换到下一个窗口 Ctrl+b l: 切换到上一次使用过的窗口 Ctrl+b \u0026lt;number\u0026gt;: 切换到指定编号的窗口 (\u0026lt;number\u0026gt; 是状态栏上的窗口编号) Ctrl+b 0 Ctrl+b 9 tmux select-window 命令用来切换窗口\n# 切换到指定编号的窗口 tmux select-window -t \u0026lt;window-number\u0026gt; # 切换到指定名称的窗口 tmux select-window -t \u0026lt;window-name\u0026gt; 重命名窗口\r快捷键\nCtrl+b ,: 重命名当前窗口 tmux rename-window 命令用于为当前窗口命名或重命名\ntmux rename-window \u0026lt;new-name\u0026gt; 窗口快捷键\r下面是一些窗口操作的快捷键\nCtrl+b f: 查找窗口 Ctrl+b \u0026amp;: 关闭当前窗口 调整窗口排序\r按下 Tmux 前缀 Ctrl+b 后, 再输入 :, 可以使用以下命令来调整窗口顺序\nswap-window -s 3 -t 1 # 交换 3 号和 1 号窗口 swap-window -t 1 # 交换当前和 1 号窗口 move-window -t 1 # 将当前窗口移动到 1 号位置 窗格操作\rTmux 可以将窗口划分为多个窗格 (pane), 每个窗格可以独立运行不同的命令。以下是一些常见的窗格操作。\n划分窗格\r快捷键\nCtrl+b %: 垂直划分窗格, 左右分割 Ctrl+b \u0026quot;: 水平划分窗格, 上下分割 tmux split-window 命令用于划分窗格\n# 划分上下两个窗格 tmux split-window tmux split-window -v # 划分左右两个窗格 tmux split-window -h 移动光标\r快捷键\nCtrl+b ↑: 将光标切换到上方窗格 Ctrl+b ↓: 将光标切换到下方窗格 Ctrl+b ←: 将光标切换到左边窗格 Ctrl+b →: 将光标切换到右边窗格 Ctrl+b ;: 切换到上一个窗格 Ctrl+b o: 切换到下一个窗格 tmux select-pane 命令用于移动光标位置\n# 光标切换到上方窗格 tmux select-pane -U # 光标切换到下方窗格 tmux select-pane -D # 光标切换到左边窗格 tmux select-pane -L # 光标切换到右边窗格 tmux select-pane -R 交换窗格位置\r快捷键\nCtrl+b {: 将当前窗格与上一个窗格交换位置 Ctrl+b }: 将当前窗格与下一个窗格交换位置 Ctrl+b Ctrl+o: 将所有窗格向前移动一个位置, 第一个窗格变成最后一个窗格 Ctrl+b Alt+o: 将所有窗格向后移动一个位置, 最后一个窗格变成第一个窗格 tmux swap-pane 命令用于交换窗格位置\n# 当前窗格上移 tmux swap-pane -U # 当前窗格下移 tmux swap-pane -D 调整窗格尺寸\r以下快捷键可用于调整窗格大小\nCtrl+b :resize-pane -U # 当前窗格向上扩大 1 格 Ctrl+b :resize-pane -L # 当前窗格向左扩大 1 格 Ctrl+b :resize-pane -R # 当前窗格向右扩大 1 格 Ctrl+b :resize-pane -D 20 # 当前窗格向下扩大 20 格 Ctrl+b :resize-pane -t 2 -L 20 # 编号为 2 的窗格向左扩大 20 格 Ctrl+b Alt+ ↑ # 向上扩大窗格 Ctrl+b Alt+ ↓ # 向下扩大窗格 Ctrl+b Alt+ ← # 向左扩大窗格 Ctrl+b Alt+ → # 向右扩大窗格 Ctrl+b Alt+ → → → # 连续向右扩大窗格 翻页及内容搜索\r快捷键\nCtrl+b [: 进入滚动模式 (scrollback mode) 模式, 使用 ↑ 和 ↓ 方向键进行单行滚动 Ctrl+b PgUp: 向上翻页 Ctrl+b PgDn: 向下翻页 在滚动模式中, 按下 q 退出滚动模式 此外, 还可以使用 Ctrl+s 进行内容搜索, 搜索到多个内容时使用 n 或 N 跳转到下一个或上一个匹配项。\n在启用 emacs bindings 时, 使用 Ctrl+s 进行搜索\n如果启用了 vim bindings, 则需要进入 copy mode, 然后使用 / (slash) 进行搜索\n使用预设布局\rTmux 提供了几种常见的布局, 快捷键如下\nCtrl+b M-1 # 切换到水平均分布局 even-horizontal Ctrl+b M-2 # 切换到垂直均分布局 even-vertical Ctrl+b M-3 # 切换到主窗口水平布局 main-horizontal Ctrl+b M-4 # 切换到主窗口垂直布局 main-vertical Ctrl+b M-5 # 切换到平铺布局 Ctrl+b 空格 # 切换到下一个布局 窗格快捷键\r以下是一些常用的窗格操作快捷键\nCtrl+b x: 关闭当前窗格 Ctrl+b !: 将当前窗格拆分为一个独立窗口 Ctrl+b z: 当前窗格全屏显示, 再次使用会恢复原来大小 Ctrl+b t: 在当前窗格中显示一个数字时钟 Ctrl+b q: 显示窗格编号 其他命令\r以下是一些 Tmux 的常用命令\n# 列出所有快捷键及其对应的 Tmux 命令 tmux list-keys # 列出所有 Tmux 命令及其参数 tmux list-commands # 列出当前所有 Tmux 会话的信息 tmux info # 重新加载当前的 Tmux 配置 tmux source-file ~/.tmux.conf 列出所有快捷键\r[root@centos ~]# tmux -V tmux 1.8 [root@centos ~]# tmux list-keys bind-key C-b send-prefix bind-key C-o rotate-window bind-key C-z suspend-client bind-key Space next-layout bind-key ! break-pane bind-key \u0026#34; split-window bind-key # list-buffers bind-key $ command-prompt -I #S \u0026#34;rename-session \u0026#39;%%\u0026#39;\u0026#34; bind-key % split-window -h bind-key \u0026amp; confirm-before -p \u0026#34;kill-window #W? (y/n)\u0026#34; kill-window bind-key \u0026#39; command-prompt -p index \u0026#34;select-window -t \u0026#39;:%%\u0026#39;\u0026#34; bind-key ( switch-client -p bind-key ) switch-client -n bind-key , command-prompt -I #W \u0026#34;rename-window \u0026#39;%%\u0026#39;\u0026#34; bind-key - delete-buffer bind-key . command-prompt \u0026#34;move-window -t \u0026#39;%%\u0026#39;\u0026#34; bind-key 0 select-window -t :0 bind-key 1 select-window -t :1 bind-key 2 select-window -t :2 bind-key 3 select-window -t :3 bind-key 4 select-window -t :4 bind-key 5 select-window -t :5 bind-key 6 select-window -t :6 bind-key 7 select-window -t :7 bind-key 8 select-window -t :8 bind-key 9 select-window -t :9 bind-key : command-prompt bind-key ; last-pane bind-key = choose-buffer bind-key ? list-keys bind-key D choose-client bind-key L switch-client -l bind-key [ copy-mode bind-key ] paste-buffer bind-key c new-window bind-key d detach-client bind-key f command-prompt \u0026#34;find-window \u0026#39;%%\u0026#39;\u0026#34; bind-key i display-message bind-key l last-window bind-key n next-window bind-key o select-pane -t :.+ bind-key p previous-window bind-key q display-panes bind-key r refresh-client bind-key s choose-tree bind-key t clock-mode bind-key w choose-window bind-key x confirm-before -p \u0026#34;kill-pane #P? (y/n)\u0026#34; kill-pane bind-key z resize-pane -Z bind-key { swap-pane -U bind-key } swap-pane -D bind-key ~ show-messages bind-key PPage copy-mode -u bind-key -r Up select-pane -U bind-key -r Down select-pane -D bind-key -r Left select-pane -L bind-key -r Right select-pane -R bind-key M-1 select-layout even-horizontal bind-key M-2 select-layout even-vertical bind-key M-3 select-layout main-horizontal bind-key M-4 select-layout main-vertical bind-key M-5 select-layout tiled bind-key M-n next-window -a bind-key M-o rotate-window -D bind-key M-p previous-window -a bind-key -r M-Up resize-pane -U 5 bind-key -r M-Down resize-pane -D 5 bind-key -r M-Left resize-pane -L 5 bind-key -r M-Right resize-pane -R 5 bind-key -r C-Up resize-pane -U bind-key -r C-Down resize-pane -D bind-key -r C-Left resize-pane -L bind-key -r C-Right resize-pane -R Tmux 命令中的 M 按键是什么\r在 Tmux 命令中, M 按键代表的是 meta 键。例如, M-1 就是 meta-1, 类似于 C-1 是 control-1\n如果你使用的是普通的 PC 键盘, 可能会注意到没有明确标记为 meta 的键。根据你的键盘布局, meta 键通常是 Alt 键或 Windows 键 (徽标键)\n一般可以在 SSH 客户端里设置 meta 按键映射\n例如, 以下命令中的 M-1、M-2 等就是通过 meta 键配合数字键执行的操作\nbind-key M-1 select-layout even-horizontal bind-key M-2 select-layout even-vertical bind-key M-3 select-layout main-horizontal bind-key M-4 select-layout main-vertical bind-key M-5 select-layout tiled bind-key M-n next-window -a bind-key M-o rotate-window -D bind-key M-p previous-window -a 原文\ntmux cheat sheet\nTmux 快捷键 \u0026amp; 速查表 \u0026amp; 简明教程\nTmux 使用教程\nHow do I resize tmux pane by holding down prefix and arrow key for a while?\nHow do I scroll in tmux?\nTmux commands: What is M-whatever\n其他\nWhat do the keys on this Symbolics Space Cadet keyboard do?\ntmux终端复用/tmate终端共享/screen\nGNU Screen splitting\n.tmux.conf 配置文件\n","date":"2022-03-02T05:05:00+08:00","image":"https://blog.acesheep.com/p/tmux-guide/cover_hu4274575501644811907.png","permalink":"https://blog.acesheep.com/p/tmux-guide/","title":"Tmux 使用指南"},{"content":"RAR 是一种用于创建和提取压缩文件 (.rar 格式) 的流行工具。当我们从网络下载压缩文件时, 通常需要使用 RAR 工具来解压它们。\n本文将介绍如何在 Linux 系统上使用官方提供的二进制文件安装 rar 和 unrar 命令行工具, 以便打开、提取和解压缩 RAR 压缩文件。\n安装和配置\r下载和安装\r要安装 RAR 工具, 请前往 RARLAB 网站下载最新的 unrar/rar 文件, 然后按照以下步骤操作\n# 下载 RAR 工具的 Linux 版本并解压 wget https://www.rarlab.com/rar/rarlinux-x64-610.tar.gz tar -xf rarlinux-x64-610.tar.gz # 进入解压后的目录 cd rar 使用 root 用户安装\n# 将 rar 和 unrar 二进制文件复制到系统路径 cp -v rar unrar /usr/local/bin/ 普通用户安装\n# 创建本地 bin 目录 mkdir -p $HOME/.local/bin # 将本地 bin 目录添加到 PATH 环境变量 export PATH=\u0026#34;$HOME/.local/bin:$PATH\u0026#34; # 创建 rar 和 unrar 的符号链接 ln -s $HOME/rar/rar $HOME/.local/bin/rar ln -s $HOME/rar/unrar $HOME/.local/bin/unrar 注册 RAR\r要注册 RAR 工具, 你需要将许可证文件 rarreg.key 复制到用户目录 /home/user 或以下任意目录之一\n/etc /usr/lib /usr/local/lib /usr/local/etc 你也可以选择将 rarreg.key 文件重命名为 .rarreg.key 或 .rarregkey, 这些名称同样有效。\n网上搜集到的可用注册码\r将 rarreg.key 文件放置在上述位置后, RAR 工具将在使用时自动读取注册信息, 从而解锁完整功能\nRAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to Federal Agency for Education RAR registration data Federal Agency for Education 1000000 PC usage license UID=b621cca9a84bc5deffbf 6412612250ffbf533df6db2dfe8ccc3aae5362c06d54762105357d 5e3b1489e751c76bf6e0640001014be50a52303fed29664b074145 7e567d04159ad8defc3fb6edf32831fd1966f72c21c0c53c02fbbb 2f91cfca671d9c482b11b8ac3281cb21378e85606494da349941fa e9ee328f12dc73e90b6356b921fbfb8522d6562a6a4b97e8ef6c9f fb866be1e3826b5aa126a4d2bfe9336ad63003fc0e71c307fc2c60 64416495d4c55a0cc82d402110498da970812063934815d81470829275 第二个\nRAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR RAR registration data WinRAR Unlimited Company License UID=4b914fb772c8376bf571 6412212250f5711ad072cf351cfa39e2851192daf8a362681bbb1d cd48da1d14d995f0bbf960fce6cb5ffde62890079861be57638717 7131ced835ed65cc743d9777f2ea71a8e32c7e593cf66794343565 b41bcf56929486b8bcdac33d50ecf773996052598f1f556defffbd 982fbe71e93df6b6346c37a3890f3c7edc65d7f5455470d13d1190 6e6fb824bcf25f155547b5fc41901ad58c0992f570be1cf5608ba9 aef69d48c864bcd72d15163897773d314187f6a9af350808719796 第三个\nRAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to State Grid Corporation Of China RAR registration data State Grid Corporation Of China 50000 PC usage license UID=5827a0bd1c43525d0a5d 64122122500a5d3d56f784f3a440ac3fb632d34e08bbaa37fc7712 6acaeb8eb044810272e86042cb7c79b1da0eaf88c79f8a7c6dd77b dba335e27a109997ac90fb0e10e4129e79f46c42b4ee1832fa5113 7443fcc1124840d4dd36f3af84a5c915a760b18c6394f938168227 fbf29edbc4b34ef85ee53fbfca71814a82afadf073876b4b033451 b6292a7cc7975b3ff3cc73404abbf7c126787344169eeae4609f62 c9ffbc159bf2640ad5d9b88f8fa9d9cbf2b7e5b022a21938465244 常用操作\r文件夹原始结构, 以下是一个压缩包的文件夹结构示例\n$ tree ├── acesheep | ├── abc.txt | ├── index.html | ├── index.php | └── xyz.txt ├── default | ├── index.html | └── index.php ├── include | └── abc.txt └── php └── xyz.txt 4 directories, 8 files 解压 RAR 文件\r解压并忽略目录结构\r使用 unrar e 命令可以提取文件 (忽略目录结构)\ne 选项会忽略压缩包中的路径信息, 将所有内容解压到目录 如果解压时遇到同名文件, 程序会提示是否覆盖 将所有内容解压到当前文件夹\n$ unrar e acesheep.rar UNRAR 6.10 freeware Copyright (c) 1993-2022 Alexander Roshal Extracting from acesheep.rar Extracting xyz.txt OK Extracting index.html OK Extracting index.php OK Extracting abc.txt OK Would you like to replace the existing file index.html 0 bytes, modified on 2022-02-25 10:33 with a new one 0 bytes, modified on 2022-02-25 10:34 [Y]es, [N]o, [A]ll, n[E]ver, [R]ename, [Q]uit a Extracting index.html OK Extracting index.php OK Extracting abc.txt OK Extracting xyz.txt OK All OK 将所有内容解压到指定路径\n$ unrar e acesheep.rar ace/ UNRAR 6.10 freeware Copyright (c) 1993-2022 Alexander Roshal Extracting from acesheep.rar Extracting ace/xyz.txt OK Extracting ace/index.html OK Extracting ace/index.php OK Extracting ace/abc.txt OK Would you like to replace the existing file ace/index.html 0 bytes, modified on 2022-02-25 10:33 with a new one 0 bytes, modified on 2022-02-25 10:34 [Y]es, [N]o, [A]ll, n[E]ver, [R]ename, [Q]uit a Extracting ace/index.html OK Extracting ace/index.php OK Extracting ace/abc.txt OK Extracting ace/xyz.txt OK All OK 解压并保留目录结构\r使用 unrar x 命令可以保留压缩包中的原始目录结构进行解压。一般情况下使用 x 解压\n程序会根据压缩包中的目录结构创建相应的文件夹并提取文件, 请看下面的命令输出\n$ unrar x acesheep.rar UNRAR 6.10 freeware Copyright (c) 1993-2022 Alexander Roshal Extracting from acesheep.rar Creating acesheep OK Extracting acesheep/xyz.txt OK Extracting acesheep/index.html OK Extracting acesheep/index.php OK Extracting acesheep/abc.txt OK Creating default OK Extracting default/index.html OK Extracting default/index.php OK Creating include OK Extracting include/abc.txt OK Creating php OK Extracting php/xyz.txt OK All OK 查看压缩包内容\r使用 unrar l 列出存档文件中的内容。它将显示文件列表及其 大小、日期、时间、权限\n$ unrar l acesheep.rar UNRAR 6.10 freeware Copyright (c) 1993-2022 Alexander Roshal Archive: acesheep.rar Details: RAR 5 Attributes Size Date Time Name ----------- --------- ---------- ----- ---- -rw-r--r-- 0 2022-02-25 10:33 acesheep/xyz.txt -rw-r--r-- 0 2022-02-25 10:33 acesheep/index.html -rw-r--r-- 0 2022-02-25 10:33 acesheep/index.php -rw-r--r-- 0 2022-02-25 10:33 acesheep/abc.txt -rw-r--r-- 0 2022-02-25 10:34 default/index.html -rw-r--r-- 0 2022-02-25 10:34 default/index.php -rw-r--r-- 0 2022-02-25 10:37 include/abc.txt -rw-r--r-- 0 2022-02-25 10:37 php/xyz.txt ----------- --------- ---------- ----- ---- 0 8 测试压缩包完整性\r使用 unrar t 检查存档文件是否损坏, 检查完整性。该命令将对压缩包中的每个文件执行完整性检查, 并显示文件的状态\n$ unrar t acesheep.rar UNRAR 6.10 freeware Copyright (c) 1993-2022 Alexander Roshal Testing archive acesheep.rar Testing acesheep/xyz.txt OK Testing acesheep/index.html OK Testing acesheep/index.php OK Testing acesheep/abc.txt OK Testing default/index.html OK Testing default/index.php OK Testing include/abc.txt OK Testing php/xyz.txt OK All OK 创建 RAR 压缩文件\r使用 rar a 创建新的 RAR 文件。unrar 命令仅支持提取、列出或测试压缩文件, 无法用于创建 RAR 压缩文件。要创建 RAR 文件, 需要使用 rar 命令。\n以下命令会将文件夹 acesheep 压缩为 acesheep.rar\n$ rar a acesheep.rar acesheep RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Updating archive acesheep.rar Updating acesheep/xyz.txt OK Updating acesheep/index.html OK Updating acesheep/index.php OK Updating acesheep/abc.txt OK Adding acesheep OK Done 在压缩过程中, rar 命令会显示每个文件的压缩状态。如果压缩成功, 会显示 OK。压缩完成后, acesheep.rar 文件将包含整个 acesheep 文件夹及其内容。\n删除压缩包中的文件\r使用 rar d 从存档中删除特定文件。\n例如, 以下命令会从 acesheep.rar 压缩包中删除文件 acesheep/abc.txt\nrar d acesheep.rar acesheep/abc.txt 更新压缩包\r使用 rar u 更新现有存档文件。如果需要向现有的 RAR 压缩文件中更新或添加文件\n例如, 以下命令会将文件 acesheep.sql 添加到现有的 acesheep.rar 压缩包中\n$ rar u acesheep.rar acesheep.sql RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Updating archive acesheep.rar Adding acesheep.sql OK Done 现在, 可以使用 rar l 命令列出压缩包的内容, 以确认文件 acesheep.sql 是否已成功添加到压缩文件中\n$ rar l acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Archive: acesheep.rar Details: RAR 5 Attributes Size Date Time Name ----------- --------- ---------- ----- ---- -rw-r--r-- 0 2022-02-25 10:33 acesheep/xyz.txt -rw-r--r-- 0 2022-02-25 10:33 acesheep/index.html -rw-r--r-- 0 2022-02-25 10:33 acesheep/index.php -rw-r--r-- 0 2022-02-25 10:33 acesheep/abc.txt drwxr-xr-x 0 2022-02-25 12:27 acesheep -rw-r--r-- 0 2022-02-25 13:36 acesheep.sql ----------- --------- ---------- ----- ---- 0 6 从输出中可以看到, acesheep.sql 文件已经成功添加到压缩包中\n修复压缩包\r使用 rar r 修复损坏的存档文件。当 RAR 压缩包损坏时, 修复操作会在同一目录下创建一个修复后的文件, 通常命名为 rebuilt.\u0026lt;原文件名\u0026gt;.rar 例如 rebuilt.acesheep.rar 文件\n$ rar r acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Data recovery record not found Reconstructing acesheep.rar Building rebuilt.acesheep.rar 8% Found acesheep/xyz.txt 26% Found acesheep/index.html 45% Found acesheep/index.php 64% Found acesheep/abc.txt 82% Found acesheep 100% Done 添加恢复记录\r为了提高压缩包的容错性, 可以在创建压缩包时添加恢复记录。使用 -rr 参数即可, 默认情况下恢复记录为 3%, 等价于 -rr3p。建议选择 3% 至 10% 的恢复记录比例, 以平衡文件大小和恢复能力。\nrar a -rr5p acesheep.rar acesheep 上述命令会在创建 acesheep.rar 压缩包时, 添加 5% 的恢复记录, 从而提高修复成功率\n高级功能\r创建带密码的压缩文件\r使用 rar a -p 创建带密码的压缩文件。可以对压缩文件进行密码保护。在命令中直接指定密码, 例如 rar a -p51522zzwlwlbb, 其中密码为 51522zzwlwlbb\n$ rar a -p acesheep.rar acesheep.sql Enter password (will not be echoed): Reenter password: RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Updating archive acesheep.rar Updating acesheep.sql OK Done 验证密码保护\r通过提取压缩文件来验证是否设置了密码。如果文件受密码保护, 提取时会提示输入密码\n$ rar x acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Extracting from acesheep.rar Creating acesheep OK Extracting acesheep/xyz.txt OK Extracting acesheep/index.html OK Extracting acesheep/index.php OK Extracting acesheep/abc.txt OK Enter password (will not be echoed) for acesheep.sql: Extracting acesheep.sql OK All OK 注意事项\n如果密码直接包含在命令中 (如 -p51522zzwlwlbb), 会有安全隐患, 因为命令可能被系统日志或其他工具记录 推荐使用交互式方式输入密码, 以提高安全性 锁定压缩文件\r使用 rar k 锁定存档以防止修改。RAR 提供了一个选项, 可以锁定压缩文件以防止其被更新、添加或修改。通过锁定, 你可以保护重要的存档文件, 避免意外更改。\n锁定后的存档文件无法通过 WinRAR 或其他工具进行修改。\n$ rar k acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Processing archive acesheep.rar Locking archive Done 注意事项\n锁定后, 存档文件处于只读状态, 任何更新或修改操作都会被拒绝 锁定操作不可逆, 确保在锁定前已完成所有必要的更新或修改 分卷压缩\r使用 -v 参数可以创建分卷压缩文件, 支持多种单位 (如 k、m、g 等)。分卷压缩适用于将大文件分割成多个小文件, 便于存储或传输。\n分卷压缩参数说明\r-v\u0026lt;n\u0026gt;[k|b|f|m|M|g|G] - 设置分卷大小\n默认单位: \u0026lt;n\u0026gt; 乘以 1000 字节为单位计算 (非 1024 字节)\n单位符号说明\n符号 值 k KiB = 1024 bytes b bytes = 1 bytes f 软盘大小 (360、720、1200、1440 或 2880 KiB)。如果省略大小, 将使用自动检测。 m MiB = 1024 KiB M MB = 1000 KiB g GiB = 1024 MiB G GB = 1000 MiB 支持小数: 可以使用小数点指定分卷大小, 例如 -v1.5g 表示 1.5 GiB\n多级分卷: 可以通过多个 -v 参数为不同分卷设置不同大小\n为不同分卷设置大小\nrar a -v100k -v200k -v300k acesheep.rar 第一个分卷大小为 100 KiB 第二个分卷大小为 200 KiB 后续所有的分卷大小为 300 KiB 验证分卷大小\n# 使用 -v10G 创建 10 GB 分卷 $ ls -all mysql-5.7.31-winx64.part01.rar -rw-r--r-- 1 user user 10000000000 Feb 22 01:51 mysql-5.7.31-winx64.part01.rar # 使用 -v10g 创建 10 GiB 分卷 $ ls -all mysql-5.7.31-winx64.part01.rar -rw-r--r-- 1 user user 10737418240 Feb 22 14:09 mysql-5.7.31-winx64.part01.rar 指定的单位会影响分卷的实际大小, 请根据需求选择合适的单位\n实际运用示例\r在实际操作中, 可以结合多个参数来优化压缩效率和分卷大小。以下命令展示了一个典型的应用场景\n目录结构\n[root@server temp]# tree -L 1 temp ├── mysql-5.7.31-winx64.rar └── mysql-5.7.31-winx64/ 压缩命令\n进入需要压缩文件的上层目录 temp 文件夹后运行以下命令\nrar a -m5 -ma5 -md128MB -mt2 -v10g -r -k mysql-5.7.31-winx64.rar mysql-5.7.31-winx64/ 参数说明\n参数 作用 -m5 使用最高压缩级别 5 -ma5 使用 RAR5 存档格式 -md128MB 设置字典大小为 128 MB -mt2 使用 2 个线程进行压缩 -v10g 分卷压缩, 每个分卷大小为 10 GiB -r 递归处理子目录 -k 锁定压缩文件, 禁止后续修改 注意事项\n压缩线程数: 根据 CPU 核心数量调整 -mt 参数以提高压缩效率 字典大小: -md 参数设置的字典大小会影响压缩率和内存使用, 推荐值为 128 MB 或更高 不在同一层目录时压缩\r当我们不在需要压缩的文件上层目录时, 可以使用绝对路径来压缩目标文件夹。但如果不加注意, 这种方式会将整个绝对路径同时存储到压缩包中, 可能导致路径层级过深的问题。通过调整参数, 可以避免这种情况。\n示例目录结构\r假设目录结构如下, 我们当前位于 WorkFolder, 使用绝对路径压缩 FolderToArchive 文件夹\n[root@server ~]# tree temp temp ├── FolderToArchive │ ├── File1 │ ├── File2 │ ├── File3 │ ├── FolderA │ │ ├── FileX │ │ ├── FileY │ │ └── FileZ │ └── FolderB │ ├── FileA │ ├── FileB │ └── FileC └── WorkFolder 4 directories, 9 files 错误示范\r如果直接使用以下命令压缩。虽然我们没有指定, 但是参数中有 -ep2 默认参数\n[root@server WorkFolder]# rar a -m5 -ma5 -md128MB -r -k acesheep.rar /temp/FolderToArchive/ RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Creating archive acesheep.rar Adding /temp/FolderToArchive/File2 OK Adding /temp/FolderToArchive/File1 OK Adding /temp/FolderToArchive/FolderA/FileX OK Adding /temp/FolderToArchive/FolderA/FileY OK Adding /temp/FolderToArchive/FolderA/FileZ OK Adding /temp/FolderToArchive/File3 OK Adding /temp/FolderToArchive/FolderB/FileB OK Adding /temp/FolderToArchive/FolderB/FileA OK Adding /temp/FolderToArchive/FolderB/FileC OK Adding /temp/FolderToArchive/FolderA OK Adding /temp/FolderToArchive/FolderB OK Locking archive Done 检查压缩包的文件列表时, 可以看到压缩时的绝对路径中的所有文件夹都被完整保存了进去。这种方式会使文件夹层数变得非常多, 因此极其不推荐使用。\n路径为: /temp/FolderToArchive/, 压缩包内路径为 temp/FolderToArchive/\n[root@server WorkFolder]# rar l acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Archive: acesheep.rar Details: RAR 5, lock Attributes Size Date Time Name ----------- --------- ---------- ----- ---- -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/File2 -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/File1 -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/FolderA/FileX -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/FolderA/FileY -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/FolderA/FileZ -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/File3 -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/FolderB/FileB -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/FolderB/FileA -rw-r--r-- 0 2022-03-28 22:44 temp/FolderToArchive/FolderB/FileC drwxr-xr-x 0 2022-03-28 22:44 temp/FolderToArchive/FolderA drwxr-xr-x 0 2022-03-28 22:44 temp/FolderToArchive/FolderB ----------- --------- ---------- ----- ---- 0 11 命令稍作修改, 添加 -ep1 参数。-ep1 参数会移除绝对路径, 仅保留目标文件夹的内容\n[root@server WorkFolder]# rar a -m5 -ma5 -md128MB -r -k -ep1 acesheep.rar /temp/FolderToArchive/ RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Creating archive acesheep.rar Adding /temp/FolderToArchive/File2 OK Adding /temp/FolderToArchive/File1 OK Adding /temp/FolderToArchive/FolderA/FileX OK Adding /temp/FolderToArchive/FolderA/FileY OK Adding /temp/FolderToArchive/FolderA/FileZ OK Adding /temp/FolderToArchive/File3 OK Adding /temp/FolderToArchive/FolderB/FileB OK Adding /temp/FolderToArchive/FolderB/FileA OK Adding /temp/FolderToArchive/FolderB/FileC OK Adding /temp/FolderToArchive/FolderA OK Adding /temp/FolderToArchive/FolderB OK Locking archive Done 此时压缩包中只包含了绝对路径中的子目录和文件, 但却排除了 FolderToArchive 目标文件夹本身。如果想要将 FolderToArchive 一并包含在压缩包中, 该怎么办呢？\n[root@server WorkFolder]# rar l acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Archive: acesheep.rar Details: RAR 5, lock Attributes Size Date Time Name ----------- --------- ---------- ----- ---- -rw-r--r-- 0 2022-03-28 22:44 File2 -rw-r--r-- 0 2022-03-28 22:44 File1 -rw-r--r-- 0 2022-03-28 22:44 FolderA/FileX -rw-r--r-- 0 2022-03-28 22:44 FolderA/FileY -rw-r--r-- 0 2022-03-28 22:44 FolderA/FileZ -rw-r--r-- 0 2022-03-28 22:44 File3 -rw-r--r-- 0 2022-03-28 22:44 FolderB/FileB -rw-r--r-- 0 2022-03-28 22:44 FolderB/FileA -rw-r--r-- 0 2022-03-28 22:44 FolderB/FileC drwxr-xr-x 0 2022-03-28 22:44 FolderA drwxr-xr-x 0 2022-03-28 22:44 FolderB ----------- --------- ---------- ----- ---- 0 11 去掉路径末尾的斜杠 /\r要将目标文件夹 FolderToArchive 一并包含在压缩包中, 需要删除绝对路径末尾的 /\n需要注意的是, 使用 TAB 键自动补全目录时, 系统会在文件夹末尾自动添加一个斜杠。\n[root@server WorkFolder]# rar a -m5 -ma5 -md128MB -r -k -ep1 acesheep.rar /temp/FolderToArchive RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Creating archive acesheep.rar Adding /temp/FolderToArchive/File2 OK Adding /temp/FolderToArchive/File1 OK Adding /temp/FolderToArchive/FolderA/FileX OK Adding /temp/FolderToArchive/FolderA/FileY OK Adding /temp/FolderToArchive/FolderA/FileZ OK Adding /temp/FolderToArchive/File3 OK Adding /temp/FolderToArchive/FolderB/FileB OK Adding /temp/FolderToArchive/FolderB/FileA OK Adding /temp/FolderToArchive/FolderB/FileC OK Adding /temp/FolderToArchive/FolderA OK Adding /temp/FolderToArchive/FolderB OK Adding /temp/FolderToArchive OK Locking archive Done 此时压缩包内的目录结构正确, 竟然是预期的目录结构\n[root@server WorkFolder]# rar l acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Archive: acesheep.rar Details: RAR 5, lock Attributes Size Date Time Name ----------- --------- ---------- ----- ---- -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/File2 -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/File1 -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/FolderA/FileX -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/FolderA/FileY -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/FolderA/FileZ -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/File3 -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/FolderB/FileB -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/FolderB/FileA -rw-r--r-- 0 2022-03-28 22:44 FolderToArchive/FolderB/FileC drwxr-xr-x 0 2022-03-28 22:44 FolderToArchive/FolderA drwxr-xr-x 0 2022-03-28 22:44 FolderToArchive/FolderB drwxr-xr-x 0 2022-03-28 22:44 FolderToArchive ----------- --------- ---------- ----- ---- 0 12 重命名压缩包内的文件夹\r如果当文件夹名称中包含空格或特殊字符时, 希望在压缩时重命名文件夹, 可以结合 -ep1 和 -ap\u0026lt;path\u0026gt; 参数。例如, 将文件夹重命名为 RenameFolder\n[root@server WorkFolder]# rar a -m5 -ma5 -md128MB -r -k -ep1 -apRenameFolder acesheep.rar /temp/FolderToArchive/ RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Creating archive acesheep.rar Adding /temp/FolderToArchive/File2 OK Adding /temp/FolderToArchive/File1 OK Adding /temp/FolderToArchive/FolderA/FileX OK Adding /temp/FolderToArchive/FolderA/FileY OK Adding /temp/FolderToArchive/FolderA/FileZ OK Adding /temp/FolderToArchive/File3 OK Adding /temp/FolderToArchive/FolderB/FileB OK Adding /temp/FolderToArchive/FolderB/FileA OK Adding /temp/FolderToArchive/FolderB/FileC OK Adding /temp/FolderToArchive/FolderA OK Adding /temp/FolderToArchive/FolderB OK Locking archive Done 这样压缩包内就是新的文件夹名称了, 完美!\n[root@server WorkFolder]# rar l acesheep.rar RAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Archive: acesheep.rar Details: RAR 5, lock Attributes Size Date Time Name ----------- --------- ---------- ----- ---- -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/File2 -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/File1 -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/FolderA/FileX -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/FolderA/FileY -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/FolderA/FileZ -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/File3 -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/FolderB/FileB -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/FolderB/FileA -rw-r--r-- 0 2022-03-28 22:44 RenameFolder/FolderB/FileC drwxr-xr-x 0 2022-03-28 22:44 RenameFolder/FolderA drwxr-xr-x 0 2022-03-28 22:44 RenameFolder/FolderB ----------- --------- ---------- ----- ---- 0 11 完整帮助\rRAR 6.10 Copyright (c) 1993-2022 Alexander Roshal 24 Jan 2022 Registered to WinRAR Usage: rar \u0026lt;command\u0026gt; -\u0026lt;switch 1\u0026gt; -\u0026lt;switch N\u0026gt; \u0026lt;archive\u0026gt; \u0026lt;files...\u0026gt; \u0026lt;@listfiles...\u0026gt; \u0026lt;path_to_extract\\\u0026gt; \u0026lt;Commands\u0026gt; a Add files to archive c Add archive comment ch Change archive parameters cw Write archive comment to file d Delete files from archive e Extract files without archived paths f Freshen files in archive i[par]=\u0026lt;str\u0026gt; Find string in archives k Lock archive l[t[a],b] List archive contents [technical[all], bare] m[f] Move to archive [files only] p Print file to stdout r Repair archive rc Reconstruct missing volumes rn Rename archived files rr[N] Add data recovery record rv[N] Create recovery volumes s[name|-] Convert archive to or from SFX t Test archive files u Update files in archive v[t[a],b] Verbosely list archive contents [technical[all],bare] x Extract files with full path \u0026lt;Switches\u0026gt; - Stop switches scanning @[+] Disable [enable] file lists ad[1,2] Alternate destination path ag[format] Generate archive name using the current date ai Ignore file attributes ap\u0026lt;path\u0026gt; Set path inside archive as Synchronize archive contents c- Disable comments show cfg- Disable read configuration cl Convert names to lower case cu Convert names to upper case df Delete files after archiving dh Open shared files ds Disable name sort for solid archive dw Wipe files after archiving e[+]\u0026lt;attr\u0026gt; Set file exclude and include attributes ed Do not add empty directories ep Exclude paths from names ep1 Exclude base directory from names, 压缩包第一层直接是文件夹内容 ep2 默认值, 不用指定 ep3 Expand paths to full including the drive letter ep4\u0026lt;path\u0026gt; Exclude the path prefix from names f Freshen files hp[password] Encrypt both file data and headers ht[b|c] Select hash type [BLAKE2,CRC32] for file checksum id[c,d,n,p,q] Display or disable messages ierr Send all messages to stderr ilog[name] Log errors to file inul Disable all messages isnd[-] Control notification sounds iver Display the version number k Lock archive kb Keep broken extracted files log[f][=name] Write names to log file m\u0026lt;0..5\u0026gt; Set compression level (0-store...3-default...5-maximal) ma[4|5] Specify a version of archiving format mc\u0026lt;par\u0026gt; Set advanced compression parameters md\u0026lt;n\u0026gt;[k,m,g] Dictionary size in KB, MB or GB me[par] Set encryption parameters ms[ext;ext] Specify file types to store mt\u0026lt;threads\u0026gt; Set the number of threads n\u0026lt;file\u0026gt; Additionally filter included files n@ Read additional filter masks from stdin n@\u0026lt;list\u0026gt; Read additional filter masks from list file o[+|-] Set the overwrite mode oh Save hard links as the link instead of the file oi[0-4][:min] Save identical files as references ol[a] Process symbolic links as the link [absolute paths] op\u0026lt;path\u0026gt; Set the output path for extracted files or Rename files automatically ow Save or restore file owner and group p[password] Set password qo[-|+] Add quick open information [none|force] r Recurse subdirectories r- Disable recursion r0 Recurse subdirectories for wildcard names only rr[N] Add data recovery record rv[N] Create recovery volumes s[\u0026lt;N\u0026gt;,v[-],e] Create solid archive s- Disable solid archiving sc\u0026lt;chr\u0026gt;[obj] Specify the character set sfx[name] Create SFX archive si[name] Read data from standard input (stdin) sl\u0026lt;size\u0026gt; Process files with size less than specified sm\u0026lt;size\u0026gt; Process files with size more than specified t Test files after archiving ta[mcao]\u0026lt;d\u0026gt; Process files modified after \u0026lt;d\u0026gt; YYYYMMDDHHMMSS date tb[mcao]\u0026lt;d\u0026gt; Process files modified before \u0026lt;d\u0026gt; YYYYMMDDHHMMSS date tk Keep original archive time tl Set archive time to latest file tn[mcao]\u0026lt;t\u0026gt; Process files newer than \u0026lt;t\u0026gt; time to[mcao]\u0026lt;t\u0026gt; Process files older than \u0026lt;t\u0026gt; time ts[m,c,a,p] Save or restore time (modification, creation, access, preserve) u Update files v\u0026lt;size\u0026gt;[k,b] Create volumes with size=\u0026lt;size\u0026gt;*1000 [*1024, *1] ver[n] File version control vn Use the old style volume naming scheme vp Pause before each volume w\u0026lt;path\u0026gt; Assign work directory x\u0026lt;file\u0026gt; Exclude specified file x@ Read file names to exclude from stdin x@\u0026lt;list\u0026gt; Exclude files listed in specified list file y Assume Yes on all queries z[file] Read archive comment from file 原文\nHow to transfer WinRAR key to Linux\nHow to Open, Extract and Create RAR Files in Linux\nSwitch -V\u0026lt;n\u0026gt;[k|b|f|m|M|g|G] - create volumes\nWinRAR storing file paths [closed]\n","date":"2022-02-25T09:57:00+08:00","permalink":"https://blog.acesheep.com/p/linux-rar-command-guide/","title":"Linux RAR 命令详解"},{"content":"在加密方式的选择上, RSA 4096 曾经是常用的选择, 但随着时间的推移, 它逐渐被淘汰, 取而代之的是更安全、更高效的 Ed25519。如今, GitHub 和大多数平台都建议尽可能使用 Ed25519\n生成 Ed25519 密钥对\r生成 Ed25519 密钥对的命令如下\nssh-keygen -t ed25519 -C \u0026#34;your_email@example.com\u0026#34; 默认轮数为 16。如果你需要提高密钥的安全性, 可以使用 -a 参数增加轮数, 但请注意, 增加轮数会导致密钥生成和验证的速度变慢, 登录时可能会出现延迟。默认值为 16, 通常不超过 1 秒的登录时间, 而值 150 或更大可能会增加几秒或更多的延迟。轮数越高, 登录速度可能会受到更大影响\n例如, 使用 100 轮生成密钥对\nssh-keygen -t ed25519 -a 100 -C \u0026#34;your_email@example.com\u0026#34; 生成 RSA 密钥对\r虽然 RSA 4096 仍然被某些系统使用, 但不推荐在新系统中使用。对于大多数用户, Ed25519 是更好的选择。如果你仍然想使用 RSA 4096, 可以使用以下命令\nssh-keygen -t rsa -b 4096 -C \u0026#34;your_email@example.com\u0026#34; 如果不指定参数, ssh-keygen 默认生成 RSA 2048 密钥\nssh-keygen -C \u0026#34;your_email@example.com\u0026#34; 将公钥复制到远程服务器 ssh-copy-id\r将生成的公钥复制到远程机器上, 使用 ssh-copy-id 命令。一般情况下, 不需要指定 -i 参数, 除非你想使用特定的公钥文件\nssh-copy-id -i .ssh/id_ed25519.pub user@192.168.0.1 这样, 公钥就会被复制到远程服务器的 ~/.ssh/authorized_keys 文件中, 从而实现无密码登录\n原文\nWhy use -t rsa -b 4096 with ssh-keygen?\n","date":"2022-02-24T18:42:00+08:00","permalink":"https://blog.acesheep.com/p/generate-ssh-public-keys-in-2022/","title":"在 2022 年生成 SSH 公钥"},{"content":"用简单的例子来理解 sync.Mutex 和 sync.RWMutex 的区别\n盖一间银行\r假设我们有一间银行, 支持存款和查询余额的功能, 代码如下\npackage main import ( \u0026#34;fmt\u0026#34; ) type Bank struct { balance int } func (b *Bank) Deposit(amount int) { b.balance += amount } func (b *Bank) Balance() int { return b.balance } func main() { b := \u0026amp;Bank{} b.Deposit(1000) b.Deposit(1000) b.Deposit(1000) fmt.Println(b.Balance()) } 运行结果\n$ go run main.go 3000 执行之后, 结果正常 3000 没问题, 1000 + 1000 + 1000 = 3000\n支持同时存款\r银行不太可能让人一个一个排队存款, 也需要支持同时存款, 当今天存款的动作是并行的, 会发生什么事呢？\n这次用 sync.WaitGroup 去等待所有 goroutine 执行完毕, 之后再打印出余额\nfunc main() { var wg sync.WaitGroup b := \u0026amp;Bank{} wg.Add(3) go func() { b.Deposit(1000) wg.Done() }() go func() { b.Deposit(1000) wg.Done() }() go func() { b.Deposit(1000) wg.Done() }() wg.Wait() fmt.Println(b.Balance()) } 结果仍然是正确的\n$ go run main.go 3000 还是 3000 没问题, 那我们同时存款 1000 次的时候会发生什么事呢？\nfunc main() { var wg sync.WaitGroup b := \u0026amp;Bank{} n := 1000 wg.Add(n) for i := 1; i \u0026lt;= n; i++ { go func() { b.Deposit(1000) wg.Done() }() } wg.Wait() fmt.Println(b.Balance()) } 运行结果\n$ go run main.go 958000 诶奇怪, 结果错误, 正常来说 1000 * 1000 = 1000000 吗？怎么数字不正确！\n我们这次多带一个参数 -race 跑看看\n-race 参数是 go 的 Race Detector, 内建整合工具, 可以轻松检查出是否有 race condition\n$ go run -race main.go ================== WARNING: DATA RACE Read at 0x00c00012c088 by goroutine 8: main.(*Bank).Deposit() .../main.go:13 +0x3c main.main.func1() .../main.go:28 +0x37 Previous write at 0x00c00012c088 by goroutine 7: main.(*Bank).Deposit() .../main.go:13 +0x4e main.main.func1() .../main.go:28 +0x37 Goroutine 8 (running) created at: main.main() .../main.go:27 +0x97 Goroutine 7 (finished) created at: main.main() .../main.go:27 +0x97 ================== 1000000 Found 1 data race(s) exit status 66 发现存在竞争条件 (race condition), 因为同时去对 Bank.balance 去做存取的动作, 数量少的时候可能没问题, 当量大的时候就可能出错\n使用 sync.Mutex 解决竞争条件\r为了防止这种状况发生, 就可以用互斥锁 sync.Mutex 来处理这个问题, 同时间只有一个 goroutine 能存取改变该数。通过 sync.Mutex 实现线程安全\n这次我们在 Deposit() 存款前先 Lock(), 存款后再 Unlock()\ntype Bank struct { balance int mux sync.Mutex } func (b *Bank) Deposit(amount int) { b.mux.Lock() b.balance += amount b.mux.Unlock() } func (b *Bank) Balance() int { return b.balance } 运行结果\n$ go run -race main.go 1000000 这次结果正确了, 而且也没跳出 race condition 的警告\n同时存款和查询余额\r会有多人一起存款, 就会有多人一起查询余额\n多加一组查询 1000 次的 goroutine 再执行看看\nfunc main() { var wg sync.WaitGroup b := \u0026amp;Bank{} n := 1000 wg.Add(n) for i := 1; i \u0026lt;= n; i++ { go func() { b.Deposit(1000) wg.Done() }() } wg.Add(n) for i := 1; i \u0026lt;= n; i++ { go func() { _ = b.Balance() wg.Done() }() } wg.Wait() fmt.Println(b.Balance()) } 不意外, 此时会再次出现竞争条件警告, 因为同时对 balance 去做读写操作会相互影响, 当然会跳出 race condition 警告\n$ go run -race main.go ================== WARNING: DATA RACE Read at 0x00c00012a080 by goroutine 56: main.(*Bank).Balance() .../main.go:20 +0x3c main.main.func2() .../main.go:39 +0x37 Previous write at 0x00c00012a080 by goroutine 53: main.(*Bank).Deposit() .../main.go:15 +0x5d main.main.func1() .../main.go:32 +0x3e Goroutine 56 (running) created at: main.main() .../main.go:38 +0x184 Goroutine 53 (finished) created at: main.main() .../main.go:31 +0xa4 ================== 1000000 Found 1 data race(s) exit status 66 我们一样在 Balance() 加上 Lock() 和 Unlock() 后执行\ntype Bank struct { balance int mux sync.Mutex } func (b *Bank) Deposit(amount int) { b.mux.Lock() b.balance += amount b.mux.Unlock() } func (b *Bank) Balance() (balance int) { b.mux.Lock() balance = b.balance b.mux.Unlock() return } 运行结果\n$ go run -race main.go 1000000 结果成功了, 也没有 race 的警告了\n读写互相阻塞\r目前看起来都还不错, 但以现在的情况来说, 只要有人读, 或只要有人写, 就会被 block\n假如银行每次存款和查询都需要 1 秒钟\npackage main import ( \u0026#34;log\u0026#34; \u0026#34;sync\u0026#34; \u0026#34;time\u0026#34; ) type Bank struct { balance int mux sync.Mutex } func (b *Bank) Deposit(amount int) { b.mux.Lock() time.Sleep(time.Second) // spend 1 second b.balance += amount b.mux.Unlock() } func (b *Bank) Balance() (balance int) { b.mux.Lock() time.Sleep(time.Second) // spend 1 second balance = b.balance b.mux.Unlock() return } func main() { var wg sync.WaitGroup b := \u0026amp;Bank{} n := 5 wg.Add(n) for i := 1; i \u0026lt;= n; i++ { go func() { b.Deposit(1000) log.Printf(\u0026#34;Write: deposit amonut: %v\u0026#34;, 1000) wg.Done() }() } wg.Add(n) for i := 1; i \u0026lt;= n; i++ { go func() { log.Printf(\u0026#34;Read: balance: %v\u0026#34;, b.Balance()) wg.Done() }() } wg.Wait() } 运行结果\n$ go run -race main.go 2022/02/18 15:12:49 Write: deposit amonut: 1000 2022/02/18 15:12:50 Write: deposit amonut: 1000 2022/02/18 15:12:51 Write: deposit amonut: 1000 2022/02/18 15:12:52 Write: deposit amonut: 1000 2022/02/18 15:12:53 Write: deposit amonut: 1000 2022/02/18 15:12:54 Read: balance: 5000 2022/02/18 15:12:55 Read: balance: 5000 2022/02/18 15:12:56 Read: balance: 5000 2022/02/18 15:12:57 Read: balance: 5000 2022/02/18 15:12:58 Read: balance: 5000 就会发现, 每隔 1 秒才能处理一个操作, 5 次存款和 5 次查询总共需要 10 秒。但对读来说, 应该可以疯狂读, 每次读都会是安全的, 值也都会是一样, 除非当下有写的动作, 它不应该被读的动作 block\n优化: 使用 sync.RWMutex\rsync.RWMutex 是一个读写锁 (multiple readers, single writer lock), 多读单写, 允许多个读操作并发, 但写操作仍然是独占的。\n把 sync.Mutex 换成 sync.RWMutex\ntype Bank struct { balance int mux sync.RWMutex // read write lock } func (b *Bank) Deposit(amount int) { b.mux.Lock() // write lock time.Sleep(time.Second) b.balance += amount b.mux.Unlock() // wirte unlock } func (b *Bank) Balance() (balance int) { b.mux.RLock() // read lock time.Sleep(time.Second) balance = b.balance b.mux.RUnlock() // read unlock return } 运行后, 读操作可以并发执行, 显著提高了性能\n$ go run -race main.go 2022/02/18 15:16:29 Write: deposit amonut: 1000 2022/02/18 15:16:30 Read: balance: 1000 2022/02/18 15:16:30 Read: balance: 1000 2022/02/18 15:16:30 Read: balance: 1000 2022/02/18 15:16:30 Read: balance: 1000 2022/02/18 15:16:30 Read: balance: 1000 2022/02/18 15:16:31 Write: deposit amonut: 1000 2022/02/18 15:16:32 Write: deposit amonut: 1000 2022/02/18 15:16:33 Write: deposit amonut: 1000 2022/02/18 15:16:34 Write: deposit amonut: 1000 执行之后会发现, 本来要花 10 秒, 已经缩短到 5 秒了, 只要当下是读的时候, 都会同时进行, 并不会互相影响, 写的时候就会 block 读和写, 只有一个写会发生。\n总结\r在写 goroutine 的时候, 需要考虑 race condition, 在执行或测试上可以加上 -race 去检查, 以免结果与预期不符 使用 sync.Mutex 可以解决竞争条件, 但读写操作会互相阻塞 使用 sync.RWMutex 可以提升性能, 允许多个读操作同时进行, 但写操作仍会阻塞所有读写 go Benchmark\ratomutex_test.go Benchmark: sync.RWMutex vs atomic.Value\n/* Benchmark_RWMutex-4 100000000\t18.1 ns/op Benchmark_Atomic-4 200000000\t8.01 ns/op Benchmark_RWMutex_parallel-4 30000000\t46.7 ns/op Benchmark_Atomic_parallel-4 1000000000\t2.61 ns/op */ package main import ( \u0026#34;sync\u0026#34; \u0026#34;sync/atomic\u0026#34; \u0026#34;testing\u0026#34; ) func Benchmark_RWMutex(b *testing.B) { var lock sync.RWMutex m := map[int]int{1: 2} for i := 0; i \u0026lt; b.N; i++ { lock.RLock() _ = m[1] lock.RUnlock() } } func Benchmark_Atomic(b *testing.B) { var ptr atomic.Value ptr.Store(map[int]int{1: 2}) for i := 0; i \u0026lt; b.N; i++ { m := ptr.Load().(map[int]int) _ = m[1] } } func Benchmark_RWMutex_parallel(b *testing.B) { var lock sync.RWMutex m := map[int]int{1: 2} b.RunParallel(func(pb *testing.PB) { for pb.Next() { lock.RLock() _ = m[1] lock.RUnlock() } }) } func Benchmark_Atomic_parallel(b *testing.B) { var ptr atomic.Value ptr.Store(map[int]int{1: 2}) b.RunParallel(func(pb *testing.PB) { for pb.Next() { m := ptr.Load().(map[int]int) _ = m[1] } }) } 运行结果\n$ go mod init benchmark $ go test -cpu 1,2,4,8,36 -bench . goos: windows goarch: amd64 pkg: benchmark cpu: Intel(R) Core(TM) i9-10980XE CPU @ 3.00GHz Benchmark_RWMutex 84223528 14.31 ns/op Benchmark_RWMutex-2 82506548 14.48 ns/op Benchmark_RWMutex-4 80424642 14.46 ns/op Benchmark_RWMutex-8 82474226 14.82 ns/op Benchmark_RWMutex-36 72245634 14.67 ns/op Benchmark_Atomic 298416230 4.013 ns/op Benchmark_Atomic-2 294261531 4.014 ns/op Benchmark_Atomic-4 298208067 4.050 ns/op Benchmark_Atomic-8 278849458 4.110 ns/op Benchmark_Atomic-36 289697505 4.060 ns/op Benchmark_RWMutex_parallel 82412020 14.31 ns/op Benchmark_RWMutex_parallel-2 39356391 30.50 ns/op Benchmark_RWMutex_parallel-4 37746673 31.62 ns/op Benchmark_RWMutex_parallel-8 38003095 31.19 ns/op Benchmark_RWMutex_parallel-36 41561199 28.36 ns/op Benchmark_Atomic_parallel 297627019 4.096 ns/op Benchmark_Atomic_parallel-2 566516064 2.016 ns/op Benchmark_Atomic_parallel-4 1000000000 1.029 ns/op Benchmark_Atomic_parallel-8 1000000000 0.5073 ns/op Benchmark_Atomic_parallel-36 100000000 14.80 ns/op PASS ok benchmark 29.463s 原文\nGo 簡單例子來理解 sync.Mutex 和 sync.RWMutex\nsync.RWMutex\natomutex_test.go\n","date":"2022-02-18T14:34:00+08:00","permalink":"https://blog.acesheep.com/p/go-mutex-vs-rwmutex/","title":"Go 简单例子来理解 sync.Mutex 和 sync.RWMutex"},{"content":"在退掉独立服务器之前, 为了防止数据被恢复, 可以选择安全擦除硬盘上的数据。以下是两种常见的方法: shred 和 dd。建议使用 Live CD 进行操作, 以避免系统占用硬盘导致擦除不完全。\n方法一: 使用 shred\rshred 工具通过多次随机数据覆盖文件或整个设备中的数据, 使数据几乎无法恢复。shred 对某些文件系统 (如日志型文件系统) 和硬件 (如 SSD) 可能无法完全擦除数据。\n操作步骤\r识别设备名称\n使用以下命令列出所有连接的存储设备, 找到需要擦除的硬盘设备 (如 /dev/sdb 或 /dev/hdb, 而非分区 /dev/sdb1)\nsudo fdisk -l 执行擦除\n注意: 确保选择正确的设备, 误操作可能导致重要数据丢失\n使用 shred 对设备进行多次随机数据覆盖。此命令默认往磁盘中写入 3 次随机数据。\nshred -v /dev/sdX 我使用这样的命令, 一共写入4次, 前三次使用随机数写入, 第四次写入零。-v 可以打印当前进度, -z 最后一次覆盖之后把整个盘写零\nroot@rescue ~ # shred -vfz /dev/sda shred: /dev/sda: pass 4/4 (000000)...5.0TiB/5.5TiB 91% shred: /dev/sda: pass 4/4 (000000)...5.1TiB/5.5TiB 93% shred: /dev/sda: pass 4/4 (000000)...5.2TiB/5.5TiB 95% shred: /dev/sda: pass 4/4 (000000)...5.3TiB/5.5TiB 97% shred: /dev/sda: pass 4/4 (000000)...5.4TiB/5.5TiB 99% shred: /dev/sda: pass 4/4 (000000)...5.5TiB/5.5TiB 100% 帮助文档\rroot@rescue ~ # shred --help Usage: shred [OPTION]... FILE... Overwrite the specified FILE(s) repeatedly, in order to make it harder for even very expensive hardware probing to recover the data. If FILE is -, shred standard output. Mandatory arguments to long options are mandatory for short options too. -f, --force change permissions to allow writing if necessary -n, --iterations=N overwrite N times instead of the default (3) --random-source=FILE get random bytes from FILE -s, --size=N shred this many bytes (suffixes like K, M, G accepted) -u deallocate and remove file after overwriting --remove[=HOW] like -u but give control on HOW to delete; See below -v, --verbose show progress -x, --exact do not round file sizes up to the next full block; this is the default for non-regular files -z, --zero add a final overwrite with zeros to hide shredding --help display this help and exit --version output version information and exit Delete FILE(s) if --remove (-u) is specified. The default is not to remove the files because it is common to operate on device files like /dev/hda, and those files usually should not be removed. The optional HOW parameter indicates how to remove a directory entry: \u0026#39;unlink\u0026#39; =\u0026gt; use a standard unlink call. \u0026#39;wipe\u0026#39; =\u0026gt; also first obfuscate bytes in the name. \u0026#39;wipesync\u0026#39; =\u0026gt; also sync each obfuscated byte to disk. The default mode is \u0026#39;wipesync\u0026#39;, but note it can be expensive. CAUTION: shred assumes the file system and hardware overwrite data in place. Although this is common, many platforms operate otherwise. Also, backups and mirrors may contain unremovable copies that will let a shredded file be recovered later. See the GNU coreutils manual for details. GNU coreutils online help: \u0026lt;https://www.gnu.org/software/coreutils/\u0026gt; Full documentation \u0026lt;https://www.gnu.org/software/coreutils/shred\u0026gt; or available locally via: info \u0026#39;(coreutils) shred invocation\u0026#39; 方法二: 使用 dd\rdd 是一个功能强大的数据复制工具, 可以将随机数据或零填充整个设备。\n# 使用零填充 dd if=/dev/zero of=/dev/hdX bs=1M # 使用随机数据覆盖 # 如果熵池耗尽随机数生成会阻塞 dd if=/dev/random of=/dev/hdX bs=1M # 使用随机数据覆盖 # 使用 urandom 设备, 不会因熵池耗尽而阻塞 dd if=/dev/urandom of=/dev/hdX bs=1M 原文\nHow can I securely erase a hard drive?\n","date":"2022-02-13T08:34:00+08:00","permalink":"https://blog.acesheep.com/p/linux-securely-erase-hard-drive/","title":"Linux 中安全地擦除机械硬盘"},{"content":"在 Linux 中, 直接使用 chmod -R 777 递归更改目录权限虽然可以快速解决权限问题, 但会同时赋予文件执行权限, 这种做法存在较大的安全隐患。短期来看确实解决了眼下问题, 万一有什么服务被攻破了, 具有执行权限的文件可能被用于运行恶意程序。因此, 为了安全起见, 我们需要一种方法只修改文件夹的权限, 而不影响文件的权限。\n递归修改权限\r递归修改文件夹权限\r文件夹的执行权限相当于允许进入目录的权限。使用以下命令为文件夹设置权限\nfind /path/to/base/dir -type d -exec chmod 755 {} + 这会递归查找指定目录下的所有文件夹, 并将它们的权限设置为 755 (可读、可写、可执行)\n递归修改文件权限\r使用以下命令为文件设置权限\nfind /path/to/base/dir -type f -exec chmod 644 {} + 这会递归查找指定目录下的所有文件, 并将它们的权限设置为 644 (可读、可写, 但不可执行)\n使用命令替代简化操作\r如果需要处理的对象较多, 可以使用以下方法\n方法 1: 直接传递给 chmod\r注意: 文件名中包含空格可能导致失败\nchmod 755 $(find /path/to/base/dir -type d) chmod 644 $(find /path/to/base/dir -type f) 方法 2: 结合 xargs 减少 chmod 调用次数\r适用于文件特别多的情况\nfind /path/to/base/dir -type d -print0 | xargs -0 chmod 755 find /path/to/base/dir -type f -print0 | xargs -0 chmod 644 在这里, -print0 和 xargs -0 的组合能够安全处理文件名中包含空格或特殊字符的情况\n原文\nHow to recursively chmod all directories except files?\n","date":"2022-02-06T15:22:00+08:00","permalink":"https://blog.acesheep.com/p/linux-chmod-folder-755-file-644/","title":"Linux chmod 高级用法 设置文件夹 755 文件 644"},{"content":"每一种 umask 对应的权限\r以下是每个 umask (user file-creatiopn mode mask) 和对应的权限列表\numask 文件权限 文件夹权限 000 rw-rw-rw- rwxrwxrwx 001 rw-rw-rw- rwxrwxrw- 002 rw-rw-r\u0026ndash; rwxrwxr-x 003 rw-rw-r\u0026ndash; rwxrwxr\u0026ndash; 004 rw-rw\u0026ndash;w- rwxrwx-wx 005 rw-rw\u0026ndash;w- rwxrwx-w- 006 rw-rw\u0026mdash;- rwxrwx\u0026ndash;x 007 rw-rw\u0026mdash;- rwxrwx\u0026mdash; 010 rw-rw-rw- rwxrw-rwx 011 rw-rw-rw- rwxrw-rw- 012 rw-rw-r\u0026ndash; rwxrw-r-x 013 rw-rw-r\u0026ndash; rwxrw-r\u0026ndash; 014 rw-rw\u0026ndash;w- rwxrw\u0026ndash;wx 015 rw-rw\u0026ndash;w- rwxrw\u0026ndash;w- 016 rw-rw\u0026mdash;- rwxrw\u0026mdash;x 017 rw-rw\u0026mdash;- rwxrw\u0026mdash;- 020 rw-r\u0026ndash;rw- rwxr-xrwx 021 rw-r\u0026ndash;rw- rwxr-xrw- 022 rw-r\u0026ndash;r\u0026ndash; rwxr-xr-x 023 rw-r\u0026ndash;r\u0026ndash; rwxr-xr\u0026ndash; 024 rw-r\u0026mdash;w- rwxr-x-wx 025 rw-r\u0026mdash;w- rwxr-x-w- 026 rw-r\u0026mdash;\u0026ndash; rwxr-x\u0026ndash;x 027 rw-r\u0026mdash;\u0026ndash; rwxr-x\u0026mdash; 030 rw-r\u0026ndash;rw- rwxr\u0026ndash;rwx 031 rw-r\u0026ndash;rw- rwxr\u0026ndash;rw- 032 rw-r\u0026ndash;r\u0026ndash; rwxr\u0026ndash;r-x 033 rw-r\u0026ndash;r\u0026ndash; rwxr\u0026ndash;r\u0026ndash; 034 rw-r\u0026mdash;w- rwxr\u0026mdash;wx 035 rw-r\u0026mdash;w- rwxr\u0026mdash;w- 036 rw-r\u0026mdash;\u0026ndash; rwxr\u0026mdash;-x 037 rw-r\u0026mdash;\u0026ndash; rwxr\u0026mdash;\u0026ndash; 040 rw\u0026ndash;w-rw- rwx-wxrwx 041 rw\u0026ndash;w-rw- rwx-wxrw- 042 rw\u0026ndash;w-r\u0026ndash; rwx-wxr-x 043 rw\u0026ndash;w-r\u0026ndash; rwx-wxr\u0026ndash; 044 rw\u0026ndash;w\u0026ndash;w- rwx-wx-wx 045 rw\u0026ndash;w\u0026ndash;w- rwx-wx-w- 046 rw\u0026ndash;w\u0026mdash;- rwx-wx\u0026ndash;x 047 rw\u0026ndash;w\u0026mdash;- rwx-wx\u0026mdash; 050 rw\u0026ndash;w-rw- rwx-w-rwx 051 rw\u0026ndash;w-rw- rwx-w-rw- 052 rw\u0026ndash;w-r\u0026ndash; rwx-w-r-x 053 rw\u0026ndash;w-r\u0026ndash; rwx-w-r\u0026ndash; 054 rw\u0026ndash;w\u0026ndash;w- rwx-w\u0026ndash;wx 055 rw\u0026ndash;w\u0026ndash;w- rwx-w\u0026ndash;w- 056 rw\u0026ndash;w\u0026mdash;- rwx-w\u0026mdash;x 057 rw\u0026ndash;w\u0026mdash;- rwx-w\u0026mdash;- 060 rw\u0026mdash;-rw- rwx\u0026ndash;xrwx 061 rw\u0026mdash;-rw- rwx\u0026ndash;xrw- 062 rw\u0026mdash;-r\u0026ndash; rwx\u0026ndash;xr-x 063 rw\u0026mdash;-r\u0026ndash; rwx\u0026ndash;xr\u0026ndash; 064 rw\u0026mdash;\u0026ndash;w- rwx\u0026ndash;x-wx 065 rw\u0026mdash;\u0026ndash;w- rwx\u0026ndash;x-w- 066 rw\u0026mdash;\u0026mdash;- rwx\u0026ndash;x\u0026ndash;x 067 rw\u0026mdash;\u0026mdash;- rwx\u0026ndash;x\u0026mdash; 070 rw\u0026mdash;-rw- rwx\u0026mdash;rwx 071 rw\u0026mdash;-rw- rwx\u0026mdash;rw- 072 rw\u0026mdash;-r\u0026ndash; rwx\u0026mdash;r-x 073 rw\u0026mdash;-r\u0026ndash; rwx\u0026mdash;r\u0026ndash; 074 rw\u0026mdash;\u0026ndash;w- rwx\u0026mdash;-wx 075 rw\u0026mdash;\u0026ndash;w- rwx\u0026mdash;-w- 076 rw\u0026mdash;\u0026mdash;- rwx\u0026mdash;\u0026ndash;x 077 rw\u0026mdash;\u0026mdash;- rwx\u0026mdash;\u0026mdash; 100 rw-rw-rw- rw-rwxrwx 101 rw-rw-rw- rw-rwxrw- 102 rw-rw-r\u0026ndash; rw-rwxr-x 103 rw-rw-r\u0026ndash; rw-rwxr\u0026ndash; 104 rw-rw\u0026ndash;w- rw-rwx-wx 105 rw-rw\u0026ndash;w- rw-rwx-w- 106 rw-rw\u0026mdash;- rw-rwx\u0026ndash;x 107 rw-rw\u0026mdash;- rw-rwx\u0026mdash; 110 rw-rw-rw- rw-rw-rwx 111 rw-rw-rw- rw-rw-rw- 112 rw-rw-r\u0026ndash; rw-rw-r-x 113 rw-rw-r\u0026ndash; rw-rw-r\u0026ndash; 114 rw-rw\u0026ndash;w- rw-rw\u0026ndash;wx 115 rw-rw\u0026ndash;w- rw-rw\u0026ndash;w- 116 rw-rw\u0026mdash;- rw-rw\u0026mdash;x 117 rw-rw\u0026mdash;- rw-rw\u0026mdash;- 120 rw-r\u0026ndash;rw- rw-r-xrwx 121 rw-r\u0026ndash;rw- rw-r-xrw- 122 rw-r\u0026ndash;r\u0026ndash; rw-r-xr-x 123 rw-r\u0026ndash;r\u0026ndash; rw-r-xr\u0026ndash; 124 rw-r\u0026mdash;w- rw-r-x-wx 125 rw-r\u0026mdash;w- rw-r-x-w- 126 rw-r\u0026mdash;\u0026ndash; rw-r-x\u0026ndash;x 127 rw-r\u0026mdash;\u0026ndash; rw-r-x\u0026mdash; 130 rw-r\u0026ndash;rw- rw-r\u0026ndash;rwx 131 rw-r\u0026ndash;rw- rw-r\u0026ndash;rw- 132 rw-r\u0026ndash;r\u0026ndash; rw-r\u0026ndash;r-x 133 rw-r\u0026ndash;r\u0026ndash; rw-r\u0026ndash;r\u0026ndash; 134 rw-r\u0026mdash;w- rw-r\u0026mdash;wx 135 rw-r\u0026mdash;w- rw-r\u0026mdash;w- 136 rw-r\u0026mdash;\u0026ndash; rw-r\u0026mdash;-x 137 rw-r\u0026mdash;\u0026ndash; rw-r\u0026mdash;\u0026ndash; 140 rw\u0026ndash;w-rw- rw\u0026ndash;wxrwx 141 rw\u0026ndash;w-rw- rw\u0026ndash;wxrw- 142 rw\u0026ndash;w-r\u0026ndash; rw\u0026ndash;wxr-x 143 rw\u0026ndash;w-r\u0026ndash; rw\u0026ndash;wxr\u0026ndash; 144 rw\u0026ndash;w\u0026ndash;w- rw\u0026ndash;wx-wx 145 rw\u0026ndash;w\u0026ndash;w- rw\u0026ndash;wx-w- 146 rw\u0026ndash;w\u0026mdash;- rw\u0026ndash;wx\u0026ndash;x 147 rw\u0026ndash;w\u0026mdash;- rw\u0026ndash;wx\u0026mdash; 150 rw\u0026ndash;w-rw- rw\u0026ndash;w-rwx 151 rw\u0026ndash;w-rw- rw\u0026ndash;w-rw- 152 rw\u0026ndash;w-r\u0026ndash; rw\u0026ndash;w-r-x 153 rw\u0026ndash;w-r\u0026ndash; rw\u0026ndash;w-r\u0026ndash; 154 rw\u0026ndash;w\u0026ndash;w- rw\u0026ndash;w\u0026ndash;wx 155 rw\u0026ndash;w\u0026ndash;w- rw\u0026ndash;w\u0026ndash;w- 156 rw\u0026ndash;w\u0026mdash;- rw\u0026ndash;w\u0026mdash;x 157 rw\u0026ndash;w\u0026mdash;- rw\u0026ndash;w\u0026mdash;- 160 rw\u0026mdash;-rw- rw\u0026mdash;xrwx 161 rw\u0026mdash;-rw- rw\u0026mdash;xrw- 162 rw\u0026mdash;-r\u0026ndash; rw\u0026mdash;xr-x 163 rw\u0026mdash;-r\u0026ndash; rw\u0026mdash;xr\u0026ndash; 164 rw\u0026mdash;\u0026ndash;w- rw\u0026mdash;x-wx 165 rw\u0026mdash;\u0026ndash;w- rw\u0026mdash;x-w- 166 rw\u0026mdash;\u0026mdash;- rw\u0026mdash;x\u0026ndash;x 167 rw\u0026mdash;\u0026mdash;- rw\u0026mdash;x\u0026mdash; 170 rw\u0026mdash;-rw- rw\u0026mdash;-rwx 171 rw\u0026mdash;-rw- rw\u0026mdash;-rw- 172 rw\u0026mdash;-r\u0026ndash; rw\u0026mdash;-r-x 173 rw\u0026mdash;-r\u0026ndash; rw\u0026mdash;-r\u0026ndash; 174 rw\u0026mdash;\u0026ndash;w- rw\u0026mdash;\u0026ndash;wx 175 rw\u0026mdash;\u0026ndash;w- rw\u0026mdash;\u0026ndash;w- 176 rw\u0026mdash;\u0026mdash;- rw\u0026mdash;\u0026mdash;x 177 rw\u0026mdash;\u0026mdash;- rw\u0026mdash;\u0026mdash;- 200 r\u0026ndash;rw-rw- r-xrwxrwx 201 r\u0026ndash;rw-rw- r-xrwxrw- 202 r\u0026ndash;rw-r\u0026ndash; r-xrwxr-x 203 r\u0026ndash;rw-r\u0026ndash; r-xrwxr\u0026ndash; 204 r\u0026ndash;rw\u0026ndash;w- r-xrwx-wx 205 r\u0026ndash;rw\u0026ndash;w- r-xrwx-w- 206 r\u0026ndash;rw\u0026mdash;- r-xrwx\u0026ndash;x 207 r\u0026ndash;rw\u0026mdash;- r-xrwx\u0026mdash; 210 r\u0026ndash;rw-rw- r-xrw-rwx 211 r\u0026ndash;rw-rw- r-xrw-rw- 212 r\u0026ndash;rw-r\u0026ndash; r-xrw-r-x 213 r\u0026ndash;rw-r\u0026ndash; r-xrw-r\u0026ndash; 214 r\u0026ndash;rw\u0026ndash;w- r-xrw\u0026ndash;wx 215 r\u0026ndash;rw\u0026ndash;w- r-xrw\u0026ndash;w- 216 r\u0026ndash;rw\u0026mdash;- r-xrw\u0026mdash;x 217 r\u0026ndash;rw\u0026mdash;- r-xrw\u0026mdash;- 220 r\u0026ndash;r\u0026ndash;rw- r-xr-xrwx 221 r\u0026ndash;r\u0026ndash;rw- r-xr-xrw- 222 r\u0026ndash;r\u0026ndash;r\u0026ndash; r-xr-xr-x 223 r\u0026ndash;r\u0026ndash;r\u0026ndash; r-xr-xr\u0026ndash; 224 r\u0026ndash;r\u0026mdash;w- r-xr-x-wx 225 r\u0026ndash;r\u0026mdash;w- r-xr-x-w- 226 r\u0026ndash;r\u0026mdash;\u0026ndash; r-xr-x\u0026ndash;x 227 r\u0026ndash;r\u0026mdash;\u0026ndash; r-xr-x\u0026mdash; 230 r\u0026ndash;r\u0026ndash;rw- r-xr\u0026ndash;rwx 231 r\u0026ndash;r\u0026ndash;rw- r-xr\u0026ndash;rw- 232 r\u0026ndash;r\u0026ndash;r\u0026ndash; r-xr\u0026ndash;r-x 233 r\u0026ndash;r\u0026ndash;r\u0026ndash; r-xr\u0026ndash;r\u0026ndash; 234 r\u0026ndash;r\u0026mdash;w- r-xr\u0026mdash;wx 235 r\u0026ndash;r\u0026mdash;w- r-xr\u0026mdash;w- 236 r\u0026ndash;r\u0026mdash;\u0026ndash; r-xr\u0026mdash;-x 237 r\u0026ndash;r\u0026mdash;\u0026ndash; r-xr\u0026mdash;\u0026ndash; 240 r\u0026mdash;w-rw- r-x-wxrwx 241 r\u0026mdash;w-rw- r-x-wxrw- 242 r\u0026mdash;w-r\u0026ndash; r-x-wxr-x 243 r\u0026mdash;w-r\u0026ndash; r-x-wxr\u0026ndash; 244 r\u0026mdash;w\u0026ndash;w- r-x-wx-wx 245 r\u0026mdash;w\u0026ndash;w- r-x-wx-w- 246 r\u0026mdash;w\u0026mdash;- r-x-wx\u0026ndash;x 247 r\u0026mdash;w\u0026mdash;- r-x-wx\u0026mdash; 250 r\u0026mdash;w-rw- r-x-w-rwx 251 r\u0026mdash;w-rw- r-x-w-rw- 252 r\u0026mdash;w-r\u0026ndash; r-x-w-r-x 253 r\u0026mdash;w-r\u0026ndash; r-x-w-r\u0026ndash; 254 r\u0026mdash;w\u0026ndash;w- r-x-w\u0026ndash;wx 255 r\u0026mdash;w\u0026ndash;w- r-x-w\u0026ndash;w- 256 r\u0026mdash;w\u0026mdash;- r-x-w\u0026mdash;x 257 r\u0026mdash;w\u0026mdash;- r-x-w\u0026mdash;- 260 r\u0026mdash;\u0026ndash;rw- r-x\u0026ndash;xrwx 261 r\u0026mdash;\u0026ndash;rw- r-x\u0026ndash;xrw- 262 r\u0026mdash;\u0026ndash;r\u0026ndash; r-x\u0026ndash;xr-x 263 r\u0026mdash;\u0026ndash;r\u0026ndash; r-x\u0026ndash;xr\u0026ndash; 264 r\u0026mdash;\u0026mdash;w- r-x\u0026ndash;x-wx 265 r\u0026mdash;\u0026mdash;w- r-x\u0026ndash;x-w- 266 r\u0026mdash;\u0026mdash;\u0026ndash; r-x\u0026ndash;x\u0026ndash;x 267 r\u0026mdash;\u0026mdash;\u0026ndash; r-x\u0026ndash;x\u0026mdash; 270 r\u0026mdash;\u0026ndash;rw- r-x\u0026mdash;rwx 271 r\u0026mdash;\u0026ndash;rw- r-x\u0026mdash;rw- 272 r\u0026mdash;\u0026ndash;r\u0026ndash; r-x\u0026mdash;r-x 273 r\u0026mdash;\u0026ndash;r\u0026ndash; r-x\u0026mdash;r\u0026ndash; 274 r\u0026mdash;\u0026mdash;w- r-x\u0026mdash;-wx 275 r\u0026mdash;\u0026mdash;w- r-x\u0026mdash;-w- 276 r\u0026mdash;\u0026mdash;\u0026ndash; r-x\u0026mdash;\u0026ndash;x 277 r\u0026mdash;\u0026mdash;\u0026ndash; r-x\u0026mdash;\u0026mdash; 300 r\u0026ndash;rw-rw- r\u0026ndash;rwxrwx 301 r\u0026ndash;rw-rw- r\u0026ndash;rwxrw- 302 r\u0026ndash;rw-r\u0026ndash; r\u0026ndash;rwxr-x 303 r\u0026ndash;rw-r\u0026ndash; r\u0026ndash;rwxr\u0026ndash; 304 r\u0026ndash;rw\u0026ndash;w- r\u0026ndash;rwx-wx 305 r\u0026ndash;rw\u0026ndash;w- r\u0026ndash;rwx-w- 306 r\u0026ndash;rw\u0026mdash;- r\u0026ndash;rwx\u0026ndash;x 307 r\u0026ndash;rw\u0026mdash;- r\u0026ndash;rwx\u0026mdash; 310 r\u0026ndash;rw-rw- r\u0026ndash;rw-rwx 311 r\u0026ndash;rw-rw- r\u0026ndash;rw-rw- 312 r\u0026ndash;rw-r\u0026ndash; r\u0026ndash;rw-r-x 313 r\u0026ndash;rw-r\u0026ndash; r\u0026ndash;rw-r\u0026ndash; 314 r\u0026ndash;rw\u0026ndash;w- r\u0026ndash;rw\u0026ndash;wx 315 r\u0026ndash;rw\u0026ndash;w- r\u0026ndash;rw\u0026ndash;w- 316 r\u0026ndash;rw\u0026mdash;- r\u0026ndash;rw\u0026mdash;x 317 r\u0026ndash;rw\u0026mdash;- r\u0026ndash;rw\u0026mdash;- 320 r\u0026ndash;r\u0026ndash;rw- r\u0026ndash;r-xrwx 321 r\u0026ndash;r\u0026ndash;rw- r\u0026ndash;r-xrw- 322 r\u0026ndash;r\u0026ndash;r\u0026ndash; r\u0026ndash;r-xr-x 323 r\u0026ndash;r\u0026ndash;r\u0026ndash; r\u0026ndash;r-xr\u0026ndash; 324 r\u0026ndash;r\u0026mdash;w- r\u0026ndash;r-x-wx 325 r\u0026ndash;r\u0026mdash;w- r\u0026ndash;r-x-w- 326 r\u0026ndash;r\u0026mdash;\u0026ndash; r\u0026ndash;r-x\u0026ndash;x 327 r\u0026ndash;r\u0026mdash;\u0026ndash; r\u0026ndash;r-x\u0026mdash; 330 r\u0026ndash;r\u0026ndash;rw- r\u0026ndash;r\u0026ndash;rwx 331 r\u0026ndash;r\u0026ndash;rw- r\u0026ndash;r\u0026ndash;rw- 332 r\u0026ndash;r\u0026ndash;r\u0026ndash; r\u0026ndash;r\u0026ndash;r-x 333 r\u0026ndash;r\u0026ndash;r\u0026ndash; r\u0026ndash;r\u0026ndash;r\u0026ndash; 334 r\u0026ndash;r\u0026mdash;w- r\u0026ndash;r\u0026mdash;wx 335 r\u0026ndash;r\u0026mdash;w- r\u0026ndash;r\u0026mdash;w- 336 r\u0026ndash;r\u0026mdash;\u0026ndash; r\u0026ndash;r\u0026mdash;-x 337 r\u0026ndash;r\u0026mdash;\u0026ndash; r\u0026ndash;r\u0026mdash;\u0026ndash; 340 r\u0026mdash;w-rw- r\u0026mdash;wxrwx 341 r\u0026mdash;w-rw- r\u0026mdash;wxrw- 342 r\u0026mdash;w-r\u0026ndash; r\u0026mdash;wxr-x 343 r\u0026mdash;w-r\u0026ndash; r\u0026mdash;wxr\u0026ndash; 344 r\u0026mdash;w\u0026ndash;w- r\u0026mdash;wx-wx 345 r\u0026mdash;w\u0026ndash;w- r\u0026mdash;wx-w- 346 r\u0026mdash;w\u0026mdash;- r\u0026mdash;wx\u0026ndash;x 347 r\u0026mdash;w\u0026mdash;- r\u0026mdash;wx\u0026mdash; 350 r\u0026mdash;w-rw- r\u0026mdash;w-rwx 351 r\u0026mdash;w-rw- r\u0026mdash;w-rw- 352 r\u0026mdash;w-r\u0026ndash; r\u0026mdash;w-r-x 353 r\u0026mdash;w-r\u0026ndash; r\u0026mdash;w-r\u0026ndash; 354 r\u0026mdash;w\u0026ndash;w- r\u0026mdash;w\u0026ndash;wx 355 r\u0026mdash;w\u0026ndash;w- r\u0026mdash;w\u0026ndash;w- 356 r\u0026mdash;w\u0026mdash;- r\u0026mdash;w\u0026mdash;x 357 r\u0026mdash;w\u0026mdash;- r\u0026mdash;w\u0026mdash;- 360 r\u0026mdash;\u0026ndash;rw- r\u0026mdash;-xrwx 361 r\u0026mdash;\u0026ndash;rw- r\u0026mdash;-xrw- 362 r\u0026mdash;\u0026ndash;r\u0026ndash; r\u0026mdash;-xr-x 363 r\u0026mdash;\u0026ndash;r\u0026ndash; r\u0026mdash;-xr\u0026ndash; 364 r\u0026mdash;\u0026mdash;w- r\u0026mdash;-x-wx 365 r\u0026mdash;\u0026mdash;w- r\u0026mdash;-x-w- 366 r\u0026mdash;\u0026mdash;\u0026ndash; r\u0026mdash;-x\u0026ndash;x 367 r\u0026mdash;\u0026mdash;\u0026ndash; r\u0026mdash;-x\u0026mdash; 370 r\u0026mdash;\u0026ndash;rw- r\u0026mdash;\u0026ndash;rwx 371 r\u0026mdash;\u0026ndash;rw- r\u0026mdash;\u0026ndash;rw- 372 r\u0026mdash;\u0026ndash;r\u0026ndash; r\u0026mdash;\u0026ndash;r-x 373 r\u0026mdash;\u0026ndash;r\u0026ndash; r\u0026mdash;\u0026ndash;r\u0026ndash; 374 r\u0026mdash;\u0026mdash;w- r\u0026mdash;\u0026mdash;wx 375 r\u0026mdash;\u0026mdash;w- r\u0026mdash;\u0026mdash;w- 376 r\u0026mdash;\u0026mdash;\u0026ndash; r\u0026mdash;\u0026mdash;-x 377 r\u0026mdash;\u0026mdash;\u0026ndash; r\u0026mdash;\u0026mdash;\u0026ndash; 400 -w-rw-rw- -wxrwxrwx 401 -w-rw-rw- -wxrwxrw- 402 -w-rw-r\u0026ndash; -wxrwxr-x 403 -w-rw-r\u0026ndash; -wxrwxr\u0026ndash; 404 -w-rw\u0026ndash;w- -wxrwx-wx 405 -w-rw\u0026ndash;w- -wxrwx-w- 406 -w-rw\u0026mdash;- -wxrwx\u0026ndash;x 407 -w-rw\u0026mdash;- -wxrwx\u0026mdash; 410 -w-rw-rw- -wxrw-rwx 411 -w-rw-rw- -wxrw-rw- 412 -w-rw-r\u0026ndash; -wxrw-r-x 413 -w-rw-r\u0026ndash; -wxrw-r\u0026ndash; 414 -w-rw\u0026ndash;w- -wxrw\u0026ndash;wx 415 -w-rw\u0026ndash;w- -wxrw\u0026ndash;w- 416 -w-rw\u0026mdash;- -wxrw\u0026mdash;x 417 -w-rw\u0026mdash;- -wxrw\u0026mdash;- 420 -w-r\u0026ndash;rw- -wxr-xrwx 421 -w-r\u0026ndash;rw- -wxr-xrw- 422 -w-r\u0026ndash;r\u0026ndash; -wxr-xr-x 423 -w-r\u0026ndash;r\u0026ndash; -wxr-xr\u0026ndash; 424 -w-r\u0026mdash;w- -wxr-x-wx 425 -w-r\u0026mdash;w- -wxr-x-w- 426 -w-r\u0026mdash;\u0026ndash; -wxr-x\u0026ndash;x 427 -w-r\u0026mdash;\u0026ndash; -wxr-x\u0026mdash; 430 -w-r\u0026ndash;rw- -wxr\u0026ndash;rwx 431 -w-r\u0026ndash;rw- -wxr\u0026ndash;rw- 432 -w-r\u0026ndash;r\u0026ndash; -wxr\u0026ndash;r-x 433 -w-r\u0026ndash;r\u0026ndash; -wxr\u0026ndash;r\u0026ndash; 434 -w-r\u0026mdash;w- -wxr\u0026mdash;wx 435 -w-r\u0026mdash;w- -wxr\u0026mdash;w- 436 -w-r\u0026mdash;\u0026ndash; -wxr\u0026mdash;-x 437 -w-r\u0026mdash;\u0026ndash; -wxr\u0026mdash;\u0026ndash; 440 -w\u0026ndash;w-rw- -wx-wxrwx 441 -w\u0026ndash;w-rw- -wx-wxrw- 442 -w\u0026ndash;w-r\u0026ndash; -wx-wxr-x 443 -w\u0026ndash;w-r\u0026ndash; -wx-wxr\u0026ndash; 444 -w\u0026ndash;w\u0026ndash;w- -wx-wx-wx 445 -w\u0026ndash;w\u0026ndash;w- -wx-wx-w- 446 -w\u0026ndash;w\u0026mdash;- -wx-wx\u0026ndash;x 447 -w\u0026ndash;w\u0026mdash;- -wx-wx\u0026mdash; 450 -w\u0026ndash;w-rw- -wx-w-rwx 451 -w\u0026ndash;w-rw- -wx-w-rw- 452 -w\u0026ndash;w-r\u0026ndash; -wx-w-r-x 453 -w\u0026ndash;w-r\u0026ndash; -wx-w-r\u0026ndash; 454 -w\u0026ndash;w\u0026ndash;w- -wx-w\u0026ndash;wx 455 -w\u0026ndash;w\u0026ndash;w- -wx-w\u0026ndash;w- 456 -w\u0026ndash;w\u0026mdash;- -wx-w\u0026mdash;x 457 -w\u0026ndash;w\u0026mdash;- -wx-w\u0026mdash;- 460 -w\u0026mdash;-rw- -wx\u0026ndash;xrwx 461 -w\u0026mdash;-rw- -wx\u0026ndash;xrw- 462 -w\u0026mdash;-r\u0026ndash; -wx\u0026ndash;xr-x 463 -w\u0026mdash;-r\u0026ndash; -wx\u0026ndash;xr\u0026ndash; 464 -w\u0026mdash;\u0026ndash;w- -wx\u0026ndash;x-wx 465 -w\u0026mdash;\u0026ndash;w- -wx\u0026ndash;x-w- 466 -w\u0026mdash;\u0026mdash;- -wx\u0026ndash;x\u0026ndash;x 467 -w\u0026mdash;\u0026mdash;- -wx\u0026ndash;x\u0026mdash; 470 -w\u0026mdash;-rw- -wx\u0026mdash;rwx 471 -w\u0026mdash;-rw- -wx\u0026mdash;rw- 472 -w\u0026mdash;-r\u0026ndash; -wx\u0026mdash;r-x 473 -w\u0026mdash;-r\u0026ndash; -wx\u0026mdash;r\u0026ndash; 474 -w\u0026mdash;\u0026ndash;w- -wx\u0026mdash;-wx 475 -w\u0026mdash;\u0026ndash;w- -wx\u0026mdash;-w- 476 -w\u0026mdash;\u0026mdash;- -wx\u0026mdash;\u0026ndash;x 477 -w\u0026mdash;\u0026mdash;- -wx\u0026mdash;\u0026mdash; 500 -w-rw-rw- -w-rwxrwx 501 -w-rw-rw- -w-rwxrw- 502 -w-rw-r\u0026ndash; -w-rwxr-x 503 -w-rw-r\u0026ndash; -w-rwxr\u0026ndash; 504 -w-rw\u0026ndash;w- -w-rwx-wx 505 -w-rw\u0026ndash;w- -w-rwx-w- 506 -w-rw\u0026mdash;- -w-rwx\u0026ndash;x 507 -w-rw\u0026mdash;- -w-rwx\u0026mdash; 510 -w-rw-rw- -w-rw-rwx 511 -w-rw-rw- -w-rw-rw- 512 -w-rw-r\u0026ndash; -w-rw-r-x 513 -w-rw-r\u0026ndash; -w-rw-r\u0026ndash; 514 -w-rw\u0026ndash;w- -w-rw\u0026ndash;wx 515 -w-rw\u0026ndash;w- -w-rw\u0026ndash;w- 516 -w-rw\u0026mdash;- -w-rw\u0026mdash;x 517 -w-rw\u0026mdash;- -w-rw\u0026mdash;- 520 -w-r\u0026ndash;rw- -w-r-xrwx 521 -w-r\u0026ndash;rw- -w-r-xrw- 522 -w-r\u0026ndash;r\u0026ndash; -w-r-xr-x 523 -w-r\u0026ndash;r\u0026ndash; -w-r\u0026ndash;xr- 524 -w-r\u0026mdash;w- -w-r-x-wx 525 -w-r\u0026mdash;w- -w-r-x-w- 526 -w-r\u0026mdash;\u0026ndash; -w-r-x\u0026ndash;x 527 -w-r\u0026mdash;\u0026ndash; -w-r-x\u0026mdash; 530 -w-r\u0026ndash;rw- -w-r\u0026ndash;rwx 531 -w-r\u0026ndash;rw- -w-r\u0026ndash;rw- 532 -w-r\u0026ndash;r\u0026ndash; -w-r\u0026ndash;r-x 533 -w-r\u0026ndash;r\u0026ndash; -w-r\u0026ndash;r\u0026ndash; 534 -w-r\u0026mdash;w- -w-r\u0026mdash;wx 535 -w-r\u0026mdash;w- -w-r\u0026mdash;w- 536 -w-r\u0026mdash;\u0026ndash; -w-r\u0026mdash;-x 537 -w-r\u0026mdash;\u0026ndash; -w-r\u0026mdash;\u0026ndash; 540 -w\u0026ndash;w-rw- -w-rwxrwx 541 -w\u0026ndash;w-rw- -w-rwxrw- 542 -w\u0026ndash;w-r\u0026ndash; -w-rwxr-x 543 -w\u0026ndash;w-r\u0026ndash; -w-rwxr\u0026ndash; 544 -w\u0026ndash;w\u0026ndash;w- -w-rwx-wx 545 -w\u0026ndash;w\u0026ndash;w- -w-rwx-w- 546 -w\u0026ndash;w\u0026mdash;- -w-rwx\u0026ndash;x 547 -w\u0026ndash;w\u0026mdash;- -w-rwx\u0026mdash; 550 -w\u0026ndash;w-rw- -w-rw-rwx 551 -w\u0026ndash;w-rw- -w-rw-rw- 552 -w\u0026ndash;w-r\u0026ndash; -w-rw-r-x 553 -w\u0026ndash;w-r\u0026ndash; -w-rw-r\u0026ndash; 554 -w\u0026ndash;w\u0026ndash;w- -w-rw\u0026ndash;wx 555 -w\u0026ndash;w\u0026ndash;w- -w-rw\u0026ndash;w- 556 -w\u0026ndash;w\u0026mdash;- -w-rw\u0026mdash;x 557 -w\u0026ndash;w\u0026mdash;- -w-rw\u0026mdash;- 560 -w\u0026mdash;-rw- -w\u0026mdash;xrwx 561 -w\u0026mdash;-rw- -w\u0026mdash;xrw- 562 -w\u0026mdash;-r\u0026ndash; -w\u0026mdash;xr-x 563 -w\u0026mdash;-r\u0026ndash; -w\u0026mdash;xr\u0026ndash; 564 -w\u0026mdash;\u0026ndash;w- -w\u0026mdash;x-wx 565 -w\u0026mdash;\u0026ndash;w- -w\u0026mdash;x-w- 566 -w\u0026mdash;\u0026mdash;- -w\u0026mdash;x\u0026ndash;x 567 -w\u0026mdash;\u0026mdash;- -w\u0026mdash;x\u0026mdash; 570 -w\u0026mdash;-rw- -w\u0026mdash;-rwx 571 -w\u0026mdash;-rw- -w\u0026mdash;-rw- 572 -w\u0026mdash;-r\u0026ndash; -w\u0026mdash;-r-x 573 -w\u0026mdash;-r\u0026ndash; -w\u0026mdash;-r\u0026ndash; 574 -w\u0026mdash;\u0026ndash;w- -w\u0026mdash;\u0026ndash;wx 575 -w\u0026mdash;\u0026ndash;w- -w\u0026mdash;\u0026ndash;w- 576 -w\u0026mdash;\u0026mdash;- -w\u0026mdash;\u0026mdash;x 577 -w\u0026mdash;\u0026mdash;- -w\u0026mdash;\u0026mdash;- 600 \u0026mdash;rw-rw- \u0026ndash;xrwxrwx 601 \u0026mdash;rw-rw- \u0026ndash;xrwxrw- 602 \u0026mdash;rw-r\u0026ndash; \u0026ndash;xrwxr-x 603 \u0026mdash;rw-r\u0026ndash; \u0026ndash;xrwxr\u0026ndash; 604 \u0026mdash;rw\u0026ndash;w- \u0026ndash;xrwx-wx 605 \u0026mdash;rw\u0026ndash;w- \u0026ndash;xrwx-w- 606 \u0026mdash;rw\u0026mdash;- \u0026ndash;xrwx\u0026ndash;x 607 \u0026mdash;rw\u0026mdash;- \u0026ndash;xrwx\u0026mdash; 610 \u0026mdash;rw-rw- \u0026ndash;xrw-rwx 611 \u0026mdash;rw-rw- \u0026ndash;xrw-rw- 612 \u0026mdash;rw-r\u0026ndash; \u0026ndash;xrw-r-x 613 \u0026mdash;rw-r\u0026ndash; \u0026ndash;xrw-r\u0026ndash; 614 \u0026mdash;rw\u0026ndash;w- \u0026ndash;xrw\u0026ndash;wx 615 \u0026mdash;rw\u0026ndash;w- \u0026ndash;xrw\u0026ndash;w- 616 \u0026mdash;rw\u0026mdash;- \u0026ndash;xrw\u0026mdash;x 617 \u0026mdash;rw\u0026mdash;- \u0026ndash;xrw\u0026mdash;- 620 \u0026mdash;r\u0026ndash;rw- \u0026ndash;xr-xrwx 621 \u0026mdash;r\u0026ndash;rw- \u0026ndash;xr-xrw- 622 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026ndash;xr-xr-x 623 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026ndash;xr-xr\u0026ndash; 624 \u0026mdash;r\u0026mdash;w- \u0026ndash;xr-x-wx 625 \u0026mdash;r\u0026mdash;w- \u0026ndash;xr-x-w- 626 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026ndash;xr-x\u0026ndash;x 627 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026ndash;xr-x\u0026mdash; 630 \u0026mdash;r\u0026ndash;rw- \u0026ndash;xr\u0026ndash;rwx 631 \u0026mdash;r\u0026ndash;rw- \u0026ndash;xr\u0026ndash;rw- 632 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026ndash;xr\u0026ndash;r-x 633 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026ndash;xr\u0026ndash;r\u0026ndash; 634 \u0026mdash;r\u0026mdash;w- \u0026ndash;xr\u0026mdash;wx 635 \u0026mdash;r\u0026mdash;w- \u0026ndash;xr\u0026mdash;w- 636 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026ndash;xr\u0026mdash;-x 637 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026ndash;xr\u0026mdash;\u0026ndash; 640 \u0026mdash;-w-rw- \u0026ndash;x-wxrwx 641 \u0026mdash;-w-rw- \u0026ndash;x-wxrw- 642 \u0026mdash;-w-r\u0026ndash; \u0026ndash;x-wxr-x 643 \u0026mdash;-w-r\u0026ndash; \u0026ndash;x-wxr\u0026ndash; 644 \u0026mdash;-w\u0026ndash;w- \u0026ndash;x-wx-wx 645 \u0026mdash;-w\u0026ndash;w- \u0026ndash;x-wx-w- 646 \u0026mdash;-w\u0026mdash;- \u0026ndash;x-wx\u0026ndash;x 647 \u0026mdash;-w\u0026mdash;- \u0026ndash;x-wx\u0026mdash; 650 \u0026mdash;-w-rw- \u0026ndash;x-w-rwx 651 \u0026mdash;-w-rw- \u0026ndash;x-w-rw- 652 \u0026mdash;-w-r\u0026ndash; \u0026ndash;x-w-r-x 653 \u0026mdash;-w-r\u0026ndash; \u0026ndash;x-w-r\u0026ndash; 654 \u0026mdash;-w\u0026ndash;w- \u0026ndash;x-w\u0026ndash;wx 655 \u0026mdash;-w\u0026ndash;w- \u0026ndash;x-w\u0026ndash;w- 656 \u0026mdash;-w\u0026mdash;- \u0026ndash;x-w\u0026mdash;x 657 \u0026mdash;-w\u0026mdash;- \u0026ndash;x-w\u0026mdash;- 660 \u0026mdash;\u0026mdash;rw- \u0026ndash;x\u0026ndash;xrwx 661 \u0026mdash;\u0026mdash;rw- \u0026ndash;x\u0026ndash;xrw- 662 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026ndash;x\u0026ndash;xr-x 663 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026ndash;x\u0026ndash;xr\u0026ndash; 664 \u0026mdash;\u0026mdash;-w- \u0026ndash;x\u0026ndash;x-wx 665 \u0026mdash;\u0026mdash;-w- \u0026ndash;x\u0026ndash;x-w- 666 \u0026mdash;\u0026mdash;\u0026mdash; \u0026ndash;x\u0026ndash;x\u0026ndash;x 667 \u0026mdash;\u0026mdash;\u0026mdash; \u0026ndash;x\u0026ndash;x\u0026mdash; 670 \u0026mdash;\u0026mdash;rw- \u0026ndash;x\u0026mdash;rwx 671 \u0026mdash;\u0026mdash;rw- \u0026ndash;x\u0026mdash;rw- 672 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026ndash;x\u0026mdash;r-x 673 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026ndash;x\u0026mdash;r\u0026ndash; 674 \u0026mdash;\u0026mdash;-w- \u0026ndash;x\u0026mdash;-wx 675 \u0026mdash;\u0026mdash;-w- \u0026ndash;x\u0026mdash;-w- 676 \u0026mdash;\u0026mdash;\u0026mdash; \u0026ndash;x\u0026mdash;\u0026ndash;x 677 \u0026mdash;\u0026mdash;\u0026mdash; \u0026ndash;x\u0026mdash;\u0026mdash; 700 \u0026mdash;rw-rw- \u0026mdash;rwxrwx 701 \u0026mdash;rw-rw- \u0026mdash;rwxrw- 702 \u0026mdash;rw-r\u0026ndash; \u0026mdash;rwxr-x 703 \u0026mdash;rw-r\u0026ndash; \u0026mdash;rwxr\u0026ndash; 704 \u0026mdash;rw\u0026ndash;w- \u0026mdash;rwx-wx 705 \u0026mdash;rw\u0026ndash;w- \u0026mdash;rwx-w- 706 \u0026mdash;rw\u0026mdash;- \u0026mdash;rwx\u0026ndash;x 707 \u0026mdash;rw\u0026mdash;- \u0026mdash;rwx\u0026mdash; 710 \u0026mdash;rw-rw- \u0026mdash;rw-rwx 711 \u0026mdash;rw-rw- \u0026mdash;rw-rw- 712 \u0026mdash;rw-r\u0026ndash; \u0026mdash;rw-r-x 713 \u0026mdash;rw-r\u0026ndash; \u0026mdash;rw-r\u0026ndash; 714 \u0026mdash;rw\u0026ndash;w- \u0026mdash;rw\u0026ndash;wx 715 \u0026mdash;rw\u0026ndash;w- \u0026mdash;rw\u0026ndash;w- 716 \u0026mdash;rw\u0026mdash;- \u0026mdash;rw\u0026mdash;x 717 \u0026mdash;rw\u0026mdash;- \u0026mdash;rw\u0026mdash;- 720 \u0026mdash;r\u0026ndash;rw- \u0026mdash;r-xrwx 721 \u0026mdash;r\u0026ndash;rw- \u0026mdash;r-xrw- 722 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026mdash;r-xr-x 723 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026mdash;r-xr\u0026ndash; 724 \u0026mdash;r\u0026mdash;w- \u0026mdash;r-x-wx 725 \u0026mdash;r\u0026mdash;w- \u0026mdash;r-x-w- 726 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026mdash;r-x\u0026ndash;x 727 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026mdash;r-x\u0026mdash; 730 \u0026mdash;r\u0026ndash;rw- \u0026mdash;r\u0026ndash;rwx 731 \u0026mdash;r\u0026ndash;rw- \u0026mdash;r\u0026ndash;rw- 732 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026mdash;r\u0026ndash;r-x 733 \u0026mdash;r\u0026ndash;r\u0026ndash; \u0026mdash;r\u0026ndash;r\u0026ndash; 734 \u0026mdash;r\u0026mdash;w- \u0026mdash;r\u0026mdash;wx 735 \u0026mdash;r\u0026mdash;w- \u0026mdash;r\u0026mdash;w- 736 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026mdash;r\u0026mdash;-x 737 \u0026mdash;r\u0026mdash;\u0026ndash; \u0026mdash;r\u0026mdash;\u0026ndash; 740 \u0026mdash;-w-rw- \u0026mdash;-wxrwx 741 \u0026mdash;-w-rw- \u0026mdash;-wxrw- 742 \u0026mdash;-w-r\u0026ndash; \u0026mdash;-wxr-x 743 \u0026mdash;-w-r\u0026ndash; \u0026mdash;-wxr\u0026ndash; 744 \u0026mdash;-w\u0026ndash;w- \u0026mdash;-wx-wx 745 \u0026mdash;-w\u0026ndash;w- \u0026mdash;-wx-w- 746 \u0026mdash;-w\u0026mdash;- \u0026mdash;-wx\u0026ndash;x 747 \u0026mdash;-w\u0026mdash;- \u0026mdash;-wx\u0026mdash; 750 \u0026mdash;-w-rw- \u0026mdash;-w-rwx 751 \u0026mdash;-w-rw- \u0026mdash;-w-rw- 752 \u0026mdash;-w-r\u0026ndash; \u0026mdash;-w-r-x 753 \u0026mdash;-w-r\u0026ndash; \u0026mdash;-w-r\u0026ndash; 754 \u0026mdash;-w\u0026ndash;w- \u0026mdash;-w\u0026ndash;wx 755 \u0026mdash;-w\u0026ndash;w- \u0026mdash;-w\u0026ndash;w- 756 \u0026mdash;-w\u0026mdash;- \u0026mdash;-w\u0026mdash;x 757 \u0026mdash;-w\u0026mdash;- \u0026mdash;-w\u0026mdash;- 760 \u0026mdash;\u0026mdash;rw- \u0026mdash;\u0026ndash;xrwx 761 \u0026mdash;\u0026mdash;rw- \u0026mdash;\u0026ndash;xrw- 762 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026mdash;\u0026ndash;xr-x 763 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026mdash;\u0026ndash;xr\u0026ndash; 764 \u0026mdash;\u0026mdash;-w- \u0026mdash;\u0026ndash;x-wx 765 \u0026mdash;\u0026mdash;-w- \u0026mdash;\u0026ndash;x-w- 766 \u0026mdash;\u0026mdash;\u0026mdash; \u0026mdash;\u0026ndash;x\u0026ndash;x 767 \u0026mdash;\u0026mdash;\u0026mdash; \u0026mdash;\u0026ndash;x\u0026mdash; 770 \u0026mdash;\u0026mdash;rw- \u0026mdash;\u0026mdash;rwx 771 \u0026mdash;\u0026mdash;rw- \u0026mdash;\u0026mdash;rw- 772 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026mdash;\u0026mdash;r-x 773 \u0026mdash;\u0026mdash;r\u0026ndash; \u0026mdash;\u0026mdash;r\u0026ndash; 774 \u0026mdash;\u0026mdash;-w- \u0026mdash;\u0026mdash;-wx 775 \u0026mdash;\u0026mdash;-w- \u0026mdash;\u0026mdash;-w- 776 \u0026mdash;\u0026mdash;\u0026mdash; \u0026mdash;\u0026mdash;\u0026ndash;x 777 \u0026mdash;\u0026mdash;\u0026mdash; \u0026mdash;\u0026mdash;\u0026mdash; 原文\nEvery Possible Umask Mode\n","date":"2022-02-06T05:57:00+08:00","permalink":"https://blog.acesheep.com/p/all-umasks-permissions/","title":"每一种 umask 对应的权限"},{"content":"rsync 是一个常用的 Linux 工具, 用于文件同步。它支持本地计算机与远程计算机之间, 或者两个本地目录之间同步文件, 但不支持两台远程计算机之间的直接同步。rsync 也可以作为文件复制工具, 替代 cp 和 mv 命令。\nrsync 中的 r 表示 remote (远程), 即 \u0026ldquo;远程同步\u0026rdquo;。与 FTP 或 SCP 等文件传输工具不同, rsync 的最大特点是它会检查发送方和接收方已有的文件, 只传输有变化的部分 (默认情况下基于文件大小或修改时间进行比较)\nrsync 基本特点\r可以镜像保存整个目录树和文件系统 可以保持原文件的权限、时间戳、软硬链接等 无需特殊权限即可安装 通过优化的流程, 提供高效的文件传输 支持 rcp、ssh 等传输方式, 也支持直接使用 socket 连接 支持匿名传输 安装 rsync\r传输的双方都必须安装 rsync。以下是常见 Linux 发行版的安装命令\n# Debian 系列 sudo apt-get install rsync # Red Hat 系列 sudo yum install rsync # Arch Linux sudo pacman -S rsync 服务端配置文件 rsyncd.conf\r创建 rsync 配置文件和密码文件\nmkdir -p ~/.config/rsync # 创建配置文件 vim ~/.config/rsync/rsyncd.conf root 用户配置\r该配置适用于 root 用户运行\n# /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # Configuration example: uid=root # 以指定的 UID 传输文件 gid=root # 以指定的 GID 传输文件 #use chroot=yes #max connections=10 # 允许的最大连接数 pid file=/var/run/rsyncd.pid # 指定 PID 文件路径 lock file=/var/run/rsync.lock # 指定进程锁文件 log file=/home/user/.config/rsync/rsyncd.log # 指定日志路径 #exclude = lost+found/ #transfer logging = yes timeout=600 # 连接超时时间 #ignore nonreadable = yes #dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 #hosts allow=10.50.53.100 # 允许指定主机访问 #hosts deny=0.0.0.0/32 # 阻止指定主机访问 port=5000 # 指定 TCP 端口 [backup] # 模块名称, 客户端访问时指定 path=/data # 模块目录 comment=rsync files # 描述信息 read only=no # 允许写入 list=yes # 允许列出文件 auth users=root # 认证用户, 服务器必须存在这个系统用户 secrets file=/home/user/.config/rsync/rsyncd.passwd 普通用户配置\r对于普通用户的配置\nuid 和 gid 必须删除, 否则会报错 setgroups failed: Operation not permitted use chroot 必须设置为 no, 否则会报错 rsync: chroot /path failed: Operation not permitted (1) use chroot=no max connections=640 lock file=/home/user/.config/rsync/rsync.lock log file=/home/user/.config/rsync/rsyncd.log timeout=600 port=5000 [user] # 用户模块 path=/home/user/data/ comment=rsync files read only=no list=yes 创建密码文件 rsyncd.passwd\r用户名: root\n密码: 51522zzwlwlbb (已加入字典)\n配置密码文件并设置适当的权限\n[root@centos7 ~]# vim ~/.config/rsync/rsyncd.passwd root:51522zzwlwlbb # 设置权限 chmod 600 ~/.config/rsync/rsyncd.passwd 启动 rsync 服务端\rrsync --daemon --config=/home/user/.config/rsync/rsyncd.conf rsync 客户端同步操作\r客户端运行在 root 用户和普通用户时客户端的命令有所不同\nroot 用户\r# 保持客户端与服务器端的数据一致 rsync -avzP --delete root@10.121.215.48::backup . # 将服务器 10.121.215.48 中 root 文件夹中的数据同步到当前目录 rsync -avzP root@10.121.215.48::backup . # 保持服务器端与客户端数据一致 rsync -avzP --delete . root@10.121.215.48::backup . # 使用指定的密码文件, 密码文件权限为 600 rsync -avzP --delete --password-file=/etc/rsyncd.pass root@10.121.215.48::backup . # 设置 (文件夹 770) 和 (文件 660) 权限, 并且设置所有者为 qaq # 文件权限要 -p 参数, 所有者要 -go 参数 rsync -rptgo --chmod=Du=rwx,Dg=rwx,Do=,Fu=rw,Fg=rw,Fo= --chown=qaq:qaq --progress user@sub.example.com:data/directory/ ./directory/ 普通用户\r# 列出目录列表 rsync --list-only --port=5000 sub.example.com::user # 保持客户端与服务器端的数据一致 rsync -avzP --delete --port=5000 sub.example.com::user . rsync -av --progress user@sub.example.com:/home/user/ /home/user/ 基本用法\r-r 参数\r-r 表示递归同步, 即包括子目录。可以将源目录同步到目标目录, 替代 cp 或 mv 命令\nrsync -r source destination source 目录表示源目录, destination 表示目标目录。\n如果有多个文件或目录需要同步, 可以写成这样\nrsync -r source1 source2 destination 上面命令中, source1、source2 都会被同步到 destination 目录\n-a 参数\r-a 参数可以替代 -r 是它扩展, 它不仅递归同步, 还保持文件的元信息 (如修改时间、权限等)。由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新, 所以 -a 比 -r 更有用。下面的用法才是常见的写法\nrsync -a source destination 如果目标目录 (destination) 不存在, rsync 会自动创建。执行上面的命令后, 源目录 (source) 被完整地复制到了目标目录 (destination) 下面, 即形成了 destination/source 的目录结构\n如果只想同步源目录 (source) 里面的内容到目标目录 (destination), 则需要在源目录后面加上斜杠\nrsync -a source/ destination 上面命令执行后, 源目录 (source) 里面的内容, 就都被复制到了目标目录 (destination) 里面, 并不会在 destination 下面创建一个 source 子目录\n-n 参数\r如果不确定 rsync 执行后的操作结果, 可以使用 -n 或 --dry-run 参数模拟执行的结果\nrsync -anv source/ destination 上面命令中, -n 参数模拟命令执行的结果, 并不真的执行命令。-v 参数则是将结果输出到终端, 这样就可以看到哪些内容会被同步\n--delete 参数\r默认情况下, rsync 只确保源目录的所有内容都复制到目标目录 (明确排除的文件除外), 不会删除目标目录中不再存在于源目录的文件。它不会使两个目录保持相同, 如果希望目标目录成为源目录的镜像副本, 则必须使用 --delete 参数, 这将删除只存在于目标目录、不存在于源目录的文件\nrsync -av --delete source/ destination 上面命令中, --delete 参数会使得 destination 成为 source 的一个镜像\n排除文件\r--exclude 参数\r有时, 我们希望同步时排除某些文件或目录, 这时可以用 --exclude 参数指定排除模式\nrsync -av --exclude=\u0026#39;*.txt\u0026#39; source/ destination # 或者 rsync -av --exclude \u0026#39;*.txt\u0026#39; source/ destination 上面命令排除了所有 TXT 文件\n注意, rsync 会同步以 \u0026ldquo;点\u0026rdquo; 开头的隐藏文件, 如果要排除隐藏文件, 可以这样写\nrsync -av --exclude=\u0026#39;.*\u0026#39; source/ destination 如果要排除某个目录里面的所有文件, 但不希望排除目录本身, 可以写成下面这样\nrsync -av --exclude \u0026#39;dir1/*\u0026#39; source/ destination 多个排除模式, 可以用多个 --exclude 参数\nrsync -av --exclude \u0026#39;file1.txt\u0026#39; --exclude \u0026#39;dir1/*\u0026#39; source/ destination 多个排除模式也可以利用 bash 的大扩号的扩展功能, 只用一个 --exclude 参数\nrsync -av --exclude={\u0026#39;file1.txt\u0026#39;,\u0026#39;dir1/*\u0026#39;} source/ destination 如果排除模式很多, 可以将它们写入一个文件, 每个模式一行, 然后用 --exclude-from 参数指定这个文件\nrsync -av --exclude-from=\u0026#39;exclude-file.txt\u0026#39; source/ destination --include 参数\r--include 参数用来指定必须同步的文件模式, 往往与 --exclude 结合使用。\n使用 --include 指定必须同步的文件, 并结合 --exclude 进行排除\n# 排除所有文件, 但是包括所有 TXT 文件 rsync -av --include=\u0026#39;*.txt\u0026#39; --include=\u0026#39;*/\u0026#39; --exclude=\u0026#39;*\u0026#39; source/ destination rsync -avzP --include=\u0026#39;*.txt\u0026#39; --include=\u0026#39;data/\u0026#39; --exclude=\u0026#39;*\u0026#39; user@sub.example.com:/home/user/data . rsync -avzP --include=\u0026#39;source*\u0026#39; --exclude=\u0026#39;*\u0026#39; user@sub.example.com:/home/user/data/ . --list-only 远程同步\rrsync 除了支持本地两个目录之间的同步, 也支持远程同步。它可以将本地内容, 同步到远程服务器。\n通过 SSH 协议\r将本地内容同步到远程服务器\nrsync -av source/ username@remote_host:destination 也可以将远程内容同步到本地\nrsync -av username@remote_host:source/ destination rsync 默认使用 SSH 进行远程登录和数据传输\n由于早期 rsync 不使用 SSH 协议, 需要用 -e 参数指定协议, 后来才改的。所以, 下面 -e ssh 可以省略\nrsync -av -e ssh source/ user@remote_host:/destination 但是, 如果 ssh 命令有附加的参数, 则必须使用 -e 参数指定所要执行的 SSH 命令\nrsync -av -e \u0026#39;ssh -p 2234\u0026#39; source/ user@remote_host:/destination 上面命令中, -e 参数指定 SSH 使用 2234 端口\n通过 rsync 协议\r除了使用 SSH, 如果另一台服务器安装并运行了 rsync 守护程序, 则也可以用 rsync:// 协议 (默认端口 87) 进行传输。具体写法是服务器与目标目录之间使用双冒号分隔 ::\nrsync -av source/ 192.168.122.32::module/destination 注意, 上面地址中的 module 并不是实际路径名, 而是 rsync 守护程序指定的一个资源名, 由管理员分配\n如果想知道 rsync 守护程序分配的所有资源名列表, 可以执行下面命令\nrsync rsync://192.168.122.32 rsync 协议除了使用双冒号, 也可以直接用 rsync:// 协议指定地址\nrsync -av source/ rsync://192.168.122.32/module/destination 增量备份\rrsync 的增量备份功能是其最大的特色。第一次同步是全量备份, 后续同步仅传输有变动的部分。除了源目录与目标目录直接比较, rsync 还支持使用基准目录, 即将源目录与基准目录之间变动的部分, 同步到目标目录。\n具体原理是, 第一次同步是全量备份, 将所有文件从源目录同步到基准目录中。之后的每次同步都是增量备份, 仅同步源目录与基准目录之间发生变动的部分, 并将这些变动的文件保存在一个新的目标目录中。新的目标目录中包含所有文件, 但实际上只有发生变动的文件是真实存在的, 其他未变动的文件则通过硬链接指向基准目录中的对应文件。\n使用 --link-dest 参数可以指定基准目录, 从而执行增量备份\nrsync -a --delete --link-dest /compare/path /source/path /target/path 这个命令将源目录与基准目录进行比较, 找出变动的文件, 复制到目标目录, 未变动的文件则通过硬链接保存在目标目录\n脚本示例\r备份用户的主目录\n#!/bin/bash # A script to perform incremental backups using rsync set -o errexit set -o nounset set -o pipefail readonly SOURCE_DIR=\u0026#34;${HOME}\u0026#34; readonly BACKUP_DIR=\u0026#34;/mnt/data/backups\u0026#34; readonly DATETIME=\u0026#34;$(date \u0026#39;+%Y-%m-%d_%H:%M:%S\u0026#39;)\u0026#34; readonly BACKUP_PATH=\u0026#34;${BACKUP_DIR}/${DATETIME}\u0026#34; readonly LATEST_LINK=\u0026#34;${BACKUP_DIR}/latest\u0026#34; mkdir -p \u0026#34;${BACKUP_DIR}\u0026#34; rsync -av --delete \\ \u0026#34;${SOURCE_DIR}/\u0026#34; \\ --link-dest \u0026#34;${LATEST_LINK}\u0026#34; \\ --exclude=\u0026#34;.cache\u0026#34; \\ \u0026#34;${BACKUP_PATH}\u0026#34; rm -rf \u0026#34;${LATEST_LINK}\u0026#34; ln -s \u0026#34;${BACKUP_PATH}\u0026#34; \u0026#34;${LATEST_LINK}\u0026#34; 上面脚本中, 每次同步都会创建一个新目录 ${BACKUP_DIR}/${DATETIME}, 并通过软链接 ${BACKUP_DIR}/latest 指向该目录。在下一次备份时, 脚本会将 ${BACKUP_DIR}/latest 作为基准目录, 通过 --link-dest 选项生成新的备份目录。备份完成后, 软链接 ${BACKUP_DIR}/latest 会更新为指向最新生成的备份目录\n命令行参数解释\r-v, --verbose # 详细模式输出, -vv 表示输出更详细的信息, -vvv 表示输出最详细的信息 -q, --quiet # 精简输出模式 -c, --checksum # 改变 rsync 的校验方式 # 默认情况下, rsync 只检查文件的大小和最后修改日期是否发生变化, 如果发生变化, 就重新传输。使用这个参数以后, 则通过判断文件内容的校验和, 决定是否重新传输 -a, --archive # 归档模式, 保存所有的元数据, 比如修改时间、权限、所有者等, 并且软链接也会同步过去, 等于 -rlptgoD --append # 文件接着上次中断的地方, 继续传输 --append-verify # 跟 --append 参数类似, 但会对传输完成后的文件进行一次校验。如果校验失败, 将重新发送整个文件 -r, --recursive # 对子目录以递归模式处理, 即包含子目录 -R, --relative # 使用相对路径信息 -b, --backup # 创建备份, 也就是对于目的已经存在有同样的文件名时, 将老的文件重新命名为 ~filename。更名规则是添加由 --suffix 选项来指定不同的备份文件前缀, 默认是 ~ --backup-dir # 指定文件备份时存放的目录 比如 /path/to/backups/~filename 存放在在目录下 --suffix=SUFFIX # 指定文件名备份时, 对文件名添加的后缀, 默认是 ~ -u, --update # 同步时跳过目标目录上修改时间较新的文件 -l, --links # 保留软链结 --link-dest # 指定增量备份的基准目录 -L, --copy-links # 想对待常规文件一样处理软链结 --copy-unsafe-links # 仅仅拷贝指向 SRC 路径目录树以外的链结 --safe-links # 忽略指向 SRC 路径目录树以外的链结 -H, --hard-links # 保留硬链结 -p, --perms # 保持文件权限 -o, --owner # 保持文件属主信息 -g, --group # 保持文件属组信息 -D, --devices # 保持设备文件信息 -t, --times # 保持文件时间信息 -S, --sparse # 对稀疏文件进行特殊处理以节省DST的空间 -n, --dry-run # 模拟将要执行的操作, 而并不真的执行。配合 -v 参数使用, 可以看到哪些内容会被同步过去 -W, --whole-file # 拷贝文件, 不进行增量检测 -x, --one-file-system # 不要跨越文件系统边界 -B, --block-size=SIZE # 检验算法使用的块尺寸, 默认是 700 字节 -e, --rsh=COMMAND # 指定使用 rsh、ssh 协议传输数据 --rsync-path=PATH # 指定远程服务器上的 rsync 命令所在路径信息 -C, --cvs-exclude # 使用和 CVS 一样的方法自动忽略文件, 用来排除那些不希望传输的文件 --existing, --ignore-non-existing # 仅已经存在于目标目录的文件, 不同步目标目录中不存在的文件和目录 --delete # 删除只存在于目标目录、不存在于源目标的文件, 保证目标目录是源目标的镜像 --delete-excluded # 同样删除接收端那些被该选项指定排除的文件 --delete-after # 传输结束以后再删除 --ignore-errors # 及时出现 IO 错误也进行删除 --ignore-existing # 只要该文件在目标目录中已经存在, 就跳过去, 不再同步这些文件 -m # 不同步空目录 --max-size # 参数设置传输的最大文件的大小限制, 比如不超过 200KB (--max-size=\u0026#39;200k\u0026#39;) --min-size # 参数设置传输的最小文件的大小限制, 比如不小于 10KB (--min-size=10k) --max-delete=NUM # 最多删除 NUM 个文件 --partial # 允许恢复中断的传输。不使用该参数时, rsync 会删除传输到一半被打断的文件, 使用该参数后, 传输到一半的文件也会同步到目标目录, 下次同步时再恢复中断的传输。一般需要与 --append 或 --append-verify 配合使用 --partial-dir # 指定将传输到一半的文件保存到一个临时目录, 比如 --partial-dir=.rsync-partial。一般需要与 --append 或 --append-verify 配合使用 --progress # 在传输时显示传输过程 -P # 是 --progress 和 --partial 这两个参数的结合 --force # 强制删除目录, 即使不为空 --numeric-ids # 不将数字的用户和组 ID 匹配为用户名和组名 --timeout=TIME # IP 超时时间, 单位为秒 -I, --ignore-times # 不跳过那些有同样的时间和长度的文件 -i # 输出源目录与目标目录之间文件差异的详细情况 --size-only # 表示只同步大小有变化的文件, 不考虑文件修改时间的差异 --modify-window=NUM # 决定文件是否时间相同时使用的时间戳窗口, 默认为 0 -T --temp-dir=DIR # 在 DIR 中创建临时文件 --compare-dest=DIR # 同样比较 DIR 中的文件来决定是否需要备份 -z, --compress # 对备份的文件在传输时进行压缩处理 --exclude=PATTERN # 排除不进行同步的文件, 比如 --exclude=\u0026#34;*.iso\u0026#34; --include=PATTERN # 同步时要包括的文件, 一般与 --exclude 结合使用 --exclude-from=FILE # 指定一个本地文件, 里面是需要排除的文件模式, 每个模式一行 --include-from=FILE # 不排除 FILE 指定模式匹配的文件 --version # 打印版本信息 --address # 绑定到特定的地址 --config=FILE # 指定其他的配置文件, 不使用默认的 rsyncd.conf 文件 --port=PORT # 指定其他的 rsync 服务端口 --blocking-io # 对远程 shell 使用阻塞 IO -stats # 给出某些文件的传输状态 --log-format=formAT # 指定日志文件格式 --password-file=FILE # 从 FILE 中得到密码 --bwlimit=KBPS # 带宽限制, 默认单位是 KB/s, 比如 --bwlimit=100 --remove-source-files # 传输成功后, 删除发送方的文件 -h, --human-readable # 以人类可读的格式输出 -h, --help # 显示帮助信息 (-h 单独使用时显示帮助) 完整命令行帮助\r[root@centos7 ~]# rsync -h rsync version 3.1.2 protocol version 31 Copyright (C) 1996-2015 by Andrew Tridgell, Wayne Davison, and others. Web site: http://rsync.samba.org/ Capabilities: 64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints, socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace, append, ACLs, xattrs, iconv, symtimes, prealloc rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public Licence for details. rsync is a file transfer program capable of efficient remote update via a fast differencing algorithm. Usage: rsync [OPTION]... SRC [SRC]... DEST or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST or rsync [OPTION]... [USER@]HOST:SRC [DEST] or rsync [OPTION]... [USER@]HOST::SRC [DEST] or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST] The \u0026#39;:\u0026#39; usages connect via remote shell, while \u0026#39;::\u0026#39; \u0026amp; \u0026#39;rsync://\u0026#39; usages connect to an rsync daemon, and require SRC or DEST to start with a module name. Options -v, --verbose increase verbosity --info=FLAGS fine-grained informational verbosity --debug=FLAGS fine-grained debug verbosity --msgs2stderr special output handling for debugging -q, --quiet suppress non-error messages --no-motd suppress daemon-mode MOTD (see manpage caveat) -c, --checksum skip based on checksum, not mod-time \u0026amp; size -a, --archive archive mode; equals -rlptgoD (no -H,-A,-X) --no-OPTION turn off an implied OPTION (e.g. --no-D) -r, --recursive recurse into directories -R, --relative use relative path names --no-implied-dirs don\u0026#39;t send implied dirs with --relative -b, --backup make backups (see --suffix \u0026amp; --backup-dir) --backup-dir=DIR make backups into hierarchy based in DIR --suffix=SUFFIX set backup suffix (default ~ w/o --backup-dir) -u, --update skip files that are newer on the receiver --inplace update destination files in-place (SEE MAN PAGE) --append append data onto shorter files --append-verify like --append, but with old data in file checksum -d, --dirs transfer directories without recursing -l, --links copy symlinks as symlinks -L, --copy-links transform symlink into referent file/dir --copy-unsafe-links only \u0026#34;unsafe\u0026#34; symlinks are transformed --safe-links ignore symlinks that point outside the source tree --munge-links munge symlinks to make them safer (but unusable) -k, --copy-dirlinks transform symlink to a dir into referent dir -K, --keep-dirlinks treat symlinked dir on receiver as dir -H, --hard-links preserve hard links -p, --perms preserve permissions -E, --executability preserve the file\u0026#39;s executability --chmod=CHMOD affect file and/or directory permissions -A, --acls preserve ACLs (implies --perms) -X, --xattrs preserve extended attributes -o, --owner preserve owner (super-user only) -g, --group preserve group --devices preserve device files (super-user only) --copy-devices copy device contents as regular file --specials preserve special files -D same as --devices --specials -t, --times preserve modification times -O, --omit-dir-times omit directories from --times -J, --omit-link-times omit symlinks from --times --super receiver attempts super-user activities --fake-super store/recover privileged attrs using xattrs -S, --sparse handle sparse files efficiently --preallocate allocate dest files before writing them -n, --dry-run perform a trial run with no changes made -W, --whole-file copy files whole (without delta-xfer algorithm) -x, --one-file-system don\u0026#39;t cross filesystem boundaries -B, --block-size=SIZE force a fixed checksum block-size -e, --rsh=COMMAND specify the remote shell to use --rsync-path=PROGRAM specify the rsync to run on the remote machine --existing skip creating new files on receiver --ignore-existing skip updating files that already exist on receiver --remove-source-files sender removes synchronized files (non-dirs) --del an alias for --delete-during --delete delete extraneous files from destination dirs --delete-before receiver deletes before transfer, not during --delete-during receiver deletes during the transfer --delete-delay find deletions during, delete after --delete-after receiver deletes after transfer, not during --delete-excluded also delete excluded files from destination dirs --ignore-missing-args ignore missing source args without error --delete-missing-args delete missing source args from destination --ignore-errors delete even if there are I/O errors --force force deletion of directories even if not empty --max-delete=NUM don\u0026#39;t delete more than NUM files --max-size=SIZE don\u0026#39;t transfer any file larger than SIZE --min-size=SIZE don\u0026#39;t transfer any file smaller than SIZE --partial keep partially transferred files --partial-dir=DIR put a partially transferred file into DIR --delay-updates put all updated files into place at transfer\u0026#39;s end -m, --prune-empty-dirs prune empty directory chains from the file-list --numeric-ids don\u0026#39;t map uid/gid values by user/group name --usermap=STRING custom username mapping --groupmap=STRING custom groupname mapping --chown=USER:GROUP simple username/groupname mapping --timeout=SECONDS set I/O timeout in seconds --contimeout=SECONDS set daemon connection timeout in seconds -I, --ignore-times don\u0026#39;t skip files that match in size and mod-time -M, --remote-option=OPTION send OPTION to the remote side only --size-only skip files that match in size --modify-window=NUM compare mod-times with reduced accuracy -T, --temp-dir=DIR create temporary files in directory DIR -y, --fuzzy find similar file for basis if no dest file --compare-dest=DIR also compare destination files relative to DIR --copy-dest=DIR ... and include copies of unchanged files --link-dest=DIR hardlink to files in DIR when unchanged -z, --compress compress file data during the transfer --compress-level=NUM explicitly set compression level --skip-compress=LIST skip compressing files with a suffix in LIST -C, --cvs-exclude auto-ignore files the same way CVS does -f, --filter=RULE add a file-filtering RULE -F same as --filter=\u0026#39;dir-merge /.rsync-filter\u0026#39; repeated: --filter=\u0026#39;- .rsync-filter\u0026#39; --exclude=PATTERN exclude files matching PATTERN --exclude-from=FILE read exclude patterns from FILE --include=PATTERN don\u0026#39;t exclude files matching PATTERN --include-from=FILE read include patterns from FILE --files-from=FILE read list of source-file names from FILE -0, --from0 all *-from/filter files are delimited by 0s -s, --protect-args no space-splitting; only wildcard special-chars --address=ADDRESS bind address for outgoing socket to daemon --port=PORT specify double-colon alternate port number --sockopts=OPTIONS specify custom TCP options --blocking-io use blocking I/O for the remote shell --stats give some file-transfer stats -8, --8-bit-output leave high-bit chars unescaped in output -h, --human-readable output numbers in a human-readable format --progress show progress during transfer -P same as --partial --progress -i, --itemize-changes output a change-summary for all updates --out-format=FORMAT output updates using the specified FORMAT --log-file=FILE log what we\u0026#39;re doing to the specified FILE --log-file-format=FMT log updates using the specified FMT --password-file=FILE read daemon-access password from FILE --list-only list the files instead of copying them --bwlimit=RATE limit socket I/O bandwidth --outbuf=N|L|B set output buffering to None, Line, or Block --write-batch=FILE write a batched update to FILE --only-write-batch=FILE like --write-batch but w/o updating destination --read-batch=FILE read a batched update from FILE --protocol=NUM force an older protocol version to be used --iconv=CONVERT_SPEC request charset conversion of filenames --checksum-seed=NUM set block/file checksum seed (advanced) -4, --ipv4 prefer IPv4 -6, --ipv6 prefer IPv6 --version print version number (-h) --help show this help (-h is --help only if used alone) Use \u0026#34;rsync --daemon --help\u0026#34; to see the daemon-mode command-line options. Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation. See http://rsync.samba.org/ for updates, bug reports, and answers 原文\nrsync 用法教程\nRsync command issues, owner and group permissions doesn´t change\nHow to change the owner for a rsync\nHow to set file/folder permissions using Rsync from Windows to Linux\n","date":"2022-02-05T16:32:00+08:00","permalink":"https://blog.acesheep.com/p/linux-rsync-remote-sync-tool/","title":"Linux rsync 远程同步工具"},{"content":"FlexGet 是一个用于自动化下载工具的管理软件, 主要用途是订阅网站最新 Free 的种子并自动下载, 可以直接传输到 qBittorrent、Deluge 或 Transmission 等客户端进行下载。\n准备条件\rPython: Python 3.6 及以上 (Python 3.10) pip3: pip 22.0.2 FlexGet: 3.2.16 (2022-01-27) transmission-rpc: 3.3.0 安装 FlexGet\r# 安装 FlexGet pip3 install flexget # 更新 FlexGet pip3 install --upgrade flexget # 删除 transmissionrpc (0.11) pip3 uninstall transmissionrpc # 安装 transmission-rpc (3.3.0) pip3 install transmission-rpc # 创建配置文件夹 mkdir -p /home/flexget/.config/flexget # 创建日志文件并设置权限 (不然反代看不到日志) touch /home/flexget/.config/flexget/flexget.log chmod 640 /home/flexget/.config/flexget/flexget.log # 查看 FlexGet 版本 [root@centos7 ~]# flexget --version 3.2.16 You are on the latest release. 创建配置文件\r在 /home/flexget/.config/flexget/config.yml 文件中添加以下内容\ntemplates: # 剩余空间模板, 当配置的 path 路径的剩余空间小于 space 规定的数值时, 停止 RSS 下载 freespace: free_space: path: /home/flexget space: 10240 qb: qbittorrent: path: /home/flexget/qbittorrent/download/ host: localhost port: 2017 username: flexget password: 51522zzwlwlbb tr: transmission: path: /home/flexget/transmission/download/ host: localhost port: 9099 username: flexget password: 51522zzwlwlbb de: deluge: path: /home/flexget/deluge/download/ host: localhost port: 58846 username: flexget password: 51522zzwlwlbb # 体积过滤模板, min 是符合条件的最小种子体积, max 是符合条件的最大种子体积, 单位均为 MB # strict 默认是 yes, 表示在无法确定大小的情况下就不下载, 这里把它改成 no 了 # 这段 size 的意思是, 只下载体积为 6000-666666 MB 的种子, 其他不满足条件的种子不下载 size: content_size: min: 6000 max: 666666 strict: no tasks: PT-HDSky-WEB: rss: https://hdsky.me/torrentrss.php # 因为 HDSWEB 发单集的时候用的标题是一样的, 因此下过一次后 # 之后新发出来的单集由于标题一样, flexget 会当成是以前已经下过的种子 # 为了避免这个问题, 对 seen 插件设定为只检查 url 是否一致 seen: fields: - url # 正则表达式；标题带 HDSWEB 的种子就下载 (accept, 接受), 不想下载的话就写拒绝 (reject) regexp: accept: - HDSWEB # 调用上边的 de 模板 template: de # 可以不使用模板的体积过滤, 针对每个任务单独设置体积过滤 content_size: min: 3000 max: 500000 strict: no # 以下设定实现的效果: 对这个任务加载到 deluge 的种子, 自动添加 WEB-DL 的标签 # 自动限制上传速度到 10MB/s (防止超速), 下完后自动移动到 /mnt/HDSky/HDSWEB deluge: label: WEB-DL # Limit upload speed to 100 MiB/s in case of being auto-banned max_up_speed: 102400 move_completed_path: /mnt/HDSky/HDSWEB ADC-AnimeBD-JPN: rss: http://asiandvdclub.org/rss.xml # 这三个过滤条件组合起来就是, 下载标题里带 Anime 和 AVC 且不含 subs only 的种子 # 并排除掉描述里含有 Custom 的种子 # 这也就约等于, RSS 日版动画蓝光碟 (非日版、DIY 碟、DVD 都过滤掉) if: - \u0026#34;\u0026#39;Anime\u0026#39; and \u0026#39;AVC\u0026#39; in title\u0026#34;: accept - \u0026#34;\u0026#39;subs only\u0026#39; in title\u0026#34;: reject - \u0026#34;\u0026#39;Custom\u0026#39; in description\u0026#34;: reject # RSS ADC 需要 Cookies, 这里我们用 headers 插件来加上 cookies headers: Cookie: \u0026#34;uid=12345; pass=abcdefg\u0026#34; # 转换 RSS 链接, 将原本形如 http://asiandvdclub.org/details.php?id=123456 的种子描述页面链接 # 替换为形如 http://asiandvdclub.org/download.php?id=123456 的种子下载链接 urlrewrite: sitename: regexp: \u0026#39;http://asiandvdclub.org/details.php\\?id=(?P\u0026lt;id\u0026gt;\\d+)\u0026#39; format: \u0026#39;http://asiandvdclub.org/download.php?id=\\g\u0026lt;id\u0026gt;\u0026#39; qbittorrent: label: ADC # Flexget 支持添加种子到 qBittorrent 的时候自动设定单种限速 maxdownspeed: 30000 btschool: rss: https://pt.btschool.club/torrents.php # 把 RSS 链接里的所有种子都下载下来, 不做过滤 accept_all: yes template: - freespace - size - tr web_server: web_ui: yes base_url: /flexget bind: 127.0.0.1 port: 6566 # schedules is disabled by default, you need to enable it or use cron to RSS schedules: no Web UI 设置\r设置 Web UI 密码\rflexget web passwd 51522zzwlwlbb 配置 Web UI\r在 /home/flexget/.config/flexget/config.yml 中添加\nweb_server: web_ui: yes base_url: /flexget bind: 127.0.0.1 port: 6566 # base_url 是为了反代设置的 # Flexget WebUI 地址就变成了 https://IP/flexget Nginx 反代设置\r在 /etc/nginx/conf.d/flexget.conf 中添加\nlocation /flexget/ { proxy_redirect off; proxy_pass http://127.0.0.1:6566/flexget/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \u0026#34;upgrade\u0026#34;; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host \\$server_name:\\$server_port; http2_push_preload on; # Show realip in flexget access.log proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } 创建系统服务\rcat\u0026gt;\u0026gt;/etc/systemd/system/flexget.service\u0026lt;\u0026lt;EOF [Unit] Description=FlexGet Daemon After=network.target [Service] User=flexget Group=flexget ExecStart=`which flexget` daemon start ExecStartPre=/bin/rm -f /home/flexget/.config/flexget/.config-lock ExecStop=`which flexget` daemon stop Restart=on-failure [Install] WantedBy=multi-user.target EOF 启动服务\r# 重新载入 service systemctl daemon-reload # 开机启动 flexget systemctl enable flexget # 启动 flexget systemctl start flexget # 查看 flexget 状态 flexget daemon status 定时任务\r使用 FlexGet 自带定时任务功能\n所有任务每 60 分钟执行一次\nschedules: - tasks: \u0026#39;*\u0026#39; interval: minutes: 60 任务名: task_name 每 15 分钟执行一次\nschedules: - tasks: \u0026#39;task_name\u0026#39; interval: minutes: 15 对不同任务设置不同的执行时间\nschedules: - tasks: \u0026#39;Update-Queue\u0026#39; interval: hours: 3 - tasks: \u0026#39;Series-*\u0026#39; interval: minutes: 30 - tasks: \u0026#39;Movies-*\u0026#39; interval: hours: 1 - tasks: \u0026#39;Update-trakt-*\u0026#39; interval: days: 1 at_time: 4:43 am - tasks: [HDC, btschool] interval: minutes: 30 如果不配置 Schedule 也可以通过 cron 命令来定时执行, 比如每隔 5 分钟执行一次\ncrontab -e */5 * * * * /usr/bin/flexget --cron execute 常用命令\rflexget check # 用于检查 config.yml 配置文件是否有格式错误 flexget --test execute # 手动模拟一次 RSS 操作, 仅供测试, 不会下载种子文件到本地 flexget execute # 手动执行所有任务 flexget execute --tasks Series-* # 手动执行指定的任务 flexget status # 查看 flexget 的 RSS 记录 flexget execute --learn # 把这次 RSS 到的种子标记为已下载, 相当于初始化数据库 更多任务模板\rtemplates: # freespace 插件 freespace: free_space: path: /data space: 10240 qb: qbittorrent: path: /data host: localhost port: 8080 username: admin password: password de: deluge: password: \u0026#34;deluge\u0026#34; path: /data tr: transmission: host: localhost port: 9091 username: admin password: \u0026#34;password\u0026#34; tasks: BTSchool: rss: https://pt.btschool.net/torrentrss.php accept_all: yes template: - de HDChina: rss: https://hdchina.org/torrentrss.php accept_all: yes template: - qb qbittorrent: label: HDChina CHDBits: rss: https://chdbits.co/torrentrss.php accept_all: no if: - \u0026#34;\u0026#39;CHDPAD\u0026#39; in title\u0026#34;: reject - \u0026#34;\u0026#39;CHDPad\u0026#39; in title\u0026#34;: reject - \u0026#34;\u0026#39;CHD\u0026#39; in title\u0026#34;: accept template: - tr U2: rss: https://u2.dmhy.org/torrentrss.php accept_all: no regexp: accept_excluding: - DVD - ADC - TTG - TSDM from: title download: /data/torrent/ Mteam: rss: https://tp.m-team.cc/torrentrss.php accept_all: no regexp: accept: - sweety from: title download: /data/torrent/ GZtown: rss: https://pt.gztown.net/torrentrss.php accept_all: no if: - \u0026#34;\u0026#39;GZtown\u0026#39; in title\u0026#34;: accept download: /data/torrent/ HDSky: rss: https://hdsky.me/torrentrss.php accept_all: yes download: /data/torrent/ Ourbits: rss: https://ourbits.club/torrentrss.php accept_all: yes download: /data/torrent/ ezrss: rss: http://eztv.ag/ezrss.xml accept_all: yes content_size: min: 200 max: 4444 strict: no download: /data ","date":"2022-02-03T18:10:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-flexget-setup/","title":"CentOS 7 配置 FlexGet"},{"content":"在找到 CentOS 8 代替品之前先继续用 CentOS 7 苟着了, Python 3.10 的 5 年支持够用了 End of support 2026-10\n安装编译环境\r安装必要的依赖包和开发工具\ryum install epel-release centos-release-scl -y yum install devtoolset-9-gcc* -y yum groupinstall \u0026#34;Development tools\u0026#34; -y 安装 Python 3.10.2 所需的依赖包\r# Python 3.10.2 依赖 yum install bzip2-devel ncurses-devel gdbm-devel xz-devel sqlite-devel tk-devel libffi-devel libuuid-devel readline-devel zlib-devel openssl11 openssl11-devel -y 特别注意事项\nPython 3.10 需要 OpenSSL 版本至少为 1.1.1 安装 OpenSSL 1.1.1\rPython 将 OpenSSL 用于加密相关功能, 例如 https 通信和消息摘要创建。\n以前, OpenSSL 版本 1.0.2 或更高版本在 Python 中可用, 但从 Python 3.10 开始, OpenSSL 版本至少为 1.1.1, 而 CentOS 7 默认包含 OpenSSL 1.0.2, 所以需要从 EPEL 安装 OpenSSL 1.1.1\n使用以下命令安装 OpenSSL 1.1.1\nyum install epel-release yum install openssl11 openssl11-devel export CFLAGS=$(pkg-config --cflags openssl11) export LDFLAGS=$(pkg-config --libs openssl11) 下载和编译 Python 3.10.2\r下载源码\rwget https://www.python.org/ftp/python/3.10.2/Python-3.10.2.tar.xz tar xf Python-3.10.2.tar.xz cd Python-3.10.2 设置编译参数并编译\r# 设置编译使用 openssl 1.1.1 依赖库 sed -i \u0026#39;s/PKG_CONFIG openssl /PKG_CONFIG openssl11 /g\u0026#39; configure scl enable devtoolset-9 \u0026#34;./configure --enable-optimizations\u0026#34; scl enable devtoolset-9 \u0026#34;make -j\u0026#34; 注意事项\rPython 3.10 需要 gcc 版本大于 5.3\n使用系统自带的 gcc 编译会遇到这个错误\ngcc: error: unrecognized command line option ‘-fno-semantic-interposition’ 我们使用 devtoolset-9 中的 gcc 9.3.1 编译 Python 3.10\n[root@centos7 ~]# gcc --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [root@centos7 ~]# scl enable devtoolset-9 \u0026#34;gcc --version\u0026#34; gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 依赖包对应关系\nbzip2-devel _bz2 ncurses-devel _curses _curses_panel gdbm-devel _dbm _gdbm xz-devel _lzma sqlite-devel _sqlite3 tk-devel _tkinter libffi-devel _ctypes libuuid-devel _uuid readline-devel readline zlib-devel zlib openssl11-devel _hashlib _ssl # 缺失的依赖库可以对应安装 Python build finished successfully! The necessary bits to build these optional modules were not found: _bz2 _curses _curses_panel _dbm _gdbm _lzma _uuid _sqlite3 _tkinter readline zlib To find the necessary bits, look in setup.py in detect_modules() for the module\u0026#39;s name. The following modules found by detect_modules() in setup.py, have been built by the Makefile instead, as configured by the Setup files: _abc pwd time Failed to build these modules: _hashlib _ssl Could not build the ssl module! Python requires a OpenSSL 1.1.1 or newer Custom linker flags may require --with-openssl-rpath=auto 检查编译版本号\r# 检查编译完成 版本号 [root@centos7 Python-3.10.2]# ./python --version Python 3.10.2 安装 Python 3.10.2\r使用 make install 完成安装, 会自动创建符号链接和手册\n# 安装到系统 会执行 commoninstall、bininstall、maninstall 会创建符号链接 make install [root@centos7 ~]# ls -all /usr/local/bin | grep python lrwxrwxrwx 1 root root 10 Jan 31 12:43 python3 -\u0026gt; python3.10 -rwxr-xr-x 1 root root 23504344 Jan 31 12:43 python3.10 -rwxr-xr-x 1 root root 3116 Jan 31 12:39 python3.10-config lrwxrwxrwx 1 root root 17 Jan 31 12:43 python3-config -\u0026gt; python3.10-config 使用 make altinstall 仅安装 Python, 不创建符号链接和手册\n# 只执行 commoninstall 不会创建软链和手册相关信息 make altinstall [root@centos7 ~]# ls -all /usr/local/bin | grep python -rwxr-xr-x 1 root root 23504344 Jan 31 12:43 python3.10 -rwxr-xr-x 1 root root 3116 Jan 31 12:39 python3.10-config 创建符号链接 (可选)\r# 创建软连接 ln -s /usr/local/bin/python3.10 /usr/local/bin/python3 ln -s /usr/local/bin/python3.10-config /usr/local/bin/python3-config 默认安装位置\r# 默认安装位置 /usr/local/lib [root@centos7 ~]# tree -L 1 /usr/local/lib /usr/local/lib ├── libpython3.10.a ├── pkgconfig └── python3.10 更新 pip3\rpython3 -m pip install --upgrade pip 原文\nPython 3.10の新機能(その8） OpenSSL 1.1.1が必須に\nHow to link python3 to use openssl11 / or latest version of openssl (1.1.1) on centos 7\nCan\u0026rsquo;t build Twisted==20.3.0 on Linux using gcc 4.8.5\nCan\u0026rsquo;t build optional modules readline and _curses when compiling Python3.4 from source on CentOS7\nPython安装：make install和make altinstall的差别\n","date":"2022-02-01T11:29:35+08:00","permalink":"https://blog.acesheep.com/p/centos-7-compile-and-install-python-3.10.2/","title":"CentOS 7 编译安装 Python 3.10.2"},{"content":"安卓 7 之前把 CA 证书安装到用户证书下即可, 但在安卓 7 以上系统中, 由于默认只信任系统级证书 (APP 可以设置信任范围, 默认仅信任系统范围的证书), 为了正常抓包, 需要将 CA 证书安装到系统证书目录。\n准备条件\r一台已 root 的安卓手机 电脑安装 Charles 抓包工具 (其他抓包工具也是一样的原理) 电脑安装 ADB (Android Debug Bridge) 获取 Charles 根证书\r导出证书文件\r在 Charles 中导出证书 (.pem 格式), 命名为 charles.pem\n获取证书文件名\r在证书所在路径打开命令行, 执行以下命令\nopenssl x509 -inform PEM -subject_hash_old -in charles.pem 示例输出\nfaf57fe3 -----BEGIN CERTIFICATE----- MIIFMDCCBBigAwIBAgIGAXWqowQPMA0GCSqGSIb3DQEBCwUAMIGbMSwwKgYDVQQD ... aXDrm30UE6+dWdQ3n0ePVLNcHV+ZrIqwka94M/t8HavZpm4y -----END CERTIFICATE----- 然后将 charles.pem 重命名为 faf57fe3.0 (faf57fe3 需根据实际生成结果调整)\n编辑证书内容\r使用命令获取证书扩展内容, 如果没有这一步安装的证书没有详细信息\nopenssl x509 -inform PEM -in faf57fe3.0 -noout -text 输出示例包含证书详细信息, 将其复制并粘贴到证书结尾, 组合为完整的 CA 文件。保存为 UTF-8 编码, 换行符设置为 LF\nCertificate: Data: Version: 3 (0x2) Serial Number: 01:76:ee:04:af:62 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = \u0026#34;Charles Proxy CA (11 Jan 2021, ACESHEEP)\u0026#34;, OU = https://charlesproxy.com/ssl, O = XK72 Ltd, L = Auckland, ST = Auckland, C = NZ Validity Not Before: Jan 9 20:37:33 2021 GMT Not After : Jan 9 20:37:33 2022 GMT Subject: CN = \u0026#34;Charles Proxy CA (11 Jan 2021, ACESHEEP)\u0026#34;, OU = https://charlesproxy.com/ssl, O = XK72 Ltd, L = Auckland, ST = Auckland, C = NZ Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:a1:02:b1:62:11:c1:4d:f3:3f:2d:71:b8:e4:26: .... b0:fc:24:e5:c6:d9:cd:09:01:a8:8f:d4:8e:10:b8: 23:9b Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE Netscape Comment: ....This Root certificate was generated by Charles Proxy for SSL Proxying. If this certificate is part of a certificate chain, this means that you\u0026#39;re browsing through Charles Proxy with SSL Proxying enabled for this website. Please see http://charlesproxy.com/ssl for more information. X509v3 Key Usage: critical Certificate Sign X509v3 Subject Key Identifier: 94:88:6E:5E:E4:17 Signature Algorithm: sha256WithRSAEncryption 8a:e4:47:c4:f2:ba:07:46:08:03:0c:91:94:c9:cf:b4:9c:73: .... ae:39:f3:a2 组合后的完整文件内容\n# cat faf57fe3.0 -----BEGIN CERTIFICATE----- MIIFPjCCBCagAwIBAgIGAXbuBK9iMA0GCSqGSIb3DQEBCwUAMIGjMTQwMgYDVQQD .... 86I= -----END CERTIFICATE----- Certificate: Data: Version: 3 (0x2) Serial Number: 01:76:ee:04:af:62 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = \u0026#34;Charles Proxy CA (11 Jan 2021, ACESHEEP)\u0026#34;, OU = https://charlesproxy.com/ssl, O = XK72 Ltd, L = Auckland, ST = Auckland, C = NZ Validity Not Before: Jan 9 20:37:33 2021 GMT Not After : Jan 9 20:37:33 2022 GMT Subject: CN = \u0026#34;Charles Proxy CA (11 Jan 2021, ACESHEEP)\u0026#34;, OU = https://charlesproxy.com/ssl, O = XK72 Ltd, L = Auckland, ST = Auckland, C = NZ Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:a1:02:b1:62:11:c1:4d:f3:3f:2d:71:b8:e4:26: .... b0:fc:24:e5:c6:d9:cd:09:01:a8:8f:d4:8e:10:b8: 23:9b Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE Netscape Comment: ....This Root certificate was generated by Charles Proxy for SSL Proxying. If this certificate is part of a certificate chain, this means that you\u0026#39;re browsing through Charles Proxy with SSL Proxying enabled for this website. Please see http://charlesproxy.com/ssl for more information. X509v3 Key Usage: critical Certificate Sign X509v3 Subject Key Identifier: 94:88:6E:5E:E4:17 Signature Algorithm: sha256WithRSAEncryption 8a:e4:47:c4:f2:ba:07:46:08:03:0c:91:94:c9:cf:b4:9c:73: .... ae:39:f3:a2 这样组合好后就可以进行下一步了\n导入到安卓手机\r按照以下步骤将证书导入到 /system/etc/security/cacerts/\n关闭验证\radb root restarting adbd as root adb disable-verity using overlayfs Successfully disabled verity Now reboot your device for settings to take effect adb reboot OTA 升级需要开启验证\nadb root restarting adbd as root adb enable-verity Successfully enabled verity Now reboot your device for settings to take effect adb reboot 将证书移动到系统目录\r开发版系统自带 root 的情况\n# 第一个窗口 adb root adb shell su mount -o rw,remount /system # 打开第二个窗口上传证书 adb push faf57fe3.0 /system/etc/security/cacerts/ # 第二个窗口传完证书继续执行 chmod 644 /system/etc/security/cacerts/faf57fe3.0 reboot 使用 Magisk (面具) root\nadb push faf57fe3.0 /sdcard/ adb shell su mount -o rw,remount /system mv /sdcard/faf57fe3.0 /system/etc/security/cacerts/ chmod 644 /system/etc/security/cacerts/faf57fe3.0 reboot 验证证书是否安装成功\r在手机中打开 系统设置 -\u0026gt; 安全 -\u0026gt; 更多安全设置 -\u0026gt; 加密与凭据 -\u0026gt; 信任的凭据, 在 \u0026ldquo;系统\u0026rdquo; 下找到刚才安装的证书 (本人用的 miui12 开发版, 不同手机位置可能不同)\n原文\n抓包安卓7以上ca证书安装方法\n最全面的解决Charles手机抓包的证书问题(步骤非常详细)\n","date":"2021-08-13T07:05:00+08:00","permalink":"https://blog.acesheep.com/p/charles-android-11-setup-guide/","title":"Android 11 Charles 手机抓包安装根证书"},{"content":"在工作中, 经常会遇到导入/导出的需求。以下是常用的 PHP 方法, 用于读取 CSV 文件和导出 CSV 文件\n读取 CSV 文件\r该方法可以分页读取 CSV 文件, 通过设置读取行数和起始行数来控制读取的范围\n/** * 读取 CSV 文件 * @param string $csv_file CSV 文件路径 * @param int $lines 读取的行数 * @param int $offset 起始行数, 从文件的第几行开始读取 * @return array|bool */ public function read_csv_lines($csv_file = \u0026#39;\u0026#39;, $lines = 0, $offset = 0) { if (!$fp = fopen($csv_file, \u0026#39;r\u0026#39;)) { return false; } $i = $j = 0; // 跳过前 $offset 行 while (false !== ($line = fgets($fp))) { if ($i++ \u0026lt; $offset) { continue; } break; } $data = array(); // 读取接下来的 $lines 行数据 while (($j++ \u0026lt; $lines) \u0026amp;\u0026amp; !feof($fp)) { $data[] = fgetcsv($fp); } fclose($fp); return $data; } 导出 CSV 文件\r导出 CSV 文件可以通过两种方法实现\n方法 1: 简单导出 CSV\r方法通过简单的输出流导出数据, 每次将数据行直接输出\n/** * 导出 CSV 文件 * @param array $data 数据 * @param array $header_data 首行数据 * @param string $file_name 文件名称 * @return string */ public function export_csv_1($data = [], $header_data = [], $file_name = \u0026#39;\u0026#39;) { header(\u0026#39;Content-Type: application/octet-stream\u0026#39;); header(\u0026#39;Content-Disposition: attachment; filename=\u0026#39; . $file_name); // 输出表头数据 if (!empty($header_data)) { echo iconv(\u0026#39;utf-8\u0026#39;, \u0026#39;gbk//TRANSLIT\u0026#39;, \u0026#39;\u0026#34;\u0026#39; . implode(\u0026#39;\u0026#34;,\u0026#34;\u0026#39;, $header_data) . \u0026#39;\u0026#34;\u0026#39;) . \u0026#34;\\n\u0026#34;; } // 输出数据 foreach ($data as $key =\u0026gt; $value) { $output = array(); $output[] = $value[\u0026#39;id\u0026#39;]; $output[] = $value[\u0026#39;name\u0026#39;]; echo iconv(\u0026#39;utf-8\u0026#39;, \u0026#39;gbk//TRANSLIT\u0026#39;, \u0026#39;\u0026#34;\u0026#39; . implode(\u0026#39;\u0026#34;,\u0026#34;\u0026#39;, $output) . \u0026#34;\\\u0026#34;\\n\u0026#34;); } } 方法 2: 分页导出 CSV\r方法则分批输出数据, 以防止内存溢出, 每隔一定行数刷新输出缓冲区, 适用于数据量较大的导出\n/** * 导出 CSV 文件 * @param array $data 数据 * @param array $header_data 首行数据 * @param string $file_name 文件名称 * @return string */ public function export_csv_2($data = [], $header_data = [], $file_name = \u0026#39;\u0026#39;) { header(\u0026#39;Content-Type: application/vnd.ms-excel\u0026#39;); header(\u0026#39;Content-Disposition: attachment;filename=\u0026#39; . $file_name); header(\u0026#39;Cache-Control: max-age=0\u0026#39;); // 打开输出流 $fp = fopen(\u0026#39;php://output\u0026#39;, \u0026#39;a\u0026#39;); // 输出表头数据 if (!empty($header_data)) { foreach ($header_data as $key =\u0026gt; $value) { $header_data[$key] = iconv(\u0026#39;utf-8\u0026#39;, \u0026#39;gbk\u0026#39;, $value); } fputcsv($fp, $header_data); } // 分批输出数据 $num = 0; // 每隔 $limit 行刷新一次输出缓冲区, 不要太大, 也不要太小 $limit = 100000; // 逐行取出数据, 不浪费内存 $count = count($data); if ($count \u0026gt; 0) { for ($i = 0; $i \u0026lt; $count; $i++) { $num++; // 刷新输出缓冲区, 防止数据过多造成内存溢出 if ($limit == $num) { ob_flush(); flush(); $num = 0; } // 处理当前行数据 $row = $data[$i]; foreach ($row as $key =\u0026gt; $value) { $row[$key] = iconv(\u0026#39;utf-8\u0026#39;, \u0026#39;gbk\u0026#39;, $value); } fputcsv($fp, $row); } } fclose($fp); } 原文\nPHP 读取/导出 CSV文件\n","date":"2021-08-07T15:57:54+08:00","permalink":"https://blog.acesheep.com/p/php-csv-handling/","title":"PHP 读取/导出 CSV 文件"},{"content":"以下是使用 OpenSSL 进行证书管理和操作的常用命令及说明\nOpenSSL x509 命令\r查看证书信息\ropenssl x509 -in signed.crt -noout -dates # 打印证书的过期时间 openssl x509 -in cert.pem -noout -text # 打印证书的内容 openssl x509 -in cert.pem -noout -serial # 打印证书的序列号 openssl x509 -in cert.pem -noout -subject # 打印证书的拥有者名字 # 按 RFC2253 格式打印拥有者名字 openssl x509 -in cert.pem -noout -subject -nameopt RFC2253 # 在支持 UTF8 的终端中一行打印拥有者名字 openssl x509 -in cert.pem -noout -subject -nameopt oneline -nameopt -escmsb openssl x509 -in cert.pem -noout -fingerprint # 打印证书的 MD5 指纹 openssl x509 -sha1 -in cert.pem -noout -fingerprint # 打印证书的 SHA 指纹 格式转换\r将 PEM 格式的证书转为 DER 格式\nopenssl x509 -in cert.pem -inform PEM -out cert.der -outform DER 证书与 CSR 相关操作\r# 将证书转为 CSR openssl x509 -x509toreq -in cert.pem -out req.pem -signkey key.pem # 使用 CSR 生成自签名证书并增加 CA 扩展项 openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca -signkey key.pem -out cacert.pem # 使用 CSR 生成用户证书并增加扩展项 openssl x509 -req -in req.pem -extfile openssl.cnf -extensions v3_usr -CA cacert.pem -CAkey key.pem -CAcreateserial # 查看 CSR 文件细节 openssl req -in my.csr -noout -text SSL 私钥管理\r证书私钥 (PrivateKey) 添加和去除密码\n检测私钥密码是否正确\r$ openssl rsa -text -noout -in server.key Private-Key: (2048 bit) modulus: 00:b0:fd:c2:81:60:3f:d2:dc:fe:2d:34:c6:46:1e: 08:72:c3:78:f3:4d:12:16:b9:39:3e:0b:d3:8b:e7: … 添加私钥密码\r系统会提示输入并确认密码, 生成加密后的私钥文件 encrypt.key\n$ openssl rsa -des -in server.key -out encrypt.key writing RSA key Enter PEM pass phrase: # 输入密码 Verifying - Enter PEM pass phrase: # 再次输入密码 encrypt.key # 这个文件就是加密过的私钥 移除私钥密码\r系统会提示输入原密码, 生成移除密码的私钥文件 nopassword.key\n$ openssl rsa -in encrypt.key -out nopassword.key writing RSA key Enter PEM pass phrase: # 输入密码 Verifying - Enter PEM pass phrase: # 再次输入密码 移除 PKCS#12 (.pfx 或 .p12) 私钥密码\r当拿到一个包含私钥和公钥的 PKCS#12 格式证书 (.pfx 或 .p12 文件), 并需要将 PKCS#12 格式转换为 PEM 格式, 然后移除私钥密码\n查看证书信息\ropenssl pkcs12 -info -in cert.pfx 格式转换\r将 PKCS#12 转为 PEM\nopenssl pkcs12 -in cert.pfx -out cert2.pem 分离公钥和私钥\r# 提取公钥 openssl x509 -in cert2.pem -out cert2.crt # 提取私钥 openssl rsa -in cert2.pem -out cert2.key 移除私钥密码\ropenssl rsa -in cert2.key -out cert22.key 合并成新的 PFX 文件\ropenssl pkcs12 -export -inkey cert22.key -in cert2.crt -out cert2.pfx 转换回 PEM 格式\ropenssl pkcs12 -in cert2.pfx -out cert22.pem ","date":"2021-07-30T08:45:00+08:00","permalink":"https://blog.acesheep.com/p/openssl-useful-commands/","title":"OpenSSL 常用命令"},{"content":"现在局域网的设备越来越多了, 默认使用 SSL 连接的 Web UI 总是提示不安全。虽然可以选择忽略提示, 但浏览器重启后仍会重置提示。如果为每个设备单独信任证书, 维护成本较高, 所以有了这份笔记。通过创建自定义 CA 根证书, 再由这个 CA 根证书为局域网设备签发证书, 这样只需要信任这个根证书所有的签发的证书都会被信任, 便可解决这一问题。自签主要是为了局域网 IP\n本文介绍如何执行以下操作\n创建自定义证书颁发机构 (CA) 使用自定义 CA 签发自签名证书 准备条件\r本教程基于 OpenSSL 工具\n在 Windows 上安装 Windows OpenSSL, 一般下载 Win64 OpenSSL v1.1.1k Light 版本就足够使用了 许多 Linux 分发版 (如 Ubuntu) 中已预先安装 OpenSSL。WSL2 (我死了啊) 这样的子系统也是可以使用的 创建根 CA 证书\r使用 OpenSSL 创建根 CA 证书\n创建根密钥\r运行以下命令生成根密钥\nopenssl ecparam -out ROOT_CA_PRIVATEKEY.key -name secp384r1 -genkey 如果需要较低加密强度, 可将 secp384r1 替换为 prime256v1\n创建根证书并进行自签名\r生成 CSR 文件\r交互模式, 需要手动填资料\nopenssl req -new -sha256 -key ROOT_CA_PRIVATEKEY.key -out ROOT_CA_CSR.csr 无交互模式\nopenssl req -new -sha256 -key ROOT_CA_PRIVATEKEY.key -out ROOT_CA_CSR.csr -subj \u0026#34;/C=CN/ST=AceSheep/L=AceSheep/OU=ALL/O=AceSheep Blog/CN=Only Copy CA\u0026#34; 配置 CA 根证书扩展\r创建 CA 根证书的配置文件 很重要!! 不然苹果这样严格的设备不会识别为 CA 根证书\n创建配置文件 ROOT_CA.cnf\n# vim ROOT_CA.cnf basicConstraints=critical,CA:TRUE nsComment = \u0026#34;This Root certificate was generated by AceSheep Blog\u0026#34; keyUsage=critical, keyCertSign subjectKeyIdentifier=hash 创建根证书\r运行以下命令生成根证书。稍后你将使用此证书来为服务器证书签名\nopenssl x509 -req -sha256 -days 36500 -extfile ROOT_CA.cnf -in ROOT_CA_CSR.csr -signkey ROOT_CA_PRIVATEKEY.key -out ROOT_CA_CERT.crt 文件结构\r到这一步我们得到了自定义 CA 根证书\n. ├── ROOT_CA.cnf ├── ROOT_CA_CERT.crt ├── ROOT_CA_CSR.csr └── ROOT_CA_PRIVATEKEY.key 创建服务器证书\r接下来, 使用 OpenSSL 创建服务器证书。原理如下: 首先生成私钥和证书签名请求 (CSR), 然后使用 CA 根证书对 CSR 进行签名, 生成最终的证书 (.crt 文件)\n生成私钥和 CSR 文件\r根据不同设备支持的加密算法选择适合的加密方式。这里使用 IP: 192.168.0.1 作为演示\nECDSA (ECC 算法) P-256\rECC (椭圆曲线密码学) 是一种高效的加密方式, 适合较为现代的设备。P-256 是较为常见的曲线, 适用于许多现代设备和应用程序, 具有较好的性能和安全性\nopenssl ecparam -out 192.168.0.1.key -name prime256v1 -genkey openssl req -new -subj \u0026#34;/C=CN/ST=AceSheep/O=AceSheep/OU=LAN/CN=192.168.0.1\u0026#34; -key 192.168.0.1.key -out 192.168.0.1.csr ECDSA (ECC 算法) P-384\rP-384 是一种较强的加密方式, 提供更高的安全性, 适用于需要更高安全要求的设备。虽然它的计算资源消耗比 P-256 更高, 但仍然是许多现代设备支持的有效算法\nopenssl ecparam -out 192.168.0.1.key -name secp384r1 -genkey openssl req -new -subj \u0026#34;/C=CN/ST=AceSheep/O=AceSheep/OU=LAN/CN=192.168.0.1\u0026#34; -key 192.168.0.1.key -out 192.168.0.1.csr RSA 2048-bit\rRSA 是一种传统的加密算法, 广泛应用于嵌入式设备及老旧设备中。如果设备不支持 ECC, 可以选择 RSA, 尤其是对某些较旧或资源有限的设备, 虽然最低推荐为 RSA 3072-bit, 可能只有 RSA 2048-bit 加密才有支持\nopenssl req -newkey rsa:2048 -nodes -subj \u0026#34;/C=CN/ST=AceSheep/O=AceSheep/OU=LAN/CN=192.168.0.1\u0026#34; -keyout 192.168.0.1.key -out 192.168.0.1.csr 使用 CA 根证书签发证书\r配置扩展文件\r在使用 CA 根证书签发证书时, 配置文件的设置非常重要。如果配置不当, 浏览器可能仍会提示连接不安全, 显示错误信息: NET::ERR_CERT_COMMON_NAME_INVALID\n为了避免这个问题, 需要特别注意域名或 IP 地址的配置\n在配置文件中, 必须将需要签发的域名或 IP 地址明确填写到 [alt_names] 部分\n[alt_names]: 用于指定域名 (DNS) 和 IP 地址, 确保证书能够匹配多个名称 DNS.x: 填写需要支持的域名 IP.x: 填写需要支持的 IP 地址 创建配置文件 ssl.cnf\nvim ssl.cnf 内容如下\nauthorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1= localhost DNS.2= localhost.loacl DNS.3= ... IP.1 = 192.168.0.1 IP.2 = 192.168.0.2 IP.3 = ... 签发证书\r证书有效期最长为 13 个月 (398 天), 大于这个时间浏览器会显示不安全。\n首次创建证书并生成序列号文件\nopenssl x509 -req -CA ROOT_CA_CERT.crt -CAkey ROOT_CA_PRIVATEKEY.key -CAcreateserial -days 398 -sha256 -extfile ssl.cnf -in 192.168.0.1.csr -out 192.168.0.1.crt 重新签发证书的正规方式\r为了确保每个证书的唯一性, 在重新签发证书时需要使用首次创建的序列号文件。以下是正确的操作步骤\n首次签发时创建序列号文件\r在第一次创建证书时, 使用 -CAcreateserial 参数生成序列号文件。例如\nopenssl x509 -req -CA ROOT_CA_CERT.crt -CAkey ROOT_CA_PRIVATEKEY.key -CAcreateserial -days 398 -sha256 -extfile ssl.cnf -in 192.168.0.1.csr -out 192.168.0.1.crt 此时, 会生成一个默认的序列号文件, 例如 ROOT_CA_CERT.srl\n保存序列号文件\r将生成的序列号文件重命名并妥善保存, 以便后续更新证书时使用\nmv ROOT_CA_CERT.srl 192.168.0.1.srl 重新签发证书时使用相同的序列号文件\r在更新或重新签发证书时, 需要指定之前保存的序列号文件, 确保证书的唯一性\nopenssl x509 -req -CA ROOT_CA_CERT.crt -CAkey ROOT_CA_PRIVATEKEY.key -CAserial 192.168.0.1.srl -days 398 -sha256 -extfile ssl.cnf -in 192.168.0.1.csr -out 192.168.0.1.crt 注意事项\n确保序列号文件对应正确的域名或 IP 地址 切勿随意删除或覆盖序列号文件, 否则可能导致证书验证问题 -CAserial 参数用于指定序列号文件, 而不再使用 -CAcreateserial 验证证书\r验证签发的证书是否可信\n$ openssl verify -CAfile ROOT_CA_CERT.crt 192.168.0.1.crt 192.168.0.1.crt: OK 输出 OK 表示证书有效\n完成以上步骤后, 将根证书安装到客户端设备, 所有由其签发的证书将被自动信任\n原文\n使用自定义根 CA 生成 Azure 应用程序网关自签名证书\nopenssl-x509, x509 - Certificate display and signing utility\nx509v3_config - X509 V3 certificate extension configuration format\n本地建立CA签发数字证书\n创建自签名SSL证书\n","date":"2021-07-30T07:24:00+08:00","permalink":"https://blog.acesheep.com/p/custom-root-ca-for-lan-ip-certificate/","title":"使用自定义 CA 根证书生成局域网 IP 自签证书"},{"content":"GPG (GNU Privacy Guard) 是一个用于加密和签名数据的开源工具, 广泛用于保护电子邮件通信、文件和数据的隐私。它实现了 OpenPGP 标准, 支持对称加密、非对称加密和数字签名。GPG 可以生成公钥和私钥对, 其中公钥用于加密数据, 私钥用于解密数据和签名消息。它广泛应用于保护敏感信息、防止身份伪造和确保数据完整性\n创建 EdDSA 密钥 (Ed25519)\r要创建一个 EdDSA (Ed25519) 密钥对, 可以使用 GPG 的 --expert 模式, 按照以下步骤生成\n运行以下命令开始创建新密钥\n$ gpg --expert --full-gen-key gpg (GnuPG) 2.1.0; Copyright (C) 2014 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. 在选择密钥类型时, 选择 ECC (sign only) (即 10)\nPlease select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (9) ECC and ECC (10) ECC (sign only) (11) ECC (set your own capabilities) Your selection? 10 选择椭圆曲线 Curve25519\nPlease select which elliptic curve you want: (1) Curve 25519 (2) NIST P-256 (3) NIST P-384 (4) NIST P-521 (5) Brainpool P-256 (6) Brainpool P-384 (7) Brainpool P-512 Your selection? 1 注意, GPG 会警告 Curve25519 尚未成为 OpenPGP 标准的一部分, 但你可以选择继续 (输入 y)\ngpg: WARNING: Curve25519 is not yet part of the OpenPGP standard. Use this curve anyway? (y/N) y 设置密钥的有效期。默认为 0, 表示密钥永不过期\nPlease specify how long the key should be valid. 0 = key does not expire \u0026lt;n\u0026gt; = key expires in n days \u0026lt;n\u0026gt;w = key expires in n weeks \u0026lt;n\u0026gt;m = key expires in n months \u0026lt;n\u0026gt;y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y 输入用户信息 (例如: 真实姓名、电子邮件等)\nGnuPG needs to construct a user ID to identify your key. Real name: Laura Poitras Email address: laura@example.org Comment: You selected this USER-ID: \u0026#34;Laura Poitras \u0026lt;laura@example.org\u0026gt;\u0026#34; Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o [...] 完成后, 系统将生成 Ed25519 密钥, 并提供相关的指纹和密钥 ID\npub ed25519/5C1AFC2A 2014-11-03 Key fingerprint = ED85 4D98 5D8F 502F C6C5 FFB2 AA81 319E 5C1A FC2A uid [ultimate] Laura Poitras \u0026lt;laura@example.org\u0026gt; 列出你拥有的密钥\r要查看本地所有的私钥和公钥, 可以使用以下命令\ngpg --list-secret-keys --keyid-format=long /Users/hubot/.gnupg/secring.gpg ------------------------------------ sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10] uid Hubot ssb 4096R/42B317FD4BA89E7A 2016-03-10 导出公钥\r如果需要导出公钥, 可以使用以下命令\n直接打印公钥\ngpg --armor --export 3AA5C34371567BD2 保存到文件\ngpg --armor --export 3AA5C34371567BD2 --output public.pgp 导出私钥\r同样, 导出私钥可以使用以下命令\n直接打印私钥\ngpg --armor --export-secret-key 3AA5C34371567BD2 保存到文件\ngpg --armor --export-secret-key 3AA5C34371567BD2 --output private.pgp 导出密钥并复制到另一台机器\r若需要将私钥文件复制到另一台机器上, 可以使用以下命令\ngpg --export-secret-key name \u0026gt; ~/my-key.asc 在另一台机器上, 可以通过以下命令导入密钥\ngpg --import my-key.asc 原文\n如何将GPG私钥和公钥导出到文件\nGenerating a new GPG key\nHow can I use GnuPG with ECDSA keys?\nWhat’s new in GnuPG 2.1\n","date":"2021-07-02T23:55:00+08:00","permalink":"https://blog.acesheep.com/p/gpg-export-keys-to-file/","title":"GPG 备份私钥和公钥导出到文件"},{"content":"在申请 SSL 证书之前, 我们需要生成一个 CSR (Certificate Signing Request, 证书请求文件) 文件。CSR 包含服务器信息和单位信息, 用于提交给 CA (证书认证机构) 进行验证。虽然有很多在线工具可以帮助生成 CSR 文件, 但为了避免私钥泄露的风险, 建议使用 WSL2 (Windows Subsystem for Linux) 中的 OpenSSL 工具本地生成该文件。\n可选的加密算法\rRSA (3072-bit, 4096-bit) ECDSA (Elliptic Curve Digital Signature Algorithm) 简称 ECC, 椭圆曲线加密 RSA 算法\rRSA 是一种广泛使用的加密算法。推荐的 RSA 密钥长度为 3072-bit 或 4096-bit, 其中 4096-bit 是最安全的选择。\n生成一个 3072 位的 RSA 私钥和 CSR 文件的命令\nopenssl req -newkey rsa:3072 -keyout PRIVATEKEY.key -out MYCSR.csr ECDSA (ECC) 算法\rECDSA (椭圆曲线加密) 是一种基于椭圆曲线的加密算法。以下是两种推荐方案\n有两种命令等效推荐 方案一\n方案一: 生成私钥和 CSR 文件\r使用以下命令在当前目录生成一个名为 PRIVATEKEY.key 的私钥文件, 加密方式为 prime256v1 (256 位)\nopenssl ecparam -out PRIVATEKEY.key -name prime256v1 -genkey 如果需要更高加密强度, 可以将 prime256v1 替换为 secp384r1, 表示 384 位的椭圆曲线。可以使用以下命令查看支持的密码列表\nopenssl ecparam -list_curves 然后使用生成的私钥文件 PRIVATEKEY.key 生成 CSR 文件。文件名为 MYCSR.csr\nopenssl req -new -key PRIVATEKEY.key -out MYCSR.csr 方案二: 生成参数文件并使用参数文件生成私钥和 CSR\r首先, 使用以下命令将生成一个 256 位 ECDSA 密钥的参数文件 ECPARAM.pem\nopenssl genpkey -genparam -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out ECPARAM.pem -genparam 生成参数文件而不是私钥。 你也可以生成私钥, 但在生成密钥和 CSR 时使用参数文件可确保系统提示你输入密码 -algorithm ec 指定椭圆曲线算法 (ECC) -pkeyopt ec_paramgen_curve:P-256 选择 256 位曲线。如果你需要 384 位曲线, 请将冒号后的部分更改为 P-384 然后使用生成的参数文件来生成私钥和 CSR 文件\nopenssl req -newkey ec:ECPARAM.pem -keyout PRIVATEKEY.key -out MYCSR.csr 如果需要可以合并命令\nopenssl req -newkey ec:\u0026lt;(openssl genpkey -genparam -algorithm ec -pkeyopt ec_paramgen_curve:P-256) -keyout PRIVATEKEY.key -out MYCSR.csr 输入证书所需字段\r无论选择 RSA 还是 ECDSA, 在生成 CSR 文件时, 我们需要根据提示输入一些信息\nCountry Name (2 letter code) [AU]:CN # 国家, 两个字母表示 State or Province Name (full name) [Some-State]:Guizhou # 州或省份, 全称 Locality Name (eg, city) []:Guiyang # 城市名 Organization Name (eg, company) [Internet Widgits Pty Ltd]:AceSheep # 组织名称, 个人申请填写真实姓名拼音 Organizational Unit Name (eg, section) []:IT # 部门名, 个人可填写 IT, 或者留空 Common Name (e.g. server FQDN or YOUR name) []:AceSheep # 填写单域名或泛域名, 此处必填。个人申请填写真实姓名拼音 Email Address []:xxx@example.com # 邮箱地址, 可为空 Please enter the following \u0026#39;extra\u0026#39; attributes to be sent with your certificate request A challenge password []: # 可选, 最好留空 An optional company name []: # 可选公司名, 可留空 按照提示输入完毕后, 私钥文件 (key) 和 CSR 文件会保存在当前目录。这时我们就可以把生成的 CSR 文件提交给 CA 了\n提示: 私钥文件 (key) 非常重要, 务必妥善保存, 不能泄露\n查看 CSR 文件信息\r你可以使用以下命令查看生成的 CSR 文件的内容\nopenssl req -in MYCSR.csr -noout -text 证书供应商签发证书后转换格式\r将 .crt 转换为 .pem\r将证书文件 .crt 转换为 .pem 格式\nopenssl x509 -inform DER -outform PEM -in MYCERT.crt -out MYCERT.pem 合并私钥和证书文件为 .pfx 格式\r将私钥文件和证书文件合并为 .pfx 文件, 以便在 Windows 上使用\n$ openssl pkcs12 -export -inkey PRIVATEKEY.key -in MYCERT.pem -out MYCERTIFICATE.pfx Enter pass phrase for PRIVATEKEY.key: Enter Export Password: Verifying - Enter Export Password: 然后将导出的 .pfx 文件导入 Windows 的证书管理器中。在证书管理器中, 确认证书上是否有私钥提示\n位置在: certmgr.msc -\u0026gt; Personal (个人)\n如果有私钥提示, 表示导入成功, 接下来就可以开始代码签名了!\n原文\nManually Generate a Certificate Signing Request (CSR) Using OpenSSL\nOpenSSL-使用OpenSSL生成CSR文件\nHow to get .pem file from .key and .crt files?\nHow to Verify Your Code Signing Certificate Is Installed (Windows)\n","date":"2021-07-02T21:53:00+08:00","permalink":"https://blog.acesheep.com/p/openssl-generate-csr-file-manually/","title":"使用 OpenSSL 手动生成 CSR 文件"},{"content":"在 MikroTik 路由器的防火墙规则中, mark-connection 和 mark-packet 是两种常用的标记方法。它们的主要区别和应用场景如下\n标记功能的区别\rmark-connection\r用于标记同一连接中的所有数据包。适合需要对整个连接进行统一处理的场景, 比如区分上传和下载流量\n优点: 只需对新连接标记一次, 后续所有属于该连接的数据包都会继承标记, 效率较高 使用场景: 识别双向流量 (上传和下载), 多线路策略路由等 mark-packet\r用于标记单个数据包。适合对每个数据包进行独立判断的场景\n优点: 可以精确标记每个数据包, 适合更细粒度的控制 使用场景: 区分小数据包、TCP 标志 (如 SYN 包) 优先处理等 性能分析\rmark-connection\r/ip firewall mangle add chain=prerouting action=mark-connection new-connection-mark=HTTP protocol=tcp dst-port=80 in-interface=bridge-local add chain=prerouting action=mark-packet new-packet-mark=HTTP in-interface=bridge-local connection-mark=HTTP 上述规则中, 第一条规则只需判断新连接是否符合条件并进行标记。第二条规则则直接根据连接标记对数据包进行处理, 无需重复判断协议和端口等条件。\n优势: 在数据包处理过程中, 减少了重复判断的性能开销 mark-packet\r/ip firewall mangle add chain=prerouting action=mark-packet new-packet-mark=HTTP protocol=tcp dst-port=80 in-interface=bridge-local add chain=prerouting action=mark-packet new-packet-mark=HTTP protocol=tcp dst-port=80 in-interface=pppoe-out1 上述规则对经过的每个数据包都需要判断以下条件\n是否为 TCP 协议？ 目标端口是否为 80？ 进入的网络端口是否符合条件？ 由于每个数据包都需要逐一匹配规则, 性能开销较大\nQoS 场景中的选择\r在 QoS 场景中使用 mark-connection 还是 mark-packet ？\n在 QoS 场景中, 上传和下载需要分开处理, 因此一般会使用 mark-packet 来标记单向数据包 标记小数据包或优先处理 TCP SYN 包等场景, 使用 mark-packet 标记双向流量时, mark-connection 和 mark-packet 都可以, 但 mark-connection 更优 多线路带宽叠加和策略路由\r在多线路叠加和策略路由中, 需要确保同一连接的所有数据包通过同一出口。此时, mark-connection 是更好的选择, 因为它可以确保整个连接的流量保持一致性\n示例规则, 先标记数据再标记路由\n/ip firewall mangle add chain=prerouting action=mark-connection new-connection-mark=pppoe_out1_conn protocol=tcp dst-port=80 connection-state=new add chain=prerouting action=mark-routing new-routing-mark=to_pppoe_out1 connection-mark=pppoe_out1_conn 我实际使用的规则\n/ip firewall mangle add chain=prerouting action=mark-connection in-interface=WAN-1000M-CU-vrrp4-pppoe new-connection-mark=WAN-1000M-CU-vrrp4-pppoe_conn passthrough=yes comment=WAN-1000M-CU-vrrp4-pppoe add chain=prerouting action=mark-routing in-interface=LAN1 new-routing-mark=to_WAN-1000M-CU-vrrp4-pppoe connection-mark=WAN-1000M-CU-vrrp4-pppoe_conn passthrough=yes 总结\rmark-connection: 适用于需要对整个连接进行统一处理的场景, 效率更高, 推荐用于双向流量标记和策略路由 mark-packet: 适用于需要对每个数据包进行独立标记的场景, 适合更细粒度的流量控制 原文\nROS标记中的mark-connection和mark-packet区别\n","date":"2021-06-17T06:41:00+08:00","permalink":"https://blog.acesheep.com/p/routeros-difference-between-mark-connection-and-mark-packet/","title":"RouterOS 标记中的 mark-connection 和 mark-packet 区别"},{"content":"TeamSpeak 是一款老牌的跨平台 VoIP 和文本聊天工具, 广泛应用于在线游戏、企业内部通信、教育培训 (如讲座) 以及朋友间的日常沟通。凭借简单的操作、高安全性、优质语音质量、低系统和带宽占用, TeamSpeak 成为国外用户的首选工具。\n然而, 由于简体中文翻译的长期缺失, 其在国内的普及度受到一定限制。\n简体中文本地化语言包\r简体中文的翻译一直处于空缺状态严重影响了拉萌新入伙, 一直使用的繁体翻译日常使用也很不舒服。所以这个简体中文本地化语言包就诞生了。\n语言包的翻译经历了以下三个阶段\n第一遍: 使用谷歌翻译完成初稿 第二遍: 参考小雾繁体翻译进行手动校对, 大部分词汇已本地化 第三遍: 在实际使用中进行微调, 最终于 2021 年 1 月 22 日完成 此后语言包稳定使用一年无翻译错误 (截至 2022 年 1 月 24 日)\n翻译完成情况\r以下是语言包的翻译进度统计 (已确认/总计翻译数量), 其中待确认部分是尚未找到软件中对应显示位置的内容, 需进一步验证语境是否合适\nerror_report_zh.qm 5/5 lagos_zh.qm 3329/3335 package_installer_zh.qm 28/28 permissions_zh.qm 466/498 qt_zh.qm 1488/1531 ts_core_errors_zh.qm 187/190 update_zh.qm 28/28 语言包信息\r名称: Simplified Chinese (zh-CN) | 简体中文本地化语言包 类型: 翻译 作者: AceSheep 、Tenko 版本 (ts版本/翻译版本/发布时间) : 3.6.2 v1.6 (2024/12/27) 平台: 全部 介绍: TeamSpeak 3 简体中文本地化语言包. 适用于 3.6.2 , 翻译完成度: 99.8%. 又成功拉到一个小萌新入伙! 快上车 下载地址\r文件下载地址: 简体中文本地化语言包 v1.6 支持 TS 3.6.2\n安装语言包\r无法直接打开语言包的解决方法\r如果遇到文件关联程序有误导致无法直接打开语言包的问题, 请使用 TeamSpeak 安装目录中的 package_inst.exe 来打开语言包文件。\n操作步骤\n将语言包文件 (如 简体中文本地化语言包 v1.3(Beta) 支持TS 3.5.6.ts3_translation) 拖动到 package_inst.exe 上, 即可启动安装 完成后, 重新启动 TeamSpeak 即可显示中文 默认安装文件夹路径: C:\\Program Files\\TeamSpeak 3 Client\nTeamSpeak 3 中文字体补丁\r在使用中文翻译时, 如果遇到字体显示不一致的问题, 可以尝试使用字体补丁进行修复。此方法适用于所有 Qt 系列软件\n补丁信息\r本整合包仅包括 64 位 dll, 32 位使用需要自行下载 dll 并重命名\n下载地址: FontMod v2.1 64 位补丁包下载: TeamSpeak 3 中文字体补丁.zip 安装步骤\r下载补丁文件后, 将 FontMod.yaml 和 winmm.dll 复制到 TeamSpeak 3 的安装目录 完成后, 重新启动 TeamSpeak 即可享受改进后的中文字体显示效果 TeamSpeak 3 默认安装位置在 C:\\Program Files\\TeamSpeak 3 Client\n","date":"2021-01-21T14:20:00+08:00","permalink":"https://blog.acesheep.com/p/teamspeak-3-simplified-chinese-translation/","title":"TeamSpeak 3 简体中文翻译 3.6.2"},{"content":"\r树莓派系统配置与优化\r适用于 Raspberry Pi OS (32-bit) Lite 版本\n系统基本信息\r操作系统: Raspberry Pi OS (32-bit) Lite - 2020-08-20 默认主机名: raspberrypi 默认用户: pi 默认密码: raspberry 开启 SSH\r使用树莓派自带的配置工具来开启 SSH 服务\nsudo raspi-config 进入 Interfacing Options -\u0026gt; SSH, 选择 YES 启用 SSH\n修改系统语言与键盘布局\r使用树莓派自带的配置工具进行语言和键盘布局设置\nsudo raspi-config 进入 Localisation Options, 然后按以下顺序进行配置\nChange Locale: 设置为 [*] en_US.UTF-8 UTF-8, 按空格选中 Change Time Zone: 设置为 Asia -\u0026gt; Shanghai Change Keyboard Layout: 设置为 Logitech -\u0026gt; Other -\u0026gt; English (US) -\u0026gt; English (US), 剩下的保持默认即可 解锁 root 用户\r树莓派的 Raspberry Pi OS (Raspbian) 系统 (基于 Debian) 默认 root 账户是锁定的。树莓派启用 root 和 Debian 是相同的。Debian 里 root 账户默认没有密码, 但账户锁定。\n可以通过以下步骤为 root 用户设置密码并解锁\nsudo passwd root sudo passwd --unlock root 关闭不需要的服务\r关闭无线驱动\r为了减少功耗并减少不必要的接口, 可以关闭蓝牙和 Wi-Fi 驱动\ncat \u0026gt; /etc/modprobe.d/raspi-blacklist.conf \u0026lt;\u0026lt;EOF # Wi-Fi blacklist brcmfmac blacklist brcmutil # Bluetooth blacklist btbcm blacklist hci_uart EOF 关闭蓝牙服务\r如果不使用蓝牙, 可以禁用蓝牙服务\nsystemctl disable bluetooth systemctl stop bluetooth 关闭 avahi 服务\r由于树莓派使用简单的单播 DNS, 而不需要多播 DNS 支持, 可以禁用 avahi 服务\nsystemctl disable avahi-daemon systemctl stop avahi-daemon 关闭 TriggerHappy 服务\rDisable TriggerHappy 这个是 raspi-config 依赖程序\n如果树莓派不使用按钮功能, 可以禁用 triggerhappy 服务\nsystemctl disable triggerhappy systemctl stop triggerhappy 关闭 SSH 的 X11 Forwarding 和监听 6100 端口\rX11 Forwarding 功能会导致 SSH 服务监听在不必要的端口 (如 6010)\n如果不需要 X11 转发, 可以禁用此功能。编辑你 SSH 服务器的配置文件\nvi /etc/ssh/sshd_config 找到 X11Forwarding 配置项, 并将其设置为 no\nX11Forwarding no 保存文件并重启 SSH 服务\nsudo service sshd restart 再次检查监听端口之前, 不要忘记重新连接到服务器！\n可以通过以下命令查看监听的端口, 确认 6100 端口已经关闭\nlsof -i4 | grep LISTEN That\u0026rsquo;s it!\n安装 pip\r在树莓派上安装 pip\nsudo apt-get install python3-pip pip3 install --upgrade pip pip install speedtest-cli 切换默认 Python 版本\r为了更方便地使用 Python 3, 将其设置为系统默认版本。为了避免破坏原有的 Python 2.7 环境, 我们采用软链接的方式切换默认 Python 版本。\n查看当前 Python 版本\r首先检查系统中 Python 2 和 Python 3 的版本信息\n# python --version Python 2.7.16 # python3 --version Python 3.7.3 查看 Python 的安装路径\r检查 Python 2 和 Python 3 的安装路径\n# which python /usr/bin/python # which python3 /usr/bin/python3 # 检查软链接关系 # ls /usr/bin/ -all | grep python lrwxrwxrwx 1 root root 7 Mar 4 2019 python -\u0026gt; python2 lrwxrwxrwx 1 root root 9 Mar 4 2019 python2 -\u0026gt; python2.7 -rwxr-xr-x 1 root root 2984816 Oct 11 2019 python2.7 lrwxrwxrwx 1 root root 9 Mar 26 2019 python3 -\u0026gt; python3.7 -rwxr-xr-x 2 root root 4275580 Jul 25 21:03 python3.7 -rwxr-xr-x 2 root root 4275580 Jul 25 21:03 python3.7m lrwxrwxrwx 1 root root 10 Mar 26 2019 python3m -\u0026gt; python3.7m 修改软链接\r# 删除旧的软链接 sudo rm -f /usr/bin/python # 创建新的软链接 sudo ln -s /usr/bin/python3 /usr/bin/python 验证是否成功\r# python --version Python 3.7.3 原文\nDisable unwanted Raspbian Services\nDisabling port 6010 on Ubuntu 16.04\n树莓派——升级为python3.x\n","date":"2020-10-24T03:28:00+08:00","permalink":"https://blog.acesheep.com/p/raspberry-pi-os-initial-setup-guide-for-new-systems/","title":"树莓派 Raspberry Pi OS (Raspbian) 新系统初始化"},{"content":"在 CentOS 7 环境中搭建 Swagger Editor 和 Swagger UI 来管理 API 文档是一个常见的做法\n准备条件\r搭建 Swagger API 文档管理系统, 截止文章发布时配置\nCentOS 7.8.2003 (Core) Swagger Editor v3.14.0 Swagger UI v3.34.0 Node.js LTS Version: 12.18.4 (includes npm 6.14.6) 安装 Node.js\rNode.js 官网文档 基于企业 Linux 的发行版 历史版本\n安装编译依赖\ryum install gcc-c++ make # or yum groupinstall \u0026#39;Development Tools\u0026#39; 安装 Node.js v12.x\r# As root curl -sL https://rpm.nodesource.com/setup_12.x | bash - yum install nodejs 验证安装\r验证 Node.js 和 npm 安装是否成功\n# 查看 Node.js 版本 node -v v12.18.4 # 查看 npm 版本 npm -v 6.14.6 安装 Swagger-Editor\r创建一个 swagger 目录\rcd swagger 下载 Swagger-Editor\r下载最新版本的 Swagger Editor\nwget https://github.com/swagger-api/swagger-editor/archive/v3.14.0.tar.gz tar -xf v3.14.0.tar.gz 安装 http-server\rnpm install -g http-server 启动 Swagger Editor 服务\rhttp-server swagger-editor # 以 8080 端口启动项目 http-server -p 8082 swagger-editor # 指定端口启动项目 http-server -p 8081 swagger-editor-3.14.0 Starting up http-server, serving swagger-editor-3.14.0 Available on: http://127.0.0.1:8081 Hit CTRL-C to stop the server 现在可以在浏览器访问 Swagger-Editor 了, 如 http://127.0.0.1:8081/\n安装 Swagger-UI\r回到 swagger 目录\rcd swagger 下载 Swagger-UI\r下载并解压最新版本的 Swagger UI\nwget https://github.com/swagger-api/swagger-ui/archive/v3.34.0.tar.gz tar -xf v3.34.0.tar.gz 初始化 Node.js 项目\r初始化 Node.js 项目, 创建 package.json 文件\nnpm init # npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do. Use `npm install \u0026lt;pkg\u0026gt;` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (swagger-ui) version: (3.34.0) keywords: author: license: (Apache-2.0) About to write to /root/swagger/swagger-ui-3.34.0/package.json: { \u0026#34;name\u0026#34;: \u0026#34;swagger-ui\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;3.34.0\u0026#34;, \u0026#34;main\u0026#34;: \u0026#34;dist/swagger-ui.js\u0026#34;, \u0026#34;module\u0026#34;: \u0026#34;dist/swagger-ui-es-bundle.js\u0026#34;, \u0026#34;homepage\u0026#34;: \u0026#34;https://github.com/swagger-api/swagger-ui\u0026#34;, \u0026#34;repository\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;git\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;git+ssh://git@github.com/swagger-api/swagger-ui.git\u0026#34; }, \u0026#34;contributors\u0026#34;: [ \u0026#34; (in alphabetical order)\u0026#34;, \u0026#34;Anna Bodnia \u0026lt;anna.bodnia@gmail.com\u0026gt;\u0026#34;, \u0026#34;Buu Nguyen \u0026lt;buunguyen@gmail.com\u0026gt;\u0026#34;, \u0026#34;Josh Ponelat \u0026lt;jponelat@gmail.com\u0026gt;\u0026#34;, \u0026#34;Kyle Shockey \u0026lt;kyleshockey@gmail.com\u0026gt;\u0026#34;, \u0026#34;Robert Barnwell \u0026lt;robert@robertismy.name\u0026gt;\u0026#34;, \u0026#34;Sahar Jafari \u0026lt;shr.jafari@gmail.com\u0026gt;\u0026#34; ], \u0026#34;license\u0026#34;: \u0026#34;Apache-2.0\u0026#34;, \u0026#34;scripts\u0026#34;: { \u0026#34;automated-release\u0026#34;: \u0026#34;release-it -VV --config ./release/.release-it.json\u0026#34;, \u0026#34;build\u0026#34;: \u0026#34;run-p --aggregate-output build-core build-bundle build-standalone build-stylesheets build:es:bundle build:es:bundle:core\u0026#34;, \u0026#34;build-bundle\u0026#34;: \u0026#34;webpack --colors --config webpack/bundle.babel.js\u0026#34;, \u0026#34;build-core\u0026#34;: \u0026#34;webpack --colors --config webpack/core.babel.js\u0026#34;, \u0026#34;build-standalone\u0026#34;: \u0026#34;webpack --colors --config webpack/standalone.babel.js\u0026#34;, \u0026#34;build-stylesheets\u0026#34;: \u0026#34;webpack --colors --config webpack/stylesheets.babel.js\u0026#34;, \u0026#34;build:es:bundle\u0026#34;: \u0026#34;webpack --colors --config webpack/es-bundle.babel.js\u0026#34;, \u0026#34;build:es:bundle:core\u0026#34;: \u0026#34;webpack --colors --config webpack/es-bundle-core.babel.js\u0026#34;, \u0026#34;predev\u0026#34;: \u0026#34;npm install\u0026#34;, \u0026#34;dev\u0026#34;: \u0026#34;webpack-dev-server --config webpack/dev.babel.js\u0026#34;, \u0026#34;deps-license\u0026#34;: \u0026#34;license-checker --production --csv --out $npm_package_config_deps_check_dir/licenses.csv \u0026amp;\u0026amp; license-checker --development --csv --out $npm_package_config_deps_check_dir/licenses-dev.csv\u0026#34;, \u0026#34;deps-size\u0026#34;: \u0026#34;webpack -p --config webpack/bundle.babel.js --json | webpack-bundle-size-analyzer \u0026gt;| $npm_package_config_deps_check_dir/sizes.txt\u0026#34;, \u0026#34;deps-check\u0026#34;: \u0026#34;run-s deps-license deps-size\u0026#34;, \u0026#34;lint\u0026#34;: \u0026#34;eslint --cache --ext \\\u0026#34;.js,.jsx\\\u0026#34; src test\u0026#34;, \u0026#34;lint-errors\u0026#34;: \u0026#34;eslint --cache --quiet --ext \\\u0026#34;.js,.jsx\\\u0026#34; src test\u0026#34;, \u0026#34;lint-fix\u0026#34;: \u0026#34;eslint --cache --ext \\\u0026#34;.js,.jsx\\\u0026#34; src test --fix\u0026#34;, \u0026#34;test\u0026#34;: \u0026#34;run-s just-test-in-node test:unit-jest e2e-cypress lint-errors\u0026#34;, \u0026#34;test-in-node\u0026#34;: \u0026#34;run-s lint-errors just-test-in-node\u0026#34;, \u0026#34;just-test-in-node\u0026#34;: \u0026#34;cross-env BABEL_ENV=test mocha \\\u0026#34;test/mocha/**/*.{js,jsx}\\\u0026#34;\u0026#34;, \u0026#34;test-e2e-cypress\u0026#34;: \u0026#34;cypress run\u0026#34;, \u0026#34;test-e2e-selenium\u0026#34;: \u0026#34;sleep 3 \u0026amp;\u0026amp; nightwatch test/e2e-selenium/scenarios/ --config test/e2e-selenium/nightwatch.json\u0026#34;, \u0026#34;test:artifact\u0026#34;: \u0026#34;run-s test:artifact:umd:bundle test:artifact:es:bundle test:artifact:es:bundle:core\u0026#34;, \u0026#34;test:artifact:umd:bundle\u0026#34;: \u0026#34;npm run build-bundle \u0026amp;\u0026amp; cross-env BABEL_ENV=commonjs jest --config ./config/jest/jest.artifact-umd-bundle.config.js\u0026#34;, \u0026#34;test:artifact:es:bundle\u0026#34;: \u0026#34;npm run build:es:bundle \u0026amp;\u0026amp; cross-env BABEL_ENV=commonjs jest --config ./config/jest/jest.artifact-es-bundle.config.js\u0026#34;, \u0026#34;test:artifact:es:bundle:core\u0026#34;: \u0026#34;npm run build:es:bundle:core \u0026amp;\u0026amp; cross-env BABEL_ENV=commonjs jest --config ./config/jest/jest.artifact-es-bundle-core.config.js\u0026#34;, \u0026#34;test:unit-jest\u0026#34;: \u0026#34;cross-env BABEL_ENV=test jest --config ./config/jest/jest.unit.config.js\u0026#34;, \u0026#34;e2e-initial-render\u0026#34;: \u0026#34;nightwatch test/e2e-selenium/scenarios/ --config test/e2e-selenium/nightwatch.json --group initial-render\u0026#34;, \u0026#34;mock-api\u0026#34;: \u0026#34;json-server --watch test/e2e-selenium/db.json --port 3204\u0026#34;, \u0026#34;hot-e2e-cypress-server\u0026#34;: \u0026#34;webpack-dev-server --config webpack/dev-e2e.babel.js --content-base test/e2e-cypress/static\u0026#34;, \u0026#34;hot-e2e-selenium-server\u0026#34;: \u0026#34;webpack-dev-server --config webpack/dev-e2e.babel.js --content-base test/e2e-selenium/static\u0026#34;, \u0026#34;e2e-cypress\u0026#34;: \u0026#34;run-p -r hot-e2e-cypress-server mock-api test-e2e-cypress\u0026#34;, \u0026#34;dev-e2e-cypress-open\u0026#34;: \u0026#34;cypress open\u0026#34;, \u0026#34;dev-e2e-cypress\u0026#34;: \u0026#34;run-p -r hot-e2e-cypress-server mock-api dev-e2e-cypress-open\u0026#34;, \u0026#34;e2e-selenium\u0026#34;: \u0026#34;run-p -r hot-e2e-selenium-server mock-api test-e2e-selenium\u0026#34;, \u0026#34;open-static\u0026#34;: \u0026#34;node -e \\\u0026#34;require(\u0026#39;open\u0026#39;)(\u0026#39;http://localhost:3002\u0026#39;)\\\u0026#34;\u0026#34;, \u0026#34;security-audit\u0026#34;: \u0026#34;run-s -sc security-audit:all security-audit:prod\u0026#34;, \u0026#34;security-audit:prod\u0026#34;: \u0026#34;npm-audit-ci-wrapper -p -t low\u0026#34;, \u0026#34;security-audit:all\u0026#34;: \u0026#34;npm-audit-ci-wrapper -t moderate\u0026#34;, \u0026#34;serve-static\u0026#34;: \u0026#34;http-server dist/ -i -a 0.0.0.0 -p 3002\u0026#34;, \u0026#34;start\u0026#34;: \u0026#34;npm-run-all --parallel serve-static open-static\u0026#34; }, \u0026#34;dependencies\u0026#34;: { \u0026#34;@babel/runtime-corejs3\u0026#34;: \u0026#34;^7.11.2\u0026#34;, \u0026#34;@braintree/sanitize-url\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;@kyleshockey/object-assign-deep\u0026#34;: \u0026#34;^0.4.2\u0026#34;, \u0026#34;@kyleshockey/xml\u0026#34;: \u0026#34;^1.0.2\u0026#34;, \u0026#34;base64-js\u0026#34;: \u0026#34;^1.2.0\u0026#34;, \u0026#34;classnames\u0026#34;: \u0026#34;^2.2.6\u0026#34;, \u0026#34;core-js\u0026#34;: \u0026#34;^2.6.11\u0026#34;, \u0026#34;css.escape\u0026#34;: \u0026#34;1.5.1\u0026#34;, \u0026#34;deep-extend\u0026#34;: \u0026#34;0.6.0\u0026#34;, \u0026#34;dompurify\u0026#34;: \u0026#34;^2.0.7\u0026#34;, \u0026#34;ieee754\u0026#34;: \u0026#34;^1.1.13\u0026#34;, \u0026#34;immutable\u0026#34;: \u0026#34;^3.x.x\u0026#34;, \u0026#34;js-file-download\u0026#34;: \u0026#34;^0.4.1\u0026#34;, \u0026#34;js-yaml\u0026#34;: \u0026#34;^3.13.1\u0026#34;, \u0026#34;lodash\u0026#34;: \u0026#34;^4.17.19\u0026#34;, \u0026#34;memoizee\u0026#34;: \u0026#34;^0.4.12\u0026#34;, \u0026#34;prop-types\u0026#34;: \u0026#34;^15.7.2\u0026#34;, \u0026#34;randombytes\u0026#34;: \u0026#34;^2.1.0\u0026#34;, \u0026#34;react\u0026#34;: \u0026#34;^15.6.2\u0026#34;, \u0026#34;react-copy-to-clipboard\u0026#34;: \u0026#34;5.0.1\u0026#34;, \u0026#34;react-debounce-input\u0026#34;: \u0026#34;^3.2.0\u0026#34;, \u0026#34;react-dom\u0026#34;: \u0026#34;^15.6.2\u0026#34;, \u0026#34;react-immutable-proptypes\u0026#34;: \u0026#34;2.1.0\u0026#34;, \u0026#34;react-immutable-pure-component\u0026#34;: \u0026#34;^1.1.1\u0026#34;, \u0026#34;react-inspector\u0026#34;: \u0026#34;^2.3.0\u0026#34;, \u0026#34;react-motion\u0026#34;: \u0026#34;^0.5.2\u0026#34;, \u0026#34;react-redux\u0026#34;: \u0026#34;=4.4.10\u0026#34;, \u0026#34;react-syntax-highlighter\u0026#34;: \u0026#34;=13.5.0\u0026#34;, \u0026#34;redux\u0026#34;: \u0026#34;=3.7.2\u0026#34;, \u0026#34;redux-immutable\u0026#34;: \u0026#34;3.1.0\u0026#34;, \u0026#34;remarkable\u0026#34;: \u0026#34;^2.0.1\u0026#34;, \u0026#34;reselect\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;serialize-error\u0026#34;: \u0026#34;^2.1.0\u0026#34;, \u0026#34;sha.js\u0026#34;: \u0026#34;^2.4.11\u0026#34;, \u0026#34;swagger-client\u0026#34;: \u0026#34;=3.11.0\u0026#34;, \u0026#34;url-parse\u0026#34;: \u0026#34;^1.4.7\u0026#34;, \u0026#34;xml-but-prettier\u0026#34;: \u0026#34;^1.0.1\u0026#34;, \u0026#34;zenscroll\u0026#34;: \u0026#34;^4.0.2\u0026#34; }, \u0026#34;devDependencies\u0026#34;: { \u0026#34;@babel/cli\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@babel/core\u0026#34;: \u0026#34;^7.10.2\u0026#34;, \u0026#34;@babel/plugin-proposal-class-properties\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@babel/plugin-proposal-nullish-coalescing-operator\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@babel/plugin-proposal-optional-chaining\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@babel/plugin-transform-runtime\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@babel/preset-env\u0026#34;: \u0026#34;^7.10.2\u0026#34;, \u0026#34;@babel/preset-react\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@babel/register\u0026#34;: \u0026#34;^7.10.1\u0026#34;, \u0026#34;@jest/globals\u0026#34;: \u0026#34;=26.4.2\u0026#34;, \u0026#34;@release-it/conventional-changelog\u0026#34;: \u0026#34;=1.1.4\u0026#34;, \u0026#34;autoprefixer\u0026#34;: \u0026#34;^9.0.0\u0026#34;, \u0026#34;babel-eslint\u0026#34;: \u0026#34;^10.0.0\u0026#34;, \u0026#34;babel-loader\u0026#34;: \u0026#34;^8.1.0\u0026#34;, \u0026#34;babel-plugin-lodash\u0026#34;: \u0026#34;=3.3.4\u0026#34;, \u0026#34;babel-plugin-module-resolver\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;babel-plugin-transform-react-remove-prop-types\u0026#34;: \u0026#34;^0.4.13\u0026#34;, \u0026#34;body-parser\u0026#34;: \u0026#34;^1.19.0\u0026#34;, \u0026#34;bundlesize\u0026#34;: \u0026#34;^0.18.0\u0026#34;, \u0026#34;chromedriver\u0026#34;: \u0026#34;^85.0.0\u0026#34;, \u0026#34;copy-webpack-plugin\u0026#34;: \u0026#34;^6.0.0\u0026#34;, \u0026#34;cors\u0026#34;: \u0026#34;^2.8.5\u0026#34;, \u0026#34;cross-env\u0026#34;: \u0026#34;=7.0.2\u0026#34;, \u0026#34;css-loader\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;cssnano\u0026#34;: \u0026#34;=4.1.10\u0026#34;, \u0026#34;cypress\u0026#34;: \u0026#34;=5.2.0\u0026#34;, \u0026#34;dedent\u0026#34;: \u0026#34;^0.7.0\u0026#34;, \u0026#34;deepmerge\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;enzyme\u0026#34;: \u0026#34;^2.7.1\u0026#34;, \u0026#34;eslint\u0026#34;: \u0026#34;^4.1.1\u0026#34;, \u0026#34;eslint-plugin-import\u0026#34;: \u0026#34;^2.21.1\u0026#34;, \u0026#34;eslint-plugin-jest\u0026#34;: \u0026#34;=24.0.1\u0026#34;, \u0026#34;eslint-plugin-mocha\u0026#34;: \u0026#34;^8.0.0\u0026#34;, \u0026#34;eslint-plugin-react\u0026#34;: \u0026#34;^7.20.0\u0026#34;, \u0026#34;esm\u0026#34;: \u0026#34;=3.2.25\u0026#34;, \u0026#34;expect\u0026#34;: \u0026#34;^1.20.2\u0026#34;, \u0026#34;express\u0026#34;: \u0026#34;^4.17.1\u0026#34;, \u0026#34;file-loader\u0026#34;: \u0026#34;^6.0.0\u0026#34;, \u0026#34;git-describe\u0026#34;: \u0026#34;^4.0.4\u0026#34;, \u0026#34;http-server\u0026#34;: \u0026#34;^0.12.3\u0026#34;, \u0026#34;ignore-assets-webpack-plugin\u0026#34;: \u0026#34;^2.0.1\u0026#34;, \u0026#34;inspectpack\u0026#34;: \u0026#34;=4.5.2\u0026#34;, \u0026#34;jest\u0026#34;: \u0026#34;=25.5.4\u0026#34;, \u0026#34;jsdom\u0026#34;: \u0026#34;=15.2.1\u0026#34;, \u0026#34;json-loader\u0026#34;: \u0026#34;^0.5.7\u0026#34;, \u0026#34;json-merger\u0026#34;: \u0026#34;^1.1.2\u0026#34;, \u0026#34;json-server\u0026#34;: \u0026#34;^0.15.0\u0026#34;, \u0026#34;less\u0026#34;: \u0026#34;^3.11.2\u0026#34;, \u0026#34;license-checker\u0026#34;: \u0026#34;^25.0.0\u0026#34;, \u0026#34;mini-css-extract-plugin\u0026#34;: \u0026#34;^0.11.0\u0026#34;, \u0026#34;mocha\u0026#34;: \u0026#34;=7.2.0\u0026#34;, \u0026#34;nightwatch\u0026#34;: \u0026#34;^1.3.6\u0026#34;, \u0026#34;node-sass\u0026#34;: \u0026#34;^4.14.1\u0026#34;, \u0026#34;npm-audit-ci-wrapper\u0026#34;: \u0026#34;^3.0.0\u0026#34;, \u0026#34;npm-run-all\u0026#34;: \u0026#34;^4.1.5\u0026#34;, \u0026#34;oauth2-server\u0026#34;: \u0026#34;^2.4.1\u0026#34;, \u0026#34;open\u0026#34;: \u0026#34;^7.0.4\u0026#34;, \u0026#34;postcss-loader\u0026#34;: \u0026#34;^3.0.0\u0026#34;, \u0026#34;postcss-preset-env\u0026#34;: \u0026#34;=6.7.0\u0026#34;, \u0026#34;prettier\u0026#34;: \u0026#34;^2.0.0\u0026#34;, \u0026#34;raw-loader\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;react-test-renderer\u0026#34;: \u0026#34;^15.5.4\u0026#34;, \u0026#34;release-it\u0026#34;: \u0026#34;=13.6.5\u0026#34;, \u0026#34;rimraf\u0026#34;: \u0026#34;^3.0.0\u0026#34;, \u0026#34;sass-loader\u0026#34;: \u0026#34;^7.1.0\u0026#34;, \u0026#34;selenium-server-standalone-jar\u0026#34;: \u0026#34;^3.141.5\u0026#34;, \u0026#34;source-map-support\u0026#34;: \u0026#34;^0.5.19\u0026#34;, \u0026#34;standard\u0026#34;: \u0026#34;^11.0.1\u0026#34;, \u0026#34;tachyons-sass\u0026#34;: \u0026#34;^4.9.5\u0026#34;, \u0026#34;terser-webpack-plugin\u0026#34;: \u0026#34;^4.0.0\u0026#34;, \u0026#34;url-loader\u0026#34;: \u0026#34;^2.3.0\u0026#34;, \u0026#34;webpack\u0026#34;: \u0026#34;^4.43.0\u0026#34;, \u0026#34;webpack-bundle-size-analyzer\u0026#34;: \u0026#34;^3.1.0\u0026#34;, \u0026#34;webpack-cli\u0026#34;: \u0026#34;^3.3.11\u0026#34;, \u0026#34;webpack-dev-server\u0026#34;: \u0026#34;^3.11.0\u0026#34;, \u0026#34;webpack-stats-plugin\u0026#34;: \u0026#34;=0.3.2\u0026#34; }, \u0026#34;config\u0026#34;: { \u0026#34;deps_check_dir\u0026#34;: \u0026#34;.deps_check\u0026#34; }, \u0026#34;bundlesize\u0026#34;: [ { \u0026#34;path\u0026#34;: \u0026#34;./dist/swagger-ui-bundle.js\u0026#34;, \u0026#34;maxSize\u0026#34;: \u0026#34;1 MB\u0026#34;, \u0026#34;compression\u0026#34;: \u0026#34;none\u0026#34; } ], \u0026#34;description\u0026#34;: \u0026#34;[![NPM version](https://badge.fury.io/js/swagger-ui.svg)](http://badge.fury.io/js/swagger-ui) [![Build Status](https://jenkins.swagger.io/view/OSS%20-%20JavaScript/job/oss-swagger-ui-master/badge/icon?subject=jenkins%20build)](https://jenkins.swagger.io/view/OSS%20-%20JavaScript/job/oss-swagger-ui-master/) [![npm audit](https://jenkins.swagger.io/buildStatus/icon?job=oss-swagger-ui-security-audit\u0026amp;subject=npm%20audit)](https://jenkins.swagger.io/job/oss-swagger-ui-security-audit/lastBuild/console) ![total GitHub contributors](https://img.shields.io/github/contributors-anon/swagger-api/swagger-ui.svg)\u0026#34;, \u0026#34;bugs\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;https://github.com/swagger-api/swagger-ui/issues\u0026#34; }, \u0026#34;directories\u0026#34;: { \u0026#34;doc\u0026#34;: \u0026#34;docs\u0026#34;, \u0026#34;test\u0026#34;: \u0026#34;test\u0026#34; }, \u0026#34;author\u0026#34;: \u0026#34;\u0026#34; } Is this OK? (yes) 安装 express\rnpm install express --save 创建 public 目录\r创建 public 目录, 并将 swagger-ui/dist 复制到 public 目录\nmkdir public cp -r dist/ public/ 创建 index.js 文件\r创建 index.js 文件, 监听端口 3000\nvim index.js 内容如下\nvar express = require(\u0026#39;express\u0026#39;); var app = express(); var http = require(\u0026#39;http\u0026#39;); app.use(\u0026#39;/static\u0026#39;, express.static(\u0026#39;public\u0026#39;)); app.get(\u0026#39;/\u0026#39;, function (req, res) { res.send(\u0026#39;Hello World!\u0026#39;); }); app.listen(3000, function () { console.log(\u0026#39;Example app listening on port 3000!\u0026#39;); }); 启动服务\rnode index.js 访问地址: http://127.0.0.1:3000/static/index.html\n后台启动进程\r为了使进程在后台运行, 可以使用 nohup 命令\n# 后台启动 Swagger Editor 服务 nohup http-server -p 8081 swagger-editor-3.14.0 \u0026amp; # 查询进程 ps aux | grep http-server # 根据端口号查询进程 lsof -i:8081 # 杀掉进程 kill -9 xxxxx 至此, Swagger Editor 和 Swagger UI 环境搭建完成, 你可以通过浏览器访问和使用这些工具来管理 API 文档, Perfect!\n原文\ncentos 7 搭建 Swagger Editor + Swagger-UI\nCentOS 7 搭建swagger Api文档管理系统\n","date":"2020-09-19T08:52:22+08:00","permalink":"https://blog.acesheep.com/p/centos-7-swagger-editor-and-ui-setup-guide/","title":"CentOS 7 搭建 Swagger API 文档管理系统"},{"content":"\r开发项目步骤\r对于客户来说, App 开发的步骤和周期是非常关心的问题。一个好的创意如果不能快速且有效地落地, 可能会因为各种原因导致项目流产。因此, 需求方和开发方必须清楚了解整个 App 开发流程及周期, 以确保项目按时完成。\n1. 交流需求\r首先, 需要与客户明确 App 的需求, 进行详细定位。通过对项目整体情况的细化, 确保开发团队能够在合同规定的期限内完成项目, 避免因需求不明确导致的经济损失。\n2. 预算评估\r需求文档是 App 开发的核心文件, 有助于明确开发过程的每一步, 可以将整个过程看得一清二楚, 尤其在预算评估阶段显得尤为重要。下载 APP 项目功能表统计报价, 对所需资源进行分析, 可以\n有效降低开发风险 准确估算项目的开发预算和后期运营预算 为 UI 设计师和后期运营提供参考, 减少沟通误差 3. 原型设计\r产品经理根据客户提供的商业模式草图, 制作产品原型图。原型设计包括用户体验设计和 App 界面的交互逻辑, 是后续开发的基础。\n4. UI 设计\r设计用户界面, 需确保界面简洁、美观、操作便捷, 为用户带来良好的使用体验。\n5. 样稿展示\r通过高质量的样稿展示初步效果, 让客户直观感受到 App 的设计成果。这不仅提升客户满意度, 还能在后期开发中节省时间和精力。\n6. 代码开发\r前期准备工作完成后, 就进入最重要的步骤代码开发阶段。此阶段包括:\n前端开发 后端开发 iOS 开发 Android 开发 代码开发通常是整个项目中耗时最长的环节。\n7. 软件测试\r开发完成后, 测试人员需对软件进行全面的 bug 测试, 确保无任何问题后方可上线。\n8. 售后维护\r项目交付后, 开发公司需按照合同规定将源代码、说明文档、操作文档等交给客户。产品上线后进入售后维护阶段, 提供技术支持, 保障 App 的正常运行。\n9. 开发时间进度表\r所有项目开发都具有明确的时间周期。为了让客户及时了解项目进展, 开发团队必须制定一份详细的开发时间进度表。通过定期或按月更新进度表, 清晰展示已完成的开发任务, 让客户能够实时掌握开发状态和项目进度, 从而确保项目按照预期顺利推进。\n下载 APP 开发项目周期表 下载 软件开发进度表 原文\nApp软件开发项目步骤和周期（含：附件下载）\n软件开发进度表\n","date":"2020-09-15T01:39:00+08:00","permalink":"https://blog.acesheep.com/p/app-software-development-steps-and-timeline/","title":"App 软件开发项目步骤和周期"},{"content":"基础安装\rHomebrew 是 MacOS 上的程序包管理器, 可以将其视为 Linux 上 apt-get 的等效工具。通过 Homebrew 安装 FFmpeg 非常简单, 使用以下命令即可完成基础安装\nbrew install ffmpeg 完整安装脚本 (支持所有依赖项)\r截止至 2020 年 3 月 25 日, MacOS + Homebrew 的 FFmpeg 安装已禁用本机依赖项支持。如果需要构建带有其他库的完整版本, 可以使用以下脚本\nbrew install nasm pkg-config texi2html aom fontconfig freetype frei0r gnutls lame libass libbluray libsoxr libvorbis libvpx opencore-amr openjpeg opus rtmpdump rubberband sdl2 snappy speex tesseract theora x264 x265 xvid xz brew uninstall --force --ignore-dependencies ffmpeg brew install chromaprint amiaopensource/amiaos/decklinksdk brew tap homebrew-ffmpeg/ffmpeg brew install ffmpeg brew cask install xquartz brew upgrade homebrew-ffmpeg/ffmpeg/ffmpeg $(brew options homebrew-ffmpeg/ffmpeg/ffmpeg | grep -vE \u0026#39;\\s\u0026#39; | grep -- \u0026#39;--with-\u0026#39; | grep -vi chromaprint | grep -vi game-music-emu | tr \u0026#39;\\n\u0026#39; \u0026#39; \u0026#39;) 该脚本来源于社区讨论, 被认为是最完整的安装脚本。原始链接: brew install ffmpeg with all options\n安装后信息\r安装完成后, 可以使用以下命令查看 FFmpeg 的详细信息\nbrew info ffmpeg 示例输出 (截至 2020 年 8 月 30 日)\nffmpeg: stable 4.3.1 (bottled), HEAD Play, record, convert, and stream audio and video https://ffmpeg.org/ /usr/local/Cellar/ffmpeg/4.3.1-with-options_2 (267 files, 55MB) * Built from source on 2020-08-30 at 02:10:22 with: --with-decklink --with-fdk-aac --with-librsvg --with-libsoxr --with-libssh --with-tesseract --with-libvidstab --with-opencore-amr --with-openh264 --with-openjpeg --with-openssl --with-rav1e --with-rubberband --with-webp --with-zeromq --with-zimg --with-srt --with-libvmaf --with-libxml2 --with-libbluray --with-libbs2b --with-libcaca --with-libgsm --with-libmodplug --with-openssl@1.1 --with-rtmpdump --with-speex --with-two-lame --with-wavpack --with-xvid From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/ffmpeg.rb License: GPL-2.0 ==\u0026gt; Dependencies Build: nasm , pkg-config , texi2html Required: aom , dav1d , fontconfig , freetype , frei0r , gnutls , lame , libass , libbluray , libsoxr , libvidstab , libvorbis , libvpx , opencore-amr , openjpeg , opus , rav1e , rtmpdump , rubberband , sdl2 , snappy , speex , srt , tesseract , theora , webp , x264 , x265 , xvid , xz ==\u0026gt; Options --HEAD Install HEAD version ==\u0026gt; Analytics install: 92,312 (30 days), 392,610 (90 days), 1,286,857 (365 days) install-on-request: 73,930 (30 days), 309,668 (90 days), 972,270 (365 days) build-error: 0 (30 days) 常见问题及解决方案\rlibclang_rt.ubsan_osx_dynamic.dylib 错误\r错误信息\n% ffmpeg dyld: Library not loaded: @rpath/libclang_rt.ubsan_osx_dynamic.dylib Referenced from: /usr/local/opt/game-music-emu/lib/libgme.0.dylib Reason: image not found zsh: abort ffmpeg 解决方法: 重新安装 FFmpeg, 并移除 --with-game-music-emu 选项\nlibxml2 依赖路径问题\r安装过程中可能出现以下提示\n==\u0026gt; Caveats ==\u0026gt; libxml2 libxml2 is keg-only, which means it was not symlinked into /usr/local, because macOS already provides this software and installing another version in parallel can cause all kinds of trouble. If you need to have libxml2 first in your PATH run: echo \u0026#39;export PATH=\u0026#34;/usr/local/opt/libxml2/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.zshrc For compilers to find libxml2 you may need to set: export LDFLAGS=\u0026#34;-L/usr/local/opt/libxml2/lib\u0026#34; export CPPFLAGS=\u0026#34;-I/usr/local/opt/libxml2/include\u0026#34; For pkg-config to find libxml2 you may need to set: export PKG_CONFIG_PATH=\u0026#34;/usr/local/opt/libxml2/lib/pkgconfig\u0026#34; 解决方法: 按照提示执行以下命令, 最后再重新运行安装脚本\necho \u0026#39;export PATH=\u0026#34;/usr/local/opt/libxml2/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.zshrc export LDFLAGS=\u0026#34;-L/usr/local/opt/libxml2/lib\u0026#34; export CPPFLAGS=\u0026#34;-I/usr/local/opt/libxml2/include\u0026#34; export PKG_CONFIG_PATH=\u0026#34;/usr/local/opt/libxml2/lib/pkgconfig\u0026#34; 原文\nHOW TO INSTALL FFMPEG ON MACOS?\n","date":"2020-08-30T12:55:00+08:00","permalink":"https://blog.acesheep.com/p/macos-catalina-10.15.4-install-ffmpeg-with-all-dependencies/","title":"MacOS Catalina 10.15.4 安装包含所有依赖的 FFmpeg"},{"content":"\r对于 Windows 系统中的中文输入法 (适用于 1809、1903、1909 版本), 其独立表情面板默认强制绑定快捷键 Ctrl+Shift+B, 且无法通过语言设置项更改。为解决此问题, 可以通过手动修改注册表或使用命令行实现解绑。\n需要注意: 从 Windows 2004 版本起, 中文输入法的表情面板已改为系统通用的表情面板 (比之前的更精简, 但不如原来单独的表情面板信息丰富), 可通过快捷键 Win + . 呼出, 因此本教程仅适用于 2004 版本之前的系统\n解决方案\r手动修改注册表\r打开注册表编辑器 (Win + R, 输入 regedit)\n定位到以下路径\nHKEY_CURRENT_USER\\Software\\Microsoft\\InputMethod\\Settings\\CHS 在右侧窗口中, 新建一个 DWORD(32位) 值\n名称 EnableOpenEmoticonSymbolView 值 0 这样设置后, 快捷键 Ctrl+Shift+B 将不再被强制绑定\n使用 .reg 文件导入\r将以下内容保存为 .reg 文件 (例如 unbind_emoticon_shortcut.reg), 然后双击运行以导入注册表设置\nWindows Registry Editor Version 5.00 [HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\InputMethod\\Settings\\CHS] \u0026#34;EnableOpenEmoticonSymbolView\u0026#34;=dword:00000000 使用命令行导入\r以管理员身份运行命令提示符 (cmd), 执行以下命令直接修改注册表\nreg add \u0026#34;HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\InputMethod\\Settings\\CHS\u0026#34; /t REG_DWORD /v EnableOpenEmoticonSymbolView /d 0 /f ","date":"2020-08-01T20:31:21+08:00","permalink":"https://blog.acesheep.com/p/windows-10-disable-ctrl-shift-b-emoji-shortcut-in-microsoft-input-method/","title":"在 Windows 10 微软输入法中禁用 Ctrl+Shift+B 表情符号快捷键"},{"content":"\r假设我们有如下网页地址\nhttp://www.example.com/index.html http://www.example.com/index.php 如果希望隐藏 .html 或 .php 后缀, 使其变为以下形式\nhttp://www.example.com/index http://www.example.com/index 可以根据服务器类型 (Apache 或 Nginx) 使用不同的方法实现\nApache\r隐藏 .html 后缀\n在 .htaccess 文件中添加以下规则\nRewriteEngine On\rRewriteCond %{REQUEST_FILENAME} !-f\rRewriteRule ^([^\\.]+)$ $1.html [NC,L] 隐藏 .php 后缀\n在 .htaccess 文件中添加以下规则\nRewriteEngine On\rRewriteCond %{REQUEST_FILENAME} !-f\rRewriteRule ^([^\\.]+)$ $1.php [NC,L] Nginx\r方法一: 使用 try_files\r在 nginx 配置文件中, 添加以下代码到对应的 server 配置块\nlocation / { try_files $uri $uri/ $uri.php$is_args$args; } 方法二: 使用 if 判断\r隐藏 .html 后缀\n在 nginx 配置文件中, 添加以下规则\nif (!-f $request_filename) { set $rule_0 1$rule_0; } if ($rule_0 = \u0026#34;1\u0026#34;) { rewrite ^/([^\\.]+)$ /$1.html last; } 隐藏 .php 后缀\n在 nginx 配置文件中, 添加以下规则\nif (!-f $request_filename) { set $rule_0 1$rule_0; } if ($rule_0 = \u0026#34;1\u0026#34;) { rewrite ^/([^\\.]+)$ /$1.php last; } 原文\n利用.htaccess隐藏html和php后缀\nApache (httpd) 伪静态设置\nnginx一招配置，帮你快速隐藏php后缀名\n","date":"2020-05-23T13:28:00+08:00","permalink":"https://blog.acesheep.com/p/web-server-hide-php-extension/","title":"Web 服务器隐藏 PHP 后缀"},{"content":"在备份磁盘时, 只备份了系统盘, 测试恢复时并没有遇到什么问题。直到磁盘分区表发生变化, 分区扇区大小变小了, 导致无法恢复备份。\n遇到解决扇区不一致的问题时, 又碰到了 UEFI 引导错误。修复引导后, 系统就可以继续使用之前备份的系统。\n为什么会遇到修复分区的问题呢？\r当然是因为手头这台生产力工具 (其实是吃灰工具) WiFi 出现了问题, 送修了。修完后, 下行速度只有 20Mbps, 微软修完后速度更低了\u0026hellip;于是决定备份系统盘镜像。\n送修后, 技术支持会抹掉磁盘并重新安装一个新的系统。重新配置系统实在太麻烦了, 因此才想着备份系统盘镜像。\n这次也总结出需要备份以下数据 分区表, UEFI, 系统盘, 恢复盘\n修复 UEFI\r修复 UEFI 引导时, 需要一个 PE 系统。进入系统后打开 cmd, 如果 EFI 分区还在, 只是被破坏需要修复, 可以执行以下命令\nbcdboot c:\\windows # 英文版 bcdboot c:\\windows /l cn-zh # 中文版 如果连 EFI 分区都没有了, 可以通过以下步骤重新分配 EFI 分区 (你也可以使用 DiskGenius 等工具来分配 EFI 分区)\ndiskpart list disk # 列出磁盘 select disk * # 选择要重建 EFI 分区的磁盘编号, * 以数字代替 list partition # 查看所有分区 # 如果有大于 100MB 的未分配空间, 跳过下两步 select partition * # 选择要减少 100MB 空间的分区编号 shrink desired = 100 # 缩小分区, 腾出 100MB 空间 create partition efi size = 100 # 创建 100MB 的 EFI 分区 format quick fs = fat32 # 格式化 EFI 分区 exit bcdboot c:\\windows /l cn-zh # 将系统盘的引导信息复制到 EFI 分区 原文\nUEFI分区的重建办法, 不需要额外软件\n基于 UEFI/GPT 的硬盘驱动器分区\n","date":"2020-05-21T07:24:14+08:00","permalink":"https://blog.acesheep.com/p/windows-10-rebuild-uefi-partition/","title":"Windows 10 重建 UEFI 分区"},{"content":"在水群时无意间看到一个 TCP + TLS 的操作, 以为是玩什么梗, 结果真有这样的配置操作。于是决定尝试搭建一下。对于新手, 建议使用 TLS 分流器 方案 (划掉\n目前, Vmess + WebSocket + TLS (以下简称 wss) 作为一种常见的方案, 由于其伪装能力极强, 像 HTTPS 流量一样, 可以隐藏 V2Ray 的路径。这种方式能够通过主动探测和伪装正常的 HTTP 网站响应来绕过审查, 广泛应用于隐匿流量。\n然而, 这种强大的伪装能力需要付出性能代价, 特别是在 TLS 1.3 握手需要消耗 1 RTT (Round-trip time) 和 WebSocket 握手也需要消耗 1 RTT, 这会增加握手延迟。此外, V2Ray 引入了 mux 来减少握手的发生, 但实际使用中 mux 体验并不好, 很多用户选择关闭。\n最近, 新的工具 Trojan, 它将类似 Socks 的协议直接通过 TLS 传输, 同时将认证失败的流量交由 Web 服务器处理, 从而减少了 WebSocket 握手的延迟, 同时保持了与 wss 相同的伪装能力。然而, Trojan 工具较为年轻, 没有路由功能, 各平台的图形化客户端也不完善, 因此仍有一定局限性。\n基于此, 本篇尝试用 V2Ray 实现类似功能, 采用 Vmess + TCP + TLS, 并通过网站伪装省下 WebSocket 握手延迟。\n工作原理\rHAProxy 监听 443 端口, 处理完 TLS 流量后, 将 HTTP 请求交由 Web 服务器处理, 其他非 HTTP 流量则交由 V2Ray 按照 Vmess 协议处理\n准备条件\r本方案使用以下组件:\nHAProxy: 作为 TLS 反向代理和流量分发器 Web 服务器: 如 Caddy 或 Nginx, 用于处理 HTTP 请求 V2Ray: 作为 Vmess 协议的处理器 服务器系统: CentOS 7 实现步骤\r本次方案使用 HAProxy, Caddy/Nginx (Web 服务器的使用不是本教程的重点, 可以用 httpd 等替代), V2Ray, 服务器系统为 CentOS 7。\n安装 HAProxy\n为支持 TLS1.3, HAProxy 版本应大于 1.8.15, OpenSSL 版本应大于 1.1.1。如果你的系统自带的版本较低, 建议自行编译安装。\n安装 Web 服务器\n可以选择 Nginx 或 Caddy 作为 Web 服务器。以 Nginx 为例, 添加官方软件仓库后, 使用以下命令安装\nyum install nginx 安装 V2Ray\n可以使用 V2Ray 官方的安装脚本进行安装\n修改 V2Ray 配置文件\n编辑 V2Ray 配置文件, 以 Vmess 协议和 TCP 方式监听 40001 端口\n{ \u0026#34;inbounds\u0026#34;: [ { \u0026#34;protocol\u0026#34;: \u0026#34;vmess\u0026#34;, \u0026#34;listen\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;port\u0026#34;: 40001, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;f2435e5c-9ad9-4367-836a-8341117d0a5f\u0026#34; } ] }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;tcp\u0026#34; } } ], \u0026#34;outbounds\u0026#34;: [ { \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34; } ] } 配置 Web 服务器\n配置 Web 服务器部署 HTTP 服务于 8080 端口, 以下为 Caddy 和 Nginx 的配置示例\nCaddy 配置\nhttp://example.com:8080 { root /var/www/html } Nginx 配置\nserver { listen 8080; server_name example.com; root /var/www/html; } 配置 HAProxy\n修改 HAProxy 配置文件, 监听 443 端口并区分 HTTP 和非 HTTP 流量\nglobal\rlog /dev/log local0\rlog /dev/log local1 notice\rchroot /var/lib/haproxy\rstats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners\rstats timeout 30s\ruser haproxy\rgroup haproxy\rdaemon\rca-base /etc/ssl/certs\rcrt-base /etc/ssl/private\r# 仅使用支持 FS 和 AEAD 的加密套件\rssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\rssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\r# 禁用 TLS 1.2 之前的 TLS\rssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11\rtune.ssl.default-dh-param 2048\rdefaults\rlog global\r# 我们需要使用 tcp 模式\rmode tcp\roption dontlognull\rtimeout connect 5s\r# 空闲连接等待时间, 这里使用与 V2Ray 默认 connIdle 一致的 300s\rtimeout client 300s\rtimeout server 300s\rfrontend tls-in\r# 监听 443 tls, tfo 根据自身情况决定是否开启, 证书放置于 /etc/ssl/private/example.com.pem\rbind *:443 tfo ssl crt /etc/ssl/private/example.com.pem\rtcp-request inspect-delay 5s\rtcp-request content accept if HTTP\r# 将 HTTP 流量发给 web 后端\ruse_backend web if HTTP\r# 将其他流量发给 vmess 后端\rdefault_backend vmess\rbackend web\rserver server1 127.0.0.1:8080\rbackend vmess\rserver server1 127.0.0.1:40001 注意: HAProxy 的证书和密钥需合并到一个文件中, 可以使用以下命令合成证书\ncat example.com.crt example.com.key \u0026gt; example.com.pem 重启服务\n重启 HAProxy、Web 服务器 (Caddy/Nginx) 和 V2Ray 服务\nsystemctl restart haproxy systemctl restart caddy systemctl restart v2ray 客户端配置\n在客户端配置文件中, 客户端连接 example.com:443, 使用 Vmess 和 TLS 协议\n{ \u0026#34;inbounds\u0026#34;: [ { \u0026#34;port\u0026#34;: 1080, \u0026#34;listen\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;socks\u0026#34; } ], \u0026#34;outbounds\u0026#34;: [ { \u0026#34;protocol\u0026#34;: \u0026#34;vmess\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;vnext\u0026#34;: [ { \u0026#34;address\u0026#34;: \u0026#34;example.com\u0026#34;, \u0026#34;port\u0026#34;: 443, \u0026#34;users\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;f2435e5c-9ad9-4367-836a-8341117d0a5f\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;none\u0026#34; } ] } ] }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;tcp\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;tls\u0026#34; } } ] } 性能测试\r测试工具为 vmessping, 可见 Vmess + TCP + TLS (左) 延迟低于 Vmess + WSS (右)\n但是我的实际测试效果没有明显改变\n总结\r性能优化\nHAProxy、V2Ray 和 Nginx 都支持 Domain Socket, 如果流量较大或数据包较多, 使用 Socket 可以提高性能\n隐蔽性\n与 wss 比较\n中间人监听时, 该方法在建立 TLS 连接后, 比 wss 少了一次握手。TLS 建立后直接发送请求并获得响应, 这符合正常 HTTPS 请求的行为 主动探测时, 如 TLS 建立后发送 HTTP 请求, 将被转发到 Web 服务器进行处理。如果发送的是非 HTTP 请求, 则会被转发给 V2Ray 处理。如果 Vmess 认证失败, 连接会被关闭。发送非 HTTPS 请求给 HTTPS 服务器时, 连接也会被关闭, 这是正常的行为 原文\nTCP + TLS + Web\n","date":"2020-05-09T07:48:02+08:00","permalink":"https://blog.acesheep.com/p/centos-7-v2ray-tcp-tls-web-protocol-setup/","title":"CentOS 7 V2ray TCP + TLS + Web 协议"},{"content":"HAProxy 是一种免费、高效且可靠的解决方案, 可为基于 TCP 和 HTTP 的应用程序提供高可用性、负载均衡和代理功能。它特别适用于高流量的网站, 并为世界上许多访问量最大的网站提供支持\n为了更好地支持 TLS 1.3, HAProxy 版本应使用 1.8.15 或更高版本, 同时 OpenSSL 的版本需要在 1.1.1 及以上。如果你当前的系统软件仓库中提供的版本较低, 需要通过编译安装的方式获取新版本\n准备条件\rHAProxy 2.0.14 OpenSSL 1.1.1g Lua 5.3.5 zlib 通过系统软件仓库获取 pcre 通过系统软件仓库获取 安装与编译依赖\r安装开发工具与依赖库\ryum groupinstall \u0026#34;Development Tools\u0026#34; yum install -y pcre-devel zlib-devel bzip2-devel systemd-devel readline-devel gcc gcc-c++ make 创建 HAProxy 专属用户\ruseradd -s /sbin/nologin -M haproxy 安装依赖 OpenSSL 1.1.1g\r# 下载并解压 wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz tar -xf openssl-1.1.1g.tar.gz cd openssl-1.1.1g # 编译并安装 less INSTALL ./config --prefix=/usr/local/openssl --openssldir=/usr/local/ssl make make test make install echo /usr/local/openssl/lib \u0026gt;\u0026gt; /etc/ld.so.conf.d/openssl.conf ldconfig /usr/local/openssl/bin/openssl version -a 安装依赖 Lua 5.3.5\r# 下载并解压 wget http://www.lua.org/ftp/lua-5.3.5.tar.gz tar -xf lua-5.3.5.tar.gz cd lua-5.3.5 # 编译并安装 make linux make install INSTALL_TOP=/usr/local/lua 安装 HAProxy 2.0.14\rHAProxy 快速安装说明\n# 下载并解压 wget http://www.haproxy.org/download/2.0/src/haproxy-2.0.14.tar.gz tar -xf haproxy-2.0.14.tar.gz cd haproxy-2.0.14 # 编译并安装 make TARGET=linux-glibc PREFIX=/usr/local/haproxy USE_OPENSSL=1 USE_ZLIB=1 USE_PCRE=1 USE_SYSTEMD=1 SSL_INC=/usr/local/openssl/include SSL_LIB=/usr/local/openssl/lib USE_LUA=1 LUA_LIB=/usr/local/lua/lib/ LUA_INC=/usr/local/lua/include/ make install PREFIX=/usr/local/haproxy /usr/local/haproxy/sbin/haproxy -vv 配置 HAProxy\r创建配置文件目录和文件\nmkdir /etc/haproxy vim /etc/haproxy/haproxy.cfg 配置文件1: 基本 HTTP 配置\r# 全局配置\rglobal\r# 设置日志\rlog 127.0.0.1 local3 info\rchroot /usr/local/haproxy\r# 用户与用户组\ruser haproxy\rgroup haproxy\r# 守护进程启动\rdaemon\r# 最大连接数\rmaxconn 4000\r# 默认配置\rdefaults\rlog global\rmode http\roption httplog\roption dontlognull\rtimeout connect 5000\rtimeout client 50000\rtimeout server 50000\rlisten stats\rbind 0.0.0.0:1080 # 监听端口\rstats refresh 30s # 统计页面自动刷新时间\rstats uri /stats # 统计页面 url\rstats realm Haproxy Manager # 统计页面密码框上提示文本\rstats auth admin:admin # 统计页面用户名和密码设置\r#stats hide-version # 隐藏统计页面上 HAProxy 的版本信息\r# 前端配置, http_front 名称可自定义\rfrontend http_front\r# 发起 http 请求到 80 端口, 会被转发到设置的 IP 及端口\rbind *:80\r# haproxy 的状态管理页面, 通过 /haproxy?stats 来访问\rstats uri /haproxy?stats\rdefault_backend http_back\r# 后端配置, http_back 名称可自定义\rbackend http_back\r# 负载均衡方式\r# - source 根据请求源 IP\r# - static-rr 根据权重\r# - leastconn 最少连接者先处理\r# - uri 根据请求的 uri\r# - url_param 根据请求的 url 参数\r# - rdp-cookie 据据 cookie (name) 来锁定并哈希每一次请求\r# - hdr(name) 根据 HTTP 请求头来锁定每一次 HTTP 请求\r# - roundrobin 轮询方式\rbalance roundrobin\r# 设置健康检查页面\roption httpchk GET /index.html\r# 传递客户端真实 IP\roption forwardfor header X-Forwarded-For\r# inter 2000 健康检查时间间隔 2 秒\r# rise 3 检测多少次才认为是正常的\r# fall 3 失败多少次才认为是不可用的\r# weight 30 权重\r# 需要转发的 IP 及端口\rserver node1 192.168.0.4:80 check inter 2000 rise 3 fall 3 weight 30\rserver node2 192.168.0.5:80 check inter 2000 rise 3 fall 3 weight 30 配置文件2: 仅状态页面\r# 全局设置\rglobal\r# 以后台进程运行\rdaemon\ruser haproxy\r# 用户与用户组\rgroup haproxy\r# 每个进程的最大连接数\rmaxconn 3500\r# 进程数, 该值可以设置小于或等于 cpu 核心数\r# balance roundrobin 负载均衡轮询方式\r# balance source 负载均衡类似 nginx 的 ip_hash\r# balance leastconn 负载均衡最小连接\rnbproc 1\r# 默认设置\rdefaults\r# 设置 http (七层模式), 也可设置为 tcp (四层模式)\r# 另外还有一个 Health 健康监测模式\r# 对 mysql 进行负载均衡的话, 这里记得修改为 tcp\rmode http\rtimeout connect 5000ms\rtimeout client 50000ms\rtimeout server 50000ms\r# 配置 haproxy 管理页面\rlisten admin_stats\r# 访问端口为 9999\rbind *:9999\rmode http\r# 继承 global 中 log 的定义\rlog global\r# 自动刷新时间\rstats refresh 30s\r# 路径为 status, ip+端口+路径即可访问\rstats uri /status\r# 配置管理用户账号密码\rstats auth admin:admin\r# 设置统计页面认证时的提示内容\rstats realm Private lands\rstats admin if TRUE\r# 隐藏统计页面上的 haproxy 版本信息\rstats hide-version 配置文件3: 带状态页面与负载均衡\r# 全局配置\rglobal\r# 配置全局日志记录\r# local0 为日志设备\r# notice 为输出的日志级别\r# 127.0.0.1 表示使用本地机器上的 rsyslog 服务中的 local0 设备记录日志等级为 notice 的日志\r# log loghost local0 info 定义 haproxy 日志级别\rlog 127.0.0.1 local0 notice\r# 工作目录\r#chroot /usr/local/haproxy-1.5.15\r# 创建 1 个进程进入 deamon 模式运行, 以后台形式运行 harpoxy\rdaemon\r# 用户与用户组\ruser haproxy\rgroup haproxy\r# 可以接收的最大并发连接数\rmaxconn 20480\r# haproxy 进程 PID 文件\rpidfile /var/run/haproxy.pid\rdefaults\r# 所处理的类别, tcp 是四层, http 是七层, health 只会返回 OK, 若是混合模式则 mode 不需要设置\rmode http\r# 定义日志, 采用全局定义\rlog global\r# 不记录健康检查的日志信息\roption dontlognull\r# 每次请求完毕后主动关闭 http 通道\roption httpclose\r# 日志类别为 http 日志格式\r# 如果是混合模式, 此处还需要加上 tcpclog\roption httplog\r# 后端服务器可以从 Http Header 中获得客户端 IP\r#option forwardfor\r# serverId 对应的服务器挂掉后, 强制定向到其他健康的服务器\roption redispatch\r# 设置默认负载均衡方式, 轮询方式\rbalance roundrobin\r# 连接超时\rtimeout connect 10s\r# 客户端连接超时\rtimeout client 10s\r# 服务器连接超时\rtimeout server 10s\r# 健康检测的超时时间\rtimeout check 10s\r# 最大连接数\rmaxconn 60000\r# 3 次连接失败就为服务不可用\rretries 3\r# 统计页面配置\r# 为 haproxy 访问状态监控页面配置, 取名为 admin_stats\rlisten admin_stats\r# 监听端口\rbind 0.0.0.0:8189\r# 启用监听端口\rstats enable\r# http 的 7 层模式\rmode http\r# 继承 global 中 log 的定义\rlog global\r# 页面自动刷新时间 30s\rstats refresh 30s\r# 监控页面的 url 访问路径, 即 http://ip/stats 访问监控页面\rstats uri /stats\r# 监控页面的用户和密码 admin, 可以设置多个用户名\rstats auth admin:admin\r# 监控页面的密码框提示信息\rstats realm Haproxy Statistics\r# 隐藏统计页面上 HAProxy 的版本信息\rstats admin if TRUE\r#stats hide-version\r# 当通过认证才可管理\r# web 设置\r# 定义 webcluster 服务器组\rlisten webcluster\r# 定义 haproxy 前端部分监听的端口\rbind 0.0.0.0:81\r# http 的 7 层模式\rmode http\r# 心跳检测 7 层访问\r#option httpchk GET /index.html\r# 继承 global 中 log 的定义\rlog global\r# server 进程可接受的最大并发连接数\rmaxconn 3000\r# 负载均衡的方式: 轮询\rbalance roundrobin\r# 根据 cookie 轮询\rcookie SESSION_COOKIE insert indirect nocache\rserver web01 10.6.76.27:1988 check inter 2000 fall 5\rserver web02 10.6.76.28:1988 check inter 2000 fall 5\r#server web01 192.168.80.102:80 cookie web01 check inter 2000 fall 5\r#server web02 192.168.80.103:80 cookie web01 check inter 2000 fall 5 配置文件4: TCP + TLS + Web\r这是我使用的配置文件, TCP + TLS + Web 方案\nglobal\rlog /dev/log local0\rlog /dev/log local1 notice\rchroot /usr/local/haproxy\r#stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners\r#stats timeout 30s\ruser haproxy\rgroup haproxy\rdaemon\rca-base /etc/ssl/certs\rcrt-base /etc/ssl/private\r# 仅使用支持 FS 和 AEAD 的加密套件\rssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384\rssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\r# 禁用 TLS 1.2 之前的 TLS\rssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11\rtune.ssl.default-dh-param 2048\rdefaults\rlog global\r# 我们需要使用 tcp 模式\rmode tcp\roption dontlognull\rtimeout connect 5s\r# 空闲连接等待时间, 这里使用与 V2Ray 默认 connIdle 一致的 300s\rtimeout client 300s\rtimeout server 300s\rlisten stats\r# 监听端口\rbind 0.0.0.0:1080\rstats enable\rmode http\r# 统计页面自动刷新时间\rstats refresh 30s\r# 统计页面 url\rstats uri /stats\r# 统计页面密码框上提示文本\rstats realm Haproxy Manager\r# 统计页面用户名和密码设置\rstats auth admin:admin\rfrontend tls-in\r# 监听 443 tls, tfo 根据自身情况决定是否开启, 证书放置于 /etc/ssl/private/example.com.pem\rbind *:443 tfo ssl crt /root/com.pem\rtcp-request inspect-delay 5s\rtcp-request content accept if HTTP\r# 将 HTTP 流量发给 web 后端\ruse_backend web if HTTP\r# 将其他流量发给 vmess 后端\rdefault_backend vmess\rbackend web\rserver server1 127.0.0.1:8080\rbackend vmess\rserver server1 127.0.0.1:40001 运行与测试\r测试配置文件\r/usr/local/haproxy/sbin/haproxy -c -f /etc/haproxy/haproxy.cfg 启动 HAProxy\r/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg 访问 Web UI 状态页面\rhttp://\u0026lt;your-ip\u0026gt;:1080/stats 设置系统服务\r创建服务文件\r创建 HAProxy 的 systemd 服务文件, 编辑文件 /lib/systemd/system/haproxy.service\n[Unit] Description=Haproxy Service After=syslog.target network.target [Service] Type=forking ExecStart=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg # ExecReload=/bin/kill -USR2 $MAINPID ExecReload=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -sf $(cat /var/run/haproxy.pid) # ExecStop=cd\u0026amp;\u0026amp;/usr/local/haproxy/sbin/\u0026amp;\u0026amp;pkill haproxy KillMode=mixed Restart=always [Install] WantedBy=multi-user.target 创建软连\rln -s /lib/systemd/system/haproxy.service /etc/systemd/system/multi-user.target.wants/haproxy 常用命令\r# 重新载入配置文件 systemctl daemon-reload # 启动 haproxy systemctl start haproxy # 停止 haproxy systemctl stop haproxy # 开机启动 systemctl enable haproxy 查看 haproxy 是否运行\rps -ef | grep haproxy haproxy 74886 1 0 07:59 ? 00:00:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg haproxy 74948 1 0 08:00 ? 00:00:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg root 74965 74037 0 08:03 pts/2 00:00:00 grep --color=auto haproxy 原文\ncentos7下haproxy2.0加lua编译安装并加入系统启动\nHaproxy在centos7下的安装及配置\ncentos7编译安装haproxy\n","date":"2020-05-09T02:44:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-build-haproxy-2.0/","title":"CentOS 7 编译安装 HAProxy 2.0"},{"content":"Google 为了提升用户数据和设备的安全性, 在 Android P (9.0) 系统中默认要求应用程序使用加密连接 (TLS)。这意味着运行 Android P 的设备将禁止 App 使用未加密的 HTTP 明文传输。所有网络流量必须通过加密协议 (如 TLS) 传输。而 Android Nougat (7.1) 和 Oreo (8.1) 系统不受此限制\n如果需要在 Android P 中允许未加密的连接 (如调试或兼容旧系统), 可以通过以下步骤配置网络安全策略\n创建 network_security_config.xml\r在项目的 res 文件夹下创建 xml 文件夹, 然后在该文件夹中创建文件 network_security_config.xml\n添加以下内容\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;network-security-config\u0026gt; \u0026lt;!-- 允许明文流量 (HTTP) --\u0026gt; \u0026lt;base-config cleartextTrafficPermitted=\u0026#34;true\u0026#34;\u0026gt; \u0026lt;!-- 指定信任的证书源 --\u0026gt; \u0026lt;trust-anchors\u0026gt; \u0026lt;!-- 信任系统证书 --\u0026gt; \u0026lt;certificates src=\u0026#34;system\u0026#34; overridePins=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;!-- 信任用户安装的证书 --\u0026gt; \u0026lt;certificates src=\u0026#34;user\u0026#34; overridePins=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;/trust-anchors\u0026gt; \u0026lt;/base-config\u0026gt; \u0026lt;/network-security-config\u0026gt; 在 AndroidManifest.xml 中引用配置文件\r在应用的 AndroidManifest.xml 文件中, 引用刚创建的网络安全配置\n\u0026lt;application android:networkSecurityConfig=\u0026#34;@xml/network_security_config\u0026#34; android:allowBackup=\u0026#34;true\u0026#34; android:label=\u0026#34;@string/app_name\u0026#34; android:icon=\u0026#34;@mipmap/ic_launcher\u0026#34;\u0026gt; ... \u0026lt;/application\u0026gt; 原文\nAndroid 9.0网络权限适配\n","date":"2020-04-14T03:12:32+08:00","permalink":"https://blog.acesheep.com/p/android-9.0-network-permission-adaptation/","title":"Android 9.0 网络权限适配"},{"content":"在 RedHat/CentOS/Fedora 系统中, 使用 yum update 更新软件时, 默认会升级内核。然而, 某些硬件可能在升级内核后无法被新内核识别, 导致需要重新安装驱动程序, 增加维护复杂性。因此, 在生产环境中, 应避免轻易升级内核, 除非已确认升级后不会引发问题\n方法一: 修改 yum 配置文件\r通过编辑 yum 的配置文件, 永久性地禁止内核升级\n使用 vim 编辑器打开 yum 的配置文件\nvim /etc/yum.conf 在 [main] 部分的末尾添加以下内容\nexclude=kernel* exclude=centos-release* 方法二: 在 yum 命令中临时排除内核更新\r如果不想修改配置文件, 可以在运行 yum update 时直接添加排除参数\nyum --exclude=kernel* update 原文\n使用yum更新时不升级Linux内核的方法\n","date":"2020-03-26T08:10:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-yum-update-without-kernel-upgrade/","title":"CentOS 7 yum 更新时不升级 Linux 内核方法"},{"content":"我们已经了解如何使用注册表编辑器 (regedit.exe) 更改注册表项和子项的所有权。本文将向你介绍如何通过命令行更改注册表项的所有权并授予权限的方法。\n在 Windows 系统中, 可以使用 takeown.exe 和 icacls.exe 更改文件或文件夹的所有权和权限, 但并没有类似工具可以直接通过命令行更改注册表项的所有权。为此, 我们可以使用第三方工具 SetACL 来实现。\nSetACL 的命令行参数简介\rSetACL 是一个强大的工具, 可用于更改文件、注册表项、网络共享等对象的所有权和权限。以下是其命令行的基本语法\nSetACL -on objectname -ot objecttype -actn action -on: 指定操作的对象路径 (如文件、注册表项, 网络共享, 服务, 打印机等) -ot: 指定对象类型。对于文件或文件夹, 使用 file；对于注册表项, 使用 reg -actn: 指定操作类型。setowner 用于更改所有权, ace 用于更改权限 有关更详细的说明, 请参考 SetACL文档\n更改注册表项的所有权和权限\r下载并安装 SetACL\r前往 SetACL 官方网站, 下载并解压工具 将 setacl.exe (根据系统选择 32 位或 64 位版本) 复制到一个文件夹, 例如 D:\\tools 注册表项的所有权并分配权限\r假设要更改注册表项 HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160} 的所有权, 并授予 Administrators 组完全控制权限\n在 管理员模式 下打开命令提示符, 运行以下命令\n设置 Administrators 组为所有者\nSetACL.exe -on \u0026#34;HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160}\u0026#34; -ot reg -actn setowner -ownr \u0026#34;n:Administrators\u0026#34; 授予 Administrators 组完全控制权限\nSetACL.exe -on \u0026#34;HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160}\u0026#34; -ot reg -actn ace -ace \u0026#34;n:Administrators;p:full\u0026#34; 你可以使用注册表编辑器进行检查, 该 Administrators 组拥有此项及其子项, 还具有完全控制权限\n递归设置\r若要对注册表项及其所有子项设置所有权和权限, 可在命令中添加 -rec Yes 参数\nSetACL.exe -on \u0026#34;HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160}\u0026#34; -ot reg -actn setowner -ownr \u0026#34;n:Administrators\u0026#34; -rec Yes SetACL.exe -on \u0026#34;HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160}\u0026#34; -ot reg -actn ace -ace \u0026#34;n:Administrators;p:full\u0026#34; -rec Yes 设置 TrustedInstaller 为所有者 owner\r如果需要设置 TrustedInstaller (NT SERVICE\\TrustedInstaller) 为注册表项的所有者并递归分配其完全控制权限, 可以使用以下命令\nSetACL.exe -on \u0026#34;HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160}\u0026#34; -ot reg -actn setowner -ownr \u0026#34;n:nt service\\trustedinstaller\u0026#34; -rec Yes SetACL.exe -on \u0026#34;HKEY_CLASSES_ROOT\\CLSID\\{D63B10C5-BB46-4990-A94F-E40B9D520160}\u0026#34; -ot reg -actn ace -ace \u0026#34;n:nt service\\trustedinstaller;p:full\u0026#34; -rec Yes 运行上述命令后, 将 TrustedInstaller 设置为项和子项的所有者\n更改注册表项权限时出错？\r尝试更改你无权访问的文件/文件夹或注册表项的权限时, SetACL 报告以下错误。为防止发生此错误, 请确保先更改其所有权, 然后再更改控制权限\nSetACL finished with error(s): SetACL error message: The call to SetNamedSecurityInfo () failed Operating system error message: Access is denied. 扩展阅读\rMicrosoft SubInACL\n在 Windows XP 时代, Microsoft 还发布了另一个名为 SubInACL 的控制台工具。它是 Windows XP/2003 资源工具包工具的一部分。它可以更改文件、文件夹和注册表的所有权和权限。但由于 Microsoft 已停止使用 SubInACL, 并且它默认为 32 位文件和注册表路径 (在 Windows 64 位系统上), 因此在某些情况下无法在 64 位版本的 Windows 中使用\nMicrosoft Regini.exe\nRegini.exe 是另一个内置工具, 可通过脚本更改注册表权限, 但无法更改注册表项的所有者\nHelge Klein SetACL\nSetACL 是功能最全面的工具, 支持更改所有权、权限, 并填补了 SubInACL 和 Regini 的不足\n原文\nTake Ownership of Registry Key \u0026amp; Assign Permissions Using Command-line\nHow to change registry values or permissions from a command line or a script\n","date":"2020-03-24T07:21:17+08:00","permalink":"https://blog.acesheep.com/p/take-ownership-of-registry-key-using-command-line/","title":"使用命令行获取注册表的所有权"},{"content":"首先, 确保你完全不再需要该应用。对于 Windows 10 中的 Modern 应用, 通常可以在右键菜单卸载, 但某些预装应用 (如 Xbox、天气、人脉、照片等) 无法通过右键菜单卸载。\n即使你没有打开该应用, 进程里 YourPhone 都会存在, 许多用户因此烦恼。如果你不需要此应用, 如何卸载它呢？\n卸载步骤\r卸载人脉\r打开 PowerShell (以管理员身份), 输入以下命令\nGet-AppxPackage *people* | Remove-AppxPackage 卸载手机\r如果上面的命令无效, 你需要先输入 Get-AppxPackage -AllUsers, 获取系统中所有已安装应用的列表, 从列表中找到你要卸载的应用, 并找到其全名称, 即 PackageFullName。如果你觉得太长, 可以把结果复制到记事本中查找关键字。\n找到应用的全名后, 使用以下命令进行卸载。替换 PackageFullName 为应用全名\nRemove-AppxPackage PackageFullName 打开 PowerShell (以管理员身份), 输入以下命令\nGet-AppxPackage Microsoft.YourPhone -AllUsers | Remove-AppxPackage 完成上述步骤后, YourPhone 应用将被彻底卸载, 并且在任务管理器中也不会再看到该进程\n原文\nwin10怎么卸载人脉\nWin10系统怎么删除我的手机应用关闭YourPhone进程\n","date":"2020-03-23T09:28:16+08:00","permalink":"https://blog.acesheep.com/p/windows-10-delete-people-and-yourphone-apps/","title":"Windows 10 删除人脉和手机系统应用"},{"content":"如果在第一次安装或更新升级后启动 Razer Synapse 3 时遇到 \u0026ldquo;failed to start\u0026rdquo; 的问题, 并且通过常规的修复方法 (如重装、删除所有跟 Razer 相关文件及注册表等) 都无法解决, 后来经过自己研究可能是因为 Razer Synapse Service 服务无法启动, 并显示服务依赖的服务不存在或已删除。以下是一个有效的解决办法\n检查服务状态\n打开 服务 (Services.msc), 检查是否有以下服务\nRazer Synapse Service Razer Game Manager Service RzActionSvc 如果只有 Razer Synapse Service, 但缺少 Razer Game Manager Service 和 RzActionSvc。恭喜你, 你的问题可以通过这个教程解决\n解决步骤\r恢复 RzActionSvc 服务\r找到以下路径中的日志文件, 注意文件名可能与示例不同。(请注意, ProgramData 文件夹是隐藏的, 需启用查看隐藏文件)\nC:\\ProgramData\\Razer\\Installer\\Logs\\RazerInstaller-cb19c464-e8c4-429d-93f5-55093fee4228.log 用记事本打开 log 文件, 搜索 RazerCentral, 搜到之后找到对应的 \u0026lt;DownloadURL\u0026gt;\n将 URL 复制到浏览器中, 下载文件并安装\n由于我修改过系统编码, 程序可能会出现乱码。这是因为我开启了 UTF-8 Beta 模式\n开始菜单中搜索 powershell, 以管理员模式启动\n输入以下命令\nNew-Service -Name \u0026#34;RzActionSvc\u0026#34; -BinaryPathName \u0026#34;C:\\Program Files (x86)\\Razer\\Razer Services\\Razer Central\\RazerCentralService.exe\u0026#34; 如果没有错误, 现在可以在服务中查看 RzActionSvc 是否存在, 并尝试启动该服务\n恢复 Razer Game Manager Service 服务\r打开日志文件, 搜索 GMS, 找到 \u0026lt;DownloadURL\u0026gt;, 将 URL 复制到浏览器中, 下载文件并安装\n安装\n打开 PowerShell (以管理员身份), 输入以下命令\nNew-Service -Name \u0026#34;Razer Game Manager Service\u0026#34; -BinaryPathName \u0026#34;C:\\Program Files (x86)\\Razer\\Razer Services\\GMS\\GameManagerService.exe\u0026#34; 现在可以去服务中检查是否有 Razer Game Manager Service, 并尝试启动该服务\n启动 Razer Synapse Service\r完成上述两项服务恢复后, 尝试启动 Razer Synapse Service 服务\n如果顺利启动, 恭喜你, 你可以正常使用 Razer Synapse 3 了\n终于把这个辣鸡管理程序启动起来了! 真鸡儿费劲\n原文\n如果你的雷云3出现“failed to start”, 请看过来\n","date":"2020-03-13T05:29:00+08:00","image":"https://blog.acesheep.com/p/fix-razer-synapse-3-failed-to-start/20200313055544_hu105966967144685904.png","permalink":"https://blog.acesheep.com/p/fix-razer-synapse-3-failed-to-start/","title":"雷云 3 \"Failed to start\" 修复"},{"content":"在启用 SELinux 的情况下, 默认情况下系统会阻止非标准端口的使用。如果你想启用一个非常用端口 (例如 8090), 你需要手动将该端口添加到 SELinux 的白名单中\n操作步骤\r安装 semanage 命令\r如果你遇到 semanage: command not found 错误, 说明你的系统未安装 semanage 工具。你可以根据不同的 CentOS 版本来安装所需的软件包\n查找命令对应的软件包名称\n[root@123123 ~]# yum provides /usr/sbin/semanage Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: ftp.iij.ad.jp * elrepo: ftp.ne.jp * epel: ftp.iij.ad.jp * extras: ftp.iij.ad.jp * updates: ftp.iij.ad.jp policycoreutils-python-2.5-33.el7.x86_64 : SELinux policy core python utilities Repo : base Matched from: Filename : /usr/sbin/semanage CentOS 7 安装命令\ryum install policycoreutils-python CentOS 8 安装命令\ryum install policycoreutils-python-utils 查看 Nginx 启动的用户组\rNginx 启动时会使用以下用户组\nuser nginx; 配置文件测试的端口\r在 Nginx 配置文件中, 需要设置一些端口来监听, 例如\nserver { listen 8090; # does not work # listen 8080; # works # listen 9090; # does not work # listen 9090 default; # does not work neighter # listen 80; # works! server_name \u0026lt;some IP\u0026gt;; ... } 查看 SELinux HTTP 端口列表\r你可以通过以下命令查看当前 SELinux 所允许的 HTTP 端口\nsemanage port -l | grep http_port_t http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 添加自定义端口\r如果你希望在 SELinux 中启用端口 8090, 可以执行以下命令\nsemanage port -a -t http_port_t -p tcp 8090 通过以上步骤, 你可以在 SELinux 环境下启用自定义端口, 以便 Nginx 或其他服务能够绑定并使用这些端口。如果没有添加到白名单, SELinux 将阻止应用程序绑定到这些端口。\n原文\nnginx: no permission to bind port 8090 but it binds to 80 and 8080\nHow to Fix ‘semanage command’ Not Found Error in CentOS/RHEL\n","date":"2020-03-09T18:18:00+08:00","permalink":"https://blog.acesheep.com/p/eslinux-nginx-add-additional-port/","title":"ESlinux 为 Nginx 添加额外端口"},{"content":"接触 OpenWRT 一年多, 大部分时间都在进行固件编译和刷机。在这个过程中遇到过不少问题, 下面记录下编译过程的详细步骤, 供以后参考\n操作步骤\r准备工具:\n系统环境: Ubuntu 16.04 LTS 64 位 路由器型号: ZBT-WA05 OpenWRT 版本: CC 编译过程建议使用非 root 用户\n安装编译所需的工具\r打开终端, 输入以下命令安装所需的编译工具\nsudo apt-get update sudo apt-get install git-core build-essential libssl-dev libncurses5-dev unzip sudo apt-get install subversion mercurial sudo apt-get install gcc g++ binutils patch bzip2 flex bison make autoconf gettext texinfo unzip sharutils subversion libncurses5-dev ncurses-term zlib1g-dev 下载 OpenWRT 源码\r下载 OpenWRT 源码前, 请确保有足够的磁盘空间 (至少 12GB)。源码体积约为几百 MB, 但编译过程中会产生大量文件。由于大部分 SVN 仓库都是失效的, 所以一些老的教程就不能参考了, 要使用 Git 下载源码。\n要下载哪个版本, 可以参考 OpenWRT 的 wiki。以 CC 版本为例, 在主文件夹下执行以下命令\ngit clone git://git.openwrt.org/15.05/openwrt.git 安装可用的 feeds\r进入 OpenWRT 源码目录, 更新并安装依赖\ncd openwrt ./scripts/feeds update -a ./scripts/feeds install -a 等待下载完成\n配置编译选项\r执行以下命令进行编译配置\nmake menuconfig 在弹出的配置界面中, 可以通过方向键选择、空格键进行选项勾选 (出现 M 表示编译但不打包进固件, * 表示编译并打包进固件)。根据 ZBT-WA05 路由器的配置, 选择硬件平台、CPU 型号等选项\n建议勾选以下选项 (前面出现 * 号)\nLuCI (Web 界面的控制台) LuCI -\u0026gt; 1.Collections -\u0026gt; luci LuCI -\u0026gt; 2.Modules -\u0026gt; Translations -\u0026gt; Chinese(zh-cn) (中文语言包) 勾选 Package the OpenWrt-base Toolchain, OpenWRT 的交叉编译工具链 完成后, 选 Save 保存更改, 退出\n以上是基本的固件编译, 如果需要其他功能, 需要再勾选添加\n编译固件\r执行以下命令开始编译\nmake V=s -j V=s 用于显示编译信息, 一定要勾选, 否则出错的话无法看到错误信息 -j 代表使用全部的 CPU 线程数, 后面跟数字表示并行编译线程数 (例如: 4C8T 的 CPU 可以使用 -j8 代表使用 8 个线程)。可以根据自己 CPU 核心数选择线程数, 但请确保系统内存足够, 若不确定可以省略 -j 参数或使用 -j1 编译完成后, 显示如下信息并且终端上没有 error 时, 表示编译成功\nSigning package index... make[2]: Leaving directory \u0026#39;/home/goldmoon/openwrt\u0026#39; make[1]: Leaving directory \u0026#39;/home/goldmoon/openwrt\u0026#39; /home/goldmoon/openwrt/bin/ramips/openwrt-ramips-mt7620-zbt-wa05-squashfs-sysupgrade.bin 结尾的文件路径即为编译出的固件文件\n常见错误排查\r在编译过程中, 可能会遇到一些错误, 大部分都是文件下载错误 (OpenWRT 源码仓库通常在国外, 最好自备梯子), 有时候需要科学上网才行。或手动下载缺失的文件放到 dl 目录中。\n网络配置\rLAN (Local Area Network, 局域网): 指的是一个局限在较小范围内 (如家庭、公司等) 的网络, 通常用于连接在同一地理位置内的设备。我们计算机和路由器之间的连接通常就是通过这个口进行\nAN (Wide Area Network, 广域网): 指的是覆盖较大地理范围的网络, 通常指的是通过运营商提供的互联网连接。运营商拉进来的网线通常连接到路由器的 WAN 口\nVLAN (Virtual Local Area Network, 虚拟局域网): VLAN 是一种将局域网划分为多个虚拟网段的技术。通过 VLAN, 一个物理网络可以被逻辑划分为多个独立的子网, 使得不同 VLAN 之间的设备通常不能直接通信。这样做的目的是为了提高网络的安全性和管理性。VLAN 可以在同一局域网内创建多个独立的网络段, 而 LAN 和 WAN 也可以在 VLAN 中划分\n配置 WAN 口和 LAN 口\r在 OpenWRT 中, 网络配置文件位于 /etc/config/ 目录下。特别是 WAN 和 LAN 口的配置在 /etc/config/network 文件中。以下是基本的配置示例\n配置文件的参数注释\nconfig interface \u0026#39;lan\u0026#39; # 配置 LAN 口 option type \u0026#39;bridge\u0026#39; # 桥接方式 option ifname \u0026#39;eth0.1\u0026#39; # 代表 VLAN1, 这个很重要, 必须与下文的 switch 配置一致 option proto \u0026#39;static\u0026#39; # 静态 IP config device \u0026#39;lan_dev\u0026#39; # 配置 LAN 硬件信息 option macaddr \u0026#39;XX:XX:XX:XX:XX:XX\u0026#39; # 设置 MAC 地址 config interface \u0026#39;wan\u0026#39; # 配置 WAN 口 option type \u0026#39;dhcp\u0026#39; # 使用 DHCP 获取 IP 地址 config switch # 交换机 option enable_vlan \u0026#39;1\u0026#39; # 启用 VLAN config switch_vlan option vlan \u0026#39;1\u0026#39; # VLAN1, 配置 LAN 口。和上面的 option ifname \u0026#39;eth0.1\u0026#39; 相匹配 option ports \u0026#39;0 1 2 3 6t\u0026#39; # 0-3 是 LAN 口, 6t 为 CPU 端口, RT5350 有 5 个端口 config switch_vlan option vlan \u0026#39;2\u0026#39; # VLAN2, 配置 WAN 口。和上面的 option ifname \u0026#39;eth0.2\u0026#39; 相匹配 option ports \u0026#39;4 6t\u0026#39; # 4 是 WAN 口, 6t 为 CPU 端口 配置解释:\nconfig interface 'lan': 配置 LAN 口, eth0.1 对应的是 VLAN1 config interface 'wan': 配置 WAN 口, 使用 DHCP 自动获取 IP 地址 config switch: 启用 VLAN 功能 config switch_vlan: 配置 VLAN1 和 VLAN2, 分别对应 LAN 和 WAN 口 原文\n官方文档: Build system – Installation\nOpenWRT编译——从源码到固件\nOpenWRT(二)配置WAN口和LAN口\n","date":"2020-03-03T00:45:05+08:00","permalink":"https://blog.acesheep.com/p/openwrt-compilation-from-source-to-firmware/","title":"OpenWRT 编译从源码到固件"},{"content":"通过 VNC 连接到甲骨文 (Oracle Cloud) 的实例\n操作步骤\r创建连接密钥\r通过 PuTTY 的 puttygen.exe 生成 .ppk 公钥和私钥\n下载 PuTTYgen\n如果你还没有安装, 可以从官网 PuTTY 下载页面 下载 puttygen.exe 生成 SSH 密钥对\n启动 puttygen.exe 后, 选择密钥类型 (通常选择 RSA 或 Ed25519, 具体视你的需求而定)。默认是 RSA, 一般情况下选择 RSA 即可 选择密钥长度, 通常使用 2048 或 4096 位 (越大越安全) 在 \u0026ldquo;Parameters\u0026rdquo; 部分设置合适的密钥位数, 比如 2048 或 4096 (推荐2048位) 生成密钥\n点击 Generate 按钮来开始生成密钥对 按住鼠标左键并随机移动鼠标, 直到进度条满, 这鼠标坐标值作为随机数, 生成密钥 保存密钥\n保存私钥: 点击 Save private key 按钮, 将私钥保存到本地。PuTTY 使用的私钥格式是 .ppk 保存公钥: 点击 Save public key 按钮, 将公钥保存到本地。公钥格式是 .pub.ppk 登录甲骨文云控制台\r打开你的甲骨文控制台, 查看实例的详细信息\n创建控制台连接\r点击 \u0026ldquo;控制台连接\u0026rdquo; 选项, 选择 \u0026ldquo;创建控制台连接\u0026rdquo;\n添加你的 .pub 文件\r在弹出的窗口中, 浏览你的 .pub 文件, 并将其粘贴到指定位置\n完成创建并查看连接状态\r创建完成后, 连接的状态变成绿色。然后, 点击左侧的三个点, 选择 \u0026ldquo;使用 VNC 连接\u0026rdquo;\n复制 VNC 密码\r点击 \u0026ldquo;WINDOWS\u0026rdquo; 按钮, 再点击 \u0026ldquo;复制\u0026rdquo;\n复制后, 你会得到类似以下的一段字符\n准备连接命令\r下面红色覆盖部分, 就是关键, 请复制到黄色位置 蓝色部分是你的 Putty 安装路径和 .ppk 文件路径, 根据实际情况填写。 D:\\PuTTY\\plink.exe -i D:\\PuTTY\\ssvip.ppk -N -ssh -P 443 -l ocid1.instanceconsoleconnection.oc1.phx.anyhq**********2la -L 5905:ocid1.instance.oc1.phx.anyhqljtj********************qhn2fimsa:5905 instance-console.us-phoenix-1.oraclecloud.com D:\\PuTTY\\plink.exe -i D:\\PuTTY\\ssvip.ppk -N -L 5900:localhost:5900 -P 5905 localhost -l ocid1.instance.oc1.phx.anyh*************fimsa 在 PowerShell 或 CMD 中执行命令\r下载并准备好 plink.exe, 可以从这里下载: plink.exe\n打开 PowerShell 或 CMD (任意一个都可以)\n在第一个窗口中, 右键粘贴第一段命令, 然后按回车。第一次执行时, 可能会提示选择 y/n, 请按 y, 然后按回车。\n直到出现 Access granted. Press Return to begin session. 的提示内容, 表示授权成功。\n窗口别关, 最小化, ssh 隧道连接建立成功\n在打开第二个窗口, 粘贴第二段命令, 然后按回车。\n直到看到 Access granted. Press Return to begin session. 的回复内容\n窗口别关, 最小化, 此时 VNC 通道连接建立成功\n使用 VNC 软件连接\r打开 VNC 软件, 输入 localhost:5900, 然后连接\n连接, 搞定, 收工！\n原文\n[经验] VNC连接甲骨文小白教程, 仅供参考, 大佬勿喷\nConverting .Pem to .Ppk on Windows\n如何在 Windows 和 Linux 上将 .pem 文件与 .ppk 互相转换？\n","date":"2020-02-28T14:30:00+08:00","permalink":"https://blog.acesheep.com/p/oracle-vps-vnc-connection-guide/","title":"VNC 连接甲骨文 vps 教程"},{"content":"在 Windows 10 的 \u0026ldquo;秋季创意者更新\u0026rdquo; (2017 年 10 月发布) 之后, 操作系统中增加了一个名为 \u0026ldquo;3D 对象\u0026rdquo; 的文件夹。该文件夹通常位于 C:\\Users\\Username\\3D Objects 路径下, 主要用于保存通过 Windows 10 新增的 3D 应用程序 (如 Paint 3D) 制作的内容。然而, 对于大部分用户来说, 这个文件夹并没有实际用途, 且会在 \u0026ldquo;这台电脑\u0026rdquo; 中显示出来, 显得多余。\n我们并不打算删除该文件夹, 因为这么做的话可能导致 3D 应用程序出现问题。但我们可以通过修改注册表来将其从文件资源管理器 (Explorer) 的侧边栏和 \u0026ldquo;这台电脑\u0026rdquo; (This PC) 中隐匿于无形\n操作步骤\r使用注册表编辑器删除 3D 对象文件夹\n打开注册表编辑器\n按 Win + R, 输入 regedit, 然后按 Enter 键 通过左侧树形图导航至以下项目\nHKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace 找到 {0DB7E03F-FC29-4DC6-9020-FF41B59E513A} 键, 这就是 3D 对象文件夹的注册表项\n右键点击该项, 选择 删除\n如果你使用的是 64 位 Windows 10, 还需要在以下路径进行相同操作\nHKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace 使用 CMD 命令删除 3D 对象文件夹\r你也可以通过命令行来删除该注册表项, 步骤如下\nreg delete \u0026#34;HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace\\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}\u0026#34; /f reg delete \u0026#34;HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace\\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}\u0026#34; /f 删除该注册表项并不会影响 3D 对象文件夹本身, 只会将其从 \u0026ldquo;这台电脑\u0026rdquo; 和文件资源管理器的侧边栏中移除。如果你需要再次显示它, 只需恢复注册表项即可\n原文\nWindows10专业版下如何删除3D对象\n","date":"2020-02-28T14:12:00+08:00","permalink":"https://blog.acesheep.com/p/how-to-delete-3d-objects-in-windows-10-pro/","title":"Windows10 专业版下如何删除 3D 对象文件夹"},{"content":"配置旁路由 LEDE\r开启 LEDE 虚拟机并进入控制台\r启动 LEDE 虚拟机, 进入虚拟机的 LEDE 控制台 在命令行输入以下命令编辑网络配置文件 vi /etc/config/network 修改网卡配置\r将网卡配置修改为如下内容。请根据自己的网络环境调整 IP 和网关设置。输入完后我们按 ESC 退出编辑, 并按 :wq 保存当前文档\noption ipaddr 设置为与 RouterOS 所在网段相同的 IP 地址 option gateway 设置为 RouterOS 的 IP 地址 config interface \u0026#39;loopback\u0026#39; option ifname \u0026#39;lo\u0026#39; option proto \u0026#39;static\u0026#39; option ipaddr \u0026#39;127.0.0.1\u0026#39; option netmask \u0026#39;255.0.0.0\u0026#39; config globals \u0026#39;globals\u0026#39; option ula_prefix \u0026#39;fdf1:53e1:6bd9::/48\u0026#39; config interface \u0026#39;lan\u0026#39; option type \u0026#39;bridge\u0026#39; option proto \u0026#39;static\u0026#39; option ipaddr \u0026#39;192.168.31.40\u0026#39; option netmask \u0026#39;255.255.255.0\u0026#39; option ip6assign \u0026#39;60\u0026#39; option ifname \u0026#39;eth0\u0026#39; option gateway \u0026#39;192.168.31.250\u0026#39; option dns \u0026#39;223.5.5.5\u0026#39; 重启网络服务\r输入以下命令重启 LEDE 网络服务\n/etc/init.d/network restart 此时, 可以通过浏览器访问 LEDE 设置的 IP 地址 192.168.31.40, 进入 LEDE 的管理界面\n配置 LAN\r进入 LEDE 管理界面后, 按照以下步骤配置 LAN 接口\n关闭 DHCP 服务器, 避免与主路由冲突\n更新软件中心及固件, 确保 LEDE 系统为最新版本\n相关文件\r在地址栏后增加 resource, 即可下载文件\nresource ├── koolclash.tar.gz ├── koolss_2.2.2.tar.gz ├── openwrt-koolshare-mod-v2.33-r12074-007caa48d1-x86-64-uefi-gpt-squashfs.img.gz └── v2ray_2.3.7.tar.gz 0 directories, 4 files 原文\nESXI打造最强家庭软路由系统ROS+LEDE+全能NAS方案(2018版) 图片不稳定\n需要端口映射的不能按照此教程设置 使用RouterOS多拨均衡负载，LEDE（OpenWRT）提供其它功能\n","date":"2020-02-17T04:54:00+08:00","permalink":"https://blog.acesheep.com/p/ultimate-10gbps-soft-router-setup-part-3-lede/","title":"究极万兆软路由搭建: LEDE 旁路由配置"},{"content":"RouterOS 系统导入到 ESXi\r解决 ESXi 6.7 U2 的 UI Bug\r由于 ESXi 6.7 U2 中导入虚拟机的地方存在 JavaScript bug, 需要将 UI 降级或者使用 ESXi 6.7 U3 版本才能正常导入虚拟机。相关的 ESXi UI 降级补丁文件是 esxui-signed-12086396.vib (本站备份), 安装方式与网卡驱动的安装相同。\n部署 MikroTik RouterOS\r文件准备\r下载文件: MikroTik RouterOS x86 6.44.1，已激活L6授权 ，可升级，永久使用.rar 解压后得到文件: MikroTik-RouterOS-6.44.2.ova 部署步骤\r选择从 OVF 或 OVA 文件部署虚拟机\n上传虚拟机文件\n选择磁盘位置\n取消勾选自动打开电源\n完成\n编辑虚拟机网卡设置, 然后启动\n配置主路由器\r将路由器通过网线直连到电脑。在电脑上安装 WinBox 用于配置路由器\n配置接口名称\r打开 WinBox, 进入 Interfaces -\u0026gt; interface 页面 为路由器的网卡设置易识别的名称 根据 MAC 地址对比 ESXi 中网卡设置, 确保名称和功能一一对应 配置需求概述\r总结一下我们要设置的内容\nRouterOS 安全设置, 增强路由器安全性 3 条宽带使用 DHCP Client 从光猫拨号的 WAN 接口获取局域网 IP 地址 1 条宽带 PPPoE 双播 LAN 口设置 DHCP Server, 为内网设备分配 IP 地址 DNS 设置, 配置路由器的 DNS 服务 DHCPv6 Client, 配置 IPv6 地址 PCC Load Balancing, 实现多线路负载均衡 Routing rules, 设置路由规则 Firewall NAT, 配置端口映射 RouterOS 安全设置\r给路由器设置密码: 进入 System -\u0026gt; Password 修改路由器登录密码, 密码越复杂越好 关闭不必要的服务: 进入 IP -\u0026gt; Services 关闭除 winbox 以外的所有服务, 减少潜在的安全风险。 创建 DHCP Client\r从光猫拨号的设备获取IP地址\n选择 IP -\u0026gt; DHCP Client 添加新的 DHCP Client 取消勾选 Use Peer DNS 取消勾选 Use Peer NTP Add Default Route 选择 no 根据需求添加三个 DHCP Client, 并为每个 Interface 选择正确的网卡 创建 PPPoE 拨号\r打开 Interfaces -\u0026gt; interface 添加一个 PPPoE Client 取消勾选 Dial On Demand 取消勾选 Use Peer DNS 取消勾选 Add Default Route 创建 LAN 口 DHCP Server\r创建 IP 分配范围 (Pool)\r建立 DHCP 服务器, 先创建 IP 分配范围 (Pool) 打开 IP -\u0026gt; Pool 添加一个新的 Pool, 定义 DHCP 分配的 IP 地址范围 配置 DHCP Server\r打开 IP -\u0026gt; DHCP Server 设置 LAN 口网卡 设置地址池 设置网关地址为主路由器地址 (例如 192.168.1.1) DNS 地址同样设置为主路由器地址 (例如 192.168.1.1) DNS 配置需根据实际网络情况设置 配置 DNS 服务\r在 RouterOS 中配置 DNS 服务, 用于解析网络中的域名。\n在 WinBox 菜单中选择 IP -\u0026gt; DNS Servers 推荐使用 DNSPod 的公共服务器 IPv4 119.29.29.29 IPv6 2402:4e00:: Allow Remote Requests 勾选此项允许路由器作为内网设备的 DNS 服务器, 处理来自局域网的域名解析请求 Cache Size 设置 DNS 缓存大小 (默认值一般足够) 这里的 Dynamic Servers 2408:8000::8 就是 WAN-500M-CU-2:1-pppoe 里勾选 Use Peer DNS 获取到的 IPv6 的 DNS 服务器\nDynamic Servers 是通过路由器的 WAN 接口 (如 PPPoE 或 DHCP Client) 自动获取的 DNS 服务器地址 如果需要使用特定的 DNS 服务器 (如 Google DNS 或其他公共 DNS), 可以在 Servers 中手动添加。自定义的 DNS 服务器优先于动态获取的 DNS 服务器 配置 IPv6 (DHCPv6)\r目前 IPv6 已在许多地区普及, 尤其是家庭宽带, 这里三个家宽已经支持 IPv6 了。通过 RouterOS, 可以为路由器设置 IPv6, 并实现 IPv4 和 IPv6 双栈 (Dual-stack) 运行, 以支持现代网络需求。\nIPv6 地址基础知识\rIPv6 地址的长度为 128 位: 共有 2128 个地址 前缀长度是 IPv6 地址的一种表示方式, 表示一个完整的 IPv6 地址块 /32: 分配给大型网络运营商, 包含 296 (128 - 32) 个地址 /48: 分配给中型企业, 包含 280 (128 - 48) 个地址 /56: 分配给小型企业, 包含 272 (128 - 56) 个地址 /64: 分配给单一子网, 包含 264 (128 - 64) 个地址 双栈技术: 允许 IPv4 和 IPv6 在同一网络中共存, 提供更广泛的兼容性 配置 DHCPv6 客户端\r打开 IPv6 -\u0026gt; DHCP Client 添加新的 DHCPv6 客户端 Interface 选择 PPPoE 拨号连接 (如 WAN-500M-CU-2:1-pppoe) Request 勾选 prefix Pool Name IPv6 地址池名称, 如 WAN-500M-CU-2:1-pppoe Pool Prefix Length 根据运营商分配填写, 我这里分配到的 IPv6 前缀是 60 (常见为 64、56 或 48) 选项 勾选 Use Peer DNS 勾选 Add Default Route 勾选 Rapid Commit 点击 OK 成功获取后, 状态显示为 Status:bound\n配置 IPv6 地址\r打开 IPv6 -\u0026gt; Addresses, 添加新的地址 Address 填写 ::/64 From Pool 选择刚刚创建的 Pool Name (如 WAN-500M-CU-2:1-pppoe) Interface 选择 LAN 端口 (例如 LAN1) 勾上 Advertise 点击 OK 验证 IPv6 配置\r检查 Windows 网卡 IPv6 连接状态\n打开浏览器访问: http://test-ipv6.com/ 测试页面会显示 IPv6 和 IPv4 的连接状态 RouterOS 的总体设置\nPCC 负载均衡按权重比例\rPCC (Per Connection Classified) 是一种基于连接分类的负载均衡技术, 可按照比例将流量分配到多条出口线路。适用于出口带宽相同或相似的线路, 确保负载均衡的效果最佳。\n假设网络环境中存在两条相同运营商的出口带宽线路\n一条为 8M 带宽 一条为 25M 带宽 通常情况下, PCC 常被用于多条相同带宽, 运营商出口的负载均衡, 而这次则利用其分类原理, 实现了按比例权重的路由策略\n需要通过 PCC 实现按比例的负载均衡路由策略。实现原理比较简单, 一条 8M, 一条是 25M, 后者大约是前者的 3 倍带宽, 所以约等于 1:3 (8/33 : 25/33), 将流量分配为 1:3 的权重路由策略。\n实现原理\r将流量划分为 4 份, 按照 1:3 的比例分别分配给两条线路 8M 带宽分配 1 份, 25M 带宽分配 3 份 PCC 使用 both-addresses:4/n 分类流量, n 表示当前流量的划分编号 Firewall Mangle 配置\r通过 Mangle 标记连接和路由。src-address-list=userip 可根据实际需求设置启用负载均衡的 IP 地址列表\n/ip firewall mangle add action=mark-connection chain=prerouting dst-address-type=!local new-connection-mark=pcc1 passthrough=yes per-connection-classifier=both-addresses:4/0 src-address-list=userip add action=mark-routing chain=prerouting connection-mark=pcc1 new-routing-mark=r1 passthrough=yes src-address-list=userip add action=mark-connection chain=prerouting dst-address-type=!local new-connection-mark=pcc2 passthrough=yes per-connection-classifier=both-addresses:4/1 src-address-list=userip add action=mark-routing chain=prerouting connection-mark=pcc2 new-routing-mark=r2 passthrough=yes src-address-list=userip add action=mark-connection chain=prerouting dst-address-type=!local new-connection-mark=pcc3 passthrough=yes per-connection-classifier=both-addresses:4/2 src-address-list=userip add action=mark-routing chain=prerouting connection-mark=pcc3 new-routing-mark=r3 passthrough=yes src-address-list=userip add action=mark-connection chain=prerouting dst-address-type=!local new-connection-mark=pcc4 passthrough=yes per-connection-classifier=both-addresses:4/3 src-address-list=userip add action=mark-routing chain=prerouting connection-mark=pcc4 new-routing-mark=r4 passthrough=yes src-address-list=userip 路由配置\r其实权重的分配关键就在路由设置上, 这里我们把网关命名为 8M 和 25M 以示区分。将标记的路由流量按照 1:3 的比例分配到两条线路\n/ip route add check-gateway=ping gateway=8M routing-mark=r1 add check-gateway=ping gateway=25M routing-mark=r2 add check-gateway=ping gateway=25M routing-mark=r3 add check-gateway=ping gateway=25M routing-mark=r4 NAT 配置\r为出口线路配置 NAT 规则\n/ip firewall nat add chain=srcnat action=masquerade out-interface=8M add chain=srcnat action=masquerade out-interface=25M 完成上述配置后, 路由器将实现按比例的负载均衡, 流量分配符合预期策略。\nPCC 负载均衡多线路 (ISP)\rPCC 介绍\rPCC (Per Connection Classifier) 是 RouterOS 的一项功能, 主要用来根据网络数据包的特定属性 (如源地址、源端口、目的地址、目的端口等) 进行分类, 从而实现流量分流和负载均衡。它通过查看 IP 包头信息, 使用特定的 Hash 算法对数据包进行分类, 并根据预设规则将数据包分配到不同的线路或连接上。\n网络拓扑\rPCC 通常用于多线路接入场景, 需至少两条 ISP 线路参与。本次示例中, 使用两条公网线路进行演示。\n如图所示, 网络拓扑包括以下组件\n两条公网线路, 分别为 1.1.1.100 (WAN1) 和 1.2.1.100 (WAN2) 路由器内网网卡地址为 172.16.0.254 (LAN) 内网服务器地址为 172.16.0.222 标记公网流量\r由于存在两条公网线路, 流量进入时必须知道是从哪条线路进入, 并确保从同一线路返回, 因此需要标记 WAN 口进入的流量。\n/ip firewall mangle add action=mark-connection chain=prerouting in-interface=WAN1 new-connection-mark=WAN1_conn add action=mark-connection chain=prerouting in-interface=WAN2 new-connection-mark=WAN2_conn 创建 PCC 规则\r这里我们选择基于源地址创建 PCC 规则, 需要注意的是, PCC 策略从 0 开始计数。\n例如, 当使用 per-connection-classifier=both-addresses:2/0 时, 2 表示划分为两组, 2/0 是第一组, 2/1 是第二组\n/ip firewall mangle add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-type=!local in-interface=LAN new-connection-mark=WAN1_conn per-connection-classifier=both-addresses:2/0 add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-type=!local in-interface=LAN new-connection-mark=WAN2_conn per-connection-classifier=both-addresses:2/1 根据标记创建动态策略路由\r标记数据包后, 我们需要根据这些标记分别创建路由规则, 解决多网关和流量负载均衡问题\n/ip firewall mangle add action=mark-routing chain=prerouting connection-mark=WAN1_conn in-interface=LAN new-routing-mark=to_WAN1 add action=mark-routing chain=prerouting connection-mark=WAN2_conn in-interface=LAN new-routing-mark=to_WAN2 add action=mark-routing chain=output connection-mark=WAN1_conn new-routing-mark=to_WAN1 add action=mark-routing chain=output connection-mark=WAN2_conn new-routing-mark=to_WAN2 创建路由\r为所有规则创建路由表\n/ip route add check-gateway=ping dst-address=0.0.0.0/0 gateway=WAN1 routing-mark=to_WAN1 add check-gateway=ping dst-address=0.0.0.0/0 gateway=WAN2 routing-mark=to_WAN2 创建故障转移路由\r防止任意线路中断\n/ip route add check-gateway=ping distance=1 gateway=WAN1,WAN2 创建 NAT 规则\r伪装方式分为两种: masquerade 和 src-nat, 根据需要选择相应配置。\nmasquerade 适合动态 IP 环境 src-nat 更适合静态 IP, 且在 NAT 转换效率上更高 masquerade 属于 src-nat 的一种, 是 src-nat 的特殊转化, 它的不同在于, 它会根据包出去的 interface, 自动将包源地址转化为对应 interface 所属网络的路由器 IP, 端口随机, 也即 masquerade 的转换是智能化设置的, 起到一个简化设置的作用。其他功能和处理方式跟 src-nat 是一样的。\n虽然动态 IP 也可以使用 src-nat 配合脚本检测外网 IP 变动后刷新规则, 但这种方法并不推荐\n/ip firewall nat add chain=srcnat action=masquerade out-interface=WAN1 add chain=srcnat action=masquerade out-interface=WAN2 此时, PCC 多线路负载均衡就建立完成了。通过 172.16.0.222 访问公网, 你会发现, 两条线路中断任意一条均不影响正常访问。同时, 开启迅雷等支持 P2P 方式下载的软件时, 会发现带宽增加了一倍\n创建端口转发规则\r因为此时为 2 条出口线路, 所以端口转发规则也需要建立两条, 因为之前根据入口标记了流量, 所以从任意线路进入的流量均会原路返回。\n这条规则将会把 2 条线路的 tcp80 端口转发到 172.16.0.222 机器的 tcp80 端口\n/ip firewall nat add chain=dstnat protocol=tcp dst-port=80 dst-address=1.1.1.100 action=dst-nat to-addresses=172.16.0.222 to-ports=80 add chain=dstnat protocol=tcp dst-port=80 dst-address=1.2.1.100 action=dst-nat to-addresses=172.16.0.222 to-ports=80 以上分流规则可以借鉴, 但在新版本则测试失败 per-connection-classifier=both-addresses 中 both-addresses 均无法正常使用\nPCC 负载均衡 PPPoE 方案\r来自于一个 TG 大佬的分享, 适用于 WAN PPPoE 负载均衡配置。\n2 WAN PPPoE балансировка нагрузки с использованием PCC.txt\n需要将 both-addresses 设置为 both-addresses-and-ports, 才能确保正常使用。PCC 建议按照 txt 里的命令设置\n/ip address add address=192.168.50.2/24 network=192.168.50.0 broadcast=192.168.50.255 interface=Local add address=192.168.1.2/24 network=192.168.1.0 broadcast=192.168.1.255 interface=WAN1 add address=192.168.2.2/24 network=192.168.2.0 broadcast=192.168.2.255 interface=WAN2 /ip firewall mangle add chain=input in-interface=WAN1 action=mark-connection new-connection-mark=WAN1_conn add chain=input in-interface=WAN2 action=mark-connection new-connection-mark=WAN2_conn add chain=output connection-mark=WAN1_conn action=mark-routing new-routing-mark=to_WAN1 add chain=output connection-mark=WAN2_conn action=mark-routing new-routing-mark=to_WAN2 add chain=prerouting dst-address=192.168.1.0/24 action=accept in-interface=Local add chain=prerouting dst-address=192.168.2.0/24 action=accept in-interface=Local add chain=prerouting dst-address-type=!local in-interface=Local per-connection-classifier=both-addresses-and-ports:3/0 action=mark-connection new-connection-mark=WAN1_conn passthrough=yes add chain=prerouting dst-address-type=!local in-interface=Local per-connection-classifier=both-addresses-and-ports:3/1 action=mark-connection new-connection-mark=WAN2_conn passthrough=yes add chain=prerouting connection-mark=WAN1_conn in-interface=Local action=mark-routing new-routing-mark=to_WAN1 add chain=prerouting connection-mark=WAN2_conn in-interface=Local action=mark-routing new-routing-mark=to_WAN2 /ip route add dst-address=0.0.0.0/0 gateway=192.168.1.1 routing-mark=to_WAN1 check-gateway=ping add dst-address=0.0.0.0/0 gateway=192.168.2.1 routing-mark=to_WAN2 check-gateway=ping add dst-address=0.0.0.0/0 gateway=192.168.1.1 distance=1 check-gateway=ping add dst-address=0.0.0.0/0 gateway=192.168.2.1 distance=2 check-gateway=ping /ip firewall nat add chain=srcnat out-interface=WAN1 action=masquerade add chain=srcnat out-interface=WAN2 action=masquerade 设置路由规则\r设置目标 IP 或者 IP 段走特定线路出口\r打开 IP -\u0026gt; Routes -\u0026gt; Rules\n添加新的路由规则\nSrc. Address 设置为 0.0.0.0/0 (表示来源地址不限) Dst. Address 输入目标地址的 IP (如 1.1.1.1) 或 IP 段 (如 1.1.1.0/24) Table 选择对应的出口线路标记 点击 OK 保存\n双线接入 联通 IP 走联通出口 电信 IP 走电信出口\r实现这一功能的最优方法是使用 BGP 路由表, 通过设置 BGP 过滤规则实现分流。\nBGP 路由表是动态更新的, 能够实时反映网络变化, 但由于获取 BGP 会话的难度较高, 这种方法并不适合大多数用户。因此, 可以采用一种低成本的替代方案, 即使用他人每日定时从 BGP 会话中提取的静态路由表, 并将其导入路由器作为分流规则。\n然而, 静态路由表也有一定的缺点。即使通过脚本实现每日定时更新以保持路由表的最新状态, 在更新路由表的过程中, 仍可能导致连接中断, 影响网络的稳定性。\n例如, jacyl4/ros-pbr-CT-CMCC 项目中提供了整理好的 IP 段规则表。如果路由表 (Table) 的名称不是默认的 CT, 需要先将其修改为 to_WAN1 或 to_WAN2, 然后再上传到路由器。\n除了手动下载和导入静态路由表外, 我们还可以通过脚本自动生成和更新所需的静态路由数据。以下是一个脚本示例\n#!/bin/sh mkdir -p ./pbr cd ./pbr # 电信 wget --no-check-certificate -c -O ct.txt https://ispip.clang.cn/chinatelecom_cidr.txt # 联通 wget --no-check-certificate -c -O cu.txt https://ispip.clang.cn/unicom_cnc_cidr.txt # 移动 wget --no-check-certificate -c -O cm.txt https://ispip.clang.cn/cmcc_cidr.txt # 铁通 wget --no-check-certificate -c -O crtc.txt https://ispip.clang.cn/crtc_cidr.txt # 教育网 wget --no-check-certificate -c -O cernet.txt https://ispip.clang.cn/cernet_cidr.txt # 长城宽带/鹏博士 wget --no-check-certificate -c -O gwbn.txt https://ispip.clang.cn/gwbn_cidr.txt # 其他 wget --no-check-certificate -c -O other.txt https://ispip.clang.cn/othernet_cidr.txt { echo \u0026#34;/ip route rule\u0026#34; for net in $(cat ct.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CT\u0026#34; done for net in $(cat cu.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CT\u0026#34; done for net in $(cat cm.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CMCC\u0026#34; done for net in $(cat crtc.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CMCC\u0026#34; done for net in $(cat cernet.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CT\u0026#34; done for net in $(cat gwbn.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CT\u0026#34; done for net in $(cat other.txt) ; do echo \u0026#34;add dst-address=$net action=lookup table=to_CT\u0026#34; done } \u0026gt; ../ros-pbr-CT-CMCC.rsc 将生成的规则表上传至 RouterOS 后, 在终端执行以下命令完成导入。规则表会导入到 IP -\u0026gt; Routes -\u0026gt; Rules\n/import ros-pbr-CT-CMCC.rsc 设置自动更新\r为了确保路由表始终保持最新, 我们可以设置脚本定期自动下载和导入路由表。以下是实现自动更新的脚本\n:local addr \u0026#34;https://ghproxy.net/https://raw.githubusercontent.com/jacyl4/chnroute/main/ros-pbr-CT-CMCC.rsc\u0026#34; :local result ([/tool fetch mode=https output=user url=$addr as-value]) :if ($result-\u0026gt;\u0026#34;status\u0026#34; = \u0026#34;finished\u0026#34;) do={ /file remove [find name=\u0026#34;ros-pbr-CT-CMCC.rsc\u0026#34;] /tool fetch url=$addr # /ip route rule remove [find table=main] /ip route rule remove [find table=to_CT] /ip route rule remove [find table=to_CMCC] # /ip route rule add src-address=10.0.0.14/32 action=lookup table=main /import ros-pbr-CT-CMCC.rsc } Firewall NAT 端口映射\r端口映射可以分为两种类型: 对等映射和不对等映射\n对等映射: 即内网的 80 端口映射到外网的 80 端口, 这种映射方式是对等的。 不对等映射: 即内网的 80 端口映射到外网的 90 端口, 或者映射到任意其他端口, 这种映射方式是不对等的。 需要注意的是, 如果你的 RouterOS 环境是多线接入, 必须为进入的数据包设置路由标记, 然后再进行端口映射。这是因为在多线接入的情况下, 流量需要从相同的线路返回, 确保数据包能够正确地通过指定的出口进行往返传输。\n如果网络中有旁路由, 则需要将局域网的网关设置为主路由 (RouterOS) 的网关, 只有这样, NAT 规则才会生效。\n测试时, 避免在路由器的局域网内进行测试, 因为可能会遇到 NAT Loopback 问题。建议通过手机使用 4G 网络进行测试, 以避免这种问题。\nNAT Loopback / Hairpin NAT\r还没整明白.jpg\n扩展阅读\r端口映射成功, 但显示的外网 IP 都是路由器的地址\r在 RouterOS 上进行端口映射成功后, 外网可以正常访问内网的服务器, 但在内网机器上使用 netstat -n 查看时, 显示的连接地址都是路由器的网关地址 (如 192.168.1.1), 而不是外网访问的真实 IP\n例如, 外网 IP: 219.138.144.129 的用户访问内网 FTP 服务器 192.168.1.6, 但是在 FTP 服务器上使用 netstat -n 查看时, 显示的连接地址是 192.168.1.1, 而不是 219.138.144.129\n在 RouterOS 的 NAT 配置栏目中我是这样设置的\nGeneral 选项 Chain: dstnat Src.address: 219.138.144.129 Dst.address: 我的外网 IP 地址 Protocol: 6 (tcp) Dst.port: 21 Action 选项 Action: dst-nat To addresses: 192.168.1.6 To Ports: 21 请问我的设置是否有问题？如何才能使外网 IP 直接显示在内网机器上？\n由于机器和网络资源有限, 且出于安全考虑, 我只允许指定的几个 IP 访问我的 FTP 服务器, 其他未指定的 IP 无法访问我的外网 IP。\n问题原因\r这个问题的根本原因是没有正确处理出站流量的源地址转换。在映射过程中, 外网流量访问内网时, NAT 会将源 IP 地址转换为路由器的 IP 地址。要避免这种情况, 必须为源流量做额外的伪装处理。\n解决方案\r在 RouterOS 中, 应该在 NAT 中添加一个 Masquerade 规则。具体配置如下\nGeneral 选项 Chain: srcnat Src.address: 192.168.1.0/24 (你的内网 IP 段) 其他项留空 Action 选项 Action: masquerade 注意 General 选项中的 Src.address: 必须指定你内网的 IP 段, 如 192.168.1.0/24。如果没有指定或者写为 0.0.0.0/0, 则会导致外网访问时显示的都是路由器的网关 IP 地址, 而不是外网的真实 IP。\n通过这种设置, NAT 将对内网的出站流量进行伪装处理, 避免出现连接时显示路由器网关地址的问题。\n配置完上述 NAT 规则后, 外网用户访问内网的服务时, 在 netstat -n 上会显示外网的真实 IP 地址, 而不是路由器的内网地址。 只允许指定 IP 访问 FTP 服务器的要求, 可以通过添加防火墙规则来实现, 限制只有特定 IP 才能访问对应端口。 千兆多网卡桥接 = 路由器 + 多口千兆交换机\r对于使用 RouterOS 软路由的朋友来说, 如果家里局域网需要多口千兆的交换机, 购买一个多口千兆交换机可能增加不少成本。实际上, 如果 RouterOS 软路由所在的计算机主板有足够的 PCI 插槽, 或者集成了双口千兆网卡, 可以按照以下方法实现多口千兆交换机的功能。\n假设你的网络环境是通过 ADSL 拨号上网, WAN 口使用 100M 网卡, 并且有五块千兆网卡 (ether1 到 ether5) 组成 LAN 网络, 而 WAN 口为 ether6, 设置步骤如下\n创建一个桥接接口\n首先, 创建一个名为 mybridge 的桥接接口\n/interface bridge add name=\u0026#34;mybridge\u0026#34; disable=no 将五个千兆网卡加入桥接\n将 ether1 到 ether5 五块网卡添加到桥接接口中\n/interface bridge port add interface=ether1 bridge=mybridge /interface bridge port add interface=ether2 bridge=mybridge /interface bridge port add interface=ether3 bridge=mybridge /interface bridge port add interface=ether4 bridge=mybridge /interface bridge port add interface=ether5 bridge=mybridge 至此, 五块网卡已经组成了一个桥接\n为桥接接口设置 IP 地址\n接着, 为 mybridge 桥接接口设置一个 IP 地址, 如 192.168.1.1/24\n/ip address add address=192.168.1.1/24 interface=mybridge 连接到 RouterOS\n完成上述设置后, 你可以使用 Winbox 连接到 RouterOS 进行进一步的配置, 所有其他设置都可以在 Winbox 中操作\n使用桥接接口作为交换机\n此时, ether1 到 ether5 的五个网口就相当于一个千兆交换机, 性能要优于普通的千兆交换机。通过这种方式, 可以大幅降低硬件成本, 同时提升网络性能\n原文\nManual:Cloud Hosted Router - CHR 官方文档\n基于RouterOS和RHEL的无障碍网络访问解决方案\n【ROS+LEDE合用】双线聚合，真旁路，超绝加速Burst Link【上篇】\n【ROS+OpenWrt合用】双线聚合，真旁路，超绝加速Burst Link【下篇】\nESXI打造最强家庭软路由系统ROS+LEDE+全能NAS方案(2018版) 图片不稳定\n本教程只是简单的ROS 基本配置 包括PPPOE DHCP DNS 伪装 和 Firewall Bridge Addresses\nRouterOS配置原生IPv6（电信IPv4/IPv6双栈）\nROS软路由功能强大的ROS系统,PCC 实现比例权重路由\n官方文档: Manual:PCC\n干货！RouterOS 多线路 PCC 负载均衡及端口映射\npppoe端口映射(port mapping)\n為你的RouterOS 設定NAT loopback (Hairpin NAT)\n官方文档 Hairpin NAT\nROS端口映射成功，但显示的外网IP都是路由器的地址\nROS 千兆多网卡（lan）桥接 ＝路由器+多口千兆交换机\nMikrotik RouterOS 通过 VRRP 实现单线多拨\n","date":"2020-02-17T03:54:00+08:00","permalink":"https://blog.acesheep.com/p/ultimate-10gbps-soft-router-setup-part-2-routeros/","title":"究极万兆软路由搭建: RouterOS 主路由搭建"},{"content":"ESXi 是一款免费的虚拟化管理系统, 对于免费用户, 其唯一的限制是单个虚拟机最多支持 8 个 CPU 核心。这一限制对我们这些家庭用户而言完全足够。以下是获取 ESXi 下载地址和免费许可证的方法\nESXi 安装步骤\r获取下载地址和许可证\r打开 VMware 官网。如果没有 VMware 账号, 需要先注册用户。注册过程较为简单, 这里不再说明。\n注册后登录, 可以获得许可证密钥以及下载地址。默认情况下, 我们下载这个 ISO 镜像文件即可。\nVMware vSphere Hypervisor (ESXi ISO) image (Includes VMware Tools) 2019-08-20 | 6.7.0U3 | 314.66 MB | iso 制作启动盘\r下载完成后, 准备一个 U 盘作为启动盘安装 ESXi 系统, 并使用软碟通将镜像烧写至 U 盘\n打开软碟通并载入镜像 选择 启动 -\u0026gt; 写入硬盘镜像, 选择 U 盘后开始写入 写入完成后, 使用该 U 盘启动计算机以安装 ESXi 系统 ESXi 系统安装过程\r插入启动 U 盘并重启电脑, 从 U 盘启动\n选择安装目标硬盘\n设置 ROOT 用户密码, 这个密码一定要记住。\n出现这个提示框安装就完成了, 拔掉 U 盘后重启系统进入 ESXi 系统\n网络配置\r启动后按 F2 进入网络配置界面\n输入 ROOT 密码后进入到设置界面, 选择 Configure Management Network\n根据自家的网络情况, 手动设置绑定的网卡、IP 地址、子网掩码以及网关\n设置完成后, 我们可以在同一局域网内的另外一台电脑中访问刚设置的 IP 地址\nWeb 面板访问\r使用浏览器访问 ESXi 的管理页面, 输入用户名和密码即可打开管理面板\nESXi 安装 Realtek RTL8111 驱动\r默认情况下, ESXi 只包含 Intel X710-4T 网卡驱动, 不包含 Realtek RTL8111 驱动。如果使用 Realtek 网卡, 需要手动安装驱动。\n下载驱动\rNet55-r8168 是一款社区支持的 ESXi 网卡驱动。该驱动由 V-Front.de 提供, 这是一个专注于为 VMware ESXi 提供额外驱动程序支持的第三方资源库。\nNet55-r8168 驱动解决了 Realtek RTL8111 系列网卡无法被 ESXi 系统识别的问题, 使这些网卡能够正常工作。特别适合在家用或小型实验室环境下使用经济实惠的 Realtek 网卡的用户。\n该驱动属于社区支持 (Community Supported), 并非 VMware 官方认证。使用时需根据自己的需求和网络环境谨慎安装。如果用于生产环境, 建议选用官方支持的硬件设备, 以获得更高的稳定性和技术支持。\n访问 Net55-r8168 该页面包含驱动的介绍及驱动下载链接 找到页面底部 VIB File of version 8.045a\n下载完成后, 你将得到一个名为 net55-r8168-8.045a-napi.x86_64.vib 的文件 备用驱动包\r如果你需要离线安装或担心下载链接失效, 可以下载本站的离线驱动包 Offline Bundle of version 8.045a 作为备份\n确认支持的网卡型号\r该驱动支持以下 Realtek 网卡型号\nRTL8111B / RTL8168B / RTL8111 / RTL8168 RTL8111C / RTL8111CP / RTL8111D(L) / RTL8168C RTL8111DP / RTL8111E / RTL8168E RTL8111F / RTL8411 / RTL8111G / RTL8111GUS RTL8411B(N) / RTL8118AS / D-Link DGE-528T 启用 SSH 和控制台\r在 ESXi Web 管理界面中, 依次点击 主机 -\u0026gt; 操作 -\u0026gt; 服务 -\u0026gt; 启用安全 Shell (SSH) 和 启动控制台 Shell\n上传驱动文件\r使用 Web 管理界面上传驱动文件: 进入 存储 -\u0026gt; 数据存储浏览器, 新建文件夹 (如 vib), 并将驱动文件上传到此文件夹。例如, /vmfs/volumes/5d00d8cd-63a0054c-95f6-00e06f68011f/vib 或使用 WinSCP 上传文件到 /tmp 目录 安装驱动\r使用以下命令安装驱动\n# 设置软件接受级别 esxcli software acceptance set --level=CommunitySupported # 安装驱动 esxcli software vib install -v /tmp/net55-r8168-8.045a-napi.x86_64.vib Installation Result Message: The update completed successfully, but the system needs to be rebooted for the changes to be effective. Reboot Required: true VIBs Installed: Realtek_bootbank_net55-r8168_8.045a-napi VIBs Removed: VIBs Skipped: 在线安装驱动 (可选)\r如果其他网卡可以正常连接网络, 也可以直接在线安装。这样就不用上传文件安装了\nesxcli software acceptance set --level=CommunitySupported esxcli network firewall ruleset set -e true -r httpClient esxcli network firewall ruleset set -e true -r dns esxcli software vib install -d https://vibsdepot.v-front.de -n net55-r8168 ESXi 网络接口分配\r打开 Web 管理页面, 进入 网络 -\u0026gt; 虚拟交换机\n添加标准虚拟交换机, 为每个网络接口添加一个对应的虚拟交换机 (保证一个接口对应一个交换机)\n添加端口组, 为每个虚拟交换机添加一个端口组\n配置完成后, 可为虚拟机添加网卡并分配到相应的端口组\nRouterOS 单线多拨和 ESXi 虚拟交换机的安全设置\r在 RouterOS 中使用 Bridge 和 VRRP 实现单线多拨时, Bridge 需要修改 MAC 地址, 并且在与 ESXi 结合使用时, 桥接接口所在虚拟交换机的 Promiscuous Mode (混杂模式) 和 Forged Transmits (伪传输) 必须都设置为 接受 状态\n单线多拨\r要实现单线多拨, 首先需要了解运营商的 BRAS (Broadband Remote Access Server, 宽带远程接入服务器) 认证设备。如果接入的是同一台运营商的 BRAS (PPPoE 认证设备), 该设备下每个拨号设备的网卡 MAC 地址是唯一的, 不能重复。因此, 作为拨号的路由器, 其 MAC 地址必须不同, 才能避免 PPPoE 拨号失败。为了解决 MAC 地址冲突问题, 通常需要使用不同的网卡。\n主流的单网卡多次拨号方式有两种\nBridge 修改 MAC 地址方式: 这种方式可以通过修改桥接接口的 MAC 地址来实现多次拨号 VRRP 修改 MAC 地址方式: 这种方式更推荐使用, VRRP (Virtual Router Redundancy Protocol) 允许通过虚拟路由器接口在同一物理接口上模拟多个 MAC 地址, 从而实现单线多拨。 对于两到三条线路来自不同运营商的情况, 可以不考虑使用 Bridge 或 VRRP 修改 MAC 地址, 直接通过网卡进行拨号即可。\nVMware 官方文档对混杂模式和伪传输的描述\rPromiscuous Mode (混杂模式)\r混杂模式控制虚拟机是否可以查看 ESXi 主机上其他节点的单播数据包。混杂模式通常应处于关闭状态, 除非你在虚拟机中运行网络入侵检测软件 (IDS) 或需要进行数据包捕获。在这种情况下, 可以选择启用混杂模式。\n默认值: Reject (拒绝) 作用: 在默认状态下, 虚拟网络适配器只能处理发送给自身的数据包, 而不能查看其他虚拟机的数据包 开启时的效果: 虚拟网络适配器无需执行任何接收过滤, 因此客户操作系统可以接收线路上所有可见的数据包。 尽管混杂模式有助于监控网络流量和网络调试, 但它会带来较高的安全风险, 因为它允许任何虚拟机访问和处理网络中所有数据包, 属于其他虚拟机的数据包也可被截获。\nForged Transmits (伪传输)\r伪传输控制的是虚拟机发送数据包时的源 MAC 地址验证。默认情况下, 伪传输设置为拒绝, 只有有效的源 MAC 地址才能发送数据包。\n默认值: Reject (拒绝) 作用: 在默认状态下, ESXi 主机会检查虚拟机发送数据包的源 MAC 地址与网络适配器的有效 MAC 地址是否匹配。如果不匹配, 数据包将被丢弃。 开启时的效果: ESXi 主机将不验证源 MAC 地址, 允许虚拟机使用模拟的 MAC 地址发送数据包, 且不会被丢弃。 虚拟机操作系统不会检测到其网络适配器接收到使用模拟的 MAC 地址的数据包。ESXi 主机会在数据包传入虚拟机之前捕获并丢弃这些伪造的 MAC 地址的数据包, 因此, 虚拟机操作系统可能认为这些数据包已被丢弃。\n原文\nInstalling Realtek Driver on ESXi 6.7\nESXI虚拟机安装Realtek瑞昱RTL8111G/8168网卡驱动\nROS的工作模式和ESXI网卡工作模式的关系\nMikrotik RouterOS 通过 VRRP 实现单线多拨\n","date":"2020-02-17T02:54:00+08:00","permalink":"https://blog.acesheep.com/p/ultimate-10gbps-soft-router-setup-part-1-esxi-6.7-u3/","title":"究极万兆软路由搭建: ESXi 6.7 U3 安装与配置"},{"content":"玩了大半年的软路由和 NAS, 给大伙分享一下我用家庭网络完整解决方案。\n刚入门时, 我使用了 AC88U 梅林固件作为家庭网络的基础架构, 但在双播叠加宽带速度方面常常失效。因此, 我开始探索新的方案, 最终选择了 RouterOS (ROS) + 旁路由 (LEDE) 的组合。\n对于虚拟化系统, 有 ESXi 6.7 和 Proxmox (PVE) 两种方案\nESXi 是 VMware 推出的一款运行在裸机上的深度定制的 Linux 系统, 优点是对 Intel 的驱动支持较好, 但对 AMD 的支持较弱, 不建议 AMD 用户使用 PVE 是开源的虚拟化平台, 对各种硬件支持较为友好 路由系统选择\r主路由系统\r起初, 我对比了 RouterOS 和 pfSense 两款主流软路由系统。虽然 OpenWRT 是一个优秀的开源路由系统, 但其功能和适用性未能完全满足我的需求, 因此不在对比的选项里。最终选择了 RouterOS, 因为许多软路由教程推荐使用它, 而我也随之入坑。RouterOS 设置即时生效, 配合 Winbox 工具使用, 操作体验非常方便。同时, 其功能丰富且强大, 特别适合复杂的家庭网络环境。\n我的网络环境比较复杂\n一条 PPoE 链接可实现双播, 获得双倍上传速率 两条路由器拨号, 都有公网 IP 一条路由器拨号, 没公网 IP 旁路由系统\r旁路由选择就比较多, 我最终选了 LEDE (固件下载: LEDE Koolshare)\nESXi 主机硬件配置\r名称 配置 CPU Intel Xeon E5-2618L v4 全新 主板 超微/Supermicro X10SRM-TF 内存 SK 海力士/Hynix DDR4 2400 8G RECC 1RX8 三条 磁盘 西部数据/WD Green SATA SSD M.2 2280 - 240GB 电源 台达/Delta NX350 80plus Bronze (铜牌) 机箱 小钢炮 双面玻璃 USB3.0 风扇 2011 四针-调速 (双风扇) 网卡 Intel Ethernet Converged Network Adapter X710-T4 网卡 Realtek RTL8111E Gigabit Ethernet Controller (Single Port) 比较好看的成品\n网络架构与实际效果\r实际使用效果, 网络下行速度达到了 2.3 Gbps, 表现十分出色！\nRouterOS 主路由主要功能\rPPoE Client DHCP Client DHCP Server DHCPv6 Client (IPv6 支持) Firewall Firewall NAT PCC Load Balancing (负载均衡) Routing rules LEDE 旁路由主要功能\rDNS 服务器 V2Ray 代理 微软 KMS 激活 koolproxy 广告过滤 frpc 内网穿透 阿里云 DDNS DIY NAS 主要功能\r数据存储 文件共享 PT 下载 KVM + 直通显卡的游戏主机 本篇文章一共分为三个章节\rPart 1: ESXi 安装与配置 Part 2: RouterOS 主路由搭建 Part 3: LEDE 旁路由配置 相关文件\r在地址栏后增加 resource, 即可下载文件\nresource ├── IPMI_Users_Guide.pdf ├── X10SRM-TF-MNL-1845.pdf └── www.supermicro.org.cn_en_products_motherboard_X10SRM-TF.png # 产品截图 0 directories, 3 files 原文\n路由器拓扑图设计网站\n分享万兆网络拓扑 (201906)\n基于ESXi的软路由(LEDE)与黑群晖的安装与配置 ★★★★★\n【ROS+LEDE合用】双线聚合，真旁路，超绝加速Burst Link【上篇】★★☆☆☆\n【ROS+OpenWrt合用】双线聚合，真旁路，超绝加速Burst Link【下篇】 ★★☆☆☆\nESXI打造最强家庭软路由系统ROS+LEDE+全能NAS方案(2018版) 图片不稳定 ★★☆☆☆\n基于RouterOS和RHEL的无障碍网络访问解决方案 ★★☆☆☆\nGen8折腾记\u0026ndash;ESXi虚拟化与软路由篇 ☆☆☆☆☆\nX10SRM-TF | Motherboards | Products | Super Micro Computer, Inc.\n","date":"2020-02-17T01:54:00+08:00","permalink":"https://blog.acesheep.com/p/ultimate-10gbps-soft-router-setup-part-0/","title":"究极万兆软路由搭建: ESXi 6.7 U3 + RouterOS 主路由 + LEDE 旁路由"},{"content":"对 Ubuntu 14.04 LTS 进行美化和优化, 这个系统专门为编译 15-18 年的 OpenWRT 而搭建。\n美化元素搭配\r主题: Flatabulous Theme 图标: Ultra Flat Icons 光标: MacBuntu OS Pointer v7 字体: 微软雅黑 (fonts-wqy-microhei) 背景: Firefox_wallpaper.png dock 栏: docky 设置主题工具: unity-tweak-tool 系统负载指示器: indicator-multiload 经典菜单指示器: classicmenu-indicator 使用主题和工具\rFlatabulous 主题安装\rFlatabulous 是一款流行的扁平化主题, 能够为系统带来现代感\nsudo add-apt-repository ppa:noobslab/themes sudo apt-get update sudo apt-get install flatabulous-theme Ultra Flat Icons 图标安装\r这是一套极简风格的图标, 完美搭配 Flatabulous 主题\nsudo add-apt-repository ppa:noobslab/icons sudo apt-get update sudo apt-get install ultra-flat-icons MacBuntu OS 光标 (可选)\rMacBuntu OS 提供了 macOS 风格的光标样式\nsudo add-apt-repository ppa:noobslab/macbuntu sudo apt-get update sudo apt-get install macbuntu-os-icons-lts-v7 sudo apt-get install macbuntu-os-ithemes-lts-v7 微软雅黑字体安装\r微软雅黑 (fonts-wqy-microhei) 适合中文系统使用\nsudo apt-get install fonts-wqy-microhei Unity Tweak Tool\r这是用于配置和管理系统主题的工具\nsudo apt-get install unity-tweak-tool 系统优化工具\rDocky - 应用程序启动器\rDocky 提供类似 macOS 的 Dock 栏\nsudo apt-get install docky # 启动程序 docky # 启动条移到底部 gsettings set com.canonical.Unity.Launcher launcher-position Bottom 系统负载指示器\rIndicator-Multiload 可以显示 CPU、内存和网络的实时负载\nsudo apt-get install -y indicator-multiload # 启动程序 indicator-multiload 经典菜单指示器\rClassicmenu-Indicator 提供经典菜单样式的系统菜单\nsudo apt-add-repository ppa:diesch/testing sudo apt-get update sudo apt-get install classicmenu-indicator 原文\n不美翻怎么开发!Ubuntu 16.04 LTS深度美化!(2017年度定稿版)\n","date":"2020-02-16T06:42:00+08:00","image":"https://blog.acesheep.com/p/how-to-beautify-ubuntu-14.04-lts-deep-customization-guide/2212260870_hu8815482302018019274.png","permalink":"https://blog.acesheep.com/p/how-to-beautify-ubuntu-14.04-lts-deep-customization-guide/","title":"不美翻怎么开发! Ubuntu 14.04 LTS 深度美化!"},{"content":"IP 转发概述\r默认情况下, 最新的 Linux 发行版通常会禁用 IP 转发功能。这种默认设置是合理的, 因为大多数用户并不需要启用 IP 转发功能。但是, 如果我们在设置一台 Linux 路由器/网关、VPN 服务器或简单的拨号服务器时, 就必须启用 IP 转发功能。\nIP 转发使得 Linux 操作系统能够像路由器一样转发数据包, 或者更通用地说, 将数据包在不同的网络之间进行路由。在本教程中, 我们将学习如何在 Linux 系统上启用 IP 转发。这个过程相对简单, 同时我们也会了解如何将 IP 转发设置为临时启用或永久启用。\n临时启用\r临时启用IP转发不需要修改配置文件, 但这种设置会在系统重启后失效。\n查看当前状态\r要查看当前 IP 转发的状态, 执行以下命令\n# IPv4 cat /proc/sys/net/ipv4/ip_forward # IPv6 cat /proc/sys/net/ipv6/conf/all/forwarding 如果返回 0, 表示 IP 转发被禁用；如果返回 1, 表示 IP 转发已启用\n临时启用 IP 转发\r临时修改, 在重启或者使用 sysctl 时会恢复默认\n# 启用 IPv4 转发 sysctl -w net.ipv4.ip_forward = 1 # 启用 IPv6 转发 sysctl -w net.ipv6.conf.all.forwarding = 1 永久启用\r要永久启用 IP 转发, 需要修改系统配置文件 /etc/sysctl.conf\n打开文件 /etc/sysctl.conf\nvim /etc/sysctl.conf 在文件末尾添加以下内容\nnet.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 使配置立即生效\nsysctl -p /etc/sysctl.conf 原文\nHow to enable IP forwarding on Linux (IPv4 / IPv6)?\n","date":"2020-02-16T04:17:24+08:00","permalink":"https://blog.acesheep.com/p/linux-enable-ip-forwarding-ipv4-or-ipv6/","title":"Linux 启用 IP 转发 (IPv4 / IPv6)"},{"content":"接上文 CentOS 7 使用 iptables 端口转发 之前配置端口转发是关闭 firewalld 程序的, 在后续更新服务器时使用上了 firewalld 这导致使用 iptables 配置的端口转发一直是失效状态\n找了很多原因才想起试试配置 firewalld 转发, 意料之中 转发设置成功了~\n控制端口 / 服务\r可以通过两种方式控制端口的开放\n指定端口号 指定服务名 虽然开放 HTTP 服务实际上就是开放了 80 端口, 但不能仅通过端口号来关闭服务。也就是说, 如果是通过服务名 (如 HTTP) 开放的端口, 则需要通过指定服务名来关闭；如果是通过端口号 (如 80) 开放的, 则需要通过端口号来关闭。\n另外, 指定端口时一定要明确协议类型 (如 TCP 或 UDP)。掌握了这一点后, 你就不需要每次关闭防火墙再重新配置, 可以让防火墙真正的生效。\nfirewall-cmd --add-service=mysql # 开放 MySQL 服务端口 firewall-cmd --remove-service=http # 删除 HTTP 服务端口 firewall-cmd --list-services # 查看开放的服务 firewall-cmd --add-port=3306/tcp # 开放通过 TCP 协议访问 3306 firewall-cmd --add-port=233/udp # 开放通过 UDP 协议访问 233 firewall-cmd --remove-port=80/tcp # 删除通过 TCP 协议访问 3306 firewall-cmd --list-ports # 查看开放的端口 端口转发\r在 CentOS 7 中, 如果你使用了 firewalld 来管理防火墙, 端口转发的配置需要通过 firewall-cmd 命令来实现\n可以实现的功能\n隐藏端口\n如果你想将某个端口隐藏, 可以先通过防火墙阻止该端口, 然后配置另一个不常见的端口, 将流量转发至原端口\n流量分发\n通过端口转发, 可以将不同端口的流量转发至不同的机器或服务。这适用于在一个防火墙后管理多个不同的服务和主机 (堡垒机)\n端口转发允许将指定端口的流量转发到其他 IP 或端口。转发的目的地址和端口可以根据需要指定。\n将 80 端口的流量转发到 8080 端口\r指定了目的端口却没指定目的 IP, 则默认为本机\nfirewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 --permanent 将 80 端口的流量转发到指定 IP 地址\r指定了目的 IP 却没指定端口, 则使用原端口\nfirewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1 --permanent 将 80 端口的流量转发到指定 IP 地址和端口\r例如转发至 192.168.0.1 的 8080 端口\nfirewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1:toport=8080 --permanent 检查端口转发是否生效\r如果配置好端口转发之后不能用, 可以检查下面两个问题\n比如我将 80 端口转发至 192.168.0.1:8080, 首先检查本地的 80 端口和目标的 8080 端口是否开放监听了\n其次检查是否允许伪装 IP, 没允许的话要开启伪装 IP\n实例\r将 443 端口的流量转发到 192.168.1.100:8443\nfirewall-cmd --add-masquerade --permanent firewall-cmd --add-forward-port=port=443:proto=tcp:toaddr=192.168.1.100:toport=8443 --permanent firewall-cmd --add-port=443/tcp --permanent 伪装 IP (NAT 功能)\r伪装 IP (或 NAT) 功能可以使得网络流量从一个IP地址通过防火墙转发到内部网络中的不同地址。启用此功能后, 可以进行端口转发\n检查防火墙是否允许伪装 IP\rfirewall-cmd --query-masquerade 启用防火墙伪装 IP\rfirewall-cmd --add-masquerade --permanent 禁用防火墙伪装 IP\rfirewall-cmd --remove-masquerade --permanent 原文\nCentOS 7下用firewall-cmd控制端口与端口转发详解\nCentOS 7 使用 iptables 端口转发\nCentOS 7 firewalld 配置教程\n","date":"2020-02-08T06:54:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-port-control-and-port-forwarding-with-firewall-cmd/","title":"CentOS 7 使用 firewall-cmd 控制端口与端口转发"},{"content":"在 Windows 上使用 PostgreSQL 时, 手动移动数据库文件夹后遇到文件夹权限问题导致服务无法启动 (错误码 1063) 时, 可以按照以下步骤检查和修复权限问题\npg_ctl: 无法启动服务 \u0026#34;postgresql-x64-10\u0026#34;: 错误码 1063 pg_ctl: could not start service \u0026#34;postgresql-x64-10\u0026#34;: error code 1063 检查旧 PG_DATA 目录的权限\n使用 cacls 命令检查旧的数据目录权限\ncacls \u0026#34;c:\\path\\to\\old\\pgdata\\dir\u0026#34; 检查新 PG_DATA 目录的权限\n同样, 检查新的数据目录权限\ncacls \u0026#34;d:\\path\\to\\NEW\\pgdata\\dir\u0026#34; 比较权限差异\n比较上述两条命令输出的权限, 找到用户和权限之间的差异\n同步权限\n根据差异, 设置新的权限, 确保 PostgreSQL 服务的用户有足够的权限来访问数据目录。使用 cacls 命令修改权限\ncacls \u0026#34;C:\\Program Files\\PostgreSQL\\9.1\\data\u0026#34; /E /T /C /G postgres:F 这样可以确保 PostgreSQL 服务有权限访问所需的文件夹\n原文\nUnable to run PostgreSQL as Windows service\nWindows cacls 命令详解\n","date":"2020-01-16T06:32:00+08:00","permalink":"https://blog.acesheep.com/p/postgresql-windows-service-error-1063/","title":"PostgreSQL Windows 服务无法启动 错误代码 1063"},{"content":"cacls 是 Windows 系统中的一个命令行工具, 用于查看和修改文件或目录的访问控制列表 (ACL)。ACL 定义了用户和组对文件或目录的访问权限。以下是 cacls 的详细介绍、参数说明和用法。\n设置权限的方法, 一般有两种:\n在图形用户界面 (GUI) 的 \u0026ldquo;安全\u0026rdquo; 选项卡中对文件或目录访问控制权限进行设置 使用 cacls 命令, 它是一个基于命令行的命令 基本语法\r:: cacls 文件名 [/t] [/e] [/c] [/g 用户:权限] [/r 用户] [/p 用户:权限] [/d 用户] cacls filename [/T] [/E] [/C] [/G user:perm] [/R user [...]] [/P user:perm [...]] [/D user [...]] 常用选项\rfilename 显示 ACL (访问控制列表) /T 修改当前目录及所有子目录中指定文件的 ACL /L 作用于符号链接本身, 而非其目标 /M 修改挂载到目录上的卷的 ACL /S 显示 DACL 的 SDDL 字符串 /S:SDDL 用指定的 SDDL 字符串替换 ACL (与 /E, /G, /R, /P 或 /D 参数不能同时使用) /E 编辑 ACL, 而不是替换它 /C 在访问被拒绝错误时继续操作 /G user:perm 为指定用户授予访问权限 perm 可以是: R 读取 W 写入 C 修改 (写入) F 完全控制 /R user 撤销指定用户的访问权限 (仅在使用 /E 时有效) /P user:perm 替换指定用户的访问权限 perm 可以是: N 无 R 读取 W 写入 C 修改 (写入) F 完全控制 /D user 拒绝指定用户的访问 可以使用通配符指定命令中多个文件 你可以在一个命令中指定多个用户 缩写说明: CI - 容器继承 ACE (访问控制项) 将由目录继承 OI - 对象继承 ACE 将由文件继承 IO - 仅继承 ACE 不适用于当前文件/目录 ID - 已继承 ACE 从父目录的 ACL 继承 使用示例\r查看文件的 ACL\rC:\\\u0026gt;cacls example.txt C:\\example.txt NT AUTHORITY\\SYSTEM:(ID)F BUILTIN\\Administrators:(ID)F BUILTIN\\Users:(ID)R 查看文件夹的 ACL\nC:\\\u0026gt;cacls C:\\Documents C:\\Documents NT AUTHORITY\\SYSTEM:(OI)(CI)(ID)F BUILTIN\\Administrators:(OI)(CI)(ID)F BUILTIN\\Users:(OI)(CI)(ID)R BUILTIN\\Users:(CI)(ID)(特殊访问:) FILE_APPEND_DATA BUILTIN\\Users:(CI)(ID)(特殊访问:) FILE_WRITE_DATA CREATOR OWNER:(OI)(CI)(IO)(ID)F 为用户授予完全控制权限\rC:\\\u0026gt;cacls example.txt /g everyone:F 是否确定(Y/N)?y 处理的文件: C:\\example.txt C:\\\u0026gt;cacls example.txt C:\\example.txt Everyone:F 使用 net localgroup 命令查看本地用户组, 赋予文件夹 Guests 所有权限\nC:\\\u0026gt;net localgroup \\\\tj3b_EDUYDN8C16 的别名 ------------------------------------------------------------------------------- *Access Control Assistance Operators *Administrators *Backup Operators *Certificate Service DCOM Access *Cryptographic Operators *Device Owners *Distributed COM Users *Event Log Readers *Guests *Hyper-V Administrators *IIS_IUSRS *Network Configuration Operators *Performance Log Users *Performance Monitor Users *Power Users *Print Operators *RDS Endpoint Servers *RDS Management Servers *RDS Remote Access Servers *Remote Desktop Users *Remote Management Users *Replicator *Storage Replica Administrators *System Managed Accounts Group *Users 命令成功完成。 C:\\\u0026gt;cacls C:\\Documents C:\\Documents NT AUTHORITY\\SYSTEM:(OI)(CI)(ID)F BUILTIN\\Administrators:(OI)(CI)(ID)F BUILTIN\\Users:(OI)(CI)(ID)R BUILTIN\\Users:(CI)(ID)(特殊访问:) FILE_APPEND_DATA BUILTIN\\Users:(CI)(ID)(特殊访问:) FILE_WRITE_DATA CREATOR OWNER:(OI)(CI)(IO)(ID)F C:\\\u0026gt;cacls C:\\Documents /p Guests:F 是否确定(Y/N)?y 处理的目录: C:\\Documents C:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)F 去除文件夹 Guests 所有权限\nC:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)F C:\\\u0026gt;cacls C:\\Documents /p Guests:N 是否确定(Y/N)?y 处理的目录: C:\\Documents C:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N 设置用户访问权限\r赋予用户 everyone 对文件夹及其所有子目录的读取权限\nC:\\\u0026gt;cacls C:\\Documents /t /g everyone:R 是否确定(Y/N)?y 处理的目录: C:\\Documents C:\\\u0026gt;cacls C:\\Documents C:\\Documents Everyone:(OI)(CI)R 赋予用户 everyone 对文件夹及其所有子目录的完全控制权限\nC:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N C:\\\u0026gt;cacls C:\\Documents /t /e /c /g everyone:F 处理的目录: C:\\Documents C:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N Everyone:(OI)(CI)F 为文件 example.txt 添加 (/e) 一个新权限, 授予用户组 everyone 写入 (W) 权限\nC:\\\u0026gt;cacls example.txt C:\\example.txt NT AUTHORITY\\SYSTEM:(ID)F BUILTIN\\Administrators:(ID)F BUILTIN\\Users:(ID)R C:\\\u0026gt;cacls example.txt /e /g everyone:W 处理的文件: C:\\example.txt C:\\\u0026gt;cacls example.txt C:\\example.txt Everyone:(特殊访问:) READ_CONTROL SYNCHRONIZE FILE_GENERIC_WRITE FILE_WRITE_DATA FILE_APPEND_DATA FILE_WRITE_EA FILE_EXECUTE FILE_WRITE_ATTRIBUTES NT AUTHORITY\\SYSTEM:(ID)F BUILTIN\\Administrators:(ID)F BUILTIN\\Users:(ID)R 替换用户访问权限\r将用户 everyone 的权限替换为只读权限\nC:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N Everyone:(OI)(CI)F C:\\\u0026gt;cacls C:\\Documents /t /e /c /p everyone:R 处理的目录: C:\\Documents C:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N Everyone:(OI)(CI)R 撤销用户访问权限\r撤销用户 everyone 的所有访问权限\nC:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N Everyone:(OI)(CI)R C:\\\u0026gt;cacls C:\\Documents /t /e /c /r everyone 处理的目录: C:\\Documents 文件名、目录名或卷标语法不正确。 C:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N 撤销用户 everyone 的所有访问权限\nC:\\\u0026gt;cacls example.txt C:\\example.txt Everyone:(特殊访问:) READ_CONTROL SYNCHRONIZE FILE_GENERIC_WRITE FILE_WRITE_DATA FILE_APPEND_DATA FILE_WRITE_EA FILE_EXECUTE FILE_WRITE_ATTRIBUTES NT AUTHORITY\\SYSTEM:(ID)F BUILTIN\\Administrators:(ID)F BUILTIN\\Users:(ID)R C:\\\u0026gt;cacls example.txt /e /r everyone 处理的文件: C:\\example.txt C:\\\u0026gt;cacls example.txt C:\\example.txt NT AUTHORITY\\SYSTEM:(ID)F BUILTIN\\Administrators:(ID)F BUILTIN\\Users:(ID)R 拒绝用户访问\r拒绝用户 everyone 对文件夹及其所有子目录的访问权限\nC:\\\u0026gt;cacls C:\\Documents C:\\Documents BUILTIN\\Guests:(OI)(CI)N C:\\\u0026gt;cacls C:\\Documents /t /e /c /d everyone 处理的目录: C:\\Documents 文件名、目录名或卷标语法不正确。 C:\\\u0026gt;cacls C:\\Documents C:\\Documents Everyone:(OI)(CI)N BUILTIN\\Guests:(OI)(CI)N 拒绝用户 everyone 对文件 example.txt 的访问权限\nC:\\\u0026gt;cacls example.txt /d everyone 是否确定(Y/N)?y 处理的文件: C:\\example.txt C:\\\u0026gt;cacls example.txt C:\\example.txt Everyone:N ","date":"2020-01-16T06:29:00+08:00","permalink":"https://blog.acesheep.com/p/windows-cacls-command-guide/","title":"Windows cacls 命令详解"},{"content":"Android-x86 虚拟机安装配置网上有很多, 但是全部说明白的确不多。本文针对 VMWare 虚拟机介绍安装配置方法。\n下载 Android-x86 ISO 文件\r在 Android-x86 下载安装包, 本文章使用的是 android-x86_64-8.1-r2.iso\npie-x86 基于 Android 9.0 版本 (Pie QPR2) oreo-x86 基于 Android 8.1 版本 (Oreo MR1) nougat-x86 基于 Android 7.1 版本 (Nougat MR2) marshmallow-x86 基于 Android 6.0 版本 (Marshmallow) lollipop-x86 基于 Android 5.1 版本 (Lollipop) kitkat-x86 基于 Android 4.4 版本 (KitKat) jb-x86 基于 Android 4.3 版本 (Jelly Bean) ics-x86 基于 Android 4.0 版本 (Ice Cream Sandwich) honeycomb-x86 基于 Android 3.2 版本 (Honeycomb) gingerbread-x86 基于 Android 2.3 版本 (Gingerbread) froyo-x86 基于 Android 2.2 版本 (Froyo) eclair-x86 基于 Android 2.1 版本 (Eclair) donut-x86 基于 Android 1.6 版本 (Donut) cupcake-x86 (aka android-x86-b0.9) 基于 Android 1.5 版本 (Cupcake) 解决黑屏问题\r在 VMware 虚拟机上安装 Android-x86 后, 会遇到启动后无法进入图形界面黑屏问题\n在启动引导时选择 Debug mode\n当出现所有的启动信息后, 按下回车, 进入命令行模式\n输入以下命令来重新挂载文件系统为可写模式\nmount -o remount,rw /mnt 如果执行成功, 会看到相关提示信息\n输入以下命令来编辑启动菜单\nvi /mnt/grub/menu.lst 进入 vi 编辑模式后, 找到如下行\n在 quiet 后添加 nomodeset_, 使其看起来像这样\n保存并退出编辑器\n重启虚拟机。此时应该能够正常进入 Android-x86 的图形界面\n设置分辨率\r如果要调整显示分辨率, 可以在启动时添加分辨率设置\n在启动参数最后添加分辨率设置 UVESA_MODE=1280x1024\nAndroid-x86 内置快捷键\rAndroid-x86 提供了几种常用的快捷键, 可以更快捷的使用虚拟机\nAlt + F1: 进入控制台 (console) 模式 Alt + F7: 返回图形用户界面模式 Alt + F9: 切换至图形界面 Alt + F10: 画面旋转 180 度 Alt + F11: 画面向左旋转 90 度 Alt + F12: 画面向右旋转 90 度 Ctrl + P: 打开 Android 设置界面 Windows 键: Android 的 Home 按钮 Esc: Android 的 Back 按钮 F2: Android 的 Menu 按钮 F3: Android 的 Search 按钮 右边的菜单键(win 和 ctrl 中间的键): Android 菜单键 原文\nVMware虚拟机安装android-x86_64-8.1-rc1.iso 无法进入图形界面黑屏问题\nAndroid-x86虚拟机安装配置全攻略\n","date":"2019-09-13T21:58:00+08:00","permalink":"https://blog.acesheep.com/p/vmware-install-android-8.1-x86-black-screen-issue/","title":"VMware 虚拟机安装 Android 8.1 X86 解决黑屏问题"},{"content":"为了保持服务持续运行并且在崩溃后自动恢复, 我们可以通过 systemd 管理服务, 并结合监控脚本来确保服务不间断运行。\n后台运行\r使用 systemctl\r我们通过 systemctl 来启动并管理服务, 确保服务能够开机启动。\n编辑服务器配置文件 /lib/systemd/system/frps.service\n[Unit] Description=frp Server After=network.target [Service] Type=simple User=root # 启动服务的命令 (此处写你的 frps 的实际安装目录) ExecStart=/your/path/frps -c /your/path/frps.ini [Install] WantedBy=multi-user.target 客户端的配置与服务器端类似。可以通过 systemctl start frps 和 systemctl start frpc 启动服务\n使用 screen\r#!/bin/bash screen_name=$\u0026#34;frpc\u0026#34; cmd=$\u0026#34;/home/frp/frpc -c /home/frp/frpc.ini\u0026#34; screen -dmS $screen_name screen -x -S $screen_name -p 0 -X stuff \u0026#34;$cmd\u0026#34; screen -x -S $screen_name -p 0 -X stuff $\u0026#39;\\n\u0026#39; 监控服务\r服务监控脚本\r为了避免服务崩溃后需要手动重启, 我们可以编写监控脚本来实时检测服务状态, 如果服务停止则自动重启。\n服务器端监控 frps\n#!/bin/sh ps -fe | grep frps | grep -v grep if [ $? -ne 0 ] then echo \u0026#34;start process.....\u0026#34; systemctl start frps else echo \u0026#34;runing.....\u0026#34; fi 客户端端监控 frpc (基于 CentOS 7 测试)\n#!/bin/bash ps -fe | grep frp/frpc | grep -v grep if [ $? -ne 0 ]; then echo \u0026#34;start process.....\u0026#34; systemctl start frpc else echo \u0026#34;runing.....\u0026#34; fi 代码执行逻辑\rps -fe | grep frps | grep -v grep ps -fe 会列出所有正在运行的进程及其详细信息\n| grep frps\n| 是管道符, 用于将前一个命令的输出传递给下一个命令 grep frps 会从 ps -fe 的输出中筛选出包含字符串 frps 的行。即, 查找所有包含 frps 进程名的进程 这一步的作用是过滤出所有包含 frps 进程名的行。如果 frps 进程在运行, 它会显示该进程的相关信息\n| grep -v grep\ngrep -v 是 grep 的一个选项, 表示反向匹配, 即排除匹配到的行 grep -v grep 会从前面的输出中排除掉包含 grep 字符串的行。因为在执行 grep 命令时, grep 本身也会被列出为一个进程, 所以这一步是用来过滤掉 grep 命令本身的输出, 确保结果中只显示 frps 进程 这条命令的目的是检查是否有名为 frps 的进程在运行。如果 frps 进程正在运行, ps -fe | grep frps 会返回进程信息, 然后通过 grep -v grep 排除掉包含 grep 本身的行, 最终只显示 frps 进程。如果没有找到 frps 进程, 返回的结果会为空, 并返回一个非 0 值。\n$? 表示上一个命令的返回值 -ne 0 表示返回值不等于 0, 表示命令执行失败, 也就是说 frps 进程没有运行。 -eq 0 表示返回值等于 0, 表示命令执行成功, 也就是说 frps 进程正在运行。 定时监控\r为了定期检测服务是否正常运行, 可以使用 cron 设置定时任务, 每一分钟执行一次监控脚本。\n设置定时任务, 使用命令 crontab -e\n*/1 * * * * sh /your/path/check_frp_status.sh 这样每分钟执行一次 check_frp_status.sh 脚本, 确保服务持续运行\n客户端也要做相应处理。到此, 再也不用担心因内网穿透服务崩溃或中断带来的问题了！\n原文\nFRP局域网穿透＋linux自动监控服务运行\n","date":"2019-09-05T13:37:00+08:00","permalink":"https://blog.acesheep.com/p/linux-auto-monitor-frp-service-status/","title":"Linux 自动监控 frp 服务运行状态"},{"content":"问题分析\r拿到手的 10G 网卡让我感到非常激动, 但在上机测试后, 我发现内网两台电脑传输文件时, 只能传输约 48MB, 之后就出现了报错并停止传输。然而, 换回之前的网卡后, 这个问题就不再出现。经过多次测试后, 我怀疑问题可能出在网卡驱动上, 并且在亚马逊的用户评价中, 发现有类似的情况。\n通过进一步查找, 了解到在亚马逊上看到了几条评价也遇到了丢包问题, 紧接着网卡就停止工作了, 这与我遇到的情况非常相似。\n亚马逊用户评论\nRed Hat Bugzilla – Bug 1499321\n驱动更新\rCentOS 7 系统默认的驱动版本是 v2.0.4.0, 网卡芯片组为 Aquantia AQC107\n确认网卡信息\r用 lspci 可以看到网卡的芯片组是 AQC107 这个也是我们要去下载的驱动的信息\nlspci -s 09:00.0 -vv 09:00.0 Ethernet controller: Aquantia Corp. AQC107 NBase-T/IEEE 802.3bz Ethernet Controller [AQtion] (rev 02) Subsystem: ASUSTeK Computer Inc. Device 8741 使用 ethtool 可以查看当前网卡使用的驱动版本\nethtool -i enp2s0 driver: atlantic version: 2.0.4.0-kern firmware-version: 3.0.33 expansion-rom-version: bus-info: 0000:09:00.0 supports-statistics: yes supports-test: no supports-eeprom-access: no supports-register-dump: yes supports-priv-flags: no 在上一步的信息里面找到了 驱动名称 atlantic 接下来就可以查看驱动详细信息\nmodinfo atlantic filename: /lib/modules/4.20.11-1.el7.elrepo.x86_64/kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko description: aQuantia Corporation(R) Network Driver author: aQuantia version: 2.0.4.0-kern license: GPL v2 srcversion: 65B2095FA0FFCABF9686A7B alias: pci:v00001D6Ad000052B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000051B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000092B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000091B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000089B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000088B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000087B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000080B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000012B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000011B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000009B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000008B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000007B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000000B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D109sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D108sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D107sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D100sv*sd*bc*sc*i* alias: pci:v00001D6Ad00000001sv*sd*bc*sc*i* depends: retpoline: Y intree: Y name: atlantic vermagic: 4.20.11-1.el7.elrepo.x86_64 SMP mod_unload modversions parm: aq_itr:Interrupt throttling mode (uint) parm: aq_itr_tx:TX interrupt throttle rate (uint) parm: aq_itr_rx:RX interrupt throttle rate (uint) 这一步可以看到我的内核是自己升级过的 4.20.11 还有就是网卡的驱动版本是 2.0.4.0-kern\n下载驱动\r华硕自家的支持 (XG-C100C Support) 里面也有驱动工具, 但是里面的版本非常低是 v2.0.15.0 截止本文发布的时候 AQC107 驱动版本是 v2.2.6.0.178\n华硕的 XG-C100C 使用的芯片组是 Aquantia AQC107 所以可以直接安装 Aquantia 的驱动 (Aquantia Driver Downloads)\n安装基础工具\r安装步骤在 README.txt 写的很详细. 这里只讲一种方法\n如果是自己升级内核就需要同时安装内核的 kernel-devel 我这个则需要修改安装脚本在 kernel-devel 中间加上 -ml 才可以正常安装\n这个可以查看当前安装的内核\nrpm -qa | grep kernel-ml 安装前需要安装必要依赖工具\nyum install kernel-devel-`uname -r` gcc gcc-c++ make dkms 解压并安装驱动\r安装好基础工具之后解压驱动程序\ntar zxf Aquantia-AQtion-x.y.z.tar.gz cd ~/aquantia 执行安装脚本\n./dkms.sh install 驱动安装位置在\n/lib/modules/`uname -r`/extra/atlantic.ko 在使用 modinfo 查看版本就是新的了\nmodinfo atlantic filename: /lib/modules/4.20.11-1.el7.elrepo.x86_64/extra/atlantic.ko description: aQuantia Corporation(R) Network Driver author: aQuantia version: 2.2.6.0 license: GPL v2 firmware: aquantia/91B1.fw firmware: aquantia/87B1.fw firmware: aquantia/80B1.fw srcversion: 3BD2BA33B9C3E4A2B0556D9 alias: pci:v00001D6Ad000092B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000091B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000089B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000088B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000087B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000080B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000012B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000011B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000009B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000008B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000007B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad000000B1sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D109sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D108sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D107sv*sd*bc*sc*i* alias: pci:v00001D6Ad0000D100sv*sd*bc*sc*i* alias: pci:v00001D6Ad00000001sv*sd*bc*sc*i* depends: crc-itu-t,ptp retpoline: Y name: atlantic vermagic: 4.20.11-1.el7.elrepo.x86_64 SMP mod_unload modversions parm: aq_ptp_offset_forced:Force to use the driver parameters (uint) parm: aq_ptp_offset_100:PTP offset for 100M (uint) parm: aq_ptp_offset_1000:PTP offset for 1G (uint) parm: aq_ptp_offset_2500:PTP offset for 2,5G (uint) parm: aq_ptp_offset_5000:PTP offset for 5G (uint) parm: aq_ptp_offset_10000:PTP offset for 10G (uint) parm: aq_itr:Interrupt throttling mode (uint) parm: aq_itr_tx:TX interrupt throttle rate (uint) parm: aq_itr_rx:RX interrupt throttle rate (uint) parm: aq_rxpageorder:RX page order override (uint) parm: aq_rx_refill_thres:RX refill threshold (uint) parm: aq_fw_did:Use FW image for this DID (array of uint) parm: aq_fw_sid:Use provisioning data for this SID (array of uint) parm: aq_force_host_boot:Force host boot (array of uint) 这里结束后还需要使用 ethtool 查看一下当前使用的版本. 发现正在使用的版本没有变化\nethtool -i enp2s0 driver: atlantic version: 2.0.4.0-kern firmware-version: 3.0.33 expansion-rom-version: bus-info: 0000:09:00.0 supports-statistics: yes supports-test: no supports-eeprom-access: no supports-register-dump: yes 加载新驱动模块\r首先移除旧模块\nrmmod atlantic 加载新模块\n# 推荐使用绝对路径 insmod /lib/modules/4.20.11-1.el7.elrepo.x86_64/extra/atlantic.ko # 或者 insmod /lib/modules/`uname -r`/extra/atlantic.ko 分析模块依赖\ndepmod -a 重启网络服务\nservice network restart 验证驱动更新\r最后使用 ethtool 查看当前使用的版本. 现在版本已经变成 2.2.6.0 新的了, 成功!\nethtool -i enp2s0 driver: atlantic version: 2.2.6.0 firmware-version: 3.0.33 expansion-rom-version: bus-info: 0000:09:00.0 supports-statistics: yes supports-test: no supports-eeprom-access: no supports-register-dump: yes supports-priv-flags: yes 命令解释\rmodprobe atlantic\r这个命令用于加载指定的内核模块 (这里是 atlantic 模块)。modprobe 会自动处理模块的依赖关系, 如果该模块依赖其他模块, modprobe 会自动加载它们。它是一个高级命令, 适合大多数情况。\nmodprobe atlantic 可以替代 insmod atlantic\ninsmod\rinsmod 命令用于手动加载指定的内核模块。与 modprobe 不同, insmod 只会加载指定的模块, 而不会自动处理依赖关系。所以如果该模块有其他依赖模块, 你需要手动加载这些依赖模块, 否则加载会失败。\ndepmod -a\r这个命令用于更新内核模块的依赖数据库。它扫描系统中的模块并生成或更新 /lib/modules/$(uname -r)/modules.dep 文件, 该文件记录了模块之间的依赖关系。通常在安装新模块后执行, 确保系统知道所有模块的依赖关系。\nrmmod atlantic\rrmmod 用于卸载指定的内核模块。它会将已加载的模块从内核中移除。如果有其他模块依赖这个模块, 卸载操作会失败, 除非依赖的模块也被卸载。\n原文\nlinux更新网卡驱动\n检查Linux服务器网卡驱动版本并更新\n","date":"2019-08-25T11:57:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-xg-c100c-file-transfer-packet-loss-and-driver-update/","title":"CentOS 7 XG-C100C 传输文件丢包问题"},{"content":"M.2 (SATA Express) 是未来的 SSD 标准, 但在购买前需要注意 SSD 的长度和性能等级。M.2 SSD 的特殊插槽 (底座) 设计可防止不匹配的错误安装, 但某些主板仅支持特定尺寸的 SSD。\n请注意: 本文假设你已确认你的主板/笔记本电脑支持 PCI-Express M.2 SSD, 而非 SATA 类型的 M.2 SSD\nM.2 SSD 插槽 (Keying)\r目前, M.2 SSD 有三种插槽类型: B、M 或 B+M, 而插槽仅支持其中一种卡槽。由于 B 和 M 的卡槽位置略有不同, M.2 SSD 只能单向安装\n带 B key 的 M.2 SSD (针脚 12-19) 可为 PCI Express SSD 提供最高 2x 通道带宽 带 M key 的 M.2 SSD (针脚 59-66) 可提供最高 4x 通道带宽 带 B+M key 的 M.2 SSD 在两种插槽中都具有最大的兼容性, 但只能以 2x 通道带宽运行 即使是 2x 通道带宽的 B key M.2 SSD, 仍能达到 10Gbit/s 的性能, 而 4x 通道带宽的 M key 可实现最高 20Gbit/s 的性能\nM.2 SSD 长度\r由于 M.2 标准要求 SSD (或其他类型, 如 WiFi、蓝牙等) 仅在向上的一侧放置芯片, 这意味着更大容量的 SSD 通常更长, 因为需要容纳更多存储芯片 (NAND)\n通常 M.2 SSD 有五种长度, 但并非所有主板或笔记本都支持所有长度\n2230 2242 2260 2280 22110 这些数字代表宽度和长度, 例如 2242 表示宽度为 22mm, 长度为 42mm。目前最常见的规格是 2242 和 2280 (长度分别为 42mm 和 80mm)。例如, Maximus VI 系列的 mPCIe Combo II 卡最多支持 2242 规格的 M.2 SSD\nM.2 SSD 购买前检查\r在购买 M.2 SSD 前, 请确认以下内容:\n主板/笔记本电脑支持的是 M.2 SATA 还是 M.2 PCI-Express (提示: 查看产品规格页面!) 主板/笔记本电脑插槽支持的钥槽类型 (B/M/B+M) 如果是 PCI Express, 插槽支持的是 2x 还是 4x PCI-Express 带宽 支持的 SSD 最大长度 (2232 到 22110) (提示: 可以查看主板的 PCB 上是否标注) 原文\nBuying An M.2 SSD? How To Tell Which Is Which\n","date":"2019-08-25T10:51:15+08:00","permalink":"https://blog.acesheep.com/p/buying-an-m-2-ssd-how-to-tell-which-is-which/","title":"购买 M.2 固态硬盘该如何辨别?"},{"content":"CPU 的推出过程大概分这几个步骤\nES1: 测试架构和工艺制程 ES2: 修正大量 BUG 这个时候的 CPU 已经能用了, 但还存在隐患 ES3 (QS, 质量认证样品): 型号确定, 在电脑上能显示型号和规格, 可能存在或不存在轻微隐患 正式版: 大量出货 ES 版\rES 版, 全称工程样板 (Engineering Sample) 是未正式上市前的测试版 CPU, 由厂商提供给下游合作厂商 (OEM) 进行研发测试, 在一个产品的研发过程中, 这种测试是不可避免的。越早期的版本稳定性越差。\n每款正式版 CPU 推出前, 和很多软件一样, 早期存在许多 bug (问题), 需要修改, 因此 ES 版 CPU 就是担当经受严格的测试考验, 验证产品的性能、发现并修正问题, 特别是进行超频、热功耗等极限测试。当测试到后期, 产品才逐步成熟。\nES 版 CPU 在修改过程中, 就会出现各种版本, 用 CPU-Z 或系统中的电脑属性检测, 可分为 不显 (ES) 和 正显 (QS) 以及各种不同的步进修订号。\n不显 (ES): 就是系统上、CPU-Z 上不能识别 CPU 名称或虽能显示名称却不显示正确规格型号, 在 CPU-Z 上看 CPU 规格上面显示 0000\n正显 (QS): 就是系统上、CPU-Z 上能正确显示 CPU 的名称和版本型号\n步进和修订\r步进 (Stepping):\n每次版本更新都会修正问题并提升性能 步进号越大, 版本越新, 性能和稳定性越好。比如, 步进 0、1 就是最初版本, 越往后步进 3、5 这样 修订号 (Revision):\n用字母标识不同阶段修订的版本 示例: B2 -\u0026gt; C0 -\u0026gt; E0 -\u0026gt; G0 -\u0026gt; L2 -\u0026gt; M0 -\u0026gt; R0 (越右越新) 步进 0、1 不显 无修订的 ES 版, 最好别碰。\n正显的, 最新步进的, 除了没质保, 基本上和正式版一样了。这就是后来大家称之为 QS 版的 CPU, 一般来说 QS \u0026gt; ES\n这里要特别说明的是: 现在有部分人提出 QS 不显 的叫法, 实际上, 这是错误的。QS 版本身就是带显的, 因此 QS 不显 这一说法本身就是自相矛盾。这种错误的叫法, 往往被奸商用来蒙骗消费者。\nQS 版\rQS 版, 全称质量认证样品 (Qualification Sample), 也叫 ES 正显版或带显版, 是 ES 的一种, 并且被认为是最好的 ES 版本。它通常是正式版推出前的最终样品版本, 与正式版几乎完全相同, 步进也一致, 稳定性与正式版相当。\nQS 版最初是提供给 OEM 厂商用于配套设计开发测试的样品, 与正式版的区别在于硬件中标注了 ES 字样。此外, QS 版的货源不同于免费供应的早期 ES 版本, INTEL 会向工厂收取少量费用, 价格仍低于正式版。\nQS 的特点是通过 CPU-Z 可以看到具体型号和 ES 标示, 优点是性能和稳定性与正式版无异, 价格更便宜；缺点是没有官方保修或仅享商家保修, 且价格略高于普通 ES 版。QS 版因其高性价比, 尤其适合追求稳定和经济的玩家购买。\n正式版\r正式版是经 CPU 厂商认证, 正式发售的 CPU 版本。其特点是通过 CPU-Z 等软件能看到完整型号且无 ES 字样。正式版 CPU 产品稳定, 价格较高, 没有风险, 市面上的盒装零售版或品牌机拆机的散装 CPU 基本都是正式版。\n辨认区分\r不显 (ES)\r就是系统上、CPU-Z 上不能识别 CPU 名称或虽能显示名称却不显示正确规格型号, 在 CPU-Z 上看 CPU 规格上面显示 0000\n这是大家常说的 2720 ES 版, 它是 ES 版的最关键因素, 是红框 2 中显示为 CPU 0 @ 主频\n正显 (QS)\r经测试后的不断修正, 基本成熟了, 才会把确定的型号显示出来, 后面再加上主频和 (ES) 的字样、CPU-Z 上能正确显示 CPU 的名称和版本型号\n正式版 (Retail)\r原文\n科普: 关于ES版的CPU (正显、不显、QS等)\nES版、QS版与正式版是什么意思\n[教學]正式版、QS版、ES版CPU? 傻傻分不清楚?\n","date":"2019-08-25T10:20:00+08:00","permalink":"https://blog.acesheep.com/p/cpu-types-es-qs-and-retail-versions/","title":"科普: CPU 的 ES 版、QS 版与正式版是什么意思"},{"content":"在 PHP 中实现 AES 加密, 常见的方法包括使用 mcrypt 或 OpenSSL\n使用 mcrypt 扩展\r适用于较老的 PHP 版本 (如 PHP 5.x 和部分 7.x)。mcrypt 扩展从 PHP 7.2 开始被废弃, 且需要额外安装。\n安装 mcrypt 扩展\rCentOS 7 / PHP 7.2\nyum install php72-mcrypt Debian / Ubuntu / PHP 7.0\nsudo apt-get install php7-mcrypt AES-128-CBC 加密类\r// AES-128-CBC 加密类 class AES { private static $key = \u0026#39;YourKeyxxxxxxxxx\u0026#39;; // 密钥 private static $iv = \u0026#39;YourIvxxxxxxxxxx\u0026#39;; // 初始化向量 // 加密方法 public static function encrypt($data) { $encrypted = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, // 使用 AES-128 self::$key, // 密钥 self::pkcs7_pad($data), // 填充数据 MCRYPT_MODE_CBC, // CBC 加密模式 self::$iv // IV 初始化向量 ); return base64_encode($encrypted); } // 解密方法 public static function decrypt($data) { $decrypted = mcrypt_decrypt( MCRYPT_RIJNDAEL_128, // 使用 AES-128 self::$key, // 密钥 base64_decode($data), // 解码后的数据 MCRYPT_MODE_CBC, // CBC 解密模式 self::$iv // IV 初始化向量 ); return self::pkcs7_unpad($decrypted); // 去除填充 } // PKCS7 填充方法 private static function pkcs7_pad($text) { $blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); // 填充至整块 } // 去除 PKCS7 填充 private static function pkcs7_unpad($text) { $len = strlen($text); $pad = ord($text[$len - 1]); // 获取填充字节值 return substr($text, 0, $len - $pad); // 去除填充 } } 使用实例\r$data = \u0026#34;test\u0026#34;; // 加密 $encrypted = AES::encrypt($data); echo $encrypted . \u0026#34;\\n\u0026#34;; // $privateKey = \u0026#34;7854156156611111\u0026#34;; // $iv = \u0026#34;0000000000000000\u0026#34;; // 解密 $encryptedData = \u0026#34;L7AswKt5/t1gND4ct22Odw==\u0026#34;; $decrypted = AES::decrypt($encryptedData); echo $decrypted . \u0026#34;\\n\u0026#34;; 使用 OpenSSL 实现 AES 加密\r对于现代 PHP 版本, mcrypt 已经被废弃, 建议使用 openssl_encrypt 和 openssl_decrypt。以下是实现 AES 加密和解密的代码, 采用 PKCS7 填充\nclass AES { /** * @param string $string 需要加密的字符串 * @param string $key 密钥 * @return string */ public static function encrypt($string, $key) { // 使用 SHA1PRNG 算法生成加密用的 16 字节密钥 (Java 兼容) $key = substr(openssl_digest(openssl_digest($key, \u0026#39;sha1\u0026#39;, true), \u0026#39;sha1\u0026#39;, true), 0, 16); // 生成随机的 16 字节 IV $iv = openssl_random_pseudo_bytes(16); // 使用 AES-128-CBC 加密 $data = openssl_encrypt($string, \u0026#39;AES-128-CBC\u0026#39;, $key, OPENSSL_RAW_DATA, $iv); // 将 IV 和加密数据合并, 并转为 HEX 格式字符串 $data = strtoupper(bin2hex($iv . $data)); return $data; } /** * @param string $string 需要解密的字符串 * @param string $key 密钥 * @return string */ public static function decrypt($string, $key) { // 使用 SHA1PRNG 算法生成解密用的 16 字节密钥 (Java 兼容) $key = substr(openssl_digest(openssl_digest($key, \u0026#39;sha1\u0026#39;, true), \u0026#39;sha1\u0026#39;, true), 0, 16); // 将 HEX 格式字符串转换为二进制数据 $data = hex2bin($string); // 从数据中提取 IV (前 16 字节) 和密文 $iv = substr($data, 0, 16); $cipherText = substr($data, 16); // 使用 AES-128-CBC 解密 $decrypted = openssl_decrypt($cipherText, \u0026#39;AES-128-CBC\u0026#39;, $key, OPENSSL_RAW_DATA, $iv); return $decrypted; } } // 测试 $encrypt = AES::encrypt(\u0026#39;test\u0026#39;, \u0026#39;blog.acesheep.com\u0026#39;); $decrypt = AES::decrypt($encrypt, \u0026#39;blog.acesheep.com\u0026#39;); echo \u0026#34;加密后: \u0026#34; . $encrypt . \u0026#34;\\n\u0026#34;; echo \u0026#34;解密: \u0026#34; . $decrypt . \u0026#34;\\n\u0026#34;; 初始化向量 (IV)\rCBC 模式要求一个初始化向量 (IV), 长度必须与块大小一致 (AES 的块大小为 16 字节) 加密时, 使用 openssl_random_pseudo_bytes(16) 生成随机 IV IV 必须与密文一起存储, 因为解密时需要它 原文\nAES/CBC/128/PKCS5Padding加密解密算法 (iOS、Android、JavaScript、PHP)\nPHP AES Encryption/Decryption Class with PKCS5 padding\nPHP AES加解密(AES-128-ECB|sha1|bin2hex)\nmd5 Hash Generator\n在线AES加密解密、AES在线加密解密、AES encryption and decryption\n","date":"2019-07-10T17:06:00+08:00","permalink":"https://blog.acesheep.com/p/php-aes-cbc-128-pkcs7padding-implementation/","title":"PHP AES/CBC/128/PKCS7Padding 实现"},{"content":"Golang 没有像 PHP 那样提供一个现成的 AES 加密函数, 不过标准库里有 crypto, 利用里面的 AES 等可以自己封装个加密函数, 不过需要理解下整个加解密的过程和原理\n这里使用的是 AES 加密中的 CBC 模式, 块加密需要划分成整数长度相等个消息块不断加密 (串行), 分组长度是固定 128 位, 但密钥的长度可以使用 128 位, 192 位或者 256 位 (这里指的是 bit), 即密钥 16, 24, 32 长度对应 AES-128, AES-192, AES-256\npackage encrypt import ( \u0026#34;bytes\u0026#34; \u0026#34;crypto/aes\u0026#34; \u0026#34;crypto/cipher\u0026#34; \u0026#34;crypto/rand\u0026#34; \u0026#34;encoding/base64\u0026#34; \u0026#34;io\u0026#34; ) // CBC 加密 按照 golang 标准库的例子代码 // 不过里面没有填充的部分, 所以补上 // 使用 PKCS7 进行填充, iOS 也是 7 // 只要少于 256 就能放到一个 byte 中, 默认的 blockSize=16 (即采用 16*8=128, AES-128 长的密钥) // 最少填充 1 个 byte, 如果明文刚好是 blocksize 的整数倍, 则再填充一个 blocksize func PKCS7Padding(ciphertext []byte, blockSize int) []byte { // 计算需要 padding 的数目, 并生成填充的文本 padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS7UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } // AES 加密, 填充秘钥 key 的 16 位, 24, 32 分别对应 AES-128, AES-192, or AES-256 func AesCBCEncrypt(rawData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { panic(err) } // 填充原文 blockSize := block.BlockSize() rawData = PKCS7Padding(rawData, blockSize) // 初始向量 IV 必须是唯一, 但不需要保密 cipherText := make([]byte, blockSize+len(rawData)) // block 大小 16 iv := cipherText[:blockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } // block 大小和初始向量大小一定要一致 mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(cipherText[blockSize:], rawData) return cipherText, nil } func AesCBCDncrypt(encryptData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { panic(err) } blockSize := block.BlockSize() if len(encryptData) \u0026lt; blockSize { panic(\u0026#34;ciphertext too short\u0026#34;) } iv := encryptData[:blockSize] encryptData = encryptData[blockSize:] // CBC mode always works in whole blocks. if len(encryptData)%blockSize != 0 { panic(\u0026#34;ciphertext is not a multiple of the block size\u0026#34;) } mode := cipher.NewCBCDecrypter(block, iv) // CryptBlocks can work in-place if the two arguments are the same. mode.CryptBlocks(encryptData, encryptData) // 解填充 encryptData = PKCS7UnPadding(encryptData) return encryptData, nil } func Encrypt(rawData, key []byte) (string, error) { data, err := AesCBCEncrypt(rawData, key) if err != nil { return \u0026#34;\u0026#34;, err } return base64.StdEncoding.EncodeToString(data), nil } func Dncrypt(rawData string, key []byte) (string, error) { data, err := base64.StdEncoding.DecodeString(rawData) if err != nil { return \u0026#34;\u0026#34;, err } dnData, err := AesCBCDncrypt(data, key) if err != nil { return \u0026#34;\u0026#34;, err } return string(dnData), nil } 其他填充模式 PKCS5Padding\npackage encrypt import ( \u0026#34;bytes\u0026#34; ) func PKCS5Padding(ciphertext []byte) []byte { // PKCS5Padding 中 blockSize 固定为 8 blockSize := 8 // 计算需要 padding 的数目, 并生成填充的文本 padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } 其他填充模式 ZeroPadding\npackage encrypt import ( \u0026#34;bytes\u0026#34; ) func ZeroPadding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize // 用 0 去填充 padtext := bytes.Repeat([]byte{0}, padding) return append(ciphertext, padtext...) } func ZeroUnPadding(origData []byte) []byte { return bytes.TrimFunc(origData, func(r rune) bool { return r == rune(0) }) } 其他实例 cipher.go\n这个例子中的错误的 PKCS5Padding 函数名, 实际在做 PKCS7Padding 的工作。blockSize 作为参数传入函数, 并非固定为 8\npackage config import ( \u0026#34;bytes\u0026#34; \u0026#34;crypto/aes\u0026#34; \u0026#34;crypto/cipher\u0026#34; \u0026#34;encoding/hex\u0026#34; \u0026#34;fmt\u0026#34; \u0026#34;strings\u0026#34; ) var ivspec = []byte(\u0026#34;0000000000000000\u0026#34;) const Key = \u0026#34;iKwb6Kt5pnqcVZcd\u0026#34; func PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS5Trimming(encrypt []byte) []byte { padding := encrypt[len(encrypt)-1] return encrypt[:len(encrypt)-int(padding)] } func AESEncodeStr(src, key string) string { block, err := aes.NewCipher([]byte(key)) if err != nil { fmt.Println(\u0026#34;key error1\u0026#34;, err) } if src == \u0026#34;\u0026#34; { fmt.Println(\u0026#34;plain content empty\u0026#34;) } ecb := cipher.NewCBCEncrypter(block, ivspec) content := []byte(src) content = PKCS5Padding(content, block.BlockSize()) crypted := make([]byte, len(content)) ecb.CryptBlocks(crypted, content) return hex.EncodeToString(crypted) } func AESDecodeStr(crypt, key string) string { crypted, err := hex.DecodeString(strings.ToLower(crypt)) if err != nil || len(crypted) == 0 { fmt.Println(\u0026#34;plain content empty\u0026#34;) } block, err := aes.NewCipher([]byte(key)) if err != nil { fmt.Println(\u0026#34;key error1\u0026#34;, err) } ecb := cipher.NewCBCDecrypter(block, ivspec) decrypted := make([]byte, len(crypted)) ecb.CryptBlocks(decrypted, crypted) return string(PKCS5Trimming(decrypted)) } 原文\ngolang 中AES加密详解\nGolang-AES加密 (CBC模式, PKCS7填充) ","date":"2019-07-10T16:27:43+08:00","permalink":"https://blog.acesheep.com/p/golang-aes-cbc-pkcs7padding-implementation/","title":"Golang AES/CBC/PKCS7Padding 实现"},{"content":"所谓块加密就是每次加密一块明文, 块加密也是对称加密, 常见的加密算法有\nIDEA 加密 DES 加密 AES 加密 Advanced Encryption Standard (AES), 高级加密标准, 是典型的块加密, 被设计来取代 DES, 由 Joan Daemen 和 Vincent Rijmen 所设计。\n块密码的分组模式\r分组加密会将明文消息划分为固定大小的块, 每块明文在密钥的控制下分别加密为密文。然而, 并非所有消息的长度都是密码块大小的整数倍, 因此通常需要对最后一块进行填充。块密码的分组模式 (Mode of Operation) 定义了如何使用同一个块密码密钥对超过单块的数据进行加密, 并保证数据的安全性。通过将变长数据划分为若干密码块, 并对最后一块使用适当的填充方式, 使其符合密码块的大小要求, 从而实现对更长数据的加密。\n分组模式描述了加密每一数据块的过程, 通常借助一个附加输入值初始化向量 (IV) 进行随机化, 以提高安全性。\n分组模式\rECB\rECB (Electronic Codebook Mode, 电子密码本模式) 每块独立加密, 易受模式分析攻击\n加密\n解密\n优点\n实现简单 不同明文分组的加密可以并行计算, 速度很快 缺点\n同样的明文块会被加密成相同的密文块, 不会隐藏明文分组的统计规律 CBC\rCBC (Cipher Block Chaining Mode, 密码块链接模式) 每块明文需与前一块密文异或后再加密, 需初始化向量 (IV)\nIV 不要求保密 IV 必须是不可预测的, 而且要保证完整性 加密\n解密\n优点\n密文块不仅和当前密文块相关, 而且和前一个密文块或 IV 相关, 隐藏了明文的统计特性 具有有限的两步错误传播特性, 即密文块中的一位变化只会影响当前密文块和下一密文块 具有自同步特性, 即第 k 块起密文正确, 则第 k+1 块就能正常解密 缺点\n加密不能并行, 解密可以并行 OFB\rOFB (Output feedback, 输出反馈模式) 这些模式不需要填充, 适合流式数据\n加密\n解密\n优点\n不具有错误传播特性 缺点\nIV 无需保密, 但是对每个消息必须选择不同的 IV 不具有自同步能力 CFB\rCFB (Cipher feedback, 密码反馈模式) 这些模式不需要填充, 适合流式数据\n加密\n解密\n优点\n适应于不同数据格式的要求 有限错误传播 自同步 缺点\n加密不能并行化, 解密不能并行 CTR\rCTR (Counter mode, 计数器模式) 这些模式不需要填充, 适合流式数据\n加密\n解密\n优点\nCTR 模式比 OFB 模式有一些优势。一个优点是它允许并行加密和解密多个块, 因为可以为每个块独立计算密钥流。这可以提高加密和解密过程的性能和效率 特性 描述 加密可并行化 (Encryption parallelizable) 是 (Yes) 解密可并行化 (Decryption parallelizable) 是 (Yes) 随机读取访问 (Random read access) 是 (Yes) XTS\rXTS (XEX-based Tweaked Codebook Mode with Ciphertext Stealing (XEX, Xor-Encrypt-Xor), 扩展磁盘模式) XTS 主要用于磁盘加密和存储设备加密, 其设计目标是高效、安全地加密大规模数据, 同时满足存储系统的特殊需求, 如支持随机访问\n数据完整性与认证\r分组模式仅保证数据的机密性, 但不直接保证数据的完整性或防篡改能力\n完整性保障通常需要采用分离的消息验证码 (MAC, Message Authentication Code) 实现, 例如 CBC-MAC。密码学社区认识到需要专门的方法来保证数据的完整性, 因此 NIST 提出了多种消息认证码方案, 包括 HMAC、CMAC 和 GMAC。\n认证加密模式\r认证加密模式 (AE, Authenticated Encryption or authenc) 为简化加密与认证的组合, 密码学社区提出了将加密与认证结合的单一模式。\nAE 模式的典型例子包括 CCM、GCM、CWC、EAX、IAPM 和 OCB\n初始化向量 (IV)\r初始化向量 (IV, Initialization Vector) 是许多分组模式中用于随机化加密的一块数据。IV 的作用是使相同的明文, 相同密钥下可以产生不同的密文, 而无需重新生成密钥, 从而避免了重新生成密钥这一复杂过程。\n初始化向量与密钥相比有不同的安全性需求\n保密性: IV 通常不需要保密 唯一性: 在同一密钥的情况下, IV 不应重复使用 CBC 和 CFB: 重复使用 IV 会泄露首个块明文的某些信息, 并可能暴露两个不同消息中相同的前缀 OFB 和 CTR: 重复使用 IV 会导致完全丧失加密安全性 不可预测性 CBC 模式, 加密时 IV 必须是无法预测的 某些不安全的 IV 生成方法 (如 SSL 2.0 使用的上一个消息的最后一块密文作为下一个消息的 IV), 是不安全的 填充 (Padding)\r在块密码的分组模式中, 不同模式对消息长度的要求和处理方式有所不同\n需要填充的模式\rECB (电子密码本模式) CBC (密码块链接模式) 这些模式要求消息长度必须是密码块大小的整数倍。因此, 对于长度不足一个完整密码块的最后一块消息, 需要在加密前进行填充\n不需要填充的模式\rCFB (密码反馈模式) OFB (输出反馈模式) CTR (计数器模式) 这些模式不要求消息长度是密码块大小的整数倍, 最后一个不完整的明文块会与密钥流块的前几个字节异或, 生成与该明文块长度相同的密文块\n常见填充模式\rPKCS7Padding\rPKCS7Padding 的块大小是一个参数, 支持 1 - 255 字节的块大小, 因此适用于更广泛的加密算法 (如 AES)。它的填充方式与 PKCS5Padding 类似, 但适用于任何块大小, 不限于 8 字节, 而 PKCS5Padding 固定为 8 字节。当块大小为 8 字节时, 它们的填充方式完全相同。\nPKCS5Padding\rPKCS5Padding 是 PKCS7Padding 的子集, 适用于块大小为 8 字节的加密算法 (如 DES)。它填充的方式是确保数据块长度达到 8 字节的整数倍。\n在填充的每个字节中写入填充的字节数。例如, 若需填充 3 个字节, 每个字节的值为 03\n严格来说, PKCS5Padding 不能与 AES 一起使用, 因为它仅定义了 8 字节的块大小。对于 AES, 块大小始终为 16 字节。我认为, AES/CBC/PKCS5Padding 在内部会被解释为 AES/CBC/PKCS7Padding\nZeroPadding\r使用零填充。适用于消息长度固定的情况, 但可能带来歧义 (当明文末尾本身包含零字节时)\n原文\ngolang 中AES加密详解\nECB - CTF Wiki\nAES/CBC/PKCS5Padding vs AES/CBC/PKCS7Padding with 256 key size performance java\n","date":"2019-07-10T15:27:43+08:00","permalink":"https://blog.acesheep.com/p/cryptography-aes-block-encryption/","title":"密码学 Crypto AES 块加密"},{"content":"Wireshark 是一款广泛使用的网络协议分析工具, 它能够帮助我们分析和调试网络流量。在分析 SSL/TLS 流量时, Wireshark 可以帮助我们查看加密的数据, 但前提是我们需要提供密钥或会话信息。\n使用预主密钥解密 SSL 和 TLS\r在 Wireshark 中使用预主密钥 (pre-master secret key) 解密 SSL 和 TLS 流量是推荐的方法。预主密钥由客户端生成, 服务器使用该密钥派生出用于加密会话流量的主密钥。这种方法通过 Diffie-Hellman 实现, 是目前的加密标准。\n你的浏览器可以记录预主密钥日志, Wireshark 可利用这些日志解密 SSL 和 TLS 会话\n设置 Windows 环境变量\r在 Windows 系统中, 需要设置名为 SSLKEYLOGFILE 的环境变量, 用于指定预主密钥日志文件的存储路径\n首先右键单击 我的电脑, 然后从菜单中选择 属性\n点击左侧的 高级系统设置\n在 系统属性 窗口的 高级 选项卡中, 点击 环境变量\n在 用户变量 下, 点击 新建。如果你想为系统上的每个用户记录 SSL 密钥, 你也可以在 系统变量 下创建变量, 但我更喜欢将其限制在我的个人资料中。\n设置变量名为 SSLKEYLOGFILE, 变量值为日志文件的路径 (例如 C:\\Users\\AceSheep\\Documents\\Wireshark\\ssl-keys.log)\n需要注意的是, 如果你创建 系统变量, 则需要使用适当的通配符或将文件存储在所有用户都可以访问的位置。例如, 你可以选择 %USERPROFILE%\\App Data\\ssl-keys.log 或 C:\\ssl-keys.log\n完成后, 单击 确定 并转到下一步骤\n设置 Linux 或 Mac 环境变量\r在 Linux 或 Mac 中, 需要使用 vim 编辑器设置 SSLKEYLOGFILE 环境变量\n打开终端, 输入以下命令编辑配置文件\n在 Linux 中: vim ~/.bashrc 在 Mac 中: vim ~/.bash_profile 在文件末尾添加以下行\nexport SSLKEYLOGFILE=~/.ssl-key.log 保存并退出编辑器 :wq\n验证变量是否设置成功\necho $SSLKEYLOGFILE 执行命令后, 你应该会看到类似于上图的输出。/Users/comparitech/.ssl-key.log 是我的 SSL 预主密钥日志的完整路径。注意: 你需要记下你的日志路径, 它会有所不同, 然后输入到 Wireshark 中\n现在已经设置好变量了, 可以继续下一步\n启动浏览器并检查日志文件\r在启动 Wireshark 并将其配置为使用预主密钥解密 SSL 之前, 你应该启动浏览器并确认日志文件正在被使用\n打开支持 SSL 的浏览器 (如 Chrome 或 Firefox)\n打开一个启用 SSL 的网站\n为了填充日志, 访问启用了 SSL 的站点非常重要。我使用自己的 Apache 服务器进行测试, 但任何站点都可以。使用预主共享密钥的最大好处之一是你 无需拥有服务器访问权限 即可解密 SSL 流量。\n检查日志文件\n访问启用 SSL 的网站后, 请检查日志文件中的数据。确认日志文件中记录了预主密钥\n在 Windows 中, 使用记事本查看日志文件\n在 Linux 或 Mac 中, 使用命令查看日志文件\ntail -f ~/.ssl-key.log 在任何操作系统上, 你的文件应该看起来与上面的类似。确认浏览器正在你选择的位置记录预主密钥后, 你可以配置 Wireshark 以使用这些密钥解密 SSL\n配置 Wireshark 解密 SSL\r一旦你的浏览器记录了预主密钥, 就可以配置 Wireshark 使用这些日志来解密 SSL\n打开 Wireshark, 点击 编辑 -\u0026gt; 首选项\n在左侧展开 Protocols\n找到并选择 SSL\n在 (Pre)-Master-Secret log filename 字段中, 输入预主密钥日志文件的路径\n点击 确定 保存设置\n捕获会话并解密 SSL\r最后一步是捕获测试会话并确保 Wireshark 成功解密 SSL\n开启 Wireshark 的抓包功能, 捕获目标流量 访问 SSL 网站, 生成加密流量数据 在 Wireshark 中选择含加密数据的包, 切换到 解密 SSL 数据 视图即可查看解密内容 就我而言, 我将选择包含 text/HTML 编码的 HTTP 流量, 因为我想查看 Web 服务器发送到浏览器的源代码。但任何使用预主密钥或私钥的加密传输都可以使用此方法。这包括通过 Diffie-Hellman 或类似密钥交换使用完美前向加密 (PFE) 的所有数据\n选择加密数据框后, 查看数据包字节视图 (Packet byte view), 特别是视图下方的选项卡。你应该会看到解密的 SSL 数据 (Decrypted SSL) 条目等\n你会注意到会话仍然看起来充满垃圾, 并且看不到 HTML。这是因为我的 Web 服务器 (以及大多数 Apache 服务器) 默认使用 GZIP 压缩\n单击未压缩实体主体 (Uncompressed entity body) 选项卡 (此选项卡仅在启用 SSL 解密的情况下显示) 时, 你可以查看站点的源代码。例如, 以下是默认 Apache 页面的纯文本形式的标题元素\n使用服务器 RSA 私钥解密 SSL\r你可能之前已经注意到, Wireshark 有一个字段允许你上传 RSA 密钥并使用它们解密 SSL。实际上, RSA 密钥解密已被弃用, 因为现代加密标准 (如 Diffie-Hellman 和 TLS 1.3) 使用完美前向保密 (PFE, Perfect Forward Encryption), 与 Diffie-Hellman 协商的会话不直接使用 RSA 密钥。而是生成一次性密钥, 仅存储在 RAM 中, 使用磁盘上的密钥进行加密。\n打开 Wireshark 点击 Edit, 选择 Preferences. Preferences 窗口会打开, 在左侧找到 Protocols -\u0026gt; SSL -\u0026gt; RSA keys list\n如果你之前使用 RSA 密钥解码流量, 并且它停止工作, 则可以通过启用 SSL 日志记录来确认目标机器正在使用 Diffie-Hellman 交换\n要打开日志记录, 请点击工具栏菜单中的 Edit, 然后选择 Preferences。展开左侧的 Protocols 菜单项并向下滚动到 SSL。从这里, 你可以点击 Browse 按钮并设置 SSL 日志的位置 (例如, C:\\Users\\AceSheep\\Documents\\Wireshark\\ssl-debug.log)\n设置位置后, 所有 SSL 交互都将记录在指定的文件中\n使用启用 SSL 的域名捕获会话, 然后检查日志。具体来说, 你应该滚动直到找到协商 TLS 握手的帧。你可能会在密码字符串中看到一个明显的 DHE 条目\n这意味着启用了 Diffie-Hellman 密钥交换。在我的例子中, Apache 使用带有椭圆曲线 (elliptic-curve) 密钥的 Diffie-Hellman, 用字符串 ECDHE 表示\n再滚动一点, 你可能会发现无法找到主密钥\n如果你的日志看起来像这样, 并且你无法使用 RSA 密钥解密数据, 那么你别无选择, 只能切换到上面的预主密钥方法\n由于 PFE 正在成为标准实践, 并且 TLSv1.3 可能会强制执行该问题, 因此简单的 RSA 密钥解密已被弃用, 不应使用\nnginx 设置\r在调试的时候需要把加密方式切换到没有 ECDHE 的套件上, 调试完成在切换回去\nssl_ciphers AES128-GCM-SHA256; 可以在这里查找 Security/Server Side TLS\n原文\nHow to Decrypt SSL with Wireshark – HTTPS Decryption Guide\n","date":"2019-07-09T17:00:00+08:00","permalink":"https://blog.acesheep.com/p/decrypt-ssl-with-wireshark-for-website-debugging/","title":"使用 Wireshark 解密 SSL"},{"content":"Charles 是一款强大的网络调试代理工具, 主要用于监控和调试 HTTP、HTTPS、WebSocket 等协议的网络请求和响应。它通常用于开发和测试 web 应用、移动应用、API 调试等场景。通过 Charles, 开发者可以捕获并分析客户端与服务器之间的网络流量, 查看请求的详细信息 (如请求头、请求体、响应内容、状态码等), 以及模拟和修改请求。\n安装 Charles\r添加公钥\r使用 wget 下载并添加 Charles 的公钥\nwget -q -O - https://www.charlesproxy.com/packages/apt/PublicKey | sudo apt-key add - 或者使用 apt-key adv\nsudo apt-key adv --keyserver pgp.mit.edu --recv-keys 1AD28806 添加资源库\r将 Charles 的 APT 包资源库添加到系统源列表中\nsudo sh -c \u0026#39;echo deb https://www.charlesproxy.com/packages/apt/ charles-proxy main \u0026gt; /etc/apt/sources.list.d/charles.list\u0026#39; 更新源并安装 Charles\r更新软件源并安装 Charles\nsudo apt-get update sudo apt-get install charles-proxy 破解 Charles\rCharles 在线破解工具\ngithub.com/8enet/Charles-Crack\n将下载的 Charles.jar 文件, 替换到安装目录下。默认安装目录在 /usr/lib/charles-proxy/\n注意: 为了保险起见先把原始 charles.jar 复制到其他目录, 将破解后的 charles.jar 移动到对应位置, 确保该目录下只有一个 charles.jar 就好了\n配置 Charles\r生成 SSL 证书\r在 Charles 中, 选择 Help -\u0026gt; SSL Proxying -\u0026gt; Install Charles Root Certificate 安装后可以在 ~/.charles/ca/ 目录找到两个证书文件 charles-proxy-ssl-proxying-certificate.cer charles-proxy-ssl-proxying-certificate.pem 转换证书格式\r使用 openssl 转换 PEM 格式为 CRT 格式\nopenssl x509 -outform der -in charles-proxy-ssl-proxying-certificate.pem -out charles-proxy-ssl-proxying-certificate.crt 添加根证书到系统\r注意扩展阅读部分\n在 /usr/share/ca-certificates 下创建一个 charles 目录 再将转换格式后得到的证书 charles-proxy-ssl-proxying-certificate.crt 复制到 /usr/share/ca-certificates/charles 中 sudo mkdir /usr/share/ca-certificates/charles sudo cp ~/.charles/ca/charles-proxy-ssl-proxying-certificate.crt /usr/share/ca-certificates/charles/ 更新根证书配置\r编辑 /etc/ca-certificates.conf 文件, 将 charles/charles-proxy-ssl-proxying-certificate.crt 添加到文件末尾\necho \u0026#39;charles/charles-proxy-ssl-proxying-certificate.crt\u0026#39; \u0026gt;\u0026gt; /etc/ca-certificates.conf 更新证书配置\nsudo update-ca-certificates 完成后发现 /etc/ssl/certs 目录中应该多了一个 charles-proxy-ssl-proxying-certificate.pem 文件, 表示成功\n配置 Charles SSL 代理\r在 Charles 中, 选择 Proxy -\u0026gt; SSL Proxy Settings -\u0026gt; SSL Proxy 添加一个 Host 为 *, Port 为 443 的 Location 来代理所有 HTTPS 请求 测试代理\r设置 Charles 使用 8888 端口 SOCKS 代理, 访问一个网站, 查看是否成功抓取 HTTP 和 HTTPS 请求信息\n扩展阅读 - Ubuntu 添加可信任根证书\r添加根证书\rUbuntu 下添加根证书非常简单, 只要将证书 (扩展名为crt) 复制到 /usr/local/share/ca-certificates 目录, 并运行 update-ca-certificates\n[yaxin@ubox ~]$ sudo cp xinmu.crt /usr/local/share/ca-certificates [yaxin@ubox ~]$ sudo update-ca-certificates Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d....done. 删除根证书\r删除证书并更新证书存储\n直接将 /usr/local/share/ca-certificates 对应的证书删除, 然后执行 update-ca-certificates\n[yaxin@ubox ~]$ sudo rm -f /usr/local/share/ca-certificates/xinmu.crt [yaxin@ubox ~]$ sudo update-ca-certificates Updating certificates in /etc/ssl/certs... 0 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d....done. 这时候并不会提示 1 removed, 但证书是已经被删除了的\n原理\r其实 update-ca-certificates 是一个 shell 脚本, 使用 which 找出 update-ca-certificates 的绝对路径, 然后打开就可以查看其源码\n[yaxin@ubox ~]$ which update-ca-certificates /usr/sbin/update-ca-certificates [yaxin@ubox ~]$ file /usr/sbin/update-ca-certificates /usr/sbin/update-ca-certificates: POSIX shell script, ASCII text executable 通过阅读源码可以看出, update-ca-certificates 命令的本质其实是将 PEM 格式的根证书内容附加到 /etc/ssl/certs/ca-certificates.crt, 而其中本身就包含了系统自带的各种可信根证书.\n原文\nCharles - APT repository\n初学Ubuntu：Ubuntu16.04系统Charles的配置\nUbuntu添加可信任根证书\n","date":"2019-07-09T16:27:10+08:00","permalink":"https://blog.acesheep.com/p/install-charles-on-ubuntu-16.04-via-apt-get/","title":"Ubuntu 16.04 通过 apt-get 安装 Charles"},{"content":"Mozilla 为使用 TLS 的服务器提供三种推荐配置。请根据你的受众选择正确的配置 (配置生成器)\n现代 (Modern): 支持 TLS 1.3 的现代客户端, 无需向后兼容 中间 (Intermediate): 通用服务器的推荐配置 旧版 (Old): 由非常旧的客户端或库访问的服务, 例如 Internet Explorer 8 (Windows XP)、Java 6 或 OpenSSL 0.9.8 配置 Firefox Android Chrome Edge Internet Explorer Java OpenSSL Opera Safari 现代 63 10.0 70 75 \u0026ndash; 11 1.1.1 57 12.1 中间 27 4.4.2 31 12 11 (Win7) 8u31 1.0.1 20 9 旧版 1 2.3 1 12 8 (WinXP) 6 0.9.8 5 1 中间和旧版配置中的密码套件顺序非常重要, 因为它决定了算法选择的优先级\nOpenSSL 会忽略其不支持的密码套件, 因此始终按照以下推荐顺序使用完整的密码套件集。在现代版本的 OpenSSL 中使用旧版配置可能需要支持已弃用密码的自定义构建。\n现代兼容性 (Modern Compatibility)\r对于支持 TLS 1.3 且不需要向后兼容的客户端, 现代配置提供了极高的安全性\n密码套件 (Cipher Suites): TLS 1.3: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 TLS 1.2: 无 (完全禁用) 协议 (Protocols): TLS 1.3 TLS 曲线 (TLS Curves): X25519 prime256v1 (P-256) secp384r1 (P-384) 证书类型 (Certificate Type): ECDSA (P-256) 椭圆曲线证书 HSTS (HTTP 严格传输安全): max-age=63072000 (两年) 证书生命周期 (Certificate Lifespan): 90 days 密码套件优先级 (Cipher Preference): 客户端选择, 以优化硬件加速支持 标识 密码套件名称 协议 密钥交换 (Kx) 认证 (Au) 加密算法 (Enc) 消息认证 (Mac) 0x13,0x01 - TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD 0x13,0x02 - TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD 0x13,0x03 - TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD 使用建议 (Rationale):\n所有密码套件均支持 前向保密 (forward secret) 和 认证加密 (authenticated) 这些密码套件都很强大, 因此允许客户端选择, 以便根据硬件支持优化性能 (如硬件加速的 AES) 推荐使用 ECDSA 证书, 并选用 P-256 曲线。P-384 曲线对安全性的提升有限, 而 Ed25519 尚未被广泛支持。 中间兼容性 (Intermediate Compatibility) 推荐 recommended\r对于不需要兼容旧版客户端 (如 Windows XP 或旧版 OpenSSL) 服务。这是针对绝大多数服务的推荐配置, 因为它非常安全, 并且与过去五年 (或更长时间) 发布的几乎所有客户端兼容。\n密码套件 (Cipher Suites): TLS 1.3: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 TLS 1.2: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305 协议 (Protocols): TLS 1.2, TLS 1.3 TLS 曲线 (TLS Curves): X25519 prime256v1 (P-256) secp384r1 (P-384) 证书类型 (Certificate Type): ECDSA (P-256) (推荐), 或者 RSA (2048-bits) DH 参数大小 (DH Parameter Size): 2048 (ffdhe2048, 符合 RFC 7919) HSTS (HTTP 严格传输安全): max-age=63072000 (两年) 证书生命周期 (Certificate Lifespan): 90 days (推荐) to 366 days 密码套件优先级 (Cipher Preference): 客户端选择 0x13,0x01 - TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD 0x13,0x02 - TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD 0x13,0x03 - TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD 0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD 0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD 0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD 0xCC,0xA9 - ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xA8 - ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0x00,0x9E - DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD 0x00,0x9F - DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD 0xCC,0xAA - DHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=DH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 使用建议:\n所有密码套件均支持 前向保密 (forward secret) 和 认证加密 (authenticated) TLS 1.2 是最低支持的协议, 符合 RFC 7525 和 PCI DSS 的要求 建议使用 ECDSA 证书, 而不是 RSA 证书, 因为它们允许在使用 Internet Explorer 11 的 Windows 7 客户端上使用 ECDHE, 可兼容 Windows Server 2008 R2 的 IE11 密码套件都很安全, 因此我们允许客户进行选择, 因为他们最清楚是否支持硬件加速的 AES Microsoft 已停止支持 Windows XP (包括所有嵌入式版本), 因此无需支持旧协议和密码 需要提供对 Windows Server 2008 R2 的 IE 11 的访问权限且无法切换或添加 ECDSA 证书的可以添加 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 虽然我们的目标是支持广泛的客户端, 但我们会合理地禁用支持较少的密码 (如 ARIA、Camellia、3DES、SEED) 建议的最长证书有效期为 90 天, 以鼓励自动化颁发流程 旧版向后兼容配置 (Old Backward Compatibility)\r此配置适用于许多非常老旧的客户端, 只应在必要时作为最后手段使用。它支持更广泛的协议和密码套件, 确保兼容某些非常老旧的客户端, 如 Internet Explorer 8 (Windows XP)、Java 6 或 OpenSSL 0.9.8\n密码套件 (Cipher Suites): TLS 1.3: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 TLS 1.0 - 1.2: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA 协议 (Protocols): TLS 1.0, TLS 1.1, TLS 1.2, TLS 1.3 TLS 曲线 (TLS Curves): X25519 prime256v1 (P-256) secp384r1 (P-384) 证书类型 (Certificate Type): RSA (2048-bits) 证书曲线 (Certificate Curve): 无 DH 参数大小 (DH Parameter Size): 1024 (生成时使用 openssl dhparam 1024) HSTS (HTTP 严格传输安全): max-age=63072000 (两年) 证书生命周期 (Certificate Lifespan): 90 days (推荐) to 366 days 密码套件优先级 (Cipher Preference): 服务器选择 0x13,0x01 - TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD 0x13,0x02 - TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD 0x13,0x03 - TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD 0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD 0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD 0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD 0xCC,0xA9 - ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xCC,0xA8 - ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0x00,0x9E - DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD 0x00,0x9F - DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD 0xCC,0xAA - DHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=DH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD 0xC0,0x23 - ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256 0xC0,0x27 - ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256 0xC0,0x09 - ECDHE-ECDSA-AES128-SHA TLSv1 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1 0xC0,0x13 - ECDHE-RSA-AES128-SHA TLSv1 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1 0xC0,0x24 - ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384 0xC0,0x28 - ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 0xC0,0x0A - ECDHE-ECDSA-AES256-SHA TLSv1 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1 0xC0,0x14 - ECDHE-RSA-AES256-SHA TLSv1 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1 0x00,0x67 - DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256 0x00,0x6B - DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256 0x00,0x9C - AES128-GCM-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(128) Mac=AEAD 0x00,0x9D - AES256-GCM-SHA384 TLSv1.2 Kx=RSA Au=RSA Enc=AESGCM(256) Mac=AEAD 0x00,0x3C - AES128-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA256 0x00,0x3D - AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256 0x00,0x2F - AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 0x00,0x35 - AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1 0x00,0x0A - DES-CBC3-SHA SSLv3 Kx=RSA Au=RSA Enc=3DES(168) Mac=SHA1 使用建议:\n此配置仅应在某些需要兼容老旧客户端的特殊情况下使用 如果可能的话, 仅对需要此此兼容性配置的接入点 (endpoints) 使用, 与其他流量隔离 完全禁用 SSLv3 支持, 终止了对旧版 Windows XP SP2 客户端的支持。对于需要支持 Windows XP SP2 的用户可以使用此配置的 先前版本, 但需要注意的是 SSLv3 已不再安全。 此配置需要自定义构建才能与 OpenSSL 的现代版本配合使用, 使用 OpenSSL 的 enable-ssl3, enable-ssl3-method, enable-deprecated, 和 enable-weak-ssl-ciphers 选项 支持大多数尚未被明确破解和使用起来很危险的密码套件 原文\nSecurity/Server Side TLS\n","date":"2019-07-09T15:32:00+08:00","image":"https://blog.acesheep.com/p/nginx-server-side-tls-best-configuration/cover_hu7317925199728832582.png","permalink":"https://blog.acesheep.com/p/nginx-server-side-tls-best-configuration/","title":"Nginx 服务器端 TLS 最佳配置"},{"content":"跳转指令分为三类：无条件跳转、基于寄存器值跳转、以及基于标志位的条件跳转\n无条件跳转\rJMP: 直接无条件跳转到指定位置\nJMP label 基于寄存器值跳转\rJCXZ：若 CX 寄存器的值为 0, 则跳转\nJCXZ label JECXZ：若 ECX 寄存器的值为 0, 则跳转\nJECXZ label 基于标志位的条件跳转\r条件跳转指令依据 EFLAGS 寄存器的特定标志位设置状态进行跳转, 常见标志位有\nCF (进位标志) PF (奇偶标志) ZF (零标志) SF (符号标志) OF (溢出标志) JE ; 等于则跳转 同 JZ JNE ; 不等于则跳转 同 JNZ JZ ; 为 0 则跳转 JNZ ; 不为 0 则跳转 JS ; 为负则跳转 JNS ; 不为负则跳转 JC ; 进位则跳转 JNC ; 不进位则跳转 JO ; 溢出则跳转 JNO ; 不溢出则跳转 JA ; 无符号大于则跳转 JNA ; 无符号不大于则跳转 JAE ; 无符号大于等于则跳转 同 JNB JNAE ; 无符号不大于等于则跳转 同 JB JG ; 有符号大于则跳转 JNG ; 有符号不大于则跳转 JGE ; 有符号大于等于则跳转 同 JNL JNGE ; 有符号不大于等于则跳转 同 JL JB ; 无符号小于则跳转 JNB ; 无符号不小于则跳转 JBE ; 无符号小于等于则跳转 同 JNA JNBE ; 无符号不小于等于则跳转 同 JA JL ; 有符号小于则跳转 JNL ; 有符号不小于则跳转 JLE ; 有符号小于等于则跳转 同 JNG JNLE ; 有符号不小于等于则跳转 同 JG JP ; 奇偶位置位则跳转 JNP ; 奇偶位清除则跳转 JPE ; 奇偶位相等则跳转 同 JP JPO ; 奇偶位不等则跳转 同 JNP 具体指令\n指令 条件描述 JE / JZ 等于/为零 (ZF=1 时跳转) JNE / JNZ 不等于/非零 (ZF=0 时跳转) JA / JNBE 大于/不低于或等于 (CF=0 且 ZF=0 时跳转) JAE / JNB 大于或等于/不低于 (CF=0 时跳转) JB / JNAE 小于/不高或等于 (CF=1 时跳转) JBE / JNA 小于或等于/不高 (CF=1 或 ZF=1 时跳转) JG / JNLE 大于/不小或等于 (ZF=0 且 SF=OF 时跳转) JGE / JNL 大于或等于/不小于 (SF=OF 时跳转) JL / JNGE 小于/不大于或等于 (SF≠OF 时跳转) JLE / JNG 小于或等于/不大于 (ZF=1 或 SF≠OF 时跳转) JS 符号标志为负 (SF=1 时跳转) JNS 符号标志为正 (SF=0 时跳转) JO 溢出标志为 1 (OF=1 时跳转) JNO 溢出标志为 0 (OF=0 时跳转) JC 进位标志为 1 (CF=1 时跳转) JNC 进位标志为 0 (CF=0 时跳转) JP / JPE 奇偶标志为 1 (偶数个 1) (PF=1 时跳转) JNP / JPO 奇偶标志为 0 (奇数个 1) (PF=0 时跳转) JE 和 JZ 的区别\r在 x86 汇编中, JE（Jump if Equal）和 JZ（Jump if Zero）本质上是相同的指令, 指向同一个操作码。它们的功能完全一致, 区别仅在于它们的语义使用场景不同\n功能\rJE: 跳转到目标地址, 如果标志寄存器（EFLAGS）的 ZF（Zero Flag） 位为 1 JZ: 跳转到目标地址, 如果标志寄存器的 ZF（Zero Flag） 位为 1 换句话说, 两者的核心是条件跳转依赖于 Zero Flag 的值, 当 Zero Flag 为 1 时跳转\n语义区别\r虽然它们是等效的, 但在程序编写中, 使用的指令名称会根据程序员的意图和上下文有所不同\nJE（Jump if Equal）\n用于表示两值相等的场景, 通常在比较（如 CMP）之后使用\n示例\nCMP EAX, EBX ; 比较 EAX 和 EBX JE EqualLabel ; 如果相等则跳转 JZ（Jump if Zero）\n用于检查结果是否为零, 通常在减法或按位运算等操作之后使用\n示例\nSUB EAX, EBX ; EAX 减去 EBX JZ ZeroLabel ; 如果结果为零则跳转 使用习惯总结\rJE 强调逻辑上的 \u0026ldquo;相等\u0026rdquo; JZ 强调结果值为零 虽然它们最终执行的效果是一样的, 使用哪一个主要取决于代码上下文和可读性\n扩展知识\rZF（Zero Flag）的设置条件\n比较（CMP）: 如果两个操作数相等, ZF 会被置为 1 减法（SUB）: 如果结果为 0, ZF 会被置为 1 按位操作: 一些按位运算（如 AND）的结果为 0 时, ZF 也会被置为 1 影响标志位的汇编指令\r加法指令：ADD、ADC、INC、XADD 除了 INC 不影响 CF 标志位外, 都影响条件标志位 CF、ZF、SF、OF CF 最高位是否有进位 DF 若两个操作数符号相同而结果符号与之相反 OF=1, 否则 OF=0 减法指令：SUB、SBB、DEC、NEG、CMP、CMPXCHG、CMPXCHG8B 前六种除了 DEC 不影响 CF 标志外都影响标志位。CMPXHG8B 只影响 ZF CF 说明无符号数相减的溢出, 同时又确实是被减数最高有效位向高位的借位 OF 位则说明带符号数的溢出 无符号运算时, 若减数\u0026gt;被减数, 有借位 CF=1, 否则 CF=0 OF 若两个数符号相反, 而结果的符号与减数相同则 OF=1. 否则 OF=0 乘法指令：MUL、IMUL MUL：如果乘积高一半为 0, 则 CF 和 OF 位均为 0, 否则 CF 和 OF 均为 1 IMUL：如果高一半是低一半符号的扩展, 则 CF 位和 OF 位均为 0, 否则就均为 1 除法指令：DIV、IDIV 对所有条件位均无定义 逻辑指令：AND、OR、NOT、XOR、TEST NOT 不影响标志位, 其余 4 种 CF、OF、置 0, AF 无定义, SF、ZF、PF 位看情况而定 定位扫描指令：BSF正向位扫描、BSR反向位扫描 影响 ZF 位 附件\r指令对标志寄存器的影响总结5.docx (PDF 版本)\n原文\n学 Win32 汇编[28] - 跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等\n汇编跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等\nx86 Assembly Guide\n","date":"2019-07-09T01:23:00+08:00","permalink":"https://blog.acesheep.com/p/x86-assembly-jump-instructions/","title":"x86 汇编跳转指令"},{"content":"rico93 大佬写了一个可以和 SSPanel-Uim 对接的后端. 可以在面板管理小鸡设置了, 这里介绍后端手动配置流程. 项目 wiki 上手确实有点难\n项目面板优先选择 rico 维护的面板. Anankke 的面板更新会延迟一点, 发现 bug 修复了也要等 pr 才能生效, dev 的分支 bug 也多\nv2Ray 付费的后端: pay-v2ray-sspanel-v3-mod_Uim-plugin\n项目变成私有的了 散了散了 v2rayv3/pay-v2ray-sspanel-v3-mod_Uim-plugin\n免费的在 rico 咕咕咕群里有存档. 自己找\n准备工作\r必需条件\r适用于 nginx + rico93 V2Ray 后端 + TLS + WS (+ Cloudflare 可选) 配置。基础条件和注意事项, 本文不作讲解\nCloudflare 账号一下简称 CF 域名一个, Nameserver 填写 CF 的 使用 acme.sh 配置 TLS 证书 (cf_dns 认证) CentOS 7.6 使用 cat /etc/redhat-release 查看 启用 BBR nginx 1.16, 且完成 WS 配置 建议开启 SELinux 和防火墙 (可选) rico93 后端配置\rrico 的免费或者付费后端 (建议付费给 rico 丢面包) rico 后端配置 rico 面板节点设置 简单介绍\r如果需要 Caddy 或者 Nginx 来反向代理, 请将第一个端口设定为 0, 让程序切成本地监听。V2Ray 的 grpc API 接口默认是 2333 (这 2333 不是连接端口)。这里不要修改\n后端支持两种连接方式\n数据库连接 ss-panel-v3-mod_Uim 和 SSRPanel webAPI ss-panel-v3-mod_Uim rico93 后端安装\r虽然支持使用脚本安装, 但是本文不用脚本安装\n安装脚本\r这里可以对应配置文件里面的参数\n--panelurl https://google.com # 表示 WEBAPI URL --panelkey 55fUxDGFzH3n # 表示 MU KEY --nodeid 123456 # 节点 ID, 可以为 0 --downwithpanel 1 # 前端面板异常下线时, 0 为节点端不下线、1 为节点跟着下线 --mysqlhost https://bing.com # 数据库访问域名 --mysqldbname demo_dbname # 数据库名 --mysqluser demo_user # 数据库用户名 --mysqlpasswd demo_dbpassword # 数据库密码 --mysqlport 3306 # 数据库连接端口 --speedtestrate 6 # 测速周期 --paneltype 0 # 面板类型, 0 为 ss-panel-v3-mod、1 为 SSRPANEL --usemysql 0 # 连接方式, 0 为 webapi, 1 为 MySQL 数据库连接, 请注意 SSRPANEL 必须使用数据库连接 --lsdn xx.xx.xx.xx # xx.xx.xx.xx 是你要设定的 dns 地址 --cfkey xxxx # cloudflare key --cfemail xxxx # cloudflare email --local xxx.zip # rico93 记忆中, 免费版的安装脚本用这个参数可以安装本地压缩包 手动安装\r简单来讲就是把原有的 v2ray 可执行程序替换成 rico93 的后端程序\n首先下载 rico93 的后端程序, 把原有的 v2ray 可执行程序替换成刚下载的后端. 注意关闭程序操作\n使用官方的脚本安装 V2Ray 官方程序, 这样能省去很多设置步骤\nbash \u0026lt;(curl -L -s https://install.direct/go.sh) 下载 rico93 的后端文件 v2ray-linux-64.zip\n解压后把 v2ray 替换到 /usr/bin/v2ray/v2ray\n修改 /etc/v2ray/config.json 文件, 复制这个模板, 并配置结尾的 sspanel:{}\n{ \u0026#34;api\u0026#34;: { \u0026#34;services\u0026#34;: [ \u0026#34;HandlerService\u0026#34;, \u0026#34;LoggerService\u0026#34;, \u0026#34;StatsService\u0026#34;, \u0026#34;RuleService\u0026#34; ], \u0026#34;tag\u0026#34;: \u0026#34;api\u0026#34; }, \u0026#34;inbounds\u0026#34;: [ { \u0026#34;listen\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;port\u0026#34;: 2333, \u0026#34;protocol\u0026#34;: \u0026#34;dokodemo-door\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;address\u0026#34;: \u0026#34;127.0.0.1\u0026#34; }, \u0026#34;tag\u0026#34;: \u0026#34;api\u0026#34; } ], \u0026#34;log\u0026#34;: { \u0026#34;access\u0026#34;: \u0026#34;/var/log/v2ray/access.log\u0026#34;, \u0026#34;error\u0026#34;: \u0026#34;/var/log/v2ray/error.log\u0026#34;, \u0026#34;loglevel\u0026#34;: \u0026#34;info\u0026#34; }, \u0026#34;outbounds\u0026#34;: [ { \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34;, \u0026#34;settings\u0026#34;: {} }, { \u0026#34;protocol\u0026#34;: \u0026#34;blackhole\u0026#34;, \u0026#34;settings\u0026#34;: {}, \u0026#34;tag\u0026#34;: \u0026#34;blocked\u0026#34; } ], \u0026#34;policy\u0026#34;: { \u0026#34;levels\u0026#34;: { \u0026#34;0\u0026#34;: { \u0026#34;connIdle\u0026#34;: 300, \u0026#34;downlinkOnly\u0026#34;: 5, \u0026#34;handshake\u0026#34;: 4, \u0026#34;statsUserDownlink\u0026#34;: true, \u0026#34;statsUserUplink\u0026#34;: true, \u0026#34;uplinkOnly\u0026#34;: 2 } }, \u0026#34;system\u0026#34;: { \u0026#34;statsInboundDownlink\u0026#34;: false, \u0026#34;statsInboundUplink\u0026#34;: false } }, \u0026#34;reverse\u0026#34;: {}, \u0026#34;routing\u0026#34;: { \u0026#34;settings\u0026#34;: { \u0026#34;rules\u0026#34;: [ { \u0026#34;ip\u0026#34;: [ \u0026#34;0.0.0.0/8\u0026#34;, \u0026#34;10.0.0.0/8\u0026#34;, \u0026#34;100.64.0.0/10\u0026#34;, \u0026#34;127.0.0.0/8\u0026#34;, \u0026#34;169.254.0.0/16\u0026#34;, \u0026#34;172.16.0.0/12\u0026#34;, \u0026#34;192.0.0.0/24\u0026#34;, \u0026#34;192.0.2.0/24\u0026#34;, \u0026#34;192.168.0.0/16\u0026#34;, \u0026#34;198.18.0.0/15\u0026#34;, \u0026#34;198.51.100.0/24\u0026#34;, \u0026#34;203.0.113.0/24\u0026#34;, \u0026#34;::1/128\u0026#34;, \u0026#34;fc00::/7\u0026#34;, \u0026#34;fe80::/10\u0026#34; ], \u0026#34;outboundTag\u0026#34;: \u0026#34;blocked\u0026#34;, \u0026#34;protocol\u0026#34;: [ \u0026#34;bittorrent\u0026#34; ], \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34; }, { \u0026#34;inboundTag\u0026#34;: [ \u0026#34;api\u0026#34; ], \u0026#34;outboundTag\u0026#34;: \u0026#34;api\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34; }, { \u0026#34;domain\u0026#34;: [ \u0026#34;regexp:(api|ps|sv|offnavi|newvector|ulog\\\\.imap|newloc)(\\\\.map|)\\\\.(baidu|n\\\\.shifen)\\\\.com\u0026#34;, \u0026#34;regexp:(.+\\\\.|^)(360|so)\\\\.(cn|com)\u0026#34;, \u0026#34;regexp:(.?)(xunlei|sandai|Thunder|XLLiveUD)(.)\u0026#34; ], \u0026#34;outboundTag\u0026#34;: \u0026#34;blocked\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34; } ] }, \u0026#34;strategy\u0026#34;: \u0026#34;rules\u0026#34; }, \u0026#34;stats\u0026#34;: {}, \u0026#34;sspanel\u0026#34;: { \u0026#34;nodeid\u0026#34;: 123456, \u0026#34;checkRate\u0026#34;: 60, \u0026#34;SpeedTestCheckRate\u0026#34;: 6, \u0026#34;panelUrl\u0026#34;: \u0026#34;https://google.com\u0026#34;, \u0026#34;panelKey\u0026#34;: \u0026#34;55fUxDGFzH3n\u0026#34;, \u0026#34;downWithPanel\u0026#34;: 1, \u0026#34;mysql\u0026#34;: { \u0026#34;host\u0026#34;: \u0026#34;https://bing.com\u0026#34;, \u0026#34;port\u0026#34;: 3306, \u0026#34;user\u0026#34;: \u0026#34;demo_user\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;demo_dbpassword\u0026#34;, \u0026#34;dbname\u0026#34;: \u0026#34;demo_dbname\u0026#34; }, \u0026#34;paneltype\u0026#34;: 0, \u0026#34;usemysql\u0026#34;: 0 } } webAPI\r修改面板 .config.php 文件 $System_Config['muKey']='55fUxDGFzH3n'; 设置一个复杂的密码 把面板地址填在 panelUrl 面板设置的 muKey 填写在 panelKey usemysql 这个后面要填 0 修改面板对应的 nodeid 配置结束w 数据库连接 (mysql)\r修改 mysql 节点, 把 数据库地址, 数据库端口, 数据库用户名, 数据库密码, 数据库表名 依次填入 usemysql 这个后面要填 1 修改面板对应的 nodeid 配置结束w rico93 面板节点设置\r添加/修改 一个节点 节点类型选择 V2Ray 或 V2Ray 中转 单端口多用户启用 -\u0026gt; 修改为 -\u0026gt; 只启用普通端口 填写节点地址, 按照下面格式 例子:\n1.1.1.1; 443; 4; tls; ws; path=/v2ray|host=tls的域名|inside_port=10550|outside_port=443 没有CDN的域名或者IP;外部端口;AlterId;协议层;附加协议;额外参数 判断逻辑:\n如果 外部端口 是 0 或者为 空, 则默认监听本地 [127.0.0.1:inside_port] (inside_port 下方有解释) 如果 外部端口 不是 0, 则监听 [0.0.0.0:外部端口], 此时无需设置 inside_port 默认使用 Caddy 来提供 TLS, 控制代码不会生成 TLS 相关的配置。Caddyfile 可以在本项目的 /Docker/Caddy_V2ray/Caddyfile 文件中看到 若 outside_port 存在, 则 PHP 端会在生成订阅时候使用 outside_port 覆盖 port 额外参数: 额外参数使用 | 来分隔\ninside_port # 为内部监听端口, 当宿主机安装多个后端时, 请确保每个不一样 outside_port # 用于重写外部端口, 当使用 WS + TLS 协议或 NAT 类型节点试使用 path # 为访问路径, 当协议为 WS 时使用。 host # 用于定义 headers, 当协议为 WS 时使用。 server # 用于当节点藏在 CDN 后时覆盖第一个地址 配置示例\r// TCP 示例, 请注意后面有两个分号 非CDN域名或者ip;非0;2;tcp;; // WS 非CDN域名或者ip;8080;2;ws;;path=/v2ray|host=这里可以用加了CDN的域名 // WS + TLS (自动配置) 非CDN域名或者ip;非0;2;tls;ws;path=/v2ray|host=tls的域名|inside_port=10550 // WS + TLS (Caddy / nginx 提供) 非CDN域名或者ip;0;2;tls;ws;path=/v2ray|host=tls的域名|inside_port=10550|outside_port=443 // nat 鸡 ws 非CDN域名或者ip;非0;2;ws;;path=/v2ray|host=这里可以用加了CDN的域名 // nat 鸡 ws + tls (自动配置), 因为部分商家并不提供 80 \u0026amp; 443 访问, 所以请考虑手动申请 SSL 证书 非CDN域名或者ip;非0;2;tls;ws;path=/v2ray|host=tls的域名 // nat 鸡 ws + tls (Caddy 提供), 因为部分商家并不提供 80 \u0026amp; 443 访问, 所以请考虑手动申请 SSL 证书 非CDN域名或者ip;0;2;tls;ws;path=/v2ray|host=tls的域名|inside_port=10550|outside_port=11120 以下为 KCP 示例部分, 支持所有 V2Ray 的 type\n// none: 默认值, 不进行伪装, 发送的数据是没有特征的数据包。 非CDN域名或者ip;非0;2;kcp;noop; // srtp: 伪装成 SRTP 数据包, 会被识别为视频通话数据 (如 FaceTime) 非CDN域名或者ip;非0;2;kcp;srtp; // utp: 伪装成 uTP 数据包, 会被识别为 BT 下载数据。 非CDN域名或者ip;非0;2;kcp;utp; // wechat-video: 伪装成微信视频通话的数据包 非CDN域名或者ip;非0;2;kcp;wechat-video; // dtls: 伪装成 DTLS 1.2 数据包 非CDN域名或者ip;非0;2;kcp;dtls; // wireguard: 伪装成 WireGuard 数据包 (并不是真正的 WireGuard 协议) 非CDN域名或者ip;非0;2;kcp;wireguard; 实例:\n(订阅) 有这个的是订阅时获取到的值. (后端) 后端用的值\n服务器IP: 111.222.333.444 服务器域名: us.exp.com v2ray(后端): 监听内网 127.0.0.1 v2ray(后端): 监听端口 9999 AlterId(订阅)(后端): 4 协议层(订阅)(后端): tls 附加协议(订阅)(后端): ws 额外参数: path=/v2ray|host=us.exp.com|inside_port=9999|server=us.exp.com|outside_port=443 ws路径(订阅)(后端): path=/v2ray Host地址(订阅)(后端): host=us.exp.com 监听端口(后端): inside_port=9999 如果套了cf这里写套了cf的域名(订阅): server=us.exp.com 外网访问的端口(订阅): outside_port=443 完整地址: 111.222.333.444;0;4;tls;ws;path=/v2ray|host=us.exp.com|inside_port=9999|server=us.exp.com|outside_port=443 原文 - rico93 的 wiki\n普通安装后端-安装 V2Ray, 仅适用于付费版\n[配置] 作为 V2Ray 后端\n仓库备份 v2ray-sspanel-v3-mod_Uim-plugin\n","date":"2019-07-08T18:05:00+08:00","permalink":"https://blog.acesheep.com/p/rico93-v2ray-backend-configuration/","title":"rico93 V2Ray 后端配置"},{"content":"PHP 7.4 可以设置好 remi repo 库之后直接用 yum 安装, 没有特殊需求不需要使用编译安装\n安装必要程序包\r首先, 安装 epel-release 和 yum-utils, 然后安装 Remi 仓库\nyum install epel-release yum-utils yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm CentOS 8\ndnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm 启用 Remi 仓库\r启用 remi-php74 仓库并更新系统\nyum-config-manager --enable remi-php74 yum update CentOS 8\nError: Problem: cannot install the best candidate for the job - nothing provides libedit-devel(x86-64) needed by php72-php-devel-7.2.33-1.el8.remi.x86_64 (try to add \u0026#39;--skip-broken\u0026#39; to skip uninstallable packages or \u0026#39;--nobest\u0026#39; to use not only best candidate packages) 对于 CentOS 8, 可能会遇到问题, 解决方法是启用 PowerTools 仓库\ndnf config-manager --set-enabled PowerTools You need to enable the PowerTools repository (equiv. of upstream CodeReady Linux Builder channel) which provide most of the developer stuff.\n你需要启用 PowerTools 存储库 (相当于上游 CodeReady Linux Builder 频道), 它提供大多数开发人员的内容\n搜索可安装的 PHP 7.4 扩展\r你可以使用以下命令来查看可用的 PHP 7.4 扩展\nyum search php74 | more yum search php74 | egrep \u0026#39;fpm|gd|mysql|memcache\u0026#39; php74-php-fpm.x86_64 : PHP FastCGI Process Manager php74-php-gd.x86_64 : A module for PHP applications for using the gd graphics php74-php-mysqlnd.x86_64 : A module for PHP applications that use MySQL php74-php-pecl-mysql.x86_64 : MySQL database access functions php74-php-pecl-mysql-xdevapi.x86_64 : MySQL database access functions 安装 PHP 7.4 和相关扩展\r根据需要安装 PHP 7.4 和相关扩展\nyum install php74 php74-php-devel php74-php-fpm php74-php-gd php74-php-json php74-php-mbstring php74-php-mysqlnd php74-php-xml php74-php-xmlrpc php74-php-opcache php74-php-mcrypt 检查 PHP 版本和模块\r你可以通过以下命令检查安装的 PHP 版本及其模块\nphp74 --version php74 --modules 配置 Nginx 以支持 PHP\r检查 php-fpm 服务的启动参数 检查 nginx 的用户组 创建 php-fpm.sock 目录 # 检查服务启动参数 cat /usr/lib/systemd/system/php74-php-fpm.service cat /etc/systemd/system/multi-user.target.wants/php74-php-fpm.service # 检查 nginx 用户组 egrep \u0026#39;^(user|group)\u0026#39; /etc/nginx/nginx.conf # 创建 sock 目录 (临时) mkdir -p /var/run/php-fpm/ # 创建 sock 目录 (永久) vim /usr/lib/systemd/system/php74-php-fpm.service ExecStartPre=/bin/mkdir -p /var/run/php-fpm/ ## 创建 sock 目录 (永久), 当 php74-php-fpm 更新后仍然生效 systemctl edit php74-php-fpm [Service] ExecStartPre=/bin/mkdir -p /var/run/php-fpm/ 修改 php-fpm 配置\r编辑 vim /etc/opt/remi/php74/php-fpm.d/www.conf 文件\nuser = nginx group = nginx listen = /var/run/php-fpm/php-fpm.sock listen.owner = nginx listen.group = nginx 修改 Session 文件夹所有权\r将 PHP 的 session 文件夹的所有权更改为 nginx 用户和组\nchown -R nginx:nginx /var/opt/remi/php74/lib/php 修改 Nginx 配置文件\r编辑 /etc/nginx/nginx.conf 文件\nserver { .... # 其他配置参数 location ~ \\.php$ { fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } } 启动 PHP-FPM 和 Nginx 服务\r启用并重启 php-fpm 和 nginx 服务\nsystemctl enable php74-php-fpm systemctl restart php74-php-fpm systemctl restart nginx 测试 PHP 配置\r在你的 Web 根目录下创建一个 phpinfo.php 文件以测试 PHP 是否正常工作\n\u0026lt;?php // test script for CentOS/RHEL 7+PHP 7.4+Nginx phpinfo(); ?\u0026gt; 配置 Xdebug 进行远程调试\r服务器主动与客户端通信, 远程调试客户端需要开放设置的端口\n把 phpinfo 页面完整复制到 Xdebug Wizard 生成安装步骤\n当 phpize, php-config 找不到时可以使用搜索命令\n# find / -name \u0026#34;phpize\u0026#34; /opt/remi/php74/root/usr/bin/phpize # find / -name \u0026#34;php-config\u0026#34; ./configure --with-php-config=/opt/remi/php74/root/usr/bin/php-config 编辑 /etc/opt/remi/php74/php.ini 文件, 添加 Xdebug 配置\nzend_extension = /opt/remi/php74/root/usr/lib64/php/modules/xdebug.so [xdebug] xdebug.auto_trace = true xdebug.remote_enable = true xdebug.remote_autostart = true xdebug.remote_connect_back = true xdebug.remote_port = 4000 xdebug.collect_vars = On xdebug.collect_return = On xdebug.collect_params = On xdebug.show_local_vars = On xdebug.default_enable = On xdebug.max_nesting_level = 10000 配置 VSCode 进行调试\r在 VSCode 中创建如下调试配置\n{ \u0026#34;version\u0026#34;: \u0026#34;0.2.0\u0026#34;, \u0026#34;configurations\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;Listen for XDebug\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;php\u0026#34;, \u0026#34;request\u0026#34;: \u0026#34;launch\u0026#34;, \u0026#34;port\u0026#34;: 4000, \u0026#34;pathMappings\u0026#34;: { \u0026#34;/usr/share/nginx/html\u0026#34;: \u0026#34;${workspaceRoot}\u0026#34;, }, }, { \u0026#34;name\u0026#34;: \u0026#34;Launch currently open script\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;php\u0026#34;, \u0026#34;request\u0026#34;: \u0026#34;launch\u0026#34;, \u0026#34;program\u0026#34;: \u0026#34;${file}\u0026#34;, \u0026#34;cwd\u0026#34;: \u0026#34;${fileDirname}\u0026#34;, \u0026#34;port\u0026#34;: 9000 } ] } 安装 Chrome 插件\r安装 Xdebug Helper 插件以便于调试\n一键安装\r在 server_init 中 安装 PHP 8.2.sh\nyum install -y epel-release yum-utils yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum install -y php82 php82-php-devel php82-php-fpm php82-php-gd php82-php-json php82-php-mbstring php82-php-mysqlnd php82-php-xml php82-php-xmlrpc php82-php-opcache php82-php-mcrypt php82-php-sodium php82-php-pgsql GraphicsMagick sed -i \u0026#39;11a\\ExecStartPre=/bin/mkdir -p /var/run/php-fpm/\u0026#39; /usr/lib/systemd/system/php82-php-fpm.service export PHP_WWW=\u0026#34;/etc/opt/remi/php82/php-fpm.d/www.conf\u0026#34; sed -i \u0026#39;s/user =.*/user = nginx/g\u0026#39; $PHP_WWW sed -i \u0026#39;s/group =.*/group = nginx/g\u0026#39; $PHP_WWW sed -i \u0026#39;s/listen =.*/listen = \\/var\\/run\\/php-fpm\\/php-fpm.sock/g\u0026#39; $PHP_WWW sed -i \u0026#39;s/;listen.owner =.*/listen.owner = nginx/g\u0026#39; $PHP_WWW sed -i \u0026#39;s/;listen.group =.*/listen.group = nginx/g\u0026#39; $PHP_WWW export PHP_INI=\u0026#34;/etc/opt/remi/php82/php.ini\u0026#34; sed -i -e \u0026#34;s|expose_php = On|expose_php = Off|\u0026#34; $PHP_INI sed -i -e \u0026#34;s|short_open_tag = Off|short_open_tag = On|\u0026#34; $PHP_INI chown -R nginx:nginx /var/opt/remi/php82/lib/php systemctl enable php82-php-fpm systemctl restart php82-php-fpm 原文\nunable to install php-devel on CentOS 8\nHow to install PHP 7.2 on CentOS 7/RHEL 7\nCento7にphp-fpmをインストールし、nginxと連携する\n","date":"2019-07-08T13:41:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-install-php-7.4-via-yum/","title":"CentOS 7 通过 yum 安装 PHP 7.4"},{"content":"对于新的服务器, 如果没有特殊需求, 可以直接通过 yum 包管理器安装 Nginx, 而不必进行编译安装\n安装 yum-utils\r在安装 Nginx 之前, 确保系统中安装了 yum-utils 工具\nyum install yum-utils 设置 Nginx 仓库\r编辑 /etc/yum.repos.d/nginx.repo 文件, 添加以下内容\n[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key 默认情况下, 会使用 nginx-stable 仓库。如果想使用最新版本的 Nginx, 可以切换到 nginx-mainline 仓库 (可选)\nyum-config-manager --enable nginx-mainline 安装 Nginx\r设置好仓库后, 运行以下命令来安装 Nginx\nyum install nginx 一键安装\r在 server_init 中 安装 nginx.sh\ncat\u0026gt;\u0026gt;/etc/yum.repos.d/nginx.repo\u0026lt;\u0026lt;\\EOF [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key EOF yum install nginx -y nginx -V systemctl enable nginx systemctl start nginx 原文\nnginx: Linux packages\n","date":"2019-07-07T13:33:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-install-latest-stable-nginx-version-via-yum/","title":"CentOS 7 通过 yum 安装最新 stable 版本 Nginx"},{"content":"Let’s Encrypt 提供免费的 SSL 证书, 支持自动续期。对于 Windows 用户, 使用 win-acme (前身为 letsencrypt-win-simple) 可以方便地在 Windows 上申请和管理 SSL 证书。以下是使用 win-acme 安装并配置自动续费的步骤。\n下载 win-acme\r下载地址: github.com/PKISharp/win-acme\n解压文件, 目录结构如下\n安装 .NET Framework 4.7.2\r确保系统已经安装了 .NET Framework 4.7.2, 如果没有安装, 可以在 Microsoft官网 下载并安装\n运行 win-acme\r打开解压后的目录, 在命令提示符 (cmd) 下进入该目录\n输入 letsencrypt.exe --san (或者直接双击 letsencrypt.exe) 启动程序\nN: Create new certificate // 创建新证书 M: Create new certificate with advanced options // 使用高级选项创建新证书 L: List scheduled renewals // 查看已安排的续期 R: Renew scheduled // 续期单个证书 S: Renew specific // 续期多个证书 A: Renew *all* // 全部续期 V: Revoke certificate // 撤销证书 C: Cancel scheduled renewal // 取消某个续期任务 X: Cancel *all* scheduled renewals // 取消全部续期任务 Q: Quit 选择 N 创建新的证书, 根据提示输入必要信息\n选择证书类型：根据自己的需求选择 IIS 单站点绑定 或其他 选择证书使用的域名 同意协议, 会提示查看并同意 Let’s Encrypt 的使用协议\n配置自动续期：可以选择 L 查看自动续期设置, 确保启用了自动续期功能\n配置证书续期\rwin-acme 默认会自动配置证书的续期。你可以通过选择 L 查看当前的续期计划, 或手动添加新的续期任务\n原文\nWindows下IIS安装SSL证书并自动续期\n","date":"2019-06-22T14:56:20+08:00","permalink":"https://blog.acesheep.com/p/windows-install-and-auto-renew-ssl-certificate-on-iis/","title":"Windows 在 IIS 上安装 SSL 证书并自动续期"},{"content":"IDA 仍然是一个 32 位的应用程序, 因此在 64 位的 Ubuntu 上运行时需要安装一些 32 位的库。以下是安装步骤\n软件文件\r软件名称: IDA_Pro_v6.4_(Linux)_and_Hex-Rays_Decompiler_(ARM).zip\n此处不提供下载地址\n安装 32 位库\r添加 32 位架构支持\rsudo dpkg --add-architecture i386 sudo apt-get update 安装所需的 32 位库\rsudo apt-get install libc6-i686:i386 libexpat1:i386 libffi6:i386 libfontconfig1:i386 libfreetype6:i386 libgcc1:i386 libglib2.0-0:i386 libice6:i386 libpcre3:i386 libsm6:i386 libstdc++6:i386 libuuid1:i386 libx11-6:i386 libxau6:i386 libxcb1:i386 libxdmcp6:i386 libxext6:i386 libxrender1:i386 zlib1g:i386 libx11-xcb1:i386 libdbus-1-3:i386 libxi6:i386 libsm6:i386 libcurl3:i386 安装 libstdc++5\r如果在命令行中运行 ./idaq 运行 IDA 时遇到提示找不到 libstdc++.so.5, 可以通过以下命令安装\nsudo apt-get install libstdc++5:i386 注意: i386 后缀是必不可少的\n运行 IDA\r完成上述步骤后, 在命令行中运行以下命令启动 IDA\n./idaq 至此, IDA Pro 应该在 Ubuntu 系统上成功安装并能够正常运行\n原文\nUbuntu下安装IDA pro\nInstalling IDA 6.9 on Linux\nInstalling IDA 6.9 on Linux 作者新域名\n","date":"2019-06-22T14:37:32+08:00","permalink":"https://blog.acesheep.com/p/ubuntu-64bit-install-ida-pro-6.4/","title":"Ubuntu 64 位安装 IDA Pro 6.4"},{"content":"jQuery 选择器大全\r基本选择器\r$(\u0026#34;#myELement\u0026#34;) // 选择 id 值等于 myElement 的元素, id 值不能重复在文档中只能有一个 id 值是myElement 所以得到的是唯一的元素 $(\u0026#34;div\u0026#34;) // 选择所有的 div 标签元素, 返回 div 元素数组 $(\u0026#34;.myClass\u0026#34;) // 选择所有使用 myClass 类的 css 元素 $(\u0026#34;*\u0026#34;) // 选择文档中的所有的元素 // 可以运用多种的选择方式进行联合选择, 例如 $(\u0026#34;#myELement,div,.myclass\u0026#34;) 后代选择与兄弟选择\r$(\u0026#34;A B\u0026#34;) // 查找 A 元素下面的所有子元素, 包括非直接子元素 $(\u0026#34;A \u0026gt; B\u0026#34;) // 查找 A 元素下面的直接子元素 $(\u0026#34;A + B\u0026#34;) // 查找 A 元素后面的第一个兄弟元素, 包括非直接子元素 $(\u0026#34;A ~ B\u0026#34;) // 查找 A 元素后面的所有兄弟元素, 不包括非直接子元素 层叠选择器\r$(\u0026#34;form input\u0026#34;) // 选择所有的 form 元素中的 input 元素 $(\u0026#34;#main \u0026gt; *\u0026#34;) // 选择 id 值为 main 的所有的子元素 $(\u0026#34;label + input\u0026#34;) // 选择所有的 label 元素后的下一个 input 元素节点。经测试选择器返回的是 label 标签后面直接跟一个 input 标签的所有 input 标签元素 $(\u0026#34;#prev ~ div\u0026#34;) // 同胞选择器, 返回的为 id 为 prev 的标签元素的所有的属于同一个父元素的 div 标签 // 过滤掉已选中的 input 元素, 选择所有未选中的 input 元素后紧跟的 span 元素 $(\u0026#34;input:not(:checked) + span\u0026#34;) 基本过滤选择器\r$(\u0026#34;tr:first\u0026#34;) // 选择所有 tr 元素的第一个 $(\u0026#34;tr:last\u0026#34;) // 选择所有 tr 元素的最后一个 $(\u0026#34;tr:even\u0026#34;) // 选择所有的 tr 元素中偶数序号的元素 (第 0, 2, 4...个元素, 因为所选择的多个元素时为数组, 所以序号是从 0 开始) $(\u0026#34;tr:odd\u0026#34;) // 选择所有的 tr 元素中奇数序号的元素 (第 1, 3, 5...个元素) $(\u0026#34;td:eq(2)\u0026#34;) // 选择所有的 td 元素中序号为 2 的那个 td 元素 $(\u0026#34;td:gt(4)\u0026#34;) // 选择 td 元素中序号大于 4 的所有 td 元素 $(\u0026#34;td:ll(4)\u0026#34;) // 选择 td 元素中序号小于 4 的所有 td 元素 $(\u0026#34;:header\u0026#34;) // 选择所有标题元素 (h1 至 h6) $(\u0026#34;div:animated\u0026#34;) // 选择所有当前正在执行动画的 div 元素 内容过滤选择器\r$(\u0026#34;div:contains(\u0026#39;John\u0026#39;)\u0026#34;) // 选择所有 div 中含有 \u0026#39;John\u0026#39; 文本的元素 $(\u0026#34;td:empty\u0026#34;) // 选择所有的为空 (也不包括文本节点) 的 td 元素的数组 $(\u0026#34;div:has(p)\u0026#34;) // 选择所有含有 p 标签的 div 元素 $(\u0026#34;td:parent\u0026#34;) // 选择所有的以 td 为父节点的元素数组 可视化过滤选择器\r$(\u0026#34;div:hidden\u0026#34;) // 选择所有被隐藏的 div 元素 $(\u0026#34;div:visible\u0026#34;) // 选择所有可见的 div 元素 属性过滤选择器\r$(\u0026#34;div[id]\u0026#34;) // 选择所有含有 id 属性的 div 元素 $(\u0026#34;input[name=\u0026#39;newsletter\u0026#39;]\u0026#34;) // 选择所有的 name 属性等于 \u0026#39;newsletter\u0026#39; 的 input 元素 $(\u0026#34;input[name!=\u0026#39;newsletter\u0026#39;]\u0026#34;) // 选择所有的 name 属性不等于 \u0026#39;newsletter\u0026#39; 的 input 元素 $(\u0026#34;input[name^=\u0026#39;news\u0026#39;]\u0026#34;) // 选择所有的 name 属性以 \u0026#39;news\u0026#39; 开头的 input 元素 $(\u0026#34;input[name$=\u0026#39;news\u0026#39;]\u0026#34;) // 选择所有的 name 属性以 \u0026#39;news\u0026#39; 结尾的 input 元素 $(\u0026#34;input[name*=\u0026#39;man\u0026#39;]\u0026#34;) // 选择所有的 name 属性包含 \u0026#39;news\u0026#39; 的 input 元素 // 可以使用多个属性进行联合选择 // 选择所有具有 id 属性且 name 属性以 \u0026#39;man\u0026#39; 结尾的元素 $(\u0026#34;input[id][name$=\u0026#39;man\u0026#39;]\u0026#34;) 子元素过滤选择器\r$(\u0026#34;ul li:nth-child(2)\u0026#34;) // 选择 ul 中的第 2 个 li 子元素 $(\u0026#34;ul li:nth-child(odd)\u0026#34;) // 选择所有 ul 中奇数序号的 li 子元素 $(\u0026#34;ul li:nth-child(3n + 1)\u0026#34;) // 选择所有 ul 中序号为 3 的倍数加 1 的 li 子元素 $(\u0026#34;div span:first-child\u0026#34;) // 选择所有 div 元素的第一个 span 子元素 $(\u0026#34;div span:last-child\u0026#34;) // 选择所有 div 元素的最后一个 span 子元素 $(\u0026#34;div button:only-child\u0026#34;) // 选择所有 div 中唯一的 button 子元素 表单元素选择器\rHTML 例子\n\u0026lt;body\u0026gt; \u0026lt;!-- :input 选择所有表单输入元素 --\u0026gt; \u0026lt;form\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; name=\u0026#34;username\u0026#34; placeholder=\u0026#34;Username\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;password\u0026#34; name=\u0026#34;password\u0026#34; placeholder=\u0026#34;Password\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;gender\u0026#34; value=\u0026#34;male\u0026#34;\u0026gt; Male \u0026lt;input type=\u0026#34;radio\u0026#34; name=\u0026#34;gender\u0026#34; value=\u0026#34;female\u0026#34;\u0026gt; Female \u0026lt;input type=\u0026#34;checkbox\u0026#34; name=\u0026#34;subscribe\u0026#34; value=\u0026#34;yes\u0026#34;\u0026gt; Subscribe \u0026lt;input type=\u0026#34;submit\u0026#34; value=\u0026#34;Submit\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;reset\u0026#34; value=\u0026#34;Reset\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;image\u0026#34; src=\u0026#34;submit.png\u0026#34; alt=\u0026#34;Submit\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;file\u0026#34; name=\u0026#34;fileUpload\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;hidden\u0026#34; name=\u0026#34;hiddenField\u0026#34; value=\u0026#34;hiddenValue\u0026#34;\u0026gt; \u0026lt;textarea name=\u0026#34;message\u0026#34; placeholder=\u0026#34;Your message\u0026#34;\u0026gt;\u0026lt;/textarea\u0026gt; \u0026lt;select name=\u0026#34;options\u0026#34;\u0026gt; \u0026lt;option value=\u0026#34;option1\u0026#34;\u0026gt;Option 1\u0026lt;/option\u0026gt; \u0026lt;option value=\u0026#34;option2\u0026#34;\u0026gt;Option 2\u0026lt;/option\u0026gt; \u0026lt;/select\u0026gt; \u0026lt;button type=\u0026#34;button\u0026#34;\u0026gt;Click Me\u0026lt;/button\u0026gt; \u0026lt;/form\u0026gt; \u0026lt;/body\u0026gt; 选择器\n$(\u0026#34;:input\u0026#34;) // 选择所有表单输入元素, 包括 input、textarea、select 和 button $(\u0026#34;:text\u0026#34;) // 选择所有 text 类型的 input 元素 $(\u0026#34;:password\u0026#34;) // 选择所有 password 类型的 input 元素 $(\u0026#34;:radio\u0026#34;) // 选择所有 radio 类型的 input 元素 $(\u0026#34;:checkbox\u0026#34;) // 选择所有 checkbox 类型的 input 元素 $(\u0026#34;:submit\u0026#34;) // 选择所有 submit 类型的 input 元素 $(\u0026#34;:image\u0026#34;) // 选择所有 image 类型的 input 元素 $(\u0026#34;:reset\u0026#34;) // 选择所有 reset 类型的 input 元素 $(\u0026#34;:button\u0026#34;) // 选择所有 button 类型的 input 元素 $(\u0026#34;:file\u0026#34;) // 选择所有 file 类型的 input 元素 $(\u0026#34;:hidden\u0026#34;) // 选择所有类型为 hidden 的 input 元素 表单元素过滤选择器\r$(\u0026#34;:enabled\u0026#34;) // 选择所有可操作的表单元素 $(\u0026#34;:disabled\u0026#34;) // 选择所有不可操作的表单元素 $(\u0026#34;:checked\u0026#34;) // 选择所有已选中的表单元素 // 选择所有的 select 元素中被选中的 option 子元素, 用户在下拉列表中选择的选项 $(\u0026#34;select option:selected\u0026#34;) 常见选取示例\r// 选取 name 为 \u0026#39;S_03_22\u0026#39; 的 input 元素的上一个 td 元素的文本值 $(\u0026#34;input[name=\u0026#39;S_03_22\u0026#39;]\u0026#34;).parent().prev().text() // 选取名字以 \u0026#34;S_\u0026#34; 开头, 且不以 \u0026#34;_R\u0026#34; 结尾的 input 元素 $(\u0026#34;input[name^=\u0026#39;S_\u0026#39;]\u0026#34;).not(\u0026#34;[name$=\u0026#39;_R\u0026#39;]\u0026#34;) // 获取名为 radio_01 的 radio 按钮选中的值 $(\u0026#34;input[name=\u0026#39;radio_01\u0026#39;][checked]\u0026#34;).val() 原文\nJquery如何选取元素及其所有子元素？jquery选择器大全\n","date":"2019-06-05T02:17:00+08:00","permalink":"https://blog.acesheep.com/p/jquery-select-element-and-all-its-child-elements/","title":"jQuery 选择元素及其所有子元素"},{"content":"3proxy 是一个俄罗斯人编写强大的跨平台代理软件, 支持多种协议。当前的稳定版本为 0.8.12, 开发版本为 0.9b-devel\n官网: 3proxy.ru\n项目地址: github.com/z3APA3A/3proxy\n配置文档: https://3proxy.ru/howtoe.asp\n支持网页协议文件传输协议 HTTP/HTTPS/FTP 代理 支持三个版本的套接字 SOCKSv4/SOCKSv4.5/SOCKSv5 (socks/socks.exe) 代理 支持邮件协议 POP3/SMTP 代理 支持即时通讯协议 AIM/ICQ (icqpr/icqpr.exe) 代理 支持 MSN 消息 / Live 消息代理 (msnpr/msnpr.exe) 支持 DNS 缓存 TCP/UDP 端口映射 安装步骤\rgit clone https://github.com/z3apa3a/3proxy cd 3proxy ln -s Makefile.Linux Makefile make make install 配置用户\r使用脚本 /etc/3proxy/add3proxyuser.sh\nbash /etc/3proxy/add3proxyuser.sh admin 123456 配置示例\r配置文件路径: /usr/local/3proxy/conf/3proxy.cfg\n################################# #### http\u0026amp;https proxy setting ################################# auth none # deny 禁止访问服务器本地 deny * * 127.0.0.1,192.168.1.1 # 允许 HTTP 和 HTTPS 流量 allow * * * 80-88,8080-8088 HTTP allow * * * 443,8443 HTTPS # 这里使用默认端口 3128 proxy -n ################################# #### socks4/4.5/5 proxy setting ################################# auth strong flush # 允许所有你配置的用户连接, 注意这里并不是不认证 allow * # 设置最大连接数为 20 maxconn 20 # 这里手动指定端口 1081 socks -p1081 可以看到刚才配置的代理端口 1081, 3128 处于监听状态\n客户端只要进行相应配置就可以\n172.26.64.82:3128 类型 HTTP/HTTPS 无密码 172.26.64.82:1081 类型 SOCKS4/5 有密码, user1/pass1, user2/pass2 启动与停止 3proxy\r启动\nservice 3proxy start 停止\npkill 3proxy # or killall 3proxy 查看监听端口状态\rnetstat -tunlp | grep 1081 示例配置\r权限管理, How to limit user access to resources\nallow \u0026lt;userlist\u0026gt; \u0026lt;sourcelist\u0026gt; \u0026lt;targetlist\u0026gt; \u0026lt;targetportlist\u0026gt; \u0026lt;commandlist\u0026gt; \u0026lt;weekdaylist\u0026gt; \u0026lt;timeperiodlist\u0026gt; deny \u0026lt;userlist\u0026gt; \u0026lt;sourcelist\u0026gt; \u0026lt;targetlist\u0026gt; \u0026lt;weekdaylist\u0026gt; \u0026lt;timeperiodlist\u0026gt; flush 启用 Web UI\r开启 webUI 在 9999 端口\nnscache 65536 nserver 8.8.8.8 nserver 8.8.4.4 config /conf/3proxy.cfg monitor /conf/3proxy.cfg log /logs/3proxy-%y%m%d.log D rotate 60 counter /count/3proxy.3cf users $/conf/passwd include /conf/counters include /conf/bandlimiters auth strong deny * * 127.0.0.1 allow * socks -p223 flush allow admin admin -p9999 使用 IP 验证\r允许 IP 1.1.1.1, 1.2.2.0/24 访问代理\nnscache 65536 nserver 8.8.8.8 nserver 119.29.29.29 config /conf/3proxy.cfg monitor /conf/3proxy.cfg log /logs/3proxy-%y%m%d.log D rotate 60 counter /count/3proxy.3cf users $/conf/passwd include /conf/counters include /conf/bandlimiters auth iponly deny * * 127.0.0.1,192.168.1.0/24 allow * 1.1.1.1,1.2.2.0/24 proxy -p8080 -i192.168.1.100 flush auth strong allow admin admin -p9999 原文\n在win8.1上用3proxy搭建socks4/4.5/5代理\n","date":"2019-06-05T01:54:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-deploy-3proxy-socks5-proxy/","title":"CentOS 7 使用 3proxy 搭建 SOCKS5 代理"},{"content":"使用 pkill 命令替代 killall\r在某些精简系统版本 (如 Ubuntu 的 JeOS 版本) 中, 一些我们认为微不足道的命令都没有安装。通常还有一种我们不知道的替代方案 (例如用 vi 代替 nano)\n在这种情况下是使用 pkill 命令, 它也能通过进程名称向匹配的所有进程发送信号。例如\n# 原命令 killall badProcess # 等同于 pkill badProcess 安装 killall 命令\r如果你有足够的访问权限, 则可以安装 psmisc 软件包使用 killall, psmisc 还提供了一些其他有用的工具\npsmisc 包有以下几个有用的工具\nfuser: 显示进程使用的文件 killall: 按名称终止进程, 类似于 pkill pstree: 以树结构显示正在运行的进程 peekfd: 查看进程的文件描述符 在 Ubuntu/Debian 系统上安装\rapt-get install psmisc 在 RHEL/Fedora/CentOS 系统上安装\ryum install psmisc 原文\nbash: killall: command not found — A solution\n","date":"2019-06-05T01:33:00+08:00","permalink":"https://blog.acesheep.com/p/killall-command-not-found-in-bash/","title":"Bash 中没有找到 killall 命令"},{"content":"PHP 生成随机密码\r使用 PHP 开发应用程序, 尤其是网站程序, 常常需要生成随机密码, 如用户注册生成随机密码, 用户重置密码也需要生成一个随机的密码。随机密码也就是一串固定长度的字符串, 这里我收集整理了几种生成随机字符串的方法, 以供大家参考。\n通过预设字符集生成随机密码\r设置一个包含所需字符的字符串 $chars, 例如: a-z、A-Z、0-9 以及特殊字符 在 $chars 字符串中随机取一个字符 重复第二步 n 次, 可得长度为 n 的密码 function generate_password($length = 8) { // 密码字符集, 可任意添加你需要的字符 $chars = \u0026#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\u0026amp;*()-_ []{}\u0026lt;\u0026gt;~`+=,.;:/?|\u0026#39;; $password = \u0026#39;\u0026#39;; for ($i = 0; $i \u0026lt; $length; $i++) { // 这里提供两种字符获取方式 // 第一种是使用 substr 截取$chars中的任意一位字符； // 第二种是取字符数组 $chars 的任意元素 // $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); $password .= $chars[mt_rand(0, strlen($chars) - 1)]; } return $password; } 简化字符集生成随机密码\r我自己再用的\n设置包含部分字符的 $chars, 如: a-z 和 0-9 随机从 $chars 中选择字符构建密码 function genPassword($length = 8) { $chars = \u0026#39;abcdefghijklmnopqrstuvwxyz123456789\u0026#39;; $password = \u0026#39;\u0026#39;; for ($i = 0; $i \u0026lt; $length; $i++) { $password .= $chars[mt_rand(0, strlen($chars) - 1)]; } return $password; } 基于当前时间戳生成密码\r使用 time() 函数获取当前时间戳 将时间戳进行 md5 加密 截取加密后的字符串截取 n 位即得想要的密码 function get_password($length = 8) { $str = substr(md5(time()), 0, $length); return $str; } 性能测试\r使用微秒计时来比较不同随机密码生成方法的运行效率\nfunction getmicrotime() { list($usec, $sec) = explode(\u0026#34; \u0026#34;, microtime()); return ((float)$usec + (float)$sec); } // 记录开始时间 $time_start = getmicrotime(); // 这里放要执行的 PHP 代码 // echo generate_password(6); // 记录结束时间 $time_end = getmicrotime(); $time = $time_end - $time_start; // 输出执行时间 echo \u0026#34;执行时间 $time seconds\u0026#34;; 原文\nPHP生成随机密码的4种方法及性能对比\n","date":"2019-06-05T01:23:00+08:00","permalink":"https://blog.acesheep.com/p/php-generate-random-password/","title":"PHP 生成随机密码"},{"content":"IPv4 和 IPv6 地址的字符串长度\rIPv4 地址: 最大长度为 15 个字符\nIPv6 地址: 最大长度为 63 个字符\nIPv4 采用 32 位地址长度 xxx.xxx.xxx.xxx IPv6 采用 128 位地址长度 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF PHP 获取客户端真实 IP 地址\r方法一\r通过 HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR 获取客户端 IP, 并过滤私有 IP 地址\nfunction get_real_ip() { $ip = false; if (!empty($_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;])) { $ip = $_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;]; } if (!empty($_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;])) { $ips = explode(\u0026#39;, \u0026#39;, $_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;]); if ($ip) { array_unshift($ips, $ip); $ip = false; } for ($i = 0; $i \u0026lt; count($ips); $i++) { if (!preg_match(\u0026#39;/^(10|172.16|192.168)./\u0026#39;, $ips[$i])) { $ip = $ips[$i]; break; } } } return ($ip ? $ip : $_SERVER[\u0026#39;REMOTE_ADDR\u0026#39;]); } 方法二\r通过不同的服务器变量获取 IP 地址 (HTTP_X_FORWARDED_FOR、HTTP_CLIENT_IP、REMOTE_ADDR)\nfunction get_real_ip() { static $realip; if (isset($_SERVER)) { if (isset($_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;])) { $realip = $_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;]; } elseif (isset($_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;])) { $realip = $_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;]; } else { $realip = $_SERVER[\u0026#39;REMOTE_ADDR\u0026#39;]; } } else { if (getenv(\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;)) { $realip = getenv(\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;); } else if (getenv(\u0026#39;HTTP_CLIENT_IP\u0026#39;)) { $realip = getenv(\u0026#39;HTTP_CLIENT_IP\u0026#39;); } else { $realip = getenv(\u0026#39;REMOTE_ADDR\u0026#39;); } } return $realip; } 方法三\rDiscuz 代码示例, 通过 is_ip 函数判断 IP 是否有效\nfunction getIp() { $ip = \u0026#39;未知IP\u0026#39;; if (!empty($_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;])) { return is_ip($_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;]) ? $_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;] : $ip; } elseif (!empty($_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;])) { return is_ip($_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;]) ? $_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;] : $ip; } else { return is_ip($_SERVER[\u0026#39;REMOTE_ADDR\u0026#39;]) ? $_SERVER[\u0026#39;REMOTE_ADDR\u0026#39;] : $ip; } } function is_ip($str) { $ip = explode(\u0026#39;.\u0026#39;, $str); for ($i = 0; $i \u0026lt; count($ip); $i++) { if ($ip[$i] \u0026gt; 255) { return false; } } return preg_match(\u0026#39;/^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$/\u0026#39;, $str); } 方法四\r我目前在使用的\nfunction getRealIp() { static $realip; if (isset($_SERVER)) { if (isset($_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;])) { $realip = $_SERVER[\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;]; } else if (isset($_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;])) { $realip = $_SERVER[\u0026#39;HTTP_CLIENT_IP\u0026#39;]; } else { $realip = $_SERVER[\u0026#39;REMOTE_ADDR\u0026#39;]; } } else { if (getenv(\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;)) { $realip = getenv(\u0026#39;HTTP_X_FORWARDED_FOR\u0026#39;); } else if (getenv(\u0026#39;HTTP_CLIENT_IP\u0026#39;)) { $realip = getenv(\u0026#39;HTTP_CLIENT_IP\u0026#39;); } else { $realip = getenv(\u0026#39;REMOTE_ADDR\u0026#39;); } } if (filter_var($realip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE)) { return $realip; } elseif (filter_var($realip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return $realip; } else { return -1; } } 判断 IP 是否为有效 IP 地址\rPHP 自带的 filter_var 函数可用于 IP 地址有效性验证, 以下为几种验证方式\n判断是否为合法 IP 地址\rif (filter_var($ip, FILTER_VALIDATE_IP)) { // 是合法 IP } else { // 不是合法 IP } 判断是否为合法 IPv4 地址\rif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { // 是合法 IPv4 } else { // 不是合法 IPv4 地址 } 判断是否为公共 IPv4 地址 (排除私有 IP 地址)\r192.168.1.1 这类的私有IP地址将会排除在外\nif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE)) { // 是公共 IPv4 地址 } else { // 不是合法 IPv4 地址 } 判断是否为合法 IPv6 地址\rif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)) { // 是合法 IPv6 地址 } else { // 不是合法 IPv6 地址 } 判断是否为公共 IPv4 或 IPv6 地址\rif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { // 是公共 IP 地址 } else { // 不是公共 IP } 判断客户端连接的 IP 版本 (IPv4/IPv6)\r可以通过检查 IP 地址字符串中是否包含 : 符号来区分 IPv4 和 IPv6\nfunction ipVersion($txt) { return strpos($txt, \u0026#34;:\u0026#34;) === false ? 4 : 6; } 原文\nphp获取客户端真实ip地址的三种方法\nphp如何判断IP为有效IP地址\nphp – 如何检查是否有人通过IPv6/IPv4连接\nHow to know which version of the Internet Protocol (IP) a client is using when connecting to my server?\nIpv4和Ipv6的地址字符串长度\n一个完整的IPv6显示在TextBox里面, 它到底占用多少个字符？\n","date":"2019-06-05T00:50:00+08:00","permalink":"https://blog.acesheep.com/p/php-get-clients-real-ip-validate-and-detect-ipv4-ipv6/","title":"PHP 获取客户端真实 IP"},{"content":"下面这个文本是经过 HTML 编码的文本, 表示的是一些汉字的 Unicode 编码。在 HTML 中使用 Unicode 编码可以用 \u0026amp;# 后跟 Unicode 码点的十进制值来表示特定字符。HTML 中的 \u0026amp;# 编码 (称为字符实体)\n# 发邀请区版规 \u0026amp;#21457;\u0026amp;#36992;\u0026amp;#21306;\u0026amp;#29256;\u0026amp;#35268; UTF-16 与 UCS-2 的区别\rUCS-2 和 UTF-16 都是 Unicode 的字符编码\nUnicode 介绍\rUnicode 通过明确的名称和称其为代码点的整数来识别字符。例如, © 字符被命名为 \u0026ldquo;copyright sign\u0026rdquo;, 其码位为 U+00A9 (0xA9 , 十进制为 169)\nUnicode 代码空间分为 17 个平面 (plane), 每个平面有 2^16 (65,536) 个码位 (code point)。\n第一个 Unicode 平面 (码位从 U+0000 至 U+FFFF) 包含了最常用的字符, 该平面被称为基本多文种平面 (Basic Multilingual Plane), 缩写为 BMP。其他平面称为辅助平面 (Supplementary Planes)\n只需要记住, 有 BMP 字符和非 BMP 字符, 后者也称为补充字符或星体字符。\nUCS-2\rUCS-2 (2-byte Universal Character Set) 是固定长度编码方式, UCS-2 仅简单的使用一个 16 位代码单元来表示码位, 也就是 0 到 0xFFFF 码位范围内 (即 BMP), 它和 UTF-16 基本一致\n不能正确处理 emoji (4 字节字符), 因为它依赖于 UCS-2 编码, 这种编码方式不支持 3 字节及以上的字符\nUTF-16\rUTF-16 (16-bit Unicode Transformation Format) 是 UCS-2 的拓展, 它产生一个可变长度结果。它可以表示 BMP 以外的字符。UTF-16 使用一个或者两个 16 位的码元来表示码位, 这样就可以从 0 到 0x10FFFF 范围内的码位进行编码\n简单的说, UTF-16 可看成是 UCS-2 的父集。在没有辅助平面字符 (surrogate code points) 前, UTF-16 与 UCS-2 所指的是同一的意思。(严格的说这并不正确, 因为在 UTF-16 中从 U+D800 到 U+DFFF 的码位不对应于任何字符, 而在使用 UCS-2 的时代, U+D800 到 U+DFFF 内的值被占用) 但当引入辅助平面字符后, 就称为 UTF-16 了。\nUnicode 编码函数\r此函数将原始中文字符串 (支持指定编码) 转换为 Unicode 编码字符串, 格式为指定前缀和后缀 (默认为 \u0026amp;# 和 ;), 可用于显示特殊字符或多语言场景下的 Unicode 表示\nGBK 转 HTML 实体\r假设所有字符都在基本多文种平面 (BMP) 内, 即每个字符正好占用两个字节, 而无需考虑代理对\n使用 UCS-2BE, 保证字符按大端序编码 (big-endian)。这将确保每个字符的高位字节在前、低位字节在后, 与 Unicode 码点顺序一致\n/** * $str 原始中文字符串 * $encoding 原始字符串的编码, 默认 GBK * $prefix 编码后的前缀, 默认 \u0026#34;\u0026amp;#\u0026#34; * $postfix 编码后的后缀, 默认 \u0026#34;;\u0026#34; */ function unicode_encode($str, $encoding = \u0026#39;GBK\u0026#39;, $prefix = \u0026#39;\u0026amp;#\u0026#39;, $postfix = \u0026#39;;\u0026#39;) { $str = iconv($encoding, \u0026#39;UCS-2BE\u0026#39;, $str); $arrstr = str_split($str, 2); $unistr = \u0026#39;\u0026#39;; for ($i = 0, $len = count($arrstr); $i \u0026lt; $len; $i++) { $dec = hexdec(bin2hex($arrstr[$i])); $unistr .= $prefix . $dec . $postfix; } return $unistr; } 这段代码会将字符串转换为 UCS-2BE 编码, 但 UCS-2BE 是一个 2 字节编码, 只适用于基本的多语言平面 (BMP) 字符。它 无法正确处理 3 字节或 4 字节的 UTF-8 字符, 如汉字 和 emoji (通常是 4 字节的 Unicode 字符)。因此, 任何 4 字节的字符 (比如 emoji) 在转换过程中会丢失或被错误编码。\nUTF-8 转 HTML 实体\r可以使用 mb_convert_encoding 将字符串转换为 HTML-ENTITIES 十进制编码\nfunction unicode_encode($str, $encoding = \u0026#39;UTF-8\u0026#39;) { // 使用 mb_convert_encoding 将 UTF-8 字符串转换为 HTML-ENTITIES $str = mb_convert_encoding($str, \u0026#39;HTML-ENTITIES\u0026#39;, $encoding); return $str; } 直接处理 UTF-8 字符\r当 mb_convert_encoding 函数不可用代替方案, 可能是因为 PHP 没有安装或启用 mbstring 扩展。你可以尝试另一种方法, 不依赖 mbstring\n不使用 mb_convert_encoding, 而是直接处理 UTF-8 编码的字符串, 将每个字符逐字节转换为十进制 Unicode 值\nfunction unicode_encode($str, $encoding = \u0026#39;UTF-8\u0026#39;, $prefix = \u0026#39;\u0026amp;#\u0026#39;, $postfix = \u0026#39;;\u0026#39;) { $str = iconv($encoding, \u0026#39;UTF-8\u0026#39;, $str); $unistr = \u0026#39;\u0026#39;; // 遍历每个 UTF-8 字符 for ($i = 0, $len = strlen($str); $i \u0026lt; $len; $i++) { $ord = ord($str[$i]); // 根据 UTF-8 编码的首字节判断字符字节长度 if ($ord \u0026lt; 128) { // 1字节字符 (ASCII) $unistr .= $prefix . $ord . $postfix; } elseif ($ord \u0026lt; 224) { // 2字节字符 $code = (($ord \u0026amp; 0x1F) \u0026lt;\u0026lt; 6) | (ord($str[++$i]) \u0026amp; 0x3F); $unistr .= $prefix . $code . $postfix; } elseif ($ord \u0026lt; 240) { // 3字节字符 $code = (($ord \u0026amp; 0x0F) \u0026lt;\u0026lt; 12) | ((ord($str[++$i]) \u0026amp; 0x3F) \u0026lt;\u0026lt; 6) | (ord($str[++$i]) \u0026amp; 0x3F); $unistr .= $prefix . $code . $postfix; } else { // 4字节字符 (不常见, 但包括一些 emoji 等) $code = (($ord \u0026amp; 0x07) \u0026lt;\u0026lt; 18) | ((ord($str[++$i]) \u0026amp; 0x3F) \u0026lt;\u0026lt; 12) | ((ord($str[++$i]) \u0026amp; 0x3F) \u0026lt;\u0026lt; 6) | (ord($str[++$i]) \u0026amp; 0x3F); $unistr .= $prefix . $code . $postfix; } } return $unistr; } 这个代码能够逐字节地解析 UTF-8 编码字符, 并根据字符的字节长度 (1 到 4 字节) 来确定如何解析它们。对于 4 字节字符 (如 emoji), 它使用正确的位运算将其转换为相应的 Unicode 编码。因此, 它能够处理包含 emoji 的字符串, 并输出正确的 Unicode 编码。\nemoji 字符通常是 UTF-8 编码的 4 字节字符, 代码能够识别并正确转换为 Unicode 编码。例如, 😍 (心形眼睛 emoji) 会被正确转换为 \u0026amp;#128525;\nUnicode 解码函数\rHTML 实体 转 GBK\r该函数将 Unicode 编码字符串 (带指定前后缀) 还原为指定编码的原始字符串。示例中的默认编码为 GBK\n/** * $str Unicode编码后的字符串 * $decoding 原始字符串的编码, 默认 GBK * $prefix 编码字符串的前缀, 默认 \u0026#34;\u0026amp;#\u0026#34; * $postfix 编码字符串的后缀, 默认 \u0026#34;;\u0026#34; */ function unicode_decode($unistr, $encoding = \u0026#39;GBK\u0026#39;, $prefix = \u0026#39;\u0026amp;#\u0026#39;, $postfix = \u0026#39;;\u0026#39;) { $arruni = explode($prefix, $unistr); $unistr = \u0026#39;\u0026#39;; for ($i = 1, $len = count($arruni); $i \u0026lt; $len; $i++) { if (strlen($postfix) \u0026gt; 0) { $arruni[$i] = substr($arruni[$i], 0, strlen($arruni[$i]) - strlen($postfix)); } $temp = intval($arruni[$i]); $unistr .= ($temp \u0026lt; 256) ? chr(0) . chr($temp) : chr($temp / 256) . chr($temp % 256); } return iconv(\u0026#39;UCS-2BE\u0026#39;, $encoding, $unistr); } HTML 实体 转 UTF-8\r要将通过 unicode_encode 编码后的 Unicode 编码字符串解码回原始的字符 (包括 emoji), 可以通过解析这些 Unicode 编码并将它们转换回相应的字符\nfunction unicode_decode($str, $encoding = \u0026#39;UTF-8\u0026#39;) { $str = mb_convert_encoding($str, $encoding, \u0026#39;HTML-ENTITIES\u0026#39;); return $str; } 直接处理 UTF-8 字符\r不依赖 mb_convert_encoding\nfunction unicode_decode($str, $encoding = \u0026#39;UTF-8\u0026#39;, $prefix = \u0026#39;\u0026amp;#\u0026#39;, $postfix = \u0026#39;;\u0026#39;) { $pattern = \u0026#39;/\u0026#39; . preg_quote($prefix) . \u0026#39;(\\d+)\u0026#39; . preg_quote($postfix) . \u0026#39;/\u0026#39;; return preg_replace_callback($pattern, function ($matches) use ($encoding) { $code = intval($matches[1]); if ($code \u0026gt;= 0x10000) { // 对于大于 0xFFFF 的 Unicode 编码 (4 字节字符, 如 emoji) $code -= 0x10000; $highSurrogate = 0xD800 | ($code \u0026gt;\u0026gt; 10); $lowSurrogate = 0xDC00 | ($code \u0026amp; 0x3FF); $packed = pack(\u0026#39;v\u0026#39;, $highSurrogate) . pack(\u0026#39;v\u0026#39;, $lowSurrogate); return iconv(\u0026#39;UTF-16LE\u0026#39;, $encoding, $packed); } else { // 对于小于 0xFFFF 的 Unicode 字符 return iconv(\u0026#39;UCS-4LE\u0026#39;, $encoding, pack(\u0026#39;V\u0026#39;, $code)); } }, $str); } 其他实现\r实现更简洁, 专门针对 \u0026amp;#...; 格式的 Unicode 实体解码, 编码固定为 UTF-8\nfunction unicode_decode($unistr) { $arr = preg_split(\u0026#34;/(\u0026amp;#[0-9]*;)/\u0026#34;, $unistr, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); $restr = \u0026#39;\u0026#39;; foreach ($arr as $key =\u0026gt; $value) { if (strstr($value, \u0026#39;\u0026amp;#\u0026#39;)) { $unistr = \u0026#39;\u0026#39;; $arruni = explode(\u0026#39;\u0026amp;#\u0026#39;, $value); $arruni = substr($arruni[1], 0, strlen($arruni[1]) - 1); $temp = intval($arruni); $unistr .= ($temp \u0026lt; 256) ? chr(0) . chr($temp) : chr($temp / 256) . chr($temp % 256); $restr .= iconv(\u0026#39;UCS-2BE\u0026#39;, \u0026#39;UTF-8\u0026#39;, $unistr); } else { $restr .= $value; } } return $restr; } 测试\r源代码: example.php\nUTF-8 字符串测试\rheader(\u0026#39;Content-Type: text/html; charset=UTF-8\u0026#39;); function pr($data) { echo \u0026#39;\u0026lt;xmp\u0026gt;\u0026#39;; var_dump($data); echo \u0026#39;\u0026lt;/xmp\u0026gt;\u0026#39;; } $str = \u0026#39;哈哈😍\u0026#39;; pr($str); $unistr = unicode_encode($str); pr($unistr); $str2 = unicode_decode($unistr); pr($str2); 输出结果\nstring(10) \u0026#34;哈哈😍\u0026#34; string(25) \u0026#34;\u0026amp;#21704;\u0026amp;#21704;\u0026amp;#128525;\u0026#34; string(10) \u0026#34;哈哈😍\u0026#34; GBK 字符串测试\r注意: GBK 在 UTF-8 下显示的乱码！可以在 php 文件头加入 header()\nGBK 编码不支持 emoji\nheader(\u0026#39;Content-Type: text/html; charset=GBK\u0026#39;); $str = \u0026#39;哈哈\u0026#39;; pr($str); $unistr = unicode_encode($str); pr($unistr); $str2 = unicode_decode($unistr); pr($str2); $gbk_str = iconv(\u0026#39;UTF-8\u0026#39;, \u0026#39;GBK\u0026#39;, $str); pr($gbk_str); $gbk_unistr = unicode_encode($gbk_str, \u0026#39;GBK\u0026#39;); pr($gbk_unistr); $gbk_str2 = unicode_decode($gbk_unistr, \u0026#39;GBK\u0026#39;); pr($gbk_str2); 输出结果\nstring(6) \u0026#34;鍝堝搱\u0026#34; string(16) \u0026#34;\u0026amp;#21704;\u0026amp;#21704;\u0026#34; string(6) \u0026#34;鍝堝搱\u0026#34; string(4) \u0026#34;哈哈\u0026#34; string(16) \u0026#34;\u0026amp;#21704;\u0026amp;#21704;\u0026#34; string(4) \u0026#34;哈哈\u0026#34; 其它后缀、前缀测试\r$str = \u0026#39;哈哈😍\u0026#39;; pr($str); $prefix_unistr = unicode_encode($str, \u0026#39;UTF-8\u0026#39;, \u0026#34;\\\\u\u0026#34;, \u0026#39;\u0026#39;); pr($prefix_unistr); $profix_unistr2 = unicode_decode($prefix_unistr, \u0026#39;UTF-8\u0026#39;, \u0026#34;\\\\u\u0026#34;, \u0026#39;\u0026#39;); pr($profix_unistr2); 输出结果\nstring(10) \u0026#34;哈哈😍\u0026#34; string(22) \u0026#34;\\u21704\\u21704\\u128525\u0026#34; string(10) \u0026#34;哈哈😍\u0026#34; 原文\nphp 中文unicode 互转\nUTF-16与UCS-2的区别\nJavaScript 的内部字符编码：UCS-2 还是 UTF-16？\n在线字符统计：支持Unicode、URL、CSS实体、HTML实体、Base64 等编码/解码 - 工具 - CodePlayer\nPHP 在线工具 | 菜鸟工具\n","date":"2019-06-05T00:39:00+08:00","permalink":"https://blog.acesheep.com/p/php-string-and-html-entity-encoding-decoding/","title":"PHP 字符串与 HTML 实体编码解码"},{"content":"在 MySQL 数据库中清空表后重置自增主键 ID 从 1 开始, 可以使用 TRUNCATE 和 DELETE 语句\n清空表并重置主键自增ID\r要清空表并让自增主键 ID 从 1 开始计数, 通常可以使用 TRUNCATE 语句\nTRUNCATE TABLE tablename; TRUNCATE 会删除表中的所有数据, 同时重置表的自增主键 ID (如果存在的话) 从1开始自增。这是比 DELETE FROM 表名 更快捷的方式, 因为 TRUNCATE 不会逐行删除, 而是直接重置表结构。\n例子\r假设有一张用户表 users, 表结构如下\nCREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) ); 如果我们想清空 users 表中的所有数据并让 id 从1重新开始自增, 可以执行\nTRUNCATE TABLE users; 清空之后, 插入新的数据时, id 将从1重新开始\n使用 DELETE 语句并手动重置自增值\r在某些场景下, 如果不想使用 TRUNCATE, 可以使用 DELETE 语句清空表, 再手动重置自增主键 ID。这样可以更细粒度地控制删除操作。\nDELETE FROM tablename; ALTER TABLE tablename AUTO_INCREMENT = 1; 这里的 ALTER TABLE ... AUTO_INCREMENT = 1 会将自增 ID 重置为1。DELETE 适合在表上有外键约束的情况, 因为 TRUNCATE 在有外键的情况下可能会报错。\n例子\rDELETE FROM users; ALTER TABLE users AUTO_INCREMENT = 1; TRUNCATE 和 DELETE 的区别\r比较项 TRUNCATE DELETE 执行速度 快速, 直接清空表和重置结构 较慢, 逐行删除 自增ID重置 自动重置 需要手动重置 触发器 不触发 AFTER DELETE 触发器 会触发 AFTER DELETE 触发器 外键约束 如果有外键约束可能会报错 可以在外键约束存在时执行 注意事项\nTRUNCATE 和 DELETE 操作都是数据不可恢复的操作, 务必在清空数据之前备份表数据\n如果表含有外键约束, 优先考虑 DELETE 语句, 或者临时禁用外键约束\n-- 1. 临时禁用外键约束 SET FOREIGN_KEY_CHECKS = 0; -- 2. 清空表并重置自增 ID TRUNCATE TABLE users; -- 3. 恢复外键约束 SET FOREIGN_KEY_CHECKS = 1; TRUNCATE 是隐式提交操作, 会立即生效并且无法回滚\n原文\nMySql数据库表清空后重置主键ID从1开始自增\n","date":"2019-06-05T00:34:00+08:00","permalink":"https://blog.acesheep.com/p/mysql-reset-auto-increment-id/","title":"MySQL 清空表数据后重置自增主键 ID 从 1 计数"},{"content":"VS Code 现在已经越来越完善。性能远超 Atom 和 webstorm, 你有什么理由不用它?\n在这里, 我会给你们推荐很多实用的插件, 让你对 vscode 有更深刻的体会, 渐渐地你就会知道它有多好用。\n走马观花前, 请先将你的 vscode 更新到最新版本\n基本插件\rHTML Snippets\r超级实用且初级的 H5代码片段以及提示\nHTML CSS Support\r让 html 标签上写class 智能提示当前项目所支持的样式\n新版已经支持scss文件检索\njQuery Code Snippets\rjquery 重度患者必须品\nvscode-icon\r让 vscode 资源树目录加上图标, 必备良品！\nPath Intellisense\r自动路劲补全, 默认不带这个功能的\nbeautify\r格式化代码的工具\nvscode-fileheader\r顶部注释模板, 可定义作者、时间等信息, 并会自动更新最后修改时间\nctrl+alt+i 按下快捷键插入顶部注释\nfilesize\r在底部状态栏显示当前文件大小, 点击后还可以看到详细创建、修改时间\nBracket Pair Colorizer\r让括号拥有独立的颜色, 易于区分。可以配合任意主题使用\n原文\nvscode 插件推荐 - 献给所有前端工程师（2018.4.29更新）\n","date":"2019-06-04T23:54:00+08:00","permalink":"https://blog.acesheep.com/p/recommended-vs-code-extensions/","title":"VS Code 插件推荐"},{"content":"起因, 新电脑安装完密码就忘了, 而且是本地账户无法通过网页重置密码. 不想重装系统重置密码\n在这种情况下可以通过 CMD 模式 (无需密码可进入) 重置开机密码, 并且保证数据原封不动。\n进入高级恢复模式\r在启动时长按 F8 键, 进入 Windows 高级恢复模式 选择 \u0026ldquo;Troubleshoot/疑难解答\u0026rdquo;, 然后进入 \u0026ldquo;Command Prompt/命令提示符\u0026rdquo; 备份并替换文件\rrem 备份 sethc.exe 文件 (粘贴键功能) copy c:\\windows\\system32\\sethc.exe c:\\ rem 将 sethc.exe 替换为 cmd.exe copy /y c:\\windows\\system32\\cmd.exe c:\\windows\\system32\\sethc.exe 重启并调用 CMD\r输入 exit , 然后按 Enter 键退出 CMD 窗口, 重启电脑 在登录界面时, 连续按 5 次 Shift 键, CMD 窗口将会弹出 设置新密码\r确保使用本地账户 (非 Microsoft 账户)\n例如, 将账户 student 的密码设置为 123456, 输入以下命令\nnet user student 123456 如忘记用户名\r查看当前系统中所有的用户组\nnet localgroup net localgroup 命令后面接上用户组名, 按回车键即可查看组中的用户\n查看 administrators 管理员用户组中的用户\nnet localgroup administrators 使用新密码登录\r退出 CMD 窗口, 使用新设置的密码登录\n整个过程中, 实际上是交换了 sethc.exe 和 cmd.exe 工具, sethc.exe 通常被用作激活粘贴键功能。但被我们用可以修改用户密码的 CMD 取而代之。尽管, 这种方法只适用于本地账户, 不能修改 Microsoft 账户。\n还原修改\r要恢复粘贴键功能, 需再次进入高级启动模式, 并在命令提示符中执行以下命令\ncopy /y c:\\sethc.exe c:\\windows\\system32\\sethc.exe 在登录界面重复按下 Shift 键, 将恢复为粘贴密钥提示\n原文\n跳过开机密码！修改 Windows 10 登录密码 :-)\nWin10如何查询用户组及组中用户？\n","date":"2019-05-13T18:19:00+08:00","permalink":"https://blog.acesheep.com/p/forgot-password-reset-windows-local-account-password/","title":"忘记密码重置 Windows 本地账户密码"},{"content":"WebDAV (Web-based Distributed Authoring and Versioning) 是一种基于 HTTP 1.1 协议的通信协议, 在GET、POST、HEAD等几个HTTP标准方法以外, 它扩展了 HTTP 1.1, 增加了支持写文件锁定 (Locking)、解锁 (Unlock) 等方法, 使应用程序可直接对 Web Server 直接读写。\nWebDAV 就是通过 Restful API , 实现对服务端文件的 创建 / 删除 / 读取 / 修改。与其他文件传输协议相比, WebDAV 使用 HTTP 传输, 不容易被当作不明流量被砍掉。支持 HTTPS 数据加密, 避免流量被阻断, 并支持 HTTP 2 和范围请求 (RFC7233)\n正是因为这些好处, 很多系统和软件都提供了对 WebDAV 的支持。比如说 OS X 的 finder 支持远程连接到 WebDAV 服务器。IOS 的播放器 nPlayer 能够播放 WebDAV 上的视频文件, 且传输速度高于 FTP / SMB 等协议。\n准备工作\r操作系统: CentOS 7.9.2009 (Core) Nginx 版本: 1.20.2 备用下载: nginx-1.20.2.tar.gz 模块支持 nginx-dav-ext-module 添加了 PROPFIND、OPTIONS、LOCK、UNLOCK 方法 版本: git.r112.f5e3088 (release-v3.0.0) headers-more-nginx-module 修复了 iOS、Windows 默认客户端在使用 COPY、MOVE 方法时, $http_destination 中的 URI 缺少 / 的问题, 导致出现无法删除、重命名文件或文件夹等错误家。该模块可以修复该错误, 兼容更多的客户端 版本: git.r259.a4a0686 (v0.33) 其他依赖: OpenSSL 1.1.1m (TLS 1.3 支持) Zlib 1.2.11 (Gzip 支持) PCRE 8.45 (正则表达式) GCC 9.3.1 20200408 (Red Hat 9.3.1-2) 安装编译环境\ryum install epel-release expat-devel httpd-tools unzip wget centos-release-scl git libxslt-devel libxml2-devel -y yum install devtoolset-9-gcc* -y yum groupinstall \u0026#34;Development tools\u0026#34; -y 创建非特权服务帐户\r创建一个与 EPEL 仓库中相同的 nginx 服务帐户\ngroupadd -g 994 nginx useradd -g 994 -u 996 -c \u0026#34;nginx user\u0026#34; -d /var/cache/nginx -s /sbin/nologin nginx 如果你得到下面的输出, 可以忽略此步骤。这只是意味着 nginx 用户已经或已经从仓库安装时创建\n[root@centos7 ~]# groupadd -g 994 nginx groupadd: group \u0026#39;nginx\u0026#39; already exists [root@centos7 ~]# useradd -g 994 -u 996 -c \u0026#34;Nginx web server\u0026#34; -d /var/lib/nginx -s /sbin/nologin nginx useradd: user \u0026#39;nginx\u0026#39; already exists 下载源码\r# 创建工作目录并进入 mkdir nginx-webdav cd nginx-webdav # download nginx 1.20.2 source wget wget https://nginx.org/download/nginx-1.20.2.tar.gz # download pcre 8.45 / zlib 1.2.11 / openssl 1.1.1m dependency wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz wget http://zlib.net/zlib-1.2.11.tar.gz wget http://www.openssl.org/source/openssl-1.1.1m.tar.gz # download nginx-dav-ext-module git.r112.f5e3088 git clone https://github.com/arut/nginx-dav-ext-module.git # download headers-more-nginx-module git.r259.a4a0686 git clone https://github.com/openresty/headers-more-nginx-module.git # Extract source file tar -zxf pcre-8.45.tar.gz tar -zxf zlib-1.2.11.tar.gz tar -zxf openssl-1.1.1m.tar.gz tar -zxf nginx-1.20.2.tar.gz 准备好的文件列表\r[root@centos7 nginx-webdav]# tree -L 1 ├── headers-more-nginx-module ├── nginx-1.20.2 ├── nginx-1.20.2.tar.gz ├── nginx-dav-ext-module ├── openssl-1.1.1m ├── openssl-1.1.1m.tar.gz ├── pcre-8.45 ├── pcre-8.45.tar.gz ├── zlib-1.2.11 └── zlib-1.2.11.tar.gz 6 directories, 4 files 编译安装 Nginx\r详细参数配置参数\n./configure \\ --prefix=/etc/nginx \\ --sbin-path=/usr/sbin/nginx \\ --modules-path=/usr/lib64/nginx/modules \\ --conf-path=/etc/nginx/nginx.conf \\ --error-log-path=/var/log/nginx/error.log \\ --http-log-path=/var/log/nginx/access.log \\ --pid-path=/var/run/nginx.pid \\ --lock-path=/var/run/nginx.lock \\ --http-client-body-temp-path=/var/cache/nginx/client_temp \\ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \\ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \\ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \\ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \\ --user=nginx \\ --group=nginx \\ --with-zlib=../zlib-1.2.11 \\ --with-zlib-opt=\u0026#39;-g -Ofast -fPIC -m64 -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2\u0026#39; \\ --with-pcre=../pcre-8.45 \\ --with-pcre-opt=\u0026#39;-g -Ofast -fPIC -m64 -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2\u0026#39; \\ --with-pcre-jit \\ --with-compat \\ --with-file-aio \\ --with-threads \\ --with-http_addition_module \\ --with-http_auth_request_module \\ --with-http_dav_module \\ --add-module=../nginx-dav-ext-module \\ --add-module=../headers-more-nginx-module \\ --with-openssl=../openssl-1.1.1m \\ --with-http_xslt_module \\ --with-http_flv_module \\ --with-http_gunzip_module \\ --with-http_gzip_static_module \\ --with-http_mp4_module \\ --with-http_random_index_module \\ --with-http_realip_module \\ --with-http_secure_link_module \\ --with-http_slice_module \\ --with-http_ssl_module \\ --with-http_stub_status_module \\ --with-http_sub_module \\ --with-http_v2_module \\ --with-mail \\ --with-mail_ssl_module \\ --with-stream \\ --with-stream_realip_module \\ --with-stream_ssl_module \\ --with-stream_ssl_preread_module \\ --with-cc-opt=\u0026#39;-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC\u0026#39; \\ --with-ld-opt=\u0026#39;-Wl,-z,relro -Wl,-z,now -pie\u0026#39; 调整文件名长度显示 (可选)\r实现网页目录不裁剪文件名\n修改 nginx-1.20.2/src/http/modules/ngx_http_autoindex_module.c\n#define NGX_HTTP_AUTOINDEX_PREALLOCATE 50 #define NGX_HTTP_AUTOINDEX_NAME_LEN 50 修改为\n#define NGX_HTTP_AUTOINDEX_PREALLOCATE 110 #define NGX_HTTP_AUTOINDEX_NAME_LEN 110 nginx: Long filenames in directory listing\nStop nginx from trimming file name in directory list?\n综上所述整理好的执行代码\r[root@centos7 nginx-webdav]# cd nginx-1.20.2 [root@centos7 nginx-1.20.2]# scl enable devtoolset-9 \u0026#34;./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-zlib=../zlib-1.2.11 --with-zlib-opt=\u0026#39;-g -Ofast -fPIC -m64 -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2\u0026#39; --with-pcre=../pcre-8.45 --with-pcre-opt=\u0026#39;-g -Ofast -fPIC -m64 -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2\u0026#39; --with-pcre-jit --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --add-module=../nginx-dav-ext-module --add-module=../headers-more-nginx-module --with-openssl=../openssl-1.1.1m --with-http_xslt_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt=\u0026#39;-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC\u0026#39; --with-ld-opt=\u0026#39;-Wl,-z,relro -Wl,-z,now -pie\u0026#39;\u0026#34; [root@centos7 nginx-1.20.2]# scl enable devtoolset-9 \u0026#34;make -j\u0026#34; [root@centos7 nginx-1.20.2]# ./objs/nginx -V nginx version: nginx/1.20.2 built by gcc 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC) built with OpenSSL 1.1.1m 14 Dec 2021 TLS SNI support enabled configure arguments: ...... [root@centos7 nginx-1.20.2]# make install 安装完检查 nginx 的版本 nginx -V\n[root@centos7 ~]# nginx -V nginx version: nginx/1.20.2 built by gcc 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC) built with OpenSSL 1.1.1m 14 Dec 2021 TLS SNI support enabled configure arguments: ...... 编译报错处理方法\robjs/ngx_modules.o \\ -Wl,-z,relro -Wl,-z,now -pie -ldl -lpthread -lpthread -lcrypt ../pcre-8.45/.libs/libpcre.a ../openssl-1.1.1m/.openssl/lib/libssl.a ../openssl-1.1.1m/.openssl/lib/libcrypto.a -ldl -lpthread ../zlib-1.2.11/libz.a -lxml2 -lxslt -lexslt \\ -Wl,-E /usr/bin/ld: ../pcre-8.45/.libs/libpcre.a(libpcre_la-pcre_compile.o): relocation R_X86_64_32S against hidden symbol `_pcre_OP_lengths\u0026#39; can not be used when making a shared object /usr/bin/ld: ../pcre-8.45/.libs/libpcre.a(libpcre_la-pcre_config.o): relocation R_X86_64_32S against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../pcre-8.45/.libs/libpcre.a(libpcre_la-pcre_exec.o): relocation R_X86_64_32S against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../pcre-8.45/.libs/libpcre.a(libpcre_la-pcre_fullinfo.o): relocation R_X86_64_32S against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../pcre-8.45/.libs/libpcre.a(libpcre_la-pcre_jit_compile.o): relocation R_X86_64_32S against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../pcre-8.45/.libs/libpcre.a(libpcre_la-pcre_study.o): relocation R_X86_64_32S against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../zlib-1.2.11/libz.a(deflate.o): relocation R_X86_64_32S against hidden symbol `_length_code\u0026#39; can not be used when making a shared object /usr/bin/ld: ../zlib-1.2.11/libz.a(inflate.o): relocation R_X86_64_32S against hidden symbol `zcfree\u0026#39; can not be used when making a shared object /usr/bin/ld: ../zlib-1.2.11/libz.a(inftrees.o): relocation R_X86_64_32 against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../zlib-1.2.11/libz.a(trees.o): relocation R_X86_64_32S against hidden symbol `_length_code\u0026#39; can not be used when making a shared object /usr/bin/ld: ../zlib-1.2.11/libz.a(zutil.o): relocation R_X86_64_32 against `.rodata.str1.1\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../zlib-1.2.11/libz.a(crc32.o): relocation R_X86_64_32S against `.rodata\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: ../zlib-1.2.11/libz.a(inffast.o): relocation R_X86_64_32S against `.rodata.str1.1\u0026#39; can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: error: ld returned 1 exit status make[1]: *** [objs/nginx] Error 1 make[1]: Leaving directory `../nginx-1.20.2\u0026#39; make: *** [build] Error 2 如果出现这个错误解决方法是在 ./configure 中加入两行参数\n--with-pcre-opt=\u0026#39;-g -Ofast -fPIC -m64 -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2\u0026#39; \\ --with-zlib-opt=\u0026#39;-g -Ofast -fPIC -m64 -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2\u0026#39; \\ libpcre throwing a \u0026ldquo;.rodata can not be used when making a shared object\u0026rdquo; error while compiling NGINX\n创建 Nginx 系统服务\r创建并编辑系统服务配置文件 /usr/lib/systemd/system/nginx.service\n[Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/sh -c \u0026#34;/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)\u0026#34; ExecStop=/bin/sh -c \u0026#34;/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)\u0026#34; [Install] WantedBy=multi-user.target 设置开机启动并启动 Nginx 服务\nsystemctl enable nginx systemctl start nginx 配置 Nginx\r站点目录\r创建站点目录\nmkdir /etc/nginx/conf.d 创建默认 nginx.conf\r修改文件 vim /etc/nginx/nginx.conf\nuser nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; # Specifies the value for maximum file descriptors that can be opened by this process. worker_rlimit_nofile 51200; # PCRE JIT can speed up processing of regular expressions significantly. pcre_jit on; events { use epoll; worker_connections 51200; multi_accept on; } http { log_format main \u0026#39;$remote_addr - $remote_user [$time_local] \u0026#34;$request\u0026#34; \u0026#39; \u0026#39;$status $body_bytes_sent \u0026#34;$http_referer\u0026#34; \u0026#39; \u0026#39;\u0026#34;$http_user_agent\u0026#34; \u0026#34;$http_x_forwarded_for\u0026#34;\u0026#39;; include /etc/nginx/mime.types; default_type application/octet-stream; server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 50m; charset utf-8; sendfile on; server_tokens off; tcp_nodelay on; tcp_nopush on; real_ip_header X-Forwarded-For; types_hash_max_size 2048; keepalive_timeout 60; access_log /var/log/nginx/access.log main; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 256k; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable \u0026#34;MSIE [1-6]\\.\u0026#34;; server { listen 80 default_server; listen [::]:80 default_server; if ($host ~ \u0026#34;\\d+\\.\\d+\\.\\d+\\.\\d+\u0026#34;) { return 404; } return 301 https://$host$request_uri; } include /etc/nginx/conf.d/*.conf; } WebDAV 账户管理\r使用 htpasswd 创建 WebDAV 访问账户\nyum install httpd-tools -y # 创建用户名为 rbq 的用户 htpasswd -c /home/SSL/webdav.htpasswd \u0026#39;rbq\u0026#39; 都配置完之后重启 nginx\nnginx -s reload 设置文件夹访问权限\rWebDAV 主目录在 /home 下访时, 需要调整权限\n将 nginx 用户加入 qaq 用户组, 并将 qaq 用户加入 nginx 组\n[root@centos7 ~]# id qaq uid=1000(qaq) gid=1000(qaq) groups=1000(qaq) [root@centos7 ~]# id nginx uid=996(nginx) gid=994(nginx) groups=994(nginx) [root@centos7 ~]# usermod -G qaq nginx [root@centos7 ~]# usermod -G nginx qaq [root@centos7 ~]# id nginx uid=996(nginx) gid=994(nginx) groups=994(nginx),1000(qaq) 修改文件夹权限为 774, 确保共享目录的读写权限\nchmod -R 774 /home/qaq 创建 WebDAV 站点\r修改文件 vim /etc/nginx/conf.d/webdav.conf\nserver { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com; ssl_certificate \u0026#34;/home/SSL/example.com.crt\u0026#34;; ssl_certificate_key \u0026#34;/home/SSL/example.com.key\u0026#34;; ssl_session_cache shared:SSL:20m; ssl_session_timeout 30m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES; ssl_prefer_server_ciphers on; access_log /var/log/nginx/access-example.com.log main; error_log /var/log/nginx/error-example.com.log error; location / { # 设置 webdav 目录, 注意 Nginx worker 用户对该目录需有读/写/执行权限 root /home/qaq; auth_basic \u0026#34;closed site\u0026#34;; auth_basic_user_file /home/SSL/webdav.htpasswd; dav_methods PUT DELETE MKCOL COPY MOVE; dav_ext_methods PROPFIND OPTIONS; # 启用完整的创建目录支持 create_full_put_path on; dav_access user:rw group:rw; autoindex on; autoindex_localtime on; autoindex_exact_size off; # 不限制文件大小 client_max_body_size 0; # 为各种方法的URI后加上斜杠, 解决各平台webdav客户端的兼容性问题 set $dest $http_destination; if (-d $request_filename) { rewrite ^(.*[^/])$ $1/; set $dest $dest/; } if ($request_method ~ (MOVE|COPY)) { more_set_input_headers \u0026#39;Destination: $dest\u0026#39;; } if ($request_method ~ MKCOL) { rewrite ^(.*[^/])$ $1/ break; } } # Mac 挂载 webdav 后会自动写入很多文件, 可以通过 nginx 配置屏蔽掉, 保持 webdav 目录的干净 location ~ \\.(_.*|DS_Store|Spotlight-V100|TemporaryItems|Trashes|hidden|localized)$ { access_log off; error_log off; if ($request_method = PUT) { return 403; } return 404; } location ~ \\.metadata_never_index$ { return 200 \u0026#34;Don\u0026#39;t index this drive, Finder!\u0026#34;; } } 本套配置经过 4 篇文章整理而成\n开启 TLSv1.2 TLSv1.3, 并且平衡了兼容性和安全性. SSL Labs 评分为 A 开启 http 基本验证 dav 权限设置为 770 dav_access user:rw group:rw; 启用 nginx 自带的网页目录列表 修复某些客户端路径结尾没有斜杠 屏蔽 Mac 挂载 webdav 后会自动写入很多文件 Nginx 安装和基本配置完成后, WebDAV 服务已生效。如果你在 Web 浏览器中访问 WebDav, 应该能够看到该目录中现有文件的目录列表, 但你无法通过 Web 浏览器上传新文件。需要使用 WebDAV 客户端 (例如 macOS Finder、Windows 中的 rclone 等) 管理文件。\n配置代码解析\r某些 WebDAV 客户端 (如 OS X 下的 ForkLift) 在 创建文件夹 / 复制文件夹 / 移动文件夹 失败的问题\nNginx 默认要求对文件夹操作时路径结尾需要有 /, 而部分客户端没有遵守这一要求。解决方法是用 url rewrite, 如果操作的是文件夹, 则补上 /\n2018/06/03 08:03:58 [error] 7#7: *1 MKCOL can create a collection only, client: 8.8.8.8, server: example.com, request: \u0026#34;MKCOL /sp HTTP/2.0\u0026#34;, host: \u0026#34;example.com\u0026#34;\r2018/06/03 08:17:20 [error] 7#7: *18 \u0026#34;/sp\u0026#34; is collection, client: 8.8.8.8, server: example.com, request: \u0026#34;MOVE /sp HTTP/2.0\u0026#34;, host: \u0026#34;example.com\u0026#34; 以下代码是为了解决某些 WebDAV 客户端 (如 macOS 下的 ForkLift) 在创建文件夹、复制文件夹或移动文件夹时因路径结尾缺少斜杠而报错的问题。\nset $dest $http_destination; if (-d $request_filename) { rewrite ^(.*[^/])$ $1/; set $dest $dest/; } if ($request_method ~ (MOVE|COPY)) { more_set_input_headers \u0026#39;Destination: $dest\u0026#39;; } if ($request_method ~ MKCOL) { rewrite ^(.*[^/])$ $1/ break; } 配置说明\n路径补全: 使用 rewrite 补全文件夹路径末尾的 /, 确保兼容客户端的操作习惯 MOVE / COPY 方法兼容性: 对 MOVE 和 COPY 操作, 将 Destination 头的路径末尾补上 /, 以满足 Nginx 的 WebDAV 需求 (需要 headers-more-nginx-module 模块) MKCOL 方法补全: 确保创建集合 (文件夹) 时路径的正确性, 避免路径缺少 / 导致的 MKCOL 报错 WebDAV 支持的请求方法\rOPTIONS: 查询 WebDAV 服务支持的方法 GET: 获取文件 PUT、POST: 上传文件 DELETE: 删除文件或集合 COPY: 复制文件 MOVE: 移动文件 MKCOL: 创建新的文件集合 (文件夹) PROPFIND: 查询文件属性 LOCK、UNLOCK: 加锁、解锁文件, 实现写保护 使用 curl 测试 WebDAV\r使用 curl 测试时, URI后面一定要带 / , 不然就会报错\n创建目录\rcurl -X MKCOL -u USER:PASSWORD https://dav.example.com/test/ 上传文件\rcurl -T FILE -u USER:PASSWORD https://dav.example.com/test/ 重命名\rcurl -X MOVE -u USER:PASSWORD --header \u0026#39;Destination:https://dav.example.com/test/newname\u0026#39; https://dav.example.com/test/File 删除\rcurl -X DELETE -u USER:PASSWORD https://dav.example.com/test/File 原文 - 编译贡献 (文章按照贡献价值排序)\n在 CentOS 7 上从源代码安装 Nginx\nHow to Build Nginx from source on CentOS 7\nCentos7.x 编译安装全功能的Nginx\n原文 - 配置贡献 (仅配置部分可供参考 其余部分没啥用)\nnginx配置功能完整的webdav服务器\n使用 nginx 搭建 WebDAV 服务器\nInstall Nginx as a WebDav File Server on CentOS 7\n如何在 Nginx 上启用 TLS 1.3\n","date":"2019-05-01T00:37:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-building-a-webdav-server-with-nginx/","title":"CentOS 7 用 nginx 构建 WebDAV 服务器"},{"content":"解决 .NET Framework 已是操作系统一部分, 但是程序运行还是有问题\n方案一 使用内置修复功能\r进入: 控制面板 \u0026gt; 程序 \u0026gt; 程序和功能\n选择: 找到 .NET Framework 版本 (如 4.5.2), 点击 卸载/更改\n操作: 选择 将 .NET Framework 修复成原始状态 , 并点击 下一步\n系统将自动检查和修复该版本的 .NET Framework\n完成后尝试重新运行出错的软件\n检查问题是否已经解决, 没有解决尝试方法二\n方案二 使用离线安装包的修复功能\r下载: dotNetFx40_Full_x86_x64.exe (如果已有该安装包, 可直接跳到第2步)\n执行命令\n打开命令提示符并进入下载目录\n执行以下命令\ndotNetFx40_Full_x86_x64.exe /NoSetupVersionCheck /repair 在弹出的修复选项中, 选择 将 .NET Framework 4 修复到其原始状态, 按提示完成修复\n方案三 使用 Microsoft .NET Framework Repair Tool\r下载并运行: Microsoft .NET Framework Repair Tool 该工具将自动检测并尝试修复所有安装的 .NET Framework 版本 原文\n如何修復/移除 .NET Framework 元件毀損錯誤\n","date":"2019-04-30T22:37:00+08:00","permalink":"https://blog.acesheep.com/p/repair-net-framework/","title":"修复 .NET Framework"},{"content":"在切割视频时, 如果直接复制而不重新编码, 处理速度会大大提升。ffmpeg 命令可以通过 -acodec copy 和 -vcodec copy 选项实现这种无损切割\n命令格式\rffmpeg -i input.mp4 -ss [开始时间] -t [持续时间] -acodec copy -vcodec copy output.mp4 -ss: 指定视频开始的时间点 (格式为 时:分:秒), 如 00:00:04 表示第 4 秒开始 -t: 指定持续时间 (格式为 时:分:秒), 如 00:04:16 表示持续 4分16秒 -acodec copy 和 -vcodec copy: 直接复制音频和视频数据, 实现无损分割 例子\r从头开始截取前 30 秒\nffmpeg -ss 00:00:00 -t 00:00:30 -i keyoutput.mp4 -vcodec copy -acodec copy split.mp4 从 30 秒开始截取 30 秒的视频\nffmpeg -ss 00:00:30 -t 00:00:30 -i keyoutput.mp4 -vcodec copy -acodec copy split1.mp4 视频合并\r在 list.txt 文件中, 对要合并的视频片段进行了描述\nfile ./split.mp4 file ./split1.mp4 ffmpeg 可以将分割后的多个视频片段进行合并\nffmpeg -f concat -i list.txt -c copy concat.mp4 原文\nffmpeg无损快速切割视频方法\n","date":"2019-04-24T10:55:22+08:00","permalink":"https://blog.acesheep.com/p/ffmpeg-lossless-fast-video-cutting/","title":"FFmpeg 无损快速切割视频"},{"content":"文件 test.txt 有 17 行\n方法一 使用 awk\r逐行输出行号, tail -n1 获取最后一行的行号, 即总行数\nawk '{print NR}' 为每一行打印当前行号。tail -n1 提取最后一个行号作为行数输出\nawk \u0026#39;{print NR}\u0026#39; test.txt | tail -n1 17 直接输出最后一行的行号 (文件总行数)\nawk 的 END 块在文件结束时执行, 所以 NR 即为文件总行数\nawk \u0026#39;END{print NR}\u0026#39; test.txt 17 方法二 使用 grep 和 awk\r为文件每行添加行号, 然后用 awk 取出行号部分, 再通过 tail -n1 获取最后一个行号\ngrep -n '' 为文件的每一行标记行号。awk -F : '{print $1}' 取出行号部分, tail -n1 返回最后一个行号\ngrep -n \u0026#39;\u0026#39; test.txt | awk -F : \u0026#39;{print $1}\u0026#39; | tail -n1 17 获取最后一行的行号, 即文件总行数\ngrep -n '' 作用相同, awk -F : 'END{print $1}' 在处理完文件后取最后的行号\ngrep -n \u0026#39;\u0026#39; test.txt | awk -F : \u0026#39;END{print $1}\u0026#39; 17 方法三 使用 sed\r显示最后一行的行号 (文件总行数)\n-n 抑制默认输出, $ 到最后一行, = 打印行号\nsed -n \u0026#39;$=\u0026#39; test.txt 17 统计文件的行数, 等同于cat test.txt | wc -l\n方法四 使用 wc\r直接统计并显示文件行数\nwc -l 输出文件行数及文件名\nwc -l test.txt 17 test.txt 显示文件的行数, 不输出文件名\nawk '{print $1}' 从 wc -l 输出中提取行数部分\nwc -l test.txt | awk \u0026#39;{print $1}\u0026#39; 17 将文件内容通过管道传递给 wc -l, 显示行数\n此命令和 wc -l test1.txt 类似, 但增加了 cat 调用\ncat test.txt | wc -l 17 原文\nlinux下统计文本行数的各种方法（一）\n","date":"2019-04-10T00:50:00+08:00","permalink":"https://blog.acesheep.com/p/count-lines-in-a-file-on-linux/","title":"Linux 下统计文件文本行数"},{"content":"sed 是 stream editor 的简称, 是一个流编辑器。它逐行处理输入文本, 处理时, 把当前处理的行存储在临时缓冲区中, 称为 \u0026quot;pattern space\u0026quot;, 接着用 sed 命令处理缓冲区中的内容, 处理完成后, 把结果输出到标准输出。接着处理下一行, 这样不断重复, 直到文件末尾。\n基本语法\r# 命令选项 sed 操作命令 要处理的文件 sed [option] \u0026#39;command\u0026#39; input_file 常用选项\r-n 使用安静 silent 模式。在一般 sed 的用法中, 所有来自 stdin 的内容一般都会被列出到屏幕上。但如果加上 -n 参数后, 则只有经过 sed 特殊处理的那一行 (或者动作) 才会被列出来 -e 多点编辑, 可以执行多个子命令 -f 从文件中读取 sed 命令, -f filename 则可以执行 filename 内的 sed 命令 -r 让 sed 命令支持扩展的正则表达式 (默认是基础正则表达式) -i 直接修改文件内容, 不仅仅是输出 -l 指定每行的最大长度 常用命令\r实验用文件内容 test.txt\nletitia mail uuencode 1003605091 01566 a 命令 - 新增\r在指定行后追加文本 (多行字符串可以用 \\n 分隔), 而这些字串会在新的一行出现\n从第一行到最后一行所有行后追加 \u0026quot;add one\u0026quot; 字符串\nsed \u0026#39;1,$a\\add one\u0026#39; test.txt letitia add one mail add one uuencode add one 1003605091 add one 01566 add one 在匹配到 mail 行后追加 \u0026quot;add one\u0026quot; 字符串\nsed \u0026#39;/mail/a\\add one\u0026#39; test.txt letitia mail add one uuencode 1003605091 01566 i 命令 - 插入\r在匹配的行前面插入字符串行, 这些字串会在新的一行出现\n在第二行之前插入一行内容 \u0026quot;inserted text\u0026quot;\nsed \u0026#39;2i\\inserted text\u0026#39; test.txt letitia inserted text mail uuencode 1003605091 01566 c 命令 - 替换整行\r用于替换整行内容\n将第二行替换为 This is a new line\nsed \u0026#39;2cThis is a new line\u0026#39; test.txt letitia This is a new line uuencode 1003605091 01566 从第一行到最后一行所有行替换为 \u0026quot;add one\u0026quot; 字符串\nsed \u0026#39;1,$c\\add one\u0026#39; test.txt add one 将匹配到 mail 行替换为 \u0026quot;add one\u0026quot; 字符串\nsed \u0026#39;/mail/c\\add one\u0026#39; test.txt letitia add one uuencode 1003605091 01566 s 命令 - 替换文本\r用于在行内替换指定的文本内容\n基本格式\nsed \u0026#39;位置参数 s/要查找的文本/替换后的文本/[flag]\u0026#39; 将所有的 apple 替换为 orange\necho \u0026#34;I have an apple\u0026#34; | sed \u0026#39;s/apple/orange/\u0026#39; I have an orange 将所有的 letitia 替换为 new\nsed \u0026#39;s/letitia/new/g\u0026#39; test.txt new mail uuencode 1003605091 01566 {} 要转义, 因为此处使用的不是扩展正则表达式\nsed \u0026#39;s/[0-9]\\{10\\}/miss letitia/g\u0026#39; test.txt letitia mail uuencode miss letitia 01566 将前两行里的 l 替换为 L\nsed \u0026#39;1,/^ma/ s/l/L/g\u0026#39; test.txt Letitia maiL uuencode 1003605091 01566 这个例子比较复杂。使用大括号, 表示对 1 到 3 行做了一组操作\nsed -n \u0026#39;1,3{ s/l/L/g s/e/E/g 2 i tyrone p }\u0026#39; test.txt LEtitia tyrone maiL uuEncodE d 命令 - 删除\r删除指定行\n删除第三行\nsed \u0026#39;3d\u0026#39; test.txt letitia mail 1003605091 01566 从第四行到最后一行全部删除\nsed \u0026#39;4,$d\u0026#39; test.txt letitia mail uuencode p 命令 - 打印\r打印指定行\n打印第一至第三行\nsed \u0026#39;1,3 p\u0026#39; test.txt letitia letitia mail mail uuencode uuencode 1003605091 01566 打印第一至第三行有 -n 参数\nsed -n \u0026#39;1,3p\u0026#39; test.txt letitia mail uuencode 观察输出结果, 不使用 -n 选项时, sed 命令把 1 到 3 行输出了两次。这是因为不使用 -n 时, sed 首先读取一行, 并默认将缓冲区内的文本输出出来, 之后 p 子命令再次输出。使用 -n 时, 默认输出取消, 只有 p 子命令的输出结果\nsed 命令支持正则表达式定位。语法为 /re/, re 表示正则表达式\n打印出从匹配正则表达式的地方到第 5 行, 也就是从匹配以 ma 开头的文本行处开始\nsed -n \u0026#39;/^ma/,5 p\u0026#39; test.txt mail uuencode 1003605091 01566 以 first 开头 end 结尾的所有行全部打印\nsed -n \u0026#39;/^first.*end$/p\u0026#39; test.txt 1~2 表示从第一行开始, 行号递增 2 输出, 即输出奇数行。语法格式为 first~step\nsed -n \u0026#39;1~2 p\u0026#39; test.txt letitia uuencode 01566 标志选项\rg # 全局匹配, 会替换文本行中所有匹配的字符串 digit # 替换文本行中第 n 个 (digit 是 1 至 9) 匹配的字符串 p # 若发生了替换操作, 并且将缓冲区输出到标准输出 w file-name # 若发生了替换操作, 并且将改动的行输出到磁盘文件中 i # 表示进行 Regexp 匹配时, 不区分大小写字母 GNU 版本的扩展标识\r\\digit # Replacement 中可含有后向引用中的 \\digit (digit 是 1 至 9), 引用前面定义的子表达 \u0026amp; # 代表模版空间中的整个匹配部分 \\L # 将在其后的替换部分转换成小写字母, 直到发现一个 \\U 或 \\E, GNU 扩展功能 \\l # 将下一个字符转换成小写字母, GNU 扩展功能 \\U # 将在其后的替换部分转换成大写字母, 直到发现一个 \\L 或 \\E, GNU 扩展功能 \\u # 将下一个字符转换成大写字母, GNU 扩展功能 \\E # 停止由 \\L 或 \\U 指示开始的大小写转换, GNU 扩展功能 基本正则表达式\r元字符 说明 * 将 * 前面的正则表达式匹配的结果重复任意次 (含 0 次) \\+ 与星号 (*) 相同, 只是至少重复 1 次, GNU 的扩展功能 \\? 与星号 (*) 相同, 只是最多重复 1 次, GNU 的扩展功能 \\{i\\} 与星号 (*) 相同, 只是重复指定的 i 次 \\{i,j\\} 与星号 (*) 相同, 只是重复 i 至 j 次 \\{i, \\} 与星号 (*) 相同, 只是至少重复 i 次 \\(regexp\\) 将 regexp 看作一个整体, 用于后向引用, 与 \\digit 配合使用 . 匹配任意单个字符 ^ 匹配模版空间开始处的 NULL 字符串 $ 匹配的是模版空间结束处的 NULL 字符串 [list] 匹配方括号中的字符列表中的任意一个 [^list] 否定匹配方括号中的字符列表中的任意一个 regexp1|regexp2 用在相邻的正则表达式之间, 表示匹配这些正则表达式中任一个都可以。匹配是从左向右开始的, 一旦匹配成功就停止匹配 regexp1regexp2 匹配 regexp1 和 regexp2 的连接结果 \\digit 匹配正则表达式前半部分定义的后向引用的第 digit 个子表达式。digit 为 1 至 9 的数字, 1 为从左开始 \\n 匹配换行符 \\meta 将元字符 meta 转换成普通字符, 以便匹配该字符本身, 有$、*、.、[、\\ 和 ^ 扩展正则表达式\r它们之间的差别很小, 那就是转义字符的使用\n简称 全称 解释 BRE basic regular expressions 基础正则表达式 (过时的) ERE extended regular expressions 扩展正则表达式 (现代的) 如果从字面理解, 基础这个字眼让 BRE 显得具有一定地位, 但实质上 BRE 的存在只是为了兼容一些老旧的软件。\n基本正则表达式 扩展正则表达式 \\? ? \\+ + \\| | \\{ \\} { } \\( \\) ( ) 常用转义字符\r转义字符 说明 \\a 匹配一个 BEL 字符 \\f 匹配一个换页字符 \\n 匹配一个换行字符 \\r 匹配一个回车字符 \\t 匹配一个水平 Tab 字符 \\v 匹配一个垂直 Tab 字符 \\cX 匹配 Control+X, X 是任意字符 \\dXXX 匹配一个 ASCII 码是十进制 XXX 的字符 \\oXXX 匹配一个 ASCII 码是八进制 XXX 的字符 \\xXX 匹配一个 ASCII 码是十六进制 XX 的字符 \\w 匹配任意一个单词字符 (字母、数字和下划线) \\W 匹配任意一个非单词字符 \\b 匹配一个单词的边界符: 字符的左边是一个单词字符, 并且右边是一个非单词字符, 反之亦然 \\B 匹配除单词边界符外所有字符: 字符的左边和右边同时是单词字符或非单词字符 原文\nLinux Sed命令详解\nsed命令详解\n","date":"2019-04-09T23:14:00+08:00","permalink":"https://blog.acesheep.com/p/linux-sed-command-guide/","title":"Linux Sed 命令详解"},{"content":"因为 CentOS 7上默认的版本是 Python 2.7, 所以我们可以通过添加 IUS 软件源使用 yum 方式安装 Python 3.6\n安装 EPEL 和 IUS 软件源\ryum install epel-release yum install https://repo.ius.io/ius-release-el7.rpm 安装 Python 3.6 和 pip3\ryum install python36u python36u-pip 创建符号链接\r创建 python3 连接符\rln -s /bin/python3.6 /bin/python3 创建 pip3 连接符\rln -s /bin/pip3.6 /bin/pip3 安装常用的 Python 库\rpip3 install requests pip3 install pymysql pip3 install xmltodict pip3 install six 以上步骤完成后, Python 3.6 和 pip3 就安装成功了, 并可以直接使用 python3 和 pip3 命令来运行和安装 Python 包\n","date":"2019-04-08T01:13:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-install-python-3.6-via-yum/","title":"CentOS 7 通过 yum 安装 Python 3.6"},{"content":"Bash 脚本的条件判断语法\nif 语法\rif 是最常用的条件判断结构, 只有符合给定条件时, 才会执行指定的命令。它的语法如下\n单分支 if 语句\rif 判断表达式; then statement1 statement2 ....... fi 双分支的 if 语句\rif 判断表达式; then statement1 statement2 ..... else statement3 statement4 fi 多分支的 if 语句\rif 判断表达式1; then statement1 elif 判断表达式2; then statement2 elif 判断表达式3; then statement3 else statement4 fi if 和 then 写在同一行时, 需要分号 (;) 分隔。分号是 Bash 的命令分隔符。它们也可以写成两行, 这时不需要分号。\nif true then echo \u0026#39;hello world\u0026#39; fi 除了多行的写法, if 结构也可以写成单行\n$ if true; then echo \u0026#39;hello world\u0026#39;; fi hello world 注意, if 关键字后面也可以是一条命令, 该条命令执行成功 (返回值 0), 就意味着判断条件成立。\n$ if echo \u0026#39;hi\u0026#39;; then echo \u0026#39;hello world\u0026#39;; fi hi hello world 上面命令中, if后面是一条命令echo 'hi'。该命令会执行, 如果返回值是0, 则执行then的部分。\nif 后面可以跟任意数量的命令。这时, 所有命令都会执行, 但是判断真假只看最后一个命令, 即使前面所有命令都失败, 只要最后一个命令返回 0, 就会执行 then 的部分。\n$ if false; true; then echo \u0026#39;hello world\u0026#39;; fi hello world 上面例子中, if 后面有两条命令 (false;true;), 第二条命令 (true) 决定了 then 的部分是否会执行。\ntest 命令\r注意, 第二种和第三种写法, 括号两端必须要有空格\n# 写法一 test expression # 写法二 [ expression ] # 写法三 [[ expression ]] 上面三种形式是等价的, 但是第三种形式还支持正则判断, 前两种不支持。\n上面的 expression 是一个表达式。\n这个表达式为真, test 命令执行成功 (返回值为 0) 表达式为假, test 命令执行失败 (返回值为 1)。\ntest -f /etc/hosts echo $? 0 [ -f /etc/hosts ] echo $? 0 上面的例子中, test 命令采用两种写法, 判断 /etc/hosts 文件是否存在, 这两种写法是等价的。命令执行后, 返回值为 0, 表示该文件确实存在\n例子\r下面把 test 命令的三种形式, 用在 if 结构中, 判断一个文件是否存在。\n# 写法一 if test -e /tmp/foo.txt ; then echo \u0026#34;Found foo.txt\u0026#34; fi # 写法二 if [ -e /tmp/foo.txt ] ; then echo \u0026#34;Found foo.txt\u0026#34; fi # 写法三 if [[ -e /tmp/foo.txt ]] ; then echo \u0026#34;Found foo.txt\u0026#34; fi 判断表达式\rif 关键字后面, 跟的是一个命令。这个命令可以是 test 命令, 也可以是其他命令。命令的返回值为 0 表示判断成立, 否则表示不成立。因为这些命令主要是为了得到返回值, 所以可以视为表达式。\n整数比较\r[ integer1 -eq integer2 ] # integer1 等于 integer2, 则为真 [ integer1 -ne integer2 ] # integer1 不等于 integer2, 则为真 [ integer1 -gt integer2 ] # integer1 大于 integer2, 则为真 [ integer1 -lt integer2 ] # integer1 小于 integer2, 则为真 [ integer1 -ge integer2 ] # integer1 大于或等于 integer2, 则为真 [ integer1 -le integer2 ] # integer1 小于或等于 integer2, 则为真 例子\r先判断变量 $INT 是否为空, 然后判断是否为 0, 接着判断正负, 最后通过求余数判断奇偶\n#!/bin/bash INT=-5 if [ -z \u0026#34;$INT\u0026#34; ]; then echo \u0026#34;INT is empty.\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi if [ $INT -eq 0 ]; then echo \u0026#34;INT is zero.\u0026#34; else if [ $INT -lt 0 ]; then echo \u0026#34;INT is negative.\u0026#34; else echo \u0026#34;INT is positive.\u0026#34; fi if [ $((INT % 2)) -eq 0 ]; then echo \u0026#34;INT is even.\u0026#34; else echo \u0026#34;INT is odd.\u0026#34; fi fi 字符串比较\r[ string ] # 如果 string 不为空 (长度大于 0), 则为真 [ -n string ] # 如果字符串 string 的长度大于零, 则为真 [ -z string ] # 如果字符串 string 的长度为零, 则为真 [ string1 = string2 ] # 如果 string1 和 string2 相同, 则为真 [ string1 == string2 ] # 等同于[ string1 = string2 ] [ string1 != string2 ] # 如果 string1 和 string2 不相同, 则为真 [ string1 \u0026#39;\u0026gt;\u0026#39; string2 ] # 如果按照字典顺序 string1 排列在 string2 之后, 则为真 [ string1 \u0026#39;\u0026lt;\u0026#39; string2 ] # 如果按照字典顺序 string1 排列在 string2 之前, 则为真 [ string1 \\\u0026gt; string2 ] # 用反斜杠转义 [ string1 \\\u0026lt; string2 ] # 用反斜杠转义 注意, test 命令内部的 \u0026gt; 和 \u0026lt;, 必须用引号引起来 (或者是用反斜杠转义)。否则, 它们会被 shell 解释为重定向操作符\n例子\r首先确定 $ANSWER 字符串是否为空。如果为空, 就终止脚本, 并把退出状态设为 1。注意, 这里的 echo 命令把错误信息 There is no answer. 重定向到标准错误, 这是处理错误信息的常用方法。如果 $ANSWER 字符串不为空, 就判断它的值是否等于 yes、no 或者 maybe\n#!/bin/bash ANSWER=maybe if [ -z \u0026#34;$ANSWER\u0026#34; ]; then echo \u0026#34;There is no answer.\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi if [ \u0026#34;$ANSWER\u0026#34; = \u0026#34;yes\u0026#34; ]; then echo \u0026#34;The answer is YES.\u0026#34; elif [ \u0026#34;$ANSWER\u0026#34; = \u0026#34;no\u0026#34; ]; then echo \u0026#34;The answer is NO.\u0026#34; elif [ \u0026#34;$ANSWER\u0026#34; = \u0026#34;maybe\u0026#34; ]; then echo \u0026#34;The answer is MAYBE.\u0026#34; else echo \u0026#34;The answer is UNKNOWN.\u0026#34; fi 注意, 字符串判断时, 变量要放在双引号之中, 比如 [ -n \u0026quot;$COUNT\u0026quot; ], 否则变量替换成字符串以后, test 命令可能会报错, 提示参数过多。另外, 如果不放在双引号之中, 变量为空时, 命令会变成 [ -n ], 这时会判断为真。如果放在双引号之中, [ -n \u0026quot;\u0026quot; ] 就判断为假。\nif 语句进行判断是否为空\r这三种写法是等价的\n[ \u0026#34;$name\u0026#34; = \u0026#34;\u0026#34; ] [ ! \u0026#34;$name\u0026#34; ] [ -z \u0026#34;$name\u0026#34; ] 逻辑运算符\r通过逻辑运算, 可以把多个 test 判断表达式结合起来, 创造更复杂的判断。三种逻辑运算 AND, OR 和 NOT, 都有自己的专用符号。\nAND 逻辑与: # 符号 \u0026amp;\u0026amp;, 也可使用参数 -a OR 逻辑或: # 符号 ||, 也可使用参数 -o NOT 逻辑非: # 符号 ! 例子\r下面是一个 AND 的例子, 判断整数是否在某个范围之内\n\u0026amp;\u0026amp; 用来连接两个判断条件: 大于等于 $MIN_VAL, 并且小于等于 $MAX_VAL\n#!/bin/bash MIN_VAL=1 MAX_VAL=100 INT=50 if [[ $INT -ge $MIN_VAL \u0026amp;\u0026amp; $INT -le $MAX_VAL ]]; then echo \u0026#34;$INT is within $MIN_VAL to $MAX_VAL.\u0026#34; else echo \u0026#34;$INT is out of range.\u0026#34; fi 使用否定操作符 ! 时, 最好用圆括号确定转义的范围\ntest 命令内部使用的圆括号, 必须使用引号或者反斜杠转义, 否则会被 Bash 解释。\nif [ ! \\( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \\) ]; then echo \u0026#34;$INT is outside $MIN_VAL to $MAX_VAL.\u0026#34; else echo \u0026#34;$INT is in range.\u0026#34; fi 使用 -a 连接两个判断条件不太直观, 一般推荐使用 \u0026amp;\u0026amp; 代替, 上面的脚本可以改写成下面这样\nif !([ $INT -ge $MIN_VAL ] \u0026amp;\u0026amp; [ $INT -le $MAX_VAL ]); then echo \u0026#34;$INT is outside $MIN_VAL to $MAX_VAL.\u0026#34; else echo \u0026#34;$INT is in range.\u0026#34; fi 正则表达式\r[[ expression ]] 这种判断形式, 支持正则表达式\n[[ string1 =~ regex ]] 上面的语法中, regex 是一个正则表示式, =~ 是正则比较运算符\n例子\r先判断变量 INT 的字符串形式, 是否满足 ^-?[0-9]+$ 的正则模式, 如果满足就表明它是一个整数\n#!/bin/bash INT=-5 if [[ \u0026#34;$INT\u0026#34; =~ ^-?[0-9]+$ ]]; then echo \u0026#34;INT is an integer.\u0026#34; exit 0 else echo \u0026#34;INT is not an integer.\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi 文件测试\r以下表达式用来判断文件状态\n[ -a file ] # 如果 file 存在, 则为真 [ -b file ] # 如果 file 存在并且是一个块 (设备) 文件, 则为真 [ -c file ] # 如果 file 存在并且是一个字符 (设备) 文件, 则为真 [ -d file ] # 如果 file 存在并且是一个目录, 则为真 [ -e file ] # 如果 file 存在, 则为真 [ -f file ] # 如果 file 存在并且是一个普通文件, 则为真 [ -g file ] # 如果 file 存在并且设置了组 ID, 则为真 [ -G file ] # 如果 file 存在并且属于有效的组 ID, 则为真 [ -h file ] # 如果 file 存在并且是符号链接, 则为真 [ -k file ] # 如果 file 存在并且设置了它的 \u0026#34;sticky bit\u0026#34;, 则为真 [ -L file ] # 如果 file 存在并且是一个符号链接, 则为真 [ -N file ] # 如果 file 存在并且自上次读取后已被修改, 则为真 [ -O file ] # 如果 file 存在并且属于有效的用户 ID, 则为真 [ -p file ] # 如果 file 存在并且是一个命名管道, 则为真 [ -r file ] # 如果 file 存在并且可读 (当前用户有可读权限), 则为真 [ -s file ] # 如果 file 存在且其长度大于零, 则为真 [ -S file ] # 如果 file 存在且是一个网络 socket, 则为真 [ -t fd ] # 如果 fd 是一个文件描述符, 并且重定向到终端, 则为真 这可以用来判断是否重定向了标准输入／输出／错误。 [ -u file ] # 如果 file 存在并且设置了 setuid 位, 则为真 [ -w file ] # 如果 file 存在并且可写 (当前用户拥有可写权限), 则为真 [ -x file ] # 如果 file 存在并且可执行 (当前用户有执行／搜索权限), 则为真 [ FILE1 -nt FILE2 ] # 如果 FILE1 比 FILE2 的更新时间更近, 或者 FILE1 存在而 FILE2 不存在, 则为真 [ FILE1 -ot FILE2 ] # 如果 FILE1 比 FILE2 的更新时间更旧, 或者 FILE2 存在而 FILE1 不存在, 则为真 [ FILE1 -ef FILE2 ] # 如果 FILE1 和 FILE2 引用相同的设备和 inode 编号, 则为真 例子\r$FILE 要放在双引号之中, 这样可以防止变量 $FILE 为空, 从而出错。因为 $FILE 如果为空, 这时 [ -e $FILE ] 就变成 [ -e ], 这会被判断为真。而 $FILE 放在双引号之中, [ -e \u0026quot;$FILE\u0026quot; ] 就变成 [ -e \u0026quot;\u0026quot; ], 这会被判断为假。\n#!/bin/bash FILE=~/.bashrc if [ -e \u0026#34;$FILE\u0026#34; ]; then if [ -f \u0026#34;$FILE\u0026#34; ]; then echo \u0026#34;$FILE is a regular file.\u0026#34; fi if [ -d \u0026#34;$FILE\u0026#34; ]; then echo \u0026#34;$FILE is a directory.\u0026#34; fi if [ -r \u0026#34;$FILE\u0026#34; ]; then echo \u0026#34;$FILE is readable.\u0026#34; fi if [ -w \u0026#34;$FILE\u0026#34; ]; then echo \u0026#34;$FILE is writable.\u0026#34; fi if [ -x \u0026#34;$FILE\u0026#34; ]; then echo \u0026#34;$FILE is executable/searchable.\u0026#34; fi else echo \u0026#34;$FILE does not exist\u0026#34; exit 1 fi 算术判断\rBash 还提供了 ((...)) 作为算术条件, 进行算术运算的判断\nif ((3 \u0026gt; 2)); then echo \u0026#34;true\u0026#34; fi 注意, 算术判断不需要使用 test 命令, 而是直接使用 ((...)) 结构。这个结构的返回值, 决定了判断的真假。\n如果算术计算的结果是非零值, 则表示判断成立。这一点跟命令的返回值正好相反, 需要小心。\n$ if ((1)); then echo \u0026#34;It is true.\u0026#34;; fi It is true. $ if ((0)); then echo \u0026#34;It is true.\u0026#34;; else echo \u0026#34;it is false.\u0026#34;; fi It is false. 上面例子中, ((1)) 表示判断成立, ((0)) 表示判断不成立。\n算术条件 ((...)) 也可以用于变量赋值, ((...)) 中变量是可以不使用 $ 来引用的\n$ if (( foo = 5 ));then echo \u0026#34;foo is $foo\u0026#34;; fi foo is 5 上面例子中, (( foo = 5 )) 完成了两件事情。首先把 5 赋值给变量 foo, 然后根据返回值 5, 判断条件为真。\n注意, 赋值语句返回等号右边的值, 如果返回的是 0, 则判断为假。\n$ if (( foo = 0 ));then echo \u0026#34;It is true.\u0026#34;;else echo \u0026#34;It is false.\u0026#34;; fi It is false. 下面是用算术条件改写的数值判断脚本\n#!/bin/bash INT=-5 if [[ \u0026#34;$INT\u0026#34; =~ ^-?[0-9]+$ ]]; then if ((INT == 0)); then echo \u0026#34;INT is zero.\u0026#34; else if ((INT \u0026lt; 0)); then echo \u0026#34;INT is negative.\u0026#34; else echo \u0026#34;INT is positive.\u0026#34; fi if (( ((INT % 2)) == 0)); then echo \u0026#34;INT is even.\u0026#34; else echo \u0026#34;INT is odd.\u0026#34; fi fi else echo \u0026#34;INT is not an integer.\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi 只要是算术表达式, 都能用于 ((...)) 语法\n普通命令的逻辑运算\r如果 if 结构使用的不是 test 命令, 而是普通命令, 比如上一节的 ((...)) 算术运算, 或者 test 命令与普通命令混用, 那么可以使用 Bash 的命令控制操作符 \u0026amp;\u0026amp; (AND) 和 || (OR), 进行多个命令的逻辑运算。\n# 对于 \u0026amp;\u0026amp; 操作符, 先执行 command1, 只有 command1 执行成功后, 才会执行 command2 command1 \u0026amp;\u0026amp; command2 # 对于 || 操作符, 先执行 command1, 只有 command1 执行失败后, 才会执行 command2 command1 || command2 创建一个名为 temp 的目录, 执行成功后, 才会执行第二个命令, 进入这个目录。\nmkdir temp \u0026amp;\u0026amp; cd temp 测试目录 temp 是否存在, 如果不存在, 就会执行第二个命令, 创建这个目录。这种写法非常有助于在脚本中处理错误。\n[ -d temp ] || mkdir temp 如果 temp 子目录不存在, 脚本会终止, 并且返回值为 1\n[ ! -d temp ] \u0026amp;\u0026amp; exit 1 if 与 \u0026amp;\u0026amp; 结合使用的写法\nif [ condition ] \u0026amp;\u0026amp; [ condition ]; then command fi 例子\n只有在指定文件里面, 同时存在搜索词 word1 和 word2, 就会执行 if 的命令部分。\n#! /bin/bash filename=$1 word1=$2 word2=$3 if grep $word1 $filename \u0026amp;\u0026amp; grep $word2 $filename then echo \u0026#34;$word1 and $word2 are both in $filename.\u0026#34; fi 将一个 \u0026amp;\u0026amp; 判断表达式, 改写成对应的 if 结构\n[[ -d \u0026#34;$dir_name\u0026#34; ]] \u0026amp;\u0026amp; cd \u0026#34;$dir_name\u0026#34; \u0026amp;\u0026amp; rm * # 等同于 if [[ ! -d \u0026#34;$dir_name\u0026#34; ]]; then echo \u0026#34;No such directory: \u0026#39;$dir_name\u0026#39;\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi if ! cd \u0026#34;$dir_name\u0026#34;; then echo \u0026#34;Cannot cd to \u0026#39;$dir_name\u0026#39;\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi if ! rm *; then echo \u0026#34;File deletion failed. Check results\u0026#34; \u0026gt;\u0026amp;2 exit 1 fi case 结构\rcase 结构用于多值判断, 可以为每个值指定对应的命令, 跟包含多个 elif 的 if 结构等价。它的语法如下\nexpression 是一个表达式, pattern 是表达式的值或者一个模式, 可以有多条, 用来匹配多个值, 每条以两个分号 (;;) 结尾\ncase expression in pattern1 ) statement1 ;; pattern2 ) statement2 ;; ... esac 最后一条匹配语句的模式是 *, 这个通配符可以匹配其他字符和没有输入字符的情况, 类似 if 的 else 部分\n#!/bin/bash echo -n \u0026#34;输入一个1到3之间的数字 (包含两端) \u0026gt; \u0026#34; read character case $character in 1 ) echo 1 ;; 2 ) echo 2 ;; 3 ) echo 3 ;; * ) echo 输入不符合要求 esac case 的匹配模式可以使用各种通配符, 下面是一些例子\na): 匹配 a a|b): 匹配 a 或 b [[:alpha:]]): 匹配单个字母 ???): 匹配 3 个字符的单词 *.txt): 匹配 .txt 结尾 *): 匹配任意输入, 通常作为 case 结构的最后一个模式 使用通配符 [[:lower:]] | [[:upper:]] 匹配字母, [0-9] 匹配数字\n#!/bin/bash echo -n \u0026#34;输入一个字母或数字 \u0026gt; \u0026#34; read character case $character in [[:lower:]] | [[:upper:]] ) echo \u0026#34;输入了字母 $character\u0026#34; ;; [0-9] ) echo \u0026#34;输入了数字 $character\u0026#34; ;; * ) echo \u0026#34;输入不符合要求\u0026#34; esac Bash 4.0 之前, case 结构只能匹配一个条件, 然后就会退出 case 结构。Bash 4.0 之后, 允许匹配多个条件, 这时可以用 ;;\u0026amp; 继续判断条件块。使用 bash --version 检查 Bash 版本\n#!/bin/bash # test.sh read -n 1 -p \u0026#34;Type a character \u0026gt; \u0026#34; echo case $REPLY in [[:upper:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is upper case.\u0026#34; ;;\u0026amp; [[:lower:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is lower case.\u0026#34; ;;\u0026amp; [[:alpha:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is alphabetic.\u0026#34; ;;\u0026amp; [[:digit:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is a digit.\u0026#34; ;;\u0026amp; [[:graph:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is a visible character.\u0026#34; ;;\u0026amp; [[:punct:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is a punctuation symbol.\u0026#34; ;;\u0026amp; [[:space:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is a whitespace character.\u0026#34; ;;\u0026amp; [[:xdigit:]]) echo \u0026#34;\u0026#39;$REPLY\u0026#39; is a hexadecimal digit.\u0026#34; ;;\u0026amp; esac 执行上面的脚本, 会得到下面的结果\n$ test.sh Type a character \u0026gt; a \u0026#39;a\u0026#39; is lower case. \u0026#39;a\u0026#39; is alphabetic. \u0026#39;a\u0026#39; is a visible character. \u0026#39;a\u0026#39; is a hexadecimal digit. 可以看到条件语句结尾添加了 ;;\u0026amp; 以后, 在匹配一个条件之后, 并没有退出 case 结构, 而是继续判断下一个条件\n原文\nshell中if语句的使用\n条件判断 - Bash 脚本教程 - 网道\nHow do I check my bash version?\n","date":"2019-04-04T23:55:00+08:00","permalink":"https://blog.acesheep.com/p/using-if-statements-in-bash-scripts/","title":"Bash 脚本中使用 if 语句"},{"content":"变量名只能包含数字、字母和下划线, 因为某些包含其他字符的变量有特殊含义, 这样的变量被称为特殊变量\n变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数。n 是一个数字, 表示第几个参数。例如, 第一个参数是$1, 第二个参数是$2 $# 传递给脚本或函数的参数个数 $* 传递给脚本或函数的所有参数 $@ 传递给脚本或函数的所有参数。被双引号(\u0026quot; \u0026ldquo;)包含时, 与 $* 稍有不同, 下面将会讲到 $? 上个命令的退出状态, 或函数的返回值 $$ 当前 Shell 进程 ID。对于 Shell 脚本, 就是这些脚本所在的进程 ID 例如\necho $$ 29949 命令行参数\r运行脚本时传递给脚本的参数称为命令行参数。命令行参数用 $n 表示, 例如, $1 表示第一个参数, $2 表示第二个参数, 依次类推。\n#!/bin/bash echo \u0026#34;File Name: $0\u0026#34; echo \u0026#34;First Parameter: $1\u0026#34; echo \u0026#34;First Parameter: $2\u0026#34; echo \u0026#34;Quoted Values: $@\u0026#34; echo \u0026#34;Quoted Values: $*\u0026#34; echo \u0026#34;Total Number of Parameters: $#\u0026#34; 运行结果\n./test.sh Zara Ali File Name : ./test.sh First Parameter: Zara Second Parameter: Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters: 2 $* 和 $@ 的区别\r在 Bash 脚本中, $* 和 $@ 都用于表示传递给脚本或函数的所有位置参数, 但它们之间有细微的区别, 主要体现在它们处理引号 (\u0026quot;) 的方式。\n当你在循环中使用这两者时, 区别会更加明显\nfor arg in \u0026#34;$@\u0026#34;; do echo \u0026#34;$arg\u0026#34; done 上述代码会逐个输出每个参数 (即使参数中有空格, 它们也会被当作一个整体处理)。\n如果使用 $*, 则会将所有参数作为一个字符串传递给 for 循环, 可能会导致意外的行为\n总结:\n$*: 将所有参数视为一个单独的字符串 $@: 每个参数被独立处理, 在双引号中使用时效果最为显著 Shell特殊变量：Shell $0, $#, $*, $@, $?, $$和命令行参数\n","date":"2019-04-04T23:41:00+08:00","permalink":"https://blog.acesheep.com/p/shell-special-variables-and-command-line-arguments/","title":"Shell 特殊变量和命令行参数"},{"content":"如题, 不知从什么版本开始, 无意中发现, 点击 QQ 聊天会话中的链接时, 不会在默认浏览器中打开, 而是会从QQ 自带的一个默认 MiniBrowser 里打开, 极其不方便。\nQQ 也太无耻了, 没办法, 我使用的一些情况, 需要从浏览器中打开。\n点击链接后, 会打开自带浏览器窗口\n只有点击窗口右上角的菜单栏, 再点击 \u0026ldquo;用默认浏览器打开\u0026rdquo;, 才能默认在浏览器中打开。\n解决方法\r查看进程所在目录\r在任务管理器中查看 QQ 启动的 minibrowser 进程所在的目录\n打开 minibrowser 进程所在的目录\r点击 打开文件位置, 找到该进程的文件夹\n删除 MiniBrowser 相关的文件\r确保关闭 QQ, 并杀死保护进程\n# 结束进程 C:\\Program Files (x86)\\Common Files\\Tencent\\QQProtect\\Bin\\QQProtect.exe 删除以下目录和文件\n# 删除此目录 C:\\Users\\aerchi\\AppData\\Local\\Tencent\\MiniBrowser # 删除文件 C:\\Program Files (x86)\\Tencent\\QQ\\Bin\\minibrowser.exe C:\\Program Files (x86)\\Tencent\\QQ\\Bin\\minibrowser_shell.dll 清理注册表\r打开注册表编辑器, 查找 minibrowser 相关的项\n按 F3 挨个查找并删除所有 minibrowser 的注册表项\n删除注册表时, 请小心操作, 确保只删除 minibrowser 相关的项\n原文\n删除QQ的MiniBrowser浏览器，QQ聊天会话中点击链接直接用默认浏览器中打开\n","date":"2019-04-04T23:22:14+08:00","permalink":"https://blog.acesheep.com/p/remove-qq-minibrowser/","title":"删除 QQ 的 MiniBrowser 浏览器"},{"content":"FFmpeg 4.1.1 直接下载编译好的版本实在是太大了 64 位的 61M, 32 位的 59M. 但是唧唧用不到所有的功能所以一直用着旧版本的只有 21M 的 FFmpeg 苟命. 但是由于编码更新了, 旧的也出现了问题在此不得不更新 FFmpeg 了.\n直接更新存在一个流量费贵的问题, 59M 的压缩后也有 18M 在算上几万次的下载请求. 流量费非常昂贵.\n于是想到了编译一个只有唧唧需要功能的 FFmpeg 给唧唧使用. 就有了这篇文章~ 编译完的只有 3M 哟!~\n如何编译精简版 FFmpeg\r如果你只需要 FFmpeg 的某些功能而不需要全部的功能, 可以通过编译精简版来减少二进制文件的大小。下面是我在编译精简版 FFmpeg 时的一些经验与操作步骤。\n唧唧处理视频需要的模块\rflv 解流|混流、MP4 混流、h264 解码器、HEVC 解码、文件协议、mp3 编码 (libmp3lame)\n环境安装\r首先, 需要安装交叉编译工具, 下面是必要的工具包\napt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64-tools yasm lua5.2 libtool automake autoconf autopoint make gettext pkg-config 编译 libmp3lame\r下载地址: LAME (Lame Aint an MP3 Encoder)\n备用下载: lame-3.100.tar.gz\n我们选择使用 MP3 编码器是 libmp3lame\nFFmpeg 4.1.2 需要 3.98.3 以上版本的, 首先需要编译 libmp3lame 3.100\nlibmp3lame 3.100 版本编译 Windows 版本会遇到一个错误\nCannot export lame_init_old: symbol not defined bug 跟踪连接 https://sourceforge.net/p/lame/bugs/487/\nVersion 3.100 breaks Windows compatibility when using libiconv since frontend/parse.c now depends on langinfo.h. I\u0026#39;m using the MinGW-w64 (GCC-compatible) compiler. Looks better now, except for this error: Cannot export lame_init_old: symbol not defined But I was able to build both static and shared libraries for Windows after removing lame_init_old from include/libmp3lame.sym. 大致解释就是编辑 include/libmp3lame.sym 文件, 把 lame_init_old 删除就可以编译了\nlibmp3lame 编译参数\r./configure --host=i686-w64-mingw32 --enable-static=yes --enable-shared=no make -j sudo make install 编译 FFmpeg\r在编译 FFmpeg 时, 我们需要配置选项来指定要编译的功能, 以便精简不需要的部分。\nFFmpeg 大部分参数是由 TG 群的 Xuan 提供的, 感谢\n# 配置 ./configure --arch=x86 --target-os=mingw32 --cross-prefix=i686-w64-mingw32- --disable-debug --disable-doc --disable-ffplay --disable-ffprobe --enable-static --disable-shared --disable-network --disable-autodetect --disable-decoders --enable-gpl --enable-version3 --enable-decoder=h264,hevc,aac*,mp3*,mp4 --disable-encoders --disable-demuxers --enable-demuxer=concat,mov,m4v,flv,mp3 --disable-muxers --enable-muxer=flv,mp4,mp3 --enable-encoder=libmp3lame,mp3 --disable-parsers --enable-parser=h264,hevc --disable-protocols --enable-protocol=concat,file --disable-bsfs --enable-bsf=h264_metadata,h264_mp4toannexb,hevc_mp4toannexb,hevc_metadata --disable-filters --enable-filter=concat,aresample --disable-iconv --enable-small --enable-libmp3lame --extra-ldflags=\u0026#34;-L/usr/local/lib\u0026#34; --extra-cflags=\u0026#34;-I/usr/local/include\u0026#34; # 编译 make -j 注意事项\rlibmp3lame 交叉编译\n如果你没有交叉编译 libmp3lame, 而是直接使用了 Linux 下的 .so 文件, 那么会出现这错误。请确保交叉编译 libmp3lame, 并将其用于 Windows 编译。\nundefined reference to \u0026#39;_lame_set_VBR_quality\u0026#39; /usr/local/lib/libmp3lame.so is your native lame library (for linux). you should cross-compile lame for windows 原文\nlame_set_VBR_quality (again)\nBest config for ffmpeg to convert MP3 file only\nHow to compile ffmpeg to get only mp3 and mp4 support\n","date":"2019-04-02T00:40:00+08:00","permalink":"https://blog.acesheep.com/p/compile-win32-ffmpeg-in-ubuntu-on-windows-10-subsystem-for-jijidown/","title":"在 Windows 10 子系统 Ubuntu 中编译 Win32 版本 FFmpeg 给唧唧特供"},{"content":"A very nice router/switch/NAS/miniserver hackable \u0026amp; extensible board powered by MT7621A.\nPROJECT OWNER\nbenn huang\nShenzhen, China\n$28,656 USD total funds raised\n241% funded on September 11, 2015\nFeatures\rThe board uses MT7621 high performance router SoC, supports open source OpenWRT OS. The board\u0026rsquo;s dimension is relatively small 16cm x 10cm, about three credit card in a row.\nThe key features are:\nMT7621A Dual-Core 880Mhz (4 threads) 256MB Memory (up to 512MB) 2.4G WiFi (supports IEEE 802.11b/g/n, up to 300Mbps) 5G WiFi (supports IEEE 802.11a/n/ac, up to 867Mbps) WAN port x2, LAN port x4(both are 1000Mbps) SATA 3.0 x2(supports 3.5 inch HDD) USB3.0 x1 microSD x1 RTC battery for storage application 30 Expansion Ports(Including USB, I2S, JTAG, UART, GPIO) 16MB SPI NOR Flash(Optional for bigger size Nand Flash) 4-pins serial debug port RF Antenna Connector x4 WPS/GPIO Key x1, Reset Key x1 Power LED x1, SATA LED x 1, WiFi LED x 2, LAN LED x4 Why did we decide to develop the WiTi board?\rI hope to be able to deploy a reliable and low-power storage server, which is used to host the company’s CMS and git code repositories instead of the heavy, high energy consumption PC server. Similarly, I also hope that families have their own storage server to share their beautiful music and wonderful pictures and videos anywhere at any time. I have used some of the other storage products before. Although some of them are very good, but none of them can meet my needs. I need a product which can meet my needs and at the same time I can freely modify it . When I saw the specification of MT7621,I felt very excited. I believe I can build a team to develop such an open platform. So people with similar ideas can concentrate on developing the real final products without wasting too much time!\nWhat\u0026rsquo;s the status of the board?\rWe have manufactured the WiTi board twice 10pcs for each before the campaign begin.\nYour browser doesn't support HTML5 video. Here is a\rlink to the video instead.\rNow, We use our WiTi board as router in office everyday(I\u0026rsquo;m so proud!).\nWe need some funds to do a massive production, design our own cases, software, etc. The hardware and firmware are all ready and carefully tested. We create our official forum discussing our products. We will open source our software and schematics, some of them already published at our own ftp server. You can even make your firmware right now! We will keep improving our docs \u0026amp; Wikis.\nWhat can be done on the WiTi platform?\rOf course, this board can be used as a good performance router. With the two SATA3 ports on board, we can easily create Soft-Raid1 by mdadm tools. After installing Samba service and NFS service, the board turns into a reliable storage server. We can also install CMS or git code repositories on the board. Wow! This board can provide all functions I need, and the consumption of electricity is very low.\nWhat’s more, WiTi has 30 expansion ports(including USB, JTAG, UART, I2S, GPIO..). We can connect to Arduino by USB extension, so that WiTi can connect to thousands of sensors; we can make WiTi as a nice wireless HiFi with the I2S extension; we can also use the GPIO extension to control electric light, Motor, and so on.\nWhat will you get?\rTransparent Acrylic Case x1\nWhen will we start shipping?\rWithin one month after this campaign, and the exact time will be announced on the website (http://mqmaker.com)\nWhere to get technical support?\rE-Mail: support@mqmaker.com\nCommunity: http://forum.mqmaker.com\nTwitter: @mqmaker\nFacebook: @mqmaker\nG+: @mqmaker\nI hope there will be a lot of geeks loving this platform, a lot of fun application will be born here.\nThanks you!\n视频资料\rYouTube 频道\nPeak current with 3.5\u0026rsquo;\u0026rsquo; SATA HDD x2\nYour browser doesn't support HTML5 video. Here is a\rlink to the video instead.\rSample Production for WiTi Board\nYour browser doesn't support HTML5 video. Here is a\rlink to the video instead.\rWorking WiTi Board with Two 3.5\u0026rsquo;\u0026rsquo; SATA HDD. A Nice NAS Router :)\nYour browser doesn't support HTML5 video. Here is a\rlink to the video instead.\r图片资料\r1st witi board for this crowdfunding.\ntop report of WiTi\nOpenWrt with MTK theme\nsamba copy speed without any performance tunning\niperf test with wired ethernet\n相关文件\r在地址栏后增加 WITI, 即可下载文件。例如 /p/witi-board-open-extensible-router-nas-platform/WITI/putty.exe\nWITI ├── MtWrt-18022317-r44-ramips-mt7621-witi-squashfs-sysupgrade.bin ├── MtWrt-18022317-witi.zip ├── WITI-16022302.zip ├── WITI-16031211.zip ├── WITI-16111522.zip ├── openwrt-18.06.1-ramips-mt7621-mqmaker_witi-512m-squashfs-sysupgrade.bin ├── openwrt-WITI-16031211-ramips-mt7621-witi-squashfs-sysupgrade.bin ├── openwrt-WITI-16111522-ramips-mt7621-witi-squashfs-sysupgrade.bin ├── openwrt-ramips-mt7621-witi-squashfs-sysupgrade-2.bin ├── openwrt-ramips-mt7621-witi-squashfs-sysupgrade.bin ├── putty.exe ├── puttygen.exe ├── tftpd32.chm ├── tftpd32.ini └── tftpd64.exe 0 directories, 15 files 原文\nWiTi Board - Open \u0026amp; Extensible Router\u0026amp;NAS Platform\n","date":"2019-03-20T09:36:00+08:00","permalink":"https://blog.acesheep.com/p/witi-board-open-extensible-router-nas-platform/","title":"WiTi Board - Open \u0026 Extensible Router \u0026 NAS Platform"},{"content":"在制作路由器固件过程中, 由于操作不当可能导致路由器变成\u0026quot;砖头\u0026quot;, 无法正常启动。在这种情况下, 我们可以通过串口连接和 TFTP 恢复固件。下面以 WITI 路由器为例, 介绍如何用 TFTP 恢复路由器。\n准备工作\r你需要准备好要烧写的 .bin 文件\n下载并安装 tftpd32 下载地址\n把下载好的固件 .bin 文件复制到 tftpd32 的同级目录下。这一步很重要\n连接好路由器的串口线, 确保你知道 COM 端口和波特率 (在本例中波特率为 57600)\n烧录固件步骤\r连接到路由器的串口\r使用 Putty 连接到路由器的串口, 协议选择 Serial\n在 Putty 配置中设置 COM 端口和波特率 (57600)\n连接进入自己的板子\n进入 CFE (Common Firmware Environment)\r在连接成功后, 执行 reboot 重启路由器。系统会进入 CFE, 它就是一个 bootloader, 类似 u-boot, redboot 之类, 这时会显示一个提示, 在 1~2 秒内等待由 TFTP 上传固件并烧写到 flash 上\n你会看到一个选择菜单, 选择 2 后按 Y 继续\n看到这里, 有一个 server IP, 这个就是我们需要填写 tftpd32 的 ip 地址\n配置 IP 地址\r网线连接到路由器, 配置路由器的 IP 地址和子网掩码, 确保它与本地机器在同一个网段。\n例如, 设置路由器的 IP 为 10.10.10.3。如图填写 IP 地址和子网掩码\n启动 TFTP 服务器\r打开 tftpd32 软件, 选择之前设置的 10.10.10.3 作为服务器 IP\nOK, 现在可以进行烧写了\n烧写固件\r由于之前我们将 .bin 文件放在了 tftpd32 的同级目录下, 输入要烧写的固件文件名称 (如 test.bin), 然后回车开始烧写\n在这里, tftpd32 会使用我们的 test.bin, 会看到 Got it, 表示正在开始烧写过程\n烧写完成后, tftpd32 会显示 done 信息, 表示固件已成功写入路由器的 Flash 存储。\n现在已经成功将 \u0026ldquo;成砖\u0026rdquo; 的路由器恢复正常。此时可以开始重新配置和研究你的路由器了！\n原文\n使用tftpd32烧写内核（拯救你的“砖”）\n","date":"2019-03-19T22:15:00+08:00","permalink":"https://blog.acesheep.com/p/witi-flash-firmware-using-tftpd32/","title":"WITI 使用 tftpd32 烧写固件"},{"content":"KVM 和 QEMU 关系及显卡直通\rKVM\rKVM (Kernel-based Virtual Machine, 即内核级虚拟机) 是一个开源的系统虚拟化模块, 基于 Linux 内核的调度器进行管理, 相对于 Xen, 它的核心代码较少。KVM 已成为学术界主流的虚拟机监控器 (VMM) 之一。KVM 包含一个为处理器提供底层虚拟化支持的可加载核心模块 kvm.ko (Intel 使用 kvm-intel.ko, AMD 使用 kvm-amd.ko)。此外, KVM 还需要一个修改过的 QEMU 软件 (qemu-kvm) 来提供虚拟机的上层控制和界面。\nKVM 的虚拟化要求硬件支持, 如 Intel 的 VT 技术或 AMD 的 SVM 技术, 因此它是基于硬件的完全虚拟化方案。KVM 允许在多个虚拟机中运行与主机系统相同的镜像, 例如 Windows 和 macOS, 每个虚拟机都会拥有独立的虚拟硬件资源, 如网卡、硬盘和图形适配器等。\nKVM 和 QEMU 的关系\rQEMU 是一个独立的虚拟化解决方案, 从某种角度来说, 它并不依赖 KVM。而 KVM 是另一套虚拟化解决方案, 实际上它仅提供对处理器 (如 Intel VT 或 AMD SVM) 的虚拟化特性支持。KVM 本身不包含设备虚拟化及用户空间的虚拟机管理工具, 因此它借用了 QEMU 的代码, 并与 KVM 配合使用, 形成了完整的虚拟化解决方案: KVM + QEMU\n通过 VFIO、KVM 和 QEMU 实现 GPU 直通\r我一直希望使用 CentOS 7 作为主要的操作系统, 但又想使用 Nvidia 显卡玩游戏, 就需要一个 Windows 系统。\n可以通过 VFIO (Virtual Function I/O)、KVM 和 QEMU 这三种开源技术实现 GPU 的直通。这种方法可以让虚拟机使用主机上的显卡, 从而达到接近原生性能的效果。具体来说, 通过 VFIO 技术, 能够将物理显卡从主机系统中 \u0026ldquo;直通\u0026rdquo; 给虚拟机, 使得虚拟机能够直接访问该显卡, 运行图形密集型应用或游戏。\n准备工作\r硬件\rCPU Intel i7-8700K 需要支持 VT-d (Intel Virtualization Technology for Directed I/O) 以及VT-x 内存 40G RAM (目前是 8G + 48G) 显卡 ASUS ROG-STRIX-RTX2080TI-O11G-GAMING 虚拟机使用 (显卡需要 UEFI 支持) 新显卡都支持, 可以在 这里查询 主板 ASUS Strix Z370-F 软件\rCentOS 7.6 KVM 套件 qemu-kvm 需要 2.9.0 以上版本 Windows 10 1809 版本 (RTX 显卡需要最新的 win 10) 软件配置\r从内核中禁用 nouveau 驱动 PCI 直通 (VFIO/IOMMU) KVM 网桥 qemu-kvm: could not open disk image ' ': Permission denied 权限问题 虚拟机 CPU 分配 (虚拟物理核心和虚拟线程的设置) 下载 VFIO 驱动程序 虚拟机中 N 卡驱动 43 错误代码 (N 卡检测到在虚拟机中运行会出现这个错误) 添加物理磁盘到虚拟机 配置流程\r检查硬件是否满足要求 准备系统环境 安装 KVM 套件 检查是否正确加载 kvm 模块 禁用 nouveau 驱动 开启 IOMMU 支持 设置 vfio-pci 设备 (IOMMU) 设置网桥 更新 qemu-kvm 到 2.9.0 以上版本 分配虚拟机磁盘 配置 qemu-kvm 权限 安装虚拟机 设置虚拟机 CPU 核心 分配鼠标键盘给虚拟机 虚拟机 win VFIO 驱动程序安装 给虚拟机添加显卡 解决显卡 43 错误代码 给虚拟机添加物理磁盘 1. 检查硬件是否满足要求\r验证 CPU 是否支持 KVM\n如果结果中有 vmx (Intel VT 虚拟化技术) 或 svm (SVM 安全虚拟化技术的 AMD 处理器, 也可以叫 AMD-V) 字样, 就说明 CPU 的支持的。如果没配置过可以在 BIOS 中启用。如果还没有任何的输出, 说明你的 cpu 不支持, 将无法使用 KVM 虚拟机。\negrep \u0026#39;(vmx|svm)\u0026#39; /proc/cpuinfo flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt 2. 准备系统环境 安装 KVM 套件\r安装基础工具\nyum install net-tools vim wget kernel-devel epel-release yum update yum install htop 安装 KVM 套件\nyum install virt-manager qemu-img qemu-kvm qemu-kvm-tools libvirt virt-install bridge-utils 添加 virtio-win 源并安装 virtio-win\nwget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo -O /etc/yum.repos.d/virtio-win.repo yum install virtio-win kvm 相关安装包及其作用\rqemu-kvm 主要的 KVM 程序包 python-virtinst 创建虚拟机所需要的命令行工具和程序库 virt-manager GUI 虚拟机管理工具 virt-top 虚拟机统计命令 virt-viewer GUI 连接程序, 连接到已配置好的虚拟机 libvirt C 语言工具包, 提供 libvirt 服务 libvirt-client 虚拟客户机提供的 C 语言工具包 virt-install 基于 libvirt 服务的虚拟机创建命令 bridge-utils 创建和管理桥接设备的工具 3. 检查是否正确加载 kvm 模块\r一共会输出三条, 三条都必须满足\n[root@corehadoop31 ~]# lsmod |grep kvm kvm_intel 170181 3 kvm 554609 1 kvm_intel irqbypass 13503 1 kvm 4. 禁用 nouveau 驱动\rCentOS 7 文件路径在 /usr/lib/modprobe.d/dist-blacklist.conf 和 /lib/modprobe.d/dist-blacklist.conf 是同一个文件, 修改其中一个即可。\n其他路径如 /etc/modprobe.d/blacklist.conf 也可以使用, 下面是禁用相关驱动的命令\necho \u0026#34;blacklist radeon\u0026#34; \u0026gt;\u0026gt; /etc/modprobe.d/blacklist.conf echo \u0026#34;blacklist nouveau\u0026#34; \u0026gt;\u0026gt; /etc/modprobe.d/blacklist.conf echo \u0026#34;blacklist nvidia\u0026#34; \u0026gt;\u0026gt; /etc/modprobe.d/blacklist.conf 本段文章教程 两篇文章结合使用\ncentos 7禁用nouveau及安装NVIDIA显卡驱动\nCentOS中禁用nouveau驱动\n在配置文件中禁用 nouveau\r编辑文件禁用 nouveau\nvim /usr/lib/modprobe.d/dist-blacklist.conf 在文件最后添加以下内容\nblacklist nouveau options nouveau modeset=0 备份并重建 initramfs 镜像\r# 备份镜像 mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak # 重建镜像 dracut -v /boot/initramfs-$(uname -r).img $(uname -r) 重启并检查是否禁用成功\rreboot # 重启之后检查是否禁用成功, 应该返回空 lsmod | grep nouveau 扩展阅读\r禁用 Nvidia 的 libGL 驱动。Using integrated graphics card for display and Nvidia card for GPU\n注释掉 /etc/ld.so.conf.d/nvidia.conf 文件中的内容\n# /etc/ld.so.conf.d/nvidia.conf provided by http://elrepo.org /usr/lib64/nvidia /usr/lib64/vdpau /usr/lib/nvidia /usr/lib/vdpau 5. 开启 IOMMU 支持\rCentOS7 minimal kvm iommu 辅助虚拟化 vt-x (用于pci透传)\n根据 CPU 类型, 启用 IOMMU 支持:\nIntel CPU: intel_iommu=on AMD CPU: amd_iommu=on 方法一\r我用方法一失败了, 很多文章都是方法一\n编辑 GRUB 配置文件\rvim /etc/default/grub 将 GRUB_CMDLINE_LINUX_DEFAULT 或 GRUB_CMDLINE_LINUX 中添加 intel_iommu=on\nGRUB_CMDLINE_LINUX_DEFAULT=\u0026#34;... intel_iommu=on ...\u0026#34;\r或\rGRUB_CMDLINE_LINUX=\u0026#34;... intel_iommu=on ...\u0026#34; 更新 GRUB 配置\rgrub2-mkconfig -o /boot/grub2/grub.cfg 重启系统\rreboot 验证是否成功启用 IOMMU\rcat /proc/cmdline | grep intel_iommu=on 查看系统日志, 确认 IOMMU 是否启用\rdmesg | grep -E \u0026#34;DMAR|IOMMU\u0026#34; 如果方法一 失败, 应该是启动的时候并没有使用 /boot/grub2/grub.cfg, 可以用方法二\n方法二\r查找 grub.cfg 文件\rfind / -name \u0026#34;grub.cfg\u0026#34; 发现还有 /boot/efi/EFI/centos/grub.cfg 这个文件, 继续执行以下操作。\n编辑该 grub.cfg 文件\rvim /boot/efi/EFI/centos/grub.cfg 对照 /boot/grub2/grub.cfg 把 intel_iommu=on 添加到相应位置\n文件里 linuxefi 出现了 3 次, 在每个 linuxefi 行添加 intel_iommu=on, 然后保存退出\n重启系统并验证配置是否生效\n6. 设置 vfio-pci 设备 (IOMMU)\r配置 VFIO-PCI\r查找设备的 PCI 信息\rlspci -nn | grep -i nvidia 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1) 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f7] (rev a1) 01:00.2 USB controller [0c03]: NVIDIA Corporation Device [10de:1ad6] (rev a1) 01:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device [10de:1ad7] (rev a1) 配置 VFIO 设备\r编辑 vim /etc/modprobe.d/vfio.conf 文件, 添加以下内容 (根据你的设备的 vendor-ID 和 device-ID)\n# create new: for [ids=***], specify [vendor-ID:device-ID] 没有 ACS 的需要把整组都放入 options vfio-pci ids=10de:1e07,10de:10f7,10de:1ad6,10de:1ad7 创建配置文件以加载 VFIO 模块\recho \u0026#39;vfio-pci\u0026#39; \u0026gt; /etc/modules-load.d/vfio-pci.conf 重启系统\rreboot 验证 VFIO 是否成功加载\r使用 dmesg 查看日志, 确认 VFIO 设备是否已加载\ndmesg | grep -i vfio \u0026gt;\u0026gt;# dmesg | grep -i vfio [ 1.423654] VFIO - User Level meta-driver version: 0.3 [ 1.435816] vfio_pci: add [10de:1e07[ffff:ffff]] class 0x000000/00000000 [ 1.447858] vfio_pci: add [10de:10f7[ffff:ffff]] class 0x000000/00000000 扩展阅读!!! 注意事项\rPci passthrough #Verify IOMMU isolation\n验证 IOMMU 是否正确隔离\r要让 PCI passthrough 正常工作, 确保每个 PCI 设备都在独立的 IOMMU 组内。使用以下命令查看 IOMMU 组信息\nfind /sys/kernel/iommu_groups/ -type l /sys/kernel/iommu_groups/0/devices/0000:00:00.0 /sys/kernel/iommu_groups/1/devices/0000:00:01.0 /sys/kernel/iommu_groups/1/devices/0000:01:00.0 /sys/kernel/iommu_groups/1/devices/0000:01:00.1 /sys/kernel/iommu_groups/2/devices/0000:00:02.0 /sys/kernel/iommu_groups/3/devices/0000:00:16.0 /sys/kernel/iommu_groups/4/devices/0000:00:1a.0 /sys/kernel/iommu_groups/5/devices/0000:00:1b.0 /sys/kernel/iommu_groups/6/devices/0000:00:1c.0 /sys/kernel/iommu_groups/7/devices/0000:00:1c.5 /sys/kernel/iommu_groups/8/devices/0000:00:1c.6 /sys/kernel/iommu_groups/9/devices/0000:00:1c.7 /sys/kernel/iommu_groups/9/devices/0000:05:00.0 /sys/kernel/iommu_groups/10/devices/0000:00:1d.0 /sys/kernel/iommu_groups/11/devices/0000:00:1f.0 /sys/kernel/iommu_groups/11/devices/0000:00:1f.2 /sys/kernel/iommu_groups/11/devices/0000:00:1f.3 /sys/kernel/iommu_groups/12/devices/0000:02:00.0 /sys/kernel/iommu_groups/12/devices/0000:02:00.1 /sys/kernel/iommu_groups/13/devices/0000:03:00.0 /sys/kernel/iommu_groups/14/devices/0000:04:00.0 IOMMU 支持 ACS\r要确保 PCI 设备能正常进行 passthrough, 每个设备需要提供专用的 IOMMU 组。为此, 你的处理器必须支持 ACS (Access Control Services)\n支持 ACS 的处理器 (Xeon、Core 系列)\nIntel Xeon 处理器 (E3、E5 系列) 大多支持 ACS, 但某些型号 (如 Xeon E3-1200) 不支持。 Intel Core 处理器: 只有一些型号支持 ACS, 常见的支持型号包括 Haswell-E (LGA2011-v3) i7-5960X (8-core, 3/3.5GHz) i7-5930K (6-core, 3.2/3.8GHz) i7-5820K (6-core, 3.3/3.6GHz) Ivy Bridge-E (LGA2011) i7-4960X (6-core, 3.6/4GHz) i7-4930K (6-core, 3.4/3.6GHz) i7-4820K (4-core, 3.7/3.9GHz) Sandy Bridge-E (LGA2011) i7-3960X (6-core, 3.3/3.9GHz) i7-3970X (6-core, 3.5/4GHz) i7-3930K (6-core, 3.2/3.8GHz) i7-3820 (4-core, 3.6/3.8GHz) 7. 设置网桥\r配置宿主机网络\nBridge 模式配置\rBridge 模式即虚拟网桥, 允许虚拟机与宿主机和网络中的其他设备进行通信, 使虚拟机获得独立的 IP 地址。\n桥接网络 (也叫物理设备共享) 被用作把一个物理设备复制到一台虚拟机。网桥多用作高级设置, 特别是主机多个网络接口的情况。\n┌─────────────────────────┐ ┌─────────────────┐ │ HOST │ │Virtual Machine 1│ │ ┌──────┐ ┌───────┐ │ │ ┌──────┐ │ │ │ br0 │──┬───│ vnet0 │─│─ ─ ─ │ │ br0 │ │ │ └──────┘ │ └───────┘ │ │ └──────┘ │ │ │ │ │ └─────────────────┘ │ │ │ ┌───────┐ │ ┌─────────────────┐ │ ┌──────┐ └───│ vnet1 │─│─ │Virtual Machine 2│ │ │ eno0 │ └───────┘ │ │ │ ┌──────┐ │ │ └──────┘ │ ─ ─ │ │ br0 │ │ │ ┌──────┐ │ │ └──────┘ │ │ │ eno1 │ │ └─────────────────┘ │ └──────┘ │ └─────────────────────────┘ 修改网卡配置文件\r修改前一定要备份!!!\n你需要修改宿主机的物理网卡配置文件, 通常位于 /etc/sysconfig/network-scripts/ 目录下, 如 ifcfg-eno1 宿主机的物理网卡配置文件\n# cat ifcfg-eno1 TYPE=\u0026#34;Ethernet\u0026#34; PROXY_METHOD=\u0026#34;none\u0026#34; BROWSER_ONLY=\u0026#34;no\u0026#34; BOOTPROTO=\u0026#34;dhcp\u0026#34; DEFROUTE=\u0026#34;yes\u0026#34; IPV4_FAILURE_FATAL=\u0026#34;no\u0026#34; IPV6INIT=\u0026#34;yes\u0026#34; IPV6_AUTOCONF=\u0026#34;yes\u0026#34; IPV6_DEFROUTE=\u0026#34;yes\u0026#34; IPV6_FAILURE_FATAL=\u0026#34;no\u0026#34; IPV6_ADDR_GEN_MODE=\u0026#34;stable-privacy\u0026#34; NAME=\u0026#34;eno1\u0026#34; UUID=\u0026#34;242b3d4d-37a5-4f46-b072-55554c185ecf\u0026#34; DEVICE=\u0026#34;eno1\u0026#34; ONBOOT=\u0026#34;yes\u0026#34; ZONE=nas BRIDGE=\u0026#34;br0\u0026#34; # 指定桥接网卡的名称 配置桥接网卡\r在同一目录下创建或修改桥接网卡配置文件 ifcfg-br0。确保配置宿主机的 IP 和路由器的网关\n# cat ifcfg-br0 BOOTPROTO=static DEFROUTE=yes PEERDNS=yes PEERROUTES=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_PEERDNS=yes IPV6_PEERROUTES=yes IPV6_FAILURE_FATAL=no NAME=br0 UUID=242b3d4d-37a5-4f46-b072-55554c185ecf DEVICE=br0 ONBOOT=yes IPV6_PRIVACY=rfc3041 TYPE=bridge # 将制定为桥接类型 IPADDR=192.168.188.133 # 设置IP地址 PREFIX=24 # 设置子网掩码 GATEWAY=192.168.188.1 # 设置网关 激活网卡和桥接网卡\r使用 ifup 激活网卡\nifup eno1 # 激活物理网卡 ifup br0 # 激活桥接网卡 重启网络服务\r两种重启网络的方法\nsystemctl restart network.service service network restart 检查网桥配置\r使用 brctl show 命令检查网桥设置\nbrctl show bridge name bridge id STP enabled interfaces br0 8000.3863bb44cf6c no vnet0 virbr0 8000.525400193f0f yes virbr0-nic 8. 更新 qemu-kvm 到 2.9.0 以上版本\rUpdate QEMU: CentOS 7 : KVM : GPU Passthrough : Server World\n查看当前 QEMU 版本\r[root@dlp ~]# /usr/libexec/qemu-kvm -version QEMU emulator version 1.5.3 (qemu-kvm-1.5.3-141.el7_4.6), Copyright (c) 2003-2008 Fabrice Bellard 安装 QEMU EV 版本\r[root@dlp ~]# yum -y install centos-release-qemu-ev 禁用默认的 QEMU 仓库\r# disable usually [root@dlp ~]# sed -i -e \u0026#34;s/enabled=1/enabled=0/g\u0026#34; /etc/yum.repos.d/CentOS-QEMU-EV.repo 安装 qemu-kvm-ev 包\r# for this installing, [qemu-kvm] package is replaced to [qemu-kvm-ev] package [root@dlp ~]# yum --enablerepo=centos-qemu-ev -y install qemu-kvm-ev 重启 libvirtd 服务\r[root@dlp ~]# systemctl restart libvirtd 确认 QEMU 版本更新成功\r[root@dlp ~]# /usr/libexec/qemu-kvm -version QEMU emulator version 2.9.0(qemu-kvm-ev-2.9.0-16.el7_4.13.1) Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers 验证支持的机器列表\r查看是否包含 q35\n# verify q35 is included like follows [root@dlp ~]# /usr/libexec/qemu-kvm -machine help Supported machines are: pc RHEL 7.4.0 PC (i440FX + PIIX, 1996) (alias of pc-i440fx-rhel7.4.0) pc-i440fx-rhel7.4.0 RHEL 7.4.0 PC (i440FX + PIIX, 1996) (default) pc-i440fx-rhel7.3.0 RHEL 7.3.0 PC (i440FX + PIIX, 1996) pc-i440fx-rhel7.2.0 RHEL 7.2.0 PC (i440FX + PIIX, 1996) pc-i440fx-rhel7.1.0 RHEL 7.1.0 PC (i440FX + PIIX, 1996) pc-i440fx-rhel7.0.0 RHEL 7.0.0 PC (i440FX + PIIX, 1996) rhel6.6.0 RHEL 6.6.0 PC rhel6.5.0 RHEL 6.5.0 PC rhel6.4.0 RHEL 6.4.0 PC rhel6.3.0 RHEL 6.3.0 PC rhel6.2.0 RHEL 6.2.0 PC rhel6.1.0 RHEL 6.1.0 PC rhel6.0.0 RHEL 6.0.0 PC q35 RHEL-7.4.0 PC (Q35 + ICH9, 2009) (alias of pc-q35-rhel7.4.0) pc-q35-rhel7.4.0 RHEL-7.4.0 PC (Q35 + ICH9, 2009) pc-q35-rhel7.3.0 RHEL-7.3.0 PC (Q35 + ICH9, 2009) none empty machine 9. 分配虚拟机磁盘\r创建虚拟磁盘\r指定磁盘格式为 raw, 50G 为虚拟大小, 并不实际占用物理空间。\nqemu-img create -f raw /root/kvm/win10.raw 50G 查看磁盘信息\rqemu-img info /root/kvm/win10.raw image: /root/kvm/win10.raw file format: raw virtual size: 50G (53687091200 bytes) disk size: 0 virtual size 是虚拟磁盘的总大小 disk size 表示实际已占用的空间 10. 配置 qemu-kvm 权限\r在使用 QEMU-KVM 时, 可能会遇到 qemu-kvm: could not open disk image ' ': Permission denied 的错误。由于 libvirtd 对权限管理较严格, 可以通过以下两种方法解决此问题。\nqemu-kvm: could not open disk image \u0026rsquo; \u0026lsquo;: Permission denied\n方法一: 修改 QEMU 配置文件\r我使用方法一, 但不推荐\n注意: 这种方法可能会带来安全隐患, 不推荐用于生产环境。\n编辑 /etc/libvirt/qemu.conf 文件, 将 user 和 group 设置为 root 用户\n# The user for QEMU processes run by the system instance. It can be # specified as a user name or as a user id. The qemu driver will try to # parse this value first as a name and then, if the name doesn\u0026#39;t exist, # as a user id. # # Since a sequence of digits is a valid user name, a leading plus sign # can be used to ensure that a user id will not be interpreted as a user # name. # # Some examples of valid values are: # # user = \u0026#34;qemu\u0026#34; # A user named \u0026#34;qemu\u0026#34; # user = \u0026#34;+0\u0026#34; # Super user (uid=0) # user = \u0026#34;100\u0026#34; # A user named \u0026#34;100\u0026#34; or a user with uid=100 # user = \u0026#34;root\u0026#34; # The group for QEMU processes run by the system instance. It can be # specified in a similar way to user. group = \u0026#34;root\u0026#34; # Whether libvirt should dynamically change file ownership # to match the configured user/group above. Defaults to 1. # Set to 0 to disable file ownership changes. #dynamic_ownership = 1 重启 libvirtd 服务\n[root@dev1 ~]# service libvirtd restart Stopping libvirtd daemon: [ OK ] Starting libvirtd daemon: [ OK ] 方法二: 设置 ACL 权限\r使用 getfacl 检查文件夹当前的 ACL 权限\nmurlock@asus:~/kubernet $ sudo getfacl -e /home/murlock getfacl: Removing leading \u0026#39;/\u0026#39; from absolute path names # file: home/murlock # owner: murlock # group: murlock user::rwx user:libvirt-qemu:--x # effective:--- group::--- # effective:--- mask::--- other::--- 为 libvirt-qemu 用户添加执行权限\nmurlock@asus:~/kubernet $ sudo setfacl -m u:libvirt-qemu:rx /home/murlock 验证权限设置是否生效\n应看到类似以下内容 user:libvirt-qemu:r-x\nmurlock@asus:~/kubernet $ sudo getfacl -e /home/murlock getfacl: Removing leading \u0026#39;/\u0026#39; from absolute path names # file: home/murlock # owner: murlock # group: murlock user::rwx user:libvirt-qemu:r-x # effective:r-x group::--- # effective:--- mask::r-x other::--- 11. 安装虚拟机\r虚拟机先创建一个可以正常运行的之后再为它添加 PCI 直通设备\n特别需要注意的参数 --machine q35 和 --features kvm_hidden=on, 这有助于更好地支持 PCI 直通。\nvirt-install \\ --name Win10 \\ --memory 16384 \\ --cpu host \\ --vcpus 8 \\ --disk path=/root/kvm/win10.raw \\ --network bridge=br0,model=\u0026#39;e1000\u0026#39; \\ --cdrom=/root/kvm/win10.iso \\ --boot cdrom \\ --virt-type kvm \\ --vnc \\ --vncport=5902 \\ --vnclisten=0.0.0.0 \\ --os-type=windows \\ --features kvm_hidden=on \\ --machine q35 参数含义\n--name Win10: 虚拟机名称为 Win10 --memory 16384: 分配 16 GB 内存 --cpu host: 使用宿主机的 CPU 配置 --vcpus 8: 分配 8 个虚拟 CPU (八路) --disk path=/root/kvm/win10.raw: 指定虚拟机磁盘文件 --network bridge=br0,model='e1000': 网络桥接方式, br0 为桥接网络接口 --cdrom=/root/kvm/win10.iso: 指定安装光盘镜像 (Windows 10 安装 ISO) --boot cdrom: 启动虚拟机时从光盘启动 --virt-type kvm: 使用 KVM 虚拟化 --vnc: 启用 VNC 连接 --vncport=5902: 指定 VNC 端口为 5902 --vnclisten=0.0.0.0: 允许任何主机连接 VNC --os-type=windows: 操作系统类型为 Windows --features kvm_hidden=on: 隐藏 KVM 特征, 防止被虚拟机探测 --machine q35: 使用 q35 架构来更好支持 PCI 直通 临时开放 VNC 端口\r临时开放 VNC 端口 5902, 以便通过 VNC 客户端连接虚拟机\nfirewall-cmd --add-port=5902/tcp 安装操作系统\r创建虚拟机后, 可以通过 VNC 客户端 (例如 VNC Viewer) 连接到 192.168.x.xxx:5902 来开始安装 Windows 10\nvirsh 基础命令\rvirsh list --all # 查看所有运行和没有运行的虚拟机 virsh list # 查看在运行的虚拟机 virsh dumpxml vm-name # 查看kvm虚拟机配置文件 virsh start vm-name # 启动kvm虚拟机 virsh shutdown vm-name # 正常关机 virsh destroy vm-name # 非正常关机, 强制关闭虚拟机 (相当于物理机直接拔掉电源) virsh undefine vm-name # 删除vm的配置文件 ls /etc/libvirt/qemu # 查看删除结果, Centos-6.6的配置文件被删除, 但磁盘文件不会被删除 virsh define file-name.xml # 根据配置文件定义虚拟机 virsh suspend vm-name # 挂起, 终止 virsh resumed vm-name # 恢复被挂起的虚拟机 virsh autostart vm-name # 开机自启动vm virsh console \u0026lt;虚拟机名称\u0026gt; # 连接虚拟机 virsh start centos72 # 虚拟机开启 (启动) virsh reboot centos72 # 虚拟机重新启动 virsh shutdown centos72 # 虚拟机关机 virsh destroy centos72 # 强制关机 (强制断电) virsh suspend centos72 # 暂停 (挂起) KVM 虚拟机 virsh resume centos72 # 恢复被挂起的 KVM 虚拟机 virsh undefine centos72 # 该方法只删除配置文件, 磁盘文件未删除 virsh autostart centos72 # 随物理机启动而启动 (开机启动) virsh autostart --disable centos72 # 取消标记为自动开始 (取消开机启动) 12. 设置虚拟机 CPU 核心\rWhy does my Windows 7 VM running under Linux\u0026rsquo; KVM not use all the virtual processors?\n在使用 KVM 创建虚拟机时, 默认的 CPU 核心配置可能不完全满足需求, 特别是对于多核虚拟机。\nKVM 默认将 vcpus 设置为多路单核单线程的方式, 上一个步骤的 --vcpus 8 含义为分配 8 个虚拟 CPU (8 个处理器, 每个处理器单核单线程), 但我们预期的是单路四核心双线程或者是单路八核心单线程\n而普通版本系统最多支持双路 CPU 的配置, 多于的 CPU 识别不出来。就算识别出来了, 在多任务调度上 8 个处理器也没有 8 核心的效率高\n修改 CPU 拓扑结构, 设置为单路处理器 8 核心单线程, 这样可以解决问题\n查看主机的 CPU 拓扑结构\r在 libvirt 0.8.3 以上, 通过 virsh capabilities 命令, 可以查看主机 CPU 拓扑结构。\nvirsh capabilities | grep topology 这将列出主机的 CPU 核心和线程拓扑。例如\n\u0026lt;topology sockets=\u0026#39;1\u0026#39; cores=\u0026#39;8\u0026#39; threads=\u0026#39;1\u0026#39;/\u0026gt; 这些数字指的是处理器数 (sockets)、每个处理器核心数 (cores) 和每核心线程数 (threads)。\n修改虚拟机的 CPU 配置\r要让虚拟机使用更多的 CPU 核心和线程, 可以修改虚拟机的 XML 配置文件。以下是如何修改虚拟机 CPU 配置的方法。\n打开虚拟机的 XML 文件, 路径为 /etc/libvirt/qemu/ 下的虚拟机配置文件 (例如: Win10.xml), 修改 vcpu 和 cpu 部分。\n\u0026lt;vcpu placement=\u0026#39;static\u0026#39;\u0026gt;8\u0026lt;/vcpu\u0026gt; \u0026lt;cpu mode=\u0026#39;host-model\u0026#39; check=\u0026#39;partial\u0026#39;\u0026gt; \u0026lt;model fallback=\u0026#39;allow\u0026#39;/\u0026gt; \u0026lt;topology sockets=\u0026#39;1\u0026#39; cores=\u0026#39;8\u0026#39; threads=\u0026#39;1\u0026#39;/\u0026gt; \u0026lt;/cpu\u0026gt; vcpu: 设置虚拟 CPU 数量为 8 topology sockets='1' cores='8' threads='1': 设置虚拟机使用 1 个处理器, 每个处理器有 8 个核心, 且每个核心为单线程 直通模式\r我使用此方法\n如果你需要使用 CPU 直通模式, 可以配置为\n\u0026lt;cpu mode=\u0026#39;host-passthrough\u0026#39;\u0026gt; \u0026lt;topology sockets=\u0026#39;1\u0026#39; cores=\u0026#39;4\u0026#39; threads=\u0026#39;2\u0026#39;/\u0026gt; \u0026lt;feature policy=\u0026#39;disable\u0026#39; name=\u0026#39;hypervisor\u0026#39;/\u0026gt; \u0026lt;/cpu\u0026gt; 应用配置\r修改完 XML 文件后, 使用以下命令重新定义虚拟机配置\nvirsh define Win10.xml 这会使新的 CPU 配置生效\n13. 分配鼠标键盘给虚拟机\rAdding USB Device Pass-through\n在 KVM 中, 可以通过 USB 设备直通 (USB pass-through) 将鼠标、键盘等设备分配给虚拟机。此操作通常需要使用 USB 2.0 或更低版本的协议。\n获取设备的供应商 ID 和产品 ID\r首先, 使用 lsusb 命令列出所有的 USB 设备, 并找到鼠标和键盘对应的供应商 ID 和产品 ID。例如\n$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 005 Device 012: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller Bus 005 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub 如果想要选择 Broadcom 公司提供的蓝牙控制器, 供应商 ID 为 0a5c, 产品 ID 为 2110\n添加 USB 设备直通\r有两种方式可以将 USB 设备添加到虚拟机中: 动态添加 (Hot Add) 和 静态添加 (Static Add)\n动态添加\r首先, 创建一个只包含设备信息的 XML 文件, 内容如下\n\u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;usb\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;source\u0026gt; \u0026lt;vendor id=\u0026#39;0x0a5c\u0026#39;/\u0026gt; \u0026lt;product id=\u0026#39;0x2110\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;/hostdev\u0026gt; 然后, 通过 virsh 命令动态添加设备到虚拟机中\nvirsh attach-device \u0026lt;guestname\u0026gt; \u0026lt;our-device-xml-file\u0026gt; 要分离设备, 可以使用以下命令\n# work with it in the guest virsh detach-device \u0026lt;guestname\u0026gt; \u0026lt;our-device-xml-file\u0026gt; 静态添加\r将设备信息直接写入虚拟机的 XML 配置文件中。打开虚拟机的 XML 文件 (例如: Win10.xml), 并在 \u0026lt;devices\u0026gt; 部分中添加 USB 设备\n\u0026lt;domain type=\u0026#39;kvm\u0026#39;\u0026gt; \u0026lt;name\u0026gt;Win10\u0026lt;/name\u0026gt; ... \u0026lt;devices\u0026gt; ... \u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;usb\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;source\u0026gt; \u0026lt;vendor id=\u0026#39;0x046d\u0026#39;/\u0026gt; \u0026lt;product id=\u0026#39;0xc534\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;address type=\u0026#39;usb\u0026#39; bus=\u0026#39;0\u0026#39; port=\u0026#39;2\u0026#39;/\u0026gt; \u0026lt;/hostdev\u0026gt; \u0026lt;/devices\u0026gt; \u0026lt;/domain\u0026gt; 修改完成后, 重新定义虚拟机配置以使更改生效 virsh define Win10.xml\n注意事项\rUSB 设备直通时, 确保设备的协议版本是 USB 2.0 或更低 在虚拟机配置中使用 hostdev 元素时, 设备 ID 必须正确无误 14. 虚拟机 win VFIO 驱动程序安装\r在虚拟机里下载驱动程序并安装\nhttps://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso 之前用 yum install virtio-win 下载的文件在 /usr/share/virtio-win/\n15. 给虚拟机添加显卡\rVirtual Machine configuration\n为了给虚拟机添加显卡, 可以使用 PCI 直通 (PCI Passthrough) 技术, 将主机的显卡设备直通到虚拟机\n获取显卡的 PCI 设备 ID\r首先, 使用 lspci -nn 命令查找系统中所有的 PCI 设备, 筛选出显卡相关信息\nlspci -nn | grep -i nvidia 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1) 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f7] (rev a1) 01:00.2 USB controller [0c03]: NVIDIA Corporation Device [10de:1ad6] (rev a1) 01:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device [10de:1ad7] (rev a1) 这里列出的 PCI 设备序号 01:00.0 01:00.1 01:00.2 01:00.3\n修改虚拟机的 XML 配置文件\r在虚拟机的 XML 配置文件中添加显卡直通配置, 首先找到虚拟机的 XML 配置文件, 路径通常在 /etc/libvirt/qemu/\n01:00.0 这里需要对应配置文件的 \u0026lt;source\u0026gt; 节点里面 \u0026lt;address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/\u0026gt;\n\u0026lt;hostdev\u0026gt; 里面是直通一个 PCI 设备, 例如我这里有 4 个需要穿透到里面, 就要有 4 个\u0026lt;hostdev\u0026gt;\n\u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;pci\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;vfio\u0026#39;/\u0026gt; \u0026lt;source\u0026gt; \u0026lt;address domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x03\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/hostdev\u0026gt; 完整的显卡和相关设备直通配置\n\u0026lt;domain type=\u0026#39;kvm\u0026#39;\u0026gt; \u0026lt;name\u0026gt;Win10\u0026lt;/name\u0026gt; ... \u0026lt;devices\u0026gt; ... \u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;pci\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;vfio\u0026#39;/\u0026gt; \u0026lt;source\u0026gt; \u0026lt;address domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x03\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/hostdev\u0026gt; \u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;pci\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;vfio\u0026#39;/\u0026gt; \u0026lt;source\u0026gt; \u0026lt;address domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x1\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x04\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/hostdev\u0026gt; \u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;pci\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;vfio\u0026#39;/\u0026gt; \u0026lt;source\u0026gt; \u0026lt;address domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x2\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x05\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/hostdev\u0026gt; \u0026lt;hostdev mode=\u0026#39;subsystem\u0026#39; type=\u0026#39;pci\u0026#39; managed=\u0026#39;yes\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;vfio\u0026#39;/\u0026gt; \u0026lt;source\u0026gt; \u0026lt;address domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x3\u0026#39;/\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x06\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/hostdev\u0026gt; \u0026lt;/devices\u0026gt; \u0026lt;/domain\u0026gt; 修改完需要重新定义虚拟机 virsh define Win10.xml\n启动虚拟机\r虚拟机现在应该已经能够使用物理显卡。将显示器视频输出线连接到独立显卡\n可以通过安装相应的驱动程序 (例如 NVIDIA 驱动程序) 来在虚拟机内使用显卡。\nvirsh start Win10 16. 解决显卡 43 错误代码\rFighting error 43 – how to use Nvidia GPU in a virtual machine.\n在安装了 NVIDIA 显卡驱动后, 如果在 Windows 设备管理器中看到 错误代码 43, 这是因为从 NVIDIA 驱动程序版本 337.88 开始, NVIDIA 会检测虚拟机管理程序 (如 KVM) 并禁用驱动, 导致该错误。\n为了解决这个问题, 可以通过修改虚拟机的 XML 配置文件来隐藏虚拟化特性, 使其不被 NVIDIA 驱动检测到\n修改 \u0026lt;domain\u0026gt; 标签\r修改虚拟机 XML 配置, 路径通常在 /etc/libvirt/qemu/\n找到第一行\n\u0026lt;domain type=\u0026#39;kvm\u0026#39;\u0026gt; 改为\n\u0026lt;domain type=\u0026#39;kvm\u0026#39; xmlns:qemu=\u0026#39;http://libvirt.org/schemas/domain/qemu/1.0\u0026#39;\u0026gt; 启用隐藏 KVM\r找到 \u0026lt;features\u0026gt; 标签, 添加 \u0026lt;kvm\u0026gt;\u0026lt;hidden state='on'/\u0026gt;\u0026lt;/kvm\u0026gt; 来隐藏 KVM 特性\n\u0026lt;features\u0026gt; ... \u0026lt;kvm\u0026gt; \u0026lt;hidden state=\u0026#39;on\u0026#39;/\u0026gt; \u0026lt;/kvm\u0026gt; \u0026lt;/features\u0026gt; 修改 CPU 配置\r在 \u0026lt;devices\u0026gt; 标签的末尾, 添加以下 qemu:commandline 配置, 以禁用虚拟化扩展并隐藏虚拟机特征\n\u0026lt;/devices\u0026gt; \u0026lt;qemu:commandline\u0026gt; \u0026lt;qemu:arg value=\u0026#39;-cpu\u0026#39;/\u0026gt; \u0026lt;qemu:arg value=\u0026#39;host,hv_time,kvm=off,hv_vendor_id=null\u0026#39;/\u0026gt; \u0026lt;/qemu:commandline\u0026gt; \u0026lt;/domain\u0026gt; 这些设置对我有用 kira~(\u0026rsquo;· w \u0026lt; ` )\n修改完需要重新定义虚拟机 virsh define Win10.xml\n17. 给虚拟机添加物理磁盘\r2012/10/14: Adding a Physical Disk to a Guest with Libvirt / KVM\n通过手动修改虚拟机的 XML 配置文件, 可以将物理磁盘添加到虚拟机中。virt-manager 本身无法直接将物理磁盘添加到虚拟机, 但通过编辑 XML 文件, 你可以实现这一功能。\n在 \u0026lt;devices\u0026gt; 标签中添加磁盘配置\r/etc/libvirt/qemu/\u0026lt;your-vm\u0026gt;.xml 在编辑器中打开\n在 XML 配置文件中的 \u0026lt;devices\u0026gt; 标签下, 添加 \u0026lt;disk\u0026gt; 配置, 指定要添加的物理磁盘路径。\n\u0026lt;devices\u0026gt; ... \u0026lt;disk type=\u0026#39;block\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;raw\u0026#39;/\u0026gt; \u0026lt;source dev=\u0026#39;/dev/md/storage\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vdb\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x04\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; ... \u0026lt;/devices\u0026gt; \u0026lt;source dev='/dev/md/storage'/\u0026gt;: 这里指定了物理磁盘的设备路径, /dev/md/storage 是一个示例路径, 你需要根据实际的磁盘路径进行调整 \u0026lt;target dev='vdb' bus='virtio'/\u0026gt;: 这是虚拟机中的虚拟磁盘名称 (vdb), 并指定了使用 virtio 总线进行连接。这是推荐的方式, 以提高磁盘性能 \u0026lt;address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/\u0026gt;: 为磁盘指定一个 PCI 地址, 这通常用于管理多个磁盘的设备。我的配置文件加入了这部分 修改完需要重新定义虚拟机 virsh define Win10.xml\n本文参考文献\nKVM : GPU Passthrough ★★★★★\nVGA Passthrough on virtual machines in CentOS 7 ★★★★★\ncentos 7禁用nouveau及安装NVIDIA显卡驱动 ★★★★★\nCentOS7 minimal kvm iommu 辅助虚拟化 vt-x (用于pci透传) ★★★★★\n配置宿主机网络 Bridge模式配置 ★★★★★\nWhy does my Windows 7 VM running under Linux\u0026rsquo; KVM not use all the virtual processors? ★★★★★\nFighting error 43 - how to use Nvidia GPU in a virtual machine. ★★★★★\nAdding_USB_Device_Pass-through ★★★★★\nAdding a Physical Disk to a Guest with Libvirt / KVM ★★★★★\nUbuntu 18.04 - KVM/QEMU Windows 10 GPU Passthrough ★★★★☆\nCentOS7.2上用KVM安装虚拟机windows10踩过的坑 ★★★★☆\nvga-passthrough/3_BASIC_SETUP.md ★★★☆☆\n\u0026ldquo;Error 43: Driver failed to load\u0026rdquo; on Nvidia GPUs passed to Windows VMs ★★☆☆☆\nCentos7.4安装kvm虚拟机（使用virt-manager管理） ★☆☆☆☆\n未使用到的资料 SR-IOV 直通设置 万兆网卡\n16.2. PCI DEVICE ASSIGNMENT WITH SR-IOV DEVICES\nFrequently Asked Questions for SR-IOV on Intel® Ethernet Server Adapters\nQEMU\u0026rsquo;s new -nic command line option\n10G NIC performance: VFIO vs virtio - KVM\nlibvirt: Domain XML format KVM xml 格式\nCentOS 7でKVM + libvirt + Open vSwitchな仮想化環境のつくり方\nKVM Virtualization 10gbe virtual ethernet\n","date":"2019-03-10T04:34:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-set-up-kvm-with-pci-passthrough-for-nvidia-gpu/","title":"CentOS 7 KVM 搭建并设置 PCI 直通 Nvidia 显卡"},{"content":"V2Ray 更新也有一段时间了, 更新逐渐稳定之后. 于是开始研究这个是如何搭建的\n第一次 V2Ray 的时候仅支持手动安装, 而且安装步骤极为复杂. 当时因为这个原因处于观望状态。时隔 2 年, 长城不断升级并且加入了新的 TCP 阻断技术. 被迫再次接触 V2Ray\n中间有听说过某某大神更新了, V2ray 的一键脚本. 但当时用着酸酸乳很稳定也就没太在意. 到了现在网上所有教程都是用一键脚本, 难得可以找到一个手动安装的方法. 此文就讲解手动安装 V2Ray 的教程\n下载并解压 V2Ray 程序\r首先, 下载 V2Ray 的发行版程序, 解压压缩包并查看目录中的文件\nwget https://github.com/v2ray/v2ray-core/releases/download/v3.24/v2ray-linux-64.zip unzip v2ray-linux-64.zip cd v2ray-v3.24-linux-64 ll -a V2Ray 的程序目录文件包括:\nv2ray: V2Ray 主程序 v2ctl: V2Ray 控制工具 geoip.dat 和 geosite.dat: 程序所需要的域名和 IP 数据文件 systemd 和 systemv: 用于生成服务的文件夹 将文件移动至正确位置\r根据 V2Ray 的安装脚本, 会自动在如下目录生成如下文件\n/usr/bin/v2ray/v2ray V2Ray 程序 /usr/bin/v2ray/v2ctl V2Ray 工具 /etc/v2ray/config.json 配置文件 /usr/bin/v2ray/geoip.dat IP 数据文件 /usr/bin/v2ray/geosite.dat 域名数据文件 现在要做的就是将文件移动至相应位置\nmkdir /usr/bin/v2ray cp v2ray /usr/bin/v2ray/v2ray cp v2ctl /usr/bin/v2ray/v2ctl cp geoip.dat /usr/bin/v2ray/geoip.dat cp geosite.dat /usr/bin/v2ray/geosite.dat mkdir /etc/v2ray/ cp vpoint_vmess_freedom.json /etc/v2ray/config.json 最后一条命令是将当前的 vpoint_vmess_freedom.json 配置文件复制到指定位置, 并修改其为 config.json。\n由于 V2Ray 是不区分服务端和客户端的, 同一个程序可以配置成服务器也可以配置成客户端, 程序目录中的 vpoint_vmess_freedom.json 一般用于配置服务器, 而 vpoint_socks_vmess.json 用于配置成为客户端。\n生成 V2Ray 服务\r为了方便使用, 一般会将 V2Ray 配置为 systemd 服务。程序目录中有两个文件夹: systemd 和 systemv, 其中保存了两种系统服务文件。如果严格按照上面的位置存放文件, 那么服务文件就不需要修改。\n将 v2ray.service 文件复制到 /usr/lib/systemd/system 目录\ncp ./systemd/v2ray.service /usr/lib/systemd/system 服务生成后, 还需要手动创建一些必要的日志文件和运行文件\nmkdir /var/log/v2ray/ touch /var/log/v2ray/access.log touch /var/log/v2ray/error.log touch /var/run/v2ray.pid 启动并查看服务状态\rsystemctl start v2ray systemctl status v2ray 全部命令执行完成后, 就可以看到如下内容\n此时, V2Ray 程序已经成功运行, 并且添加至系统服务。你可以使用以下命令将其设置为系统启动时自动启动\nsystemctl enable v2ray 原文\nCentOS 7系统手动安装V2Ray程序\n","date":"2019-03-09T11:25:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-manually-install-v2ray/","title":"CentOS 7 系统手动安装 V2Ray 程序"},{"content":"V2ray 是一个新型的工具, 由于官网说明的很多地方说的不够直白, 所以本文记录了一些使用方法\n本实例采取 V2Ray、Cloudflare、Nginx、WebSocket 和 TLS 技术搭建一个科学上网的环境, 以便绕过防火墙的封锁, 并实现安全、隐蔽的网络连接。\nProject V 是一个工具集合, 它可以帮助你打造专属的基础通信网络。Project V 的核心工具称为 V2Ray, 其主要负责网络协议和功能的实现, 与其它 Project V 通信。V2Ray 可以单独运行, 也可以和其它工具配合, 以提供简便的操作流程。\n科学上网担心 IP 被墙？ 你可以使用 Cloudflare 中转 V2Ray WebSocket 的流量来避免 IP 被墙。简单说就是使用 V2Ray 的 WebSocket + TLS 传输协议, 并且由于使用了 Cloudflare 中转, 所以墙根本不知道背后的 IP 是多少, 还怎么墙你的 IP 呢？\nV2ray 官网: https://www.v2ray.com/\n本次部署主要采用 V2ray+Nginx+CloudFlare+WwebSocket+TLS 方式, 所以准备内容略多, 但是效果显著, 可以利用 CDN 让被墙的服务器 80% 血量复活。(我的测试之后满血复活)\n准备条件\rCentOS 7 freenom (域名) Cloudflare (CDN) Nginx V2ray SSL证书 (acme.sh) 安装和配置 V2Ray 服务端\r一键安装脚本 官方安装说明\nbash \u0026lt;(curl -L -s https://install.direct/go.sh) go.sh 参数\n-p 或 --proxy: 使用代理服务器来下载 V2Ray 的文件, 格式与 curl 接受的参数一致, 比如 socks5://127.0.0.1:1080 或 http://127.0.0.1:3128 -f 或 --force: 强制安装。在默认情况下, 如果当前系统中已有最新版本的 V2Ray, go.sh 会在检测之后就退出。如果需要强制重装一遍, 则需要指定该参数。 --version: 指定需要安装的版本, 比如 v1.13。默认值为最新版本。 --local: 使用一个本地文件进行安装。如果你已经下载了某个版本的 V2Ray, 则可通过这个参数指定一个文件路径来进行安装。 示例:\n使用地址为 127.0.0.1:1080 的 SOCKS 代理下载并安装最新版本:\n./go.sh -p socks5://127.0.0.1:1080 安装本地的 v1.13 版本:\n./go.sh --version v1.13 --local /path/to/v2ray.zip 配置文件修改\r编辑 /etc/v2ray/config.json 配置文件, 修改监听端口、UUID 和 WebSocket 设置等。\nUUID 在线生成\n{ \u0026#34;inbounds\u0026#34;: [{ \u0026#34;port\u0026#34;: 10000, // 设置监听端口 \u0026#34;listen\u0026#34;:\u0026#34;127.0.0.1\u0026#34;, // 要指定监听内网地址 \u0026#34;protocol\u0026#34;: \u0026#34;vmess\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;ef5af5fe-96f9-4072-b393-4f3b392af0a2\u0026#34;, // UUID 填在这里, 用在线生成的即可 \u0026#34;level\u0026#34;: 1, \u0026#34;alterId\u0026#34;: 64 } ] }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;ws\u0026#34;, // 设置WebSocket 模式 \u0026#34;wsSettings\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;/ray\u0026#34; } } }], \u0026#34;outbounds\u0026#34;: [{ \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34;, \u0026#34;settings\u0026#34;: {} },{ \u0026#34;protocol\u0026#34;: \u0026#34;blackhole\u0026#34;, \u0026#34;settings\u0026#34;: {}, \u0026#34;tag\u0026#34;: \u0026#34;blocked\u0026#34; }], \u0026#34;routing\u0026#34;: { \u0026#34;rules\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;ip\u0026#34;: [\u0026#34;geoip:private\u0026#34;], \u0026#34;outboundTag\u0026#34;: \u0026#34;blocked\u0026#34; }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;block\u0026#34;, // 禁止BT下载 \u0026#34;protocol\u0026#34;: [ \u0026#34;bittorrent\u0026#34; ] } ] } } 复制配置文件, 然后替换前 4 个注释的内容即可\nfreenom 域名注册\r注册域名成功后把 DNS 服务器设置成 Cloudflare 提供的 DNS 登陆 Cloudflare 添加域名, 它会提供 DNS 服务器地址 在 freenom 修改 nameserver 之后, 稍等10分钟 在 Cloudflare 选择申请验证 DNS 服务器. 等待 5 分钟左右 验证成功后会收到 Cloudflare 的邮件, 告诉你 DNS 修改成功, 可以开始使用了 配置 SSL 证书\r在 Cloudflare 的个人资料里面找到 API Keys \u0026ndash;\u0026gt; Global API Key 创建一个 API key 留作备用.\n使用 acme.sh 工具获取免费的 Let\u0026rsquo;s Encrypt SSL 证书\ncurl https://get.acme.sh | sh alias acme.sh=~/.acme.sh/acme.sh acme.sh --upgrade --auto-upgrade # 替换成你自己的 API key export CF_Key=\u0026#34;o0xrmni6602i4sbeq13b4i5uwn2hswk3\u0026#34; # 换成你的 Cloudflare 登录邮箱 export CF_Email=\u0026#34;email@example.com\u0026#34; # example.com 换成自己的域名 下面的也要换 acme.sh --issue --dns dns_cf -d example.com acme.sh --install-cert -d example.com --fullchain-file /etc/v2ray/v2ray.crt --key-file /etc/v2ray/v2ray.key --reloadcmd \u0026#34;nginx -s reload\u0026#34; 配置 Nginx 反向代理\r本部分的官网文档: WebSocket\n修改 Nginx 配置文件 /etc/nginx/nginx.conf, 首先把文件里面默认开启的 80 和 443 的服务器注释掉\n创建新的配置文件来代理 V2Ray WebSocket 流量, 在 /etc/nginx/conf.d 目录下新建一个文件 v2ray.conf\nserver { listen 443 ssl; ssl on; ssl_certificate /etc/v2ray/v2ray.crt; ssl_certificate_key /etc/v2ray/v2ray.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; server_name example.com; #替换成自己的域名 location / { default_type application/json; add_header Content-Type \u0026#34;text/plain;charset=utf-8\u0026#34;; return 200 \u0026#34;OK~!\u0026#34;; } location /ray { proxy_redirect off; proxy_pass http://127.0.0.1:10000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \u0026#34;upgrade\u0026#34;; proxy_set_header Host $http_host; # Show realip in v2ray access.log proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } 注意事项\nV2Ray 暂时不支持 TLS 1.3, 如果开启并强制 TLS 1.3 会导致 V2Ray 无法连接\n如果在设置完成之后不能成功使用, 可能是由于 SElinux 机制 (如果你是 CentOS 7 的用户请特别留意 SElinux\n这一机制) 阻止了 Nginx 转发向内网的数据。如果是这样的话, 在 V2Ray 的日志里不会有访问信息, 在 Nginx\n的日志里会出现大量的 Permission Denied 字段, 要解决这一问题需要在终端下键入以下命令:\nsetsebool -P httpd_can_network_connect 1 请保持服务器和客户端的 wsSettings 严格一致, 对于 V2Ray, /ray 和 /ray/ 是不一样的\n不安全的因素在于人, 自己的问题就不要甩锅, 哪怕我把示例中的 path 改成一个 UUID, 依然有不少人原封不动地 COPY\nApache 配置\r\u0026lt;VirtualHost *:443\u0026gt; ServerName example.com SSLCertificateFile /etc/v2ray/v2ray.crt SSLCertificateKeyFile /etc/v2ray/v2ray.key SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2 SSLCipherSuite HIGH:!aNULL \u0026lt;Location \u0026#34;/ray/\u0026#34;\u0026gt; ProxyPass ws://127.0.0.1:10000/ray/ upgrade=WebSocket ProxyAddHeaders Off ProxyPreserveHost On RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s \u0026lt;/Location\u0026gt; \u0026lt;/VirtualHost\u0026gt; 配置 Cloudflare CDN\r修改默认配置,以下是必须调整的\nNetwork 中的 Websocket, 必须开启 DNS 中的对应域名的解析, 必须套用 CDN, 即黄色 DNS and HTTP proxy(CDN) Cloudflare 的 Crypto 选项卡的 SSL 为 Full 可能的要调整的, 具体是否有影响, 不清楚。\nCrypto 中, Authenticated Origin Pulls 应该要关闭 (我没关) Opportunistic Encryption 应该要关闭(我关了) 测试\r注意, 注意, 完成配置后确认无误, 仍然需要等待 10-20 分钟让 CDN 反应, 允许 websocket。所以期间不要着急. 刚刚配置完的延迟会非常高. 要等待 24-48 小时左右匹配到最佳线路. 延迟才会下降.\n数据流向为\nV2 客户端 -\u0026gt; CDN:443 -\u0026gt; Nginx:443 -\u0026gt; V2 服务端:10000 不要使用伪装 http 报头 加密协议为 none 或者 aes-128-cfb 开启 UDP 与 KCP 使用客户端连接, 套 CDN 无 Error, 可访问 Google, 速度大约在 500KB 左右。并且此方式突破 GFW 封锁 IP 地址, 但是不排除封域名。24小时之后, 速度可以达到 22m/s (满血复活)\n客户端配置\r官方推荐的工具: 神一样的工具们\nWindows: V2RayN Mac OS: V2RayX, ClashX iOS: Shadowrocket Android: V2RayNG 以 V2RayN 为例, 服务器配置文件没有加密方式和伪装类型。\n而 GUI 界面的客户端使用者需要填以下内容\n地址 example.com 端口 443 用户 ID ef5af5fe-96f9-4072-b393-4f3b392af0a2 AlterID 64 加密方式 客户端控制 # 建议aes-128-gcm 传输协议 ws 伪装类型 客户端控制 # 默认none 伪装域名 /ray 底层传输 tls 扩展阅读\r内置的域名文件 geosite.dat\r在下载 V2Ray 的时候, 下载的压缩包有一个 geosite.dat。这个文件是在路由功能里用到的, 文件内置了许多常见的网站域名。配置方式如下, geosite 指 geosite.dat 文件, 后面的 cn 是一个标签, 代表着使用 geosite.dat 文件里的 cn 规则\n{ \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;direct\u0026#34;, \u0026#34;domain\u0026#34;: [ \u0026#34;geosite:cn\u0026#34; ] } 通过它可以设定这些国内域名走直连, 这样就相当把规则的域名写到一个文件里, 然后在配置中引用这个域名文件, 其中有一个好处是配置比较简洁, 看起来比较清爽。\n外置的域名文件 (自定义的 geosite.dat)\r很多时候, V2Ray 内置的国内域名不能满足使用。不过 V2Ray 可以使用外部自定义的像 geosite.dat 这样的域名文件, 刚好我也制作了一个, 可以供大家使用\n到 github.com/ToutyRater/V2Ray-SiteDAT/tree/master/geofiles 下载 h2y.dat 文件放到 V2Ray 运行文件的目录下\n按需要写路由规则, 格式为 ext:h2y.dat:tag。\next 表示使用外部文件 h2y.dat 是具体的文件名 tag 泛指标签, 有哪些标签由文件提供 步骤 1 下载的 h2y.dat 文件目前只有 ad 和 gfw 两个标签, ad 包含着常见的广告域名, gfw 包含着常见的被 gfw 屏蔽的域名。它们各自所包含的域名在这里可以看到。这个域名文件每星期自动更新, 如果你使用了我提供的域名文件也请定期更新。\n路由配置示例如下\n\u0026#34;rules\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;block\u0026#34;, // 拦截广告相关域名 \u0026#34;domain\u0026#34;: [ \u0026#34;ext:h2y.dat:ad\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;proxy\u0026#34;, // 被 gfw 屏蔽的域名走代理 \u0026#34;domain\u0026#34;: [ \u0026#34;ext:h2y.dat:gfw\u0026#34; ] }, { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;network\u0026#34;: \u0026#34;tcp,udp\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;direct\u0026#34; // 默认直连 } ] 因为使用了 gfw 列表的用户, 通常是想要默认情况下直连, 但有时候习惯上在 outbounds 的第一个是代理的出站, 所以在上面的配置中, 最后加了一条直连的规则。那个 \u0026quot;network\u0026quot;: \u0026quot;tcp,udp\u0026quot; 是为了让所有流量都能匹配上。\n运行 V2Ray\n需要注意的是, 目前所有第三方的 V2Ray GUI 客户端都不支持加载外置的域名文件\n禁止 BT 流量\r国外版权意识比较重, 如果下载盗版的影音文件很有可能会吃官司, 所以大多数国外的 VPS 的使用条例都不允许下载 BT。但是一些人并不清楚这点, 经常使用朋友分享给他的翻墙账号进行 BT 下载最终导致 VPS 被提供商封禁。\n尽管有时候说了不能使用代理下载 BT, 对方也表示明白了清楚了, 但总是有软件喜欢设置系统代理, 也总有软件喜欢使用系统代理, 好像也有不少人把路由器翻墙当成了不可或缺的, 最终还是逃不了封禁的厄运。\n这个问题似乎从进入到 VPS 翻墙时代就困扰这大家, 于是各种禁止 BT 的一键脚本也随之应运而生, 也时常有人在讨论哪个脚本比较好用, 其实最根本的几乎全是 IPTABLES 的字符串匹配。\n在 V2Ray, 修改配置文件的路由配置即可禁用 BT。单从禁用 BT 来说的话, 也许 IPTABLES 的方式会好一些, 也可能不是。但是别忘了, V2Ray 的路由功能可不是只能禁止连接而已, 本质应该是转发。也就是说, 如果你有一台无视版权的 VPS, 那么大可将 BT 流量转到这台 VPS 上。\n服务器配置\n\u0026#34;routing\u0026#34;: { \u0026#34;domainStrategy\u0026#34;: \u0026#34;AsIs\u0026#34;, \u0026#34;rules\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;outboundTag\u0026#34;: \u0026#34;block\u0026#34;, \u0026#34;protocol\u0026#34;: [ \u0026#34;bittorrent\u0026#34; ] } ] } 注意: inbound 的 sniffing 必须开启\n原文\nV2ray 新平台搭建\n禁用 BT\n","date":"2019-03-09T11:23:00+08:00","permalink":"https://blog.acesheep.com/p/v2ray-new-tool-deployment-guide/","title":"V2ray 新平台搭建"},{"content":"ss-panel-v3 是一套功能齐全的 shadowsocks 用户面板程序, 安装这款程序可以实现用户注册、用户管理、流量限制、签到、添加节点、充值购买、充值返利等诸多功能。搭建完毕后完全可以使用这款程序在线销售 shadowsocks\nss-panel-v3-mod 真的是一款炒鸡棒的 ss 面板程序\n环境要求\n操作系统: CentOS 7 或 Debian 8 PHP: 7.2 数据库: MariaDB Web 服务器: Apache 2 (httpd) ss-panel-v3-mod Github 已失效, 备用下载地址: ss-panel-v3-mod-new_master.zip 前端安装教程\r注意: 大概在 2019-01-13 左右发生的事情\n赵大的魔改版 (new_master 分支) /esdeathlove/ss-panel-v3-mod\n赵大的魔改版后端 /esdeathlove/shadowsocks\n/glzjin/shadowsocks\n以上库均已删库\nss-panel-v3-mod 再次修改版 github.com/Anankke/ss-panel-v3-mod_Uim\n初始化系统环境\rCentOS 7\ryum install git python-devel libffi-devel openssl-devel python-setuptools epel-release screen ncurses-devel build-essential gcc wget m2crypto net-tools -y yum update -y yum install -y htop nload vim python-pip systemctl stop firewalld 记得开启 BBR, 重要!\nDebian 8\rapt-get update apt install vim htop screen python-setuptools python-dev python-pip git libxml2-dev libxslt1-dev python-dev zlib1g-dev libevent-dev pip install --upgrade setuptools apt-get install supervisor /usr/bin/supervisord -c /etc/supervisor/supervisord.conf 安装 PHP 7.2\r可以使用 yum 仓库安装或者从源代码编译安装\nApache 2 (httpd) 设置\r在 Apache 配置文件中添加以下代码, 以启用 URL 重写。设置伪静态\n\u0026lt;Directory \u0026#34;/ss-panel/public\u0026#34;\u0026gt; Options -Indexes +FollowSymLinks AllowOverride All Require all granted RewriteEngine on RewriteBase \u0026#34;/\u0026#34; RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] \u0026lt;/Directory\u0026gt; MariaDB 配置\r创建数据库和用户, 并分配权限\nCREATE DATABASE sspanel; CREATE USER \u0026#39;sspaneluser\u0026#39;@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; GRANT ALL PRIVILEGES ON sspanel.* TO \u0026#39;sspaneluser\u0026#39;@\u0026#39;localhost\u0026#39;; FLUSH PRIVILEGES; 解决 MySQL 新建用户后无法登录问题\nERROR 1045 (28000): Access denied for user \u0026#39;laravel\u0026#39;@\u0026#39;localhost\u0026#39; (using password: YES) 安装 ss-panel-v3-mod\r首先打开 ss-panel-v3-mod 的官方 Github: github.com/esdeathlove/ss-panel-v3-mod\n将程序的zip压缩包下载到本地\n在 中新建一个数据库, 新建用户, 分配权限.\n解压压缩包找到 sql 目录中的 glzjin_all.sql, 并把 glzjin_all.sql 导入进数据库\n新建用户并赋予权限命令:\n数据库: sspanel 用户: sspaneluser 密码: 123456 insert into mysql.user(Host,User,Password) values(\u0026#39;%\u0026#39;,\u0026#39;sspaneluser\u0026#39;,password(\u0026#39;123456\u0026#39;)); grant all privileges on `sspanel`.* to \u0026#39;sspaneluser\u0026#39;@\u0026#39;%\u0026#39; identified by \u0026#39;123456\u0026#39;; FLUSH PRIVILEGES; 回到 Bash 中, 再来进行 ss-panel-v3-mod 的配置\n# 进入站点目录 cd /home/wwwroot/你站点的域名 # 安装依赖 php composer.phar install # 创建默认配置文件 cp config/.config.php.example config/.config.php 编辑 .config.php 文件 vim config/.config.php\n# 由于配置太多, 这里只说重点 $System_Config[\u0026#39;key\u0026#39;] = \u0026#39;\u0026#39;; // 修改此 key 为随机字符串确保网站安全 $System_Config[\u0026#39;appName\u0026#39;] = \u0026#39;\u0026#39;; // 站点名称 $System_Config[\u0026#39;baseUrl\u0026#39;] = \u0026#39;https://zhaojin97.cn\u0026#39;; // 站点地址 $System_Config[\u0026#39;timeZone\u0026#39;] = \u0026#39;PRC\u0026#39;; // RPC 天朝时间 UTC 格林时间 $System_Config[\u0026#39;pwdMethod\u0026#39;] = \u0026#39;sha256\u0026#39;; // 密码加密 可选 md5, sha256 $System_Config[\u0026#39;salt\u0026#39;] = \u0026#39;\u0026#39;; // 密码加密用, 从旧版升级请留空 $System_Config[\u0026#39;authDriver\u0026#39;] = \u0026#39;cookie\u0026#39;; // 登录验证存储方式, 推荐使用 Redis 可选: cookie,redis $System_Config[\u0026#39;mailDriver\u0026#39;] = \u0026#39;mailgun\u0026#39;; // 邮件 可选 mailgun or smtp 需要支持qq邮箱的选 smtp $System_Config[\u0026#39;checkinMin\u0026#39;] = \u0026#39;100\u0026#39;; // 签到最少流量 单位MB $System_Config[\u0026#39;checkinMax\u0026#39;] = \u0026#39;500\u0026#39;; // 签到最多流量 $System_Config[\u0026#39;defaultTraffic\u0026#39;] = \u0026#39;100\u0026#39;; // 用户初始流量 单位GB $System_Config[\u0026#39;inviteNum\u0026#39;] = \u0026#39;0\u0026#39;; // 注册后获得的邀请码数量 # database 数据库配置 $System_Config[\u0026#39;db_driver\u0026#39;] = \u0026#39;mysql\u0026#39;; $System_Config[\u0026#39;db_host\u0026#39;] = \u0026#39;localhost\u0026#39;; // 数据库地址 $System_Config[\u0026#39;db_database\u0026#39;] = \u0026#39;\u0026#39;; // 数据库名称 sspanel $System_Config[\u0026#39;db_username\u0026#39;] = \u0026#39;\u0026#39;; // 数据库用户 sspanel $System_Config[\u0026#39;db_password\u0026#39;] = \u0026#39;\u0026#39;; // sspanel用户的密码 $System_Config[\u0026#39;db_charset\u0026#39;] = \u0026#39;utf8\u0026#39;; $System_Config[\u0026#39;db_collation\u0026#39;] = \u0026#39;utf8_general_ci\u0026#39;; $System_Config[\u0026#39;db_prefix\u0026#39;] = \u0026#39;\u0026#39;; # redis $System_Config[\u0026#39;redis_scheme\u0026#39;] = \u0026#39;tcp\u0026#39;; // 登录验证存储方式选了 redis 的话需要配置 $System_Config[\u0026#39;redis_host\u0026#39;] = \u0026#39;127.0.0.1\u0026#39;; $System_Config[\u0026#39;redis_port\u0026#39;] = \u0026#39;6379\u0026#39;; $System_Config[\u0026#39;redis_database\u0026#39;] = \u0026#39;0\u0026#39;; $System_Config[\u0026#39;redis_password\u0026#39;]=\u0026#34;\u0026#34;; # smtp $System_Config[\u0026#39;smtp_host\u0026#39;] = \u0026#39;\u0026#39;; // 例如 smtp.qq.com $System_Config[\u0026#39;smtp_username\u0026#39;] = \u0026#39;\u0026#39;; $System_Config[\u0026#39;smtp_port\u0026#39;] = \u0026#39;25\u0026#39;; $System_Config[\u0026#39;smtp_name\u0026#39;] = \u0026#39;\u0026#39;; $System_Config[\u0026#39;smtp_sender\u0026#39;] = \u0026#39;\u0026#39;; $System_Config[\u0026#39;smtp_passsword\u0026#39;] = \u0026#39;\u0026#39;; $System_Config[\u0026#39;smtp_ssl\u0026#39;] = \u0026#39;false\u0026#39;; # 功能开关 需要用到的才开 建议先别动 $System_Config[\u0026#39;enable_wecenter\u0026#39;]=\u0026#39;false\u0026#39;; $System_Config[\u0026#39;enable_radius\u0026#39;]=\u0026#39;false\u0026#39;; // 配置了 radius 的话就开 $System_Config[\u0026#39;enable_cloudxns\u0026#39;]=\u0026#39;false\u0026#39;; $System_Config[\u0026#39;enable_duoshuo\u0026#39;]=\u0026#39;false\u0026#39;; $System_Config[\u0026#39;enable_rss\u0026#39;]=\u0026#39;true\u0026#39;; $System_Config[\u0026#39;enable_paymentwall\u0026#39;]=\u0026#39;false\u0026#39;; # Radius 数据库设置 $System_Config[\u0026#39;radius_db_host\u0026#39;]=\u0026#39;\u0026#39;; // 跟上面 database 数据库配置差不多 换成radius即可 $System_Config[\u0026#39;radius_db_database\u0026#39;]=\u0026#39;\u0026#39;; $System_Config[\u0026#39;radius_db_user\u0026#39;]=\u0026#39;\u0026#39;; $System_Config[\u0026#39;radius_db_password\u0026#39;]=\u0026#39;\u0026#39;; # Radius 连接密钥 $System_Config[\u0026#39;radius_secret\u0026#39;]=\u0026#39;\u0026#39;; // 这个重要 必须设 # 端口池 $System_Config[\u0026#39;min_port\u0026#39;]=\u0026#39;10000\u0026#39;; // SSR 分配端口号范围 $System_Config[\u0026#39;max_port\u0026#39;]=\u0026#39;65535\u0026#39;; # 两种方式相对于 ss 端口的偏移 $System_Config[\u0026#39;pacp_offset\u0026#39;]=\u0026#39;-20000\u0026#39;; // PAC+ 和 PAC++ 用到 $System_Config[\u0026#39;pacpp_offset\u0026#39;]=\u0026#39;-20000\u0026#39;; # 测速周期/h $System_Config[\u0026#39;Speedtest_duration\u0026#39;]=\u0026#39;6\u0026#39;; // 对应后端 SSR 的 userapiconfig.py 里的 SPEEDTEST # 随机分组, 注册时随机分配到的分组, 多个分组请用英文半角逗号分隔。 $System_Config[\u0026#39;ramdom_group\u0026#39;]=\u0026#39;0\u0026#39;; // 组别用于区分用户组 对应组只能访问对应组和0组的服务器 明白后再修改 # 充值返利百分比 $System_Config[\u0026#39;code_payback\u0026#39;]=\u0026#39;20\u0026#39;; // 用户充值后 给邀请他注册的人返利多少% # 注册时的流量重置日以及需要重置的流量, 0 不重置 $System_Config[\u0026#39;reg_auto_reset_day\u0026#39;]=\u0026#39;0\u0026#39;; $System_Config[\u0026#39;reg_auto_reset_bandwidth\u0026#39;]=\u0026#39;100\u0026#39;; // 单位 G 修改数据库配置信息\r创建管理员账号\r配置好之后, 给 ss-panel-v3-mod 创建一个管理员账号\nphp -n xcat createAdmin 创建完成后来同步一下用户\nphp xcat syncusers 设置定时任务\r最后来设置几个定时任务确保 ss-panel-v3-mod 的长期稳定运行\n使用 crontab -e 设置定时任务\n30 22 * * * php /home/wwwroot/你的站点域名/xcat sendDiaryMail\r*/1 * * * * php /home/wwwroot/你的站点域名/xcat synclogin\r*/1 * * * * php /home/wwwroot/你的站点域名/xcat syncvpn\r0 0 * * * php -n /home/wwwroot/你的站点域名/xcat dailyjob\r*/1 * * * * php /home/wwwroot/你的站点域名/xcat checkjob\r*/1 * * * * php -n /home/wwwroot/你的站点域名/xcat syncnas 到这里, ss-panel-v3-mod 的前端面板就安装完成了。但现在依旧不能正常使用, 因为这只是一个前端 WEB 网站, 我们还需要搭建后端服务和这个前端结合起来才能正常使用。\n配置后端服务\r安装支持 ss-panel 的 ShadowsocksR 后端\n安装 libsodium 加密库\rlibsodium 是给 SSR (ShadowsocksR) 提供 chacha20、salsa20、chacha20-ietf 等高级加密所必须的扩展库, 如果不用这几个加密方式, 可以不安装\ncd ~ # 安装 libsodium 加密库必须的 wget https://github.com/jedisct1/libsodium/releases/download/1.0.10/libsodium-1.0.10.tar.gz tar -xzf libsodium-1.0.10.tar.gz cd libsodium-1.0.10 ./configure make make install # 修复关联 echo /usr/local/lib \u0026gt; /etc/ld.so.conf.d/usr_local_lib.conf ldconfig 下载并配置后端服务\rcd .. git clone -b manyuser https://github.com/glzjin/shadowsocks.git cd shadowsocks pip install -r requirements.txt 设置程序的配置文件\ncp apiconfig.py userapiconfig.py cp config.json user-config.json 编辑 userapiconfig.py\n# 来解释下里面各项配置的意思 # Config # 节点ID 对应前端节点列表的 ID NODE_ID = 1 #自动化测速, 为 0 不测试, 此处以小时为单位, 要和 ss-panel 设置的小时数一致 SPEEDTEST = 6 # 云安全, 自动上报与下载封禁 IP, 1 为开启, 0 为关闭 CLOUDSAFE = 1 # 自动封禁 SS 密码和加密方式错误的 IP, 1 为开启, 0 为关闭 ANTISSATTACK = 0 # 是否接受上级下发的命令, 如果你要用这个命令, 请参考我之前写的东西, 公钥放在目录下的 ssshell.asc AUTOEXEC = 1 # 是否以多线程模式运行, 关闭这个限速就会无效。请优先测试 1 , 开启试试, 能运行没。 MULTI_THREAD = 0 # 多端口单用户设置, 看重大更新说明。 MU_SUFFIX = \u0026#39;zhaoj.in\u0026#39; # 多端口单用户设置, 看重大更新说明。 MU_REGEX = \u0026#39;%5m%id.%suffix\u0026#39; # 不明觉厉 SERVER_PUB_ADDR = \u0026#39;127.0.0.1\u0026#39; # mujson_mgr need this to generate ssr link # 此处不要修改 API_INTERFACE = \u0026#39;glzjinmod\u0026#39; #mudbjson, sspanelv2, sspanelv3, sspanelv3ssr, muapiv2(not support) # mudb, 不要管 MUDB_FILE = \u0026#39;mudb.json\u0026#39; # Mysql 数据库连接信息 MYSQL_HOST = \u0026#39;127.0.0.1\u0026#39; MYSQL_PORT = 3306 MYSQL_USER = \u0026#39;ss\u0026#39; MYSQL_PASS = \u0026#39;ss\u0026#39; MYSQL_DB = \u0026#39;shadowsocks\u0026#39; MYSQL_UPDATE_TIME = 60 # 是否启用SSL连接, 0为关, 1为开 MYSQL_SSL_ENABLE = 0 # 客户端证书目录, 请看 https://github.com/glzjin/shadowsocks/wiki/Mysql-SSL%E9%85%8D%E7%BD%AE MYSQL_SSL_CERT = \u0026#39;/root/shadowsocks/client-cert.pem\u0026#39; MYSQL_SSL_KEY = \u0026#39;/root/shadowsocks/client-key.pem\u0026#39; MYSQL_SSL_CA = \u0026#39;/root/shadowsocks/ca.pem\u0026#39; # API, 不用管 API_HOST = \u0026#39;127.0.0.1\u0026#39; API_PORT = 80 API_PATH = \u0026#39;/mu/v2/\u0026#39; API_TOKEN = \u0026#39;abcdef\u0026#39; API_UPDATE_TIME = 60 # Manager 不用管 MANAGE_PASS = \u0026#39;ss233333333\u0026#39; # if you want manage in other server you should set this value to global ip MANAGE_BIND_IP = \u0026#39;127.0.0.1\u0026#39; # make sure this port is idle MANAGE_PORT = 23333 modwebapi 改为: glzjinmod\n节点 ID 改为 3\n找到配置文件中的 MySQL 信息, 正确填写我们之前创建的数据库信息\n启动后端服务\rpython server.py 用于调错的 ./run.sh 无日志后台运行 ./logrun.sh 有日志后台运行 supervisord 在前端添加后端节点信息\r现在我们登录 ss-panel-v3-mod 面板, 点击左下角最后一个管理面板按钮, 进入到管理界面\n点击节点管理, 右下角 + 号添加一个新节点。\n注意: 添加节点的时候, 节点名称务必要是这样的: 伯力 - Shadowsocks (- 号前后都有一个空格才行)\n然后就是节点地址、加密方式、流量比例、节点状态、节点描述这些都是必填的, 建议按我如图填写\n全部添加好后可以看到节点已经正常的在线了\n使用 Supervisor 守护进程启动 SSR\r安装 supervisor\reasy_install supervisor 修改 supervisor 配置文件\rmkdir -p /etc/supervisor/conf.d echo_supervisord_conf \u0026gt; /etc/supervisor/supervisord.conf echo \u0026#34;[include]\u0026#34; \u0026gt;\u0026gt; /etc/supervisor/supervisord.conf echo \u0026#34;files = /etc/supervisor/conf.d/*.conf\u0026#34; \u0026gt;\u0026gt; /etc/supervisor/supervisord.conf 创建 ssr 后端守护任务\rcat\u0026gt;\u0026gt;/etc/supervisor/conf.d/ssr.conf\u0026lt;\u0026lt;\\EOF [program:ssr] command=python /root/shadowsocks/server.py autorestart=true autostart=true user=root EOF 创建系统服务 (在 CentOS 7 测试)\rcat\u0026gt;\u0026gt;/usr/lib/systemd/system/supervisord.service\u0026lt;\u0026lt;\\EOF [Unit] Description=supervisord - Supervisor process control system for UNIX Documentation=http://supervisord.org After=network.target [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf ExecReload=/usr/bin/supervisorctl reload ExecStop=/usr/bin/supervisorctl shutdown User=root [Install] WantedBy=multi-user.target EOF 重新启动 supervisord\rsystemctl restart supervisord systemctl enable supervisord 查看 ssr 执行状态\rsupervisorctl status ssr 扩展阅读 - 对接方式\r数据库对接\r数据库对接需要修改的地方:\nNODE_ID = 这里输入前端的节点 ID API_INTERFACE = 'glzjinmod' 务必选择 glzjinmod Mysql 下面填写前端的 MySQL 数据库信息 (务必注意, 需要打开前端数据库的远程连接) 这样修改后就可以保存了\nWEBAPI 对接\r数据库对接需要修改的地方:\nNODE_ID = 这里输入前端的节点 ID API_INTERFACE = 'modwebapi' 务必选择 modwebapi WEBAPI_URL = 'https://ssr.tn' 这里需要把地址改成前端地址, 务必区分 http 和 https WEBAPI_TOKEN='' 这里需要和前端一致, 具体在网站目录 config/.config.php 中查询, 前端默认 key 是 NimaQu 这样修改后就可以保存了\n原文\n现在很多教程隔一段时间就消失了不得不自己备份一个\n详细安装ss-panel-v3魔改版前端+后端教程\nss-panel-v3-mod安装说明 (使用Supervisor守护进程启动ssr)\nss-panel-v3-mod_Uim魔改后端部署教程\n","date":"2019-03-08T03:08:00+08:00","permalink":"https://blog.acesheep.com/p/ss-panel-v3-modified-version-frontend-and-backend-installation-guide/","title":"安装 ss-panel-v3 魔改版 前端 + 后端 详细教程"},{"content":"玩 PT 站的时候, 检查 Tracker 的时候遇到了一个提示就是 ipv6 会泄露 Mac 地址, 这是安全性较高的站点非常关注的问题。\n我去 NAS 上使用 ifconfig 检查 ipv6 和 mac 地址. 从输出的结果来看 ipv6 确实泄露了 Mac 地址. 这个 PT 站安全警惕性非常高. 遇到不安全的客户端也会通知大家立即停止使用, 以及发布一些分析文章.\nWe have detected one (or more) of your clients on IPv6 is leaking your mac address. You can recognize these clients as they will end with FF:FE__:____ (where _ is a random hexadecimal character) 实际情况\rIPv6 地址: fdbe:6442:2ece:0:a00:27ff:fe15:fb4e MAC 地址: 08-00-27-15-FB-4E 提示: 由于十六进制转换, 某些 MAC 地址可能会转换为地址中的字母。这个是正常的。\n解决方案\r关闭 Torrent 客户端中的 IPv6\r这是最直接的解决方案, 确保客户端不会使用 IPv6 地址\n设置设备使用临时 IPv6 地址\r对于 Windows 7、8 和 8.1 系统, 默认启用了基于 MAC 地址的 IPv6 地址生成。可以通过以下步骤启用隐私扩展。\nWindows 7/8\r以管理员身份运行 cmd, 启用临时 IPv6 地址\n# 以下命令以启用随机 IP 地址生成功能 netsh interface ipv6 set global randomizeidentifiers=enabled # 以允许 Windows 随机生成用于网络通信的临时地址 netsh interface ipv6 set privacy state=enabled 如果要禁用临时 IPv6 地址, 以管理员身份运行 cmd\nnetsh interface ipv6 set global randomizeidentifiers=disabled netsh interface ipv6 set privacy state=disabled 检查结果\n使用 ipconfig 检查 IPv6 地址, 确保临时地址成功启用\nCentOS 7\r隐私扩展中所述 RFC 4941 (废弃 RFC 3041) 为无状态地址自动配置/隐私扩展中的 IPv6 正在取代静态接口 ID (主要是基于字宽唯一的 MAC 地址) 通过伪随机的一个, 并从生成的自动配置过程中使用一个新的贬低旧的一个。\nCentOS 7 建议使用 Network Manager 启用隐私扩展\n使用 sysctl 启用隐私扩展\r临时启用\r启用例如接口 eth0 的隐私扩展, 并优先选择生成的地址\nsysctl -w net.ipv6.conf.eth0.use_tempaddr = 2 之后, 需要重新启动网络接口\nip link set dev eth0 down ip link set dev eth0 up 重启完成后, 结果应如下所示\nip -6 addr show dev eth0 2: eth0: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1500 qlen 1000 inet6 2001:db8:0:1:8992:3c03:d6e2:ed72/64 scope global secondary dynamic \u0026lt;- pseudo-random IID valid_lft 604711sec preferred_lft 86311sec inet6 2001:db8:0:1::224:21ff:fe01:2345/64 scope global \u0026lt;- IID based on MAC valid_lft 604711sec preferred_lft 86311sec ... 永久启用\r对于永久激活, 每个接口的特殊 initscript 值将启用隐私或在 /etc/sysctl.conf 文件中添加以下行\nnet.ipv6.conf.eth0.use_tempaddr = 2 注意: 应用 sysctl.conf 时, 接口必须已存在且具有正确的名称。如果不是这种情况 (例如重启后), 则默认情况下必须为所有接口配置隐私\nnet.ipv6.conf.all.use_tempaddr = 2 net.ipv6.conf.default.use_tempaddr = 2 然后应用更改\nsysctl -p 使用 Network Manager 启用隐私扩展\r新 (客户端) 系统使用 Network Manager 配置接口。内置命令行工具, 可用于更改 GUI 不可用的设置。\n检查现有接口\n# nmcli connection NAME UUID TYPE DEVICE ens4v1 d0fc2b2e-5fa0-4675-96b5-b723ca5c46db 802-3-ethernet ens4v1 可以使用以下方式检查当前 IPv6 隐私扩展地址的数量\nip -o addr show dev ens4v1 | grep temporary | wc -l 0 检查当前的 IPv6 隐私扩展设置\nnmcli connection show ens4v1 | grep ip6-privacy ipv6.ip6-privacy: -1 (unknown) 启用 IPv6 隐私扩展并重新启动接口\nnmcli connection modify ens4v1 ipv6.ip6-privacy 2 nmcli connection down ens4v1; nmcli connection up ens4v1 再次检查当前的 IPv6 隐私扩展设置\nnmcli connection show ens4v1 | grep ip6-privacy ipv6.ip6-privacy: 2 (active, prefer temporary IP) 再次检查 IPv6 隐私扩展地址的数量\nip -o addr show dev ens4v1 | grep temporary | wc -l 2 测试真实 IPv6 地址是否启用隐私扩展\r检查具有由 Privacy Extension 生成的接口 ID 的 IPv6 地址是否真的用于传出连接, 可以访问 ip.bieringer.de 测试生成的 IPv6 地址是否启用了隐私扩展。确保 EUI64_SCOPE 显示 iid-privacy\n原文\nCentOS 7: Enable Privacy Extension: Configuring IPv6 addresses\nWindows 7: IPv6 Temporary Address - Enable or Disable - How to Enable or Disable Temporary IPv6 Address Feature in Windows 7 and 8\n","date":"2019-03-08T02:06:00+08:00","permalink":"https://blog.acesheep.com/p/fix-ipv6-mac-address-leak/","title":"防止 IPv6 泄露 MAC 地址"},{"content":"当需要为混流视频生成 SUP 字幕文件时, 可以使用 avs2bdnxml 工具将 ASS/SSA/SRT 字幕转换为 SUP 格式, 以便在一些低级的高清播放机上播放特效字幕。\n作者没有提供已经构建好的版本. 所以需要自行构建\n下载与构建\r首先下载源码 avs2bdnxml-2.09.tar.bz2, 备用下载址: avs2bdnxml-2.09.tar.bz2\n在安装了 GCC 的 Linux 环境下, 执行以下命令构建程序\nmake 或者, 如果想要构建分发版本\nmake dist 准备字幕文件\r准备字幕。可以使用 SRT 或 ASS/SSA 格式生成字幕, 也可以预先生成 RGBA 视频\n创建 AviSynth 脚本\r要生成 SUP 字幕, 可以参考以下 AviSynth 脚本\nvideo=AviSource(\u0026#34;video.avi\u0026#34;)\r# 需要至少 VSFilter 2.39\rMaskSub(\u0026#34;subtitles.ext\u0026#34;, video.width, video.height, video.framerate, video.framecount) 实例 创建一个名为 srttosup.avs 的脚本, 内容如下\nvideo=LWLibavVideoSource(\u0026#34;X:\\zip2\\00800.1.hevc\u0026#34;)\rMaskSub(\u0026#34;C:\\Users\\Desktop\\Annihilation.2018.1080p.BluRay.x264.Atmos.TrueHD7.1-HDChina.ass\u0026#34;, 1920, video.height, video.framerate, video.framecount) 如果创建 RGBA 视频, 脚本示例如下\nAviSource(\u0026#34;subtitles_RGBA.avi\u0026#34;)\rFlipVertical() 运行程序\ravs2bdnxml -t Undefined -l und -v 1080p -f 23.976 -b1 -o output.xml input.avs 对于某些程序, 可能需要将 PNG 文件转换为 8 位 RGBA 调色板, 使用 -p 参数即可, 但 BDSupEdit 不需要此步骤\n输出格式\r生成的 BDN XML 格式示例\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;BDN Version=\u0026#34;0.93\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xsi:noNamespaceSchemaLocation=\u0026#34;BD-03-006-0093b BDN File Format.xsd\u0026#34;\u0026gt; \u0026lt;Description\u0026gt; \u0026lt;Name Title=\u0026#34;Undefined\u0026#34; Content=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Language Code=\u0026#34;und\u0026#34;/\u0026gt; \u0026lt;Format VideoFormat=\u0026#34;[ 480i / 480p / 576i / 720p / 1080i /1080p ]\u0026#34; FrameRate=\u0026#34;[ 23.976 / 24 / 25 / 29.97 / 50 / 59.94 ]\u0026#34; DropFrame=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;Events LastEventOutTC=\u0026#34;00:00:00:00\u0026#34; FirstEventInTC=\u0026#34;00:00:00:00\u0026#34; ContentInTC=\u0026#34;00:00:00:00\u0026#34; ContentOutTC=\u0026#34;00:00:00:00\u0026#34; NumberofEvents=\u0026#34;[ number of encoded frames ]\u0026#34; Type=\u0026#34;Graphic\u0026#34;/\u0026gt; \u0026lt;/Description\u0026gt; \u0026lt;Events\u0026gt; \u0026lt;Event Forced=\u0026#34;[ False / True ]\u0026#34; InTC=\u0026#34;00:00:00:00\u0026#34; OutTC=\u0026#34;00:00:00:00\u0026#34;\u0026gt; \u0026lt;Graphic Width=\u0026#34;0\u0026#34; Height=\u0026#34;0\u0026#34; X=\u0026#34;0\u0026#34; Y=\u0026#34;0\u0026#34;\u0026gt;000000.png\u0026lt;/Graphic\u0026gt; \u0026lt;/Event\u0026gt; \u0026lt;/Events\u0026gt; \u0026lt;/BDN\u0026gt; 后续步骤\r使用如 BDSupEdit 或 BDSup2Sub 的程序将 BDN XML 转换为 BD-SUP 文件。后续操作留给读者自行探索\n原文\nAviSynth rendered subtitles to BluRay SUP/PGS and BDN XML (v2.08)\nAVS to BluRay SUP/PGS and BDN XML\n","date":"2019-03-08T01:07:00+08:00","permalink":"https://blog.acesheep.com/p/create-sup-subtitles-with-avs2bdnxml-convert-ass-ssa-srt-to-sup/","title":"avs2bdnxml 制作 SUP 格式字幕 | ASS/SSA/SRT 字幕转 SUP"},{"content":"nc 是 netcat 的简写, 被誉为\u0026quot;网络界的瑞士军刀\u0026quot;, 因其短小精悍且功能实用, 是一款简易可靠的网络工具, 适用于 Windows 和 Linux 系统。它能够通过 TCP 或 UDP 协议读写数据, 因此非常适合作为网络调试和分析工具。\nnc 支持创建多种网络连接, 可用作服务器或客户端, 广泛应用于端口侦听、扫描、文件传输和网络测试等任务。\nnc 的主要功能\rTCP/UDP 端口侦听: 作为服务器端监听特定端口, 接收连接 端口扫描: 作为客户端发起 TCP 或 UDP 连接, 测试目标端口状态 文件传输: 在不同主机之间通过网络传输文件 网络测速: 测试网络连接速度 (虽然 iperf3 更适合网络速度测试) 基本语法\r语法 nc [-hlnruz][-g\u0026lt;网关...\u0026gt;][-G\u0026lt;指向器数目\u0026gt;][-i\u0026lt;延迟秒数\u0026gt;][-o\u0026lt;输出文件\u0026gt;][-p\u0026lt;通信端口\u0026gt;][-s\u0026lt;来源位址\u0026gt;][-v...][-w\u0026lt;超时秒数\u0026gt;][主机名称][通信端口...] 常用选项及参数说明\r参数 功能描述 -g \u0026lt;网关\u0026gt; 设置数据包发送路径中的网关 (最多可指定 8 个) -G \u0026lt;指向器数目\u0026gt; 设置源路由指向器, 值应为 4 的倍数 -h 显示帮助信息 -i \u0026lt;延迟秒数\u0026gt; 设置数据传输或端口扫描的间隔时间 -l 监听模式, 用于接收传入数据 (适合作为服务器端) -n 直接使用 IP 地址而不通过域名解析服务器 (减少 DNS 查询延迟) -o \u0026lt;输出文件\u0026gt; 指定输出文件, 将传输的数据以 16 进制格式保存到文件 -p \u0026lt;通信端口\u0026gt; 指定本地主机的端口 -r 随机选择本地与远程主机的端口 -s \u0026lt;来源位址\u0026gt; 设置本地主机送出数据包的 IP 地址。适用于多网卡机 -u 使用 UDP 协议传输数据 -v 显示详细输出信息, -vv 获取更多详细内容 -w \u0026lt;超时秒数\u0026gt; 设置等待连接的超时时间 -z 0 输入/输出模式 (用于端口扫描时, 不传输任何数据包) 使用示例\r简单聊天工具\r在两个设备间建立简易聊天通道\n在 192.168.2.34 上作为服务器端侦听 1234 端口\nnc -l 1234 在 192.168.2.33 上连接到该端口\nnc 192.168.2.34 1234 此时, 双方可以互相发送消息, 使用 Ctrl + C (或 Ctrl + D) 退出会话\n文件传输\r将文件从 192.168.2.33 传输到 192.168.2.34\n在 192.168.2.34 上监听 1234 端口并接收文件\nnc -l 1234 \u0026gt; test.txt 在 192.168.2.33 上发送文件\nnc 192.168.2.34 1234 \u0026lt; test.txt 传输完成后, test.txt 文件会保存在 192.168.2.34 上\n端口可用性测试\r用于检查目标主机端口是否可访问, 支持 TCP 和 UDP 两种模式\nTCP 模式\r在 192.168.2.34 上监听端口\nnc -l 1234 在 192.168.2.33 上连接到端口进行测试\nnc 192.168.2.34 1234 UDP 模式\r在 192.168.2.34 上使用 UDP 协议监听端口\nnc -lu 1234 在 192.168.2.33 上以 UDP 协议连接到端口\nnc -u 192.168.2.34 1234 注意事项\rnc 的 -z 选项非常适合端口扫描, 因为它不会发送实际数据。结合 -w 设置超时时间可以快速测试开放端口 使用 -v 可查看详细的操作日志, 适合调试时使用 文件传输可能因网络速度不同有所差异, 建议在稳定的网络环境下进行大文件传输 ","date":"2019-03-07T23:56:20+08:00","permalink":"https://blog.acesheep.com/p/netcat-port-testing/","title":"netcat 端口测试"},{"content":"H.264 与 x264\rH.264 (MPEG-4 AVC) 是一种高效的视频编码格式, 具有优越的压缩率, 能以较低的比特率提供较好的视频质量。就目前已成熟的视频编码格式而言, H.264的压缩率是最佳的。 x264 是一个开源的 H.264 编码器, 以出色的编码效率而闻名, 是目前最佳的开放源码 H.264 编码工具。 H.264 Profiles\rWikipedia - Advanced Video Coding - Profiles\nH.264 包含多个不同的 Profile, 用于适应不同的应用需求:\nBaseline Profile\r适合低成本和早期的移动设备使用, 目前已经很少采用\n主要用于低成本应用, 对播放设备的性能要求不高, 此 profile 常见用于早期性能较低的行动设备 (如 Apple iPod)。现今行动设备性能比起以前强大许多, 此 profile 已经没有什么必要性了\nMain Profile\r早期用于电视广播, 现今应用不多\n此 profile 原本是用于 SD 分辨率数码电视广播, 虽然没有实行, 然而被用于 HD 分辨率的电视广播。在 2004 年 High Profile 被开发之后, 此 profile 已经没有什么必要性了\n早期的高性能行动播放设备(如 Sony PSP), 也是使用此 profile\nHigh Profile\r广泛用于 HD 应用, 如 Blu-ray、高清电视和游戏机\n目前使用最广泛的 profile, 由其是 HD 分辨率电视应用 (如 Blu-ray / AVCHD 光盘储存、游戏机等电视多媒体播放器、HDTV DVB 广播服务)\n现今的行动播放设备都可以流畅播放用此 profile 的 SD 分辨率影片, 中阶等级可以上 720p 分辨率, 高阶甚至可上 FullHD (软解可能会有点吃力, 硬解完全没问题)\nHigh 10 Profile\r支持更高位深和更精确的色彩取样, 主要用于专业领域\n超越目前主流的消费型产品能力, 此 profile 建立在 High Profile 之上, 多了支持 10 bit 的精度, 色彩更精准。\n以影片压制而言, 将 High Profile (8 bit) 影片重新编码输出为 H.264 High 10 Profile , 虽然色彩精度不会变, 但至少压缩率比输出 High Profile (8 bit) 还要高。\nHigh 4:2:2 Profile\r针对专业领域应用, 此 profile 建立在 High 10 Profile 之上, 多了支持 4:2:2 色彩取样, 比特深度达 10 bit\nHigh 4:4:4 Predictive Profile\r支持最高的色彩精度和无损压缩, 适合专业需求\n此 profile 建立在 High 4:2:2 Profile 之上, 多了支持 4:4:4 色彩取样, 比特深度达 14 bit, 并且支持高效率无损重新编码, 且每张画面编码为三个独立的色彩平面\nH.264 Frame Types\r影片是由许多连续的 Frames 所组成, 但并不是所有 Frames 都是完整的画面, 那些 Frames 需要参考其他 Frames 才能解码出一张完整的画面。\nH.264 使用三种不同类型的帧, 以减少数据量和提高压缩效率:\nI-frame\r独立完整的帧, 可直接解码, 不依赖其他帧\n不需要参考其他 Frames, 是一张完整的画面。\nIDR frame 为真正的 关键帧 (keyframes), P-frame \u0026amp; B-frame 不会越过 IDR frame 去参考其他 Frames, 所以可以随意跳转到任意 IDR frame 开始播放/解码, 而不会发生问题。\nP-frame\r记录相对于前一帧的差异, 只保存变化部分, 提高压缩效率\n只记录了与之前的 Frames 相异的区块, 最多可以参考 16 张 之前的 Frames\n播放 / 解码时需要参用到之前的 Frames 的部分资料, 才能解码出完整画面\n在 x264 中, 你不能控制 P-frame 数量, 但你可以控制一个 P-frame 所能参考的 Frame 数量, 也就是 Reference frame (ref) 的数值\nB-frame\r利用前后两帧的信息记录差异部分, 具有最高的压缩率, 但增加了解码的复杂度\n只记录了与前一张与后一张的 Frames 相异的区块, 压缩率高(由其是在低动态/低变化的影片), 播放/解码时需要用到前后两张的 Frames 的部分资料, 才能解码出完整画面\n例子\r(登入后即可检视图片)\n从此图你可以发见 B-Frame 有用到前一张与后一张 Frame 的资料\n播放 Farme 的顺序是依照 Frame 的时间点, 但解码顺序则不一定, 当 B-Frame 有用到后一张 Frame 的资料时, 就必须预先解码后一张 Frame\n以上图为例\n解码(处理)顺序: 1-2-4-3\n显示(播放)顺序: 1-2-3-4\n由于 P-/B-frame 不是完整的画面, 解码时必须参考其他 Frames, 所以你不能随意跳转到 P-/B-frame 上播放/解码\n也就是说你如果播放 MPEG 视频格式, 当你跳播放时间点时, 正常而言, 并不会跳到你所选的时间点上, 而是最近的 IDR / I-frame\n就压缩率而言\u0026hellip;\n由于 P-/B-frame 并不是完整的画面, 所以占用的空间较少, 提高这类 Frame 使用量可以有效提升压缩率, 但对画质几乎不会降低, 这代表可以使用较少的 bitrate (比特率) 达到维持一定画质\n由以上得知, 在 bitrate 充足的情况下, 则不需要使用较多 B-frame、Reference frame (ref), 多少 bitrate 为充足依影片内容为定, 高动态影片需要较多 bitrate, 低动则较少\n至于使用时机\u0026hellip;\n提高 B-frame/ref 使用量可以降低 bitrate 的需求, 使用较少 bitrate 达到目标品质。低动态的影片可以使用较多的 B-frame, 高动态或是纯静态则是 P-frame 效果较好\n对于相容性与硬件负担\u0026hellip;\n提高 B-frame/ref 使用量的副作用是降相容性以及提高硬件负担, 请先保证相容性再来追求压缩率。\n而 ref 的副作用要比 B-frame 强, 例如 ref=16 这代表解码一个 P-frame 必须要连跳回 1~16 张之前的 Frames 取用资料。\nx264 参数设置\rMax B-frame (bframes)\r控制 B-frame 的最大数量, 用于提升压缩率。\n当设置 B-frame 时, 重复部分比较多/变化较少的 Frames 会被编码为 B-frame\nReference frame (ref)\r指定 P-frame 的参考帧 (Frames) 数量。适度提高该值可优化压缩效果, 但会增加硬件解码负担\n推荐设置\nMaximun B-frame: 3 - 6 Reference frame (ref): 3 - 5 GOP 长度\r指定关键帧 (IDR frame) 的间隔, 以便在跳转播放时保持解码的流畅性。\n一个 keyframe (IDR frame) 到下一个 keyframe 的范围。\n所以将 GOP 设为无限大虽然可以大幅增加压缩率, 但这样就不能随意跳转到其他时间点播放/解码。\n建议维持 default 即可\nProfile 和 Level\r决定视频的压缩比和硬件性能需求, Profile 越高代表更高的压缩率和更复杂的编码, 但要求设备具有更高的解码性能\ninterlaced (隔行扫描)\r支持编码输出 interlaced (隔行扫描) 的视频\nx264 预设 (Preset)\rx264 提供了多种预设选项 (Preset), 从 ultrafast 到 placebo, 用于控制编码速度和压缩效率的平衡。一般建议选择一个合适的预设以在编码效率和文件大小之间取得平衡。\n速度越慢则会得到更好的压缩编码效率 (画质-比特率比 或 画质-视频大小比)。也就是说, 若你设置一个目标比特率或是视频大小, 则越慢的 Preset 将会得到更好的输出品质。而对于设置一个恒定品质 (CRF) 或是恒定量化值 (QP), 你可以透过选择更慢的 Preset 来简单的节省比特率 (也就是得到更小的视频大小)。\n一般而言是使用你所能忍受的最慢 Preset。目前 Presets 依速度递减排序是\nultrafast superfast veryfast faster fast medium slow slower veryslow placebo 该默认 Preset 是 medium, 忽略 placebo 因为它会比 veryslow 浪费更多时间而且效果差异太小。\n而越慢的 Preset 其 Reference frame (ref) 值也越高, 例如 veryslow preset 的 ref 为 16。由于通常不需这么高的 ref, 你可以透过指定一个 Level 来限制 ref, 或是手动指定一个合理的 ref 值 (1 ~ 6)\nx264 微调 (Tune)\rTune 参数则是针对特定内容类型 (如电影、动画、低延迟等) 优化的设置, 以改善特定应用的压缩效果。\n压缩效果 内容类型 film (电影) 胶片电影、真人类型 animation (动画) 例如卡通/日本动画 grain (胶片颗粒) 颗粒感很重的影片。需要保留大量的 grain 时用 stillimage (静止影像) 例如幻灯片效果的影片。静态图像编码时使用 PSNR 优化 PSNR 值。 Wiki 为提高 psnr 做了优化的参数 SSIM 优化 SSIM 值。 Wiki 为提高 ssim 做了优化的参数 Fast Decode (快速解码) 用于低性能播放设备。可以快速解码的参数 (※ 压缩率极低) zerolatency (零延迟) 处里时间低延迟。主要用于直播等。用在需要非常低的延迟的情况下, 比如电视电话会议的编码。(※ 压缩率极低) 参考实例\r以下示例演示了如何应用基本选项来输出压缩高效的 H.264 视频文件\n常规压缩 (适用于一般影片)\nx264 --preset slow --crf 20 -o output.mp4 input.mp4 此命令使用 slow 预设, 以获得较高压缩比, CRF 设置为 20, 这将保持高画质\n动画影片 (适用于卡通或动画类型)\nx264 --preset medium --tune animation --crf 18 -o output.mp4 input.mp4 --tune animation 调整了编码参数, 以确保细节和动态画面效果适合动画\n低延迟设置 (适用于直播或会议场景)\nx264 --preset fast --tune zerolatency -o output.mp4 input.mp4 --tune zerolatency 适用于需要快速解码的实时场景\nH.264 Level\rH.264 的 Level 和 MaxDpbMbs 直接表示了播放设备的解码性能要求。Level 值越高, 设备的解码性能要求越高, 输出影片的压缩率也越高。\nMaxDpbMbs 对应的 Level\rWikipedia - Decoded picture buffering\nLevel MaxDpbMbs 1 396 1b 396 1.1 900 1.2 2,376 1.3 2,376 2 2,376 2.1 4,752 2.2 8,100 3 8,100 3.1 18,000 3.2 20,480 4 32,768 4.1 32,768 4.2 34,816 5 110,400 5.1 184,320 5.2 184,320 6 696,320 6.1 696,320 6.2 696,320 关系方程式\n强制指定 Level (限制 MaxDpbMbs)\nref = Min(Floor(MaxDpbMbs / (PicWidthInMbs * FrameHeightInMbs)), 16) $$\r\\text{ref} = \\min\\left(\\text{Floor}\\left(\\frac{\\text{MaxDpbMbs}}{\\text{PicWidthInMbs} \\times \\text{FrameHeightInMbs}} \\right), 16\\right)\r$$ Floor(x): 向下取整数, 小数点直接舍去。 ex. Floor(1.9) = 1 Min(x, y): 取比较小的数值。 ex. Min(2, 5) = 2 强制指定 ref\nMaxDpbMbs = PicWidthInMbs * FrameHeightInMbs * ref $$\r\\text{MaxDpbMbs} = \\text{PicWidthInMbs} \\times \\text{FrameHeightInMbs} \\times \\text{ref}\r$$计算 PicWidthInMbs 和 FrameHeightInMbs (小数点向上取整)\nPicWidthInMbs = Width / 16 FrameHeightInMbs = Height / 16 $$\r\\text{PicWidthInMbs} = \\frac{\\text{Width}}{16}\r$$$$\r\\text{FrameHeightInMbs} = \\frac{\\text{Height}}{16}\r$$示例\r输出设置\n分辨率: 1280x1720 Level: 不指定(自动) 参考帧 (ref): 4 计算 MaxDpbMbs:\n$$\r\\text{MaxDpbMbs} = 80 \\times 45 \\times 4 = 14400\r$$对照表得出 Level = 3.1\n输出设置\n分辨率: 1280x1720 Level: 3.1 参考帧 (ref): 不指定(自动) 计算 ref\n$$\r\\text{ref} = \\min\\left(\\text{Floor}\\left(\\frac{18000}{80 \\times 45}\\right), 16\\right) = \\min(5, 16) = 5\r$$输出 H.264 的 ref 可能为 4 或 5\n同时强制指定 ref 与 Level\nref 设置值不能大于 5 (强制指定 ref 不能超过 Level 的限制)\nx264 比特率控制\rx264 提供多种输出品质和比特率控制方式, 主要包括 Constant Rate Factor (CRF) 和 2-Pass Bitrate。速率控制是指决定多少比特将被用于每帧的方法。这将决定视频大小且品质如何分布。而 CRF 的比特率分配效果是最佳的, 若无控制输出大小的需求则使用 CRF 即可。\nConstant Quantizer (QP)\r每个帧获得相同品质 设置 x264 以恒定量化值 (Constant Quantizer) 模式来编码视频。此方法可以让每帧获得相同品质 (设置值)。\n设置值范围: 0 - 69, 0 为最无损, 默认值为 23。比较低的数值会得到比较高的品质, 合理的范围 21 - 28。\nConstant Ratefactor (CRF)\r自动分配比特率以达到设置品质 此方法允许编码器自动分配比特速率来试着达到一定输出品质。让每帧得到它需要的比特率来保持所需的品质等级。CRF 会得到最佳的比特速率分配结果, 缺点是你不能直接指定一个目标比特率或是视频大小。\n设置值范围为 0 - 51.0, 0 为最高品质, 默认值为 23。比较低的数值会得到比较高的品质, 合理的范围 18 - 28。考虑 18 为视觉无损 (或接近), 所以它看起来应该与输入相同 (或接近) 但它技术上不是无损。\nBitrate\r自定义比特率直接控制输出大小 可能导致比特率分配不均 自订 Bitrate 控制输出 Size, 直接编码输出视频。由于没有先扫描过一次, x264 无法得知影片各时间点的复杂程度。所以 x264 只能在编码中不断猜后之后的复杂程度, 这样将不能精准依各时间点的复杂程度等比例分配比特率, 因为如果之前分配了过多流量, 那么之后就必下修流量来使输出比特率平均值等于用户设置值\nBitrate, 2-Pass\r先扫描视频以获取复杂程度, 之后精确分配比特率 耗时较长, 结果接近 CRF 此方法让编码器 1st-Pass 将会得知影片各个帧的复杂程度, 2nd-Pass 时依照输入视频各个帧的复杂程度等比例分配比特数输出, 并且最终平均比特速率会等于设置值。2-Pass 比特速率分配结果会接近 CRF, 缺点是耗费大量时间\n1st-Pass CRF + 2-Pass Bitrate\r结合以上两种方法, 效果接近 CRF, 耗时较长 此方法让编码器在 1st-Pass 时将会得知影片各个帧所需要的比特数, 2nd-Pass 时依照各个帧所需要的比特数等比例分配使最终比特速率总平均值会等于设置值。2-Pass 比特速率分配结果会接近 CRF, 缺点是耗费大量时间\nx264 设置优先级\r设置优先级顺序\npreset -\u0026gt; tune -\u0026gt; 使用者设置选项 -\u0026gt; fast first pass -\u0026gt; profile -\u0026gt; level 当参数冲突时, 后者会取代前者或是影响前者\npreset slower 的参数为\n--b-adapt 2 --direct auto --me umh --partitions all --rc-lookahead 60 \\ --ref 8 \\ --subme 9 --trellis 2 当我设置\nx264 Preset: Slower Reference frame (ref): 4 等同于\n--b-adapt 2 --direct auto --me umh --partitions all --rc-lookahead 60 \\ --ref 4 \\ --subme 9 --trellis 2 输出 H.264 的 Reference frame (ref) 为 4\n当我设置\nx264 Preset: Slower Level: 3.2 输出 H.264 的 Reference frame (ref) 为 5\n基本用法\r基本语法\nx264 [选项] -o \u0026lt;输出\u0026gt; \u0026lt;输入\u0026gt; 输入格式支持\nraw 输入 YUV4MPEG (*.y4m) Avisynth (*.avs, 需要有支持的编码版) lavf / ffms 支持的输入格式 输出文件格式\n.264: Raw bytestream .mkv: Matroska .flv: Flash Video .mp4: MP4 (需要有 GPAC 的编译版) Piping 使用方法\r64bit 的 x264\r如果用了 64 位的 Windows, 就可以用 64 位的 x264。64 位的 x264 大约能比 32 位的 x264 快上 10% 左右, 能节省的时间还是比较可观的。但是用 AviSynth 输入时, 64 位的 x264 只接受 64 位的 AviSynth 输入, 32 位的 x264 只接受 32 位的 AviSynth。\n虽然现在有 64 位的 AviSynth 和不少常用的滤镜, 但是大多数人还是愿意用 32 位的 AviSynth。那么如何用让 64位的 x264 配合 32 位的 AviSynth 呢？\n方法是用 pipe。用命令行工具 (如 ffmpeg、mencoder 或 avs2yuv) 打开 avs, 让输出的 raw yuv 画面直接输入给 x264, 期间不产生中间文件。这个操作也是在命令行里实现的。\n使用 ffmpeg 输入\r先下载 ffmpeg 的 Windows 编译版, 可以用 static link 版本。和 x264 一样, ffmpeg 放在任何目录里都能运行, 假设和 x264、要进行编码的 input.avs 放在一个目录里\nffmpeg -i input.avs -f yuv4mpegpipe -an -v 0 - | x264 [options] --demuxer y4m -o output.264 - 先用 ffmpeg 打开 input.avs, 并不指定输出的文件, 而是以 - 代替输出的文件。后面写 |, 再写 x264, x264 的选项和输出文件写法不变, 但是输入文件写 -\n使用 mencoder 输入 (未测试)\rmencoder 有很多有价值的滤镜, 用起来也很方便。libx264 可以编译进 mencoder 本身, 和单独的 x264 效果一样。mencoder 也可以打开 avs 文件, pipe 给 64 位的 x264。mplayer-ww 的命令行版里就带有 mencoder\n同样假设 mencoder、x264 和要编码的 input.avs (1280x720) 在一个目录里\nmencoder input.avs -vf format=yv12 -of rawvideo -ovc raw -nosound -o - | x264 [options] --input-res 1280x720 --input-csp yv12 -o output.264 - 使用 avs2yuv 输入\ravs2yuv 本来是为了给 linux 上 wine 来用的, 因为 AviSynth 是运行在 Windows 的, 在 linux 里必须 wine avs2yuv 来打开 avs, 再 pipe 给 x264。当然也可以用来 pipe 给 64 位的 x264\n同样假设 avs2yuv、x264 和要编码的 input.avs 在一个目录里\navs2yuv input.avs - | x264 [options] --demuxer y4m -o output.264 - avs2yuv 的输出格式默认是 yuv4mpeg, x264 用 y4m 格式解码即可从中读取分辨率, 所以无须再用 --input-res 指定分辨率\n以上介绍了 3 种方法, 个人比较倾向于用 ffmpeg。2pass 的编码也是像上面所讲的方法一样\n原文\nWikipedia - H.264/MPEG-4 AVC\nVideoLAN - x264\nWikipedia - x264\nX264使用介绍 关于pipe\nx264 - 高品质 H.264 编码器\n","date":"2019-03-04T21:54:00+08:00","permalink":"https://blog.acesheep.com/p/x264-high-quality-h264-encoder/","title":"x264 - 高品质 H.264 编码器"},{"content":"本文介绍如何在 Linux 系统中开启内核转发, 并通过 iptables 实现多端口和单端口的端口转发。我们还将讨论在双网卡跳板机上配置端口转发的实例。\n开启内核转发\r首先, 你需要在系统中启用 IP 转发\nvim /etc/sysctl.conf # 在文件中添加或修改以下行 net.ipv4.ip_forward=1 # 保存并使修改生效 sysctl -p 端口转发\r用户 \u0026ndash;\u0026gt; 中转 IP \u0026ndash;\u0026gt; 目标 IP\n单端口转发\r将中转服务器 (IP 2.2.2.2) 的特定端口 (如 4000) 转发至目标服务器 (IP 1.1.1.1) 的同一端口\n# TCP 端口转发 iptables -t nat -A PREROUTING -p tcp --dport 4000 -j DNAT --to-destination 1.1.1.1:4000 # UDP 端口转发 iptables -t nat -A PREROUTING -p udp --dport 4000 -j DNAT --to-destination 1.1.1.1:4000 # 修改源地址为中转服务器 IP iptables -t nat -A POSTROUTING -p tcp -d 1.1.1.1 --dport 4000 -j SNAT --to-source 2.2.2.2 iptables -t nat -A POSTROUTING -p udp -d 1.1.1.1 --dport 4000 -j SNAT --to-source 2.2.2.2 多端口转发\r将中转服务器 (IP 2.2.2.2) 的 10000~30000 端口转发至目标服务器 (IP 1.1.1.1) 的 10000~30000 端口\n# TCP 端口转发 iptables -t nat -A PREROUTING -p tcp -m tcp --dport 10000:30000 -j DNAT --to-destination 1.1.1.1:10000-30000 # UDP 端口转发 iptables -t nat -A PREROUTING -p udp -m udp --dport 10000:30000 -j DNAT --to-destination 1.1.1.1:10000-30000 # 修改源地址为中转服务器 IP iptables -t nat -A POSTROUTING -p tcp -m tcp -d 1.1.1.1 --dport 10000:30000 -j SNAT --to-source 2.2.2.2 iptables -t nat -A POSTROUTING -p udp -m udp -d 1.1.1.1 --dport 10000:30000 -j SNAT --to-source 2.2.2.2 按需要替换对应的 中转服务器IP 和 目标服务器IP\n保存 iptables 配置\r这部分未测试\n查看规则\niptables --list-rule 导出和导入 iptables 配置\nmkdir /etc/iptables iptables-save \u0026gt; /etc/iptables.up.rules iptables-restore \u0026lt; /etc/iptables.up.rules 由于这种方式并不是下次启动就会自动加载 iptables 规则\n要确保在重启后自动加载 iptables 规则, 请执行以下步骤\n# 编辑 /etc/rc.local vim /etc/rc.local # 在 exit 0 前加入下面代码 iptables-restore \u0026lt; /etc/iptables.up.rules 查看和删除 NAT 规则\r查看 NAT 规则\riptables -t nat -vnL POSTROUTING iptables -t nat -vnL PREROUTING 删除 NAT 规则\r通过上面的查看规则命令, 查看规则后, 确定你要删除的规则的序号\n根据规则序号删除特定规则 (例如删除第一个规则)\niptables -t nat -D POSTROUTING 1 iptables -t nat -D PREROUTING 1 双网卡跳板机上的端口转发\r跳板机是双网卡, 有一个内网 IP 和一个公网 IP\n内网 IP: 10.0.10.30\n外网 IP: 58.68.255.123\n内网机器: 10.0.30.88, 可以和 10.0.10.30 通讯\n内网机器 (10.0.30.88) 需要通过公网去连接 ssh, 由于这台内网设备没有公网 IP 所以需要跳板机通过 iptables 做端口转发\n配置命令\r最初的命令可能会因为缺少路由而无法生效\n刚开始用的 Iptbales 做端口映射命令如下\niptables -t nat -A PREROUTING -p tcp -d 58.68.255.123 --dport 31688 -j DNAT --to-destination 10.0.30.88:22 iptables -t nat -A POSTROUTING -p tcp -d 10.0.30.88 --dport 22 -j SNAT --to-source 58.68.255.123 发现无法通过 58.68.255.123:31688 去 ssh 连接这台机器, 试了好几次都是如此, 开始想是不是因为双网卡原因\n查看跳板机路由表后发现 58.68.255.123 并没有到内网 10.0.10.0 的路由, 大概就是这个原因了\niptables 把请求转发到内网 10.0.30.88 后, 10.0.30.88 跨网段了无法把包通过 58.68.255.123 转发回客户端 (就是连接这台机器的 ssh 客户端)\n因为 10.0.30.88 无法回源, 必须通过 10.0.10.30 转发给 58.68.255.123 再转发给客户端, 大概明白这个道理就该知道怎么做了。\n修正后的命令\r要确保回复包能够正确返回, 需修改源地址\niptables -t nat -A PREROUTING -p tcp -d 58.68.255.123 --dport 31688 -j DNAT --to-destination 10.0.30.88:22 iptables -t nat -A POSTROUTING -p tcp -d 10.0.30.88 --dport 22 -j SNAT --to-source 10.0.10.30 --to-source 10.0.10.30 只是修改回源 IP 而已, 把回源地址更改为跳板机内网 IP, 这样就可以在跳板机上把请求转发给客户端了\n替代命令\r也可以使用 MASQUERADE 选项\niptables -t nat -A PREROUTING -p tcp -i em1 --dport 31688 -j DNAT --to 10.0.30.88:22 iptables -t nat -A POSTROUTING -j MASQUERADE 效果是一样的, 需要指定网卡, em1 为跳板机外网网卡\n以上第一次命令不生效原因主要还是跨网段的原因, 10.0.10.0/24 跨到 10.0.30.0/24, 导致这个问题, 如果公网 IP 转发端口的这台机器内网 IP也在 10.0.30.0/24 网段, 那么第一条命令是可以生效的。\n相关文章\niptables 命令、规则、参数详解\n原文\nnanopi neo利用iptables实现中继(中转/端口转发)\n[网络管理] iptables -m参数的含义\n双网卡Iptables端口转发\n","date":"2019-03-04T21:09:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-port-forwarding-with-iptables/","title":"CentOS 7 使用 iptables 端口转发"},{"content":"TeamSpeak 是一款老牌 VoIP 工具软件, 被国外广大游戏玩家所采用。国内用户可能不是很熟悉, 其实, TeamSpeak 是一款非常流行的跨平台 VoIP 和文本聊天应用程序, 可用于企业内部业务通信、教育和培训（讲座）、在线游戏以及朋友间的聊天沟通。TeamSpeak 提供了一种使用更简单、安全性强、语音质量高、系统和带宽利用率低的解决方案。软件采用客户机、服务器体系结构, 可以实时处理成千上万的用户。\nTeamSpeak 具有以下关键特性:\n易于使用, 高度可定制 高度可扩展性 支持高安全性标准 提供卓越的语音质量 允许低系统资源和带宽使用 支持强大的文件传输 支持健壮的权限系统 支持惊人的3D声音效果 允许移动连接 看到以上特性, 感觉这就是一个私密的语音聊天服务器么, 是不是有些心动, 想搭建一台属于自己的 TeamSpeak 服务器呢？如果有 VPS 服务器, 并且想搭建 TeamSpeak 服务器的朋友注意了, 本文将详细讲解如何在 CentOS 7 系统搭建 TeamSpeak 服务器, 并对相关细节进行说明。\nCentOS 7 系统安装 TeamSpeak 服务器\r升级系统并安装依赖\r在进行服务器安装之前, 首先使用如下命令升级 CentOS 7 系统并安装 TeamSpeak 服务器所需的依赖工具包\nyum update yum install vim wget perl tar net-tools bzip2 创建 TeamSpeak 用户\r出于安全性的考虑, TeamSpeak 服务器并不建议使用 root 用户来执行, 所以我们可以创建一个用户 teamspeak 来单独执行 TeamSpeak 服务器程序。使用如下命令创建用户 teamspeak 并为其设置密码:\nadduser teamspeak passwd teamspeak 下载并配置 TeamSpeak 服务器\r从 TeamSpeak 官方网站下载最新版的服务器程序, 解压后将文件拷贝到 teamspeak 用户的家目录, 方便授权及文件管理\nwget https://files.teamspeak-services.com/releases/server/3.13.6/teamspeak3-server_linux_amd64-3.13.6.tar.bz2 tar -xjf teamspeak3-server_linux_amd64-3.13.6.tar.bz2 mv teamspeak3-server_linux_amd64 /home/teamspeak/ # 设置文件权限 chown -R teamspeak:teamspeak /home/teamspeak/teamspeak3-server_linux_amd64/ find /home/teamspeak/teamspeak3-server_linux_amd64 -type d -exec chmod 705 {} + find /home/teamspeak/teamspeak3-server_linux_amd64 -type f -exec chmod 604 {} + chmod 705 /home/teamspeak/teamspeak3-server_linux_amd64/ts3server 手动启动 TeamSpeak 服务\r当全部文件就位, 就可以切换成 teamspeak 用户来启动 TeamSpeak 服务器了。如果浏览过程序目录的话, 就会发现 TeamSpeak 服务器程序已经很方便使用了, 完全的绿色版, 无需安装直接运行, 并且程序还提供了服务器管理脚本, 方便操作服务器。\n启动 TeamSpeak 服务器命令如下\nsu - teamspeak cd teamspeak3/ # 首次启动时需要设置授权文件 touch .ts3server_license_accepted ./ts3server_startscript.sh start 第一次启动服务器时, 会出现如下提示\n可以看到, 程序会提示创建了一个服务器管理员帐户, 并且创建了一个管理服务器的 token 字符串, 这个 token 串是通过客户端管理服务器的, 所以会着重提醒。\n常见问题\r如果出现错误提示, 表示缺少授权文件, 可以创建该文件\n之后再使用之前的命令启动服务器, 就可以正常启动服务器了。\nAccounting failed to register\nERROR |Accounting | |failed to register local accounting service: File exists 如果遇到了这个错误需要删除这个文件\nrm -f /dev/shm/7gbhujb54g8z9hu43jre8 添加 systemctl 服务\r为了管理服务器方便, 可以将 TeamSpeak 服务器添加为 CentOS 服务, 在 /lib/systemd/system/ 目录中添加一个名为 ts3.service 的文件, 使用如下命令:\nsu - vim /lib/systemd/system/ts3.service 在文件中添加以下内容\n[Unit] Description=TeamSpeak 3 Server Wants=network-online.target After=network.target [Service] Type=simple User=teamspeak Group=teamspeak WorkingDirectory=/home/teamspeak/teamspeak3-server_linux_amd64/ ExecStart=/home/teamspeak/teamspeak3-server_linux_amd64/ts3server license_accepted=1 RestartSec=15 Restart=always [Install] WantedBy=multi-user.target 然后使用如下命令启动 TeamSpeak 服务, 并将其设置为开机自动启动, 最后查看服务状态\nsystemctl start ts3 systemctl enable ts3 systemctl status ts3 如果见到如下提示, 就表示服务已经添加成功, 并且工作正常了\n好了, 现在 TeamSpeak 服务器就安装完成了, 可以通过 systemctl 命令来方便管理, 并且开机可以自行启动。\n配置防火墙\rCentOS 7 默认是安装并启用了防火墙的, 现需要通过以下命令将 TeamSpeak 服务器侦听的所有端口都打开\nfirewall-cmd --add-port=9987/udp --permanent firewall-cmd --add-port=10011/tcp --permanent firewall-cmd --add-port=30033/tcp --permanent firewall-cmd --reload firewall-cmd --list-all 所有操作都完成后, 服务器就搭建完成。\nTeamSpeak 客户端的使用\r服务器搭建好后, 还需要一些基本的设置, 不然服务器就没有个性。\n这里演示如何使用 windows 客户端来管理服务器。客户端的下载和安装这里就不再讲解, 根据自己系统版本下载安装程序自行安装即可。\n安装完成后, 连接自己搭建的服务器, 会看到如下提示询问是否使用 token\n还记得之前生成的 token 吗, 将这个密钥输入到对话框中, 就会得到服务器的管理权限, 就可以对服务器进行相关设置了。\n选中服务器, 然后点击右键选择 Edit Virtual Server 菜单, 就可以进行服务器管理了, 典型设置如下图所示\n当然, 还可以对服务器及聊天频道等内容进行更多的设置, 这里不再进行演示。\n至此, 通过 VPS 搭建 TeamSpeak 服务器的主要工作就完成了, 当然还可以进行其它内容的细化, 包括服务器的其它配置等, 这里就不再赘述, 因为理论上不影响主要功能的使用。\n原文\nCentOS 7系统搭建TeamSpeak服务器详细教程\nTeamSpeak 3 - Accounting failed to register\n","date":"2019-03-04T20:24:00+08:00","image":"https://blog.acesheep.com/p/centos-7-teamspeak-server-setup-guide/4097974873_hu9456681849736649547.jpg","permalink":"https://blog.acesheep.com/p/centos-7-teamspeak-server-setup-guide/","title":"CentOS 7 系统搭建 TeamSpeak 服务器详细教程"},{"content":"今天在给一台电脑配置 MySQL 时, 使用 root 账户创建了一个新的用户, 设置了密码并指定了允许登录的 Host, 同时授权了所有权限。但是却一直无法使用这个账户登录到 MySQL 里\n尝试使用该账户登录时, 出现了以下错误\nERROR 1045 (28000): Access denied for user \u0026#39;laravel\u0026#39;@\u0026#39;localhost\u0026#39; (using password: YES) 问题分析\r经过多次尝试, 我找了一个解决方案\n发现 MySQL 中默认存在一个用户名为空的账户。在本地环境下, 可以不用输入账号密码即可登录到 MySQL 中。而因为这个账户的存在, 导致了使用密码登录无法正确登录。\n解决方案\r以 root 账户登录 MySQL\nmysql -u root 选择 mysql 库\nuse mysql; 删除用户名为空的账户\ndelete from user where User=\u0026#39;\u0026#39;; 刷新权限\nflush privileges; 完成上述步骤后, 就可以使用新创建的用户及密码成功登录 MySQL 了\n原文\n解决MySQL新建用户后无法登录问题\n","date":"2019-03-04T19:38:00+08:00","permalink":"https://blog.acesheep.com/p/fix-mysql-new-user-login-issues/","title":"解决 MySQL 新建用户后无法登录问题"},{"content":"Rocket.Chat 是一个完整的团队沟通平台, 是一个自我托管的 Slack 替代品。它由 Meteor 构建, 提供多种功能, 包括帮助台聊天、视频会议、文件共享、语音消息、API等。\n在本教程中, 我们将向你展示如何在使用 Nginx SSL 反向代理在 CentOS 7 服务器 (至少 1GB 内存) 上部署 Rocket.Chat v0.69.1\n安装基础环境\ryum install epel-release curl GraphicsMagick gcc-c++ yum install nodejs npm nginx # 安装 Node.js npm install -g inherits n n 8.11.3 安装 MongoDB\rMongoDB 是一个面向 NoSQL 文档的数据库\nRocket.Chat 建议使用 MongoDB 3.6。使用 yum 安装官方 MongoDB 存储库\nvim /etc/yum.repos.d/mongodb-org.repo # 把下面的复制进去 [mongodb-org-3.6] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc :wq 保存并退出\n安装 MongoDB 并设置开机启动\nyum install mongodb-org systemctl start mongod systemctl enable mongod 创建新用户\r创建一个新用户和组, 使用 rocket 运行 Rocket.Chat\nuseradd -m -U -r -d /opt/rocket rocket 将 nginx 用户添加到新用户组并更改 /opt/rocket 目录权限, 以便 nginx 可以访问它\nusermod -a -G rocket nginx chmod 750 /opt/rocket 安装 Rocket.Chat\r# 切换到 rocket 用户 su - rocket # 下载最新稳定版的 Rocket.Chat curl -L https://releases.rocket.chat/latest/download -o rocket.chat.tgz # 解压并重命名文件夹 tar zxf rocket.chat.tgz mv bundle Rocket.Chat # 进入到 Rocket.Chat/programs/server 目录并安装所有必需的 npm 包 cd Rocket.Chat/programs/server npm install 在创建系统服务和使用 Nginx 反向代理之前, 最好先测试安装是否成功\n设置所需的环境变量\rexport PORT=3000 export ROOT_URL=http://example.com:3000/ export MONGO_URL=mongodb://localhost:27017/rocketchat 返回 Rocket.Chat 目录并启动 Rocket.Chat 服务器\ncd ../../ node main.js 如果没有错误, 应该看到如下输出\n➔ +---------------------------------------------+ ➔ | SERVER RUNNING | ➔ +---------------------------------------------+ ➔ | | ➔ | Rocket.Chat Version: 0.71.1 | ➔ | NodeJS Version: 8.11.3 - x64 | ➔ | Platform: linux | ➔ | Process Port: 3000 | ➔ | Site URL: http://0.0.0.0:3000/ | ➔ | ReplicaSet OpLog: Disabled | ➔ | Commit Hash: e73dc78ffd | ➔ | Commit Branch: HEAD | ➔ | | ➔ +---------------------------------------------+ 此时, Rocket.Chat 已经安装在 CentOS 7 机器上。按下 CTRL+C 停止 Rocket.Chat 服务器\n创建系统服务\rvim /etc/systemd/system/rocketchat.service # 把下面的复制进去 [Unit] Description=Rocket.Chat server After=network.target nss-lookup.target mongod.target [Service] StandardOutput=syslog StandardError=syslog SyslogIdentifier=rocketchat User=rocket Environment=MONGO_URL=mongodb://localhost:27017/rocketchat ROOT_URL=http://example.com:3000/ PORT=3000 ExecStart=/usr/local/bin/node /opt/rocket/Rocket.Chat/main.js [Install] WantedBy=multi-user.target 刷新系统服务, 并启动 Rocket.Chat\nsystemctl daemon-reload systemctl start rocketchat 检查是否启动成功\nsystemctl status rocketchat ● rocketchat.service - Rocket.Chat server Loaded: loaded (/etc/systemd/system/rocketchat.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2018-04-10 20:30:56 UTC; 8s ago Main PID: 32356 (node) CGroup: /system.slice/rocketchat.service └─32356 /usr/local/bin/node /opt/rocket/Rocket.Chat/main.js 如果没有错误, 可以设置开机自动启动\nsystemctl enable rocketchat 使用 Nginx 设置反向代理\rvim /etc/nginx/conf.d/rocket.chat.conf 在文件中添加以下配置\nupstream rocketchat_backend { server 127.0.0.1:3000; } server { listen 80; server_name example.com www.example.com; return 301 https://example.com$request_uri; } server { listen 443 ssl http2; server_name example.com; ssl_certificate /SSL/example.com.crt; ssl_certificate_key /SSL/example.com.key; # ssl_trusted_certificate /SSL/example.com.pfx; # ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers \u0026#39;ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256\u0026#39;; ssl_prefer_server_ciphers on; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 30s; add_header Strict-Transport-Security \u0026#34;max-age=15768000; includeSubdomains; preload\u0026#34;; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; access_log /var/log/nginx/example.com-access.log; error_log /var/log/nginx/example.com-error.log; location / { proxy_pass http://rocketchat_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \u0026#34;upgrade\u0026#34;; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; proxy_set_header X-Forward-Proto http; proxy_set_header X-Nginx-Proxy true; proxy_redirect off; } } 重新加载 Nginx 服务以使更改生效\nsystemctl reload nginx 配置 Rocket.Chat\r打开浏览器并输入: http://chat.example.com\n如果安装成功, 你将看到 Rocket.Chat 安装向导, 它将指导你设置第一个管理员用户和配置账号信息\n配置完成后即可进入 Rocket.Chat\n你现在可以开始使用 Rocket.Chat 与你的团队协作, 共享文件和实时聊天\n原文\nHow to deploy Rocket.Chat on CentOS 7\nSecure Nginx with Let\u0026rsquo;s Encrypt on CentOS 7\n","date":"2019-02-21T21:04:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-install-rocket.chat/","title":"CentOS 7 安装 Rocket.Chat"},{"content":"nVidia GTX 10 系列的 Threads 和 Blocks 设置\r根据我的计算, 以下是适合 GTX 10 系列显卡的设置:\nBlocks: 使用 SMXx4 作为块的设置似乎是最佳值 Threads: 每块的线程数不应超过 32 理想设置\rTxB (Threads x Blocks) CN Lite: 每线程 1MB 的内存需求 CN: 每线程 2MB 的内存需求 CN Heavy: 每线程 4MB 的内存需求 对于 CN Lite, 可以使用与 CN 相同的设置或将 Blocks 加倍, 以找出哪种设置的哈希效率更高\n内存使用\rWindows 系统会保留大约 21% 的显存, 因此可用显存会小于安装的显存。具体可用显存的数值因型号而异, 欢迎在评论中分享, 以便更新计算结果。我目前只有 GTX 1060 3GB 卡\n效率总结\r效率最高: 1050 Ti 4GB 用于 CN Heavy 效率最低: 1060 3GB GTX Model Memory Cores SMX Blocks CN Threads CNH Threads Linux CNH Threads Win Titan Xp 12GB 3840 30 120 32 25 20 Titan X 12GB 3584 28 112 32 27 21 1080 Ti 11GB 3584 28 112 32 25 19 1080 8GB 2560 20 80 32 25 20 1070 Ti 8GB 2432 19 76 32 26 21 1070 laptop 8GB 2048 16 64 32 32 25 1070 8GB 1920 15 60 32 32 27 1060 6GB 1280 10 40 32 32 30 1060 3GB 1152 9 36 32 21 16 1050 Ti 4GB 768 6 24 32 32 32 1050 2GB 640 5 20 32 25 20 1050 laptop 4GB 640 5 20 32 32 32 1030 2GB 384 3 12 32 32 32 本文工具在 xmrig 文件夹\n原文\nThreads and Blocks for nVidia GTX 10 series\nMANUAL - How to setup XMRig nVidia miner for newbies\n","date":"2019-02-21T17:30:00+08:00","permalink":"https://blog.acesheep.com/p/xmrig-nvidia-optimization-for-gtx-10-series-mining/","title":"xmrig-nvidia 10 系列 N 卡挖矿优化"},{"content":"UPS (Uninterrupted Power System) 利用电池化学能作为后备能量, 在市电断电等电网故障时, 不间断地为用户设备提供 (交流) 电能的一种能量转换装置。\n购买 UPS\r购买 UPS 的时候尽量购买在线式的 UPS\n在线式 UPS, 提供正弦波输出, 价格较贵但效果好, 噪音大 后备式 UPS, 通常输出模拟正弦波或方波, 效果差, 不工作时很安静 (不推荐, 没钱还是用这个吧) 由于官方没有为 Linux 提供配套的守护程序, Apcupsd 是一个社区维护的项目\nApcupsd 安装及配置\rUPS 配给了一条是 USB+串口 的电缆。我们使用这条电缆将 UPS 和服务器相连接\n# 安装 USB 工具 yum install libusbx libusb usbutils # lsusb 这里可以检查 UPS 的 usb 有没有被识别 lsusb Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 005: ID 051d:0002 American Power Conversion Uninterruptible Power Supply Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub # usb-devices 这个可以展示 usb 的详细信息 usb-devices T: Bus=01 Lev=01 Prnt=01 Port=13 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=00(\u0026gt;ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=051d ProdID=0002 Rev=00.90 S: Manufacturer=American Power Conversion S: Product=Back-UPS RS 1500G FW:878.L5 .I USB FW:L5 S: SerialNumber=******** C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=2mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid # 安装 Apcupsd yum install apcupsd 配置 Apcupsd\r编辑配置文件 /etc/apcupsd/apcupsd.conf, 以下是推荐的配置示例\n# 用于将 UPS 连接到计算机的电缆类型。采用 USB 接口 UPSCABLE usb # 拥有的 apcups 类型, DEVICE 留空它会自动识别 UPSTYPE usb DEVICE # 每 60秒 轮询一次 UPS 状态 POLLTIME 60 # Apcupsd 为指定目录中的串行或 USB 端口创建一个锁文件。 LOCKFILE /var/spool/lock # Apccontrol 和事件脚本所在的目录。 SCRIPTDIR /usr/local/etc/apcupsd # POWERFAIL 和 NOLOGIN 文件放到 /var/run (实际上并不需要) PWRFAILDIR /var/run NOLOGINDIR /var/run # 等待 6秒 才开始真正的 ONBATTERY 操作: 如果电源只是短暂地发生瞬断则不做反应。 ONBATTERYDELAY 6 # 当停电导致电池剩余容量低于 8% 时, 立即执行关机操作。默认值为 5 BATTERYLEVEL 8 # 当停电导致剩余容量低于 3分钟时, 立即执行关机操作。 MINUTES 3 # 0 禁止按掉电时间为关机判断条件。发生电源故障后, apcupsd 将在指定的秒数过期后关闭系统。 TIMEOUT 0 # 指定请求登录用户从系统注销的广播消息之间的时间 (以秒为单位)。仅当 UPS 使用电池运行时, 此计时器才会启动。每 5分钟 (300s) 警告一次登录的用户系统发生掉电。 ANNOY 300 # 首次掉电后 1分钟 (60s) 告知登录的用户发生掉电。 ANNOYDELAY 60 # 禁止在掉电时阻止用户登录。 NOLOGON disable # 禁止 apcupsd 关闭电源。 KILLDELAY 0 # 启用 NIS 服务 (提供让 munin 收集的 UPS 数据)。 NETSERVER on # NIS 服务监听 127.0.0.1:3551 NISIP 127.0.0.1 NISPORT 3551 # 在 /var/log/apcupsd.events 中记录 \u0026#34;事件\u0026#34;。 EVENTSFILE /var/log/apcupsd.events EVENTSFILEMAX 1024 # 设置 ups 的模式, 我们主要用主从模式 UPSCLASS standalone # 设置为 \u0026#34;禁用\u0026#34; 以进行正常的独立操作, 指示你正在禁用 Share-UPS 接口扩展器支持。 UPSMODE disable STATTIME 0 STATFILE /var/log/apcupsd.status LOGSTATS off DATATIME 0 FACILITY DAEMON SENSITIVITY H # UPS 在供电恢复后等待 60秒 再恢复对设备的供电 WAKEUP 60 LOWBATT 02 # 每两周进行一次自检 SELFTEST 336 配置完了需要重启 Apcupsd 服务\nsystemctl restart apcupsd 设置开机启动\nsystemctl enable apcupsd 检查 Apcupsd 运行状态\r使用 apcaccess 检查是否正常运行\nAPC : 001,038,0986 DATE : 2019-02-21 17:22:55 +0800 HOSTNAME : NAS VERSION : 3.14.14 (31 May 2016) redhat UPSNAME : UPS-Network CABLE : USB Cable DRIVER : USB UPS Driver UPSMODE : Stand Alone STARTTIME: 2019-01-16 21:31:05 +0800 MODEL : Back-UPS RS 1500G STATUS : ONLINE LINEV : 236.0 Volts LOADPCT : 26.0 Percent BCHARGE : 100.0 Percent TIMELEFT : 25.0 Minutes MBATTCHG : 10 Percent MINTIMEL : 6 Minutes MAXTIME : 0 Seconds SENSE : Medium LOTRANS : 176.0 Volts HITRANS : 294.0 Volts ALARMDEL : 30 Seconds BATTV : 27.2 Volts LASTXFER : Automatic or explicit self test NUMXFERS : 4 XONBATT : 2019-02-16 08:34:11 +0800 TONBATT : 0 Seconds CUMONBATT: 67 Seconds XOFFBATT : 2019-02-16 08:34:21 +0800 LASTSTEST: 2019-02-16 08:34:11 +0800 SELFTEST : NO STATFLAG : 0x05000008 SERIALNO : ****** BATTDATE : 2017-11-08 NOMINV : 230 Volts NOMBATTV : 24.0 Volts NOMPOWER : 865 Watts FIRMWARE : 878.L5 .I USB FW:L5 END APC : 2019-02-21 17:23:00 +0800 原文\nApcupsd UPS control software\nAPC UPS Daemon unter CentOS 7.x\nCentos7下ups监控apcupsd的使用\n配合 APC BE550G UPS 的 apcupsd 配置\n","date":"2019-02-21T16:18:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-apc-ups-daemon-apcupsd-setup/","title":"CentOS 7 配置 APC UPS 监控软件 Apcupsd"},{"content":"使用 LVM 分区把 vps 变成大盒子\n安装系统时使用 LVM 分区\r安装系统时, 需要在后台进入 Rescue 模式\n输入 installimage 或者按向上的方向键会有历史命令回车后会弹出配置文件让你编辑, 在分区那里需要这么写\nPART /boot ext4 512M PART lvm vg0 all LV vg0 root / ext4 all 双击 Esc 退出, 正常安装就行, 之后 LVM 分区就挂载在 / 这里了\n重启并合并新 Volume\r重启后, 进入系统, 在 Volume 页面创建并附加 (attach) 新的 Volume。通常, 系统安装在 /dev/sda, 新的 Volume 在 /dev/sdb。执行以下命令将分区合并\npvcreate -ff /dev/sdb vgextend vg0 /dev/sdb lvresize -l +100%FREE vg0/root resize2fs /dev/vg0/root 执行以上命令的步骤:\n在 /dev/sdb 上创建 Physical Volume 将 Volume Group vg0 扩展到 /dev/sdb 上 将 Logical Volume vg0/root 扩展到所有可用空间 扩展 /dev/vg0/root 上的文件系统 检查结果\r通过以下命令检查效果\npvdisplay vgdisplay lsblk 详细输出\nroot@sb1 ~ # pvdisplay --- Physical volume --- PV Name /dev/sda2 VG Name vg0 PV Size \u0026lt;37.65 GiB / not usable 2.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 9637 Free PE 0 Allocated PE 9637 PV UUID ZbfxjP-RNf5-ScPU-eclg-dMjj-0WKg-T3FA2p --- Physical volume --- PV Name /dev/sdb VG Name vg0 PV Size 750.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 191999 Free PE 191999 Allocated PE 0 PV UUID ZphGg0-2XcJ-Kjzy-gfBX-7pSp-Wo4L-fbVkD5 root@sb1 ~ # vgdisplay --- Volume group --- VG Name vg0 System ID Format lvm2 Metadata Areas 2 Metadata Sequence No 3 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 2 Act PV 2 VG Size 787.64 GiB PE Size 4.00 MiB Total PE 201636 Alloc PE / Size 9637 / 37.64 GiB Free PE / Size 191999 / \u0026lt;750.00 GiB VG UUID 7It9l8-70zz-03Uk-8md3-mPBZ-o7fe-clN3QX root@sb1 ~ # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 38.2G 0 disk ├─sda1 8:1 0 512M 0 part /boot └─sda2 8:2 0 37.7G 0 part └─vg0-root 253:0 0 787.7G 0 lvm / sdb 8:16 0 750G 0 disk └─vg0-root 253:0 0 787.7G 0 lvm / sr0 11:0 1 1024M 0 rom 在完成了所有命令之后, 可以在 lsblk 中看到 / 已经扩充到了 787.7G\n通过 LVM 逻辑卷扩展 swap 分区\r在我们日常运维工作中, 偶尔也会遇到需要扩展 swap 空间的操作。扩展 swap 空间的方法很多, 现在让我们一起来探讨一下, 在 LVM 下扩展 swap 空间的方法\n在 CentOS 7 中, 扩展 LVM 下的 swap 空间的步骤如下\n查看一下卷组空闲空间, 是否还有空闲空间能用于扩展 swap 分区\nvgdisplay 从倒数第二行, 我们可以看到, 本机 CentOS 卷组的空闲空间小于 5GB, 分出 1GB 来扩展 swap 空间足够了\n查看逻辑卷\nlvdisplay 逻辑卷 swap 的路径为 /dev/centos/swap\n扩展逻辑卷 swap\n[root@Geeklp201 ~]# lvextend -L 2GB /dev/centos/swap Size of logical volume centos/swap changed from 1.00 GiB (256 extents) to 2.00 GiB (512 extents). Logical volume centos/swap successfully resized. 扩展成功! 然而, 用 free 命令看一下, 当前 swap 空间并未增加。还需要执行以下几步\n更新 swap 设置\n[root@Geeklp201 ~]# lvextend -L 2GB /dev/centos/swap # 在操作之前最好把将缓冲区的数据写 入磁盘 [root@Geeklp201 ~]# sync;sync [root@Geeklp201 ~]# swapoff /dev/centos/swap [root@Geeklp201 ~]# mkswap /dev/centos/swap mkswap: /dev/centos/swap: warning: wiping old swap signature. 正在设置交换空间版本 1, 大小 = 2097148 KiB 无标签, UUID=4250fdac-92c1-43f4-b266-c9d9c69a2783 [root@Geeklp201 ~]# swapon /dev/centos/swap 增加成功！都不用去修改 fstab 文件, 是不是很方便？\nLinux LVM简明教程 图片备份\r原文\nHetzner Cloud Volume 功能的使用\nLinux LVM简明教程\n新玩法, CentOS7中LVM通过扩展逻辑卷扩展swap空间\n","date":"2019-02-21T14:07:00+08:00","permalink":"https://blog.acesheep.com/p/hetzner-cloud-volume-lvm-partitioning-and-swap-space/","title":"Hetzner Cloud Volume | LVM 分区 | swap 空间"},{"content":"在 web.config 文件中找到 system.net 节点, 在节点里加入即可.\n\u0026lt;system.net\u0026gt; \u0026lt;defaultProxy\u0026gt; \u0026lt;proxy proxyaddress=\u0026#34;http://10.0.2.231:42\u0026#34; bypassonlocal=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;/defaultProxy\u0026gt; \u0026lt;/system.net\u0026gt; 原文\nHow to set proxy settings for IIS processes?\n","date":"2019-01-17T17:44:00+08:00","permalink":"https://blog.acesheep.com/p/iis-10-web-server-proxy-setup-route-requests-through-proxy/","title":"IIS 10 网页服务器设置代理 | 服务器请求走代理"},{"content":"Linux 下代理一般是通过 http_proxy 和 https_proxy 这两个环境变量, 但是很多软件并不使用这两个变量, 导致流量无法走代理。 在不使用 vpn 的前提下, linux 并没有转发所有流量的真全局代理。但是可以用 proxychains-ng 为程序指定走代理, proxychains-ng 是 proxychains 的新版. ng 含义是 new generation\n项目地址: rofl0r/proxychains-ng\n主要有以下功能\n支持 HTTP 或者 SOCKS4a/5 代理 认证 远端 dns 查询 多种代理模式 缺点\n仅支持 TCP, 不支持 UDP/ICMP 转发 少部分程序和在后台运行的可能无法代理 安装 ProxyChains-NG\rwget https://github.com/rofl0r/proxychains-ng/archive/v4.13.tar.gz -O Proxychains-ng-4.13.tar.gz tar xzf Proxychains-ng-4.13.tar.gz cd proxychains-ng ./configure --prefix=/usr --sysconfdir=/etc # 如果不是 root 用户 ./configure --prefix=$HOME/proxychains --sysconfdir=$HOME/proxychains make make install make install-config # 如果不是 root 用户, 设置别名 alias pc=\u0026#39;$HOME/proxychains/bin/proxychains4 -q\u0026#39; 配置 ProxyChains-NG\r编辑配置文件 /etc/proxychains.conf\nvim /etc/proxychains.conf 在文件最后将 socks4 127.0.0.1 9095 改为 socks5 127.0.0.1 1080\n代理模式\rProxychains-ng支持多种代理模式:\ndynamic_chain : 按照代理列表顺序自动选取可用代理 strict_chain : 按照代理列表顺序使用代理, 所有代理必须可用 round_robin_chain : 轮询模式, 自动跳过不可用代理 random_chain : 随机模式 使用方法\r可以用 proxychains4 代理一个 shell, 在 shell 中执行的命令就会自动使用代理了, 例如\nproxychains4 -q /bin/bash ","date":"2019-01-11T18:13:00+08:00","permalink":"https://blog.acesheep.com/p/compile-and-install-proxychains-ng/","title":"CentOS 7/Ubuntu 16 编译安装 Proxychains-ng"},{"content":"Alibabaprotect 是阿里巴巴的全家桶插件, 此进程不仅会占用大量内存和 cpu 性能, 会在后台悄悄的监控你的上网过程, 还在后台监控你的一举一动, 然后给你精准推送广告, 所以它不仅仅是一个文件, 还是一个恶意软件。而且 Alibabaprotect 非常难删除, 删掉后重启电脑又会自动出现, 是一个名副其实的流氓软件.\n删除 AlibabaProtect.exe\n下载 Autoruns 系统管理工具\n以 管理员权限 启动 Autoruns64.exe\n选择 Drivers 选项卡\n找到 AliPaladin 驱动, 右键点击, 选择 Delete 删除\n重启计算机\n删除以下文件\n删除 %systemroot%\\system32\\drivers 下的 AliPaladin.sys 驱动文件 删除 %SystemDrive%\\Program Files (x86)\\AlibabaProtect 整个目录 阿里巴巴的这款软件是一种带有自我保护特性的驱动级 \u0026ldquo;安全软件\u0026rdquo;。要完全清除这类软件, 必须先将相关驱动从内核加载的驱动列表中移除, 然后再进行文件删除。\n原文\n干掉AlibabaProtect.exe的正确方式\n","date":"2019-01-07T14:43:00+08:00","permalink":"https://blog.acesheep.com/p/delete-alibaba-pc-safe-service/","title":"优雅的干掉 AlibabaProtect.exe | 彻底删除 Alibaba PC Safe Service"},{"content":"在国外论坛扒了一分比较全的配置优化参数, 可以在 ltconfig 上优化. 配置适用于 Deluge 1.3.15\nactive_limit = 2000; active_seeds = 2000; allow_multiple_connections_per_ip: true auto_upload_slots = false; cache_buffer_chunk_size = 128; cache_expiry: 120 cache_size: 512000; choking_algorithm: 1; close_redundant_connections = true; enable_incoming_utp: false; enable_outgoing_utp: false; file_pool_size = 500; inactivity_timeout = 20; low_prio_disk: false; max_failcount = 1; max_rejects = 10; max_queued_disk_bytes: 262144000; max_queued_disk_bytes_low_watermark: 131072000; optimize_hashing_for_speed = true; read_cache_line_size = 512; request_timeout = 10; peer_timeout = 20; seed_choking_algorithm: 1; send_buffer_low_watermark: 13107200; send_buffer_watermark: 26214400; send_buffer_watermark_factor: 250; strict_end_game_mode: false; use_parole_mode: false; use_read_cache = true; write_cache_line_size = 512; 原文\nDeluge 配置优化\n","date":"2018-12-29T19:59:00+08:00","permalink":"https://blog.acesheep.com/p/deluge-ltconfig-optimization-notes/","title":"Deluge ltconfig 优化笔记"},{"content":"本教程在 HG2201U 5.0 版本测试成功 (2018.11), 可以实现的功能 | 不影响 IPTV 和 固话\n导出配置文件, 上传配置文件光猫改桥接 光猫改桥接 HG2201U 5.01 HG6201U 5.0 删除路由器远程管理连接 (1_INTERNET_R_VID_3969) 路由器光猫连接协议开启 IPv6 修改配置文件达到改桥接 重置为默认预设配置 超级管理员获取 开启 Telnet 服务器 Telnet 载入配置文件 重要事先说下\r配置文件一定要备份!!!!\n配置文件一定要备份!!!!\n配置文件一定要备份!!!!\n导出配置和更新配置\r导出配置: 访问 http://192.168.1.1/backupsettings.conf\n更新配置文件: 访问 http://192.168.1.1/updatesettings.html\n光猫改桥接\r登录光猫首页: 先用普通用户登录光猫 访问 http://192.168.1.1/fbctwanconfig.html 因为网页背景是白色, 需要点击全选, 才能看见文字 修改连接设置, 选择连接名称为 2_INTERNET_R_VID_3961 将模式从 route 改为 bridge 服务模式选择 INTERNET 绑定端口选项里勾选 端口_1 保存应用 修改后, 2 (这个数字会变化, 不会再是 2 了) _INTERNET_R_VID_3961 删除路由器远程管理连接 (1_INTERNET_R_VID_3969)\r先普通用户登录, 进入到光猫首页, 不必进行任何操作 访问 http://192.168.1.1/fbctwanconfig.html 因为网页背景是白色, 需要点击全选, 才能看见文字 删除连接名称为 1_INTERNET_R_VID_3969 的选项 删除即应用 路由器光猫连接协议开启 IPv6\r备份配置文件\n使用专业文本编辑软件(UltraEdit, VS Code), 查找字符串 _INTERNET_R_VID_3961 或者设置过桥接的搜索 _INTERNET_B_VID_3961\n在 \u0026lt;X_BROADCOM_COM_MLD_SOURCEEnabled\u0026gt;TRUE\u0026lt;/X_BROADCOM_COM_MLD_SOURCEEnabled\u0026gt; 前添加以下代码\n\u0026lt;X_CT-COM_IPv6Enable\u0026gt;TRUE\u0026lt;/X_CT-COM_IPv6Enable\u0026gt; \u0026lt;X_BROADCOM_COM_IPv6Enabled\u0026gt;TRUE\u0026lt;/X_BROADCOM_COM_IPv6Enabled\u0026gt; 保存文件\n把配置文件导入到路由器里 (更新配置文件)\n修改配置文件达到改桥接\r备份配置文件\n找到 \u0026lt;Telnet\u0026gt; 选项卡, 将 FALSE 改为 TRUE, 便于后期通过 Telnet 调试光猫\n继续找到 \u0026lt;WANConnectionDevice instance=\u0026quot;4\u0026quot;\u0026gt; 选项卡下的 \u0026lt;X_BROADCOM_COM_IfName\u0026gt;, 记录你的设备号以便后期修改配置使用 (图中设备号为 epondef.)\n找到 \u0026lt;WANConnectionDevice instance=\u0026quot;2\u0026quot;\u0026gt; 选项卡\n删除 \u0026lt;IdleDisconnectTime\u0026gt;120\u0026lt;/IdleDisconnectTime\u0026gt; 一整行\n修改 IP_Routed 改为 PPPoE_Bridged\n\u0026lt;ConnectionType\u0026gt;IP_Routed\u0026lt;/ConnectionType\u0026gt; \u0026lt;ConnectionType\u0026gt;PPPoE_Bridged\u0026lt;/ConnectionType\u0026gt; 修改 2_INTERNET_R_VID_3961 改为 2_INTERNET_B_VID_3961\n\u0026lt;Name\u0026gt;2_INTERNET_R_VID_3961\u0026lt;/Name\u0026gt; \u0026lt;Name\u0026gt;2_INTERNET_B_VID_3961\u0026lt;/Name\u0026gt; 修改 ppp0.2 改为 epondef.2\n\u0026lt;X_BROADCOM_COM_IfName\u0026gt;ppp0.2\u0026lt;/X_BROADCOM_COM_IfName\u0026gt; \u0026lt;X_BROADCOM_COM_IfName\u0026gt;你的设备号.2 (本例中为epondef.2)\u0026lt;/X_BROADCOM_COM_IfName\u0026gt; 在之前的 \u0026lt;X_BROADCOM_COM_IfName\u0026gt;epon0.2\u0026lt;/X_BROADCOM_COM_IfName\u0026gt; 下面新建一行, 内容为\u0026lt;X_CU_IPMode\u0026gt;3\u0026lt;/X_CU_IPMode\u0026gt;\n修改完成后保存此文件\n重置为默认预设配置\r如果设置不成功或者出现问题, 可以登录光猫的管理页面进入下面的网址, 可以选择地区, 然后导入配置, 就重新恢复到光猫的原始配置。\n访问 http://192.168.1.1/loadPresettings.html, 选择地区并导入配置\n超级管理员获取\r备份配置文件\n将 G 修改为 0\n\u0026lt;X_FIB_COM_Tr069Control\u0026gt; \u0026lt;AreaCode\u0026gt;0\u0026lt;/AreaCode\u0026gt; \u0026lt;/X_FIB_COM_Tr069Control\u0026gt; \u0026lt;AreaCode\u0026gt;0\u0026lt;/AreaCode\u0026gt; 提交重启后无法链接互联网!!!! 只有 1_TR069_R_VID_3969 获取到地址 IP 地址, 不影响修改设置\n搜索 \u0026lt;AdminHideEnable\u0026gt; 把 FALSE 改为 TRUE 非常重要!!!! (不修改此步骤将失去对路由器的管理权限, 成砖)\n把配置文件导入到路由器里 (更新配置文件)\n访问管理员界面: 使用 http://192.168.1.1/cu.html, 密码为 123qweasdzxc\n修改完设置之后需要把 AreaCode 改为原来的值\n开启 Telnet 服务器\r访问 http://192.168.1.1/servmngr.html\n打开 Telnet 选项, 可以修改密码, 保存 (默认看不到内容, 正常, 鼠标全选整个网页就能看到了, 原因字体背景颜色是白色)\nTelnet 账号密码默认: 账号: admin 密码: admin\n设置 Telnet LAN 可访问, 保存\nTelnet 载入配置文件\rTelnet 登录: 使用命令 telnet 192.168.1.1, 输入用户名和密码\n在 \u0026gt; 输入 sh 回车 变成 #\n备份当前配置\ncp /fhconf/backpresetting.conf /fhconf/backpresetting.bak vi /fhconf/backpresetting.conf 按 i 键 编辑配置文件, 改好后按 ESC 健, 输入 :wq! [强制保存]\n输入 exit 回车, 退出 sh\n载入配置文件, 会触发重启\n\u0026gt; loaddefsettings fhconf/backpresettings.conf [会触发重启] set loid (null) to psp success set password (null) to psp success uploadpre=TRUE flash image complete, ret=0 \u0026gt; 遗失对主机的连接。更新配置文件会自动重启路由器\n原文\n烽火HG220G-U 2.03+ / HG2201U 5.0+光猫改桥接教程\nHG2201U / HG6201U 5.0 和 5.01 修改桥接页面方法\n烽火hg2201u 5.01版改桥接方法\n","date":"2018-11-25T16:27:00+08:00","permalink":"https://blog.acesheep.com/p/hg2201u-bridge-mode-ipv6-setup-super-admin-access/","title":"烽火 HG2201U 5.0/5.01 版本 光猫改桥接 | 设置 IPv6 | 超级管理员获取"},{"content":" 启动时停留在 GRUB 界面\n在启动时按任意键, 例如空格 (不能是回车), 使其停留在 GRUB 界面\n编辑启动选项\n选择要启动的内核, 然后按 e 键进入编辑模式\n修改启动参数\n找到以 linux16 或 linux 开头的行, 将 ro 改为 rw init=/sysroot/bin/sh, 然后按 Ctrl + x 启动\n系统将进入单用户模式\n输入以下命令以修改 root 密码\nchroot /sysroot/ passwd touch /.autorelabel 修改完成后, 强制重启系统\nreboot -f 修改 root 密码后, 系统可能会在下次启动时进行 SELinux 标签的重新标记, 具体取决于你是否触发了 .autorelabel\n原文\nCentos7.0进入单用户模式修改root密码\n","date":"2018-11-11T23:32:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-single-user-mode-to-reset-root-password/","title":"CentOS 7 进入单用户模式修改 root 密码"},{"content":"准备工具\r小米 3G 路由器 - R3G\n小米账号\n小米手机 APP - 用于绑定路由器\n小米开发版固件 - miwifi_r3g_firmware_c2175_2.25.122.bin\n小米 SSH 工具包 - miwifi_ssh.bin\n一个 FAT32 的 U 盘\nPutty 或者 Windows 10 Linux 子系统\nOpenWRT 固件\nkernel1 - openwrt-18.06.1-ramips-mt7621-mir3g-squashfs-kernel1.bin\nrootfs0 - openwrt-18.06.1-ramips-mt7621-mir3g-squashfs-rootfs0.bin\n小米路由器刷官方开发版固件\r小米路由器 3G 出厂是稳定版固件, 需要刷成开发版后才能刷 OpenWRT\n在官网 下载开发版固件 (根据自己路由器型号选择, 我的是 ROM for R3G 开发版 版本2.25.122 (8月25日更新)) 电脑连接上路由器 (刷机建议全程使用网线连接路由器) 登陆管理地址 192.168.31.1, 配置 Wi-Fi 并设置密码 在管理界面右上角选择 系统升级 在下一个界面选择 手动升级 上传刚下载的固件, 点击手动升级 小米路由器开启 SSH 登录\r手机下载小米 Wi-Fi 客户端, 使用小米账号登录, 绑定路由器\n登录 SSH 下载页面, 下载 SSH 工具包 miwifi_ssh.bin, 保存到 U 盘, 记下 root 密码\n打开 OpenWRT 下载页面 下载相应的 OpenWRT 固件, 保存到 U 盘\nmir3g-squashfs-kernel1.bin mir3g-squashfs-rootfs0.bin 断开电源, 将 U 盘插入路由器\n使用卡针按住路由器的 reset 按钮, 接通电源, 保持按住 reset, 直到路由器指示灯变为黄色闪烁状态\n等待 3-5 秒安装完成之后, 小米路由器会自动重启\n等待路由器重启之后, 就可以通过 SSH 接入路由器啦\n选择一款SSH登录工具, 使用 SSH 工具登录路由器 (推荐用 Windows 10 Linux 子系统)\n打开 cmd 输入 bash, 输入 ssh root@192.168.31.1, 密码为第 2 步中记下的密码 837djcsll\n在 SSH 终端中输入以下命令\n# 根据实际情况修改路径 cd /extdisks/sda1 nvram set flag_last_success=1 nvram set boot_wait=on nvram set uart_en=1 nvram commit # 注意修改文件名 mtd write openwrt-18.06.1-ramips-mt7621-mir3g-squashfs-kernel1.bin kernel1 mtd write openwrt-18.06.1-ramips-mt7621-mir3g-squashfs-rootfs0.bin rootfs0 reboot 前面 4 条命 nvram 令非常重要, 它开启串口, 因为小米默认锁死串口, 如果你不开启, 万一刷机失败或者出现意外, 再也救不回来了\n此时 OpenWRT 就刷好了, 管理地址改为 192.168.1.1, 初始 root 用户无密码, 无需键入密码就可以使用 SSH 登陆服务器。\n连接网线, 开始更新系统和安装中文语言包\n# luci-ssl # luci-theme-material # wget # curl # luci-proto-ipv6 # luci-i18n-firewall-zh-cn # luci-i18n-base-zh-cn # luci-app-upnp # luci-i18n-upnp-zh-cn # luci-app-wol # luci-i18n-wol-zh-cn # luci-app-mwan3 # luci-i18n-mwan3-zh-cn # luci-app-shadowsocks-libev opkg update opkg install uci-ssl wget curl luci-proto-ipv6 luci-i18n-firewall-zh-cn luci-i18n-base-zh-cn luci-app-upnp luci-i18n-upnp-zh-cn luci-app-wol luci-i18n-wol-zh-cn luci-app-mwan3 luci-i18n-mwan3-zh-cn 升级系统使用 mir3g-squashfs-sysupgrade.tar 文件, 软件包需要自己重装, 也可以自己编译一份专属的 OpenWRT 固件\n从 OpenWRT 固件刷回官方固件的方法\r从 小米官方下载固件 下载, 将其格式化为 FAT/FAT32 格式, 命名为 miwifi.bin, 并传至 U 盘根目录, 插入小米路由器 USB 接口\nSSH 登录 OpenWRT 系统, 执行命令\nfw_setenv flag_last_success 0 关机路由器, 插电重启并按住 reset 键, 直到 LED 灯闪烁, 约 5-10 分钟后恢复原版固件。\n原文\nLEDE最新系统 支持小米路由3G 刷机教程\nX-WRT/OpenWrt/LEDE最新固件 适配大量硬件（2022-10月更新）\n","date":"2018-10-21T15:52:00+08:00","permalink":"https://blog.acesheep.com/p/flash-openwrt-on-xiaomi-router-3g/","title":"小米路由器 3G 刷 OpenWRT"},{"content":"更新 Ubuntu 系统\r要将 Ubuntu 14.04.4 更新到 Ubuntu 16.04.1, 可以使用 do-release-upgrade 按照以下步骤操作\nsudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade do-release-upgrade 软件包配置损坏\r当出现 dpkg: warning: files list file for package 的错误时, 可以通过以下步骤修复\n进入恢复模式\n启动系统并进入恢复模式\n检查并修复安装包错误\nsudo dpkg --configure -a 启动网络\nsudo dhclient eth0 进行升级或修复\n处理大量 dpkg: warning 警告\n如果出现大量的警告, 可以按照以下步骤处理\n# 将 info 文件夹更名 mv /var/lib/dpkg/info /var/lib/dpkg/info.bak # 再新建一个新的 info 文件夹 sudo mkdir /var/lib/dpkg/info # 更新并修复安装 sudo apt-get update sudo apt-get -f install # 执行完上一步操作后会在新的 info 文件夹下生成一些文件, 现将这些文件全部移到 info.bak 文件夹下 sudo mv /var/lib/dpkg/info/* /var/lib/dpkg/info.bak # 把自己新建的 info 文件夹删掉 sudo rm -rf /var/lib/dpkg/info # 把以前的 info 文件夹重新改回名字 sudo mv /var/lib/dpkg/info.bak /var/lib/dpkg/info 虚拟机网络问题导致写入文件异常\r当 Ubuntu 内核损坏或不小心将内核都删除时, 启动时将无法进入系统, 此时就需要进行系统修复。首先要准备好 Ubuntu 的安装光盘, 如果在虚机里可以使用系统 ISO 文件挂载。\n如果 Ubuntu 内核损坏或被删除, 可以通过以下步骤进行系统修复:\n准备: 准备好 Ubuntu 的安装光盘或 ISO 文件, 并挂载。\n启动: 开机选择从光盘启动系统。\n进入系统: 选择 Try Ubuntu, 进入光盘的 Ubuntu 系统。此时系统会将本机上的 Ubuntu 文件系统识别出来, 即使是 lvm 的也一样能识别出来。\n识别文件系统: 打开终端, 使用 mount 命令挂载本机系统的目录。如果 /boot 是独立分区就会显示出两个子目录, 可以分别进入这两个目录确定哪个是 / 根分区哪个是 /boot 引导分区。\n通过 mount --bind 命令组装本机文件系统, 如果根分区目录为 root_id, boot 分区目录为 boot_id 为例\ncd /media/ubuntu/root_id sudo mount --bind /media/ubuntu/boot_id boot # 挂载 /boot 分区 sudo mount --bind /proc proc # 挂载 /proc 目录 sudo mount --bind /dev dev # 挂载 /dev 目录 sudo mount --bind /sys sys # 挂载 /sys 目录 sudo cp /etc/resolv.conf etc/resolv.conf # 建立域名解析文件 chroot 到当前目录\nchroot . 安装内核或者安装指定内核\napt-get install linux-image-generic 如果一切顺利, 核查一下 /boot/grub/grub.cfg 是否已经有内核菜单\n关机, 拿出光盘, 重启即可。\n原文\nUbuntu 14.04.4 使用 do-release-upgrade 无法检测到 Ubuntu 16.04.1 的更新\ndpkg info修复及dpkg: warning: files list file for package\nubuntu内核损坏或误删除时的系统修复\n","date":"2018-10-20T14:18:00+08:00","permalink":"https://blog.acesheep.com/p/ubuntu-system-update-issues-corrupted-system-and-packages/","title":"Ubuntu 更新系统导致系统损坏, 软件包损坏"},{"content":"今天收到报错: [ERROR] mysqld: The table 'pvlogs' is full, 导致数据无法写入, 影响业务。首先检查系统是否空间满了, 查看之后发现是正常的。经过查询发现, 该表使用的是内存存储引擎, 则可能是由于内存表大小限制所致。\n内存存储引擎 (MEMORY)\r数据存储: 内存存储引擎的表数据完全存储在内存中, 因此可以快速处理数据。 文件结构: 每个基于 MEMORY 存储引擎的表会在磁盘上有一个对应的文件 (.frm), 该文件仅存储表的结构, 数据存储在内存中。 索引: 内存存储引擎默认使用哈希 (HASH) 索引, 速度较快, 但也支持 B-Tree 索引。 数据持久性: 由于数据完全在内存中, 若 mysqld 进程崩溃或服务器重启, 这些数据将会丢失。因此, 内存表的生命周期通常较短, 适合一次性使用的场景。 解决方案\r调整内存表大小相关参数\r查看当前参数\n-- 查看内存表大小 MariaDB [log]\u0026gt; show VARIABLES like \u0026#39;%max_heap_table_size%\u0026#39;; +---------------------+-----------+ | Variable_name | Value | +---------------------+-----------+ | max_heap_table_size | 671088640 | +---------------------+-----------+ 1 row in set (0.00 sec) -- 查看临时表大小 MariaDB [log]\u0026gt; show VARIABLES like \u0026#39;%tmp_table_size%\u0026#39;; +----------------+----------+ | Variable_name | Value | +----------------+----------+ | tmp_table_size | 67108864 | +----------------+----------+ 1 row in set (0.01 sec) 设置新的参数 (临时生效, 重启后失效)\nmysql\u0026gt; SET GLOBAL max_heap_table_size=1048576000; mysql\u0026gt; SET GLOBAL tmp_table_size=1048576000; 永久生效的配置, 在 MySQL 配置文件 my.cnf 中添加\ntmp_table_size = 671088640 max_heap_table_size = 671088640 客户端重新连接数据库。如果问题仍然存在, 考虑重新创建相关的内存表。\n参数说明\ntmp_table_size: 规定内部内存临时表的最大值, 每个线程分配。如果超出限制, MySQL 将自动转化为基于磁盘的 MyISAM 表, 存储在指定的 tmpdir 目录下 (默认是 /tmp/)。\nmysql\u0026gt; show variables like \u0026#34;tmpdir\u0026#34;; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | tmpdir | /tmp/ | +---------------+-------+ max_heap_table_size: 定义用户可创建的内存表的最大大小。支持动态改变, 但对已存在的内存表无效, 需通过重新创建或修改表的方式生效。\n但是对于已经存在的内存表就没有什么用了, 除非这个表被重新创建 (create table) 或者修改 (alter table) 或者 truncate table。服务重启也会设置已经存在的内存表为全局 max_heap_table_size 的值。这个变量和 tmp_table_size 一起限制了内部内存表的大小。\n调整表的最大行数\rALTER TABLE tbl_name MAX_ROWS=1000000000; 这样可以立即生效, 解决表满的问题。\n原文\nMySQL 内存表The table \u0026lsquo;pvlogs\u0026rsquo; is full问题处理\n","date":"2018-09-10T20:23:00+08:00","permalink":"https://blog.acesheep.com/p/mysql-memory-table-pvlogs-is-full-issue/","title":"MySQL 内存表 The table 'pvlogs' is full 问题"},{"content":"NexusPHP 是由浙江大学的 Nexus 团队开发的项目, 旨在提供一个完整、重视用户信誉和知识的资源分享社区的解决方案。\n这是一个比较老的 BT 开源项目, 2010 年开源的。\n安装准备\r服务器最低配置\n1 核心, 1GB RAM, 需要 IPv6 (Debian 8) 所需软件\nApache 2 MySQL 5.5 PHP 5.6 (推荐。PHP 7 不支持) Memcached NexusPHP SourceForge 原版: 下载链接 备份下载: nexusphp.v1.5.beta5.20120707.zip 安装 LAMP (Apache/MySQL/PHP)\r安装 Apache\rApache 是一个开源软件, 它目前运行在全球超过 50% 的服务器上\n首先, 对你的源进行更新\nsudo apt-get install vim chkconfig sudo apt-get update sudo apt-get install apache2 安装完成后可以在浏览器地址栏输入 IP 地址, 安装成功会有一个 It works 页面。\n获取服务器 IP 地址\nsudo ifconfig eth0 | grep inet | awk \u0026#39;{ print $2 }\u0026#39; 安装 MySQL\rMySQL 是用于组织和检索数据的广泛部署的数据库管理系统\nsudo apt-get install mysql-server libmysqlclient-dev 在安装过程中, MySQL 要求你设置一个 root 密码, 不过你要是忘了设置, 也可以在安装之后通过 MySQL shell 设置。\n# 安装完成 MySQL 后你需要进行 MySQL 的初始设置, 利用以下命令: mysql_secure_installation 这步会要求你的 root 密码。 Enter current password for root (enter for none): OK, successfully used password, moving on... 之后会提示你是否想修改 root 密码, 输入 N 不修改, Enter 进入下一步。\n之后的步骤全部 Yes , 最后 MySQL 会重载使得设置完成, 如下\nBy default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from \u0026#39;localhost\u0026#39;. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] y ... Success! By default, MySQL comes with a database named \u0026#39;test\u0026#39; that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up... 完成以上步骤后你就可以开始安装 PHP。\n安装 PHP\rPHP 是种开源的 Web 脚本语言, 并被广泛应用来制作动态网页。\n添加 PPA\nsudo apt-get install python-software-properties software-properties-common sudo add-apt-repository ppa:ondrej/php sudo apt-get update 安装 PHP (Debian 7 以下)\napt-get install php5 php-pear php5-suhosin php5-mysql 安装 PHP (Debian 7 or Higher)\napt-get install php5 php-pear php5-mysql php5-gd php5.6-gd php5.6-mysql php5.6-common php5.6-curl php5.6-cli php5.6-mcrypt php5.6-mbstring php5.6-dom 接下来将会有两次询问, 全部 yes 即可\n配置 PHP 5.6\r打开 php.ini 配置文件\nvim /etc/php/5.6/fpm/php.ini display_errors = on 完成 PHP 安装后, 重载 Apache\nservice apache2 restart 恭喜！你已经成功安装 LAMP！\n测试 LAMP\r虽然我们已经安装了 LAMP , 但我们还是需要更直观一点查看安装成功的 LAMP\n首先创建一个文件\nsudo vim /var/www/info.php 写入以下内容\n\u0026lt;?php phpinfo(); ?\u0026gt; :wq 保存退出\n现在你可以在浏览器中输入 http://localhost/info.php 查看 PHP 版本等信息\n安装 Memcached\rMemcache 是一个高性能的分布式内存对象缓存系统, 用于动态 Web 应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数, 从而提高了网站访问的速度。 MemCache 是一个存储键值对的 HashMap, 在内存中对任意的数据 (比如字符串、对象等) 所使用的 key-value 存储, 数据可以来自数据库调用、API 调用, 或者页面渲染的结果。\nMemCache 设计理念就是小而强大, 它简单的设计促进了快速部署、易于开发并解决面对大规模的数据缓存的许多难题, 而所开放的 API 使得 MemCache 能用于 Java、C/C++、C#、Perl、Python、PHP、Ruby 等大部分流行的程序语言。\n安装 Memcached 服务及 PHP 扩展\napt-get install memcached php5-memcached php5-memcache 修改配置文件\nvim /etc/memcached.conf 修改内存大小和监听 IP 地址\n这里只需修改两个参数\r一是指定 memcached 所能使用的内存大小, 如下:\r-m 256 # 默认是 64M, 请修改成实际所需要的大小 256M 即可\r二是修改监听的 IP 地址, 默认时 memcached 只监听在 127.0.0.1 这个本地回环地址上, 如下修改成本地网卡接口上的实际 IP:\r-l 127.0.0.1 # 不修改 然后重启服务\nsudo service memcached restart 验证安装\nps aux | grep memcached netstat -tap | grep \u0026#39;memcached\u0026#39; ss -tnl | grep 11211 LISTEN 0 128 172.31.11.96:11211 *:* 使用 telnet 来连接 memcache 实例, 输入 stats 验证\ntelnet localhost 11211 stats 导入数据库\r在 NexusPHP 文件夹中找到 dbstructure.sql 数据库文件。建议使用 Adminer 导入数据库, 比 phpMyAdmin 好用。\n等待导入完成\n配置 NexusPHP\r编辑网站目录下的 config/allconfig.php 配置文件\nvim /var/www/html/config/allconfig.php chmod -R 777 config 找到以下部分\n$BASIC = array( \u0026#39;SITENAME\u0026#39; =\u0026gt; \u0026#39;NexusPHP\u0026#39;, # 这是站名 \u0026#39;BASEURL\u0026#39; =\u0026gt; \u0026#39;localhost\u0026#39;, # 填写设置解析之后的域名 \u0026#39;announce_url\u0026#39; =\u0026gt; \u0026#39;localhost/announce.php\u0026#39;, # localhost 填网站域名 \u0026#39;mysql_host\u0026#39; =\u0026gt; \u0026#39;localhost\u0026#39;, # 数据库 IP, 填 127.0.0.1 比 localhost 好 \u0026#39;mysql_user\u0026#39; =\u0026gt; \u0026#39;root\u0026#39;, # 填数据库用户名 \u0026#39;mysql_pass\u0026#39; =\u0026gt; \u0026#39;nexusphprocks\u0026#39;, # 填数据库密码 \u0026#39;mysql_db\u0026#39; =\u0026gt; \u0026#39;nexusphp\u0026#39;, # 填数据库名称 ); 配置好就可以访问了\nNexusPHP 常见问题\rNexusPHP 不显示验证码\rPHP 没有安装图片处理扩展 (GD 库), 使用下面命令即可安装\nsudo apt-get install php5-gd MySQL 内存表 The table \u0026lsquo;pvlogs\u0026rsquo; is full\r在 MySQL 中执行命令\nset global max_heap_table_size=1048576000; set global tmp_table_size=1048576000; 原文\n在 Debian 下安装 Apache,MySQL,PHP\nLinux+nginx+mysql+php实战nexusPHP\n[Linux] 簡易搭建NexusPHP PT站\nDebian安装memcached和php5-memcache模块\nDebian 8.1(amd64)下部署Memcached\nMySQL 内存表The table \u0026lsquo;pvlogs\u0026rsquo; is full问题处理\n","date":"2018-09-10T18:35:00+08:00","permalink":"https://blog.acesheep.com/p/build-nexusphp-pt-site/","title":"搭建 NexusPHP PT 站"},{"content":"什么是 SSH\rSSH (Secure Shell) 是一种网络协议, 用于在计算机之间进行加密登录。用户通过 SSH 协议从本地计算机登录远程计算机, 这种登录方式是安全的, 即使被截获, 密码也不会泄露。\n最初, 互联网通信都是明文的, 容易被截获。1995 年, 芬兰学者 Tatu Ylonen 设计了 SSH 协议, 将登录信息加密, 迅速成为互联网安全的基本解决方案。目前, SSH 已成为 Linux 系统的标准配置。\nSSH 作为一种协议, 有多种实现, 本文讨论的主要是 OpenSSH, 它是一个广泛应用的自由软件。此外, 本文主要关注 SSH 在 Linux Shell 中的用法, Windows 用户可以使用 PuTTY 等软件。\n8102年 Windows 10 系统可以下载内置子系统了, 可以使用子系统实现公钥登录\n最基本的用法\rSSH 主要用于远程登录。假设你要以用户名 user 登录远程主机 host, 只需执行以下命令\nssh user@host 如果本地用户名与远程用户名一致, 可以省略用户名\nssh host SSH 默认使用端口 22, 你的登录请求会送进远程主机的 22 端口。若需指定其他端口, 可使用 -p 参数\nssh -p 2222 user@host 中间人攻击\rSSH 的安全性在于其公钥加密机制。整个过程如下:\n远程主机接收用户的登录请求并发送其公钥给用户 用户使用公钥加密登录密码并发送回去 远程主机用私钥解密密码并验证 然而, 中间人攻击 (Man-in-the-Middle Attack) 是 SSH 安全的潜在风险。如果攻击者截获请求并伪装成远程主机, 用户很难辨别真伪。因为不像 https 协议, SSH 协议的公钥是没有证书中心 (CA) 公证的, 也就是说, 都是自己签发的。\n可以设想, 如果攻击者插在用户与远程主机之间 (比如在公共的 wifi 区域), 用伪造的公钥, 获取用户的登录密码。再用这个密码登录远程主机, 那么SSH的安全机制就荡然无存了。这种风险就是著名的 \u0026ldquo;中间人攻击\u0026rdquo; (Man-in-the-middle attack)\n密码登录\r第一次登录时, 系统会提示\n$ ssh user@host The authenticity of host \u0026#39;host (12.18.429.21)\u0026#39; can\u0026#39;t be established. RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d. Are you sure you want to continue connecting (yes/no)? 这段话的意思是, 无法确认host主机的真实性, 只知道它的公钥指纹, 问你还想继续连接吗？\n所谓 \u0026ldquo;公钥指纹\u0026rdquo;, 是指公钥长度较长 (这里采用 RSA 算法, 长达 1024 位), 很难比对, 所以对其进行 MD5 计算, 将它变成一个 128 位的指纹。上例中是 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d, 再进行比较, 就容易多了。\n很自然的一个问题就是, 用户怎么知道远程主机的公钥指纹应该是多少？回答是没有好办法\n远程主机必须在自己的网站上贴出公钥指纹, 以便用户自行核对 使用主机商提供的控制台登录远程主机获取公钥指纹 \u0026ldquo;我相信你, 第一次你肯定不会骗我的\u0026rdquo; 假定经过风险衡量以后, 用户决定接受这个远程主机的公钥。\nAre you sure you want to continue connecting (yes/no)? yes # 系统会出现一句提示, 表示 host 主机已经得到认可 Warning: Permanently added \u0026#39;host,12.18.429.21\u0026#39; (RSA) to the list of known hosts. # 然后, 会要求输入密码 Password: (enter password) 如果密码正确, 就可以登录了, 主机的公钥指纹将保存到 $HOME/.ssh/known_hosts 文件中, 以便下次直接登录而不再提示。\n下次再连接这台主机, 系统就会认出它的公钥指纹已经保存在本地了, 如果远程提供的和记录的一样则跳过警告部分, 直接提示输入密码。不一样则会有警告。\n每个 SSH 用户都有自己的 known_hosts 文件, 此外系统也有一个这样的文件, 通常在 /etc/ssh/ssh_known_hosts, 保存一些对所有用户都可信赖的远程主机的公钥。\n公钥登录\r使用密码登录, 每次都必须输入密码, 非常麻烦。为简化登录, SSH 提供了公钥登录方式, 可以省去输入密码的步骤。\n公钥登录原理很简单, 就是用户将自己的公钥储存在远程主机上。登录的时候, 远程主机会向用户发送一段随机字符串, 用户用自己的私钥加密后, 再发回来。远程主机用事先储存的公钥进行解密, 如果成功, 就证明用户是可信的, 直接允许登录 shell, 不再要求密码。\n用户需将自己的公钥存储在远程主机上, 这种方法要求用户必须提供自己的公钥。若无公钥, 可以使用以下命令生成\nssh-keygen -b 4096 运行上面的命令以后, 系统会出现一系列提示, 可以一路回车。其中有一个问题是, 要不要对私钥设置口令 (passphrase), 如果担心私钥的安全, 这里可以设置一个。\n运行结束以后, 在 $HOME/.ssh/ 目录下, 会新生成两个文件: 公钥 id_rsa.pub 和私钥 id_rsa。\n生成后, 将公钥传送到远程主机\nssh-copy-id user@host 设置完成后, 再次登录时无需输入密码。\n如果没成功, 检查开远程主机的 /etc/ssh/sshd_config 文件, 检查下面几行前面 # 注释是否删掉\nPermitRootLogin without-password\rRSAAuthentication yes\rPubkeyAuthentication yes\rAuthorizedKeysFile .ssh/authorized_keys 重启 SSH 服务\n# CentOS 系统 systemctl restart sshd # Ubuntu 系统 service ssh restart # Debian 系统 /etc/init.d/ssh restart authorized_keys 文件\r用户的公钥保存在远程主机的 $HOME/.ssh/authorized_keys 文件中。公钥就是一段字符串, 只要把它追加在 authorized_keys 文件的末尾就行了。\n这里不使用上面的 ssh-copy-id 命令, 改用下面的命令, 解释公钥的保存过程\nssh user@host \u0026#39;mkdir -p .ssh \u0026amp;\u0026amp; cat \u0026gt;\u0026gt; .ssh/authorized_keys\u0026#39; \u0026lt; ~/.ssh/id_rsa.pub 这条命令由多个语句组成, 依次分解开来看\nssh user@host, 表示登录远程主机\n单引号中的 mkdir -p .ssh \u0026amp;\u0026amp; cat \u0026gt;\u0026gt; .ssh/authorized_keys, 表示登录后在远程 shell 上执行的命令\nmkdir -p .ssh 的作用是, 如果用户主目录中的 .ssh 目录不存在, 就创建一个 cat \u0026gt;\u0026gt; .ssh/authorized_keys, 将内容增量写入到文件末尾 \u0026lt; ~/.ssh/id_rsa.pub 的作用是, 将本地的公钥文件 ~/.ssh/id_rsa.pub, 重定向追加到远程文件 authorized_keys 的末尾\n写入 authorized_keys 文件后, 公钥登录的设置就完成了。\n远程执行命令\rSSH 不仅用于登录, 还可以直接在远程主机上执行命令。例如\nssh user@host \u0026#39;mkdir -p .ssh \u0026amp;\u0026amp; cat \u0026gt;\u0026gt; .ssh/authorized_keys\u0026#39; \u0026lt; ~/.ssh/id_rsa.pub 单引号中间的部分, 表示在远程主机上执行的操作。后面的输入重定向, 表示数据通过SSH传向远程主机。\n这就是说, SSH可以在用户和远程主机之间, 建立命令和数据的传输通道, 因此很多事情都可以通过SSH来完成。\n下面看几个例子。\n将本地 $HOME/src/ 目录下面的所有文件, 复制本地文件到远程主机\ncd \u0026amp;\u0026amp; tar czv src | ssh user@host \u0026#39;tar xz\u0026#39; 将远程主机 $HOME/src/ 目录下面的所有文件, 复制到本地用户的当前目录\nssh user@host \u0026#39;tar cz src\u0026#39; | tar xzv 检查远程进程, 查看远程主机是否运行进程 httpd\nssh user@host \u0026#39;ps ax | grep [h]ttpd\u0026#39; SSH 隧道\rssh 命令除了登陆外还有三种代理功能\n正向代理 (-L) : 端口转发, 相当于 iptable 的 port-forwarding 反向代理 (-R) : 内网穿透, 相当于 frp 或者 ngrok socks5 代理 (-D) : 相当于 ss / ssr 正向代理 (-L)\r正向代理就是在本地启动端口, 把本地端口数据转发到远端。\n假设由于种种原因, Host1 和 Host2 两台主机之间无法连通。但是, 另外还有一台 Host3, 可以同时连通前面两台主机。因此, 很自然的想法就是, 通过 Host3, 将 Host1 连上 Host2\nHost1 是本地主机 Host2 是目标主机 Host3 是代理主机 Alice 和 Bob (Host1) 在一家公司工作, 公司网络在防火墙后面。在外网有一个服务器 123.7.8.9:8090 (Host2) 上有一个 web 服务器。 Alice 想访问, 但是公司防火墙只开通的 22 端口, 其他端口都封闭了。\nBob 在外网放了一台机器, 123.4.5.6 (Host3), 提供了 SSH 服务。 Bob 可以帮助 Alice\nBob 在自己的电脑 192.168.0.1 (Host1) 上, 登陆 123.4.5.6 (Host3)\nssh -L 0.0.0.0:8080:123.7.8.9:8090 bob@123.4.5.6 然后 Alice 就可以访问 192.168.0.1:8080 (Host1), 就像访问 123.7.8.9:8090 (Host2) 一样\n参数含义\r打开本地端口。发送到该端口的所有内容都将通过 ssh 连接并通过服务器离开。\n-L \u0026lt;local ip\u0026gt;:\u0026lt;local port\u0026gt;:\u0026lt;remote ip\u0026gt;:\u0026lt;remote port\u0026gt; \u0026lt;user\u0026gt;@\u0026lt;server addr\u0026gt; 用于建立一个 ssh 隧道, 在本机 (Host1) 监听 \u0026lt;local ip\u0026gt;:\u0026lt;local port\u0026gt; 这个地址。如果有客户端建立 tcp 连接, 那么就像在 \u0026lt;user\u0026gt;@\u0026lt;server addr\u0026gt; (Host3) 这台机器上, 创建了一个连接到 \u0026lt;remote ip\u0026gt;:\u0026lt;remote port\u0026gt; (Host2) 上一样。\n例子\r将本机 (Host1) 的 5900 端口绑定到 Host3 的 5900 端口。\n转发使用的域名, 而非 IP 地址。这里的 localhost 解析后指的是 Host3, 因为是 Host3 主机负责解析。\nssh -L 5900:localhost:5900 user@Host3 将本机 (Host1) 的 4444 端口转发到 google.com:80 (Host2)。\nssh -L 4444:google.com:80 user@Host3 在浏览器上打开 http://localhost:4444, 实际上会看到 google 的页面。\nHost1 通过 Host3 的端口转发, ssh 登录 Host2\nssh -L 9001:Host2:22 user@Host3 只要 ssh 登录本机的 9001 端口, 就相当于登录 Host2 了。\n转发使用的 IP 地址, 不需要解析。这里的 localhost 由 Host1 主机负责解析。\n# -p 参数表示指定登录端口 ssh -p 9001 user@localhost 反向代理 (-R)\r反向代理就是让远端启动端口, 把远端端口数据转发到本地。\nHost1 是本地主机 Host2 是目标主机 Host3 是代理主机 Bob 家里面有两台机器, 192.168.0.1 (Host1) 和 192.168.0.100 (Host2)\nBob 买了一台虚拟主机, 互联网 IP 123.4.5.6 (Host3)。\n他在公司里, 想登陆家里的服务器 192.168.0.100 (Host2)。那么他上班前, 在 192.168.0.1 (Host1) 上运行命令\nssh -R 123.4.5.6:60022:192.168.0.100:22 user@123.4.5.6 这样就在 123.4.5.6 (Host3) 上建立了一个反向隧道。\nBob 在公司里面, 就可以\nssh -p 60022 user@123.4.5.6 登陆家里的 192.168.0.100 , 就像从 192.168.0.1 上登陆一样。\n参数含义\rHost1 将自己可以访问的 Host2:Port2 暴露给外网服务器 Host3:Port3, 在 Host1 上运行\nHost1$ ssh -R Host3:Port3:Host2:Port2 user@Host3 那么链接 Host3:Port3 就相当于链接 Host2:Port2。使用时需修改 Host3 的 /etc/ssh/sshd_config, 添加\nGatewayPorts yes 相当于内网穿透, 比如 Host1 和 Host2 是同一个内网下的两台可以互相访问的机器, Host3 是外网跳板机, Host3 不能访问 Host1, 但是 Host1 可以访问 Host3。\n那么通过在内网 Host1 上运行 ssh -R 告诉 Host3, 创建 Port3 端口监听, 把该端口所有数据转发给我 (Host1), 我会再转发给同一个内网下的 Host2:Port2。\n同内网下的 Host1 / Host2 也可以是同一台机器, 换句话说就是内网 Host1 把自己可以访问的端口暴露给了外网 Host3。\n本地 socks5 代理 (-D)\r在 Host1 的本地 1080 端口启动一个 socks5 服务, 通过本地 socks5 代理的数据会通过 ssh 链接先发送给 Host2, 再从 Host2 转发送给远程主机\n假设要将本地 1080 端口创建一个基于 SSH 的 socks5 代理, 命令如下\nssh -D 1080 user@Host2 那么在 Host1 上面, 浏览器配置 socks5 代理为 127.0.0.1:1080, 浏览器请求的所有内容都会通过 ssh 隧道。浏览网页时数据通过 Host2 代理出去, 对于公共互联网, 就好像是从 ssh 服务器访问而不是从本地访问。\n类似 ss/ssr, 只不过用 ssh 来实现。\nSSH 的其他参数\rSSH 提供了其他参数, 值得注意\n-N: 仅连接远程主机, 不打开远程 shell -T: 不为连接分配 TTY -f: SSH 连接成功后转入后台运行 这个两个参数可以放在一起用, 代表这个SSH连接只用来传数据, 不执行远程操作。\nssh -NT -D 1080 host 在不中断SSH连接的情况下, 在本地shell中执行其他操作。要关闭这个后台连接, 就只有用 kill 命令去杀掉进程。\nssh -f -D 8080 host 原文\nDifferences between ssh -L to -D\nSSH 命令的三种代理功能 (-L/-R/-D) 和外网访问隐私数据库的示例\n用 SSH 命令打洞\nSSH原理与运用 (一) : 远程登录\nSSH原理与运用 (二) : 远程操作与端口转发\n","date":"2018-09-10T15:36:00+08:00","permalink":"https://blog.acesheep.com/p/deep-dive-into-ssh-secure-remote-login-and-data-transfer-protocol/","title":"深入探究 SSH: 安全远程登录和数据传输协议"},{"content":"从 MySQL 8.0 开始, utf8mb4 是默认字符集, utf8mb4 的默认排序规则是 utf8mb4_0900_ai_ci。MySQL 8.0 还为 utf8mb4 字符集提供了一整套新的 Unicode 排序规则。\n这将允许在 MySQL 中使用完整的 Unicode 9.0.0 字符集。\nMySQL 5.7 以下版本在创建数据库时, 如果选择了 UTF-8 (utf8mb4) 编码格式, 但在使用 PDM 生成的脚本导入后发现表和字段的编码格式却是 GBK, 可以通过以下几种方法进行修改。\n修改表的默认编码格式\r作用: 修改表的默认字符集为 UTF-8 (utf8mb4)。\n注意: 这只会影响新添加的字段, 现有字段的编码格式不会改变。\nALTER TABLE `table` DEFAULT CHARACTER SET utf8mb4; 修改字段的编码格式\r作用: 单独修改某个字段的编码格式为 UTF-8 (utf8mb4)。\n缺点: 每次只能修改一个字段, 操作繁琐。\nALTER TABLE `tablename` CHANGE `Name1` `Name2` VARCHAR(36) CHARACTER SET utf8mb4 NOT NULL; 一次性修改整张表的所有字段编码格式\r作用: 将整张表的所有字段的编码格式更改为 UTF-8 (utf8mb4)。\n优点: 方便快捷, 适用于需要批量修改字段编码格式的场景。\nALTER TABLE `tablename` CONVERT TO CHARACTER SET utf8mb4; 原文\nMySQL 8.0 Collations: Migrating from older collations\nmysql修改数据库表和表中的字段的编码格式的修改\n","date":"2018-09-10T14:13:00+08:00","permalink":"https://blog.acesheep.com/p/change-character-encoding-for-mysql-database-and-tables/","title":"MySQL 修改数据库和表中的字段编码"},{"content":"在 Linux 系统中, 用户可以使用多种压缩与解压缩工具, 如 tar、gzip、bzip2、compress、zip、rar 及其对应的解压程序 gunzip、bunzip2、uncompress、unzip、unrar。通过它们可以对不同格式的压缩文件进行操作, 如 .tar、.gz、.tar.gz、.tgz、.bz2、.tar.bz2、.Z、.tar.Z、.zip、.rar 等。下面将逐一介绍这些程序的基本用法及常用命令, 以后应该不需要为下载了一个软件而不知道如何在 Linux 下解开而烦恼了。\ntar 命令\rtar 是 Linux 中最常用的打包程序, 通常用于将多个文件打包成一个 .tar 文件, 便于管理和分发\ntar 使用破折号传递参数 (例如: tar -cf 而不是 tar cf), 则 -f 选项必须放在最后, 因为它指定文件名\ntar 命令的基本用法如下\n# 将所有 .jpg 文件打包为 all.tar # -c 创建新包 # -f 指定包文件名 tar -cf all.tar *.jpg # 将所有 .gif 文件添加到 all.tar 中 # -r 向已有的 tar 包中添加文件 tar -rf all.tar *.gif # 更新 all.tar 中的 logo.gif 文件 # -u 更新文件 tar -uf all.tar logo.gif # 列出 all.tar 中的所有文件 # -t 列出 tar 包中的文件 tar -tf all.tar # 解压 all.tar # -x 解压文件 tar -xf all.tar tar 调用压缩程序 (组合使用)\rtar 可以在打包或解包的同时调用其它的压缩程序, 如 compress、gzip、bzip2、xz 等。\ncompress, gzip, bzip2, xz 与 tar 的组合适用于 Linux 系统打包压缩工作, 适合高效存储。\ntar 格式: Linux/Unix 系统常用 .tar.Z 、.tar.gz、.tar.bz2、.tar.xz 格式, 解压时通常需要先使用对应的压缩工具解压, 再使用 tar 提取归档。\n下面分别介绍如何调用这些压缩程序\ntar 调用 compress\rcompress 是早期 Unix 系统中使用的一种压缩工具, 采用 LZW 算法 (Lempel-Ziv-Welch)。\n.Z 文件是使用 compress 压缩的文件, 解压程序是 uncompress。\ntar 中使用 -Z 参数调用 compress\n# 将所有 .jpg 文件打包为 all.tar, 并用 compress 压缩生成 all.tar.Z tar -cZf all.tar.Z *.jpg # 解压 all.tar.Z tar -xZf all.tar.Z tar 调用 gzip\rgzip (GNU zip) 是由 Jean-loup Gailly 和 Mark Adler 开发的, 基于 DEFLATE 算法。广泛用于 Linux 和 Unix 系统。\n.gz, .tgz 文件是使用 gzip 压缩的文件, 解压程序是 gunzip。\ntar 中使用 -z 参数调用 gzip\n# 将所有 .jpg 文件打包为 all.tar, 并用 gzip 压缩生成 all.tar.gz tar -czf all.tar.gz *.jpg # 解压 all.tar.gz tar -xzf all.tar.gz tar 调用 bzip2\rbzip2 是使用 Burrows-Wheeler (BWT+RLE+Huffman) 变换算法的压缩工具, 专为压缩率优化而设计。\n.bz2 文件是使用 bzip2 压缩的文件, 解压程序是 bunzip2。\ntar 中使用 -j 参数调用 bzip2\n# 将所有 .jpg 文件打包为 all.tar, 并用 bzip2 压缩生成 all.tar.bz2 tar -cjf all.tar.bz2 *.jpg # 解压 all.tar.bz2 tar -xjf all.tar.bz2 tar 调用 xz\rxz 是一种基于 LZMA2 算法的压缩工具, 提供更高的压缩比和更高的压缩效率。\n.xz 文件是使用 xz 压缩的文件, 解压程序是 unxz。\ntar 中使用 -J 参数调用 xz\n# 将所有 .jpg 文件打包为 all.tar, 并用 xz 压缩生成 all.tar.xz tar -cJf all.tar.xz *.jpg # 解压 all.tar.xz tar -xJf all.tar.xz 一体化压缩工具\r在 Windows 中常见的压缩格式, zip, 7z, rar 这些工具可以同时进行打包和压缩, 将多个文件压缩到一个文件中, 因此生成的文件只需一个步骤即可完成归档和压缩。\nzip、7z 和 rar 通常只生成 .zip、.7z、.rar 文件, 跨平台兼容性较好。\nzip\rLinux 中 zip 和 unzip 程序分别用于压缩和解压 .zip 格式的文件\n# 将所有 .jpg 文件压缩成 all.zip zip all.zip *.jpg # 解压 all.zip unzip all.zip 7z\rLinux 中处理 .7z 文件需要安装 7-Zip for Linux: console version, 下载地址: 7-Zip for Linux\n# 下载并解压 wget https://www.7-zip.org/a/7z2408-linux-x64.tar.xz mkdir 7z tar -xJpf 7z2107-linux-x64.tar.xz -C 7z cp 7z/7zzs /usr/local/bin/7z 安装完成后, 可以使用 7z 命令。\n# 将所有 .jpg 文件压缩成 all.7z 7z a all.7z *.jpg # 解压 all.7z 7z e all.7z rar\rLinux 中处理 .rar 文件需要安装 RAR for Linux (Command line only), 下载地址: WinRAR and RAR archiver downloads\n# 下载并解压 tar -xzpvf rarlinux-3.2.0.tar.gz cd rar # 安装 make 安装完成后, 可以使用 rar 和 unrar 命令。\n# 将所有 .jpg 文件压缩成 all.rar rar a all.rar *.jpg # 解压 all.rar unrar e all.rar 常见压缩文件的解压命令总结\r压缩文件格式 解压命令 .Z uncompress file.Z .gz gzip -d file.gz 或 gunzip file.gz .bz2 bzip2 -d file.bz2 或 bunzip2 file.bz2 .xz xz -d file.gz .tar tar -xf file.tar .tar.Z tar -xZf file.tar.Z .tar.gz 或 .tgz tar -xzf file.tar.gz 或 tar -xzf file.tgz .tar.bz2 tar -xjf file.tar.bz2 .tar.xz tar -xJf file.tar.xz .zip unzip file.zip .7z 7z e all.7z .rar unrar e file.rar 综合比较\r特性 compress gzip bzip2 xz 7z rar 压缩算法 LZW DEFLATE BWT+RLE+Huffman LZMA2 LZMA2 RAR 文件格式支持 .Z .gz .bz2 .xz .7z .rar 压缩比 较低 中等 高 非常高 非常高 高 压缩速度 快 很快 较慢 慢 较慢 慢 解压速度 快 很快 较慢 慢 快 较快 资源使用 低 低 中等 高 高 较高 大文件支持 否 是 是 是 是 是 多线程支持 否 否 否 是 是 否 例子\r将整个 /home/www/images 目录下的文件全部打包为 /home/www/images.tar\n在参数 f 后面的压缩文件名是自己取的, 习惯上用 .tar, 如果加 z 参数, 则以 .tar.gz 或 .tgz 来代表 gzip 压缩过的 tar 文件\n# 仅打包, 不压缩 tar -cvf /home/www/images.tar /home/www/images # 打包后, 以 gzip 压缩 tar -zcvf /home/www/images.tar.gz /home/www/images 将 .tgz 文件解压到指定目录\ntar -zxvf test.tgz -C 指定目录 # 比如将 /source/kernel.tgz 解压到 /source/linux-2.6.29 目录 tar -zxvf /source/kernel.tgz -C /source/linux-2.6.29 原文\nCreate a tar.xz in one command\nLinux File Compression: gzip, bzip2, and xz Unveiled\nLinux解压文件到指定目录\n","date":"2018-09-10T12:27:00+08:00","permalink":"https://blog.acesheep.com/p/linux-compression-and-decompression-commands/","title":"Linux 压缩、解压命令"},{"content":"什么是谷歌三件套\r谷歌服务框架 (Google Services Framework) 谷歌 Play 服务 (Google Play Services) 谷歌 Play 商店 (Google Play Store) 详细步骤\r安装谷歌服务框架 (Google Services Framework)\r打开 APKMirror - Free APK Downloads\n在搜索框中输入 Google Services Framework\n出现了很多个版本的 apk, 根据自己的手机 Android 版本进行选择\n比如我的手机系统是 Android 7.1.2, 那么就选择版本号为 7.1.2 的 Google Services Framework\n点击红框内的 Download 按钮, 弹出下载框\n下载完成后, 将 apk 文件安装到手机上。安装完毕后在桌面看不到图标, 这是正常现象。继续进行下一步\n安装谷歌 Play 服务 (Google Play Services)\r返回 APKMirror 网站, 在搜索框中输入 Google Play Services\n出现多个版本的 Google Play Services, 选择发布日期最新, 并且变种版本 (variants) 最多的那个版本。\n向下滚动页面, 可以看到不同的 Android 版本、CPU 架构 (如 ARM、x86) 和屏幕 DPI 对应的 apk 变种。根据手机配置选择合适的版本\n提示: 如果不清楚自己的屏幕 DPI, 可以选择带有 nodpi 标记的版本\n点击 Download 按钮, 下载所选版本的 Google Play Services\n下载完成后, 将 apk 文件安装到手机上。安装完毕后, 依然看不到图标, 继续安装最后一个应用\n安装谷歌 Play 商店 (Google Play Store)\r在 APKMirror 网站中, 搜索 Google Play Store 选择最新版本, 点击 Download 按钮进行下载 下载完成后, 将 apk 文件安装到手机上 完成安装\r到此, 谷歌三件套 (Google Services Framework、Google Play Services、Google Play Store) 已经安装完成。打开 Google Play 商店时, 如果是第一次使用, 你需要使用 Google 帐户登录或注册\n","date":"2018-09-10T10:55:00+08:00","permalink":"https://blog.acesheep.com/p/install-google-framework-on-chinese-android-phones/","title":"辣鸡国内安卓手机安装谷歌三件套"},{"content":"XFS 是一种高性能的文件系统, 广泛应用于 Linux 服务器和存储设备中。尽管 XFS 采用了延迟写入、分配组 (AG) 等技术来降低文件碎片的产生。虽然 XFS 文件系统在设计时引入了减少碎片化的机制, 但长时间运行且文件操作频繁时, 碎片化仍然不可避免, 影响读写性能。\n很多人认为 XFS 无需做碎片整理, 这是误解。对于文件操作频繁的服务器来说, 碎片整理是提升 XFS 文件系统性能的必要手段。特别是使用多年的服务器, 若未进行过碎片整理, 可能会导致文件访问速度下降、磁盘操作延迟增加等问题。\n软件包\nxfsdump - Administrative utilities for the XFS filesystem xfslibs-dev - XFS filesystem-specific static libraries and headers xfsprogs - Utilities for managing the XFS filesystem 文件系统碎片检查\r在对 XFS 文件系统进行碎片整理前, 首先需要查看文件系统的碎片率。可以通过以下命令来检查\n# 查看 /dev/sdc1 的碎片情况 # 如果碎片率 (fragmentation factor) 超过 50%, 建议进行碎片整理 xfs_db -c frag -r /dev/sdc1 actual 93133, ideal 8251, fragmentation factor 91.14% # 查看 /dev/sdb1 的碎片情况 # 碎片率较低, 无需进行碎片整理 xfs_db -c frag -r /dev/sdb1 actual 905607, ideal 900507, fragmentation factor 0.56% 通过交互式命令检查文件碎片\nxfs_db -r /dev/sdd1 xfs_db\u0026gt; frag actual 117578, ideal 116929, fragmentation factor 0.55% 查看特定文件的块映射情况\nxfs_bmap -v case19.dat case19.dat: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL 0: [0..9551]: 592061576..592071127 1 (103696496..103706047) 9552 1: [9552..86039]: 599312816..599389303 1 (110947736..111024223) 76488 2: [86040..170399]: 599655400..599739759 1 (111290320..111374679) 84360 3: [170400..256799]: 599751632..599838031 1 (111386552..111472951) 86400 4: [256800..340079]: 1185490752..1185574031 2 (208760592..208843871) 83280 5: [340080..592703]: 1185577976..1185830599 2 (208847816..209100439) 252624 文件系统碎片整理\r使用 xfs_fsr 命令可以对 XFS 文件系统进行碎片整理。需要注意的是, 该命令不属于 xfsprogs 包, 而是在 xfsdump 包中。因此, 使用前需先安装 xfsdump\nyum install xfsdump -y 然后使用 xfs_fsr 进行碎片整理\n整理 /dev/sdc1 的碎片\r该操作将尝试将分散的文件块重新组合, 从而减少文件系统中的碎片, 提高文件读写性能\nxfs_fsr /dev/sdc1 碎片整理后的性能提升实例\rWow! Thanks. That\u0026rsquo;l teach me to use a non-default tech without researching it.\nOver the years, my MythTV box had gotten inexplicably slow with lots of disk access for many operations like starting playback of a recorded video. With the advice here, I measured 98.6% fragmentation. A few sample files I checked that were 1-6GB captured MPEG-2 videos were stored on over 30,000 extents!\nAfter 2 nights of de-fragmenting, I\u0026rsquo;m down to 17% fragmented and startup time of playing a video is noticeably faster with less hard drive activity.\n根据某位用户的经验分享, 长期使用的 XFS 文件系统可能会出现严重的碎片化现象。经过 xfs_fsr 整理后, 该用户的磁盘访问性能有了显著提升\n原始碎片率: 98.6% 整理后碎片率: 17% 优化效果: 视频文件的启动时间缩短, 硬盘活动减少, 文件读写速度明显提升。 常见 XFS 管理命令\r以下为 XFS 文件系统管理的常用命令, 可用于检查、修复、优化 XFS 文件系统\nxfs_admin 调整 XFS 文件系统的各种参数 xfs_copy 将 XFS 文件系统的内容并行拷贝到一个或多个目标系统 xfs_db 调试或检测 XFS 文件系统 (例如查看碎片情况) xfs_check 检测 XFS 文件系统的完整性 xfs_repair 修复受损的 XFS 文件系统 xfs_fsr 整理 XFS 文件系统碎片 xfs_quota 管理 XFS 文件系统的磁盘配额 xfs_metadump 将 XFS 文件系统的元数据 (metadata) 拷贝到文件中 xfs_mdrestore 从文件中恢复 XFS 文件系统的元数据 xfs_growfs 扩展 XFS 文件系统大小 (仅支持扩展) xfs_info 查看文件系统信息 原文\nUse xfs_fsr to keep your XFS filesystem optimal 文章备份\nXFS文件系统碎片整理\nhttp://blog.sina.com.cn/s/blog_b87700f50102wpug.html\n","date":"2018-06-27T11:29:00+08:00","permalink":"https://blog.acesheep.com/p/xfs-file-system-defragmentation/","title":"XFS 文件系统碎片整理"},{"content":"echo 指令基本用法\r用法: echo [短选项]... [字符串]... 或: echo 长选项 将 STRING 回显到标准输出。 -n 不尾随换行符 -e 启用解释反斜杠的转义功能 -E 禁用解释反斜杠的转义功能(默认) --help 显示此帮助信息并退出 --version 显示版本信息并退出 若 -e 可用, 则以下序列即可识别: \\\\ 反斜杠 \\a 响铃声 \\b 退格 \\c 不再产生新的输出 \\e 转义符 \\f 换页 \\n 新行 \\r 回车 \\t 水平制表符 \\v 竖直制表符 \\0NNN 字节数以八进制数 NNN (1至3位)表示 \\xHH 字节数以十六进制数 HH (1至2位)表示 覆盖文件内容\r使用 \u0026gt; 指令覆盖文件原内容并重新输入内容, 若文件不存在则创建文件。\necho \u0026#34;Raspberry\u0026#34; \u0026gt; test.txt cat test.txt Raspberry 追加文件内容\recho \u0026#34;Raspberry\u0026#34; \u0026gt; test.txt echo \u0026#34;Intel Galileo\u0026#34; \u0026gt;\u0026gt; test.txt cat test.txt Raspberry Intel Galileo 输入转义字符\r此处用到了两处转移字符, \\t 制表符, \\\u0026quot; 双引号。\necho -e \u0026#34;{\u0026#34; \u0026gt; test-json.txt echo -e \u0026#34;\\t\\\u0026#34;name\\\u0026#34;:\\\u0026#34;acesheep\\\u0026#34;\u0026#34; \u0026gt;\u0026gt; test-json.txt echo -e \u0026#34;}\u0026#34; \u0026gt;\u0026gt; test-json.txt cat test.txt { \u0026#34;name\u0026#34;:\u0026#34;acesheep\u0026#34; } 使用变量\rFILE=\u0026#34;test-json.txt\u0026#34; echo -e \u0026#34;{\u0026#34; \u0026gt; $FILE echo -e \u0026#34;\\t\\\u0026#34;name\\\u0026#34;:\\\u0026#34;acesheep\\\u0026#34;\u0026#34; \u0026gt;\u0026gt; $FILE echo -e \u0026#34;}\u0026#34; \u0026gt;\u0026gt; $FILE cat test.txt { \u0026#34;name\u0026#34;:\u0026#34;acesheep\u0026#34; } 原文\nLinux学习笔记——如何使用echo指令向文件写入内容\n","date":"2018-06-19T16:41:00+08:00","permalink":"https://blog.acesheep.com/p/linux-echo-command-write-string-to-file/","title":"Linux echo 命令 字符串写入文件"},{"content":"起因, 无意间查看磁盘的 SMART 信息, 发现 SSD 写入了 1.59TB, 读取才 320G. 这才仅仅使用了 68 天. 这样下去128G 的 SSD. 迟早会把写入量用完, 导致不能写入数据\n首先看一下磁盘信息\nsmartctl -Ai /dev/nvme0n1 smartctl 6.5 2016-05-07 r4318 [x86_64-linux-4.15.4-1.el7.elrepo.x86_64] (local build) Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org === START OF INFORMATION SECTION === Model Number: SAMSUNG MZVPW128HEGM-00000 Serial Number: --- Firmware Version: CXZ7500Q PCI Vendor/Subsystem ID: --- IEEE OUI Identifier: --- Total NVM Capacity: 128,035,676,160 [128 GB] Unallocated NVM Capacity: 0 Controller ID: 2 Number of Namespaces: 1 Namespace 1 Size/Capacity: 128,035,676,160 [128 GB] Namespace 1 Formatted LBA Size: 512 Local Time is: Fri Jun 8 21:29:48 2018 CST === START OF SMART DATA SECTION === SMART/Health Information (NVMe Log 0x02, NSID 0x1) Critical Warning: 0x00 Temperature: 44 Celsius Available Spare: 100% Available Spare Threshold: 10% Percentage Used: 0% Data Units Read: 626,052 [320 GB] Data Units Written: 3,111,426 [1.59 TB] Host Read Commands: 12,856,998 Host Write Commands: 31,600,168 Controller Busy Time: 266 Power Cycles: 12 Power On Hours: 821 Unsafe Shutdowns: 0 Media and Data Integrity Errors: 0 Error Information Log Entries: 0 Warning Comp. Temperature Time: 0 Critical Comp. Temperature Time: 0 Temperature Sensor 1: 44 Celsius Temperature Sensor 2: 50 Celsius 禁用文件的最后访问时间 (relatime 选项)\r在 /etc/fstab 中为所有 xfs 分区添加 relatime 挂载参数, 减少文件系统对访问时间 (atime) 的写入操作\n修改 /etc/fstab 文件\n/dev/mapper/centos-root / xfs defaults,relatime 0 0 UUID=xxxx-xxxx-xxxx-xxxx /boot xfs defaults 0 0 UUID=xxxx-xxxx-xxxx-xxxx /boot/efi vfat umask=0077,shortname=winnt 0 0 /dev/mapper/centos-home /home xfs defaults,relatime 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 启用 TRIM 操作\r开启 fstrim 服务\nsystemctl enable --now fstrim.timer 或者定期手动执行 TRIM\nfstrim / fstrim /home fstrim /boot 限制交换分区的使用 (SWAP 分区)\r设置 vm.swappiness 为 1 会极大地减少系统对 SWAP 的使用, 除非内存非常紧张时才会使用 SWAP, 从而减少磁盘写入\n编辑 /etc/sysctl.conf 文件, 减少系统对交换分区的依赖\nvm.swappiness=1 # vm.vfs_cache_pressure=50 (可选, 我没用) 运行命令使更改生效\nsysctl vm.swappiness=1 sysctl -p # 快速导入 echo \u0026#34;vm.swappiness=1\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf 使用 tmpfs 保存临时文件\r使用 tmpfs 可以将 /tmp 的所有写操作都存储在内存中, 避免将临时文件写入磁盘, 从而减少对 SSD 的写入\n启用 tmp.mount 服务\nsystemctl enable tmp.mount 其他优化建议\r将 /home 和 /var/log 等经常写入数据的路径映射到 HDD 上。如果系统中有机械硬盘 (HDD), 可以将经常写入的目录如 /home 和 /var/log 挂载到 HDD 上, 减少 SSD 的写入量。\n原文\nLinux: IO Performance Tuning with noatime, nodiratime, relatime\n优化 CentOS 7，延长 SSD 使用寿命\n","date":"2018-06-08T22:00:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-ssd-optimization-reduce-disk-writes/","title":"CentOS 7 SSD 优化 减少磁盘写入"},{"content":"Supervisor 简介\rSupervisor 是一个用 Python 开发的进程管理工具, 可以在 Linux/Unix 系统中对多个进程进行启动、停止、重启、监听等管理操作, 不推荐在 Windows 系统上使用。它非常适合在服务器环境中运行服务进程时使用, 因为它可以在进程意外崩溃时自动重启这些进程, 不再需要自己写 shell 脚本来控制。\nSupervisor 通过 supervisord 进程来管理所有配置的子进程, 并通过 supervisorctl 命令与 supervisord 交互\n安装 Supervisor\r在安装 Supervisor 之前, 需要确保系统中已安装了 Python 2.4 及以上版本。以下命令适用于 CentOS 7, 默认使用 Python 2.7 环境进行安装\n安装所需依赖\r# 首先安装 python-setuptools yum -y install python-setuptools # 然后通过 easy_install 安装 Supervisor easy_install supervisor 创建 Supervisor 配置文件\r在 /etc/supervisor 目录下创建 conf.d 文件夹, 用来存放各个进程的配置文件\nmkdir -p /etc/supervisor/conf.d echo_supervisord_conf 是 supervisor 提供的一个命令, 用于生成默认的配置文件\n使用 echo_supervisord_conf 命令生成默认的 supervisord 配置文件\necho_supervisord_conf \u0026gt; /etc/supervisor/supervisord.conf 创建新用户 (可选)\n为了安全起见, 可以创建一个专门用于运行 Supervisor 的系统用户\nuseradd supervisor 将 Supervisor 配置为系统服务\r要将 supervisord 进程配置为 CentOS 7 的 Systemd 服务, 可以在 /usr/lib/systemd/system 目录下创建 supervisord.service 文件\nvim /usr/lib/systemd/system/supervisord.service 编辑 supervisord.service 文件, 内容如下\n[Unit] Description=supervisord - Supervisor process control system for UNIX Documentation=http://supervisord.org After=network.target [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf ExecReload=/usr/bin/supervisorctl reload ExecStop=/usr/bin/supervisorctl shutdown # 也可以换成 supervisor User=root [Install] WantedBy=multi-user.target 配置 Supervisor\r编辑 supervisord 的主配置文件 /etc/supervisor/supervisord.conf, 在文件末尾添加以下内容\n[include] files = /etc/supervisor/conf.d/*.conf 这样 Supervisor 会自动读取并加载 conf.d 目录中的所有 .conf 配置文件\n添加服务配置文件\r现在可以为要管理的进程创建配置文件, 例如管理一个名为 goapp 的 Go 应用, 可以创建 /etc/supervisor/conf.d/goapp.conf\nvim /etc/supervisor/conf.d/goapp.conf 在 goapp.conf 中添加以下内容\n[program:main] command=/srv/www/websiteurl.com/bin/main autostart=true autorestart=true startretries=10 user=supervisor 参数含义\ncommand 指定要启动的程序路径 autostart 是否随 supervisord 启动时自动启动该程序 autorestart 是否在进程退出后自动重启该程序 startretries 启动失败后的重试次数 user 启动该进程的用户 设置 Supervisor 开机启动\r# 设置开机启动 systemctl enable supervisord # 重启supervisord服务 systemctl restart supervisord # 可以使用 supervisorctl 查看 main 进程的运行状态 supervisorctl status main Supervisor 详细配置文件\r[unix_http_server] file=/tmp/supervisor.sock ;UNIX socket 文件, supervisorctl 会使用 ;chmod=0700 ;socket 文件的 mode, 默认是 0700 ;chown=nobody:nogroup ;socket 文件的 owner, 格式: uid:gid ;[inet_http_server] ;HTTP 服务器, 提供 web 管理界面 ;port=127.0.0.1:9001 ;Web 管理后台运行的 IP 和端口, 如果开放到公网, 需要注意安全性 ;username=user ;登录管理后台的用户名 ;password=123 ;登录管理后台的密码 [supervisord] logfile=/tmp/supervisord.log ;日志文件, 默认是 $CWD/supervisord.log logfile_maxbytes=50MB ;日志文件大小, 超出会 rotate, 默认 50MB, 如果设成0, 表示不限制大小 logfile_backups=10 ;日志文件保留备份数量默认 10, 设为0表示不备份 loglevel=info ;日志级别, 默认 info, 其它: debug,warn,trace pidfile=/tmp/supervisord.pid ;pid 文件 nodaemon=false ;是否在前台启动, 默认是 false, 即以 daemon 的方式启动 minfds=1024 ;可以打开的文件描述符的最小值, 默认 1024 minprocs=200 ;可以打开的进程数的最小值, 默认 200 [supervisorctl] serverurl=unix:///tmp/supervisor.sock ;通过 UNIX socket 连接 supervisord, 路径与 unix_http_server 部分的 file 一致 ;serverurl=http://127.0.0.1:9001 ;通过 HTTP 的方式连接 supervisord ; [program:xx]是被管理的进程配置参数, xx是进程的名称 [program:xx] command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run ;程序启动命令 autostart=true ;在 supervisord 启动的时候也自动启动 startsecs=10 ;启动 10秒 后没有异常退出, 就表示进程正常启动了, 默认为 1秒 autorestart=true ;程序退出后自动重启,可选值: [unexpected,true,false], 默认为 unexpected, 表示进程意外杀死后才重启 startretries=3 ;启动失败自动重试次数, 默认是 3 user=tomcat ;用哪个用户启动进程, 默认是 root priority=999 ;进程启动优先级, 默认 999, 值小的优先启动 redirect_stderr=true ;把 stderr 重定向到 stdout, 默认 false stdout_logfile_maxbytes=20MB ;stdout 日志文件大小, 默认 50MB stdout_logfile_backups = 20 ;stdout 日志文件备份数, 默认是 10 ;stdout 日志文件, 需要注意当指定目录不存在时无法正常启动, 所以需要手动创建目录 (supervisord 会自动创建日志文件) stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out stopasgroup=false ;默认为 false, 进程被杀死时, 是否向这个进程组发送 stop 信号, 包括子进程 killasgroup=false ;默认为 false, 向进程组发送 kill 信号, 包括子进程 ;包含其它配置文件 [include] files=/etc/supervisor/conf.d/*.conf ;可以指定一个或多个以 .ini 结束的配置文件 原文\nSupervisor安装与配置（Linux/Unix进程管理工具）\nLinux Supervisor的安装与使用入门\nSupervisord on linux CentOS 7 only works when run with root\n","date":"2018-05-17T17:07:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-install-supervisor/","title":"CentOS 7 安装 Supervisor"},{"content":"mktorrent 是一个轻量级、简单易用的命令行工具, 能够快速在 Windows 系统上创建 .torrent 文件。\n工具下载\rGitHub 仓库地址: q3aql/mktorrent-win\n备份下载 mktorrent-1.1-win-64bit-build2.7z\n创建 .torrent 文件\r使用以下命令在命令行中创建一个 .torrent 文件\nmktorrent -v -p -a http://tracker.url -o filename.torrent folder_name 参数含义\n-v 启用详细输出 (verbose), 可以显示更多执行信息。 -p 创建私有 (private) 种子, 不启用 DHT 或 PeerExchange。 -a 指定 tracker 服务器的 URL。 -o 指定输出 .torrent 文件的文件名。 folder_name 目标文件夹的路径, 生成的 .torrent 文件会包含该目录中的所有文件 注意: 命令必须写成一行, 如果目标文件夹路径中包含空格, 则需要使用引号 \u0026quot;\u0026quot; 将路径括起来\n示例\r假设我们要为 ~/torrents/completed/VA - Summer Trance 2009 目录生成一个种子文件, 并使用 http://tracker.what.cd:34000/xxxXXXxxx/announce 作为 tracker URL。可以使用以下命令\nmktorrent -v -p -a http://tracker.what.cd:34000/xxxXXXxxx/announce -o VA-Summer_Trance_2009.torrent \u0026#34;VA - Summer Trance 2009\u0026#34; 注意: 上例中, 目标目录名 \u0026quot;VA - Summer Trance 2009\u0026quot; 中含有空格, 因此使用了引号\n关于 Windows 系统路径格式\r在 Windows 系统中, mktorrent 使用 Cygwin 或 MSYS 提供的 Linux 样式路径格式, 因此磁盘路径应使用 /cygdrive/\u0026lt;磁盘盘符\u0026gt;/ 形式。\n例如, C: 盘对应 /cygdrive/c/。因此在命令行中指定文件夹路径时, 要转换为这种格式。\n或者先 cd 到目录再使用相对路径\nmktorrent -v -p -a http://tracker.url -o my_torrent.torrent /cygdrive/c/my_folder 设置分块大小\r可以使用 -l 参数 (小写字母 L) 来指定生成 .torrent 文件时的分块大小。分块大小以 2 的幂次方为单位, 适用于不同大小的文件\n2^19 = 524,288 字节 = 512 KiB 适用于 512 MiB - 1024 MiB 的文件 2^20 = 1,048,576 字节 = 1024 KiB 适用于 1 GiB - 2 GiB 的文件 2^21 = 2,097,152 字节 = 2048 KiB 适用于 2 GiB - 4 GiB 的文件 2^22 = 4,194,304 字节 = 4096 KiB 适用于 4 GiB - 8 GiB 的文件 2^23 = 8,388,608 字节 = 8192 KiB 适用于 8 GiB - 16 GiB 的文件 2^24 = 16,777,216 字节 = 16384 KiB 适用于 16 GiB - 512 GiB 的文件 (最大推荐值) 2^25 = 33,554,432 字节 = 32768 KiB utorrent 3.x 版本之前的客户端无法加载分块大小大于 2^24 的种子文件\n示例\r使用 -l 指定分块大小为 2^19 (512 KiB)\nmktorrent -v -p -l 19 -a http://example.tracker.com/announce -o my_torrent.torrent folder_name 原文\nHow To Create A Torrent Using Mktorrent\n","date":"2018-05-14T17:24:00+08:00","permalink":"https://blog.acesheep.com/p/create-torrents-with-mktorrent-on-windows/","title":"Windows 命令行使用 mktorrent 制作种子"},{"content":"Apache 2.2\nDocumentRoot \u0026#34;/var/www/example.com/public\u0026#34; \u0026lt;Directory \u0026#34;/var/www/example.com/public\u0026#34;\u0026gt; RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] \u0026lt;/Directory\u0026gt; Apache 2.4\nApache 文档\napache 2.4 的 rewrite 需要多配置一个 RewriteBase\n如果项目部署在域名根目录, 则在 RewriteEngine on 后面添加一行\nDocumentRoot \u0026#34;/var/www/example.com/public\u0026#34; \u0026lt;Directory \u0026#34;/var/www/example.com/public\u0026#34;\u0026gt; RewriteEngine On RewriteBase \u0026#34;/\u0026#34; RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] \u0026lt;/Directory\u0026gt; 原文\napache2.4和2.2的伪静态是不是不一样啊？\n","date":"2018-04-28T12:06:00+08:00","permalink":"https://blog.acesheep.com/p/apache-url-rewrite-for-pseudo-static/","title":"Apache (httpd) 伪静态设置"},{"content":"Open Chinese Convert (OpenCC, 开放中文转换) 是一个用于繁体中文、简体中文和日文汉字 (新字体) 之间转换的开源项目。它支持字级和短语级转换、字形转换和中国大陆、台湾和香港之间的区域性习语。这不是普通话和粤语之间的翻译工具等\nGitHub: BYVoid/OpenCC\n# doxygen 文档生成工具, 通常用于提取注释生成代码文档 # libnet-devel 用于网络应用开发 yum install gcc-c++ cmake doxygen libnet-devel # 检查 doxygen 是否成功安装并查看版本号 doxygen --version 1.8.5 # 下载并编译 OpenCC 源码 wget https://github.com/BYVoid/OpenCC/archive/ver.1.0.5.tar.gz tar zxf ver.1.0.5.tar.gz cd OpenCC-ver.1.0.5/ make make install 默认情况下, make install 会将 OpenCC 的库文件安装到 /usr/lib 目录中。如果你的系统使用的是 lib64 目录 (例如 64 位系统), 则可能需要手动创建一个符号链接, 将 /usr/lib/libopencc.so.2 链接到 /usr/lib64/libopencc.so.2\nln -s /usr/lib/libopencc.so.2 /usr/lib64/libopencc.so.2 测试\recho \u0026#34;伦\u0026#34; | opencc -c s2tw echo \u0026#34;伦\u0026#34; | opencc -c s2hk echo \u0026#34;伦\u0026#34; | opencc -c s2t echo \u0026#34;伦\u0026#34; | opencc -c s2twp echo \u0026#34;倫\u0026#34; | opencc -c s2twp echo \u0026#34;倫\u0026#34; | opencc -c s2tw echo \u0026#34;倫\u0026#34; | opencc -c s2hk echo \u0026#34;倫\u0026#34; | opencc -c s2t echo \u0026#34;倫\u0026#34; | opencc -c s2twp 原文\ncentos7 opencc 安装\n","date":"2018-04-07T18:12:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-compile-opencc/","title":"CentOS 7 编译 OpenCC"},{"content":"ncurses 是一个提供文本终端处理功能的库, 用于创建基于文本的用户界面。本章节展示了如何从源码编译和安装 ncurses-5.6\n通过这种方式, 可以将 ncurses 库安装到用户主目录的指定位置, 并在编译其他软件时引用该目录, 从而避免与系统默认安装的 ncurses 冲突。同时也便于管理多个版本的 ncurses\n下载与解压源码\rwget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.6.tar.gz tar zxf ncurses-5.6.tar.gz 配置、编译与安装\r./configure -prefix=$HOME/screen -with-shared -without-debug --enable-widec make \u0026amp;\u0026amp; make install 解释各个参数的含义\n--prefix=$HOME/screen 指定安装目录为 $HOME/screen, 表示将 ncurses 安装到用户主目录下的 screen 文件夹中 --with-shared 编译动态链接的共享库 --without-debug 不包含调试信息, 以减小库的大小 --enable-widec 启用对宽字符 (如 Unicode) 的支持 执行 make 命令进行编译, 并通过 make install 安装到指定目录 $HOME/screen 中\n编译其他软件时使用自定义的 ncurses 库\r在编译安装其他依赖 ncurses 的软件时, 可能需要指定自定义 ncurses 的路径。可以通过以下配置命令实现\n./configure --prefix=$HOME CFLAGS=\u0026#34;-I$HOME/include -I$HOME/include/ncursesw\u0026#34; LDFLAGS=\u0026#34;-L$HOME/lib -L$HOME/include/ncursesw -L$HOME/include\u0026#34; CPPFLAGS=\u0026#34;-I$HOME/include -I$HOME/include/ncursesw\u0026#34; LDFLAGS=\u0026#34;-static -L$HOME/include -L$HOME/include/ncursesw -L$HOME/lib\u0026#34; 原文\n记录23\u0026ndash;编译安装ncurses-5.6\n非root用户源码安装Tmux\n","date":"2018-03-29T18:23:00+08:00","permalink":"https://blog.acesheep.com/p/linux-install-ncurses-without-root/","title":"Linux 非 root 用户安装 ncurses"},{"content":"名词介绍\rCUDA 简介\r显卡厂商 NVIDIA 推出的运算平台 CUDA (Compute Unified Device Architecture), 是一种通用的并行计算架构, 该架构使 GPU 能够解决复杂的计算问题, 它包含了 CUDA 指令集以及 GPU 内部的并行计算引擎。\n提供了硬件的直接访问接口, 而不必像传统方式一样必须依赖图形 API 接口来实现 GPU 的访问, 从而给大规模的数据计算应用提供了一种比 CPU 更加强大的计算能力。程序开发人员通过 C 语言, 利用 CUDA 的指令接口, 就可以编写 CUDA 架构的程序。\nCuDNN 简介\rCuDNN (CUDA Deep Neural Network library) 是专门针对深度学习框架的 GPU 计算加速方案, 支持卷积、池化和 RNN 的性能优化。大部分深度学习框架, 包括 TensorFlow, 都支持 CuDNN。\n目前包括 TensorFlow 在内的大部分深度学习框架, 都支持 CUDA。所以, 为了让我们的深度神经网络的程序在 TensorFlow 上跑的更加好, 推荐配置至少一块支持 CUDA 和 CuDNN 的 NVIDIA 的显卡。\n安装环境\rTensorflow 推荐在 Ubuntu 16.04.1 LTS 上进行安装, 但同时也支持 Mac 和 Windows。深度学习计算需要大量的向量和矩阵计算, 使用 GPU 可以有一个数量级的速度提升\n# 可以显示服务器信息,测速 wget -qO- bench.sh | bash ---------------------------------------------------------------------- CPU model : Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz Number of cores : 40 CPU frequency : 1200.031 MHz Total size of Disk : 15120.4 GB (22.2 GB Used) Total amount of Mem : 257851 MB (632 MB Used) Total amount of Swap : 7812 MB (0 MB Used) System uptime : 8 days, 1 hour 6 min Load average : 0.00, 0.00, 0.00 OS : Ubuntu 16.04.1 LTS Arch : x86_64 (64 Bit) Kernel : 4.4.0-31-generic ---------------------------------------------------------------------- 安装 TensorFlow\rTensorFlow 的 Python API 支持 Python 2.7 和 Python 3.3 以上版本。GPU 版本推荐使用 CUDA Toolkit 8.0 和 CuDNN v5 版本。\n通过 pip 安装 TensorFlow\r安装 CPU 版本的 TensorFlow\n# Python 2.7 sudo pip install tensorflow # Python 3.5 sudo pip3 install tensorflow 安装支持 GPU 版本的 TensorFlow\n# Python 2.7 sudo pip install tensorflow-gpu # Python 3.5 sudo pip3 install tensorflow-gpu 源码编译安装 TensorFlow\r从 GitHub 下载源码\rgit clone https://github.com/tensorflow/tensorflow 安装 Bazel\rBazel 是 Google 开源的一套自动化构建工具, 可以通过源的方式安装, 也可以通过编译源码安装, 这里只介绍最简单的通过源的安装方式\n先安装 JDK8\nsudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java8-installer 添加 Bazel 源的地址\necho \u0026#34;deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8\u0026#34; | sudo tee /etc/apt/sources.list.d/bazel.list curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - 安装 Bazel\nsudo apt-get update sudo apt-get install -y bazel 编译 TensorFlow\r过程中会进行一些参数路径选择, 根据需要自己配置\ncd tensorflow ./configure # 添加 --config=cuda 表示 GPU 版本 bazel build -c opt --config=cuda --define=use_fast_cpp_protos=true /tensorflow/tools/pip_package:build_pip_package # 编译生成的 whl 文件会放在 /tmp/tensorflow_pkg 目录 bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg # 安装编译好的 TensorFlow sudo pip install --upgrade /tmp/tensorflow_pkg/tensorflow-0.12*.whl 编译安装过程中可能出现一些其他的依赖, 需要手动安装\n# 根据运行出错的提示可能需要安装 funcsigs 和 pbr sudo pip install funcsigs sudo pip install pbr CUDA 和 CuDNN 安装\r要使用 TensorFlow 的 GPU 版本, 需安装 CUDA 和 CuDNN 库\nNVIDIA 驱动安装\r驱动下载地址: NVIDIA 驱动下载\nsudo chmod +x NVIDIA-Linux-x86_64-367.44.run ./NVIDIA-Linux-x86_64-367.44.run CUDA 安装\r根据系统选择 CUDA 版本\n下载地址: CUDA 下载\n安装过程会提示一些选项, 需要注意的是, 我们在上一步已经安装了 NVIDIA 的驱动, 所以在提示是否需要安装NVIDIA Accelerated Graphics Driver 的时候选择 n\n选择参考如下: 请先阅读完许可文件, 以下是非 root 安装步骤\nDo you accept the previously read EULA? accept/decline/quit: accept Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 384.81? (y)es/(n)o/(q)uit: n Install the CUDA 9.0 Toolkit? (y)es/(n)o/(q)uit: y Enter Toolkit Location [ default is /usr/local/cuda-9.0 ]: /home/acesheep/cuda-9.0 Do you want to install a symbolic link at /usr/local/cuda? (y)es/(n)o/(q)uit: y /usr/local is not writable. Do you wish to run the installation with \u0026#39;sudo\u0026#39;? (y)es/(n)o: n sudo permissions are required to create the symbolic link. Do you want to install a symbolic link at /usr/local/cuda? (y)es/(n)o/(q)uit: n Install the CUDA 9.0 Samples? (y)es/(n)o/(q)uit: y Enter CUDA Samples Location [ default is /home/acesheep ]: Installing the CUDA Toolkit in /home/acesheep/cuda-9.0 ... Installing the CUDA Samples in /home/acesheep ... Copying samples to /home/acesheep/NVIDIA_CUDA-9.0_Samples now... Finished copying samples. 安装成功后, 提示我们需要把路径添加到环境变量里\nPlease make sure that - PATH includes /home/acesheep/cuda-9.0/bin - LD_LIBRARY_PATH includes /home/acesheep/cuda-9.0/lib64, or, add /home/acesheep/cuda-9.0/lib64 to /etc/ld.so.conf and run ldconfig as root root 用户在 /etc/profile 或者非 root 用户在 ~/.bashrc 文件中添加如下内容\nexport PATH=/home/acesheep/cuda-9.0/bin:$PATH export LD_LIBRARY_PATH=/home/acesheep/cuda-9.0/lib64/:$LD_LIBRARY_PATH # 然后执行 source, 使其立即生效 source /etc/profile source ~/.bashrc CuDNN 安装\r下载地址: CuDNN 下载\n以 CuDNN 的 v7.1 版本, Cuda 9.0 为例\ncp cudnn-9.0-linux-x64-v7.1.solitairetheme8 cudnn-9.0-linux-x64-v7.1.tgz tar xvf cudnn-9.0-linux-x64-v7.1.tgz cuda/include/cudnn.h cuda/NVIDIA_SLA_cuDNN_Support.txt cuda/lib64/libcudnn.so cuda/lib64/libcudnn.so.7 cuda/lib64/libcudnn.so.7.1.2 cuda/lib64/libcudnn_static.a 设置环境变量\nroot 用户在 /etc/profile 或者非 root 用户在 ~/.bashrc 文件, 在末尾添加如下内容\nexport CUDA_HOME=/home/acesheep/cuda-9.0 export LD_LIBRARY_PATH=\u0026#34;$HOME/cuda/lib64/:$LD_LIBRARY_PATH\u0026#34; export LD_LIBRARY_PATH=\u0026#34;$CUDA_HOME/lib64/:$LD_LIBRARY_PATH\u0026#34; export PATH=\u0026#34;$CUDA_HOME/bin:$PATH\u0026#34; # 然后执行 source, 使其立即生效 source /etc/profile source ~/.bashrc 安装完成之后, 让我们来测试一下 CUDA, 运行 nvidia-smi\nThu Mar 29 15:55:46 2018 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 384.111 Driver Version: 384.111 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 TITAN Xp Off | 00000000:04:00.0 Off | N/A | | 23% 28C P0 59W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 1 TITAN Xp Off | 00000000:05:00.0 Off | N/A | | 23% 29C P0 60W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 2 TITAN Xp Off | 00000000:08:00.0 Off | N/A | | 23% 33C P0 61W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 3 TITAN Xp Off | 00000000:09:00.0 Off | N/A | | 23% 35C P0 62W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 4 TITAN Xp Off | 00000000:85:00.0 Off | N/A | | 23% 30C P0 60W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 5 TITAN Xp Off | 00000000:86:00.0 Off | N/A | | 23% 35C P0 60W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 6 TITAN Xp Off | 00000000:89:00.0 Off | N/A | | 23% 30C P0 60W / 250W | 0MiB / 12189MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 7 TITAN Xp Off | 00000000:8A:00.0 Off | N/A | | 23% 29C P0 59W / 250W | 0MiB / 12189MiB | 3% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+ 说明 NVIDIA 的驱动和 CUDA 已经安装成功了\n上面的显示表示本机有 8 个GPU, GPU 核心 GeForce GTX TITAN Xp, 每个 GPU 有 12G 显存, 因为没有在上面跑任何程序, 所以目前 GPU 显存利用了 0M, GPU 利用率 0%\n测试 TensorFlow\r好, 如果顺利的话, 到这里我们已经成功安装好了 TensorFlow, 那么让我简单测试一下安装是否成功\n$ python ... \u0026gt;\u0026gt;\u0026gt; import tensorflow as tf \u0026gt;\u0026gt;\u0026gt; print(tf.__version__) 1.6.0 上面这段代码, 正常运行会打印出来 TensorFlow 的版本号, 这里是 1.6.0\n我们再跑一个简单的计算, 看看 TensorFlow 是否运行正常。输入如下代码\n$ python ... \u0026gt;\u0026gt;\u0026gt; import tensorflow as tf \u0026gt;\u0026gt;\u0026gt; hello = tf.constant(\u0026#39;Hello, TensorFlow!\u0026#39;) \u0026gt;\u0026gt;\u0026gt; sess = tf.Session() \u0026gt;\u0026gt;\u0026gt; print(sess.run(hello)) Hello, TensorFlow! \u0026gt;\u0026gt;\u0026gt; a = tf.constant(1) \u0026gt;\u0026gt;\u0026gt; b = tf.constant(2) \u0026gt;\u0026gt;\u0026gt; c=sess.run(a + b) \u0026gt;\u0026gt;\u0026gt; print(\u0026#34;1+2= %d\u0026#34; % c) 1+2= 3 \u0026gt;\u0026gt;\u0026gt; 如果你的这段代码可以正常输出 Hello, TensorFlow! 和 1+2= 3, 那么恭喜你, TensorFlow 安装成功！\n原文\nTensorflow环境搭建\n","date":"2018-03-29T16:05:00+08:00","permalink":"https://blog.acesheep.com/p/tensorflow-1.6.0-environment-setup/","title":"Tensorflow 环境搭建 1.6.0"},{"content":"很多时候我们拿到服务器的账号, 只是一个普通用户, 没有 root 权限, 这没有关系。关键是没有 pip、没有必要的python 包。\n参考 Stack Overflow 给出解决方案, 适用于 python2.7, python3.x\n安装 pip\r一定要加上 --user 参数, 以避免权限问题\n文件备份: get-pip.zip\nwget https://bootstrap.pypa.io/get-pip.py python get-pip.py --user 安装完成后, pip 会被放在用户的 ~/.local/bin 目录下。如果要直接使用, 需要将该目录加入到环境变量中\nexport PATH=~/.local/bin:$PATH 安装其他包\r有了 pip, 可以方便地安装其他 Python 包。这样安装的包会被放在 ~/.local 目录中\npip install --user 包名称 pip install --user virtualenv 虚拟环境 (virtualenv)\r为了管理不同项目的依赖, 可以使用 virtualenv 创建独立的环境\n# 安装 virtualenv pip install --user virtualenv # 创建虚拟环境 virtualenv env # 激活虚拟环境 source env/bin/activate 激活后, 可以在这个独立环境中使用 pip 安装依赖, 确保不同项目之间的包版本不会冲突\n原文\n【python-tips】非root权限安装pip、其他包\n","date":"2018-03-28T15:41:00+08:00","permalink":"https://blog.acesheep.com/p/python-install-pip-and-packages-without-root/","title":"Python 非 root 权限安装 pip、其他包"},{"content":"Mojo 和 IRC 安装及使用说明\rMojo::Webqq 和 Mojo::IRC 是两个基于 Perl 的模块, 可以用来与 QQ 和 IRC 服务器进行交互。以下步骤讲解了如何在 Linux 系统中安装和配置这些模块\n官方文档: Mojo::Webqq - A Webqq Client Framework base on Mojolicious\n项目仓库: github.com/hexsum/Mojo-Webqq\n环境准备\r首先, 我们需要安装 Perl 以及其他依赖工具。根据操作系统的不同, 可以选择相应的命令进行安装。\n安装 Perl\r# Debian sudo apt-get install perl # CentOS 7 yum install perl 安装包管理器 cpanm\r使用 cpanminus 可以方便地管理和安装 Perl 的第三方模块。以下是安装 cpanm 的命令\ncpan -i App::cpanminus 安装 Mojo::Webqq\rMojo::Webqq 是一个 Perl 的模块, 用于模拟 QQ 客户端, 可以与 QQ 服务器进行通信。安装步骤如下\ncpanm Mojo::Webqq 安装完成后, 如果输出如下内容, 则说明安装成功\nBuilding and testing Mojolicious-7.46 ... OK Successfully installed Mojolicious-7.46 Building and testing Mojo-Webqq-v2.1.4 ... OK Successfully installed Mojo-Webqq-v2.1.4 2 distributions installed 如果安装过程中出现 IO::Socket::SSL 错误, 请先安装 SSL 的开发库, 然后重新安装 Mojo::Webqq\n# Debian sudo apt-get install libssl-dev # CentOS 7 yum install openssl-devel 安装 IRC 模块\rMojo::IRC::Server::Chinese 模块是基于 Mojolicious 的中文 IRC 服务器\ncpanm -v Mojo::IRC::Server::Chinese 如果出现类似输出说明安装成功\nad-multi/perllocal.pod OK Successfully installed Mojo-IRC-Server-Chinese-v1.8.1 Installing /home/luhui/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/.meta/Mojo-IRC-Server-Chinese-1.8.1/MYMETA.json Installing /home/luhui/perl5/lib/perl5/x86_64-linux-gnu-thread-multi/.meta/Mojo-IRC-Server-Chinese-1.8.1/install.json 2 distributions installed 创建 IRC 启动脚本\r创建一个 Perl 脚本文件 ircqq.pl\nvim ircqq.pl 使用文本编辑器 (如 nano、vim) 编辑该脚本, 写入以下内容\n#!/usr/bin/env perl use Mojo::Webqq; my $client = Mojo::Webqq-\u0026gt;new(); $client-\u0026gt;load(\u0026#34;ShowMsg\u0026#34;); $client-\u0026gt;load(\u0026#34;IRCShell\u0026#34;); #加载IRCShell插件 $client-\u0026gt;run(); 启动 ircqq\r脚本需要一直保持运行状态, 因此请勿关闭终端或停止该进程\n保存文件后, 执行以下命令启动 IRC 服务器\nperl ircqq.pl 登录 QQ 并使用 IRC\r启动脚本后, 将会在 tmp 目录中生成一个登录二维码。使用手机 QQ 扫描该二维码完成登录。\n登录成功后, 脚本会在终端中显示 QQ 号和昵称, 并创建一个本地 IRC 服务器。\n安装并配置 IRC 客户端\r推荐使用 weechat 作为 IRC 客户端。安装命令如下\nsudo apt install weechat 启动\nweechat 连接本地 IRC 服务器\r在 weechat 中输入以下命令连接到本地 IRC 服务器\n/connect localhost 连接成功后, weechat 会自动创建 QQ 频道和联系人列表。weechat 中的使用方法与普通 IRC 客户端一致。可以通过以下命令查看频道\n/list 原文\n在Linux上使用mojoqq来实现命令行QQ\n","date":"2018-03-28T12:06:00+08:00","permalink":"https://blog.acesheep.com/p/use-mojoqq-for-command-line-qq-on-linux/","title":"在 Linux 上使用 MojoQQ 来实现命令行 QQ"},{"content":"Google Drive 即 GDrive 是谷歌家的云盘产品, 官方网站: https://drive.google.com, 新注册账号默认 15G 免费, 教育版无限空间, 官方支持 Windows、iOS、Android 客户端同步, 那么如何在 Linux 下使用谷歌的超大云盘呢?\n准备条件\r本教程基于 CentOS 7.3\n相关软件版本: pip 8.1.2/python 2.7.5\n项目主页: dsoprea/GDriveFS\n安装\r安装依赖\ryum -y install gcc gcc-c++ python-devel libxslt-devel libffi-devel openssl-devel fuse fuse-devel # Debian 安装命令 apt-get install python-pip build-essential python-dev 安装 Google API\rgit clone https://github.com/google/google-api-python-client cd google-api-python-client python setup.py install python setup.py install_egg_info 安装 GDriveFS\rpip install gdrivefs 使用\r登录\rgdfstool auth -u To authorize FUSE to use your Google Drive account... 将显示的 URL 贴到网页, 会显示授权页面, 授权后显示授权码, 拷贝完整授权码待用\ngdfstool auth -a /var/cache/gdfs.creds \u0026#34;刚拷贝的完整授权码\u0026#34; Authorization code recorded 挂载\rmkdir /mnt/gdrivefs gdfstool mount /var/cache/gdfs.creds /mnt/gdrivefs 问题摘要\rgreenlet.h:8:20: fatal error: Python.h: No such file or directory\nyum install python-devel -y OSError: [Errno 2] No such file or directory: \u0026lsquo;/usr/lib/python2.7/site-packages/google_api_python_client-1.6.2-py2.7.egg\u0026rsquo;\nyum install libffi-devel -y ImportError: cannot import name util\npip install oauth2client==2.2.0 注: 可能会提示: OSError: [Errno 2] No such file or directory: '/usr/lib/python2.7/site-packages/oauth2client-4.1.1-py2.7.egg', 可无视, 因为我们装的是 2.2.0 版本\n原文\nCentOS 7 如何挂载 Google Drive\n","date":"2018-03-25T21:39:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-mount-google-drive/","title":"CentOS 7 如何挂载 Google Drive"},{"content":"禁用并删除 Windows Update 服务\r彻底禁用 win10 自动更新!!!!\n1709 更新强制更新以前的 win10 版本\u0026hellip;\n莫名其妙的被安装了 WIN10 UPDATE ASSISTANT\n而且 Windows Update 的服务启动模式也定时从禁用被修改成手动\u0026hellip;\n再也无法忍受 每天起来电脑是一个升级后的状态\n以管理员身份运行 cmd 并输入一下命令\n在您妈的见, 辣鸡微软\n停止 Windows Update 服务\r对于 Windows 10 系统, 如果你不想被强制更新, 可以通过以下命令来禁用和删除 Windows Update 服务\n此步骤可选。停止服务后, 可以避免 wuauserv 服务在删除时仍然处于运行状态, 删除服务后不会终止正在运行的进程, 需要手动结束\nnet stop wuauserv 其他和更新相关的服务\nwuauserv Windows Update 服务 bits 后台智能传输服务 (Background Intelligent Transfer Service) dosvc 递送优化服务 (Delivery Optimization) 删除 Windows Update 服务\r删除服务后, Windows Update 服务将不再启动, 系统无法自动检查和安装更新。Microsoft Store 无法下载软件, 无法自动安装新设备驱动\nsc delete wuauserv 使用 regedit 编辑注册表\r防止服务重新生成\n在 HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services 中查找相应服务项 (如 wuauserv、bits 等), 将其删除\n修复 Windows 更新服务\r为什么要修复 更新服务呢?\n因为找到了一篇文章可以永久激活 Windows\n现在为了永久激活 win 10, 不得不再把更新服务装回去了. 不过激活后需要在把更新服务删除!!!\n下载并导入所需的注册文件\r选择你对应系统的文件下载 双击运行, 导入注册表 重新启动计算机 Windows 7\nBITSWin7.reg WindowsUpdateWin7.reg Windows 8\nBITSWin8.reg WindowsUpdateWin8.reg Windows 10\nBITSWin10.reg WindowsUpdateWin10.reg Windows 11\nBITSWin11.reg WindowsUpdateWin11.reg 检查更新服务是否在运行, 修复完成~\n可以开始永久激活 win 10 了~\nFIX: Windows Update service missing (not listed) in services.\n","date":"2018-03-19T02:51:00+08:00","permalink":"https://blog.acesheep.com/p/forced-disable-windows-updates-with-sc-command/","title":"在您妈的见, 彻底禁用微软强制更新!!! | 禁止 Win10 自动更新"},{"content":"SC 命令使用方法\rSC 命令 (Service Control) 是 Windows 系统中用于管理服务 (service) 的命令行工具。我们可以通过 sc 命令来安装、配置、启动、停止以及删除服务, 还可以用来管理 Windows 系统自带的服务。下面是 sc 命令及相关 net 命令的详细使用说明\n安装服务\r使用 sc create 命令可以在系统中安装一个新的 Windows 服务\nsc create 服务名 binPath= \u0026#34;C:\\Users\\Administrator\\Desktop\\win32srvDemo\\win32srvdemo\\Debug\\win32srvDemo.exe\u0026#34; 服务名: 指定创建的 Windows 服务的名称, 可以是任意唯一标识的字符串\nbinPath: 指定服务程序的可执行文件路径, 需要用引号括起来。注意 binPath= 等号与路径之间必须有一个空格, 否则会报错\n配置服务\r启动类型\n使用 sc config 命令配置服务的启动类型\nsc config 服务名 start= AUTO 其他选项\nstart= AUTO 自动启动 start= demand 手动启动 start= DISABLED 禁用服务 start= boot 用于引导启动 start= system 服务随系统启动 开启服务\r使用 net start 命令启动已经安装的服务\nnet start 服务名 sc start 服务名 关闭服务\r使用 net stop 命令停止正在运行的服务\nnet stop 服务名 sc stop 服务名 删除服务\r使用 sc delete 命令彻底删除指定的服务\nsc delete 服务名 查询服务状态\rsc query 服务名 更改服务描述\rsc description 服务名 \u0026#34;This is a custom service for data processing\u0026#34; 配置服务登录账户\r此命令将服务的登录账户配置为 LocalService 帐户, 并且不使用密码\nsc config 服务名 obj= \u0026#34;NT AUTHORITY\\LocalService\u0026#34; password= \u0026#34;\u0026#34; 更多信息\r如果想了解更多 SC 命令的用法, 可以在 CMD 中输入以下命令查看帮助\nsc /? 原文\nMicrosoft SC Command Documentation\n","date":"2018-03-19T01:51:00+08:00","permalink":"https://blog.acesheep.com/p/windows-sc-command-guide/","title":"Windows sc 命令使用方法"},{"content":"在 Windows 命令提示符 (CMD) 中, 如果路径中包含空格, 很容易引发命令执行错误。因此, 我们通常会采用以下几种方法来处理路径中的空格问题\n方法 1: 用双引号包裹路径\r对于包含空格的路径, 可以使用双引号来将路径括起来。这样 CMD 会将整个路径识别为一个整体。\n\u0026#34;D:/Program Files/xx\u0026#34; 方法 2: 使用 DOS 8.3 命名规则 (短文件名)\r在早期的 DOS 系统中, 不允许文件夹名称中带空格, 因此采用了 8 个字符命名规则 (8.3 格式)。这种格式为前 6 个字符加上 ~ 符号和一个数字表示序列。例如\nD:/Progra~1/xx 当 Progra~1: 前 6 个字符加 ~ 符号及数字 1, 表示第一个匹配的文件夹。\n多个文件夹具有相同的前 6 个字符时, 后缀数字顺序递增, 例如:\nProgram Files -\u0026gt; Progra~1 Progra file -\u0026gt; Progra~2 Progra zhang -\u0026gt; Progra~3 注意: 为了实现这样的缩写形式, 文件和文件夹必须已经存在。可以使用以下命令查看文件的 8.3 格式:\ndir /x 关于 8.3 命名规则的更多细节\r对于长文件名 (包含空格或超过 8 个字符), Windows 会为其生成一个符合 8.3 规则的短文件名, 以保持兼容性。这些规则如下:\n生成短文件名: 取前 6 个字符, 略去空格, 再加 ~ 和数字 1。 处理冲突: 如果文件夹的前 6 个字符相同, 则递增数字表示不同的目录。 例如:\n\u0026#34;Documents and Settings\u0026#34; -\u0026gt; DOCUME~1 \u0026#34;Local Settings\u0026#34; -\u0026gt; LOCALS~1 \u0026#34;Temporary Files\u0026#34; -\u0026gt; TEMPOR~1 如果前 6 个字符有重复:\nProgram Files -\u0026gt; Progra~1 Progra file -\u0026gt; Progra~2 Progra zhang -\u0026gt; Progra~3 方法 3: 使用 subst 命令映射虚拟磁盘\r利用 subst 命令可以将包含空格的目录映射为一个虚拟磁盘, 这样就不必每次输入长路径。具体步骤如下:\n映射虚拟磁盘:\n该命令会将 C:\\Documents and Settings\\hopeshared 目录映射为 B 盘\nsubst B: \u0026#34;C:\\Documents and Settings\\hopeshared\u0026#34; 删除虚拟磁盘:\nsubst B: /D 查看当前的虚拟磁盘映射\nsubst 使用 subst 命令的更多场景\r虚拟软驱: 安装某些软件时需要从软盘开始, 但机器上没有软驱时, 可以使用 subst 来创建虚拟软驱\nsubst A: C:\\temp 然后将 A: 盘符加入 Autoexec.bat 文件中, 即可在系统启动后将 C:\\temp 目录映射为 A: 盘\n隐藏软驱: 将一个目录属性设置为 \u0026ldquo;只读\u0026rdquo;、\u0026ldquo;隐藏\u0026rdquo;, 然后映射为软盘的盘符, 可以隐藏软盘的实际内容。\n原文\nCmD空格转义\n虚拟磁盘命令Subst使用详解\n","date":"2018-03-17T11:44:00+08:00","permalink":"https://blog.acesheep.com/p/cmd-space-escape-methods/","title":"CMD 空格转义与路径处理方法"},{"content":"视频处理工具及软件安装指南\r需要安装的软件\rX264 下载地址 eac3to Doom9 论坛地址 MKV 混流软件 下载地址 MP4Box 下载地址 VSFilterMod 修改版 NMM-HD 论坛地址 github.com/sorayuki/VSFilterMod Google Code 归档地址 工具简介与用途\rBDInfo\r用来查看蓝光原盘的 MPLS 信息, 目前为最新版。\nL-Smash\r替换系统自带的视频滤镜, 使用后视频处理速度大幅提升, 大约提升 35 fps 左右。\nSupTitle\r用于在 AVS (AviSynth 脚本) 中挂载蓝光原盘提取的 SUP 字幕内嵌, 目前可以用 MeGUI 中提供的。\nAviSynth\r脱离 MeGUI 和命令行环境, 让电脑中的其他软件也能正常支持 AVS 处理, 需要安装。\nMatroskaSplitter\r当用 eac3to 抽取视频并直接输出为 MKV 时, 需要这个工具才能正常输出, 如果出现错误, 可以安装尝试解决。\nx264_32.exe\r用于视频压制, 详细用途可以参照 x264 文档。\nx265_64_10bit 和 ffmpeg 三件套\r在处理 4K 压制时需要用到的工具, 压制 4K 时, 电脑中必须安装 AviSynth。\nneroAceEnc.exe\r放置在 eac3to.exe 的文件夹中, 用于直接输出 AAC 格式音频。\n基本使用流程\r以《Justice League》为示例说明操作流程:\n原盘处理\r原盘处理\n如果系统为 Win7, 需要安装虚拟光驱加载 ISO 镜像或使用 WinRAR、7-Zip 等解压软件解压 如果系统为 Win8/8.1/10, 直接双击 ISO 文件即可挂载。 提取内容\n必须提取的文件: 第一优顺位: 章节文件 (Chapter) 第二优顺位: 视频流 第三优顺位 (通常情况下): 音频流 提取输出格式\n通常输出得到: MKV 文件 (视频) AC3 文件 (音频) (取决于片源音轨, 如果是 True-HD Atmos 自动输出为 AC3, DTS-HDMA 自动输出为 DTS, RAW/PCM 自动输出为 WAV) TXT 文件 (章节信息) 若干 SUP 字幕文件 (根据提取内容选择) 封装规则\r如果使用 SUP 字幕, 只能封装为 M2TS 格式 如果使用 ASS/SSA 字幕, 只能封装为 MKV 格式 MP4Box 只支持部分格式, 如 SRT 和 IDX+SUB 等 命令行操作示例\rMP4Box 封装 MP4\n\u0026#34;C:\\MeGUI\\tools\\mp4box\\mp4box.exe\u0026#34; -chap \u0026#34;E:\\CHD\\Get Out\\GET_OUT_00968 - Chapter Information.txt\u0026#34; -add \u0026#34;D:\\CHD\\Test\\test.264\u0026#34; -add \u0026#34;D:\\CHD\\Test\\03.m4a:lang=ENG:name=English\u0026#34; -add \u0026#34;D:\\CHD\\Test\\Criminal.Minds.S13E16.720p.HDTV.x264-AVS.简体\u0026amp;英文.srt\u0026#34; -new \u0026#34;E:\\CHD\\Get Out\\test.mp4\u0026#34; 命令解析:\n-chap 后面是章节文件的路径, 由 eac3to 输出 -add \u0026quot;文件名及绝对路径\u0026quot; 是标准格式。示例中添加了一条视频流、音轨、和字幕 -new 后面是输出文件路径及文件名 MKVMerge 命令行封装 MKV 文件\n\u0026#34;C:\\Program Files\\MKVToolNix\\mkvmerge.exe\u0026#34; -o \u0026#34;D:\\CHD\\Test\\test.mkv\u0026#34; --chapters \u0026#34;D:\\CHD\\Test\\chapter.txt\u0026#34; \u0026#34;D:\\CHD\\Test\\video.264\u0026#34; \u0026#34;D:\\CHD\\Signal\\03.m4a\u0026#34; 命令解析:\n-o 设定输出文件路径 --chapters 指定章节文件路径 依次输入视频流、音频流、字幕文件。路径使用双引号包裹 使用工具的流程总结\r使用 BDInfo 查看蓝光原盘信息 使用 eac3to 读取指定的 MPLS 文件, 抽取所需的音视频流及字幕等内容。 使用 x264 或 x265 进行视频压制 最后使用 MP4Box 或 MKVMerge 进行封装, 生成所需格式的文件 总结\r以上内容为一套完整的蓝光原盘处理流程笔记, 包括了各个工具的下载链接、基本功能介绍及命令行使用示例。希望对你有所帮助\n","date":"2018-03-15T14:25:00+08:00","permalink":"https://blog.acesheep.com/p/x264-encoding-notes/","title":"x264 压制教程 随记"},{"content":"无论是 windows 系统还是 linux 系统, 除了物理内存外, 都还有一个虚拟内存。在 linux 上, 虚拟内存被称为 swap space。过去以来, 虚拟内存的大小应该是物理内存的两倍, 但是最近几年来, 物理内存的大小至少都有了好几个 GB, 如果 16G 内存用 32G 的 swap 岂不是太占用硬盘空间？\n下图是虚拟内存和交换空间的映射关系, 虚拟内存的存在, 可以提高电脑的运行速度, 所以其存在很有意义\n我们看看 redhat 的官方答复是怎么说的\n对于内存较少 (1 GB 及以下) 的系统尤其重要。在这些系统上, 如果分配的交换空间不足, 可能会导致不稳定等问题, 甚至导致已安装的系统无法启动。\nAmount of RAM in the system 物理内存 Recommended swap space 建议的交换空间大小 Recommended swap space if allowing for hibernation 如果开启休眠功能建议的交换空间大小 ⩽ 2GB 2 times the amount of RAM 3 times the amount of RAM \u0026gt; 2GB - 8GB Equal to the amount of RAM 2 times the amount of RAM \u0026gt; 8GB - 64GB At least 4 GB 1.5 times the amount of RAM \u0026gt; 64GB At least 4 GB Hibernation not recommended 总结起来就是\n如果不打算开启休眠功能, 物理内存在 8G 以下, 则 swap 设置为与物理内存一样大 如果不打算开启休眠功能, 物理内存在 8G 以上, 则 swap 空间设置为 8G 即可 当物理内存大于 64G 时, 不建议开启休眠功能 物理内存小于 1G 时, 则 swap 空间最少设置为 1G 以下是 Ubuntu 的指南, 更加细致: (从左至右依次是 RAM 大小, 不开启休眠, 开启休眠, 最大值)\nRAM No hibernation With Hibernation Maximum 256MB 256MB 512MB 512MB 512MB 512MB 1024MB 1024MB 1024MB 1024MB 2048MB 2048MB RAM No hibernation With Hibernation Maximum 1GB 1GB 2GB 2GB 2GB 1GB 3GB 4GB 3GB 2GB 5GB 6GB 4GB 2GB 6GB 8GB 5GB 2GB 7GB 10GB 6GB 2GB 8GB 12GB 8GB 3GB 11GB 16GB 12GB 3GB 15GB 24GB 16GB 4GB 20GB 32GB 24GB 5GB 29GB 48GB 32GB 6GB 38GB 64GB 64GB 8GB 72GB 128GB 128GB 11GB 139GB 256GB 256GB 16GB 272GB 512GB 512GB 23GB 535GB 1TB 1TB 32GB 1056GB 2TB 2TB 46GB 2094GB 4TB 4TB 64GB 4160GB 8TB 8TB 91GB 8283GB 16TB 原文\nLinux的swap空间需要设置多大？\n16.17.5. Recommended Partitioning Scheme\nSwapFaq\n","date":"2018-03-03T01:05:05+08:00","permalink":"https://blog.acesheep.com/p/linux-swap-space-sizing-guide/","title":"Linux 的 swap 空间需要设置多大?"},{"content":"在 Windows 操作系统中重置网络设置, 以解决网络连接问题。以下命令需要 cmd 以管理员身份运行\n重置 IPv4 配置\r如果遇到 IPv4 网络连接不稳定、IP 冲突或无法连接到网络的问题, 可以使用这条命令来重置 IPv4 网络配置\n它会将所有 IPv4 配置 (包括 IP 地址、子网掩码、网关等) 恢复到默认状态, 类似于清除 IP 堆栈的配置\nnetsh interface ipv4 reset 重置 IPv6 配置\r主要用于解决与 IPv6 相关的网络连接问题, 如无法通过 IPv6 协议访问网络资源或 IPv6 地址配置错误等问题\n它会将所有 IPv6 配置 (包括 IPv6 地址、前缀、网关等) 恢复到默认状态\nnetsh interface ipv6 reset 重置 Winsock 配置\r当系统出现网络连接问题 (例如无法访问网页、特定网络应用程序无法正常运行、网络设备驱动程序配置错误等), 且怀疑是由 Winsock 配置问题引起时, 可以使用该命令进行重置\nWinsock (Windows Sockets) 是 Windows 操作系统中网络应用程序和网络服务之间通信的接口。此命令会重置 Winsock 目录中的所有设置, 包括动态链接库 (DLL) 文件的顺序、注册表中 Winsock 配置的相关项。该操作不会影响 IP 地址或 DNS 配置, 但会修复由于 Winsock 配置损坏而导致的网络连接问题\nnetsh winsock reset 清除系统中的 DNS 缓存\r解决无法访问某个网站的问题 (例如 DNS 解析错误) 清除过期或错误的 DNS 缓存, 获取最新的域名解析记录。 DNS 配置变更后立即生效, 例如修改 hosts 文件或更换 DNS 服务器 它会删除本地存储的所有域名与 IP 地址映射关系, 强制系统重新向 DNS 服务器请求最新的解析记录\nipconfig /flushdns 重新注册 DNS 记录\r手动向 DNS (域名系统) 服务器注册或重新注册该计算机的 DNS 名称, 以便网络上的其他计算机可以通过其主机名找到它。\n这个命令用于确保计算机的 DNS 名称与其 IP 地址正确地注册在 DNS 服务器上 适用于当你修改了 DNS 设置或主机名, 但 DNS 记录没有及时更新时 常用于解决计算机在局域网中访问不正常的问题 ipconfig /registerdns 重新获取局域网 IP\r释放当前的 IP 地址\r个命令会让计算机放弃现有的 IP 地址 (通常意味着断开与网络的连接), 并通知 DHCP 服务器地址已经被释放。\n通常与 ipconfig /renew 配合使用, 以重置和更新 IP 地址。\nipconfig /release 获取新 IP 地址\r向 DHCP (动态主机配置协议) 服务器请求新的 IP 地址租约或续约现有租约。\n这个命令会释放现有的 IP 地址, 然后重新获取一个新的 IP 地址 适用于当你更换网络或希望手动更新 IP 地址时 通常用于解决 IP 地址冲突或连接性问题 ipconfig /renew ","date":"2018-03-01T17:17:00+08:00","permalink":"https://blog.acesheep.com/p/windows-network-reset/","title":"重置 Windows 网络"},{"content":"NAS 用的系统盘出现坏道, 时不时能听到 哒, 哒, 哒 的声音. 需要在他彻底坏掉之前把数据备份出来, 换上新的硬盘.\n于是想到如果能用 VMWare 虚拟机加载快坏的物理硬盘中的系统, 可以在旧系统里面拷贝数据到新的系统里面。每个文件的位置也能清楚的找到\n磁盘分区情况如下\n找到 boot 分区 /dev/sda2\n准备条件\rVMware® Workstation 14 Pro 14.1.1 build-7528167\nLinux Mint 的安装盘的 ISO 镜像文件 linuxmint-18.3-kde-64bit.iso\n建立虚拟机步骤\r在 VMWare 中新建虚拟机\r虚拟机参数根据实际情况设定\n删除虚拟机中的默认硬盘\r在上一个步骤中, 默认建立了一个硬盘。我们要把这个硬盘删掉。手动建立硬盘。\n加载物理分区\r选 编辑虚拟机设置\n将磁盘删除\n然后点击 添加 按钮。选择 磁盘, 点下一步\n这里应该根据物理硬盘的类型选择, 我选择的是 SATA。点下一步\n选择 使用物理磁盘 选项。点击下一步\n选择 Linux 所在的磁盘设备, 然后选择 使用单个分区 。点下一步\n选择 Linux 的分区, 包括交换分区。我的整个磁盘都是 Linux 我全部选择了。点下一步\n点击完成按钮。完成了物理磁盘的加载。\n建立引导分区\r我们需要在建立一个虚拟硬盘来引导 Linux。重复上面的步骤, 建立虚拟硬盘。在选择磁盘步骤。选择 创建新虚拟磁盘。点击下一步\n这个磁盘的容量不需要很大, 1G 已经足够大了\n建立完成后如下\n检查一下磁盘的 虚拟设备结点, 保证物理磁盘是 0:0。\n用 Linux Mint 光盘镜像引导虚拟机\r首先设置光盘镜像\n然后, 启动虚拟机。\n启动一个终端, 输入 sudo fdisk -l 来查看磁盘情况。我的虚拟磁盘如下。\n加载的物理磁盘是 /dev/sda, 新创建的 1G 虚拟磁盘是 /dev/sdb\n为启动盘创建分区\r输入 sudo fdisk /dev/sdb, 在 sdb 上创建分区 输入 n, 建立新分区 然后输入 p, 建立主分区 后续步骤都是用默认选项 最后输入 w 写入并退出 fdisk 在启动分区上创建引导记录\r首先, 要挂载 boot 分区。我的 boot 分区是 /dev/sda2\n然后, 用 grub-install 命令创建引导记录\nmint@mint ~ $ sudo mkdir /mnt/boot mint@mint ~ $ sudo mount /dev/sda2 /mnt/boot mint@mint ~ $ sudo grub-install --boot-directory=/mnt/boot /dev/sdb grub-probe: error: failed to get canonical path of \u0026#39;aufs\u0026#39;. Installing for i386-pc platform. Installation finished. No error reported. mint@mint ~ $ 启动 Mint\r现在可以重启系统。\n在虚拟机启动时, 按 F2 键进入虚拟机的 bios 设置 在 boot 选项页面, 调整 Hard Drive 设备的启动顺序 把 0:2 设备作为第一个启动的 Hard Deive 设备 成功进入 GRUB2 引导界面\n手动引导启动系统\rroot 目录为 boot 所在目录, 其中内核 vmlinuz 和 initrd.img 的版本号可按 Tab 键自动查看\n# 其中 hd0 为根目录所在的磁盘, IDE 硬盘用 hd 开始, SCSI 硬盘用 sd 开头。软盘用 fd 开头。命名和linux 不大一样。是从0算起。 # 输入 hd 后按 tab 键可以进行查看。msdos1 为根目录所在的分区, 输入 msdos 后按 tab 键可以进行查看 grub\u0026gt;set root=(hd1,5) # 其中 xxx-xxx 为内核版本, 输入 /boot/vmlinuz 后按 tab 键可以进行自动补全 # sda5 为根目录所在的分区 # 若 boot 目录是单独分区同上为 linux /vm... # 若 boot 不是单独分区就输入 linux /boot/vm... grub\u0026gt;linux /boot/vmlinuz-xxx-xxx root=/dev/sdb5 grub\u0026gt;initrd /boot/initrd.img-xxx-xxx # 启动系统w, 成功~ grub\u0026gt;boot 原文\nhttp://www.cnblogs.com/qiaoyanlin/p/6901242.html\nGRUB2手动引导Ubuntu\nGrub2启动项的修改和相关操作命令\n","date":"2018-02-18T17:43:00+08:00","permalink":"https://blog.acesheep.com/p/vmware-boot-linux-from-physical-disk-with-grub2/","title":"使用 VMware 启动物理硬盘上的 Linux (CentOS 7), 并用 GRUB2 手动引导"},{"content":"\r这个汉化存在错别字, 还有左侧任务栏汉化不完整的问题\n在此基础上我已经进行了修复. 达到了 95% 的汉化\nDeluge-web 汉化\r新增:\n左侧任务列表汉化 选项设置汉化 任务选项卡汉化 进度条颜色 v2.2 加入文件过滤, 更容易的找到种子文件 v2.3 修复:\n任务栏错别字 连接管理逻辑错误 修复名称图标不显示问题 v2.1 修改:\n汉化署名 已知BUG:\n断开服务器后,刷新页面会出现服务器错误.不刷新的话不会出现.这个问题不确定是 Deluge的问题还是汉化后才出现的. 版本预告 2.4\n批量添加文件支持 下载\rDeluge-web_zh-cn_v2.0.zip\nDeluge-web_zh-cn_v2.1.zip\nDeluge-web_zh-cn_v2.2.zip\nDeluge-web_zh-cn_v2.3.zip\nDeluge-web_zh-cn_v2.4.zip\n安装路径\rCentOS 6 的路径是\n/usr/lib/python2.6/site-packages/deluge/ui/web/ Ubuntu 16\n/usr/lib/python2.7/dist-packages/deluge-1.3.15-py2.7.egg/deluge/ui/web 群晖 deluge 1.3.15 替换路径为\n/volume1/@appstore/deluge/env/lib/python2.7/site-packages/deluge-1.3.15-py2.7.egg/deluge/ui/web 其他\n\u0026lt;PY安装路径\u0026gt;/python2.7/site-packages/deluge-1.3.15-py2.7.egg/deluge/ui/web/ 原文\nDeluge-web界面汉化\n","date":"2018-01-09T04:44:00+08:00","permalink":"https://blog.acesheep.com/p/deluge-web-1.3.15-chinese-translation/","title":"Deluge-web 1.3.15 完整汉化版"},{"content":"firewalld 概述\r动态防火墙后台程序 firewalld 提供了一个 动态管理的防火墙, 用以支持网络 \u0026ldquo;zones\u0026rdquo;, 以分配对一个网络及其相关链接和界面一定程度的信任。它具备对 IPv4 和 IPv6 防火墙设置的支持。它支持以太网桥, 并有分离运行时间和永久性配置选择。它还具备一个通向服务或者应用程序以直接增加防火墙规则的接口。\n系统提供了图像化的配置工具 firewall-config、system-config-firewall, 提供命令行客户端 firewall-cmd, 用于配置 firewalld 永久性或非永久性运行时间的改变: 它依次用 iptables 工具与执行数据包筛选的内核中的 Netfilter 通信\n基于用户对网络中设备和交通所给与的信任程度, 防火墙可以用来将网络分割成不同的区域 NetworkManager 通知 firewalld 一个接口归属某个区域, 新加入的接口被分配到默认区域。\n网络区名称 默认配置\rtrusted(信任) 可接受所有的网络连接 home(家庭) 用于家庭网络, 仅接受 ssh、mdns、ipp-client、samba-client、或 dhcpv6-client 服务连接 internal(内部) 用于内部网络, 仅接受 ssh、mdns、ipp-client、samba-client、dhcpv6-client 服务连接 work(工作) 用于工作区, 仅接受 ssh、ipp-client 或 dhcpv6-client 服务连接 public(公共) 在公共区域内使用, 仅接受 ssh 或 dhcpv6-client 服务连接, 为 firewalld 的默认区域 external(外部) 出去的 ipv4 网络连接通过此区域伪装和转发, 仅接受 ssh 服务连接 dmz(非军事区) 仅接受 ssh 服务接连 block(限制) 拒绝所有网络连接 drop(丢弃) 任何接收的网络数据包都被丢弃, 没有任何回复 我们知道每个 zone 就是一套规则集, 但是有那么多 zone, 对于一个具体的请求来说应该使用哪个 zone (哪套规则) 来处理呢？这个问题至关重要, 如果这点不弄明白其他的都是空中楼阁, 即使规则设置的再好, 不知道怎样用、在哪里用也不行\n对于一个接受到的请求具体使用哪个 zone, firewalld 是通过三种方法来判断的\nsource, 也就是源地址 优先级最高 interface, 接收请求的网卡 优先级第二 firewalld.conf 中配置的默认 zone 优先级最低 这三个的优先级按顺序依次降低, 也就是说如果按照 source 可以找到就不会再按 interface 去查找, 如果前两个都找不到才会使用第三个, 也就是在前面给大家讲过的在 firewalld.conf 中配置的默认 zone\n管理防火墙\r安装防火墙软件\nyum install firewalld firewall-config -y firewalld 操作命令\r# 查看版本 firewall-cmd --version # 查看帮助 firewall-cmd --help # 显示状态 firewall-cmd --state # 查看所有可用区域 firewall-cmd --get-zones # 查看区域信息 firewall-cmd --get-active-zones # 查看默认网络区域 firewall-cmd --get-default-zone # 列出指定域的所有设置 [root@localhost ~]# firewall-cmd --zone=public --list-all public (default, active) interfaces: eth0 sources: services: dhcpv6-client ssh ports: masquerade: no forward-ports: icmp-blocks: rich rules: # 列出所有预设服务 (这样将列出 /usr/lib/firewalld/services/ 中的服务器名称。注意: 配置文件是以服务本身命名的 service-name.xml) firewall-cmd --get-services # 查看指定接口所属区域 firewall-cmd --get-zone-of-interface=eth0 # 拒绝所有包 firewall-cmd --panic-on # 取消拒绝状态 firewall-cmd --panic-off # 查看是否拒绝 firewall-cmd --query-panic # 打开端口 (貌似这个才最常用) # 查看 dmz 区域所有打开的端口 firewall-cmd --zone=dmz --list-ports # 加入一个端口到 dmz 区域 firewall-cmd --zone=dmz --add-port=8080/tcp # 若要永久生效方法同上 # 永久生效再加上 --permanent, 然后 reload 防火墙 # 更新防火墙规则 # 两者的区别就是第一个无需断开连接, 就是 firewalld 特性之一动态添加规则 # 第二个需要断开连接, 类似重启服务 firewall-cmd --reload firewall-cmd --complete-reload # 打开一个服务, 类似于将端口可视化, 服务需要在配置文件中添加, /etc/firewalld 目录下有services 文件夹 firewall-cmd --zone=work --add-service=smtp # 移除 work 区域服务 firewall-cmd --zone=work --remove-service=smtp 手动编辑服务文件\rfirewalld 的配置文件以 xml 格式为主 (主配置文件 firewalld.conf 例外), 他们有两个存储位置\n/etc/firewalld/ 用户配置文件 /usr/lib/firewalld/ 系统配置文件, 预置文件 限制 SSH 只能由特定的 IP 连接\nvim /etc/firewalld/zones/dmz.xml \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;zone\u0026gt; \u0026lt;short\u0026gt;DMZ\u0026lt;/short\u0026gt; \u0026lt;description\u0026gt;(文字说明省略)\u0026lt;/description\u0026gt; \u0026lt;rule family=\u0026#34;ipv4\u0026#34;\u0026gt; \u0026lt;source address=\u0026#34;211.72.188.188\u0026#34;/\u0026gt; \u0026lt;service name=\u0026#34;ssh\u0026#34;/\u0026gt; \u0026lt;!-- \u0026lt;log prefix=\u0026#34;sshlog\u0026#34; level=\u0026#34;info\u0026#34;/\u0026gt; --\u0026gt; \u0026lt;accept/\u0026gt; \u0026lt;/rule\u0026gt; \u0026lt;/zone\u0026gt; 注意事项\n无须考虑 ICMP 封包的问题, 除非有特别想阻挡的 ICMP 项目 配置里, 要注解某一行时, 请用 \u0026lt;!-- --\u0026gt; 在 \u0026lt;rule\u0026gt; 里的 \u0026lt;service\u0026gt;, 只能有一个 \u0026lt;service\u0026gt; 将 source address 换成你允许开放连接的 IP 上面的例子 \u0026lt;log\u0026gt; 是无作用, 若要记录此规则的相关连接日志, 可以将 \u0026lt;!-- --\u0026gt; 删除, 它会将资料记录在 /var/log/messages 里 若语法有错误, 重新载入时, 会将错误写在 /var/log/firewalld 里 zone 配置只能限制访问 ip 和设置允许的服务\n端口设置要在服务里面设置, 也就是自定义服务至少需要两个文件\n一个 zone (区域) xml, 一个是要开启端口 (服务) xml\n原文\nfirewalld的配置\ncentos7\u0026amp;redhat 之 firewalld 详细介绍配置\nCentOS 7 － firewalld防火牆基本概念\n","date":"2017-12-27T16:58:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-firewalld-configuration-guide/","title":"CentOS 7 firewalld 配置教程"},{"content":"什么是 aria2\raria2 是一款用于下载文件的实用程序。支持的协议包括 HTTP(S)、FTP、SFTP、BitTorrent 和 Metalink。aria2 可以从多个来源/协议下载文件, 并尝试利用你的最大下载带宽。它支持同时从 HTTP(S)/FTP/SFTP 和 BitTorrent 下载文件。使用 Metalink 的块校验和, aria2 会在下载文件 (如 BitTorrent) 时自动验证数据块。\n安装依赖\r下载最新的程序代码 2018年1月1日 需要的第三方库\n功能 依赖 HTTPS OSX or GnuTLS or OpenSSL or Windows SFTP libssh2 BitTorrent None. Optional: libnettle+libgmp or libgcryptor OpenSSL (see note) Metalink libxml2 or Expat. Checksum None. Optional: OSX or libnettle or libgcryptor OpenSSL or Windows (see note) gzip, deflate in HTTP zlib Async DNS C-Ares Firefox3/Chromium cookie libsqlite3 XML-RPC libxml2 or Expat. JSON-RPC over WebSocket libnettle or libgcrypt or OpenSSL 需要什么功能在 ./configure 之前把依赖安装好\n例如 我用的是 CentOS 7 要想支持全部的功能. 就需要安装 OpenSSL libssh2 libxml2 zlib libsqlite3 这 5 个的 devel 版本\n全部安装可以直接执行这个命令. 这样所有依赖都可以解决\nyum install libxml2-devel autoconf automake autopoint libtool gettext-devel libssh2-devel libgcrypt-devel LibGmp openssl-devel kernel-devel cppunit-devel sqlite-devel 下载 aria2 源码\rgithub.com/aria2/aria2\nwget https://github.com/aria2/aria2/releases/download/release-1.33.1/aria2-1.33.1.tar.gz tar -xvf aria2-1.33.1.tar.gz cd aria2-1.33.1 # 生成 configure 文件 autoreconf -i # 静态编译 ./configure ARIA2_STATIC=yes # 使用 12核心 同时编译. 2分钟编译完成 make -j12 # 检查是否编译成功 make check # 编译好如果文件过大, 可以用 strip 命令裁剪小 # 我这里编译完 78 MB, 裁剪之后只有 2.72 MB strip -s test/aria2c # 安装 aria2 make install 编译安装很简单. 接下来是配置 aria2\n配置 aria2\r配置文件的文档资料在这里 aria2c(1) 有最新的配置参数\n要配置的地方有七处\n全局设置 磁盘缓存 断点续传 HTTP/FTP/SFTP HTTP RPC Options BT/PT下载相关 这个是我的配置文件, 每一个详细参数说明都在配置文件里面有\n# 全局设置 min-tls-version=TLSv1.1 disable-ipv6=true log=./aria2.log content-disposition-default-utf8=true # 磁盘缓存 disk-cache=256M # 断点续传 continue=true input-file=./aria2.session save-session=./aria2.session save-session-interval=60 force-save=true # HTTP/FTP/SFTP lowest-speed-limit=10 max-connection-per-server=16 split=16 min-split-size=10M # HTTP max-concurrent-downloads=5 http-accept-gzip=true user-agent= \u0026lt;写自己的\u0026gt; save-cookies=./aria2.cookies # RPC Options enable-rpc=true rpc-listen-port=6800 rpc-allow-origin-all=true rpc-certificate=./aria2.crt rpc-private-key=./aria2.key rpc-secret= \u0026lt;安全密码, 写自己的\u0026gt; rpc-listen-all=true rpc-secure=true # BT/PT下载相关 bt-save-metadata=true bt-max-peers=0 bt-request-peer-speed-limit=8M # 根据自己的网速设置 max-upload-limit=300K seed-time=10 listen-port=6801-6919 启动命令\r# 配置文件写自己的绝对路径 -D 是后台运行 aria2c --conf-path=./aria2.conf -D aria2 web UI\rAriaNg 下载地址: https://github.com/mayswind/AriaNg\n下载后放在 httpd 服务器里面\n在服务器设置里面填写 aria2 的服务器地址. 连接成功后就可以远程下载了\n如果没有 httpd 服务器可以下载 AriaNg Native 使用\n由于 AriaNg 通过异步加载语言文件, 所以你可能无法直接在本地文件系统打开 index.html 来运行 AriaNg。建议将 AriaNg 部署在 Web 容器中, 或下载不需要浏览器就可以运行的 AriaNg Native\n","date":"2017-12-24T08:46:00+08:00","permalink":"https://blog.acesheep.com/p/aria2-compile-install-and-configure/","title":"aria2 编译安装和配置"},{"content":"Extra Packages for Enterprise Linux (EPEL)\r企业版 Linux 额外软件包 (EPEL) 是 Fedora 项目内的一项计划, 旨在为 CentOS 和 Red Hat Enterprise Linux (RHEL) 提供高质量的附加软件包\nEPEL 软件包通常基于 Fedora 软件包, 不会与基础企业 Linux 发行版中的软件包冲突或替代它们。EPEL 使用与 Fedora 相同的许多基础架构, 包括构建系统、Bugzilla 实例、更新管理器、镜像管理器等\n安装\r我们会看到 centos yum 从仓库中根本找不到这几个包\n但我不想使用源码编译就想使用 yum 安装, 怎么办?\n# 安装扩展包 yum install epel-release # 清除 yum 缓存 yum clean all # 生成新的缓存 yum makecache ","date":"2017-12-22T22:07:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-install-epel/","title":"CentOS 7 安装 EPEL"},{"content":"编译安装\r下载安装\nwget http://ffmpeg.org/releases/ffmpeg-3.4.1.tar.bz2 tar -jxvf ffmpeg-3.4.1.tar.bz2 cd ffmpeg-3.4.1 编译, 安装\n./configure --prefix=/usr/local/ffmpeg # 等待安装完成... NAS 2 分钟编译完成 make -j$(($(nproc) + 1)) make install 设置环境变量\nvim /etc/profile # 在最后PATH添加环境变量 export PATH=$PATH:/usr/local/ffmpeg/bin # 保存退出 # 设置生效 source /etc/profile # 查看版本 ffmpeg -version 注意事项\r若安装过程中出现以下错误\nnasm/yasm not found or too old. Use \u0026ndash;disable-x86asm for a crippled build.\nIf you think configure made a mistake, make sure you are using the latest\nversion from Git. If the latest version fails, report the problem to the\nffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.\nInclude the log file \u0026ldquo;ffbuild/config.log\u0026rdquo; produced by configure as this will help\nsolve the problem.\n需要安装 yasm\rwget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz tar -zxvf yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure make -j$(($(nproc) + 1)) make install 原文\n[CentOS_7.4]Linux编译安装ffmpeg\n","date":"2017-12-22T21:18:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-compile-and-install-ffmpeg/","title":"CentOS 7 编译安装 ffmpeg"},{"content":"Linux 终端命令行全部为白色, 会经常导致命令与输出内容难以分辨\n通过定义 PS1 环境变量即可实现,下面我以 root 用户身份进行操作\n在终端输入命令\necho $PS1 可得到当前 PS1 的定义值\nPS1=\u0026#39;[\\u@\\h \\W]\\$ \u0026#39; PS1 的定义\r常用的参数的含义如下\n\\d # 代表日期, 格式为 weekday month date, 例如: \u0026#34;Mon Aug 1\u0026#34; \\H # 完整的主机名称 \\h # 仅取主机的第一个名字 \\t # 显示时间为24小时格式, 如: HH:MM:SS \\T # 显示时间为12小时格式 \\A # 显示时间为24小时格式: HH:MM \\u # 当前用户的账号名称 \\v # BASH 的版本信息 \\w # 完整的工作目录名称 \\W # 利用 basename 取得工作目录名称, 所以只会列出最后一个目录 \\# # 下达的第几个命令 \\$ # 提示字符, 如果是 root 时, 提示符为: #, 普通用户则为: $ 由此, 我们可知 linux 默认的命令行提示信息为\n# [当前用户的账号名称@主机的第一个名字 工作目录的最后一项]# [\\u@\\h \\W]\\$ 颜色的设置\r在PS1中设置字符颜色的格式为\n\\[\\e[F;Bm\\]....\\[\\e[0m\\] 其中 F 为字体颜色, 编号为 30-37, B 为背景颜色, 编号为 40-47\n\\[\\e[0m\\] 作为颜色设定的结束\n颜色表如下\nF B 颜色名称 30 40 黑色 31 41 红色 32 42 绿色 33 43 黄色 34 44 蓝色 35 45 紫红色 36 46 青蓝色 37 47 白色 只需将对应数字套入设置格式中即可\n比如要设置命令行的格式为绿字黑底 \\[\\e[32;40m\\], 显示当前用户的账号名称 \\u、主机的第一个名字 \\h、完整的当前工作目录名称 \\w、24 小时格式时间 \\t, 可以直接在命令行键入如下命令\nPS1=\u0026#39;[\\[\\e[32;40m\\]\\u@\\h \\w \\t]\\$ \\[\\e[0m\\]\u0026#39; # 样式 [root@server ~ 14:42:23]# 经过多次测试后, 最终确定了一个适合我自己的格式\nPS1=\u0026#39;\\[\\e[35;40m\\][\\[\\e[31;40m\\]\\u\\[\\e[33;40m\\]@\\[\\e[36;40m\\]\\h\\[\\e[35;40m\\]]-[\\[\\e[37;40m\\]\\t\\[\\e[35;40m\\]]-[\\[\\e[33;40m\\]\\#\\[\\e[35;40m\\]]-[\\[\\e[32;40m\\]\\w\\[\\e[35;40m\\]]\\n\\[\\e[33;40m\\] \u0026gt;\u0026gt;\\$ \\[\\e[0m\\]\u0026#39; # 样式 [root@server]-[14:44:51]-[4]-[~] \u0026gt;\u0026gt;# PS1=\u0026#39;[\\[\\e[31;40m\\]\\u\\[\\e[33;40m\\]@\\[\\e[36;40m\\]\\h \\[\\e[32;40m\\]\\w \\[\\e[37;40m\\]\\t]\\$ \\[\\e[0m\\]\u0026#39; # 样式 [root@server ~ 03:47:37]# 永久保存\r修改 .bashrc 文件, 永久保存命令行样式\n通过上面的设置只能改变当前终端的命令行格式, 关闭这个终端, 在重新打开的一个终端中命令行格式又会恢复到默认的形式。想要永久性的改变终端命令行格式, 需要修改 .bashrc 文件\n键入命令\ncd ~ ls -al 现在可以看到 .bashrc 这个文件\n编辑 .bashrc\nvim .bashrc 加入这一行\nPS1=\u0026#39;\\[\\e[35;40m\\][\\[\\e[31;40m\\]\\u\\[\\e[33;40m\\]@\\[\\e[36;40m\\]\\h\\[\\e[35;40m\\]]-[\\[\\e[37;40m\\]\\t\\[\\e[35;40m\\]]-[\\[\\e[33;40m\\]\\#\\[\\e[35;40m\\]]-[\\[\\e[32;40m\\]\\w\\[\\e[35;40m\\]]\\n\\[\\e[33;40m\\] \u0026gt;\u0026gt;\\$ \\[\\e[0m\\]\u0026#39; 保存退出\n重新加载 bash 配置文件\nsource ~/.bashrc 或者可以一键导入\necho \u0026#34;PS1=\u0026#39;\\[\\e[35;40m\\][\\[\\e[31;40m\\]\\u\\[\\e[33;40m\\]@\\[\\e[36;40m\\]\\h\\[\\e[35;40m\\]]-[\\[\\e[37;40m\\]\\t\\[\\e[35;40m\\]]-[\\[\\e[33;40m\\]\\#\\[\\e[35;40m\\]]-[\\[\\e[32;40m\\]\\w\\[\\e[35;40m\\]]\\n\\[\\e[33;40m\\] \u0026gt;\u0026gt;\\$ \\[\\e[0m\\]\u0026#39;\u0026#34; \u0026gt;\u0026gt; ~/.bashrc 原文\n修改linux终端命令行颜色\nPS1应用之——修改linux终端命令行各字体颜色\n","date":"2017-12-21T19:48:00+08:00","permalink":"https://blog.acesheep.com/p/linux-change-terminal-command-line-colors/","title":"Linux 修改终端命令行颜色"},{"content":"dstat 命令是一个用来替换 vmstat、iostat、netstat、nfsstat 和 ifstat 这些命令的工具, 是一个全能系统信息统计工具。与 sysstat 相比, dstat 拥有一个彩色的界面, 在手动观察性能状况时, 数据比较显眼容易观察\n而且 dstat 支持即时刷新, 譬如输入dstat 3 即每三秒收集一次, 但最新的数据都会每秒刷新显示。\n和 sysstat 相同的是, dstat 也可以收集指定的性能资源, 譬如 dstat -c 即显示CPU的使用情况。\n下载安装\r方法一\nyum install -y dstat 方法二\n官网下载地址: http://dag.wieers.com/rpm/packages/dstat\nwget http://dag.wieers.com/rpm/packages/dstat/dstat-0.6.7-1.rh7.rf.noarch.rpm rpm -ivh dstat-0.6.7-1.rh7.rf.noarch.rpm 使用说明\r安装完后就可以使用了, dstat 非常强大, 可以实时的监控 cpu、磁盘、网络、IO、内存等使用情况\n直接使用 dstat, 默认使用的是 -cdngy 参数, 分别显示 cpu、disk、net、page、system 信息, 默认是 1s 显示一条信息。可以在后指定显示一条信息的时间间隔, 如 dstat 5 是没 5s 显示一条, dstat 5 10 表示每 5s 显示一条, 一共显示 10 条\n[root@iZ23uulau1tZ ~]# dstat ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 0 0 99 0 0 0|7706B 164k| 0 0 | 0 0 | 189 225 0 0 100 0 0 0| 0 0 |4436B 826B| 0 0 | 195 248 1 0 99 0 0 0| 0 0 |4744B 346B| 0 0 | 203 242 0 0 100 0 0 0| 0 0 |5080B 346B| 0 0 | 206 242 0 1 99 0 0 0| 0 0 |5458B 444B| 0 0 | 214 244 1 0 99 0 0 0| 0 0 |5080B 346B| 0 0 | 208 242 下面对显示出来的部分信息作一些说明\ncpu: hiq、siq 分别为硬中断和软中断次数 system: int、csw 分别为系统的中断次数 (interrupt) 和上下文切换 (context switch) 其他的都很好理解\n语法\rdstat [-afv] [options..] [delay [count]] 常用选项\r-c: 显示CPU系统占用, 用户占用, 空闲, 等待, 中断, 软件中断等信息。 -C: 当有多个CPU时候, 此参数可按需分别显示cpu状态, 例: -C 0,1 是显示cpu0和cpu1的信息。 -d: 显示磁盘读写数据大小。 -D hda,total: include hda and total。 -n: 显示网络状态。 -N eth1,total: 有多块网卡时, 指定要显示的网卡。 -l: 显示系统负载情况。 -m: 显示内存使用情况。 -g: 显示页面使用情况。 -p: 显示进程状态。 -s: 显示交换分区使用情况。 -S: 类似D/N。 -r: I/O请求情况。 -y: 系统状态。 --ipc: 显示ipc消息队列, 信号等信息。 --socket: 用来显示tcp udp端口状态。 -a: 此为默认选项, 等同于-cdngy。 -v: 等同于 -pmgdsc -D total。 --output 文件: 此选项也比较有用, 可以把状态信息以csv的格式重定向到指定的文件中, 以便日后查看。例: dstat --output /root/dstat.csv \u0026amp; 此时让程序默默的在后台运行并把结果输出到/root/dstat.csv文件中。 当然 dstat 还有很多更高级的用法, 常用的基本这些选项, 更高级的用法可以结合 man 文档。\n实例\r如想监控 swap, process, sockets, filesystem 并显示监控的时间\n[root@iZ23uulau1tZ ~]# dstat -tsp --socket --fs ----system---- ----swap--- ---procs--- ------sockets------ --filesystem- date/time | used free|run blk new|tot tcp udp raw frg|files inodes 26-07 09:23:48| 0 0 | 0 0 0.0|104 8 5 0 0| 704 6488 26-07 09:23:49| 0 0 | 0 0 0|104 8 5 0 0| 704 6488 26-07 09:23:50| 0 0 | 0 0 0|104 8 5 0 0| 704 6489 26-07 09:23:51| 0 0 | 0 0 0|104 8 5 0 0| 704 6489 26-07 09:23:52| 0 0 | 0 0 0|104 8 5 0 0| 704 6489 26-07 09:23:53| 0 0 | 0 0 0|104 8 5 0 0| 704 6489 若要将结果输出到文件可以加 --output filename\n[root@iZ23uulau1tZ ~]# dstat -tsp --socket --fs --output /tmp/ds.csv ----system---- ----swap--- ---procs--- ------sockets------ --filesystem- date/time | used free|run blk new|tot tcp udp raw frg|files inodes 26-07 09:25:31| 0 0 | 0 0 0.0|104 8 5 0 0| 736 6493 26-07 09:25:32| 0 0 | 0 0 0|104 8 5 0 0| 736 6493 26-07 09:25:33| 0 0 | 0 0 0|104 8 5 0 0| 736 6493 26-07 09:25:34| 0 0 | 0 0 0|104 8 5 0 0| 736 6493 26-07 09:25:35| 0 0 | 0 0 0|104 8 5 0 0| 736 6494 26-07 09:25:36| 0 0 | 0 0 0|104 8 5 0 0| 736 6494 这样生成的 csv 文件可以用 excel 打开, 然后生成图表\n通过 dstat --list 可以查看 dstat 能使用的所有参数, 其中上面 internal 是 dstat 本身自带的一些监控参数, 下面 /usr/share/dstat 中是dstat的插件, 这些插件可以扩展 dstat 的功能, 如可以监控电源 (battery)、mysql 等。\n下面这些插件并不是都可以直接使用的, 有的还依赖其他包, 如想监控 mysql, 必须要装 python 连接 mysql 的一些包\n[root@iZ23uulau1tZ ~]# dstat --list internal: aio, cpu, cpu24, disk, disk24, disk24old, epoch, fs, int, int24, io, ipc, load, lock, mem, net, page, page24, proc, raw, socket, swap, swapold, sys, tcp, time, udp, unix, vm /usr/share/dstat: battery, battery-remain, cpufreq, dbus, disk-util, fan, freespace, gpfs, gpfs-ops, helloworld, innodb-buffer, innodb-io, innodb-ops, lustre, memcache-hits, mysql-io, mysql-keys, mysql5-cmds, mysql5-conn, mysql5-io, mysql5-keys, net-packets, nfs3, nfs3-ops, nfsd3, nfsd3-ops, ntp, postfix, power, proc-count, rpc, rpcd, sendmail, snooze, thermal, top-bio, top-cpu, top-cputime, top-cputime-avg, top-io, top-latency, top-latency-avg, top-mem, top-oom, utmp, vm-memctl, vmk-hba, vmk-int, vmk-nic, vz-cpu, vz-io, vz-ubc, wifi 原文\nhttp://man.linuxde.net/dstat\n","date":"2017-12-21T17:42:00+08:00","permalink":"https://blog.acesheep.com/p/dstat-command-guide/","title":"dstat 命令详解"},{"content":"系统环境准备\r系统平台: CentOS Linux release 7.4.1708 (Core) Samba版本: samba.x86_64 4.4.4-14.el7_3 Samba Server IP: 192.168.126.15 配置防火墙 (CentOS 7 默认使用 firewalld ) 配置 SELinux # 查看系统信息 [root@localhost ~]# cat /etc/redhat-release # 查看 yum 源中 SAMBA 版本 [root@localhost ~]# yum list | grep samba # 临时关闭SeLinux [root@localhost ~]# setenforce 0 安装 Samba 服务\ryum install samba samba-client samba-common 1、安装包说明\nrpm -qa | grep samba samba-common-3.5.10-125.el6.x86_64 # 主要提供 samba 服务器的设置文件与设置文件语法检验程序 testparm samba-client-3.5.10-125.el6.x86_64 # 客户端软件, 主要提供 linux 主机作为客户端时, 所需要的工具指令集 samba-swat-3.5.10-125.el6.x86_64 # 基于 https 协议的 samba 服务器 web 配置界面 samba-3.5.10-125.el6.x86_64 # 服务器端软件, 主要提供 samba 服务器的守护程序, 共享文档, 日志的轮替, 开机默认选项 Samba 服务器安装完毕, 会生成配置文件目录 /etc/samba, /etc/samba/smb.conf 是 samba 的核心配置文件。\nSamba 安装好后, 使用 testparm 命令可以测试 smb.conf 配置是否正确。使用 testparm -v 命令可以详细的列出 smb.conf 支持的配置参数。\n配置 Samba 服务\rSamba 的主配置文件为 /etc/samba/smb.conf\n默认的 smb.conf 有很多个选项和内容, 比较繁琐, 这里我们按照案例来讲解配置选项, 先备份一下自己的 smb.conf 文件, 然后重新建立一个 smb.conf\ncp -p /etc/samba/smb.conf /etc/samba/smb.conf.bak 配置如下\n[global] workgroup = WORKGROUP server string = AceSheepSsmba hosts allow = 127. 192.168.10. max connections = 40 log file = /var/log/samba/log.%m max log size = 3072 security = user passdb backend = tdbsam load printers = no [名称] comment = 注释. path = /mnt/xfs/sda/ 挂载点 guest ok = no admin users = xxx valid users = @xxx writable = yes create mask = 0644 directory mask = 0750 测试是否配置成功\n# 重启 smb 服务器 systemctl restart smb # 设置开机启动 systemctl enable smb 主配置文件由两部分构成\nGlobal Settings (55-245行) - 该设置都是与 Samba 服务整体运行环境有关的选项, 它的设置项目是针对所有共享资源的\nShare Definitions (246-尾行) - 该设置针对的是共享目录个别的设置, 只对当前的共享资源起作用\nGlobal Settings\r[global]\nconfig file = /usr/local/samba/lib/smb.conf.%m\n说明: config file可以让你使用另一个配置文件来覆盖缺省的配置文件。如果文件不存在, 则该项无效。这个参数很有用, 可以使得samba配置更灵活, 可以让一台 samba服务器模拟多台不同配置的服务器。比如, 你想让PC1 (主机名) 这台电脑在访问Samba Server时使用它自己的配置文件, 那么先在/etc/samba/host/下为PC1配置一个名为smb.conf.pc1的文件, 然后在 smb.conf中加入: config file = /etc/samba/host/smb.conf.%m。这样当PC1请求连接Samba Server时, smb.conf.%m就被替换成smb.conf.pc1。这样, 对于PC1来说, 它所使用的Samba服务就是由 smb.conf.pc1定义的, 而其他机器访问Samba Server则还是应用smb.conf。\nworkgroup = WORKGROUP\n说明: 设定 Samba Server 所要加入的工作组或者域。\nserver string = Samba Server Version %v\n说明: 设定 Samba Server 的注释, 可以是任何字符串, 也可以不填。宏%v表示显示Samba的版本号。\nnetbios name = smbserver\n说明: 设置Samba Server的NetBIOS名称。如果不填, 则默认会使用该服务器的DNS名称的第一部分。netbios name和workgroup名字不要设置成一样了。\ninterfaces = lo eth0 192.168.12.2/24 192.168.13.2/24\n说明: 设置Samba Server监听哪些网卡, 可以写网卡名, 也可以写该网卡的IP地址。\nhosts allow = 127. 192.168.1. 192.168.10.1\n说明: 表示允许连接到Samba Server的客户端, 多个参数以空格隔开。可以用一个IP表示, 也可以用一个网段表示。hosts deny 与hosts allow 刚好相反。\n例如: hosts allow=172.17.2.EXCEPT172.17.2.50\n表示容许来自172.17.2.*的主机连接, 但排除172.17.2.50\nhosts allow=172.17.2.0/255.255.0.0\n表示容许来自172.17.2.0/255.255.0.0子网中的所有主机连接\nhosts allow=M1, M2\n表示容许来自M1和M2两台计算机连接\nhosts allow=@pega\n表示容许来自pega网域的所有计算机连接\nmax connections = 0\n说明: max connections用来指定连接Samba Server的最大连接数目。如果超出连接数目, 则新的连接请求将被拒绝。0表示不限制。\ndeadtime = 0\n说明: deadtime用来设置断掉一个没有打开任何文件的连接的时间。单位是分钟, 0代表Samba Server不自动切断任何连接。\ntime server = yes/no\n说明: time server用来设置让nmdb成为windows客户端的时间服务器。\nlog file = /var/log/samba/log.%m\n说明: 设置Samba Server日志文件的存储位置以及日志文件名称。在文件名后加个宏%m (主机名), 表示对每台访问Samba Server的机器都单独记录一个日志文件。如果pc1、pc2访问过Samba Server, 就会在/var/log/samba目录下留下log.pc1和log.pc2两个日志文件。\nmax log size = 50\n说明: 设置Samba Server日志文件的最大容量, 单位为kB, 0代表不限制。\nsecurity = user\n说明: 设置用户访问Samba Server的验证方式, 一共有四种验证方式。\nshare: 用户访问Samba Server不需要提供用户名和口令, 安全性能较低。 user: Samba Server共享目录只能被授权的用户访问,由Samba Server负责检查账号和密码的正确性。账号和密码要在本Samba Server中建立。 server: 依靠其他Windows NT/2000或Samba Server来验证用户的账号和密码,是一种代理验证。此种安全模式下,系统管理员可以把所有的Windows用户和口令集中到一个NT系统上,使用 Windows NT进行Samba认证, 远程服务器可以自动认证全部用户和口令,如果认证失败,Samba将使用用户级安全模式作为替代的方式。 domain: 域安全级别,使用主域控制器(PDC)来完成认证。 passdb backend = tdbsam\n说明: passdb backend就是用户后台的意思。目前有三种后台: smbpasswd、tdbsam和ldapsam。sam应该是security account manager (安全账户管理) 的简写。\n1.smbpasswd: 该方式是使用smb自己的工具smbpasswd来给系统用户 (真实用户或者虚拟用户) 设置一个Samba密码, 客户端就用这个密码来访问Samba的资源。smbpasswd文件默认在/etc/samba目录下, 不过有时候要手工建立该文件。\n2.tdbsam: 该方式则是使用一个数据库文件来建立用户数据库。数据库文件叫passdb.tdb, 默认在/etc/samba目录下。passdb.tdb用户数据库 可以使用smbpasswd -a来建立Samba用户, 不过要建立的Samba用户必须先是系统用户。我们也可以使用pdbedit命令来建立Samba账户。pdbedit命令的 参数很多, 我们列出几个主要的。\npdbedit -a username: 新建Samba账户。\npdbedit -x username: 删除Samba账户。\npdbedit -L: 列出Samba用户列表, 读取passdb.tdb数据库文件。\npdbedit -Lv: 列出Samba用户列表的详细信息。\npdbedit -c \u0026ldquo;[D]\u0026rdquo; -u username: 暂停该Samba用户的账号。\npdbedit -c \u0026ldquo;[]\u0026rdquo; -u username: 恢复该Samba用户的账号。\n3.ldapsam: 该方式则是基于LDAP的账户管理方式来验证用户。首先要建立LDAP服务, 然后设置 \u0026ldquo;passdb backend = ldapsam:ldap://LDAP Server\u0026rdquo;\nencrypt passwords = yes/no\n说明: 是否将认证密码加密。因为现在windows操作系统都是使用加密密码, 所以一般要开启此项。不过配置文件默认已开启。\nsmb passwd file = /etc/samba/smbpasswd\n说明: 用来定义samba用户的密码文件。smbpasswd文件如果没有那就要手工新建。\nusername map = /etc/samba/smbusers\n说明: 用来定义用户名映射, 比如可以将root换成administrator、admin等。不过要事先在smbusers文件中定义好。比如: root = administrator admin, 这样就可以用administrator或admin这两个用户来代替root登陆Samba Server, 更贴近windows用户的习惯。\nguest account = nobody\n说明: 用来设置guest用户名。\nsocket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192\n说明: 用来设置服务器和客户端之间会话的Socket选项, 可以优化传输速度。\ndomain master = yes/no\n说明: 设置Samba服务器是否要成为网域主浏览器, 网域主浏览器可以管理跨子网域的浏览服务。\nlocal master = yes/no\n说明: local master用来指定Samba Server是否试图成为本地网域主浏览器。如果设为no, 则永远不会成为本地网域主浏览器。但是即使设置为yes, 也不等于该Samba Server就能成为主浏览器, 还需要参加选举。\npreferred master = yes/no\n说明: 设置Samba Server一开机就强迫进行主浏览器选举, 可以提高Samba Server成为本地网域主浏览器的机会。如果该参数指定为yes时, 最好把domain master也指定为yes。使用该参数时要注意: 如果在本Samba Server所在的子网有其他的机器 (不论是windows NT还是其他Samba Server) 也指定为首要主浏览器时, 那么这些机器将会因为争夺主浏览器而在网络上大发广播, 影响网络性能。\n如果同一个区域内有多台Samba Server, 将上面三个参数设定在一台即可。\nos level = 200\n说明: 设置samba服务器的os level。该参数决定Samba Server是否有机会成为本地网域的主浏览器。os level从0到255, winNT的os level是32, win95/98的os level是1。Windows 2000的os level是64。如果设置为0, 则意味着Samba Server将失去浏览选择。如果想让Samba Server成为PDC, 那么将它的os level值设大些。\ndomain logons = yes/no\n说明: 设置Samba Server是否要做为本地域控制器。主域控制器和备份域控制器都需要开启此项。\nlogon script = %u.bat\n说明: 当使用者用windows客户端登陆, 那么Samba将提供一个登陆档。如果设置成%u.bat, 那么就要为每个用户提供一个登陆档。如果人比较多, 那就比较麻烦。可以设置成一个具体的文件名, 比如start.bat, 那么用户登陆后都会去执行start.bat, 而不用为每个用户设定一个登陆档了。 这个文件要放置在[netlogon]的path设置的目录路径下。\nwins support = yes/no\n说明: 设置samba服务器是否提供wins服务。\nwins server = wins服务器IP地址\n说明: 设置Samba Server是否使用别的wins服务器提供wins服务。\nwins proxy = yes/no\n说明: 设置Samba Server是否开启wins代理服务。\ndns proxy = yes/no\n说明: 设置Samba Server是否开启dns代理服务。\nload printers = yes/no\n说明: 设置是否在启动Samba时就共享打印机。\nprintcap name = cups\n说明: 设置共享打印机的配置文件。\nprinting = cups\n说明: 设置Samba共享打印机的类型。现在支持的打印系统有: bsd, sysv, plp, lprng, aix, hpux, qnx\nShare Definitions\r[共享名]\ncomment = 任意字符串 可以是中文\n说明: comment是对该共享的描述, 可以是任意字符串。\npath = 共享目录路径\n说明: path用来指定共享目录的路径。可以用%u、%m这样的宏来代替路径里的unix用户和客户机的Netbios名, 用宏表示主要用于[homes] 共享域。例如: 如果我们不打算用home段做为客户的共享, 而是在/home/share/下为每个Linux用户以他的用户名建个目录, 作为他的共享目 录, 这样path就可以写成: path = /home/share/%u; 。用户在连接到这共享时具体的路径会被他的用户名代替, 要注意这个用户名路径一定要存在, 否则, 客户机在访问时会找不到网络路径。同样, 如果我们不是以用 户来划分目录, 而是以客户机来划分目录, 为网络上每台可以访问samba的机器都各自建个以它的netbios名的路径, 作为不同机器的共享资源, 就可以 这样写: path = /home/share/%m 。\nbrowseable = yes/no\n说明: browseable用来指定该共享是否可以浏览。\nwritable = yes/no\n说明: writable用来指定该共享路径是否可写。\navailable = yes/no\n说明: available用来指定该共享资源是否可用。\nadmin users = 该共享的管理者\n说明: admin users用来指定该共享的管理员 (对该共享具有完全控制权限)。在samba 3.0中, 如果用户验证方式设置成 \u0026ldquo;security=share\u0026rdquo; 时, 此项无效。\n例如: admin users =david, sandy (多个用户中间用逗号隔开)。\nvalid users = 允许访问该共享的用户\n说明: valid users用来指定允许访问该共享资源的用户。\n例如: valid users = david, @dave, @tech (多个用户或者组中间用逗号隔开, 如果要加入一个组就用 \u0026ldquo;@组名\u0026rdquo; 表示。)\ninvalid users = 禁止访问该共享的用户\n说明: invalid users用来指定不允许访问该共享资源的用户。\n例如: invalid users = root, @bob (多个用户或者组中间用逗号隔开。)\nwrite list = 允许写入该共享的用户\n说明: write list用来指定可以在该共享下写入文件的用户。\n例如: write list = david, @dave\npublic = yes/no\n说明: public用来指定该共享是否允许guest账户访问。\nguest ok = yes/no\n说明: 意义同 \u0026ldquo;public\u0026rdquo;。\n几个特殊共享:\n[homes] comment = Home Directories browseable = no writable = yes valid users = %S ; valid users = MYDOMAIN\\%S [printers] comment = All Printers path = /var/spool/samba browseable = no guest ok = no writable = no printable = yes [netlogon] comment = Network Logon Service path = /var/lib/samba/netlogon guest ok = yes writable = no share modes = no [Profiles] path = /var/lib/samba/profiles browseable = no guest ok = yes 向 SMB 服务器添加用户, 并设置密码\r# 新建 Samba 账户 smbpasswd -a \u0026lt;username\u0026gt; smbpasswd 命令详解\rsmbpasswd (选项) (用户名: 指定要修改SMB密码的用户。) -a: 向smbpasswd文件中添加用户； -c: 指定samba的配置文件； -x: 从smbpasswd文件中删除用户； -d: 在smbpasswd文件中禁用指定的用户； -e: 在smbpasswd文件中激活指定的用户； -n: 将指定的用户的密码置空。 设置防火墙\r使用新的防火墙 firewall 添加就可以, 比 iptables 更方便\nfirewall-cmd --list-services firewall-cmd --permanent --add-service=samba firewall-cmd --reload firewall-cmd --list-services 要注意的地方\n由于 redhat 7 开始, iptables 被 firewalld 代替了, 所以使用 firewalld 的方法\n关于 firewalld 的说明, 可以看 fedora 官网介绍 FirewallD/zh-cn\nLinux 中 /etc/passwd 里的用户和 Samba 里的用户几乎没啥关系, 硬说有的话, 那就是: Samba 的所有用户都必须是系统里已存在的用户。我们要授权系统用户访问 Samba 的话, 通过命令:\n# 添加用户 koorey 到 Samba 用户数据库中 smbpasswd -a koorey 这条命令输入完后, 会提示为新建的用户 koorey 设置访问密码。\n最后再执行一下 systemctl restart smb 命令就OK了。\n至此, Samba 服务器就架设好了。\n不信？为啥？因为后面还有章节, 哈哈, 说的没错。\n理论上说确实已经架设好了, 可千万不要忽略了 CentOS 7 的安全机制的存在: iptables 和 SELinux\n其中本人就吃了 SELinux 不少苦头。因为只弄了iptables, 却忘记了 SELinux 这个牛叉叉的家伙。\n关于 iptables 本人会在后面的博客从头到脚, 从里到外, 循序渐进的以此和大家交待它的来龙去脉。\n当然, 如果你感兴趣的话。\n在对待 iptables 的问题上\r普通青年: 直接在命令行敲…\nservice iptables stop 文艺青年: 依次在命令行敲…\niptables -I RH-Firewall-1-INPUT 5 -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT iptables -I RH-Firewall-1-INPUT 5 -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT iptables -I RH-Firewall-1-INPUT 5 -p udp -m udp --dport 137 -j ACCEPT iptables -I RH-Firewall-1-INPUT 5 -p udp -m udp --dport 138-j ACCEPT iptables-save service iptables restart SELinux 设置\rgetsebool -a | grep samba setsebool -P samba_enable_home_dirs on 在对待 SELinux 的问题上\r普通青年: 直接在命令行敲…\nsetenforce 0 vi /etc/selinux/config 文艺青年: 依次在命令行敲…\nsetsebool -P samba_enable_home_dirs on setsebool -P samba_export_all_rw on 完事儿之后再: getsebool -a | grep samba 一把, 你懂得…\n最后在 Windows 系统里 iOS 手机 Mac 测试成功, 访问正常! 收工啦!!\n原文\nCentOS 7下Samba服务器的安装与配置\nLinux下最完整的Samba服务器配置攻略\n","date":"2017-12-21T02:03:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-samba-server-setup/","title":"CentOS 7 下 Samba 服务器的安装与配置 | SMB"},{"content":"CentOS 7 下想要挂载 NTFS 的文件系统该怎么办呢? 我们需要一个 NTFS-3G 工具, 并编译它之后在 mount 就可以了, 就这么简单\n首先要进入官网下载 NTFS-3G 工具\nhttps://www.tuxera.com/community/open-source-ntfs-3g/\ngithub.com/tuxera/ntfs-3g\n下载之后进行解压\rwget https://tuxera.com/opensource/ntfs-3g_ntfsprogs-2017.3.23.tgz tar -xvf ntfs-3g_ntfsprogs-2017.3.23.tgz 编译并进行安装\r进入 ntfs-3g_ntfsprogs-2017.3.23 文件夹中\n./configure make make install # or \u0026#39;sudo make install\u0026#39; if you aren\u0026#39;t root 如果提示没有 gcc, 则 yum install gcc* 将编译环境安装好在执行一次上面的命令\n挂载 NTFS\rmount -t ntfs-3g /dev/sda2 /mnt/Windows mount 重启之后就会失效\nCentOS 7 开机自动挂载 NTFS\rvim /etc/fstab # \u0026lt;file system\u0026gt; \u0026lt;mount point\u0026gt; \u0026lt;type\u0026gt; \u0026lt;options\u0026gt; \u0026lt;dump\u0026gt; \u0026lt;pass\u0026gt; # 在结尾添加 /dev/sda1 /mnt/windows ntfs-3g defaults 0 0 常见参数如下:\nauto: 系统自动挂载, fstab 默认就是这个选项 defaults: rw, suid, dev, exec, auto, nouser, and async. noauto 开机不自动挂载 nouser 只有超级用户可以挂载 ro 按只读权限挂载 rw 按可读可写权限挂载 user 任何用户都可以挂载 请注意光驱和软驱只有在装有介质时才可以进行挂载, 因此它是 noauto 原文\nTuxera NTFS-3G\n","date":"2017-12-17T15:53:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-mount-ntfs-file-system/","title":"CentOS 7 下挂载 NTFS 文件系统 开机自动挂载"},{"content":"grep 命令简介\rgrep 是一个最初用于 Unix 操作系统的命令行工具。在给出文件列表或标准输入后, grep 会对匹配一个或多个正则表达式的文本进行搜索, 并只输出匹配 (或者不匹配) 的行或文本。\ngrep 可根据提供的匹配模式列表, 查询文件中的匹配行. 发现匹配行后, 行内容会被标准输出 (默认), 如果使用了其它参数, 可以产生其它格式的输出\ngrep 用于匹配文本, 它对输入行的长度没有限制, 除非受限于可用内存大小, 并且可以匹配行内任意字符\n使用方法\rgrep -[acinv] \u0026#39;搜索内容串\u0026#39; filename 常用参数选项\n选项 含义 -c 计算找到的符合行的次数 -i 忽略大小写 -n 显示匹配行及行号 -v 找到没有搜索字符串的行 -h 查询多文件时不显示文件名 -l 查询多文件时只输出包含匹配字符的文件名 -s 不显示不存在或无匹配文本的错误信息 实际使用举例\r搜索日志, 查询有多少条 503 错误\ngrep -c \u0026#39;503\u0026#39; /var/log/httpd/error_log-20141116 搜索含有 error 字样的行, 并且输出行号\ngrep -n \u0026#39;error\u0026#39; /var/log/httpd/error_log-20141116 搜索没有 error 字样的行, 并且输出行号\ngrep -nv \u0026#39;error\u0026#39; /var/log/httpd/error_log-20141116 搜索寻找安装的软件版本有几个\n# centos 下查看安装的 Python 版本 rpm -qa | grep -i python # Ubuntu 下查看安装的 Python 版本 sudo dpkg -l | grep -i python 过滤配置文件的注释符号#\n#匹配 # 符号的行, 但是输出的是 # 符号以外的行 grep -v \u0026#39;#\u0026#39; /etc/httpd/conf/httpd.conf 查询每个网卡和IP地址\nifconfig | grep -n inet 忽略大小写搜索 (-i)\ngrep -i \u0026#34;ErroR\u0026#34; log.txt 所有子目录下的搜索 (-r)\ngrep -r \u0026#34;exception\u0026#34; log.txt 精准全匹配搜索 (-w)\ngrep -w \u0026#34;boo\u0026#34; /path/to/file 精准全字匹配搜索两个不同单词\ngrep -w \u0026#39;word1|word2\u0026#39; /path/to/file 统计字符串出现的次数 (-c) grep -c \u0026#39;word\u0026#39; /path/to/file # -n 的话, 会在结果中, 列出匹配字符串的序列号, 并且会列出内容 grep -n \u0026#39;word\u0026#39; /path/to/file 只列出文件名 (-l) grep -l \u0026#39;main\u0026#39; *.pls 高亮显示搜索结果 (-color) grep --color apache /etc/passwd grep 正则表达式元字符集整理\rERE 和 BRE\r简称 全称 解释 BRE basic regular expressions 基础正则表达式 (过时的) ERE extended regular expressions 扩展正则表达式 (现代的) 如果从字面理解, 基础这个字眼让 BRE 显得具有一定地位, 但实质上 BRE 的存在只是为了兼容一些老旧的软件。\nGNU grep 对 BRE 和 ERE 进行了扩展, 使得它们之间的差别很小, 那就是转义字符的使用:\n? + | { } ( ) \\? \\+ \\| \\{ \\} \\( \\) BRE 中前者表示字面量, 后者具有特殊含义。而 ERE 则相反, 前者具有特殊含义, 后者表示字面量。例如列出文件名以 config 或者 conf 或者 cfg 结尾的文件\n# 使用 ERE ls -a | grep -E \u0026#39;(config|conf|cfg)$\u0026#39; # 使用 BRE ls -a | grep \u0026#39;\\(config\\|conf\\|cfg\\)$\u0026#39; 推荐使用 ERE\rERE 的风格被现代应用程序广泛支持, 推荐使用 ERE\ngrep 默认使用 BRE, grep -E 或者 egrep 使用 ERE\nsed 默认使用 BRE, sed -E 使用 ERE\ngawk 使用 ERE\negrep 等同于 grep -E, 下文将统一使用 egrep\ngrep 适用的正则表达式\n符号 含义 ^ 锚定行的开始 如: ^grep 匹配所有以 grep 开头的行 $ 锚定行的结束 如: grep$ 匹配所有以 grep 结尾的行 . 匹配一个非换行符的字符 如: gr.p 匹配 gr 后接一个任意字符, 然后是 p * 匹配零个或多个先前字符 如: *grep 匹配所有一个或多个空格后紧跟 grep 的行 [] 匹配一个指定范围内的字符, 如 [Gg]rep 匹配 Grep 和 grep [^] 匹配一个不在指定范围内的字符, 如: [^A-FH-Z]rep 匹配不包含 A-R 和 T-Z 的一个字母开头, 紧跟 rep 的行 .* 一起用代表任意字符 \\(..\\) 标记匹配字符, 如 \\(love\\), love 被标记为 1 \\\u0026lt;word 以某单词开头 (GNU 扩展) word\\\u0026gt; 以某单词结尾 (GNU 扩展) x\\{m\\} 重复字符 x, m 次, 如: o\\{5\\} 匹配包含 5 个 o 的行 x\\{m,\\} 重复字符 x, 至少 m 次, 如: o\\{5,\\} 匹配至少有 5 个 o 的行 x\\{m,n\\} 重复字符 x, 至少 m 次, 不多于 n 次, 如: o\\{5,10\\} 匹配 5 - 10 个 o 的行 \\w 匹配文字和数字字符 \\b 匹配单词的开始或结束, 匹配单词边缘。(GNU 扩展), 如: \\bgrep\\b 只匹配 grep 原文\nhttps://www.cnblogs.com/nonghu/p/6328595.html\n","date":"2017-12-15T13:22:00+08:00","permalink":"https://blog.acesheep.com/p/linux-grep-command-guide/","title":"Linux grep 命令"},{"content":" useradd testuser 创建的用户 testuser 说明: 新创建的用户会在 /home 下创建一个用户目录 testuser passwd testuser 给已创建的用户 testuser 设置密码 usermod \u0026ndash;help 修改用户这个命令的相关参数 userdel testuser 删除用户 testuser 创建用户 useradd\r作用 useradd 或 adduser 命令用来建立用户帐号和创建用户的起始目录, 使用权限是超级用户。\n格式 useradd [-d home] [-s shell] [-c comment] [-m [-k template]] [-f inactive] [-e expire ] [-p passwd] [-r] name 主要参数 -c: 加上备注文字, 备注文字保存在 passwd 的备注栏中 -d: 指定用户登入时的主目录, 替换系统默认值 /home/\u0026lt;用户名\u0026gt; -D: 变更预设值 -e: 指定账号的失效日期, 日期格式为 MM/DD/YY, 例如 06/30/12。缺省表示永久有效 -f: 指定在密码过期后多少天即关闭该账号。如果为 0 账号立即被停用；如果为 -1 则账号一直可用。默认值为 -1 -g: 指定用户所属的群组。值可以使组名也可以是 GID。用户组必须已经存在的, 期默认值为 100, 即 users -G: 指定用户所属的附加群组 -m: 自动建立用户的登入目录 -M: 不要自动建立用户的登入目录 -n: 取消建立以用户名称为名的群组 -r: 建立系统账号 -s: 指定用户登入后所使用的 shell。默认值为 /bin/bash -u: 指定用户 ID 号。该值在系统中必须是唯一的。0~499 默认是保留给系统用户账号使用的, 所以该值必须大于 499 应用实例 建立一个新用户账户 testuser1, 并设置 uid 为 544, 主目录为 /usr/testuser1, 属于 users 组\nuseradd -u 544 -d /usr/testuser1 -g users -m testuser1 加 -m 如果主目录不存在则自动创建\n例子 使用管理员账号登陆系统, 建立用户 tmp_3452 密码 3sdt5:Eawhg\n# 添加用户命令 adduser tmp_3452 # 修改密码命令 passwd tmp_3452 在系统出现提示输入密码是输入密码: 3sdt5:Eawhg 系统提示输入确认密码后再输入一次。OK 添加成功。\nuseradd 批量添加用户\r使用 useradd 时, 如果后面不添加任何参数选项, 例如: sudo useradd test 创建出来的用户将是默认 三无 用户: 一无 Home Directory, 二无密码, 三无系统 Shell\n步骤如下\n建立用户名列表文件 username.txt\n创建用户密码对应文件 serc.txt, 格式为 username:password\nstu1:tt1 stu2:tt2 stu3:tt3 stu4:tt4 stu5:tt5 stu6:tt6 批量添加的脚本文件 batch_useradd.sh # 添加用户, 并且在 /home/ 下为用户生成用户目录 # 批处理模式下更新密码 cat \u0026lt; username.txt | xargs -n 1 useradd -m # 将上述的密码转换到密码文件和组文件 chpasswd \u0026lt; serc.txt # 结束验证信息 pwconv echo \u0026#34;OK 新建完成\u0026#34; 执行该脚本文件, 查看执行过程 sh batch_useradd.sh 新建完成 useradd 命令, 在执行没有出错的情况下, 不会输出任何的信息, 不会与用户交互。\n但是用户必须要记住那些设置项目, 否则添加的用户可能出现一些预想不到的结果。\n创建用户并设置密码\nadduser ${ANUSER} -m echo \u0026#34;${ANUSER}:${ANPASS}\u0026#34; | chpasswd # 快速修改root 密码, 忽略密码规则 echo root:abc123 | sudo chpasswd root 修改用户 usermod\r新创建一个 oracle 用户, 这初始属于 oinstall 组, 且同时让他也属于 dba 组\nuseradd oracle -g oinstall -G dba 将一个用户添加到用户组中, 千万不能直接用. 这样做会使你离开其他用户组, 仅仅做为 这个用户组 sftp 的成员\nusermod -G sftp 将用户 docker 加入到 sftp 组, 用户和组均存在\nusermod -a -G sftp docker 创建用户 tomcat 使其无法使用 shell, 且其用户目录至 /var/servlet/service\nuseradd tomcat -d /var/servlet/service -s /sbin/nologin 禁止登录系统,要修改一个已经存在的用户, 执行这个命令\nusermod -s /sbin/nologin \u0026lt;username\u0026gt; 对新用户, 可以使用这个命令\nuseradd -s /sbin/nologin \u0026lt;new username\u0026gt; /bin/false 是最严格的禁止 login 选项, 一切服务都不能用。而 /sbin/nologin 只是不允许 login 系统, 但可以使用其他 ftp 等服务。\nAccess to the server over SSH: /bin/sh /bin/bash /sbin/nologin /bin/tcsh /bin/csh /bin/ksh /bin/bash (chrooted) /bin/rbash 删除用户 userdel\r删除刚创建的账号 tmp_3452\n删除用户命令\nuserdel tmp_3452 或者连同用户目录一并删除\nuserdel -f tmp_3452 注意: 这里如果用户还在登陆的话, 会提示 用户正在登陆无法删除。此时可能需要先强制用户退出。\n强制退出已经登陆用户\r查看当前登陆用户的命令\n[root@ptr228 ~]# w 会输入如下结果\n12:10:27 up 21:13, 1 user, load average: 0.00, 0.01, 0.08 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 ***.**.***.** 11:33 0.00s 0.08s 0.00s w tmp_3254 ps1 ***.**.***.** 11:33 0.00s 0.08s 0.00s ls 这里知道了登陆用户的 tty 是 ps1 执行强制退出命令 pkill\n# pkill -kill -t [TTY] [root@ptr228 ~]# pkill -kill -t ps1 执行之后再执行名 w 可以看到用户已经退出。\n重复执行删除用户命令, 删除成功。\n原文\nlinux命令useradd添加用户详解\nWhat is the difference between bin/sh, bin/bash, sbin/nologin, bin/tcsh, etc? [closed]\n","date":"2017-12-15T13:20:00+08:00","permalink":"https://blog.acesheep.com/p/linux-user-management/","title":"Linux 添加用户 修改用户 删除用户 | adduser | useradd | usermod | userdel"},{"content":"yum install hdparm hdparm -Y /dev/sd* # 使硬盘进入睡眠模式 hdparm -y /dev/sd* # 使硬盘进入省电模式 # 设置超时值使硬盘进入睡眠模式 # hdparm -S [value (0..255) 1=5秒] /dev/sd* hdparm -S 180 /dev/sda 唤醒硬盘 hdparm 好像没有相应参数, 实际上你去操作硬盘就会自动唤醒硬盘\n使用 ioctl 有个参数可以唤醒硬盘, 你可以查看硬盘操作的相应头文件。\n具体看 hdparm 的源代码, 实际是使用 ioctl 操作硬盘相应寄存器。\nhdparm 帮助选项\r[root@server ~]# hdparm --help hdparm - get/set hard disk parameters - version v9.43, by Mark Lord. Usage: hdparm [options] [device ...] Options: -a Get/set fs readahead -A Get/set the drive look-ahead flag (0/1) -b Get/set bus state (0 == off, 1 == on, 2 == tristate) -B Set Advanced Power Management setting (1-255) -c Get/set IDE 32-bit IO setting -C Check drive power mode status -d Get/set using_dma flag -D Enable/disable drive defect management -E Set cd/dvd drive speed -f Flush buffer cache for device on exit -F Flush drive write cache -g Display drive geometry -h Display terse usage information -H Read temperature from drive (Hitachi only) -i Display drive identification -I Detailed/current information directly from drive -J Get/set Western DIgital \u0026#34;Idle3\u0026#34; timeout for a WDC \u0026#34;Green\u0026#34; drive (DANGEROUS) -k Get/set keep_settings_over_reset flag (0/1) -K Set drive keep_features_over_reset flag (0/1) -L Set drive doorlock (0/1) (removable harddisks only) -m Get/set multiple sector count -M Get/set acoustic management (0-254, 128: quiet, 254: fast) -n Get/set ignore-write-errors flag (0/1) -N Get/set max visible number of sectors (HPA) (VERY DANGEROUS) -p Set PIO mode on IDE interface chipset (0,1,2,3,4,...) -P Set drive prefetch count -q Change next setting quietly -Q Get/set DMA queue_depth (if supported) -r Get/set device readonly flag (DANGEROUS to set) -R Get/set device write-read-verify flag -s Set power-up in standby flag (0/1) (DANGEROUS) -S Set standby (spindown) timeout -t Perform device read timings -T Perform cache read timings -u Get/set unmaskirq flag (0/1) -U Obsolete -v Use defaults; same as -acdgkmur for IDE drives -V Display program version and exit immediately -w Perform device reset (DANGEROUS) -W Get/set drive write-caching flag (0/1) -x Obsolete -X Set IDE xfer mode (DANGEROUS) -y Put drive in standby mode -Y Put drive to sleep -z Re-read partition table -Z Disable Seagate auto-powersaving mode --dco-freeze Freeze/lock current device configuration until next power cycle --dco-identify Read/dump device configuration identify data --dco-restore Reset device configuration back to factory defaults --direct Use O_DIRECT to bypass page cache for timings --drq-hsm-error Crash system with a \u0026#34;stuck DRQ\u0026#34; error (VERY DANGEROUS) --fallocate Create a file without writing data to disk --fibmap Show device extents (and fragmentation) for a file --fwdownload Download firmware file to drive (EXTREMELY DANGEROUS) --fwdownload-mode3 Download firmware using min-size segments (EXTREMELY DANGEROUS) --fwdownload-mode3-max Download firmware using max-size segments (EXTREMELY DANGEROUS) --fwdownload-mode7 Download firmware using a single segment (EXTREMELY DANGEROUS) --idle-immediate Idle drive immediately --idle-unload Idle immediately and unload heads --Istdin Read identify data from stdin as ASCII hex --Istdout Write identify data to stdout as ASCII hex --make-bad-sector Deliberately corrupt a sector directly on the media (VERY DANGEROUS) --offset use with -t, to begin timings at given offset (in GiB) from start of drive --prefer-ata12 Use 12-byte (instead of 16-byte) SAT commands when possible --read-sector Read and dump (in hex) a sector directly from the media --repair-sector Alias for the --write-sector option (VERY DANGEROUS) --security-help Display help for ATA security commands --trim-sector-ranges Tell SSD firmware to discard unneeded data sectors: lba:count .. --trim-sector-ranges-stdin Same as above, but reads lba:count pairs from stdin --verbose Display extra diagnostics from some commands --write-sector Repair/overwrite a (possibly bad) sector directly on the media (VERY DANGEROUS) ","date":"2017-12-15T12:23:00+08:00","permalink":"https://blog.acesheep.com/p/linux-hard-drive-sleep-mode/","title":"Linux 系统下如何使硬盘进入休眠状态"},{"content":"MBR 分区表支持的磁盘最大容量为 2 TB, GPT 分区表最大支持的磁盘容量为 18 EB, 因此当为容量大于 2 TB的磁盘分区时, 需采用 GPT分区表\nLinux 操作系统, 当磁盘分区形式选用 GPT 时, fdisk 分区工具将无法使用, 需要采用 parted 工具\n# 用 parted 命令对 3TB 硬盘进行分区处理 parted /dev/sdX # 用 gpt 格式可以将 3TB 弄在一个分区里 mklabel gpt # 设置单位为 TB unit TB # 设置为一个主分区, 大小为 3TB, 开始是 0, 结束是 3 mkpart primary 0 3 # 显示设置的分区大小 print # 退出 parted 程序 quit # 用 parted 将分区做好后, 进行格式化操作, 完成后即可挂载使用 mkfs.xfs /dev/sdX1 # 挂载使用 mount /dev/sdX1 /mnt ","date":"2017-12-15T12:21:00+08:00","permalink":"https://blog.acesheep.com/p/linux-partition-and-mount-3tb-hard-drive/","title":"Linux 系统 3TB 以上硬盘如何分区, 格式化后挂载到服务器上"},{"content":"OS Sierra 以上系统\n打开 「Launchpad」 - 「实用工具」 - 「终端」\n你在终端里输入\nsudo spctl --master-disable 输入 password (开机密码), 输完敲回车\n任何来源 就会显示了, 然后勾选你要的选项\n关闭\nsudo spctl --master-enable 输入 password (开机密码), 输完敲回车\n任何来源 就会关闭显示了\n","date":"2017-12-15T09:41:00+08:00","permalink":"https://blog.acesheep.com/p/macos-10.12-allow-apps-from-anywhere/","title":"MacOS 10.12 以上允许任何来源的程序"},{"content":"OpenSSL 是一个开源的第三方库, 它实现了 SSL (Secure SocketLayer) 和 TLS (Transport Layer Security) 协议, 囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议, 并提供丰富的应用程序供测试或其它目的使用。\nlib: 包含了所有的库文件 (例如: libeay32.lib、ssleay32.lib)\ninclude: 包含了所有的头文件 (例如: aes.h、md5.h)\nbin: 包含了测试程序、存储证书和密钥的文件 (*.pem)\n准备条件\r注意: 笔者写博客之时, 这几个软件为最新版本\n在微软网站下载并安装 Visual Studio, 我用的是 2017 Community 版。VS 2017 需要勾选安装 C++ 环境完整安装, 不然会少很多东西\n1.0.2 版本和 1.1.1 版本的编译方式不一样这里分为两种方式\n下载并安装 ActivePerl\n下载地址: http://www.activestate.com/activeperl/downloads ActivePerl 5.24.1 Build 2402 Windows (64-bit, x64) Windows Installer (EXE) 下载并安装 Nasm 汇编器\n将 C:\\Program Files\\NASM 添加到系统环境变量 Path 中, 安装的时候可选。 下载地址: http://www.nasm.us/ nasm-2.13.01-installer-x64.exe 下载并安装 OpenSSL\n下载地址: http://www.openssl.org/ openssl-1.0.2l.tar.gz openssl-1.1.1i.tar.gz 1.0.2 版本\r在完成所有上述步骤, 我们就可以解压缩 OpenSSL 包 (解压至: E:\\openssl-1.0.2l), 在对它进行修改便可以编译了。解压后的目录中有两个文件 INSTALL.W32、INSTALL.W64 需要被关注。打开其中任何一个文件, 你会看到如何编译 OpenSSL 的各个步骤。\n打开 2017 控制台 开始 -\u0026gt; 所有程序 -\u0026gt; Visual Studio 2017 -\u0026gt; x64 Native Tools Command Prompt for VS 2017\n定位到 X:\\openssl-1.0.2l 编译64位的需要用 x64 Native Tools Command Prompt for VS 2017\n编译32位的需要用 x86 Native Tools Command Prompt for VS 2017\n配置编译文件及安装目录, 输入 # 将其安装到 E:\\OpenSSL # perl Configure { VC-WIN32 | VC-WIN64A | VC-WIN64I | VC-CE } # VC-WIN32 | VC-WIN64A 分别对应 x86 和 x64 perl Configure VC-WIN32 --perfix=E:\\OpenSSL # 编译 Win32 perl Configure VC-WIN32 --prefix=E:\\OpenSSL # 编译 Win64 perl Configure VC-WIN64A 搭建编译环境 x86 ms\\do_nasm ms\\do_ms x64 ms\\do_nasm ms\\do_win64a # 对于 64 位编译, 将 msdo_ms 替换成 msdo_win64a 如果没有用第一步的 VS 2017 命令行工具打开, 则需要手动初始化编译环境\n将命令提示符定位到 C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\nx86 输入 vcvars32.bat x64 输入 vcvars64.bat 执行后会显示 Settingenvironment for using Microsoft Visual Studio 2017 x86 tools.\n如果没有这一步, 会提示 nmake 不是内部或外部命令\n编译 OpenSSL 不能同时生成静态库和动态库. 要清空 out32dll 文件夹再生成另外一个\n# 编译动态库 nmake -f ms\\ntdll.mak # 编译静态库 nmake -f ms\\nt.mak 输入命令执行后若最终显示 passed all tests 说明生成的库正确 nmake -f ms\\nt.mak test 输入命令执行后则会在 E:\\OpenSSL 目录下生成 bin、include、lib、ssl 四个文件夹 nmake -f ms\\nt.mak install 注意事项\r以上编译的是 release 库, 若编译 debug 库, 则将以上第 3 步中的 VC-WIN32 改成 debug-VC-WIN32, VC-WIN64A 改成 debug-VC-WIN64A 即可 若生成不带汇编支持的库, 则需将以上第 3 步用 perl Configure VC-WIN64A no-asm --prefix=E:\\OpenSSL\\ 替换即可, 增加 no-asm 选项 E:\\OpenSSL\\openssl-1.0.2l\\tmp32 文件夹下包含相应的汇编文件 1.1.1 版本\r随着新的 1.1.0 版本的发布, 构建过程发生了变化。\n从 1.1.0 开始, 没有 ms\\do_*.bat 文件了。\nx32 compilation on Windows\nperl Configure VC-WIN32 nmake nmake test x64A compilation on Windows\nperl Configure VC-WIN64A no-shared no-capieng --perfix=E:\\openssl-1.1.1i\\build64-static-no-capi # perl Configure VC-WIN64A [no-shared|shared] nmake nmake test # 测试通过修改 makefile 的 INSTALLTOP_dir= 参数设置的有问题 nmake install 注意事项\r其他项目调用编译好的 openssl 的静态库时在 windows 中会遇到这个错误 Windows CAPI library\n因为 openssl 调用了 Windows 的加密库但是你的项目没有添加这个库.\n有两种方式解决这个问题.\n第一种\r项目不需要这个在编译的时候去掉 CAPI engine\n编译 openssl 的时候添加 no-capieng 即可解决\n第二种\r在项目里面添加需要的静态库 crypt32.lib\n项目属性 -\u0026gt; 链接器 -\u0026gt; 输入 -\u0026gt; 附加依赖项 中加入: crypt32.lib\n1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertFreeCertificateContext@4 referenced in function _capi_free_key 1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertGetCertificateContextProperty@16 referenced in function _capi_get_prov_info 1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertOpenStore@20 referenced in function _capi_open_store 1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertFindCertificateInStore@24 referenced in function _capi_find_cert 1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertEnumCertificatesInStore@8 referenced in function _capi_find_cert 1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertCloseStore@8 referenced in function _capi_find_key 1\u0026gt;libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp__CertDuplicateCertificateContext@4 referenced in function _capi_load_ssl_client_cert 奇怪的报错\rNMAKE : fatal error U1073: don\u0026#39;t know how to make \u0026#39;\u0026#34;crypto\\bn\\bn_dh.c\u0026#34;\u0026#39; Stop. NMAKE : fatal error U1077: \u0026#39;\u0026#34;C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX64\\x64\\nmake.exe\u0026#34;\u0026#39; : return code \u0026#39;0x2\u0026#39; Stop. 再执行 nmake 就可以了\n1.0.2 版本原文\nWindows 下编译 OpenSSL\n如何在 Windows 下编译 OpenSSL VS2013\nOpenSSL: Nmake fatal error U1077: \u0026lsquo;ias\u0026rsquo; : return code \u0026lsquo;0x1\u0026rsquo;\n1.1.1 版本原文\nWhy is there no msdo_ms.bat after perl Configure VC-WIN64A?\nCompile OpenSSL 1.1.1 with VS 2017 Statically or Dinamically include removed macros.\nopenssl-1.1.0 - Linker error on Windows\n其他\nhttp://download.videolan.org/pub/pub/videolan/vlc/last/win64/\n","date":"2017-09-21T13:35:00+08:00","permalink":"https://blog.acesheep.com/p/compile-openssl-on-win10/","title":"Win10 下编译 OpenSSL-1.0.2l | OpenSSL-1.1.1i"},{"content":"其实我很早就知道这玩意, 并以以下的方式屏蔽, 最近又有很多人关心, 我就把我的方案公布一下\n在系统的 host 加入如下的东西即可 (即屏蔽掉这些域名)\n1.0.0.1 api.map.baidu.com\r1.0.0.1 ps.map.baidu.com\r1.0.0.1 sv.map.baidu.com\r1.0.0.1 offnavi.map.baidu.com\r1.0.0.1 newvector.map.baidu.com\r1.0.0.1 ulog.imap.baidu.com\r1.0.0.1 newloc.map.n.shifen.com ::2 api.map.baidu.com\r::2 ps.map.baidu.com\r::2 sv.map.baidu.com\r::2 offnavi.map.baidu.com\r::2 newvector.map.baidu.com\r::2 ulog.imap.baidu.com\r::2 newloc.map.n.shifen.com 以上写法会让连接超时等待, 如果你希望连接立即拒绝断开, 那么把 1.0.0.1 改为 0.0.0.0, 把 ::2 改为 :: 即可\n如果你使用代理, 那么在代理服务器及本地都最好设置一下\n原文\n如何以最暴力的方式防止百度定位泄露真实位置\n","date":"2017-07-28T13:35:00+08:00","permalink":"https://blog.acesheep.com/p/prevent-baidu-location-leakage-aggressively/","title":"如何以最暴力的方式防止百度定位泄露真实位置"},{"content":"ffmpeg 用 x264 视频编码, 视频画面会出现锯齿 (或者叫拉丝), 下面两张图对比一下效果\n导致此效果的原因是录制设备使用的是 1080i 隔行扫描, 问题在于这个隔行扫描造成的\n在一些相机设置里我们也能看到隔行扫描的选项, 比如这里的 1080p 和 1080i, 其中 p (progressive) 就是逐行扫描. 而 i (interlace) 则是隔行扫描\n下面说明如何设置 ffmpeg 参数来避免画面出现锯齿\n方法一: 设置 ffmpeg 参数 -deinterlace 测试失败\nffmpeg -i test.mpg -vcodec libx264 -s 1024x768 -b:v 700k -r 25 -deinterlace -acodec libmp3lame -ar 22050 -f flv -y test.flv 方法二: 使用 ffmpeg 滤镜 -vf yadif 成功\nffmpeg -i test.mpg -vcodec libx264 -s 1280x768 -b:v 700k -r 25 -vf yadif -acodec libmp3lame -ar 22050 -f flv -y test.flv 原文\nffmpeg转码问题一：反交错\n","date":"2017-05-15T19:21:00+08:00","permalink":"https://blog.acesheep.com/p/ffmpeg-deinterlace-and-antialiasing-filters/","title":"FFmpeg 视频锯齿与反交错滤镜"},{"content":"方法一 人际交往\r跟安装工程师套套近乎, 要到他们的电话, 他们可以跟服务台联系报出光猫的设备号算出超级密码的。\n方法二 查看配置文件法\r浏览器输入 http://192.168.1.1/manager_dev_config_t.gch, 打开网页后点击 导出配置, 导出配置文件config.bin\n使用 Offzip \u0026amp; Packzip UI 软件打开 config.bin 文件, 解密后生成 6 个 xxx.dat 的文件。\n下载软件 Offzip \u0026amp; Packzip UI\noffzip 的使用方法:\n注意: OffzipPackzip UI.exe 只能在 WinXP 32bit 及以下系统中 (装有 Microsoft .NET Framework) 运行, 不然软件直接报错无法运行\n路径不能包含中文字符 (一些特殊符号, 比如空格也会报错), 否则会出现没有解压文件的情况。\n其他系统比如 win 7 64bit, 可以使用 CMD 命令:\noffzip.exe -a config.bin . 0 用记事本 (最好是其他一些文本工具格式比较正确, 如 EditPlus、UltraEdit、Notepad++ 等) 打开这几个文件, 搜索 telecomadmin, 其中 telecomadminxxxxxxx 就是管理员密码 (xxxx为一串数字)\n3.我这里使用 EditPlus 搜索 telec 找到下图红色框框内的就是超级帐号和密码。\n方法三 (慎用) TLL 连接线破解, 专业方法\r这方法简单写写了, 既要买工具又要拆机, 大部分人估计没心情去破解了, 我自己也闲麻烦没有去搞, 以下是网上找的图片。\n首先准备一个 USB 转 TLL 转接器\n拆开猫连好 TLL 接线\n只需连接 TxD、RxD、GND 三根线, 波特率是设置为 115200。连接后帐号和密码一般为 root 和 root\n注意: 接线不要接错, 后果自付, 最好找个懂的人来帮忙。\n原文\nhttp://www.myxzy.com/post-422.html\n","date":"2017-03-05T20:53:00+08:00","permalink":"https://blog.acesheep.com/p/zte-f460-super-admin-password-crack/","title":"中兴 F460 光猫破解超级管理员密码"},{"content":"在 CentOS 下, nload 目前就只能基于源代码进行编译安装了。默认安装的 CentOS , 要编译安装 nload 时, 可能还需要安装几个需要的软件包: gcc 、gcc-c++ 和 ncurses-devel\nnload 官方网站\n备份下载: nload-0.7.4.tar.gz\nyum install gcc gcc-c++ ncurses-devel ncurses* wget http://www.roland-riegel.de/nload/nload-0.7.4.tar.gz tar xvf nload-0.7.4.tar.gz cd nload-0.7.4 ./configure make make install 完成后, nload 被安装在了 /usr/local/bin/nload\n用图形方式查看实时流量:\nnload -t 200 -i 1024 -o 128 -u H 查看第一网卡的流量情况, 显示的是实时的流量图\nnload eth0 同时查看多个网卡的流量情况。\nnload -m 参数说明:\nOptions: -a period Sets the length in seconds of the time window for average calculation. Default is 300. -a period 设置在时间窗口平均计算秒的长度。默认值是300。 -i max_scaling Specifies the 100% mark in kBit/s of the graph indicating the incoming bandwidth usage. Ignored if max_scaling is 0 or the switch -m is given. Default is 10240. -i max_scaling 指定了100％标记在图中的kbit / s的指示传入的带宽使用率。如果max_scaling为0或开关-m时给予忽略。默认值是10240。 -m Show multiple devices at a time; no traffic graphs. -m 显示多个设备同时使用;没有流量图。 -o max_scaling Same as -i but for the graph indicating the outgoing bandwidth usage. Default is 10240. -o max_scaling 相同的AS-I, 但对于曲线图, 显示出带宽使用。默认值是10240。 -t interval Determines the refresh interval of the display in milliseconds. Default is 500. -t interval 确定以毫秒为单位显示的刷新间隔。默认值是500。 -u h|b|k|m|g Sets the type of unit used for the display of traffic numbers. -u h|b|k|m|g 设置用于流量数字的显示单元的类型。 H|B|K|M|G h: auto, b: Bit/s, k: kBit/s, m: MBit/s etc. H: auto, B: Byte/s, K: kByte/s, M: MByte/s etc. Default is h. -U h|b|k|m|g Same as -u, but for a total amount of data (without \u0026#34;/s\u0026#34;). -U h|b|k|m|g 同-U, 但是对于数据的总量 (without \u0026#34;/秒\u0026#34;)。 H|B|K|M|G Default is H. devices Network devices to use. Default is to use all auto-detected devices. devices 网络设备使用。默认值是使用所有自动检测到的设备。 例子: nload -t 200 -i 1024 -o 128 -U M The options above can also be changed at run time by pressing the ‘F2′ key. 面的选项也可以在运行时按 \u0026#34;F2\u0026#34; 键改变。 原文\nlinux使用nload查看网卡流量\n","date":"2017-02-24T16:49:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-compile-and-install-nload/","title":"CentOS 7 编译安装 nload 查看网卡流量"},{"content":"谷歌推出的 TCP-BBR 开源算法, 起到单线程加速的作用 %\u0026amp;*(!$(\u0026amp;# (此处省略X字) 你要是问我具体什么理论和技术\u0026hellip; 网络上有很多文章。我不懂我怎么说?\ngithub.com/google/bbr\nbbr-quick-start.md\nBBR Development\n系统 Centos7\r开启 TCP-BBR 首先要升级 Linux 核心, 也就是升级到 4.9.0-1.el7.elrepo.x86_64 (目前是这个版本, 以后会有更高的更新)\nOpenVZ 架构的 VPS 没办法使用。\n部分服务商首先要去后台改一下内核设置, 例如 Digital Ocean 和 Linode\n如何更新 Digital Ocean 服务器 linux 核心?\n我的 VPS 服务商是 Digital Ocean , 首先要在服务商的网页后台, Kernel 选择为 GrubLoader , 远程命令 poweroff VPS 关机 (为了避免数据损坏使用命令关机而不是网页后台), 后台进入 Power , 选择 Power On VPS 开机, 如果没问题应该可以开始更换内核了。\n这里我出现了些问题, 因为选择几次 GrubLoader, 我已经安装配置好内核, 但是内核没有改变, 我当时是傻掉的。\n原因是 DO 在国内属于被墙一半的情况, 这几天网络掉包严重, 后台选择后没有生效\u0026hellip;\nLinode 服务商 Kernel 选择 GRUB 2 启动 (大概这样?! 我没有使用过 Linode )\n首先确认目前使用内核\nuname -r ELRepo Project\nrpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm yum --enablerepo=elrepo-kernel install kernel-ml -y 下载指定版本内核更新, 到目前位置最新内核版本为 5.5.6 这个内核在甲骨文上不支持. 5.3.0 测试可用\n因 elrepo 源都是最新版本, 4.19 找不到了\nkernel rpm 历史归档版本\n# wget http://mirror.rc.usf.edu/compute_lock/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-devel-5.3.0-1.el7.elrepo.x86_64.rpm # wget http://mirror.rc.usf.edu/compute_lock/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-headers-5.3.0-1.el7.elrepo.x86_64.rpm wget http://mirror.rc.usf.edu/compute_lock/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-5.3.0-1.el7.elrepo.x86_64.rpm rpm -ivh kernel-ml-5.3.0-1.el7.elrepo.x86_64.rpm 删除旧内核\nuname -a rpm -qa | grep kernel [root@localhost ~]# rpm -qa | grep kernel kernel-3.10.0-327.22.2.el7.x86_64 kernel-devel-3.10.0-327.22.2.el7.x86_64 kernel-headers-3.10.0-327.28.2.el7.x86_64 kernel-3.10.0-327.28.2.el7.x86_64 kernel-tools-3.10.0-327.28.2.el7.x86_64 kernel-devel-3.10.0-327.28.2.el7.x86_64 yum remove kernel-3.10.0-327.22.2.el7.x86_64 查看内核列表, 第一个的编号是 0\n# 一般位置 egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \\\u0026#39; # 甲骨文 Oracle Cloud egrep ^menuentry /boot/efi/EFI/centos/grub.cfg | cut -f 2 -d \\\u0026#39; 返回信息, 可以看见刚刚安装的内核 4.9 处于第 1 位, 编号 0\nCentOS Linux (4.9.0-1.el7.elrepo.x86_64) 7 (Core) CentOS Linux (3.10.0-327.13.1.el7.x86_64) 7 (Core) CentOS Linux (3.10.0-327.10.1.el7.x86_64) 7 (Core) CentOS Linux (3.10.0-229.20.1.el7.x86_64) 7 (Core) CentOS Linux (0-rescue-fd8cf26e06e411e4a9d004010897bd01) 7 (Core) 设置处于编号 0 的 4.9 内核默认运行\ngrub2-set-default 0 重启 linux, SSD 存储器的服务器重启速度还是快的, 1分钟就可以重新远程控制了\nreboot 查看内核是否在使用 4.9\nuname -r 返回信息\n[root@set-fire ~]# uname -r 4.9.0-1.el7.elrepo.x86_64 写入参数到 sysctl.conf\necho \u0026#34;net.core.default_qdisc=fq\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf echo \u0026#34;net.ipv4.tcp_congestion_control=bbr\u0026#34; \u0026gt;\u0026gt; /etc/sysctl.conf sysctl -p 检测设置是否生效\nsysctl net.ipv4.tcp_available_congestion_control 返回信息, 可以看见 bbr 已经启用\n[root@set-fire ~]# sysctl net.ipv4.tcp_available_congestion_control net.ipv4.tcp_available_congestion_control = bbr cubic reno 查看 bbr 是否在运行\nlsmod | grep bbr 返回信息\n[root@set-fire ~]# lsmod | grep bbr tcp_bbr 16384 29 这样应该安装完成了, 可以测试一下有没有传输速度上的提升。\n我认为传输速度提升是有的, 只是效果的差别, 有些服务器作用明显, 有些服务器因为网路传输原因而作用微小\u0026hellip; 并且中国大陆有神奇的网路 (丢包)。\n原文\nDebian8/Centos7 开启 TCP-BBR 的方式\n","date":"2017-02-20T20:02:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-enable-tcp-bbr/","title":"CentOS 7 开启 TCP-BBR 的方式"},{"content":"n2n 是一个开放源代码的第 2 层轻量 VPN 程序, 该程序利用了点对点的架构来处理网络间的成员关系和路由。\n准备条件 2020-12 更新\r由于我们需要自己自建整个 n2n , 因此我们需要一台有公网固定 IP 地址的服务器来充当 supernode 的角色\nvps: aliyun-ecs.t5-lc2m1.nano 1核512MB CentOS 7 宽带25Mbps\n注意: 472a987 2.8 版本使用压缩存在内存泄漏, 在 99e56e9 得到修复.\n构建环境\nWindows 10 Visual Studio 2017 安装 Desktop development with C++ 开发套件 OpenSSL-1.1.1i 编译指南 zstd-1.4.8.tar.gz - Zstandard v1.4.8 cmake-3.12.4-win64-x64.msi n2n-2.8 Stable Release OpenVPN-2.5.0-I601-amd64.msi (TAP 网卡驱动 TAP-Windows Provider V9 - 9.24.6.601) 编译好的版本已修复内存泄漏 不想努力下载这个\nn2n-2.8.r540.53afd3c-x64-with-openssl-1.1.1-zstd-1.4.8-Release-AceSheep.zip\nWindows 10 客户端\r首先准备好 Cmake, Openssl, zstd\nn2n-2.8 在 windows 上支持 zstd 很复杂 需要修改 CMakeLists.txt, 大概这几个内容\n删除代码里所有 #ifdef HAVE_LIBZSTD ... #endif 项目太乱了\nadd_definitions(-DHAVE_OPENSSL_1_1) add_definitions(-DN2N_HAVE_AES) add_definitions(-DN2N_HAVE_ZSTD) add_definitions(-DHAVE_LIBZSTD) target_link_libraries(n2n \u0026#34;C:/zstd-1.4.8/build/VS2010/bin/x64_Release/libzstd_static.lib\u0026#34;) zstd-1.4.8 不要下载编译好的我们要自己编译, 不然静态 zstd 会不够静态 (大雾\n下载解压之后在 zstd-1.4.8\\build\\VS2010\\zstd.sln 中 编译 libzstd 就可以使用了 zstd-1.4.8\\build\\VS2010\\bin\\x64_Release\\libzstd_static.lib\n解压源码 e:\\n2n-2.8, 新建一个 build 或 build64 文件夹\n在 build 文件里打开cmd窗口\nx86 -A Win32 x64 -A x64 C:\\n2n-2.8\\build64\u0026gt;cmake .. -A x64 -DOPENSSL_ROOT_DIR=C:\\openssl-1.1.1i\\build64 -DOPENSSL_USE_STATIC_LIBS=true 这时候我们会遇到第一个错误\nn2n.h(42,10): fatal error C1083: 无法打开包括文件: \u0026#34;config.h\u0026#34;: No such file or directory --- a/include/n2n.h\r+++ b/include/n2n.h\r@@ -38,11 +38,7 @@\r#ifdef WIN32\r#include \u0026#34;win32/n2n_win32.h\u0026#34;\r-#ifdef _MSC_VER\r-#include \u0026#34;config.h\u0026#34; /* Visual C++ */\r-#else\r#include \u0026#34;win32/winconfig.h\u0026#34;\r-#endif\r#define N2N_CAN_NAME_IFACE 1\r#undef N2N_HAVE_DAEMON\r#undef N2N_HAVE_SETUID 按照上面说的修改下 n2n.h 重新编译。\nC:\\n2n-2.8\\build64\u0026gt;cmake .. -A x64 -DOPENSSL_ROOT_DIR=C:\\openssl-1.1.1i\\build64 -DOPENSSL_USE_STATIC_LIBS=true -- Building for: Visual Studio 15 2017 -- The C compiler identification is MSVC 19.16.27045.0 -- The CXX compiler identification is MSVC 19.16.27045.0 -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done fatal: Not a git repository (or any of the parent directories): .git fatal: Not a git repository (or any of the parent directories): .git -- Build from git rev: 2.7.0.r.AceSheep -- Configuring done -- Generating done -- Build files have been written to: C:/n2n-2.8/build64 执行完在目录下会生成 n2n.sln 解决方案, 在 ALL_BUILD 右键选择 Build 就可以了\n这时候属于我们的 edge 就出炉了\nedge.exe -h Welcome to n2n v.2.7.0.r.AceSheep for Windows-10.0.15063 Built on Dec 18 2020 20:27:33 Copyright 2007-2020 - ntop.org and contributors edge (see edge.conf) or edge -d -a [static:|dhcp:] -c [-k ] [-s ] [-n cidr:gateway] [-m ] -l [-p ] [-M ] [-D] [-r] [-E] [-v] [-i ] [-L ] [-t ] [-A[]] [-H] [-z[]] [-h] -d | tun device name -a | Set interface address. For DHCP use \u0026#39;-r -a dhcp:0.0.0.0\u0026#39; -c | n2n community name the edge belongs to. -k | Encryption key (ASCII) - also N2N_KEY=. -s | Edge interface netmask in dotted decimal notation (255.255.255.0). -l | Supernode IP:port -i | Registration interval, for NAT hole punching (default 20 seconds) -L | TTL for registration packet when UDP NAT hole punching through supernode (default 0 for not set ) -p | Fixed local UDP port. -m | Fix MAC address for the TAP interface (otherwise it may be random) | eg. -m 01:02:03:04:05:06 -M | Specify n2n MTU of edge interface (default 1290). -D | Enable PMTU discovery. PMTU discovery can reduce fragmentation but | causes connections stall when not properly supported. -r | Enable packet forwarding through n2n community. -A1 | Disable payload encryption. Do not use with key (defaulting to Twofish then). -A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish (default), | -A3 or -A (deprecated) = AES-CBC, -A5 = Speck-CTR. -H | Enable full header encryption. Requires supernode with fixed community. -z1 ... -z2 or -z | Enable compression for outgoing data packets: -z1 or -z = lzo1x (default=disabled). -E | Accept multicast MAC addresses (default=drop). -S | Do not connect P2P. Always use the supernode. -n | Route an IPv4 network via the gw. Use 0.0.0.0/0 for the default gw. Can be set multiple times. -v | Make more verbose. Repeat as required. -t | Management UDP Port (for multiple edges on a machine). Environment variables: N2N_KEY | Encryption key (ASCII). Not with -k. Available TAP adapters: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} - OpenVPN TAP-Windows6 Windows 10:\n需要安装TAP 网卡驱动 TAP-Windows Provider V9 - 9.24.6.601\n这个驱动是 OpenVPN 里面的 OpenVPN-2.5.0-I601-amd64.msi, 下载好社区版的 msi 文件之后可以使用命令仅安装 TAP 驱动\n在下载的文件夹打开命令行执行, 这样可以不用在 GUI 里面选择需要安装的项目.\n重命名网卡, 设置为 OpenVPN TAP-Windows6\nmsiexec /i OpenVPN-2.5.0-I601-amd64.msi ADDLOCAL=Drivers.TAPWindows6 /passive ncpa.cpl 一键安装脚本 once-install.bat\n@echo off chcp 936 cls %1 %2 mode con:cols=46 lines=5 net session \u0026gt;nul 2\u0026gt;\u0026amp;1 if not %errorlevel% equ 0 ( echo 错误 - 脚本必须以管理员身份运行或者女装! echo: echo 在弹出窗口点击 \u0026#39;允许\u0026#39; ) else ( goto :begin ) mshta vbscript:createobject(\u0026#34;shell.application\u0026#34;).shellexecute(\u0026#34;%~dp0%~snx0\u0026#34;,\u0026#34;goto :begin\u0026#34;,\u0026#34;\u0026#34;,\u0026#34;runas\u0026#34;,1)(window.close)\u0026amp;\u0026amp;exit :begin echo. echo 正在安装 TAP Windows 虚拟网卡 cd \u0026#34;%~dp0\u0026#34; msiexec /i OpenVPN-2.5.0-I601-amd64.msi ADDLOCAL=Drivers.TAPWindows6 /passive echo. echo 启动控制面板网络适配器设置 修改虚拟网卡名称为 OpenVPN TAP-Windows6 ::ncpa.cpl netsh interface show interface echo. echo 正在设置防火墙 PowerShell -Command \u0026#34;\u0026amp; {Set-NetFirewallRule -Name FPS-ICMP4-ERQ-In -Enabled True}\u0026#34; PowerShell -Command \u0026#34;\u0026amp; {Get-NetFirewallRule -Name FPS-ICMP4-ERQ-In}\u0026#34; echo. echo 已经安装完成, 可以启动试试了. ping 127.0.0.1 -n 6 -w 1000 2\u0026gt;nul 1\u0026gt;nul exit 其他的用法\n/i - the installer file /passive - run as silent ADDLOCAL= - choose what to install, including: - OpenVPN.Service - OpenVPN - OpenVPN.GUI - OpenVPN.GUI.OnLogon - Drivers - Drivers.Wintun - Drivers.TAPWindows6 PRODUCTDIR= - target directory e.g.: msiexec /i OpenVPN-2.5.msi ADDLOCAL=OpenVPN.Service,OpenVPN,Drivers,Drivers.Wintun /passive 运行\r第一次启动需要使用管理员身份运行, 不然无法设置ip地址\npassword: Cartoons - Witch Doctor\nedge.exe -l 1xx.1xx.1xx.1xx:6666 -d \u0026#34;OpenVPN TAP-Windows6\u0026#34; -c GTFO -A3 -k 51522zzwlwlbb -a 192.168.6.100 20/Dec/2020 00:00:14 [edge_utils.c:2575] Adding supernode[0] = 1xx.1xx.1xx.1xx:6666 20/Dec/2020 00:00:14 [edge.c:852] Starting n2n edge 2.7.0.r.AceSheep Dec 20 2020 13:42:56 20/Dec/2020 00:00:14 [edge.c:858] Using compression: none. 20/Dec/2020 00:00:14 [edge.c:859] Using AES-CBC cipher. 20/Dec/2020 00:00:14 [edge.c:869] ip_mode=\u0026#39;static\u0026#39; Open device [name={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}][ip=192.168.6.100][ifName=OpenVPN TAP-Windows6][MTU=1290][mac=01:02:03:04:05:06] 20/Dec/2020 00:00:14 [edge_utils.c:211] supernode 0 =\u0026gt; 1xx.1xx.1xx.1xx:6666 20/Dec/2020 00:00:14 [edge.c:947] edge started 20/Dec/2020 00:00:24 [edge_utils.c:1800] [OK] Edge Peer \u0026lt;\u0026lt;\u0026lt; ================ \u0026gt;\u0026gt;\u0026gt; Super Node 也可以设置配置文件 edge.conf\n-c=GTFO -A3 -k=51522zzwlwlbb # 服务器地址 -l=1xx.1xx.1xx.1xx:6666 # openVPN 网卡名称 -d=OpenVPN TAP-Windows6 # edge IP address 修改这里 2-254 192.168.6.xxx -a=192.168.6.100 ping 不通 / ping 超时\r需要开启防火墙规则, 管理员 cmd 执行\nCMD witn Administrator 有的系统运行不成功优先使用 PowerShell 命令: netsh advfirewall firewall set rule name=\u0026#34;File and Printer Sharing (Echo Request - ICMPv4-In)\u0026#34; dir=in new enable=Yes PowerShell witn Administrator: Set-NetFirewallRule -Name FPS-ICMP4-ERQ-In -Enabled True 设置网卡跃点数 / 优先级\r管理员 cmd 执行\n\u0026gt;netsh interface ipv4 show interfaces Idx Met MTU State Name --- ---------- ---------- ------------ --------------------------- 1 75 4294967295 connected Loopback Pseudo-Interface 1 9 10 1290 connected OpenVPN TAP-Windows6 23 35 1500 connected VMware Network Adapter VMnet1 28 35 1500 connected VMware Network Adapter VMnet8 10 25 1500 connected Ethernet 7 找到 TAP 网卡 Idx 为 9\n\u0026gt;netsh interface ipv4 set interface 9 metric=10 Ok. 这样就成功了\n隐藏黑色的运行窗口\r新建一个 start.bat 文件, 保存运行就可以了. 结束的时候运行 stop.bat taskkill /f /im edge.exe\n目录结构\nstart.bat\n@echo off chcp 936 cls %1 %2 mode con:cols=46 lines=5 net session \u0026gt;nul 2\u0026gt;\u0026amp;1 if not %errorlevel% equ 0 ( echo 错误 - 脚本必须以管理员身份运行或者女装! echo: echo 在弹出窗口点击 \u0026#39;允许\u0026#39; ) else ( goto :begin ) ::mshta vbscript:createobject(\u0026#34;wscript.shell\u0026#34;).run(\u0026#34;%~dp0%~nx0 h\u0026#34;,0)(window.close)\u0026amp;\u0026amp;exit mshta vbscript:createobject(\u0026#34;shell.application\u0026#34;).shellexecute(\u0026#34;%~dp0%~snx0\u0026#34;,\u0026#34;goto :begin\u0026#34;,\u0026#34;\u0026#34;,\u0026#34;runas\u0026#34;,0)(window.close)\u0026amp;\u0026amp;exit :begin tasklist /nh|find /i \u0026#34;n2nedge.exe\u0026#34; if ERRORLEVEL 1 ( \u0026#34;%~dp0n2nedge.exe\u0026#34; \u0026#34;%~dp0edge.conf\u0026#34; exit ) else ( echo n2nedge.exe is already running exit ) stop.bat\n@echo off chcp 936 cls mode con:cols=46 lines=5 %1 %2 net session \u0026gt;nul 2\u0026gt;\u0026amp;1 if not %errorlevel% equ 0 ( echo 错误 - 脚本必须以管理员身份运行或者女装! echo: echo 在弹出窗口点击 \u0026#39;允许\u0026#39; ) else ( goto :begin ) mshta vbscript:createobject(\u0026#34;shell.application\u0026#34;).shellexecute(\u0026#34;%~dp0%~snx0\u0026#34;,\u0026#34;goto :begin\u0026#34;,\u0026#34;\u0026#34;,\u0026#34;runas\u0026#34;,1)(window.close)\u0026amp;\u0026amp;exit :begin taskkill /f /im n2nedge.exe 2\u0026gt;nul 1\u0026gt;nul echo n2nedge.exe 已发送退出指令 ping 127.0.0.1 -n 3 -w 1000 2\u0026gt;nul 1\u0026gt;nul tasklist /nh|find /i \u0026#34;n2nedge.exe\u0026#34; if ERRORLEVEL 1 ( echo n2nedge.exe 已退出 ) else ( echo n2nedge.exe 还在运行 稍等几秒在执行一次 ) ping 127.0.0.1 -n 3 -w 1000 2\u0026gt;nul 1\u0026gt;nul exit test.bat\n@echo off chcp 936 cls mode con:cols=60 lines=25 ping 192.168.100.1 echo: echo: echo: if not %errorlevel% equ 0 ( echo 错误 - 未能与服务器建立连接 echo: tasklist /nh|find /i \u0026#34;n2nedge.exe\u0026#34; if ERRORLEVEL 1 ( echo 错误 - N2N 未运行 echo: ) else ( echo 错误 - N2N 已经启动但无法连接 echo: ) ) else ( echo 测试成功 可以进行游戏了 echo: ) ping 127.0.0.1 -n 10 -w 1000 2\u0026gt;nul 1\u0026gt;nul exit 其他设置 暂时无用\r这个命令比较新, 需要 powershell , 或者去改注册表\u0026hellip;\n设置网卡为 专用网络 (Private Network)\nGet-NetIPInterface -AddressFamily IPv4 -ConnectionState Connected Set-NetConnectionProfile -InterfaceAlias \u0026#34;OpenVPN TAP-Windows6\u0026#34; -NetworkCategory Private 下载的静态 zstd 不够静态\rlibzstd_static.lib(zstd_v06.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(zstd_v07.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(huf_decompress.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(fse_decompress.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(huf_compress.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(fse_compress.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(hist.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(zstd_v05.o) : error LNK2001: unresolved external symbol ___chkstk_ms libzstd_static.lib(fse_compress.o) : error LNK2019: unresolved external symbol ___udivdi3 referenced in function _FSE_normalizeCount 因为下载的是 MinGW 编译的所以 MSBuild 无法使用, 这里我们使用 Visual Studio 2017 编译使用\nCentOS 7 服务端\rvps: aliyun-ecs.t5-lc2m1.nano 1核512MB CentOS 7 宽带25Mbps\n服务器创建好了之后就可以开始执行了\nyum install gcc-c git autoconf automake libtool git dhcp libzstd-devel nmap htop screen -y git clone https://github.com/ntop/n2n.git --depth 1 --branch 2.8-stable cd n2n ./autogen.sh ./configure CFLAGS=\u0026#34;-O3 -march=native\u0026#34; make \u0026amp;\u0026amp; make install 装完之后就可以运行测试了\nsupernode -l 6666 服务器简单很多\n记得开放 udp 的端口\n#firewalld firewall-cmd --zone=public --add-port=6666/udp --permanent firewall-cmd --reload #iptables iptables -I INPUT -p udp --dport 6666 -j ACCEPT service iptables save service iptables restart #ufw ufw allow 6666/udp 搭建 DHCP 服务器 并把 N2N 设置为系统服务 (可选步骤)\r限制社区连接 (可选)\n这个文件可以参考 Communities.md\nvim /home/n2n/n2n_community.list\nAceSheep supernode 配置文件\nvim /home/n2n/n2n_config.conf\n-l=3000 -c=/home/n2n/n2n_community.list supernode 系统服务/守护程序\nvim /etc/systemd/system/n2nserver.service\n[Unit] Description=n2n v.2.8.0.r1.53afd3c After=network.target [Service] Type=simple User=root ExecStart=/usr/sbin/supernode /home/n2n/n2n_config.conf Restart=on-failure [Install] WantedBy=multi-user.target 启动测试, 查看状态\nsystemctl daemon-reload systemctl start n2nserver systemctl status n2nserver nc -u 127.0.0.1 5645 N2N 搭建 DHCP 实现自动分配 IP地址\r在服务器上启动一个 edge 作为分配 DHCP 的接口\nedge 配置文件\nvim /home/n2n/n2n_edgedhcp.conf\n-c=AceSheep -z2 -A3 -k=8hKS1ew2VfX0M962 -l=0.0.0.0:3000 -d=n2ndhcp -r -a=192.168.50.0 -f edge 系统服务/守护程序\nvim /etc/systemd/system/n2ndhcp.service\n[Unit] Description=n2n DHCP After=network.target n2nserver.service [Service] Type=simple User=root ExecStart=/usr/sbin/edge /home/n2n/n2n_edgedhcp.conf Restart=on-failure [Install] WantedBy=multi-user.target 启动测试, 查看状态\nsystemctl daemon-reload systemctl start n2ndhcp systemctl status n2ndhcp nc -u 127.0.0.1 5645 配置 DHCP 服务器\nvim /etc/dhcp/dhcpd.conf\nddns-update-style interim;\rignore client-updates;\rsubnet 192.168.50.0 netmask 255.255.255.0 {\rrange dynamic-bootp 192.168.50.100 192.168.50.200;\roption subnet-mask 255.255.255.0;\rdefault-lease-time 86400;\rmax-lease-time 864000;\rinterface n2ndhcp;\r}\rhost ftp_server {\rhardware ethernet 52:54:00:6f:f9:63; # 指定主机 mac 地址\rfixed-address 192.168.50.254; # 为指定主机分配的ip\r} 启动测试, 查看状态\nsystemctl start dhcpd systemctl status dhcpd 都运行正常本地测试成功之后 设置为开机启动\nsystemctl enable dhcpd n2ndhcp n2nserver reboot 2017-2 旧\rSupernode: CentOS 7\nEdge: CentOS 7 ARM\n安装\rn2n 有两种协议, 一种是 v1 协议, 另一种是 v2 协议, 两种是不兼容的。\n我们最好使用编译安装.\nUbuntu / Debian 系列\nsudo apt-get install subversion build-essential libssl-dev CentOS 系列\nyum install subversion gcc-c openssl-devel 不管你是什么系统, 下面的代码都是一样的, 我们使用 v2 协议。\nsvn co https://svn.ntop.org/svn/ntop/trunk/n2n cd n2n/n2n_v2 make sudo make install 如果不出问题的话, 我们就安装成功了。\n配置\rSupernode 配置\nSupernode 并不需要 root 权限就可以运行, 不过如果你是想使用小于 1024 的端口, 就需要 root 权限了。\n运行以下命令即可把supernode运行在后台。\nsupernode -l 12345 更多的用法如下\npi@raspberrypi ~ $ supernode -h supernode usage -l Set UDP main listen port to -f Run in foreground. -v Increase verbosity. Can be used multiple times. -h This help message. Edge 配置\n简单修改并运行以下命令即可运行edge\nedge -d edge0 -a 10.0.0.10 -c [community] -k [encrypt key] -u 1000 -g 1000 -l [Supernode IP]:[Supernode Port] 例子\nedge -d edge0 -a 10.0.0.10 -c myn2nline -k password123 -u 1000 -g 1000 -l 123.121.22.102:43321 更多的用法如下\npi@raspberrypi ~ $ edge -h Welcome to n2n v.2.1.0 for unknown Built on Sep 26 2015 16:11:34 Copyright 2007-09 - http://www.ntop.org edge -d -a [static:|dhcp:] -c [-k | -K ] [-s ] [-u -g ][-f][-m ] -l [-p ] [-M ] [-r] [-E] [-v] [-t ] [-b] [-h] -d | tun device name -a | Set interface address. For DHCP use \u0026#39;-r -a dhcp:0.0.0.0\u0026#39; -c | n2n community name the edge belongs to. -k | Encryption key (ASCII) - also N2N_KEY=. Not with -K. -K | Specify a key schedule file to load. Not with -k. -s | Edge interface netmask in dotted decimal notation (255.255.255.0). -l | Supernode IP:port -b | Periodically resolve supernode IP : (when supernodes are running on dynamic IPs) -p | Fixed local UDP port. -u | User ID (numeric) to use when privileges are dropped. -g | Group ID (numeric) to use when privileges are dropped. -f | Do not fork and run as a daemon; rather run in foreground. -m | Fix MAC address for the TAP interface (otherwise it may be random) : eg. -m 01:02:03:04:05:06 -M | Specify n2n MTU of edge interface (default 1400). -r | Enable packet forwarding through n2n community. -E | Accept multicast MAC addresses (default=drop). -v | Make more verbose. Repeat as required. -t | Management UDP Port (for multiple edges on a machine). Environment variables: N2N_KEY | Encryption key (ASCII). Not with -K or -k. 需要注意的是, -a 参数所指定的是你连接上 n2n 网络上的 IP 地址, 显然这是不可以重复的。\n你可以使用 DHCP 服务器进行分配 IP , 使用 -a dhcp:10.0.0.22 意思就是使用 10.0.0.22 作为 DHCP 服务器进行 IP 地址的分配, 而 10.0.0.22 这台服务器也是需要连接上同一个 Edge 的。\n更多的用法你们可以自己参考上面的文档。\n错误解决\nn2n[4405]: ERROR: ioctl() [Operation not permitted][-1]\n在我的树莓派上面运行的时候出现了上面的问题, 显然这是由于权限不足导致的, 因为 edge 需要 root 权限来创建一个 TAP 接口, 因此我们需要通过 sudo 来运行。\n新原文\nN2N Windows编译过程。。。以及遇到的一些坑（这篇不是网上复制的。绝对有用）\nHow to build x86 and/or x64 on Windows from command line with CMAKE?\nCMake not able to find OpenSSL library\nn2n Build on Windows\nCommand-line installation of OpenVPN\n使用N2N搭建虚拟局域网联机游戏（服务端）\nLAN discovery\nEnable file and print sharing command line - how to enable it just for profile=private\nStatic linking of OpenSSL Crypto in CMake\nMinecraft Local Server Discovery – Can’t find LAN games?\nN2N组建虚拟局域网联机遇到搜不到房间的问题一例\nIs static library not enough static? - zstd\nWindows Network Public To Private.sh\nEnable file and print sharing command line - how to enable it just for profile=private\n旧原文\nHow to enable broadcast and multicast support on Amazon (AWS) EC2 n2n\nwww.buckhill.co.uk 网页离线缓存\nN2N Edge GUI 文件很旧 备份下载: n2neg.zip\n","date":"2017-02-13T22:00:00+08:00","permalink":"https://blog.acesheep.com/p/n2n-2.8-virtual-lan-setup/","title":"n2n 2.8 虚拟局域网搭建 | n2n build with x64 | GTFO n2n"},{"content":"什么是抓包\r抓包 (Packet Capture), 实际上就是对网络请求 (包括发送与接收) 的数据包进行截获、重发、编辑、转存等操作, 在 Android 下, 也经常被用来进行数据截取等。\n学会抓包之后, 获取某个 App 的 API 就是轻而易举的事了, 当然, 现在有很多App, 都对API进行了加密验证, 例如 Hash 校验。所以在这种条件下, 调用人家的API就困难得多了。\n在局域网使用 ARP 攻击也可以抓包 Kali Linux ARP 攻击\n抓包工具\r抓包工具比较常见的是 Fiddler, Wireshark 等, 个人比较喜欢 Charles, 官网, 界面简洁人性化, 只做数据截取的话, 足够用了, 并且同时支持 Windows, Mac, Linux。下面就介绍如何利用 Charles 进行抓包。\n去 Charles 的官方网站 (http://www.charlesproxy.com) 下载最新版的 Charles 安装包\nCharles 是收费软件, 可以免费试用30天。试用期过后, 未付费的用户仍然可以继续使用, 但是每次使用时间不能超过 30 分钟, 并且启动时将会有 10 秒种的延时。\nCharles\rCharles 界面如图\n主机允许代理模式\r菜单栏 Proxy -\u0026gt; Proxy settings, Port 设置一个不与电脑其他端口冲突的端口号, 比如 8888, 并勾选 Enable transparent HTTP proxying, 点击 OK。这样, 就允许了HTTP代理模式。\n客户端设置代理\r在 Android / iOS 下设置代理\n首先, 通过 ipconfig 查看主机 ip 地址 (mac 或 linux 下使用 ifconfig)\n然后, Android 或 iOS 须和主机处于同一个局域网下 (连同一个路由器, 同网段)\n在 Android 中打开 设置 -\u0026gt; WLAN -\u0026gt; 长按当前连接的 Wi-Fi -\u0026gt; 修改网络 -\u0026gt; 高级选项 -\u0026gt; 打开代理 (手动) -\u0026gt; 输入主机ip 地址及代理端口号 -\u0026gt; 保存\niOS 开启代理的方式也差不多, 进入设置 -\u0026gt; 无线局域网 -\u0026gt; 查看当前连接的 Wi-Fi信息 -\u0026gt; HTTP 设置服务器和端口\n截获数据包\r前面设置完毕之后, 当 Android / iOS 下, 有进行网络请求时, 那么 Charles 会弹出一个对话框, 确认是否允许代理, 点击 Allow, 表示允许\n这个时候, 请求的地址就会出现在左侧的 structure 栏里面, 点击可以查看具体请求的信息\nHTTPS\r安装 SSL 证书\rHTTPS 请求, 响应数据可能会出现乱码, 这时候就需要安装 Charles 的 CA 证书\n去 http://www.charlesproxy.com/ssl.zip 下载CA证书文件\n解压该 zip 文件后, 双击其中的 .crt 文件, 这时候在弹出的菜单中选择 总是信任, 如下所示\n从钥匙串访问中即可看到添加成功的证书。如下所示\n当然如果要抓取 iPhone 设备上的 HTTPS 请求, 需要在 iPhone 上也安装一个证书, 在 safari 输入这个网址: http://charlesproxy.com/getssl, 点击安装即可\n截取 SSL 信息\rCharles 默认并不截取 SSL 的信息, 如果你想对截取某个网站上的所有 SSL 网络请求, 可以在该请求上右击, 选择 SSL proxying\n这样, 对于该 Host 的所有 SSL 请求可以被截取到了。用通配符 * 可以监控所有 HTTPS 请求\n模拟慢速网络\r在做 iPhone 开发的时候, 我们常常需要模拟慢速网络或者高延迟的网络, 以测试在移动网络下, 应用的表现是否正常。Charles 对此需求提供了很好的支持。\n在 Charles 的菜单上, 选择 Proxy -\u0026gt; Throttle Setting 项, 在之后弹出的对话框中, 我们可以勾选上 Enable Throttling, 并且可以设置 Throttle Preset 的类型。\n如果我们只想模拟指定网站的慢速网络, 可以再勾选上图中的 Only for selected hosts 项, 然后在对话框的下半部分设置中增加指定的 hosts 项即可。\n修改网络请求内容\r有些时候为了调试服务器的接口, 我们需要反复尝试不同参数的网络请求。Charles 可以方便地提供网络请求的修改和重发功能。只需要在以往的网络请求上点击右键, 选择 Edit, 即可创建一个可编辑的网络请求。\n我们可以修改该请求的任何信息, 包括 url 地址, 端口, 参数等, 之后点击 Execute 即可发送该修改后的网络请求。Charles 支持我们多次修改和发送该请求, 这对于我们和服务器端调试接口非常方便。\n总结\r通过 Charles 软件, 我们可以很方便地在日常开发中, 截取和调试网络请求内容, 分析封包协议以及模拟慢速网络。用好 Charles 可以极大的方便我们对于带有网络请求的 App 的开发和调试。\nCharles 还有其他挺多功能, 比如 断点, 数据过滤, 重定向等功能, 这里就不一一介绍了~\n加密请求\r有一些做的比较好的接口, 可能需要对请求参数做一个校验。例如哔哩哔哩的API, 就需要把所有的请求参数, 排序后进行 MD5 加密, 服务端会对加密结果进行校验。但是这方面没有固定的套路, 还需要自己檫亮眼睛去发现加密方式~~\n原文\n详解Android/IOS平台下抓包工具使用以及抓取API接口\niOS 开发工具——网络封包分析工具 Charles\n","date":"2017-01-22T14:43:00+08:00","permalink":"https://blog.acesheep.com/p/charles-proxy-usage-guide/","title":"Charles 抓包工具使用详解"},{"content":"服务器 forge 版本 mc 1.7.10\rforge-1.7.10-10.13.4.1558-1.7.10-installer.jar\n服务器 MOD\r无中生有 Ex-Nihilo-1.38-52.jar\n星辉生万物 Ex-Astris-MC1.7.10-1.16-36.jar\n压缩工具 excompressum-mc1.7.10-1.1.143.jar\n极限末地 HardcoreEnderExpansionMC-1.7.10v1.8.6.jar\n工业2实验版 industrialcraft-2-2.2.826-experimental.jar\n高级太阳能 AdvancedSolarPanel-1.7.10-3.5.1[TFCN].jar\n能源转换 PowerConverters1.7.10.jar\n沉浸工程 ImmersiveEngineering-0.6.5.1.jar\n匠魂 ( 前置 Mantle-1.7.10-0.3.2b.jar 本体 TConstruct-1.7.10-1.8.8.build991.jar )\n凿子 Chisel-2.9.5.11.jar\n热力膨胀 (核心 CoFHCore-[1.7.10]3.1.3-327.jar ThermalDynamics-[1.7.10]1.2.0-171.jar ThermalFoundation-[1.7.10]1.2.5-115.jar ThermalExpansion-[1.7.10]4.1.4-247.jar )\n超能物质 (CoFHLib-[1.7.10]1.0.3B4-174.jar MatterOverdrive-1.7.10-0.4.0.jar) 删除!!\n神秘时代 (前置 Baubles-1.7.10-1.0.1.10.jar 本体 Thaumcraft-1.7.10-4.2.3.5.jar )\n神秘附属 (神秘工匠 ThaumicTinkerer-2.5-1.7.10-164.jar 禁忌魔法 Forbidden Magic-1.7.10-0.575.jar 节点学 NodalMechanics-1.7-1.0-7.jar )\n和风 Bamboo-2.6.8.5.jar\n末影接口 EnderIO-1.7.10-2.2.8.381.jar\n矿脉矿工汉化 VeinMiner_0.23.0.50.jar\n矿工天堂 1.7.10矿工天堂v3.1.1.jar\n更多实用设备2 extrautilities-1.2.12.jar\n","date":"2016-12-26T18:02:00+08:00","permalink":"https://blog.acesheep.com/p/mc-1.7.10-industrial-server/","title":"Minecraft 1.7.10 工业服务器"},{"content":"下载\rSourceMod + Metamod Source\n下面标记的版本 (和以后的版本) 才支持 L4D2\nSourceMod\rSourceMod 是针对任何运行 Half-Life 2 引擎的游戏的服务器修改。它是一个功能强大、高度优化的平台, 用于编写插件脚本和处理服务器管理。默认软件包附带一组基本插件, 但社区中有超过 2500 个插件。\nSourceMod 版本号: 1.3.0-hg2865 下载地址\n备份下载 sourcemod-1.8.0-git5505-windows.zip\nMetaMod:Source\rMetamod:Source是 Half-Life 2 的一个 C++ 插件环境。它充当游戏和引擎之间的 \u0026ldquo;metamod\u0026rdquo;, 允许插件拦截两者之间的调用。它提供了一种称为 SourceHook 的机制, 这是一个非常强大的库, 用于拦截、覆盖和取代虚拟函数调用。\nMetaMod:Source 版本号: 1.8.0-hg688 下载地址\n备份下载 mmsource-1.10.5-windows.zip\n安装步骤\r.zip 为 Windows 系统使用\n.tar.gz 为 Linux 系统使用\n1. 下载并解压\r将 sourcemod-1.3.0-hg2865.zip 和 mmsource-1.8.0-hg688.zip 解压至\nX:\\Steam\\steamapps\\common\\left 4 dead 2\\left4dead2\nX 代表你的盘符, 其路径改成你的 L4D2 所在目录, 如有提示覆盖, 点选\u0026lt;全部\u0026gt;即可\n2. 生成VDF文件\r进入 http://www.metamodsource.net/vdf\nGame 选择游戏 Left 4 Dead 2 点击按钮生成 Generate metamod.vdf 把所得的 metamod.vdf 放入 X:\\Steam\\steamapps\\common\\left 4 dead 2\\left4dead2\\addons\n3. 测试安装是否成功\r运行 srcds.exe (没有就下载 srcds.rar)\n在 srcds.exe 上的控制台输入: meta version\n如提示为下面的信息, 则表示安装成功\nMetamod:Source version 1.8.0-dev Build ID: 682:f125dd3ed7d0-dev Loaded As: Valve Server Plugin Compiled on: Nov 17 2009 Plugin interface version: 15:14 SourceHook version: 5:5 http://www.metamodsource.net/ 4. 设置管理员 (正版) 盗略\rleft 4 dead 2\\left4dead2\\addons\\sourcemod\\configs 目录下\n找到 admins.cfg 用 VS Code 或 UltraEdit 打开\n\u0026#34;BAILOPAN\u0026#34; # \u0026lt;游戏名字\u0026gt; { \u0026#34;auth\u0026#34; \u0026#34;steam\u0026#34; # steam账号, 游戏名字, IP \u0026#34;identity\u0026#34; \u0026#34;STEAM_0:1:16\u0026#34; # steam_ID (不是账号哦), 游戏名字 \u0026#34;flags\u0026#34; \u0026#34;abcdef\u0026#34; # 这里是设置管理员的权限, 具体请参考同目录下的 admin_levels.cfg 文件 } 同目录下找到 admins_simple.ini 用 VS Code 或 UltraEdit 打开, 并在最后加入\n\u0026#34;007\u0026#34; \u0026#34;99:z\u0026#34; \u0026#34;007\u0026#34; 前面的 007 表示游戏名字\n中间的 99:z 表示最高权限 (具体参考同目录下的 admin_levels.cfg 文件)\n后面的 007 表示管理员的密码\n保存时, 游戏名字如为中文, 需要另存为 UTF-8 编码\n同目录下找到 core.cfg\n\u0026#34;PassInfoVar\u0026#34; \u0026#34;_password\u0026#34; 将 _password 改为 _pass\n注意: _ 该值前必须带有哦\n5. 设置管理员 (盗版) 正略\r盗版用户无需设置 admins.cfg 文件\nleft 4 dead 2\\left4dead2\\addons\\sourcemod\\configs 目录下找到 admins_simple.ini 用 VS Code 或 UltraEdit 打开, 并在最后加入\n\u0026#34;007\u0026#34; \u0026#34;99:z\u0026#34; \u0026#34;007\u0026#34; 前面的 007 表示游戏名字\n中间的 99:z 表示最高权限 (具体参考同目录下的 admin_levels.cfg 文件)\n后面的 007 表示管理员的密码\n保存时, 游戏名字如为中文, 需要另存为 UTF-8 编码\n同目录下找到 core.cfg\n\u0026#34;PassInfoVar\u0026#34; \u0026#34;_password\u0026#34; 将 _password 改为 _pass\n注意: _ 该值前必须带有哦\n6. 设置 Autoexec.cfg\rleft 4 dead 2\\left4dead2\\cfg\\ 目录下找到 autoexec.cfg (没有的话自己创建)\n在其输入:\nsetinfo \u0026#34;_pass\u0026#34; \u0026#34;007\u0026#34; 007 为刚才所设置的密码\n7. 测试\r运行 srcds.exe\n在 srcds.exe 中的控制台输入: meta list 如果显示以下信息表示成功\nListing 3 plugins: [01] SourceMod (1.3.0-dev) by AlliedModders LLC [02] SDK Tools (1.3.0-dev) by AlliedModders LLC [03] BinTools (1.3.0-dev) by AlliedModders LLC 8. 使用帮助及命令\r进入游戏按 ~ 呼出控制台或在 srcds.exe 的控制台输入 meta 即可获得其相关命令, 如下:\nMetamod:Source Menu usage: meta \u0026lt;command\u0026gt; [arguments] alias - List or set an alias clear - Unload all plugins forcefully cmds - Show plugin commands cvars - Show plugin cvars credits - About Metamod:Source force_unload - Forcefully unload a plugin game - Information about GameDLL info - Information about a plugin list - List plugins load - Load a plugin pause - Pause a running plugin refresh - Reparse plugin files retry - Attempt to reload a plugin unload - Unload a loaded plugin unpause - Unpause a paused plugin version - Version information 在游戏中按 Y 或 U 输入 !admin 即可获得管理菜单\n其他的插件有的也有相关的命令.\n插件安装教学\rSP 格式 - 此为源码\n放入 addons\\sourcemod\\scripting\n并将文件拖到 compile.exe 文件上, 将自动在 compiled 文件夹里生成 smx 格式 的文件\n再将其编译好的文件复制到 addons\\sourcemod\\plugins 即可\nSMX 格式 - 此为已编译好的文件\n直接放入 addons\\sourcemod\\plugins 即可\n关于 CFG - 此为插件的相关参数文件\n位置在 left 4 dead 2\\left4dead2\\cfg\\sourcemod\n参数文件与插件文件名是一样的. 不过格式是 cfg\n如果此目录没有插件的 cfg文件. 那么请启动 srcds.exe, 开一次服务器然后关闭即可自动生成\n插件索引\r插件论坛 - AlliedModders\n格林机枪 - [L4D \u0026amp; L4D2] Mini Gun Spawner (1.9) [11-Dec-2022]\nmini 机枪 - [L4D] Spawn Minigun\n破解 L4D2 多人限制 - L4DToolZ Metamod plugin (l4d1 \u0026amp; l4d2)\nBackpack 背包 - Backpack by Oshroth\n角色选择菜单 - [L4D/L4D2] Character Select Menu (2.5a/b)\nTank 血条 - [L4D2] Tank Health Gauge\n卫星炮 - [L4D2] Satellite Cannon\n[EXTENSION] Left 4 Downtown 2 (0.5.4.2) - L4D2 Only, Updated Left4Downtown\n[L4D(2)] Remove Lobby Reservation (When Full)\n原文\n求生之路2(Left 4 Dead 2) SourceMod+插件 综合帖子\n","date":"2016-11-27T23:52:00+08:00","permalink":"https://blog.acesheep.com/p/left-4-dead-2-sourcemod-plugins/","title":"求生之路 2 (Left 4 Dead 2) SourceMod + 插件"},{"content":"有时候你发现用 root 权限都不能修改某个文件, 大部分原因是曾经用 chattr 命令锁定该文件了。chattr 命令的作用很大, 其中一些功能是由 Linux 内核版本来支持的, 不过现在生产绝大部分跑的 linux 系统都是 2.6 以上内核了。通过 chattr 命令修改属性能够提高系统的安全性, 但是它并不适合所有的目录。chattr 命令不能保护 /、/dev、/tmp、/var目录。lsattr 命令是显示 chattr 命令设置的文件属性。\n这两个命令是用来查看和改变文件、目录属性的, 与 chmod 这个命令相比, chmod 只是改变文件的读写、执行权限, 更底层的属性控制是由 chattr 来改变的。\nchattr 命令的用法:\nchattr [ -RVf ] [ -v version ] [ mode ] files… 最关键的是在 [mode] 部分, [mode] 部分是由 +-= 和 [ASacDdIijsTtu] 这些字符组合的, 这部分是用来控制文件的属性。\n+ : 在原有参数设定基础上, 追加参数。 - : 在原有参数设定基础上, 移除参数。 = : 更新为指定参数设定。 A: 文件或目录的 atime (access time)不可被修改(modified), 可以有效预防例如手提电脑磁盘I/O错误的发生。 S: 硬盘I/O同步选项, 功能类似sync。 a: 即append, 设定该参数后, 只能向文件中添加数据, 而不能删除, 多用于服务器日志文件安全, 只有root才能设定这个属性。 c: 即compresse, 设定文件是否经压缩后再存储。读取时需要经过自动解压操作。 d: 即no dump, 设定文件不能成为dump程序的备份目标。 i: 设定文件不能被删除、改名、设定链接关系, 同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助。 j: 即journal, 设定此参数使得当通过mount参数: data=ordered 或者 data=writeback 挂 载的文件系统, 文件在写入时会先被记录(在journal中)。如果filesystem被设定参数为 data=journal, 则该参数自动失效。 s: 保密性地删除文件或目录, 即硬盘空间被全部收回。 u: 与s相反, 当设定为u时, 数据内容其实还存在磁盘中, 可以用于undeletion。 各参数选项中常用到的是a和i。a选项强制只可添加不可删除, 多用于日志系统的安全设定。而i是更为严格的安全设定, 只有superuser (root) 或具有CAP_LINUX_IMMUTABLE处理能力 (标识) 的进程能够施加该选项。 应用举例:\n用 chattr 命令防止系统中某个关键文件被修改:\nchattr +i /etc/resolv.conf 然后用 mv /etc/resolv.conf 等命令操作于该文件, 都是得到 Operation not permitted 的结果。\nvim 编辑该文件时会提示 W10: Warning: Changing a readonly file 错误。\n要想修改此文件就要把 i 属性去掉: chattr -i /etc/resolv.conf\nlsattr /etc/resolv.conf # 会显示如下属性 ----i-------- /etc/resolv.conf 让某个文件只能往里面追加数据, 但不能删除, 适用于各种日志文件:\nchattr +a /var/log/messages 本次使用目录 /usr/bin/ /usr/bin/wget ","date":"2016-11-11T11:52:00+08:00","permalink":"https://blog.acesheep.com/p/linux-chattr-and-lsattr-guide/","title":"Linux chattr 与 lsattr 命令详解"},{"content":"看到很多 qq 好友的气泡聊天窗口超炫, 有没有很羡慕啊？没有!!\n这个其实是用了一个软件! 软件最后更新于 2016年10月24日 不确保可以使用的时效性!!!\n这个软件可以帮你扫描账号下可以用的气泡 并且可以看到每个气泡的图片\n程序源代码 解压密码: blog.acesheep.com\n启动步骤\n将 img 文件夹 和 程序源码放在一个目录里面\n调试程序源码\n用快捷登录 登录你需要变换气泡的号码\n点击开始 会自动帮你把可以变换的气泡号码筛选出来.\n可以把获取到的数据库先保存下来, 不建议每次使用都扫描, 因为有扫描限制(5小时内不能超过500次)\n导出的文件在运行目录, 若关闭程序之后还需使用只需把 txt 文件拖到软件里即可, 会自动还原关闭前的数据库.\n可以选择自动变化气泡 也可以手动变化气泡\n当下面显示OK 说明替换成功!! 不要需要继续点替换!!\n就可以愉快的玩耍了!!!!\n要注意的问题: 需要一直开着软件才可以变化气泡.\n如果拿到了新的 气泡权限必须重建一个数据库才可以随机到新的气泡\n软件不可以被编译, 只可以开源分享, 你可以修改代码, 必须开源分享!!!\n随时都有可能失效\n最后测试 2017年1月22日 14:31:13\n","date":"2016-10-24T03:46:00+08:00","permalink":"https://blog.acesheep.com/p/d96d9a969dbc95d1affad8da38dfcc6c/","title":"QQ 随机聊天气泡"},{"content":"准备条件\r系统: CentOS 7 ARM\n检查日志\r读取 /var/log/secure, 查找关键字 Failed, 例如 (注: 文中的IP地址特意做了删减)\nSep 17 09:08:09 localhost sshd[29087]: Failed password for root from 13.7.3.6 port 44367 ssh2\rSep 17 09:08:20 localhost sshd[29087]: Failed password for root from 13.7.3.6 port 44367 ssh2\rSep 17 09:10:02 localhost sshd[29223]: Failed password for root from 13.7.3.6 port 56482 ssh2\rSep 17 09:10:14 localhost sshd[29223]: Failed password for root from 13.7.3.6 port 56482 ssh2 从这些行中提取IP地址, 如果次数达到 5次则将该IP写到 /etc/hosts.deny 中。\n编写脚本\r先把始终允许的IP填入 /etc/hosts.allow , 这很重要！比如\nsshd:19.16.18.1:allow sshd:19.16.18.2:allow 脚本 /root/secure_ssh.sh\n#! /bin/bash cat /var/log/secure|awk \u0026#39;/Failed/{print $(NF-3)}\u0026#39;|sort|uniq -c|awk \u0026#39;{print $2\u0026#34;=\u0026#34;$1;}\u0026#39; \u0026gt; /root/black.txt DEFINE=\u0026#34;5\u0026#34; for i in `cat /root/black.txt` do IP=`echo $i |awk -F= \u0026#39;{print $1}\u0026#39;` NUM=`echo $i|awk -F= \u0026#39;{print $2}\u0026#39;` if [ $NUM -gt $DEFINE ];then grep $IP /etc/hosts.deny \u0026gt; /dev/null if [ $? -gt 0 ];then echo \u0026#34;sshd:$IP:deny\u0026#34; \u0026gt;\u0026gt; /etc/hosts.deny fi fi done 这里要注意换行符格式问题 要用 UNIX 换行符\n将 secure_ssh.sh 脚本放入 cron计划任务, 每 1 分钟执行一次。\n# crontab -e */1 * * * * sh /root/secure_ssh.sh 测试\r开两个终端窗口, 一个 ssh 连上服务器, 另一个用错误的密码连接服务器几次。\n很快, 服务器上黑名单文件里已经有记录了:\n[root@ ~]# cat /root/black.txt 13.26.21.27=3 再看看服务器上的 hosts.deny\n[root@ ~]# cat /etc/hosts.deny sshd:13.7.3.6:deny sshd:92.4.0.4:deny sshd:94.10.4.2:deny sshd:94.4.1.6:deny sshd:11.64.11.5:deny 从另一个终端窗口继续 \u0026ldquo;暴力\u0026rdquo; 连接服务器\n看看服务器上的黑名单文件:\n[root@ ~]# cat black.txt 13.26.21.27=6 再看看服务器上的 hosts.deny\n[root@ ~]# cat /etc/hosts.deny sshd:13.7.3.6:deny sshd:92.4.0.4:deny sshd:94.10.4.2:deny sshd:94.4.1.6:deny sshd:11.64.11.5:deny sshd:13.26.21.27:deny 原文\nSSH访问控制,多次失败登录即封掉IP,防止暴力破解\n","date":"2016-10-10T13:05:00+08:00","permalink":"https://blog.acesheep.com/p/linux-ssh-brute-force-detection-and-blocking/","title":"Linux 监控 ssh 爆破并封禁 ip"},{"content":"防火墙相关概念\r此处先描述一些相关概念。\n从逻辑上讲。防火墙可以大体分为主机防火墙和网络防火墙。\n主机防火墙: 针对于单个主机进行防护。\n网络防火墙: 往往处于网络入口或边缘, 针对于网络入口进行防护, 服务于防火墙背后的本地局域网。\n网络防火墙和主机防火墙并不冲突, 可以理解为, 网络防火墙主外 (集体), 主机防火墙主内 (个人)。\n从物理上讲, 防火墙可以分为硬件防火墙和软件防火墙。\n硬件防火墙: 在硬件级别实现部分防火墙功能, 另一部分功能基于软件实现, 性能高, 成本高。\n软件防火墙: 应用软件处理逻辑运行于通用硬件平台之上的防火墙, 性能低, 成本低。\n那么在此处, 我们就来聊聊 Linux 的 iptables\niptables 其实不是真正的防火墙, 我们可以把它理解成一个客户端代理, 用户通过 iptables 这个代理, 将用户的安全设定执行到对应的\u0026quot;安全框架\u0026quot;中, 这个\u0026quot;安全框架\u0026quot;才是真正的防火墙, 这个框架的名字叫 netfilter\nnetfilter 才是防火墙真正的安全框架 (framework), netfilter 位于内核空间。\niptables 其实是一个命令行工具, 位于用户空间, 我们用这个工具操作真正的框架。\nnetfilter/iptables (下文中简称为iptables) 组成 Linux 平台下的包过滤防火墙, 与大多数的Linux软件一样, 这个包过滤防火墙是免费的, 它可以代替昂贵的商业防火墙解决方案, 完成封包过滤、封包重定向和网络地址转换 (NAT) 等功能。\nNetfilter 是 Linux 操作系统核心层内部的一个数据包处理模块, 它具有如下功能:\n网络地址转换 (Network Address Translate)\n数据包内容修改\n以及数据包过滤的防火墙功能\n所以说, 虽然我们使用 service iptables start 启动 iptables \u0026ldquo;服务\u0026rdquo;, 但是其实准确的来说, iptables 并没有一个守护进程, 所以并不能算是真正意义上的服务, 而应该算是内核提供的功能。\niptables 基础\r我们知道 iptables 是按照规则来办事的, 我们就来说说规则 (rules), 规则其实就是网络管理员预定义的条件, 规则一般的定义为\u0026quot;如果数据包头符合这样的条件, 就这样处理这个数据包\u0026quot;。规则存储在内核空间的信息包过滤表中, 这些规则分别指定了源地址、目的地址、传输协议 (如TCP、UDP、ICMP) 和服务类型 (如HTTP、FTP和SMTP) 等。当数据包与规则匹配时, iptables就根据规则所定义的方法来处理这些数据包, 如放行 (accept)、拒绝 (reject) 和丢弃 (drop) 等。配置防火墙的主要工作就是添加、修改和删除这些规则。\n这样说可能并不容易理解, 我们来换个容易理解的角度, 从头说起.\n当客户端访问服务器的web服务时, 客户端发送报文到网卡, 而 tcp/ip 协议栈是属于内核的一部分, 所以, 客户端的信息会通过内核的 TCP 协议传输到用户空间中的 web 服务中, 而此时, 客户端报文的目标终点为 web 服务所监听的套接字 (IP: Port) 上, 当web服务需要响应客户端请求时, web服务发出的响应报文的目标终点则为客户端, 这个时候, web服务所监听的IP与端口反而变成了原点, 我们说过, netfilter 才是真正的防火墙, 它是内核的一部分, 所以, 如果我们想要防火墙能够达到\u0026quot;防火\u0026quot;的目的, 则需要在内核中设置关卡, 所有进出的报文都要通过这些关卡, 经过检查后, 符合放行条件的才能放行, 符合阻拦条件的则需要被阻止, 于是, 就出现了 input 关卡和 output 关卡, 而这些关卡在 iptables 中不被称为\u0026quot;关卡\u0026quot;, 而被称为\u0026quot;链\u0026quot;。\n其实我们上面描述的场景并不完善, 因为客户端发来的报文访问的目标地址可能并不是本机, 而是其他服务器, 当本机的内核支持 IP_FORWARD 时, 我们可以将报文转发给其他服务器, 所以, 这个时候, 我们就会提到iptables中的其他\u0026quot;关卡\u0026quot;, 也就是其他\u0026quot;链\u0026quot;, 他们就是 \u0026ldquo;路由前\u0026rdquo;、\u0026ldquo;转发\u0026rdquo;、\u0026ldquo;路由后\u0026rdquo;, 他们的英文名是\nPREROUTING、FORWARD、POSTROUTING\n也就是说, 当我们启用了防火墙功能时, 报文需要经过如下关卡, 也就是说, 根据实际情况的不同, 报文经过\u0026quot;链\u0026quot;可能不同。如果报文需要转发, 那么报文则不会经过 input 链发往用户空间, 而是直接在内核空间中经过 forward 链和 postrouting 链转发出去的。\n所以, 根据上图, 我们能够想象出某些常用场景中, 报文的流向:\n到本机某进程的报文: PREROUTING \u0026ndash;\u0026gt; INPUT\n由本机转发的报文: PREROUTING \u0026ndash;\u0026gt; FORWARD \u0026ndash;\u0026gt; POSTROUTING\n由本机的某进程发出报文 (通常为响应报文): OUTPUT \u0026ndash;\u0026gt; POSTROUTING\n链的概念\r现在, 我们想象一下, 这些\u0026quot;关卡\u0026quot;在 iptables 中为什么被称作\u0026quot;链\u0026quot;呢？我们知道, 防火墙的作用就在于对经过的报文匹配\u0026quot;规则\u0026quot;, 然后执行对应的\u0026quot;动作\u0026quot;,所以, 当报文经过这些关卡的时候, 则必须匹配这个关卡上的规则, 但是, 这个关卡上可能不止有一条规则, 而是有很多条规则, 当我们把这些规则串到一个链条上的时候, 就形成了\u0026quot;链\u0026quot;,所以, 我们把每一个\u0026quot;关卡\u0026quot;想象成如下图中的模样 , 这样来说, 把他们称为\u0026quot;链\u0026quot;更为合适, 每个经过这个\u0026quot;关卡\u0026quot;的报文, 都要将这条\u0026quot;链\u0026quot;上的所有规则匹配一遍, 如果有符合条件的规则, 则执行规则对应的动作。\n表的概念\r我们再想想另外一个问题, 我们对每个\u0026quot;链\u0026quot;上都放置了一串规则, 但是这些规则有些很相似, 比如, A类规则都是对IP或者端口的过滤, B类规则是修改报文, 那么这个时候, 我们是不是能把实现相同功能的规则放在一起呢, 必须能的。\n我们把具有相同功能的规则的集合叫做\u0026quot;表\u0026quot;, 所以说, 不同功能的规则, 我们可以放置在不同的表中进行管理, 而iptables已经为我们定义了4种表, 每种表对应了不同的功能, 而我们定义的规则也都逃脱不了这4种功能的范围, 所以, 学习iptables之前, 我们必须先搞明白每种表 的作用。\niptables 为我们提供了如下规则的分类, 或者说, iptables为我们提供了如下\u0026quot;表\u0026quot;\nfilter表: 负责过滤功能, 防火墙；内核模块: iptables_filter nat表: network address translation, 网络地址转换功能；内核模块: iptable_nat mangle表: 拆解报文, 做出修改, 并重新封装 的功能；iptable_mangle raw表: 关闭nat表上启用的连接追踪机制；iptable_raw 也就是说, 我们自定义的所有规则, 都是这四种分类中的规则, 或者说, 所有规则都存在于这4张\u0026quot;表\u0026quot;中。\n表链关系\r但是我们需要注意的是, 某些\u0026quot;链\u0026quot;中注定不会包含\u0026quot;某类规则\u0026quot;, 就像某些\u0026quot;关卡\u0026quot;天生就不具备某些功能一样, 比如, A\u0026quot;关卡\u0026quot;只负责打击陆地敌人, 没有防空能力, B\u0026quot;关卡\u0026quot;只负责打击空中敌人, 没有防御步兵的能力, C\u0026quot;关卡\u0026quot;可能比较NB, 既能防空, 也能防御陆地敌人, D\u0026quot;关卡\u0026quot;最屌, 海陆空都能防。\n那让我们来看看, 每个\u0026quot;关卡\u0026quot;都有哪些能力, 或者说, 让我们看看每个\u0026quot;链\u0026quot;上的规则都存在于哪些\u0026quot;表\u0026quot;中。\n我们还是以图为例, 先看看prerouting\u0026quot;链\u0026quot;上的规则都存在于哪些表中。\n注意: 下图只用于说明prerouting链上的规则存在于哪些表中, 并没有描述表的顺序。\n这幅图是什么意思呢？它的意思是说, prerouting\u0026quot;链\u0026quot;只拥有nat 表、raw 表和 mangle 表所对应的功能, 所以, prerouting 中的规则只能存放于 nat 表、raw 表和 mangle 表中。\n那么, 根据上述思路, 我们来总结一下, 每个\u0026quot;关卡\u0026quot;都拥有什么功能, 或者说, 每个\u0026quot;链\u0026quot;中的规则都存在于哪些\u0026quot;表\u0026quot;中。\nPREROUTING 的规则可以存在于: raw表, mangle表, nat表。 INPUT 的规则可以存在于: mangle表, filter表, (centos7 中还有 nat 表, centos6 中没有)。 FORWARD 的规则可以存在于: mangle表, filter表。 OUTPUT 的规则可以存在于: raw表mangle表, nat表, filter表。 POSTROUTING 的规则可以存在于: mangle表, nat表。 但是, 我们在实际的使用过程中, 往往是通过\u0026quot;表\u0026quot;作为操作入口, 对规则进行定义的, 之所以按照上述过程介绍 iptables, 是因为从 \u0026ldquo;关卡\u0026rdquo; 的角度更容易从入门的角度理解, 但是为了以便在实际使用的时候, 更加顺畅的理解它们, 此处我们还要将各\u0026quot;表\u0026quot;与\u0026quot;链\u0026quot;的关系罗列出来\n表 (功能) \u0026lt;\u0026ndash;\u0026gt; 链 (钩子):\nraw 表中的规则可以被哪些链使用: PREROUTING, OUTPUT\nmangle 表中的规则可以被哪些链使用: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING\nnat 表中的规则可以被哪些链使用: PREROUTING, OUTPUT, POSTROUTING (centos7 中还有 INPUT, centos6中没有)\nfilter 表中的规则可以被哪些链使用: INPUT, FORWARD, OUTPUT\n其实我们还需要注意一点, 因为数据包经过一个\u0026quot;链\u0026quot;的时候, 会将当前链的所有规则都匹配一遍, 但是匹配时总归要有顺序, 我们应该一条一条的去匹配, 而且我们说过, 相同功能类型的规则会汇聚在一张\u0026quot;表\u0026quot;中, 那么, 哪些\u0026quot;表\u0026quot;中的规则会放在\u0026quot;链\u0026quot;的最前面执行呢, 这时候就需要有一个优先级的问题, 我们还拿 prerouting \u0026ldquo;链\u0026quot;做图示。\nprerouting 链中的规则存放于三张表中, 而这三张表中的规则执行的优先级如下:\nraw \u0026ndash;\u0026gt; mangle \u0026ndash;\u0026gt; nat\n但是我们知道, iptables为我们定义了4张\u0026quot;表\u0026rdquo;,当他们处于同一条\u0026quot;链\u0026quot;时, 执行的优先级如下。\n优先级次序 (由高而低):\nraw \u0026ndash;\u0026gt; mangle \u0026ndash;\u0026gt; nat \u0026ndash;\u0026gt; filter\n但是我们前面说过, 某些链天生就不能使用某些表中的规则, 所以, 4张表中的规则处于同一条链的目前只有output链, 它就是传说中海陆空都能防守的关卡。\n为了更方便的管理, 我们还可以在某个表里面创建自定义链, 将针对某个应用程序所设置的规则放置在这个自定义链中, 但是自定义链接不能直接使用, 只能被某个默认的链当做动作去调用才能起作用, 我们可以这样想象, 自定义链就是一段比较\u0026quot;短\u0026quot;的链子, 这条\u0026quot;短\u0026quot;链子上的规则都是针对某个应用程序制定的, 但是这条短的链子并不能直接使用, 而是需要\u0026quot;焊接\u0026quot;在 iptables 默认定义链子上, 才能被 IPtables 使用, 这就是为什么默认定义的\u0026quot;链\u0026quot;需要把\u0026quot;自定义链\u0026quot;当做\u0026quot;动作\u0026quot;去引用的原因。这是后话, 后面再聊, 在实际使用时我们即可更加的明白。\n数据经过防火墙的流程\r结合上述所有的描述, 我们可以将数据包通过防火墙的流程总结为下图:\n我们在写Iptables规则的时候, 要时刻牢记这张路由次序图, 灵活配置规则。\n我们将经常用到的对应关系重新写在此处, 方便对应图例查看。\n链的规则存放于哪些表中 (从链到表的对应关系):\nPREROUTING 的规则可以存在于: raw表, mangle表, nat表。 INPUT 的规则可以存在于: mangle表, filter表, (centos7 中还有 nat 表, centos6 中没有)。 FORWARD 的规则可以存在于: mangle表, filter表。 OUTPUT 的规则可以存在于: raw表mangle表, nat表, filter表。 POSTROUTING 的规则可以存在于: mangle表, nat表。 表中的规则可以被哪些链使用 (从表到链的对应关系):\nraw 表中的规则可以被哪些链使用: PREROUTING, OUTPUT mangle 表中的规则可以被哪些链使用: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING nat 表中的规则可以被哪些链使用: PREROUTING, OUTPUT, POSTROUTING (centos7中还有INPUT, centos6中没有) filter 表中的规则可以被哪些链使用: INPUT, FORWARD, OUTPUT 下图中 nat 表在 centos7 中的情况就不再标明。\n规则的概念\r说了一圈又说回来了, 在上述描述中我们一直在提规则, 可是没有细说, 现在说说它。\n先说说规则的概念, 然后再通俗的解释它。\n规则: 根据指定的匹配条件来尝试匹配每个流经此处的报文, 一旦匹配成功, 则由规则后面指定的处理动作进行处理；\n那么我们来通俗的解释一下什么是 iptables 的规则, 之前打过一个比方, 每条\u0026quot;链\u0026quot;都是一个\u0026quot;关卡\u0026quot;, 每个通过这个\u0026quot;关卡\u0026quot;的报文都要匹配这个关卡上的规则, 如果匹配, 则对报文进行对应的处理, 比如说, 你我二人此刻就好像两个\u0026quot;报文\u0026quot;, 你我二人此刻都要入关, 可是城主有命, 只有器宇轩昂的人才能入关, 不符合此条件的人不能入关, 于是守关将士按照城主制定的\u0026quot;规则\u0026quot;, 开始打量你我二人, 最终, 你顺利入关了, 而我已被拒之门外, 因为你符合\u0026quot;器宇轩昂\u0026quot;的标准, 所以把你\u0026quot;放行\u0026quot;了, 而我不符合标准, 所以没有被放行, 其实, \u0026ldquo;器宇轩昂\u0026quot;就是一种\u0026quot;匹配条件\u0026rdquo;, \u0026ldquo;放行\u0026quot;就是一种\u0026quot;动作\u0026rdquo;, \u0026ldquo;匹配条件\u0026quot;与\u0026quot;动作\u0026quot;组成了规则。\n了解了规则的概念, 那我们来聊聊规则的组成部分,此处只是大概的将规则的结构列出, 后面的文章中会单独对规则进行总结。\n规则由匹配条件和处理动作组成。\n匹配条件\r匹配条件分为基本匹配条件与扩展匹配条件\n基本匹配条件:\n源地址 Source IP, 目标地址 Destination IP\n上述内容都可以作为基本匹配条件。\n扩展匹配条件:\n除了上述的条件可以用于匹配, 还有很多其他的条件可以用于匹配, 这些条件泛称为扩展条件, 这些扩展条件其实也是 netfilter 中的一部分, 只是以模块的形式存在, 如果想要使用这些条件, 则需要依赖对应的扩展模块。\n源端口 Source Port, 目标端口 Destination Port\n上述内容都可以作为扩展匹配条件\n处理动作\r处理动作在iptables中被称为target (这样说并不准确, 我们暂且这样称呼), 动作也可以分为基本动作和扩展动作。\n此处列出一些常用的动作, 之后的文章会对它们进行详细的示例与总结:\nACCEPT: 允许数据包通过。 DROP: 直接丢弃数据包, 不给任何回应信息, 这时候客户端会感觉自己的请求泥牛入海了, 过了超时时间才会有反应。 REJECT: 拒绝数据包通过, 必要时会给数据发送端一个响应的信息, 客户端刚请求就会收到拒绝的信息。 SNAT: 源地址转换, 解决内网用户用同一个公网地址上网的问题。 MASQUERADE: 是SNAT的一种特殊形式, 适用于动态的、临时会变的ip上。 DNAT: 目标地址转换。 REDIRECT: 在本机做端口映射。 LOG: 在/var/log/messages文件中记录日志信息, 然后将数据包传递给下一条规则, 也就是说除了记录以外不对数据包做任何其他操作, 仍然让下一条规则去匹配。 表 (table)\n包含4个表:\n4个表的优先级由高到低: raw\u0026ndash;\u0026gt;mangle\u0026ndash;\u0026gt;nat\u0026ndash;\u0026gt;filter\nraw: RAW 表只使用在 PREROUTING 链 和 OUTPUT 链上,因为优先级最高, 从而可以对收到的数据包在连接跟踪前进行处理。一但用户使用了 RAW 表,在某个链上,RAW 表处理完后,将跳过 NAT 表和 ip_conntrack 处理,即不再做地址转换和数据包的链接跟踪处理了. filter: 这个规则表是预设规则表, 拥有 INPUT、FORWARD 和 OUTPUT 三个规则链, 这个规则表顾名思义是用来进行封包过滤的理动作 net: 此规则表拥有 prerouting 和 postrouting 两个规则链, 主要功能为进行一对一、一对多、多对多等网址转译工作 (SNATDNAT) mangle: 此规则表拥有 prerouting、FORWARD、postrouting 三个规则链, 除了进行网址转译工作会改写封包外, 在某些特殊应用可能也必须去改写封包(ITL、TOS)或者是设定 MARK (将封包作记号, 以进行后续的过滤)这时就必须将这些工作定义在 mangles 规则表中 常用命令:\n-A 追加规则--\u0026gt;iptables -A INPUT -D 删除规则--\u0026gt;iptables -D INPUT 1(编号) -R 修改规则--\u0026gt;iptables -R INPUT 1 -s 192.168.12.0 -j DROP 取代现行规则, 顺序不变(1是位置) -I 插入规则--\u0026gt;iptables -I INPUT 1 --dport 80 -j ACCEPT 插入一条规则, 原本位置上的规则将会往后移动一个顺位 -L 查看规则--\u0026gt;iptables -L INPUT 列出规则链中的所有规则 -N 新的规则--\u0026gt;iptables -N allowed 定义新的规则 通用参数:\n-p 协议 例: iptables -A INPUT -p tcp -s源地址 例: iptables -A INPUT -s 192.168.1.1 -d目的地址 例: iptables -A INPUT -d 192.168.12.1 -sport源端口 例:iptables -A INPUT -p tcp --sport 22 -dport目的端口 例:iptables -A INPUT -p tcp --dport 22 -i指定入口网卡 例:iptables -A INPUT -i eth0 -o指定出口网卡 例:iptables -A FORWARD -o eth0 -j 指定要进行的处理动作\n常用的ACTION: DROP: 丢弃 REJECT: 明示拒绝 ACCEPT: 接受 SNAT基于原地址的转换 source--指定原地址 比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.1这个假设出来的外网地址: iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.1(外网有效ip) 这样, 只要是来自本地网络的试图通过网卡访问网络的, 都会被统统转换成172.16.100.1这个IP. MASQUERADE(动态伪装) --家用带宽获取的外网ip, 就是用到了动态伪装 iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE DNAT目标地址转换 destination-指定目标地址 iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -j DNAT --to-destination 172.16.100.2 10.18访问80端口转换到100.2上 MASQUERADE: 源地址伪装 REDIRECT: 重定向: 主要用于实现端口重定向 MARK: 打防火墙标记的 RETURN: 返回 在自定义链执行完毕后使用返回, 来返回原规则链。 链 (chain)\n每个表都有自己的一组内置链, 可以对链进行自定义, 这样就可以建立一组规则, filter 表中的 input、output 和 forward 链 匹配(match)\n每个iptables规则都包含一组匹配以及一个目标, iptables匹配指的是数据包必须匹配的条件, 只有当 数据包满足所有的匹配条件时, iptables才能根据由该规则的目标所指定的动作来处理该数据包 匹配都在iptable的命令行中指定 source--匹配源ip地址或网络 destination (-d)--匹配目标ip地址或网络 protocol (-p)--匹配ip值 in-interface (-i)--流入接口(例如, eth0) out-interface (-o)--流出接口 state--匹配一组连接状态 string--匹配应用层数据字节序列 comment--在内核内存中为一个规则关联多达256个字节的注释数据 目标(target)\niptables支持一组目标, 用于数据包匹配一条规则时触发一个动作 ACCEPT--允许数据包通过 DROP--丢弃数据包, 不对该数据包做进一步的处理, 对接收栈而言, 就好像该数据包从来没有被接收一样 LOG--将数据包信息记录到syslog REJECT--丢弃数据包, 同时发送适当的响应报文(针对TCP连接的TCP重要数据包或针对UDP数据包的ICMP端口不可达消息) RETURN--在调用链中继续处理数据包 默认配置文件\rvim /etc/sysconfig/iptables 策略文件 vim /etc/sysconfig/iptables-config 配置文件 iptables 缺省具有5条规则链\nprerouting(内到外) forward(转发) postrouting(外到内) input(输入) output(输出) 链管理命令 (这都是立即生效的)\r-P :设置默认策略的 (设定默认门是关着的还是开着的) 默认策略一般只有两种 iptables -P INPUT (DROP|ACCEPT) 默认是关的/默认是开的 比如: iptables -P INPUT DROP 这就把默认规则给拒绝了。并且没有定义哪个动作, 所以关于外界连接的所有规则包括Xshell连接之类的, 远程连接都被拒绝了 -F: FLASH, 清空规则链的(注意每个链的管理权限) iptables -t nat -F PREROUTING iptables -t nat -F 清空nat表的所有链 -N:NEW 支持用户新建一个链 iptables -N inbound_tcp_web 表示附在tcp表上用于检查web的。 -X: 用于删除用户自定义的空链 使用方法跟-N相同, 但是在删除之前必须要将里面的链给清空昂了 -E: 用来Rename chain主要是用来给用户自定义的链重命名 -E oldname newname -Z: 清空链, 及链中默认规则的计数器的 (有两个计数器, 被匹配到多少个数据包, 多少个字节) iptables -Z :清空 规则管理命令\r-A: 追加, 在当前链的最后新增一个规则 -I num : 插入, 把当前规则插入为第几条。 -I 3 :插入为第三条 -R num: Replays替换/修改第几条规则 格式: iptables -R 3 ………… -D num: 删除, 明确指定删除第几条规则 查看管理命令 \u0026ldquo;-L\u0026rdquo;\r附加子命令 -n: 以数字的方式显示ip, 它会将ip直接显示出来, 如果不加-n, 则会将ip反向解析成主机名。 -v: 显示详细信息 -vv -vvv :越多越详细 -x: 在计数器上显示精确值, 不做单位换算 --line-numbers : 显示规则的行号 -t nat: 显示所有的关卡的信息 扩展匹配\r隐含扩展: 对协议的扩展\r-p tcp :TCP协议的扩展。一般有三种扩展 --dport XX-XX: 指定目标端口,不能指定多个非连续端口,只能指定单个端口, 比如 --dport 21 或者 --dport 21-23 (此时表示21,22,23) --sport: 指定源端口 --tcp-fiags: TCP的标志位 (SYN,ACK, FIN,PSH, RST,URG) 对于它, 一般要跟两个参数: 1.检查的标志位 2.必须为1的标志位 --tcpflags syn,ack,fin,rst syn = --syn 表示检查这4个位, 这4个位中syn必须为1, 其他的必须为0。所以这个意思就是用于检测三次握手的第一次包的。对于这种专门匹配第一包的SYN为1的包, 还有一种简写方式, 叫做--syn -p udp: UDP协议的扩展 --dport --sport -p icmp: icmp数据报文的扩展 --icmp-type: echo-request(请求回显), 一般用8 来表示 所以 --icmp-type 8 匹配请求回显数据包 echo-reply (响应的数据包) 一般用0来表示 系统CentOS 7\n# 启动指令 systemctl start iptables # 重启指令 systemctl restart iptables # 关闭指令 systemctl stop iptables 命令笔记\n*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 1080 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT 原文\niptables详解 (1): iptables概念\niptables命令、规则、参数详解\n","date":"2016-09-25T19:25:00+08:00","image":"https://blog.acesheep.com/p/iptables-commands-and-rules-guide/3240312840_hu3405016227253320022.png","permalink":"https://blog.acesheep.com/p/iptables-commands-and-rules-guide/","title":"iptables 命令、规则、参数详解"},{"content":"systemd 是 Linux 系统中最新的初始化系统 (init), systemd 和 upstart 是竞争对手, ubantu 上使用的是 upstart 的启动方式, CentOS 7 上使用 systemd.\nsystemctl 是管理服务的主要工具, 它整合了 chkconfig 与 service 功能于一体。\nsystem: 系统启动和服务器守护进程管理器, 负责在系统启动或运行时, 激活系统资源, 服务器进程和其他进程, 字母 d 是守护进程 (daemon) 的缩写, systemd 这个名字的含义就是它要守护整个系统。\n服务\rsystemctl is-enabled nginx.service # 查询服务是否开机启动 systemctl is-active nginx.service # 查询某服务当前激活的状态, 如果启动会显示 active, 否则会显示 unknown systemctl enable nginx.service # 开机运行服务 systemctl disable nginx.service # 取消开机运行 systemctl start nginx.service # 启动服务 systemctl stop nginx.service # 停止服务 systemctl restart nginx.service # 重启服务 systemctl try-restart nginx.service # 已启动才重启, 否则不做任何操作 systemctl reload-or-try-restart nginx.service # 先加载, 然后再启动 systemctl reload nginx.service # 重新加载服务配置文件 systemctl status nginx.service # 查询服务运行状态 systemctl kill nginx.service # 杀死进程 系统\rsystemctl reboot # 重启机器 systemctl [ poweroff | halt ] # 关机 systemctl suspend # 挂起-睡眠-保存在內存 systemctl hibernate # 休眠-断电-保存在硬盘 systemctl hybrid-sleep # 混合休眠模式 (同时休眠到硬盘并挂起) systemctl rescue # 强制进入救援模式 systemctl emergency # 强制进入紧急救援模式 systemctl is-active [unit type] # 查看服务是否运行 systemctl is-enable [unit type] # 查看服务是否设置为开机启动 systemctl mask [unit type] # 注销指定服务 systemctl unmask [unit type] # 取消注销指定服务 systemctl list-units # 列出所有启动 unit systemctl list-unit-files # 列出所有启动文件 systemctl list-unit-files | grep firewalld systemctl list-units -t service -all # 列出所有 service 类型的 unit systemctl list-units -t service -all grep cpu # 列出 cpu电源管理机制的服务 systemctl list-units -t target -all # 列出所有 target systemctl get-default # 获得当前的运行级别 systemctl set-default multi-user.target # 设置默认的运行级别为 mulit-user systemctl isolate multi-user.target # 在不重启的情况下, 切换到运行级别mulit-user 下 systemctl isolate graphical.target # 在不重启的情况下, 切换到图形界面下 systemctl daemon-reload # 重新载入 systemd, 扫描新的或有变动的单元 systemctl -t help # 查看 Unit 类型 systemctl --failed # 显示启动失败的服务 systemctl list-dependencies # 查看服务的依赖关系 配置文件位置\r/usr/lib/systemd/system 每个服务最主要的启动脚本设置, 类似于之前的 /etc/initd.d\n/run/system/system 系统执行过程中所产生的服务脚本, 比上面的目录优先运行\n/etc/system/system 管理员建立的执行脚本, 类似于/etc/rc.d/rcN.d/Sxx 类的功能, 比上面目录优先运行, 在三者之中, 此目录优先级最高\n服务状态\rsystemctl list-units -t service -a 显示状态 loaded: unit 配置文件已处理 active (running): 一次或多次持续处理的运行 active (exited): 成功完成一次性的配置 active (waiting): 运行中, 等待一个事件 inactive: 不运行 enabled: 开机启动 disabled: 开机不启动 static: 开机不启动, 但可以被另一个启用的服务激活 运行级别\runit 配置文件: 以 .target 结尾的文件\nsystemctl list-unit-files -t target -all 0 -\u0026gt; runlevel0.target, poweroff.target 1 -\u0026gt; runlevel1.target, rescue.target 2 -\u0026gt; runlevel2.target, muti-user.target 3 -\u0026gt; runlevel3.target, mutil-user.target 4 -\u0026gt; runlevel4.target, multi-user.target 5 -\u0026gt; runlevel5.target, graphical.target 6 -\u0026gt; runlevel6.target, reboot.target Unit 类型\r查看 Unit 类型\n# systemctl -t help Available unit types: service # 定义系统服务 socket # 标识进程间通信用的 socket 文件, 也可以在系统启动时, 延迟启动服务, 实现按需启动 busname # target # 模拟实现 \u0026#34;运行级别\u0026#34; snapshot # 系统快照 device # 定义内核识别的设备 mount # 定义文件系统挂载点 automount # 文件系统的自动挂载点如: /misc 目录 swap # 表示 swap 设备 timer # 由 systemd 管理的计时器 path # 定义文件系统中的一个文件或目录使用, 常用于当文件系统变化时, 延迟激活服务, 如 spool 目录 slice # scope # Unit 文件格式\r以 # 开头的行后面的内容会被认为是注释\n布尔值\n开启: 1、yes、on、ture 关闭: 0、no、off、false 时间单位默认是 秒\nUnit 文件组成\r[Unit] : 定义 Unit 描述, 启动顺序, 依赖关系 [Service] : 与特定类型相关的专用选项, 此处为Service类型 [Install] : 定义由 systemctl enable 及 systemctl disable 命令在实现服务启用或禁用时用到的一些选项 [Unit] 选项\rDescription: 描述信息 before: 在哪些服务前启动 After: 定义服务的启动次序, 表示当前服务应该晚与哪些服务启动, 其功能与 before 相反 Requires: 依赖到的其他服务, 强依赖, 被依赖的服务无法激活时, 当前服务即无法激活 Wants: 依赖到的其他服务, 弱依赖 Conflicts: 定义服务间的冲突关系 [Service] 选项\rType: 服务启动类型 simple: 默认值, 这个 daemon 主要由 ExecStart 参数的命令行来启动, 启动后常驻于内存中 forking: 由 ExecStart 启动的程序透过spawns延伸出其他子程序来作为此 daemon 的主要服务。原生父程序在启动结束后就会终止 onshot: 用于执行一项任务, 随后立即退出的服务, 不会常驻于内存中 notify: 与 simple 相同, 但约定服务会在就绪后向 systemd 发送一个信号, 需要配合 NotifyAccess 来让 systemd 接收消息 idle: 与 simple 类似, 要执行这个 daemon 必须要所有的工作都顺利执行完毕后才会执行。这类的 daemon 通常是开机到最后才只能激活的服务 User: 用户 Group: 用户组 EnvironmentFile: 环境配置文件 ExeStart: 指明启动服务要运行命令或脚本的绝对路径 ExeStartPre: 在 ExecStart 前运行 ExeStartPost: 在 ExecStart 后运行 ExecStop: 停止服务运行的命令或脚本 Restart: 当设定 Restart=1 时, 则服务意外终止后, 总是自动重新启动此服务 [Install] 选项\rAlias: 别名, 可使用 systemctl command Alial.service RequiredBy: 被哪些服务所依赖, 强依赖 WantedBy: 被哪些服务所依赖, 弱依赖 Also: 安装本服务的时候还要安装别的相关服务 例子\r# vim /etc/systemd/system/transmission.service [Unit] Description=Transmission Service After=network.target [Service] LimitNOFILE=666666 User=user Group=user ExecStart=/usr/bin/transmission-daemon --log-error -f ExecStop=/usr/bin/killall -w -s 9 /usr/bin/transmission-daemon [Install] WantedBy=multi-user.target 普通用户模式\rsystemd 支持普通用户定义的 unit[s] 开机启动\n--user 不可省略, 因为默认是执行 systemctl [--system], 对于系统级 unit[s] 来说, 不必显式添加 --system 选项\nsystemctl --user enable/disable/start/stop/daemon-reload xxx.timer/xxx.service 用户自定义的 unit[s] 可以放置在如下四个位置 (按优先级从低到高排序)\n/usr/lib/systemd/user/ 这里存放的是各个软件包安装的服务。 ~/.local/share/systemd/user/ 这里存放的是HOME目录中已安装的软件包的单元。 /etc/systemd/user/ 这里存放的是由系统管理员维护的系统范围的用户服务。 ~/.config/systemd/user/ 这里存放的是用户自身的服务。 用户级 unit 与系统级 unit 相互独立, 不能互相关联或依赖 用户级 unit 运行环境用 default.target, 系统级通常用 multi-user.target 即使用户不登陆, 其定制的服务依然会启动 ","date":"2016-09-25T19:17:00+08:00","permalink":"https://blog.acesheep.com/p/centos-7-systemctl-guide/","title":"CentOS 7 systemctl 用法详解"},{"content":"树莓派 3 只有信用卡大小的单片机, 其系统基于 Linux. ARM 构架 CPU. 其强大的 CPU 如果只用 OpenWrt 其实太浪费了 而且 OpenWrt 网卡驱动不齐全基本需要自己再次安装. 甚至连板载 wifi 还有 HDMI AV 接口都无法使用这极大的浪费了树莓派 3 代的性能.\n树莓派自带的 raspbian 系统过于臃肿 作为服务器不需要的UI系统 一些基于 UI 的软件太多, 如果作为服务器的话不推荐使用. CentOS 7 支持树莓派 3 代以后 外接USB网卡基本插上就可以识别了 我这里有2个USB有线网卡(一个X宝, 一个苹果的 A1277) 1个无线网卡 (TL-WN821N) 全部都识别不需要再次安装驱动. 在 OpenWrt 全部都不识别而且驱动及其难找.\nShadowsocks是我们常用的代理工具, 它使用 socks5 协议, 而终端很多工具目前只支持 http 和 https 等协议, 对 socks5 协议支持不够好, 所以我们为终端设置 shadowsocks 的思路就是将 socks 协议转换成 http 协议, 然后为终端设置即可。windows 下一般软件自带了转换功能无需再次安装.\nshadowsocks 版本选择说明\rshadowsocks - Python version × 树莓派 CentOS 7 无法安装 pip shadowsocks-nodejs - Node.js version × 树莓派 CentOS 7 无 Node.js 环境 shadowsocks-go - Go version √ 树莓派 CentOS 7 有 Golang 环境 Go 版本运行效率高 shadowsocks-libev - C libev version × Linux 常见版本 树莓派 CentOS 7 缺少编译环境 shadowsocks-libuv - C libuv version × 我没见过的版本 教程相对较少 shadowsocks-erlang - Erlang version × 我没见过.. shadowsocks-dotcloud - Dotcloud PAAS version × 还是没见过的 准备阶段\r树莓派 3 代 B 型 CentOS 7 ARM版 golang 环境 (crypto支持库) shadowsocks-go 客户端 privoxy-3.0.28-1.fc31.armv7hl.rpm (截止2019年4月25日 最新版本) privoxy 比 polipo 要稳定许多\n安装系统\r下载系统: http://mirror.centos.org/altarch/7/isos/armhfp/\nwindows 使用 Win32DiskImager 烧录 img 镜像\nLinux 使用 dd 命令烧录\n准备系统\r用户名: root\n密码: centos\nyum update yum install screen vim wget iptables vsftpd iptables-servies golang -y reboot #重启 首先把 crypto 支持库解压到 /root/go/src/golang.org/x/crypto/ 目录\nGOPATH=/root/go go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-local rpm -ivh privoxy-3.0.28-1.fc31.armv7hl.rpm reboot #重启 到这里环境搭建完毕了!\n运行配置\r进入 screen 运行 ss\nscreen -S Shadowsocks 第一步, 进入 /root/go/bin/ 目录\ncd /root/go/bin/ 第二步, 运行 ./shadowsocks-local\n# 参数 shadowsocks-local -s server_address -p server_port -k password -m aes-128-cfb -b local_address -l local_port ./shadowsocks-local -s=\u0026#34;服务器ip\u0026#34; -p=服务器端口 -k=密码 -m=aes-256-cfb(加密方式) -b=\u0026#34;本地ip 默认填127.0.0.1\u0026#34; -l=8001 有服务器激活状态表示连接成功了\n按 Ctrl+a+d 退出屏幕!!\n运行代理 privoxy\r编辑配置文件 vim /etc/privoxy/config\n需要向文件里面添加 (按 i 编辑 ESC 结束编辑)\n#listen-address 本机IP地址:端口 listen-address 0.0.0.0:1080 #全网卡监听 forward-socks5 / 127.0.0.1:8001 . # socks5代理地址和端口 输入:wq 回车保存退出!! 启动: systemctl start privoxy\n查看状态: systemctl status privoxy\n现在就可以用手机家里的设备连接 HTTP 代理 苹果 iOS 也不需要 600 多的 surge 软件了\n","date":"2016-09-25T18:39:00+08:00","permalink":"https://blog.acesheep.com/p/8b6be8b8155476673f68ed3a06da4603/","title":"shadowsocks-go 客户端 +  privoxy + 树莓派3 (Centos7 ARM)"},{"content":"本人的树莓派使用的是 8G 的 TF卡。可是最近频繁提示 空间不足, df -h 看看已经用了 96% 了, 插到电脑上显示55.9M 可能是 windows 只能识别 fat32 这么多, 其他可能未被识别。\n我们到磁盘管理器中查看。\n还有4.35G没有被识别, 好下面我们将这4.35G放到树莓派中。\n执行如下命令！！！\nPS:磁盘操作命令操作不当可能会引起数据丢失, 无论有没有把握都必须备份重要的数据。\nfdisk /dev/mmcblk0 按 P 将看到的分区复制下来 /dev/mmcblk0p2 的 start 值, 122880。下面会用到 执行命令: d (删除分区2, 选择 2) 执行命令: p (按这时候应该是少了一个分区了) 执行命令: n (加分区) 执行命令: p (主要分区) 选择 2 在开始位置输入 start 的值, 如下图 122880, 看下图 后面的值默认即可 执行命令: p 执行命令: w 成功后如下图\n然后我们重启树莓派 reboot\n重启后登录SSH执行如下命令。\nsudo resize2fs /dev/mmcblk0p2 用于修复分区。\n执行成功后, 再次df看看。\nSize为 7.2G, 我的是8G的内存卡正常了, 使用率为38%\n","date":"2016-08-11T11:21:00+08:00","permalink":"https://blog.acesheep.com/p/raspberry-pi-partition-resizing/","title":"树莓派调整分区大小"},{"content":"利用 ettercap 进行 arp 欺骗\rroot 权限下打开 ettercap:\nettercap -C (curses UI) ettercap -G (GTK+ GUI) curses UI工作界面\nGTK+ UI工作界面\n这里以GTK+ UI为例, 打开ettercap之后, 选择 Sniff\u0026mdash;-Unified-sniffing, 然后选择网卡\n然后 Hosts\u0026mdash;Scan for hosts\u0026mdash;Hosts list, 此时可以看到目标主机ip (192.168.1.107)\n选定目标主机, 然后点 add to target 1,将目标主机添加到目标1;选定路由, 点 add to target 2,将路由添加到目标2\n如图, 添加成功！\n然后点 mitm \u0026mdash; arp posoning , 勾选 sniff remote connections\n之后 start \u0026mdash; start sniffing开始监听～\n点 view \u0026ndash; connections 开始查看连接\n双击链接查看详细信息\n截获到目标主机登录路由器的明文密码\n163 邮箱帐号密码\n在 Kali 下命令行输入:\narpspoof 的命令参数解释: -i 网卡 -t 目标IP 网关 arpspoof -i eth0 -t 192.168.1.106 192.168.1.1 利用 ettercap+driftnet 截获目标主机的图片数据流\r打开一个终端窗, root权限执行:\n# 对目标主机进行arp欺骗 ettercap -i wlan0 -Tq -M arp:remote /192.168.1.107/ /192.168.1.1/ 新建一个终端窗口, 执行:\n# 监听 wlan0 driftnet -i wlan0 效果图: (备用手机像素太烂, 大家见谅)\n被攻击主机界面\n此时攻击主机截取图片流界面\n利用 ettercap+dns 截获目标主机访问\r原文\n利用ettercap进行简单的arp欺骗和mitm攻击\nhttp://www.3fwork.com/b506/000099MYM019924/\nhttps://huirong.github.io/2015/03/25/arpspoof/\n","date":"2016-07-13T13:06:00+08:00","permalink":"https://blog.acesheep.com/p/kali-linux-arp-spoofing/","title":"Kali Linux ARP 攻击"},{"content":"先用这个查询网卡要修改的网卡\nAceSheeProdePro:~ AceSheep$ ifconfig 我需要改有线网口一般是 eth0 eth1 无线网的话就是 wlan0 wlan1 以此类推\nAceSheeProdePro:~ AceSheep$ sudo ifconfig en1 ether AA:66:66:66:66:66 en1 就是你要修改的那个网卡 默认是 en0 en1 en2\nAA:66:66:66:66:66 是你要修改的mac地址 0~F 一共6组\nAceSheeProdePro:~ AceSheep$ networksetup -detectnewhardware 最后重新启动网卡. 锵锵锵锵修改成功\nmac 10.11.5 测试有效\n","date":"2016-06-23T15:22:00+08:00","permalink":"https://blog.acesheep.com/p/change-mac-address-on-mac/","title":"Mac 电脑修改 mac 地址"},{"content":"扫描方式:\n全连接扫描, 三次握手 防火墙能有效拦截, 故很少使用 (产生大量日志, 很少使用) 半链接扫描, 三次握手前两次, 源SYN 目标 SYN/ACK 端口开放; 源 SYN 目标RST/ACK 端口关闭 (不记日志, 隐蔽性好) 秘密扫描, 发送 FIN, 返回 RST (端口关闭, 回复RST包；端口开放, 不回复) 半链接扫描与叫做间接扫描 FIN 扫描、Xmas 扫描、Null 扫描对 Windows 无效 nmap 类型 选项 目标 nmap [Scan Type(s)] [Options] {target specification} 类型:\nnmap -sT TCP扫描 全链接扫描 nmap -sS SYN扫描 半链接扫描 nmap -sF FIN扫描 秘密扫描 除SYN、ACK其它位置1 nmap -sX Xmas扫描 秘密扫描 FIN、URG、PUSH位置1 nmap -sN Null扫描 秘密扫描 标志位全为0, 发送TCP分组 nmap -sP ping扫描 同时使用ICMP和TCP ACK 80, 返回RST说明主机运行(外网) nmap -sU UDP扫描 发送0字节UDP包, 快速扫描Windows的UDP端口 nmap -sA ACK扫描 TCP ACK扫描, 当防火墙开启时, 查看防火墙有未过虑某端口 nmap -sV 打开系统版本检测 nmap -sW 滑动窗口扫描 nmap -sR RPC扫描 nmap -b FTP反弹攻击(FTP Bounce attack) 外网用户通过FTP渗透内网 选项:\nnmap -P0 Nmap扫描前不Ping目标主机,允许你关闭 ICMP pings nmap -PT Nmap扫描前使用TCP ACK包确定主机是否在运行 (-PT默认80) nmap -PS Nmap使用TCP SYN包进行扫描 nmap -PI Nmap进行Ping扫描 nmap -PB 结合-PT和-PI功能 nmap -O Nmap扫描TCP/IP指纹特征, 确定目标主机系统类型,尝试识别远程操作系统 nmap -I 反向标志扫描, 扫描监听端口的用户 nmap -f 分片发送SYN、FIN、Xmas、和Null扫描的数据包 nmap -v 冗余模式扫描, 详细输出扫描情况. nmap -oN 扫描结果重定向到文件 nmap -resume 使被中断的扫描可以继续 nmap -iL -iL,扫描目录文件列表 nmap -p -p扫描端口列表,默认扫描1-1024端口和/usr/share/nmap/nmap-services文件中指定端口；-p例: 23；20-30,139,60000- nmap -A 同时打开操作系统指纹和版本检测 nmap -F 快速扫描模式, 只扫描nmap-services文件中的端口 nmap -D 欺骗扫描, 可有效隐藏扫描者IP地址 nmap -S 在欺骗扫描时, 用来指定源主机IP nmap -e 指定从哪个网卡发送和接收数据包 nmap -g 指定扫描源端口 nmap -r 按顺序扫描端口 参数:\n192.168.10.1 192.168.10.0/24 192.168.*.* 192.168.0-255.0-255 例子:\n获取远程主机的系统类型及开放端口\nnmap -sS -P0 -sV -O \u0026lt;target\u0026gt; 原文\nhttp://blog.sina.com.cn/s/blog_62347f3c01019rwd.html\n","date":"2016-06-10T14:11:00+08:00","permalink":"https://blog.acesheep.com/p/nmap-scan-commands/","title":"Nmap 扫描命令汇总"},{"content":"准备材料\rSY6502 CPU CY62256 SRAM ","date":"2016-06-08T14:40:00+08:00","permalink":"https://blog.acesheep.com/p/81fe791a3887532cd20b8d7c258c3398/","title":"Apple 1 制作[未完成]"},{"content":"php7 编译参数\r./configure \\ --prefix=/usr/local/php7 \\ --exec-prefix=/usr/local/php7 \\ --bindir=/usr/local/php7/bin \\ --sbindir=/usr/local/php7/sbin \\ --includedir=/usr/local/php7/include \\ --libdir=/usr/local/php7/lib/php \\ --mandir=/usr/local/php7/php/man \\ --with-config-file-path=/usr/local/php7/etc \\ --with-mysql-sock=/var/lib/mysql/mysql.sock \\ --with-mhash \\ --with-mysqli \\ --with-pdo-mysql \\ --with-gd \\ --with-iconv \\ --with-zlib \\ --with-openssl \\ --enable-zip \\ --enable-inline-optimization \\ --disable-debug \\ --disable-rpath \\ --enable-shared \\ --enable-xml \\ --enable-bcmath \\ --enable-shmop \\ --enable-sysvsem \\ --enable-mbregex \\ --enable-mbstring \\ --enable-ftp \\ --enable-pcntl \\ --enable-sockets \\ --with-xmlrpc \\ --enable-soap \\ --without-pear \\ --with-gettext \\ --enable-session \\ --with-curl \\ --with-jpeg-dir \\ --with-freetype-dir \\ --enable-opcache \\ --enable-fpm \\ --with-fpm-user=php-fpm \\ --with-fpm-group=php-fpm \\ --without-gdbm \\ --enable-exif \\ --with-apxs2=/usr/bin/apxs phpize为php添加exif扩展库\r进入 exif 扩展库目录\ncd /root/php-7.2.0/ext/exif 调用 phpize 程序生成编译配置文件(如果不在扩展库目录下执行phpize命令会报错!i)\n[root@localhost exif]# /usr/local/php7/bin/phpize Configuring for: PHP Api Version: 20170718 Zend Module Api No: 20170718 Zend Extension Api No: 320170718 编译扩展库, 分别执行下面的 configure 和 make 命令\n./configure --with-php-config=/usr/local/php7/bin/php-config make -j12 make -j12 install 配置 php.ini\nvim /usr/local/php7/etc/php.ini 在 php.ini 文件中找到设置扩展目录的位置, 然后将扩展路径设置到 apache2 modules 目录下\nextension_dir = \u0026#34;/usr/local/php7/lib/php/extensions/no-debug-non-zts-20170718/\u0026#34;\rextension=exif.so 重启 apache, 查看 phpinfo 信息, 即可看到刚才添加进去的 exif 扩展库\n安装Xdebug\rXdebug官网: https://xdebug.org\nwget https://xdebug.org/files/xdebug-2.6.0alpha1.tgz tar -zxvf xdebug-2.6.0alpha1.tgz /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php7/bin/php-config make -j12 make -j12 install 配置 Xdebug, 修改 php.ini\n具体参数这里有说明 https://xdebug.org/docs/all_settings\n[Xdebug] extension=xdebug.so xdebug.remote_enable=1 xdebug.remote_autostart = 1 xdebug.remote_host=192.168.10. xdebug.remote_port=9000 ;xdebug.remote_connect_back = 1 ;日志记录 ;xdebug.profiler_enable=on ;xdebug.trace_output_dir=\u0026#34;/root/xdebug/trace.log\u0026#34; ;xdebug.profiler_output_dir=\u0026#34;/root/xdebug/profiler.log\u0026#34; 通过在请求里面带上 XDEBUG_SESSION 参数, 并且把参数值设置为之前 XDebug 里面配置的 idekey 的值, 就可以激活服务端的调试。\n例如, 可以在 POST 或者 GET 参数里面加上 XDEBUG_SESSION=AceSheep, 服务端就会启动调试了。\n比如我们要调试 http://www.abc.com/test.php, 那么访问链接 http://www.abc.com/test.php?XDEBUG_SESSION=AceSheep 就可以启动调试了。\n","date":"2016-02-28T00:40:00+08:00","permalink":"https://blog.acesheep.com/p/php-build-options/","title":"PHP 编译参数"},{"content":"境外服务器网络优化\r有两种优化网络的方法(都可以达到相同的效果):\n微林网桥 FinalSpeed 第一种 使用微林网桥——线路加速、服务器优化\r加速方式非常灵活有很多加速节点, 不但可以把VPN速度给国内提升还可以让服务器连接到个个运营商, 能达到带宽满速。手机也可以用。收费。\n网址: https://vnet.link/\n微林有一个服务, 叫vxTrans, 啥意思呢, 套用官方的一个解释:\n直接连接目标服务的情况下:\n您-\u0026gt;路由1-\u0026gt;路由2-\u0026gt;骨干网1-\u0026gt;骨干网2-\u0026gt;骨干网3-\u0026gt;路由4-\u0026gt;路由5-\u0026gt;路由6-\u0026gt;目标服务器 使用 vxTrans 时:\n您-\u0026gt;路由1-\u0026gt;vxTrans连接点-\u0026gt;目标服务器 由于 vxTrans 连接点处于您与目标服务之间, 并且拥有更好的路由, 因此 vxTrans 改善了原先您与目标服务的网络链路。\n说简单点, 就是提供了更快, 更好的网络路径。\n使用方法\r先注册, 网址在上面, 注册好后购买6元6G首次优惠流量。\n注册的时候记得勾上 vxTrans 服务, 没勾注册好后在设置里面添加也一样。\n然后进入 vxTrans 面板:\n第二步进入授权页, 授权自己的服务器:\n授权完成后, 进入连接点, 创建连接点, 添加加速端口, 选择加速节点\n填写完后点击【建立连接点】系统会分配一个网址, 和一个端口, 那么直接在ss/的客户端填入这个ip和端口就可, 密码和其他不用修改！\n有时候如果链路不给力, 你还可以套两层, 比如 我的vps——日本NTT——CN2——本地。当然, 这样就双计费了！\n实际效果还是非常明显的, vultr 直连如果是3000的话, CN2优化之后能达到20000甚至更高。当然, 这也是取决于在不在网络高峰期！\n总之就是速度快, 解决像我只有10MB带宽的可以看4K视频了码率在10000-9000, 流量烧得也快。不过用这个微林里面的 vxgg, 和别人联机玩全景缩水。\n第二种 FinalSpeed 服务端安装及教程\rFinalSpeed 是高速双边加速软件, 可加速所有基于 tcp 协议的网络服务, 在高丢包和高延迟环境下, 仍可达到 90% 的物理带宽利用率, 即使高峰时段也能轻松跑满带宽.\n可以压缩流量发包 (双边), 与 Net-Speeder 多发包不同的是, FinalSpeed 是压缩流量以增加传输成功率, 这样就不会多耗费 VPS 流量, 但是有可能对同机房的网络稳定造成影响。\n适用范围\n客户端: Windows、OS X (需要 java) 服务端: 在装有 SS 的 Windows 服务器或者 Linux 服务器 (Debian / CentOS / Ubuntu) 服务端架构要求: Openvz、KVM等, 适用于绝大部分 VPS, 包括 Banwagong 等廉价 VPS 项目运行需要安装 libpcap, windows 下为 winpcap 客户端启动类: net.fs.client.FSClient 服务端启动类: net.fs.server.FSServer 是一个开源的黑科技, 目前只能在电脑上面使用。手机暂时不能用。免费。\n本脚本适用环境:\n系统支持: CentOS 6, 7, Debian, Ubuntu 内存要求: ≥256M FinalSpeed 必须服务端和客户端同时配合使用, 否则没有任何加速效果 openvz 架构只支持 udp 协议 服务端可以和锐速共存, 互不影响. 在如下图依次输入以下代码: (一共3行)\nwget https://github.com/dupontjoy/customization/raw/master/Rules/Shadowsocks/Finalspeed/install_fs.sh chmod +x install_fs.sh ./install_fs.sh 2\u0026gt;\u0026amp;1 | tee install.log debian, ubuntu 下如果执行脚本出错, 请切换到 dash\n切换方法: sudo dpkg-reconfigure dash 选 no\n安装完后查看日志\ntail -f /fs/server.log 如果服务端正常运行会有类似以下提示:\n如果出现 java 运行失败的提示,说明脚本安装 java 失败, 需要手动安装 java\n卸载\nsh /fs/stop.sh ; rm -rf /fs 启动\nsh /fs/start.sh; tail -f /fs/server.log 重复运行启动会出现以下端口绑定错误,请先停止或直接重启服务.\n常用命令\n# 停止 sh /fs/stop.sh # 重新启动 sh /fs/restart.sh; tail -f /fs/server.log # 查看日志 tail -f /fs/server.log # 设置开机启动 chmod +x /etc/rc.local vi /etc/rc.local # 启动 sh /fs/start.sh 每天晚上3点自动重启\ncrontab -e 0 3 * * * sh /fs/restart.sh FinalSpeed 客户端\rWindows 版 - 运行需要 java 环境和 winpcap\nJava 版 支持 OS X, Linux\n系统需安装 java 运行环境, Linux 还需安装 libpcap\n# Ubuntu, Debian 安装 libpcap apt-get -y install libpcap-dev # CentOS 安装 libpcap yum -y install libpcap 注意问题\n服务器必须同时部署 FinalSpeed 服务端才能进行加速 客户端必须准确设置物理带宽, 最终加速的速度不会超过所设置的带宽值, 如果设置值高于实际带宽会造成丢包, 导致速度变慢 客户端首选 tcp 协议, 如果 tcp 不稳定, 请切换到 udp 若服务器为 openvz 架构, 客户端只能选择 udp 协议, 其他架构同时支持 tcp 和 udp 协议 windows 客户端使用 tcp 协议时不兼容锐速, 停止锐速后可以正常运行 FinalSpeed 不提供加密功能, 如有安全需求, 不要直接加速明文协议 原文\n第一个\n第二个\n","date":"2016-02-20T18:10:00+08:00","permalink":"https://blog.acesheep.com/p/vps-network-optimization/","title":"境外服务器 VPS 网络优化"},{"content":"Shadowsocks 问题合集\rShadowsocks 有几种版本？区别是什么？\r首先要明确一点, 不管 Shadowsocks 有几种版本, 都分为服务端和客户端, 服务端是部署在服务器 (VPS) 上的, 客户端是在你的电脑上使用的。\nShadowsocks 服务端大体上有 4 种版本, 按照程序语言划分, 分别为 Python, libev, Go , Nodejs, 目前主流使用前 3 种。\nShadowsocks 客户端几乎包括了所有的终端设备, PC, Mac, Android, iOS, Linux 等。\n其实作者已经作了详细总结, 包括 UDP 转发, 多用户等 Feature , 具体可参考《Feature Comparison across Different Versions》一文, 英文很简单, 耐心一点, 能看懂的。\nShadowsocks 的最低安装需求是多少？\r个人建议最少 128MB 内存, 因为在连接数比较多的情况下, 还是占用不少内存的, 如果内存不足, 进程就会被系统 kill 掉, 这时候就需要手动重启进程。当然, 低于 128MB 也是可以安装的, Go 版是二进制安装, 无需编译, 非常简单快捷, libev 版运行过程中, 占用内存较少, 可以搭建在 Openwrt 的路由器上。\n自己个人使用, 且连接数不是特别大的情况下, 64MB 内存也基本够用了。如果你要分享给朋友们一起使用, 最好还是选用大内存的。\n为什么我安装 (启动) Shadowsocks 失败？\r我只能说脚本并没有在所有的 VPS 上都测试过, 所以遇到问题是在所难免的。大部分情况下, 请参考《Troubleshooting》一文, 自行解决。据我所知, 很多人都是配置文件出了问题导致的启动失败。还有部分是改错了 iptables 导致的。\n在 Amazon EC2 , 百度云, 青云上启动失败, 连接不上怎么办？\n在这类云 VPS 上搭建, 需要注意, 配置服务器端时, 应使用内网IP；Amazon EC2 缺省不允许 inbound traffic, 需要在security group里配置允许连接的端口, 和开通SSH client连接类似, 这个在 Amazon EC2 使用指南里有说明。同样的, 青云, 百度云也差不多, 默认不允许入网流量, 网卡绑定的是内网IP, 因此需要将配置文件里的 server 值改为对应的内网 IP 后再重新启动。然后在云管理界面, 允许入网端口。\n我帮人设置了过之后, 才发觉这些云和普通的 VPS 不一样, 所以需要注意以上事项。\nShadowsocks 有没有控制面板？\r答案是有的, 有人基于 PHP + MySQL 写出来一个前端控制面板, 被很多人用来发布收费或免费的 Shadowsocks 服务。Github 地址如下: https://github.com/orvice/ss-panel\n具体怎么安装和使用, 别来问我, 自己研究去。\n多用户怎么开启？\rShadowsocks 有多种服务端程序, 目前据我所知只有 Python 和 Go 版是支持在配置文件里直接设置多端口的, 至于 libev 版则需要使用多个配置文件并开启多个实例才行。\n所谓的多用户, 其实就是把不同的端口给不同的人使用, 每个端口则对应不同的密码。Python 和 Go 版通过简单的修改单一配置文件, 然后重启程序即可。\n有没有必要简单学习 Linux ？\r很有必要。\n很多人问怎么修改配置文件, 你用 winscp 连接上你的 vps , 把配置文件下载到本地, 用记事本改吧改吧, 改完后再上传覆盖一下不就完了么。\n那为什么我还要建议你稍微懂一点 Linux 呢, 说白了就是懂一点 Shell 命令。\n看看这篇《Linux系统中常用操作命令》, 在 putty 或者 xshell 的界面里, 你用 vi 或者 nano 命令就能搞定配置文件, 这样多好。\n最后, 请仔细阅读下面的话, 姑且称之为作者有话说\rShadowsocks 没有办法离开去中心化的服务器。要么自己花钱买 VPS, 要么用有人分享的账号, 要么用有人提供的付费服务, 他们各有所长, 适合不同的人。所以作为开发者, 保持中立, 不偏袒其中任何一方, 顺其自然发展下去是最好的吧。\n很多人要么一窝蜂的支持, 要么一窝蜂的反对, 还要把它给封禁掉, 大概这种心理鲁迅先生也曾批判过。如果你们真的那么讨厌商业, 那你们应该首先把你们的苹果设备给摔了, 因为它就是商业社会巅峰造极的产物。我反对不喜欢一个东西就要拿出简单粗暴的制裁手段, 正是这种习性成就了 GFW。\n维护这个项目到现在大概总共回复过几千个问题, 开始慢慢想清楚了一件事, 为什么会存在 GFW。从这些提问可以看出, 大部分人的自理能力都很差, 只是等着别人帮他。特别是那些从 App Store 下载了 App 用着公共服务器的人, 经常发来一封只有四个字的邮件: \u0026ldquo;不能用了？\u0026rdquo; 我觉得这是一个社会常识, 花一分钟写的问题, 不能期待一个毫无交情的陌生人花一个小时耐心地问你版本和操作步骤, 模拟出你的环境来帮你分析解决。\nWindows 版加上 GFWList 功能以来, 我反复呼吁给 GFWList 提交规则, 但是一个月过去了竟然一个提交都没有。如果没有人做一点什么, 它自己是不会更新的啊, 没有人会义务地帮你打理这些。我觉得, 政府无限的权力, 都是大部分人自己放弃的。假货坑爹, 让政府审核。孩子管不好, 让政府关网吧。房价太高, 让政府去限购。我们的文化实在太独特, 创造出了家长式威权政府, GFW 正是在这种背景下产生的, 一个社会矛盾的终极调和器, 最终生活不能自理的你每天做的每一件事情都要给政府审查一遍, 以免伤害到其他同样生活不能自理的人。这是一个零和游戏, 越和这样的用户打交道, 越对未来持悲观态度, 觉得 GFW 可能永远也不会消失, 而墙内的这个局域网看起来还似乎生机勃勃的自成一体, 真是让人绝望\n","date":"2016-02-20T17:12:00+08:00","permalink":"https://blog.acesheep.com/p/d3f92e0ca83bda0384684ab525518c91/","title":"Shadowsocks 问题合集"},{"content":"科学上网\r免费的 SS 账号, 大家可以去一些服务提供商购买 ss 账号, 但是这些账号是共用带宽, 浏览网页没问题, 但是看视频 (youtube 等) 就不行了, 如果你对 ss 的带宽有需求, 那么这篇文章就适合你。 SS全称是 Shadowsocks 租用境外虚拟服务器\r搭建SS服务端还是VPN服务端, 我们首先要有一台境外 VPS。\n所以首先咱们先租一个 vps, 提供 vps 的服务商有很多, 比较出名的有 Lindeo, DO, vultr, 当然还有比较便宜的版瓦工。\n本 Linode、vultr、DO 都有, 高峰时期看哪个带宽高用哪个。\nLinode: 名气最大的 vps 提供商, 东京主机国内链接速度非常快, 但是新用户买不了东京主机, 所以不推荐。 DO: 旧金山的服务器还行, 我用的非高峰时期看 youtube 大概有 15000~20000 的速度, 看 4k 无压力 vultr: 比较推荐, 价格便宜, 可以用 paypal 付款, 有东京服务器, 5 刀一个月, 400G 流量, 绝对够用了。 这几个虚拟服务器对比可以点这里 因为朕已经在 vultr 有个 VPN 的服务器了, 不过直连 VPN 速度不是很理想, 看视频只能看 144P 的。简直卡的要死要死。\n进入首页后输入邮箱密码注册, 这个谁都会。注册好后用 paypal 充值5刀 (一般会5~10刀的赠送,我没遇到), 然后会到以下界面选择服务器配置:\n按如图所示选择即可, 当然, 这个是可以在科学上网的同时, 私有云, 当然如果要多人使用建议买内存大的, 可以选择更贵一点的服务器。\n服务器: 日本\n系统: CentoOS 7 x64\n其他的可以个性化。\n如果只是科学上网一两个人同时使用, 选 5 刀一个月的即可。(扣款是按小时扣的, 满一个月的时间就按照月的价格结算, 如果长时间不用, 可以把服务器删了, 用的时候再开一个服务器重新配置)\n选择好用服务器初始化需要一点时间, 大概5分钟左右。\n只有点击上图服务器右边的 Manage 进入管理页面\n这里需要下载图中所示软件: putty 点我下载 官网下载 (如果有 linux 的可以直接在终端连接, 这里以 Windows 演示)\n填入服务器 ip, 端口 22 不用修改, 之后点下方 open 后如下图\n第一次连接会出现这个提示:\n这个是连接 Linux 服务器的指纹, 加密连接, 确定即可。\n用户名root, 然后回车\n然后要求输入密码, 密码在管理页面的 root密码\n没用过 linux 的同学这里我要说明一下, 你输密码的时候, 光标是不动的, 也就是你看不见你输了几位密码, 也看不见光标动, 反正你按照密码输完, 回车即可。\n当然你可以复制密码, 方法是, 在网页上复制密码后, 在 putty 界面按鼠标右键, 即为粘贴, 回车即可。\n进入系统后如下图:\nSS 服务端搭建\r紧接上一步 (如果租用的不是 vultr 的服务器, 使用其他提供商的话, 只要在配置服务器的时候使用 Ubuntu 14.04 LTS 操作系统)\n这里我们使用 秋水逸冰 的一键安装代码\n本脚本适用环境: (脚本备份下载)\n系统支持: CentOS 6, 7, Debian, Ubuntu\n内存要求: ≥128M\n日期: 2015年08月28日\n在如上图依次输入以下代码: (一共3行)\nwget --no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh chmod +x shadowsocks.sh ./shadowsocks.sh 2\u0026gt;\u0026amp;1 | tee shadowsocks.log 出现如下页面, 这里是让你输入密码, 自己输一个吧。\n密码输入好回车界面如下, 这里是让你输入端口, 默认是 8989, 不更改直接回车即可\n之后会有一段时间的等待, 中间不要关闭putty, 等着即可\n大约需要几分钟的时间 (根据你选的 CPU 决定), 好了后的页面如下:\n记录:\n第一行的 ip 第二行的端口 第三行的密码 第六行的加密方式 (第四行是服务器内网 ip, 第五行是内网端口, 不用管)\n搭建完成啦！！！\nSS 多用户实现方法:\n单用户的配置文: /etc/shadowsocks.json\n使用命令: vi /etc/shadowsocks.json\n内容如下:\n{ \u0026#34;server\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;server_port\u0026#34;: 8989, \u0026#34;local_address\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;local_port\u0026#34;: 1080, \u0026#34;password\u0026#34;: \u0026#34;yourpassword\u0026#34;, \u0026#34;timeout\u0026#34;: 300, \u0026#34;method\u0026#34;: \u0026#34;aes-256-cfb\u0026#34;, \u0026#34;fast_open\u0026#34;: false } 修改为多用户配置文件:\n{ \u0026#34;server\u0026#34;: \u0026#34;0.0.0.0\u0026#34;, \u0026#34;local_address\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;local_port\u0026#34;: 1080, \u0026#34;port_password\u0026#34;: { \u0026#34;8989\u0026#34;: \u0026#34;password0\u0026#34;, \u0026#34;9001\u0026#34;: \u0026#34;password1\u0026#34;, \u0026#34;9002\u0026#34;: \u0026#34;password2\u0026#34;, \u0026#34;9003\u0026#34;: \u0026#34;password3\u0026#34;, \u0026#34;9004\u0026#34;: \u0026#34;password4\u0026#34; }, \u0026#34;timeout\u0026#34;: 300, \u0026#34;method\u0026#34;: \u0026#34;aes-256-cfb\u0026#34;, \u0026#34;fast_open\u0026#34;: false } 如上代码, 一个端口对应一个密码, 就为一个用户\n:wq 是保存命令, i 是编辑命令, 编辑完需要按 Esc 退出编辑模式才可以保存\n修改好后保存退出。\n/etc/init.d/shadowsocks restart 重启 ss 服务, 如果显示成功就 ok 了！\n默认配置:\n服务器端口: 自己设定 (如不设定, 默认为 8989)\n客户端端口: 1080\n密码: 自己设定 (如不设定, 默认为 teddysun.com)\n备注: 脚本默认创建单用户配置文件, 如需配置多用户, 安装完毕后参照下面的教程 sample 手动修改配置文件后重启即可。\n卸载方法\n使用 root 用户登录, 运行以下命令\n./shadowsocks.sh uninstall 使用命令\n启动: /etc/init.d/shadowsocks start 停止: /etc/init.d/shadowsocks stop 重启: /etc/init.d/shadowsocks restart 状态: /etc/init.d/shadowsocks status 更多关于SS的问题请看这里\nSS 客户端\r客户端下载: 点我下载 (国外有点慢, 多刷新, 翻墙更快)\n需要 Net.4.0 支持库, XP 安装可以正常使用, 其他电脑会提示安装的。\n启动后, 会最小化在任务栏, 右键\n选择服务器 -\u0026gt; 编辑服务器\n把刚刚记录的 IP 端口 密码 加密方式 填完之后保存\n右键 SS 选择启动代理\n启动之后再右键 SS 选择 系统代理模式 -\u0026gt; 全局模式\n恭喜你开始了科学上网！！！\nvultr 的直连速度还是不错的, 非高峰期可以达到 20000+\n看 720p 只要 3000+ 就不会卡, 1080p 需要 5000 左右的速度\n如果视频卡, 速度慢, 需要做线路优化请看这个贴\n","date":"2016-02-20T14:38:00+08:00","permalink":"https://blog.acesheep.com/p/5afb2bbfaed6c26f3572d54e1c53a7d6/","title":"私人 SS 服务器搭建"},{"content":"Bandwagon (搬瓦工)\r如果你只是上 twitter、facebook、google 什么的刷下动态搜下资料, 那我就推荐用搬瓦工, 毕竟便宜实惠, 如果你说你用龟速的goagent的话, 也行, 不过那速度…\n搬瓦工的价格是最便宜的, 我用的一款是 9.99$/年 月流量 500G 的可以说是性价比最好的了, 只不过那网络稳定性实在是差的可以, 基本上就是天朝人民玩的太猛了\r优点:\n便宜 操作简单, 搭建SS非常方便, 一键安装完毕 可以随意更换机房 支持支付宝 缺点:\n速度非常不稳定 Vultr\r如果你需要在youtube看视频或者是玩游戏 (玩游戏这个可能会迟些时候我才会更新) 的话, 我推荐用Vultr, 速度不错价格便宜重点是又日本机房, 国内连接优势很大啊。\n优点:\n相对便宜 稳定 有日本机房离大陆近 我用这个做演示\r缺点:\n操作比较麻烦 不支持更换IP, 切换机房只能重新开通 (不过貌似有快照) DigitalOcean\r这个是非常出名的 VPS 提供商了, 后起之秀, 速度是我用过最稳定的, 远远超过了 linode, 价格也挺公道, 只不过 DigitalOcean 监管非常严格, 如果你违反了使用条款, 账号可能会直接被删除, 所以要注意哦！\n优点:\n超稳定 缺点:\n严格 Linode\r这个是老牌王者, 不过价格也非常高, 本人一直没敢继续用\r优点:\n之一是老牌王道质量上乘 稳定 缺点:\n贵 ","date":"2016-02-20T14:36:00+08:00","permalink":"https://blog.acesheep.com/p/2c7214ce7c3e7dba6b9c74a9262a0e55/","title":"境外虚拟服务器VPS比较"},{"content":"代码高亮失败 不能上传附件 我的天哪, 我要换主机了\n\u0026lt;?php define(\u0026#39;IN_ADMINCP\u0026#39;, true); define(\u0026#39;DISABLE_PLUGIN\u0026#39;, true); require_once \u0026#39;./system/info.ace.php\u0026#39;; if(!is_admin($uid)) exit(); $formhash = substr(md5(substr(TIMESTAMP, 0, -7).$username.$uid.SYS_KEY.ROOT.\u0026#39;ADMINCP_ONLY\u0026#39;), 5, 14); ","date":"2016-02-20T03:20:00+08:00","permalink":"https://blog.acesheep.com/p/ce52d5f75aea3764c8711a24d0048f28/","title":"2016年2月20日 空间搭建完成还是不戳的！！！"},{"content":"如果您看到这篇文章, 表示您的 blog 已经安装成功。\n2016年2月20日 本站搭建完成\n2016年9月30日12:36:42 本站更新域名 并且启用SSL 证书 全面支持HTTPS\n","date":"2016-02-20T01:16:00+08:00","permalink":"https://blog.acesheep.com/p/hello-world/","title":"博客创建成功"}]