在测试ES-SQL的过程中发现当前最新版ES 7.8.0的JDBC是收费的,不过都已经花了时间去搞那么还是需要小小的`测试`一下的。 其实,说ES破解也不太对,主要是ES的增强包X-Pack,这个增强包包含了JDBC、ODBC、安全、告警、机器学习等,所以这个工具的付费还是不错的,可惜目前还未得到能接受付费的回应,那就先用一下吧。 根据目前我的场景,已经安装好ElasticSearch7.8.0kibana7.8.0

下载反编译工具

因为要修改期验证license的代码,所以我们需要通过反编译工具来查看代码,这里推荐Luyten,可以去Releases · deathmarine/Luyten · GitHub下载,官方提供了win的安装包已经可执行的jar,所以这里下载jar即可。

查看x-pack-core的源码

es我是通过rpm安装的,所以在其安装目录/usr/share/elasticsearch/modules/x-pack-core中下载x-pack-core-7.8.0.jar文件到本地,通过Luyten打开这个jar。 找到以下两个文件:

  • org.elasticsearch.license.LicenseVerifier
  • org.elasticsearch.xpack.core.XPackBuild

将这两个class文件中的所有内容拷贝到两个对应的java文件内 LicenseVerifier.java

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
package org.elasticsearch.license;

import java.nio.*;
import org.elasticsearch.common.bytes.*;
import java.security.*;
import java.util.*;
import org.elasticsearch.common.xcontent.*;
import org.apache.lucene.util.*;
import org.elasticsearch.core.internal.io.*;
import java.io.*;

public class LicenseVerifier
{
public static boolean verifyLicense(final License license, final byte\[\] publicKeyData) {
// byte[] signedContent = null;
// byte[] publicKeyFingerprint = null;
// try {
// final byte[] signatureBytes = Base64.getDecoder().decode(license.signature());
// final ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
// final int version = byteBuffer.getInt();
// final int magicLen = byteBuffer.getInt();
// final byte[] magic = new byte[magicLen];
// byteBuffer.get(magic);
// final int hashLen = byteBuffer.getInt();
// publicKeyFingerprint = new byte[hashLen];
// byteBuffer.get(publicKeyFingerprint);
// final int signedContentLen = byteBuffer.getInt();
// signedContent = new byte[signedContentLen];
// byteBuffer.get(signedContent);
// final XContentBuilder contentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
// license.toXContent(contentBuilder, (ToXContent.Params)new ToXContent.MapParams((Map)Collections.singletonMap("license_spec_view", "true")));
// final Signature rsa = Signature.getInstance("SHA512withRSA");
// rsa.initVerify(CryptUtils.readPublicKey(publicKeyData));
// final BytesRefIterator iterator = BytesReference.bytes(contentBuilder).iterator();
// BytesRef ref;
// while ((ref = iterator.next()) != null) {
// rsa.update(ref.bytes, ref.offset, ref.length);
// }
// return rsa.verify(signedContent);
// }
// catch (IOException ex) {}
// catch (NoSuchAlgorithmException ex2) {}
// catch (SignatureException ex3) {}
// catch (InvalidKeyException e) {
// throw new IllegalStateException(e);
// }
// finally {
// if (signedContent != null) {
// Arrays.fill(signedContent, (byte)0);
// }
// }
return true;
}

public static boolean verifyLicense(final License license) {
// byte[] publicKeyBytes;
// try {
// final InputStream is = LicenseVerifier.class.getResourceAsStream("/public.key");
// try {
// final ByteArrayOutputStream out = new ByteArrayOutputStream();
// Streams.copy(is, (OutputStream)out);
// publicKeyBytes = out.toByteArray();
// if (is != null) {
// is.close();
// }
// }
// catch (Throwable t) {
// if (is != null) {
// try {
// is.close();
// }
// catch (Throwable t2) {
// t.addSuppressed(t2);
// }
// }
// throw t;
// }
// }
// catch (IOException ex) {
// throw new IllegalStateException(ex);
// }
// return verifyLicense(license, publicKeyBytes);
return true;
}
}

将验证license的代码注释了,返回trueXPackBuild.java

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
package org.elasticsearch.xpack.core;

import org.elasticsearch.common.io.*;
import java.net.*;
import org.elasticsearch.common.*;
import java.nio.file.*;
import java.io.*;
import java.util.jar.*;

public class XPackBuild
{
public static final XPackBuild CURRENT;
private String shortHash;
private String date;

@SuppressForbidden(reason = "looks up path of xpack.jar directly")
static Path getElasticsearchCodebase() {
final URL url = XPackBuild.class.getProtectionDomain().getCodeSource().getLocation();
try {
return PathUtils.get(url.toURI());
}
catch (URISyntaxException bogus) {
throw new RuntimeException(bogus);
}
}

XPackBuild(final String shortHash, final String date) {
this.shortHash = shortHash;
this.date = date;
}

public String shortHash() {
return this.shortHash;
}

public String date() {
return this.date;
}

static {
final Path path = getElasticsearchCodebase();
String shortHash = null;
String date = null;
Label_0109: {
/*
if (path.toString().endsWith(".jar")) {
try {
final JarInputStream jar = new JarInputStream(Files.newInputStream(path, new OpenOption[0]));
try {
final Manifest manifest = jar.getManifest();
shortHash = manifest.getMainAttributes().getValue("Change");
date = manifest.getMainAttributes().getValue("Build-Date");
jar.close();
}
catch (Throwable t) {
try {
jar.close();
}
catch (Throwable t2) {
t.addSuppressed(t2);
}
throw t;
}
break Label_0109;
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
*/
shortHash = "Unknown";
date = "Unknown";
}
CURRENT = new XPackBuild(shortHash, date);
}
}

将校验文件是否修改的逻辑注释了即可。 将这两个文件上传到安装了ES的服务器上,进行编译生成class字节码文件。

1
2
3
4
5
# 编译LicenseVerifier.java
javac -cp "/usr/share/elasticsearch/lib/elasticsearch-7.8.0.jar:/usr/share/elasticsearch/lib/lucene-core-8.0.0.jar:/usr/share/elasticsearch/modules/x-pack-core/x-pack-core-7.8.0.jar:/usr/share/elasticsearch/modules/x-pack-core/netty-common-4.1.32.Final.jar:/usr/share/elasticsearch/lib/elasticsearch-core-7.8.0.jar" /root/LicenseVerifier.java

# 编译XPackBuild.java
javac -cp "/usr/share/elasticsearch/lib/elasticsearch-7.8.0.jar:/usr/share/elasticsearch/lib/lucene-core-8.0.0.jar:/usr/share/elasticsearch/modules/x-pack-core/x-pack-core-7.8.0.jar:/usr/share/elasticsearch/modules/x-pack-core/netty-common-4.1.32.Final.jar:/usr/share/elasticsearch/lib/elasticsearch-core-7.8.0.jar" /root/XPackBuild.java

替换生成的class文件

将es安装包/usr/share/elasticsearch/modules/x-pack-core内的x-pack-core-7.8.0.jar拷贝到其他目录,按照如下步骤进行替换:

1
2
3
4
5
6
# 将其拷贝到其他目录
cp /usr/share/elasticsearch/modules/x-pack-core/x-pack-core-7.0.1.jar /root/es
# 进入/root
cd ~/es
# 解压
jar -xvf x-pack-core-7.8.0.jar

查看文件

1
2
3
4
ls
ilm-history-ilm-policy.json monitoring-alerts-7.json monitoring-logstash.json security-tokens-index-template-7.json watches.json watch-history-no-ilm-10.json
ilm-history.json monitoring-beats.json org slm-history-ilm-policy.json watch-history-10.json watch-history-no-ilm.json
logstash-management.json monitoring-es.json public.key slm-history.json watch-history-ilm-policy.json x-pack-core-7.8.0.jar META-INF monitoring-kibana.json security-index-template-7.json triggered-watches.json watch-history.json

替换文件

1
2
cp /root/XPackBuild.class org/elasticsearch/xpack/core/
cp /root/LicenseVerifier.class org/elasticsearch/license/

替换完成后,重新将其打包,在刚才操作的目录`/root/es`,执行如下命令:

重新打包

1
2
3
4
# 先删除刚才解压的文件
rm -rf x-pack-core-7.8.0.jar
# 重新生成,注意后面的点,代表当前目录
jar cvf x-pack-core-7.8.0.jar .

替换x-pack-core-7.8.0.jar

1
2
# 将x-pack-core-7.8.0.jar拷贝到该目录
cp ~/es/x-pack-core-7.8.0.jar /usr/share/elasticsearch/modules/x-pack-core

替换完成后重启ElasticSearch

申请免费的ElasticSearch License

打开Register Elastic申请一个一年的免费license,申请完成后会发送文件到你的邮箱中,打开后: 点击Download the license for Elasticsearch 5.x/6.x,下载后打开这个文件,修改两个地方,将typebasic修改为platinum(白金),将expiry_date_in_millis修改为2524579200999(2050年)。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"license": {
"uid": "c3f3df93-4636-45af-aafa-65d982dcabcd",
"type": "platinum", //修改这里
"issue_date_in_millis": 1594598400000,
"expiry_date_in_millis": 2524579200999, //修改这里
"max_nodes": 100,
"issued_to": "Yun Ma (alibaba)",
"issuer": "Web Form",
"signature": "AAAAAwAAAA2OlDvwgEit+SgvmIMdAAABmC9ZN0hjZDBGYnVyRXpCOW5Bb3FjZDAxOWpSbTVoMVZwUzRxVk1PSmkxaktJRVl5MUYvUWh3bHZVUTllbXNPbzBUemtnbWpBbmlWRmRZb25KNFlBR2x0TXc2K2p1Y1VtMG1UQU9TRGZVSGRwaEJGUjE3bXd3LzRqZ05iLzRteWFNekdxRGpIYlFwYkJdadadvcvTVlJKNVlXekMrSlVUdFIvV0FNeWdOYnlESDc3MWhlY3hSQmdKSjJ2ZTcvYlBFOHhPQlV3ZHdDQ0tHcG5uOElCaDJ4K1hob29xSG85N0kvTWV3THhlQk9NL01VMFRjNDZpZEVXeUtUMXIyMlIveFpJUkk2WUdveEZaME9XWitGUi9WNTZVQW1FMG1DenhZU0ZmeXlZakVEMjZFT2NvOWxpZGlqVmlHNC8rWVVUYzMwRGVySHpIdURzKzFiRDl4TmM1TUp2VTBOUlJZUlAyV0ZVL2kvVk10L0NsbXNFYVZwT3NSU082dFNNa2prQ0ZsclZ4NTltbU1CVE5lR09Bck93V2J1Y3c9PQAAAQAiHgOdr6bXoO1mENpZuipAKKjoMyW2cAT0DD8FQ2fotYibJO2rK4JX4e4Ce4yO/g5lv6/DgNt95qN2m9c2NpZlv3Qu0wg3lovrnAzstX3IddpnIvoDOIOTDULFLBNL5+jENUVZ+OtKewXUqldPKQWA4v2a4UjQ8TKV6dwxYNMz55Ml8y0XU9mK/DoRCsXUwDFsOdR+bUHOZsTMA1EUgosIykxo5L8E7bYgMIuW8IirRB50DmtzUxCe5eX+SoarOIHVKQica/YHXETD0dzGRhHR7AOm3AMoHnXcg652dNvKVbyiaSXLaTwy2NuHKxmRR9L/fcPgA/xf2+pCXzTMfgjm",
"start_date_in_millis": 1594598400000
}
}

修改完成后将这个文件通过kibana上传上去即可。