jamesagarside/elastic-at-home
GitHub: jamesagarside/elastic-at-home
基于 Elastic Stack 和 Docker Compose 构建的家庭网络自托管 SIEM/XDR 平台,可在 Raspberry Pi 上实现终端检测、syslog 摄取和威胁分析。
Stars: 5 | Forks: 1
# Elastic 在家庭中的使用
[](LICENSE)
[](https://github.com/jamesagarside/elastic-at-home/releases/latest)
[](https://github.com/jamesagarside/elastic-at-home/stargazers)
[](https://github.com/jamesagarside/elastic-at-home/commits)
[](https://www.elastic.co/)
[](https://docs.docker.com/compose/)
[](https://www.raspberrypi.com/)
[](https://traefik.io/)
**一个为家庭网络设计的自托管 SIEM 和 XDR 平台,基于 Elastic Stack、Docker Compose 和 Raspberry Pi 构建。**
Elastic at Home 将一台低成本设备转变为一个完整的家庭安全运营中心:SIEM、终端检测与响应(EDR)、威胁情报、从您的路由器/防火墙收集 syslog、基于机器学习的异常检测,以及用于私密 AI 辅助调查的可选本地 LLM。一切都在容器中运行,所有流量都经过 TLS 加密,无需将任何数据传出您的网络。

## 目录
- [为什么选择 Elastic at Home?](#why-elastic-at-home)
- [功能](#features)
- [快速开始](#quick-start)
- [物料清单](#bill-of-materials)
- [前置条件](#prerequisites)
- [安装 Docker](#install-docker--docker-compose)
- [部署 Elastic Stack](#deploy-the-elastic-stack)
- [访问您的 Stack](#access-your-stack)
- [证书模式](#certificate-modes)
- [本地 LLM(可选)](#local-llm-optional)
- [项目结构](#project-structure)
- [核心概念](#core-concepts)
- [故障排除](#troubleshooting)
- [常见问题](#faq)
## 为什么选择 Elastic at Home?
商业家庭安全工具大多是封闭的、极度渴求数据的,并且很少将网络和终端信号进行交叉关联。企业级 SIEM 功能强大,但定价专为大型企业设计。Elastic at Home 填补了这一空白:世界 500 强企业 SOC 中运行的同类 Elastic Security 平台,现在可以部署在您家中的 Raspberry Pi 5 上,监控您的家庭网络和设备,而您只需承担硬件成本。
**适用人群:** 家庭实验室爱好者、需要练习环境的安全专业人士、注重隐私的用户,以及任何希望真正了解自己网络中正在发生什么的人。
## 功能
- **SIEM**:带有预构建检测规则、警报、时间线和调查工作流的 Elastic Security
- **EDR / XDR**:用于进程、文件和网络遥测数据的 Elastic Defend 终端代理
- **Syslog 摄取**:用于路由器、防火墙和交换机的 TCP 和 UDP pipeline(Ubiquiti、pfSense、OPNsense 等)
- **威胁情报**:与开源和商业威胁情报源集成
- **基于机器学习的异常检测**:DNS 和网络流量异常检测任务(试用版/Platinum 版)
- **Slack 警报**:将高严重性检测推送到您的手机
- **Fleet 管理的代理**:从 Kibana 集中配置每个代理
- **本地 LLM(可选)**:Ollama 加 Google Gemma 4 E2B 为 Kibana AI Assistant 提供动力,数据无需离开您的网络
- **三种入口模式**:Let's Encrypt(公共信任)、自签名(物理隔离/air-gapped)或直接 IP:端口(无需 DNS)
- **一条命令部署**:执行 `docker compose up -d`,整个 stack 将自动完成初始化引导
## 快速开始
在 5 分钟内运行起 Elastic Stack(假设已安装 Docker):
```
# 1. 克隆 repository
git clone https://github.com/jamesagarside/elastic-at-home.git
cd elastic-at-home
# 2. 创建你的环境文件
cp .env.example .env
# 3. 编辑 .env 并设置:
# - ELASTIC_PASSWORD (管理员密码)
# - KIBANA_PASSWORD (内部 Kibana 密码)
# - INGRESS_MODE (selfsigned | letsencrypt | direct)
# 4. 启动 stack
docker compose up -d
# 5. 等待服务变为 healthy 状态(约 3-5 分钟)
docker compose ps
# 6. 打开 Kibana
# selfsigned/letsencrypt: https://kibana.yourdomain.com
# direct: https://:5601
# 用户名:elastic
# 密码:<你的 ELASTIC_PASSWORD>
```
如需逐步操作指南,请跳转到[前置条件](#prerequisites)。
## 物料清单
- [Raspberry Pi 5 (16 GB)](https://thepihut.com/products/raspberry-pi-5?variant=53972414431617)
- [GeeekPi P31 M.2 NVMe PoE+ Hat](https://www.amazon.co.uk/dp/B0D7BXGLH8?ref=ppx_yo2ov_dt_b_fed_asin_title)
- [Crucial P310 SSD 1TB M.2 2230 NVMe](https://www.amazon.co.uk/dp/B0D61Z8R1W?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1)
此设置使用以太网供电,因此您需要一个支持 PoE 的交换机或供电模块。
## 前置条件
### 1. 将 `vm.max_map_count` 设置为至少 `262144`
```
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
```
### 2. 禁用 swap
**Raspberry Pi OS**(使用 `dphys-swapfile`):
```
sudo dphys-swapfile swapoff && sudo dphys-swapfile uninstall && sudo systemctl disable dphys-swapfile
```
**其他 Debian/Ubuntu 主机**(无 `dphys-swapfile`):
```
sudo swapoff -a
# 注释掉(或删除)/etc/fstab 中的任何 swap 条目,以便 swap 在重启后保持关闭
sudo sed -i.bak '/\sswap\s/s/^/# /' /etc/fstab
```
### 3. 启用 cgroup 内存控制器(仅限 Raspberry Pi)
```
sudo sed -i 's/$/ cgroup_enable=memory cgroup_memory=1/' /boot/firmware/cmdline.txt && sudo reboot
```
### 4. 调整基于 PCIe 的 NVMe(仅限 Raspberry Pi 5)
针对 [52pi POE+NVMe](https://wiki.52pi.com/index.php?title=EP-0241) hat:
```
sudo rpi-eeprom-config --edit
# 添加:PSU_MAX_CURRENT=5000
# 保存并重启
```
在 `/boot/firmware/config.txt` 中启用 PCIe:
```
dtparam=pciex1
# 可选:强制使用 Gen 3.0 (10 GT/sec)。该接口仅通过 Gen 2.0 认证。
dtparam=pciex1_gen=3
```
## 安装 Docker & Docker Compose
```
# 添加 Docker 官方 GPG key
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# 添加 repository
sudo tee /etc/apt/sources.list.d/docker.sources </dev/null || sudo groupadd docker
sudo usermod -aG docker $USER
# 在当前 shell 中应用新组;或者注销并重新登录
newgrp docker
```
## 部署 Elastic Stack
### 1. 克隆仓库
```
git clone https://github.com/jamesagarside/elastic-at-home.git
cd elastic-at-home
```
### 2. 创建您的 `.env` 文件
```
cp .env.example .env
vi .env
```
**必填设置:**
```
# 安全凭证(请修改这些!)
ELASTIC_PASSWORD=YourSecurePassword123!
KIBANA_PASSWORD=AnotherSecurePassword456!
# 选择你的证书模式
INGRESS_MODE=selfsigned # selfsigned | letsencrypt | direct
# 域名(selfsigned / letsencrypt 模式)
ES_DOMAIN_NAME=es.yourdomain.com
KIBANA_DOMAIN_NAME=kibana.yourdomain.com
FLEET_DOMAIN_NAME=fleet.yourdomain.com
```
### 3. 启动 stack
```
docker compose up -d
```
首次启动需要 3 到 5 分钟,因为 stack 需要生成 TLS 证书、初始化 Elasticsearch、配置 Kibana 和 Fleet,并注册 SIEM 代理。
### 4. 验证所有服务是否正常运行
```
docker compose ps
```
预期输出:
```
NAME STATUS
elastic-at-home-es01-1 Up (healthy)
elastic-at-home-kibana-1 Up (healthy)
elastic-at-home-fleet-server-1 Up (healthy)
elastic-at-home-agent-1 Up
elastic-at-home-traefik-1 Up
elastic-at-home-setup-1 Up (healthy)
```
## 访问您的 Stack
### 凭据
| 设置 | 值 |
| ------------ | ----------------------------------- |
| **用户名** | `elastic` |
| **密码** | 您在 `.env` 中的 `ELASTIC_PASSWORD` |
### 各模式对应的 URL
**自签名** (`INGRESS_MODE=selfsigned`):
| 服务 | URL |
| ------------- | ----------------------------- |
| Kibana | `https://` |
| Elasticsearch | `https://` |
| Fleet | `https://` |
**Let's Encrypt** (`INGRESS_MODE=letsencrypt`):URL 与自签名模式相同,但使用公开受信任的证书(无浏览器警告)。
**直接访问** (`INGRESS_MODE=direct`):
| 服务 | URL |
| ------------- | ------------------------ |
| Kibana | `https://:5601` |
| Elasticsearch | `https://:9200` |
| Fleet | `https://:8220` |
### 首次登录
1. 在浏览器中访问 Kibana
2. 接受证书警告(仅限自签名/直接访问模式)
3. 使用 `elastic` 和您的 `ELASTIC_PASSWORD` 登录
4. 前往 **Security > Overview** 查看您的 SIEM 仪表板
### 验证 Fleet 代理
1. 在 Kibana 中进入 **Management > Fleet**
2. 确认 `siem-agent` 已注册且状态为 **Healthy**
3. 代理已开始收集系统日志和指标
## 证书模式
Elastic at Home 支持三种 TLS/入口模式。请选择与您环境相匹配的模式;所有其他配置都会自动调整。
| 模式 | 最适用于 | 需要互联网 | 信任链 | 访问方式 |
| ---------------- | ------------------------------ | ---------------- | ------------------------------------------ | ------------------- |
| **selfsigned** | 物理隔离,仅限内部网络 | 否 | 点击通过(浏览器)/ 分发 CA(代理) | 主机名 :443 |
| **letsencrypt** | 生产环境,外部代理 | 是 (ACME) | 公开受信任(自动) | 主机名 :443 |
| **direct** | 开发,测试,无 DNS | 否 | 点击通过(浏览器)/ 分发 CA(代理) | IP : 服务端口 |
切换模式只需修改变量:
```
INGRESS_MODE=letsencrypt # or selfsigned | direct
```
然后,Docker Compose 会自动加载正确的 Traefik 配置 (`traefik-.yml`) 和 env 文件 (`configurations/elastic/env_files/.env.`)。
### 模式特定的 env 文件如何工作
每个模式的配置文件都位于 `configurations/elastic/env_files/`:
```
.env.selfsigned # CA paths for internal validation
.env.letsencrypt # No custom CA, uses system trust store
.env.direct # CA paths for internal validation
```
服务通过以下方式加载正确的配置:
```
env_file:
- configurations/elastic/env_files/.env.${INGRESS_MODE:-selfsigned}
```
### 为什么自签名/直接访问模式需要 CA 路径,而 Let's Encrypt 不需要?
| 变量 | selfsigned 和 direct | letsencrypt | 用途 |
| ------------------ | ----------------------------- | ----------- | ------------------------------------------- |
| `FLEET_CA` | `/certs/ca/ca.crt` | 未设置 | Fleet Server 到 Elasticsearch 的验证 |
| `ELASTICSEARCH_CA` | `/certs/ca/ca.crt` | 未设置 | 代理到 Elasticsearch 的验证 |
| `KIBANA_FLEET_CA` | `/certs/ca/ca.crt` | 未设置 | Kibana 到 Fleet Server 的验证 |
- **selfsigned/direct**:Traefik 提供由 Elasticsearch 内部 CA 签名的证书,因此代理需要 `ca.crt` 来验证它们。否则会出现:`certificate signed by unknown authority`。
- **letsencrypt**:Traefik 提供公开受信任的证书。系统信任库中已经包含 Let's Encrypt 根证书;指定自定义 CA 会破坏信任链。
### 结合 Cloudflare DNS 验证的 Let's Encrypt
**最适用于:** 需要公共信任且无需手动分发 CA 的生产环境部署。
Traefik 使用 [Lego](https://go-acme.github.io/lego/) 通过 [ACME DNS-01 验证](https://doc.traefik.io/traefik/reference/install-configuration/tls/certificate-resolvers/acme/#dnschallenge) 获取证书,支持[多家 DNS 提供商](https://go-acme.github.io/lego/dns/index.html)。证书会自动续期。
**要求:**
- 位于[受支持的 DNS 提供商](https://go-acme.github.io/lego/dns/index.html)处的域名
- 该提供商的 API token(例如 Cloudflare)
- 用于 ACME 的出站互联网访问
在 `.env` 中配置:
```
INGRESS_MODE=letsencrypt
ACME_EMAIL=your-email@example.com
CF_DNS_API_TOKEN=your-cloudflare-api-token
```
然后重新部署:
```
docker compose down && docker compose up -d
```
此方法要求您的客户端能够解析内部 DNS 记录。选项包括 [Pi-hole](https://pi-hole.net/)、[Unifi](https://ui.com/)、[pfSense](https://www.pfsense.org/),或 ISP 路由器上的自定义记录。设置一条泛域名 A 记录(从 `*.siem.example.com` 指向 ``)可以在您添加服务时省去后续维护的麻烦。

### 基于 Traefik 的自签名模式
**最适用于:** 物理隔离网络或仅限内部的部署。
Traefik 使用由 Elasticsearch 内置 CA 签名的证书进行反向代理。所有域名都作为 SAN 包含在同一张证书中。Traefik 使用内部 CA 验证后端服务证书(无需设置 `insecureSkipVerify`)。
**要求:**
- **浏览器:** 点击*继续*以跳过警告(使用无痕窗口以避免缓存证书问题)
- **代理:** 分发 `ca.crt` 并将其配置为受信任
- 不需要互联网访问
为代理提取 CA:
```
docker cp $(docker compose ps -q setup):/certs/ca/ca.crt ./ca.crt
```
默认模式;无需更改 `.env`:
```
INGRESS_MODE=selfsigned
```
### 直接访问(IP : 端口)
**最适用于:** 开发、测试或无 DNS 的环境。
Traefik 使用基于端口的路由。每个服务都有自己的主机端口。
| 服务 | URL |
| ------------- | ------------------------ |
| Kibana | `https://:5601` |
| Elasticsearch | `https://:9200` |
| Fleet Server | `https://:8220` |
| APM Server | `https://:8200` |
代理需执行与自签名模式相同的 CA 分发步骤。
```
INGRESS_MODE=direct
```
### 预期日志信息
### Traefik 入口流程(结合 Cloudflare 的 Let's Encrypt)
│
│ TXT Records: _acme-challenge.* (auto-created for ACME) │
└──────────────────────────────┬──────────────────────────────────┘
│
▼
┌────────────────────┐ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │ │ TRAEFIK │
│ INTERNET │ │ ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │ ENTRYPOINTS ROUTERS SERVICES │ │
│ ┌──────────────┐ │ │ │ │ │
│ │ Clients │ │ │ │ ┌─────────────┐ ┌────────────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ │
│ │ (Browsers, │──┼────►│ │ │ websecure │───►│ elastic.* ──► TLS:letsencrypt ─────────┼───►│ es01:9200 (Elasticsearch) │ │ │
│ │ Agents) │ │ 443 │ │ │ :443 │ │ kibana.* ──► TLS:letsencrypt ─────────┼───►│ kibana:5601 (Kibana) │ │ │
│ └──────────────┘ │ │ │ └─────────────┘ │ fleet.* ──► TLS:letsencrypt ─────────┼───►│ fleet-server:8220 (Fleet Server) │ │ │
│ │ │ │ │ apm.* ──► TLS:letsencrypt ─────────┼───►│ fleet-server:8200 (APM) │ │ │
│ ┌──────────────┐ │ │ │ └────────────────────────────────────────┘ └─────────────────────────────────────────┘ │ │
│ │ Syslog │ │ │ │ │ │
│ │ Sources │──┼────►│ │ ┌─────────────┐ ┌────────────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ │
│ │ (Routers, │ │5514 │ │ │ syslog-tcp │───►│ ClientIP(`192.168.0.0/16`) ────────────┼───►│ elastic-agent:5514/tcp │ │ │
│ │ Firewalls) │ │ │ │ │ :5514/tcp │ └────────────────────────────────────────┘ └─────────────────────────────────────────┘ │ │
│ └──────────────┘ │ │ │ └─────────────┘ │ │
│ │ │ │ │ │
│ ┌──────────────┐ │ │ │ ┌─────────────┐ ┌────────────────────────────────────────┐ ┌─────────────────────────────────────────┐ │ │
│ │ Syslog │──┼────►│ │ │ syslog-udp │───►│ HostSNI(`*`) ──────────────────────────┼───►│ elastic-agent:5514/udp │ │ │
│ │ (UDP) │ │5514 │ │ │ :5514/udp │ └────────────────────────────────────────┘ └─────────────────────────────────────────┘ │ │
│ └──────────────┘ │ │ │ └─────────────┘ │ │
│ │ │ └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │
└────────────────────┘ │ │
│ ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ CERTIFICATE RESOLVER (Let's Encrypt via DNS-01 Challenge) │ │
│ │ │ │
│ │ 1. Request cert ──► 2. DNS-01 challenge ──► 3. Create TXT via Cloudflare API ──► 4. Verify ──► 5. Issue cert │ │
│ │ │ │
│ │ Environment: CF_DNS_API_TOKEN= Storage: /letsencrypt/acme.json │ │
│ └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ DOCKER NETWORK (elastic) │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Elasticsearch │ │ Kibana │ │ Fleet Server │ │ Elastic Agent │ │
│ │ (es01) │ │ │ │ │ │ │ │
│ │ :9200/tcp │ │ :5601/tcp │ │ :8220/tcp (Fleet) │ │ :5514/tcp (Syslog) │ │
│ │ │ │ │ │ :8200/tcp (APM) │ │ :5514/udp (Syslog) │ │
│ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```
## 本地 LLM(可选)
Elastic at Home 附带了对通过 [Ollama](https://ollama.com) 运行本地大型语言模型的可选支持,运行的是 Google [Gemma 4 E2B](https://deepmind.google/models/gemma/gemma-4/)(20 亿参数)。这允许您使用 Elasticsearch 的 功能(Kibana AI Assistant、语义搜索、推理 pipeline)**而无需将任何数据发送给外部提供商**。
### 硬件要求
| 服务 | RAM |
| -------------------- | ------------ |
| Elasticsearch | 4 GB |
| Ollama (Gemma 4 E2B) | 8 GB |
| Kibana | 1 GB |
| Fleet Server | 1 GB |
| Agent | 1 GB |
| **总计** | **~15 GB** |
| 资源 | 要求 |
| -------- | ------------------------------ |
| 主机内存 | 推荐 16 GB |
| 磁盘 | 2 GB(用于模型下载) |
| GPU | 非必需(使用 CPU 推理) |
### 启用 LLM
```
# 在 .env 中
ENABLE_LLM=true
ES_MEM_LIMIT=4294967296 # 4 GB for Elasticsearch
LLM_MEM_LIMIT=8589934592 # 8 GB for Ollama
LLM_API_KEY= # optional: set to require auth on Ollama
```
像往常一样启动:
```
docker compose up -d
```
首次启动会下载模型(约 1.5 GB)。随后的启动将使用缓存。
### 会自动配置哪些内容
设置 `ENABLE_LLM=true` 后,设置容器将执行以下操作:
1. 启动 **Ollama 容器**并拉取模型
2. 创建指向 Ollama 兼容 OpenAI API 的 **Elasticsearch 推理 endpoint** (`local-llm`)
3. 激活**试用许可证**(GenAI connector 必需)
4. 创建 **Kibana GenAI connector**(`Local LLM (Ollama)`)
5. 将 **Kibana AI Assistant** 配置为使用本地模型
如果设置了 `LLM_API_KEY`,它将用于推理 endpoint 和 Kibana connector,并作为 `OLLAMA_API_KEY` 传递给 Ollama。
### 验证其是否正常工作
```
# Ollama 健康?
docker compose ps ollama
# Inference endpoint 存在?
curl -s --cacert ./ca.crt -u elastic:$ELASTIC_PASSWORD \
https:///_inference/completion/local-llm | jq
# 测试 completion
curl -s --cacert ./ca.crt -u elastic:$ELASTIC_PASSWORD \
-H "Content-Type: application/json" \
https:///_inference/completion/local-llm \
-d '{"input":"What is Elasticsearch?"}' | jq
# Kibana 中的 GenAI connector?
curl -s --cacert ./ca.crt -u elastic:$ELASTIC_PASSWORD \
-H "kbn-xsrf: true" \
https:///api/actions/connectors \
| jq '.[] | select(.connector_type_id == ".gen-ai")'
# 试用许可证状态
curl -s --cacert ./ca.crt -u elastic:$ELASTIC_PASSWORD \
https:///_license | jq '.license | {type, status, expiry_date}'
```
### 将 LLM 暴露给其他设备
为了让网络上的其他设备调用 LLM(例如作为兼容 OpenAI API 的直接替代品),还需设置:
```
ENABLE_LLM=true
ENABLE_LLM_INGRESS=true
LLM_DOMAIN_NAME=llm.example.com
```
将 `LLM_DOMAIN_NAME` 添加到您的 DNS 或 `/etc/hosts` 中(自签名模式)。
| 模式 | URL |
| ------------- | ----------------------------- |
| Self-signed | `https://` |
| Let's Encrypt | `https://` |
| Direct | `https://:11434` |
```
curl https:///v1/chat/completions \
--cacert ./ca.crt \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $LLM_API_KEY" \
-d '{"model":"gemma4:e2b","messages":[{"role":"user","content":"Hello!"}]}'
```
如果未设置 `LLM_API_KEY`,请省略 `Authorization` header。
## 项目结构
采用模块化的 Docker Compose 文件以提高可维护性:
| 文件 | 用途 |
| -------------------------------------- | ---------------------------------------------- |
| `docker-compose.yaml` | 主编排器(包含所有模块) |
| `docker-compose.1.traefik.yaml` | 反向代理和 TLS 终止 |
| `docker-compose.2.setup.yaml` | 证书生成和初始设置 |
| `docker-compose.3.elasticsearch.yaml` | 搜索和分析引擎 |
| `docker-compose.4.kibana.yaml` | Web UI 和 Fleet 配置 |
| `docker-compose.5.fleet.yaml` | Elastic Agent 管理 |
| `docker-compose.6.agent.yaml` | SIEM 代理和 syslog 摄取 |
| `docker-compose.7.ollama.yaml` | 通过 Ollama 实现的本地 LLM(可选,受 profile 控制) |
配置文件位于 `configurations/`:
```
configurations/
├── elastic/
│ ├── fleet-configuration.yaml # Fleet Server & Agent policies
│ └── env_files/
│ ├── .env.selfsigned
│ ├── .env.letsencrypt
│ └── .env.direct
└── traefik/
├── traefik-selfsigned.yml # Static config: self-signed
├── traefik-selfsigned-dynamic.yaml # TLS certs & backend transports
├── traefik-letsencrypt.yml # Static config: Let's Encrypt
├── traefik-letsencrypt-dynamic.yaml # Backend transports
├── traefik-direct.yml # Static config: direct
└── traefik-direct-dynamic.yaml # TLS, routers & backend transports
```
## 核心概念
对 SIEM、网络或 Docker 感到陌生?以下是快速入门介绍。
### 什么是 TLS/SSL?
TLS(传输层安全性)会加密您的浏览器/代理与 Elastic Stack 之间的数据。如果不加密,网络上的任何人都可以读取密码和数据。Elastic at Home 对每个服务都使用 HTTPS。证书既可以是自签名的(Elasticsearch 的内置 CA),也可以是公开受信任的。
### 什么是证书颁发机构(CA)?
CA 是受信任的证书签名实体。浏览器信任 Let's Encrypt,因为它存在于所有主流信任库中;它们不信任您的自签名 CA,因为您不在它们的信任库中。在自签名模式下,您要么需要点击跳过警告,要么将 `ca.crt` 分发给您的设备。
### 什么是反向代理?
反向代理位于互联网和您的容器之间,将每个传入的请求路由到正确的服务。它提供了一个统一的入口点和处理 TLS 的位置。Elastic at Home 使用 [Traefik](https://traefik.io/),通过主机名(`kibana.example.com`)或端口(`:5601`)进行路由。
### Layer 4 与 Layer 7 路由
| 层级 | 协议 | 用例 | 示例 |
| ----------- | ----------- | ----------------------- | --------------------------- |
| **Layer 4** | TCP/UDP | 原始连接,syslog | 路由器到 Elastic Agent |
| **Layer 7** | HTTP/HTTPS | Web 流量,API | 浏览器到 Kibana |
Syslog 不是 HTTP,因此它使用 Layer 4。Web 服务使用带有主机名规则的 Layer 7。
### 什么是 syslog?
一种用于通过网络发送日志的标准协议。几乎所有路由器、防火墙和交换机都支持它。
- **UDP (514)**:速度快,无交付保证。适用于大量日志。
- **TCP (514)**:交付可靠。更适合安全事件。
Elastic Agent 通过 Traefik 接收 syslog 并将其索引到 Elasticsearch 中。
### 什么是 Fleet?
Fleet 是 Elastic 的集中式代理管理平台。您可以在 Kibana 中定义策略,代理会自动拉取这些策略。关键术语:
- **Agent Policy**:分配给代理的集成 bundle
- **Integration**:一个数据收集模块(System、Syslog、Network 等)
- **Enrolment**:将代理连接到 Fleet Server 的握手过程
### Docker 网络
容器运行在一个名为 `elastic` 的隔离网络中。在内部,它们通过名称(`es01`、`kibana`)互相访问。在外部,Traefik 将端口 443 和 514 发布到主机。
## 故障排除
### 容器显示为“unhealthy”
```
# 查看失败服务的日志
docker compose logs
# 检查 health check 详情
docker inspect --format='{{json .State.Health}}' elastic-at-home--1
```
**常见原因:** 内存不足(检查 `docker stats`)、证书生成仍在进行中、Elasticsearch 尚未就绪(Kibana/Fleet 依赖于它)。
### “Certificate signed by unknown authority”(证书由未知机构签名)
**自签名 / 直接访问模式:**
```
# 提取 CA
docker cp $(docker compose ps -q setup):/certs/ca/ca.crt ./ca.crt
```
将 `ca.crt` 分发给代理并使其受信任。对于浏览器,请将其添加到系统信任库中或直接点击跳过警告。
**Let's Encrypt 模式:**
- 确认 DNS 记录指向您的主机 IP
- `docker compose logs traefik` 并查找 ACME 错误
- 验证 `CF_DNS_API_TOKEN` 是否具有正确的权限
### Fleet 注册失败
```
docker compose logs fleet-server
docker compose logs agent
```
**常见原因:** Fleet Server 尚未变绿(处于健康状态)、`FLEET_URL` 错误、CA 信任问题(见上文)。
### Syslog 未到达
1. 端口 514 可访问吗?根据协议进行测试:
- **TCP:** `nc -zv 514`
- **UDP:** `nc -u -zv 514`(UDP 没有握手过程,因此正常退出只能确认套接字已打开;请通过观察代理日志或使用发送方的测试工具来确认是否收到)
2. 代理日志显示 syslog 输入处于活动状态吗?
3. 发送方是否指向了正确的 IP、端口和协议?
4. 仅限 TCP:您的源子网是否在 `ALLOWED_SYSLOG_IPS` 中?
### 内存 / 资源问题
- 在 `.env` 中调整限制(`KB_MEM_LIMIT`、`ES_MEM_LIMIT` 等)
- 确认 `sysctl vm.max_map_count` 是否为 262144+
- `docker stats`:查看是谁在消耗 RAM
**建议的最低配置:**
| 服务 | RAM |
| ------------- | ------ |
| Elasticsearch | 2 GB |
| Kibana | 1 GB |
| Fleet Server | 1 GB |
| Agent | 512 MB |
## 常见问题
### 我可以在 Raspberry Pi 上运行 Elastic Security 吗?
可以。配备 16 GB RAM 和 NVMe SSD 的 Raspberry Pi 5 可以轻松运行完整的 stack(Elasticsearch、Kibana、Fleet Server、Agent、Traefik),并且还有空间留给可选的本地 LLM。内存较低的板子(8 GB)可以在没有 LLM 的情况下运行 SIEM。
### 这是免费的吗?
核心 stack(SIEM、EDR、syslog 摄取、仪表板、Fleet)可以永久在免费的 Basic 许可证上运行。机器学习异常检测、Kibana AI Assistant、Watcher 和文档级安全性需要 Platinum/Enterprise 许可证或内置的 30 天试用版。
### 我需要将我的 stack 暴露在互联网上吗?
不需要。Let's Encrypt 的 DNS-01 验证通过对您的 DNS 提供商进行 API 调用来证明域名所有权;不需要开放入站端口。自签名和直接访问模式则完全不需要互联网。
### 这与付费的家庭安全产品有什么不同?
您拥有数据、检测规则和代理的所有权。您可以编写自定义规则,集成任何支持 syslog 的设备,关联网络和终端遥测数据,并使用与企业级 SOC 分析师相同的工具。
### 我可以将其用于生产环境吗?
Elastic at Home 针对单主机上的家庭和实验室部署进行了优化。如用于生产环境,请遵循 Elastic 的[多节点生产指南](https://www.elastic.co/docs/deploy-manage/deploy/self-managed/install-elasticsearch-docker-prod),并搭配受支持的许可证。
## 许可证
参见 [LICENSE](LICENSE)。
## 贡献
欢迎在 [github.com/jamesagarside/elastic-at-home](https://github.com/jamesagarside/elastic-at-home) 提交 issue 和 PR。
点击展开 ASCII 流程图
``` ┌─────────────────────────────────────────────────────────────────┐ │ CLOUDFLARE DNS │ │ A Records: elastic.*, kibana.*, fleet.* →标签:AI风险缓解, Docker Compose, Elastic Stack, MIT许可证, Raspberry Pi, 内存执行, 子域名变形, 安全运营中心, 流量重放, 版权保护, 网络映射