8 min de lectura

¿Puede la transferencia de entorno SSH filtrar contexto local?

La transferencia de entorno SSH puede exponer contexto local a órdenes remotas. Audita SendEnv y AcceptEnv y prueba una lista exacta.

¿Puede la transferencia de entorno SSH filtrar contexto local?

La transferencia de entorno SSH puede filtrar mucho más contexto local del que necesita una tarea remota. El canal está cifrado, pero el cifrado solo protege el trayecto. No convierte AWS_PROFILE, GIT_AUTHOR_EMAIL, el nombre de un inquilino ni una opción interna en entradas apropiadas para un proceso de otra máquina.

Trato cada variable transferida como un argumento de la orden remota. Por tanto, necesita un nombre, un motivo, un responsable y una prueba. Un comodín copiado de una configuración SSH cómoda para un portátil no cumple ese criterio, porque su significado cambia cada vez que alguien añade una variable local coincidente.

El objetivo seguro no es un entorno remoto vacío. sshd, la cuenta de acceso, el intérprete y los envoltorios crean su propia base. El objetivo es más preciso: el cliente aporta exactamente las variables de trabajo recogidas en un contrato escrito, el servidor no acepta un conjunto más amplio y una prueba comprueba tanto los valores necesarios como los señuelos rechazados.

La transferencia solo ocurre si ambos extremos SSH están de acuerdo

La transferencia de entorno de OpenSSH tiene dos barreras. En el cliente, SendEnv selecciona nombres del entorno del proceso local, mientras que SetEnv del cliente proporciona pares literales NOMBRE=VALOR. En el servidor, AcceptEnv decide qué nombres enviados por el cliente entran en el entorno de la sesión. Por regla general, un nombre solo cruza cuando el cliente lo ofrece y el servidor lo acepta.

RFC 4254 describe el mecanismo que hay debajo de esos ajustes. Antes de iniciar el intérprete o la orden, el cliente puede enviar una petición de canal SSH de tipo env que contiene un nombre de variable y un valor. El RFC también advierte que configurar el entorno sin control puede ser peligroso en un proceso privilegiado y recomienda usar una lista permitida o esperar a que se hayan reducido los privilegios. Esa advertencia forma parte de la especificación del protocolo.

Los manuales de OpenSSH añaden una excepción que suele confundir las auditorías: cuando el cliente solicita un pseudoterminal, TERM siempre se envía y se acepta porque el protocolo la necesita. Ejecuta la automatización con ssh -T cuando no necesite terminal. Así eliminas de este camino el comportamiento del terminal, las sorpresas del inicio interactivo y TERM.

De este acuerdo se desprenden cuatro observaciones.

  • Un SendEnv amplio permanece inactivo contra un servidor que no acepta nada, pero entra en vigor en cuanto un administrador amplía AcceptEnv.
  • Un AcceptEnv amplio permanece inactivo para un cliente cuidadoso, pero cualquier usuario autorizado puede conectarse con otra configuración y proporcionar un valor coincidente.
  • Ningún extremo puede imponer por sí solo todo el contrato cuando hay personas que controlan ambas configuraciones.
  • Que una orden termine bien no dice qué peticiones de entorno rechazó el servidor.

El último punto importa. OpenSSH puede ignorar una variable ofrecida y continuar la sesión. Si un despliegue funciona porque el intérprete remoto ya define el mismo nombre, una prueba que solo comprueba el valor final puede atribuir a la transferencia un valor que nunca se entregó.

Los comodines convierten el estado local futuro en entrada remota

SendEnv WORKFLOW_* no significa «las variables que revisé hoy». Significa todos los nombres coincidentes presentes en el entorno de cada proceso SSH futuro. Seis semanas después, alguien puede añadir WORKFLOW_DEBUG_DUMP, WORKFLOW_CUSTOMER o WORKFLOW_TOKEN_FILE a su perfil. La antigua regla SSH adquiere comportamiento nuevo sin avisar.

La transferencia de configuración regional muestra cómo se propaga. Muchas configuraciones de estación de trabajo envían LANG y LC_* para que una sesión interactiva muestre bien el texto. Puede ser razonable para un acceso humano, pero no pertenece automáticamente a una cuenta de compilación o despliegue no interactiva. Esos valores pueden cambiar la ordenación, las clases de caracteres, las fechas y los diagnósticos. Una tarea que analice la salida puede fallar sin que se filtre secreto alguno.

Los patrones con más riesgo son los que parecen espacios de nombres prácticos:

  • AWS_* puede incluir perfiles, regiones, datos relacionados con credenciales y rutas de configuración.
  • GIT_* puede transportar identidad, trazas, directorios de objetos alternativos o el comportamiento de askpass.
  • CI_* suele mezclar etiquetas de compilación inocuas con contexto del proveedor y rutas temporales.
  • LC_* parece cosmético hasta que un script depende de una intercalación o unos mensajes estables.
  • APP_* suele crecer con la aplicación y rara vez tiene un único significado de seguridad.

No clasifiques un espacio de nombres como seguro. Clasifica nombres concretos. Puede que DEPLOY_REGION sea necesaria y AWS_PROFILE sea contexto de la estación. Puede que BUILD_REF sea necesaria mientras GIT_CONFIG_COUNT cambia la configuración de Git en ejecución. El prefijo común organiza, pero no crea una frontera de confianza.

Los valores también revelan contexto sin ser credenciales. Una ruta muestra un nombre de usuario y la estructura del repositorio. Un perfil identifica una cuenta o un entorno. Una opción de trazas puede hacer que una herramienta remota imprima datos de órdenes en un registro compartido. Después, un agente puede usar ese contexto en otras acciones aunque la primera orden solo lo mostrara. La filtración incluye influencia y divulgación no deseadas, no solo cadenas secretas.

Una excepción que parece segura puede ampliarse meses después

La deriva de configuración suele crear esta filtración sin un único cambio temerario. Primero, alguien añade SendEnv APP_* a un bloque porque una prueba necesita APP_COLOR=0. El servidor lo rechaza y no ocurre nada. Más tarde, un administrador añade AcceptEnv APP_* para otro equipo que necesita dos ajustes en el mismo servidor compartido. Ambos cambios superan su revisión local porque cada revisor solo ve la mitad del acuerdo.

La siguiente conexión une las dos reglas inactivas. El intérprete local ya contiene APP_CUSTOMER=acme-lab, APP_TRACE=1 y APP_CONFIG=/Users/lee/work/private/config. El cliente SSH ofrece las cuatro variables y el demonio las acepta. Un envoltorio de diagnóstico ejecuta env cuando falla la publicación y guarda la salida en un registro legible por el grupo. No se copió ningún token, pero identidad local, contexto del cliente, una ruta y una opción de trazas cruzaron la frontera sin aprobación.

Quitar el comodín del servidor corrige las sesiones futuras, pero no borra el registro ni indica qué órdenes vieron los valores. Trata el hallazgo como un incidente pequeño:

  1. Deja de aceptar el patrón amplio y valida la configuración del demonio.
  2. Identifica cuentas, clientes y periodo en que coincidieron ambos patrones.
  3. Busca en los registros remotos aprobados los nombres expuestos, no sus valores sensibles.
  4. Decide si cada valor cambió la conducta de la orden o reveló contexto a otro usuario.
  5. Sustituye el comodín por nombres exactos y añade señuelos para las clases rechazadas.

Por eso «el servidor lo rechaza ahora» no defiende una regla amplia del cliente. La configuración inactiva no tiene responsable cuando se activa. Elimina las ofertas innecesarias del cliente aunque el servidor sea estricto, y elimina la aceptación innecesaria del servidor aunque los clientes actuales sean prudentes.

También ocurre la deriva inversa. Un servidor lleva años aceptando LC_* para usuarios interactivos. Una actualización de la imagen de automatización instala una configuración de cliente que envía LC_*. La tarea de despliegue hereda LC_COLLATE elegido por un desarrollador y genera otro orden de archivos. No hay una divulgación que escalar, pero el mismo acuerdo causó un fallo de integridad. Revisa juntos confidencialidad y comportamiento.

Inspecciona la configuración que SSH usará de verdad

Lee la configuración evaluada del cliente antes de editar un archivo. ssh -G de OpenSSH aplica bloques Host y Match, inclusiones y configuraciones de usuario y sistema, y después imprime el resultado para el destino indicado. El archivo que parece autoritativo puede perder frente a un valor anterior o ganar entradas de una inclusión.

Ejecuta esto desde la misma cuenta y contexto que el flujo de trabajo:

ssh -G deploy-prod |
  awk '$1 == "sendenv" || $1 == "setenv" { print }'

Un resultado inseguro representativo tiene este aspecto:

sendenv LANG
sendenv LC_*
sendenv AWS_*
setenv WORKFLOW_KIND=deploy

ssh -G no imprime los valores actuales seleccionados por SendEnv, sino las reglas efectivas. Eso es mejor para una revisión porque la salida no vuelca credenciales. También significa que la revisión queda incompleta hasta comparar los nombres o patrones con el entorno del proceso que inicia SSH.

Captura los nombres sin sus valores:

env | sed 's/=.*//' | LC_ALL=C sort > local-env.names
grep -E '^(LANG|LC_|AWS_|WORKFLOW_)' local-env.names

La expresión regular es una ayuda de inspección, no una política reutilizable. Adáptala a todos los patrones de ssh -G. Si un supervisor, IDE, agente o tarea programada inicia SSH, inspecciona el entorno de ese proceso y no tu intérprete interactivo. La herencia sigue el árbol de procesos; probar desde el padre equivocado ofrece una respuesta limpia pero irrelevante.

Revisa el servidor por separado. En OpenSSH, sshd -T comprueba e imprime los ajustes efectivos. Proporciona criterios de conexión cuando haya bloques Match:

sudo sshd -T \
  -C user=deploybot,host=deploy.example,addr=192.0.2.44 |
  grep '^acceptenv'

Usa el usuario, host y dirección reales de la conexión revisada. Conserva la dirección de documentación del ejemplo solo en ejemplos. Ejecuta también sudo sshd -t antes de recargar el demonio; validar la sintaxis cuesta poco y endurecer el entorno no justifica romper el acceso.

Un archivo de cliente dedicado hace legible la lista permitida

Separa credenciales de entradas remotas
Sallyport guarda la clave SSH; tu lista SendEnv exacta sigue controlando el contexto.

Para automatización, la configuración más fiable es un archivo SSH pequeño pasado con -F. El manual indica que el archivo explícito sustituye el archivo normal del usuario y hace que se ignore el archivo general del sistema. Así una actualización del puesto o de la flota no puede añadir comodines regionales al flujo.

Host deploy-prod
    HostName deploy.example
    User deploybot
    IdentityFile ~/.ssh/deploy_ed25519
    IdentitiesOnly yes
    RequestTTY no
    SendEnv DEPLOY_REGION
    SendEnv BUILD_REF
    SetEnv WORKFLOW_KIND=deploy

Invócalo de forma explícita:

ssh -F ./deploy-ssh.conf deploy-prod /usr/local/bin/release

SendEnv lee el valor del entorno del proceso ssh local. Úsalo cuando el valor cambie legítimamente en cada ejecución. SetEnv del cliente fija un literal en la configuración. Resérvalo para una etiqueta constante no secreta, no para una credencial ni para un valor que alguien olvidará actualizar.

OpenSSH permite además que un patrón SendEnv con prefijo - borre nombres seleccionados antes. Sirve para reparar una configuración por capas:

Host deploy-prod
    SendEnv -*
    SendEnv DEPLOY_REGION BUILD_REF

La limpieza afecta a las selecciones acumuladas hasta ese punto. Una inclusión o regla posterior puede volver a añadir nombres. Por eso no uso la sustracción como frontera final. Un archivo dedicado pasado con -F tiene menos piezas y produce una configuración que otra persona entiende en una pantalla.

No metas credenciales en este contrato. Un token transferido se convierte en estado normal del proceso remoto y puede llegar a procesos hijos, trazas, informes de fallos, inspección de /proc cuando los permisos lo permitan o una ejecución accidental de env. SSH protege el transporte, no la vida del valor después de la entrega.

El servidor debe aceptar nombres exactos para una cuenta limitada

El servidor es el último sitio donde rechazar una variable del cliente antes de iniciar la sesión. OpenSSH no acepta ninguna por defecto, salvo el tratamiento de TERM con pseudoterminal. Mantén ese valor global y añade nombres exactos solo para la cuenta propietaria del flujo.

Match User deploybot
    AcceptEnv DEPLOY_REGION
    AcceptEnv BUILD_REF
    AcceptEnv WORKFLOW_KIND

No uses AcceptEnv APP_*, AcceptEnv AWS_* ni un comodín desnudo. El manual de sshd_config avisa expresamente de que algunas variables pueden eludir entornos de usuario restringidos. Es fácil ignorarlo cuando los nombres actuales parecen inocuos, pero el comodín concede nombres futuros sin otro cambio del servidor.

Un AcceptEnv global amplio debilita todas las cuentas coincidentes. Añadir un bloque Match User más estrecho no borra nombres ya aceptados globalmente; las entradas pueden acumularse. Si los usuarios interactivos necesitan configuración regional y una cuenta de despliegue no debe recibirla, no empieces con una regla regional global. Limita la excepción a los usuarios o grupos y comprueba cada conexión con sshd -T -C.

SetEnv del servidor es otro control. Define valores en sesiones hijas y prevalece sobre valores predeterminados o suministrados mediante AcceptEnv o PermitUserEnvironment. Úsalo cuando el servidor sea dueño de una constante. Si todas las ejecuciones deben usar el mismo valor aprobado por el servidor, configúralo allí en lugar de aceptarlo del cliente.

PermitUserEnvironment es otra vía. Controla ~/.ssh/environment y opciones environment= en claves autorizadas, y OpenSSH lo desactiva por defecto. Una auditoría limitada a AcceptEnv puede pasarlo por alto. Déjalo apagado salvo que el diseño de una cuenta lo exija; entonces incluye sus patrones en la misma revisión.

Una lista de nombres exactos controla nombres, no valores. Un DEPLOY_REGION permitido puede contener espacios, metacaracteres, un salto de línea o una región prohibida. El protocolo lo lleva como datos, pero el script receptor puede convertirlo después en sintaxis mediante eval, una expansión sin comillas, una configuración generada o una cadena de orden.

Valida cada valor en el punto de entrada remoto:

case ${DEPLOY_REGION-} in
    us-east-1|us-west-2) ;;
    *)
        printf 'invalid DEPLOY_REGION\n' >&2
        exit 64
        ;;
esac

case ${BUILD_REF-} in
    [0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]*)
        ;;
    *)
        printf 'invalid BUILD_REF\n' >&2
        exit 64
        ;;
esac

Usa una validación que corresponda al contrato real. El patrón breve ilustra la forma; si una publicación exige un identificador completo, impón su longitud exacta y comprueba que el repositorio lo contiene. No hagas un validador tan permisivo que solo rechace cadenas vacías.

Después de editar, inspecciona el resultado efectivo:

sudo sshd -t
sudo sshd -T \
  -C user=deploybot,host=deploy.example,addr=192.0.2.44 |
  grep -E '^(acceptenv|permituserenvironment|setenv)'

Guarda esta salida con la revisión. Registra lo que el demonio interpretó para la conexión probada, algo más útil que la captura de un fragmento en un directorio lleno de inclusiones.

Demuestra valores necesarios y señuelos rechazados en remoto

Sabe qué proceso lo pidió
La primera tarjeta de aprobación muestra primero la autoridad de firma del proceso.

Una prueba útil comprueba casos positivos y negativos dentro del proceso remoto. Asigna marcadores inconfundibles a cada valor requerido, define señuelos que habrían coincidido con patrones antiguos, inicia una sesión no interactiva con el archivo dedicado y haz que el intérprete remoto falle si se incumple el contrato.

Esta secuencia espera del cliente solo DEPLOY_REGION, BUILD_REF y el valor fijo WORKFLOW_KIND:

export DEPLOY_REGION='env-audit-region'
export BUILD_REF='env-audit-ref'
export AWS_PROFILE='must-not-cross'
export LC_AUDIT_CANARY='must-not-cross'
export APP_PRIVATE_PATH='must-not-cross'

ssh -F ./deploy-ssh.conf -T deploy-prod 'sh -s' <<'REMOTE'
set -eu

test "$(printenv DEPLOY_REGION)" = 'env-audit-region'
test "$(printenv BUILD_REF)" = 'env-audit-ref'
test "$(printenv WORKFLOW_KIND)" = 'deploy'

for name in AWS_PROFILE LC_AUDIT_CANARY APP_PRIVATE_PATH; do
    if printenv "$name" >/dev/null 2>&1; then
        printf 'unexpected forwarded variable: %s\n' "$name" >&2
        exit 1
    fi
done

printf '%s\n' 'SSH environment contract passed'
REMOTE

La salida esperada es una línea:

SSH environment contract passed

Haz una segunda prueba negativa eliminando un valor local obligatorio. SendEnv no puede enviar un nombre ausente, así que la aserción remota debe fallar:

unset BUILD_REF
if ssh -F ./deploy-ssh.conf -T deploy-prod 'test -n "$BUILD_REF"'; then
    printf '%s\n' 'test failed: BUILD_REF appeared unexpectedly' >&2
    exit 1
fi

Esto distingue un valor opcional de una entrada necesaria. Si la tarea debe fallar sin BUILD_REF, falla también antes de SSH con ${BUILD_REF:?BUILD_REF is required}. La comprobación remota sigue siendo necesaria porque verifica el transporte y detecta un rechazo del servidor.

Los señuelos deben cubrir cada comodín o clase dudosa encontrada. Usa valores obviamente falsos. Nunca pongas una credencial real en una prueba de filtración: un fallo puede imprimirla en los registros mientras confirma el riesgo.

Una ejecución correcta no demuestra que ninguna variable imaginable pueda cruzar. Demuestra los casos negativos nombrados bajo una configuración y un entorno. Combínala con dos controles estáticos: ssh -G solo debe contener nombres exactos y sshd -T -C solo los AcceptEnv previstos. Si aparece * o ?, ninguna matriz puede enumerar lo que añadirá un entorno futuro.

Ejecuta la prueba desde cada iniciador distinto. Un intérprete de desarrollador, un trabajador de CI, una tarea del editor y un agente autónomo pueden invocar el mismo binario con rutas y entornos distintos. Registra la ruta del archivo dedicado en el iniciador, no en un alias interactivo.

También hay diferencia entre observar el entorno final y demostrar la contribución SSH. Si /etc/profile define DEPLOY_REGION=us-east-1 y el cliente envía lo mismo, la aserción pasa aunque el servidor lo rechace. Usa marcadores únicos que no existan en la base remota y ejecuta el caso de entrada ausente. Juntos descubren un valor obligatorio rechazado y un valor remoto de reserva.

La prueba no afirma que el entorno remoto solo contenga tres variables. Una sesión normal recibe HOME, USER, SHELL, PATH y metadatos SSH, y los inicios o envoltorios pueden añadir más. La aserción prueba que la parte aportada por el cliente coincide con el contrato. Audita aparte la base del servidor si la orden necesita un entorno total mínimo.

Construir la orden puede evitar SendEnv por completo

Vaciar SendEnv no impide que un intérprete expanda variables locales dentro de la cadena remota. Esta es otra ruta de datos:

ssh deploy-prod "release '$TENANT' '$TOKEN'"

El intérprete local sustituye ambos valores antes de ejecutar ssh. Viajan dentro de la petición cifrada de orden, no en una petición env, por lo que AcceptEnv no puede rechazarlos. También pueden aparecer en inspección de procesos, historial, registros de CI o errores según cómo se construya y registre la orden.

Este prefijo afecta al proceso SSH local, pero solo cruza si la configuración selecciona el nombre:

DEPLOY_REGION=west ssh -F ./deploy-ssh.conf deploy-prod /usr/local/bin/release

Los equipos confunden ambos casos. Que estuviera en el entorno cuando se ejecutó SSH no prueba que se transfiriera; desactivar SendEnv tampoco prueba que un envoltorio no lo interpolara en argumentos o entrada estándar. Sigue el canal real.

El código de inicio remoto crea otra fuente. Un intérprete, /etc/environment, PAM, una orden forzada, sudo, un gestor de servicios o un contenedor pueden quitar, reemplazar o añadir valores después de que SSH los acepte. Si falta un marcador, usa ssh -vvv para ver decisiones del cliente, los registros permitidos del servidor y una orden mínima anterior al envoltorio. No amplíes AcceptEnv de inmediato: suele ocultar la capa que cambió el valor.

sudo merece una revisión propia. Según sudoers, puede reiniciar el entorno, conservar nombres o permitir que se solicite su conservación. Eso solo cambia lo que llega al hijo privilegiado. El valor ya llegó a la sesión SSH sin privilegios, donde scripts, ganchos y envoltorios pudieron verlo. Configura sudoers para la orden privilegiada, pero limita SSH antes de esa capa.

El host remoto tampoco es una tubería pasiva. Quien controla la cuenta suele poder imprimir su entorno, y un administrador controla la máquina. Transferir un valor lo revela al dominio remoto por diseño. Si tu argumento exige que el host nunca conozca un valor, no lo envíes mediante SSH de ninguna forma.

Evita volcados de env en registros habituales. Durante una auditoría autorizada, captura primero nombres y revela valores solo para marcadores falsos. Un volcado completo convierte variables ajenas en material de auditoría y puede crear el incidente que intentabas evitar.

El SSH ejecutado por agentes necesita un límite de proceso menor

Mantén las claves SSH fuera del agente
Sallyport ejecuta SSH mediante sp-ssh y el agente nunca recibe la clave SSH.

Un agente autónomo suele heredar el entorno del terminal, editor u orquestador que lo inició. Ese entorno se preparó para una persona que trabaja con varios repositorios y cuentas. Enviar sus espacios de nombres al host da al agente más contexto y a las herramientas remotas entradas que nadie revisó.

Inicia el flujo con un entorno local explícito y un archivo SSH explícito. Un envoltorio mínimo puede exigir los dos valores cambiantes, descartar el estado heredado y restaurar solo lo que necesita el cliente:

#!/bin/sh
set -eu
: "${DEPLOY_REGION:?DEPLOY_REGION is required}"
: "${BUILD_REF:?BUILD_REF is required}"

exec env -i \
  HOME="$HOME" \
  PATH='/usr/bin:/bin:/usr/sbin:/sbin' \
  DEPLOY_REGION="$DEPLOY_REGION" \
  BUILD_REF="$BUILD_REF" \
  ssh -F ./deploy-ssh.conf deploy-prod /usr/local/bin/release

Ajusta PATH y las entradas necesarias al sistema operativo y mantén la lista explícita. HOME aparece porque OpenSSH puede necesitar archivos de usuario, como hosts conocidos y la ruta de identidad. Si un ejecutor gestionado los proporciona de otro modo, quita también HOME.

Para SSH operado por agentes en un Mac, Sallyport puede mantener la clave SSH en su almacén cifrado y ejecutar mediante sp-ssh, de modo que el agente no recibe la credencial. Eso cambia la custodia, pero no excusa un contrato vago; conserva la prueba de nombres exactos alrededor de la orden permitida.

No transfieras credenciales locales de nube como atajo. Si la acción remota necesita otro servicio, dale una identidad propia y limitada o enrútala por una pasarela que guarde la credencial. Copiar la credencial ambiental del operador a un proceso remoto une fronteras de confianza y complica la revocación.

Mantén el contrato ejecutable cuando cambie la configuración

Las reglas de entorno derivan porque los paquetes añaden valores, los administradores consolidan fragmentos y los flujos adquieren entradas. Una norma escrita no detectará esa deriva. Revisa juntos el archivo dedicado, la configuración de cuenta y la aserción de señuelos.

Ejecuta la aserción tras cambios en estas superficies:

  • Paquetes del cliente SSH o del sistema operativo
  • Inclusiones de configuración de usuario y sistema
  • sshd_config, PAM, inicios del intérprete u órdenes forzadas
  • El iniciador del agente, ejecutor de CI, gestor de servicios o imagen
  • La lista de entradas requeridas por el flujo

Trata una variable nueva como un cambio de interfaz. Documenta por qué la necesita la orden, quién posee el valor, si contiene contexto sensible y qué prueba demuestra su ausencia en otros sitios. Si nadie responde, pásala como entrada validada o rediseña la acción en vez de ampliar un comodín.

Haz que el fallo sea evidente. Un despliegue que recurre a un valor remoto por defecto cuando se rompe la transferencia es más difícil de diagnosticar y más fácil de usar mal que uno que se detiene. Las entradas obligatorias deben fallar en el iniciador local y en el punto remoto.

Por último, revisa la cuenta desde el lado remoto. Una lista perfecta no protege una cuenta que ejecuta intérpretes arbitrarios, lee entornos ajenos o reescribe sus inicios. La transferencia es un canal de entrada. Hazlo exacto, demuestra su conducta y limita la autoridad de la orden para que un valor inesperado no se convierta en otra acción.

FAQ

¿SSH envía todas las variables locales por defecto?

No. OpenSSH envía los nombres seleccionados por SendEnv y los valores literales de SetEnv; el servidor normalmente debe aceptarlos con AcceptEnv. Un pseudoterminal aplica un tratamiento especial a TERM.

¿Qué diferencia hay entre SendEnv y SetEnv?

SendEnv toma el valor actual de una variable del proceso SSH local. SetEnv del cliente define un par literal NOMBRE=VALOR, por lo que sirve para una etiqueta fija no secreta, no para una entrada por ejecución.

¿Puede AcceptEnv recibir una variable que el cliente no envió?

No. AcceptEnv permite una petición, pero no crea el valor. El mismo nombre puede proceder de configuración del servidor, PAM, inicios o envoltorios, así que identifica su origen antes de cambiar SSH.

¿Es seguro transferir LANG y LC_*?

Puede ser aceptable para cuentas interactivas, pero es más amplio de lo que necesita la automatización. Los valores regionales cambian ordenación, análisis y diagnósticos; limita las tareas a nombres exactos o fija el comportamiento en el servidor.

¿Puedo eliminar reglas SendEnv heredadas?

OpenSSH acepta un patrón SendEnv con prefijo - para borrar selecciones anteriores. Reglas posteriores pueden añadirlas de nuevo, así que un archivo dedicado con ssh -F resulta más fácil de auditar.

¿Cómo veo qué reglas SendEnv se aplican a un host?

Ejecuta ssh -G host desde la cuenta del flujo y filtra sendenv y setenv. Muestra las reglas evaluadas después de coincidencias e inclusiones, pero no los valores actuales.

¿Por qué falta una variable transferida en el host remoto?

Puede estar ausente localmente, no seleccionada, rechazada por el servidor o eliminada por una capa posterior. Prueba cada barrera en ese orden y usa un marcador falso antes de ampliar AcceptEnv.

¿ssh -T detiene toda transferencia de entorno?

No. -T desactiva el pseudoterminal, evitando la ruta de TERM y el comportamiento interactivo. Otros nombres seleccionados y aceptados todavía pueden cruzar.

¿Son seguras las variables de entorno para credenciales SSH?

Son un mal transporte. Una vez aceptada, la credencial es estado del proceso remoto y puede llegar a hijos, registros, diagnósticos o superficies de inspección; usa una identidad remota o una pasarela que custodie credenciales.

¿Con qué frecuencia debo probar la transferencia de entorno SSH?

Ejecuta la aserción de señuelos cuando cambien paquetes, configuraciones, ajustes del demonio, iniciadores, imágenes o entradas. Inclúyela en la revisión normal para detener el cambio antes de producción.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov