Qué hace Turnout en tu Mac

Turnout instala un servicio que se ejecuta como root, así que aquí tienes una explicación exacta de lo que hace y de cómo comprobarlo: qué es el servicio, qué cambia, qué guarda y a qué se conecta, cada cosa con una forma de verla en tu propio Mac.

Dos partes: una app y un servicio en segundo plano

La app, Turnout.app, se ejecuta con tu usuario, sin privilegios especiales. Muestra tus túneles, edita configuraciones y pide al servicio en segundo plano que los conecte y desconecte. Nunca toca tu tráfico de red.

El servicio en segundo plano es un LaunchDaemon, cc.ctsite.turnout.daemon, que se ejecuta como root. Su programa, turnout-daemon, está dentro de la app, en /Applications/Turnout.app/Contents/MacOS/. Turnout lo registra mediante los ítems de inicio de macOS (SMAppService), así que macOS te pide que lo permitas en Ajustes del Sistema › General › Ítems de inicio y extensiones, y puedes desactivarlo ahí.

El servicio crea la interfaz utun de cada túnel y ejecuta WireGuard en espacio de usuario con GotaTun, una implementación de Mullvad con licencia MPL-2.0, integrada en el servicio. Solo los paquetes del túnel pasan por él; el resto de tu tráfico lo enruta macOS como siempre. Los túneles siguen activos cuando cierras la app, porque viven en el servicio.

Qué cambia y con qué herramientas

Las direcciones, la MTU, las rutas y el DNS se cambian con los programas que usa wg-quick en macOS. Cada uno se ejecuta directamente con sus argumentos, nunca a través de un shell.

/sbin/ifconfig
Las direcciones y la MTU de la interfaz del túnel, y su activación.
/sbin/route
Las rutas hacia el túnel, la ruta que mantiene la dirección del servidor en tu red física y las rutas que evitan el túnel.
/usr/sbin/networksetup
Los servidores DNS y dominios de búsqueda de tus servicios de red.

Así, los comandos de siempre muestran exactamente lo que hizo:

netstat -rn
networksetup -listallnetworkservices
networksetup -getdnsservers Wi-Fi   # u otro servicio de la lista

Cuando un túnel se desconecta, el servicio quita las rutas que añadió y restaura la configuración de DNS que había reemplazado.

Tus configuraciones

Los túneles se guardan en /Library/Application Support/cc.ctsite.turnout/tunnels, una carpeta que pertenece a root, un archivo por túnel con permisos 0600, claves privadas incluidas. Solo el servicio escribe ahí; la app le pide que guarde.

sudo ls -l "/Library/Application Support/cc.ctsite.turnout/tunnels"

Hooks

PreUp, PostUp, PreDown y PostDown se ejecutan como root, mediante /bin/bash -c, con %i sustituido por la interfaz utun del túnel y %I por su nombre. Eso es tanto poder como sudo, así que:

  • Los hooks solo salen de un archivo de configuración en disco, nunca de nada que la app envíe al servicio.
  • Guardar una configuración con hooks nuevos o cambiados requiere la aprobación de un administrador. El servicio comprueba esa aprobación por sí mismo, con Authorization Services de macOS; no se fía de lo que diga la app.
  • Los cambios que no tocan los hooks no necesitan una nueva aprobación.

Lee los hooks de una configuración antes de aprobarlos, como harías con un script que ejecutas con sudo.

A quién responde el servicio

La app habla con el servicio por un socket Unix, /var/run/cc.ctsite.turnout.daemon.sock. Con cada programa que se conecta, el servicio comprueba su firma de código y solo responde a un programa firmado por el mismo equipo de desarrollo con el identificador de paquete de Turnout, cc.ctsite.turnout. Los demás programas se rechazan.

Después de un fallo

Cuando el servicio se detiene, macOS elimina la interfaz del túnel, y las rutas que tenía desaparecen con ella. Las rutas por tu puerta de enlace física y la configuración de DNS no, y el DNS configurado así sobrevive incluso a un reinicio. Por eso el servicio anota cada cambio en un registro antes de hacerlo y, en su siguiente arranque, deshace lo que dejó una ejecución anterior. Hasta terminar no conecta ningún túnel, y Turnout muestra lo que sigue pendiente, con Restaurar ahora.

Turnout › Reparar ajustes de red… hace lo mismo cuando lo pides. Si el servicio no está en marcha, pide una contraseña de administrador y aplica el registro por su cuenta.

Conexiones de red

Por las actualizaciones, la app en sí se conecta a dos sitios: GitHub, para ver si hay una versión nueva, y Google Analytics, para contar la instalación. Por la licencia se conecta a Polar, cuando has comprado una, y a tu cuenta de iCloud; La licencia, más abajo, dice cuándo y con qué.

  • Solo la copia de /Applications comprueba por su cuenta, como mucho una vez por hora, cuando abres el menú o una ventana. Turnout › Buscar actualizaciones… comprueba cada vez que lo eliges.
  • La comprobación pide un archivo pequeño de la última versión de este proyecto en GitHub. No lleva ninguna cuenta ni nada sobre ti o tus túneles. GitHub ve la solicitud y tu dirección IP.
  • Con cada comprobación, la app envía un evento a Google Analytics (www.google-analytics.com, mediante su Measurement Protocol): un identificador de instalación aleatorio que Turnout crea la primera vez que se usa y guarda en sus preferencias, nunca derivado del hardware; la versión y la compilación de Turnout; la versión de macOS; la arquitectura del procesador; el idioma del sistema; y dos campos que Google Analytics necesita para contarlo, un número de sesión tomado de cuándo se abrió Turnout y un tiempo de interacción fijo. Nada sobre túneles, servidores, claves o redes, y ninguna cuenta ni identificador de usuario. Google ve la solicitud y tu dirección IP, según la Política de privacidad de Google.
  • Al desactivar Buscar actualizaciones automáticamente en General (Turnout › Ajustes…) se detienen tanto la comprobación automática como el informe. Buscar actualizaciones… sigue comprobando cuando lo eliges, sin enviar ningún informe.
  • Si instalas una actualización, el instalador sale de la misma versión, y Turnout comprueba su suma de verificación y su firma Developer ID antes de pasarlo al instalador de macOS.

Tus túneles se conectan a los servidores de tus configuraciones, y tus hooks hacen lo que escribiste en ellos. Aparte de eso, ni la app ni el servicio se conectan a ningún sitio: sin informes de fallos propios, sin publicidad, sin cuenta.

La licencia

Turnout funciona completo durante una prueba de 7 días en cada Mac, y 7 días más una vez si los pides; después, conectar un túnel necesita una licencia. Solo conectar: los túneles conectados siguen conectados, y desconectar, editar, importar, exportar, Reparar ajustes de red… y desinstalar funcionan siempre. Nunca se desconecta nada por motivos de licencia.

La licencia vive en la app. El servicio en segundo plano no sabe nada de ella y nunca se conecta a Polar ni a iCloud.

  • Durante la prueba no se comprueba ninguna licencia. Las fechas de la prueba se guardan en el llavero de este Mac, en un elemento llamado cc.ctsite.turnout.license, que se queda al desinstalar Turnout, así que instalar de nuevo no empieza otra prueba.
  • Cuando has comprado, la app llama al servicio de licencias de Polar, api.polar.sh, al activar este Mac (la clave, el nombre que le das al Mac, su identificador de modelo, las versiones de macOS y de Turnout y un hash unidireccional de su identificador de hardware); más o menos una vez por semana cuando abres el menú o la ventana, y cuando la compruebas a mano (la clave, el identificador de activación de este Mac y el hash); y al quitar un Mac (la clave y el identificador de activación de ese Mac). Sin cuenta, y nada sobre tus túneles.
  • Si no se puede llegar a Polar, no cambia nada: un Mac con licencia sigue conectando, por mucho tiempo que pase sin conexión, y el panel Licencia solo dice cuándo se confirmó la licencia por última vez.
  • La clave y la lista de Mac que la usan se guardan como registros en el área de Turnout de tu cuenta de iCloud (CloudKit), así que tus otros Mac con la misma cuenta encuentran la licencia y la usan con un clic. La app los lee al abrirse y cuando abres su menú o su ventana, y solo los escribe después de una activación, una comprobación o una retirada. Se guardan con la protección estándar de iCloud de Apple, sin cifrado de extremo a extremo. Un Mac sin sesión iniciada en iCloud no sincroniza nada; en él, la clave se introduce a mano.

Todo lo que se envía, y a quién, está en la política de privacidad; los términos, en Términos de la licencia.

Ubicación y reglas de Wi-Fi

Una regla de Wi-Fi (#@ OnWiFi) necesita el nombre de la red a la que está conectado el Mac. macOS considera ese nombre información de ubicación, así que solo una app con acceso a la ubicación puede leerlo. Turnout pide acceso cuando configuras una regla de Wi-Fi, nunca al abrirse, y solo lo usa para el nombre de la red, nunca para saber dónde estás. Los nombres que pongas se quedan en el archivo de configuración de tu Mac. Sin acceso, las reglas de Wi-Fi no hacen nada.

Registros

/Library/Logs/cc.ctsite.turnout.daemon.log
Lo que hizo el servicio en segundo plano, y sus errores.
/Library/Logs/cc.ctsite.turnout.update.log
Se escribe al instalar una actualización.

Ayuda › Mostrar registros en el Finder muestra los dos archivos. Los mensajes de la propia app están en el registro del sistema:

/usr/bin/log show --predicate 'subsystem == "cc.ctsite.turnout"' --last 1h

En zsh hace falta la ruta completa, porque log a secas es otro comando integrado.

Compruébalo tú mismo

launchctl print system/cc.ctsite.turnout.daemon   # el servicio, tal como lo ve launchd
ls -l /Applications/Turnout.app/Contents/MacOS/    # Turnout y turnout-daemon
cat /Applications/Turnout.app/Contents/Resources/uninstall.sh
defaults read cc.ctsite.turnout analyticsClientID  # el identificador de instalación aleatorio
netstat -rn
networksetup -getdnsservers Wi-Fi

El desinstalador es un script de shell dentro de la app. Léelo antes de ejecutarlo.

Desinstalar

Hay tres formas, y todas ejecutan ese mismo script:

  • Con la ventana de Turnout abierta, elige Turnout › Desinstalar Turnout…. En la confirmación, Eliminar también los túneles guardados y sus claves privadas los borra también. En un Mac con licencia, primero quita este Mac de tu licencia y borra su registro de tu cuenta de iCloud (en la confirmación puedes elegir no hacerlo).
  • Abre el instalador y, donde lista lo que se va a instalar, elige Remove Turnout, y también Delete saved tunnels si lo quieres (por ahora el instalador solo está en inglés).
  • En Terminal, añadiendo --purge para borrar también los túneles guardados:
    sudo sh /Applications/Turnout.app/Contents/Resources/uninstall.sh

Cada una desconecta todos los túneles, lo que restaura las rutas y el DNS; quita el servicio en segundo plano de Ítems de inicio; deshace lo que haya dejado un servicio que falló; y borra la app, sus registros, el recibo del instalador y, para cada usuario, las preferencias, el estado de las ventanas y las cachés de Turnout. Los túneles guardados y sus claves privadas, en /Library/Application Support/cc.ctsite.turnout, se quedan salvo que elijas borrarlos.

El elemento de licencia del llavero se queda, así que instalar de nuevo no empieza otra prueba, y la clave se queda en tu cuenta de iCloud para tus otros Mac. El instalador y el script de Terminal se ejecutan como root, sin acceso a tu llavero ni a tu cuenta de iCloud, así que no pueden quitar este Mac de tu licencia: hazlo antes en el panel Licencia, o después desde otro Mac o en el portal de clientes de Polar.