Introducción
La defensa en profundidad consiste en utilizar varios controles de forma conjunta para que un solo error no deje expuesto un activo importante por sí solo. Una comprobación de token, una vinculación a la red local, los permisos de archivo y el registro de eventos (logging) protegen, cada uno, una parte diferente del mismo servicio.
En este laboratorio, fortalecerá un pequeño servicio en Python que lee un archivo secreto. Realizará un pequeño cambio a la vez, ejecutará el servicio, lo probará con curl y verificará que las capas funcionen juntas.
Comenzar desde un secreto expuesto
En este paso, inspeccionará el servicio y observará el primer control: una solicitud sin el token esperado es rechazada, mientras que una solicitud con el token tiene éxito. La defensa en profundidad comienza comprobando qué está ya protegido y qué necesita otra capa adicional.
Muévase al directorio del proyecto:
cd /home/labex/project
Liste los archivos preparados:
ls -l
Debería ver secret_service.py, secret.txt y service-check.py.
Inicie el servicio en segundo plano. El símbolo & al final le indica al shell que mantenga el servicio en ejecución mientras usted continúa escribiendo comandos:
python3 secret_service.py > service.log 2>&1 &
Guarde el ID del proceso en segundo plano para poder detenerlo limpiamente más tarde:
echo $! > service.pid
Intente leer el secreto sin un token:
curl -i http://127.0.0.1:8081/secret
La respuesta debería incluir 403 Forbidden. Ahora envíe el encabezado de token requerido:
curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret
Debería ver:
Project launch code: ORBIT-742
Detenga el servicio antes de continuar:
kill "$(cat service.pid)"
Ejecute el verificador para la capa de token:
python3 service-check.py token
El resultado esperado es:
token: complete
Mantener el servicio local
En este paso, confirmará la capa de exposición de red. Un servicio que solo necesita acceso local debe vincularse a 127.0.0.1, también conocido como localhost. Esa dirección solo acepta conexiones desde la misma máquina.
Inspeccione la configuración del host predeterminado del servicio:
grep 'default="127.0.0.1"' secret_service.py
Debería ver la definición del argumento para la opción --host. Este valor predeterminado significa que ejecutar python3 secret_service.py inicia el servicio en localhost.
Inicie el servicio de nuevo:
python3 secret_service.py > service.log 2>&1 &
Guarde el ID del proceso:
echo $! > service.pid
Utilice ss para inspeccionar los sockets TCP en escucha. Las opciones -ltn significan escucha (listening), TCP y direcciones numéricas:
ss -ltn | grep ':8081'
La salida debería mostrar 127.0.0.1:8081, lo cual es evidencia de que el servicio es solo local:
LISTEN ... 127.0.0.1:8081 ...
Detenga el servicio:
kill "$(cat service.pid)"
Ejecute el verificador para la capa de localhost:
python3 service-check.py localhost
El resultado esperado es:
localhost: complete
Restringir el archivo secreto
En este paso, añadirá una capa de permisos del sistema de archivos. Incluso si el servicio tiene un error, el archivo secreto no debería ser legible por todas las cuentas locales.
Compruebe los permisos actuales del archivo:
ls -l secret.txt
El archivo comienza con permisos más amplios para que pueda mejorarlos. Utilice chmod 600 para que el archivo sea legible y escribible solo por su propietario:
chmod 600 secret.txt
Compruebe los permisos de nuevo:
ls -l secret.txt
Los bits de permiso ahora deberían comenzar con -rw-------:
-rw------- ... secret.txt
Ejecute el verificador para esta capa:
python3 service-check.py permissions
El resultado esperado es:
permissions: complete
Registrar solicitudes rechazadas
En este paso, probará la capa de detección. Bloquear una solicitud no autorizada es útil, pero registrar ese rechazo proporciona a los operadores evidencia de que alguien intentó acceder a la ruta protegida.
Elimine cualquier archivo de registro antiguo para que este paso comience limpiamente:
rm -f access.log
Inicie el servicio:
python3 secret_service.py > service.log 2>&1 &
Guarde el ID del proceso:
echo $! > service.pid
Envíe una solicitud sin el token:
curl -s http://127.0.0.1:8081/secret
El cuerpo de la respuesta debería ser:
forbidden
Vea el registro de acceso:
cat access.log
El registro debería contener rejected, /secret y missing_or_bad_token.
Detenga el servicio:
kill "$(cat service.pid)"
Ejecute el verificador para la capa de registro:
python3 service-check.py logging
El resultado esperado es:
logging: complete
Verificar las capas en conjunto
En este paso, verificará el resultado completo de la defensa en profundidad. El servicio debe requerir el token, permanecer local de forma predeterminada, proteger el archivo secreto con permisos exclusivos del propietario y registrar las solicitudes rechazadas.
Ejecute el verificador completo:
python3 service-check.py all
Cada capa debería estar completa:
token: complete
localhost: complete
permissions: complete
logging: complete
Inicie el servicio una última vez:
python3 secret_service.py > service.log 2>&1 &
Guarde el ID del proceso:
echo $! > service.pid
Confirme que el secreto sigue funcionando para una solicitud autorizada:
curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret
Debería seguir viendo:
Project launch code: ORBIT-742
Detenga el servicio:
kill "$(cat service.pid)"
Esta comprobación final es importante porque la defensa en profundidad debe proteger el servicio sin interrumpir el uso autorizado previsto.
Resumen
Ha practicado la defensa en profundidad mediante la implementación de controles en capas alrededor de un pequeño servicio. Ha verificado un requisito de token, la vinculación solo local, permisos de archivo exclusivos del propietario y el registro de accesos rechazados.
La lección principal es que cada capa protege un punto de fallo diferente mientras el comportamiento autorizado del servicio sigue funcionando correctamente.



