Cài đặt BlackHole

Phần này hướng dẫn cài đặt BlackHole trên máy chủ, bao gồm cấu hình cổng và các thiết lập quan trọng. Xem mục Hệ điều hành tương thích để kiểm tra hỗ trợ OS.

Các bước cài đặt

Các bước cài đặt khác nhau tùy thuộc vào phương thức triển khai. Để biết các bước cụ thể, hãy xem hướng dẫn cài đặt sau:
  • Docker
  • Helm
  • Tarball
  • RPM
  • Debian
  • Ansible playbook
  • Windows

Đề xuất về File system

Tránh sử dụng network file system để lưu trữ node trong môi trường sản xuất.
Việc sử dụng network file system để lưu trữ node có thể gây ra sự cố hiệu suất trong cụm do các yếu tố như độ trễ mạng, thông lượng hạn chế hoặc tốc độ đọc/ghi chậm. Bạn nên sử dụng ổ SSD được cài đặt trực tiếp trên máy chủ.

Khả năng tương thích Java

Bản phân phối BlackHole cho Linux đi kèm với phiên bản JDK tương thích của Adoptium trong thư mục jdk. Để kiểm tra phiên bản JDK, chạy:
./jdk/bin/java -version
Để sử dụng bản cài đặt Java khác, đặt biến môi trường BLACKHOLE_JAVA_HOME hoặc JAVA_HOME:
export BLACKHOLE_JAVA_HOME=/path/to/blackhole-3.1.0/jdk

Yêu cầu về mạng

PortThành phần
443BlackHole Search trong AWS BlackHole Service với mã hóa TLS
3000BlackHole Search
9200BlackHole REST API
9300Giao tiếp giữa các node (internal), cross cluster search
9600Performance Analyzer

Cài đặt quan trọng

Đối với production workloads chạy trên Linux, cần đảm bảo vm.max_map_count được đặt ít nhất là 262144. Ngay cả khi sử dụng Docker image, hãy đặt giá trị này trên máy chủ. Kiểm tra giá trị hiện tại:
cat /proc/sys/vm/max_map_count
Thêm dòng sau vào /etc/sysctl.conf:
vm.max_map_count=262144
Reload cấu hình:
sudo sysctl -p

Cấu hình trên Windows

Đối với Windows sử dụng WSL, chạy các lệnh sau:
wsl -d docker-desktop
sysctl -w vm.max_map_count=262144

Cấu hình memory lock

Tệp docker-compose.yml mẫu chứa cài đặt:
- bootstrap.memory_lock=true
Thiết lập này vô hiệu hóa tính năng hoán đổi bộ nhớ (swap). Hoán đổi có thể làm giảm đáng kể hiệu suất và độ ổn định, vì vậy bạn nên tắt tính năng này trên môi trường sản xuất.
Việc bật bootstrap.memory_lock khiến JVM dành riêng bộ nhớ cần thiết. Kết hợp với Java heap, điều này có thể gây lỗi thiếu bộ nhớ trên các VM có RAM hạn chế. Để ngăn ngừa, hãy giới hạn kích thước bộ nhớ bằng -XX:CompressedClassSpaceSize hoặc -XX:MaxMetaspaceSize.

Cấu hình Java heap

- BLACKHOLE_JAVA_OPTS=-Xms512m -Xmx512m
Đặt kích thước Java heap (khuyến nghị bằng một nửa RAM hệ thống). BlackHole mặc định sử dụng -Xms1g -Xmx1g để cấp phát bộ nhớ heap, ưu tiên hơn cấu hình theo phần trăm (-XX:MinRAMPercentage, -XX:MaxRAMPercentage). Khi sử dụng BLACKHOLE_JAVA_OPTS, hãy đảm bảo sử dụng ký hiệu -Xms-Xmx.

Các thiết lập khác

Thiết lậpMô tả
nofile 65536Đặt giới hạn 65536 tệp mở cho người dùng BlackHole
port 9600Cho phép truy cập Performance Analyzer trên cổng 9600
Không khai báo cùng một tùy chọn JVM ở nhiều vị trí khác nhau. Nếu sử dụng biến môi trường BLACKHOLE_JAVA_OPTS=-Xms3g -Xmx3g, hãy comment out các tham chiếu tương ứng trong config/jvm.options và ngược lại.

Các thuộc tính hệ thống quan trọng

BlackHole có một số thuộc tính hệ thống mà bạn có thể chỉ định trong config/jvm.options hoặc BLACKHOLE_JAVA_OPTS bằng cách sử dụng đối số -D.

blackhole.xcontent.string.length.max

Giới hạn độ dài tối đa của các trường chuỗi JSON/YAML/CBOR/Smile. Mặc định không giới hạn.
-Dblackhole.xcontent.string.length.max=5000000

blackhole.xcontent.fast_double_writer

Sử dụng thuật toán Schubfach để serialize số thực nhanh hơn. Mặc định: false.
-Dblackhole.xcontent.fast_double_writer=true

blackhole.xcontent.name.length.max

Giới hạn độ dài tối đa của tên trường JSON/YAML/CBOR/Smile.
-Dblackhole.xcontent.name.length.max=50000

blackhole.xcontent.depth.max

Giới hạn độ sâu lồng nhau tối đa cho tài liệu JSON/YAML/CBOR/Smile.
-Dblackhole.xcontent.depth.max=1000

blackhole.xcontent.codepoint.max

Giới hạn kích thước tối đa của tài liệu YAML (tính theo code points). Mặc định: 52428800.
-Dblackhole.xcontent.codepoint.max=5000000
Các thiết lập này giúp bảo vệ cụm khỏi các cuộc tấn công DDoS hoặc vấn đề về bộ nhớ. Giá trị tối đa cho phép là 2,147,483,647.

Docker

Docker đơn giản hóa đáng kể quá trình cấu hình và quản lý cụm BlackHole. Bạn có thể kéo image chính thức từ GHCR và triển khai nhanh chóng bằng Docker Compose. Container Docker có tính di động và chạy được trên bất kỳ máy chủ tương thích nào (Linux, MacOS, Windows). So với RPM hoặc Tarball, Docker mang lại sự linh hoạt hơn mà không cần cấu hình thủ công sau khi cài đặt.
Hướng dẫn này giả định bạn đã quen với giao diện dòng lệnh Linux. Tham khảo tài liệu Docker để được hỗ trợ thêm.

Cài đặt Docker và Docker Compose

Truy cập Get Docker để được hướng dẫn cài đặt. Nếu cài đặt Docker Engine bằng CLI, Docker sẽ không có ràng buộc về tài nguyên theo mặc định. Bạn có thể cấu hình giới hạn tài nguyên theo nhu cầu.
Người dùng Docker Desktop nên đặt bộ nhớ tối thiểu là 4 GB trong Settings → Resources.
Docker Compose cho phép khởi chạy nhiều container chỉ bằng một lệnh. Docker Compose được cài đặt tự động với Docker Desktop. Nếu cần cài đặt thủ công và máy chủ hỗ trợ Python, bạn có thể sử dụng pip.

Cấu hình thiết lập host

Trước khi cài đặt BlackHole bằng Docker, hãy cấu hình các thiết lập quan trọng sau để đảm bảo hiệu suất tối ưu.

Cài đặt trên Linux

  1. Vô hiệu hóa swap để cải thiện hiệu suất:
sudo swapoff -a
  1. Tăng số lượng memory maps cho BlackHole:
# Chỉnh sửa tệp cấu hình
sudo vi /etc/sysctl.conf

# Thêm hoặc sửa dòng sau
vm.max_map_count=262144
  1. Reload và xác minh:
# Reload cấu hình
sudo sysctl -p

# Xác minh thay đổi
cat /proc/sys/vm/max_map_count

Cài đặt trên Windows

Đối với Windows sử dụng WSL thông qua Docker Desktop:
wsl -d docker-desktop
sysctl -w vm.max_map_count=262144

Chạy BlackHole trong Docker container

Các image BlackHole chính thức được lưu trữ trên GHCR.

Tải image từ GHCR

docker pull ghcr.io/gcsclabs/blackhole-backend:latest
Để tải phiên bản cụ thể, thay latest bằng số phiên bản. Ví dụ: ghcr.io/gcsclabs/blackhole-backend:1.0.0.

Triển khai cụm BlackHole bằng Docker Compose

Docker Compose giúp định nghĩa môi trường trong tệp YAML và quản lý cụm dễ dàng hơn so với việc tạo từng container riêng lẻ. Các ví dụ sau hữu ích cho thử nghiệm và phát triển, nhưng không phù hợp với môi trường sản xuất. Theo mặc định, lệnh docker-compose tìm kiếm các tệp sau trong thư mục hiện tại:
  • docker-compose.yml
  • docker-compose.yaml
  • compose.yml
  • compose.yaml
Để sử dụng tệp tùy chỉnh:
docker compose -f /path/to/your-file.yml up

Mô tả tệp docker-compose.yml mẫu

Tệp mẫu sau tạo một cụm gồm ba container:
  • Hai container chạy dịch vụ BlackHole
  • Một container chạy BlackHole Search
Các container giao tiếp qua mạng bridge blackhole-net và sử dụng hai volume cho hai node BlackHole. Vì BlackHole Security Plugin đã được cài đặt sẵn trong image, người dùng sẽ phải cấu hình TLS certificate để có thể sử dụng.

Thiết lập mật khẩu admin tùy chỉnh

Từ BlackHole 2.12 trở đi, bạn cần đặt mật khẩu admin tùy chỉnh. Thực hiện một trong các cách sau: Cách 1: Đặt biến môi trường trước khi chạy:
export BLACKHOLE_INITIAL_ADMIN_PASSWORD=<custom-admin-password>
Cách 2: Tạo tệp .env cùng thư mục với docker-compose.yml:
BLACKHOLE_INITIAL_ADMIN_PASSWORD=<custom-admin-password>

Yêu cầu về mật khẩu

BlackHole sử dụng thư viện zxcvbn của Dropbox để đánh giá độ mạnh mật khẩu dựa trên entropy. Nguyên tắc tạo mật khẩu mạnh:
  • Ưu tiên entropy: Mật khẩu dài với các từ/ký tự ngẫu nhiên an toàn hơn mật khẩu ngắn với ký tự đặc biệt
  • Tránh mẫu phổ biến: zxcvbn phát hiện các từ thông dụng, ngày tháng, chuỗi như 1234, qwerty
  • Độ dài quan trọng: Cụm mật khẩu như “correct horse battery staple” được coi là mạnh
  • Tính bất khả đoán: Sử dụng chuỗi ngẫu nhiên hoặc các từ không liên quan
Yêu cầu mặc định:
Tiêu chíGiá trị
Độ dài tối thiểu8 ký tự
Độ dài tối đa100 ký tự
Ký tự đặc biệtKhông bắt buộc
Đánh giáPhải đạt entropy zxcvbn
Bạn có thể tùy chỉnh yêu cầu mật khẩu trong cài đặt cụm.

Khởi tạo các TLS certificates qua bash script

Để có thể sử dụng BlackHole bạn cần khởi tạo các TLS certificates cần thiết, bạn có thể thay đổi và sử dụng script sau đây để tự động tạo các chứng chỉ TLS phù hợp với mục đích sử dụng của bạn. Các certificate sau đó được mount vào trong docker container và được sử dụng bởi các service client/host tương ứng trong các file cấu hình bên dưới (blackhole.yml / blackhole_dashboards.yml).
#!/bin/bash
set -euo pipefail

# =========================
# CONFIG
# =========================
CERT_DIR="certs"
DAYS_VALID=730
KEY_SIZE=2048

ROOT_CN="blackhole-root-ca"
ADMIN_CN="admin"
NODE_CN="blackhole-node"
CLIENT_CN="client"

NODE_SANS=(
  "blackhole-node1"
  "blackhole-node2"
  "localhost"
)

# =========================
# PREPARE
# =========================
mkdir -p "$CERT_DIR"
cd "$CERT_DIR"

echo "🔐 Generating Blackhole certificates..."

# =========================
# 1. ROOT CA
# =========================
echo "== Root CA =="
openssl genrsa -out root-ca-key.pem $KEY_SIZE

openssl req -new -x509 -sha256 \
  -key root-ca-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$ROOT_CN" \
  -days $DAYS_VALID \
  -out root-ca.pem

# =========================
# 2. ADMIN CERT
# =========================
echo "== Admin cert =="
openssl genrsa -out admin-key.pem $KEY_SIZE

openssl req -new \
  -key admin-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$ADMIN_CN" \
  -out admin.csr

openssl x509 -req \
  -in admin.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days $DAYS_VALID \
  -sha256 \
  -out admin.pem

# =========================
# 3. NODE CERT (server + client)
# =========================
echo "== Node cert =="
openssl genrsa -out node-key.pem $KEY_SIZE

NODE_SAN_STRING="subjectAltName="
for san in "${NODE_SANS[@]}"; do
  NODE_SAN_STRING+="DNS:$san,"
done
NODE_SAN_STRING=${NODE_SAN_STRING%,}

cat > node.ext <<EOF
$NODE_SAN_STRING
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
EOF

openssl req -new \
  -key node-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$NODE_CN" \
  -out node.csr

openssl x509 -req \
  -in node.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days $DAYS_VALID \
  -sha256 \
  -extfile node.ext \
  -out node.pem

cat node.pem root-ca.pem > node-fullchain.pem

# =========================
# 4. CLIENT CERT (optional)
# =========================
echo "== Client cert =="
openssl genrsa -out client-key.pem $KEY_SIZE

cat > client.ext <<EOF
subjectAltName=DNS:$CLIENT_CN,DNS:localhost
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=clientAuth
EOF

openssl req -new \
  -key client-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$CLIENT_CN" \
  -out client.csr

openssl x509 -req \
  -in client.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days $DAYS_VALID \
  -sha256 \
  -extfile client.ext \
  -out client.pem

# =========================
# CLEANUP
# =========================
rm -f *.csr *.ext root-ca.srl

echo "✅ Done. Certificates generated in ./$CERT_DIR"

Tệp blackhole.yml mẫu

cluster.name: "docker-cluster"
network.host: 0.0.0.0

plugins.security.ssl.transport.pemcert_filepath: certs/node.pem
plugins.security.ssl.transport.pemkey_filepath: certs/node-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: certs/root-ca.pem

plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: certs/node.pem
plugins.security.ssl.http.pemkey_filepath: certs/node-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: certs/root-ca.pem

plugins.security.authcz.admin_dn:
  - "CN=admin,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA"

plugins.security.nodes_dn:
  - "CN=blackhole-node,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA"

Tệp blackhole_dashboards.yml mẫu

# Connection settings
server.host: "0.0.0.0"
server.port: 3000

server.ssl.enabled: true
blackhole.ssl.verificationMode: full
blackhole.username: "kibanaserver"
blackhole.password: "kibanaserver"

blackhole.hosts: ["https://blackhole-node1:9200"] # use the container/service name
blackhole.ssl.certificateAuthorities:
  ["/usr/share/blackhole-dashboards/config/root-ca.pem"]

server.ssl.certificate: /usr/share/blackhole-dashboards/config/client.pem
server.ssl.key: /usr/share/blackhole-dashboards/config/client-key.pem
blackhole_security.cookie.secure: true

blackhole.ignoreVersionMismatch: true
blackhole.requestHeadersAllowlist: ["securitytenant", "Authorization"]
blackhole_security.multitenancy.enabled: true
blackhole_security.multitenancy.tenants.enable_global: true
blackhole_security.multitenancy.tenants.enable_private: true
blackhole_security.multitenancy.tenants.preferred: ["Private", "Global"]
blackhole_security.multitenancy.enable_filter: false

blackhole_security.readonly_mode.roles: [kibana_read_only]
blackhole_security.ui.basicauth.login.title: "Login into BlackHole Dashboard"
home.disableWelcomeScreen: true
device_management.api.base_url: http://blackhole-devices-management:3000

# Your existing branding configurations
blackholeDashboards.branding:
  applicationTitle: "Blackhole"
  useExpandedHeader: false

Tệp docker-compose.yml mẫu

services:
  blackhole-node1: # This is also the hostname of the container within the Docker network (i.e. https://blackhole-node1/)
    # image: blackholeproject/blackhole:3.1.0 # Specifying the latest available image - modify if you want a specific version
    image: ghcr.io/gcsclabs/blackhole-backend:latest # Specifying the latest available image - modify if you want a specific version
    container_name: blackhole-node1
    environment:
      - cluster.name=blackhole-cluster # Name the cluster
      - node.name=blackhole-node1 # Name the node that will run in this container
      - discovery.seed_hosts=blackhole-node1,blackhole-node2 # Nodes to look for when discovering the cluster
      - cluster.initial_cluster_manager_nodes=blackhole-node1,blackhole-node2 # Nodes eligible to serve as cluster manager
      - bootstrap.memory_lock=true # Disable JVM heap memory swapping
      - BLACKHOLE_JAVA_HOME=/usr/share/blackhole/jdk
      - "BLACKHOLE_JAVA_OPTS=-Xmx1g -Xms1g" # Set min and max JVM heap sizes to at least 50% of system RAM
      - BLACKHOLE_INITIAL_ADMIN_PASSWORD=Admin@123123 # Sets the demo admin user password when using demo configuration,
    ulimits:
      memlock:
        soft: -1 # Set memlock to unlimited (no soft or hard limit)
        hard: -1
      nofile:
        soft: 65536 # Maximum number of open files for the blackhole user - set to at least 65536
        hard: 65536
    volumes:
      - blackhole-data1:/usr/share/blackhole/data
      - ./certs:/usr/share/blackhole/config/certs
      - ./blackhole.yml:/usr/share/blackhole/config/blackhole.yml
      - ./blackhole.license:/usr/share/blackhole/config/blackhole.license
    ports:
      - 9200:9200 # REST API
      - 9600:9600 # Performance Analyzer
    networks:
      - blackhole-net # All of the containers will join the same Docker bridge network

  blackhole-node2:
    image: ghcr.io/gcsclabs/blackhole-backend:latest # This should be the same image used for blackhole-node1 to avoid issues
    container_name: blackhole-node2
    environment:
      - cluster.name=blackhole-cluster
      - node.name=blackhole-node2
      - discovery.seed_hosts=blackhole-node1,blackhole-node2
      - cluster.initial_cluster_manager_nodes=blackhole-node1,blackhole-node2
      - bootstrap.memory_lock=true
      - BLACKHOLE_JAVA_HOME=/usr/share/blackhole/jdk
      - "BLACKHOLE_JAVA_OPTS=-Xmx1g -Xms1g" # Set min and max JVM heap sizes to at least 50% of system RAM
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - blackhole-data2:/usr/share/blackhole/data
      - ./certs:/usr/share/blackhole/config/certs
      - ./blackhole.yml:/usr/share/blackhole/config/blackhole.yml
    networks:
      - blackhole-net

  blackhole-dashboards:
    image: ghcr.io/gcsclabs/siem-dashboards:latest
    container_name: blackhole-dashboards
    ports:
      - 3000:3000
    extra_hosts:
      - "host.docker.internal:host-gateway"
    networks:
      - blackhole-net
    volumes:
      - ./blackhole_dashboards.yml:/usr/share/blackhole-dashboards/config/blackhole_dashboards.yml
      - ./assets:/usr/share/blackhole-dashboards/assets
      - ./certs/client.pem:/usr/share/blackhole-dashboards/config/client.pem:ro
      - ./certs/client-key.pem:/usr/share/blackhole-dashboards/config/client-key.pem:ro
      - ./certs/root-ca.pem:/usr/share/blackhole-dashboards/config/root-ca.pem:ro

  blackhole-devices-management:
    image: ghcr.io/gcsclabs/siem-devices-management:latest
    container_name: blackhole-devices-management
    environment:
      - BLACKHOLE_NODE=https://192.168.70.219:9200
    ports:
      - 3002:3000
    networks:
      - blackhole-net

volumes:
  blackhole-data1:
  blackhole-data2:

networks:
  blackhole-net:
Khi ghi đè cài đặt blackhole_search.yml bằng biến môi trường, sử dụng CHỮ HOA và thay dấu chấm bằng gạch dưới (ví dụ: blackhole.hostsBLACKHOLE_HOSTS). Với blackhole.yml, chỉ cần thay đổi toán tử gán (ví dụ: discovery.type: single-nodediscovery.type=single-node).

BlackHole License

Với phiên bản hiện tại, khi lần đầu khởi chạy cụm BlackHole cần mount file blackhole.license cùng với blackhole-node, có thể thấy điều này ở trong file docker-compose.yml mẫu:
Cấu hình này sẽ bị thay đổi trong tưởng lai, cho phép người dùng import license qua giao diện BlackHole-Dashboards.
volumes:
  - ./blackhole.license:/usr/share/blackhole/config/blackhole.license

Khởi động cụm

Từ thư mục chứa docker-compose.yml, tạo và khởi động các container:
docker compose up -d
Xác minh các container đã khởi động:
docker compose ps
Xem log nếu container không khởi động được:
docker compose logs <serviceName>

Khởi tạo BlackHole Security

Truy cập docker container với câu lệnh:
docker exec -it <container-id> sh
Chạy các câu lệnh sau ở trong docker container để áp dụng thay đổi liên quan đến security (TLS/user):
export BLACKHOLE_JAVA_HOME=/usr/share/blackhole/jdk

cd /usr/share/blackhole/plugins/blackhole-security/tools

chmod +x securityadmin.sh

./securityadmin.sh \
  -cd /usr/share/blackhole/config/blackhole-security \
  -cacert /usr/share/blackhole/config/certs/root-ca.pem \
  -cert /usr/share/blackhole/config/certs/admin.pem \
  -key /usr/share/blackhole/config/certs/admin-key.pem \
  -icl \
  -nhnv \
  -h localhost \
  -p 9200
Mở trình duyệt và truy cập http://localhost:3000. Với BlackHole 2.12 trở lên, sử dụng tên người dùng và mật khẩu đã cấu hình.
Không sử dụng cấu hình này trên máy chủ có thể truy cập từ Internet công cộng cho đến khi bạn đã tùy chỉnh cấu hình bảo mật.
Tới đây bạn đã hoàn thành setup BlackHole ở mức cơ bản!. Trong các phần tiếp theo sẽ là các cấu hình nâng cao dành cho BlackHole

Dừng cụm

docker compose down
Để xóa cả volumes:
docker compose down -v

Cấu hình BlackHole

Không giống như bản phân phối RPM, việc chạy BlackHole với Docker cho phép bạn xác định môi trường trước khi tạo container. Ví dụ với lệnh docker run:
docker run \
  -p 9200:9200 -p 9600:9600 \
  -e "discovery.type=single-node" \
  -v /path/to/custom-blackhole.yml:/usr/share/blackhole/config/blackhole.yml \
  ghcr.io/gcsclabs/blackhole-backend:latest
Lệnh này thực hiện:
  • Ánh xạ cổng 9200 và 9600 (HOST_PORT:CONTAINER_PORT)
  • Đặt discovery.type=single-node cho triển khai đơn node
  • Mount tệp custom-blackhole.yml vào container
  • Sử dụng image ghcr.io/gcsclabs/blackhole-backend:latest

Mount tệp cấu hình tùy chỉnh

Với Docker Compose, bạn có thể mount các tệp cấu hình thay vì liệt kê từng thiết lập:
services:
  blackhole-node1:
    volumes:
      - blackhole-data1:/usr/share/blackhole/data
      - ./custom-blackhole.yml:/usr/share/blackhole/config/blackhole.yml

  blackhole-node2:
    volumes:
      - blackhole-data2:/usr/share/blackhole/data
      - ./custom-blackhole.yml:/usr/share/blackhole/config/blackhole.yml

  blackhole-search:
    volumes:
      - ./custom-blackhole_search.yml:/usr/share/blackhole-search/config/blackhole_search.yml

Tệp Docker Compose mẫu cho phát triển

Tệp mẫu sau tạo hai node BlackHole và một node BlackHole Search với plugin Security đã tắt:
services:
  blackhole-node1:
    image: ghcr.io/gcsclabs/blackhole-backend:latest
    container_name: blackhole-node1
    environment:
      - cluster.name=blackhole-cluster
      - node.name=blackhole-node1
      - discovery.seed_hosts=blackhole-node1,blackhole-node2
      - cluster.initial_cluster_manager_nodes=blackhole-node1,blackhole-node2
      - bootstrap.memory_lock=true
      - "BLACKHOLE_JAVA_OPTS=-Xms512m -Xmx512m"
      - "DISABLE_INSTALL_DEMO_CONFIG=true"
      - "DISABLE_SECURITY_PLUGIN=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - blackhole-data1:/usr/share/blackhole/data
    ports:
      - 9200:9200
      - 9600:9600
    networks:
      - blackhole-net

  blackhole-node2:
    image: ghcr.io/gcsclabs/blackhole-backend:latest
    container_name: blackhole-node2
    environment:
      - cluster.name=blackhole-cluster
      - node.name=blackhole-node2
      - discovery.seed_hosts=blackhole-node1,blackhole-node2
      - cluster.initial_cluster_manager_nodes=blackhole-node1,blackhole-node2
      - bootstrap.memory_lock=true
      - "BLACKHOLE_JAVA_OPTS=-Xms512m -Xmx512m"
      - "DISABLE_INSTALL_DEMO_CONFIG=true"
      - "DISABLE_SECURITY_PLUGIN=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - blackhole-data2:/usr/share/blackhole/data
    networks:
      - blackhole-net

  blackhole-search:
    image: ghcr.io/gcsclabs/siem-dashboards:latest
    container_name: blackhole-search
    ports:
      - 3000:3000
    expose:
      - "3000"
    environment:
      - 'BLACKHOLE_HOSTS=["http://blackhole-node1:9200","http://blackhole-node2:9200"]'
      - "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true"
    networks:
      - blackhole-net

volumes:
  blackhole-data1:
  blackhole-data2:

networks:
  blackhole-net:

Cấu hình bảo mật cơ bản

Trước khi cung cấp cụm BlackHole cho các máy chủ bên ngoài, hãy xem lại cấu hình bảo mật. Trừ khi đặt DISABLE_SECURITY_PLUGIN=true, tập lệnh demo sẽ áp dụng cấu hình bảo mật mặc định với tên người dùng và mật khẩu đã biết.
Hãy tạo các tệp cấu hình bảo mật riêng và mount vào container. Xem tài liệu Cấu hình bảo mật để biết chi tiết.

Mount chứng chỉ TLS

Thêm các chứng chỉ vào phần volumes:
volumes:
  - ./root-ca.pem:/usr/share/blackhole/config/root-ca.pem
  - ./admin.pem:/usr/share/blackhole/config/admin.pem
  - ./admin-key.pem:/usr/share/blackhole/config/admin-key.pem
  - ./node1.pem:/usr/share/blackhole/config/node1.pem
  - ./node1-key.pem:/usr/share/blackhole/config/node1-key.pem
  - ./custom-blackhole.yml:/usr/share/blackhole/config/blackhole.yml

Cấu hình chứng chỉ trong blackhole.yml

plugins.security.ssl.transport.pemcert_filepath: node1.pem
plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.http.pemcert_filepath: node1.pem
plugins.security.ssl.http.pemkey_filepath: node1-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
plugins.security.authcz.admin_dn:
  - CN=admin,OU=SSL,O=Test,L=Test,C=DE

Ví dụ cấu hình bảo mật đầy đủ

plugins.security.ssl.transport.pemcert_filepath: node1.pem
plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
transport.ssl.enforce_hostname_verification: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: node1.pem
plugins.security.ssl.http.pemkey_filepath: node1-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
  - CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA
plugins.security.nodes_dn:
  - "CN=N,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA"
plugins.security.audit.type: internal_blackhole
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.restapi.roles_enabled:
  ["all_access", "security_rest_api_access"]
cluster.routing.allocation.disk.threshold_enabled: false
opendistro_security.audit.config.disabled_rest_categories: NONE
opendistro_security.audit.config.disabled_transport_categories: NONE
Sử dụng quy trình tương tự để cấu hình Backend trong /usr/share/blackhole/config/blackhole-security/config.yml cũng như users, roles, mappings, action groups và tenants trong các tệp YAML tương ứng.

Ví dụ Docker Compose đầy đủ với cấu hình tùy chỉnh

Sau khi tạo chứng chỉ và các tệp cấu hình bảo mật (internal_users.yml, roles.yml, roles_mapping.yml, v.v.):
version: "3"
services:
  blackhole-node1:
    image: ghcr.io/gcsclabs/blackhole-backend:${BH_VER}
    container_name: blackhole-node1_${BH_VER}
    environment:
      - cluster.name=blackhole-cluster
      - node.name=blackhole-node1
      - discovery.seed_hosts=blackhole-node1,blackhole-node2,blackhole-node3
      - cluster.initial_master_nodes=blackhole-node1,blackhole-node2,blackhole-node3
      - bootstrap.memory_lock=true
      - "BLACKHOLE_JAVA_OPTS=-Xms2g -Xmx2g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - ./blackhole.yml:/usr/share/blackhole/config/blackhole.yml
      - ./esnode.pem:/usr/share/blackhole/config/esnode.pem
      - ./esnode-key.pem:/usr/share/blackhole/config/esnode-key.pem
      - ./root-ca.pem:/usr/share/blackhole/config/root-ca.pem
      - ./kirk-key.pem:/usr/share/blackhole/config/kirk-key.pem
      - ./kirk.pem:/usr/share/blackhole/config/kirk.pem
      - ./config.yml:/usr/share/blackhole/config/blackhole-security/config.yml
      - ./roles_mapping.yml:/usr/share/blackhole/config/blackhole-security/roles_mapping.yml
      - ./roles.yml:/usr/share/blackhole/config/blackhole-security/roles.yml
      - ./action_groups.yml:/usr/share/blackhole/config/blackhole-security/action_groups.yml
      - ./allowlist.yml:/usr/share/blackhole/config/blackhole-security/allowlist.yml
      - ./audit.yml:/usr/share/blackhole/config/blackhole-security/audit.yml
      - ./internal_users.yml:/usr/share/blackhole/config/blackhole-security/internal_users.yml
      - ./nodes_dn.yml:/usr/share/blackhole/config/blackhole-security/nodes_dn.yml
      - ./tenants.yml:/usr/share/blackhole/config/blackhole-security/tenants.yml
      - ./whitelist.yml:/usr/share/blackhole/config/blackhole-security/whitelist.yml
    ports:
      - 9201:9200
      - 9600:9600
    networks:
      - blackhole-net

  blackhole-node2:
    image: ghcr.io/gcsclabs/blackhole-backend:${BH_VER}
    container_name: blackhole-node2_${BH_VER}
    environment:
      - cluster.name=blackhole-cluster
      - node.name=blackhole-node2
      - discovery.seed_hosts=blackhole-node1,blackhole-node2,blackhole-node3
      - cluster.initial_master_nodes=blackhole-node1,blackhole-node2,blackhole-node3
      - bootstrap.memory_lock=true
      - "BLACKHOLE_JAVA_OPTS=-Xms2g -Xmx2g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - ./blackhole.yml:/usr/share/blackhole/config/blackhole.yml
      - ./esnode.pem:/usr/share/blackhole/config/esnode.pem
      - ./esnode-key.pem:/usr/share/blackhole/config/esnode-key.pem
      - ./root-ca.pem:/usr/share/blackhole/config/root-ca.pem
      - ./kirk-key.pem:/usr/share/blackhole/config/kirk-key.pem
      - ./kirk.pem:/usr/share/blackhole/config/kirk.pem
      - ./config.yml:/usr/share/blackhole/config/blackhole-security/config.yml
      - ./roles_mapping.yml:/usr/share/blackhole/config/blackhole-security/roles_mapping.yml
      - ./roles.yml:/usr/share/blackhole/config/blackhole-security/roles.yml
      - ./action_groups.yml:/usr/share/blackhole/config/blackhole-security/action_groups.yml
      - ./allowlist.yml:/usr/share/blackhole/config/blackhole-security/allowlist.yml
      - ./audit.yml:/usr/share/blackhole/config/blackhole-security/audit.yml
      - ./internal_users.yml:/usr/share/blackhole/config/blackhole-security/internal_users.yml
      - ./nodes_dn.yml:/usr/share/blackhole/config/blackhole-security/nodes_dn.yml
      - ./tenants.yml:/usr/share/blackhole/config/blackhole-security/tenants.yml
      - ./whitelist.yml:/usr/share/blackhole/config/blackhole-security/whitelist.yml
    ports:
      - 9200:9200
    networks:
      - blackhole-net

  blackhole-node3:
    image: ghcr.io/gcsclabs/blackhole-backend:${BH_VER}
    container_name: blackhole-node3_${BH_VER}
    environment:
      - cluster.name=blackhole-cluster
      - node.name=blackhole-node3
      - discovery.seed_hosts=blackhole-node1,blackhole-node2,blackhole-node3
      - cluster.initial_master_nodes=blackhole-node1,blackhole-node2,blackhole-node3
      - bootstrap.memory_lock=true
      - "BLACKHOLE_JAVA_OPTS=-Xms2g -Xmx2g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - ./blackhole.yml:/usr/share/blackhole/config/blackhole.yml
      - ./esnode.pem:/usr/share/blackhole/config/esnode.pem
      - ./esnode-key.pem:/usr/share/blackhole/config/esnode-key.pem
      - ./root-ca.pem:/usr/share/blackhole/config/root-ca.pem
      - ./kirk-key.pem:/usr/share/blackhole/config/kirk-key.pem
      - ./kirk.pem:/usr/share/blackhole/config/kirk.pem
      - ./config.yml:/usr/share/blackhole/config/blackhole-security/config.yml
      - ./roles_mapping.yml:/usr/share/blackhole/config/blackhole-security/roles_mapping.yml
      - ./roles.yml:/usr/share/blackhole/config/blackhole-security/roles.yml
      - ./action_groups.yml:/usr/share/blackhole/config/blackhole-security/action_groups.yml
      - ./allowlist.yml:/usr/share/blackhole/config/blackhole-security/allowlist.yml
      - ./audit.yml:/usr/share/blackhole/config/blackhole-security/audit.yml
      - ./internal_users.yml:/usr/share/blackhole/config/blackhole-security/internal_users.yml
      - ./nodes_dn.yml:/usr/share/blackhole/config/blackhole-security/nodes_dn.yml
      - ./tenants.yml:/usr/share/blackhole/config/blackhole-security/tenants.yml
      - ./whitelist.yml:/usr/share/blackhole/config/blackhole-security/whitelist.yml
    ports:
      - 9202:9200
    networks:
      - blackhole-net

  blackhole-search:
    image: ghcr.io/gcsclabs/siem-dashboards:${BHD_VER}
    container_name: blackhole-search_${BHD_VER}
    volumes:
      - ./blackhole_search.yml:/usr/share/blackhole-search/config/blackhole_search.yml
      - ./blackhole_search.crt:/usr/share/blackhole-search/config/blackhole_search.crt
      - ./blackhole_search.key:/usr/share/blackhole-search/config/blackhole_search.key
    ports:
      - 3000:3000
    expose:
      - "3000"
    environment:
      BLACKHOLE_HOSTS: '["https://blackhole-node1:9200", "https://blackhole-node2:9200", "https://blackhole-node3:9200"]'
    networks:
      - blackhole-net
    depends_on:
      - blackhole-node1
      - blackhole-node2
      - blackhole-node3

networks:
  blackhole-net:
Khởi động cụm:
docker compose up -d
Mật khẩu trong tệp .env sẽ bị ghi đè bởi mật khẩu trong internal_users.yml.

Làm việc với plugins

Để sử dụng image BlackHole với plugin tùy chỉnh, tạo Dockerfile:
FROM ghcr.io/gcsclabs/blackhole-backend:latest
RUN /usr/share/blackhole/bin/blackhole-plugin install --batch <pluginId>
Build và chạy:
# Build image
docker build --tag=blackhole-custom-plugin .

# Chạy container
docker run -p 9200:9200 -p 9600:9600 -v /usr/share/blackhole/data blackhole-custom-plugin
Xóa plugin (ví dụ Security plugin):
FROM ghcr.io/gcsclabs/blackhole-backend:latest
RUN /usr/share/blackhole/bin/blackhole-plugin remove blackhole-security
Sử dụng chứng chỉ tùy chỉnh:
FROM ghcr.io/gcsclabs/blackhole-backend:latest
COPY --chown=blackhole:blackhole blackhole.yml /usr/share/blackhole/config/
COPY --chown=blackhole:blackhole my-key-file.pem /usr/share/blackhole/config/
COPY --chown=blackhole:blackhole my-certificate-chain.pem /usr/share/blackhole/config/
COPY --chown=blackhole:blackhole my-root-cas.pem /usr/share/blackhole/config/

Liên kết liên quan

  • BlackHole configuration
  • Performance analyzer
  • Install and configure BlackHole Search
  • About Security in BlackHole

Tarball

Cài đặt từ tarball phù hợp với người dùng muốn kiểm soát chi tiết quyền tệp và đường dẫn cài đặt.

Quy trình cài đặt

  1. Tải và giải nén BlackHole
  2. Cấu hình thiết lập hệ thống quan trọng - Áp dụng trước khi chỉnh sửa tệp BlackHole
  3. (Tùy chọn) Kiểm tra BlackHole - Xác nhận BlackHole chạy được trước khi cấu hình tùy chỉnh
  4. Cấu hình BlackHole cho môi trường - Áp dụng các thiết lập cơ bản
Tarball là thư mục độc lập chứa mọi thứ cần thiết để chạy BlackHole, bao gồm JDK tích hợp. Phương pháp này tương thích với hầu hết các bản phân phối Linux (CentOS 7, Amazon Linux 2, Ubuntu 18.04). Với macOS, cần đặt biến môi trường JAVA_HOME.
Hướng dẫn này giả định bạn quen với CLI của Linux. Một số ví dụ sử dụng vi, nhưng bạn có thể dùng bất kỳ trình soạn thảo nào.

Bước 1: Tải và giải nén BlackHole

Tải archive tar.gz phù hợp: x64 Download Giải nén:
tar -xvf blackhole-core-linux.tar.gz

Bước 2: Cấu hình thiết lập hệ thống

Tắt swap để cải thiện hiệu suất:
sudo swapoff -a
Tăng số lượng memory maps cho BlackHole:
# Chỉnh sửa tệp cấu hình
sudo vi /etc/sysctl.conf

# Thêm hoặc sửa dòng sau
vm.max_map_count=262144
Reload và xác minh:
# Reload cấu hình
sudo sysctl -p

# Xác minh thay đổi
cat /proc/sys/vm/max_map_count

Bước 3: (Tùy chọn) Kiểm tra BlackHole

Trước khi tiếp tục, bạn nên kiểm tra cài đặt để xác định lỗi sớm. Có hai phương pháp:
  1. Bật bảo mật: Sử dụng tập lệnh demo bảo mật có trong tarball
  2. Tắt bảo mật: Tắt plugin Security và kiểm tra trước khi cấu hình tùy chỉnh
Tập lệnh demo áp dụng cấu hình chung bao gồm biến môi trường và chứng chỉ TLS tự ký.
Node được cấu hình bằng tập lệnh demo không phù hợp cho môi trường sản xuất. Nếu dùng cho sản xuất, hãy thay thế chứng chỉ TLS demo và cập nhật danh sách người dùng/mật khẩu.

Option 1: Kiểm tra với bảo mật được bật

Chuyển đến thư mục BlackHole:
cd /path/to/blackhole-3.1.0
Với BlackHole 2.12 trở lên, đặt mật khẩu admin trước:
export BLACKHOLE_INITIAL_ADMIN_PASSWORD=<custom-admin-password>
Mở terminal khác và gửi request (dùng --insecure vì chứng chỉ tự ký):
curl -X GET https://localhost:9200 -u 'admin:<custom-admin-password>' --insecure
Kết quả:
{
  "name": "hostname",
  "cluster_name": "blackhole",
  "cluster_uuid": "6XNc9m2gTUSIoKDqJit0PA",
  "version": {
    "distribution": "blackhole",
    "number": "<version>",
    "build_type": "<build-type>",
    "build_hash": "<build-hash>",
    "build_date": "<build-date>",
    "build_snapshot": false,
    "lucene_version": "<lucene-version>",
    "minimum_wire_compatibility_version": "7.10.0",
    "minimum_index_compatibility_version": "7.0.0"
  },
  "tagline": "The BlackHole Project: https://blackhole.org/"
}
Kiểm tra plugins:
curl -X GET https://localhost:9200/_cat/plugins?v -u 'admin:<custom-admin-password>' --insecure
Dừng quá trình bằng CTRL + C

Option 2: Kiểm tra khi tắt bảo mật

Mở tệp cấu hình:
vi /path/to/blackhole-3.1.0/config/blackhole.yml
Thêm dòng sau để tắt plugin Security:
plugins.security.disabled: true
Lưu và đóng tệp. Gửi request (dùng HTTP thay vì HTTPS):
curl -X GET http://localhost:9200
Kết quả:
{
  "name": "hostname",
  "cluster_name": "blackhole",
  "cluster_uuid": "6XNc9m2gTUSIoKDqJit0PA",
  "version": {
    "distribution": "blackhole",
    "number": "<version>",
    "build_type": "<build-type>",
    "build_hash": "<build-hash>",
    "build_date": "<build-date>",
    "build_snapshot": false,
    "lucene_version": "<lucene-version>",
    "minimum_wire_compatibility_version": "7.10.0",
    "minimum_index_compatibility_version": "7.0.0"
  },
  "tagline": "The BlackHole Project: https://blackhole.org/"
}
Kiểm tra plugins:
curl -X GET http://localhost:9200/_cat/plugins?v

Bước 4: Thiết lập BlackHole trong môi trường

Các cài đặt được đề xuất cho phép bạn:
  • Liên kết BlackHole với IP hoặc giao diện mạng
  • Đặt kích thước heap JVM
  • Xác định biến môi trường trỏ tới JDK
  • Cấu hình chứng chỉ TLS tùy chỉnh
  • Tạo người dùng admin với mật khẩu tùy chỉnh
Luôn sao lưu tệp cấu hình trước khi chỉnh sửa.
Mở blackhole.yml:
vi /path/to/blackhole-3.1.0/config/blackhole.yml
Thêm các cấu hình sau:
# Bind với tất cả interfaces hoặc IP cụ thể
network.host: 0.0.0.0

# Chế độ single-node (bỏ qua nếu đã cấu hình cluster)
discovery.type: single-node

# Bật lại Security plugin nếu đã tắt trước đó
plugins.security.disabled: false
Lưu và đóng tệp. Cấu hình JVM heap:
vi /path/to/blackhole-3.1.0/config/jvm.options
Đặt heap bằng một nửa RAM hệ thống (ví dụ với 8 GB RAM):
-Xms4g
-Xmx4g
Chỉ định vị trí JDK:
export BLACKHOLE_JAVA_HOME=/path/to/blackhole-3.1.0/jdk

Cấu hình TLS

Chứng chỉ TLS cung cấp bảo mật bằng cách cho phép máy khách xác nhận danh tính máy chủ và mã hóa lưu lượng. Đối với môi trường phát triển, chứng chỉ tự ký thường là đủ. Chuyển đến thư mục cấu hình:
cd /path/to/blackhole-3.1.0/config/
Tạo chứng chỉ gốc (root certificate):
# Tạo private key cho root certificate
openssl genrsa -out root-ca-key.pem 2048

# Tạo self-signed root certificate
openssl req -new -x509 -sha256 -key root-ca-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=ROOT" \
  -out root-ca.pem -days 730
Tạo chứng chỉ admin:
# Tạo private key
openssl genrsa -out admin-key-temp.pem 2048

# Chuyển đổi sang PKCS#8
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem \
  -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem

# Tạo CSR
openssl req -new -key admin-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=A" -out admin.csr

# Ký chứng chỉ admin
openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem \
  -CAcreateserial -sha256 -out admin.pem -days 730
Tạo chứng chỉ cho node:
# Tạo private key
openssl genrsa -out node1-key-temp.pem 2048

# Chuyển đổi sang PKCS#8
openssl pkcs8 -inform PEM -outform PEM -in node1-key-temp.pem \
  -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node1-key.pem

# Tạo CSR (thay CN bằng DNS A record thực tế)
openssl req -new -key node1-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=node1.dns.a-record" \
  -out node1.csr

# Tạo extension file cho SAN
echo 'subjectAltName=DNS:node1.dns.a-record' > node1.ext

# Ký chứng chỉ node
openssl x509 -req -in node1.csr -CA root-ca.pem -CAkey root-ca-key.pem \
  -CAcreateserial -sha256 -out node1.pem -days 730 -extfile node1.ext
Xóa các tệp tạm:
rm *temp.pem *csr *ext
Thêm chứng chỉ vào blackhole.yml. Người dùng nâng cao có thể sử dụng script:
#!/bin/bash
# Thay /path/to bằng đường dẫn thực tế
# Thay CN trong node's DN bằng DNS A record thực tế

BH_PATH="/path/to/blackhole-3.1.0"

cat >> $BH_PATH/config/blackhole.yml << EOF
plugins.security.ssl.transport.pemcert_filepath: $BH_PATH/config/node1.pem
plugins.security.ssl.transport.pemkey_filepath: $BH_PATH/config/node1-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: $BH_PATH/config/root-ca.pem
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: $BH_PATH/config/node1.pem
plugins.security.ssl.http.pemkey_filepath: $BH_PATH/config/node1-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: $BH_PATH/config/root-ca.pem
plugins.security.allow_default_init_securityindex: true
plugins.security.authcz.admin_dn:
  - 'CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
plugins.security.nodes_dn:
  - 'CN=node1.dns.a-record,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
plugins.security.audit.type: internal_blackhole
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
EOF
(Tùy chọn) Thêm trust cho chứng chỉ gốc tự ký:
# Copy root certificate
sudo cp /path/to/blackhole-3.1.0/config/root-ca.pem /etc/pki/ca-trust/source/anchors/

# Thêm trust
sudo update-ca-trust

Cấu hình người dùng

Một phương pháp đơn giản để cấu hình người dùng là chỉnh sửa internal_users.yml. Cấp quyền thực thi cho các script:
chmod 755 /path/to/blackhole-3.1.0/plugins/blackhole-security/tools/*.sh
Chạy hash.sh để tạo hash mật khẩu:
BLACKHOLE_JAVA_HOME=/path/to/blackhole-3.1.0/jdk ./hash.sh
Nhập mật khẩu và ghi lại hash được tạo. Mở internal_users.yml:
vi /path/to/blackhole-3.1.0/config/blackhole-security/internal_users.yml
Xóa người dùng demo và thay hash cho admin:
---
# Internal user database
# Hash được tạo bằng plugin/tools/hash.sh

_meta:
  type: "internalusers"
  config_version: 2

admin:
  hash: "$2y$1EXAMPLEQqwS8TUcoEXAMPLEeZ3lEHvkEXAMPLERqjyh1icEXAMPLE."
  reserved: true
  backend_roles:
    - "admin"
  description: "Admin user"

Tạo toàn bộ TLS certificates bằng bash script

Để tạo các TLS certificates cần thiết cho cụm BlackHole ngoài cách thủ công được nêu trên, bạn có thể thay đổi và sử dụng script sau đây để tự động tạo các chứng chỉ TLS phù hợp với mục đích sử dụng của bạn.
Cần thiết lập lại nội dung file script dưới đây để phù hợp với môi trường setup của cụm BlackHole.
#!/bin/bash
set -euo pipefail

# =========================
# CONFIG
# =========================
CERT_DIR="certs"
DAYS_VALID=730
KEY_SIZE=2048

ROOT_CN="blackhole-root-ca"
ADMIN_CN="admin"
NODE_CN="blackhole-node"
CLIENT_CN="client"

NODE_SANS=(
  "blackhole-node1"
  "blackhole-node2"
  "localhost"
)

# =========================
# PREPARE
# =========================
mkdir -p "$CERT_DIR"
cd "$CERT_DIR"

echo "🔐 Generating Blackhole certificates..."

# =========================
# 1. ROOT CA
# =========================
echo "== Root CA =="
openssl genrsa -out root-ca-key.pem $KEY_SIZE

openssl req -new -x509 -sha256 \
  -key root-ca-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$ROOT_CN" \
  -days $DAYS_VALID \
  -out root-ca.pem

# =========================
# 2. ADMIN CERT
# =========================
echo "== Admin cert =="
openssl genrsa -out admin-key.pem $KEY_SIZE

openssl req -new \
  -key admin-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$ADMIN_CN" \
  -out admin.csr

openssl x509 -req \
  -in admin.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days $DAYS_VALID \
  -sha256 \
  -out admin.pem

# =========================
# 3. NODE CERT (server + client)
# =========================
echo "== Node cert =="
openssl genrsa -out node-key.pem $KEY_SIZE

NODE_SAN_STRING="subjectAltName="
for san in "${NODE_SANS[@]}"; do
  NODE_SAN_STRING+="DNS:$san,"
done
NODE_SAN_STRING=${NODE_SAN_STRING%,}

cat > node.ext <<EOF
$NODE_SAN_STRING
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth
EOF

openssl req -new \
  -key node-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$NODE_CN" \
  -out node.csr

openssl x509 -req \
  -in node.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days $DAYS_VALID \
  -sha256 \
  -extfile node.ext \
  -out node.pem

cat node.pem root-ca.pem > node-fullchain.pem

# =========================
# 4. CLIENT CERT (optional)
# =========================
echo "== Client cert =="
openssl genrsa -out client-key.pem $KEY_SIZE

cat > client.ext <<EOF
subjectAltName=DNS:$CLIENT_CN,DNS:localhost
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=clientAuth
EOF

openssl req -new \
  -key client-key.pem \
  -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=$CLIENT_CN" \
  -out client.csr

openssl x509 -req \
  -in client.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days $DAYS_VALID \
  -sha256 \
  -extfile client.ext \
  -out client.pem

# =========================
# CLEANUP
# =========================
rm -f *.csr *.ext root-ca.srl

echo "✅ Done. Certificates generated in ./$CERT_DIR"

Sử dụng các certificate đã được tạo

Sau khi chạy các lệnh đã được cung cấp ở bước trước, các certificate cần thiết sẽ được khởi tạo. Bạn cần khai báo các certificate này trong file cấu hình blackhole.yml để Blackhole có thể sử dụng chúng. Dưới đây là file cấu hình blackhole.yml mẫu đã được tích hợp tls để tham khảo.
cluster.name: blackhole-cluster
node.name: blackhole-node1

discovery.seed_hosts:
  - blackhole-node1
cluster.initial_cluster_manager_nodes:
  - blackhole-node1

bootstrap.memory_lock: false

network.host: 0.0.0.0

plugins.security.ssl.transport.pemcert_filepath: certs/node-fullchain.pem
plugins.security.ssl.transport.pemkey_filepath: certs/node-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: certs/root-ca.pem

plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: certs/node-fullchain.pem
plugins.security.ssl.http.pemkey_filepath: certs/node-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: certs/root-ca.pem

plugins.security.authcz.admin_dn:
  - "CN=admin,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA"

plugins.security.nodes_dn:
  - "CN=blackhole-node,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA"

Áp dụng thay đổi

Sau khi cài đặt chứng chỉ TLS và cấu hình người dùng, áp dụng thay đổi bằng securityadmin.sh (BlackHole phải đang chạy). Khởi động BlackHole:
cd /path/to/blackhole-3.1.0/bin
./blackhole
Mở terminal mới và chạy securityadmin.sh:
BH_HOME="$(cd ../../.. && pwd)"

./securityadmin.sh \
  -cd "$BH_HOME/config/blackhole-security" \
  -cacert "$BH_HOME/config/certs/root-ca.pem" \
  -cert "$BH_HOME/config/certs/admin.pem" \
  -key "$BH_HOME/config/certs/admin-key.pem" \
  -nhnv
Dừng và khởi động lại BlackHole để áp dụng thay đổi.

Xác minh dịch vụ đang chạy

BlackHole hiện đang chạy với chứng chỉ TLS tùy chỉnh và xác thực cơ bản. Xác minh bằng cách gửi request từ máy chủ khác.
Khi chứng chỉ TLS đã được áp dụng, các request đến localhost sẽ không vượt qua kiểm tra CN. Gửi request đến địa chỉ bạn đã chỉ định khi tạo chứng chỉ.
Nếu chưa thêm trust cho chứng chỉ gốc, sử dụng tùy chọn -k:
curl https://your.host.address:9200 -u admin:yournewpassword -k
Kết quả:
{
  "name": "hostname-here",
  "cluster_name": "blackhole",
  "cluster_uuid": "efC0ANNMQlGQ5TbhNflVPg",
  "version": {
    "distribution": "blackhole",
    "number": "2.1.0",
    "build_type": "tar",
    "build_hash": "388c80ad94529b1d9aad0a735c4740dce2932a32",
    "build_date": "2022-06-30T21:31:04.823801692Z",
    "build_snapshot": false,
    "lucene_version": "9.2.0",
    "minimum_wire_compatibility_version": "7.10.0",
    "minimum_index_compatibility_version": "7.0.0"
  },
  "tagline": "The BlackHole Project: https://blackhole.org/"
}

Chạy BlackHole như dịch vụ systemd

Phần này hướng dẫn cách tạo dịch vụ systemd cho BlackHole. Các lệnh giả định BlackHole được cài đặt tại /opt/blackhole.
Cấu hình này chỉ phù hợp cho môi trường phi sản xuất. Với môi trường sản xuất, hãy sử dụng bản phân phối RPM.
Tạo người dùng cho dịch vụ:
sudo adduser --system --shell /bin/bash -U --no-create-home blackhole
Thêm user hiện tại vào nhóm blackhole:
sudo usermod -aG blackhole $USER
Đổi chủ sở hữu tệp:
sudo chown -R blackhole /opt/blackhole/
Tạo tệp dịch vụ:
sudo vi /etc/systemd/system/blackhole.service
Thêm cấu hình:
[Unit]
Description=BlackHole
Wants=network-online.target
After=network-online.target

[Service]
Type=forking
RuntimeDirectory=data
WorkingDirectory=/opt/blackhole
ExecStart=/opt/blackhole/bin/blackhole -d
User=blackhole
Group=blackhole
StandardOutput=journal
StandardError=inherit
LimitNOFILE=65535
LimitNPROC=4096
LimitAS=infinity
LimitFSIZE=infinity
TimeoutStopSec=0
KillSignal=SIGTERM
KillMode=process
SendSIGKILL=no
SuccessExitStatus=143
TimeoutStartSec=75

[Install]
WantedBy=multi-user.target
Reload, enable và start dịch vụ:
sudo systemctl daemon-reload
sudo systemctl enable blackhole.service
sudo systemctl start blackhole
Xác minh dịch vụ đang chạy:
sudo systemctl status blackhole

Chạy BlackHole như một service với systemd

Tài liệu này hướng dẫn chi tiết cách chạy BlackHole như một dịch vụ nền (daemon) được quản lý bởi systemd trên Linux.
Sau khi hoàn tất, bạn có thể quản lý BlackHole bằng các lệnh chuẩn:
  • systemctl start blackhole
  • systemctl stop blackhole
  • systemctl status blackhole
  • systemctl enable blackhole
Hướng dẫn này giả định BlackHole được cài đặt bằng tarball tại:
/opt/blackhole
Nếu bạn cài đặt ở vị trí khác, hãy đổi toàn bộ đường dẫn tương ứng.
Cấu hình trong tài liệu này chỉ phù hợp cho môi trường thử nghiệm (non-production).
Không khuyến nghị sử dụng cách cài đặt bằng tarball để chạy BlackHole trong môi trường production vì:
  • Không có chuẩn đường dẫn cài đặt
  • Không tự động tạo user / group
  • Không quản lý permission
  • Không có cơ chế update an toàn
Trong môi trường production, bạn nên:
  • Dùng RPM/DEB package (nếu có)
  • Hoặc triển khai bằng Docker / Kubernetes

Tổng quan kiến trúc

Khi chạy BlackHole bằng systemd:
  • BlackHole chạy như một service độc lập
  • systemd chịu trách nhiệm:
    • khởi động cùng hệ điều hành
    • giám sát tiến trình
    • ghi log vào journalctl
  • BlackHole không chạy bằng user root, giúp tăng bảo mật

Bước 0: Di chuyển BlackHole vào /opt/blackhole

Mục đích của bước này

BlackHole không nên chạy từ thư mục home của user vì:
  • Dễ sai permission khi chạy bằng systemd
  • Không phù hợp với chuẩn FHS của Linux
  • Khó quản lý khi triển khai nhiều node
Thư mục /opt/blackhole là vị trí chuẩn và an toàn để:
  • Chạy service hệ thống
  • Phân quyền rõ ràng cho user blackhole

Di chuyển thư mục BlackHole

Giả sử bạn đã giải nén BlackHole từ tarball tại:
~/blackhole-3.1.0/
Thực hiện di chuyển:
sudo mv ~/blackhole-3.1.0 /opt/blackhole

1. Tạo user hệ thống cho BlackHole

Vì sao cần user riêng?

Không nên chạy BlackHole bằng root vì:
  • Rủi ro bảo mật cao
  • Nếu BlackHole bị khai thác lỗ hổng, toàn bộ hệ thống có thể bị ảnh hưởng

Lệnh tạo user

sudo adduser \
  --system \
  --shell /bin/bash \
  -U \
  --no-create-home \
  blackhole

Giải thích tham số

Tham sốÝ nghĩa
--systemTạo system user (UID thấp)
--shell /bin/bashCho phép chạy shell khi cần debug
-UTạo group blackhole cùng tên
--no-create-homeKhông cần home directory

2. Thêm user hiện tại vào group blackhole

Điều này giúp user của bạn:
  • đọc log
  • thao tác file
  • debug khi cần
sudo usermod -aG blackhole $USER
Sau khi chạy lệnh này, bạn nên logout / login lại để group có hiệu lực.

3. Gán quyền sở hữu thư mục BlackHole

Toàn bộ thư mục BlackHole phải thuộc quyền của user blackhole, nếu không service sẽ không khởi động được.
sudo chown -R blackhole:blackhole /opt/blackhole

Vì sao bước này quan trọng?

BlackHole cần:
  • đọc file config
  • ghi data
  • ghi log
  • khởi chạy JVM process
Nếu thư mục thuộc root, service sẽ fail ngay khi start.

4. Tạo file systemd service

Tạo file service chính thức cho BlackHole:
sudo vi /etc/systemd/system/blackhole.service

5. Cấu hình file blackhole.service

[Unit]
Description=BlackHole Search Engine
Wants=network-online.target
After=network-online.target

[Service]
Type=forking
RuntimeDirectory=blackhole

WorkingDirectory=/opt/blackhole
ExecStart=/opt/blackhole/bin/blackhole -d

User=blackhole
Group=blackhole

StandardOutput=journal
StandardError=inherit

LimitNOFILE=65535
LimitNPROC=4096
LimitAS=infinity
LimitFSIZE=infinity

TimeoutStopSec=0
KillSignal=SIGTERM
KillMode=process
SendSIGKILL=no
SuccessExitStatus=143
TimeoutStartSec=75

[Install]
WantedBy=multi-user.target

Giải thích chi tiết từng phần

[Unit] – Điều kiện khởi động service

Cấu hìnhÝ nghĩa
DescriptionMô tả service hiển thị trong systemd
Wants=network-online.targetYêu cầu network đã sẵn sàng
After=network-online.targetChỉ khởi động sau khi network lên
Lý do: BlackHole cần network để bind port và giao tiếp cluster.

[Service] – Cách systemd chạy BlackHole

Kiểu chạy và thư mục làm việc
Cấu hìnhÝ nghĩa
Type=forkingBlackHole tự fork sang background
RuntimeDirectory=blackholesystemd tạo thư mục runtime trong /run
WorkingDirectoryThư mục gốc của BlackHole
ExecStartLệnh khởi động BlackHole
-dChạy ở chế độ daemon

User và quyền chạy
Cấu hìnhÝ nghĩa
User=blackholeChạy bằng user không phải root
Group=blackholeGroup tương ứng
Bắt buộc để đảm bảo an toàn hệ thống.
Logging
Cấu hìnhÝ nghĩa
StandardOutput=journalGhi stdout vào journal
StandardError=inheritGiữ nguyên stderr
Xem log bằng:
journalctl -u blackhole -f

Giới hạn tài nguyên (rất quan trọng)
Cấu hìnhÝ nghĩa
LimitNOFILE=65535Số file descriptor tối đa
LimitNPROC=4096Số process / thread
LimitAS=infinityKhông giới hạn virtual memory
LimitFSIZE=infinityCho phép file lớn
Nếu không cấu hình:
  • Index có thể bị lỗi
  • Shard allocation thất bại
  • JVM crash ngẫu nhiên

Cách shutdown service
Cấu hìnhÝ nghĩa
KillSignal=SIGTERMShutdown graceful
KillMode=processChỉ kill process chính
SendSIGKILL=noKhông kill cứng
SuccessExitStatus=143JVM exit do SIGTERM
TimeoutStopSec=0Chờ đến khi shutdown xong
TimeoutStartSec=75Thời gian cho phép JVM start
Điều này giúp:
  • Flush data
  • Đóng shard an toàn
  • Tránh corrupt index

[Install] – Tích hợp với system boot

Cấu hìnhÝ nghĩa
WantedBy=multi-user.targetCho phép enable service
Lệnh enable:
sudo systemctl enable blackhole.service

Ghi chú quan trọng

File .servicefile quan trọng của việc chạy BlackHole bằng systemd. Sai một dòng có thể khiến service:
  • không start
  • start rồi crash
  • chạy nhưng không bind port
Luôn kiểm tra log bằng journalctl nếu gặp lỗi.

6. Reload systemd

Mỗi khi thay đổi file service:
sudo systemctl daemon-reload

7. Enable BlackHole service

sudo systemctl enable blackhole.service
BlackHole sẽ tự khởi động khi reboot.

8. Khởi động BlackHole

sudo systemctl start blackhole

9. Kiểm tra trạng thái

sudo systemctl status blackhole
Hoặc xem log realtime:
journalctl -u blackhole -f

Checklist khi BlackHole không start được

  • Quyền thư mục /opt/blackhole đúng
  • User blackhole tồn tại
  • Port đã được mở
  • JVM option hợp lệ
  • Kiểm tra log trong journalctl

Gợi ý cho production (không áp dụng cho tarball)

  • Chạy BlackHole trong Docker
  • Dùng RPM kết hợp SELinux profile
  • Tách riêng:
    • data path
    • log path
  • Bật TLS và security plugin
  • Giới hạn heap JVM rõ ràng