【问题标题】:How to use boto3 to find an EC2 jump host for ssh port forwarding to RDS?如何使用boto3找到EC2跳转主机ssh端口转发到RDS?
【发布时间】:2017-08-22 22:39:54
【问题描述】:

我想使用 Python 和 boto3 编写一个脚本,让我 psql 到使用 EC2 作为代理的指定 RDS 实例,例如使用ssh -L 端口转发或隧道。

我有一堆 RDS 和 EC2 实例。一个 RDS 实例可能被多个 EC2 实例使用。这是使用安全组和一个入站规则来实现的,该规则将两个安全组(用于 EC2 和 RDS)连接到数据库端口 (5432) 上的流量。

我可以使用 boto3 来获取 EC2 和 RDS 实例的信息,包括安全组。但我不知道我需要 ssh 哪个 EC2 实例来充当给定 RDS 实例的代理。

如何将 EC2 服务器配置为通过 ssh 进行外部连接的代理/跳转服务器?我应该选择哪个 EC2 实例?

【问题讨论】:

  • 正确的术语是“端口转发”。
  • 如果您可以获取 EC2 实例列表、RDS 实例列表以及分配给 EC2 和 RDS 实例的安全组规则列表,那么是什么阻止您检查安全性确定哪个 EC2 实例可以访问 RDS 实例的组规则?
  • @MarkB Nothing:我只是懒惰,并希望这会很尴尬。同时我发现我可以获取安全组,从中获取 .ip_permissions,然后使用它来加入 EC2 和 RDS 实例。写完代码我会写答案
  • @mootmoot 是的。我在某处使用了错误的术语吗?
  • 您的jump 是指port forwarding 吗?由于ssh -L 正在做端口转发。

标签: python amazon-web-services amazon-rds boto3


【解决方案1】:

这是一个 UNTESTED sn-p,应该接近工作,与实际工作代码分离:

import boto3

def find_jump_host(rds_name):
    rds_client = boto3.client('rds')
    ec2_client = boto3.client('ec2')
    ec2 = boto3.resource('ec2')

    rds_instances = rds_client.describe_db_instances()['DBInstances']
    for rds_instance in rds_instances:
        if rds_instance.get('DBInstanceIdentifier') == rds_name:
            break

    vpc_groups = rds_instance.get('VpcSecurityGroups', [])
    vpc_group_ids = [group.get('VpcSecurityGroupId', None) for group in vpc_groups]
    vpc_group_ids = [id_ for id_ in vpc_group_ids if id_ is not None]

    security_groups = [ec2.SecurityGroup(id_).ip_permissions for id_ in vpc_group_ids]
    group_ids = set(pair.get('GroupId')
                    for link in security_groups
                    for pair in link.get('UserIdGroupPairs', []))

    ec2_instances = ec2_client.describe_instances()
    reservations = ec2_instances['Reservations']

    for reservation in reservations:
        for instance in reservation.get('Instances', []):
            if instance['State']['Name'] == 'stopped':
                continue

            for group in instance.get('SecurityGroups', []):
                if group.get('GroupId') in group_ids:
                    break

    for instance in reservation['Instances']:
        print("Public IP", instance.get('PublicIpAddress', '<no public IP>'))
        print("Private IP", instance['PrivateIpAddress'])
        print("Public DNS name", instance['PublicDnsName'])
        print()

请注意,这会做出一些随意的决定,例如选择第一个可能的预订。此外,某些主机可能不适合您的设置中的跳转主机(例如,您可能没有 ssh 访问权限)。所以这需要适应你所处的特定环境。

【讨论】:

    【解决方案2】:

    这里仍然缺少许多信息。请添加详细信息,以便其他人可以修改您的问题。

    首先,可以在here 找到 ssh-tunneling/port-forwarding 的答案。只需将端口从 mysql 3306 更改为您的 RDS psql 端口。

    其次,如果您想使用从本地 PC 到 EC2 ssh 代理的连接,这是唯一可能的:

    1. EC2 服务器有一个公共连接的 IP 地址,或者
    2. 您与位于 VPC 私有子网上的 EC2 服务器建立了 VPN 连接

    【讨论】:

    • 为什么这不是评论?它没有回答原始问题,也没有回答已编辑的问题(经过编辑 - 我确信是出于好意 - 现在是关于不同的事情,请参阅我对问题的评论)。我已经可以从命令行连接,但是我没有找到合适的跳转主机的代码。但是,既然我已经说过我解决了自己的问题,并且会在我编写完代码后发布答案:也许你等待几天而不是投反对票并添加一个没有答案的答案会更好问题?
    猜你喜欢
    • 2017-03-14
    • 2012-03-20
    • 2020-06-17
    • 1970-01-01
    • 2017-06-04
    • 2016-07-17
    • 2020-07-24
    • 2013-07-20
    • 2018-10-07
    相关资源
    最近更新 更多