From 7135a6e42dbc3960d4813cf7a70779f42d9afa83 Mon Sep 17 00:00:00 2001 From: Firstyear Date: Thu, 2 Jan 2020 18:54:50 +1100 Subject: [PATCH] Attempted to add caching but it failed, improve usage (#162) --- .dockerignore | 1 - kanidm_book/src/installing_the_server.md | 2 +- kanidm_book/src/radius.md | 7 +- kanidm_rlm_python/Dockerfile | 4 +- kanidm_rlm_python/cache | 133 +++++++++++++++++++++++ kanidm_rlm_python/default | 11 +- kanidm_rlm_python/entrypoint.py | 4 +- kanidm_rlm_python/inner-tunnel | 11 +- kanidm_rlm_python/kanidmradius.py | 10 +- kanidmd/Dockerfile | 13 ++- 10 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 kanidm_rlm_python/cache diff --git a/.dockerignore b/.dockerignore index a2350ff47..a7a514da5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,5 +2,4 @@ target .git .gitignore test.db -vendor diff --git a/kanidm_book/src/installing_the_server.md b/kanidm_book/src/installing_the_server.md index d7ade733b..cadc78286 100644 --- a/kanidm_book/src/installing_the_server.md +++ b/kanidm_book/src/installing_the_server.md @@ -27,5 +27,5 @@ You then want to set your domain name so that spn's are generated correctly. Now we can run the server so that it can accept connections. - docker run -p 8443:8443 -v /Users/william/development/rsidm/insecure:/data firstyear/kanidmd:latest + docker run -p 8443:8443 -v kanidmd:/data firstyear/kanidmd:latest diff --git a/kanidm_book/src/radius.md b/kanidm_book/src/radius.md index 4cd8b6b3c..13a7d8de3 100644 --- a/kanidm_book/src/radius.md +++ b/kanidm_book/src/radius.md @@ -157,7 +157,7 @@ A fully configured example is: You can then run the container with: - docker run --name radiusd -i -t -v ...:/data firstyear/kanidm_radius:latest + docker run --name radiusd -v ...:/data firstyear/kanidm_radius:latest Authentication can be tested through the client.localhost nas configuration with: @@ -173,7 +173,10 @@ Finally, to expose this to a wifi infrastructure, add your NAS in config.ini: And re-create/run your docker instance with `-p 1812:1812 -p 1812:1812/udp` ... If you have any issues, check the logs from the radius output they tend to indicate the cause -of the problem. +of the problem. To increase the logging you can re-run your environment with debug enabled: + + docker rm radiusd + docker run --name radiusd -e DEBUG=True -i -t -v ...:/data firstyear/kanidm_radius:latest Note the radius container *is* configured to provide Tunnel-Private-Group-ID so if you wish to use wifi assigned vlans on your infrastructure, you can assign these by groups in the config.ini as diff --git a/kanidm_rlm_python/Dockerfile b/kanidm_rlm_python/Dockerfile index 08cec13ff..cf346d5bb 100644 --- a/kanidm_rlm_python/Dockerfile +++ b/kanidm_rlm_python/Dockerfile @@ -15,11 +15,13 @@ COPY entrypoint.py /entrypoint.py # Copy in the python changes, as well as the default/inner-tunnel changes COPY mod-python /etc/raddb/mods-available/python COPY eap /etc/raddb/mods-available/eap +COPY cache /etc/raddb/mods-available/cache COPY default /etc/raddb/sites-available/default COPY inner-tunnel /etc/raddb/sites-available/inner-tunnel -# Enable the python module. +# Enable the python and cache module. RUN ln -s ../mods-available/python /etc/raddb/mods-enabled/python +# RUN ln -s ../mods-available/cache /etc/raddb/mods-enabled/cache # Allows radiusd (?) to write to the directory RUN chown -R radiusd: /etc/raddb && \ diff --git a/kanidm_rlm_python/cache b/kanidm_rlm_python/cache new file mode 100644 index 000000000..95526efd0 --- /dev/null +++ b/kanidm_rlm_python/cache @@ -0,0 +1,133 @@ +# -*- text -*- +# +# $Id: 8bd4730cf570fdfedc9c516dc6974eab39981600 $ + +# +# A module to cache attributes. The idea is that you can look +# up information in a database, and then cache it. Repeated +# requests for the same information will then have the cached +# values added to the request. +# +# The module can cache a fixed set of attributes per key. +# It can be listed in "authorize", "post-auth", "pre-proxy" +# and "post-proxy". +# +# If you want different things cached for authorize and post-auth, +# you will need to define two instances of the "cache" module. +# +# The module returns "ok" if it found or created a cache entry. +# The module returns "updated" if it merged a cached entry. +# The module returns "noop" if it did nothing. +# The module returns "fail" on error. +# +cache { + # The backend datastore used to store the cache entries. + # Current datastores are + # rlm_cache_rbtree - An in memory, non persistent rbtree based datastore. + # Useful for caching data locally. + # rlm_cache_memcached - A non persistent "webscale" distributed datastore. + # Useful if the cached data need to be shared between + # a cluster of RADIUS servers. + driver = "rlm_cache_rbtree" + + # + # Some drivers accept specific options, to set them a + # config section with the the name as the driver should be added + # to the cache instance. + # + # Driver specific options are: + # +# memcached { +# # Memcached configuration options, as documented here: +# # http://docs.libmemcached.org/libmemcached_configuration.html#memcached +# options = "--SERVER=localhost" +# +# pool { +# start = ${thread[pool].start_servers} +# min = ${thread[pool].min_spare_servers} +# max = ${thread[pool].max_servers} +# spare = ${thread[pool].max_spare_servers} +# uses = 0 +# lifetime = 0 +# idle_timeout = 60 +# } +# } + + # The key used to index the cache. It is dynamically expanded + # at run time. + key = "%{User-Name}" + + # The TTL of cache entries, in seconds. Entries older than this + # will be expired. + # + # This value should be between 10 and 86400. + ttl = 10 + + # If yes the following attributes will be added to the request: + # * &request:Cache-Entry-Hits - The number of times this entry + # has been retrieved. + # + # Note: Not supported by the rlm_cache_memcached module. + add_stats = no + + # + # The list of attributes to cache for a particular key. + # + # Each key gets the same set of cached attributes. The attributes + # are dynamically expanded at run time. + # + # The semantics of this construct are identical to an unlang + # update block, except the left hand side of the expression + # represents the cache entry. see man unlang for more information + # on update blocks. + # + # Note: Only request, reply, control and session-state lists + # are available in cache entries. Attempting to store attributes + # in other lists will raise an error during config validation. + # + update { + # : + + # Cache all instances of Reply-Message in the reply list + &reply:Reply-Message += &reply:Reply-Message[*] + + # Add our own to show when the cache was last updated + &reply:Reply-Message += "Cache last updated at %t" + + &reply:Class := "%{randstr:ssssssssssssssssssssssssssssssss}" + + } + + # This module supports a number of runtime configuration parameters + # represented by attributes in the &control: list. + # + # &control:Cache-TTL - Sets the TTL of an entry to be created, or + # modifies the TTL of an existing entry. + # - Setting a Cache-TTL of > 0 means set the TTL of the entry to + # the new value (and reset the expiry timer). + # - Setting a Cache-TTL of < 0 means expire the existing entry + # (without merging) and create a new one with TTL set to + # value * -1. + # - Setting a Cache-TTL of 0 means expire the existing entry + # (without merging) and don't create a new one. + # + # &control:Cache-Status-Only - If present and set to 'yes' will + # prevent a new entry from being created, and existing entries from + # being merged. It will also alter the module's return codes. + # - The module will return "ok" if a cache entry was found. + # - The module will return "notfound" if no cache entry was found. + # + # &control:Cache-Read-Only - If present and set to 'yes' will + # prevent a new entry from being created, but will allow existing + # entries to be merged. It will also alter the module's return codes. + # - The module will return "updated" if a cache entry was found. + # - The module will return "notfound" if no cache was found. + # + # &control:Cache-Merge - If present and set to 'yes' will merge new + # cache entries into the current request. Useful if results + # of execs or expansions are stored directly in the cache. + # + # All runtime configuration attributes will be removed from the + # &control: list after the cache module is called. + +} diff --git a/kanidm_rlm_python/default b/kanidm_rlm_python/default index 293d9b847..ecdc0c943 100644 --- a/kanidm_rlm_python/default +++ b/kanidm_rlm_python/default @@ -421,7 +421,16 @@ authorize { # The ldap module reads passwords from the LDAP database. -ldap - python + # update control { + # Cache-Status-Only = 'yes' + # } + # cache + # if (notfound) { + # python + # } + # cache + + python # # Enforce daily limits on time spent logged in. diff --git a/kanidm_rlm_python/entrypoint.py b/kanidm_rlm_python/entrypoint.py index fd3f8ec1e..058cd9a17 100644 --- a/kanidm_rlm_python/entrypoint.py +++ b/kanidm_rlm_python/entrypoint.py @@ -13,7 +13,9 @@ if MAJOR >= 3: else: import ConfigParser as configparser -DEBUG = True +DEBUG = False +if os.environ.get('DEBUG', False): + DEBUG = True CONFIG = configparser.ConfigParser() CONFIG.read('/data/config.ini') diff --git a/kanidm_rlm_python/inner-tunnel b/kanidm_rlm_python/inner-tunnel index 159cf581b..9e3fa4baa 100644 --- a/kanidm_rlm_python/inner-tunnel +++ b/kanidm_rlm_python/inner-tunnel @@ -153,7 +153,16 @@ authorize { # The ldap module reads passwords from the LDAP database. -ldap - python + # update control { + # Cache-Status-Only = 'yes' + # } + # cache + # if (notfound) { + # python + # } + # cache + + python # # Enforce daily limits on time spent logged in. diff --git a/kanidm_rlm_python/kanidmradius.py b/kanidm_rlm_python/kanidmradius.py index 583727fcd..58910901f 100644 --- a/kanidm_rlm_python/kanidmradius.py +++ b/kanidm_rlm_python/kanidmradius.py @@ -79,7 +79,7 @@ def authorize(args): radiusd.radlog(radiusd.L_INFO, 'kanidm python module called') dargs = dict(args) - print(dargs) + # print(dargs) username = dargs['User-Name'] @@ -89,7 +89,7 @@ def authorize(args): print(e) return radiusd.RLM_MODULE_NOTFOUND - print("got token %s" % tok) + # print("got token %s" % tok) # Are they in the required group? @@ -97,13 +97,13 @@ def authorize(args): for group in tok["groups"]: if group['name'] == REQ_GROUP: req_sat = True - print("required group satisfied -> %s" % req_sat) + print("required group satisfied -> %s:%s" % (username, req_sat)) if req_sat is not True: return radiusd.RLM_MODULE_NOTFOUND # look up them in config for group vlan if possible. uservlan = reduce(check_vlan, tok["groups"], 0) - print("selected vlan %s" % uservlan) + print("selected vlan %s:%s" % (username, uservlan)) # Convert the tok groups to groups. name = tok["name"] secret = tok["secret"] @@ -119,7 +119,7 @@ def authorize(args): ('Cleartext-Password', str(secret)), ) - print("OK! Returning details to radius ...") + print("OK! Returning details to radius for %s ..." % username) return (radiusd.RLM_MODULE_OK, reply, config) diff --git a/kanidmd/Dockerfile b/kanidmd/Dockerfile index 7cf5ad8e2..a48fdd50c 100644 --- a/kanidmd/Dockerfile +++ b/kanidmd/Dockerfile @@ -1,14 +1,21 @@ FROM opensuse/tumbleweed:latest AS builder MAINTAINER william@blackhats.net.au -RUN zypper install -y timezone cargo rust gcc sqlite3-devel libopenssl-devel +RUN zypper mr -d repo-non-oss && \ + zypper mr -d repo-oss && \ + zypper mr -d repo-update && \ + zypper ar https://download.opensuse.org/update/tumbleweed/ repo-update-https && \ + zypper ar https://download.opensuse.org/tumbleweed/repo/oss/ repo-oss-https && \ + zypper ar https://download.opensuse.org/tumbleweed/repo/non-oss/ repo-non-oss-https && \ + zypper install -y timezone cargo rust gcc sqlite3-devel libopenssl-devel COPY . /home/kanidm/ WORKDIR /home/kanidm/ RUN cargo build --release +# == end builder setup, we now have static artifacts. FROM opensuse/tumbleweed:latest -EXPOSE 8080 +EXPOSE 8443 WORKDIR / COPY --from=builder /home/kanidm/target/release/kanidmd /sbin/ RUN zypper install -y sqlite3 openssl @@ -16,5 +23,5 @@ RUN zypper install -y sqlite3 openssl VOLUME /data ENV RUST_BACKTRACE 1 -CMD ["/sbin/kanidmd", "server", "-D", "/data/kanidm.db", "-C", "/data/ca.pem", "-c", "/data/cert.pem", "-k", "/data/key.pem", "--bindaddr", "0.0.0.0:8080"] +CMD ["/sbin/kanidmd", "server", "-D", "/data/kanidm.db", "-C", "/data/ca.pem", "-c", "/data/cert.pem", "-k", "/data/key.pem", "--bindaddr", "0.0.0.0:8443"]