Re: [squid-users] external_acl_type ttl not working? or not as I understand?

From: Mike Brentlinger <msbrentlinger@dont-contact.us>
Date: Thu, 9 Jun 2005 16:05:06 -0500

beautiful, you were entirely right Chris...

for those interested heres the solution i conjured. please excuse the
ugly / sloppy coding technique. :)

does the following...
for each request, takes source address, snmp queries a novell box on
the requesters lan to find what novell user is logged on at that box.
if its only one user (eg its not a citrix box with 10 different
users) then it looks that user up via ldap host to see if that user is
in the "internet" group. if so, throws "OK user=blah", if not throws
ERR. thus allowing novell users to authenticate and be logged in squid
logs.

finally i also threw in a ncsa_auth parm to give admins and others in
the know ability to get out thru the proxy even if they havent logged
into novell.

adding a user with command..
        htpasswd -c /etc/squid.htpasswd admin
                
in squid.conf
        external_acl_type ldap_lookup ttl=120 %SRC /tmp/ldap_lookup.pl
        acl group1 external ldap_lookup
        http_access allow group1

        auth_parm basic program /usr/sbin/ncsa_auth /etc/squid.htpasswd
        acl htpasswd_auth proxy_auth admin
        http_access allow htpasswd_auth

/tmp/ldap_lookup.pl contains....

#!/usr/bin/perl
use strict;
$|=1;
while ( 1 == 1 ) {
        my $sought_ip = <STDIN>;
        chomp($sought_ip);
        if ($sought_ip =~ /^172\.16\.\d{1,3}\.\d{1,3}$/){
                print &lookup_info('novell_box_w_snmp1',$sought_ip,'ldapbox');
        } elsif ($sought_ip =~ /^192\.168\.1\.\d{1,3}$/) {
                print &lookup_info('novell_box_w_snmp2',$sought_ip,'ldapbox');
        } elsif ($sought_ip =~ /^192\.168\.61\.\d{1,3}$/) {
                print &lookup_info('novell_box_w_snmp3',$sought_ip,'ldapbox');
        } else {
                print 'ERR error=no_idea_what_snmp_host_to_query_youre_not_at_novell
box 1 2 or 3'."\n";
        }
}
sub lookup_info {
        #get args...
        (my $snmp_host,my $sought_ip,my $ldap_host)=@_;
        #convert ip to hex
        my @hex_ip = split(/\./,$sought_ip);
        foreach (@hex_ip) {
                $_ = dec2hex($_);
        };
        my $hex_ip = join(' ',@hex_ip,);
        #get session_ids/users and session_ids/ips_in_hex_form
        my @users = `snmpwalk -v 1 -c public $snmp_host .1.3.6.1.4.1.23.2.28.3.8.1.2`;
        my @ips_in_hex = `snmpwalk -v 1 -c public $snmp_host
.1.3.6.1.4.1.23.2.28.3.8.1.4`;
        #print "ips\t\t::\tconnection id\n";
        # regex thru ips in hex form and find our specific ip then save that
session id in an array
        my @connection_ids;
        foreach (@ips_in_hex) {
                if (/^.*\.(\d{1,9}) = Hex-STRING: $hex_ip/i) {
                        #print $sought_ip."\t::\t".$1."\n";
                        push(@connection_ids,$1);
                }
        }
        #for each unique connection id on an IP, look thru users and on
matching id #'s pull the user tied to that session
        my %users;
        my %connection_ids = map {$_ => 1} @connection_ids;
        foreach (sort keys %connection_ids) {
                my $connection_id = $_;
                foreach (@users){
                        if ( ($_ !~ /ou=workstations/i) and ($_ =~
/.*23\.2\.28\.3\.8\.1\.2\.($connection_id)\s=\s.*STRING:\s"(.*)"/)){
                                $users{$1}=$2;
                        }
                }
        }
        #print "there are ".scalar(keys %users)." users on that ip\n";
        return 'ERR error=not_just_1_user_on_this_ip'."\n" if (scalar(keys
%users) != 1);
        #print "\nconnection id\t::\t person at connection\t\tcan get on internet\n";
        # for each user on a session id
        open LDAPSEARCH, 'c:\openldap\ldapsearch -LLLxh '.'ldaphost'.'
"(cn=Internet)" member |' or die "Can't ldapsearch :$!";
        my @ldap_search;
        while (<LDAPSEARCH>) {
                push (@ldap_search, $_) if (/member:/i);
        }
        foreach (keys %users) {
                $users{$_} =~ s/\.T=.*//g;
                $users{$_} =~ s/\.CN=/CN=/g;
                $users{$_} =~ s/\./,/g;
                #print "$users{$_} :: $_";
                #print "$_ \t\t::\t $users{$_}\t" if (($_) and ($users{$_} !~
/[a-z,0-9,:]{17,17},ou=workstations/i ));
                my $fullusername = $users{$_};
                my $found = 0;
                foreach (@ldap_search) {
                        if ($_ =~ /$fullusername/i) {
                                $found = 1;
                                /member: (.*)/i;
                          last;
                        }
                }

                $fullusername =~ s/CN=//g;
                $fullusername =~ s/,OU=|,O=/./g;
                
                if ($found == 0){
                        return 'ERR error='.$fullusername."\n";
                } else {
                        return 'OK user='.$fullusername."\n";
                }
        }
}
sub hex2dec($) {
        eval "return sprintf(\"\%d\", 0x$_[0])";
}
sub dec2hex($) {
        return sprintf("%02lX", $_[0])
}

On 6/1/05, Chris Robertson <crobertson@gci.com> wrote:
> > -----Original Message-----
> > From: Mike Brentlinger [mailto:msbrentlinger@gmail.com]
> > Sent: Wednesday, June 01, 2005 1:57 PM
> > To: Chris Robertson
> > Cc: squid-users@squid-cache.org
> > Subject: Re: [squid-users] external_acl_type ttl not working? or not as I
> understand?
> >
> > On 6/1/05, Chris Robertson <crobertson@gci.com> wrote:
> >>> -----Original Message-----
> >>> From: Mike Brentlinger [mailto:msbrentlinger@gmail.com]
> >>> Sent: Wednesday, June 01, 2005 10:23 AM
> >>> To: squid-users@squid-cache.org
> >>> Subject: [squid-users] external_acl_type ttl not working? or not as I
> >>> understand?
> >>>
> >>>
> >>> Im trying to conjure up a replacement to novell border manager +
> >>> client trust for transpartent auth in a novell environment. there are
> >>> some squid proxy auth things it seems, however they require that the
> >>> user be prompted to enter a user+pass... not really ideal. instead
> >>> users should not have to think about logging on. i know ident can be
> >>> spoofed but for this test its not a huge issue so got the following to
> >>> work on squid 2.5 stable 5:
> >>>
> >>> external_acl_type ldap_lookup ttl=120 %IDENT /tmp/ldaplookup.pl
> >>> acl group1 external ldap_lookup
> >>> http_access allow group1
> >>>
> >>> where /tmp/ldaplookup.pl is
> >>> #!/usr/bin/perl
> >>> $|=1;
> >>> while ( 1 == 1 ) {
> >>> $input = <STDIN>;
> >>> chomp($input);
> >>> open LDAPSEARCH, 'ldapsearch -LLLxh server "(cn=Internet)" member
> >>> |' or die "Can't ldapsearch :$!";
> >>> $found = 0;
> >>> $fullusername = '';
> >>> while (<LDAPSEARCH>) {
> >>> #print "$_";
> >>> if ($_ =~ /cn=$input,/i) {
> >>> $found = 1;
> >>> /member: (.*)/i;
> >>> $fullusername = $1;
> >>> last;
> >>> };
> >>> }
> >>> if ($found == 0){
> >>> print 'ERR ERROR="'.$input.' not a valid internet user"'."\n";
> >>> } else {
> >>> print 'OK USER="'.$fullusername.' authorized internet user"'."\n";
> >>> };
> >>> };
> >>>
> >>>
> >>> and my client is running
> >>> http://ftp.tdcnorge.no/pub/windows/Identd/Identd-1.1.0.zip
> >>>
> >>>
> >>> everything works except the ttl isnt as I thought... eg: my client
> >>> tries to hit a page, squid ident requests my client, which responds,
> >>> then squid uses my script to see if that user name is in the
> >>> "internet" group as retured from my ldap search. if the users in the
> >>> group the page is served, if not, they get access denied.
> >>>
> >>> so my question is this... if i imediately shut down my identd on my
> >>> client, squid starts denying access immediately. a net sniff shows
> >>> that squid is doing an ident query for every access request. I would
> >>> have expected with the ttl=120 that squid wouldnt query until 2
> >>> minutes later. this seems like a lot of needless ident traffic and
> >>> when i start piling on users ill be doing more ident and ldap lookups
> >>> than web proxying.
> >>>
> >>> I suppose I just misunderstand the ttl option. is there anyway to get
> >>> squid to only ask for this ident auth at some specified timeout and
> >>> not for every page request?
> >>>
> >>> any help would be greatly appreciated.
> >>
> >> The TTL value specified is how long Squid caches the result for the
> external
> >> ACL. So (as it stands now) if you authenticate, and then shut down the
> LDAP
> >> server (or revoke the account), you'll be able to continue surfing for
> two
> >> minutes. Move the ident lookup to the Perl script, and you should see a
> >> reduction in network traffic.
> >>
> >> Chris
> >>
> > Chris,
> > Thanks for the reply. to make sure I understand correctly...... youre
> > saying something like the following would only do a single idnet query
> > and ldap lookup every 2 mins... and in-between squid would just
> > remember for the duration of the ttl that %SRC has access ?
> >
> >
> > external_acl_type lookup ttl=120 %SRC /tmp/lookup.pl
> > acl group1 external lookup
> > http_access allow group1
> >
> >
> > where /tmp/lookup.pl is
> >
> > #!/usr/bin/perl
> > while ( 1 == 1 ) {
> > $input = <STDIN>; #client ip from squid
> > $ident_rtn_name = return of some func doing an ident query to
> > client for a username
> > open LDAPSEARCH, 'ldapsearch -LLLxh server "(cn=Internet)" member|' ;
> > $found = 0;
> > $fullusername = '';
> > while (<LDAPSEARCH>) {
> > if ($_ =~ /cn=$ident_rtn_name,/i) {
> > $found = 1;
> > /member: (.*)/i;
> > $fullusername = $1;
> > last;
> > };
> > }
> > if ($found == 0){
> > print 'ERR ERROR="'.$ident_rtn_name.' not a valid internet
> user"'."\n";
> > } else {
> > print 'OK USER="'.$fullusername.' authorized internet user"'."\n";
> > };
> > };
> >
> >
> > --
> > msb
>
> That is what I am saying. Whether I am correct or not is the big question.
> :o) FWIW, I have a high level of confidence in my assertion.
>
> Chris
>

-- 
 msb
Received on Thu Jun 09 2005 - 15:05:07 MDT

This archive was generated by hypermail pre-2.1.9 : Fri Jul 01 2005 - 12:00:02 MDT