rap/lib/exec/init

146 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# lib/exec/init
#
# Copyright (c) 2020- RAP <contacto@partidopirata.com.ar>
# Copyright (c) 2011-2016 LibreVPN <vpn@hackcoop.com.ar>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General
# Public License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
#
# Crea un nuevo nodo
. "${RAP_LIBDIR}"/common
requires tincd
# Opciones
# ConnectTo
connectto=""
# Address
address=""
# Port
port=""
# Instalar
install=false
# Modo verborrágico por defecto
verbose=true
force=false
# Procesar los flags (ver doc)
while getopts 'dvhifp:l:a:c:' arg; do
case $arg in
h) help $self; exit 0 ;;
q) verbose=false ;;
i) install=true;;
f) force=true ;;
p) port="$OPTARG" ;;
l) localnet="${localnet} $OPTARG" ;;
a) address="${address} $OPTARG" ;;
c) connectto="$connectto $OPTARG" ;;
esac
done ;
let OPTIND--; shift $OPTIND
# Obtener el nombre del host
# Exportamos para post comandos
export NODE="$(get_node_name "${1:-$HOSTNAME}")"
if test -z "${NODE}" ; then
fatal_error "Se necesita un nombre de nodo"
fi
# Podríamos usar get_node_dir pero chequea si ya existe, cosa que no
nodedir="${RAP_DIR}/nodos/${NODE}"
nodefile="${nodedir}/hosts/${NODE}"
conffile="${nodedir}/tinc.conf"
# Con -f se eliminan los archivos anteriores pero se guarda una copia
if $force; then
rm -rf "${nodefile}~" "${nodedir}~"
mv "${nodefile}"{,~}
mv "${nodedir}"{,~}
fi
$verbose && msg "Creando %s..." "*${NODE}*"
if test -f "${nodefile}" ; then
fatal_error "El nodo ya existe! Utilice -f para re-crearlo"
fi
$verbose && msg "Creando %s..." "*${nodedir}*"
if test -d "${nodedir}" ; then
fatal_error "El directorio del nodo ya existe"
fi
# Crea los directorios de hosts y scripts
mkdir -p "${nodedir}"/{hosts,scripts} || fatal_error "No se pudo crear el directorio"
$verbose && msg "Generando %s..." "*${nodefile}*"
if test ! -z "${address}" ; then
for _a in ${address}; do
add_to_file "${nodefile}" "Address = ${_a}"
done
else
$verbose && warning "El nodo no tiene una dirección pública, se configura como nodo privado"
# Cuando no tenemos una dirección pública probablemente estemos detrás
# de un firewall, esto le indica a los demás nodos que no traten de
# conectarse directamente sino que nos envíen paquetes a través de un
# nodo al que estemos conectadxs.
add_to_file "${nodefile}" "IndirectData = yes"
PORT=$(until test ${r:-0} -gt 20000; do r=${RANDOM}; done; echo $r)
$verbose && msg "Utilizando puerto al azar %s" "*${PORT}*"
fi
add_to_file "${nodefile}" "Port = ${port:-${PORT}}"
$verbose && msg "Generando %s..." "*${conffile}*"
add_to_file "${conffile}" "Name = ${NODE}"
add_to_file "${conffile}" "Mode = switch"
add_to_file "${conffile}" "GraphDumpFile = /tmp/${NETWORK}.dot"
# Copiar los scripts de inicio
$verbose && msg "Copiando el resto de archivos..."
install -Dm 750 "${RAP_SKELDIR}/run-script" "${nodedir}/run-script"
for s in up down ; do
install -Dm 750 "${RAP_SKELDIR}"/tinc-${s} "${nodedir}"/tinc-${s}
done
$verbose && msg "Añadiendo hosts..."
if test -n "${connectto}" ; then
${RAP} connectto ${NODE} ${connectto}
fi
$verbose && msg "Generando llaves..."
echo -e "\n" | tincd -c "${nodedir}" --generate-keys=${KEYSIZE}
# Sólo guardar el host si podemos escribir en hosts
if test -w "${RAP_HOSTS}"; then
$verbose && msg "Guardando el archivo de host con los demás nodos"
cp -f "${nodefile}" "${RAP_HOSTS}"
fi
# Instalar el terminar
$install && ${RAP} install ${NODE}
msg "El nodo se ha creado con éxito"
# Chequeamos si hay hook para post comando
run_post_script
exit 0