Getting Started with Full Stack
Course Introduction
Slides
Part 1
Things you’ll learn
- Learn how to use Node and Bash to create shell scripts
- Learn advanced Nginx configuration
- Common server vulnerabilibies and how to mitigate them
- How to add HTTPS to your server
- Understand databases
- Containers and automating deployments
Full Stack for Frontend Part 1 Recap & Purpose
Recap
- How the internet works
- Command line basics
- How to create and manage a web server
- Create a deploy system for a Node app
- Build a basic web page
Why full stack
emm.. a lot of reasons…
Server Setup
Basic Server Setup, Updating and User Permissions
- Create a new Ubuntu server
a. Use Ubuntu 16.04.x
b. Be sure to use an SSH key
- Point domain to new server
- Log into server as root
- Update server
- Add a new user ‘test’
- Grant ‘test’ sudo access
- Switch to ‘test’ user
Node setup and installation
update apt repo for nodejs
1
| curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
|
explain shell
install nodejs and npm
check npm directory
If the npm directory is not /usr/local, follow instructions here.
更改npm安装目录主要是权限问题。如果安装在全局文件夹下,需要sudo权限才能安装全局包。
install forever module
change working directory
更改文件夹权限
1
| sudo chown -R $USER:$USER /var/www
|
clone repo
1
| git clone https://github.com/young/fsfe2.git
|
change working directory again
install module
Server Security
Security Overview
- Control access
- Strong authentication
- Firewalls
- user/file permissions
- Secure your applications
- Keep software up to date
- limit application use
Adding SSH keys
create a new directory
paste public key into authorized_keys file
1
| vi ~/.ssh/authorized_keys
|
Be sure to test logging in with your new user.
Security Setting
- Add a password for root
- Disable root login
- Disable password login
Firewalls
nmap
Firewall configurations: iptables
1
| sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
|
-A
append rule
-p
protocol(tcp, icmp)
--dport
destination port
-j
jump(DROP, REJECT, ACCEPT, LOG)
Create an iptable rule to block all outgoing HTTP connections
1
| iptables -A OUTPUT -p tcp --dport 80 -j REJECT
|
Create an iptable rule to only allow icmp connections on port 892 from the IP address 192.0.0.1
1
| iptables -A INPUT -s 192.0.0.1 -p icmp --dport 892 -j ACCEPT
|
Firewall configurations: UFW and GUI options
There has to be a better way!
ufw - uncomplicated firewall
1 2
| sudo ufw allow ssh sudo ufw enable
|
Create a ufw rule to block all outgoing HTTP connections
GUI
Degital Ocean的Droplets下的networking下的firewalls选项
Automatic Updates
1
| sudo apt install unattended-upgrades
|
/etc/apt/apt.conf.d/20auto-upgrades
1 2
| APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1";
|
https://wiki.debian.org/UnattendedUpgrades
1
| sudo vi /etc/apt/apt.conf.d/50unattended-upgrades
|
Fail2ban: Exercise
Install fail2ban
1
| sudo apt install fail2ban
|
Copy jail file
1
| sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
|
Edit configuration file
1
| sudo vi /etc/fail2ban/jail.local
|
WARNING!
If you misconfigure fail2ban, you can lock yourself out of your server!
Advanced Shells
- Finding Things
- Redirection Operators
- Shells
- Shell Scripts
find: search file names
find |
/bar |
-name |
foo.txt |
find |
directory |
option |
file/folder |
useful options
- -name
- -type
- -empty
- -executable
- -writable
grep: search file contents
grep |
-i |
'jem' |
/var/www |
grep |
options |
search expression |
directory |
search inside gzip file
Find: Exercise
find all log files in /log
1
| find /var/log/ -type f -name *.log
|
find all empty files
1
| find /etc -type f -empty
|
find all directories with the word log
1
| find / -type d -name log
|
Grep: Exercise
Redirection
write to file
Shells
shell => application => kernel
show current shell:
Changing Shells
list acceptable shells to change to
change shell to sh
login into new shell to see the change
change shell to bash
Shell scripting
Why shell scripting ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #!/bin/sh
trap 'echo "/nPlease choose!"' INT
FILES= `find /var/log/ -name *.log -mtime 1` echo "Old files ready to be deleted:\n" echo "$FILES" echo "Do you want to continue? \c"
while : do read INPUT case $INPUT in y) echo "deleting files..." break ;; *) echo "Please make a valid selection" ;; esac done
|
Bash scripting: Exercise
1 2 3
| #!/bin/sh
cat /proc/loadavg | awk '{print $1"-"$2"-"$3}'
|
Get load average:
Extract the 1st, 2nd, and 3rd columns of data:
1
| awk '{print $1"-"$2"-"$3}'
|
Make executable:
1
| sudo chmod 755 ./load.sh
|
Creating a shell script with Node: Exercise
create a workspace folder:
move into workspace folder:
create index.js:
initialize project:
add reference to script:
1 2 3
| "bin": { "myscript": "index.js" },
|
1 2 3 4 5 6 7 8 9
| #!/user/bin/node
const exec = require('child_process').exec const stat = exec(`cat /proc/loadavg | awk '{print $1"-"$2"-"$3}'`)
stat.stdout.on('data', function(data) { console.log(data) })
|
HTTPS
- Nginx setup
- Why HTTPS
- Getting a certificate
- Cron
Nginx Setup: Installation
- Install nginx
sudo apt-get install nginx
sudo service ngnix start
- Proxy traffic to node server
- Add domain name
- Open port 443
- Reload nginx
Nginx Setup: proxy traffic to node server
1
| cd /etc/ngnix/site/available
|
1 2 3
| location / { proxy_pass http://127.0.0.1:3001/; }
|
测试配置文件是否有效:
1 2 3 4
| sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
|
启动forever是提示command not found,查了一下是全局变量配置问题,使用如下命令修改配置
1
| sudo echo -e "export PATH=$(npm prefix -g)/bin:$PATH" >> ~/.bashrc && source ~/.bashrc
|
此时打开网址,可以看到已经显示站点。
Nginx Setup: Adding a domain name and opening port 443
add domain name to nginx conf
1
| sudo vi /etc/nginx/sites-available/default
|
1
| server_name $YOUR_DOMAIN;
|
open port 443:
open ssh link
enable ufw
check ufw status
Why HTTPS
简单来说,HTTPS更加安全,是一种必要措施。
- Security
- Technology
- Service Workers
- Web Bluetooth
- HTTP/2
Installing HTTPS certificate
Old way:
acme-tiny
New way:
certbot
- Add the certbot repository
sudo add-apt-repository ppa:certbot/certbot
- Pull in new repository information
- Install certbot with nginx plugin
sudo apt install python-certbot-nginx
- Use certbot to get certificate
- Test auto renew
sudo certbot renew --dry-run
安装时开始一直失败,输入sudo ufw disable
,把防火墙暂时关闭后安装成功。
此时在通过域名访问网站即可发现https已经启用。
cron
How do we run periodic tasks?
minute |
hour |
day of month |
month |
day of week |
command to execute |
00 |
16 |
* |
* |
5 |
`echo “It’s party time!” |
crontab-The quick and simple editor for cron schedule expressions
cron: Exercise
Open crontab for editing
Renew certificate every week at 12pm on Monday
1
| 00 12 * * 1 certbot renew
|
Nginx Tuning
Nginx Tuning: Overview and Gzip
gzip is an algorithm that runs through and compresses files
1
| sudo vi /etc/nginx/nginx.conf
|
1
| sudo vi /etc/nginx/sites-available/default
|
添加如下规则:
1 2 3 4
| location /static/ { expires 30d; proxy_padd http://127.0.0.1:3001/static/; }
|
测试规则
重启Nginx,刷新网页,会在Response Headers
的Cache-Control
中看到max-age=2592000
。
当缓存时间设置比较长时,网站更新后并不会在客户端更新。
Caching
上述是客户端缓存设置,也可以对服务端进行缓存设置,来使得一些复杂的sql语句查询或者一些大计算量的请求进行缓存,提高访问速度(缓存时间不宜过长,否则无法进行更新)。
1
| sudo vi /etc/nginx/sites-available/default
|
文件头部添加(server{}
外)
1 2 3 4 5
| proxy_cache_path /tmp/nginx levels=1:2 keys_zone=slowfile_cache:10m inactive=60m use_temp_path=off;
proxy_cache_key "$request_uri";
|
1 2 3 4 5 6 7
| location /slowfile { proxy_cache_valid 1m; Proxy_ignore_headers Cache-Control; add_header X-Proxy-Cache $upstream_cache_status; proxy_cache slowfile_cache; proxy_pass http://127.0.0.1:3001/slowfile; }
|
warm cache:对一些耗时较长的请求首先进行缓存,这样在他人访问时可以直接从缓存中获取,提高访问速度。
此时访问网站的/slowfile,第一次访问可以看到请求头添加了X-Proxy-Cache
字段,并且为MISS
,请求时间较长。刷新后X-Proxy-Cache
字段为HIT
,请求仅耗时300ms。
Websockets: Setup
1
| sudo vi /etc/nginx/sites-avaliable/default
|
1 2 3 4 5 6
| location / { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:3001; }
|
通过上述配置,Nginx开启Websockets。
Websockets: Client-side code and observables
Websockets: Exercise
1 2 3
| cd /var/www/fsfe2/
vi app.js
|
1 2 3 4 5 6 7 8 9 10 11
| function getServerLoad() { return setInterval(() => { const loadScript = exec(`~/load.sh`);
loadScript.stdout.on('data', function(data) { wss.broadcast(JSON.stringify({name: 'load', data})); });
}, 2 * 1000); }
|
http/2
1
| sudo vi /etc/nginx/sites-avaliable/default
|
demo
http/2: Exercise
更改配置文件后,重启Nginx,打开/cats网址,会看到图片传输协议已经更改为h2
Redirect
Redirect request to new url
1
| sudo vi /ect/nginx/sites-avaliable/default
|
1 2 3
| location /help { return 301 https://developer.mozilla.org/zh-CN/; }
|
Databases
Database Types
- relational
- SQL
- MySQL
- Microsoft SQL Server
- Postgre SQL
- non-relational
Exercise: MySQL Installation
Install MySQL
1
| sudo apt install mysql-server
|
Run setup script
1
| mysql_secure_installation
|
Login as root
Database Best Practice
Tips:
- Back up your database
- Use a strong root password
- Don’t expose the database outside the network
- Sanitize your SQL
- Back up your database
Containers and More
Containers
- shared resources
- no OS
- fast deployment
Docker-Enterprise Container Platform for High-Velocity Innovation
Installing Postgres on Docker
Orchestration
Tools
Kubernetes
Automated Deployment