$npx -y skills add adityahimaone/hermes-agent-rtk-caveman --skill git-ssh-custom-hostSet up SSH authentication for custom Git hosts (non-standard ports, custom domains, VPN-dependent hosts) with verification workflow and troubleshooting for common connectivity issues.
| 1 | # SSH Authentication for Custom Git Hosts |
| 2 | |
| 3 | This skill sets up SSH-based authentication for Git hosts that aren't standard GitHub/GitLab.com (e.g., self-hosted GitLab, custom ports, internal domains, VPN-dependent hosts). |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | - Connecting to self-hosted GitLab/Gitea/Gitea instances |
| 8 | - Using non-standard SSH ports (not port 22) |
| 9 | - Hosts accessible only via VPN/internal network |
| 10 | - Custom domain names that require DNS or /etc/hosts configuration |
| 11 | - When standard github-auth skill doesn't apply due to host specificity |
| 12 | |
| 13 | ## Detection Flow |
| 14 | |
| 15 | First, understand what kind of host we're dealing with: |
| 16 | |
| 17 | ```bash |
| 18 | # Get host details from user |
| 19 | echo \"Git host hostname (e.g., dev.fast-8.com):\"\nread GIT_HOST\necho \"Git host port (default 22):\"\nread GIT_PORT\necho \"Git username (usually 'git'):\"\nread GIT_USER |
| 20 | ``` |
| 21 | |
| 22 | If no port specified, default to 22. |
| 23 | If no username specified, default to 'git'. |
| 24 | |
| 25 | ### Port Service Detection (Recommended) |
| 26 | Before configuring, verify what service is running on the target port: |
| 27 | ```bash |
| 28 | # Test if port is reachable |
| 29 | nc -z $GIT_HOST $GIT_PORT && echo \"Port $GIT_PORT reachable\" || echo \"Port $GIT_PORT unreachable\" |
| 30 | |
| 31 | # If reachable, check what service is responding |
| 32 | if nc -z $GIT_HOST $GIT_PORT; then |
| 33 | echo \"Checking service type on port $GIT_PORT...\" |
| 34 | # Make a brief connection to see if it's SSH or HTTP |
| 35 | RESPONSE=$(echo -n \"\" | nc $GIT_HOST $GIT_PORT 2>&1 | head -5) |
| 36 | if echo \"$RESPONSE\" | grep -q \"SSH\" || echo \"$RESPONSE\" | grep -q \"^SSH-\"; then |
| 37 | echo \"✓ Detected SSH service on port $GIT_PORT\" |
| 38 | elif echo \"$RESPONSE\" | grep -q \"HTTP\" || echo \"$RESPONSE\" | grep -q \"<html\" || echo \"$RESPONSE\" | grep -q \"<!DOCTYPE\"; then |
| 39 | echo \"⚠ Detected HTTP service on port $GIT_PORT - this is likely the web UI, not SSH\" |
| 40 | echo \" Try checking if SSH is available on the standard port (22) instead\" |
| 41 | # Suggest checking standard SSH port |
| 42 | nc -z $GIT_HOST 22 && echo \" Port 22 is reachable - SSH might be on standard port\" || echo \" Port 22 also unreachable\" |
| 43 | else |
| 44 | echo \"? Unclear service type on port $GIT_PORT\" |
| 45 | fi |
| 46 | fi |
| 47 | ``` |
| 48 | read GIT_USER |
| 49 | ``` |
| 50 | |
| 51 | If no port specified, default to 22. |
| 52 | If no username specified, default to 'git'. |
| 53 | |
| 54 | ## Step-by-Step Setup |
| 55 | |
| 56 | ### 1. Check for Existing SSH Key |
| 57 | |
| 58 | ```bash |
| 59 | # Check for existing SSH keys |
| 60 | ls -la ~/.ssh/id_*.pub 2>/dev/null || echo "No SSH keys found" |
| 61 | |
| 62 | # If user wants to use existing key, note the path |
| 63 | # If needs new key, generate one: |
| 64 | ssh-keygen -t ed25519 -C "user@domain" -f ~/.ssh/id_custom_git -N "" |
| 65 | ``` |
| 66 | |
| 67 | ### 2. Configure SSH Config for Custom Host |
| 68 | |
| 69 | Create or update `~/.ssh/config` with host-specific settings: |
| 70 | |
| 71 | ```bash |
| 72 | # Backup existing config if needed |
| 73 | cp ~/.ssh/config ~/.ssh/config.backup.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true |
| 74 | |
| 75 | # Add host configuration |
| 76 | cat >> ~/.ssh/config << EOF |
| 77 | |
| 78 | # Custom Git host: $GIT_HOST |
| 79 | Host $GIT_HOST |
| 80 | HostName $GIT_HOST |
| 81 | Port ${GIT_PORT:-22} |
| 82 | User ${GIT_USER:-git} |
| 83 | IdentityFile ~/.ssh/id_custom_git |
| 84 | IdentitiesOnly yes |
| 85 | TCPKeepAlive yes |
| 86 | ServerAliveInterval 30 |
| 87 | ServerAliveCountMax 3 |
| 88 | EOF |
| 89 | |
| 90 | # Set proper permissions |
| 91 | chmod 600 ~/.ssh/config |
| 92 | ``` |
| 93 | |
| 94 | ### 3. Add SSH Key to Agent |
| 95 | |
| 96 | ```bash |
| 97 | # Start ssh-agent if needed |
| 98 | eval "$(ssh-agent -s)" 2>/dev/null || true |
| 99 | |
| 100 | # Add the key |
| 101 | ssh-add ~/.ssh/id_custom_git |
| 102 | |
| 103 | # Verify it's loaded |
| 104 | ssh-add -l | grep id_custom_git |
| 105 | ``` |
| 106 | |
| 107 | ### 4. Test Connectivity |
| 108 | |
| 109 | ```bash |
| 110 | # Test SSH connection to the host |
| 111 | ssh -T $GIT_HOST |
| 112 | |
| 113 | # Expected output varies by host: |
| 114 | # - GitLab: "Welcome to GitLab, @username!" |
| 115 | # - Generic: "PTY allocation request failed on channel 0" (still success if no permission error) |
| 116 | # - Success indicator: exit code 0 or 1 (but not 255 for network issues) |
| 117 | |
| 118 | if [ $? -eq 255 ]; then |
| 119 | echo "SSH connection failed - likely network/host issue" |
| 120 | elif [ $? -eq 1 ]; then |
| 121 | echo "SSH connected but shell access restricted (normal for Git hosts)" |
| 122 | else |
| 123 | echo "SSH connection successful" |
| 124 | fi |
| 125 | ``` |
| 126 | |
| 127 | ## Troubleshooting Common Issues |
| 128 | |
| 129 | ### A. Hostname Resolution Problems |
| 130 | |
| 131 | If you get: `ssh: Could not resolve hostname HOST: nodename nor servname provided, or not known` |
| 132 | |
| 133 | **Solutions:** |
| 134 | 1. **Check VPN connection** - Ensure VPN is active if host is internal |
| 135 | 2. **Test DNS resolution:** |
| 136 | ```bash |
| 137 | dig $GIT_HOST +short |
| 138 | nslookup $GIT_HOST |
| 139 | host $GIT_HOST |
| 140 | ``` |
| 141 | 3. **Temporary /etc/hosts fix** (if you have IP): |
| 142 | ```bash |
| 143 | # Get IP from user or network admin |
| 144 | echo "IP_ADDRESS $GIT_HOST" | sudo tee -a /etc/hosts > /dev/null |
| 145 | ``` |
| 146 | 4. **Check alternative hostname** - Maybe there's an internal DNS name |
| 147 | |
| 148 | ### B. Connection Timeout/ |