Skip to content

Commit 7addc41

Browse files
authored
#39: add support port range generation (#40)
Signed-off-by: kaizhe <derek0405@gmail.com>
1 parent 95f0419 commit 7addc41

File tree

9 files changed

+219
-12
lines changed

9 files changed

+219
-12
lines changed

advisor/types/portrange.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package types
2+
3+
import (
4+
"fmt"
5+
"sort"
6+
)
7+
8+
type PortRangeList []*PortRange
9+
10+
type PortRange struct {
11+
Min int32
12+
Max int32
13+
}
14+
15+
func NewPortRange(min, max int32) *PortRange {
16+
return &PortRange{
17+
Min: min,
18+
Max: max,
19+
}
20+
}
21+
22+
func (pl PortRangeList) Consolidate() PortRangeList {
23+
newPortRangeList := PortRangeList{}
24+
25+
max := pl.GetMax()
26+
27+
min := pl.GetMin()
28+
29+
if min == -1 {
30+
return newPortRangeList
31+
}
32+
33+
tmpPl := make(PortRangeList, max+1)
34+
35+
for _, pr := range pl {
36+
tmpPl[pr.Min] = pr
37+
}
38+
39+
pr := tmpPl[min]
40+
i := min
41+
42+
for ; i <= max; i++ {
43+
if tmpPl[i] != nil {
44+
pr.Max = tmpPl[i].Max
45+
} else {
46+
// there is a break
47+
newPortRangeList = append(newPortRangeList, pr)
48+
49+
// look for next port range
50+
for {
51+
i++
52+
if i > max {
53+
break
54+
}
55+
56+
if tmpPl[i] != nil {
57+
pr = tmpPl[i]
58+
break
59+
}
60+
}
61+
}
62+
}
63+
64+
newPortRangeList = append(newPortRangeList, pr)
65+
66+
sort.Sort(newPortRangeList)
67+
68+
return newPortRangeList
69+
}
70+
71+
func (pl PortRangeList) GetMin() int32 {
72+
min := int32(-1)
73+
74+
for _, pr := range pl {
75+
if pr != nil {
76+
if min == int32(-1) {
77+
min = pr.Min
78+
}
79+
80+
if pr.Min < min {
81+
min = pr.Min
82+
}
83+
}
84+
}
85+
86+
return min
87+
}
88+
89+
func (pl PortRangeList) GetMax() int32 {
90+
max := int32(-1)
91+
92+
for _, pr := range pl {
93+
if pr != nil {
94+
if pr.Max > max {
95+
max = pr.Max
96+
}
97+
}
98+
}
99+
100+
return max
101+
}
102+
103+
func (pl PortRangeList) String() string {
104+
ret := "["
105+
106+
for idx, pr := range pl {
107+
ret += fmt.Sprintf("{%d %d}", pr.Min, pr.Max)
108+
109+
if idx < len(pl)-1 {
110+
ret += ", "
111+
}
112+
}
113+
114+
ret += "]"
115+
116+
return ret
117+
}
118+
119+
func (pl PortRangeList) Less(i, j int) bool { return pl[i].Min < pl[j].Min }
120+
121+
func (pl PortRangeList) Len() int { return len(pl) }
122+
123+
func (pl PortRangeList) Swap(i, j int) { pl[j], pl[i] = pl[i], pl[j] }

advisor/types/portrange_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package types
2+
3+
import (
4+
"testing"
5+
)
6+
7+
var (
8+
prList = PortRangeList{
9+
&PortRange{Min: 1, Max: 1},
10+
&PortRange{Min: 2, Max: 2},
11+
&PortRange{Min: 3, Max: 3},
12+
&PortRange{Min: 5, Max: 5},
13+
&PortRange{Min: 6, Max: 6},
14+
&PortRange{Min: 7, Max: 7},
15+
&PortRange{Min: 50, Max: 50},
16+
&PortRange{Min: 99, Max: 99},
17+
}
18+
19+
expectedPrList = PortRangeList{
20+
&PortRange{Min: 1, Max: 3},
21+
&PortRange{Min: 5, Max: 7},
22+
&PortRange{Min: 50, Max: 50},
23+
&PortRange{Min: 99, Max: 99},
24+
}
25+
)
26+
27+
func TestPortRange(t *testing.T) {
28+
newPrList := prList.Consolidate()
29+
30+
if len(newPrList) != 4 {
31+
t.Errorf("length is not 3: %+v", newPrList)
32+
}
33+
34+
for i := range expectedPrList {
35+
if newPrList[i].Min != expectedPrList[i].Min || newPrList[i].Max != expectedPrList[i].Max {
36+
t.Errorf("expected port range: %v; actual port range: %v", *expectedPrList[i], *newPrList[i])
37+
}
38+
}
39+
}

advisor/types/securityspec.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ const (
2626
//PodSecurityPolicy Recommendation System help in the following attributes:
2727
// 1. allowPrivilegeEscalation - done
2828
// 2. allowedCapabilities - done
29-
// 3. allowedHostPaths - need further investigation
29+
// 3. allowedHostPaths - done
3030
// 4. hostIPC - done
3131
// 5. hostNetwork - done
3232
// 6. hostPID - done
33-
// 7. hostPorts - need further investigation
33+
// 7. hostPorts - done
3434
// 8. privileged - done
3535
// 9. readOnlyRootFilesystem - done
3636
// 10. runAsUser - done
37-
// 11. runAsGroup - half done
37+
// 11. runAsGroup - done
3838
// 12. Volume - done
3939
// 13. seLinux and others - need further investigation
4040

generator/generator.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ func (pg *Generator) GeneratePSPWithName(
372372

373373
hostPaths := map[string]bool{}
374374

375+
hostPorts := map[int32]bool{}
376+
375377
runAsUserCount := 0
376378

377379
runAsGroupCount := 0
@@ -447,11 +449,9 @@ func (pg *Generator) GeneratePSPWithName(
447449
notAllowPrivilegeEscationCount++
448450
}
449451

450-
// set host ports
451-
//TODO: need to integrate with listening port during the runtime, might cause false positive.
452-
//for _, port := range sc.HostPorts {
453-
// psp.Spec.HostPorts = append(psp.Spec.HostPorts, policyv1beta1.HostPortRange{Min: port, Max: port})
454-
//}
452+
for _, port := range sc.HostPorts {
453+
hostPorts[port] = true
454+
}
455455
}
456456

457457
// set allowedPrivilegeEscalation
@@ -532,6 +532,17 @@ func (pg *Generator) GeneratePSPWithName(
532532
}
533533
}
534534

535+
// set host ports
536+
portRangeList := types.PortRangeList{}
537+
for hostPort := range hostPorts {
538+
portRange := types.NewPortRange(hostPort, hostPort)
539+
portRangeList = append(portRangeList, portRange)
540+
}
541+
542+
for _, portRange := range portRangeList.Consolidate() {
543+
psp.Spec.HostPorts = append(psp.Spec.HostPorts, policyv1beta1.HostPortRange{Min: portRange.Min, Max: portRange.Max})
544+
}
545+
535546
// set to default values
536547
if string(psp.Spec.RunAsUser.Rule) == "" {
537548
psp.Spec.RunAsUser.Rule = policyv1beta1.RunAsUserStrategyRunAsAny

generator/generator_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var (
3232
Namespace: namespaceTest,
3333
RunAsUser: &runAsUser,
3434
RunAsGroup: &runAsGroup,
35+
HostPorts: []int32{80, 8080},
3536
},
3637
{Metadata: types.Metadata{
3738
Kind: "Deployment",
@@ -47,6 +48,7 @@ var (
4748
Namespace: namespaceTest,
4849
RunAsUser: &runAsUser,
4950
RunAsGroup: &runAsGroup,
51+
HostPorts: []int32{80, 8081},
5052
},
5153
}
5254

@@ -118,6 +120,18 @@ func TestCSS(t *testing.T) {
118120
if psp.Spec.RunAsGroup.Ranges[0].Min != runAsGroup && psp.Spec.RunAsGroup.Ranges[0].Max != runAsGroup {
119121
t.Fatal("psp should have set run as group to 1000")
120122
}
123+
124+
if len(psp.Spec.HostPorts) != 2 {
125+
t.Fatalf("there should be 2 port ranges, actual: %d", len(psp.Spec.HostPorts))
126+
}
127+
128+
if psp.Spec.HostPorts[0].Min != 80 || psp.Spec.HostPorts[0].Max != 80 {
129+
t.Fatalf("Expect port range [80, 80], actual: %v", psp.Spec.HostPorts[0])
130+
}
131+
132+
if psp.Spec.HostPorts[1].Min != 8080 || psp.Spec.HostPorts[1].Max != 8081 {
133+
t.Fatalf("Expect port range [8080, 8081], actual: %v", psp.Spec.HostPorts[1])
134+
}
121135
}
122136

123137
func TestPSS(t *testing.T) {

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@ require (
1818
github.com/modern-go/reflect2 v1.0.1 // indirect
1919
github.com/sirupsen/logrus v1.4.2
2020
github.com/spf13/cobra v0.0.5
21-
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc // indirect
2221
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
2322
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect
2423
golang.org/x/text v0.3.2 // indirect
2524
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
26-
golang.org/x/tools v0.0.0-20200206204726-37215997d4fb // indirect
25+
golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7
2726
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
2827
gopkg.in/inf.v0 v0.9.0 // indirect
2928
gopkg.in/yaml.v2 v2.2.4 // indirect

go.sum

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,28 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
9292
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
9393
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
9494
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
95+
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
9596
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
9697
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
9798
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
9899
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
99100
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
100101
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
102+
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
103+
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
101104
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
102105
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
103106
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
104107
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
105108
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
106109
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
110+
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
111+
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
107112
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
108113
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
109114
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
110115
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
116+
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
111117
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
112118
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
113119
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -122,9 +128,17 @@ golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq
122128
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
123129
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
124130
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
131+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
125132
golang.org/x/tools v0.0.0-20200206204726-37215997d4fb h1:EvFvbyipa48qGILQqY8iDrep83Zd1YCssXQFh/6zhpY=
126133
golang.org/x/tools v0.0.0-20200206204726-37215997d4fb/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
134+
golang.org/x/tools v0.0.0-20200401192744-099440627f01 h1:ysQJ/fU6laLOZJseIeOqXl6Mo+lw5z6b7QHnmUKjW+k=
135+
golang.org/x/tools v0.0.0-20200401192744-099440627f01/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
136+
golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7 h1:nm4zDh9WvH4jiuUpMY5RUsvOwrtTVVAsUaCdLW71hfY=
137+
golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
138+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
127139
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
140+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
141+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
128142
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
129143
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
130144
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

kube-psp-advisor_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ import (
99
var (
1010
workloadDir = "./test-yaml"
1111

12-
expectedYamls = []string{"test-yaml/base-busybox.yaml", "test-yaml/psp-grant.yaml", "test-yaml/testSrcDir/testdir/busy-box.yaml", "test-yaml/testTargetDir/testdir/busy-box.yaml"}
12+
expectedYamls = []string{
13+
"test-yaml/base-busybox.yaml",
14+
"test-yaml/psp-grant.yaml",
15+
"test-yaml/srcYamls/busy-box.yaml",
16+
"test-yaml/srcYamls/nginx.yaml",
17+
"test-yaml/targetYamls/busy-box.yaml",
18+
"test-yaml/targetYamls/nginx.yaml",
19+
}
1320
)
1421

1522
func TestReadYamls(t *testing.T) {

version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.7.0
1+
1.8.0

0 commit comments

Comments
 (0)