Securing your AWS keys for SES with IP restrictions - AMITAV ROY BLOG
    Securing your AWS keys for SES with IP restrictions
    Security is a crucial aspect of any application, and safeguarind the AWS keys and secret is very important. In this article, I would talk about how you can add an additional layer of security by restricting the keys for AWS Send Email Service (SES) to your EC2 instance IP address only.
    29 April, 2024

    TL;DR

    Got SES keys? Level up their security with IAM policy magic! Restrict access to whitelisted IPs, turning your EC2 instances into the only keymasters. Double-layered defense stops intruders cold. Details in the The policy section below.

    Introduction

    Before we dive into the topic of IAM and security, just so that we are on the same page - let's understand what is AWS IAM and what is it's role?

    Amazon Web Services (AWS) Identity and Access Management (IAM) is a fundamental component of AWS that provides robust security management capabilities. IAM enables you to control access to AWS services and resources securely. With IAM, you can create and manage AWS users and groups and use permissions to allow or deny their access to AWS resources. Some of the key features of IAM are:

    • User Management
    • Groups and Policies
    • Roles
    • Granular Permissions
    • Multi-Factor Authentication (MFA)
    • Access Management

    So, you can see IAM is a very useful feature and the more you explore it, you will understand the pivotal role it plays in AWS infrastructure.

    AWS Send Email Service (SES) and keys

    From the plethora of services that Amazon has to offer for any cloud solutions, SES is one which can be used to send emails. And, like many other AWS services, we can generate any AWS key and secret to use the SES service as an SMTP connection to send emails. I have been using AWS SES service to send emails with Laravel beause of the effortless integration that is provided out of the box.

    The problem

    Although using SES can be very easy, there are some important security aspects that every developer should be aware of. For example, like many frameworks, Laravel, when running in debug mode, will show a lot of information when exceptions are raised, and the AWS keys and secrets are part of them. The most common way that AWS secret keys get leaked and abused is by generating exceptions and looking at those exposed keys.

    The solution

    Now, it is obvious that debugging should not be turned on when the application is publicly available. However, staging and testing instances sometimes do get into this situation. So, although I don't ever recommend having debugging information on any public-facing instance, let's talk about one additional layer of security that we can add to SES using IAM.

    The IP address restriction

    Imagine having an exclusive email key, like a secret handshake that only your trusted servers can use. With IAM policies in AWS, you can turn this into reality for your Amazon SES keys! This is some serious James Bond stuff, because by restricting access to a set of whitelisted IP addresses, you ensure those keys can only be used by your designated EC2 instances. No imposters allowed!

    This creates a double layer of security. Not only do you need the key itself, but you also need to be coming from an authorized EC2 instance. It's like requiring a specific password and a fingerprint scan to access your top-secret files. Even if someone gets their hands on the key, they'd have to hack into your EC2 instance as well, making unauthorized email sending a near-impossible feat.

    This IAM policy basically throws up a digital "Fort Knox" around your SES keys, keeping them safe and sound. So, rest easy knowing your emails are only being sent by the machines you trust, and any wannabe hackers are left out in the cold.

    The policy

    Below is the policy in which we allow the IAM user to use the SES service. We are allowing sending raw email and we have whitelisted the IP address that can send emails.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "ses:SendRawEmail",
          "Resource": "*",
          "Condition": {
            "IpAddress": {
              "aws:SourceIp": [
                "203.0.113.0/24",
                "192.0.2.0/24" // can add as many IP address that you want
              ]
            }
          }
        }
      ]
    }
    

    Conclusion

    In today's fast paced technology and security strategies, no system is 100% safe. And hence, it makes sense for us to put all possible safe guards as possible to our cloud infrastructure so that it continues to be difficult for a hacker to exploit.

    Share your thoughts about security and do comment if you know of other ways to also secure things.

    AMITAV ROY

    Transforming ideas into impactful solutions, one project at a time. For me, software engineering isn't just about writing code; it's about building tools that make lives better.

    Share with the post url and description