1 puntos por GN⁺ 2025-02-09 | 1 comentarios | Compartir por WhatsApp
  • Fly.io intentó integrarse con el flujo de edición remota por SSH de VSCode y comprobó que VSCode, en lugar de usar de forma ligera el shell remoto, instala y ejecuta un agente aparte
  • La generación de código con LLM es más útil dentro de un bucle de agente conectado al entorno de ejecución, pero como puede llegar a tocar incluso la configuración del sistema de la laptop de desarrollo, hace falta una instancia Linux aislada
  • Tramp de Emacs amplía sus funciones a entornos remotos ejecutando comandos de Bourne shell en entornos interactivos como SSH, pero VSCode descarga un agente y un binario de Node mediante un stager de snippets Bash
  • El agente de VSCode se ejecuta sobre SSH con reenvío de puertos y establece una conexión WebSockets con el frontend de VSCode, lo que le permite explorar archivos, editar archivos arbitrarios, ejecutar una PTY de shell y mantenerse persistente
  • Solo permitir edición remota de VSCode en un servidor de desarrollo ya implica una carga considerable, y si este enfoque se usa durante un incidente en producción la preocupación es mayor; aun así, para la conexión personalizada de Fly Machine se pudo evitar esta estructura

El aislamiento necesario para los bucles de agentes con LLM

  • Fly.io se interesó en integrarse con el flujo con el que VSCode realiza edición remota por SSH
    • Porque hay muchos usuarios de VSCode y, en especial, porque se están usando forks de VSCode que generan código con LLM
  • El código generado por LLM es útil cuando sabe qué está haciendo el usuario, y se vuelve aún más eficaz si puede cerrar el bucle con el entorno de ejecución
    • El LLM genera código
    • El andamiaje del agente ejecuta el código
    • El código genera errores
    • El agente devuelve los errores al LLM
    • Este proceso se repite
  • Esta estructura puede ser un antídoto a medias efectivo contra las alucinaciones, pero es riesgosa para ejecutarla tal cual en una laptop de desarrollo
    • El LLM puede tocar repetidamente no solo el proyecto Git en el que se está trabajando, sino también la configuración del sistema
  • Una mejor forma es ejecutar una configuración de agente de bucle cerrado en una instancia Linux limpia que se levanta al instante e impedir que ese entorno pueda perjudicar al usuario

Cómo funciona el agente SSH remoto de VSCode

  • Tramp de Emacs es código Elisp que se acerca a ser el ancestro espiritual de los sistemas de edición remota
    • Si se conecta a un entorno interactivo donde se pueden ejecutar comandos de Bourne shell, como una sesión SSH, extiende las funciones de Emacs a ese entorno
  • VSCode también tiene una función parecida a Tramp, pero no es una estructura que simplemente haya trasladado una versión simplificada de Tramp a TypeScript
  • En lugar de usar solo herramientas existentes en la conexión remota, VSCode ejecuta un stager de snippets Bash para descargar un agente
  • El agente funciona sobre SSH con reenvío de puertos y crea una conexión WebSockets con el frontend de VSCode en ejecución
    • El subprotocolo puede recorrer el sistema de archivos
    • Permite editar archivos arbitrarios
    • Puede ejecutar su propio proceso PTY de shell
    • Puede persistirse a sí mismo
  • Hay un nombre que la industria de seguridad usa para una herramienta que funciona de esta manera, pero no se dice directamente porque sería injusto con VSCode
  • Permitir edición remota de VSCode en un servidor de desarrollo genera inquietud, y si se usa el mismo enfoque durante un incidente en producción la preocupación aumenta
  • Al crear una conexión personalizada para Fly Machine no fue necesario preocuparse por esta estructura, así que, en un sentido profundo, consideraron que no era un problema importante

1 comentarios

 
GN⁺ 2025-02-09
Opiniones en Hacker News
  • Intenté escribir durante más o menos un mes un texto largo sobre software con el que llevaba 3 o 4 años trasteando, pero Kurt se puso nervioso porque no había publicado nada en el blog desde agosto, así que al final decidí escribir el post más simple posible.
    La idea era hacer lo contrario de lo que venía haciendo: escribir un post de bajo esfuerzo, y pensé que podía sacar uno en 30 minutos. Esto fue simplemente poner por escrito algo con lo que había estado jugando, y probablemente lo pensé menos que quienes lo leyeron.

    • Después de leer el post por fin entendí que esta arquitectura no tiene ningún sentido, pero solo con la entrada del blog no me cayó la ficha de inmediato. Al ver la lista de cosas que podía hacer el agente, asumí que no podía ir por ese lado.
      La frase del README, “A compromised remote could use the VS Code Remote connection to execute code on your local machine.”, era mucho más clara, y siento que junto a esta advertencia de seguridad debería haber un número de CVE.
    • Creo que el primer párrafo del comentario en HN se habría leído mejor si no hubiera tenido ni un solo punto. Me alegra que un blog que me gusta siga vivo; justo me estaba preocupando un poco.
      Los dos primeros posts que se ven ahora, el de McCord-Valim sobre FLAME-Livebook-GPU y este que contiene “murid”, muestran muy bien la trayectoria psicológica de un desarrollador.
    • Ojalá publique más posts de bajo esfuerzo.
    • El problema quizá sea ssh. Al conectarse por ssh debería haber una forma de pedir una experiencia tipo Docker, y estaría bueno poder especificar que se use una API que bloquee procesos o accesos al sistema de archivos fuera de una carpeta concreta.
      Se podrían permitir binarios del sistema, pero eso se vuelve complejo y quizá obligue a VSCode a meter más cosas en el cliente. Buscando por encima, aparecen opciones de chroot del lado del servidor ssh, pero el manual del cliente ssh no dice mucho al respecto.
      O quizá la solución sea descargar un contenedor Docker en el remoto, ejecutar un contenedor con el directorio remoto montado y luego conectarse por ssh a ese contenedor.
      El problema de sincronizar solo los archivos de un subdirectorio es que también se necesita la ejecución remota y la depuración iniciadas por VSCode. Por eso los plugins también necesitan acceso remoto o deben ejecutarse en el remoto, y para cierta observación de código, si se ejecuta en local, el costo de sincronizar previamente todo el subdirectorio puede ser demasiado alto.
    • El enfoque de “simplemente decidimos volver a ser un blog. Así que tuvimos que aprender esto, y ahora tú también tienes que aprenderlo” es justamente el camino correcto.
  • Puede sonar ingenuo, pero no entiendo bien por qué esto es un problema de seguridad. Si puedes conectarte por ssh a una máquina y hacer reenvío de puertos por socket, en la práctica ya tienes permiso para hacer todo lo demás, y el protocolo de VSCode parece exponer eso de una forma cómoda para ellos.
    Me pregunto si la razón por la que es un problema de seguridad es que alguien que está en la misma red que la máquina remota, pero no tiene permisos de SSH, puede conectarse al puerto reenviado por SSH. Como usuario, el sistema SSH de VSCode me gusta bastante porque funciona bastante bien.

    • La diferencia es que lo que hace VSCode no es una sesión SSH como la que obtienes con el comando ssh o con PuTTY.
      VSCode instala un agente remoto en la máquina destino, usa ssh como protocolo de transporte y dice que va a compartir ese transporte con el usuario. Si solo hace lo que uno quiere, no hay problema, pero un sistema basado en agentes que expone APIs arbitrarias crea una superficie de ataque y un riesgo mucho mayores que la forma conocida, aunque todavía delicada, de imitar una terminal sobre ssh.
    • El punto clave es que el agente se ejecuta sobre SSH con reenvío de puertos y establece una conexión WebSocket con el frontend de VSCode en ejecución.
      El protocolo sobre esa conexión puede recorrer el sistema de archivos, editar archivos arbitrarios, levantar su propio proceso PTY de shell y hacerse persistente. Que el cliente se conecte por ssh a un servidor remoto no significa que ese servidor pueda ejecutar código arbitrario en el cliente; como mínimo, el cliente tendría que realizar explícitamente alguna acción.
    • En lo básico, es cierto. Esto no es, en esencia, una vulnerabilidad ni un cruce de un límite de seguridad.
      Pero sí es un problema de seguridad en el mismo sentido en que “curl | bash” es un problema de seguridad. Una analogía más cercana podría ser curl | bash dentro de bashrc.
    • El agente del servidor de desarrollo ahora se convierte en un vector inverso de vuelta hacia VS Code en la laptop.
      Como el agente está conectado a la red y siempre en ejecución, un agujero en el firewall del servidor de desarrollo pasa a ser un agujero en el firewall de la laptop.
    • Claro, los permisos ya existen. El problema es que ahora un agente de terceros puede usar esos permisos a su antojo, y el usuario quizá no se dé cuenta.
  • Cuanto más sabes de cómo funciona VSCode, más parece algo apenas sostenido con cinta adhesiva y las ideas más malditas que se le podrían ocurrir a un desarrollador JavaScript.
    Solo mirando la extensión SSH, hay dos formatos de URI para espacios de trabajo: uno que básicamente solo tiene el nombre del host y otro que es un documento JSON codificado en hexadecimal. Este último se usa cuando se necesita información adicional, como un nombre de usuario concreto, o cuando el nombre del host contiene mayúsculas.
    La razón por la que esto es realmente necesario es que, por algún motivo, cuando se guarda en espacios de trabajo recientes se convierte a minúsculas.
    La conexión SSH también admite configurar extensiones que se instalarán en el servidor, pero si pones demasiadas no puede conectarse a hosts Windows. Las pasa como argumentos de línea de comandos a través de CMD, y CMD tiene un límite de 8191 caracteres, y desde ese CMD llama a PowerShell.

    • VS Code era mejor que Eclipse. Nunca necesité SSH a través de un IDE, así que no sé sobre esa parte; normalmente me conectaba por SSH con PuTTY y, si tenía que trabajar en el servidor, usaba Vi.
    • Si sabes JavaScript/TypeScript, es muy bueno lo fácil que es agregar al editor soporte para lenguajes personalizados o herramientas.
      Puedes ofrecer autocompletado personalizado, diagnósticos, etc., y también crear un Go to definition personalizado para soporte entre lenguajes.
    • Hay unas líneas que son de las más desafortunadas que me vienen a la mente cuando pienso en algo hecho con cinta adhesiva: https://github.com/microsoft/vscode/blob/6dbde2a3ed308f88164...
      Ojalá Microsoft me contratara solo por unos meses, me sentara en un rincón y me dejara desenredar este desastre.
    • Parecía algo armado con basura y cordeles, así que volví a vim.
  • Administré servidores para clases de redes, exploits binarios y programación de sistemas introductoria, y esta cosa es un gran dolor de cabeza. Por culpa de este tonto troyano de acceso remoto, los estudiantes no entienden cómo usar el cliente OpenSSH
    Intenté varias cosas para solucionarlo. En el motd del servidor de la clase escribí que no usaran el plugin de servidor remoto de VSCode, y frente a la clase ejecuté ncdu /home para mostrar que cualquier estudiante cuyo uso de disco en el servidor superara los 100 MB era, sin excepción, usuario de VSCode
    También puse un límite de 45 procesos por usuario, porque por alguna razón el troyano de acceso remoto de VSCode usa alrededor de 50 procesos de Node. Si los estudiantes ignoraban el motd y las advertencias en clase, caían en el límite y tenían que pedirnos que matáramos sus procesos para poder conectarse de nuevo
    Al final cambié el límite de procesos por un script que mata todos los troyanos de acceso remoto .vscode-server cada 10 segundos

    • Me recuerda mucho a cuando estaba en la universidad y esquivaba las restricciones anacrónicamente estrictas que los administradores de sistemas de la escuela habían puesto en la red
    • Esto no pasa solo porque VSCode sea popular. Hace más de 10 años, cuando estaba en la universidad, también había estudiantes que usaban Sublime con un plugin SFTP, o que programaban localmente y transferían archivos con un cliente GUI como FileZilla
      En una clase en la que fui ayudante, había una tarea que consistía en procesar código máquina básico para imitar las herramientas de ensamblado y ejecución de la ISA que habíamos aprendido, y los estudiantes tenían que entender la estructura de bytes de los archivos con cosas como hexdump
      Pero Sublime “amablemente” renderizaba los archivos objeto como una representación textual tipo hexdump, agregando espacios para mejorar la legibilidad, y los mostraba en un orden de endianidad distinto al que se veía al hacer hexdump en el servidor Linux de la escuela
      Cada semestre algunos estudiantes venían a preguntar por qué el código que habían escrito para leer una cadena ASCII como AD DE EF BE encontraba texto desconocido, y era porque no habían comprobado que los bytes reales empezaran con 0xDE, 0xAD, 0xBE, 0xEF
    • Me pregunto por qué había que llegar tan lejos. Entiendo que se esforzaron mucho por bloquear VSCode, pero no queda claro qué causaba concretamente VSCode
    • 50 procesos de Node, cada día estamos más lejos de Dios
    • Si te preguntabas a qué se refiere “murid” aquí y tampoco habías oído RAT antes, RAT es la sigla de Remote Access Trojan
  • No tengo muy claro cuál es la alternativa aquí. La edición por SSH de VSCode funciona sorprendentemente bien, y hace mucho dejé de andar peleándome con vim, nano o micro en máquinas remotas
    El agente me deja trabajar en silencio y sin estorbar. Se siente casi como trabajar en mi máquina local, y para mí eso es una gran ventaja
    Puede ser un riesgo de seguridad, pero la experiencia de desarrollo no tiene comparación. No me importa mucho qué otros editores esté matando VSCode; solo necesito que la herramienta me deje trabajar sin estorbar

    • La alternativa se parece más al enfoque que propone TRAMP. Hasta donde sé, TRAMP trata lo remoto como un sistema de archivos de red, no como un host de ejecución
      No despliega binarios; lee y escribe bytes a través de pipes, y toda ejecución significativa ocurre localmente. En particular, no crea persistencia: no es lo mismo que “el plugin de VSCode pueda acceder mientras estás conectado por SSH” a que “el plugin de VSCode pueda acceder para siempre”
    • El riesgo de seguridad viene de que plugins no verificados tengan acceso ilimitado al editor
    • Por lo que he visto, los colegas que usan VSCode quedan limitados de formas que no perciben, y no tienen idea de lo buena que podría ser una forma mejor
      Cuando trabajan con varios remotos, a menudo no saben a cuál están conectados ni cuál es el estado de la conexión. La terminal es lenta y la persistencia del estado de la sesión es irregular
      Es una experiencia mucho peor que usar tmux y un editor de texto decente. Además, el servidor es muy pesado y no se cierra correctamente, así que es común que terminen con seis instancias del servidor levantadas
      La mitad de las actualizaciones se rompen, y a veces pierden una hora porque no saben entrar al host con un cliente ssh real y limpiar el servidor de vscode roto
    • No sé exactamente qué funciones ofrece VSCode, pero para varias tareas de edición remota sshfs funciona bastante bien. Básicamente debería ser parecido a VSCode
    • TRAMP de Emacs también es bastante malo, pero aun así es más estable y amigable para el usuario que el desastre de la edición remota de VSCode
  • ¿Qué aprendimos? ¿Que existe la ejecución remota de código? ¿Que la confianza mal puesta en herramientas de desarrollo suele terminar en arrepentimiento? ¿Que el diseño de software moderno es un desastre? Todo eso era obvio con un poco de cuidado.
    SSH es una solución de los 90. Es Telnet con algunas funciones agregadas y, aunque se le llame shell “segura”, literalmente es menos segura que Telnet+TLS.
    La gente que decidió que, como ya tenía un túnel con una sesión de usuario en el servidor, no hacía falta crear un transporte de red para aplicaciones ni un protocolo de conexión segura por separado, terminó montando sobre SSH toda clase de cosas raras pero celebradas.
    Es el resultado de abandonar conceptos aprendidos de los sistemas operativos distribuidos, ignorar la autenticación y autorización avanzadas desarrolladas desde entonces, y adoptar lo peor y más fácil.
    Que exista este tipo de “SSH agent” no es absurdo. No nos movimos para crear la herramienta correcta para el trabajo, así que seguimos metiendo cada vez más cosas en una herramienta existente que no fue diseñada originalmente para eso. No tenemos derecho a hacernos los sorprendidos.
    Este es el mundo que construimos. Lo construimos todos, con nuestro trabajo o con nuestra complicidad silenciosa. Aunque no sea SSH, pasa lo mismo en la política, el comercio, la escuela y todo lo demás. Vivimos todos los días en el montón que nosotros mismos levantamos, y cada día que no hacemos nada es otra palada encima. No puedes tener la pala en la mano y fingir que esto es sorprendente o una locura.

    • Esto no lo hicieron los desarrolladores, sino los responsables de seguridad de red. Si bloqueas todos los puertos salientes excepto HTTPS y ssh, entonces todo lo demás inevitablemente se tunelizará sobre HTTPS o ssh.
      Por eso, si en general permites conexiones HTTPS salientes, lo correcto sería permitir también todas las conexiones salientes excepto SMTP. El tráfico malicioso real de todos modos se tunelizará por HTTPS, y el único efecto restante es obstaculizar el despliegue de protocolos nuevos que no carguen con la complejidad e ineficiencia de los túneles.
    • En cambio, la autenticación con par de claves SSH y los certificados me parecen de los mejores métodos de autenticación que conozco. También se integra con FIDO2 sin configuración previa.
      Ojalá los inicios de sesión web se parecieran más a la forma en que lo hace SSH.
    • Esto suena a una teoría conspirativa fuerte. No todo en el mundo funciona por malicia; la mayoría de las veces la gente intenta hacer lo mejor que se le ocurre bajo presión.
      Salir de vez en cuando a tocar pasto le hace bien al alma. Y también estaría bueno que propusieras cómo crear un protocolo SSH mejor. Quejarse sin crítica constructiva no sirve de mucho.
  • El término “SSH agent” aquí es confuso, porque normalmente se refiere a un daemon que cachea tokens de autenticación.

    • Correcto. VSCode no proporciona un SSH Agent; se comunica con el SSH Agent local. En la práctica es su propia versión de ForwardAgent, con las mismas implicaciones de seguridad.
      Además, ese enfoque rompe el conocido SSH agent de macOS: https://github.com/maxgoedjen/secretive/issues/543
    • Como “SSH Agent” lleva “VSCode” adelante, la distinción queda bastante clara.
  • Estoy totalmente de acuerdo en que usar vscode remote en un servidor de producción es una locura.
    Dicho eso, el resto de las funciones descritas como “absurdas” suenan a funciones esperables.

    • Pensando en las implicaciones de seguridad, me pregunto cuál es el caso de uso de esta función. Supongo que algo como una instancia de staging suficientemente aislada de otros entornos.
  • Llegué a staff engineer en MAANG, y creo que es un nivel difícil de alcanzar solo con Vim básico. Aun así, veo que otros perfiles de alto rendimiento tienden a seguir usando Vim o Emacs.
    Hay muchos desarrolladores excelentes que usan VCode, JetBrains, etc., pero creo que la tendencia a buscar barreras de entrada, desarmar la magia de las herramientas mediante exploración, y valorar proyectos completamente open source, muy modificables e impulsados por la comunidad explica mejor este fenómeno que la funcionalidad o la facilidad de uso.
    Leer lo complejo que es la edición remota de VSCode en realidad me da menos ganas de usar VSCode. Basta con entrar por ssh a la máquina y usar el editor que está en esa máquina.
    La solución de VSCode funciona, pero no es elegante, no es aplicable universalmente y es más fácil que se rompa. Y, con perdón para los usuarios de Emacs, Tramp sigue siendo bastante horrible y netrw tampoco es mejor.

    • Coincido en que Tramp no es excelente, pero hay una solución simple que funciona mejor: watchexec + rsync
      Puedes vigilar rutas de archivos específicas y sincronizar exactamente solo lo necesario. Sigues trabajando en el sistema de archivos local, así que no hay latencia al editar, puedes usar todas tus herramientas locales y la sincronización termina en milisegundos.
      Puedes hacer que los archivos que borras localmente también se borren en remoto, y siempre te queda una copia local después de terminar de trabajar en la máquina remota. En Tramp, eso era algo que siempre había que sincronizar manualmente. Además, es independiente del editor.
      Esta función de VS Code me inquieta ahora que sé lo que realmente hace.
    • Después de unirme a un equipo nuevo centrado en VSCode, he pensado mucho en por qué sigo prefiriendo vim. Mi observación reciente es que las barras de herramientas y otros elementos que llenan la pantalla son demasiado ruidosos visualmente.
      Activé Copilot y aparecieron más barras de herramientas, además de texto entrando volando en el lugar donde quería escribir. Vim simplemente me deja ver el código, pensar y escribir. Con VSCode me cuesta entrar en estado de flow.
      Estoy a mitad de mis 30; en la universidad usaba emacs y en mi primer trabajo cambié a vim. En proyectos Java muy enrevesados usé IntelliJ, pero fuera de eso seguí usando vim.
    • Cuando programaba por hobby me gustaba explorar herramientas y desarmar su magia. Ahora que es mi trabajo, me gusta VSCode. No requiere demasiada configuración ni trasteo, y me permite concentrarme en terminar el trabajo.
      Solo abro vim de vez en cuando cuando necesito manipular texto con regex complejas.
    • El principal engineer y el distinguished engineer de nuestro equipo usaban Vim y Emacs.
  • En vez de funcionar junto con las herramientas remotas existentes, VSCode despliega un agente integral que incluye la instalación de un binario de Node.js, una conexión WebSocket de vuelta al frontend de VSCode y amplias capacidades de acceso al sistema.
    Este agente de VSCode tiene permisos amplios, que incluyen explorar el sistema de archivos, editar archivos, crear procesos PTY de shell e incluso la capacidad de persistirse a sí mismo.

    • No se ve una alternativa razonable para soportar lo que hace VSCode, como ejecutar extensiones que no están instaladas localmente. Puede que no quieras esas funciones, pero forman parte del conjunto de funcionalidades del producto.
    • No queda claro si este problema corresponde a la instancia local de VS Code o a la instancia remota.
      Si es la remota, entiendo que el Tramp de elisp es más liviano en términos de dependencias, pero me pregunto si la superficie de ataque realmente es tan distinta. Es decir, no sé si el binario remoto de Node tiene permisos que no tenga un usuario que ejecuta comandos ssh arbitrarios.
      Si el objetivo original era darle a un LLM todas las llaves de una máquina virtual temporal y descartable, me pregunto si el socket abierto por el agente implica que también puede tocar la máquina del desarrollador que se buscaba aislar.
    • Desde cierto punto de vista, podría decirse que estas son cosas que un sistema operativo moderno debería ofrecer como funciones estándar, y que VSCode está haciendo rodeos porque esas funciones no existen.
      Suena como una idea loca, pero el propio kernel podría ofrecer un servidor web u otro protocolo con cifrado y autenticación, y permitir controlar directamente toda la máquina mediante eBPF. Podría ser un paradigma completamente distinto de control remoto cliente/servidor.
      Claro que también podría ser un agujero de seguridad tan grande como para que pase la Estrella de la Muerte.