send/docs/AWS.md

5.2 KiB

Deployment to AWS

This document describes how to do a deployment of Send in AWS

AWS requirements

Security groups (2)

  • ALB:

    • inbound: allow traffic from anywhere on port 80 and 443
    • ountbound: allow traffic to the instance security group on port 8080
  • Instance:

    • inbound: allow SSH from your public IP or a bastion (changing the default SSH port is a good idea)
    • inbound: allow traffic from the ALB security group on port 8080
    • ountbound: allow all traffic to anywhere

Resources

  • An S3 bucket (block all public access)

  • A private EC2 instance running Ubuntu 20.04 (you can use the Amazon EC2 AMI Locator to find the latest)

    Attach an IAM role to the instance with the following inline policy:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "s3:ListAllMyBuckets"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            },
            {
                "Action": [
                    "s3:ListBucket",
                    "s3:GetBucketLocation",
                    "s3:ListBucketMultipartUploads"
                ],
                "Resource": [
                    "arn:aws:s3:::<s3_bucket_name>"
                ],
                "Effect": "Allow"
            },
            {
                "Action": [
                    "s3:GetObject",
                    "s3:GetObjectVersion",
                    "s3:ListMultipartUploadParts",
                    "s3:PutObject",
                    "s3:AbortMultipartUpload",
                    "s3:DeleteObject",
                    "s3:DeleteObjectVersion"
                ],
                "Resource": [
                    "arn:aws:s3:::<s3_bucket_name>/*"
                ],
                "Effect": "Allow"
            }
        ]
    }
    
  • A public ALB:

    • Create a target group with the instance registered (HTTP on port 8080 and path /)
    • Configure HTTP (port 80) to redirect to HTTPS (port 443)
    • HTTPS (port 443) using the latest security policy and an ACM certificate like send.mydomain.com
  • A Route53 public record, alias from send.mydomain.com to the ALB

Software requirements

  • Git
  • NodeJS 15.x LTS
  • Local Redis server

Prerequisite packages

sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

Add repositories

curl -fsSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -
echo 'deb [arch=amd64] https://deb.nodesource.com/node_15.x focal main' | sudo tee /etc/apt/sources.list.d/nodejs.list
  • Git (latest)
sudo add-apt-repository ppa:git-core/ppa
  • Redis (latest)
sudo add-apt-repository ppa:redislabs/redis

Install required packages

sudo apt update
sudo apt install git nodejs redis-server telnet

Redis server

Password (optional)

Generate a strong password:

makepasswd --chars=100

Edit Redis configuration file /etc/redis/redis.conf:

requirepass <redis_password>

Note: documentation on securing Redis https://redis.io/topics/security

Systemd

Enable and (re)start the Redis server service:

sudo systemctl enable redis-server
sudo systemctl restart redis-server
sudo systemctl status redis-server

Website directory

Setup a directory for the data

sudo mkdir -pv /var/www/send
sudo chown www-data:www-data /var/www/send
sudo 750 /var/www/send

NodeJS

Update npm:

sudo npm install -g npm

Checkout current NodeJS and npm versions:

node --version
npm --version

Clone repository, install JavaScript packages and compiles the assets:

sudo su -l www-data -s /bin/bash
cd /var/www/send
git clone https://gitlab.com/timvisee/send.git .
npm install
npm run build
exit

Create the file /var/www/send/.env used by Systemd with your environment variables (checkout config.js for more configuration environment variables):

BASE_URL='https://send.mydomain.com'
NODE_ENV='production'
PORT='8080'
REDIS_PASSWORD='<redis_password>'
S3_BUCKET='<s3_bucket_name>'

Lower files and folders permissions to user and group www-data:

sudo find /var/www/send -type d -exec chmod 750 {} \;
sudo find /var/www/send -type f -exec chmod 640 {} \;
sudo chmod 750 /var/www/send/node_modules/.bin/*

Systemd

Create the file /etc/systemd/system/send.service with root user and 644 mode:

[Unit]
Description=Send
After=network.target
Requires=redis-server.service
Documentation=https://gitlab.com/timvisee/send

[Service]
Type=simple
ExecStart=/usr/bin/npm run prod
EnvironmentFile=/var/www/send/.env
WorkingDirectory=/var/www/send
User=www-data
Group=www-data
Restart=on-failure

[Install]
WantedBy=multi-user.target

Note: could be better tuner to secure the service by restricting system permissions, check with systemd-analyze security send

Enable and start the Send service, check logs:

sudo systemctl daemon-reload
sudo systemctl enable send
sudo systemctl start send
sudo systemctl status send
journalctl -fu send