[server] Add initial working Linux seccomp
filter for the server.
This commit is contained in:
parent
644be877f6
commit
b53992060e
7 changed files with 235 additions and 18 deletions
|
@ -18,6 +18,12 @@ func listenTcp (_endpoint string) (net.Listener, error) {
|
||||||
|
|
||||||
_useTcpListen := false
|
_useTcpListen := false
|
||||||
|
|
||||||
|
if ! _useTcpListen {
|
||||||
|
if seccompApplied {
|
||||||
|
_useTcpListen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ! _useTcpListen {
|
if ! _useTcpListen {
|
||||||
if (runtime.GOOS == "android") {
|
if (runtime.GOOS == "android") {
|
||||||
_useTcpListen = true
|
_useTcpListen = true
|
||||||
|
|
|
@ -11,25 +11,121 @@ import . "github.com/volution/kawipiko/lib/common"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var _seccompBaseSyscalls = []string {
|
||||||
|
|
||||||
|
"brk",
|
||||||
|
"mmap",
|
||||||
|
"munmap",
|
||||||
|
"madvise",
|
||||||
|
"mprotect",
|
||||||
|
|
||||||
|
"clone3",
|
||||||
|
"getpid",
|
||||||
|
"gettid",
|
||||||
|
"tgkill",
|
||||||
|
"exit_group",
|
||||||
|
"sched_yield",
|
||||||
|
"nanosleep",
|
||||||
|
|
||||||
|
"sigaltstack",
|
||||||
|
"rt_sigaction",
|
||||||
|
"rt_sigprocmask",
|
||||||
|
"rt_sigreturn",
|
||||||
|
"restart_syscall",
|
||||||
|
|
||||||
|
"futex",
|
||||||
|
"set_robust_list",
|
||||||
|
"rseq",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: While serving.
|
||||||
|
var _seccompPhase3Syscalls = append ([]string {
|
||||||
|
|
||||||
|
"accept4",
|
||||||
|
"close",
|
||||||
|
"getsockname",
|
||||||
|
"getpeername",
|
||||||
|
"getsockopt",
|
||||||
|
"setsockopt",
|
||||||
|
|
||||||
|
"read",
|
||||||
|
"write",
|
||||||
|
|
||||||
|
"pread64",
|
||||||
|
"pwrite64",
|
||||||
|
|
||||||
|
"recvmmsg",
|
||||||
|
"sendmsg",
|
||||||
|
|
||||||
|
"epoll_ctl",
|
||||||
|
"epoll_pwait",
|
||||||
|
|
||||||
|
"getrandom",
|
||||||
|
|
||||||
|
"getrusage",
|
||||||
|
|
||||||
|
}, _seccompBaseSyscalls ...)
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: While listening.
|
||||||
|
var _seccompPhase2Syscalls = append ([]string {
|
||||||
|
|
||||||
|
"socket",
|
||||||
|
"bind",
|
||||||
|
"listen",
|
||||||
|
|
||||||
|
"pipe2",
|
||||||
|
"fcntl",
|
||||||
|
|
||||||
|
"epoll_create1",
|
||||||
|
|
||||||
|
"seccomp",
|
||||||
|
"prctl",
|
||||||
|
|
||||||
|
}, _seccompPhase3Syscalls ...)
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: While loading.
|
||||||
|
var _seccompPhase1Syscalls = append ([]string {
|
||||||
|
|
||||||
|
"openat",
|
||||||
|
"fstat",
|
||||||
|
"newfstatat",
|
||||||
|
|
||||||
|
"mmap",
|
||||||
|
|
||||||
|
"seccomp",
|
||||||
|
"prctl",
|
||||||
|
|
||||||
|
}, _seccompPhase2Syscalls ...)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func seccompApplyPhase1 () () {
|
func seccompApplyPhase1 () () {
|
||||||
|
seccompApplied = true
|
||||||
log.Printf ("[ii] [d53cf86e] [seccomp.] applying Linux seccomp filter (phase 1)...\n")
|
log.Printf ("[ii] [d53cf86e] [seccomp.] applying Linux seccomp filter (phase 1)...\n")
|
||||||
if _error := seccomp.ApplyServer (); _error != nil {
|
if _error := seccomp.AllowOnlySyscalls (_seccompPhase1Syscalls); _error != nil {
|
||||||
AbortError (_error, "[58d1492b] failed to apply Linux seccomp filter (phase 1)!")
|
AbortError (_error, "[58d1492b] failed to apply Linux seccomp filter (phase 1)!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func seccompApplyPhase2 () () {
|
func seccompApplyPhase2 () () {
|
||||||
|
seccompApplied = true
|
||||||
log.Printf ("[ii] [a338ddaf] [seccomp.] applying Linux seccomp filter (phase 2)...\n")
|
log.Printf ("[ii] [a338ddaf] [seccomp.] applying Linux seccomp filter (phase 2)...\n")
|
||||||
if _error := seccomp.ApplyServer (); _error != nil {
|
if _error := seccomp.AllowOnlySyscalls (_seccompPhase2Syscalls); _error != nil {
|
||||||
AbortError (_error, "[68283e68] failed to apply Linux seccomp filter (phase 2)!")
|
AbortError (_error, "[68283e68] failed to apply Linux seccomp filter (phase 2)!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func seccompApplyPhase3 () () {
|
func seccompApplyPhase3 () () {
|
||||||
|
seccompApplied = true
|
||||||
log.Printf ("[ii] [a319ff21] [seccomp.] applying Linux seccomp filter (phase 3)...\n")
|
log.Printf ("[ii] [a319ff21] [seccomp.] applying Linux seccomp filter (phase 3)...\n")
|
||||||
if _error := seccomp.ApplyServer (); _error != nil {
|
if _error := seccomp.AllowOnlySyscalls (_seccompPhase3Syscalls); _error != nil {
|
||||||
AbortError (_error, "[7c5a0f44] failed to apply Linux seccomp filter (phase 3)!")
|
AbortError (_error, "[7c5a0f44] failed to apply Linux seccomp filter (phase 3)!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,5 +133,6 @@ func seccompApplyPhase3 () () {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var seccompApplied = false
|
||||||
var seccompSupported = seccomp.Supported
|
var seccompSupported = seccomp.Supported
|
||||||
|
|
||||||
|
|
|
@ -1035,7 +1035,7 @@ func main_0 () (error) {
|
||||||
if _seccompEnabled && (_processes > 1) {
|
if _seccompEnabled && (_processes > 1) {
|
||||||
AbortError (nil, "[69c06e0c] Linux seccomp is not supported with multiple processes!")
|
AbortError (nil, "[69c06e0c] Linux seccomp is not supported with multiple processes!")
|
||||||
}
|
}
|
||||||
if _seccompEnabled && ((_profilingCpu != "") || (_profilingMem != "")) {
|
if _seccompEnabled && ((_profileCpu != "") || (_profileMem != "")) {
|
||||||
AbortError (nil, "[1fb06ca1] Linux seccomp is not supported with profiling!")
|
AbortError (nil, "[1fb06ca1] Linux seccomp is not supported with profiling!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,19 +1056,6 @@ func main_0 () (error) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if _seccompEnabled {
|
|
||||||
seccompApplyPhase1 ()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
runtime.GOMAXPROCS (int (_threads))
|
runtime.GOMAXPROCS (int (_threads))
|
||||||
|
|
||||||
debug.SetGCPercent (50)
|
debug.SetGCPercent (50)
|
||||||
|
@ -1097,6 +1084,19 @@ func main_0 () (error) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if _seccompEnabled {
|
||||||
|
seccompApplyPhase1 ()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if _processes > 1 {
|
if _processes > 1 {
|
||||||
|
|
||||||
log.Printf ("[ii] [06f8c944] [master..] sub-processes starting (`%d` processes with `%d` threads each)...\n", _processes, _threads)
|
log.Printf ("[ii] [06f8c944] [master..] sub-processes starting (`%d` processes with `%d` threads each)...\n", _processes, _threads)
|
||||||
|
@ -2185,7 +2185,7 @@ func main_0 () (error) {
|
||||||
if !_quiet {
|
if !_quiet {
|
||||||
log.Printf ("[ii] [4cf834b0] [quic-h3.] starting QUIC server...\n")
|
log.Printf ("[ii] [4cf834b0] [quic-h3.] starting QUIC server...\n")
|
||||||
}
|
}
|
||||||
if _error := _server.httpQuicServer.Serve (_httpQuicListener); (_error != nil) && (_error.Error () != "server closed") {
|
if _error := _server.httpQuicServer.Serve (_httpQuicListener); (_error != nil) && (_error.Error () != "quic: Server closed") {
|
||||||
AbortError (_error, "[73e700c5] [quic-h3.] failed executing server!")
|
AbortError (_error, "[73e700c5] [quic-h3.] failed executing server!")
|
||||||
}
|
}
|
||||||
if !_quiet {
|
if !_quiet {
|
||||||
|
|
|
@ -32,6 +32,7 @@ require (
|
||||||
github.com/nxadm/tail v1.4.8 // indirect
|
github.com/nxadm/tail v1.4.8 // indirect
|
||||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||||
github.com/onsi/gomega v1.19.0 // indirect
|
github.com/onsi/gomega v1.19.0 // indirect
|
||||||
|
github.com/seccomp/libseccomp-golang v0.10.0 // indirect
|
||||||
github.com/stretchr/testify v1.8.0 // indirect
|
github.com/stretchr/testify v1.8.0 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/zeebo/assert v1.3.1 // indirect
|
github.com/zeebo/assert v1.3.1 // indirect
|
||||||
|
|
|
@ -144,6 +144,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
||||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
|
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
|
||||||
|
github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||||
|
|
95
sources/lib/seccomp/supported.go
Normal file
95
sources/lib/seccomp/supported.go
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
|
||||||
|
|
||||||
|
//go:build linux && amd64 && seccomp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package seccomp
|
||||||
|
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
|
||||||
|
import "github.com/seccomp/libseccomp-golang"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func init () {
|
||||||
|
|
||||||
|
Supported = true
|
||||||
|
|
||||||
|
if false {
|
||||||
|
|
||||||
|
_filter, _error := seccomp.NewFilter (seccomp.ActLog)
|
||||||
|
if _error != nil {
|
||||||
|
panic (_error)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _error = _filter.Load (); _error != nil {
|
||||||
|
panic (_error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func AllowOnlySyscalls (_syscalls []string) (error) {
|
||||||
|
|
||||||
|
_architectures := []seccomp.ScmpArch {
|
||||||
|
seccomp.ArchNative,
|
||||||
|
seccomp.ArchX86,
|
||||||
|
seccomp.ArchX32,
|
||||||
|
seccomp.ArchAMD64,
|
||||||
|
}
|
||||||
|
|
||||||
|
_fallbackAction := seccomp.ActKill
|
||||||
|
switch 0 {
|
||||||
|
case 1 :
|
||||||
|
_fallbackAction = seccomp.ActErrno.SetReturnCode (int16 (syscall.EPERM))
|
||||||
|
case 2 :
|
||||||
|
_fallbackAction = seccomp.ActLog
|
||||||
|
}
|
||||||
|
|
||||||
|
_filter, _error := seccomp.NewFilter (_fallbackAction)
|
||||||
|
if _error != nil {
|
||||||
|
return _error
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, _architecture := range _architectures {
|
||||||
|
if _error := _filter.AddArch (_architecture); _error != nil {
|
||||||
|
return _error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, _syscall := range _syscalls {
|
||||||
|
|
||||||
|
var _sc_syscall seccomp.ScmpSyscall
|
||||||
|
switch {
|
||||||
|
|
||||||
|
case _syscall[0] == '!' :
|
||||||
|
continue
|
||||||
|
|
||||||
|
default :
|
||||||
|
if _sc_syscall_0, _error := seccomp.GetSyscallFromNameByArch (_syscall, seccomp.ArchNative); _error == nil {
|
||||||
|
_sc_syscall = _sc_syscall_0
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf ("[5cf9cd60] failed resolving syscall `%s`: %w", _syscall, _error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _error := _filter.AddRule (_sc_syscall, seccomp.ActAllow); _error != nil {
|
||||||
|
return _error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _error = _filter.Load (); _error != nil {
|
||||||
|
return _error
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
16
sources/lib/seccomp/unsupported.go
Normal file
16
sources/lib/seccomp/unsupported.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
|
||||||
|
//go:build !(linux && amd64 && seccomp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
package seccomp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func AllowOnlySyscalls (_syscalls []string) (error) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue