- Access the server
- Install Oh My Zsh
- Install Nginx
- Install Node.js
- Install Fail2Ban
- Using Let’s Encrypt SSL/TLS Certificates
- Automatic Deployment with Git
- Useful commands
- Useful links
I will use $
and ▶
to indicate the local or server terminal:
$
: local▶
: server
$ ssh root@<server-ip>
Generate a new user
▶ adduser axel
As root
, run this command to add your new user to the sudo group.
-a
append
-G
groups
▶ usermod -aG sudo axel
$ ssh-keygen
You will see output that looks like the following.
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/<localuser>/.ssh/id_rsa):
/Users/<localuser>/.ssh/id_rsa
is the default path,
but you can add your own if needed /Users/<localuser>/.ssh/id_rsa_test
copy the key
$ cat ~/.ssh/id_rsa.pub | pbcopy
$ ssh root@<server-ip>
▶ su - axel
Create a new folder .ssh
and restrict its permissions
▶ mkdir ~/.ssh
▶ chmod 700 ~/.ssh
▶ vim ~/.ssh/authorized_keys
Insert the key (which should be in your clipboard) by pasting it into the editor.
Restrict the permissions of the authorized_keys file with this command:
▶ chmod 600 ~/.ssh/authorized_keys
▶ exit
$ vim ~/.ssh/config
Host <login-name> #server-axel
HostName <server-ip>
User axel
IdentityFile ~/.ssh/id_rsa_test #(optional)
If your key is located in /Users/<localuser>/.ssh/id_rsa
and is called id_rsa
there is no need to add the IdentityFile
field.
Now you can enter the server with
$ ssh server-axel
$ ssh server-axel
▶ sudo vim /etc/ssh/sshd_config
Change these settings
PasswordAuthentication no
PermitRootLogin no
Save the sshd_config
file and reload the SSH daemon
▶ sudo systemctl reload sshd
▶ sudo ufw app list
Available applications:
OpenSSH
We need to make sure that the firewall allows SSH connections so that we can log back in next time.
▶ sudo ufw allow OpenSSH
▶ sudo ufw enable
You can see that SSH connections are still allowed by typing:
▶ sudo ufw status
Oh-My-Zsh is a framework for Zsh, the Z shell. In order for Oh-My-Zsh to work, Zsh must be installed.
▶ sudo apt-get install zsh
Verify installation by running zsh --version
. Expected result: zsh 4.3.9
or more recent.
Make it your default shell.
▶ chsh -s $(which zsh)
exit
the server and log-in again. You are going to see the Z Shell configuration, choose the option (2)
.
You can test that it worked with
▶ echo $SHELL
Expected result: /bin/zsh
or similar.
Oh My Zsh is installed via curl
running the following command.
▶ sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
After it finish you are going to see you new terminal style. You can start styling your terminal by editing the file
▶ sudo vim ~/.zshrc
For more information about all the things you could do with Oh My Zsh check https://github.com/robbyrussell/oh-my-zsh
Example:
# ~/.zshrc file
ZSH_THEME="avit" #change your theme.
plugins=(git npm) #use different plugins.
alias zsho="sudo vim ~/.zshrc" #write your own aliases.
Every time you change the ~/.zshrc
file you need reload your zsh settings:
▶ source ~/.zshrc
This package provides syntax highlighing for the shell zsh
Install it in the oh-my-zsh's plugins directory:
▶ git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
Add it to your plugin list
▶ sudo vim ~/.zshrc
# scroll to plugins
▶ plugins=( git npm zsh-syntax-highlighting)
Source ~/.zshrc
to take changes into account
▶ source ~/.zshrc
▶ sudo apt-get update
▶ sudo apt-get install nginx
▶ sudo ufw allow 'Nginx HTTP'
Verify the change
▶ sudo ufw status
To check if Nginx is running type:
▶ systemctl status nginx
or just check it in Chrome with the <server-ip>
▶ sudo systemctl stop nginx
▶ sudo systemctl start nginx
▶ sudo systemctl restart nginx
▶ sudo systemctl reload nginx
▶ sudo systemctl disable nginx
▶ sudo systemctl enable nginx
/var/www/html
: The actual web content, which by default only consists of the default Nginx page you saw earlier, is served out of the /var/www/html directory. This can be changed by altering Nginx configuration files./etc/nginx
: The nginx configuration directory. All of the Nginx configuration files reside here./etc/nginx/sites-enabled/
: The directory where enabled per-site "server blocks" are stored. Typically, these are created by linking to configuration files found in thesites-available
directory.
Follow this guide if you don't know how to set up your host name
Open the file for editing:
▶ sudo vim /etc/nginx/sites-enabled/default
server {
listen 80;
server_name www.mysite.com mysite.com;
location / {
root /var/www/portfolio;
index index.html;
}
error_page 404 /404.html;
location = /404.html {
root /var/www/portfolio;
}
}
# reverse proxy
server {
listen 80;
server_name www.test.mysite.com test.mysite.com; # subdomains
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Make sure you didn't introduce any syntax errors by typing:
▶ sudo nginx -t
Next, restart Nginx:
▶ sudo systemctl restart nginx
Node.js with NodeSource
▶ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
▶ sudo apt-get install -y nodejs
▶ sudo apt-get install build-essential
PM2 is a process manager for Node.js applications
▶ sudo npm i -g pm2
The startup
subcommand generates and configures a startup script to launch PM2 and its managed processes on server boots:
▶ pm2 startup systemd
▶ sudo npm install pm2@latest -g ; pm2 update
Process State Management:
▶ pm2 start app.js --name "api"
▶ pm2 restart api/all
▶ pm2 stop api/all
▶ pm2 delete api/all
▶ pm2 kill
Process Monitoring:
▶ pm2 list
▶ pm2 monit
▶ pm2 show [app-name]
▶ pm2 logs
Fail2Ban is an intrusion prevention software framework that protects computer servers from brute-force attacks.
▶ sudo apt-get update
▶ sudo apt-get install fail2ban
We need to copy the jail.conf
file with the contents commented out, as the basis for the our jail.local
file. We can do this by typing:
▶ awk '{ printf "# "; print; }' /etc/fail2ban/jail.conf | sudo tee /etc/fail2ban/jail.local
▶ sudo vim /etc/fail2ban/jail.local
Important default settings:
[DEFAULT]
...
# source addresses that fail2ban ignores
ignoreip = 127.0.0.1/8
# length of time that a client will be banned. 600 seconds = or 10 minutes.
bantime = 600
# The maxretry variable sets the number of tries a client has to authenticate within a window of time defined by findtime, before being banned.
findtime = 600
maxretry = 3
In the jail.local
file there is a JAILS
section. Each of these sections can be enabled by uncommenting the header and changing the enabled
line to be true
.
To enable log monitoring for Nginx login attempts, we will enable the [nginx-http-auth]
jail.
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = %(nginx_error_log)s
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = %(nginx_error_log)s
maxretry = 2
This is the only Nginx-specific jail included with Ubuntu's fail2ban
package. However, we can create our own jails to add additional functionality.
[nginx-noscript]
enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx/access.log
maxretry = 6
[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 2
[nginx-nohome]
enabled = true
port = http,https
filter = nginx-nohome
logpath = /var/log/nginx/access.log
maxretry = 2
[nginx-noproxy]
enabled = true
port = http,https
filter = nginx-noproxy
logpath = /var/log/nginx/access.log
maxretry = 2
We need to create the filter files for the jails we've created. These filter files will specify the patterns to look for within the Nginx logs.
▶ cd /etc/fail2ban/filter.d
We actually want to start by adjusting the pre-supplied Nginx authentication filter to match an additional failed login log pattern.
▶ sudo vim nginx-http-auth.conf
[Definition]
failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: <HOST>, server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$
^ \[error\] \d+#\d+: \*\d+ no user/password was provided for basic authentication, client: <HOST>, server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$
ignoreregex =
Next, we'll create a filter for our [nginx-noscript]
jail:
▶ sudo vim nginx-noscript.conf
[Definition]
failregex = ^<HOST> -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\.scgi)
ignoreregex =
Next, create a filter for the [nginx-nohome]
jail:
▶ sudo vim nginx-nohome.conf
[Definition]
failregex = ^<HOST> -.*GET .*/~.*
ignoreregex =
We create the filter for the [nginx-noproxy]
jail:
▶ sudo vim nginx-noproxy.conf
[Definition]
failregex = ^<HOST> -.*GET http.*
ignoreregex =
And finally, we can copy the apache-badbots.conf
file to use with Nginx.
▶ sudo cp apache-badbots.conf nginx-badbots.conf
To implement your configuration changes, you'll need to restart the fail2ban service. You can do that by typing:
▶ sudo service fail2ban restart
You can look at iptables to see that fail2ban has modified your firewall rules to create a framework for banning clients
▶ sudo iptables -S
▶ sudo fail2ban-client status
see the enable jails▶ sudo fail2ban-client status nginx-http-auth
: see the status of that particular jail
From another server, we can test the rules by getting our second server banned. After logging into your second server, try to SSH into the fail2ban server. You can try to connect using a non-existent name for instance:
# second sever
▶ ssh blah@fail2ban_server_ip
Repeat this a few times. At some point, the fail2ban server will stop responding.
On your fail2ban server, you can see the new rule by checking our iptables again:
▶ sudo iptables -S
...
-A f2b-sshd -s second_server_ip -j REJECT --reject-with icmp-port-unreachable
Let’s Encrypt is a certificate authority (CA) offering free and automated SSL/TLS certificates. Certificates issued by Let’s Encrypt are trusted by most browsers in production today.
Install certbot check here
▶ sudo apt-get update
▶ sudo apt-get install software-properties-common
▶ sudo add-apt-repository universe
▶ sudo add-apt-repository ppa:certbot/certbot
▶ sudo apt-get update
▶ sudo apt-get install python-certbot-nginx
Certbot has various plugins to generate SSL certificates. The NGINX Plugin will take care of re-configuring NGINX and reloading the configuration whenever necessary.
To generate SSL certificates with the NGINX plugin, run the following command:
▶ sudo certbot --nginx -d example.com -d www.example.com
Once the process has completed successfully, certbot will prompt you to configure your HTTPS settings, which includes entering your email address and agreeing to the Let’s Encrypt terms of service.
We need to make sure that the firewall allows HTTPS connections.
▶ sudo ufw allow 'Nginx HTTPS'
Let’s Encrypt certificates expire in 90 days. We encourage you to automatically renew your certificates when they expire. We’ll set up a cron job to do this.
crontab -e
we enter the certbot command we wish to run daily. The command will check to see if the certificate on the server will expire within the next 30 days, and renew it if so.
0 12 * * * /usr/bin/certbot renew --quiet
▶ cd /var
▶ sudo mkdir repo && sudo mkdir repo/<site-name>.git
▶ sudo chown -R <owner>:<group> repo
▶ cd repo/<site-name>.git && git init --bare
--bare
means that our folder will have no source files, just the version control.
in /var/repo/<site-name>.git/hooks/
create the file 'post-receive' and type:
git --work-tree=/var/www/<site-folder> --git-dir=/var/repo/<site-name> checkout -f
save and set the proper permissions using:
chmod +x post-receive
In you local repository add a new remote:
git remote add live ssh://user@mydomain.com/var/repo/<site-name>.git
git push live master
▶ sudo chown -R <owner>:<group> <folder>
Change the owner and/or group of each FILE to OWNER and/or GROUP.▶ sudo tail -f /var/log/nginx/access.log
view Nginx logs▶ sudo tail -f /var/log/nginx/error.log
view Nginx error logs▶ ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
check ip▶ curl -4 icanhazip.com
check ip
- How To Set Up a Host Name with DigitalOcean
- How To Set Up a Node.js Application for Production on Ubuntu 16.04
- How To Set Up Automatic Deployment with Git with a VPS
- How To Set Up a Host Name with DigitalOcean
- How To Protect SSH with Fail2Ban on Ubuntu 14.04
- Using Free Let’s Encrypt SSL/TLS Certificates with NGINX