Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions compose/openbao.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
services:
core:
depends_on:
openbao-init:
condition: service_completed_successfully

celery:
depends_on:
openbao-init:
condition: service_completed_successfully

openbao:
image: ${OPENBAO_IMAGE:-openbao/openbao:2.6.0}
container_name: jms_openbao
hostname: openbao
# Start the image entrypoint as root so it can fix bind-mount ownership;
# the official entrypoint then launches bao via su-exec as openbao.
user: "0"
restart: always
command: server -config=/openbao/config/server.hcl
environment:
BAO_ADDR: http://127.0.0.1:8200
VAULT_API_ADDR: ${OPENBAO_RAFT_API_ADDR:-http://openbao:8200}
VAULT_CLUSTER_ADDR: ${OPENBAO_RAFT_CLUSTER_ADDR:-http://openbao:8201}
VAULT_RAFT_NODE_ID: ${OPENBAO_RAFT_NODE_ID:-openbao}
TZ: ${TZ:-Asia/Shanghai}
volumes:
- ${CONFIG_DIR}/openbao/server.hcl:/openbao/config/server.hcl:ro
- ${VOLUME_DIR}/openbao/data:/openbao/file
ports:
- "${OPENBAO_UI_BIND:-127.0.0.1}:${OPENBAO_UI_PORT:-8200}:8200"
- "${OPENBAO_CLUSTER_BIND:-127.0.0.1}:${OPENBAO_CLUSTER_PORT:-8201}:8201"
healthcheck:
test: "bao status -address=http://127.0.0.1:8200"
interval: 10s
timeout: 5s
retries: 3
start_period: 10s
networks:
- net

openbao-init:
image: ${OPENBAO_IMAGE:-openbao/openbao:2.6.0}
container_name: jms_openbao_init
hostname: openbao-init
# The one-shot initializer writes root-owned 0600 unseal material.
user: "0"
restart: "no"
command: sh /openbao/bootstrap/bootstrap.sh
env_file:
- ${CONFIG_FILE}
environment:
BAO_ADDR: http://openbao:8200
TZ: ${TZ:-Asia/Shanghai}
volumes:
- ${CONFIG_DIR}/openbao:/openbao/bootstrap
depends_on:
- openbao
networks:
- net
33 changes: 33 additions & 0 deletions config-example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,36 @@ USE_LB=1
#
TZ=Asia/Shanghai
CURRENT_VERSION=

################################# Vault Configuration #################################
# OpenBao runs as an independent Docker service in this installer. JumpServer connects to OpenBao Server directly.
# OpenBao 作为独立 Docker 服务部署,JumpServer 直接访问 OpenBao Server。
#
# Disabled by default. Set to true to enable Vault storage. When the backend is
# openbao and OPENBAO_EXTERNAL=false, the installer starts the built-in service.
# 默认关闭;设为 true 后启用 Vault。当后端为 openbao 且 OPENBAO_EXTERNAL=false 时,安装器启动内置服务。
VAULT_ENABLED=false
VAULT_BACKEND=openbao
VAULT_OPENBAO_ADDR=http://openbao:8200
VAULT_OPENBAO_MOUNT_POINT=pam
VAULT_OPENBAO_TOKEN=
VAULT_OPENBAO_TIMEOUT=10

# Set to true when VAULT_OPENBAO_ADDR points to an external OpenBao cluster or HA endpoint.
# 设置为 true 时,installer 不会启动内置 OpenBao,Core 仍使用上面的 Vault 配置连接外部服务。
OPENBAO_EXTERNAL=false

OPENBAO_RAFT_NODE_ID=openbao
OPENBAO_RAFT_API_ADDR=http://openbao:8200
OPENBAO_RAFT_CLUSTER_ADDR=http://openbao:8201
OPENBAO_RAFT_BOOTSTRAP=true
# Additional Raft nodes must set OPENBAO_RAFT_BOOTSTRAP=false and receive a
# protected copy of openbao/init.json from the bootstrap node before startup.
# OPENBAO_RAFT_RETRY_JOIN=http://openbao-1:8200,http://openbao-2:8200

OPENBAO_UNSEAL_KEY_SHARES=5
OPENBAO_UNSEAL_KEY_THRESHOLD=3
OPENBAO_UI_BIND=127.0.0.1
OPENBAO_UI_PORT=8200
OPENBAO_CLUSTER_BIND=127.0.0.1
OPENBAO_CLUSTER_PORT=8201
162 changes: 162 additions & 0 deletions config_init/openbao/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/sh
set -eu

export BAO_ADDR="${BAO_ADDR:-http://openbao:8200}"

MOUNT_POINT="${VAULT_OPENBAO_MOUNT_POINT:-pam}"
SERVICE_TOKEN="${VAULT_OPENBAO_TOKEN:-}"
RAFT_BOOTSTRAP="${OPENBAO_RAFT_BOOTSTRAP:-true}"
UNSEAL_KEY_SHARES="${OPENBAO_UNSEAL_KEY_SHARES:-5}"
UNSEAL_KEY_THRESHOLD="${OPENBAO_UNSEAL_KEY_THRESHOLD:-3}"
INIT_FILE="/openbao/bootstrap/init.json"
POLICY_FILE="/tmp/jumpserver-policy.hcl"
SERVICE_TOKEN_FILE="/openbao/bootstrap/jumpserver-token.json"

wait_openbao() {
i=0
while [ "$i" -lt 60 ]; do
if bao status >/tmp/openbao-status 2>&1; then
return 0
fi
if grep -q "Initialized" /tmp/openbao-status 2>/dev/null; then
return 0
fi
i=$((i + 1))
sleep 1
done
cat /tmp/openbao-status 2>/dev/null || true
echo "OpenBao is not reachable"
exit 1
}

json_value() {
key="$1"
tr -d '\n ' <"${INIT_FILE}" | sed -n "s/.*\"${key}\":\"\\([^\"]*\\)\".*/\\1/p"
}

json_array_first() {
key="$1"
tr -d '\n ' <"${INIT_FILE}" | sed -n "s/.*\"${key}\":\\[\"\\([^\"]*\\)\".*/\\1/p"
}

json_array_values() {
key="$1"
tr -d '\n ' <"${INIT_FILE}" | sed -n "s/.*\"${key}\":\\[\\([^]]*\\)\\].*/\\1/p" | tr ',' '\n' | sed 's/^"//;s/"$//'
}

is_true() {
case "$1" in
1|true|True|TRUE|yes|Yes|YES) return 0 ;;
*) return 1 ;;
esac
}

is_initialized() {
bao status 2>/dev/null | grep -q "Initialized[[:space:]]*true"
}

is_uninitialized() {
bao status 2>/dev/null | grep -q "Initialized[[:space:]]*false"
}

is_sealed() {
bao status 2>/dev/null | grep -q "Sealed[[:space:]]*true"
}

wait_unsealed() {
i=0
while [ "$i" -lt 30 ]; do
if ! is_sealed; then
return 0
fi
i=$((i + 1))
sleep 1
done
return 1
}

unseal_openbao() {
if ! is_sealed; then
return 0
fi

json_array_values unseal_keys_b64 | while IFS= read -r key; do
[ -z "${key}" ] && continue
if ! is_sealed; then
break
fi
bao operator unseal "${key}" >/dev/null
done

if ! wait_unsealed; then
echo "OpenBao is still sealed after applying unseal keys from ${INIT_FILE}."
exit 1
fi
}

wait_openbao

if is_uninitialized; then
if is_true "${RAFT_BOOTSTRAP}"; then
bao operator init -key-shares="${UNSEAL_KEY_SHARES}" -key-threshold="${UNSEAL_KEY_THRESHOLD}" -format=json >"${INIT_FILE}"
chmod 600 "${INIT_FILE}" 2>/dev/null || true
else
i=0
while [ "$i" -lt 60 ]; do
is_initialized && break
i=$((i + 1))
sleep 1
done
if is_uninitialized; then
echo "OpenBao is not initialized. Set OPENBAO_RAFT_BOOTSTRAP=true on the first Raft node, or wait for retry_join to finish."
exit 1
fi
fi
fi

if [ ! -f "${INIT_FILE}" ]; then
echo "OpenBao is initialized, but ${INIT_FILE} is missing; cannot unseal automatically."
echo "On an additional Raft node, copy init.json from the bootstrap node to this node before startup."
exit 1
fi

ROOT_TOKEN="$(json_value root_token)"

if [ -z "${ROOT_TOKEN}" ] || [ -z "$(json_array_first unseal_keys_b64)" ]; then
echo "Invalid OpenBao initialization file: ${INIT_FILE}"
exit 1
fi

unseal_openbao

export BAO_TOKEN="${ROOT_TOKEN}"

if ! bao secrets list -format=json | grep -q "\"${MOUNT_POINT}/\""; then
bao secrets enable -path="${MOUNT_POINT}" -version=2 kv
fi

bao write "${MOUNT_POINT}/config" max_versions=20 >/dev/null

cat >"${POLICY_FILE}" <<POLICY
path "${MOUNT_POINT}/data/*" {
capabilities = ["create", "read", "update", "patch"]
}

path "${MOUNT_POINT}/metadata/*" {
capabilities = ["create", "update", "delete"]
}
POLICY

bao policy write jumpserver "${POLICY_FILE}" >/dev/null

if [ -n "${SERVICE_TOKEN}" ]; then
if ! bao token lookup "${SERVICE_TOKEN}" >/dev/null 2>&1; then
bao token create \
-id="${SERVICE_TOKEN}" \
-policy=jumpserver \
-orphan \
-no-default-policy \
-format=json >"${SERVICE_TOKEN_FILE}"
chmod 600 "${SERVICE_TOKEN_FILE}" 2>/dev/null || true
fi
fi
16 changes: 16 additions & 0 deletions config_init/openbao/server.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ui = true
disable_mlock = true

storage "raft" {
path = "/openbao/file"
node_id = "openbao"
}

listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_disable = true
}

api_addr = "http://openbao:8200"
cluster_addr = "http://openbao:8201"
3 changes: 3 additions & 0 deletions jmsctl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ function service_to_docker_name() {
EXE=""

function start() {
set_openbao || return 1
gen_safe_config >/dev/null
EXE=$(get_docker_compose_cmd_line)
${EXE} up -d

base_dir="${PROJECT_DIR}"
Expand Down
4 changes: 4 additions & 0 deletions scripts/0_prepare.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ function prepare_image_files() {
fi
rm -f "${IMAGE_DIR}"/*

# The offline bundle must carry optional OpenBao even when it is disabled by
# default, so it can be enabled later without registry access.
local INCLUDE_OPENBAO_IMAGE=1
export INCLUDE_OPENBAO_IMAGE
pull_images

images=$(get_images)
Expand Down
1 change: 1 addition & 0 deletions scripts/1_config_jumpserver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ function main() {
if set_redis; then
echo_done
fi
set_openbao || return 1
if set_service; then
echo_done
fi
Expand Down
1 change: 1 addition & 0 deletions scripts/7_upgrade.sh
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ function update_config_if_need() {
migrate_coco_to_koko
migrate_config
upgrade_config
set_openbao || exit 1
clean_file
}

Expand Down
17 changes: 16 additions & 1 deletion scripts/gists/conf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,19 @@ function get_config_or_env() {
echo "${value}"
}

CONFIG_SAFE_EXCLUDES="DB_HOST DB_PORT DB_PASSWORD"
CONFIG_SAFE_EXCLUDES="DB_HOST DB_PORT DB_PASSWORD REDIS_PASSWORD VAULT_OPENBAO_TOKEN"

function is_config_excluded() {
local key=$1
local excluded

for excluded in ${CONFIG_SAFE_EXCLUDES}; do
if [[ "${key}" == "${excluded}" ]]; then
return 0
fi
done
return 1
}

function gen_safe_config() {
local base_config_file=${CONFIG_FILE}
Expand Down Expand Up @@ -177,6 +189,9 @@ function prepare_config() {
find "${CONFIG_DIR}" -type d -exec chmod 700 {} \;
find "${CONFIG_DIR}" -type f -exec chmod 600 {} \;
chmod 644 "${CONFIG_DIR}/redis/redis.conf"
if [[ -f "${CONFIG_DIR}/openbao/server.hcl" ]]; then
chmod 644 "${CONFIG_DIR}/openbao/server.hcl"
fi

if [[ "$(uname -m)" == "aarch64" ]]; then
sed_in_place "s/# ignore-warnings ARM64-COW-BUG/ignore-warnings ARM64-COW-BUG/g" "${CONFIG_DIR}/redis/redis.conf"
Expand Down
11 changes: 9 additions & 2 deletions scripts/gists/image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ function get_pull_images() {
if [[ "${use_xpack}" == "1" ]]; then
images+=("jumpserver/ansible-executor:latest")
fi
if should_include_openbao_image; then
images+=("$(get_openbao_image)")
fi
echo "${images[@]}"
}

Expand All @@ -47,6 +50,9 @@ function get_images() {
if [[ "${use_xpack}" == "1" ]]; then
images+=("${namespace}/ansible-executor:latest")
fi
if should_include_openbao_image; then
images+=("$(get_openbao_image)")
fi
echo "${images[@]}"
}

Expand Down Expand Up @@ -86,7 +92,9 @@ function get_image_full_path() {

full_image_path="${image}"
if [[ -n "${DOCKER_IMAGE_PREFIX}" ]]; then
if echo "${DOCKER_IMAGE_PREFIX}" | grep -q "/";then
if [[ "${image}" == */* && $(image_has_prefix "${image}") != "1" ]]; then
full_image_path="${image}"
elif echo "${DOCKER_IMAGE_PREFIX}" | grep -q "/";then
app=$(echo "$image" | awk -F'/' '{ print $NF }')
full_image_path="${DOCKER_IMAGE_PREFIX}/${app}"
elif [[ $(image_has_prefix "${image}") != "1" ]]; then
Expand Down Expand Up @@ -151,4 +159,3 @@ function pull_images() {

trap - SIGINT SIGTERM
}

Loading