func configRunRoutes() { http.HandleFunc("/run", func(w http.ResponseWriter, r *http.Request) { if g.IsTrustable(r.RemoteAddr) { if r.ContentLength == 0 { http.Error(w, "body is blank", http.StatusBadRequest) return } bs, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } body := string(bs) out, err := sys.CmdOutBytes("sh", "-c", body) if err != nil { w.Write([]byte("exec fail: " + err.Error())) return } w.Write(out) } else { w.Write([]byte("no privilege")) } }) }
func ListeningPorts() ([]int64, error) { ports := []int64{} bs, err := sys.CmdOutBytes("ss", "-t", "-l", "-n") if err != nil { return ports, err } reader := bufio.NewReader(bytes.NewBuffer(bs)) // ignore the first line line, err := file.ReadLine(reader) if err != nil { return ports, err } for { line, err = file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return ports, err } fields := strings.Fields(string(line)) fieldsLen := len(fields) if fieldsLen != 4 && fieldsLen != 5 { return ports, fmt.Errorf("output of [ss -t -l -n] format not supported") } portColumnIndex := 2 if fieldsLen == 5 { portColumnIndex = 3 } location := strings.LastIndex(fields[portColumnIndex], ":") port := fields[portColumnIndex][location+1:] if p, e := strconv.ParseInt(port, 10, 64); e != nil { return ports, fmt.Errorf("parse port to int64 fail: %s", e.Error()) } else { ports = append(ports, p) } } return slice.UniqueInt64(ports), nil }
func SocketStatSummary() (m map[string]uint64, err error) { m = make(map[string]uint64) var bs []byte bs, err = sys.CmdOutBytes("sh", "-c", "ss -s") if err != nil { return } reader := bufio.NewReader(bytes.NewBuffer(bs)) // ignore the first line line, e := file.ReadLine(reader) if e != nil { return m, e } for { line, err = file.ReadLine(reader) if err != nil { return } lineStr := string(line) if strings.HasPrefix(lineStr, "TCP") { left := strings.Index(lineStr, "(") right := strings.Index(lineStr, ")") if left < 0 || right < 0 { continue } content := lineStr[left+1 : right] arr := strings.Split(content, ", ") for _, val := range arr { fields := strings.Fields(val) if fields[0] == "timewait" { timewait_arr := strings.Split(fields[1], "/") m["timewait"], _ = strconv.ParseUint(timewait_arr[0], 10, 64) m["slabinfo.timewait"], _ = strconv.ParseUint(timewait_arr[1], 10, 64) continue } m[fields[0]], _ = strconv.ParseUint(fields[1], 10, 64) } return } } return }
func PingStatSummary(ip string, count, timeout int) (m map[string]string, err error) { m = make(map[string]string) var bs []byte bs, err = sys.CmdOutBytes("ping", "-c", strconv.Itoa(count), "-W", strconv.Itoa(timeout), ip) if err != nil { return m, err } reader := bufio.NewReader(bytes.NewBuffer(bs)) // ignore the first line line, e := file.ReadLine(reader) if e != nil { return m, e } for { line, err = file.ReadLine(reader) if err == io.EOF { err = nil break } else if err != nil { return m, err } lineStr := string(line) if strings.Contains(lineStr, "packet loss") { arr := strings.Split(lineStr, ", ") for _, val := range arr { fields := strings.Fields(val) if fields[1] == "packet" { m["pkloss"] = fields[0] } } } if strings.Contains(lineStr, "min/avg/max") { fields := strings.Fields(lineStr) result := strings.Split(fields[3], "/") m["min"] = result[0] m["avg"] = result[1] m["max"] = result[2] } } return m, e }
func probeUrl(furl string, timeout string) (bool, error) { bs, err := sys.CmdOutBytes("curl", "--max-filesize", "102400", "-I", "-m", timeout, "-o", "/dev/null", "-s", "-w", "%{http_code}", furl) if err != nil { log.Printf("probe url [%v] failed.the err is: [%v]\n", furl, err) return false, err } reader := bufio.NewReader(bytes.NewBuffer(bs)) retcode, err := file.ReadLine(reader) if err != nil { log.Println("read retcode failed.err is:", err) return false, err } if strings.TrimSpace(string(retcode)) != "200" { log.Printf("return code [%v] is not 200.query url is [%v]", string(retcode), furl) return false, err } return true, err }