Documentation: full deployment example in AWS with Ubuntu 20.04
This commit is contained in:
parent
72377d3438
commit
dc816d0e59
5 changed files with 299 additions and 32 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
node_modules
|
||||
coverage
|
||||
dist
|
||||
.env
|
||||
.idea
|
||||
.DS_Store
|
||||
.nyc_output
|
||||
|
|
|
@ -49,6 +49,7 @@ Cynthia Pereira
|
|||
Daniel Thorn
|
||||
Daniela Arcese
|
||||
Danny Coates
|
||||
David Dumas
|
||||
Davide
|
||||
Derek Tamsen
|
||||
Dhyey Thakore
|
||||
|
|
|
@ -81,7 +81,7 @@ A file sharing experiment which allows you to send encrypted files to other user
|
|||
|
||||
## Requirements
|
||||
|
||||
- [Node.js 12.x](https://nodejs.org/)
|
||||
- [Node.js 15.x](https://nodejs.org/)
|
||||
- [Redis server](https://redis.io/) (optional for development)
|
||||
- [AWS S3](https://aws.amazon.com/s3/) or compatible service (optional)
|
||||
|
||||
|
@ -141,6 +141,8 @@ Find a list of public instances here: https://github.com/timvisee/send-instances
|
|||
|
||||
See also [docs/deployment.md](docs/deployment.md)
|
||||
|
||||
AWS example using Ubuntu Server `20.04` [docs/AWS.md](docs/AWS.md)
|
||||
|
||||
---
|
||||
|
||||
## Clients
|
||||
|
|
236
docs/AWS.md
Normal file
236
docs/AWS.md
Normal file
|
@ -0,0 +1,236 @@
|
|||
# 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](https://cloud-images.ubuntu.com/locator/ec2/) to find the latest)
|
||||
|
||||
Attach an IAM role to the instance with the following inline policy:
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
|
||||
```
|
||||
|
||||
### Add repositories
|
||||
|
||||
* NodeJS `15.x` LTS (checkout [package.json](../package.json)):
|
||||
|
||||
```bash
|
||||
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)
|
||||
|
||||
```bash
|
||||
sudo add-apt-repository ppa:git-core/ppa
|
||||
```
|
||||
|
||||
* Redis (latest)
|
||||
|
||||
```bash
|
||||
sudo add-apt-repository ppa:redislabs/redis
|
||||
```
|
||||
|
||||
### Install required packages
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install git nodejs redis-server telnet
|
||||
```
|
||||
|
||||
### Redis server
|
||||
|
||||
#### Password (optional)
|
||||
|
||||
Generate a strong password:
|
||||
|
||||
```bash
|
||||
makepasswd --chars=100
|
||||
```
|
||||
|
||||
Edit Redis configuration file `/etc/redis/redis.conf`:
|
||||
|
||||
```bash
|
||||
requirepass <redis_password>
|
||||
```
|
||||
|
||||
_Note: documentation on securing Redis https://redis.io/topics/security_
|
||||
|
||||
#### Systemd
|
||||
|
||||
Enable and (re)start the Redis server service:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
sudo npm install -g npm
|
||||
```
|
||||
|
||||
Checkout current NodeJS and npm versions:
|
||||
|
||||
```bash
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
Clone repository, install JavaScript packages and compiles the assets:
|
||||
|
||||
```bash
|
||||
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](../server/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
|
||||
```
|
|
@ -1,16 +1,20 @@
|
|||
## Requirements
|
||||
|
||||
This document describes how to do a full deployment of Send on your own Linux server. You will need:
|
||||
|
||||
* A working (and ideally somewhat recent) installation of NodeJS and NPM
|
||||
* GIT
|
||||
* An Apache webserver
|
||||
* A working (and ideally somewhat recent) installation of NodeJS and npm
|
||||
* Git
|
||||
* Apache webserver
|
||||
* Optionally telnet, to be able to quickly check your installation
|
||||
|
||||
For Debian/Ubuntu systems this probably just means something like this:
|
||||
For example in Debian/Ubuntu systems:
|
||||
|
||||
* apt install git apache2 nodejs npm telnet
|
||||
```bash
|
||||
sudo apt install git apache2 nodejs npm telnet
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
* We assume an already configured virtual-host on your webserver with an existing empty htdocs folder
|
||||
* First, remove that htdocs folder - we will replace it with Send's version now
|
||||
* git clone https://github.com/timvisee/send.git htdocs
|
||||
|
@ -19,51 +23,74 @@ For Debian/Ubuntu systems this probably just means something like this:
|
|||
* npm run build
|
||||
|
||||
## Running
|
||||
|
||||
To have a permanently running version of Send as a background process:
|
||||
|
||||
* Create a file "run.sh" with:
|
||||
```
|
||||
* Create a file `run.sh` with:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
nohup su www-data -c "npm run prod" 2>/dev/null &
|
||||
```
|
||||
* chmod +x run.sh
|
||||
* ./run.sh
|
||||
|
||||
* Execute the script:
|
||||
|
||||
```bash
|
||||
chmod +x run.sh
|
||||
./run.sh
|
||||
```
|
||||
|
||||
Now the Send backend should be running on port 1443. You can check with:
|
||||
* telnet localhost 1443
|
||||
|
||||
```bash
|
||||
telnet localhost 1443
|
||||
```
|
||||
|
||||
## Reverse Proxy
|
||||
|
||||
Of course, we don't want to expose the service on port 1443. Instead we want our normal webserver to forward all requests to Send ("Reverse proxy").
|
||||
|
||||
# Apache webserver
|
||||
|
||||
* a2enmod proxy
|
||||
* a2enmod proxy_http
|
||||
* a2enmod proxy_wstunnel
|
||||
* a2enmod rewrite
|
||||
* Enable Apache required modules:
|
||||
|
||||
In your Apache virtual host configuration file, insert this:
|
||||
```bash
|
||||
sudo a2enmod headers
|
||||
sudo a2enmod proxy
|
||||
sudo a2enmod proxy_http
|
||||
sudo a2enmod proxy_wstunnel
|
||||
sudo a2enmod rewrite
|
||||
```
|
||||
|
||||
* Edit your Apache virtual host configuration file, insert this:
|
||||
|
||||
```
|
||||
# Enable rewrite engine
|
||||
RewriteEngine on
|
||||
# Enable rewrite engine
|
||||
RewriteEngine on
|
||||
|
||||
# Make sure the original domain name is forwarded to Send
|
||||
# Otherwise the generated URLs will be wrong
|
||||
ProxyPreserveHost on
|
||||
# Make sure the original domain name is forwarded to Send
|
||||
# Otherwise the generated URLs will be wrong
|
||||
ProxyPreserveHost on
|
||||
|
||||
# Make sure the generated URL is https://
|
||||
RequestHeader set X-Forwarded-Proto https
|
||||
# Make sure the generated URL is https://
|
||||
RequestHeader set X-Forwarded-Proto https
|
||||
|
||||
# If it's a normal file (e.g. PNG, CSS) just return it
|
||||
RewriteCond %{REQUEST_FILENAME} -f
|
||||
RewriteRule .* - [L]
|
||||
# If it's a normal file (e.g. PNG, CSS) just return it
|
||||
RewriteCond %{REQUEST_FILENAME} -f
|
||||
RewriteRule .* - [L]
|
||||
|
||||
# If it's a websocket connection, redirect it to a Send WS connection
|
||||
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
||||
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
|
||||
# If it's a websocket connection, redirect it to a Send WS connection
|
||||
RewriteCond %{HTTP:Upgrade} =websocket [NC]
|
||||
RewriteRule /(.*) ws://127.0.0.1:1443/$1 [P,L]
|
||||
|
||||
# Otherwise redirect it to a normal HTTP connection
|
||||
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
|
||||
ProxyPassReverse "/" "http://127.0.0.1:1443"
|
||||
# Otherwise redirect it to a normal HTTP connection
|
||||
RewriteRule ^/(.*)$ http://127.0.0.1:1443/$1 [P,QSA]
|
||||
ProxyPassReverse "/" "http://127.0.0.1:1443"
|
||||
```
|
||||
|
||||
* Test configuration and restart Apache:
|
||||
|
||||
```bash
|
||||
sudo apache2ctl configtest
|
||||
sudo systemctl restart apache2
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue