部署Tailscale的中转服务器的过程

了解Tailscale很久,但是基本很少用,常用的场景下基本没有办法直联,官方中继延迟太高了。后来突然有一天了解到,tailscale可以自行部署中转服务器derp,于是就打算部署一个来解决延迟太高的问题. 过程中基本是按照官方文档来进行操作,文档本身已经写的很好了,只是正好不是我的母语,tailscale我又没有特别的深入使用,同时又有不少专属名词,导致有点东西理解,因此大概折腾了一周左右,反反复复的折腾,才算是真正的搞好和理解。 下面是具体操作步骤: 打开云服务器的防火墙设置,当前教程下需要开启10443(tcp协议),3478(UDP协议), icmp协议的防火墙策略。以上防火墙策略是必须的。 在云服务上安装go应用程序,具体参考go官网 执行一下命令,安装并编译最新的derper程序。(这个步骤可能在你的tailscale无法连接到这个中继服务器的时候重复执行,以保持与tailscale各个客户端的兼容性) go install tailscale.com/cmd/derper@latest 安装certbot程序(其实就是Let`s Encryept)来获取https证书, 具体安装步骤见certbot官网 执行一下命令获取https证书,一切按照默认继续下去即可。具体意思就是单独获取你域名的nginx证书,并保存到指定路径。 sudo certbot certonly --manual --preferred-challenges dns -d <你的域名> 上一步获取到https证书之后,会打印出来证书保存的路径。其中fullchain.pem和privkey.pem分别代表你证书的crt和key,在很多地方使用https证书的时候会指定具体的crt和key文件路径。我们通过ln -s命令分别创建privkey.pem的副本,并重命名为.crt和.key的后缀文件。 sudo ln -s <cerbot证书保存路径>/fullchain.pem <cerbot证书保存路径>/<你的域名>.crt sudo ln -s <cerbot证书保存路径>/privkey.pem <cerbot证书保存路径>/<你的域名>.key 启动derper程序开启中继服务 sudo <go的bin目录>/derper -a :10443 --http-port=-1 --hostname=<你的域名> -certmode manual -certdir <cerbot证书保存路径> --verify-clients -a :10443 指定https服务的监听端口为10443,且监听所有网口 http-port=-1 不开启http服务 hostname 指定你的derp中继服务的对外域名 certmode manual代表手动管理https证书 certdir 指定手动管理的https证书的具体路径 –verify-clients 代表需要校验tailscale的客户端,这个可以去掉(第8步无需执行)。但是就意味着你的服务谁都可以使用 在云服务器上安装tailscale客户端,并登录授权,具体参考官网。...

2024-12-15 14:41 · 1 min · 江波·林沂

返利插件后台服务器崩溃与恢复的一点感想

去年5,6月份的时候,临时兴起写了一个京东返利插件。放到chrome和edge的插件市场,没啥流量,不过每天也有点人用,高峰期大概可以给我攻陷个差不多200的收入。 前两天研究rspress,想把我的返利插件的文档页面重构一下,更美观一点。当时手残的就在返利插件的后台服务器上使用vscode尝试。心想一个静态网站生成器吗,没啥大问题,我之前在上面跑rust开发也没出现什么大事。谁知道就坏在这个上面。 在修改一个文件重新编译生成的时候,系统竟然没反应了,我以为可能是网络卡顿了,谁知道差不多10分钟也没恢复,登录到腾讯云控制台,发现cpu和内存同时爆到到99%以上。没办法,只能重启。谁知道重启之后,ssh竟然链接不上,通过控制台的vnc连接工具连接到机器上,发现启动的时候死在了cloudflared服务上。不知道我当初怎么安装的,竟然自启动cloudflared,然后还没其他成功,导致整个系统完全进入不来kernel. 由此而来第一个教训就是不能在生产机器上进行无关生产操作的其他任务,说不定什么时候这个任务就会导致生产服务器崩溃。 这就坑了,本来就是个重启解决的问题,现在要解决系统问题了。拜托了google和chatgpt搞了半天也没解决怎么进入系统问题。还好腾讯还有个救援模式,通过vnc进入之后还可以挂载原来机器的数据,否则数据丢失就坑了。虽然用户不是很多,涉及的钱也不多,但是也不能白白浪费了。 vnc连接机器虽然可以挂载原来机器数据,但是不能直接下载。好在我有台nas,通过cloudflare可以webdav暴露到公网。简单的通过curl将重要数据传递到nas上之后我重装了服务器,然后很快的就恢复了服务。 从系统崩溃到最终恢复过去了大概12小时,仅操作尝试就花了大概4个小时。主要还是不太了解linux的启动过程,导致在排查启动问题时就消耗了很长时间,最终还没有解决。其次,就是数据备份不存在,导致后续通过救援模式进入系统之后要重新备份数据,因为救援模式不太好安装新的工具,只能通过curl命令上传webdav简单的备份数据,如果遇到大量的数据,那么就花费更多的时间。最终的纯系统重装及恢复服务,其实到并没有花费太多的时间。 由此也可见数据备份的重要性。也就是我这个服务用户量小,影响面低,如果换成其他重要服务,这么长的恢复时间就会造成很大的损失。如果有完善的数据备份,那么完全可以开一台新机器很快的恢复服务。 在最终备份数据的时候还发现另外一个问题。因为这个插件的后台我开发的有段时间且后续也没有怎么维护,导致数据备份的时候差点忘记一块重要的数据。这个时候就体现出项目readme.md的重要性了。核心内容及操作一定要记录其中,否则过了一段时间之后,即使你是当初的开发者,有意外情况发生时也会忘记重要步骤,从而导致事故。

2024-02-20 16:11 · 1 min · 江波·林沂

使用rust入门discord机器人遇到的一些坑

最近几天在研究discord,其实之前也玩过,只不过当时没怎么玩下去,感觉怎么用都不知道。这两天感觉突然开悟了,用起来非常顺手,突发奇想弄个discord的bot玩玩。 快进到官网的教程,在进入开发之前的步骤非常流程,新加的机器人顺利的加入了群组,但是接下来的就看不懂了。 官网的示例是用的http做的,我研究了一下rust下的相关库,找到了serenity。看了看它的hello world,倒是也正常跑起来了,但是这鬼东西,连个http的端口都没有,怎么让discord访问呢? 接着又去研究官网,研究了了一两天,我发现discord还有一种使用websocket的连接方案。猜一下,大概率serenity大概率用的这种方案,这也就解释了它为什么不需要http的端口了。直接都连上了discord服务器的websocket,还需要什么自行车。暴露什么端口徒增风险呢。 仔细一想,serenity使用websocket其实是满明智的,Im这种应用消息的频率是相当高的,如果使用http的话,目标服务器的负载基本上都是很大的,毕竟很大一部分bot是需要读取频道里面的每条消息的,一个成熟的bot是会有相当多的频段和用户消息的,这个时候可以复用tcp通道,主动接受推送的websocket简直不要太合适。 知道了serenity是使用websocket的,那么它的示例应该是可以正常让机器人在线的啊,我应用都跑起来了,不科学啊,这么广泛使用的类库不应该会犯这么低级的错误。 这个时候尝试了一下telnet discord的wss服务器,我靠,果然是不通的,这个示例怎么还一直正常运行,这不是坑爹吗。调整日志级别,打印出serenity的DEBUG日志,看日志果然是连接discord的wss服务器异常,而且DEBUG级别日志下,应用自己报错关闭了,真坑。 知道网络不通剩下就好办了,打开clash for windows的tun模式,再次启动程序。我的discord bot终于正常上线了。 在频道中输入!ping, bot自动回复了Pong。终于discord的入门级bot完成了!!!!

2023-08-07 17:29 · 1 min · 江波·林沂

用rust调用pytorch的一点记录

最近在研究openAI的CLIP模型,但是python的水平不够,写起来总感觉别扭。就随手搜了一下,发现正好tch做了一层libtorch的包装,使用rust来调用pytorch还是相当顺手的,就跟着tch的README来做一点尝试。 解释一下:pytorch的底层其实就是libtorch,这个是使用c++写的,可以理解pytorch是libtorch的python包装。 以下所有尝试都是在windows的wsl上操作的,具体linux版本为ubuntu/22:04 使用tch的前提: conda(我使用的是miniconda3) rust(1.71.0) python(3.11.4) pytorch(2.0.1) 我在这里没有使用miniconda3的默认env,而是创建了一个tch的专用env,使用了以下命令 conda create -n rust_pytorch1 pytorch 命令的意思就是就是创建一个名字叫做rust_pytorch1的env,并在其中安装pytorch。 下面,我们使用命令激活这个env conda activate rust_pytorch1 按照tch的README我们还需要下载libtorch,这个需要在页面根据自己的环境进行选择,我这边只有cpu环境,因此选择的是libtorch的cpu版本。我们可以在页面https://pytorch.org/get-started/locally/自行选择自己需要的版本并下载,然后解压到指定目录即可。 我们通过export导入环境变量,以便程序知道libtorch的路径,使用以下命令 export LIBTORCH=/home/jiangbo212/libtorch 这个时候我们cargo run运行README上的Tensor的例子时,可能会得到一个cc的编译错误。这时需要执行以下命令,导入一个变量。具体原因暂时未知。 export LIBTORCH_CXX11_ABI=0 此时,我们运行cargo run,依旧可能得到以下错误: error while loading shared libraries: libtorch_cpu.so: cannot open shared object file: No such file or directory 这是由于cargo找不到libtorch.so的路径,虽然我们在前面导入了LIBTORCH的位置。需要执行以下命令, 让cargo可以在LD_LIBRARY_PATH下找到libtorch的lib路径 export LD_LIBRARY_PATH=/home/jiangbo212/libtorch//lib:$LD_LIBRARY_PATH 最后,我们运行cargo run, 可以看到正常输出了Tensor。

2023-07-28 09:39 · 1 min · 江波·林沂

从Vue2迁移到Svelte

本文翻译自https://escape.tech/blog/from-vue2-to-svelte/ 在使用Vue2作为我们的前端框架差不多快两年后,它被宣布不再继续维护,因此我们决定迁移到一个新的框架。但是哪一个是我们应该选择的呢?Vue3 OR Svelte。 需要注意的是在这次迁移中我们也需要提升我们的开发体验,特别是在类型检查, 高性能以及构建时间方面。我们没有考虑React,因为我们没有太多的时间去学习。同时相对于Vue和Svelte,它也没有提供一个开箱即用的方案。此外,Vue和Svelte使用了相同的单文件组件概念:逻辑(javascript), 结构(html), 样式(CSS)在同一个文件中。 我们做了一些研究,最终选定了Svelte。下面一些解释关于为什么选择Svelte: Svelte PK Vue3 Svelte拥有更好的学习留存率。我们选择了市场上两个新的前端框架,Vue3和Svelte。下面是一个插图,显示的是不同框架在过去5年的留存率。从State of JS survey收集的该领域的开发人员的数据,我们可以看到Svelte来到了第2的位置,而Vue3仅排名第4。 In 2021 Svelte was in the 2nd position and Vue 3 in 4th position (source: State of JS) 这张图显示过去使用Svelte的开发人员在将来更愿意使用他们 更好的类型检查 Svelte 通过更简单的组件设计过程和内置类型化事件提供更好的类型检查体验,这对我们来说非常人性化。 严格的全局访问 在Svelte中可以从其他文件导入枚举,并在模板中使用它们,在Vue3中是不存在这种情形的。 Escape Benchmark about frontend stack 语法 主观的,我认为Svelte的语法相比于Vue更加的人性化和友好。你可以看看下面这些代码块,想下自己是什么感觉。 Svelte <script> let firstName = ""; let town = ""; $: fullName = "Full name: " + firstName + ' ' + lastName; const reset = () => { firstName = ""; lastName = ""; } </script> <main> <div> <label>First name</label> <input type="text" bind:value={firstName}> <label>Last name</label> <input type="text" bind:value={lastName}> <button on:click={reset}>Reset</button> </div> <div> {fullName} </div> </main> <style> main{ background-color: white; } </style> Vue...

2023-02-10 16:07 · 2 min · 江波·林沂