我想用Python和boto3写一个脚本,让我用EC2作为代理,将psql转发到指定的RDS实例,例如,要么用 ssh -L
端口转发或隧道。
我有一堆RDS和EC2实例。 一个RDS实例可能被很多EC2实例使用。 这是用安全组和一个入站规则来实现的,该规则将两个安全组(针对EC2和RDS)的流量挂在数据库端口(5432)上。
我可以使用boto3来获取EC2和RDS实例的信息,包括安全组。 但我不知道我需要用哪一个EC2实例来代理一个给定的RDS实例。
我如何配置EC2服务器作为我通过ssh进行外部连接的proxyjump-server? 我应该选择哪个EC2实例?
这里是一个未经测试的片段,应该是接近工作的,脱离了实际工作代码。
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权限)。 所以这就需要根据你所处的特殊环境进行调整。
这里还缺少很多信息。 请把细节补充进来,这样别人就可以修改你的问题了。
首先,ssh-tunnelingport-forwarding的答案可以在这里找到。 此处. 只要把端口从mysql 3306改为你的RDS psql端口即可。
二、如果你想使用从本地PC到EC2的SSH代理连接,这才有可能。