<p align="center">
  <a href="https://git.konsthol.eu/konsthol/SecDep">
    <img src="assets/images/logo.png?raw=true" width="800"/>
  </a>
</p>

### Instant ⚡ Secure 🔒 Cloud ☁️  Docker Deployment 💻

Automated secure docker images deployment and virtual machine management using (mainly) the [libcloud](https://github.com/apache/libcloud) <a href="https://libcloud.apache.org/"><img src="https://libcloud.apache.org/images/libcloud_logo.png" width="25" /></a> library to connect to <a href="https://aws.amazon.com/"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Amazon_Web_Services_Logo.svg/512px-Amazon_Web_Services_Logo.svg.png?20170912170050" width="25" /></a>, <a href="https://azure.microsoft.com/en-us/"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Microsoft_Azure_Logo.svg/187px-Microsoft_Azure_Logo.svg.png?20210815110837" width="60" /></a> and <a href="https://cloud.google.com/"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Google_Cloud_logo.svg/220px-Google_Cloud_logo.svg.png" width="100" /></a>. 

# Description 📔 and motivation 🧐

Have you ever wanted to instantly deploy a simple virtual machine (or multiple) using one or more of the IaaS that the top 🔝 3 cloud providers offer? 🤔 If yes 🙌💡, you might have noticed some things that keep you off like the fact that their web portals are bloated 🫃 for your use case or confusing 😕. Or that more often than not the same goes for their official cli tools 🤦. In the case you want to manage more than one provider's virtual machines, it becomes a hassle having to head over to their web portal, or tool and do the same thing in a different manner.

That's where SecDep comes in 💪. With SecDep, you can manage your virtual machines across all three cloud providers with ease 😎 without having to think of where to go and how to get there to do what you want 🥳.

# Features and roadmap 🗺️

- [x] Virtual machine creation
    - [x] GCE
    - [x] Azure
    - [x] AWS
- [x] Virtual machine actions (delete, start, stop, reboot)
    - [x] GCE
    - [x] Azure
    - [x] AWS
- [x] Virtual machine simple ssh connection
- [x] Interactive `.env` file editing
- [x] Provider image, location, size and instance listing
    - [x] GCE
    - [x] Azure
    - [x] AWS
- [x] Choice to perform above actions and instance listing on a single or all providers
- [x] Hardening during creation
    - [x] SSH hardening
    - [x] Firewall installation and configuration (UFW or firewalld)
    - [x] Fail2ban installation and configuration
    - [x] Kernel Security Module installation (AppArmor or SELinux)
    - [x] Docker Rootless installation
    - [x] gVisor installation and integration with Docker Rootless
    - [x] CronJob to update the system periodically
    - [x] CronJob to allow or disallow docker ports
- [x] Docker deployment during hardening
    - [x] Single docker-compose file deployment
    - [x] Pulling of multiple docker images
    - [x] Automatic portainer deployment
    - [x] Automatic watchtower deployment

# Prerequisites 📋

Even though we want to avoid using the tools or the web portals we actually have to do it just once to have everything set up to go 😐.

## GCE

First and foremost, you need to have a Google account. If you don't have one, you can create one [here](https://accounts.google.com/SignUp?hl=en).

Then follow the instructions 👉 [here](assets/pages/gce/GCE_setup.md) to set up your GCE account.

Instructions based on [libcloud's](https://libcloud.readthedocs.io/en/stable/compute/drivers/gce.html#service-account) documentation.

## Azure

For Azure you need to be a part of an organization that has an Azure subscription 🏢. 

Then follow the instructions [here](assets/pages/azure/Azure_setup.md) to set up your Azure account.

Instructions based on [libcloud's](https://libcloud.readthedocs.io/en/stable/compute/drivers/azure_arm.html#connecting-to-azure) documentation.

## AWS

For AWS you firstly need an [account](https://aws.amazon.com/account/) and then to follow the instructions [here](assets/pages/aws/AWS_setup.md) 👈.

# Dependencies 📦

We would have 3 core external dependecies but due to missing functionality in libcloud when it comes to Azure management we need 6 of them. The rest are just quality of life dependecies 🏖️

1. [libcloud](https://github.com/apache/libcloud) which is the main dependency to connect to the cloud providers
2. [python-dotenv](https://github.com/theskumar/python-dotenv) which is used to read the `.env` file
3. [paramiko](https://github.com/paramiko/paramiko) which is actually needed for the deployment of libcloud
4. [azure-sdk-for-python](https://github.com/Azure/azure-sdk-for-python) from which we need
   1. [azure-identity](https://pypi.org/project/azure-identity/) to authenticate with Azure
   2. [azure-mgmt-resource](https://pypi.org/project/azure-mgmt-resource/) to manage Azure resources
   3. [azure-mgmt-network](https://pypi.org/project/azure-mgmt-network/) to manage Azure networks
5. [shtab](https://github.com/iterative/shtab) which is used to generate bash and zsh completion scripts
6. [rich](https://github.com/Textualize/rich) which is used to make the output more colorful and easier to read

# Installation 🛠️

## Cloning the repository 📁

You can clone the repository by running `git clone https://git.konsthol.eu/konsthol/SecDep.git` in the directory you want the files to reside.

It goes without saying that you need to have git installed and that you need python to run it since it is a python script afterall.

## Installing the dependencies 📥

The simplest way to install them is to run `pip install -r requirements.txt` in the root directory of the project.

If you don't have pip installed you can install it by running `sudo apt install python3-pip` on Debian based systems or `sudo dnf install python3-pip` on Fedora based systems.

For other systems you can check [here](https://pip.pypa.io/en/stable/installation/) 👈 for more information.

# Walkthrough 🚶

Assuming you have set up your accounts and have the dependencies installed, you can now start using SecDep.

Check this [page](assets/pages/usage/usage.md) to get more familiar with the program.

# Some program outputs 📊

Images and videos of common tasks will reside [here](assets/pages/demo/demo.md)

# Connecting to the virtual machines 🛰️ 🖥️

If you want to connect using your ssh client you will be able to run `ssh -i ~/Path/To/SecDep/secdep secdep@<ip>`.

On instance creation the actual ssh command will be outputted once so you'll able to just copy and paste to connect 😎

To use PuTTY you will need to probably add the key to the program.

The ip will be outputted after the creation of the virtual machine.

If for any reason you delete either the public or the private key they will both be regenerated and you should probably delete the virtual machines that use it or find another way to log in and manually put the secdep.pub key to the authorized_keys file of the secdep user.

# Hardening 🛡️

By using the `--deploy` flag, apart from the vps creation, you will also get a more secure than default virtual machine.

The extra security measures are:

1. SSH hardening

We configure sshd with better security measures among which are:
1. Disabling root login
2. Disabling password authentication
3. Allowing only public key authentication
4. Changing the default port

2. Firewall installation and configuration

We install and configure a firewall (UFW or firewalld) to block all incoming traffic except for the ports we need.

3. Fail2ban installation and configuration

We install and configure fail2ban to block ip addresses that have too many failed login attempts.

4. Kernel Security Module installation (AppArmor or SELinux)

We install and setup a kernel security module (AppArmor or SELinux) on enforcing mode to confine the processes.

5. Docker Rootless installation

We install docker rootless to run docker as a non-root user and avoid the security risks that come with running docker as root.

6. gVisor installation and integration with Docker Rootless

We install gVisor to add an extra layer of security to docker containers by running them in a more sandboxed environment.

7. CronJob to update the system periodically

We create a cronjob to update the system periodically to avoid security vulnerabilities that might come with outdated packages, with a script that works on all supported distros.

8. CronJob to allow or disallow docker ports

We create a cronjob to allow or disallow docker ports periodically to avoid security vulnerabilities that might come with having ports open that we forgot to close and no longer need.

9. Watchtower deployment

When using the `--deploy` flag, we also deploy watchtower to automatically update our docker containers to avoid security vulnerabilities that might come with outdated containers.
For more information about watchtower check [here](https://containrrr.dev/watchtower/)

# Docker deployment 🐳

The `--deploy` flag also allows you to pull containers that you may need by name like so:

`--deploy <container_name1> <container_name2> ...`

A full example using aws would be:

`python3 secdep.py -P aws -c -n test-node -s t3.micro -i ami-08869bacfa1188ec9 --yes --deploy traefik owncast/owncast:latest`

## Docker compose 🐙

By having a `docker-compose.yml` file in the same directory as the script, you can deploy it by using the `--deploy` flag like so:

`--docker_compose --deploy`

A full example using aws would be:

`python3 secdep.py -P aws -c -n test-node -s t3.micro -i ami-08869bacfa1188ec9 --yes --docker_compose --deploy`

Note: The needed ports will be automatically allowed by the firewall but you should change any volume mappings to directories owned by your user (secdep) and not by root

## Portainer

By default, with the use of the `--deploy` flag, portainer will be deployed as well to help you manage your containers in a more user friendly way.

You can access it by going to `https://<ip>:9443` after which you will be able to make a user and login. If that doesn't happen within 5 minutes, it stops for security reasons and must be restarted either manually or by rebooting the virtual machine.

You can read more about portainer [here](https://www.portainer.io/).

# Tips and tricks 🤩

For some tips and tricks to make your life easier check [this](assets/pages/tips_tricks/tips_n_tricks.md) out.

# Important disclaimers ⚠️

Carefully select the machine sizes

* Get a little familiar with the provider's pricing to not get caught by surprise 💸

According to the libcloud's documentation "unlimited" attributes like for example amazon's bandwidth get displayed as 0

* Don't blindly trust the scraped prices of the program output as they are not scraped by me but libcloud's library

Consider changing some default passwords

* For extra security, you should change the default root password that is set by the cloud provider

Login as secdep user with the ssh command that is outputted after the creation of the virtual machine and run `sudo su` to become root. On a GCE or an Azure machine this will happen without the need for an extra password because of the default configuration of the sudoers file. Then run `echo "root:newpassword" | chpasswd`

For AWS you should also change the default "secdeppass" password of the secdep user by running `sudo echo "secedep:newpassword" | sudo chpasswd`

One last thing to recommend is to change the default sudoers file configuration to ask for the root password instead of the user password by adding the line `Defaults targetpw`. This file should be changed using `sudo visudo`

# Contributing 🤝

If you want to contribute to the project, you can always open an issue or a pull request.

# License 📜
<p align="left">
  <a href="https://www.gnu.org/licenses/gpl-3.0.html">
    <img src="assets/images/gplv3.png?raw=true" width="250"/>
  </a>
</p>
