mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2026-01-20 15:11:31 +01:00
Compare commits
786 Commits
2.4.60-202
...
2.4.80-202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2d43e5d22 | ||
|
|
51bb4837f5 | ||
|
|
caec424e44 | ||
|
|
156176c628 | ||
|
|
81b4c4e2c0 | ||
|
|
d4107dc60a | ||
|
|
d34605a512 | ||
|
|
af5e7cd72c | ||
|
|
93378e92e6 | ||
|
|
81ce762250 | ||
|
|
cb727bf48d | ||
|
|
9a0bad88cc | ||
|
|
680e84851b | ||
|
|
ea771ed21b | ||
|
|
c332cd777c | ||
|
|
9fce85c988 | ||
|
|
6141c7a849 | ||
|
|
bf91030204 | ||
|
|
9577c3f59d | ||
|
|
77dedc575e | ||
|
|
0295b8d658 | ||
|
|
6a9d78fa7c | ||
|
|
b84521cdd2 | ||
|
|
ff4679ec08 | ||
|
|
c5ce7102e8 | ||
|
|
70c001e22b | ||
|
|
f1dc22a200 | ||
|
|
aae1b69093 | ||
|
|
8781419b4a | ||
|
|
2eea671857 | ||
|
|
73acfbf864 | ||
|
|
ae0e994461 | ||
|
|
07b9011636 | ||
|
|
bc2b3b7f8f | ||
|
|
ea02a2b868 | ||
|
|
ba3a6cbe87 | ||
|
|
268dcbe00b | ||
|
|
6be97f13d0 | ||
|
|
95d6c93a07 | ||
|
|
a2bb220043 | ||
|
|
911d6dcce1 | ||
|
|
5f6a9850eb | ||
|
|
de18bf06c3 | ||
|
|
73473d671d | ||
|
|
3fbab7c3af | ||
|
|
521cccaed6 | ||
|
|
35da3408dc | ||
|
|
c03096e806 | ||
|
|
2afc947d6c | ||
|
|
076da649cf | ||
|
|
93ced0959c | ||
|
|
6f13fa50bf | ||
|
|
3bface12e0 | ||
|
|
b584c8e353 | ||
|
|
6caf87df2d | ||
|
|
4d1f2c2bc1 | ||
|
|
0b1175b46c | ||
|
|
4e50dabc56 | ||
|
|
ce45a5926a | ||
|
|
c540a4f257 | ||
|
|
7af94c172f | ||
|
|
7556587e35 | ||
|
|
a0030b27e2 | ||
|
|
8080e05444 | ||
|
|
af11879545 | ||
|
|
c89f1c9d95 | ||
|
|
b7ac599a42 | ||
|
|
8363877c66 | ||
|
|
4bcb4b5b9c | ||
|
|
68302e14b9 | ||
|
|
c1abc7a7f1 | ||
|
|
484717d57d | ||
|
|
b91c608fcf | ||
|
|
8f8ece2b34 | ||
|
|
9b5c1c01e9 | ||
|
|
816a1d446e | ||
|
|
19bfd5beca | ||
|
|
9ac7e051b3 | ||
|
|
80b1d51f76 | ||
|
|
6340ebb36d | ||
|
|
70721afa51 | ||
|
|
9c31622598 | ||
|
|
f372b0907b | ||
|
|
fac96e0b08 | ||
|
|
2bc53f9868 | ||
|
|
e8106befe9 | ||
|
|
83412b813f | ||
|
|
b56d497543 | ||
|
|
dd40962288 | ||
|
|
b7eebad2a5 | ||
|
|
092f716f12 | ||
|
|
c38f48c7f2 | ||
|
|
d5ef0e5744 | ||
|
|
e90557d7dc | ||
|
|
628893fd5b | ||
|
|
a81e4c3362 | ||
|
|
ca7b89c308 | ||
|
|
03335cc015 | ||
|
|
08557ae287 | ||
|
|
08d2a6242d | ||
|
|
4b481bd405 | ||
|
|
0b1e3b2a7f | ||
|
|
dbd9873450 | ||
|
|
c6d0a17669 | ||
|
|
adeab10f6d | ||
|
|
824f852ed7 | ||
|
|
284c1be85f | ||
|
|
7ad6baf483 | ||
|
|
f1638faa3a | ||
|
|
dea786abfa | ||
|
|
f96b82b112 | ||
|
|
95fe11c6b4 | ||
|
|
f2f688b9b8 | ||
|
|
0139e18271 | ||
|
|
657995d744 | ||
|
|
4057238185 | ||
|
|
fb07ff65c9 | ||
|
|
dbc56ffee7 | ||
|
|
ee696be51d | ||
|
|
5d3fd3d389 | ||
|
|
fa063722e1 | ||
|
|
f5cc35509b | ||
|
|
d39c8fae54 | ||
|
|
d3b81babec | ||
|
|
f35f6bd4c8 | ||
|
|
d5cfef94a3 | ||
|
|
f37f5ba97b | ||
|
|
42818a9950 | ||
|
|
e85c3e5b27 | ||
|
|
a39c88c7b4 | ||
|
|
73ebf5256a | ||
|
|
6d31cd2a41 | ||
|
|
5600fed9c4 | ||
|
|
6920b77b4a | ||
|
|
ccd6b3914c | ||
|
|
c4723263a4 | ||
|
|
4581a46529 | ||
|
|
33a2c5dcd8 | ||
|
|
f6a8a21f94 | ||
|
|
ff5773c837 | ||
|
|
66f8084916 | ||
|
|
a2467d0418 | ||
|
|
3b0339a9b3 | ||
|
|
fb1d4fdd3c | ||
|
|
56a16539ae | ||
|
|
c0b2cf7388 | ||
|
|
d9c58d9333 | ||
|
|
ef3a52468f | ||
|
|
c88b731793 | ||
|
|
2e85a28c02 | ||
|
|
964fef1aab | ||
|
|
1a832fa0a5 | ||
|
|
75bdc92bbf | ||
|
|
a8c231ad8c | ||
|
|
f396247838 | ||
|
|
e3ea4776c7 | ||
|
|
37a928b065 | ||
|
|
85c269e697 | ||
|
|
6e70268ab9 | ||
|
|
fb8929ea37 | ||
|
|
5d9c0dd8b5 | ||
|
|
debf093c54 | ||
|
|
00b5a5cc0c | ||
|
|
dbb99d0367 | ||
|
|
7702f05756 | ||
|
|
2c635bce62 | ||
|
|
48713a4e7b | ||
|
|
e831354401 | ||
|
|
55c5ea5c4c | ||
|
|
1fd5165079 | ||
|
|
949cea95f4 | ||
|
|
12762e08ef | ||
|
|
62bdb2627a | ||
|
|
386be4e746 | ||
|
|
dfcf7a436f | ||
|
|
d9ec556061 | ||
|
|
876d860488 | ||
|
|
88651219a6 | ||
|
|
a655f8dc04 | ||
|
|
e98b8566c9 | ||
|
|
ef10794e3b | ||
|
|
0d034e7adc | ||
|
|
59097070ef | ||
|
|
77b5aa4369 | ||
|
|
0d7c331ff0 | ||
|
|
1c1a1a1d3f | ||
|
|
47efcfd6e2 | ||
|
|
15a0b959aa | ||
|
|
ca49943a7f | ||
|
|
ee4ca0d7a2 | ||
|
|
0d634f3b8e | ||
|
|
f68ac23f0e | ||
|
|
825c4a9adb | ||
|
|
2a2b86ebe6 | ||
|
|
74dfc25376 | ||
|
|
81ee60e658 | ||
|
|
fcb6a47e8c | ||
|
|
49fd84a3a7 | ||
|
|
58b565558d | ||
|
|
185fb38b2d | ||
|
|
550b3ee92d | ||
|
|
29a87fd166 | ||
|
|
f90d40b471 | ||
|
|
4344988abe | ||
|
|
979147a111 | ||
|
|
66725b11b3 | ||
|
|
19f9c4e389 | ||
|
|
bd11d59c15 | ||
|
|
15155613c3 | ||
|
|
b5f656ae58 | ||
|
|
7177392adc | ||
|
|
ea7715f729 | ||
|
|
0b9ebefdb6 | ||
|
|
19e66604d0 | ||
|
|
1e6161f89c | ||
|
|
a8c287c491 | ||
|
|
2c4f5f0a91 | ||
|
|
8e7c487cb0 | ||
|
|
3d4f3a04a3 | ||
|
|
ce063cf435 | ||
|
|
a072e34cfe | ||
|
|
d19c1a514b | ||
|
|
b415810485 | ||
|
|
3cfd710756 | ||
|
|
382cd24a57 | ||
|
|
b1beb617b3 | ||
|
|
91f8b1fef7 | ||
|
|
ca6e2b8e22 | ||
|
|
8af3158ea7 | ||
|
|
8b011b8d7e | ||
|
|
f9e9b825cf | ||
|
|
3992ef1082 | ||
|
|
556fdfdcf9 | ||
|
|
f4490fab58 | ||
|
|
5aaf44ebb2 | ||
|
|
deb140e38e | ||
|
|
3de6454d4f | ||
|
|
d57cc9627f | ||
|
|
8ce19a93b9 | ||
|
|
d315b95d77 | ||
|
|
6172816f61 | ||
|
|
03826dd32c | ||
|
|
b7a4f20c61 | ||
|
|
02b4d37c11 | ||
|
|
f8ce039065 | ||
|
|
e2d0b8f4c7 | ||
|
|
8a3061fe3e | ||
|
|
c594168b65 | ||
|
|
31fdf15ce1 | ||
|
|
6b2219b7f2 | ||
|
|
64144b4759 | ||
|
|
6e97c39f58 | ||
|
|
026023fd0a | ||
|
|
d7ee89542a | ||
|
|
6fac6eebce | ||
|
|
3c3497c2fd | ||
|
|
fcc72a4f4e | ||
|
|
28dea9be58 | ||
|
|
0cc57fc240 | ||
|
|
17518b90ca | ||
|
|
d9edff38df | ||
|
|
300d8436a8 | ||
|
|
1c4d36760a | ||
|
|
34a5985311 | ||
|
|
aa0163349b | ||
|
|
572b8d08d9 | ||
|
|
cc6cb346e7 | ||
|
|
b54632080e | ||
|
|
44d3468f65 | ||
|
|
9d4668f4d3 | ||
|
|
da2ac4776e | ||
|
|
9796354b48 | ||
|
|
aa32eb9c0e | ||
|
|
4771810361 | ||
|
|
52f27c00ce | ||
|
|
ab9ec2ec6b | ||
|
|
4d7835612d | ||
|
|
8076ea0e0a | ||
|
|
320ae641b1 | ||
|
|
b4aec9a9d0 | ||
|
|
6af0308482 | ||
|
|
08024c7511 | ||
|
|
3a56058f7f | ||
|
|
795de7ab07 | ||
|
|
8803ad4018 | ||
|
|
62a8024c6c | ||
|
|
ea253726a0 | ||
|
|
a0af25c314 | ||
|
|
e3a0847867 | ||
|
|
7345d2c5a6 | ||
|
|
7cbc3a83c6 | ||
|
|
427b1e4524 | ||
|
|
2dbbe8dec4 | ||
|
|
e76c2c95a9 | ||
|
|
51862e5803 | ||
|
|
27ad84ebd9 | ||
|
|
67645a662d | ||
|
|
1d16f6b7ed | ||
|
|
5b45c80a62 | ||
|
|
6dec9b4cf7 | ||
|
|
13062099b3 | ||
|
|
7250fb1188 | ||
|
|
437d0028db | ||
|
|
1ef9509aac | ||
|
|
d606f259d1 | ||
|
|
c8870eae65 | ||
|
|
2419066dc8 | ||
|
|
e430de88d3 | ||
|
|
c4c38f58cb | ||
|
|
26b5a39912 | ||
|
|
eb03858230 | ||
|
|
2643da978b | ||
|
|
649f52dac7 | ||
|
|
927fe91f25 | ||
|
|
9d6f6c7893 | ||
|
|
28e40e42b3 | ||
|
|
6c71c45ef6 | ||
|
|
641899ad56 | ||
|
|
d120326cb9 | ||
|
|
a4f2d8f327 | ||
|
|
ae323cf385 | ||
|
|
788c31014d | ||
|
|
154dc605ef | ||
|
|
2a0e33401d | ||
|
|
79b4d7b6b6 | ||
|
|
986cbb129a | ||
|
|
950c68783c | ||
|
|
cec75ba475 | ||
|
|
26cb8d43e1 | ||
|
|
a1291e43c3 | ||
|
|
45fd07cdf8 | ||
|
|
fecd674fdb | ||
|
|
dff2de4527 | ||
|
|
19e1aaa1a6 | ||
|
|
074d063fee | ||
|
|
6ed82d7b29 | ||
|
|
ea4cf42913 | ||
|
|
8a34f5621c | ||
|
|
823ff7ce11 | ||
|
|
fb8456b4a6 | ||
|
|
c864fec70c | ||
|
|
a74fee4cd0 | ||
|
|
3a99624eb8 | ||
|
|
656bf60fda | ||
|
|
cdc47cb1cd | ||
|
|
01a68568a6 | ||
|
|
2ad87bf1fe | ||
|
|
eca2a4a9c8 | ||
|
|
dff609d829 | ||
|
|
b916465b06 | ||
|
|
0567b93534 | ||
|
|
ad9fdf064b | ||
|
|
77e2117051 | ||
|
|
5b7b6e5fb8 | ||
|
|
c7845bdf56 | ||
|
|
5a5a1e86ac | ||
|
|
796eefc2f0 | ||
|
|
1862deaf5e | ||
|
|
0d2e5e0065 | ||
|
|
5dc098f0fc | ||
|
|
af681881e6 | ||
|
|
47dc911b79 | ||
|
|
6d2ecce9b7 | ||
|
|
326c59bb26 | ||
|
|
c1257f1c13 | ||
|
|
2eee617788 | ||
|
|
70ef8092a7 | ||
|
|
8364b2a730 | ||
|
|
cb7dea1295 | ||
|
|
1da88b70ac | ||
|
|
b4817fa062 | ||
|
|
bc24227732 | ||
|
|
2e70d157e2 | ||
|
|
5e2e5b2724 | ||
|
|
dcc1f656ee | ||
|
|
23da1f6ee9 | ||
|
|
bee8c2c1ce | ||
|
|
4ebe070cd8 | ||
|
|
a5e89c0854 | ||
|
|
a25e43db8f | ||
|
|
b997e44715 | ||
|
|
1e48955376 | ||
|
|
5056ec526b | ||
|
|
2431d7b028 | ||
|
|
d2fa77ae10 | ||
|
|
445fb31634 | ||
|
|
5aa611302a | ||
|
|
554a203541 | ||
|
|
be1758aea7 | ||
|
|
38f74d2e9e | ||
|
|
5b966b83a9 | ||
|
|
a67f0d93a0 | ||
|
|
3f73b14a6a | ||
|
|
e57d1a5fb5 | ||
|
|
f689cfcd0a | ||
|
|
26c6a98b45 | ||
|
|
45c344e3fa | ||
|
|
7b905f5a94 | ||
|
|
6d5ff59657 | ||
|
|
7f12d4c815 | ||
|
|
b50789a77c | ||
|
|
bdf1b45a07 | ||
|
|
3d4fd59a15 | ||
|
|
91c9f26a0c | ||
|
|
6cbbb81cad | ||
|
|
442a717d75 | ||
|
|
fa3522a233 | ||
|
|
bbc374b56e | ||
|
|
9ae6fc5666 | ||
|
|
5fe8c6a95f | ||
|
|
2929877042 | ||
|
|
8035740d2b | ||
|
|
4f8aaba6c6 | ||
|
|
e9b1263249 | ||
|
|
3b2d3573d8 | ||
|
|
e960ae66a3 | ||
|
|
093cbc5ebc | ||
|
|
f663ef8c16 | ||
|
|
de9f6425f9 | ||
|
|
33d1170a91 | ||
|
|
240ffc0862 | ||
|
|
0822a46e94 | ||
|
|
1be3e6204d | ||
|
|
956ae7a7ae | ||
|
|
3285ae9366 | ||
|
|
47ced60243 | ||
|
|
72b2503b49 | ||
|
|
58ebbfba20 | ||
|
|
e164d15ec6 | ||
|
|
3efdb4e532 | ||
|
|
854799fabb | ||
|
|
47ba4c0f57 | ||
|
|
10c8e4203c | ||
|
|
05c69925c9 | ||
|
|
252d9a5320 | ||
|
|
7122709bbf | ||
|
|
f7223f132a | ||
|
|
8cd75902f2 | ||
|
|
c71af9127b | ||
|
|
e6f45161c1 | ||
|
|
fe2edeb2fb | ||
|
|
6294f751ee | ||
|
|
de0af58cf8 | ||
|
|
84abfa6881 | ||
|
|
6b60e85a33 | ||
|
|
63f3e23e2b | ||
|
|
ad1cda1746 | ||
|
|
66563a4da0 | ||
|
|
d0e140cf7b | ||
|
|
87c6d0a820 | ||
|
|
eb1249618b | ||
|
|
cef9bb1487 | ||
|
|
9a25d3c30f | ||
|
|
9a4a85e3ae | ||
|
|
bb49944b96 | ||
|
|
72db369fbb | ||
|
|
84db82852c | ||
|
|
fcc4050f86 | ||
|
|
9c83a52c6d | ||
|
|
ea4750d8ad | ||
|
|
e9944796c8 | ||
|
|
4d6124f982 | ||
|
|
dd168e1cca | ||
|
|
ddf662bdb4 | ||
|
|
fadb6e2aa9 | ||
|
|
192d91565d | ||
|
|
82ef4c96c3 | ||
|
|
a6e8b25969 | ||
|
|
529bc01d69 | ||
|
|
a663bf63c6 | ||
|
|
11055b1d32 | ||
|
|
fd9a91420d | ||
|
|
529c8d7cf2 | ||
|
|
13ccb58f84 | ||
|
|
086ebe1a7c | ||
|
|
29c964cca1 | ||
|
|
f2c3c928fc | ||
|
|
3cbc29e767 | ||
|
|
89cb8b79fd | ||
|
|
b5c5c7857b | ||
|
|
ed05d51969 | ||
|
|
2c7eb3c755 | ||
|
|
cc17de2184 | ||
|
|
b424426298 | ||
|
|
03f9160fcc | ||
|
|
d50de804a8 | ||
|
|
983ef362e9 | ||
|
|
d88c1a5e0a | ||
|
|
44afa55274 | ||
|
|
ab832e4bb2 | ||
|
|
3c3ed8b5c5 | ||
|
|
c9d9979f22 | ||
|
|
383420b554 | ||
|
|
73b5bb1a75 | ||
|
|
59a02635ed | ||
|
|
13a6520a8c | ||
|
|
4b7f826a2a | ||
|
|
0bd0c7b1ec | ||
|
|
428fe787c4 | ||
|
|
1b3a0a3de8 | ||
|
|
96ec285241 | ||
|
|
75b5e16696 | ||
|
|
8a0a435700 | ||
|
|
e53e7768a0 | ||
|
|
36573d6005 | ||
|
|
aa0c589361 | ||
|
|
bef408b944 | ||
|
|
691b02a15e | ||
|
|
fc1c41e5a4 | ||
|
|
58ddd55123 | ||
|
|
685b80e519 | ||
|
|
5a401af1fd | ||
|
|
25d63f7516 | ||
|
|
d402943403 | ||
|
|
64c43b1a55 | ||
|
|
a237ef5d96 | ||
|
|
6c5e0579cf | ||
|
|
4ac04a1a46 | ||
|
|
746128e37b | ||
|
|
fe81ffaf78 | ||
|
|
1f6eb9cdc3 | ||
|
|
c48da45ac3 | ||
|
|
5cc358de4e | ||
|
|
406dda6051 | ||
|
|
229a989914 | ||
|
|
6c6647629c | ||
|
|
610dd2c08d | ||
|
|
506bbd314d | ||
|
|
7f9bc1fc0f | ||
|
|
8d9aae1983 | ||
|
|
4caa6a10b5 | ||
|
|
665b7197a6 | ||
|
|
3854620bcd | ||
|
|
67a57e9df7 | ||
|
|
4b79623ce3 | ||
|
|
ff28476191 | ||
|
|
8cc4d2668e | ||
|
|
dbfb178556 | ||
|
|
c4994a208b | ||
|
|
eedea2ca88 | ||
|
|
de6ea29e3b | ||
|
|
bb983d4ba2 | ||
|
|
5e8b16569f | ||
|
|
c014508519 | ||
|
|
f5e42e73af | ||
|
|
fcfbb1e857 | ||
|
|
911ee579a9 | ||
|
|
a6ff92b099 | ||
|
|
d73ba7dd3e | ||
|
|
04ddcd5c93 | ||
|
|
af29ae1968 | ||
|
|
fbd3cff90d | ||
|
|
0ed9894b7e | ||
|
|
a54a72c269 | ||
|
|
5b81a73e58 | ||
|
|
49ccd86c39 | ||
|
|
f514e5e9bb | ||
|
|
3955587372 | ||
|
|
6b28dc72e8 | ||
|
|
ca7253a589 | ||
|
|
af53dcda1b | ||
|
|
55cf90f477 | ||
|
|
c269fb90ac | ||
|
|
1250a728ac | ||
|
|
68e016090b | ||
|
|
fd689a4607 | ||
|
|
ae09869417 | ||
|
|
1c5f02ade2 | ||
|
|
ed97aa4e78 | ||
|
|
7124f04138 | ||
|
|
2ab9cbba61 | ||
|
|
4097e1d81a | ||
|
|
d3bd56b131 | ||
|
|
e9e61ea2d8 | ||
|
|
86b984001d | ||
|
|
2206553e03 | ||
|
|
fa7f8104c8 | ||
|
|
bd5fe43285 | ||
|
|
d38051e806 | ||
|
|
daa5342986 | ||
|
|
c48436ccbf | ||
|
|
7aa00faa6c | ||
|
|
6217a7b9a9 | ||
|
|
d67ebabc95 | ||
|
|
b9474b9352 | ||
|
|
376efab40c | ||
|
|
65274e89d7 | ||
|
|
acf29a6c9c | ||
|
|
721e04f793 | ||
|
|
00cea6fb80 | ||
|
|
433309ef1a | ||
|
|
cbc95d0b30 | ||
|
|
21f86be8ee | ||
|
|
8e38c3763e | ||
|
|
ca807bd6bd | ||
|
|
735cfb4c29 | ||
|
|
6202090836 | ||
|
|
436cbc1f06 | ||
|
|
40b08d737c | ||
|
|
4c5b42b898 | ||
|
|
7a6b72ebac | ||
|
|
f72cbd5f23 | ||
|
|
1d7e47f589 | ||
|
|
49d5fa95a2 | ||
|
|
204f44449a | ||
|
|
6046848ee7 | ||
|
|
b0aee238b1 | ||
|
|
d8ac3f1292 | ||
|
|
8788b34c8a | ||
|
|
784ec54795 | ||
|
|
54fce4bf8f | ||
|
|
c4ebe25bab | ||
|
|
7b4e207329 | ||
|
|
5ec3b834fb | ||
|
|
7668fa1396 | ||
|
|
470b0e4bf6 | ||
|
|
d3f163bf9e | ||
|
|
4b31632dfc | ||
|
|
c2f7f7e3a5 | ||
|
|
07cb0c7d46 | ||
|
|
14c824143b | ||
|
|
c75c411426 | ||
|
|
a7fab380b4 | ||
|
|
a9517e1291 | ||
|
|
1017838cfc | ||
|
|
1d221a574b | ||
|
|
a35bfc4822 | ||
|
|
7c64fc8c05 | ||
|
|
f66cca96ce | ||
|
|
12da7db22c | ||
|
|
1b8584d4bb | ||
|
|
9c59f42c16 | ||
|
|
fb5eea8284 | ||
|
|
9db9af27ae | ||
|
|
0f50a265cf | ||
|
|
3e05c04aa1 | ||
|
|
8f8896c505 | ||
|
|
941a841da0 | ||
|
|
13105c4ab3 | ||
|
|
dc27bbb01d | ||
|
|
2b8a051525 | ||
|
|
1c7cc8dd3b | ||
|
|
58d081eed1 | ||
|
|
9078b2bad2 | ||
|
|
8889c974b8 | ||
|
|
f615a73120 | ||
|
|
66844af1c2 | ||
|
|
a0b7d89eb6 | ||
|
|
c31e459c2b | ||
|
|
b863060df1 | ||
|
|
d96d696c35 | ||
|
|
105eadf111 | ||
|
|
ca57c20691 | ||
|
|
c4767bfdc8 | ||
|
|
0de1f76139 | ||
|
|
5f4a0fdfad | ||
|
|
18f95e867f | ||
|
|
ed6137a76a | ||
|
|
c3f02a698e | ||
|
|
db106f8ca1 | ||
|
|
c712529cf6 | ||
|
|
976ddd3982 | ||
|
|
64748b98ad | ||
|
|
3335612365 | ||
|
|
513273c8c3 | ||
|
|
0dfde3c9f2 | ||
|
|
0efdcfcb52 | ||
|
|
fbdcc53fe0 | ||
|
|
8e47cc73a5 | ||
|
|
639bf05081 | ||
|
|
c1b5ef0891 | ||
|
|
a8f25150f6 | ||
|
|
1ee2a6d37b | ||
|
|
f64d9224fb | ||
|
|
4e142e0212 | ||
|
|
c9bf1c86c6 | ||
|
|
82830c8173 | ||
|
|
7f5741c43b | ||
|
|
643d4831c1 | ||
|
|
b032eed22a | ||
|
|
1b49c8540e | ||
|
|
f7534a0ae3 | ||
|
|
b6187ab769 | ||
|
|
780ad9eb10 | ||
|
|
283939b18a | ||
|
|
e25bc8efe4 | ||
|
|
3b112e20e3 | ||
|
|
26abe90671 | ||
|
|
23a6c4adb6 | ||
|
|
2f03cbf115 | ||
|
|
a678a5a416 | ||
|
|
b2b54ccf60 | ||
|
|
55e71c867c | ||
|
|
6c2437f8ef | ||
|
|
261f2cbaf7 | ||
|
|
f083558666 | ||
|
|
505eeea66a | ||
|
|
1001aa665d | ||
|
|
7f488422b0 | ||
|
|
f17d8d3369 | ||
|
|
ff777560ac | ||
|
|
2c68fd6311 | ||
|
|
c1bf710e46 | ||
|
|
9d2b40f366 | ||
|
|
3aea2dec85 | ||
|
|
65f6b7022c | ||
|
|
e5a3a54aea | ||
|
|
be88dbe181 | ||
|
|
b64ed5535e | ||
|
|
5be56703e9 | ||
|
|
0c7ba62867 | ||
|
|
d9d851040c | ||
|
|
e747a4e3fe | ||
|
|
000d15a53c | ||
|
|
cc2164221c | ||
|
|
102c3271d1 | ||
|
|
32b8649c77 | ||
|
|
9c5ba92589 | ||
|
|
d2c9e0ea4a | ||
|
|
2928b71616 | ||
|
|
216b8c01bf | ||
|
|
ce0c9f846d | ||
|
|
ba262ee01a | ||
|
|
b571eeb8e6 | ||
|
|
7fe377f899 | ||
|
|
d57f773072 | ||
|
|
389357ad2b | ||
|
|
e2caf4668e | ||
|
|
63a58efba4 | ||
|
|
bbcd3116f7 | ||
|
|
9c12aa261e | ||
|
|
cc0f4847ba | ||
|
|
923b80ba60 | ||
|
|
7c4ea8a58e | ||
|
|
20bd9a9701 | ||
|
|
f0cb30a649 | ||
|
|
94ee761207 | ||
|
|
0a5dc411d0 | ||
|
|
d7ecad4333 | ||
|
|
49fa800b2b | ||
|
|
446f1ffdf5 | ||
|
|
57553bc1e5 | ||
|
|
df058b3f4a | ||
|
|
5e21da443f | ||
|
|
7898277a9b | ||
|
|
029d8a0e8f | ||
|
|
b8d33ab983 | ||
|
|
e124791d5d | ||
|
|
8ae30d0a77 | ||
|
|
81f3d69eb9 | ||
|
|
237946e916 | ||
|
|
3d04d37030 | ||
|
|
bb0da2a5c5 | ||
|
|
d6ce3851ec | ||
|
|
9c6f3f4808 | ||
|
|
1ab56033a2 | ||
|
|
a78a304d4f | ||
|
|
5ca9ec4b17 | ||
|
|
4e1543b6a8 | ||
|
|
0e7d08b957 | ||
|
|
f889a089bf | ||
|
|
2b019ec8fe | ||
|
|
5934829e0d | ||
|
|
486a633dfe | ||
|
|
77ac342786 | ||
|
|
8429a364dc | ||
|
|
1568f57096 | ||
|
|
f431e9ae08 | ||
|
|
4b03d088c3 | ||
|
|
4a33234c34 | ||
|
|
778997bed4 | ||
|
|
655d3e349c | ||
|
|
f3b921342e | ||
|
|
fff4d20e39 | ||
|
|
d2fb067110 | ||
|
|
876690a9f6 | ||
|
|
4c2f2759d4 | ||
|
|
dd603934bc | ||
|
|
d4d17e1835 | ||
|
|
d84af803a6 | ||
|
|
020eb47026 | ||
|
|
c6df805556 | ||
|
|
47d447eadd | ||
|
|
af5b3feb96 | ||
|
|
8cf29682bb | ||
|
|
86dc7cc804 |
2
.github/.gitleaks.toml
vendored
2
.github/.gitleaks.toml
vendored
@@ -536,7 +536,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.*''']
|
||||
regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*''', '''.*:.*StrelkaHexDump.*''', '''.*:.*PLACEHOLDER.*''', '''ssl_.*password''']
|
||||
paths = [
|
||||
'''gitleaks.toml''',
|
||||
'''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
|
||||
|
||||
33
.github/workflows/close-threads.yml
vendored
Normal file
33
.github/workflows/close-threads.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: 'Close Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '50 1 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
discussions: write
|
||||
|
||||
concurrency:
|
||||
group: lock-threads
|
||||
|
||||
jobs:
|
||||
close-threads:
|
||||
if: github.repository_owner == 'security-onion-solutions'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
days-before-issue-stale: -1
|
||||
days-before-issue-close: 60
|
||||
stale-issue-message: "This issue is stale because it has been inactive for an extended period. Stale issues convey that the issue, while important to someone, is not critical enough for the author, or other community members to work on, sponsor, or otherwise shepherd the issue through to a resolution."
|
||||
close-issue-message: "This issue was closed because it has been stale for an extended period. It will be automatically locked in 30 days, after which no further commenting will be available."
|
||||
days-before-pr-stale: 45
|
||||
days-before-pr-close: 60
|
||||
stale-pr-message: "This PR is stale because it has been inactive for an extended period. The longer a PR remains stale the more out of date with the main branch it becomes."
|
||||
close-pr-message: "This PR was closed because it has been stale for an extended period. It will be automatically locked in 30 days. If there is still a commitment to finishing this PR re-open it before it is locked."
|
||||
20
.github/workflows/lock-threads.yml
vendored
20
.github/workflows/lock-threads.yml
vendored
@@ -2,7 +2,7 @@ name: 'Lock Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '50 1 * * *'
|
||||
- cron: '50 2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -14,24 +14,8 @@ concurrency:
|
||||
group: lock-threads
|
||||
|
||||
jobs:
|
||||
close-threads:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
days-before-issue-stale: -1
|
||||
days-before-issue-close: 60
|
||||
stale-issue-message: "This issue is stale because it has been inactive for an extended period. Stale issues convey that the issue, while important to someone, is not critical enough for the author, or other community members to work on, sponsor, or otherwise shepherd the issue through to a resolution."
|
||||
close-issue-message: "This issue was closed because it has been stale for an extended period. It will be automatically locked in 30 days, after which no further commenting will be available."
|
||||
days-before-pr-stale: 45
|
||||
days-before-pr-close: 60
|
||||
stale-pr-message: "This PR is stale because it has been inactive for an extended period. The longer a PR remains stale the more out of date with the main branch it becomes."
|
||||
close-pr-message: "This PR was closed because it has been stale for an extended period. It will be automatically locked in 30 days. If there is still a commitment to finishing this PR re-open it before it is locked."
|
||||
|
||||
lock-threads:
|
||||
if: github.repository_owner == 'security-onion-solutions'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: jertel/lock-threads@main
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
### 2.4.60-20240320 ISO image released on 2024/03/20
|
||||
### 2.4.80-20240624 ISO image released on 2024/06/25
|
||||
|
||||
|
||||
### Download and Verify
|
||||
|
||||
2.4.60-20240320 ISO image:
|
||||
https://download.securityonion.net/file/securityonion/securityonion-2.4.60-20240320.iso
|
||||
2.4.80-20240624 ISO image:
|
||||
https://download.securityonion.net/file/securityonion/securityonion-2.4.80-20240624.iso
|
||||
|
||||
MD5: 178DD42D06B2F32F3870E0C27219821E
|
||||
SHA1: 73EDCD50817A7F6003FE405CF1808A30D034F89D
|
||||
SHA256: DD334B8D7088A7B78160C253B680D645E25984BA5CCAB5CC5C327CA72137FC06
|
||||
MD5: 139F9762E926F9CB3C4A9528A3752C31
|
||||
SHA1: BC6CA2C5F4ABC1A04E83A5CF8FFA6A53B1583CC9
|
||||
SHA256: 70E90845C84FFA30AD6CF21504634F57C273E7996CA72F7250428DDBAAC5B1BD
|
||||
|
||||
Signature for ISO image:
|
||||
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.60-20240320.iso.sig
|
||||
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.80-20240624.iso.sig
|
||||
|
||||
Signing key:
|
||||
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS
|
||||
@@ -25,27 +25,29 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.
|
||||
|
||||
Download the signature file for the ISO:
|
||||
```
|
||||
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.60-20240320.iso.sig
|
||||
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.80-20240624.iso.sig
|
||||
```
|
||||
|
||||
Download the ISO image:
|
||||
```
|
||||
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.60-20240320.iso
|
||||
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.80-20240624.iso
|
||||
```
|
||||
|
||||
Verify the downloaded ISO image using the signature file:
|
||||
```
|
||||
gpg --verify securityonion-2.4.60-20240320.iso.sig securityonion-2.4.60-20240320.iso
|
||||
gpg --verify securityonion-2.4.80-20240624.iso.sig securityonion-2.4.80-20240624.iso
|
||||
```
|
||||
|
||||
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
|
||||
```
|
||||
gpg: Signature made Tue 19 Mar 2024 03:17:58 PM EDT using RSA key ID FE507013
|
||||
gpg: Signature made Mon 24 Jun 2024 02:42:03 PM EDT using RSA key ID FE507013
|
||||
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
13
README.md
13
README.md
@@ -8,19 +8,22 @@ Alerts
|
||||

|
||||
|
||||
Dashboards
|
||||

|
||||

|
||||
|
||||
Hunt
|
||||

|
||||

|
||||
|
||||
Detections
|
||||

|
||||
|
||||
PCAP
|
||||

|
||||

|
||||
|
||||
Grid
|
||||

|
||||

|
||||
|
||||
Config
|
||||

|
||||

|
||||
|
||||
### Release Notes
|
||||
|
||||
|
||||
@@ -19,4 +19,4 @@ role:
|
||||
receiver:
|
||||
standalone:
|
||||
searchnode:
|
||||
sensor:
|
||||
sensor:
|
||||
2
pillar/kafka/nodes.sls
Normal file
2
pillar/kafka/nodes.sls
Normal file
@@ -0,0 +1,2 @@
|
||||
kafka:
|
||||
nodes:
|
||||
@@ -43,8 +43,6 @@ base:
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- soctopus.soc_soctopus
|
||||
- soctopus.adv_soctopus
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- kratos.soc_kratos
|
||||
@@ -61,10 +59,11 @@ base:
|
||||
- elastalert.adv_elastalert
|
||||
- backup.soc_backup
|
||||
- backup.adv_backup
|
||||
- soctopus.soc_soctopus
|
||||
- soctopus.adv_soctopus
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
- stig.soc_stig
|
||||
|
||||
'*_sensor':
|
||||
@@ -108,8 +107,6 @@ base:
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- soctopus.soc_soctopus
|
||||
- soctopus.adv_soctopus
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- strelka.soc_strelka
|
||||
@@ -165,8 +162,6 @@ base:
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- soctopus.soc_soctopus
|
||||
- soctopus.adv_soctopus
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- strelka.soc_strelka
|
||||
@@ -184,6 +179,9 @@ base:
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- stig.soc_stig
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
|
||||
'*_heavynode':
|
||||
- elasticsearch.auth
|
||||
@@ -228,6 +226,7 @@ base:
|
||||
- minions.adv_{{ grains.id }}
|
||||
- stig.soc_stig
|
||||
- soc.license
|
||||
- kafka.nodes
|
||||
|
||||
'*_receiver':
|
||||
- logstash.nodes
|
||||
@@ -240,6 +239,10 @@ base:
|
||||
- redis.adv_redis
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
- soc.license
|
||||
|
||||
'*_import':
|
||||
- secrets
|
||||
@@ -262,8 +265,6 @@ base:
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- soctopus.soc_soctopus
|
||||
- soctopus.adv_soctopus
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- backup.soc_backup
|
||||
|
||||
14
pyci.sh
14
pyci.sh
@@ -15,12 +15,16 @@ TARGET_DIR=${1:-.}
|
||||
|
||||
PATH=$PATH:/usr/local/bin
|
||||
|
||||
if ! which pytest &> /dev/null || ! which flake8 &> /dev/null ; then
|
||||
echo "Missing dependencies. Consider running the following command:"
|
||||
echo " python -m pip install flake8 pytest pytest-cov"
|
||||
if [ ! -d .venv ]; then
|
||||
python -m venv .venv
|
||||
fi
|
||||
|
||||
source .venv/bin/activate
|
||||
|
||||
if ! pip install flake8 pytest pytest-cov pyyaml; then
|
||||
echo "Unable to install dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pip install pytest pytest-cov
|
||||
flake8 "$TARGET_DIR" "--config=${HOME_DIR}/pytest.ini"
|
||||
python3 -m pytest "--cov-config=${HOME_DIR}/pytest.ini" "--cov=$TARGET_DIR" --doctest-modules --cov-report=term --cov-fail-under=100 "$TARGET_DIR"
|
||||
python3 -m pytest "--cov-config=${HOME_DIR}/pytest.ini" "--cov=$TARGET_DIR" --doctest-modules --cov-report=term --cov-fail-under=100 "$TARGET_DIR"
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
'suricata',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'tcpreplay',
|
||||
'docker_clean'
|
||||
],
|
||||
@@ -66,6 +65,7 @@
|
||||
'registry',
|
||||
'manager',
|
||||
'nginx',
|
||||
'strelka.manager',
|
||||
'soc',
|
||||
'kratos',
|
||||
'influxdb',
|
||||
@@ -92,6 +92,7 @@
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'influxdb',
|
||||
'strelka.manager',
|
||||
'soc',
|
||||
'kratos',
|
||||
'elasticfleet',
|
||||
@@ -101,9 +102,9 @@
|
||||
'suricata.manager',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'docker_clean',
|
||||
'stig'
|
||||
'stig',
|
||||
'kafka'
|
||||
],
|
||||
'so-managersearch': [
|
||||
'salt.master',
|
||||
@@ -113,6 +114,7 @@
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'influxdb',
|
||||
'strelka.manager',
|
||||
'soc',
|
||||
'kratos',
|
||||
'elastic-fleet-package-registry',
|
||||
@@ -123,9 +125,9 @@
|
||||
'suricata.manager',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'docker_clean',
|
||||
'stig'
|
||||
'stig',
|
||||
'kafka'
|
||||
],
|
||||
'so-searchnode': [
|
||||
'ssl',
|
||||
@@ -157,10 +159,10 @@
|
||||
'healthcheck',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'tcpreplay',
|
||||
'docker_clean',
|
||||
'stig'
|
||||
'stig',
|
||||
'kafka'
|
||||
],
|
||||
'so-sensor': [
|
||||
'ssl',
|
||||
@@ -191,7 +193,10 @@
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'schedule',
|
||||
'docker_clean'
|
||||
'docker_clean',
|
||||
'kafka',
|
||||
'elasticsearch.ca',
|
||||
'stig'
|
||||
],
|
||||
'so-desktop': [
|
||||
'ssl',
|
||||
@@ -200,10 +205,6 @@
|
||||
],
|
||||
}, grain='role') %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone'] %}
|
||||
{% do allowed_states.append('mysql') %}
|
||||
{% endif %}
|
||||
|
||||
{%- if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %}
|
||||
{% do allowed_states.append('zeek') %}
|
||||
{%- endif %}
|
||||
@@ -229,10 +230,6 @@
|
||||
{% do allowed_states.append('elastalert') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
{% do allowed_states.append('playbook') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-receiver'] %}
|
||||
{% do allowed_states.append('logstash') %}
|
||||
{% endif %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
bpf:
|
||||
pcap:
|
||||
description: List of BPF filters to apply to PCAP.
|
||||
description: List of BPF filters to apply to Stenographer.
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: bpf.html
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
mine_functions:
|
||||
x509.get_pem_entries: [/etc/pki/ca.crt]
|
||||
|
||||
x509_signing_policies:
|
||||
filebeat:
|
||||
- minions: '*'
|
||||
@@ -70,3 +67,17 @@ x509_signing_policies:
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- days_valid: 820
|
||||
- copypath: /etc/pki/issued_certs/
|
||||
kafka:
|
||||
- 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: "digitalSignature, keyEncipherment"
|
||||
- subjectKeyIdentifier: hash
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- extendedKeyUsage: "serverAuth, clientAuth"
|
||||
- days_valid: 820
|
||||
- copypath: /etc/pki/issued_certs/
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
{% import_yaml '/opt/so/saltstack/local/pillar/global/soc_global.sls' as SOC_GLOBAL %}
|
||||
{% if SOC_GLOBAL.global.airgap %}
|
||||
{% set UPDATE_DIR='/tmp/soagupdate/SecurityOnion' %}
|
||||
{% else %}
|
||||
{% set UPDATE_DIR='/tmp/sogh/securityonion' %}
|
||||
{% endif %}
|
||||
# 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.
|
||||
|
||||
{% 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 %}
|
||||
{% if SOC_GLOBAL.global.airgap %}
|
||||
{% set UPDATE_DIR='/tmp/soagupdate/SecurityOnion' %}
|
||||
{% else %}
|
||||
{% set UPDATE_DIR='/tmp/sogh/securityonion' %}
|
||||
{% endif %}
|
||||
|
||||
remove_common_soup:
|
||||
file.absent:
|
||||
@@ -13,6 +20,8 @@ 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
|
||||
# in case a state run tries to overwrite what we do in the next section.
|
||||
copy_so-common_common_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-common
|
||||
@@ -41,6 +50,21 @@ copy_so-firewall_manager_tools_sbin:
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-yaml_manager_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-yaml.py
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-repo-sync_manager_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-repo-sync
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync
|
||||
- preserve: True
|
||||
|
||||
# This section is used to put the new script in place so that it can be called during soup.
|
||||
# It is faster than calling the states that normally manage them to put them in place.
|
||||
copy_so-common_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/so-common
|
||||
@@ -68,3 +92,26 @@ copy_so-firewall_sbin:
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-yaml_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/so-yaml.py
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-repo-sync_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/so-repo-sync
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
{% 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 %}
|
||||
|
||||
@@ -5,8 +5,13 @@
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
salt-call state.highstate -l info
|
||||
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:
|
||||
https://docs.securityonion.net/en/2.4/salt.html
|
||||
|
||||
EOF
|
||||
|
||||
salt-call state.highstate -l info queue=True
|
||||
|
||||
@@ -31,6 +31,11 @@ if ! echo "$PATH" | grep -q "/usr/sbin"; then
|
||||
export PATH="$PATH:/usr/sbin"
|
||||
fi
|
||||
|
||||
# See if a proxy is set. If so use it.
|
||||
if [ -f /etc/profile.d/so-proxy.sh ]; then
|
||||
. /etc/profile.d/so-proxy.sh
|
||||
fi
|
||||
|
||||
# Define a banner to separate sections
|
||||
banner="========================================================================="
|
||||
|
||||
@@ -179,6 +184,21 @@ copy_new_files() {
|
||||
cd /tmp
|
||||
}
|
||||
|
||||
create_local_directories() {
|
||||
echo "Creating local pillar and salt directories if needed"
|
||||
PILLARSALTDIR=$1
|
||||
local_salt_dir="/opt/so/saltstack/local"
|
||||
for i in "pillar" "salt"; do
|
||||
for d in $(find $PILLARSALTDIR/$i -type d); do
|
||||
suffixdir=${d//$PILLARSALTDIR/}
|
||||
if [ ! -d "$local_salt_dir/$suffixdir" ]; then
|
||||
mkdir -pv $local_salt_dir$suffixdir
|
||||
fi
|
||||
done
|
||||
chown -R socore:socore $local_salt_dir/$i
|
||||
done
|
||||
}
|
||||
|
||||
disable_fastestmirror() {
|
||||
sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
|
||||
}
|
||||
@@ -248,6 +268,14 @@ get_random_value() {
|
||||
head -c 5000 /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1
|
||||
}
|
||||
|
||||
get_agent_count() {
|
||||
if [ -f /opt/so/log/agents/agentstatus.log ]; then
|
||||
AGENTCOUNT=$(cat /opt/so/log/agents/agentstatus.log | grep -wF active | awk '{print $2}')
|
||||
else
|
||||
AGENTCOUNT=0
|
||||
fi
|
||||
}
|
||||
|
||||
gpg_rpm_import() {
|
||||
if [[ $is_oracle ]]; then
|
||||
if [[ "$WHATWOULDYOUSAYYAHDOHERE" == "setup" ]]; then
|
||||
@@ -329,7 +357,7 @@ lookup_salt_value() {
|
||||
local=""
|
||||
fi
|
||||
|
||||
salt-call --no-color ${kind}.get ${group}${key} --out=${output} ${local}
|
||||
salt-call -lerror --no-color ${kind}.get ${group}${key} --out=${output} ${local}
|
||||
}
|
||||
|
||||
lookup_pillar() {
|
||||
@@ -570,8 +598,9 @@ sync_options() {
|
||||
set_version
|
||||
set_os
|
||||
salt_minion_count
|
||||
get_agent_count
|
||||
|
||||
echo "$VERSION/$OS/$(uname -r)/$MINIONCOUNT/$(read_feat)"
|
||||
echo "$VERSION/$OS/$(uname -r)/$MINIONCOUNT:$AGENTCOUNT/$(read_feat)"
|
||||
}
|
||||
|
||||
systemctl_func() {
|
||||
|
||||
@@ -50,16 +50,14 @@ container_list() {
|
||||
"so-idh"
|
||||
"so-idstools"
|
||||
"so-influxdb"
|
||||
"so-kafka"
|
||||
"so-kibana"
|
||||
"so-kratos"
|
||||
"so-logstash"
|
||||
"so-mysql"
|
||||
"so-nginx"
|
||||
"so-pcaptools"
|
||||
"so-playbook"
|
||||
"so-redis"
|
||||
"so-soc"
|
||||
"so-soctopus"
|
||||
"so-steno"
|
||||
"so-strelka-backend"
|
||||
"so-strelka-filestream"
|
||||
@@ -67,7 +65,7 @@ container_list() {
|
||||
"so-strelka-manager"
|
||||
"so-suricata"
|
||||
"so-telegraf"
|
||||
"so-zeek"
|
||||
"so-zeek"
|
||||
)
|
||||
else
|
||||
TRUSTED_CONTAINERS=(
|
||||
|
||||
@@ -49,10 +49,6 @@ if [ "$CONTINUE" == "y" ]; then
|
||||
sed -i "s|$OLD_IP|$NEW_IP|g" $file
|
||||
done
|
||||
|
||||
echo "Granting MySQL root user permissions on $NEW_IP"
|
||||
docker exec -i so-mysql mysql --user=root --password=$(lookup_pillar_secret 'mysql') -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'$NEW_IP' IDENTIFIED BY '$(lookup_pillar_secret 'mysql')' WITH GRANT OPTION;" &> /dev/null
|
||||
echo "Removing MySQL root user from $OLD_IP"
|
||||
docker exec -i so-mysql mysql --user=root --password=$(lookup_pillar_secret 'mysql') -e "DROP USER 'root'@'$OLD_IP';" &> /dev/null
|
||||
echo "Updating Kibana dashboards"
|
||||
salt-call state.apply kibana.so_savedobjects_defaults -l info queue=True
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ if [[ $EXCLUDE_STARTUP_ERRORS == 'Y' ]]; then
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|error while communicating" # Elasticsearch MS -> HN "sensor" temporarily unavailable
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|tls handshake error" # Docker registry container when new node comes onlines
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unable to get license information" # Logstash trying to contact ES before it's ready
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|process already finished" # Telegraf script finished just as the auto kill timeout kicked in
|
||||
fi
|
||||
|
||||
if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then
|
||||
@@ -154,15 +155,11 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|fail\\(error\\)" # redis/python generic stack line, rely on other lines for actual error
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|urlerror" # idstools connection timeout
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|timeouterror" # idstools connection timeout
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|forbidden" # playbook
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|_ml" # Elastic ML errors
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|context canceled" # elastic agent during shutdown
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|exited with code 128" # soctopus errors during forced restart by highstate
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|geoip databases update" # airgap can't update GeoIP DB
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|filenotfounderror" # bug in 2.4.10 filecheck salt state caused duplicate cronjobs
|
||||
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|generating elastalert config" # playbook expected error
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|activerecord" # playbook expected error
|
||||
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|missing versions record" # stenographer corrupt index
|
||||
@@ -201,7 +198,13 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|req.LocalMeta.host.ip" # known issue in GH
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|sendmail" # zeek
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|stats.log"
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unknown column" # Elastalert errors from running EQL queries
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|parsing_exception" # Elastalert EQL parsing issue. Temp.
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|context deadline exceeded"
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Error running query:" # Specific issues with detection rules
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|detect-parse" # Suricata encountering a malformed rule
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|integrity check failed" # Detections: Exclude false positive due to automated testing
|
||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|syncErrors" # Detections: Not an actual error
|
||||
fi
|
||||
|
||||
RESULT=0
|
||||
@@ -210,7 +213,9 @@ RESULT=0
|
||||
CONTAINER_IDS=$(docker ps -q)
|
||||
exclude_container so-kibana # kibana error logs are too verbose with large varieties of errors most of which are temporary
|
||||
exclude_container so-idstools # ignore due to known issues and noisy logging
|
||||
exclude_container so-playbook # ignore due to several playbook known issues
|
||||
exclude_container so-playbook # Playbook is removed as of 2.4.70, disregard output in stopped containers
|
||||
exclude_container so-mysql # MySQL is removed as of 2.4.70, disregard output in stopped containers
|
||||
exclude_container so-soctopus # Soctopus is removed as of 2.4.70, disregard output in stopped containers
|
||||
|
||||
for container_id in $CONTAINER_IDS; do
|
||||
container_name=$(docker ps --format json | jq ". | select(.ID==\"$container_id\")|.Names")
|
||||
@@ -228,10 +233,14 @@ exclude_log "kibana.log" # kibana error logs are too verbose with large variet
|
||||
exclude_log "spool" # disregard zeek analyze logs as this is data specific
|
||||
exclude_log "import" # disregard imported test data the contains error strings
|
||||
exclude_log "update.log" # ignore playbook updates due to several known issues
|
||||
exclude_log "playbook.log" # ignore due to several playbook known issues
|
||||
exclude_log "cron-cluster-delete.log" # ignore since Curator has been removed
|
||||
exclude_log "cron-close.log" # ignore since Curator has been removed
|
||||
exclude_log "curator.log" # ignore since Curator has been removed
|
||||
exclude_log "curator.log" # ignore since Curator has been removed
|
||||
exclude_log "playbook.log" # Playbook is removed as of 2.4.70, logs may still be on disk
|
||||
exclude_log "mysqld.log" # MySQL is removed as of 2.4.70, logs may still be on disk
|
||||
exclude_log "soctopus.log" # Soctopus is removed as of 2.4.70, logs may still be on disk
|
||||
exclude_log "agentstatus.log" # ignore this log since it tracks agents in error state
|
||||
exclude_log "detections_runtime-status_yara.log" # temporarily ignore this log until Detections is more stable
|
||||
|
||||
for log_file in $(cat /tmp/log_check_files); do
|
||||
status "Checking log file $log_file"
|
||||
|
||||
98
salt/common/tools/sbin/so-luks-tpm-regen
Normal file
98
salt/common/tools/sbin/so-luks-tpm-regen
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/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."
|
||||
|
||||
set -e
|
||||
# This script is intended to be used in the case the ISO install did not properly setup TPM decrypt for LUKS partitions at boot.
|
||||
if [ -z $NOROOT ]; then
|
||||
# Check for prerequisites
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run using sudo!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
ENROLL_TPM=N
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--enroll-tpm)
|
||||
ENROLL_TPM=Y
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
echo "where options are:"
|
||||
echo " --enroll-tpm for when TPM enrollment was not selected during ISO install."
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
check_for_tpm() {
|
||||
echo -n "Checking for TPM: "
|
||||
if [ -d /sys/class/tpm/tpm0 ]; then
|
||||
echo -e "tpm0 found."
|
||||
TPM="yes"
|
||||
# Check if TPM is using sha1 or sha256
|
||||
if [ -d /sys/class/tpm/tpm0/pcr-sha1 ]; then
|
||||
echo -e "TPM is using sha1.\n"
|
||||
TPM_PCR="sha1"
|
||||
elif [ -d /sys/class/tpm/tpm0/pcr-sha256 ]; then
|
||||
echo -e "TPM is using sha256.\n"
|
||||
TPM_PCR="sha256"
|
||||
fi
|
||||
else
|
||||
echo -e "No TPM found.\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_for_luks_partitions() {
|
||||
echo "Checking for LUKS partitions"
|
||||
for part in $(lsblk -o NAME,FSTYPE -ln | grep crypto_LUKS | awk '{print $1}'); do
|
||||
echo "Found LUKS partition: $part"
|
||||
LUKS_PARTITIONS+=("$part")
|
||||
done
|
||||
if [ ${#LUKS_PARTITIONS[@]} -eq 0 ]; then
|
||||
echo -e "No LUKS partitions found.\n"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
enroll_tpm_in_luks() {
|
||||
read -s -p "Enter the LUKS passphrase used during ISO install: " LUKS_PASSPHRASE
|
||||
echo ""
|
||||
for part in "${LUKS_PARTITIONS[@]}"; do
|
||||
echo "Enrolling TPM for LUKS device: /dev/$part"
|
||||
if [ "$TPM_PCR" == "sha1" ]; then
|
||||
clevis luks bind -d /dev/$part tpm2 '{"pcr_bank":"sha1","pcr_ids":"7"}' <<< $LUKS_PASSPHRASE
|
||||
elif [ "$TPM_PCR" == "sha256" ]; then
|
||||
clevis luks bind -d /dev/$part tpm2 '{"pcr_bank":"sha256","pcr_ids":"7"}' <<< $LUKS_PASSPHRASE
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
regenerate_tpm_enrollment_token() {
|
||||
for part in "${LUKS_PARTITIONS[@]}"; do
|
||||
clevis luks regen -d /dev/$part -s 1 -q
|
||||
done
|
||||
}
|
||||
|
||||
check_for_tpm
|
||||
check_for_luks_partitions
|
||||
|
||||
if [[ $ENROLL_TPM == "Y" ]]; then
|
||||
enroll_tpm_in_luks
|
||||
else
|
||||
regenerate_tpm_enrollment_token
|
||||
fi
|
||||
|
||||
echo "Running dracut"
|
||||
dracut -fv
|
||||
echo -e "\nTPM configuration complete. Reboot the system to verify the TPM is correctly decrypting the LUKS partition(s) at boot.\n"
|
||||
@@ -89,6 +89,7 @@ function suricata() {
|
||||
-v ${LOG_PATH}:/var/log/suricata/:rw \
|
||||
-v ${NSM_PATH}/:/nsm/:rw \
|
||||
-v "$PCAP:/input.pcap:ro" \
|
||||
-v /dev/null:/nsm/suripcap:rw \
|
||||
-v /opt/so/conf/suricata/bpf:/etc/suricata/bpf:ro \
|
||||
{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-suricata:{{ VERSION }} \
|
||||
--runmode single -k none -r /input.pcap > $LOG_PATH/console.log 2>&1
|
||||
@@ -247,7 +248,7 @@ fi
|
||||
START_OLDEST_SLASH=$(echo $START_OLDEST | sed -e 's/-/%2F/g')
|
||||
END_NEWEST_SLASH=$(echo $END_NEWEST | sed -e 's/-/%2F/g')
|
||||
if [[ $VALID_PCAPS_COUNT -gt 0 ]] || [[ $SKIPPED_PCAPS_COUNT -gt 0 ]]; then
|
||||
URL="https://{{ URLBASE }}/#/dashboards?q=$HASH_FILTERS%20%7C%20groupby%20-sankey%20event.dataset%20event.category%2a%20%7C%20groupby%20-pie%20event.category%20%7C%20groupby%20-bar%20event.module%20%7C%20groupby%20event.dataset%20%7C%20groupby%20event.module%20%7C%20groupby%20event.category%20%7C%20groupby%20observer.name%20%7C%20groupby%20source.ip%20%7C%20groupby%20destination.ip%20%7C%20groupby%20destination.port&t=${START_OLDEST_SLASH}%2000%3A00%3A00%20AM%20-%20${END_NEWEST_SLASH}%2000%3A00%3A00%20AM&z=UTC"
|
||||
URL="https://{{ URLBASE }}/#/dashboards?q=$HASH_FILTERS%20%7C%20groupby%20event.module*%20%7C%20groupby%20-sankey%20event.module*%20event.dataset%20%7C%20groupby%20event.dataset%20%7C%20groupby%20source.ip%20%7C%20groupby%20destination.ip%20%7C%20groupby%20destination.port%20%7C%20groupby%20network.protocol%20%7C%20groupby%20rule.name%20rule.category%20event.severity_label%20%7C%20groupby%20dns.query.name%20%7C%20groupby%20file.mime_type%20%7C%20groupby%20http.virtual_host%20http.uri%20%7C%20groupby%20notice.note%20notice.message%20notice.sub_message%20%7C%20groupby%20ssl.server_name%20%7C%20groupby%20source_geo.organization_name%20source.geo.country_name%20%7C%20groupby%20destination_geo.organization_name%20destination.geo.country_name&t=${START_OLDEST_SLASH}%2000%3A00%3A00%20AM%20-%20${END_NEWEST_SLASH}%2000%3A00%3A00%20AM&z=UTC"
|
||||
|
||||
status "Import complete!"
|
||||
status
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
. /usr/sbin/so-common
|
||||
. /usr/sbin/so-image-common
|
||||
|
||||
REPLAYIFACE=${REPLAYIFACE:-$(lookup_pillar interface sensor)}
|
||||
REPLAYIFACE=${REPLAYIFACE:-"{{salt['pillar.get']('sensor:interface', '')}}"}
|
||||
REPLAYSPEED=${REPLAYSPEED:-10}
|
||||
|
||||
mkdir -p /opt/so/samples
|
||||
@@ -67,13 +67,6 @@ docker:
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-mysql':
|
||||
final_octet: 30
|
||||
port_bindings:
|
||||
- 0.0.0.0:3306:3306
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-nginx':
|
||||
final_octet: 31
|
||||
port_bindings:
|
||||
@@ -91,13 +84,6 @@ docker:
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-playbook':
|
||||
final_octet: 32
|
||||
port_bindings:
|
||||
- 0.0.0.0:3000:3000
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-redis':
|
||||
final_octet: 33
|
||||
port_bindings:
|
||||
@@ -118,13 +104,6 @@ docker:
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-soctopus':
|
||||
final_octet: 35
|
||||
port_bindings:
|
||||
- 0.0.0.0:7000:7000
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-strelka-backend':
|
||||
final_octet: 36
|
||||
custom_bind_mounts: []
|
||||
@@ -201,8 +180,19 @@ docker:
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
ulimits:
|
||||
- memlock=524288000
|
||||
'so-zeek':
|
||||
final_octet: 99
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
'so-kafka':
|
||||
final_octet: 88
|
||||
port_bindings:
|
||||
- 0.0.0.0:9092:9092
|
||||
- 0.0.0.0:9093:9093
|
||||
- 0.0.0.0:8778:8778
|
||||
custom_bind_mounts: []
|
||||
extra_hosts: []
|
||||
extra_env: []
|
||||
|
||||
@@ -20,30 +20,30 @@ dockergroup:
|
||||
dockerheldpackages:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- containerd.io: 1.6.21-1
|
||||
- docker-ce: 5:24.0.3-1~debian.12~bookworm
|
||||
- docker-ce-cli: 5:24.0.3-1~debian.12~bookworm
|
||||
- docker-ce-rootless-extras: 5:24.0.3-1~debian.12~bookworm
|
||||
- containerd.io: 1.6.33-1
|
||||
- docker-ce: 5:26.1.4-1~debian.12~bookworm
|
||||
- docker-ce-cli: 5:26.1.4-1~debian.12~bookworm
|
||||
- docker-ce-rootless-extras: 5:26.1.4-1~debian.12~bookworm
|
||||
- hold: True
|
||||
- update_holds: True
|
||||
{% elif grains.oscodename == 'jammy' %}
|
||||
dockerheldpackages:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- containerd.io: 1.6.21-1
|
||||
- docker-ce: 5:24.0.2-1~ubuntu.22.04~jammy
|
||||
- docker-ce-cli: 5:24.0.2-1~ubuntu.22.04~jammy
|
||||
- docker-ce-rootless-extras: 5:24.0.2-1~ubuntu.22.04~jammy
|
||||
- containerd.io: 1.6.33-1
|
||||
- docker-ce: 5:26.1.4-1~ubuntu.22.04~jammy
|
||||
- docker-ce-cli: 5:26.1.4-1~ubuntu.22.04~jammy
|
||||
- docker-ce-rootless-extras: 5:26.1.4-1~ubuntu.22.04~jammy
|
||||
- hold: True
|
||||
- update_holds: True
|
||||
{% else %}
|
||||
dockerheldpackages:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- containerd.io: 1.4.9-1
|
||||
- docker-ce: 5:20.10.8~3-0~ubuntu-focal
|
||||
- docker-ce-cli: 5:20.10.5~3-0~ubuntu-focal
|
||||
- docker-ce-rootless-extras: 5:20.10.5~3-0~ubuntu-focal
|
||||
- containerd.io: 1.6.33-1
|
||||
- docker-ce: 5:26.1.4-1~ubuntu.20.04~focal
|
||||
- docker-ce-cli: 5:26.1.4-1~ubuntu.20.04~focal
|
||||
- docker-ce-rootless-extras: 5:26.1.4-1~ubuntu.20.04~focal
|
||||
- hold: True
|
||||
- update_holds: True
|
||||
{% endif %}
|
||||
@@ -51,10 +51,10 @@ dockerheldpackages:
|
||||
dockerheldpackages:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- containerd.io: 1.6.21-3.1.el9
|
||||
- docker-ce: 24.0.4-1.el9
|
||||
- docker-ce-cli: 24.0.4-1.el9
|
||||
- docker-ce-rootless-extras: 24.0.4-1.el9
|
||||
- containerd.io: 1.6.33-3.1.el9
|
||||
- docker-ce: 3:26.1.4-1.el9
|
||||
- docker-ce-cli: 1:26.1.4-1.el9
|
||||
- docker-ce-rootless-extras: 26.1.4-1.el9
|
||||
- hold: True
|
||||
- update_holds: True
|
||||
{% endif %}
|
||||
|
||||
@@ -46,14 +46,11 @@ docker:
|
||||
so-kibana: *dockerOptions
|
||||
so-kratos: *dockerOptions
|
||||
so-logstash: *dockerOptions
|
||||
so-mysql: *dockerOptions
|
||||
so-nginx: *dockerOptions
|
||||
so-nginx-fleet-node: *dockerOptions
|
||||
so-playbook: *dockerOptions
|
||||
so-redis: *dockerOptions
|
||||
so-sensoroni: *dockerOptions
|
||||
so-soc: *dockerOptions
|
||||
so-soctopus: *dockerOptions
|
||||
so-strelka-backend: *dockerOptions
|
||||
so-strelka-filestream: *dockerOptions
|
||||
so-strelka-frontend: *dockerOptions
|
||||
@@ -66,5 +63,42 @@ docker:
|
||||
so-elastic-agent: *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-kafka: *dockerOptions
|
||||
@@ -82,6 +82,36 @@ elastasomodulesync:
|
||||
- group: 933
|
||||
- makedirs: True
|
||||
|
||||
elastacustomdir:
|
||||
file.directory:
|
||||
- name: /opt/so/conf/elastalert/custom
|
||||
- user: 933
|
||||
- group: 933
|
||||
- makedirs: True
|
||||
|
||||
elastacustomsync:
|
||||
file.recurse:
|
||||
- name: /opt/so/conf/elastalert/custom
|
||||
- source: salt://elastalert/files/custom
|
||||
- user: 933
|
||||
- group: 933
|
||||
- makedirs: True
|
||||
- file_mode: 660
|
||||
- show_changes: False
|
||||
|
||||
elastapredefinedsync:
|
||||
file.recurse:
|
||||
- name: /opt/so/conf/elastalert/predefined
|
||||
- source: salt://elastalert/files/predefined
|
||||
- user: 933
|
||||
- group: 933
|
||||
- makedirs: True
|
||||
- template: jinja
|
||||
- file_mode: 660
|
||||
- context:
|
||||
elastalert: {{ ELASTALERTMERGED }}
|
||||
- show_changes: False
|
||||
|
||||
elastaconf:
|
||||
file.managed:
|
||||
- name: /opt/so/conf/elastalert/elastalert_config.yaml
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
elastalert:
|
||||
enabled: False
|
||||
alerter_parameters: ""
|
||||
config:
|
||||
rules_folder: /opt/elastalert/rules/
|
||||
scan_subdirectories: true
|
||||
|
||||
@@ -30,6 +30,8 @@ so-elastalert:
|
||||
- /opt/so/rules/elastalert:/opt/elastalert/rules/:ro
|
||||
- /opt/so/log/elastalert:/var/log/elastalert:rw
|
||||
- /opt/so/conf/elastalert/modules/:/opt/elastalert/modules/:ro
|
||||
- /opt/so/conf/elastalert/predefined/:/opt/elastalert/predefined/:ro
|
||||
- /opt/so/conf/elastalert/custom/:/opt/elastalert/custom/:ro
|
||||
- /opt/so/conf/elastalert/elastalert_config.yaml:/opt/elastalert/config.yaml:ro
|
||||
{% if DOCKER.containers['so-elastalert'].custom_bind_mounts %}
|
||||
{% for BIND in DOCKER.containers['so-elastalert'].custom_bind_mounts %}
|
||||
|
||||
1
salt/elastalert/files/custom/placeholder
Normal file
1
salt/elastalert/files/custom/placeholder
Normal file
@@ -0,0 +1 @@
|
||||
THIS IS A PLACEHOLDER FILE
|
||||
@@ -1,38 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 time import gmtime, strftime
|
||||
import requests,json
|
||||
from elastalert.alerts import Alerter
|
||||
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
class PlaybookESAlerter(Alerter):
|
||||
"""
|
||||
Use matched data to create alerts in elasticsearch
|
||||
"""
|
||||
|
||||
required_options = set(['play_title','play_url','sigma_level'])
|
||||
|
||||
def alert(self, matches):
|
||||
for match in matches:
|
||||
today = strftime("%Y.%m.%d", gmtime())
|
||||
timestamp = strftime("%Y-%m-%d"'T'"%H:%M:%S"'.000Z', gmtime())
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
creds = None
|
||||
if 'es_username' in self.rule and 'es_password' in self.rule:
|
||||
creds = (self.rule['es_username'], self.rule['es_password'])
|
||||
|
||||
payload = {"tags":"alert","rule": { "name": self.rule['play_title'],"case_template": self.rule['play_id'],"uuid": self.rule['play_id'],"category": self.rule['rule.category']},"event":{ "severity": self.rule['event.severity'],"module": self.rule['event.module'],"dataset": self.rule['event.dataset'],"severity_label": self.rule['sigma_level']},"kibana_pivot": self.rule['kibana_pivot'],"soc_pivot": self.rule['soc_pivot'],"play_url": self.rule['play_url'],"sigma_level": self.rule['sigma_level'],"event_data": match, "@timestamp": timestamp}
|
||||
url = f"https://{self.rule['es_host']}:{self.rule['es_port']}/logs-playbook.alerts-so/_doc/"
|
||||
requests.post(url, data=json.dumps(payload), headers=headers, verify=False, auth=creds)
|
||||
|
||||
def get_info(self):
|
||||
return {'type': 'PlaybookESAlerter'}
|
||||
63
salt/elastalert/files/modules/so/securityonion-es.py
Normal file
63
salt/elastalert/files/modules/so/securityonion-es.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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 time import gmtime, strftime
|
||||
import requests,json
|
||||
from elastalert.alerts import Alerter
|
||||
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
class SecurityOnionESAlerter(Alerter):
|
||||
"""
|
||||
Use matched data to create alerts in Elasticsearch.
|
||||
"""
|
||||
|
||||
required_options = set(['detection_title', 'sigma_level'])
|
||||
optional_fields = ['sigma_category', 'sigma_product', 'sigma_service']
|
||||
|
||||
def alert(self, matches):
|
||||
for match in matches:
|
||||
timestamp = strftime("%Y-%m-%d"'T'"%H:%M:%S"'.000Z', gmtime())
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
creds = None
|
||||
if 'es_username' in self.rule and 'es_password' in self.rule:
|
||||
creds = (self.rule['es_username'], self.rule['es_password'])
|
||||
|
||||
# Start building the rule dict
|
||||
rule_info = {
|
||||
"name": self.rule['detection_title'],
|
||||
"uuid": self.rule['detection_public_id']
|
||||
}
|
||||
|
||||
# Add optional fields if they are present in the rule
|
||||
for field in self.optional_fields:
|
||||
rule_key = field.split('_')[-1] # Assumes field format "sigma_<key>"
|
||||
if field in self.rule:
|
||||
rule_info[rule_key] = self.rule[field]
|
||||
|
||||
# Construct the payload with the conditional rule_info
|
||||
payload = {
|
||||
"tags": "alert",
|
||||
"rule": rule_info,
|
||||
"event": {
|
||||
"severity": self.rule['event.severity'],
|
||||
"module": self.rule['event.module'],
|
||||
"dataset": self.rule['event.dataset'],
|
||||
"severity_label": self.rule['sigma_level']
|
||||
},
|
||||
"sigma_level": self.rule['sigma_level'],
|
||||
"event_data": match,
|
||||
"@timestamp": timestamp
|
||||
}
|
||||
url = f"https://{self.rule['es_host']}:{self.rule['es_port']}/logs-detections.alerts-so/_doc/"
|
||||
requests.post(url, data=json.dumps(payload), headers=headers, verify=False, auth=creds)
|
||||
|
||||
def get_info(self):
|
||||
return {'type': 'SecurityOnionESAlerter'}
|
||||
6
salt/elastalert/files/predefined/jira_auth.yaml
Normal file
6
salt/elastalert/files/predefined/jira_auth.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
{% if elastalert.get('jira_user', '') | length > 0 and elastalert.get('jira_pass', '') | length > 0 %}
|
||||
user: {{ elastalert.jira_user }}
|
||||
password: {{ elastalert.jira_pass }}
|
||||
{% else %}
|
||||
apikey: {{ elastalert.get('jira_api_key', '') }}
|
||||
{% endif %}
|
||||
2
salt/elastalert/files/predefined/smtp_auth.yaml
Normal file
2
salt/elastalert/files/predefined/smtp_auth.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
user: {{ elastalert.get('smtp_user', '') }}
|
||||
password: {{ elastalert.get('smtp_pass', '') }}
|
||||
@@ -13,3 +13,19 @@
|
||||
{% do ELASTALERTDEFAULTS.elastalert.config.update({'es_password': pillar.elasticsearch.auth.users.so_elastic_user.pass}) %}
|
||||
|
||||
{% set ELASTALERTMERGED = salt['pillar.get']('elastalert', ELASTALERTDEFAULTS.elastalert, merge=True) %}
|
||||
|
||||
{% if 'ntf' in salt['pillar.get']('features', []) %}
|
||||
{% set params = ELASTALERTMERGED.get('alerter_parameters', '') | load_yaml %}
|
||||
{% if params != None and params | length > 0 %}
|
||||
{% do ELASTALERTMERGED.config.update(params) %}
|
||||
{% endif %}
|
||||
|
||||
{% if ELASTALERTMERGED.get('smtp_user', '') | length > 0 %}
|
||||
{% do ELASTALERTMERGED.config.update({'smtp_auth_file': '/opt/elastalert/predefined/smtp_auth.yaml'}) %}
|
||||
{% endif %}
|
||||
|
||||
{% if ELASTALERTMERGED.get('jira_user', '') | length > 0 or ELASTALERTMERGED.get('jira_key', '') | length > 0 %}
|
||||
{% do ELASTALERTMERGED.config.update({'jira_account_file': '/opt/elastalert/predefined/jira_auth.yaml'}) %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
@@ -2,6 +2,99 @@ elastalert:
|
||||
enabled:
|
||||
description: You can enable or disable Elastalert.
|
||||
helpLink: elastalert.html
|
||||
alerter_parameters:
|
||||
title: Alerter Parameters
|
||||
description: Optional configuration parameters for additional alerters that can be enabled for all Sigma rules. Filter for 'Alerter' in this Configuration screen to find the setting that allows these alerters to be enabled within the SOC ElastAlert module. Use YAML format for these parameters, and reference the ElastAlert 2 documentation, located at https://elastalert2.readthedocs.io, for available alerters and their required configuration parameters. A full update of the ElastAlert rule engine, via the Detections screen, is required in order to apply these changes. Requires a valid Security Onion license key.
|
||||
global: True
|
||||
multiline: True
|
||||
syntax: yaml
|
||||
helpLink: elastalert.html
|
||||
forcedType: string
|
||||
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.
|
||||
global: True
|
||||
sensitive: True
|
||||
helpLink: elastalert.html
|
||||
forcedType: string
|
||||
jira_pass:
|
||||
title: Jira Password
|
||||
description: Optional configuration parameter for Jira password. Requires a valid Security Onion license key.
|
||||
global: True
|
||||
sensitive: True
|
||||
helpLink: elastalert.html
|
||||
forcedType: string
|
||||
jira_user:
|
||||
title: Jira Username
|
||||
description: Optional configuration parameter for Jira username. Requires a valid Security Onion license key.
|
||||
global: True
|
||||
helpLink: elastalert.html
|
||||
forcedType: string
|
||||
smtp_pass:
|
||||
title: SMTP Password
|
||||
description: Optional configuration parameter for SMTP password, required for authenticating email servers. Requires a valid Security Onion license key.
|
||||
global: True
|
||||
sensitive: True
|
||||
helpLink: elastalert.html
|
||||
forcedType: string
|
||||
smtp_user:
|
||||
title: SMTP Username
|
||||
description: Optional configuration parameter for SMTP username, required for authenticating email servers. Requires a valid Security Onion license key.
|
||||
global: True
|
||||
helpLink: elastalert.html
|
||||
forcedType: string
|
||||
files:
|
||||
custom:
|
||||
alertmanager_ca__crt:
|
||||
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
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
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.
|
||||
global: True
|
||||
file: True
|
||||
helpLink: elastalert.html
|
||||
config:
|
||||
disable_rules_on_error:
|
||||
description: Disable rules on failure.
|
||||
|
||||
@@ -37,6 +37,7 @@ elasticfleet:
|
||||
- azure
|
||||
- barracuda
|
||||
- carbonblack_edr
|
||||
- cef
|
||||
- checkpoint
|
||||
- cisco_asa
|
||||
- cisco_duo
|
||||
@@ -118,3 +119,8 @@ elasticfleet:
|
||||
base_url: https://api.platform.sublimesecurity.com
|
||||
poll_interval: 5m
|
||||
limit: 100
|
||||
kismet:
|
||||
base_url: http://localhost:2501
|
||||
poll_interval: 1m
|
||||
api_key:
|
||||
enabled_nodes: []
|
||||
|
||||
@@ -27,7 +27,9 @@ wait_for_elasticsearch_elasticfleet:
|
||||
so-elastic-fleet-auto-configure-logstash-outputs:
|
||||
cmd.run:
|
||||
- name: /usr/sbin/so-elastic-fleet-outputs-update
|
||||
- retry: True
|
||||
- retry:
|
||||
attempts: 4
|
||||
interval: 30
|
||||
{% endif %}
|
||||
|
||||
# If enabled, automatically update Fleet Server URLs & ES Connection
|
||||
@@ -35,7 +37,9 @@ so-elastic-fleet-auto-configure-logstash-outputs:
|
||||
so-elastic-fleet-auto-configure-server-urls:
|
||||
cmd.run:
|
||||
- name: /usr/sbin/so-elastic-fleet-urls-update
|
||||
- retry: True
|
||||
- retry:
|
||||
attempts: 4
|
||||
interval: 30
|
||||
{% endif %}
|
||||
|
||||
# Automatically update Fleet Server Elasticsearch URLs & Agent Artifact URLs
|
||||
@@ -43,12 +47,16 @@ so-elastic-fleet-auto-configure-server-urls:
|
||||
so-elastic-fleet-auto-configure-elasticsearch-urls:
|
||||
cmd.run:
|
||||
- name: /usr/sbin/so-elastic-fleet-es-url-update
|
||||
- retry: True
|
||||
- retry:
|
||||
attempts: 4
|
||||
interval: 30
|
||||
|
||||
so-elastic-fleet-auto-configure-artifact-urls:
|
||||
cmd.run:
|
||||
- name: /usr/sbin/so-elastic-fleet-artifacts-url-update
|
||||
- retry: True
|
||||
- retry:
|
||||
attempts: 4
|
||||
interval: 30
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
36
salt/elasticfleet/files/integrations-optional/kismet.json
Normal file
36
salt/elasticfleet/files/integrations-optional/kismet.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{% from 'elasticfleet/map.jinja' import ELASTICFLEETMERGED %}
|
||||
{% raw %}
|
||||
{
|
||||
"package": {
|
||||
"name": "httpjson",
|
||||
"version": ""
|
||||
},
|
||||
"name": "kismet-logs",
|
||||
"namespace": "so",
|
||||
"description": "Kismet Logs",
|
||||
"policy_id": "FleetServer_{% endraw %}{{ NAME }}{% raw %}",
|
||||
"inputs": {
|
||||
"generic-httpjson": {
|
||||
"enabled": true,
|
||||
"streams": {
|
||||
"httpjson.generic": {
|
||||
"enabled": true,
|
||||
"vars": {
|
||||
"data_stream.dataset": "kismet",
|
||||
"request_url": "{% endraw %}{{ ELASTICFLEETMERGED.optional_integrations.kismet.base_url }}{% raw %}/devices/last-time/-600/devices.tjson",
|
||||
"request_interval": "{% endraw %}{{ ELASTICFLEETMERGED.optional_integrations.kismet.poll_interval }}{% raw %}",
|
||||
"request_method": "GET",
|
||||
"request_transforms": "- set:\r\n target: header.Cookie\r\n value: 'KISMET={% endraw %}{{ ELASTICFLEETMERGED.optional_integrations.kismet.api_key }}{% raw %}'",
|
||||
"request_redirect_headers_ban_list": [],
|
||||
"oauth_scopes": [],
|
||||
"processors": "",
|
||||
"tags": [],
|
||||
"pipeline": "kismet.common"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"force": true
|
||||
}
|
||||
{% endraw %}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"package": {
|
||||
"name": "winlog",
|
||||
"version": ""
|
||||
},
|
||||
"name": "windows-defender",
|
||||
"namespace": "default",
|
||||
"description": "Windows Defender - Operational logs",
|
||||
"policy_id": "endpoints-initial",
|
||||
"inputs": {
|
||||
"winlogs-winlog": {
|
||||
"enabled": true,
|
||||
"streams": {
|
||||
"winlog.winlog": {
|
||||
"enabled": true,
|
||||
"vars": {
|
||||
"channel": "Microsoft-Windows-Windows Defender/Operational",
|
||||
"data_stream.dataset": "winlog.winlog",
|
||||
"preserve_original_event": false,
|
||||
"providers": [],
|
||||
"ignore_older": "72h",
|
||||
"language": 0,
|
||||
"tags": [] }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"force": true
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"policy_id": "so-grid-nodes_general",
|
||||
"package": {
|
||||
"name": "log",
|
||||
"version": ""
|
||||
},
|
||||
"name": "soc-detections-logs",
|
||||
"description": "Security Onion Console - Detections Logs",
|
||||
"namespace": "so",
|
||||
"inputs": {
|
||||
"logs-logfile": {
|
||||
"enabled": true,
|
||||
"streams": {
|
||||
"log.logs": {
|
||||
"enabled": true,
|
||||
"vars": {
|
||||
"paths": [
|
||||
"/opt/so/log/soc/detections_runtime-status_sigma.log",
|
||||
"/opt/so/log/soc/detections_runtime-status_yara.log"
|
||||
],
|
||||
"exclude_files": [],
|
||||
"ignore_older": "72h",
|
||||
"data_stream.dataset": "soc",
|
||||
"tags": [
|
||||
"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",
|
||||
"custom": "pipeline: common"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"force": true
|
||||
}
|
||||
@@ -16,6 +16,9 @@
|
||||
"paths": [
|
||||
"/var/log/auth.log*",
|
||||
"/var/log/secure*"
|
||||
],
|
||||
"tags": [
|
||||
"so-grid-node"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -25,6 +28,9 @@
|
||||
"paths": [
|
||||
"/var/log/messages*",
|
||||
"/var/log/syslog*"
|
||||
],
|
||||
"tags": [
|
||||
"so-grid-node"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
"paths": [
|
||||
"/var/log/auth.log*",
|
||||
"/var/log/secure*"
|
||||
],
|
||||
"tags": [
|
||||
"so-grid-node"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -25,6 +28,9 @@
|
||||
"paths": [
|
||||
"/var/log/messages*",
|
||||
"/var/log/syslog*"
|
||||
],
|
||||
"tags": [
|
||||
"so-grid-node"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,3 +79,29 @@ elasticfleet:
|
||||
helpLink: elastic-fleet.html
|
||||
advanced: True
|
||||
forcedType: int
|
||||
kismet:
|
||||
base_url:
|
||||
description: Base URL for Kismet.
|
||||
global: True
|
||||
helpLink: elastic-fleet.html
|
||||
advanced: True
|
||||
forcedType: string
|
||||
poll_interval:
|
||||
description: Poll interval for wireless device data from Kismet. Integration is currently configured to return devices seen as active by any Kismet sensor within the last 10 minutes.
|
||||
global: True
|
||||
helpLink: elastic-fleet.html
|
||||
advanced: True
|
||||
forcedType: string
|
||||
api_key:
|
||||
description: API key for Kismet.
|
||||
global: True
|
||||
helpLink: elastic-fleet.html
|
||||
advanced: True
|
||||
forcedType: string
|
||||
sensitive: True
|
||||
enabled_nodes:
|
||||
description: Fleet nodes with the Kismet integration enabled. Enter one per line.
|
||||
global: True
|
||||
helpLink: elastic-fleet.html
|
||||
advanced: True
|
||||
forcedType: "[]string"
|
||||
|
||||
@@ -19,7 +19,7 @@ NUM_RUNNING=$(pgrep -cf "/bin/bash /sbin/so-elastic-agent-gen-installers")
|
||||
|
||||
for i in {1..30}
|
||||
do
|
||||
ENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-initial")) | .api_key')
|
||||
ENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys?perPage=100" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-initial")) | .api_key')
|
||||
FLEETHOST=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/fleet_server_hosts/grid-default' | jq -r '.item.host_urls[]' | paste -sd ',')
|
||||
if [[ $FLEETHOST ]] && [[ $ENROLLMENTOKEN ]]; then break; else sleep 10; fi
|
||||
done
|
||||
@@ -72,5 +72,5 @@ do
|
||||
printf "\n### $GOOS/$GOARCH Installer Generated...\n"
|
||||
done
|
||||
|
||||
printf "\n### Cleaning up temp files in /nsm/elastic-agent-workspace"
|
||||
printf "\n### Cleaning up temp files in /nsm/elastic-agent-workspace\n"
|
||||
rm -rf /nsm/elastic-agent-workspace
|
||||
|
||||
@@ -21,64 +21,104 @@ function update_logstash_outputs() {
|
||||
# Update Logstash Outputs
|
||||
curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/outputs/so-manager_logstash" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" | jq
|
||||
}
|
||||
function update_kafka_outputs() {
|
||||
# Make sure SSL configuration is included in policy updates for Kafka output. SSL is configured in so-elastic-fleet-setup
|
||||
SSL_CONFIG=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/outputs/so-manager_kafka" | jq -r '.item.ssl')
|
||||
|
||||
# Get current list of Logstash Outputs
|
||||
RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_logstash')
|
||||
JSON_STRING=$(jq -n \
|
||||
--arg UPDATEDLIST "$NEW_LIST_JSON" \
|
||||
--argjson SSL_CONFIG "$SSL_CONFIG" \
|
||||
'{"name": "grid-kafka","type": "kafka","hosts": $UPDATEDLIST,"is_default": true,"is_default_monitoring": true,"config_yaml": "","ssl": $SSL_CONFIG}')
|
||||
# Update Kafka outputs
|
||||
curl -K /opt/so/conf/elasticsearch/curl.config -L -X PUT "localhost:5601/api/fleet/outputs/so-manager_kafka" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" | jq
|
||||
}
|
||||
|
||||
# Check to make sure that the server responded with good data - else, bail from script
|
||||
CHECKSUM=$(jq -r '.item.id' <<< "$RAW_JSON")
|
||||
if [ "$CHECKSUM" != "so-manager_logstash" ]; then
|
||||
printf "Failed to query for current Logstash Outputs..."
|
||||
exit 1
|
||||
fi
|
||||
{% if GLOBALS.pipeline == "KAFKA" %}
|
||||
# Get current list of Kafka Outputs
|
||||
RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_kafka')
|
||||
|
||||
# Get the current list of Logstash outputs & hash them
|
||||
CURRENT_LIST=$(jq -c -r '.item.hosts' <<< "$RAW_JSON")
|
||||
CURRENT_HASH=$(sha1sum <<< "$CURRENT_LIST" | awk '{print $1}')
|
||||
# Check to make sure that the server responded with good data - else, bail from script
|
||||
CHECKSUM=$(jq -r '.item.id' <<< "$RAW_JSON")
|
||||
if [ "$CHECKSUM" != "so-manager_kafka" ]; then
|
||||
printf "Failed to query for current Kafka Outputs..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
declare -a NEW_LIST=()
|
||||
# Get the current list of kafka outputs & hash them
|
||||
CURRENT_LIST=$(jq -c -r '.item.hosts' <<< "$RAW_JSON")
|
||||
CURRENT_HASH=$(sha1sum <<< "$CURRENT_LIST" | awk '{print $1}')
|
||||
|
||||
declare -a NEW_LIST=()
|
||||
|
||||
# Query for the current Grid Nodes that are running kafka
|
||||
KAFKANODES=$(salt-call --out=json pillar.get kafka:nodes | jq '.local')
|
||||
|
||||
# Query for Kafka nodes with Broker role and add hostname to list
|
||||
while IFS= read -r line; do
|
||||
NEW_LIST+=("$line")
|
||||
done < <(jq -r 'to_entries | .[] | select(.value.role | contains("broker")) | .key + ":9092"' <<< $KAFKANODES)
|
||||
|
||||
{# If global pipeline isn't set to KAFKA then assume default of REDIS / logstash #}
|
||||
{% else %}
|
||||
# Get current list of Logstash Outputs
|
||||
RAW_JSON=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/outputs/so-manager_logstash')
|
||||
|
||||
# Check to make sure that the server responded with good data - else, bail from script
|
||||
CHECKSUM=$(jq -r '.item.id' <<< "$RAW_JSON")
|
||||
if [ "$CHECKSUM" != "so-manager_logstash" ]; then
|
||||
printf "Failed to query for current Logstash Outputs..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the current list of Logstash outputs & hash them
|
||||
CURRENT_LIST=$(jq -c -r '.item.hosts' <<< "$RAW_JSON")
|
||||
CURRENT_HASH=$(sha1sum <<< "$CURRENT_LIST" | awk '{print $1}')
|
||||
|
||||
declare -a NEW_LIST=()
|
||||
|
||||
{# If we select to not send to manager via SOC, then omit the code that adds manager to NEW_LIST #}
|
||||
{% if ELASTICFLEETMERGED.enable_manager_output %}
|
||||
# Create array & add initial elements
|
||||
if [ "{{ GLOBALS.hostname }}" = "{{ GLOBALS.url_base }}" ]; then
|
||||
NEW_LIST+=("{{ GLOBALS.url_base }}:5055")
|
||||
else
|
||||
NEW_LIST+=("{{ GLOBALS.url_base }}:5055" "{{ GLOBALS.hostname }}:5055")
|
||||
fi
|
||||
{% endif %}
|
||||
|
||||
# Query for FQDN entries & add them to the list
|
||||
{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %}
|
||||
CUSTOMFQDNLIST=('{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(' ') }}')
|
||||
readarray -t -d ' ' CUSTOMFQDN < <(printf '%s' "$CUSTOMFQDNLIST")
|
||||
for CUSTOMNAME in "${CUSTOMFQDN[@]}"
|
||||
do
|
||||
NEW_LIST+=("$CUSTOMNAME:5055")
|
||||
done
|
||||
{% endif %}
|
||||
|
||||
# Query for the current Grid Nodes that are running Logstash
|
||||
LOGSTASHNODES=$(salt-call --out=json pillar.get logstash:nodes | jq '.local')
|
||||
|
||||
# Query for Receiver Nodes & add them to the list
|
||||
if grep -q "receiver" <<< $LOGSTASHNODES; then
|
||||
readarray -t RECEIVERNODES < <(jq -r ' .receiver | keys_unsorted[]' <<< $LOGSTASHNODES)
|
||||
for NODE in "${RECEIVERNODES[@]}"
|
||||
do
|
||||
NEW_LIST+=("$NODE:5055")
|
||||
done
|
||||
fi
|
||||
|
||||
# Query for Fleet Nodes & add them to the list
|
||||
if grep -q "fleet" <<< $LOGSTASHNODES; then
|
||||
readarray -t FLEETNODES < <(jq -r ' .fleet | keys_unsorted[]' <<< $LOGSTASHNODES)
|
||||
for NODE in "${FLEETNODES[@]}"
|
||||
do
|
||||
NEW_LIST+=("$NODE:5055")
|
||||
done
|
||||
fi
|
||||
|
||||
{# If we select to not send to manager via SOC, then omit the code that adds manager to NEW_LIST #}
|
||||
{% if ELASTICFLEETMERGED.enable_manager_output %}
|
||||
# Create array & add initial elements
|
||||
if [ "{{ GLOBALS.hostname }}" = "{{ GLOBALS.url_base }}" ]; then
|
||||
NEW_LIST+=("{{ GLOBALS.url_base }}:5055")
|
||||
else
|
||||
NEW_LIST+=("{{ GLOBALS.url_base }}:5055" "{{ GLOBALS.hostname }}:5055")
|
||||
fi
|
||||
{% endif %}
|
||||
|
||||
# Query for FQDN entries & add them to the list
|
||||
{% if ELASTICFLEETMERGED.config.server.custom_fqdn | length > 0 %}
|
||||
CUSTOMFQDNLIST=('{{ ELASTICFLEETMERGED.config.server.custom_fqdn | join(' ') }}')
|
||||
readarray -t -d ' ' CUSTOMFQDN < <(printf '%s' "$CUSTOMFQDNLIST")
|
||||
for CUSTOMNAME in "${CUSTOMFQDN[@]}"
|
||||
do
|
||||
NEW_LIST+=("$CUSTOMNAME:5055")
|
||||
done
|
||||
{% endif %}
|
||||
|
||||
# Query for the current Grid Nodes that are running Logstash
|
||||
LOGSTASHNODES=$(salt-call --out=json pillar.get logstash:nodes | jq '.local')
|
||||
|
||||
# Query for Receiver Nodes & add them to the list
|
||||
if grep -q "receiver" <<< $LOGSTASHNODES; then
|
||||
readarray -t RECEIVERNODES < <(jq -r ' .receiver | keys_unsorted[]' <<< $LOGSTASHNODES)
|
||||
for NODE in "${RECEIVERNODES[@]}"
|
||||
do
|
||||
NEW_LIST+=("$NODE:5055")
|
||||
done
|
||||
fi
|
||||
|
||||
# Query for Fleet Nodes & add them to the list
|
||||
if grep -q "fleet" <<< $LOGSTASHNODES; then
|
||||
readarray -t FLEETNODES < <(jq -r ' .fleet | keys_unsorted[]' <<< $LOGSTASHNODES)
|
||||
for NODE in "${FLEETNODES[@]}"
|
||||
do
|
||||
NEW_LIST+=("$NODE:5055")
|
||||
done
|
||||
fi
|
||||
|
||||
# Sort & hash the new list of Logstash Outputs
|
||||
NEW_LIST_JSON=$(jq --compact-output --null-input '$ARGS.positional' --args -- "${NEW_LIST[@]}")
|
||||
NEW_HASH=$(sha1sum <<< "$NEW_LIST_JSON" | awk '{print $1}')
|
||||
@@ -87,9 +127,28 @@ NEW_HASH=$(sha1sum <<< "$NEW_LIST_JSON" | awk '{print $1}')
|
||||
if [ "$NEW_HASH" = "$CURRENT_HASH" ]; then
|
||||
printf "\nHashes match - no update needed.\n"
|
||||
printf "Current List: $CURRENT_LIST\nNew List: $NEW_LIST_JSON\n"
|
||||
|
||||
# Since output can be KAFKA or LOGSTASH, we need to check if the policy set as default matches the value set in GLOBALS.pipeline and update if needed
|
||||
printf "Checking if the correct output policy is set as default\n"
|
||||
OUTPUT_DEFAULT=$(jq -r '.item.is_default' <<< $RAW_JSON)
|
||||
OUTPUT_DEFAULT_MONITORING=$(jq -r '.item.is_default_monitoring' <<< $RAW_JSON)
|
||||
if [[ "$OUTPUT_DEFAULT" = "false" || "$OUTPUT_DEFAULT_MONITORING" = "false" ]]; then
|
||||
printf "Default output policy needs to be updated.\n"
|
||||
{%- if GLOBALS.pipeline == "KAFKA" and 'gmd' in salt['pillar.get']('features', []) %}
|
||||
update_kafka_outputs
|
||||
{%- else %}
|
||||
update_logstash_outputs
|
||||
{%- endif %}
|
||||
else
|
||||
printf "Default output policy is set - no update needed.\n"
|
||||
fi
|
||||
exit 0
|
||||
else
|
||||
printf "\nHashes don't match - update needed.\n"
|
||||
printf "Current List: $CURRENT_LIST\nNew List: $NEW_LIST_JSON\n"
|
||||
{%- if GLOBALS.pipeline == "KAFKA" and 'gmd' in salt['pillar.get']('features', []) %}
|
||||
update_kafka_outputs
|
||||
{%- else %}
|
||||
update_logstash_outputs
|
||||
{%- endif %}
|
||||
fi
|
||||
|
||||
@@ -77,6 +77,11 @@ curl -K /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fl
|
||||
printf "\n\n"
|
||||
{%- endif %}
|
||||
|
||||
printf "\nCreate Kafka Output Config if node is not an Import or Eval install\n"
|
||||
{% if grains.role not in ['so-import', 'so-eval'] %}
|
||||
/usr/sbin/so-kafka-fleet-output-policy
|
||||
{% endif %}
|
||||
|
||||
# Add Manager Hostname & URL Base to Fleet Host URLs
|
||||
printf "\nAdd SO-Manager Fleet URL\n"
|
||||
if [ "{{ GLOBALS.hostname }}" = "{{ GLOBALS.url_base }}" ]; then
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/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.
|
||||
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
{% if GLOBALS.role in ['so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
# Check to make sure that Kibana API is up & ready
|
||||
RETURN_CODE=0
|
||||
wait_for_web_response "http://localhost:5601/api/fleet/settings" "fleet" 300 "curl -K /opt/so/conf/elasticsearch/curl.config"
|
||||
RETURN_CODE=$?
|
||||
|
||||
if [[ "$RETURN_CODE" != "0" ]]; then
|
||||
printf "Kibana API not accessible, can't setup Elastic Fleet output policy for Kafka..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
output=$(curl -sK /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/outputs" | jq -r .items[].id)
|
||||
|
||||
if ! echo "$output" | grep -q "so-manager_kafka"; then
|
||||
KAFKACRT=$(openssl x509 -in /etc/pki/elasticfleet-kafka.crt)
|
||||
KAFKAKEY=$(openssl rsa -in /etc/pki/elasticfleet-kafka.key)
|
||||
KAFKACA=$(openssl x509 -in /etc/pki/tls/certs/intca.crt)
|
||||
KAFKA_OUTPUT_VERSION="2.6.0"
|
||||
JSON_STRING=$( jq -n \
|
||||
--arg KAFKACRT "$KAFKACRT" \
|
||||
--arg KAFKAKEY "$KAFKAKEY" \
|
||||
--arg KAFKACA "$KAFKACA" \
|
||||
--arg MANAGER_IP "{{ GLOBALS.manager_ip }}:9092" \
|
||||
--arg KAFKA_OUTPUT_VERSION "$KAFKA_OUTPUT_VERSION" \
|
||||
'{ "name": "grid-kafka", "id": "so-manager_kafka", "type": "kafka", "hosts": [ $MANAGER_IP ], "is_default": false, "is_default_monitoring": false, "config_yaml": "", "ssl": { "certificate_authorities": [ $KAFKACA ], "certificate": $KAFKACRT, "key": $KAFKAKEY, "verification_mode": "full" }, "proxy_id": null, "client_id": "Elastic", "version": $KAFKA_OUTPUT_VERSION, "compression": "none", "auth_type": "ssl", "partition": "round_robin", "round_robin": { "group_events": 1 }, "topics":[{"topic":"%{[event.module]}-securityonion","when":{"type":"regexp","condition":"event.module:.+"}},{"topic":"default-securityonion"}], "headers": [ { "key": "", "value": "" } ], "timeout": 30, "broker_timeout": 30, "required_acks": 1 }'
|
||||
)
|
||||
curl -sK /opt/so/conf/elasticsearch/curl.config -L -X POST "localhost:5601/api/fleet/outputs" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$JSON_STRING" -o /dev/null
|
||||
refresh_output=$(curl -sK /opt/so/conf/elasticsearch/curl.config -L "http://localhost:5601/api/fleet/outputs" | jq -r .items[].id)
|
||||
|
||||
if ! echo "$refresh_output" | grep -q "so-manager_kafka"; then
|
||||
echo -e "\nFailed to setup Elastic Fleet output policy for Kafka...\n"
|
||||
exit 1
|
||||
elif echo "$refresh_output" | grep -q "so-manager_kafka"; then
|
||||
echo -e "\nSuccessfully setup Elastic Fleet output policy for Kafka...\n"
|
||||
fi
|
||||
|
||||
elif echo "$output" | grep -q "so-manager_kafka"; then
|
||||
echo -e "\nElastic Fleet output policy for Kafka already exists...\n"
|
||||
fi
|
||||
{% else %}
|
||||
echo -e "\nNo update required...\n"
|
||||
{% endif %}
|
||||
@@ -4,7 +4,7 @@
|
||||
# Elastic License 2.0.
|
||||
|
||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||
{% if sls.split('.')[0] in allowed_states %}
|
||||
{% if sls.split('.')[0] in allowed_states or sls in allowed_states %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
# Move our new CA over so Elastic and Logstash can use SSL with the internal CA
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +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
|
||||
# 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.split('.')[0] in allowed_states %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
include:
|
||||
- mysql.sostatus
|
||||
|
||||
so-mysql:
|
||||
docker_container.absent:
|
||||
- force: True
|
||||
|
||||
so-mysql_so-status.disabled:
|
||||
file.comment:
|
||||
- name: /opt/so/conf/so-status/so-status.conf
|
||||
- regex: ^so-mysql$
|
||||
so-elasticsearch_image:
|
||||
docker_image.present:
|
||||
- name: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elasticsearch:{{ GLOBALS.so_version }}
|
||||
|
||||
{% else %}
|
||||
|
||||
@@ -200,9 +200,15 @@ so-elasticsearch-roles-load:
|
||||
- require:
|
||||
- docker_container: so-elasticsearch
|
||||
- file: elasticsearch_sbin_jinja
|
||||
{% if grains.role in ['so-eval', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-manager'] %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-manager'] %}
|
||||
{% if ELASTICSEARCHMERGED.index_clean %}
|
||||
{% set ap = "present" %}
|
||||
{% else %}
|
||||
{% set ap = "absent" %}
|
||||
{% endif %}
|
||||
so-elasticsearch-indices-delete:
|
||||
cron.present:
|
||||
cron.{{ap}}:
|
||||
- name: /usr/sbin/so-elasticsearch-indices-delete > /opt/so/log/elasticsearch/cron-elasticsearch-indices-delete.log 2>&1
|
||||
- identifier: so-elasticsearch-indices-delete
|
||||
- user: root
|
||||
@@ -211,7 +217,8 @@ so-elasticsearch-indices-delete:
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
|
||||
@@ -57,10 +57,11 @@
|
||||
{ "convert": { "field": "log.id.uid", "type": "string", "ignore_failure": true, "ignore_missing": true } },
|
||||
{ "convert": { "field": "agent.id", "type": "string", "ignore_failure": true, "ignore_missing": true } },
|
||||
{ "convert": { "field": "event.severity", "type": "integer", "ignore_failure": true, "ignore_missing": true } },
|
||||
{ "set": { "field": "event.dataset", "ignore_empty_value":true, "copy_from": "event.dataset_temp" }},
|
||||
{ "set": { "field": "event.dataset", "ignore_empty_value":true, "copy_from": "event.dataset_temp" } },
|
||||
{ "set": { "if": "ctx.event?.dataset != null && !ctx.event.dataset.contains('.')", "field": "event.dataset", "value": "{{event.module}}.{{event.dataset}}" } },
|
||||
{ "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "dataset_tag_temp" } },
|
||||
{ "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp.1}}" }},
|
||||
{ "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "dataset_tag_temp" } },
|
||||
{ "append": { "if": "ctx.dataset_tag_temp != null", "field": "tags", "value": "{{dataset_tag_temp.1}}" } },
|
||||
{ "grok": { "if": "ctx.http?.response?.status_code != null", "field": "http.response.status_code", "patterns": ["%{NUMBER:http.response.status_code:long} %{GREEDYDATA}"]} },
|
||||
{ "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "dataset_tag_temp", "event.dataset_temp" ], "ignore_missing": true, "ignore_failure": true } }
|
||||
{%- endraw %}
|
||||
{%- if HIGHLANDER %}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"field": "_security",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
},
|
||||
{ "set": { "ignore_failure": true, "field": "event.module", "value": "elastic_agent" } },
|
||||
{ "split": { "if": "ctx.event?.dataset != null && ctx.event.dataset.contains('.')", "field": "event.dataset", "separator": "\\.", "target_field": "module_temp" } },
|
||||
{ "set": { "if": "ctx.module_temp != null", "override": true, "field": "event.module", "value": "{{module_temp.0}}" } },
|
||||
@@ -80,9 +80,11 @@
|
||||
{ "set": { "if": "ctx.network?.type == 'ipv6'", "override": true, "field": "destination.ipv6", "value": "true" } },
|
||||
{ "set": { "if": "ctx.tags.0 == 'import'", "override": true, "field": "data_stream.dataset", "value": "import" } },
|
||||
{ "set": { "if": "ctx.tags.0 == 'import'", "override": true, "field": "data_stream.namespace", "value": "so" } },
|
||||
{ "date": { "if": "ctx.event?.module == 'system'", "field": "event.created", "target_field": "@timestamp", "formats": ["yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'"] } },
|
||||
{ "date": { "if": "ctx.event?.module == 'system'", "field": "event.created", "target_field": "@timestamp","ignore_failure": true, "formats": ["yyyy-MM-dd'T'HH:mm:ss.SSSX","yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'"] } },
|
||||
{ "community_id":{ "if": "ctx.event?.dataset == 'endpoint.events.network'", "ignore_failure":true } },
|
||||
{ "set": { "if": "ctx.event?.module == 'fim'", "override": true, "field": "event.module", "value": "file_integrity" } },
|
||||
{ "rename": { "if": "ctx.winlog?.provider_name == 'Microsoft-Windows-Windows Defender'", "ignore_missing": true, "field": "winlog.event_data.Threat Name", "target_field": "winlog.event_data.threat_name" } },
|
||||
{ "set": { "if": "ctx?.metadata?.kafka != null" , "field": "kafka.id", "value": "{{metadata.kafka.partition}}{{metadata.kafka.offset}}{{metadata.kafka.timestamp}}", "ignore_failure": true } },
|
||||
{ "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset", "event.dataset_temp", "dataset_tag_temp", "module_temp" ], "ignore_missing": true, "ignore_failure": true } }
|
||||
],
|
||||
"on_failure": [
|
||||
|
||||
10
salt/elasticsearch/files/ingest/kismet.ad_hoc
Normal file
10
salt/elasticsearch/files/ingest/kismet.ad_hoc
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_macaddr",
|
||||
"target_field": "network.wireless.bssid"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
50
salt/elasticsearch/files/ingest/kismet.ap
Normal file
50
salt/elasticsearch/files/ingest/kismet.ap
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.dot11_device.dot11_device_last_beaconed_ssid_record.dot11_advertisedssid_cloaked",
|
||||
"target_field": "network.wireless.ssid_cloaked",
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_last_beaconed_ssid_record?.dot11_advertisedssid_cloaked != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.dot11_device.dot11_device_last_beaconed_ssid_record.dot11_advertisedssid_ssid",
|
||||
"target_field": "network.wireless.ssid",
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_last_beaconed_ssid_record?.dot11_advertisedssid_ssid != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "network.wireless.ssid",
|
||||
"value": "Hidden",
|
||||
"if": "ctx?.network?.wireless?.ssid_cloaked != null && ctx?.network?.wireless?.ssid_cloaked == 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.dot11_device.dot11_device_last_beaconed_ssid_record.dot11_advertisedssid_dot11e_channel_utilization_perc",
|
||||
"target_field": "network.wireless.channel_utilization",
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_last_beaconed_ssid_record?.dot11_advertisedssid_dot11e_channel_utilization_perc != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.dot11_device.dot11_device_last_bssid",
|
||||
"target_field": "network.wireless.bssid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"foreach": {
|
||||
"field": "message2.dot11_device.dot11_device_associated_client_map",
|
||||
"processor": {
|
||||
"append": {
|
||||
"field": "network.wireless.associated_clients",
|
||||
"value": "{{_ingest._key}}"
|
||||
}
|
||||
},
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_associated_client_map != null"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
16
salt/elasticsearch/files/ingest/kismet.bridged
Normal file
16
salt/elasticsearch/files/ingest/kismet.bridged
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_macaddr",
|
||||
"target_field": "client.mac"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.dot11_device.dot11_device_last_bssid",
|
||||
"target_field": "network.wireless.bssid"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
29
salt/elasticsearch/files/ingest/kismet.client
Normal file
29
salt/elasticsearch/files/ingest/kismet.client
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_macaddr",
|
||||
"target_field": "client.mac"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.dot11_device.dot11_device_last_bssid",
|
||||
"target_field": "network.wireless.last_connected_bssid",
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_last_bssid != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"foreach": {
|
||||
"field": "message2.dot11_device.dot11_device_client_map",
|
||||
"processor": {
|
||||
"append": {
|
||||
"field": "network.wireless.known_connected_bssid",
|
||||
"value": "{{_ingest._key}}"
|
||||
}
|
||||
},
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_client_map != null"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
159
salt/elasticsearch/files/ingest/kismet.common
Normal file
159
salt/elasticsearch/files/ingest/kismet.common
Normal file
@@ -0,0 +1,159 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"json": {
|
||||
"field": "message",
|
||||
"target_field": "message2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"field": "message2.kismet_device_base_mod_time",
|
||||
"formats": [
|
||||
"epoch_second"
|
||||
],
|
||||
"target_field": "@timestamp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.category",
|
||||
"value": "network"
|
||||
}
|
||||
},
|
||||
{
|
||||
"dissect": {
|
||||
"field": "message2.kismet_device_base_type",
|
||||
"pattern": "%{wifi} %{device_type}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"lowercase": {
|
||||
"field": "device_type"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.dataset",
|
||||
"value": "kismet.{{device_type}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.dataset",
|
||||
"value": "kismet.wds_ap",
|
||||
"if": "ctx?.device_type == 'wds ap'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.dataset",
|
||||
"value": "kismet.ad_hoc",
|
||||
"if": "ctx?.device_type == 'ad-hoc'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.module",
|
||||
"value": "kismet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_packets_tx_total",
|
||||
"target_field": "source.packets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_num_alerts",
|
||||
"target_field": "kismet.alerts.count"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_channel",
|
||||
"target_field": "network.wireless.channel",
|
||||
"if": "ctx?.message2?.kismet_device_base_channel != ''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_frequency",
|
||||
"target_field": "network.wireless.frequency",
|
||||
"if": "ctx?.message2?.kismet_device_base_frequency != 0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_last_time",
|
||||
"target_field": "kismet.last_seen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"field": "kismet.last_seen",
|
||||
"formats": [
|
||||
"epoch_second"
|
||||
],
|
||||
"target_field": "kismet.last_seen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_first_time",
|
||||
"target_field": "kismet.first_seen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"field": "kismet.first_seen",
|
||||
"formats": [
|
||||
"epoch_second"
|
||||
],
|
||||
"target_field": "kismet.first_seen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_seenby",
|
||||
"target_field": "kismet.seenby"
|
||||
}
|
||||
},
|
||||
{
|
||||
"foreach": {
|
||||
"field": "kismet.seenby",
|
||||
"processor": {
|
||||
"pipeline": {
|
||||
"name": "kismet.seenby"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_manuf",
|
||||
"target_field": "device.manufacturer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "{{event.dataset}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"remove": {
|
||||
"field": [
|
||||
"message2",
|
||||
"message",
|
||||
"device_type",
|
||||
"wifi",
|
||||
"agent",
|
||||
"host",
|
||||
"event.created"
|
||||
],
|
||||
"ignore_failure": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
9
salt/elasticsearch/files/ingest/kismet.device
Normal file
9
salt/elasticsearch/files/ingest/kismet.device
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "kismet.client"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
52
salt/elasticsearch/files/ingest/kismet.seenby
Normal file
52
salt/elasticsearch/files/ingest/kismet.seenby
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "_ingest._value.kismet_common_seenby_num_packets",
|
||||
"target_field": "_ingest._value.packets_seen",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "_ingest._value.kismet_common_seenby_uuid",
|
||||
"target_field": "_ingest._value.serial_number",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "_ingest._value.kismet_common_seenby_first_time",
|
||||
"target_field": "_ingest._value.first_seen",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "_ingest._value.kismet_common_seenby_last_time",
|
||||
"target_field": "_ingest._value.last_seen",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"field": "_ingest._value.first_seen",
|
||||
"formats": [
|
||||
"epoch_second"
|
||||
],
|
||||
"target_field": "_ingest._value.first_seen",
|
||||
"ignore_failure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"field": "_ingest._value.last_seen",
|
||||
"formats": [
|
||||
"epoch_second"
|
||||
],
|
||||
"target_field": "_ingest._value.last_seen",
|
||||
"ignore_failure": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
10
salt/elasticsearch/files/ingest/kismet.wds
Normal file
10
salt/elasticsearch/files/ingest/kismet.wds
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_macaddr",
|
||||
"target_field": "client.mac"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
22
salt/elasticsearch/files/ingest/kismet.wds_ap
Normal file
22
salt/elasticsearch/files/ingest/kismet.wds_ap
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"processors": [
|
||||
{
|
||||
"rename": {
|
||||
"field": "message2.kismet_device_base_commonname",
|
||||
"target_field": "network.wireless.bssid"
|
||||
}
|
||||
},
|
||||
{
|
||||
"foreach": {
|
||||
"field": "message2.dot11_device.dot11_device_associated_client_map",
|
||||
"processor": {
|
||||
"append": {
|
||||
"field": "network.wireless.associated_clients",
|
||||
"value": "{{_ingest._key}}"
|
||||
}
|
||||
},
|
||||
"if": "ctx?.message2?.dot11_device?.dot11_device_associated_client_map != null"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
389
salt/elasticsearch/files/ingest/logs-pfsense.log-1.16.0
Normal file
389
salt/elasticsearch/files/ingest/logs-pfsense.log-1.16.0
Normal file
@@ -0,0 +1,389 @@
|
||||
{
|
||||
"description": "Pipeline for pfSense",
|
||||
"processors": [
|
||||
{
|
||||
"set": {
|
||||
"field": "ecs.version",
|
||||
"value": "8.10.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "observer.vendor",
|
||||
"value": "netgate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "observer.type",
|
||||
"value": "firewall"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "message",
|
||||
"target_field": "event.original"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.kind",
|
||||
"value": "event"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.timezone",
|
||||
"value": "{{_tmp.tz_offset}}",
|
||||
"if": "ctx._tmp?.tz_offset != null && ctx._tmp?.tz_offset != 'local'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"grok": {
|
||||
"description": "Parse syslog header",
|
||||
"field": "event.original",
|
||||
"patterns": [
|
||||
"^(%{ECS_SYSLOG_PRI})?%{TIMESTAMP} %{GREEDYDATA:message}"
|
||||
],
|
||||
"pattern_definitions": {
|
||||
"ECS_SYSLOG_PRI": "<%{NONNEGINT:log.syslog.priority:long}>(\\d )?",
|
||||
"TIMESTAMP": "(?:%{BSD_TIMESTAMP_FORMAT}|%{SYSLOG_TIMESTAMP_FORMAT})",
|
||||
"BSD_TIMESTAMP_FORMAT": "%{SYSLOGTIMESTAMP:_tmp.timestamp}(%{SPACE}%{BSD_PROCNAME}|%{SPACE}%{OBSERVER}%{SPACE}%{BSD_PROCNAME})(\\[%{POSINT:process.pid:long}\\])?:",
|
||||
"BSD_PROCNAME": "(?:\\b%{NAME:process.name}|\\(%{NAME:process.name}\\))",
|
||||
"NAME": "[[[:alnum:]]_-]+",
|
||||
"SYSLOG_TIMESTAMP_FORMAT": "%{TIMESTAMP_ISO8601:_tmp.timestamp8601}%{SPACE}%{OBSERVER}%{SPACE}%{PROCESS}%{SPACE}(%{POSINT:process.pid:long}|-) - (-|%{META})",
|
||||
"TIMESTAMP_ISO8601": "%{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE:event.timezone}?",
|
||||
"OBSERVER": "(?:%{IP:observer.ip}|%{HOSTNAME:observer.name})",
|
||||
"PROCESS": "(\\(%{DATA:process.name}\\)|(?:%{UNIXPATH}*/)?%{BASEPATH:process.name})",
|
||||
"BASEPATH": "[[[:alnum:]]_%!$@:.,+~-]+",
|
||||
"META": "\\[[^\\]]*\\]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"if": "ctx._tmp.timestamp8601 != null",
|
||||
"field": "_tmp.timestamp8601",
|
||||
"target_field": "@timestamp",
|
||||
"formats": [
|
||||
"ISO8601"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": {
|
||||
"if": "ctx.event?.timezone != null && ctx._tmp?.timestamp != null",
|
||||
"field": "_tmp.timestamp",
|
||||
"target_field": "@timestamp",
|
||||
"formats": [
|
||||
"MMM d HH:mm:ss",
|
||||
"MMM d HH:mm:ss",
|
||||
"MMM dd HH:mm:ss"
|
||||
],
|
||||
"timezone": "{{ event.timezone }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"grok": {
|
||||
"description": "Set Event Provider",
|
||||
"field": "process.name",
|
||||
"patterns": [
|
||||
"^%{HYPHENATED_WORDS:event.provider}"
|
||||
],
|
||||
"pattern_definitions": {
|
||||
"HYPHENATED_WORDS": "\\b[A-Za-z0-9_]+(-[A-Za-z_]+)*\\b"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-firewall",
|
||||
"if": "ctx.event.provider == 'filterlog'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-openvpn",
|
||||
"if": "ctx.event.provider == 'openvpn'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-ipsec",
|
||||
"if": "ctx.event.provider == 'charon'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-dhcp",
|
||||
"if": "[\"dhcpd\", \"dhclient\", \"dhcp6c\"].contains(ctx.event.provider)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-unbound",
|
||||
"if": "ctx.event.provider == 'unbound'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-haproxy",
|
||||
"if": "ctx.event.provider == 'haproxy'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-php-fpm",
|
||||
"if": "ctx.event.provider == 'php-fpm'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-squid",
|
||||
"if": "ctx.event.provider == 'squid'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log-1.16.0-suricata",
|
||||
"if": "ctx.event.provider == 'suricata'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"drop": {
|
||||
"if": "![\"filterlog\", \"openvpn\", \"charon\", \"dhcpd\", \"dhclient\", \"dhcp6c\", \"unbound\", \"haproxy\", \"php-fpm\", \"squid\", \"suricata\"].contains(ctx.event?.provider)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "event.category",
|
||||
"value": "network",
|
||||
"if": "ctx.network != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"convert": {
|
||||
"field": "source.address",
|
||||
"target_field": "source.ip",
|
||||
"type": "ip",
|
||||
"ignore_failure": true,
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"convert": {
|
||||
"field": "destination.address",
|
||||
"target_field": "destination.ip",
|
||||
"type": "ip",
|
||||
"ignore_failure": true,
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "network.type",
|
||||
"value": "ipv6",
|
||||
"if": "ctx.source?.ip != null && ctx.source.ip.contains(\":\")"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "network.type",
|
||||
"value": "ipv4",
|
||||
"if": "ctx.source?.ip != null && ctx.source.ip.contains(\".\")"
|
||||
}
|
||||
},
|
||||
{
|
||||
"geoip": {
|
||||
"field": "source.ip",
|
||||
"target_field": "source.geo",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"geoip": {
|
||||
"field": "destination.ip",
|
||||
"target_field": "destination.geo",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"geoip": {
|
||||
"ignore_missing": true,
|
||||
"database_file": "GeoLite2-ASN.mmdb",
|
||||
"field": "source.ip",
|
||||
"target_field": "source.as",
|
||||
"properties": [
|
||||
"asn",
|
||||
"organization_name"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"geoip": {
|
||||
"database_file": "GeoLite2-ASN.mmdb",
|
||||
"field": "destination.ip",
|
||||
"target_field": "destination.as",
|
||||
"properties": [
|
||||
"asn",
|
||||
"organization_name"
|
||||
],
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "source.as.asn",
|
||||
"target_field": "source.as.number",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "source.as.organization_name",
|
||||
"target_field": "source.as.organization.name",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "destination.as.asn",
|
||||
"target_field": "destination.as.number",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"rename": {
|
||||
"field": "destination.as.organization_name",
|
||||
"target_field": "destination.as.organization.name",
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"community_id": {
|
||||
"target_field": "network.community_id",
|
||||
"ignore_failure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"grok": {
|
||||
"field": "observer.ingress.interface.name",
|
||||
"patterns": [
|
||||
"%{DATA}.%{NONNEGINT:observer.ingress.vlan.id}"
|
||||
],
|
||||
"ignore_missing": true,
|
||||
"ignore_failure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "network.vlan.id",
|
||||
"copy_from": "observer.ingress.vlan.id",
|
||||
"ignore_empty_value": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "related.ip",
|
||||
"value": "{{destination.ip}}",
|
||||
"allow_duplicates": false,
|
||||
"if": "ctx.destination?.ip != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "related.ip",
|
||||
"value": "{{source.ip}}",
|
||||
"allow_duplicates": false,
|
||||
"if": "ctx.source?.ip != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "related.ip",
|
||||
"value": "{{source.nat.ip}}",
|
||||
"allow_duplicates": false,
|
||||
"if": "ctx.source?.nat?.ip != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "related.hosts",
|
||||
"value": "{{destination.domain}}",
|
||||
"if": "ctx.destination?.domain != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "related.user",
|
||||
"value": "{{user.name}}",
|
||||
"if": "ctx.user?.name != null"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "network.direction",
|
||||
"value": "{{network.direction}}bound",
|
||||
"if": "ctx.network?.direction != null && ctx.network?.direction =~ /^(in|out)$/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"remove": {
|
||||
"field": [
|
||||
"_tmp"
|
||||
],
|
||||
"ignore_failure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": {
|
||||
"lang": "painless",
|
||||
"description": "This script processor iterates over the whole document to remove fields with null values.",
|
||||
"source": "void handleMap(Map map) {\n for (def x : map.values()) {\n if (x instanceof Map) {\n handleMap(x);\n } else if (x instanceof List) {\n handleList(x);\n }\n }\n map.values().removeIf(v -> v == null || (v instanceof String && v == \"-\"));\n}\nvoid handleList(List list) {\n for (def x : list) {\n if (x instanceof Map) {\n handleMap(x);\n } else if (x instanceof List) {\n handleList(x);\n }\n }\n}\nhandleMap(ctx);\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"remove": {
|
||||
"field": "event.original",
|
||||
"if": "ctx.tags == null || !(ctx.tags.contains('preserve_original_event'))",
|
||||
"ignore_failure": true,
|
||||
"ignore_missing": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "logs-pfsense.log@custom",
|
||||
"ignore_missing_pipeline": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"on_failure": [
|
||||
{
|
||||
"remove": {
|
||||
"field": [
|
||||
"_tmp"
|
||||
],
|
||||
"ignore_failure": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"set": {
|
||||
"field": "event.kind",
|
||||
"value": "pipeline_error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "error.message",
|
||||
"value": "{{{ _ingest.on_failure_message }}}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"_meta": {
|
||||
"managed_by": "fleet",
|
||||
"managed": true,
|
||||
"package": {
|
||||
"name": "pfsense"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"description": "Pipeline for parsing pfSense Suricata logs.",
|
||||
"processors": [
|
||||
{
|
||||
"pipeline": {
|
||||
"name": "suricata.common"
|
||||
}
|
||||
}
|
||||
],
|
||||
"on_failure": [
|
||||
{
|
||||
"set": {
|
||||
"field": "event.kind",
|
||||
"value": "pipeline_error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"append": {
|
||||
"field": "error.message",
|
||||
"value": "{{{ _ingest.on_failure_message }}}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"_meta": {
|
||||
"managed_by": "fleet",
|
||||
"managed": true,
|
||||
"package": {
|
||||
"name": "pfsense"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,7 @@
|
||||
{ "set": { "if": "ctx.exiftool?.Subsystem != null", "field": "host.subsystem", "value": "{{exiftool.Subsystem}}", "ignore_failure": true }},
|
||||
{ "set": { "if": "ctx.scan?.yara?.matches instanceof List", "field": "rule.name", "value": "{{scan.yara.matches.0}}" }},
|
||||
{ "set": { "if": "ctx.rule?.name != null", "field": "event.dataset", "value": "alert", "override": true }},
|
||||
{ "set": { "if": "ctx.rule?.name != null", "field": "rule.uuid", "value": "{{rule.name}}", "override": true }},
|
||||
{ "rename": { "field": "file.flavors.mime", "target_field": "file.mime_type", "ignore_missing": true }},
|
||||
{ "set": { "if": "ctx.rule?.name != null && ctx.rule?.score == null", "field": "event.severity", "value": 3, "override": true } },
|
||||
{ "convert" : { "if": "ctx.rule?.score != null", "field" : "rule.score","type": "integer"}},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"description" : "suricata.alert",
|
||||
"processors" : [
|
||||
{ "set": { "field": "_index", "value": "logs-suricata.alerts-so" } },
|
||||
{ "set": { "field": "tags","value": "alert" }},
|
||||
{ "rename":{ "field": "message2.alert", "target_field": "rule", "ignore_failure": true } },
|
||||
{ "rename":{ "field": "rule.signature", "target_field": "rule.name", "ignore_failure": true } },
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
{ "rename": { "field": "message2.vlan", "target_field": "network.vlan.id", "ignore_failure": true } },
|
||||
{ "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } },
|
||||
{ "rename": { "field": "message2.xff", "target_field": "xff.ip", "ignore_missing": true } },
|
||||
{ "lowercase": { "field": "network.transport", "ignore_failure": true } },
|
||||
{ "set": { "field": "event.dataset", "value": "{{ message2.event_type }}" } },
|
||||
{ "set": { "field": "observer.name", "value": "{{agent.name}}" } },
|
||||
{ "set": { "field": "event.ingested", "value": "{{@timestamp}}" } },
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
"monitor",
|
||||
"read",
|
||||
"read_cross_cluster",
|
||||
"view_index_metadata"
|
||||
"view_index_metadata",
|
||||
"write"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
"monitor",
|
||||
"read",
|
||||
"read_cross_cluster",
|
||||
"view_index_metadata"
|
||||
"view_index_metadata",
|
||||
"write"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -5,6 +5,10 @@ elasticsearch:
|
||||
esheap:
|
||||
description: Specify the memory heap size in (m)egabytes for Elasticsearch.
|
||||
helpLink: elasticsearch.html
|
||||
index_clean:
|
||||
description: Determines if indices should be considered for deletion by available disk space in the cluster. Otherwise, indices will only be deleted by the age defined in the ILM settings.
|
||||
forcedType: bool
|
||||
helpLink: elasticsearch.html
|
||||
retention:
|
||||
retention_pct:
|
||||
decription: Total percentage of space used by Elasticsearch for multi node clusters
|
||||
@@ -98,10 +102,6 @@ elasticsearch:
|
||||
policy:
|
||||
phases:
|
||||
hot:
|
||||
max_age:
|
||||
description: Maximum age of index. ex. 7d - This determines when the index should be moved out of the hot tier.
|
||||
global: True
|
||||
helpLink: elasticsearch.html
|
||||
actions:
|
||||
set_priority:
|
||||
priority:
|
||||
@@ -120,7 +120,9 @@ elasticsearch:
|
||||
helpLink: elasticsearch.html
|
||||
cold:
|
||||
min_age:
|
||||
description: Minimum age of index. ex. 30d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed.
|
||||
description: Minimum age of index. ex. 60d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed.
|
||||
regex: ^[0-9]{1,5}d$
|
||||
forcedType: string
|
||||
global: True
|
||||
helpLink: elasticsearch.html
|
||||
actions:
|
||||
@@ -131,8 +133,8 @@ elasticsearch:
|
||||
helpLink: elasticsearch.html
|
||||
warm:
|
||||
min_age:
|
||||
description: Minimum age of index. ex. 30d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed.
|
||||
regex: ^\[0-9\]{1,5}d$
|
||||
description: Minimum age of index. ex. 30d - This determines when the index should be moved to the warm tier. Nodes in the warm tier generally don’t need to be as fast as those in the hot tier.
|
||||
regex: ^[0-9]{1,5}d$
|
||||
forcedType: string
|
||||
global: True
|
||||
actions:
|
||||
@@ -145,6 +147,8 @@ elasticsearch:
|
||||
delete:
|
||||
min_age:
|
||||
description: Minimum age of index. ex. 90d - This determines when the index should be deleted.
|
||||
regex: ^[0-9]{1,5}d$
|
||||
forcedType: string
|
||||
global: True
|
||||
helpLink: elasticsearch.html
|
||||
so-logs: &indexSettings
|
||||
@@ -271,7 +275,9 @@ elasticsearch:
|
||||
helpLink: elasticsearch.html
|
||||
warm:
|
||||
min_age:
|
||||
description: Minimum age of index. This determines when the index should be moved to the hot tier.
|
||||
description: Minimum age of index. ex. 30d - This determines when the index should be moved to the warm tier. Nodes in the warm tier generally don’t need to be as fast as those in the hot tier.
|
||||
regex: ^[0-9]{1,5}d$
|
||||
forcedType: string
|
||||
global: True
|
||||
advanced: True
|
||||
helpLink: elasticsearch.html
|
||||
@@ -296,7 +302,9 @@ elasticsearch:
|
||||
helpLink: elasticsearch.html
|
||||
cold:
|
||||
min_age:
|
||||
description: Minimum age of index. This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed.
|
||||
description: Minimum age of index. ex. 60d - This determines when the index should be moved to the cold tier. While still searchable, this tier is typically optimized for lower storage costs rather than search speed.
|
||||
regex: ^[0-9]{1,5}d$
|
||||
forcedType: string
|
||||
global: True
|
||||
advanced: True
|
||||
helpLink: elasticsearch.html
|
||||
@@ -311,6 +319,8 @@ elasticsearch:
|
||||
delete:
|
||||
min_age:
|
||||
description: Minimum age of index. This determines when the index should be deleted.
|
||||
regex: ^[0-9]{1,5}d$
|
||||
forcedType: string
|
||||
global: True
|
||||
advanced: True
|
||||
helpLink: elasticsearch.html
|
||||
@@ -366,6 +376,7 @@ elasticsearch:
|
||||
so-logs-azure_x_signinlogs: *indexSettings
|
||||
so-logs-azure_x_springcloudlogs: *indexSettings
|
||||
so-logs-barracuda_x_waf: *indexSettings
|
||||
so-logs-cef_x_log: *indexSettings
|
||||
so-logs-cisco_asa_x_log: *indexSettings
|
||||
so-logs-cisco_ftd_x_log: *indexSettings
|
||||
so-logs-cisco_ios_x_log: *indexSettings
|
||||
@@ -383,6 +394,7 @@ elasticsearch:
|
||||
so-logs-darktrace_x_ai_analyst_alert: *indexSettings
|
||||
so-logs-darktrace_x_model_breach_alert: *indexSettings
|
||||
so-logs-darktrace_x_system_status_alert: *indexSettings
|
||||
so-logs-detections_x_alerts: *indexSettings
|
||||
so-logs-f5_bigip_x_log: *indexSettings
|
||||
so-logs-fim_x_event: *indexSettings
|
||||
so-logs-fortinet_x_clientendpoint: *indexSettings
|
||||
@@ -509,8 +521,10 @@ elasticsearch:
|
||||
so-endgame: *indexSettings
|
||||
so-idh: *indexSettings
|
||||
so-suricata: *indexSettings
|
||||
so-suricata_x_alerts: *indexSettings
|
||||
so-import: *indexSettings
|
||||
so-kratos: *indexSettings
|
||||
so-kismet: *indexSettings
|
||||
so-logstash: *indexSettings
|
||||
so-redis: *indexSettings
|
||||
so-strelka: *indexSettings
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
{% set DEFAULT_GLOBAL_OVERRIDES = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings.pop('global_overrides') %}
|
||||
|
||||
{% set PILLAR_GLOBAL_OVERRIDES = {} %}
|
||||
{% if salt['pillar.get']('elasticsearch:index_settings') is defined %}
|
||||
{% set ES_INDEX_PILLAR = salt['pillar.get']('elasticsearch:index_settings') %}
|
||||
{% if ES_INDEX_PILLAR.global_overrides is defined %}
|
||||
{% set PILLAR_GLOBAL_OVERRIDES = ES_INDEX_PILLAR.pop('global_overrides') %}
|
||||
{% endif %}
|
||||
{% set ES_INDEX_PILLAR = salt['pillar.get']('elasticsearch:index_settings', {}) %}
|
||||
{% if ES_INDEX_PILLAR.global_overrides is defined %}
|
||||
{% set PILLAR_GLOBAL_OVERRIDES = ES_INDEX_PILLAR.pop('global_overrides') %}
|
||||
{% endif %}
|
||||
|
||||
{% set ES_INDEX_SETTINGS_ORIG = ELASTICSEARCHDEFAULTS.elasticsearch.index_settings %}
|
||||
@@ -19,6 +17,12 @@
|
||||
{% set ES_INDEX_SETTINGS = {} %}
|
||||
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.update(salt['defaults.merge'](ES_INDEX_SETTINGS_GLOBAL_OVERRIDES, ES_INDEX_PILLAR, in_place=False)) %}
|
||||
{% for index, settings in ES_INDEX_SETTINGS_GLOBAL_OVERRIDES.items() %}
|
||||
{# if policy isn't defined in the original index settings, then dont merge policy from the global_overrides #}
|
||||
{# this will prevent so-elasticsearch-ilm-policy-load from trying to load policy on non ILM manged indices #}
|
||||
{% if not ES_INDEX_SETTINGS_ORIG[index].policy is defined and ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].policy is defined %}
|
||||
{% do ES_INDEX_SETTINGS_GLOBAL_OVERRIDES[index].pop('policy') %}
|
||||
{% endif %}
|
||||
|
||||
{% if settings.index_template is defined %}
|
||||
{% if not settings.get('index_sorting', False) | to_bool and settings.index_template.template.settings.index.sort is defined %}
|
||||
{% do settings.index_template.template.settings.index.pop('sort') %}
|
||||
|
||||
36
salt/elasticsearch/templates/component/ecs/device.json
Normal file
36
salt/elasticsearch/templates/component/ecs/device.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"_meta": {
|
||||
"documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-device.html",
|
||||
"ecs_version": "1.12.2"
|
||||
},
|
||||
"template": {
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"device": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"manufacturer": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"model": {
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"name": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
salt/elasticsearch/templates/component/ecs/kismet.json
Normal file
32
salt/elasticsearch/templates/component/ecs/kismet.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"_meta": {
|
||||
"documentation": "https://www.elastic.co/guide/en/ecs/current/ecs-base.html",
|
||||
"ecs_version": "1.12.2"
|
||||
},
|
||||
"template": {
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"kismet": {
|
||||
"properties": {
|
||||
"alerts": {
|
||||
"properties": {
|
||||
"count": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"first_seen": {
|
||||
"type": "date"
|
||||
},
|
||||
"last_seen": {
|
||||
"type": "date"
|
||||
},
|
||||
"seenby": {
|
||||
"type": "nested"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,43 @@
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"wireless": {
|
||||
"properties": {
|
||||
"associated_clients": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"bssid": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"channel": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"channel_utilization": {
|
||||
"type": "float"
|
||||
},
|
||||
"frequency": {
|
||||
"type": "double"
|
||||
},
|
||||
"ssid": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"ssid_cloaked": {
|
||||
"type": "integer"
|
||||
},
|
||||
"known_connected_bssid": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"last_connected_bssid": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"template": {
|
||||
"mappings": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"binary": {
|
||||
"type": "binary"
|
||||
},
|
||||
"boolean": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"byte": {
|
||||
"type": "byte"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "date"
|
||||
},
|
||||
"created_by": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"date": {
|
||||
"type": "date"
|
||||
},
|
||||
"date_nanos": {
|
||||
"type": "date_nanos"
|
||||
},
|
||||
"date_range": {
|
||||
"type": "date_range"
|
||||
},
|
||||
"deserializer": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"double": {
|
||||
"type": "double"
|
||||
},
|
||||
"double_range": {
|
||||
"type": "double_range"
|
||||
},
|
||||
"float": {
|
||||
"type": "float"
|
||||
},
|
||||
"float_range": {
|
||||
"type": "float_range"
|
||||
},
|
||||
"geo_point": {
|
||||
"type": "geo_point"
|
||||
},
|
||||
"geo_shape": {
|
||||
"type": "geo_shape"
|
||||
},
|
||||
"half_float": {
|
||||
"type": "half_float"
|
||||
},
|
||||
"integer": {
|
||||
"type": "integer"
|
||||
},
|
||||
"integer_range": {
|
||||
"type": "integer_range"
|
||||
},
|
||||
"ip": {
|
||||
"type": "ip"
|
||||
},
|
||||
"ip_range": {
|
||||
"type": "ip_range"
|
||||
},
|
||||
"keyword": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"list_id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"long": {
|
||||
"type": "long"
|
||||
},
|
||||
"long_range": {
|
||||
"type": "long_range"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"enabled": false
|
||||
},
|
||||
"serializer": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"shape": {
|
||||
"type": "shape"
|
||||
},
|
||||
"short": {
|
||||
"type": "short"
|
||||
},
|
||||
"text": {
|
||||
"type": "text"
|
||||
},
|
||||
"tie_breaker_id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "date"
|
||||
},
|
||||
"updated_by": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"aliases": {}
|
||||
},
|
||||
"version": 2,
|
||||
"_meta": {
|
||||
"managed": true,
|
||||
"description": "default mappings for the .items index template installed by Kibana/Security"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"template": {
|
||||
"mappings": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "date"
|
||||
},
|
||||
"created_by": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"deserializer": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"immutable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"enabled": false
|
||||
},
|
||||
"name": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"serializer": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"tie_breaker_id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"type": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "date"
|
||||
},
|
||||
"updated_by": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"version": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"aliases": {}
|
||||
},
|
||||
"version": 2,
|
||||
"_meta": {
|
||||
"managed": true,
|
||||
"description": "default mappings for the .lists index template installed by Kibana/Security"
|
||||
}
|
||||
}
|
||||
@@ -20,21 +20,36 @@
|
||||
"so_detection": {
|
||||
"properties": {
|
||||
"publicId": {
|
||||
"type": "text"
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"severity": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"author": {
|
||||
"type": "text"
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"category": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"product": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"service": {
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"content": {
|
||||
"type": "text"
|
||||
},
|
||||
@@ -48,7 +63,8 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"tags": {
|
||||
"type": "text"
|
||||
"ignore_above": 1024,
|
||||
"type": "keyword"
|
||||
},
|
||||
"ruleset": {
|
||||
"ignore_above": 1024,
|
||||
@@ -135,4 +151,4 @@
|
||||
"_meta": {
|
||||
"ecs_version": "1.12.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
|
||||
curl -K /opt/so/conf/elasticsearch/curl.config-X GET -k -L "https://localhost:9200/_cat/indices?v&s=index"
|
||||
curl -K /opt/so/conf/elasticsearch/curl.config -s -k -L "https://localhost:9200/_cat/indices?pretty&v&s=index"
|
||||
|
||||
@@ -40,7 +40,7 @@ fi
|
||||
|
||||
# Iterate through the output of _cat/allocation for each node in the cluster to determine the total available space
|
||||
{% if GLOBALS.role == 'so-manager' %}
|
||||
for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v {{ GLOBALS.manager }} | awk '{print $5}'); do
|
||||
for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v "{{ GLOBALS.manager }}$" | awk '{print $5}'); do
|
||||
{% else %}
|
||||
for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | awk '{print $5}'); do
|
||||
{% endif %}
|
||||
|
||||
@@ -13,7 +13,7 @@ TOTAL_USED_SPACE=0
|
||||
# Iterate through the output of _cat/allocation for each node in the cluster to determine the total used space
|
||||
{% if GLOBALS.role == 'so-manager' %}
|
||||
# Get total disk space - disk.total
|
||||
for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v {{ GLOBALS.manager }} | awk '{print $3}'); do
|
||||
for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | grep -v "{{ GLOBALS.manager }}$" | awk '{print $3}'); do
|
||||
{% else %}
|
||||
# Get disk space taken up by indices - disk.indices
|
||||
for i in $(/usr/sbin/so-elasticsearch-query _cat/allocation | awk '{print $2}'); do
|
||||
|
||||
@@ -27,6 +27,7 @@ overlimit() {
|
||||
# 2. Check if the maximum number of iterations - MAX_ITERATIONS - has been exceeded. If so, exit.
|
||||
# Closed indices will be deleted first. If we are able to bring disk space under LOG_SIZE_LIMIT, or the number of iterations has exceeded the maximum allowed number of iterations, we will break out of the loop.
|
||||
|
||||
|
||||
while overlimit && [[ $ITERATION -lt $MAX_ITERATIONS ]]; do
|
||||
|
||||
# If we can't query Elasticsearch, then immediately return false.
|
||||
@@ -34,28 +35,36 @@ while overlimit && [[ $ITERATION -lt $MAX_ITERATIONS ]]; do
|
||||
[ $? -eq 1 ] && echo "$(date) - Could not query Elasticsearch." >> ${LOG} && exit
|
||||
|
||||
# We iterate through the closed and open indices
|
||||
CLOSED_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'close$' | awk '{print $1}' | grep -vE "playbook|so-case" | grep -E "(logstash-|so-|.ds-logs-)" | sort -t- -k3)
|
||||
OPEN_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'open$' | awk '{print $1}' | grep -vE "playbook|so-case" | grep -E "(logstash-|so-|.ds-logs-)" | sort -t- -k3)
|
||||
CLOSED_SO_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'close$' | awk '{print $1}' | grep -E "(^logstash-.*|^so-.*)" | grep -vE "so-case|so-detection" | sort -t- -k3)
|
||||
CLOSED_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'close$' | awk '{print $1}' | grep -E "^.ds-logs-.*" | grep -v "suricata" | sort -t- -k4)
|
||||
OPEN_SO_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'open$' | awk '{print $1}' | grep -E "(^logstash-.*|^so-.*)" | grep -vE "so-case|so-detection" | sort -t- -k3)
|
||||
OPEN_INDICES=$(/usr/sbin/so-elasticsearch-query _cat/indices?h=index,status | grep 'open$' | awk '{print $1}' | grep -E "^.ds-logs-.*" | grep -v "suricata" | sort -t- -k4)
|
||||
|
||||
for INDEX in ${CLOSED_INDICES} ${OPEN_INDICES}; do
|
||||
# Now that we've sorted the indices from oldest to newest, we need to check each index to see if it is assigned as the current write index for a data stream
|
||||
# To do so, we need to identify to which data stream this index is associated
|
||||
# We extract the data stream name using the pattern below
|
||||
DATASTREAM_PATTERN="logs-[a-zA-Z_.]+-[a-zA-Z_.]+"
|
||||
DATASTREAM=$(echo "${INDEX}" | grep -oE "$DATASTREAM_PATTERN")
|
||||
# We look up the data stream, and determine the write index. If there is only one backing index, we delete the entire data stream
|
||||
BACKING_INDICES=$(/usr/sbin/so-elasticsearch-query _data_stream/${DATASTREAM} | jq -r '.data_streams[0].indices | length')
|
||||
if [ "$BACKING_INDICES" -gt 1 ]; then
|
||||
CURRENT_WRITE_INDEX=$(/usr/sbin/so-elasticsearch-query _data_stream/$DATASTREAM | jq -r .data_streams[0].indices[-1].index_name)
|
||||
# We make sure we are not trying to delete a write index
|
||||
if [ "${INDEX}" != "${CURRENT_WRITE_INDEX}" ]; then
|
||||
# This should not be a write index, so we should be allowed to delete it
|
||||
printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - Deleting ${INDEX} index...\n" >> ${LOG}
|
||||
/usr/sbin/so-elasticsearch-query ${INDEX} -XDELETE >> ${LOG} 2>&1
|
||||
fi
|
||||
for INDEX in ${CLOSED_SO_INDICES} ${OPEN_SO_INDICES} ${CLOSED_INDICES} ${OPEN_INDICES}; do
|
||||
# Check if index is an older index. If it is an older index, delete it before moving on to newer indices.
|
||||
if [[ "$INDEX" =~ "^logstash-.*|so-.*" ]]; then
|
||||
printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - Deleting ${INDEX} index...\n" >> ${LOG}
|
||||
/usr/sbin/so-elasticsearch-query ${INDEX} -XDELETE >> ${LOG} 2>&1
|
||||
else
|
||||
printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - There is only one backing index (${INDEX}). Deleting ${DATASTREAM} data stream...\n" >> ${LOG}
|
||||
# Now that we've sorted the indices from oldest to newest, we need to check each index to see if it is assigned as the current write index for a data stream
|
||||
# To do so, we need to identify to which data stream this index is associated
|
||||
# We extract the data stream name using the pattern below
|
||||
DATASTREAM_PATTERN="logs-[a-zA-Z_.]+-[a-zA-Z_.]+"
|
||||
DATASTREAM=$(echo "${INDEX}" | grep -oE "$DATASTREAM_PATTERN")
|
||||
# We look up the data stream, and determine the write index. If there is only one backing index, we delete the entire data stream
|
||||
BACKING_INDICES=$(/usr/sbin/so-elasticsearch-query _data_stream/${DATASTREAM} | jq -r '.data_streams[0].indices | length')
|
||||
if [ "$BACKING_INDICES" -gt 1 ]; then
|
||||
CURRENT_WRITE_INDEX=$(/usr/sbin/so-elasticsearch-query _data_stream/$DATASTREAM | jq -r .data_streams[0].indices[-1].index_name)
|
||||
# We make sure we are not trying to delete a write index
|
||||
if [ "${INDEX}" != "${CURRENT_WRITE_INDEX}" ]; then
|
||||
# This should not be a write index, so we should be allowed to delete it
|
||||
printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - Deleting ${INDEX} index...\n" >> ${LOG}
|
||||
/usr/sbin/so-elasticsearch-query ${INDEX} -XDELETE >> ${LOG} 2>&1
|
||||
fi
|
||||
else
|
||||
printf "\n$(date) - Used disk space exceeds LOG_SIZE_LIMIT (${LOG_SIZE_LIMIT_GB} GB) - There is only one backing index (${INDEX}). Deleting ${DATASTREAM} data stream...\n" >> ${LOG}
|
||||
/usr/sbin/so-elasticsearch-query _data_stream/$DATASTREAM -XDELETE >> ${LOG} 2>&1
|
||||
fi
|
||||
fi
|
||||
if ! overlimit ; then
|
||||
exit
|
||||
|
||||
@@ -133,7 +133,7 @@ if [ ! -f $STATE_FILE_SUCCESS ]; then
|
||||
for i in $pattern; do
|
||||
TEMPLATE=${i::-14}
|
||||
COMPONENT_PATTERN=${TEMPLATE:3}
|
||||
MATCH=$(echo "$TEMPLATE" | grep -E "^so-logs-|^so-metrics" | grep -v osquery)
|
||||
MATCH=$(echo "$TEMPLATE" | grep -E "^so-logs-|^so-metrics" | grep -vE "detections|osquery")
|
||||
if [[ -n "$MATCH" && ! "$COMPONENT_LIST" =~ "$COMPONENT_PATTERN" ]]; then
|
||||
load_failures=$((load_failures+1))
|
||||
echo "Component template does not exist for $COMPONENT_PATTERN. The index template will not be loaded. Load failures: $load_failures"
|
||||
|
||||
@@ -9,11 +9,9 @@
|
||||
'so-influxdb',
|
||||
'so-kibana',
|
||||
'so-kratos',
|
||||
'so-mysql',
|
||||
'so-nginx',
|
||||
'so-redis',
|
||||
'so-soc',
|
||||
'so-soctopus',
|
||||
'so-strelka-coordinator',
|
||||
'so-strelka-gatekeeper',
|
||||
'so-strelka-frontend',
|
||||
@@ -29,14 +27,13 @@
|
||||
'so-elastic-fleet',
|
||||
'so-elastic-fleet-package-registry',
|
||||
'so-influxdb',
|
||||
'so-kafka',
|
||||
'so-kibana',
|
||||
'so-kratos',
|
||||
'so-logstash',
|
||||
'so-mysql',
|
||||
'so-nginx',
|
||||
'so-redis',
|
||||
'so-soc',
|
||||
'so-soctopus',
|
||||
'so-strelka-coordinator',
|
||||
'so-strelka-gatekeeper',
|
||||
'so-strelka-frontend',
|
||||
@@ -84,6 +81,7 @@
|
||||
{% set NODE_CONTAINERS = [
|
||||
'so-logstash',
|
||||
'so-redis',
|
||||
'so-kafka'
|
||||
] %}
|
||||
|
||||
{% elif GLOBALS.role == 'so-idh' %}
|
||||
|
||||
@@ -90,27 +90,27 @@ firewall:
|
||||
tcp:
|
||||
- 8086
|
||||
udp: []
|
||||
kafka_controller:
|
||||
tcp:
|
||||
- 9093
|
||||
udp: []
|
||||
kafka_data:
|
||||
tcp:
|
||||
- 9092
|
||||
udp: []
|
||||
kibana:
|
||||
tcp:
|
||||
- 5601
|
||||
udp: []
|
||||
localrules:
|
||||
tcp:
|
||||
- 7788
|
||||
udp: []
|
||||
mysql:
|
||||
tcp:
|
||||
- 3306
|
||||
- 7788
|
||||
udp: []
|
||||
nginx:
|
||||
tcp:
|
||||
- 80
|
||||
- 443
|
||||
udp: []
|
||||
playbook:
|
||||
tcp:
|
||||
- 3000
|
||||
udp: []
|
||||
redis:
|
||||
tcp:
|
||||
- 6379
|
||||
@@ -178,8 +178,6 @@ firewall:
|
||||
hostgroups:
|
||||
eval:
|
||||
portgroups:
|
||||
- playbook
|
||||
- mysql
|
||||
- kibana
|
||||
- redis
|
||||
- influxdb
|
||||
@@ -363,8 +361,6 @@ firewall:
|
||||
hostgroups:
|
||||
manager:
|
||||
portgroups:
|
||||
- playbook
|
||||
- mysql
|
||||
- kibana
|
||||
- redis
|
||||
- influxdb
|
||||
@@ -559,8 +555,6 @@ firewall:
|
||||
hostgroups:
|
||||
managersearch:
|
||||
portgroups:
|
||||
- playbook
|
||||
- mysql
|
||||
- kibana
|
||||
- redis
|
||||
- influxdb
|
||||
@@ -756,8 +750,6 @@ firewall:
|
||||
- all
|
||||
standalone:
|
||||
portgroups:
|
||||
- playbook
|
||||
- mysql
|
||||
- kibana
|
||||
- redis
|
||||
- influxdb
|
||||
@@ -769,7 +761,6 @@ firewall:
|
||||
- beats_5044
|
||||
- beats_5644
|
||||
- beats_5056
|
||||
- redis
|
||||
- elasticsearch_node
|
||||
- elastic_agent_control
|
||||
- elastic_agent_data
|
||||
@@ -1283,35 +1274,51 @@ firewall:
|
||||
chain:
|
||||
DOCKER-USER:
|
||||
hostgroups:
|
||||
desktop:
|
||||
portgroups:
|
||||
- elastic_agent_data
|
||||
fleet:
|
||||
portgroups:
|
||||
- beats_5056
|
||||
- elastic_agent_data
|
||||
idh:
|
||||
portgroups:
|
||||
- elastic_agent_data
|
||||
sensor:
|
||||
portgroups:
|
||||
- beats_5044
|
||||
- beats_5644
|
||||
- elastic_agent_data
|
||||
searchnode:
|
||||
portgroups:
|
||||
- redis
|
||||
- beats_5644
|
||||
- elastic_agent_data
|
||||
standalone:
|
||||
portgroups:
|
||||
- redis
|
||||
- elastic_agent_data
|
||||
manager:
|
||||
portgroups:
|
||||
- elastic_agent_data
|
||||
managersearch:
|
||||
portgroups:
|
||||
- redis
|
||||
- beats_5644
|
||||
- elastic_agent_data
|
||||
self:
|
||||
portgroups:
|
||||
- redis
|
||||
- beats_5644
|
||||
- elastic_agent_data
|
||||
beats_endpoint:
|
||||
portgroups:
|
||||
- beats_5044
|
||||
beats_endpoint_ssl:
|
||||
portgroups:
|
||||
- beats_5644
|
||||
elastic_agent_endpoint:
|
||||
portgroups:
|
||||
- elastic_agent_data
|
||||
endgame:
|
||||
portgroups:
|
||||
- endgame
|
||||
receiver:
|
||||
portgroups: []
|
||||
customhostgroup0:
|
||||
portgroups: []
|
||||
customhostgroup1:
|
||||
|
||||
@@ -18,4 +18,28 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{# Only add Kafka firewall items when Kafka enabled #}
|
||||
{% set role = GLOBALS.role.split('-')[1] %}
|
||||
|
||||
{% if GLOBALS.pipeline == 'KAFKA' and role in ['manager', 'managersearch', 'standalone'] %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups[role].portgroups.append('kafka_controller') %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.receiver.portgroups.append('kafka_controller') %}
|
||||
{% endif %}
|
||||
|
||||
{% if GLOBALS.pipeline == 'KAFKA' and role == 'receiver' %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.self.portgroups.append('kafka_controller') %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.standalone.portgroups.append('kafka_controller') %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.manager.portgroups.append('kafka_controller') %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.managersearch.portgroups.append('kafka_controller') %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups.receiver.portgroups.append('kafka_controller') %}
|
||||
{% endif %}
|
||||
|
||||
{% if GLOBALS.pipeline == 'KAFKA' and role in ['manager', 'managersearch', 'standalone', 'receiver'] %}
|
||||
{% for r in ['manager', 'managersearch', 'standalone', 'receiver', 'fleet', 'idh', 'sensor', 'searchnode','heavynode', 'elastic_agent_endpoint', 'desktop'] %}
|
||||
{% if FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups[r] is defined %}
|
||||
{% do FIREWALL_DEFAULT.firewall.role[role].chain["DOCKER-USER"].hostgroups[r].portgroups.append('kafka_data') %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% set FIREWALL_MERGED = salt['pillar.get']('firewall', FIREWALL_DEFAULT.firewall, merge=True) %}
|
||||
|
||||
@@ -7,6 +7,7 @@ firewall:
|
||||
multiline: True
|
||||
regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$
|
||||
regexFailureMessage: You must enter a valid IP address or CIDR.
|
||||
duplicates: True
|
||||
anywhere: &hostgroupsettingsadv
|
||||
description: List of IP or CIDR blocks to allow access to this hostgroup.
|
||||
forcedType: "[]string"
|
||||
@@ -15,6 +16,7 @@ firewall:
|
||||
advanced: True
|
||||
regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$
|
||||
regexFailureMessage: You must enter a valid IP address or CIDR.
|
||||
duplicates: True
|
||||
beats_endpoint: *hostgroupsettings
|
||||
beats_endpoint_ssl: *hostgroupsettings
|
||||
dockernet: &ROhostgroupsettingsadv
|
||||
@@ -53,6 +55,7 @@ firewall:
|
||||
multiline: True
|
||||
regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$
|
||||
regexFailureMessage: You must enter a valid IP address or CIDR.
|
||||
duplicates: True
|
||||
customhostgroup1: *customhostgroupsettings
|
||||
customhostgroup2: *customhostgroupsettings
|
||||
customhostgroup3: *customhostgroupsettings
|
||||
@@ -70,12 +73,14 @@ firewall:
|
||||
helpLink: firewall.html
|
||||
advanced: True
|
||||
multiline: True
|
||||
duplicates: True
|
||||
udp: &udpsettings
|
||||
description: List of UDP ports for this port group.
|
||||
forcedType: "[]string"
|
||||
helpLink: firewall.html
|
||||
advanced: True
|
||||
multiline: True
|
||||
duplicates: True
|
||||
agrules:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
@@ -115,21 +120,18 @@ firewall:
|
||||
influxdb:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
kafka:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
kibana:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
localrules:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
mysql:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
nginx:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
playbook:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
redis:
|
||||
tcp: *tcpsettings
|
||||
udp: *udpsettings
|
||||
@@ -193,6 +195,7 @@ firewall:
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: firewall.html
|
||||
duplicates: True
|
||||
sensor:
|
||||
portgroups: *portgroupsdocker
|
||||
searchnode:
|
||||
@@ -246,6 +249,7 @@ firewall:
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: firewall.html
|
||||
duplicates: True
|
||||
dockernet:
|
||||
portgroups: *portgroupshost
|
||||
localhost:
|
||||
@@ -938,7 +942,6 @@ firewall:
|
||||
portgroups: *portgroupshost
|
||||
customhostgroup9:
|
||||
portgroups: *portgroupshost
|
||||
|
||||
idh:
|
||||
chain:
|
||||
DOCKER-USER:
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
global:
|
||||
pcapengine: STENO
|
||||
pcapengine: STENO
|
||||
pipeline: REDIS
|
||||
@@ -28,7 +28,7 @@ global:
|
||||
description: Used for handling of authentication cookies.
|
||||
global: True
|
||||
airgap:
|
||||
description: Sets airgap mode.
|
||||
description: Airgapped systems do not have network connectivity to the internet. This setting represents how this grid was configured during initial setup. While it is technically possible to manually switch systems between airgap and non-airgap, there are some nuances and additional steps involved. For that reason this setting is marked read-only. Contact your support representative for guidance if there is a need to change this setting.
|
||||
global: True
|
||||
readonly: True
|
||||
imagerepo:
|
||||
@@ -36,9 +36,10 @@ global:
|
||||
global: True
|
||||
advanced: True
|
||||
pipeline:
|
||||
description: Sets which pipeline technology for events to use. Currently only Redis is supported.
|
||||
description: Sets which pipeline technology for events to use. Currently only Redis is fully supported. Kafka is experimental and requires a Security Onion Pro license.
|
||||
regex: ^(REDIS|KAFKA)$
|
||||
regexFailureMessage: You must enter either REDIS or KAFKA.
|
||||
global: True
|
||||
readonly: True
|
||||
advanced: True
|
||||
repo_host:
|
||||
description: Specify the host where operating system packages will be served from.
|
||||
|
||||
@@ -11,6 +11,8 @@ idh_sshd_selinux:
|
||||
- sel_type: ssh_port_t
|
||||
- prereq:
|
||||
- file: openssh_config
|
||||
- require:
|
||||
- pkg: python_selinux_mgmt_tools
|
||||
{% endif %}
|
||||
|
||||
openssh_config:
|
||||
|
||||
@@ -15,3 +15,9 @@ openssh:
|
||||
- enable: False
|
||||
- name: {{ openssh_map.service }}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.os_family == 'RedHat' %}
|
||||
python_selinux_mgmt_tools:
|
||||
pkg.installed:
|
||||
- name: policycoreutils-python-utils
|
||||
{% endif %}
|
||||
|
||||
@@ -33,6 +33,19 @@ idstools_sbin_jinja:
|
||||
- file_mode: 755
|
||||
- template: jinja
|
||||
|
||||
suricatacustomdirsfile:
|
||||
file.directory:
|
||||
- name: /nsm/rules/detect-suricata/custom_file
|
||||
- user: 939
|
||||
- group: 939
|
||||
- makedirs: True
|
||||
|
||||
suricatacustomdirsurl:
|
||||
file.directory:
|
||||
- name: /nsm/rules/detect-suricata/custom_temp
|
||||
- user: 939
|
||||
- group: 939
|
||||
|
||||
{% else %}
|
||||
|
||||
{{sls}}_state_not_allowed:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{%- from 'vars/globals.map.jinja' import GLOBALS -%}
|
||||
{%- from 'idstools/map.jinja' import IDSTOOLSMERGED -%}
|
||||
{%- from 'soc/merged.map.jinja' import SOCMERGED -%}
|
||||
--suricata-version=6.0
|
||||
--merged=/opt/so/rules/nids/suri/all.rules
|
||||
--output=/nsm/rules/detect-suricata/custom_temp
|
||||
--local=/opt/so/rules/nids/suri/local.rules
|
||||
{%- if GLOBALS.md_engine == "SURICATA" %}
|
||||
--local=/opt/so/rules/nids/suri/extraction.rules
|
||||
@@ -10,8 +12,12 @@
|
||||
--disable=/opt/so/idstools/etc/disable.conf
|
||||
--enable=/opt/so/idstools/etc/enable.conf
|
||||
--modify=/opt/so/idstools/etc/modify.conf
|
||||
{%- if IDSTOOLSMERGED.config.urls | length > 0 %}
|
||||
{%- for URL in IDSTOOLSMERGED.config.urls %}
|
||||
--url={{ URL }}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- if SOCMERGED.config.server.modules.suricataengine.customRulesets %}
|
||||
{%- for ruleset in SOCMERGED.config.server.modules.suricataengine.customRulesets %}
|
||||
{%- if 'url' in ruleset %}
|
||||
--url={{ ruleset.url }}
|
||||
{%- elif 'file' in ruleset %}
|
||||
--local={{ ruleset.file }}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
@@ -9,43 +9,53 @@ idstools:
|
||||
forcedType: string
|
||||
helpLink: rules.html
|
||||
ruleset:
|
||||
description: 'Defines the ruleset you want to run. Options are ETOPEN or ETPRO. WARNING! Changing the ruleset will remove all existing Suricata rules of the previous ruleset and their associated overrides. This removal cannot be undone.'
|
||||
description: 'Defines the ruleset you want to run. Options are ETOPEN or ETPRO. Once you have changed the ruleset here, you will need to wait for the rule update to take place (every 24 hours), or you can force the update by nagivating to Detections --> Options dropdown menu --> Suricata --> Full Update. WARNING! Changing the ruleset will remove all existing non-overlapping Suricata rules of the previous ruleset and their associated overrides. This removal cannot be undone.'
|
||||
global: True
|
||||
regex: ETPRO\b|ETOPEN\b
|
||||
helpLink: rules.html
|
||||
urls:
|
||||
description: This is a list of additional rule download locations.
|
||||
description: This is a list of additional rule download locations. This feature is currently disabled.
|
||||
global: True
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
readonly: True
|
||||
helpLink: rules.html
|
||||
sids:
|
||||
disabled:
|
||||
description: Contains the list of NIDS rules manually disabled across the grid. To disable a rule, add its Signature ID (SID) to the Current Grid Value box, one entry per line. To disable multiple rules, you can use regular expressions.
|
||||
description: Contains the list of NIDS rules (or regex patterns) disabled across the grid. This setting is readonly; Use the Detections screen to disable rules.
|
||||
global: True
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
regex: \d*|re:.*
|
||||
helpLink: managing-alerts.html
|
||||
readonlyUi: True
|
||||
advanced: true
|
||||
enabled:
|
||||
description: Contains the list of NIDS rules manually enabled across the grid. To enable a rule, add its Signature ID (SID) to the Current Grid Value box, one entry per line. To enable multiple rules, you can use regular expressions.
|
||||
description: Contains the list of NIDS rules (or regex patterns) enabled across the grid. This setting is readonly; Use the Detections screen to enable rules.
|
||||
global: True
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
regex: \d*|re:.*
|
||||
helpLink: managing-alerts.html
|
||||
readonlyUi: True
|
||||
advanced: true
|
||||
modify:
|
||||
description: Contains the list of NIDS rules that were modified from their default values. Entries must adhere to the following format - SID "REGEX_SEARCH_TERM" "REGEX_REPLACE_TERM"
|
||||
description: Contains the list of NIDS rules (SID "REGEX_SEARCH_TERM" "REGEX_REPLACE_TERM"). This setting is readonly; Use the Detections screen to modify rules.
|
||||
global: True
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: managing-alerts.html
|
||||
readonlyUi: True
|
||||
advanced: true
|
||||
rules:
|
||||
local__rules:
|
||||
description: Contains the list of custom NIDS rules applied to the grid. To add custom NIDS rules to the grid, enter one rule per line in the Current Grid Value box.
|
||||
description: Contains the list of custom NIDS rules applied to the grid. This setting is readonly; Use the Detections screen to adjust rules.
|
||||
file: True
|
||||
global: True
|
||||
advanced: True
|
||||
title: Local Rules
|
||||
helpLink: local-rules.html
|
||||
readonlyUi: True
|
||||
filters__rules:
|
||||
description: If you are using Suricata for metadata, then you can set custom filters for that metadata here.
|
||||
file: True
|
||||
|
||||
@@ -26,8 +26,6 @@ if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
|
||||
docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force
|
||||
{%- elif IDSTOOLSMERGED.config.ruleset == 'ETPRO' %}
|
||||
docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force --etpro={{ IDSTOOLSMERGED.config.oinkcode }}
|
||||
{%- elif IDSTOOLSMERGED.config.ruleset == 'TALOS' %}
|
||||
docker exec so-idstools idstools-rulecat -v --suricata-version 6.0 -o /nsm/rules/suricata/ --merged=/nsm/rules/suricata/emerging-all.rules --force --url=https://www.snort.org/rules/snortrules-snapshot-2983.tar.gz?oinkcode={{ IDSTOOLSMERGED.config.oinkcode }}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
91
salt/kafka/config.map.jinja
Normal file
91
salt/kafka/config.map.jinja
Normal file
@@ -0,0 +1,91 @@
|
||||
{# 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 'kafka/map.jinja' import KAFKAMERGED %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
{% set KAFKA_NODES_PILLAR = salt['pillar.get']('kafka:nodes') %}
|
||||
{% set KAFKA_PASSWORD = salt['pillar.get']('kafka:password') %}
|
||||
|
||||
{# Create list of KRaft controllers #}
|
||||
{% set controllers = [] %}
|
||||
|
||||
{# Check for Kafka nodes with controller in process_x_roles #}
|
||||
{% for node in KAFKA_NODES_PILLAR %}
|
||||
{% if 'controller' in KAFKA_NODES_PILLAR[node].role %}
|
||||
{% do controllers.append(KAFKA_NODES_PILLAR[node].nodeid ~ "@" ~ node ~ ":9093") %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% set kafka_controller_quorum_voters = ','.join(controllers) %}
|
||||
|
||||
{# By default all Kafka eligible nodes are given the role of broker, except for
|
||||
grid MANAGER (broker,controller) until overridden through SOC UI #}
|
||||
{% set node_type = salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname + ':role') %}
|
||||
|
||||
{# Generate server.properties for 'broker' , 'controller', 'broker,controller' node types
|
||||
anything above this line is a configuration needed for ALL Kafka nodes #}
|
||||
{% if node_type == 'broker' %}
|
||||
{% do KAFKAMERGED.config.broker.update({'advertised_x_listeners': 'BROKER://'+ GLOBALS.node_ip +':9092' }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'controller_x_quorum_x_voters': kafka_controller_quorum_voters }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'node_x_id': salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname +':nodeid') }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %}
|
||||
|
||||
{# Nodes with only the 'broker' role need to have the below settings for communicating with controller nodes #}
|
||||
{% do KAFKAMERGED.config.broker.update({'controller_x_listener_x_names': KAFKAMERGED.config.controller.controller_x_listener_x_names }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({
|
||||
'listener_x_security_x_protocol_x_map': KAFKAMERGED.config.broker.listener_x_security_x_protocol_x_map
|
||||
+ ',' + KAFKAMERGED.config.controller.listener_x_security_x_protocol_x_map })
|
||||
%}
|
||||
{% endif %}
|
||||
|
||||
{% if node_type == 'controller' %}
|
||||
{% do KAFKAMERGED.config.controller.update({'controller_x_quorum_x_voters': kafka_controller_quorum_voters }) %}
|
||||
{% do KAFKAMERGED.config.controller.update({'node_x_id': salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname +':nodeid') }) %}
|
||||
{% do KAFKAMERGED.config.controller.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{# Kafka nodes of this type are not recommended for use outside of development / testing. #}
|
||||
{% if node_type == 'broker,controller' %}
|
||||
{% do KAFKAMERGED.config.broker.update({'advertised_x_listeners': 'BROKER://'+ GLOBALS.node_ip +':9092' }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'controller_x_listener_x_names': KAFKAMERGED.config.controller.controller_x_listener_x_names }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'controller_x_quorum_x_voters': kafka_controller_quorum_voters }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'node_x_id': salt['pillar.get']('kafka:nodes:'+ GLOBALS.hostname +':nodeid') }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'process_x_roles': 'broker,controller' }) %}
|
||||
{% do KAFKAMERGED.config.broker.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %}
|
||||
|
||||
{% do KAFKAMERGED.config.broker.update({
|
||||
'listeners': KAFKAMERGED.config.broker.listeners + ',' + KAFKAMERGED.config.controller.listeners })
|
||||
%}
|
||||
|
||||
{% do KAFKAMERGED.config.broker.update({
|
||||
'listener_x_security_x_protocol_x_map': KAFKAMERGED.config.broker.listener_x_security_x_protocol_x_map
|
||||
+ ',' + KAFKAMERGED.config.controller.listener_x_security_x_protocol_x_map })
|
||||
%}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{# If a password other than PLACEHOLDER isn't set remove it from the server.properties #}
|
||||
{% if KAFKAMERGED.config.broker.ssl_x_truststore_x_password == 'PLACEHOLDER' %}
|
||||
{% do KAFKAMERGED.config.broker.pop('ssl_x_truststore_x_password') %}
|
||||
{% endif %}
|
||||
|
||||
{% if KAFKAMERGED.config.controller.ssl_x_truststore_x_password == 'PLACEHOLDER' %}
|
||||
{% do KAFKAMERGED.config.controller.pop('ssl_x_truststore_x_password') %}
|
||||
{% endif %}
|
||||
|
||||
{# Client properties stuff #}
|
||||
{% if KAFKAMERGED.config.client.ssl_x_truststore_x_password == 'PLACEHOLDER' %}
|
||||
{% do KAFKAMERGED.config.client.pop('ssl_x_truststore_x_password') %}
|
||||
{% endif %}
|
||||
{% do KAFKAMERGED.config.client.update({'ssl_x_keystore_x_password': KAFKA_PASSWORD }) %}
|
||||
|
||||
{% if 'broker' in node_type %}
|
||||
{% set KAFKACONFIG = KAFKAMERGED.config.broker %}
|
||||
{% else %}
|
||||
{% set KAFKACONFIG = KAFKAMERGED.config.controller %}
|
||||
{% endif %}
|
||||
|
||||
{% set KAFKACLIENT = KAFKAMERGED.config.client %}
|
||||
69
salt/kafka/config.sls
Normal file
69
salt/kafka/config.sls
Normal file
@@ -0,0 +1,69 @@
|
||||
# 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.split('.')[0] in allowed_states %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
include:
|
||||
- ssl
|
||||
|
||||
kafka_group:
|
||||
group.present:
|
||||
- name: kafka
|
||||
- gid: 960
|
||||
|
||||
kafka:
|
||||
user.present:
|
||||
- uid: 960
|
||||
- gid: 960
|
||||
|
||||
kafka_sbin_tools:
|
||||
file.recurse:
|
||||
- name: /usr/sbin
|
||||
- source: salt://kafka/tools/sbin
|
||||
- user: 960
|
||||
- group: 960
|
||||
- file_mode: 755
|
||||
|
||||
kafka_log_dir:
|
||||
file.directory:
|
||||
- name: /opt/so/log/kafka
|
||||
- user: 960
|
||||
- group: 960
|
||||
- makedirs: True
|
||||
|
||||
kafka_data_dir:
|
||||
file.directory:
|
||||
- name: /nsm/kafka/data
|
||||
- user: 960
|
||||
- group: 960
|
||||
- makedirs: True
|
||||
|
||||
{% for sc in ['server', 'client'] %}
|
||||
kafka_kraft_{{sc}}_properties:
|
||||
file.managed:
|
||||
- source: salt://kafka/etc/{{sc}}.properties.jinja
|
||||
- name: /opt/so/conf/kafka/{{sc}}.properties
|
||||
- template: jinja
|
||||
- user: 960
|
||||
- group: 960
|
||||
- makedirs: True
|
||||
- show_changes: False
|
||||
{% endfor %}
|
||||
|
||||
reset_quorum_on_changes:
|
||||
cmd.run:
|
||||
- name: rm -f /nsm/kafka/data/__cluster_metadata-0/quorum-state
|
||||
- onchanges:
|
||||
- file: /opt/so/conf/kafka/server.properties
|
||||
|
||||
{% else %}
|
||||
|
||||
{{sls}}_state_not_allowed:
|
||||
test.fail_without_changes:
|
||||
- name: {{sls}}_state_not_allowed
|
||||
|
||||
{% endif %}
|
||||
62
salt/kafka/defaults.yaml
Normal file
62
salt/kafka/defaults.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
kafka:
|
||||
enabled: False
|
||||
cluster_id:
|
||||
password:
|
||||
controllers:
|
||||
reset:
|
||||
config:
|
||||
broker:
|
||||
advertised_x_listeners:
|
||||
auto_x_create_x_topics_x_enable: true
|
||||
controller_x_quorum_x_voters:
|
||||
default_x_replication_x_factor: 1
|
||||
inter_x_broker_x_listener_x_name: BROKER
|
||||
listeners: BROKER://0.0.0.0:9092
|
||||
listener_x_security_x_protocol_x_map: BROKER:SSL
|
||||
log_x_dirs: /nsm/kafka/data
|
||||
log_x_retention_x_check_x_interval_x_ms: 300000
|
||||
log_x_retention_x_hours: 168
|
||||
log_x_segment_x_bytes: 1073741824
|
||||
node_x_id:
|
||||
num_x_io_x_threads: 8
|
||||
num_x_network_x_threads: 3
|
||||
num_x_partitions: 3
|
||||
num_x_recovery_x_threads_x_per_x_data_x_dir: 1
|
||||
offsets_x_topic_x_replication_x_factor: 1
|
||||
process_x_roles: broker
|
||||
socket_x_receive_x_buffer_x_bytes: 102400
|
||||
socket_x_request_x_max_x_bytes: 104857600
|
||||
socket_x_send_x_buffer_x_bytes: 102400
|
||||
ssl_x_keystore_x_location: /etc/pki/kafka.p12
|
||||
ssl_x_keystore_x_type: PKCS12
|
||||
ssl_x_keystore_x_password:
|
||||
ssl_x_truststore_x_location: /etc/pki/java/sos/cacerts
|
||||
ssl_x_truststore_x_password: PLACEHOLDER
|
||||
ssl_x_truststore_x_type: PEM
|
||||
transaction_x_state_x_log_x_min_x_isr: 1
|
||||
transaction_x_state_x_log_x_replication_x_factor: 1
|
||||
client:
|
||||
security_x_protocol: SSL
|
||||
ssl_x_truststore_x_location: /etc/pki/java/sos/cacerts
|
||||
ssl_x_truststore_x_password: PLACEHOLDER
|
||||
ssl_x_truststore_x_type: PEM
|
||||
ssl_x_keystore_x_location: /etc/pki/kafka.p12
|
||||
ssl_x_keystore_x_type: PKCS12
|
||||
ssl_x_keystore_x_password:
|
||||
controller:
|
||||
controller_x_listener_x_names: CONTROLLER
|
||||
controller_x_quorum_x_voters:
|
||||
listeners: CONTROLLER://0.0.0.0:9093
|
||||
listener_x_security_x_protocol_x_map: CONTROLLER:SSL
|
||||
log_x_dirs: /nsm/kafka/data
|
||||
log_x_retention_x_check_x_interval_x_ms: 300000
|
||||
log_x_retention_x_hours: 168
|
||||
log_x_segment_x_bytes: 1073741824
|
||||
node_x_id:
|
||||
process_x_roles: controller
|
||||
ssl_x_keystore_x_location: /etc/pki/kafka.p12
|
||||
ssl_x_keystore_x_type: PKCS12
|
||||
ssl_x_keystore_x_password:
|
||||
ssl_x_truststore_x_location: /etc/pki/java/sos/cacerts
|
||||
ssl_x_truststore_x_password: PLACEHOLDER
|
||||
ssl_x_truststore_x_type: PEM
|
||||
25
salt/kafka/disabled.sls
Normal file
25
salt/kafka/disabled.sls
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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 'kafka/map.jinja' import KAFKAMERGED %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
so-kafka:
|
||||
docker_container.absent:
|
||||
- force: True
|
||||
|
||||
so-kafka_so-status.disabled:
|
||||
file.comment:
|
||||
- name: /opt/so/conf/so-status/so-status.conf
|
||||
- regex: ^so-kafka$
|
||||
- onlyif: grep -q '^so-kafka$' /opt/so/conf/so-status/so-status.conf
|
||||
|
||||
{% if GLOBALS.is_manager and KAFKAMERGED.enabled or GLOBALS.pipeline == "KAFKA" %}
|
||||
ensure_default_pipeline:
|
||||
cmd.run:
|
||||
- name: |
|
||||
/usr/sbin/so-yaml.py replace /opt/so/saltstack/local/pillar/kafka/soc_kafka.sls kafka.enabled False;
|
||||
/usr/sbin/so-yaml.py replace /opt/so/saltstack/local/pillar/global/soc_global.sls global.pipeline REDIS
|
||||
{% endif %}
|
||||
86
salt/kafka/enabled.sls
Normal file
86
salt/kafka/enabled.sls
Normal file
@@ -0,0 +1,86 @@
|
||||
# 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.
|
||||
#
|
||||
# Note: Per the Elastic License 2.0, the second limitation states:
|
||||
#
|
||||
# "You may not move, change, disable, or circumvent the license key functionality
|
||||
# in the software, and you may not remove or obscure any functionality in the
|
||||
# software that is protected by the license key."
|
||||
|
||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||
{% if sls.split('.')[0] in allowed_states %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
{% from 'docker/docker.map.jinja' import DOCKER %}
|
||||
{% set KAFKANODES = salt['pillar.get']('kafka:nodes') %}
|
||||
{% if 'gmd' in salt['pillar.get']('features', []) %}
|
||||
|
||||
include:
|
||||
- elasticsearch.ca
|
||||
- kafka.sostatus
|
||||
- kafka.config
|
||||
- kafka.storage
|
||||
|
||||
so-kafka:
|
||||
docker_container.running:
|
||||
- image: {{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-kafka:{{ GLOBALS.so_version }}
|
||||
- hostname: so-kafka
|
||||
- name: so-kafka
|
||||
- networks:
|
||||
- sobridge:
|
||||
- ipv4_address: {{ DOCKER.containers['so-kafka'].ip }}
|
||||
- user: kafka
|
||||
- environment:
|
||||
KAFKA_HEAP_OPTS: -Xmx2G -Xms1G
|
||||
KAFKA_OPTS: -javaagent:/opt/jolokia/agents/jolokia-agent-jvm-javaagent.jar=port=8778,host={{ DOCKER.containers['so-kafka'].ip }},policyLocation=file:/opt/jolokia/jolokia.xml
|
||||
- extra_hosts:
|
||||
{% for node in KAFKANODES %}
|
||||
- {{ node }}:{{ KAFKANODES[node].ip }}
|
||||
{% endfor %}
|
||||
{% if DOCKER.containers['so-kafka'].extra_hosts %}
|
||||
{% for XTRAHOST in DOCKER.containers['so-kafka'].extra_hosts %}
|
||||
- {{ XTRAHOST }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
- port_bindings:
|
||||
{% for BINDING in DOCKER.containers['so-kafka'].port_bindings %}
|
||||
- {{ BINDING }}
|
||||
{% endfor %}
|
||||
- binds:
|
||||
- /etc/pki/kafka.p12:/etc/pki/kafka.p12:ro
|
||||
- /etc/pki/tls/certs/intca.crt:/etc/pki/java/sos/cacerts:ro
|
||||
- /nsm/kafka/data/:/nsm/kafka/data/:rw
|
||||
- /opt/so/log/kafka:/opt/kafka/logs/:rw
|
||||
- /opt/so/conf/kafka/server.properties:/opt/kafka/config/kraft/server.properties:ro
|
||||
- /opt/so/conf/kafka/client.properties:/opt/kafka/config/kraft/client.properties
|
||||
- watch:
|
||||
{% for sc in ['server', 'client'] %}
|
||||
- file: kafka_kraft_{{sc}}_properties
|
||||
{% endfor %}
|
||||
|
||||
delete_so-kafka_so-status.disabled:
|
||||
file.uncomment:
|
||||
- name: /opt/so/conf/so-status/so-status.conf
|
||||
- regex: ^so-kafka$
|
||||
|
||||
{% else %}
|
||||
|
||||
{{sls}}_no_license_detected:
|
||||
test.fail_without_changes:
|
||||
- name: {{sls}}_no_license_detected
|
||||
- comment:
|
||||
- "Kafka for Guaranteed Message Delivery is a feature supported only for customers with a valid license.
|
||||
Contact Security Onion Solutions, LLC via our website at https://securityonionsolutions.com
|
||||
for more information about purchasing a license to enable this feature."
|
||||
include:
|
||||
- kafka.disabled
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{{sls}}_state_not_allowed:
|
||||
test.fail_without_changes:
|
||||
- name: {{sls}}_state_not_allowed
|
||||
|
||||
{% endif %}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user