[master] c8d7078 Add VMOD proxy
Emmanuel Hocdet
manu at gandi.net
Wed Mar 14 16:10:09 UTC 2018
commit c8d7078fcc902445530f45120b1e6efbd4e93bae
Author: Emmanuel Hocdet <manu at gandi.net>
Date: Thu Mar 1 18:06:31 2018 +0100
Add VMOD proxy
diff --git a/bin/varnishtest/tests/o00005.vtc b/bin/varnishtest/tests/o00005.vtc
new file mode 100644
index 0000000..49cb0ef
--- /dev/null
+++ b/bin/varnishtest/tests/o00005.vtc
@@ -0,0 +1,41 @@
+varnishtest "PROXY v2 TLV test"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -proto "PROXY" -vcl+backend {
+ import proxy;
+
+ sub vcl_deliver {
+ if (proxy.ssl_verify_result() == 0) {
+ set resp.http.verify = "ok";
+ }
+ set resp.http.alpn = proxy.alpn();
+ set resp.http.ssl-version = proxy.ssl_version();
+ set resp.http.cipher = proxy.ssl_cipher();
+ set resp.http.key = proxy.cert_key();
+ set resp.http.sign = proxy.cert_sign();
+ }
+} -start
+
+client c1 {
+ sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a 21 11 00 65"
+ sendhex "d9 46 b5 21 5f 8e a8 22 ed 96 01 bb 03 00 04 95"
+ sendhex "03 ee 75 01 00 02 68 32 02 00 0a 68 6f 63 64 65"
+ sendhex "74 2e 6e 65 74 20 00 3d 01 00 00 00 00 21 00 07"
+ sendhex "54 4c 53 76 31 2e 33 25 00 05 45 43 32 35 36 24"
+ sendhex "00 0a 52 53 41 2d 53 48 41 32 35 36 23 00 16 41"
+ sendhex "45 41 44 2d 41 45 53 31 32 38 2d 47 43 4d 2d 53"
+ sendhex "48 41 32 35 36"
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.verify == ok
+ expect resp.http.alpn == h2
+ expect resp.http.ssl-version == TLSv1.3
+ expect resp.http.cipher == AEAD-AES128-GCM-SHA256
+ expect resp.http.key == EC256
+ expect resp.http.sign == RSA-SHA256
+} -run
diff --git a/bin/varnishtest/vmods.h b/bin/varnishtest/vmods.h
index fb8f68f..06ab9b8 100644
--- a/bin/varnishtest/vmods.h
+++ b/bin/varnishtest/vmods.h
@@ -34,3 +34,4 @@ VTC_VMOD(purge)
VTC_VMOD(vtc)
VTC_VMOD(blob)
VTC_VMOD(unix)
+VTC_VMOD(proxy)
diff --git a/configure.ac b/configure.ac
index 4323d1b..45bdb45 100644
--- a/configure.ac
+++ b/configure.ac
@@ -760,6 +760,7 @@ AC_CONFIG_FILES([
lib/libvmod_vtc/Makefile
lib/libvmod_blob/Makefile
lib/libvmod_unix/Makefile
+ lib/libvmod_proxy/Makefile
man/Makefile
varnishapi.pc
varnishapi-uninstalled.pc
diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am
index 810e903..04fa9db 100644
--- a/doc/sphinx/Makefile.am
+++ b/doc/sphinx/Makefile.am
@@ -222,6 +222,10 @@ reference/vmod_unix.generated.rst: reference $(top_builddir)/lib/libvmod_unix/vm
cp $(top_builddir)/lib/libvmod_unix/vmod_unix.rst $@ || true
BUILT_SOURCES += reference/vmod_unix.generated.rst
+reference/vmod_proxy.generated.rst: reference $(top_builddir)/lib/libvmod_proxy/vmod_proxy.rst
+ cp $(top_builddir)/lib/libvmod_proxy/vmod_proxy.rst $@ || true
+BUILT_SOURCES += reference/vmod_proxy.generated.rst
+
EXTRA_DIST += $(BUILT_SOURCES)
MAINTAINERCLEANFILES = $(EXTRA_DIST)
diff --git a/doc/sphinx/reference/index.rst b/doc/sphinx/reference/index.rst
index 9df60eb..1bf5435 100644
--- a/doc/sphinx/reference/index.rst
+++ b/doc/sphinx/reference/index.rst
@@ -26,6 +26,7 @@ The Varnish Reference Manual
vmod_purge.generated.rst
vmod_blob.generated.rst
vmod_unix.generated.rst
+ vmod_proxy.generated.rst
directors.rst
varnish-counters.rst
vsl.rst
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 411bd80..907ee4a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -11,4 +11,5 @@ SUBDIRS = \
libvmod_purge \
libvmod_vtc \
libvmod_blob \
- libvmod_unix
+ libvmod_unix \
+ libvmod_proxy
diff --git a/lib/libvmod_proxy/Makefile.am b/lib/libvmod_proxy/Makefile.am
new file mode 100644
index 0000000..d8d5861
--- /dev/null
+++ b/lib/libvmod_proxy/Makefile.am
@@ -0,0 +1,7 @@
+#
+
+libvmod_proxy_la_SOURCES = \
+ vmod_proxy.c
+
+# Use vmodtool.py generated automake boilerplate
+include $(srcdir)/automake_boilerplate.am
diff --git a/lib/libvmod_proxy/automake_boilerplate.am b/lib/libvmod_proxy/automake_boilerplate.am
new file mode 100644
index 0000000..64f3c5a
--- /dev/null
+++ b/lib/libvmod_proxy/automake_boilerplate.am
@@ -0,0 +1,39 @@
+
+# Boilerplate generated by vmodtool.py - changes will be overwritten
+
+AM_LDFLAGS = $(AM_LT_LDFLAGS)
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/bin/varnishd \
+ -I$(top_builddir)/include
+
+vmoddir = $(pkglibdir)/vmods
+vmodtool = $(top_srcdir)/lib/libvcc/vmodtool.py
+vmodtoolargs = --strict --boilerplate
+
+vmod_LTLIBRARIES = libvmod_proxy.la
+
+libvmod_proxy_la_CFLAGS = \
+ @SAN_CFLAGS@
+
+libvmod_proxy_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ $(VMOD_LDFLAGS) \
+ @SAN_LDFLAGS@
+
+nodist_libvmod_proxy_la_SOURCES = vcc_if.c vcc_if.h
+
+$(libvmod_proxy_la_OBJECTS): vcc_if.h
+
+vcc_if.h vmod_proxy.rst vmod_proxy.man.rst: vcc_if.c
+
+vcc_if.c: $(vmodtool) $(srcdir)/vmod.vcc
+ @PYTHON@ $(vmodtool) $(vmodtoolargs) $(srcdir)/vmod.vcc
+
+EXTRA_DIST = vmod.vcc automake_boilerplate.am
+
+CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h \
+ $(builddir)/vmod_proxy.rst \
+ $(builddir)/vmod_proxy.man.rst
+
diff --git a/lib/libvmod_proxy/vmod.vcc b/lib/libvmod_proxy/vmod.vcc
new file mode 100644
index 0000000..c3774db
--- /dev/null
+++ b/lib/libvmod_proxy/vmod.vcc
@@ -0,0 +1,125 @@
+#-
+# Copyright (c) 2018 GANDI SAS
+# All rights reserved.
+#
+# Author: Emmanuel Hocdet <manu at gandi.net>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+$Module proxy 3 Varnish Standard Module
+$ABI strict
+
+DESCRIPTION
+===========
+
+`vmod_proxy` contains functions to extract proxy-protocol-v2 TLV attributes
+as described in https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt.
+
+
+$Function STRING alpn()
+
+Description
+ Extract alpn attribute.
+Example
+ set req.http.alpn = proxy.alpn();
+
+$Function STRING authority()
+
+Description
+ Extract authority attribute. This corresponds to sni from a tls
+ connection.
+Example
+ set req.http.authority = proxy.authority();
+
+$Function BOOL is_ssl()
+
+Description
+ Report if proxy-protocol-v2 has ssl tlv.
+
+Example
+ | if (proxy.is_ssl()) {
+ | set req.http.ssl-version = proxy.ssl_version();
+ | }
+
+$Function BOOL client_has_cert_sess()
+
+Description
+ Report if the client provided a certificate at least once over the TLS
+ session this connection belongs to.
+
+$Function BOOL client_has_cert_conn()
+
+Description
+ Report if the client provided a certificate over the current connection.
+
+$Function INT ssl_verify_result()
+
+Description
+ Report the SSL_get_verify_result from a TLS session. It only matters
+ if client_has_cert_sess() is true. Per default, value is set to 0
+ (X509_V_OK).
+
+Example
+ | if (proxy.client_has_cert_sess() && proxy.ssl_verify_result() == 0) {
+ | set req.http.ssl-verify = "ok";
+ | }
+
+$Function STRING ssl_version()
+
+Description
+ Extract ssl version attribute.
+Example
+ set req.http.ssl-version = proxy.ssl_version();
+
+$Function STRING client_cert_cn()
+
+Description
+ Extract the common name attribute of the client certificate's.
+Example
+ set req.http.cert-cn = proxy.client_cert_cn();
+
+$Function STRING ssl_cipher()
+
+Description
+ Extract the ssl cipher attribute.
+Example
+ set req.http.ssl-cipher = proxy.ssl_cipher();
+
+$Function STRING cert_sign()
+
+Description
+ Extract the certificate signature algorithm attribute.
+Example
+ set req.http.cert-sign = proxy.cert_sign();
+
+$Function STRING cert_key()
+
+Description
+ Extract the certificate key algorithm attribute.
+Example
+ set req.http.cert-key = proxy.cert_key();
+
+SEE ALSO
+========
+
+* :ref:`varnishd(1)`
+* :ref:`vsl(7)`
diff --git a/lib/libvmod_proxy/vmod_proxy.c b/lib/libvmod_proxy/vmod_proxy.c
new file mode 100644
index 0000000..8c6973c
--- /dev/null
+++ b/lib/libvmod_proxy/vmod_proxy.c
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2018 GANDI SAS
+ * All rights reserved.
+ *
+ * Author: Emmanuel Hocdet <manu at gandi.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cache/cache.h"
+
+#include "vend.h"
+#include "vcl.h"
+
+#include "proxy/cache_proxy.h"
+
+#include "vcc_if.h"
+
+
+struct pp2_tlv_ssl {
+ uint8_t client;
+ uint32_t verify;
+}__attribute__((packed));
+
+#define PP2_CLIENT_SSL 0x01
+#define PP2_CLIENT_CERT_CONN 0x02
+#define PP2_CLIENT_CERT_SESS 0x04
+
+static VCL_BOOL
+tlv_ssl_flag(VRT_CTX, int flag)
+{
+ struct pp2_tlv_ssl *dst;
+ int len;
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+ if (VPX_tlv(ctx->req, PP2_TYPE_SSL, (void **)&dst, &len))
+ return (0);
+
+ return ((dst->client & flag) == flag);
+}
+
+VCL_BOOL v_matchproto_(td_proxy_is_ssl)
+vmod_is_ssl(VRT_CTX)
+{
+ return tlv_ssl_flag(ctx, PP2_CLIENT_SSL);
+}
+
+VCL_BOOL v_matchproto_(td_proxy_client_has_cert_sess)
+vmod_client_has_cert_sess(VRT_CTX)
+{
+ return tlv_ssl_flag(ctx, PP2_CLIENT_CERT_SESS);
+}
+
+VCL_BOOL v_matchproto_(td_proxy_client_has_cert_conn)
+vmod_client_has_cert_conn(VRT_CTX)
+{
+ return tlv_ssl_flag(ctx, PP2_CLIENT_CERT_CONN);
+}
+
+/* return come from SSL_get_verify_result */
+VCL_INT v_matchproto_(td_proxy_ssl_verify_result)
+vmod_ssl_verify_result(VRT_CTX)
+{
+ struct pp2_tlv_ssl *dst;
+ int len;
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+ if (VPX_tlv(ctx->req, PP2_TYPE_SSL, (void **)&dst, &len))
+ return (0); /* X509_V_OK */
+
+ return (vbe32dec(&dst->verify));
+}
+
+static VCL_STRING
+tlv_string(VRT_CTX, int tlv)
+{
+ char *dst, *d;
+ int len;
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+ if (VPX_tlv(ctx->req, tlv, (void **)&dst, &len))
+ return (NULL);
+ if (!WS_Reserve(ctx->ws, len+1))
+ return (NULL);
+ d = ctx->ws->f;
+ memcpy(d, dst, len);
+ d[len] = '\0';
+ WS_Release(ctx->ws, len+1);
+ return (d);
+}
+
+VCL_STRING v_matchproto_(td_proxy_alpn)
+vmod_alpn(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_TYPE_ALPN);
+}
+
+VCL_STRING v_matchproto_(td_proxy_authority)
+vmod_authority(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_TYPE_AUTHORITY);
+}
+
+VCL_STRING v_matchproto_(td_proxy_ssl_version)
+vmod_ssl_version(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_SUBTYPE_SSL_VERSION);
+}
+
+VCL_STRING v_matchproto_(td_proxy_ssl_cipher)
+vmod_ssl_cipher(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_SUBTYPE_SSL_CIPHER);
+}
+
+VCL_STRING v_matchproto_(td_proxy_cert_sign)
+vmod_cert_sign(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_SUBTYPE_SSL_SIG_ALG);
+}
+
+VCL_STRING v_matchproto_(td_proxy_cert_key)
+vmod_cert_key(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_SUBTYPE_SSL_KEY_ALG);
+}
+
+VCL_STRING v_matchproto_(td_proxy_client_cert_cn)
+vmod_client_cert_cn(VRT_CTX)
+{
+ return tlv_string(ctx, PP2_SUBTYPE_SSL_CN);
+}
diff --git a/man/Makefile.am b/man/Makefile.am
index e7c00df..0e35dc5 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -20,7 +20,8 @@ dist_man_MANS = \
vmod_std.3 \
vmod_vtc.3 \
vmod_blob.3 \
- vmod_unix.3
+ vmod_unix.3 \
+ vmod_proxy.3
CLEANFILES = $(dist_man_MANS)
@@ -105,4 +106,7 @@ vmod_blob.3: $(top_builddir)/lib/libvmod_blob/vmod_blob.man.rst
vmod_unix.3: $(top_builddir)/lib/libvmod_unix/vmod_unix.man.rst
${RST2MAN} $(RST2ANY_FLAGS) $? $@
+vmod_proxy.3: $(top_builddir)/lib/libvmod_proxy/vmod_proxy.man.rst
+ ${RST2MAN} $(RST2ANY_FLAGS) $? $@
+
.NOPATH: $(dist_man_MANS)
More information about the varnish-commit
mailing list