Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lethal Trifecta Mitigation Demo

This demo shows how to use Tailscale device posture attributes and Aperture to help mitigate the lethal trifecta.

Its web interface creates user-owned EC2 machines in one of two network classes:

  • noegress machines receive custom:hasEgress=false when their single-use device auth key is created.
  • open machines receive the custom:hasEgress=true attribute.

The example tailnet policy grants members access to devices tagged tag:aperture, with the Aperture connectors gated by device posture: a device with the explicit custom:hasEgress=false value may use both label:noCustomerData and label:hasCustomerData connectors, while a device with custom:hasEgress=true is limited to label:noCustomerData.

Layout

cmd/egressd/          web service that allows users to create EC2 instances
cmd/allowlist/        discovers the Tailscale control and DERP endpoints for Terraform
terraform/            creates the egress-restricted infrastructure, and an optional jump host
tool/terraform        downloads, verifies, and runs a pinned Terraform release
policy.hujson         example posture-gated tailnet policy

The restricted VPC allows TCP 443 only to the Tailscale control and DERP IPv4 and IPv6 addresses discovered during each Terraform plan or apply, plus the regional S3 IPv4 and IPv6 prefix lists. A default-deny Route 53 Resolver DNS Firewall permits only the corresponding Tailscale hostnames and the four S3 names: the regional and dual-stack endpoints, each plain and bucket-qualified.

The Tailscale .deb package is staged in an endpoint-scoped S3 bucket because restricted machines cannot reach the package repository.

Setup

The operator host needs Go, AWS credentials, Bash, curl, jq, unzip, and either sha256sum or shasum.

  1. Create the infrastructure:

    tool/terraform -chdir=terraform init
    tool/terraform -chdir=terraform apply

    To include the isolated SSH jump host, also set jump_host_enable=true, an existing aws_key_name, and at least one of jump_host_ssh_cidrs or jump_host_ssh_ipv6_cidrs.

    Terraform downloads a pinned Tailscale package, verifies its hash, and stages it in the S3 bucket during the apply. To upgrade the package, update the version, URL, and checksum in terraform/bootstrap_s3.tf.

  2. Apply policy.hujson to a test tailnet, and add Aperture to the tailnet with the tag:aperture tag.

  3. Get a Tailscale API access token from the console: https://console.tailscale.com/admin/settings/keys

  4. Create a device-provisioning OAuth app with the callback URL and allowed node attributes:

    curl -X POST "https://api.tailscale.com/api/v2/tailnet/-/oauth-apps" \
      -u "<api-access-token>:" \
      -H "Content-Type: application/json" \
      -o oauth-credentials.json \
      -d '{
        "name": "lethal-trifecta-mitigation-demo",
        "redirectUris": ["http://localhost:8080/oauth/callback"],
        "scopes": ["auth_keys:create:once"],
        "allowedNodeAttributes": ["custom:hasEgress"]
      }'

    Custom posture attributes require a supported Tailscale plan.

  5. Run the service:

    export TS_OAUTH_APP_CLIENT_SECRET=tskey-app-...
    go run ./cmd/egressd \
      --region us-east-2 \
      --deb-url "$(tool/terraform -chdir=terraform output -raw bootstrap_deb_url)"

    Open http://localhost:8080, choose a machine class, and complete the Tailscale consent screen. Set --aws-key-name when using the jump host.

What to observe

Create one machine of each class. In the Tailscale admin console, the restricted device has custom:hasEgress=false; the open device has custom:hasEgress=true instead. From the restricted machine, TODO something about Aperture, but it cannot reach the internet. The open machine can reach the internet but cannot TODO something about Aperture.

Future work

The restricted VPC currently allows Tailscale's public DERP servers. A root-level agent could join another tailnet—using, for example, a reusable auth key supplied through prompt injection—and regain internet access through an exit node there.

Deployments concerned about this attack can run a custom DERP server with --verify-clients, admit only devices from the intended tailnet, and allowlist only that DERP instead of the public servers.

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages