Links#
https://docs.victoriametrics.com/victorialogs/security-and-lb/
https://docs.victoriametrics.com/victoriametrics/vmauth/
https://docs.victoriametrics.com/victorialogs/data-ingestion/
https://docs.victoriametrics.com/victorialogs/querying/
https://docs.fluentbit.io/manual/data-pipeline/outputs/http1. Target#
目标是不要把 VictoriaLogs 直接暴露给客户端,而是在前面放 vmauth 做认证和路径路由。
clients / ECS FireLens / browser
-> vmauth :8427
-> VictoriaLogs :9428账号拆分:
logs-ingest:
only /insert/.*
给 ECS FireLens / collector 用
logs-reader:
only /select/.*
给查询、UI、Grafana 或人工排查用
logs-admin:
/insert/.* and /select/.*
只用于临时排查或 break-glass2. Recommended Layout#
/opt/victorialogs-auth/
├── docker-compose.yml
└── vmauth.yml外部只暴露 vmauth:
public / client reachable:
vmauth:8427
private only:
victorialogs:9428生产上再把 vmauth 放到 ALB / Nginx / Caddy / ingress 后面做 TLS。
3. vmauth Config#
vmauth.yml:
users:
- username: logs-ingest
password: change-ingest-password
url_map:
- src_paths:
- "/insert/.*"
url_prefix: "http://victorialogs:9428"
- username: logs-reader
password: change-reader-password
url_map:
- src_paths:
- "/select/.*"
url_prefix: "http://victorialogs:9428"
- username: logs-admin
password: change-admin-password
url_map:
- src_paths:
- "/insert/.*"
url_prefix: "http://victorialogs:9428"
- src_paths:
- "/select/.*"
url_prefix: "http://victorialogs:9428"规则:
logs-ingest:
can write logs
cannot query logs
cannot open UI
logs-reader:
can query logs
can open /select/vmui/
cannot write logs4. Docker Compose Hands-on#
docker-compose.yml:
services:
victorialogs:
image: docker.io/victoriametrics/victoria-logs:v1.50.0
command:
- -storageDataPath=/victoria-logs-data
- -httpListenAddr=:9428
volumes:
- victorialogs-data:/victoria-logs-data
expose:
- "9428"
vmauth:
image: docker.io/victoriametrics/vmauth:v1.103.0
command:
- -auth.config=/etc/vmauth/vmauth.yml
- -httpListenAddr=:8427
ports:
- "8427:8427"
volumes:
- ./vmauth.yml:/etc/vmauth/vmauth.yml:ro
depends_on:
- victorialogs
volumes:
victorialogs-data:Start:
mkdir -p /opt/victorialogs-auth
cd /opt/victorialogs-auth
docker compose up -d
docker compose psCheck logs:
docker compose logs -f victorialogs
docker compose logs -f vmauth5. Run vmauth With systemd#
如果 VictoriaLogs 已经用 systemctl 方式启动,vmauth 也建议用独立 systemd service 管理。这样启动命令、重启策略、日志和开机自启都能从 systemd 查到。
install binary#
vmauth binary comes from the VictoriaMetrics vmutils release archive. Pin the version instead of using a floating latest URL.
release page:
https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.103.0
download:
vmutils-linux-amd64-v1.103.0.tar.gz for Linux x86_64
vmutils-linux-arm64-v1.103.0.tar.gz for Linux ARM64Download example:
curl -LO https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.103.0/vmutils-linux-amd64-v1.103.0.tar.gzInstall vmauth:
mkdir -p /tmp/vmutils-v1.103.0
tar -xzf vmutils-linux-amd64-v1.103.0.tar.gz -C /tmp/vmutils-v1.103.0
ls -l /tmp/vmutils-v1.103.0/vmauth*
# Install vmauth-prod as /usr/local/bin/vmauth so systemd uses a stable and readable command name.
sudo install -m 0755 /tmp/vmutils-v1.103.0/vmauth-prod /usr/local/bin/vmauth
/usr/local/bin/vmauth -versionIf your archive contains vmauth instead of vmauth-prod, install that file:
sudo install -m 0755 /tmp/vmutils-v1.103.0/vmauth /usr/local/bin/vmauthdirectories#
sudo useradd --system --no-create-home --shell /usr/sbin/nologin vmauth
sudo mkdir -p /etc/vmauth
sudo chown root:vmauth /etc/vmauth
sudo chmod 0750 /etc/vmauthPlace config:
/etc/vmauth/vmauth.ymlPermissions:
sudo chown root:vmauth /etc/vmauth/vmauth.yml
sudo chmod 0640 /etc/vmauth/vmauth.ymlconfig for local VictoriaLogs#
如果 VictoriaLogs 在同一台机器监听 127.0.0.1:9428,url_prefix 用 loopback,避免绕过本机防火墙暴露后端。
users:
- username: logs-ingest
password: change-ingest-password
url_map:
- src_paths:
- "/insert/.*"
url_prefix: "http://127.0.0.1:9428"
- username: logs-reader
password: change-reader-password
url_map:
- src_paths:
- "/select/.*"
url_prefix: "http://127.0.0.1:9428"
- username: logs-admin
password: change-admin-password
url_map:
- src_paths:
- "/insert/.*"
url_prefix: "http://127.0.0.1:9428"
- src_paths:
- "/select/.*"
url_prefix: "http://127.0.0.1:9428"systemd unit#
/etc/systemd/system/vmauth.service:
[Unit]
Description=VictoriaMetrics vmauth for VictoriaLogs
Documentation=https://docs.victoriametrics.com/victoriametrics/vmauth/
After=network-online.target victorialogs.service
Wants=network-online.target
[Service]
Type=simple
User=vmauth
Group=vmauth
ExecStart=/usr/local/bin/vmauth \
-auth.config=/etc/vmauth/vmauth.yml \
-httpListenAddr=:8427
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.targetNotes:
ExecStart:
adjust /usr/local/bin/vmauth to your real binary path
After=victorialogs.service:
useful when VictoriaLogs service is named victorialogs
remove or rename it if your unit name is different
httpListenAddr:
use :8427 if a reverse proxy / firewall controls access
use 127.0.0.1:8427 if only local Nginx/Caddy/ALB agent should reach itstart and enable#
sudo systemctl daemon-reload
sudo systemctl enable --now vmauth
sudo systemctl status vmauthLogs:
journalctl -u vmauth -n 200
journalctl -u vmauth -fVerify process source:
pid=$(systemctl show vmauth --property=MainPID --value)
ps -o pid,ppid,user,tty,stat,lstart,cmd -p "$pid"
systemctl cat vmauth
cat /proc/"$pid"/cgroupExpected:
systemctl status vmauth shows active/running
cgroup contains /system.slice/vmauth.service
ExecStart points to vmauth with -auth.config=/etc/vmauth/vmauth.ymlfirewall / exposure#
same host reverse proxy:
bind vmauth to 127.0.0.1:8427
expose only Nginx/Caddy/ALB listener
internal network clients:
bind vmauth to :8427
allow 8427 only from trusted collector/query networks
always:
keep VictoriaLogs :9428 private
clients should not bypass vmauthrestart after config change#
vmauth -help | grep -E 'auth.config|httpListenAddr'
sudo systemctl restart vmauth
sudo systemctl status vmauth
journalctl -u vmauth -n 1006. Verify Auth#
health through vmauth#
If /health is not mapped in vmauth.yml, this should return unauthorized or no route:
curl -i http://localhost:8427/healthThat is acceptable. Clients should use authenticated /insert/* and /select/* paths.
ingest with writer#
echo '{"date":"2026-06-10T08:15:30Z","service":"order-api","env":"uat","log":"hello auth"}' \
| curl -i \
-u logs-ingest:change-ingest-password \
-H 'content-type: application/stream+json' \
--data-binary @- \
'http://localhost:8427/insert/jsonline?_stream_fields=service,env&_time_field=date&_msg_field=log'Expected:
HTTP 2xxquery with reader#
curl -i \
-u logs-reader:change-reader-password \
-G 'http://localhost:8427/select/logsql/query' \
--data-urlencode 'query=service:order-api'Expected:
HTTP 2xx
logs contain hello authreader cannot insert#
echo '{"date":"2026-06-10T08:16:00Z","service":"order-api","env":"uat","log":"should fail"}' \
| curl -i \
-u logs-reader:change-reader-password \
-H 'content-type: application/stream+json' \
--data-binary @- \
'http://localhost:8427/insert/jsonline?_stream_fields=service,env&_time_field=date&_msg_field=log'Expected:
401 / 403 / no routeingest user cannot query#
curl -i \
-u logs-ingest:change-ingest-password \
-G 'http://localhost:8427/select/logsql/query' \
--data-urlencode 'query=service:order-api'Expected:
401 / 403 / no routeUI#
Open:
http://localhost:8427/select/vmui/Use:
username: logs-reader
password: change-reader-password7. ECS FireLens With Auth#
For ECS FireLens HTTP output, use Fluent Bit Basic Auth fields:
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "http",
"Host": "logs.example.com",
"Port": "443",
"URI": "/insert/jsonline?_stream_fields=service,env,cluster,task_definition,image_version&_msg_field=log&_time_field=date",
"Format": "json_lines",
"json_date_format": "iso8601",
"json_date_key": "date",
"tls": "On",
"tls.verify": "On",
"HTTP_User": "logs-ingest"
},
"secretOptions": [
{
"name": "HTTP_Passwd",
"valueFrom": "arn:aws:secretsmanager:ap-east-1:123456789012:secret:prod/victorialogs/logs-ingest-password-AbCdEf"
}
]
}Notes:
HTTP_User:
Fluent Bit HTTP output Basic Auth username
HTTP_Passwd:
Fluent Bit HTTP output Basic Auth password
put it in ECS secretOptions, not plain task definition options
logs-ingest:
must only route to /insert/.*8. Put TLS In Front#
vmauth can be exposed internally first:
http://vmauth.internal:8427For production, put a TLS layer in front:
ECS FireLens
-> https://logs.example.com
-> ALB / Nginx / Caddy / ingress
-> vmauth:8427
-> victorialogs:9428TLS layer should handle:
certificate
HTTPS listener
security group / firewall
optional WAF / IP allowlistKeep VictoriaLogs itself private:
do not expose :9428 to internet
do not bypass vmauth from client networks9. Rotate Passwords#
Steps:
1. add a new user/password in vmauth.yml
2. reload or restart vmauth
3. update clients to use the new password
4. verify ingest/query
5. remove old user/password
6. reload or restart vmauth againRestart:
docker compose restart vmauth
# or systemd:
sudo systemctl restart vmauthVerify after rotation:
curl -i \
-u logs-reader:new-reader-password \
-G 'http://localhost:8427/select/logsql/query' \
--data-urlencode 'query=service:order-api'10. Troubleshooting#
| Symptom | Check |
|---|---|
401 Unauthorized |
wrong username/password or missing Basic Auth |
404 / no route |
src_paths does not match request path |
| insert works, query fails | using logs-ingest for query |
| query works, insert fails | using logs-reader for insert |
| FireLens cannot write | check HTTP_User, HTTP_Passwd, endpoint URL, TLS, security group |
| direct VictoriaLogs access still works | :9428 is exposed; close it from client networks |
Useful commands:
docker compose logs --tail=100 vmauth
docker compose logs --tail=100 victorialogs
journalctl -u vmauth -n 200
systemctl status vmauth
systemctl cat vmauth
curl -i -u logs-reader:change-reader-password \
'http://localhost:8427/select/vmui/'11. Checklist#
1. VictoriaLogs :9428 is private
2. vmauth is the only client-facing endpoint
3. logs-ingest can only access /insert/.*
4. logs-reader can only access /select/.*
5. ECS FireLens uses logs-ingest
6. passwords are stored in Secrets Manager or secret store
7. TLS is enabled before production exposure
8. password rotation process is tested
9. ingest and query are verified separately