Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent MSI support #206

Closed
wants to merge 10 commits into from
Closed

Agent MSI support #206

wants to merge 10 commits into from

Conversation

amitkanfer
Copy link
Contributor

@amitkanfer amitkanfer commented Oct 26, 2023

  • Support basic functionality e2e (copy files and execute agent install from the target folder)
  • Support uninstall
  • Check return code from agent install and fail execution if code is different than 0
  • Support custom installation folder (EDIT: not sure this is needed. See comment here)
  • Implement the buildkite logic to trigger an MSI build whenever there's a new Agent version (similar to the logic we have with beats)
  • Cleanup all temp files after agent install is executed successfully
  • check installation with endpoint

@amitkanfer amitkanfer requested a review from a team as a code owner October 26, 2023 15:09
@hmnichols
Copy link

Extremely excited to see this work, thank you!

@gabriellandau
Copy link

➕ Thank you @amitkanfer!

Copy link
Contributor

@dliappis dliappis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for raising this @amitkanfer !

Took a first look at the Buildkite failure, left a question that might help us understand the problem.

@gabriellandau
Copy link

Is it possible to enroll Agent using this MSI, or is a subsequent command required to enroll Agent?

@amitkanfer
Copy link
Contributor Author

Is it possible to enroll Agent using this MSI, or is a subsequent command required to enroll Agent?

Working on it right now, should be possible.

@amitkanfer
Copy link
Contributor Author

amitkanfer commented Oct 31, 2023

I have a working version now.
The MSI:

  1. copies all the contents of the zip file to c:\Program Files\Elastic\Beats\<version>\elastic-agent
  2. Executes the process c:\Program Files\Elastic\Beats\<version>\elastic-agent\elastic-agent.exe with the arguments install -f <args> where args are the arguments that are passed to the MSI installer.

So for example, this works:
elastic-agent-8.10.4-windows-x86_64.msi INSTALLARGS=--url=<url> --enrollment-token=<token>

After the MSI finished copying all the files, it'll run the install command for the newly deployed elastic-agent.exe file. The installer will wait for the install command to finish and only then will exit. Logic can be found here. Worth noting that the process is ran w/o the command prompt window in the background.

What's missing:

  • Validate the functionality with infosec
  • Making sure we didn't change any logic for the beats MSI installers
  • Discuss how to tackle issues when the install command fails (due to network issues, token issues etc`). Should we rollback the installation? should we retry?
  • Make the CI happy (update: CI is happy now)

Copy link
Contributor

@strawgate strawgate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple of comments

public class AgentCustomAction
{
[CustomAction]
public static ActionResult MyAction(Session session)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is we also need a custom action for uninstall?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes we do. on it... not as straightforward as it seems, unfortunately.

var textInfo = new CultureInfo("en-US", false).TextInfo;
var serviceDisplayName = $"{companyName} {textInfo.ToTitleCase(ap.TargetName)} {ap.SemVer}";
var beatsInstallPath =
$"[ProgramFiles{(ap.Is64Bit ? "64" : string.Empty)}Folder]" +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we only support 64-bit windows so this check is likely unnecessary?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct we only support 64-bit Windows.

Elastic Agent is not supported on 32-bit operating systems.

https://www.elastic.co/support/matrix

Copy link
Contributor Author

@amitkanfer amitkanfer Nov 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can change this ofcourse... but note it's the original code that is also shared with the beats MSI, i tried not to change any logic for the beats MSI.

@cmacknz
Copy link
Member

cmacknz commented Oct 31, 2023

Make sure you can install Elastic Defend for an agent that was installed with this MSI.

@cmacknz
Copy link
Member

cmacknz commented Oct 31, 2023

A few more:

  • The MSI uninstall should call elastic-agent uninstall
  • We need to present errors from the elastic-agent install command back to the user in an obvious way. This is particularly important for Fleet enrollment where first time setup is likely to fail due to incorrect credentials, proxy configurations, etc.

@nimarezainia
Copy link

Would installation in a different directory path be something we need to test also?

@amitkanfer
Copy link
Contributor Author

Updated the description with what's left to be implemented.

@gabriellandau
Copy link

gabriellandau commented Nov 1, 2023

Would installation in a different directory path be something we need to test also?

Do we need to support that on Windows? It adds complexity and risk. For example, if we allow users to install to user-writable directories, then our [un]install processes can end up writing/deleting user-controlled paths and we might unintentionally create LPEs and DoS. C:\Program Files is only-admin-writable by default, which prevents a variety of filesystem-related attacks such as this one.

@amitkanfer
Copy link
Contributor Author

Do we need to support that on Windows? It adds complexity and risk. For example, if we allow users to install to user-writable directories, then our [un]install processes can end up writing/deleting user-controlled paths and we might unintentionally create LPEs and DoS. C:\Program Files is only-admin-writable by default, which prevents a variety of filesystem-related attacks such as this one.

funny you mention this. I was just implementing the uninstall flow, and nothing in the MSI package has information about the final destination of the install command (c:\Program Files\Elastic\Agent). I had to hard code it.

@strawgate
Copy link
Contributor

The MSI way to change the directory is TARGETDIR https://learn.microsoft.com/en-us/windows/win32/msi/targetdir not sure if our current method bypasses that but refactoring around targetdir is probably the right way to get customizable install destination

@amitkanfer
Copy link
Contributor Author

@strawgate i believe Nima was referring to where agent installs itself (which is a different path than where the MSI unpacks its contents). TARGETDIR is probably the right thing to change 99% of the time, however, as i explained here, the MSI unpacks the CAB files to TARGETDIR, but then calls agent install which again copies all the files to c:\Program Files\Elastic\Agent. I believe the latter is what Nima referred to.

btw, the latest version of the MSI cleans up the TARGETDIR folder after it successfully runs the agent install command.

@amitkanfer
Copy link
Contributor Author

amitkanfer commented Nov 1, 2023

Another approach we could have taken is to unpack the contents of the MSI to the final folder (c:\Program Files\Elastic\Agent) and then register it as a service and then also call enroll. But after talking with @cmacknz we decided it'll be best to keep things simple and call install.

@cmacknz
Copy link
Member

cmacknz commented Nov 1, 2023

To change the target install path, we added the --base-path option to the install command. We could have the MSI set the value of that flag. It is slightly more complex than just unpacking agent in the new directory, some symlinks need to be set up and this is all encapsulated inside the install command today.

https://github.com/elastic/ingest-docs/blob/main/docs/en/ingest-management/commands.asciidoc#options-4

We disallowed changing the install path when using Elastic Defend, so at least in cases where someone is actively trying to use us for endpoint protection they aren't vulnerable to the arbitrary file deletion attacks Gabriel mentioned.

@amitkanfer amitkanfer closed this Nov 19, 2023
@amitkanfer
Copy link
Contributor Author

Closing this PR in favor of: #212

@amitkanfer amitkanfer mentioned this pull request Nov 19, 2023
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants