如何在GCP函数中使用SSH密钥访问第三方服务器
Got it, let's walk through how to get your Cloud Function set up with SSH key auth for that third-party server—since you already have a working VM, we just need to adapt that setup securely for serverless. Here's a practical, production-ready approach:
1. 先把SSH密钥安全存起来(绝对不能硬编码!)
Cloud Functions don’t let you persist files easily, and hardcoding private keys is a huge security no-no. Use GCP Secret Manager to store your private key:
- Head to the Secret Manager console in your GCP project
- Create a new secret, paste the full content of your private key (e.g.,
id_rsa) into the secret value - Grant your Cloud Function's service account the
roles/secretmanager.secretAccessorpermission—this lets the function pull the key when it runs.
2. Load the key in your function and establish the SSH connection
Let’s use Python as an example (the logic translates easily to Node.js or other languages with SSH libraries):
First, list your dependencies in requirements.txt:
paramiko>=2.12.0 # SSH/SFTP library google-cloud-secret-manager>=2.16.0 # To access Secret Manager google-cloud-storage>=2.10.0 # For GCS event-triggered file handling
Then, here's the function code that fetches the key, connects to the server, and uploads a file (assuming you're triggered by a GCS storage event—adjust the file handling part to match your use case):
import paramiko from google.cloud import secretmanager import os from google.cloud import storage def get_secret(project_id, secret_id): # Fetch secret from Secret Manager client = secretmanager.SecretManagerServiceClient() secret_name = f"projects/{project_id}/secrets/{secret_id}/versions/latest" response = client.access_secret_version(request={"name": secret_name}) return response.payload.data.decode("utf-8") def upload_to_ssh_server(event, context): # Configure your values here (use environment variables for production!) GCP_PROJECT = os.environ.get("GCP_PROJECT", "your-project-id") SSH_KEY_SECRET = "your-ssh-private-key-secret-name" REMOTE_HOST = "third-party-server-ip-or-domain" REMOTE_USER = "your-ssh-username" REMOTE_UPLOAD_PATH = "/path/on/server/to/save/file" # 1. Download the triggering file from GCS to /tmp (Cloud Function's temp dir) gcs_client = storage.Client() bucket = gcs_client.get_bucket(event["bucket"]) blob = bucket.blob(event["name"]) local_temp_path = f"/tmp/{event['name']}" blob.download_to_filename(local_temp_path) # 2. Fetch SSH private key from Secret Manager private_key_str = get_secret(GCP_PROJECT, SSH_KEY_SECRET) private_key = paramiko.RSAKey.from_private_key(paramiko.StringIO(private_key_str)) # 3. Establish SSH connection and upload via SFTP ssh_client = paramiko.SSHClient() # Optional: Instead of AutoAddPolicy, store known_hosts in Secret Manager for security ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh_client.connect(REMOTE_HOST, username=REMOTE_USER, pkey=private_key) sftp = ssh_client.open_sftp() sftp.put(local_temp_path, REMOTE_UPLOAD_PATH) print(f"Successfully uploaded {event['name']} to {REMOTE_UPLOAD_PATH}") except Exception as e: print(f"SSH connection/upload failed: {str(e)}") raise e finally: # Clean up connections and temp file if 'sftp' in locals(): sftp.close() ssh_client.close() os.remove(local_temp_path)
3. Important Security & Practical Notes
- Known Hosts Hardening: The
AutoAddPolicy()is convenient but not ideal for production. Instead, copy the line for your third-party server from your VM's~/.ssh/known_hosts, store that as another secret, and load it into the SSH client withssh_client.load_host_keys(paramiko.StringIO(known_hosts_secret)). - Permissions: Double-check that your Cloud Function's service account has:
roles/secretmanager.secretAccessorfor the secretsroles/storage.objectViewerfor the GCS bucket (if using storage events)
- Temp Dir Limits: Cloud Functions have a 512MB limit on
/tmp—if you're uploading large files, consider chunked uploads or streaming directly from GCS to the SSH server instead of saving to temp. - Language Alternatives: For Node.js, use the
ssh2library and@google-cloud/secret-manager—the logic is identical: fetch the key, create an SSH client, use SFTP to upload.
4. If You Need More Flexibility: Cloud Run Alternative
If Cloud Functions' environment feels too restrictive (e.g., you need to cache SSH connections for repeated runs), you can deploy a small Cloud Run service instead. It still uses Secret Manager for the key, but gives you more control over the runtime environment.
内容的提问来源于stack exchange,提问作者Sándor Turánszky

