近期研究Xdea激活的总结

0x0 背景

也是无意中浏览看雪论坛发现https://bbs.kanxue.com/thread-285675.htm别人实现了一个多次试用的实现。
注意到发布者在帖子中解释是通过系统变量中的USERNAME变量的值进行匹配的(在Linux和Windows系统下)。
于是乎我也在我本地搭建一套环境来进行窥探Xdea试用注册的秘密。

0x1 基础环境

操作系统:Windows 11
Jdk Version: 21
Xdea 版本:2024.3.4
还准备了一些其他工具:
反编译工具:jadx、jd-gui
字节查看工具:jclasslib
java依赖管理工具:maven
抓包工具:fiddler

我只总结我的思路

0x0 我第一想到的突破口就是通过抓包

这个方法还是很给力,通过抓包观察发现有一个有/service***/trial?特征的一个GET请求;
通过接口名基本就能判断这是试用注册的请求。所有参数都在URL里:
productFamilyId:II
hostName:肉眼观察是一个Base64编码后的值
salt:猜测是一个当前的时间戳
ideProductCode:II
buildDate:20241113
clientVersion:20
secure:false
userName:也是经过Base64编码的值
buildNumber:2024.3.4 Build IU-243.25659.39
machineId:肉眼观察是一个UUID
productCode:II
machineUUID:疑似也是UUID

这个接口返回的数据应该是加密过的:
关键数据应该是EncodeAsset.data下的内容

0x1 既然是加密的数据那么Xdea中一定会有解密相关的操作

通过在jadx通过搜索到了EncodeAsset相关的类并且是public,那么我是否可以直接通过idea添加idea的类库来实例化这个类呢。
还别说通过new EncodeAsset();然后setdata(“***”)还真的可行;System.out.println打印这个类就能直接获取到解密后的内容了。
不过这个解密我并没有深入的跟踪。当然现在写搜索EncodeAsset相关的类感觉很容易的样子,其实我都是一个一个jar拖到jadx
中进行搜索的最终是在product.jar中发现。

0x2 接下来就来到的试用请求的参数生成了

我主要关注hostName、userName、machineId、machineUUID这几个参数是如何生成的;
其他几个参数都比较好理解,大部分都是和版本相关的信息。通过搜索这几个参数的名字
最终确定是通过一个名为ObtainAnonTrialRequest的类进行组装的;进一步跟踪到获取这些参数的
函数发现都是获取的一些静态数据(都是在Xdea启动时已经构建好的数据了),而且这几个参数的值使固定的。
观察到获取这几个数据的函数都是public,我就在idea中掉了一下测试;没想到还真能获取
不过machineUUID这个参数并没有正确打印,这里走了弯路我还以为这个参数是依赖启动时的一些东西
中间使用了asm插桩不过并没有发现生成的核心都是停留在表面,唯一值得有用的那就是发现了反射调用了一些
标准库里的函数。最终还是通过调试获取machineUUID的函数,一步一步跟踪后发现依赖了jna的native没找到导致
获取值异常了。这几个参数最终都是通过引用idea的类库直接调用相关函数获取到的,具体算法
都是通过调试函数来窥探的。

hostName跟踪生成

这个参数是machineId的值经过了加密计算后再编码成了Base64

userName跟踪生成

这个参数是System.getProperty(“user.name”)的值经过了加密计算后再编码成了Base64,和上面hostName的生成算法是一样的
只是传入的值不一样。

machinheId跟踪生成

这个参数是在PermanentInstallationID.calculateInstallationId()函数中获取的,大致逻辑是检查注册表中是否存在
user_id_on_machine的值,如果存在直接返回这个值,不存在就调用UUID.randomUUID()生成一个并且存入到注册表中。

machineUUID跟踪生成

这个参数计算比较复杂首先会读取注册表键为HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography的值,如果没有
这个值,就会调用native函数进行读取硬件的ID,具体读取的啥我并没有细究;
然后将System.getProperty(“user.name”)获取到的值加上”Licensing”转换成bytes,再交给了sha256,这个sha256算法
我没有细究是否是魔改过的,因为我是直接将反编译的代码复制过来测试的并且能够良好工作;最后是将sha256生成的结果
给UUID.nameUUIDFromBytes()进行了计算后得到了machineUUID。

0x3 最后总结

在看雪发布者提供的网站中生成的内容发现Windows会修改PermanentUserId文件的内容,但是经过我的测试就算生成新的用户名
获取到的lincese不修改这个文件也是可行的,我是直接修改了user.name中获取的用户名来实现的(通过修改idea启动参数-Duser.name=**来实现的);目前工作良好。

ttyd配合lrzsz/trzsz实现文件传输

安装ttyd

因为管理服务器需要登录堡垒机需要双因子认证,麻烦得很这才想到了用ttyd
我的安装是直接下载github上的文件,放在了系统环境变量PATH中的目录里面:

1
2
curl -L -o /usr/local/bin/ttyd https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64
chmod +x /usr/local/bin/ttyd

编辑配置文件

看官方介绍能支持不少功能:

1
2
3
4
5
6
7
8
Built on top of libuv and WebGL2 for speed
Fully-featured terminal with CJK and IME support
ZMODEM (lrzsz) / trzsz file transfer support
Sixel image output support (img2sixel / lsix)
SSL support based on OpenSSL / Mbed TLS
Run any custom command with options
Basic authentication support and many other custom options
Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt, Windows

我主要用到的是文件传输功能,参考wiki:
https://github.com/tsl0922/ttyd/wiki/Example-Usage
https://github.com/tsl0922/ttyd/wiki/Client-Options

1
2
enable ZMODEM / lrzsz file transfer support: ttyd -t enableZmodem=true bash
enable trzsz file transfer support: ttyd -t enableTrzsz=true bash

下面来编写一个systemd service让ttyd自启动:
编辑/etc/systemd/system/ttyd.service
enableTrzsz=true 启用这个是因为lrzsz上传超过100M终端会乱码;
enableZmodem=true 这个是启用lrzsz,这个我测试100M以内的文件能够正常工作
-c 是配置简单的认证用户和密码;
-W 是启用可写,如果不加上这个参数终端是没法输入的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=ttyd - Share your terminal over the web
After=network.target

[Service]
ExecStart=/usr/local/bin/ttyd -t enableTrzsz=true -t enableZmodem=true -c admin:xxxx@ -W bash
Restart=always
User=root
Group=root
Environment=TERM=xterm-256color
WorkingDirectory=/root
StandardOutput=null
StandardError=journal

[Install]
WantedBy=multi-user.target

重新读取所有daemon:

1
systemctl daemon-reload

加入开机自启动:

1
systemctl enable ttyd

启动ttyd:

1
systemctl start ttyd

安装lrzsz:

1
dnf install lrzsz

安装trzsz:

1
pip install trzsz

然后就能通过浏览器访问了:localhost:7681
不过我这边为了能够跳过堡垒机直接访问终端,我还在服务器上部署了一个nginx,然后通过nginx反代了ttyd服务;我的配置如下:

1
2
3
4
5
6
7
8
9
10
11
location /ttyd/ {
proxy_pass http://ttyd:7681/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

# 防止 WebSocket 子路径混淆
rewrite /ttyd/(.*) /$1 break;
}

虚拟机多出口提供服务

背景

我在本地硬件服务器VM HOST中通过qemu创建一个虚拟机,并且在虚拟机VM1中部署了一个openvpn服务,它的IP地址是10.89.103.14;
因为硬件服务器配置了两个出口,但是呢虚拟机VM1的默认路由是走的其中一条线路,当通过另一条线路的公网IP访问进来的流量就没法路由了。
我的环境是:
VM HOST: Linux
VM1: Linux
我的拓扑如下:
Image

配置

我的配置如下仅仅做下记录,也是研究了很久才搞定的,大致的原理是通过iptables在VM HOST进行匹配特定IP和端口的流量然后将流量设置特定的tos,然后流量会流进到虚拟机VM1,VM1再通过匹配不同tos的流量将其进行mark;因为这个mark是链路级别的,当数据到达应用程序进行处理后出去的流量也会带上mark,后面再将mark的流量设置不同的tos;至于为什么还要设置tos,我的理解是tos是跨主机的标记,mark是当前机器链路级别的标记。当然如果没有匹配到tos的流量还是会走到默认路由的。
因为虚拟机VM1出去的流量也设置了tos,所以流量包到达VM HOST的时候就会进行匹配策略路由,将标记不同的tos的流量选择不同的路由表进行路由,至此就能做到多出口的提供服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
内部机器VM1(如果里面的机器还是DNAT,还得在DNAT的目标主机里添加规则进行标记):
iptables -t mangle -A PREROUTING -m tos --tos 0x02 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -m tos --tos 0x04 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -m mark ! --mark 0 -j RETURN
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m mark --mark 2 -j TOS --set-tos 0x02
iptables -t mangle -A OUTPUT -m mark --mark 4 -j TOS --set-tos 0x04

外面机器VM HOST:
iptables -t mangle -A PREROUTING -d 10.88.100.14 -p tcp --dport 9000 -j TOS --set-tos 0x02
iptables -t mangle -A PREROUTING -d 192.168.100.14 -p tcp --dport 9000 -j TOS --set-tos 0x04
iptables -t mangle -A PREROUTING -d 10.88.100.14 -p tcp --dport 6789 -j TOS --set-tos 0x02
iptables -t mangle -A PREROUTING -d 192.168.100.14 -p tcp --dport 6789 -j TOS --set-tos 0x04

ip rule add tos 0x02 table 10
ip rule add tos 0x04 table 20
ip route add default via 10.88.100.1 table 10
ip route add 10.89.103.0/24 dev virbr0 proto kernel scope link src 10.89.103.1 table 10
ip route add default via 192.168.100.1 table 20
ip route add 10.89.103.0/24 dev virbr0 proto kernel scope link src 10.89.103.1 table 20

cloudflare workerd把玩-编译workerd(一)

背景

最近迷上了cloudflare的workers和pages,这个东西能做不少事情主要是还有免费额度。当然现在的博客就是部署在cloudflare的pages上面的,还能写api服务、前端打包部署(通过Wrangler CLI这个工具)能做部署大多数框架生成的前端工程;这样就能前后端都部署在cloudflare workers中了;安装Wrangler CLI可以参考下面的命令,当然官方文件中也写得很清楚:

1
yarn add --user wrangler

我也是无意中发现的cloudflare他们开源了自己的workers引擎,具体是在哪里发现的也记不太清楚了;于是呼就研究了一番workerd。

编译workerd

要研究这个项目肯定是少不了自己编译,参考官方的github给出的文档进行了编译,官方给出在linux下面编译环境如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Bazel
If you use Bazelisk (recommended), it will automatically download and use the right version of Bazel for building workerd.

On Linux:
We use the clang/LLVM toolchain to build workerd and support version 16 and higher. Earlier versions of clang may still work, but are not officially supported.

Clang 16+ (e.g. package clang-16 on Debian Bookworm). If clang is installed as clang-<version> please create a symlink to it in your PATH named clang, or use --action_env=CC=clang-<version> on bazel command lines to specify the compiler name.

libc++ 16+ (e.g. packages libc++-16-dev and libc++abi-16-dev)

LLD 16+ (e.g. package lld-16).

python3, python3-distutils, and tcl8.6

You may then build workerd at the command-line with:
1
bazel build //src/workerd/server:workerd

我准备的系统和官方推荐的一致:
1.系统:Debian Bookworm
2.编译器:Clang 16
3.其他依赖的组件有clang-16,libc++-16-dev,libc++abi-16-dev,lld-16,python3,python3-distutils,tcl8.6
这里需要注意我使用的lxc创建的debian bookworm, 官方的这个文档中在我准备的这个系统中缺少了一些组件和一些配置:
1.因为我是使用官方推荐的Bazelisk,官方给的编译命令是Bazel build …,因为Bazelisk自动安装的Bazel在系统环境变量中找不到,所以应到替换成Bazelisk build …;这样就会自动下载特定版本的Bazel并运行了。
2.因为使用lxc创建的debian,如果直接安装好官方所需的组件后直接编译会提示缺少git;故最好在编译前安装好git。
3.到后边编译的时候会提示tclsh命令找不到,这是因为tclsh8.6没有生成软连接;最好在编译前手动生成一下。
3.后面生成带调试信息的workerd运行结束的时候会提示找不到llvm-symbolizer;同理手动生成一下llvm-symbolizer-16的软连接到llvm-symbolizer。

1
2
3
4
➜  helloworld git:(main) ../../bazel-bin/src/workerd/server/workerd serve config.capnp           
^Ckj/exception.c++:357: warning: llvm-symbolizer was not found. To symbolize stack traces, install it in your $PATH or set $LLVM_SYMBOLIZER to the location of the binary. When running tests under bazel, use `--test_env=LLVM_SYMBOLIZER=<path>`.
*** Received signal #2: Interrupt
stack: /lib/x86_64-linux-gnu/libc.so.6@108c1d ../../bazel-bin/src/workerd/server/workerd@a82418a ../../bazel-bin/src/workerd/server/workerd@a77784d ../../bazel-bin/src/workerd/server/workerd@a778ee8 ../../bazel-bin/src/workerd/server/workerd@3e9458e ../../bazel-bin/src/workerd/server/workerd@3ea9112 ../../bazel-bin/src/workerd/server/workerd@3ea8bac ../../bazel-bin/src/workerd/server/workerd@3ea8b88 ../../bazel-bin/src/workerd/server/workerd@3ea8b5e ../../bazel-bin/src/workerd/server/workerd@3ea8ab3 ../../bazel-bin/src/workerd/server/workerd@3ea8a83 ../../bazel-bin/src/workerd/server/workerd@a86356f ../../bazel-bin/src/workerd/server/workerd@a862035 ../../bazel-bin/src/workerd/server/workerd@a86a690 ../../bazel-bin/src/workerd/server/workerd@a863c51 ../../bazel-bin/src/workerd/server/workerd@a860f86 ../../bazel-bin/src/workerd/server/workerd@a86a690 ../../bazel-bin/src/workerd/server/workerd@a863c51 ../../bazel-bin/src/workerd/server/workerd@a86742b ../../bazel-bin/src/workerd/server/workerd@a85d52c ../../bazel-bin/src/workerd/server/workerd@a85d31a ../../bazel-bin/src/workerd/server/workerd@3e63189 /lib/x86_64-linux-gnu/libc.so.6@27249 /lib/x86_64-linux-gnu/libc.so.6@27304 ../../bazel-bin/src/workerd/server/workerd@3e63020

编译workerd会下载很多的依赖的第三方库,很多东西都是在墙外需要自行准备好梯子。

编译带调试信息的workerd

要研究workerd,不可避免的需要调试它;因为workerd是使用Bazel编译的,通过查找官方文档得知只需要在build后面加上-c dbg参数就能生成带调试信息的workerd了,如下:

1
bazelisk build -c dbg //src/workerd/server:workerd

这样生成的workerd相当的庞大,我这边生成后文件大小来到了1.3G。生成后的文件在:bazel-bin/src/workerd/server/workerd

1
2
➜  helloworld git:(main) ls -alh ../../bazel-bin/src/workerd/server/workerd
-r-xr-xr-x 1 root root 1.3G Jan 6 16:47 ../../bazel-bin/src/workerd/server/workerd

freerdp连接远程主机互相复制粘贴文件的操作

远程主机复制文件到本地linux主机

如果在远程主机中复制文件粘贴到本地linux系统中,那么剪切板中的数据类型是下面三种类型的数据:

1
2
3
text/uri-list
x-special/gnome-copied-files
x-special/mate-copied-files

注意在使用了wl-paste命令后,会将剪切板中的文件内容保存在命令执行后的路径中;如果不执行wl-paste命令是不会生成这个文件的,类似如下的路径:

1
file:///tmp/com.freerdp.client.cliprdr.2180867/20/region_2024_3_18 11_13_48.csv

其中/2180867/20是随机生成的。

本地linux主机复制文件到远程主机中

本地linux主机复制文件到远程windows主机中当然也需要满足特定的格式,
1.需要获取到文件的绝对路径(没有测试过文件夹是否能够正常复制到远程主机中)
2.复制的数据要将类型设置成text/uri-list,我的桌面环境sway;如果是gnome或者别的桌面环境可能要使用不同的类型,这些可以自行测试。
以下是我生成文件绝对路径到剪切板的命令:

1
readlink -f <PATH_FILE> | sed 's|^|file://|' |wl-copy -t text/uri-list

生成了以后就能直接在远程windows主机中粘贴文件了。为了方便我将这一长串命令封装成了一个函数这样就能简单的调用复制了,我的写法如下(在.bashrc文件中定义函数实现的):

1
2
3
rdpcp() {
readlink -f $1 | sed 's|^|file://|' |wl-copy -t text/uri-list
}

将上面的内容添加到.bashrc;使用source .bashrc生效刚刚的配置;然后就能直接在终端中使用这个函数了如下格式:

1
rdpcp <PATH_FILE>

<PATH_FILE>可以是相对路径
注意这个复制仅仅适用于在终端中使用,如果有文件管理器就无需这些步骤了。直接在文件管理器中复制就能正常工作。

Python ctypes调用openssl动态C库的一些例子

AES 256 GCM加解密相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* Copyright 2012-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

/*
* Simple AES GCM test program, uses the same NIST data used for the FIPS
* self test but uses the application level EVP APIs.
*/
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

/* AES-GCM test data from NIST public test vectors */

static const unsigned char gcm_key[] = {
0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66,
0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,
0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
};

static const unsigned char gcm_iv[] = {
0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
};

static const unsigned char gcm_pt[] = {
0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea,
0xcc, 0x2b, 0xf2, 0xa5
};

static const unsigned char gcm_aad[] = {
0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43,
0x7f, 0xec, 0x78, 0xde
};

static const unsigned char gcm_ct[] = {
0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c, 0xd5, 0x36, 0x86, 0x7e,
0xb9, 0xf2, 0x17, 0x36
};

static const unsigned char gcm_tag[] = {
0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87, 0xd7, 0x37, 0xee, 0x62,
0x98, 0xf7, 0x7e, 0x0c
};

void aes_gcm_encrypt(void)
{
EVP_CIPHER_CTX *ctx;
int outlen, tmplen;
unsigned char outbuf[1024];
printf("AES GCM Encrypt:\n");
printf("Plaintext:\n");
BIO_dump_fp(stdout, gcm_pt, sizeof(gcm_pt));
ctx = EVP_CIPHER_CTX_new();
/* Set cipher type and mode */
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
/* Set IV length if default 96 bits is not appropriate */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL);
/* Initialise key and IV */
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
/* Zero or more calls to specify any AAD */
EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad));
/* Encrypt plaintext */
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
/* Output encrypted block */
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf, outlen);
/* Finalise: note get no output for GCM */
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
/* Get tag */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf);
/* Output tag */
printf("Tag:\n");
BIO_dump_fp(stdout, outbuf, 16);
EVP_CIPHER_CTX_free(ctx);
}

void aes_gcm_decrypt(void)
{
EVP_CIPHER_CTX *ctx;
int outlen, tmplen, rv;
unsigned char outbuf[1024];
printf("AES GCM Decrypt:\n");
printf("Ciphertext:\n");
BIO_dump_fp(stdout, gcm_ct, sizeof(gcm_ct));
ctx = EVP_CIPHER_CTX_new();
/* Select cipher */
EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
/* Set IV length, omit for 96 bits */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL);
/* Specify key and IV */
EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
/* Zero or more calls to specify any AAD */
EVP_DecryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad));
/* Decrypt plaintext */
EVP_DecryptUpdate(ctx, outbuf, &outlen, gcm_ct, sizeof(gcm_ct));
/* Output decrypted block */
printf("Plaintext:\n");
BIO_dump_fp(stdout, outbuf, outlen);
/* Set expected tag value. */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(gcm_tag),
(void *)gcm_tag);
/* Finalise: note get no output for GCM */
rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen);
/*
* Print out return value. If this is not successful authentication
* failed and plaintext is not trustworthy.
*/
printf("Tag Verify %s\n", rv > 0 ? "Successful!" : "Failed!");
EVP_CIPHER_CTX_free(ctx);
}

int main(int argc, char **argv)
{
aes_gcm_encrypt();
aes_gcm_decrypt();
}

参考:https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/demos/evp/aesgcm.c
转换成Python ctypes方式调用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import base64
import ctypes
import os
from ctypes import c_void_p, c_char_p, c_int, create_string_buffer, POINTER

# 加载 OpenSSL 动态库
libcrypto = ctypes.CDLL("libcrypto.so") # 根据系统选择动态库路径(Linux)

# 设置 OpenSSL 相关的函数原型
libcrypto.EVP_CIPHER_CTX_new.restype = c_void_p
libcrypto.EVP_CIPHER_CTX_new.argtypes = []

libcrypto.EVP_CIPHER_CTX_free.argtypes = [c_void_p]

libcrypto.EVP_CIPHER_CTX_get_params.argtypes = [c_void_p, POINTER(c_void_p)]
libcrypto.EVP_CIPHER_free.argtypes = [c_void_p]

libcrypto.EVP_EncryptInit_ex.argtypes = [
c_void_p,
c_void_p,
c_void_p,
c_char_p,
c_char_p,
]
libcrypto.EVP_EncryptUpdate.argtypes = [
c_void_p,
c_char_p,
POINTER(c_int),
c_char_p,
c_int,
]
libcrypto.EVP_EncryptFinal_ex.argtypes = [c_void_p, c_char_p, POINTER(c_int)]

libcrypto.EVP_DecryptInit_ex.argtypes = [
c_void_p,
c_void_p,
c_void_p,
c_char_p,
c_char_p,
]
libcrypto.EVP_DecryptUpdate.argtypes = [
c_void_p,
c_char_p,
POINTER(c_int),
c_char_p,
c_int,
]
libcrypto.EVP_DecryptFinal_ex.argtypes = [c_void_p, c_char_p, POINTER(c_int)]

libcrypto.EVP_aes_256_gcm.restype = c_void_p
libcrypto.EVP_aes_256_gcm.argtypes = []

libcrypto.EVP_CIPHER_fetch.argtypes = [c_void_p, c_char_p, c_void_p]
libcrypto.EVP_CIPHER_fetch.restype = c_void_p

libcrypto.EVP_CIPHER_CTX_ctrl.argtypes = [c_void_p, c_int, c_int, c_void_p]
libcrypto.EVP_CIPHER_CTX_ctrl.restype = c_int
# (ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL)
libcrypto.BIO_dump_fp.argtypes = [c_void_p, c_void_p, c_int]
libcrypto.BIO_dump_fp.restype = c_int
libcrypto.fopen.argtypes = [c_char_p, c_char_p]
libcrypto.fopen.restype = c_void_p


# AES GCM加密
def aes_256_gcm_encrypt(key: bytes, iv: bytes, plaintext: bytes, aad: bytes = b""):
key_ptr = c_char_p(key)
iv_ptr = c_char_p(iv)

# 创建加密上下文
ctx = libcrypto.EVP_CIPHER_CTX_new()
cipher = libcrypto.EVP_aes_256_gcm()
# print(11111)
# cipher = libcrypto.EVP_CIPHER_fetch(
# libctx, c_char_p(b"AES-256-GCM"), propq)
# print(ctypes.cast(cipher, c_void_p))
# print(11111)

# 初始化加密操作
print(2222)
ls = libcrypto.EVP_EncryptInit_ex(ctx, cipher, None, None, None)
print(ls)

print(2222)
libcrypto.EVP_CIPHER_CTX_ctrl(ctx, c_int(0x9), c_int(len(iv)), None)
print(333)
libcrypto.EVP_EncryptInit_ex(ctx, None, None, key_ptr, iv_ptr)
print(444)
# 处理AAD(附加认证数据)
outlen = c_int(0)
libcrypto.EVP_EncryptUpdate(
ctx, None, ctypes.byref(outlen), c_char_p(aad), c_int(len(aad))
)
print(555)
# outlen = c_int(0)
# if not libcrypto.EVP_EncryptUpdate(ctx, None, None, aad_buffer, len(aad)):
# raise ValueError("Error encrypting AAD")
outbuf = create_string_buffer(len(plaintext))
libcrypto.EVP_EncryptUpdate(
ctx, outbuf, ctypes.byref(outlen), c_char_p(
plaintext), c_int(len(plaintext))
)
print(666)

# # 加密明文
# ciphertext = create_string_buffer(len(plaintext))
# if not libcrypto.EVP_EncryptUpdate(
# ctx, ciphertext, ctypes.byref(outlen), plaintext_buffer, len(plaintext)
# ):
# raise ValueError("Error encrypting plaintext")
print(outbuf.raw[: outlen.value].hex())
# 获取加密后的数据
ciphertext = outbuf.raw[: outlen.value]
libcrypto.EVP_EncryptFinal_ex(ctx, outbuf, ctypes.byref(outlen))
print(777)
import sys

libcrypto.BIO_dump_fp(
libcrypto.fopen(b"1", b"w"),
c_char_p(b"test"),
len(b"test"),
)
libcrypto.EVP_CIPHER_CTX_ctrl(ctx, c_int(0x10), c_int(16), outbuf)

# 获取认证标签
# #tag = create_string_buffer(16)
# if not libcrypto.EVP_EncryptFinal_ex(ctx, tag, ctypes.byref(outlen)):
# raise ValueError("Error finalizing encryption")

# 释放上下文
libcrypto.EVP_CIPHER_CTX_free(ctx)

return ciphertext, outbuf.raw


# AES GCM 解密
def aes_256_gcm_decrypt(
key: bytes, iv: bytes, ciphertext: bytes, aad: bytes = b"", tag: bytes = b""
):
print("tag:", tag.hex())
ctx = libcrypto.EVP_CIPHER_CTX_new()
libcrypto.EVP_DecryptInit_ex(
ctx, libcrypto.EVP_aes_256_gcm(), None, None, None)
libcrypto.EVP_CIPHER_CTX_ctrl(ctx, c_int(0x9), len(iv), None)
libcrypto.EVP_DecryptInit_ex(ctx, None, None, c_char_p(key), c_char_p(iv))
outlen = c_int(0)
libcrypto.EVP_DecryptUpdate(
ctx, None, ctypes.byref(outlen), c_char_p(aad), len(aad)
)
outbuf = create_string_buffer(len(ciphertext))
libcrypto.EVP_DecryptUpdate(
ctx, outbuf, ctypes.byref(outlen), c_char_p(
ciphertext), len(ciphertext)
)
print("Plaintext:\n")
# BIO_dump_fp(stdout, outbuf, outlen);
print(outbuf.raw)
text = outbuf.raw[: outlen.value]
print("tag:", tag)
libcrypto.EVP_CIPHER_CTX_ctrl(ctx, c_int(0x10), len(tag), c_char_p(tag))
rv = libcrypto.EVP_DecryptFinal_ex(ctx, outbuf, ctypes.byref(outlen))
print(rv)

# 释放解密上下文
libcrypto.EVP_CIPHER_CTX_free(ctx)

return text


# 测试数据
key = b"77889900112233445566778899001122"
print(key.hex())
iv = b"778899001122"
print(iv.hex())
plaintext = b"1231"
print(plaintext.hex())
aad = b""

# 加密过程
ciphertext, tag = aes_256_gcm_encrypt(key, iv, plaintext, aad)
print(f"Ciphertext: {ciphertext.hex()}")
print(f"Tag: {tag.hex()}")


ciphertext = base64.b64decode(
b"BGDr211pjM/koptwkyQ7iXWTBqVf1R89Z19MPY2QiIv4/h/UNXuDjjc+uQ/9ZkJqdOfZ8MH/j+P907tbTFJhYyyd2+dqyEzBSEKq8RlpZIbHyYcnw6XRdA4c4HiAcB0ZzW8Qu3gMnH3DydMSNHwx1r7oEGewL/2SgejQemo3wK7BlpKWAJ7oX/pXCrS3JRRKHE8QG6piJLyUBB+GwuggNbE7sev7StGjezNoD2y0w0gTagKfF4C/5bVxmxbDX+DFSTfPIwA7KhRa58Vm3vL2kf+RBi1/aL9SA2+a1E6uJEAt/EEzZJ+4UJPljqIkQOAEwmD99ijG1smrRfmMkXdwmEOYeckYNwoUQbPv1wOI40UfOh2etmu9nzmuSsoNDWGJza9x4CwOXlIHvPbZtBbYO20mBy0W2byx7dh+vGbzeLgBJ8IWbHc50DNAV6GA/sxifcZPZs8USn42WoKtuKqrUVq28H+faCNvaVdSbI+ZUSG6F/euDMVdguWMlfub4J3KLxC346MDCRoX6bEXG3J4+Mo7JPi+xfoh2JKewHF2D4RgJIEkPt9ffhEDKG7jtJGSzYYqfKBEVU2/vDuGV8Y+nHmsGFcbCiM1I7onmMS1L977O0UEMwvz8cIjnXd9kRMhGrBU6yR0DvEZ67K3a5wCxbwEbNaWPy5n2oDUF3mWESXSMSIgdN6qcgpok95xegLmcEkKtp4MYdd/cT7IS2qtWJmNJKiAqg=="
)

tag = b""

iv = base64.b64decode(b"eorS/CBlfWrqeWWj")
print(iv.hex())
key = b"4e3b9ft1a68eb6548af9y895c1b14ad5"
# 解密过程
try:
decrypted_plaintext = aes_256_gcm_decrypt(key, iv, ciphertext, aad, tag)
print(decrypted_plaintext[:-16])
except ValueError as e:
print(e)

RSA非对称加解密相关,使用chatgpt生成手动修护了异常和错误

加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import ctypes
import sys
import base64
from ctypes import c_char_p, c_void_p, POINTER

# 加载 OpenSSL 动态库(Linux 下通常是 libcrypto.so)
libcrypto = ctypes.CDLL("libcrypto.so") # 根据系统调整库的路径

# 定义 C 函数原型
libcrypto.PEM_read_RSAPrivateKey.argtypes = [
c_void_p,
POINTER(c_void_p),
c_void_p,
c_void_p,
]
libcrypto.PEM_read_RSAPrivateKey.restype = c_void_p # 返回类型是 RSA*

# 打开私钥文件的 C 函数
libcrypto.fopen.argtypes = [c_char_p, c_char_p]
libcrypto.fopen.restype = c_void_p # 返回 FILE*,即 void*
# 定义 C 函数原型
libcrypto.BN_bn2hex.argtypes = [c_void_p]
libcrypto.BN_bn2hex.restype = c_char_p # 返回类型是 C 字符串

libcrypto.BN_bn2dec.argtypes = [c_void_p]
libcrypto.BN_bn2dec.restype = c_char_p # 返回类型是 C 字符串


# 打开文件
def open_file(filename):
return libcrypto.fopen(filename.encode("utf-8"), b"r")


# RSA_get0_key: 获取 RSA 密钥的模数和公钥指数
libcrypto.RSA_get0_key.argtypes = [
c_void_p,
POINTER(c_void_p),
POINTER(c_void_p),
c_void_p,
]
libcrypto.RSA_get0_key.restype = None # 返回类型是 void


# 打印 RSA 密钥信息
def print_rsa_info(rsa):
if rsa is None:
print("RSA key is NULL.")
return

# 获取模数和公钥指数
n = c_void_p()
e = c_void_p()
libcrypto.RSA_get0_key(rsa, ctypes.byref(n), ctypes.byref(e), None)

# 打印模数 (n)
print("RSA Key Info:")
print(" Modulus (n):")

# 使用 sys.stdout 获取 FILE* 类型
n_hex = libcrypto.BN_bn2hex(n)
print(n_hex.decode()) # 打印十六进制表示
# libcrypto.BN_print_fp(stdout_fp, n) # 输出到标准输出

print("\n Public exponent (e):")
e_hex = libcrypto.BN_bn2hex(e)
print(e_hex.decode()) # 打印十六进制表示
# libcrypto.BN_print_fp(stdout_fp, e) # 输出到标准输出

# 获取 RSA 密钥的大小
bits = (
libcrypto.RSA_size(ctypes.cast(rsa, c_void_p)) * 8
) # RSA_size 返回字节数,乘以 8 转换为位数
print(f" Key size: {bits} bits")


# 错误打印函数
libcrypto.ERR_print_errors_fp.argtypes = [c_void_p]
libcrypto.ERR_print_errors_fp.restype = None


# 加载私钥
def load_private_key(privkey_filename):
# 打开文件
privkey_file = open_file(privkey_filename)
if not privkey_file:
print("Unable to open private key file")
return None

# 加载 RSA 私钥
rsa = libcrypto.PEM_read_RSAPrivateKey(privkey_file, None, None, None)
if not rsa:
print("Unable to load private key")
libcrypto.ERR_print_errors_fp(None) # 输出 OpenSSL 错误
return None

print(f"Private key loaded successfully from {privkey_filename}.")
return rsa


# 使用示例
privkey_filename = "private_key.pem"
rsa_privkey = load_private_key(privkey_filename)

if rsa_privkey:
print("Private key loaded successfully")
print_rsa_info(rsa_privkey)
else:
print("Failed to load private key")


# 分块加密
def encrypt_rsa(rsa, data):
rsa_len = libcrypto.RSA_size(ctypes.cast(rsa, c_void_p))
block_size = rsa_len - 11 # 最大加密块大小:RSA_size - 填充空间

encrypted_data = ctypes.create_string_buffer(
rsa_len * ((len(data) // block_size) + 1)
)

data_len = len(data)
encrypted_len = 0
i = 0

while i < data_len:
chunk_len = min(block_size, data_len - i)
# 对当前块进行加密
len_encrypted = libcrypto.RSA_private_encrypt(
chunk_len,
ctypes.byref(ctypes.create_string_buffer(data[i: i + chunk_len])),
ctypes.byref(encrypted_data, encrypted_len),
ctypes.cast(rsa, c_void_p),
1, # RSA_PKCS1_OAEP_PADDING
)

if len_encrypted == -1:
print("RSA encryption failed")
libcrypto.ERR_print_errors_fp(sys.stderr)
return None

encrypted_len += len_encrypted
i += chunk_len

return encrypted_data.raw[:encrypted_len]


# 待加密的数据
# data = b"Hello, RSA encryption! This is a long message that will be split into multiple blocks."
data = """
test_-------TEST
""".encode("utf-8")

print(f"Original Data (length: {len(data)}):\n{data.decode()}")

# 加密
encrypted_data = encrypt_rsa(rsa_privkey, data)
if encrypted_data is None:
sys.exit(1)

print(f"\nEncrypted Data (length: {len(encrypted_data)}):")
print(" ".join(f"{byte:02x}" for byte in encrypted_data))
print(base64.b64encode(encrypted_data))

解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import ctypes
import base64
import sys
from ctypes import c_char_p, c_void_p, POINTER

# 加载 OpenSSL 动态库(Linux 下通常是 libcrypto.so)
libcrypto = ctypes.CDLL("libcrypto.so") # 根据系统调整库的路径

# 用于错误处理
libcrypto.ERR_print_errors_fp.argtypes = [c_void_p]

# 打开私钥文件的 C 函数
libcrypto.fopen.argtypes = [c_char_p, c_char_p]
libcrypto.fopen.restype = c_void_p # 返回 FILE*,即 void*
# 定义 C 函数原型
libcrypto.BN_bn2hex.argtypes = [c_void_p]
libcrypto.BN_bn2hex.restype = c_char_p # 返回类型是 C 字符串

libcrypto.BN_bn2dec.argtypes = [c_void_p]
libcrypto.BN_bn2dec.restype = c_char_p # 返回类型是 C 字符串


# 打开文件
def open_file(filename):
return libcrypto.fopen(filename.encode("utf-8"), b"r")


# RSA_get0_key: 获取 RSA 密钥的模数和公钥指数
libcrypto.RSA_get0_key.argtypes = [
c_void_p,
POINTER(c_void_p),
POINTER(c_void_p),
c_void_p,
]
libcrypto.RSA_get0_key.restype = None # 返回类型是 void


# 打印 RSA 密钥信息
def print_rsa_info(rsa):
if rsa is None:
print("RSA key is NULL.")
return

# 获取模数和公钥指数
n = c_void_p()
e = c_void_p()
libcrypto.RSA_get0_key(rsa, ctypes.byref(n), ctypes.byref(e), None)

# 打印模数 (n)
print("RSA Key Info:")
print(" Modulus (n):")

# 使用 sys.stdout 获取 FILE* 类型
n_hex = libcrypto.BN_bn2hex(n)
print(n_hex.decode()) # 打印十六进制表示
# libcrypto.BN_print_fp(stdout_fp, n) # 输出到标准输出

print("\n Public exponent (e):")
e_hex = libcrypto.BN_bn2hex(e)
print(e_hex.decode()) # 打印十六进制表示
# libcrypto.BN_print_fp(stdout_fp, e) # 输出到标准输出

# 获取 RSA 密钥的大小
bits = (
libcrypto.RSA_size(ctypes.cast(rsa, c_void_p)) * 8
) # RSA_size 返回字节数,乘以 8 转换为位数
print(f" Key size: {bits} bits")


# 定义 C 函数原型
libcrypto.PEM_read_RSA_PUBKEY.argtypes = [
c_void_p, c_void_p, c_void_p, c_void_p]
libcrypto.PEM_read_RSA_PUBKEY.restype = c_void_p # 返回 RSA 对象指针


# 加载 RSA 公钥并打印信息
def load_public_key(pubkey_filename):
try:
# 打开文件并加载公钥
public_file = open_file(pubkey_filename)

if not public_file:
print("Unable to open private key file")
return None
# 创建 C 字符串指针,指向文件内容
# buffer = ctypes.create_string_buffer(file_data)

# 加载 RSA 公钥
rsa1 = libcrypto.PEM_read_RSA_PUBKEY(public_file, None, None, None)

if not rsa1:
print("Failed to load public key.")
libcrypto.ERR_print_errors_fp(sys.stderr) # 打印 OpenSSL 错误
return None

print(f"Public key loaded successfully from {pubkey_filename}.")
return rsa1

except Exception as e:
print(f"An error occurred: {e}")
return None


# 使用示例
pubkey_filename = "public_key.pem"
rsa_pubkey = load_public_key(pubkey_filename)

if rsa_pubkey:
print("Private key loaded successfully")
print_rsa_info(rsa_pubkey)
else:
print("Failed to load private key")


# 分块解密
def decrypt_rsa(rsa, encrypted_data):
rsa_len = libcrypto.RSA_size(ctypes.cast(rsa, c_void_p))
block_size = rsa_len
encrypted_len = len(encrypted_data)

decrypted_data = ctypes.create_string_buffer(encrypted_len)

decrypted_len = 0
i = 0

while i < encrypted_len:
# 对当前块进行解密
len_decrypted = libcrypto.RSA_public_decrypt(
block_size,
ctypes.byref(
ctypes.create_string_buffer(encrypted_data[i: i + block_size])
),
ctypes.byref(decrypted_data, decrypted_len),
ctypes.cast(rsa, c_void_p),
1, # RSA_PKCS1_OAEP_PADDING
)

if len_decrypted == -1:
print("RSA decryption failed")
libcrypto.ERR_print_errors_fp(sys.stderr)
return None

decrypted_len += len_decrypted
i += block_size

return decrypted_data.raw[:decrypted_len]


encrypted_base64 = b"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"
encrypted_data = base64.b64decode(encrypted_base64)

# 解密
decrypted_data = decrypt_rsa(rsa_pubkey, encrypted_data)
if decrypted_data is None:
sys.exit(1)

print(f"\nDecrypted Data:\n{decrypted_data.decode()}")

k8s二进制在Ubuntu下部署

自用部署k8s记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

#curl -L -O 'https://github.com/containerd/containerd/releases/download/v1.7.22/containerd-1.7.22-linux-amd64.tar.gz'
sudo tar Cxzvf /usr/local containerd-1.7.21-linux-amd64.tar.gz
#curl -L -o /usr/local/lib/systemd/system/containerd.service 'https://raw.githubusercontent.com/containerd/containerd/main/containerd.service'
sudo mkdir -p /usr/local/lib/systemd/system/
sudo cp containerd.service /usr/local/lib/systemd/system/containerd.service
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
#curl -L -O 'https://github.com/opencontainers/runc/releases/download/v1.1.15/runc.amd64'
sudo install -m 755 runc.amd64 /usr/local/sbin/runc

#curl -L -O 'https://github.com/containernetworking/plugins/releases/download/v1.5.1/cni-plugins-linux-amd64-v1.5.1.tgz'
#mkdir -p /opt/cni/bin
#tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz

CNI_PLUGINS_VERSION="v1.5.1"
ARCH="amd64"
DEST="/opt/cni/bin"
sudo mkdir -p "$DEST"
#curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${ARCH}-${CNI_PLUGINS_VERSION}.tgz" | sudo tar -C "$DEST" -xz
cat cni-plugins-linux-${ARCH}-${CNI_PLUGINS_VERSION}.tgz | sudo tar -C "$DEST" -xz

DOWNLOAD_DIR="/usr/local/bin"
sudo mkdir -p "$DOWNLOAD_DIR"

CRICTL_VERSION="v1.31.1"
ARCH="amd64"
#curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | sudo tar -C $DOWNLOAD_DIR -xz
cat crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz | sudo tar -C $DOWNLOAD_DIR -xz


RELEASE="v1.31.1"
ARCH="amd64"
sudo cp {kubeadm,kubelet} $DOWNLOAD_DIR
cd $DOWNLOAD_DIR
#sudo curl -L --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux/${ARCH}/{kubeadm,kubelet}
sudo chmod +x {kubeadm,kubelet}
cd -
RELEASE_VERSION="master"
#curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/krel/templates/latest/kubelet/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /usr/lib/systemd/system/kubelet.service
cat kubelet.service | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /usr/lib/systemd/system/kubelet.service
sudo mkdir -p /usr/lib/systemd/system/kubelet.service.d
#curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/krel/templates/latest/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
cat 10-kubeadm.conf | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf


#curl -LO "https://dl.k8s.io/release/v1.31.1/bin/linux/amd64/kubectl"
chmod +x kubectl
mkdir -p ~/.local/bin
cp ./kubectl ~/.local/bin/kubectl

sudo systemctl enable --now kubelet
# 以下导入离线镜像是在k8s官方仓库被墙的墙框下才需要,因为最新的配置已经加入了自定义的k8s仓库代理,故只要在网络联通的情况下不再需要手动单独导入了。
sudo ctr -n k8s.io i import coredns:v1.11.1.tar
sudo ctr -n k8s.io i import etcd:3.5.15-0.tar
sudo ctr -n k8s.io i import kube-apiserver:v1.31.0.tar
sudo ctr -n k8s.io i import kube-controller-manager:v1.31.0.tar
sudo ctr -n k8s.io i import kube-proxy:v1.31.0.tar
sudo ctr -n k8s.io i import kube-scheduler:v1.31.0.tar
sudo ctr -n k8s.io i import pause:3.10.tar

sudo mkdir -p /etc/containerd/
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup *= *false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo sed -i 's@sandbox_image *= *"registry.k8s.io/pause:3.8"@sandbox_image = "registry.k8s.io/pause:3.10"@g' /etc/containerd/config.toml
sudo sed -i 's@\<config_path = ""@config_path = "/etc/containerd/certs.d"@g' /etc/containerd/config.toml
sudo mkdir -p /etc/containerd/certs.d/_default
cat << EOF | sudo tee /etc/containerd/certs.d/_default/hosts.toml
[host."https://docker.505345784.xyz"]
capabilities = ["pull", "resolve"]
EOF
sudo systemctl restart containerd
sudo apt install -y socat conntrack
sudo kubeadm init --kubernetes-version 1.31.0

mkdir -p $HOME/.kube
sudo cp -rf /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

cat << EOF | sudo tee /etc/cni/net.d/10-containerd-net.conflist
{
"cniVersion": "1.0.0",
"name": "containerd-net",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"promiscMode": true,
"ipam": {
"type": "host-local",
"ranges": [
[{
"subnet": "10.88.0.0/16"
}],
[{
"subnet": "2001:db8:4860::/64"
}]
],
"routes": [
{ "dst": "0.0.0.0/0" },
{ "dst": "::/0" }
]
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true},
"externalSetMarkChain": "KUBE-MARK-MASQ"
}
]
}
EOF

sudo systemctl restart containerd
# docker镜像服务器被墙时候进行手动导入镜像,最新的配置了自定义docker容器代理;可以在线拉去了。
sudo ctr -n k8s.io i import --platform linux/amd64 kafka.tar
sudo ctr -n k8s.io i import --platform linux/amd64 minio.tar
sudo ctr -n k8s.io i import --platform linux/amd64 mysql.tar
sudo ctr -n k8s.io i import --platform linux/amd64 nacos.tar
sudo ctr -n k8s.io i import --platform linux/amd64 nginx.tar
sudo ctr -n k8s.io i import --platform linux/amd64 openjdk.tar
sudo ctr -n k8s.io i import --platform linux/amd64 redis.tar
sudo ctr -n k8s.io i import --platform linux/amd64 seata.tar
sudo ctr -n k8s.io i import --platform linux/amd64 kkfileview.tar

# 消除污点
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

注意:最新的版本号可以到github上面进行查询后修改。

nginx自签SSL证书生成和配置

创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -subj "/C=CN/ST=SiChuan/L=ChengDu/O=ACS" -keyout CA-private.key -out CA-certificate.crt -reqexts v3_req -extensions v3_ca
$ openssl genrsa -out private.key 2048
$ openssl req -new -key private.key -subj "/C=CN/ST=SiChuan/L=ChengDu/O=ACS/CN=secrets--manager.oss-cn-shanghai.aliyuncs.com" -sha256 -out private.csr
$ cat > private.ext << EOF
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
req_extensions = san
extensions = san
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Definesys
localityName = Definesys
organizationName = Definesys
[SAN]
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = DNS:secrets--manager.oss-cn-shanghai.aliyuncs.com
EOF
# subjectAltName可以是DNS和IP,写法: DNS:域名.com/IP:192.168.1.1; 多个用逗号隔开。
$ openssl x509 -req -days 3650 -in private.csr -CA CA-certificate.crt -CAkey CA-private.key -CAcreateserial -sha256 -out private.crt -extfile private.ext -extensions SAN

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
server {
listen 443 ssl;
server_name secrets--manager.oss-cn-shanghai.aliyuncs.com;
keepalive_timeout 65;
client_max_body_size 512m;
client_header_buffer_size 1024k;
large_client_header_buffers 4 1024k;
client_body_timeout 5m;
ssl_certificate "/etc/nginx/conf.d/ssl/private.crt";
ssl_certificate_key "/etc/nginx/conf.d/ssl/private.key";
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!ADH:!aNULL:!MD5:!3DES:!IDEA:!DES;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
#ssl_session_timeout 10m;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4;
#ssl_prefer_server_ciphers on;
fastcgi_param HTTPS $https if_not_empty;

###### 根目录 #######
#location / {
#add_header Access-Control-Allow-Origin *;
#add_header Access-Control-Allow-Credentials: true;
#add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
#add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
#root /usr/share/nginx/html/sqfy;
#index index.html;
#proxy_pass http://nginx:80/;
#}

add_header Alt-Svc 'h3=":443"; ma=86400';
add_header Cross-0rigin-Opener-Policy same-origin;
add_header Cross-0rigin-Embedder-Policy require-corp;
location / {
#add_header Access-Control-Allow-Origin *;
#add_header Access-Control-Allow-Credentials: true;
#add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
#add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
root /usr/share/nginx/html;
index index.html;
}
location /mes-secrets-manager.json {
default_type application/json;
return 200 '{"tokenKey":"UoeqTwLRGtZJug==","jksResourceName":"xxx-jwt.jks","jksName":"xxxx","jksAlias":"iyunware-oauth-jwt","authorizationKey":"","refreshTokenKey":"","platformKey":"","mapKey":""}';
}
}

将CA-certificate.crt复制到/usr/local/share/ca-certificates; 然后执行update-ca-certificates更新证书缓存

上面是我的配置示例

hexo操作记录

hexo博客操作记录

hexo 创建博文

1
./node_modules/.bin/hexo new "博文标题"

创建完成后会在source/_posts/生成一个”博文标题”.md文件,按需编辑此文件。

hexo 生成

1
./node_modules/.bin/hexo g

hexo 上传渲染好的文章到github

1
./node_modules/.bin/hexo deploy

hexo 启动本地简易server

1
2
./node_modules/.bin/hexo server