Skip to content

Commit b757688

Browse files
authored
Add maxmind acl plugin (#6980)
Add maxmind acl plugin This plugin is similar to the current geoip acl plugin however it is based on the libmaxminddb library. The GeoIP library is considered legacy at this point and it only supports the old dat formatted databases. This will work with the newer more common mmdb format. It takes a yaml formatted configuration file as shown in the docs, which specifies the database to use for that remap, and then any sets of allow and deny rules. Currently the only rules supported are `country`,`ip`, and `regex`. Deny rules will always take precedence if both allow and deny rules are set, and in the case of having both sets of rules or only allow rules the default action is to deny a connection. However if no accept rules are specified then the default action will flip to always allow, since it doesnt make much sense to leave it as blocking everything if you only want to deny. In that case all connections are allowed except those that fall into one of the deny rules.
1 parent 744e02e commit b757688

File tree

8 files changed

+890
-0
lines changed

8 files changed

+890
-0
lines changed

configure.ac

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,6 +1685,21 @@ AC_CHECK_HEADERS([GeoIP.h], [
16851685
])
16861686
])
16871687

1688+
#
1689+
# Check for libmaxmind. This is the maxmind v2 API where GeoIP is the legacy
1690+
# v1 dat file based API
1691+
#
1692+
AC_CHECK_HEADERS([maxminddb.h], [
1693+
AC_CHECK_LIB([maxminddb], [MMDB_open], [
1694+
AC_SUBST([MAXMINDDB_LIBS], ["-lmaxminddb"])
1695+
AC_SUBST(has_maxmind, 1)
1696+
], [
1697+
AC_SUBST([MAXMINDDB_LIBS], [""])
1698+
AC_SUBST(has_maxmind, 0)
1699+
])
1700+
])
1701+
1702+
AM_CONDITIONAL([BUILD_MAXMIND_ACL_PLUGIN], [test "x${has_maxmind}" = "x1" ])
16881703

16891704
# Right now, the healthcheck plugins requires inotify_init (and friends)
16901705
AM_CONDITIONAL([BUILD_HEALTHCHECK_PLUGIN], [ test "$ac_cv_func_inotify_init" = "yes" ])

doc/admin-guide/plugins/index.en.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ directory of the |TS| source tree. Experimental plugins can be compiled by passi
156156
Hook Trace <hook-trace.en>
157157
ICAP <icap.en>
158158
JA3 Fingerprint <ja3_fingerprint.en>
159+
Maxmind ACL <maxmind_acl.en>
159160
Memcache <memcache.en>
160161
Metalink <metalink.en>
161162
Money Trace <money_trace.en>
@@ -199,6 +200,9 @@ directory of the |TS| source tree. Experimental plugins can be compiled by passi
199200
:doc:`JA3 Fingerprint <ja3_fingerprint.en>`
200201
Calculates JA3 Fingerprints for incoming SSL traffic.
201202

203+
:doc:`MaxMind ACL <maxmind_acl.en>`
204+
ACL based on the maxmind geo databases (GeoIP2 mmdb and libmaxminddb)
205+
202206
:doc:`Memcache <memcache.en>`
203207
Implements the memcache protocol for cache contents.
204208

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
.. _admin-plugins-maxmind-acl:
2+
3+
MaxMind ACL Plugin
4+
******************
5+
6+
.. Licensed to the Apache Software Foundation (ASF) under one
7+
or more contributor license agreements. See the NOTICE file
8+
distributed with this work for additional information
9+
regarding copyright ownership. The ASF licenses this file
10+
to you under the Apache License, Version 2.0 (the
11+
"License"); you may not use this file except in compliance
12+
with the License. You may obtain a copy of the License at
13+
14+
http://www.apache.org/licenses/LICENSE-2.0
15+
16+
Unless required by applicable law or agreed to in writing,
17+
software distributed under the License is distributed on an
18+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19+
KIND, either express or implied. See the License for the
20+
specific language governing permissions and limitations
21+
under the License.
22+
23+
This remap plugin provides allow and deny functionality based on the libmaxminddb
24+
library and GeoIP2 databases (mmdb format). It requires libmaxminddb to run
25+
and the associated development headers in order to build. You can find a sample
26+
mmdb-lite database on the maxmind website or provide your own. You must provide a database
27+
for any usages and specify it in the configuration file as shown below.
28+
29+
Configuration
30+
=============
31+
32+
The plugin takes a single pparam which is the location of the configuration yaml
33+
file. This can either be relative to the ATS configuration directory or an absolute path ::
34+
35+
map http://example.com/music http://music.example.com @plugin=maxmind_acl.so @pparam=maxmind.yaml
36+
37+
An example configuration ::
38+
39+
maxmind:
40+
database: GeoIP2-City.mmdb
41+
html: deny.html
42+
allow:
43+
country:
44+
- US
45+
ip:
46+
- 127.0.0.1
47+
- 192.168.10.0/20
48+
deny:
49+
country:
50+
- DE
51+
ip:
52+
- 127.0.0.1
53+
regex:
54+
- [US, ".*\\.txt"] # Because these get parsed you must escape the escape of the ``.`` in order to have it be escaped in the regex, resulting in ".*\.txt"
55+
- [US, ".*\\.mp3"]
56+
57+
In order to load an updated configuration while ATS is running you will have to touch or modify the remap.config file in order to initiate a plugin reload to pull in any changes.
58+
59+
Rules
60+
=====
61+
62+
You can mix and match the allow rules and deny rules, however deny rules will always take precedence so in the above case ``127.0.0.1`` would be denied.
63+
The IP rules can take either single IPs or cidr formatted rules. It will also accept IPv6 IP and ranges.
64+
65+
The regex portion can be added to both the allow and deny sections for creating allowable or denyable regexes. Each regex takes a country code first and a regex second.
66+
In the above example all requests from the US would be allowed except for those on ``txt`` and ``mp3`` files. More rules should be added as pairs, not as additions to existing lists.
67+
68+
Currently the only rules available are ``country``, ``ip``, and ``regex``, though more can easily be added if needed. Each config file does require a top level
69+
``maxmind`` entry as well as a ``database`` entry for the IP lookups. You can supply a separate database for each remap used in case you use custom
70+
ones and have specific needs per remap.
71+
72+
One other thing to note. You can reverse the logic of the plugin, so that it will default to always allowing if you do not supply any ``allow`` rules.
73+
In the case you supply no allow rules all connections will be allowed through except those that fall in to any of the deny rule lists. In the above example
74+
the rule of denying ``DE`` would be a noop because there are allow rules set, so by default everything is blocked unless it is explicitly in an allow rule.
75+
However in this case the regexes would still apply since they are based on an allowable country.
76+
77+
Optional
78+
========
79+
80+
There is an optional ``html`` field which takes a html file that will be used as the body of the response for any denied requests if you wish to use a custom one.

plugins/Makefile.am

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ include experimental/header_freq/Makefile.inc
6969
include experimental/hook-trace/Makefile.inc
7070
include experimental/icap/Makefile.inc
7171
include experimental/inliner/Makefile.inc
72+
73+
if BUILD_MAXMIND_ACL_PLUGIN
74+
include experimental/maxmind_acl/Makefile.inc
75+
endif
76+
7277
include experimental/memcache/Makefile.inc
7378
include experimental/metalink/Makefile.inc
7479
include experimental/money_trace/Makefile.inc
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
pkglib_LTLIBRARIES += experimental/maxmind_acl/maxmind_acl.la
18+
19+
experimental_maxmind_acl_maxmind_acl_la_SOURCES = \
20+
experimental/maxmind_acl/maxmind_acl.cc \
21+
experimental/maxmind_acl/mmdb.cc
22+
23+
experimental_maxmind_acl_maxmind_acl_la_LIBADD = $(MAXMINDDB_LIBS)
24+
25+
experimental_maxmind_acl_maxmind_acl_la_LDFLAGS = \
26+
$(AM_LDFLAGS)
27+
28+
AM_CPPFLAGS += @YAMLCPP_INCLUDES@
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
#include "mmdb.h"
20+
21+
///////////////////////////////////////////////////////////////////////////////
22+
// Initialize the plugin as a remap plugin.
23+
//
24+
TSReturnCode
25+
TSRemapInit(TSRemapInterface *api_info, char *errbuf, int errbuf_size)
26+
{
27+
if (api_info->size < sizeof(TSRemapInterface)) {
28+
strncpy(errbuf, "[tsremap_init] - Incorrect size of TSRemapInterface structure", errbuf_size - 1);
29+
return TS_ERROR;
30+
}
31+
32+
if (api_info->tsremap_version < TSREMAP_VERSION) {
33+
snprintf(errbuf, errbuf_size, "[tsremap_init] - Incorrect API version %ld.%ld", api_info->tsremap_version >> 16,
34+
(api_info->tsremap_version & 0xffff));
35+
return TS_ERROR;
36+
}
37+
38+
TSDebug(PLUGIN_NAME, "remap plugin is successfully initialized");
39+
return TS_SUCCESS;
40+
}
41+
42+
TSReturnCode
43+
TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf */, int /* errbuf_size */)
44+
{
45+
if (argc < 3) {
46+
TSError("[%s] Unable to create remap instance, missing configuration file", PLUGIN_NAME);
47+
return TS_ERROR;
48+
}
49+
50+
Acl *a = new Acl();
51+
*ih = static_cast<void *>(a);
52+
if (!a->init(argv[2])) {
53+
TSError("[%s] Failed to initialize maxmind with %s", PLUGIN_NAME, argv[2]);
54+
return TS_ERROR;
55+
}
56+
57+
TSDebug(PLUGIN_NAME, "created remap instance with configuration %s", argv[2]);
58+
return TS_SUCCESS;
59+
}
60+
61+
void
62+
TSRemapDeleteInstance(void *ih)
63+
{
64+
if (nullptr != ih) {
65+
Acl *const a = static_cast<Acl *>(ih);
66+
delete a;
67+
}
68+
}
69+
70+
///////////////////////////////////////////////////////////////////////////////
71+
// Main entry point when used as a remap plugin.
72+
//
73+
TSRemapStatus
74+
TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo *rri)
75+
{
76+
if (nullptr == ih) {
77+
TSDebug(PLUGIN_NAME, "No ACLs configured");
78+
} else {
79+
Acl *a = static_cast<Acl *>(ih);
80+
if (!a->eval(rri, rh)) {
81+
TSDebug(PLUGIN_NAME, "denying request");
82+
TSHttpTxnStatusSet(rh, TS_HTTP_STATUS_FORBIDDEN);
83+
a->send_html(rh);
84+
}
85+
}
86+
return TSREMAP_NO_REMAP;
87+
}

0 commit comments

Comments
 (0)