| 1 | #!/bin/bash |
| 2 | |
| 3 | # Ubuntu User Setup Script |
| 4 | # Creates user account, sets up SSH keys from GitHub, and optionally grants sudo privileges |
| 5 | # Must be run as root |
| 6 | |
| 7 | set -e # Exit on any error |
| 8 | |
| 9 | # Color codes for output |
| 10 | RED='\033[0;31m' |
| 11 | GREEN='\033[0;32m' |
| 12 | YELLOW='\033[1;33m' |
| 13 | BLUE='\033[0;34m' |
| 14 | NC='\033[0m' # No Color |
| 15 | |
| 16 | # Function to print colored output |
| 17 | print_status() { |
| 18 | echo -e "${GREEN}[INFO]${NC} $1" |
| 19 | } |
| 20 | |
| 21 | print_warning() { |
| 22 | echo -e "${YELLOW}[WARNING]${NC} $1" |
| 23 | } |
| 24 | |
| 25 | print_error() { |
| 26 | echo -e "${RED}[ERROR]${NC} $1" |
| 27 | } |
| 28 | |
| 29 | print_question() { |
| 30 | echo -e "${BLUE}[QUESTION]${NC} $1" |
| 31 | } |
| 32 | |
| 33 | # Check if running as root |
| 34 | if [[ $EUID -ne 0 ]]; then |
| 35 | print_error "This script must be run as root" |
| 36 | exit 1 |
| 37 | fi |
| 38 | |
| 39 | # Check if required tools are available |
| 40 | if ! command -v curl &> /dev/null; then |
| 41 | print_error "curl is required but not installed. Please install it first: apt update && apt install curl" |
| 42 | exit 1 |
| 43 | fi |
| 44 | |
| 45 | print_status "Starting Ubuntu User Setup Script" |
| 46 | echo "==================================" |
| 47 | echo |
| 48 | |
| 49 | # Step 1: Ask for username |
| 50 | while true; do |
| 51 | print_question "Enter the username for the new user account:" |
| 52 | read -r USERNAME |
| 53 | |
| 54 | if [[ -z "$USERNAME" ]]; then |
| 55 | print_warning "Username cannot be empty. Please try again." |
| 56 | continue |
| 57 | fi |
| 58 | |
| 59 | if [[ ! "$USERNAME" =~ ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$ ]]; then |
| 60 | print_warning "Invalid username format. Please use lowercase letters, numbers, hyphens and underscores only." |
| 61 | continue |
| 62 | fi |
| 63 | |
| 64 | break |
| 65 | done |
| 66 | |
| 67 | # Step 2: Create user account if it doesn't exist |
| 68 | if id "$USERNAME" &>/dev/null; then |
| 69 | print_warning "User '$USERNAME' already exists. Skipping user creation." |
| 70 | else |
| 71 | print_status "Creating user account '$USERNAME'..." |
| 72 | useradd -m -s /bin/bash "$USERNAME" |
| 73 | print_status "User '$USERNAME' created successfully with home directory." |
| 74 | fi |
| 75 | |
| 76 | # Get user's home directory |
| 77 | USER_HOME=$(eval echo "~$USERNAME") |
| 78 | |
| 79 | # Step 3: Ask for GitHub username |
| 80 | while true; do |
| 81 | print_question "Enter the GitHub username to fetch SSH keys from:" |
| 82 | read -r GITHUB_USER |
| 83 | |
| 84 | if [[ -z "$GITHUB_USER" ]]; then |
| 85 | print_warning "GitHub username cannot be empty. Please try again." |
| 86 | continue |
| 87 | fi |
| 88 | |
| 89 | # Validate GitHub user exists |
| 90 | print_status "Validating GitHub user '$GITHUB_USER'..." |
| 91 | HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://api.github.com/users/$GITHUB_USER") |
| 92 | |
| 93 | if [[ "$HTTP_STATUS" == "200" ]]; then |
| 94 | print_status "GitHub user '$GITHUB_USER' found." |
| 95 | break |
| 96 | elif [[ "$HTTP_STATUS" == "404" ]]; then |
| 97 | print_warning "GitHub user '$GITHUB_USER' not found. Please check the username and try again." |
| 98 | continue |
| 99 | else |
| 100 | print_warning "Unable to validate GitHub user (HTTP $HTTP_STATUS). Please check your internet connection and try again." |
| 101 | continue |
| 102 | fi |
| 103 | done |
| 104 | |
| 105 | # Step 4: Download and setup SSH keys |
| 106 | print_status "Downloading SSH keys for GitHub user '$GITHUB_USER'..." |
| 107 | |
| 108 | # Create .ssh directory with correct permissions |
| 109 | SSH_DIR="$USER_HOME/.ssh" |
| 110 | mkdir -p "$SSH_DIR" |
| 111 | chmod 700 "$SSH_DIR" |
| 112 | |
| 113 | # Download SSH keys from GitHub |
| 114 | KEYS_URL="https://github.com/$GITHUB_USER.keys" |
| 115 | AUTHORIZED_KEYS_FILE="$SSH_DIR/authorized_keys" |
| 116 | |
| 117 | # Download keys and check if any were found |
| 118 | KEYS_CONTENT=$(curl -s "$KEYS_URL") |
| 119 | |
| 120 | if [[ -z "$KEYS_CONTENT" ]] || [[ "$KEYS_CONTENT" == "Not Found" ]]; then |
| 121 | print_warning "No public SSH keys found for GitHub user '$GITHUB_USER'." |
| 122 | print_warning "The user will need to add SSH keys manually or use password authentication." |
| 123 | # Create empty authorized_keys file |
| 124 | touch "$AUTHORIZED_KEYS_FILE" |
| 125 | else |
| 126 | # Write keys to authorized_keys file (overwrites existing content) |
| 127 | echo "$KEYS_CONTENT" > "$AUTHORIZED_KEYS_FILE" |
| 128 | KEY_COUNT=$(echo "$KEYS_CONTENT" | wc -l) |
| 129 | print_status "Successfully downloaded and installed $KEY_COUNT SSH key(s) for user '$USERNAME'." |
| 130 | fi |
| 131 | |
| 132 | # Set correct permissions for SSH files |
| 133 | chmod 600 "$AUTHORIZED_KEYS_FILE" |
| 134 | chown -R "$USERNAME:$USERNAME" "$SSH_DIR" |
| 135 | |
| 136 | # Step 5: Ask about sudo privileges |
| 137 | echo |
| 138 | while true; do |
| 139 | print_question "Should user '$USERNAME' get sudo privileges? (y/N):" |
| 140 | read -r GRANT_SUDO |
| 141 | |
| 142 | case $GRANT_SUDO in |
| 143 | [Yy]|[Yy][Ee][Ss]) |
| 144 | # Add user to sudo group |
| 145 | print_status "Adding user '$USERNAME' to sudo group..." |
| 146 | usermod -aG sudo "$USERNAME" |
| 147 | |
| 148 | # Create sudoers file |
| 149 | SUDOERS_FILE="/etc/sudoers.d/$USERNAME" |
| 150 | print_status "Creating sudoers configuration file..." |
| 151 | echo "$USERNAME ALL=(ALL:ALL) NOPASSWD: ALL" > "$SUDOERS_FILE" |
| 152 | chmod 440 "$SUDOERS_FILE" |
| 153 | |
| 154 | # Validate sudoers file |
| 155 | if visudo -c -f "$SUDOERS_FILE"; then |
| 156 | print_status "User '$USERNAME' granted sudo privileges with NOPASSWD." |
| 157 | else |
| 158 | print_error "Error in sudoers file configuration. Removing file..." |
| 159 | rm -f "$SUDOERS_FILE" |
| 160 | exit 1 |
| 161 | fi |
| 162 | break |
| 163 | ;; |
| 164 | [Nn]|[Nn][Oo]|"") |
| 165 | print_status "User '$USERNAME' will not have sudo privileges." |
| 166 | break |
| 167 | ;; |
| 168 | *) |
| 169 | print_warning "Please answer 'y' for yes or 'n' for no." |
| 170 | ;; |
| 171 | esac |
| 172 | done |
| 173 | |
| 174 | # Step 6: Summary |
| 175 | echo |
| 176 | print_status "Setup completed successfully!" |
| 177 | echo "==================================" |
| 178 | echo "Summary:" |
| 179 | echo "- User: $USERNAME" |
| 180 | echo "- Home directory: $USER_HOME" |
| 181 | echo "- SSH directory: $SSH_DIR (permissions: 700)" |
| 182 | echo "- SSH keys source: GitHub user '$GITHUB_USER'" |
| 183 | if [[ -n "$KEYS_CONTENT" ]] && [[ "$KEYS_CONTENT" != "Not Found" ]]; then |
| 184 | echo "- SSH keys: $(echo "$KEYS_CONTENT" | wc -l) key(s) installed" |
| 185 | else |
| 186 | echo "- SSH keys: No keys found (manual setup required)" |
| 187 | fi |
| 188 | echo "- Sudo privileges: $(if [[ "$GRANT_SUDO" =~ ^[Yy] ]]; then echo "Yes (NOPASSWD)"; else echo "No"; fi)" |
| 189 | echo |
| 190 | print_status "The user '$USERNAME' can now connect via SSH using their GitHub SSH keys." |
| 191 | |
| 192 | if [[ "$GRANT_SUDO" =~ ^[Yy] ]]; then |
| 193 | print_status "The user has passwordless sudo access." |
| 194 | fi |
| 195 | |
| 196 | echo |
| 197 | print_status "Setup script finished." |
wthiel / Ubuntu User Setup Script
Last active 4 months ago
Creates user account, sets up SSH keys from GitHub, and optionally grants sudo privileges
Revision 8f1bd9751e2512495118be98dcf5021687a71804