如何通过网站输入在服务器上创建新的Nginx用户?
Hey, I see where you're stuck—your current approach isn't working because htpasswd runs interactively by default, and those separate system() calls can't pass the password input to the original htpasswd process. Let's break this down and fix it properly.
The Core Problem
When you run system("htpasswd /etc/nginx/.htpasswd $username"), it launches htpasswd which waits for you to type a password and confirm it. But your subsequent system("$password1") and system("$password2") are running separate commands (trying to execute the password as if it's a shell command—definitely not what you want!). These can't feed input into the waiting htpasswd process.
Solution 1: Use htpasswd's Non-Interactive Mode (-b Flag)
htpasswd has a -b option that lets you pass the username and password directly in the command line. This avoids the interactive prompt entirely.
First, let's fix your form and PHP code with this method:
- Switch to POST for Security: GET exposes passwords in the URL, so use POST instead:
<form action="make-user.php" method="post"> Username: <input type="text" name="username"> Password: <input type="password" name="password1"> repeat Password: <input type="password" name="password2"> <input type="submit"> </form>
- Updated PHP Code:
<?php // Check if form was submitted if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = $_POST["username"]; $password1 = $_POST["password1"]; $password2 = $_POST["password2"]; // First, validate passwords match if ($password1 !== $password2) { echo "Passwords don't match!"; exit; } // Sanitize the username to prevent shell injection attacks // Remove any characters that aren't alphanumeric, underscores, or hyphens $sanitized_username = preg_replace('/[^a-zA-Z0-9_-]/', '', $username); if ($sanitized_username !== $username) { echo "Invalid username characters!"; exit; } // Build the htpasswd command with -b flag $command = "htpasswd -b /etc/nginx/.htpasswd $sanitized_username '$password1'"; // Execute the command and capture the exit status system($command, $return_var); // Check if the command succeeded if ($return_var === 0) { echo "User $sanitized_username created successfully!"; } else { echo "Failed to create user. Check permissions or username."; } } ?>
Solution 2: Pipe Passwords to htpasswd (-i Flag)
If you don't want to pass the password in the command line (for slightly better security, since command line args can be seen via ps), you can use the -i flag to read the password from standard input, and pipe the password twice (for confirmation):
Replace the command line in the PHP code with:
$command = "echo -e '$password1\n$password1' | htpasswd -i /etc/nginx/.htpasswd $sanitized_username";
Critical Notes to Make This Work
- File Permissions: The web server user (usually
www-dataon Debian/Ubuntu,apacheon RHEL/CentOS) needs write permissions to/etc/nginx/.htpasswd. You can set this with:sudo chown www-data:www-data /etc/nginx/.htpasswd sudo chmod 600 /etc/nginx/.htpasswd - Shell Injection Prevention: Always sanitize user input! The username filter above removes dangerous characters that could let an attacker run arbitrary commands.
- Error Handling: Checking the
$return_varfromsystem()tells you ifhtpasswdsucceeded (0 = success, non-zero = failure).
内容的提问来源于stack exchange,提问作者Miihau

