同一VPC内EC2无法通过psql访问PostgreSQL求助排查
我用AWS CDK在同一VPC中创建了一台公网EC2实例和一台部署在私有子网的PostgreSQL RDS实例,已配置RDS安全组允许所有IP访问5432端口,但EC2无法通过psql连接PostgreSQL,可能的问题如下:
可能的故障点
RDS的
publiclyAccessible配置矛盾:代码中RDS部署在PRIVATE_WITH_NAT子网,却设置了publiclyAccessible(true)。该参数设为true时,RDS会被分配公网IP,但私有子网内的实例无法直接通过公网IP被访问,反而会导致EC2解析RDS的DNS时指向公网IP,VPC内流量走公网路径出现异常。应将该参数改为false,让EC2通过RDS的内网IP连接。PostgreSQL内部配置限制:即使安全组开放了端口,PostgreSQL的
pg_hba.conf文件可能未允许EC2所在的内网IP段或指定用户连接。默认配置通常只允许本地连接,需要添加规则允许VPC内网IP段(如10.0.0.0/16)的主机使用密码认证连接。DNS解析异常:若
publiclyAccessible为true,EC2可能解析到RDS的公网IP,导致VPC内流量绕经NAT网关访问,引发连接问题。需确保VPC启用了DNS主机名和DNS解析(默认已启用),同时将publiclyAccessible设为false,让RDS的DNS指向内网IP。网络ACL限制:虽然安全组允许流量,但子网的网络ACL可能存在拦截规则。比如EC2所在的公网子网未允许出站5432端口流量,或RDS所在的私有子网未允许入站5432端口流量。默认网络ACL允许所有流量,若有自定义配置需检查。
连接地址错误:连接时可能误用了RDS的公网端点,而VPC内的EC2应使用RDS的内网端点进行连接。公网端点的流量需要走公网,可能被安全组或路由策略拦截。
相关代码
Vpc vpc = new Vpc(this,"RDS-VPC", VpcProps.builder() .natGateways(1).maxAzs(2).build()); SecurityGroup ec2SG = new SecurityGroup(this,"EC2-SG", SecurityGroupProps.builder().vpc(vpc).allowAllOutbound(true).build()); ec2SG.addIngressRule(Peer.ipv4("xxx.xxx.xxx.xxx/32"),Port.tcp(22),"The specified IP can be accessed"); SecurityGroup rdsSg = new SecurityGroup(this,"RDS-SG", SecurityGroupProps.builder().vpc(vpc).allowAllOutbound(true).build()); rdsSg.addIngressRule(Peer.anyIpv4(),Port.tcp(5432),"allow public ssh access"); List<SecurityGroup> securityGroups = new ArrayList<>(); securityGroups.add(rdsSg); Instance Ec2Instace = new Instance(this,"ec2", InstanceProps.builder().vpc(vpc) .instanceType(InstanceType.of(InstanceClass.T3,InstanceSize.MEDIUM)) .machineImage(MachineImage.latestAmazonLinux(AmazonLinuxImageProps.builder().generation(AmazonLinuxGeneration.AMAZON_LINUX_2).build())) .securityGroup(ec2SG) .vpcSubnets(SubnetSelection.builder().subnetType(SubnetType.PUBLIC).build()) .keyName("keyname") .build()); Credentials credentials = Credentials.fromPassword("xxx", new SecretValue("xxxx")); SubnetGroup subnetGroup = new SubnetGroup(this,"postgresql", SubnetGroupProps.builder().vpcSubnets(SubnetSelection.builder().subnetType(SubnetType.PRIVATE_WITH_NAT).build()).build()); DatabaseInstance databaseInstance = new DatabaseInstance(this,"postgresql",DatabaseInstanceProps.builder() .vpc(vpc) .deleteAutomatedBackups(true) .instanceType(InstanceType.of(InstanceClass.T3,InstanceSize.MICRO)) .allocatedStorage(10) .credentials(credentials) .databaseName("xxxx") .securityGroups(securityGroups) .subnetGroup(subnetGroup) .publiclyAccessible(true) .engine(DatabaseInstanceEngine.postgres(PostgresInstanceEngineProps.builder().version(PostgresEngineVersion.VER_13).build())) .build());
内容的提问来源于stack exchange,提问作者Mily

