mirror of
https://github.com/hackerschoice/segfault.git
synced 2024-06-28 17:51:22 +00:00
merge
This commit is contained in:
commit
4f6895da0a
14
Makefile
14
Makefile
@ -2,7 +2,7 @@ VER := 0.4.3rc2
|
||||
|
||||
all:
|
||||
make -C router
|
||||
make -C cleaner/cg
|
||||
make -C tools/cg
|
||||
make -C master
|
||||
make -C host
|
||||
make -C tor
|
||||
@ -123,12 +123,12 @@ FILES_ROOT += "segfault-$(VER)/sfbin/sf"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/loginmsg-new.sh-example"
|
||||
FILES_ROOT += "segfault-$(VER)/sfbin/loginmsg-all.sh-example"
|
||||
|
||||
FILES_CLEANER += "segfault-$(VER)/cleaner/cg/Dockerfile"
|
||||
FILES_CLEANER += "segfault-$(VER)/cleaner/cg/go.mod"
|
||||
FILES_CLEANER += "segfault-$(VER)/cleaner/cg/go.sum"
|
||||
FILES_CLEANER += "segfault-$(VER)/cleaner/cg/main.go"
|
||||
FILES_CLEANER += "segfault-$(VER)/cleaner/cg/Makefile"
|
||||
FILES_CLEANER += "segfault-$(VER)/cleaner/cg/sysinfo_linux.go"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/Dockerfile"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/go.mod"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/go.sum"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/main.go"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/Makefile"
|
||||
FILES_CLEANER += "segfault-$(VER)/tools/cg/sysinfo_linux.go"
|
||||
|
||||
FILES += $(FILES_CLEANER) $(FILES_MASTER) $(FILES_ROOT) $(FILES_GSNC) $(FILES_CONFIG) $(FILES_ROUTER) $(FILES_TOR) $(FILES_ENCFSD) $(FILES_GUEST) $(FILES_HOST) $(FILES_PROVISION)
|
||||
TARX = $(shell command -v gtar 2>/dev/null)
|
||||
|
@ -1,11 +0,0 @@
|
||||
module mfs
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/yanzay/tbot/v2 v2.2.0
|
||||
golang.org/x/crypto v0.1.0
|
||||
)
|
||||
|
||||
require golang.org/x/sys v0.2.0 // indirect
|
Binary file not shown.
@ -89,15 +89,17 @@ services:
|
||||
- "${SF_BASEDIR:-.}/sfbin:/sf/bin:ro"
|
||||
|
||||
sf-containerguard:
|
||||
build: cleaner/cg
|
||||
build: tools/cg
|
||||
image: sf-containerguard
|
||||
container_name: sf-containerguard
|
||||
restart: ${SF_RESTART:-on-failure}
|
||||
cgroup_parent: sf.slice
|
||||
pid: "host"
|
||||
cap_add:
|
||||
- SYS_PTRACE # access to /proc/<PID>/root/dev/pts/* to send messages to user.
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
- "/var/run/containerd/io.containerd.runtime.v2.task:/var/run/containerd/io.containerd.runtime.v2.task:ro"
|
||||
- "/var/run/containerd/io.containerd.runtime.v2.task:/var/run/containerd/io.containerd.runtime.v2.task"
|
||||
- "${SF_BASEDIR:-.}/config:${SF_BASEDIR:-.}/config"
|
||||
- "/sys/fs/cgroup:/sys/fs/cgroup"
|
||||
|
||||
|
0
cleaner/cg/.gitignore → tools/cg/.gitignore
vendored
0
cleaner/cg/.gitignore → tools/cg/.gitignore
vendored
0
cleaner/cg/Makefile → tools/cg/Makefile
Executable file → Normal file
0
cleaner/cg/Makefile → tools/cg/Makefile
Executable file → Normal file
BIN
tools/cg/cg.tgz
Normal file
BIN
tools/cg/cg.tgz
Normal file
Binary file not shown.
@ -15,13 +15,13 @@ require (
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/stretchr/testify v1.8.0 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/term v0.5.0 // indirect
|
@ -19,8 +19,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
|
||||
@ -41,10 +41,12 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
@ -12,7 +12,6 @@ import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -37,7 +36,7 @@ var (
|
||||
debugFlag = flag.Bool("debug", false, "activate debug mode")
|
||||
)
|
||||
|
||||
func init() {
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *debugFlag {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
@ -47,21 +46,12 @@ func init() {
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
ForceColors: true,
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
log.Infof("ContainerGuard (CG) started protecting [%v]", hostname)
|
||||
log.Infof("compiled on %v from commit %v", Buildtime, Version)
|
||||
|
||||
// docker client
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Debugf("connected to docker client v%v", cli.ClientVersion())
|
||||
|
||||
// number of virtual cores
|
||||
var numCPU = runtime.NumCPU()
|
||||
// MAX_LOAD defines the maximum amount of `strain` each CPU can have
|
||||
@ -97,11 +87,20 @@ func main() {
|
||||
}
|
||||
|
||||
log.Warnf("[TRIGGER] load (%.2f) on cpu (%v) higher than max_load (%v)", sysLoad1mAvg(), numCPU, MAX_LOAD)
|
||||
LAST_LOAD = sysLoad1mAvg()
|
||||
|
||||
// docker client
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Debugf("connected to docker client v%v", cli.ClientVersion())
|
||||
|
||||
err = stopContainersBasedOnUsage(cli)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
LAST_LOAD = sysLoad1mAvg()
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,6 +138,7 @@ func stopContainersBasedOnUsage(cli *client.Client) error {
|
||||
highestUsage = usage
|
||||
mu.Unlock()
|
||||
}
|
||||
|
||||
log.Infof("[%v] usage (%.2f%%)", c.Names[0][1:], usage)
|
||||
}(c)
|
||||
}
|
||||
@ -152,20 +152,25 @@ func stopContainersBasedOnUsage(cli *client.Client) error {
|
||||
intPtr := func(v int) *int { return &v }
|
||||
var killTimeout = container.StopOptions{
|
||||
Signal: "SIGTERM",
|
||||
Timeout: intPtr(10),
|
||||
Timeout: intPtr(5),
|
||||
}
|
||||
|
||||
var killThreshold = highestUsage * 0.8 // 80% of highestUsage
|
||||
const action = "STOP (2s) || KILL"
|
||||
const abuseMessage = "Your server was shut down because it consumed to many resources. If you feel that this was a mistake then please contact us 💙"
|
||||
|
||||
const actionMessage = "STOP (5s) || KILL"
|
||||
const abuseMessage = "Your server was shut down because it consumed too many resources. If you feel that this was a mistake then please contact us 💙"
|
||||
|
||||
// stop all containers where usage > `highestUsage` * 0.8
|
||||
if usage > killThreshold {
|
||||
log.Warnf("[%v] usage (%.2f%%) > threshold (%.2f%%) | action %v", c.Names[0][1:], usage, killThreshold, action)
|
||||
if killThreshold < 10.0 {
|
||||
return fmt.Errorf("StopContainer: operation aborted: threshold too low %.5f", killThreshold)
|
||||
}
|
||||
log.Warnf("[%v] usage (%.2f%%) > threshold (%.2f%%) | action %v", c.Names[0][1:], usage, killThreshold, actionMessage)
|
||||
|
||||
// message user that he's being abusive
|
||||
err = sendMessage(c.ID, abuseMessage)
|
||||
if err != nil {
|
||||
log.Errorf("unable to message the user: %v", err)
|
||||
log.Errorf("unable to message container: %v", err)
|
||||
}
|
||||
|
||||
err = printProcs(c.ID, c.Names[0])
|
||||
@ -187,7 +192,7 @@ func stopContainersBasedOnUsage(cli *client.Client) error {
|
||||
usage: usage,
|
||||
threshold: killThreshold,
|
||||
load: sysLoad1mAvg(),
|
||||
action: action,
|
||||
action: actionMessage,
|
||||
}
|
||||
if err := logData.save(*resultFlag); err != nil {
|
||||
log.Error(err)
|
||||
@ -232,7 +237,7 @@ func sendMessage(cID string, message string) error {
|
||||
|
||||
pid, err := os.ReadFile(pidPath)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("readfile: %v", err)
|
||||
}
|
||||
|
||||
// keeps track of how many FDs we've walked past.
|
||||
@ -243,14 +248,15 @@ func sendMessage(cID string, message string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fdCount++
|
||||
|
||||
_, err = strconv.Atoi(d.Name())
|
||||
if err != nil {
|
||||
log.Debugf("not a number: %v", path)
|
||||
log.Debugf("not a number: %v", d.Name())
|
||||
return nil
|
||||
}
|
||||
|
||||
fdCount++
|
||||
|
||||
log.Debugf("MESSAGE to: %v", path)
|
||||
err = _sendMessage(path, message)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -263,7 +269,7 @@ func sendMessage(cID string, message string) error {
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("walkpath: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -289,9 +295,10 @@ func _sendMessage(fd, message string) error {
|
||||
return fmt.Errorf("%v is a symlink! dodging attack...", file.Name())
|
||||
}
|
||||
|
||||
if info.Mode().Type() != os.ModeSocket {
|
||||
return fmt.Errorf("%v is NOT a socket! dodging attack...", file.Name())
|
||||
}
|
||||
// removed this check as pts/0 is not detected as socket and the message won't be sent.
|
||||
// if info.Mode().Type() != os.ModeSocket {
|
||||
// return fmt.Errorf("%v is NOT a socket! dodging attack...", file.Name())
|
||||
// }
|
||||
|
||||
if !terminal.IsTerminal(int(file.Fd())) {
|
||||
return fmt.Errorf("unable to write to %v: not a tty", file.Name())
|
||||
@ -343,18 +350,20 @@ func (a LogData) save(path string) error {
|
||||
func sanitize(s string) string {
|
||||
clean := func(s []byte) string {
|
||||
j := 0
|
||||
for _, b := range s {
|
||||
for i, b := range s {
|
||||
if b == '\x00' {
|
||||
s[i] = '\x20'
|
||||
}
|
||||
if ('a' <= b && b <= 'z') ||
|
||||
('A' <= b && b <= 'Z') ||
|
||||
('0' <= b && b <= '9') ||
|
||||
b == '#' {
|
||||
b == '#' || b == ' ' || b == '-' {
|
||||
s[j] = b
|
||||
j++
|
||||
}
|
||||
}
|
||||
return string(s[:j])
|
||||
}
|
||||
s = strings.ToValidUTF8(s, "#")
|
||||
s = clean([]byte(s))
|
||||
return s
|
||||
}
|
||||
@ -367,8 +376,14 @@ func printProcs(cid, cname string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var count int
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
if count > 12 {
|
||||
return fmt.Errorf("reached max commands, skipping extra output")
|
||||
}
|
||||
count++
|
||||
|
||||
cmdline := fmt.Sprintf("/proc/%s/cmdline", scanner.Text())
|
||||
|
||||
// limit each command string to max 255 characters
|
||||
@ -381,14 +396,8 @@ func printProcs(cid, cname string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var count int
|
||||
_scanner := bufio.NewScanner(file)
|
||||
for _scanner.Scan() {
|
||||
if count > 128 {
|
||||
return fmt.Errorf("reached 128 commands, skipping extra output")
|
||||
}
|
||||
count++
|
||||
|
||||
data := sanitize(_scanner.Text())
|
||||
log.Warnf("[%s] proc: %v", cname, data)
|
||||
}
|
25
tools/cg/main_test.go
Normal file
25
tools/cg/main_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSanitize(t *testing.T) {
|
||||
from := "/dev/urandom"
|
||||
file, err := os.Open(from)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to open file %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
data := make([]byte, 4096)
|
||||
n, err := file.Read(data)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read bytes: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("read %v bytes from %v", n, from)
|
||||
r1 := sanitize(string(data))
|
||||
t.Logf("result1: %v", r1)
|
||||
}
|
14
tools/monitor_ssh/go.mod
Normal file
14
tools/monitor_ssh/go.mod
Normal file
@ -0,0 +1,14 @@
|
||||
module mfs
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/yanzay/tbot/v2 v2.2.0
|
||||
golang.org/x/crypto v0.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
)
|
@ -6,16 +6,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/yanzay/tbot/v2 v2.2.0 h1:bK1+XTwY59IskXpwtHc/ItfU2uELTTqYP3pajfBaPeM=
|
||||
github.com/yanzay/tbot/v2 v2.2.0/go.mod h1:q0+8JblBq9tLAnKHdBIZsHwDvMS9TfO6mNfaAk1VrHg=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
Loading…
Reference in New Issue
Block a user