skip to Main Content

I have got an application hosted on ec2 instance in private subnet where no internect connection is established. However, I want to send emails from this instance. So I decided to use VPC Endpoint.

Here is the security group of the vpc endpoint I created
enter image description here

Source is the private ip of my ec2 instance.

When I invoke the following command:

telnet email-smtp.eu-central-1.amazonaws.com 587

The connnection is established because I got the response

Connected to email-smtp.eu-central-1.amazonaws.com.

but when I try to send an email from my java application, I got the exception

amazon.awssdk.core.exception.SdkClientException: 
Unable to execute HTTP request: Connect to email.eu-central-1.amazonaws.com:443 
[email.eu-central-1.amazonaws.com/<SOME_IP>, 
email.eu-central-1.amazonaws.com/<SOME_IP>,
email.eu-central-1.amazonaws.com/<SOME_IP>, 
email.eu-central-1.amazonaws.com/<SOME_IP>, 
email.eu-central-1.amazonaws.com/<SOME_IP>, 
email.eu-central-1.amazonaws.com/<SOME_IP>] failed: 
Connect timed out

the method I use to send emails

fun sendEmail() {
        val url = "url"
        val destination = Destination.builder().toAddresses(email).build()
        val subject = Content.builder().data("Suybject").build()
        val sesBody = Body.builder().text(Content.builder().data(data(url)).build()).build()
        val msg = Message.builder().subject(subject).body(sesBody).build()

        sesClient.sendEmail(
            SendEmailRequest.builder()
                .destination(destination)
                .message(msg)
                .source("[email protected]")
                .build()
        )
    }

and the sesClient config

  @Bean
    fun sesClient(): SesClient {
        val basicAWSCredentials = AwsBasicCredentials.create(sesAccessKey, sesSecretKey)
        val credentialsProvider = StaticCredentialsProvider.create(basicAWSCredentials)

        return SesClient
            .builder()
            .credentialsProvider(credentialsProvider)
            .region(Region.EU_CENTRAL_1)
            .build()
    }

2

Answers


  1. Chosen as BEST ANSWER

    Okay, I solved the problem. I stopped using aws ses sdk, because it tries to connect through HTTPS, while I need to connect through SMTP on 587 port. So here is my final configuration

    spring:
      mail:
        host: email-smtp.eu-central-1.amazonaws.com
        username: ${AWS_SES_USERNAME}
        password: ${AWS_SES_PASSWORD}
        port: 587
        protocol: smtp
        properties:
          mail.smtp.auth: true
          mail.smtp.starttls.enable: true
          mail.smtp.starttls.required: true
          mail.smtp.ssl.trust: email-smtp.eu-central-1.amazonaws.com
        test-connection: false
    
    

    To generate AWS_SES_USERNAME and AWS_SES_PASSWORD you need to sign in into aws console, go to Amazon SES -> SMTP Settings -> Create my SMTP credentials

    and the email is sent like this

            val message = mailSender.createMimeMessage()
            val helper = MimeMessageHelper(message, true)
            val body = data(url)
    
            helper.setFrom("[email protected]")
            helper.setTo(destination)
            helper.setSubject("Subject")
            helper.setText(body)
    
            mailSender.send(message)
    

  2. The SDK tries to connect through HTTP API of SES. The error log message says it tries to connect through 443 port, which is encrypted HTTP.

    Your security group for this endpoint does not allow connections on 443 port. Please open it and retry the connection.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search