Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-acltools
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
libvmod-acltools
Commits
72aef84f
Unverified
Commit
72aef84f
authored
Mar 31, 2023
by
Nils Goroll
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add minimum mask parameters and a real world example
parent
97344ac3
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
151 additions
and
14 deletions
+151
-14
Makefile.am
src/Makefile.am
+3
-2
vmod_acltools.c
src/vmod_acltools.c
+27
-3
vmod_acltools.man.rst
src/vmod_acltools.man.rst
+19
-6
vmod_acltools.vcc
src/vmod_acltools.vcc
+10
-3
vmod_acltools.vtc
src/vtc/vmod_acltools.vtc
+56
-0
vmod_acltools_checkmask.vtc
src/vtc/vmod_acltools_checkmask.vtc
+36
-0
No files found.
src/Makefile.am
View file @
72aef84f
...
@@ -19,13 +19,14 @@ AM_TESTS_ENVIRONMENT = \
...
@@ -19,13 +19,14 @@ AM_TESTS_ENVIRONMENT = \
PATH
=
"
$(abs_builddir)
:
$(VARNISH_TEST_PATH)
:
$(PATH)
"
\
PATH
=
"
$(abs_builddir)
:
$(VARNISH_TEST_PATH)
:
$(PATH)
"
\
LD_LIBRARY_PATH
=
"
$(VARNISH_LIBRARY_PATH)
"
LD_LIBRARY_PATH
=
"
$(VARNISH_LIBRARY_PATH)
"
TEST_EXTENSIONS
=
.vtc
TEST_EXTENSIONS
=
.vtc
VTC_LOG_COMPILER
=
varnishtest
-v
VTC_LOG_COMPILER
=
varnishtest
-
l
v
AM_VTC_LOG_FLAGS
=
\
AM_VTC_LOG_FLAGS
=
\
-p
vcl_path
=
"
$(abs_top_srcdir)
/vcl:
$(VARNISHAPI_VCLDIR)
"
\
-p
vcl_path
=
"
$(abs_top_srcdir)
/vcl:
$(VARNISHAPI_VCLDIR)
"
\
-p
vmod_path
=
"
$(abs_builddir)
/.libs:
$(vmoddir)
:
$(VARNISHAPI_VMODDIR)
"
-p
vmod_path
=
"
$(abs_builddir)
/.libs:
$(vmoddir)
:
$(VARNISHAPI_VMODDIR)
"
TESTS
=
\
TESTS
=
\
vtc/vmod_acltools.vtc
vtc/vmod_acltools.vtc
\
vtc/vmod_acltools_checkmask.vtc
# Documentation
# Documentation
...
...
src/vmod_acltools.c
View file @
72aef84f
...
@@ -123,12 +123,27 @@ vmod_dyn_single(VRT_CTX, struct VARGS(dyn_single)*args)
...
@@ -123,12 +123,27 @@ vmod_dyn_single(VRT_CTX, struct VARGS(dyn_single)*args)
unsigned
const
char
*
addr
;
unsigned
const
char
*
addr
;
struct
vmod_priv
*
priv_task
;
struct
vmod_priv
*
priv_task
;
unsigned
long
mask
=
ULONG_MAX
;
unsigned
long
mask
=
ULONG_MAX
;
unsigned
maxmask
;
unsigned
m
inmask
,
m
axmask
;
uintptr_t
sn
;
uintptr_t
sn
;
int
quot
=
0
;
int
quot
=
0
;
int
fam
;
int
fam
;
VCL_ACL
fb
;
VCL_ACL
fb
;
if
(
args
->
min_mask_ip4
<
0
||
args
->
min_mask_ip6
<
0
)
{
VRT_fail
(
ctx
,
"min_mask_* arguments must not be negative"
);
return
(
&
acl_fail
);
}
if
(
args
->
min_mask_ip4
>
32
)
{
VRT_fail
(
ctx
,
"min_mask_ip4 value too largs (%ld)"
,
args
->
min_mask_ip4
);
return
(
&
acl_fail
);
}
if
(
args
->
min_mask_ip6
>
128
)
{
VRT_fail
(
ctx
,
"min_mask_ip6 value too largs (%ld)"
,
args
->
min_mask_ip6
);
return
(
&
acl_fail
);
}
if
(
args
->
valid_fallback
&&
args
->
fallback
!=
NULL
&&
if
(
args
->
valid_fallback
&&
args
->
fallback
!=
NULL
&&
args
->
fallback
->
magic
==
VRT_ACL_MAGIC
)
args
->
fallback
->
magic
==
VRT_ACL_MAGIC
)
fb
=
args
->
fallback
;
fb
=
args
->
fallback
;
...
@@ -218,9 +233,11 @@ vmod_dyn_single(VRT_CTX, struct VARGS(dyn_single)*args)
...
@@ -218,9 +233,11 @@ vmod_dyn_single(VRT_CTX, struct VARGS(dyn_single)*args)
fam
=
VSA_GetPtr
(
vsa
,
&
addr
);
fam
=
VSA_GetPtr
(
vsa
,
&
addr
);
switch
(
fam
)
{
switch
(
fam
)
{
case
PF_INET
:
case
PF_INET
:
minmask
=
args
->
min_mask_ip4
;
maxmask
=
32
;
maxmask
=
32
;
break
;
break
;
case
PF_INET6
:
case
PF_INET6
:
minmask
=
args
->
min_mask_ip6
;
maxmask
=
128
;
maxmask
=
128
;
break
;
break
;
default:
default:
...
@@ -230,12 +247,19 @@ vmod_dyn_single(VRT_CTX, struct VARGS(dyn_single)*args)
...
@@ -230,12 +247,19 @@ vmod_dyn_single(VRT_CTX, struct VARGS(dyn_single)*args)
if
(
mask
==
ULONG_MAX
)
if
(
mask
==
ULONG_MAX
)
mask
=
maxmask
;
mask
=
maxmask
;
else
if
(
mask
>
maxmask
)
{
else
if
(
mask
>
maxmask
)
{
VSLb
(
ctx
->
vsl
,
SLT_Error
,
VSLb
(
ctx
->
vsl
,
SLT_Error
,
"acltools.dyn_single: "
"
acltools.dyn_single:
mask %lu too long for %s"
,
"mask %lu too long for %s"
,
mask
,
args
->
ipmask
);
mask
,
args
->
ipmask
);
WS_Reset
(
ctx
->
ws
,
sn
);
WS_Reset
(
ctx
->
ws
,
sn
);
return
(
fb
);
return
(
fb
);
}
}
else
if
(
mask
<
minmask
)
{
VSLb
(
ctx
->
vsl
,
SLT_Error
,
"acltools.dyn_single: "
"mask %lu shorter than minimum %d for %s"
,
mask
,
minmask
,
args
->
ipmask
);
WS_Reset
(
ctx
->
ws
,
sn
);
return
(
fb
);
}
ads
->
mask
=
mask
;
ads
->
mask
=
mask
;
ads
->
acl
.
magic
=
VRT_ACL_MAGIC
;
ads
->
acl
.
magic
=
VRT_ACL_MAGIC
;
...
...
src/vmod_acltools.man.rst
View file @
72aef84f
...
@@ -23,7 +23,7 @@ SYNOPSIS
...
@@ -23,7 +23,7 @@ SYNOPSIS
import acltools [as name] [from "path"]
import acltools [as name] [from "path"]
ACL dyn_single(STRING ipmask, [ACL fallback], BOOL resolve)
ACL dyn_single(STRING ipmask, [ACL fallback], BOOL resolve
, INT min_mask_ip4, INT min_mask_ip6
)
DESCRIPTION
DESCRIPTION
===========
===========
...
@@ -33,12 +33,18 @@ This vmod contains additional functions for Access Control Lists
...
@@ -33,12 +33,18 @@ This vmod contains additional functions for Access Control Lists
.. _acltools.dyn_single():
.. _acltools.dyn_single():
ACL dyn_single(STRING ipmask, [ACL fallback], BOOL resolve)
ACL dyn_single(STRING ipmask, [ACL fallback], BOOL resolve
, INT min_mask_ip4, INT min_mask_ip6
)
-----------------------------------------------------------
-----------------------------------------------------------
------------------------------------
::
::
ACL dyn_single(STRING ipmask, [ACL fallback], BOOL resolve=0)
ACL dyn_single(
STRING ipmask,
[ACL fallback],
BOOL resolve=0,
INT min_mask_ip4=0,
INT min_mask_ip6=0
)
Returns a dynamic ACL **for immediate use** (see **NOTE** below) with
Returns a dynamic ACL **for immediate use** (see **NOTE** below) with
a single entry constructed from the *ipmask* string, which must be of
a single entry constructed from the *ipmask* string, which must be of
...
@@ -54,8 +60,8 @@ or, for compatibility with built-in static ACLs::
...
@@ -54,8 +60,8 @@ or, for compatibility with built-in static ACLs::
*<ip>* undergoes the same parsing as the *s* argument of
*<ip>* undergoes the same parsing as the *s* argument of
`std.ip()`_. If *<ip>* is an IPv4 address, *<mask>*, if present, must
`std.ip()`_. If *<ip>* is an IPv4 address, *<mask>*, if present, must
be an integer between
0
and 32. If *<ip>* is an IPv6 address,
be an integer between
*min_mask_ip4*
and 32. If *<ip>* is an IPv6 address,
*<mask>*, if present, must be an integer between
0
and 128. If
*<mask>*, if present, must be an integer between
*min_mask_ip6*
and 128. If
*<mask>* is not present, it defaults to the maximum mask (32 or 128,
*<mask>* is not present, it defaults to the maximum mask (32 or 128,
respectively).
respectively).
...
@@ -67,6 +73,13 @@ fail.
...
@@ -67,6 +73,13 @@ fail.
If the *resolve* argument is ``true``, *<ip>* will be resolved as a
If the *resolve* argument is ``true``, *<ip>* will be resolved as a
DNS name.
DNS name.
*min_mask_ip4* must be an integer between 0 and 32, inclusively.
*min_mask_ip6* must be an integer between 0 and 128, inclusively.
For both *min_mask_* arguments, a VCL error is triggered if they are
out of range. Both default to zero.
Example
Example
::
::
...
...
src/vmod_acltools.vcc
View file @
72aef84f
...
@@ -7,7 +7,7 @@ This vmod contains additional functions for Access Control Lists
...
@@ -7,7 +7,7 @@ This vmod contains additional functions for Access Control Lists
(ACLs).
(ACLs).
$Function ACL dyn_single(STRING ipmask, [ACL fallback],
$Function ACL dyn_single(STRING ipmask, [ACL fallback],
BOOL resolve = 0)
BOOL resolve = 0
, INT min_mask_ip4 = 0, INT min_mask_ip6 = 0
)
Returns a dynamic ACL **for immediate use** (see **NOTE** below) with
Returns a dynamic ACL **for immediate use** (see **NOTE** below) with
a single entry constructed from the *ipmask* string, which must be of
a single entry constructed from the *ipmask* string, which must be of
...
@@ -23,8 +23,8 @@ or, for compatibility with built-in static ACLs::
...
@@ -23,8 +23,8 @@ or, for compatibility with built-in static ACLs::
*<ip>* undergoes the same parsing as the *s* argument of
*<ip>* undergoes the same parsing as the *s* argument of
`std.ip()`_. If *<ip>* is an IPv4 address, *<mask>*, if present, must
`std.ip()`_. If *<ip>* is an IPv4 address, *<mask>*, if present, must
be an integer between
0
and 32. If *<ip>* is an IPv6 address,
be an integer between
*min_mask_ip4*
and 32. If *<ip>* is an IPv6 address,
*<mask>*, if present, must be an integer between
0
and 128. If
*<mask>*, if present, must be an integer between
*min_mask_ip6*
and 128. If
*<mask>* is not present, it defaults to the maximum mask (32 or 128,
*<mask>* is not present, it defaults to the maximum mask (32 or 128,
respectively).
respectively).
...
@@ -36,6 +36,13 @@ fail.
...
@@ -36,6 +36,13 @@ fail.
If the *resolve* argument is ``true``, *<ip>* will be resolved as a
If the *resolve* argument is ``true``, *<ip>* will be resolved as a
DNS name.
DNS name.
*min_mask_ip4* must be an integer between 0 and 32, inclusively.
*min_mask_ip6* must be an integer between 0 and 128, inclusively.
For both *min_mask_* arguments, a VCL error is triggered if they are
out of range. Both default to zero.
Example
Example
::
::
...
...
src/vtc/vmod_acltools.vtc
View file @
72aef84f
...
@@ -24,7 +24,36 @@ varnish v1 -proto PROXY -vcl {
...
@@ -24,7 +24,36 @@ varnish v1 -proto PROXY -vcl {
} else {
} else {
return (synth(403, "denied"));
return (synth(403, "denied"));
}
}
} else if (req.url == "/cov4") {
if (client.ip ~ acltools.dyn_single(req.http.acl,
fallback=fallback, min_mask_ip4 = -1)) {
return (synth(200, "matched"));
} else {
return (synth(403, "denied"));
}
} else if (req.url == "/cov6") {
if (client.ip ~ acltools.dyn_single(req.http.acl,
fallback=fallback, min_mask_ip6 = -1)) {
return (synth(200, "matched"));
} else {
return (synth(403, "denied"));
}
} else if (req.url == "/cov4l") {
if (client.ip ~ acltools.dyn_single(req.http.acl,
fallback=fallback, min_mask_ip4 = 33)) {
return (synth(200, "matched"));
} else {
return (synth(403, "denied"));
}
} else if (req.url == "/cov6l") {
if (client.ip ~ acltools.dyn_single(req.http.acl,
fallback=fallback, min_mask_ip6 = 129)) {
return (synth(200, "matched"));
} else {
return (synth(403, "denied"));
}
}
}
return (synth(404));
return (synth(404));
}
}
} -start
} -start
...
@@ -242,8 +271,35 @@ client c3 -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828"
...
@@ -242,8 +271,35 @@ client c3 -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828"
expect resp.status == 403
expect resp.status == 403
} -start
} -start
client c4 -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828" {
txreq -url "/cov4"
rxresp
expect resp.status == 503
} -start
client c5 -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828" {
txreq -url "/cov6"
rxresp
expect resp.status == 503
} -start
client c6 -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828" {
txreq -url "/cov4l"
rxresp
expect resp.status == 503
} -start
client c7 -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828" {
txreq -url "/cov6l"
rxresp
expect resp.status == 503
} -start
client c1 -wait
client c1 -wait
client c2 -wait
client c2 -wait
client c3 -wait
client c3 -wait
client c4 -wait
client c5 -wait
client c6 -wait
client c7 -wait
logexpect l1 -wait
logexpect l1 -wait
logexpect l2 -wait
logexpect l2 -wait
\ No newline at end of file
src/vtc/vmod_acltools_checkmask.vtc
0 → 100644
View file @
72aef84f
varnishtest "acltools real world example: check with minimum mask"
# real world use case: we get a <net/mask> and an <ip> and want to
# check if <ip> is contained in <net/mask>, with a limit by protocol
varnish v1 -vcl {
import acltools;
import std;
backend none none;
sub vcl_recv {
if (std.ip(req.http.ip, "0.0.0.0", resolve=false) ~
acltools.dyn_single(req.http.net,
min_mask_ip4 = 24,
min_mask_ip6 = 40)) {
return (synth(200));
}
return (synth(403));
}
} -start
client c1 {
txreq -hdr "ip: 1.2.3.4" -hdr "net: 1.2.3.0/24"
rxresp
expect resp.status == 200
txreq -hdr "ip: 1.2.3.4" -hdr "net: 1.2.3.0/25"
rxresp
expect resp.status == 200
txreq -hdr "ip: 1.2.3.4" -hdr "net: 1.2.2.0/23"
rxresp
expect resp.status == 403
} -run
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment