Course Content‎ > ‎

Section 10: Deploying on the Cloud


Cloud Computing

Cloud Computing is a model that facilitates easy, on-demand access to a shared collection of computing resources (e.g. servers, storage, applications, services).  The "Cloud" is another name for a distributed network and provides the ability to run programs and applications from any location on a collection of computing resources simultaneously.   

Commonly, most individuals see "The Cloud" as simply meaning "The Internet" and, while a little simplistic, this is technically correct.  However, let us try to streamline a more precise definition, by looking at the characteristics of Cloud Computing.  The characteristics here are those defined by the NIST (National Institute of Standards and Technology) in the US (Source: http://csrc.nist.gov/publications/nistpubs/800-145/SP800-145.pdf).  

1) On-Demand Self-Service: A consumer of cloud services should be able to provision computing resources without the need for any human interaction at the service end.  For example, when a new consumer of Dropbox wishes to set up an account, they do not have to communicate with a human.  They provision the resource themselves by simply filling in some details and working through some steps to register.

2) Broad Network Access: Services are available over the network and through standard protocols and devices, such as mobile phones, PCs, tablets etc.  Again, using the Dropbox example, we can access Dropbox services over HTTP through mobile phones, tablets and PCs.  

3) Resource Pooling: The service provider is using a pool of computing resources, with resources dynamically provisioned in accordance with consumer demand.  Users of Dropbox share a common set of virtual resources (mostly hard drive space) which are balanced by user demand.  Some users will only use a small portion of their allocation while others will sign up for premium services which provide more resources.   Similarly, with Amazon AWS, some users may simply utilise a small "micro" server (with low memory, CPU, bandwidth), while others will utilise dozens of powerful, high-bandwidth multi-core virtual machines.  Users of these resources typically have no sense of physical location of these services, although this may be controller in a broad sense (e.g. specifically asking Amazon AWS for servers in EU-WEST (Dublin))

4) Rapid Elasticity: Server resources can be elastically provisioned or released.  This may be as a result of a manual request from a consumer, or it may happen automatically in certain scenarios.  For example, with Amazon AWS, it is possible to request that if a virtual server exceeds a certain load threshold, additional identical virtual servers can be automatically added to handle the increased load. 

5) Measured Service: Cloud systems typically contain some form of "metering" to assess the usage of resources by consumers. Resources can be monitored, controlled and (typically) appropriately charged by the service provider.  For example, consumers on AWS are charged based on the number of servers they are using, the CPU/Memory of those servers, the bandwidth usage and a variety of other factors.  Amazon keep a track of all of these factors and provide detailed billing to consumers.

A Cloud Computing Problem

Let us take a real world example, to provide a scenario where cloud computing demonstrates both its characteristics and its benefits.  Consider for a moment that you worked in a ticketing company for online concert ticket sales (at a national level).  You are asked to write a web application which would allow customers to purchase tickets for concerts at any time of the year.  Let us assume that if we were to sell "one million tickets" equally spread over the course of the year, where each transaction (for simplicity's sake) was one ticket, then we would have the following load on our server:

365 (days) x 24 (hours) x 60 (minutes) x 60 (seconds) = 31,536,000 seconds
So assuming it was 5 clicks/page loads involved per ticket we get the following:
(1,000,000*5) / 31,536,000 = 0.16 requests per second

As can be seen, this is an extremely low load and one might make an assumption that the following set up would suffice:
- Server (similar to a basic PC in CPU/Memory)
- Tomcat running the 'student records' web application
- MySQL running on same server

This server is purchased, installed and the application deployed and tested.  On deployment, we discover that it can easily handle 5 requests per second without problems - easily higher than our server demand. The ticketing system is deployed and everything works well ...for a time!

Of course, the reality of our business process is that our servers will experience very little traffic during night-time periods and will experience considerable "peaking" of usage.

Let us now consider one of those "peaks".  Consider a popular concert which is advertised as "Tickets go on sale at 9am on Monday 1st of January".  80,000 tickets will be sold within 5 minutes, involving 5 clicks per sale.  Note: We are going to assume that there are no undersupply or this situation would be worse.

5 (minutes) x 60 (seconds) = 300 seconds
80,000 * 5 (page loads) = 400,000 page loads
Requests per second = 1,333 requests per second

In this scenario we can see that our load during these 5 minutes is approximately 8,000 times heavier than "on average".
At 9:00 am on the day of ticket sales the system crashes!

The problem here is that the load on such a system is not evenly distributed
The server experiences a peak in usage that it can not handle (similar to a 'denial of service' (DOS) attack) and crashes as a result.  To make things more complicated, each time the page fails to load for the customer, they hit Refresh, greatly increasing the number of requests the server is expected to process.

A Solution

The issue here is that there is a very significant distribution of the load with significant peaking of the need for resources.  The University could attempt to spend hundreds of thousands in an attempt to provision enough resources through the use of a powerful server or set of load-balanced servers.  This would be widely expensive and would result in an under-utilised resource for 99.9% of the time.  Let us instead consider Cloud Computing and take some real world pricing from Amazon AWS.

At the time of writing these notes, the following pricing applies on Amazon AWS.

Amazon Pricing

As can be seen here, instead of creating our own physical servers, we instead deploy into the AWS Cloud.  When we deploy our web application, we can indicate that it will be deployed on a single m3.xlarge server (at a cost of 4,336 (365*24*0.495) euro per annum).  However, we also indicate that our application can automatically scale when it goes above a certain load (automated) so that it can spawn up to 6 parallel m3.xlarge servers.  This way, it can dynamically adapt to business environment changes.

During the periods where we expand to multiple servers, our company simply pays for this additional server time by the hour.  As can be seen, this is an extremely cost effective approach to deploying server resources elastically.

Cloud Service Models

There are three principle service models associated with Cloud Computing:

Cloud Stack
Figure: The Cloud Computing Stack showing the hierarchy of SaaS, PaaS and Iaas


1. Software as a Service (SaaS)

In the SaaS business model, consumers are provided access to use the provider's applications, which are running on a cloud infrastructure.  The Cloud providers manage the infrastructure which runs the software, but the client simply uses a thin client interface, such as a web browser to use the software.  Clients are provided with access to application software but do not have to worry about installation and set up.  Clients typically pay for the software on a "pay-as-you-go" basis or at no charge, where other streams of revenue (such as advertising) can be generated.  
Examples: Google Apps, Dropbox, Facebook, Twitter, any web application on a cloud infrastructure 


Platform as a Service (PaaS)

Building and deploying web applications has traditionally been complex, expensive, and slow. Each application required hardware, an operating system, a database, load balancing and system configuration. This hardware and software needing maintenance, patching, backups and constant management.  

With PaaS, consumers are provided with computing platforms which typically includes the operating systems, programming language execution environment, database, web application server, load balancers and so on.  This provides an instant environment for the deployment of web applications and allows developers to focus on the core business logic of the system (writing the application code) rather than spending considerable time on managing the "platform".  

The consumer does not manage the underlying cloud infrastructure including servers, operating systems, bandwidth, networks and storage.  They have full control over the deployed applications, load balancing, elasticity and configuration of the hosting environment.

Examples: AWS Elastic Beanstalk, Google App Engine, Heroku (SalesForce)


Infrastructure as a Service (IaaS)

IaaS is the foundation block of cloud computing.  Rather than purchasing or renting space in a costly datacenter, cloud consumers rent space in a virtual data center from a cloud provider.  With IaaS the "raw materials" are provided and consumers will pay for only the resources they consume.  These resources include CPU cores, memory, hard disk storage and bandwidth.  Consumers are provided with the capability of modifying the resources available to them, typically through interfaces provided by the cloud provider.
  • Cloud Provider Responsibilities: management of the hardware & networks, ensuring that the servers run correctly with minimal downtime, maintenance of the interface that consumers use to manage IaaS services
  • Cloud Consumer Responsibilities: configuration of the servers, management of the operating systems, management of deployed software including patching
Cloud Providers are not responsible for managing or troubleshooting deployed software, as Consumers are free to deploy millions of different combinations of software packages on the provided infrastructure.

Examples: Amazon EC2, Rackspace, Windows Azure


Deploying on the Cloud (Amazon AWS) - QuickStart Basic Setup

All of the above is all very well in theory, but let us put it into practice by performing a live demonstration of PaaS (Platform as a Service).  We are already familiar with the concept of building web applications, so let us now look at deploying an existing web application on the cloud.  The application we will use is one we built earlier, namely the sample login system.  
This consisted of a few primary files:
The details of creating and deploying it were covered in that section, so we won't go over them again here.  

Note: In that example we did not use a database and we will not use a database here.  There are some extra configuration steps involved in deploying a database application on Amazon AWS and it is not too important that we deal with this here.  Instead, we are just going to deploy this simple, non-database application to demonstrate the basic workings of PaaS on AWS.

In this example, we are going to use AWS Elastic Beanstalk to provide the platform (Java 7 / Tomcat 7) for us so that we can deploy our web application.  In the video, you will hopefully see how simple this process is for us.  We can quickly configure a server of any required processing power, memory, HDD space and elasticity and deploy our application on it for the duration of our need.  

There is little need to explain more here, as the video below describes all of the steps involved.  Feel free to try this yourself, although you will likely need a credit card in order to set up an account.  Please be careful not to create anything larger than a micro server and to terminate your environments after you are finished - otherwise unexpected bills could come your way down the line.  

Video - Deploying our Login System on AWS Elastic Beanstalk

http://www.eeng.dcu.ie/~davidm/courses/ee417/videos/EE417_deploying_on_beanstalk/EE417_deploying_on_beanstalk.html


Deploying on the Cloud (Real World AWS Production Environment)

In the previous example, we successfully deployed our application in the Cloud using AWS Beanstalk.  This created a fairly straightforward public facing Tomcat instance in the default virtual private cloud.  In a real-world scenario, we have a number of extra requirements:
  • We would want to provide both a test and a production environment
  • We would have a database typically attached to our application
  • We should protect both our database and our application server from all external requests (except port 80/443 requests to our load balancer)
  • We should protect our servers through the use of a "Bastion" host
  • We should set up SSL so that traffic to our site is secured
  • We should ensure that our application server and database server are on a private subnetwork
  • We should have the minimal set of rules and routing tables to facilitate the application running
Most of these are networking issues and Amazon AWS provides us with a range of functionality to facilitate the building of network infrastructure.  This infrastructure is entirely virtual, but essentially mimics the traditional real world set-up involving routers, gateways, physical servers and wires!
Does your server room look like this?
Does your server room look like this?

Before we get into Cloud Computing networking, let's talk a little bit first about CIDR.

Classless Inter-Domain Routing (CIDR)

As most of us should be aware, internet addresses have the following format:   a.b.c.d   (where each has a value of 0-255)
Consider the address: 192.168.0.1

This is made up of four octets - the first of these is 192 which can be written as:

1100 0000 which is equal to  128 + 64 + 0 + 0 + 0 + 0 + 0 + 0

To represent the whole IP address, we can use the following table:

 128      64  32  16  8  4  2  1  Result
1 1
0
0
0
0
0
0
 192
1 0
1 0
1 0
0 0  168
0
0 0
0
0
0 0 0  0
0
0
0 0
0 0 0
1
 1

CIDR notation looks like an IP address with a trailing / symbol and a number and it represents a range of IP addresses..  For example,

192.168.0.0/24

The '24' in the above example is known as the bit mask.  The 24 means that the first 24 bits must be the same.  Our first 24 bits are:

192.168.0  =  11000000 10101000 00000000

The remaining bits are allowed to be 0 or 1, which means that we have a range from:

192.168.0.0 =  11000000 10101000 00000000 00000000
up to:
192.168.0.255 = 11000000 10101000 00000000 11111111
and everything in between.

So our 192.168.0.0/24 represents 255 IP addresses which match the pattern 192.168.0.*


More Common CIDR Examples

Question 1: What range of IP addresses is represented by  35.0.0.0/8

Answer: We can represent this address as:

00100011 00000000 00000000 0000000 

The bit mask is 8 which means that the first 8 bits must stay the same:

00100011

with the remaining bits being either 1 or 0.

Essentially, our answer is that this range covers all IP addresses of the form:  35.*.*.*


Question 2: What range of IP addresses is represented by 35.190.0.0/16
Answer: We can represent this address as:
00100011 10111110 00000000 00000000
The bit mask is 16 which means that the first 16 bits must stay the same:

00100011 10111110
with the remaining bits being either 1 or 0.
Hence, we are covering all of the ip addresses of the form:   35.190.*.*


Question 3: What range of IP addresses is represented by 35.190.110.45/32
Answer: This is a simple answer, as the 32 means that all 32 bits must match the 32 bits of the address.
Hence, the CIDR block represents the IP  35.190.110.45 only!


Question 4: What range of IP addresses is represented by 35.190.110.0/23
Answer: This is a little bit of a trickier example, since we aren't dealing with multiples of 8 in our bit mask.  However, the same principal applies.

00100011 10111110 01101110 00000000
The bit mask indicates that the first 23 bits must be the same:
00100011 10111110 0110111- --------

Hence, the CIDR block represents the following:  35.190.110.*  or 35.190.111.*   


Virtual Private Clouds (VPCs)

Amazon AWS enables us to launch cloud services into a virtual network that you design yourself. Traditionally, this would have been handled using the network equipment shown in the image above: routers, switches, gateways, wiring etc. all storage in cooled server rooms.  This equipment obviously involved considerable maintenance, would have occasional hardware failure and had lots of ancillary costs including electricity costs, cooling and rent for the physical location. More importantly however, it cost TIME.  The single largest cost in virtually any software company is salary.  If a senior network engineering is being paid 100k per annum and he/she is spending 30% of their time on managing a network infrastructure, the real cost of that network infrastructure can be raised by 30k per annum.

This is one of the greatest benefits in moving to a Cloud Deployment.  Engineers can set up network infrastructure, databases and servers in a fraction of the time it would take through traditional approaches.  If they are saving time, then the company is saving money!

So we know that a VPC is a virtual network in which we we launch our Amazon services.  When we create a VPC, it will be logically isolated from any other virtual networks in the AWS Cloud and will not be linked to the internet in any way (unless we configure it to). 

When we are configuring our VPCs, we will configure:
  • Subnets
  • Routing Tables
  • Network Gateways
  • NAT Servers
  • Security Settings
Let's talk about a few of these:

VPC Subnets

A subnet is a range of IP addresses in your VPC. This is where our CIDR notation is going to come in useful!  We have two choices here:
  • A public subnet for resources that must be connected to the internet (e.g. our load balancers)
  • A private subnet for resources that we don't want connected to the internet  (e.g. our database servers)
Let's take a look at once of the examples provided by AWS Documentation:

AWS Public Networks with Internet Gateway

By default, all Subnets that are created are private. In order to enable access for instances (e.g. servers) to connect to the internet, we need to do a number of things:
  1. Attach an internet gateway to our VPC
  2. Create routing rules to direct specific traffic through the internet gateway (IGW)
  3. Ensure that security rules will allow outgoing/incoming traffic as appropriate       (later!)
  4. Assign elastic IPs to instances that need to connect to the outside   (later!)

Looking at the diagram above in more detail, we can see that we have created two Subnets: Subnet 1 which is a public subnet and Subnet 2 which is private. 

Subnet 2: Instances only have private IP addresses (10.0.1.5 etc.) which are only internally available.  In addition, there is no Route to the Internet Gateway.  There is only one route allowing traffic within the VPC to addresses of the format 10.0.*.*  (why we learned CIDR!).  This means that EC2 instances in the private subnet have routes to connect with EC2 instances in both Subnet 1 and Subnet 2.  They would be allowed to connect, subject to Security Rules, which we will look at later.

Subnet 1: Instances here have both a private IP address (10.0.0.5 etc.) AND a public elastic IP address (EIP which we will explain shortly).  In addition, the subnet has a custom route table which allows local traffic to be routed locally and other traffic to be routed through the internet gateway.

  • 10.0.0.0/16 -> Means that any requests to connect to addresses of the format 10.0.*.* will be routed locally within the VPC.
  • 0.0.0.0/0 -> Means that all traffic (excluding 10.0.*.*) will be routed through the internet gateway.  The 10.0.*.* routing rule supercedes the 0.0.0.0/0 rule as it has a more restrictive bit mask.


Elastic IP Addresses (EIPs)

When we are dealing with local private networks we typically use IPv4 Private Address Spaces (Wikipedia).  There are a number of available ranges:

10.0.0.0 - 10.255.255.255   = 10.0.0.0/8              (16,777,216 addresses)

172.16.0.0 - 172.31.255.255 = 172.16.0.0/12         (1,048,576 addresses)

192.168.0.0 - 192.168.255.255 = 192.168.0.0/16      (65,536 addresses)

These addresses are typically used for local home networks, LANs and inside our Cloud VPC subnets.  In our subnet examples above, you can see that we use the first of these ranges. 

As these are private address spaces, used on many other networks around the world, they cannot be used as public IP addresses on the internet. 

Hence, if we wish to allow connectivity to our instances from outside, we need to assign them a public IP address.  These IPv4 addresses are in short supply world-wide and you must request them from Amazon where they are needed.  With a public IP address assigned to specific instance, that instance can be connected to from the internet (assuming other settings are correct). 

But what do we mean by Elastic? 

In Amazon AWS, public IP addresses are elasticAn elastic IP address (EIP) is a static IP address designed for dynamic cloud computing.  You can assign an IP address to an instance initially.  However, if that instance were to have a server or software problem, you can quickly remap the elastic IP address to another working instance.

Your elastic IP addresses are associated with your particular AWS account, rather than being tied to a particular instance.  In fact, if you were to destroy an instance on AWS, the IP address would simply be disassociated with the instance but would remain within your account.  Note: you pay a monthly charge for any EIPs that are not associated with a particular instance (to discourage people from being wasteful of IPs).

By default, any instance created in a nondefault VPC, will be assigned only a private IP address.  However, you can request an EIP and associate it with an address where necessary.

Looking at the diagram above again, we can see that the public subnetwork instances had two IP addresses.  For example, the first instance had:

Private IP address: 10.0.0.5       and      Elastic IP Address: 198.51.100.1


Security Groups

A security group acts as a virtual firewall for your instance to control inbound and outbound traffic. You can assign multiple security groups to individual instances.  Note: Security groups act at the instance level and not the subnet level. 

Security groups are made up of sets of rules that govern what traffic can arrive in to an instance and what traffic can leave an instance.

When we create a security group, we give it a format like the following:

Name: MyTomcatSecurityGroup

 Inbound      
 Source      Protocol  Port Range
 Comments
 0.0.0.0/0  ALL      ALL      Allows all inbound traffic from any IP address
       
 Outbound      
Source    
Protocol
Port Range
Comments
 0.0.0.0/0  ALL ALL
Allows all outbound traffic to any IP address

We can then assign this (very liberal) security group to any instances that we create.  This group facilitates all traffic to/from everywhere.

A more restrictive security group for a server running Tomcat, might be the following:
 Inbound      
 Source      Protocol  Port Range
 Comments
 0.0.0.0/0  TCP   
 80  Allows HTTP Traffic Inwards
 0.0.0.0/0  TCP  443  Allow HTTPS Traffic Inwards
 12.13.14.15/0  TCP  22  Allow SSH Access from the System Admin
       
 Outbound      
Source    
Protocol
Port Range
Comments
 0.0.0.0/0 ALL  
ALL
Allow all traffic outbound

This provides us with fine-grained control over what traffic is allowed in and out of our AWS instances.

Note: It is also possible to set up security group rules that reference other security groups.  For example: you might say that a database security group could have an inbound rule to accept port 1521 (Oracle) requests from an application server security group.  You will see this in practice in some of the diagrams below.


Deploying a Three-Tier Web Application in AWS

Looking back at a typical three-tier web application, it should look like the following:

Three-tier system
In our case, we will have a browser front end, communication with Tomcat over HTTP with our Tomcat-hosted application in turn communicating with a database server.

So let us attempt to place this into an AWS VPC (and get a few things wrong!)

Basic VPC Setup for a Three-tier System
Basic VPC Setup for a Three-tier System on AWS

We indicated that we would get a few things wrong.  So let us consider some of these:

  • Application Server Security: our application server can be connected to from any location and on any port.  This opens up numerous points of attack for hackers.  If a hacker was able to work out our SSH username/password (or private key) then they could connect to our server and from there do whatever they wished, including destroying our services or stealing our data from our database.
  • Database Server Security: there is no need for our database server to have any other incoming ports available than the standard database port (1521 for Oracle, 3306 for MySQL).  In Amazon AWS, we won't actually set up full servers for database provision, but rather use their RDS service. In addition, we only ever want a connection to be made from the application server itself.

So let's take our previous diagram and make a couple of modifications:

VPC with Improved Security Group Settings

Here, we have changed the security groups so that the application server can be connected to from: 0.0.0.0/0 for HTTP/HTTPS traffic - after all, this is a web application and usable by anyone, but specifically only those ports are available.  We also added an entry for  12.13.14.15 to be able to connect to port 22.  We are assuming here that 12.13.14.15 is the IP address of the system administrator for this network and this port will allow them to SSH in to the Tomcat server, but only from that specific IP address.

So now we can see that with a few security settings, we can greatly secure up our network.

What we have implemented now is pretty good but it's not production level.  This section is entitled 'Deploying on the Cloud (Real-World Production Environment) so we had better live up to the name!

So what is wrong with our new setup?

  1. The IP address of our application server is known by hackers: the web address points directly at the elastic IP.  In some respects, as long as our security groups are correct we *should* be ok here, as long as we lock down the various ports.  However, if we host all of our servers in this way it creates many attackable addresses.  If our network administrator makes a mistake on one of these security groups, hackers could potentially get into your network.
  2. Best practice says we should not have our application server in a public network: if we use load-balancers, we have no particular need to place our Application Servers into a public subnet.  We can place our load balancers in a public subnet and move our application servers to the much more security private subnets.
  3. Any production deployment should have a staging/test deployment server: In a real world production environment, web application code is constantly changing.  However, these code changes need to be tested rigorously against a staging environment before being pushed to the production deployment.  The staging/test environment should mimic the production environment as much as practicable, but would typically be more restricted regarding who can access it.

So, with all of this in mind, let's jump ahead to a more detailed deployment: (not perfect but almost there!)

Moving Servers to Private Subnets
Here we have done a few main things:
  1. We have introduced a Staging/Test environment in a separate pair of subnets.  Our staging environment exists in subnets 10.1.1.0/24 and 10.1.1.0/24.  Our production environment exists in subnets 10.1.2.0/24 and 10.1.12.0/24.  By placing our environments in different subnets and by applying different security group settings, this gives us full control over these environments.  For example, it is impossible for us now to accidentally point our STAGING server at the PRODUCTION database, which could result in a loss of data.
  2. We have moved our application servers to the much more secure private subnets.  This greatly reduces the risk of hacking from outside and limits the damage that server mis-configuration can cause.
  3. We are now accessing our servers through Elastic Load Balancers.  This has the added bonus of allowing us to auto-scale our environments elastically.  For example, we could spawn up multiple servers each sharing the user load between them.

So are we done? Unfortunately, no!

While we are a good deal closer to what a production environment should look like, we have a couple of problems.

  1. We are not able to connect to our STAGING or PRODUCTION servers any more.  In the diagram above, you can see that the only route in to our servers is over Port 80 originating from our Elastic Load Balancer.  While this is ultra secure, it is unfortunately too secure!  There are many scenarios where we might need to connect to our application servers (via SSH - secure shell) and work on them directly.
  2. The STAGING and PRODUCTION servers have no internet connectivity.  Isn't this a good thing? Mostly, but not entirely!  Sometimes our application servers will need to communicate outwards on to the internet.  For example, maybe they want to utilise a web or RESTful service somewhere on the web.   Or indeed, when we want to patch the servers (e.g. in Linux using 'sudo yum update') those servers will need to be able to communicate with the internet to download the required patches and software.

To fix these two problems, the last two parts that we need to include are:

  1. A Bastion Host
  2. A NAT Gateway
Full Working Production Network

Figure: Our full, working production environment with appropriate security settings.


Bastion Hosts

One of the elements we just introduced as a secure Bastion Host.  A bastion comes from a castle fortification terminology (https://en.wikipedia.org/wiki/Bastion) and is designed to protect the castle and it's inhabitants.  The Bastion Host in this scenario has a similar function.  It is designed to protect all of our instances in our VPC from attack!

As can be seen in the diagram, there is only one external facing server which a hacker can attempt to connect to.  All of the other servers are configured so that the only way an individual could connect to them is by logging into the Bastion host in the first instance.  For this reason, Bastion hosts are sometimes called 'Jump Servers'.  Logging in to our primary servers requires a two stage process. 

Why is this better?

  1. We have less externally facing servers: there is now only one point of attack
  2. We only have to be careful with the Bastion Security group to ensure that only specific IP addresses can access
  3. We will have separate usernames/passwords/private keys for our Bastion hosts and servers
  4. Bastion hosts should only have a minimal set of software installed so are harder to hack
  5. Hackers do not know the elastic IP address of the Bastion host and hence have nowhere to target in the first instance
  6. Bastion servers can be set up so that two-factor authentication is required on logging in (e.g. Google Authenticator)

For one of our servers to be compromised, the hacker would need to know the IP address of the bastion host, have security keys for both the Bastion and the target server and be able to attack from a specific IP address.  If Bastion was protected with two factor authentication, they would also need to two know the seed used to generate these random 6 digit numbers.

-> Unless you have done something stupid, hackers will not get in.

Having said that, this section is focused on network infrastructure.  While we might have secured our network infrastructure, this does not necessarily mean that your application is secure.  Software security concerns, such as SQL Injection, Cross-site Request Forgery (CSRF), Cross-Site Scripting and many many more are all still concerns when we build web applications.


NAT Gateways

Network Address Translation (NAT) Gateways are used to enable instances located in a private subnet to connect to the Internet or to other AWS services.  Importantly, they also prevent the Internet from initiating a connection with those instances. 

Servers in private subnets frequently need to initiate traffic to the Internet.  For example, if the servers are being updated or if our web application needs to make an external request.

When you create a NAT gateway, you must specific the public subnet in which the NAT gateway resides.  The NAT gateway also needs to have a public Elastic IP address assigned to it to facilitate Internet communication. As the NAT gateway is located in a public subnetwork, it will in turn send traffic via the Internet Gateway to the Internet. 

Finally, we need to set up a route from the private subnets to point Internet-bound traffic to the NAT gateway.

Our instances in the private subnets are now able to send outbound internet traffic as required.


Conclusion

Creating a network infrastructure on AWS is not an easy process to learn.  It requires an understanding of the basic building blocks shown above.  When designing a network, it is important to work on a policy of 'DENY ALL' and slowly work towards enabling communication.  This will take some trial and error and you will lose some of your hair in the process! 

However, the benefits of a well-designed network infrastructure will be many-fold, particularly in the area of security.  Hackers have increasingly powerful tools available at their disposal and are all too willing to exploit any mistakes you make in a production environment.

There are many other AWS tools not covered here in these notes (VPC Peering, Access Control Lists, Customer Gateways, VPNs etc.) but this content should start you well on the way to establishing your own network if this is something you need to do in the future.



Comments