# Creating a VPS for OGSpy Multi From Ubuntu 20.04 LTS # Packages sudo apt update sudo apt upgrade # Create User sudo adduser darknoon Add user to sudo group sudo usermod -aG sudo darknoon # SSH Config Warn : Each step need to be tested here as it could break the ssh connectivity ## Configure Default SSH port sudo vi /etc/ssh/sshd_config uncomment Port line and set a new port : Port 3421 Reload Parameters for the service: sudo service sshd reload ## Authorize Certificates Connect with user su - darknoon Create folder .ssh mkdir ~/.ssh Create file Authorized keys touch ./authorized_keys Add that line to the file ssh-ed25519 AAAAfsdfdfsfsdfsdfklopzekoprejzifo5zefio7fio4zioyfiozvfiozf1 ## Remove Authentication with Password Default SSH port sudo vi /etc/ssh/sshd_config Set passwordAuthentification to no PasswordAuthentication no Reload Parameters for the service: sudo service sshd reload Before closing the SSH window, try the connection using a new SSH client. If its not working revert PasswordAuthentification to yes and reload the service. # Firewall Config ## Update OpenSSH Profile in UFW Apps with your custom port sudo vi /etc/ufw/applications.d/openssh-server Change line ports to : ports=3421/tcp Enable Firewall with OpenSSH App sudo ufw enable sudo ufw allow 'Openssh’ sudo ufw status Before closing the SSH window, try the connection using a new SSH client. If its not working : sudo ufw disable # Hostname Set the server hostname according to your DNS pointed on that machine sudo vi /etc/hostname # Web Stack ## Install LNMP Stack Packages sudo apt install nginx php php-fpm mariadb-server php-mysql php-json php-zip php-xml ## Open Firewall Ports sudo ufw allow 'Nginx Full' ## Set Web Server Working Folder mkdir /srv/www/ogspy.fr Set Correct rights on that folder sudo chown ww-data:www-data -R . sudo chmod -R ## Configure Nginx for HTTP Edit Configure a simple Http Server to get your first certificate (See well-known part) Edit /etc/nginx/sites.available/default # Default server configuration # server { listen 80 default_server; listen [::]:80 default_server; server_name ogspy.fr www.ogspy.fr pma-darkcity.ogspy.fr; root /srv/www/ogspy.fr; #Your root folder #Lets Encrypt location ~ /.well-known { allow all; } location / { return 301 https://$host$request_uri; # Redirection HTTPS } } Start Server sudo service nginx start ## Prerequisites HTTPS Configure Lets Encrypt Certificate sudo apt install certbot certbot certonly --webroot -w /srv/www/ogspy.fr -d ogspy.fr Your certificate is now available in /etc/letsencrypt/live/ogspy.fr ## Configure Diffie Hellman Dhparam https://wiki.openssl.org/index.php/Diffie_Hellman cd /etc/ssl/certs sudo openssl dhparam -out dhparam.pem 4096 ## Configure SSL in NGINX Nginx : Add this section to your default configuration (/etc/nginx/sites-available/default server { # SSL configuration # listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; # # Note: You should disable gzip for SSL traffic. # See: https://bugs.debian.org/773332 # # Read up on ssl_ciphers to ensure a secure configuration. # See: https://bugs.debian.org/765782 # # Self signed certs generated by the ssl-cert package # Don't use them in a production server! # include snippets/ssl-ogspy.fr.conf; # Will be created just after include snippets/ssl-params.conf; # Will be created just after root /srv/www/ogspy.fr; #Configurations client_max_body_size 64M; # Add index.php to the list if you are using PHP index index.php index.html index.htm index.nginx-debian.html; server_name ogspy.fr www.ogspy.fr; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { include snippets/fastcgi-php.conf; # With php7.4-fpm: fastcgi_pass 127.0.0.1:9001; # fastcgi_pass unix:/run/php/php7.0-fpm.sock; #Socket Option } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\.ht { deny all; } #Lets Encrypt location ~ /.well-known { allow all; } # Block xmlrpc.php access location = /xmlrpc.php { deny all; } } We will now create mentioned files in the snippets folder : Create the file /etc/nginx/snippets/ssl-ogspy.fr.conf for the link with your certificate ssl_certificate /etc/letsencrypt/live/ogspy.fr/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ogspy.fr/privkey.pem; Create the file /etc/nginx/snippets/ssl-params.conf for the SSL configuration # from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1.2; ssl_prefer_server_ciphers on; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # disable HSTS header for now #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:!ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:!ECDHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA256:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA256:!DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:!ECDHE-RSA-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!AES128-GCM-SHA256:!AES256-GCM-SHA384:!AES128-SHA256:!AES256-SHA256:!AES128-SHA:!AES256-SHA:!DES-CBC3-SHA:!DSS"; # ssl_session_timeout 24h; # keepalive_timeout 300s; # up from 75 secs default ssl_dhparam /etc/ssl/certs/dhparam.pem; ## PHP-FPM Configure the default Pool : Open file /etc/php/7.4 sudo vi /etc/php/7.4/fpm/pool.d/www.conf Change socket to port 9001 ; The address on which to accept FastCGI requests. ; Valid syntaxes are: ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on ; a specific port; ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on ; a specific port; ; 'port' - to listen on a TCP socket to all addresses ; (IPv6 and IPv4-mapped) on a specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. ;listen = /run/php/php7.4-fpm.sock listen = 127.0.0.1:9001 # Configure here You can now try to start your Nginx Server 🙂 sudo service nginx start ## MariaDB Configure Root Access (Root access is accessible by unix socket) sudo mysql_secure_installation Connect to MariaDb console mysql -u root -p Create User CREATE USER 'darknoon'@localhost IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'darknoon'@localhost IDENTIFIED BY 'password'; FLUSH PRIVILEGES; SHOW GRANTS FOR 'darknoon'@localhost; You should now be able to connect to the SQL Server using HeidiSQL for example. Connection using SSH. ## Backup Create a backup user to allow access from outside. sudo adduser userbackup Add user to sudo group sudo usermod -aG backup userbackup Create for a SSH Keys that you will define in its home folder : .ssh/authorized_keys (Public key) Here is the backup script, we can set it anywhere in the filesystem. I use to put it in the root folder but its your choice 🙂 #!/bin/bash #################################### # # Backup Files # #################################### # What to backup. backup_files="/home /etc /root /srv/www" # Where to backup to. dest="/var/archives" # Create archive filename. day=$(date +%F) hostname=$(hostname -s) archive_file="$hostname-$day.tgz" # Print start status message. echo "Backing up $backup_files to $dest/$archive_file" if [ ! -f "$dest/$archive_file" ]; then # Backup the files using tar. tar czf $dest/$archive_file $backup_files else echo "Backup already generated today" fi #################################### # # Backup SQL DB # #################################### # Print start status message. echo "Backing up SQL DB" for DB in $(mysql -e 'show databases' -s --skip-column-names); do if [ ! -f "$dest/$hostname-$day-sql-$DB.gz" ]; then mysqldump $DB | gzip > "$dest/$hostname-$day-sql-$DB.gz"; fi done ####################################### # # Clean Up # ####################################### find $dest/. -type f ! -name "$hostname-$day*" -execdir rm -i {} + chown userbackup:backup $dest/* # Print end status message. echo echo "Backup finished" date # Long listing of files in $dest to check file sizes. ls -lh $dest ## Set Backup Execution Time sudo crontab -e Select your favorite Editor and add the line : 0 02 * * * /root/backup.sh Will run every Day at 2AM. (https://www.adminschoice.com/crontab-quick-reference)