[squid-users] How to allow users authenticated to access only their own ports.

Amos Jeffries squid3 at treenet.co.nz
Thu Jul 14 10:15:56 UTC 2022


On 8/07/22 11:13, Marcelo wrote:
> Hi everyone ;)
> 
> I have a little bit complex task at hand.
> 

This is not particularly complex and comes up relatively often.


> What I must do:
> 
> 1-Allow an user to access squid only through specific port. This same 
> user can access 1 port or several ports, depending on how many routes he 
> have.

Why do Squid listening ports need to be linked to routes? There is 
nothing special about listening ports.

If you have a business/contractual level thing indicating that certain 
clients IP ranges can access certain port(s) that is better dealt with 
at a firewall prohibiting other IP ranges reaching those ports. Letting 
the traffic reach Squid in that case is "too late".


> 
> 2- Authenticated users can access only their own ports.
> 

These are not separate items. They are achieved by the same config setup:

  http_port 3218
  acl port3128 myportname 3128

  # repeat above for each listening port

  # below lines only need to exist once

  auth_param ...
  acl login proxy_auth REQUIRED
  http_access deny !login

  external_acl_type checkUserPort \
     ttl=0 negative_ttl=0 cache=0 \
     %ul %rp \
     /path/to/ext_sql_session_acl ...

  acl userHasPort external checkUserPort
  http_access deny !userHasPort


In the DB the session helper checks you simply add entries for each 
"username portname" as the session ID column. Removing DB entries 
immediately stops all *new* traffic from that user account being 
accepted. You can adjust the TTL / cache options, but that will affect 
the speed of user traffic halting.


> 3- Every access is via IP:Port that brings the user to a different 
> tcp_outgoing_address
> 


Please be aware that the concept of an end-to-end route decided by one 
agent along the line is not compatible with modern networking protocols.

Firstly, you will need to disable HTTP persistence features entirely on 
outbound traffic. This erases all possibility of TCP-fast-open, HTTP 
connection sharing and multiplexing performance boosters for traffic 
going through your proxy. It will also make use of cache_peer extremely 
difficult.

   server_persistent_connections off


Next you have Squid tell the OS routing system what IP(s) each listening 
port is linked to:

   tcp_outgoing_address 192.168.0.1 port3128
   tcp_outgoing_address ::1 port3128

I would place them right after the port3128 line so it is easy to manage 
many entries and see what port+routes are linked.
   You could even place the repeated groups of 
http_access+acl+tcp_outgoing_address lines in a separate config file 
per-port to allow automated management with the include directive.


Please be aware that tcp_outgoing_address is at best a *hint* to the OS 
routing system about what IP address is preferred as outgoing. The 
routing system can itself re-assign IP related details (eg outgoing NAT 
or gateway traffic balancing).


So, if you can clarify what actual business need is leading to it being 
considered a requirement? very likely there are alternatives that will 
not break your traffic as much.




If you are interested here are some pointers on where the experiments 
went wrong ...

> Example
> 
> An user must have 2 routes:
> 
> 192.168.0.2:3001 this route brings this user to tcp_outgoing_address 
> 200.2.2.11
> 
> 192.168.0.2:3002 this route brings this user to tcp_outgoing_address 
> 200.2.2.12
> 
> Yes, every port have to route to a different tcp outgoing address.
> 
> The closest I could get to a solution was using this:
> 
> http_port 192.168.0.2:3001 name=5
> 
> acl ip5 myportname 5
> 
> tcp_outgoing_address 200.2.2.11 ip5
> 
> This way, an user that enters via 192.168.0.2:3001 goes out via 200.2.2.11.
> 

It *looks* like working. But only does if the user is accessing an IPv4 
service.

You need a second tcp_outgoing_address entry to provide routing to IPv6 
services. Otherwise IPv6 traffic will completely disobey your route 
assignment policy.


> And its fine, but this way, every authenticated user can access all routes.
> 
> I have tried several ways to bind an username in this solution, but it 
> is not working.
> Authentication was via basic_db_auth, but I “downgraded it” to 
> basic_ncsa_auth to simplify tests. Authentication is working fine.
> 
> My last try was using the setup below, but It made squid a little dizzy:
> 
> acl ip3 proxy_auth test myportname 3
> 

The above will accept logins for these usernames:
   "test", "myportname", and "3"

Each "acl" line has a single type parameter (above "proxy_auth") and 
performs a boolean 'OR' condition matching values listed after the type.



> http_access allow ip3
> 

This allows the above mentioned usernames unlimited access. No criteria 
other than they had to login.


> http_port 192.168.0.2:2000 name=3
> 
> tcp_outgoing_address 200.2.2.11 ip3
> 

This assigns the *username* to that route. No connection to the port 
they arrived at.


> http_access deny ip3
> 

Never happens, "ip3" has already been allowed above.


Same issues for these ip4 rules

> acl ip4 proxy_auth test1 myportname 4
> http_access allow ip4
> http_port 192.168.0.2:2000 name=4
> tcp_outgoing_address 200.2.2.12 ip4
> http_access deny ip4
> 

Then finally, all attempts to login that are *not* matching "ip3" nor 
"ip4" are *ALLOWED* (oops).


HTH
Amos


More information about the squid-users mailing list