Skip to content

Commit 8bec098

Browse files
Refactor architecture and enable audit functionality (#19)
* moving stuff * moving code around * Fix environment variables not being passed to commands - Initialize preparedEnv with config.Env in both macOS and Linux constructors - Remove unused SetEnv methods - Update comments to reflect the new approach Co-authored-by: f0ssel <[email protected]> --------- Co-authored-by: Garrett Delfosse <[email protected]> Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> Co-authored-by: f0ssel <[email protected]>
1 parent c261491 commit 8bec098

File tree

12 files changed

+222
-200
lines changed

12 files changed

+222
-200
lines changed

audit/logging_auditor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func NewLoggingAuditor(logger *slog.Logger) *LoggingAuditor {
1515
}
1616

1717
// AuditRequest logs the request using structured logging
18-
func (a *LoggingAuditor) AuditRequest(req *Request) {
18+
func (a *LoggingAuditor) AuditRequest(req Request) {
1919
if req.Allowed {
2020
a.logger.Info("ALLOW",
2121
"method", req.Method,

audit/logging_auditor_test.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import (
1111
func TestLoggingAuditor(t *testing.T) {
1212
tests := []struct {
1313
name string
14-
request *Request
14+
request Request
1515
expectedLevel string
1616
expectedFields []string
1717
}{
1818
{
1919
name: "allow request",
20-
request: &Request{
20+
request: Request{
2121
Method: "GET",
2222
URL: "https://github.com",
2323
Allowed: true,
@@ -28,7 +28,7 @@ func TestLoggingAuditor(t *testing.T) {
2828
},
2929
{
3030
name: "deny request",
31-
request: &Request{
31+
request: Request{
3232
Method: "POST",
3333
URL: "https://example.com",
3434
Allowed: false,
@@ -38,7 +38,7 @@ func TestLoggingAuditor(t *testing.T) {
3838
},
3939
{
4040
name: "allow with empty rule",
41-
request: &Request{
41+
request: Request{
4242
Method: "PUT",
4343
URL: "https://api.github.com/repos",
4444
Allowed: true,
@@ -49,7 +49,7 @@ func TestLoggingAuditor(t *testing.T) {
4949
},
5050
{
5151
name: "deny HTTPS request",
52-
request: &Request{
52+
request: Request{
5353
Method: "GET",
5454
URL: "https://malware.bad.com/payload",
5555
Allowed: false,
@@ -59,7 +59,7 @@ func TestLoggingAuditor(t *testing.T) {
5959
},
6060
{
6161
name: "allow with wildcard rule",
62-
request: &Request{
62+
request: Request{
6363
Method: "POST",
6464
URL: "https://api.github.com/graphql",
6565
Allowed: true,
@@ -70,7 +70,7 @@ func TestLoggingAuditor(t *testing.T) {
7070
},
7171
{
7272
name: "deny HTTP request",
73-
request: &Request{
73+
request: Request{
7474
Method: "GET",
7575
URL: "http://insecure.example.com",
7676
Allowed: false,
@@ -80,7 +80,7 @@ func TestLoggingAuditor(t *testing.T) {
8080
},
8181
{
8282
name: "allow HEAD request",
83-
request: &Request{
83+
request: Request{
8484
Method: "HEAD",
8585
URL: "https://cdn.jsdelivr.net/health",
8686
Allowed: true,
@@ -91,7 +91,7 @@ func TestLoggingAuditor(t *testing.T) {
9191
},
9292
{
9393
name: "deny OPTIONS request",
94-
request: &Request{
94+
request: Request{
9595
Method: "OPTIONS",
9696
URL: "https://restricted.api.com/cors",
9797
Allowed: false,
@@ -101,7 +101,7 @@ func TestLoggingAuditor(t *testing.T) {
101101
},
102102
{
103103
name: "allow with port number",
104-
request: &Request{
104+
request: Request{
105105
Method: "GET",
106106
URL: "https://localhost:3000/api/health",
107107
Allowed: true,
@@ -112,7 +112,7 @@ func TestLoggingAuditor(t *testing.T) {
112112
},
113113
{
114114
name: "deny DELETE request",
115-
request: &Request{
115+
request: Request{
116116
Method: "DELETE",
117117
URL: "https://api.production.com/users/admin",
118118
Allowed: false,
@@ -153,13 +153,13 @@ func TestLoggingAuditor(t *testing.T) {
153153
func TestLoggingAuditor_EdgeCases(t *testing.T) {
154154
tests := []struct {
155155
name string
156-
request *Request
156+
request Request
157157
expectedLevel string
158158
expectedFields []string
159159
}{
160160
{
161161
name: "empty fields",
162-
request: &Request{
162+
request: Request{
163163
Method: "",
164164
URL: "",
165165
Allowed: true,
@@ -170,7 +170,7 @@ func TestLoggingAuditor_EdgeCases(t *testing.T) {
170170
},
171171
{
172172
name: "special characters in URL",
173-
request: &Request{
173+
request: Request{
174174
Method: "POST",
175175
URL: "https://api.example.com/users?name=John%20Doe&id=123",
176176
Allowed: true,
@@ -181,7 +181,7 @@ func TestLoggingAuditor_EdgeCases(t *testing.T) {
181181
},
182182
{
183183
name: "very long URL",
184-
request: &Request{
184+
request: Request{
185185
Method: "GET",
186186
URL: "https://example.com/" + strings.Repeat("a", 1000),
187187
Allowed: false,
@@ -191,7 +191,7 @@ func TestLoggingAuditor_EdgeCases(t *testing.T) {
191191
},
192192
{
193193
name: "deny with custom URL",
194-
request: &Request{
194+
request: Request{
195195
Method: "DELETE",
196196
URL: "https://malicious.com",
197197
Allowed: false,
@@ -233,13 +233,13 @@ func TestLoggingAuditor_DifferentLogLevels(t *testing.T) {
233233
tests := []struct {
234234
name string
235235
logLevel slog.Level
236-
request *Request
236+
request Request
237237
expectOutput bool
238238
}{
239239
{
240240
name: "info level allows info logs",
241241
logLevel: slog.LevelInfo,
242-
request: &Request{
242+
request: Request{
243243
Method: "GET",
244244
URL: "https://github.com",
245245
Allowed: true,
@@ -250,7 +250,7 @@ func TestLoggingAuditor_DifferentLogLevels(t *testing.T) {
250250
{
251251
name: "warn level blocks info logs",
252252
logLevel: slog.LevelWarn,
253-
request: &Request{
253+
request: Request{
254254
Method: "GET",
255255
URL: "https://github.com",
256256
Allowed: true,
@@ -261,7 +261,7 @@ func TestLoggingAuditor_DifferentLogLevels(t *testing.T) {
261261
{
262262
name: "warn level allows warn logs",
263263
logLevel: slog.LevelWarn,
264-
request: &Request{
264+
request: Request{
265265
Method: "POST",
266266
URL: "https://example.com",
267267
Allowed: false,
@@ -271,7 +271,7 @@ func TestLoggingAuditor_DifferentLogLevels(t *testing.T) {
271271
{
272272
name: "error level blocks warn logs",
273273
logLevel: slog.LevelError,
274-
request: &Request{
274+
request: Request{
275275
Method: "POST",
276276
URL: "https://example.com",
277277
Allowed: false,
@@ -312,7 +312,7 @@ func TestLoggingAuditor_NilLogger(t *testing.T) {
312312
}()
313313

314314
auditor := &LoggingAuditor{logger: nil}
315-
req := &Request{
315+
req := Request{
316316
Method: "GET",
317317
URL: "https://example.com",
318318
Allowed: true,
@@ -331,7 +331,7 @@ func TestLoggingAuditor_JSONHandler(t *testing.T) {
331331
}))
332332

333333
auditor := NewLoggingAuditor(logger)
334-
req := &Request{
334+
req := Request{
335335
Method: "GET",
336336
URL: "https://github.com",
337337
Allowed: true,
@@ -364,7 +364,7 @@ func TestLoggingAuditor_DiscardHandler(t *testing.T) {
364364
logger := slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{}))
365365

366366
auditor := NewLoggingAuditor(logger)
367-
req := &Request{
367+
req := Request{
368368
Method: "GET",
369369
URL: "https://example.com",
370370
Allowed: true,

audit/request.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package audit
22

3-
import (
4-
"net/http"
5-
)
3+
import "net/http"
64

75
// Request represents information about an HTTP request for auditing
86
type Request struct {

cli/cli.go

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import (
1111

1212
"github.com/coder/jail"
1313
"github.com/coder/jail/audit"
14-
"github.com/coder/jail/namespace"
15-
"github.com/coder/jail/proxy"
1614
"github.com/coder/jail/rules"
1715
"github.com/coder/jail/tls"
1816
"github.com/coder/serpent"
@@ -115,20 +113,7 @@ func Run(config Config, args []string) error {
115113
ruleEngine := rules.NewRuleEngine(allowRules, logger)
116114

117115
// Create auditor
118-
auditor := audit.NewLoggingAuditor(logger)
119-
120-
// Create network namespace configuration
121-
nsConfig := namespace.Config{
122-
HTTPPort: 8040,
123-
HTTPSPort: 8043,
124-
}
125-
126-
// Create commander
127-
commander, err := namespace.New(nsConfig, logger)
128-
if err != nil {
129-
logger.Error("Failed to create network namespace", "error", err)
130-
return fmt.Errorf("failed to create network namespace: %v", err)
131-
}
116+
// auditor := audit.NewLoggingAuditor(logger)
132117

133118
// Create certificate manager
134119
certManager, err := tls.NewCertificateManager(logger)
@@ -137,39 +122,17 @@ func Run(config Config, args []string) error {
137122
return fmt.Errorf("failed to create certificate manager: %v", err)
138123
}
139124

140-
// Setup TLS config and write CA certificate to file
141-
var caCertPath, configDir string
142-
tlsConfig, caCertPath, configDir, err := certManager.SetupTLSAndWriteCACert()
143-
if err != nil {
144-
logger.Error("Failed to setup TLS and CA certificate", "error", err)
145-
return fmt.Errorf("failed to setup TLS and CA certificate: %v", err)
146-
}
147-
148-
// Set standard CA certificate environment variables for common tools
149-
// This makes tools like curl, git, etc. trust our dynamically generated CA
150-
commander.SetEnv("SSL_CERT_FILE", caCertPath) // OpenSSL/LibreSSL-based tools
151-
commander.SetEnv("SSL_CERT_DIR", configDir) // OpenSSL certificate directory
152-
commander.SetEnv("CURL_CA_BUNDLE", caCertPath) // curl
153-
commander.SetEnv("GIT_SSL_CAINFO", caCertPath) // Git
154-
commander.SetEnv("REQUESTS_CA_BUNDLE", caCertPath) // Python requests
155-
commander.SetEnv("NODE_EXTRA_CA_CERTS", caCertPath) // Node.js
156-
157-
// Create proxy server
158-
proxyServer := proxy.NewProxyServer(proxy.Config{
159-
HTTPPort: 8040,
160-
HTTPSPort: 8043,
161-
RuleEngine: ruleEngine,
162-
Auditor: auditor,
163-
Logger: logger,
164-
TLSConfig: tlsConfig,
165-
})
166-
167125
// Create jail instance
168-
jailInstance := jail.New(jail.Config{
169-
Commander: commander,
170-
ProxyServer: proxyServer,
126+
jailInstance, err := jail.New(context.Background(), jail.Config{
127+
RuleEngine: ruleEngine,
128+
Auditor: audit.NewLoggingAuditor(logger),
171129
Logger: logger,
130+
CertManager: certManager,
172131
})
132+
if err != nil {
133+
logger.Error("Failed to create jail instance", "error", err)
134+
return fmt.Errorf("failed to create jail instance: %v", err)
135+
}
173136

174137
// Setup signal handling BEFORE any setup
175138
sigChan := make(chan os.Signal, 1)
@@ -198,7 +161,7 @@ func Run(config Config, args []string) error {
198161
}()
199162

200163
// Open jail (starts network namespace and proxy server)
201-
err = jailInstance.Open()
164+
err = jailInstance.Start()
202165
if err != nil {
203166
logger.Error("Failed to open jail", "error", err)
204167
return fmt.Errorf("failed to open jail: %v", err)

0 commit comments

Comments
 (0)