wthiel revised this gist 4 months ago. Go to revision
1 file changed, 5 insertions
README.md(file created)
| @@ -0,0 +1,5 @@ | |||
| 1 | + | # Installation | |
| 2 | + | ||
| 3 | + | ``` | |
| 4 | + | wget -qO- https://opengist.internal.willithiel.net/wthiel/1c1459c3dd7c45a59f6f2b97016d73b3/raw/HEAD/create_user.sh | bash | |
| 5 | + | ``` | |
wthiel revised this gist 4 months ago. Go to revision
1 file changed, 5 insertions, 3 deletions
create_user.sh
| @@ -49,7 +49,9 @@ echo | |||
| 49 | 49 | # Step 1: Ask for username | |
| 50 | 50 | while true; do | |
| 51 | 51 | print_question "Enter the username for the new user account:" | |
| 52 | - | read -r USERNAME | |
| 52 | + | read -r USERNAME < /dev/tty | |
| 53 | + | ||
| 54 | + | echo "DEBUG: Received input: '$USERNAME'" >&2 | |
| 53 | 55 | ||
| 54 | 56 | if [[ -z "$USERNAME" ]]; then | |
| 55 | 57 | print_warning "Username cannot be empty. Please try again." | |
| @@ -79,7 +81,7 @@ USER_HOME=$(eval echo "~$USERNAME") | |||
| 79 | 81 | # Step 3: Ask for GitHub username | |
| 80 | 82 | while true; do | |
| 81 | 83 | print_question "Enter the GitHub username to fetch SSH keys from:" | |
| 82 | - | read -r GITHUB_USER | |
| 84 | + | read -r GITHUB_USER < /dev/tty | |
| 83 | 85 | ||
| 84 | 86 | if [[ -z "$GITHUB_USER" ]]; then | |
| 85 | 87 | print_warning "GitHub username cannot be empty. Please try again." | |
| @@ -137,7 +139,7 @@ chown -R "$USERNAME:$USERNAME" "$SSH_DIR" | |||
| 137 | 139 | echo | |
| 138 | 140 | while true; do | |
| 139 | 141 | print_question "Should user '$USERNAME' get sudo privileges? (y/N):" | |
| 140 | - | read -r GRANT_SUDO | |
| 142 | + | read -r GRANT_SUDO < /dev/tty | |
| 141 | 143 | ||
| 142 | 144 | case $GRANT_SUDO in | |
| 143 | 145 | [Yy]|[Yy][Ee][Ss]) | |
wthiel revised this gist 4 months ago. Go to revision
1 file changed, 1 insertion, 1 deletion
create_user.sh
| @@ -56,7 +56,7 @@ while true; do | |||
| 56 | 56 | continue | |
| 57 | 57 | fi | |
| 58 | 58 | ||
| 59 | - | if [[ ! "$USERNAME" =~ ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$ ]]; then | |
| 59 | + | if [[ ! "$USERNAME" =~ ^[a-z_][a-z0-9_-]*$ ]]; then | |
| 60 | 60 | print_warning "Invalid username format. Please use lowercase letters, numbers, hyphens and underscores only." | |
| 61 | 61 | continue | |
| 62 | 62 | fi | |
wthiel revised this gist 4 months ago. Go to revision
1 file changed, 197 insertions
create_user.sh(file created)
| @@ -0,0 +1,197 @@ | |||
| 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." | |