Deployment guide

Vector 0.60.0

Overview

Vector is an observability data pipeline from Datadog's open source team. It collects logs and metrics from sources (HTTP, files, syslog, Kafka, agents and many more), transforms them with the Vector Remap Language (VRL) and routes them to sinks such as Amazon S3, CloudWatch Logs, Kinesis, OpenSearch, Loki or another Vector. It is a single Rust binary configured with one YAML file.

This SecureAnyCloud image runs Vector 0.60.0 on Ubuntu 24.04 on Amazon EC2 as a ready-to-use, authenticated HTTPS log ingest endpoint. It is one version of the SecureAnyCloud log management listing on AWS Marketplace. You select it as the software version when you subscribe and launch.

What you get:

  • HTTPS from the first boot. nginx is the only network entry point. It accepts events on https://<your-host>/ingest with a certificate generated on your instance's first boot. Port 80 only redirects to HTTPS.
  • A credential unique to your instance. Every ingest request needs HTTP Basic Auth as the user ingest. The password is generated on first boot and written to the root-only file /root/vector-credentials.txt. nginx stores only its bcrypt hash, and the credential never reaches Vector. No password is baked into the image, and no two instances share one.
  • Vector on loopback only. Vector's HTTP source (port 9880) and its GraphQL API (port 8686, used by vector top and vector tap) are bound to 127.0.0.1. Never open them in a security group.
  • Fail closed. nginx refuses to start until first boot has written the certificate and the credential, so the endpoint is never served without a login.
  • Sandboxed service. Vector runs as the unprivileged vector user with no Linux capabilities, a read-only system and write access only to /var/lib/vector.
  • Instance role access for Vector only. Vector uses the instance's IAM role via IMDSv2. No other service on the image can reach IMDS (the base OS's cloud-init and SSM Agent aside). Attach an IAM role to use the S3, CloudWatch Logs and Kinesis sinks.
  • Fixed host name and real client addresses. Requests for a host name the instance does not serve are dropped. nginx passes the real client address (client-supplied X-Forwarded-For headers are overwritten), and cross-site browser requests are refused.
  • Key-only SSH. Password logins, root logins and X11 forwarding are switched off.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Vector 0.60.0 (the unmodified upstream release package vector_0.60.0-1_amd64.deb, checksum and signature verified, MPL-2.0), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The starter pipeline is HTTPS ingest, a VRL transform that stamps each event with received_by and received_at, and a file sink under /var/lib/vector/ingest/. Replace the file sink with your own destinations in Step 7.

Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large.

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet
  • A security group that allows TCP 22 (SSH) from your own networks and TCP 443 (the ingest endpoint) from the networks your log agents are in. TCP 80 only redirects to HTTPS and is optional. If your agents run inside the same VPC, allow 443 from the VPC CIDR only.
  • Optional: an IAM instance profile, if Vector should write to Amazon S3, CloudWatch Logs or Kinesis (Step 7)
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Vector 0.60.0 on Ubuntu 24.04 as the software version and select your Region. Then choose Launch through EC2.

Choose m5.large, your key pair, and a security group as described above. If you will use the AWS sinks, add an IAM instance profile. Under Advanced details, keep Metadata version at V2 only and set Metadata response hop limit to 1.

To launch with the AWS CLI instead, replace the values in angle brackets:

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --iam-instance-profile Name=<your-instance-profile> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled,HttpPutResponseHopLimit=1 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=vector}]'

The AMI is IMDSv2 only. A hop limit of 1 keeps the instance role's credentials on the instance itself, because containers and forwarded traffic cannot reach the metadata service.

2

Connect to your instance

Version SSH user

Vector 0.60.0 on Ubuntu 24.04 ubuntu

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

On first boot, the instance generates the certificate and the credential, and then nginx starts in front of Vector. Confirm that the services are active:

systemctl is-active vector nginx vector-firstboot
sudo test -f /var/lib/sac/data/vector-firstboot.done && echo FIRSTBOOT_DONE vector --version curl -s http://127.0.0.1:8686/health; echo
active active active FIRSTBOOT_DONE vector 0.60.0 (x86_64-unknown-linux-gnu 0d0b358 2026-10-19 16:56:14.309955068) {"ok":true}

Only SSH and nginx listen on public addresses. Vector listens on loopback:

sudo ss -Hlntp | awk '{print $4, $6}' | grep -v '127.0.0.5' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g' | sort
0.0.0.0:22 users:(("sshd"),("systemd")) 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx")) 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) 127.0.0.1:8686 users:(("vector")) 127.0.0.1:9880 users:(("vector")) [::]:22 users:(("sshd"),("systemd")) [::]:443 users:(("nginx"),("nginx"),("nginx")) [::]:80 users:(("nginx"),("nginx"),("nginx"))
4

Get your ingest URL and credential

The URL, the user name and the certificate path are in the root-only credentials file:

sudo grep -E '^VECTOR_(INGEST_URL|INGEST_USER|CA_CERT|SINK_DIR)=' /root/vector-credentials.txt
VECTOR_INGEST_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/ingest VECTOR_INGEST_USER=ingest VECTOR_CA_CERT=/etc/ssl/vector/vector.crt VECTOR_SINK_DIR=/var/lib/vector/ingest

The password is the VECTOR_INGEST_PASSWORD line of the same file: sudo grep '^VECTOR_INGEST_PASSWORD=' /root/vector-credentials.txt. It is unique to this instance. Store it in your password manager or secrets store.

The URL uses the instance's public DNS name from EC2 instance metadata (IMDSv2), or its public or private IPv4 address when it has no public name. The certificate names that host plus the instance's public and private IP addresses, so agents can use any of them:

openssl x509 -in /etc/ssl/vector/vector.crt -noout -subject -ext subjectAltName -enddate
subject=CN = ec2-<public-ip-dashed>.compute-1.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost notAfter=<date about 27 months after first boot>
5

Check the login

Confirm that the endpoint enforces its login. A request without the credential is refused, a wrong password is refused, only POST /ingest is accepted, and port 80 redirects to HTTPS.

The commands below read the password from the credentials file into a shell variable and pass it to curl through a file descriptor. The password never appears in the process list or your shell history.

U=$(sudo sed -n 's/^VECTOR_INGEST_URL=//p' /root/vector-credentials.txt); H=${U#https://}; H=${H%%/*}
PW=$(sudo sed -n 's/^VECTOR_INGEST_PASSWORD=//p' /root/vector-credentials.txt) CA=/etc/ssl/vector/vector.crt curl -s -o /dev/null -w 'http:// -> %{http_code} %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/ingest" curl -s -o /dev/null -w 'no login -> HTTP %{http_code}\n' --cacert $CA --resolve "$H:443:127.0.0.1" -X POST -d '{}' "$U" curl -s -o /dev/null -w 'wrong password -> HTTP %{http_code}\n' --cacert $CA --resolve "$H:443:127.0.0.1" -K <(printf 'user = "ingest:not-the-password"\n') -X POST -d '{}' "$U" curl -s -o /dev/null -w 'ingest + password -> HTTP %{http_code}\n' --cacert $CA --resolve "$H:443:127.0.0.1" -K <(printf 'user = "ingest:%s"\n' "$PW") -X POST -d '{"message":"login check"}' "$U" curl -s -o /dev/null -w 'GET /ingest -> HTTP %{http_code}\n' --cacert $CA --resolve "$H:443:127.0.0.1" -K <(printf 'user = "ingest:%s"\n' "$PW") "$U"
http:// -> 301 https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/ingest no login -> HTTP 401 wrong password -> HTTP 401 ingest + password -> HTTP 200 GET /ingest -> HTTP 403

--resolve sends the request to this instance while keeping the real host name, so the certificate check passes. From another machine, drop --resolve and use the URL directly.

6

Send events and see them arrive

The endpoint accepts newline-delimited JSON, one event per line. Send three events, then read the newest lines of today's file sink:

U=$(sudo sed -n 's/^VECTOR_INGEST_URL=//p' /root/vector-credentials.txt); H=${U#https://}; H=${H%%/*}
PW=$(sudo sed -n 's/^VECTOR_INGEST_PASSWORD=//p' /root/vector-credentials.txt) CA=/etc/ssl/vector/vector.crt for svc in web-01 web-02 db-01; do printf '{"message":"order placed","service":"checkout","host":"%s","level":"info"}\n' "$svc" done | curl -s -o /dev/null -w 'ingest -> HTTP %{http_code}\n' --cacert $CA --resolve "$H:443:127.0.0.1" \
  -K <(printf 'user = "ingest:%s"\n' "$PW") -H 'Content-Type: application/x-ndjson' --data-binary @- "$U" sleep 2
sudo tail -n 3 /var/lib/vector/ingest/ingest-$(date -u +%F).log | jq -c '{host, level, message, received_by}'
ingest -> HTTP 200 {"host":"web-01","level":"info","message":"order placed","received_by":"vector"} {"host":"web-02","level":"info","message":"order placed","received_by":"vector"} {"host":"db-01","level":"info","message":"order placed","received_by":"vector"}

Each event also carries received_at, the time Vector accepted it, added by the stamp transform.

To watch events flow live, run vector top (throughput per component) or vector tap --outputs-of stamp (the events themselves) on the instance. Both use the loopback GraphQL API.

7

Route events to your own destinations

The pipeline lives in /etc/vector/vector.yaml. Add a sink, point its inputs at stamp, then validate and apply the change:

sudo nano /etc/vector/vector.yaml
sudo vector validate /etc/vector/vector.yaml
sudo systemctl reload vector

Amazon S3 uses the instance's IAM role. Attach a role that allows s3:PutObject on the bucket:

sinks: archive_s3: type: aws_s3 inputs: [stamp] bucket: <your-bucket> region: <region> key_prefix: "vector/%Y/%m/%d/" compression: gzip encoding: codec: json

CloudWatch Logs needs a role with logs:CreateLogStream, logs:PutLogEvents and logs:DescribeLogStreams:

sinks: cloudwatch: type: aws_cloudwatch_logs inputs: [stamp] region: <region> group_name: <your-log-group> stream_name: "{{ host }}" encoding: codec: json

Vector uses the instance's IAM role via IMDSv2, and no other service on the image can reach IMDS. You never put AWS access keys in the configuration.

Other destinations (OpenSearch, Loki, Kafka, HTTP, another Vector) work the same way. See the upstream sink reference. Keep any destination password or token in a root-only file referenced from the configuration, never in a world-readable file. To stop writing the local copy, remove the ingest_archive sink.

8

Send logs from your servers

Any agent that can POST JSON over HTTPS works. Give it the URL, the user ingest, the password and the instance's certificate, so it can verify the connection. Copy the certificate to each agent host first. The certificate is public, not a secret:

scp -i <your-key.pem> ubuntu@<vector-host>:/etc/ssl/vector/vector.crt ./vector.crt

Fluent Bit ([OUTPUT] section):

[OUTPUT] Name http Match * Host <vector-host> Port 443 URI /ingest Format json_lines tls On tls.verify On tls.ca_file /etc/fluent-bit/vector.crt http_User ingest http_Passwd <VECTOR_INGEST_PASSWORD>

Another Vector can run as an edge agent that forwards to this instance:

sinks: to_central: type: http inputs: [your_source] uri: "<VECTOR_INGEST_URL>" method: post encoding: codec: json framing: method: newline_delimited auth: strategy: basic user: ingest password: "${VECTOR_INGEST_PASSWORD}" tls: ca_file: /etc/vector/central.crt

Keep the password in the agent's own secret store or a root-only file, not in a world-readable configuration. Agents send no browser Origin header, so the image's cross-site request guard does not affect them.

To accept other protocols (syslog, Fluent forward, Kafka), add the source in vector.yaml, bound to the address you need. Open that port in the security group only to your VPC or VPN CIDRs, never to 0.0.0.0/0. Those ports stay closed until you open them.

9

Use your own DNS name or certificate

The served host name is fixed by configuration and never taken from a request. To serve the endpoint under your own DNS name, point the name at the instance and run the helper. It records the name, regenerates the self-signed certificate for it, updates the credentials file and reloads nginx:

sudo vector-set-hostname <your-dns-name>

Run the same command after a stop and start if the instance's public DNS name changed. An Elastic IP avoids that. A request for a name the instance does not serve is dropped.

To use a certificate from your own CA or a public CA instead, replace /etc/ssl/vector/vector.crt (full chain) and /etc/ssl/vector/vector.key (mode 0600, owner root). Then run sudo nginx -t && sudo systemctl reload nginx. Alternatively, put the instance behind an Application Load Balancer with an AWS Certificate Manager certificate that forwards to port 443.

10

Security notes

Vector runs as its own unprivileged user with no capabilities and a read-only system. nginx cannot reach the instance metadata service. Verify both:

systemctl show vector -p User -p NoNewPrivileges -p ProtectSystem -p ProtectHome -p CapabilityBoundingSet
systemctl show nginx -p IPAddressDeny
CapabilityBoundingSet= User=vector ProtectHome=yes ProtectSystem=strict NoNewPrivileges=yes IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32

SSH accepts keys only. Passwords, root logins and X11 forwarding are switched off in /etc/ssh/sshd_config.d/00-sac.conf, which sorts before every other SSH setting. Check the effective values:

sudo sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin|x11forwarding|pubkeyauthentication) '
permitrootlogin no pubkeyauthentication yes passwordauthentication no kbdinteractiveauthentication no x11forwarding no

A request carrying a foreign browser Origin is refused, even with the right password. A web page therefore cannot post events through a browser that holds the credential:

U=$(sudo sed -n 's/^VECTOR_INGEST_URL=//p' /root/vector-credentials.txt); H=${U#https://}; H=${H%%/*}
PW=$(sudo sed -n 's/^VECTOR_INGEST_PASSWORD=//p' /root/vector-credentials.txt)
curl -s -o /dev/null -w 'Origin evil.example ingest -> HTTP %{http_code}\n' --cacert /etc/ssl/vector/vector.crt --resolve "$H:443:127.0.0.1" -K <(printf 'user = "ingest:%s"\n' "$PW") -H 'Origin: https://evil.example' -d '{"message":"x"}' "$U"
Origin evil.example ingest -> HTTP 403

Other points:

  • Only root can change the pipeline. Vector fetches no URL that a remote party supplies.
  • nginx passes the real client address of every request. X-Forwarded-For headers sent by clients are ignored.
  • The AMI requires IMDSv2. Restrict port 443 to the networks your agents use, and never open 8686 or 9880.
  • To rotate the password, generate a new one and write its bcrypt hash with sudo htpasswd -iB /etc/nginx/vector.htpasswd ingest (it reads the new password from standard input). Then update /root/vector-credentials.txt, reload nginx and update your agents.

Support and licensing

Vector is open source under the Mozilla Public License 2.0. The image ships the unmodified upstream release package, and there is no per-host or per-CPU license fee. The AMI price covers SecureAnyCloud's hardening, first-boot setup and support.

  • Email: sales@secureanycloud.com
  • Website: https://secureanycloud.com

For sources, transforms, sinks and VRL, see the upstream Vector documentation.

Vector is named only to identify the unmodified upstream software, which is developed by Datadog, Inc. SecureAnyCloud is not affiliated with or endorsed by Datadog.

Deploy on AWS

Launch Vector 0.60.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS