El script de inicio de OpenVPN no ejecuta un comando

El script de inicio de OpenVPN no ejecuta un comando

Fondo: Estoy configurando Transmission (v2.93) y OpenVPN (v2.4.6) en una cárcel (una cárcel del complemento FreeNAS 11.1) y quiero agregar un --upscript a OpenVPN que solicitará a Transmission que cambie su puerto de escucha (usando transmission-remoteel programa).

Mi openvpn.confcontiene lo siguiente (entre otros):

verb 4
script-security 2
up /usr/local/etc/openvpn/set_port.sh
up-restart ;only to make the up script be executed on restarts
           ;but disabling this changes nothing

y el set_port.shscript contiene (un script mínimo que aún reproduce el comportamiento):

#!/usr/local/bin/bash
/usr/local/bin/transmission-remote --auth rpc_user:rpc_pass -p 6666 2>&1 > output.txt
echo 'the script itself runs: '$(pwd) $(whoami) > status.txt

El script tiene todos los permisos (777) y el binario ( transmission-remote) tiene todos los permisos. Soy consciente de que la ruta al binario es en realidad un enlace suave, así que lo reemplacé con la ruta real ( /usr/pbi/transmission-amd64/.sbin/transmission-remote), pero el comportamiento que observo es el mismo.

Problema: cuando inicio OpenVPN ( service openvpn start),el guión en síse ejecuta, pero el comando real falla misteriosamente: el puerto no está siendo asignado (verificado revisandoGUI remota de transmisióny el comando genera una salida vacía.
El contenido de los archivos de depuración es el siguiente:
output.txtestá vacío (con y sinstderrredirección)
status.txtdice lo esperado: the script itself runs: /usr/local/etc/openvpn root.

Sin embargo, cuando ejecuto este script manualmente ( ./set_port.sh), dicho comando se completa correctamente: output.txtdirá localhost:9091/transmission/rpc/ responded: "success"y se cambiará el puerto.

¿Qué me estoy perdiendo?

Similaraesta pregunta, excepto que no recibo ningún mensaje de "permiso denegado"; parece que el comando ni siquiera se ejecuta (si echo $(<that command>) > file.txtrecibo un archivo vacío).
Éstetambién está algo relacionado, pero el OP pregunta --client-connecty finalmente resuelve el problema escribiendo rutas completas a los programas que quieren ejecutar; esto no ayudó en mi caso (pero si lo hago echo $(ls /usr/local/bin) > log.txt, la lista de archivos binarios es correcta).

Actualizarpor solicitud de @roaima. Cambié el set_port.sha lo siguiente:

#!/usr/local/bin/bash
exec >debug.txt 2>&1
set -x
echo script is running
/usr/pbi/transmission-amd64/.sbin/transmission-remote  --auth rpc_user:rpc_pass -p 6666 2>&1 > output.txt

luego enjuagado y repetido. El debug.txtarchivo contenía estas líneas:

+ echo script is running
script is running
+ /usr/pbi/transmission-amd64/.sbin/transmission-remote --auth rpc_user:rpc_pass -p 12345
/usr/local/etc/openvpn/test.sh: line 5:  6795 Segmentation fault      /usr/pbi/transmission-amd64/.sbin/transmission-remote --auth rpc_user:rpc_pass -p 12345 2>&1 > output.txt

Respuesta1

mirando la linea

/usr/local/etc/openvpn/test.sh: line 5:  6795 Segmentation fault      /usr/pbi/transmission-amd64/.sbin/transmission-remote --auth rpc_user:rpc_pass -p 12345 2>&1 > output.txt

Parece que sus ejecutables tienen bibliotecas que no coinciden. Vuelva a verificar cómo ha creado su chroot. (No he usado FreeBSD durante años y años, así que no puedo darte consejos sobre cómo hacerlo, lo siento).

Respuesta2

No tengo idea de la falta de coincidencia de bibliotecas que está ocurriendo aquí, especialmente porque todo sucede en una "cárcel de complementos" de FreeNAS y no sé cómo está configurado. Sin embargo, logré solucionar el problema para lograr el objetivo de que OpenVPN configure la transmisión en el enrutamiento.
Nota: la siguiente respuesta NO resuelve el problema del error de segmentación, por lo que no la marcaré como aceptada.

La solución se basa en la siguiente observación: aunque transmission-remotetiene un error de segmentación si lo llama OpenVPN, funciona perfectamente bien si cronlo llama en su lugar:

  1. Déjalo openvpn.confcomo está.

  2. En set_port.sh, en lugar de llamar transmission-remote, almacene el número de puerto en un archivo, por ejemplo así: echo $port > $path/port-id(de aquí en adelante asumiré que la variable pathconduce a la carpeta donde almacenamos los scripts, etc.)

  3. Crea un nuevo script, llamémoslo actually_set.sh, con lo siguiente:

#!/usr/local/bin/bash
if [ -f $path/port-id ]; then
  port=$(cat $path/port-id)
  rm $path/port-id
  transmission-remote -n 'rpc_user:rpc_pass' -p $port
fi
  1. Configure cronpara llamar al script anterior cada minuto. Puse lo siguiente en mi crontab:
    * * * * * /usr/local/etc/openvpn/ports/tp_setter.sh

Respuesta3

Si establece su verbnivel en 3-4, probablemente debería ver advertencias sobre los scripts que no se ejecutan. De forma predeterminada, OpenVPN 2.2+ solo llama a ciertas funciones integradas. Necesitas relajar esto usandoscript-security:

--script-security level

Esta directiva ofrece control a nivel de política sobre el uso de programas y scripts externos por parte de OpenVPN. Los valores de nivel más bajo son más restrictivos, los valores más altos son más permisivos.

Configuraciones para el nivel:

0-- Estrictamente prohibido llamar a programas externos.
1-- (Predeterminado) Llame solo a ejecutables integrados como ifconfig, ip, route o netsh.
2-- Permitir la llamada de ejecutables integrados y scripts definidos por el usuario.
3-- Permitir que las contraseñas se pasen a los scripts a través de variables ambientales (potencialmente inseguras).

Debe asegurarse de haber script-securityconfigurado 2 o 3 (2 si no necesita enviar contraseñas al script, 3 en caso contrario).

información relacionada