RemoveAllEventListeners

没法直接移除所有监听器,难受死了,不过查了下 stackoverflow,发现有个叫做getEventListeners可以获取 EventTarget 的所有监听器。

于是我就基于这个函数,给 EventTarget 补上了RemoveAllEventListeners这个方法。

1
2
3
4
5
6
7
8
EventTarget.prototype.removeAllEventListeners = function (eventname) {
let listeners = getEventListeners(this)
if (listeners[eventname]) {
listeners[eventname].forEach((e) => {
this.removeEventListener(e.type, e.listener);
})
}
}

IPv6爬虫猛爬

IPv4的稀少让人很无奈,无法获得大量IP,而IPv6国家正大力推进,而且只要家里宽带支持ipv6,一般都会发下来最小一个/64段,大的可能给到/48甚至更大,同时,由于ipv6的海量性,除了依靠运营商提供外,还可以从不少的网站上直接申请到很大的一个ipv6段来使用,只不过要花点钱找支持bgp session的vps供应商,学习一堆相关的知识配置后才能使用。

受 zu1k 的 http-proxy-ipv6-pool的启发,结合我对于nodejs的理解,配置出了一个算是半起飞级别的爬虫。

本文将会简单介绍我在我的树莓派上配置ipv6爬虫的过程,从系统配置到删库跑路全过程。

首先,你需要确认你能够使用ipv6网络且有大段的ipv6使用,你可以在路由器上查找确认是否获得了公网ipv6地址,并有可用的公网ipv6 Lan前缀,如果你能够看到上面提到这些,并且能够在test-ipv6上去的10/10,那么恭喜你,你已经满足了一半的前提了。

然后,确认你的目标爬取站点是否支持ipv6,通常情况下,你只需要在命令行中打开nslookup,设置查询类型set type=AAAA,然后查询你所需要爬取的网站的域名,看返回的结果是否有ipv6地址,有的话,就满足另一半的前提了。

接下来是系统的配置工作,首先你需要安装一个ndppd,于是就sudo apt install ndppd,然后,因为我不会配置系统服务启动失败不影响重启,我是直接先systemctl stop ndppd,按需要去启动这个ndppd。ndppd的作用是向周围设备通报,我这里有这个段的地址,请把这些数据包发给我。我们首先创建一个ndppd的模板:

1
2
3
4
5
6
7
8
9
10
11
12
# /etc/ndppd.template.conf
route-ttl 30000

proxy eth0 {
router no
timeout 500
ttl 30000

rule 240e::1/64 {
static
}
}

然后我们编辑ndppd的服务脚本,我在他的启动部分增加了自动获取ipv6前缀并配置ndppd的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# /etc/init.d/ndppd
do_start()
{
sleep 5
ndppd_6=`ip -6 route | grep 240e | sed 's/::\/64.*$//g'`
log_daemon_msg "Grep IPv6 Prefix: $ndppd_6"
cat /etc/ndppd.template.conf | sed 's/240e::1/'$ndppd_6'/g' > /etc/ndppd.conf
ip -6 route add local "$ndppd_6"::/64 dev eth0
echo $ndppd_6:1794 > /etc/ndppd_ipv6_prefix.txt
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS || return 2
}

完成这一步之后,我们只需要systemctl start ndppd就开始使用这个ipv6段了,我一般建议是比你路由器上的Lan前缀小一点,确保不会干扰到你正常的ipv6上网。

这时候我们可以使用curl来测试你的ipv6配置是否正确

这里我是用zulk的例子

1
2
3
4
5
$ curl --interface 2001:19f0:6001:48e4::1 ipv6.ip.sb
2001:19f0:6001:48e4::1

$ curl --interface 2001:19f0:6001:48e4::2 ipv6.ip.sb
2001:19f0:6001:48e4::2

我们可以看到成功返回了我们指定的地址。

接下来就是结合你自己的爬虫程序,设定好请求时的源IP即可。

通常来说,家宽会每隔24小时强制重新拨号一次,这种情况下,你只需要重新启动,然后使用 systemctl start ndppd 启动我们的ndppd 即可恢复正常的继续爬取网站。

这里有很多不规范的东西,欢迎私信告诉我怎么修改。

WinSpy介绍

偷个懒,让bing介绍吧:

WinSpy是一个开源项目,它仿造了微软的Spy++工具。微软的Spy++是Visual Studio上的工具,用于检查和修改任何Windows程序的窗口属性。如果您没有安装VS,可以选择使用WinSpy。
原项目地址为: https://github.com/strobejb/winspy ,但是原项目最后更新时间为9年前。好在GitHub还有其他人维护该项目,在其最受欢迎的分支中,找到了最近的更新: https://github.com/m417z/winspy
您想了解更多关于WinSpy的信息吗?

我为了搜这个东西搜了两个小时你会相信。。。

CPP与CodePage最终解决之路

因为https://github.com/shugen002/DesktopLricsFix这个项目再次和Github Action打架。

这个项目是个C++的随手项目吧,中间夹了一堆中文,本地编译还好好的,结果上去编译就给我炸了

1
2>D:\a\DesktopLricsFix\DesktopLricsFix\DesktopLricsFix.cpp(10,15): warning C4566: character represented by universal-character-name '\u7F51' cannot be represented in the current code page (1252) [D:\a\DesktopLricsFix\DesktopLricsFix\DesktopLricsFix.vcxproj]

显然又是一个CodePage的导致的错误,我试了一堆解决方案都不行,最终看了这篇文档后 https://learn.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-170 ,发现原来/utf-8实际上是/source-charset:utf-8 /execution-charset:utf-8的结合,根据我项目的实际情况,代码是用UTF-8编写的,而最终执行环境是个简体中文的GB2312,抱着垃圾巨硬的心态试了试本地编译直接加/utf-8,符合预期的乱码了,于是又试了下/source-charset:utf-8 /execution-charset:gb2312,欸,正常了,上传到Github编译一波试试,成了!。

项目配置

成果

解释一下这两个选项吧,/source-charset:utf-8表示源码是个utf-8/execution-charset:utf-8表示最终执行环境是个gb2312,在没有指定的情况下,前者会根据BOM头判断,没有则按系统代码页,而后者则是直接按系统代码页。

在这里,由于Github Action上面的执行环境是个英文的cp1252导致代码中的中文全部寄掉了。

顺带一提,你在msbuild前面加chcp 936 &&之类的做法没用。

linux 连不上 127.0.0.1

碰上了点阴间的情况,debian 11系统居然连不上127.0.0.1

查了一轮,最后竟然是环回网卡lo没有地址,过于惊讶,特此记一笔。

先来一波ip addr

1
2
3
4
5
6
7
8
9
10
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
altname enp0s17
altname ens17
inet xx.xx.xxx.xx/24 brd xx.xx.xxx.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::dad5:d8ff:fe00:74e/64 scope link
valid_lft forever preferred_lft forever

可以看到lo下面是没有地址的,这时候只需要来一句 ip addr add 127.0.0.1/8 dev lo 就能解决问题,如果开启了ipv6,建议再来一句 ip addr add ::1/128 dev lo

::1/128是ipv6的环回地址。

Powershell-Timing

不知道为什么,我每次 build 项目的时候,总是感到十分慢。

于是我想去看看我到底浪费了多少时间在等待项目构建,先去看来一眼 Github Action 上的计时,咦,才两分钟,并不久啊,难道是我电脑太差了?

不行,我得去实际测试一下项目在本地的构建用时,去谷歌搜了一轮, Measure-Command 这个东西进入我的视野,我就知道,Powershell 这玩意必定会有这些功能的!

1
Measure-Command { npx vite build | Out-Default }

走你

1
2
3
4
5
6
7
8
9
10
11
Days              : 0
Hours : 0
Minutes : 1
Seconds : 10
Milliseconds : 867
Ticks : 708677304
TotalDays : 0.000820228361111111
TotalHours : 0.0196854806666667
TotalMinutes : 1.18112884
TotalSeconds : 70.8677304
TotalMilliseconds : 70867.7304

emmm 也就一分多钟,看来是我对于等待的忍受能力下降了。。。

顺带一提, Measure-Command 接受的一个代码块,所以中间你可以塞一堆命令,然后计时,这样就可以计算出这个代码块的执行时间了。

但由于 Measure-Command 吞掉了输出,所以我们需要通过 Out-Default 来输出中间命令的输出。

NginxProxyManager和Vaultwarden结合

之前翻这玩意的文档翻得太累了,搞了一大轮才明白这玩意到底该怎么配。

如果你不需要使用 Vaultwarden 的自动同步,那么你直接无脑写了Forward Hostname/IP和端口就可以了,并不需要下面的设置。

启用 Vaultwarden 的 WebSocket

Vaultwarden 的 websocket 服务器默认是关闭的,这个地方坑了我几轮,后面才发现这个配置是必须的。

只需要在 docker 的环境变量中添加WEBSOCKET_ENABLED=true即可。

在 NginxProxyManager 中配置 Vaultwarden

Detail 部分不用说了,直接写就完事了,这个是额外需要添加的部分。

由于 Vaultwarden 的 websocket 服务器是运行在另一个端口 3012 上,并没有和网站的 80 端口合并,所以产生了这个配置的需求。

首先是在Detail中把Websockets Support打开,

然后在Custom locations中添加如下配置:

1.

1
2
3
4
Define location `/notifications/hub`
Scheme `http`
Forward Hostname / IP `你的服务器的IP地址`
Forward Port `3012`

2.

1
2
3
4
Define location `/notifications/hub/negotiate`
Scheme `http`
Forward Hostname / IP `你的服务器的IP地址`
Forward Port `80`

就这样。

一条可能有用的forge查卡顿指令

偶尔被人喊去查服务器卡顿的原因,虽然爱看不看吧,但有时候会忘了还有这几条指令的存在,在这里记一笔,后续可以翻查。

/forge track

开始跟踪实体及方块实体的用时:

1
/forge track start <entity|te> <duration>

查看跟踪结果:

1
/forge track <entity|te>

返回的数据大概是这样的

1
2
3
4
5
6
7
8
9
10
[23:50:29] [Server thread/INFO]: alexsmobs:laviathan - minecraft:the_nether [317, 23, -433]: 352.60ms
[23:50:29] [Server thread/INFO]: minecraft:axolotl - minecraft:overworld [387, 67, -87]: 309.33ms
[23:50:29] [Server thread/INFO]: minecraft:axolotl - minecraft:overworld [392, 64, -85]: 284.93ms
[23:50:29] [Server thread/INFO]: minecraft:axolotl - minecraft:overworld [392, 64, -89]: 246.71ms
[23:50:29] [Server thread/INFO]: minecraft:axolotl - minecraft:overworld [387, 65, -89]: 236.62ms
[23:50:29] [Server thread/INFO]: minecraft:axolotl - minecraft:overworld [387, 64, -89]: 235.05ms
[23:50:29] [Server thread/INFO]: alexsmobs:crow - minecraft:overworld [140, 72, -221]: 230.03ms
[23:50:29] [Server thread/INFO]: alexsmobs:tasmanian_devil - minecraft:overworld [-21, 73, -184]: 228.14ms
[23:50:29] [Server thread/INFO]: minecraft:axolotl - minecraft:overworld [388, 63, -86]: 206.64ms
[23:50:29] [Server thread/INFO]: alexsmobs:crow - minecraft:overworld [525, 63, -162]: 197.49ms

就是 实体类型 - 世界名称 [坐标]: 时间 的样子,基本上看着就能看出来了。

清空跟踪数据:

1
/forge track reset <entity|te>

无聊的ilo提权

简单的科普

如果有接触过实体服务器的人可能会知道有个东西叫 ipmi 服务,给不知道的同学简单讲讲这个有什么用。

智能平台管理接口(Intelligent Platform Management Interface)原本是一种 Intel 架构的企业系统的周边设备所采用的一种工业标准。IPMI 亦是一个开放的免费标准,用户无需支付额外的费用即可使用此标准。
IPMI 能够横跨不同的操作系统、固件和硬件平台,可以智能的监控、控制和自动回报大量服务器的运作状况,以降低服务器系统成本。

上面是中文维基百科的定义,看起来很迷惑对不对,我简单的说,就是你可以借助它在不依赖服务器系统,不在服务器旁边的情况下,操作服务器,哪怕服务器系统坏掉了,你也可以在不到服务器旁边完成重装的操作。

我们对于 ipmi 服务,最常用的就是一个远程终端(画面加键鼠操作),还有开关机,稍微少一点就是挂载镜像,更偏门的就是远程刷 bios 固件(对,部分厂商的 ipmi 服务甚至可以刷 bios 固件)。对于天天用云服务的同学的话,就是也是一样开关机和 vnc 远程连接,挂载一般都是云硬盘之类的。

(之前在 B 站看到一个老哥直播自己工作,内容应该就是测试服务器 bios,直接就在 ipmi 界面上刷 bios 固件。

似乎有个 ipmi 在等我

因为还是前面开服那个淘宝卖家,因为某些原因,系统的文件系统炸裂了,偏偏炸的还是根分区,不知道是我技术不到家还是怎么的,没办法在系统中跑 fsck 来修复,这就很伤脑了,只能希望进 rescue 模式看看能不能修复,进这个的话是需要在系统引导时来进入。

于是我就隔着淘宝卖家的远程桌面操作这个 vnc,在这个过程中,我发现,似乎这个 vnc,并不是那么纯正的 vnc,露出一堆 ipmi 的玩意,同时还暴露给我了ipmi 的内网 ip,是一个 java 的玩意,掉线了还不会自己重连,于是我就想了,能不能直接连,之前试过问能不能给 ipmi,他说只有这个 vnc。

无聊的提权

我试着操作同机房有内网的机器,直接 SSH 映射这个 ip 的 443 到我电脑伤,试图确认是不是同一个内网,意外的是,居然是用一个内网,很顺利的给了我一个虽然证书不对,但确确实实是一个 HP 的 iLO 登录界面给我。

(为什么是映射 443 呢,因为上面这个 vnc 露出 ip 的同时,暴露是一个 java 的程序,进而推断出是个 jnlp,那么必然是个 http 服务,盲猜一下 443 不过分吧)

既然到了这了,我们当然是想办法登录啊,我就去搜这个默认密码了,但毕竟是企业级的玩意啊,虽然老一点,默认密码都是每台机不一样的,这就尼玛坑爹了,试了下面板上给的其他密码,也是错误。但这个搜索并不是完全没用的,告诉我一个事情,就是你可以在服务器启动过程中进这个 iLo 的管理界面直接新建用户或重建用户来实现重置密码!

于是重启服务器,在 vnc 中进 iLo 管理界面,新建用户,网页登录,轻松提权!

上不去的 console

登录成功后,当然是自己进 console 操作啊,但这时候发现了个问题,.net java 的 console 全都起不来,没办法,只能去惠普那边下了个 HP iLO Integrated Remote Console。

程序有了,登录也过了,但就是没画面,秒断线,这他妈坑爹啊,但想了想,可能还差点什么。

仔细查了下,原来还得映射多几个端口

端口号 说明
22 Secure Shell (SSH) Port
80 Web Server Non-SSL Port (HTTP)
443 Web Server SSL Port (HTTPS)
17988 Virtual Media Port
17990 Remote Console Port

22 这个大概不是,80 和 443 可能要用,17988 和 17990 应该是没跑。

补了一波映射,我现在用的映射命令是这样

1
ssh -L 17990:内网IP:17990 -L 443:内网IP:443 -L 80:内网IP:80 -L 17988:内网IP:17988 root@跳板IP

这个我只测试了 hp 的,没去测试其他牌子的,虽然手上有其他牌子机子,但不方便重启来提权,有缘再补更详细的吧。

后记

那个租服务器给淘宝卖家的人表示惊呆加害怕。