Installation
wget -qO- https://opengist.internal.willithiel.net/wthiel/1c1459c3dd7c45a59f6f2b97016d73b3/raw/HEAD/create_user.sh | bash
Last active 4 months ago
Creates user account, sets up SSH keys from GitHub, and optionally grants sudo privileges
wget -qO- https://opengist.internal.willithiel.net/wthiel/1c1459c3dd7c45a59f6f2b97016d73b3/raw/HEAD/create_user.sh | bash
| 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 < /dev/tty |
| 53 | |
| 54 | echo "DEBUG: Received input: '$USERNAME'" >&2 |
| 55 | |
| 56 | if [[ -z "$USERNAME" ]]; then |
| 57 | print_warning "Username cannot be empty. Please try again." |
| 58 | continue |
| 59 | fi |
| 60 | |
| 61 | if [[ ! "$USERNAME" =~ ^[a-z_][a-z0-9_-]*$ ]]; then |
| 62 | print_warning "Invalid username format. Please use lowercase letters, numbers, hyphens and underscores only." |
| 63 | continue |
| 64 | fi |
| 65 | |
| 66 | break |
| 67 | done |
| 68 | |
| 69 | # Step 2: Create user account if it doesn't exist |
| 70 | if id "$USERNAME" &>/dev/null; then |
| 71 | print_warning "User '$USERNAME' already exists. Skipping user creation." |
| 72 | else |
| 73 | print_status "Creating user account '$USERNAME'..." |
| 74 | useradd -m -s /bin/bash "$USERNAME" |
| 75 | print_status "User '$USERNAME' created successfully with home directory." |
| 76 | fi |
| 77 | |
| 78 | # Get user's home directory |
| 79 | USER_HOME=$(eval echo "~$USERNAME") |
| 80 | |
| 81 | # Step 3: Ask for GitHub username |
| 82 | while true; do |
| 83 | print_question "Enter the GitHub username to fetch SSH keys from:" |
| 84 | read -r GITHUB_USER < /dev/tty |
| 85 | |
| 86 | if [[ -z "$GITHUB_USER" ]]; then |
| 87 | print_warning "GitHub username cannot be empty. Please try again." |
| 88 | continue |
| 89 | fi |
| 90 | |
| 91 | # Validate GitHub user exists |
| 92 | print_status "Validating GitHub user '$GITHUB_USER'..." |
| 93 | HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://api.github.com/users/$GITHUB_USER") |
| 94 | |
| 95 | if [[ "$HTTP_STATUS" == "200" ]]; then |
| 96 | print_status "GitHub user '$GITHUB_USER' found." |
| 97 | break |
| 98 | elif [[ "$HTTP_STATUS" == "404" ]]; then |
| 99 | print_warning "GitHub user '$GITHUB_USER' not found. Please check the username and try again." |
| 100 | continue |
| 101 | else |
| 102 | print_warning "Unable to validate GitHub user (HTTP $HTTP_STATUS). Please check your internet connection and try again." |
| 103 | continue |
| 104 | fi |
| 105 | done |
| 106 | |
| 107 | # Step 4: Download and setup SSH keys |
| 108 | print_status "Downloading SSH keys for GitHub user '$GITHUB_USER'..." |
| 109 | |
| 110 | # Create .ssh directory with correct permissions |
| 111 | SSH_DIR="$USER_HOME/.ssh" |
| 112 | mkdir -p "$SSH_DIR" |
| 113 | chmod 700 "$SSH_DIR" |
| 114 | |
| 115 | # Download SSH keys from GitHub |
| 116 | KEYS_URL="https://github.com/$GITHUB_USER.keys" |
| 117 | AUTHORIZED_KEYS_FILE="$SSH_DIR/authorized_keys" |
| 118 | |
| 119 | # Download keys and check if any were found |
| 120 | KEYS_CONTENT=$(curl -s "$KEYS_URL") |
| 121 | |
| 122 | if [[ -z "$KEYS_CONTENT" ]] || [[ "$KEYS_CONTENT" == "Not Found" ]]; then |
| 123 | print_warning "No public SSH keys found for GitHub user '$GITHUB_USER'." |
| 124 | print_warning "The user will need to add SSH keys manually or use password authentication." |
| 125 | # Create empty authorized_keys file |
| 126 | touch "$AUTHORIZED_KEYS_FILE" |
| 127 | else |
| 128 | # Write keys to authorized_keys file (overwrites existing content) |
| 129 | echo "$KEYS_CONTENT" > "$AUTHORIZED_KEYS_FILE" |
| 130 | KEY_COUNT=$(echo "$KEYS_CONTENT" | wc -l) |
| 131 | print_status "Successfully downloaded and installed $KEY_COUNT SSH key(s) for user '$USERNAME'." |
| 132 | fi |
| 133 | |
| 134 | # Set correct permissions for SSH files |
| 135 | chmod 600 "$AUTHORIZED_KEYS_FILE" |
| 136 | chown -R "$USERNAME:$USERNAME" "$SSH_DIR" |
| 137 | |
| 138 | # Step 5: Ask about sudo privileges |
| 139 | echo |
| 140 | while true; do |
| 141 | print_question "Should user '$USERNAME' get sudo privileges? (y/N):" |
| 142 | read -r GRANT_SUDO < /dev/tty |
| 143 | |
| 144 | case $GRANT_SUDO in |
| 145 | [Yy]|[Yy][Ee][Ss]) |
| 146 | # Add user to sudo group |
| 147 | print_status "Adding user '$USERNAME' to sudo group..." |
| 148 | usermod -aG sudo "$USERNAME" |
| 149 | |
| 150 | # Create sudoers file |
| 151 | SUDOERS_FILE="/etc/sudoers.d/$USERNAME" |
| 152 | print_status "Creating sudoers configuration file..." |
| 153 | echo "$USERNAME ALL=(ALL:ALL) NOPASSWD: ALL" > "$SUDOERS_FILE" |
| 154 | chmod 440 "$SUDOERS_FILE" |
| 155 | |
| 156 | # Validate sudoers file |
| 157 | if visudo -c -f "$SUDOERS_FILE"; then |
| 158 | print_status "User '$USERNAME' granted sudo privileges with NOPASSWD." |
| 159 | else |
| 160 | print_error "Error in sudoers file configuration. Removing file..." |
| 161 | rm -f "$SUDOERS_FILE" |
| 162 | exit 1 |
| 163 | fi |
| 164 | break |
| 165 | ;; |
| 166 | [Nn]|[Nn][Oo]|"") |
| 167 | print_status "User '$USERNAME' will not have sudo privileges." |
| 168 | break |
| 169 | ;; |
| 170 | *) |
| 171 | print_warning "Please answer 'y' for yes or 'n' for no." |
| 172 | ;; |
| 173 | esac |
| 174 | done |
| 175 | |
| 176 | # Step 6: Summary |
| 177 | echo |
| 178 | print_status "Setup completed successfully!" |
| 179 | echo "==================================" |
| 180 | echo "Summary:" |
| 181 | echo "- User: $USERNAME" |
| 182 | echo "- Home directory: $USER_HOME" |
| 183 | echo "- SSH directory: $SSH_DIR (permissions: 700)" |
| 184 | echo "- SSH keys source: GitHub user '$GITHUB_USER'" |
| 185 | if [[ -n "$KEYS_CONTENT" ]] && [[ "$KEYS_CONTENT" != "Not Found" ]]; then |
| 186 | echo "- SSH keys: $(echo "$KEYS_CONTENT" | wc -l) key(s) installed" |
| 187 | else |
| 188 | echo "- SSH keys: No keys found (manual setup required)" |
| 189 | fi |
| 190 | echo "- Sudo privileges: $(if [[ "$GRANT_SUDO" =~ ^[Yy] ]]; then echo "Yes (NOPASSWD)"; else echo "No"; fi)" |
| 191 | echo |
| 192 | print_status "The user '$USERNAME' can now connect via SSH using their GitHub SSH keys." |
| 193 | |
| 194 | if [[ "$GRANT_SUDO" =~ ^[Yy] ]]; then |
| 195 | print_status "The user has passwordless sudo access." |
| 196 | fi |
| 197 | |
| 198 | echo |
| 199 | print_status "Setup script finished." |