#!/bin/sh /etc/rc.common START=60 STOP=01 USE_PROCD=1 MAINU=ripe-atlas MEASU=ripe-atlas GROUP=ripe-atlas extra_command "get_key" "Print the public key to register the probe with" extra_command "probeid" "Print the probe ID" validate_config() { uci_load_validate 'ripe-atlas' 'ripe-atlas' "${1}" "${2}" \ 'enabled:bool:1' \ 'log_stderr:bool:0' \ 'log_stdout:bool:0' \ 'mode:string:prod' \ 'rxtx_report:bool:0' } create_dir() { local user local group local mode local dir local ret=0 user="${1}" shift group="${1}" shift mode="${1}" shift while [ -n "${1}" ]; do dir="${1}" # The probe user may have put a link in its place. [ -L "${dir}" ] && rm -f "${dir}" mkdir -p "${dir}" || ret=1 chown ${user}:${group} "${dir}" || ret=1 chmod ${mode} "${dir}" || ret=1 shift done return ${ret} } setup_environment() { local stamp=/var/run/ripe-atlas/spool.done create_dir root root 0755 /var/run/ripe-atlas create_dir ${MEASU} ${GROUP} 0775 \ /var/run/ripe-atlas/pids \ /var/run/ripe-atlas/status # Below a spool someone else made, links could be swapped in at any # time. mkdir -p /var/spool if [ -n "$(find /var/spool /var/spool/ripe-atlas -maxdepth 0 \ ! -user 0 2> /dev/null)" ]; then logger -t ripe-atlas -p daemon.err \ '/var/spool/ripe-atlas was not made by root' return 1 fi # The probe user owns the spool directories and could swap in a link # for root's chown and chmod to follow. Set them up only until that # worked once since boot (/var is a tmpfs), so only while no probe # runs. [ -e "${stamp}" ] && [ -d /var/spool/ripe-atlas ] && return 0 create_dir ${MEASU} ${GROUP} 2775 \ /var/spool/ripe-atlas/crons \ /var/spool/ripe-atlas/crons/main \ /var/spool/ripe-atlas/crons/2 \ /var/spool/ripe-atlas/crons/3 \ /var/spool/ripe-atlas/crons/4 \ /var/spool/ripe-atlas/crons/5 \ /var/spool/ripe-atlas/crons/6 \ /var/spool/ripe-atlas/crons/7 \ /var/spool/ripe-atlas/crons/8 \ /var/spool/ripe-atlas/crons/9 \ /var/spool/ripe-atlas/crons/10 \ /var/spool/ripe-atlas/crons/11 \ /var/spool/ripe-atlas/crons/12 \ /var/spool/ripe-atlas/crons/13 \ /var/spool/ripe-atlas/crons/14 \ /var/spool/ripe-atlas/crons/15 \ /var/spool/ripe-atlas/crons/16 \ /var/spool/ripe-atlas/crons/17 \ /var/spool/ripe-atlas/crons/18 \ /var/spool/ripe-atlas/crons/19 \ /var/spool/ripe-atlas/crons/20 \ /var/spool/ripe-atlas/data \ /var/spool/ripe-atlas/data/new \ /var/spool/ripe-atlas/data/oneoff \ /var/spool/ripe-atlas/data/out \ /var/spool/ripe-atlas/data/out/ooq \ /var/spool/ripe-atlas/data/out/ooq10 && rm -f "${stamp}" && : > "${stamp}" return 0 } start_instance() { local cfg=/etc/ripe-atlas/config.txt local mod=/etc/ripe-atlas/mode local key=/etc/ripe-atlas/probe_key if [ ${2} -ne 0 ]; then echo 'validation failed' return 1 fi enabled="$(get_bool "${enabled}" 1)" log_stderr="$(get_bool "${log_stderr}" 0)" log_stdout="$(get_bool "${log_stdout}" 0)" rxtx_report="$(get_bool "${rxtx_report}" 0)" if [ ${enabled} -eq 0 ]; then return 1 fi case "${mode}" in test|dev|prod) ;; *) return 1 ;; esac # Only one probe may present the key: wait until the atlas-sw-probe # one is taken over and atlas is disabled. While the key is not taken # over, log the wait, as at boot the takeover runs before the log # daemon and its errors are lost. if [ -e /etc/uci-defaults/80-ripe-atlas ]; then if [ ! -s "${key}" ] && { [ -s /usr/libexec/atlas-probe-scripts/etc/probe_key ] || [ -s /etc/atlas/probe_key ]; }; then logger -t ripe-atlas -p daemon.warn \ 'waiting for /etc/uci-defaults/80-ripe-atlas' fi return 1 fi # ripe-atlas-probe or -anchor brings the rest. apk installs it only after # this package started the service, also over an older variant without # this file. [ -f /usr/share/ripe-atlas/variant ] || return 1 echo 'Starting RIPE Atlas' umask 022 setup_environment || return 1 # /etc/ripe-atlas stays root's, so prepare what generic-ATLAS.sh would # otherwise write there: the key, and the registration servers of the # mode, which it copies only when they are missing. if [ ! -s "${key}" ]; then # ssh-keygen would ask before replacing an empty file. rm -f "${key}" "${key}.pub" if ! ssh-keygen -q -t rsa -P '' -C "$(uname -n)" -f "${key}" \ < /dev/null; then logger -t ripe-atlas -p daemon.err "cannot create ${key}" return 1 fi logger -t ripe-atlas -p daemon.notice 'created a new probe key' fi # OpenSSH refuses a private key that others can read. chmod 0600 "${key}" rm -f /etc/ripe-atlas/reg_servers.sh "${cfg}" "${mod}" cp /usr/lib/ripe-atlas/scripts/reg_servers.sh.${mode} \ /etc/ripe-atlas/reg_servers.sh || return 1 : > "${cfg}" if [ ${rxtx_report} -ne 0 ]; then echo 'RXTXRPT=yes' >> "${cfg}" fi echo "${mode}" > "${mod}" procd_open_instance procd_set_param command /usr/sbin/ripe-atlas procd_set_param group ${GROUP} procd_set_param stdout ${log_stdout} procd_set_param stderr ${log_stderr} procd_set_param respawn if [ -x /sbin/ujail ] && user_exists ${MAINU}; then chown ${MAINU}:${GROUP} "${key}" "${key}.pub" procd_set_param user ${MAINU} procd_add_jail ripe-atlas procd_append_param capabilities /usr/share/ripe-atlas/capabilities.json else # procd grants capabilities only through ujail, and without # CAP_NET_RAW ping and traceroute fail. Run as root, like # atlas-sw-probe did; the group still tags the probe processes. logger -t ripe-atlas -p daemon.warn \ "ujail or user ${MAINU} missing, running the probe as root" fi procd_close_instance return 0 } start_service() { config_load 'ripe-atlas' config_foreach validate_config 'ripe-atlas' start_instance } stop_service() { local pids local pid local procs # Up to OpenWrt 25.12, procd signals only the main script; the daemons, # the ssh tunnel and telnetd it started would keep running. Take them # from the instance's cgroup, or, when that holds none, from the group # only the probe uses. for procs in /sys/fs/cgroup/services/ripe-atlas/*/cgroup.procs; do [ -f "${procs}" ] || continue while read -r pid; do pids="${pid} ${pids}" done < "${procs}" done if [ -z "${pids}" ]; then for pid in $(find /proc -maxdepth 1 -type d -group ${GROUP} \ 2> /dev/null); do pids="${pid##*/} ${pids}" done fi if [ -n "${pids}" ]; then kill ${pids} 1>/dev/null 2>&1 fi } # procd would not restart the probe when its options change, and up to # OpenWrt 25.12, when it stops the instance, it signals only the main # script. reload_service() { stop start } registered_id() { awk '$1 == "PROBE_ID" { print $2 }' \ /var/run/ripe-atlas/status/reg_init_reply.txt 2> /dev/null } get_key() { local pub=/etc/ripe-atlas/probe_key.pub local variant local id variant="$(cat /usr/share/ripe-atlas/variant 2> /dev/null)" if [ -z "${variant}" ]; then echo 'Install ripe-atlas-probe or ripe-atlas-anchor first' >&2 return 1 fi if [ ! -s "${pub}" ]; then echo "${pub} is missing, start the probe to create it" >&2 return 1 fi id="$(registered_id)" if [ -n "${id}" ]; then echo "Registered as probe ${id} with:" elif [ "${variant}" = anchor ]; then echo 'Register the anchor at https://atlas.ripe.net/anchors/apply/ with:' else echo 'Register the probe at https://atlas.ripe.net/apply/swprobe/ with:' fi cat "${pub}" } probeid() { local id id="$(registered_id)" if [ -z "${id}" ]; then echo 'The probe has not registered since boot' >&2 return 1 fi echo "Probe ID is ${id}" } service_triggers() { procd_add_reload_trigger 'ripe-atlas' procd_add_validation validate_config }