---
tags: devtools2022
---
# 01-Amazon Web Server
**[Day1 AM]** We will be using **AWS EC2 Instance** and other AWS services to demonstrate several learning points in this course. You can choose to use your own account if you wish, or your own computers (if you already have POSIX compliant OS).
## Schedule and Learning Objectives
* **0900-0930**: Setting up EC2 instance, SEED Lab instance, run starter program
## Motivation
Suppose we are a team working on a project that requires a Web Server (or any other server for public clients to use). **What are the things we should consider beforehand and potential challenges?**
We certainly need at the very least:
- Collaboration tools: _we can't be sending the code back and forth via email or chat apps_. 
- A reliable **Computer** to **run** the code: _sure we can use our PC, but it has to run 24/7, 365 days a year, how do we make sure such reliability?_
- A suitable **Operating System** that can actually run the code: _Windows App cant run on macOS, and vice versa. We also need to ensure dependency packages are all installed properly_. 
- **Tools** to monitor the server and maintain the code: _How do we know if it is running fine? Has it crashed? Do we need to restart the computer? If yes, how do we run the app again?_ 
- **Security Measures**: _is the network traffic encrypted or prone to cyberattacks?_
We must **choose** a suitable Operating System and hardware to succesfully deploy our server `html.js` or `server.js`. Surely we can deploy it on our personal computer, but that's not an ideal machine to use for long-term servers (unreliable, lack of proper security measures, not to mention **expensive** to maintain).
As such we typically rely on existing services, like the AWS EC2, Google Compute Engine, DigitalOcean Droplets, Azure VMs among many others. All of these services are web services that provides secure, resizable compute capacity in the cloud. They're **ideal** to be used to run our server code reliably.
## Amazon Web Server setup (50 mins)
For the purpose of this course, we will be using AWS. We have **created** an EC2 **Instance** for each of you.
### EC2 Creation [FYI]
This section is FYI only, since we have created the instances for you. Below is a brief explanation on how to create an **instance** of your own.
Then, choose a region of your choice. **Remember this region** because that's where your instance is hosted. In this example, we use "Ohio".

Right now we do not have any instances yet, so let's create one. Click on **Launch Instances**, and select `Ubuntu Server 20.04 LTS` for the **Operating System** (also known as machine image) option:

For the instance type, select `t2.micro`. It is **free tier** eligible. The *instance type* simply defines the hardware capacity of our computer.

Click "Review and Launch" to immediately launch the Instance. We can do other settings later. You will see this page:

When you click "Launch", you will be prompted with key-pair generation. Select create new pair and give it a name, then download the `.pem` file.

This is important if you want to remotely access your AWS EC2 instance via `ssh`. We will do this later. For now, you will see that you have one instance in the dashboard:

Click on the instance and then click the **connect** button on the next page:

## Connect to EC2
There are two ways to connect to your EC2 since we have given the IP address and login username + password to you.
### Connect to EC2 using SSH client
If you wish to use your own SSH client, then you can follow these steps:
1. Navigate to the private key downloaded earlier, and change it to be executable using the command `chmod 400 <filename>.pem`
2. Execute `ssh` command to your instance.
3. You can also use **VSCode for this**. See [this](https://code.visualstudio.com/docs/remote/ssh) guide.
> Bonus: see [amazing stuffs](https://vscodecandothat.com) VSCode can do.
The output should looks similar to that of EC2InstanceConnect:

### Connect to EC2 using Cloud9
Another convenient and recommended way to connect to your EC2 instance is to use AWS Cloud9. Cloud9 is a **free** web IDE that allows you to connect and access your EC2 instances. However, you need to **create an AWS account first** (which needs a credit card).
> Worry not, that's just for guarantee and you will not be charged.
Select Cloud9 services from the "Services" tab of your AWS console:

Afterwards, click on *create environment*:

Give your environment a nice name:

Configure the environment using your EC2 username (which will be `ubuntu` by default) and hostname:

The EC2 hostname can be found in the EC2 dashboard we saw earlier

**Click "Copy key to clipboard" at Cloud9 environment setting**, and head to your EC2 InstanceConnect terminal or your own terminal (that has SSH access to your EC earlier) and paste in the following commands in succession:
```shell=
sudo apt-get update
sudo apt-get -y upgrade
echo <paste the copied key> >> ~/.ssh/authorized_keys
sudo apt-get install -y nodejs
```
The first two commands updates the Ubuntu OS in your EC2. The third command adds the Cloud9 public key to your EC2 `~/.ssh/authorized_keys` file. The complete command will look something like this:
```
echo ssh-rsa 5QGOtWtUJqiBnZQb0ZqPXzgCmd0JgH0H/pSZSr2qFqUjHgYC/yknqCQ6O0WhmeK9ond8vR40zk4aZKnuvE+ZTZDQhMtQSuBcyQPzAqLmXmWAHF5vPAsdLmCXVRTAsQ6aYeDom8viwiZ1yHTuWWAuxeNm7SQTIxho0KSjwRc3OO1gIU6UhFK/jpWZ8X+vEppMRKYMiB1+OTUbrcL9UPUizXp5GIkNO7bgqRtvIRzRriTkiXg+zOSIEcg7KkXXPhoeLUHcAUGpqKqesGTy9jJars8hRAczRaynDL5lHiiL3Ah4UXAvl8bO+WosohPai/4nZ6TX45yOMWEIKidCGal8VGjwnEmsWMmWduwquXey4T6tcGK7cLmM9hPymdwyxgZMTv05Cop2d3XemeH/NNu9BNWucvoZjbCieKih2wcqqxYdwxNFhKzc+TydJGa7ALrS+BznJMwb+HrfDpVzsWBFAwOUseC1vgVKOCpkeriDp+PVMwjly0ABwtJkww5/73zmVewet7eN+EAYPusd9SJAF+CbevRb18dhFxUSaFFetKBbcns9hzBZNR6S7GQ8vATnsrhj9Qzd/krWmFmsX+mMRqzSDng74WVnwBtFWM253ZEdCcRl8RFY0ia0ff0upJ++dwrNCm9k/Y/U+Km9fuYaC9NX12MNB4vwdQ== nat+581994641164@cloud9.amazon.com >> ~/.ssh/authorized_keys
```
You can read the file by typing the command:
```
cat ~/.ssh/authorized_keys
```
Finally, the fourth command is to install `node` into the EC2. Cloud9 requires `node` to run. You might be faced with warnings as such to restart some outdated daemon. Simply select (navigate with arrow and press space to select) all and tab to the `OK` to restart.

Once you're done, head back to the Cloud9 dashboard and click on "next step":

This will bring you to the next page where you can simply click "Create Environment". You will then be prompted with this:

You can click "next" to allow Cloud9 to install manually, but that's rather hassling and you might be met with unexpected errors. It's best to install this manually.
> For now, just ignore this and head back to your EC2 SSH console.
Right click on the C9 install link and **get the link address**: https://d1q2hgnv37wylw.cloudfront.net/static/c9-install.sh
> If it's still the same as the above, copy the commands below to continue. Else replace the link for `wget` with the new link. We never now when they will ever update their CDN.
Head back to your EC2 terminal in InstanceConnect or your own SSH client. Type the following commands in succession:
```shell=
wget https://d1q2hgnv37wylw.cloudfront.net/static/c9-install.sh
chmod a+x c9-install.sh
sudo apt-get -y install python2
sudo apt-get -y install build-essential
./c9-install.sh
```
The first command downloads the shell script `c9-install.sh` from the cloudfront website. We then change the **file permission** of this script into **executable**. The next two commands install the necessary libraries (Python and some basic utilities -- generally includes the GCC/g++ compilers and libraries). The last command executes the script to install C9 into your EC2.
Wait for a few minutes and once it is done, return to your Cloud9 webpage and click **refresh** to **relaunch** the IDE. You can also find your environments in the Cloud9 dashboard:

The IDE looks like this:

If you're faced with outdated package warning e.g: `tmux`, just click `Update`:

Right now, you only have **one file** in your Root directory, which is the `install.sh` script you downloaded earlier using `wget`. With this, you're all connected with a convenient editor GUI to traverse and manipulate the EC2 filesystem.
One last thing to do is to **run** the code you pushed at the remote github repository in this EC2.
## Exercise: Run the code in your EC2 instance (5 mins)
You can create this program `html.js` in your EC2 instance.
```javascript
// Sample server that serves direct HTML
const http = require("http");
const host = '0.0.0.0';
const port = 8000;
const requestListener = function (req, res) {
res.setHeader("Content-Type", "text/html");
res.writeHead(200);
res.end(`<html><body><h1>This is HTML</h1></body></html>`);
};
const server = http.createServer(requestListener);
server.listen(port, host, () => {
console.log(`Server is running on http://${host}:${port}`);
});
```
If you don't have npm installed, install it:
```
sudo apt install nodejs
```
> Sure you can be fancy and use `[nvm`](https://github.com/nvm-sh/nvm).
You should have this at the C9 IDE and run the server with command `node html.js`.

But wait! How do we access them? We cant just do http://0.0.0.0:8000 in our browser because this is now hosted at another machine (our EC2).
> In the context of servers, 0.0.0.0 means *all IPv4 addresses on the local machine*. For instance, if a host is assigned two IP addresses, 192.168.1.1 and 10.1.2.21, and a server running on the host is configured to listen on 0.0.0.0, it will be reachable at both of those IP addresses. Note that this is common to hosts that have more than one *[network interface](https://goinbigdata.com/demystifying-ifconfig-and-network-interfaces-in-linux/)*, as they have one Internet address for each interface.
This means we must find out the **PUBLIC IP address** of our EC2 instance.
> We have given this to you.
Afterwards, construct the url: `http://<your-EC2-public-IPv4>:8000`.
### Security Rules
We need to also tell our EC2 to **accept** incoming traffic. **We have done this for you**. If you have your own account and would like to do it on your own, then go to the **security** tab in your instance's EC2 dashboard, and click on the security group entry highlighted in blue:

Click on "edit inbound rules" in the new page:

Then add the new rule to allow **custom TCP** connection from any IPv4 address (so the public can access this server) and give it a nice description:

After saving the inbound rules, try the url to your server in your computer's browser. You should see the nice webpage:

## Possible error: EADDRINUSE
If you're met with certain errors like this when running node for the second time:

..it means that there's a process that is using that exact port 8000. We need to manually **kill** the **process** by typing the command:
`ps aux | grep node`. This lists out all processes with the name "node":

The first entry indicates that there's a `node` process that still runs `html.js`. We need to kill that process by the `kill` command:`kill -9 <pid>` where `pid` is the process id number (51934) in this case. Afterwards, you can run `node html.js` again.
> Always press ctrl+c to kill the `node` process properly.
## Conclusion
From now onwards, you can choose to use this EC2 instance to host any services you want for the duration of this course.
# Summary
- [x] Login to EC2, setup security groups
- [x] Setup SSH Key, connect using VSCode or Cloud9
- [x] Host simple server, reachable via public ip:port
# Homework
Please **install** SEED Ubuntu 16.04 VM (+ VirtualBox) following [this](https://seedsecuritylabs.org/labsetup.html) guide before tomorrow's class. You will need it as part of the class activities.