求助:ejabberd 17.09中使用Python实现外部认证的教程链接
Hey there! Since you're new to Python and working with ejabberd 17.09, let's walk through setting up external authentication step by step—no need to feel overwhelmed, we'll keep it straightforward.
1. Understand ejabberd's External Auth Protocol
First, a quick primer: ejabberd communicates with external auth scripts via standard input/output (STDIN/STDOUT) using a simple binary protocol:
- ejabberd sends a 4-byte big-endian integer (this is the length of the following request string)
- Then it sends the request string, which looks like
auth:USERNAME:SERVER:PASSWORDfor authentication checks - Your script needs to respond with a 4-byte big-endian length prefix followed by either
ok(success) orfail(failure)
2. Write the Python Authentication Script
Here's a basic, working script you can start with. We'll use Python 3 (since Python 2 is no longer supported) and handle the binary protocol correctly:
#!/usr/bin/env python3 import sys import struct def read_request(): # Read 4-byte length prefix (big-endian) length_data = sys.stdin.read(4) if not length_data: return None length = struct.unpack('!I', length_data)[0] # Read the actual request string request = sys.stdin.read(length).decode('utf-8') return request def send_response(response): # Encode response string to bytes response_bytes = response.encode('utf-8') # Pack the length as 4-byte big-endian length = struct.pack('!I', len(response_bytes)) # Write length + response to stdout sys.stdout.write(length + response_bytes) sys.stdout.flush() def authenticate(username, server, password): # Replace this with your actual authentication logic! # For testing, we'll use hardcoded credentials valid_users = { ("john", "example.com"): "secure123", ("jane", "example.com"): "mypassword" } return valid_users.get((username, server)) == password def main(): while True: request = read_request() if not request: break parts = request.split(':') if parts[0] == 'auth' and len(parts) == 4: _, username, server, password = parts if authenticate(username, server, password): send_response("ok") else: send_response("fail") # Handle other request types if needed (like isuser, setpass) elif parts[0] == 'isuser' and len(parts) == 3: _, username, server = parts # Check if user exists (adjust logic as needed) valid_users = [("john", "example.com"), ("jane", "example.com")] send_response("ok" if (username, server) in valid_users else "fail") else: # Invalid request, return fail send_response("fail") if __name__ == "__main__": main()
Notes on the script:
- Make sure to set the correct shebang (
#!/usr/bin/env python3) so ejabberd knows to run it with Python 3 - The
authenticatefunction is where you'll add your real logic—connect to a database, check LDAP, etc. For now, it uses hardcoded users for testing. - We use
structto handle the 4-byte big-endian length, which is critical for ejabberd to parse your response correctly. - Always
flush()stdout after sending a response—otherwise, ejabberd might not receive the data immediately.
3. Configure ejabberd to Use the Script
Next, you need to update your ejabberd.yml configuration file:
Step 3.1: Enable external authentication
Find the auth_method setting and add external to the list:
auth_method: [internal, external]
(Keep internal if you still want to use ejabberd's built-in users, or remove it if you only want external auth.)
Step 3.2: Define the external auth command
Add this section to specify the path to your Python script:
extauth_program: "/path/to/your/auth_script.py"
Replace /path/to/your/auth_script.py with the actual full path to your script (e.g., /home/ejabberd/auth.py).
Step 3.3: Set proper permissions
ejabberd runs under a specific user (usually ejabberd), so make sure the script is executable and accessible:
# Make the script executable chmod +x /path/to/your/auth_script.py # Ensure ejabberd user can read/execute it chown ejabberd:ejabberd /path/to/your/auth_script.py
4. Test the Setup
Step 4.1: Test the script manually
First, test the script directly to make sure it works. Run it in your terminal, then send a test request (you'll need to input binary data, so we can use printf):
# Send an auth request for user john@example.com with password secure123 printf '\x00\x00\x00\x1dauth:john:example.com:secure123' | /path/to/your/auth_script.py
You should see a binary response that includes ok (you can pipe to hexdump to check: ... | hexdump -C—look for 6f 6b which is "ok" in hex).
Step 4.2: Test with ejabberd
Restart ejabberd to apply the config changes:
sudo systemctl restart ejabberd
Then try logging in with a test user using an XMPP client (like Pidgin or Gajim) using the credentials you set in the script. If it works, you're good to go!
Troubleshooting Tips
- Check ejabberd logs (
/var/log/ejabberd/ejabberd.log) for any errors related to external auth - Make sure your script doesn't print any extra output (like print statements for debugging)—this will break the protocol
- Double-check the path to the script in
ejabberd.yml—typos are a common issue - Ensure Python 3 is installed on your system and available at
/usr/bin/env python3
内容的提问来源于stack exchange,提问作者Lora

