0

I'm trying to configure SQUID (3.5.27 on Ubuntu 18.04) to be a transparent proxy. Further down the line it is supposed to handle authentication and request logging, but I started simple and got stuck already.

I'm working on my local network. There is a simple webserver running on port 5000 on the SQUID server (jarvis). From another computer on my network I'm trying to access http://jarvis:5000 (obviously that works when switching iptables off).

IPTABLES config works with

iptables -t nat -A PREROUTING -i enp1s0 -p tcp -j REDIRECT --to-port 3128

My squid.conf is as simple as humanly possible

auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/htpasswd
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
http_port 3128 transparent
visible_hostname jarvis

/usr/lib/squid/basic_ncsa_auth /etc/squid/htpasswd works (without colon between username and password:

# /usr/lib/squid/basic_ncsa_auth /etc/squid/htpasswd
me itsame
OK

On the other machine I'm doing

curl -v -u me:itsame http://jarvis:5000

receiving

GET / HTTP/1.1
> Host: jarvis:5000
> Authorization: Basic bWU6aXRzYW1l
> User-Agent: curl/7.63.0
> Accept: */*
> 
< HTTP/1.1 407 Proxy Authentication Required
< Server: squid/3.5.27
< Mime-Version: 1.0
< Date: Thu, 15 Aug 2019 16:41:13 GMT
< Content-Type: text/html;charset=utf-8
< Content-Length: 3538
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Vary: Accept-Language
< Content-Language: en
* Authentication problem. Ignoring this.
< Proxy-Authenticate: Basic realm="Squid proxy-caching web server"
< X-Cache: MISS from jarvis
< X-Cache-Lookup: NONE from jarvis:0
< Via: 1.1 jarvis (squid/3.5.27)
< Connection: keep-alive

What am I missing?

1

Looks like you're trying to do transparent proxying (or "interception proxying", as the Squid FAQ calls it) with authentication.

The Squid FAQ says it pretty clearly:

Can I use ''proxy_auth'' with interception?

No, you cannot. See the answer to the previous question. With interception proxying, the client thinks it is talking to an origin server and would never send the Proxy-authorization request header.

And the "previous question" is:

Why can't I use authentication together with interception proxying?

Interception Proxying works by having an active agent (the proxy) where there should be none. The browser is not expecting it to be there, and it's for all effects and purposes being cheated or, at best, confused. As an user of that browser, I would require it not to give away any credentials to an unexpected party, wouldn't you agree? Especially so when the user-agent can do so without notifying the user [...]

Furthermore, your use case looks more like a reverse proxy, also known as web accelerator, which also adds features like authentication and logging, as the web-server-like application at your http://jarvis:5000 might be deficient at those things.

  • A transparent proxy is used when the clients need to be able to access basically any web server without requiring any sort of proxy-specific configuration at the browser: the network (typically a router) intercepts and redirects any browser-like connections to the proxy, which then may apply caching to e.g. minimize international traffic, or implement something like malware checking or adult content filtering.

  • A reverse proxy is only involved with one particular web server, or a group of servers. It may be used to load-balance a group of backend servers, or to add something like authentication or HTTPS to an appliance that only provides unauthenticated HTTP.

If what you actually want is actually more like a reverse proxy, then you might be much better served with using the proxy capabilities of a real web server, since those will give you much better capabilities on HTTP server-side authentication, which seems to be your primary requirement.

With Apache, you might do something like this:

<Location />
    AuthType Basic
    AuthName "Restricted Service"
    # (Following line optional)
    AuthBasicProvider file
    AuthUserFile "/etc/apache/htpasswd"
    Require user me
    ProxyPass http://jarvis:5000
    ProxyPassReverse http://jarvis:5000
</Location>

and initialize the /etc/apache/htpasswd file with:

# htpasswd -c /usr/local/apache/passwd/passwords me
New password: itsame
Re-type new password: itsame
Adding password for user me

If the server in http://jarvis:5000 embeds links or other references to itself in the HTML it outputs, and those references cannot be adjusted by configuring that server, you might have to play tricks like getting that server listening on the localhost interface only, and Apache in port 5000 of the actual network interface only.

Knowing more about the capabilities of the http://jarvis:5000 server would be important here. If it constructs its responses using whatever hostname and port the client says it used to reach it (the principle of "well, that information got the client connected to me so it must be correct"), then this will be easy. But if it hardcodes its HTML with links to itself using a particular protocol, hostname and port, and those are not configurable, achieving what you want may require trickery with hostnames, or something to edit the URLs in the response HTML in real-time.

  • I've tried the various curl options without success. I'd also argue that using proxy settings would make the proxy intransparent. My current suspicion is that I've done something wrong with the port configuration. Might be that I fundamentally don't understand how SQUID works – Mulle Aug 16 at 5:42
  • After a good night's sleep and another reading through your question, it looks like you're trying to use a proxy_auth ACL with a transparent proxy configuration - and the Squid FAQ says pretty clearly that this won't work. Answer completely overhauled. – telcoM Aug 16 at 8:10
  • Thanks for the excellent comprehensive answer. Makes sense. If I'd have known that the "interception" keyword is basically the same as "transparent", I'd have stumbled upon that FAQ. Funnily, the first idea I had to solve this problem was very similar to using Apache, but discarded it as I thought a full blown proxy would be more efficient. Additionally one has to take care that the user can't bypass the proxy and access the web service directly. A bit iptables magic probably does that job – Mulle Aug 16 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.