136 lines
4.1 KiB
Bash
Executable File
136 lines
4.1 KiB
Bash
Executable File
provision_vps() {
|
|
LABEL="$1"
|
|
REGION="$2"
|
|
TYPE="$3"
|
|
IMAGE="$4"
|
|
ROOT_PASS="${5:-$(openssl rand -base64 16)}"
|
|
|
|
if [[ "$LINODE_API_TOKEN" == "REPLACE_WITH_YOUR_LINODE_API_TOKEN" ]]; then
|
|
echo "❌ Error: You must set your LINODE_API_TOKEN at the top of this script."
|
|
exit 1
|
|
fi
|
|
|
|
CLOUD_INIT=$(cat <<EOF
|
|
#cloud-config
|
|
hostname: genesis-vps
|
|
manage_etc_hosts: true
|
|
write_files:
|
|
- path: /usr/local/bin/genesis_squeaky.sh
|
|
permissions: '0755'
|
|
content: |
|
|
#!/bin/bash
|
|
set -e
|
|
GEN_HOSTNAME="genesis-vps-$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 6)"
|
|
LOGDIR="/home/doc/vpslogs"
|
|
LOGFILE="$LOGDIR/$GEN_HOSTNAME.log"
|
|
IP_ADDR=$(hostname -I | awk '{print $1}')
|
|
|
|
iptables -A OUTPUT -p icmp --icmp-type time-exceeded -j DROP
|
|
iptables -A INPUT -p udp --dport 33434:33534 -j DROP
|
|
iptables -A INPUT -p tcp --dport 33434:33534 -j DROP
|
|
|
|
hostnamectl set-hostname "$GEN_HOSTNAME"
|
|
sed -i "s/^127.0.1.1.*/127.0.1.1 $GEN_HOSTNAME/" /etc/hosts
|
|
|
|
systemctl stop linode-cloudinit 2>/dev/null || true
|
|
systemctl disable linode-cloudinit 2>/dev/null || true
|
|
touch /etc/cloud/cloud-init.disabled
|
|
rm -rf /etc/cloud /var/lib/cloud /var/log/cloud-init.log
|
|
|
|
rm -f /etc/motd /etc/update-motd.d/linode
|
|
rm -rf /usr/share/linode*
|
|
rm -f /etc/apt/sources.list.d/linode.list
|
|
apt remove --purge -y linode-cli linode-config 2>/dev/null || true
|
|
|
|
echo "[genesisctl] Attempting to log to Krang via webhook..." >> /var/log/genesis-harden.log
|
|
curl -s -X POST -H "Content-Type: application/json" \
|
|
-d "{\"host\": \"$GEN_HOSTNAME\", \"ip\": \"$IP_ADDR\", \"timestamp\": \"$(date)\"}" \
|
|
http://krang.core.sshjunkie.com:8080/genesislog >> /var/log/genesis-harden.log 2>&1 || echo "[genesisctl] Krang webhook logging failed" >> /var/log/genesis-harden.log
|
|
|
|
touch /var/log/genesis-hardened.ok
|
|
|
|
runcmd:
|
|
- [ bash, /usr/local/bin/genesis_squeaky.sh ]
|
|
EOF
|
|
)
|
|
|
|
USER_DATA=$(echo "$CLOUD_INIT" | base64 -w 0)
|
|
|
|
echo "Provisioning VPS '$LABEL' in $REGION with type $TYPE and image $IMAGE..."
|
|
TMP_FILE=$(mktemp)
|
|
JSON_PAYLOAD=$(cat <<EOF
|
|
{
|
|
"label": "$LABEL",
|
|
"region": "$REGION",
|
|
"type": "$TYPE",
|
|
"image": "$IMAGE",
|
|
"authorized_users": [],
|
|
"root_pass": "$ROOT_PASS",
|
|
"booted": true,
|
|
"metadata": {
|
|
"user_data": "$USER_DATA"
|
|
}
|
|
}
|
|
EOF
|
|
)
|
|
|
|
HTTP_STATUS=$(curl -s -o "$TMP_FILE" -w "%{http_code}" -X POST https://api.linode.com/v4/linode/instances \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer $LINODE_API_TOKEN" \
|
|
-d "$JSON_PAYLOAD")
|
|
|
|
echo -e "\n--- HTTP STATUS: $HTTP_STATUS ---"
|
|
echo "--- RAW RESPONSE: ---"
|
|
cat "$TMP_FILE"
|
|
|
|
if [[ "$HTTP_STATUS" != "200" && "$HTTP_STATUS" != "201" ]]; then
|
|
echo -e "\n❌ Failed to provision VPS (HTTP $HTTP_STATUS)"
|
|
jq . "$TMP_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "\n✅ VPS provisioned:"
|
|
IP=$(jq -r '.ipv4[0]' "$TMP_FILE")
|
|
LINODE_ID=$(jq -r '.id' "$TMP_FILE")
|
|
echo "Label: $LABEL"
|
|
echo "IP Address: $IP"
|
|
echo "Root Password: $ROOT_PASS"
|
|
|
|
# Add DNS record to Cloudflare
|
|
echo "📡 Adding A record for $LABEL.$CF_DOMAIN → $IP..."
|
|
echo "[DEBUG] CF_API_TOKEN=$CF_API_TOKEN"
|
|
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records" \
|
|
-H "Authorization: Bearer $CF_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data-binary @<(cat <<JSON
|
|
{
|
|
"type": "A",
|
|
"name": "$LABEL.$CF_DOMAIN",
|
|
"content": "$IP",
|
|
"ttl": 120,
|
|
"proxied": false
|
|
}
|
|
JSON
|
|
) | jq '.success, .errors, .messages'
|
|
|
|
echo "⏳ Waiting indefinitely for DNS to propagate before setting rDNS..."
|
|
i=1
|
|
while true; do
|
|
CURRENT_IP=$(dig +short "$LABEL.$CF_DOMAIN")
|
|
if [[ "$CURRENT_IP" == "$IP" ]]; then
|
|
echo "✅ A record resolved. Setting rDNS..."
|
|
curl -s -X PUT "https://api.linode.com/v4/linode/instances/$LINODE_ID/ips/$IP" \
|
|
-H "Authorization: Bearer $LINODE_API_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"rdns": "'"$LABEL.$CF_DOMAIN"'"}'
|
|
break
|
|
fi
|
|
echo "⏳ Attempt $i: DNS not ready. Waiting 15s..."
|
|
sleep 15
|
|
((i++))
|
|
done
|
|
|
|
|
|
echo "$LINODE_ID|$IP|$LABEL" >> /home/doc/vpslogs/pending_rdns.log
|
|
}
|