[master] 7877283 First batch of docs concerning UDS and VCL in "Upgrading to 6.0".

Geoff Simmons geoff at uplex.de
Wed Mar 7 22:17:08 UTC 2018


commit 78772832944c550d65269f4ad8436902b850684e
Author: Geoff Simmons <geoff at uplex.de>
Date:   Wed Mar 7 23:15:07 2018 +0100

    First batch of docs concerning UDS and VCL in "Upgrading to 6.0".
    
    This anticipates some features planned for 6.0 that are presently
    not yet implemented:
    
    - UDS requires VCL 4.1.
    - VCL variables local.socket and local.endpoint

diff --git a/doc/sphinx/whats-new/upgrading-6.0.rst b/doc/sphinx/whats-new/upgrading-6.0.rst
index d2af1ac..ff0c6ec 100644
--- a/doc/sphinx/whats-new/upgrading-6.0.rst
+++ b/doc/sphinx/whats-new/upgrading-6.0.rst
@@ -30,10 +30,158 @@ Changes to VCL
 
 XXX: ... intro paragraph
 
-XXX VCL subhead 1
-~~~~~~~~~~~~~~~~~
-
-XXX: ... etc.
+Unix domain sockets and VCL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We have made an effort to adapt the support of Unix domain sockets in
+VCL so that you may not have to change anything in your VCL deployment
+at all, other than changing the version to 4.1. Most importantly, this
+affects the meaning of the ``*.ip`` variables and the use of ACLs; and
+there are a number of other details you should consider.
+
+If you don't use UDSen, then nothing about VCL changes. UDS support
+requires version 4.1, so if you are keeping your VCL level at 4.0 (and
+hence are staying with IP addresses), then none of the following is of
+concern.
+
+``client.ip``, ``server.ip``, ``local.ip`` and ``remote.ip``
+------------------------------------------------------------
+
+When referring to a connection that was in fact addressed as a UDS,
+the ``*.ip`` variables always have a value equivalent to the IPv4
+address ``0.0.0.0:0`` -- the "any IPv4" address with port 0.
+
+Remember that if you are using the PROXY protocol, then ``client.ip``
+and ``server.ip`` are set to the addresses sent in the PROXY header by
+the forwarding component. So these two variables may have "real" IP
+address values, even when the Varnish listener address is a UDS, if
+PROXY was specified. ``local.ip`` and ``remote.ip``, however, are
+always ``0.0.0.0`` for a UDS listener.
+
+If you have more than one UDS listener (more than one ``-a``
+command-line argument specifying a socket path), then you may not be
+able to use the ``*.ip`` variables to tell them apart, especially
+since ``local.ip`` will be ``0.0.0.0`` for all of them. If you need to
+distinguish such addresses in VCL, you can use ``local.socket`` (which
+is the name given for the ``-a`` argument; ``a0``, ``a1`` etc. by
+default) or ``local.endpoint``, which in the case of UDS is the path
+given in the ``-a`` argument. You can, for example, use string
+operations such as regex matching on ``local.endpoint`` to determine
+properties of the path address::
+
+  # admin requests allowed only on the listener whose path ends in
+  # "admin.sock"
+  if (req.url ~ "^/admin") {
+  	if (local.endpoint !~ "admin.sock$") {
+		# wrong listener, respond with "403 Forbidden"
+		return( synth(403) );
+	}
+	else {
+		# process the admin request ...
+	}
+  }
+
+  # superadmin requests only allowed on the "superadmin.sock" listener
+  if (req.url ~ "^/superadmin") {
+  	if (local.endpoint !~ "superadmin.sock$") {
+		return( synth(403) );
+	}
+	else {
+		# superadmin request ...
+	}
+  }
+
+ACLs
+----
+
+As before, ACLs can only specify ranges of IP addresses, and matches
+against ACLs can only be run against IP-valued elements.
+
+This means that if a ``*.ip`` variable whose value is ``0.0.0.0`` due
+to the use of UDS is matched against an ACL, the match can only
+succeed if the ACL includes ``0.0.0.0``. If you currently have a
+security requirement that depends on an ACL matching a range of IP
+addresses, then that will continue to work with a UDS listener (since
+you almost certainly have not included ``0.0.0.0`` in that range).
+
+Recall again that ``client.ip`` and ``server.ip`` are set by the PROXY
+protocol. So if you have a UDS listener configured to use PROXY and
+are using an ACL to match against one of those two variables, the
+matches will continue working against the "real" IPs sent via PROXY.
+
+You can of course define an ACL to match in the UDS case, by including
+``0.0.0.0``::
+
+  # matches local.ip and remote.ip when the listener is UDS
+  acl uds {
+  	"0.0.0.0";
+  }
+
+But such an ACL cannot distinguish different UDS listeners, if you
+have more than one. For that, you can achieve a similar effect by
+inspecting ``local.socket`` and/or ``local.endpoint``, as discussed
+above.
+
+``client.identity`` and the hash and shard directors
+----------------------------------------------------
+
+As before, ``client.identity`` defaults to ``client.ip``; that is, if
+its value has not been explicitly set in VCL, then it returns the same
+value as ``client.ip`` when it is read.
+
+A common use of ``client.identity`` is to configure the hash and shard
+directors (see :ref:`vmod_directors(3)`). This is a way to achieve
+"client-sticky" distribution of requests to backends -- requests from
+the same clients are always sent to the same backends.
+
+Such a configuration will almost certainly not do what you want if:
+
+* The listener is set to a UDS address.
+* PROXY is not used to set ``client.ip``.
+* ``client.identity`` is not set to a distinct value before it is
+  used to configure the director.
+
+Since ``client.identity`` defaults to ``client.ip``, which is always
+``0.0.0.0`` under these conditions, the result will be that the
+director sends all requests to just one backend, and no requests to
+any other backend.
+
+To avoid that result, change one of the conditions listed above -- use
+PROXY to set distinct values for ``client.ip``, or set
+``client.identity`` to distinct values before it is used.
+
+``server.ip`` and default hashing for the cache
+-----------------------------------------------
+
+The default algorithm for computing a hash value for the cache (the
+implementation of ``vcl_hash`` in ``builtin.vcl``) mixes ``req.url``
+and the Host header (``req.http.Host``) into the hash data. If there
+is no Host header, then ``server.ip`` is used instead. Considering the
+Host header or ``server.ip`` is a way of achieving a kind of "virtual
+hosting" -- if your site receives requests with different Host headers
+or at distinct server addresses, then requests for the same URL will
+not hit the same cached response, if the requests are different in
+those other respects.
+
+If you have UDS listeners and are not using PROXY to set distinct
+values of ``server.ip``, then requests without a Host header will have
+the same value of ``server.ip == 0.0.0.0`` mixed into the hash. In
+that case, requests with the same URL will result in the same hash
+value, and hit the same cached responses.
+
+That doesn't matter, of course, if you don't need the "virtual
+hosting" effect -- you only have one listener, you never receive
+different host headers, or you never receive the same URL for what
+should lead to distinct responses.
+
+But if you need to avoid that result, then you can make one or more
+of these changes:
+
+* Use the PROXY protocol to set distinct ``server.ip`` values.
+* Write your own implementation of ``vcl_hash``, for example to
+  mix ``local.socket`` or ``local.endpoint`` into the hash.
+* Set ``req.http.Host`` to a distinct value if it is absent before
+  ``vcl_hash`` is entered.
 
 VCL variables
 ~~~~~~~~~~~~~


More information about the varnish-commit mailing list