blob: 6f782c14384ad1c65b25e98c0e81b27d6655e26a (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
(define-module (battering services opensnitch)
#:use-module (guix gexp)
#:use-module (guix records)
#:use-module (guix modules)
#:use-module (gnu services)
#:use-module (gnu services shepherd)
#:use-module (gnu services configuration)
#:use-module (gnu packages guile)
#:use-module (battering packages opensnitch)
#:use-module (srfi srfi-171)
#:export (opensnitch-configuration
serialize-json-configuration
opensnitch-service-type))
;; Turns lisp-case into PascalCase
(define (pascal-field-name field-name)
(apply
string-append
(map string-capitalize (string-tokenize
(format #f "~a" field-name)
char-set:letter))))
(define (serialize-field field-name val)
`(,(pascal-field-name field-name) . ,val))
(define serialize-boolean serialize-field)
(define (serialize-integer field-name val)
(let ((serialized (serialize-field field-name val)))
(if (eq? field-name 'workers)
`("Stats" ,serialized)
serialized)))
(define (serialize-string field-name val)
(let ((serialized (serialize-field field-name val)))
(if (eq? field-name 'address)
`("Server" ,serialized
;; LogFile should always be stdout because logging will be managed
;; by Shepherd
("LogFile" . "/dev/stdout"))
serialized)))
(define methods-list '(ftrace audit ebpf proc))
(define actions-list '(allow deny))
(define durations-list '(once until-restart forever))
(define (method? val)
(memq val methods-list))
(define (action? val)
(memq val actions-list))
(define (duration? val)
(memq val durations-list))
(define serialize-method serialize-field)
(define serialize-action serialize-field)
(define (serialize-duration field-name val)
(serialize-field
field-name
(string-join (string-split (format #f "~a" val) #\-))))
(define (serialize-json-configuration config fields)
"Return a G-expression that contains a json representation the values
corresponding to the FIELDS of CONFIG."
(with-extensions (list guile-json-4)
(with-imported-modules (source-module-closure '((json builder)))
#~(begin
(use-modules (json builder))
(scm->json
'#$(list-transduce (base-transducer config) rcons fields)
#:pretty #t)))))
(define-configuration opensnitch-configuration
(opensnitchd
(file-like opensnitchd)
"Opensnitchd package to use.")
(address
(string "unix:///tmp/osui.sock")
"Opensnitch UI socket path.")
(workers
(integer 6)
"Number of workers started by the daemon.")
(log-utc?
(boolean #t)
"Use UTC timestamps in event logging?")
(log-micro?
(boolean #f)
"Include microseconds in event timestamps?")
(log-level
(integer 2)
"Daemon log level.")
(process-monitor-method
(method 'proc)
"Process monitor method to use.")
(default-action
(action 'allow)
"Default action to take when the UI isn't connected.")
(default-duration
(duration 'once)
"Duration of the rules created automatically.")
(intercept-unknown?
(boolean #f)
"Intercept unknown network connections?")
(rules
(list '())
"List of rules to add in /etc/opensnitchd/rules."))
(define (opensnitch-activation config)
"Create the opensnitch rules and configuration according to CONFIG."
(match-record config <opensnitch-configuration> (opensnitchd)
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(when (not (file-exists? "/etc/opensnitchd"))
(mkdir-p "/etc/opensnitchd/rules/")
(copy-file #$(file-append opensnitchd "/etc/system-fw.json")
"/etc/opensnitchd/system-fw.json"))))))
(define (opensnitch-shepherd-service config)
"Return a <shepherd-service> for opensnitch with CONFIG."
(let ((default-config
(computed-file
"opensnitchd-config.json"
#~(with-output-to-file #$output
(lambda _
#$(serialize-json-configuration
config
opensnitch-configuration-fields))))))
(list (shepherd-service
(documentation "Opensnitchd daemon.")
(requirement '(syslogd loopback))
(provision '(opensnitch))
(start
#~(make-forkexec-constructor
(list #$(file-append opensnitchd "/bin/opensnitchd")
"-config-file" #$default-config)))
(stop #~(make-kill-destructor))))))
(define opensnitch-service-type
(service-type
(name 'opensnitch)
(description "Run the Opensnitch application firewall daemon.")
(extensions
(list
(service-extension shepherd-root-service-type
opensnitch-shepherd-service)
(service-extension activation-service-type
opensnitch-activation)
(service-extension profile-service-type
(lambda (config)
`(,(opensnitch-configuration-opensnitchd config))))))
(compose identity)
(default-value (opensnitch-configuration))))
|