def Initialize(config=None,
               external_hostname: Optional[Text] = None,
               admin_password: Optional[Text] = None,
               redownload_templates: bool = False,
               repack_templates: bool = True):
    """Initialize or update a GRR configuration."""

    print("Checking write access on config %s" % config["Config.writeback"])
    if not os.access(config.parser.filename, os.W_OK):
        raise IOError("Config not writeable (need sudo?)")

    print("\nStep 0: Importing Configuration from previous installation.")
    options_imported = 0
    prev_config_file = config.Get("ConfigUpdater.old_config", default=None)
    if prev_config_file and os.access(prev_config_file, os.R_OK):
        print("Found config file %s." % prev_config_file)
        # pytype: disable=wrong-arg-count
        if input("Do you want to import this configuration? "
                 "[yN]: ").upper() == "Y":
            options_imported = ImportConfig(prev_config_file, config)
        # pytype: enable=wrong-arg-count
    else:
        print("No old config file found.")

    print("\nStep 1: Setting Basic Configuration Parameters")
    print(
        "We are now going to configure the server using a bunch of questions.")
    fs_config = FleetspeakConfig()
    fs_config.Prompt(config)
    ConfigureDatastore(config)
    ConfigureUrls(config, external_hostname=external_hostname)
    ConfigureEmails(config)

    print("\nStep 2: Key Generation")
    if config.Get("PrivateKeys.server_key", default=None):
        if options_imported > 0:
            print(
                "Since you have imported keys from another installation in the "
                "last step,\nyou probably do not want to generate new keys now."
            )
        # pytype: disable=wrong-arg-count
        if (input("You already have keys in your config, do you want to"
                  " overwrite them? [yN]: ").upper() or "N") == "Y":
            config_updater_keys_util.GenerateKeys(config, overwrite_keys=True)
        # pytype: enable=wrong-arg-count
    else:
        config_updater_keys_util.GenerateKeys(config)

    fs_config.Write(config)
    FinalizeConfigInit(config,
                       admin_password=admin_password,
                       redownload_templates=redownload_templates,
                       repack_templates=repack_templates,
                       prompt=True)
def main(argv):
    del argv  # Unused.

    if not flags.FLAGS.dest_server_config_path:
        raise ValueError("dest_server_config_path flag has to be provided.")

    if not flags.FLAGS.dest_client_config_path:
        raise ValueError("dest_client_config_path flag has to be provided.")

    admin_ui_port = portpicker.pick_unused_port()
    frontend_port = portpicker.pick_unused_port()

    source_server_config_path = package.ResourcePath(
        "grr-response-core", "install_data/etc/grr-server.yaml")
    config_lib.LoadConfig(config.CONFIG, source_server_config_path)
    config.CONFIG.SetWriteBack(flags.FLAGS.dest_server_config_path)

    # TODO(user): remove when AFF4 is gone.
    config.CONFIG.Set("Database.enabled", True)

    config.CONFIG.Set("Blobstore.implementation", "DbBlobStore")
    config.CONFIG.Set("Database.implementation", "MysqlDB")
    config.CONFIG.Set("Mysql.database", flags.FLAGS.config_mysql_database)
    if flags.FLAGS.config_mysql_username is not None:
        config.CONFIG.Set("Mysql.username", flags.FLAGS.config_mysql_username)
    if flags.FLAGS.config_mysql_password is not None:
        config.CONFIG.Set("Mysql.password", flags.FLAGS.config_mysql_password)
    config.CONFIG.Set("AdminUI.port", admin_ui_port)
    config.CONFIG.Set("AdminUI.headless", True)
    config.CONFIG.Set("Frontend.bind_address", "127.0.0.1")
    config.CONFIG.Set("Frontend.bind_port", frontend_port)
    config.CONFIG.Set("Server.initialized", True)
    config.CONFIG.Set("Cron.active", False)
    config.CONFIG.Set("Client.poll_max", 1)
    config.CONFIG.Set("Client.server_urls",
                      ["http://localhost:%d/" % frontend_port])

    if flags.FLAGS.config_logging_path is not None:
        config.CONFIG.Set("Logging.path", flags.FLAGS.config_logging_path)
    config.CONFIG.Set("Logging.verbose", False)

    if flags.FLAGS.config_osquery_path:
        config.CONFIG.Set("Osquery.path", flags.FLAGS.config_osquery_path)

    config_updater_keys_util.GenerateKeys(config.CONFIG)
    config.CONFIG.Write()

    config_lib.SetPlatformArchContext()
    context = list(config.CONFIG.context)
    context.append("Client Context")
    config_data = build_helpers.GetClientConfig(context,
                                                validate=False,
                                                deploy_timestamp=False)
    with io.open(flags.FLAGS.dest_client_config_path, "w") as fd:
        fd.write(config_data)
示例#3
0
def main(argv):
    del argv  # Unused.

    if not flags.FLAGS.dest_server_config_path:
        raise ValueError("dest_server_config_path flag has to be provided.")

    if not flags.FLAGS.dest_client_config_path:
        raise ValueError("dest_client_config_path flag has to be provided.")

    admin_ui_port = portpicker.pick_unused_port()
    frontend_port = portpicker.pick_unused_port()
    datastore_port = portpicker.pick_unused_port()

    source_server_config_path = package.ResourcePath(
        "grr-response-core", "install_data/etc/grr-server.yaml")
    config_lib.LoadConfig(config.CONFIG, source_server_config_path)
    config.CONFIG.SetWriteBack(flags.FLAGS.dest_server_config_path)

    # TODO(user): remove when AFF4 is gone.
    config.CONFIG.Set("Database.aff4_enabled", False)
    config.CONFIG.Set("Database.enabled", True)

    config.CONFIG.Set("Blobstore.implementation", "DbBlobStore")
    config.CONFIG.Set("Database.implementation", "SharedMemoryDB")
    config.CONFIG.Set("SharedMemoryDB.port", datastore_port)
    config.CONFIG.Set("AdminUI.port", admin_ui_port)
    config.CONFIG.Set("AdminUI.headless", True)
    config.CONFIG.Set("Frontend.bind_address", "127.0.0.1")
    config.CONFIG.Set("Frontend.bind_port", frontend_port)
    config.CONFIG.Set("Server.initialized", True)
    config.CONFIG.Set("Client.poll_max", 1)
    config.CONFIG.Set("Client.server_urls",
                      ["http://localhost:%d/" % frontend_port])

    config_updater_keys_util.GenerateKeys(config.CONFIG)
    config.CONFIG.Write()

    config_lib.SetPlatformArchContext()
    context = list(config.CONFIG.context)
    context.append("Client Context")
    deployer = build.ClientRepacker()
    config_data = deployer.GetClientConfig(context,
                                           validate=False,
                                           deploy_timestamp=False)
    with io.open(flags.FLAGS.dest_client_config_path, "w") as fd:
        fd.write(config_data)
示例#4
0
def InitializeNoPrompt(config=None, token=None):
    """Initialize GRR with no prompts.

  Args:
    config: config object
    token: auth token

  Raises:
    ValueError: if required flags are not provided, or if the config has
      already been initialized.
    IOError: if config is not writeable
    ConfigInitError: if GRR is unable to connect to a running MySQL instance.

  This method does the minimum work necessary to configure GRR without any user
  prompting, relying heavily on config default values. User must supply the
  external hostname, admin password, and MySQL password; everything else is set
  automatically.
  """
    if config["Server.initialized"]:
        raise ValueError("Config has already been initialized.")
    if not flags.FLAGS.external_hostname:
        raise ValueError(
            "--noprompt set, but --external_hostname was not provided.")
    if not flags.FLAGS.admin_password:
        raise ValueError(
            "--noprompt set, but --admin_password was not provided.")
    if flags.FLAGS.mysql_password is None:
        raise ValueError(
            "--noprompt set, but --mysql_password was not provided.")

    print("Checking write access on config %s" % config.parser)
    if not os.access(config.parser.filename, os.W_OK):
        raise IOError("Config not writeable (need sudo?)")

    config_dict = {}
    config_dict["Datastore.implementation"] = "MySQLAdvancedDataStore"
    config_dict["Mysql.host"] = (flags.FLAGS.mysql_hostname
                                 or config["Mysql.host"])
    config_dict["Mysql.port"] = (flags.FLAGS.mysql_port
                                 or config["Mysql.port"])
    config_dict["Mysql.database_name"] = (flags.FLAGS.mysql_db
                                          or config["Mysql.database_name"])
    config_dict["Mysql.database_username"] = (
        flags.FLAGS.mysql_username or config["Mysql.database_username"])
    hostname = flags.FLAGS.external_hostname
    config_dict["Client.server_urls"] = [
        "http://%s:%s/" % (hostname, config["Frontend.bind_port"])
    ]

    config_dict["AdminUI.url"] = "http://%s:%s" % (hostname,
                                                   config["AdminUI.port"])
    config_dict["Logging.domain"] = hostname
    config_dict["Monitoring.alert_email"] = "grr-monitoring@%s" % hostname
    config_dict["Monitoring.emergency_access_email"] = ("grr-emergency@%s" %
                                                        hostname)
    config_dict["Rekall.enabled"] = flags.FLAGS.enable_rekall
    # Print all configuration options, except for the MySQL password.
    print("Setting configuration as:\n\n%s" % config_dict)
    config_dict["Mysql.database_password"] = flags.FLAGS.mysql_password
    if CheckMySQLConnection(config_dict):
        print("Successfully connected to MySQL with the given configuration.")
    else:
        print(
            "Error: Could not connect to MySQL with the given configuration.")
        raise ConfigInitError()
    for key, value in iteritems(config_dict):
        config.Set(key, value)
    config_updater_keys_util.GenerateKeys(config)
    FinalizeConfigInit(config, token)
示例#5
0
def main(args):
    """Main."""
    grr_config.CONFIG.AddContext(contexts.COMMAND_LINE_CONTEXT)
    grr_config.CONFIG.AddContext(contexts.CONFIG_UPDATER_CONTEXT)

    if args.subparser_name == "initialize":
        config_lib.ParseConfigCommandLine()
        if args.noprompt:
            config_updater_util.InitializeNoPrompt(
                grr_config.CONFIG,
                external_hostname=args.external_hostname,
                admin_password=args.admin_password,
                mysql_hostname=args.mysql_hostname,
                mysql_port=args.mysql_port,
                mysql_username=args.mysql_username,
                mysql_password=args.mysql_password,
                mysql_db=args.mysql_db,
                mysql_client_key_path=args.mysql_client_key_path,
                mysql_client_cert_path=args.mysql_client_cert_path,
                mysql_ca_cert_path=args.mysql_ca_cert_path,
                redownload_templates=args.redownload_templates,
                repack_templates=not args.norepack_templates)
        else:
            config_updater_util.Initialize(
                grr_config.CONFIG,
                external_hostname=args.external_hostname,
                admin_password=args.admin_password,
                redownload_templates=args.redownload_templates,
                repack_templates=not args.norepack_templates)
        return

    server_startup.Init()

    try:
        print("Using configuration %s" % grr_config.CONFIG)
    except AttributeError:
        raise RuntimeError("No valid config specified.")

    if args.subparser_name == "generate_keys":
        try:
            config_updater_keys_util.GenerateKeys(
                grr_config.CONFIG, overwrite_keys=args.overwrite_keys)
        except RuntimeError as e:
            # GenerateKeys will raise if keys exist and overwrite_keys is not set.
            print("ERROR: %s" % e)
            sys.exit(1)
        grr_config.CONFIG.Write()

    elif args.subparser_name == "repack_clients":
        upload = not args.noupload
        repacking.TemplateRepacker().RepackAllTemplates(upload=upload)

    elif args.subparser_name == "show_user":
        if args.username:
            print(config_updater_util.GetUserSummary(args.username))
        else:
            print(config_updater_util.GetAllUserSummaries())

    elif args.subparser_name == "update_user":
        config_updater_util.UpdateUser(args.username,
                                       password=args.password,
                                       is_admin=args.admin)

    elif args.subparser_name == "delete_user":
        config_updater_util.DeleteUser(args.username)

    elif args.subparser_name == "add_user":
        config_updater_util.CreateUser(args.username,
                                       password=args.password,
                                       is_admin=args.admin)

    elif args.subparser_name == "upload_python":
        config_updater_util.UploadSignedBinary(
            args.file,
            rdf_objects.SignedBinaryID.BinaryType.PYTHON_HACK,
            args.platform,
            upload_subdirectory=args.upload_subdirectory)

    elif args.subparser_name == "upload_exe":
        config_updater_util.UploadSignedBinary(
            args.file,
            rdf_objects.SignedBinaryID.BinaryType.EXECUTABLE,
            args.platform,
            upload_subdirectory=args.upload_subdirectory)

    elif args.subparser_name == "set_var":
        var = args.var
        val = args.val

        config = grr_config.CONFIG
        print("Setting %s to %s" % (var, val))
        if val.startswith("["):  # Allow setting of basic lists.
            val = val[1:-1].split(",")
        config.Set(var, val)
        config.Write()

    elif args.subparser_name == "switch_datastore":
        config_updater_util.SwitchToRelDB(grr_config.CONFIG)
        grr_config.CONFIG.Write()

    elif args.subparser_name == "upload_artifact":
        with io.open(args.file, "r") as filedesc:
            source = filedesc.read()
        try:
            artifact.UploadArtifactYamlFile(source,
                                            overwrite=args.overwrite_artifact)
        except rdf_artifacts.ArtifactDefinitionError as e:
            print("Error %s. You may need to set --overwrite_artifact." % e)

    elif args.subparser_name == "delete_artifacts":
        artifact_list = args.artifact
        if not artifact_list:
            raise ValueError("No artifact to delete given.")
        artifact_registry.DeleteArtifactsFromDatastore(artifact_list)
        print("Artifacts %s deleted." % artifact_list)

    elif args.subparser_name == "rotate_server_key":
        print("""
You are about to rotate the server key. Note that:

  - Clients might experience intermittent connection problems after
    the server keys rotated.

  - It's not possible to go back to an earlier key. Clients that see a
    new certificate will remember the cert's serial number and refuse
    to accept any certificate with a smaller serial number from that
    point on.
    """)

        if input("Continue? [yN]: ").upper() == "Y":
            if args.keylength:
                keylength = int(args.keylength)
            else:
                keylength = grr_config.CONFIG["Server.rsa_key_length"]

            maintenance_utils.RotateServerKey(cn=args.common_name,
                                              keylength=keylength)
示例#6
0
def InitializeNoPrompt(config=None,
                       external_hostname = None,
                       admin_password = None,
                       mysql_hostname = None,
                       mysql_port = None,
                       mysql_username = None,
                       mysql_password = None,
                       mysql_db = None,
                       mysql_client_key_path = None,
                       mysql_client_cert_path = None,
                       mysql_ca_cert_path = None,
                       redownload_templates = False,
                       repack_templates = True):
  """Initialize GRR with no prompts.

  Args:
    config: config object
    external_hostname: A hostname.
    admin_password: A password used for the admin user.
    mysql_hostname: A hostname used for establishing connection to MySQL.
    mysql_port: A port used for establishing connection to MySQL.
    mysql_username: A username used for establishing connection to MySQL.
    mysql_password: A password used for establishing connection to MySQL.
    mysql_db: Name of the MySQL database to use.
    mysql_client_key_path: The path name of the client private key file.
    mysql_client_cert_path: The path name of the client public key certificate.
    mysql_ca_cert_path: The path name of the CA certificate file.
    redownload_templates: Indicates whether templates should be re-downloaded.
    repack_templates: Indicates whether templates should be re-packed.

  Raises:
    ValueError: if required flags are not provided, or if the config has
      already been initialized.
    IOError: if config is not writeable
    ConfigInitError: if GRR is unable to connect to a running MySQL instance.

  This method does the minimum work necessary to configure GRR without any user
  prompting, relying heavily on config default values. User must supply the
  external hostname, admin password, and MySQL password; everything else is set
  automatically.
  """
  if config["Server.initialized"]:
    raise ValueError("Config has already been initialized.")
  if not external_hostname:
    raise ValueError(
        "--noprompt set, but --external_hostname was not provided.")
  if not admin_password:
    raise ValueError("--noprompt set, but --admin_password was not provided.")
  if mysql_password is None:
    raise ValueError("--noprompt set, but --mysql_password was not provided.")

  print("Checking write access on config %s" % config.parser)
  if not os.access(config.parser.filename, os.W_OK):
    raise IOError("Config not writeable (need sudo?)")

  config_dict = {}
  config_dict["Database.implementation"] = "MysqlDB"
  config_dict["Blobstore.implementation"] = "DbBlobStore"

  config_dict["Mysql.host"] = mysql_hostname or config["Mysql.host"]
  config_dict["Mysql.port"] = mysql_port or config["Mysql.port"]
  config_dict["Mysql.database_name"] = config_dict[
      "Mysql.database"] = mysql_db or config["Mysql.database_name"]
  config_dict["Mysql.database_username"] = config_dict["Mysql.username"] = (
      mysql_username or config["Mysql.database_username"])
  config_dict["Client.server_urls"] = [
      "http://%s:%s/" % (external_hostname, config["Frontend.bind_port"])
  ]
  config_dict["AdminUI.url"] = "http://%s:%s" % (external_hostname,
                                                 config["AdminUI.port"])
  config_dict["Logging.domain"] = external_hostname
  config_dict["Monitoring.alert_email"] = ("grr-monitoring@%s" %
                                           external_hostname)
  config_dict["Monitoring.emergency_access_email"] = ("grr-emergency@%s" %
                                                      external_hostname)
  # Print all configuration options, except for the MySQL password.
  print("Setting configuration as:\n\n%s" % config_dict)
  config_dict["Mysql.database_password"] = config_dict[
      "Mysql.password"] = mysql_password

  if mysql_client_key_path is not None:
    config_dict["Mysql.client_key_path"] = mysql_client_key_path
    config_dict["Mysql.client_cert_path"] = mysql_client_cert_path
    config_dict["Mysql.ca_cert_path"] = mysql_ca_cert_path

  if CheckMySQLConnection(config_dict):
    print("Successfully connected to MySQL with the given configuration.")
  else:
    print("Error: Could not connect to MySQL with the given configuration.")
    raise ConfigInitError()
  for key, value in iteritems(config_dict):
    config.Set(key, value)
  config_updater_keys_util.GenerateKeys(config)
  FinalizeConfigInit(
      config,
      admin_password=admin_password,
      redownload_templates=redownload_templates,
      repack_templates=repack_templates,
      prompt=False)
示例#7
0
def main(argv):
    """Main."""
    del argv  # Unused.

    if flags.FLAGS.subparser_name == "version":
        version = config_server.VERSION["packageversion"]
        print("GRR configuration updater {}".format(version))
        return

    token = config_updater_util.GetToken()
    grr_config.CONFIG.AddContext(contexts.COMMAND_LINE_CONTEXT)
    grr_config.CONFIG.AddContext(contexts.CONFIG_UPDATER_CONTEXT)

    if flags.FLAGS.subparser_name == "initialize":
        config_lib.ParseConfigCommandLine()
        if flags.FLAGS.noprompt:
            config_updater_util.InitializeNoPrompt(grr_config.CONFIG,
                                                   token=token)
        else:
            config_updater_util.Initialize(grr_config.CONFIG, token=token)
        return

    server_startup.Init()

    try:
        print("Using configuration %s" % grr_config.CONFIG)
    except AttributeError:
        raise RuntimeError("No valid config specified.")

    if flags.FLAGS.subparser_name == "generate_keys":
        try:
            config_updater_keys_util.GenerateKeys(
                grr_config.CONFIG, overwrite_keys=flags.FLAGS.overwrite_keys)
        except RuntimeError as e:
            # GenerateKeys will raise if keys exist and overwrite_keys is not set.
            print("ERROR: %s" % e)
            sys.exit(1)
        grr_config.CONFIG.Write()

    elif flags.FLAGS.subparser_name == "repack_clients":
        upload = not flags.FLAGS.noupload
        repacking.TemplateRepacker().RepackAllTemplates(upload=upload,
                                                        token=token)

    elif flags.FLAGS.subparser_name == "show_user":
        if flags.FLAGS.username:
            print(config_updater_util.GetUserSummary(flags.FLAGS.username))
        else:
            print(config_updater_util.GetAllUserSummaries())

    elif flags.FLAGS.subparser_name == "update_user":
        config_updater_util.UpdateUser(flags.FLAGS.username,
                                       password=flags.FLAGS.password,
                                       is_admin=flags.FLAGS.admin)

    elif flags.FLAGS.subparser_name == "delete_user":
        config_updater_util.DeleteUser(flags.FLAGS.username)

    elif flags.FLAGS.subparser_name == "add_user":
        config_updater_util.CreateUser(flags.FLAGS.username,
                                       password=flags.FLAGS.password,
                                       is_admin=flags.FLAGS.admin)

    elif flags.FLAGS.subparser_name == "upload_python":
        config_updater_util.UploadSignedBinary(
            flags.FLAGS.file,
            rdf_objects.SignedBinaryID.BinaryType.PYTHON_HACK,
            flags.FLAGS.platform,
            upload_subdirectory=flags.FLAGS.upload_subdirectory,
            token=token)

    elif flags.FLAGS.subparser_name == "upload_exe":
        config_updater_util.UploadSignedBinary(
            flags.FLAGS.file,
            rdf_objects.SignedBinaryID.BinaryType.EXECUTABLE,
            flags.FLAGS.platform,
            upload_subdirectory=flags.FLAGS.upload_subdirectory,
            token=token)

    elif flags.FLAGS.subparser_name == "set_var":
        config = grr_config.CONFIG
        print("Setting %s to %s" % (flags.FLAGS.var, flags.FLAGS.val))
        if flags.FLAGS.val.startswith("["):  # Allow setting of basic lists.
            flags.FLAGS.val = flags.FLAGS.val[1:-1].split(",")
        config.Set(flags.FLAGS.var, flags.FLAGS.val)
        config.Write()

    elif flags.FLAGS.subparser_name == "upload_artifact":
        yaml.load(open(flags.FLAGS.file, "rb"))  # Check it will parse.
        try:
            artifact.UploadArtifactYamlFile(
                open(flags.FLAGS.file, "rb").read(),
                overwrite=flags.FLAGS.overwrite_artifact)
        except rdf_artifacts.ArtifactDefinitionError as e:
            print("Error %s. You may need to set --overwrite_artifact." % e)

    elif flags.FLAGS.subparser_name == "delete_artifacts":
        artifact_list = flags.FLAGS.artifact
        if not artifact_list:
            raise ValueError("No artifact to delete given.")
        artifact_registry.DeleteArtifactsFromDatastore(artifact_list,
                                                       token=token)
        print("Artifacts %s deleted." % artifact_list)

    elif flags.FLAGS.subparser_name == "download_missing_rekall_profiles":
        print("Downloading missing Rekall profiles.")
        s = rekall_profile_server.GRRRekallProfileServer()
        s.GetMissingProfiles()

    elif flags.FLAGS.subparser_name == "rotate_server_key":
        print("""
You are about to rotate the server key. Note that:

  - Clients might experience intermittent connection problems after
    the server keys rotated.

  - It's not possible to go back to an earlier key. Clients that see a
    new certificate will remember the cert's serial number and refuse
    to accept any certificate with a smaller serial number from that
    point on.
    """)

        if builtins.input("Continue? [yN]: ").upper() == "Y":
            if flags.FLAGS.keylength:
                keylength = int(flags.FLAGS.keylength)
            else:
                keylength = grr_config.CONFIG["Server.rsa_key_length"]

            maintenance_utils.RotateServerKey(cn=flags.FLAGS.common_name,
                                              keylength=keylength)