No description
  • HTML 98.5%
  • Vim Script 1.2%
  • Nix 0.3%
Find a file
2026-02-03 18:35:39 +08:00
claper.png more updates 2026-02-03 14:54:31 +08:00
extras.md more 2026-02-03 01:40:22 +08:00
extras.pdf more 2026-02-03 01:40:22 +08:00
flake.lock more updates 2026-02-03 14:54:31 +08:00
flake.nix more updates 2026-02-03 14:54:31 +08:00
HelloWorld.java add vimtutor and sample java file 2026-02-03 11:00:52 +08:00
README.md more 2026-02-03 01:40:22 +08:00
slides.html fix colorscheme 2026-02-03 18:29:51 +08:00
slides.md fix colorscheme 2026-02-03 18:29:51 +08:00
slides.pdf readd pdf 2026-02-03 18:35:39 +08:00
vimrc fix colorscheme 2026-02-03 18:29:51 +08:00
vimtutor add vimtutor and sample java file 2026-02-03 11:00:52 +08:00

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:

  1. /usr/local/bin/workshop-pam-auth - change WORKSHOP_PASSWORD
  2. Run echo "workshop_template:NEWPASSWORD" | chpasswd

How It Works

  1. libnss-ato: Makes any username resolve to the template user (UID 3000)
  2. PAM script: Accepts the workshop password for any non-root user
  3. ForceCommand: Runs the setup script on every SSH connection
  4. 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.