cloudinit/sbcl-nginx.yml
2023-11-05 14:47:47 +01:00

530 lines
18 KiB
YAML

#cloud-config
# Make sure to check the cloud-init logs: /var/log/cloud-init.log and /var/log/cloud-init-output.log
# Author: Marcus Kammer
# Tested: Ubuntu 22.04
# Copyright © 2023 Marcus Kammer
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the “Software”), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
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 'cl'
- name: cl
# 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
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6xSH5nE0uy0C0kglpp4EqrbbW2CrBeAIj+X6Sf2pd0 XPS-8930-Ubuntu_22
packages:
- detachtty
- fail2ban
- ufw
- unattended-upgrades
- sbcl
- mosh
- tmux
- git
- mercurial
- nginx
- certbot
- python3-certbot-nginx
- libev4
- build-essential
- libzstd-dev
- libsqlite3-dev
- 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 cl
- 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]
# Specify the filter to use (created earlier)
filter = sshd
# 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
[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/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.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
log_format csv '$time_iso8601,$remote_addr,$remote_user,$request,$status,$body_bytes_sent,$http_referer,"$http_user_agent"';
access_log /var/log/nginx/access.csv csv;
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;
##
# Dont send nginx version number
##
server_tokens off;
##
# 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.metalisp.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.metalisp.dev;
# Include SSL certificate managed by Certbot
ssl_certificate /etc/letsencrypt/live/u1.metalisp.dev/fullchain.pem;
# Include SSL certificate key managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/u1.metalisp.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.metalisp.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.metalisp.dev;
# Include SSL certificate managed by Certbot
ssl_certificate /etc/letsencrypt/live/docs.u1.metalisp.dev/fullchain.pem;
# Include SSL certificate key managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/docs.u1.metalisp.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/cl/www/u1/docs/public;
index index.html;
}
}
- path: /home/cl/setup_git.sh
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
#!/bin/bash
git config --global user.email "marcus.kammer@mailbox.org"
git config --global user.name "Marcus Kammer"
git config --global init.defaultBranch main
- path: /home/cl/setup_repos.sh
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
#!/bin/bash
# Clone the SBCL repository for a specific branch and depth.
# Version is equal to the sbcl version available in ubuntu apt-get repo.
git clone --depth 1 --branch sbcl-2.1.11 git://git.code.sf.net/p/sbcl/sbcl /home/cl/sbcl
# Clone the SLIME repository for a specific branch and depth
git clone --depth 1 --branch v2.28 https://github.com/slime/slime.git /home/cl/slime
- path: /home/cl/setup_quicklisp.sh
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
#!/bin/bash
# Needs to be run manually, cant be run automatically.
# If runs automatically, `quicklisp.lisp' cant be find by sbcl.
curl https://beta.quicklisp.org/quicklisp.lisp -o /home/cl/quicklisp.lisp && chown cl:cl /home/cl/quicklisp.lisp
sbcl --load quicklisp.lisp --non-interactive --eval '(quicklisp-quickstart:install)' --quit
curl https://git.sr.ht/~marcuskammer/cloudinit/blob/main/.sbclrc -o /home/cl/.sbclrc && chown cl:cl /home/cl/.sbclrc
sbcl --non-interactive --eval "(ql:quickload '(:hunchentoot :jonathan :spinneret :dexador :rove :vecto :woo :clsql-sqlite3 :mito :bknr.datastore :cl-project))" --quit
- path: /home/cl/block_openai.sh
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
#!/bin/bash
# Purpose: Block OpenAI ChatGPT bot CIDR
# Tested on: Debian and Ubuntu Linux
# Author: Vivek Gite {https://www.cyberciti.biz} under GPL v2.x+
# ------------------------------------------------------------------
file="/tmp/out.txt.$$"
wget -q -O "$file" https://openai.com/gptbot-ranges.txt 2>/dev/null
while IFS= read -r cidr
do
sudo ufw deny proto tcp from $cidr to any port 80
sudo ufw deny proto tcp from $cidr to any port 443
done < "$file"
[ -f "$file" ] && rm -f "$file"
- path: /home/cl/setup_user_all.sh
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
#!/bin/bash
/bin/bash /home/cl/setup_git.sh
/bin/bash /home/cl/setup_repos.sh
ssh-keygen -t ed25519 -C 'u1.metalisp' -f ~/.ssh/id_ed25519 -N ''
mkdir -p ~/www/u1/docs/
- path: /home/cl/.tmux.conf
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
# Improve colors and set TERM correctly inside tmux
set -g default-terminal "screen-256color"
# Set prefix key to Ctrl-a, like GNU Screen
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Enable mouse support
set -g mouse on
# Use Alt-arrow keys to switch panes
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D
# Use Alt+h/j/k/l to resize panes
bind -n M-h resize-pane -L 2
bind -n M-j resize-pane -D 2
bind -n M-k resize-pane -U 2
bind -n M-l resize-pane -R 2
# Split panes with | and -
bind | split-window -h
bind - split-window -v
# Reload tmux config
bind r source-file ~/.tmux.conf
# Quick pane cycling
unbind ^A
bind ^A select-pane -t :.+
# Enable clipboard support on macOS
# Uncomment the line below if you are on macOS and have reattach-to-user-namespace installed
# set-option -g default-command "reattach-to-user-namespace -l $SHELL"
# Set status bar
set -g status-bg black
set -g status-fg white
set -g status-interval 5
set -g status-left "#[fg=green]#H"
set -g status-right "#[fg=yellow]#(date '+%Y-%m-%d %H:%M')"
# Highlight active window in status bar
setw -g window-status-current-style bg=red
# Increase history limit
set -g history-limit 50000
- path: /home/cl/access_logs.sql
owner: 'cl:cl'
defer: True
content: |
-- commands.sql
-- Set the mode to CSV to properly import CSV files
.mode csv
-- If the table doesn't exist, create it
CREATE TABLE IF NOT EXISTS access_logs (
timestamp TEXT,
ip_address TEXT,
remote_user TEXT,
request TEXT,
status_code INTEGER,
body_bytes_sent INTEGER,
http_referer TEXT,
http_user_agent TEXT
);
-- Import the data into the 'access_logs' table
.import '/var/log/nginx/access.csv' access_logs
- path: /home/cl/setup_sbcl.sh
owner: 'cl:cl'
permissions: '0755'
defer: True
content: |
#!/bin/bash
# Exit on error
set -e
# Download SBCL source
wget http://prdownloads.sourceforge.net/sbcl/sbcl-2.3.10-source.tar.bz2
# Extract it
tar -xjf sbcl-2.3.10-source.tar.bz2
# Change into the directory
cd sbcl-2.3.10
# Compile and install
sh make.sh --fancy
sudo sh install.sh
# Check version
sbcl --version
# Remove ubuntu specific sbcl
sudo apt remove sbcl -y
# Remove source packages
rm sbcl-2.3.10-source.tar.bz2 && rm -rf sbcl-2.3.10
runcmd:
# Run Certbot to obtain SSL certificates and configure Nginx
- certbot certonly --nginx -d u1.metalisp.dev --non-interactive --agree-tos --email marcus.kammer@mailbox.org --redirect
- certbot certonly --nginx -d docs.u1.metalisp.dev --non-interactive --agree-tos --email marcus.kammer@mailbox.org --redirect
# Add cron job for automatic certificate renewal (runs once a month)
- echo '0 0 1 * * root certbot renew --post-hook "systemctl reload nginx" >> /var/log/letsencrypt/letsencrypt-auto-renew.log' > /etc/cron.d/letsencrypt-renew
# Download DHPARAM
# The Diffie-Hellman algorithm is used to establish a shared secret between two
# parties (typically a client and a server) over a public channel, and is a
# fundamental part of many cryptographic protocols, including HTTPS.
# However, generating Diffie-Hellman parameters can be computationally expensive,
# so pre-generated parameters are often used. Mozilla provides such pre-generated
# parameters, and they are considered to be trustworthy.
# The downloaded parameters are saved in a file named ssl-dhparam.pem in the
# /etc/letsencrypt directory. This file is then referenced in the configuration
# of services that use Diffie-Hellman key exchange, such as your Nginx server, to
# establish secure communications.
# This step is part of a broader effort to set up SSL/TLS securely on your
# server, enhancing the security of your connections.
- 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
- |
#!/bin/bash
# Purpose: Block OpenAI ChatGPT bot CIDR
# Tested on: Debian and Ubuntu Linux
# Author: Vivek Gite {https://www.cyberciti.biz} under GPL v2.x+
# ------------------------------------------------------------------
file="/tmp/out.txt.$$"
wget -q -O "$file" https://openai.com/gptbot-ranges.txt 2>/dev/null
while IFS= read -r cidr
do
sudo ufw deny proto tcp from $cidr to any port 80
sudo ufw deny proto tcp from $cidr to any port 443
done < "$file"
[ -f "$file" ] && rm -f "$file"
# 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 cl /bin/bash /home/cl/setup_user_all.sh