/cj-cloud-init.yml Secret
Last active
December 28, 2025 14:23
-
Star
(127)
You must be signed in to star a gist -
Fork
(111)
You must be signed in to fork a gist
-
-
Save w3cj/cdd447b1a10ce741e4ee968fa6b75553 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This config was written for Ubuntu 22.04 | |
| # If you are using a more recent version, see the comments of this gist for fixes | |
| #cloud-config | |
| users: | |
| - name: cj | |
| ssh_authorized_keys: | |
| - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBlfqermlV44zAU+iTCa5im5O0QWXid6sHqh2Z4L1Cm cj@null.computer" | |
| sudo: ALL=(ALL:ALL) ALL | |
| groups: sudo | |
| shell: /bin/bash | |
| chpasswd: | |
| expire: true | |
| users: | |
| - name: cj | |
| password: changeme | |
| type: text | |
| runcmd: | |
| - sed -i '/PermitRootLogin/d' /etc/ssh/sshd_config | |
| - echo "PermitRootLogin without-password" >> /etc/ssh/sshd_config | |
| - sed -i '/PubkeyAuthentication/d' /etc/ssh/sshd_config | |
| - echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config | |
| - sed -i '/PasswordAuthentication/d' /etc/ssh/sshd_config | |
| - echo "PasswordAuthentication no" >> /etc/ssh/sshd_config | |
| - systemctl restart sshd | |
| - echo "\$nrconf{kernelhints} = -1;" > /etc/needrestart/conf.d/99disable-prompt.conf | |
| - apt update | |
| - apt upgrade -y --allow-downgrades --allow-remove-essential --allow-change-held-packages | |
| - reboot |
@vlad1mirJ on Hetzner Ubuntu 24.04, if you add ssh key, root user don't have a password, so we don't need that extra config I think
I created this script with the help of AI
This script hardens and automates your server setup in 3 quick steps:
- Hardens Access: Creates a new user, moves SSH to new port, and bans passwords/root login (keys only).
- Locks Firewall: Blocks all traffic except your SSH port and Cloudflare IPs (hides your server from the public).
- Deploys Coolify: Installs the app, injects automation keys, and patches the database to use your custom settings.
I am also using Cloudflare DNS and origin certificates by following this video: https://www.youtube.com/watch?v=HZFNt-Grw0U
Note: I am not an expert in Linux and self-hosting, please guide me if I am doing anything wrong, I will correct it.
#!/bin/bash
set -e
# ================= CONFIG =================
REMOTE_IP="23.92.65.231"
USERNAME="tolres2"
NEW_SSH_PORT="2311"
LOCAL_KEY_DIR="$HOME/Documents/coolify-new-imp/$USERNAME"
# =========================================
mkdir -p "$LOCAL_KEY_DIR"
# Generate Keys
[ ! -f "$LOCAL_KEY_DIR/id_ed25519_personal" ] && ssh-keygen -t ed25519 -f "$LOCAL_KEY_DIR/id_ed25519_personal" -N "" -C "$USERNAME-personal"
[ ! -f "$LOCAL_KEY_DIR/id_ed25519_coolify" ] && ssh-keygen -t ed25519 -f "$LOCAL_KEY_DIR/id_ed25519_coolify" -N "" -C "coolify-automation"
PERSONAL_PUB=$(cat "$LOCAL_KEY_DIR/id_ed25519_personal.pub")
COOLIFY_PUB=$(cat "$LOCAL_KEY_DIR/id_ed25519_coolify.pub")
COOLIFY_PRIV_DATA=$(cat "$LOCAL_KEY_DIR/id_ed25519_coolify")
echo "π Starting Deployment on $REMOTE_IP..."
ssh root@$REMOTE_IP "PERSONAL_PUB='$PERSONAL_PUB' COOLIFY_PUB='$COOLIFY_PUB' COOLIFY_PRIV='$COOLIFY_PRIV_DATA' USERNAME='$USERNAME' NEW_SSH_PORT='$NEW_SSH_PORT'" 'bash -s' <<'EOF'
set -e
# 1. USER SETUP
if ! id -u "$USERNAME" >/dev/null 2>&1; then useradd -m -s /bin/bash "$USERNAME"; fi
usermod -aG sudo "$USERNAME"
echo "$USERNAME ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USERNAME
mkdir -p /home/$USERNAME/.ssh
echo "$PERSONAL_PUB" > /home/$USERNAME/.ssh/authorized_keys
echo "$COOLIFY_PUB" >> /home/$USERNAME/.ssh/authorized_keys
chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh
chmod 700 /home/$USERNAME/.ssh
chmod 600 /home/$USERNAME/.ssh/authorized_keys
# 2. SSH HARDENING (Clean & Safe)
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Remove any existing Port or AllowUsers lines to prevent duplicates
sed -i "/^Port /d" /etc/ssh/sshd_config
sed -i "/^AllowUsers /d" /etc/ssh/sshd_config
sed -i "/^PermitRootLogin /d" /etc/ssh/sshd_config
echo "Port $NEW_SSH_PORT" >> /etc/ssh/sshd_config
echo "AllowUsers $USERNAME" >> /etc/ssh/sshd_config
echo "PermitRootLogin no" >> /etc/ssh/sshd_config
echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
# 3. FIREWALL (Including Cloudflare)
apt-get update && apt-get install -y ufw curl
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow $NEW_SSH_PORT/tcp
ufw allow 22/tcp # EMERGENCY BACKUP PORT - Close this manually later!
ufw allow from 172.17.0.0/16 to any # Allow Docker Bridge
echo "Adding Cloudflare IPs..."
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do ufw allow from "$ip" to any port 80,443 proto tcp; done
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do ufw allow from "$ip" to any port 80,443 proto tcp; done
ufw --force enable
# 4. INSTALL COOLIFY
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
# 5. RESTART SSH
sshd -t
systemctl restart ssh
# -------- 6. FIX PERMISSIONS & KEY INJECTION --------
echo "π§ Applying final permission fixes..."
# 1. Add your user to the root group FIRST
# This ensures that once we set '750' (Group access), you are already in that group.
usermod -aG root "$USERNAME"
# 2. Set the internal Coolify user (9999) as the owner
# and 'root' as the group for the entire directory.
chown -R 9999:root /data/coolify
# 3. Create/Verify the SSH directory
mkdir -p /data/coolify/ssh/keys
# 4. Inject the Automation Key
echo "$COOLIFY_PRIV" > /data/coolify/ssh/keys/id.root@host.docker.internal
# 5. Apply the 750 Permission (Owner: Full, Group: Enter/Read, Others: None)
# This allows you (as part of the root group) to 'cd' into these folders.
chmod 750 /data/coolify
chmod 750 /data/coolify/ssh
chmod 750 /data/coolify/proxy
# 6. Critical Security: Keep the private key locked to the owner only
chmod 600 /data/coolify/ssh/keys/id.root@host.docker.internal
chown 9999:9999 /data/coolify/ssh/keys/id.root@host.docker.internal
echo "β
Permissions updated. Group 'root' now has access to /data/coolify."
# 7. DATABASE PATCH (WAITING FOR DB)
echo "β³ Patching Coolify DB (User: $USERNAME, Port: $NEW_SSH_PORT)..."
for i in {1..60}; do
DB=$(docker ps --filter name=coolify-db --format "{{.Names}}")
if [ -n "$DB" ] && docker exec $DB pg_isready -U coolify >/dev/null 2>&1; then
docker exec $DB psql -U coolify -d coolify -c "UPDATE servers SET \"user\"='$USERNAME', port=$NEW_SSH_PORT WHERE name='localhost';"
echo "β
DB Patched."
break
fi
[ $i -eq 60 ] && echo "β DB Patch timed out. You must update the server settings in Coolify UI."
sleep 5
done
EOF
echo "-------------------------------------------------------"
echo "β
SETUP FINISHED"
echo "1. Attempt login: ssh -p $NEW_SSH_PORT $USERNAME@$REMOTE_IP -i $LOCAL_KEY_DIR/id_ed25519_personal"
echo "2. If successful, run 'sudo ufw delete allow 22/tcp' on the server."
echo "-------------------------------------------------------"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@vlad1mirJ your solution worked like a charm for me (Ubuntu 24.04). Thanks!