只让服务器流量走 VPN

背景 服务器在学校的校园网中,然后平时需要使用 Easy Connect 连接学校的 VPN 之后,才能通过 SSH 连接到服务器。但是学校配置的 VPN 又很烦人,会接管本机上的所有流量走校园网,导致访问其他网站的速度很慢,并且连接不上外网用不了 GPT 之类的麻烦。 学校提供的 VPN 服务有两种软件可以使用,一个是 Easy Connect,一种是 Open VPN 。两种我都尝试了,都是登陆的同样的账号,但是openvpn始终ssh连接不上学校内网中的服务器,但是 Easy Connect 却可以。所以之后我都是在 Easy Connect 上进行操作的。 发现问题 发现启动 VPN 软件之后,运行ifconfig可以看到本地会多一个utun*的网络接口,然后运行netstat -rn查看电脑的路由表中可以看到,有大量的路由配置信息指向了这个utun*的网络接口。 之前之所以连接上了 VPN 之后无法正常的访问外网,是因为学校的 VPN 服务器推送了很多的路由,几乎涵盖了从1.*.*.*到255.*.*.*中的所有路由,全部设置为走utun*。即使我的default路由走的是我正常的网口,但是具体的路由的优先级是要比default路由要高的,所以几乎全部都走了 VPN 。 解决思路 有两个方法可以解决这个问题: 1 在Docker上运行 VPN 软件进行转发 在本地启动一个Docker,然后让 VPN 运行在 Docker 内,将走服务器IP地址的流量走到 Docker 容器内,然后在容器内走 VPN 出去。这个方法肯定是可行的,不过感觉稍微麻烦了一点,采用了第二个idea 2 删除多余的路由表 在 VPN 软件启动之后,他不是注册了很多具体的路由嘛,而我的需求只是让服务器流量走 VPN 就可以了,其他的流量不用他管。所以写了一个脚本,在 VPN 软件启动之后运行就行。 脚本主要实现的功能是,在路由表中匹配 VPN 网口的所有路由,只保留我服务器那一条路由,其他的全部删除,就OK,简单又完美。 #!/bin/bash # 示例 # 提示用户输入网络接口名称 read -p "请输入 VPN 网络接口名称(例如utun6): " vpn_interface # 提示用户输入需要保留的服务器IP地址或网段 read -p "请输入需要保留的服务器IP地址或网段(例如192....

January 4, 2025 · 1 min · 132 words · sirius1y

Docker run hello-world 超时

问题描述 $ docker run hello-world Unable to find image 'hello-world:latest' locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers). See 'docker run --help'. 在安装完成docker之后,本来想运行一下 docker run hello-world测试安装成功与否,然后发现连接不上。 先测试以下curl这个网站的返回情况,发现返回401,说明 DNS 没有问题 $ curl -v https://registry-1.docker.io/v2/ * Uses proxy env variable no_proxy == '127.0.0.1,localhost' * Uses proxy env variable https_proxy == 'http://127.0.0.1:7890' * Trying 127.0.0.1:7890... * Connected to 127.0.0.1 (127.0.0.1) port 7890 * CONNECT tunnel: HTTP/1....

December 25, 2024 · 2 min · 402 words · sirius1y

BLOG迁移之旅

迁移的开始 在随着华为云服务器到期邮件和电话的轰炸之下,我终于开始行动起来要去迁移我的博客了。太久没有写博客,已经忘记了距离上一篇博文一经过了很久很久了,想不起来时间,只记得是在做 aorb 项目的时候写的。 也忘记了之前对博客进行了一系列 CI 的优化,现在已经能够实现提交博客内容到 git repo 上,会自动拉起 github action 进行检查和部署的操作。 不幸 然额呢,隐约记得我之前在部署的时候在 workflow 里面编写了一些机密 (secrets) 用于访问服务器但是又不公开,现在大体忘却了他们是干什么的了。服务器过了十二点就冻结了,现在晚上十点,明天下午有一个面试,可能面试官会看我的博客(虽然我大概知道他们不会这么做),但是还想在这之前把他修好。冰冷的房间,饥饿的肚子,颤抖的双手,宕机的脑袋…尝试了无论怎么修改 secrets 中的 private key,依然显示我的 SSH 验证不通过。似乎我隐约记得上次我也这么干过,在这里也卡住了。 … 还尝试了不用 github action,直接把它部署到云服务器上的方案,虽然最后也没成功(因为我后来发现这台新电脑上的博客拉下来之后本地都没有跑对页面)。 但是复习到了以下内容: 存放我们 public/ 代码的地方在 /var/www/blog/ 下,我是直接把 public/ 下的内容拿过的,没有要 public/ 这一层。这里要与 nginx 的配置相对应 nginx 的配置文件在:/etc/nginx/sites-availble/sirius1y.top,日志文件在 /var/log/nginx/error.log ,分析网站为什么返回403、404很常用的 检查 nginx 配置文件是否正确的命令:sudo nginx -t,重新加载 nginx 配置文件的命令 sudo systemctl reload nginx /var/www/下的文件所有者和组应该是 www-data,并且对目录和文件的权限有要求的 … 第二天晚上,在清醒的大脑之下,在排除了用户的权限和文件夹、文件的权限正确设置之后,google 了一下,发现网上有两种说法:https://github.com/openssl/openssl/issues/20054 。大概是: 添加一段 before_script 的代码 私钥后添加 \n 然后我尝试之后,由于我设置的用户没有 sudo 权限,所以在 before_scirot 中的 chmod 命令无法执行。然后就试了第二种方法,还是不行。然后我索性在私钥之后按下回车。然后,It works!...

December 16, 2024 · 1 min · 157 words · sirius1y

【go的源码阅读】context的实现:context.go

理解Context 这篇文章介绍的很清楚:深入理解Go Context 这个比较详细,但是层次不好:理解GO CONTEXT机制 关于context的使用场景 context的主要使用场景在于:一个任务在处理的过程中可能会启动很多个协程来进行处理。在这个过程中,如果上游的任务想要取消,下游的任务也应当一起取消。context的任务就来了。 内容介绍 context包的内容可以概括为:1个接口,4个实现,6个方法 接口 context.Context 一个接口是指:context.Context type Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chan struct{} Err() error Value(key interface{}) interface{} } Deadline( ) Deadline会返回一个超时时间,Goroutine获得了超时时间后,例如可以对某些io操作设定超时时间。 函数签名 Deadline() (deadline time.Time, ok bool) Deadline 返回的时间 deadline time.Time 代表这个ctx应该被取消的时间。返回的 ok 如果是 false 表示这个context没有设置deadline。连续调用 Deadline 会返回相同的结果。 // Deadline returns the time when work done on behalf of this context // should be canceled. Deadline returns ok==false when no deadline is // set....

July 26, 2024 · 14 min · 2785 words · sirius1y

gRPC调用坎坷历程记录

gRPC服务的架构图 RPC调用总的来说就是客户端调用存根的代码,然后存根代码和RPC库实现通信,服务端的存根收到了信息后交给具体的服务进行处理,之后再原路返回就完了。 这里附上一篇关于gRPC讲解的博客园的文章 Proto文件代码生成 项目的前后端都是使用的gRPC进行通信,都需要使用protoc编译器把之前定义好的proto文件进行编译生成对应的代码进行调用。 问题1 timestamp.proto文件找不到 timestamp.proto是google的一个时间戳的包,因为在我们自己的proto文件中使用到了google.protobuf.Timestamp,在proeo文件的最上方也要导入对应的proto文件import "google/protobuf/timestamp.proto"; 我记得在下载protoc编译器的时候,压缩包下面就有一个include文件夹,其中就包含有timestamp.proto文件 问题2 go代码生成对应的包名和位置对不上 项目的后端采用的是go,想要把proto文件编译成golang的代码。这就需要在proto文件中加上go_package的字段,比如: syntax = "proto3"; package rpc.auth; option go_package = "github.com/BigNoseCattyHome/aorb/backend/rpc/auth;auth"; import "google/protobuf/timestamp.proto"; // 定义消息,用于请求和响应结构 message LoginRequest { string username = 1; // 用户名/用户ID string password = 2; // 密码的md5摘要 string device_id = 3; // 设备ID google.protobuf.Timestamp timestamp = 4; // 时间戳 string nonce = 5; // 随机数 } 然后在使用protoc编译的时候,在命令行中也要加上go的一些选项,比如: protoc --go_out=. person.proto // 找到当前目录下的person.proto并生成go的代码,输出到当前目录(.) 但是又有了一个问题就是在该文件夹下面,会生成你的包名go_package的层级目录,最后才是你的最终代码。但是我想让proto文件直接生成在一个固定的文件夹位置,并且没有那么多的层级文件夹。 然后发现了有一个命令选项是--go_opt=paths=source_relative,使得生成的Go代码文件的路径与对应的.proto文件的路径保持一致 问题3 dart代码生成的时候老是存在找不到pb.xx 后来上google和stackoverflow看了半天,发现结果是依赖版本的问题,把protobuf的依赖版本从^2....

July 23, 2024 · 4 min · 662 words · sirius1y