Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
executable file
·3323 lines (2943 loc) · 198 KB
/
Copy pathMakefile
File metadata and controls
executable file
·3323 lines (2943 loc) · 198 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
.PHONY: help status
.PHONY: up halt destroy ssh
.PHONY: submodule-init
.PHONY: proto proto-unified proto-verify sniffer detector firewall all rebuild
.PHONY: sniffer-build sniffer-clean sniffer-package sniffer-install
.PHONY: detector-build detector-clean
.PHONY: firewall-build firewall-clean
.PHONY: run-sniffer run-detector run-firewall
.PHONY: logs-sniffer logs-detector logs-firewall logs-lab
.PHONY: run-lab-dev kill-lab status-lab
.PHONY: run-lab-dev-day23 kill-lab-day23 status-lab-day23
.PHONY: kill-all check-ports restart
.PHONY: clean clean-libs clean-components clean-all distclean test test-libs test-components test-all dev-setup schema-update parquet-convert test-parquet deploy-configs deploy-configs-prod test-alert-client
.PHONY: build-unified rebuild-unified quick-fix dev-setup-unified
.PHONY: check-libbpf verify-bpf-maps diagnose-bpf
.PHONY: test-replay-small test-replay-neris test-replay-big test-replay-neris-x86-ebpf test-replay-neris-x86-libpcap experiment-suricata-up experiment-suricata-down experiment-suricata-run experiment-suricata-results experiment-suricata-status
.PHONY: monitor-day13-tmux logs-dual-score logs-dual-score-live extract-dual-scores
.PHONY: test-integration-day13 test-integration-day13-tmux test-dual-score-quick
.PHONY: clean-day13-logs stats-dual-score
.PHONY: analyze-dual-scores test-analyze-workflow test-day13-full quick-analyze
.PHONY: rag-log-init rag-log-clean rag-log-status rag-log-analyze rag-log-tail rag-log-tail-live
.PHONY: test-rag-integration test-rag-quick rag-watch rag-validate test-rag-small test-rag-neris test-rag-big
.PHONY: quick-lab-test rag-consolidate detector-debug
.PHONY: etcd-client-build etcd-client-clean etcd-client-test
.PHONY: verify-etcd-linkage verify-encryption verify-pipeline-config verify-all
.PHONY: monitor-day23-tmux
.PHONY: test-day23-full test-day23-stress verify-rag-logs-day23
.PHONY: day23
.PHONY: rag-ingester rag-ingester-build rag-ingester-clean
.PHONY: tools-build tools-clean tools-synthetic-gen
.PHONY: crypto-transport-build crypto-transport-clean crypto-transport-test
.PHONY: plugin-loader-build plugin-loader-clean plugin-loader-test
.PHONY: plugin-hello-build plugin-hello-clean validate-prod-configs
.PHONY: correlation-engine-smoke correlation-engine-smoke-matrix
# DEBT-HELLO-001 (PHASE 3, DAY 115)
# Falla si algún JSON de producción referencia libplugin_hello.
# Ejecutar antes de pipeline-start en CI/CD (TEST-PROVISION-1).
validate-prod-configs:
@echo "🔍 Validando que libplugin_hello NO está en configs de producción..."
@if vagrant ssh -c "grep -rl --include='*.json' 'libplugin_hello' \
/vagrant/sniffer/config/ \
/vagrant/firewall-acl-agent/config/ \
/vagrant/ml-detector/config/ \
/vagrant/rag/config/ \
/vagrant/rag-ingester/config/ \
/vagrant/etcd-server/config/ 2>/dev/null" 2>/dev/null | grep -v '.backup'; then \
echo ""; \
echo "❌ DEBT-HELLO-001: libplugin_hello encontrado en configs de producción"; \
echo " Ejecuta: python3 tools/debt_hello_001.py para limpiar"; \
exit 1; \
fi
@echo "✅ validate-prod-configs: libplugin_hello ausente en todos los configs"
.PHONY: etcd-server etcd-server-build etcd-server-clean etcd-server-start etcd-server-stop
.PHONY: rag-build rag-clean rag-start rag-stop rag-status rag-logs rag-attach
.PHONY: etcd-server-status pipeline-start pipeline-stop pipeline-status
.PHONY: test-hardening test-hardening-build test-hardening-run
.PHONY: day38-step1 day38-step2 day38-step3 day38-step4 day38-step5
.PHONY: day38-full day38-status day38-clean day38-pipeline
.PHONY: tsan-all tsan-quick tsan-clean tsan-summary tsan-status
.PHONY: etcd-server-status pipeline-start pipeline-stop pipeline-status
.PHONY: ml-detector-start firewall-start sniffer-start sniffer-libpcap-start rag-ingester-start
.PHONY: etcd-server-start rag-start rag-stop dev-setup-tools pipeline-health
.PHONY: provision provision-status provision-check provision-reprovision test-provision-1 test-invariant-seed
.PHONY: seed-client-build seed-client-test seed-client-clean seed-client-rebuild
# ============================================================================
# ML Defender Pipeline - Master Makefile
# Single Source of Truth for Build Configurations
# ============================================================================
# Run from macOS - Commands execute in VM via vagrant ssh -c
# Day 57+ - Refactored for coherent clean/test/verify workflow
# ============================================================================
# ============================================================================
# BUILD PROFILES - SINGLE SOURCE OF TRUTH
# ============================================================================
# All compiler flags are defined HERE and ONLY here.
# CMakeLists.txt files MUST NOT hardcode any -O, -g, or -fsanitize flags.
# ============================================================================
# Base flags (always applied)
CXX_STD := -std=c++20
CXX_WARNINGS := -Wall -Wextra -Wpedantic -Werror
C_STD := -std=c11
# Profile-specific flags
PROFILE_PRODUCTION_CXX := -O3 -march=native -DNDEBUG -flto -fno-omit-frame-pointer
PROFILE_PRODUCTION_C := -O3 -march=native -DNDEBUG -flto -fno-omit-frame-pointer
PROFILE_DEBUG_CXX := -g -O0 -fno-omit-frame-pointer -DDEBUG
PROFILE_DEBUG_C := -g -O0 -fno-omit-frame-pointer -DDEBUG
PROFILE_TSAN_CXX := -fsanitize=thread -g -O1 -fno-omit-frame-pointer -DTSAN_ENABLED
PROFILE_TSAN_C := -fsanitize=thread -g -O1 -fno-omit-frame-pointer -DTSAN_ENABLED
PROFILE_TSAN_LD := -fsanitize=thread
PROFILE_ASAN_CXX := -fsanitize=address -fsanitize=undefined -g -O1 -fno-omit-frame-pointer -DASAN_ENABLED
PROFILE_ASAN_C := -fsanitize=address -fsanitize=undefined -g -O1 -fno-omit-frame-pointer -DASAN_ENABLED
PROFILE_ASAN_LD := -fsanitize=address -fsanitize=undefined
# Combined flags per profile
CMAKE_FLAGS_PRODUCTION := -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="$(CXX_STD) $(CXX_WARNINGS) $(PROFILE_PRODUCTION_CXX)" \
-DCMAKE_C_FLAGS="$(C_STD) $(PROFILE_PRODUCTION_C)"
CMAKE_FLAGS_DEBUG := -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="$(CXX_STD) $(CXX_WARNINGS) $(PROFILE_DEBUG_CXX)" \
-DCMAKE_C_FLAGS="$(C_STD) $(PROFILE_DEBUG_C)"
CMAKE_FLAGS_TSAN := -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_CXX_FLAGS="$(CXX_STD) $(CXX_WARNINGS) $(PROFILE_TSAN_CXX)" \
-DCMAKE_C_FLAGS="$(C_STD) $(PROFILE_TSAN_C)" \
-DCMAKE_EXE_LINKER_FLAGS="$(PROFILE_TSAN_LD)" \
-DCMAKE_SHARED_LINKER_FLAGS="$(PROFILE_TSAN_LD)"
CMAKE_FLAGS_ASAN := -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_CXX_FLAGS="$(CXX_STD) $(CXX_WARNINGS) $(PROFILE_ASAN_CXX)" \
-DCMAKE_C_FLAGS="$(C_STD) $(PROFILE_ASAN_C)" \
-DCMAKE_EXE_LINKER_FLAGS="$(PROFILE_ASAN_LD)" \
-DCMAKE_SHARED_LINKER_FLAGS="$(PROFILE_ASAN_LD)"
# Default profile (can be overridden: make PROFILE=tsan all)
PROFILE ?= debug
CMAKE_FLAGS := $(CMAKE_FLAGS_$(shell echo $(PROFILE) | tr a-z A-Z))
VERBOSE ?=
FORCE_ALL_HEADS ?=
# ============================================================================
# COMPONENT BUILD DIRECTORIES (Profile-specific)
# ============================================================================
SNIFFER_BUILD_DIR := /vagrant/sniffer/build-$(PROFILE)
ML_DETECTOR_BUILD_DIR := /vagrant/ml-detector/build-$(PROFILE)
RAG_INGESTER_BUILD_DIR := /vagrant/rag-ingester/build-$(PROFILE)
FIREWALL_BUILD_DIR := /vagrant/firewall-acl-agent/build-$(PROFILE)
ETCD_SERVER_BUILD_DIR := /vagrant/etcd-server/build-$(PROFILE)
TOOLS_BUILD_DIR := /vagrant/tools/build-$(PROFILE)
# Libraries (always release, no sanitizers)
CRYPTO_TRANSPORT_BUILD_DIR := /vagrant/crypto-transport/build
ETCD_CLIENT_BUILD_DIR := /vagrant/etcd-client/build
PLUGIN_LOADER_BUILD_DIR := /vagrant/plugin-loader/build
# Legacy compatibility (for existing scripts that reference /vagrant/component/build)
SNIFFER_LEGACY_LINK := /vagrant/sniffer/build
ML_DETECTOR_LEGACY_LINK := /vagrant/ml-detector/build
RAG_INGESTER_LEGACY_LINK := /vagrant/rag-ingester/build
FIREWALL_LEGACY_LINK := /vagrant/firewall-acl-agent/build
ETCD_SERVER_LEGACY_LINK := /vagrant/etcd-server/build
TOOLS_LEGACY_LINK := /vagrant/tools/build
RAG_BUILD_DIR := /vagrant/rag/build
RAG_INGESTER_BIN_DIR := /vagrant/rag-ingester/build
# ============================================================================
# HELP
# ============================================================================
help:
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ ML Defender Pipeline - Master Makefile (Day 57+) ║"
@echo "║ Single Source of Truth - Build Profile System ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "📋 Build Profiles (PROFILE=name):"
@echo " debug - Debug symbols (-g -O0) [DEFAULT] — desarrollo diario"
@echo " production - Optimized (-O3, LTO, march=native) — ODR check + benchmarks FEDER"
@echo " tsan - ThreadSanitizer (-fsanitize=thread) — race conditions"
@echo " asan - AddressSanitizer (-fsanitize=address,undefined) — memory errors + UB"
@echo " NOTE: PROFILE=production activa -flto → ODR verification cross-module (P0 bloqueante)"
@echo ""
@echo "Usage: make [PROFILE=<profile>] <target>"
@echo " Example: make PROFILE=tsan all"
@echo " Example: make PROFILE=production sniffer"
@echo ""
@echo "🏗️ Build Commands (Dependencies handled automatically):"
@echo " make all - Build EVERYTHING (proto → libs → components)"
@echo " make proto - Regenerate protobuf"
@echo " make crypto-transport-build - Build crypto-transport library"
@echo " make etcd-client-build - Build etcd-client library"
@echo " make plugin-loader-build - Build plugin-loader library (ADR-012)"
@echo " make sniffer - Build sniffer (Variant A, eBPF/XDP)"
@echo " make sniffer-libpcap - Build sniffer (Variant B, libpcap)"
@echo " make ml-detector - Build ML detector"
@echo " make rag-ingester - Build RAG ingester"
@echo " make firewall - Build firewall agent"
@echo " make etcd-server - Build etcd server"
@echo " make tools - Build tools"
@echo ""
@echo "🧹 Clean Commands (NEW - Day 57):"
@echo " make clean - Clean components (current profile)"
@echo " make clean-libs - Clean libraries (crypto-transport, etcd-client)"
@echo " make clean-components - Same as 'clean'"
@echo " make clean-all - Clean EVERYTHING (legacy + profiles + libs)"
@echo " make distclean - Nuclear clean (clean-all + protobuf)"
@echo ""
@echo " Note: clean-all removes BOTH legacy build/ and build-PROFILE/"
@echo ""
@echo "🧪 Test Commands (NEW - Day 57):"
@echo " make test - Run ALL tests (libs + components)"
@echo " make test-libs - Run library tests only"
@echo " make test-components - Run component tests only"
@echo ""
@echo "✅ Verification Commands (NEW - Day 57):"
@echo " make verify-all - Run ALL verifications post-build"
@echo " make verify-etcd-linkage - Check etcd-client linkage"
@echo " make verify-encryption - Check encryption configs"
@echo ""
@echo "🔧 TSAN Validation (Day 48 Phase 0):"
@echo " make tsan-all - Full TSAN validation"
@echo " make tsan-quick - Quick TSAN check"
@echo " make tsan-summary - View TSAN report"
@echo ""
@echo "🚀 Run & Test:"
@echo " make run-lab-dev - Start full lab"
@echo " make status-lab - Check lab status"
@echo " make test-replay-small - Replay test dataset"
@echo ""
@echo "📊 Current Profile: $(PROFILE)"
@echo " Component builds: build-$(PROFILE)/"
@echo " Libraries: build/ (always release)"
@echo ""
@echo "VM Management:"
@echo " make up - Start VM"
@echo " make halt - Stop VM"
@echo " make ssh - SSH into VM"
@echo " make status - VM + libbpf status"
@echo ""
@echo "🏛️ Via Appia Quality: Piano piano - stone by stone"
# ============================================================================
# VM Management
# ============================================================================
.PHONY: bootstrap bootstrap-x86-ebpf bootstrap-x86-libpcap pipeline-start-x86-libpcap
# ============================================================================
# DEBT-BOOTSTRAP-001 + DEBT-INFRA-VERIFY-001/002 — DAY 120
# ============================================================================
.PHONY: check-system-deps check-build-artifacts post-up-verify
bootstrap: bootstrap-x86-ebpf
bootstrap-x86-ebpf:
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🚀 aRGus NDR — Bootstrap x86 Variant A (eBPF/XDP) ║"
@echo "║ Ejecutar tras: git clone && make up ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo "[1/8] Verificando entorno post-up..."
@$(MAKE) post-up-verify
@echo "[2/8] Verificando dependencias del sistema..."
@$(MAKE) check-system-deps
@echo "[3/8] Activando perfil de build..."
@$(MAKE) set-build-profile
@echo "[4/8] Instalando systemd units..."
@$(MAKE) install-systemd-units
@echo "[5/8] Compilando pipeline (incluye pubkey runtime + plugin-test-message)..."
@$(MAKE) pipeline-build
@$(MAKE) check-build-artifacts
@echo "[6/8] Desplegando modelos ML..."
@$(MAKE) deploy-models
@echo "[6b/8] Firmando plugins..."
@$(MAKE) sign-plugins
@echo "[7/8] Verificando provisioning..."
@$(MAKE) test-provision-1
@echo "[8/8] Arrancando pipeline (Variant A — eBPF/XDP)..."
@$(MAKE) pipeline-start
@$(MAKE) pipeline-status
@$(MAKE) plugin-integ-test
@vagrant ssh defender -c "tmux has-session -t sniffer 2>/dev/null" || (echo "\n❌ Bootstrap FAILED — sniffer STOPPED (DEBT-BOOTSTRAP-SNIFFER-VERIFY-001)" && exit 1)
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ ✅ Bootstrap x86 eBPF completado — 6/6 RUNNING ║"
@echo "║ Sniffer activo: Variant A (eBPF/XDP) ║"
@echo "║ Siguiente: make test-all ║"
@echo "╚════════════════════════════════════════════════════════════╝"
bootstrap-x86-libpcap:
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🚀 aRGus NDR — Bootstrap x86 Variant B (libpcap) ║"
@echo "║ Ejecutar tras: git clone && make up ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo "[1/8] Verificando entorno post-up..."
@$(MAKE) post-up-verify
@echo "[2/8] Verificando dependencias del sistema..."
@$(MAKE) check-system-deps
@echo "[3/8] Activando perfil de build..."
@$(MAKE) set-build-profile
@echo "[4/8] Instalando systemd units..."
@$(MAKE) install-systemd-units
@echo "[5/8] Compilando pipeline (incluye Variant B sniffer-libpcap)..."
@$(MAKE) pipeline-build
@$(MAKE) sniffer-libpcap
@$(MAKE) check-build-artifacts
@echo "[6/8] Desplegando modelos ML..."
@$(MAKE) deploy-models
@echo "[6b/8] Firmando plugins..."
@$(MAKE) sign-plugins
@echo "[7/8] Verificando provisioning..."
@$(MAKE) test-provision-1
@echo "[8/8] Arrancando pipeline (Variant B — libpcap)..."
@$(MAKE) pipeline-start-x86-libpcap
@$(MAKE) pipeline-status
@$(MAKE) plugin-integ-test
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ ✅ Bootstrap x86 libpcap completado — 6/6 RUNNING ║"
@echo "║ Sniffer activo: Variant B (libpcap) ║"
@echo "║ Siguiente: make test-all ║"
@echo "╚════════════════════════════════════════════════════════════╝"
check-system-deps:
@echo "🔍 Verificando dependencias del sistema..."
@vagrant ssh -c "command -v xxd >/dev/null || { echo '❌ xxd missing'; exit 1; }"
@vagrant ssh -c "command -v tmux >/dev/null || { echo '❌ tmux missing'; exit 1; }"
@vagrant ssh -c "pkg-config --modversion libsodium 2>/dev/null | grep -q '1.0.19' || { echo '❌ libsodium 1.0.19 missing'; exit 1; }"
@vagrant ssh -c "bash /vagrant/tools/check-xgboost-version.sh" || { echo '❌ xgboost 3.2.0 missing'; exit 1; }
@vagrant ssh -c "test -f /usr/local/lib/libxgboost.so || { echo '❌ libxgboost.so missing'; exit 1; }"
@vagrant ssh -c "test -f /usr/local/lib/libcrypto_transport.so || { echo '❌ libcrypto_transport.so missing'; exit 1; }"
@vagrant ssh -c "test -f /usr/sbin/nft || { echo '❌ nftables missing'; exit 1; }"
@echo "✅ Todas las dependencias del sistema presentes"
check-build-artifacts:
@echo "🔍 Verificando artefactos de build..."
@vagrant ssh -c "test -f /usr/local/bin/argus-network-isolate || { echo '❌ argus-network-isolate missing'; exit 1; }"
@echo "✅ Artefactos de build presentes"
post-up-verify:
@echo "🔍 Verificando entorno post-up..."
@$(MAKE) check-system-deps
@vagrant ssh -c "test -d /usr/lib/ml-defender/plugins || { echo '❌ plugins dir missing'; exit 1; }"
@vagrant ssh -c "test -f /usr/lib/ml-defender/plugins/libplugin_xgboost.so || { echo '❌ libplugin_xgboost.so missing'; exit 1; }"
@vagrant ssh -c "test -f /etc/ml-defender/plugins/plugin_signing.pk || { echo '❌ plugin_signing.pk missing'; exit 1; }"
@vagrant ssh -c "sudo find /etc/ml-defender -name 'seed.bin' | wc -l | tr -d ' ' | grep -q '^6$$' || { echo '❌ seeds missing (esperados 6)'; exit 1; }"
@echo "✅ Entorno post-up verificado"
# [LAB-CLOCK-STEP-D296] Alinea los relojes del lab tras suspender el Mac: makestep en defender y DESPUES en client
# (el client toma la hora del defender). Verifica DENTRO de cada VM con chronyc waitsync: desfase menor que
# LAB_CLOCK_MAX_OFFSET_S en LAB_CLOCK_WAIT_TRIES intentos de 1 s, o falla con el nombre de la VM.
# Un solo vagrant ssh por VM (~14 s cada uno); comparar relojes con date por vagrant ssh no sirve.
LAB_CLOCK_MAX_OFFSET_S ?= 0.001
LAB_CLOCK_WAIT_TRIES ?= 30
.PHONY: lab-clock-step
lab-clock-step:
@echo "[LAB-CLOCK-STEP] defender: makestep + waitsync"
@vagrant ssh defender -c 'sudo chronyc makestep >/dev/null; chronyc waitsync $(LAB_CLOCK_WAIT_TRIES) $(LAB_CLOCK_MAX_OFFSET_S) 0 1 >/dev/null; rc=$$?; chronyc -n tracking | grep -E "Reference ID|System time"; if [ $$rc -ne 0 ]; then echo "[LAB-CLOCK-STEP] FALLO defender: desfase >= $(LAB_CLOCK_MAX_OFFSET_S) s tras $(LAB_CLOCK_WAIT_TRIES) s"; exit 1; fi; echo "[LAB-CLOCK-STEP] defender OK (< $(LAB_CLOCK_MAX_OFFSET_S) s)"'
@echo "[LAB-CLOCK-STEP] client: makestep + waitsync (fuente 192.168.100.1)"
@vagrant ssh client -c 'sudo chronyc makestep >/dev/null; chronyc waitsync $(LAB_CLOCK_WAIT_TRIES) $(LAB_CLOCK_MAX_OFFSET_S) 0 1 >/dev/null; rc=$$?; chronyc -n tracking | grep -E "Reference ID|System time"; if ! chronyc -n tracking | grep -qF "(192.168.100.1)"; then echo "[LAB-CLOCK-STEP] FALLO client: su fuente no es el defender 192.168.100.1"; exit 1; fi; if [ $$rc -ne 0 ]; then echo "[LAB-CLOCK-STEP] FALLO client: desfase >= $(LAB_CLOCK_MAX_OFFSET_S) s tras $(LAB_CLOCK_WAIT_TRIES) s"; exit 1; fi; echo "[LAB-CLOCK-STEP] client OK (< $(LAB_CLOCK_MAX_OFFSET_S) s)"'
@echo "[LAB-CLOCK-STEP] OK: defender y client alineados"
up-argus:
@vagrant up defender client
up-suricata:
@cd experiments/suricata-comparative && vagrant up suricata client
up:
@vagrant up defender client suricata zeek wazuh
halt-argus:
@vagrant halt defender client
halt-suricata:
@cd experiments/suricata-comparative && vagrant halt
halt:
@vagrant halt defender client suricata zeek wazuh
destroy:
@vagrant destroy -f
ssh:
@vagrant ssh
status:
@echo "════════════════════════════════════════════════════════════"
@echo "VM Status:"
@vagrant status
@echo ""
@echo "════════════════════════════════════════════════════════════"
@echo "libbpf Status (Day 8 Fix):"
@vagrant ssh -c "pkg-config --modversion libbpf 2>/dev/null || echo '❌ libbpf not found'" | \
awk '{if ($$1 >= "1.2.0") print "✅ libbpf " $$1 " (BPF map bug FIXED)"; else print "⚠️ libbpf " $$1 " (needs upgrade to 1.2.0+)"}'
@echo "════════════════════════════════════════════════════════════"
@echo "Current Profile: $(PROFILE)"
@echo "════════════════════════════════════════════════════════════"
# ============================================================================
# Protobuf (Foundation Layer)
# ============================================================================
PROTOBUF_VERIFY_SCRIPT := /vagrant/scripts/verify_protobuf.sh
proto-unified:
@echo "🔨 Protobuf Unified System..."
@vagrant ssh -c "cd /vagrant/protobuf && chmod +x generate.sh && ./generate.sh"
proto-verify:
@echo "🔍 Verificando consistencia protobuf..."
@vagrant ssh -c "cd /vagrant && bash scripts/verify_protobuf.sh"
proto: proto-unified
@echo "✅ Protobuf unificado generado y distribuido"
# ============================================================================
# Libraries Layer (No Sanitizers - Always Release)
# ============================================================================
# Dependencies: crypto-transport has no deps
# etcd-client depends on: proto, crypto-transport
# ============================================================================
crypto-transport-build: seed-client-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building crypto-transport Library ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@vagrant ssh -c 'cd /vagrant/crypto-transport && \
rm -rf build && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4'
@echo "Installing system-wide..."
@vagrant ssh -c "cd /vagrant/crypto-transport/build && sudo make install && sudo ldconfig"
@echo ""
@echo "✅ crypto-transport installed to /usr/local/lib"
@vagrant ssh -c "ls -lh /usr/local/lib/libcrypto_transport.so* 2>/dev/null || echo '⚠️ Library not found in /usr/local/lib'"
crypto-transport-clean:
@echo "🧹 Cleaning crypto-transport..."
@vagrant ssh -c "rm -rf /vagrant/crypto-transport/build"
@vagrant ssh -c "sudo rm -f /usr/local/lib/libcrypto_transport.so*"
@vagrant ssh -c "sudo rm -rf /usr/local/include/crypto_transport"
@vagrant ssh -c "sudo ldconfig"
@echo "✅ crypto-transport cleaned"
crypto-transport-test:
@echo "🧪 Testing crypto-transport..."
@vagrant ssh -c "cd /vagrant/crypto-transport/build && ctest --output-on-failure"
# ADR-025: sincroniza MLD_PLUGIN_PUBKEY_HEX en CMakeLists.txt con el keypair activo en VM
# Ejecutar SIEMPRE tras vagrant destroy+up o provision.sh --reset
# Sin esto: TEST-INTEG-SIGN falla porque la pubkey compilada != keypair activo
sync-pubkey:
@echo "⚠️ DEPRECATED: sync-pubkey ya no es necesario (DEBT-PUBKEY-RUNTIME-001 CERRADO)"
@echo " plugin-loader lee la pubkey desde /etc/ml-defender/plugins/plugin_signing.pk en cmake-time"
@echo " Ejecuta directamente: make plugin-loader-build"
@$(MAKE) plugin-loader-build
plugin-loader-build:
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔌 Building plugin-loader Library (PHASE 1) ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo " Phase: 1 — no crypto, no seed-client (ADR-012)"
@echo " Auth: PHASE 2 (ADR-013, seed-client DAY 95-96)"
@echo ""
@vagrant ssh -c 'cd /vagrant/plugin-loader && \
rm -rf build && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4'
@echo "Installing system-wide..."
@vagrant ssh -c "cd /vagrant/plugin-loader/build && sudo make install && sudo ldconfig"
@echo ""
@echo "✅ plugin-loader installed to /usr/local/lib"
@vagrant ssh -c "ls -lh /usr/local/lib/libplugin_loader.so* 2>/dev/null || echo '⚠️ Library not found in /usr/local/lib'"
plugin-loader-clean:
@echo "🧹 Cleaning plugin-loader..."
@vagrant ssh -c "rm -rf /vagrant/plugin-loader/build"
@vagrant ssh -c "sudo rm -f /usr/local/lib/libplugin_loader.so*"
@vagrant ssh -c "sudo rm -rf /usr/local/include/plugin_loader"
@vagrant ssh -c "sudo ldconfig"
@echo "✅ plugin-loader cleaned"
plugin-loader-test:
@echo "Testing safe-path property tests..."
@vagrant ssh -c "/vagrant/contrib/safe-path/build/test_safe_path_property" || (echo "❌ safe-path property tests FAILED" && exit 1)
@echo ""
@echo "🧪 Testing plugin-loader..."
@vagrant ssh -c "cd /vagrant/plugin-loader/build && ctest --output-on-failure"
# ADR-025: firma todos los plugins instalados en /usr/lib/ml-defender/plugins/
# Prerequisito: provision.sh full (keypair generado)
# Repetible: re-firmar sobreescribe .sig anterior
# ADR-025: TEST-INTEG-SIGN-1 a 7 — verificacion Ed25519 plugin loader
test-sign:
@echo "TEST-INTEG-SIGN: Ed25519 plugin verification (ADR-025)..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_integ_sign /vagrant/plugins/test-message/test_integ_sign.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && sudo ./test_integ_sign && echo TEST-INTEG-SIGN PASSED || echo TEST-INTEG-SIGN FAILED'
deploy-models:
@vagrant ssh -c "sudo mkdir -p /etc/ml-defender/models && \
sudo cp /vagrant/ml-detector/models/production/level1/xgboost_cicids2017.ubj \
/etc/ml-defender/models/xgboost_cicids2017.ubj && \
sudo chmod 644 /etc/ml-defender/models/xgboost_cicids2017.ubj"
@echo "✅ Modelos ML desplegados en /etc/ml-defender/models/"
sign-plugins:
@echo "Firmando plugins (ADR-025 D1)..."
@vagrant ssh -c 'sudo bash /vagrant/tools/provision.sh sign'
test-integ-xgboost-1:
@echo "TEST-INTEG-XGBOOST-1: XGBoost plugin inference (ADR-026 OBS-2)..."
@vagrant ssh -c "cd /tmp && g++ -std=c++20 -o test_integ_xgboost_1 /vagrant/plugins/test-message/test_integ_xgboost_1.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && sudo ./test_integ_xgboost_1 && echo TEST-INTEG-XGBOOST-1 PASSED || echo TEST-INTEG-XGBOOST-1 FAILED"
sign-models:
@echo "══ Firma de modelos (ADR-026 OBS-1) ══"
@vagrant ssh -c "sudo bash /vagrant/tools/sign-model.sh /vagrant/ml-detector/models/production/level1/xgboost_cicids2017.ubj"
@vagrant ssh -c "sudo bash /vagrant/tools/sign-model.sh /vagrant/ml-detector/models/production/level2/ddos/xgboost_ddos.ubj"
@vagrant ssh -c "sudo bash /vagrant/tools/sign-model.sh /vagrant/ml-detector/models/production/level3/ransomware_xgboost_v2/xgboost_ransomware.ubj"
@vagrant ssh -c "sudo bash /vagrant/tools/sign-model.sh /vagrant/ml-detector/models/production/level1/xgboost_cicids2017_v2.ubj"
@echo " ✅ 4 modelo(s) firmado(s) correctamente"
plugin-integ-test:
@echo "TEST-INTEG-4a-PLUGIN: variantes A/B/C..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_variants /vagrant/plugins/test-message/test_variants.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && MLD_ALLOW_DEV_MODE=1 ./test_variants && echo TEST-INTEG-4a PASSED || echo TEST-INTEG-4a FAILED'
@echo "TEST-INTEG-4b: plugin READ-ONLY contract (rag-ingester PHASE 2b)..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_integ_4b /vagrant/plugins/test-message/test_integ_4b.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && MLD_ALLOW_DEV_MODE=1 ./test_integ_4b && echo TEST-INTEG-4b PASSED || echo TEST-INTEG-4b FAILED'
@echo "TEST-INTEG-4c: plugin NORMAL contract (sniffer PHASE 2c)..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_integ_4c /vagrant/plugins/test-message/test_integ_4c.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && MLD_ALLOW_DEV_MODE=1 ./test_integ_4c && echo TEST-INTEG-4c PASSED || echo TEST-INTEG-4c FAILED'
@echo "TEST-INTEG-4d: plugin NORMAL contract (ml-detector PHASE 2d)..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_integ_4d /vagrant/plugins/test-message/test_integ_4d.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && MLD_ALLOW_DEV_MODE=1 ./test_integ_4d && echo TEST-INTEG-4d PASSED || echo TEST-INTEG-4d FAILED'
@echo "TEST-INTEG-4e: rag-security READONLY + ADR-029 D1-D5..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_integ_4e /vagrant/plugins/test-message/test_integ_4e.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && MLD_ALLOW_DEV_MODE=1 ./test_integ_4e && echo TEST-INTEG-4e PASSED || echo TEST-INTEG-4e FAILED'
@echo "TEST-INTEG-SIGN: Ed25519 plugin verification (ADR-025)..."
@vagrant ssh -c 'cd /tmp && g++ -std=c++20 -o test_integ_sign /vagrant/plugins/test-message/test_integ_sign.cpp -I/usr/local/include -L/usr/local/lib -lplugin_loader -Wl,-rpath,/usr/local/lib && sudo ./test_integ_sign && echo TEST-INTEG-SIGN PASSED || echo TEST-INTEG-SIGN FAILED'
plugin-hello-build: plugin-loader-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔌 Building Hello World Plugin (ADR-012 validation) ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@vagrant ssh -c 'cd /vagrant/plugins/hello && \
rm -rf build && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4'
@echo "Deploying to plugin directory..."
@vagrant ssh -c "sudo mkdir -p /usr/lib/ml-defender/plugins"
@vagrant ssh -c "sudo cp /vagrant/plugins/hello/build/libplugin_hello.so /usr/lib/ml-defender/plugins/"
@echo ""
@echo "✅ libplugin_hello.so deployed to /usr/lib/ml-defender/plugins/"
@vagrant ssh -c "ls -lh /usr/lib/ml-defender/plugins/"
plugin-test-message-build: plugin-loader-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔌 Building Test Message Plugin (ADR-025 integration) ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@vagrant ssh -c 'cd /vagrant/plugins/test-message && rm -rf build && mkdir -p build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make -j4'
@vagrant ssh -c "sudo mkdir -p /usr/lib/ml-defender/plugins"
@vagrant ssh -c "sudo cp /vagrant/plugins/test-message/build/libplugin_test_message.so /usr/lib/ml-defender/plugins/"
@echo "✅ libplugin_test_message.so deployed to /usr/lib/ml-defender/plugins/"
plugin-hello-clean:
@echo "🧹 Cleaning hello plugin..."
@vagrant ssh -c "rm -rf /vagrant/plugins/hello/build"
@vagrant ssh -c "sudo rm -f /usr/lib/ml-defender/plugins/libplugin_hello.so"
@echo "✅ hello plugin cleaned"
etcd-client-build: proto-unified crypto-transport-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building etcd-client Library ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Dependencies:"
@echo " ✅ proto-unified"
@echo " ✅ crypto-transport-build"
@echo ""
@vagrant ssh -c 'cd /vagrant/etcd-client && \
rm -rf build && \
mkdir -p build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4'
@echo "Installing system-wide..."
@vagrant ssh -c "cd /vagrant/etcd-client/build && sudo make install && sudo ldconfig"
@echo ""
@echo "✅ etcd-client installed to /usr/local/lib"
@echo ""
@echo "Verifying library size and methods..."
@vagrant ssh -c "ls -lh /vagrant/etcd-client/build/libetcd_client.so"
@vagrant ssh -c "ls -lh /usr/local/lib/libetcd_client.so* 2>/dev/null || echo '⚠️ Library not found in /usr/local/lib'"
@vagrant ssh -c "nm -D /usr/local/lib/libetcd_client.so.1.0.0 2>/dev/null | grep -c ' T ' | xargs echo 'Public methods:'" || echo "⚠️ Cannot verify methods"
etcd-client-clean:
@echo "🧹 Cleaning etcd-client..."
@vagrant ssh -c "rm -rf /vagrant/etcd-client/build"
@vagrant ssh -c "sudo rm -f /usr/local/lib/libetcd_client.so*"
@vagrant ssh -c "sudo rm -rf /usr/local/include/etcd_client"
@vagrant ssh -c "sudo ldconfig"
@echo "✅ etcd-client cleaned"
etcd-client-test:
@echo "🧪 Testing etcd-client..."
@vagrant ssh -c "cd /vagrant/etcd-client/build && ctest --output-on-failure"
# ============================================================================
# Component Builds (Profile-Aware)
# ============================================================================
# CRITICAL: All components copy protobuf files BEFORE cmake
# Dependencies are explicit and automatic
# ============================================================================
# Ajusta estas rutas a tu estructura real
SNIFFER_DIR := /vagrant/sniffer
SNIFFER_BIN := ./$(notdir $(SNIFFER_BUILD_DIR))/sniffer
SNIFFER_CFG := ../config/sniffer.json
SNIFFER_LIBPCAP_BIN:= ./$(notdir $(SNIFFER_LIBPCAP_BUILD_DIR))/sniffer-libpcap
# ── Macro de exclusión mutua (inline, sin script externo) ────────────────────
define CHECK_SNIFFER_MUTEX
@vagrant ssh defender -c " \
EBPF=\$$(tmux has-session -t sniffer 2>/dev/null && echo 1 || echo 0); \
PCAP=\$$(tmux has-session -t sniffer-libpcap 2>/dev/null && echo 1 || echo 0); \
if [ \$$EBPF -eq 1 ] || [ \$$PCAP -eq 1 ]; then \
echo '❌ MUTEX VIOLATION: otro sniffer activo — para primero con pipeline-stop'; \
exit 1; \
fi"
endef
# DAY284 — ruta del log del sniffer; override p.ej. SNIFFER_LOG=/tmp/argus-lab/sniffer.log
SNIFFER_LOG ?= /vagrant/logs/lab/sniffer.log
# ── sniffer-start — Variant A (eBPF) ─────────────────────────────────────────
sniffer-start:
@echo "🚀 Starting Sniffer Variant A (eBPF/XDP) [$(PROFILE)]..."
$(CHECK_SNIFFER_MUTEX)
@vagrant ssh defender -c "tmux kill-session -t sniffer 2>/dev/null || true"
@vagrant ssh defender -c "tmux new-session -d -s sniffer \
'mkdir -p $(dir $(SNIFFER_LOG)) && \
cd $(SNIFFER_BUILD_DIR) && \
sudo env LD_LIBRARY_PATH=/usr/local/lib ./sniffer -c /vagrant/sniffer/config/sniffer.json \
>> $(SNIFFER_LOG) 2>&1'"
@sleep 4
# ── sniffer-libpcap-start — Variant B (libpcap) ──────────────────────────────
sniffer-libpcap-start:
@echo "🚀 Starting Sniffer Variant B (libpcap) [$(PROFILE)]..."
$(CHECK_SNIFFER_MUTEX)
@vagrant ssh defender -c "tmux kill-session -t sniffer-libpcap 2>/dev/null || true"
@vagrant ssh defender -c "tmux new-session -d -s sniffer-libpcap \
'mkdir -p /vagrant/logs/lab && \
cd $(SNIFFER_LIBPCAP_BUILD_DIR) && \
sudo env LD_LIBRARY_PATH=/usr/local/lib ./sniffer-libpcap \
-c /etc/ml-defender/sniffer/sniffer-libpcap.json \
>> /vagrant/logs/lab/sniffer-libpcap.log 2>&1'"
@sleep 4
sniffer: proto etcd-client-build plugin-loader-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building Sniffer [$(PROFILE)] ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Build dir: $(SNIFFER_BUILD_DIR)"
@echo "Flags: $(CMAKE_FLAGS)"
@echo ""
@echo "Copying protobuf files..."
@vagrant ssh -c 'mkdir -p $(SNIFFER_BUILD_DIR)/proto && \
cp /vagrant/protobuf/network_security.pb.* $(SNIFFER_BUILD_DIR)/proto/'
@echo "Running CMake and build..."
@vagrant ssh -c 'cd /vagrant/sniffer && \
mkdir -p $(SNIFFER_BUILD_DIR) && \
cd $(SNIFFER_BUILD_DIR) && \
cmake $(CMAKE_FLAGS) .. && \
make -j4'
@vagrant ssh -c "ln -sfn $(SNIFFER_BUILD_DIR) $(SNIFFER_LEGACY_LINK)"
@echo ""
@echo "✅ Sniffer built ($(PROFILE))"
# DAY284 — ruta del log del ml-detector; override p.ej. ML_DETECTOR_LOG=/tmp/argus-lab/ml-detector.log
ML_DETECTOR_LOG ?= /vagrant/logs/lab/ml-detector.log
ml-detector-start:
@vagrant ssh -c "tmux new-session -d -s ml-detector 'mkdir -p $(dir $(ML_DETECTOR_LOG)) && cd $(ML_DETECTOR_BUILD_DIR) && export LD_LIBRARY_PATH=/usr/local/lib:$$LD_LIBRARY_PATH && sudo env LD_LIBRARY_PATH=/usr/local/lib ./ml-detector $(if $(VERBOSE),--verbose,) $(if $(FORCE_ALL_HEADS),--force-all-heads,) >> $(ML_DETECTOR_LOG) 2>&1'"
ml-detector: proto etcd-client-build plugin-loader-build correlation-v1-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building ML Detector [$(PROFILE)] ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Build dir: $(ML_DETECTOR_BUILD_DIR)"
@echo "Flags: $(CMAKE_FLAGS)"
@echo ""
@echo "Copying protobuf files..."
@vagrant ssh -c 'mkdir -p $(ML_DETECTOR_BUILD_DIR)/proto && \
cp /vagrant/protobuf/network_security.pb.* $(ML_DETECTOR_BUILD_DIR)/proto/'
@echo "Running CMake and build..."
@vagrant ssh -c 'cd /vagrant/ml-detector && \
mkdir -p $(ML_DETECTOR_BUILD_DIR) && \
cd $(ML_DETECTOR_BUILD_DIR) && \
cmake $(CMAKE_FLAGS) .. && \
make -j4'
@vagrant ssh -c "ln -sfn $(ML_DETECTOR_BUILD_DIR) $(ML_DETECTOR_LEGACY_LINK)"
@echo ""
@echo "✅ ML Detector built ($(PROFILE))"
rag-ingester-start:
@echo "🚀 Starting RAG Ingester (Full Context)..."
@vagrant ssh -c "tmux kill-session -t rag-ingester 2>/dev/null || true"
@echo "🧹 Limpiando SQLite lock anterior (si existe)..."
@vagrant ssh -c "rm -f /vagrant/shared/indices/metadata.db-wal /vagrant/shared/indices/metadata.db-shm || true"
@echo "Ejecución desde la raíz del componente para resolver paths relativos del config..."
@vagrant ssh -c "tmux new-session -d -s rag-ingester 'mkdir -p /vagrant/logs/lab && cd /vagrant/rag-ingester && export LD_LIBRARY_PATH=/usr/local/lib:$$LD_LIBRARY_PATH && sudo env LD_LIBRARY_PATH=/usr/local/lib ./build-debug/rag-ingester /etc/ml-defender/rag-ingester/rag-ingester.json >> /vagrant/logs/lab/rag-ingester.log 2>&1'"
@sleep 2
rag-ingester: proto etcd-client-build crypto-transport-build plugin-loader-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building RAG Ingester [$(PROFILE)] ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Build dir: $(RAG_INGESTER_BUILD_DIR)"
@echo "Flags: $(CMAKE_FLAGS)"
@echo ""
@echo "Copying protobuf files..."
@vagrant ssh -c 'mkdir -p $(RAG_INGESTER_BUILD_DIR)/proto && \
cp /vagrant/protobuf/network_security.pb.* $(RAG_INGESTER_BUILD_DIR)/proto/'
@echo "Running CMake and build..."
@vagrant ssh -c 'cd /vagrant/rag-ingester && \
mkdir -p $(RAG_INGESTER_BUILD_DIR) && \
cd $(RAG_INGESTER_BUILD_DIR) && \
cmake $(CMAKE_FLAGS) .. && \
make -j4'
@vagrant ssh -c "ln -sfn $(RAG_INGESTER_BUILD_DIR) $(RAG_INGESTER_LEGACY_LINK)"
@echo ""
@echo "✅ RAG Ingester built ($(PROFILE))"
FIREWALL_DIR := /vagrant/firewall-acl-agent
FIREWALL_BIN := ./firewall-acl-agent
FIREWALL_CFG := /etc/ml-defender/firewall-acl-agent/firewall.json
firewall-start:
@vagrant ssh -c "tmux new-session -d -s firewall 'mkdir -p /vagrant/logs/lab && cd $(FIREWALL_BUILD_DIR) && sudo env LD_LIBRARY_PATH=/usr/local/lib $(FIREWALL_BIN) -c $(FIREWALL_CFG) >> /vagrant/logs/lab/firewall-agent.log 2>&1'"
firewall: proto seed-client-build etcd-client-build plugin-loader-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building Firewall ACL Agent [$(PROFILE)] ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Build dir: $(FIREWALL_BUILD_DIR)"
@echo "Flags: $(CMAKE_FLAGS)"
@echo ""
@echo "Copying protobuf files..."
@vagrant ssh -c 'mkdir -p $(FIREWALL_BUILD_DIR)/proto && \
cp /vagrant/protobuf/network_security.pb.* $(FIREWALL_BUILD_DIR)/proto/'
@echo "Running CMake and build..."
@vagrant ssh -c 'cd /vagrant/firewall-acl-agent && \
mkdir -p $(FIREWALL_BUILD_DIR) && \
cd $(FIREWALL_BUILD_DIR) && \
cmake $(CMAKE_FLAGS) .. && \
make -j4'
@vagrant ssh -c "ln -sfn $(FIREWALL_BUILD_DIR) $(FIREWALL_LEGACY_LINK)"
@echo ""
@echo "✅ Firewall built ($(PROFILE))"
etcd-server:
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building etcd-server [$(PROFILE)] ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Build dir: $(ETCD_SERVER_BUILD_DIR)"
@echo "Flags: $(CMAKE_FLAGS)"
@echo ""
@vagrant ssh -c 'cd /vagrant/etcd-server && \
mkdir -p $(ETCD_SERVER_BUILD_DIR) && \
cd $(ETCD_SERVER_BUILD_DIR) && \
cmake $(CMAKE_FLAGS) .. && \
make -j4'
@vagrant ssh -c "ln -sfn $(ETCD_SERVER_BUILD_DIR) $(ETCD_SERVER_LEGACY_LINK)"
@echo ""
@echo "✅ etcd-server built ($(PROFILE))"
etcd-server-status:
@echo "════════════════════════════════════════════════════════════"
@echo "etcd-server Status:"
@vagrant ssh -c "pgrep -a -f etcd-server && echo '✅ etcd-server: RUNNING' || echo '❌ etcd-server: STOPPED'"
@vagrant ssh -c "curl -s http://localhost:2379/health || echo '⚠️ Not responding'"
@echo "════════════════════════════════════════════════════════════"
# ============================================================================
# Logging estándar — todos los componentes escriben en /vagrant/logs/lab/
# Standard: un componente, un fichero, nombre predecible.
# ADR pendiente: mover configuración log_file a JSON de cada componente.
# ============================================================================
logs-all:
@echo '📋 Tailing all 6 pipeline component logs (Ctrl+C to stop)...'
@vagrant ssh -c "tail -f /vagrant/logs/lab/etcd-server.log /vagrant/logs/lab/rag-security.log /vagrant/logs/lab/rag-ingester.log /vagrant/logs/lab/ml-detector.log /vagrant/logs/lab/firewall-agent.log /vagrant/logs/lab/sniffer.log 2>/dev/null"
logs-lab-clean:
@echo '🧹 Rotating pipeline logs...'
@vagrant ssh -c "mkdir -p /vagrant/logs/lab/archive && mv /vagrant/logs/lab/*.log /vagrant/logs/lab/archive/ 2>/dev/null || true"
@echo '✅ Logs rotated to /vagrant/logs/lab/archive/'
pipeline-health:
@bash scripts/pipeline_health.sh
# =============================================================================
# TEST-PROVISION-1 — CI Gate PHASE 3 (DAY 115)
# Verifica que el entorno está listo para arrancar el pipeline de forma segura.
# Encadena todos los checks de PHASE 3 ítems 1-4.
#
# USO:
# make test-provision-1 # CI gate completo
# make pipeline-start # llama a test-provision-1 automáticamente
#
# CHECKS:
# 1. Claves criptográficas (provision.sh verify)
# 2. Plugins firmados (provision.sh check-plugins --production)
# 3. No dev plugins en prod configs (validate-prod-configs)
# 4. build-active symlinks presentes (set-build-profile.sh ejecutado)
# 5. systemd units instalados en /etc/systemd/system/
# =============================================================================
test-provision-1:
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔍 TEST-PROVISION-1 — CI Gate PHASE 3 ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "── Check 1/8: Claves criptográficas ──"
@vagrant ssh -c "sudo bash /vagrant/tools/provision.sh verify" || \
(echo "❌ CHECK 1 FAILED: claves ausentes o inválidas" && \
echo " Ejecuta: make provision" && exit 1)
@echo "✅ Check 1/8 OK"
@echo ""
@echo "── Check 2/8: Firmas de plugins (producción) ──"
@vagrant ssh -c "sudo bash /vagrant/tools/provision.sh check-plugins --production" || \
(echo "❌ CHECK 2 FAILED: plugins sin firma válida" && \
echo " Ejecuta: make sign-plugins" && exit 1)
@echo "✅ Check 2/8 OK"
@echo ""
@echo "── Check 3/8: Configs de producción (sin dev plugins) ──"
@$(MAKE) validate-prod-configs || \
(echo "❌ CHECK 3 FAILED: dev plugins en configs de producción" && exit 1)
@echo "✅ Check 3/8 OK"
@echo ""
@echo "── Check 4/8: build-active symlinks ──"
@vagrant ssh -c "test -L /vagrant/sniffer/build-active && \
test -L /vagrant/ml-detector/build-active && \
test -L /vagrant/firewall-acl-agent/build-active && \
test -L /vagrant/etcd-server/build-active && \
test -L /vagrant/rag-ingester/build-active" || \
(echo "❌ CHECK 4 FAILED: build-active symlinks ausentes" && \
echo " Ejecuta: vagrant ssh -c 'sudo bash /vagrant/etcd-server/config/set-build-profile.sh debug'" && \
exit 1)
@echo "✅ Check 4/8 OK"
@echo ""
@echo "── Check 5/8: systemd units instalados ──"
@vagrant ssh -c "systemctl list-unit-files ml-defender-*.service 2>/dev/null | grep -c 'ml-defender'" | \
grep -q "6" || \
(echo "❌ CHECK 5 FAILED: systemd units no instalados (esperado: 6)" && \
echo " Ejecuta: vagrant ssh -c 'sudo bash /vagrant/etcd-server/config/install-systemd-units.sh'" && \
exit 1)
@echo "✅ Check 5/8 OK"
@echo ""
@echo ""
@echo "── Check 6/8: Permisos ficheros sensibles ──"
@vagrant ssh -c "sudo find /etc/ml-defender -type f \( -name '*.sk' \) -perm /022 2>/dev/null | grep -q . && echo FAIL || true" | grep -q FAIL && \
(echo "❌ CHECK 6 FAILED: .sk con permisos world/group-writable" && exit 1) || true
@vagrant ssh -c "sudo find /etc/ml-defender -name 'seed.bin' ! -perm 400 ! -perm 440 2>/dev/null | grep -q . && echo FAIL || true" | grep -q FAIL && \
(echo "❌ CHECK 6 FAILED: seed.bin con permisos incorrectos (esperado: 0400 o 0440)" && exit 1) || true
@echo "✅ Check 6/8 OK"
@echo ""
@echo "── Check 7/8: Consistencia JSONs con plugins reales ──"
@vagrant ssh -c "python3 /vagrant/tools/check-json-plugins.py" || \
(echo "❌ CHECK 7 FAILED: plugins referenciados en JSONs sin .so o .sig" && exit 1)
@echo "✅ Check 7/8 OK"
@echo ""
@echo "── Check 8/8: apparmor-utils instalado ──"
@vagrant ssh -c "/usr/sbin/aa-complain --help > /dev/null 2>&1 && /usr/sbin/aa-enforce --help > /dev/null 2>&1 && echo OK || echo FAIL" | grep -q OK || \
(echo "❌ CHECK 8 FAILED: apparmor-utils no instalado" && \
echo " Ejecuta: vagrant ssh -c \"sudo apt-get install -y apparmor-utils\"" && exit 1)
@echo "✅ Check 8/8 OK"
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ ✅ TEST-PROVISION-1 PASSED — entorno listo ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
test-invariant-seed:
@echo ""
@echo "── TEST-INVARIANT-SEED: 6 seeds idénticos post-reset ──"
@vagrant ssh -c 'sudo bash -c " \
hashes=\"\" ; \
for c in etcd-server ml-detector sniffer firewall-acl-agent rag-ingester rag-security; do \
h=\$$(od -A n -t x1 /etc/ml-defender/\$$c/seed.bin | tr -d \" \\n\") ; \
hashes=\"\$$hashes \$$h\" ; \
done ; \
unique=\$$(echo \$$hashes | tr \" \" \"\\n\" | sort -u | grep -v \"^$$\" | wc -l) ; \
echo \"Hashes únicos: \$$unique\" ; \
[ \"\$$unique\" -eq 1 ] && echo \"✅ TEST-INVARIANT-SEED PASSED\" || { echo \"❌ TEST-INVARIANT-SEED FAILED\"; exit 1; } \
"' || (echo "❌ INVARIANTE-SEED-001 violado: seeds divergentes" && exit 1)
@echo ""
pipeline-start: test-provision-1 etcd-server-start
@echo "⏳ Waiting for etcd-server to stabilize (Seed generation)..."
@sleep 4
@$(MAKE) rag-start
@sleep 5
@$(MAKE) ml-detector-start VERBOSE=$(VERBOSE) FORCE_ALL_HEADS=$(FORCE_ALL_HEADS)
@$(MAKE) firewall-start
@sleep 2
@$(MAKE) sniffer-start
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ ✅ FULL PIPELINE STARTED (DAY 103 — con provisioning) ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@$(MAKE) pipeline-status
pipeline-start-x86-libpcap: test-provision-1 etcd-server-start
@echo "⏳ Waiting for etcd-server to stabilize (Seed generation)..."
@sleep 4
@$(MAKE) rag-start
@sleep 5
@$(MAKE) ml-detector-start
@$(MAKE) firewall-start
@sleep 2
@$(MAKE) sniffer-libpcap-start
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ ✅ FULL PIPELINE STARTED — Variant B (libpcap) ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@$(MAKE) pipeline-status
pipeline-stop:
@echo "🛑 Stopping all pipeline components..."
@vagrant ssh -c "for s in sniffer ml-detector firewall rag-ingester rag-security etcd-server; do tmux kill-session -t $$s 2>/dev/null || true; done"
@echo "✅ Pipeline stopped"
pipeline-status:
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 📊 ML Defender Pipeline Status (via TMUX + pgrep) ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@vagrant ssh -c "( tmux has-session -t etcd-server 2>/dev/null || pgrep -x etcd-server >/dev/null 2>&1 ) && echo ' ✅ etcd-server: RUNNING' || echo ' ❌ etcd-server: STOPPED'"
@vagrant ssh -c "( tmux has-session -t rag-security 2>/dev/null || pgrep -x rag-security >/dev/null 2>&1 ) && echo ' ✅ rag-security: RUNNING' || echo ' ❌ rag-security: STOPPED'"
@vagrant ssh -c "( tmux has-session -t ml-detector 2>/dev/null || pgrep -x ml-detector >/dev/null 2>&1 ) && echo ' ✅ ml-detector: RUNNING' || echo ' ❌ ml-detector: STOPPED'"
@vagrant ssh -c " \
EBPF=0; PCAP=0; \
tmux has-session -t sniffer 2>/dev/null && EBPF=1; \
tmux has-session -t sniffer-libpcap 2>/dev/null && PCAP=1; \
pgrep -x sniffer >/dev/null 2>&1 && EBPF=1; \
pgrep -x sniffer-libpcap >/dev/null 2>&1 && PCAP=1; \
if [ \$$EBPF -eq 1 ] && [ \$$PCAP -eq 0 ]; then \
echo ' ✅ sniffer: RUNNING [Variant A — eBPF]'; \
elif [ \$$EBPF -eq 0 ] && [ \$$PCAP -eq 1 ]; then \
echo ' ✅ sniffer: RUNNING [Variant B — libpcap]'; \
elif [ \$$EBPF -eq 1 ] && [ \$$PCAP -eq 1 ]; then \
echo ' 🚨 sniffer: INVARIANT VIOLATION — eBPF + libpcap SIMULTANEOUS'; \
else \
echo ' ❌ sniffer: STOPPED'; \
fi"
@vagrant ssh -c "( tmux has-session -t firewall 2>/dev/null || pgrep -x firewall-acl-agent >/dev/null 2>&1 ) && echo ' ✅ firewall: RUNNING' || echo ' ❌ firewall: STOPPED'"
@vagrant ssh -c "VAULT_ADDR=http://127.0.0.1:8200 VAULT_TOKEN=argus-dev-token vault status >/dev/null 2>&1 && echo ' ✅ vault: RUNNING [dev]' || echo ' ❌ vault: STOPPED'"
@vagrant ssh -c "curl -s http://127.0.0.1:8080/api/json >/dev/null 2>&1 && echo ' ✅ jenkins: RUNNING' || echo ' ➖ jenkins: NOT CONFIGURED'"
@echo "╚════════════════════════════════════════════════════════════╝"
install-systemd-units:
@echo "═══ Instalando systemd units ML Defender ═══"
@vagrant ssh -c "sudo bash /vagrant/etcd-server/config/install-systemd-units.sh"
set-build-profile:
@echo "═══ Activando perfil de build: $(PROFILE) ═══"
@vagrant ssh -c "sudo bash /vagrant/etcd-server/config/set-build-profile.sh $(PROFILE)"
# Secuencia completa post-build:
# 1. pipeline-build → compila todos los componentes y libs
# 2. install-systemd-units → instala units en /etc/systemd/system/
# 3. set-build-profile → activa symlinks build-active
# 4. sign-plugins → firma Ed25519 (ADR-025)
# 5. test-provision-1 → CI gate PHASE 3
# 6. pipeline-start → arranca los 6 componentes
pipeline-build: crypto-transport-build seed-client-build etcd-client-build plugin-loader-build vault-client-build plugin-test-message-build etcd-server rag-build rag-ingester-build ml-detector sniffer firewall-build argus-network-isolate-build argus-network-isolate-install
tools: proto etcd-client-build crypto-transport-build
@echo ""
@echo "╔════════════════════════════════════════════════════════════╗"
@echo "║ 🔨 Building Tools [$(PROFILE)] ║"
@echo "╚════════════════════════════════════════════════════════════╝"
@echo ""
@echo "Build dir: $(TOOLS_BUILD_DIR)"
@echo "Flags: $(CMAKE_FLAGS)"
@echo ""
@echo "Copying protobuf files..."
@vagrant ssh -c 'mkdir -p $(TOOLS_BUILD_DIR)/proto && \
cp /vagrant/protobuf/network_security.pb.* $(TOOLS_BUILD_DIR)/proto/'
@echo "Running CMake and build..."
@vagrant ssh -c 'cd /vagrant/tools && \