2026年2月

突然想到,没人说域名只能映射公网 IP 吧?

So ,如果我内网有个反代服务器,我将 A 记录 * 指向这个服务的内网 IP

那么我只要在这个服务器上配置好子域名的反向代理,剩下的只要利用 Tailscale 这样的组网工具将终端纳入到这个内网就好了。权限什么的完全可以只利用组网工具来做配置。

各位兄弟帮我想想有没有什么盲点哈哈哈

各位大佬好,想请教一个香港独服方案的定价与可行性,希望听听大家从成本、市场需求、风控/滥用、高防真实性等角度给建议。

方案草案(香港)

CPU:Intel Xeon E5-2680 v4 ( 14C/28T )

内存:16G / 32G (两档)

硬盘:1T / 2T 机械 或 128G / 256G SSD

带宽:100Mbps 高防(公平使用)

流量:按需购买,基础包 1T 或 10T (待定)可以加

定价:200-300CNY/月

想请教的问题

  1. 以香港市场来看,这个配置配置还有什么需要修改的吗?
  2. 流量包 1T/10T 哪个更贴近用户真实需求?大家更喜欢“月付含流量”还是“低月付+流量按需”?
  3. 你们觉得更合理的定价/规格组合是什么?欢迎给出你认为更能卖的套餐建议。
    先谢谢各位,任何经验/踩坑都很有帮助。

最近肥牛的 0day 漏洞很火,分享下我的观点:

普通人如果不对不特定公众人群提供网络服务的话,完全可以不对外暴露任何端口,以获得最大的数据安全。

那在外如何访问家里的数据呢,只需要一个中转服务,把当前设备的 IP 传递给家里的防火墙即可。分享下我的实现方式

  1. 本地防火墙默认 drop 掉所有的入栈请求,注意是 drop 不是 reject 。被扫描时选择不回应,而不是大喊“不准进”,网络黑暗森林法则
  2. 本地防火墙上运行一个监听脚本/程序,只通过 cf tunnel 监听来自 cf worker 的认证后的请求,不监听公网请求
  3. 在 cf Worker 上部署一个中转脚本,用于接受远程设备的 ip 并转发给本地防火墙
  4. 远程设备,比如手机需要访问家里的设备时,先访问 cf worker 脚本,脚本将设备的 IP 和请求端口等信息传递给本地防火墙的监听程序,再由其加入到防火墙的临时白名单里,允许 10 分钟内入栈连接。超时后将 ip 移出白名单
  5. iOS 设备可以利用快捷指令,在启动某个 App ,比如群晖 Photos 时自动后台访问 worker 脚本,将当前设备的 IP 传递给家里的防火墙,基本可以无感直接访问家里。其他有更高权限的系统,完全可以将设备的 IP 变动实时传递给家里

其中第二步也可以简化为只运行一个轮询脚本,通过 cron job 不断轮询 cf worker 获取最新的白名单 IP 。时效性比通过 cf tunnel 监听稍差。自己有 VPS 的话可以通过其他方式与 VPS 建立一个长连接传递白名单 IP ,增加时效性

PyTorch 的即时执行模式在原型开发阶段很方便,但在推理性能上存在明显短板。每个张量操作独立启动 kernel、独立访问显存,导致内存带宽成为瓶颈GPU 算力无法充分利用。

torch.compile 通过提前构建计算图来解决这个问题。它的核心策略是操作融合和缓冲区复用:第一次调用需要编译而之后的推理会快很多。在 PyTorch 官方的基准测试中,各种模型平均获得了 20%-36% 的加速。

即时执行意味着每个操作独立运行。一个 32 层、每层 100 个操作的模型,前向传播一次就要触发 3200 次 kernel 启动,这些开销全部叠加到推理延迟里。

延迟飙升的根本原因是什么?内存才是即时执行成为瓶颈。Nvidia H100 能跑到 300+ TFLOPs但内存带宽只有约 3 TB/s。所以内存搬运的代价太高了,即时执行模式在规模化场景下根本撑不住。每个操作至少要做三次内存访问:从 VRAM 读输入张量、把中间结果写回 VRAM、再从 VRAM 读权重。

比如说这个简单的表达式

x = torch.relu(torch.matmul(a, b) + c)

,即时执行模式下至少要六次内存传输:分别读 a、b、c,写矩阵乘法结果,读这个结果,写最终输出。内存带宽很快就被打满了,GPU 核心反而闲着。

所以问题的本质在于:独立的操作没法融合内存传输,造成大量冗余的 VRAM 访问。

生产环境下情况更糟。CPU 要处理成千上万的并发请求,花在 PyTorch 调度器上的时间可能比真正计算还多,吞吐量被严重拖累。

计算图

torch.compile 要解决的就是这种逐操作的开销。它会提前捕获整个计算图,核心靠两个组件:TorchDynamo 是一个 Python JIT 编译器,负责拦截字节码执行;TorchInductor 是后端,为 GPU 生成优化过的 Triton kernel,为 CPU 生成 C++ 代码。

PyTorch 里这个计算图叫 FX Graph,把操作表示成有向无环图(DAG)的节点。调用 torch.compile 时,TorchDynamo 分析 Python 字节码,生成 FX 图:节点是张量操作,边是数据依赖。

TorchInductor 拿到 FX 图后会做三件事:操作融合、内存规划、Triton 自动调优。

操作融合

还是前面那个例子

x = torch.relu(torch.matmul(a, b) + c)

。即时执行要六次 VRAM 传输,TorchInductor 把它们融合成一个 Triton kernel:先把 a、b、c 的分块加载到片上 SRAM(共享内存),在寄存器里算矩阵乘法,加法和 ReLU 也在寄存器里做完,最后只把结果写回 VRAM。

内存传输从 6 次降到 2 次,减少了 3 倍。

内存规划

TorchInductor 不会给每个中间结果都分配新内存,而是让生命周期不重叠的缓冲区共用同一块空间——和编译器复用寄存器是一个思路。这相当于在整个计算图上做全局缓冲区复用,对激活模式不规则的 Transformer 模型特别有效。另一个好处是压低峰值内存占用,能跑更大的 batch。

Triton 自动调优

Triton 自动调优会针对具体硬件和输入 shape,自动搜索最优的 kernel 配置:tile 大小、线程块维度、流水线深度这些参数都不用手动调。

结果

第一次调用时,大模型的编译可能要几分钟。但后续调用只需要几毫秒加载预编译好的 kernel。初始开销会在后续推理中摊销掉,特别适合生产场景下模型持续运行的情况。冷启动慢一点,后面每个请求都快很多。

PyTorch 官方在 165 种模型(Transformer、CNN、扩散模型都有)上做了基准测试,torch.compile 在 float32 精度下平均加速 20%,开启自动混合精度(AMP)后加速 36%。

用起来也很简单:

 import torch  

# For a model  
model = YourModel()  
compiled_model = torch.compile(model)  

# Or for a function, also enables Triton autotuning  
@torch.compile(backend="inductor")    
def forward_pass(x, weights):  
    return torch.relu(torch.matmul(x, weights))  

 output = compiled_model(input_tensor)

这就是 torch.compile 的大致原理:不再为每个操作单独启动 kernel、单独搬运数据,而是用一个 kernel 处理多个操作,共享内存缓冲区。内存瓶颈的影响被大幅削减,GPU 算力利用率上去了。

总结

这种加速具有普适性,不只对大语言模型有效,CNN、扩散模型等架构同样适用。torch.compile 的价值在于:它把原本需要手写 CUDA 或 Triton 才能实现的优化,封装成了一行代码的事情。对于生产环境下的推理服务,这是目前性价比最高的优化手段之一。

https://avoid.overfit.cn/post/271bbf42f4a946c3a92b8a9745e223db

作者:Aryan Keluskar

IEEE 近日发布了一项新的隐私标准:7012-2025 IEEE 标准,其昵称为 MyTerms。该标准定义了一套机制,用于在个人与在线服务提供方之间交换个人信息,并明确规定个人如何在交易过程中执行自身的隐私要求。

这一新标准在伦敦举行的一场活动上正式发布。Linux Journal 主编、《The Intention Economy: When Customers Take Charge》一书作者,同时也是 MyTerms 最早倡导者之一、该标准委员会联合主席的 Doc Searls 在现场介绍了这一标准。他将 MyTerms 描述为一种尝试:把我们在现实世界中对“隐私”的理解,与在线世界重新对齐。

Searls 表示,MyTerms 是一次“彻底翻转既有规则”的尝试。在这一模式下,用户成为“第一方”,不再被动接受网站条款,而是通过选择一套预先定义的条款,或使用一份可在不同网站间通用的默认协议,来主动决定自己如何与作为“第二方”的服务和产品提供者互动。

这些条款既可以用于持续性的关系,比如“仅用于服务交付”或“在支持数据可携带性的前提下用于服务交付”,也可以用于一次性的数据贡献场景,例如“用于 AI 训练和运行”“共享意图数据”等。一旦第二方接受相关条款,该条款即构成一份合同,在法律上约束其必须按照第一方的约定方式使用数据。

MyTerms 协议以机器可读格式定义,可以通过 HTTP 头信息或其他机制进行传输。协议双方都会各自保留一份完全一致的记录。

此处输入图片的描述

Searls 指出

这一机制将使 Cookie 提示彻底过时,并为个人与组织、客户与企业、需求与供给之间的关系奠定更加稳固的基础。

专注于数字身份与用户主导个人数据的公司 Customer Futures Ltd. 创始人 Jamie Smith 也表示:“我们已经接近当前在线模式的可接受极限。人们不断点击自己根本不会阅读的条款和条件,……而这些条款并没有真正完成它们应该承担的功能。”

Smith 认为,在当前这个由 AI Agent 逐渐替代人类进行上网操作的时代,MyTerms 显得尤为重要。这些 AI Agent 正在代表用户完成购物、预订、投诉处理、与各类机构互动等任务,而 Cookie 并不适用于“代理型商业”(agentic commerce)。在未来,每个 Agent 都将拥有自己的身份,并发布自己的条款,也就是合同。

他表示:

随着 Agent 成为新的客户渠道,MyTerms 将成为企业与 Agent 之间建立信任、并展开交互的重要基石。

Consumer Reports 实验工程负责人 Dan Leninger 描绘了一个未来场景:用户通过在线推荐系统购买一件家电。用户不仅会提交自己的 MyTerms 条款,还会附加额外条件,例如最高价格、最晚交付时间等。推荐系统随后只会展示那些已接受用户条款的商家,用户即可完成购买。

年龄验证平台 Yoti 的首席商务官 John Abbott 则讨论了 MyTerms 对儿童的潜在影响,尤其是在年龄验证方面。他认为,MyTerms 为个人根据自身年龄明确数据使用方式提供了一种更合适的机制,也有助于企业应对全球范围内日益严格的监管要求。

MyTerms 标准的制定历时约八年,其项目授权请求(Project Authorization Request,PAR)最早于 2017 年 12 月提出并获得批准。若想进一步深入了解 MyTerms,可以阅读 Doc Searls 围绕该主题撰写的大量文章。

原文链接:

https://www.infoq.com/news/2026/02/myterms-privacy-cookies/

以前从境外访问 www.txrjy.com 或者使用招行信用卡 APP ,虽然相应速度慢,但是终究还能用!这两天 www.txrjy.com 一直打不开,招行信用卡 APP 提示网络异常,几天都是如此。使用 12306 购票总是提示网络错误!想问一下,其他人也是如此吗?
正在 Ping www.txrjy.com.w.kunlunpi.com [114.80.179.170] 具有 32 字节的数据:
请求超时。
请求超时。
请求超时。
来自 114.80.179.170 的回复: 字节=32 时间=365ms TTL=44

视频点播业务,波形图如下,支持按流量计费/日 95 计费,用量预估 3000PB/年左右

日 95 计费要求:4400/Gbps 以下
流量计费要求 21/TB 1 系数 1024 进制
人民币支付
能做到这个价以下请留下联系方式
1770108812491.png

我理解公钥私钥只是一个更加复杂的密码

倘若我本身密码就是 16 位以上大小写英文数字符号混合,并且每个服务器密码均随机生成不一样
并且我开启了 auto-ban 之类的服务,防止穷举猜测密码

那是否可以认为安全性是接近的
特别如果是私钥泄露意味你几乎所有服务器等于密码泄露,难道是每个服务器私钥都不一样?

本文在鲲鹏920openEuler,从0开始使用Containerd部署k8s1.30.13+Ks。

1.说明

关于kt

kt是基于kk二次开发的产物,具备kk的所有功能。二开主要为适配信创国产化环境、简化arm部署过程和国产化环境离线部署。支持arm64amd64架构国产操作系统,已适配芯片+操作系统 如下。

kt新增功能点

  • 适配arm架构harbor和支持,部署体验与X86一样简单。
  • 离线环境部署增强。常用国际和国产操作系统依赖,内置到安装包中。已适配芯片和操作系统如下

    • ./kt init-os 一条命令完成操作系统依赖安装和初始化操作。
    • CPU:鲲鹏、飞腾、海光、兆芯、intel、amd等。
    • OS:Centos、Rocky Linux、Ubuntu、Debian、银河麒麟V10、麒麟V11、麒麟国防版、麒麟信安、中标麒麟V7、统信UOS、华为欧拉、移动大云、阿里龙蜥、TencenOS等。
  • 支持开启防火墙,只暴露30000-32767端口,其他k8s端口添加到节点白名单。

    • ./kt firewall 一条命令自动获取节点信息开白名单和防火墙。

kt版本更新和下载地址

  • kt: kt
  • 关注我不迷路

2.环境准备

服务器基本信息

<!-- 这是一张图片,ocr 内容为: -->

主机名架构OS配置IP
masterarm64openEuler2核4G192.168.0.101
nodearm64openEuler2核4G192.168.0.133
harborarm64openEuler2核4G192.168.0.232

2.1 上传离线制品

操作系统不需要安装docker,不需要设置selinux,swap等操作,全新的操作系统即可。

将离线制品、配置文件、kt和sh脚本上传至服务器其中一个节点(本文以master为例),后续在该节点操作创建集群。本文使用kt:3.1.13.1版本

<!-- 这是一张图片,ocr 内容为: -->

2.2 修改配置文件

根据实际服务器信息,配置到生成的config-sample.yaml

kind: Cluster
metadata:
  name: sample
spec:
  hosts:
  - {name: master, address: 192.168.0.101, internalAddress: 192.168.0.101, user: root, password: "123213", arch: "arm64"}
  - {name: node1, address: 192.168.0.133, internalAddress: 192.168.0.133, user: root, password: "123213", arch: "arm64"}
  - {name: harbor, address: 192.168.0.232, internalAddress: 192.168.0.232, user: root, password: "123213", arch: "arm64"}
  roleGroups:
    etcd:
    - master
    control-plane:
    - master
    worker:
    - node1
    # 如需使用 kt 自动部署镜像仓库,请设置该主机组 (建议仓库与集群分离部署,减少相互影响)
    # 如果需要部署 harbor 并且 containerManager 为 containerd 时,由于部署 harbor 依赖 docker,建议单独节点部署 harbor
    registry:
    - harbor
  controlPlaneEndpoint:
    ## Internal loadbalancer for apiservers 
    internalLoadbalancer: haproxy

    domain: lb.kubesphere.local
    address: ""
    port: 6443
  kubernetes:
    version: v1.30.14
    clusterName: cluster.local
    autoRenewCerts: true
    containerManager: containerd
  etcd:
    type: kubekey
  network:
    plugin: calico
    kubePodsCIDR: 10.233.64.0/18
    kubeServiceCIDR: 10.233.0.0/18
    ## multus support. https://github.com/k8snetworkplumbingwg/multus-cni
    multusCNI:
      enabled: false
  registry:
    type: harbor
    registryMirrors: []
    insecureRegistries: []
    privateRegistry: "dockerhub.kubekey.local"
    namespaceOverride: "kubesphereio"
    auths: # if docker add by `docker login`, if containerd append to `/etc/containerd/config.toml`
      "dockerhub.kubekey.local":
        username: "admin"
        password: Harbor@123 # 此处可自定义,kk3.1.8新特性
        skipTLSVerify: true # Allow contacting registries over HTTPS with failed TLS verification.
        plainHTTP: false # Allow contacting registries over HTTP.
        certsPath: "/etc/docker/certs.d/dockerhub.kubekey.local"
  addons: []

2.3 系统初始化

解压kt-centos.tar.gz文件后执行./kt init-os -f config-sample.yaml 已适配操作系统和架构见1.说明

该命令kt会根据配置文件自动判断操作系统和架构以完成所有节点的初始化配置和依赖安装。

<!-- 这是一张图片,ocr 内容为: -->

3 创建 Harbor私有仓库

3.1 创建镜像仓库

./kt init registry -f config-sample.yaml -a artifact-arm-k8s13014-ks3.4.1.tar.gz

此命令会在harbor节点自动安装dockerdocker-compose

<!-- 这是一张图片,ocr 内容为: -->

<!-- 这是一张图片,ocr 内容为: -->

3.2 创建harbor项目

<font style="background-color:rgb(255,245,235);">说明:</font>

<font style="background-color:rgb(255,245,235);">Harbor 管理员账号:</font><font style="background-color:rgb(255,245,235);">admin</font><font style="background-color:rgb(255,245,235);">,密码:</font><font style="background-color:rgb(255,245,235);">Harbor@123</font><font style="background-color:rgb(255,245,235);">。密码同步使用配置文件中的对应password</font>

<font style="background-color:rgb(255,245,235);">harbor 安装文件在 /opt/harbor<font style="background-color:rgb(255,245,235);"> 目录下,可在该目录下对 harbor 进行运维。</font>

创建 Harbor 项目

chmod +x create_project_harbor.sh && ./create_project_harbor.sh

<!-- 这是一张图片,ocr 内容为: -->

4 创建k8s和KubeSphere

./kt create cluster -f config-sample.yaml -a artifact-arm-k8s13014-ks3.4.1.tar.gz

此命令kt会自动将离线制品中的镜像推送到harbor 私有仓库

执行后会有如下提示,输入yes/y继续执行

<!-- 这是一张图片,ocr 内容为: -->

等待一段时间,直至出现熟悉的等待安装完成的小箭头>>--->

<!-- 这是一张图片,ocr 内容为: -->

期间可以另开一个窗口用以下命令查看部署日志

kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f

继续等待一段时间,可以看到在内核3.10.0上面使用containerd成功部署了1.30.14版本+ks

<!-- 这是一张图片,ocr 内容为: -->

5 验证

<!-- 这是一张图片,ocr 内容为: -->

ps:default-http-backend那个pod显示:ImagePullBackOff,没啥用,不需要理会。

登录页面

<!-- 这是一张图片,ocr 内容为: -->

集群管理

<!-- 这是一张图片,ocr 内容为: -->

集群节点

<!-- 这是一张图片,ocr 内容为: -->

监控告警

<!-- 这是一张图片,ocr 内容为: -->

集群信息

<!-- 这是一张图片,ocr 内容为: -->

节点情况

<!-- 这是一张图片,ocr 内容为: -->

配置文件默认只安装了监控,如果需要安装其他组件,可以自行在自定义资源中开启

<!-- 这是一张图片,ocr 内容为: -->

一、核心配置结构说明

containerd 2.x 对镜像仓库配置进行了结构化优化,所有相关配置均集中在 /etc/containerd/certs.d/ 目录下,遵循 "一仓库一目录" 的配置原则:

  • 每个镜像仓库(registry)对应一个独立目录,目录名需与仓库域名(或 IP 地址)完全一致
  • 每个目录下必须包含一个 hosts.toml 文件,用于定义仓库连接参数
  • hosts.toml 核心配置项:仓库服务地址(server)、操作权限(capabilities)、认证信息(auth)、证书验证开关(skip\_verify)

二、分步配置实战

1. 版本确认

首先通过以下命令验证 containerd 版本是否为 2.x 系列:

\\\[root@k8s-master ~]# containerd --version
containerd containerd.io v2.2.0 1c4457e00facac03ce1d75f7b6777a7a851e5c41

2. 创建配置目录

根据 Harbor 仓库地址创建对应的配置目录,目录名需与仓库域名(或 IP)严格匹配(示例中 Harbor 仓库地址为 harbor.liyb.com):

mkdir -p /etc/containerd/certs.d/harbor.liyb.com
注意:若仓库未使用域名(直接通过 IP 访问),可直接以 IP 地址作为目录名(如 /etc/containerd/certs.d/192.168.1.100

3. 编写 hosts.toml 配置文件

创建并编辑 hosts.toml 文件,配置仓库连接参数:

vi /etc/containerd/certs.d/harbor.liyb.com/hosts.toml

添加如下配置内容:

server = "https://harbor.liyb.com"

\\\[host."https://harbor.liyb.com"]
capabilities = \\\["pull", "resolve", "push"]  # 支持的操作:拉取、解析、推送
skip\\\_verify = true  # 自签名证书时启用(跳过证书验证)
\\\[host."https://harbor.liyb.com".auth]
username = "admin"  # Harbor 登录用户名
password = "Harbor12345"  # Harbor 登录密码

配置说明:

  • 若使用企业级可信证书,无需设置 skip\\\_verify = true,只需将 CA 证书文件放置到对应配置目录(如 /etc/containerd/certs.d/harbor.liyb.com/)即可
  • 权限配置可根据实际需求调整,例如仅需拉取镜像时可改为 capabilities = \\\["pull", "resolve"]

4. 确认主配置文件路径

检查 containerd 主配置文件 /etc/containerd/config.toml 中是否正确指定了仓库配置路径,确保以下配置项存在且无误:

toml

# /etc/containerd/config.toml
\\\[plugins."io.containerd.grpc.v1.cri".registry]
config\\\_path = "/etc/containerd/certs.d"  # 仓库配置目录路径(默认已启用)
注意:containerd 2.x 默认启用该配置,但生产环境部署时务必手动校验,避免路径配置错误导致配置失效

三、配置验证方法

1. 使用 nerdctl 验证(推荐)

通过 nerdctl 工具拉取 Harbor 仓库镜像,验证配置是否生效:

nerdctl pull harbor.liyb.com/prod/nginx:1.27

成功输出示例:

plaintext

harbor.liyb.com/prod/nginx:1.27: manifest-sha256:114dff0fc8ee3d0200c3a12c60e3e2b79d0920dd953175ecb78a0b157425b25e: done
config-sha256:1e5f3c5b981a9f91ca91cf13ce87c2eedfc7a083f4f279552084dd08fc477512: done
elapsed: 0.1 s
total: 0.0 B (0.0 B/s)

2. Kubernetes 节点验证

在 Kubernetes 节点上通过 crictl 工具拉取镜像(适用于 K8s 集群环境):

crictl pull harbor.liyb.com/prod/nginx:1.27
关键注意点:镜像名称必须显式包含 Harbor 仓库地址(完整格式:仓库地址 / 项目名 / 镜像名:标签),否则会导致 K8s Pod 拉取镜像失败

四、高频踩坑与解决方案

image.png

OpenClaw 远程访问配置指南:SSH 隧道与免密登录

本文介绍如何从 Windows 访问部署在虚拟机/远程服务器上的 OpenClaw Gateway,包括 SSH 隧道配置和免密登录设置。

目录

  1. 场景说明
  2. SSH 隧道访问
  3. 配置免密登录
  4. 创建快捷启动脚本
  5. 常见问题

一、场景说明

网络架构

┌─────────────────────┐                    ┌─────────────────────┐
│   Windows 主机       │                    │   虚拟机/服务器      │
│                     │    SSH 隧道         │                     │
│  浏览器 ◄───────────┼───────────────────►│   OpenClaw Gateway  │
│  localhost:18790    │   端口转发          │   127.0.0.1:18789   │
└─────────────────────┘                    └─────────────────────┘

为什么需要 SSH 隧道?

OpenClaw Gateway 默认绑定在 127.0.0.1(本地回环),这是最安全的配置。直接绑定 LAN IP 可能会遇到 WebSocket 认证问题(1008 错误)。

SSH 隧道的优势:

  • ✅ 安全(加密传输)
  • ✅ 稳定(避免 WebSocket 直连问题)
  • ✅ 无需修改 Gateway 配置

二、SSH 隧道访问

基本命令

在 Windows PowerShell 中运行:

ssh -N -L 18790:127.0.0.1:18789 用户名@虚拟机IP

参数说明:

参数说明
-N不执行远程命令,只做端口转发
-L本地端口转发
18790Windows 本地端口(可自定义)
127.0.0.1:18789虚拟机上的 Gateway 地址
用户名@虚拟机IPSSH 登录信息

实际示例:

ssh -N -L 18790:127.0.0.1:18789 maple@162.16.30.210

访问 Gateway

隧道建立后,在浏览器打开:

http://localhost:18790/?token=你的Token

或者打开 http://localhost:18790,然后手动输入 Token。


三、配置免密登录

每次 SSH 都输密码很麻烦,配置密钥认证可以实现免密登录。

步骤 1:生成 SSH 密钥(Windows)

打开 PowerShell,运行:

ssh-keygen -t ed25519

提示时一路回车(不设置密码)。

会生成两个文件:

  • C:\Users\你的用户名\.ssh\id_ed25519 — 私钥(保密)
  • C:\Users\你的用户名\.ssh\id_ed25519.pub — 公钥(可公开)

步骤 2:复制公钥到服务器

运行以下命令(一行):

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh 用户名@虚拟机IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

实际示例:

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh maple@162.16.30.210 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

这次需要输入密码,之后就不用了。

步骤 3:测试免密登录

ssh maple@162.16.30.210 "echo 免密登录成功"

如果显示 免密登录成功 而不要求输密码,配置完成!


四、创建快捷启动脚本

创建批处理文件

在桌面(或任意位置)创建 openclaw隧道.bat

@echo off
chcp 65001 >nul
echo ========================================
echo   OpenClaw Gateway SSH 隧道
echo ========================================
echo.
echo 正在连接到 Gateway...
echo.
echo 连接成功后,请访问:
echo   http://localhost:18790
echo.
echo [!] 保持此窗口开启
echo [!] 关闭窗口会断开连接
echo.
echo ----------------------------------------
ssh -N -L 18790:127.0.0.1:18789 maple@162.16.30.210
maple@162.16.30.210 替换为你的实际用户名和 IP。

使用方法

  1. 启动虚拟机,确保 OpenClaw Gateway 正在运行
  2. 双击 openclaw隧道.bat
  3. 窗口显示连接信息后,打开浏览器访问 http://localhost:18790
  4. 使用完毕后关闭命令行窗口

进阶:创建桌面快捷方式

  1. 右键 openclaw隧道.bat → 创建快捷方式
  2. 右键快捷方式 → 属性 → 更改图标
  3. 可以设置一个好看的图标

五、常见问题

Q1: 连接时提示 "Connection refused"

原因: 虚拟机未启动或 SSH 服务未运行。

解决:

# 在虚拟机上检查 SSH 服务
sudo systemctl status sshd

# 如果未运行,启动它
sudo systemctl start sshd

Q2: 连接时提示 "Host key verification failed"

原因: 服务器指纹变更(重装系统等)。

解决:

# 删除旧的指纹记录
ssh-keygen -R 162.16.30.210

Q3: 免密登录不生效

检查清单:

  1. 服务器端权限:

    # 在虚拟机上执行
    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys
  2. 确认公钥已添加:

    cat ~/.ssh/authorized_keys
  3. 检查 SSH 配置:

    # 确保这些选项没有被禁用
    grep -E "PubkeyAuthentication|AuthorizedKeysFile" /etc/ssh/sshd_config

Q4: 浏览器显示 1008 错误

原因: Token 验证失败。

解决:

  • 确认 Token 正确(检查 ~/.openclaw/openclaw.json 中的 gateway.auth.token
  • URL 中 Token 不要有多余空格
  • 尝试手动在页面输入 Token 而不是 URL 参数

Q5: 隧道断开后如何重连?

直接重新运行 openclaw隧道.bat 或 SSH 命令即可。

Q6: 如何让隧道后台运行?

Windows 上可以用 start 命令:

start /min ssh -N -L 18790:127.0.0.1:18789 maple@162.16.30.210

或者使用 nssm 等工具将其注册为 Windows 服务。


附录:相关配置参考

OpenClaw Gateway 配置位置

~/.openclaw/openclaw.json

查看 Gateway Token

cat ~/.openclaw/openclaw.json | grep -A2 '"auth"'

重启 Gateway

openclaw gateway restart

查看 Gateway 状态

openclaw status
openclaw health

总结

步骤命令/操作
1. 建立隧道ssh -N -L 18790:127.0.0.1:18789 user@host
2. 生成密钥ssh-keygen -t ed25519
3. 复制公钥`type ... \ssh user@host "..."`
4. 创建脚本保存为 .bat 文件双击运行
5. 访问http://localhost:18790/?token=xxx

配置一次,以后只需双击脚本即可连接!


文档整理于 2026-02-03
适用于 Windows 连接 Linux 虚拟机/服务器上的 OpenClaw

本文由mdnice多平台发布

[大模型实战 03预备] 云端炼丹房 1:Google Colab 上手指南

核心摘要 (TL;DR)

  • 痛点:本地电脑显存不足,跑不动 7B 以上的大模型,或者运行速度如蜗牛。
  • 方案:利用 Google Colab 提供的免费 Tesla T4 GPU 算力。
  • 技巧:通过挂载 Google Drive,解决 Colab 运行时重置导致模型文件丢失的问题。
  • 目标:配置好云端环境,为下一篇“云端运行 RAG”打好地基。

前言

Ollama因为有llama.cpp库和量化技术的加成,是可以在cpu和更日常的电脑上运行的,但是性能是远比不上在专业的显存设备上的。
有高端显卡(NVIDIA 4090/5090/A100/H100),可以在自己的服务器上脱缰运行小规模的大模型。但是对于没有高端显卡设备的友人们也不用担心, 我们可以使用谷歌大善人带给我们的免费GPU算力:爱来自Google Colab。 本篇博文的主要目的就是提前带各位友人们从零上手Colab的核心操作,确保在我们后续的实战过程中的流畅操作。

1. Google Colab

一言概之,Google Colab = Jupyter Notebook + 云端服务器

  • Jupyter Notebook:我们知道python是一门动态脚本语言,意味着我们可以一边编写,一边以交互式的方式看到当前结果,然后还能继续往下写。Jupyter Notebook就是一种可以一边写代码,一边写文档,还能实时看到代码运行结果的交互式笔记。
  • 云端服务器:区别于在我们本地环境写代码时,代码在我们的本地电脑,换一台电脑就需要重新拉取代码运行,在云端服务器编码是在远程的服务器编码,我们通过自己的电脑,甚至手机或者任何能联网打开浏览器的设备,连接上远程的那台服务器进行代码编写和模型训练。会更为灵活,不受设备限制。

2. 快速介绍

2.1 访问与创建

  1. 咱们确保有一个Google账户,并且登录
  2. 访问Google Colab 官网,就会进入到一个欢迎界面
    进入Colab的欢迎页面截图
  3. 点击菜单栏上File->new notebook in drive创建新的笔记本
    Colab菜单栏打开File鼠标指向其下拉菜单new notebook in drive的截图
    创建新的notebook后的新notebook界面截图

2.2 界面介绍

在新的notebook界面,我们可以看到

  • 文件名:左上角“Untitled0.ipynb”的文件名,可以单击重命名,ipynb就是jupyter notebook的后缀名
    notebook界面重新重命名后的文件名截图
  • 单元格:页面中心一长条带一个▶按钮的就说单元格,也叫Cell,是我们的核心编码区域, Jupyter notebook的逻辑是“一段一段”执行代码,而非我们平常写代码时候写完一整个文件再执行。
    notebook界面中心单元格的截图
  • 快捷操作栏:在单元格上方的位置有一条快捷菜单栏,支持我们添加新的代码块(Code Cell)和文本块(Text Cell),运行全部单元格(Run All)。
    在单元格上方的快捷操作栏的截图
  • 左侧工具栏: 包含目录速览,查找替换,密钥管理,数据查看等等工具。
    左侧工具栏的截图
  • 变量和终端:这里的变量按钮可以查看执行到当前的变量信息,就不用去print变量了,很方便。终端按钮就和Linux终端一样,可以用来执行一些命令。
    最下方的变量按钮和终端按钮

3. 核心操作

在界面介绍时,咱们快速介绍了一下两种单元格:代码块文本块,接下来可以稍微多了解一点点这两种单元格

3.1 代码块

就是我们的主力战场,编写Python代码的地方,可以快速体验一下使用流程

  • 直接输入python代码,然后点击运行(那个▶按钮或者使用快捷键 Shift + Enter
    在代码块中写入代码后运行之后的界面截图
  • 可以看到代码块左侧有一个[1],一个绿色的√,代码块下方有输出的打印结果
    前面的序号标明代码块的执行顺序,因为我们可以乱序执行,执行完下方代码块再回来执行前面的代码块

3.2 文本块

jupyter notebook是支持直接渲染markdown格式的文档的,所以也有人直接用它当文档。相比于我们用注释去记录,markdown格式的文本块会更直观。

  • 点击上面的➕Text按钮(或者在当前单元格上方/下方中间浮现显示的快捷按钮)去新增一个文本块
  • Shift+Enter快捷键“运行/渲染”它,
    输入了# This is Title!!的文本块截图
    渲染之后的文本块截图

4. 开启免费GPU算力

默认状态下Colab是使用的CPU,我们接下来去开启GPU

  • 点击顶部菜单栏的Runtime(运行时)下拉菜单中的Change runtime type(更改运行时类型)
    点击Runtime下来菜单,鼠标指向Change runtime type的截图
  • 选择Hardware accelerator(硬件加速器)T4 GPU.
    进入change runtime type后鼠标选择T4GPU的截图
  • 弹出的窗口警告我们会断联当前运行时,切换到T4GPU的硬件,选择OK
    点击T4GPU后,弹出结束运行时的截图
  • 保存,然后会发现之前运行过的代码块失活了(前面框框里的数字消失了,所有运行过的代码块需要重新运行)
  • 我们来输入以下代码验证
!nvidia-smi

nvidia-smi的运行结果截图
从返回的表格结果中,能看到咱们的设备是TeslaT4。

在notebook代码块中以!开头即可运行命令,这里等效为在terminal中运行nvidia-smi
PS:除了切换文件夹得用%cd而不是!cd

5. 下载大模型

我们使用Colab主要是为了使用大模型以及训练大模型,对于Colab而言,模型的下载有个痛点:Colab是临时的,哪怕我们通过命令下载了好几个G的模型,甚至好几十G的模型,但是每次重置运行时的时候,这一切都会灰飞烟灭,消散如烟。为了避免每次都重新下载,浪费时间,我们可以通过挂在Google Drive来保存模型。

5.1 挂载Google Drive

  1. 我们运行以下代码
from google.colab import drive
drive.mount('/content/drive')
  1. 然后在弹出授权窗口中授权
    运行完挂载代码后,弹出的授权提示截图
  2. 就能在代码块下方看见已经成功挂载的打印信息
    成功挂载google drive后的打印信息截图

5.2 配置HuggingFace环境变量和Token

在下载受限模型(如 Llama 3)时,你需要 Hugging Face Token。

  1. Hugging Face Settings 获取 Token。
  2. 在 Colab 左侧钥匙图标(Secrets)里添加 HF_TOKEN

Colab 左侧 Secrets 面板配置 HF_TOKEN 的截图

5.3 指定缓存路径下载

因为咱们在Colab环境,是国外的魔法环境,我们可以直接使用hugging face来下载模型,我们接下来指定一下模型下载的缓存路径到挂载的Google Drive。

  1. 咱们先切回CPU环境,因为下载模型并不需要GPU,切回去可以节约一点咱们的额度。
  2. 输入以下代码然后运行
from google.colab import drive
import os

# 1. 挂载云盘
if not os.path.exists('/content/drive'):
    drive.mount('/content/drive')

# 2. 准备目录
cache_dir = "/content/drive/MyDrive/huggingface_cache"
os.makedirs(cache_dir, exist_ok=True)

# 3. 设置 Token (如果你在左侧 Secrets 设置了 HF_TOKEN,这里自动读取)
# 如果没设置,请手动把下行代码引号里换成你的 token,或者留空试下(Qwen 有时不需要)
my_token = os.getenv('HF_TOKEN') or ""

print("屏幕可能会静止 5-10 分钟,请盯着左边的小圆圈转动即可。")

cmd = f"huggingface-cli download Qwen/Qwen2.5-7B-Instruct --cache-dir {cache_dir} --quiet"
if my_token:
    cmd += f" --token {my_token}"

# 执行命令
result = os.system(cmd)

if result == 0:
    print("\n 下载成功!")
else:
    print("\n 下载失败,请检查网络或 Token。")
  1. 然后运行下面的命令检验模型是否下载完毕
# check disk usage (查看磁盘占用)
# -s: 汇总大小, -h: 人类可读格式 (GB/MB)
!du -sh /content/drive/MyDrive/huggingface_cache/models--Qwen--Qwen2.5-7B-Instruct

看到的结果应该是15G大小的文件
运行du -sh /content/drive/MyDrive/huggingface_cache/models--Qwen--Qwen2.5-7B-Instruct后的结果截图

一般情况下,建议模型下载和数据处理都在CPU模式下进行,然后处理完毕存入云盘. 4. 然后新建代码块,运行如下代码,来确认模型是否能够被识别

import os
import glob
from transformers import AutoConfig, AutoTokenizer

# 1. 设置你的缓存根目录
base_cache_path = '/content/drive/MyDrive/huggingface_cache'

# 2. 构造快照目录的通配符路径
# 结构通常是: base / models--ID / snapshots / <哈希值>
snapshot_pattern = os.path.join(
    base_cache_path,
    "models--Qwen--Qwen2.5-7B-Instruct",
    "snapshots",
    "*"  # 这里用 * 匹配那个随机生成的哈希文件夹
)

# 3. 寻找真实的文件夹路径
found_folders = glob.glob(snapshot_pattern)

if not found_folders:
    print(" 错误:找不到 snapshots 文件夹,请检查下载是否成功或路径是否正确。")
else:
    local_model_path = found_folders[0]

    print(f"锁定本地模型路径: {local_model_path}")
    print("正在尝试直接加载...")

    try:
        config = AutoConfig.from_pretrained(local_model_path)
        tokenizer = AutoTokenizer.from_pretrained(local_model_path)

        print("\n成功!模型可以被正确加载。")
        print(f"模型隐藏层维度: {config.hidden_size}")
        print(f"词表大小: {tokenizer.vocab_size}")

    except Exception as e:
        print(f"\n加载依然失败。可能是 Google Drive 的软链接失效了。")
        print(f"错误信息: {e}")

通过运行模型加载命令,显示模型成功加载的截图

05. 常见问题 (Q&A)

Q: CPU 和 GPU 跑大模型,性能差异到底有多大?
A: 差异巨大,就像法拉利拖拉机的区别。

  • CPU (中央处理器):像一个知识渊博的教授,计算能力强但只能一个一个任务串行处理。推理大模型时,它需要逐个计算矩阵乘法,生成一个字可能需要好几秒。
  • GPU (图形处理器):像一个由几千名小学生组成的方阵,虽然单人能力不如教授,但能同时进行大规模并行计算。大模型的本质是海量的矩阵运算,GPU 可以瞬间完成,生成速度通常是 CPU 的几十倍甚至上百倍。

Q: 那一台 RTX 4090 能运行多大的模型?能微调多大?
A: RTX 4090 拥有 24GB 显存,这是核心瓶颈。

  • 推理 (运行)

    • 4-bit 量化:显存占用 ≈ 参数量 × 0.7。4090 极限可以跑 30B - 34B 参数的模型(如 Yi-34B-Chat-Int4)。
    • 全精度 (FP16):显存占用 ≈ 参数量 × 2。4090 最多跑 10B - 12B 参数的模型。
  • 微调 (训练)

    • 全量微调:想都不要想,需要几百 GB 显存。
    • LoRA / QLoRA (轻量微调):这是咱们个人玩家的主流。4090 可以轻松微调 7B - 10B 的模型。

Q: 动态脚本语言 (Python) 和常规预编译语言 (C++/Java) 有什么区别?
A:

  • 预编译语言 (C++/Java):像写书。写完一整本书(代码),送去印刷厂(编译),最后出来成品书(可执行文件)。执行速度快,但修改麻烦,改一个字要重新印刷。
  • 动态脚本语言 (Python):像聊天。你说一句(写一行代码),解释器就执行一句。虽然执行速度稍慢,但胜在交互性极强。在数据科学和 AI 领域,我们需要频繁查看数据的中间结果(比如查看模型输出的张量形状),Python 的这种特性让它成为了 AI 领域的霸主。

Q: Colab 里的 T4, A100, TPU 都有什么差别?
A:

  • T4 (免费版标配):入门级推理卡,16GB 显存。跑 7B 模型推理没问题,微调 QLoRA 勉强够用。咱们薅羊毛主要就薅它。
  • A100 (付费版):顶级计算卡,40GB/80GB 显存。速度极快,显存极大,适合跑大参数模型或进行严肃的训练任务。Colab Pro/Pro+ 才能刷到。
  • TPU (Tensor Processing Unit):Google 专门为机器学习定制的芯片,处理矩阵运算比 GPU 更快,但生态和兼容性(PyTorch 支持)不如 Nvidia GPU 通用,上手门槛稍高。

本文作者: Algieba
本文链接: https://blog.algieba12.cn/llm02-1-online-environment-colab/
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

派出所的直接去公司找老板,把邮箱密码啥的整出来,让整改。
把公司所有的业务,服务器,端口,各种内容 全部备案了,搞了好几天,每个系统是干嘛的,业务类型,都要记录清楚,打印签字盖章,送到派出所,拿回执,交罚款。

不知道飞牛这个会不会被罚款。

帮老板发招聘:

🚩 硅谷独角兽,总部旧金山,用技术支撑全球供应链的数字货代

🚩 业务复杂度很高,系统规模大、技术栈多样,能接触到分布式系统、数据平台、前后端完整工程体系

🚩 围绕 AI 有多条产品线和持续工程投入

🚩 团队氛围好,WLB 拉满,待遇优渥

有多个不同 level 的 open hc

Hiring manager 直招,无中间环节

要求英语读写熟练,有基本的口语能力

JD 👉 aHR0cHM6Ly9qb2ItYm9hcmRzLmdyZWVuaG91c2UuaW8vZmxleHBvcnQvam9icy82NzMzNDIzP2doX2ppZD02NzMzNDIz

也欢迎直接发简历给 dGVjaGhpcmluZ2xpdUBnbWFpbC5jb20=

  1. 物理机直接安装 ubuntu, 所有应用都部署在 docker
  2. ssh 只允许密钥登录, 禁止 root 用户登录
  3. 所有访问( http, tcp)都通过 nginx 代理, ufw 只暴露固定的几个端口, nginx 开启 https 证书
  4. nginx 配置 geolite2, 禁止任何 国外 ip 访问, 异常访问基本都是国外 ip
  5. fail2ban 自动封禁所有 nginx 日志里面国外 ip
  6. 不安装 1panel,宝塔等任何 web 管理工具, 直接 ssh 到机器上命令行管理

分享下我的 nginx 配置

load_module "modules/ngx_http_geoip2_module.so";
load_module "modules/ngx_stream_geoip2_module.so";

worker_processes 4;

error_log /var/log/nginx/nginx_error.log;
error_log /var/log/nginx/nginx_error.log notice;
error_log /var/log/nginx/nginx_error.log info;

pid /var/log/nginx/nginx.pid;

events {
    worker_connections 1024;
}


http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
      auto_reload 24h;
      $geoip_country_code  default=Unknown source=$remote_addr country iso_code;
      $geoip_country_name  country  names  en;
    }
    geoip2 /etc/nginx/geoip/GeoLite2-City.mmdb {
      auto_reload 24h;
      $geoip_city   default=Unknown city names en;
    }

    map $geoip_country_code $allowed_country {
        default no;
        CN yes;
    }

    map $remote_addr $allowed {
        default $allowed_country;
        127.0.0.1 yes;
        ~^192\.168\.\\d+\.\\d+$ yes;
        ~^172\.16\.0\.\\d+$ yes;
        ~^172\.17\.\\d+\.\\d+$ yes;
    }

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' "";
    }

    log_format json_analytics escape=json '{'
    '"timestamp": "$msec", ' # request unixtime in seconds with a milliseconds resolution
    '"request_id": "$request_id", ' # the unique request id
    '"request_length": "$request_length", ' # request length (including headers and body)
    '"body_bytes_sent": "$body_bytes_sent", '
    '"remote_addr": "$remote_addr", ' # client IP
    '"time_iso8601": "$time_iso8601", '
    '"request_uri": "$request_uri", ' # full path and arguments if the request
    '"code": "$status", ' # response status code
    '"http_host": "$http_host", ' # the request Host: header
    '"server_name": "$server_name", ' # the name of the vhost serving the request
    '"request_time": "$request_time", ' # request processing time in seconds with msec resolution
    '"upstream": "$upstream_addr", ' # upstream backend server for proxied requests
    '"request_method": "$request_method", ' # request method
    '"allowed": "$allowed", '
    '"geoip_country_code": "$geoip_country_code", '
    '"geoip_country_name": "$geoip_country_name", '
    '"geoip_city": "$geoip_city"'
    '}';

    access_log /var/log/nginx/access.log json_analytics;
    error_log /var/log/nginx/error.log warn;

    set_real_ip_from 0.0.0.0/0;
    real_ip_header X-Real-IP;
    real_ip_recursive on;

    sendfile on;
    server_tokens off;
    keepalive_timeout 65;

    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    proxy_buffering off;
    proxy_buffers 4 128k;
    proxy_buffer_size 256k;
    proxy_busy_buffers_size 256k;



    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL;

    ssl_certificate /etc/nginx/ssl/fullchain.cer;
    ssl_certificate_key /etc/nginx/ssl/xxx.cc.key;


    include /etc/nginx/conf.d/*.conf;

}


stream {

    geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
      auto_reload 24h;
      $geoip_country_code  default=Unknown source=$remote_addr country iso_code;
      $geoip_country_name  country  names  en;
    }
    geoip2 /etc/nginx/geoip/GeoLite2-City.mmdb {
      auto_reload 24h;
      $geoip_city   default=Unknown city names en;
    }



    map $geoip_country_code $allowed_country {
        default no;
        CN yes;
    }

    map $remote_addr $allowed {
        default $allowed_country;
        127.0.0.1 yes;
        ~^192\.168\.\\d+\.\\d+$ yes;
        ~^172\.16\.0\.\\d+$ yes;
        ~^172\.17\.\\d+\.\\d+$ yes;
    }

    log_format json_analytics escape=json '{'
    '"timestamp": "$msec", ' # request unixtime in seconds with a milliseconds resolution
    '"connection": "$connection", ' # connection serial number
    '"pid": "$pid", ' # process pid
    '"remote_addr": "$remote_addr", ' # client IP
    '"remote_port": "$remote_port", ' # client port
    '"time_iso8601": "$time_iso8601", ' # local time in the ISO 8601 standard format
    '"upstream": "$upstream_addr", '
    '"protocol": "$protocol", '
    '"allowed": "$allowed", '
    '"request_method": "STREAM", '
    '"geoip_country_code": "$geoip_country_code", '
    '"geoip_country_name": "$geoip_country_name", '
    '"geoip_city": "$geoip_city"'
    '}';

    access_log /var/log/nginx/access.log json_analytics;
    error_log /var/log/nginx/error.log warn;

    include /etc/nginx/stream.d/*.conf;
}

ssh 代理

map $allowed $ssh_server {
    yes ssh;
}

upstream ssh {
    server  192.168.5.1:1234;
}

server {
    listen    5678;
    listen [::]:5678;
    proxy_pass $ssh_server;
    proxy_connect_timeout 30s;
    proxy_timeout 60s;

    ssl_preread on;
}

http 代理

server {
    server_name x.x.com;
    listen 1233 ssl;
    listen [::]:1233 ssl;

    http2 on;
    charset "utf-8";

    if ($allowed != yes) {
        return 404;
    }

    error_page 497 =307 https://$host:$server_port$request_uri;

    client_max_body_size 512M;
    proxy_buffering off;


    set $backend "http://192.168.5.1:1234";
    include /etc/nginx/conf.d/basic/no_log.conf;

    location / {
        proxy_redirect off;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass $backend;
    }

}