How to Disable GCE’s Automatic User Creation and Enforce Custom SSH Authentication in CoreOS Clusters


2 views

Google Compute Engine's default behavior creates a potential security vulnerability in CoreOS clusters. When any project member authenticates with GCP, they can SSH into instances as virtually any user - a significant security concern for teams.

GCE handles user creation through metadata-based SSH key management. The instance metadata contains SSH public keys that GCE automatically processes to create corresponding user accounts. The process works like this:

1. Instance boots and reads metadata
2. For each SSH key in metadata:
   a. Creates user account if doesn't exist
   b. Adds key to ~/.ssh/authorized_keys
3. Updates occur whenever metadata changes

To disable this behavior and enforce your cloud-config specified users exclusively:

# Disable GCE's automatic account creation
sudo systemctl stop google-accounts-daemon
sudo systemctl disable google-accounts-daemon

# Alternatively, block the metadata server
sudo iptables -A OUTPUT -d metadata.google.internal -j DROP

Here's a complete cloud-config example that creates specific users with controlled access:

#cloud-config
users:
  - name: admin
    groups: sudo,docker
    ssh-authorized-keys:
      - ssh-rsa AAAAB3Nza... admin@workstation
    expire: false
  - name: deploy
    ssh-authorized-keys:
      - ssh-rsa AAAAB3Nza... ci@jenkins
    expire: 2024-12-31

Combine with these security best practices:

# Enable SSH key rotation
chage -M 30 admin

# Disable root login
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config

# Restart SSH service
sudo systemctl restart sshd

After implementation:

# Verify accounts
cat /etc/passwd | grep -v nologin

# Check running services
systemctl list-units | grep google

# Test SSH access
ssh -i ~/.ssh/deploy_key deploy@your-instance

Google Compute Engine automatically provisions users through its metadata server when instances boot. This occurs via the following workflow:


1. Instance boots and requests metadata from http://metadata.google.internal
2. The metadata server provides SSH keys from project/instance metadata
3. These keys are injected into ~/.ssh/authorized_keys for corresponding users
4. Users are created on-the-fly when first authenticating

This "just-in-time" user creation means any valid Google identity with appropriate IAM permissions can SSH as any username that doesn't already exist in /etc/passwd.

The automatic user provisioning creates several security concerns:

  • No centralized control over user accounts
  • No password expiration policies
  • Difficulty auditing access (since users are ephemeral)
  • Project-level access grants too much privilege

To disable this behavior in CoreOS, we need to modify the cloud-init configuration:

#cloud-config

write_files:
  - path: /etc/ssh/sshd_config.d/disable-gce-users.conf
    permissions: 0600
    owner: root:root
    content: |
      # Disable GCE metadata-based auth
      AuthorizedKeysCommand none
      AuthorizedKeysCommandUser nobody

users:
  - name: admin
    groups: sudo,docker
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2E... user@example.com
    lock-passwd: false
    passwd: $6$rounds=5000$N1yqR2dX$wW0Z6...

For proper user control, implement these additional measures:

# Set up PAM module for password expiration
auth required pam_faillock.so preauth audit silent deny=5 unlock_time=900
auth [success=1 default=bad] pam_unix.so
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900

# Weekly cron job to enforce password changes
0 0 * * 0 /usr/bin/passwd -e admin

Complement the technical controls with proper IAM configuration:

  • Use project-level SSH key restrictions
  • Implement granular IAM roles (avoid primitive roles)
  • Enable OS Login for managed identities
  • Set up VPC Service Controls for additional isolation

After implementation, verify the configuration:

# Check SSH config
sudo sshd -T | grep AuthorizedKeysCommand

# Verify user creation attempt fails
gcloud compute ssh unauthorized-user@instance --project=your-project