# Lab 9: NGINX and NTP
## *Kseniya Evdokimova*
---
## **The exercises from the lab:**
**Install Nginx From Ubuntu Repositories**
Nginx is included in the Ubuntu 20.04 default repositories, so to install it I enter the following command:
`$sudo apt-get update`
`$sudo apt-get install nginx`


I will *verify the successful installation* by running by checking the software versionwith the command:
`$nginx -v`

The system displays the software version of Nginx.
**Controlling the Nginx Service**
Start by checking the status of the Nginx service:
`$sudo systemctl status nginx`

It is not active.
If Nginx is not running, we can use the following command to launch the Nginx service:
`$sudo systemctl start nginx`

**Allow Nginx Traffic**
Nginx needs access through the system’s firewall. To do this, Nginx installs a set of profiles for the Ubuntu default ufw (UnComplicated Firewall).
Start by displaying the available Nginx profiles:
`$sudo ufw app list`

In order to check current general rules if any, use:
`$ufw status verbose`

To grant Nginx access through the default Ubuntu firewall (ufw or netfilter), if in your machine firewall was enabled and then enter the following:
`$sudo ufw allow 'nginx http'`
The system should display Rules updated.
Refresh the firewall settings by entering:
`$sudo ufw reload`

I've added the first command, since after the first attempt to reload I got "firewall not enabled skipping reload".
To allow both, enter:
`$sudo ufw allow 'nginx full'`

**Test Nginx**
Nginx service is running, as in the previous step.
The Nginx Welcome page can be loaded in the terminal using curl:
`$sudo apt-get install curl`
`$curl –i 127.0.0.1`
The system displays the HTML code for the Nginx Welcome page as well as http headers.

**Configure a Server Block (Optional)**
In Nginx, a server block is a configuration that works as its own server. By default, Nginx has one server block preconfigured.
It is located at /var/www/html. However, it can be configured with multiple server blocks for different sites.
Note: Examples use test_domain.com for the domain name. I will replace with my own domain name.
Create a Directory for the Test Domain
In a terminal window, I created a new directory by entering the following:
`$sudo mkdir -p /var/www/test_domain.com/html`

Configure Ownership and Permissions
With the use of chown and chmod configured ownership and permission rules:
`$sudo chown –R $USER:$USER /var/www/test_domain.com`
`$sudo chmod –R 755 /var/www/test_domain.com`

**Create an index.html File for the Server Block**
I opened index.html for editing in a text editor nano:
`$sudo nano /var/www/test_domain.com/html/index.html`
In the text editor, entered the following HTML code and saved:
```
<html>
<head>
<title>Welcome to kseniyadomain.com!</title>
</head>
<body>
<h1>This message confirms that Nginx server block is working!</h1>
</body>
</html>
```

**Create Nginx Server Block Configuration**
Open the configuration file for editing:
`$sudo nano /etc/nginx/sites-available/test_domain.com`
Entered the following code:
```
server {
listen 80;
root /var/www/kseniyadomain.com/html;
index index.html index.htm;
server_name kseniyadomain.com www.kseniyadomain.com;
location / {
try_files $uri $uri/ =404;
}
}
```

> try_files $uri $uri/ =404 - checks the existence of files/directories in the specified order and uses the first found file for request processing; the processing is performed in the current context. If none of the files were found, an internal redirect to the uri specified in the last parameter is made.
> This is one of a number of common tricks to overcome a particular script injection exploit by ensuring the the backend file (*.php for example) is a real file before sending the URL to the upstream interpreter.
**Create Symbolic Link for Nginx to Read on Startup**
Create a symbolic link between the server block and the startup directory by entering the following:
`$sudo ln –s /etc/nginx/sites-available/test_domain.com /etc/nginx/sites-enabled`

**Restart the Nginx Service**
Restart Nginx by running the following command:
`$sudo systemctl restart nginx`
And test the Configuration
`$sudo nginx –t`

**Modify the Hosts File (Optional)**
Display the system’s IP address with the following command:
`$hostname –i`
Make a note of the IP address displayed: 127.0.0.1.

Next, open /etc/hosts for editing:
`$sudo nano /etc/hosts`
In an empty space just below the localhost information, add the following line:
127.0.1.1 test_domain.com www.test_domain.com

*Check testdomain.com in a Web Browser*
Open a browser window and navigate to test_domain.com (or the domain name you configured in Nginx).

## **Questions to answer
### 1. Configure static web page and generate ssl certificate (certificate with your own domain name) and configure it in the web server, enable redirection from http to https. Show you configuration of nginx and certificate used (make screenshots from the browser)
> #### Preparation for this question (and part of the solution) is in the part above
**Creating the SSL Certificate**
SSL works by using a combination of a public certificate and a private key. The SSL key is kept secret on the server, used to encrypt content sent to clients. The SSL certificate is publicly shared with anyone requesting the content, used to decrypt the content signed by the associated SSL key.
We can create a self-signed key and certificate pair with OpenSSL:
`sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt`

- openssl: This is the basic command line tool for creating and managing OpenSSL certificates, keys, and other files.
- req: This subcommand specifies that we want to use X.509 certificate signing request (CSR) management. The “X.509” is a public key infrastructure standard that SSL and TLS adheres to for its key and certificate management. We want to create a new X.509 cert, so we are using this subcommand.
- x509: This further modifies the previous subcommand by telling the utility that we want to make a self-signed certificate instead of generating a certificate signing request, as would normally happen.
- nodes: This tells OpenSSL to skip the option to secure our certificate with a passphrase. We need Nginx to be able to read the file, without user intervention, when the server starts up. A passphrase would prevent this from happening because we would have to enter it after every restart.
- days 365: This option sets the length of time that the certificate will be considered valid. We set it for one year here.
- newkey rsa:2048: This specifies that we want to generate a new certificate and a new key at the same time. We did not create the key that is required to sign the certificate in a previous step, so we need to create it along with the certificate. The rsa:2048 portion tells it to make an RSA key that is 2048 bits long.
- keyout: This line tells OpenSSL where to place the generated private key file that we are creating.
- out: This tells OpenSSL where to place the certificate that we are creating.
These options will create both a key file and a certificate.
In the Common Name I will write my server’s public IP address.

Both of the created files will be placed in the appropriate subdirectories of the /etc/ssl directory.
**Create a strong Diffie-Hellman group**, which is used in negotiating Perfect Forward Secrecy with clients:
`sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096`
When it’s done, I will have a strong DH group at /etc/nginx/dhparam.pem that we can use in our configuration.

**Configuring Nginx to Use SSL**
**Creating a Configuration Snippet Pointing to the SSL Key and Certificate**
First, let’s create a new Nginx configuration snippet, self-signed.conf, in the /etc/nginx/snippets directory.
`sudo nano /etc/nginx/snippets/self-signed.conf`


**Creating a Configuration Snippet with Strong Encryption Settings**
Next, we will create another snippet that will define some SSL settings. This will set Nginx up with a strong SSL cipher suite and enable some advanced features that will help keep our server secure:
`sudo nano /etc/nginx/snippets/ssl-params.conf`


**Adjusting the Nginx Configuration to Use SSL**
Back up our current configuration file:
`sudo cp /etc/nginx/sites-available/kseniyadomain.com /etc/nginx/sites-available/kseniyadomain.com.bak`

Then I made adjustments to the configuration file:
`sudo nano /etc/nginx/sites-available/kseniyadomain.com`
*FROM:* 
*TO:* 
This configuration listens on port 80 (HTTP) and performs the redirect to HTTPS.
**Adjusting the Firewall**

We can allow the “Nginx Full” profile and then delete the redundant “Nginx HTTP” profile allowance:
`sudo ufw delete allow 'Nginx HTTP'`

**Enabling the Changes in Nginx**
Make sure that there are no syntax errors in our files:
`sudo nginx -t`

Restart Nginx to implement our changes:

**Testing Encryption**
In web browser I type https:// followed by the IP into the address bar:

Because the certificate we created isn’t signed by one of your browser’s trusted certificate authorities
After clicking “ADVANCED” and then choosing proceed to your host anyways we will see our web-page:

Let's check whether the redirect functions correctly. http://kseniyadomain.com results in the same warning page:

**Changing to a Permanent Redirect**
Open the server block configuration file again:
`sudo nano /etc/nginx/sites-available/kseniyadomain.com`
Find the return 302 and change it to return 301:

Applying changes:

### 2. On the webserver configure maximum file upload/download 1GB to site. If you have any other usefull configuration, it also could be shown
The **client_max_body_size** directive sets the maximum allowed size of the client's request body, specified in the "Content-Length" line in the request header. If the size is larger than the specified one, the error "Request Entity Too Large" (413) is returned to the client.
So, we need to specify this parameter in /etc/nginx/nginx.conf:

And then add the following line into http section **client_max_body_size 100m;** :

After reloading nginx changes will be applied:

We can also specify the timeout by adding into **location / {}** section the following lines:
```
location / {
...
proxy_connect_timeout 200;
proxy_send_timeout 200;
proxy_read_timeout 200;
...
}
```
### 3. Configure your machine synchronization with any NTP server which located in the United Kingdom.
First, **install NTP with apt.** You can use any service such as chrony.
`$ sudo apt install ntp`

by checking service
`$ sntp --version`

**Sync the clock of NTP client machine with NTP server**
By default, NTP is configured to pull the time from internet servers. However, we can manually configure it.
`sudo vim /etc/ntp.conf`
Changing to the following:

After making the changes to the /etc/ntp.conf file, restart the NTP service using the following command:
`$ sudo service ntp restart`

**View NTP Synchronization Status**
In order to view NTP current synchronization status, issue the following command in
`$ ntpq -p`
