Last active
January 29, 2026 17:31
-
-
Save mrmans0n/9e36988a2b561353671a0c98daef3ff9 to your computer and use it in GitHub Desktop.
Setup GitHub SSH Keys with cache - local or remote installation
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
| #!/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