When managing multiple user accounts on a web server, there's often a need to:
- Automatically configure user directories (like Apache's
UserDir
functionality) - Handle special username cases for domain hosting
- Maintain these configurations during user creation/deletion
Here's a complete Bash script solution that hooks into adduser
to achieve this:
#!/bin/bash
# File: /usr/local/bin/custom_adduser
# Create user with standard home directory
adduser "$@"
# Get the username (last argument)
USERNAME="${@: -1}"
# Nginx userdir configuration
NGINX_USERDIR="
location ~ ^/~(.+?)(/.*)?$ {
alias /home/\$1/www\$2;
index index.html index.htm;
autoindex on;
}
"
# Check if username matches domain pattern (www.domain.com)
if [[ "$USERNAME" =~ ^www\..+$ ]]; then
# Extract domain
DOMAIN="${USERNAME#www.}"
# Create nginx vhost config
cat > /etc/nginx/conf.d/${USERNAME}.conf << EOF
server {
listen 80;
server_name ${DOMAIN} www.${DOMAIN};
root /home/${USERNAME}/www;
index index.html index.htm;
location / {
try_files \$uri \$uri/ =404;
}
}
EOF
else
# Add userdir config if not already present
if ! grep -q "location ~ ^/~" /etc/nginx/nginx.conf; then
sed -i "/http {/a ${NGINX_USERDIR}" /etc/nginx/nginx.conf
fi
fi
# Create www directory and set permissions
mkdir -p /home/${USERNAME}/www
chown ${USERNAME}:${USERNAME} /home/${USERNAME}/www
chmod 755 /home/${USERNAME}/www
# Test and reload nginx
nginx -t && systemctl reload nginx
To make this work effectively:
- Save the script as
/usr/local/bin/custom_adduser
- Make it executable:
chmod +x /usr/local/bin/custom_adduser
- Create a symlink to override default adduser:
ln -s /usr/local/bin/custom_adduser /usr/sbin/adduser
- Ensure proper SELinux/AppArmor permissions if applicable
When implementing automated web directory creation:
- Set proper directory permissions (755 for directories, 644 for files)
- Consider using
chroot
for user directories in production - Implement proper PHP-FPM pool isolation if running PHP applications
- Add rate limiting to prevent abuse of user directories
For more sophisticated systems, consider using PAM hooks:
# /etc/pam.d/common-session
session optional pam_exec.so /usr/local/bin/userdir_setup.sh
Then create the setup script:
#!/bin/bash
# /usr/local/bin/userdir_setup.sh
if [ "$PAM_TYPE" = "open_session" ]; then
USERNAME="$PAM_USER"
# Add your nginx configuration logic here
fi
exit 0
If things don't work as expected:
- Check nginx error logs:
tail -f /var/log/nginx/error.log
- Verify directory ownership:
ls -la /home/USERNAME
- Test nginx configuration:
nginx -t
- Ensure SELinux contexts are correct if using SELinux:
chcon -R -t httpd_user_content_t /home/USERNAME/www
When managing web servers for multiple users, we often need to automatically configure Nginx to serve user directories (~/www
) and handle custom domain mappings (like www.domain.com
pointing to user's ~/www
). This requires dynamic Nginx configuration during user creation.
We'll create a shell script that hooks into the adduser
process to:
- Create standard
~/www
directory for each user - Generate proper Nginx configuration for user directory access
- Handle special username cases for domain mapping
Create /usr/local/bin/nginx-user-setup
:
#!/bin/bash
USER=$1
HOME_DIR=$(getent passwd "$USER" | cut -d: -f6)
# Create www directory
mkdir -p "$HOME_DIR/www"
chown "$USER:$USER" "$HOME_DIR/www"
# Check for domain pattern in username
if [[ "$USER" =~ ^www\. ]]; then
DOMAIN="${USER#www.}"
NGINX_CONF="/etc/nginx/conf.d/${DOMAIN}.conf"
cat << EOF > "$NGINX_CONF"
server {
listen 80;
server_name $DOMAIN www.$DOMAIN;
root $HOME_DIR/www;
index index.html index.htm;
location / {
try_files \$uri \$uri/ =404;
}
}
EOF
else
# Standard user directory configuration
NGINX_USER_CONF="/etc/nginx/sites-available/user_$USER"
cat << EOF > "$NGINX_USER_CONF"
location ~ ^/~$USER(/.*)?$ {
alias $HOME_DIR/www\$1;
index index.html index.htm;
autoindex on;
try_files \$uri \$uri/ =404;
}
EOF
ln -s "$NGINX_USER_CONF" "/etc/nginx/sites-enabled/"
fi
# Test and reload Nginx
nginx -t && systemctl reload nginx
Configure the script to run automatically when users are added:
# For Debian/Ubuntu systems
echo '#!/bin/sh
if [ "$1" = "add" ]; then
/usr/local/bin/nginx-user-setup "$2"
fi' > /etc/adduser.conf
When implementing this solution:
- Set proper directory permissions (755 for directories, 644 for files)
- Consider using
userdir
module with proper security restrictions - Implement rate limiting for user directories
- Add proper logging for each virtual host
For more complex setups, you might want to:
# Add PHP support for user directories
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Enable HTTPS for custom domains
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;