如何通过VPS上设备唯一的标识生成UUID

目的

希望在VPS上多次运行脚本时, 不需要输入UUID, 但能使得搭建梯子的过程中, 用到的UUID固定. 这样翻墙客户端的节点信息不需要更新.


过程

问了一下GPT的建议, 用 blkid



1. 在 HAX 上面执行, 得到这样一行的结果

root@391932510hax:~# blkid
/dev/ploop26075p1: UUID="170458b2-6bc7-4820-b908-33b71b3bbe0b" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="6c2c4759-ffdb-4248-aa56-d1c03eabf846"

注意到里面有 UUID="..." 还有 PARTUUID="..." 所以我决定用正则表达式写出UUID的格式来匹配.

用 sed 和正则表达式写成这样:

blkid | sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g'

执行, 得到正确的结果:

root@391932510hax:~# blkid | sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g'
6c2c4759-ffdb-4248-aa56-d1c03eabf846

 2. 在 Racknerd 的VPS上面执行, 得到下面这样的结果, 是多行的.

root@crazypeace:~# blkid | sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g'
6f428b8e-676e-49e1-84e1-7783a21804ce
aad632ec-ca02-4417-be8a-ae20cb1faed4
查看一下 blkid 原本的样子, 原来本来就是多行的.
root@crazypeace:~# blkid
/dev/vda1: UUID="6f428b8e-676e-49e1-84e1-7783a21804ce" TYPE="ext4" PARTUUID="2eb406ac-01"
/dev/vda2: UUID="aad632ec-ca02-4417-be8a-ae20cb1faed4" TYPE="swap" PARTUUID="2eb406ac-02"

那么我们用 head 来帮忙

blkid | sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g' | head -1

结果就正确了

root@crazypeace:~# blkid | sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g' | head -1
6f428b8e-676e-49e1-84e1-7783a21804ce


3. 在VC鸡上面执行, 得到下面这样的结果, 完全没有正确的答案

root@5032-vpsvc:~# blkid | sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g' | head -1
/dev/sr0: BLOCK_SIZE="2048" UUID="2023-06-17-04-46-45-00" LABEL="cidata" TYPE="iso9660"

查看一下 blkid 原本的样子, 原来第一行就不包含符合条件的UUID

root@5032-vpsvc:~# blkid
/dev/sr0: BLOCK_SIZE="2048" UUID="2023-06-17-04-46-45-00" LABEL="cidata" TYPE="iso9660"
/dev/sda1: UUID="56c6249c-209a-427a-82c8-95a4cbe15687" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="11e06615-bf2f-524a-bd5d-2991360466f2"
/dev/sda15: SEC_TYPE="msdos" UUID="BB09-C166" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="a09b3906-b77a-914f-9a99-46b8f182662f"
/dev/sda14: PARTUUID="997dd1fe-ed57-0a4f-8c21-940577797c9a"

那么我们要用sed -n参数, 让sed默认不打印; 再用 /.../p 的命令打印我们想要的部分. /.../p的命令可以和已有的s/../.../g结合起来.

blkid | sed -nr 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/gp'

测试一下, 结果只剩下UUID了

root@5032-vpsvc:~# blkid | sed -nr 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/gp'
11e06615-bf2f-524a-bd5d-2991360466f2
a09b3906-b77a-914f-9a99-46b8f182662f
997dd1fe-ed57-0a4f-8c21-940577797c9a
再加上 head 就可以了.
blkid | sed -nr 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/gp' | head -1


4. 转换为perl语句

sed和perl在处理正则表达式时, 在很多情况下是可以互相转化.

思路是一样的, 用 -n 参数关闭默认的打印; 再用 print 打印.

blkid | perl -ne 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g and print'


5. 申请了一台Woiden鸡 测试重装系统

发现重装系统之后, blkid 得到的结果会变化. 那只好转换思路. 

GPT说, 可以用系统网卡的MAC. 先用 ip a 查询, 再找其中的 ether 关键字.

ip a | grep ether

结果发现, 在OpenVZ虚拟化的VPS上(比如 hax, woiden), 查不到MAC地址.


6. 那么我就设想, 以IP地址作为种子, 去计算UUID.

这样很合理啊, 如果IP都变了, 翻墙客户端的节点参数也是要更新的. 那UUID换一下, 也关系的. 或者说, 一个VPS上多IP, 这样当你决定把梯子搭在某个IP上时, 

学习了一下UUID的规范, V1 和 V4 是随机生成, V3 和 V5是可以根据种子生成的. Google了一下 UUID V3, 找到这个网站 https://www.uuidtools.com/v3 

网站还提供 API 使用, 


形如:

https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/base64:Y3JhenlwZWFjZQ==

猜想应该可以不用base64, 直接用种子字符串, 形如:

https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/crazypeace

找个VPS一试, 果然是这么回事.

root@391932510hax:~# curl -sL https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/crazypeace
["b9a609e2-82c7-3898-9c8b-e049b268447a"]root@391932510hax:~# 

结合我们取IP地址的方法

curl -sL https://www.cloudflare.com/cdn-cgi/trace | grep -oP "ip=\K.*$"

得到

curl -sL https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/$(curl -sL https://www.cloudflare.com/cdn-cgi/trace | grep -oP "ip=\K.*$")

测试一下, 结果不错.

root@391932510hax:~# curl -sL https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/$(curl -sL https://www.cloudflare.com/cdn-cgi/trace | grep -oP "ip=\K.*$")
["976bb2fa-6685-3e06-907f-9133e1536320"]root@391932510hax:~# 
注意结果是个JSON格式, 是带着括号和双引号的. 

参考前面折腾命令行的结果, 综合起来为:

curl -sL https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/$(curl -sL https://www.cloudflare.com/cdn-cgi/trace | grep -oP "ip=\K.*$") |  sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g'

测试一下, 结果不错.

root@391932510hax:~# curl -sL https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/$(curl -sL https://www.cloudflare.com/cdn-cgi/trace | grep -oP "ip=\K.*$") |  sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g'
976bb2fa-6685-3e06-907f-9133e1536320root@391932510hax:~# 


总结

curl -sL https://www.uuidtools.com/api/generate/v3/namespace/ns:dns/name/$(curl -sL https://www.cloudflare.com/cdn-cgi/trace | grep -oP "ip=\K.*$") |  sed -r 's/.*([^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}).*/\1/g'

评论

The Hot3 in Last 30 Days