-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmain.go
126 lines (95 loc) · 3.45 KB
/
main.go
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
package main
import (
"context"
"flag"
"log"
"os"
"os/signal"
"github.com/loopholelabs/drafter/pkg/nat"
"github.com/loopholelabs/goroutine-manager/pkg/manager"
)
func main() {
hostInterface := flag.String("host-interface", "wlp0s20f3", "Host gateway interface")
hostVethCIDR := flag.String("host-veth-cidr", "10.0.8.0/22", "CIDR for the veths outside the namespace")
namespaceVethCIDR := flag.String("namespace-veth-cidr", "10.0.15.0/24", "CIDR for the veths inside the namespace")
blockedSubnetCIDR := flag.String("blocked-subnet-cidr", "10.0.15.0/24", "CIDR to block for the namespace")
namespaceInterface := flag.String("namespace-interface", "tap0", "Name for the interface inside the namespace")
namespaceInterfaceGateway := flag.String("namespace-interface-gateway", "172.16.0.1", "Gateway for the interface inside the namespace")
namespaceInterfaceNetmask := flag.Uint("namespace-interface-netmask", 30, "Netmask for the interface inside the namespace")
namespaceInterfaceIP := flag.String("namespace-interface-ip", "172.16.0.2", "IP for the interface inside the namespace")
namespaceInterfaceMAC := flag.String("namespace-interface-mac", "02:0e:d9:fd:68:3d", "MAC address for the interface inside the namespace")
namespacePrefix := flag.String("namespace-prefix", "ark", "Prefix for the namespace IDs")
allowIncomingTraffic := flag.Bool("allow-incoming-traffic", true, "Whether to allow incoming traffic to the namespaces (at host-veth-internal-ip:port)")
flag.Parse()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var errs error
defer func() {
if errs != nil {
panic(errs)
}
}()
goroutineManager := manager.NewGoroutineManager(
ctx,
&errs,
manager.GoroutineManagerHooks{},
)
defer goroutineManager.Wait()
defer goroutineManager.StopAllGoroutines()
defer goroutineManager.CreateBackgroundPanicCollector()()
go func() {
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt)
<-done
log.Println("Exiting gracefully")
cancel()
}()
namespaces, err := nat.CreateNAT(
goroutineManager.Context(),
context.Background(), // Never give up on rescue operations
nat.TranslationConfiguration{
HostInterface: *hostInterface,
HostVethCIDR: *hostVethCIDR,
NamespaceVethCIDR: *namespaceVethCIDR,
BlockedSubnetCIDR: *blockedSubnetCIDR,
NamespaceInterface: *namespaceInterface,
NamespaceInterfaceGateway: *namespaceInterfaceGateway,
NamespaceInterfaceNetmask: uint32(*namespaceInterfaceNetmask),
NamespaceInterfaceIP: *namespaceInterfaceIP,
NamespaceInterfaceMAC: *namespaceInterfaceMAC,
NamespacePrefix: *namespacePrefix,
AllowIncomingTraffic: *allowIncomingTraffic,
},
nat.CreateNamespacesHooks{
OnBeforeCreateNamespace: func(id string) {
log.Println("Creating namespace", id)
},
OnBeforeRemoveNamespace: func(id string) {
log.Println("Removing namespace", id)
},
},
)
defer func() {
defer goroutineManager.CreateForegroundPanicCollector()()
if err := namespaces.Wait(); err != nil {
panic(err)
}
}()
if err != nil {
panic(err)
}
defer func() {
defer goroutineManager.CreateForegroundPanicCollector()()
if err := namespaces.Close(); err != nil {
panic(err)
}
}()
goroutineManager.StartForegroundGoroutine(func(_ context.Context) {
if err := namespaces.Wait(); err != nil {
panic(err)
}
})
log.Println("Created all namespaces")
<-goroutineManager.Context().Done()
log.Println("Shutting down")
}