From 4466d2ec250322c1b603d041703259586e213b22 Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Sun, 2 Jan 2022 12:16:53 +1100 Subject: [PATCH] introduce deplyoment config --- command.lsp | 40 +++++++++++++++++++++++++++++++++ control-logic.lsp | 19 +++++++++------- control.dat | 3 +-- hourglass.conf | 21 +++++++++++++++++ howto.adoc | 7 ++++++ ipset-control.lsp | 4 ++-- listener.lsp | 20 ++++++++++------- manager/basic_login.lsp | 10 ++++----- manager/install.lsp | 2 +- manager/tmpl/controls-form.html | 4 ---- run-manager.sh | 2 +- setup.sh | 12 ++++++---- 12 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 hourglass.conf diff --git a/command.lsp b/command.lsp index 3e5094c..8751fc3 100644 --- a/command.lsp +++ b/command.lsp @@ -2,6 +2,46 @@ # This script is intended as main script for packnl embedding, it # dispatches to the command of the first argument. +(context 'MAIN:SITE) + +(define (set-int K V) (set K (int V 0 10))) + +(define (set-ints K V) + (map (curry set-int K) (clean empty? (parse V "\\s*,?\\s*" 0)))) + +(define (set-list K V) + (map (curry set K) (clean empty? (parse V "\\s*,?\\s*" 0)))) + +(constant + 'FILE "hourglass.conf" + 'KEYS '( + ("libc" set) + ("listener.ports" set-ints) + ("listener.ip" set) + ("listener.activity.dir" set) + ("control.action" set) + ("control.dat" set) + ("control.net" set) + ("control.extra.dat" set) + ("control.usage.dat" set) + ("control.usage.tmp" set) + + ("wui.port" set-int) + ("wui.roles" set) + ("wui.passwd" set) + ) + ) + +(define (setting LINE) + (when (regex "^\\s([^;#][^=]*)=(.*)" LINE 0) + (let ((KV (map trim (list $1 $2)))) + (if (lookup (KV 0) KEYS) (apply $it (list (sym (KV 0)) (KV 1))))))) + +(map setting (parse (or (read-file FILE) "") "\n")) + +#################### +(context MAIN) + (if (exists file? (list (main-args 1) (string (main-args 1) ".lsp"))) (load $it) diff --git a/control-logic.lsp b/control-logic.lsp index c842c06..d75a913 100644 --- a/control-logic.lsp +++ b/control-logic.lsp @@ -9,7 +9,14 @@ (write-line 2 (join (map string args))) (exit 1)) -(constant 'NOW (date-value)) +(constant + 'NOW (date-value) + 'ACTDIR SITE:listener.activity.dir + 'CONTROL.DAT SITE:control.dat + 'EXTRA.DAT SITE:control.extra.dat + 'USAGE.DAT SITE:usage.dat + 'USAGE.TMP SITE:usage.tmp + ) # Set current time variables in local timezone (map set '(YEAR MONTH DATE HOUR MINUTE SECOND DOY DOW) @@ -20,10 +27,6 @@ DAY (list YEAR MONTH DATE) HM (list HOUR MINUTE) TOTAL '() - CONTROL.DAT "control.dat" - EXTRA.DAT "control-extra.dat" - USAGE.DAT "usage.dat" - USAGE.TMP ".usage.dat" ) # Load CONTROL.DAT @@ -40,7 +43,6 @@ (setf GAP (or (lookup 'gap CONTROL) 15) CLIP (or (lookup 'clip CONTROL) 1000) - NET (or (lookup 'net CONTROL) "10.0.0.0/8") ) # Load the configured control mechanism @@ -67,15 +69,16 @@ ;;==== Utilities for activity data # Activity is lines of timestamps. Collect TOTAL as list of unique # time values (H M) within the start-end time span. + (define (log-name-fmt t) (format "%d%02d%02d-.*\\.dat" (0 3 (date-list t)))) (define (log-lines f) - (find-all "([0-9]+( \\S+)?).*" (read-file (string "activity/" f)) $1 0)) + (find-all "([0-9]+( \\S+)?).*" (read-file (format "%s/%s" ACTDIR f)) $1 0)) # Collect all timestamps of the UTC date of the given time stamp (define (logs t) - (flat (map log-lines (directory "activity" (log-name-fmt t))))) + (flat (map log-lines (directory ACTDIR (log-name-fmt t))))) # Translate timestamp into its local time (hour minute), if it's # within the applicable day, null otherwise. diff --git a/control.dat b/control.dat index 3eda9d4..551e938 100644 --- a/control.dat +++ b/control.dat @@ -1,6 +1,5 @@ ; Updated at Sun Aug 8 22:53:01 2021 -((control "ipset-control.lsp") - (net "192.168.104.0/24") +((net "192.168.104.0/24") (gap 10) (clip 1000) (1 timed (5 30) (2 0) (20 0)) diff --git a/hourglass.conf b/hourglass.conf new file mode 100644 index 0000000..c424ffb --- /dev/null +++ b/hourglass.conf @@ -0,0 +1,21 @@ +; Hourglass site configuration +libc = /lib/x86_64-linux-gnu/libc.so.6 + +listener.net = 192.168.255 +listener.ports = 80 443 +listener.activity.dir = activity +listener.tap = hourglass +listener.tundev = /dev/net/tun + +control.action = ipset-control.lsp +control.dat = control.dat +control.net = 10.0.0.0/8 +control.extra.dat = control-extra.dat +control.usage.dat = usage.dat +control.usage.tmp = .usage.dat + +ipset.bin = /sbin/ipset +ipset.table = TIMO + +wui.port = 1070 +wui.passwd = .htpassswd diff --git a/howto.adoc b/howto.adoc index e0c25cf..fea2a54 100644 --- a/howto.adoc +++ b/howto.adoc @@ -30,6 +30,13 @@ control policy, held in the +control.dat+ file, as well as the control override setting, in file +control-extra.dat+, whilst also showing current usage measure from file +usage.dat+. +The server +hourglass-web+ is first installed with +---- +$ ./hourglass-web install +---- +That installation sets up a small +www+ sub directory with "CGI" +scripting to provide the Hourglass User Interface on port 1070. + Hourglass Network Traffic Capture --------------------------------- diff --git a/ipset-control.lsp b/ipset-control.lsp index 899e37a..cd81384 100644 --- a/ipset-control.lsp +++ b/ipset-control.lsp @@ -1,10 +1,10 @@ # Should load from "ipset.cfg" -(constant 'IPSET "/sbin/ipset" 'TABLE "TIMO" ) +(constant 'IPSET SITE:ipset.bin 'TABLE SITE:ipset.table NET SITE:control.net) ;; Return current low-leve "close" or "open" status (define (current-status) - (if (exec (format "%s list %s | grep %s" IPSET TABLE NET)) "close" "open")) + (if (member NET (exec (format "%s list %s" IPSET TABLE))) "close" "open")) ;; Ensure low-level setting is "close" or "open" as given (define (control cmd reason) diff --git a/listener.lsp b/listener.lsp index bd823f2..ceefed4 100644 --- a/listener.lsp +++ b/listener.lsp @@ -11,9 +11,7 @@ (signal 2 (fn (x) (exit 0))) # The following is for Devuan GNU+Linux -(constant 'LIBC (exists file? '("/lib/x86_64-linux-gnu/libc.so.6" - "/lib/i386-linux-gnu/libc.so.6" - ))) +(constant 'LIBC SITE:libc) (import LIBC "ioctl" "int" "int" "long" "void*" ) (import LIBC "perror" "void" "char*" ) (import LIBC "ntohl" "int" "int" ) @@ -31,18 +29,23 @@ (if (null? a) v (nil? v) true (null? (1 a)) v (a 1)))) # Set logging mode. -(constant 'listener-log-ip (mainarg "-l" nil)) - # Open the tap named by "-t tapX" on the command line, or "tap0" byt # default. Then make a TUNSETIFF call to initialize it (as # IFF_TAP|IFF_NO_PI). -(constant 'IFNAME (mainarg "-t" "tap0") 'IFD (open "/dev/net/tun" "u") ) +(constant + 'listener-log-ip SITE:listener.ip + 'IFNAME SITE:listener.tap + 'PORTS SITE:listener.ports + 'IFD (open SITE:listener.tundev "u") + 'ACTNAMEFMT "%d%02d%02d-network.dat" + 'ACTDIR SITE:listener.activity.dir + 'ACTFILEFMT (format "%s/%s" ACTDIR ACTNAMEFMT ) +) (unless (number? IFD) (die "open")) (unless (zero? (ioctl IFD 0x400454ca (pack "s16 u s22" IFNAME 0x1002 ""))) (die (string "set " IFNAME))) # The TCP ports of interest -(constant 'PORTS '(80 443)) # Set up for optional tracking of IP addresses (define counter:counter nil) @@ -67,12 +70,13 @@ # This funcion collates all given ips, and it extends the log line # with the list of ips used during the minute. (setf next-mark 0 packet-count 0) + (define (mark-active t) ; buffer (when listener-log-ip (track-data)) (inc packet-count) ;(write-line 2 (string (list t packet-count ports (counter)))) (when (>= t next-mark) - (let ((d (format "activity/%d%02d%02d-network.dat" (0 3 (date-list t)))) + (let ((d (format ACTFILEFMT (0 3 (date-list t)))) (c (map string (counter)))) (append-file d (string t " " packet-count " " (join c " ") "\n")) (setf next-mark (+ t 60) packet-count 0) diff --git a/manager/basic_login.lsp b/manager/basic_login.lsp index 7231ef0..f491a9e 100644 --- a/manager/basic_login.lsp +++ b/manager/basic_login.lsp @@ -30,16 +30,14 @@ (write-line 1 (read-file "tmpl/unauthorized.http")) (exit 0)) -(define (role-script ROLE) +;; Determine actual script name respecting given role, if any. +(define (role-script (ROLE ".")) (let ((CMD (and (regex "([^/]*).cgi$" (main-args 0) 0) $1))) - (if (= "." ROLE) (string CMD ".lsp") - (format "%s/%s.lsp" ROLE CMD)))) + (if (= "." ROLE) (string CMD ".lsp") (format "%s/%s.lsp" ROLE CMD)))) (setf - ROLES (map (fn (x) (parse x ":")) (parse (read-file "roles.txt") "\n")) REMOTE_USER (and (regex "([^:]+):" (base64-dec (6 AUTH)) 0) $1) - ROLE (or (lookup REMOTE_USER ROLES) "child") - SCRIPT (role-script ROLE) + SCRIPT (role-script) ) (env "REMOTE_USER" REMOTE_USER) (env "ROLE" ROLE) diff --git a/manager/install.lsp b/manager/install.lsp index 6e234d2..c4193be 100644 --- a/manager/install.lsp +++ b/manager/install.lsp @@ -1,6 +1,6 @@ #!/usr/bin/newlisp # -# Install the Hourglass service to new directory www +# Install the Hourglass web tree to a new "www" subdirectory (when (directory? "www") (write-line 2 "** directory www exists. aborting") diff --git a/manager/tmpl/controls-form.html b/manager/tmpl/controls-form.html index 88dd6fa..84b2611 100644 --- a/manager/tmpl/controls-form.html +++ b/manager/tmpl/controls-form.html @@ -70,10 +70,6 @@ networks packets in a minute, to count as activity. -
- - controlled network. -
diff --git a/run-manager.sh b/run-manager.sh index a7b3c32..3e2690a 100755 --- a/run-manager.sh +++ b/run-manager.sh @@ -5,7 +5,7 @@ function die() { exit 1 } -SERVICE=manager/hourglass-web +SERVICE=hourglass-web [ -f "$SERVICE" ] || die "** missing $SERVICE ** aborting" diff --git a/setup.sh b/setup.sh index 3585d74..4cf7a80 100755 --- a/setup.sh +++ b/setup.sh @@ -3,10 +3,14 @@ # This is a control script to start and stop the network activity # listening. -CMD=${1-start} -NET=192.168.249 -TAP=hourglass0 -SET=TIMO +CONF="hourglass.conf" +function getcfg() { + grep -E "\\s*[^;#]$1]\\s*=" $CONF | sed 's/.*=\s*(.*)/\1/;s/\s*$//' +} + +NET="$(getcfg listener.ip)" +TAP="$(getcfg listener.tap)" +SET="$(getcfg ipset.table)" cd $(dirname $0) -- 2.39.2