Compare commits
737 Commits
2.4.160-20
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f3b92887b | ||
|
|
d15678f638 | ||
|
|
93c29bc1da | ||
|
|
56263675f6 | ||
|
|
1599e69851 | ||
|
|
5ae7e27ace | ||
|
|
945d2abeed | ||
|
|
68eb2d3ceb | ||
|
|
595f965183 | ||
|
|
834d18b77c | ||
|
|
4849da1c11 | ||
|
|
fbbddc2aaf | ||
|
|
4b24500b79 | ||
|
|
f6a765addc | ||
|
|
8b56c0a744 | ||
|
|
b31d38e734 | ||
|
|
b1db4137d0 | ||
|
|
44ef164713 | ||
|
|
43f7dce297 | ||
|
|
4e4a4686f1 | ||
|
|
b5f44e48ab | ||
|
|
a44448519b | ||
|
|
6245ee9a5b | ||
|
|
49ca970076 | ||
|
|
f49fb7cbae | ||
|
|
7692c9be53 | ||
|
|
25ef12cdc5 | ||
|
|
2967adca90 | ||
|
|
d198458366 | ||
|
|
9e98b409a5 | ||
|
|
ba8f729976 | ||
|
|
5b67795c23 | ||
|
|
483bf60ae3 | ||
|
|
1a9350f60b | ||
|
|
f4afda0975 | ||
|
|
137372337c | ||
|
|
1521532c60 | ||
|
|
ada32967dc | ||
|
|
d5d2b5fbc7 | ||
|
|
84d6fcb752 | ||
|
|
de9e9a2716 | ||
|
|
cec6cff19d | ||
|
|
7311d6480c | ||
|
|
f967c8e362 | ||
|
|
cfad6414d2 | ||
|
|
0fdaed9cf7 | ||
|
|
1dc88781f1 | ||
|
|
0cfb8b0816 | ||
|
|
c0968d3843 | ||
|
|
3b133e87cd | ||
|
|
fee9b61ce9 | ||
|
|
57612c69fe | ||
|
|
94accb0e8c | ||
|
|
3b8d1d470e | ||
|
|
c624a44b0e | ||
|
|
bc509a0aa9 | ||
|
|
ee0ef3217f | ||
|
|
18e319cbe3 | ||
|
|
3316e1261d | ||
|
|
b7cf44466c | ||
|
|
e321aa52a5 | ||
|
|
07df045e79 | ||
|
|
7b11ddb032 | ||
|
|
ac4428940e | ||
|
|
a9457d5f53 | ||
|
|
3672701dde | ||
|
|
07ed2cb3da | ||
|
|
3839e52401 | ||
|
|
b005a10a8e | ||
|
|
752ff5917f | ||
|
|
815e5d53a6 | ||
|
|
a967db8152 | ||
|
|
7835cb6a7a | ||
|
|
07b92eef9e | ||
|
|
8855619453 | ||
|
|
7763218b71 | ||
|
|
29f12fac90 | ||
|
|
1a9f8f0bc2 | ||
|
|
3e5f354d8b | ||
|
|
a1b76d2cd3 | ||
|
|
43e402fad4 | ||
|
|
170b408feb | ||
|
|
e55725cca4 | ||
|
|
2b9f6b26d8 | ||
|
|
f10b67599e | ||
|
|
ea03613df3 | ||
|
|
8ffb6b9e1c | ||
|
|
ffadd4aa42 | ||
|
|
78ccea12b1 | ||
|
|
8bef5a84f7 | ||
|
|
679775a7d0 | ||
|
|
3f5f93059e | ||
|
|
d2ae8f81e1 | ||
|
|
fcc369d4b9 | ||
|
|
9bb28fd0b5 | ||
|
|
93c5e6a9e8 | ||
|
|
6a7e756a37 | ||
|
|
f6b9dec2ae | ||
|
|
37386057d9 | ||
|
|
800945c3b6 | ||
|
|
b56c0c5e64 | ||
|
|
01b986cd50 | ||
|
|
3e862151f3 | ||
|
|
15b3982930 | ||
|
|
3d687f0404 | ||
|
|
e74c2fa1b0 | ||
|
|
ffc91393e7 | ||
|
|
d0ab2db312 | ||
|
|
4906068c7f | ||
|
|
ef8eece53b | ||
|
|
660a50c08d | ||
|
|
5d326a3c32 | ||
|
|
2a907d3de3 | ||
|
|
33134b1814 | ||
|
|
b0962da758 | ||
|
|
8148fd9e56 | ||
|
|
1ee332b55b | ||
|
|
873632ec4f | ||
|
|
f8068d7975 | ||
|
|
a79ebea5c3 | ||
|
|
2fdc3874ca | ||
|
|
7f52c2015d | ||
|
|
548e1e6937 | ||
|
|
c949101d0f | ||
|
|
7c1f19b91f | ||
|
|
598d6b025e | ||
|
|
4d0d0714a5 | ||
|
|
cb0c078955 | ||
|
|
aa426244bf | ||
|
|
97b2ae8d82 | ||
|
|
7047125759 | ||
|
|
43f73abd4d | ||
|
|
51a8684850 | ||
|
|
b3c5239787 | ||
|
|
0f562279ee | ||
|
|
834f45c0f2 | ||
|
|
d4cf9efeca | ||
|
|
c620983b4a | ||
|
|
ed19c139ea | ||
|
|
af85c6261b | ||
|
|
e9f58269cd | ||
|
|
208c3d96e9 | ||
|
|
1e888a5d9e | ||
|
|
f7ae8d449e | ||
|
|
195274bb11 | ||
|
|
a0ac1d2274 | ||
|
|
3dd39c7f59 | ||
|
|
ba846bbf35 | ||
|
|
0baf8e9471 | ||
|
|
e30fec7af0 | ||
|
|
884f5cd3a6 | ||
|
|
11babd2f1c | ||
|
|
b440ab5c02 | ||
|
|
91d667c3ad | ||
|
|
f04c01b28c | ||
|
|
71ab8ddf1d | ||
|
|
f1f79d55dc | ||
|
|
db1bd16758 | ||
|
|
ef73834d58 | ||
|
|
3891548d6d | ||
|
|
9d6ed8b9b2 | ||
|
|
ef92815a08 | ||
|
|
19b5cdcb0e | ||
|
|
272b345892 | ||
|
|
7fad9d60ef | ||
|
|
46fc62b8dc | ||
|
|
ca9a93a4b0 | ||
|
|
aa2e18fca9 | ||
|
|
7e4ce7b81d | ||
|
|
e5c0058dd1 | ||
|
|
07c5b541a3 | ||
|
|
b756b8ea32 | ||
|
|
5b46e57ae1 | ||
|
|
924009afb8 | ||
|
|
8f5bacc510 | ||
|
|
d5e48a7eca | ||
|
|
6346a92f0f | ||
|
|
13a566a9a2 | ||
|
|
063c6599d8 | ||
|
|
9fb315c99d | ||
|
|
6e0891e586 | ||
|
|
3a96d59899 | ||
|
|
5fa945956e | ||
|
|
b0aab96cf5 | ||
|
|
11def72790 | ||
|
|
2ca2724a4c | ||
|
|
884883a225 | ||
|
|
5c8ba3af65 | ||
|
|
4b5d314adf | ||
|
|
6e637f559c | ||
|
|
cc5304e9f7 | ||
|
|
002403055d | ||
|
|
b80b80e825 | ||
|
|
c539d53a02 | ||
|
|
3a22978c2b | ||
|
|
5b1461e9a1 | ||
|
|
69f889dbd9 | ||
|
|
aefe1cceb8 | ||
|
|
b7e97eceb3 | ||
|
|
450e02e874 | ||
|
|
09bebf08d6 | ||
|
|
4dd54cea6c | ||
|
|
e07f4bd0ed | ||
|
|
6adb586bb4 | ||
|
|
2f99821736 | ||
|
|
db27c22158 | ||
|
|
2ff284fc7f | ||
|
|
5d0a3ef205 | ||
|
|
ac9c10dd3a | ||
|
|
d4d67b545d | ||
|
|
2dced35800 | ||
|
|
c2a04a79c5 | ||
|
|
d43346a084 | ||
|
|
0c4a27d120 | ||
|
|
b4530ffffe | ||
|
|
d12aa0ed56 | ||
|
|
17bcf50ccb | ||
|
|
48401f6a3f | ||
|
|
a96825f43e | ||
|
|
2d48ae7bca | ||
|
|
0ff519ed2f | ||
|
|
127533492f | ||
|
|
7d4b4a8bd4 | ||
|
|
e9fa84d71b | ||
|
|
cd8cf4a1ac | ||
|
|
9718e61a6a | ||
|
|
22ec638e85 | ||
|
|
7b0c22f967 | ||
|
|
672cab858e | ||
|
|
29312d595b | ||
|
|
b54f2e8752 | ||
|
|
1470e120ef | ||
|
|
2c747ec837 | ||
|
|
8cb5cd5fee | ||
|
|
a4bae77973 | ||
|
|
96a568f57f | ||
|
|
7dcdcc18a5 | ||
|
|
10fc8de9f9 | ||
|
|
3482df5ee1 | ||
|
|
9ea3d6bb1f | ||
|
|
a67a254edc | ||
|
|
08a5a9ab31 | ||
|
|
e3d32c7871 | ||
|
|
20d6ce1ce9 | ||
|
|
bd114eb1c4 | ||
|
|
55c6fc422b | ||
|
|
5d060f9832 | ||
|
|
edcbfd17f5 | ||
|
|
ff4850d9ce | ||
|
|
3e1a5b6329 | ||
|
|
b1709f3ea3 | ||
|
|
76a73ea35c | ||
|
|
991a6ec43c | ||
|
|
e2c0607249 | ||
|
|
82c61e6bc9 | ||
|
|
37aa779095 | ||
|
|
9e631ad63d | ||
|
|
fe6a55b58e | ||
|
|
87cebedc85 | ||
|
|
e66c995b1f | ||
|
|
e8a8f65ddc | ||
|
|
a7a15117f0 | ||
|
|
865ba4264b | ||
|
|
6985b0ab27 | ||
|
|
6e4912f759 | ||
|
|
b0d934daf7 | ||
|
|
8e50868abd | ||
|
|
aa08803f03 | ||
|
|
bb346d531d | ||
|
|
6c057d0b0a | ||
|
|
47e43e53d9 | ||
|
|
a8456a4d65 | ||
|
|
98a1fb96c2 | ||
|
|
874bbd2580 | ||
|
|
90dedbb841 | ||
|
|
df5dd5fe28 | ||
|
|
d5ab455485 | ||
|
|
20b79b7ab0 | ||
|
|
56019f48ca | ||
|
|
d7dd2d2ef8 | ||
|
|
3d431eaba9 | ||
|
|
f85fb5ecf9 | ||
|
|
1716cb0297 | ||
|
|
0ec366f075 | ||
|
|
e9b9e128c6 | ||
|
|
ef15de130a | ||
|
|
e975ee0a8e | ||
|
|
da94ddca13 | ||
|
|
6e94751c65 | ||
|
|
d48d473f43 | ||
|
|
cff5a83ad5 | ||
|
|
225b7e359c | ||
|
|
9a616caf53 | ||
|
|
0aab268801 | ||
|
|
0bb7f5c5e3 | ||
|
|
4aff1f0fdb | ||
|
|
35ca08ea88 | ||
|
|
7b05627d5c | ||
|
|
e3c1b6dbba | ||
|
|
f0c3b876a9 | ||
|
|
531423f49a | ||
|
|
dfad5a748c | ||
|
|
819b39c0bb | ||
|
|
0dd2e51e83 | ||
|
|
f7730741c2 | ||
|
|
cb2d6b7876 | ||
|
|
93ca7548f8 | ||
|
|
9cbbed1038 | ||
|
|
967fd30bb1 | ||
|
|
6c8c8a2d8e | ||
|
|
8bb3b22993 | ||
|
|
5b6182c003 | ||
|
|
69c5a9dd90 | ||
|
|
86c31c129a | ||
|
|
483a9d477f | ||
|
|
d7f60a0e58 | ||
|
|
f06443f3dd | ||
|
|
fe798138e3 | ||
|
|
e9bb60dedb | ||
|
|
992ced685f | ||
|
|
592bbf4217 | ||
|
|
eacf6238d8 | ||
|
|
0a7ada314d | ||
|
|
c8edb43748 | ||
|
|
f112663a76 | ||
|
|
a1b2c28a42 | ||
|
|
4311d5135b | ||
|
|
2b2d39c869 | ||
|
|
fcc0534572 | ||
|
|
a3f9859fdb | ||
|
|
cf5d5e4fc2 | ||
|
|
7184b9cb25 | ||
|
|
544d716c19 | ||
|
|
f1f611cede | ||
|
|
5988c12773 | ||
|
|
dc5f4ef942 | ||
|
|
91e15c233d | ||
|
|
42cde0b6f0 | ||
|
|
1279997ca9 | ||
|
|
93e0ec8696 | ||
|
|
8f0547beda | ||
|
|
6cb4c02200 | ||
|
|
8c54c44690 | ||
|
|
5d72f8d55a | ||
|
|
768225ff5a | ||
|
|
571ac4edec | ||
|
|
86cfac4983 | ||
|
|
e00a80feb4 | ||
|
|
e8e39a7105 | ||
|
|
13ea44db95 | ||
|
|
7f4f1397e7 | ||
|
|
5db3e22363 | ||
|
|
6fe2857ba5 | ||
|
|
56b0bae089 | ||
|
|
f947e501cb | ||
|
|
ff8bbc399f | ||
|
|
80226a27cc | ||
|
|
266207cc18 | ||
|
|
5255c120c5 | ||
|
|
d44f8e495b | ||
|
|
13a8cbdabb | ||
|
|
c3c505f8ff | ||
|
|
7ea0aa87e4 | ||
|
|
82317656b1 | ||
|
|
1cc5961c07 | ||
|
|
220e998b45 | ||
|
|
16cd1080be | ||
|
|
5db643e53b | ||
|
|
745cdef538 | ||
|
|
aa767b8dc1 | ||
|
|
45cdd16308 | ||
|
|
1bb76bb251 | ||
|
|
4251331bd4 | ||
|
|
124d56f4b9 | ||
|
|
02821b97ad | ||
|
|
9a50832669 | ||
|
|
cffbe757a6 | ||
|
|
14ff5670f7 | ||
|
|
92e238aa10 | ||
|
|
8462e66873 | ||
|
|
2763b5846c | ||
|
|
dd4c34397d | ||
|
|
a796fa2ff7 | ||
|
|
268253ce14 | ||
|
|
6a2f886fcc | ||
|
|
63915b0486 | ||
|
|
ce7b16a230 | ||
|
|
a4f5e7b2a6 | ||
|
|
cfbbc3a1a3 | ||
|
|
11a7f051a6 | ||
|
|
cb06269b1a | ||
|
|
d026414bcf | ||
|
|
e15ca408e7 | ||
|
|
0e2753393b | ||
|
|
b06e9e8477 | ||
|
|
45892400cb | ||
|
|
1f0c984b98 | ||
|
|
6d814d3909 | ||
|
|
9ea59355d5 | ||
|
|
c1287a61af | ||
|
|
e44c94c56b | ||
|
|
ec0cf71c3f | ||
|
|
73adc571de | ||
|
|
62c1bb2c0c | ||
|
|
692ec05b2d | ||
|
|
00078fd9e5 | ||
|
|
13c8fb0004 | ||
|
|
920b16e494 | ||
|
|
d98c57510a | ||
|
|
58aa730437 | ||
|
|
f36da68009 | ||
|
|
0091675ab6 | ||
|
|
83d25a97d3 | ||
|
|
e536568c8a | ||
|
|
a00eb9071f | ||
|
|
c39cd9a290 | ||
|
|
cb5483d401 | ||
|
|
fab0d17314 | ||
|
|
465e6c4605 | ||
|
|
a119d6a842 | ||
|
|
be8ce43b74 | ||
|
|
b2a33d4800 | ||
|
|
78fac49e66 | ||
|
|
ca08989404 | ||
|
|
4ed757916e | ||
|
|
676c543178 | ||
|
|
aa2eab5738 | ||
|
|
fe21b8bc17 | ||
|
|
33a478ff59 | ||
|
|
62fee1f420 | ||
|
|
2ada4712bc | ||
|
|
fad6c46e7c | ||
|
|
6f27c1b21e | ||
|
|
0afb20ffa8 | ||
|
|
40688a6076 | ||
|
|
9431bf1c2a | ||
|
|
9f5e75b302 | ||
|
|
3f62cddc3b | ||
|
|
085420997c | ||
|
|
723e145eeb | ||
|
|
0a1d0d35c8 | ||
|
|
9ee96f2280 | ||
|
|
3871268c19 | ||
|
|
bc620b7def | ||
|
|
5950771003 | ||
|
|
7c8ce7899b | ||
|
|
08d5f494ab | ||
|
|
13827f3be5 | ||
|
|
3a64362887 | ||
|
|
e77a60bcbf | ||
|
|
e560edf493 | ||
|
|
7caf827b77 | ||
|
|
f40ccb7eff | ||
|
|
e0cd550820 | ||
|
|
4e5106c863 | ||
|
|
5a107c63b8 | ||
|
|
8a9a13865c | ||
|
|
9cd6273beb | ||
|
|
724b26228c | ||
|
|
3c054fd133 | ||
|
|
24ee38369f | ||
|
|
0bbe642d20 | ||
|
|
8e17c23659 | ||
|
|
92170941f0 | ||
|
|
10ac789fbf | ||
|
|
db58a35562 | ||
|
|
1ad7a0db59 | ||
|
|
af626fe3a1 | ||
|
|
073f5ed789 | ||
|
|
bbcefea417 | ||
|
|
73c282595d | ||
|
|
07a53db09a | ||
|
|
80e50fa7b4 | ||
|
|
84d333e915 | ||
|
|
ae582caa55 | ||
|
|
264ae2b9ac | ||
|
|
b522c9eea4 | ||
|
|
51cc047933 | ||
|
|
2a805ac1a6 | ||
|
|
595f615ed9 | ||
|
|
aa7c39d312 | ||
|
|
2170d498c5 | ||
|
|
95a6f9aa7d | ||
|
|
ba65b351a2 | ||
|
|
4c09c8856b | ||
|
|
3afa8bd9da | ||
|
|
72eccd2649 | ||
|
|
310ea633b6 | ||
|
|
31b4d9cd70 | ||
|
|
0536d174fe | ||
|
|
96d7429a1c | ||
|
|
a54bb2bad4 | ||
|
|
d4abbd89ca | ||
|
|
bdfab6858d | ||
|
|
f80c8b89e4 | ||
|
|
29384d33e1 | ||
|
|
aebedf9ac6 | ||
|
|
40ee529c7e | ||
|
|
b9ee2f1e38 | ||
|
|
089b403a3b | ||
|
|
a28e5de5f4 | ||
|
|
2e30cefd91 | ||
|
|
33bf0c6902 | ||
|
|
13b6b43324 | ||
|
|
78bc2a95e5 | ||
|
|
5bb0e6e8c0 | ||
|
|
a278194037 | ||
|
|
1b8e546045 | ||
|
|
7319cb07e2 | ||
|
|
35e131b888 | ||
|
|
fd34eb3c26 | ||
|
|
02b00d2c87 | ||
|
|
b0e08ed749 | ||
|
|
ec3a688e66 | ||
|
|
4400c77f7e | ||
|
|
d890f75cca | ||
|
|
91b6087350 | ||
|
|
edcbcec10a | ||
|
|
18ab90288a | ||
|
|
9bf1c1e869 | ||
|
|
1e96a0b6a6 | ||
|
|
8dc08f66fd | ||
|
|
73b1e5949b | ||
|
|
2d6a4d7c28 | ||
|
|
ae389ee487 | ||
|
|
85d30520ce | ||
|
|
934ce9ba64 | ||
|
|
595a95fdf5 | ||
|
|
fc649a565c | ||
|
|
113b38056b | ||
|
|
559276534d | ||
|
|
4acd9f8816 | ||
|
|
7ee4eb6101 | ||
|
|
84b2fc9c17 | ||
|
|
a7417a7242 | ||
|
|
d18ff69ec9 | ||
|
|
5532577fdd | ||
|
|
5ebf470a86 | ||
|
|
4b39ccec6d | ||
|
|
18cd7a83c6 | ||
|
|
c5bfe6ffdb | ||
|
|
4ac365e670 | ||
|
|
ff1a903895 | ||
|
|
65f8b1ebe3 | ||
|
|
c23e8e5a7b | ||
|
|
aa4a9a093f | ||
|
|
0af813d7fe | ||
|
|
388486ec08 | ||
|
|
b1b0a7df30 | ||
|
|
f74aee6a03 | ||
|
|
4c6e66428c | ||
|
|
16d8e9e5a0 | ||
|
|
ee1f55361e | ||
|
|
cb33464668 | ||
|
|
06ddae13b5 | ||
|
|
16d3dead04 | ||
|
|
f7043f3f62 | ||
|
|
bf41f2984a | ||
|
|
86ca3602f3 | ||
|
|
416c28fded | ||
|
|
297373877a | ||
|
|
db9b93a96c | ||
|
|
5635375d8d | ||
|
|
07e72e4013 | ||
|
|
518d2aaa9c | ||
|
|
e93e2995b7 | ||
|
|
d2eb61a830 | ||
|
|
4c5a2c0610 | ||
|
|
e9e7362005 | ||
|
|
b97c822800 | ||
|
|
71e3b2d1fb | ||
|
|
326ba710ce | ||
|
|
1ea6feca37 | ||
|
|
c524442172 | ||
|
|
8e4d0db738 | ||
|
|
a170c194c8 | ||
|
|
2b51d72585 | ||
|
|
0d71006f40 | ||
|
|
a91e3b601c | ||
|
|
4940421297 | ||
|
|
58b4a8fbab | ||
|
|
bd7e12f682 | ||
|
|
64e43f07b9 | ||
|
|
2d84e2e977 | ||
|
|
465a1a82d7 | ||
|
|
61d36d584f | ||
|
|
2d343110cc | ||
|
|
4502e2c260 | ||
|
|
beb67847f9 | ||
|
|
9cdc29c482 | ||
|
|
292f66138b | ||
|
|
0087768946 | ||
|
|
01d177366d | ||
|
|
712340a027 | ||
|
|
1caac3f0b0 | ||
|
|
54a5dd6cbd | ||
|
|
6570177b0c | ||
|
|
f7ed992f24 | ||
|
|
4a18f8d18a | ||
|
|
24cf481f4a | ||
|
|
cd4e0c1f8e | ||
|
|
4a60310dc8 | ||
|
|
930620fce6 | ||
|
|
7a60d0987c | ||
|
|
9ac06057c1 | ||
|
|
e5c69c3236 | ||
|
|
39f050c6e4 | ||
|
|
4ee083759c | ||
|
|
072bfd87b7 | ||
|
|
b7aaaa80bb | ||
|
|
b8884b6ac9 | ||
|
|
05e271af47 | ||
|
|
58e80a9db8 | ||
|
|
e16fc3605e | ||
|
|
f13f05eb94 | ||
|
|
a54fc4cead | ||
|
|
2127ba90ee | ||
|
|
3373aef87d | ||
|
|
fa45e8ded7 | ||
|
|
6d0ead7b5b | ||
|
|
a2a6625f3b | ||
|
|
3c2510acd7 | ||
|
|
0d807d20f4 | ||
|
|
f4042263a3 | ||
|
|
a930f8233d | ||
|
|
7401008523 | ||
|
|
5199ea483e | ||
|
|
454a7a4799 | ||
|
|
6fb7733d8c | ||
|
|
ab17cbee31 | ||
|
|
9991f0cf95 | ||
|
|
44d46b06a2 | ||
|
|
ba7231f07d | ||
|
|
8dc11ea23a | ||
|
|
116a6a0acd | ||
|
|
311b69dc4a | ||
|
|
fd59acce5d | ||
|
|
956d3e4345 | ||
|
|
b8355b3a03 | ||
|
|
535b9f86db | ||
|
|
97c66a5404 | ||
|
|
6553beec99 | ||
|
|
e171dd52b8 | ||
|
|
27a837369d | ||
|
|
043b9f78e2 | ||
|
|
2f260a785f | ||
|
|
001b2dc6cc | ||
|
|
b13eedfbc2 | ||
|
|
dd70ef17b9 | ||
|
|
82dff3e9da | ||
|
|
d9cfd92b8f | ||
|
|
33cb771780 | ||
|
|
76cca8594d | ||
|
|
5c9c95ba1f | ||
|
|
e62bebeafe | ||
|
|
8a0e92cc6f | ||
|
|
3f9259dd0a | ||
|
|
30b9868de1 | ||
|
|
e88243c306 | ||
|
|
2128550df2 | ||
|
|
db67c0ed94 | ||
|
|
2e32c0d236 | ||
|
|
4b1ad1910d | ||
|
|
c337145b2c | ||
|
|
bd7b4c92bc | ||
|
|
33ebed3468 | ||
|
|
616bc40412 | ||
|
|
f00d9074ff | ||
|
|
9a692288e2 | ||
|
|
fea2b481e3 | ||
|
|
c17f0081ef | ||
|
|
fbf0803906 | ||
|
|
5deda45b66 | ||
|
|
3b8d8163b3 | ||
|
|
2dfd41bd3c | ||
|
|
49eead1d55 | ||
|
|
54cb3c3a5a | ||
|
|
9f2b920454 | ||
|
|
604af45661 | ||
|
|
3f435c5c1a | ||
|
|
7769af4541 | ||
|
|
9903be8120 | ||
|
|
991a601a3d | ||
|
|
86519d43dc | ||
|
|
179f669acf | ||
|
|
a02f878dcc | ||
|
|
32c29b28eb | ||
|
|
7bf2603414 | ||
|
|
4003876465 | ||
|
|
4c677961c4 | ||
|
|
e950d865d8 | ||
|
|
fd7a118664 | ||
|
|
d7906945df | ||
|
|
cb384ae024 | ||
|
|
7caead2387 | ||
|
|
4827c9e0d4 | ||
|
|
3b62fc63c9 | ||
|
|
ad32c2b1a5 | ||
|
|
f02f431dab | ||
|
|
812964e4d8 | ||
|
|
99805cc326 | ||
|
|
8d2b3f3dfe | ||
|
|
15f7fd8920 | ||
|
|
50460bf91e | ||
|
|
ee654f767a | ||
|
|
8c694a7ca3 | ||
|
|
9ac640fa67 | ||
|
|
db8d9fff2c | ||
|
|
811063268f | ||
|
|
f2b10a5a86 | ||
|
|
c69cac0e5f | ||
|
|
fed4433088 | ||
|
|
839cfcaefa | ||
|
|
3123407ef0 | ||
|
|
d24125c9e6 | ||
|
|
64dc278c95 | ||
|
|
626a824cd6 | ||
|
|
10ba3b4b5a | ||
|
|
1d059fc96e | ||
|
|
4c1585f8d8 | ||
|
|
e235957c00 | ||
|
|
2cc665bac6 | ||
|
|
d6e118dcd3 | ||
|
|
1d2534b2a1 | ||
|
|
484aa7b207 | ||
|
|
6986448239 | ||
|
|
f1d74dcd67 | ||
|
|
dd48d66c1c | ||
|
|
440f4e75c1 | ||
|
|
c795a70e9c | ||
|
|
340dbe8547 | ||
|
|
52a5e743e9 | ||
|
|
5ceff52796 | ||
|
|
f3a0ab0b2d | ||
|
|
4a7c994b66 | ||
|
|
07b8785f3d | ||
|
|
9a1092ab01 |
3
.github/.gitleaks.toml
vendored
@@ -536,10 +536,11 @@ secretGroup = 4
|
||||
|
||||
[allowlist]
|
||||
description = "global allow lists"
|
||||
regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''', '''RPM-GPG-KEY.*''', '''.*:.*StrelkaHexDump.*''', '''.*:.*PLACEHOLDER.*''', '''ssl_.*password''', '''integration_key\s=\s"so-logs-"''']
|
||||
regexes = ['''219-09-9999''', '''078-05-1120''', '''(9[0-9]{2}|666)-\d{2}-\d{4}''']
|
||||
paths = [
|
||||
'''gitleaks.toml''',
|
||||
'''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
|
||||
'''(go.mod|go.sum)$''',
|
||||
|
||||
'''salt/nginx/files/enterprise-attack.json'''
|
||||
]
|
||||
|
||||
16
.github/DISCUSSION_TEMPLATE/2-4.yml
vendored
@@ -11,6 +11,7 @@ body:
|
||||
description: Which version of Security Onion 2.4.x are you asking about?
|
||||
options:
|
||||
-
|
||||
- 2.4 Pre-release (Beta, Release Candidate)
|
||||
- 2.4.10
|
||||
- 2.4.20
|
||||
- 2.4.30
|
||||
@@ -21,14 +22,6 @@ body:
|
||||
- 2.4.80
|
||||
- 2.4.90
|
||||
- 2.4.100
|
||||
- 2.4.110
|
||||
- 2.4.111
|
||||
- 2.4.120
|
||||
- 2.4.130
|
||||
- 2.4.140
|
||||
- 2.4.141
|
||||
- 2.4.150
|
||||
- 2.4.160
|
||||
- Other (please provide detail below)
|
||||
validations:
|
||||
required: true
|
||||
@@ -39,10 +32,9 @@ body:
|
||||
options:
|
||||
-
|
||||
- Security Onion ISO image
|
||||
- Cloud image (Amazon, Azure, Google)
|
||||
- Network installation on Red Hat derivative like Oracle, Rocky, Alma, etc. (unsupported)
|
||||
- Network installation on Ubuntu (unsupported)
|
||||
- Network installation on Debian (unsupported)
|
||||
- Network installation on Red Hat derivative like Oracle, Rocky, Alma, etc.
|
||||
- Network installation on Ubuntu
|
||||
- Network installation on Debian
|
||||
- Other (please provide detail below)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
12
.github/ISSUE_TEMPLATE
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
PLEASE STOP AND READ THIS INFORMATION!
|
||||
|
||||
If you are creating an issue just to ask a question, you will likely get faster and better responses by posting to our discussions forum instead:
|
||||
https://securityonion.net/discuss
|
||||
|
||||
If you think you have found a possible bug or are observing a behavior that you weren't expecting, use the discussion forum to start a conversation about it instead of creating an issue.
|
||||
|
||||
If you are very familiar with the latest version of the product and are confident you have found a bug in Security Onion, you can continue with creating an issue here, but please make sure you have done the following:
|
||||
- duplicated the issue on a fresh installation of the latest version
|
||||
- provide information about your system and how you installed Security Onion
|
||||
- include relevant log files
|
||||
- include reproduction steps
|
||||
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,38 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: This option is for experienced community members to report a confirmed, reproducible bug
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
PLEASE STOP AND READ THIS INFORMATION!
|
||||
|
||||
If you are creating an issue just to ask a question, you will likely get faster and better responses by posting to our discussions forum at https://securityonion.net/discuss.
|
||||
|
||||
If you think you have found a possible bug or are observing a behavior that you weren't expecting, use the discussion forum at https://securityonion.net/discuss to start a conversation about it instead of creating an issue.
|
||||
|
||||
If you are very familiar with the latest version of the product and are confident you have found a bug in Security Onion, you can continue with creating an issue here, but please make sure you have done the following:
|
||||
- duplicated the issue on a fresh installation of the latest version
|
||||
- provide information about your system and how you installed Security Onion
|
||||
- include relevant log files
|
||||
- include reproduction steps
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Security Onion Discussions
|
||||
url: https://securityonion.com/discussions
|
||||
about: Please ask and answer questions here
|
||||
1
.github/workflows/close-threads.yml
vendored
@@ -15,7 +15,6 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
close-threads:
|
||||
if: github.repository_owner == 'security-onion-solutions'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
4
.github/workflows/contrib.yml
vendored
@@ -11,14 +11,14 @@ jobs:
|
||||
steps:
|
||||
- name: "Contributor Check"
|
||||
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
||||
uses: cla-assistant/github-action@v2.3.1
|
||||
uses: cla-assistant/github-action@v2.1.3-beta
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
with:
|
||||
path-to-signatures: 'signatures_v1.json'
|
||||
path-to-document: 'https://securityonionsolutions.com/cla'
|
||||
allowlist: dependabot[bot],jertel,dougburks,TOoSmOotH,defensivedepth,m0duspwnens
|
||||
allowlist: dependabot[bot],jertel,dougburks,TOoSmOotH,weslambert,defensivedepth,m0duspwnens
|
||||
remote-organization-name: Security-Onion-Solutions
|
||||
remote-repository-name: licensing
|
||||
|
||||
|
||||
1
.github/workflows/lock-threads.yml
vendored
@@ -15,7 +15,6 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
lock-threads:
|
||||
if: github.repository_owner == 'security-onion-solutions'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: jertel/lock-threads@main
|
||||
|
||||
12
.github/workflows/pythontest.yml
vendored
@@ -1,10 +1,6 @@
|
||||
name: python-test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "salt/sensoroni/files/analyzers/**"
|
||||
- "salt/manager/tools/sbin"
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -13,8 +9,8 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.13"]
|
||||
python-code-path: ["salt/sensoroni/files/analyzers", "salt/manager/tools/sbin"]
|
||||
python-version: ["3.10"]
|
||||
python-code-path: ["salt/sensoroni/files/analyzers"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -32,4 +28,4 @@ jobs:
|
||||
flake8 ${{ matrix.python-code-path }} --show-source --max-complexity=12 --doctests --max-line-length=200 --statistics
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
PYTHONPATH=${{ matrix.python-code-path }} pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=pytest.ini
|
||||
pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=${{ matrix.python-code-path }}/pytest.ini
|
||||
|
||||
53
LICENSE
@@ -1,53 +0,0 @@
|
||||
Elastic License 2.0 (ELv2)
|
||||
|
||||
Acceptance
|
||||
|
||||
By using the software, you agree to all of the terms and conditions below.
|
||||
|
||||
Copyright License
|
||||
|
||||
The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below.
|
||||
|
||||
Limitations
|
||||
|
||||
You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.
|
||||
|
||||
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.
|
||||
|
||||
You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law.
|
||||
|
||||
Patents
|
||||
|
||||
The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
||||
|
||||
Notices
|
||||
|
||||
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms.
|
||||
|
||||
If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software.
|
||||
|
||||
No Other Rights
|
||||
|
||||
These terms do not imply any licenses other than those expressly granted in these terms.
|
||||
|
||||
Termination
|
||||
|
||||
If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently.
|
||||
|
||||
No Liability
|
||||
|
||||
As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
|
||||
|
||||
Definitions
|
||||
|
||||
The licensor is the entity offering these terms, and the software is the software the licensor makes available under these terms, including any portion of it.
|
||||
|
||||
you refers to the individual or entity agreeing to these terms.
|
||||
|
||||
your company is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. control means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
||||
|
||||
your licenses are all the licenses granted to you for the software under these terms.
|
||||
|
||||
use means anything you do with the software requiring one of your licenses.
|
||||
|
||||
trademark means trademarks, service marks, and similar rights.
|
||||
49
README.md
@@ -1,50 +1,55 @@
|
||||
## Security Onion 2.4
|
||||
## Security Onion 2.3
|
||||
|
||||
Security Onion 2.4 is here!
|
||||
Security Onion 2.3 is here!
|
||||
|
||||
## End Of Life Warning
|
||||
|
||||
Security Onion 2.3 reaches End Of Life (EOL) on April 6, 2024:
|
||||
|
||||
https://blog.securityonion.net/2023/10/6-month-eol-notice-for-security-onion-23.html
|
||||
|
||||
For new installations, please see the 2.4 branch of this repo:
|
||||
|
||||
https://github.com/Security-Onion-Solutions/securityonion/tree/2.4/main
|
||||
|
||||
If you have an existing 2.3 installation and would like to migrate to 2.4, please see:
|
||||
|
||||
https://docs.securityonion.net/en/2.4/appendix.html
|
||||
|
||||
## Screenshots
|
||||
|
||||
Alerts
|
||||

|
||||

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

|
||||

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

|
||||

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

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

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

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

|
||||
Cases
|
||||

|
||||
|
||||
### Release Notes
|
||||
|
||||
https://docs.securityonion.net/en/2.4/release-notes.html
|
||||
https://docs.securityonion.net/en/2.3/release-notes.html
|
||||
|
||||
### Requirements
|
||||
|
||||
https://docs.securityonion.net/en/2.4/hardware.html
|
||||
https://docs.securityonion.net/en/2.3/hardware.html
|
||||
|
||||
### Download
|
||||
|
||||
https://docs.securityonion.net/en/2.4/download.html
|
||||
https://docs.securityonion.net/en/2.3/download.html
|
||||
|
||||
### Installation
|
||||
|
||||
https://docs.securityonion.net/en/2.4/installation.html
|
||||
https://docs.securityonion.net/en/2.3/installation.html
|
||||
|
||||
### FAQ
|
||||
|
||||
https://docs.securityonion.net/en/2.4/faq.html
|
||||
https://docs.securityonion.net/en/2.3/faq.html
|
||||
|
||||
### Feedback
|
||||
|
||||
https://docs.securityonion.net/en/2.4/community-support.html
|
||||
https://docs.securityonion.net/en/2.3/community-support.html
|
||||
|
||||
@@ -4,12 +4,9 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.4.x | :white_check_mark: |
|
||||
| 2.3.x | :x: |
|
||||
| 2.x.x | :white_check_mark: |
|
||||
| 16.04.x | :x: |
|
||||
|
||||
Security Onion 2.3 has reached End Of Life and is no longer supported.
|
||||
|
||||
Security Onion 16.04 has reached End Of Life and is no longer supported.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
### 2.4.160-20250625 ISO image released on 2025/06/25
|
||||
### 2.3.300-20240401 ISO image built on 2024/04/01
|
||||
|
||||
|
||||
|
||||
### Download and Verify
|
||||
|
||||
2.4.160-20250625 ISO image:
|
||||
https://download.securityonion.net/file/securityonion/securityonion-2.4.160-20250625.iso
|
||||
|
||||
MD5: 78CF5602EFFAB84174C56AD2826E6E4E
|
||||
SHA1: FC7EEC3EC95D97D3337501BAA7CA8CAE7C0E15EA
|
||||
SHA256: 0ED965E8BEC80EE16AE90A0F0F96A3046CEF2D92720A587278DDDE3B656C01C2
|
||||
2.3.300-20240401 ISO image:
|
||||
https://download.securityonion.net/file/securityonion/securityonion-2.3.300-20240401.iso
|
||||
|
||||
MD5: 5CBDA8012D773C5EC362D21C4EA3B7FB
|
||||
SHA1: 7A34FAA0E11F09F529FF38EC3239211CD87CB1A7
|
||||
SHA256: 123066DAFBF6F2AA0E1924296CFEFE1213002D7760E8797AB74F1FC1D683C6D7
|
||||
|
||||
Signature for ISO image:
|
||||
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.160-20250625.iso.sig
|
||||
https://github.com/Security-Onion-Solutions/securityonion/raw/master/sigs/securityonion-2.3.300-20240401.iso.sig
|
||||
|
||||
Signing key:
|
||||
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS
|
||||
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/master/KEYS
|
||||
|
||||
For example, here are the steps you can use on most Linux distributions to download and verify our Security Onion ISO image.
|
||||
|
||||
Download and import the signing key:
|
||||
```
|
||||
wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS -O - | gpg --import -
|
||||
wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/master/KEYS -O - | gpg --import -
|
||||
```
|
||||
|
||||
Download the signature file for the ISO:
|
||||
```
|
||||
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.160-20250625.iso.sig
|
||||
wget https://github.com/Security-Onion-Solutions/securityonion/raw/master/sigs/securityonion-2.3.300-20240401.iso.sig
|
||||
```
|
||||
|
||||
Download the ISO image:
|
||||
```
|
||||
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.160-20250625.iso
|
||||
wget https://download.securityonion.net/file/securityonion/securityonion-2.3.300-20240401.iso
|
||||
```
|
||||
|
||||
Verify the downloaded ISO image using the signature file:
|
||||
```
|
||||
gpg --verify securityonion-2.4.160-20250625.iso.sig securityonion-2.4.160-20250625.iso
|
||||
gpg --verify securityonion-2.3.300-20240401.iso.sig securityonion-2.3.300-20240401.iso
|
||||
```
|
||||
|
||||
The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
|
||||
```
|
||||
gpg: Signature made Wed 25 Jun 2025 10:13:33 AM EDT using RSA key ID FE507013
|
||||
gpg: Signature made Wed 27 Mar 2024 05:09:33 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
|
||||
https://docs.securityonion.net/en/2.3/installation.html
|
||||
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,8 +1,8 @@
|
||||
{% import_yaml 'firewall/ports/ports.yaml' as default_portgroups %}
|
||||
{% set default_portgroups = default_portgroups.firewall.ports %}
|
||||
{% import_yaml 'firewall/ports/ports.local.yaml' as local_portgroups %}
|
||||
{% if local_portgroups.firewall.ports %}
|
||||
{% set local_portgroups = local_portgroups.firewall.ports %}
|
||||
{% import_yaml 'firewall/portgroups.yaml' as default_portgroups %}
|
||||
{% set default_portgroups = default_portgroups.firewall.aliases.ports %}
|
||||
{% import_yaml 'firewall/portgroups.local.yaml' as local_portgroups %}
|
||||
{% if local_portgroups.firewall.aliases.ports %}
|
||||
{% set local_portgroups = local_portgroups.firewall.aliases.ports %}
|
||||
{% else %}
|
||||
{% set local_portgroups = {} %}
|
||||
{% endif %}
|
||||
@@ -12,6 +12,7 @@ role:
|
||||
eval:
|
||||
fleet:
|
||||
heavynode:
|
||||
helixsensor:
|
||||
idh:
|
||||
import:
|
||||
manager:
|
||||
@@ -19,4 +20,4 @@ role:
|
||||
receiver:
|
||||
standalone:
|
||||
searchnode:
|
||||
sensor:
|
||||
sensor:
|
||||
|
||||
82
files/firewall/hostgroups.local.yaml
Normal file
@@ -0,0 +1,82 @@
|
||||
firewall:
|
||||
hostgroups:
|
||||
analyst:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
beats_endpoint:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
beats_endpoint_ssl:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
elasticsearch_rest:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
endgame:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
fleet:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
heavy_node:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
idh:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
manager:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
minion:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
node:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
osquery_endpoint:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
receiver:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
search_node:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
sensor:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
strelka_frontend:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
syslog:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
wazuh_agent:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
wazuh_api:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
wazuh_authd:
|
||||
ips:
|
||||
delete:
|
||||
insert:
|
||||
3
files/firewall/portgroups.local.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
firewall:
|
||||
aliases:
|
||||
ports:
|
||||
@@ -1,2 +0,0 @@
|
||||
firewall:
|
||||
ports:
|
||||
@@ -41,8 +41,7 @@ file_roots:
|
||||
base:
|
||||
- /opt/so/saltstack/local/salt
|
||||
- /opt/so/saltstack/default/salt
|
||||
- /nsm/elastic-fleet/artifacts
|
||||
- /opt/so/rules/nids
|
||||
|
||||
|
||||
# The master_roots setting configures a master-only copy of the file_roots dictionary,
|
||||
# used by the state compiler.
|
||||
@@ -65,4 +64,8 @@ peer:
|
||||
.*:
|
||||
- x509.sign_remote_certificate
|
||||
|
||||
reactor:
|
||||
- 'so/fleet':
|
||||
- salt://reactor/fleet.sls
|
||||
|
||||
|
||||
|
||||
@@ -45,10 +45,12 @@ echo " rootfs: $ROOTFS" >> $local_salt_dir/pillar/data/$TYPE.sls
|
||||
echo " nsmfs: $NSM" >> $local_salt_dir/pillar/data/$TYPE.sls
|
||||
if [ $TYPE == 'sensorstab' ]; then
|
||||
echo " monint: bond0" >> $local_salt_dir/pillar/data/$TYPE.sls
|
||||
salt-call state.apply grafana queue=True
|
||||
fi
|
||||
if [ $TYPE == 'evaltab' ] || [ $TYPE == 'standalonetab' ]; then
|
||||
echo " monint: bond0" >> $local_salt_dir/pillar/data/$TYPE.sls
|
||||
if [ ! $10 ]; then
|
||||
salt-call state.apply grafana queue=True
|
||||
salt-call state.apply utility queue=True
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{% set node_types = {} %}
|
||||
{% for minionid, ip in salt.saltutil.runner(
|
||||
'mine.get',
|
||||
tgt='elasticsearch:enabled:true',
|
||||
fun='network.ip_addrs',
|
||||
tgt_type='pillar') | dictsort()
|
||||
%}
|
||||
|
||||
# only add a node to the pillar if it returned an ip from the mine
|
||||
{% if ip | length > 0%}
|
||||
{% set hostname = minionid.split('_') | first %}
|
||||
{% set node_type = minionid.split('_') | last %}
|
||||
{% if node_type not in node_types.keys() %}
|
||||
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
|
||||
{% else %}
|
||||
{% if hostname not in node_types[node_type] %}
|
||||
{% do node_types[node_type].update({hostname: ip[0]}) %}
|
||||
{% else %}
|
||||
{% do node_types[node_type][hostname].update(ip[0]) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
elasticsearch:
|
||||
nodes:
|
||||
{% for node_type, values in node_types.items() %}
|
||||
{{node_type}}:
|
||||
{% for hostname, ip in values.items() %}
|
||||
{{hostname}}:
|
||||
ip: {{ip}}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
@@ -1,2 +0,0 @@
|
||||
kafka:
|
||||
nodes:
|
||||
13
pillar/logrotate/init.sls
Normal file
@@ -0,0 +1,13 @@
|
||||
logrotate:
|
||||
conf: |
|
||||
daily
|
||||
rotate 14
|
||||
missingok
|
||||
copytruncate
|
||||
compress
|
||||
create
|
||||
extension .log
|
||||
dateext
|
||||
dateyesterday
|
||||
group_conf: |
|
||||
su root socore
|
||||
42
pillar/logstash/helix.sls
Normal file
@@ -0,0 +1,42 @@
|
||||
logstash:
|
||||
pipelines:
|
||||
helix:
|
||||
config:
|
||||
- so/0010_input_hhbeats.conf
|
||||
- so/1033_preprocess_snort.conf
|
||||
- so/1100_preprocess_bro_conn.conf
|
||||
- so/1101_preprocess_bro_dhcp.conf
|
||||
- so/1102_preprocess_bro_dns.conf
|
||||
- so/1103_preprocess_bro_dpd.conf
|
||||
- so/1104_preprocess_bro_files.conf
|
||||
- so/1105_preprocess_bro_ftp.conf
|
||||
- so/1106_preprocess_bro_http.conf
|
||||
- so/1107_preprocess_bro_irc.conf
|
||||
- so/1108_preprocess_bro_kerberos.conf
|
||||
- so/1109_preprocess_bro_notice.conf
|
||||
- so/1110_preprocess_bro_rdp.conf
|
||||
- so/1111_preprocess_bro_signatures.conf
|
||||
- so/1112_preprocess_bro_smtp.conf
|
||||
- so/1113_preprocess_bro_snmp.conf
|
||||
- so/1114_preprocess_bro_software.conf
|
||||
- so/1115_preprocess_bro_ssh.conf
|
||||
- so/1116_preprocess_bro_ssl.conf
|
||||
- so/1117_preprocess_bro_syslog.conf
|
||||
- so/1118_preprocess_bro_tunnel.conf
|
||||
- so/1119_preprocess_bro_weird.conf
|
||||
- so/1121_preprocess_bro_mysql.conf
|
||||
- so/1122_preprocess_bro_socks.conf
|
||||
- so/1123_preprocess_bro_x509.conf
|
||||
- so/1124_preprocess_bro_intel.conf
|
||||
- so/1125_preprocess_bro_modbus.conf
|
||||
- so/1126_preprocess_bro_sip.conf
|
||||
- so/1127_preprocess_bro_radius.conf
|
||||
- so/1128_preprocess_bro_pe.conf
|
||||
- so/1129_preprocess_bro_rfb.conf
|
||||
- so/1130_preprocess_bro_dnp3.conf
|
||||
- so/1131_preprocess_bro_smb_files.conf
|
||||
- so/1132_preprocess_bro_smb_mapping.conf
|
||||
- so/1133_preprocess_bro_ntlm.conf
|
||||
- so/1134_preprocess_bro_dce_rpc.conf
|
||||
- so/8001_postprocess_common_ip_augmentation.conf
|
||||
- so/9997_output_helix.conf.jinja
|
||||
@@ -3,8 +3,6 @@ logstash:
|
||||
port_bindings:
|
||||
- 0.0.0.0:3765:3765
|
||||
- 0.0.0.0:5044:5044
|
||||
- 0.0.0.0:5055:5055
|
||||
- 0.0.0.0:5056:5056
|
||||
- 0.0.0.0:5644:5644
|
||||
- 0.0.0.0:6050:6050
|
||||
- 0.0.0.0:6051:6051
|
||||
|
||||
9
pillar/logstash/manager.sls
Normal file
@@ -0,0 +1,9 @@
|
||||
logstash:
|
||||
pipelines:
|
||||
manager:
|
||||
config:
|
||||
- so/0009_input_beats.conf
|
||||
- so/0010_input_hhbeats.conf
|
||||
- so/0011_input_endgame.conf
|
||||
- so/9999_output_redis.conf.jinja
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
{% set node_types = {} %}
|
||||
{% set cached_grains = salt.saltutil.runner('cache.grains', tgt='*') %}
|
||||
{% for minionid, ip in salt.saltutil.runner(
|
||||
'mine.get',
|
||||
tgt='logstash:enabled:true',
|
||||
tgt='G@role:so-manager or G@role:so-managersearch or G@role:so-standalone or G@role:so-node or G@role:so-heavynode or G@role:so-receiver or G@role:so-helix',
|
||||
fun='network.ip_addrs',
|
||||
tgt_type='pillar') | dictsort()
|
||||
tgt_type='compound') | dictsort()
|
||||
%}
|
||||
|
||||
# only add a node to the pillar if it returned an ip from the mine
|
||||
{% if ip | length > 0%}
|
||||
{% set hostname = minionid.split('_') | first %}
|
||||
{% set node_type = minionid.split('_') | last %}
|
||||
{% if node_type not in node_types.keys() %}
|
||||
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
|
||||
{% set hostname = cached_grains[minionid]['host'] %}
|
||||
{% set node_type = minionid.split('_')[1] %}
|
||||
{% if node_type not in node_types.keys() %}
|
||||
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
|
||||
{% else %}
|
||||
{% if hostname not in node_types[node_type] %}
|
||||
{% do node_types[node_type].update({hostname: ip[0]}) %}
|
||||
{% else %}
|
||||
{% if hostname not in node_types[node_type] %}
|
||||
{% do node_types[node_type].update({hostname: ip[0]}) %}
|
||||
{% else %}
|
||||
{% do node_types[node_type][hostname].update(ip[0]) %}
|
||||
{% endif %}
|
||||
{% do node_types[node_type][hostname].update(ip[0]) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
logstash:
|
||||
nodes:
|
||||
{% for node_type, values in node_types.items() %}
|
||||
|
||||
9
pillar/logstash/receiver.sls
Normal file
@@ -0,0 +1,9 @@
|
||||
logstash:
|
||||
pipelines:
|
||||
receiver:
|
||||
config:
|
||||
- so/0009_input_beats.conf
|
||||
- so/0010_input_hhbeats.conf
|
||||
- so/0011_input_endgame.conf
|
||||
- so/9999_output_redis.conf.jinja
|
||||
|
||||
18
pillar/logstash/search.sls
Normal file
@@ -0,0 +1,18 @@
|
||||
logstash:
|
||||
pipelines:
|
||||
search:
|
||||
config:
|
||||
- so/0900_input_redis.conf.jinja
|
||||
- so/9000_output_zeek.conf.jinja
|
||||
- so/9002_output_import.conf.jinja
|
||||
- so/9034_output_syslog.conf.jinja
|
||||
- so/9050_output_filebeatmodules.conf.jinja
|
||||
- so/9100_output_osquery.conf.jinja
|
||||
- so/9400_output_suricata.conf.jinja
|
||||
- so/9500_output_beats.conf.jinja
|
||||
- so/9600_output_ossec.conf.jinja
|
||||
- so/9700_output_strelka.conf.jinja
|
||||
- so/9800_output_logscan.conf.jinja
|
||||
- so/9801_output_rita.conf.jinja
|
||||
- so/9802_output_kratos.conf.jinja
|
||||
- so/9900_output_endgame.conf.jinja
|
||||
@@ -1,39 +1,33 @@
|
||||
{% set node_types = {} %}
|
||||
{% set manage_alived = salt.saltutil.runner('manage.alived', show_ip=True) %}
|
||||
{% set manager = grains.master %}
|
||||
{% set manager_type = manager.split('_')|last %}
|
||||
{% for minionid, ip in salt.saltutil.runner('mine.get', tgt='*', fun='network.ip_addrs', tgt_type='glob') | dictsort() %}
|
||||
{% set hostname = minionid.split('_')[0] %}
|
||||
{% set node_type = minionid.split('_')[1] %}
|
||||
{% set is_alive = False %}
|
||||
|
||||
# only add a node to the pillar if it returned an ip from the mine
|
||||
{% if ip | length > 0%}
|
||||
{% if minionid in manage_alived.keys() %}
|
||||
{% if ip[0] == manage_alived[minionid] %}
|
||||
{% set is_alive = True %}
|
||||
{% endif %}
|
||||
{% if minionid in manage_alived.keys() %}
|
||||
{% if ip[0] == manage_alived[minionid] %}
|
||||
{% set is_alive = True %}
|
||||
{% endif %}
|
||||
{% if node_type not in node_types.keys() %}
|
||||
{% do node_types.update({node_type: {hostname: {'ip':ip[0], 'alive':is_alive }}}) %}
|
||||
{% endif %}
|
||||
{% if node_type not in node_types.keys() %}
|
||||
{% do node_types.update({node_type: {hostname: {'ip':ip[0], 'alive':is_alive }}}) %}
|
||||
{% else %}
|
||||
{% if hostname not in node_types[node_type] %}
|
||||
{% do node_types[node_type].update({hostname: {'ip':ip[0], 'alive':is_alive}}) %}
|
||||
{% else %}
|
||||
{% if hostname not in node_types[node_type] %}
|
||||
{% do node_types[node_type].update({hostname: {'ip':ip[0], 'alive':is_alive}}) %}
|
||||
{% else %}
|
||||
{% do node_types[node_type][hostname].update({'ip':ip[0], 'alive':is_alive}) %}
|
||||
{% endif %}
|
||||
{% do node_types[node_type][hostname].update({'ip':ip[0], 'alive':is_alive}) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if node_types %}
|
||||
node_data:
|
||||
{% for node_type, host_values in node_types.items() %}
|
||||
{{node_type}}:
|
||||
{% for hostname, details in host_values.items() %}
|
||||
{{hostname}}:
|
||||
ip: {{details.ip}}
|
||||
alive: {{ details.alive }}
|
||||
role: {{node_type}}
|
||||
{{hostname}}:
|
||||
ip: {{details.ip}}
|
||||
alive: {{ details.alive }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
node_data: False
|
||||
{% endif %}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{% set node_types = {} %}
|
||||
{% for minionid, ip in salt.saltutil.runner(
|
||||
'mine.get',
|
||||
tgt='redis:enabled:true',
|
||||
fun='network.ip_addrs',
|
||||
tgt_type='pillar') | dictsort()
|
||||
%}
|
||||
|
||||
# only add a node to the pillar if it returned an ip from the mine
|
||||
{% if ip | length > 0%}
|
||||
{% set hostname = minionid.split('_') | first %}
|
||||
{% set node_type = minionid.split('_') | last %}
|
||||
{% if node_type not in node_types.keys() %}
|
||||
{% do node_types.update({node_type: {hostname: ip[0]}}) %}
|
||||
{% else %}
|
||||
{% if hostname not in node_types[node_type] %}
|
||||
{% do node_types[node_type].update({hostname: ip[0]}) %}
|
||||
{% else %}
|
||||
{% do node_types[node_type][hostname].update(ip[0]) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
redis:
|
||||
nodes:
|
||||
{% for node_type, values in node_types.items() %}
|
||||
{{node_type}}:
|
||||
{% for hostname, ip in values.items() %}
|
||||
{{hostname}}:
|
||||
ip: {{ip}}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
@@ -1,14 +0,0 @@
|
||||
# Copyright Jason Ertel (github.com/jertel).
|
||||
# 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."
|
||||
|
||||
# This file is generated by Security Onion and contains a list of license-enabled features.
|
||||
features: []
|
||||
44
pillar/thresholding/pillar.example
Normal file
@@ -0,0 +1,44 @@
|
||||
thresholding:
|
||||
sids:
|
||||
8675309:
|
||||
- threshold:
|
||||
gen_id: 1
|
||||
type: threshold
|
||||
track: by_src
|
||||
count: 10
|
||||
seconds: 10
|
||||
- threshold:
|
||||
gen_id: 1
|
||||
type: limit
|
||||
track: by_dst
|
||||
count: 100
|
||||
seconds: 30
|
||||
- rate_filter:
|
||||
gen_id: 1
|
||||
track: by_rule
|
||||
count: 50
|
||||
seconds: 30
|
||||
new_action: alert
|
||||
timeout: 30
|
||||
- suppress:
|
||||
gen_id: 1
|
||||
track: by_either
|
||||
ip: 10.10.3.7
|
||||
11223344:
|
||||
- threshold:
|
||||
gen_id: 1
|
||||
type: limit
|
||||
track: by_dst
|
||||
count: 10
|
||||
seconds: 10
|
||||
- rate_filter:
|
||||
gen_id: 1
|
||||
track: by_src
|
||||
count: 50
|
||||
seconds: 20
|
||||
new_action: pass
|
||||
timeout: 60
|
||||
- suppress:
|
||||
gen_id: 1
|
||||
track: by_src
|
||||
ip: 10.10.3.0/24
|
||||
20
pillar/thresholding/pillar.usage
Normal file
@@ -0,0 +1,20 @@
|
||||
thresholding:
|
||||
sids:
|
||||
<signature id>:
|
||||
- threshold:
|
||||
gen_id: <generator id>
|
||||
type: <threshold | limit | both>
|
||||
track: <by_src | by_dst>
|
||||
count: <count>
|
||||
seconds: <seconds>
|
||||
- rate_filter:
|
||||
gen_id: <generator id>
|
||||
track: <by_src | by_dst | by_rule | by_both>
|
||||
count: <count>
|
||||
seconds: <seconds>
|
||||
new_action: <alert | pass>
|
||||
timeout: <seconds>
|
||||
- suppress:
|
||||
gen_id: <generator id>
|
||||
track: <by_src | by_dst | by_either>
|
||||
ip: <ip | subnet>
|
||||
378
pillar/top.sls
@@ -1,326 +1,136 @@
|
||||
base:
|
||||
'*':
|
||||
- global.soc_global
|
||||
- global.adv_global
|
||||
- docker.soc_docker
|
||||
- docker.adv_docker
|
||||
- influxdb.token
|
||||
- logrotate.soc_logrotate
|
||||
- logrotate.adv_logrotate
|
||||
- ntp.soc_ntp
|
||||
- ntp.adv_ntp
|
||||
- patch.needs_restarting
|
||||
- patch.soc_patch
|
||||
- patch.adv_patch
|
||||
- sensoroni.soc_sensoroni
|
||||
- sensoroni.adv_sensoroni
|
||||
- telegraf.soc_telegraf
|
||||
- telegraf.adv_telegraf
|
||||
- versionlock.soc_versionlock
|
||||
- versionlock.adv_versionlock
|
||||
- logrotate
|
||||
|
||||
'* and not *_desktop':
|
||||
- firewall.soc_firewall
|
||||
- firewall.adv_firewall
|
||||
- nginx.soc_nginx
|
||||
- nginx.adv_nginx
|
||||
'* and not *_eval and not *_import':
|
||||
- logstash.nodes
|
||||
|
||||
'*_eval or *_helixsensor or *_heavynode or *_sensor or *_standalone or *_import':
|
||||
- match: compound
|
||||
- zeek
|
||||
|
||||
'*_managersearch or *_heavynode':
|
||||
- match: compound
|
||||
- logstash
|
||||
- logstash.manager
|
||||
- logstash.search
|
||||
- elasticsearch.index_templates
|
||||
|
||||
'*_manager':
|
||||
- logstash
|
||||
- logstash.manager
|
||||
- elasticsearch.index_templates
|
||||
|
||||
'*_manager or *_managersearch':
|
||||
- match: compound
|
||||
- node_data.ips
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- data.*
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
- kibana.secrets
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
- secrets
|
||||
- manager.soc_manager
|
||||
- manager.adv_manager
|
||||
- idstools.soc_idstools
|
||||
- idstools.adv_idstools
|
||||
- logstash.nodes
|
||||
- logstash.soc_logstash
|
||||
- logstash.adv_logstash
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- kratos.soc_kratos
|
||||
- kratos.adv_kratos
|
||||
- hydra.soc_hydra
|
||||
- hydra.adv_hydra
|
||||
- redis.nodes
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- influxdb.soc_influxdb
|
||||
- influxdb.adv_influxdb
|
||||
- elasticsearch.nodes
|
||||
- elasticsearch.soc_elasticsearch
|
||||
- elasticsearch.adv_elasticsearch
|
||||
- elasticfleet.soc_elasticfleet
|
||||
- elasticfleet.adv_elasticfleet
|
||||
- elastalert.soc_elastalert
|
||||
- elastalert.adv_elastalert
|
||||
- backup.soc_backup
|
||||
- backup.adv_backup
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
- stig.soc_stig
|
||||
|
||||
'*_sensor':
|
||||
- zeeklogs
|
||||
- healthcheck.sensor
|
||||
- strelka.soc_strelka
|
||||
- strelka.adv_strelka
|
||||
- zeek.soc_zeek
|
||||
- zeek.adv_zeek
|
||||
- bpf.soc_bpf
|
||||
- bpf.adv_bpf
|
||||
- pcap.soc_pcap
|
||||
- pcap.adv_pcap
|
||||
- suricata.soc_suricata
|
||||
- suricata.adv_suricata
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- stig.soc_stig
|
||||
- soc.license
|
||||
|
||||
'*_eval':
|
||||
- node_data.ips
|
||||
- data.*
|
||||
- zeeklogs
|
||||
- secrets
|
||||
- healthcheck.eval
|
||||
- elasticsearch.index_templates
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
- kibana.secrets
|
||||
{% endif %}
|
||||
- kratos.soc_kratos
|
||||
- kratos.adv_kratos
|
||||
- elasticsearch.soc_elasticsearch
|
||||
- elasticsearch.adv_elasticsearch
|
||||
- elasticfleet.soc_elasticfleet
|
||||
- elasticfleet.adv_elasticfleet
|
||||
- elastalert.soc_elastalert
|
||||
- elastalert.adv_elastalert
|
||||
- manager.soc_manager
|
||||
- manager.adv_manager
|
||||
- idstools.soc_idstools
|
||||
- idstools.adv_idstools
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- strelka.soc_strelka
|
||||
- strelka.adv_strelka
|
||||
- hydra.soc_hydra
|
||||
- hydra.adv_hydra
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- influxdb.soc_influxdb
|
||||
- influxdb.adv_influxdb
|
||||
- backup.soc_backup
|
||||
- backup.adv_backup
|
||||
- zeek.soc_zeek
|
||||
- zeek.adv_zeek
|
||||
- bpf.soc_bpf
|
||||
- bpf.adv_bpf
|
||||
- pcap.soc_pcap
|
||||
- pcap.adv_pcap
|
||||
- suricata.soc_suricata
|
||||
- suricata.adv_suricata
|
||||
{% endif %}
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
|
||||
'*_standalone':
|
||||
- node_data.ips
|
||||
- logstash.nodes
|
||||
- logstash.soc_logstash
|
||||
- logstash.adv_logstash
|
||||
- logstash
|
||||
- logstash.manager
|
||||
- logstash.search
|
||||
- elasticsearch.index_templates
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
- kibana.secrets
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
- data.*
|
||||
- zeeklogs
|
||||
- secrets
|
||||
- healthcheck.standalone
|
||||
- idstools.soc_idstools
|
||||
- idstools.adv_idstools
|
||||
- kratos.soc_kratos
|
||||
- kratos.adv_kratos
|
||||
- hydra.soc_hydra
|
||||
- hydra.adv_hydra
|
||||
- redis.nodes
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- influxdb.soc_influxdb
|
||||
- influxdb.adv_influxdb
|
||||
- elasticsearch.nodes
|
||||
- elasticsearch.soc_elasticsearch
|
||||
- elasticsearch.adv_elasticsearch
|
||||
- elasticfleet.soc_elasticfleet
|
||||
- elasticfleet.adv_elasticfleet
|
||||
- elastalert.soc_elastalert
|
||||
- elastalert.adv_elastalert
|
||||
- manager.soc_manager
|
||||
- manager.adv_manager
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- strelka.soc_strelka
|
||||
- strelka.adv_strelka
|
||||
- backup.soc_backup
|
||||
- backup.adv_backup
|
||||
- zeek.soc_zeek
|
||||
- zeek.adv_zeek
|
||||
- bpf.soc_bpf
|
||||
- bpf.adv_bpf
|
||||
- pcap.soc_pcap
|
||||
- pcap.adv_pcap
|
||||
- suricata.soc_suricata
|
||||
- suricata.adv_suricata
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
|
||||
'*_node':
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- stig.soc_stig
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
|
||||
'*_heavynode':
|
||||
- zeeklogs
|
||||
- elasticsearch.auth
|
||||
- logstash.nodes
|
||||
- logstash.soc_logstash
|
||||
- logstash.adv_logstash
|
||||
- elasticsearch.soc_elasticsearch
|
||||
- elasticsearch.adv_elasticsearch
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- zeek.soc_zeek
|
||||
- zeek.adv_zeek
|
||||
- bpf.soc_bpf
|
||||
- bpf.adv_bpf
|
||||
- pcap.soc_pcap
|
||||
- pcap.adv_pcap
|
||||
- suricata.soc_suricata
|
||||
- suricata.adv_suricata
|
||||
- strelka.soc_strelka
|
||||
- strelka.adv_strelka
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
|
||||
'*_idh':
|
||||
- idh.soc_idh
|
||||
- idh.adv_idh
|
||||
'*_helixsensor':
|
||||
- fireeye
|
||||
- zeeklogs
|
||||
- logstash
|
||||
- logstash.helix
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
|
||||
'*_searchnode':
|
||||
- logstash.nodes
|
||||
- logstash.soc_logstash
|
||||
- logstash.adv_logstash
|
||||
- elasticsearch.nodes
|
||||
- elasticsearch.soc_elasticsearch
|
||||
- elasticsearch.adv_elasticsearch
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
- redis.nodes
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- stig.soc_stig
|
||||
- soc.license
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
|
||||
'*_receiver':
|
||||
- logstash.nodes
|
||||
- logstash.soc_logstash
|
||||
- logstash.adv_logstash
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- kafka.nodes
|
||||
- kafka.soc_kafka
|
||||
- kafka.adv_kafka
|
||||
- soc.license
|
||||
|
||||
'*_import':
|
||||
- node_data.ips
|
||||
- secrets
|
||||
- elasticsearch.index_templates
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
- kibana.secrets
|
||||
{% endif %}
|
||||
- kratos.soc_kratos
|
||||
- kratos.adv_kratos
|
||||
- elasticsearch.soc_elasticsearch
|
||||
- elasticsearch.adv_elasticsearch
|
||||
- elasticfleet.soc_elasticfleet
|
||||
- elasticfleet.adv_elasticfleet
|
||||
- elastalert.soc_elastalert
|
||||
- elastalert.adv_elastalert
|
||||
- manager.soc_manager
|
||||
- manager.adv_manager
|
||||
- soc.soc_soc
|
||||
- soc.adv_soc
|
||||
- soc.license
|
||||
- kibana.soc_kibana
|
||||
- kibana.adv_kibana
|
||||
- backup.soc_backup
|
||||
- backup.adv_backup
|
||||
- hydra.soc_hydra
|
||||
- hydra.adv_hydra
|
||||
- redis.soc_redis
|
||||
- redis.adv_redis
|
||||
- influxdb.soc_influxdb
|
||||
- influxdb.adv_influxdb
|
||||
- zeek.soc_zeek
|
||||
- zeek.adv_zeek
|
||||
- bpf.soc_bpf
|
||||
- bpf.adv_bpf
|
||||
- pcap.soc_pcap
|
||||
- pcap.adv_pcap
|
||||
- suricata.soc_suricata
|
||||
- suricata.adv_suricata
|
||||
- strelka.soc_strelka
|
||||
- strelka.adv_strelka
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
|
||||
'*_fleet':
|
||||
- node_data.ips
|
||||
- backup.soc_backup
|
||||
- backup.adv_backup
|
||||
- logstash.nodes
|
||||
- logstash.soc_logstash
|
||||
- logstash.adv_logstash
|
||||
- elasticfleet.soc_elasticfleet
|
||||
- elasticfleet.adv_elasticfleet
|
||||
- data.*
|
||||
- secrets
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
|
||||
'*_desktop':
|
||||
'*_idh':
|
||||
- data.*
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
|
||||
'*_searchnode':
|
||||
- logstash
|
||||
- logstash.search
|
||||
- elasticsearch.index_templates
|
||||
- elasticsearch.auth
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
- data.nodestab
|
||||
|
||||
'*_receiver':
|
||||
- logstash
|
||||
- logstash.receiver
|
||||
- elasticsearch.auth
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
|
||||
'*_import':
|
||||
- zeeklogs
|
||||
- secrets
|
||||
- elasticsearch.index_templates
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/elasticsearch/auth.sls') %}
|
||||
- elasticsearch.auth
|
||||
{% endif %}
|
||||
{% if salt['file.file_exists']('/opt/so/saltstack/local/pillar/kibana/secrets.sls') %}
|
||||
- kibana.secrets
|
||||
{% endif %}
|
||||
- global
|
||||
- minions.{{ grains.id }}
|
||||
|
||||
'*_workstation':
|
||||
- minions.{{ grains.id }}
|
||||
- minions.adv_{{ grains.id }}
|
||||
- stig.soc_stig
|
||||
- soc.license
|
||||
|
||||
@@ -1 +1,70 @@
|
||||
zeek:
|
||||
zeekctl:
|
||||
MailTo: root@localhost
|
||||
MailConnectionSummary: 1
|
||||
MinDiskSpace: 5
|
||||
MailHostUpDown: 1
|
||||
LogRotationInterval: 3600
|
||||
LogExpireInterval: 0
|
||||
StatsLogEnable: 1
|
||||
StatsLogExpireInterval: 0
|
||||
StatusCmdShowAll: 0
|
||||
CrashExpireInterval: 0
|
||||
SitePolicyScripts: local.zeek
|
||||
LogDir: /nsm/zeek/logs
|
||||
SpoolDir: /nsm/zeek/spool
|
||||
CfgDir: /opt/zeek/etc
|
||||
CompressLogs: 1
|
||||
ZeekPort: 27760
|
||||
local:
|
||||
'@load':
|
||||
- misc/loaded-scripts
|
||||
- tuning/defaults
|
||||
- misc/capture-loss
|
||||
- misc/stats
|
||||
- frameworks/software/vulnerable
|
||||
- frameworks/software/version-changes
|
||||
- protocols/ftp/software
|
||||
- protocols/smtp/software
|
||||
- protocols/ssh/software
|
||||
- protocols/http/software
|
||||
- protocols/dns/detect-external-names
|
||||
- protocols/ftp/detect
|
||||
- protocols/conn/known-hosts
|
||||
- protocols/conn/known-services
|
||||
- protocols/ssl/known-certs
|
||||
- protocols/ssl/validate-certs
|
||||
- protocols/ssl/log-hostcerts-only
|
||||
- protocols/ssh/geo-data
|
||||
- protocols/ssh/detect-bruteforcing
|
||||
- protocols/ssh/interesting-hostnames
|
||||
- protocols/http/detect-sqli
|
||||
- frameworks/files/hash-all-files
|
||||
- frameworks/files/detect-MHR
|
||||
- policy/frameworks/notice/extend-email/hostnames
|
||||
- policy/frameworks/notice/community-id
|
||||
- policy/protocols/conn/community-id-logging
|
||||
- ja3
|
||||
- hassh
|
||||
- intel
|
||||
- cve-2020-0601
|
||||
- securityonion/bpfconf
|
||||
- securityonion/file-extraction
|
||||
- oui-logging
|
||||
- icsnpp-modbus
|
||||
- icsnpp-dnp3
|
||||
- icsnpp-bacnet
|
||||
- icsnpp-ethercat
|
||||
- icsnpp-enip
|
||||
- icsnpp-opcua-binary
|
||||
- icsnpp-bsap
|
||||
- icsnpp-s7comm
|
||||
- zeek-plugin-tds
|
||||
- zeek-plugin-profinet
|
||||
- zeek-spicy-wireguard
|
||||
- zeek-spicy-stun
|
||||
'@load-sigs':
|
||||
- frameworks/signatures/detect-windows-shells
|
||||
redef:
|
||||
- LogAscii::use_json = T;
|
||||
- CaptureLoss::watch_interval = 5 mins;
|
||||
|
||||
30
pyci.sh
@@ -1,30 +0,0 @@
|
||||
#!/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.
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 <python_script_dir>"
|
||||
echo "Runs tests on all *_test.py files in the given directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HOME_DIR=$(dirname "$0")
|
||||
TARGET_DIR=${1:-.}
|
||||
|
||||
PATH=$PATH:/usr/local/bin
|
||||
|
||||
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
|
||||
|
||||
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"
|
||||
@@ -3,14 +3,14 @@ import subprocess
|
||||
|
||||
def check():
|
||||
|
||||
osfam = __grains__['os_family']
|
||||
os = __grains__['os']
|
||||
retval = 'False'
|
||||
|
||||
if osfam == 'Debian':
|
||||
if os == 'Ubuntu':
|
||||
if path.exists('/var/run/reboot-required'):
|
||||
retval = 'True'
|
||||
|
||||
elif osfam == 'RedHat':
|
||||
elif os == 'CentOS':
|
||||
cmd = 'needs-restarting -r > /dev/null 2>&1'
|
||||
|
||||
try:
|
||||
|
||||
@@ -5,8 +5,6 @@ import logging
|
||||
def status():
|
||||
return __salt__['cmd.run']('/usr/sbin/so-status')
|
||||
|
||||
def version():
|
||||
return __salt__['cp.get_file_str']('/etc/soversion')
|
||||
|
||||
def mysql_conn(retry):
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -63,4 +61,4 @@ def mysql_conn(retry):
|
||||
for addr in ip_arr:
|
||||
log.debug(f' - {addr}')
|
||||
|
||||
return mysql_up
|
||||
return mysql_up
|
||||
@@ -1,8 +1,18 @@
|
||||
# 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 ZEEKVER = salt['pillar.get']('global:mdengine', '') %}
|
||||
{% set WAZUH = salt['pillar.get']('global:wazuh', '0') %}
|
||||
{% set PLAYBOOK = salt['pillar.get']('manager:playbook', '0') %}
|
||||
{% set FREQSERVER = salt['pillar.get']('manager:freq', '0') %}
|
||||
{% set DOMAINSTATS = salt['pillar.get']('manager:domainstats', '0') %}
|
||||
{% set FLEETMANAGER = salt['pillar.get']('global:fleet_manager', False) %}
|
||||
{% set FLEETNODE = salt['pillar.get']('global:fleet_node', False) %}
|
||||
{% set ELASTALERT = salt['pillar.get']('elastalert:enabled', True) %}
|
||||
{% set ELASTICSEARCH = salt['pillar.get']('elasticsearch:enabled', True) %}
|
||||
{% set FILEBEAT = salt['pillar.get']('filebeat:enabled', True) %}
|
||||
{% set KIBANA = salt['pillar.get']('kibana:enabled', True) %}
|
||||
{% set LOGSTASH = salt['pillar.get']('logstash:enabled', True) %}
|
||||
{% set CURATOR = salt['pillar.get']('curator:enabled', True) %}
|
||||
{% set REDIS = salt['pillar.get']('redis:enabled', True) %}
|
||||
{% set STRELKA = salt['pillar.get']('strelka:enabled', '0') %}
|
||||
{% set ISAIRGAP = salt['pillar.get']('global:airgap', False) %}
|
||||
{% import_yaml 'salt/minion.defaults.yaml' as saltversion %}
|
||||
{% set saltversion = saltversion.salt.minion.version %}
|
||||
@@ -22,11 +32,9 @@
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'influxdb',
|
||||
'grafana',
|
||||
'soc',
|
||||
'kratos',
|
||||
'hydra',
|
||||
'elasticfleet',
|
||||
'elastic-fleet-package-registry',
|
||||
'firewall',
|
||||
'idstools',
|
||||
'suricata.manager',
|
||||
@@ -35,8 +43,10 @@
|
||||
'suricata',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'tcpreplay',
|
||||
'docker_clean'
|
||||
'docker_clean',
|
||||
'learn'
|
||||
],
|
||||
'so-heavynode': [
|
||||
'ssl',
|
||||
@@ -46,15 +56,46 @@
|
||||
'pcap',
|
||||
'suricata',
|
||||
'healthcheck',
|
||||
'elasticagent',
|
||||
'schedule',
|
||||
'tcpreplay',
|
||||
'docker_clean'
|
||||
],
|
||||
'so-helixsensor': [
|
||||
'salt.master',
|
||||
'ca',
|
||||
'ssl',
|
||||
'registry',
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'idstools',
|
||||
'suricata.manager',
|
||||
'zeek',
|
||||
'redis',
|
||||
'elasticsearch',
|
||||
'logstash',
|
||||
'schedule',
|
||||
'tcpreplay',
|
||||
'docker_clean'
|
||||
],
|
||||
'so-fleet': [
|
||||
'ssl',
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'mysql',
|
||||
'redis',
|
||||
'fleet',
|
||||
'fleet.install_package',
|
||||
'filebeat',
|
||||
'schedule',
|
||||
'docker_clean'
|
||||
],
|
||||
'so-idh': [
|
||||
'ssl',
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'fleet.install_package',
|
||||
'filebeat',
|
||||
'idh',
|
||||
'schedule',
|
||||
'docker_clean'
|
||||
@@ -66,12 +107,8 @@
|
||||
'registry',
|
||||
'manager',
|
||||
'nginx',
|
||||
'strelka.manager',
|
||||
'soc',
|
||||
'kratos',
|
||||
'hydra',
|
||||
'influxdb',
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'idstools',
|
||||
'suricata.manager',
|
||||
@@ -82,8 +119,7 @@
|
||||
'schedule',
|
||||
'tcpreplay',
|
||||
'docker_clean',
|
||||
'elasticfleet',
|
||||
'elastic-fleet-package-registry'
|
||||
'learn'
|
||||
],
|
||||
'so-manager': [
|
||||
'salt.master',
|
||||
@@ -94,20 +130,17 @@
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'influxdb',
|
||||
'strelka.manager',
|
||||
'grafana',
|
||||
'soc',
|
||||
'kratos',
|
||||
'hydra',
|
||||
'elasticfleet',
|
||||
'elastic-fleet-package-registry',
|
||||
'firewall',
|
||||
'idstools',
|
||||
'suricata.manager',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'docker_clean',
|
||||
'stig',
|
||||
'kafka'
|
||||
'learn'
|
||||
],
|
||||
'so-managersearch': [
|
||||
'salt.master',
|
||||
@@ -117,32 +150,26 @@
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'influxdb',
|
||||
'strelka.manager',
|
||||
'grafana',
|
||||
'soc',
|
||||
'kratos',
|
||||
'hydra',
|
||||
'elastic-fleet-package-registry',
|
||||
'elasticfleet',
|
||||
'firewall',
|
||||
'manager',
|
||||
'idstools',
|
||||
'suricata.manager',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'docker_clean',
|
||||
'stig',
|
||||
'kafka'
|
||||
'learn'
|
||||
],
|
||||
'so-searchnode': [
|
||||
'so-node': [
|
||||
'ssl',
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'schedule',
|
||||
'docker_clean',
|
||||
'stig',
|
||||
'kafka.ca',
|
||||
'kafka.ssl'
|
||||
'docker_clean'
|
||||
],
|
||||
'so-standalone': [
|
||||
'salt.master',
|
||||
@@ -153,11 +180,9 @@
|
||||
'nginx',
|
||||
'telegraf',
|
||||
'influxdb',
|
||||
'grafana',
|
||||
'soc',
|
||||
'kratos',
|
||||
'hydra',
|
||||
'elastic-fleet-package-registry',
|
||||
'elasticfleet',
|
||||
'firewall',
|
||||
'idstools',
|
||||
'suricata.manager',
|
||||
@@ -166,10 +191,10 @@
|
||||
'healthcheck',
|
||||
'utility',
|
||||
'schedule',
|
||||
'soctopus',
|
||||
'tcpreplay',
|
||||
'docker_clean',
|
||||
'stig',
|
||||
'kafka'
|
||||
'learn'
|
||||
],
|
||||
'so-sensor': [
|
||||
'ssl',
|
||||
@@ -179,20 +204,10 @@
|
||||
'pcap',
|
||||
'suricata',
|
||||
'healthcheck',
|
||||
'wazuh',
|
||||
'filebeat',
|
||||
'schedule',
|
||||
'tcpreplay',
|
||||
'docker_clean',
|
||||
'stig'
|
||||
],
|
||||
'so-fleet': [
|
||||
'ssl',
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'logstash',
|
||||
'nginx',
|
||||
'healthcheck',
|
||||
'schedule',
|
||||
'elasticfleet',
|
||||
'docker_clean'
|
||||
],
|
||||
'so-receiver': [
|
||||
@@ -200,51 +215,96 @@
|
||||
'telegraf',
|
||||
'firewall',
|
||||
'schedule',
|
||||
'docker_clean',
|
||||
'kafka',
|
||||
'stig'
|
||||
'docker_clean'
|
||||
],
|
||||
'so-desktop': [
|
||||
'ssl',
|
||||
'docker_clean',
|
||||
'telegraf',
|
||||
'stig'
|
||||
'so-workstation': [
|
||||
],
|
||||
}, grain='role') %}
|
||||
|
||||
{%- if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %}
|
||||
{% if FILEBEAT and grains.role in ['so-helixsensor', 'so-eval', 'so-manager', 'so-standalone', 'so-node', 'so-managersearch', 'so-heavynode', 'so-import', 'so-receiver'] %}
|
||||
{% do allowed_states.append('filebeat') %}
|
||||
{% endif %}
|
||||
|
||||
{% if ((FLEETMANAGER or FLEETNODE) or PLAYBOOK != 0) and grains.role in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone'] %}
|
||||
{% do allowed_states.append('mysql') %}
|
||||
{% endif %}
|
||||
|
||||
{% if (FLEETMANAGER or FLEETNODE) and grains.role in ['so-sensor', 'so-eval', 'so-manager', 'so-standalone', 'so-node', 'so-managersearch', 'so-heavynode', 'so-receiver'] %}
|
||||
{% do allowed_states.append('fleet.install_package') %}
|
||||
{% endif %}
|
||||
|
||||
{% if (FLEETMANAGER or FLEETNODE) and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode'] %}
|
||||
{% do allowed_states.append('fleet') %}
|
||||
{% endif %}
|
||||
|
||||
{% if (FLEETMANAGER or FLEETNODE) and grains.role in ['so-eval'] %}
|
||||
{% do allowed_states.append('redis') %}
|
||||
{% endif %}
|
||||
|
||||
{%- if ZEEKVER != 'SURICATA' and grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %}
|
||||
{% do allowed_states.append('zeek') %}
|
||||
{%- endif %}
|
||||
|
||||
{% if grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %}
|
||||
{% if STRELKA and grains.role in ['so-sensor', 'so-eval', 'so-standalone', 'so-heavynode'] %}
|
||||
{% do allowed_states.append('strelka') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-import'] %}
|
||||
{% if WAZUH and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-node', 'so-managersearch', 'so-heavynode', 'so-receiver','so-idh']%}
|
||||
{% do allowed_states.append('wazuh') %}
|
||||
{% endif %}
|
||||
|
||||
{% if ELASTICSEARCH and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-node', 'so-managersearch', 'so-heavynode', 'so-import'] %}
|
||||
{% do allowed_states.append('elasticsearch') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %}
|
||||
{% if ELASTICSEARCH and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %}
|
||||
{% do allowed_states.append('elasticsearch.auth') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %}
|
||||
{% if KIBANA and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %}
|
||||
{% do allowed_states.append('kibana') %}
|
||||
{% do allowed_states.append('kibana.secrets') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
{% if grains.role in ['so-eval', 'so-standalone', 'so-node', 'so-managersearch', 'so-heavynode', 'so-manager'] %}
|
||||
{% do allowed_states.append('curator') %}
|
||||
{% endif %}
|
||||
|
||||
{% if ELASTALERT and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
{% do allowed_states.append('elastalert') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-manager', 'so-standalone', 'so-searchnode', 'so-managersearch', 'so-heavynode', 'so-receiver'] %}
|
||||
{% if (PLAYBOOK !=0) and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
{% do allowed_states.append('playbook') %}
|
||||
{% endif %}
|
||||
|
||||
{% if (PLAYBOOK !=0) and grains.role in ['so-eval'] %}
|
||||
{% do allowed_states.append('redis') %}
|
||||
{% endif %}
|
||||
|
||||
{% if (FREQSERVER !=0) and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
{% do allowed_states.append('freqserver') %}
|
||||
{% endif %}
|
||||
|
||||
{% if (DOMAINSTATS !=0) and grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch'] %}
|
||||
{% do allowed_states.append('domainstats') %}
|
||||
{% endif %}
|
||||
|
||||
{% if LOGSTASH and grains.role in ['so-helixsensor', 'so-manager', 'so-standalone', 'so-node', 'so-managersearch', 'so-heavynode', 'so-receiver'] %}
|
||||
{% do allowed_states.append('logstash') %}
|
||||
{% endif %}
|
||||
|
||||
{% if grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver', 'so-eval'] %}
|
||||
{% if REDIS and grains.role in ['so-manager', 'so-standalone', 'so-managersearch', 'so-heavynode', 'so-receiver'] %}
|
||||
{% do allowed_states.append('redis') %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if grains.os == 'CentOS' %}
|
||||
{% if not ISAIRGAP %}
|
||||
{% do allowed_states.append('yum') %}
|
||||
{% endif %}
|
||||
{% do allowed_states.append('yum.packages') %}
|
||||
{% endif %}
|
||||
|
||||
{# all nodes on the right salt version can run the following states #}
|
||||
{% do allowed_states.append('common') %}
|
||||
{% do allowed_states.append('patch.os.schedule') %}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{% from 'backup/map.jinja' import BACKUP_MERGED %}
|
||||
|
||||
# Lock permissions on the backup directory
|
||||
backupdir:
|
||||
file.directory:
|
||||
- name: /nsm/backup
|
||||
- user: 0
|
||||
- group: 0
|
||||
- makedirs: True
|
||||
- mode: 700
|
||||
|
||||
config_backup_script:
|
||||
file.managed:
|
||||
- name: /usr/sbin/so-config-backup
|
||||
- user: root
|
||||
- group: root
|
||||
- mode: 755
|
||||
- template: jinja
|
||||
- source: salt://backup/tools/sbin/so-config-backup.jinja
|
||||
- defaults:
|
||||
BACKUPLOCATIONS: {{ BACKUP_MERGED.locations }}
|
||||
DESTINATION: {{ BACKUP_MERGED.destination }}
|
||||
|
||||
# Add config backup
|
||||
so_config_backup:
|
||||
cron.present:
|
||||
- name: /usr/sbin/so-config-backup > /dev/null 2>&1
|
||||
- identifier: so_config_backup
|
||||
- user: root
|
||||
- minute: '1'
|
||||
- hour: '0'
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
@@ -1,8 +0,0 @@
|
||||
backup:
|
||||
locations:
|
||||
- /opt/so/saltstack/local
|
||||
- /etc/pki
|
||||
- /etc/salt
|
||||
- /nsm/kratos
|
||||
- /nsm/hydra
|
||||
destination: "/nsm/backup"
|
||||
@@ -1,2 +0,0 @@
|
||||
{% import_yaml 'backup/defaults.yaml' as BACKUP_DEFAULTS %}
|
||||
{% set BACKUP_MERGED = salt['pillar.get']('backup', BACKUP_DEFAULTS.backup, merge=true, merge_nested_lists=true) %}
|
||||
@@ -1,10 +0,0 @@
|
||||
backup:
|
||||
locations:
|
||||
description: List of locations to back up to the destination.
|
||||
helpLink: backup.html
|
||||
global: True
|
||||
destination:
|
||||
description: Directory to store the configuration backups in.
|
||||
helpLink: backup.html
|
||||
global: True
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/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.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
TODAY=$(date '+%Y_%m_%d')
|
||||
BACKUPDIR={{ DESTINATION }}
|
||||
BACKUPFILE="$BACKUPDIR/so-config-backup-$TODAY.tar"
|
||||
MAXBACKUPS=7
|
||||
|
||||
# Create backup dir if it does not exist
|
||||
mkdir -p /nsm/backup
|
||||
|
||||
# If we haven't already written a backup file for today, let's do so
|
||||
if [ ! -f $BACKUPFILE ]; then
|
||||
|
||||
# Create empty backup file
|
||||
tar -cf $BACKUPFILE -T /dev/null
|
||||
|
||||
# Loop through all paths defined in global.sls, and append them to backup file
|
||||
{%- for LOCATION in BACKUPLOCATIONS %}
|
||||
tar -rf $BACKUPFILE {{ LOCATION }}
|
||||
{%- endfor %}
|
||||
|
||||
fi
|
||||
|
||||
# Find oldest backup files and remove them
|
||||
NUMBACKUPS=$(find /nsm/backup/ -type f -name "so-config-backup*" | wc -l)
|
||||
while [ "$NUMBACKUPS" -gt "$MAXBACKUPS" ]; do
|
||||
OLDESTBACKUP=$(find /nsm/backup/ -type f -name "so-config-backup*" -type f -printf '%T+ %p\n' | sort | head -n 1 | awk -F" " '{print $2}')
|
||||
rm -f $OLDESTBACKUP
|
||||
NUMBACKUPS=$(find /nsm/backup/ -type f -name "so-config-backup*" | wc -l)
|
||||
done
|
||||
@@ -1,4 +0,0 @@
|
||||
bpf:
|
||||
pcap: []
|
||||
suricata: []
|
||||
zeek: []
|
||||
@@ -1,10 +0,0 @@
|
||||
{% macro remove_comments(bpfmerged, app) %}
|
||||
|
||||
{# remove comments from the bpf #}
|
||||
{% for bpf in bpfmerged[app] %}
|
||||
{% if bpf.strip().startswith('#') %}
|
||||
{% do bpfmerged[app].pop(loop.index0) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endmacro %}
|
||||
@@ -1,10 +0,0 @@
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
{% if GLOBALS.pcap_engine == "TRANSITION" %}
|
||||
{% set PCAPBPF = ["ip and host 255.255.255.1 and port 1"] %}
|
||||
{% else %}
|
||||
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
||||
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
||||
{% import 'bpf/macros.jinja' as MACROS %}
|
||||
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }}
|
||||
{% set PCAPBPF = BPFMERGED.pcap %}
|
||||
{% endif %}
|
||||
@@ -1,16 +0,0 @@
|
||||
bpf:
|
||||
pcap:
|
||||
description: List of BPF filters to apply to Stenographer.
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: bpf.html
|
||||
suricata:
|
||||
description: List of BPF filters to apply to Suricata.
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: bpf.html
|
||||
zeek:
|
||||
description: List of BPF filters to apply to Zeek.
|
||||
multiline: True
|
||||
forcedType: "[]string"
|
||||
helpLink: bpf.html
|
||||
@@ -1,7 +0,0 @@
|
||||
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
||||
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
||||
{% import 'bpf/macros.jinja' as MACROS %}
|
||||
|
||||
{{ MACROS.remove_comments(BPFMERGED, 'suricata') }}
|
||||
|
||||
{% set SURICATABPF = BPFMERGED.suricata %}
|
||||
@@ -1,7 +0,0 @@
|
||||
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
|
||||
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
|
||||
{% import 'bpf/macros.jinja' as MACROS %}
|
||||
|
||||
{{ MACROS.remove_comments(BPFMERGED, 'zeek') }}
|
||||
|
||||
{% set ZEEKBPF = BPFMERGED.zeek %}
|
||||
@@ -1,3 +1,6 @@
|
||||
mine_functions:
|
||||
x509.get_pem_entries: [/etc/pki/ca.crt]
|
||||
|
||||
x509_signing_policies:
|
||||
filebeat:
|
||||
- minions: '*'
|
||||
@@ -34,7 +37,7 @@ x509_signing_policies:
|
||||
- ST: Utah
|
||||
- L: Salt Lake City
|
||||
- basicConstraints: "critical CA:false"
|
||||
- keyUsage: "critical keyEncipherment digitalSignature"
|
||||
- keyUsage: "critical keyEncipherment, digitalSignature"
|
||||
- subjectKeyIdentifier: hash
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- extendedKeyUsage: serverAuth
|
||||
@@ -54,7 +57,7 @@ x509_signing_policies:
|
||||
- extendedKeyUsage: serverAuth
|
||||
- days_valid: 820
|
||||
- copypath: /etc/pki/issued_certs/
|
||||
elasticfleet:
|
||||
fleet:
|
||||
- minions: '*'
|
||||
- signing_private_key: /etc/pki/ca.key
|
||||
- signing_cert: /etc/pki/ca.crt
|
||||
@@ -62,22 +65,9 @@ x509_signing_policies:
|
||||
- ST: Utah
|
||||
- L: Salt Lake City
|
||||
- basicConstraints: "critical CA:false"
|
||||
- keyUsage: "digitalSignature, nonRepudiation"
|
||||
- keyUsage: "critical keyEncipherment"
|
||||
- subjectKeyIdentifier: hash
|
||||
- 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"
|
||||
- extendedKeyUsage: serverAuth
|
||||
- days_valid: 820
|
||||
- copypath: /etc/pki/issued_certs/
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||
{% if sls in allowed_states %}
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
|
||||
include:
|
||||
- ca.dirs
|
||||
|
||||
{% set manager = salt['grains.get']('master') %}
|
||||
/etc/salt/minion.d/signing_policies.conf:
|
||||
file.managed:
|
||||
- source: salt://ca/files/signing_policies.conf
|
||||
@@ -18,8 +12,9 @@ include:
|
||||
pki_private_key:
|
||||
x509.private_key_managed:
|
||||
- name: /etc/pki/ca.key
|
||||
- keysize: 4096
|
||||
- bits: 4096
|
||||
- passphrase:
|
||||
- cipher: aes_256_cbc
|
||||
- backup: True
|
||||
{% if salt['file.file_exists']('/etc/pki/ca.key') -%}
|
||||
- prereq:
|
||||
@@ -30,7 +25,7 @@ pki_public_ca_crt:
|
||||
x509.certificate_managed:
|
||||
- name: /etc/pki/ca.crt
|
||||
- signing_private_key: /etc/pki/ca.key
|
||||
- CN: {{ GLOBALS.manager }}
|
||||
- CN: {{ manager }}
|
||||
- C: US
|
||||
- ST: Utah
|
||||
- L: Salt Lake City
|
||||
@@ -38,7 +33,7 @@ pki_public_ca_crt:
|
||||
- keyUsage: "critical cRLSign, keyCertSign"
|
||||
- extendedkeyUsage: "serverAuth, clientAuth"
|
||||
- subjectKeyIdentifier: hash
|
||||
- authorityKeyIdentifier: keyid:always, issuer
|
||||
- authorityKeyIdentifier: keyid,issuer:always
|
||||
- days_valid: 3650
|
||||
- days_remaining: 0
|
||||
- backup: True
|
||||
@@ -50,12 +45,6 @@ pki_public_ca_crt:
|
||||
attempts: 5
|
||||
interval: 30
|
||||
|
||||
mine_update_ca_crt:
|
||||
module.run:
|
||||
- mine.update: []
|
||||
- onchanges:
|
||||
- x509: pki_public_ca_crt
|
||||
|
||||
cakeyperms:
|
||||
file.managed:
|
||||
- replace: False
|
||||
|
||||
2
salt/common/cron/common-rotate
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
/usr/sbin/logrotate -f /opt/so/conf/log-rotate.conf > /dev/null 2>&1
|
||||
2
salt/common/cron/sensor-rotate
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
/usr/sbin/logrotate -f /opt/so/conf/sensor-rotate.conf > /dev/null 2>&1
|
||||
79
salt/common/files/analyst/README
Normal file
@@ -0,0 +1,79 @@
|
||||
The following GUI tools are available on the analyst workstation:
|
||||
|
||||
chromium
|
||||
url: https://www.chromium.org/Home
|
||||
To run chromium, click Applications > Internet > Chromium Web Browser
|
||||
|
||||
Wireshark
|
||||
url: https://www.wireshark.org/
|
||||
To run Wireshark, click Applications > Internet > Wireshark Network Analyzer
|
||||
|
||||
NetworkMiner
|
||||
url: https://www.netresec.com
|
||||
To run NetworkMiner, click Applications > Internet > NetworkMiner
|
||||
|
||||
The following CLI tools are available on the analyst workstation:
|
||||
|
||||
bit-twist
|
||||
url: http://bittwist.sourceforge.net
|
||||
To run bit-twist, open a terminal and type: bittwist -h
|
||||
|
||||
chaosreader
|
||||
url: http://chaosreader.sourceforge.net
|
||||
To run chaosreader, open a terminal and type: chaosreader -h
|
||||
|
||||
dnsiff
|
||||
url: https://www.monkey.org/~dugsong/dsniff/
|
||||
To run dsniff, open a terminal and type: dsniff -h
|
||||
|
||||
foremost
|
||||
url: http://foremost.sourceforge.net
|
||||
To run foremost, open a terminal and type: foremost -h
|
||||
|
||||
hping3
|
||||
url: http://www.hping.org/hping3.html
|
||||
To run hping3, open a terminal and type: hping3 -h
|
||||
|
||||
netsed
|
||||
url: http://silicone.homelinux.org/projects/netsed/
|
||||
To run netsed, open a terminal and type: netsed -h
|
||||
|
||||
ngrep
|
||||
url: https://github.com/jpr5/ngrep
|
||||
To run ngrep, open a terminal and type: ngrep -h
|
||||
|
||||
scapy
|
||||
url: http://www.secdev.org/projects/scapy/
|
||||
To run scapy, open a terminal and type: scapy
|
||||
|
||||
ssldump
|
||||
url: http://www.rtfm.com/ssldump/
|
||||
To run ssldump, open a terminal and type: ssldump -h
|
||||
|
||||
sslsplit
|
||||
url: https://github.com/droe/sslsplit
|
||||
To run sslsplit, open a terminal and type: sslsplit -h
|
||||
|
||||
tcpdump
|
||||
url: http://www.tcpdump.org
|
||||
To run tcpdump, open a terminal and type: tcpdump -h
|
||||
|
||||
tcpflow
|
||||
url: https://github.com/simsong/tcpflow
|
||||
To run tcpflow, open a terminal and type: tcpflow -h
|
||||
|
||||
tcpstat
|
||||
url: https://frenchfries.net/paul/tcpstat/
|
||||
To run tcpstat, open a terminal and type: tcpstat -h
|
||||
|
||||
tcptrace
|
||||
url: http://www.tcptrace.org
|
||||
To run tcptrace, open a terminal and type: tcptrace -h
|
||||
|
||||
tcpxtract
|
||||
url: http://tcpxtract.sourceforge.net/
|
||||
To run tcpxtract, open a terminal and type: tcpxtract -h
|
||||
|
||||
whois
|
||||
url: http://www.linux.it/~md/software/
|
||||
To run whois, open a terminal and type: whois -h
|
||||
|
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 269 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 319 KiB |
@@ -1,12 +1,12 @@
|
||||
{%- set DOCKERRANGE = salt['pillar.get']('docker:range', '172.17.0.0/24') %}
|
||||
{%- set DOCKERBIND = salt['pillar.get']('docker:bip', '172.17.0.1/24') %}
|
||||
{
|
||||
"registry-mirrors": [
|
||||
"https://:5000"
|
||||
],
|
||||
"bip": "172.17.0.1/24",
|
||||
"default-address-pools": [
|
||||
{
|
||||
"base": "172.17.0.0/24",
|
||||
"size": 24
|
||||
}
|
||||
]
|
||||
"registry-mirrors": [ "https://:5000" ],
|
||||
"bip": "{{ DOCKERBIND }}",
|
||||
"default-address-pools": [
|
||||
{
|
||||
"base" : "{{ DOCKERRANGE }}",
|
||||
"size" : 24
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
37
salt/common/files/log-rotate.conf
Normal file
@@ -0,0 +1,37 @@
|
||||
{%- set logrotate_conf = salt['pillar.get']('logrotate:conf') %}
|
||||
{%- set group_conf = salt['pillar.get']('logrotate:group_conf') %}
|
||||
|
||||
|
||||
/opt/so/log/aptcacher-ng/*.log
|
||||
/opt/so/log/idstools/*.log
|
||||
/opt/so/log/nginx/*.log
|
||||
/opt/so/log/soc/*.log
|
||||
/opt/so/log/kratos/*.log
|
||||
/opt/so/log/kibana/*.log
|
||||
/opt/so/log/influxdb/*.log
|
||||
/opt/so/log/elastalert/*.log
|
||||
/opt/so/log/soctopus/*.log
|
||||
/opt/so/log/curator/*.log
|
||||
/opt/so/log/fleet/*.log
|
||||
/opt/so/log/suricata/*.log
|
||||
/opt/so/log/mysql/*.log
|
||||
/opt/so/log/telegraf/*.log
|
||||
/opt/so/log/redis/*.log
|
||||
/opt/so/log/sensoroni/*.log
|
||||
/opt/so/log/stenographer/*.log
|
||||
/opt/so/log/salt/so-salt-minion-check
|
||||
/opt/so/log/salt/minion
|
||||
/opt/so/log/salt/master
|
||||
/opt/so/log/logscan/*.log
|
||||
/nsm/idh/*.log
|
||||
{
|
||||
{{ logrotate_conf | indent(width=4) }}
|
||||
}
|
||||
|
||||
# Playbook's log directory needs additional configuration
|
||||
# because Playbook requires a more permissive directory
|
||||
/opt/so/log/playbook/*.log
|
||||
{
|
||||
{{ logrotate_conf | indent(width=4) }}
|
||||
{{ group_conf | indent(width=4) }}
|
||||
}
|
||||
35
salt/common/files/sensor-rotate.conf
Normal file
@@ -0,0 +1,35 @@
|
||||
/opt/so/log/sensor_clean.log
|
||||
{
|
||||
daily
|
||||
rotate 2
|
||||
missingok
|
||||
nocompress
|
||||
create
|
||||
sharedscripts
|
||||
}
|
||||
|
||||
/nsm/strelka/log/strelka.log
|
||||
{
|
||||
daily
|
||||
rotate 14
|
||||
missingok
|
||||
copytruncate
|
||||
compress
|
||||
create
|
||||
extension .log
|
||||
dateext
|
||||
dateyesterday
|
||||
}
|
||||
|
||||
/opt/so/log/strelka/filecheck.log
|
||||
{
|
||||
daily
|
||||
rotate 14
|
||||
missingok
|
||||
copytruncate
|
||||
compress
|
||||
create
|
||||
extension .log
|
||||
dateext
|
||||
dateyesterday
|
||||
}
|
||||
@@ -3,3 +3,4 @@ filetype plugin indent on
|
||||
|
||||
" Sets .sls files to use YAML syntax highlighting
|
||||
autocmd BufNewFile,BufRead *.sls set syntax=yaml
|
||||
set number
|
||||
@@ -1,29 +1,25 @@
|
||||
{% from 'allowed_states.map.jinja' import allowed_states %}
|
||||
{% if sls in allowed_states %}
|
||||
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
{% set role = grains.id.split('_') | last %}
|
||||
{% from 'elasticsearch/auth.map.jinja' import ELASTICAUTH with context %}
|
||||
|
||||
include:
|
||||
- common.packages
|
||||
{% if GLOBALS.role in GLOBALS.manager_roles %}
|
||||
- common.soup_scripts
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %}
|
||||
- manager.elasticsearch # needed for elastic_curl_config state
|
||||
- manager.kibana
|
||||
{% endif %}
|
||||
|
||||
net.core.wmem_default:
|
||||
sysctl.present:
|
||||
- value: 26214400
|
||||
|
||||
# Users are not a fan of console messages
|
||||
kernel.printk:
|
||||
sysctl.present:
|
||||
- value: "3 4 1 3"
|
||||
|
||||
# Remove variables.txt from /tmp - This is temp
|
||||
rmvariablesfile:
|
||||
file.absent:
|
||||
- name: /tmp/variables.txt
|
||||
|
||||
dockergroup:
|
||||
group.present:
|
||||
- name: docker
|
||||
- gid: 920
|
||||
|
||||
# Add socore Group
|
||||
socoregroup:
|
||||
group.present:
|
||||
@@ -58,12 +54,13 @@ so-status.conf:
|
||||
- name: /opt/so/conf/so-status/so-status.conf
|
||||
- unless: ls /opt/so/conf/so-status/so-status.conf
|
||||
|
||||
socore_opso_perms:
|
||||
sosaltstackperms:
|
||||
file.directory:
|
||||
- name: /opt/so
|
||||
- name: /opt/so/saltstack
|
||||
- user: 939
|
||||
- group: 939
|
||||
|
||||
- dir_mode: 770
|
||||
|
||||
so_log_perms:
|
||||
file.directory:
|
||||
- name: /opt/so/log
|
||||
@@ -91,6 +88,91 @@ vimconfig:
|
||||
- source: salt://common/files/vimrc
|
||||
- replace: False
|
||||
|
||||
# Install common packages
|
||||
{% if grains['os'] != 'CentOS' %}
|
||||
commonpkgs:
|
||||
pkg.installed:
|
||||
- skip_suggestions: True
|
||||
- pkgs:
|
||||
- apache2-utils
|
||||
- wget
|
||||
- ntpdate
|
||||
- jq
|
||||
- python3-docker
|
||||
- curl
|
||||
- ca-certificates
|
||||
- software-properties-common
|
||||
- apt-transport-https
|
||||
- openssl
|
||||
- netcat
|
||||
- python3-mysqldb
|
||||
- sqlite3
|
||||
- libssl-dev
|
||||
- python3-dateutil
|
||||
- python3-m2crypto
|
||||
- python3-packaging
|
||||
- python3-lxml
|
||||
- git
|
||||
- vim
|
||||
|
||||
heldpackages:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
{% if grains['oscodename'] == 'bionic' %}
|
||||
- containerd.io: 1.4.4-1
|
||||
- docker-ce: 5:20.10.5~3-0~ubuntu-bionic
|
||||
- docker-ce-cli: 5:20.10.5~3-0~ubuntu-bionic
|
||||
- docker-ce-rootless-extras: 5:20.10.5~3-0~ubuntu-bionic
|
||||
{% elif grains['oscodename'] == 'focal' %}
|
||||
- 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
|
||||
{% endif %}
|
||||
- hold: True
|
||||
- update_holds: True
|
||||
|
||||
{% else %}
|
||||
commonpkgs:
|
||||
pkg.installed:
|
||||
- skip_suggestions: True
|
||||
- pkgs:
|
||||
- wget
|
||||
- ntpdate
|
||||
- bind-utils
|
||||
- jq
|
||||
- tcpdump
|
||||
- httpd-tools
|
||||
- net-tools
|
||||
- curl
|
||||
- sqlite
|
||||
- mariadb-devel
|
||||
- nmap-ncat
|
||||
- python3
|
||||
- python36-docker
|
||||
- python36-dateutil
|
||||
- python36-m2crypto
|
||||
- python36-packaging
|
||||
- python36-lxml
|
||||
- yum-utils
|
||||
- device-mapper-persistent-data
|
||||
- lvm2
|
||||
- openssl
|
||||
- git
|
||||
- vim-enhanced
|
||||
|
||||
heldpackages:
|
||||
pkg.installed:
|
||||
- pkgs:
|
||||
- containerd.io: 1.4.4-3.1.el7
|
||||
- docker-ce: 3:20.10.5-3.el7
|
||||
- docker-ce-cli: 1:20.10.5-3.el7
|
||||
- docker-ce-rootless-extras: 20.10.5-3.el7
|
||||
- python36-mysql: 1.3.12-2.el7
|
||||
- hold: True
|
||||
- update_holds: True
|
||||
{% endif %}
|
||||
|
||||
# Always keep these packages up to date
|
||||
|
||||
alwaysupdated:
|
||||
@@ -105,8 +187,7 @@ alwaysupdated:
|
||||
Etc/UTC:
|
||||
timezone.system
|
||||
|
||||
# Sync curl configuration for Elasticsearch authentication
|
||||
{% if GLOBALS.role in ['so-eval', 'so-heavynode', 'so-import', 'so-manager', 'so-managersearch', 'so-searchnode', 'so-standalone'] %}
|
||||
{% if salt['pillar.get']('elasticsearch:auth:enabled', False) %}
|
||||
elastic_curl_config:
|
||||
file.managed:
|
||||
- name: /opt/so/conf/elasticsearch/curl.config
|
||||
@@ -114,82 +195,87 @@ elastic_curl_config:
|
||||
- mode: 600
|
||||
- show_changes: False
|
||||
- makedirs: True
|
||||
{% if GLOBALS.role in GLOBALS.manager_roles %}
|
||||
{% if grains.role in ['so-eval', 'so-manager', 'so-standalone', 'so-managersearch', 'so-import'] %}
|
||||
- require:
|
||||
- file: elastic_curl_config_distributed
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
common_sbin:
|
||||
# Sync some Utilities
|
||||
utilsyncscripts:
|
||||
file.recurse:
|
||||
- name: /usr/sbin
|
||||
- source: salt://common/tools/sbin
|
||||
- user: 939
|
||||
- group: 939
|
||||
- file_mode: 755
|
||||
- show_changes: False
|
||||
{% if GLOBALS.role == 'so-heavynode' %}
|
||||
- exclude_pat:
|
||||
- so-pcap-import
|
||||
{% endif %}
|
||||
|
||||
common_sbin_jinja:
|
||||
file.recurse:
|
||||
- name: /usr/sbin
|
||||
- source: salt://common/tools/sbin_jinja
|
||||
- user: 939
|
||||
- group: 939
|
||||
- user: root
|
||||
- group: root
|
||||
- file_mode: 755
|
||||
- template: jinja
|
||||
- show_changes: False
|
||||
{% if GLOBALS.role == 'so-heavynode' %}
|
||||
- source: salt://common/tools/sbin
|
||||
- defaults:
|
||||
ELASTICCURL: 'curl'
|
||||
- context:
|
||||
ELASTICCURL: {{ ELASTICAUTH.elasticcurl }}
|
||||
- exclude_pat:
|
||||
- so-import-pcap
|
||||
{% endif %}
|
||||
- so-common
|
||||
- so-firewall
|
||||
- so-image-common
|
||||
- soup
|
||||
|
||||
{% if GLOBALS.role == 'so-heavynode' %}
|
||||
remove_so-pcap-import_heavynode:
|
||||
file.absent:
|
||||
- name: /usr/sbin/so-pcap-import
|
||||
|
||||
remove_so-import-pcap_heavynode:
|
||||
file.absent:
|
||||
- name: /usr/sbin/so-import-pcap
|
||||
{% endif %}
|
||||
|
||||
{% if not GLOBALS.is_manager%}
|
||||
# prior to 2.4.50 these scripts were in common/tools/sbin on the manager because of soup and distributed to non managers
|
||||
# these two states remove the scripts from non manager nodes
|
||||
remove_soup:
|
||||
file.absent:
|
||||
- name: /usr/sbin/soup
|
||||
|
||||
remove_so-firewall:
|
||||
file.absent:
|
||||
- name: /usr/sbin/so-firewall
|
||||
{% endif %}
|
||||
|
||||
so-status_script:
|
||||
file.managed:
|
||||
- name: /usr/sbin/so-status
|
||||
- source: salt://common/tools/sbin/so-status
|
||||
- mode: 755
|
||||
|
||||
{% if GLOBALS.role in GLOBALS.sensor_roles %}
|
||||
{% if role in ['eval', 'standalone', 'sensor', 'heavynode'] %}
|
||||
# Add sensor cleanup
|
||||
so-sensor-clean:
|
||||
/usr/sbin/so-sensor-clean:
|
||||
cron.present:
|
||||
- name: /usr/sbin/so-sensor-clean
|
||||
- identifier: so-sensor-clean
|
||||
- user: root
|
||||
- minute: '*'
|
||||
- hour: '*'
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
|
||||
sensorrotatescript:
|
||||
file.managed:
|
||||
- name: /usr/local/bin/sensor-rotate
|
||||
- source: salt://common/cron/sensor-rotate
|
||||
- mode: 755
|
||||
|
||||
sensorrotateconf:
|
||||
file.managed:
|
||||
- name: /opt/so/conf/sensor-rotate.conf
|
||||
- source: salt://common/files/sensor-rotate.conf
|
||||
- mode: 644
|
||||
|
||||
/usr/local/bin/sensor-rotate:
|
||||
cron.present:
|
||||
- user: root
|
||||
- minute: '1'
|
||||
- hour: '0'
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
|
||||
{% endif %}
|
||||
|
||||
commonlogrotatescript:
|
||||
file.managed:
|
||||
- name: /usr/local/bin/common-rotate
|
||||
- source: salt://common/cron/common-rotate
|
||||
- mode: 755
|
||||
|
||||
commonlogrotateconf:
|
||||
file.managed:
|
||||
- name: /opt/so/conf/log-rotate.conf
|
||||
- source: salt://common/files/log-rotate.conf
|
||||
- template: jinja
|
||||
- mode: 644
|
||||
|
||||
/usr/local/bin/common-rotate:
|
||||
cron.present:
|
||||
- user: root
|
||||
- minute: '1'
|
||||
- hour: '0'
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
|
||||
# Create the status directory
|
||||
sostatusdir:
|
||||
file.directory:
|
||||
@@ -202,13 +288,10 @@ sostatus_log:
|
||||
file.managed:
|
||||
- name: /opt/so/log/sostatus/status.log
|
||||
- mode: 644
|
||||
- replace: False
|
||||
|
||||
# Install sostatus check cron. This is used to populate Grid.
|
||||
so-status_check_cron:
|
||||
|
||||
# Install sostatus check cron
|
||||
'/usr/sbin/so-status -q; echo $? > /opt/so/log/sostatus/status.log 2>&1':
|
||||
cron.present:
|
||||
- name: '/usr/sbin/so-status -j > /opt/so/log/sostatus/status.log 2>&1'
|
||||
- identifier: so-status_check_cron
|
||||
- user: root
|
||||
- minute: '*/1'
|
||||
- hour: '*'
|
||||
@@ -216,21 +299,36 @@ so-status_check_cron:
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
|
||||
# This cronjob/script runs a check if the node needs restarted, but should be used for future status checks as well
|
||||
common_status_check_cron:
|
||||
{% if role in ['eval', 'manager', 'managersearch', 'standalone'] %}
|
||||
# Install cron job to determine size of influxdb for telegraf
|
||||
'du -s -k /nsm/influxdb | cut -f1 > /opt/so/log/telegraf/influxdb_size.log 2>&1':
|
||||
cron.present:
|
||||
- name: '/usr/sbin/so-common-status-check > /dev/null 2>&1'
|
||||
- identifier: common_status_check
|
||||
- user: root
|
||||
- minute: '*/10'
|
||||
|
||||
remove_post_setup_cron:
|
||||
cron.absent:
|
||||
- name: 'PATH=$PATH:/usr/sbin salt-call state.highstate'
|
||||
- identifier: post_setup_cron
|
||||
|
||||
{% if GLOBALS.role not in ['eval', 'manager', 'managersearch', 'standalone'] %}
|
||||
|
||||
- minute: '*/1'
|
||||
- hour: '*'
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
|
||||
# Lock permissions on the backup directory
|
||||
backupdir:
|
||||
file.directory:
|
||||
- name: /nsm/backup
|
||||
- user: 0
|
||||
- group: 0
|
||||
- makedirs: True
|
||||
- mode: 700
|
||||
|
||||
# Add config backup
|
||||
/usr/sbin/so-config-backup > /dev/null 2>&1:
|
||||
cron.present:
|
||||
- user: root
|
||||
- minute: '1'
|
||||
- hour: '0'
|
||||
- daymonth: '*'
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
{% else %}
|
||||
soversionfile:
|
||||
file.managed:
|
||||
- name: /etc/soversion
|
||||
@@ -240,8 +338,34 @@ soversionfile:
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if GLOBALS.so_model and GLOBALS.so_model not in ['SO2AMI01', 'SO2AZI01', 'SO2GCI01'] %}
|
||||
{% if GLOBALS.os == 'OEL' %}
|
||||
# Manager daemon.json
|
||||
docker_daemon:
|
||||
file.managed:
|
||||
- source: salt://common/files/daemon.json
|
||||
- name: /etc/docker/daemon.json
|
||||
- template: jinja
|
||||
|
||||
# Make sure Docker is always running
|
||||
docker:
|
||||
service.running:
|
||||
- enable: True
|
||||
- watch:
|
||||
- file: docker_daemon
|
||||
|
||||
# Reserve OS ports for Docker proxy in case boot settings are not already applied/present
|
||||
# 55000 = Wazuh, 57314 = Strelka, 47760-47860 = Zeek
|
||||
dockerapplyports:
|
||||
cmd.run:
|
||||
- name: if [ ! -s /etc/sysctl.d/99-reserved-ports.conf ]; then sysctl -w net.ipv4.ip_local_reserved_ports="55000,57314,47760-47860"; fi
|
||||
|
||||
# Reserve OS ports for Docker proxy
|
||||
dockerreserveports:
|
||||
file.managed:
|
||||
- source: salt://common/files/99-reserved-ports.conf
|
||||
- name: /etc/sysctl.d/99-reserved-ports.conf
|
||||
|
||||
{% if salt['grains.get']('sosmodel', '') %}
|
||||
{% if grains['os'] == 'CentOS' %}
|
||||
# Install Raid tools
|
||||
raidpkgs:
|
||||
pkg.installed:
|
||||
@@ -252,10 +376,8 @@ raidpkgs:
|
||||
{% endif %}
|
||||
|
||||
# Install raid check cron
|
||||
so-raid-status:
|
||||
/usr/sbin/so-raid-status > /dev/null 2>&1:
|
||||
cron.present:
|
||||
- name: '/usr/sbin/so-raid-status > /dev/null 2>&1'
|
||||
- identifier: so-raid-status
|
||||
- user: root
|
||||
- minute: '*/15'
|
||||
- hour: '*'
|
||||
@@ -263,7 +385,8 @@ so-raid-status:
|
||||
- month: '*'
|
||||
- dayweek: '*'
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{{sls}}_state_not_allowed:
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
{% from 'vars/globals.map.jinja' import GLOBALS %}
|
||||
|
||||
{% if GLOBALS.os_family == 'Debian' %}
|
||||
commonpkgs:
|
||||
pkg.installed:
|
||||
- skip_suggestions: True
|
||||
- pkgs:
|
||||
- apache2-utils
|
||||
- wget
|
||||
- ntpdate
|
||||
- jq
|
||||
- curl
|
||||
- ca-certificates
|
||||
- software-properties-common
|
||||
- apt-transport-https
|
||||
- openssl
|
||||
- netcat-openbsd
|
||||
- sqlite3
|
||||
- libssl-dev
|
||||
- procps
|
||||
- python3-dateutil
|
||||
- python3-docker
|
||||
- python3-packaging
|
||||
- python3-lxml
|
||||
- git
|
||||
- rsync
|
||||
- vim
|
||||
- tar
|
||||
- unzip
|
||||
- bc
|
||||
{% if grains.oscodename != 'focal' %}
|
||||
- python3-rich
|
||||
{% endif %}
|
||||
|
||||
{% if grains.oscodename == 'focal' %}
|
||||
# since Ubuntu requires and internet connection we can use pip to install modules
|
||||
python3-pip:
|
||||
pkg.installed
|
||||
|
||||
python-rich:
|
||||
pip.installed:
|
||||
- name: rich
|
||||
- target: /usr/local/lib/python3.8/dist-packages/
|
||||
- require:
|
||||
- pkg: python3-pip
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if GLOBALS.os_family == 'RedHat' %}
|
||||
|
||||
remove_mariadb:
|
||||
pkg.removed:
|
||||
- name: mariadb-devel
|
||||
|
||||
commonpkgs:
|
||||
pkg.installed:
|
||||
- skip_suggestions: True
|
||||
- pkgs:
|
||||
- python3-dnf-plugin-versionlock
|
||||
- bc
|
||||
- curl
|
||||
- device-mapper-persistent-data
|
||||
- fuse
|
||||
- fuse-libs
|
||||
- fuse-overlayfs
|
||||
- fuse-common
|
||||
- fuse3
|
||||
- fuse3-libs
|
||||
- git
|
||||
- httpd-tools
|
||||
- jq
|
||||
- lvm2
|
||||
- net-tools
|
||||
- nmap-ncat
|
||||
- procps-ng
|
||||
- python3-docker
|
||||
- python3-m2crypto
|
||||
- python3-packaging
|
||||
- python3-pyyaml
|
||||
- python3-rich
|
||||
- rsync
|
||||
- sqlite
|
||||
- tcpdump
|
||||
- unzip
|
||||
- wget
|
||||
- yum-utils
|
||||
|
||||
{% endif %}
|
||||
@@ -1,142 +1,13 @@
|
||||
# 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 %}
|
||||
{% set SOVERSION = salt['file.read']('/etc/soversion').strip() %}
|
||||
|
||||
remove_common_soup:
|
||||
file.absent:
|
||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/soup
|
||||
|
||||
remove_common_so-firewall:
|
||||
file.absent:
|
||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-firewall
|
||||
|
||||
# This section is used to put the scripts in place in the Salt file system
|
||||
# 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
|
||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-image-common_common_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-image-common
|
||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_soup_manager_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/soup
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-firewall_manager_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-firewall
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall
|
||||
- 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
|
||||
|
||||
copy_bootstrap-salt_manager_tools_sbin:
|
||||
file.copy:
|
||||
- name: /opt/so/saltstack/default/salt/salt/scripts/bootstrap-salt.sh
|
||||
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
||||
- 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
|
||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-image-common_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/so-image-common
|
||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_soup_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/soup
|
||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
copy_so-firewall_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/so-firewall
|
||||
- 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
|
||||
|
||||
copy_bootstrap-salt_sbin:
|
||||
file.copy:
|
||||
- name: /usr/sbin/bootstrap-salt.sh
|
||||
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
||||
- force: True
|
||||
- preserve: True
|
||||
|
||||
{# this is added in 2.4.120 to remove salt repo files pointing to saltproject.io to accomodate the move to broadcom and new bootstrap-salt script #}
|
||||
{% if salt['pkg.version_cmp'](SOVERSION, '2.4.120') == -1 %}
|
||||
{% set saltrepofile = '/etc/yum.repos.d/salt.repo' %}
|
||||
{% if grains.os_family == 'Debian' %}
|
||||
{% set saltrepofile = '/etc/apt/sources.list.d/salt.list' %}
|
||||
{% endif %}
|
||||
remove_saltproject_io_repo_manager:
|
||||
file.absent:
|
||||
- name: {{ saltrepofile }}
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
fix_23_soup_sbin:
|
||||
cmd.run:
|
||||
- name: curl -s -f -o /usr/sbin/soup https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.3/main/salt/common/tools/sbin/soup
|
||||
fix_23_soup_salt:
|
||||
cmd.run:
|
||||
- name: curl -s -f -o /opt/so/saltstack/defalt/salt/common/tools/sbin/soup https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.3/main/salt/common/tools/sbin/soup
|
||||
{% endif %}
|
||||
# Sync some Utilities
|
||||
soup_scripts:
|
||||
file.recurse:
|
||||
- name: /usr/sbin
|
||||
- user: root
|
||||
- group: root
|
||||
- file_mode: 755
|
||||
- source: salt://common/tools/sbin
|
||||
- include_pat:
|
||||
- so-common
|
||||
- so-firewall
|
||||
- so-image-common
|
||||
- soup
|
||||
|
||||
207
salt/common/tools/sbin/so-allow
Executable file
@@ -0,0 +1,207 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ipaddress
|
||||
import textwrap
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
import re
|
||||
from lxml import etree as ET
|
||||
from datetime import datetime as dt
|
||||
from datetime import timezone as tz
|
||||
|
||||
|
||||
LOCAL_SALT_DIR='/opt/so/saltstack/local'
|
||||
WAZUH_CONF='/nsm/wazuh/etc/ossec.conf'
|
||||
VALID_ROLES = {
|
||||
'a': { 'role': 'analyst','desc': 'Analyst - 80/tcp, 443/tcp' },
|
||||
'b': { 'role': 'beats_endpoint', 'desc': 'Logstash Beat - 5044/tcp' },
|
||||
'e': { 'role': 'elasticsearch_rest', 'desc': 'Elasticsearch REST API - 9200/tcp' },
|
||||
'f': { 'role': 'strelka_frontend', 'desc': 'Strelka frontend - 57314/tcp' },
|
||||
'o': { 'role': 'osquery_endpoint', 'desc': 'Osquery endpoint - 8090/tcp' },
|
||||
's': { 'role': 'syslog', 'desc': 'Syslog device - 514/tcp/udp' },
|
||||
'w': { 'role': 'wazuh_agent', 'desc': 'Wazuh agent - 1514/tcp/udp' },
|
||||
'p': { 'role': 'wazuh_api', 'desc': 'Wazuh API - 55000/tcp' },
|
||||
'r': { 'role': 'wazuh_authd', 'desc': 'Wazuh registration service - 1515/tcp' }
|
||||
}
|
||||
|
||||
|
||||
def validate_ip_cidr(ip_cidr: str) -> bool:
|
||||
try:
|
||||
ipaddress.ip_address(ip_cidr)
|
||||
except ValueError:
|
||||
try:
|
||||
ipaddress.ip_network(ip_cidr)
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def role_prompt() -> str:
|
||||
print()
|
||||
print('Choose the role for the IP or Range you would like to allow')
|
||||
print()
|
||||
for role in VALID_ROLES:
|
||||
print(f'[{role}] - {VALID_ROLES[role]["desc"]}')
|
||||
print()
|
||||
role = input('Please enter your selection: ')
|
||||
if role in VALID_ROLES.keys():
|
||||
return VALID_ROLES[role]['role']
|
||||
else:
|
||||
print(f'Invalid role \'{role}\', please try again.', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def ip_prompt() -> str:
|
||||
ip = input('Enter a single ip address or range to allow (ex: 10.10.10.10 or 10.10.0.0/16): ')
|
||||
if validate_ip_cidr(ip):
|
||||
return ip
|
||||
else:
|
||||
print(f'Invalid IP address or CIDR block \'{ip}\', please try again.', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def wazuh_enabled() -> bool:
|
||||
file = f'{LOCAL_SALT_DIR}/pillar/global.sls'
|
||||
with open(file, 'r') as pillar:
|
||||
if 'wazuh: 1' in pillar.read():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def root_to_str(root: ET.ElementTree) -> str:
|
||||
return ET.tostring(root, encoding='unicode', method='xml', xml_declaration=False, pretty_print=True)
|
||||
|
||||
|
||||
def add_wl(ip):
|
||||
parser = ET.XMLParser(remove_blank_text=True)
|
||||
with open(WAZUH_CONF, 'rb') as wazuh_conf:
|
||||
tree = ET.parse(wazuh_conf, parser)
|
||||
root = tree.getroot()
|
||||
|
||||
source_comment = ET.Comment(f'Address {ip} added by /usr/sbin/so-allow on {dt.utcnow().replace(tzinfo=tz.utc).strftime("%a %b %e %H:%M:%S %Z %Y")}')
|
||||
new_global = ET.Element("global")
|
||||
new_wl = ET.SubElement(new_global, 'white_list')
|
||||
new_wl.text = ip
|
||||
|
||||
root.append(source_comment)
|
||||
root.append(new_global)
|
||||
|
||||
with open(WAZUH_CONF, 'w') as add_out:
|
||||
add_out.write(root_to_str(root))
|
||||
|
||||
|
||||
def apply(role: str, ip: str) -> int:
|
||||
firewall_cmd = ['so-firewall', 'includehost', role, ip]
|
||||
salt_cmd = ['salt-call', 'state.apply', '-l', 'quiet', 'firewall', 'queue=True']
|
||||
restart_wazuh_cmd = ['so-wazuh-restart']
|
||||
print(f'Adding {ip} to the {role} role. This can take a few seconds...')
|
||||
cmd = subprocess.run(firewall_cmd)
|
||||
if cmd.returncode == 0:
|
||||
cmd = subprocess.run(salt_cmd, stdout=subprocess.DEVNULL)
|
||||
else:
|
||||
return cmd.returncode
|
||||
if cmd.returncode == 0:
|
||||
if wazuh_enabled() and role=='analyst':
|
||||
try:
|
||||
add_wl(ip)
|
||||
print(f'Added whitelist entry for {ip} from {WAZUH_CONF}', file=sys.stderr)
|
||||
except Exception as e:
|
||||
print(f'Failed to add whitelist entry for {ip} from {WAZUH_CONF}', file=sys.stderr)
|
||||
print(e)
|
||||
return 1
|
||||
print('Restarting OSSEC Server...')
|
||||
cmd = subprocess.run(restart_wazuh_cmd)
|
||||
else:
|
||||
return cmd.returncode
|
||||
else:
|
||||
print(f'Commmand \'{" ".join(salt_cmd)}\' failed.', file=sys.stderr)
|
||||
return cmd.returncode
|
||||
if cmd.returncode != 0:
|
||||
print('Failed to restart OSSEC server.')
|
||||
return cmd.returncode
|
||||
|
||||
|
||||
def main():
|
||||
if os.geteuid() != 0:
|
||||
print('You must run this script as root', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
main_parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=textwrap.dedent(f'''\
|
||||
additional information:
|
||||
To use this script in interactive mode call it with no arguments
|
||||
'''
|
||||
))
|
||||
|
||||
group = main_parser.add_argument_group(title='roles')
|
||||
group.add_argument('-a', dest='roles', action='append_const', const=VALID_ROLES['a']['role'], help="Analyst - 80/tcp, 443/tcp")
|
||||
group.add_argument('-b', dest='roles', action='append_const', const=VALID_ROLES['b']['role'], help="Logstash Beat - 5044/tcp")
|
||||
group.add_argument('-e', dest='roles', action='append_const', const=VALID_ROLES['e']['role'], help="Elasticsearch REST API - 9200/tcp")
|
||||
group.add_argument('-f', dest='roles', action='append_const', const=VALID_ROLES['f']['role'], help="Strelka frontend - 57314/tcp")
|
||||
group.add_argument('-o', dest='roles', action='append_const', const=VALID_ROLES['o']['role'], help="Osquery endpoint - 8090/tcp")
|
||||
group.add_argument('-s', dest='roles', action='append_const', const=VALID_ROLES['s']['role'], help="Syslog device - 514/tcp/udp")
|
||||
group.add_argument('-w', dest='roles', action='append_const', const=VALID_ROLES['w']['role'], help="Wazuh agent - 1514/tcp/udp")
|
||||
group.add_argument('-p', dest='roles', action='append_const', const=VALID_ROLES['p']['role'], help="Wazuh API - 55000/tcp")
|
||||
group.add_argument('-r', dest='roles', action='append_const', const=VALID_ROLES['r']['role'], help="Wazuh registration service - 1515/tcp")
|
||||
|
||||
ip_g = main_parser.add_argument_group(title='allow')
|
||||
ip_g.add_argument('-i', help="IP or CIDR block to disallow connections from, requires at least one role argument", metavar='', dest='ip')
|
||||
|
||||
args = main_parser.parse_args(sys.argv[1:])
|
||||
|
||||
if args.roles is None:
|
||||
role = role_prompt()
|
||||
ip = ip_prompt()
|
||||
try:
|
||||
return_code = apply(role, ip)
|
||||
except Exception as e:
|
||||
print(f'Unexpected exception occurred: {e}', file=sys.stderr)
|
||||
return_code = e.errno
|
||||
sys.exit(return_code)
|
||||
elif args.roles is not None and args.ip is None:
|
||||
if os.environ.get('IP') is None:
|
||||
main_parser.print_help()
|
||||
sys.exit(1)
|
||||
else:
|
||||
args.ip = os.environ['IP']
|
||||
|
||||
if validate_ip_cidr(args.ip):
|
||||
try:
|
||||
for role in args.roles:
|
||||
return_code = apply(role, args.ip)
|
||||
if return_code > 0:
|
||||
break
|
||||
except Exception as e:
|
||||
print(f'Unexpected exception occurred: {e}', file=sys.stderr)
|
||||
return_code = e.errno
|
||||
else:
|
||||
print(f'Invalid IP address or CIDR block \'{args.ip}\', please try again.', file=sys.stderr)
|
||||
return_code = 1
|
||||
|
||||
sys.exit(return_code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(1)
|
||||
|
||||
23
salt/common/tools/sbin/so-allow-view
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
echo ""
|
||||
echo "Hosts/Networks that have access to login to the Security Onion Console:"
|
||||
|
||||
so-firewall includedhosts analyst
|
||||
100
salt/common/tools/sbin/so-analyst-install
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
doc_workstation_url="https://docs.securityonion.net/en/2.3/analyst-vm.html"
|
||||
{# we only want the script to install the workstation if it is CentOS -#}
|
||||
{% if grains.os == 'CentOS' -%}
|
||||
{# if this is a manager -#}
|
||||
{% if grains.master == grains.id.split('_')|first -%}
|
||||
|
||||
source /usr/sbin/so-common
|
||||
pillar_file="/opt/so/saltstack/local/pillar/minions/{{grains.id}}.sls"
|
||||
|
||||
if [ -f "$pillar_file" ]; then
|
||||
if ! grep -q "^workstation:$" "$pillar_file"; then
|
||||
|
||||
FIRSTPASS=yes
|
||||
while [[ $INSTALL != "yes" ]] && [[ $INSTALL != "no" ]]; do
|
||||
if [[ "$FIRSTPASS" == "yes" ]]; then
|
||||
echo "###########################################"
|
||||
echo "## ** W A R N I N G ** ##"
|
||||
echo "## _______________________________ ##"
|
||||
echo "## ##"
|
||||
echo "## Installing the Security Onion ##"
|
||||
echo "## analyst node on this device will ##"
|
||||
echo "## make permanent changes to ##"
|
||||
echo "## the system. ##"
|
||||
echo "## A system reboot will be required ##"
|
||||
echo "## to complete the install. ##"
|
||||
echo "## ##"
|
||||
echo "###########################################"
|
||||
echo "Do you wish to continue? (Type the entire word 'yes' to proceed or 'no' to exit)"
|
||||
FIRSTPASS=no
|
||||
else
|
||||
echo "Please type 'yes' to continue or 'no' to exit."
|
||||
fi
|
||||
read INSTALL
|
||||
done
|
||||
|
||||
if [[ $INSTALL == "no" ]]; then
|
||||
echo "Exiting analyst node installation."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Add workstation pillar to the minion's pillar file
|
||||
printf '%s\n'\
|
||||
"workstation:"\
|
||||
" gui:"\
|
||||
" enabled: true"\
|
||||
"" >> "$pillar_file"
|
||||
echo "Applying the workstation state. This could take some time since there are many packages that need to be installed."
|
||||
if salt-call state.apply workstation -linfo queue=True; then # make sure the state ran successfully
|
||||
echo ""
|
||||
echo "Analyst workstation has been installed!"
|
||||
echo "Press ENTER to reboot or Ctrl-C to cancel."
|
||||
read pause
|
||||
|
||||
reboot;
|
||||
else
|
||||
echo "There was an issue applying the workstation state. Please review the log above or at /opt/so/logs/salt/minion."
|
||||
fi
|
||||
else # workstation is already added
|
||||
echo "The workstation pillar already exists in $pillar_file."
|
||||
echo "To enable/disable the gui, set 'workstation:gui:enabled' to true or false in $pillar_file."
|
||||
echo "Additional documentation can be found at $doc_workstation_url."
|
||||
fi
|
||||
else # if the pillar file doesn't exist
|
||||
echo "Could not find $pillar_file and add the workstation pillar."
|
||||
fi
|
||||
|
||||
{#- if this is not a manager #}
|
||||
{% else -%}
|
||||
|
||||
echo "Since this is not a manager, the pillar values to enable analyst workstation must be set manually. Please view the documentation at $doc_workstation_url."
|
||||
|
||||
{#- endif if this is a manager #}
|
||||
{% endif -%}
|
||||
|
||||
{#- if not CentOS #}
|
||||
{%- else %}
|
||||
|
||||
echo "The Analyst Workstation can only be installed on CentOS. Please view the documentation at $doc_workstation_url."
|
||||
|
||||
{#- endif grains.os == CentOS #}
|
||||
{% endif -%}
|
||||
|
||||
exit 0
|
||||
@@ -1,17 +1,20 @@
|
||||
#!/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.
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
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
|
||||
salt-call state.highstate -l info
|
||||
|
||||
@@ -1,33 +1,26 @@
|
||||
#!/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.
|
||||
|
||||
# Elastic agent is not managed by salt. Because of this we must store this base information in a
|
||||
# script that accompanies the soup system. Since so-common is one of those special soup files,
|
||||
# and since this same logic is required during installation, it's included in this file.
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
DEFAULT_SALT_DIR=/opt/so/saltstack/default
|
||||
DOC_BASE_URL="https://docs.securityonion.net/en/2.4"
|
||||
|
||||
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
|
||||
|
||||
# Ensure /usr/sbin is in path
|
||||
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
|
||||
# Check for prerequisites
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run using sudo!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Define a banner to separate sections
|
||||
@@ -63,53 +56,38 @@ add_interface_bond0() {
|
||||
ethtool -K "$BNIC" $i off &>/dev/null
|
||||
fi
|
||||
done
|
||||
# Check if the bond slave connection has already been created
|
||||
nmcli -f name,uuid -p con | grep -q "bond0-slave-$BNIC"
|
||||
local found_int=$?
|
||||
|
||||
if ! [[ $is_cloud ]]; then
|
||||
# Check if the bond slave connection has already been created
|
||||
nmcli -f name,uuid -p con | grep -q "bond0-slave-$BNIC"
|
||||
local found_int=$?
|
||||
if [[ $found_int != 0 ]]; then
|
||||
# Create the slave interface and assign it to the bond
|
||||
nmcli con add type ethernet ifname "$BNIC" con-name "bond0-slave-$BNIC" master bond0 -- \
|
||||
ethernet.mtu "$MTU" \
|
||||
connection.autoconnect "yes"
|
||||
else
|
||||
local int_uuid
|
||||
int_uuid=$(nmcli -f name,uuid -p con | sed -n "s/bond0-slave-$BNIC //p" | tr -d ' ')
|
||||
|
||||
if [[ $found_int != 0 ]]; then
|
||||
# Create the slave interface and assign it to the bond
|
||||
nmcli con add type ethernet ifname "$BNIC" con-name "bond0-slave-$BNIC" master bond0 -- \
|
||||
ethernet.mtu "$MTU" \
|
||||
connection.autoconnect "yes"
|
||||
else
|
||||
local int_uuid
|
||||
int_uuid=$(nmcli -f name,uuid -p con | sed -n "s/bond0-slave-$BNIC //p" | tr -d ' ')
|
||||
|
||||
nmcli con mod "$int_uuid" \
|
||||
ethernet.mtu "$MTU" \
|
||||
connection.autoconnect "yes"
|
||||
fi
|
||||
fi
|
||||
nmcli con mod "$int_uuid" \
|
||||
ethernet.mtu "$MTU" \
|
||||
connection.autoconnect "yes"
|
||||
fi
|
||||
|
||||
ip link set dev "$BNIC" arp off multicast off allmulticast off promisc on
|
||||
|
||||
if ! [[ $is_cloud ]]; then
|
||||
# Bring the slave interface up
|
||||
if [[ $verbose == true ]]; then
|
||||
nmcli con up "bond0-slave-$BNIC"
|
||||
else
|
||||
nmcli con up "bond0-slave-$BNIC" &>/dev/null
|
||||
fi
|
||||
|
||||
# Bring the slave interface up
|
||||
if [[ $verbose == true ]]; then
|
||||
nmcli con up "bond0-slave-$BNIC"
|
||||
else
|
||||
nmcli con up "bond0-slave-$BNIC" &>/dev/null
|
||||
fi
|
||||
|
||||
if [ "$nic_error" != 0 ]; then
|
||||
return "$nic_error"
|
||||
fi
|
||||
}
|
||||
|
||||
airgap_playbooks() {
|
||||
SRC_DIR=$1
|
||||
# Copy playbooks if using airgap
|
||||
mkdir -p /nsm/airgap-resources
|
||||
# Purge old airgap playbooks to ensure SO only uses the latest released playbooks
|
||||
rm -fr /nsm/airgap-resources/playbooks
|
||||
tar xf $SRC_DIR/airgap-resources/playbooks.tgz -C /nsm/airgap-resources/
|
||||
chown -R socore:socore /nsm/airgap-resources/playbooks
|
||||
git config --global --add safe.directory /nsm/airgap-resources/playbooks
|
||||
}
|
||||
|
||||
check_container() {
|
||||
docker ps | grep "$1:" > /dev/null 2>&1
|
||||
return $?
|
||||
@@ -143,149 +121,56 @@ check_elastic_license() {
|
||||
}
|
||||
|
||||
check_salt_master_status() {
|
||||
local count=0
|
||||
local attempts="${1:- 10}"
|
||||
current_time="$(date '+%b %d %H:%M:%S')"
|
||||
echo "Checking if we can access the salt master and that it is ready at: ${current_time}"
|
||||
while ! salt-call state.show_top -l error concurrent=true 1> /dev/null; do
|
||||
current_time="$(date '+%b %d %H:%M:%S')"
|
||||
echo "Can't access salt master or it is not ready at: ${current_time}"
|
||||
((count+=1))
|
||||
if [[ $count -eq $attempts ]]; then
|
||||
# 10 attempts takes about 5.5 minutes
|
||||
echo "Gave up trying to access salt-master"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
current_time="$(date '+%b %d %H:%M:%S')"
|
||||
echo "Successfully accessed and salt master ready at: ${current_time}"
|
||||
return 0
|
||||
local timeout=$1
|
||||
echo "Checking if we can talk to the salt master"
|
||||
salt-call state.show_top concurrent=true
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
# this is only intended to be used to check the status of the minion from a salt master
|
||||
check_salt_minion_status() {
|
||||
local minion="$1"
|
||||
local timeout="${2:-5}"
|
||||
local logfile="${3:-'/dev/stdout'}"
|
||||
echo "Checking if the salt minion: $minion will respond to jobs" >> "$logfile" 2>&1
|
||||
salt "$minion" test.ping -t $timeout > /dev/null 2>&1
|
||||
local timeout=$1
|
||||
echo "Checking if the salt minion will respond to jobs" >> "$setup_log" 2>&1
|
||||
salt "$MINION_ID" test.ping -t $timeout > /dev/null 2>&1
|
||||
local status=$?
|
||||
if [ $status -gt 0 ]; then
|
||||
echo " Minion did not respond" >> "$logfile" 2>&1
|
||||
echo " Minion did not respond" >> "$setup_log" 2>&1
|
||||
else
|
||||
echo " Received job response from salt minion" >> "$logfile" 2>&1
|
||||
echo " Received job response from salt minion" >> "$setup_log" 2>&1
|
||||
fi
|
||||
|
||||
return $status
|
||||
}
|
||||
|
||||
# Compare es versions and return the highest version
|
||||
compare_es_versions() {
|
||||
# Save the original IFS
|
||||
local OLD_IFS="$IFS"
|
||||
|
||||
IFS=.
|
||||
local i ver1=($1) ver2=($2)
|
||||
|
||||
# Restore the original IFS
|
||||
IFS="$OLD_IFS"
|
||||
|
||||
# Determine the maximum length between the two version arrays
|
||||
local max_len=${#ver1[@]}
|
||||
if [[ ${#ver2[@]} -gt $max_len ]]; then
|
||||
max_len=${#ver2[@]}
|
||||
fi
|
||||
|
||||
# Compare each segment of the versions
|
||||
for ((i=0; i<max_len; i++)); do
|
||||
# If a segment in ver1 or ver2 is missing, set it to 0
|
||||
if [[ -z ${ver1[i]} ]]; then
|
||||
ver1[i]=0
|
||||
fi
|
||||
if [[ -z ${ver2[i]} ]]; then
|
||||
ver2[i]=0
|
||||
fi
|
||||
if ((10#${ver1[i]} > 10#${ver2[i]})); then
|
||||
echo "$1"
|
||||
return 0
|
||||
fi
|
||||
if ((10#${ver1[i]} < 10#${ver2[i]})); then
|
||||
echo "$2"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$1" # If versions are equal, return either
|
||||
return 0
|
||||
}
|
||||
|
||||
copy_new_files() {
|
||||
# Copy new files over to the salt dir
|
||||
cd $UPDATE_DIR
|
||||
rsync -a salt $DEFAULT_SALT_DIR/ --delete
|
||||
rsync -a pillar $DEFAULT_SALT_DIR/ --delete
|
||||
rsync -a salt $DEFAULT_SALT_DIR/
|
||||
rsync -a pillar $DEFAULT_SALT_DIR/
|
||||
chown -R socore:socore $DEFAULT_SALT_DIR/
|
||||
chmod 755 $DEFAULT_SALT_DIR/pillar/firewall/addfirewall.sh
|
||||
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 -p $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
|
||||
}
|
||||
|
||||
download_and_verify() {
|
||||
source_url=$1
|
||||
source_md5_url=$2
|
||||
dest_file=$3
|
||||
md5_file=$4
|
||||
expand_dir=$5
|
||||
|
||||
if [[ -n "$expand_dir" ]]; then
|
||||
mkdir -p "$expand_dir"
|
||||
fi
|
||||
|
||||
if ! verify_md5_checksum "$dest_file" "$md5_file"; then
|
||||
retry 15 10 "curl --fail --retry 5 --retry-delay 15 -L '$source_url' --output '$dest_file'" "" ""
|
||||
retry 15 10 "curl --fail --retry 5 --retry-delay 15 -L '$source_md5_url' --output '$md5_file'" "" ""
|
||||
|
||||
if verify_md5_checksum "$dest_file" "$md5_file"; then
|
||||
echo "Source file and checksum are good."
|
||||
else
|
||||
echo "Unable to download and verify the source file and checksum."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$expand_dir" ]]; then
|
||||
tar -xf "$dest_file" -C "$expand_dir"
|
||||
fi
|
||||
}
|
||||
|
||||
elastic_license() {
|
||||
|
||||
read -r -d '' message <<- EOM
|
||||
\n
|
||||
Elastic Stack binaries and Security Onion components are only available under the Elastic License version 2 (ELv2):
|
||||
https://securityonion.net/license/
|
||||
Starting in Elastic Stack version 7.11, the Elastic Stack binaries are only available under the Elastic License:
|
||||
https://securityonion.net/elastic-license
|
||||
|
||||
Do you agree to the terms of ELv2?
|
||||
Please review the Elastic License:
|
||||
https://www.elastic.co/licensing/elastic-license
|
||||
|
||||
If so, type AGREE to accept ELv2 and continue. Otherwise, press Enter to exit this program without making any changes.
|
||||
Do you agree to the terms of the Elastic License?
|
||||
|
||||
If so, type AGREE to accept the Elastic License and continue. Otherwise, press Enter to exit this program without making any changes.
|
||||
EOM
|
||||
|
||||
AGREED=$(whiptail --title "$whiptail_title" --inputbox \
|
||||
@@ -308,51 +193,25 @@ fail() {
|
||||
exit 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}' | sed 's/,//')
|
||||
[[ -z "$AGENTCOUNT" ]] && AGENTCOUNT="0"
|
||||
else
|
||||
AGENTCOUNT=0
|
||||
fi
|
||||
}
|
||||
|
||||
get_elastic_agent_vars() {
|
||||
local path="${1:-/opt/so/saltstack/default}"
|
||||
local defaultsfile="${path}/salt/elasticsearch/defaults.yaml"
|
||||
|
||||
if [ -f "$defaultsfile" ]; then
|
||||
ELASTIC_AGENT_TARBALL_VERSION=$(egrep " +version: " $defaultsfile | awk -F: '{print $2}' | tr -d '[:space:]')
|
||||
ELASTIC_AGENT_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz"
|
||||
ELASTIC_AGENT_MD5_URL="https://repo.securityonion.net/file/so-repo/prod/2.4/elasticagent/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5"
|
||||
ELASTIC_AGENT_FILE="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.tar.gz"
|
||||
ELASTIC_AGENT_MD5="/nsm/elastic-fleet/artifacts/elastic-agent_SO-$ELASTIC_AGENT_TARBALL_VERSION.md5"
|
||||
ELASTIC_AGENT_EXPANSION_DIR=/nsm/elastic-fleet/artifacts/beats/elastic-agent
|
||||
else
|
||||
fail "Could not find salt/elasticsearch/defaults.yaml"
|
||||
fi
|
||||
}
|
||||
|
||||
get_random_value() {
|
||||
length=${1:-20}
|
||||
head -c 5000 /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1
|
||||
}
|
||||
|
||||
gpg_rpm_import() {
|
||||
if [[ $is_oracle ]]; then
|
||||
if [[ "$OS" == "centos" ]]; then
|
||||
if [[ "$WHATWOULDYOUSAYYAHDOHERE" == "setup" ]]; then
|
||||
local RPMKEYSLOC="../salt/repo/client/files/$OS/keys"
|
||||
local RPMKEYSLOC="../salt/repo/client/files/centos/keys"
|
||||
else
|
||||
local RPMKEYSLOC="$UPDATE_DIR/salt/repo/client/files/$OS/keys"
|
||||
local RPMKEYSLOC="$UPDATE_DIR/salt/repo/client/files/centos/keys"
|
||||
fi
|
||||
RPMKEYS=('RPM-GPG-KEY-oracle' 'RPM-GPG-KEY-EPEL-9' 'SALT-PROJECT-GPG-PUBKEY-2023.pub' 'docker.pub' 'securityonion.pub')
|
||||
for RPMKEY in "${RPMKEYS[@]}"; do
|
||||
|
||||
RPMKEYS=('RPM-GPG-KEY-EPEL-7' 'GPG-KEY-WAZUH' 'docker.pub' 'SALTSTACK-GPG-KEY.pub' 'securityonion.pub')
|
||||
|
||||
for RPMKEY in "${RPMKEYS[@]}"; do
|
||||
rpm --import $RPMKEYSLOC/$RPMKEY
|
||||
echo "Imported $RPMKEY"
|
||||
done
|
||||
elif [[ $is_rpm ]]; then
|
||||
echo "Importing the security onion GPG key"
|
||||
rpm --import ../salt/repo/client/files/oracle/keys/securityonion.pub
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -365,15 +224,12 @@ init_monitor() {
|
||||
|
||||
if [[ $MONITORNIC == "bond0" ]]; then
|
||||
BIFACES=$(lookup_bond_interfaces)
|
||||
for i in rx tx sg tso ufo gso gro lro rx-vlan-offload tx-vlan-offload generic-receive-offload generic-segmentation-offload tcp-segmentation-offload; do
|
||||
ethtool -K "$MONITORNIC" "$i" off;
|
||||
done
|
||||
else
|
||||
BIFACES=$MONITORNIC
|
||||
fi
|
||||
|
||||
for DEVICE_IFACE in $BIFACES; do
|
||||
for i in rx tx sg tso ufo gso gro lro rx-vlan-offload tx-vlan-offload generic-receive-offload generic-segmentation-offload tcp-segmentation-offload; do
|
||||
for i in rx tx sg tso ufo gso gro lro; do
|
||||
ethtool -K "$DEVICE_IFACE" "$i" off;
|
||||
done
|
||||
ip link set dev "$DEVICE_IFACE" arp off multicast off allmulticast off promisc on
|
||||
@@ -381,17 +237,31 @@ init_monitor() {
|
||||
}
|
||||
|
||||
is_manager_node() {
|
||||
grep "role: so-" /etc/salt/grains | grep -E "manager|eval|managersearch|standalone|import" &> /dev/null
|
||||
# Check to see if this is a manager node
|
||||
role=$(lookup_role)
|
||||
is_single_node_grid && return 0
|
||||
[ $role == 'manager' ] && return 0
|
||||
[ $role == 'managersearch' ] && return 0
|
||||
[ $role == 'helix' ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
is_sensor_node() {
|
||||
# Check to see if this is a sensor (forward) node
|
||||
role=$(lookup_role)
|
||||
is_single_node_grid && return 0
|
||||
grep "role: so-" /etc/salt/grains | grep -E "sensor|heavynode" &> /dev/null
|
||||
[ $role == 'sensor' ] && return 0
|
||||
[ $role == 'heavynode' ] && return 0
|
||||
[ $role == 'helix' ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
is_single_node_grid() {
|
||||
grep "role: so-" /etc/salt/grains | grep -E "eval|standalone|import" &> /dev/null
|
||||
role=$(lookup_role)
|
||||
[ $role == 'eval' ] && return 0
|
||||
[ $role == 'standalone' ] && return 0
|
||||
[ $role == 'import' ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
lookup_bond_interfaces() {
|
||||
@@ -419,7 +289,7 @@ lookup_salt_value() {
|
||||
local=""
|
||||
fi
|
||||
|
||||
salt-call -lerror --no-color ${kind}.get ${group}${key} --out=${output} ${local}
|
||||
salt-call --no-color ${kind}.get ${group}${key} --out=${output} ${local}
|
||||
}
|
||||
|
||||
lookup_pillar() {
|
||||
@@ -445,24 +315,6 @@ lookup_role() {
|
||||
echo ${pieces[1]}
|
||||
}
|
||||
|
||||
is_feature_enabled() {
|
||||
feature=$1
|
||||
enabled=$(lookup_salt_value features)
|
||||
for cur in $enabled; do
|
||||
if [[ "$feature" == "$cur" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
read_feat() {
|
||||
if [ -f /opt/so/log/sostatus/lks_enabled ]; then
|
||||
lic_id=$(cat /opt/so/saltstack/local/pillar/soc/license.sls | grep license_id: | awk '{print $2}')
|
||||
echo "$lic_id/$(cat /opt/so/log/sostatus/lks_enabled)/$(cat /opt/so/log/sostatus/fps_enabled)"
|
||||
fi
|
||||
}
|
||||
|
||||
require_manager() {
|
||||
if is_manager_node; then
|
||||
echo "This is a manager, so we can proceed."
|
||||
@@ -494,10 +346,6 @@ retry() {
|
||||
echo "<Start of output>"
|
||||
echo "$output"
|
||||
echo "<End of output>"
|
||||
if [[ $exitcode -eq 0 ]]; then
|
||||
echo "Forcing exit code to 1"
|
||||
exitcode=1
|
||||
fi
|
||||
fi
|
||||
elif [ -n "$failedOutput" ]; then
|
||||
if [[ "$output" =~ "$failedOutput" ]]; then
|
||||
@@ -506,7 +354,7 @@ retry() {
|
||||
echo "$output"
|
||||
echo "<End of output>"
|
||||
if [[ $exitcode -eq 0 ]]; then
|
||||
echo "Forcing exit code to 1"
|
||||
echo "The exitcode was 0, but we are setting to 1 since we found $failedOutput in the output."
|
||||
exitcode=1
|
||||
fi
|
||||
else
|
||||
@@ -544,82 +392,19 @@ run_check_net_err() {
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_salt_minion() {
|
||||
local minion="$1"
|
||||
local timeout="${2:-5}"
|
||||
local logfile="${3:-'/dev/stdout'}"
|
||||
retry 60 5 "journalctl -u salt-minion.service | grep 'Minion is ready to receive requests'" >> "$logfile" 2>&1 || fail
|
||||
local attempt=0
|
||||
# each attempts would take about 15 seconds
|
||||
local maxAttempts=20
|
||||
until check_salt_minion_status "$minion" "$timeout" "$logfile"; do
|
||||
attempt=$((attempt+1))
|
||||
if [[ $attempt -eq $maxAttempts ]]; then
|
||||
return 1
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
salt_minion_count() {
|
||||
local MINIONDIR="/opt/so/saltstack/local/pillar/minions"
|
||||
MINIONCOUNT=$(ls -la $MINIONDIR/*.sls | grep -v adv_ | wc -l)
|
||||
|
||||
set_cron_service_name() {
|
||||
if [[ "$OS" == "centos" ]]; then
|
||||
cron_service_name="crond"
|
||||
else
|
||||
cron_service_name="cron"
|
||||
fi
|
||||
}
|
||||
|
||||
set_os() {
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
if grep -q "Rocky Linux release 9" /etc/redhat-release; then
|
||||
OS=rocky
|
||||
OSVER=9
|
||||
is_rocky=true
|
||||
is_rpm=true
|
||||
elif grep -q "CentOS Stream release 9" /etc/redhat-release; then
|
||||
OS=centos
|
||||
OSVER=9
|
||||
is_centos=true
|
||||
is_rpm=true
|
||||
elif grep -q "AlmaLinux release 9" /etc/redhat-release; then
|
||||
OS=alma
|
||||
OSVER=9
|
||||
is_alma=true
|
||||
is_rpm=true
|
||||
elif grep -q "Red Hat Enterprise Linux release 9" /etc/redhat-release; then
|
||||
if [ -f /etc/oracle-release ]; then
|
||||
OS=oracle
|
||||
OSVER=9
|
||||
is_oracle=true
|
||||
is_rpm=true
|
||||
else
|
||||
OS=rhel
|
||||
OSVER=9
|
||||
is_rhel=true
|
||||
is_rpm=true
|
||||
fi
|
||||
fi
|
||||
cron_service_name="crond"
|
||||
elif [ -f /etc/os-release ]; then
|
||||
if grep -q "UBUNTU_CODENAME=focal" /etc/os-release; then
|
||||
OSVER=focal
|
||||
UBVER=20.04
|
||||
OS=ubuntu
|
||||
is_ubuntu=true
|
||||
is_deb=true
|
||||
elif grep -q "UBUNTU_CODENAME=jammy" /etc/os-release; then
|
||||
OSVER=jammy
|
||||
UBVER=22.04
|
||||
OS=ubuntu
|
||||
is_ubuntu=true
|
||||
is_deb=true
|
||||
elif grep -q "VERSION_CODENAME=bookworm" /etc/os-release; then
|
||||
OSVER=bookworm
|
||||
DEBVER=12
|
||||
is_debian=true
|
||||
OS=debian
|
||||
is_deb=true
|
||||
fi
|
||||
cron_service_name="cron"
|
||||
OS=centos
|
||||
else
|
||||
OS=ubuntu
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -628,7 +413,7 @@ set_minionid() {
|
||||
}
|
||||
|
||||
set_palette() {
|
||||
if [[ $is_deb ]]; then
|
||||
if [ "$OS" == ubuntu ]; then
|
||||
update-alternatives --set newt-palette /etc/newt/palette.original
|
||||
fi
|
||||
}
|
||||
@@ -652,19 +437,6 @@ set_version() {
|
||||
fi
|
||||
}
|
||||
|
||||
status () {
|
||||
printf "\n=========================================================================\n$(date) | $1\n=========================================================================\n"
|
||||
}
|
||||
|
||||
sync_options() {
|
||||
set_version
|
||||
set_os
|
||||
salt_minion_count
|
||||
get_agent_count
|
||||
|
||||
echo "$VERSION/$OS/$(uname -r)/$MINIONCOUNT:$AGENTCOUNT/$(read_feat)"
|
||||
}
|
||||
|
||||
systemctl_func() {
|
||||
local action=$1
|
||||
local echo_action=$1
|
||||
@@ -688,13 +460,6 @@ has_uppercase() {
|
||||
|| return 1
|
||||
}
|
||||
|
||||
update_elastic_agent() {
|
||||
local path="${1:-/opt/so/saltstack/default}"
|
||||
get_elastic_agent_vars "$path"
|
||||
echo "Checking if Elastic Agent update is necessary..."
|
||||
download_and_verify "$ELASTIC_AGENT_URL" "$ELASTIC_AGENT_MD5_URL" "$ELASTIC_AGENT_FILE" "$ELASTIC_AGENT_MD5" "$ELASTIC_AGENT_EXPANSION_DIR"
|
||||
}
|
||||
|
||||
valid_cidr() {
|
||||
# Verify there is a backslash in the string
|
||||
echo "$1" | grep -qP "^[^/]+/[^/]+$" || return 1
|
||||
@@ -753,18 +518,6 @@ valid_hostname() {
|
||||
[[ $hostname =~ ^[a-zA-Z0-9\-]+$ ]] && [[ $hostname != 'localhost' ]] && return 0 || return 1
|
||||
}
|
||||
|
||||
verify_ip4() {
|
||||
local ip=$1
|
||||
# Is this an IP or CIDR?
|
||||
if grep -qP "^[^/]+/[^/]+$" <<< $ip; then
|
||||
# Looks like a CIDR
|
||||
valid_ip4_cidr_mask "$ip"
|
||||
else
|
||||
# We know this is not a CIDR - Is it an IP?
|
||||
valid_ip4 "$ip"
|
||||
fi
|
||||
}
|
||||
|
||||
valid_ip4() {
|
||||
local ip=$1
|
||||
|
||||
@@ -848,23 +601,6 @@ valid_username() {
|
||||
echo "$user" | grep -qP '^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$' && return 0 || return 1
|
||||
}
|
||||
|
||||
verify_md5_checksum() {
|
||||
data_file=$1
|
||||
md5_file=${2:-${data_file}.md5}
|
||||
|
||||
if [[ ! -f "$dest_file" || ! -f "$md5_file" ]]; then
|
||||
return 2
|
||||
fi
|
||||
|
||||
SOURCEHASH=$(md5sum "$data_file" | awk '{ print $1 }')
|
||||
HASH=$(cat "$md5_file")
|
||||
|
||||
if [[ "$HASH" == "$SOURCEHASH" ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
wait_for_web_response() {
|
||||
url=$1
|
||||
expected=$2
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
import json
|
||||
|
||||
sys.path.append('/opt/saltstack/salt/lib/python3.10/site-packages/')
|
||||
import salt.config
|
||||
import salt.loader
|
||||
|
||||
__opts__ = salt.config.minion_config('/etc/salt/minion')
|
||||
__grains__ = salt.loader.grains(__opts__)
|
||||
|
||||
def check_needs_restarted():
|
||||
osfam = __grains__['os_family']
|
||||
val = '0'
|
||||
outfile = "/opt/so/log/sostatus/needs_restarted"
|
||||
|
||||
if osfam == 'Debian':
|
||||
if os.path.exists('/var/run/reboot-required'):
|
||||
val = '1'
|
||||
elif osfam == 'RedHat':
|
||||
cmd = 'needs-restarting -r > /dev/null 2>&1'
|
||||
try:
|
||||
needs_restarting = subprocess.check_call(cmd, shell=True)
|
||||
except subprocess.CalledProcessError:
|
||||
val = '1'
|
||||
else:
|
||||
fail("Unsupported OS")
|
||||
|
||||
with open(outfile, 'w') as f:
|
||||
f.write(val)
|
||||
|
||||
def check_for_fps():
|
||||
feat = 'fps'
|
||||
feat_full = feat.replace('ps', 'ips')
|
||||
fps = 0
|
||||
try:
|
||||
result = subprocess.run([feat_full + '-mode-setup', '--is-enabled'], stdout=subprocess.PIPE)
|
||||
if result.returncode == 0:
|
||||
fps = 1
|
||||
except:
|
||||
fn = '/proc/sys/crypto/' + feat_full + '_enabled'
|
||||
try:
|
||||
with open(fn, 'r') as f:
|
||||
contents = f.read()
|
||||
if '1' in contents:
|
||||
fps = 1
|
||||
except:
|
||||
# Unknown, so assume 0
|
||||
fps = 0
|
||||
|
||||
with open('/opt/so/log/sostatus/fps_enabled', 'w') as f:
|
||||
f.write(str(fps))
|
||||
|
||||
def check_for_lks():
|
||||
feat = 'Lks'
|
||||
feat_full = feat.replace('ks', 'uks')
|
||||
lks = 0
|
||||
result = subprocess.run(['lsblk', '-p', '-J'], check=True, stdout=subprocess.PIPE)
|
||||
data = json.loads(result.stdout)
|
||||
for device in data['blockdevices']:
|
||||
if 'children' in device:
|
||||
for gc in device['children']:
|
||||
if 'children' in gc:
|
||||
try:
|
||||
arg = 'is' + feat_full
|
||||
result = subprocess.run(['cryptsetup', arg, gc['name']], stdout=subprocess.PIPE)
|
||||
if result.returncode == 0:
|
||||
lks = 1
|
||||
except FileNotFoundError:
|
||||
for ggc in gc['children']:
|
||||
if 'crypt' in ggc['type']:
|
||||
lks = 1
|
||||
if lks:
|
||||
break
|
||||
with open('/opt/so/log/sostatus/lks_enabled', 'w') as f:
|
||||
f.write(str(lks))
|
||||
|
||||
def fail(msg):
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
proc = subprocess.run(['id', '-u'], stdout=subprocess.PIPE, encoding="utf-8")
|
||||
if proc.stdout.strip() != "0":
|
||||
fail("This program must be run as root")
|
||||
# Ensure that umask is 0022 so that files created by this script have rw-r-r permissions
|
||||
org_umask = os.umask(0o022)
|
||||
check_needs_restarted()
|
||||
check_for_fps()
|
||||
check_for_lks()
|
||||
# Restore umask to whatever value was set before this script was run. SXIG sets to 0077 rw---
|
||||
os.umask(org_umask)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
50
salt/common/tools/sbin/so-config-backup
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
{% set BACKUPLOCATIONS = salt['pillar.get']('backup:locations', {}) %}
|
||||
|
||||
TODAY=$(date '+%Y_%m_%d')
|
||||
BACKUPFILE="/nsm/backup/so-config-backup-$TODAY.tar"
|
||||
MAXBACKUPS=7
|
||||
|
||||
# Create backup dir if it does not exist
|
||||
mkdir -p /nsm/backup
|
||||
|
||||
# If we haven't already written a backup file for today, let's do so
|
||||
if [ ! -f $BACKUPFILE ]; then
|
||||
|
||||
# Create empty backup file
|
||||
tar -cf $BACKUPFILE -T /dev/null
|
||||
|
||||
# Loop through all paths defined in global.sls, and append them to backup file
|
||||
{%- for LOCATION in BACKUPLOCATIONS %}
|
||||
tar -rf $BACKUPFILE {{ LOCATION }}
|
||||
{%- endfor %}
|
||||
tar -rf $BACKUPFILE /etc/pki
|
||||
tar -rf $BACKUPFILE /etc/salt
|
||||
tar -rf $BACKUPFILE /nsm/kratos
|
||||
|
||||
fi
|
||||
|
||||
# Find oldest backup files and remove them
|
||||
NUMBACKUPS=$(find /nsm/backup/ -type f -name "so-config-backup*" | wc -l)
|
||||
while [ "$NUMBACKUPS" -gt "$MAXBACKUPS" ]; do
|
||||
OLDESTBACKUP=$(find /nsm/backup/ -type f -name "so-config-backup*" -type f -printf '%T+ %p\n' | sort | head -n 1 | awk -F" " '{print $2}')
|
||||
rm -f $OLDESTBACKUP
|
||||
NUMBACKUPS=$(find /nsm/backup/ -type f -name "so-config-backup*" | wc -l)
|
||||
done
|
||||
20
salt/common/tools/sbin/so-cortex-restart
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
echo "TheHive and its components are no longer part of Security Onion"
|
||||
20
salt/common/tools/sbin/so-cortex-start
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
echo "TheHive and its components are no longer part of Security Onion"
|
||||
20
salt/common/tools/sbin/so-cortex-stop
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
echo "TheHive and its components are no longer part of Security Onion"
|
||||
20
salt/common/tools/sbin/so-cortex-user-add
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
echo "TheHive and its components are no longer part of Security Onion"
|
||||
20
salt/common/tools/sbin/so-cortex-user-enable
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
echo "TheHive and its components are no longer part of Security Onion"
|
||||
20
salt/common/tools/sbin/so-curator-restart
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
/usr/sbin/so-restart curator $1
|
||||
20
salt/common/tools/sbin/so-curator-start
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
/usr/sbin/so-start curator $1
|
||||
20
salt/common/tools/sbin/so-curator-stop
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
/usr/sbin/so-stop curator $1
|
||||
@@ -1,11 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ipaddress
|
||||
import textwrap
|
||||
@@ -19,12 +27,17 @@ from xml.dom import minidom
|
||||
|
||||
|
||||
LOCAL_SALT_DIR='/opt/so/saltstack/local'
|
||||
WAZUH_CONF='/nsm/wazuh/etc/ossec.conf'
|
||||
VALID_ROLES = {
|
||||
'a': { 'role': 'analyst','desc': 'Analyst - 80/tcp, 443/tcp' },
|
||||
'b': { 'role': 'beats_endpoint', 'desc': 'Logstash Beat - 5044/tcp' },
|
||||
'e': { 'role': 'elasticsearch_rest', 'desc': 'Elasticsearch REST API - 9200/tcp' },
|
||||
'f': { 'role': 'strelka_frontend', 'desc': 'Strelka frontend - 57314/tcp' },
|
||||
'o': { 'role': 'osquery_endpoint', 'desc': 'Osquery endpoint - 8090/tcp' },
|
||||
's': { 'role': 'syslog', 'desc': 'Syslog device - 514/tcp/udp' },
|
||||
'w': { 'role': 'wazuh_agent', 'desc': 'Wazuh agent - 1514/tcp/udp' },
|
||||
'p': { 'role': 'wazuh_api', 'desc': 'Wazuh API - 55000/tcp' },
|
||||
'r': { 'role': 'wazuh_authd', 'desc': 'Wazuh registration service - 1515/tcp' }
|
||||
}
|
||||
|
||||
|
||||
@@ -63,15 +76,73 @@ def ip_prompt() -> str:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def wazuh_enabled() -> bool:
|
||||
for file in os.listdir(f'{LOCAL_SALT_DIR}/pillar'):
|
||||
with open(file, 'r') as pillar:
|
||||
if 'wazuh: 1' in pillar.read():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def root_to_str(root: ET.ElementTree) -> str:
|
||||
xml_str = ET.tostring(root, encoding='unicode', method='xml').replace('\n', '')
|
||||
xml_str = re.sub(r'(?:(?<=>) *)', '', xml_str)
|
||||
|
||||
# Remove specific substrings to better format comments on intial parse/write
|
||||
xml_str = re.sub(r' -', '', xml_str)
|
||||
xml_str = re.sub(r' -->', ' -->', xml_str)
|
||||
|
||||
dom = minidom.parseString(xml_str)
|
||||
return dom.toprettyxml(indent=" ")
|
||||
|
||||
|
||||
def rem_wl(ip):
|
||||
parser = ET.XMLParser(remove_blank_text=True)
|
||||
with open(WAZUH_CONF, 'rb') as wazuh_conf:
|
||||
tree = ET.parse(wazuh_conf, parser)
|
||||
root = tree.getroot()
|
||||
|
||||
global_elems = root.findall(f"global/white_list[. = '{ip}']/..")
|
||||
if len(global_elems) > 0:
|
||||
for g_elem in global_elems:
|
||||
ge_index = list(root).index(g_elem)
|
||||
if ge_index > 0 and root[list(root).index(g_elem) - 1].tag == ET.Comment:
|
||||
root.remove(root[ge_index - 1])
|
||||
root.remove(g_elem)
|
||||
|
||||
with open(WAZUH_CONF, 'w') as out:
|
||||
out.write(root_to_str(root))
|
||||
|
||||
|
||||
def apply(role: str, ip: str) -> int:
|
||||
firewall_cmd = ['so-firewall', 'excludehost', role, ip]
|
||||
salt_cmd = ['salt-call', 'state.apply', '-l', 'quiet', 'firewall', 'queue=True']
|
||||
restart_wazuh_cmd = ['so-wazuh-restart']
|
||||
print(f'Removing {ip} from the {role} role. This can take a few seconds...')
|
||||
cmd = subprocess.run(firewall_cmd)
|
||||
if cmd.returncode == 0:
|
||||
cmd = subprocess.run(salt_cmd, stdout=subprocess.DEVNULL)
|
||||
else:
|
||||
return cmd.returncode
|
||||
if cmd.returncode == 0:
|
||||
if wazuh_enabled and role=='analyst':
|
||||
try:
|
||||
rem_wl(ip)
|
||||
print(f'Removed whitelist entry for {ip} from {WAZUH_CONF}', file=sys.stderr)
|
||||
except Exception as e:
|
||||
print(f'Failed to remove whitelist entry for {ip} from {WAZUH_CONF}', file=sys.stderr)
|
||||
print(e)
|
||||
return 1
|
||||
print('Restarting OSSEC Server...')
|
||||
cmd = subprocess.run(restart_wazuh_cmd)
|
||||
else:
|
||||
return cmd.returncode
|
||||
else:
|
||||
print(f'Commmand \'{" ".join(salt_cmd)}\' failed.', file=sys.stderr)
|
||||
return cmd.returncode
|
||||
if cmd.returncode != 0:
|
||||
print('Failed to restart OSSEC server.')
|
||||
return cmd.returncode
|
||||
|
||||
|
||||
def main():
|
||||
@@ -92,7 +163,11 @@ def main():
|
||||
group.add_argument('-b', dest='roles', action='append_const', const=VALID_ROLES['b']['role'], help="Logstash Beat - 5044/tcp")
|
||||
group.add_argument('-e', dest='roles', action='append_const', const=VALID_ROLES['e']['role'], help="Elasticsearch REST API - 9200/tcp")
|
||||
group.add_argument('-f', dest='roles', action='append_const', const=VALID_ROLES['f']['role'], help="Strelka frontend - 57314/tcp")
|
||||
group.add_argument('-o', dest='roles', action='append_const', const=VALID_ROLES['o']['role'], help="Osquery endpoint - 8090/tcp")
|
||||
group.add_argument('-s', dest='roles', action='append_const', const=VALID_ROLES['s']['role'], help="Syslog device - 514/tcp/udp")
|
||||
group.add_argument('-w', dest='roles', action='append_const', const=VALID_ROLES['w']['role'], help="Wazuh agent - 1514/tcp/udp")
|
||||
group.add_argument('-p', dest='roles', action='append_const', const=VALID_ROLES['p']['role'], help="Wazuh API - 55000/tcp")
|
||||
group.add_argument('-r', dest='roles', action='append_const', const=VALID_ROLES['r']['role'], help="Wazuh registration service - 1515/tcp")
|
||||
|
||||
ip_g = main_parser.add_argument_group(title='allow')
|
||||
ip_g.add_argument('-i', help="IP or CIDR block to disallow connections from, requires at least one role argument", metavar='', dest='ip')
|
||||
@@ -1,19 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
|
||||
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
|
||||
# https://securityonion.net/license; you may not use this file except in compliance with the
|
||||
# Elastic License 2.0.
|
||||
import sys, argparse, re, subprocess, json
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys, argparse, re, docker
|
||||
from packaging.version import Version, InvalidVersion
|
||||
from itertools import groupby, chain
|
||||
|
||||
|
||||
def get_image_name(string) -> str:
|
||||
return ':'.join(string.split(':')[:-1])
|
||||
|
||||
|
||||
def get_so_image_basename(string) -> str:
|
||||
return get_image_name(string).split('/so-')[-1]
|
||||
|
||||
|
||||
def get_image_version(string) -> str:
|
||||
ver = string.split(':')[-1]
|
||||
if ver == 'latest':
|
||||
@@ -29,75 +43,56 @@ def get_image_version(string) -> str:
|
||||
return '999999.9.9'
|
||||
return ver
|
||||
|
||||
def run_command(command):
|
||||
process = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
if process.returncode != 0:
|
||||
print(f"Error executing command: {command}", file=sys.stderr)
|
||||
print(f"Error message: {process.stderr}", file=sys.stderr)
|
||||
exit(1)
|
||||
return process.stdout
|
||||
|
||||
def main(quiet):
|
||||
client = docker.from_env()
|
||||
|
||||
# Prune old/stopped containers
|
||||
if not quiet: print('Pruning old containers')
|
||||
client.containers.prune()
|
||||
|
||||
image_list = client.images.list(filters={ 'dangling': False })
|
||||
|
||||
# Map list of image objects to flattened list of tags (format: "name:version")
|
||||
tag_list = list(chain.from_iterable(list(map(lambda x: x.attrs.get('RepoTags'), image_list))))
|
||||
|
||||
# Filter to only SO images (base name begins with "so-")
|
||||
tag_list = list(filter(lambda x: re.match(r'^.*\/so-[^\/]*$', get_image_name(x)), tag_list))
|
||||
|
||||
# Group tags into lists by base name (sort by same projection first)
|
||||
tag_list.sort(key=lambda x: get_so_image_basename(x))
|
||||
grouped_tag_lists = [ list(it) for _, it in groupby(tag_list, lambda x: get_so_image_basename(x)) ]
|
||||
|
||||
no_prunable = True
|
||||
for t_list in grouped_tag_lists:
|
||||
try:
|
||||
# Prune old/stopped containers using docker CLI
|
||||
if not quiet: print('Pruning old containers')
|
||||
run_command('docker container prune -f')
|
||||
|
||||
# Get list of images using docker CLI
|
||||
images_json = run_command('docker images --format "{{json .}}"')
|
||||
|
||||
# Parse the JSON output
|
||||
image_list = []
|
||||
for line in images_json.strip().split('\n'):
|
||||
if line: # Skip empty lines
|
||||
image_list.append(json.loads(line))
|
||||
|
||||
# Extract tags in the format "name:version"
|
||||
tag_list = []
|
||||
for img in image_list:
|
||||
# Skip dangling images
|
||||
if img.get('Repository') != "<none>" and img.get('Tag') != "<none>":
|
||||
tag = f"{img.get('Repository')}:{img.get('Tag')}"
|
||||
# Filter to only SO images (base name begins with "so-")
|
||||
if re.match(r'^.*\/so-[^\/]*$', get_image_name(tag)):
|
||||
tag_list.append(tag)
|
||||
|
||||
# Group tags into lists by base name (sort by same projection first)
|
||||
tag_list.sort(key=lambda x: get_so_image_basename(x))
|
||||
grouped_tag_lists = [list(it) for k, it in groupby(tag_list, lambda x: get_so_image_basename(x))]
|
||||
|
||||
no_prunable = True
|
||||
for t_list in grouped_tag_lists:
|
||||
# Group tags by version, in case multiple images exist with the same version string
|
||||
t_list.sort(key=lambda x: Version(get_image_version(x)), reverse=True)
|
||||
grouped_t_list = [ list(it) for _,it in groupby(t_list, lambda x: get_image_version(x)) ]
|
||||
|
||||
# Keep the 2 most current version groups
|
||||
if len(grouped_t_list) <= 2:
|
||||
continue
|
||||
else:
|
||||
no_prunable = False
|
||||
for group in grouped_t_list[2:]:
|
||||
for tag in group:
|
||||
if not quiet: print(f'Removing image {tag}')
|
||||
try:
|
||||
# Group tags by version, in case multiple images exist with the same version string
|
||||
t_list.sort(key=lambda x: Version(get_image_version(x)), reverse=True)
|
||||
grouped_t_list = [list(it) for k, it in groupby(t_list, lambda x: get_image_version(x))]
|
||||
# Keep the 2 most current version groups
|
||||
if len(grouped_t_list) <= 2:
|
||||
continue
|
||||
else:
|
||||
no_prunable = False
|
||||
for group in grouped_t_list[2:]:
|
||||
for tag in group:
|
||||
if not quiet: print(f'Removing image {tag}')
|
||||
try:
|
||||
run_command(f'docker rmi -f {tag}')
|
||||
except Exception as e:
|
||||
print(f'Could not remove image {tag}, continuing...')
|
||||
except (InvalidVersion) as e:
|
||||
print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr)
|
||||
exit(1)
|
||||
except Exception as e:
|
||||
print('Unhandled exception occurred:')
|
||||
print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
if no_prunable and not quiet:
|
||||
print('No Security Onion images to prune')
|
||||
|
||||
client.images.remove(tag, force=True)
|
||||
except docker.errors.ClientError as e:
|
||||
print(f'Could not remove image {tag}, continuing...')
|
||||
except (docker.errors.APIError, InvalidVersion) as e:
|
||||
print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr)
|
||||
exit(1)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
exit(1)
|
||||
print('Unhandled exception occurred:')
|
||||
print(f'so-{get_so_image_basename(t_list[0])}: {e}', file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
if no_prunable and not quiet:
|
||||
print('No Security Onion images to prune')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main_parser = argparse.ArgumentParser(add_help=False)
|
||||
|
||||
22
salt/common/tools/sbin/so-docker-refresh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
. /usr/sbin/so-image-common
|
||||
|
||||
require_manager
|
||||
update_docker_containers "refresh"
|
||||
20
salt/common/tools/sbin/so-elastalert-restart
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
/usr/sbin/so-restart elastalert $1
|
||||
20
salt/common/tools/sbin/so-elastalert-start
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
/usr/sbin/so-start elastalert $1
|
||||
20
salt/common/tools/sbin/so-elastalert-stop
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
/usr/sbin/so-stop elastalert $1
|
||||
67
salt/common/tools/sbin/so-elastic-auth
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if [ -f "/usr/sbin/so-common" ]; then
|
||||
. /usr/sbin/so-common
|
||||
fi
|
||||
|
||||
ES_AUTH_PILLAR=${ELASTIC_AUTH_PILLAR:-/opt/so/saltstack/local/pillar/elasticsearch/auth.sls}
|
||||
ES_USERS_FILE=${ELASTIC_USERS_FILE:-/opt/so/saltstack/local/salt/elasticsearch/files/users}
|
||||
|
||||
authEnable=$1
|
||||
|
||||
if ! grep -q "enabled: " "$ES_AUTH_PILLAR"; then
|
||||
echo "Elastic auth pillar file is invalid. Unable to proceed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function restart() {
|
||||
if [[ -z "$ELASTIC_AUTH_SKIP_HIGHSTATE" ]]; then
|
||||
echo "Elasticsearch on all affected minions will now be stopped and then restarted..."
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode' cmd.run so-elastic-stop queue=True
|
||||
echo "Applying highstate to all affected minions..."
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode' state.highstate queue=True
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$authEnable" == "true" ]]; then
|
||||
if grep -q "enabled: False" "$ES_AUTH_PILLAR"; then
|
||||
sed -i 's/enabled: False/enabled: True/g' "$ES_AUTH_PILLAR"
|
||||
restart
|
||||
echo "Elastic auth is now enabled."
|
||||
if grep -q "argon" "$ES_USERS_FILE"; then
|
||||
echo ""
|
||||
echo "IMPORTANT: The following users will need to change their password, after logging into SOC, in order to access Kibana:"
|
||||
grep argon "$ES_USERS_FILE" | cut -d ":" -f 1
|
||||
fi
|
||||
else
|
||||
echo "Auth is already enabled."
|
||||
fi
|
||||
elif [[ "$authEnable" == "false" ]]; then
|
||||
if grep -q "enabled: True" "$ES_AUTH_PILLAR"; then
|
||||
sed -i 's/enabled: True/enabled: False/g' "$ES_AUTH_PILLAR"
|
||||
restart
|
||||
echo "Elastic auth is now disabled."
|
||||
else
|
||||
echo "Auth is already disabled."
|
||||
fi
|
||||
else
|
||||
echo "Usage: $0 <true|false>"
|
||||
echo ""
|
||||
echo "Toggles Elastic authentication. Elasticsearch will be restarted on each affected minion."
|
||||
echo ""
|
||||
fi
|
||||
27
salt/manager/tools/sbin/so-elastic-auth-password-reset → salt/common/tools/sbin/so-elastic-auth-password-reset
Executable file → Normal file
@@ -1,10 +1,19 @@
|
||||
#!/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.
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
source $(dirname $0)/so-common
|
||||
require_manager
|
||||
@@ -89,14 +98,18 @@ function killAllSaltJobs() {
|
||||
function soUserSync() {
|
||||
# apply this state to update /opt/so/saltstack/local/salt/elasticsearch/curl.config on the manager
|
||||
salt-call state.sls_id elastic_curl_config_distributed manager queue=True
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-searchnode or G@role:so-heavynode' saltutil.kill_all_jobs
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode' saltutil.kill_all_jobs
|
||||
# apply this state to get the curl.config
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-searchnode or G@role:so-heavynode' state.sls_id elastic_curl_config common queue=True
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode' state.sls_id elastic_curl_config common queue=True
|
||||
$(dirname $0)/so-user sync
|
||||
printf "\nApplying logstash state to the appropriate nodes.\n\n"
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-searchnode or G@role:so-heavynode' state.apply logstash queue=True
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode' state.apply logstash queue=True
|
||||
printf "\nApplying filebeat state to the appropriate nodes.\n\n"
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode or G@role:so-sensor or G@role:so-fleet' state.apply filebeat queue=True
|
||||
printf "\nApplying kibana state to the appropriate nodes.\n\n"
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch' state.apply kibana queue=True
|
||||
printf "\nApplying curator state to the appropriate nodes.\n\n"
|
||||
salt -C 'G@role:so-standalone or G@role:so-eval or G@role:so-import or G@role:so-manager or G@role:so-managersearch or G@role:so-node or G@role:so-heavynode' state.apply curator queue=True
|
||||
}
|
||||
|
||||
function highstateManager() {
|
||||
116
salt/common/tools/sbin/so-elastic-clear
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
{%- set NODEIP = salt['pillar.get']('elasticsearch:mainip', '') %}
|
||||
. /usr/sbin/so-common
|
||||
|
||||
SKIP=0
|
||||
#########################################
|
||||
# Options
|
||||
#########################################
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Security Onion Elastic Clear
|
||||
Options:
|
||||
-h This message
|
||||
-y Skip interactive mode
|
||||
EOF
|
||||
}
|
||||
while getopts "h:y" OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
|
||||
y)
|
||||
SKIP=1
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ $SKIP -ne 1 ]; then
|
||||
# List indices
|
||||
echo
|
||||
{{ ELASTICCURL }} -k -L https://{{ NODEIP }}:9200/_cat/indices?v
|
||||
echo
|
||||
# Inform user we are about to delete all data
|
||||
echo
|
||||
echo "This script will delete all data (documents, indices, etc.) in the Elasticsearch database."
|
||||
echo
|
||||
echo "If you would like to proceed, please type "AGREE" and hit ENTER."
|
||||
echo
|
||||
# Read user input
|
||||
read INPUT
|
||||
if [ "$INPUT" != "AGREE" ] ; then exit 0; fi
|
||||
fi
|
||||
|
||||
# Check to see if Logstash/Filebeat are running
|
||||
LS_ENABLED=$(so-status | grep logstash)
|
||||
FB_ENABLED=$(so-status | grep filebeat)
|
||||
EA_ENABLED=$(so-status | grep elastalert)
|
||||
|
||||
if [ ! -z "$FB_ENABLED" ]; then
|
||||
|
||||
/usr/sbin/so-filebeat-stop
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -z "$LS_ENABLED" ]; then
|
||||
|
||||
/usr/sbin/so-logstash-stop
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -z "$EA_ENABLED" ]; then
|
||||
|
||||
/usr/sbin/so-elastalert-stop
|
||||
|
||||
fi
|
||||
|
||||
# Delete data
|
||||
echo "Deleting data..."
|
||||
|
||||
INDXS=$({{ ELASTICCURL }} -s -XGET -k -L https://{{ NODEIP }}:9200/_cat/indices?v | egrep 'logstash|elastalert|so-' | awk '{ print $3 }')
|
||||
for INDX in ${INDXS}
|
||||
do
|
||||
{{ ELASTICCURL }} -XDELETE -k -L https://"{{ NODEIP }}:9200/${INDX}" > /dev/null 2>&1
|
||||
done
|
||||
|
||||
#Start Logstash/Filebeat
|
||||
if [ ! -z "$FB_ENABLED" ]; then
|
||||
|
||||
/usr/sbin/so-filebeat-start
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -z "$LS_ENABLED" ]; then
|
||||
|
||||
/usr/sbin/so-logstash-start
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -z "$EA_ENABLED" ]; then
|
||||
|
||||
/usr/sbin/so-elastalert-start
|
||||
|
||||
fi
|
||||
|
||||
33
salt/common/tools/sbin/so-elastic-diagnose
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Source common settings
|
||||
. /usr/sbin/so-common
|
||||
|
||||
# Check for log files
|
||||
for FILE in /opt/so/log/elasticsearch/*.log /opt/so/log/logstash/*.log /opt/so/log/kibana/*.log /opt/so/log/elastalert/*.log /opt/so/log/curator/*.log /opt/so/log/freqserver/*.log /opt/so/log/nginx/*.log; do
|
||||
|
||||
# If file exists, then look for errors or warnings
|
||||
if [ -f $FILE ]; then
|
||||
MESSAGE=`grep -i 'ERROR\|FAIL\|WARN' $FILE`
|
||||
if [ ! -z "$MESSAGE" ]; then
|
||||
header $FILE
|
||||
echo $MESSAGE | sed 's/WARN/\nWARN/g' | sed 's/WARNING/\nWARNING/g' | sed 's/ERROR/\nERROR/g' | sort | uniq -c | sort -nr
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
done
|
||||
43
salt/common/tools/sbin/so-elastic-restart
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
|
||||
{%- if grains['role'] in ['so-eval','so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node', 'so-import']%}
|
||||
/usr/sbin/so-restart elasticsearch $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone', 'so-import']%}
|
||||
/usr/sbin/so-restart kibana $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node']%}
|
||||
/usr/sbin/so-restart logstash $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node', 'so-sensor']%}
|
||||
/usr/sbin/so-restart filebeat $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node']%}
|
||||
/usr/sbin/so-restart curator $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-eval','so-manager', 'so-managersearch', 'so-standalone']%}
|
||||
/usr/sbin/so-restart elastalert $1
|
||||
{%- endif %}
|
||||
43
salt/common/tools/sbin/so-elastic-start
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2014-2023 Security Onion Solutions, LLC
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. /usr/sbin/so-common
|
||||
|
||||
|
||||
{%- if grains['role'] in ['so-eval','so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node', 'so-import']%}
|
||||
/usr/sbin/so-start elasticsearch $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-eval', 'so-manager', 'so-managersearch', 'so-standalone', 'so-import']%}
|
||||
/usr/sbin/so-start kibana $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node']%}
|
||||
/usr/sbin/so-start logstash $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node', 'so-sensor']%}
|
||||
/usr/sbin/so-start filebeat $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-manager', 'so-managersearch', 'so-standalone', 'so-heavynode', 'so-node']%}
|
||||
/usr/sbin/so-start curator $1
|
||||
{%- endif %}
|
||||
|
||||
{%- if grains['role'] in ['so-eval','so-manager', 'so-managersearch', 'so-standalone']%}
|
||||
/usr/sbin/so-start elastalert $1
|
||||
{%- endif %}
|
||||