☁️ Cloud Computing
Primary Services
Compute
Storage
Databases
Services Models
IaaS
- Networking
- Servers
- Storage
- Virtualization
Providers
Target Audience
- DevOps Engineers
PaaS
- Middleware
- Operating System
- Runtime
Target Audience
- Software Engineers
SaaS
- Applications
- Data
Roles
Cloud Architect
- Solutions architect of the cloud
- Design cloud infrastructure based on business requirements
Security Engineer
- Ensure data privacy of users and the organization is protected
- Spec out technical security requirements based on regulations and business requirements
Further Reading
DevOps Engineer
- Maintain infrastracture through code
- Ensure reliability, availability, and scalability through automation
- Experienced in software development and IT operations
Further Reading
[ ]
DevOps for the Desperate [Book][ ]
Python for DevOps [Book][ ]
DevOps With Python [Learning Path][ ]
Python DevOps [Tutorials][ ]
Learn Linux Administration and Supercharge Your Career [Video][ ]
Linux Administration Bootcamp [Video][ ]
Linux Security and Hardening [Video][ ]
Linux Shell Scripting [Video]
Setup VPS / Ubuntu
Init / Update The VM
I assume you already create a new virtual machine and you have a fresh system available. I also assume your virtual machine runs Ubuntu.
Change the default root password to a new one:
passwd root
Update the system packages to the newest version:
apt update && apt -y upgrade
If you want, you can install a terminalmultiplexer like tmux. Sometimes it is easier to work with tmux on a remote machine. Also I like to use mosh instead of ssh, because mosh is less restrictive if the connection is lost.
apt install -y tmux mosh
Setup A Standard User
You will do this initial setup as the root user. All work after setting up a new user should be done by using the new user, not the root user.
Create a new user and add it to the sudo group. Do not manage the server with the root user! Later we will disable root login in the sshd config. So no one is able to log in with the root user by ssh.
useradd -G sudo -s /bin/bash -m marcus
useradd is a command in Linux that is used to add user accounts to your system. It is just a symbolic link to adduser command in Linux and the difference between both of them is that useradd is a native binary compiled with system whereas adduser is a Perl script which uses useradd binary in the background. It make changes to the following files:
/etc/passwd
/etc/shadow
/etc/group
/etc/gshadow
creates a directory for new user in /home
Set a good password for your new user:
passwd marcus
Verify that the user was created correctly:
id marcus
uid=1000(marcus) gid=1000(marcus) groups=1000(marcus),27(sudo)
You can get more detailed information of a user by using the finger tool:
apt install -y finger finger marcus
Login: marcus Name: Directory: /home/marcus Shell: /bin/bash On since Sun Aug 28 07:04 (UTC) on pts/0 from 2003:ca:1f1e:7700:751a:6940:4e3b:3f49 1 minute 7 seconds idle On since Sun Aug 28 07:01 (UTC) on pts/1 from 2003:ca:1f1e:7700:751a:6940:4e3b:3f49 1 second idle (messages off) No mail. No Plan.
Send the public ssh key from your local machine to the remote machine to be able to log in via ssh with your new created user.
(I assume you only have one public key in your ~/.ssh directory)
ssh-copy-id marcus@u1.metaebene.dev
Automatic systems are constantly scanning the internet for open services and ports. This is a normal thing.
As a security action, using one of the following user names should be avoided:
ubuntu, oracle, rust, rustserver, kubernetes, vagrant, admin, account, pgsql, deploy, hadoop, ansible, user, pi, test, guest, support, xbmc, nagios, debian, minecraft, cisco, www, wwwrun, ftpuser, centos, joomla, puppet, docker, glassfish, bugzilla, wpuser, ts3, ts3server, postgres, jenkins, web, solarwinds, codenvy, mcserver, chef, deployer, ftpadmin, tomcat, wordpress, git, mysql, ec2-user, cloud, csgoserver, csgo, odoo, samsung, apple, acer, systems, maria, centos, cirros, mcserver, mcsrv, es
The following tasks should be done by using the new created user and not the root user.
SSHD Configuration
To be able to secure connect and work on the virtual machine you need to configure and setup sshd.
In simple terms, SSH (Secure Shell) is a protocol used to securely access remote computers over a network. It allows users to log in to a remote system and execute commands as if they were using a local terminal, but with the added security of encryption and authentication to protect the communication from eavesdropping, tampering, and other security threats. SSH also supports file transfers and port forwarding, making it a versatile tool for remote system management and access.
Create the sshd_config
Include /etc/ssh/sshd_config.d/*.conf
Disable login using root
Disabling root login in the sshd_config file makes it harder for attackers to gain unauthorized access to your server, and reduces the risk of accidental damage to the system. Root accounts have powerful access, and disabling their direct login forces attackers to use other accounts and adds an additional layer of security.
PermitRootLogin no UsePAM no
In general, it is recommended to disable challenge-response authentication, as it is less secure than other methods of authentication, such as public key authentication or password authentication.
ChallengeResponseAuthentication no
Disable password based login
PasswordAuthentication no
The AuthenticationMethods publickey setting allows only public key authentication for SSH connections, which is more secure than other methods of authentication like password authentication. It involves generating a key pair and providing the public key to the server, limiting the methods of authentication that an attacker can use to gain unauthorized access to the system.
AuthorizedKeysFile .ssh/authorized_keys AuthenticationMethods publickey PubkeyAuthentication yes
Limit Users’ ssh access
AllowUsers marcus DenyUsers root
Disable empty passwords
PermitEmptyPasswords no
Configure idle log out timeout interval
ClientAliveInterval 300 ClientAliveCountMax 0
The X11 protocol is not security oriented. If you don’t need it, you should disable the X11 forwarding in SSH.
X11Forwarding no
But still enable TCP forwarding, we will use it to secure connect to the lisp machine.
AllowTcpForwarding yes
Default configs
Subsystem sftp /usr/lib/openssh/sftp-server AcceptEnv LANG LC_* PrintMotd no
“KexAlgorithms curve25519-sha256@libssh.org” is a cryptographic setting that specifies the use of a key exchange algorithm called “curve25519-sha256” to securely establish a connection between the SSH client and server.
KexAlgorithms curve25519-sha256@libssh.org
“Ciphers chacha20-poly1305@openssh.com” is a cryptographic setting that specifies the use of a cipher algorithm called “chacha20-poly1305” to secure data during data exchange.
Ciphers chacha20-poly1305@openssh.com
“MACs hmac-sha2-512-etm@openssh.com” is a cryptographic setting that specifies the use of a MAC (Message Authentication Code) algorithm called “hmac-sha2-512-etm” to ensure data integrity during data exchange.
MACs hmac-sha2-512-etm@openssh.com
Copy the sshd_config to the remote maschine
On your remote machine first create a copy of the default sshd_config:
cp /etc/ssh/sshd_config ~/sshd_config.bak
Copy the newely created sshd_config to your remote machine into the /etc/ssh directory and restart the sshd server:
scp sshd_config marcus@u1.metaebene.dev:~/sshd_config sudo cp ~/sshd_config /etc/ssh/sshd_config sudo systemctl restart sshd
Cloud Init
#cloud-config #Make sure to check the cloud-init logs (/var/log/cloud-init.log and /var/log/cloud-init-output.log) locale: en_US.UTF-8 keyboard: layout: us timezone: Europe/Berlin groups: - nginxgroup users: - name: nginxuser system: true shell: /usr/sbin/nologin groups: nginxgroup sudo: null # Create a new user named 'marcus' - name: marcus # Add the user to the 'users' and 'admin' groups groups: users, admin # Allow the user to execute any command with sudo without entering a password sudo: ALL=(ALL) NOPASSWD:ALL # Set the user's default shell to /bin/bash shell: /bin/bash # Add the user's public SSH key for key-based authentication ssh_authorized_keys: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+46Y3AHPLJgz8KK61doqH3jBX2TL3TJvZsJrB9Km03 visua@xps-8930 - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMIHJ5qpMIKL7N3nC0GG1O4ygtkqOlQuZReoik6xGBxn marcus@XPS-13-9380.local packages: - fail2ban - ufw - unattended-upgrades - sbcl - mosh - tmux - git - mercurial - nginx - certbot - python3-certbot-nginx - libev4 - build-essential - sqlite3 - emacs-nox - python3-pip - python3-pandas - python3-matplotlib package_update: true package_upgrade: true write_files: - path: /etc/apt/apt.conf.d/20auto-upgrades content: | APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; APT::Periodic::Unattended-Upgrade "1"; - path: /etc/ssh/sshd_config content: | # Include additional configuration files from the specified directory Include /etc/ssh/sshd_config.d/*.conf # Set the maximum number of authentication attempts allowed per connection MaxAuthTries 3 # Specifies the file containing public keys for user authentication AuthorizedKeysFile .ssh/authorized_keys # Disables password authentication PasswordAuthentication no # Specifies the authentication method(s) to use (public key authentication in this case) AuthenticationMethods publickey # Enables public key authentication PubkeyAuthentication yes # Disables root login via SSH PermitRootLogin no # Disables keyboard-interactive authentication KbdInteractiveAuthentication no # Enables the Pluggable Authentication Module (PAM) for authentication UsePAM yes # Disables agent forwarding for SSH connections AllowAgentForwarding no # Enables TCP forwarding for SSH connections AllowTcpForwarding yes # Disables X11 forwarding for SSH connections X11Forwarding no # Disables printing of the message of the day (MOTD) when a user logs in PrintMotd no # Specifies the key exchange algorithms to use KexAlgorithms curve25519-sha256@libssh.org # Specifies the ciphers allowed for protocol version 2 Ciphers chacha20-poly1305@openssh.com # Specifies the message authentication code (MAC) algorithms in order of preference MACs hmac-sha2-512-etm@openssh.com # Specifies environment variables sent by the client to the server AcceptEnv LANG LC_* # Specifies the command to use for the SFTP subsystem Subsystem sftp /usr/lib/openssh/sftp-server # Specifies the user(s) allowed to log in via SSH (in this case, only the user "marcus") AllowUsers marcus # Create a new filter for Nginx - path: /etc/fail2ban/filter.d/nginx-http-auth.conf content: | # Define the filter [Definition] # Regular expression to match unauthorized requests in Nginx logs failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 401 .* # Regular expressions to ignore (none in this case) ignoreregex = # Add Nginx jail configuration - path: /etc/fail2ban/jail.d/nginx.conf content: | # Define the jail for Nginx [nginx-http-auth] # Enable the jail enabled = true # Specify the filter to use (created earlier) filter = nginx-http-auth # Define the action to take (using UFW) action = ufw # Specify the log file to monitor logpath = /var/log/nginx/error.log # Set the maximum number of failed attempts before banning maxretry = 6 # Set the ban time in seconds (1 hour) bantime = 3600 # Set the time window for failed attempts in seconds (10 minutes) findtime = 600 - path: /etc/fail2ban/jail.local content: | [DEFAULT] # Ban time (in seconds) for an IP after reaching the max number of retries. bantime = 3600 # Time window (in seconds) in which 'maxretry' failures must occur. findtime = 600 # Maximum number of failed login attempts before an IP gets banned. maxretry = 3 # Ban action to use (ufw in this case). banaction = ufw [sshd] # Enable the sshd jail. enabled = true # Specify the port for the sshd service. port = 22 # Path to the log file for the sshd service. logpath = /var/log/auth.log [sshd-ddos] # Enable the sshd-ddos jail. enabled = true # Specify the port for the sshd service. port = ssh # Path to the log file for the sshd service. logpath = /var/log/auth.log # Maximum number of failed login attempts before an IP gets banned (for DDoS protection). maxretry = 5 # Ban time (in seconds) for an IP after reaching the max number of retries (for DDoS protection). bantime = 600 - path: /etc/nginx/nginx.conf content: | user nginxuser; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } # Write reverse-proxy configuration file - path: /etc/nginx/sites-available/reverse-proxy.conf content: | # Listen on port 80 server { listen 80; # Set your domain name server_name u1.metaebene.dev; # Redirect all requests to HTTPS return 301 https://$host$request_uri; } # Listen on port 443 with SSL server { listen 443 ssl; # Set your domain name server_name u1.metaebene.dev; # Include SSL certificate managed by Certbot ssl_certificate /etc/letsencrypt/live/u1.metaebene.dev/fullchain.pem; # Include SSL certificate key managed by Certbot ssl_certificate_key /etc/letsencrypt/live/u1.metaebene.dev/privkey.pem; # Include SSL options provided by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # Include DH parameters provided by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Proxy settings for the location location / { # Set backend server address and port proxy_pass http://localhost:8080; # Set Host header proxy_set_header Host $host; # Set X-Real-IP header proxy_set_header X-Real-IP $remote_addr; # Set X-Forwarded-For header proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Set X-Forwarded-Proto header proxy_set_header X-Forwarded-Proto $scheme; } } server { listen 80; # Set your domain name server_name docs.u1.metaebene.dev; # Redirect all requests to HTTPS return 301 https://$host$request_uri; } # Listen on port 443 with SSL server { listen 443 ssl; # Set your domain name server_name docs.u1.metaebene.dev; # Include SSL certificate managed by Certbot ssl_certificate /etc/letsencrypt/live/docs.u1.metaebene.dev/fullchain.pem; # Include SSL certificate key managed by Certbot ssl_certificate_key /etc/letsencrypt/live/docs.u1.metaebene.dev/privkey.pem; # Include SSL options provided by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # Include DH parameters provided by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { root /home/marcus/www/u1/docs/public; index index.html; } } runcmd: # Generate the en_US.UTF-8 locale - locale-gen en_US.UTF-8 # Set the system's default locale to en_US.UTF-8 - update-locale LANG=en_US.UTF-8 # Set the system's timezone to Europe/Berlin - timedatectl set-timezone Europe/Berlin # Run Certbot to obtain SSL certificates and configure Nginx - certbot certonly --nginx -d u1.metaebene.dev --non-interactive --agree-tos --email marcus.kammer@mailbox.org --redirect - certbot certonly --nginx -d docs.u1.metaebene.dev --non-interactive --agree-tos --email marcus.kammer@mailbox.org --redirect # Download DHPARAM - curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/letsencrypt/ssl-dhparam.pem # Create a symlink for the configuration file - ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/ # Remove default Nginx configuration - rm /etc/nginx/sites-enabled/default # Reload Nginx configuration - systemctl reload nginx # Allow Nginx Full (HTTP and HTTPS) through the firewall - ufw allow 'Nginx Full' # Set UFW firewall rules - ufw default deny incoming - ufw default allow outgoing - ufw allow 22/tcp - ufw allow mosh - ufw enable # Enable and start the fail2ban service - systemctl enable fail2ban && systemctl start fail2ban # Restart the SSH server to apply the new configuration - systemctl restart sshd - | sudo -u marcus git config --global user.email "marcus.kammer@mailbox.org" sudo -u marcus git config --global user.name "Marcus Kammer" sudo -u marcus git config --global init.defaultBranch main # Clone the SBCL repository for a specific branch and depth - sudo -u marcus git clone --depth 1 --branch sbcl-2.1.11 git://git.code.sf.net/p/sbcl/sbcl /home/marcus/sbcl # Clone the SLIME repository for a specific branch and depth - sudo -u marcus git clone --depth 1 --branch v2.28 https://github.com/slime/slime.git /home/marcus/slime # Download the Quicklisp installer - | curl https://beta.quicklisp.org/quicklisp.lisp -o /home/marcus/quicklisp.lisp chown marcus:marcus /home/marcus/quicklisp.lisp