Skip to content

Instantly share code, notes, and snippets.

@mrmans0n
Last active January 29, 2026 17:31
Show Gist options
  • Select an option

  • Save mrmans0n/9e36988a2b561353671a0c98daef3ff9 to your computer and use it in GitHub Desktop.

Select an option

Save mrmans0n/9e36988a2b561353671a0c98daef3ff9 to your computer and use it in GitHub Desktop.
Setup GitHub SSH Keys with cache - local or remote installation
#!/bin/bash
#
# Setup GitHub SSH Keys con caché
#
# Uso local:
# sudo ./setup-github-ssh-keys.sh <github_username>
#
# Uso remoto (instala en otro servidor via SSH):
# ./setup-github-ssh-keys.sh <github_username> <user@server>
# ./setup-github-ssh-keys.sh <github_username> <user@server1> <user@server2> ...
#
# Ejemplos:
# sudo ./setup-github-ssh-keys.sh mrmans0n # Local
# ./setup-github-ssh-keys.sh mrmans0n [email protected] # Un servidor
# ./setup-github-ssh-keys.sh mrmans0n root@srv1 nacho@srv2 # Varios servidores
#
set -e
# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
GITHUB_USER="${1:-}"
shift 2>/dev/null || true
SERVERS=("$@")
# Mostrar uso
usage() {
echo "Uso:"
echo " Local: sudo $0 <github_username>"
echo " Remoto: $0 <github_username> <user@server> [user@server2] ..."
echo ""
echo "Ejemplos:"
echo " sudo $0 mrmans0n"
echo " $0 mrmans0n [email protected]"
echo " $0 mrmans0n root@srv1 nacho@srv2 admin@srv3"
exit 1
}
if [ -z "$GITHUB_USER" ]; then
usage
fi
# Verificar que el usuario de GitHub existe y tiene claves
verify_github_user() {
echo -e "${YELLOW}Verificando usuario GitHub: $GITHUB_USER${NC}"
KEYS=$(curl -sf "https://github.com/${GITHUB_USER}.keys" 2>/dev/null || echo "")
if [ -z "$KEYS" ]; then
echo -e "${RED}ERROR: No se encontraron claves para '$GITHUB_USER'${NC}"
echo "Verifica que el usuario existe y tiene claves en GitHub → Settings → SSH and GPG keys"
exit 1
fi
KEY_COUNT=$(echo "$KEYS" | wc -l | tr -d ' ')
echo -e "${GREEN}✓ Encontradas $KEY_COUNT clave(s)${NC}"
}
# Script de instalación que se ejecuta en el servidor
INSTALL_SCRIPT='
#!/bin/bash
set -e
GITHUB_USER="__GITHUB_USER__"
CACHE_DIR="/var/cache/github-ssh-keys"
SCRIPT_PATH="/usr/local/bin/github-ssh-keys"
CACHE_FILE="${CACHE_DIR}/${GITHUB_USER}"
SSHD_CONFIG="/etc/ssh/sshd_config"
echo "=== Instalando GitHub SSH Keys ==="
echo "Usuario: $GITHUB_USER"
# Verificar root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Necesita ejecutarse como root"
exit 1
fi
# Crear directorio de caché
mkdir -p "$CACHE_DIR"
chmod 755 "$CACHE_DIR"
# Obtener claves iniciales
curl -sf "https://github.com/${GITHUB_USER}.keys" > "$CACHE_FILE"
chmod 644 "$CACHE_FILE"
echo "✓ Caché inicial creado"
# Crear script de claves
cat > "$SCRIPT_PATH" << '\''KEYSCRIPT'\''
#!/bin/bash
GITHUB_USER="%%GITHUB_USER%%"
CACHE_DIR="/var/cache/github-ssh-keys"
CACHE_FILE="${CACHE_DIR}/${GITHUB_USER}"
CACHE_TTL=3600
CURL_TIMEOUT=5
mkdir -p "$CACHE_DIR" 2>/dev/null || true
if [ -f "$CACHE_FILE" ]; then
if [[ "$OSTYPE" == "darwin"* ]]; then
CACHE_AGE=$(( $(date +%s) - $(stat -f %m "$CACHE_FILE") ))
else
CACHE_AGE=$(( $(date +%s) - $(stat -c %Y "$CACHE_FILE") ))
fi
else
CACHE_AGE=999999
fi
if [ $CACHE_AGE -gt $CACHE_TTL ]; then
NEW_KEYS=$(curl -sf --max-time $CURL_TIMEOUT "https://github.com/${GITHUB_USER}.keys" 2>/dev/null)
if [ -n "$NEW_KEYS" ]; then
echo "$NEW_KEYS" > "${CACHE_FILE}.tmp" 2>/dev/null && \
mv "${CACHE_FILE}.tmp" "$CACHE_FILE" 2>/dev/null || true
fi
fi
cat "$CACHE_FILE" 2>/dev/null || true
KEYSCRIPT
sed -i.bak "s/%%GITHUB_USER%%/${GITHUB_USER}/" "$SCRIPT_PATH" 2>/dev/null || \
sed -i "" "s/%%GITHUB_USER%%/${GITHUB_USER}/" "$SCRIPT_PATH"
rm -f "${SCRIPT_PATH}.bak"
chmod 755 "$SCRIPT_PATH"
echo "✓ Script creado"
# Backup sshd_config
cp "$SSHD_CONFIG" "${SSHD_CONFIG}.bak.$(date +%Y%m%d%H%M%S)"
# Configurar sshd si no está ya
if ! grep -q "AuthorizedKeysCommand.*github-ssh-keys" "$SSHD_CONFIG"; then
echo "" >> "$SSHD_CONFIG"
echo "# GitHub SSH Keys" >> "$SSHD_CONFIG"
echo "AuthorizedKeysCommand $SCRIPT_PATH" >> "$SSHD_CONFIG"
echo "AuthorizedKeysCommandUser nobody" >> "$SSHD_CONFIG"
echo "✓ sshd configurado"
else
echo "✓ sshd ya configurado"
fi
# Verificar config
if ! sshd -t 2>/dev/null; then
echo "ERROR: Configuración sshd inválida, restaurando..."
cp "${SSHD_CONFIG}.bak."* "$SSHD_CONFIG" 2>/dev/null
exit 1
fi
# Cron para actualizar caché
if [ -d /etc/cron.d ]; then
echo "0 * * * * root $SCRIPT_PATH > /dev/null 2>&1" > /etc/cron.d/github-ssh-keys
chmod 644 /etc/cron.d/github-ssh-keys
echo "✓ Cron configurado"
fi
# Reiniciar sshd
if command -v systemctl &> /dev/null; then
systemctl restart sshd 2>/dev/null || systemctl restart ssh 2>/dev/null || true
elif command -v service &> /dev/null; then
service sshd restart 2>/dev/null || service ssh restart 2>/dev/null || true
else
launchctl unload /System/Library/LaunchDaemons/ssh.plist 2>/dev/null || true
launchctl load /System/Library/LaunchDaemons/ssh.plist 2>/dev/null || true
fi
echo "✓ sshd reiniciado"
echo ""
echo "✅ Instalación completada"
echo " Claves de github.com/${GITHUB_USER} ahora autorizan SSH"
'
# Reemplazar usuario en el script
INSTALL_SCRIPT="${INSTALL_SCRIPT//__GITHUB_USER__/$GITHUB_USER}"
# Función para instalar en un servidor remoto
install_remote() {
local SERVER="$1"
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}Instalando en: $SERVER${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
# Ejecutar script via SSH (forzar TTY para que sudo pueda pedir password)
echo "$INSTALL_SCRIPT" | ssh -tt -o RequestTTY=force -o ConnectTimeout=10 "$SERVER" "sudo bash -s"
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ $SERVER completado${NC}"
else
echo -e "${RED}❌ $SERVER falló${NC}"
fi
}
# Función para instalar localmente
install_local() {
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}ERROR: Para instalación local, ejecuta con sudo${NC}"
echo " sudo $0 $GITHUB_USER"
exit 1
fi
echo ""
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}Instalando localmente${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo "$INSTALL_SCRIPT" | bash -s
}
# Main
verify_github_user
if [ ${#SERVERS[@]} -eq 0 ]; then
# Instalación local
install_local
else
# Instalación remota en uno o más servidores
echo ""
echo -e "${YELLOW}Servidores a configurar: ${#SERVERS[@]}${NC}"
for server in "${SERVERS[@]}"; do
echo " - $server"
done
for server in "${SERVERS[@]}"; do
install_remote "$server"
done
echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}Instalación completada en ${#SERVERS[@]} servidor(es)${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment