כניסה באמצעות אימות מסד נתונים של IAM

בדף הזה מוסבר איך משתמשים וחשבונות שירות יכולים להתחבר למסדי נתונים של Cloud SQL באמצעות אימות מסד נתונים של Cloud SQL IAM. מידע נוסף זמין במאמר אימות IAM.

לפני שמתחילים

כניסה באמצעות אימות אוטומטי של מסד נתונים של IAM

אתם יכולים להגדיר מחבר Cloud SQL שיטפל אוטומטית באימות למופע Cloud SQL בשם משתמש או אפליקציה. המחברים כוללים את שרת ה-proxy ל-Cloud SQL Auth, את מחבר Go, את מחבר Java ואת מחבר Python, שכולם תומכים באימות אוטומטי של מסד נתונים ב-IAM. כשמשתמשים במחבר Cloud SQL עם אימות אוטומטי של מסד נתונים באמצעות IAM, החשבון ב-IAM שמשמש להפעלת המחבר צריך להיות אותו חשבון שמאמת את מסד הנתונים.

כדי להיכנס באמצעות אימות אוטומטי של מסד נתונים של IAM:

שרת proxy ל-Cloud SQL Auth

  1. מבצעים אימות ב- Google Cloud.

    משתמש

    אימות ל- Google Cloud באמצעות Application Default Credentials ‏ (ADC).

    משתמשים בפקודה gcloud auth application-default login. מידע נוסף זמין במאמר בנושא הגדרה של Application Default Credentials.

    חשבון שירות

    כדי לבצע אימות ל- Google Cloud באמצעות ADC עם חשבון שירות, אתם יכולים להתחזות לחשבון שירות או להגדיר מפתח לחשבון שירות. אם רוצים לבצע אימות באמצעות התחזות לחשבון שירות, מחליפים את SERVICE_ACCOUNT_EMAIL_ADDRESS ומריצים את הפקודה הבאה:

    gcloud auth application-default login --impersonate-service-account SERVICE_ACCOUNT_EMAIL_ADDRESS

    מידע נוסף זמין במאמר בנושא הגדרה של Application Default Credentials.

  2. מפעילים את שרת ה-proxy ל-Cloud SQL Auth עם הדגל --auto-iam-authn. מחליפים את INSTANCE_CONNECTION_NAME במחרוזת החיבור שמשמשת לזיהוי מכונת Cloud SQL. אם אתם משתמשים ביציאה שונה מיציאת ברירת המחדל של MySQL, אתם צריכים לציין את מספר היציאה. למידע נוסף על איתור המחרוזת הזו ויצירתה, ראו אפשרויות לאימות של Cloud SQL Auth Proxy.

    ./cloud-sql-proxy --auto-iam-authn INSTANCE_CONNECTION_NAME

    מידע נוסף על הפעלת ה-proxy זמין במאמר הפעלת Cloud SQL Auth Proxy.

  3. כשמוכנים להתחבר למכונה באמצעות שרת proxy ל-Cloud SQL Auth, מתחברים באמצעות לקוח mysql. מחליפים את מה שכתוב בשדות הבאים:

    • HOSTNAME: כתובת ה-IP שבה נעשה שימוש בשרת ה-proxy של Cloud SQL Auth. כברירת מחדל, שרת proxy ל-Cloud SQL Auth משתמש בכתובת המארח המקומי 127.0.0.1, אבל אפשר להקצות כתובת IP אחרת כשמפעילים את שרת proxy ל-Cloud SQL Auth.
    • USERNAME: בחשבון משתמש ב-IAM, זהו כתובת האימייל של המשתמש, בלי הסמל @ או שם הדומיין. לדוגמה, כדי להזין את test-user@example.com, מקלידים test-user. בחשבון שירות, זהו כתובת האימייל של חשבון השירות ללא הסיומת @project-id.iam.gserviceaccount.com.
    • PORT_NUMBER: אופציונלי. אם ציינתם יציאה אחרת במחרוזת החיבור של המופע, צריך לציין את מספר היציאה הזה.

    מריצים את הפקודה הבאה:

    mysql --host=HOSTNAME \
    --user=USERNAME \
    --port=PORT_NUMBER

    מידע נוסף על חיבור לשרת proxy ל-Cloud SQL Auth זמין במאמר בנושא חיבור באמצעות לקוח mysql.

Go

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"net"
	"os"

	"cloud.google.com/go/cloudsqlconn"
	"github.com/go-sql-driver/mysql"
)

func connectWithConnectorIAMAuthN() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Warning: %s environment variable not set.", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser                 = mustGetenv("DB_IAM_USER")              // e.g. 'service-account-name'
		dbName                 = mustGetenv("DB_NAME")                  // e.g. 'my-database'
		instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance'
		usePrivate             = os.Getenv("PRIVATE_IP")
	)

	// WithLazyRefresh() Option is used to perform refresh
	// when needed, rather than on a scheduled interval.
	// This is recommended for serverless environments to
	// avoid background refreshes from throttling CPU.
	d, err := cloudsqlconn.NewDialer(
		context.Background(),
		cloudsqlconn.WithIAMAuthN(),
		cloudsqlconn.WithLazyRefresh(),
	)
	if err != nil {
		return nil, fmt.Errorf("cloudsqlconn.NewDialer: %w", err)
	}
	var opts []cloudsqlconn.DialOption
	if usePrivate != "" {
		opts = append(opts, cloudsqlconn.WithPrivateIP())
	}
	mysql.RegisterDialContext("cloudsqlconn",
		func(ctx context.Context, addr string) (net.Conn, error) {
			return d.Dial(ctx, instanceConnectionName, opts...)
		})

	dbURI := fmt.Sprintf("%s:empty@cloudsqlconn(localhost:3306)/%s?parseTime=true",
		dbUser, dbName)

	dbPool, err := sql.Open("mysql", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}
	return dbPool, nil
}

Java JDBC

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class ConnectorIamAuthnConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String INSTANCE_CONNECTION_NAME =
      System.getenv("INSTANCE_CONNECTION_NAME");
  private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET");
  private static final String DB_IAM_USER = System.getenv("DB_IAM_USER");
  private static final String DB_NAME = System.getenv("DB_NAME");


  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:mysql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);

    // If connecting using automatic database authentication, follow the instructions for
    // connecting using the connector, but set the DB_IAM_USER value to an IAM user or
    // service account that has been given access to the database.
    // See https://cloud.google.com/sql/docs/postgres/iam-logins for more details.
    config.addDataSourceProperty("enableIamAuth", "true");
    config.addDataSourceProperty("user", DB_IAM_USER);
    // Explicitly set sslmode to disable to prevent driver from hanging.
    // The Java Connector will handle SSL so it is unneccesary to enable it at the driver level.
    config.addDataSourceProperty("sslmode", "disable");

    // cloudSqlRefreshStrategy set to "lazy" is used to perform a
    // refresh when needed, rather than on a scheduled interval.
    // This is recommended for serverless environments to
    // avoid background refreshes from throttling CPU.
    config.addDataSourceProperty("cloudSqlRefreshStrategy", "lazy");


    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Java R2DBC

// Set up ConnectionFactoryOptions
ConnectionFactoryOptions options =
    ConnectionFactoryOptions.builder()
        .option(DRIVER, "gcp")
        .option(PROTOCOL, "mysql")
        .option(USER, DB_USER)
        .option(DATABASE, DB_NAME)
        .option(HOST, CONNECTION_NAME)
        .option(IP_TYPES, IP_TYPE)
        .option(ENABLE_IAM_AUTH, true)
        .build();

// Initialize connection pool
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
ConnectionPoolConfiguration configuration =
    ConnectionPoolConfiguration.builder(connectionFactory).build();

this.connectionPool = new ConnectionPool(configuration);

Python

import os

from google.cloud.sql.connector import Connector, IPTypes
import pymysql

import sqlalchemy


def connect_with_connector_auto_iam_authn() -> sqlalchemy.engine.base.Engine:
    """
    Initializes a connection pool for a Cloud SQL instance of MySQL.

    Uses the Cloud SQL Python Connector with Automatic IAM Database Authentication.
    """
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    instance_connection_name = os.environ[
        "INSTANCE_CONNECTION_NAME"
    ]  # e.g. 'project:region:instance'
    db_iam_user = os.environ["DB_IAM_USER"]  # e.g. 'service-account-name'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'

    ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC

    # initialize Cloud SQL Python Connector object
    connector = Connector(refresh_strategy="LAZY")

    def getconn() -> pymysql.connections.Connection:
        conn: pymysql.connections.Connection = connector.connect(
            instance_connection_name,
            "pymysql",
            user=db_iam_user,
            db=db_name,
            enable_iam_auth=True,
            ip_type=ip_type,
        )
        return conn

    # The Cloud SQL Python Connector can be used with SQLAlchemy
    # using the 'creator' argument to 'create_engine'
    pool = sqlalchemy.create_engine(
        "mysql+pymysql://",
        creator=getconn,
        # ...
    )
    return pool

כניסה באמצעות אימות ידני של מסד נתונים של IAM

משתמש או אפליקציה יכולים לבצע אימות למסד הנתונים באמצעות IAM על ידי בקשה ידנית של אסימון גישה מ- Google Cloud והצגתו למסד הנתונים. באמצעות ה-CLI של gcloud, אפשר לבקש במפורש אסימון OAuth 2.0 עם היקף Cloud SQL Admin API שמשמש לכניסה למסד הנתונים. כשמתחברים כמשתמש במסד נתונים עם אימות ידני של מסד נתונים ב-IAM, משתמשים בכתובת האימייל כשם המשתמש ובאסימון הגישה כסיסמה. אפשר להשתמש בשיטה הזו עם חיבור ישיר למסד הנתונים או עם מחבר Cloud SQL.

בשלב הזה, אתם מבצעים אימות ל- Google Cloud, מבקשים אסימון גישה ואז מתחברים למסד הנתונים על ידי העברת האסימון כסיסמה למשתמש במסד הנתונים של IAM. כדי להתחבר בלי שרת proxy ל-Cloud SQL Auth, צריך לבצע את השלבים הבאים.

בשלבים האלה, צריך:

כדי להיכנס באמצעות אימות ידני של מסד נתונים של IAM:

gcloud

  1. מבצעים אימות ב- Google Cloud.

    משתמש

    אימות ל-IAM באמצעות gcloud auth login. מידע נוסף זמין במאמר בנושא הרשאה באמצעות חשבון משתמש.

    חשבון שירות

    אימות ל-IAM באמצעות gcloud auth activate-service-account. מידע נוסף זמין במאמר מתן הרשאה באמצעות חשבון שירות.

  2. מבקשים את אסימון הגישה ונכנסים באמצעות לקוח.

    מחליפים את מה שכתוב בשדות הבאים:

    • HOSTNAME: כתובת ה-IP של המופע, כתובת ה-IP הציבורית או כתובת ה-IP הפרטית.
    • USERNAME: בחשבון משתמש ב-IAM, זהו כתובת האימייל של המשתמש, ללא הסמל @ או שם הדומיין. לדוגמה, כדי להזין את test-user@example.com, מקלידים test-user. בחשבון שירות, זהו כתובת האימייל של חשבון השירות ללא הסיומת @project-id.iam.gserviceaccount.com.

     export MYSQL_PWD=`gcloud sql generate-login-token` \
     mysql --enable-cleartext-plugin \
     --ssl-mode=REQUIRED \
     --host=HOSTNAME \
     --user=USERNAME
     

    אם ssl_mode במכונת Cloud SQL מוגדר כ-TRUSTED_CLIENT_CERTIFICATE_REQUIRED, צריך לכלול אישור לקוח ומפתח לקוח כשמתחברים. בנוסף, כדי לאפשר ללקוח לאמת את זהות השרת לצורך אימות הדדי, צריך לציין את אישור השרת server-ca.pem. לדוגמה:

     export MYSQL_PWD=`gcloud sql generate-login-token` \
     mysql --enable-cleartext-plugin \
     --ssl-mode=VERIFY_CA \
     --ssl-ca=server-ca.pem \
     --ssl-cert=client-cert.pem \
     --ssl-key=client-key.pem \
     --host=HOSTNAME \
     --user=USERNAME
     

    מידע על יצירת אישור ומפתח לקוח מופיע במאמר בנושא אישורי לקוח.

המאמרים הבאים