![]()
AWS Security with EC2 Linux
Example Architecture Overview
+----------------------+
| Internet |
| Website Visitors |
+----------+-----------+
|
|
Contact Form / HTTPS
|
v
+-----------------------------+
| EC2 Linux Server |
| (Nginx / Apache + PHP) |
| |
| WordPress / Scripts |
| |
| IAM Instance Role |
+------+-----------+----------+
| |
| |
| |
SES Email API AWS SDK
| |
v v
+----------------+ +------------------+
| Amazon SES | | Amazon S3 |
| | | Private Buckets |
| Send Emails | | Images / Files |
+--------+-------+ +---------+--------+
| |
| |
v v
+------------------+ Temporary Signed
| Lambda Filters |-----> Access URLs
| |
| Spam / Forward |
+---------+--------+
|
v
Verified Admin Emails
(SES Identities)
Key security ideas in this architecture
-
EC2 does not store credentials
-
Access occurs through an IAM Instance Role
-
S3 buckets remain private
-
Images/files are accessed through temporary signed URLs
-
Email is sent through SES with restricted policies
-
Optional Lambda filtering processes incoming email
Scope and Assumptions
This article describes a practical security approach for small AWS deployments using Linux servers and common AWS services.
The discussion assumes the following environment:
-
A Linux EC2 instance running a web server such as Apache or Nginx
-
Applications such as WordPress or custom PHP scripts
-
Use of Amazon S3 for file storage
-
Use of Amazon SES for sending or receiving email
-
Administration performed by individuals or small teams without dedicated security staff
The article focuses on architecture and design principles, not step-by-step implementation.
AWS security configurations often require significant development and testing, including IAM policy design, scripting, and application integration. Those details vary between environments and are outside the scope of this overview.
Instead, the goal is to outline a structured approach to securing common AWS workflows, including:
-
administrative alert emails
-
website contact form emails
-
controlled access to files stored in S3
-
safe handling of credentials when they cannot be avoided
AWS Security with EC2 Linux
A practical overview for small operators
Running services in AWS without a dedicated security team means that security must be built into the architecture from the start.
This article provides a high-level overview of practical security patterns when using:
-
EC2 Linux servers
-
Amazon S3
-
Amazon SES email services
The goal is not to document exact implementation steps. Those are complex and vary by environment. Instead, this article describes a practical approach and design philosophy that small operators can use when building secure systems in AWS.
Many of the scripts, policies and integrations discussed here require development and testing. Tools such as the AWS SDK, Bash scripting, and increasingly AI-assisted coding can help generate the required components.
Security Philosophy
A few core principles guide the approach described here:
1. Least privilege access
Every AWS component should only have the permissions it absolutely needs.
2. No stored credentials where possible
Instead of storing keys in ~/.aws, services should use IAM roles attached to EC2 instances.
3. Separate roles for different tasks
Different operations (administrative alerts, public emails, S3 access) should use different IAM policies or roles.
4. Private resources by default
S3 buckets and internal services should remain private and only be accessed through controlled methods.
5. Defence in depth
Security should exist at multiple layers:
-
AWS IAM policies
-
server configuration
-
application logic
-
network protections
Example Security Scenarios
The following scenarios illustrate how these principles can be applied.
Scenario 1
Sending administrative alerts from a Linux server
A common requirement is for a server to send email alerts to administrators.
Examples include:
-
SSL certificate renewal failures
-
website uptime monitoring alerts
-
system warnings or failures
To secure this process:
-
An IAM Role is attached to the EC2 instance.
-
The role contains two restricted IAM policies:
-
one for Amazon S3 access
-
one for Amazon SES email sending
The SES policy is restricted so that emails can only be sent to verified addresses or domains.
This is important because it prevents a compromised server from sending spam to the public internet.
Linux monitoring scripts can then trigger alerts and send email using the AWS SDK, without storing credentials locally.
This avoids using:
These systems can take time to design and debug, but they significantly improve security.
Scenario 2
Sending public emails from a WordPress contact form
A different requirement occurs when a website contact form sends email responses to public users.
For example:
A visitor submits a form and receives a copy of their message.
Because this involves sending to non-verified addresses, the security model must be expanded carefully.
One approach is:
-
The EC2 instance keeps its restricted IAM role.
-
A second IAM role is created with permissions to send public emails.
-
The EC2 role is allowed to assume the second role when required.
WordPress can then trigger email sending through a plugin or custom hook (for example in mu-plugins).
Additional protections can also be added, such as:
-
page tokens
-
rate limiting
-
verification checks
This ensures that even if the website application is abused, it is difficult to turn it into a spam relay.
Scenario 3
Secure access to files stored in S3
Another common use case is hosting images or downloadable files in S3.
To prevent bots or crawlers from discovering permanent URLs, files can remain in private S3 buckets.
Instead of exposing direct links, the website can generate temporary pre-signed URLs using the AWS SDK.
These URLs:
-
allow controlled access to the file
-
automatically expire after a defined time
This approach works well for:
-
image delivery
-
document downloads
-
temporary file access
Scenario 4
When credentials cannot be avoided
Sometimes credentials must still be used.
Examples include:
-
plugins that require SMTP credentials
-
software that cannot use IAM roles directly
In these cases, credentials must be protected carefully.
Some applications store secrets encrypted in databases. For example, the WordPress plugin WP Mail SMTP stores SMTP credentials in encrypted form.
If the AWS CLI is used with credentials in:
additional monitoring and access controls should be considered.
AWS logging and monitoring services can help detect unusual activity, but these must be configured carefully to avoid unexpected costs.
Server-side security on the Linux host
AWS configuration alone is not enough.
The Linux server itself should also include protective measures.
These may include:
-
firewall rules using nftables
-
rate limiting
-
tools such as fail2ban
-
IP whitelisting where appropriate
Web server configuration must also block access to sensitive files and directories.
For example, Apache or Nginx rules should prevent access to files such as:
-
.env -
config.php -
wp-config.php
These protections help prevent accidental exposure of credentials.
Email filtering with SES and Lambda
Amazon SES can also be integrated with AWS Lambda to process incoming mail.
A typical architecture may include:
Two Lambda roles:
1. Filtering role
Used to inspect incoming mail and drop spam or unwanted messages.
2. Forwarding role
Used to forward valid email to verified recipients.
SES can temporarily store incoming messages in an S3 bucket, where Lambda functions can process them before forwarding.
This architecture allows flexible email handling while keeping S3 buckets private.
Monitoring and cost awareness
Security monitoring is important, but AWS services can generate unexpected charges if misconfigured.
Small operators should carefully evaluate:
-
logging levels
-
monitoring services
-
automated alerts
Security should improve visibility without creating bill shock.
Final Thoughts
Building secure systems in AWS takes time and experimentation.
The key ideas are:
-
use IAM roles instead of stored credentials
-
apply least-privilege policies
-
keep S3 buckets private
-
separate roles for different functions
-
combine AWS security with server-level protections
Even small systems can achieve strong security when these principles are applied consistently.
Common Mistakes in Small AWS Deployments
These are problems frequently seen in smaller AWS setups.
Storing AWS credentials on servers
Leaving long-term keys in:
is common but risky. IAM roles are usually safer.
Overly broad IAM permissions
Policies created quickly during development sometimes grant far more access than necessary.
This defeats the least privilege principle.
Public S3 buckets
Accidentally exposing files through public buckets is one of the most common AWS mistakes.
Private buckets with controlled access are much safer.
Mixing administrative and public email
If SES permissions allow sending to any address, a compromised application could become a spam relay.
Separating admin alerts from public email roles reduces this risk.
Ignoring server-level security
AWS IAM alone does not secure the system.
The Linux server still needs:
-
firewall rules
-
rate limiting
-
hardened web server configuration
Lack of testing
Many IAM and SES configurations require significant debugging before they behave correctly.
Testing alert scripts, policies, and email handling early can prevent difficult troubleshooting later.
Security principles used
This model relies on a few important principles:
-
Least privilege IAM policies
-
No stored credentials where possible
-
Private resources by default
-
Separation of roles for different functions
-
Multiple layers of protection
Closing Thoughts
AWS provides powerful security tools, but configuring them correctly takes time and experimentation. For individuals and small operators, the key is not perfection but developing a structured approach to security.
Using IAM roles, restricting permissions, keeping storage private, and combining AWS security with careful Linux configuration can significantly reduce risk.
Even relatively small deployments can achieve strong protection when these practices are applied consistently.



