github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/extractors/linux.go (about)

     1  package extractors
     2  
     3  import (
     4  	"debug/elf"
     5  	"fmt"
     6  	"os/user"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/shirou/gopsutil/process"
    12  	"go.aporeto.io/enforcerd/trireme-lib/common"
    13  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    14  	"go.aporeto.io/enforcerd/trireme-lib/utils/cgnetcls"
    15  	portspec "go.aporeto.io/enforcerd/trireme-lib/utils/portspec"
    16  )
    17  
    18  // LinuxMetadataExtractorType is a type of Linux metadata extractors
    19  type LinuxMetadataExtractorType func(event *common.EventInfo) (*policy.PURuntime, error)
    20  
    21  // DefaultHostMetadataExtractor is a host specific metadata extractor
    22  func DefaultHostMetadataExtractor(event *common.EventInfo) (*policy.PURuntime, error) {
    23  
    24  	runtimeTags := policy.NewTagStore()
    25  
    26  	for _, tag := range event.Tags {
    27  		parts := strings.SplitN(tag, "=", 2)
    28  		if len(parts) != 2 {
    29  			return nil, fmt.Errorf("invalid tag: %s", tag)
    30  		}
    31  		runtimeTags.AppendKeyValue("@usr:"+parts[0], parts[1])
    32  	}
    33  
    34  	options := &policy.OptionsType{
    35  		CgroupName: event.PUID,
    36  		CgroupMark: strconv.FormatUint(cgnetcls.MarkVal(), 10),
    37  		Services:   event.Services,
    38  	}
    39  
    40  	runtimeIps := policy.ExtendedMap{"bridge": "0.0.0.0/0"}
    41  
    42  	return policy.NewPURuntime(event.Name, int(event.PID), "", runtimeTags, runtimeIps, event.PUType, policy.None, options), nil
    43  }
    44  
    45  // SystemdEventMetadataExtractor is a systemd based metadata extractor
    46  // TODO: Remove OLDTAGS
    47  func SystemdEventMetadataExtractor(event *common.EventInfo) (*policy.PURuntime, error) {
    48  
    49  	runtimeTags := policy.NewTagStore()
    50  
    51  	for _, tag := range event.Tags {
    52  		parts := strings.SplitN(tag, "=", 2)
    53  		if len(parts) != 2 {
    54  			return nil, fmt.Errorf("invalid tag: %s", tag)
    55  		}
    56  		key, value := parts[0], parts[1]
    57  
    58  		if strings.HasPrefix(key, "@app:linux:") {
    59  			runtimeTags.AppendKeyValue(key, value)
    60  			continue
    61  		}
    62  
    63  		runtimeTags.AppendKeyValue("@usr:"+key, value)
    64  	}
    65  
    66  	userdata := ProcessInfo(event.PID)
    67  
    68  	for _, u := range userdata {
    69  		runtimeTags.AppendKeyValue("@app:linux:"+u, "true")
    70  	}
    71  
    72  	runtimeTags.AppendKeyValue("@os:hostname", findFQDN(time.Second))
    73  
    74  	options := policy.OptionsType{}
    75  	for index, s := range event.Services {
    76  		if s.Port != 0 && s.Ports == nil {
    77  			if pspec, err := portspec.NewPortSpec(s.Port, s.Port, nil); err == nil {
    78  				event.Services[index].Ports = pspec
    79  				event.Services[index].Port = 0
    80  			} else {
    81  				return nil, fmt.Errorf("Invalid Port Spec %s", err)
    82  			}
    83  		}
    84  	}
    85  	options.Services = event.Services
    86  	options.UserID, _ = runtimeTags.Get("@usr:originaluser")
    87  	options.CgroupMark = strconv.FormatUint(cgnetcls.MarkVal(), 10)
    88  	options.AutoPort = event.AutoPort
    89  
    90  	runtimeIps := policy.ExtendedMap{"bridge": "0.0.0.0/0"}
    91  
    92  	return policy.NewPURuntime(event.Name, int(event.PID), "", runtimeTags, runtimeIps, event.PUType, policy.None, &options), nil
    93  }
    94  
    95  // ProcessInfo returns all metadata captured by a process
    96  func ProcessInfo(pid int32) []string {
    97  	userdata := []string{}
    98  
    99  	p, err := process.NewProcess(pid)
   100  	if err != nil {
   101  		return userdata
   102  	}
   103  
   104  	uids, err := p.Uids()
   105  	if err != nil {
   106  		return userdata
   107  	}
   108  
   109  	groups, err := p.Gids()
   110  	if err != nil {
   111  		return userdata
   112  	}
   113  
   114  	username, err := p.Username()
   115  	if err != nil {
   116  		return userdata
   117  	}
   118  
   119  	for _, uid := range uids {
   120  		userdata = append(userdata, "uid:"+strconv.Itoa(int(uid)))
   121  	}
   122  
   123  	for _, gid := range groups {
   124  		userdata = append(userdata, "gid:"+strconv.Itoa(int(gid)))
   125  	}
   126  
   127  	userdata = append(userdata, "username:"+username)
   128  
   129  	userid, err := user.Lookup(username)
   130  	if err != nil {
   131  		return userdata
   132  	}
   133  
   134  	gids, err := userid.GroupIds()
   135  	if err != nil {
   136  		return userdata
   137  	}
   138  
   139  	for i := 0; i < len(gids); i++ {
   140  		userdata = append(userdata, "gids:"+gids[i])
   141  		group, err := user.LookupGroupId(gids[i])
   142  		if err != nil {
   143  			continue
   144  		}
   145  		userdata = append(userdata, "groups:"+group.Name)
   146  	}
   147  
   148  	return userdata
   149  }
   150  
   151  // Libs returns the list of dynamic library dependencies of an executable
   152  func Libs(binpath string) []string {
   153  	f, err := elf.Open(binpath)
   154  	if err != nil {
   155  		return []string{}
   156  	}
   157  
   158  	libraries, _ := f.ImportedLibraries()
   159  	return libraries
   160  }