How to get started with securing your AWS trading servers?
To get started with securing your AWS trading servers, there are a few prerequisites and things that are important to take note of. The first prerequisite is that you need an AWS account. You can visit this article to see how to make one.
Another thing to have in mind is that some of the things that we will feature here might come under the AWS free account limits (such as the t2.micro instance), be completely free (such as IAM and Security Groups), while others will cost you a bit to use (such as the trading server and custom VPN).
From my experience, you can comfortably remain under $20-30 a month while having all of the features implemented that we will cover in this article. At the end of the article, you will find some additional optional features that might provide even more security.
We will use the AWS CLI for most of the steps because it will make the process faster without the need to hop through many different UI parts. To install the AWS CLI, write the following command:
To ensure that you can run commands, run
sudo aws configure and pass it your access key and secret access key which you obtained when creating your account. It is advised to create an IAM user with admin privileges and use that instead of your root account.
But, the root account can do for this article as we won’t use it for long.
You can also skip the installation of the CLI and write the commands straight from your AWS account by accessing the AWS CloudShell.
You will find a
setup.sh script in my GitHub repo linked near the end of the article that will do the whole setup for you where you only need to edit it at the beginning to set a few variables. It does everything for you up to header 17.
We will start by creating our own environment for the trading server, and then move to implement some security best practices and finish off with launching an instance with 2FA and creating a secure VPN SSH “tunnel” to it.
How to set up your Internet Gateway for trading on AWS?
To set up your Internet Gateway for trading on AWS, there are two main steps to perform which are the following:
- Create an internet gateway and attach it to your VPC.
- Add a route to your subnet’s route table that directs internet-bound traffic to the internet gateway.
To create an internet gateway, we use the AWS CLI
create-internet-gateway command which is the following:
aws ec2 create-internet-gateway --query InternetGateway.InternetGatewayId --output text
Now, we will attach the created gateway to our VPC by using the
attach-internet-gateway command that will be provided with our VPC id and internet gateway id.
aws ec2 attach-internet-gateway
The next thing we want to do is to create a Route Table and configure it and the routes inside of it. The Route Table is essentially a set of rules that determines how internet packets are traveling around.
To create a Route Table we use the
create-route-table command and pass it the VPC id like the following:
aws ec2 create-route-table
--query RouteTable.RouteTableId --output text
Now, we will add a route that will use the Internet Gateway to pass traffic through it. To do this, we will use the
create-route command and pass it the route table id, destination CIDR block, and internet gateway id.
aws ec2 create-route
Finally, we will associate the Route Table with our Subnet by using the associate-route-table command and passing it the id of the Subnet and the id of the route table.
aws ec2 associate-route-table
The next thing we want to do is to create a security group.
To create a Security Group for trading on AWS, we will use the AWS CLI create-security-group command and pass it the group name, description, and the VPC id in which we want to deploy our trading servers.
The next thing to do is to open the SSH port, which is port 22, inside of the ingress rules. To do this, we use the authorize-security-group-ingress command and pass it the security group id, port number, and CIDR block of the IP(s) that can access the SSH port.
If you want any IP to access this port, the CIDR will be 0.0.0.0/0. This is not advisable and you should usually put your own IP in the following format X.Y.X.Y/32. But, your IP also changes and you might use multiple devices.
Thus, we’ll create a VPN “tunnel” later in the article that can be used only if you have adequate files to access the trading server. Here’s the command for the SSH ingress rule:
In order to access the trading server through the SSH client, we will need a key pair.
How to create a secure EC2 trading server on AWS?
To create a secure EC2 trading server on AWS, we will deploy it inside of a VPC subnet with our defined security group and give it a private key. To do this, we use the AWS CLI run-instances command and pass it the image id, instance type, security group id, key pair, and more.
aws ec2 run-instances
In the above command, we create a t2.micro EC2 instance for trading, set the image to Ubuntu 22.04, provided it the key pair, set up the security group and subnet, and associated the public IP address. To find the image you want to use, go here.
Now, let us connect via SSH to this server. You can get your public IP by going to the running EC2 instances tab, or by observing the output of your instance creation. To SSH into the instance we run:
ssh -i "Algotrading101Keys.pem" [email protected]<PUBLIC-IP-HERE>
We’re in! Be sure to run
sudo apt-get update. The next step is to secure the EC2 instance itself.
How to harden your trading server on AWS?
To harden your trading server on AWS you can do various things such as, ensure that the root account can’t access it, ensure that the kernel is hardened, set up 2FA, set up password rotations, and more.
At this point of the article, we can consider doing 2 things to secure our SSH login attempts. The first thing is to set up a fail2ban service that will ban malicious actors that are trying to brute force entrance into the server and set up 2FA. This is the cheaper option.
The second thing is to create a private VPN that ensures that only the person holding the keypair and a VPN access file can get into the instance via SSH. This way will block every other aspect of trying to connect to the instance be it root or otherwise. This way accrues costs while you are establishing a connection and being connected.
For most retail traders, the first way might be enough. For those that want extra security and don’t mind paying for it, you will find the second way more interesting. I’ll cover the first way manually and point you to a great AWS guide for the second one.
You can also combine 2FA with a VPN if you want to make it extra hard for anyone to break in.
Setting up fail2ban is easy, just run these commands:
sudo apt-get install -y fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
This will ban anyone trying to brute force.
How to enable 2FA for an EC2 instance on AWS?
To enable 2FA for an EC2 instance on AWS, you will need to install the google authenticator (or similar) 2FA software. To do this inside our trading server, we run the following command:
sudo apt install libpam-google-authenticator
Now, we can start the initialization for the authenticator by writing:
You will be presented with a series of questions that will configure how your authenticator functions. Let’s cover them one by one.
Do you want authentication tokens to be time-based (y/n) y
We want our authenticator tokens to expire and refresh themselves over time. After this step, you will be presented with a QR code that you need to scan with your Google Authenticator app on your mobile phone. Then, enter the code in the terminal emulator.
You will then see a few emergency scratch codes that can get you inside your trading server if your phone bugs out, goes missing, and similar. They are for one-time use only so be sure to store them somewhere safe and only use them when it is an actual emergency.
Do you want me to update your "~/.google_authenticator" file (y/n) y
This step will enable Authenticator to work, if you opt-out of it it won’t work.
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y
This is more of a personal preference but the shorter the timeframe is, the more secure you are.
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between the authentication server and client. Suppose you
experience problems with poor time synchronization. In that case, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the eight previous codes, the current
code, and the eight next codes). This will permit a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) n
By answering no, we limit ourselves to 3 valid codes in a 1:30-minute rolling window which is a more secure option.
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than three login attempts every 30s.
Do you want to enable rate-limiting (y/n) y
This will stop any brute-force attacks. Even though we have fail2ban activated, an additional feature like this doesn’t hurt, does it? The Google Authenticator is now configured, the next step is to make SSH utilize it.
Before we touch anything, let’s create two backups just in case something goes wrong.
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Now, we will edit the
sshd file to set the authenticator procedure. I’ll use Vim as my editor but you can use something else (e.g., nano) that you preferred over Vim.
Comment out the line
@include common-auth then go to the bottom of the file and add these two lines:
auth required pam_google_authenticator.so
auth required pam_permit.so
If you want to make the 2FA optional for some reason (such as testing) you can add
nullok to the end of the first line presented in the code cell above.
Now that this is done, let’s configure SSH to support the authenticator. To do so you will edit the
sshd_config file by adding
yes next to the
ChallengeResponseAuthentication line it might be named
KbdInteractiveAuthentication in your version so keep an eye out for it.
sudo vim /etc/ssh/sshd_config
If the line isn’t present for some reason, add it. After that, restart the service:
sudo systemctl restart sshd.service
Now, we want to make SSH the first Authentication factor and our Google Authenticator the second. To do this, we need to change the
sshd_config file again and add the following line at the very bottom:
We restart the service with
sudo systemctl restart sshd.service. That’s it, you now have 2FA set up for your trading server!
Now, let’s cover the second way which will require us to change a couple of things.