- HTML 98.5%
- Vim Script 1.2%
- Nix 0.3%
| claper.png | ||
| extras.md | ||
| extras.pdf | ||
| flake.lock | ||
| flake.nix | ||
| HelloWorld.java | ||
| README.md | ||
| slides.html | ||
| slides.md | ||
| slides.pdf | ||
| vimrc | ||
| vimtutor | ||
Shell and Vim Workshop
Workshop SSH Server Setup
This documents how to set up a temporary SSH server where participants can log in with any username and a shared password. Users are auto-created on first login.
Requirements
- Ubuntu 24.04 server (tested on DigitalOcean droplet)
- Root SSH access
Quick Setup
SSH into your server as root and run the following commands.
1. Install Dependencies
apt-get update
apt-get install -y vim build-essential git libnss-extrausers sshpass
2. Build and Install libnss-ato
This allows any username to be accepted by SSH.
cd /tmp
git clone https://github.com/donapieppo/libnss-ato.git
cd libnss-ato
make
make install
3. Create Template User
useradd -m -s /bin/bash -u 3000 workshop_template
echo "workshop_template:workshop2026" | chpasswd
4. Configure libnss-ato
cat > /etc/libnss-ato.conf << 'EOF'
workshop_template:x:3000:3000:Workshop Template:/home/workshop_template:/bin/bash
EOF
5. Configure NSS (Name Service Switch)
Edit /etc/nsswitch.conf to add extrausers and ato:
sed -i 's/^passwd:.*/passwd: files extrausers ato systemd/' /etc/nsswitch.conf
sed -i 's/^group:.*/group: files extrausers systemd/' /etc/nsswitch.conf
sed -i 's/^shadow:.*/shadow: files extrausers ato systemd/' /etc/nsswitch.conf
6. Initialize extrausers Directory
mkdir -p /var/lib/extrausers
touch /var/lib/extrausers/passwd
touch /var/lib/extrausers/shadow
touch /var/lib/extrausers/group
chmod 644 /var/lib/extrausers/passwd /var/lib/extrausers/group
chmod 640 /var/lib/extrausers/shadow
chown root:shadow /var/lib/extrausers/shadow
7. Create Workshop Setup Script
This script creates users on-the-fly when they SSH in:
cat > /usr/local/bin/workshop-setup << 'SCRIPT'
#!/bin/bash
# Workshop setup - creates user and runs as them
USERNAME="${USER}"
USERNAME=$(echo "$USERNAME" | tr -cd '[:alnum:]_-' | head -c 32)
if [ "$USERNAME" = "root" ]; then
if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
exec /bin/bash -c "$SSH_ORIGINAL_COMMAND"
else
exec /bin/bash -l
fi
fi
CURRENT_UID=$(id -u)
if [ "$CURRENT_UID" = "3000" ]; then
# Create user in extrausers if not exists
if ! grep -q "^${USERNAME}:" /var/lib/extrausers/passwd 2>/dev/null && \
! grep -q "^${USERNAME}:" /etc/passwd 2>/dev/null; then
NEXT_UID=$(cat /etc/passwd /var/lib/extrausers/passwd 2>/dev/null | awk -F: '$3 >= 4000 && $3 < 65000 {print $3}' | sort -n | tail -1)
NEXT_UID=${NEXT_UID:-3999}
NEXT_UID=$((NEXT_UID + 1))
echo "${USERNAME}:x:${NEXT_UID}:${NEXT_UID}:Workshop User:/home/${USERNAME}:/bin/bash" | sudo tee -a /var/lib/extrausers/passwd > /dev/null
echo "${USERNAME}:!:19000:0:99999:7:::" | sudo tee -a /var/lib/extrausers/shadow > /dev/null
echo "${USERNAME}:x:${NEXT_UID}:" | sudo tee -a /var/lib/extrausers/group > /dev/null
fi
# Create home if needed
if [ ! -d "/home/$USERNAME" ]; then
sudo /usr/bin/mkdir -p "/home/$USERNAME"
sudo /usr/bin/cp -r /etc/skel/. "/home/$USERNAME/" 2>/dev/null || true
fi
# Fix ownership using USERNAME (not numeric UID - NSS quirk)
sudo /usr/bin/chown -R "${USERNAME}:${USERNAME}" "/home/$USERNAME" 2>/dev/null
# Run as user
if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
exec sudo /bin/su -s /bin/bash "$USERNAME" -c "cd /home/$USERNAME && $SSH_ORIGINAL_COMMAND"
else
exec sudo /bin/su -l "$USERNAME"
fi
else
if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
exec /bin/bash -c "$SSH_ORIGINAL_COMMAND"
else
exec /bin/bash -l
fi
fi
SCRIPT
chmod +x /usr/local/bin/workshop-setup
8. Create PAM Authentication Script
This accepts the workshop password for all users:
cat > /usr/local/bin/workshop-pam-auth << 'SCRIPT'
#!/bin/bash
# PAM authentication for workshop
# Accept workshop password for any user except root
WORKSHOP_PASSWORD="workshop2026"
# Don't interfere with root auth
if [ "$PAM_USER" = "root" ]; then
exit 25 # PAM_IGNORE
fi
# Read password from stdin (expose_authtok)
read -r password
if [ "$password" = "$WORKSHOP_PASSWORD" ]; then
exit 0 # PAM_SUCCESS
else
exit 1 # PAM_AUTH_ERR
fi
SCRIPT
chmod +x /usr/local/bin/workshop-pam-auth
9. Configure PAM for SSH
Edit /etc/pam.d/sshd to add custom auth at the top (after the first comment block):
cat > /etc/pam.d/sshd << 'EOF'
# PAM configuration for the Secure Shell service
# Workshop: Custom auth for any username
auth [success=done default=ignore] pam_exec.so expose_authtok /usr/local/bin/workshop-pam-auth
# Standard Un*x authentication.
@include common-auth
# Disallow non-root logins when /etc/nologin exists.
account required pam_nologin.so
# Standard Un*x authorization.
@include common-account
# SELinux needs to be the first session rule.
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
# Set the loginuid process attribute.
session required pam_loginuid.so
# Create a new session keyring.
session optional pam_keyinit.so force revoke
# Standard Un*x session setup and teardown.
@include common-session
# Print the message of the day upon successful login.
session optional pam_motd.so motd=/run/motd.dynamic
session optional pam_motd.so noupdate
# Print the status of the user's mailbox upon successful login.
session optional pam_mail.so standard noenv
# Set up user limits from /etc/security/limits.conf.
session required pam_limits.so
# Read environment variables
session required pam_env.so
session required pam_env.so user_readenv=1 envfile=/etc/default/locale
# SELinux
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
# Standard Un*x password updating.
@include common-password
EOF
10. Configure Sudoers
Allow workshop_template to run necessary commands:
cat > /etc/sudoers.d/workshop << 'EOF'
workshop_template ALL=(root) NOPASSWD: /usr/bin/tee, /usr/bin/mkdir, /usr/bin/cp, /usr/bin/chown, /bin/su
EOF
chmod 440 /etc/sudoers.d/workshop
visudo -c # Verify syntax
11. Configure SSH
Enable password authentication and add ForceCommand:
# Enable password auth
sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config.d/*.conf 2>/dev/null || true
# Add ForceCommand for non-root users
cat >> /etc/ssh/sshd_config << 'EOF'
# Workshop: Run setup script for all non-root users
Match User *,!root
ForceCommand /usr/local/bin/workshop-setup
EOF
# Verify and restart
sshd -t && systemctl restart ssh
Usage
Participants can now SSH with any username:
ssh anyname@YOUR_SERVER_IP
# Password: workshop2026
Changing the Password
To use a different password, update it in two places:
/usr/local/bin/workshop-pam-auth- changeWORKSHOP_PASSWORD- Run
echo "workshop_template:NEWPASSWORD" | chpasswd
How It Works
- libnss-ato: Makes any username resolve to the template user (UID 3000)
- PAM script: Accepts the workshop password for any non-root user
- ForceCommand: Runs the setup script on every SSH connection
- Setup script: Creates the real user in extrausers if needed, sets up home directory, then switches to that user
Security Notes
This setup is intended for temporary workshop use only:
- All users share the same password
- Users are auto-created without verification
- No rate limiting on login attempts
Tear down the server after the workshop.