Example #1
0
def _GetLastContactFromFleetspeak(client_ids):
    """Fetches last contact times for the given clients from Fleetspeak.

  Args:
    client_ids: Iterable containing GRR client ids.

  Returns:
    A dict mapping the given client ids to timestamps representing when
    Fleetspeak last contacted the clients.
  """
    if not fleetspeak_connector.CONN or not fleetspeak_connector.CONN.outgoing:
        logging.warning(
            "Tried to get last-contact timestamps for Fleetspeak clients "
            "without an active connection to Fleetspeak.")
        return {}
    fs_ids = [fleetspeak_utils.GRRIDToFleetspeakID(cid) for cid in client_ids]
    fs_result = fleetspeak_connector.CONN.outgoing.ListClients(
        admin_pb2.ListClientsRequest(client_ids=fs_ids))
    if len(client_ids) != len(fs_result.clients):
        logging.error("Expected %d results from Fleetspeak; got %d instead.",
                      len(client_ids), len(fs_result.clients))
    last_contact_times = {}
    for fs_client in fs_result.clients:
        grr_id = fleetspeak_utils.FleetspeakIDToGRRID(fs_client.client_id)
        last_contact_times[grr_id] = fleetspeak_utils.TSToRDFDatetime(
            fs_client.last_contact_time)
    return last_contact_times
Example #2
0
def GetLabelsFromFleetspeak(client_id):
    """Returns labels for a Fleetspeak-enabled client.

  Fleetspeak-enabled clients delegate labeling to Fleetspeak, as opposed to
  using labels in the GRR config.

  Args:
    client_id: Id of the client to fetch Fleetspeak labels for.

  Returns:
    A list of client labels.
  """
    res = fleetspeak_connector.CONN.outgoing.ListClients(
        admin_pb2.ListClientsRequest(
            client_ids=[GRRIDToFleetspeakID(client_id)]))
    if not res.clients or not res.clients[0].labels:
        return []

    grr_labels = []
    label_prefix = config.CONFIG["Server.fleetspeak_label_prefix"]
    for fs_label in res.clients[0].labels:
        if (fs_label.service_name != "client" or
            (label_prefix and not fs_label.label.startswith(label_prefix))):
            continue
        try:
            grr_labels.append(fleetspeak_connector.label_map[fs_label.label])
        except KeyError:
            grr_labels.append(fs_label.label)

    return grr_labels
Example #3
0
def _GetAddrFromFleetspeak(client_id):
  res = fleetspeak_connector.CONN.outgoing.ListClients(
      admin_pb2.ListClientsRequest(
          client_ids=[fleetspeak_utils.GRRIDToFleetspeakID(client_id)]))
  if not res.clients or not res.clients[0].last_contact_address:
    return "", None
  # last_contact_address typically includes a port
  parsed = urlparse.urlparse("//{}".format(res.clients[0].last_contact_address))
  ip_str = parsed.hostname
  return ip_str, ipaddress.ip_address(ip_str)
Example #4
0
def GetLabelFromFleetspeak(client_id):
  """Returns the primary GRR label to use for a fleetspeak client."""
  res = fleetspeak_connector.CONN.outgoing.ListClients(
      admin_pb2.ListClientsRequest(client_ids=[GRRIDToFleetspeakID(client_id)]))
  if not res.clients or not res.clients[0].labels:
    return fleetspeak_connector.unknown_label

  for label in res.clients[0].labels:
    if label.service_name != "client":
      continue
    if label.label in fleetspeak_connector.label_map:
      return fleetspeak_connector.label_map[label.label]

  return fleetspeak_connector.unknown_label
Example #5
0
def UpdateClientsFromFleetspeak(clients):
  """Updates ApiClient records to include info from Fleetspeak."""
  if not fleetspeak_connector.CONN or not fleetspeak_connector.CONN.outgoing:
    # FS not configured, or an outgoing connection is otherwise unavailable.
    return
  id_map = {}
  for client in clients:
    if client.fleetspeak_enabled:
      id_map[fleetspeak_utils.GRRIDToFleetspeakID(client.client_id)] = client
  if not id_map:
    return
  res = fleetspeak_connector.CONN.outgoing.ListClients(
      admin_pb2.ListClientsRequest(client_ids=list(iterkeys(id_map))))
  for read in res.clients:
    api_client = id_map[read.client_id]
    api_client.last_seen_at = fleetspeak_utils.TSToRDFDatetime(
        read.last_contact_time)
    api_client.last_clock = fleetspeak_utils.TSToRDFDatetime(read.last_clock)
Example #6
0
    def Run(self):
        if not fleetspeak_connector.CONN or not fleetspeak_connector.CONN.outgoing:
            # Nothing to do if Fleetspeak is not enabled.
            self.Log("Fleetspeak has not been initialized. Will do nothing.")
            return

        if not data_store.RelationalDBWriteEnabled():
            raise NotImplementedError(
                "Cronjob does not support the legacy datastore.")

        age_threshold = config.CONFIG["Server.fleetspeak_last_ping_threshold"]
        max_last_ping = rdfvalue.RDFDatetime.Now() - age_threshold
        last_pings = data_store.REL_DB.ReadClientLastPings(
            max_last_ping=max_last_ping, fleetspeak_enabled=True)

        num_clients_updated = 0
        batch_size = config.CONFIG["Server.fleetspeak_list_clients_batch_size"]
        for client_ids in collection.Batch(iterkeys(last_pings), batch_size):
            fs_ids = [
                fleetspeak_utils.GRRIDToFleetspeakID(i) for i in client_ids
            ]
            request_start = rdfvalue.RDFDatetime.Now()
            fs_result = fleetspeak_connector.CONN.outgoing.ListClients(
                admin_pb2.ListClientsRequest(client_ids=fs_ids))
            latency = rdfvalue.RDFDatetime.Now() - request_start
            logging.info("Fleetspeak ListClients() took %s.", latency)
            stats_collector_instance.Get().RecordEvent(
                "fleetspeak_last_ping_latency_millis", latency.milliseconds)

            for fs_client in fs_result.clients:
                grr_id = fleetspeak_utils.FleetspeakIDToGRRID(
                    fs_client.client_id)
                new_last_ping = fleetspeak_utils.TSToRDFDatetime(
                    fs_client.last_contact_time)
                if last_pings[grr_id] is None or last_pings[
                        grr_id] < new_last_ping:
                    data_store.REL_DB.WriteClientMetadata(
                        grr_id, last_ping=new_last_ping)
                    num_clients_updated += 1

            self.Log("Updated timestamps for %d clients.", num_clients_updated)