BOSh
文章227
标签320
分类74
315晚会 36氪 80后 ADB AI AI Agent AI 代理 AI 助手 AI 网关 AI 评测 AI助手 AI大模型 AI安全 AI应用 AI智能体 AI网关 API API 集成 Agent AionUi Android Automation C++ CLI CLI Proxy API CLIProxyAPI CRM Chrome 插件 Claude Opus 4.6 ConnectBot Debian DeepSeek DenchClaw DevOps Docker GEO GPL GPS GPU Gemini Gemini 3.1 Pro GitHub Gmail Gog Google AI Pro Google API Google Gemini HKUDS Hermes Hermes Agent Hexo Hugo IPV6 Jetpack Compose Kimi-K2.5 Kotlin LINUX LaTeX Linux Markdow Markdown MemU Bot MiniMax NAT64 NIX NODE NVIDIA Build NanoClaw Netcatty Newsletter Open WebUI OpenAI OpenAI 兼容接口 OpenCLI OpenClaw PDF 编译 PicoClaw Prismer QClaw QQ机器人 RAG Reddit Rust SFTP SSH Skills Subagent SuperCall Telegram Bot WebSSH Windows WorkBuddy X X热榜 YouTube ZeroClaw arXiv arch c++ git hugo iMessage n8n nanobot node js ntfs pacman podman zz.ac 东海 两性关系 个人助理 中东 中东冲突 中东局势 中关村论坛 中南大学 中国 中美 习惯养成 云同步 亚洲 代理 以色列 任务管理 伊朗 伊朗危机 伊朗战争 伦理 体育 保护主义 信息流 信息管理 停火 健康管理 光通信 免费试用 共和党 养老金 内容工厂 内容生产 内容筛选 军事冲突 军事动态 军民融合 农村 分享 创业 办公自动化 加密 加密货币 加沙 北斗 医学生 半导体 华为 博客 博客助手 博客部署成功 卫星 原生 JS 反重力 台海局势 台湾 命令 喷嚏网 国产 国产化 国产替代 国际 国际关系 国际局势 国际新闻 图卦 图说 地缘政治 基础设施 多代理 多模态AI 大学分析 大模型 孙少平 学习 安全 实时监控 家庭助理 家庭服务器 家装设计 工作总结 工作效率 工作流编排 工具链 平凡的世界 平台责任 开发 开发实录 开源 开源项目 张雪峰 微信 心理健康 情感 战争 投资工具 指标看板 提示词工程 播客 收件箱清理 效率 效率工具 教程 教育制度 数据分析 数据投毒 文献管理 新能源汽车 新闻汇总 日历聚合 时事 时事总结 显卡 晨报 智能体 智能体生态 朝鲜 架构 架构实践 核协议 核武器 桌面Cowork 模型接入 每日图说 比亚迪 油价 活动运营 浏览器自动化 消息通道 消费者权益 渔船 游戏开发 湘雅医院 热点新闻 版本更新 特朗普 生态系统 生活 生活自动化 生物识别 用例 甲骨文云 电池技术 症状追踪 皮皮虾 监管 目标管理 知识库 社交媒体 社会保障 社会百态 社会观察 科技 科研助手 笔记 第一财经 算法推荐 纽森 经济 经济观察 经验分享 编程 网关 网络 网络安全 美伊关系 美伊冲突 美国 美国大选 美国政治 能源安全 能源市场 腾讯 腾讯,龙虾,OpenClaw 腾讯云 自动化 自动化创作 自动化协作 自动化提醒 自动化流水线 自动化运维 自律教练 自由软件 行为改变 视频摘要 记录 许可证 论文写作 论文阅读 语义搜索 语音代理 读书 读书笔记 读后感 财报季 路遥 迁移 运维 远程运维 邀请确认 部署指南 量子计算 销售自动化 阅读感悟 随笔 霍尔木兹海峡 项目管理 飞书 高中生活 高考志愿 黎巴嫩 龙虾

一言

文章归档

「zz.ac」公益主机代理地址浅究

「zz.ac」公益主机代理地址浅究

涛叔在ZZ.NIC 公益 Linux 主机空间这篇文章中说:

注意它已经设置了 fe80::2/64 本地链接地址。登录之后无法直接访问外部网络环境。但你用 curl 访问 github.com 就会发现是通的。这是因为系统会自动设置 HTTP 代理环境变量:

1
2
3
$ export|grep http
declare -x http_proxy="http://[fe80::1%eth0]:8888"
declare -x https_proxy="http://[fe80::1%eth0]:8888"

这个代理究竟是什么意思呢?今天通过Gemini探究一下:

1
2
declare -x http_proxy="http://[fe80::1%eth0]:8888"
declare -x https_proxy="http://[fe80::1%eth0]:8888"
  1. 语法拆解:declare -x
  • 在 Bash 中,declare 是一个用于声明变量及其属性的内置命令: declare: 告知 Shell 我要定义一个变量。

  • -x: 代表 export(导出)。它的作用是将该变量变成“环境变量”。

区别:如果只写 http_proxy=“…”,这个变量只在当前终端窗口有效;使用 -x 后,从这个终端启动的所有程序(如 curl、wget、git、apt 等)都能读取到这个变量。

  1. 地址拆解:IPv6 链路本地地址:
  • 这是这条命令中最复杂的部分:http://[fe80::1%eth0]:8888

  • http://: 即使是代理 IPv6 流量,代理服务器本身运行的协议通常仍然是 HTTP。

  • fe80::1: 这是一个 IPv6 Link-Local Address(链路本地地址)。这类地址仅在当前的物理网段内有效(可以理解为局域网?)。

  • fe80::1 通常是网关(如路由器或宿主机)在 IPv6 环境下的简写形式。

    完整(非压缩)形式为:fe80:0000:0000:0000:0000:0000:0000:0001

  • %eth0: 这是 Zone Index(区域索引/范围标识)。

    关键点:由于所有的网卡(eth0, eth1, wlan0)都可能拥有以 fe80 开头的地址,系统无法仅凭地址知道该往哪个网卡发包。

  • %eth0 明确告诉系统:通过名为 eth0 的网卡去寻找这个代理服务器。

    在 IPv6 的语法中,这个 % 符号被称为 Zone Index(区域索引) 或 Scope ID(作用域标识符) 的分隔符。
    在网络中,fe80::/10 开头的地址是链路本地地址(Link-Local Address)。这种地址在每个网络接口(网卡)上都会自动生成一个,且只在当前物理网段内有效。
    由于一个操作系统可能插了多张网卡(如 eth0 是有线,wlan0 是无线),每张网卡对应的物理网段里可能都有一个 fe80::1:

    如果不加 %,电脑不知道应该从哪张网卡把数据包发出去。
    加上 %eth0,就是明确告诉电脑:“请通过 eth0 这张网卡,去找那个叫 fe80::1 的目标”。

  • [ ]: 在 URL 中,如果使用 IPv6 地址,必须用方括号包围,以区分地址中的冒号和端口号的冒号。

  • :8888: 代理服务器监听的端口号。

  1. 变量名拆解:
  • http_proxy 与 https_proxy这两个是 Linux 系统中约定俗成的环境变量名:
  • http_proxy拦截所有不加密的 HTTP 请求,并转发给代理服务器。
  • https_proxy拦截所有加密的 HTTPS 请求(通常通过 HTTP CONNECT 隧道)。

我的公益主机上的代理:

1
2
3
export |grep http
declare -x http_proxy="http://[fe80::1%25eth0]:8888"
declare -x https_proxy="http://[fe80::1%25eth0]:8888"

而涛叔的文章中是:

1
2
declare -x http_proxy="http://[fe80::1%eth0]:8888"
declare -x https_proxy="http://[fe80::1%eth0]:8888"

显而易见:

区别在于我的代理的%25eth0和默认的%eth0的区别:我网卡名前多了25

这个区别是我为了运行node js项目的时候,Gemini让我修改的。 有个困惑:为啥需要改成这样呢?区别在那里呢?

关于这里的25,这涉及到了 URL 编码(URL Encoding) 的底层机制:

简单的说:%25 其实就是百分号 % 本身经过“翻译”后的样子

  1. 为什么会有 %25?

    • 在计算机网络标准中,% 符号是一个特殊保留字符。它在 URL(统一资源定位符)中被用作“转义字符”的前缀。例如:空格会被编码为 %20,斜杠 / 会被编码为 %2F
    • 当直接写 %eth0 时,某些底层解析器(比如 npm 使用的 Node.js 网络库或某些版本的 curl)会尝试去寻找 % 后面跟随的两个十六进制数字。因为它发现后面跟着的是 et而不是数字,解析器就会报错,或者无法正确识别这个地址,导致代理失效。
    • 为了在 URL 中表示一个“纯粹的百分号”,你必须对百分号本身进行编码。在 ASCII 码表中,百分号 % 的十六进制值是 25
  2. 两组代理的区别特性:

    特性 第一组 (%eth0) 第二组 (%25eth0)
    形式 原始/未编码形式 URL 编码形式
    解析行为 Shell 脚本或简单的系统工具能识别,但高级编程语言(Node.js, Go)往往会报错。 符合标准规范。所有的现代网络库都能正确识别。
    稳定性 不稳定,取决于具体软件对 URL 的解析严谨程度。 非常稳定,是跨平台、跨工具的标准写法。
    npm 表现 失败。Node.js 的 URL 解析器会认为这是一个非法的 URL 格式。 成功。Node.js 将 %25 还原为 %,从而正确找到网卡。

实测:在这个系统curl 进行下载正常,使用wget 下载却报错:

1
2
3
4
5
6
bosh@h1:~$ wget www.google.com
Error parsing proxy URL http://[fe80::1%25eth0]:8888: Invalid IPv6 numeric address.
bosh@h1:~$ crule www.google.com
-bash: crule: command not found
bosh@h1:~$ curl www.google.com
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for." name="description"><meta content="noodp, " name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/images/branding/googleg/1x/googleg_standard_color_128dp.png" itemprop="image"><title>Google</title><script nonce="qOaPXbwdBh-h

这是为何那么呢?

  • Linux 中两个最常用的下载工具 curl 和 wget 在代码实现严谨程度上的差异。
  • 核心原因:wget 的一个已知“顽疾”
  • wget 的报错信息:Error parsing proxy URL … Invalid IPv6 numeric address 已经给出了答案。
  • 原因:wget 的 URL 解析器(Parser)写得比较陈旧。它无法正确处理 IPv6 地址中的 Scope ID(作用域标识符,即 %eth0 部分)。
  • 现象:
  • 即使使用了 %25 转义,wget 依然会尝试去验证这个 IP 地址是否符合它心目中的“标准 IPv6 格式”。
  • 在 wget 的逻辑里,它可能只认 [fe80::1] 这种纯地址。一旦看到里面夹杂了 % 这种符号,它的解析逻辑就会“崩溃”,认为这是一个无效的数字地址。
  • 为什么 curl 可以?
  • curl 被称为网络界的“瑞士军刀”,它的背后是强大的 libcurl 库。
  • 更现代的解析器:curl 完美支持 RFC 4007(定义 IPv6 作用域地址的标准)。它不仅能识别 % 符号,还知道如何在建立连接时提取 % 后的网卡名称,并调用底层系统函数(如 getaddrinfo)去绑定正确的网卡。
  • 对转义的宽容度:当你使用 %25 时,curl 的解析器会先执行一层 URL 解码,将其还原为 %,然后再正常处理。

  1. 为什么 npm 需要这个?
    npm 是基于 Node.js 运行的。Node.js 在处理网络请求时,对环境变量中的 URL 格式要求非常严格。
  • 当 Node.js 读取到 http://[fe80::1%eth0]:8888 时,它会尝试解析这个字符串。

  • 由于 % 后面不是有效的十六进制数,解析器会抛出一个内部错误,或者直接忽略这个代理配置,导致 npm install 尝试直接连接网络,进而因为连不上墙外的服务器而超时。

而使用 %25eth0 时,Node.js 会执行以下逻辑:

  • 检测到 %25。

  • 将其解码(Decode)为 %。

  • 得到最终地址 fe80::1%eth0。

  • 交给操作系统,操作系统通过 eth0 网卡连接到 fe80::1。

总结:

这个坑其实是 “标准之争”。虽然在终端手动 ping 的时候可以直接用 %eth0,但在程序代码、配置文件和 URL 中,永远建议使用 %25 来代替 %,以确保最大的兼容性。


😄 😄 😄 😄 😄

本文作者:BOSh
本文链接:http://bosh.zz.ac/posts/1925092226.html
版权声明:本文由BoSh发布,部分内容来源于网络。