blob: 435e9f7cbd13e1016970692744adccfb632fecb5 (
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
|
(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 (opensnitchd-configuration
serialize-json-configuration
opensnitchd-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 opensnitchd-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?"))
(define (opensnitchd-activation config)
"Create the opensnitchd rules and configuration according to CONFIG."
(match-record config <opensnitchd-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 (opensnitchd-shepherd-service config)
"Return a <shepherd-service> for opensnitchd with CONFIG."
(let ((default-config
(computed-file
"opensnitchd-config.json"
#~(with-output-to-file #$output
(lambda _
#$(serialize-json-configuration
config
opensnitchd-configuration-fields))))))
(list (shepherd-service
(documentation "Opensnitchd daemon.")
(requirement '(syslogd loopback))
(provision '(opensnitchd))
(start
#~(make-forkexec-constructor
(list #$(file-append opensnitchd "/bin/opensnitchd")
"-config-file" #$default-config)))
(stop #~(make-kill-destructor))))))
(define opensnitchd-service-type
(service-type
(name 'opensnitchd)
(description "Run the Opensnitch application firewall daemon.")
(extensions
(list
(service-extension shepherd-root-service-type
opensnitchd-shepherd-service)
(service-extension activation-service-type
opensnitchd-activation)
(service-extension profile-service-type
(lambda (config)
`(,(opensnitchd-configuration-opensnitchd config))))))
(compose identity)
(default-value (opensnitchd-configuration))))
|