Skip to content
← Back to the Academy

Story · 4 min read · Part 1 of 3 · Windows + Mac with Claude Code

SSH with a dedicated key, and why I never paste blocks that ask for a password

Getting into the Mac over SSH without a password: own key, alias, hardening with a drop-in, and the mistake of pasting several commands at once.

Spanish only for now · Solo en español por ahora

Todo lo que viene después en esta serie depende de que ssh mac 'comando' funcione desde Windows sin pedir nada. Un agente va a mandar comandos a la Mac cuando yo no esté mirando, y no puede teclear una contraseña. Los comandos exactos están en el paso SSH de la guía; aquí cuento las decisiones y los errores.

Una llave dedicada

Ya tenía una llave ~/.ssh/id_ed25519 que uso para otros servicios. Cuando fui a generar la nueva, estaba a punto de correr ssh-keygen sin la opción -f, y eso la habría sobrescrito. Me di cuenta mirando la pantalla: el comando me mostraba la ruta de la llave existente antes de pisarla. Lo registré como “tropiezo evitado”.

Mi decisión fue generar una llave con nombre propio, id_mac, y sin passphrase. La razón de la passphrase es práctica: Claude Desktop ignora las llaves protegidas con passphrase, y esta llave solo abre la Mac dentro de mi red local. Es un compromiso, no una recomendación general. Si tu llave abriera algo más, ponle passphrase.

El error: pegar un bloque con una contraseña adentro

Para copiar la llave pública a la Mac hay que escribir la contraseña de la Mac una sola vez. Yo pegué varios comandos juntos. Las líneas siguientes entraron como respuesta al prompt Password:, la llave no se copió y ssh mac quedó colgado esperando una contraseña.

La regla que saqué, y que repito a lo largo de toda la guía: nunca pegues un bloque que contiene un prompt de contraseña. Un comando a la vez cuando hay una contraseña de por medio.

El alias y un bloque duplicado

En ~/.ssh/config de Windows definí un alias mac con la IP, el usuario, la llave y dos opciones: IdentitiesOnly yes, para que ssh no pruebe todas mis llaves antes de la correcta (el servidor corta tras pocos intentos fallidos), y ServerAliveInterval 30.

El archivo me quedó con dos bloques Host mac. Funcionaba, y por una razón curiosa: ssh toma el primer valor que encuentra para cada opción, y el segundo bloque aportaba el IdentityFile. Es frágil, y por eso lo dejé anotado como pendiente de limpiar a un solo bloque. En el último estado que revisé, seguía con dos.

Apagar la contraseña

Una Mac con SSH abierto y contraseña habilitada se puede atacar por fuerza bruta desde cualquier equipo de la red. Así que, con la llave funcionando, hay que apagarla. Esto requiere sudo, así que lo hago yo.

El concepto que aprendí aquí: sshd se queda con el primer valor que lee de cada opción, y los archivos de sshd_config.d/ se leen en orden alfabético. macOS ya trae 100-macos.conf. Mi archivo se llama 050-no-password.conf para que se lea antes y gane. No edité /etc/ssh/sshd_config porque las actualizaciones de macOS lo reemplazan.

El procedimiento tiene un orden que importa: escribir el archivo, validar con sshd -t antes de reiniciar el servicio, reiniciarlo, y comprobar con sshd -T. Y no cerrar la sesión abierta hasta confirmar que una conexión nueva entra con la llave.

Cómo verificar sin quedarse colgado

Para comprobar que la contraseña ya no se ofrece, el comando “obvio” (PreferredAuthentications=password con PubkeyAuthentication=no) no sirve desde un agente: se queda esperando una contraseña que nadie va a escribir. La variante que funciona usa NumberOfPasswordPrompts=0 y lee la lista de métodos que el servidor ofrece en el mensaje de error. Antes del hardening, esa lista era publickey,password,keyboard-interactive. Después debe decir solo publickey.

Estado hoy: esto último sigue pendiente. En la última comprobación que hice, el servidor aún ofrecía password,keyboard-interactive. Son cuatro líneas con sudo, y las corro una a la vez.

Una frontera que no se cruza

También probé si el agente podía sacar capturas de la Mac por SSH. No puede: screencapture responde “could not create image from display”. macOS exige el permiso de Grabación de pantalla, y un proceso que llega por SSH no lo tiene. No intenté abrir esa puerta. Las capturas de la interfaz de macOS las saco yo con Cmd+Shift+4.

Lo que me llevo

Llave dedicada con nombre propio, un comando a la vez cuando hay contraseña, y verificar con un comando que no dependa de que alguien conteste. Y una nota para mí: apagar la contraseña es la mitad del trabajo; falta comprobarlo.

Siguiente: la IP de la Mac cambió y ssh mac dejó de responder.