Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用boto3找到用于ssh端口转发到RDS的EC2跳转主机?_Python_Amazon Web Services_Amazon Rds_Boto3 - Fatal编程技术网

Python 如何使用boto3找到用于ssh端口转发到RDS的EC2跳转主机?

Python 如何使用boto3找到用于ssh端口转发到RDS的EC2跳转主机?,python,amazon-web-services,amazon-rds,boto3,Python,Amazon Web Services,Amazon Rds,Boto3,我想使用Python和boto3编写一个脚本,以便使用EC2作为代理将psql发送到指定的RDS实例,例如使用ssh-L端口转发或隧道 我有一堆RDS和EC2实例。一个RDS实例可以被多个EC2实例使用。这是使用安全组和入站规则来实现的,该入站规则为数据库端口(5432)上的流量连接两个安全组(用于EC2和RDS) 我可以使用boto3获取EC2和RDS实例的信息,包括安全组。但我不知道我需要ssh哪个EC2实例来充当给定RDS实例的代理 如何配置EC2服务器作为通过ssh进行外部连接的代理/跳

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

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

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


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

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

首先,可以找到ssh隧道/端口转发应答。只需将端口从mysql 3306更改为您的RDS psql端口

第二,如果您想使用从本地PC到EC2 ssh代理的连接,这只能是:

  • EC2服务器具有公共连接的IP地址,或
  • 您与位于VPC专用子网上的EC2服务器有VPN连接

  • 下面是一个未经测试的代码片段,应该与实际工作代码分离,接近工作状态:

    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()
    
    导入boto3
    def查找跳转主机(rds\U名称):
    rds_client=boto3.client('rds')
    ec2_client=boto3.client('ec2')
    ec2=boto3.resource('ec2')
    rds_instances=rds_客户端。描述_db_instances()['DBInstances']
    对于rds\ U实例中的rds\ U实例:
    如果rds_instance.get('DBInstanceIdentifier')==rds_名称:
    打破
    vpc_groups=rds_instance.get('VpcSecurityGroups',[])
    vpc_组_id=[group.get('VpcSecurityGroupId',None)用于vpc_组中的组]
    vpc_组_id=[如果id_u不是None,则为vpc_组_id中的id_u的id_u]
    security_groups=[ec2.SecurityGroup(id_uu).vpc_group_uid中id_u的ip_u权限]
    group_id=set(pair.get('GroupId'))
    用于安全组中的链接
    对于link.get中的pair('UserIdGroupPairs',[]))
    ec2_实例=ec2_客户端。描述_实例()
    保留=ec2_实例[“保留”]
    对于保留中的保留:
    例如,reservation.get('Instances',[])中的实例:
    如果实例['State']['Name']=='stopped':
    持续
    对于实例.get中的组('SecurityGroups',[]):
    如果组ID中的group.get('GroupId'):
    打破
    例如,在预订['Instances']中:
    打印(“Public IP”,instance.get('PublicIpAddress','')
    打印(“私有IP”,实例['PrivateIpAddress'])
    打印(“公共DNS名称”,实例['PublicDnsName'])
    打印()
    

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

    正确的术语是“端口转发”。如果您可以获取EC2实例列表、RDS实例列表以及分配给EC2和RDS实例的安全组规则列表,那么,是什么阻止您检查安全组规则以确定哪个EC2实例可以访问RDS实例?@MarkB Nothing:我只是很懒,希望这会很尴尬。同时,我发现我可以获取安全组,从这些组获取.ip_权限,然后使用这些权限加入EC2和RDS实例。我写完报告后再写答复code@mootmoot对我是否在某个地方使用了错误的术语?您的
    跳转是
    端口转发的意思吗?既然
    ssh-L
    正在进行端口转发,为什么这不是一个注释?它没有回答原来的问题,也没有回答经过编辑的问题(经过编辑——我确信是出于好意——现在是关于另一件事的,请参见我对问题的评论)。我已经可以从命令行进行连接,但是我没有代码来找到合适的跳转主机。但既然我已经说过我解决了我自己的问题,并将在我编码好后发布答案:也许你最好等几天,而不是投否决票,然后添加一个不回答问题的答案?