To write a Python program which can be used to authenticate for Squid proxy server. This is useful when you don’t want to configure complex systems like LDAP, ntlm etc.
- When you want to authenticate clients using mysql database.
- When you want to authenticate clients using flat files or /etc/passwd file or some custom service on your network.
How to proceed
From auth_param section in squid.conf file:
Specify the command for the external authenticator. Such a program reads a line containing "username password" and replies "OK" or "ERR" in an endless loop. "ERR" responses may optionally be followed by a error description available as %m in the returned error page.
By default, the basic authentication scheme is not used unless a program is specified.
That clearly states that our python program should read a line from standard input (stdin) and write the appropriate response to the standard output (stdout). But there are some issues with I/O. The output should be unbuffered and should be flushed to standard output immediately after the response is known.
So, lets see a small program where we authenticate using a function ‘matchpassword()‘. This function returns True when username, password pair matches and returns False when they mismatch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#!/usr/bin/python import sys import socket """USAGE:The function returns True if the user and passwd match False otherwise""" def matchpasswd(login,passwd): # Write your own function definition. # Use mysql, files, /etc/passwd or some service or whatever you want pass while True: # read a line from stdin line = sys.stdin.readline() # remove '\n' from line line = line.strip() # extract username and password from line username = line[:line.find(' ')] password = line[line.find(' ')+1:] if matchpasswd(username, password): sys.stdout.write('OK\n') else: sys.stdout.write('ERR\n') # Flush the output to stdout. sys.stdout.flush()
Save the above file somewhere. We save this example file in /etc/squid/custom_auth.py .Now, we have the function for authenticating clients. We need to configure squid to use custom_auth.py . Below is the squid configuration for telling squid to use the above program as basic authenticator.
1 2 3 4 5 6 7 8 9 10 11
# you need to specify /usr/bin/python if your file is not executable and needs an interpreter to be invoked. # Replace /usr/bin/python with /usr/bin/php , if you write auth program in php. auth_param basic program /usr/bin/python /etc/squid/custom_auth.py # how many instances of the above program should run concurrently auth_param basic children 5 # display some message to clients when they are asked for username, password auth_param basic realm Please enter your proxy server username and password # for how much time the authentication should be valid auth_param basic credentialsttl 2 hours # whether username, password should be case sensitive or not auth_param basic casesensitive on
Now, to force clients to authenticate, configure the acls as follow. Below we assume, you want to force all clients on your lan to authenticate for using proxy server.
1 2 3 4 5 6
# acl to force proxy authentication acl authenticated proxy_auth REQUIRED # acl to define IPs from your lan acl lan src 192.168.0.0/16 # acl to force clients on your lan to authenticate http_access allow lan authenticated
Now, reload/restart squid. That’s all we need to write and use a custom authentication plugin for squid.
Username can’t contain spaces. Otherwise program will not be able to parse/extract username, password from standard input.