Skip to content

Instantly share code, notes, and snippets.

@disono
Last active March 5, 2023 18:04
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save disono/633c6fc37a10ba752018a870336e5b70 to your computer and use it in GitHub Desktop.
Save disono/633c6fc37a10ba752018a870336e5b70 to your computer and use it in GitHub Desktop.
Setup Ubuntu Server for 20.04

SSH

$ sudo apt install openssh-server
$ sudo systemctl status ssh
# firewall
$ sudo ufw allow ssh

Swap file

In sleep mode, the content of ram is kept as it is, 
and the computer works on a very low power mode, 
so as to keep the ram content intact (as ram will 
lose the data if power supply is cut to it). 
But in hibernation, the ram content is stored in the swap space, 
so power can be completely cut off. Hence it is 
recommended to have swap size as large as the ram size.

First disable the swap and delete it
 $ sudo swapoff /swapfile  
 $ sudo rm  /swapfile

Create new swap space of size 16 GB (16 * 1024 = 16384). 
bs is the block size. Basically bs * count = bytes to 
be allocated (in this case 16 GB). Here bs = 1M 
(M stands for mega, so we are assigning 1MB block size) and 
we are allocating 16384 * 1MB (=16GB) to swap.

 $ sudo dd if=/dev/zero of=/swapfile bs=1M count=16384

Give it the read/write permission for root

 $ sudo chmod 600 /swapfile

Format it to swap

 $ sudo mkswap /swapfile

Turn on swap again

 $ sudo swapon /swapfile

Now reboot the PC for the above changes to take place.

Redis

$ sudo apt install redis-server

Golang

Installing Python3

Creating New User Account

$ sudo adduser username

# verification
$ cat /etc/passwd
$ grep '^username' /etc/passwd

Install Nginx

$ sudo apt-get install nginx -y

# restart php-fpm
$ sudo service php7.4-fpm restart

# configure max upload (optional)
$ sudo nano /etc/nginx/nginx.conf
client_max_body_size 100M;
fastcgi_read_timeout 300;
proxy_read_timeout 300;

Installing Nginx to Windows 10 Subsystem

Issues

$ sudo nano /etc/nginx/nginx.conf
> fastcgi_buffering off;

Install Components

$ sudo apt install curl git unzip

PHP Setup

$ sudo apt-add-repository ppa:ondrej/php

Install PHP 8.1

$ sudo apt install php-dev php-fpm php-mysql php-json php-xml php-bz2 php-zip php-mbstring php-curl php-pear php-gd

Install PHP 7.2

$ sudo apt install php7.2-dev php7.2-fpm php7.2-mysql php7.2-json php7.2-xml php7.2-bz2 php7.2-zip php7.2-mbstring php7.2-curl php7.2-pear php7.2-php-gettext php7.2-gd

SQL (Microsoft Mod)

sudo apt-get -y install php-pear php7.*-dev

sudo update-alternatives --set php /usr/bin/php7.*
sudo update-alternatives --set phar /usr/bin/phar7.*
sudo update-alternatives --set phar.phar /usr/bin/phar.phar7.*
sudo update-alternatives --set phpize /usr/bin/phpize7.*
sudo update-alternatives --set php-config /usr/bin/php-config7.*

sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
sudo su
printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/7.*/mods-available/sqlsrv.ini
printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/7.*/mods-available/pdo_sqlsrv.ini
exit
sudo phpenmod -v 7.* sqlsrv pdo_sqlsrv

Install Composer

$ sudo apt install composer

Enable PHP module

$ sudo phpenmod -v <PHP VERSION> <MODULE NAME>

e.g. phpenmod -v 7.2 mbstring

Install FFMpeg (optional)

$ sudo apt install ffmpeg

Install NodeJS

# clean install
$ sudo apt-get remove nodejs ^node-* nodejs-*
$ sudo apt-get autoremove
$ sudo apt-get clean

# apt
$ sudo apt install nodejs
$ sudo apt install npm

# stable release
$ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt-get install -y nodejs

# optional
$ sudo apt install libssl1.0-dev
$ sudo apt install node-gyp
$ sudo apt install npm

# configure npm without sudo
# list currently installed packages
$ npm list -g --depth=0

# npm to install packages to home
$ npm config get prefix
$ npm config set prefix ~/npm

# fix your paths
$ nano ~/.bashrc
# add these lines:
> export PATH="$PATH:$HOME/npm/bin"
> export NODE_PATH="$NODE_PATH:$HOME/npm/lib/node_modules"
$ . ~/.bashrc

# take ownership
$ ls -la ~/.npm
$ sudo chown -R $USER:`id -g -n $USER` ~/.npm

# update your .bash_profile
# add this line:
> source ~/.bashrc

Installing PM2 (Optional)

$ npm install pm2@latest -g
$ pm2 start your_app.js

# run pm2 on startup
$ pm2 startup systemd
# The last line of the resulting output will include a command 
# to run with superuser privileges in order to set PM2 to start on boot:
# Output:
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u username --hp /home/username

# Run the command from the output, with your username in place of username:
$ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u username --hp /home/username

# As an additional step, we can save the PM2 process list and corresponding environments:
$ pm2 save

# You have now created a systemd unit that runs pm2 for your user on boot. 
# This pm2 instance, in turn, runs hello.js. 
# Start the service with systemctl:
$ sudo systemctl start pm2-username

# Check the status of the systemd unit:
$ systemctl status pm2-username

# Stop an application with this command (specify the PM2 App name or id):
$ pm2 stop app_name_or_id

# Restart an application:
$ pm2 restart app_name_or_id

# List the applications currently managed by PM2:
$ pm2 list

# Get information about a specific application using its App name:
$ pm2 info app_name

# The PM2 process monitor can be pulled up with the monit subcommand. 
# This displays the application status, CPU, and memory usage:
$ pm2 monit

Setting Up Nginx as a Reverse Proxy Server (Optional)

$ sudo nano /etc/nginx/sites-available/example.com

# content
server {
        ...
        location / {
                proxy_pass http://localhost:3000;
                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;
        }
        ...
}

$ sudo nginx -t
$ sudo systemctl restart nginx

Install MongoDb (Optional)

$ sudo apt install -y mongodb

# check status
$ sudo systemctl status mongodb
$ mongo --eval 'db.runCommand({ connectionStatus: 1 })'

# status
$ sudo systemctl status mongodb

# stop
$ sudo systemctl stop mongodb

# start
$ sudo systemctl start mongodb

# restart
$ sudo systemctl restart mongodb

# disable on restart
$ sudo systemctl disable mongodb

# enable on restart
$ sudo systemctl enable mongodb

# Adjusting the Firewall (Optional)
# allow other server to connect
$ sudo ufw allow from {your_other_server_ip}/32 to any port 27017

Secure Mongo

Terminal 1:

$ mongod --auth
Terminal 2:

$ db.createUser({user:"admin_name", pwd:"1234",roles:["readWrite","dbAdmin"]})
if you want to add without roles (optional):

$ db.createUser({user:"admin_name", pwd:"1234", roles:[]})
to check if authenticated or not:

$ db.auth("admin_name", "1234")
it should give you:

1
else :

Error: Authentication failed.
0

Install MySQL

# stop mysql before reinstalling
$ sudo pkill mysql
$ sudo pkill mysqld

# clean install
$ sudo apt-get remove --purge mysql*
$ sudo apt-get purge mysql*
$ sudo apt-get autoremove
$ sudo apt-get autoclean
$ sudo apt-get remove dbconfig-mysql

$ sudo apt install mysql-server
$ sudo mysql_secure_installation

# create new mysql user non-sudo
$ sudo mysql -u root -p
> CREATE USER 'user_name'@'localhost' IDENTIFIED BY 'your_password';
> CREATE DATABASE your_database_name;
> GRANT ALL PRIVILEGES ON your_database_name.* TO 'user_name'@'localhost';
> FLUSH PRIVILEGES;

# remove sudo (development)
$ sudo mysql -u root -p
> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';

# create new super user or another root (optional)
> GRANT ALL PRIVILEGES ON *.* TO 'your_root_username'@'localhost';

# Rename user
> RENAME USER 'username'@'host' TO 'new_username'@'localhost';

# Allow remote login (WARNING)
> CREATE USER 'root'@'%' IDENTIFIED BY 'root';
> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

# Remove password (for development ONLY)
> SHOW VARIABLES LIKE 'validate_password%';
> SET GLOBAL validate_password.number_count = 0;
> SET GLOBAL validate_password.length = 0;
> SET GLOBAL validate_password.mixed_case_count = 0;
> SET GLOBAL validate_password.policy = 0;
> SET GLOBAL validate_password.special_char_count = 0;
> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';

# Legacy password (Warning)
> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

# Delete or remove user
> DROP USER 'username'@'localhost';

# Start and Stop
$ sudo service mysql start
$ sudo service mysql stop

# Make sure date and time is correct
> SELECT CURDATE();

Disabling ONLY_FULL_GROUP_BY (MySQL 5.7+)

# Mysql 5.*
$ sudo nano /etc/mysql/my.cnf
> [mysqld]
> sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

# Mysql 8
$ sudo nano /etc/mysql/my.cnf
> [mysql]
> sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,TIME_TRUNCATE_FRACTIONAL"

Securing Server

// setup firewall
$ sudo ufw enable
$ sudo ufw allow 'Nginx HTTP'
$ sudo ufw disable
$ sudo ufw status

ClamAV

$ sudo apt install clamav
$ sudo systemctl stop clamav-freshclam
# update
$ sudo freshclam
$ sudo systemctl start clamav-freshclam
# scan folder
$ sudo clamscan -i -r --max-scansize=4000M --max-filesize=4000M ~/your_folder

Fail2ban

$ sudo apt install fail2ban -y
$ sudo systemctl start fail2ban
$ sudo systemctl enable fail2ban

Firewall

1. Using IPv6 with UFW (Optional)
$ sudo nano /etc/default/ufw
IPV6=yes

2. Setting Up Default Policies
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing

3. Allowing SSH Connections
$ sudo ufw allow ssh
$ sudo ufw allow 22

4. Enabling UFW
$ sudo ufw enable

Configure Nginx

$ sudo nano /etc/nginx/sites-available/example.com

// add this to content
server {
        listen                  8080 ssl;
        root                    /var/www/html/example.com;
        index                   index.php index.html index.htm index.nginx-debian.html;
        server_name             example.com;
        
        # SSL Certificate
        ssl_certificate         /usr/local/var/www/Certificate/selfsigned.crt;
        ssl_certificate_key     /usr/local/var/www/Certificate/selfsigned.key;
        
        # SSL
        ssl_ciphers             EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
        ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_cache       shared:SSL:10m;
        ssl_session_timeout     10m;
        
        # Headers with under score
        underscores_in_headers  on;

        location / {
                try_files       $uri $uri/ =404;
                
                # all query to index.php
                # try_files     $uri $uri/ /index.php?$query_string;
        }

        # PHP FPM configuration.
        location ~ \.php$ {
                # include       snippets/fastcgi-php.conf;
                # fastcgi_pass  unix:/var/run/php/php7.4-fpm.sock;
                
                include         fastcgi.conf;
                fastcgi_pass    127.0.0.1:9000;
                fastcgi_index   index.php;
                include         fastcgi_params;
        }

        # We don't need .ht files with nginx.
        location ~ /\.ht {
                deny all;
        }
        
        # Remove trailing slash to please routing system.
        if (!-d $request_filename) {
                rewrite         ^/(.+)/$ /$1 permanent;
        }
        
        # Set header expirations on per-project basis
        location ~* \.(?:ico|css|js|jpe?g|JPG|png|svg|woff)$ {
                expires         365d;
        }
}

// enable the site
$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

// test the configuration
$ sudo nginx -t

// reload nginx
$ sudo systemctl reload nginx

HTTPS/SSL

$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot
$ sudo ufw allow 80

# note to disable nginx before continue
sudo certbot certonly --standalone --preferred-challenges http -d example.com -d sub1.example.com -d sub2.example

# Automatic renewal
$ sudo nano /etc/letsencrypt/renewal/example.com.conf
# Update
renew_hook = systemctl reload rabbitmq

$ sudo certbot renew --dry-run

Permissions

1. Allow Apache access to the folders and the files.
$ sudo chgrp -R www-data /var/www/html
$ sudo find /var/www/html -type d -exec chmod g+rx {} +
$ sudo find /var/www/html -type f -exec chmod g+r {} +

2. Give your owner read/write privileges to the folders and the files, 
and permit folder access to traverse the directory structure.
$ sudo chown -R {username} /var/www/html/
$ sudo find /var/www/html -type d -exec chmod u+rwx {} +
$ sudo find /var/www/html -type f -exec chmod u+rw {} +

3. (Optional) Make sure every new file after this is created with www-data as the 'access' user.
$ sudo find /var/www/html -type d -exec chmod g+s {} +

4. (Optional) Final security cleanup, if you don't want other users to be able to see the data
$ sudo chmod -R o-rwx /var/www/html/

Configure PHPMyAdmin

$ sudo apt-get install phpmyadmin
$ sudo ln -s /usr/share/phpmyadmin /var/www/html

Install RTMP

$ sudo apt install libnginx-mod-rtmp

Install FTP

$ sudo apt-get install vsftpd

1. Update the file
$ sudo nano /etc/vsftpd.conf
> anonymous_enable=Yes

# To allow local users to login, edit the /etc/vsftpd.conf  file by changing.
> local_enable=YES
> local_umask=022

# To grant local users to write to a directory change the write_enable setting to YES.
> write_enable=YES

# Local users can be limited to their home directories by uncommenting.
> chroot_local_user=YES
> allow_writeable_chroot=YES

# Restart ftp
$ service vsftpd restart

# Allo to firewall (ufw)
$ sudo ufw allow 20/tcp
$ sudo ufw allow 21/tcp
$ sudo ufw allow 990/tcp
$ sudo ufw allow 40000:50000/tcp
$ sudo ufw status

Change user default home folder

$ cd /home;
$ sudo mkdir folder_name
$ sudo chown username:username folder_name
$ sudo usermod -d /your/new/home folder_name

Add a existing user to www-data group

$ sudo usermod -a -G www-data {username}
$ id {username}
$ groups {username}

Virtualbox www-data permission for shared folder /media/sf_*

$ sudo apt install build-essential dkms linux-headers-$(uname -r)

$ sudo mkdir -p /mnt/cdrom
$ sudo mount /dev/cdrom /mnt/cdrom

$ cd /mnt/cdrom
$ sudo sh ./VBoxLinuxAdditions.run --nox11
$ sudo shutdown -r now
# verify
$ lsmod | grep vboxguest

# add folder persmission under shared folder /media/sf_*
$ sudo usermod -aG vboxsf $USER
$ sudo adduser $USER vboxsf
$ sudo shutdown -r now

$ sudo usermod -a -G vboxsf www-data

# enable syslink (Dangerous) for host OS
# after enabling restart vm and run vm as administrator
$ VBoxManage setextradata "VM_Name" VBoxInternal2/SharedFoldersEnableSymlinksCreate/Folder_Name 1

# list vm
$ VBoxManage list vms

# show vm info
$ VBoxManage showvminfo "VM_Name"

Laravel folder permissions (optional)

$ find {laravel-folder}/ -type d -exec chmod 755 {} \;
$ find {laravel-folder}/ -type d -exec chmod ug+s {} \;
$ find {laravel-folder}/ -type f -exec sudo chmod 644 {} \;
$ sudo chown -R {username}:www-data {laravel-folder}
$ sudo chmod -R 777 {laravel-folder}/storage
$ sudo chmod -R 777 {laravel-folder}/public/private
$ sudo chmod -R 777 {laravel-folder}/bootstrap/cache

CronJob

$ sudo nano /etc/crontab
# add to your cron job (run every minute)
> * * * * * {username} php /{your-app-folder}/artisan schedule:run >> /dev/null 2>&1

# to run every hour
> 0 * * * *

# restart cron
$ sudo service cron restart

# syntax
1 2 3 4 5 USERNAME /path/to/command arg1 arg2

1: Minute (0-59)
2: Hours (0-23)
3: Day (0-31)
4: Month (0-12 [12 == December])
5: Day of the week(0-7 [7 or 0 == sunday])
USERNAME - Name of the user
/path/to/command – Script or command name to schedule

Examples:
The correct syntax is as follows for root user to run a cron job at 00:50 every day.
> 50 0 * * * root /etc/cron.d/backups

Add to path variables

# open and add to .bashrc
$ nano .bashrc
> export PATH="/your-path-to-software/bin:/your-path-to-software/bin:${PATH}"
$ source ~/.bashrc

Configure Network

# list network cards
$ ip link show

# network info
$ netstat -i

# details
$ ifconfig {interface-name}

# update network
$ sudo nano /etc/network/interfaces

# Use NetPlan
# check available config files
$ ls /etc/netplan/
$ sudo nano /etc/netplan/01-netcfg.yaml
> dhcp4: no
>      addresses: [192.168.1.8/24]
>      gateway4: 192.168.1.1
>      nameservers:
>        addresses: [8.8.8.8,8.8.4.4]
$ sudo netplan apply

# for debugging
$ sudo netplan --debug apply

# DHCP
> source /etc/network/interfaces.d/*
> # The loopback network interface
> auto lo
> iface lo inet loopback
> # The primary network interface
> auto {interface-name}
> iface {interface-name} inet dhcp

# Static
> source /etc/network/interfaces.d/*
> # The loopback network interface
> auto lo
> iface lo inet loopback
> # The primary network interface
> auto {interface-name}
> iface {interface-name} inet static
> address 192.168.1.1
> netmask 255.255.255.0
> network 192.168.1.0
> broadcst 192.168.0.255
> gateway 192.168.1.1
> dns-nameservers 8.8.8.8

Assign Static IP

$ ip add show

$ sudo nano /etc/netplan/00-installer-config.yaml

# update
  enp0s3:
    addresses: [ip-address/24]
    gateway4: ip-gateway
    nameservers:
      addresses: [8.8.4.4, 8.8.8.8]

$ sudo netplan apply

USB Automount (Optional)

$ sudo apt-get install usbmount

# NTFS support
$ sudo apt-get install ntfs-3g

# Update configuration
$ sudo nano /etc/usbmount/usbmount.conf

# Add new support under "FILESYSTEMS"
# ntfs and fuseblk

Install deb packages

$ sudo dpkg -i example.deb

# force install
$ sudo apt install -f

Mount remote shared folder on reboot

$ sudo nano /etc/fstab
> //your-ip-address/Works /path-to-shared-folder cifs username=developer,password=your-password,iocharset=utf8,file_mode=0777,dir_mode=0777,noperm 0 0

Python & Pip3

# add pip3 installed packages
$ sudo nano ~/.profile
> export PATH=$HOME/.local/bin:$PATH
$ source ~/.profile

$ sudo apt-get install gcc
$ sudo apt-get install libpq-dev python3-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev libffi-dev

# for cryptography (required by twisted[tls])
$ sudo apt-get install -y libssl-dev libffi-dev

# for lxml
$ sudo apt-get install -y libxml2-dev libxslt1-dev

Java/JDK 8

# JDK
$ sudo apt install openjdk-8-jdk-headless

# JRE
$ sudo apt install openjdk-8-jre-headless

Hyper-V (Optional)

# install desktop version of Ubuntu
$ git clone https://github.com/Microsoft/linux-vm-tools.git
$ cd ~/linux-vm-tools/ubuntu/**.**/
$ sudo chmod +x install.sh
$ sudo ./install.sh
$ sudo reboot

# Edit XRDP INI file
$ sudo nano /etc/xrdp/xrdp.ini
> port=vsock://-1:3389
> use_vsock=false

# Start XRDP service
$ sudo systemctl enable xrdp.service
$ sudo systemctl start xrdp.service

# run powershell as admistration
$ Set-VM -VMName {Hyper-V-Name} -EnhancedSessionTransportType HvSocket
$ VMConnect.exe localhost {Hyper-V-Name} /edit

References

@macroramesh6
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment