Redshift IAM認証をVPC内部とそれ以外で絞ってみる

2022.08.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

データアナリティクス事業本部のkobayashiです。

RedshiftのIAM認証を使用したデータベース接続の検証を行う記事を何本か書きましたが、それらは今回行う接続元による接続の制御をIAM認証で行えるかを検証するのが最終的な目的でした。具体的にはVPC エンドポイントを経由したRedshiftのIAM認証で接続する場合とパブリック環境からRedshiftのIAM認証で接続する場合において同一ユーザーで接続するが所属するグループの制限をかけられるかという内容です。これを試してみたのでまとめます。

接続経路によるRedshiftユーザーの所属グループ制御

IAM認証を使用したデータベースユーザー認証に関しては以下の2つのエントリがあるのでそちらをご確認ください。

今回使うのはRedshiftのユーザー自動作成の際に使用したredshift:JoinGroupのアクションを接続ルートによって制限をかけるというものです。具体的には以下の様な形で実現したいと思います。

  • Route A
    • パブリックな環境からVPC内のRedshiftへ接続を行う
    • IAM 認証を使用したデータベースユーザー認証で接続し、stgスキーマをSelectだけできるグループstg_readonlyに所属させる
  • Route B
    • VPC内にあるインスタンスやDirect Connect(or VPN)などプライベートネットワークからRedshiftへ接続を行う
    • IAM 認証を使用したデータベースユーザー認証で接続し、stgスキーマをSelectだけでなくすべて操作できるグループstg_readwriteに所属させる

これを実現するためにはRedshift APIサービス用のVPCエンドポイントの作成とIAMポリシーにVPCエンドポイント経由のConditionを設定することで実現することができます。

では早速設定を行っていきます。

VPC エンドポイントを使用した Amazon Redshift への接続

はじめにVPCエンドポイントを作成しVPCエンドポイントを経由してAmazon Redshift API のサービスへアクセスするようにします。これは公式ドキュメント(インターフェイス VPC エンドポイントを使用した Amazon Redshift への接続 - Amazon Redshift )に詳しい解説がありますのでそちらをご確認ください。

ここではTerraformで作成する際のコードを記載しておきます。下記のコードでRedshift APIサービス用のVPCエンドポイントが作成できます。

resource "aws_vpc_endpoint" "redshift" {
  vpc_id              = aws_vpc.main.id
  service_name        = "com.amazonaws.ap-northeast-1.redshift"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = [aws_subnet.redshift_1a.id,aws_subnet.redshift_1c.id]
  security_group_ids  = [aws_security_group.vpc_endpoint.id]
  private_dns_enabled = true

  tags = {
    Name = "vpce-rs"
  }
}

resource "aws_security_group" "vpc_endpoint" {
  name   = "vpce-sg"
  vpc_id = aws_vpc.main.id

  ingress {
    from_port = 443
    protocol = "tcp"
    to_port = 443
    cidr_blocks = [aws_vpc.main.cidr_block]
  }

  egress {
    from_port = 0
    protocol = "-1"
    to_port = 0
    cidr_blocks = [aws_vpc.main.cidr_block]
  }

  tags = {
    Name = "vpce-sg"
  }
}

RedshiftユーザーのIAMポリシーの修正

次にIAMポリシーでは前回設定したポリシー(Redshift IAM認証でのユーザーの自動作成を試してみる | DevelopersIO )をベースに、上記で作成したVPCエンドポイント経由でのアクセスではstgスキーマをSelectだけでなくすべて操作できるグループstg_readwritに所属させるようにします。

具体的にはConditionaws:sourceVpceに先に作成したVPCエンドポイントIDを指定するだけです。

以下が修正したIAMポリシーになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "GetClusterCredsStatement",
            "Effect": "Allow",
            "Action": [
                "redshift:GetClusterCredentials"
            ],
            "Resource": [
                "arn:aws:redshift:ap-northeast-1:アカウントID:dbuser:{クラスター識別子}/user3",
                "arn:aws:redshift:ap-northeast-1:アカウントID:dbname:{クラスター識別子}/dev",
                "arn:aws:redshift:ap-northeast-1:アカウントID:dbgroup:{クラスター識別子}/stg_readonly"
            ]
        },
        {
            "Sid": "CreateClusterUserStatement",
            "Effect": "Allow",
            "Action": [
                "redshift:CreateClusterUser"
            ],
            "Resource": [
                "arn:aws:redshift:ap-northeast-1:アカウントID:dbuser:{クラスター識別子}/user3"
            ]
        },
        {
            "Sid": "RedshiftJoinGroupStatement",
            "Effect": "Allow",
            "Action": [
                "redshift:JoinGroup"
            ],
            "Resource": [
                "arn:aws:redshift:ap-northeast-1:アカウントID:dbgroup:{クラスター識別子}/stg_readonly"
            ]
        },
        // 追加した部分
        {
            "Sid": "RedshiftJoinGroupStatementRW",
            "Effect": "Allow",
            "Action": [
                "redshift:JoinGroup"
            ],
            "Resource": [
                "arn:aws:redshift:ap-northeast-1:アカウントID:dbgroup:{クラスター識別子}/stg_readwrite"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "vpce-0123456789abcdefg"
                }
            }
        }
    ]
}

なお、Redshiftのグループは以下のSQLで作成しています。

-- グループの作成
CREATE GROUP stg_readonly;
CREATE GROUP stg_readwrite;

-- SCHEMA利用権限付与
GRANT USAGE ON SCHEMA stg TO GROUP stg_readonly;
GRANT USAGE ON SCHEMA stg TO GROUP stg_readwrite;

--
-- スキーマの管理グループ
--
ALTER default privileges IN SCHEMA stg GRANT SELECT ON tables TO GROUP stg_readonly;
ALTER default privileges IN SCHEMA stg GRANT ALL ON tables TO GROUP stg_readwrite;

JDBC URLをプライベート接続用のものに修正

以上で設定は終わったのでプライベート接続用のJDBC URLを作成しますが、単に文字列のDbGroupsで指定しているグループ名を書き換えるだけになります。

VPC内にあるインスタンスやDirect Connect(or VPN)などプライベートネットワークからRedshiftへ接続を行うJDBC URL

jdbc:redshift:iam://{クラスター識別子}:{リージョン}:5439/dev?Profile=cm_rs_iam&DbUser=user3&DbGroups=stg_readwrite&AutoCreate=true

当然、パブリックな環境からこのJDBC URLで接続を行おうとしても接続は拒否されますので パブリックな環境からの接続を行う場合はConditionが設定されていないstg_readonlyDbGroupsに指定して接続する必要があります。

jdbc:redshift:iam://{クラスター識別子}:{リージョン}:5439/dev?Profile=cm_rs_iam&DbUser=user3&DbGroups=stg_readonly&AutoCreate=true

まとめ

VPC エンドポイントを経由したRedshiftのIAM認証で接続する場合とパブリック環境からRedshiftのIAM認証で接続する場合において同一ユーザーで接続するが所属するグループをIAMポリシーで制限してみました。RedshiftのIAM認証ではRedshiftのユーザー管理を簡単に行えるのでRedshift内でDDLを使いユーザーを作成するよりも柔軟に管理が行えるので非常に便利です。

最後まで読んで頂いてありがとうございました。