rpki/deploy/bird/entrypoint.sh
xiuting.xu cef9495534 add bird deploy
add data
add certs
2026-04-23 15:13:50 +08:00

159 lines
4.0 KiB
Bash

#!/bin/sh
set -eu
mkdir -p /run/bird
SOCK_PATH="/run/bird/bird.ctl"
PROTO="${OBSERVE_PROTO:-rpki_tcp}"
INTERVAL="${OBSERVE_INTERVAL:-30}"
RPKI_HOST="${RPKI_HOST:-host.docker.internal}"
RPKI_PORT="${RPKI_PORT:-323}"
BIRD_CONFIG_PATH="${BIRD_CONFIG_PATH:-/config/bird.conf}"
ASPA_TABLE="${OBSERVE_ASPA_TABLE:-rtr_aspa}"
ROA4_TABLE="${OBSERVE_ROA4_TABLE:-rtr_roa_v4}"
ROA6_TABLE="${OBSERVE_ROA6_TABLE:-rtr_roa_v6}"
ASPA_COUNT="${OBSERVE_ASPA_COUNT:-3}"
ROA4_COUNT="${OBSERVE_ROA4_COUNT:-3}"
ROA6_COUNT="${OBSERVE_ROA6_COUNT:-3}"
SHOW_ASPA="${SHOW_ASPA:-1}"
SHOW_ROA4="${SHOW_ROA4:-1}"
SHOW_ROA6="${SHOW_ROA6:-1}"
SSH_HOST_PUBKEY_PATH="${SSH_HOST_PUBKEY_PATH:-/config/ssh/ssh_host_rsa_key.pub}"
SSH_KNOWN_HOSTS_PATH="${SSH_KNOWN_HOSTS_PATH:-/run/bird/known_hosts}"
ensure_ssh_known_hosts() {
if [ -s "$SSH_KNOWN_HOSTS_PATH" ]; then
return
fi
if [ ! -r "$SSH_HOST_PUBKEY_PATH" ]; then
echo "[entrypoint] WARNING: SSH host key file not found: $SSH_HOST_PUBKEY_PATH"
return
fi
set -- $(awk 'NF >= 2 { print $1, $2; exit }' "$SSH_HOST_PUBKEY_PATH")
if [ $# -ne 2 ]; then
echo "[entrypoint] WARNING: invalid SSH host key format in $SSH_HOST_PUBKEY_PATH"
return
fi
key_type="$1"
key_data="$2"
if echo "$key_type" | grep -q '^ssh-'; then
{
echo "$RPKI_HOST $key_type $key_data"
echo "[$RPKI_HOST]:$RPKI_PORT $key_type $key_data"
} > "$SSH_KNOWN_HOSTS_PATH"
else
cp "$SSH_HOST_PUBKEY_PATH" "$SSH_KNOWN_HOSTS_PATH"
fi
chmod 600 "$SSH_KNOWN_HOSTS_PATH" || true
echo "[entrypoint] generated known_hosts: $SSH_KNOWN_HOSTS_PATH"
}
print_first_n_objects() {
table_name="$1"
max_objects="$2"
birdc -s "$SOCK_PATH" show route table "$table_name" all 2>/dev/null | awk -v max="$max_objects" '
BEGIN {
count = 0
}
# 直接跳过空行
/^[[:space:]]*$/ {
next
}
# 保留 birdc 的表头
/^BIRD / {
print
next
}
/^Table / {
print
next
}
# 非缩进且不是表头,视为一个新对象的开始
/^[^[:space:]]/ {
count++
if (count > max) {
exit
}
print
next
}
# 缩进内容,只有在已进入前 max 个对象时才打印
{
if (count > 0 && count <= max) {
print
}
}
' || true
}
echo "[entrypoint] starting bird"
echo "[entrypoint] config : $BIRD_CONFIG_PATH"
echo "[entrypoint] observe proto : $PROTO"
echo "[entrypoint] observe interval : $INTERVAL"
echo "[entrypoint] target : $RPKI_HOST:$RPKI_PORT"
echo "[entrypoint] show aspa : $SHOW_ASPA ($ASPA_TABLE, first $ASPA_COUNT objects)"
echo "[entrypoint] show roa4 : $SHOW_ROA4 ($ROA4_TABLE, first $ROA4_COUNT objects)"
echo "[entrypoint] show roa6 : $SHOW_ROA6 ($ROA6_TABLE, first $ROA6_COUNT objects)"
if [ "$PROTO" = "rpki_ssh" ] || grep -q 'transport[[:space:]]\+ssh' "$BIRD_CONFIG_PATH"; then
ensure_ssh_known_hosts
fi
if nc -zvw3 "$RPKI_HOST" "$RPKI_PORT"; then
echo "[entrypoint] TCP connectivity to $RPKI_HOST:$RPKI_PORT OK"
else
echo "[entrypoint] WARNING: cannot connect to $RPKI_HOST:$RPKI_PORT before BIRD starts"
fi
bird -f -c "$BIRD_CONFIG_PATH" -s "$SOCK_PATH" &
BIRD_PID="$!"
sleep 1
case "$INTERVAL" in
''|*[!0-9]*)
INTERVAL=0
;;
esac
if [ "$INTERVAL" -gt 0 ]; then
while kill -0 "$BIRD_PID" 2>/dev/null; do
echo "==== $(date -u +"%Y-%m-%dT%H:%M:%SZ") RPKI snapshot ($PROTO) ===="
birdc -s "$SOCK_PATH" show protocols all "$PROTO" || true
if [ "$SHOW_ASPA" = "1" ]; then
echo "---- ASPA table ($ASPA_TABLE, first ${ASPA_COUNT} objects) ----"
print_first_n_objects "$ASPA_TABLE" "$ASPA_COUNT"
fi
if [ "$SHOW_ROA4" = "1" ]; then
echo "---- ROA4 table ($ROA4_TABLE, first ${ROA4_COUNT} objects) ----"
print_first_n_objects "$ROA4_TABLE" "$ROA4_COUNT"
fi
if [ "$SHOW_ROA6" = "1" ]; then
echo "---- ROA6 table ($ROA6_TABLE, first ${ROA6_COUNT} objects) ----"
print_first_n_objects "$ROA6_TABLE" "$ROA6_COUNT"
fi
sleep "$INTERVAL"
done
fi
wait "$BIRD_PID"