mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2026-07-22 16:55:40 +02:00
Compare commits
1127
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
894d323323 | ||
|
|
89f4950521 | ||
|
|
387781c629 | ||
|
|
011749ad09 | ||
|
|
ad78e84ccd | ||
|
|
c4295b4e0a | ||
|
|
c2075ddafb | ||
|
|
4886034fef | ||
|
|
48a7d66964 | ||
|
|
6876b25280 | ||
|
|
30f3bddb8b | ||
|
|
811b799b0b | ||
|
|
aaea6dbd58 | ||
|
|
8095b82841 | ||
|
|
141116f550 | ||
|
|
f6d3cbe08d | ||
|
|
9e7e6edae0 | ||
|
|
6f61e7c901 | ||
|
|
cc2bfc26e2 | ||
|
|
073e32520b | ||
|
|
5867b50720 | ||
|
|
8a16ead33d | ||
|
|
f9b154ccef | ||
|
|
3503d0c33d | ||
|
|
517538a9a7 | ||
|
|
23c74f1727 | ||
|
|
b76f9d022e | ||
|
|
02318f065c | ||
|
|
f958212bea | ||
|
|
376607d292 | ||
|
|
186bf86e99 | ||
|
|
bd70dd53fb | ||
|
|
be7d8a2aa7 | ||
|
|
5178d5fd0e | ||
|
|
fee62ab976 | ||
|
|
618712469e | ||
|
|
8b488f9226 | ||
|
|
1657480d31 | ||
|
|
63d4061500 | ||
|
|
405dc52587 | ||
|
|
e42f7cd6fc | ||
|
|
8167ae3282 | ||
|
|
2cd889782d | ||
|
|
87a5639643 | ||
|
|
ed533efb7b | ||
|
|
5af6c56996 | ||
|
|
99e9fc1c3b | ||
|
|
e5de499bcc | ||
|
|
7d17784e96 | ||
|
|
f0bbbf37d8 | ||
|
|
6fc0fd954c | ||
|
|
566f90a0c0 | ||
|
|
89e6a746c8 | ||
|
|
52885e28c5 | ||
|
|
fbeac25ee9 | ||
|
|
8a3f5d0f81 | ||
|
|
4e856f02da | ||
|
|
f6a2758321 | ||
|
|
0b078c4804 | ||
|
|
2959dc9564 | ||
|
|
8b0759866e | ||
|
|
6fa0d327cb | ||
|
|
9a71f64a35 | ||
|
|
40c02b3149 | ||
|
|
5fd5df54b4 | ||
|
|
3394e9aab7 | ||
|
|
3766f74102 | ||
|
|
c04a30785f | ||
|
|
ca4d22a5fe | ||
|
|
ea199aee55 | ||
|
|
5a57bbe4de | ||
|
|
1f44e98681 | ||
|
|
9a313d1966 | ||
|
|
85d7f6bebc | ||
|
|
2a4a7307f7 | ||
|
|
f8de176f4b | ||
|
|
dffe0d3780 | ||
|
|
d131d167de | ||
|
|
8a8f2c4a33 | ||
|
|
7f6014096b | ||
|
|
70af3cec53 | ||
|
|
57b7d59387 | ||
|
|
ef83450107 | ||
|
|
032d792331 | ||
|
|
66a1141b84 | ||
|
|
0cac761edc | ||
|
|
db91ce981d | ||
|
|
bd8e5a63db | ||
|
|
18212cad0d | ||
|
|
9975d36b4f | ||
|
|
8e9e221196 | ||
|
|
1fe7726aff | ||
|
|
83cf1f0793 | ||
|
|
3310e19ee4 | ||
|
|
07d6b2cfdd | ||
|
|
89afea876a | ||
|
|
1243a25bd3 | ||
|
|
8675296393 | ||
|
|
23f04e2866 | ||
|
|
76f6947f36 | ||
|
|
92a55386c6 | ||
|
|
e7352eb841 | ||
|
|
795aa898a3 | ||
|
|
69d77382f1 | ||
|
|
dc9b4f3ce5 | ||
|
|
87b9276c79 | ||
|
|
99118f9bed | ||
|
|
24b75b4a2b | ||
|
|
395bd627f1 | ||
|
|
868b217549 | ||
|
|
c33db9d00f | ||
|
|
e88eb65a44 | ||
|
|
dc8c80633b | ||
|
|
f441d98e71 | ||
|
|
895aa18486 | ||
|
|
2a6cc58306 | ||
|
|
ee36f5f84c | ||
|
|
9217670bab | ||
|
|
a3f586cf88 | ||
|
|
670d2b2757 | ||
|
|
3b8459c6ec | ||
|
|
52574e21c6 | ||
|
|
a330bea25e | ||
|
|
33c24cd136 | ||
|
|
12f4447875 | ||
|
|
576c7bfedd | ||
|
|
b3b7ecdded | ||
|
|
0af020b6c3 | ||
|
|
339a5af4a3 | ||
|
|
da94788255 | ||
|
|
7952c274c4 | ||
|
|
67a9abadf2 | ||
|
|
94f31e1356 | ||
|
|
435e2b4182 | ||
|
|
d0edfd2131 | ||
|
|
13ebde61bd | ||
|
|
fa2ae1b87f | ||
|
|
5bf9751adf | ||
|
|
3effdbc91e | ||
|
|
30312b93a6 | ||
|
|
a9c03e39bb | ||
|
|
8836529496 | ||
|
|
b09c3776b7 | ||
|
|
dfdb1fbaeb | ||
|
|
4d34470b84 | ||
|
|
b0b022c3ad | ||
|
|
27c1c35e62 | ||
|
|
f45631af3a | ||
|
|
61aa963a2d | ||
|
|
81c8d54589 | ||
|
|
4f3b57f495 | ||
|
|
84228a819b | ||
|
|
81ebea0451 | ||
|
|
8e2753aeb8 | ||
|
|
698a746d6d | ||
|
|
d71e80cf66 | ||
|
|
a9f9d8bd0d | ||
|
|
953fdee3af | ||
|
|
e2e3e690ca | ||
|
|
323491f58e | ||
|
|
96fcc0ec38 | ||
|
|
bcc60a4ae0 | ||
|
|
b77103aa9f | ||
|
|
63a2e20698 | ||
|
|
22d5c96bd5 | ||
|
|
28fdd1eb6f | ||
|
|
d0bea2ebcb | ||
|
|
62c01a9756 | ||
|
|
b143e1e577 | ||
|
|
16149df71f | ||
|
|
6a18f35020 | ||
|
|
aa58225e8f | ||
|
|
8e33d0e1e9 | ||
|
|
acf48db915 | ||
|
|
3daed551df | ||
|
|
4456bde1c8 | ||
|
|
4a6c675223 | ||
|
|
a769d4c680 | ||
|
|
f68e3e47a1 | ||
|
|
b81257bf45 | ||
|
|
1a423a2434 | ||
|
|
95cae4c734 | ||
|
|
596471e140 | ||
|
|
d10f21399c | ||
|
|
ae1ddf3817 | ||
|
|
ea73216f4e | ||
|
|
1ee555957a | ||
|
|
43f72c1f9f | ||
|
|
9031c1fd22 | ||
|
|
ae6a705ce1 | ||
|
|
80c39d612c | ||
|
|
c505160480 | ||
|
|
d9f6cde4e1 | ||
|
|
b1273573ed | ||
|
|
6c42c419e2 | ||
|
|
f03f0155f4 | ||
|
|
f23652397c | ||
|
|
07d3b148b5 | ||
|
|
780d9faf0d | ||
|
|
d2fe51d5fe | ||
|
|
0cc94980af | ||
|
|
b8bf684077 | ||
|
|
f083db67e4 | ||
|
|
4741cc92bd | ||
|
|
46655860e9 | ||
|
|
289ddda5e8 | ||
|
|
83aaa76f98 | ||
|
|
f905afbc6f | ||
|
|
bd5e77afc5 | ||
|
|
944e773759 | ||
|
|
33a116357d | ||
|
|
cf456dc58c | ||
|
|
9aa9ea3255 | ||
|
|
3ba96da3b7 | ||
|
|
f0712bd780 | ||
|
|
448668a72e | ||
|
|
f088a27159 | ||
|
|
9f5a9616a5 | ||
|
|
27c7702325 | ||
|
|
8c306eb37d | ||
|
|
e536ffa363 | ||
|
|
eb82f9ea9d | ||
|
|
d7aa7ab228 | ||
|
|
fe0b68d24c | ||
|
|
6ad345730b | ||
|
|
9580976ba2 | ||
|
|
ac907ba45f | ||
|
|
f957954abf | ||
|
|
cb3631da81 | ||
|
|
f5d63f585e | ||
|
|
13f8be40b5 | ||
|
|
9ee90a5bc0 | ||
|
|
ca85c5d900 | ||
|
|
2d653b6f1b | ||
|
|
34fee25b0c | ||
|
|
1d3d98f759 | ||
|
|
a767c79641 | ||
|
|
61e72c89e4 | ||
|
|
d9fb7313f9 | ||
|
|
7ca2313255 | ||
|
|
534f0e639d | ||
|
|
559465b407 | ||
|
|
f9c2579261 | ||
|
|
33699a914b | ||
|
|
0c2d8f8973 | ||
|
|
8c17ae0f66 | ||
|
|
f2996fb888 | ||
|
|
3c533cccbc | ||
|
|
79da9f9f2c | ||
|
|
99a027589b | ||
|
|
68a82a425b | ||
|
|
f54939b444 | ||
|
|
d86a3c5cc9 | ||
|
|
86edc5aaba | ||
|
|
d48a22e37e | ||
|
|
9a70a06b3b | ||
|
|
526d739b3b | ||
|
|
68d783e760 | ||
|
|
1e9b6b0975 | ||
|
|
2131e7d450 | ||
|
|
2a2d853ac4 | ||
|
|
5abd6de4b5 | ||
|
|
bb8ae91d91 | ||
|
|
93ffce98d7 | ||
|
|
5599cce22c | ||
|
|
b2a82fec29 | ||
|
|
613eca52fc | ||
|
|
79987f3659 | ||
|
|
bf609a112e | ||
|
|
0b4a4de609 | ||
|
|
ad376d2a43 | ||
|
|
0834998cca | ||
|
|
473f93f0ee | ||
|
|
16055c4d88 | ||
|
|
6393d08e86 | ||
|
|
7cc2e045fb | ||
|
|
6955ee73bf | ||
|
|
c0272ddb81 | ||
|
|
d72219c586 | ||
|
|
ffd34d4e0e | ||
|
|
aa78978740 | ||
|
|
75d4f5e496 | ||
|
|
89a28d2cfe | ||
|
|
c1d187599b | ||
|
|
d87313db27 | ||
|
|
141a61f5b5 | ||
|
|
901cbf03e4 | ||
|
|
b485be4602 | ||
|
|
7d13007aa9 | ||
|
|
d7a1b67095 | ||
|
|
6c8997b28a | ||
|
|
58f1d08ebe | ||
|
|
d0aa33a255 | ||
|
|
730c828bec | ||
|
|
74b50f6009 | ||
|
|
e89c820b65 | ||
|
|
9ac05a6ad1 | ||
|
|
24ee3318bc | ||
|
|
ce566ba174 | ||
|
|
2635a60a8c | ||
|
|
244a73b7a2 | ||
|
|
e45ad45d73 | ||
|
|
1189621ec5 | ||
|
|
d2524a593f | ||
|
|
f2ab2354fd | ||
|
|
64731c73ba | ||
|
|
024fece607 | ||
|
|
249b126312 | ||
|
|
8e38bff0c3 | ||
|
|
b9f2d56932 | ||
|
|
03fa01a705 | ||
|
|
450eacca41 | ||
|
|
b7a13899f7 | ||
|
|
6f273d7d97 | ||
|
|
fabecb8288 | ||
|
|
907f699721 | ||
|
|
e7a7047f71 | ||
|
|
b4e5171415 | ||
|
|
b328820c01 | ||
|
|
936295f1c4 | ||
|
|
61ca60a94c | ||
|
|
638aca97c8 | ||
|
|
74a5c895e8 | ||
|
|
84decc1db6 | ||
|
|
d56bf01823 | ||
|
|
d29267d9c2 | ||
|
|
72327285b2 | ||
|
|
cc7a237457 | ||
|
|
b068ad2b35 | ||
|
|
b103f412b5 | ||
|
|
ef79c63858 | ||
|
|
01fb1aa156 | ||
|
|
f19bdd7aae | ||
|
|
f637dc62d1 | ||
|
|
081f6fa1fb | ||
|
|
d6d90d84cd | ||
|
|
125610ed42 | ||
|
|
306b0af4d0 | ||
|
|
492ae80da7 | ||
|
|
4a2177c827 | ||
|
|
006ac31109 | ||
|
|
7d4d6a0756 | ||
|
|
66c0a662fc | ||
|
|
49a643fff4 | ||
|
|
e1d830da76 | ||
|
|
778cc055ea | ||
|
|
e847c46129 | ||
|
|
499f7102bd | ||
|
|
932deab751 | ||
|
|
1281f0ee37 | ||
|
|
4bc19f91ce | ||
|
|
f774334b6c | ||
|
|
4990d0ddea | ||
|
|
3e49322220 | ||
|
|
ecb92d43fc | ||
|
|
3b714db0bf | ||
|
|
f17da4e68b | ||
|
|
04cfc22e3f | ||
|
|
dceed421ae | ||
|
|
652ac5d61f | ||
|
|
f888a2ba6b | ||
|
|
8a1ee02335 | ||
|
|
192f6cfe13 | ||
|
|
5bca81d833 | ||
|
|
1c6574c694 | ||
|
|
b701664e04 | ||
|
|
bc64f1431d | ||
|
|
2203037ce7 | ||
|
|
77a4ad877e | ||
|
|
702b3585cc | ||
|
|
86966d2778 | ||
|
|
7fcace34c4 | ||
|
|
9541024eb7 | ||
|
|
ce3ad3a895 | ||
|
|
3a4b7b50de | ||
|
|
0d166ef732 | ||
|
|
f7d2994f8b | ||
|
|
39d0947102 | ||
|
|
8f0757606d | ||
|
|
0a8f2e01a0 | ||
|
|
4546d7bc52 | ||
|
|
0085d9a353 | ||
|
|
2f01ce3b23 | ||
|
|
71b19c1b5f | ||
|
|
82e55ae87f | ||
|
|
3e02001544 | ||
|
|
17849d8758 | ||
|
|
82f70bb53a | ||
|
|
2dcded6cca | ||
|
|
d3d30a587c | ||
|
|
8ca59e6f0c | ||
|
|
82dac82d15 | ||
|
|
288a823edf | ||
|
|
f9e3d30a71 | ||
|
|
9cec79b299 | ||
|
|
c86399327b | ||
|
|
034711d148 | ||
|
|
fa8162de02 | ||
|
|
33abc429d1 | ||
|
|
b22585ca90 | ||
|
|
9f2ca7012f | ||
|
|
21aeb68188 | ||
|
|
81e60ec5bf | ||
|
|
199c2746f1 | ||
|
|
8eca465ef6 | ||
|
|
a45e59239f | ||
|
|
2ad0bcab7c | ||
|
|
070d150420 | ||
|
|
90ecbe90d8 | ||
|
|
813fa03dc3 | ||
|
|
02381fbbe9 | ||
|
|
0722b681b1 | ||
|
|
564815e836 | ||
|
|
88b30adf7f | ||
|
|
b6acf3b522 | ||
|
|
ba55468da8 | ||
|
|
cdd217283d | ||
|
|
810a582717 | ||
|
|
a6948e8dcb | ||
|
|
5f35554fdc | ||
|
|
0ecc7ae594 | ||
|
|
fdfca469cc | ||
|
|
5f2ec76ba8 | ||
|
|
b015c8ff14 | ||
|
|
7e70870a9e | ||
|
|
eadad6c163 | ||
|
|
22b32a16dd | ||
|
|
22f869734e | ||
|
|
398bc9e4ed | ||
|
|
72dbb69a1c | ||
|
|
339959d1c0 | ||
|
|
d5c0ec4404 | ||
|
|
e616b4c120 | ||
|
|
f240a99e22 | ||
|
|
614f32c5e0 | ||
|
|
cd6707a566 | ||
|
|
edd207a9d5 | ||
|
|
724d76965f | ||
|
|
dbf4fb66a4 | ||
|
|
5f28e9b191 | ||
|
|
01bd3b6e06 | ||
|
|
1abfd77351 | ||
|
|
06a555fafb | ||
|
|
81c0f2b464 | ||
|
|
d5dc28e526 | ||
|
|
7411031e11 | ||
|
|
247091766c | ||
|
|
7f93110d68 | ||
|
|
05f6503d61 | ||
|
|
a149ea7e8f | ||
|
|
bb71e44614 | ||
|
|
84197fb33b | ||
|
|
89a6e7c0dd | ||
|
|
a902f667ba | ||
|
|
f72c30abd0 | ||
|
|
37e9257698 | ||
|
|
72105f1f2f | ||
|
|
ee89b78751 | ||
|
|
33ef138866 | ||
|
|
71da27dc8e | ||
|
|
80bf07ffd8 | ||
|
|
b69e50542a | ||
|
|
3ecd19d085 | ||
|
|
b6a3d1889c | ||
|
|
1cb34b089c | ||
|
|
1537ba5031 | ||
|
|
8225d41661 | ||
|
|
ee437265fc | ||
|
|
affede7f0a | ||
|
|
97366c0496 | ||
|
|
3f46caaf02 | ||
|
|
f3181b204a | ||
|
|
dd39db4584 | ||
|
|
759880a800 | ||
|
|
f5cd90d139 | ||
|
|
31383bd9d0 | ||
|
|
ebb93b4fa7 | ||
|
|
21076af01e | ||
|
|
f11e9da83a | ||
|
|
0fddcd8fe7 | ||
|
|
927eba566c | ||
|
|
af9330a9dd | ||
|
|
b3fbd5c7a4 | ||
|
|
5228668be0 | ||
|
|
7d07f3c8fe | ||
|
|
d9a9029ce5 | ||
|
|
9fe53d9ccc | ||
|
|
f7b80f5931 | ||
|
|
f11d315fea | ||
|
|
2013bf9e30 | ||
|
|
a2ffb92b8d | ||
|
|
8b6d11b118 | ||
|
|
ba00ae8a7b | ||
|
|
470b3bd4da | ||
|
|
c124186989 | ||
|
|
d24808ff98 | ||
|
|
7d22f7bd58 | ||
|
|
88582c94e8 | ||
|
|
cefbe01333 | ||
|
|
76a6997de2 | ||
|
|
16a4a42faf | ||
|
|
0e4623c728 | ||
|
|
d598e20fbb | ||
|
|
8b0d4b2195 | ||
|
|
cf414423b1 | ||
|
|
0405a66c72 | ||
|
|
da7c2995b0 | ||
|
|
696a1a729c | ||
|
|
5fa7006f11 | ||
|
|
5634aed679 | ||
|
|
a232cd89cc | ||
|
|
dd40e44530 | ||
|
|
47d226e189 | ||
|
|
440537140b | ||
|
|
29e13b2c0b | ||
|
|
2006a07637 | ||
|
|
abcad9fde0 | ||
|
|
a43947cca5 | ||
|
|
f51de6569f | ||
|
|
b0584a4dc5 | ||
|
|
08f34d408f | ||
|
|
6298397534 | ||
|
|
a0cf0489d6 | ||
|
|
9ccd0acb4f | ||
|
|
1ffdcab3be | ||
|
|
da1045e052 | ||
|
|
55be1f1119 | ||
|
|
9272afa9e5 | ||
|
|
378d1ec81b | ||
|
|
c1b1452bd9 | ||
|
|
cdbacdcd7e | ||
|
|
6b8a6267da | ||
|
|
89e49d0bf3 | ||
|
|
2dfa83dd7d | ||
|
|
f0b67a415a | ||
|
|
b87af8ea3d | ||
|
|
46e38d39bb | ||
|
|
81afbd32d4 | ||
|
|
e9c4f40735 | ||
|
|
61bdfb1a4b | ||
|
|
9ec4a26f97 | ||
|
|
358a2e6d3f | ||
|
|
762e73faf5 | ||
|
|
ef3cfc8722 | ||
|
|
28d31f4840 | ||
|
|
2166bb749a | ||
|
|
868cd11874 | ||
|
|
7356f3affd | ||
|
|
dd56e7f1ac | ||
|
|
075b592471 | ||
|
|
51a3c04c3d | ||
|
|
1a8aae3039 | ||
|
|
8101bc4941 | ||
|
|
88de246ce3 | ||
|
|
3643b57167 | ||
|
|
5b3ca98b80 | ||
|
|
51e0ca2602 | ||
|
|
664f3fd18a | ||
|
|
76f4ccf8c8 | ||
|
|
2a37ad82b2 | ||
|
|
80540da52f | ||
|
|
e4ba3d6a2a | ||
|
|
3dec6986b6 | ||
|
|
bbfb58ea4e | ||
|
|
c91deb97b1 | ||
|
|
dc2598d5cf | ||
|
|
ff45e5ebc6 | ||
|
|
1e2b51eae6 | ||
|
|
58d332ea94 | ||
|
|
dcc67b9b8f | ||
|
|
cd886dd0f9 | ||
|
|
37a6e28a6c | ||
|
|
434a2e7866 | ||
|
|
79707db6ee | ||
|
|
0707507412 | ||
|
|
c7e865aa1c | ||
|
|
a89db79854 | ||
|
|
812f65eee8 | ||
|
|
cfa530ba9c | ||
|
|
922c008b11 | ||
|
|
ea30749512 | ||
|
|
0a55592d7e | ||
|
|
115ca2c41d | ||
|
|
9e53bd3f2d | ||
|
|
d4f1078f84 | ||
|
|
1f9bf45b66 | ||
|
|
271de757e7 | ||
|
|
d4ac352b5a | ||
|
|
afcef1d0e7 | ||
|
|
91b164b728 | ||
|
|
6a4501241d | ||
|
|
c6978f9037 | ||
|
|
7300513636 | ||
|
|
fb7b73c601 | ||
|
|
f2b6d59c65 | ||
|
|
67162357a3 | ||
|
|
8ea97e4af3 | ||
|
|
2f9a2e15b3 | ||
|
|
a4fcf4ddf2 | ||
|
|
165e69cd11 | ||
|
|
07580c3afd | ||
|
|
f0f9de4b44 | ||
|
|
e857a8487a | ||
|
|
fa4bf218d5 | ||
|
|
2186872317 | ||
|
|
6e3986b0b0 | ||
|
|
2585bdd23f | ||
|
|
ca588d2e78 | ||
|
|
f756ecb396 | ||
|
|
82107f00a1 | ||
|
|
5c53244b54 | ||
|
|
3b269e8b82 | ||
|
|
7ece93d7e0 | ||
|
|
14d254e81b | ||
|
|
7af6efda1e | ||
|
|
ce972238fe | ||
|
|
442bd1499d | ||
|
|
30ea309dff | ||
|
|
bfeefeea2f | ||
|
|
8251d56a96 | ||
|
|
1b1e602716 | ||
|
|
034b1d045b | ||
|
|
20bf88b338 | ||
|
|
d3f819017b | ||
|
|
c92aedfff3 | ||
|
|
7aded184b3 | ||
|
|
d3938b61d2 | ||
|
|
c2c5aea244 | ||
|
|
83b7fecbbc | ||
|
|
d227cf71c8 | ||
|
|
020b9db610 | ||
|
|
cceaebe350 | ||
|
|
a982056363 | ||
|
|
db81834e06 | ||
|
|
318e4ec54b | ||
|
|
20bf05e9f3 | ||
|
|
4254769e68 | ||
|
|
c16ff2bd99 | ||
|
|
0c88b32fc2 | ||
|
|
0814f34f0e | ||
|
|
b6366e52ba | ||
|
|
825f377d2d | ||
|
|
74ad2990a7 | ||
|
|
738ce62d35 | ||
|
|
057ec6f0f1 | ||
|
|
20c4da50b1 | ||
|
|
5fb396fc09 | ||
|
|
a0b1e31717 | ||
|
|
cacae12ba3 | ||
|
|
83bd8a025c | ||
|
|
2a271b950b | ||
|
|
e19e83bebb | ||
|
|
066918e27d | ||
|
|
930985b770 | ||
|
|
346dc446de | ||
|
|
7e7b8dc8a8 | ||
|
|
341471d38e | ||
|
|
2349750e13 | ||
|
|
2c6c502067 | ||
|
|
00986dc2fd | ||
|
|
d60bef1371 | ||
|
|
5806a85214 | ||
|
|
2d97dfc8a1 | ||
|
|
d6263812a6 | ||
|
|
ef7d1771ab | ||
|
|
4dc377c99f | ||
|
|
a52e5d0474 | ||
|
|
1a943aefc5 | ||
|
|
4bb61d999d | ||
|
|
e0e0e3e97b | ||
|
|
6b039b3f94 | ||
|
|
d2d2f0cb5f | ||
|
|
e6ee7dac7c | ||
|
|
7bf63b822d | ||
|
|
1a7d72c630 | ||
|
|
4224713cc6 | ||
|
|
b452e70419 | ||
|
|
6809497730 | ||
|
|
70597a77ab | ||
|
|
f5faf86cb3 | ||
|
|
be4e253620 | ||
|
|
ebc1152376 | ||
|
|
625bfb3ba7 | ||
|
|
c11b83c712 | ||
|
|
a3b471c1d1 | ||
|
|
eaf3f10adc | ||
|
|
84f4e460f6 | ||
|
|
88841c9814 | ||
|
|
64bb0dfb5b | ||
|
|
ddb26a9f42 | ||
|
|
744d8fdd5e | ||
|
|
6feb06e623 | ||
|
|
afc14ec29d | ||
|
|
59134c65d0 | ||
|
|
614537998a | ||
|
|
d2cee468a0 | ||
|
|
94f454c311 | ||
|
|
17881c9a36 | ||
|
|
5b2def6fdd | ||
|
|
9b6d29212d | ||
|
|
c1bff03b1c | ||
|
|
b00f113658 | ||
|
|
7dcd923ebf | ||
|
|
1fcd8a7c1a | ||
|
|
4a89f7f26b | ||
|
|
a9196348ab | ||
|
|
12dec366e0 | ||
|
|
1713f6af76 | ||
|
|
7f4adb70bd | ||
|
|
e2483e4be0 | ||
|
|
322c0b8d56 | ||
|
|
81c1d8362d | ||
|
|
d1156ee3fd | ||
|
|
18f971954b | ||
|
|
e55ac7062c | ||
|
|
c178eada22 | ||
|
|
92213e302f | ||
|
|
72193b0249 | ||
|
|
066d7106b0 | ||
|
|
589de8e361 | ||
|
|
914cd8b611 | ||
|
|
845290595e | ||
|
|
544b60d111 | ||
|
|
aa0787b0ff | ||
|
|
89f144df75 | ||
|
|
cfccbe2bed | ||
|
|
3dd9a06d67 | ||
|
|
4bfe9039ed | ||
|
|
75cddbf444 | ||
|
|
89b18341c5 | ||
|
|
90137f7093 | ||
|
|
d7e971a0fc | ||
|
|
480187b1f5 | ||
|
|
b3ed54633f | ||
|
|
0360d4145c | ||
|
|
2bec5afcdd | ||
|
|
4539024280 | ||
|
|
398bd0c1da | ||
|
|
91759587f5 | ||
|
|
bc9841ea8c | ||
|
|
32241faf55 | ||
|
|
685e22bd68 | ||
|
|
88de779ff7 | ||
|
|
d452694c55 | ||
|
|
7fba8ac2b4 | ||
|
|
0738208627 | ||
|
|
a3720219d8 | ||
|
|
385726b87c | ||
|
|
d78a5867b8 | ||
|
|
ad960c2101 | ||
|
|
7f07c96a2f | ||
|
|
90bea975d0 | ||
|
|
e8adea3022 | ||
|
|
71839bc87f | ||
|
|
6809a40257 | ||
|
|
cea55a72c3 | ||
|
|
e38a4a21ee | ||
|
|
613d31c8a6 | ||
|
|
7ac1e767ab | ||
|
|
2c4d833a5b | ||
|
|
41d3dd0aa5 | ||
|
|
6050ab6b21 | ||
|
|
ae05251359 | ||
|
|
f23158aed5 | ||
|
|
b03b75315d | ||
|
|
cbd98efaf4 | ||
|
|
1f7bf1fd88 | ||
|
|
179019b136 | ||
|
|
ac022acbbe | ||
|
|
6bfe020c3b | ||
|
|
55a960bbc5 | ||
|
|
42bc657b60 | ||
|
|
a9d2be8131 | ||
|
|
7457d5565d | ||
|
|
863276e24f | ||
|
|
9bd5e1897a | ||
|
|
17e3a4bf21 | ||
|
|
2284283b17 | ||
|
|
90789bdb07 | ||
|
|
fcad82c4d4 | ||
|
|
972aa1f8a1 | ||
|
|
79d9b6e0a4 | ||
|
|
dfed3681df | ||
|
|
6b82712474 | ||
|
|
039e8db85f | ||
|
|
55e984df4c | ||
|
|
5e7b0cfe0e | ||
|
|
ee4a2f00be | ||
|
|
c4b6cef8ee | ||
|
|
c1c568e94d | ||
|
|
12b3081a62 | ||
|
|
91ea0e6952 | ||
|
|
0bcfec3f56 | ||
|
|
4d5ace2a89 | ||
|
|
f4be73fdde | ||
|
|
742649a337 | ||
|
|
32a26559dd | ||
|
|
7e5daf7f7f | ||
|
|
2552a5c17d | ||
|
|
fa479c4b89 | ||
|
|
479e3e0afa | ||
|
|
be35b59b8c | ||
|
|
c52d3269d6 | ||
|
|
3583b92836 | ||
|
|
2375061cfa | ||
|
|
1a9a087af2 | ||
|
|
bf16de7bfd | ||
|
|
863c7abc8b | ||
|
|
7170289a5e | ||
|
|
ca040044bb | ||
|
|
f17e2961ed | ||
|
|
bbc7668786 | ||
|
|
1888f9e757 | ||
|
|
5822d1c974 | ||
|
|
b3139c5008 | ||
|
|
0a64bb0a87 | ||
|
|
cf6b5aeceb | ||
|
|
bcb850d98a | ||
|
|
f0139c04f0 | ||
|
|
78ae6cd84c | ||
|
|
b7e0b2faa3 | ||
|
|
bfd1cf2d9b | ||
|
|
8cc8a63a4e | ||
|
|
b3a0eb0761 | ||
|
|
38e45056f2 | ||
|
|
39bad077ae | ||
|
|
b349d27e8c | ||
|
|
90eee49ab6 | ||
|
|
f025886b31 | ||
|
|
7fa01f5fd5 | ||
|
|
75e1f74244 | ||
|
|
4036469857 | ||
|
|
256c1122c3 | ||
|
|
aa2a1a3d3c | ||
|
|
93f52453b4 | ||
|
|
a9307aa308 | ||
|
|
0ebd8e4d6c | ||
|
|
8fc3011f92 | ||
|
|
911c9d56db | ||
|
|
c1273c3d2c | ||
|
|
d0018c9333 | ||
|
|
3349c1a936 | ||
|
|
32819c8635 | ||
|
|
58c0a9183c | ||
|
|
7dfd212519 | ||
|
|
b8fb0fa735 | ||
|
|
e6f767b613 | ||
|
|
d00fb4ccf7 | ||
|
|
a29eff37a0 | ||
|
|
534a0ad41f | ||
|
|
4c86275cd6 | ||
|
|
a1c806a944 | ||
|
|
3d1a2c12ec | ||
|
|
8538e5572e | ||
|
|
9b525612a8 | ||
|
|
fb364aec5d | ||
|
|
ed014b431e | ||
|
|
82ca64d66f | ||
|
|
7e0fb73fec | ||
|
|
c28bcfa85e | ||
|
|
be6d94d65b | ||
|
|
ada463320b | ||
|
|
2b05583035 | ||
|
|
4d6b2de374 | ||
|
|
41d94b6bfd | ||
|
|
2d74002e9e | ||
|
|
04a757dde0 | ||
|
|
e7e379ce82 | ||
|
|
fe0178b8ac | ||
|
|
0661c3af1a | ||
|
|
4778bd6680 | ||
|
|
5033462098 | ||
|
|
6b4b1d74fd | ||
|
|
f0df6a171c | ||
|
|
dc4cd93c02 | ||
|
|
19157aa76c | ||
|
|
1c092bf791 | ||
|
|
ff8790b35b | ||
|
|
c6168c1487 | ||
|
|
c431ac3765 | ||
|
|
6ff4901067 | ||
|
|
eea14b493c | ||
|
|
6b98c5a10d | ||
|
|
6d5ac5a16b | ||
|
|
42060a9112 | ||
|
|
cca4bec43f | ||
|
|
9e7c304ea1 | ||
|
|
d540b024b2 | ||
|
|
cf1c3ac38d | ||
|
|
a99c553ada | ||
|
|
b1575237fc | ||
|
|
6ce6eb95d6 | ||
|
|
b3d1dd51a4 | ||
|
|
cd0d88e2c0 | ||
|
|
80f8fdc8d3 | ||
|
|
fd29fdd975 | ||
|
|
2de98b1397 | ||
|
|
1d57c02608 | ||
|
|
ebeeb91297 | ||
|
|
6282beb6bd | ||
|
|
1c06bddb09 | ||
|
|
36f8c490c8 | ||
|
|
94c1a641d8 | ||
|
|
057131dce7 | ||
|
|
e5226b50ed | ||
|
|
ff4ec69f7c | ||
|
|
4ad6136d98 | ||
|
|
006c17bdca | ||
|
|
6b1939b827 | ||
|
|
2038227308 | ||
|
|
950852d673 | ||
|
|
8900f9ade3 | ||
|
|
8cf0d59560 | ||
|
|
a78e0b0871 | ||
|
|
32f030f6f6 | ||
|
|
b0d87b49c6 | ||
|
|
55b3fa389e | ||
|
|
b3ae716929 | ||
|
|
5d0c187497 | ||
|
|
30d8cf5a6c | ||
|
|
07dbdb9f8f | ||
|
|
b4c8f7924a | ||
|
|
809422c517 | ||
|
|
bb7593a53a | ||
|
|
8e3ba8900f | ||
|
|
005ec87248 | ||
|
|
4c6ff0641b | ||
|
|
3e242913e9 | ||
|
|
ba68e3c9bd | ||
|
|
e1199a91b9 | ||
|
|
d381248e30 | ||
|
|
f4f0218cae | ||
|
|
7a38e52b01 | ||
|
|
959fd55e32 | ||
|
|
a8e218a9ff | ||
|
|
3f5cd46d7d | ||
|
|
627f0c2bcc | ||
|
|
f6bde3eb04 | ||
|
|
f6e95c17a0 | ||
|
|
1234cbd04b | ||
|
|
fd5b93542e | ||
|
|
a192455fae | ||
|
|
66f17e95aa | ||
|
|
6f4b96b61b | ||
|
|
9905d23976 | ||
|
|
17532fe49d | ||
|
|
074158b495 | ||
|
|
82d5115b3f | ||
|
|
5c63111002 | ||
|
|
6eda7932e8 | ||
|
|
399b7567dd | ||
|
|
2133ada3a1 | ||
|
|
4f6d4738c4 | ||
|
|
d430ed6727 | ||
|
|
596bc178df | ||
|
|
0cd3d7b5a8 | ||
|
|
349d77ffdf | ||
|
|
c3283b04e5 | ||
|
|
0da0788e6b | ||
|
|
6f7e249aa2 | ||
|
|
dfaeed54b6 | ||
|
|
4f59e46235 | ||
|
|
bf4cc7befb | ||
|
|
c63c6dc68b | ||
|
|
e4225d6e9b | ||
|
|
3fb153c43e | ||
|
|
6de20c63d4 | ||
|
|
00fbc1c259 | ||
|
|
3bc552ef38 | ||
|
|
ee70d94e15 | ||
|
|
1887d2c0e9 | ||
|
|
c99dd4e44f | ||
|
|
541b8b288d | ||
|
|
db168a0452 | ||
|
|
aa96cf44d4 | ||
|
|
0d59c35d2a | ||
|
|
8463bde90d | ||
|
|
150c31009e | ||
|
|
693494024d | ||
|
|
ee66d6c7d1 | ||
|
|
3effd30f7e | ||
|
|
4ab20c2454 | ||
|
|
c075b5a1a7 | ||
|
|
cb1e59fa49 | ||
|
|
588aa435ec | ||
|
|
752c764066 | ||
|
|
af604c2ea8 | ||
|
|
6c3f9f149d | ||
|
|
152f2e03f1 | ||
|
|
605797c86a | ||
|
|
1ee5b1611a | ||
|
|
5028729e4c | ||
|
|
ab00fa8809 | ||
|
|
2d705e7caa | ||
|
|
f2370043a8 | ||
|
|
3b349b9803 | ||
|
|
f2b7ffe0eb | ||
|
|
3a410eed1a | ||
|
|
a53619f10f | ||
|
|
893aaafa1b | ||
|
|
33c34cdeca | ||
|
|
9b411867df | ||
|
|
fd1596b3a0 | ||
|
|
b05de22f58 | ||
|
|
e9341ee8d3 | ||
|
|
f666ad600f | ||
|
|
9345718967 | ||
|
|
6c879cbd13 | ||
|
|
089b5aaf44 | ||
|
|
b61885add5 | ||
|
|
702ba2e0a4 | ||
|
|
5cb1e284af | ||
|
|
e3a4f0873e | ||
|
|
7977a020ac | ||
|
|
1d63269883 | ||
|
|
dd8027480b | ||
|
|
c45bd77e44 | ||
|
|
032e0abd61 | ||
|
|
8509d1e454 | ||
|
|
8ff0c6828b | ||
|
|
ddd6935e50 | ||
|
|
5588a56b24 | ||
|
|
12aed6e280 | ||
|
|
b2a469e08c | ||
|
|
285b0e4af9 | ||
|
|
f9edfd6391 | ||
|
|
c0845e1612 | ||
|
|
9878d9d37e | ||
|
|
a2196085d5 | ||
|
|
ba62a8c10c | ||
|
|
38f38e2789 | ||
|
|
1475f0fc2f | ||
|
|
a3396b77a3 | ||
|
|
8158fee8fc | ||
|
|
f6301bc3e5 | ||
|
|
6c5c176b7d | ||
|
|
c6d52b5eb1 | ||
|
|
7cac528389 | ||
|
|
d518f75468 | ||
|
|
c6fac8c36b | ||
|
|
17b5b81696 | ||
|
|
9960db200c | ||
|
|
b9ff1704b0 | ||
|
|
6fe817ca4a | ||
|
|
cb9a6fac25 | ||
|
|
a945768251 | ||
|
|
c6646e3821 | ||
|
|
99dc72cece | ||
|
|
04d6cca204 | ||
|
|
5ab6bda639 | ||
|
|
f433de7e12 | ||
|
|
8ef6c2f91d | ||
|
|
7575218697 | ||
|
|
dc945dad00 | ||
|
|
ddcd74ffd2 | ||
|
|
e105bd12e6 | ||
|
|
f5688175b6 | ||
|
|
72a4ba405f | ||
|
|
94694d394e | ||
|
|
03dd746601 | ||
|
|
eec3373ae7 | ||
|
|
db45ce07ed | ||
|
|
ba49765312 | ||
|
|
72c8c2371e | ||
|
|
80411ab6cf | ||
|
|
0ff8fa57e7 | ||
|
|
411f28a049 | ||
|
|
0f42233092 | ||
|
|
2dd49f6d9b | ||
|
|
271f545f4f | ||
|
|
c4a70b540e | ||
|
|
bef85772e3 | ||
|
|
a6b19c4a6c | ||
|
|
44f5e6659b | ||
|
|
3f9a9b7019 | ||
|
|
b7ad985c7a | ||
|
|
dba087ae25 | ||
|
|
bbc4b1b502 | ||
|
|
9304513ce8 | ||
|
|
0b127582cb | ||
|
|
6e9b8791c8 | ||
|
|
ef87ad77c3 | ||
|
|
8477420911 | ||
|
|
f5741e318f | ||
|
|
545060103a | ||
|
|
e010b5680a | ||
|
|
8620d3987e | ||
|
|
30487a54c1 | ||
|
|
f15a39c153 | ||
|
|
aed27fa111 | ||
|
|
822c411e83 | ||
|
|
41b3ac7554 | ||
|
|
23575fdf6c | ||
|
|
52f70dc49a | ||
|
|
79c9749ff7 | ||
|
|
8d2701e143 | ||
|
|
877444ac29 | ||
|
|
b0d9426f1b | ||
|
|
18accae47e | ||
|
|
55e3a2c6b6 | ||
|
|
ef092e2893 | ||
|
|
89eb95c077 | ||
|
|
e871ec358e | ||
|
|
271a2f74ad | ||
|
|
d6bd951c37 | ||
|
|
8abd4c9c78 | ||
|
|
45a8c0acd1 | ||
|
|
c372cd533d | ||
|
|
999f83ce57 | ||
|
|
6fbed2dd9f | ||
|
|
36a6a59d55 | ||
|
|
875de88cb4 | ||
|
|
63bb44886e | ||
|
|
edf3c9464f | ||
|
|
cc8fb96047 | ||
|
|
3339b50daf | ||
|
|
415ea07a4f | ||
|
|
b80ec95fa8 | ||
|
|
99cb51482f | ||
|
|
90638f7a43 | ||
|
|
1fb00c8eb6 | ||
|
|
4490ea7635 | ||
|
|
bce7a20d8b | ||
|
|
b52dd53e29 | ||
|
|
a155f45036 | ||
|
|
de4424fab0 | ||
|
|
33ada95bbc |
@@ -1,546 +0,0 @@
|
|||||||
title = "gitleaks config"
|
|
||||||
|
|
||||||
# Gitleaks rules are defined by regular expressions and entropy ranges.
|
|
||||||
# Some secrets have unique signatures which make detecting those secrets easy.
|
|
||||||
# Examples of those secrets would be GitLab Personal Access Tokens, AWS keys, and GitHub Access Tokens.
|
|
||||||
# All these examples have defined prefixes like `glpat`, `AKIA`, `ghp_`, etc.
|
|
||||||
#
|
|
||||||
# Other secrets might just be a hash which means we need to write more complex rules to verify
|
|
||||||
# that what we are matching is a secret.
|
|
||||||
#
|
|
||||||
# Here is an example of a semi-generic secret
|
|
||||||
#
|
|
||||||
# discord_client_secret = "8dyfuiRyq=vVc3RRr_edRk-fK__JItpZ"
|
|
||||||
#
|
|
||||||
# We can write a regular expression to capture the variable name (identifier),
|
|
||||||
# the assignment symbol (like '=' or ':='), and finally the actual secret.
|
|
||||||
# The structure of a rule to match this example secret is below:
|
|
||||||
#
|
|
||||||
# Beginning string
|
|
||||||
# quotation
|
|
||||||
# │ End string quotation
|
|
||||||
# │ │
|
|
||||||
# ▼ ▼
|
|
||||||
# (?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9=_\-]{32})['\"]
|
|
||||||
#
|
|
||||||
# ▲ ▲ ▲
|
|
||||||
# │ │ │
|
|
||||||
# │ │ │
|
|
||||||
# identifier assignment symbol
|
|
||||||
# Secret
|
|
||||||
#
|
|
||||||
[[rules]]
|
|
||||||
id = "gitlab-pat"
|
|
||||||
description = "GitLab Personal Access Token"
|
|
||||||
regex = '''glpat-[0-9a-zA-Z\-\_]{20}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "aws-access-token"
|
|
||||||
description = "AWS"
|
|
||||||
regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'''
|
|
||||||
|
|
||||||
# Cryptographic keys
|
|
||||||
[[rules]]
|
|
||||||
id = "PKCS8-PK"
|
|
||||||
description = "PKCS8 private key"
|
|
||||||
regex = '''-----BEGIN PRIVATE KEY-----'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "RSA-PK"
|
|
||||||
description = "RSA private key"
|
|
||||||
regex = '''-----BEGIN RSA PRIVATE KEY-----'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "OPENSSH-PK"
|
|
||||||
description = "SSH private key"
|
|
||||||
regex = '''-----BEGIN OPENSSH PRIVATE KEY-----'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "PGP-PK"
|
|
||||||
description = "PGP private key"
|
|
||||||
regex = '''-----BEGIN PGP PRIVATE KEY BLOCK-----'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "github-pat"
|
|
||||||
description = "GitHub Personal Access Token"
|
|
||||||
regex = '''ghp_[0-9a-zA-Z]{36}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "github-oauth"
|
|
||||||
description = "GitHub OAuth Access Token"
|
|
||||||
regex = '''gho_[0-9a-zA-Z]{36}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "SSH-DSA-PK"
|
|
||||||
description = "SSH (DSA) private key"
|
|
||||||
regex = '''-----BEGIN DSA PRIVATE KEY-----'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "SSH-EC-PK"
|
|
||||||
description = "SSH (EC) private key"
|
|
||||||
regex = '''-----BEGIN EC PRIVATE KEY-----'''
|
|
||||||
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "github-app-token"
|
|
||||||
description = "GitHub App Token"
|
|
||||||
regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "github-refresh-token"
|
|
||||||
description = "GitHub Refresh Token"
|
|
||||||
regex = '''ghr_[0-9a-zA-Z]{76}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "shopify-shared-secret"
|
|
||||||
description = "Shopify shared secret"
|
|
||||||
regex = '''shpss_[a-fA-F0-9]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "shopify-access-token"
|
|
||||||
description = "Shopify access token"
|
|
||||||
regex = '''shpat_[a-fA-F0-9]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "shopify-custom-access-token"
|
|
||||||
description = "Shopify custom app access token"
|
|
||||||
regex = '''shpca_[a-fA-F0-9]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "shopify-private-app-access-token"
|
|
||||||
description = "Shopify private app access token"
|
|
||||||
regex = '''shppa_[a-fA-F0-9]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "slack-access-token"
|
|
||||||
description = "Slack token"
|
|
||||||
regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})?'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "stripe-access-token"
|
|
||||||
description = "Stripe"
|
|
||||||
regex = '''(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "pypi-upload-token"
|
|
||||||
description = "PyPI upload token"
|
|
||||||
regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "gcp-service-account"
|
|
||||||
description = "Google (GCP) Service-account"
|
|
||||||
regex = '''\"type\": \"service_account\"'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "heroku-api-key"
|
|
||||||
description = "Heroku API Key"
|
|
||||||
regex = ''' (?i)(heroku[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "slack-web-hook"
|
|
||||||
description = "Slack Webhook"
|
|
||||||
regex = '''https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8,12}/[a-zA-Z0-9_]{24}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "twilio-api-key"
|
|
||||||
description = "Twilio API Key"
|
|
||||||
regex = '''SK[0-9a-fA-F]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "age-secret-key"
|
|
||||||
description = "Age secret key"
|
|
||||||
regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "facebook-token"
|
|
||||||
description = "Facebook token"
|
|
||||||
regex = '''(?i)(facebook[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "twitter-token"
|
|
||||||
description = "Twitter token"
|
|
||||||
regex = '''(?i)(twitter[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{35,44})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "adobe-client-id"
|
|
||||||
description = "Adobe Client ID (Oauth Web)"
|
|
||||||
regex = '''(?i)(adobe[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "adobe-client-secret"
|
|
||||||
description = "Adobe Client Secret"
|
|
||||||
regex = '''(p8e-)(?i)[a-z0-9]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "alibaba-access-key-id"
|
|
||||||
description = "Alibaba AccessKey ID"
|
|
||||||
regex = '''(LTAI)(?i)[a-z0-9]{20}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "alibaba-secret-key"
|
|
||||||
description = "Alibaba Secret Key"
|
|
||||||
regex = '''(?i)(alibaba[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{30})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "asana-client-id"
|
|
||||||
description = "Asana Client ID"
|
|
||||||
regex = '''(?i)(asana[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9]{16})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "asana-client-secret"
|
|
||||||
description = "Asana Client Secret"
|
|
||||||
regex = '''(?i)(asana[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "atlassian-api-token"
|
|
||||||
description = "Atlassian API token"
|
|
||||||
regex = '''(?i)(atlassian[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{24})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "bitbucket-client-id"
|
|
||||||
description = "Bitbucket client ID"
|
|
||||||
regex = '''(?i)(bitbucket[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "bitbucket-client-secret"
|
|
||||||
description = "Bitbucket client secret"
|
|
||||||
regex = '''(?i)(bitbucket[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9_\-]{64})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "beamer-api-token"
|
|
||||||
description = "Beamer API token"
|
|
||||||
regex = '''(?i)(beamer[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](b_[a-z0-9=_\-]{44})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "clojars-api-token"
|
|
||||||
description = "Clojars API token"
|
|
||||||
regex = '''(CLOJARS_)(?i)[a-z0-9]{60}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "contentful-delivery-api-token"
|
|
||||||
description = "Contentful delivery API token"
|
|
||||||
regex = '''(?i)(contentful[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9\-=_]{43})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "databricks-api-token"
|
|
||||||
description = "Databricks API token"
|
|
||||||
regex = '''dapi[a-h0-9]{32}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "discord-api-token"
|
|
||||||
description = "Discord API key"
|
|
||||||
regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{64})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "discord-client-id"
|
|
||||||
description = "Discord client ID"
|
|
||||||
regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9]{18})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "discord-client-secret"
|
|
||||||
description = "Discord client secret"
|
|
||||||
regex = '''(?i)(discord[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9=_\-]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "doppler-api-token"
|
|
||||||
description = "Doppler API token"
|
|
||||||
regex = '''['\"](dp\.pt\.)(?i)[a-z0-9]{43}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "dropbox-api-secret"
|
|
||||||
description = "Dropbox API secret/key"
|
|
||||||
regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{15})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "dropbox--api-key"
|
|
||||||
description = "Dropbox API secret/key"
|
|
||||||
regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{15})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "dropbox-short-lived-api-token"
|
|
||||||
description = "Dropbox short lived API token"
|
|
||||||
regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](sl\.[a-z0-9\-=_]{135})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "dropbox-long-lived-api-token"
|
|
||||||
description = "Dropbox long lived API token"
|
|
||||||
regex = '''(?i)(dropbox[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"][a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "duffel-api-token"
|
|
||||||
description = "Duffel API token"
|
|
||||||
regex = '''['\"]duffel_(test|live)_(?i)[a-z0-9_-]{43}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "dynatrace-api-token"
|
|
||||||
description = "Dynatrace API token"
|
|
||||||
regex = '''['\"]dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "easypost-api-token"
|
|
||||||
description = "EasyPost API token"
|
|
||||||
regex = '''['\"]EZAK(?i)[a-z0-9]{54}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "easypost-test-api-token"
|
|
||||||
description = "EasyPost test API token"
|
|
||||||
regex = '''['\"]EZTK(?i)[a-z0-9]{54}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "fastly-api-token"
|
|
||||||
description = "Fastly API token"
|
|
||||||
regex = '''(?i)(fastly[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9\-=_]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "finicity-client-secret"
|
|
||||||
description = "Finicity client secret"
|
|
||||||
regex = '''(?i)(finicity[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{20})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "finicity-api-token"
|
|
||||||
description = "Finicity API token"
|
|
||||||
regex = '''(?i)(finicity[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "flutterwave-public-key"
|
|
||||||
description = "Flutterwave public key"
|
|
||||||
regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "flutterwave-secret-key"
|
|
||||||
description = "Flutterwave secret key"
|
|
||||||
regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "flutterwave-enc-key"
|
|
||||||
description = "Flutterwave encrypted key"
|
|
||||||
regex = '''FLWSECK_TEST[a-h0-9]{12}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "frameio-api-token"
|
|
||||||
description = "Frame.io API token"
|
|
||||||
regex = '''fio-u-(?i)[a-z0-9\-_=]{64}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "gocardless-api-token"
|
|
||||||
description = "GoCardless API token"
|
|
||||||
regex = '''['\"]live_(?i)[a-z0-9\-_=]{40}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "grafana-api-token"
|
|
||||||
description = "Grafana API token"
|
|
||||||
regex = '''['\"]eyJrIjoi(?i)[a-z0-9\-_=]{72,92}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "hashicorp-tf-api-token"
|
|
||||||
description = "HashiCorp Terraform user/org API token"
|
|
||||||
regex = '''['\"](?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "hubspot-api-token"
|
|
||||||
description = "HubSpot API token"
|
|
||||||
regex = '''(?i)(hubspot[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "intercom-api-token"
|
|
||||||
description = "Intercom API token"
|
|
||||||
regex = '''(?i)(intercom[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9=_]{60})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "intercom-client-secret"
|
|
||||||
description = "Intercom client secret/ID"
|
|
||||||
regex = '''(?i)(intercom[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "ionic-api-token"
|
|
||||||
description = "Ionic API token"
|
|
||||||
regex = '''(?i)(ionic[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](ion_[a-z0-9]{42})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "linear-api-token"
|
|
||||||
description = "Linear API token"
|
|
||||||
regex = '''lin_api_(?i)[a-z0-9]{40}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "linear-client-secret"
|
|
||||||
description = "Linear client secret/ID"
|
|
||||||
regex = '''(?i)(linear[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "lob-api-key"
|
|
||||||
description = "Lob API Key"
|
|
||||||
regex = '''(?i)(lob[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]((live|test)_[a-f0-9]{35})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "lob-pub-api-key"
|
|
||||||
description = "Lob Publishable API Key"
|
|
||||||
regex = '''(?i)(lob[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]((test|live)_pub_[a-f0-9]{31})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "mailchimp-api-key"
|
|
||||||
description = "Mailchimp API key"
|
|
||||||
regex = '''(?i)(mailchimp[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32}-us20)['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "mailgun-private-api-token"
|
|
||||||
description = "Mailgun private API token"
|
|
||||||
regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](key-[a-f0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "mailgun-pub-key"
|
|
||||||
description = "Mailgun public validation key"
|
|
||||||
regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](pubkey-[a-f0-9]{32})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "mailgun-signing-key"
|
|
||||||
description = "Mailgun webhook signing key"
|
|
||||||
regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "mapbox-api-token"
|
|
||||||
description = "Mapbox API token"
|
|
||||||
regex = '''(?i)(pk\.[a-z0-9]{60}\.[a-z0-9]{22})'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "messagebird-api-token"
|
|
||||||
description = "MessageBird API token"
|
|
||||||
regex = '''(?i)(messagebird[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{25})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "messagebird-client-id"
|
|
||||||
description = "MessageBird API client ID"
|
|
||||||
regex = '''(?i)(messagebird[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{8}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{4}-[a-h0-9]{12})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "new-relic-user-api-key"
|
|
||||||
description = "New Relic user API Key"
|
|
||||||
regex = '''['\"](NRAK-[A-Z0-9]{27})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "new-relic-user-api-id"
|
|
||||||
description = "New Relic user API ID"
|
|
||||||
regex = '''(?i)(newrelic[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([A-Z0-9]{64})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "new-relic-browser-api-token"
|
|
||||||
description = "New Relic ingest browser API token"
|
|
||||||
regex = '''['\"](NRJS-[a-f0-9]{19})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "npm-access-token"
|
|
||||||
description = "npm access token"
|
|
||||||
regex = '''['\"](npm_(?i)[a-z0-9]{36})['\"]'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "planetscale-password"
|
|
||||||
description = "PlanetScale password"
|
|
||||||
regex = '''pscale_pw_(?i)[a-z0-9\-_\.]{43}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "planetscale-api-token"
|
|
||||||
description = "PlanetScale API token"
|
|
||||||
regex = '''pscale_tkn_(?i)[a-z0-9\-_\.]{43}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "postman-api-token"
|
|
||||||
description = "Postman API token"
|
|
||||||
regex = '''PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "pulumi-api-token"
|
|
||||||
description = "Pulumi API token"
|
|
||||||
regex = '''pul-[a-f0-9]{40}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "rubygems-api-token"
|
|
||||||
description = "Rubygem API token"
|
|
||||||
regex = '''rubygems_[a-f0-9]{48}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "sendgrid-api-token"
|
|
||||||
description = "SendGrid API token"
|
|
||||||
regex = '''SG\.(?i)[a-z0-9_\-\.]{66}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "sendinblue-api-token"
|
|
||||||
description = "Sendinblue API token"
|
|
||||||
regex = '''xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "shippo-api-token"
|
|
||||||
description = "Shippo API token"
|
|
||||||
regex = '''shippo_(live|test)_[a-f0-9]{40}'''
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "linkedin-client-secret"
|
|
||||||
description = "LinkedIn Client secret"
|
|
||||||
regex = '''(?i)(linkedin[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z]{16})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "linkedin-client-id"
|
|
||||||
description = "LinkedIn Client ID"
|
|
||||||
regex = '''(?i)(linkedin[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{14})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "twitch-api-token"
|
|
||||||
description = "Twitch API token"
|
|
||||||
regex = '''(?i)(twitch[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-z0-9]{30})['\"]'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "typeform-api-token"
|
|
||||||
description = "Typeform API token"
|
|
||||||
regex = '''(?i)(typeform[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}(tfp_[a-z0-9\-_\.=]{59})'''
|
|
||||||
secretGroup = 3
|
|
||||||
|
|
||||||
[[rules]]
|
|
||||||
id = "generic-api-key"
|
|
||||||
description = "Generic API Key"
|
|
||||||
regex = '''(?i)((key|api[^Version]|token|secret|password)[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([0-9a-zA-Z\-_=]{8,64})['\"]'''
|
|
||||||
entropy = 3.7
|
|
||||||
secretGroup = 4
|
|
||||||
|
|
||||||
|
|
||||||
[allowlist]
|
|
||||||
description = "global allow lists"
|
|
||||||
regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*''', '''.*:.*StrelkaHexDump.*''', '''.*:.*PLACEHOLDER.*''', '''ssl_.*password''', '''integration_key\s=\s"so-logs-"''']
|
|
||||||
paths = [
|
|
||||||
'''gitleaks.toml''',
|
|
||||||
'''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
|
|
||||||
'''(go.mod|go.sum)$''',
|
|
||||||
'''salt/nginx/files/enterprise-attack.json''',
|
|
||||||
'''(.*?)whl$'''
|
|
||||||
]
|
|
||||||
@@ -2,13 +2,11 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
⚠️ This category is solely for conversations related to Security Onion 2.4 ⚠️
|
|
||||||
|
|
||||||
If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support
|
If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
attributes:
|
attributes:
|
||||||
label: Version
|
label: Version
|
||||||
description: Which version of Security Onion 2.4.x are you asking about?
|
description: Which version of Security Onion are you asking about?
|
||||||
options:
|
options:
|
||||||
-
|
-
|
||||||
- 2.4.10
|
- 2.4.10
|
||||||
@@ -33,6 +31,9 @@ body:
|
|||||||
- 2.4.180
|
- 2.4.180
|
||||||
- 2.4.190
|
- 2.4.190
|
||||||
- 2.4.200
|
- 2.4.200
|
||||||
|
- 2.4.201
|
||||||
|
- 2.4.210
|
||||||
|
- 2.4.211
|
||||||
- Other (please provide detail below)
|
- Other (please provide detail below)
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@@ -94,7 +95,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Hardware Specs
|
label: Hardware Specs
|
||||||
description: >
|
description: >
|
||||||
Does your hardware meet or exceed the minimum requirements for your installation type as shown at https://docs.securityonion.net/en/2.4/hardware.html?
|
Does your hardware meet or exceed the minimum requirements for your installation type as shown at https://securityonion.net/docs/hardware?
|
||||||
options:
|
options:
|
||||||
-
|
-
|
||||||
- Meets minimum requirements
|
- Meets minimum requirements
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: Which version of Security Onion are you asking about?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- 3.0.0
|
||||||
|
- 3.1.0
|
||||||
|
- 3.2.0
|
||||||
|
- Other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Installation Method
|
||||||
|
description: How did you install Security Onion?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Security Onion ISO image
|
||||||
|
- Cloud image (Amazon, Azure, Google)
|
||||||
|
- Network installation on Oracle 9 (unsupported)
|
||||||
|
- Other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: >
|
||||||
|
Is this discussion about installation, configuration, upgrading, or other?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- installation
|
||||||
|
- configuration
|
||||||
|
- upgrading
|
||||||
|
- other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Installation Type
|
||||||
|
description: >
|
||||||
|
When you installed, did you choose Import, Eval, Standalone, Distributed, or something else?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Import
|
||||||
|
- Eval
|
||||||
|
- Standalone
|
||||||
|
- Distributed
|
||||||
|
- other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Location
|
||||||
|
description: >
|
||||||
|
Is this deployment in the cloud, on-prem with Internet access, or airgap?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- cloud
|
||||||
|
- on-prem with Internet access
|
||||||
|
- airgap
|
||||||
|
- other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Hardware Specs
|
||||||
|
description: >
|
||||||
|
Does your hardware meet or exceed the minimum requirements for your installation type as shown at https://securityonion.net/docs/hardware?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Meets minimum requirements
|
||||||
|
- Exceeds minimum requirements
|
||||||
|
- Does not meet minimum requirements
|
||||||
|
- other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: CPU
|
||||||
|
description: How many CPU cores do you have?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: RAM
|
||||||
|
description: How much RAM do you have?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Storage for /
|
||||||
|
description: How much storage do you have for the / partition?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Storage for /nsm
|
||||||
|
description: How much storage do you have for the /nsm partition?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Network Traffic Collection
|
||||||
|
description: >
|
||||||
|
Are you collecting network traffic from a tap or span port?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- tap
|
||||||
|
- span port
|
||||||
|
- other (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Network Traffic Speeds
|
||||||
|
description: >
|
||||||
|
How much network traffic are you monitoring?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Less than 1Gbps
|
||||||
|
- 1Gbps to 10Gbps
|
||||||
|
- more than 10Gbps
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Status
|
||||||
|
description: >
|
||||||
|
Does SOC Grid show all services on all nodes as running OK?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Yes, all services on all nodes are running OK
|
||||||
|
- No, one or more services are failed (please provide detail below)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Salt Status
|
||||||
|
description: >
|
||||||
|
Do you get any failures when you run "sudo salt-call state.highstate"?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Yes, there are salt failures (please provide detail below)
|
||||||
|
- No, there are no failures
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
attributes:
|
||||||
|
label: Logs
|
||||||
|
description: >
|
||||||
|
Are there any additional clues in /opt/so/log/?
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
- Yes, there are additional clues in /opt/so/log/ (please provide detail below)
|
||||||
|
- No, there are no additional clues
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Detail
|
||||||
|
description: Please read our discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 and then provide detailed information to help us help you.
|
||||||
|
placeholder: |-
|
||||||
|
STOP! Before typing, please read our discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 in their entirety!
|
||||||
|
|
||||||
|
If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Guidelines
|
||||||
|
options:
|
||||||
|
- label: I have read the discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 and assert that I have followed the guidelines.
|
||||||
|
required: true
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Explain the purpose of the pull request. Be brief or detailed depending on the scope of the changes.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Related Issues
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Optionally, list any related issues that this pull request addresses.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ] I have read and followed the [CONTRIBUTING.md](https://github.com/Security-Onion-Solutions/securityonion/blob/3/main/CONTRIBUTING.md) file.
|
||||||
|
- [ ] I have read and agree to the terms of the [Contributor License Agreement](https://securityonionsolutions.com/cla)
|
||||||
|
|
||||||
|
## Questions or Comments
|
||||||
|
|
||||||
|
<!--
|
||||||
|
If you have any questions or comments about this pull request, add them here.
|
||||||
|
-->
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
name: contrib
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
pull_request_target:
|
|
||||||
types: [opened,closed,synchronize]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
CLAssistant:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: "Contributor Check"
|
|
||||||
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
|
||||||
uses: cla-assistant/github-action@v2.3.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
|
||||||
with:
|
|
||||||
path-to-signatures: 'signatures_v1.json'
|
|
||||||
path-to-document: 'https://securityonionsolutions.com/cla'
|
|
||||||
allowlist: dependabot[bot],jertel,dougburks,TOoSmOotH,defensivedepth,m0duspwnens
|
|
||||||
remote-organization-name: Security-Onion-Solutions
|
|
||||||
remote-repository-name: licensing
|
|
||||||
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
name: leak-test
|
|
||||||
|
|
||||||
on: [pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: '0'
|
|
||||||
|
|
||||||
- name: Gitleaks
|
|
||||||
uses: gitleaks/gitleaks-action@v1.6.0
|
|
||||||
with:
|
|
||||||
config-path: .github/.gitleaks.toml
|
|
||||||
@@ -5,6 +5,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- "salt/sensoroni/files/analyzers/**"
|
- "salt/sensoroni/files/analyzers/**"
|
||||||
- "salt/manager/tools/sbin/**"
|
- "salt/manager/tools/sbin/**"
|
||||||
|
- "salt/_beacons/**"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -13,8 +14,8 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.13"]
|
python-version: ["3.14"]
|
||||||
python-code-path: ["salt/sensoroni/files/analyzers", "salt/manager/tools/sbin"]
|
python-code-path: ["salt/sensoroni/files/analyzers", "salt/manager/tools/sbin", "salt/_beacons"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
* Link the PR to the related issue, either using [keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in the PR description, or [manually](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-issues/linking-a-pull-request-to-an-issue#manually-linking-a-pull-request-to-an-issue).
|
* Link the PR to the related issue, either using [keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in the PR description, or [manually](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-issues/linking-a-pull-request-to-an-issue#manually-linking-a-pull-request-to-an-issue).
|
||||||
|
|
||||||
* **Pull requests should be opened against the `dev` branch of this repo**, and should clearly describe the problem and solution.
|
* **Pull requests should be opened against the current `?/dev` branch of this repo**, and should clearly describe the problem and solution.
|
||||||
|
|
||||||
* Be sure you have tested your changes and are confident they will not break other parts of the product.
|
* Be sure you have tested your changes and are confident they will not break other parts of the product.
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -1,46 +1,46 @@
|
|||||||
### 2.4.190-20251024 ISO image released on 2025/10/24
|
### 3.1.0-20260528 ISO image released on 2026/05/28
|
||||||
|
|
||||||
|
|
||||||
### Download and Verify
|
### Download and Verify
|
||||||
|
|
||||||
2.4.190-20251024 ISO image:
|
3.1.0-20260528 ISO image:
|
||||||
https://download.securityonion.net/file/securityonion/securityonion-2.4.190-20251024.iso
|
https://download.securityonion.net/file/securityonion/securityonion-3.1.0-20260528.iso
|
||||||
|
|
||||||
MD5: 25358481FB876226499C011FC0710358
|
MD5: 9D6FF58DEEE24089D722C73169765B3E
|
||||||
SHA1: 0B26173C0CE136F2CA40A15046D1DFB78BCA1165
|
SHA1: 2B8B816B6CEC3B7F96B3C5E040EBF502DD2C412F
|
||||||
SHA256: 4FD9F62EDA672408828B3C0C446FE5EA9FF3C4EE8488A7AB1101544A3C487872
|
SHA256: 62FAB57E247C843D6A04F0796D8162C732B65D82FC3E4A59D087135B9FD32912
|
||||||
|
|
||||||
Signature for ISO image:
|
Signature for ISO image:
|
||||||
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.190-20251024.iso.sig
|
https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.1.0-20260528.iso.sig
|
||||||
|
|
||||||
Signing key:
|
Signing key:
|
||||||
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS
|
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/main/KEYS
|
||||||
|
|
||||||
For example, here are the steps you can use on most Linux distributions to download and verify our Security Onion ISO image.
|
For example, here are the steps you can use on most Linux distributions to download and verify our Security Onion ISO image.
|
||||||
|
|
||||||
Download and import the signing key:
|
Download and import the signing key:
|
||||||
```
|
```
|
||||||
wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS -O - | gpg --import -
|
wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/3/main/KEYS -O - | gpg --import -
|
||||||
```
|
```
|
||||||
|
|
||||||
Download the signature file for the ISO:
|
Download the signature file for the ISO:
|
||||||
```
|
```
|
||||||
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.190-20251024.iso.sig
|
wget https://github.com/Security-Onion-Solutions/securityonion/raw/3/main/sigs/securityonion-3.1.0-20260528.iso.sig
|
||||||
```
|
```
|
||||||
|
|
||||||
Download the ISO image:
|
Download the ISO image:
|
||||||
```
|
```
|
||||||
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.190-20251024.iso
|
wget https://download.securityonion.net/file/securityonion/securityonion-3.1.0-20260528.iso
|
||||||
```
|
```
|
||||||
|
|
||||||
Verify the downloaded ISO image using the signature file:
|
Verify the downloaded ISO image using the signature file:
|
||||||
```
|
```
|
||||||
gpg --verify securityonion-2.4.190-20251024.iso.sig securityonion-2.4.190-20251024.iso
|
gpg --verify securityonion-3.1.0-20260528.iso.sig securityonion-3.1.0-20260528.iso
|
||||||
```
|
```
|
||||||
|
|
||||||
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
|
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
|
||||||
```
|
```
|
||||||
gpg: Signature made Thu 23 Oct 2025 07:21:46 AM EDT using RSA key ID FE507013
|
gpg: Signature made Wed 27 May 2026 03:03:59 PM EDT using RSA key ID FE507013
|
||||||
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
|
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
|
||||||
gpg: WARNING: This key is not certified with a trusted signature!
|
gpg: WARNING: This key is not certified with a trusted signature!
|
||||||
gpg: There is no indication that the signature belongs to the owner.
|
gpg: There is no indication that the signature belongs to the owner.
|
||||||
@@ -50,4 +50,4 @@ Primary key fingerprint: C804 A93D 36BE 0C73 3EA1 9644 7C10 60B7 FE50 7013
|
|||||||
If it fails to verify, try downloading again. If it still fails to verify, try downloading from another computer or another network.
|
If it fails to verify, try downloading again. If it still fails to verify, try downloading from another computer or another network.
|
||||||
|
|
||||||
Once you've verified the ISO image, you're ready to proceed to our Installation guide:
|
Once you've verified the ISO image, you're ready to proceed to our Installation guide:
|
||||||
https://docs.securityonion.net/en/2.4/installation.html
|
https://securityonion.net/docs/installation
|
||||||
|
|||||||
@@ -1,50 +1,58 @@
|
|||||||
## Security Onion 2.4
|
<p align="center">
|
||||||
|
<img src="https://securityonionsolutions.com/logo/logo-so-onion-dark.svg" width="400" alt="Security Onion Logo">
|
||||||
|
</p>
|
||||||
|
|
||||||
Security Onion 2.4 is here!
|
# Security Onion
|
||||||
|
|
||||||
## Screenshots
|
Security Onion is a free and open Linux distribution for threat hunting, enterprise security monitoring, and log management. It includes a comprehensive suite of tools designed to work together to provide visibility into your network and host activity.
|
||||||
|
|
||||||
Alerts
|
## ✨ Features
|
||||||

|
|
||||||
|
|
||||||
Dashboards
|
Security Onion includes everything you need to monitor your network and host systems:
|
||||||

|
|
||||||
|
|
||||||
Hunt
|
* **Security Onion Console (SOC)**: A unified web interface for analyzing security events and managing your grid.
|
||||||

|
* **Elastic Stack**: Powerful search backed by Elasticsearch.
|
||||||
|
* **Intrusion Detection**: Network-based IDS with Suricata and host-based monitoring with Elastic Fleet.
|
||||||
|
* **Network Metadata**: Detailed network metadata generated by Zeek or Suricata.
|
||||||
|
* **Full Packet Capture**: Retain and analyze raw network traffic with Suricata PCAP.
|
||||||
|
|
||||||
Detections
|
## ⭐ Security Onion Pro
|
||||||

|
|
||||||
|
|
||||||
PCAP
|
For organizations and enterprises requiring advanced capabilities, **Security Onion Pro** offers additional features designed for scale and efficiency:
|
||||||

|
|
||||||
|
|
||||||
Grid
|
* **Onion AI**: Leverage powerful AI-driven insights to accelerate your analysis and investigations.
|
||||||

|
* **Enterprise Features**: Enhanced tools and integrations tailored for enterprise-grade security operations.
|
||||||
|
|
||||||
Config
|
For more information, visit the [Security Onion Pro](https://securityonionsolutions.com/pro) page.
|
||||||

|
|
||||||
|
|
||||||
### Release Notes
|
## ☁️ Cloud Deployment
|
||||||
|
|
||||||
https://docs.securityonion.net/en/2.4/release-notes.html
|
Security Onion is available and ready to deploy in the **AWS**, **Azure**, and **Google Cloud (GCP)** marketplaces.
|
||||||
|
|
||||||
### Requirements
|
## 🚀 Getting Started
|
||||||
|
|
||||||
https://docs.securityonion.net/en/2.4/hardware.html
|
| Goal | Resource |
|
||||||
|
| :--- | :--- |
|
||||||
|
| **Download** | [Security Onion ISO](https://securityonion.net/docs/download) |
|
||||||
|
| **Requirements** | [Hardware Guide](https://securityonion.net/docs/hardware) |
|
||||||
|
| **Install** | [Installation Instructions](https://securityonion.net/docs/installation) |
|
||||||
|
| **What's New** | [Release Notes](https://securityonion.net/docs/release-notes) |
|
||||||
|
|
||||||
### Download
|
## 📖 Documentation & Support
|
||||||
|
|
||||||
https://docs.securityonion.net/en/2.4/download.html
|
For more detailed information, please visit our [Documentation](https://docs.securityonion.net).
|
||||||
|
|
||||||
### Installation
|
* **FAQ**: [Frequently Asked Questions](https://securityonion.net/docs/faq)
|
||||||
|
* **Community**: [Discussions & Support](https://securityonion.net/docs/community-support)
|
||||||
|
* **Training**: [Official Training](https://securityonion.net/training)
|
||||||
|
|
||||||
https://docs.securityonion.net/en/2.4/installation.html
|
## 🤝 Contributing
|
||||||
|
|
||||||
### FAQ
|
We welcome contributions! Please see our [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to get involved.
|
||||||
|
|
||||||
https://docs.securityonion.net/en/2.4/faq.html
|
## 🛡️ License
|
||||||
|
|
||||||
### Feedback
|
Security Onion is licensed under the terms of the license found in the [LICENSE](LICENSE) file.
|
||||||
|
|
||||||
https://docs.securityonion.net/en/2.4/community-support.html
|
---
|
||||||
|
*Built with 🧅 by Security Onion Solutions.*
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | ------------------ |
|
| ------- | ------------------ |
|
||||||
|
| 3.x | :white_check_mark: |
|
||||||
| 2.4.x | :white_check_mark: |
|
| 2.4.x | :white_check_mark: |
|
||||||
| 2.3.x | :x: |
|
| 2.3.x | :x: |
|
||||||
| 16.04.x | :x: |
|
| 16.04.x | :x: |
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ca:
|
||||||
|
server:
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# This script adds sensors/nodes/etc to the nodes tab
|
|
||||||
default_salt_dir=/opt/so/saltstack/default
|
|
||||||
local_salt_dir=/opt/so/saltstack/local
|
|
||||||
TYPE=$1
|
|
||||||
NAME=$2
|
|
||||||
IPADDRESS=$3
|
|
||||||
CPUS=$4
|
|
||||||
GUID=$5
|
|
||||||
MANINT=$6
|
|
||||||
ROOTFS=$7
|
|
||||||
NSM=$8
|
|
||||||
MONINT=$9
|
|
||||||
#NODETYPE=$10
|
|
||||||
#HOTNAME=$11
|
|
||||||
|
|
||||||
echo "Seeing if this host is already in here. If so delete it"
|
|
||||||
if grep -q $NAME "$local_salt_dir/pillar/data/$TYPE.sls"; then
|
|
||||||
echo "Node Already Present - Let's re-add it"
|
|
||||||
awk -v blah=" $NAME:" 'BEGIN{ print_flag=1 }
|
|
||||||
{
|
|
||||||
if( $0 ~ blah )
|
|
||||||
{
|
|
||||||
print_flag=0;
|
|
||||||
next
|
|
||||||
}
|
|
||||||
if( $0 ~ /^ [a-zA-Z0-9]+:$/ )
|
|
||||||
{
|
|
||||||
print_flag=1;
|
|
||||||
}
|
|
||||||
if ( print_flag == 1 )
|
|
||||||
print $0
|
|
||||||
|
|
||||||
} ' $local_salt_dir/pillar/data/$TYPE.sls > $local_salt_dir/pillar/data/tmp.$TYPE.sls
|
|
||||||
mv $local_salt_dir/pillar/data/tmp.$TYPE.sls $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo "Deleted $NAME from the tab. Now adding it in again with updated info"
|
|
||||||
fi
|
|
||||||
echo " $NAME:" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo " ip: $IPADDRESS" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo " manint: $MANINT" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo " totalcpus: $CPUS" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo " guid: $GUID" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo " rootfs: $ROOTFS" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
echo " nsmfs: $NSM" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
if [ $TYPE == 'sensorstab' ]; then
|
|
||||||
echo " monint: bond0" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
fi
|
|
||||||
if [ $TYPE == 'evaltab' ] || [ $TYPE == 'standalonetab' ]; then
|
|
||||||
echo " monint: bond0" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
if [ ! $10 ]; then
|
|
||||||
salt-call state.apply utility queue=True
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ $TYPE == 'nodestab' ]; then
|
|
||||||
salt-call state.apply elasticsearch queue=True
|
|
||||||
# echo " nodetype: $NODETYPE" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
# echo " hotname: $HOTNAME" >> $local_salt_dir/pillar/data/$TYPE.sls
|
|
||||||
fi
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
elasticsearch:
|
|
||||||
index_settings:
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
# Per-minion Telegraf Postgres credentials. so-telegraf-cred on the manager is
|
||||||
|
# the single writer; it mutates /opt/so/saltstack/local/pillar/telegraf/creds.sls
|
||||||
|
# under flock. Pillar_roots order (local before default) means the populated
|
||||||
|
# copy shadows this default on any real grid; this file exists so the pillar
|
||||||
|
# key is always defined on fresh installs and when no minions have creds yet.
|
||||||
|
telegraf:
|
||||||
|
postgres_creds: {}
|
||||||
+24
-13
@@ -1,7 +1,10 @@
|
|||||||
base:
|
base:
|
||||||
'*':
|
'*':
|
||||||
|
- ca
|
||||||
- global.soc_global
|
- global.soc_global
|
||||||
- global.adv_global
|
- global.adv_global
|
||||||
|
- salt.soc_salt
|
||||||
|
- salt.adv_salt
|
||||||
- docker.soc_docker
|
- docker.soc_docker
|
||||||
- docker.adv_docker
|
- docker.adv_docker
|
||||||
- influxdb.token
|
- influxdb.token
|
||||||
@@ -16,6 +19,7 @@ base:
|
|||||||
- sensoroni.adv_sensoroni
|
- sensoroni.adv_sensoroni
|
||||||
- telegraf.soc_telegraf
|
- telegraf.soc_telegraf
|
||||||
- telegraf.adv_telegraf
|
- telegraf.adv_telegraf
|
||||||
|
- telegraf.creds
|
||||||
- versionlock.soc_versionlock
|
- versionlock.soc_versionlock
|
||||||
- versionlock.adv_versionlock
|
- versionlock.adv_versionlock
|
||||||
- soc.license
|
- soc.license
|
||||||
@@ -37,6 +41,9 @@ base:
|
|||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||||
- elasticsearch.auth
|
- elasticsearch.auth
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/postgres/auth.sls') %}
|
||||||
|
- postgres.auth
|
||||||
|
{% endif %}
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||||
- kibana.secrets
|
- kibana.secrets
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -59,6 +66,8 @@ base:
|
|||||||
- redis.adv_redis
|
- redis.adv_redis
|
||||||
- influxdb.soc_influxdb
|
- influxdb.soc_influxdb
|
||||||
- influxdb.adv_influxdb
|
- influxdb.adv_influxdb
|
||||||
|
- postgres.soc_postgres
|
||||||
|
- postgres.adv_postgres
|
||||||
- elasticsearch.nodes
|
- elasticsearch.nodes
|
||||||
- elasticsearch.soc_elasticsearch
|
- elasticsearch.soc_elasticsearch
|
||||||
- elasticsearch.adv_elasticsearch
|
- elasticsearch.adv_elasticsearch
|
||||||
@@ -86,8 +95,6 @@ base:
|
|||||||
- zeek.adv_zeek
|
- zeek.adv_zeek
|
||||||
- bpf.soc_bpf
|
- bpf.soc_bpf
|
||||||
- bpf.adv_bpf
|
- bpf.adv_bpf
|
||||||
- pcap.soc_pcap
|
|
||||||
- pcap.adv_pcap
|
|
||||||
- suricata.soc_suricata
|
- suricata.soc_suricata
|
||||||
- suricata.adv_suricata
|
- suricata.adv_suricata
|
||||||
- minions.{{ grains.id }}
|
- minions.{{ grains.id }}
|
||||||
@@ -98,10 +105,12 @@ base:
|
|||||||
- node_data.ips
|
- node_data.ips
|
||||||
- secrets
|
- secrets
|
||||||
- healthcheck.eval
|
- healthcheck.eval
|
||||||
- elasticsearch.index_templates
|
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||||
- elasticsearch.auth
|
- elasticsearch.auth
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/postgres/auth.sls') %}
|
||||||
|
- postgres.auth
|
||||||
|
{% endif %}
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||||
- kibana.secrets
|
- kibana.secrets
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -127,14 +136,14 @@ base:
|
|||||||
- redis.adv_redis
|
- redis.adv_redis
|
||||||
- influxdb.soc_influxdb
|
- influxdb.soc_influxdb
|
||||||
- influxdb.adv_influxdb
|
- influxdb.adv_influxdb
|
||||||
|
- postgres.soc_postgres
|
||||||
|
- postgres.adv_postgres
|
||||||
- backup.soc_backup
|
- backup.soc_backup
|
||||||
- backup.adv_backup
|
- backup.adv_backup
|
||||||
- zeek.soc_zeek
|
- zeek.soc_zeek
|
||||||
- zeek.adv_zeek
|
- zeek.adv_zeek
|
||||||
- bpf.soc_bpf
|
- bpf.soc_bpf
|
||||||
- bpf.adv_bpf
|
- bpf.adv_bpf
|
||||||
- pcap.soc_pcap
|
|
||||||
- pcap.adv_pcap
|
|
||||||
- suricata.soc_suricata
|
- suricata.soc_suricata
|
||||||
- suricata.adv_suricata
|
- suricata.adv_suricata
|
||||||
- minions.{{ grains.id }}
|
- minions.{{ grains.id }}
|
||||||
@@ -145,10 +154,12 @@ base:
|
|||||||
- logstash.nodes
|
- logstash.nodes
|
||||||
- logstash.soc_logstash
|
- logstash.soc_logstash
|
||||||
- logstash.adv_logstash
|
- logstash.adv_logstash
|
||||||
- elasticsearch.index_templates
|
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||||
- elasticsearch.auth
|
- elasticsearch.auth
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/postgres/auth.sls') %}
|
||||||
|
- postgres.auth
|
||||||
|
{% endif %}
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||||
- kibana.secrets
|
- kibana.secrets
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -163,6 +174,8 @@ base:
|
|||||||
- redis.adv_redis
|
- redis.adv_redis
|
||||||
- influxdb.soc_influxdb
|
- influxdb.soc_influxdb
|
||||||
- influxdb.adv_influxdb
|
- influxdb.adv_influxdb
|
||||||
|
- postgres.soc_postgres
|
||||||
|
- postgres.adv_postgres
|
||||||
- elasticsearch.nodes
|
- elasticsearch.nodes
|
||||||
- elasticsearch.soc_elasticsearch
|
- elasticsearch.soc_elasticsearch
|
||||||
- elasticsearch.adv_elasticsearch
|
- elasticsearch.adv_elasticsearch
|
||||||
@@ -184,8 +197,6 @@ base:
|
|||||||
- zeek.adv_zeek
|
- zeek.adv_zeek
|
||||||
- bpf.soc_bpf
|
- bpf.soc_bpf
|
||||||
- bpf.adv_bpf
|
- bpf.adv_bpf
|
||||||
- pcap.soc_pcap
|
|
||||||
- pcap.adv_pcap
|
|
||||||
- suricata.soc_suricata
|
- suricata.soc_suricata
|
||||||
- suricata.adv_suricata
|
- suricata.adv_suricata
|
||||||
- minions.{{ grains.id }}
|
- minions.{{ grains.id }}
|
||||||
@@ -208,8 +219,6 @@ base:
|
|||||||
- zeek.adv_zeek
|
- zeek.adv_zeek
|
||||||
- bpf.soc_bpf
|
- bpf.soc_bpf
|
||||||
- bpf.adv_bpf
|
- bpf.adv_bpf
|
||||||
- pcap.soc_pcap
|
|
||||||
- pcap.adv_pcap
|
|
||||||
- suricata.soc_suricata
|
- suricata.soc_suricata
|
||||||
- suricata.adv_suricata
|
- suricata.adv_suricata
|
||||||
- strelka.soc_strelka
|
- strelka.soc_strelka
|
||||||
@@ -263,10 +272,12 @@ base:
|
|||||||
'*_import':
|
'*_import':
|
||||||
- node_data.ips
|
- node_data.ips
|
||||||
- secrets
|
- secrets
|
||||||
- elasticsearch.index_templates
|
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||||
- elasticsearch.auth
|
- elasticsearch.auth
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/postgres/auth.sls') %}
|
||||||
|
- postgres.auth
|
||||||
|
{% endif %}
|
||||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||||
- kibana.secrets
|
- kibana.secrets
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -292,12 +303,12 @@ base:
|
|||||||
- redis.adv_redis
|
- redis.adv_redis
|
||||||
- influxdb.soc_influxdb
|
- influxdb.soc_influxdb
|
||||||
- influxdb.adv_influxdb
|
- influxdb.adv_influxdb
|
||||||
|
- postgres.soc_postgres
|
||||||
|
- postgres.adv_postgres
|
||||||
- zeek.soc_zeek
|
- zeek.soc_zeek
|
||||||
- zeek.adv_zeek
|
- zeek.adv_zeek
|
||||||
- bpf.soc_bpf
|
- bpf.soc_bpf
|
||||||
- bpf.adv_bpf
|
- bpf.adv_bpf
|
||||||
- pcap.soc_pcap
|
|
||||||
- pcap.adv_pcap
|
|
||||||
- suricata.soc_suricata
|
- suricata.soc_suricata
|
||||||
- suricata.adv_suricata
|
- suricata.adv_suricata
|
||||||
- strelka.soc_strelka
|
- strelka.soc_strelka
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
# Custom salt beacon that watches the SOC audit_settings table in postgres for
|
||||||
|
# new settings changes and emits a beacon event per new row. This replaces the
|
||||||
|
# inotify watch on /opt/so/saltstack/local/pillar -- instead of monitoring pillar
|
||||||
|
# files on disk, we monitor the securityonion.audit_settings table that SOC writes to.
|
||||||
|
#
|
||||||
|
# Detection is poll-based with a monotonic `id` watermark persisted to
|
||||||
|
# WATERMARK_FILE: each pass selects rows with id greater than the last id seen,
|
||||||
|
# which makes it self-healing (a missed poll simply catches up on the next one).
|
||||||
|
#
|
||||||
|
# Each emitted event carries setting_id and node_id; the push_pillar reactor maps
|
||||||
|
# setting_id -> app via pillar_push_map.yaml and writes a push intent, after which
|
||||||
|
# the existing so-push-drainer / orch.push_batch pipeline takes over unchanged.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
WATERMARK_FILE = '/opt/so/state/postgres_pillar_beacon_watch.id'
|
||||||
|
CONTAINER = 'so-postgres'
|
||||||
|
DATABASE = 'securityonion'
|
||||||
|
|
||||||
|
# Unaligned, tuples-only psql output with a field separator that cannot appear in
|
||||||
|
# an id/setting_id/node_id, so we can split each row reliably.
|
||||||
|
FIELD_SEP = '\x1f'
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def validate(config):
|
||||||
|
return True, 'valid'
|
||||||
|
|
||||||
|
|
||||||
|
def _read_watermark():
|
||||||
|
# Returns the last processed id, or None if the watermark has not been seeded.
|
||||||
|
try:
|
||||||
|
with open(WATERMARK_FILE, 'r') as f:
|
||||||
|
return int((f.read() or '').strip())
|
||||||
|
except (IOError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _write_watermark(value):
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.dirname(WATERMARK_FILE), exist_ok=True)
|
||||||
|
tmp = WATERMARK_FILE + '.tmp'
|
||||||
|
with open(tmp, 'w') as f:
|
||||||
|
f.write(str(int(value)))
|
||||||
|
os.rename(tmp, WATERMARK_FILE)
|
||||||
|
except OSError:
|
||||||
|
log.exception('postgres_pillar_beacon: failed to persist watermark to %s', WATERMARK_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
def _query(sql):
|
||||||
|
# Run a query against securityonion inside the so-postgres container over the unix
|
||||||
|
# socket (trust auth, no password). Returns stdout on success, or None on any
|
||||||
|
# failure so the caller can no-op and retry on the next interval.
|
||||||
|
cmd = [
|
||||||
|
'docker', 'exec', CONTAINER,
|
||||||
|
'psql', '-U', 'postgres', '-d', DATABASE,
|
||||||
|
'-tA', '-F', FIELD_SEP, '-c', sql,
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
log.warning('postgres_pillar_beacon: psql timed out')
|
||||||
|
return None
|
||||||
|
except Exception:
|
||||||
|
log.exception('postgres_pillar_beacon: failed to exec psql')
|
||||||
|
return None
|
||||||
|
if result.returncode != 0:
|
||||||
|
log.warning('postgres_pillar_beacon: psql failed (rc=%s): %s',
|
||||||
|
result.returncode, (result.stderr or '').strip())
|
||||||
|
return None
|
||||||
|
return result.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def beacon(config): # noqa: C901
|
||||||
|
retval = []
|
||||||
|
|
||||||
|
watermark = _read_watermark()
|
||||||
|
|
||||||
|
# First run / missing watermark: seed to the current MAX(id) and emit nothing
|
||||||
|
# so we never replay the entire settings history into a fleetwide push.
|
||||||
|
if watermark is None:
|
||||||
|
seed = _query('SELECT COALESCE(MAX(id), 0) FROM audit_settings;')
|
||||||
|
if seed is None:
|
||||||
|
return retval # postgres not ready yet; retry next interval
|
||||||
|
try:
|
||||||
|
_write_watermark(int((seed or '0').strip() or 0))
|
||||||
|
except ValueError:
|
||||||
|
log.warning('postgres_pillar_beacon: could not parse MAX(id) seed: %r', seed)
|
||||||
|
return retval
|
||||||
|
|
||||||
|
rows = _query(
|
||||||
|
"SELECT id, setting_id, COALESCE(node_id, '') FROM audit_settings "
|
||||||
|
"WHERE id > %d ORDER BY id;" % watermark
|
||||||
|
)
|
||||||
|
if rows is None:
|
||||||
|
return retval
|
||||||
|
|
||||||
|
max_id = watermark
|
||||||
|
for line in rows.splitlines():
|
||||||
|
# Do NOT str.strip() the whole line: Python treats the \x1f field
|
||||||
|
# separator (and \x1c-\x1e) as whitespace, so stripping would eat an
|
||||||
|
# empty trailing node_id field and make the row look malformed.
|
||||||
|
if not line.strip():
|
||||||
|
continue
|
||||||
|
parts = line.split(FIELD_SEP)
|
||||||
|
if len(parts) < 3:
|
||||||
|
log.warning('postgres_pillar_beacon: skipping malformed row: %r', line)
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
row_id = int(parts[0])
|
||||||
|
except ValueError:
|
||||||
|
log.warning('postgres_pillar_beacon: skipping row with non-int id: %r', line)
|
||||||
|
continue
|
||||||
|
setting_id = parts[1]
|
||||||
|
node_id = parts[2]
|
||||||
|
retval.append({
|
||||||
|
'tag': 'audit_settings',
|
||||||
|
'id': row_id,
|
||||||
|
'setting_id': setting_id,
|
||||||
|
'node_id': node_id,
|
||||||
|
})
|
||||||
|
if row_id > max_id:
|
||||||
|
max_id = row_id
|
||||||
|
|
||||||
|
if max_id > watermark:
|
||||||
|
_write_watermark(max_id)
|
||||||
|
log.info('postgres_pillar_beacon: emitted %d change(s), watermark %d -> %d',
|
||||||
|
len(retval), watermark, max_id)
|
||||||
|
|
||||||
|
return retval
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import postgres_pillar_beacon
|
||||||
|
|
||||||
|
|
||||||
|
class TestPostgresPillarBeacon(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Point WATERMARK_FILE at a throwaway dir so the real read/write helpers
|
||||||
|
# (and their os.makedirs/os.rename) run against actual files, then clean
|
||||||
|
# it all up in tearDown.
|
||||||
|
self.tmpdir = tempfile.mkdtemp()
|
||||||
|
self.watermark = os.path.join(self.tmpdir, 'state', 'watch.id')
|
||||||
|
patcher = patch.object(postgres_pillar_beacon, 'WATERMARK_FILE', self.watermark)
|
||||||
|
patcher.start()
|
||||||
|
self.addCleanup(patcher.stop)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
||||||
|
|
||||||
|
# -- trivial contract -------------------------------------------------
|
||||||
|
|
||||||
|
def test_virtual_returns_true(self):
|
||||||
|
self.assertTrue(postgres_pillar_beacon.__virtual__())
|
||||||
|
|
||||||
|
def test_validate_returns_valid(self):
|
||||||
|
self.assertEqual(postgres_pillar_beacon.validate({}), (True, 'valid'))
|
||||||
|
|
||||||
|
# -- _read_watermark --------------------------------------------------
|
||||||
|
|
||||||
|
def test_read_watermark_valid(self):
|
||||||
|
postgres_pillar_beacon._write_watermark(42)
|
||||||
|
self.assertEqual(postgres_pillar_beacon._read_watermark(), 42)
|
||||||
|
|
||||||
|
def test_read_watermark_missing_file_returns_none(self):
|
||||||
|
# tmp watermark file was never created
|
||||||
|
self.assertIsNone(postgres_pillar_beacon._read_watermark())
|
||||||
|
|
||||||
|
def test_read_watermark_garbage_returns_none(self):
|
||||||
|
os.makedirs(os.path.dirname(self.watermark), exist_ok=True)
|
||||||
|
with open(self.watermark, 'w') as f:
|
||||||
|
f.write('nope')
|
||||||
|
self.assertIsNone(postgres_pillar_beacon._read_watermark())
|
||||||
|
|
||||||
|
# -- _write_watermark -------------------------------------------------
|
||||||
|
|
||||||
|
def test_write_watermark_round_trip(self):
|
||||||
|
postgres_pillar_beacon._write_watermark(7)
|
||||||
|
with open(self.watermark) as f:
|
||||||
|
self.assertEqual(f.read(), '7')
|
||||||
|
|
||||||
|
def test_write_watermark_swallows_oserror(self):
|
||||||
|
with patch.object(postgres_pillar_beacon.os, 'makedirs', side_effect=OSError):
|
||||||
|
# Must not raise; failure is logged and the beacon retries next pass.
|
||||||
|
postgres_pillar_beacon._write_watermark(5)
|
||||||
|
self.assertFalse(os.path.exists(self.watermark))
|
||||||
|
|
||||||
|
# -- _query -----------------------------------------------------------
|
||||||
|
|
||||||
|
def test_query_success_returns_stdout_and_builds_argv(self):
|
||||||
|
completed = subprocess.CompletedProcess(args=[], returncode=0, stdout='rows', stderr='')
|
||||||
|
with patch.object(postgres_pillar_beacon.subprocess, 'run', return_value=completed) as mock_run:
|
||||||
|
result = postgres_pillar_beacon._query('SELECT 1;')
|
||||||
|
self.assertEqual(result, 'rows')
|
||||||
|
argv = mock_run.call_args[0][0]
|
||||||
|
self.assertEqual(argv[:5], ['docker', 'exec', 'so-postgres', 'psql', '-U'])
|
||||||
|
self.assertIn('SELECT 1;', argv)
|
||||||
|
self.assertFalse(mock_run.call_args[1].get('shell', False))
|
||||||
|
|
||||||
|
def test_query_timeout_returns_none(self):
|
||||||
|
with patch.object(postgres_pillar_beacon.subprocess, 'run',
|
||||||
|
side_effect=subprocess.TimeoutExpired(cmd='psql', timeout=30)):
|
||||||
|
self.assertIsNone(postgres_pillar_beacon._query('SELECT 1;'))
|
||||||
|
|
||||||
|
def test_query_generic_exception_returns_none(self):
|
||||||
|
with patch.object(postgres_pillar_beacon.subprocess, 'run', side_effect=Exception('boom')):
|
||||||
|
self.assertIsNone(postgres_pillar_beacon._query('SELECT 1;'))
|
||||||
|
|
||||||
|
def test_query_nonzero_returncode_returns_none(self):
|
||||||
|
completed = subprocess.CompletedProcess(args=[], returncode=1, stdout='', stderr='bad')
|
||||||
|
with patch.object(postgres_pillar_beacon.subprocess, 'run', return_value=completed):
|
||||||
|
self.assertIsNone(postgres_pillar_beacon._query('SELECT 1;'))
|
||||||
|
|
||||||
|
# -- beacon: first run / seeding --------------------------------------
|
||||||
|
|
||||||
|
def test_beacon_seeds_when_postgres_not_ready(self):
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=None), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value=None), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
self.assertEqual(postgres_pillar_beacon.beacon({}), [])
|
||||||
|
mock_write.assert_not_called()
|
||||||
|
|
||||||
|
def test_beacon_seeds_to_max_id_and_emits_nothing(self):
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=None), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value='7\n'), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
self.assertEqual(postgres_pillar_beacon.beacon({}), [])
|
||||||
|
mock_write.assert_called_once_with(7)
|
||||||
|
|
||||||
|
def test_beacon_seed_unparseable_is_swallowed(self):
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=None), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value='abc'), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
self.assertEqual(postgres_pillar_beacon.beacon({}), [])
|
||||||
|
mock_write.assert_not_called()
|
||||||
|
|
||||||
|
# -- beacon: steady state ---------------------------------------------
|
||||||
|
|
||||||
|
def test_beacon_query_failure_returns_empty(self):
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=10), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value=None), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
self.assertEqual(postgres_pillar_beacon.beacon({}), [])
|
||||||
|
mock_write.assert_not_called()
|
||||||
|
|
||||||
|
def test_beacon_emits_events_and_advances_watermark(self):
|
||||||
|
sep = postgres_pillar_beacon.FIELD_SEP
|
||||||
|
rows = '11%s5%snode1\n12%s6%s\n' % (sep, sep, sep, sep)
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=10), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value=rows), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
result = postgres_pillar_beacon.beacon({})
|
||||||
|
self.assertEqual(result, [
|
||||||
|
{'tag': 'audit_settings', 'id': 11, 'setting_id': '5', 'node_id': 'node1'},
|
||||||
|
{'tag': 'audit_settings', 'id': 12, 'setting_id': '6', 'node_id': ''},
|
||||||
|
])
|
||||||
|
mock_write.assert_called_once_with(12)
|
||||||
|
|
||||||
|
def test_beacon_skips_malformed_blank_and_noninteger_rows(self):
|
||||||
|
sep = postgres_pillar_beacon.FIELD_SEP
|
||||||
|
rows = (
|
||||||
|
'\n' # blank line -> skipped
|
||||||
|
'13%s7\n' # too few fields -> skipped
|
||||||
|
'abc%s8%snodeX\n' # non-integer id -> skipped
|
||||||
|
'14%s9%snodeY\n' # the one good row
|
||||||
|
) % (sep, sep, sep, sep, sep)
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=10), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value=rows), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
result = postgres_pillar_beacon.beacon({})
|
||||||
|
self.assertEqual(result, [
|
||||||
|
{'tag': 'audit_settings', 'id': 14, 'setting_id': '9', 'node_id': 'nodeY'},
|
||||||
|
])
|
||||||
|
mock_write.assert_called_once_with(14)
|
||||||
|
|
||||||
|
def test_beacon_no_new_rows_does_not_advance_watermark(self):
|
||||||
|
with patch.object(postgres_pillar_beacon, '_read_watermark', return_value=10), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_query', return_value=''), \
|
||||||
|
patch.object(postgres_pillar_beacon, '_write_watermark') as mock_write:
|
||||||
|
self.assertEqual(postgres_pillar_beacon.beacon({}), [])
|
||||||
|
mock_write.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
# Custom salt beacon that watches the suricata/strelka rule directories for changes
|
||||||
|
# and emits a beacon event per changed directory. This replaces the stock salt
|
||||||
|
# `inotify` beacon, which leaks a kernel inotify instance every time the minion
|
||||||
|
# rebuilds the beacon loader's __context__ (orphaning the old pyinotify.Notifier
|
||||||
|
# without closing it) until fs.inotify.max_user_instances is exhausted and the
|
||||||
|
# beacon dies with EMFILE. Polling holds zero inotify instances, so the leak is
|
||||||
|
# impossible, and it keeps firing during state runs (no blackout).
|
||||||
|
#
|
||||||
|
# Detection is poll-based with a per-directory fingerprint persisted to
|
||||||
|
# WATERMARK_DIR: each pass walks the directory and hashes every file's
|
||||||
|
# (relpath, st_mtime_ns, st_size), which catches content writes, additions,
|
||||||
|
# moves, and deletions. A change in the digest emits one event; an unchanged
|
||||||
|
# digest emits nothing. This makes it self-healing (a missed poll simply catches
|
||||||
|
# up on the next one).
|
||||||
|
#
|
||||||
|
# Each emitted event carries the watched directory path under the configured tag
|
||||||
|
# (e.g. salt/beacon/<minion>/rules_beacon/suricata); the push_suricata / push_strelka
|
||||||
|
# reactors write a push intent, after which the existing so-push-drainer /
|
||||||
|
# orch.push_batch pipeline takes over unchanged.
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
WATERMARK_DIR = '/opt/so/state'
|
||||||
|
|
||||||
|
# Temp/editor files that should not trigger a push. Mirrors the exclude regexes
|
||||||
|
# the inotify beacon used. Matched against the full pathname.
|
||||||
|
EXCLUDES = [
|
||||||
|
re.compile(r'\.sw[a-z]$'),
|
||||||
|
re.compile(r'~$'),
|
||||||
|
re.compile(r'/4913$'),
|
||||||
|
re.compile(r'/\.#'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def validate(config):
|
||||||
|
return True, 'valid'
|
||||||
|
|
||||||
|
|
||||||
|
def _paths_from_config(config):
|
||||||
|
# The beacon config arrives as a list of single-key dicts (salt beacon style).
|
||||||
|
# Merge it and return the {dir: tag} mapping under the 'paths' key.
|
||||||
|
merged = {}
|
||||||
|
if isinstance(config, list):
|
||||||
|
for item in config:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
merged.update(item)
|
||||||
|
elif isinstance(config, dict):
|
||||||
|
merged = config
|
||||||
|
paths = merged.get('paths', {})
|
||||||
|
return paths if isinstance(paths, dict) else {}
|
||||||
|
|
||||||
|
|
||||||
|
def _excluded(pathname):
|
||||||
|
for pattern in EXCLUDES:
|
||||||
|
if pattern.search(pathname):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _fingerprint(directory):
|
||||||
|
# Stat-only walk; hash each file's (relpath, mtime_ns, size). Returns a hex
|
||||||
|
# digest, or the digest of an empty tree if the directory does not exist.
|
||||||
|
h = hashlib.sha1()
|
||||||
|
if os.path.isdir(directory):
|
||||||
|
entries = []
|
||||||
|
for root, _dirs, files in os.walk(directory):
|
||||||
|
for name in files:
|
||||||
|
full = os.path.join(root, name)
|
||||||
|
if _excluded(full):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
st = os.stat(full)
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
rel = os.path.relpath(full, directory)
|
||||||
|
entries.append('%s\0%d\0%d' % (rel, st.st_mtime_ns, st.st_size))
|
||||||
|
for line in sorted(entries):
|
||||||
|
h.update(line.encode('utf-8', 'surrogateescape'))
|
||||||
|
h.update(b'\n')
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _watermark_file(tag):
|
||||||
|
return os.path.join(WATERMARK_DIR, 'rules_beacon_%s.hash' % tag)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_watermark(tag):
|
||||||
|
try:
|
||||||
|
with open(_watermark_file(tag), 'r') as f:
|
||||||
|
return (f.read() or '').strip() or None
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _write_watermark(tag, digest):
|
||||||
|
path = _watermark_file(tag)
|
||||||
|
try:
|
||||||
|
os.makedirs(WATERMARK_DIR, exist_ok=True)
|
||||||
|
tmp = path + '.tmp'
|
||||||
|
with open(tmp, 'w') as f:
|
||||||
|
f.write(digest)
|
||||||
|
os.rename(tmp, path)
|
||||||
|
except OSError:
|
||||||
|
log.exception('rules_beacon: failed to persist watermark to %s', path)
|
||||||
|
|
||||||
|
|
||||||
|
def beacon(config):
|
||||||
|
retval = []
|
||||||
|
|
||||||
|
for directory, tag in _paths_from_config(config).items():
|
||||||
|
digest = _fingerprint(directory)
|
||||||
|
previous = _read_watermark(tag)
|
||||||
|
|
||||||
|
# First run / missing watermark: seed the digest and emit nothing so a
|
||||||
|
# fresh host does not fire a spurious fleetwide push.
|
||||||
|
if previous is None:
|
||||||
|
_write_watermark(tag, digest)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if digest != previous:
|
||||||
|
_write_watermark(tag, digest)
|
||||||
|
retval.append({'tag': tag, 'path': directory})
|
||||||
|
log.info('rules_beacon: change detected in %s, emitting %s', directory, tag)
|
||||||
|
|
||||||
|
return retval
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import rules_beacon
|
||||||
|
|
||||||
|
|
||||||
|
class TestRulesBeacon(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Isolate all on-disk state (watermarks and the dirs we fingerprint) in a
|
||||||
|
# throwaway tree, and point WATERMARK_DIR at it so the real read/write
|
||||||
|
# helpers run against actual files.
|
||||||
|
self.tmpdir = tempfile.mkdtemp()
|
||||||
|
self.state = os.path.join(self.tmpdir, 'state')
|
||||||
|
patcher = patch.object(rules_beacon, 'WATERMARK_DIR', self.state)
|
||||||
|
patcher.start()
|
||||||
|
self.addCleanup(patcher.stop)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.tmpdir, ignore_errors=True)
|
||||||
|
|
||||||
|
def _make_dir(self, name, files=None):
|
||||||
|
path = os.path.join(self.tmpdir, name)
|
||||||
|
os.makedirs(path, exist_ok=True)
|
||||||
|
for fname, content in (files or {}).items():
|
||||||
|
with open(os.path.join(path, fname), 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
return path
|
||||||
|
|
||||||
|
# -- trivial contract -------------------------------------------------
|
||||||
|
|
||||||
|
def test_virtual_returns_true(self):
|
||||||
|
self.assertTrue(rules_beacon.__virtual__())
|
||||||
|
|
||||||
|
def test_validate_returns_valid(self):
|
||||||
|
self.assertEqual(rules_beacon.validate({}), (True, 'valid'))
|
||||||
|
|
||||||
|
# -- _paths_from_config -----------------------------------------------
|
||||||
|
|
||||||
|
def test_paths_from_config_list_of_dicts(self):
|
||||||
|
config = [{'interval': 10}, {'paths': {'/a': 'suricata', '/b': 'strelka'}}]
|
||||||
|
self.assertEqual(
|
||||||
|
rules_beacon._paths_from_config(config),
|
||||||
|
{'/a': 'suricata', '/b': 'strelka'},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_paths_from_config_plain_dict(self):
|
||||||
|
self.assertEqual(
|
||||||
|
rules_beacon._paths_from_config({'paths': {'/a': 'suricata'}}),
|
||||||
|
{'/a': 'suricata'},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_paths_from_config_skips_non_dict_items(self):
|
||||||
|
self.assertEqual(rules_beacon._paths_from_config(['bogus', 42]), {})
|
||||||
|
|
||||||
|
def test_paths_from_config_paths_not_a_dict(self):
|
||||||
|
self.assertEqual(rules_beacon._paths_from_config({'paths': 'nope'}), {})
|
||||||
|
|
||||||
|
def test_paths_from_config_unexpected_type(self):
|
||||||
|
self.assertEqual(rules_beacon._paths_from_config('nonsense'), {})
|
||||||
|
|
||||||
|
# -- _excluded --------------------------------------------------------
|
||||||
|
|
||||||
|
def test_excluded_matches_temp_and_editor_files(self):
|
||||||
|
for pathname in ('/rules/foo.swp', '/rules/foo~', '/rules/4913', '/rules/.#foo'):
|
||||||
|
self.assertTrue(rules_beacon._excluded(pathname), pathname)
|
||||||
|
|
||||||
|
def test_excluded_allows_real_rule_files(self):
|
||||||
|
self.assertFalse(rules_beacon._excluded('/rules/suricata.rules'))
|
||||||
|
|
||||||
|
# -- _fingerprint -----------------------------------------------------
|
||||||
|
|
||||||
|
def test_fingerprint_missing_dir_is_empty_tree_digest(self):
|
||||||
|
missing = os.path.join(self.tmpdir, 'does-not-exist')
|
||||||
|
self.assertEqual(rules_beacon._fingerprint(missing), hashlib.sha1().hexdigest())
|
||||||
|
|
||||||
|
def test_fingerprint_changes_when_content_changes(self):
|
||||||
|
d = self._make_dir('rules', {'a.rules': 'alert'})
|
||||||
|
before = rules_beacon._fingerprint(d)
|
||||||
|
with open(os.path.join(d, 'a.rules'), 'w') as f:
|
||||||
|
f.write('alert tcp any any -> any any') # different size
|
||||||
|
self.assertNotEqual(rules_beacon._fingerprint(d), before)
|
||||||
|
|
||||||
|
def test_fingerprint_ignores_excluded_files(self):
|
||||||
|
d = self._make_dir('rules', {'a.rules': 'alert'})
|
||||||
|
before = rules_beacon._fingerprint(d)
|
||||||
|
with open(os.path.join(d, 'a.rules.swp'), 'w') as f:
|
||||||
|
f.write('editor swap')
|
||||||
|
self.assertEqual(rules_beacon._fingerprint(d), before)
|
||||||
|
|
||||||
|
def test_fingerprint_skips_unstatable_entries(self):
|
||||||
|
# A dangling symlink appears in os.walk's file list but os.stat raises
|
||||||
|
# OSError, exercising the except-continue path.
|
||||||
|
d = self._make_dir('rules', {'a.rules': 'alert'})
|
||||||
|
good = rules_beacon._fingerprint(d)
|
||||||
|
os.symlink(os.path.join(d, 'missing-target'), os.path.join(d, 'broken.link'))
|
||||||
|
self.assertEqual(rules_beacon._fingerprint(d), good)
|
||||||
|
|
||||||
|
# -- _read_watermark / _write_watermark -------------------------------
|
||||||
|
|
||||||
|
def test_watermark_round_trip(self):
|
||||||
|
rules_beacon._write_watermark('suricata', 'deadbeef')
|
||||||
|
self.assertEqual(rules_beacon._read_watermark('suricata'), 'deadbeef')
|
||||||
|
|
||||||
|
def test_read_watermark_missing_returns_none(self):
|
||||||
|
self.assertIsNone(rules_beacon._read_watermark('suricata'))
|
||||||
|
|
||||||
|
def test_read_watermark_empty_file_returns_none(self):
|
||||||
|
os.makedirs(self.state, exist_ok=True)
|
||||||
|
with open(rules_beacon._watermark_file('suricata'), 'w') as f:
|
||||||
|
f.write('')
|
||||||
|
self.assertIsNone(rules_beacon._read_watermark('suricata'))
|
||||||
|
|
||||||
|
def test_write_watermark_swallows_oserror(self):
|
||||||
|
with patch.object(rules_beacon.os, 'makedirs', side_effect=OSError):
|
||||||
|
rules_beacon._write_watermark('suricata', 'deadbeef')
|
||||||
|
self.assertIsNone(rules_beacon._read_watermark('suricata'))
|
||||||
|
|
||||||
|
# -- beacon -----------------------------------------------------------
|
||||||
|
|
||||||
|
def _config(self, mapping):
|
||||||
|
return [{'paths': mapping}]
|
||||||
|
|
||||||
|
def test_beacon_seeds_first_run_and_emits_nothing(self):
|
||||||
|
with patch.object(rules_beacon, '_fingerprint', return_value='hash1'), \
|
||||||
|
patch.object(rules_beacon, '_read_watermark', return_value=None), \
|
||||||
|
patch.object(rules_beacon, '_write_watermark') as mock_write:
|
||||||
|
result = rules_beacon.beacon(self._config({'/rules/suricata': 'suricata'}))
|
||||||
|
self.assertEqual(result, [])
|
||||||
|
mock_write.assert_called_once_with('suricata', 'hash1')
|
||||||
|
|
||||||
|
def test_beacon_emits_on_change(self):
|
||||||
|
with patch.object(rules_beacon, '_fingerprint', return_value='newhash'), \
|
||||||
|
patch.object(rules_beacon, '_read_watermark', return_value='oldhash'), \
|
||||||
|
patch.object(rules_beacon, '_write_watermark') as mock_write:
|
||||||
|
result = rules_beacon.beacon(self._config({'/rules/suricata': 'suricata'}))
|
||||||
|
self.assertEqual(result, [{'tag': 'suricata', 'path': '/rules/suricata'}])
|
||||||
|
mock_write.assert_called_once_with('suricata', 'newhash')
|
||||||
|
|
||||||
|
def test_beacon_no_change_emits_nothing(self):
|
||||||
|
with patch.object(rules_beacon, '_fingerprint', return_value='samehash'), \
|
||||||
|
patch.object(rules_beacon, '_read_watermark', return_value='samehash'), \
|
||||||
|
patch.object(rules_beacon, '_write_watermark') as mock_write:
|
||||||
|
result = rules_beacon.beacon(self._config({'/rules/suricata': 'suricata'}))
|
||||||
|
self.assertEqual(result, [])
|
||||||
|
mock_write.assert_not_called()
|
||||||
|
|
||||||
|
def test_beacon_end_to_end_with_real_files(self):
|
||||||
|
# Exercise the full stack (real fingerprint + real watermark files) across
|
||||||
|
# two poll passes: first seeds silently, second fires after a write.
|
||||||
|
d = self._make_dir('rules', {'a.rules': 'alert'})
|
||||||
|
config = self._config({d: 'suricata'})
|
||||||
|
|
||||||
|
self.assertEqual(rules_beacon.beacon(config), []) # seed pass
|
||||||
|
self.assertEqual(rules_beacon.beacon(config), []) # unchanged pass
|
||||||
|
|
||||||
|
with open(os.path.join(d, 'b.rules'), 'w') as f:
|
||||||
|
f.write('alert tcp any any -> any any')
|
||||||
|
self.assertEqual(rules_beacon.beacon(config), [{'tag': 'suricata', 'path': d}])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
+18
-19
@@ -3,31 +3,30 @@ import logging
|
|||||||
|
|
||||||
def status():
|
def status():
|
||||||
|
|
||||||
cmd = "runuser -l zeek -c '/opt/zeek/bin/zeekctl status'"
|
cmd = "runuser -l zeek -c '/opt/zeek/bin/zeekctl status'"
|
||||||
retval = __salt__['docker.run']('so-zeek', cmd)
|
retval = __salt__['docker.run']('so-zeek', cmd) # noqa: F821
|
||||||
logging.info('zeekctl_module: zeekctl.status retval: %s' % retval)
|
logging.info('zeekctl_module: zeekctl.status retval: %s' % retval)
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
def beacon(config):
|
def beacon(config):
|
||||||
|
|
||||||
retval = []
|
retval = []
|
||||||
|
|
||||||
is_enabled = __salt__['healthcheck.is_enabled']()
|
is_enabled = __salt__['healthcheck.is_enabled']() # noqa: F821
|
||||||
logging.info('zeek_beacon: healthcheck_is_enabled: %s' % is_enabled)
|
logging.info('zeek_beacon: healthcheck_is_enabled: %s' % is_enabled)
|
||||||
|
|
||||||
if is_enabled:
|
if is_enabled:
|
||||||
zeekstatus = status().lower().split(' ')
|
zeekstatus = status().lower().split(' ')
|
||||||
logging.info('zeek_beacon: zeekctl.status: %s' % str(zeekstatus))
|
logging.info('zeek_beacon: zeekctl.status: %s' % str(zeekstatus))
|
||||||
if 'stopped' in zeekstatus or 'crashed' in zeekstatus or 'error' in zeekstatus or 'error:' in zeekstatus:
|
if 'stopped' in zeekstatus or 'crashed' in zeekstatus or 'error' in zeekstatus or 'error:' in zeekstatus:
|
||||||
zeek_restart = True
|
zeek_restart = True
|
||||||
else:
|
else:
|
||||||
zeek_restart = False
|
zeek_restart = False
|
||||||
|
|
||||||
__salt__['telegraf.send']('healthcheck zeek_restart=%s' % str(zeek_restart))
|
__salt__['telegraf.send']('healthcheck zeek_restart=%s' % str(zeek_restart)) # noqa: F821
|
||||||
retval.append({'zeek_restart': zeek_restart})
|
retval.append({'zeek_restart': zeek_restart})
|
||||||
logging.info('zeek_beacon: retval: %s' % str(retval))
|
logging.info('zeek_beacon: retval: %s' % str(retval))
|
||||||
|
|
||||||
return retval
|
|
||||||
|
|
||||||
|
return retval
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
import zeek
|
||||||
|
|
||||||
|
ZEEKCTL_CMD = "runuser -l zeek -c '/opt/zeek/bin/zeekctl status'"
|
||||||
|
|
||||||
|
|
||||||
|
class TestZeekBeacon(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# zeek.py relies on the __salt__ dunder that Salt injects at load time.
|
||||||
|
# Nothing defines it under test, so we attach a dict of mock loader
|
||||||
|
# functions to the module and remove it again afterwards.
|
||||||
|
self.salt = {
|
||||||
|
'docker.run': MagicMock(return_value='Zeek is running'),
|
||||||
|
'healthcheck.is_enabled': MagicMock(return_value=True),
|
||||||
|
'telegraf.send': MagicMock(),
|
||||||
|
}
|
||||||
|
zeek.__salt__ = self.salt
|
||||||
|
self.addCleanup(lambda: delattr(zeek, '__salt__'))
|
||||||
|
|
||||||
|
# -- status -----------------------------------------------------------
|
||||||
|
|
||||||
|
def test_status_runs_zeekctl_and_returns_output(self):
|
||||||
|
self.salt['docker.run'].return_value = 'Zeek is running'
|
||||||
|
result = zeek.status()
|
||||||
|
self.assertEqual(result, 'Zeek is running')
|
||||||
|
self.salt['docker.run'].assert_called_once_with('so-zeek', ZEEKCTL_CMD)
|
||||||
|
|
||||||
|
# -- beacon -----------------------------------------------------------
|
||||||
|
|
||||||
|
def test_beacon_disabled_returns_empty_and_skips_telegraf(self):
|
||||||
|
self.salt['healthcheck.is_enabled'].return_value = False
|
||||||
|
self.assertEqual(zeek.beacon({}), [])
|
||||||
|
self.salt['telegraf.send'].assert_not_called()
|
||||||
|
|
||||||
|
def test_beacon_running_reports_no_restart(self):
|
||||||
|
self.salt['docker.run'].return_value = 'Zeek is running'
|
||||||
|
self.assertEqual(zeek.beacon({}), [{'zeek_restart': False}])
|
||||||
|
self.salt['telegraf.send'].assert_called_once_with('healthcheck zeek_restart=False')
|
||||||
|
|
||||||
|
def test_beacon_unhealthy_status_triggers_restart(self):
|
||||||
|
# Each of these status tokens should flag a restart (the or-chain in beacon).
|
||||||
|
for status_text in ('Zeek is stopped', 'Zeek crashed', 'Zeek error state', 'Zeek error:'):
|
||||||
|
with self.subTest(status=status_text):
|
||||||
|
self.salt['docker.run'].return_value = status_text
|
||||||
|
self.salt['telegraf.send'].reset_mock()
|
||||||
|
self.assertEqual(zeek.beacon({}), [{'zeek_restart': True}])
|
||||||
|
self.salt['telegraf.send'].assert_called_once_with('healthcheck zeek_restart=True')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@@ -1,24 +1,14 @@
|
|||||||
from os import path
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
def check():
|
def check():
|
||||||
|
|
||||||
osfam = __grains__['os_family']
|
|
||||||
retval = 'False'
|
retval = 'False'
|
||||||
|
|
||||||
if osfam == 'Debian':
|
cmd = 'needs-restarting -r > /dev/null 2>&1'
|
||||||
if path.exists('/var/run/reboot-required'):
|
|
||||||
retval = 'True'
|
|
||||||
|
|
||||||
elif osfam == 'RedHat':
|
try:
|
||||||
cmd = 'needs-restarting -r > /dev/null 2>&1'
|
needs_restarting = subprocess.check_call(cmd, shell=True)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
try:
|
retval = 'True'
|
||||||
needs_restarting = subprocess.check_call(cmd, shell=True)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
retval = 'True'
|
|
||||||
|
|
||||||
else:
|
|
||||||
retval = 'Unsupported OS: %s' % os
|
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|||||||
@@ -15,11 +15,7 @@
|
|||||||
'salt.minion-check',
|
'salt.minion-check',
|
||||||
'sensoroni',
|
'sensoroni',
|
||||||
'salt.lasthighstate',
|
'salt.lasthighstate',
|
||||||
'salt.minion'
|
'salt.minion',
|
||||||
] %}
|
|
||||||
|
|
||||||
{% set ssl_states = [
|
|
||||||
'ssl',
|
|
||||||
'telegraf',
|
'telegraf',
|
||||||
'firewall',
|
'firewall',
|
||||||
'schedule',
|
'schedule',
|
||||||
@@ -28,21 +24,23 @@
|
|||||||
|
|
||||||
{% set manager_states = [
|
{% set manager_states = [
|
||||||
'salt.master',
|
'salt.master',
|
||||||
'ca',
|
'ca.server',
|
||||||
'registry',
|
'registry',
|
||||||
'manager',
|
'manager',
|
||||||
'nginx',
|
'nginx',
|
||||||
'influxdb',
|
'influxdb',
|
||||||
|
'postgres',
|
||||||
|
'postgres.auth',
|
||||||
'soc',
|
'soc',
|
||||||
'kratos',
|
'kratos',
|
||||||
'hydra',
|
'hydra',
|
||||||
'elasticfleet',
|
'elasticfleet',
|
||||||
'elastic-fleet-package-registry',
|
'elasticfleet.manager',
|
||||||
'utility'
|
'elasticsearch.cluster',
|
||||||
|
'elastic-fleet-package-registry'
|
||||||
] %}
|
] %}
|
||||||
|
|
||||||
{% set sensor_states = [
|
{% set sensor_states = [
|
||||||
'pcap',
|
|
||||||
'suricata',
|
'suricata',
|
||||||
'healthcheck',
|
'healthcheck',
|
||||||
'tcpreplay',
|
'tcpreplay',
|
||||||
@@ -75,28 +73,24 @@
|
|||||||
{# Map role-specific states #}
|
{# Map role-specific states #}
|
||||||
{% set role_states = {
|
{% set role_states = {
|
||||||
'so-eval': (
|
'so-eval': (
|
||||||
ssl_states +
|
|
||||||
manager_states +
|
manager_states +
|
||||||
sensor_states +
|
sensor_states +
|
||||||
elastic_stack_states | reject('equalto', 'logstash') | list
|
elastic_stack_states | reject('equalto', 'logstash') | list +
|
||||||
|
['logstash.ssl']
|
||||||
),
|
),
|
||||||
'so-heavynode': (
|
'so-heavynode': (
|
||||||
ssl_states +
|
|
||||||
sensor_states +
|
sensor_states +
|
||||||
['elasticagent', 'elasticsearch', 'logstash', 'redis', 'nginx']
|
['elasticagent', 'elasticsearch', 'elasticsearch.cluster', 'logstash', 'redis', 'nginx']
|
||||||
),
|
),
|
||||||
'so-idh': (
|
'so-idh': (
|
||||||
ssl_states +
|
|
||||||
['idh']
|
['idh']
|
||||||
),
|
),
|
||||||
'so-import': (
|
'so-import': (
|
||||||
ssl_states +
|
|
||||||
manager_states +
|
manager_states +
|
||||||
sensor_states | reject('equalto', 'strelka') | reject('equalto', 'healthcheck') | list +
|
sensor_states | reject('equalto', 'strelka') | reject('equalto', 'healthcheck') | list +
|
||||||
['elasticsearch', 'elasticsearch.auth', 'kibana', 'kibana.secrets', 'strelka.manager']
|
['elasticsearch', 'elasticsearch.auth', 'kibana', 'kibana.secrets', 'logstash.ssl', 'strelka.manager']
|
||||||
),
|
),
|
||||||
'so-manager': (
|
'so-manager': (
|
||||||
ssl_states +
|
|
||||||
manager_states +
|
manager_states +
|
||||||
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] +
|
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] +
|
||||||
stig_states +
|
stig_states +
|
||||||
@@ -104,7 +98,6 @@
|
|||||||
elastic_stack_states
|
elastic_stack_states
|
||||||
),
|
),
|
||||||
'so-managerhype': (
|
'so-managerhype': (
|
||||||
ssl_states +
|
|
||||||
manager_states +
|
manager_states +
|
||||||
['salt.cloud', 'strelka.manager', 'hypervisor', 'libvirt'] +
|
['salt.cloud', 'strelka.manager', 'hypervisor', 'libvirt'] +
|
||||||
stig_states +
|
stig_states +
|
||||||
@@ -112,7 +105,6 @@
|
|||||||
elastic_stack_states
|
elastic_stack_states
|
||||||
),
|
),
|
||||||
'so-managersearch': (
|
'so-managersearch': (
|
||||||
ssl_states +
|
|
||||||
manager_states +
|
manager_states +
|
||||||
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] +
|
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users', 'strelka.manager'] +
|
||||||
stig_states +
|
stig_states +
|
||||||
@@ -120,12 +112,10 @@
|
|||||||
elastic_stack_states
|
elastic_stack_states
|
||||||
),
|
),
|
||||||
'so-searchnode': (
|
'so-searchnode': (
|
||||||
ssl_states +
|
|
||||||
['kafka.ca', 'kafka.ssl', 'elasticsearch', 'logstash', 'nginx'] +
|
['kafka.ca', 'kafka.ssl', 'elasticsearch', 'logstash', 'nginx'] +
|
||||||
stig_states
|
stig_states
|
||||||
),
|
),
|
||||||
'so-standalone': (
|
'so-standalone': (
|
||||||
ssl_states +
|
|
||||||
manager_states +
|
manager_states +
|
||||||
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users'] +
|
['salt.cloud', 'libvirt.packages', 'libvirt.ssh.users'] +
|
||||||
sensor_states +
|
sensor_states +
|
||||||
@@ -134,29 +124,24 @@
|
|||||||
elastic_stack_states
|
elastic_stack_states
|
||||||
),
|
),
|
||||||
'so-sensor': (
|
'so-sensor': (
|
||||||
ssl_states +
|
|
||||||
sensor_states +
|
sensor_states +
|
||||||
['nginx'] +
|
['nginx'] +
|
||||||
stig_states
|
stig_states
|
||||||
),
|
),
|
||||||
'so-fleet': (
|
'so-fleet': (
|
||||||
ssl_states +
|
|
||||||
stig_states +
|
stig_states +
|
||||||
['logstash', 'nginx', 'healthcheck', 'elasticfleet']
|
['logstash', 'nginx', 'healthcheck', 'elasticfleet']
|
||||||
),
|
),
|
||||||
'so-receiver': (
|
'so-receiver': (
|
||||||
ssl_states +
|
|
||||||
kafka_states +
|
kafka_states +
|
||||||
stig_states +
|
stig_states +
|
||||||
['logstash', 'redis']
|
['logstash', 'redis']
|
||||||
),
|
),
|
||||||
'so-hypervisor': (
|
'so-hypervisor': (
|
||||||
ssl_states +
|
|
||||||
stig_states +
|
stig_states +
|
||||||
['hypervisor', 'libvirt']
|
['hypervisor', 'libvirt']
|
||||||
),
|
),
|
||||||
'so-desktop': (
|
'so-desktop': (
|
||||||
['ssl', 'docker_clean', 'telegraf'] +
|
|
||||||
stig_states
|
stig_states
|
||||||
)
|
)
|
||||||
} %}
|
} %}
|
||||||
|
|||||||
@@ -32,3 +32,4 @@ so_config_backup:
|
|||||||
- daymonth: '*'
|
- daymonth: '*'
|
||||||
- month: '*'
|
- month: '*'
|
||||||
- dayweek: '*'
|
- dayweek: '*'
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
backup:
|
backup:
|
||||||
locations:
|
locations:
|
||||||
description: List of locations to back up to the destination.
|
description: List of locations to back up to the destination.
|
||||||
helpLink: backup.html
|
helpLink: backup
|
||||||
global: True
|
global: True
|
||||||
destination:
|
destination:
|
||||||
description: Directory to store the configuration backups in.
|
description: Directory to store the configuration backups in.
|
||||||
helpLink: backup.html
|
helpLink: backup
|
||||||
global: True
|
global: True
|
||||||
|
|
||||||
@@ -25,9 +25,11 @@ if [ ! -f $BACKUPFILE ]; then
|
|||||||
# Create empty backup file
|
# Create empty backup file
|
||||||
tar -cf $BACKUPFILE -T /dev/null
|
tar -cf $BACKUPFILE -T /dev/null
|
||||||
|
|
||||||
# Loop through all paths defined in global.sls, and append them to backup file
|
# Loop through all paths defined in global.sls, and append them to backup file if they exist
|
||||||
{%- for LOCATION in BACKUPLOCATIONS %}
|
{%- for LOCATION in BACKUPLOCATIONS %}
|
||||||
tar -rf $BACKUPFILE "${EXCLUSIONS[@]}" {{ LOCATION }}
|
if [[ -d {{ LOCATION }} || -f {{ LOCATION }} ]]; then
|
||||||
|
tar -rf $BACKUPFILE "${EXCLUSIONS[@]}" {{ LOCATION }}
|
||||||
|
fi
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
{% macro remove_comments(bpfmerged, app) %}
|
{% macro remove_comments(bpfmerged, app) %}
|
||||||
|
|
||||||
{# remove comments from the bpf #}
|
{# remove comments from the bpf #}
|
||||||
|
{% set app_list = [] %}
|
||||||
{% for bpf in bpfmerged[app] %}
|
{% for bpf in bpfmerged[app] %}
|
||||||
{% if bpf.strip().startswith('#') %}
|
{% if not bpf.strip().startswith('#') %}
|
||||||
{% do bpfmerged[app].pop(loop.index0) %}
|
{% do app_list.append(bpf) %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% do bpfmerged.update({app: app_list}) %}
|
||||||
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% set PCAP_BPF_STATUS = 0 %}
|
{% set PCAP_BPF_STATUS = 0 %}
|
||||||
{% set STENO_BPF_COMPILED = "" %}
|
|
||||||
|
|
||||||
{% if GLOBALS.pcap_engine == "TRANSITION" %}
|
|
||||||
{% set PCAPBPF = ["ip and host 255.255.255.1 and port 1"] %}
|
|
||||||
{% else %}
|
|
||||||
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
||||||
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
||||||
{% import 'bpf/macros.jinja' as MACROS %}
|
{% import 'bpf/macros.jinja' as MACROS %}
|
||||||
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }}
|
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }}
|
||||||
{% set PCAPBPF = BPFMERGED.pcap %}
|
{% set PCAPBPF = BPFMERGED.pcap %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if PCAPBPF %}
|
{% if PCAPBPF %}
|
||||||
{% set PCAP_BPF_CALC = salt['cmd.run_all']('/usr/sbin/so-bpf-compile ' ~ GLOBALS.sensor.interface ~ ' ' ~ PCAPBPF|join(" "), cwd='/root') %}
|
{% set PCAP_BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + PCAPBPF|join(" "),cwd='/root') %}
|
||||||
{% if PCAP_BPF_CALC['retcode'] == 0 %}
|
{% if PCAP_BPF_CALC['retcode'] == 0 %}
|
||||||
{% set PCAP_BPF_STATUS = 1 %}
|
{% set PCAP_BPF_STATUS = 1 %}
|
||||||
{% set STENO_BPF_COMPILED = ",\\\"--filter=" + PCAP_BPF_CALC['stdout'] + "\\\"" %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ bpf:
|
|||||||
description: List of BPF filters to apply to the PCAP engine.
|
description: List of BPF filters to apply to the PCAP engine.
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
helpLink: bpf.html
|
helpLink: bpf
|
||||||
suricata:
|
suricata:
|
||||||
description: List of BPF filters to apply to Suricata. This will apply to alerts and, if enabled, to metadata and PCAP logs generated by Suricata.
|
description: List of BPF filters to apply to Suricata. This will apply to alerts and, if enabled, to metadata and PCAP logs generated by Suricata.
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
helpLink: bpf.html
|
helpLink: bpf
|
||||||
zeek:
|
zeek:
|
||||||
description: List of BPF filters to apply to Zeek.
|
description: List of BPF filters to apply to Zeek.
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
helpLink: bpf.html
|
helpLink: bpf
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
{% set SURICATABPF = BPFMERGED.suricata %}
|
{% set SURICATABPF = BPFMERGED.suricata %}
|
||||||
|
|
||||||
{% if SURICATABPF %}
|
{% if SURICATABPF %}
|
||||||
{% set SURICATA_BPF_CALC = salt['cmd.run_all']('/usr/sbin/so-bpf-compile ' ~ GLOBALS.sensor.interface ~ ' ' ~ SURICATABPF|join(" "), cwd='/root') %}
|
{% set SURICATA_BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + SURICATABPF|join(" "),cwd='/root') %}
|
||||||
{% if SURICATA_BPF_CALC['retcode'] == 0 %}
|
{% if SURICATA_BPF_CALC['retcode'] == 0 %}
|
||||||
{% set SURICATA_BPF_STATUS = 1 %}
|
{% set SURICATA_BPF_STATUS = 1 %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
{% set ZEEKBPF = BPFMERGED.zeek %}
|
{% set ZEEKBPF = BPFMERGED.zeek %}
|
||||||
|
|
||||||
{% if ZEEKBPF %}
|
{% if ZEEKBPF %}
|
||||||
{% set ZEEK_BPF_CALC = salt['cmd.run_all']('/usr/sbin/so-bpf-compile ' ~ GLOBALS.sensor.interface ~ ' ' ~ ZEEKBPF|join(" "), cwd='/root') %}
|
{% set ZEEK_BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + ZEEKBPF|join(" "),cwd='/root') %}
|
||||||
{% if ZEEK_BPF_CALC['retcode'] == 0 %}
|
{% if ZEEK_BPF_CALC['retcode'] == 0 %}
|
||||||
{% set ZEEK_BPF_STATUS = 1 %}
|
{% set ZEEK_BPF_STATUS = 1 %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
pki_issued_certs:
|
|
||||||
file.directory:
|
|
||||||
- name: /etc/pki/issued_certs
|
|
||||||
- makedirs: True
|
|
||||||
@@ -54,6 +54,20 @@ x509_signing_policies:
|
|||||||
- extendedKeyUsage: serverAuth
|
- extendedKeyUsage: serverAuth
|
||||||
- days_valid: 820
|
- days_valid: 820
|
||||||
- copypath: /etc/pki/issued_certs/
|
- copypath: /etc/pki/issued_certs/
|
||||||
|
postgres:
|
||||||
|
- minions: '*'
|
||||||
|
- signing_private_key: /etc/pki/ca.key
|
||||||
|
- signing_cert: /etc/pki/ca.crt
|
||||||
|
- C: US
|
||||||
|
- ST: Utah
|
||||||
|
- L: Salt Lake City
|
||||||
|
- basicConstraints: "critical CA:false"
|
||||||
|
- keyUsage: "critical keyEncipherment"
|
||||||
|
- subjectKeyIdentifier: hash
|
||||||
|
- authorityKeyIdentifier: keyid,issuer:always
|
||||||
|
- extendedKeyUsage: serverAuth
|
||||||
|
- days_valid: 820
|
||||||
|
- copypath: /etc/pki/issued_certs/
|
||||||
elasticfleet:
|
elasticfleet:
|
||||||
- minions: '*'
|
- minions: '*'
|
||||||
- signing_private_key: /etc/pki/ca.key
|
- signing_private_key: /etc/pki/ca.key
|
||||||
|
|||||||
+3
-63
@@ -3,70 +3,10 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
|
||||||
{% if sls in allowed_states %}
|
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
|
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- ca.dirs
|
{% if GLOBALS.is_manager %}
|
||||||
|
- ca.server
|
||||||
/etc/salt/minion.d/signing_policies.conf:
|
|
||||||
file.managed:
|
|
||||||
- source: salt://ca/files/signing_policies.conf
|
|
||||||
|
|
||||||
pki_private_key:
|
|
||||||
x509.private_key_managed:
|
|
||||||
- name: /etc/pki/ca.key
|
|
||||||
- keysize: 4096
|
|
||||||
- passphrase:
|
|
||||||
- backup: True
|
|
||||||
{% if salt['file.file_exists']('/etc/pki/ca.key') -%}
|
|
||||||
- prereq:
|
|
||||||
- x509: /etc/pki/ca.crt
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
pki_public_ca_crt:
|
|
||||||
x509.certificate_managed:
|
|
||||||
- name: /etc/pki/ca.crt
|
|
||||||
- signing_private_key: /etc/pki/ca.key
|
|
||||||
- CN: {{ GLOBALS.manager }}
|
|
||||||
- C: US
|
|
||||||
- ST: Utah
|
|
||||||
- L: Salt Lake City
|
|
||||||
- basicConstraints: "critical CA:true"
|
|
||||||
- keyUsage: "critical cRLSign, keyCertSign"
|
|
||||||
- extendedkeyUsage: "serverAuth, clientAuth"
|
|
||||||
- subjectKeyIdentifier: hash
|
|
||||||
- authorityKeyIdentifier: keyid:always, issuer
|
|
||||||
- days_valid: 3650
|
|
||||||
- days_remaining: 0
|
|
||||||
- backup: True
|
|
||||||
- replace: False
|
|
||||||
- require:
|
|
||||||
- sls: ca.dirs
|
|
||||||
- timeout: 30
|
|
||||||
- retry:
|
|
||||||
attempts: 5
|
|
||||||
interval: 30
|
|
||||||
|
|
||||||
mine_update_ca_crt:
|
|
||||||
module.run:
|
|
||||||
- mine.update: []
|
|
||||||
- onchanges:
|
|
||||||
- x509: pki_public_ca_crt
|
|
||||||
|
|
||||||
cakeyperms:
|
|
||||||
file.managed:
|
|
||||||
- replace: False
|
|
||||||
- name: /etc/pki/ca.key
|
|
||||||
- mode: 640
|
|
||||||
- group: 939
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
{{sls}}_state_not_allowed:
|
|
||||||
test.fail_without_changes:
|
|
||||||
- name: {{sls}}_state_not_allowed
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
- ca.trustca
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{% set CA = {
|
||||||
|
'server': pillar.ca.server
|
||||||
|
}%}
|
||||||
+30
-2
@@ -1,7 +1,35 @@
|
|||||||
pki_private_key:
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
{% set setup_running = salt['cmd.retcode']('pgrep -x so-setup') == 0 %}
|
||||||
|
|
||||||
|
{% if setup_running%}
|
||||||
|
|
||||||
|
include:
|
||||||
|
- ssl.remove
|
||||||
|
|
||||||
|
remove_pki_private_key:
|
||||||
file.absent:
|
file.absent:
|
||||||
- name: /etc/pki/ca.key
|
- name: /etc/pki/ca.key
|
||||||
|
|
||||||
pki_public_ca_crt:
|
remove_pki_public_ca_crt:
|
||||||
file.absent:
|
file.absent:
|
||||||
- name: /etc/pki/ca.crt
|
- name: /etc/pki/ca.crt
|
||||||
|
|
||||||
|
remove_trusttheca:
|
||||||
|
file.absent:
|
||||||
|
- name: /etc/pki/tls/certs/intca.crt
|
||||||
|
|
||||||
|
remove_pki_public_ca_crt_symlink:
|
||||||
|
file.absent:
|
||||||
|
- name: /opt/so/saltstack/local/salt/ca/files/ca.crt
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
so-setup_not_running:
|
||||||
|
test.show_notification:
|
||||||
|
- text: "This state is reserved for usage during so-setup."
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
|
{% if sls in allowed_states %}
|
||||||
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
|
|
||||||
|
pki_private_key:
|
||||||
|
x509.private_key_managed:
|
||||||
|
- name: /etc/pki/ca.key
|
||||||
|
- keysize: 4096
|
||||||
|
- passphrase:
|
||||||
|
- backup: True
|
||||||
|
{% if salt['file.file_exists']('/etc/pki/ca.key') -%}
|
||||||
|
- prereq:
|
||||||
|
- x509: /etc/pki/ca.crt
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
pki_public_ca_crt:
|
||||||
|
x509.certificate_managed:
|
||||||
|
- name: /etc/pki/ca.crt
|
||||||
|
- signing_private_key: /etc/pki/ca.key
|
||||||
|
- CN: {{ GLOBALS.manager }}
|
||||||
|
- C: US
|
||||||
|
- ST: Utah
|
||||||
|
- L: Salt Lake City
|
||||||
|
- basicConstraints: "critical CA:true"
|
||||||
|
- keyUsage: "critical cRLSign, keyCertSign"
|
||||||
|
- extendedkeyUsage: "serverAuth, clientAuth"
|
||||||
|
- subjectKeyIdentifier: hash
|
||||||
|
- authorityKeyIdentifier: keyid:always, issuer
|
||||||
|
- days_valid: 3650
|
||||||
|
- days_remaining: 7
|
||||||
|
- backup: True
|
||||||
|
- replace: False
|
||||||
|
- timeout: 30
|
||||||
|
- retry:
|
||||||
|
attempts: 5
|
||||||
|
interval: 30
|
||||||
|
|
||||||
|
pki_public_ca_crt_symlink:
|
||||||
|
file.symlink:
|
||||||
|
- name: /opt/so/saltstack/local/salt/ca/files/ca.crt
|
||||||
|
- target: /etc/pki/ca.crt
|
||||||
|
- require:
|
||||||
|
- x509: pki_public_ca_crt
|
||||||
|
|
||||||
|
cakeyperms:
|
||||||
|
file.managed:
|
||||||
|
- replace: False
|
||||||
|
- name: /etc/pki/ca.key
|
||||||
|
- mode: 640
|
||||||
|
- group: 939
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{{sls}}_state_not_allowed:
|
||||||
|
test.fail_without_changes:
|
||||||
|
- name: {{sls}}_state_not_allowed
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
# when the salt-minion signs the cert, a copy is stored here
|
||||||
|
issued_certs_copypath:
|
||||||
|
file.directory:
|
||||||
|
- name: /etc/pki/issued_certs
|
||||||
|
- makedirs: True
|
||||||
|
|
||||||
|
signing_policy:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/salt/minion.d/signing_policies.conf
|
||||||
|
- source: salt://ca/files/signing_policies.conf
|
||||||
Executable → Regular
+11
-11
@@ -1,18 +1,18 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
include:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
# Trust the CA
|
||||||
|
trusttheca:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/pki/tls/certs/intca.crt
|
||||||
|
- source: salt://ca/files/ca.crt
|
||||||
|
- watch_in:
|
||||||
|
- service: docker_running
|
||||||
|
- show_changes: False
|
||||||
|
- makedirs: True
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
|
||||||
echo "Usage: $0 <steno-query> Output-Filename"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker exec -t so-sensoroni scripts/stenoquery.sh "$1" -w /nsm/pcapout/$2.pcap
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "If successful, the output was written to: /nsm/pcapout/$2.pcap"
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"registry-mirrors": [
|
|
||||||
"https://:5000"
|
|
||||||
],
|
|
||||||
"bip": "172.17.0.1/24",
|
|
||||||
"default-address-pools": [
|
|
||||||
{
|
|
||||||
"base": "172.17.0.0/24",
|
|
||||||
"size": 24
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
+12
-28
@@ -20,11 +20,6 @@ kernel.printk:
|
|||||||
sysctl.present:
|
sysctl.present:
|
||||||
- value: "3 4 1 3"
|
- value: "3 4 1 3"
|
||||||
|
|
||||||
# Remove variables.txt from /tmp - This is temp
|
|
||||||
rmvariablesfile:
|
|
||||||
file.absent:
|
|
||||||
- name: /tmp/variables.txt
|
|
||||||
|
|
||||||
# Add socore Group
|
# Add socore Group
|
||||||
socoregroup:
|
socoregroup:
|
||||||
group.present:
|
group.present:
|
||||||
@@ -135,6 +130,17 @@ common_sbin:
|
|||||||
- so-pcap-import
|
- so-pcap-import
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
# Pin physical NIC names by MAC (run-once) so a kernel upgrade can't renumber the
|
||||||
|
# interfaces SO binds by name. The marker keeps it a one-time setup; an admin can
|
||||||
|
# pre-create the marker to opt out.
|
||||||
|
pin_nic_names:
|
||||||
|
cmd.run:
|
||||||
|
- name: /usr/sbin/so-nic-pin
|
||||||
|
- unless: 'test -e /opt/so/state/nic_names_pinned'
|
||||||
|
- require:
|
||||||
|
- file: common_sbin
|
||||||
|
- file: statedir
|
||||||
|
|
||||||
common_sbin_jinja:
|
common_sbin_jinja:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
@@ -149,35 +155,13 @@ common_sbin_jinja:
|
|||||||
- so-import-pcap
|
- so-import-pcap
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if GLOBALS.role == 'so-heavynode' %}
|
|
||||||
remove_so-pcap-import_heavynode:
|
|
||||||
file.absent:
|
|
||||||
- name: /usr/sbin/so-pcap-import
|
|
||||||
|
|
||||||
remove_so-import-pcap_heavynode:
|
|
||||||
file.absent:
|
|
||||||
- name: /usr/sbin/so-import-pcap
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if not GLOBALS.is_manager%}
|
|
||||||
# prior to 2.4.50 these scripts were in common/tools/sbin on the manager because of soup and distributed to non managers
|
|
||||||
# these two states remove the scripts from non manager nodes
|
|
||||||
remove_soup:
|
|
||||||
file.absent:
|
|
||||||
- name: /usr/sbin/soup
|
|
||||||
|
|
||||||
remove_so-firewall:
|
|
||||||
file.absent:
|
|
||||||
- name: /usr/sbin/so-firewall
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
so-status_script:
|
so-status_script:
|
||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-status
|
- name: /usr/sbin/so-status
|
||||||
- source: salt://common/tools/sbin/so-status
|
- source: salt://common/tools/sbin/so-status
|
||||||
- mode: 755
|
- mode: 755
|
||||||
|
|
||||||
{% if GLOBALS.role in GLOBALS.sensor_roles %}
|
{% if GLOBALS.is_sensor %}
|
||||||
# Add sensor cleanup
|
# Add sensor cleanup
|
||||||
so-sensor-clean:
|
so-sensor-clean:
|
||||||
cron.present:
|
cron.present:
|
||||||
|
|||||||
@@ -1,52 +1,5 @@
|
|||||||
# we cannot import GLOBALS from vars/globals.map.jinja in this state since it is called in setup.virt.init
|
# we cannot import GLOBALS from vars/globals.map.jinja in this state since it is called in setup.virt.init
|
||||||
# since it is early in setup of a new VM, the pillars imported in GLOBALS are not yet defined
|
# since it is early in setup of a new VM, the pillars imported in GLOBALS are not yet defined
|
||||||
{% if grains.os_family == 'Debian' %}
|
|
||||||
commonpkgs:
|
|
||||||
pkg.installed:
|
|
||||||
- skip_suggestions: True
|
|
||||||
- pkgs:
|
|
||||||
- apache2-utils
|
|
||||||
- wget
|
|
||||||
- ntpdate
|
|
||||||
- jq
|
|
||||||
- curl
|
|
||||||
- ca-certificates
|
|
||||||
- software-properties-common
|
|
||||||
- apt-transport-https
|
|
||||||
- openssl
|
|
||||||
- netcat-openbsd
|
|
||||||
- sqlite3
|
|
||||||
- libssl-dev
|
|
||||||
- procps
|
|
||||||
- python3-dateutil
|
|
||||||
- python3-docker
|
|
||||||
- python3-packaging
|
|
||||||
- python3-lxml
|
|
||||||
- git
|
|
||||||
- rsync
|
|
||||||
- vim
|
|
||||||
- tar
|
|
||||||
- unzip
|
|
||||||
- bc
|
|
||||||
{% if grains.oscodename != 'focal' %}
|
|
||||||
- python3-rich
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if grains.oscodename == 'focal' %}
|
|
||||||
# since Ubuntu requires and internet connection we can use pip to install modules
|
|
||||||
python3-pip:
|
|
||||||
pkg.installed
|
|
||||||
|
|
||||||
python-rich:
|
|
||||||
pip.installed:
|
|
||||||
- name: rich
|
|
||||||
- target: /usr/local/lib/python3.8/dist-packages/
|
|
||||||
- require:
|
|
||||||
- pkg: python3-pip
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if grains.os_family == 'RedHat' %}
|
|
||||||
|
|
||||||
remove_mariadb:
|
remove_mariadb:
|
||||||
pkg.removed:
|
pkg.removed:
|
||||||
@@ -84,5 +37,3 @@ commonpkgs:
|
|||||||
- unzip
|
- unzip
|
||||||
- wget
|
- wget
|
||||||
- yum-utils
|
- yum-utils
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
{% if '2.4' in salt['cp.get_file_str']('/etc/soversion') %}
|
|
||||||
|
|
||||||
{% import_yaml '/opt/so/saltstack/local/pillar/global/soc_global.sls' as SOC_GLOBAL %}
|
{% import_yaml '/opt/so/saltstack/local/pillar/global/soc_global.sls' as SOC_GLOBAL %}
|
||||||
{% if SOC_GLOBAL.global.airgap %}
|
{% if SOC_GLOBAL.global.airgap %}
|
||||||
{% set UPDATE_DIR='/tmp/soagupdate/SecurityOnion' %}
|
{% set UPDATE_DIR='/tmp/soagupdate/SecurityOnion' %}
|
||||||
@@ -13,14 +11,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% set SOVERSION = salt['file.read']('/etc/soversion').strip() %}
|
{% set SOVERSION = salt['file.read']('/etc/soversion').strip() %}
|
||||||
|
|
||||||
remove_common_soup:
|
|
||||||
file.absent:
|
|
||||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/soup
|
|
||||||
|
|
||||||
remove_common_so-firewall:
|
|
||||||
file.absent:
|
|
||||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-firewall
|
|
||||||
|
|
||||||
# This section is used to put the scripts in place in the Salt file system
|
# This section is used to put the scripts in place in the Salt file system
|
||||||
# in case a state run tries to overwrite what we do in the next section.
|
# in case a state run tries to overwrite what we do in the next section.
|
||||||
copy_so-common_common_tools_sbin:
|
copy_so-common_common_tools_sbin:
|
||||||
@@ -120,23 +110,3 @@ copy_bootstrap-salt_sbin:
|
|||||||
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- preserve: True
|
||||||
|
|
||||||
{# this is added in 2.4.120 to remove salt repo files pointing to saltproject.io to accomodate the move to broadcom and new bootstrap-salt script #}
|
|
||||||
{% if salt['pkg.version_cmp'](SOVERSION, '2.4.120') == -1 %}
|
|
||||||
{% set saltrepofile = '/etc/yum.repos.d/salt.repo' %}
|
|
||||||
{% if grains.os_family == 'Debian' %}
|
|
||||||
{% set saltrepofile = '/etc/apt/sources.list.d/salt.list' %}
|
|
||||||
{% endif %}
|
|
||||||
remove_saltproject_io_repo_manager:
|
|
||||||
file.absent:
|
|
||||||
- name: {{ saltrepofile }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
fix_23_soup_sbin:
|
|
||||||
cmd.run:
|
|
||||||
- name: curl -s -f -o /usr/sbin/soup https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.3/main/salt/common/tools/sbin/soup
|
|
||||||
fix_23_soup_salt:
|
|
||||||
cmd.run:
|
|
||||||
- name: curl -s -f -o /opt/so/saltstack/defalt/salt/common/tools/sbin/soup https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.3/main/salt/common/tools/sbin/soup
|
|
||||||
{% endif %}
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
if [ "$#" -lt 2 ]; then
|
if [ "$#" -lt 2 ]; then
|
||||||
cat 1>&2 <<EOF
|
cat 1>&2 <<EOF
|
||||||
$0 compiles a BPF expression to be passed to stenotype to apply a socket filter.
|
$0 compiles a BPF expression to be passed to PCAP to apply a socket filter.
|
||||||
Its first argument is the interface (link type is required) and all other arguments
|
Its first argument is the interface (link type is required) and all other arguments
|
||||||
are passed to TCPDump.
|
are passed to TCPDump.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
cat << EOF
|
cat << EOF
|
||||||
|
|
||||||
so-checkin will run a full salt highstate to apply all salt states. If a highstate is already running, this request will be queued and so it may pause for a few minutes before you see any more output. For more information about so-checkin and salt, please see:
|
so-checkin will run a full salt highstate to apply all salt states. If a highstate is already running, this request will be queued and so it may pause for a few minutes before you see any more output. For more information about so-checkin and salt, please see:
|
||||||
https://docs.securityonion.net/en/2.4/salt.html
|
https://securityonion.net/docs/salt
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# and since this same logic is required during installation, it's included in this file.
|
# and since this same logic is required during installation, it's included in this file.
|
||||||
|
|
||||||
DEFAULT_SALT_DIR=/opt/so/saltstack/default
|
DEFAULT_SALT_DIR=/opt/so/saltstack/default
|
||||||
DOC_BASE_URL="https://docs.securityonion.net/en/2.4"
|
DOC_BASE_URL="https://securityonion.net/docs"
|
||||||
|
|
||||||
if [ -z $NOROOT ]; then
|
if [ -z $NOROOT ]; then
|
||||||
# Check for prerequisites
|
# Check for prerequisites
|
||||||
@@ -142,6 +142,11 @@ check_elastic_license() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_elasticsearch_responsive() {
|
||||||
|
retry 3 15 "so-elasticsearch-query / --output /dev/null --fail" ||
|
||||||
|
fail "Elasticsearch is not responding. Please review Elasticsearch logs /opt/so/log/elasticsearch/securityonion.log for more details. Additionally, consider running so-elasticsearch-troubleshoot."
|
||||||
|
}
|
||||||
|
|
||||||
check_salt_master_status() {
|
check_salt_master_status() {
|
||||||
local count=0
|
local count=0
|
||||||
local attempts="${1:- 10}"
|
local attempts="${1:- 10}"
|
||||||
@@ -286,6 +291,20 @@ download_and_verify() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# check if container with name is running and optionally stop it
|
||||||
|
docker_check_running() {
|
||||||
|
# show running containers, only names
|
||||||
|
if docker ps --format '{{.Names}}' | grep -q "^so-${1}$"; then
|
||||||
|
if [[ "$2" == "--stop" ]]; then
|
||||||
|
docker stop "so-${1}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
elastic_license() {
|
elastic_license() {
|
||||||
|
|
||||||
read -r -d '' message <<- EOM
|
read -r -d '' message <<- EOM
|
||||||
@@ -333,8 +352,8 @@ get_elastic_agent_vars() {
|
|||||||
|
|
||||||
if [ -f "$defaultsfile" ]; then
|
if [ -f "$defaultsfile" ]; then
|
||||||
ELASTIC_AGENT_TARBALL_VERSION=$(egrep " +version: " $defaultsfile | awk -F: '{print $2}' | tr -d '[:space:]')
|
ELASTIC_AGENT_TARBALL_VERSION=$(egrep " +version: " $defaultsfile | awk -F: '{print $2}' | tr -d '[:space:]')
|
||||||
ELASTIC_AGENT_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz"
|
ELASTIC_AGENT_URL="https://repo.securityonion.net/file/so-repo/prod/3/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz"
|
||||||
ELASTIC_AGENT_MD5_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5"
|
ELASTIC_AGENT_MD5_URL="https://repo.securityonion.net/file/so-repo/prod/3/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5"
|
||||||
ELASTIC_AGENT_FILE="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz"
|
ELASTIC_AGENT_FILE="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz"
|
||||||
ELASTIC_AGENT_MD5="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5"
|
ELASTIC_AGENT_MD5="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5"
|
||||||
ELASTIC_AGENT_EXPANSION_DIR=/nsm/elastic-fleet/artifacts/beats/elastic-agent
|
ELASTIC_AGENT_EXPANSION_DIR=/nsm/elastic-fleet/artifacts/beats/elastic-agent
|
||||||
@@ -349,21 +368,16 @@ get_random_value() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gpg_rpm_import() {
|
gpg_rpm_import() {
|
||||||
if [[ $is_oracle ]]; then
|
if [[ "$WHATWOULDYOUSAYYAHDOHERE" == "setup" ]]; then
|
||||||
if [[ "$WHATWOULDYOUSAYYAHDOHERE" == "setup" ]]; then
|
local RPMKEYSLOC="../salt/repo/client/files/$OS/keys"
|
||||||
local RPMKEYSLOC="../salt/repo/client/files/$OS/keys"
|
else
|
||||||
else
|
local RPMKEYSLOC="$UPDATE_DIR/salt/repo/client/files/$OS/keys"
|
||||||
local RPMKEYSLOC="$UPDATE_DIR/salt/repo/client/files/$OS/keys"
|
|
||||||
fi
|
|
||||||
RPMKEYS=('RPM-GPG-KEY-oracle' 'RPM-GPG-KEY-EPEL-9' 'SALT-PROJECT-GPG-PUBKEY-2023.pub' 'docker.pub' 'securityonion.pub')
|
|
||||||
for RPMKEY in "${RPMKEYS[@]}"; do
|
|
||||||
rpm --import $RPMKEYSLOC/$RPMKEY
|
|
||||||
echo "Imported $RPMKEY"
|
|
||||||
done
|
|
||||||
elif [[ $is_rpm ]]; then
|
|
||||||
echo "Importing the security onion GPG key"
|
|
||||||
rpm --import ../salt/repo/client/files/oracle/keys/securityonion.pub
|
|
||||||
fi
|
fi
|
||||||
|
RPMKEYS=('RPM-GPG-KEY-oracle' 'RPM-GPG-KEY-EPEL-9' 'SALT-PROJECT-GPG-PUBKEY-2023.pub' 'docker.pub' 'securityonion.pub')
|
||||||
|
for RPMKEY in "${RPMKEYS[@]}"; do
|
||||||
|
rpm --import $RPMKEYSLOC/$RPMKEY
|
||||||
|
echo "Imported $RPMKEY"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
header() {
|
header() {
|
||||||
@@ -404,6 +418,25 @@ is_single_node_grid() {
|
|||||||
grep "role: so-" /etc/salt/grains | grep -E "eval|standalone|import" &> /dev/null
|
grep "role: so-" /etc/salt/grains | grep -E "eval|standalone|import" &> /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialize_elasticsearch_indices() {
|
||||||
|
local index_names=$1
|
||||||
|
local default_entry=${2:-'{"@timestamp":"0"}'}
|
||||||
|
|
||||||
|
for idx in $index_names; do
|
||||||
|
if ! so-elasticsearch-query "$idx" --fail --retry 3 --retry-delay 30 >/dev/null 2>&1; then
|
||||||
|
echo "Index does not already exist. Initializing $idx index."
|
||||||
|
|
||||||
|
if retry 3 10 "so-elasticsearch-query "$idx/_doc" -d '$default_entry' -XPOST --fail 2>/dev/null" '"successful":1'; then
|
||||||
|
echo "Successfully initialized $idx index."
|
||||||
|
else
|
||||||
|
echo "Failed to initialize $idx index after 3 attempts."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Index $idx already exists. No action needed."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
lookup_bond_interfaces() {
|
lookup_bond_interfaces() {
|
||||||
cat /proc/net/bonding/bond0 | grep "Slave Interface:" | sed -e "s/Slave Interface: //g"
|
cat /proc/net/bonding/bond0 | grep "Slave Interface:" | sed -e "s/Slave Interface: //g"
|
||||||
}
|
}
|
||||||
@@ -531,6 +564,22 @@ retry() {
|
|||||||
return $exitcode
|
return $exitcode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rollover_index() {
|
||||||
|
idx=$1
|
||||||
|
exists=$(so-elasticsearch-query $idx -o /dev/null -w "%{http_code}")
|
||||||
|
if [[ $exists -eq 200 ]]; then
|
||||||
|
rollover=$(so-elasticsearch-query $idx/_rollover -o /dev/null -w "%{http_code}" -XPOST)
|
||||||
|
|
||||||
|
if [[ $rollover -eq 200 ]]; then
|
||||||
|
echo "Successfully triggered rollover for $idx..."
|
||||||
|
else
|
||||||
|
echo "Could not trigger rollover for $idx..."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Could not find index $idx..."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
run_check_net_err() {
|
run_check_net_err() {
|
||||||
local cmd=$1
|
local cmd=$1
|
||||||
local err_msg=${2:-"Unknown error occured, please check /root/$WHATWOULDYOUSAYYAHDOHERE.log for details."} # Really need to rename that variable
|
local err_msg=${2:-"Unknown error occured, please check /root/$WHATWOULDYOUSAYYAHDOHERE.log for details."} # Really need to rename that variable
|
||||||
@@ -553,24 +602,6 @@ run_check_net_err() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_for_salt_minion() {
|
|
||||||
local minion="$1"
|
|
||||||
local timeout="${2:-5}"
|
|
||||||
local logfile="${3:-'/dev/stdout'}"
|
|
||||||
retry 60 5 "journalctl -u salt-minion.service | grep 'Minion is ready to receive requests'" >> "$logfile" 2>&1 || fail
|
|
||||||
local attempt=0
|
|
||||||
# each attempts would take about 15 seconds
|
|
||||||
local maxAttempts=20
|
|
||||||
until check_salt_minion_status "$minion" "$timeout" "$logfile"; do
|
|
||||||
attempt=$((attempt+1))
|
|
||||||
if [[ $attempt -eq $maxAttempts ]]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
sleep 10
|
|
||||||
done
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
salt_minion_count() {
|
salt_minion_count() {
|
||||||
local MINIONDIR="/opt/so/saltstack/local/pillar/minions"
|
local MINIONDIR="/opt/so/saltstack/local/pillar/minions"
|
||||||
MINIONCOUNT=$(ls -la $MINIONDIR/*.sls | grep -v adv_ | wc -l)
|
MINIONCOUNT=$(ls -la $MINIONDIR/*.sls | grep -v adv_ | wc -l)
|
||||||
@@ -578,69 +609,19 @@ salt_minion_count() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_os() {
|
set_os() {
|
||||||
if [ -f /etc/redhat-release ]; then
|
if [ -f /etc/redhat-release ] && grep -q "Red Hat Enterprise Linux release 9" /etc/redhat-release && [ -f /etc/oracle-release ]; then
|
||||||
if grep -q "Rocky Linux release 9" /etc/redhat-release; then
|
OS=oracle
|
||||||
OS=rocky
|
OSVER=9
|
||||||
OSVER=9
|
is_oracle=true
|
||||||
is_rocky=true
|
is_rpm=true
|
||||||
is_rpm=true
|
|
||||||
elif grep -q "CentOS Stream release 9" /etc/redhat-release; then
|
|
||||||
OS=centos
|
|
||||||
OSVER=9
|
|
||||||
is_centos=true
|
|
||||||
is_rpm=true
|
|
||||||
elif grep -q "AlmaLinux release 9" /etc/redhat-release; then
|
|
||||||
OS=alma
|
|
||||||
OSVER=9
|
|
||||||
is_alma=true
|
|
||||||
is_rpm=true
|
|
||||||
elif grep -q "Red Hat Enterprise Linux release 9" /etc/redhat-release; then
|
|
||||||
if [ -f /etc/oracle-release ]; then
|
|
||||||
OS=oracle
|
|
||||||
OSVER=9
|
|
||||||
is_oracle=true
|
|
||||||
is_rpm=true
|
|
||||||
else
|
|
||||||
OS=rhel
|
|
||||||
OSVER=9
|
|
||||||
is_rhel=true
|
|
||||||
is_rpm=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
cron_service_name="crond"
|
|
||||||
elif [ -f /etc/os-release ]; then
|
|
||||||
if grep -q "UBUNTU_CODENAME=focal" /etc/os-release; then
|
|
||||||
OSVER=focal
|
|
||||||
UBVER=20.04
|
|
||||||
OS=ubuntu
|
|
||||||
is_ubuntu=true
|
|
||||||
is_deb=true
|
|
||||||
elif grep -q "UBUNTU_CODENAME=jammy" /etc/os-release; then
|
|
||||||
OSVER=jammy
|
|
||||||
UBVER=22.04
|
|
||||||
OS=ubuntu
|
|
||||||
is_ubuntu=true
|
|
||||||
is_deb=true
|
|
||||||
elif grep -q "VERSION_CODENAME=bookworm" /etc/os-release; then
|
|
||||||
OSVER=bookworm
|
|
||||||
DEBVER=12
|
|
||||||
is_debian=true
|
|
||||||
OS=debian
|
|
||||||
is_deb=true
|
|
||||||
fi
|
|
||||||
cron_service_name="cron"
|
|
||||||
fi
|
fi
|
||||||
|
cron_service_name="crond"
|
||||||
}
|
}
|
||||||
|
|
||||||
set_minionid() {
|
set_minionid() {
|
||||||
MINIONID=$(lookup_grain id)
|
MINIONID=$(lookup_grain id)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_palette() {
|
|
||||||
if [[ $is_deb ]]; then
|
|
||||||
update-alternatives --set newt-palette /etc/newt/palette.original
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set_version() {
|
set_version() {
|
||||||
CURRENTVERSION=0.0.0
|
CURRENTVERSION=0.0.0
|
||||||
@@ -685,7 +666,7 @@ systemctl_func() {
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "${echo_action^}ing $service_name service at $(date +"%T.%6N")"
|
echo "${echo_action^}ing $service_name service at $(date +"%T.%6N")"
|
||||||
systemctl $action $service_name && echo "Successfully ${echo_action}ed $service_name." || echo "Failed to $action $service_name."
|
systemctl $action $service_name && echo "Successfully ${echo_action}ed $service_name at $(date +"%T.%6N")." || echo "Failed to $action $service_name at $(date +"%T.%6N")."
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ container_list() {
|
|||||||
"so-hydra"
|
"so-hydra"
|
||||||
"so-nginx"
|
"so-nginx"
|
||||||
"so-pcaptools"
|
"so-pcaptools"
|
||||||
|
"so-postgres"
|
||||||
"so-soc"
|
"so-soc"
|
||||||
"so-steno"
|
|
||||||
"so-suricata"
|
"so-suricata"
|
||||||
"so-telegraf"
|
"so-telegraf"
|
||||||
"so-zeek"
|
"so-zeek"
|
||||||
@@ -56,9 +56,9 @@ container_list() {
|
|||||||
"so-logstash"
|
"so-logstash"
|
||||||
"so-nginx"
|
"so-nginx"
|
||||||
"so-pcaptools"
|
"so-pcaptools"
|
||||||
|
"so-postgres"
|
||||||
"so-redis"
|
"so-redis"
|
||||||
"so-soc"
|
"so-soc"
|
||||||
"so-steno"
|
|
||||||
"so-strelka-backend"
|
"so-strelka-backend"
|
||||||
"so-strelka-manager"
|
"so-strelka-manager"
|
||||||
"so-suricata"
|
"so-suricata"
|
||||||
@@ -71,7 +71,6 @@ container_list() {
|
|||||||
"so-logstash"
|
"so-logstash"
|
||||||
"so-nginx"
|
"so-nginx"
|
||||||
"so-redis"
|
"so-redis"
|
||||||
"so-steno"
|
|
||||||
"so-suricata"
|
"so-suricata"
|
||||||
"so-soc"
|
"so-soc"
|
||||||
"so-telegraf"
|
"so-telegraf"
|
||||||
@@ -165,8 +164,8 @@ update_docker_containers() {
|
|||||||
# Pull down the trusted docker image
|
# Pull down the trusted docker image
|
||||||
run_check_net_err \
|
run_check_net_err \
|
||||||
"docker pull $CONTAINER_REGISTRY/$IMAGEREPO/$image" \
|
"docker pull $CONTAINER_REGISTRY/$IMAGEREPO/$image" \
|
||||||
"Could not pull $image, please ensure connectivity to $CONTAINER_REGISTRY" >> "$LOG_FILE" 2>&1
|
"Could not pull $image, please ensure connectivity to $CONTAINER_REGISTRY" >> "$LOG_FILE" 2>&1
|
||||||
|
|
||||||
# Get signature
|
# Get signature
|
||||||
run_check_net_err \
|
run_check_net_err \
|
||||||
"curl --retry 5 --retry-delay 60 -A '$CURLTYPE/$CURRENTVERSION/$OS/$(uname -r)' $sig_url --output $SIGNPATH/$image.sig" \
|
"curl --retry 5 --retry-delay 60 -A '$CURLTYPE/$CURRENTVERSION/$OS/$(uname -r)' $sig_url --output $SIGNPATH/$image.sig" \
|
||||||
@@ -189,8 +188,27 @@ update_docker_containers() {
|
|||||||
if [ -z "$HOSTNAME" ]; then
|
if [ -z "$HOSTNAME" ]; then
|
||||||
HOSTNAME=$(hostname)
|
HOSTNAME=$(hostname)
|
||||||
fi
|
fi
|
||||||
docker tag $CONTAINER_REGISTRY/$IMAGEREPO/$image $HOSTNAME:5000/$IMAGEREPO/$image >> "$LOG_FILE" 2>&1
|
docker tag $CONTAINER_REGISTRY/$IMAGEREPO/$image $HOSTNAME:5000/$IMAGEREPO/$image >> "$LOG_FILE" 2>&1 || {
|
||||||
docker push $HOSTNAME:5000/$IMAGEREPO/$image >> "$LOG_FILE" 2>&1
|
echo "Unable to tag $image" >> "$LOG_FILE" 2>&1
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
# Push to the embedded registry via a registry-to-registry copy. Avoids
|
||||||
|
# `docker push`, which on Docker 29.x with the containerd image store
|
||||||
|
# represents freshly-pulled images as an index whose layer content
|
||||||
|
# isn't reachable through the push path. The local `docker tag` above
|
||||||
|
# is preserved so so-image-pull's `:5000` existence check still works.
|
||||||
|
# Pin to the digest already gpg-verified above so we copy exactly the
|
||||||
|
# bytes we approved.
|
||||||
|
local VERIFIED_REF
|
||||||
|
VERIFIED_REF=$(echo "$DOCKERINSPECT" | jq -r ".[0].RepoDigests[] | select(. | contains(\"$CONTAINER_REGISTRY\"))" | head -n 1)
|
||||||
|
if [ -z "$VERIFIED_REF" ] || [ "$VERIFIED_REF" = "null" ]; then
|
||||||
|
echo "Unable to determine verified digest for $image" >> "$LOG_FILE" 2>&1
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
docker buildx imagetools create --tag $HOSTNAME:5000/$IMAGEREPO/$image "$VERIFIED_REF" >> "$LOG_FILE" 2>&1 || {
|
||||||
|
echo "Unable to copy $image to embedded registry" >> "$LOG_FILE" 2>&1
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "There is a problem downloading the $image image. Details: " >> "$LOG_FILE" 2>&1
|
echo "There is a problem downloading the $image image. Details: " >> "$LOG_FILE" 2>&1
|
||||||
|
|||||||
Executable
+243
@@ -0,0 +1,243 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
# Elastic License 2.0.
|
||||||
|
#
|
||||||
|
# so-kernel-upgrade — install the UEK8 (6.x) kernel and make it the boot default.
|
||||||
|
#
|
||||||
|
# Security Onion is moving off the EL9 stock kernel (RHCK, 5.14) and UEK7 (5.15) onto UEK8
|
||||||
|
# (6.x). Three things have to happen, and the tool has to drive each one:
|
||||||
|
#
|
||||||
|
# 1. Populate. The manager mirrors the UEK8 packages into /nsm/kernelrepo via so-repo-sync,
|
||||||
|
# and serves them to the grid over https://<manager>/kernelrepo. Until that sync runs the
|
||||||
|
# repo is valid but EMPTY -- dnf resolves it happily and installs nothing, with no error.
|
||||||
|
# 2. Install. A node on RHCK has no kernel-uek* package at all, so there is nothing for
|
||||||
|
# 'dnf update' to upgrade. A node on UEK7 does have kernel-uek installed, so
|
||||||
|
# 'dnf install kernel-uek' reports "Nothing to do" and exits 0 without installing 6.x.
|
||||||
|
# Both cases need an explicit install of the UEK8 NEVRA.
|
||||||
|
# 3. Boot it. Whether a newly installed UEK8 kernel becomes the boot default depends on the
|
||||||
|
# RUNNING kernel's flavor. kernel-install/grubby (with UPDATEDEFAULT=yes) only auto-promote
|
||||||
|
# within the running kernel's flavor lineage:
|
||||||
|
# - From UEK7 (5.x, kernel-uek) the install stays in the kernel-uek lineage and IS
|
||||||
|
# auto-promoted, so no grubby change is needed -- just make sure the repo is populated
|
||||||
|
# and install UEK8.
|
||||||
|
# - From the stock EL9 kernel (RHCK, 5.14, no UEK) it is a flavor CROSS that is NOT
|
||||||
|
# auto-promoted, so the box keeps booting RHCK until grubby is told otherwise.
|
||||||
|
# This tool inspects the running kernel and only runs 'grubby --set-default' for RHCK.
|
||||||
|
#
|
||||||
|
# Every one of those failure modes is silent by default. This tool handles each case and fails
|
||||||
|
# loudly when it cannot, rather than reporting success while changing nothing.
|
||||||
|
#
|
||||||
|
# Manager vs minion: only the manager owns /nsm/kernelrepo, so only the manager can populate
|
||||||
|
# it. If the repo is empty here, a manager runs so-repo-sync itself; a minion has no way to
|
||||||
|
# fix it and exits non-zero telling the admin to sync the manager first.
|
||||||
|
#
|
||||||
|
# Idempotent: an already-installed, already-default UEK8 kernel is left alone. It only sets
|
||||||
|
# the boot default; it does NOT reboot -- the admin reboots the node on their own schedule.
|
||||||
|
|
||||||
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
|
# Client-side repo id (what dnf enables on this node, from repo/client/oracle.sls) vs the
|
||||||
|
# reposync-side section in repodownload.conf that the manager mirrors from (mirrors the
|
||||||
|
# securityonion/securityonionsync split for the main repo).
|
||||||
|
KERNEL_REPO="securityonionkernel"
|
||||||
|
KERNEL_REPO_SYNC="securityonionkernelsync"
|
||||||
|
KERNEL_PKG="kernel-uek"
|
||||||
|
KERNEL_REPO_DIR="/nsm/kernelrepo"
|
||||||
|
REPOSYNC_CONF="/opt/so/conf/reposync/repodownload.conf"
|
||||||
|
GLOBAL_PILLAR="/opt/so/saltstack/local/pillar/global/soc_global.sls"
|
||||||
|
|
||||||
|
log() { echo "[so-kernel-upgrade] $*"; }
|
||||||
|
die() { echo "[so-kernel-upgrade] ERROR: $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
command -v grubby >/dev/null 2>&1 || die "grubby not found"
|
||||||
|
command -v dnf >/dev/null 2>&1 || die "dnf not found"
|
||||||
|
|
||||||
|
ARCH="$(rpm -E '%{_arch}')"
|
||||||
|
|
||||||
|
is_airgap() {
|
||||||
|
[ -f "$GLOBAL_PILLAR" ] && grep -q 'airgap: *[Tt]rue' "$GLOBAL_PILLAR"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Newest installed UEK8 (6.x) kernel known to the bootloader. UEK8 vmlinuz paths look like
|
||||||
|
# /boot/vmlinuz-6.12.0-204.92.4.2.el9uek.x86_64; UEK7 (5.15) and RHCK (5.14) won't match.
|
||||||
|
find_uek8() {
|
||||||
|
grubby --info=ALL 2>/dev/null \
|
||||||
|
| sed -n 's/^kernel="\(.*\)"$/\1/p' \
|
||||||
|
| grep -E '/vmlinuz-6\.[0-9]+.*uek' \
|
||||||
|
| sort -V | tail -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Classify the RUNNING kernel (uname -r) -- this, not what's installed, is what decides whether
|
||||||
|
# a UEK8 install auto-promotes to the boot default:
|
||||||
|
# uek8 6.x UEK already on the target line; nothing to do
|
||||||
|
# uek7 5.x UEK a UEK8 install stays in the kernel-uek lineage and auto-promotes (no grubby)
|
||||||
|
# rhck 5.14 EL9 crossing into the UEK flavor does NOT auto-promote (needs grubby --set-default)
|
||||||
|
running_flavor() {
|
||||||
|
case "$(uname -r)" in
|
||||||
|
6.*uek*) echo uek8 ;;
|
||||||
|
*uek*) echo uek7 ;;
|
||||||
|
*) echo rhck ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Newest UEK8 kernel-uek NEVRA offered by the kernel repo, empty if the repo has none.
|
||||||
|
# Restricted to the kernel repo so a UEK7 kernel-uek in the main repo can't be picked up,
|
||||||
|
# and filtered to 6.x so we never "succeed" by reinstalling the 5.15 we already have.
|
||||||
|
uek8_available() {
|
||||||
|
dnf -q repoquery --disablerepo='*' --enablerepo="$KERNEL_REPO" \
|
||||||
|
--arch="$ARCH" --latest-limit=1 \
|
||||||
|
--qf '%{name}-%{evr}.%{arch}\n' "$KERNEL_PKG" 2>/dev/null \
|
||||||
|
| grep -E "^${KERNEL_PKG}-6\." | tail -1
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelrepo_rpm_count() {
|
||||||
|
find "$KERNEL_REPO_DIR" -maxdepth 1 -name '*.rpm' 2>/dev/null | wc -l
|
||||||
|
}
|
||||||
|
|
||||||
|
# The kernel repo starts life as valid-but-empty (kernelrepo_init_empty in
|
||||||
|
# salt/manager/init.sls) and is filled by so-repo-sync. During a soup, so-repo-sync runs
|
||||||
|
# BEFORE the highstate deploys the [securityonionkernelsync] section into repodownload.conf, so
|
||||||
|
# the first kernel-aware soup leaves the repo empty until the next nightly sync.
|
||||||
|
sync_kernel_repo() {
|
||||||
|
if is_airgap; then
|
||||||
|
log "airgap install: $KERNEL_REPO_DIR is populated from the airgap ISO, not by so-repo-sync."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! grep -q "^\[${KERNEL_REPO_SYNC}\]" "$REPOSYNC_CONF" 2>/dev/null; then
|
||||||
|
log "$REPOSYNC_CONF has no [${KERNEL_REPO_SYNC}] section -- run a highstate to deploy it."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "populating $KERNEL_REPO_DIR with so-repo-sync (mirrors upstream; can take several minutes)"
|
||||||
|
su socore -c '/usr/sbin/so-repo-sync' || { log "so-repo-sync failed"; return 1; }
|
||||||
|
|
||||||
|
dnf -q clean expire-cache >/dev/null 2>&1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make the kernel repo actually able to serve a UEK8 package, or fail trying.
|
||||||
|
ensure_kernel_repo() {
|
||||||
|
# The repo is assigned by the repo.client highstate, and only once NICs are pinned by MAC
|
||||||
|
# (/opt/so/state/nic_names_pinned) so the kernel swap can't renumber interfaces SO binds
|
||||||
|
# by name. skip_if_unavailable=1 means a broken repo is silently ignored, so check first.
|
||||||
|
if ! dnf -q repolist --enabled 2>/dev/null | awk '{print $1}' | grep -qx "$KERNEL_REPO"; then
|
||||||
|
log "repo '$KERNEL_REPO' is not enabled on this node."
|
||||||
|
log "Run a highstate first; the repo is skipped until /opt/so/state/nic_names_pinned"
|
||||||
|
log "exists (run so-nic-pin) and this node's salt matches the version this release ships."
|
||||||
|
die "kernel repo unavailable"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -n "$(uek8_available)" ] && return 0
|
||||||
|
|
||||||
|
log "repo '$KERNEL_REPO' is enabled but offers no UEK8 $KERNEL_PKG package"
|
||||||
|
|
||||||
|
if ! is_manager_node; then
|
||||||
|
log "This is a minion; it consumes the kernel repo from the manager and cannot populate it."
|
||||||
|
log "On the manager, run: su socore -c /usr/sbin/so-repo-sync"
|
||||||
|
log "then re-run this script here."
|
||||||
|
die "manager's kernel repo is empty"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "this is a manager and $KERNEL_REPO_DIR holds $(kernelrepo_rpm_count) rpm(s)"
|
||||||
|
sync_kernel_repo || die "could not populate $KERNEL_REPO_DIR"
|
||||||
|
|
||||||
|
[ -n "$(uek8_available)" ] \
|
||||||
|
|| die "so-repo-sync completed but $KERNEL_REPO still offers no UEK8 $KERNEL_PKG"
|
||||||
|
}
|
||||||
|
|
||||||
|
reboot_notice() {
|
||||||
|
[ "$(uname -r)" = "$(basename "$1" | sed 's/^vmlinuz-//')" ] \
|
||||||
|
|| log "REBOOT REQUIRED to start using the UEK8 kernel (currently running $(uname -r))."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep future kernel updates on the UEK line rather than falling back to RHCK. Oracle ships
|
||||||
|
# /etc/sysconfig/kernel; only rewrite it when it's actually pointing somewhere else.
|
||||||
|
set_default_kernel_conf() {
|
||||||
|
if [ -f /etc/sysconfig/kernel ] && ! grep -q '^DEFAULTKERNEL=kernel-uek-core$' /etc/sysconfig/kernel; then
|
||||||
|
log "setting DEFAULTKERNEL=kernel-uek-core in /etc/sysconfig/kernel"
|
||||||
|
sed -i 's/^DEFAULTKERNEL=.*/DEFAULTKERNEL=kernel-uek-core/' /etc/sysconfig/kernel
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make sure a UEK8 kernel is installed, leaving its boot entry in INSTALLED_UEK8. If one is
|
||||||
|
# already present we leave the repo alone -- it may be disabled or empty and we don't need it
|
||||||
|
# just to flip the boot default. Otherwise install the explicit NEVRA, not the bare package
|
||||||
|
# name: on a UEK7 node 'dnf install kernel-uek' sees 5.15 already present, prints "Nothing to
|
||||||
|
# do" and exits 0 without installing 6.x.
|
||||||
|
ensure_uek8_installed() {
|
||||||
|
INSTALLED_UEK8="$(find_uek8)"
|
||||||
|
if [ -n "$INSTALLED_UEK8" ]; then
|
||||||
|
log "UEK8 kernel already installed: $INSTALLED_UEK8"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ensure_kernel_repo
|
||||||
|
local nevra; nevra="$(uek8_available)"
|
||||||
|
log "installing $nevra from $KERNEL_REPO"
|
||||||
|
dnf -y install "$nevra" || die "failed to install $nevra"
|
||||||
|
|
||||||
|
INSTALLED_UEK8="$(find_uek8)"
|
||||||
|
[ -n "$INSTALLED_UEK8" ] || die "$nevra installed but no 6.x UEK boot entry appeared -- check 'grubby --info=ALL'"
|
||||||
|
log "installed UEK8 kernel: $INSTALLED_UEK8"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$(running_flavor)" in
|
||||||
|
uek8)
|
||||||
|
# Already on the 6.x UEK line. A plain 'dnf update' keeps this node current within the
|
||||||
|
# lineage and auto-promotes newer builds, so there is nothing for this tool to do.
|
||||||
|
log "already running a UEK8 kernel ($(uname -r)); nothing to do."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
uek7)
|
||||||
|
# On a 5.x UEK kernel. Installing UEK8 stays inside the kernel-uek lineage, so dnf/grubby
|
||||||
|
# (UPDATEDEFAULT=yes) auto-promote it and we do NOT touch grubby. A node still on UEK7
|
||||||
|
# usually means the kernel repo was empty when it last updated, so populate it and install.
|
||||||
|
log "running UEK7 kernel ($(uname -r)); the kernel repo was likely not yet populated when"
|
||||||
|
log "this node last updated. Populating it and installing UEK8 -- the update stays on the"
|
||||||
|
log "kernel-uek line, so it becomes the boot default automatically (no grubby change needed)."
|
||||||
|
set_default_kernel_conf
|
||||||
|
ensure_uek8_installed
|
||||||
|
|
||||||
|
now="$(grubby --default-kernel 2>/dev/null)"
|
||||||
|
if [ "$now" = "$INSTALLED_UEK8" ]; then
|
||||||
|
log "boot default auto-promoted to UEK8 kernel: $INSTALLED_UEK8"
|
||||||
|
else
|
||||||
|
log "WARNING: expected the UEK8 kernel to auto-promote but the default is still"
|
||||||
|
log "'${now:-unknown}'. Run 'grubby --set-default=$INSTALLED_UEK8' to force it."
|
||||||
|
fi
|
||||||
|
reboot_notice "$INSTALLED_UEK8"
|
||||||
|
;;
|
||||||
|
|
||||||
|
rhck)
|
||||||
|
# On the stock EL9 kernel (5.14, no UEK installed). Crossing from RHCK into the UEK flavor
|
||||||
|
# does NOT auto-promote -- kernel-install/grubby only auto-promote within the running
|
||||||
|
# kernel's flavor lineage -- so after installing we must set the boot default explicitly.
|
||||||
|
log "running stock EL9 (RHCK) kernel ($(uname -r)); installing UEK8 and setting it as the"
|
||||||
|
log "boot default explicitly (a RHCK->UEK flavor change does not auto-promote)."
|
||||||
|
set_default_kernel_conf
|
||||||
|
ensure_uek8_installed
|
||||||
|
target="$INSTALLED_UEK8"
|
||||||
|
|
||||||
|
current="$(grubby --default-kernel 2>/dev/null)"
|
||||||
|
if [ "$current" = "$target" ]; then
|
||||||
|
log "UEK8 kernel is already the boot default: $target"
|
||||||
|
reboot_notice "$target"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "current default kernel: ${current:-unknown}"
|
||||||
|
log "switching boot default to UEK8 kernel: $target"
|
||||||
|
grubby --set-default="$target" || die "grubby --set-default failed for $target"
|
||||||
|
|
||||||
|
# Verify the change actually took before claiming success.
|
||||||
|
now="$(grubby --default-kernel 2>/dev/null)"
|
||||||
|
[ "$now" = "$target" ] || die "default kernel is still '${now:-unknown}' after set-default"
|
||||||
|
|
||||||
|
log "boot default is now $target"
|
||||||
|
reboot_notice "$target"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -129,6 +129,10 @@ if [[ $EXCLUDE_STARTUP_ERRORS == 'Y' ]]; then
|
|||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|responded with status-code 503" # telegraf getting 503 from ES during startup
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|responded with status-code 503" # telegraf getting 503 from ES during startup
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|process_cluster_event_timeout_exception" # logstash waiting for elasticsearch to start
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|process_cluster_event_timeout_exception" # logstash waiting for elasticsearch to start
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|not configured for GeoIP" # SO does not bundle the maxminddb with Zeek
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|not configured for GeoIP" # SO does not bundle the maxminddb with Zeek
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|HTTP 404: Not Found" # Salt loops until Kratos returns 200, during startup Kratos may not be ready
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Cancelling deferred write event maybeFenceReplicas because the event queue is now closed" # Kafka controller log during shutdown/restart
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Redis may have been restarted" # Redis likely restarted by salt
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|file already closed" # Go logging race condition during container restart
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then
|
if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then
|
||||||
@@ -159,7 +163,11 @@ if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then
|
|||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|adding ingest pipeline" # false positive (elasticsearch ingest pipeline names contain 'error')
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|adding ingest pipeline" # false positive (elasticsearch ingest pipeline names contain 'error')
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|updating index template" # false positive (elasticsearch index or template names contain 'error')
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|updating index template" # false positive (elasticsearch index or template names contain 'error')
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|updating component template" # false positive (elasticsearch index or template names contain 'error')
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|updating component template" # false positive (elasticsearch index or template names contain 'error')
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|upgrading component template" # false positive (elasticsearch index or template names contain 'error')
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|upgrading composable template" # false positive (elasticsearch composable template names contain 'error')
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|upgrading composable template" # false positive (elasticsearch composable template names contain 'error')
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Error while parsing document for index \[.ds-logs-kratos-so-.*object mapping for \[file\]" # false positive (mapping error occuring BEFORE kratos index has rolled over in 2.4.210)
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|No such container" # false positive (telegraf trying to run stats on an old container)
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|passwords do not match" # false positive (automated hydra test)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
||||||
@@ -175,7 +183,6 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
|||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|salt-minion-check" # bug in early 2.4 place Jinja script in non-jinja salt dir causing cron output errors
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|salt-minion-check" # bug in early 2.4 place Jinja script in non-jinja salt dir causing cron output errors
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|monitoring.metrics" # known issue with elastic agent casting the field incorrectly if an integer value shows up before a float
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|monitoring.metrics" # known issue with elastic agent casting the field incorrectly if an integer value shows up before a float
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|repodownload.conf" # known issue with reposync on pre-2.4.20
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|repodownload.conf" # known issue with reposync on pre-2.4.20
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|missing versions record" # stenographer corrupt index
|
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|soc.field." # known ingest type collisions issue with earlier versions of SO
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|soc.field." # known ingest type collisions issue with earlier versions of SO
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|error parsing signature" # Malformed Suricata rule, from upstream provider
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|error parsing signature" # Malformed Suricata rule, from upstream provider
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|sticky buffer has no matches" # Non-critical Suricata error
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|sticky buffer has no matches" # Non-critical Suricata error
|
||||||
@@ -223,6 +230,8 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
|||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|from NIC checksum offloading" # zeek reporter.log
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|from NIC checksum offloading" # zeek reporter.log
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|marked for removal" # docker container getting recycled
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|marked for removal" # docker container getting recycled
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|tcp 127.0.0.1:6791: bind: address already in use" # so-elastic-fleet agent restarting. Seen starting w/ 8.18.8 https://github.com/elastic/kibana/issues/201459
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|tcp 127.0.0.1:6791: bind: address already in use" # so-elastic-fleet agent restarting. Seen starting w/ 8.18.8 https://github.com/elastic/kibana/issues/201459
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|TransformTask\] \[logs-(tychon|aws_billing|microsoft_defender_endpoint|armis|o365_metrics|microsoft_sentinel|snyk|cyera|island_browser).*user so_kibana lacks the required permissions \[(logs|metrics)-\1" # Known issue with integrations starting transform jobs that are explicitly not allowed to start as a system user. This error should not be seen on fresh ES 9.3.3 installs or after SO 3.1.0 with soups addition of check_transform_health_and_reauthorize()
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|manifest unknown" # appears in so-dockerregistry log for so-tcpreplay following docker upgrade to 29.2.1-1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RESULT=0
|
RESULT=0
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# so-nic-pin — pin physical NIC names by permanent MAC via classic by-MAC udev
|
||||||
|
# rules, so a kernel upgrade can't renumber them.
|
||||||
|
#
|
||||||
|
# Security Onion binds its management and monitor interfaces BY NAME in pillar
|
||||||
|
# (host:mainint, sensor:mainint, and bond0 is built on a specific physical NIC).
|
||||||
|
# A kernel upgrade can change the kernel/systemd-udevd predictable-naming output
|
||||||
|
# and renumber those NICs (e.g. enp1s0 -> enp2s0), which breaks the grid: the
|
||||||
|
# pillar references a name that no longer exists and bond/bridge bring-up fails.
|
||||||
|
#
|
||||||
|
# This writes /etc/udev/rules.d/70-persistent-net.rules pinning each PHYSICAL NIC
|
||||||
|
# to its CURRENT name by its PERMANENT MAC, freezing the names across future kernel
|
||||||
|
# changes. It only writes the rules file; it does NOT live-trigger a rename (the
|
||||||
|
# rules apply on the next boot/kernel, and a live rename would be disruptive).
|
||||||
|
#
|
||||||
|
# Run-once: gated by the drop file /opt/so/state/nic_names_pinned. If the marker is
|
||||||
|
# present the script does nothing, so an admin can pre-create it to opt out. Invoked
|
||||||
|
# from the common state on every highstate; the marker keeps it a one-time setup.
|
||||||
|
|
||||||
|
NET_RULES_FILE="/etc/udev/rules.d/70-persistent-net.rules"
|
||||||
|
MARKER="/opt/so/state/nic_names_pinned"
|
||||||
|
|
||||||
|
log() { echo -e "[so-nic-pin] $*"; }
|
||||||
|
|
||||||
|
# Echo "<name> <permanent-mac>" for every PHYSICAL NIC. A physical NIC is backed by a
|
||||||
|
# real device (has device/driver), which excludes bond0/sobridge/docker0/veth*/lo whose
|
||||||
|
# MACs are dynamic and must never be pinned. The PERMANENT MAC is used (ethtool -P, with
|
||||||
|
# fallbacks), not the current one: an enslaved bond member's current MAC is rewritten to
|
||||||
|
# the bond's, so matching on it would be wrong/ambiguous.
|
||||||
|
physical_nics() {
|
||||||
|
local path n mac
|
||||||
|
for path in /sys/class/net/*; do
|
||||||
|
n="${path##*/}"
|
||||||
|
[ "$n" = "lo" ] && continue
|
||||||
|
[ -e "${path}/device/driver" ] || continue # real device only
|
||||||
|
mac="$(ethtool -P "$n" 2>/dev/null | awk '/Permanent address/{print $NF}')"
|
||||||
|
case "$mac" in ""|00:00:00:00:00:00) mac="$(cat "${path}/bonding_slave/perm_hwaddr" 2>/dev/null)" ;; esac
|
||||||
|
case "$mac" in ""|00:00:00:00:00:00) mac="$(cat "${path}/address" 2>/dev/null)" ;; esac
|
||||||
|
case "$mac" in ""|00:00:00:00:00:00) continue ;; esac
|
||||||
|
echo "$n $mac"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Turn "<name> <mac>" lines on stdin into classic by-MAC persistent-net udev rules.
|
||||||
|
render_net_rules() {
|
||||||
|
echo "# Generated by so-nic-pin: pin NIC names by MAC so kernel upgrades can't renumber them."
|
||||||
|
echo "# Security Onion binds its management/monitor interfaces by name; do not hand-edit."
|
||||||
|
local n mac
|
||||||
|
while read -r n mac; do
|
||||||
|
[ -n "$n" ] || continue
|
||||||
|
printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", NAME="%s"\n' \
|
||||||
|
"$mac" "$n"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$(id -u)" -eq 0 ] || exit 0 # salt runs us as root; bail quietly otherwise
|
||||||
|
[ -e "${MARKER}" ] && exit 0 # run-once guard (mirrors the state's unless)
|
||||||
|
|
||||||
|
nics="$(physical_nics)"
|
||||||
|
if [ -z "${nics}" ]; then
|
||||||
|
log "no physical NICs detected — nothing to pin (will retry on next highstate)"
|
||||||
|
exit 0 # do NOT drop the marker; let it retry later
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "pinning physical NICs by permanent MAC:"
|
||||||
|
echo "${nics}" | sed 's/^/ /'
|
||||||
|
|
||||||
|
[ -f "${NET_RULES_FILE}" ] && cp -f "${NET_RULES_FILE}" "${NET_RULES_FILE}.bak"
|
||||||
|
echo "${nics}" | render_net_rules > "${NET_RULES_FILE}" || {
|
||||||
|
log "ERROR: failed to write ${NET_RULES_FILE}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "${MARKER}")" && touch "${MARKER}"
|
||||||
|
log "wrote ${NET_RULES_FILE} ($(grep -c '^SUBSYSTEM' "${NET_RULES_FILE}") NIC(s) pinned); dropped ${MARKER}"
|
||||||
@@ -55,19 +55,22 @@ if [ $SKIP -ne 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
delete_pcap() {
|
delete_pcap() {
|
||||||
PCAP_DATA="/nsm/pcap/"
|
PCAP_DATA="/nsm/suripcap/"
|
||||||
[ -d $PCAP_DATA ] && so-pcap-stop && rm -rf $PCAP_DATA/* && so-pcap-start
|
[ -d $PCAP_DATA ] && rm -rf $PCAP_DATA/*
|
||||||
}
|
}
|
||||||
delete_suricata() {
|
delete_suricata() {
|
||||||
SURI_LOG="/nsm/suricata/"
|
SURI_LOG="/nsm/suricata/"
|
||||||
[ -d $SURI_LOG ] && so-suricata-stop && rm -rf $SURI_LOG/* && so-suricata-start
|
[ -d $SURI_LOG ] && rm -rf $SURI_LOG/*
|
||||||
}
|
}
|
||||||
delete_zeek() {
|
delete_zeek() {
|
||||||
ZEEK_LOG="/nsm/zeek/logs/"
|
ZEEK_LOG="/nsm/zeek/logs/"
|
||||||
[ -d $ZEEK_LOG ] && so-zeek-stop && rm -rf $ZEEK_LOG/* && so-zeek-start
|
[ -d $ZEEK_LOG ] && so-zeek-stop && rm -rf $ZEEK_LOG/* && so-zeek-start
|
||||||
}
|
}
|
||||||
|
|
||||||
|
so-suricata-stop
|
||||||
delete_pcap
|
delete_pcap
|
||||||
delete_suricata
|
delete_suricata
|
||||||
delete_zeek
|
delete_zeek
|
||||||
|
so-suricata-start
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,28 +5,44 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Usage: so-restart kibana | playbook
|
|
||||||
|
|
||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
if [ $# -ge 1 ]; then
|
usage() {
|
||||||
|
echo "Usage: $0 <component> [args]"
|
||||||
|
echo ""
|
||||||
|
echo "Supported args:"
|
||||||
|
echo " --force | -f Force stop all Salt jobs before starting component."
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " $0 kibana Restart Kibana"
|
||||||
|
echo " $0 kibana --force Force stop all Salt jobs before restarting Kibana"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
echo $banner
|
if [[ $# -lt 1 ]]; then
|
||||||
printf "Restarting $1...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n"
|
usage
|
||||||
echo $banner
|
|
||||||
|
|
||||||
if [ "$2" = "--force" ]; then
|
|
||||||
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
|
|
||||||
salt-call saltutil.kill_all_jobs
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
"steno") docker stop so-steno && docker rm so-steno && salt-call state.apply pcap queue=True;;
|
|
||||||
"elastic-fleet") docker stop so-elastic-fleet && docker rm so-elastic-fleet && salt-call state.apply elasticfleet queue=True;;
|
|
||||||
*) docker stop so-$1 ; docker rm so-$1 ; salt-call state.apply $1 queue=True;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo -e "\nPlease provide an argument by running like so-restart $component, or by using the component-specific script.\nEx. so-restart logstash, or so-logstash-restart\n"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#shellcheck disable=SC2154
|
||||||
|
echo "$banner"
|
||||||
|
printf "Restarting %s...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n" "$1"
|
||||||
|
echo "$banner"
|
||||||
|
if [[ "$2" = "--force" ]] || [[ "$2" = "-f" ]]; then
|
||||||
|
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
|
||||||
|
salt-call saltutil.kill_all_jobs
|
||||||
|
fi
|
||||||
|
case $1 in
|
||||||
|
"elastic-fleet"|"elasticfleet")
|
||||||
|
docker_check_running "elastic-fleet" "--stop"
|
||||||
|
docker rm "so-elastic-fleet" 2> /dev/null
|
||||||
|
# Removing the elastic fleet state directory, so that the next startup re-enrolls with a fresh policy
|
||||||
|
rm -rf /opt/so/conf/elastic-fleet/state
|
||||||
|
|
||||||
|
salt-call state.apply elasticfleet queue=True
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
docker_check_running "$1" "--stop"
|
||||||
|
docker rm "so-${1}" 2> /dev/null
|
||||||
|
salt-call state.apply "$1" queue=True
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ clean() {
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## Clean up extracted pcaps from Steno
|
## Clean up extracted pcaps
|
||||||
PCAPS='/nsm/pcapout'
|
PCAPS='/nsm/pcapout'
|
||||||
OLDEST_PCAP=$(find $PCAPS -type f -printf '%T+ %p\n' | sort -n | head -n 1)
|
OLDEST_PCAP=$(find $PCAPS -type f -printf '%T+ %p\n' | sort -n | head -n 1)
|
||||||
if [ -z "$OLDEST_PCAP" -o "$OLDEST_PCAP" == ".." -o "$OLDEST_PCAP" == "." ]; then
|
if [ -z "$OLDEST_PCAP" -o "$OLDEST_PCAP" == ".." -o "$OLDEST_PCAP" == "." ]; then
|
||||||
|
|||||||
@@ -5,28 +5,54 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
|
||||||
# Usage: so-start all | kibana | playbook
|
|
||||||
|
|
||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
if [ $# -ge 1 ]; then
|
usage() {
|
||||||
echo $banner
|
echo "Usage: $0 <component> [args]"
|
||||||
printf "Starting $1...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n"
|
echo ""
|
||||||
echo $banner
|
echo "Supported args:"
|
||||||
|
echo " --force | -f Force stop all Salt jobs before starting component."
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " $0 kibana Start Kibana"
|
||||||
|
echo " $0 kibana --force Force stop all Salt jobs before starting Kibana"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
if [ "$2" = "--force" ]; then
|
if [[ $# -lt 1 ]]; then
|
||||||
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
|
usage
|
||||||
salt-call saltutil.kill_all_jobs
|
|
||||||
fi
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
"all") salt-call state.highstate queue=True;;
|
|
||||||
"steno") if docker ps | grep -q so-$1; then printf "\n$1 is already running!\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply pcap queue=True; fi ;;
|
|
||||||
"elastic-fleet") if docker ps | grep -q so-$1; then printf "\n$1 is already running!\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply elasticfleet queue=True; fi ;;
|
|
||||||
*) if docker ps | grep -E -q '^so-$1$'; then printf "\n$1 is already running\n\n"; else docker rm so-$1 >/dev/null 2>&1 ; salt-call state.apply $1 queue=True; fi ;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo -e "\nPlease provide an argument by running like so-start $component, or by using the component-specific script.\nEx. so-start logstash, or so-logstash-start\n"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#shellcheck disable=SC2154
|
||||||
|
echo "$banner"
|
||||||
|
printf "Starting %s...\n\nThis could take a while if another Salt job is running. \nRun this command with --force to stop all Salt jobs before proceeding.\n" "$1"
|
||||||
|
echo "$banner"
|
||||||
|
if [[ "$2" = "--force" ]] || [[ "$2" == "-f" ]]; then
|
||||||
|
printf "\nForce-stopping all Salt jobs before proceeding\n\n"
|
||||||
|
salt-call saltutil.kill_all_jobs
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
"all")
|
||||||
|
salt-call state.highstate queue=True
|
||||||
|
;;
|
||||||
|
"elastic-fleet"|"elasticfleet")
|
||||||
|
if docker_check_running "elastic-fleet"; then
|
||||||
|
printf "\nso-%s is already running!\n\n" "elastic-fleet"
|
||||||
|
/usr/sbin/so-status
|
||||||
|
else
|
||||||
|
docker rm "so-elastic-fleet" 2> /dev/null
|
||||||
|
salt-call state.apply elasticfleet queue=True
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if docker_check_running "$1"; then
|
||||||
|
printf "\nso-%s is already running\n\n" "$1"
|
||||||
|
/usr/sbin/so-status
|
||||||
|
else
|
||||||
|
docker rm "so-${1}" 2> /dev/null
|
||||||
|
salt-call state.apply "$1" queue=True
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ def output(options, console, code, data):
|
|||||||
summary = { "status_code": code, "containers": data }
|
summary = { "status_code": code, "containers": data }
|
||||||
print(json.dumps(summary))
|
print(json.dumps(summary))
|
||||||
elif "-q" not in options:
|
elif "-q" not in options:
|
||||||
if code == 2:
|
if code == 99:
|
||||||
console.print(" [bold yellow]:hourglass: [bold white]System appears to be starting. No highstate has completed since the system was restarted.")
|
|
||||||
elif code == 99:
|
|
||||||
console.print(" [bold red]:exclamation: [bold white]Installation does not appear to be complete. A highstate has not fully completed.")
|
console.print(" [bold red]:exclamation: [bold white]Installation does not appear to be complete. A highstate has not fully completed.")
|
||||||
elif code == 100:
|
elif code == 100:
|
||||||
console.print(" [bold red]:exclamation: [bold white]Installation encountered errors.")
|
console.print(" [bold red]:exclamation: [bold white]Installation encountered errors.")
|
||||||
else:
|
else:
|
||||||
|
if code == 2:
|
||||||
|
console.print(" [bold yellow]:hourglass: [bold white]System appears to be starting. No highstate has completed since the system was restarted. Container status is shown below.")
|
||||||
table = Table(title = "Security Onion Status", show_edge = False, safe_box = True, box = box.MINIMAL)
|
table = Table(title = "Security Onion Status", show_edge = False, safe_box = True, box = box.MINIMAL)
|
||||||
table.add_column("Container", justify="right", style="white", no_wrap=True)
|
table.add_column("Container", justify="right", style="white", no_wrap=True)
|
||||||
table.add_column("Status", justify="left", style="green", no_wrap=True)
|
table.add_column("Status", justify="left", style="green", no_wrap=True)
|
||||||
@@ -154,8 +154,14 @@ def check_status(options, console):
|
|||||||
code = check_installation_status(options, console)
|
code = check_installation_status(options, console)
|
||||||
if code == 0:
|
if code == 0:
|
||||||
code = check_system_status(options, console)
|
code = check_system_status(options, console)
|
||||||
if code == 0:
|
# Containers now start on boot without a highstate, so gather/display their
|
||||||
code, container_list = check_container_status(options, console)
|
# status even when the system is still "starting" (code 2). Keep the starting
|
||||||
|
# code as the exit/status_code so SOC keeps showing the "restarting" message
|
||||||
|
# on the Grid until a highstate completes.
|
||||||
|
if code == 0 or code == 2:
|
||||||
|
container_code, container_list = check_container_status(options, console)
|
||||||
|
if code == 0:
|
||||||
|
code = container_code
|
||||||
output(options, console, code, container_list)
|
output(options, console, code, container_list)
|
||||||
return code
|
return code
|
||||||
|
|
||||||
@@ -180,4 +186,3 @@ def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,35 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
|
||||||
# Usage: so-stop kibana | playbook | thehive
|
|
||||||
|
|
||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
if [ $# -ge 1 ]; then
|
usage() {
|
||||||
echo $banner
|
echo "Usage: $0 <component>"
|
||||||
printf "Stopping $1...\n"
|
echo ""
|
||||||
echo $banner
|
echo "Examples:"
|
||||||
|
echo " $0 kibana Stop Kibana"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
case $1 in
|
if [[ $# -lt 1 ]]; then
|
||||||
*) docker stop so-$1 ; docker rm so-$1 ;;
|
usage
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo -e "\nPlease provide an argument by running like so-stop $component, or by using the component-specific script.\nEx. so-stop logstash, or so-logstash-stop\n"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#shellcheck disable=SC2154
|
||||||
|
echo "$banner"
|
||||||
|
printf "Stopping %s...\n" "$1"
|
||||||
|
echo "$banner"
|
||||||
|
case $1 in
|
||||||
|
"elasticfleet"|"elastic-fleet")
|
||||||
|
docker_check_running "elastic-fleet" "--stop"
|
||||||
|
docker rm "so-elastic-fleet" 2> /dev/null
|
||||||
|
# Removing the elastic fleet state directory, so that the next startup re-enrolls with a fresh policy
|
||||||
|
rm -rf /opt/so/conf/elastic-fleet/state
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
docker_check_running "$1" "--stop"
|
||||||
|
docker rm "so-${1}" 2> /dev/null
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
source /usr/sbin/so-common
|
source /usr/sbin/so-common
|
||||||
doc_desktop_url="$DOC_BASE_URL/desktop.html"
|
doc_desktop_url="$DOC_BASE_URL/desktop"
|
||||||
|
|
||||||
{# we only want the script to install the desktop if it is OEL -#}
|
{# we only want the script to install the desktop if it is OEL -#}
|
||||||
{% if grains.os == 'OEL' -%}
|
{% if grains.os == 'OEL' -%}
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ function status {
|
|||||||
function pcapinfo() {
|
function pcapinfo() {
|
||||||
PCAP=$1
|
PCAP=$1
|
||||||
ARGS=$2
|
ARGS=$2
|
||||||
docker run --rm -v "$PCAP:/input.pcap" --entrypoint capinfos {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-pcaptools:{{ VERSION }} /input.pcap -ae $ARGS
|
docker run --rm -v "$PCAP:/input.pcap" --entrypoint capinfos {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-pcaptools:{{ VERSION }} /input.pcap -ae $ARGS |\
|
||||||
|
sed 's/First packet/Earliest packet/g' | sed 's/Last packet/Latest packet/g'
|
||||||
}
|
}
|
||||||
|
|
||||||
function pcapfix() {
|
function pcapfix() {
|
||||||
@@ -85,7 +86,7 @@ function suricata() {
|
|||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v /opt/so/conf/suricata/suricata.yaml:/etc/suricata/suricata.yaml:ro \
|
-v /opt/so/conf/suricata/suricata.yaml:/etc/suricata/suricata.yaml:ro \
|
||||||
-v /opt/so/conf/suricata/threshold.conf:/etc/suricata/threshold.conf:ro \
|
-v /opt/so/conf/suricata/threshold.conf:/etc/suricata/threshold.conf:ro \
|
||||||
-v /opt/so/conf/suricata/rules:/etc/suricata/rules:ro \
|
-v /opt/so/rules/suricata/:/etc/suricata/rules:ro \
|
||||||
-v ${LOG_PATH}:/var/log/suricata/:rw \
|
-v ${LOG_PATH}:/var/log/suricata/:rw \
|
||||||
-v ${NSM_PATH}/:/nsm/:rw \
|
-v ${NSM_PATH}/:/nsm/:rw \
|
||||||
-v "$PCAP:/input.pcap:ro" \
|
-v "$PCAP:/input.pcap:ro" \
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
. /usr/sbin/so-common
|
. /usr/sbin/so-common
|
||||||
|
|
||||||
software_raid=("SOSMN" "SOSMN-DE02" "SOSSNNV" "SOSSNNV-DE02" "SOS10k-DE02" "SOS10KNV" "SOS10KNV-DE02" "SOS10KNV-DE02" "SOS2000-DE02" "SOS-GOFAST-LT-DE02" "SOS-GOFAST-MD-DE02" "SOS-GOFAST-HV-DE02")
|
software_raid=("SOSMN" "SOSMN-DE02" "SOSSNNV" "SOSSNNV-DE02" "SOS10k-DE02" "SOS10KNV" "SOS10KNV-DE02" "SOS10KNV-DE02" "SOS2000-DE02" "SOS-GOFAST-LT-DE02" "SOS-GOFAST-MD-DE02" "SOS-GOFAST-HV-DE02" "HVGUEST")
|
||||||
hardware_raid=("SOS1000" "SOS1000F" "SOSSN7200" "SOS5000" "SOS4000")
|
hardware_raid=("SOS1000" "SOS1000F" "SOSSN7200" "SOS5000" "SOS4000")
|
||||||
|
|
||||||
{%- if salt['grains.get']('sosmodel', '') %}
|
{%- if salt['grains.get']('sosmodel', '') %}
|
||||||
@@ -87,6 +87,11 @@ check_boss_raid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_software_raid() {
|
check_software_raid() {
|
||||||
|
if [[ ! -f /proc/mdstat ]]; then
|
||||||
|
SWRAID=0
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
SWRC=$(grep "_" /proc/mdstat)
|
SWRC=$(grep "_" /proc/mdstat)
|
||||||
if [[ -n $SWRC ]]; then
|
if [[ -n $SWRC ]]; then
|
||||||
# RAID is failed in some way
|
# RAID is failed in some way
|
||||||
@@ -107,7 +112,9 @@ if [[ "$is_hwraid" == "true" ]]; then
|
|||||||
fi
|
fi
|
||||||
if [[ "$is_softwareraid" == "true" ]]; then
|
if [[ "$is_softwareraid" == "true" ]]; then
|
||||||
check_software_raid
|
check_software_raid
|
||||||
check_boss_raid
|
if [ "$model" != "HVGUEST" ]; then
|
||||||
|
check_boss_raid
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sum=$(($SWRAID + $BOSSRAID + $HWRAID))
|
sum=$(($SWRAID + $BOSSRAID + $HWRAID))
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
{% import_yaml 'salt/minion.defaults.yaml' as SALT_MINION_DEFAULTS -%}
|
|
||||||
|
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
@@ -7,7 +5,7 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
{% from 'salt/schedule.map.jinja' import SCHEDULEMERGED %}
|
||||||
|
|
||||||
# this script checks the time the file /opt/so/log/salt/state-apply-test was last modified and restarts the salt-minion service if it is outside a threshold date/time
|
# this script checks the time the file /opt/so/log/salt/state-apply-test was last modified and restarts the salt-minion service if it is outside a threshold date/time
|
||||||
# the file is modified via file.touch using a scheduled job healthcheck.salt-minion.state-apply-test that runs a state.apply.
|
# the file is modified via file.touch using a scheduled job healthcheck.salt-minion.state-apply-test that runs a state.apply.
|
||||||
@@ -20,12 +18,14 @@
|
|||||||
|
|
||||||
QUIET=false
|
QUIET=false
|
||||||
UPTIME_REQ=1800 #in seconds, how long the box has to be up before considering restarting salt-minion due to /opt/so/log/salt/state-apply-test not being touched
|
UPTIME_REQ=1800 #in seconds, how long the box has to be up before considering restarting salt-minion due to /opt/so/log/salt/state-apply-test not being touched
|
||||||
|
HIGHSTATE_UPTIME_REQ=900 #in seconds; if the box has been up this long and no highstate has completed since boot, force one
|
||||||
CURRENT_TIME=$(date +%s)
|
CURRENT_TIME=$(date +%s)
|
||||||
SYSTEM_START_TIME=$(date -d "$(</proc/uptime awk '{print $1}') seconds ago" +%s)
|
SYSTEM_START_TIME=$(date -d "$(</proc/uptime awk '{print $1}') seconds ago" +%s)
|
||||||
LAST_HIGHSTATE_END=$([ -e "/opt/so/log/salt/lasthighstate" ] && date -r /opt/so/log/salt/lasthighstate +%s || echo 0)
|
LAST_HIGHSTATE_END=$([ -e "/opt/so/log/salt/lasthighstate" ] && date -r /opt/so/log/salt/lasthighstate +%s || echo 0)
|
||||||
LAST_HEALTHCHECK_STATE_APPLY=$([ -e "/opt/so/log/salt/state-apply-test" ] && date -r /opt/so/log/salt/state-apply-test +%s || echo 0)
|
LAST_HEALTHCHECK_STATE_APPLY=$([ -e "/opt/so/log/salt/state-apply-test" ] && date -r /opt/so/log/salt/state-apply-test +%s || echo 0)
|
||||||
# SETTING THRESHOLD TO ANYTHING UNDER 600 seconds may cause a lot of salt-minion restarts since the job to touch the file occurs every 5-8 minutes by default
|
# SETTING THRESHOLD TO ANYTHING UNDER 600 seconds may cause a lot of salt-minion restarts since the job to touch the file occurs every 5-8 minutes by default
|
||||||
THRESHOLD={{SALT_MINION_DEFAULTS.salt.minion.check_threshold}} #within how many seconds the file /opt/so/log/salt/state-apply-test must have been touched/modified before the salt minion is restarted
|
# THRESHOLD is derived from the salt schedule highstate interval + 1 hour, so the minion-check grace period tracks the schedule automatically.
|
||||||
|
THRESHOLD=$(( ({{ SCHEDULEMERGED.highstate_interval_hours }} + 1) * 3600 )) #within how many seconds the file /opt/so/log/salt/state-apply-test must have been touched/modified before the salt minion is restarted
|
||||||
THRESHOLD_DATE=$((LAST_HEALTHCHECK_STATE_APPLY+THRESHOLD))
|
THRESHOLD_DATE=$((LAST_HEALTHCHECK_STATE_APPLY+THRESHOLD))
|
||||||
|
|
||||||
logCmd() {
|
logCmd() {
|
||||||
@@ -77,24 +77,50 @@ done
|
|||||||
|
|
||||||
log "running so-salt-minion-check"
|
log "running so-salt-minion-check"
|
||||||
|
|
||||||
|
RESTARTED=false
|
||||||
|
|
||||||
|
# Check 1 (minion-restart-check): if the minion has stopped applying states (the
|
||||||
|
# state-apply-test healthcheck file has gone stale), restart the salt-minion service.
|
||||||
if [ $CURRENT_TIME -ge $((SYSTEM_START_TIME+$UPTIME_REQ)) ]; then
|
if [ $CURRENT_TIME -ge $((SYSTEM_START_TIME+$UPTIME_REQ)) ]; then
|
||||||
if [ $THRESHOLD_DATE -le $CURRENT_TIME ]; then
|
if [ $THRESHOLD_DATE -le $CURRENT_TIME ]; then
|
||||||
log "salt-minion is unable to apply states" E
|
log "[minion-restart-check] salt-minion is unable to apply states; restarting salt-minion" E
|
||||||
log "/opt/so/log/salt/healthcheck-state-apply not touched by required date: `date -d @$THRESHOLD_DATE`, last touched: `date -d @$LAST_HEALTHCHECK_STATE_APPLY`" I
|
log "[minion-restart-check] state-apply-test not touched by required date `date -d @$THRESHOLD_DATE`, last touched `date -d @$LAST_HEALTHCHECK_STATE_APPLY`" I
|
||||||
log "last highstate completed at `date -d @$LAST_HIGHSTATE_END`" I
|
log "[minion-restart-check] last highstate completed at `date -d @$LAST_HIGHSTATE_END`" I
|
||||||
log "checking if any jobs are running" I
|
log "[minion-restart-check] checking if any jobs are running" I
|
||||||
logCmd "salt-call --local saltutil.running" I
|
logCmd "salt-call --local saltutil.running" I
|
||||||
log "ensure salt.minion-state-apply-test is enabled" I
|
log "[minion-restart-check] ensure salt.minion-state-apply-test is enabled" I
|
||||||
logCmd "salt-call state.enable salt.minion-state-apply-test" I
|
logCmd "salt-call state.enable salt.minion-state-apply-test" I
|
||||||
log "ensure highstate is enabled" I
|
log "[minion-restart-check] ensure highstate is enabled" I
|
||||||
logCmd "salt-call state.enable highstate" I
|
logCmd "salt-call state.enable highstate" I
|
||||||
log "killing all salt-minion processes" I
|
log "[minion-restart-check] killing all salt-minion processes" I
|
||||||
logCmd "pkill -9 -ef /usr/bin/salt-minion" I
|
logCmd "pkill -9 -ef /usr/bin/salt-minion" I
|
||||||
log "starting salt-minion service" I
|
log "[minion-restart-check] starting salt-minion service" I
|
||||||
logCmd "systemctl start salt-minion" I
|
logCmd "systemctl start salt-minion" I
|
||||||
|
log "[minion-restart-check] waiting for salt-minion to become ready, then applying highstate in the background (queued)" I
|
||||||
|
nohup bash -c '/usr/sbin/so-salt-minion-wait; salt-call state.highstate queue=True' >> "/opt/so/log/salt/so-salt-minion-check" 2>&1 &
|
||||||
|
RESTARTED=true
|
||||||
else
|
else
|
||||||
log "/opt/so/log/salt/healthcheck-state-apply last touched: `date -d @$LAST_HEALTHCHECK_STATE_APPLY` must be touched by `date -d @$THRESHOLD_DATE` to avoid salt-minion restart" I
|
log "[minion-restart-check] healthy: state-apply-test last touched `date -d @$LAST_HEALTHCHECK_STATE_APPLY`, must go stale past `date -d @$THRESHOLD_DATE` to trigger a salt-minion restart" I
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log "system uptime only $((CURRENT_TIME-SYSTEM_START_TIME)) seconds does not meet $UPTIME_REQ second requirement." I
|
log "[minion-restart-check] skipped: system uptime $((CURRENT_TIME-SYSTEM_START_TIME))s is below the ${UPTIME_REQ}s minimum required before a salt-minion restart" I
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check 2 (boot-highstate-check): if the host has been up long enough but no highstate
|
||||||
|
# has completed since this boot, force one. This recovers a host whose boot highstate
|
||||||
|
# (so-boot-highstate.service) failed or was skipped, even while the minion is otherwise
|
||||||
|
# healthy (touching state-apply-test). We deliberately do NOT enable highstate here: if
|
||||||
|
# soup has disabled it during an upgrade, Salt will refuse the highstate and we avoid
|
||||||
|
# forcing one mid-upgrade.
|
||||||
|
if $RESTARTED; then
|
||||||
|
log "[boot-highstate-check] skipped: minion-restart-check already queued a highstate this run" I
|
||||||
|
elif [ $CURRENT_TIME -lt $((SYSTEM_START_TIME+HIGHSTATE_UPTIME_REQ)) ]; then
|
||||||
|
log "[boot-highstate-check] skipped: system uptime $((CURRENT_TIME-SYSTEM_START_TIME))s is below the ${HIGHSTATE_UPTIME_REQ}s minimum required before forcing a highstate" I
|
||||||
|
elif [ $LAST_HIGHSTATE_END -ge $SYSTEM_START_TIME ]; then
|
||||||
|
log "[boot-highstate-check] healthy: a highstate completed at `date -d @$LAST_HIGHSTATE_END`, after this boot at `date -d @$SYSTEM_START_TIME`" I
|
||||||
|
elif salt-call --local saltutil.running 2>/dev/null | grep -q 'state.highstate'; then
|
||||||
|
log "[boot-highstate-check] no highstate has completed since boot, but one is already running; skipping" I
|
||||||
|
else
|
||||||
|
log "[boot-highstate-check] no highstate has completed since boot after $((CURRENT_TIME-SYSTEM_START_TIME))s uptime; applying highstate" E
|
||||||
|
nohup bash -c 'salt-call state.highstate -l info queue=True' >> "/opt/so/log/salt/so-salt-minion-check" 2>&1 &
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
|
||||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
|
||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
|
||||||
# Elastic License 2.0.
|
|
||||||
|
|
||||||
so-curator:
|
|
||||||
docker_container.absent:
|
|
||||||
- force: True
|
|
||||||
|
|
||||||
so-curator_so-status.disabled:
|
|
||||||
file.line:
|
|
||||||
- name: /opt/so/conf/so-status/so-status.conf
|
|
||||||
- match: ^so-curator$
|
|
||||||
- mode: delete
|
|
||||||
|
|
||||||
so-curator-cluster-close:
|
|
||||||
cron.absent:
|
|
||||||
- identifier: so-curator-cluster-close
|
|
||||||
|
|
||||||
so-curator-cluster-delete:
|
|
||||||
cron.absent:
|
|
||||||
- identifier: so-curator-cluster-delete
|
|
||||||
|
|
||||||
delete_curator_configuration:
|
|
||||||
file.absent:
|
|
||||||
- name: /opt/so/conf/curator
|
|
||||||
- recurse: True
|
|
||||||
|
|
||||||
{% set files = salt.file.find(path='/usr/sbin', name='so-curator*') %}
|
|
||||||
{% if files|length > 0 %}
|
|
||||||
delete_curator_scripts:
|
|
||||||
file.absent:
|
|
||||||
- names: {{files|yaml}}
|
|
||||||
{% endif %}
|
|
||||||
@@ -3,29 +3,16 @@
|
|||||||
{# we only want this state to run it is CentOS #}
|
{# we only want this state to run it is CentOS #}
|
||||||
{% if GLOBALS.os == 'OEL' %}
|
{% if GLOBALS.os == 'OEL' %}
|
||||||
|
|
||||||
{% set global_ca_text = [] %}
|
|
||||||
{% set global_ca_server = [] %}
|
|
||||||
{% set manager = GLOBALS.manager %}
|
|
||||||
{% set x509dict = salt['mine.get'](manager | lower~'*', 'x509.get_pem_entries') %}
|
|
||||||
{% for host in x509dict %}
|
|
||||||
{% if host.split('_')|last in ['manager', 'managersearch', 'standalone', 'import', 'eval'] %}
|
|
||||||
{% do global_ca_text.append(x509dict[host].get('/etc/pki/ca.crt')|replace('\n', '')) %}
|
|
||||||
{% do global_ca_server.append(host) %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% set trusttheca_text = global_ca_text[0] %}
|
|
||||||
{% set ca_server = global_ca_server[0] %}
|
|
||||||
|
|
||||||
trusted_ca:
|
trusted_ca:
|
||||||
x509.pem_managed:
|
file.managed:
|
||||||
- name: /etc/pki/ca-trust/source/anchors/ca.crt
|
- name: /etc/pki/ca-trust/source/anchors/ca.crt
|
||||||
- text: {{ trusttheca_text }}
|
- source: salt://ca/files/ca.crt
|
||||||
|
|
||||||
update_ca_certs:
|
update_ca_certs:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
- name: update-ca-trust
|
- name: update-ca-trust
|
||||||
- onchanges:
|
- onchanges:
|
||||||
- x509: trusted_ca
|
- file: trusted_ca
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
docker:
|
docker:
|
||||||
range: '172.17.1.0/24'
|
range: '172.17.1.0/24'
|
||||||
gateway: '172.17.1.1'
|
gateway: '172.17.1.1'
|
||||||
|
ulimits:
|
||||||
|
- name: nofile
|
||||||
|
soft: 1048576
|
||||||
|
hard: 1048576
|
||||||
containers:
|
containers:
|
||||||
'so-dockerregistry':
|
'so-dockerregistry':
|
||||||
final_octet: 20
|
final_octet: 20
|
||||||
@@ -9,6 +13,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-elastic-fleet':
|
'so-elastic-fleet':
|
||||||
final_octet: 21
|
final_octet: 21
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -16,6 +21,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-elasticsearch':
|
'so-elasticsearch':
|
||||||
final_octet: 22
|
final_octet: 22
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -24,6 +30,16 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits:
|
||||||
|
- name: memlock
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
- name: nofile
|
||||||
|
soft: 65536
|
||||||
|
hard: 65536
|
||||||
|
- name: nproc
|
||||||
|
soft: 4096
|
||||||
|
hard: 4096
|
||||||
'so-influxdb':
|
'so-influxdb':
|
||||||
final_octet: 26
|
final_octet: 26
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -31,6 +47,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-kibana':
|
'so-kibana':
|
||||||
final_octet: 27
|
final_octet: 27
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -38,6 +55,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-kratos':
|
'so-kratos':
|
||||||
final_octet: 28
|
final_octet: 28
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -46,6 +64,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-hydra':
|
'so-hydra':
|
||||||
final_octet: 30
|
final_octet: 30
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -54,6 +73,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-logstash':
|
'so-logstash':
|
||||||
final_octet: 29
|
final_octet: 29
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -70,6 +90,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-nginx':
|
'so-nginx':
|
||||||
final_octet: 31
|
final_octet: 31
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -81,6 +102,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-nginx-fleet-node':
|
'so-nginx-fleet-node':
|
||||||
final_octet: 31
|
final_octet: 31
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -88,6 +110,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-redis':
|
'so-redis':
|
||||||
final_octet: 33
|
final_octet: 33
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -96,11 +119,13 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-sensoroni':
|
'so-sensoroni':
|
||||||
final_octet: 99
|
final_octet: 99
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-soc':
|
'so-soc':
|
||||||
final_octet: 34
|
final_octet: 34
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -108,16 +133,19 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-strelka-backend':
|
'so-strelka-backend':
|
||||||
final_octet: 36
|
final_octet: 36
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-strelka-filestream':
|
'so-strelka-filestream':
|
||||||
final_octet: 37
|
final_octet: 37
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-strelka-frontend':
|
'so-strelka-frontend':
|
||||||
final_octet: 38
|
final_octet: 38
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -125,11 +153,13 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-strelka-manager':
|
'so-strelka-manager':
|
||||||
final_octet: 39
|
final_octet: 39
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-strelka-gatekeeper':
|
'so-strelka-gatekeeper':
|
||||||
final_octet: 40
|
final_octet: 40
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -137,6 +167,7 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-strelka-coordinator':
|
'so-strelka-coordinator':
|
||||||
final_octet: 41
|
final_octet: 41
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -144,11 +175,13 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-elastalert':
|
'so-elastalert':
|
||||||
final_octet: 42
|
final_octet: 42
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-elastic-fleet-package-registry':
|
'so-elastic-fleet-package-registry':
|
||||||
final_octet: 44
|
final_octet: 44
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -156,11 +189,13 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-idh':
|
'so-idh':
|
||||||
final_octet: 45
|
final_octet: 45
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-elastic-agent':
|
'so-elastic-agent':
|
||||||
final_octet: 46
|
final_octet: 46
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -169,28 +204,28 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
'so-telegraf':
|
'so-telegraf':
|
||||||
final_octet: 99
|
final_octet: 99
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
'so-steno':
|
ulimits: []
|
||||||
final_octet: 99
|
|
||||||
custom_bind_mounts: []
|
|
||||||
extra_hosts: []
|
|
||||||
extra_env: []
|
|
||||||
'so-suricata':
|
'so-suricata':
|
||||||
final_octet: 99
|
final_octet: 99
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
ulimits:
|
ulimits: []
|
||||||
- memlock=524288000
|
|
||||||
'so-zeek':
|
'so-zeek':
|
||||||
final_octet: 99
|
final_octet: 99
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits:
|
||||||
|
- name: core
|
||||||
|
soft: 0
|
||||||
|
hard: 0
|
||||||
'so-kafka':
|
'so-kafka':
|
||||||
final_octet: 88
|
final_octet: 88
|
||||||
port_bindings:
|
port_bindings:
|
||||||
@@ -201,3 +236,12 @@ docker:
|
|||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
|
'so-postgres':
|
||||||
|
final_octet: 47
|
||||||
|
port_bindings:
|
||||||
|
- 0.0.0.0:5432:5432
|
||||||
|
custom_bind_mounts: []
|
||||||
|
extra_hosts: []
|
||||||
|
extra_env: []
|
||||||
|
ulimits: []
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{% import_yaml 'docker/defaults.yaml' as DOCKERDEFAULTS %}
|
{% import_yaml 'docker/defaults.yaml' as DOCKERDEFAULTS %}
|
||||||
{% set DOCKER = salt['pillar.get']('docker', DOCKERDEFAULTS.docker, merge=True) %}
|
{% set DOCKERMERGED = salt['pillar.get']('docker', DOCKERDEFAULTS.docker, merge=True) %}
|
||||||
{% set RANGESPLIT = DOCKER.range.split('.') %}
|
{% set RANGESPLIT = DOCKERMERGED.range.split('.') %}
|
||||||
{% set FIRSTTHREE = RANGESPLIT[0] ~ '.' ~ RANGESPLIT[1] ~ '.' ~ RANGESPLIT[2] ~ '.' %}
|
{% set FIRSTTHREE = RANGESPLIT[0] ~ '.' ~ RANGESPLIT[1] ~ '.' ~ RANGESPLIT[2] ~ '.' %}
|
||||||
|
|
||||||
{% for container, vals in DOCKER.containers.items() %}
|
{% for container, vals in DOCKERMERGED.containers.items() %}
|
||||||
{% do DOCKER.containers[container].update({'ip': FIRSTTHREE ~ DOCKER.containers[container].final_octet}) %}
|
{% do DOCKERMERGED.containers[container].update({'ip': FIRSTTHREE ~ DOCKERMERGED.containers[container].final_octet}) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED -%}
|
||||||
|
{
|
||||||
|
"registry-mirrors": [
|
||||||
|
"https://:5000"
|
||||||
|
],
|
||||||
|
"bip": "172.17.0.1/24",
|
||||||
|
"default-address-pools": [
|
||||||
|
{
|
||||||
|
"base": "172.17.0.0/24",
|
||||||
|
"size": 24
|
||||||
|
}
|
||||||
|
]
|
||||||
|
{%- if DOCKERMERGED.ulimits %},
|
||||||
|
"default-ulimits": {
|
||||||
|
{%- for ULIMIT in DOCKERMERGED.ulimits %}
|
||||||
|
"{{ ULIMIT.name }}": {
|
||||||
|
"Name": "{{ ULIMIT.name }}",
|
||||||
|
"Soft": {{ ULIMIT.soft }},
|
||||||
|
"Hard": {{ ULIMIT.hard }}
|
||||||
|
}{{ "," if not loop.last else "" }}
|
||||||
|
{%- endfor %}
|
||||||
|
}
|
||||||
|
{%- endif %}
|
||||||
|
}
|
||||||
+12
-48
@@ -3,61 +3,27 @@
|
|||||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
|
|
||||||
# include ssl since docker service requires the intca
|
# docker service requires the ca.crt
|
||||||
include:
|
include:
|
||||||
- ssl
|
- ca
|
||||||
|
|
||||||
dockergroup:
|
dockergroup:
|
||||||
group.present:
|
group.present:
|
||||||
- name: docker
|
- name: docker
|
||||||
- gid: 920
|
- gid: 920
|
||||||
|
|
||||||
{% if GLOBALS.os_family == 'Debian' %}
|
|
||||||
{% if grains.oscodename == 'bookworm' %}
|
|
||||||
dockerheldpackages:
|
dockerheldpackages:
|
||||||
pkg.installed:
|
pkg.installed:
|
||||||
- pkgs:
|
- pkgs:
|
||||||
- containerd.io: 1.7.21-1
|
- containerd.io: 2.2.1-1.el9
|
||||||
- docker-ce: 5:27.2.0-1~debian.12~bookworm
|
- docker-ce: 3:29.2.1-1.el9
|
||||||
- docker-ce-cli: 5:27.2.0-1~debian.12~bookworm
|
- docker-ce-cli: 1:29.2.1-1.el9
|
||||||
- docker-ce-rootless-extras: 5:27.2.0-1~debian.12~bookworm
|
- docker-ce-rootless-extras: 29.2.1-1.el9
|
||||||
- hold: True
|
- hold: True
|
||||||
- update_holds: True
|
- update_holds: True
|
||||||
{% elif grains.oscodename == 'jammy' %}
|
|
||||||
dockerheldpackages:
|
|
||||||
pkg.installed:
|
|
||||||
- pkgs:
|
|
||||||
- containerd.io: 1.7.21-1
|
|
||||||
- docker-ce: 5:27.2.0-1~ubuntu.22.04~jammy
|
|
||||||
- docker-ce-cli: 5:27.2.0-1~ubuntu.22.04~jammy
|
|
||||||
- docker-ce-rootless-extras: 5:27.2.0-1~ubuntu.22.04~jammy
|
|
||||||
- hold: True
|
|
||||||
- update_holds: True
|
|
||||||
{% else %}
|
|
||||||
dockerheldpackages:
|
|
||||||
pkg.installed:
|
|
||||||
- pkgs:
|
|
||||||
- containerd.io: 1.7.21-1
|
|
||||||
- docker-ce: 5:27.2.0-1~ubuntu.20.04~focal
|
|
||||||
- docker-ce-cli: 5:27.2.0-1~ubuntu.20.04~focal
|
|
||||||
- docker-ce-rootless-extras: 5:27.2.0-1~ubuntu.20.04~focal
|
|
||||||
- hold: True
|
|
||||||
- update_holds: True
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
dockerheldpackages:
|
|
||||||
pkg.installed:
|
|
||||||
- pkgs:
|
|
||||||
- containerd.io: 1.7.21-3.1.el9
|
|
||||||
- docker-ce: 3:27.2.0-1.el9
|
|
||||||
- docker-ce-cli: 1:27.2.0-1.el9
|
|
||||||
- docker-ce-rootless-extras: 27.2.0-1.el9
|
|
||||||
- hold: True
|
|
||||||
- update_holds: True
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
#disable docker from managing iptables
|
#disable docker from managing iptables
|
||||||
iptables_disabled:
|
iptables_disabled:
|
||||||
@@ -75,10 +41,9 @@ dockeretc:
|
|||||||
file.directory:
|
file.directory:
|
||||||
- name: /etc/docker
|
- name: /etc/docker
|
||||||
|
|
||||||
# Manager daemon.json
|
|
||||||
docker_daemon:
|
docker_daemon:
|
||||||
file.managed:
|
file.managed:
|
||||||
- source: salt://common/files/daemon.json
|
- source: salt://docker/files/daemon.json.jinja
|
||||||
- name: /etc/docker/daemon.json
|
- name: /etc/docker/daemon.json
|
||||||
- template: jinja
|
- template: jinja
|
||||||
|
|
||||||
@@ -89,10 +54,9 @@ docker_running:
|
|||||||
- enable: True
|
- enable: True
|
||||||
- watch:
|
- watch:
|
||||||
- file: docker_daemon
|
- file: docker_daemon
|
||||||
- x509: trusttheca
|
|
||||||
- require:
|
- require:
|
||||||
- file: docker_daemon
|
- file: docker_daemon
|
||||||
- x509: trusttheca
|
- file: trusttheca
|
||||||
|
|
||||||
|
|
||||||
# Reserve OS ports for Docker proxy in case boot settings are not already applied/present
|
# Reserve OS ports for Docker proxy in case boot settings are not already applied/present
|
||||||
@@ -110,12 +74,12 @@ dockerreserveports:
|
|||||||
sos_docker_net:
|
sos_docker_net:
|
||||||
docker_network.present:
|
docker_network.present:
|
||||||
- name: sobridge
|
- name: sobridge
|
||||||
- subnet: {{ DOCKER.range }}
|
- subnet: {{ DOCKERMERGED.range }}
|
||||||
- gateway: {{ DOCKER.gateway }}
|
- gateway: {{ DOCKERMERGED.gateway }}
|
||||||
- options:
|
- options:
|
||||||
com.docker.network.bridge.name: 'sobridge'
|
com.docker.network.bridge.name: 'sobridge'
|
||||||
com.docker.network.driver.mtu: '1500'
|
com.docker.network.driver.mtu: '1500'
|
||||||
com.docker.network.bridge.enable_ip_masquerade: 'true'
|
com.docker.network.bridge.enable_ip_masquerade: 'true'
|
||||||
com.docker.network.bridge.enable_icc: 'true'
|
com.docker.network.bridge.enable_icc: 'true'
|
||||||
com.docker.network.bridge.host_binding_ipv4: '0.0.0.0'
|
com.docker.network.bridge.host_binding_ipv4: '0.0.0.0'
|
||||||
- unless: 'docker network ls | grep sobridge'
|
- unless: ip l | grep sobridge
|
||||||
|
|||||||
+46
-45
@@ -1,44 +1,82 @@
|
|||||||
docker:
|
docker:
|
||||||
gateway:
|
gateway:
|
||||||
description: Gateway for the default docker interface.
|
description: Gateway for the default docker interface.
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
advanced: True
|
advanced: True
|
||||||
range:
|
range:
|
||||||
description: Default docker IP range for containers.
|
description: Default docker IP range for containers.
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
advanced: True
|
advanced: True
|
||||||
|
ulimits:
|
||||||
|
description: |
|
||||||
|
Default ulimit settings applied to all containers via the Docker daemon. Each entry specifies a resource name (e.g. nofile, memlock, core, nproc) with soft and hard limits. Individual container ulimits override these defaults. Valid resource names include: cpu, fsize, data, stack, core, rss, nproc, nofile, memlock, as, locks, sigpending, msgqueue, nice, rtprio, rttime.
|
||||||
|
forcedType: "[]{}"
|
||||||
|
syntax: json
|
||||||
|
advanced: True
|
||||||
|
helpLink: docker.html
|
||||||
|
uiElements:
|
||||||
|
- field: name
|
||||||
|
label: Resource Name
|
||||||
|
required: True
|
||||||
|
regex: ^(cpu|fsize|data|stack|core|rss|nproc|nofile|memlock|as|locks|sigpending|msgqueue|nice|rtprio|rttime)$
|
||||||
|
regexFailureMessage: You must enter a valid ulimit name (cpu, fsize, data, stack, core, rss, nproc, nofile, memlock, as, locks, sigpending, msgqueue, nice, rtprio, rttime).
|
||||||
|
- field: soft
|
||||||
|
label: Soft Limit
|
||||||
|
forcedType: int
|
||||||
|
- field: hard
|
||||||
|
label: Hard Limit
|
||||||
|
forcedType: int
|
||||||
containers:
|
containers:
|
||||||
so-dockerregistry: &dockerOptions
|
so-dockerregistry: &dockerOptions
|
||||||
final_octet:
|
final_octet:
|
||||||
description: Last octet of the container IP address.
|
description: Last octet of the container IP address.
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
readonly: True
|
readonly: True
|
||||||
advanced: True
|
advanced: True
|
||||||
global: True
|
global: True
|
||||||
port_bindings:
|
port_bindings:
|
||||||
description: List of port bindings for the container.
|
description: List of port bindings for the container.
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
advanced: True
|
advanced: True
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
custom_bind_mounts:
|
custom_bind_mounts:
|
||||||
description: List of custom local volume bindings.
|
description: List of custom local volume bindings.
|
||||||
advanced: True
|
advanced: True
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
description: List of additional host entries for the container.
|
description: List of additional host entries for the container.
|
||||||
advanced: True
|
advanced: True
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
extra_env:
|
extra_env:
|
||||||
description: List of additional ENV entries for the container.
|
description: List of additional ENV entries for the container.
|
||||||
advanced: True
|
advanced: True
|
||||||
helpLink: docker.html
|
helpLink: docker
|
||||||
multiline: True
|
multiline: True
|
||||||
forcedType: "[]string"
|
forcedType: "[]string"
|
||||||
|
ulimits:
|
||||||
|
description: |
|
||||||
|
Ulimit settings for the container. Each entry specifies a resource name (e.g. nofile, memlock, core, nproc) with optional soft and hard limits. Valid resource names include: cpu, fsize, data, stack, core, rss, nproc, nofile, memlock, as, locks, sigpending, msgqueue, nice, rtprio, rttime.
|
||||||
|
advanced: True
|
||||||
|
helpLink: docker.html
|
||||||
|
forcedType: "[]{}"
|
||||||
|
syntax: json
|
||||||
|
uiElements:
|
||||||
|
- field: name
|
||||||
|
label: Resource Name
|
||||||
|
required: True
|
||||||
|
regex: ^(cpu|fsize|data|stack|core|rss|nproc|nofile|memlock|as|locks|sigpending|msgqueue|nice|rtprio|rttime)$
|
||||||
|
regexFailureMessage: You must enter a valid ulimit name (cpu, fsize, data, stack, core, rss, nproc, nofile, memlock, as, locks, sigpending, msgqueue, nice, rtprio, rttime).
|
||||||
|
- field: soft
|
||||||
|
label: Soft Limit
|
||||||
|
forcedType: int
|
||||||
|
- field: hard
|
||||||
|
label: Hard Limit
|
||||||
|
forcedType: int
|
||||||
so-elastic-fleet: *dockerOptions
|
so-elastic-fleet: *dockerOptions
|
||||||
so-elasticsearch: *dockerOptions
|
so-elasticsearch: *dockerOptions
|
||||||
so-influxdb: *dockerOptions
|
so-influxdb: *dockerOptions
|
||||||
@@ -62,43 +100,6 @@ docker:
|
|||||||
so-idh: *dockerOptions
|
so-idh: *dockerOptions
|
||||||
so-elastic-agent: *dockerOptions
|
so-elastic-agent: *dockerOptions
|
||||||
so-telegraf: *dockerOptions
|
so-telegraf: *dockerOptions
|
||||||
so-steno: *dockerOptions
|
so-suricata: *dockerOptions
|
||||||
so-suricata:
|
|
||||||
final_octet:
|
|
||||||
description: Last octet of the container IP address.
|
|
||||||
helpLink: docker.html
|
|
||||||
readonly: True
|
|
||||||
advanced: True
|
|
||||||
global: True
|
|
||||||
port_bindings:
|
|
||||||
description: List of port bindings for the container.
|
|
||||||
helpLink: docker.html
|
|
||||||
advanced: True
|
|
||||||
multiline: True
|
|
||||||
forcedType: "[]string"
|
|
||||||
custom_bind_mounts:
|
|
||||||
description: List of custom local volume bindings.
|
|
||||||
advanced: True
|
|
||||||
helpLink: docker.html
|
|
||||||
multiline: True
|
|
||||||
forcedType: "[]string"
|
|
||||||
extra_hosts:
|
|
||||||
description: List of additional host entries for the container.
|
|
||||||
advanced: True
|
|
||||||
helpLink: docker.html
|
|
||||||
multiline: True
|
|
||||||
forcedType: "[]string"
|
|
||||||
extra_env:
|
|
||||||
description: List of additional ENV entries for the container.
|
|
||||||
advanced: True
|
|
||||||
helpLink: docker.html
|
|
||||||
multiline: True
|
|
||||||
forcedType: "[]string"
|
|
||||||
ulimits:
|
|
||||||
description: Ulimits for the container, in bytes.
|
|
||||||
advanced: True
|
|
||||||
helpLink: docker.html
|
|
||||||
multiline: True
|
|
||||||
forcedType: "[]string"
|
|
||||||
so-zeek: *dockerOptions
|
so-zeek: *dockerOptions
|
||||||
so-kafka: *dockerOptions
|
so-kafka: *dockerOptions
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
prune_images:
|
prune_images:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
- name: so-docker-prune
|
- name: so-docker-prune
|
||||||
- order: last
|
- onlyif: command -v /usr/sbin/so-docker-prune >/dev/null 2>&1
|
||||||
|
- order: 9000
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- elastalert.config
|
- elastalert.config
|
||||||
@@ -19,12 +19,13 @@ wait_for_elasticsearch:
|
|||||||
so-elastalert:
|
so-elastalert:
|
||||||
docker_container.running:
|
docker_container.running:
|
||||||
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastalert:{{ GLOBALS.so_version }}
|
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastalert:{{ GLOBALS.so_version }}
|
||||||
|
- restart_policy: unless-stopped
|
||||||
- hostname: elastalert
|
- hostname: elastalert
|
||||||
- name: so-elastalert
|
- name: so-elastalert
|
||||||
- user: so-elastalert
|
- user: so-elastalert
|
||||||
- networks:
|
- networks:
|
||||||
- sobridge:
|
- sobridge:
|
||||||
- ipv4_address: {{ DOCKER.containers['so-elastalert'].ip }}
|
- ipv4_address: {{ DOCKERMERGED.containers['so-elastalert'].ip }}
|
||||||
- detach: True
|
- detach: True
|
||||||
- binds:
|
- binds:
|
||||||
- /opt/so/rules/elastalert:/opt/elastalert/rules/:ro
|
- /opt/so/rules/elastalert:/opt/elastalert/rules/:ro
|
||||||
@@ -33,24 +34,30 @@ so-elastalert:
|
|||||||
- /opt/so/conf/elastalert/predefined/:/opt/elastalert/predefined/:ro
|
- /opt/so/conf/elastalert/predefined/:/opt/elastalert/predefined/:ro
|
||||||
- /opt/so/conf/elastalert/custom/:/opt/elastalert/custom/:ro
|
- /opt/so/conf/elastalert/custom/:/opt/elastalert/custom/:ro
|
||||||
- /opt/so/conf/elastalert/elastalert_config.yaml:/opt/elastalert/config.yaml:ro
|
- /opt/so/conf/elastalert/elastalert_config.yaml:/opt/elastalert/config.yaml:ro
|
||||||
{% if DOCKER.containers['so-elastalert'].custom_bind_mounts %}
|
{% if DOCKERMERGED.containers['so-elastalert'].custom_bind_mounts %}
|
||||||
{% for BIND in DOCKER.containers['so-elastalert'].custom_bind_mounts %}
|
{% for BIND in DOCKERMERGED.containers['so-elastalert'].custom_bind_mounts %}
|
||||||
- {{ BIND }}
|
- {{ BIND }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- extra_hosts:
|
- extra_hosts:
|
||||||
- {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }}
|
- {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }}
|
||||||
{% if DOCKER.containers['so-elastalert'].extra_hosts %}
|
{% if DOCKERMERGED.containers['so-elastalert'].extra_hosts %}
|
||||||
{% for XTRAHOST in DOCKER.containers['so-elastalert'].extra_hosts %}
|
{% for XTRAHOST in DOCKERMERGED.containers['so-elastalert'].extra_hosts %}
|
||||||
- {{ XTRAHOST }}
|
- {{ XTRAHOST }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if DOCKER.containers['so-elastalert'].extra_env %}
|
{% if DOCKERMERGED.containers['so-elastalert'].extra_env %}
|
||||||
- environment:
|
- environment:
|
||||||
{% for XTRAENV in DOCKER.containers['so-elastalert'].extra_env %}
|
{% for XTRAENV in DOCKERMERGED.containers['so-elastalert'].extra_env %}
|
||||||
- {{ XTRAENV }}
|
- {{ XTRAENV }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if DOCKERMERGED.containers['so-elastalert'].ulimits %}
|
||||||
|
- ulimits:
|
||||||
|
{% for ULIMIT in DOCKERMERGED.containers['so-elastalert'].ulimits %}
|
||||||
|
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
- require:
|
- require:
|
||||||
- cmd: wait_for_elasticsearch
|
- cmd: wait_for_elasticsearch
|
||||||
- file: elastarules
|
- file: elastarules
|
||||||
@@ -60,7 +67,7 @@ so-elastalert:
|
|||||||
- watch:
|
- watch:
|
||||||
- file: elastaconf
|
- file: elastaconf
|
||||||
- onlyif:
|
- onlyif:
|
||||||
- "so-elasticsearch-query / | jq -r '.version.number[0:1]' | grep -q 8" {# only run this state if elasticsearch is version 8 #}
|
- "so-elasticsearch-query / | jq -r '.version.number[0:1]' | grep -q 9" {# only run this state if elasticsearch is version 9 #}
|
||||||
|
|
||||||
delete_so-elastalert_so-status.disabled:
|
delete_so-elastalert_so-status.disabled:
|
||||||
file.uncomment:
|
file.uncomment:
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
THIS IS A PLACEHOLDER FILE
|
|
||||||
@@ -1,47 +1,48 @@
|
|||||||
elastalert:
|
elastalert:
|
||||||
enabled:
|
enabled:
|
||||||
description: Enables or disables the ElastAlert 2 process. This process is critical for ensuring alerts arrive in SOC, and for outbound notification delivery.
|
description: Enables or disables the ElastAlert 2 process. This process is critical for ensuring alerts arrive in SOC, and for outbound notification delivery.
|
||||||
helpLink: elastalert.html
|
forcedType: bool
|
||||||
|
helpLink: elastalert
|
||||||
alerter_parameters:
|
alerter_parameters:
|
||||||
title: Custom Configuration Parameters
|
title: Custom Configuration Parameters
|
||||||
description: Optional configuration parameters made available as defaults for all rules and alerters. Use YAML format for these parameters, and reference the ElastAlert 2 documentation, located at https://elastalert2.readthedocs.io, for available configuration parameters. Requires a valid Security Onion license key.
|
description: Optional configuration parameters made available as defaults for all rules and alerters. Use YAML format for these parameters, and reference the ElastAlert 2 documentation, located at https://elastalert2.readthedocs.io, for available configuration parameters. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
multiline: True
|
multiline: True
|
||||||
syntax: yaml
|
syntax: yaml
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
forcedType: string
|
forcedType: string
|
||||||
jira_api_key:
|
jira_api_key:
|
||||||
title: Jira API Key
|
title: Jira API Key
|
||||||
description: Optional configuration parameter for Jira API Key, used instead of the Jira username and password. Requires a valid Security Onion license key.
|
description: Optional configuration parameter for Jira API Key, used instead of the Jira username and password. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
sensitive: True
|
sensitive: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
forcedType: string
|
forcedType: string
|
||||||
jira_pass:
|
jira_pass:
|
||||||
title: Jira Password
|
title: Jira Password
|
||||||
description: Optional configuration parameter for Jira password. Requires a valid Security Onion license key.
|
description: Optional configuration parameter for Jira password. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
sensitive: True
|
sensitive: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
forcedType: string
|
forcedType: string
|
||||||
jira_user:
|
jira_user:
|
||||||
title: Jira Username
|
title: Jira Username
|
||||||
description: Optional configuration parameter for Jira username. Requires a valid Security Onion license key.
|
description: Optional configuration parameter for Jira username. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
forcedType: string
|
forcedType: string
|
||||||
smtp_pass:
|
smtp_pass:
|
||||||
title: SMTP Password
|
title: SMTP Password
|
||||||
description: Optional configuration parameter for SMTP password, required for authenticating email servers. Requires a valid Security Onion license key.
|
description: Optional configuration parameter for SMTP password, required for authenticating email servers. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
sensitive: True
|
sensitive: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
forcedType: string
|
forcedType: string
|
||||||
smtp_user:
|
smtp_user:
|
||||||
title: SMTP Username
|
title: SMTP Username
|
||||||
description: Optional configuration parameter for SMTP username, required for authenticating email servers. Requires a valid Security Onion license key.
|
description: Optional configuration parameter for SMTP username, required for authenticating email servers. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
forcedType: string
|
forcedType: string
|
||||||
files:
|
files:
|
||||||
custom:
|
custom:
|
||||||
@@ -49,91 +50,131 @@ elastalert:
|
|||||||
description: Optional custom Certificate Authority for connecting to an AlertManager server. To utilize this custom file, the alertmanager_ca_certs key must be set to /opt/elastalert/custom/alertmanager_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to an AlertManager server. To utilize this custom file, the alertmanager_ca_certs key must be set to /opt/elastalert/custom/alertmanager_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
gelf_ca__crt:
|
gelf_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to a Graylog server. To utilize this custom file, the graylog_ca_certs key must be set to /opt/elastalert/custom/graylog_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to a Graylog server. To utilize this custom file, the graylog_ca_certs key must be set to /opt/elastalert/custom/graylog_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
http_post_ca__crt:
|
http_post_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to a generic HTTP server, via the legacy HTTP POST alerter. To utilize this custom file, the http_post_ca_certs key must be set to /opt/elastalert/custom/http_post2_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to a generic HTTP server, via the legacy HTTP POST alerter. To utilize this custom file, the http_post_ca_certs key must be set to /opt/elastalert/custom/http_post2_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
http_post2_ca__crt:
|
http_post2_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to a generic HTTP server, via the newer HTTP POST 2 alerter. To utilize this custom file, the http_post2_ca_certs key must be set to /opt/elastalert/custom/http_post2_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to a generic HTTP server, via the newer HTTP POST 2 alerter. To utilize this custom file, the http_post2_ca_certs key must be set to /opt/elastalert/custom/http_post2_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
ms_teams_ca__crt:
|
ms_teams_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to Microsoft Teams server. To utilize this custom file, the ms_teams_ca_certs key must be set to /opt/elastalert/custom/ms_teams_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to Microsoft Teams server. To utilize this custom file, the ms_teams_ca_certs key must be set to /opt/elastalert/custom/ms_teams_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
pagerduty_ca__crt:
|
pagerduty_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to PagerDuty server. To utilize this custom file, the pagerduty_ca_certs key must be set to /opt/elastalert/custom/pagerduty_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to PagerDuty server. To utilize this custom file, the pagerduty_ca_certs key must be set to /opt/elastalert/custom/pagerduty_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
rocket_chat_ca__crt:
|
rocket_chat_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to PagerDuty server. To utilize this custom file, the rocket_chart_ca_certs key must be set to /opt/elastalert/custom/rocket_chat_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to PagerDuty server. To utilize this custom file, the rocket_chart_ca_certs key must be set to /opt/elastalert/custom/rocket_chat_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
smtp__crt:
|
smtp__crt:
|
||||||
description: Optional custom certificate for connecting to an SMTP server. To utilize this custom file, the smtp_cert_file key must be set to /opt/elastalert/custom/smtp.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom certificate for connecting to an SMTP server. To utilize this custom file, the smtp_cert_file key must be set to /opt/elastalert/custom/smtp.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
smtp__key:
|
smtp__key:
|
||||||
description: Optional custom certificate key for connecting to an SMTP server. To utilize this custom file, the smtp_key_file key must be set to /opt/elastalert/custom/smtp.key in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom certificate key for connecting to an SMTP server. To utilize this custom file, the smtp_key_file key must be set to /opt/elastalert/custom/smtp.key in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
slack_ca__crt:
|
slack_ca__crt:
|
||||||
description: Optional custom Certificate Authority for connecting to Slack. To utilize this custom file, the slack_ca_certs key must be set to /opt/elastalert/custom/slack_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
description: Optional custom Certificate Authority for connecting to Slack. To utilize this custom file, the slack_ca_certs key must be set to /opt/elastalert/custom/slack_ca.crt in the Alerter Parameters setting. Requires a valid Security Onion license key.
|
||||||
global: True
|
global: True
|
||||||
file: True
|
file: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
config:
|
config:
|
||||||
|
scan_subdirectories:
|
||||||
|
description: Recursively scan subdirectories for rules.
|
||||||
|
forcedType: bool
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
helpLink: elastalert
|
||||||
disable_rules_on_error:
|
disable_rules_on_error:
|
||||||
description: Disable rules on failure.
|
description: Disable rules on failure.
|
||||||
|
forcedType: bool
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
run_every:
|
run_every:
|
||||||
minutes:
|
minutes:
|
||||||
description: Amount of time in minutes between searches.
|
description: Amount of time in minutes between searches.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
buffer_time:
|
buffer_time:
|
||||||
minutes:
|
minutes:
|
||||||
description: Amount of time in minutes to look through.
|
description: Amount of time in minutes to look through.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
old_query_limit:
|
old_query_limit:
|
||||||
minutes:
|
minutes:
|
||||||
description: Amount of time in minutes between queries to start at the most recently run query.
|
description: Amount of time in minutes between queries to start at the most recently run query.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
es_conn_timeout:
|
es_conn_timeout:
|
||||||
description: Timeout in seconds for connecting to and reading from Elasticsearch.
|
description: Timeout in seconds for connecting to and reading from Elasticsearch.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
max_query_size:
|
max_query_size:
|
||||||
description: The maximum number of documents that will be returned from Elasticsearch in a single query.
|
description: The maximum number of documents that will be returned from Elasticsearch in a single query.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
|
use_ssl:
|
||||||
|
description: Use SSL to connect to Elasticsearch.
|
||||||
|
forcedType: bool
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
helpLink: elastalert
|
||||||
|
verify_certs:
|
||||||
|
description: Verify TLS certificates when connecting to Elasticsearch.
|
||||||
|
forcedType: bool
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
helpLink: elastalert
|
||||||
alert_time_limit:
|
alert_time_limit:
|
||||||
days:
|
days:
|
||||||
description: The retry window for failed alerts.
|
description: The retry window for failed alerts.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
index_settings:
|
index_settings:
|
||||||
shards:
|
shards:
|
||||||
description: The number of shards for elastalert indices.
|
description: The number of shards for elastalert indices.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
replicas:
|
replicas:
|
||||||
description: The number of replicas for elastalert indices.
|
description: The number of replicas for elastalert indices.
|
||||||
global: True
|
global: True
|
||||||
helpLink: elastalert.html
|
helpLink: elastalert
|
||||||
|
logging:
|
||||||
|
incremental:
|
||||||
|
description: When incremental is false (the default), the logging configuration is applied in full, replacing any existing logging setup. When true, only the level attributes of existing loggers and handlers are updated, leaving the rest of the logging configuration unchanged.
|
||||||
|
forcedType: bool
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
helpLink: elastalert
|
||||||
|
disable_existing_loggers:
|
||||||
|
description: Disable existing loggers.
|
||||||
|
forcedType: bool
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
helpLink: elastalert
|
||||||
|
loggers:
|
||||||
|
'':
|
||||||
|
propagate:
|
||||||
|
description: Propagate log messages to parent loggers.
|
||||||
|
forcedType: bool
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
helpLink: elastalert
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- elastic-fleet-package-registry.config
|
- elastic-fleet-package-registry.config
|
||||||
@@ -15,36 +15,53 @@ include:
|
|||||||
so-elastic-fleet-package-registry:
|
so-elastic-fleet-package-registry:
|
||||||
docker_container.running:
|
docker_container.running:
|
||||||
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-fleet-package-registry:{{ GLOBALS.so_version }}
|
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-fleet-package-registry:{{ GLOBALS.so_version }}
|
||||||
|
- restart_policy: unless-stopped
|
||||||
- name: so-elastic-fleet-package-registry
|
- name: so-elastic-fleet-package-registry
|
||||||
- hostname: Fleet-package-reg-{{ GLOBALS.hostname }}
|
- hostname: Fleet-package-reg-{{ GLOBALS.hostname }}
|
||||||
- detach: True
|
- detach: True
|
||||||
- user: 948
|
- user: 948
|
||||||
- networks:
|
- networks:
|
||||||
- sobridge:
|
- sobridge:
|
||||||
- ipv4_address: {{ DOCKER.containers['so-elastic-fleet-package-registry'].ip }}
|
- ipv4_address: {{ DOCKERMERGED.containers['so-elastic-fleet-package-registry'].ip }}
|
||||||
- extra_hosts:
|
- extra_hosts:
|
||||||
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
|
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
|
||||||
{% if DOCKER.containers['so-elastic-fleet-package-registry'].extra_hosts %}
|
{% if DOCKERMERGED.containers['so-elastic-fleet-package-registry'].extra_hosts %}
|
||||||
{% for XTRAHOST in DOCKER.containers['so-elastic-fleet-package-registry'].extra_hosts %}
|
{% for XTRAHOST in DOCKERMERGED.containers['so-elastic-fleet-package-registry'].extra_hosts %}
|
||||||
- {{ XTRAHOST }}
|
- {{ XTRAHOST }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- port_bindings:
|
- port_bindings:
|
||||||
{% for BINDING in DOCKER.containers['so-elastic-fleet-package-registry'].port_bindings %}
|
{% for BINDING in DOCKERMERGED.containers['so-elastic-fleet-package-registry'].port_bindings %}
|
||||||
- {{ BINDING }}
|
- {{ BINDING }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if DOCKER.containers['so-elastic-fleet-package-registry'].custom_bind_mounts %}
|
{% if DOCKERMERGED.containers['so-elastic-fleet-package-registry'].custom_bind_mounts %}
|
||||||
- binds:
|
- binds:
|
||||||
{% for BIND in DOCKER.containers['so-elastic-fleet-package-registry'].custom_bind_mounts %}
|
{% for BIND in DOCKERMERGED.containers['so-elastic-fleet-package-registry'].custom_bind_mounts %}
|
||||||
- {{ BIND }}
|
- {{ BIND }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if DOCKER.containers['so-elastic-fleet-package-registry'].extra_env %}
|
{% if DOCKERMERGED.containers['so-elastic-fleet-package-registry'].extra_env %}
|
||||||
- environment:
|
- environment:
|
||||||
{% for XTRAENV in DOCKER.containers['so-elastic-fleet-package-registry'].extra_env %}
|
{% for XTRAENV in DOCKERMERGED.containers['so-elastic-fleet-package-registry'].extra_env %}
|
||||||
- {{ XTRAENV }}
|
- {{ XTRAENV }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if DOCKERMERGED.containers['so-elastic-fleet-package-registry'].ulimits %}
|
||||||
|
- ulimits:
|
||||||
|
{% for ULIMIT in DOCKERMERGED.containers['so-elastic-fleet-package-registry'].ulimits %}
|
||||||
|
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
wait_for_so-elastic-fleet-package-registry:
|
||||||
|
http.wait_for_successful_query:
|
||||||
|
- name: "http://localhost:8080/health"
|
||||||
|
- status: 200
|
||||||
|
- wait_for: 300
|
||||||
|
- request_interval: 15
|
||||||
|
- require:
|
||||||
|
- docker_container: so-elastic-fleet-package-registry
|
||||||
|
|
||||||
delete_so-elastic-fleet-package-registry_so-status.disabled:
|
delete_so-elastic-fleet-package-registry_so-status.disabled:
|
||||||
file.uncomment:
|
file.uncomment:
|
||||||
- name: /opt/so/conf/so-status/so-status.conf
|
- name: /opt/so/conf/so-status/so-status.conf
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
elastic_fleet_package_registry:
|
elastic_fleet_package_registry:
|
||||||
enabled:
|
enabled:
|
||||||
description: Enables or disables the Fleet package registry process. This process must remain enabled to allow Elastic Agent packages to be updated.
|
description: Enables or disables the Fleet package registry process. This process must remain enabled to allow Elastic Agent packages to be updated.
|
||||||
|
forcedType: bool
|
||||||
advanced: True
|
advanced: True
|
||||||
|
|||||||
@@ -6,32 +6,34 @@
|
|||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
- ca
|
||||||
- elasticagent.config
|
- elasticagent.config
|
||||||
- elasticagent.sostatus
|
- elasticagent.sostatus
|
||||||
|
|
||||||
so-elastic-agent:
|
so-elastic-agent:
|
||||||
docker_container.running:
|
docker_container.running:
|
||||||
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }}
|
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }}
|
||||||
|
- restart_policy: unless-stopped
|
||||||
- name: so-elastic-agent
|
- name: so-elastic-agent
|
||||||
- hostname: {{ GLOBALS.hostname }}
|
- hostname: {{ GLOBALS.hostname }}
|
||||||
- detach: True
|
- detach: True
|
||||||
- user: 949
|
- user: 949
|
||||||
- networks:
|
- networks:
|
||||||
- sobridge:
|
- sobridge:
|
||||||
- ipv4_address: {{ DOCKER.containers['so-elastic-agent'].ip }}
|
- ipv4_address: {{ DOCKERMERGED.containers['so-elastic-agent'].ip }}
|
||||||
- extra_hosts:
|
- extra_hosts:
|
||||||
- {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }}
|
- {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }}
|
||||||
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
|
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
|
||||||
{% if DOCKER.containers['so-elastic-agent'].extra_hosts %}
|
{% if DOCKERMERGED.containers['so-elastic-agent'].extra_hosts %}
|
||||||
{% for XTRAHOST in DOCKER.containers['so-elastic-agent'].extra_hosts %}
|
{% for XTRAHOST in DOCKERMERGED.containers['so-elastic-agent'].extra_hosts %}
|
||||||
- {{ XTRAHOST }}
|
- {{ XTRAHOST }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- port_bindings:
|
- port_bindings:
|
||||||
{% for BINDING in DOCKER.containers['so-elastic-agent'].port_bindings %}
|
{% for BINDING in DOCKERMERGED.containers['so-elastic-agent'].port_bindings %}
|
||||||
- {{ BINDING }}
|
- {{ BINDING }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
- binds:
|
- binds:
|
||||||
@@ -40,23 +42,31 @@ so-elastic-agent:
|
|||||||
- /etc/pki/tls/certs/intca.crt:/etc/pki/tls/certs/intca.crt:ro
|
- /etc/pki/tls/certs/intca.crt:/etc/pki/tls/certs/intca.crt:ro
|
||||||
- /nsm:/nsm:ro
|
- /nsm:/nsm:ro
|
||||||
- /opt/so/log:/opt/so/log:ro
|
- /opt/so/log:/opt/so/log:ro
|
||||||
{% if DOCKER.containers['so-elastic-agent'].custom_bind_mounts %}
|
{% if DOCKERMERGED.containers['so-elastic-agent'].custom_bind_mounts %}
|
||||||
{% for BIND in DOCKER.containers['so-elastic-agent'].custom_bind_mounts %}
|
{% for BIND in DOCKERMERGED.containers['so-elastic-agent'].custom_bind_mounts %}
|
||||||
- {{ BIND }}
|
- {{ BIND }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- environment:
|
- environment:
|
||||||
- FLEET_CA=/etc/pki/tls/certs/intca.crt
|
- FLEET_CA=/etc/pki/tls/certs/intca.crt
|
||||||
- LOGS_PATH=logs
|
- LOGS_PATH=logs
|
||||||
{% if DOCKER.containers['so-elastic-agent'].extra_env %}
|
{% if DOCKERMERGED.containers['so-elastic-agent'].extra_env %}
|
||||||
{% for XTRAENV in DOCKER.containers['so-elastic-agent'].extra_env %}
|
{% for XTRAENV in DOCKERMERGED.containers['so-elastic-agent'].extra_env %}
|
||||||
- {{ XTRAENV }}
|
- {{ XTRAENV }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if DOCKERMERGED.containers['so-elastic-agent'].ulimits %}
|
||||||
|
- ulimits:
|
||||||
|
{% for ULIMIT in DOCKERMERGED.containers['so-elastic-agent'].ulimits %}
|
||||||
|
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
- require:
|
- require:
|
||||||
- file: create-elastic-agent-config
|
- file: create-elastic-agent-config
|
||||||
|
- file: trusttheca
|
||||||
- watch:
|
- watch:
|
||||||
- file: create-elastic-agent-config
|
- file: create-elastic-agent-config
|
||||||
|
- file: trusttheca
|
||||||
|
|
||||||
delete_so-elastic-agent_so-status.disabled:
|
delete_so-elastic-agent_so-status.disabled:
|
||||||
file.uncomment:
|
file.uncomment:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{%- set ES_PASS = salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:pass', '') %}
|
{%- set ES_PASS = salt['pillar.get']('elasticsearch:auth:users:so_elastic_user:pass', '') %}
|
||||||
|
|
||||||
id: aea1ba80-1065-11ee-a369-97538913b6a9
|
id: aea1ba80-1065-11ee-a369-97538913b6a9
|
||||||
revision: 1
|
revision: 4
|
||||||
outputs:
|
outputs:
|
||||||
default:
|
default:
|
||||||
type: elasticsearch
|
type: elasticsearch
|
||||||
@@ -22,242 +22,133 @@ agent:
|
|||||||
metrics: false
|
metrics: false
|
||||||
features: {}
|
features: {}
|
||||||
inputs:
|
inputs:
|
||||||
- id: logfile-logs-fefef78c-422f-4cfa-8abf-4cd1b9428f62
|
- id: filestream-filestream-85820eb0-25ef-11f0-a18d-1b26f69b8310
|
||||||
name: import-evtx-logs
|
|
||||||
revision: 2
|
|
||||||
type: logfile
|
|
||||||
use_output: default
|
|
||||||
meta:
|
|
||||||
package:
|
|
||||||
name: log
|
|
||||||
version:
|
|
||||||
data_stream:
|
|
||||||
namespace: so
|
|
||||||
package_policy_id: fefef78c-422f-4cfa-8abf-4cd1b9428f62
|
|
||||||
streams:
|
|
||||||
- id: logfile-log.log-fefef78c-422f-4cfa-8abf-4cd1b9428f62
|
|
||||||
data_stream:
|
|
||||||
dataset: import
|
|
||||||
paths:
|
|
||||||
- /nsm/import/*/evtx/*.json
|
|
||||||
processors:
|
|
||||||
- dissect:
|
|
||||||
field: log.file.path
|
|
||||||
tokenizer: '/nsm/import/%{import.id}/evtx/%{import.file}'
|
|
||||||
target_prefix: ''
|
|
||||||
- decode_json_fields:
|
|
||||||
fields:
|
|
||||||
- message
|
|
||||||
target: ''
|
|
||||||
- drop_fields:
|
|
||||||
ignore_missing: true
|
|
||||||
fields:
|
|
||||||
- host
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: system.security
|
|
||||||
type: logs
|
|
||||||
namespace: default
|
|
||||||
target: data_stream
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: system.security
|
|
||||||
module: system
|
|
||||||
imported: true
|
|
||||||
target: event
|
|
||||||
- then:
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: windows.sysmon_operational
|
|
||||||
target: data_stream
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: windows.sysmon_operational
|
|
||||||
module: windows
|
|
||||||
imported: true
|
|
||||||
target: event
|
|
||||||
if:
|
|
||||||
equals:
|
|
||||||
winlog.channel: Microsoft-Windows-Sysmon/Operational
|
|
||||||
- then:
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: system.application
|
|
||||||
target: data_stream
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: system.application
|
|
||||||
target: event
|
|
||||||
if:
|
|
||||||
equals:
|
|
||||||
winlog.channel: Application
|
|
||||||
- then:
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: system.system
|
|
||||||
target: data_stream
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: system.system
|
|
||||||
target: event
|
|
||||||
if:
|
|
||||||
equals:
|
|
||||||
winlog.channel: System
|
|
||||||
- then:
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: windows.powershell_operational
|
|
||||||
target: data_stream
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
dataset: windows.powershell_operational
|
|
||||||
module: windows
|
|
||||||
target: event
|
|
||||||
if:
|
|
||||||
equals:
|
|
||||||
winlog.channel: Microsoft-Windows-PowerShell/Operational
|
|
||||||
tags:
|
|
||||||
- import
|
|
||||||
- id: logfile-redis-fc98c947-7d17-4861-a318-7ad075f6d1b0
|
|
||||||
name: redis-logs
|
|
||||||
revision: 2
|
|
||||||
type: logfile
|
|
||||||
use_output: default
|
|
||||||
meta:
|
|
||||||
package:
|
|
||||||
name: redis
|
|
||||||
version:
|
|
||||||
data_stream:
|
|
||||||
namespace: default
|
|
||||||
package_policy_id: fc98c947-7d17-4861-a318-7ad075f6d1b0
|
|
||||||
streams:
|
|
||||||
- id: logfile-redis.log-fc98c947-7d17-4861-a318-7ad075f6d1b0
|
|
||||||
data_stream:
|
|
||||||
dataset: redis.log
|
|
||||||
type: logs
|
|
||||||
exclude_files:
|
|
||||||
- .gz$
|
|
||||||
paths:
|
|
||||||
- /opt/so/log/redis/redis.log
|
|
||||||
tags:
|
|
||||||
- redis-log
|
|
||||||
exclude_lines:
|
|
||||||
- '^\s+[\-`(''.|_]'
|
|
||||||
- id: logfile-logs-3b56803d-5ade-4c93-b25e-9b37182f66b8
|
|
||||||
name: import-suricata-logs
|
name: import-suricata-logs
|
||||||
revision: 2
|
revision: 3
|
||||||
type: logfile
|
type: filestream
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: log
|
name: filestream
|
||||||
version:
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: 3b56803d-5ade-4c93-b25e-9b37182f66b8
|
package_policy_id: 85820eb0-25ef-11f0-a18d-1b26f69b8310
|
||||||
streams:
|
streams:
|
||||||
- id: logfile-log.log-3b56803d-5ade-4c93-b25e-9b37182f66b8
|
- id: filestream-filestream.generic-85820eb0-25ef-11f0-a18d-1b26f69b8310
|
||||||
data_stream:
|
data_stream:
|
||||||
dataset: import
|
dataset: import
|
||||||
pipeline: suricata.common
|
|
||||||
paths:
|
paths:
|
||||||
- /nsm/import/*/suricata/eve*.json
|
- /nsm/import/*/suricata/eve*.json
|
||||||
|
pipeline: suricata.common
|
||||||
|
prospector.scanner.recursive_glob: true
|
||||||
|
prospector.scanner.exclude_files:
|
||||||
|
- \.gz$
|
||||||
|
ignore_older: 72h
|
||||||
|
clean_inactive: -1
|
||||||
|
parsers: null
|
||||||
processors:
|
processors:
|
||||||
- add_fields:
|
- add_fields:
|
||||||
|
target: event
|
||||||
fields:
|
fields:
|
||||||
|
category: network
|
||||||
module: suricata
|
module: suricata
|
||||||
imported: true
|
imported: true
|
||||||
category: network
|
|
||||||
target: event
|
|
||||||
- dissect:
|
- dissect:
|
||||||
|
tokenizer: /nsm/import/%{import.id}/suricata/%{import.file}
|
||||||
field: log.file.path
|
field: log.file.path
|
||||||
tokenizer: '/nsm/import/%{import.id}/suricata/%{import.file}'
|
|
||||||
target_prefix: ''
|
target_prefix: ''
|
||||||
- id: logfile-logs-c327e1a3-1ebe-449c-a8eb-f6f35032e69d
|
file_identity.native: null
|
||||||
name: soc-server-logs
|
prospector.scanner.fingerprint.enabled: false
|
||||||
revision: 2
|
- id: filestream-filestream-86b4e960-25ef-11f0-a18d-1b26f69b8310
|
||||||
type: logfile
|
name: import-zeek-logs
|
||||||
|
revision: 3
|
||||||
|
type: filestream
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: log
|
name: filestream
|
||||||
version:
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: c327e1a3-1ebe-449c-a8eb-f6f35032e69d
|
package_policy_id: 86b4e960-25ef-11f0-a18d-1b26f69b8310
|
||||||
streams:
|
streams:
|
||||||
- id: logfile-log.log-c327e1a3-1ebe-449c-a8eb-f6f35032e69d
|
- id: filestream-filestream.generic-86b4e960-25ef-11f0-a18d-1b26f69b8310
|
||||||
data_stream:
|
data_stream:
|
||||||
dataset: soc
|
dataset: import
|
||||||
pipeline: common
|
|
||||||
paths:
|
paths:
|
||||||
- /opt/so/log/soc/sensoroni-server.log
|
- /nsm/import/*/zeek/logs/*.log
|
||||||
|
prospector.scanner.recursive_glob: true
|
||||||
|
prospector.scanner.exclude_files:
|
||||||
|
- >-
|
||||||
|
(broker|capture_loss|cluster|conn-summary|console|ecat_arp_info|known_certs|known_hosts|known_services|loaded_scripts|ntp|ocsp|packet_filter|reporter|stats|stderr|stdout).log$
|
||||||
|
clean_inactive: -1
|
||||||
|
parsers: null
|
||||||
processors:
|
processors:
|
||||||
- decode_json_fields:
|
- dissect:
|
||||||
add_error_key: true
|
tokenizer: /nsm/import/%{import.id}/zeek/logs/%{import.file}
|
||||||
process_array: true
|
field: log.file.path
|
||||||
max_depth: 2
|
target_prefix: ''
|
||||||
fields:
|
- script:
|
||||||
- message
|
lang: javascript
|
||||||
target: soc
|
source: |
|
||||||
|
function process(event) {
|
||||||
|
var pl = event.Get("import.file").slice(0,-4);
|
||||||
|
event.Put("@metadata.pipeline", "zeek." + pl);
|
||||||
|
}
|
||||||
- add_fields:
|
- add_fields:
|
||||||
fields:
|
|
||||||
module: soc
|
|
||||||
dataset_temp: server
|
|
||||||
category: host
|
|
||||||
target: event
|
target: event
|
||||||
- rename:
|
|
||||||
ignore_missing: true
|
|
||||||
fields:
|
fields:
|
||||||
- from: soc.fields.sourceIp
|
category: network
|
||||||
to: source.ip
|
module: zeek
|
||||||
- from: soc.fields.status
|
imported: true
|
||||||
to: http.response.status_code
|
- add_tags:
|
||||||
- from: soc.fields.method
|
tags: ics
|
||||||
to: http.request.method
|
when:
|
||||||
- from: soc.fields.path
|
regexp:
|
||||||
to: url.path
|
import.file: >-
|
||||||
- from: soc.message
|
^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*
|
||||||
to: event.action
|
file_identity.native: null
|
||||||
- from: soc.level
|
prospector.scanner.fingerprint.enabled: false
|
||||||
to: log.level
|
- id: filestream-filestream-91741240-25ef-11f0-a18d-1b26f69b8310
|
||||||
tags:
|
|
||||||
- so-soc
|
|
||||||
- id: logfile-logs-906e0d4c-9ec3-4c6a-bef6-e347ec9fd073
|
|
||||||
name: soc-sensoroni-logs
|
name: soc-sensoroni-logs
|
||||||
revision: 2
|
revision: 3
|
||||||
type: logfile
|
type: filestream
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: log
|
name: filestream
|
||||||
version:
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: 906e0d4c-9ec3-4c6a-bef6-e347ec9fd073
|
package_policy_id: 91741240-25ef-11f0-a18d-1b26f69b8310
|
||||||
streams:
|
streams:
|
||||||
- id: logfile-log.log-906e0d4c-9ec3-4c6a-bef6-e347ec9fd073
|
- id: filestream-filestream.generic-91741240-25ef-11f0-a18d-1b26f69b8310
|
||||||
data_stream:
|
data_stream:
|
||||||
dataset: soc
|
dataset: soc
|
||||||
pipeline: common
|
|
||||||
paths:
|
paths:
|
||||||
- /opt/so/log/sensoroni/sensoroni.log
|
- /opt/so/log/sensoroni/sensoroni.log
|
||||||
|
pipeline: common
|
||||||
|
prospector.scanner.recursive_glob: true
|
||||||
|
prospector.scanner.exclude_files:
|
||||||
|
- \.gz$
|
||||||
|
clean_inactive: -1
|
||||||
|
parsers: null
|
||||||
processors:
|
processors:
|
||||||
- decode_json_fields:
|
- decode_json_fields:
|
||||||
add_error_key: true
|
|
||||||
process_array: true
|
|
||||||
max_depth: 2
|
|
||||||
fields:
|
fields:
|
||||||
- message
|
- message
|
||||||
target: sensoroni
|
target: sensoroni
|
||||||
|
process_array: true
|
||||||
|
max_depth: 2
|
||||||
|
add_error_key: true
|
||||||
- add_fields:
|
- add_fields:
|
||||||
|
target: event
|
||||||
fields:
|
fields:
|
||||||
|
category: host
|
||||||
module: soc
|
module: soc
|
||||||
dataset_temp: sensoroni
|
dataset_temp: sensoroni
|
||||||
category: host
|
|
||||||
target: event
|
|
||||||
- rename:
|
- rename:
|
||||||
ignore_missing: true
|
|
||||||
fields:
|
fields:
|
||||||
- from: sensoroni.fields.sourceIp
|
- from: sensoroni.fields.sourceIp
|
||||||
to: source.ip
|
to: source.ip
|
||||||
@@ -271,141 +162,100 @@ inputs:
|
|||||||
to: event.action
|
to: event.action
|
||||||
- from: sensoroni.level
|
- from: sensoroni.level
|
||||||
to: log.level
|
to: log.level
|
||||||
- id: logfile-logs-df0d7f2c-221f-433b-b18b-d1cf83250515
|
ignore_missing: true
|
||||||
name: soc-salt-relay-logs
|
file_identity.native: null
|
||||||
revision: 2
|
prospector.scanner.fingerprint.enabled: false
|
||||||
type: logfile
|
- id: filestream-filestream-976e3900-25ef-11f0-a18d-1b26f69b8310
|
||||||
use_output: default
|
|
||||||
meta:
|
|
||||||
package:
|
|
||||||
name: log
|
|
||||||
version:
|
|
||||||
data_stream:
|
|
||||||
namespace: so
|
|
||||||
package_policy_id: df0d7f2c-221f-433b-b18b-d1cf83250515
|
|
||||||
streams:
|
|
||||||
- id: logfile-log.log-df0d7f2c-221f-433b-b18b-d1cf83250515
|
|
||||||
data_stream:
|
|
||||||
dataset: soc
|
|
||||||
pipeline: common
|
|
||||||
paths:
|
|
||||||
- /opt/so/log/soc/salt-relay.log
|
|
||||||
processors:
|
|
||||||
- dissect:
|
|
||||||
field: message
|
|
||||||
tokenizer: '%{soc.ts} | %{event.action}'
|
|
||||||
target_prefix: ''
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
module: soc
|
|
||||||
dataset_temp: salt_relay
|
|
||||||
category: host
|
|
||||||
target: event
|
|
||||||
tags:
|
|
||||||
- so-soc
|
|
||||||
- id: logfile-logs-74bd2366-fe52-493c-bddc-843a017fc4d0
|
|
||||||
name: soc-auth-sync-logs
|
|
||||||
revision: 2
|
|
||||||
type: logfile
|
|
||||||
use_output: default
|
|
||||||
meta:
|
|
||||||
package:
|
|
||||||
name: log
|
|
||||||
version:
|
|
||||||
data_stream:
|
|
||||||
namespace: so
|
|
||||||
package_policy_id: 74bd2366-fe52-493c-bddc-843a017fc4d0
|
|
||||||
streams:
|
|
||||||
- id: logfile-log.log-74bd2366-fe52-493c-bddc-843a017fc4d0
|
|
||||||
data_stream:
|
|
||||||
dataset: soc
|
|
||||||
pipeline: common
|
|
||||||
paths:
|
|
||||||
- /opt/so/log/soc/sync.log
|
|
||||||
processors:
|
|
||||||
- dissect:
|
|
||||||
field: message
|
|
||||||
tokenizer: '%{event.action}'
|
|
||||||
target_prefix: ''
|
|
||||||
- add_fields:
|
|
||||||
fields:
|
|
||||||
module: soc
|
|
||||||
dataset_temp: auth_sync
|
|
||||||
category: host
|
|
||||||
target: event
|
|
||||||
tags:
|
|
||||||
- so-soc
|
|
||||||
- id: logfile-logs-d151d9bf-ff2a-4529-9520-c99244bc0253
|
|
||||||
name: suricata-logs
|
name: suricata-logs
|
||||||
revision: 2
|
revision: 3
|
||||||
type: logfile
|
type: filestream
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: log
|
name: filestream
|
||||||
version:
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: d151d9bf-ff2a-4529-9520-c99244bc0253
|
package_policy_id: 976e3900-25ef-11f0-a18d-1b26f69b8310
|
||||||
streams:
|
streams:
|
||||||
- id: logfile-log.log-d151d9bf-ff2a-4529-9520-c99244bc0253
|
- id: filestream-filestream.generic-976e3900-25ef-11f0-a18d-1b26f69b8310
|
||||||
data_stream:
|
data_stream:
|
||||||
dataset: suricata
|
dataset: suricata
|
||||||
pipeline: suricata.common
|
|
||||||
paths:
|
paths:
|
||||||
- /nsm/suricata/eve*.json
|
- /nsm/suricata/eve*.json
|
||||||
|
pipeline: suricata.common
|
||||||
|
prospector.scanner.recursive_glob: true
|
||||||
|
prospector.scanner.exclude_files:
|
||||||
|
- \.gz$
|
||||||
|
clean_inactive: -1
|
||||||
|
parsers: null
|
||||||
processors:
|
processors:
|
||||||
- add_fields:
|
- add_fields:
|
||||||
fields:
|
|
||||||
module: suricata
|
|
||||||
category: network
|
|
||||||
target: event
|
target: event
|
||||||
- id: logfile-logs-31f94d05-ae75-40ee-b9c5-0e0356eff327
|
fields:
|
||||||
|
category: network
|
||||||
|
module: suricata
|
||||||
|
file_identity.native: null
|
||||||
|
prospector.scanner.fingerprint.enabled: false
|
||||||
|
- id: filestream-filestream-95091fe0-25ef-11f0-a18d-1b26f69b8310
|
||||||
name: strelka-logs
|
name: strelka-logs
|
||||||
revision: 2
|
revision: 3
|
||||||
type: logfile
|
type: filestream
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: log
|
name: filestream
|
||||||
version:
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: 31f94d05-ae75-40ee-b9c5-0e0356eff327
|
package_policy_id: 95091fe0-25ef-11f0-a18d-1b26f69b8310
|
||||||
streams:
|
streams:
|
||||||
- id: logfile-log.log-31f94d05-ae75-40ee-b9c5-0e0356eff327
|
- id: filestream-filestream.generic-95091fe0-25ef-11f0-a18d-1b26f69b8310
|
||||||
data_stream:
|
data_stream:
|
||||||
dataset: strelka
|
dataset: strelka
|
||||||
pipeline: strelka.file
|
|
||||||
paths:
|
paths:
|
||||||
- /nsm/strelka/log/strelka.log
|
- /nsm/strelka/log/strelka.log
|
||||||
|
pipeline: strelka.file
|
||||||
|
prospector.scanner.recursive_glob: true
|
||||||
|
prospector.scanner.exclude_files:
|
||||||
|
- \.gz$
|
||||||
|
clean_inactive: -1
|
||||||
|
parsers: null
|
||||||
processors:
|
processors:
|
||||||
- add_fields:
|
- add_fields:
|
||||||
fields:
|
|
||||||
module: strelka
|
|
||||||
category: file
|
|
||||||
target: event
|
target: event
|
||||||
- id: logfile-logs-6197fe84-9b58-4d9b-8464-3d517f28808d
|
fields:
|
||||||
|
category: file
|
||||||
|
module: strelka
|
||||||
|
file_identity.native: null
|
||||||
|
prospector.scanner.fingerprint.enabled: false
|
||||||
|
- id: filestream-filestream-9f309ca0-25ef-11f0-a18d-1b26f69b8310
|
||||||
name: zeek-logs
|
name: zeek-logs
|
||||||
revision: 1
|
revision: 2
|
||||||
type: logfile
|
type: filestream
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: log
|
name: filestream
|
||||||
version:
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: 6197fe84-9b58-4d9b-8464-3d517f28808d
|
package_policy_id: 9f309ca0-25ef-11f0-a18d-1b26f69b8310
|
||||||
streams:
|
streams:
|
||||||
- id: logfile-log.log-6197fe84-9b58-4d9b-8464-3d517f28808d
|
- id: filestream-filestream.generic-9f309ca0-25ef-11f0-a18d-1b26f69b8310
|
||||||
data_stream:
|
data_stream:
|
||||||
dataset: zeek
|
dataset: zeek
|
||||||
paths:
|
paths:
|
||||||
- /nsm/zeek/logs/current/*.log
|
- /nsm/zeek/logs/current/*.log
|
||||||
|
prospector.scanner.recursive_glob: true
|
||||||
|
prospector.scanner.exclude_files:
|
||||||
|
- >-
|
||||||
|
(broker|capture_loss|cluster|conn-summary|console|ecat_arp_info|known_certs|known_hosts|known_services|loaded_scripts|ntp|ocsp|packet_filter|reporter|stats|stderr|stdout).log$
|
||||||
|
clean_inactive: -1
|
||||||
|
parsers: null
|
||||||
processors:
|
processors:
|
||||||
- dissect:
|
- dissect:
|
||||||
tokenizer: '/nsm/zeek/logs/current/%{pipeline}.log'
|
tokenizer: /nsm/zeek/logs/current/%{pipeline}.log
|
||||||
field: log.file.path
|
field: log.file.path
|
||||||
trim_chars: .log
|
trim_chars: .log
|
||||||
target_prefix: ''
|
target_prefix: ''
|
||||||
@@ -427,18 +277,17 @@ inputs:
|
|||||||
regexp:
|
regexp:
|
||||||
pipeline: >-
|
pipeline: >-
|
||||||
^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*
|
^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*
|
||||||
exclude_files:
|
file_identity.native: null
|
||||||
- >-
|
prospector.scanner.fingerprint.enabled: false
|
||||||
broker|capture_loss|cluster|ecat_arp_info|known_hosts|known_services|loaded_scripts|ntp|ocsp|packet_filter|reporter|stats|stderr|stdout.log$
|
|
||||||
- id: udp-udp-35051de0-46a5-11ee-8d5d-9f98c8182f60
|
- id: udp-udp-35051de0-46a5-11ee-8d5d-9f98c8182f60
|
||||||
name: syslog-udp-514
|
name: syslog-udp-514
|
||||||
revision: 3
|
revision: 4
|
||||||
type: udp
|
type: udp
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: udp
|
name: udp
|
||||||
version: 1.10.0
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: 35051de0-46a5-11ee-8d5d-9f98c8182f60
|
package_policy_id: 35051de0-46a5-11ee-8d5d-9f98c8182f60
|
||||||
@@ -458,13 +307,13 @@ inputs:
|
|||||||
- syslog
|
- syslog
|
||||||
- id: tcp-tcp-33d37bb0-46a5-11ee-8d5d-9f98c8182f60
|
- id: tcp-tcp-33d37bb0-46a5-11ee-8d5d-9f98c8182f60
|
||||||
name: syslog-tcp-514
|
name: syslog-tcp-514
|
||||||
revision: 3
|
revision: 4
|
||||||
type: tcp
|
type: tcp
|
||||||
use_output: default
|
use_output: default
|
||||||
meta:
|
meta:
|
||||||
package:
|
package:
|
||||||
name: tcp
|
name: tcp
|
||||||
version: 1.10.0
|
version:
|
||||||
data_stream:
|
data_stream:
|
||||||
namespace: so
|
namespace: so
|
||||||
package_policy_id: 33d37bb0-46a5-11ee-8d5d-9f98c8182f60
|
package_policy_id: 33d37bb0-46a5-11ee-8d5d-9f98c8182f60
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
elasticagent:
|
elasticagent:
|
||||||
enabled:
|
enabled:
|
||||||
description: Enables or disables the Elastic Agent process. This process must remain enabled to allow collection of node events.
|
description: Enables or disables the Elastic Agent process. This process must remain enabled to allow collection of node events.
|
||||||
|
forcedType: bool
|
||||||
advanced: True
|
advanced: True
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||||
|
https://securityonion.net/license; you may not use this file except in compliance with the
|
||||||
|
Elastic License 2.0. #}
|
||||||
|
|
||||||
|
{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %}
|
||||||
|
|
||||||
|
{# advanced config_yaml options for elasticfleet logstash output #}
|
||||||
|
{% set ADV_OUTPUT_LOGSTASH_RAW = ELASTICFLEETMERGED.config.outputs.logstash %}
|
||||||
|
{% set ADV_OUTPUT_LOGSTASH = {} %}
|
||||||
|
{% for k, v in ADV_OUTPUT_LOGSTASH_RAW.items() %}
|
||||||
|
{% if v != "" and v is not none %}
|
||||||
|
{% if k == 'queue_mem_events' %}
|
||||||
|
{# rename queue_mem_events queue.mem.events #}
|
||||||
|
{% do ADV_OUTPUT_LOGSTASH.update({'queue.mem.events':v}) %}
|
||||||
|
{% elif k == 'loadbalance' %}
|
||||||
|
{% if v %}
|
||||||
|
{# only include loadbalance config when its True #}
|
||||||
|
{% do ADV_OUTPUT_LOGSTASH.update({k:v}) %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% do ADV_OUTPUT_LOGSTASH.update({k:v}) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% set LOGSTASH_CONFIG_YAML_RAW = [] %}
|
||||||
|
{% if ADV_OUTPUT_LOGSTASH %}
|
||||||
|
{% for k, v in ADV_OUTPUT_LOGSTASH.items() %}
|
||||||
|
{% do LOGSTASH_CONFIG_YAML_RAW.append(k ~ ': ' ~ v) %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% set LOGSTASH_CONFIG_YAML = LOGSTASH_CONFIG_YAML_RAW | join('\\n') if LOGSTASH_CONFIG_YAML_RAW else '' %}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
include:
|
include:
|
||||||
- elasticfleet.artifact_registry
|
- elasticfleet.artifact_registry
|
||||||
|
- elasticfleet.ssl
|
||||||
|
|
||||||
# Add EA Group
|
# Add EA Group
|
||||||
elasticfleetgroup:
|
elasticfleetgroup:
|
||||||
@@ -95,6 +96,9 @@ soresourcesrepoclone:
|
|||||||
- rev: 'main'
|
- rev: 'main'
|
||||||
- depth: 1
|
- depth: 1
|
||||||
- force_reset: True
|
- force_reset: True
|
||||||
|
- retry:
|
||||||
|
attempts: 3
|
||||||
|
interval: 10
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
elasticdefendconfdir:
|
elasticdefendconfdir:
|
||||||
@@ -169,7 +173,7 @@ eaoptionalintegrationsdir:
|
|||||||
|
|
||||||
{% for minion in node_data %}
|
{% for minion in node_data %}
|
||||||
{% set role = node_data[minion]["role"] %}
|
{% set role = node_data[minion]["role"] %}
|
||||||
{% if role in [ "eval","fleet","heavynode","import","manager", "managerhype", "managersearch","standalone" ] %}
|
{% if role in [ "eval","fleet","import","manager", "managerhype", "managersearch","standalone" ] %}
|
||||||
{% set optional_integrations = ELASTICFLEETMERGED.optional_integrations %}
|
{% set optional_integrations = ELASTICFLEETMERGED.optional_integrations %}
|
||||||
{% set integration_keys = optional_integrations.keys() %}
|
{% set integration_keys = optional_integrations.keys() %}
|
||||||
fleet_server_integrations_{{ minion }}:
|
fleet_server_integrations_{{ minion }}:
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
{# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||||
|
or more contributor license agreements. Licensed under the Elastic License 2.0; you may not use
|
||||||
|
this file except in compliance with the Elastic License 2.0. #}
|
||||||
|
|
||||||
|
|
||||||
|
{% import_json '/opt/so/state/esfleet_content_package_components.json' as ADDON_CONTENT_PACKAGE_COMPONENTS %}
|
||||||
|
{% import_json '/opt/so/state/esfleet_component_templates.json' as INSTALLED_COMPONENT_TEMPLATES %}
|
||||||
|
{% import_yaml 'elasticfleet/defaults.yaml' as ELASTICFLEETDEFAULTS %}
|
||||||
|
|
||||||
|
{% set CORE_ESFLEET_PACKAGES = ELASTICFLEETDEFAULTS.get('elasticfleet', {}).get('packages', {}) %}
|
||||||
|
{% set ADDON_CONTENT_INTEGRATION_DEFAULTS = {} %}
|
||||||
|
|
||||||
|
{% for pkg in ADDON_CONTENT_PACKAGE_COMPONENTS %}
|
||||||
|
{% if pkg.name in CORE_ESFLEET_PACKAGES %}
|
||||||
|
{# skip core content packages #}
|
||||||
|
{% elif pkg.name not in CORE_ESFLEET_PACKAGES %}
|
||||||
|
{# generate defaults for each content package #}
|
||||||
|
{% if pkg.dataStreams is defined and pkg.dataStreams is not none and pkg.dataStreams | length > 0%}
|
||||||
|
{% for pattern in pkg.dataStreams %}
|
||||||
|
{# in ES 9.3.2 'input' type integrations no longer create default component templates and instead they wait for user input during 'integration' setup (fleet ui config)
|
||||||
|
title: generic is an artifact of that and is not in use #}
|
||||||
|
{% if pattern.title == "generic" %}
|
||||||
|
{% continue %}
|
||||||
|
{% endif %}
|
||||||
|
{% if "metrics-" in pattern.name %}
|
||||||
|
{% set integration_type = "metrics-" %}
|
||||||
|
{% elif "logs-" in pattern.name %}
|
||||||
|
{% set integration_type = "logs-" %}
|
||||||
|
{% else %}
|
||||||
|
{% set integration_type = "" %}
|
||||||
|
{% endif %}
|
||||||
|
{# on content integrations the component name is user defined at the time it is added to an agent policy #}
|
||||||
|
{% set component_name = pattern.title %}
|
||||||
|
{% set index_pattern = pattern.name %}
|
||||||
|
{# component_name_x maintains the functionality of merging local pillar changes with generated 'defaults' via SOC UI #}
|
||||||
|
{% set component_name_x = component_name.replace(".","_x_") %}
|
||||||
|
{# pillar overrides/merge expects the key names to follow the naming in elasticsearch/defaults.yaml eg. so-logs-1password_x_item_usages . The _x_ is replaced later on in elasticsearch/template.map.jinja #}
|
||||||
|
{% set integration_key = "so-" ~ integration_type ~ pkg.name + '_x_' ~ component_name_x %}
|
||||||
|
{# Default integration settings #}
|
||||||
|
{% set integration_defaults = {
|
||||||
|
"index_sorting": false,
|
||||||
|
"index_template": {
|
||||||
|
"composed_of": [integration_type ~ component_name ~ "@package", integration_type ~ component_name ~ "@custom", "so-fleet_integrations.ip_mappings-1", "so-fleet_globals-1", "so-fleet_agent_id_verification-1"],
|
||||||
|
"data_stream": {
|
||||||
|
"allow_custom_routing": false,
|
||||||
|
"hidden": false
|
||||||
|
},
|
||||||
|
"ignore_missing_component_templates": [integration_type ~ component_name ~ "@custom"],
|
||||||
|
"index_patterns": [index_pattern],
|
||||||
|
"priority": 501,
|
||||||
|
"template": {
|
||||||
|
"settings": {
|
||||||
|
"index": {
|
||||||
|
"lifecycle": {"name": "so-" ~ integration_type ~ component_name ~ "-logs"},
|
||||||
|
"number_of_replicas": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
"phases": {
|
||||||
|
"cold": {
|
||||||
|
"actions": {
|
||||||
|
"allocate":{
|
||||||
|
"number_of_replicas": ""
|
||||||
|
},
|
||||||
|
"set_priority": {"priority": 0}
|
||||||
|
},
|
||||||
|
"min_age": "60d"
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"actions": {
|
||||||
|
"delete": {}
|
||||||
|
},
|
||||||
|
"min_age": "365d"
|
||||||
|
},
|
||||||
|
"hot": {
|
||||||
|
"actions": {
|
||||||
|
"rollover": {
|
||||||
|
"max_age": "30d",
|
||||||
|
"max_primary_shard_size": "50gb"
|
||||||
|
},
|
||||||
|
"forcemerge":{
|
||||||
|
"max_num_segments": ""
|
||||||
|
},
|
||||||
|
"shrink":{
|
||||||
|
"max_primary_shard_size": "",
|
||||||
|
"method": "COUNT",
|
||||||
|
"number_of_shards": ""
|
||||||
|
},
|
||||||
|
"set_priority": {"priority": 100}
|
||||||
|
},
|
||||||
|
"min_age": "0ms"
|
||||||
|
},
|
||||||
|
"warm": {
|
||||||
|
"actions": {
|
||||||
|
"allocate": {
|
||||||
|
"number_of_replicas": ""
|
||||||
|
},
|
||||||
|
"forcemerge": {
|
||||||
|
"max_num_segments": ""
|
||||||
|
},
|
||||||
|
"shrink":{
|
||||||
|
"max_primary_shard_size": "",
|
||||||
|
"method": "COUNT",
|
||||||
|
"number_of_shards": ""
|
||||||
|
},
|
||||||
|
"set_priority": {"priority": 50}
|
||||||
|
},
|
||||||
|
"min_age": "30d"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} %}
|
||||||
|
|
||||||
|
|
||||||
|
{% do ADDON_CONTENT_INTEGRATION_DEFAULTS.update({integration_key: integration_defaults}) %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
@@ -10,6 +10,14 @@ elasticfleet:
|
|||||||
grid_enrollment: ''
|
grid_enrollment: ''
|
||||||
defend_filters:
|
defend_filters:
|
||||||
enable_auto_configuration: False
|
enable_auto_configuration: False
|
||||||
|
outputs:
|
||||||
|
logstash:
|
||||||
|
bulk_max_size: ''
|
||||||
|
worker: ''
|
||||||
|
queue_mem_events: ''
|
||||||
|
timeout: ''
|
||||||
|
loadbalance: False
|
||||||
|
compression_level: ''
|
||||||
subscription_integrations: False
|
subscription_integrations: False
|
||||||
auto_upgrade_integrations: False
|
auto_upgrade_integrations: False
|
||||||
logging:
|
logging:
|
||||||
|
|||||||
+49
-101
@@ -6,64 +6,34 @@
|
|||||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||||
{% if sls.split('.')[0] in allowed_states %}
|
{% if sls.split('.')[0] in allowed_states %}
|
||||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
{% from 'docker/docker.map.jinja' import DOCKERMERGED %}
|
||||||
{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %}
|
{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %}
|
||||||
|
|
||||||
{# This value is generated during node install and stored in minion pillar #}
|
{# This value is generated during node install and stored in minion pillar #}
|
||||||
{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:config:server:es_token','') %}
|
{% set SERVICETOKEN = salt['pillar.get']('elasticfleet:config:server:es_token','') %}
|
||||||
|
{# Prevent Elastic Agent from re-enrolling with a new agent.id everytime the container starts up.
|
||||||
|
- if a fresh enrollment is needed use 'so-stop elasticfleet'
|
||||||
|
#}
|
||||||
|
{% set ENROLLED = salt['file.file_exists']('/opt/so/conf/elastic-fleet/state/fleet.enc') %}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
- ca
|
||||||
|
- logstash.ssl
|
||||||
- elasticfleet.config
|
- elasticfleet.config
|
||||||
- elasticfleet.sostatus
|
- elasticfleet.sostatus
|
||||||
- ssl
|
{%- if GLOBALS.role != "so-fleet" %}
|
||||||
|
- elasticfleet.manager
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{% if grains.role not in ['so-fleet'] %}
|
{% if GLOBALS.role != "so-fleet" %}
|
||||||
# Wait for Elasticsearch to be ready - no reason to try running Elastic Fleet server if ES is not ready
|
# Wait for Elasticsearch to be ready - no reason to try running Elastic Fleet server if ES is not ready
|
||||||
wait_for_elasticsearch_elasticfleet:
|
wait_for_elasticsearch_elasticfleet:
|
||||||
cmd.run:
|
cmd.run:
|
||||||
- name: so-elasticsearch-wait
|
- name: so-elasticsearch-wait
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# If enabled, automatically update Fleet Logstash Outputs
|
{% if GLOBALS.role == "so-fleet" %}
|
||||||
{% if ELASTICFLEETMERGED.config.server.enable_auto_configuration and grains.role not in ['so-import', 'so-eval', 'so-fleet'] %}
|
|
||||||
so-elastic-fleet-auto-configure-logstash-outputs:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-outputs-update
|
|
||||||
- retry:
|
|
||||||
attempts: 4
|
|
||||||
interval: 30
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# If enabled, automatically update Fleet Server URLs & ES Connection
|
|
||||||
{% if ELASTICFLEETMERGED.config.server.enable_auto_configuration and grains.role not in ['so-fleet'] %}
|
|
||||||
so-elastic-fleet-auto-configure-server-urls:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-urls-update
|
|
||||||
- retry:
|
|
||||||
attempts: 4
|
|
||||||
interval: 30
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs
|
|
||||||
{% if grains.role not in ['so-fleet'] %}
|
|
||||||
so-elastic-fleet-auto-configure-elasticsearch-urls:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-es-url-update
|
|
||||||
- retry:
|
|
||||||
attempts: 4
|
|
||||||
interval: 30
|
|
||||||
|
|
||||||
so-elastic-fleet-auto-configure-artifact-urls:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-artifacts-url-update
|
|
||||||
- retry:
|
|
||||||
attempts: 4
|
|
||||||
interval: 30
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Sync Elastic Agent artifacts to Fleet Node
|
# Sync Elastic Agent artifacts to Fleet Node
|
||||||
{% if grains.role in ['so-fleet'] %}
|
|
||||||
elasticagent_syncartifacts:
|
elasticagent_syncartifacts:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /nsm/elastic-fleet/artifacts/beats
|
- name: /nsm/elastic-fleet/artifacts/beats
|
||||||
@@ -76,36 +46,39 @@ elasticagent_syncartifacts:
|
|||||||
so-elastic-fleet:
|
so-elastic-fleet:
|
||||||
docker_container.running:
|
docker_container.running:
|
||||||
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }}
|
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent:{{ GLOBALS.so_version }}
|
||||||
|
- restart_policy: unless-stopped
|
||||||
- name: so-elastic-fleet
|
- name: so-elastic-fleet
|
||||||
- hostname: FleetServer-{{ GLOBALS.hostname }}
|
- hostname: FleetServer-{{ GLOBALS.hostname }}
|
||||||
- detach: True
|
- detach: True
|
||||||
- user: 947
|
- user: 947
|
||||||
- networks:
|
- networks:
|
||||||
- sobridge:
|
- sobridge:
|
||||||
- ipv4_address: {{ DOCKER.containers['so-elastic-fleet'].ip }}
|
- ipv4_address: {{ DOCKERMERGED.containers['so-elastic-fleet'].ip }}
|
||||||
- extra_hosts:
|
- extra_hosts:
|
||||||
- {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }}
|
- {{ GLOBALS.manager }}:{{ GLOBALS.manager_ip }}
|
||||||
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
|
- {{ GLOBALS.hostname }}:{{ GLOBALS.node_ip }}
|
||||||
{% if DOCKER.containers['so-elastic-fleet'].extra_hosts %}
|
{% if DOCKERMERGED.containers['so-elastic-fleet'].extra_hosts %}
|
||||||
{% for XTRAHOST in DOCKER.containers['so-elastic-fleet'].extra_hosts %}
|
{% for XTRAHOST in DOCKERMERGED.containers['so-elastic-fleet'].extra_hosts %}
|
||||||
- {{ XTRAHOST }}
|
- {{ XTRAHOST }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- port_bindings:
|
- port_bindings:
|
||||||
{% for BINDING in DOCKER.containers['so-elastic-fleet'].port_bindings %}
|
{% for BINDING in DOCKERMERGED.containers['so-elastic-fleet'].port_bindings %}
|
||||||
- {{ BINDING }}
|
- {{ BINDING }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
- binds:
|
- binds:
|
||||||
- /etc/pki/elasticfleet-server.crt:/etc/pki/elasticfleet-server.crt:ro
|
- /etc/pki/elasticfleet-server.crt:/etc/pki/elasticfleet-server.crt:ro
|
||||||
- /etc/pki/elasticfleet-server.key:/etc/pki/elasticfleet-server.key:ro
|
- /etc/pki/elasticfleet-server.key:/etc/pki/elasticfleet-server.key:ro
|
||||||
- /etc/pki/tls/certs/intca.crt:/etc/pki/tls/certs/intca.crt:ro
|
- /etc/pki/tls/certs/intca.crt:/etc/pki/tls/certs/intca.crt:ro
|
||||||
|
- /opt/so/conf/elastic-fleet/state:/usr/share/elastic-agent/state
|
||||||
- /opt/so/log/elasticfleet:/usr/share/elastic-agent/logs
|
- /opt/so/log/elasticfleet:/usr/share/elastic-agent/logs
|
||||||
{% if DOCKER.containers['so-elastic-fleet'].custom_bind_mounts %}
|
{% if DOCKERMERGED.containers['so-elastic-fleet'].custom_bind_mounts %}
|
||||||
{% for BIND in DOCKER.containers['so-elastic-fleet'].custom_bind_mounts %}
|
{% for BIND in DOCKERMERGED.containers['so-elastic-fleet'].custom_bind_mounts %}
|
||||||
- {{ BIND }}
|
- {{ BIND }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- environment:
|
- environment:
|
||||||
|
{% if not ENROLLED %}
|
||||||
- FLEET_SERVER_ENABLE=true
|
- FLEET_SERVER_ENABLE=true
|
||||||
- FLEET_URL=https://{{ GLOBALS.hostname }}:8220
|
- FLEET_URL=https://{{ GLOBALS.hostname }}:8220
|
||||||
- FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200
|
- FLEET_SERVER_ELASTICSEARCH_HOST=https://{{ GLOBALS.manager }}:9200
|
||||||
@@ -115,68 +88,43 @@ so-elastic-fleet:
|
|||||||
- FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet-server.key
|
- FLEET_SERVER_CERT_KEY=/etc/pki/elasticfleet-server.key
|
||||||
- FLEET_CA=/etc/pki/tls/certs/intca.crt
|
- FLEET_CA=/etc/pki/tls/certs/intca.crt
|
||||||
- FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/tls/certs/intca.crt
|
- FLEET_SERVER_ELASTICSEARCH_CA=/etc/pki/tls/certs/intca.crt
|
||||||
|
{% endif %}
|
||||||
|
- STATE_PATH=/usr/share/elastic-agent/state
|
||||||
|
- CONFIG_PATH=/usr/share/elastic-agent/state
|
||||||
- LOGS_PATH=logs
|
- LOGS_PATH=logs
|
||||||
{% if DOCKER.containers['so-elastic-fleet'].extra_env %}
|
{% if DOCKERMERGED.containers['so-elastic-fleet'].extra_env %}
|
||||||
{% for XTRAENV in DOCKER.containers['so-elastic-fleet'].extra_env %}
|
{% for XTRAENV in DOCKERMERGED.containers['so-elastic-fleet'].extra_env %}
|
||||||
- {{ XTRAENV }}
|
- {{ XTRAENV }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if DOCKERMERGED.containers['so-elastic-fleet'].ulimits %}
|
||||||
|
- ulimits:
|
||||||
|
{% for ULIMIT in DOCKERMERGED.containers['so-elastic-fleet'].ulimits %}
|
||||||
|
- {{ ULIMIT.name }}={{ ULIMIT.soft }}:{{ ULIMIT.hard }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
- watch:
|
- watch:
|
||||||
|
- file: trusttheca
|
||||||
- x509: etc_elasticfleet_key
|
- x509: etc_elasticfleet_key
|
||||||
- x509: etc_elasticfleet_crt
|
- x509: etc_elasticfleet_crt
|
||||||
|
- require:
|
||||||
|
- file: trusttheca
|
||||||
|
- file: eastatedir
|
||||||
|
- x509: etc_elasticfleet_key
|
||||||
|
- x509: etc_elasticfleet_crt
|
||||||
|
|
||||||
|
wait_for_so-elastic-fleet:
|
||||||
|
http.wait_for_successful_query:
|
||||||
|
- name: "https://localhost:8220/api/status"
|
||||||
|
- ssl: True
|
||||||
|
- verify_ssl: False
|
||||||
|
- status: 200
|
||||||
|
- wait_for: 300
|
||||||
|
- request_interval: 15
|
||||||
|
- require:
|
||||||
|
- docker_container: so-elastic-fleet
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if GLOBALS.role != "so-fleet" %}
|
|
||||||
so-elastic-fleet-package-statefile:
|
|
||||||
file.managed:
|
|
||||||
- name: /opt/so/state/elastic_fleet_packages.txt
|
|
||||||
- contents: {{ELASTICFLEETMERGED.packages}}
|
|
||||||
|
|
||||||
so-elastic-fleet-package-upgrade:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-package-upgrade
|
|
||||||
- retry:
|
|
||||||
attempts: 3
|
|
||||||
interval: 10
|
|
||||||
- onchanges:
|
|
||||||
- file: /opt/so/state/elastic_fleet_packages.txt
|
|
||||||
|
|
||||||
so-elastic-fleet-integrations:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-integration-policy-load
|
|
||||||
- retry:
|
|
||||||
attempts: 3
|
|
||||||
interval: 10
|
|
||||||
|
|
||||||
so-elastic-agent-grid-upgrade:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-agent-grid-upgrade
|
|
||||||
- retry:
|
|
||||||
attempts: 12
|
|
||||||
interval: 5
|
|
||||||
|
|
||||||
so-elastic-fleet-integration-upgrade:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-integration-upgrade
|
|
||||||
- retry:
|
|
||||||
attempts: 3
|
|
||||||
interval: 10
|
|
||||||
|
|
||||||
{# Optional integrations script doesn't need the retries like so-elastic-fleet-integration-upgrade which loads the default integrations #}
|
|
||||||
so-elastic-fleet-addon-integrations:
|
|
||||||
cmd.run:
|
|
||||||
- name: /usr/sbin/so-elastic-fleet-optional-integrations-load
|
|
||||||
|
|
||||||
{% if ELASTICFLEETMERGED.config.defend_filters.enable_auto_configuration %}
|
|
||||||
so-elastic-defend-manage-filters-file-watch:
|
|
||||||
cmd.run:
|
|
||||||
- name: python3 /sbin/so-elastic-defend-manage-filters.py -c /opt/so/conf/elasticsearch/curl.config -d /opt/so/conf/elastic-fleet/defend-exclusions/disabled-filters.yaml -i /nsm/securityonion-resources/event_filters/ -i /opt/so/conf/elastic-fleet/defend-exclusions/rulesets/custom-filters/ &>> /opt/so/log/elasticfleet/elastic-defend-manage-filters.log
|
|
||||||
- onchanges:
|
|
||||||
- file: elasticdefendcustom
|
|
||||||
- file: elasticdefenddisabled
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
delete_so-elastic-fleet_so-status.disabled:
|
delete_so-elastic-fleet_so-status.disabled:
|
||||||
file.uncomment:
|
file.uncomment:
|
||||||
- name: /opt/so/conf/so-status/so-status.conf
|
- name: /opt/so/conf/so-status/so-status.conf
|
||||||
|
|||||||
+24
-5
@@ -2,27 +2,46 @@
|
|||||||
{%- raw -%}
|
{%- raw -%}
|
||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "import-zeek-logs",
|
"name": "import-zeek-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Zeek Import logs",
|
"description": "Zeek Import logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/nsm/import/*/zeek/logs/*.log"
|
"/nsm/import/*/zeek/logs/*.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "import",
|
"data_stream.dataset": "import",
|
||||||
"tags": [],
|
"pipeline": "",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": ["({%- endraw -%}{{ ELASTICFLEETMERGED.logging.zeek.excluded | join('|') }}{%- raw -%})(\\..+)?\\.log$"],
|
||||||
|
"include_files": [],
|
||||||
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/zeek/logs/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"import.file\").slice(0,-4);\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n imported: true\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n import.file: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"",
|
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/zeek/logs/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"import.file\").slice(0,-4);\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n imported: true\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n import.file: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"",
|
||||||
"custom": "exclude_files: [\"{%- endraw -%}{{ ELASTICFLEETMERGED.logging.zeek.excluded | join('|') }}{%- raw -%}.log$\"]\n"
|
"tags": [],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"fingerprint_length": "64",
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,36 +11,57 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "kratos-logs",
|
"name": "kratos-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Kratos logs",
|
"description": "Kratos logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/opt/so/log/kratos/kratos.log"
|
"/opt/so/log/kratos/kratos.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "kratos",
|
"data_stream.dataset": "kratos",
|
||||||
"tags": ["so-kratos"],
|
"pipeline": "kratos",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
{%- if valid_identities -%}
|
{%- if valid_identities -%}
|
||||||
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos\n- if:\n has_fields:\n - identity_id\n then:{% for id, email in identities %}\n - if:\n equals:\n identity_id: \"{{ id }}\"\n then:\n - add_fields:\n target: ''\n fields:\n user.name: \"{{ email }}\"{% endfor %}",
|
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos\n- if:\n has_fields:\n - identity_id\n then:{% for id, email in identities %}\n - if:\n equals:\n identity_id: \"{{ id }}\"\n then:\n - add_fields:\n target: ''\n fields:\n user.name: \"{{ email }}\"{% endfor %}",
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos",
|
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: kratos",
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
"custom": "pipeline: kratos"
|
"tags": [
|
||||||
|
"so-kratos"
|
||||||
|
],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,28 +2,44 @@
|
|||||||
{%- raw -%}
|
{%- raw -%}
|
||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"id": "zeek-logs",
|
|
||||||
"name": "zeek-logs",
|
"name": "zeek-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Zeek logs",
|
"description": "Zeek logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/nsm/zeek/logs/current/*.log"
|
"/nsm/zeek/logs/current/*.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "zeek",
|
"data_stream.dataset": "zeek",
|
||||||
"tags": [],
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": ["({%- endraw -%}{{ ELASTICFLEETMERGED.logging.zeek.excluded | join('|') }}{%- raw -%})(\\..+)?\\.log$"],
|
||||||
|
"include_files": [],
|
||||||
"processors": "- dissect:\n tokenizer: \"/nsm/zeek/logs/current/%{pipeline}.log\"\n field: \"log.file.path\"\n trim_chars: \".log\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\");\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n pipeline: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"",
|
"processors": "- dissect:\n tokenizer: \"/nsm/zeek/logs/current/%{pipeline}.log\"\n field: \"log.file.path\"\n trim_chars: \".log\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\");\n event.Put(\"@metadata.pipeline\", \"zeek.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: zeek\n- add_tags:\n tags: \"ics\"\n when:\n regexp:\n pipeline: \"^bacnet*|^bsap*|^cip*|^cotp*|^dnp3*|^ecat*|^enip*|^modbus*|^opcua*|^profinet*|^s7comm*\"",
|
||||||
"custom": "exclude_files: [\"{%- endraw -%}{{ ELASTICFLEETMERGED.logging.zeek.excluded | join('|') }}{%- raw -%}.log$\"]\n"
|
"tags": [],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,4 +47,4 @@
|
|||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
{%- endraw -%}
|
{%- endraw -%}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"package": {
|
"package": {
|
||||||
"name": "endpoint",
|
"name": "endpoint",
|
||||||
"title": "Elastic Defend",
|
"title": "Elastic Defend",
|
||||||
"version": "8.18.1",
|
"version": "9.3.1",
|
||||||
"requires_root": true
|
"requires_root": true
|
||||||
},
|
},
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
@@ -6,21 +6,23 @@
|
|||||||
"name": "agent-monitor",
|
"name": "agent-monitor",
|
||||||
"namespace": "",
|
"namespace": "",
|
||||||
"description": "",
|
"description": "",
|
||||||
|
"policy_id": "so-grid-nodes_general",
|
||||||
"policy_ids": [
|
"policy_ids": [
|
||||||
"so-grid-nodes_general"
|
"so-grid-nodes_general"
|
||||||
],
|
],
|
||||||
"output_id": null,
|
|
||||||
"vars": {},
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"filestream-filestream": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"filestream.generic": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/opt/so/log/agents/agent-monitor.log"
|
"/opt/so/log/agents/agent-monitor.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "agentmonitor",
|
"data_stream.dataset": "agentmonitor",
|
||||||
"pipeline": "elasticagent.monitor",
|
"pipeline": "elasticagent.monitor",
|
||||||
"parsers": "",
|
"parsers": "",
|
||||||
@@ -34,15 +36,16 @@
|
|||||||
"ignore_older": "72h",
|
"ignore_older": "72h",
|
||||||
"clean_inactive": -1,
|
"clean_inactive": -1,
|
||||||
"harvester_limit": 0,
|
"harvester_limit": 0,
|
||||||
"fingerprint": true,
|
"fingerprint": false,
|
||||||
"fingerprint_offset": 0,
|
"fingerprint_offset": 0,
|
||||||
"fingerprint_length": 64,
|
"file_identity_native": true,
|
||||||
"file_identity_native": false,
|
|
||||||
"exclude_lines": [],
|
"exclude_lines": [],
|
||||||
"include_lines": []
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"force": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,49 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "hydra-logs",
|
"name": "hydra-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Hydra logs",
|
"description": "Hydra logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/opt/so/log/hydra/hydra.log"
|
"/opt/so/log/hydra/hydra.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "hydra",
|
"data_stream.dataset": "hydra",
|
||||||
"tags": ["so-hydra"],
|
"pipeline": "hydra",
|
||||||
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: iam\n module: hydra",
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
"custom": "pipeline: hydra"
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
|
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- add_fields:\n target: event\n fields:\n category: iam\n module: hydra",
|
||||||
|
"tags": [
|
||||||
|
"so-hydra"
|
||||||
|
],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"ignore_older": "72h",
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,3 +51,5 @@
|
|||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,50 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "idh-logs",
|
"name": "idh-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "IDH integration",
|
"description": "IDH integration",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/nsm/idh/opencanary.log"
|
"/nsm/idh/opencanary.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "idh",
|
"data_stream.dataset": "idh",
|
||||||
"tags": [],
|
"pipeline": "common",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
"processors": "\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- convert:\n fields:\n - {from: \"logtype\", to: \"event.code\", type: \"string\"}\n- drop_fields:\n when:\n equals:\n event.code: \"1001\"\n fields: [\"src_host\", \"src_port\", \"dst_host\", \"dst_port\" ]\n ignore_missing: true\n- rename:\n fields:\n - from: \"src_host\"\n to: \"source.ip\"\n - from: \"src_port\"\n to: \"source.port\"\n - from: \"dst_host\"\n to: \"destination.host\"\n - from: \"dst_port\"\n to: \"destination.port\"\n ignore_missing: true\n- drop_fields:\n fields: '[\"prospector\", \"input\", \"offset\", \"beat\"]'\n- add_fields:\n target: event\n fields:\n category: host\n module: opencanary",
|
"processors": "\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n add_error_key: true\n- convert:\n fields:\n - {from: \"logtype\", to: \"event.code\", type: \"string\"}\n- drop_fields:\n when:\n equals:\n event.code: \"1001\"\n fields: [\"src_host\", \"src_port\", \"dst_host\", \"dst_port\" ]\n ignore_missing: true\n- rename:\n fields:\n - from: \"src_host\"\n to: \"source.ip\"\n - from: \"src_port\"\n to: \"source.port\"\n - from: \"dst_host\"\n to: \"destination.host\"\n - from: \"dst_port\"\n to: \"destination.port\"\n ignore_missing: true\n- drop_fields:\n fields: '[\"prospector\", \"input\", \"offset\", \"beat\"]'\n- add_fields:\n target: event\n fields:\n category: host\n module: opencanary",
|
||||||
"custom": "pipeline: common"
|
"tags": [],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
@@ -1,33 +1,52 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "import-evtx-logs",
|
"name": "import-evtx-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Import Windows EVTX logs",
|
"description": "Import Windows EVTX logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
"vars": {},
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/nsm/import/*/evtx/*.json"
|
"/nsm/import/*/evtx/*.json"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "import",
|
"data_stream.dataset": "import",
|
||||||
"custom": "",
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-2.6.1\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-3.1.2\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-2.6.1\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-2.6.1\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-3.1.2\n- add_fields:\n target: data_stream\n fields:\n dataset: import",
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
|
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-2.20.0\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-3.8.3\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-2.20.0\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-2.20.0\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-3.8.3\n- add_fields:\n target: data_stream\n fields:\n dataset: import",
|
||||||
"tags": [
|
"tags": [
|
||||||
"import"
|
"import"
|
||||||
]
|
],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"ignore_older": "72h",
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,51 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "import-suricata-logs",
|
"name": "import-suricata-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Import Suricata logs",
|
"description": "Import Suricata logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/nsm/import/*/suricata/eve*.json"
|
"/nsm/import/*/suricata/eve*.json"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "import",
|
"data_stream.dataset": "import",
|
||||||
|
"pipeline": "suricata.common",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
|
"processors": "- add_fields:\n target: event\n fields:\n category: network\n module: suricata\n imported: true\n- dissect:\n tokenizer: \"/nsm/import/%{import.id}/suricata/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"processors": "- add_fields:\n target: event\n fields:\n category: network\n module: suricata\n imported: true\n- dissect:\n tokenizer: \"/nsm/import/%{import.id}/suricata/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"",
|
"recursive_glob": true,
|
||||||
"custom": "pipeline: suricata.common"
|
"ignore_older": "72h",
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/opt/so/log/redis/redis.log"
|
"/opt/so/log/redis/redis-server.log"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"redis-log"
|
"redis-log"
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "rita-logs",
|
"name": "rita-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "RITA Logs",
|
"description": "RITA Logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
"vars": {},
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
@@ -20,15 +23,30 @@
|
|||||||
"/nsm/rita/exploded-dns.csv",
|
"/nsm/rita/exploded-dns.csv",
|
||||||
"/nsm/rita/long-connections.csv"
|
"/nsm/rita/long-connections.csv"
|
||||||
],
|
],
|
||||||
"exclude_files": [],
|
"compression_gzip": false,
|
||||||
"ignore_older": "72h",
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "rita",
|
"data_stream.dataset": "rita",
|
||||||
"tags": [],
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
"processors": "- dissect:\n tokenizer: \"/nsm/rita/%{pipeline}.csv\"\n field: \"log.file.path\"\n trim_chars: \".csv\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\").split(\"-\");\n if (pl.length > 1) {\n pl = pl[1];\n }\n else {\n pl = pl[0];\n }\n event.Put(\"@metadata.pipeline\", \"rita.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: rita",
|
"processors": "- dissect:\n tokenizer: \"/nsm/rita/%{pipeline}.csv\"\n field: \"log.file.path\"\n trim_chars: \".csv\"\n target_prefix: \"\"\n- script:\n lang: javascript\n source: >\n function process(event) {\n var pl = event.Get(\"pipeline\").split(\"-\");\n if (pl.length > 1) {\n pl = pl[1];\n }\n else {\n pl = pl[0];\n }\n event.Put(\"@metadata.pipeline\", \"rita.\" + pl);\n }\n- add_fields:\n target: event\n fields:\n category: network\n module: rita",
|
||||||
"custom": "exclude_lines: ['^Score', '^Source', '^Domain', '^No results']"
|
"tags": [],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"ignore_older": "72h",
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"force": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,47 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "so-ip-mappings",
|
"name": "so-ip-mappings",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "IP Description mappings",
|
"description": "IP Description mappings",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
"vars": {},
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/nsm/custom-mappings/ip-descriptions.csv"
|
"/nsm/custom-mappings/ip-descriptions.csv"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "hostnamemappings",
|
"data_stream.dataset": "hostnamemappings",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
|
"processors": "- decode_csv_fields:\n fields:\n message: decoded.csv\n separator: \",\"\n ignore_missing: false\n overwrite_keys: true\n trim_leading_space: true\n fail_on_error: true\n\n- extract_array:\n field: decoded.csv\n mappings:\n so.ip_address: '0'\n so.description: '1'\n\n- script:\n lang: javascript\n source: >\n function process(event) {\n var ip = event.Get('so.ip_address');\n var validIpRegex = /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$/\n if (!validIpRegex.test(ip)) {\n event.Cancel();\n }\n }\n- fingerprint:\n fields: [\"so.ip_address\"]\n target_field: \"@metadata._id\"\n",
|
||||||
"tags": [
|
"tags": [
|
||||||
"so-ip-mappings"
|
"so-ip-mappings"
|
||||||
],
|
],
|
||||||
"processors": "- decode_csv_fields:\n fields:\n message: decoded.csv\n separator: \",\"\n ignore_missing: false\n overwrite_keys: true\n trim_leading_space: true\n fail_on_error: true\n\n- extract_array:\n field: decoded.csv\n mappings:\n so.ip_address: '0'\n so.description: '1'\n\n- script:\n lang: javascript\n source: >\n function process(event) {\n var ip = event.Get('so.ip_address');\n var validIpRegex = /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$/\n if (!validIpRegex.test(ip)) {\n event.Cancel();\n }\n }\n- fingerprint:\n fields: [\"so.ip_address\"]\n target_field: \"@metadata._id\"\n",
|
"recursive_glob": true,
|
||||||
"custom": ""
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,5 +49,3 @@
|
|||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,50 @@
|
|||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "soc-auth-sync-logs",
|
"name": "soc-auth-sync-logs",
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
"description": "Security Onion - Elastic Auth Sync - Logs",
|
"description": "Security Onion - Elastic Auth Sync - Logs",
|
||||||
"policy_id": "so-grid-nodes_general",
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/opt/so/log/soc/sync.log"
|
"/opt/so/log/soc/sync.log"
|
||||||
],
|
],
|
||||||
|
"compression_gzip": false,
|
||||||
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "soc",
|
"data_stream.dataset": "soc",
|
||||||
"tags": ["so-soc"],
|
"pipeline": "common",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
"processors": "- dissect:\n tokenizer: \"%{event.action}\"\n field: \"message\"\n target_prefix: \"\"\n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: auth_sync",
|
"processors": "- dissect:\n tokenizer: \"%{event.action}\"\n field: \"message\"\n target_prefix: \"\"\n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: auth_sync",
|
||||||
"custom": "pipeline: common"
|
"tags": [],
|
||||||
|
"recursive_glob": true,
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
@@ -1,35 +1,54 @@
|
|||||||
{
|
{
|
||||||
"policy_id": "so-grid-nodes_general",
|
|
||||||
"package": {
|
"package": {
|
||||||
"name": "log",
|
"name": "filestream",
|
||||||
"version": ""
|
"version": ""
|
||||||
},
|
},
|
||||||
"name": "soc-detections-logs",
|
"name": "soc-detections-logs",
|
||||||
"description": "Security Onion Console - Detections Logs",
|
|
||||||
"namespace": "so",
|
"namespace": "so",
|
||||||
|
"description": "Security Onion Console - Detections Logs",
|
||||||
|
"policy_id": "so-grid-nodes_general",
|
||||||
|
"policy_ids": [
|
||||||
|
"so-grid-nodes_general"
|
||||||
|
],
|
||||||
|
"vars": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"logs-logfile": {
|
"filestream-filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"streams": {
|
"streams": {
|
||||||
"log.logs": {
|
"filestream.filestream": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"vars": {
|
"vars": {
|
||||||
"paths": [
|
"paths": [
|
||||||
"/opt/so/log/soc/detections_runtime-status_sigma.log",
|
"/opt/so/log/soc/detections_runtime-status_sigma.log",
|
||||||
"/opt/so/log/soc/detections_runtime-status_yara.log"
|
"/opt/so/log/soc/detections_runtime-status_yara.log"
|
||||||
],
|
],
|
||||||
"exclude_files": [],
|
"compression_gzip": false,
|
||||||
"ignore_older": "72h",
|
"use_logs_stream": false,
|
||||||
"data_stream.dataset": "soc",
|
"data_stream.dataset": "soc",
|
||||||
|
"pipeline": "common",
|
||||||
|
"parsers": "#- ndjson:\n# target: \"\"\n# message_key: msg\n#- multiline:\n# type: count\n# count_lines: 3\n",
|
||||||
|
"exclude_files": [
|
||||||
|
"\\.gz$"
|
||||||
|
],
|
||||||
|
"include_files": [],
|
||||||
|
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"soc\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: detections\n- rename:\n fields:\n - from: \"soc.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"soc.fields.status\"\n to: \"http.response.status_code\"\n - from: \"soc.fields.method\"\n to: \"http.request.method\"\n - from: \"soc.fields.path\"\n to: \"url.path\"\n - from: \"soc.message\"\n to: \"event.action\"\n - from: \"soc.level\"\n to: \"log.level\"\n ignore_missing: true",
|
||||||
"tags": [
|
"tags": [
|
||||||
"so-soc"
|
"so-soc"
|
||||||
],
|
],
|
||||||
"processors": "- decode_json_fields:\n fields: [\"message\"]\n target: \"soc\"\n process_array: true\n max_depth: 2\n add_error_key: true \n- add_fields:\n target: event\n fields:\n category: host\n module: soc\n dataset_temp: detections\n- rename:\n fields:\n - from: \"soc.fields.sourceIp\"\n to: \"source.ip\"\n - from: \"soc.fields.status\"\n to: \"http.response.status_code\"\n - from: \"soc.fields.method\"\n to: \"http.request.method\"\n - from: \"soc.fields.path\"\n to: \"url.path\"\n - from: \"soc.message\"\n to: \"event.action\"\n - from: \"soc.level\"\n to: \"log.level\"\n ignore_missing: true",
|
"recursive_glob": true,
|
||||||
"custom": "pipeline: common"
|
"ignore_older": "72h",
|
||||||
|
"clean_inactive": -1,
|
||||||
|
"harvester_limit": 0,
|
||||||
|
"fingerprint": false,
|
||||||
|
"fingerprint_offset": 0,
|
||||||
|
"file_identity_native": true,
|
||||||
|
"exclude_lines": [],
|
||||||
|
"include_lines": [],
|
||||||
|
"delete_enabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"force": true
|
"force": true
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user