29. 06. 2026 Reinhold Trocker Uncategorized

Distribute Elastic Endpoint Artifacts via NetEye Satellites

In real-world security environments, “simple” rarely means simple. As a technical consultant, I often see Elastic Defend deployed in infrastructures that are anything but standard: segmented networks, restricted outbound connectivity, compliance-driven isolation, and operational constraints that make direct internet access impossible for managed endpoints.

One recurring requirement in these environments is the local delivery of Elastic Endpoint artifacts. Elastic documents the general approach for offline endpoints and air-gapped environments here:

In this article, I want to focus on a practical implementation variant in NetEye-based installations: providing Elastic Endpoint artifacts locally through a NetEye Satellite (that already runs the nginx-satellite service).

Rather than building a separate web infrastructure just for artifact delivery, we can use the existing HTTPS service on the satellite and expose the required files in a clean, maintainable way.

This is somehow a ‘sister’ blog of Enabling Elastic Agents Upgrades in Restricted or Closed Networks.

Why this matters

Elastic Endpoint components need access to artifact updates. In connected environments, these are typically retrieved from Elastic-managed infrastructure. In restricted or air-gapped setups, however, this model does not work.

That means we need to:

  • host the artifacts locally,
  • make them reachable via HTTPS,
  • ensure the delivery path fits the architecture already in place,
  • and keep the setup operationally simple for complex customer environments.

For NetEye Satellites, this is a natural fit because nginx-satellite is already available and can serve as the local HTTPS endpoint.

Scenario: NetEye Satellite as local artifact server

In this setup, the NetEye Satellite serves the Elastic Defend artifacts through its existing web server.

The resulting URL looks like this:

https://satname/neteyeshare/defendartifacts

This path points to:

/usr/share/nginx/html/neteyeshare/defendartifacts

So from an implementation perspective, the satellite becomes the local artifact repository exposed over HTTPS.

Preparation and prerequisites

Before starting, make sure the following prerequisites are met:

  • the NetEye Satellite is up and running,
  • the nginx-satellite service is active,
  • HTTPS access to the satellite is working,
  • and the artifact files are available or will be synchronized into the target directory.

The key assumption for this blog post is that nginx-satellite is already serving content successfully, and we are extending that setup for Elastic Defend artifacts.

Directory structure

The directory used for publishing the files is:

/usr/share/nginx/html/neteyeshare/defendartifacts

This is exposed through the URL:

https://satname/neteyeshare/defendartifacts

This URL (substitute satname with the hostname of your satellite) has to be used as described by elastic defend documentation:

Set the advanced.artifacts.global.base_url advanced setting for each Elastic Defend integration policy that needs to use the mirror. Note that there’s a separate setting for each operating system:

  • linux.advanced.artifacts.global.base_url
  • mac.advanced.artifacts.global.base_url
  • windows.advanced.artifacts.global.base_url

If the directory does not yet exist, create it and ensure the files placed there are readable by nginx.

Download the artifacts periodically

A local artifact repository is only useful if it is kept current. This means the artifacts have to be downloaded periodically onto the satellites.

A practical example is:

export ENDPOINT_VERSION=9.3.0 && wget -P downloads/endpoint/manifest https://artifacts.security.elastic.co/downloads/endpoint/manifest/artifacts-$ENDPOINT_VERSION.zip && zcat -q downloads/endpoint/manifest/artifacts-$ENDPOINT_VERSION.zip | jq -r '.artifacts | to_entries[] | .value.relative_url' | xargs -I@ curl "https://artifacts.security.elastic.co@" --create-dirs -o ".@"

Please note that the version should be matching the version of your elastic agents. That version usually corresponds with the version of the elasticsearch installed on your NetEye cluster, so use the following command on elasticsearch nodes, to find out your version:

/usr/share/neteye/elasticsearch/scripts/es_curl.sh -s  https://elasticsearch.neteyelocal:9200/ | jq .version.number -r

In practice, you will usually wrap this into an operational procedure or scheduled job so that each satellite receives the required artifact set regularly.

The key point is simple: hosting artifacts locally is not a one-time task. It is an ongoing synchronization responsibility.

Fix permissions so nginx can serve the files

After downloading or updating the artifacts, permissions should be fixed so that nginx can actually serve the files on the satellite.

A common approach is to ensure the files and directories are readable and traversable as needed, for example:

chown -R +u+r /usr/share/nginx/html/neteyeshare/defendartifacts

or, where directory traversal permissions are also required:

chown -R +u+rx /usr/share/nginx/html/neteyeshare/defendartifacts

Operationally, the important point is not the exact command variant used in every environment, but that ownership and permissions must be corrected consistently after artifact updates. Otherwise, the files may exist on disk but still not be retrievable through nginx-satellite.

Important detail: ETag header configuration is critical

This is the part that deserves special emphasis.

When implementing local artifact hosting for Elastic Endpoint, correct handling of the ETag header is not a cosmetic improvement. It is a critical part of making the locally served artifacts behave as expected.

In NetEye Satellite setups, the main implementation detail is that the ETag generated by nginx may need to be transformed before being returned to the client. If this is overlooked, the endpoint may retrieve artifacts incorrectly or fail to validate them the way the integration expects.

In other words: if you only remember one technical detail from this article, let it be this one – pay close attention to the ETag header and how it is calculated.

Create the ETag mapping

Create a file next to the default HTTPS nginx configuration, for example:

map_elastic_etag.conf

Use the following content:

map $sent_http_etag $elastic_etag {
  "~(.*)-(.*)" "$1$2";
}

This mapping is the key piece.

What it does is take the ETag value generated by nginx and transform it by removing the separator between the two captured groups. In practical terms, nginx may produce an ETag in a format that is not ideal for this use case, and the map rewrites it into the form expected by the Elastic Endpoint artifact workflow.

That means the calculation and delivery of the ETag are explicitly controlled, instead of just relying on the default behavior.

Add the location configuration

Next, create a location snippet in the nginx locations directory, for example:

defendartifacts_location.conf

Use content similar to the following:

location /neteyeshare/defendartifacts {
    add_header ETag "$elastic_etag";
}

This ensures that requests to the artifact path return the adjusted ETag header.

Again, this deserves emphasis: the location itself is simple, but its purpose is essential. It does not merely expose the files; it makes sure the ETag returned for artifact requests is the mapped one, not just the unmodified default.

Depending on the local nginx structure in your environment, you may want to extend this snippet with additional directives such as autoindex off, explicit MIME handling, or access restrictions. But for the core use case, the critical point is that the location serving /neteyeshare/defendartifacts includes the rewritten ETag header.

Restart nginx-satellite on all satellites

After the configuration changes, all satellites should do:

restart service nginx-satellite

This is a straightforward but important operational step. Without restarting the service, the new mapping and location configuration will not become active.

Practical implementation notes

From a consultant’s perspective, this approach is especially useful because it fits neatly into existing NetEye Satellite designs:

  • no separate artifact web server is required,
  • no additional reverse proxy layer is needed,
  • the HTTPS endpoint already exists,
  • and the implementation remains transparent for operations teams.

In complex customer environments, reducing moving parts is often more valuable than designing a theoretically perfect but operationally heavy solution. Reusing nginx-satellite keeps the architecture understandable and supportable.

What to verify after configuration

After creating the directory, downloading artifacts, fixing permissions, and adding the nginx snippets, validate the setup carefully.

Recommended checks include:

  • confirm the nginx configuration is syntactically valid,
  • restart nginx-satellite,
  • verify that https://satname/neteyeshare/defendartifacts is reachable,
  • confirm that the expected files are downloadable,
  • and inspect the HTTP response headers, especially ETag.

A simple test with curl -I from a system that can reach the satellite is usually enough to validate the header behavior.

For example, you should verify that:

  • the endpoint answers via HTTPS,
  • the artifact path is correct,
  • the files are readable through nginx,
  • and the returned ETag matches the transformed format introduced by the nginx map.

Operational considerations

A few operational points are worth keeping in mind:

  • Artifact content must be kept up to date. Hosting locally solves the connectivity problem, but it also makes you responsible for maintaining the repository content.
  • Certificates must be trusted by the systems consuming the artifacts. In isolated environments, internal PKI and trust distribution are often part of the real project effort.
  • File ownership and permissions must be checked after every update cycle.
  • The ETag behavior should be treated as a first-class validation item, not as an afterthought.
  • Changes should be implemented in a way that survives standard NetEye and nginx maintenance procedures.
  • Documentation matters. In complex installations, future troubleshooting is much easier when the relationship between the URL, filesystem path, nginx snippets, and synchronization process is clearly documented.

Final thoughts

Implementing Elastic’s offline endpoint artifact delivery in a NetEye environment is not just about reproducing vendor documentation. In practice, it is about adapting the concept to the customer’s existing architecture in a way that is robust, simple, and supportable.

When a NetEye Satellite already provides HTTPS via nginx-satellite, using it to publish Elastic Defend artifacts is an efficient solution. The required setup is relatively small:

  • expose a dedicated directory,
  • publish it under /neteyeshare/defendartifacts,
  • download and refresh the artifacts periodically,
  • fix permissions so nginx can serve the content,
  • and carefully adjust ETag handling with a lightweight nginx mapping.

For complex and segmented environments, this gives you a pragmatic way to provide Elastic Endpoint artifacts locally without introducing unnecessary infrastructure.

If you are implementing this in a customer setup, my recommendation is straightforward: keep it simple, validate headers carefully, and treat ETag calculation as a core part of the solution rather than a minor nginx detail.

Reinhold Trocker

Reinhold Trocker

IT professional, IT security, (ISC)2 CISSP, technical consultant

Author

Reinhold Trocker

IT professional, IT security, (ISC)2 CISSP, technical consultant

Leave a Reply

Your email address will not be published. Required fields are marked *

Archive