feat: convert to shell script and improve documentation
This commit is contained in:
parent
96a5720497
commit
0ecdeadfd5
5 changed files with 527 additions and 238 deletions
330
forgejo-ssh-key-setup.sh
Normal file
330
forgejo-ssh-key-setup.sh
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
GRAY='\033[0;90m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to validate email format
|
||||
validate_email() {
|
||||
echo "$1" | grep -E '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' >/dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
# Function to validate token format
|
||||
validate_token() {
|
||||
echo "$1" | grep -E '^[a-fA-F0-9]{64}$' >/dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
# Function to validate Forgejo URL format
|
||||
validate_forgejo_url() {
|
||||
echo "$1" | grep -E '^https?://[a-zA-Z0-9.-]+(:[0-9]+)?$|^[a-zA-Z0-9.-]+(:[0-9]+)?$' >/dev/null
|
||||
return $?
|
||||
}
|
||||
|
||||
# Function to generate signature
|
||||
generate_signature() {
|
||||
local token="$1"
|
||||
local private_key_path="$2"
|
||||
|
||||
# Validate parameters
|
||||
if [ ! -f "$private_key_path" ]; then
|
||||
echo -e "${RED}Error: Private key not found at path: $private_key_path${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Normalize token format
|
||||
token=$(echo "$token" | tr '[:upper:]' '[:lower:]' | tr -d ' ')
|
||||
|
||||
# Debug: Check token format
|
||||
echo -e "\n${GRAY}Debug: Token format check:${NC}"
|
||||
echo -e "${GRAY}Length: ${#token}${NC}"
|
||||
echo -e "${GRAY}Format: $(echo "$token" | grep -E '^[a-f0-9]{64}$' >/dev/null && echo "valid" || echo "invalid")${NC}"
|
||||
|
||||
# Generate signature
|
||||
echo -e "\n${GRAY}Generating signature...${NC}"
|
||||
signature=$(echo -n "$token" | ssh-keygen -Y sign -n gitea -f "$private_key_path" 2>&1)
|
||||
|
||||
# Debug: Check raw output
|
||||
echo -e "\n${GRAY}Debug: Raw signature output:${NC}"
|
||||
echo "$signature" | while IFS= read -r line; do
|
||||
echo -e "${GRAY} $line${NC}"
|
||||
done
|
||||
|
||||
# Filter the output to get only the signature block
|
||||
signature=$(echo "$signature" | grep -E '^(-----BEGIN SSH SIGNATURE-----|-----END SSH SIGNATURE-----|[A-Za-z0-9+/=]+)$')
|
||||
|
||||
# Debug: Check filtered signature
|
||||
echo -e "\n${GRAY}Debug: Filtered signature:${NC}"
|
||||
echo "$signature" | while IFS= read -r line; do
|
||||
echo -e "${GRAY} $line${NC}"
|
||||
done
|
||||
|
||||
# Verify signature format
|
||||
if ! echo "$signature" | grep -q '^-----BEGIN SSH SIGNATURE-----' || \
|
||||
! echo "$signature" | grep -q '-----END SSH SIGNATURE-----' || \
|
||||
! echo "$signature" | grep -E '^-----BEGIN SSH SIGNATURE-----\r?\n[A-Za-z0-9+/=]+\r?\n-----END SSH SIGNATURE-----\r?$' >/dev/null; then
|
||||
echo -e "${YELLOW}Warning: Signature format may be incorrect or incomplete.${NC}"
|
||||
fi
|
||||
|
||||
echo "$signature"
|
||||
}
|
||||
|
||||
# --- Get Forgejo Location ---
|
||||
forgejo_location=""
|
||||
while ! validate_forgejo_url "$forgejo_location"; do
|
||||
echo -e "\n${CYAN}Please enter your Forgejo location (e.g., forgejo.example.com or 192.168.1.100:3000)${NC}"
|
||||
read -r forgejo_location
|
||||
if ! validate_forgejo_url "$forgejo_location"; then
|
||||
echo -e "${RED}Invalid format. Please enter a valid URL or IP address.${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove http:// or https:// if present
|
||||
forgejo_location=$(echo "$forgejo_location" | sed -E 's|^https?://||')
|
||||
|
||||
# --- SSH Key Generation ---
|
||||
|
||||
# Get user's email for key comment
|
||||
email=""
|
||||
while ! validate_email "$email"; do
|
||||
echo -e "\n${CYAN}Please enter your email address for your SSH key comment (e.g., user@example.com)${NC}"
|
||||
read -r email
|
||||
if ! validate_email "$email"; then
|
||||
echo -e "${RED}Invalid email format. Please try again.${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Generate SSH key
|
||||
echo -e "\n${CYAN}--- Generating SSH Key ---${NC}"
|
||||
echo -e "${YELLOW}You'll be prompted for a passphrase. Please remember it and keep it safe!${NC}"
|
||||
|
||||
private_key_path="$HOME/.ssh/id_ed25519"
|
||||
public_key_path="$HOME/.ssh/id_ed25519.pub"
|
||||
|
||||
# Check if key already exists
|
||||
if [ -f "$private_key_path" ]; then
|
||||
echo -e "\n${YELLOW}Warning: An SSH key already exists at '$private_key_path'.${NC}"
|
||||
echo -e "${YELLOW}Do you want to overwrite it? (y/N)${NC}"
|
||||
read -r overwrite
|
||||
if [ "$overwrite" != "y" ] && [ "$overwrite" != "Y" ]; then
|
||||
echo -e "${RED}Key generation cancelled. Exiting.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Execute ssh-keygen
|
||||
ssh-keygen -t ed25519 -C "$email" -f "$private_key_path"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Error generating SSH key. Please check your SSH installation.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add key to SSH agent
|
||||
echo -e "\n${YELLOW}--- Adding Key to SSH Agent ---${NC}"
|
||||
echo -e "${YELLOW}This avoids re-entering your passphrase. You might be prompted for your passphrase now.${NC}"
|
||||
ssh-add "$private_key_path"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Failed to add key to SSH agent. You may need to start the SSH agent manually.${NC}"
|
||||
echo -e "${YELLOW}To start the agent manually, run: eval \$(ssh-agent -s)${NC}"
|
||||
fi
|
||||
|
||||
# Display the public key
|
||||
echo -e "\n${GREEN}--- Your Public Key ---${NC}"
|
||||
echo -e "${GREEN}Please copy the FOLLOWING ENTIRE KEY and paste it into Forgejo:${NC}"
|
||||
cat "$public_key_path"
|
||||
echo -e "${GREEN}---------------------------${NC}"
|
||||
|
||||
# --- Forgejo Web Server Instructions ---
|
||||
echo -e "\n${CYAN}--- Next Steps (Manual on Forgejo Web Server) ---${NC}"
|
||||
echo "1. Login to your Forgejo web server (e.g., https://$forgejo_location)"
|
||||
echo "2. Click on your profile avatar (top right corner)"
|
||||
echo "3. Select 'Settings'"
|
||||
echo "4. In the left sidebar, click on 'SSH / GPG Keys'"
|
||||
echo "5. Click the 'Add Key' button"
|
||||
echo "6. Give your key a descriptive 'Title' (e.g., 'My Laptop Key')"
|
||||
echo "7. PASTE the public key shown ABOVE into the 'Content' text area"
|
||||
echo "8. Click 'Add Key'."
|
||||
echo "9. After adding, click the 'Verify' button next to your new key."
|
||||
echo "10. Copy the challenge token (the long hexadecimal string) provided by Forgejo."
|
||||
|
||||
# --- Key Verification ---
|
||||
verification_passed=false
|
||||
max_attempts=3
|
||||
attempts=0
|
||||
|
||||
while [ "$verification_passed" = false ] && [ $attempts -lt $max_attempts ]; do
|
||||
attempts=$((attempts + 1))
|
||||
|
||||
# Get and validate the token
|
||||
token=""
|
||||
while ! validate_token "$token"; do
|
||||
echo -e "\n${YELLOW}--- Key Verification (Attempt $attempts of $max_attempts) ---${NC}"
|
||||
echo -e "${YELLOW}Please get a fresh token from Forgejo (tokens expire after a few minutes)${NC}"
|
||||
read -r token
|
||||
if ! validate_token "$token"; then
|
||||
echo -e "${RED}Invalid token format. Token should be 64 hexadecimal characters.${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify the token
|
||||
echo -e "\n${YELLOW}Verifying key with Forgejo...${NC}"
|
||||
echo -e "${YELLOW}Running verification command using private key: $private_key_path${NC}"
|
||||
echo -e "${YELLOW}--------------------------------------------------------${NC}"
|
||||
|
||||
# Generate signature
|
||||
verification_output=$(generate_signature "$token" "$private_key_path")
|
||||
|
||||
echo -e "\n${GREEN}--- Copy and Paste the Signature ---${NC}"
|
||||
echo -e "${GREEN}Please copy the FOLLOWING ENTIRE BLOCK (including BEGIN and END lines) and paste it back into the Forgejo web verification box:${NC}"
|
||||
echo ""
|
||||
echo "$verification_output"
|
||||
echo ""
|
||||
echo -e "${GREEN}------------------------------------${NC}"
|
||||
|
||||
echo -e "\n${CYAN}--- Final Steps (Manual on Forgejo Web Server) ---${NC}"
|
||||
echo "11. Paste the signature above into the verification box in Forgejo."
|
||||
echo "12. Click 'Verify'. You should see 'Successfully verified'."
|
||||
echo "13. Once verified, you can now test your SSH connection to Forgejo."
|
||||
|
||||
# Check verification status
|
||||
echo -e "\n${YELLOW}--- Verification Status Check ---${NC}"
|
||||
echo -e "${YELLOW}Did the verification pass in the Forgejo web interface? (y/N)${NC}"
|
||||
read -r verification_status
|
||||
if [ "$verification_status" = "y" ] || [ "$verification_status" = "Y" ]; then
|
||||
verification_passed=true
|
||||
else
|
||||
echo -e "\n${RED}Verification failed. Here are some troubleshooting steps:${NC}"
|
||||
echo -e "${YELLOW}1. Make sure you copied the ENTIRE signature block, including BEGIN and END lines${NC}"
|
||||
echo -e "${YELLOW}2. Check that there are no extra spaces or line breaks in the signature${NC}"
|
||||
echo -e "${YELLOW}3. Verify that the token was entered correctly${NC}"
|
||||
echo -e "${YELLOW}4. The token may have expired - get a fresh token from Forgejo${NC}"
|
||||
echo -e "${YELLOW}5. Try again with a new token${NC}"
|
||||
|
||||
if [ $attempts -lt $max_attempts ]; then
|
||||
echo -e "\n${YELLOW}Let's try again with a new token...${NC}"
|
||||
else
|
||||
echo -e "\n${RED}Maximum verification attempts reached. Please check your key and try again later.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# --- SSH Config Setup ---
|
||||
echo -e "\n${YELLOW}--- SSH Config Setup (Optional) ---${NC}"
|
||||
echo -e "${YELLOW}Would you like to set up your SSH config for easier connections? (y/N)${NC}"
|
||||
read -r setup_config
|
||||
if [ "$setup_config" = "y" ] || [ "$setup_config" = "Y" ]; then
|
||||
echo -e "${YELLOW}Enter your Forgejo username:${NC}"
|
||||
read -r forgejo_user
|
||||
|
||||
ssh_config_path="$HOME/.ssh/config"
|
||||
ssh_private_key_path="$private_key_path"
|
||||
|
||||
# Create config content
|
||||
config_content="# Forgejo Configuration
|
||||
Host $forgejo_location
|
||||
HostName $forgejo_location
|
||||
User $forgejo_user
|
||||
IdentityFile $ssh_private_key_path
|
||||
PreferredAuthentications publickey
|
||||
PubkeyAuthentication yes
|
||||
PasswordAuthentication no
|
||||
"
|
||||
|
||||
# Create .ssh directory if it doesn't exist
|
||||
mkdir -p "$HOME/.ssh"
|
||||
|
||||
# Read existing config
|
||||
if [ -f "$ssh_config_path" ]; then
|
||||
existing_config=$(cat "$ssh_config_path")
|
||||
else
|
||||
existing_config=""
|
||||
fi
|
||||
|
||||
# Remove existing block for this host using sed
|
||||
updated_config=$(echo "$existing_config" | sed -E "/^Host[[:space:]]+$forgejo_location[[:space:]]*$/,/^[^[:space:]]/d")
|
||||
|
||||
# Append new config
|
||||
updated_config="$updated_config
|
||||
$config_content"
|
||||
|
||||
# Write updated config
|
||||
echo "$updated_config" > "$ssh_config_path"
|
||||
|
||||
echo -e "\n${GREEN}SSH config has been updated. You can now connect using:${NC}"
|
||||
echo -e "${CYAN}ssh $forgejo_location${NC}"
|
||||
echo -e "\n${YELLOW}Your SSH config is located at: $ssh_config_path${NC}"
|
||||
|
||||
# Wait a moment for the key to be fully processed
|
||||
echo -e "\n${YELLOW}Waiting a moment for the key to be fully processed...${NC}"
|
||||
sleep 5
|
||||
|
||||
# Test the connection
|
||||
echo -e "\n${YELLOW}--- Testing SSH Connection ---${NC}"
|
||||
echo -e "${YELLOW}Testing connection to $forgejo_location with verbose output...${NC}"
|
||||
test_output=$(ssh -v -T "$forgejo_location" 2>&1)
|
||||
ssh_exit_code=$?
|
||||
|
||||
if [ "$ssh_exit_code" -eq 1 ]; then
|
||||
# Exit code 1 typically means success for ssh -T without remote command
|
||||
echo -e "${GREEN}Connection successful! You can now use Git with your Forgejo repository.${NC}"
|
||||
elif [ "$ssh_exit_code" -eq 0 ]; then
|
||||
# This can happen if ssh does run an implicit command or due to specific server configs
|
||||
echo -e "${YELLOW}Warning: SSH command returned exit code 0. This might indicate a successful connection, but verify manually if expected.${NC}"
|
||||
echo -e "${GREEN}Connection successful! You can now use Git with your Forgejo repository.${NC}"
|
||||
else
|
||||
echo -e "${RED}Connection test failed. Here are some troubleshooting steps:${NC}"
|
||||
# Display the verbose output of the failed ssh command
|
||||
echo "$test_output" | while IFS= read -r line; do echo -e "${RED} $line${NC}"; done
|
||||
echo -e "${YELLOW}1. Verify that your SSH key is properly added to your Forgejo account:${NC}"
|
||||
echo -e "${YELLOW} - Check that the key appears in your SSH keys list${NC}"
|
||||
echo -e "${YELLOW} - Verify that the key fingerprint matches: $(ssh-keygen -lf "$public_key_path" | cut -d' ' -f2)${NC}"
|
||||
echo -e "${YELLOW}2. Check your SSH config:${NC}"
|
||||
echo -e "${YELLOW} - Verify the hostname is correct: $forgejo_location${NC}"
|
||||
echo -e "${YELLOW} - Verify the username is correct: $forgejo_user${NC}"
|
||||
echo -e "${YELLOW} - Check that the key path is correct: $ssh_private_key_path${NC}"
|
||||
echo -e "${YELLOW}3. Try connecting manually with verbose output:${NC}"
|
||||
echo -e "${CYAN} ssh -v -T $forgejo_user@$forgejo_location${NC}"
|
||||
echo -e "${YELLOW}Note: SSH returned exit code $ssh_exit_code.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# If user didn't set up SSH config, still offer to test connection
|
||||
echo -e "\n${YELLOW}--- Testing SSH Connection ---${NC}"
|
||||
echo -e "${YELLOW}Would you like to test your SSH connection now? (y/N)${NC}"
|
||||
read -r test_connection
|
||||
if [ "$test_connection" = "y" ] || [ "$test_connection" = "Y" ]; then
|
||||
echo -e "${YELLOW}Enter your Forgejo username:${NC}"
|
||||
read -r forgejo_user
|
||||
echo -e "\n${YELLOW}Testing connection to $forgejo_user@$forgejo_location with verbose output...${NC}"
|
||||
test_output=$(ssh -v -T "$forgejo_user@$forgejo_location" 2>&1)
|
||||
ssh_exit_code=$?
|
||||
|
||||
if [ "$ssh_exit_code" -eq 1 ]; then
|
||||
echo -e "${GREEN}Connection successful! You can now use Git with your Forgejo repository.${NC}"
|
||||
elif [ "$ssh_exit_code" -eq 0 ]; then
|
||||
echo -e "${YELLOW}Warning: SSH command returned exit code 0. This might indicate a successful connection, but verify manually if expected.${NC}"
|
||||
echo -e "${GREEN}Connection successful! You can now use Git with your Forgejo repository.${NC}"
|
||||
else
|
||||
echo -e "${RED}Connection test failed. Here are some troubleshooting steps:${NC}"
|
||||
# Display the verbose output of the failed ssh command
|
||||
echo "$test_output" | while IFS= read -r line; do echo -e "${RED} $line${NC}"; done
|
||||
echo -e "${YELLOW}1. Verify that your SSH key is properly added to your Forgejo account:${NC}"
|
||||
echo -e "${YELLOW} - Check that the key appears in your SSH keys list${NC}"
|
||||
echo -e "${YELLOW} - Verify that the key fingerprint matches: $(ssh-keygen -lf "$public_key_path" | cut -d' ' -f2)${NC}"
|
||||
echo -e "${YELLOW}2. Try connecting manually with verbose output:${NC}"
|
||||
echo -e "${CYAN} ssh -v -T $forgejo_user@$forgejo_location${NC}"
|
||||
echo -e "${YELLOW}Note: SSH returned exit code $ssh_exit_code.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "\n${GREEN}Process for SSH key setup and verification completed!${NC}"
|
||||
Loading…
Add table
Add a link
Reference in a new issue