0x01 本地化集成包更新服务
安装集成更新服务
容器
docker pull docker.elastic.co/package-registry/distribution:8.15.3
这个包很大, 建议使用🪜安装
启动
docker run -it -p 8080:8080 docker.elastic.co/package-registry/distribution:8.15.3
使用该方式,每次有更新的时候,都需要重新拉取新包,比较麻烦, 后面会讲到使用程序进行自动更新
自编译
如果想要Kibana不去es官网而是从我们内网环境中获取集成组件的相关数据,就需要使用es官网提供的package-registry
服务
相关源代码如下: https://github.com/elastic/package-registry
基础环境准备
系统环境中需要安装golang, 目前的版本要求是1.23版本
wget https://go.dev/dl/go1.23.2.linux-amd64.tar.gz
编译更新服务
wget https://github.com/elastic/package-registry/archive/refs/tags/v1.26.0.zip
unzip v1.26.0.zip
cd package-registry-1.26.0
go build
修改配置文件
config.yml
package_path
参数根据具体环境指定即可,这里我将该路径指定为可执行程序的当前目录的packages
目录下
package_paths:
- ./packages
cache_time.index: 10s
cache_time.search: 10m
cache_time.categories: 10m
cache_time.catch_all: 10m
启动服务
./package-registry --address 0.0.0.0:8080
同步集成包
获取所有的集成包信息
https://epr.elastic.co/search
如果加上get参数all=true
,https://epr.elastic.co/search?all=true
则表示获取所有的包。没有参数默认只返回最新的包。
返回格式如下:
[
{
"name": "1password",
"title": "1Password",
"version": "1.10.0",
"release": "ga",
"description": "Collect logs from 1Password with Elastic Agent.",
"type": "integration",
"download": "/epr/1password/1password-1.10.0.zip",
"path": "/package/1password/1.10.0",
"icons": [
{
"src": "/img/1password-logo-light-bg.svg",
"path": "/package/1password/1.10.0/img/1password-logo-light-bg.svg",
"title": "1Password",
"size": "116x116",
"type": "image/svg+xml"
}
],
"policy_templates": [
{
"name": "1password",
"title": "1Password Events",
"description": "Collect events from 1Password Events Reporting"
}
],
"conditions": {
"kibana": {
"version": "^8.6.1"
}
},
"owner": {
"github": "elastic/security-external-integrations"
},
"categories": [
"security",
"credential_management"
],
"signature_path": "/epr/1password/1password-1.10.0.zip.sig"
},
.....
]
然后根据上面的返回的数据,从url
https://package-storage.elastic.co/artifacts/packages/
进行下载,比如下载1password
,根据上面获取的数据中的signature_path
字段,下载
# 下载安装包
https://package-storage.elastic.co/artifacts/packages/1password-1.10.0.zip
#下载hash
https://package-storage.elastic.co/artifacts/packages/1password-1.10.0.zip.sig
实现自动化的集成更新程序。
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
type UpdateIntegrations struct {
installedIntegrations map[string]bool
allIntegrations map[string]bool
interval time.Duration
directory string
newIntegrationsCount int
}
func NewUpdateIntegrations(directory string, interval time.Duration) *UpdateIntegrations {
return &UpdateIntegrations{
installedIntegrations: make(map[string]bool),
allIntegrations: make(map[string]bool),
interval: interval,
directory: directory,
}
}
var integrationClient = &http.Client{
Transport: &http.Transport{DisableKeepAlives: false},
}
func (ui *UpdateIntegrations) getAllIntegrationsInfo() {
log.Println("Getting all integrations info")
client := &http.Client{}
//"https://epr.elastic.co/search?all=true") # 获取所有的包
req, err := http.NewRequest("GET", "https://epr.elastic.co/search", nil)
if err != nil {
log.Fatalf("Failed to create request: %v", err)
}
req.Header.Set("User-Agent", "Kibana/8.15.3 node-fetch")
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Failed to get response: %v", err)
}
defer resp.Body.Close()
var items []map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&items); err != nil {
log.Printf("Failed to decode JSON: %v", err)
}
for _, item := range items {
if signaturePath, ok := item["signature_path"].(string); ok {
filename := strings.TrimSuffix(filepath.Base(signaturePath), ".sig")
ui.allIntegrations[filename] = true
} else {
log.Printf("Get signature_path error: %v", item["name"])
}
}
log.Println("getAllIntegrationsInfo success")
}
func (ui *UpdateIntegrations) downloadFile(url, filename string) error {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("User-Agent", "Kibana/8.15.3 node-fetch")
resp, err := integrationClient.Do(req)
if err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
defer resp.Body.Close()
out, err := os.Create(filepath.Join(ui.directory, filename))
if err != nil {
return fmt.Errorf("failed to create file: %w", err)
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
return fmt.Errorf("failed to write to file: %w", err)
}
return nil
}
func (ui *UpdateIntegrations) downloadIntegrations(filename string) {
for i := 0; i < 3; i++ {
if i > 0 {
log.Printf("Download integrations failed, retry %d", i)
}
url := fmt.Sprintf("https://package-storage.elastic.co/artifacts/packages/%s", filename)
if err := ui.downloadFile(url, filename); err != nil {
log.Printf("Download integrations error: %v", err)
time.Sleep(2 * time.Second)
continue
}
sigFilename := filename + ".sig"
sigURL := fmt.Sprintf("https://package-storage.elastic.co/artifacts/packages/%s", sigFilename)
if err := ui.downloadFile(sigURL, sigFilename); err != nil {
log.Printf("Download integrations sig file error: %v", err)
time.Sleep(2 * time.Second)
continue
}
ui.newIntegrationsCount++
log.Printf("Download new integrations success: %s", filename)
return
}
}
func (ui *UpdateIntegrations) readPackagesName() {
files, err := os.ReadDir(ui.directory)
if err != nil {
log.Fatalf("Failed to read directory: %v", err)
}
for _, file := range files {
if strings.HasSuffix(file.Name(), ".sig") {
ui.installedIntegrations[strings.TrimSuffix(file.Name(), ".sig")] = true
}
}
}
func (ui *UpdateIntegrations) updateIntegrations() {
for {
ui.getAllIntegrationsInfo()
ui.readPackagesName()
for filename := range ui.allIntegrations {
if !ui.installedIntegrations[filename] {
ui.downloadIntegrations(filename)
}
}
log.Printf("updateIntegrations done, install new package number: %d", ui.newIntegrationsCount)
log.Printf("sleep %f seconds", ui.interval.Seconds())
ui.newIntegrationsCount = 0
time.Sleep(ui.interval)
}
}
func main() {
logFile, err := os.OpenFile("./update_integrations.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("Failed to open log file: %v", err)
}
defer logFile.Close()
log.SetOutput(logFile)
log.Println("update_integrations start")
updateIntegrations := NewUpdateIntegrations("./packages", 24*time.Hour)
updateIntegrations.updateIntegrations()
}
配置kibana
修改kibana的配置文件/etc/kibana/kibana.yml
,让其默认访问我们搭建的内网集成服务
xpack.fleet.isAirGapped: true
xpack.fleet.registryUrl: "http://127.0.0.1:8080"
重启kibana服务,完成
systemctl restart kibana
0x02 本地化二进制包升级服务
官网的地址为:https://artifacts.elastic.co
下载所有的二进制包
curl -O https://artifacts.elastic.co/downloads/apm-server/apm-server-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/apm-server/apm-server-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/apm-server/apm-server-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/auditbeat/auditbeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/auditbeat/auditbeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/auditbeat/auditbeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/elastic-agent/elastic-agent-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/heartbeat/heartbeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/osquerybeat/osquerybeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/osquerybeat/osquerybeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/osquerybeat/osquerybeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/beats/packetbeat/packetbeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/beats/packetbeat/packetbeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/beats/packetbeat/packetbeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/cloudbeat/cloudbeat-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/cloudbeat/cloudbeat-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/cloudbeat/cloudbeat-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/endpoint-dev/endpoint-security-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/endpoint-dev/endpoint-security-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/endpoint-dev/endpoint-security-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/fleet-server/fleet-server-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/fleet-server/fleet-server-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/fleet-server/fleet-server-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-host-agent-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-host-agent-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-host-agent-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-elastic-collector-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-elastic-collector-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-elastic-collector-8.15.3-linux-x86_64.tar.gz.asc
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-elastic-symbolizer-8.15.3-linux-x86_64.tar.gz
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-elastic-symbolizer-8.15.3-linux-x86_64.tar.gz.sha512
curl -O https://artifacts.elastic.co/downloads/prodfiler/pf-elastic-symbolizer-8.15.3-linux-x86_64.tar.gz.asc
然后自己搭建一个文件服务器即可完成。
注意: 访问的链接的格式必须满足 http[s]:/[你的域名或者IP+端口]/downloads/beats/osquerybeat/osquerybeat-8.15.3-linux-x86_64.tar.gz.sha512
最后在fleet-》设置 里面设置即可