From eccc022eff04f39e029832c4698a5db70f65ce63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Gonz=C3=A1lez=20Garz=C3=B3n?= Date: Sun, 29 Oct 2023 11:11:32 -0500 Subject: [PATCH 1/6] =?UTF-8?q?Cambios=20requeridos=20para=20la=20ejecuci?= =?UTF-8?q?=C3=B3n=20del=20back.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 22 +++++++++++++++++++--- docker-compose.yml | 8 +++++--- src/app.module.ts | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index be5bfe8..c285d14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,27 @@ -FROM node:12-alpine +# Build stage +FROM node:12-alpine AS builder WORKDIR /usr/src/app -COPY package.json . +COPY package*.json ./ RUN npm install --quiet COPY . . -CMD ["npm", "run", "start"] +RUN npm run build + +# Production stage +FROM node:12-alpine + +WORKDIR /usr/src/app + +COPY package*.json ./ + +# Install only production dependencies +RUN npm ci --only=production + +# Copy built app from the previous stage +COPY --from=builder /usr/src/app/dist ./dist + +CMD ["npm", "run", "start:prod"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 5a80d0b..2d62d4a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,9 +3,6 @@ version: "3.8" services: web: build: . - command: npm run start - volumes: - - /usr/src/app environment: DB_HOST: "db" ports: @@ -23,7 +20,12 @@ services: - POSTGRES_DB=vinyls - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres + volumes: + - pgdata:/var/lib/postgresql/data ports: - "5432:5432" networks: - default + +volumes: + pgdata: \ No newline at end of file diff --git a/src/app.module.ts b/src/app.module.ts index 2978258..057de14 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -42,7 +42,7 @@ import { AlbumMusicianModule } from './albummusician/albummusician.module'; password: 'postgres', database: 'vinyls', entities: [Album, CollectorAlbum, Band, Collector, Comment, Musician, Performer, PerformerPrize, Prize, Track,], - dropSchema: true, + dropSchema: false, synchronize: true, keepConnectionAlive: true, migrations: [__dirname + '/migration/**/*{.ts,.js}'], From 94e77612995c4c59190880251aa706d60a658ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Gonz=C3=A1lez=20Garz=C3=B3n?= Date: Tue, 31 Oct 2023 23:43:26 -0500 Subject: [PATCH 2/6] probar pipeline para crear imagen del back --- .github/publish_image.yml | 35 +++++++++++++++++++++++++++++++++++ docker-compose.prod.yml | 31 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 .github/publish_image.yml create mode 100644 docker-compose.prod.yml diff --git a/.github/publish_image.yml b/.github/publish_image.yml new file mode 100644 index 0000000..65a79ad --- /dev/null +++ b/.github/publish_image.yml @@ -0,0 +1,35 @@ +name: publish_image + +on: + push: + branches: + - "master" + +jobs: + docker-image-offer: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to GHCR + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: downcase GITHUB_REPOSITORY + run: | + echo "GITHUB_REPOSITORY_LOWERCASE=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: ./ + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ghcr.io/${{ env.GITHUB_REPOSITORY_LOWERCASE }}:latest + ghcr.io/${{ env.GITHUB_REPOSITORY_LOWERCASE }}:1.0.1 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..9a39098 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,31 @@ +version: "3.8" + +services: + web: + image: ghcr.io/juanmanuelgg/backvynils:latest + environment: + DB_HOST: "db" + ports: + - "3000:3000" + depends_on: + - db + links: + - db + networks: + - default + + db: + image: postgres + environment: + - POSTGRES_DB=vinyls + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + volumes: + - pgdata:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - default + +volumes: + pgdata: \ No newline at end of file From 26ed57a8db1b54579547821f944785218e889091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Gonz=C3=A1lez=20Garz=C3=B3n?= Date: Tue, 31 Oct 2023 23:48:30 -0500 Subject: [PATCH 3/6] probar pipeline para crear imagen del back (2) --- .github/{ => workflow}/publish_image.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflow}/publish_image.yml (100%) diff --git a/.github/publish_image.yml b/.github/workflow/publish_image.yml similarity index 100% rename from .github/publish_image.yml rename to .github/workflow/publish_image.yml From fb7259141f48fa6ba73f1c19df71098fba3456f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Gonz=C3=A1lez=20Garz=C3=B3n?= Date: Tue, 31 Oct 2023 23:49:29 -0500 Subject: [PATCH 4/6] probar pipeline para crear imagen del back (3) --- .github/{workflow => workflows}/publish_image.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{workflow => workflows}/publish_image.yml (100%) diff --git a/.github/workflow/publish_image.yml b/.github/workflows/publish_image.yml similarity index 100% rename from .github/workflow/publish_image.yml rename to .github/workflows/publish_image.yml From 95ddf8bce27fd29dd6dd9bcd6cf1137ebca32079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Gonz=C3=A1lez=20Garz=C3=B3n?= Date: Wed, 1 Nov 2023 05:16:15 -0500 Subject: [PATCH 5/6] Desplegar el api en nuestro servidor. --- .github/workflows/publish_image.yml | 2 +- .gitignore | 35 ++++++ .vscode/extensions.json | 7 ++ .vscode/settings.json | 15 +++ terraform/.terraform.lock.hcl | 26 ++++ terraform/main.sh | 6 + terraform/main.tf | 24 ++++ terraform/modules/firewall/main.tf | 75 +++++++++++ terraform/modules/firewall/provider.tf | 12 ++ terraform/modules/firewall/variables.tf | 9 ++ terraform/modules/foundation/main.tf | 34 +++++ terraform/modules/foundation/outputs.tf | 15 +++ terraform/modules/foundation/provider.tf | 12 ++ terraform/modules/foundation/variables.tf | 19 +++ terraform/modules/vm/main.tf | 42 +++++++ terraform/modules/vm/outputs.tf | 3 + terraform/modules/vm/provider.tf | 12 ++ terraform/modules/vm/variables.tf | 29 +++++ terraform/outputs.tf | 4 + terraform/secure/.gitignore | 2 + terraform/secure/README.md | 144 ++++++++++++++++++++++ terraform/variables.tf | 16 +++ 22 files changed, 542 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 terraform/.terraform.lock.hcl create mode 100644 terraform/main.sh create mode 100644 terraform/main.tf create mode 100644 terraform/modules/firewall/main.tf create mode 100644 terraform/modules/firewall/provider.tf create mode 100644 terraform/modules/firewall/variables.tf create mode 100644 terraform/modules/foundation/main.tf create mode 100644 terraform/modules/foundation/outputs.tf create mode 100644 terraform/modules/foundation/provider.tf create mode 100644 terraform/modules/foundation/variables.tf create mode 100644 terraform/modules/vm/main.tf create mode 100644 terraform/modules/vm/outputs.tf create mode 100644 terraform/modules/vm/provider.tf create mode 100644 terraform/modules/vm/variables.tf create mode 100644 terraform/outputs.tf create mode 100644 terraform/secure/.gitignore create mode 100644 terraform/secure/README.md create mode 100644 terraform/variables.tf diff --git a/.github/workflows/publish_image.yml b/.github/workflows/publish_image.yml index 65a79ad..4634cef 100644 --- a/.github/workflows/publish_image.yml +++ b/.github/workflows/publish_image.yml @@ -6,7 +6,7 @@ on: - "master" jobs: - docker-image-offer: + docker-image: runs-on: ubuntu-latest steps: - name: Checkout diff --git a/.gitignore b/.gitignore index 0fcb15a..815fedb 100644 --- a/.gitignore +++ b/.gitignore @@ -390,3 +390,38 @@ Temporary Items docker-compose.yml .env dist + +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..cae686f --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "hashicorp.terraform", + "pkief.material-icon-theme" + ] +} + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7c011cf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "files.eol": "\n", + "[terraform]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + }, + "[terraform-vars]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + }, + "workbench.iconTheme": "material-icon-theme" + } + \ No newline at end of file diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl new file mode 100644 index 0000000..658a911 --- /dev/null +++ b/terraform/.terraform.lock.hcl @@ -0,0 +1,26 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/digitalocean/digitalocean" { + version = "2.31.0" + constraints = "~> 2.0" + hashes = [ + "h1:Ra3eOZAAkwTzUBLdKRWubvJ2nnGiorEB100eSAXyIWU=", + "zh:1eaf43da5ba5cf0ad4579fc084866ac70d2f597250218db8e573ee6045b51879", + "zh:1fd974e38833443c7d2c4b6e56cbb83d5ac086858c6dcaa9be79a85cb4106984", + "zh:2143630f078f844e4006b546a6f43653308d00ef5a5afa51e5605d290d8f9270", + "zh:2ea11260f4aada058d978abf6371fb0016f1e5ad650583b1842733dde1a1c6ed", + "zh:2f77f4e385db98bfc26b7c43c52ab4bcda2221191404726d0b76939d96eeb254", + "zh:3262dbbbfa33f3e0e775f4e2a0d995f942a0606df3f92f3db58d3a2b828eb4c1", + "zh:39cc06925c2141b7fccd729e2d98d84194af4b6603849c8eeef9e16c6e473507", + "zh:4a401f612caef535905c793bad2c7d7e54ff385f0cd5fd352bad648468647a80", + "zh:50d59d672d7c9e7e7eb4228eb6bdbe8dae8e8dac106c8c5effced15bfa65300a", + "zh:7760d8ec7af57b95a115496698fed14676b584d85465459d50e21c37add4b3e1", + "zh:8bc9f5b3b74bc084724b7342fff44e93a4f552acf4cf5878e53bd4f327a6362a", + "zh:9abf8e64705d57e29129472ac937531154dc8eec83a3a4848fbaaee87a656276", + "zh:a3d7ac59fdeb704fcb0a8c354e0ae611b377637fb76d88f89e9dc9be0e3c3945", + "zh:c71fa05665304954f62d7e2632634f29e8ab7a0a228698c6605c951dfb843a51", + "zh:efd7b29d8f65a97cb65823948b878f0cd3e42703c2ed71e2fe39769a1a9b9faa", + "zh:fb04df7c68ee96b110b5e72da7a776f01007ec919ecff914fd84ae6cb8e3ddad", + ] +} diff --git a/terraform/main.sh b/terraform/main.sh new file mode 100644 index 0000000..8642bfb --- /dev/null +++ b/terraform/main.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# This script is used to run terraform commands +terraform init +terraform destroy +terraform apply diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..3fb5b76 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,24 @@ +module "foundation" { + source = "./modules/foundation" + do_token = var.do_token + region = var.region + domain = var.domain + do_ssh_pub_key_file = var.do_ssh_pub_key_file +} + +module "vm" { + source = "./modules/vm" + do_token = var.do_token + region = var.region + digitalocean_ssh_key_id = module.foundation.digitalocean_ssh_key_id + vpc_uuid = module.foundation.vpc_uuid + ip_address = module.foundation.ip_address + proyect_id = module.foundation.proyect_id +} + + +module "firewall" { + source = "./modules/firewall" + do_token = var.do_token + droplet_id = module.vm.droplet_id +} diff --git a/terraform/modules/firewall/main.tf b/terraform/modules/firewall/main.tf new file mode 100644 index 0000000..9c260cd --- /dev/null +++ b/terraform/modules/firewall/main.tf @@ -0,0 +1,75 @@ +resource "digitalocean_firewall" "web" { + name = "web-22-53-80-443-3000-y-5432-8140-local" + + droplet_ids = [var.droplet_id] + + inbound_rule { + protocol = "tcp" + port_range = "22" + source_addresses = ["0.0.0.0/0", "::/0"] + } + inbound_rule { + protocol = "tcp" + port_range = "80" + source_addresses = ["0.0.0.0/0", "::/0"] + } + inbound_rule { + protocol = "tcp" + port_range = "443" + source_addresses = ["0.0.0.0/0", "::/0"] + } + /* Solo para pruebas + inbound_rule { + protocol = "tcp" + port_range = "3000" + source_addresses = ["0.0.0.0/0", "::/0"] + } + */ + inbound_rule { + protocol = "tcp" + port_range = "5432" + source_addresses = ["127.0.0.1/8", "::1/128"] + } + inbound_rule { + protocol = "tcp" + port_range = "8140" + source_addresses = ["127.0.0.1/8", "::1/128"] + } + outbound_rule { + protocol = "tcp" + port_range = "53" + destination_addresses = ["0.0.0.0/0", "::/0"] + } + outbound_rule { + protocol = "udp" + port_range = "53" + destination_addresses = ["0.0.0.0/0", "::/0"] + } + outbound_rule { + protocol = "tcp" + port_range = "80" + destination_addresses = ["0.0.0.0/0", "::/0"] + } + outbound_rule { + protocol = "tcp" + port_range = "443" + destination_addresses = ["0.0.0.0/0", "::/0"] + } + /* Solo para pruebas + outbound_rule { + protocol = "tcp" + port_range = "3000" + destination_addresses = ["0.0.0.0/0", "::/0"] + } + */ + outbound_rule { + protocol = "tcp" + port_range = "5432" + destination_addresses = ["127.0.0.1/8", "::1/128"] + } + outbound_rule { + protocol = "tcp" + port_range = "8140" + destination_addresses = ["127.0.0.1/8", "::1/128"] + } +} diff --git a/terraform/modules/firewall/provider.tf b/terraform/modules/firewall/provider.tf new file mode 100644 index 0000000..8f16273 --- /dev/null +++ b/terraform/modules/firewall/provider.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + digitalocean = { + source = "digitalocean/digitalocean" + version = "~> 2.0" + } + } +} + +provider "digitalocean" { + token = var.do_token +} diff --git a/terraform/modules/firewall/variables.tf b/terraform/modules/firewall/variables.tf new file mode 100644 index 0000000..b931a57 --- /dev/null +++ b/terraform/modules/firewall/variables.tf @@ -0,0 +1,9 @@ +variable "do_token" { + description = "DigitalOcean API token" + type = string +} + +variable "droplet_id" { + description = "The ID of the droplet to apply the firewall to" + type = number +} diff --git a/terraform/modules/foundation/main.tf b/terraform/modules/foundation/main.tf new file mode 100644 index 0000000..f5fe599 --- /dev/null +++ b/terraform/modules/foundation/main.tf @@ -0,0 +1,34 @@ +resource "digitalocean_ssh_key" "default" { + name = "SSH-DigitalOcean-key" + public_key = file(var.do_ssh_pub_key_file) +} + +resource "digitalocean_vpc" "default" { + name = "my-network" + region = var.region + ip_range = "10.10.11.0/24" +} + +resource "digitalocean_reserved_ip" "default" { + region = var.region +} + +resource "digitalocean_domain" "default" { + name = var.domain + ip_address = digitalocean_reserved_ip.default.ip_address +} + +resource "digitalocean_record" "www" { + domain = digitalocean_domain.default.id + type = "A" + name = "www" + value = digitalocean_reserved_ip.default.ip_address +} + +resource "digitalocean_project" "default" { + name = "AppBajoPruebas" + description = "Un proyecto web del curso: Ingenieria de software para aplicaciones moviles." + purpose = "Web Application" + environment = "Development" + resources = [digitalocean_domain.default.urn] +} diff --git a/terraform/modules/foundation/outputs.tf b/terraform/modules/foundation/outputs.tf new file mode 100644 index 0000000..ba25605 --- /dev/null +++ b/terraform/modules/foundation/outputs.tf @@ -0,0 +1,15 @@ +output "digitalocean_ssh_key_id" { + value = digitalocean_ssh_key.default.id +} + +output "vpc_uuid" { + value = digitalocean_vpc.default.id +} + +output "ip_address" { + value = digitalocean_reserved_ip.default.ip_address +} + +output "proyect_id" { + value = digitalocean_project.default.id +} diff --git a/terraform/modules/foundation/provider.tf b/terraform/modules/foundation/provider.tf new file mode 100644 index 0000000..8f16273 --- /dev/null +++ b/terraform/modules/foundation/provider.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + digitalocean = { + source = "digitalocean/digitalocean" + version = "~> 2.0" + } + } +} + +provider "digitalocean" { + token = var.do_token +} diff --git a/terraform/modules/foundation/variables.tf b/terraform/modules/foundation/variables.tf new file mode 100644 index 0000000..f5bfc54 --- /dev/null +++ b/terraform/modules/foundation/variables.tf @@ -0,0 +1,19 @@ +variable "do_token" { + description = "DigitalOcean API token" + type = string +} + +variable "do_ssh_pub_key_file" { + description = "Path to the public key file for DigitalOcean" + type = string +} + +variable "region" { + description = "The region to deploy to" + type = string +} + +variable "domain" { + description = "value for the domain name" + type = string +} diff --git a/terraform/modules/vm/main.tf b/terraform/modules/vm/main.tf new file mode 100644 index 0000000..99d59d5 --- /dev/null +++ b/terraform/modules/vm/main.tf @@ -0,0 +1,42 @@ +# Create a new tag +resource "digitalocean_tag" "default" { + name = "webapp" +} + +# Create a web server +resource "digitalocean_droplet" "default" { + name = "backvynils" + size = "s-1vcpu-2gb" + image = "ubuntu-22-04-x64" + region = var.region + monitoring = true + graceful_shutdown = true + ssh_keys = [var.digitalocean_ssh_key_id] + vpc_uuid = var.vpc_uuid + tags = [digitalocean_tag.default.id] +} + +resource "digitalocean_monitor_alert" "cpu_alert" { + alerts { + email = ["jm.gonzalez1844@uniandes.edu.co"] + } + window = "5m" + type = "v1/insights/droplet/cpu" + compare = "GreaterThan" + value = 90 + enabled = true + entities = [digitalocean_droplet.default.id] + description = "Alert about CPU usage" +} + +resource "digitalocean_reserved_ip_assignment" "default" { + ip_address = var.ip_address + droplet_id = digitalocean_droplet.default.id +} + +resource "digitalocean_project_resources" "default" { + project = var.proyect_id + resources = [ + digitalocean_droplet.default.urn + ] +} diff --git a/terraform/modules/vm/outputs.tf b/terraform/modules/vm/outputs.tf new file mode 100644 index 0000000..f585b03 --- /dev/null +++ b/terraform/modules/vm/outputs.tf @@ -0,0 +1,3 @@ +output "droplet_id" { + value = digitalocean_droplet.default.id +} diff --git a/terraform/modules/vm/provider.tf b/terraform/modules/vm/provider.tf new file mode 100644 index 0000000..8f16273 --- /dev/null +++ b/terraform/modules/vm/provider.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + digitalocean = { + source = "digitalocean/digitalocean" + version = "~> 2.0" + } + } +} + +provider "digitalocean" { + token = var.do_token +} diff --git a/terraform/modules/vm/variables.tf b/terraform/modules/vm/variables.tf new file mode 100644 index 0000000..89fa363 --- /dev/null +++ b/terraform/modules/vm/variables.tf @@ -0,0 +1,29 @@ +variable "do_token" { + description = "DigitalOcean API token" + type = string +} + +variable "region" { + description = "The region to deploy to" + type = string +} + +variable "digitalocean_ssh_key_id" { + description = "The ID of the SSH key to use for the droplet" + type = string +} + +variable "vpc_uuid" { + description = "The ID of the VPC to use for the droplet" + type = string +} + +variable "ip_address" { + description = "The IP address to assign to the droplet" + type = string +} + +variable "proyect_id" { + description = "The ID of the project to use for the droplet" + type = string +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000..e4cfea2 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,4 @@ +# Output the reserved ip address. +output "reserved_ip_address" { + value = module.foundation.ip_address +} diff --git a/terraform/secure/.gitignore b/terraform/secure/.gitignore new file mode 100644 index 0000000..bc5ed1d --- /dev/null +++ b/terraform/secure/.gitignore @@ -0,0 +1,2 @@ +do_ecdsa +do_ecdsa.pub \ No newline at end of file diff --git a/terraform/secure/README.md b/terraform/secure/README.md new file mode 100644 index 0000000..5be84c8 --- /dev/null +++ b/terraform/secure/README.md @@ -0,0 +1,144 @@ +# Configuración de la infraestructura + +## Generate SSH key pair + +```bash +ssh-keygen -t ecdsa -b 521 -C 'Llave para digital ocean' -f do_ecdsa +``` + +## Configuracion del servidor + +```bash +ssh -i do_ecdsa root@appbajopruebas.com + +# Una vez dentro del servidor + +# 1. Actualizar el sistema e instalar nginx y docker +apt update +apt upgrade -y +apt install -y nginx certbot python3-certbot-nginx apt-transport-https ca-certificates curl software-properties-common apache2-utils +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null +apt update +apt-cache policy docker-ce +apt -y install docker-ce docker-compose-plugin +systemctl status docker + +# 2. Configurar el usuario +useradd -ms /bin/bash appuser +# Asegurar que el nuevo ususario no pertenesca a ningun grupo mas que a el mismo. +groups appuser +# En caso de que pertenesca a alguno borrar con: gpasswd -d appuser grupo + +# Agregar el usuario al grupo docker +usermod -aG docker appuser +apt autoremove -y +su - appuser +mkdir -p ~/.ssh +chmod 700 ~/.ssh +touch ~/.ssh/authorized_keys +chmod 600 ~/.ssh/authorized_keys +vim ~/.ssh/authorized_keys # Copiar la llave publica del usuario que se usara para conectarse al servidor +``` + +## Levanatar el api de BackVynils + +```bash +# desde la maquina local +scp -i do_ecdsa ../../docker-compose.prod.yml appuser@appbajopruebas.com:~/docker-compose.yml +ssh -i do_ecdsa appuser@appbajopruebas.com + +# desde el servidor (como appuser) +docker-compose up -d --build +``` + +## Configurar nginx + +```bash +# desde el servidor (como root) +vim /etc/nginx/sites-available/appbajopruebas.com +``` + +```nginx +server { + listen 80; + server_name appbajopruebas.com www.appbajopruebas.com; + location / { + proxy_pass http://localhost:3000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} +``` + +```bash +# desde el servidor (como root) +ln -s /etc/nginx/sites-available/appbajopruebas.com /etc/nginx/sites-enabled/ +nginx -t +systemctl restart nginx +``` + +## Configurar certbot + +```bash +# desde el servidor (como root) +certbot --nginx -d appbajopruebas.com -d www.appbajopruebas.com +``` + +## Agregar un api-key a nginx para proteger el api + +```bash +# desde el servidor (como root) +htpasswd -c /etc/nginx/.htpasswd appuser +vim /etc/nginx/sites-available/appbajopruebas.com +``` + +```nginx +server { + listen 80; + server_name appbajopruebas.com www.appbajopruebas.com; + location / { + auth_basic "Restricted Content"; + auth_basic_user_file /etc/nginx/.htpasswd; + proxy_pass http://localhost:3000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} +# ... El resto del archivo con la configuracion https que creo certbot +``` + +```bash +# desde el servidor (como root) +nginx -t +systemctl restart nginx +``` + +## Configurar el firewall de ubuntu (Como medida redundante al firewall de digital ocean) + +```bash +#!/bin/bash + +# Asegurar que el script esta siendo ejecutado como root. +if [[ "${UID}" -ne 0 ]]; then + echo 'Por favor correr con sudo o como root.' >&2 + exit 1 +fi + +ufw reset + +ufw default deny incoming +ufw default allow outgoing + +ufw allow in on lo +ufw allow from 127.0.0.1/8 + +ufw allow 22 +ufw allow 80 # Se podria quitar ya que se usa https +ufw allow 443 + +# Prender cuando ya tenga las reglas claras +ufw enable # disable + +ufw status numbered +``` \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..9fe1b16 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,16 @@ +# La primera esta vacia aqui pero tienen valor en terraform.tfvars (Archivo que debe meterse en el .gitignore) +# do_token = "" + +variable "do_token" {} + +variable "do_ssh_pub_key_file" { + default = "secure/do_ecdsa.pub" +} + +variable "region" { + default = "nyc3" +} + +variable "domain" { + default = "appbajopruebas.com" +} From afc8088071575a21b46cb43d9dd49414a73aa850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Gonz=C3=A1lez=20Garz=C3=B3n?= Date: Sun, 12 Nov 2023 23:07:54 -0500 Subject: [PATCH 6/6] Hacer el firewall mas estricto. --- terraform/modules/firewall/main.tf | 24 +++--------------------- terraform/secure/README.md | 2 +- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/terraform/modules/firewall/main.tf b/terraform/modules/firewall/main.tf index 9c260cd..21d2439 100644 --- a/terraform/modules/firewall/main.tf +++ b/terraform/modules/firewall/main.tf @@ -1,5 +1,5 @@ resource "digitalocean_firewall" "web" { - name = "web-22-53-80-443-3000-y-5432-8140-local" + name = "web-22-53-80-443" droplet_ids = [var.droplet_id] @@ -8,11 +8,13 @@ resource "digitalocean_firewall" "web" { port_range = "22" source_addresses = ["0.0.0.0/0", "::/0"] } + /* La idea es quitar http cuando ya se tiene https. inbound_rule { protocol = "tcp" port_range = "80" source_addresses = ["0.0.0.0/0", "::/0"] } + */ inbound_rule { protocol = "tcp" port_range = "443" @@ -25,16 +27,6 @@ resource "digitalocean_firewall" "web" { source_addresses = ["0.0.0.0/0", "::/0"] } */ - inbound_rule { - protocol = "tcp" - port_range = "5432" - source_addresses = ["127.0.0.1/8", "::1/128"] - } - inbound_rule { - protocol = "tcp" - port_range = "8140" - source_addresses = ["127.0.0.1/8", "::1/128"] - } outbound_rule { protocol = "tcp" port_range = "53" @@ -62,14 +54,4 @@ resource "digitalocean_firewall" "web" { destination_addresses = ["0.0.0.0/0", "::/0"] } */ - outbound_rule { - protocol = "tcp" - port_range = "5432" - destination_addresses = ["127.0.0.1/8", "::1/128"] - } - outbound_rule { - protocol = "tcp" - port_range = "8140" - destination_addresses = ["127.0.0.1/8", "::1/128"] - } } diff --git a/terraform/secure/README.md b/terraform/secure/README.md index 5be84c8..0b57c5e 100644 --- a/terraform/secure/README.md +++ b/terraform/secure/README.md @@ -134,7 +134,7 @@ ufw allow in on lo ufw allow from 127.0.0.1/8 ufw allow 22 -ufw allow 80 # Se podria quitar ya que se usa https +# ufw allow 80 # La idea es quitar http cuando ya se tiene https. ufw allow 443 # Prender cuando ya tenga las reglas claras