声明:本文仅作为学习交流,请勿用于商业用途,否则后果自负。如需使用黄金或白金版X-Pack请购买正版。
文章采用的ELK版本为5.4.3,其他版本没有做过验证。本文参考了博文http://blog.csdn.net/u013066244/article/details/73927756的破解方法,并解决了破解后空指针问题。
首先需要正常安装Kibana 5.4.3和ElasticSearch 5.4.3及其x-pack组件。
ElasticSearch 破解步骤如下:
1.下载ElasticSearch 目录中的/plugins/x-pack/x-pack-5.4.3.jar,并反编译。
注:此处要用 Luyten 来进行反编译,jd-gui有些文件反编译不出来。
主要需要反编译的两个文件:
org/elasticsearch/license/LicenseVerifier.class org/elasticsearch/xpack/XPackBuild.class
反编译后,将这两个文件做如下修改,并保存问java文件。
LicenseVerifier.java,跳过校验部分,直接返回true
package org.elasticsearch.license; public class LicenseVerifier { public static boolean verifyLicense(final License license, final byte[] array) { return true; } public static boolean verifyLicense(final License license) { return true; } }
XPackBuild.java,主要修改static部分,获取hash和date,这两个值需要跟“curl XGET ${es_host}/_xpack”这个命令执行结果中的build的值一样,如果有需要,可以直接sysout输出到控制台,然后update到es中
package org.elasticsearch.xpack; 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; if (path.toString().endsWith(".jar")) { try { // JarInputStream jar = new JarInputStream(Files.newInputStream(path)); JarFile jar = new JarFile(path.toString()); Manifest manifest = jar.getManifest(); shortHash = manifest.getMainAttributes().getValue("Change"); date = manifest.getMainAttributes().getValue("Build-Date"); } catch (IOException e) { throw new RuntimeException(e); } } else { shortHash = "Unknown"; date = "Unknown"; } // System.out.println("hash:"+ shortHash); // System.out.println("date:"+ date); CURRENT = new XPackBuild(shortHash, date); } }
2. 将这两个java上传到服务器中,进行javac编译,我的es安装路径:/usr/local/elastic/elasticsearch-node1,以下用${es_dir}代替
javac -cp "${es_dir}/lib/elasticsearch-5.4.3.jar:${es_dir}/lib/lucene-core-6.5.1.jar:${es_dir}/plugins/x-pack/x-pack-5.4.3.jar" LicenseVerifier.java javac -cp "${es_dir}/lib/elasticsearch-5.4.3.jar:${es_dir}/lib/lucene-core-6.5.1.jar:${es_dir}/plugins/x-pack/x-pack-5.4.3.jar" XPackBuild.java
3. 将编译好的两个class下载到本地,用压缩工具将其打包覆盖到x-pack-5.4.3.jar中。
4. 将修改好的x-pack-5.4.3.jar上传到${es_host}/plugins/x-pack/中,将原来的覆盖掉,如果是集群,则每个节点都需要覆盖。
5. 更新之后,启动ES。
6. 去官网申请license,将得到一个类似如下json格式的文件
{ "license": { "uid": "fd2deee3-*****-4fd959056bea", "type": "platinum", "issue_date_in_millis": 1504051200000, "expiry_date_in_millis": 1598922000000, "max_nodes": 100, "issued_to": "hong king", "issuer": "Web Form", "signature": "AAAAAwAAA.......N长的一串.......zdGJHVbnD3yd", "start_date_in_millis": 1504051200000 } }
将其中的type修改为“platinum”,过期时间(expiry_date_in_millis)随便设置一个将来的日期,其他数据视实际情况修改。将文件保存为license.json
7. 将license.json文件上传到服务器,并执行以下命令
curl -XPUT -u elastic:changeme 'http://192.168.1.115:9200/_xpack/license' -d @license.json
注:如果有多个节点,则每个节点都需要按这个命令进行license更新
8. 再次重启ES就OK了。
Kibana的破解:
如果这端不做修改,目前也没有问题,不过我不知道在expiry_date_in_millis时间之后会不会有什么问题,为了保险起见可以按如下步骤处理。
1. 修改${kibana}/plugins/x-pack/server/lib/_xpack_info.js文件,将其中需要验证的函数方法都返回true,修改后的文件如下
import { createHash } from 'crypto'; import moment from 'moment'; import { get, set, includes, forIn } from 'lodash'; import Poller from './poller'; import { LICENSE_EXPIRY_SOON_DURATION_IN_DAYS } from './constants'; export default function _xpackInfo(server, pollFrequencyInMillis, clusterSource = 'data') { if(!pollFrequencyInMillis) { const config = server.config(); pollFrequencyInMillis = config.get('xpack.xpack_main.xpack_api_polling_frequency_millis'); } let _cachedResponseFromElasticsearch; const _licenseCheckResultsGenerators = {}; const _licenseCheckResults = {}; let _cachedXPackInfoJSON; let _cachedXPackInfoJSONSignature; const poller = new Poller({ functionToPoll: _callElasticsearchXPackAPI, successFunction: _handleResponseFromElasticsearch, errorFunction: _handleErrorFromElasticsearch, pollFrequencyInMillis, continuePollingOnError: true }); const xpackInfoObject = { license: { getUid: function () { return get(_cachedResponseFromElasticsearch, 'license.uid'); }, isActive: function () { // return get(_cachedResponseFromElasticsearch, 'license.status') === 'active'; return true; }, expiresSoon: function () { // const expiryDateMillis = get(_cachedResponseFromElasticsearch, 'license.expiry_date_in_millis'); // const expirySoonDate = moment.utc(expiryDateMillis).subtract(moment.duration(LICENSE_EXPIRY_SOON_DURATION_IN_DAYS, 'days')); // return moment.utc().isAfter(expirySoonDate); return false; }, getExpiryDateInMillis: function () { return get(_cachedResponseFromElasticsearch, 'license.expiry_date_in_millis'); }, isOneOf: function (candidateLicenses) { if (!Array.isArray(candidateLicenses)) { candidateLicenses = [ candidateLicenses ]; } return includes(candidateLicenses, get(_cachedResponseFromElasticsearch, 'license.mode')); }, getType: function () { return get(_cachedResponseFromElasticsearch, 'license.type'); } }, feature: function (feature) { return { isAvailable: function () { // return get(_cachedResponseFromElasticsearch, 'features.' + feature + '.available'); return true; }, isEnabled: function () { // return get(_cachedResponseFromElasticsearch, 'features.' + feature + '.enabled'); return true; }, registerLicenseCheckResultsGenerator: function (generator) { _licenseCheckResultsGenerators[feature] = generator; _updateXPackInfoJSON(); }, getLicenseCheckResults: function () { return _licenseCheckResults[feature]; } }; }, isAvailable: function () { // return !!_cachedResponseFromElasticsearch && !!get(_cachedResponseFromElasticsearch, 'license'); return true; }, getSignature: function () { return _cachedXPackInfoJSONSignature; }, refreshNow: function () { const self = this; return _callElasticsearchXPackAPI() .then(_handleResponseFromElasticsearch) .catch(_handleErrorFromElasticsearch) .then(() => self); }, stopPolling: function () { // This method exists primarily for unit testing poller.stop(); }, toJSON: function () { return _cachedXPackInfoJSON; } }; const cluster = server.plugins.elasticsearch.getCluster(clusterSource); function _callElasticsearchXPackAPI() { server.log([ 'license', 'debug', 'xpack' ], 'Calling Elasticsearch _xpack API'); return cluster.callWithInternalUser('transport.request', { method: 'GET', path: '/_xpack' }); }; function _updateXPackInfoJSON() { const json = {}; // Set response elements common to all features set(json, 'license.type', xpackInfoObject.license.getType()); set(json, 'license.isActive', xpackInfoObject.license.isActive()); set(json, 'license.expiryDateInMillis', xpackInfoObject.license.getExpiryDateInMillis()); // Set response elements specific to each feature. To do this, // call the license check results generator for each feature, passing them // the xpack info object forIn(_licenseCheckResultsGenerators, (generator, feature) => { _licenseCheckResults[feature] = generator(xpackInfoObject); // return value expected to be a dictionary object }); set(json, 'features', _licenseCheckResults); _cachedXPackInfoJSON = json; _cachedXPackInfoJSONSignature = createHash('md5') .update(JSON.stringify(json)) .digest('hex'); } function _hasLicenseInfoFromElasticsearchChanged(response) { const cachedResponse = _cachedResponseFromElasticsearch; return (get(response, 'license.mode') !== get(cachedResponse, 'license.mode') || get(response, 'license.status') !== get(cachedResponse, 'license.status') || get(response, 'license.expiry_date_in_millis') !== get(cachedResponse, 'license.expiry_date_in_millis')); } function _getLicenseInfoForLog(response) { const mode = get(response, 'license.mode'); const status = get(response, 'license.status'); const expiryDateInMillis = get(response, 'license.expiry_date_in_millis'); return [ 'mode: ' + mode, 'status: ' + status, 'expiry date: ' + moment(expiryDateInMillis, 'x').format() ].join(' | '); } function _handleResponseFromElasticsearch(response) { if (_hasLicenseInfoFromElasticsearchChanged(response)) { let changed = ''; if (_cachedResponseFromElasticsearch) { changed = 'changed '; } const licenseInfo = _getLicenseInfoForLog(response); const logMessage = `Imported ${changed}license information from Elasticsearch for [${clusterSource}] cluster: ${licenseInfo}`; server.log([ 'license', 'info', 'xpack' ], logMessage); } _cachedResponseFromElasticsearch = response; _updateXPackInfoJSON(); } function _handleErrorFromElasticsearch(error) { server.log([ 'license', 'warning', 'xpack' ], 'License information could not be obtained from Elasticsearch. ' + error); _cachedResponseFromElasticsearch = null; _updateXPackInfoJSON(); // allow tests to shutdown error.info = xpackInfoObject; throw error; } // Start polling for changes return poller.start() .then(() => xpackInfoObject); }
2. 删除${kibana}/optimize下的所有编译文件
3. 启动kibana
完工,附件为破解后的jar包和license文件。
补充:另一破解思路是,自己生成RSA的公钥私钥,然后按照 LicenseVerifier里的验证方法,自己写一个加密方法计算license.signature,然后替换jar中的public.key,上传后,再导入license.json,该方法没有验证,等后期验证完再详细说明。
在整个破解过程中,在按照参考博文进行破解时也碰到空指针错误,经排查是XPackBuild用JarInputStream读取jar包后,获取不到Manifest 对象,所以改用JarFile来读取jar包文件。
参考链接:http://blog.csdn.net/u013066244/article/details/73927756
相关推荐
Elasticsearch 7.6 和 Kibana 7.6 开启 X-Pack,支持 HTTPS 访问 ES,增加 ES 用户认证,增强数据安全,Kibana 支持用户权限分配,支持汉化。 Elasticsearch 7.6 和 Kibana 7.6 的 X-Pack 是一组商业功能,提供了...
8. 一站式解决方案:X-Pack整合了Elasticsearch、Logstash、Kibana和Beats等多个组件,为用户提供了一个完整的数据处理、搜索、分析和可视化平台,使得企业可以更加高效地管理和利用其数据。 总结来说,X-Pack增强...
6. **X-Pack设置**: X-Pack是Elasticsearch的安全组件,包括身份验证、权限管理等功能。安装X-Pack的步骤包括在每个节点上解压`x-pack`插件,然后在`elasticsearch.yml`中启用它,如`xpack.security.enabled: true`...
ELK(Elasticsearch, Logstash, Kibana)是一个流行的开源日志分析栈,用于收集、解析、存储和可视化各种日志数据。在ELK 6.3.2版本中,X-Pack是一个包含安全、监控、警报、报告和管理功能的插件集合。X-Pack的引入...
Kibana 是 Elasticsearch 的可视化界面,5.* 版本的 Kibana 与 X-Pack 集成更加紧密,提供了丰富的可视化面板和工作台,方便用户进行数据分析和故障排查。 总的来说,Elasticsearch 的 X-Pack 5.* 通过提供全面的...
5.6.3 X-Pack elasticsearch logstash kibana 参考: https://www.waitig.com/x-pack破解.html http://blog.csdn.net/qq_20641565/article/details/78286894 # curl -u elastic:changeme '...
Elasticsearch是一个强大的开源搜索引擎,而Kibana是与之配套的数据可视化和分析工具,尤其在日志管理和实时数据分析方面表现突出。Kibana 6.0.0是其一个重要的版本,它提供了丰富的功能,使得用户能够方便地对...
X-Pack是Elastic公司为Elastic Stack(包括Elasticsearch、Logstash、Kibana和Beats)提供的一款强大扩展,版本5.4.0包含了丰富的特性和功能。Elastic Stack是一套开源的数据收集、分析和可视化工具,广泛应用于日志...
**Elasticsearch 5.2.0 和 Kibana 5.2.0 for Windows x86** Elasticsearch 是一个流行的开源全文搜索引擎,广泛应用于数据检索、分析和存储。5.2.0 版本是 Elasticsearch 的一个重要里程碑,它在性能、稳定性和用户...
x-pack-5.6.4.jar 是 elk 必备文件 5.6.4 X-Pack elasticsearch logstash kibana 步骤:下载本文件,替换elasticsearch里同名文件,重启es、kibana,申请注册文件,修改注册文件到永久,注册,搞定。 参考: ...
至于压缩包子文件 "Snipaste-1.16.2-x64" 似乎与 Kibana 无关,它可能是一个截屏工具 Snipaste 的版本,同样为 64 位系统设计。Snipaste 是一款轻量级且功能强大的截图工具,允许用户快速捕获屏幕图像并将其作为贴图...
《X-Pack 6.2.4:Elasticsearch与Kibana协同工作的重要插件》 X-Pack 6.2.4是Elastic生态系统中的一个重要组成部分,它为Elasticsearch和Kibana提供了丰富的安全、监控、告警、报告以及管理功能。这个版本与elastic...
7. **安全性和权限**:7.14.0版本可能包含增强的安全特性,例如支持基本认证、TLS/SSL加密以及集成Elasticsearch的X-Pack安全模块,这使得Kibana的数据访问和管理更加安全。 8. **插件和自定义**:Kibana允许安装和...
Kibana是一款强大的开源分析和可视化平台,专为与Elasticsearch协同工作而设计。它提供了丰富的数据探索、仪表板创建以及数据可视化的功能,帮助用户理解存储在Elasticsearch中的海量数据。Kibana的核心目标是使数据...
Kibana是ELK Stack(Elasticsearch、Logstash、Kibana)的重要组成部分,它为Elasticsearch的数据提供了强大的可视化界面,使得数据的分析和理解变得更加直观易懂。在本篇中,我们将深入探讨Kibana 6.7.1的特性及其...
搭建elasticsearch集群需要的x-pack for kibana : x-pack-core-6.7.2.jar
虽然“kibana-6.3.0-windows-x64”可能不包含完整的X-Pack插件,但Kibana 6.3.0版本已经集成了部分X-Pack的基础功能,如安全、监视、报告和警报等,提供更高级的安全管理和监控能力。 七、日志分析 Kibana与...
Linux Kibana 7.15.1 是一个强大的数据可视化和分析工具,主要用于与Elasticsearch协同工作,提供交互式的数据探索和仪表板构建功能。这个版本是针对64位Linux系统的,所以文件名为“kibana-7.15.1-linux-x86_64.tar...
docker cp <Elasticsearch容器ID>:/usr/share/elasticsearch/modules/x-pack/x-pack-core/x-pack-core-6.3.0.jar /docker/elasticsearch/ ``` - **参数解释**: - `<Elasticsearch容器ID>`: 此处应替换为实际运行...