Compare commits
1194 Commits
17.10.alph
...
20.06
Author | SHA1 | Date | |
---|---|---|---|
e2752458d4 | |||
cac7cdcec6 | |||
ed79b72869 | |||
e7e521edba | |||
7d012726b7 | |||
d6ea4cdde2 | |||
f441ec0bfc | |||
fb49a77180 | |||
5dc6350106 | |||
202246a3cd | |||
467dfae320 | |||
788a4c4f98 | |||
0178b4c4d3 | |||
68b080a3a8 | |||
ef1a1fa057 | |||
daf41b4b71 | |||
0bca794fe7 | |||
aaccb43471 | |||
beb9abca16 | |||
fb93d85119 | |||
ceee197e68 | |||
b0339610a2 | |||
a98b447556 | |||
b4c1805551 | |||
0ef2e89cac | |||
b76f0f109f | |||
5f29516197 | |||
ff1c12e848 | |||
2ee2d08e5a | |||
3103c94355 | |||
a3be0011fb | |||
ce39e1bd4f | |||
6fb2fa783a | |||
e76a643296 | |||
6c155ad87f | |||
81b8242c68 | |||
d2cbf6ebbc | |||
591be0791b | |||
adee51bee5 | |||
b214db6e9d | |||
2694c05953 | |||
c9b909e51d | |||
db74c610ad | |||
ea624351b5 | |||
c1eb9f7216 | |||
1a844d13ba | |||
348a5d572b | |||
77dcd771df | |||
b566b39688 | |||
8285657e5d | |||
dd7fb325b6 | |||
ab092faa2c | |||
28681ef398 | |||
eefd38a335 | |||
261b380db7 | |||
77e2dd2da6 | |||
183136c1f1 | |||
1fe0247095 | |||
adab02a067 | |||
58aa3162cb | |||
405ee521a6 | |||
9a3465aef1 | |||
e23c57e58d | |||
44749fe9e7 | |||
f5d11bb008 | |||
efa9d991ba | |||
a7faafeba9 | |||
f05abc07c9 | |||
eeae863820 | |||
9f9d1a65bd | |||
a48840d1b2 | |||
48de3d846c | |||
122135dd80 | |||
8576e576a6 | |||
32e1e8a8ea | |||
ed224215a4 | |||
e9c03e512c | |||
ed0c5aa89f | |||
d5290e68ff | |||
9de1bdd0b5 | |||
00457b8b70 | |||
e26600ad75 | |||
310f560c65 | |||
06ef8850fe | |||
05a7d33c9f | |||
baaba5311a | |||
35014a15ca | |||
2aa4c3c2c6 | |||
0867d8f011 | |||
a2071eb4d2 | |||
e6402b793c | |||
4cb84166c5 | |||
b6be931641 | |||
f51ab7ec0f | |||
f22ec3a360 | |||
de38e5e86f | |||
bd9cb43960 | |||
7763ceff4c | |||
0e1a86f93b | |||
0f0c728c90 | |||
16d5a6e0c1 | |||
0c5ab33b8a | |||
cd91183b8b | |||
12c4308b89 | |||
bbf5d70d98 | |||
60e57bce52 | |||
460214f848 | |||
334b98c01b | |||
0493e5eb3d | |||
dceaa984c9 | |||
8abd1be5bb | |||
d0cc43e89e | |||
8c19ea68c8 | |||
0649d56521 | |||
628ea0224c | |||
c9ec5347d5 | |||
de3d7c7f4f | |||
b0ea90c65b | |||
0c7d0d0eaa | |||
aec0761580 | |||
77e0b8c313 | |||
c659572df1 | |||
37120a7324 | |||
532907c27c | |||
fb860fb861 | |||
1c7e5274aa | |||
7587efaed8 | |||
f7d696007c | |||
46e297386b | |||
7d423f29da | |||
41c0255ea6 | |||
d5f0ceb15b | |||
5f38e730d4 | |||
c48ad0863d | |||
4bc2b1bf03 | |||
3d123f35a4 | |||
d4519892f6 | |||
0aa1a05c92 | |||
69c535619d | |||
5fe59c3bd8 | |||
d8d0a6f190 | |||
4d407b420d | |||
181e3585b7 | |||
2597af73ee | |||
0ab220ebf0 | |||
2777fc1f41 | |||
91483a231d | |||
95ea079f4d | |||
8112f48270 | |||
898f8be4db | |||
a28ee97f13 | |||
b01bf50aaf | |||
86cc54ee88 | |||
2fb1967ef1 | |||
48e02ceb1c | |||
c014e9635d | |||
ca4946c87c | |||
9ff9c3c4df | |||
423914f63f | |||
f6db541293 | |||
efb51f8233 | |||
acc64c2771 | |||
780acd0384 | |||
b014f73045 | |||
bb8d2f27c6 | |||
487c091ba7 | |||
c3ebf8487b | |||
51b15b6510 | |||
f2c48d7efc | |||
039f3c115a | |||
80d9efa729 | |||
e5f29f3c90 | |||
01af362ff6 | |||
98c7dd17d7 | |||
70c152377d | |||
b214bed014 | |||
bde60734ea | |||
362dd75473 | |||
a7be2ca0a8 | |||
da81f12877 | |||
4e8a1e8ea9 | |||
1b386ed32f | |||
5a65ceb5b5 | |||
c60d53ca3f | |||
e7a41feef4 | |||
ee3d667615 | |||
df27ba4e5f | |||
459db01e23 | |||
f767179cc9 | |||
749e7ee246 | |||
3a7eda96fa | |||
43ae92cf44 | |||
2fb51f3b3a | |||
d2dc43e1ef | |||
db73a0656e | |||
b3b983afe6 | |||
273cab4759 | |||
e1745bdea1 | |||
c34570f665 | |||
020cbb5355 | |||
aea14c9ead | |||
b57f6ddd1e | |||
af6ce8854d | |||
6069b214a5 | |||
252051dfe7 | |||
f9fa1bcc74 | |||
f3f9f6ae72 | |||
bdf095367d | |||
4abb0e5ce6 | |||
ba87ebfdaa | |||
8a7e81815e | |||
17eff81e9c | |||
f8f1bc1757 | |||
87a27e4f2b | |||
7f8f3a01c3 | |||
2ecef8c607 | |||
d992a25a0a | |||
73a5847753 | |||
c976aea73e | |||
4ada38988c | |||
0010f99662 | |||
e2f76c44cb | |||
e26853c7fa | |||
d64cbe6741 | |||
c3809b5a98 | |||
a3d40cc57c | |||
e3fda4d464 | |||
4bf245d13b | |||
92925cecbd | |||
f204cdf9b8 | |||
ff4a394e3b | |||
ce7b79b71a | |||
b28cc2edd0 | |||
84a741ec64 | |||
6b37578d8d | |||
d351a89096 | |||
488da48df7 | |||
85da099cd0 | |||
bd8a9ca92d | |||
1afbb89ef4 | |||
b1d8e293de | |||
7fdf9edb60 | |||
0e7abb8d2c | |||
2bac239763 | |||
a90f135f06 | |||
adee659baa | |||
1e8f6305c9 | |||
38b792a06e | |||
1ee9c29805 | |||
2e5639a50b | |||
47dca8b835 | |||
1ac79d6be7 | |||
9a7f55bb52 | |||
42852a85ea | |||
c33229b53a | |||
840662da48 | |||
d8f14d9c9f | |||
72e4134c86 | |||
5b1e07b9c8 | |||
2be185a371 | |||
54a6a944aa | |||
b86d2c715b | |||
8f06b5b499 | |||
6ec5a04802 | |||
5080151b7c | |||
c1f7146800 | |||
743616fa09 | |||
6e18b6f660 | |||
50d67fc286 | |||
c28642932a | |||
969e269bd1 | |||
8af45c9440 | |||
6d29f504df | |||
9b7f100f74 | |||
e1485bfd04 | |||
31c6bc6f96 | |||
3badae587c | |||
530564fb3f | |||
7f0a191530 | |||
3c32c9ca88 | |||
04e3748781 | |||
77d21d9e65 | |||
47c5a7bcef | |||
3873b8d6e4 | |||
1d0e502b78 | |||
e4ef35f3f7 | |||
6c8acb36fb | |||
8bfc64a945 | |||
618ee3c6e9 | |||
3a418534d8 | |||
4e6510b5c7 | |||
16a7cdb975 | |||
6419f4d521 | |||
0031980416 | |||
6a98496e8c | |||
ec8f5d9b66 | |||
da7d095d6f | |||
238a08b055 | |||
99d8cf9b32 | |||
81c6351cf1 | |||
39c0abb92e | |||
65e849cf33 | |||
a396356785 | |||
6ab87e684a | |||
a7c653e7fe | |||
5a479b0d8e | |||
697c5cb3f6 | |||
2882668826 | |||
739c7c1154 | |||
66d9005c61 | |||
d1dd805f80 | |||
27a5db9edf | |||
77ddb68413 | |||
0aaf73e205 | |||
dc1ec0f48c | |||
1e06136016 | |||
4cc1aa08c2 | |||
be918033e0 | |||
f502b6876a | |||
cd973301fd | |||
680194adf7 | |||
be7afd8042 | |||
fea6b8a646 | |||
cbefe6a074 | |||
ed73d83317 | |||
34bbbf59ac | |||
a6c8d3d712 | |||
1a7b3b3795 | |||
2f9648d1f6 | |||
75c1b253e5 | |||
46707683c7 | |||
349f6ed6a9 | |||
489de1854a | |||
73e1842c16 | |||
e8af9a0aa7 | |||
be1a90524a | |||
bde3d5df29 | |||
bedd13af20 | |||
63131b6712 | |||
78587cb85c | |||
6b77862e5c | |||
4db8f60ddf | |||
3d217d1eaf | |||
7191beaa68 | |||
7b081d164f | |||
f69455a3b0 | |||
2acd5da25b | |||
a73f34490d | |||
435e8c2034 | |||
f73ca5b328 | |||
f606187350 | |||
7815f4e8e4 | |||
f5b097b19a | |||
e588e62815 | |||
20cdb4f454 | |||
9d7b37b126 | |||
62aae45dd6 | |||
21d48ca2bb | |||
80ee3cc5dd | |||
67e70780bf | |||
5bbebd6fc4 | |||
cc70144c41 | |||
140a3d22ac | |||
6a1f4f9aea | |||
4409d9cdac | |||
1452ca4e4c | |||
313df2f644 | |||
f6503cce3c | |||
5badf352be | |||
2201e072f6 | |||
5192ce1dc7 | |||
5319c548ad | |||
c32a150c51 | |||
e77d24db08 | |||
857190ec20 | |||
809d598076 | |||
9a64c88aba | |||
af3242e8d5 | |||
5ddf1fdd07 | |||
020d4e9738 | |||
7081bafb6e | |||
fb06c46793 | |||
f76d8ab161 | |||
a256ecedc8 | |||
fb3777141b | |||
a18304dfdc | |||
6a703544c6 | |||
941a0e1587 | |||
692a21ddb1 | |||
df22adb45d | |||
07c68c85bb | |||
a4227e6a9f | |||
3b8c959c66 | |||
5d7a6f3270 | |||
ee1342ce2a | |||
53e9470d58 | |||
21c68f75e2 | |||
bf7d1299ca | |||
70dca02ce4 | |||
6bfcf8b1c4 | |||
b7b6e9fa0e | |||
d889651d63 | |||
bd0e6936eb | |||
545209dce6 | |||
153f7be9dc | |||
faa5667246 | |||
aa4a93684d | |||
f11ad6b523 | |||
a49d560809 | |||
f2abb1d1bd | |||
b31225b97c | |||
ad861200de | |||
5ce5911ec1 | |||
b9da9f04af | |||
92c0543c55 | |||
984ba958fb | |||
2d249ac6b1 | |||
64729f5064 | |||
5a4724bcba | |||
64907a2eba | |||
fa0fdbb579 | |||
1e47497c30 | |||
a3e0c51493 | |||
33222a92b6 | |||
1167231560 | |||
62b519999e | |||
8b19228d99 | |||
2d16a9c9f6 | |||
95a075e764 | |||
dc75b5567a | |||
d643ca7a01 | |||
f110eb08b0 | |||
a470a7b12f | |||
c7eed86bd7 | |||
20d6c6ab7f | |||
b033d515c6 | |||
1d0aad3b34 | |||
a6ed6613a5 | |||
a953542f8f | |||
be3e998a92 | |||
1bc514a067 | |||
9ad83fae51 | |||
e803d188c9 | |||
8a844e6dd3 | |||
0ef2b083fc | |||
755cbb77db | |||
3498f3e635 | |||
2ed0f939d1 | |||
af3ef271d4 | |||
3713139fc6 | |||
0928e37326 | |||
f7a6a30c90 | |||
ec46dc9ab0 | |||
7c5fc000c0 | |||
64628c1293 | |||
29d223865f | |||
0ed60329b8 | |||
1442a257e5 | |||
a1d903db01 | |||
756215519c | |||
659831cf99 | |||
a370e2b414 | |||
f4a078c443 | |||
02bdc8194a | |||
878538e3df | |||
ca01bfd82f | |||
71dc3227c4 | |||
fd39b3a94d | |||
3b43c55c04 | |||
d15005195d | |||
c5ddfd0a72 | |||
e9520eefb5 | |||
72709bc186 | |||
59757f87f0 | |||
60ef4eeeea | |||
68a10a2f1f | |||
170439d977 | |||
9c7c6ac4a3 | |||
6224146cde | |||
8314a7d34a | |||
145856960c | |||
71523cf7ef | |||
cbb2b66a72 | |||
2076cea40f | |||
34f335c7e6 | |||
602ebfc952 | |||
78f9a83b04 | |||
4c9ff2c006 | |||
7d56264a8d | |||
78135df9e7 | |||
3d85ca94f1 | |||
4d7ee46cd5 | |||
6921857573 | |||
5ee19e3e30 | |||
4fa66a2747 | |||
a1e81b57c9 | |||
1813b78ff0 | |||
6cff8e390d | |||
5079b57f94 | |||
42c19e4d81 | |||
b9fb3d4695 | |||
544def9481 | |||
dca06918c0 | |||
9137440d3c | |||
d75a612416 | |||
487ce4bed5 | |||
ba8564b348 | |||
e914643882 | |||
1c8d3451ef | |||
e7fe917738 | |||
0ed394db6a | |||
99cc91d671 | |||
357f40d573 | |||
24ac6d203f | |||
08ff1377fd | |||
42c57636b9 | |||
c86d6f15af | |||
670dddfea0 | |||
2132f80988 | |||
cae95ebe20 | |||
221f75be33 | |||
66bb9443f9 | |||
29c6be5571 | |||
16868a7532 | |||
4620666d4e | |||
9a5dd587b3 | |||
cca1d0f727 | |||
bc6e94d329 | |||
78d9d1f7c7 | |||
f1275e5b07 | |||
4164b75bea | |||
c2afdc0f1f | |||
e0427cfc21 | |||
786ab5c082 | |||
a59fc19133 | |||
bf39c0f5b2 | |||
364831ae58 | |||
31d7707d19 | |||
a053be50f3 | |||
ade81e2dc2 | |||
3f15373e7b | |||
3186b88641 | |||
fc4c4e8675 | |||
f80e693d8b | |||
bf9a14081d | |||
a906633cfd | |||
7fcf406781 | |||
eb22f8e99b | |||
0cff5f4be4 | |||
579aaaa577 | |||
37c9507354 | |||
08d2665f66 | |||
472edc5ac2 | |||
0baff7340d | |||
d9f7360daf | |||
15ebffa58f | |||
c8bd84316f | |||
413fe4704a | |||
0dac77036b | |||
8815d13903 | |||
5e926a092f | |||
43376d94b0 | |||
b7769df794 | |||
a5856082c8 | |||
76ec8ae20e | |||
640d74a851 | |||
54ed268041 | |||
c5f1c94674 | |||
c613c48c75 | |||
b6f18cf5f1 | |||
f70f1a7f70 | |||
16179b3ed9 | |||
d8378e73d4 | |||
d29a30d79d | |||
399d0e1e6e | |||
ec7c6a4ba4 | |||
d25bbd0032 | |||
fe7f6ad510 | |||
e7f577200b | |||
d63e9356ba | |||
f2dd83840f | |||
7a5a732ece | |||
2a4128d77c | |||
06407e42d7 | |||
0392517fa2 | |||
bcb6c7e616 | |||
1fab2a690a | |||
9b67c9e66c | |||
f501d440c8 | |||
504e3f2734 | |||
93417ddefd | |||
9db5c92f4d | |||
0c1257b863 | |||
cca0a065c7 | |||
fc752b10c2 | |||
f4daa17f41 | |||
d02bac1ea1 | |||
d85ad5c475 | |||
b505d560e7 | |||
1113c9c0c9 | |||
a5236d518f | |||
4d8149846b | |||
658b71d6d8 | |||
74b8f6656f | |||
ab65c20b5c | |||
2b0cff97a9 | |||
28f5491977 | |||
3acb52ce63 | |||
1a9a284930 | |||
5e22afd10b | |||
a87af2ce6a | |||
a8b7cc4e9a | |||
f18c5586bf | |||
6b2d9e5401 | |||
8b03fb8f28 | |||
bbf226aeda | |||
0f8eaef8f5 | |||
a7e553efe9 | |||
f870c8e885 | |||
4e902b6560 | |||
d3239b78c4 | |||
867bda6ad7 | |||
9edb84e3b4 | |||
b658a01637 | |||
efdd2fc11d | |||
018630aabe | |||
52c64f57d1 | |||
262e22155e | |||
965170ff21 | |||
190fba654a | |||
d71532678b | |||
8163cf8b2d | |||
bc658a0575 | |||
f3214b935c | |||
c874e9d080 | |||
4efc62b529 | |||
9815f17b16 | |||
12cf4ecd89 | |||
ad7f3a6485 | |||
4b3337de48 | |||
8b2898bd4e | |||
c5585f2652 | |||
6b40c1ca7f | |||
72cdf68a60 | |||
6710d6e698 | |||
3ab7de8d09 | |||
687299ba60 | |||
28da547e75 | |||
17073c3a15 | |||
3fef0fd6da | |||
3b1e4e8402 | |||
4cd18c3764 | |||
006a7c322c | |||
3d55d16f8d | |||
65ba32c056 | |||
c09547e3a4 | |||
ce89e44474 | |||
72c98ac811 | |||
44385fb9b7 | |||
9ec1992929 | |||
03d1449b3c | |||
0dcd0b6dc5 | |||
581f06e2e8 | |||
886f08f7e2 | |||
ecd47346e5 | |||
df617e9d7b | |||
f0a4990bb8 | |||
3037e6f5fb | |||
f9c85f08e0 | |||
c7a795c6d4 | |||
8ba91add41 | |||
1e5682480b | |||
c23934a5bb | |||
9cd6ccc2c2 | |||
452ccfc3d1 | |||
b3b6bdef98 | |||
73d82c513d | |||
4d9756c26e | |||
28449417d0 | |||
919eaabfb2 | |||
2587435f96 | |||
eda9fe0ee0 | |||
c15e94cf26 | |||
a5f0b912a1 | |||
b66d18540a | |||
9132cb963c | |||
ef9fd95e61 | |||
1a12f6c881 | |||
280953b456 | |||
a2a4d130d2 | |||
f1edd4fc2e | |||
d4b7cc15e9 | |||
ad9634386e | |||
4c5447658d | |||
949a8854c6 | |||
c05b602497 | |||
98d55f77c9 | |||
0415827f08 | |||
de6735e309 | |||
5860fcd736 | |||
e454d63e27 | |||
bf51829dca | |||
c1434c0fb0 | |||
fbf4ca00a3 | |||
00e4043bca | |||
b4ed9952bf | |||
2976bf7102 | |||
8d91874c9e | |||
19c30f9709 | |||
7d8a5b9dc6 | |||
c3d2f74d4e | |||
e99b851624 | |||
83e6c5309b | |||
8649a1a2e1 | |||
9f7f5068c0 | |||
871fa91616 | |||
baa7294024 | |||
d099b90b98 | |||
7ada64e16c | |||
1df1662140 | |||
e3034da106 | |||
f0d9fa90a8 | |||
a6d75002cd | |||
ea93cd1db7 | |||
b59485eea2 | |||
3edc0a7218 | |||
dfa7320380 | |||
2c7c5b656d | |||
52918767f6 | |||
e55c1b9189 | |||
1cffd95bf3 | |||
5482fa6748 | |||
ecb2b4a587 | |||
3f324f0fb1 | |||
7e9cc240e3 | |||
da134adbc8 | |||
8c6aacf1f5 | |||
ade98060d8 | |||
33e98822e3 | |||
d4654f2bbc | |||
16bed23afb | |||
e6fb310bef | |||
e21bcf54de | |||
c2006f0a34 | |||
5833b69e72 | |||
e8d7b8b3aa | |||
dee314dfb0 | |||
0d1b7d56a2 | |||
e9f19a33d9 | |||
f94c00eba1 | |||
a452b9bd9d | |||
c0d0e016e6 | |||
20711cb633 | |||
d93d0662ee | |||
c7e9015a5a | |||
a95ab7ed3e | |||
5e32e42439 | |||
b5d45bc539 | |||
5b6bb5ea47 | |||
04877b6999 | |||
249b9318b6 | |||
58ce021c27 | |||
349982baf7 | |||
da6299e6a1 | |||
96d1c16958 | |||
60021763de | |||
712b88227a | |||
e8d8773863 | |||
5b710d5b28 | |||
573ceb98a1 | |||
5dae44b5e9 | |||
86715ccf7c | |||
2b7d8ee01e | |||
0b92b56c55 | |||
7ed3530130 | |||
522da73710 | |||
6f30322ad5 | |||
d9e5331a84 | |||
bfa54853ab | |||
35e89b1e20 | |||
2cc8c9eba1 | |||
869f05ca8b | |||
85e5f8d7aa | |||
89b249d228 | |||
8d59602a75 | |||
e1fe025dd7 | |||
6467a03d19 | |||
12e9a2aaeb | |||
65f242d322 | |||
728607a2da | |||
06ccf17c5f | |||
32043158bf | |||
00f068980e | |||
2b8a82d0f5 | |||
caf8573bcd | |||
9664d7b6c3 | |||
4e34e5c77d | |||
28d6487ff5 | |||
238fc05854 | |||
fd150699f2 | |||
ca454f663e | |||
1f07f3c045 | |||
3e91da3e08 | |||
094f3b2726 | |||
05c15cc533 | |||
364a6c6d9c | |||
469591c083 | |||
66eca440b2 | |||
a64ac72fce | |||
9564954825 | |||
0d58dff171 | |||
8fc5f4a418 | |||
39ac35935b | |||
bb1cc6bd04 | |||
b5e12f9dae | |||
fccb78c8e5 | |||
1e4d4d2b04 | |||
d1850e34c7 | |||
0e3afd9642 | |||
3bbb9561db | |||
0abf7c70a8 | |||
e99ebf59e3 | |||
f3bfbf2926 | |||
ab4b21acb4 | |||
7b3d157cdc | |||
e100937007 | |||
ba6ef72bfd | |||
d6536fda3d | |||
bb3f99c058 | |||
1edd768a4b | |||
b692ebd822 | |||
010da57392 | |||
f7a65719bf | |||
8fc4f07f9f | |||
097e1d4684 | |||
08d6d443af | |||
93d2ebabda | |||
8a6b7bc53e | |||
8314170438 | |||
f716c1fba8 | |||
06f6e99299 | |||
6364454849 | |||
c215910d06 | |||
5474e380df | |||
fe6e0bd189 | |||
ec30cf89b9 | |||
c67e4593d7 | |||
a0fcc62bf1 | |||
565f156173 | |||
abb84e2a9b | |||
c1f48c6197 | |||
86251b7215 | |||
568f11c003 | |||
139a497071 | |||
b32bd3aa0e | |||
0f9df3f388 | |||
ddbb9cd02c | |||
0cab79cd35 | |||
80411c9466 | |||
6fea980cfd | |||
4754526884 | |||
2fa03671e2 | |||
526674b5e0 | |||
c4bae5f715 | |||
9f905f70de | |||
c7873554c3 | |||
223aed6676 | |||
391097a2a1 | |||
572d90a1a9 | |||
d9f5cbb854 | |||
f97e300dba | |||
ab9ee6c349 | |||
7ef37cb8a7 | |||
6613244573 | |||
5801c2ae00 | |||
bb223881f0 | |||
a4e63dec56 | |||
afbe22ddf6 | |||
e939bb3545 | |||
1c8074bce3 | |||
aa17604a7a | |||
bc7f9ad2fd | |||
c85f921fd2 | |||
d14205bb36 | |||
5e8345695f | |||
b1ee78b1bc | |||
32a03cba0b | |||
fc73d386c9 | |||
2562533727 | |||
d0aae74e18 | |||
ca9b569bfd | |||
d6a700d2b2 | |||
b978065a43 | |||
9a834c5607 | |||
ece169dd76 | |||
2620b94863 | |||
4ca50f5c63 | |||
16b3dcb156 | |||
4c1649d960 | |||
870c640a5b | |||
4cda722cc7 | |||
bf1bfcd773 | |||
ed921d31f8 | |||
53383f7313 | |||
4fa6ed7d23 | |||
373c64e95f | |||
3cca47b0f1 | |||
7d7bdd27c1 | |||
5754c79086 | |||
106193fac5 | |||
eefa093945 | |||
5890fa42a1 | |||
13e86a04e8 | |||
2f67e9740c | |||
618b94e7da | |||
ccfedf5565 | |||
89a1553429 | |||
acb9aa4fd2 | |||
546dad3684 | |||
8b63eafcf2 | |||
fb012ae683 | |||
c46d3e4f6f | |||
4de81cf13d | |||
5c89e16d18 | |||
0ba2258d5c | |||
14c9585b7e | |||
7591b349e0 | |||
0c86bd9a5a | |||
992d453b9a | |||
f0f6981f34 | |||
8b4a233b7a | |||
39fb972589 | |||
6869ceb548 | |||
47ab206f68 | |||
cac981f8f5 | |||
660a046bcc | |||
0abb518177 | |||
7c66579baa | |||
28fd8532b5 | |||
a4ead73672 | |||
5fcb7ed4ce | |||
64fed3d15b | |||
b2883b5fff | |||
775c7aeb95 | |||
79bb324a4a | |||
d19d3823f6 | |||
7255a3dbe0 | |||
59c8c5b34c | |||
ea1bf604c8 | |||
ec1f6664b9 | |||
d02e34764e | |||
ee4927391d | |||
25ec9be340 | |||
bce7118cf1 | |||
a2afdcde7e | |||
5ce77c6f60 | |||
8473f1f3f8 | |||
a8a5c8cd84 | |||
f417872414 | |||
ae713199a7 | |||
9a1a732808 | |||
8a689c9900 | |||
6b77e64ff4 | |||
e2613e7d17 | |||
ff1a857241 | |||
bd52a53615 | |||
a4635d21d6 | |||
0463deed5c | |||
13a991f17f | |||
02bf508e81 | |||
06a695466d | |||
2e944a9fc1 | |||
a75cf7efbe | |||
f6a30dd973 | |||
3d259bbc34 | |||
00e909ea24 | |||
78adc5a0e1 | |||
a6d996d016 | |||
a5f027e896 | |||
67d5c5a26c | |||
7945961cee | |||
1978414ccf | |||
0373d7145d | |||
d91714cdf2 | |||
3516520d2d | |||
992f2a052a | |||
7e15e1b2fa | |||
ac47c7b555 | |||
38112755ce | |||
00482df95b | |||
b40acd505a | |||
b8a650002e | |||
804f47f7ab | |||
b19aa6d5c8 | |||
51a2b655b3 | |||
cd55b3c51f | |||
e5f539695f | |||
9002447181 | |||
1dd57d8022 | |||
0862fdf6bb | |||
7e6637847d | |||
b9245aef0f | |||
9d9af24ace | |||
081397b48a | |||
a13f06f33d | |||
d07a128181 | |||
cad11c40a8 | |||
a6fa6f2776 | |||
d6077792b9 | |||
96e02eeb10 | |||
1705f3d1db | |||
b500c8aace | |||
ab5d2bdc06 | |||
aaf3859b1c | |||
b9fd390601 | |||
d0b22aa38f | |||
cc187bfe0f | |||
95fdaebe15 | |||
6b0d07c6bd | |||
d919d063e4 | |||
d047d1edbb | |||
eb6e877ae4 | |||
97a4c2c94d | |||
a1f42bc137 | |||
0d40ec44cf | |||
c2baf27761 | |||
e623dbeb4d | |||
4cbd5e1b0b | |||
b008c8460b | |||
42577b6016 | |||
09ad1941b7 | |||
e901334748 | |||
bf6fd94ea9 | |||
9acd87730f | |||
d3aab284a2 | |||
52ecc767f8 | |||
1a1231d496 | |||
650b4a9b51 | |||
e8621fbba1 | |||
e211a19c37 | |||
fbc11fa12c | |||
62b02a7500 | |||
37424eb541 | |||
72313a600d | |||
428ee43c18 | |||
cabd5a3941 | |||
a4bfa08393 | |||
5b11952899 | |||
1b0d11177b | |||
4bbc63fd02 | |||
88e252fbfb | |||
1b5e39e448 | |||
b406c9b4e0 | |||
35221f56c9 | |||
2f8cbcb2d1 | |||
e1c806ebe8 | |||
2128c6a2b0 | |||
38fce345cf | |||
fbe1fff088 | |||
4e8d629b63 | |||
a07776d16c | |||
551a3c2168 | |||
52cf2a6094 | |||
7638fb89d6 | |||
84c51afe17 | |||
eb55ad5870 | |||
48b8915689 | |||
779dc7fc7e | |||
0e64b48388 | |||
77cd9df8f7 | |||
114997308b | |||
913cccf98a | |||
4fde6ac15f | |||
b151397d85 | |||
3e4985da8c | |||
e72ef5c094 | |||
5447978191 | |||
842bec2cb3 | |||
213c3c8566 | |||
4e1340ab9e | |||
6119c3a30a | |||
aa5751ac20 | |||
3bea740632 | |||
731e18d083 | |||
94af9493b1 | |||
3b852385d3 | |||
a5745cbeb1 | |||
85aa874f5e | |||
b1fbcd9532 | |||
144bdb8315 | |||
915d3f1b89 | |||
40244d3bcb | |||
a944925124 | |||
063463ba2e | |||
dbd78921c9 | |||
5d7afc86e5 | |||
4bac26bef9 | |||
5e5723334e | |||
89d31ffbe0 | |||
fd40fc96a6 | |||
6e072980a0 | |||
06c7454da6 | |||
004af6dec7 | |||
d1756fa934 | |||
446880de55 | |||
edfd5eaa5b | |||
83fbc3eee0 | |||
13c56c6ea1 | |||
2f6a8014bc | |||
4ee334aee8 | |||
5c403a5cce | |||
594361a056 | |||
df6e4dcd44 | |||
201aa85e68 | |||
a525289ea2 | |||
640f8e85fb | |||
136e741334 | |||
8257ae0a09 | |||
c9a33870ff | |||
60cb42b34d | |||
56a20756c8 | |||
eddd9c9462 | |||
565ecddafd | |||
fc0f3ad0fb | |||
7a507156bd | |||
2f063b28c0 | |||
ed159349ce | |||
fffea6d2a2 | |||
50fab2207c | |||
76dc360641 | |||
ef5fc21a56 | |||
46c92047cb | |||
8e76d4c909 | |||
b891feebc0 | |||
ce21e24a65 | |||
467fb4e9f8 | |||
4a52d35a7c | |||
c8bcc8c611 | |||
aa12139d8d | |||
8824f90e22 | |||
d2f1a27908 | |||
c28dfa6bc7 | |||
44731a54bf | |||
57aba69cb7 | |||
90d88008ee | |||
db8a37a94d | |||
f767c829e4 | |||
00dfa6e797 | |||
ae89b71bd7 | |||
a995358d21 | |||
ac168f71cf | |||
78feb12d5a | |||
4af1f8d57f | |||
9a23e1010a | |||
a370ae5f41 | |||
57492266ca | |||
a2783a048b | |||
b0b555ae7a | |||
f2f2fcdd57 | |||
fb37cb6152 | |||
50d1c212ad | |||
46264774b3 | |||
70f75d51ee | |||
f2880ec3d6 | |||
b71f2f67f4 | |||
a15d79780d | |||
7c495250b4 | |||
a1a2dd370b | |||
09a5f4bec0 | |||
7d96e4f210 | |||
8e3967f2e1 | |||
b6e62e8e77 | |||
c2c76459a1 | |||
0d5d80b1e3 | |||
f1ada16414 | |||
d6b4d96142 | |||
b56ed67dd0 | |||
a584d9869e | |||
9ec38852ae | |||
b2ba5f1ea7 | |||
9ef39d1af6 | |||
8159e98e72 | |||
4409f9bca0 | |||
3f444ef22f | |||
2e7a0fdf4c | |||
dbaccf18f0 | |||
65c7d9cc88 | |||
e5e8ad4785 | |||
7b228c5be0 | |||
1347eac88f | |||
b5a4ef948f | |||
65bb8d30b4 | |||
cca4c3602b | |||
9e880d14ed |
38
.github/ISSUE_TEMPLATE.md
vendored
@ -1,38 +0,0 @@
|
|||||||
# Contribution
|
|
||||||
|
|
||||||
Thank you for your decision to contribute to T-Pot.
|
|
||||||
|
|
||||||
## Issues
|
|
||||||
|
|
||||||
Please feel free to post your problems, ideas and issues [here](https://github.com/dtag-dev-sec/tpotce/issues). We will try to answer ASAP, but to speed things up we encourage you to ...
|
|
||||||
- [ ] Use the [search function](https://github.com/dtag-dev-sec/tpotce/issues?utf8=%E2%9C%93&q=) first
|
|
||||||
- [ ] Check the [FAQ](#faq)
|
|
||||||
- [ ] Provide [basic support information](#info) with regard to your issue
|
|
||||||
|
|
||||||
Thank you :smiley:
|
|
||||||
|
|
||||||
-
|
|
||||||
|
|
||||||
<a name="faq"></a>
|
|
||||||
### FAQ
|
|
||||||
|
|
||||||
##### Where can I find the honeypot logs?
|
|
||||||
###### The honeypot logs are located in `/data/`. You have to login via ssh and run `sudo cd /data/`. Do not change any permissions here or T-Pot will fail to work.
|
|
||||||
|
|
||||||
-
|
|
||||||
|
|
||||||
|
|
||||||
<a name="info"></a>
|
|
||||||
### Baisc support information
|
|
||||||
|
|
||||||
- What T-Pot version are you currtently using?
|
|
||||||
- Are you running on a Intel NUC or a VM?
|
|
||||||
- How long has your installation been running?
|
|
||||||
- Did you install any upgrades or packages?
|
|
||||||
- Did you modify any scripts?
|
|
||||||
- Have you turned persistence on/off?
|
|
||||||
- How much RAM available (login via ssh and run `htop`)?
|
|
||||||
- How much stress are the CPUs under (login via ssh and run `htop`)?
|
|
||||||
- How much swap space is being used (login via ssh and run `htop`)?
|
|
||||||
- How much free disk space is available (login via ssh and run `sudo df -h`)?
|
|
||||||
- What is the current container status (login via ssh and run `sudo start.sh`)?
|
|
37
.github/ISSUE_TEMPLATE/bug-report-for-t-pot.md
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: Bug report for T-Pot
|
||||||
|
about: Bug report for T-Pot
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Before you post your issue make sure it has not been answered yet and provide `basic support information` if you come to the conclusion it is a new issue.
|
||||||
|
|
||||||
|
- 🔍 Use the [search function](https://github.com/dtag-dev-sec/tpotce/issues?utf8=%E2%9C%93&q=) first
|
||||||
|
- 🧐 Check our [WIKI](https://github.com/dtag-dev-sec/tpotce/wiki)
|
||||||
|
- 📚 Consult the documentation of 💻 [Debian](https://www.debian.org/doc/), 🐳 [Docker](https://docs.docker.com/), the 🦌 [ELK stack](https://www.elastic.co/guide/index.html) and the 🍯 [T-Pot Readme](https://github.com/dtag-dev-sec/tpotce/blob/master/README.md).
|
||||||
|
- **⚠️ Provide [basic support information](#info) or similiar information with regard to your issue or we can not help you and will close the issue without further notice**
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="info"></a>
|
||||||
|
## ⚠️ Basic support information (commands are expected to run as `root`)
|
||||||
|
|
||||||
|
- What version of the OS are you currently using `lsb_release -a` and `uname -a`?
|
||||||
|
- What T-Pot version are you currently using?
|
||||||
|
- What edition (Standard, Nextgen, etc.) of T-Pot are you running?
|
||||||
|
- What architecture are you running on (i.e. hardware, cloud, VM, etc.)?
|
||||||
|
- Did you have any problems during the install? If yes, please attach `/install.log` `/install.err`.
|
||||||
|
- How long has your installation been running?
|
||||||
|
- Did you install upgrades, packages or use the update script?
|
||||||
|
- Did you modify any scripts or configs? If yes, please attach the changes.
|
||||||
|
- Please provide a screenshot of `glances` and `htop`.
|
||||||
|
- How much free disk space is available (`df -h`)?
|
||||||
|
- What is the current container status (`dps.sh`)?
|
||||||
|
- What is the status of the T-Pot service (`systemctl status tpot`)?
|
||||||
|
- What ports are being occupied? Stop T-Pot `systemctl stop tpot` and run `netstat -tulpen`
|
||||||
|
- If a single container shows as `DOWN` you can run `docker logs <container-name>` for the latest log entries
|
20
.github/ISSUE_TEMPLATE/feature-request-for-t-pot.md
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request for T-Pot
|
||||||
|
about: Suggest an idea for T-Pot
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
39
.github/ISSUE_TEMPLATE/general-issue-for-t-pot.md
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
name: General issue for T-Pot
|
||||||
|
about: General issue for T-Pot
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
🗨️ Please post your questions in [Discussions](https://github.com/telekom-security/tpotce/discussions) and keep the issues for **issues**. Thank you 😁.<br>
|
||||||
|
|
||||||
|
Before you post your issue make sure it has not been answered yet and provide `basic support information` if you come to the conclusion it is a new issue.
|
||||||
|
|
||||||
|
- 🔍 Use the [search function](https://github.com/dtag-dev-sec/tpotce/issues?utf8=%E2%9C%93&q=) first
|
||||||
|
- 🧐 Check our [WIKI](https://github.com/dtag-dev-sec/tpotce/wiki)
|
||||||
|
- 📚 Consult the documentation of 💻 [Debian](https://www.debian.org/doc/), 🐳 [Docker](https://docs.docker.com/), the 🦌 [ELK stack](https://www.elastic.co/guide/index.html) and the 🍯 [T-Pot Readme](https://github.com/dtag-dev-sec/tpotce/blob/master/README.md).
|
||||||
|
- **⚠️ Provide [basic support information](#info) or similiar information with regard to your issue or we can not help you and will close the issue without further notice**
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="info"></a>
|
||||||
|
## ⚠️ Basic support information (commands are expected to run as `root`)
|
||||||
|
|
||||||
|
- What version of the OS are you currently using `lsb_release -a` and `uname -a`?
|
||||||
|
- What T-Pot version are you currently using?
|
||||||
|
- What edition (Standard, Nextgen, etc.) of T-Pot are you running?
|
||||||
|
- What architecture are you running on (i.e. hardware, cloud, VM, etc.)?
|
||||||
|
- Did you have any problems during the install? If yes, please attach `/install.log` `/install.err`.
|
||||||
|
- How long has your installation been running?
|
||||||
|
- Did you install upgrades, packages or use the update script?
|
||||||
|
- Did you modify any scripts or configs? If yes, please attach the changes.
|
||||||
|
- Please provide a screenshot of `glances` and `htop`.
|
||||||
|
- How much free disk space is available (`df -h`)?
|
||||||
|
- What is the current container status (`dps.sh`)?
|
||||||
|
- What is the status of the T-Pot service (`systemctl status tpot`)?
|
||||||
|
- What ports are being occupied? Stop T-Pot `systemctl stop tpot` and run `netstat -tulpen`
|
||||||
|
- If a single container shows as `DOWN` you can run `docker logs <container-name>` for the latest log entries
|
323
CHANGELOG.md
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 20210222
|
||||||
|
- **New Release 20.06.2**
|
||||||
|
- **Countless Cloud Contributions**
|
||||||
|
- Thanks to @shaderecker
|
||||||
|
|
||||||
|
## 20210219
|
||||||
|
- **Rebuild Snare, Tanner, Redis, Phpox**
|
||||||
|
- Rebuild images to their latest masters and upgrade Alpine OS to 3.13 where possible.
|
||||||
|
- **Bump Elastic Stack to 7.11.1**
|
||||||
|
- Updgrade Elastic Stack Images to 7.11.1 and update License Info to reflect new Elastic License.
|
||||||
|
- Prepare for new release.
|
||||||
|
|
||||||
|
## 20210218
|
||||||
|
- **Rebuild Conpot, EWSPoster, Cowrie, Glutton, Dionaea**
|
||||||
|
- Rebuild images to their latest masters and upgrade Alpine OS to 3.13 where possible.
|
||||||
|
|
||||||
|
## 20210216
|
||||||
|
- **Bump Heralding to 1.0.7**
|
||||||
|
- Rebuild and upgrade image to 1.0.7 and upgrade Alpine OS to 3.13.
|
||||||
|
- Enable SMTPS for Heralding.
|
||||||
|
- **Rebuild IPPHoney, Fatt, EWSPoster, Spiderfoot**
|
||||||
|
- Rebuild images to their latest masters and upgrade Alpine OS to 3.13 where possible.
|
||||||
|
- Upgrade Spiderfoot to 3.3
|
||||||
|
|
||||||
|
## 20210215
|
||||||
|
- **Rebuild Dicompot, p0f, Medpot, Honeysap, Heimdall, Elasticpot, Citrixhoneypot, Ciscoasa**
|
||||||
|
- Rebuild images to their latest masters and upgrade Alpine OS to 3.13 where possible.
|
||||||
|
|
||||||
|
## 20210212
|
||||||
|
- **Rebuild Cyberchef, Adbhoney, Elastic Stack**
|
||||||
|
- Rebuild images to their latest masters and upgrade Alpine OS to 3.13 where possible.
|
||||||
|
- Bump Elastic Stack to 7.11.0
|
||||||
|
- Bump Cyberchef to 9.27.0
|
||||||
|
|
||||||
|
## 20210119
|
||||||
|
- **Bump Dionaea to 0.11.0**
|
||||||
|
- Upgrade Dionaea to 0.11.0, rebuild image and upgrade Alpine OS to 3.13.
|
||||||
|
|
||||||
|
## 20210106
|
||||||
|
- **Update Internet IF retrieval**
|
||||||
|
- To be consistent with @adepasquale PR #746 fatt, glutton and p0f Dockerfiles were updated accordingly.
|
||||||
|
- Merge PR #746 from @adepasquale, thank you!
|
||||||
|
|
||||||
|
## 20201228
|
||||||
|
- **Fix broken SQlite DB**
|
||||||
|
- Fix a broken `app.sqlite` in Heimdall
|
||||||
|
- **Avoid ghcr.io because of slow transfers**
|
||||||
|
- **Remove netselect-apt**
|
||||||
|
- causes too many unpredictable errors #733 as the latest example
|
||||||
|
|
||||||
|
## 20201210
|
||||||
|
- **Bump Elastic Stack 7.10.1, EWSPoster to 1.12**
|
||||||
|
|
||||||
|
## 20201202
|
||||||
|
- **Update Elastic Stack to 7.10.0**
|
||||||
|
|
||||||
|
## 20201130
|
||||||
|
- **Suricata, use suricata-update for rule management**
|
||||||
|
- As a bonus we can now run "suricata-update" using docker-exec, triggering both a rule update and a Suricata rule reload.
|
||||||
|
- Thanks to @adepasquale!
|
||||||
|
|
||||||
|
## 20201126
|
||||||
|
- **Suricata, update suricata.yaml for 6.x**
|
||||||
|
- Merge in the latest updates from suricata-6.0.x while at the same time keeping the custom T-Pot configuration.
|
||||||
|
- Thanks to @adepasquale!
|
||||||
|
- **Bump Cowrie to 2.2.0**
|
||||||
|
|
||||||
|
## 20201028
|
||||||
|
- **Bump Suricata to 5.0.4, Spiderfoot to 3.2.1, Dionaea to 0.9.2, IPPHoney, Heralding, Conpot to latest masters**
|
||||||
|
|
||||||
|
## 20201027
|
||||||
|
- **Bump Dicompot to latest master, Elastic Stack to 7.9.3**
|
||||||
|
|
||||||
|
## 20201005
|
||||||
|
- **Bump Elastic Stack to 7.9.2**
|
||||||
|
- @brianlechthaler, thanks for PR #706, which had issues regarding Elastic Stack and resulted in reverting to 7.9.1
|
||||||
|
|
||||||
|
## 20200904
|
||||||
|
- **Release T-Pot 20.06.1**
|
||||||
|
- Github offers a free Docker Container Registry for public packages. For our Open Source projects we want to make sure to have everything in one place and thus moving from Docker Hub to the GitHub Container Registry.
|
||||||
|
- **Bump Elastic Stack**
|
||||||
|
- Update the Elastic Stack to 7.9.1.
|
||||||
|
- **Rebuild Images**
|
||||||
|
- All docker images were rebuilt based on the latest (and stable running) versions of the tools and honeypots and have been pinned to specific Alpine / Debian versions and git commits so rebuilds will less likely fail.
|
||||||
|
- **Cleaning up**
|
||||||
|
- Clean up old references and links.
|
||||||
|
|
||||||
|
## 20200630
|
||||||
|
- **Release T-Pot 20.06**
|
||||||
|
- After 4 months of public testing with the NextGen edition T-Pot 20.06 can finally be released.
|
||||||
|
- **Debian Buster**
|
||||||
|
- With the release of Debian Buster T-Pot now has access to all packages required right out of the box.
|
||||||
|
- **Add new honeypots**
|
||||||
|
- [Dicompot](https://github.com/nsmfoo/dicompot) by @nsmfoo is a low interaction honeypot for the Dicom protocol which is the international standard to process medical imaging information. Together with Medpot which supports the HL7 protocol T-Pot is now offering a Medical Installation type.
|
||||||
|
- [Honeysap](https://github.com/SecureAuthCorp/HoneySAP) by SecureAuthCorp is a low interaction honeypot for the SAP services, in case of T-Pot configured for the SAP router.
|
||||||
|
- [Elasticpot](https://gitlab.com/bontchev/elasticpot) by Vesselin Bontchev replaces ElasticpotPY as a low interaction honeypot for Elasticsearch with more features, plugins and scripted responses.
|
||||||
|
- **Rebuild Images**
|
||||||
|
- All docker images were rebuilt based on the latest (and stable running) versions of the tools and honeypots. Mostly the images now run on Alpine 3.12 / Debian Buster. However some honeypots / tools still reuire Alpine 3.11 / 3.10 to run properly.
|
||||||
|
- **Install Types**
|
||||||
|
- All docker-compose files (`/opt/tpot/etc/compose`) were remixed and most of the NextGen honeypots are now available in Standard.
|
||||||
|
- There is now a **Medical** Installation Type with Dicompot and Medpot which will be of most interest for medical institutions to get started with T-Pot.
|
||||||
|
- **Update Tools**
|
||||||
|
- Connecting to T-Pot via `https://<ip>:64297` brings you to the T-Pot Landing Page now which is based on Heimdall and the latest NGINX enforcing TLS 1.3.
|
||||||
|
- The ELK stack was updated to 7.8.0 and stripped down to the necessary core functions (where possible) for T-Pot while keeping ELK RAM requirements to a minimum (8GB of RAM is recommended now). The number of index pattern fields was reduced to **697** which increases performance significantly. There are **22** Kibana Dashboards, **397** Kibana Visualizations and **24** Kibana Searches readily available to cover all your needs to get started and familiar with T-Pot.
|
||||||
|
- Cyberchef was updated to 9.21.0.
|
||||||
|
- Elasticsearch Head was updated to the latest version available on GitHub.
|
||||||
|
- Spiderfoot was updated to latest 3.1 dev.
|
||||||
|
- **Landing Page**
|
||||||
|
- After logging into T-Pot via web you are now greeted with a beautifully designed landing page.
|
||||||
|
- **Countless Tweaks and improvements**
|
||||||
|
- Under the hood lots of tiny tweaks, improvements and a few bugfixes will increase your overall experience with T-Pot.
|
||||||
|
|
||||||
|
## 20200316
|
||||||
|
- **Move from Sid to Stable**
|
||||||
|
- Debian Stable has now all the packages and versions we need for T-Pot. As a consequence we can now move to the `stable` branch.
|
||||||
|
|
||||||
|
## 20200310
|
||||||
|
- **Add 2FA to Cockpit**
|
||||||
|
- Just run `2fa.sh` to enable two factor authentication in Cockpit.
|
||||||
|
- **Find fastest mirror with netselect-apt**
|
||||||
|
- Netselect-apt will find the fastest mirror close to you (outgoing ICMP required).
|
||||||
|
|
||||||
|
## 20200309
|
||||||
|
- **Bump Nextgen to 20.06**
|
||||||
|
- All NextGen images have been rebuilt to their latest master.
|
||||||
|
- ElasticStack bumped to 7.6.1 (Elasticsearch will need at least 2048MB of RAM now, T-Pot at least 8GB of RAM) and tweak to accomodate changes of 7.x.
|
||||||
|
- Fixed errors in Tanner / Snare which will now handle downloads of malware via SSL and store them correctly (thanks to @afeena).
|
||||||
|
- Fixed errors in Heralding which will now improve on RDP connections (thanks to @johnnykv, @realsdx).
|
||||||
|
- Fixed error in honeytrap which will now build in Debian/Buster (thanks to @tillmannw).
|
||||||
|
- Mailoney is now logging in JSON format (thanks to @monsherko).
|
||||||
|
- Base T-Pot landing page on Heimdall.
|
||||||
|
- Tweaking of tools and some minor bug fixing
|
||||||
|
|
||||||
|
## 20200116
|
||||||
|
- **Bump ELK to latest 6.8.6**
|
||||||
|
- **Update ISO image to fix upstream bug of missing kernel modules**
|
||||||
|
- **Include dashboards for CitrixHoneypot**
|
||||||
|
- Please run `/opt/tpot/update.sh` for the necessary modifications, omit the reboot and run `/opt/tpot/bin/tped.sh` to (re-)select the NextGen installation type.
|
||||||
|
- This update requires the latest Kibana objects as well. Download the latest from https://raw.githubusercontent.com/telekom-security/tpotce/master/etc/objects/kibana_export.json.zip, unzip and import the objects within Kibana WebUI > Management > Saved Objects > Export / Import". All objects will be overwritten upon import, make sure to run an export first.
|
||||||
|
|
||||||
|
## 20200115
|
||||||
|
- **Prepare integration of CitrixHoneypot**
|
||||||
|
- Prepare integration of [CitrixHoneypot](https://github.com/MalwareTech/CitrixHoneypot) by MalwareTech
|
||||||
|
- Integration into ELK is still open
|
||||||
|
- Please run `/opt/tpot/update.sh` for the necessary modifications, omit the reboot and run `/opt/tpot/bin/tped.sh` to (re-)select the NextGen installation type.
|
||||||
|
|
||||||
|
## 20191224
|
||||||
|
- **Use pigz, optimize logrotate.conf**
|
||||||
|
- Use `pigz` for faster archiving, especially with regard to high volumes of logs - Thanks to @workandresearchgithub!
|
||||||
|
- Optimize `logrotate.conf` to improve archiving speed and get rid of multiple compression, also introduce `pigz`.
|
||||||
|
|
||||||
|
## 20191121
|
||||||
|
- **Bump ADBHoney to latest master**
|
||||||
|
- Use latest version of ADBHoney, which now fully support Python 3.x - Thanks to @huuck!
|
||||||
|
|
||||||
|
## 20191113, 20191104, 20191103, 20191028
|
||||||
|
- **Switch to Debian 10 on OTC, Ansible Improvements**
|
||||||
|
- OTC now supporting Debian 10 - Thanks to @shaderecker!
|
||||||
|
|
||||||
|
## 20191028
|
||||||
|
- **Fix an issue with pip3, yq**
|
||||||
|
- `yq` needs rehashing.
|
||||||
|
|
||||||
|
## 20191026
|
||||||
|
- **Remove cockpit-pcp**
|
||||||
|
- `cockpit-pcp` floods swap for some reason - removing for now.
|
||||||
|
|
||||||
|
## 20191022
|
||||||
|
- **Bump Suricata to 5.0.0**
|
||||||
|
|
||||||
|
## 20191021
|
||||||
|
- **Bump Cowrie to 2.0.0**
|
||||||
|
|
||||||
|
## 20191016
|
||||||
|
- **Tweak installer, pip3, Heralding**
|
||||||
|
- Install `cockpit-pcp` right from the start for machine monitoring in cockpit.
|
||||||
|
- Move installer and update script to use pip3.
|
||||||
|
- Bump heralding to latest master (1.0.6) - Thanks @johnnykv!
|
||||||
|
|
||||||
|
## 20191015
|
||||||
|
- **Tweaking, Bump glutton, unlock ES script**
|
||||||
|
- Add `unlock.sh` to unlock ES indices in case of lockdown after disk quota has been reached.
|
||||||
|
- Prevent too much terminal logging from p0f and glutton since `daemon.log` was filled up.
|
||||||
|
- Bump glutton to latest master now supporting payload_hex. Thanks to @glaslos.
|
||||||
|
|
||||||
|
## 20191002
|
||||||
|
- **Merge**
|
||||||
|
- Support Debian Buster images for AWS #454
|
||||||
|
- Thank you @piffey
|
||||||
|
|
||||||
|
## 20190924
|
||||||
|
- **Bump EWSPoster**
|
||||||
|
- Supports Python 3.x
|
||||||
|
- Thank you @Trixam
|
||||||
|
|
||||||
|
## 20190919
|
||||||
|
- **Merge**
|
||||||
|
- Handle non-interactive shells #454
|
||||||
|
- Thank you @Oogy
|
||||||
|
|
||||||
|
## 20190907
|
||||||
|
- **Logo tweaking**
|
||||||
|
- Add QR logo
|
||||||
|
|
||||||
|
## 20190828
|
||||||
|
- **Upgrades and rebuilds**
|
||||||
|
- Bump Medpot, Nginx and Adbhoney to latest master
|
||||||
|
- Bump ELK stack to 6.8.2
|
||||||
|
- Rebuild Mailoney, Honeytrap, Elasticpot and Ciscoasa
|
||||||
|
- Add 1080p T-Pot wallpaper for download
|
||||||
|
|
||||||
|
## 20190824
|
||||||
|
- **Add some logo work**
|
||||||
|
- Thanks to @thehadilps's suggestion adjusted social preview
|
||||||
|
- Added 4k T-Pot wallpaper for download
|
||||||
|
|
||||||
|
## 20190823
|
||||||
|
- **Fix for broken Fuse package**
|
||||||
|
- Fuse package in upstream is broken
|
||||||
|
- Adjust installer as workaround, fixes #442
|
||||||
|
|
||||||
|
## 20190816
|
||||||
|
- **Upgrades and rebuilds**
|
||||||
|
- Adjust Dionaea to avoid nmap detection, fixes #435 (thanks @iukea1)
|
||||||
|
- Bump Tanner, Cyberchef, Spiderfoot and ES Head to latest master
|
||||||
|
|
||||||
|
## 20190815
|
||||||
|
- **Bump ELK stack to 6.7.2**
|
||||||
|
- Transition to 7.x must iterate slowly through previous versions to prevent changes breaking T-Pots
|
||||||
|
|
||||||
|
## 20190814
|
||||||
|
- **Logstash Translation Maps improvement**
|
||||||
|
- Download translation maps rather than running a git pull
|
||||||
|
- Translation maps will now be bzip2 compressed to reduce traffic to a minimum
|
||||||
|
- Fixes #432
|
||||||
|
|
||||||
|
## 20190802
|
||||||
|
- **Add support for Buster as base image**
|
||||||
|
- Install ISO is now based on Debian Buster
|
||||||
|
- Installation upon Debian Buster is now supported
|
||||||
|
|
||||||
|
## 20190701
|
||||||
|
- **Reworked Ansible T-Pot Deployment**
|
||||||
|
- Transitioned from bash script to all Ansible
|
||||||
|
- Reusable Ansible Playbook for OpenStack clouds
|
||||||
|
- Example Showcase with our Open Telekom Cloud
|
||||||
|
- Adaptable for other cloud providers
|
||||||
|
|
||||||
|
## 20190626
|
||||||
|
- **HPFEEDS Opt-In commandline option**
|
||||||
|
- Pass a hpfeeds config file as a commandline argument
|
||||||
|
- hpfeeds config is saved in `/data/ews/conf/hpfeeds.cfg`
|
||||||
|
- Update script restores hpfeeds config
|
||||||
|
|
||||||
|
## 20190604
|
||||||
|
- **Finalize Fatt support**
|
||||||
|
- Build visualizations, searches, dashboards
|
||||||
|
- Rebuild index patterns
|
||||||
|
- Some finishing touches
|
||||||
|
|
||||||
|
## 20190601
|
||||||
|
- **Start supporting Fatt, remove Glastopf**
|
||||||
|
- Build Dockerfile, Adjust logstash, installer, update and such.
|
||||||
|
- Glastopf is no longer supported within T-Pot
|
||||||
|
|
||||||
|
## 20190528+20190531
|
||||||
|
- **Increase total number of fields**
|
||||||
|
- Adjust total number of fileds for logstash templae from 1000 to 2000.
|
||||||
|
|
||||||
|
## 20190526
|
||||||
|
- **Fix build for Cowrie**
|
||||||
|
- Upstream changes required a new package `py-bcrypt`.
|
||||||
|
|
||||||
|
## 20190525
|
||||||
|
- **Fix build for RDPY**
|
||||||
|
- Building was prevented due to cache error which occurs lately on Alpine if `apk` is using `--no-ache' as options.
|
||||||
|
|
||||||
|
## 20190520
|
||||||
|
- **Adjust permissions for /data folder**
|
||||||
|
- Now it is possible to download files from `/data` using SCP, WINSCP or CyberDuck.
|
||||||
|
|
||||||
|
## 20190513
|
||||||
|
- **Added Ansible T-Pot Deployment on Open Telekom Cloud**
|
||||||
|
- Reusable Ansible Playbooks for all cloud providers
|
||||||
|
- Example Showcase with our Open Telekom Cloud
|
||||||
|
|
||||||
|
## 20190511
|
||||||
|
- **Add hptest script**
|
||||||
|
- Quickly test if the honeypots are working with `hptest.sh <[ip,host]>` based on nmap.
|
||||||
|
|
||||||
|
## 20190508
|
||||||
|
- **Add tsec / install user to tpot group**
|
||||||
|
- For users being able to easily download logs from the /data folder the installer now adds the `tpot` or the logged in user (`who am i`) via `usermod -a -G tpot <user>` to the tpot group. Also /data permissions will now be enforced to `770`, which is necessary for directory listings.
|
||||||
|
|
||||||
|
## 20190502
|
||||||
|
- **Fix KVPs**
|
||||||
|
- Some KVPs for Cowrie changed and the tagcloud was not showing any values in the Cowrie dashboard.
|
||||||
|
- New installations are not affected, however existing installations need to import the objects from /opt/tpot/etc/objects/kibana-objects.json.zip.
|
||||||
|
- **Makeiso**
|
||||||
|
- Move to Xorriso for building the ISO image.
|
||||||
|
- This allows to support most of the Debian based distros, i.e. Debian, MxLinux and Ubuntu.
|
||||||
|
|
||||||
|
## 20190428
|
||||||
|
- **Rebuild ISO**
|
||||||
|
- The install ISO needed a rebuilt after some changes in the Debian mirrors.
|
||||||
|
- **Disable Netselect**
|
||||||
|
- After some reports in the issues that some Debian mirrors were not fully synced and thus some packages were unavailable the netselect-apt feature was disabled.
|
||||||
|
|
||||||
|
## 20190406
|
||||||
|
- **Fix for SSH**
|
||||||
|
- In some situations the SSH Port was not written to a new line (thanks to @dpisano for reporting).
|
||||||
|
- **Fix race condition for apt-fast**
|
||||||
|
- Curl and wget need to be installed before apt-fast installation.
|
||||||
|
|
||||||
|
## 20190404
|
||||||
|
- **Fix #332**
|
||||||
|
- If T-Pot, opposed to the requirements, does not have full internet access netselect-apt fails to determine the fastest mirror as it needs ICMP and UDP outgoing. Should netselect-apt fail the default mirrors will be used.
|
||||||
|
- **Improve install speed with apt-fast**
|
||||||
|
- Migrating from a stable base install to Debian (Sid) requires downloading lots of packages. Depending on your geo location the download speed was already improved by introducing netselect-apt to determine the fastest mirror. With apt-fast the downloads will be even faster by downloading packages not only in parallel but also with multiple connections per package.
|
||||||
|
|
||||||
|
`git log --date=format:"## %Y%m%d" --pretty=format:"%ad %n- **%s**%n - %b"`
|
@ -1,38 +0,0 @@
|
|||||||
# Contribution
|
|
||||||
|
|
||||||
Thank you for your decision to contribute to T-Pot.
|
|
||||||
|
|
||||||
## Issues
|
|
||||||
|
|
||||||
Please feel free to post your problems, ideas and issues [here](https://github.com/dtag-dev-sec/tpotce/issues). We will try to answer ASAP, but to speed things up we encourage you to ...
|
|
||||||
- [ ] Use the [search function](https://github.com/dtag-dev-sec/tpotce/issues?utf8=%E2%9C%93&q=) first
|
|
||||||
- [ ] Check the [FAQ](#faq)
|
|
||||||
- [ ] Provide [basic support information](#info) with regard to your issue
|
|
||||||
|
|
||||||
Thank you :smiley:
|
|
||||||
|
|
||||||
-
|
|
||||||
|
|
||||||
<a name="faq"></a>
|
|
||||||
### FAQ
|
|
||||||
|
|
||||||
##### Where can I find the honeypot logs?
|
|
||||||
###### The honeypot logs are located in `/data/`. You have to login via ssh and run `sudo su -` and then `cd /data/`. Do not change any permissions here or T-Pot will fail to work.
|
|
||||||
|
|
||||||
-
|
|
||||||
|
|
||||||
|
|
||||||
<a name="info"></a>
|
|
||||||
### Basic support information
|
|
||||||
|
|
||||||
- What T-Pot version are you currtently using?
|
|
||||||
- Are you running on a Intel NUC or a VM?
|
|
||||||
- How long has your installation been running?
|
|
||||||
- Did you install any upgrades or packages?
|
|
||||||
- Did you modify any scripts?
|
|
||||||
- Have you turned persistence on/off?
|
|
||||||
- How much RAM available (login via ssh and run `htop`)?
|
|
||||||
- How much stress are the CPUs under (login via ssh and run `htop`)?
|
|
||||||
- How much swap space is being used (login via ssh and run `htop`)?
|
|
||||||
- How much free disk space is available (login via ssh and run `sudo df -h`)?
|
|
||||||
- What is the current container status (login via ssh and run `sudo start.sh`)?
|
|
571
README.md
@ -1,71 +1,81 @@
|
|||||||
# T-Pot 17.10 (Alpha)
|

|
||||||
|
|
||||||
This repository contains the necessary files to create the **[T-Pot](http://dtag-dev-sec.github.io/)** ISO image.
|
T-Pot 20.06 runs on Debian (Stable), is based heavily on
|
||||||
The image can then be used to install T-Pot on a physical or virtual machine.
|
|
||||||
|
|
||||||
In October 2016 we released
|
|
||||||
[T-Pot 16.10](http://dtag-dev-sec.github.io/mediator/feature/2016/10/31/t-pot-16.10.html)
|
|
||||||
|
|
||||||
# T-Pot 17.10 (Alpha - be careful there may be dragons!)
|
|
||||||
|
|
||||||
T-Pot 17.10 uses latest 16.04 LTS Ubuntu Server Network Installer image, is based on
|
|
||||||
|
|
||||||
[docker](https://www.docker.com/), [docker-compose](https://docs.docker.com/compose/)
|
[docker](https://www.docker.com/), [docker-compose](https://docs.docker.com/compose/)
|
||||||
|
|
||||||
and includes dockerized versions of the following honeypots
|
and includes dockerized versions of the following honeypots
|
||||||
|
|
||||||
|
* [adbhoney](https://github.com/huuck/ADBHoney),
|
||||||
|
* [ciscoasa](https://github.com/Cymmetria/ciscoasa_honeypot),
|
||||||
|
* [citrixhoneypot](https://github.com/MalwareTech/CitrixHoneypot),
|
||||||
* [conpot](http://conpot.org/),
|
* [conpot](http://conpot.org/),
|
||||||
* [cowrie](http://www.micheloosterhof.com/cowrie/),
|
* [cowrie](https://github.com/cowrie/cowrie),
|
||||||
|
* [ddospot](https://github.com/aelth/ddospot),
|
||||||
|
* [dicompot](https://github.com/nsmfoo/dicompot),
|
||||||
* [dionaea](https://github.com/DinoTools/dionaea),
|
* [dionaea](https://github.com/DinoTools/dionaea),
|
||||||
* [elasticpot](https://github.com/schmalle/ElasticPot),
|
* [elasticpot](https://gitlab.com/bontchev/elasticpot),
|
||||||
* [emobility](https://github.com/dtag-dev-sec/emobility),
|
* [endlessh](https://github.com/skeeto/endlessh),
|
||||||
* [glastopf](http://glastopf.org/),
|
* [glutton](https://github.com/mushorg/glutton),
|
||||||
|
* [heralding](https://github.com/johnnykv/heralding),
|
||||||
|
* [hellpot](https://github.com/yunginnanet/HellPot),
|
||||||
|
* [honeypots](https://github.com/qeeqbox/honeypots),
|
||||||
|
* [honeypy](https://github.com/foospidy/HoneyPy),
|
||||||
|
* [honeysap](https://github.com/SecureAuthCorp/HoneySAP),
|
||||||
* [honeytrap](https://github.com/armedpot/honeytrap/),
|
* [honeytrap](https://github.com/armedpot/honeytrap/),
|
||||||
|
* [ipphoney](https://gitlab.com/bontchev/ipphoney),
|
||||||
|
* [log4pot](https://github.com/thomaspatzke/Log4Pot),
|
||||||
* [mailoney](https://github.com/awhitehatter/mailoney),
|
* [mailoney](https://github.com/awhitehatter/mailoney),
|
||||||
* [rdpy](https://github.com/citronneur/rdpy) and
|
* [medpot](https://github.com/schmalle/medpot),
|
||||||
* [vnclowpot](https://github.com/magisterquis/vnclowpot)
|
* [rdpy](https://github.com/citronneur/rdpy),
|
||||||
|
* [redishoneypot](https://github.com/cypwnpwnsocute/RedisHoneyPot),
|
||||||
|
* [snare](http://mushmush.org/),
|
||||||
|
* [tanner](http://mushmush.org/)
|
||||||
|
|
||||||
|
|
||||||
Furthermore we use the following tools
|
Furthermore T-Pot includes the following tools
|
||||||
|
|
||||||
|
* [Cockpit](https://cockpit-project.org/running) for a lightweight, webui for docker, os, real-time performance monitoring and web terminal.
|
||||||
|
* [Cyberchef](https://gchq.github.io/CyberChef/) a web app for encryption, encoding, compression and data analysis.
|
||||||
* [ELK stack](https://www.elastic.co/videos) to beautifully visualize all the events captured by T-Pot.
|
* [ELK stack](https://www.elastic.co/videos) to beautifully visualize all the events captured by T-Pot.
|
||||||
* [Elasticsearch Head](https://mobz.github.io/elasticsearch-head/) a web front end for browsing and interacting with an Elastic Search cluster.
|
* [Elasticsearch Head](https://mobz.github.io/elasticsearch-head/) a web front end for browsing and interacting with an Elastic Search cluster.
|
||||||
* [Netdata](http://my-netdata.io/) for real-time performance monitoring.
|
* [Fatt](https://github.com/0x4D31/fatt) a pyshark based script for extracting network metadata and fingerprints from pcap files and live network traffic.
|
||||||
* [Portainer](http://portainer.io/) a web based UI for docker.
|
|
||||||
* [Spiderfoot](https://github.com/smicallef/spiderfoot) a open source intelligence automation tool.
|
* [Spiderfoot](https://github.com/smicallef/spiderfoot) a open source intelligence automation tool.
|
||||||
* [Suricata](http://suricata-ids.org/) a Network Security Monitoring engine.
|
* [Suricata](http://suricata-ids.org/) a Network Security Monitoring engine.
|
||||||
* [Wetty](https://github.com/krishnasrinivas/wetty) a web based SSH client.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TL;DR
|
# TL;DR
|
||||||
1. Meet the [system requirements](#requirements). The T-Pot installation needs at least 4 GB RAM and 64 GB free disk space as well as a working internet connection.
|
1. Meet the [system requirements](#requirements). The T-Pot installation needs at least 8 GB RAM and 128 GB free disk space as well as a working (outgoing non-filtered) internet connection.
|
||||||
2. Download the T-Pot ISO from [GitHub](https://github.com/dtag-dev-sec/tpotce/releases) or [create it yourself](#createiso).
|
2. Download the T-Pot ISO from [GitHub](https://github.com/telekom-security/tpotce/releases) or [create it yourself](#createiso).
|
||||||
3. Install the system in a [VM](#vm) or on [physical hardware](#hw) with [internet access](#placement).
|
3. Install the system in a [VM](#vm) or on [physical hardware](#hw) with [internet access](#placement).
|
||||||
4. Enjoy your favorite beverage - [watch](http://sicherheitstacho.eu/?peers=communityPeers) and [analyze](#kibana).
|
4. Enjoy your favorite beverage - [watch](https://sicherheitstacho.eu) and [analyze](#kibana).
|
||||||
|
|
||||||
Seeing is believing :bowtie:
|
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=SNo7CkQ7ZWQ)
|
|
||||||
|
|
||||||
|
|
||||||
# Table of Contents
|
# Table of Contents
|
||||||
- [Changelog](#changelog)
|
|
||||||
- [Technical Concept](#concept)
|
- [Technical Concept](#concept)
|
||||||
- [System Requirements](#requirements)
|
- [System Requirements](#requirements)
|
||||||
|
- [Installation Types](#types)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Prebuilt ISO Image](#prebuilt)
|
- [Prebuilt ISO Image](#prebuilt)
|
||||||
- [Create your own ISO Image](#createiso)
|
- [Create your own ISO Image](#createiso)
|
||||||
- [Running in a VM](#vm)
|
- [Running in a VM](#vm)
|
||||||
- [Running on Hardware](#hardware)
|
- [Running on Hardware](#hardware)
|
||||||
|
- [Post Install User](#postinstall)
|
||||||
|
- [Post Install Auto](#postinstallauto)
|
||||||
|
- [Cloud Deployments](#cloud)
|
||||||
|
- [Ansible](#ansible)
|
||||||
|
- [Terraform](#terraform)
|
||||||
- [First Run](#firstrun)
|
- [First Run](#firstrun)
|
||||||
- [System Placement](#placement)
|
- [System Placement](#placement)
|
||||||
|
- [Updates](#updates)
|
||||||
- [Options](#options)
|
- [Options](#options)
|
||||||
- [SSH and web access](#ssh)
|
- [SSH and web access](#ssh)
|
||||||
|
- [T-Pot Landing Page](#heimdall)
|
||||||
- [Kibana Dashboard](#kibana)
|
- [Kibana Dashboard](#kibana)
|
||||||
- [Tools](#tools)
|
- [Tools](#tools)
|
||||||
- [Maintenance](#maintenance)
|
- [Maintenance](#maintenance)
|
||||||
- [Community Data Submission](#submission)
|
- [Community Data Submission](#submission)
|
||||||
|
- [Opt-In HPFEEDS Data Submission](#hpfeeds-optin)
|
||||||
- [Roadmap](#roadmap)
|
- [Roadmap](#roadmap)
|
||||||
- [Disclaimer](#disclaimer)
|
- [Disclaimer](#disclaimer)
|
||||||
- [FAQ](#faq)
|
- [FAQ](#faq)
|
||||||
@ -73,169 +83,133 @@ Seeing is believing :bowtie:
|
|||||||
- [Licenses](#licenses)
|
- [Licenses](#licenses)
|
||||||
- [Credits](#credits)
|
- [Credits](#credits)
|
||||||
- [Stay tuned](#staytuned)
|
- [Stay tuned](#staytuned)
|
||||||
- [Fun Fact](#funfact)
|
- [Testimonial](#testimonial)
|
||||||
|
|
||||||
<a name="background"></a>
|
|
||||||
# Changelog
|
|
||||||
- **Size still matters** 😅
|
|
||||||
- All docker images have been rebuilt as micro containers based on Alpine Linux to even further reduce the image size and leading to image sizes (compressed) below the 50 MB mark. The uncompressed size of eMobility and the ELK stack could each be reduced by a whopping 600 MB!
|
|
||||||
- A "Everything" installation now takes roughly 1.6 GB download size
|
|
||||||
- **docker-compose**
|
|
||||||
- T-Pot containers are now being controlled and monitored through docker-compose and a single configuration file `/etc/tpot/tpot.yml` allowing for greater flexibility and resulting in easier image management (i.e. updated images).
|
|
||||||
- As a benefit only a single `systemd` script `/etc/systemd/system/tpot.service` is needed to start `systemctl start tpot` and stop `systemctl stop tpot` the T-Pot services.
|
|
||||||
- There are four pre-configured compose configurations which do reflect the T-Pot editions `/etc/tpot/compose`. Simply stop the T-Pot services and copy i.e. `cp /etc/tpot/compose/all.yml /etc/tpot/tpot.yml`, restart the T-Pot services and the selcted edition will be running after downloading the required docker images.
|
|
||||||
|
|
||||||
- **Introducing** [Spiderfoot](https://github.com/smicallef/spiderfoot) a open source intelligence automation tool.
|
|
||||||
- **Installation** procedure simplified
|
|
||||||
- Within the Ubuntu Installer you only have to choose language settings
|
|
||||||
- After the first reboot the T-Pot installer checks if internet and required services are reachable before the installation procedure begins
|
|
||||||
- T-Pot Installer now uses a “dialog” which looks way better than the old text based installer
|
|
||||||
- `tsec` user & password dialog is now part of the T-Pot Installer
|
|
||||||
- The self-signed certificate is now created automatically to reduce unnecessary overhead for novice users
|
|
||||||
- New ASCII logo and login screen pointing to web and ssh logins
|
|
||||||
- Hostnames are now generated using an offline name generator, which still produces funny and collision free hostnames
|
|
||||||
- **CVE IDs for Suricata**
|
|
||||||
- Our very own [Listbot](https://github.com/dtag-dev-sec/listbot) builds translation maps for Logstash. If Logstash registers a match the events' CVE ID will be stored alongside the event within Elasticsearch.
|
|
||||||
- **IP Reputations**
|
|
||||||
- [Listbot](https://github.com/dtag-dev-sec/listbot) also builds translation maps for blacklisted IPs
|
|
||||||
- Based upon 30+ publicly available IP blacklisting sources listbot creates a logstash translation map matching the events' source IP addresses against the IPs reputation
|
|
||||||
- If the source IP is known to a blacklist service a corresponding tag will be stored with the event
|
|
||||||
- Updates occur on every logstash container start; by default every 24h
|
|
||||||
- **Honeypot updates and improvements**
|
|
||||||
- All honeypots were updated to their latest & stable versions.
|
|
||||||
- **New Honeypots** were added ...
|
|
||||||
* [mailoney](https://github.com/awhitehatter/mailoney)
|
|
||||||
- A low interaction SMTP honeypot
|
|
||||||
* [rdpy](https://github.com/citronneur/rdpy)
|
|
||||||
- A low interaction RDP honeypot
|
|
||||||
* [vnclowpot](https://github.com/magisterquis/vnclowpot)
|
|
||||||
- A low interaction VNC honeypot
|
|
||||||
- **Persistence** is now enabled by default and will keep honeypot logs and tools data in `/data/` and its sub-folders by default for 30 days. You may change that behavior in `/etc/tpot/logrotate/logrotate.conf`. ELK data however will be kept for 90 days by default. You may change that behavior in `/etc/tpot/curator/actions.yml`. Scripts will be triggered through `/etc/crontab`.
|
|
||||||
- **Updates**
|
|
||||||
- **Docker** was updated to the latest **1.12.6** release within Ubuntu 16.04.x LTS
|
|
||||||
- **ELK** was updated to the latest **Kibana 5.6.1**, **Elasticsearch 5.6.1** and **Logstash 5.6.1** releases.
|
|
||||||
- **Suricata** was updated to the latest **4.0.0** version including the latest **Emerging Threats** community ruleset.
|
|
||||||
|
|
||||||
- **Dashboards Makeover**
|
|
||||||
- We now have **160+ Visualizations** pre-configured and compiled to 14 individual **Kibana Dashboards** for every honeypot. Monitor all *honeypot events* locally on your T-Pot installation. Aside from *honeypot events* you can also view *Suricata NSM, Syslog and NGINX* events for a quick overview of local host events.
|
|
||||||
- View available IP reputation of any source IP address
|
|
||||||
- View available CVE ID for events
|
|
||||||
- More **Smart links** are now included.
|
|
||||||
|
|
||||||
<a name="concept"></a>
|
<a name="concept"></a>
|
||||||
# Technical Concept
|
# Technical Concept
|
||||||
|
|
||||||
T-Pot is based on the network installer of Ubuntu Server 16.04.x LTS.
|
T-Pot is based on the Debian (Stable) network installer.
|
||||||
The honeypot daemons as well as other support components being used have been containerized using [docker](http://docker.io).
|
The honeypot daemons as well as other support components are [dockered](http://docker.io).
|
||||||
This allows us to run multiple honeypot daemons on the same network interface while maintaining a small footprint and constrain each honeypot within its own environment.
|
This allows T-Pot to run multiple honeypot daemons and tools on the same network interface while maintaining a small footprint and constrain each honeypot within its own environment.
|
||||||
|
|
||||||
In T-Pot we combine the dockerized honeypots
|
In T-Pot we combine the dockerized honeypots ...
|
||||||
[conpot](http://conpot.org/),
|
* [adbhoney](https://github.com/huuck/ADBHoney),
|
||||||
[cowrie](http://www.micheloosterhof.com/cowrie/),
|
* [ciscoasa](https://github.com/Cymmetria/ciscoasa_honeypot),
|
||||||
[dionaea](https://github.com/DinoTools/dionaea),
|
* [citrixhoneypot](https://github.com/MalwareTech/CitrixHoneypot),
|
||||||
[elasticpot](https://github.com/schmalle/ElasticPot),
|
* [conpot](http://conpot.org/),
|
||||||
[emobility](https://github.com/dtag-dev-sec/emobility),
|
* [cowrie](http://www.micheloosterhof.com/cowrie/),
|
||||||
[glastopf](http://glastopf.org/),
|
* [ddospot](https://github.com/aelth/ddospot),
|
||||||
[honeytrap](https://github.com/armedpot/honeytrap/),
|
* [dicompot](https://github.com/nsmfoo/dicompot),
|
||||||
[mailoney](https://github.com/awhitehatter/mailoney),
|
* [dionaea](https://github.com/DinoTools/dionaea),
|
||||||
[rdpy](https://github.com/citronneur/rdpy) and
|
* [elasticpot](https://gitlab.com/bontchev/elasticpot),
|
||||||
[vnclowpot](https://github.com/magisterquis/vnclowpot) with
|
* [endlessh](https://github.com/skeeto/endlessh),
|
||||||
[ELK stack](https://www.elastic.co/videos) to beautifully visualize all the events captured by T-Pot,
|
* [glutton](https://github.com/mushorg/glutton),
|
||||||
[Elasticsearch Head](https://mobz.github.io/elasticsearch-head/) a web front end for browsing and interacting with an Elastic Search cluster,
|
* [heralding](https://github.com/johnnykv/heralding),
|
||||||
[Netdata](http://my-netdata.io/) for real-time performance monitoring,
|
* [hellpot](https://github.com/yunginnanet/HellPot),
|
||||||
[Portainer](http://portainer.io/) a web based UI for docker,
|
* [honeypots](https://github.com/qeeqbox/honeypots),
|
||||||
[Spiderfoot](https://github.com/smicallef/spiderfoot) a open source intelligence automation tool,
|
* [honeypy](https://github.com/foospidy/HoneyPy),
|
||||||
[Suricata](http://suricata-ids.org/) a Network Security Monitoring engine and
|
* [honeysap](https://github.com/SecureAuthCorp/HoneySAP),
|
||||||
[Wetty](https://github.com/krishnasrinivas/wetty) a web based SSH client.
|
* [honeytrap](https://github.com/armedpot/honeytrap/),
|
||||||
|
* [ipphoney](https://gitlab.com/bontchev/ipphoney),
|
||||||
|
* [log4pot](https://github.com/thomaspatzke/Log4Pot),
|
||||||
|
* [mailoney](https://github.com/awhitehatter/mailoney),
|
||||||
|
* [medpot](https://github.com/schmalle/medpot),
|
||||||
|
* [redishoneypot](https://github.com/cypwnpwnsocute/RedisHoneyPot),
|
||||||
|
* [rdpy](https://github.com/citronneur/rdpy),
|
||||||
|
* [snare](http://mushmush.org/),
|
||||||
|
* [tanner](http://mushmush.org/)
|
||||||
|
|
||||||

|
... with the following tools ...
|
||||||
|
* [Cockpit](https://cockpit-project.org/running) for a lightweight, webui for docker, os, real-time performance monitoring and web terminal.
|
||||||
|
* [Cyberchef](https://gchq.github.io/CyberChef/) a web app for encryption, encoding, compression and data analysis.
|
||||||
|
* [ELK stack](https://www.elastic.co/videos) to beautifully visualize all the events captured by T-Pot.
|
||||||
|
* [Elasticsearch Head](https://mobz.github.io/elasticsearch-head/) a web front end for browsing and interacting with an Elastic Search cluster.
|
||||||
|
* [Fatt](https://github.com/0x4D31/fatt) a pyshark based script for extracting network metadata and fingerprints from pcap files and live network traffic.
|
||||||
|
* [Spiderfoot](https://github.com/smicallef/spiderfoot) a open source intelligence automation tool.
|
||||||
|
* [Suricata](http://suricata-ids.org/) a Network Security Monitoring engine.
|
||||||
|
|
||||||
While data within docker containers is volatile we do now ensure a default 30 day persistence of all relevant honeypot and tool data in the well known `/data` folder and sub-folders. The persistence configuration may be adjusted in `/etc/tpot/logrotate/logrotate.conf`. Once a docker container crashes, all other data produced within its environment is erased and a fresh instance is started from the corresponding docker image.<br>
|
... to give you the best out-of-the-box experience possible and an easy-to-use multi-honeypot appliance.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
While data within docker containers is volatile T-Pot ensures a default 30 day persistence of all relevant honeypot and tool data in the well known `/data` folder and sub-folders. The persistence configuration may be adjusted in `/opt/tpot/etc/logrotate/logrotate.conf`. Once a docker container crashes, all other data produced within its environment is erased and a fresh instance is started from the corresponding docker image.<br>
|
||||||
|
|
||||||
Basically, what happens when the system is booted up is the following:
|
Basically, what happens when the system is booted up is the following:
|
||||||
|
|
||||||
- start host system
|
- start host system
|
||||||
- start all the necessary services (i.e. docker-engine, reverse proxy, etc.)
|
- start all the necessary services (i.e. cockpit, docker, etc.)
|
||||||
- start all docker containers via docker-compose (honeypots, nms, elk)
|
- start all docker containers via docker-compose (honeypots, nms, elk, etc.)
|
||||||
|
|
||||||
Within the T-Pot project, we provide all the tools and documentation necessary to build your own honeypot system and contribute to our [community data view](http://sicherheitstacho.eu/?peers=communityPeers), a separate channel on our [Sicherheitstacho](http://sicherheitstacho.eu) that is powered by T-Pot community data.
|
The T-Pot project provides all the tools and documentation necessary to build your own honeypot system and contribute to our [Sicherheitstacho](https://sicherheitstacho.eu).
|
||||||
|
|
||||||
The source code and configuration files are stored in individual GitHub repositories, which are linked below. The docker images are pre-configured for the T-Pot environment. If you want to run the docker images separately, make sure you study the docker-compose configuration (`/etc/tpot/tpot.yml`) and the T-Pot systemd script (`/etc/systemd/system/tpot.service`), as they provide a good starting point for implementing changes.
|
The source code and configuration files are fully stored in the T-Pot GitHub repository. The docker images are preconfigured for the T-Pot environment. If you want to run the docker images separately, make sure you study the docker-compose configuration (`/opt/tpot/etc/tpot.yml`) and the T-Pot systemd script (`/etc/systemd/system/tpot.service`), as they provide a good starting point for implementing changes.
|
||||||
|
|
||||||
The individual docker configurations are located in the following GitHub repositories:
|
The individual docker configurations are located in the [docker folder](https://github.com/telekom-security/tpotce/tree/master/docker).
|
||||||
|
|
||||||
- [conpot](https://github.com/dtag-dev-sec/conpot)
|
|
||||||
- [cowrie](https://github.com/dtag-dev-sec/cowrie)
|
|
||||||
- [dionaea](https://github.com/dtag-dev-sec/dionaea)
|
|
||||||
- [elasticpot](https://github.com/dtag-dev-sec/elasticpot)
|
|
||||||
- [elk-stack](https://github.com/dtag-dev-sec/elk)
|
|
||||||
- [emobility](https://github.com/dtag-dev-sec/emobility)
|
|
||||||
- [ewsposter](https://github.com/dtag-dev-sec/ews)
|
|
||||||
- [glastopf](https://github.com/dtag-dev-sec/glastopf)
|
|
||||||
- [honeytrap](https://github.com/dtag-dev-sec/honeytrap)
|
|
||||||
- [mailoney](https://github.com/dtag-dev-sec/mailoney)
|
|
||||||
- [netdata](https://github.com/dtag-dev-sec/netdata)
|
|
||||||
- [portainer](https://github.com/dtag-dev-sec/ui-for-docker)
|
|
||||||
- [rdpy](https://github.com/dtag-dev-sec/rdpy)
|
|
||||||
- [spiderfoot](https://github.com/dtag-dev-sec/spiderfoot)
|
|
||||||
- [suricata & p0f](https://github.com/dtag-dev-sec/suricata)
|
|
||||||
- [vnclowpot](https://github.com/dtag-dev-sec/vnclowpot)
|
|
||||||
|
|
||||||
<a name="requirements"></a>
|
<a name="requirements"></a>
|
||||||
# System Requirements
|
# System Requirements
|
||||||
Depending on your installation type, whether you install on [real hardware](#hardware) or in a [virtual machine](#vm), make sure your designated T-Pot system meets the following requirements:
|
Depending on the installation type, whether installing on [real hardware](#hardware) or in a [virtual machine](#vm), make sure the designated system meets the following requirements:
|
||||||
|
|
||||||
##### T-Pot Installation (Cowrie, Dionaea, ElasticPot, Glastopf, Honeytrap, Mailoney, Rdpy, Vnclowpot, ELK, Suricata+P0f & Tools)
|
- 8 GB RAM (less RAM is possible but might introduce swapping / instabilities)
|
||||||
When installing the T-Pot ISO image, make sure the target system (physical/virtual) meets the following minimum requirements:
|
- 128 GB SSD (smaller is possible but limits the capacity of storing events)
|
||||||
|
|
||||||
- 4 GB RAM (6-8 GB recommended)
|
|
||||||
- 64 GB SSD (128 GB SSD recommended)
|
|
||||||
- Network via DHCP
|
- Network via DHCP
|
||||||
- A working, non-proxied, internet connection
|
- A working, non-proxied, internet connection
|
||||||
|
|
||||||
##### Honeypot Installation (Cowrie, Dionaea, ElasticPot, Glastopf, Honeytrap, Mailoney, Rdpy, Vnclowpot)
|
|
||||||
When installing the T-Pot ISO image, make sure the target system (physical/virtual) meets the following minimum requirements:
|
|
||||||
|
|
||||||
- 3 GB RAM (4-6 GB recommended)
|
<a name="types"></a>
|
||||||
- 64 GB SSD (64 GB SSD recommended)
|
# Installation Types
|
||||||
- Network via DHCP
|
There are prebuilt installation types available each focussing on different aspects to get you started right out of the box. The docker-compose files are located in `/opt/tpot/etc/compose`. If you want to build your own compose file just create a new one (based on the layout and settings of the prebuilds) in `/opt/tpot/etc/compose` and run `tped.sh` afterwards to point T-Pot to the new compose file and run you personalized edition.
|
||||||
- A working, non-proxied, internet connection
|
|
||||||
|
|
||||||
##### Industrial Installation (ConPot, eMobility, ELK, Suricata+P0f & Tools)
|
##### Standard
|
||||||
When installing the T-Pot ISO image, make sure the target system (physical/virtual) meets the following minimum requirements:
|
- Honeypots: adbhoney, ciscoasa, citrixhoneypot, conpot, cowrie, dicompot, dionaea, elasticpot, heralding, honeysap, honeytrap, mailoney, medpot, rdpy, snare & tanner
|
||||||
|
- Tools: cockpit, cyberchef, ELK, fatt, elasticsearch head, ewsposter, nginx / heimdall, spiderfoot, p0f & suricata
|
||||||
|
|
||||||
- 4 GB RAM (8 GB recommended)
|
|
||||||
- 64 GB SSD (128 GB SSD recommended)
|
|
||||||
- Network via DHCP
|
|
||||||
- A working, non-proxied, internet connection
|
|
||||||
|
|
||||||
##### Everything Installation (Everything, all of the above)
|
##### Sensor
|
||||||
When installing the T-Pot ISO image, make sure the target system (physical/virtual) meets the following minimum requirements:
|
- Honeypots: adbhoney, ciscoasa, citrixhoneypot, conpot, cowrie, dicompot, dionaea, elasticpot, heralding, honeypy, honeysap, honeytrap, mailoney, medpot, rdpy, snare & tanner
|
||||||
|
- Tools: cockpit, ewsposter, fatt, p0f & suricata
|
||||||
|
- Since there is no ELK stack provided the Sensor Installation only requires 4 GB of RAM.
|
||||||
|
|
||||||
|
|
||||||
|
##### Industrial
|
||||||
|
- Honeypots: conpot, cowrie, dicompot, heralding, honeysap, honeytrap, medpot & rdpy
|
||||||
|
- Tools: cockpit, cyberchef, ELK, fatt, elasticsearch head, ewsposter, nginx / heimdall, spiderfoot, p0f & suricata
|
||||||
|
|
||||||
|
|
||||||
|
##### Collector
|
||||||
|
- Honeypots: heralding & honeytrap
|
||||||
|
- Tools: cockpit, cyberchef, fatt, ELK, elasticsearch head, ewsposter, nginx / heimdall, spiderfoot, p0f & suricata
|
||||||
|
|
||||||
|
|
||||||
|
##### NextGen
|
||||||
|
- Honeypots: adbhoney, ciscoasa, citrixhoneypot, conpot, cowrie, dicompot, dionaea, glutton, heralding, honeypy, honeysap, ipphoney, mailoney, medpot, rdpy, snare & tanner
|
||||||
|
- Tools: cockpit, cyberchef, ELK, fatt, elasticsearch head, ewsposter, nginx / heimdall, spiderfoot, p0f & suricata
|
||||||
|
|
||||||
|
|
||||||
|
##### Medical
|
||||||
|
- Honeypots: dicompot & medpot
|
||||||
|
- Tools: cockpit, cyberchef, ELK, fatt, elasticsearch head, ewsposter, nginx / heimdall, spiderfoot, p0f & suricata
|
||||||
|
|
||||||
- 8+ GB RAM
|
|
||||||
- 128+ GB SSD
|
|
||||||
- Network via DHCP
|
|
||||||
- A working, non-proxied, internet connection
|
|
||||||
|
|
||||||
<a name="installation"></a>
|
<a name="installation"></a>
|
||||||
# Installation
|
# Installation
|
||||||
The installation of T-Pot is straight forward and heavily depends on a working, transparent and non-proxied up and running internet connection. Otherwise the installation **will fail!**
|
The installation of T-Pot is straight forward and heavily depends on a working, transparent and non-proxied up and running internet connection. Otherwise the installation **will fail!**
|
||||||
|
|
||||||
Firstly, decide if you want to download our prebuilt installation ISO image from [GitHub](https://github.com/dtag-dev-sec/tpotce/releases) ***or*** [create it yourself](#createiso).
|
Firstly, decide if you want to download the prebuilt installation ISO image from [GitHub](https://github.com/telekom-security/tpotce/releases), [create it yourself](#createiso) ***or*** [post-install on an existing Debian 10 (Buster)](#postinstall).
|
||||||
|
|
||||||
Secondly, decide where you want to let the system run: [real hardware](#hardware) or in a [virtual machine](#vm)?
|
Secondly, decide where you the system to run: [real hardware](#hardware) or in a [virtual machine](#vm)?
|
||||||
|
|
||||||
<a name="prebuilt"></a>
|
<a name="prebuilt"></a>
|
||||||
## Prebuilt ISO Image
|
## Prebuilt ISO Image
|
||||||
We provide an installation ISO image for download (~50MB), which is created using the same [tool](https://github.com/dtag-dev-sec/tpotce) you can use yourself in order to create your own image. It will basically just save you some time downloading components and creating the ISO image.
|
An installation ISO image is available for download (~50MB), which is created by the [ISO Creator](https://github.com/telekom-security/tpotce) you can use yourself in order to create your own image. It will basically just save you some time downloading components and creating the ISO image.
|
||||||
You can download the prebuilt installation image from [GitHub](https://github.com/dtag-dev-sec/tpotce/releases) and jump to the [installation](#vm) section.
|
You can download the prebuilt installation ISO from [GitHub](https://github.com/telekom-security/tpotce/releases) and jump to the [installation](#vm) section.
|
||||||
|
|
||||||
<a name="createiso"></a>
|
<a name="createiso"></a>
|
||||||
## Create your own ISO Image
|
## Create your own ISO Image
|
||||||
For transparency reasons and to give you the ability to customize your install, we provide you the [ISO Creator](https://github.com/dtag-dev-sec/tpotce) that enables you to create your own ISO installation image.
|
For transparency reasons and to give you the ability to customize your install you use the [ISO Creator](https://github.com/telekom-security/tpotce) that enables you to create your own ISO installation image.
|
||||||
|
|
||||||
**Requirements to create the ISO image:**
|
**Requirements to create the ISO image:**
|
||||||
- Ubuntu 16.04 LTS or newer as host system (others *may* work, but remain untested)
|
- Debian 10 as host system (others *may* work, but *remain* untested)
|
||||||
- 4GB of free memory
|
- 4GB of free memory
|
||||||
- 32GB of free storage
|
- 32GB of free storage
|
||||||
- A working internet connection
|
- A working internet connection
|
||||||
@ -244,27 +218,27 @@ For transparency reasons and to give you the ability to customize your install,
|
|||||||
|
|
||||||
1. Clone the repository and enter it.
|
1. Clone the repository and enter it.
|
||||||
```
|
```
|
||||||
git clone https://github.com/dtag-dev-sec/tpotce
|
git clone https://github.com/telekom-security/tpotce
|
||||||
cd tpotce
|
cd tpotce
|
||||||
```
|
```
|
||||||
2. Invoke the script that builds the ISO image.
|
2. Run the `makeiso.sh` script to build the ISO image.
|
||||||
The script will download and install dependencies necessary to build the image on the invoking machine. It will further download the ubuntu network installer image (~50MB) which T-Pot is based on.
|
The script will download and install dependencies necessary to build the image on the invoking machine. It will further download the ubuntu network installer image (~50MB) which T-Pot is based on.
|
||||||
```
|
```
|
||||||
sudo ./makeiso.sh
|
sudo ./makeiso.sh
|
||||||
```
|
```
|
||||||
After a successful build, you will find the ISO image `tpot.iso` along with a SHA256 checksum `tpot.sha256`in your directory.
|
After a successful build, you will find the ISO image `tpot.iso` along with a SHA256 checksum `tpot.sha256` in your folder.
|
||||||
|
|
||||||
<a name="vm"></a>
|
<a name="vm"></a>
|
||||||
## Running in VM
|
## Running in VM
|
||||||
You may want to run T-Pot in a virtualized environment. The virtual system configuration depends on your virtualization provider.
|
You may want to run T-Pot in a virtualized environment. The virtual system configuration depends on your virtualization provider.
|
||||||
|
|
||||||
We successfully tested T-Pot with [VirtualBox](https://www.virtualbox.org) and [VMWare](http://www.vmware.com) with just little modifications to the default machine configurations.
|
T-Pot is successfully tested with [VirtualBox](https://www.virtualbox.org) and [VMWare](http://www.vmware.com) with just little modifications to the default machine configurations.
|
||||||
|
|
||||||
It is important to make sure you meet the [system requirements](#requirements) and assign a virtual harddisk >=64 GB, >=4 GB RAM and bridged networking to T-Pot.
|
It is important to make sure you meet the [system requirements](#requirements) and assign virtual harddisk and RAM according to the requirements while making sure networking is bridged.
|
||||||
|
|
||||||
You need to enable promiscuous mode for the network interface for suricata and p0f to work properly. Make sure you enable it during configuration.
|
You need to enable promiscuous mode for the network interface for fatt, suricata and p0f to work properly. Make sure you enable it during configuration.
|
||||||
|
|
||||||
If you want to use a wifi card as primary NIC for T-Pot, please be aware of the fact that not all network interface drivers support all wireless cards. E.g. in VirtualBox, you then have to choose the *"MT SERVER"* model of the NIC.
|
If you want to use a wifi card as a primary NIC for T-Pot, please be aware that not all network interface drivers support all wireless cards. In VirtualBox e.g. you have to choose the *"MT SERVER"* model of the NIC.
|
||||||
|
|
||||||
Lastly, mount the `tpot.iso` ISO to the VM and continue with the installation.<br>
|
Lastly, mount the `tpot.iso` ISO to the VM and continue with the installation.<br>
|
||||||
|
|
||||||
@ -275,96 +249,197 @@ You can now jump [here](#firstrun).
|
|||||||
If you decide to run T-Pot on dedicated hardware, just follow these steps:
|
If you decide to run T-Pot on dedicated hardware, just follow these steps:
|
||||||
|
|
||||||
1. Burn a CD from the ISO image or make a bootable USB stick using the image. <br>
|
1. Burn a CD from the ISO image or make a bootable USB stick using the image. <br>
|
||||||
Whereas most CD burning tools allow you to burn from ISO images, the procedure to create a bootable USB stick from an ISO image depends on your system. There are various Windows GUI tools available, e.g. [this tip](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-windows) might help you.<br> On [Linux](http://askubuntu.com/questions/59551/how-to-burn-a-iso-to-a-usb-device) or [MacOS](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-mac-osx) you can use the tool *dd* or create the USB stick with T-Pot's [ISO Creator](https://github.com/dtag-dev-sec).
|
Whereas most CD burning tools allow you to burn from ISO images, the procedure to create a bootable USB stick from an ISO image depends on your system. There are various Windows GUI tools available, e.g. [this tip](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-windows) might help you.<br> On [Linux](http://askubuntu.com/questions/59551/how-to-burn-a-iso-to-a-usb-device) or [MacOS](http://www.ubuntu.com/download/desktop/create-a-usb-stick-on-mac-osx) you can use the tool *dd* or create the USB stick with T-Pot's [ISO Creator](https://github.com/telekom-security).
|
||||||
2. Boot from the USB stick and install.
|
2. Boot from the USB stick and install.
|
||||||
|
|
||||||
*Please note*: We will ensure the compatibility with the Intel NUC platform, as we really like the form factor, looks and build quality.
|
*Please note*: Limited tests are performed for the Intel NUC platform other hardware platforms **remain untested**. There is no hardware support provided of any kind.
|
||||||
|
|
||||||
|
<a name="postinstall"></a>
|
||||||
|
## Post-Install User
|
||||||
|
In some cases it is necessary to install Debian 10 (Buster) on your own:
|
||||||
|
- Cloud provider does not offer mounting ISO images.
|
||||||
|
- Hardware setup needs special drivers and / or kernels.
|
||||||
|
- Within your company you have to setup special policies, software etc.
|
||||||
|
- You just like to stay on top of things.
|
||||||
|
|
||||||
|
The T-Pot Universal Installer will upgrade the system and install all required T-Pot dependencies.
|
||||||
|
|
||||||
|
Just follow these steps:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/telekom-security/tpotce
|
||||||
|
cd tpotce/iso/installer/
|
||||||
|
./install.sh --type=user
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer will now start and guide you through the install process.
|
||||||
|
|
||||||
|
<a name="postinstallauto"></a>
|
||||||
|
## Post-Install Auto
|
||||||
|
You can also let the installer run automatically if you provide your own `tpot.conf`. An example is available in `tpotce/iso/installer/tpot.conf.dist`. This should make things easier in case you want to automate the installation i.e. with **Ansible**.
|
||||||
|
|
||||||
|
Just follow these steps while adjusting `tpot.conf` to your needs:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/telekom-security/tpotce
|
||||||
|
cd tpotce/iso/installer/
|
||||||
|
cp tpot.conf.dist tpot.conf
|
||||||
|
./install.sh --type=auto --conf=tpot.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
The installer will start automatically and guide you through the install process.
|
||||||
|
|
||||||
|
<a name="cloud"></a>
|
||||||
|
## Cloud Deployments
|
||||||
|
Located in the [`cloud`](cloud) folder.
|
||||||
|
Currently there are examples with Ansible & Terraform.
|
||||||
|
If you would like to contribute, you can add other cloud deployments like Chef or Puppet or extend current methods with other cloud providers.
|
||||||
|
|
||||||
|
*Please note*: Cloud providers usually offer adjusted Debian OS images, which might not be compatible with T-Pot. There is no cloud provider support provided of any kind.
|
||||||
|
|
||||||
|
<a name="ansible"></a>
|
||||||
|
### Ansible Deployment
|
||||||
|
You can find an [Ansible](https://www.ansible.com/) based T-Pot deployment in the [`cloud/ansible`](cloud/ansible) folder.
|
||||||
|
The Playbook in the [`cloud/ansible/openstack`](cloud/ansible/openstack) folder is reusable for all **OpenStack** clouds out of the box.
|
||||||
|
|
||||||
|
It first creates all resources (security group, network, subnet, router), deploys one (or more) new servers and then installs and configures T-Pot on them.
|
||||||
|
|
||||||
|
You can have a look at the Playbook and easily adapt the deploy role for other [cloud providers](https://docs.ansible.com/ansible/latest/scenario_guides/cloud_guides.html). Check out [Ansible Galaxy](https://galaxy.ansible.com/search?keywords=&order_by=-relevance&page=1&deprecated=false&type=collection&tags=cloud) for more cloud collections.
|
||||||
|
|
||||||
|
*Please note*: Cloud providers usually offer adjusted Debian OS images, which might not be compatible with T-Pot. There is no cloud provider support provided of any kind.
|
||||||
|
|
||||||
|
<a name="terraform"></a>
|
||||||
|
### Terraform Configuration
|
||||||
|
|
||||||
|
You can find [Terraform](https://www.terraform.io/) configuration in the [`cloud/terraform`](cloud/terraform) folder.
|
||||||
|
|
||||||
|
This can be used to launch a virtual machine, bootstrap any dependencies and install T-Pot in a single step.
|
||||||
|
|
||||||
|
Configuration for **Amazon Web Services** (AWS) and **Open Telekom Cloud** (OTC) is currently included.
|
||||||
|
This can easily be extended to support other [Terraform providers](https://registry.terraform.io/browse/providers?category=public-cloud%2Ccloud-automation%2Cinfrastructure).
|
||||||
|
|
||||||
|
*Please note*: Cloud providers usually offer adjusted Debian OS images, which might not be compatible with T-Pot. There is no cloud provider support provided of any kind.
|
||||||
|
|
||||||
<a name="firstrun"></a>
|
<a name="firstrun"></a>
|
||||||
## First Run
|
## First Run
|
||||||
The installation requires very little interaction, only a locale and keyboard setting has to be answered for the basic linux installation. The system will reboot and please maintain an active internet connection. The T-Pot installer will start and ask you for an installation type, password for the **tsec** user and credentials for a **web user**. Everything else will be configured automatically. All docker images and other componenents will be downloaded. Depending on your network connection and the chosen installation type, the installation may take some time. During our tests (50Mbit down, 10Mbit up), the installation is usually finished within a 30 minute timeframe.
|
The installation requires very little interaction, only a locale and keyboard setting have to be answered for the basic linux installation. While the system reboots maintain the active internet connection. The T-Pot installer will start and ask you for an installation type, password for the **tsec** user and credentials for a **web user**. Everything else will be configured automatically. All docker images and other componenents will be downloaded. Depending on your network connection and the chosen installation type, the installation may take some time. With 250Mbit down / 40Mbit up the installation is usually finished within 15-30 minutes.
|
||||||
|
|
||||||
Once the installation is finished, the system will automatically reboot and you will be presented with the T-Pot login screen. On the console you may login with the **tsec** user:
|
Once the installation is finished, the system will automatically reboot and you will be presented with the T-Pot login screen. On the console you may login with:
|
||||||
|
|
||||||
- user: **tsec**
|
- user: **[tsec or user]** *you chose during one of the post install methods*
|
||||||
- pass: **password you chose during the installation**
|
- pass: **[password]** *you chose during the installation*
|
||||||
|
|
||||||
All honeypot services are preconfigured and are starting automatically.
|
All honeypot services are preconfigured and are starting automatically.
|
||||||
|
|
||||||
You can also login from your browser: ``https://<your.ip>:64297``
|
You can login from your browser and access the Admin UI: `https://<your.ip>:64294` or via SSH to access the command line: `ssh -l tsec -p 64295 <your.ip>`
|
||||||
|
|
||||||
- user: **user you chose during the installation**
|
- user: **[tsec or user]** *you chose during one of the post install methods*
|
||||||
- pass: **password you chose during the installation**
|
- pass: **[password]** *you chose during the installation*
|
||||||
|
|
||||||
|
You can also login from your browser and access the Web UI: `https://<your.ip>:64297`
|
||||||
|
- user: **[user]** *you chose during the installation*
|
||||||
|
- pass: **[password]** *you chose during the installation*
|
||||||
|
|
||||||
|
|
||||||
<a name="placement"></a>
|
<a name="placement"></a>
|
||||||
# System Placement
|
# System Placement
|
||||||
Make sure your system is reachable through the internet. Otherwise it will not capture any attacks, other than the ones from your internal network! We recommend you put it in an unfiltered zone, where all TCP and UDP traffic is forwarded to T-Pot's network interface.
|
Make sure your system is reachable through a network you suspect intruders in / from (i.e. the internet). Otherwise T-Pot will most likely not capture any attacks, other than the ones from your internal network! For starters it is recommended to put T-Pot in an unfiltered zone, where all TCP and UDP traffic is forwarded to T-Pot's network interface. However to avoid fingerprinting you can put T-Pot behind a firewall and forward all TCP / UDP traffic in the port range of 1-64000 to T-Pot while allowing access to ports > 64000 only from trusted IPs.
|
||||||
|
|
||||||
A list of all relevant ports is available as part of the [Technical Concept](#concept)
|
A list of all relevant ports is available as part of the [Technical Concept](#concept)
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Basically, you can forward as many TCP ports as you want, as honeytrap dynamically binds any TCP port that is not covered by the other honeypot daemons.
|
Basically, you can forward as many TCP ports as you want, as glutton & honeytrap dynamically bind any TCP port that is not covered by the other honeypot daemons.
|
||||||
|
|
||||||
|
In case you need external Admin UI access, forward TCP port 64294 to T-Pot, see below.
|
||||||
In case you need external SSH access, forward TCP port 64295 to T-Pot, see below.
|
In case you need external SSH access, forward TCP port 64295 to T-Pot, see below.
|
||||||
In case you need external web access, forward TCP port 64297 to T-Pot, see below.
|
In case you need external Web UI access, forward TCP port 64297 to T-Pot, see below.
|
||||||
|
|
||||||
T-Pot requires outgoing git, http, https connections for updates (Ubuntu, Docker, GitHub, PyPi) and attack submission (ewsposter, hpfeeds). Ports and availability may vary based on your geographical location.
|
T-Pot requires outgoing git, http, https connections for updates (Debian, Docker, GitHub, PyPi), attack submission (ewsposter, hpfeeds) and CVE / IP reputation translation map updates (logstash, listbot). Ports and availability may vary based on your geographical location. Also during first install outgoing ICMP / TRACEROUTE is required additionally to find the closest and fastest mirror to you.
|
||||||
|
|
||||||
|
<a name="updates"></a>
|
||||||
|
# Updates
|
||||||
|
For the ones of you who want to live on the bleeding edge of T-Pot development we introduced an update feature which will allow you to update all T-Pot relevant files to be up to date with the T-Pot master branch.
|
||||||
|
**If you made any relevant changes to the T-Pot relevant config files make sure to create a backup first.**
|
||||||
|
|
||||||
|
The Update script will:
|
||||||
|
- **mercilessly** overwrite local changes to be in sync with the T-Pot master branch
|
||||||
|
- upgrade the system to the packages available in Debian (Stable)
|
||||||
|
- update all resources to be in-sync with the T-Pot master branch
|
||||||
|
- ensure all T-Pot relevant system files will be patched / copied into the original T-Pot state
|
||||||
|
- restore your custom ews.cfg and HPFEED settings from `/data/ews/conf`
|
||||||
|
|
||||||
|
You simply run the update script:
|
||||||
|
```
|
||||||
|
sudo su -
|
||||||
|
cd /opt/tpot/
|
||||||
|
./update.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Despite all testing efforts please be reminded that updates sometimes may have unforeseen consequences. Please create a backup of the machine or the files with the most value to your work.**
|
||||||
|
|
||||||
<a name="options"></a>
|
<a name="options"></a>
|
||||||
# Options
|
# Options
|
||||||
The system is designed to run without any interaction or maintenance and automatically contribute to the community.<br>
|
The system is designed to run without any interaction or maintenance and automatically contributes to the community.<br>
|
||||||
We know, for some this may not be enough. So here come some ways to further inspect the system and change configuration parameters.
|
For some this may not be enough. So here some examples to further inspect the system and change configuration parameters.
|
||||||
|
|
||||||
<a name="ssh"></a>
|
<a name="ssh"></a>
|
||||||
## SSH and web access
|
## SSH and web access
|
||||||
By default, the SSH daemon only allows access on **tcp/64295** with a user / password combination from RFC1918 networks. However, if you want to be able to login remotely via SSH you need to put your SSH keys on the host as described below.<br>
|
By default, the SSH daemon allows access on **tcp/64295** with a user / password combination and prevents credential brute forcing attempts using `fail2ban`. This also counts for Admin UI (**tcp/64294**) and Web UI (**tcp/64297**) access.<br>
|
||||||
It is configured to prevent password login from official IP addresses and pubkey-authentication must be used. Copy your SSH keyfile to `/home/tsec/.ssh/authorized_keys` and set the appropriate permissions (`chmod 600 authorized_keys`) as well as the correct ownership (`chown tsec:tsec authorized_keys`).
|
|
||||||
|
|
||||||
If you do not have a SSH client at hand and still want to access the machine via SSH you can do so by directing your browser to `https://<your.ip>:64297`, enter
|
If you do not have a SSH client at hand and still want to access the machine via command line you can do so by accessing the Admin UI from `https://<your.ip>:64294`, enter
|
||||||
|
|
||||||
- user: **user you chose during the installation**
|
- user: **[tsec or user]** *you chose during one of the post install methods*
|
||||||
- pass: **password you chose during the installation**
|
- pass: **[password]** *you chose during the installation*
|
||||||
|
|
||||||
and choose **WebTTY** from the navigation bar. You will be prompted to allow access for this connection and enter the password for the user **tsec**.
|
You can also add two factor authentication to Cockpit just by running `2fa.sh` on the command line.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
<a name="heimdall"></a>
|
||||||
|
## T-Pot Landing Page
|
||||||
|
Just open a web browser and connect to `https://<your.ip>:64297`, enter
|
||||||
|
|
||||||
|
- user: **[user]** *you chose during the installation*
|
||||||
|
- pass: **[password]** *you chose during the installation*
|
||||||
|
|
||||||
|
and the **Landing Page** will automagically load. Now just click on the tool / link you want to start.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
<a name="kibana"></a>
|
<a name="kibana"></a>
|
||||||
## Kibana Dashboard
|
## Kibana Dashboard
|
||||||
Just open a web browser and access and connect to `https://<your.ip>:64297`, enter
|
|
||||||
|
|
||||||
- user: **user you chose during the installation**
|

|
||||||
- pass: **password you chose during the installation**
|
|
||||||
|
|
||||||
and **Kibana** will automagically load. The Kibana dashboard can be customized to fit your needs. By default, we haven't added any filtering, because the filters depend on your setup. E.g. you might want to filter out your incoming administrative ssh connections and connections to update servers.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<a name="tools"></a>
|
<a name="tools"></a>
|
||||||
## Tools
|
## Tools
|
||||||
We included some web based management tools to improve and ease up on your daily tasks.
|
The following web based tools are included to improve and ease up daily tasks.
|
||||||
|
|
||||||

|

|
||||||

|
|
||||||

|

|
||||||

|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
<a name="maintenance"></a>
|
<a name="maintenance"></a>
|
||||||
## Maintenance
|
## Maintenance
|
||||||
As mentioned before, the system was designed to be low maintenance. Basically, there is nothing you have to do but let it run.
|
T-Pot is designed to be low maintenance. Basically, there is nothing you have to do but let it run.
|
||||||
|
|
||||||
If you run into any problems, a reboot may fix it :bowtie:
|
If you run into any problems, a reboot may fix it :bowtie:
|
||||||
|
|
||||||
If new versions of the components involved appear, we will test them and build new docker images. Those new docker images will be pushed to docker hub and downloaded to T-Pot and activated accordingly.
|
If new versions of the components involved appear new docker images will be created and distributed. New images will be available from docker hub and downloaded automatically to T-Pot and activated accordingly.
|
||||||
|
|
||||||
<a name="submission"></a>
|
<a name="submission"></a>
|
||||||
## Community Data Submission
|
## Community Data Submission
|
||||||
We provide T-Pot in order to make it accessible to all parties interested in honeypot deployment. By default, the data captured is submitted to a community backend. This community backend uses the data to feed a [community data view](http://sicherheitstacho.eu/?peers=communityPeers), a separate channel on our own [Sicherheitstacho](http://sicherheitstacho.eu), which is powered by our own set of honeypots.
|
T-Pot is provided in order to make it accessible to all interested in honeypots. By default, the captured data is submitted to a community backend. This community backend uses the data to feed [Sicherheitstacho](https://sicherheitstacho.eu).
|
||||||
You may opt out the submission to our community server by removing the `# Ewsposter service` from `/etc/tpot/tpot.yml`:
|
You may opt out of the submission by removing the `# Ewsposter service` from `/opt/tpot/etc/tpot.yml`:
|
||||||
1. Stop T-Pot services: `systemctl stop tpot`
|
1. Stop T-Pot services: `systemctl stop tpot`
|
||||||
2. Remove Ewsposter service: `vi /etc/tpot/tpot.yml`
|
2. Remove Ewsposter service: `vi /opt/tpot/etc/tpot.yml`
|
||||||
3. Remove the following lines, save and exit vi (`:x!`):<br>
|
3. Remove the following lines, save and exit vi (`:x!`):<br>
|
||||||
```
|
```
|
||||||
# Ewsposter service
|
# Ewsposter service
|
||||||
@ -373,7 +448,7 @@ You may opt out the submission to our community server by removing the `# Ewspos
|
|||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- ewsposter_local
|
- ewsposter_local
|
||||||
image: "dtagdevsec/ewsposter:1710"
|
image: "ghcr.io/telekom-security/ewsposter:2006"
|
||||||
volumes:
|
volumes:
|
||||||
- /data:/data
|
- /data:/data
|
||||||
- /data/ews/conf/ews.ip:/opt/ewsposter/ews.ip
|
- /data/ews/conf/ews.ip:/opt/ewsposter/ews.ip
|
||||||
@ -382,84 +457,105 @@ You may opt out the submission to our community server by removing the `# Ewspos
|
|||||||
|
|
||||||
Data is submitted in a structured ews-format, a XML stucture. Hence, you can parse out the information that is relevant to you.
|
Data is submitted in a structured ews-format, a XML stucture. Hence, you can parse out the information that is relevant to you.
|
||||||
|
|
||||||
We encourage you not to disable the data submission as it is the main purpose of the community approach - as you all know **sharing is caring** 😍
|
It is encouraged not to disable the data submission as it is the main purpose of the community approach - as you all know **sharing is caring** 😍
|
||||||
|
|
||||||
|
<a name="hpfeeds-optin"></a>
|
||||||
|
## Opt-In HPFEEDS Data Submission
|
||||||
|
As an Opt-In it is now possible to also share T-Pot data with 3rd party HPFEEDS brokers.
|
||||||
|
If you want to share your T-Pot data you simply have to register an account with a 3rd party broker with its own benefits towards the community. You simply run `hpfeeds_optin.sh` which will ask for your credentials. It will automatically update `/opt/tpot/etc/tpot.yml` to deliver events to your desired broker.
|
||||||
|
|
||||||
|
The script can accept a config file as an argument, e.g. `./hpfeeds_optin.sh --conf=hpfeeds.cfg`
|
||||||
|
|
||||||
|
Your current config will also be stored in `/data/ews/conf/hpfeeds.cfg` where you can review or change it.
|
||||||
|
Be sure to apply any changes by running `./hpfeeds_optin.sh --conf=/data/ews/conf/hpfeeds.cfg`.
|
||||||
|
No worries: Your old config gets backed up in `/data/ews/conf/hpfeeds.cfg.old`
|
||||||
|
|
||||||
|
Of course you can also rerun the `hpfeeds_optin.sh` script to change and apply your settings interactively.
|
||||||
|
|
||||||
<a name="roadmap"></a>
|
<a name="roadmap"></a>
|
||||||
# Roadmap
|
# Roadmap
|
||||||
As with every development there is always room for improvements ...
|
As with every development there is always room for improvements ...
|
||||||
|
|
||||||
- Bump ELK-stack to 6.x
|
|
||||||
- Introduce new honeypots
|
|
||||||
- Include automatic updates
|
|
||||||
|
|
||||||
Some features may be provided with updated docker images, others may require some hands on from your side.
|
Some features may be provided with updated docker images, others may require some hands on from your side.
|
||||||
|
|
||||||
You are always invited to participate in development on our [GitHub](https://github.com/dtag-dev-sec/tpotce) page.
|
You are always invited to participate in development on our [GitHub](https://github.com/telekom-security/tpotce) page.
|
||||||
|
|
||||||
<a name="disclaimer"></a>
|
<a name="disclaimer"></a>
|
||||||
# Disclaimer
|
# Disclaimer
|
||||||
- We don't have access to your system. So we cannot remote-assist when you break your configuration. But you can simply reinstall.
|
- We don't have access to your system. So we cannot remote-assist when you break your configuration. But you can simply reinstall.
|
||||||
- The software was designed with best effort security, not to be in stealth mode. Because then, we probably would not be able to provide those kind of honeypot services.
|
- The software was designed with best effort security, not to be in stealth mode. Because then, we probably would not be able to provide those kind of honeypot services.
|
||||||
- You install and you run within your responsibility. Choose your deployment wisely as a system compromise can never be ruled out.
|
- You install and you run within your responsibility. Choose your deployment wisely as a system compromise can never be ruled out.
|
||||||
- Honeypots should - by design - not host any sensitive data. Make sure you don't add any.
|
- Honeypots - by design - should not host any sensitive data. Make sure you don't add any.
|
||||||
- By default, your data is submitted to the community dashboard. You can disable this in the config. But hey, wouldn't it be better to contribute to the community?
|
- By default, your data is submitted to [SecurityMeter](https://www.sicherheitstacho.eu/start/main). You can disable this in the config. But hey, wouldn't it be better to contribute to the community?
|
||||||
|
|
||||||
<a name="faq"></a>
|
<a name="faq"></a>
|
||||||
# FAQ
|
# FAQ
|
||||||
Please report any issues or questions on our [GitHub issue list](https://github.com/dtag-dev-sec/tpotce/issues), so the community can participate.
|
Please report any issues or questions on our [GitHub issue list](https://github.com/telekom-security/tpotce/issues), so the community can participate.
|
||||||
|
|
||||||
<a name="contact"></a>
|
<a name="contact"></a>
|
||||||
# Contact
|
# Contact
|
||||||
We provide the software **as is** in a Community Edition format. T-Pot is designed to run out of the box and with zero maintenance involved. <br>
|
The software is provided **as is** in a Community Edition format. T-Pot is designed to run out of the box and with zero maintenance involved. <br>
|
||||||
We hope you understand that we cannot provide support on an individual basis. We will try to address questions, bugs and problems on our [GitHub issue list](https://github.com/dtag-dev-sec/tpotce/issues).
|
We hope you understand that we cannot provide support on an individual basis. We will try to address questions, bugs and problems on our [GitHub issue list](https://github.com/telekom-security/tpotce/issues).
|
||||||
|
|
||||||
For general feedback you can write to cert @ telekom.de.
|
|
||||||
|
|
||||||
<a name="licenses"></a>
|
<a name="licenses"></a>
|
||||||
# Licenses
|
# Licenses
|
||||||
The software that T-Pot is built on uses the following licenses.
|
The software that T-Pot is built on uses the following licenses.
|
||||||
<br>GPLv2: [conpot (by Lukas Rist)](https://github.com/mushorg/conpot/blob/master/LICENSE.txt), [dionaea](https://github.com/DinoTools/dionaea/blob/master/LICENSE), [honeytrap (by Tillmann Werner)](https://github.com/armedpot/honeytrap/blob/master/LICENSE), [suricata](http://suricata-ids.org/about/open-source/)
|
<br>GPLv2: [conpot](https://github.com/mushorg/conpot/blob/master/LICENSE.txt), [dionaea](https://github.com/DinoTools/dionaea/blob/master/LICENSE), [honeysap](https://github.com/SecureAuthCorp/HoneySAP/blob/master/COPYING), [honeypy](https://github.com/foospidy/HoneyPy/blob/master/LICENSE), [honeytrap](https://github.com/armedpot/honeytrap/blob/master/LICENSE), [suricata](http://suricata-ids.org/about/open-source/)
|
||||||
<br>GPLv3: [elasticpot (by Markus Schmall)](https://github.com/schmalle/ElasticPot), [emobility (by Mohamad Sbeiti)](https://github.com/dtag-dev-sec/emobility/blob/master/LICENSE), [ewsposter (by Markus Schroer)](https://github.com/dtag-dev-sec/ews/), [glastopf (by Lukas Rist)](https://github.com/glastopf/glastopf/blob/master/GPL), [rdpy](https://github.com/citronneur/rdpy/blob/master/LICENSE), [netdata](https://github.com/firehol/netdata/blob/master/LICENSE.md)
|
<br>GPLv3: [adbhoney](https://github.com/huuck/ADBHoney), [elasticpot](https://gitlab.com/bontchev/elasticpot/-/blob/master/LICENSE), [ewsposter](https://github.com/telekom-security/ews/), [log4pot](https://github.com/thomaspatzke/Log4Pot/blob/master/LICENSE), [fatt](https://github.com/0x4D31/fatt/blob/master/LICENSE), [rdpy](https://github.com/citronneur/rdpy/blob/master/LICENSE), [heralding](https://github.com/johnnykv/heralding/blob/master/LICENSE.txt), [ipphoney](https://gitlab.com/bontchev/ipphoney/-/blob/master/LICENSE), [redishoneypot](https://github.com/cypwnpwnsocute/RedisHoneyPot/blob/main/LICENSE), [snare](https://github.com/mushorg/snare/blob/master/LICENSE), [tanner](https://github.com/mushorg/snare/blob/master/LICENSE)
|
||||||
<br>Apache 2 License: [elasticsearch](https://github.com/elasticsearch/elasticsearch/blob/master/LICENSE.txt), [logstash](https://github.com/elasticsearch/logstash/blob/master/LICENSE), [kibana](https://github.com/elasticsearch/kibana/blob/master/LICENSE.md), [docker](https://github.com/docker/docker/blob/master/LICENSE), [elasticsearch-head](https://github.com/mobz/elasticsearch-head/blob/master/LICENCE)
|
<br>Apache 2 License: [cyberchef](https://github.com/gchq/CyberChef/blob/master/LICENSE), [dicompot](https://github.com/nsmfoo/dicompot/blob/master/LICENSE), [elasticsearch](https://github.com/elasticsearch/elasticsearch/blob/master/LICENSE.txt), [logstash](https://github.com/elasticsearch/logstash/blob/master/LICENSE), [kibana](https://github.com/elasticsearch/kibana/blob/master/LICENSE.md), [docker](https://github.com/docker/docker/blob/master/LICENSE), [elasticsearch-head](https://github.com/mobz/elasticsearch-head/blob/master/LICENCE)
|
||||||
<br>MIT License: [ctop](https://github.com/bcicen/ctop/blob/master/LICENSE), [wetty](https://github.com/krishnasrinivas/wetty/blob/master/LICENSE)
|
<br>MIT license: [ciscoasa](https://github.com/Cymmetria/ciscoasa_honeypot/blob/master/LICENSE), [ddospot](https://github.com/aelth/ddospot/blob/master/LICENSE), [glutton](https://github.com/mushorg/glutton/blob/master/LICENSE), [hellpot](https://github.com/yunginnanet/HellPot/blob/master/LICENSE)
|
||||||
<br>zlib License: [vnclowpot](https://github.com/magisterquis/vnclowpot/blob/master/LICENSE)
|
<br> Unlicense: [endlessh](https://github.com/skeeto/endlessh/blob/master/UNLICENSE)
|
||||||
<br>[cowrie (copyright disclaimer by Upi Tamminen)](https://github.com/micheloosterhof/cowrie/blob/master/doc/COPYRIGHT)
|
<br> Other: [citrixhoneypot](https://github.com/MalwareTech/CitrixHoneypot#licencing-agreement-malwaretech-public-licence), [cowrie](https://github.com/micheloosterhof/cowrie/blob/master/LICENSE.md), [mailoney](https://github.com/awhitehatter/mailoney), [Debian licensing](https://www.debian.org/legal/licenses/), [Elastic License](https://www.elastic.co/licensing/elastic-license)
|
||||||
<br>[mailoney](https://github.com/awhitehatter/mailoney)
|
<br> AGPL-3.0: [honeypots](https://github.com/qeeqbox/honeypots/blob/main/LICENSE)
|
||||||
<br>[Ubuntu licensing](http://www.ubuntu.com/about/about-ubuntu/licensing)
|
|
||||||
<br>[Portainer](https://github.com/portainer/portainer/blob/develop/LICENSE)
|
|
||||||
|
|
||||||
<a name="credits"></a>
|
<a name="credits"></a>
|
||||||
# Credits
|
# Credits
|
||||||
Without open source and the fruitful development community we are proud to be a part of T-Pot would not have been possible. Our thanks are extended but not limited to the following people and organizations:
|
Without open source and the fruitful development community (we are proud to be a part of), T-Pot would not have been possible! Our thanks are extended but not limited to the following people and organizations:
|
||||||
|
|
||||||
### The developers and development communities of
|
### The developers and development communities of
|
||||||
|
|
||||||
|
* [adbhoney](https://github.com/huuck/ADBHoney/graphs/contributors)
|
||||||
|
* [apt-fast](https://github.com/ilikenwf/apt-fast/graphs/contributors)
|
||||||
|
* [ciscoasa](https://github.com/Cymmetria/ciscoasa_honeypot/graphs/contributors)
|
||||||
|
* [citrixhoneypot](https://github.com/MalwareTech/CitrixHoneypot/graphs/contributors)
|
||||||
|
* [cockpit](https://github.com/cockpit-project/cockpit/graphs/contributors)
|
||||||
* [conpot](https://github.com/mushorg/conpot/graphs/contributors)
|
* [conpot](https://github.com/mushorg/conpot/graphs/contributors)
|
||||||
* [cowrie](https://github.com/micheloosterhof/cowrie/graphs/contributors)
|
* [cowrie](https://github.com/micheloosterhof/cowrie/graphs/contributors)
|
||||||
|
* [ddospot](https://github.com/aelth/ddospot/graphs/contributors)
|
||||||
|
* [debian](http://www.debian.org/)
|
||||||
|
* [dicompot](https://github.com/nsmfoo/dicompot/graphs/contributors)
|
||||||
* [dionaea](https://github.com/DinoTools/dionaea/graphs/contributors)
|
* [dionaea](https://github.com/DinoTools/dionaea/graphs/contributors)
|
||||||
* [docker](https://github.com/docker/docker/graphs/contributors)
|
* [docker](https://github.com/docker/docker/graphs/contributors)
|
||||||
* [elasticpot](https://github.com/schmalle/ElasticPot/graphs/contributors)
|
* [elasticpot](https://gitlab.com/bontchev/elasticpot/-/project_members)
|
||||||
* [elasticsearch](https://github.com/elastic/elasticsearch/graphs/contributors)
|
* [elasticsearch](https://github.com/elastic/elasticsearch/graphs/contributors)
|
||||||
* [elasticsearch-head](https://github.com/mobz/elasticsearch-head/graphs/contributors)
|
* [elasticsearch-head](https://github.com/mobz/elasticsearch-head/graphs/contributors)
|
||||||
* [emobility](https://github.com/dtag-dev-sec/emobility/graphs/contributors)
|
* [endlessh](https://github.com/skeeto/endlessh/graphs/contributors)
|
||||||
* [ewsposter](https://github.com/armedpot/ewsposter/graphs/contributors)
|
* [ewsposter](https://github.com/armedpot/ewsposter/graphs/contributors)
|
||||||
* [glastopf](https://github.com/mushorg/glastopf/graphs/contributors)
|
* [fatt](https://github.com/0x4D31/fatt/graphs/contributors)
|
||||||
|
* [glutton](https://github.com/mushorg/glutton/graphs/contributors)
|
||||||
|
* [hellpot](https://github.com/yunginnanet/HellPot/graphs/contributors)
|
||||||
|
* [heralding](https://github.com/johnnykv/heralding/graphs/contributors)
|
||||||
|
* [honeypots](https://github.com/qeeqbox/honeypots/graphs/contributors)
|
||||||
|
* [honeypy](https://github.com/foospidy/HoneyPy/graphs/contributors)
|
||||||
|
* [honeysap](https://github.com/SecureAuthCorp/HoneySAP/graphs/contributors)
|
||||||
* [honeytrap](https://github.com/armedpot/honeytrap/graphs/contributors)
|
* [honeytrap](https://github.com/armedpot/honeytrap/graphs/contributors)
|
||||||
|
* [ipphoney](https://gitlab.com/bontchev/ipphoney/-/project_members)
|
||||||
* [kibana](https://github.com/elastic/kibana/graphs/contributors)
|
* [kibana](https://github.com/elastic/kibana/graphs/contributors)
|
||||||
* [logstash](https://github.com/elastic/logstash/graphs/contributors)
|
* [logstash](https://github.com/elastic/logstash/graphs/contributors)
|
||||||
|
* [log4pot](https://github.com/thomaspatzke/Log4Pot/graphs/contributors)
|
||||||
* [mailoney](https://github.com/awhitehatter/mailoney)
|
* [mailoney](https://github.com/awhitehatter/mailoney)
|
||||||
* [netdata](https://github.com/firehol/netdata/graphs/contributors)
|
* [medpot](https://github.com/schmalle/medpot/graphs/contributors)
|
||||||
* [p0f](http://lcamtuf.coredump.cx/p0f3/)
|
* [p0f](http://lcamtuf.coredump.cx/p0f3/)
|
||||||
* [portainer](https://github.com/portainer/portainer/graphs/contributors)
|
|
||||||
* [rdpy](https://github.com/citronneur/rdpy)
|
* [rdpy](https://github.com/citronneur/rdpy)
|
||||||
|
* [redishoneypot](https://github.com/cypwnpwnsocute/RedisHoneyPot/graphs/contributors)
|
||||||
* [spiderfoot](https://github.com/smicallef/spiderfoot)
|
* [spiderfoot](https://github.com/smicallef/spiderfoot)
|
||||||
|
* [snare](https://github.com/mushorg/snare/graphs/contributors)
|
||||||
|
* [tanner](https://github.com/mushorg/tanner/graphs/contributors)
|
||||||
* [suricata](https://github.com/inliniac/suricata/graphs/contributors)
|
* [suricata](https://github.com/inliniac/suricata/graphs/contributors)
|
||||||
* [ubuntu](http://www.ubuntu.com/)
|
|
||||||
* [vnclowpot](https://github.com/magisterquis/vnclowpot)
|
|
||||||
* [wetty](https://github.com/krishnasrinivas/wetty/graphs/contributors)
|
|
||||||
|
|
||||||
### The following companies and organizations
|
### The following companies and organizations
|
||||||
* [cannonical](http://www.canonical.com/)
|
* [debian](https://www.debian.org/)
|
||||||
* [docker](https://www.docker.com/)
|
* [docker](https://www.docker.com/)
|
||||||
* [elastic.io](https://www.elastic.co/)
|
* [elastic.io](https://www.elastic.co/)
|
||||||
* [honeynet project](https://www.honeynet.org/)
|
* [honeynet project](https://www.honeynet.org/)
|
||||||
@ -467,12 +563,13 @@ Without open source and the fruitful development community we are proud to be a
|
|||||||
|
|
||||||
### ... and of course ***you*** for joining the community!
|
### ... and of course ***you*** for joining the community!
|
||||||
|
|
||||||
|
|
||||||
<a name="staytuned"></a>
|
<a name="staytuned"></a>
|
||||||
# Stay tuned ...
|
# Stay tuned ...
|
||||||
We will be releasing a new version of T-Pot about every 6-12 months.
|
A new version of T-Pot is released about every 6-12 months, development has shifted more and more towards rolling releases and the usage of `/opt/tpot/update.sh`.
|
||||||
|
|
||||||
<a name="funfact"></a>
|
<a name="testimonial"></a>
|
||||||
# Fun Fact
|
# Testimonials
|
||||||
|
One of the greatest feedback we have gotten so far is by one of the Conpot developers:<br>
|
||||||
Coffee just does not cut it anymore which is why we needed a different caffeine source and consumed *215* bottles of [Club Mate](https://de.wikipedia.org/wiki/Club-Mate) during the development of T-Pot 17.10 😇
|
***"[...] I highly recommend T-Pot which is ... it's not exactly a swiss army knife .. it's more like a swiss army soldier, equipped with a swiss army knife. Inside a tank. A swiss tank. [...]"***<br>
|
||||||
|
And from @robcowart (creator of [ElastiFlow](https://github.com/robcowart/elastiflow)):<br>
|
||||||
|
***"#TPot is one of the most well put together turnkey honeypot solutions. It is a must-have for anyone wanting to analyze and understand the behavior of malicious actors and the threat they pose to your organization."***
|
||||||
|
77
bin/2fa.sh
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Make sure script is started as non-root.
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" = "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as non-root ..."
|
||||||
|
echo ""
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set vars, check deps
|
||||||
|
myPAM_COCKPIT_FILE="/etc/pam.d/cockpit"
|
||||||
|
if ! [ -s "$myPAM_COCKPIT_FILE" ];
|
||||||
|
then
|
||||||
|
echo "### Cockpit PAM module config does not exist. Something went wrong."
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
myPAM_COCKPIT_GA="
|
||||||
|
|
||||||
|
# google authenticator for two-factor
|
||||||
|
auth required pam_google_authenticator.so
|
||||||
|
"
|
||||||
|
myAUTHENTICATOR=$(which google-authenticator)
|
||||||
|
if [ "$myAUTHENTICATOR" == "" ];
|
||||||
|
then
|
||||||
|
echo "### Could not locate google-authenticator, trying to install (if asked provide root password)."
|
||||||
|
echo ""
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libpam-google-authenticator
|
||||||
|
exec "$1" "$2"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# write PAM changes
|
||||||
|
function fuWRITE_PAM_CHANGES {
|
||||||
|
myCHECK=$(cat $myPAM_COCKPIT_FILE | grep -c "google")
|
||||||
|
if ! [ "$myCHECK" == "0" ];
|
||||||
|
then
|
||||||
|
echo "### PAM config already enabled. Skipped."
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo "### Updating PAM config for Cockpit (if asked provide root password)."
|
||||||
|
echo "$myPAM_COCKPIT_GA" | sudo tee -a $myPAM_COCKPIT_FILE
|
||||||
|
sudo systemctl restart cockpit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# create 2fa
|
||||||
|
function fuGEN_TOKEN {
|
||||||
|
echo "### Now generating token for Google Authenticator."
|
||||||
|
echo ""
|
||||||
|
google-authenticator -t -d -r 3 -R 30 -w 17
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# main
|
||||||
|
echo "### This script will enable Two Factor Authentication for Cockpit."
|
||||||
|
echo ""
|
||||||
|
echo "### Please download one of the many authenticator apps from the appstore of your choice."
|
||||||
|
echo ""
|
||||||
|
while true;
|
||||||
|
do
|
||||||
|
read -p "### Ready to start (y/n)? " myANSWER
|
||||||
|
case $myANSWER in
|
||||||
|
[Yy]* ) echo "### OK. Starting ..."; break;;
|
||||||
|
[Nn]* ) echo "### Exiting."; exit;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
fuWRITE_PAM_CHANGES
|
||||||
|
fuGEN_TOKEN
|
||||||
|
|
||||||
|
echo "Done. Re-run this script by every user who needs Cockpit access."
|
||||||
|
echo ""
|
@ -1,11 +1,19 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Run as root only.
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" != "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as root ..."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
# Backup all ES relevant folders
|
# Backup all ES relevant folders
|
||||||
# Make sure ES is available
|
# Make sure ES is available
|
||||||
myES="http://127.0.0.1:64298/"
|
myES="http://127.0.0.1:64298/"
|
||||||
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
||||||
if ! [ "$myESSTATUS" = "1" ]
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
then
|
then
|
||||||
echo "### Elasticsearch is not available, try starting via 'systemctl start elk'."
|
echo "### Elasticsearch is not available, try starting via 'systemctl start tpot'."
|
||||||
exit
|
exit
|
||||||
else
|
else
|
||||||
echo "### Elasticsearch is available, now continuing."
|
echo "### Elasticsearch is available, now continuing."
|
||||||
@ -16,7 +24,7 @@ fi
|
|||||||
myCOUNT=1
|
myCOUNT=1
|
||||||
myDATE=$(date +%Y%m%d%H%M)
|
myDATE=$(date +%Y%m%d%H%M)
|
||||||
myELKPATH="/data/elk/data"
|
myELKPATH="/data/elk/data"
|
||||||
myKIBANAINDEXNAME=$(curl -s -XGET ''$myES'_cat/indices/' | grep .kibana | awk '{ print $4 }')
|
myKIBANAINDEXNAME=$(curl -s -XGET ''$myES'_cat/indices/.kibana' | awk '{ print $4 }')
|
||||||
myKIBANAINDEXPATH=$myELKPATH/nodes/0/indices/$myKIBANAINDEXNAME
|
myKIBANAINDEXPATH=$myELKPATH/nodes/0/indices/$myKIBANAINDEXNAME
|
||||||
|
|
||||||
# Let's ensure normal operation on exit or if interrupted ...
|
# Let's ensure normal operation on exit or if interrupted ...
|
89
bin/change_ews_config.sh
Executable file
@ -0,0 +1,89 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo """
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# T-POT DTAG Data Submission #
|
||||||
|
# Contact: #
|
||||||
|
# cert@telekom.de #
|
||||||
|
##############################
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Got root?
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" != "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as root ..."
|
||||||
|
sudo ./$0
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "[*] Enter your API UserID: "
|
||||||
|
read apiUser
|
||||||
|
printf "[*] Enter your API Token: "
|
||||||
|
read apiToken
|
||||||
|
printf "[*] If you have multiple T-Pots running, give them each a unique NUMBER, e.g. '2' for your second T-Pot installation. Enter unique number for THIS T-Pot: "
|
||||||
|
read indexNumber
|
||||||
|
if ! [[ "$indexNumber" =~ ^[0-9]+$ ]]
|
||||||
|
then
|
||||||
|
echo "Sorry integers only. You have to start over..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
apiURL="https://community.sicherheitstacho.eu/ews-0.1/alert/postSimpleMessage"
|
||||||
|
printf "[*] Currently, your honeypot is configured to transmit data the default backend at 'https://community.sicherheitstacho.eu/ews-0.1/alert/postSimpleMessage'. Do you want to change this API endpoint? Only do this if you run your own PEBA backend instance? (N/y): "
|
||||||
|
read replyAPI
|
||||||
|
if [[ $replyAPI =~ ^[Yy]$ ]]
|
||||||
|
then
|
||||||
|
printf "[*] Enter your API endpoint URL and make sure it contains the full path, e.g. 'https://myDomain.local:9922/ews-0.1/alert/postSimpleMessage': "
|
||||||
|
read apiURL
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "[*] Recap! You defined: "
|
||||||
|
echo "############################"
|
||||||
|
echo "API User: " $apiUser
|
||||||
|
echo "API Token: " $apiToken
|
||||||
|
echo "API URL: " $apiURL
|
||||||
|
echo "Unique numeric ID for your T-Pot Installation: " $indexNumber
|
||||||
|
echo "Specific honeypot-IDs will look like : <honeypotType>-"$apiUser"-"$indexNumber
|
||||||
|
echo "############################"
|
||||||
|
echo ""
|
||||||
|
printf "[*] Is the above correct (y/N)? "
|
||||||
|
read reply
|
||||||
|
if [[ ! $reply =~ ^[Yy]$ ]]
|
||||||
|
then
|
||||||
|
echo "OK, then run this again..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "[+] Creating config file with API UserID '$apiUser' and API Token '$apiToken'."
|
||||||
|
echo "[+] Fetching config file from github. Outgoing https requests must be enabled!"
|
||||||
|
wget -q https://raw.githubusercontent.com/telekom-security/tpotce/master/docker/ews/dist/ews.cfg -O ews.cfg.dist
|
||||||
|
if [[ -f "ews.cfg.dist" ]]; then
|
||||||
|
echo "[+] Successfully downloaded ews.cfg from github."
|
||||||
|
else
|
||||||
|
echo "[+] Could not download ews.cfg from github."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "[+] Patching ews.cfg API Credentials."
|
||||||
|
sed 's/community-01-user/'$apiUser'/' ews.cfg.dist > ews.cfg
|
||||||
|
sed -i 's/foth{a5maiCee8fineu7/'$apiToken'/' ews.cfg
|
||||||
|
echo "[+] Patching ews.cfg API Url."
|
||||||
|
apiURL=${apiURL////\\/};
|
||||||
|
sed -i 's/https:\/\/community.sicherheitstacho.eu\/ews-0.1\/alert\/postSimpleMessage/'$apiURL'/' ews.cfg
|
||||||
|
echo "[+] Patching ews.cfg honeypot IDs."
|
||||||
|
sed -i 's/community-01/'$apiUser'-'$indexNumber'/' ews.cfg
|
||||||
|
|
||||||
|
rm ews.cfg.dist
|
||||||
|
|
||||||
|
echo "[+] Changing tpot.yml to include new ews.cfg."
|
||||||
|
|
||||||
|
cp ews.cfg /data/ews/conf/ews.cfg
|
||||||
|
cp /opt/tpot/etc/tpot.yml /opt/tpot/etc/tpot.yml.bak
|
||||||
|
sed -i '/- \/data\/ews\/conf\/ews.ip:\/opt\/ewsposter\/ews.ip/a\ \ \ - \/data\/ews\/conf\/ews.cfg:\/opt\/ewsposter\/ews.cfg' /opt/tpot/etc/tpot.yml
|
||||||
|
|
||||||
|
echo "[+] Restarting T-Pot."
|
||||||
|
systemctl restart tpot
|
||||||
|
echo "[+] Done."
|
372
bin/clean.sh
Executable file
@ -0,0 +1,372 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# T-Pot Container Data Cleaner & Log Rotator
|
||||||
|
# Set colors
|
||||||
|
myRED="[0;31m"
|
||||||
|
myGREEN="[0;32m"
|
||||||
|
myWHITE="[0;0m"
|
||||||
|
|
||||||
|
# Set pigz
|
||||||
|
myPIGZ=$(which pigz)
|
||||||
|
|
||||||
|
# Set persistence
|
||||||
|
myPERSISTENCE=$1
|
||||||
|
|
||||||
|
# Let's create a function to check if folder is empty
|
||||||
|
fuEMPTY () {
|
||||||
|
local myFOLDER=$1
|
||||||
|
|
||||||
|
echo $(ls $myFOLDER | wc -l)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to rotate and compress logs
|
||||||
|
fuLOGROTATE () {
|
||||||
|
local mySTATUS="/opt/tpot/etc/logrotate/status"
|
||||||
|
local myCONF="/opt/tpot/etc/logrotate/logrotate.conf"
|
||||||
|
local myADBHONEYTGZ="/data/adbhoney/downloads.tgz"
|
||||||
|
local myADBHONEYDL="/data/adbhoney/downloads/"
|
||||||
|
local myCOWRIETTYLOGS="/data/cowrie/log/tty/"
|
||||||
|
local myCOWRIETTYTGZ="/data/cowrie/log/ttylogs.tgz"
|
||||||
|
local myCOWRIEDL="/data/cowrie/downloads/"
|
||||||
|
local myCOWRIEDLTGZ="/data/cowrie/downloads.tgz"
|
||||||
|
local myDIONAEABI="/data/dionaea/bistreams/"
|
||||||
|
local myDIONAEABITGZ="/data/dionaea/bistreams.tgz"
|
||||||
|
local myDIONAEABIN="/data/dionaea/binaries/"
|
||||||
|
local myDIONAEABINTGZ="/data/dionaea/binaries.tgz"
|
||||||
|
local myHONEYTRAPATTACKS="/data/honeytrap/attacks/"
|
||||||
|
local myHONEYTRAPATTACKSTGZ="/data/honeytrap/attacks.tgz"
|
||||||
|
local myHONEYTRAPDL="/data/honeytrap/downloads/"
|
||||||
|
local myHONEYTRAPDLTGZ="/data/honeytrap/downloads.tgz"
|
||||||
|
local myTANNERF="/data/tanner/files/"
|
||||||
|
local myTANNERFTGZ="/data/tanner/files.tgz"
|
||||||
|
|
||||||
|
# Ensure correct permissions and ownerships for logrotate to run without issues
|
||||||
|
chmod 770 /data/ -R
|
||||||
|
chown tpot:tpot /data -R
|
||||||
|
chmod 644 /data/nginx/conf -R
|
||||||
|
chmod 644 /data/nginx/cert -R
|
||||||
|
|
||||||
|
# Run logrotate with force (-f) first, so the status file can be written and race conditions (with tar) be avoided
|
||||||
|
logrotate -f -s $mySTATUS $myCONF
|
||||||
|
|
||||||
|
# Compressing some folders first and rotate them later
|
||||||
|
if [ "$(fuEMPTY $myADBHONEYDL)" != "0" ]; then tar -I $myPIGZ -cvf $myADBHONEYTGZ $myADBHONEYDL; fi
|
||||||
|
if [ "$(fuEMPTY $myCOWRIETTYLOGS)" != "0" ]; then tar -I $myPIGZ -cvf $myCOWRIETTYTGZ $myCOWRIETTYLOGS; fi
|
||||||
|
if [ "$(fuEMPTY $myCOWRIEDL)" != "0" ]; then tar -I $myPIGZ -cvf $myCOWRIEDLTGZ $myCOWRIEDL; fi
|
||||||
|
if [ "$(fuEMPTY $myDIONAEABI)" != "0" ]; then tar -I $myPIGZ -cvf $myDIONAEABITGZ $myDIONAEABI; fi
|
||||||
|
if [ "$(fuEMPTY $myDIONAEABIN)" != "0" ]; then tar -I $myPIGZ -cvf $myDIONAEABINTGZ $myDIONAEABIN; fi
|
||||||
|
if [ "$(fuEMPTY $myHONEYTRAPATTACKS)" != "0" ]; then tar -I $myPIGZ -cvf $myHONEYTRAPATTACKSTGZ $myHONEYTRAPATTACKS; fi
|
||||||
|
if [ "$(fuEMPTY $myHONEYTRAPDL)" != "0" ]; then tar -I $myPIGZ -cvf $myHONEYTRAPDLTGZ $myHONEYTRAPDL; fi
|
||||||
|
if [ "$(fuEMPTY $myTANNERF)" != "0" ]; then tar -I $myPIGZ -cvf $myTANNERFTGZ $myTANNERF; fi
|
||||||
|
|
||||||
|
# Ensure correct permissions and ownership for previously created archives
|
||||||
|
chmod 770 $myADBHONEYTGZ $myCOWRIETTYTGZ $myCOWRIEDLTGZ $myDIONAEABITGZ $myDIONAEABINTGZ $myHONEYTRAPATTACKSTGZ $myHONEYTRAPDLTGZ $myTANNERFTGZ
|
||||||
|
chown tpot:tpot $myADBHONEYTGZ $myCOWRIETTYTGZ $myCOWRIEDLTGZ $myDIONAEABITGZ $myDIONAEABINTGZ $myHONEYTRAPATTACKSTGZ $myHONEYTRAPDLTGZ $myTANNERFTGZ
|
||||||
|
|
||||||
|
# Need to remove subfolders since too many files cause rm to exit with errors
|
||||||
|
rm -rf $myADBHONEYDL $myCOWRIETTYLOGS $myCOWRIEDL $myDIONAEABI $myDIONAEABIN $myHONEYTRAPATTACKS $myHONEYTRAPDL $myTANNERF
|
||||||
|
|
||||||
|
# Recreate subfolders with correct permissions and ownership
|
||||||
|
mkdir -p $myADBHONEYDL $myCOWRIETTYLOGS $myCOWRIEDL $myDIONAEABI $myDIONAEABIN $myHONEYTRAPATTACKS $myHONEYTRAPDL $myTANNERF
|
||||||
|
chmod 770 $myADBHONEYDL $myCOWRIETTYLOGS $myCOWRIEDL $myDIONAEABI $myDIONAEABIN $myHONEYTRAPATTACKS $myHONEYTRAPDL $myTANNERF
|
||||||
|
chown tpot:tpot $myADBHONEYDL $myCOWRIETTYLOGS $myCOWRIEDL $myDIONAEABI $myDIONAEABIN $myHONEYTRAPATTACKS $myHONEYTRAPDL $myTANNERF
|
||||||
|
|
||||||
|
# Run logrotate again to account for previously created archives - DO NOT FORCE HERE!
|
||||||
|
logrotate -s $mySTATUS $myCONF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare honeytrap data
|
||||||
|
fuADBHONEY () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/adbhoney/*; fi
|
||||||
|
mkdir -p /data/adbhoney/log/ /data/adbhoney/downloads/
|
||||||
|
chmod 770 /data/adbhoney/ -R
|
||||||
|
chown tpot:tpot /data/adbhoney/ -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare ciscoasa data
|
||||||
|
fuCISCOASA () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/ciscoasa/*; fi
|
||||||
|
mkdir -p /data/ciscoasa/log
|
||||||
|
chmod 770 /data/ciscoasa -R
|
||||||
|
chown tpot:tpot /data/ciscoasa -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare citrixhoneypot data
|
||||||
|
fuCITRIXHONEYPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/citrixhoneypot/*; fi
|
||||||
|
mkdir -p /data/citrixhoneypot/logs/
|
||||||
|
chmod 770 /data/citrixhoneypot/ -R
|
||||||
|
chown tpot:tpot /data/citrixhoneypot/ -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare conpot data
|
||||||
|
fuCONPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/conpot/*; fi
|
||||||
|
mkdir -p /data/conpot/log
|
||||||
|
chmod 770 /data/conpot -R
|
||||||
|
chown tpot:tpot /data/conpot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare cowrie data
|
||||||
|
fuCOWRIE () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/cowrie/*; fi
|
||||||
|
mkdir -p /data/cowrie/log/tty/ /data/cowrie/downloads/ /data/cowrie/keys/ /data/cowrie/misc/
|
||||||
|
chmod 770 /data/cowrie -R
|
||||||
|
chown tpot:tpot /data/cowrie -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare ddospot data
|
||||||
|
fuDDOSPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/ddospot/log; fi
|
||||||
|
mkdir -p /data/ddospot/log
|
||||||
|
chmod 770 /data/ddospot -R
|
||||||
|
chown tpot:tpot /data/ddospot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare dicompot data
|
||||||
|
fuDICOMPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/dicompot/log; fi
|
||||||
|
mkdir -p /data/dicompot/log
|
||||||
|
mkdir -p /data/dicompot/images
|
||||||
|
chmod 770 /data/dicompot -R
|
||||||
|
chown tpot:tpot /data/dicompot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare dionaea data
|
||||||
|
fuDIONAEA () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/dionaea/*; fi
|
||||||
|
mkdir -p /data/dionaea/log /data/dionaea/bistreams /data/dionaea/binaries /data/dionaea/rtp /data/dionaea/roots/ftp /data/dionaea/roots/tftp /data/dionaea/roots/www /data/dionaea/roots/upnp
|
||||||
|
chmod 770 /data/dionaea -R
|
||||||
|
chown tpot:tpot /data/dionaea -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare elasticpot data
|
||||||
|
fuELASTICPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/elasticpot/*; fi
|
||||||
|
mkdir -p /data/elasticpot/log
|
||||||
|
chmod 770 /data/elasticpot -R
|
||||||
|
chown tpot:tpot /data/elasticpot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare elk data
|
||||||
|
fuELK () {
|
||||||
|
# ELK data will be kept for <= 90 days, check /etc/crontab for curator modification
|
||||||
|
# ELK daemon log files will be removed
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/elk/log/*; fi
|
||||||
|
mkdir -p /data/elk
|
||||||
|
chmod 770 /data/elk -R
|
||||||
|
chown tpot:tpot /data/elk -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare endlessh data
|
||||||
|
fuENDLESSH () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/endlessh/log; fi
|
||||||
|
mkdir -p /data/endlessh/log
|
||||||
|
chmod 770 /data/endlessh -R
|
||||||
|
chown tpot:tpot /data/endlessh -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare fatt data
|
||||||
|
fuFATT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/fatt/*; fi
|
||||||
|
mkdir -p /data/fatt/log
|
||||||
|
chmod 770 -R /data/fatt
|
||||||
|
chown tpot:tpot -R /data/fatt
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare glastopf data
|
||||||
|
fuGLUTTON () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/glutton/*; fi
|
||||||
|
mkdir -p /data/glutton/log
|
||||||
|
chmod 770 /data/glutton -R
|
||||||
|
chown tpot:tpot /data/glutton -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare hellpot data
|
||||||
|
fuHELLPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/hellpot/log; fi
|
||||||
|
mkdir -p /data/hellpot/log
|
||||||
|
chmod 770 /data/hellpot -R
|
||||||
|
chown tpot:tpot /data/hellpot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare heralding data
|
||||||
|
fuHERALDING () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/heralding/*; fi
|
||||||
|
mkdir -p /data/heralding/log
|
||||||
|
chmod 770 /data/heralding -R
|
||||||
|
chown tpot:tpot /data/heralding -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare honeypots data
|
||||||
|
fuHONEYPOTS () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/honeypots/*; fi
|
||||||
|
mkdir -p /data/honeypots/log
|
||||||
|
chmod 770 /data/honeypots -R
|
||||||
|
chown tpot:tpot /data/honeypots -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare honeypy data
|
||||||
|
fuHONEYPY () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/honeypy/*; fi
|
||||||
|
mkdir -p /data/honeypy/log
|
||||||
|
chmod 770 /data/honeypy -R
|
||||||
|
chown tpot:tpot /data/honeypy -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare honeysap data
|
||||||
|
fuHONEYSAP () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/honeysap/*; fi
|
||||||
|
mkdir -p /data/honeysap/log
|
||||||
|
chmod 770 /data/honeysap -R
|
||||||
|
chown tpot:tpot /data/honeysap -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare honeytrap data
|
||||||
|
fuHONEYTRAP () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/honeytrap/*; fi
|
||||||
|
mkdir -p /data/honeytrap/log/ /data/honeytrap/attacks/ /data/honeytrap/downloads/
|
||||||
|
chmod 770 /data/honeytrap/ -R
|
||||||
|
chown tpot:tpot /data/honeytrap/ -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare ipphoney data
|
||||||
|
fuIPPHONEY () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/ipphoney/*; fi
|
||||||
|
mkdir -p /data/ipphoney/log
|
||||||
|
chmod 770 /data/ipphoney -R
|
||||||
|
chown tpot:tpot /data/ipphoney -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare log4pot data
|
||||||
|
fuLOG4POT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/log4pot/*; fi
|
||||||
|
mkdir -p /data/log4pot/log
|
||||||
|
chmod 770 /data/log4pot -R
|
||||||
|
chown tpot:tpot /data/log4pot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare mailoney data
|
||||||
|
fuMAILONEY () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/mailoney/*; fi
|
||||||
|
mkdir -p /data/mailoney/log/
|
||||||
|
chmod 770 /data/mailoney/ -R
|
||||||
|
chown tpot:tpot /data/mailoney/ -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare mailoney data
|
||||||
|
fuMEDPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/medpot/*; fi
|
||||||
|
mkdir -p /data/medpot/log/
|
||||||
|
chmod 770 /data/medpot/ -R
|
||||||
|
chown tpot:tpot /data/medpot/ -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up nginx logs
|
||||||
|
fuNGINX () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/nginx/log/*; fi
|
||||||
|
touch /data/nginx/log/error.log
|
||||||
|
chmod 644 /data/nginx/conf -R
|
||||||
|
chmod 644 /data/nginx/cert -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare rdpy data
|
||||||
|
fuRDPY () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/rdpy/*; fi
|
||||||
|
mkdir -p /data/rdpy/log/
|
||||||
|
chmod 770 /data/rdpy/ -R
|
||||||
|
chown tpot:tpot /data/rdpy/ -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare redishoneypot data
|
||||||
|
fuREDISHONEYPOT () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/redishoneypot/log; fi
|
||||||
|
mkdir -p /data/redishoneypot/log
|
||||||
|
chmod 770 /data/redishoneypot -R
|
||||||
|
chown tpot:tpot /data/redishoneypot -R
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to prepare spiderfoot db
|
||||||
|
fuSPIDERFOOT () {
|
||||||
|
mkdir -p /data/spiderfoot
|
||||||
|
touch /data/spiderfoot/spiderfoot.db
|
||||||
|
chmod 770 -R /data/spiderfoot
|
||||||
|
chown tpot:tpot -R /data/spiderfoot
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare suricata data
|
||||||
|
fuSURICATA () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/suricata/*; fi
|
||||||
|
mkdir -p /data/suricata/log
|
||||||
|
chmod 770 -R /data/suricata
|
||||||
|
chown tpot:tpot -R /data/suricata
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare p0f data
|
||||||
|
fuP0F () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/p0f/*; fi
|
||||||
|
mkdir -p /data/p0f/log
|
||||||
|
chmod 770 -R /data/p0f
|
||||||
|
chown tpot:tpot -R /data/p0f
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's create a function to clean up and prepare p0f data
|
||||||
|
fuTANNER () {
|
||||||
|
if [ "$myPERSISTENCE" != "on" ]; then rm -rf /data/tanner/*; fi
|
||||||
|
mkdir -p /data/tanner/log /data/tanner/files
|
||||||
|
chmod 770 -R /data/tanner
|
||||||
|
chown tpot:tpot -R /data/tanner
|
||||||
|
}
|
||||||
|
|
||||||
|
# Avoid unwanted cleaning
|
||||||
|
if [ "$myPERSISTENCE" = "" ];
|
||||||
|
then
|
||||||
|
echo $myRED"!!! WARNING !!! - This will delete ALL honeypot logs. "$myWHITE
|
||||||
|
while [ "$myQST" != "y" ] && [ "$myQST" != "n" ];
|
||||||
|
do
|
||||||
|
read -p "Continue? (y/n) " myQST
|
||||||
|
done
|
||||||
|
if [ "$myQST" = "n" ];
|
||||||
|
then
|
||||||
|
echo $myGREEN"Puuh! That was close! Aborting!"$myWHITE
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check persistence, if enabled compress and rotate logs
|
||||||
|
if [ "$myPERSISTENCE" = "on" ];
|
||||||
|
then
|
||||||
|
echo "Persistence enabled, now rotating and compressing logs."
|
||||||
|
fuLOGROTATE
|
||||||
|
else
|
||||||
|
echo "Cleaning up and preparing data folders."
|
||||||
|
fuADBHONEY
|
||||||
|
fuCISCOASA
|
||||||
|
fuCITRIXHONEYPOT
|
||||||
|
fuCONPOT
|
||||||
|
fuCOWRIE
|
||||||
|
fuDDOSPOT
|
||||||
|
fuDICOMPOT
|
||||||
|
fuDIONAEA
|
||||||
|
fuELASTICPOT
|
||||||
|
fuELK
|
||||||
|
fuENDLESSH
|
||||||
|
fuFATT
|
||||||
|
fuGLUTTON
|
||||||
|
fuHERALDING
|
||||||
|
fuHELLPOT
|
||||||
|
fuHONEYSAP
|
||||||
|
fuHONEYPOTS
|
||||||
|
fuHONEYPY
|
||||||
|
fuHONEYTRAP
|
||||||
|
fuIPPHONEY
|
||||||
|
fuLOG4POT
|
||||||
|
fuMAILONEY
|
||||||
|
fuMEDPOT
|
||||||
|
fuNGINX
|
||||||
|
fuREDISHONEYPOT
|
||||||
|
fuRDPY
|
||||||
|
fuSPIDERFOOT
|
||||||
|
fuSURICATA
|
||||||
|
fuP0F
|
||||||
|
fuTANNER
|
||||||
|
fi
|
182
bin/deploy.sh
Executable file
@ -0,0 +1,182 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Do we have root?
|
||||||
|
function fuGOT_ROOT {
|
||||||
|
echo
|
||||||
|
echo -n "### Checking for root: "
|
||||||
|
if [ "$(whoami)" != "root" ];
|
||||||
|
then
|
||||||
|
echo "[ NOT OK ]"
|
||||||
|
echo "### Please run as root."
|
||||||
|
echo "### Example: sudo $0"
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
echo "[ OK ]"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuDEPLOY_POT () {
|
||||||
|
echo
|
||||||
|
echo "###############################"
|
||||||
|
echo "# Deploying to T-Pot Hive ... #"
|
||||||
|
echo "###############################"
|
||||||
|
echo
|
||||||
|
sshpass -e ssh -4 -t -T -l "$MY_TPOT_USERNAME" -p 64295 "$MY_HIVE_IP" << EOF
|
||||||
|
echo "$SSHPASS" | sudo -S bash -c 'useradd -m -s /sbin/nologin -G tpotlogs "$MY_HIVE_USERNAME";
|
||||||
|
mkdir -p /home/"$MY_HIVE_USERNAME"/.ssh;
|
||||||
|
echo "$MY_POT_PUBLICKEY" >> /home/"$MY_HIVE_USERNAME"/.ssh/authorized_keys;
|
||||||
|
chmod 600 /home/"$MY_HIVE_USERNAME"/.ssh/authorized_keys;
|
||||||
|
chmod 755 /home/"$MY_HIVE_USERNAME"/.ssh;
|
||||||
|
chown "$MY_HIVE_USERNAME":"$MY_HIVE_USERNAME" -R /home/"$MY_HIVE_USERNAME"/.ssh'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "###########################"
|
||||||
|
echo "# Done. Please reboot ... #"
|
||||||
|
echo "###########################"
|
||||||
|
echo
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check Hive availability
|
||||||
|
function fuCHECK_HIVE () {
|
||||||
|
echo
|
||||||
|
echo "############################################"
|
||||||
|
echo "# Checking for T-Pot Hive availability ... #"
|
||||||
|
echo "############################################"
|
||||||
|
echo
|
||||||
|
sshpass -e ssh -4 -t -l "$MY_TPOT_USERNAME" -p 64295 -f -N -L64305:127.0.0.1:64305 "$MY_HIVE_IP" -o "StrictHostKeyChecking=no"
|
||||||
|
if [ $? -eq 0 ];
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo "#########################"
|
||||||
|
echo "# T-Pot Hive available! #"
|
||||||
|
echo "#########################"
|
||||||
|
echo
|
||||||
|
myHIVE_OK=$(curl -s http://127.0.0.1:64305)
|
||||||
|
if [ "$myHIVE_OK" == "ok" ];
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo "##############################"
|
||||||
|
echo "# T-Pot Hive tunnel test OK! #"
|
||||||
|
echo "##############################"
|
||||||
|
echo
|
||||||
|
kill -9 $(pidof ssh)
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "######################################################"
|
||||||
|
echo "# T-Pot Hive tunnel test FAILED! #"
|
||||||
|
echo "# Tunneled port tcp/64305 unreachable on T-Pot Hive. #"
|
||||||
|
echo "# Aborting. #"
|
||||||
|
echo "######################################################"
|
||||||
|
echo
|
||||||
|
kill -9 $(pidof ssh)
|
||||||
|
rm $MY_POT_PUBLICKEYFILE
|
||||||
|
rm $MY_POT_PRIVATEKEYFILE
|
||||||
|
rm $MY_LS_ENVCONFIGFILE
|
||||||
|
exit 1
|
||||||
|
fi;
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "#################################################################"
|
||||||
|
echo "# Something went wrong, most likely T-Pot Hive was unreachable! #"
|
||||||
|
echo "# Aborting. #"
|
||||||
|
echo "#################################################################"
|
||||||
|
echo
|
||||||
|
rm $MY_POT_PUBLICKEYFILE
|
||||||
|
rm $MY_POT_PRIVATEKEYFILE
|
||||||
|
rm $MY_LS_ENVCONFIGFILE
|
||||||
|
exit 1
|
||||||
|
fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuGET_DEPLOY_DATA () {
|
||||||
|
echo
|
||||||
|
echo "### Please provide data from your T-Pot Hive installation."
|
||||||
|
echo "### This usually is the one running the 'T-Pot Hive' type."
|
||||||
|
echo "### You will be needing the OS user (typically 'tsec'), the users' password and the IP / FQDN."
|
||||||
|
echo "### Do not worry, the password will not be persisted!"
|
||||||
|
echo
|
||||||
|
|
||||||
|
read -p "Username: " MY_TPOT_USERNAME
|
||||||
|
read -s -p "Password: " SSHPASS
|
||||||
|
echo
|
||||||
|
export SSHPASS
|
||||||
|
read -p "IP / FQDN: " MY_HIVE_IP
|
||||||
|
MY_HIVE_USERNAME="$(hostname)"
|
||||||
|
MY_TPOT_TYPE="POT"
|
||||||
|
MY_LS_ENVCONFIGFILE="/data/elk/logstash/ls_environment"
|
||||||
|
|
||||||
|
MY_POT_PUBLICKEYFILE="/data/elk/logstash/$MY_HIVE_USERNAME.pub"
|
||||||
|
MY_POT_PRIVATEKEYFILE="/data/elk/logstash/$MY_HIVE_USERNAME"
|
||||||
|
if ! [ -s "$MY_POT_PRIVATEKEYFILE" ] && ! [ -s "$MY_POT_PUBLICKEYFILE" ];
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo "##############################"
|
||||||
|
echo "# Generating ssh keyfile ... #"
|
||||||
|
echo "##############################"
|
||||||
|
echo
|
||||||
|
mkdir -p /data/elk/logstash
|
||||||
|
ssh-keygen -f "$MY_POT_PRIVATEKEYFILE" -N "" -C "$MY_HIVE_USERNAME"
|
||||||
|
MY_POT_PUBLICKEY="$(cat "$MY_POT_PUBLICKEYFILE")"
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "#############################################"
|
||||||
|
echo "# There is already a ssh keyfile. Aborting. #"
|
||||||
|
echo "#############################################"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo "###########################################################"
|
||||||
|
echo "# Writing config to /data/elk/logstash/ls_environment. #"
|
||||||
|
echo "# If you make changes to this file, you need to reboot or #"
|
||||||
|
echo "# run /opt/tpot/bin/updateip.sh. #"
|
||||||
|
echo "###########################################################"
|
||||||
|
echo
|
||||||
|
tee $MY_LS_ENVCONFIGFILE << EOF
|
||||||
|
MY_TPOT_TYPE=$MY_TPOT_TYPE
|
||||||
|
MY_POT_PRIVATEKEYFILE=$MY_POT_PRIVATEKEYFILE
|
||||||
|
MY_HIVE_USERNAME=$MY_HIVE_USERNAME
|
||||||
|
MY_HIVE_IP=$MY_HIVE_IP
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deploy Pot to Hive
|
||||||
|
fuGOT_ROOT
|
||||||
|
echo
|
||||||
|
echo "#################################"
|
||||||
|
echo "# Ship T-Pot Logs to T-Pot Hive #"
|
||||||
|
echo "#################################"
|
||||||
|
echo
|
||||||
|
echo "If you already have a T-Pot Hive installation running and"
|
||||||
|
echo "this T-Pot installation is running the type \"Pot\" the"
|
||||||
|
echo "script will automagically setup this T-Pot to ship and"
|
||||||
|
echo "prepare the Hive to receive logs from this T-Pot."
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "###################################"
|
||||||
|
echo "# Deploy T-Pot Logs to T-Pot Hive #"
|
||||||
|
echo "###################################"
|
||||||
|
echo
|
||||||
|
echo "[c] - Continue deplyoment"
|
||||||
|
echo "[q] - Abort and exit"
|
||||||
|
echo
|
||||||
|
while [ 1 != 2 ]
|
||||||
|
do
|
||||||
|
read -s -n 1 -p "Your choice: " mySELECT
|
||||||
|
echo $mySELECT
|
||||||
|
case "$mySELECT" in
|
||||||
|
[c,C])
|
||||||
|
fuGET_DEPLOY_DATA
|
||||||
|
fuCHECK_HIVE
|
||||||
|
fuDEPLOY_POT
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[q,Q])
|
||||||
|
echo "Aborted."
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
94
bin/deprecated/export_kibana-objects.sh
Executable file
@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Export all Kibana objects through Kibana Saved Objects API
|
||||||
|
# Make sure ES is available
|
||||||
|
myES="http://127.0.0.1:64298/"
|
||||||
|
myKIBANA="http://127.0.0.1:64296/"
|
||||||
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
||||||
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
|
then
|
||||||
|
echo "### Elasticsearch is not available, try starting via 'systemctl start tpot'."
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
echo "### Elasticsearch is available, now continuing."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set vars
|
||||||
|
myDATE=$(date +%Y%m%d%H%M)
|
||||||
|
myINDEXCOUNT=$(curl -s -XGET ''$myKIBANA'api/saved_objects/_find?type=index-pattern' | jq '.saved_objects[].attributes' | tr '\\' '\n' | grep -E "scripted|url" | wc -w)
|
||||||
|
myINDEXID=$(curl -s -XGET ''$myKIBANA'api/saved_objects/_find?type=index-pattern' | jq '.saved_objects[].id' | tr -d '"')
|
||||||
|
myDASHBOARDS=$(curl -s -XGET ''$myKIBANA'api/saved_objects/_find?type=dashboard&per_page=500' | jq '.saved_objects[].id' | tr -d '"')
|
||||||
|
myVISUALIZATIONS=$(curl -s -XGET ''$myKIBANA'api/saved_objects/_find?type=visualization&per_page=500' | jq '.saved_objects[].id' | tr -d '"')
|
||||||
|
mySEARCHES=$(curl -s -XGET ''$myKIBANA'api/saved_objects/_find?type=search&per_page=500' | jq '.saved_objects[].id' | tr -d '"')
|
||||||
|
myCONFIGS=$(curl -s -XGET ''$myKIBANA'api/saved_objects/_find?type=config&per_page=500' | jq '.saved_objects[].id' | tr -d '"')
|
||||||
|
myCOL1="[0;34m"
|
||||||
|
myCOL0="[0;0m"
|
||||||
|
|
||||||
|
# Let's ensure normal operation on exit or if interrupted ...
|
||||||
|
function fuCLEANUP {
|
||||||
|
rm -rf patterns/ dashboards/ visualizations/ searches/ configs/
|
||||||
|
}
|
||||||
|
trap fuCLEANUP EXIT
|
||||||
|
|
||||||
|
# Export index patterns
|
||||||
|
mkdir -p patterns
|
||||||
|
echo $myCOL1"### Now exporting"$myCOL0 $myINDEXCOUNT $myCOL1"index pattern fields." $myCOL0
|
||||||
|
curl -s -XGET ''$myKIBANA'api/saved_objects/index-pattern/'$myINDEXID'' | jq '. | {attributes, references}' > patterns/$myINDEXID.json &
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Export dashboards
|
||||||
|
mkdir -p dashboards
|
||||||
|
echo $myCOL1"### Now exporting"$myCOL0 $(echo $myDASHBOARDS | wc -w) $myCOL1"dashboards." $myCOL0
|
||||||
|
for i in $myDASHBOARDS;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XGET ''$myKIBANA'api/saved_objects/dashboard/'$i'' | jq '. | {attributes, references}' > dashboards/$i.json &
|
||||||
|
done;
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Export visualizations
|
||||||
|
mkdir -p visualizations
|
||||||
|
echo $myCOL1"### Now exporting"$myCOL0 $(echo $myVISUALIZATIONS | wc -w) $myCOL1"visualizations." $myCOL0
|
||||||
|
for i in $myVISUALIZATIONS;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XGET ''$myKIBANA'api/saved_objects/visualization/'$i'' | jq '. | {attributes, references}' > visualizations/$i.json &
|
||||||
|
done;
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Export searches
|
||||||
|
mkdir -p searches
|
||||||
|
echo $myCOL1"### Now exporting"$myCOL0 $(echo $mySEARCHES | wc -w) $myCOL1"searches." $myCOL0
|
||||||
|
for i in $mySEARCHES;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XGET ''$myKIBANA'api/saved_objects/search/'$i'' | jq '. | {attributes, references}' > searches/$i.json &
|
||||||
|
done;
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Export configs
|
||||||
|
mkdir -p configs
|
||||||
|
echo $myCOL1"### Now exporting"$myCOL0 $(echo $myCONFIGS | wc -w) $myCOL1"configs." $myCOL0
|
||||||
|
for i in $myCONFIGS;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XGET ''$myKIBANA'api/saved_objects/config/'$i'' | jq '. | {attributes, references}' > configs/$i.json &
|
||||||
|
done;
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Wait for background exports to finish
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Building tar archive
|
||||||
|
echo $myCOL1"### Now building archive"$myCOL0 "kibana-objects_"$myDATE".tgz"
|
||||||
|
tar cvfz kibana-objects_$myDATE.tgz patterns dashboards visualizations searches configs > /dev/null
|
||||||
|
|
||||||
|
# Stats
|
||||||
|
echo
|
||||||
|
echo $myCOL1"### Statistics"
|
||||||
|
echo $myCOL1"###### Exported"$myCOL0 $myINDEXCOUNT $myCOL1"index patterns." $myCOL0
|
||||||
|
echo $myCOL1"###### Exported"$myCOL0 $(echo $myDASHBOARDS | wc -w) $myCOL1"dashboards." $myCOL0
|
||||||
|
echo $myCOL1"###### Exported"$myCOL0 $(echo $myVISUALIZATIONS | wc -w) $myCOL1"visualizations." $myCOL0
|
||||||
|
echo $myCOL1"###### Exported"$myCOL0 $(echo $mySEARCHES | wc -w) $myCOL1"searches." $myCOL0
|
||||||
|
echo $myCOL1"###### Exported"$myCOL0 $(echo $myCONFIGS | wc -w) $myCOL1"configs." $myCOL0
|
||||||
|
echo
|
126
bin/deprecated/import_kibana-objects.sh
Executable file
@ -0,0 +1,126 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Import Kibana objects
|
||||||
|
# Make sure ES is available
|
||||||
|
myES="http://127.0.0.1:64298/"
|
||||||
|
myKIBANA="http://127.0.0.1:64296/"
|
||||||
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
||||||
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
|
then
|
||||||
|
echo "### Elasticsearch is not available, try starting via 'systemctl start tpot'."
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
echo "### Elasticsearch is available, now continuing."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set vars
|
||||||
|
myDUMP=$1
|
||||||
|
myCOL1="[0;34m"
|
||||||
|
myCOL0="[0;0m"
|
||||||
|
|
||||||
|
# Let's ensure normal operation on exit or if interrupted ...
|
||||||
|
function fuCLEANUP {
|
||||||
|
rm -rf patterns/ dashboards/ visualizations/ searches/ configs/
|
||||||
|
}
|
||||||
|
trap fuCLEANUP EXIT
|
||||||
|
|
||||||
|
# Check if parameter is given and file exists
|
||||||
|
if [ "$myDUMP" = "" ];
|
||||||
|
then
|
||||||
|
echo $myCOL1"### Please provide a backup file name."$myCOL0
|
||||||
|
echo $myCOL1"### import_kibana-objects.sh <kibana-objects.tgz>"$myCOL0
|
||||||
|
echo
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if ! [ -a $myDUMP ];
|
||||||
|
then
|
||||||
|
echo $myCOL1"### File not found."$myCOL0
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unpack tar
|
||||||
|
tar xvfz $myDUMP > /dev/null
|
||||||
|
|
||||||
|
# Restore index patterns
|
||||||
|
myINDEXID=$(ls patterns/*.json | cut -c 10- | rev | cut -c 6- | rev)
|
||||||
|
myINDEXCOUNT=$(cat patterns/$myINDEXID.json | tr '\\' '\n' | grep -E "scripted|url" | wc -w)
|
||||||
|
echo $myCOL1"### Now importing"$myCOL0 $myINDEXCOUNT $myCOL1"index pattern fields." $myCOL0
|
||||||
|
curl -s -XDELETE ''$myKIBANA'api/saved_objects/index-pattern/logstash-*' -H "Content-Type: application/json" -H "kbn-xsrf: true" > /dev/null
|
||||||
|
curl -s -XDELETE ''$myKIBANA'api/saved_objects/index-pattern/'$myINDEXID'' -H "Content-Type: application/json" -H "kbn-xsrf: true" > /dev/null
|
||||||
|
curl -s -XPOST ''$myKIBANA'api/saved_objects/index-pattern/'$myINDEXID'' -H "Content-Type: application/json" -H "kbn-xsrf: true" -d @patterns/$myINDEXID.json > /dev/null &
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Restore dashboards
|
||||||
|
myDASHBOARDS=$(ls dashboards/*.json | cut -c 12- | rev | cut -c 6- | rev)
|
||||||
|
echo $myCOL1"### Now importing "$myCOL0$(echo $myDASHBOARDS | wc -w)$myCOL1 "dashboards." $myCOL0
|
||||||
|
for i in $myDASHBOARDS;
|
||||||
|
do
|
||||||
|
curl -s -XDELETE ''$myKIBANA'api/saved_objects/dashboard/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" > /dev/null &
|
||||||
|
done;
|
||||||
|
wait
|
||||||
|
for i in $myDASHBOARDS;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XPOST ''$myKIBANA'api/saved_objects/dashboard/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" -d @dashboards/$i.json > /dev/null &
|
||||||
|
done;
|
||||||
|
wait
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Restore visualizations
|
||||||
|
myVISUALIZATIONS=$(ls visualizations/*.json | cut -c 16- | rev | cut -c 6- | rev)
|
||||||
|
echo $myCOL1"### Now importing "$myCOL0$(echo $myVISUALIZATIONS | wc -w)$myCOL1 "visualizations." $myCOL0
|
||||||
|
for i in $myVISUALIZATIONS;
|
||||||
|
do
|
||||||
|
curl -s -XDELETE ''$myKIBANA'api/saved_objects/visualization/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" > /dev/null &
|
||||||
|
done;
|
||||||
|
wait
|
||||||
|
for i in $myVISUALIZATIONS;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XPOST ''$myKIBANA'api/saved_objects/visualization/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" -d @visualizations/$i.json > /dev/null &
|
||||||
|
done;
|
||||||
|
wait
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Restore searches
|
||||||
|
mySEARCHES=$(ls searches/*.json | cut -c 10- | rev | cut -c 6- | rev)
|
||||||
|
echo $myCOL1"### Now importing "$myCOL0$(echo $mySEARCHES | wc -w)$myCOL1 "searches." $myCOL0
|
||||||
|
for i in $mySEARCHES;
|
||||||
|
do
|
||||||
|
curl -s -XDELETE ''$myKIBANA'api/saved_objects/search/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" > /dev/null &
|
||||||
|
done;
|
||||||
|
wait
|
||||||
|
for i in $mySEARCHES;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XPOST ''$myKIBANA'api/saved_objects/search/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" -d @searches/$i.json > /dev/null &
|
||||||
|
done;
|
||||||
|
echo
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Restore configs
|
||||||
|
myCONFIGS=$(ls configs/*.json | cut -c 9- | rev | cut -c 6- | rev)
|
||||||
|
echo $myCOL1"### Now importing "$myCOL0$(echo $myCONFIGS | wc -w)$myCOL1 "configs." $myCOL0
|
||||||
|
for i in $myCONFIGS;
|
||||||
|
do
|
||||||
|
curl -s -XDELETE ''$myKIBANA'api/saved_objects/configs/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" > /dev/null &
|
||||||
|
done;
|
||||||
|
wait
|
||||||
|
for i in $myCONFIGS;
|
||||||
|
do
|
||||||
|
echo $myCOL1"###### "$i $myCOL0
|
||||||
|
curl -s -XPOST ''$myKIBANA'api/saved_objects/configs/'$i'' -H "Content-Type: application/json" -H "kbn-xsrf: true" -d @configs/$i.json > /dev/null &
|
||||||
|
done;
|
||||||
|
echo
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Stats
|
||||||
|
echo
|
||||||
|
echo $myCOL1"### Statistics"
|
||||||
|
echo $myCOL1"###### Imported"$myCOL0 $myINDEXCOUNT $myCOL1"index patterns." $myCOL0
|
||||||
|
echo $myCOL1"###### Imported"$myCOL0 $(echo $myDASHBOARDS | wc -w) $myCOL1"dashboards." $myCOL0
|
||||||
|
echo $myCOL1"###### Imported"$myCOL0 $(echo $myVISUALIZATIONS | wc -w) $myCOL1"visualizations." $myCOL0
|
||||||
|
echo $myCOL1"###### Imported"$myCOL0 $(echo $mySEARCHES | wc -w) $myCOL1"searches." $myCOL0
|
||||||
|
echo $myCOL1"###### Imported"$myCOL0 $(echo $myCONFIGS | wc -w) $myCOL1"configs." $myCOL0
|
||||||
|
echo
|
||||||
|
|
54
bin/dps.sh
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Run as root only.
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" != "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as root ..."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show current status of T-Pot containers
|
||||||
|
myPARAM="$1"
|
||||||
|
myCONTAINERS="$(cat /opt/tpot/etc/tpot.yml | grep -v '#' | grep container_name | cut -d: -f2 | sort | tr -d " ")"
|
||||||
|
myRED="[1;31m"
|
||||||
|
myGREEN="[1;32m"
|
||||||
|
myBLUE="[1;34m"
|
||||||
|
myWHITE="[0;0m"
|
||||||
|
myMAGENTA="[1;35m"
|
||||||
|
|
||||||
|
function fuGETSTATUS {
|
||||||
|
grc --colour=on docker ps -f status=running -f status=exited --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -v "NAME" | sort
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuGETSYS {
|
||||||
|
printf "========| System |========\n"
|
||||||
|
printf "%+10s %-20s\n" "Date: " "$(date)"
|
||||||
|
printf "%+10s %-20s\n" "Uptime: " "$(uptime | cut -b 2-)"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
myDPS=$(fuGETSTATUS)
|
||||||
|
myDPSNAMES=$(echo "$myDPS" | awk '{ print $1 }' | sort)
|
||||||
|
fuGETSYS
|
||||||
|
printf "%-21s %-28s %s\n" "NAME" "STATUS" "PORTS"
|
||||||
|
if [ "$myDPS" != "" ];
|
||||||
|
then
|
||||||
|
echo "$myDPS"
|
||||||
|
fi
|
||||||
|
for i in $myCONTAINERS; do
|
||||||
|
myAVAIL=$(echo "$myDPSNAMES" | grep -o "$i" | uniq | wc -l)
|
||||||
|
if [ "$myAVAIL" = "0" ];
|
||||||
|
then
|
||||||
|
printf "%-28s %-28s\n" "$myRED$i" "DOWN$myWHITE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ $myPARAM =~ ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$ ]];
|
||||||
|
then
|
||||||
|
sleep "$myPARAM"
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
@ -2,10 +2,10 @@
|
|||||||
# Dump all ES data
|
# Dump all ES data
|
||||||
# Make sure ES is available
|
# Make sure ES is available
|
||||||
myES="http://127.0.0.1:64298/"
|
myES="http://127.0.0.1:64298/"
|
||||||
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c "green\|yellow")
|
||||||
if ! [ "$myESSTATUS" = "1" ]
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
then
|
then
|
||||||
echo "### Elasticsearch is not available, try starting via 'systemctl start elk'."
|
echo "### Elasticsearch is not available, try starting via 'systemctl start tpot'."
|
||||||
exit
|
exit
|
||||||
else
|
else
|
||||||
echo "### Elasticsearch is available, now continuing."
|
echo "### Elasticsearch is available, now continuing."
|
||||||
@ -20,12 +20,12 @@ trap fuCLEANUP EXIT
|
|||||||
|
|
||||||
# Set vars
|
# Set vars
|
||||||
myDATE=$(date +%Y%m%d%H%M)
|
myDATE=$(date +%Y%m%d%H%M)
|
||||||
myINDICES=$(curl -s -XGET ''$myES'_cat/indices/' | grep logstash | awk '{ print $3 }' | sort | grep -v 1970)
|
myINDICES=$(curl -s -XGET ''$myES'_cat/indices/logstash-*' | awk '{ print $3 }' | sort | grep -v 1970)
|
||||||
myES="http://127.0.0.1:64298/"
|
myINDICES+=" .kibana"
|
||||||
myCOL1="[0;34m"
|
myCOL1="[0;34m"
|
||||||
myCOL0="[0;0m"
|
myCOL0="[0;0m"
|
||||||
|
|
||||||
# Dumping all ES data
|
# Dumping Kibana and Logstash data
|
||||||
echo $myCOL1"### The following indices will be dumped: "$myCOL0
|
echo $myCOL1"### The following indices will be dumped: "$myCOL0
|
||||||
echo $myINDICES
|
echo $myINDICES
|
||||||
echo
|
echo
|
||||||
@ -41,5 +41,5 @@ for i in $myINDICES;
|
|||||||
|
|
||||||
# Build tar archive
|
# Build tar archive
|
||||||
echo $myCOL1"### Now building tar archive: es_dump_"$myDATE".tgz" $myCOL0
|
echo $myCOL1"### Now building tar archive: es_dump_"$myDATE".tgz" $myCOL0
|
||||||
tar cvf es_dump_$myDATE.tar tmp/*
|
tar cvf es_dump_$myDATE.tar tmp/.
|
||||||
echo $myCOL1"### Done."$myCOL0
|
echo $myCOL1"### Done."$myCOL0
|
134
bin/hpfeeds_optin.sh
Executable file
@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Run as root only.
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" != "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as root ..."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
myTPOTYMLFILE="/opt/tpot/etc/tpot.yml"
|
||||||
|
|
||||||
|
function fuGENERIC () {
|
||||||
|
echo
|
||||||
|
echo "You chose generic, please provide all the details of the broker"
|
||||||
|
echo
|
||||||
|
myENABLE="true"
|
||||||
|
read -p "Host URL: " myHOST
|
||||||
|
read -p "Port: " myPORT
|
||||||
|
read -p "Channel: " myCHANNEL
|
||||||
|
echo "For generic providers set this to 'false'"
|
||||||
|
echo "If you received a CA certficate mount it into the ewsposter container by modifying $myTPOTYMLFILE"
|
||||||
|
read -p "TLS - 'false' or path to CA in container: " myCERT
|
||||||
|
read -p "Ident: " myIDENT
|
||||||
|
read -p "Secret: " mySECRET
|
||||||
|
read -p "Format ews (xml) or json: " myFORMAT
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuOPTOUT () {
|
||||||
|
echo
|
||||||
|
while [ 1 != 2 ]
|
||||||
|
do
|
||||||
|
read -s -n 1 -p "You chose to opt out (y/n)? " mySELECT
|
||||||
|
echo $mySELECT
|
||||||
|
case "$mySELECT" in
|
||||||
|
[y,Y])
|
||||||
|
echo "Opt out."
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[n,N])
|
||||||
|
echo "Aborted."
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
myENABLE="false"
|
||||||
|
myHOST="host"
|
||||||
|
myPORT="port"
|
||||||
|
myCHANNEL="channels"
|
||||||
|
myCERT="false"
|
||||||
|
myIDENT="user"
|
||||||
|
mySECRET="secret"
|
||||||
|
myFORMAT="json"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuWRITETOFILE () {
|
||||||
|
if [ -f '/data/ews/conf/hpfeeds.cfg' ]; then
|
||||||
|
echo "Creating backup of current config in /data/ews/conf/hpfeeds.cfg.old"
|
||||||
|
mv /data/ews/conf/hpfeeds.cfg /data/ews/conf/hpfeeds.cfg.old
|
||||||
|
fi
|
||||||
|
echo "Storing new config in /data/ews/conf/hpfeeds.cfg"
|
||||||
|
cat >> /data/ews/conf/hpfeeds.cfg <<EOF
|
||||||
|
myENABLE=$myENABLE
|
||||||
|
myHOST=$myHOST
|
||||||
|
myPORT=$myPORT
|
||||||
|
myCHANNEL=$myCHANNEL
|
||||||
|
myCERT=$myCERT
|
||||||
|
myIDENT=$myIDENT
|
||||||
|
mySECRET=$mySECRET
|
||||||
|
myFORMAT=$myFORMAT
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuAPPLY () {
|
||||||
|
echo "Now stopping T-Pot ..."
|
||||||
|
systemctl stop tpot
|
||||||
|
echo "Applying your settings to tpot.yml ... "
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_ENABLE.*/EWS_HPFEEDS_ENABLE=${myENABLE}/g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_HOST.*/EWS_HPFEEDS_HOST=${myHOST}/g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_PORT.*/EWS_HPFEEDS_PORT=${myPORT}/g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_CHANNELS.*/EWS_HPFEEDS_CHANNELS=${myCHANNEL}/g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s#EWS_HPFEEDS_TLSCERT.*#EWS_HPFEEDS_TLSCERT=${myCERT}#g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_IDENT.*/EWS_HPFEEDS_IDENT=${myIDENT}/g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_SECRET.*/EWS_HPFEEDS_SECRET=${mySECRET}/g" "$myTPOTYMLFILE"
|
||||||
|
sed --follow-symlinks -i "s/EWS_HPFEEDS_FORMAT.*/EWS_HPFEEDS_FORMAT=${myFORMAT}/g" "$myTPOTYMLFILE"
|
||||||
|
echo "Now starting T-Pot ..."
|
||||||
|
systemctl start tpot
|
||||||
|
echo "You can always change or review your settings in /data/ews/conf/hpfeeds.cfg and apply changes by"
|
||||||
|
echo "running \"./hpfeeds_optin.sh --conf=/data/ews/conf/hpfeeds.cfg\""
|
||||||
|
echo "Done."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for cmdline argument and parse config file
|
||||||
|
filename=$(echo $@ | cut -d= -f2)
|
||||||
|
if [ $# == 1 ] && echo $@ | grep '\-\-conf=' > /dev/null && [ ! -z $filename ] && [ -f $filename ]
|
||||||
|
then
|
||||||
|
source $filename
|
||||||
|
else
|
||||||
|
|
||||||
|
# Proceed with interactive setup when no config file is found
|
||||||
|
echo "HPFEEDS Delivery Opt-In for T-Pot"
|
||||||
|
echo "---------------------------------"
|
||||||
|
echo "By running this script you agree to share your data with a 3rd party and agree to their corresponding sharing terms."
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "Please choose your broker"
|
||||||
|
echo "---------------------------"
|
||||||
|
echo "[1] - Generic (enter details manually)"
|
||||||
|
echo "[0] - Opt out of HPFEEDS"
|
||||||
|
echo "[q] - Do not agree end exit"
|
||||||
|
echo
|
||||||
|
while [ 1 != 2 ]
|
||||||
|
do
|
||||||
|
read -s -n 1 -p "Your choice: " mySELECT
|
||||||
|
echo $mySELECT
|
||||||
|
case "$mySELECT" in
|
||||||
|
[1])
|
||||||
|
fuGENERIC
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[0])
|
||||||
|
fuOPTOUT
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[q,Q])
|
||||||
|
echo "Aborted."
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
fuWRITETOFILE
|
||||||
|
fuAPPLY
|
122
bin/hptest.sh
Executable file
@ -0,0 +1,122 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
myHOST="$1"
|
||||||
|
myPACKAGES="dcmtk netcat nmap"
|
||||||
|
myMEDPOTPACKET="
|
||||||
|
MSH|^~\&|ADT1|MCM|LABADT|MCM|198808181126|SECURITY|ADT^A01|MSG00001-|P|2.6
|
||||||
|
EVN|A01|198808181123
|
||||||
|
PID|||PATID1234^5^M11^^AN||JONES^WILLIAM^A^III||19610615|M||2106-3|677 DELAWARE AVENUE^^EVERETT^MA^02149|GL|(919)379-1212|(919)271-3434~(919)277-3114||S||PATID12345001^2^M10^^ACSN|123456789|9-87654^NC
|
||||||
|
NK1|1|JONES^BARBARA^K|SPO|||||20011105
|
||||||
|
NK1|1|JONES^MICHAEL^A|FTH
|
||||||
|
PV1|1|I|2000^2012^01||||004777^LEBAUER^SIDNEY^J.|||SUR||-||ADM|A0
|
||||||
|
AL1|1||^PENICILLIN||CODE16~CODE17~CODE18
|
||||||
|
AL1|2||^CAT DANDER||CODE257
|
||||||
|
DG1|001|I9|1550|MAL NEO LIVER, PRIMARY|19880501103005|F
|
||||||
|
PR1|2234|M11|111^CODE151|COMMON PROCEDURES|198809081123
|
||||||
|
ROL|45^RECORDER^ROLE MASTER LIST|AD|RO|KATE^SMITH^ELLEN|199505011201
|
||||||
|
GT1|1122|1519|BILL^GATES^A
|
||||||
|
IN1|001|A357|1234|BCMD|||||132987
|
||||||
|
IN2|ID1551001|SSN12345678
|
||||||
|
ROL|45^RECORDER^ROLE MASTER LIST|AD|RO|KATE^ELLEN|199505011201"
|
||||||
|
|
||||||
|
function fuGOTROOT {
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" != "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as root ..."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuCHECKDEPS {
|
||||||
|
myINST=""
|
||||||
|
for myDEPS in $myPACKAGES;
|
||||||
|
do
|
||||||
|
myOK=$(dpkg -s $myDEPS | grep ok | awk '{ print $3 }');
|
||||||
|
if [ "$myOK" != "ok" ]
|
||||||
|
then
|
||||||
|
myINST=$(echo $myINST $myDEPS)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$myINST" != "" ]
|
||||||
|
then
|
||||||
|
apt-get update -y
|
||||||
|
for myDEPS in $myINST;
|
||||||
|
do
|
||||||
|
apt-get install $myDEPS -y
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuCHECKFORARGS {
|
||||||
|
if [ "$myHOST" != "" ];
|
||||||
|
then
|
||||||
|
echo "All arguments met. Continuing."
|
||||||
|
else
|
||||||
|
echo "Usage: hp_test.sh <[host or ip]>"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuGETPORTS {
|
||||||
|
myDOCKERCOMPOSEPORTS=$(cat $myDOCKERCOMPOSEYML | yq -r '.services[].ports' | grep ':' | sed -e s/127.0.0.1// | tr -d '", ' | sed -e s/^:// | cut -f1 -d ':' | grep -v "6429\|6430" | sort -gu)
|
||||||
|
myPORTS=$(for i in $myDOCKERCOMPOSEPORTS; do echo "$i"; done)
|
||||||
|
echo "Found these ports enabled:"
|
||||||
|
echo "$myPORTS"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuSCAN {
|
||||||
|
local myTIMEOUT="$1"
|
||||||
|
local mySCANPORT="$2"
|
||||||
|
local mySCANIP="$3"
|
||||||
|
local mySCANOPTS="$4"
|
||||||
|
|
||||||
|
timeout --foreground ${myTIMEOUT} nmap ${mySCANOPTS} -T4 -v -p ${mySCANPORT} ${mySCANIP} &
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main
|
||||||
|
fuGOTROOT
|
||||||
|
fuCHECKDEPS
|
||||||
|
fuCHECKFORARGS
|
||||||
|
|
||||||
|
echo "Starting scans ..."
|
||||||
|
echo "$myMEDPOTPACKET" | nc "$myHOST" 2575 &
|
||||||
|
curl -XGET "http://$myHOST:9200/logstash-*/_search" &
|
||||||
|
curl -XPOST -H "Content-Type: application/json" -d '{"name":"test","email":"test@test.com"}' "http://$myHOST:9200/test" &
|
||||||
|
echo "I20100" | timeout --foreground 3 nc "$myHOST" 10001 &
|
||||||
|
findscu -P -k PatientName="*" $myHOST 11112 &
|
||||||
|
getscu -P -k PatientName="*" $myHOST 11112 &
|
||||||
|
telnet $myHOST 3299 &
|
||||||
|
fuSCAN "180" "7,8,102,135,161,1025,1080,5000,9200" "$myHOST" "-sC -sS -sU -sV"
|
||||||
|
fuSCAN "180" "2048,4096,5432" "$myHOST" "-sC -sS -sU -sV --version-light"
|
||||||
|
fuSCAN "120" "20,21" "$myHOST" "--script=ftp* -sC -sS -sV"
|
||||||
|
fuSCAN "120" "22" "$myHOST" "--script=ssh2-enum-algos,ssh-auth-methods,ssh-hostkey,ssh-publickey-acceptance,sshv1 -sC -sS -sV"
|
||||||
|
fuSCAN "30" "22" "$myHOST" "--script=ssh-brute"
|
||||||
|
fuSCAN "120" "23,2323,2324" "$myHOST" "--script=telnet-encryption,telnet-ntlm-info -sC -sS -sV --version-light"
|
||||||
|
fuSCAN "120" "25" "$myHOST" "--script=smtp* -sC -sS -sV"
|
||||||
|
fuSCAN "180" "42" "$myHOST" "-sC -sS -sV"
|
||||||
|
fuSCAN "120" "69" "$myHOST" "--script=tftp-enum -sU"
|
||||||
|
fuSCAN "120" "80,81,8080,8443" "$myHOST" "-sC -sS -sV"
|
||||||
|
fuSCAN "120" "110,995" "$myHOST" "--script=pop3-capabilities,pop3-ntlm-info -sC -sS -sV --version-light"
|
||||||
|
fuSCAN "30" "110,995" "$myHOST" "--script=pop3-brute -sS"
|
||||||
|
fuSCAN "120" "143,993" "$myHOST" "--script=imap-capabilities,imap-ntlm-info -sC -sS -sV --version-light"
|
||||||
|
fuSCAN "30" "143,993" "$myHOST" "--script=imap-brute -sS"
|
||||||
|
fuSCAN "240" "445" "$myHOST" "--script=smb-vuln* -sS -sU"
|
||||||
|
fuSCAN "120" "502" "$myHOST" "--script=modbus-discover -sS -sU"
|
||||||
|
fuSCAN "120" "623" "$myHOST" "--script=ipmi-cipher-zero,ipmi-version,supermicro-ipmi -sS -sU"
|
||||||
|
fuSCAN "30" "623" "$myHOST" "--script=ipmi-brute -sS -sU"
|
||||||
|
fuSCAN "120" "1433" "$myHOST" "--script=ms-sql* -sS"
|
||||||
|
fuSCAN "120" "1723" "$myHOST" "--script=pptp-version -sS"
|
||||||
|
fuSCAN "120" "1883" "$myHOST" "--script=mqtt-subscribe -sS"
|
||||||
|
fuSCAN "120" "2404" "$myHOST" "--script=iec-identify -sS"
|
||||||
|
fuSCAN "120" "3306" "$myHOST" "--script=mysql-vuln* -sC -sS -sV"
|
||||||
|
fuSCAN "120" "3389" "$myHOST" "--script=rdp* -sC -sS -sV"
|
||||||
|
fuSCAN "120" "5000" "$myHOST" "--script=*upnp* -sS -sU"
|
||||||
|
fuSCAN "120" "5060,5061" "$myHOST" "--script=sip-call-spoof,sip-enum-users,sip-methods -sS -sU"
|
||||||
|
fuSCAN "120" "5900" "$myHOST" "--script=vnc-info,vnc-title,realvnc-auth-bypass -sS"
|
||||||
|
fuSCAN "120" "27017" "$myHOST" "--script=mongo* -sS"
|
||||||
|
fuSCAN "120" "47808" "$myHOST" "--script=bacnet* -sS"
|
||||||
|
wait
|
||||||
|
reset
|
||||||
|
echo "Done."
|
103
bin/myip.sh
Executable file
@ -0,0 +1,103 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## Get my external IP
|
||||||
|
|
||||||
|
timeout=2 # seconds to wait for a reply before trying next server
|
||||||
|
verbose=1 # prints which server was used to STDERR
|
||||||
|
|
||||||
|
dnslist=(
|
||||||
|
"dig +short myip.opendns.com @resolver1.opendns.com"
|
||||||
|
"dig +short myip.opendns.com @resolver2.opendns.com"
|
||||||
|
"dig +short myip.opendns.com @resolver3.opendns.com"
|
||||||
|
"dig +short myip.opendns.com @resolver4.opendns.com"
|
||||||
|
"dig +short -4 -t a whoami.akamai.net @ns1-1.akamaitech.net"
|
||||||
|
"dig +short whoami.akamai.net @ns1-1.akamaitech.net"
|
||||||
|
)
|
||||||
|
|
||||||
|
httplist=(
|
||||||
|
alma.ch/myip.cgi
|
||||||
|
api.infoip.io/ip
|
||||||
|
api.ipify.org
|
||||||
|
bot.whatismyipaddress.com
|
||||||
|
canhazip.com
|
||||||
|
checkip.amazonaws.com
|
||||||
|
eth0.me
|
||||||
|
icanhazip.com
|
||||||
|
ident.me
|
||||||
|
ipecho.net/plain
|
||||||
|
ipinfo.io/ip
|
||||||
|
ipof.in/txt
|
||||||
|
ip.tyk.nu
|
||||||
|
l2.io/ip
|
||||||
|
smart-ip.net/myip
|
||||||
|
wgetip.com
|
||||||
|
whatismyip.akamai.com
|
||||||
|
)
|
||||||
|
|
||||||
|
# function to check for valid ip
|
||||||
|
function valid_ip()
|
||||||
|
{
|
||||||
|
local ip=$1
|
||||||
|
local stat=1
|
||||||
|
|
||||||
|
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||||
|
OIFS=$IFS
|
||||||
|
IFS='.'
|
||||||
|
ip=($ip)
|
||||||
|
IFS=$OIFS
|
||||||
|
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
|
||||||
|
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
|
||||||
|
stat=$?
|
||||||
|
fi
|
||||||
|
return $stat
|
||||||
|
}
|
||||||
|
|
||||||
|
# function to shuffle the global array "array"
|
||||||
|
shuffle() {
|
||||||
|
local i tmp size max rand
|
||||||
|
size=${#array[*]}
|
||||||
|
max=$(( 32768 / size * size ))
|
||||||
|
for ((i=size-1; i>0; i--)); do
|
||||||
|
while (( (rand=$RANDOM) >= max )); do :; done
|
||||||
|
rand=$(( rand % (i+1) ))
|
||||||
|
tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
|
||||||
|
done
|
||||||
|
}
|
||||||
|
# if we have dig and a list of dns methods, try that first
|
||||||
|
if hash dig 2>/dev/null && [ ${#dnslist[*]} -gt 0 ]; then
|
||||||
|
eval array=( \"\${dnslist[@]}\" )
|
||||||
|
shuffle
|
||||||
|
for cmd in "${array[@]}"; do
|
||||||
|
[ "$verbose" == 1 ] && echo Trying: $cmd 1>&2
|
||||||
|
ip=$(timeout $timeout $cmd)
|
||||||
|
if [ -n "$ip" ]; then
|
||||||
|
if valid_ip $ip; then
|
||||||
|
echo $ip
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
# if we haven't succeeded with DNS, try HTTP
|
||||||
|
if [ ${#httplist[*]} == 0 ]; then
|
||||||
|
echo "No hosts in httplist array!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# use curl or wget, depending on which one we find
|
||||||
|
curl_or_wget=$(if hash curl 2>/dev/null; then echo "curl -s"; elif hash wget 2>/dev/null; then echo "wget -qO-"; fi);
|
||||||
|
if [ -z "$curl_or_wget" ]; then
|
||||||
|
echo "Neither curl nor wget found. Cannot use http method." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
eval array=( \"\${httplist[@]}\" )
|
||||||
|
shuffle
|
||||||
|
for url in "${array[@]}"; do
|
||||||
|
[ "$verbose" == 1 ] && echo Trying: $curl_or_wget "$url" 1>&2
|
||||||
|
ip=$(timeout $timeout $curl_or_wget "$url")
|
||||||
|
if [ -n "$ip" ]; then
|
||||||
|
if valid_ip $ip; then
|
||||||
|
echo $ip
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
27
bin/mytopips.sh
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Make sure ES is available
|
||||||
|
myES="http://127.0.0.1:64298/"
|
||||||
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
||||||
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
|
then
|
||||||
|
echo "### Elasticsearch is not available, try starting via 'systemctl start elk'."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "### Elasticsearch is available, now continuing."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
function fuMYTOPIPS {
|
||||||
|
curl -s -XGET $myES"_search" -H 'Content-Type: application/json' -d'
|
||||||
|
{
|
||||||
|
"aggs": {
|
||||||
|
"ips": {
|
||||||
|
"terms": { "field": "src_ip.keyword", "size": 100 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"size" : 0
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "### Aggregating top 100 source IPs in ES"
|
||||||
|
fuMYTOPIPS | jq '.aggregations.ips.buckets[].key' | tr -d '"'
|
@ -2,10 +2,10 @@
|
|||||||
# Restore folder based ES backup
|
# Restore folder based ES backup
|
||||||
# Make sure ES is available
|
# Make sure ES is available
|
||||||
myES="http://127.0.0.1:64298/"
|
myES="http://127.0.0.1:64298/"
|
||||||
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c green)
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c "green\|yellow")
|
||||||
if ! [ "$myESSTATUS" = "1" ]
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
then
|
then
|
||||||
echo "### Elasticsearch is not available, try starting via 'systemctl start elk'."
|
echo "### Elasticsearch is not available, try starting via 'systemctl start tpot'."
|
||||||
exit
|
exit
|
||||||
else
|
else
|
||||||
echo "### Elasticsearch is available, now continuing."
|
echo "### Elasticsearch is available, now continuing."
|
||||||
@ -41,16 +41,50 @@ echo $myCOL1"### Now unpacking tar archive: "$myDUMP $myCOL0
|
|||||||
tar xvf $myDUMP
|
tar xvf $myDUMP
|
||||||
|
|
||||||
# Build indices list
|
# Build indices list
|
||||||
myINDICES=$(ls tmp/logstash*.gz | cut -c 5- | rev | cut -c 4- | rev)
|
myINDICES="$(ls tmp/logstash*.gz | cut -c 5- | rev | cut -c 4- | rev)"
|
||||||
|
myINDICES+=" .kibana"
|
||||||
echo $myCOL1"### The following indices will be restored: "$myCOL0
|
echo $myCOL1"### The following indices will be restored: "$myCOL0
|
||||||
echo $myINDICES
|
echo $myINDICES
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
# Force single seat template for everything
|
||||||
|
echo -n $myCOL1"### Forcing single seat template: "$myCOL0
|
||||||
|
curl -s XPUT ''$myES'_template/.*' -H 'Content-Type: application/json' -d'
|
||||||
|
{ "index_patterns": ".*",
|
||||||
|
"order": 1,
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"number_of_shards": 1,
|
||||||
|
"number_of_replicas": 0
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Set logstash template
|
||||||
|
echo -n $myCOL1"### Setting up logstash template: "$myCOL0
|
||||||
|
curl -s XPUT ''$myES'_template/logstash' -H 'Content-Type: application/json' -d'
|
||||||
|
{
|
||||||
|
"index_patterns": "logstash-*",
|
||||||
|
"settings" : {
|
||||||
|
"index" : {
|
||||||
|
"number_of_shards": 1,
|
||||||
|
"number_of_replicas": 0,
|
||||||
|
"mapping" : {
|
||||||
|
"total_fields" : {
|
||||||
|
"limit" : "2000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
echo
|
||||||
|
|
||||||
# Restore indices
|
# Restore indices
|
||||||
|
curl -s -X DELETE ''$myES'.kibana*' > /dev/null
|
||||||
for i in $myINDICES;
|
for i in $myINDICES;
|
||||||
do
|
do
|
||||||
# Delete index if it already exists
|
# Delete index if it already exists
|
||||||
curl -s -XDELETE $myES$i > /dev/null
|
curl -s -X DELETE $myES$i > /dev/null
|
||||||
echo $myCOL1"### Now uncompressing: tmp/$i.gz" $myCOL0
|
echo $myCOL1"### Now uncompressing: tmp/$i.gz" $myCOL0
|
||||||
gunzip -f tmp/$i.gz
|
gunzip -f tmp/$i.gz
|
||||||
# Restore index to ES
|
# Restore index to ES
|
107
bin/rules.sh
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
### Vars, Ports for Standard services
|
||||||
|
myHOSTPORTS="7634 64294 64295"
|
||||||
|
myDOCKERCOMPOSEYML="$1"
|
||||||
|
myRULESFUNCTION="$2"
|
||||||
|
|
||||||
|
function fuCHECKFORARGS {
|
||||||
|
### Check if args are present, if not throw error
|
||||||
|
|
||||||
|
if [ "$myDOCKERCOMPOSEYML" != "" ] && ([ "$myRULESFUNCTION" == "set" ] || [ "$myRULESFUNCTION" == "unset" ]);
|
||||||
|
then
|
||||||
|
echo "All arguments met. Continuing."
|
||||||
|
else
|
||||||
|
echo "Usage: rules.sh <docker-compose.yml> <[set, unset]>"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuNFQCHECK {
|
||||||
|
### Check if honeytrap or glutton is actively enabled in docker-compose.yml
|
||||||
|
|
||||||
|
myNFQCHECK=$(grep -e '^\s*honeytrap:\|^\s*glutton:' $myDOCKERCOMPOSEYML | tr -d ': ' | uniq)
|
||||||
|
if [ "$myNFQCHECK" == "" ];
|
||||||
|
then
|
||||||
|
echo "No NFQ related honeypot detected, no iptables-legacy rules needed. Exiting."
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
echo "Detected $myNFQCHECK as NFQ based honeypot, iptables-legacy rules needed. Continuing."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuGETPORTS {
|
||||||
|
### Get ports from docker-compose.yml
|
||||||
|
|
||||||
|
myDOCKERCOMPOSEPORTS=$(cat $myDOCKERCOMPOSEYML | yq -r '.services[].ports' | grep ':' | sed -e s/127.0.0.1// | tr -d '", ' | sed -e s/^:// | cut -f1 -d ':' )
|
||||||
|
myDOCKERCOMPOSEPORTS+=" $myHOSTPORTS"
|
||||||
|
myRULESPORTS=$(for i in $myDOCKERCOMPOSEPORTS; do echo $i; done | sort -gu)
|
||||||
|
echo "Setting up / removing these ports:"
|
||||||
|
echo "$myRULESPORTS"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuSETRULES {
|
||||||
|
### Setting up iptables-legacy rules for honeytrap
|
||||||
|
if [ "$myNFQCHECK" == "honeytrap" ];
|
||||||
|
then
|
||||||
|
/usr/sbin/iptables-legacy -w -A INPUT -s 127.0.0.1 -j ACCEPT
|
||||||
|
/usr/sbin/iptables-legacy -w -A INPUT -d 127.0.0.1 -j ACCEPT
|
||||||
|
|
||||||
|
for myPORT in $myRULESPORTS; do
|
||||||
|
/usr/sbin/iptables-legacy -w -A INPUT -p tcp --dport $myPORT -j ACCEPT
|
||||||
|
done
|
||||||
|
|
||||||
|
/usr/sbin/iptables-legacy -w -A INPUT -p tcp --syn -m state --state NEW -j NFQUEUE
|
||||||
|
fi
|
||||||
|
|
||||||
|
### Setting up iptables-legacy rules for glutton
|
||||||
|
if [ "$myNFQCHECK" == "glutton" ];
|
||||||
|
then
|
||||||
|
/usr/sbin/iptables-legacy -w -t raw -A PREROUTING -s 127.0.0.1 -j ACCEPT
|
||||||
|
/usr/sbin/iptables-legacy -w -t raw -A PREROUTING -d 127.0.0.1 -j ACCEPT
|
||||||
|
|
||||||
|
for myPORT in $myRULESPORTS; do
|
||||||
|
/usr/sbin/iptables-legacy -w -t raw -A PREROUTING -p tcp --dport $myPORT -j ACCEPT
|
||||||
|
done
|
||||||
|
# No need for NFQ forwarding, such rules are set up by glutton
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function fuUNSETRULES {
|
||||||
|
### Removing iptables-legacy rules for honeytrap
|
||||||
|
if [ "$myNFQCHECK" == "honeytrap" ];
|
||||||
|
then
|
||||||
|
/usr/sbin/iptables-legacy -w -D INPUT -s 127.0.0.1 -j ACCEPT
|
||||||
|
/usr/sbin/iptables-legacy -w -D INPUT -d 127.0.0.1 -j ACCEPT
|
||||||
|
|
||||||
|
for myPORT in $myRULESPORTS; do
|
||||||
|
/usr/sbin/iptables-legacy -w -D INPUT -p tcp --dport $myPORT -j ACCEPT
|
||||||
|
done
|
||||||
|
|
||||||
|
/usr/sbin/iptables-legacy -w -D INPUT -p tcp --syn -m state --state NEW -j NFQUEUE
|
||||||
|
fi
|
||||||
|
|
||||||
|
### Removing iptables-legacy rules for glutton
|
||||||
|
if [ "$myNFQCHECK" == "glutton" ];
|
||||||
|
then
|
||||||
|
/usr/sbin/iptables-legacy -w -t raw -D PREROUTING -s 127.0.0.1 -j ACCEPT
|
||||||
|
/usr/sbin/iptables-legacy -w -t raw -D PREROUTING -d 127.0.0.1 -j ACCEPT
|
||||||
|
|
||||||
|
for myPORT in $myRULESPORTS; do
|
||||||
|
/usr/sbin/iptables-legacy -w -t raw -D PREROUTING -p tcp --dport $myPORT -j ACCEPT
|
||||||
|
done
|
||||||
|
# No need for removing NFQ forwarding, such rules are removed by glutton
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main
|
||||||
|
fuCHECKFORARGS
|
||||||
|
fuNFQCHECK
|
||||||
|
fuGETPORTS
|
||||||
|
|
||||||
|
if [ "$myRULESFUNCTION" == "set" ];
|
||||||
|
then
|
||||||
|
fuSETRULES
|
||||||
|
else
|
||||||
|
fuUNSETRULES
|
||||||
|
fi
|
56
bin/tped.sh
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Run as root only.
|
||||||
|
myWHOAMI=$(whoami)
|
||||||
|
if [ "$myWHOAMI" != "root" ]
|
||||||
|
then
|
||||||
|
echo "Need to run as root ..."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set backtitle, get filename
|
||||||
|
myBACKTITLE="T-Pot Edition Selection Tool"
|
||||||
|
myYMLS=$(cd /opt/tpot/etc/compose/ && ls -1 *.yml)
|
||||||
|
myLINK="/opt/tpot/etc/tpot.yml"
|
||||||
|
|
||||||
|
# Let's load docker images in parallel
|
||||||
|
function fuPULLIMAGES {
|
||||||
|
local myTPOTCOMPOSE="/opt/tpot/etc/tpot.yml"
|
||||||
|
for name in $(cat $myTPOTCOMPOSE | grep -v '#' | grep image | cut -d'"' -f2 | uniq)
|
||||||
|
do
|
||||||
|
docker pull $name &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# setup menu
|
||||||
|
for i in $myYMLS;
|
||||||
|
do
|
||||||
|
myITEMS+="$i $(echo $i | cut -d "." -f1 | tr [:lower:] [:upper:]) "
|
||||||
|
done
|
||||||
|
myEDITION=$(dialog --backtitle "$myBACKTITLE" --menu "Select T-Pot Edition" 17 50 10 $myITEMS 3>&1 1>&2 2>&3 3>&-)
|
||||||
|
if [ "$myEDITION" == "" ];
|
||||||
|
then
|
||||||
|
echo "Have a nice day!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
dialog --backtitle "$myBACKTITLE" --title "[ Activate now? ]" --yesno "\n$myEDITION" 7 50
|
||||||
|
myOK=$?
|
||||||
|
if [ "$myOK" == "0" ];
|
||||||
|
then
|
||||||
|
echo "OK - Activating and downloading latest images."
|
||||||
|
systemctl stop tpot
|
||||||
|
if [ "$(docker ps -aq)" != "" ];
|
||||||
|
then
|
||||||
|
docker stop $(docker ps -aq)
|
||||||
|
docker rm $(docker ps -aq)
|
||||||
|
fi
|
||||||
|
rm -f $myLINK
|
||||||
|
ln -s /opt/tpot/etc/compose/$myEDITION $myLINK
|
||||||
|
fuPULLIMAGES
|
||||||
|
systemctl start tpot
|
||||||
|
echo "Done. Use \"dps.sh\" for monitoring"
|
||||||
|
else
|
||||||
|
echo "Have a nice day!"
|
||||||
|
fi
|
19
bin/unlock_es.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#/bin/bash
|
||||||
|
# Unlock all ES indices for read / write mode
|
||||||
|
# Useful in cases where ES locked all indices after disk quota has been reached
|
||||||
|
# Make sure ES is available
|
||||||
|
myES="http://127.0.0.1:64298/"
|
||||||
|
myESSTATUS=$(curl -s -XGET ''$myES'_cluster/health' | jq '.' | grep -c "green\|yellow")
|
||||||
|
if ! [ "$myESSTATUS" = "1" ]
|
||||||
|
then
|
||||||
|
echo "### Elasticsearch is not available, try starting via 'systemctl start tpot'."
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
echo "### Elasticsearch is available, now continuing."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "### Trying to unlock all ES indices for read / write operation: "
|
||||||
|
curl -XPUT -H "Content-Type: application/json" ''$myES'_all/_settings' -d '{"index.blocks.read_only_allow_delete": null}'
|
||||||
|
echo
|
||||||
|
|
48
bin/updateip.sh
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Let's add the first local ip to the /etc/issue and external ip to ews.ip file
|
||||||
|
# If the external IP cannot be detected, the internal IP will be inherited.
|
||||||
|
source /etc/environment
|
||||||
|
myUUID=$(lsblk -o MOUNTPOINT,UUID | grep "/" | awk '{ print $2 }')
|
||||||
|
myLOCALIP=$(hostname -I | awk '{ print $1 }')
|
||||||
|
myEXTIP=$(/opt/tpot/bin/myip.sh)
|
||||||
|
if [ "$myEXTIP" = "" ];
|
||||||
|
then
|
||||||
|
myEXTIP=$myLOCALIP
|
||||||
|
fi
|
||||||
|
mySSHUSER=$(cat /etc/passwd | grep 1000 | cut -d ':' -f1)
|
||||||
|
echo "[H[2J" > /etc/issue
|
||||||
|
toilet -f ivrit -F metal --filter border:metal "T-Pot 20.06" | sed 's/\\/\\\\/g' >> /etc/issue
|
||||||
|
echo >> /etc/issue
|
||||||
|
echo ",---- [ [1;34m\n[0m ] [ [0;34m\d[0m ] [ [1;30m\t[0m ]" >> /etc/issue
|
||||||
|
echo "|" >> /etc/issue
|
||||||
|
echo "| [1;34mIP: $myLOCALIP ($myEXTIP)[0m" >> /etc/issue
|
||||||
|
echo "| [0;34mSSH: ssh -l tsec -p 64295 $myLOCALIP[0m" >> /etc/issue
|
||||||
|
echo "| [1;30mWEB: https://$myLOCALIP:64297[0m" >> /etc/issue
|
||||||
|
echo "| [0;37mADMIN: https://$myLOCALIP:64294[0m" >> /etc/issue
|
||||||
|
echo "|" >> /etc/issue
|
||||||
|
echo "\`----" >> /etc/issue
|
||||||
|
echo >> /etc/issue
|
||||||
|
tee /data/ews/conf/ews.ip << EOF
|
||||||
|
[MAIN]
|
||||||
|
ip = $myEXTIP
|
||||||
|
EOF
|
||||||
|
tee /opt/tpot/etc/compose/elk_environment << EOF
|
||||||
|
HONEY_UUID=$myUUID
|
||||||
|
MY_EXTIP=$myEXTIP
|
||||||
|
MY_INTIP=$myLOCALIP
|
||||||
|
MY_HOSTNAME=$HOSTNAME
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ -s "/data/elk/logstash/ls_environment" ];
|
||||||
|
then
|
||||||
|
source /data/elk/logstash/ls_environment
|
||||||
|
tee -a /opt/tpot/etc/compose/elk_environment << EOF
|
||||||
|
MY_TPOT_TYPE=$MY_TPOT_TYPE
|
||||||
|
MY_POT_PRIVATEKEYFILE=$MY_POT_PRIVATEKEYFILE
|
||||||
|
MY_HIVE_USERNAME=$MY_HIVE_USERNAME
|
||||||
|
MY_HIVE_IP=$MY_HIVE_IP
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
chown tpot:tpot /data/ews/conf/ews.ip
|
||||||
|
chmod 770 /data/ews/conf/ews.ip
|
10
cloud/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Ansible
|
||||||
|
*.retry
|
||||||
|
|
||||||
|
# Terraform
|
||||||
|
**/.terraform
|
||||||
|
**/terraform.*
|
||||||
|
|
||||||
|
# OpenStack clouds
|
||||||
|
**/clouds.yaml
|
||||||
|
**/secure.yaml
|
257
cloud/ansible/README.md
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
# T-Pot Ansible
|
||||||
|
|
||||||
|
Here you can find a ready-to-use solution for your automated T-Pot deployment using [Ansible](https://www.ansible.com/).
|
||||||
|
It consists of an Ansible Playbook with multiple roles, which is reusable for all [OpenStack](https://www.openstack.org/) based clouds (e.g. Open Telekom Cloud, Orange Cloud, Telefonica Open Cloud, OVH) out of the box.
|
||||||
|
Apart from that you can easily adapt the deploy role to use other [cloud providers](https://docs.ansible.com/ansible/latest/scenario_guides/cloud_guides.html). Check out [Ansible Galaxy](https://galaxy.ansible.com/search?keywords=&order_by=-relevance&page=1&deprecated=false&type=collection&tags=cloud) for more cloud collections.
|
||||||
|
|
||||||
|
The Playbook first creates all resources (security group, network, subnet, router), deploys one (or more) new servers and then installs and configures T-Pot on them.
|
||||||
|
|
||||||
|
This example showcases the deployment on our own OpenStack based Public Cloud Offering [Open Telekom Cloud](https://open-telekom-cloud.com/en).
|
||||||
|
|
||||||
|
# Table of contents
|
||||||
|
- [Preparation of Ansible Master](#ansible-master)
|
||||||
|
- [Ansible Installation](#ansible)
|
||||||
|
- [OpenStack Collection Installation](#collection)
|
||||||
|
- [Agent Forwarding](#agent-forwarding)
|
||||||
|
- [Preparations in Open Telekom Cloud Console](#preparation)
|
||||||
|
- [Create new project](#project)
|
||||||
|
- [Create API user](#api-user)
|
||||||
|
- [Import Key Pair](#key-pair)
|
||||||
|
- [Clone Git Repository](#clone-git)
|
||||||
|
- [Settings and recommended values](#settings)
|
||||||
|
- [clouds.yaml](#clouds-yaml)
|
||||||
|
- [Ansible remote user](#remote-user)
|
||||||
|
- [Number of instances to deploy](#number)
|
||||||
|
- [Instance settings](#instance-settings)
|
||||||
|
- [User password](#user-password)
|
||||||
|
- [Configure `tpot.conf.dist`](#tpot-conf)
|
||||||
|
- [Optional: Custom `ews.cfg`](#ews-cfg)
|
||||||
|
- [Optional: Custom HPFEEDS](#hpfeeds)
|
||||||
|
- [Deploying a T-Pot](#deploy)
|
||||||
|
- [Further documentation](#documentation)
|
||||||
|
|
||||||
|
<a name="ansible-master"></a>
|
||||||
|
# Preparation of Ansible Master
|
||||||
|
You can either run the Ansible Playbook locally on your Linux or macOS machine or you can use an ECS (Elastic Cloud Server) on Open Telekom Cloud, which I did.
|
||||||
|
I used Ubuntu 18.04 for my Ansible Master Server, but other OSes are fine too.
|
||||||
|
Ansible works over the SSH Port, so you don't have to add any special rules to your Security Group.
|
||||||
|
|
||||||
|
<a name="ansible"></a>
|
||||||
|
## Ansible Installation
|
||||||
|
:warning: Ansible 2.10 or newer is required!
|
||||||
|
|
||||||
|
Example for Ubuntu 18.04:
|
||||||
|
|
||||||
|
At first we update the system:
|
||||||
|
`sudo apt update`
|
||||||
|
`sudo apt dist-upgrade`
|
||||||
|
|
||||||
|
Then we need to add the repository and install Ansible:
|
||||||
|
`sudo apt-add-repository --yes --update ppa:ansible/ansible`
|
||||||
|
`sudo apt install ansible`
|
||||||
|
|
||||||
|
For other OSes and Distros have a look at the official [Ansible Documentation](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html).
|
||||||
|
|
||||||
|
If your OS does not offer a recent version of Ansible (>= 2.10) you should consider [installing Ansible with pip](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-with-pip).
|
||||||
|
In short (if you already have Python3/pip3 installed):
|
||||||
|
```
|
||||||
|
pip3 install ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="collection"></a>
|
||||||
|
## OpenStack Collection Installation
|
||||||
|
For interacting with OpenStack resources in Ansible, you need to install the collection from Ansible Galaxy:
|
||||||
|
`ansible-galaxy collection install openstack.cloud`
|
||||||
|
|
||||||
|
<a name="agent-forwarding"></a>
|
||||||
|
## Agent Forwarding
|
||||||
|
If you run the Ansible Playbook remotely on your Ansible Master Server, Agent Forwarding must be enabled in order to let Ansible connect to newly created machines.
|
||||||
|
- On Linux or macOS:
|
||||||
|
- Create or edit `~/.ssh/config`
|
||||||
|
```
|
||||||
|
Host ANSIBLE_MASTER_IP
|
||||||
|
ForwardAgent yes
|
||||||
|
```
|
||||||
|
- On Windows using Putty:
|
||||||
|

|
||||||
|
|
||||||
|
<a name="preparation"></a>
|
||||||
|
# Preparations in Open Telekom Cloud Console
|
||||||
|
(You can skip this if you have already set up a project and an API account with key pair)
|
||||||
|
(Just make sure you know the naming for everything, as you need to configure the Ansible variables.)
|
||||||
|
|
||||||
|
Before we can start deploying, we have to prepare the Open Telekom Cloud tenant.
|
||||||
|
For that, go to the [Web Console](https://auth.otc.t-systems.com/authui/login) and log in with an admin user.
|
||||||
|
|
||||||
|
<a name="project"></a>
|
||||||
|
## Create new project
|
||||||
|
I strongly advise you to create a separate project for the T-Pots in your tenant.
|
||||||
|
In my case I named it `tpot`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<a name="api-user"></a>
|
||||||
|
## Create API user
|
||||||
|
The next step is to create a new user account, which is restricted to the project.
|
||||||
|
This ensures that the API access is limited to that project.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<a name="key-pair"></a>
|
||||||
|
## Import Key Pair
|
||||||
|
:warning: Now log in with the newly created API user account and select your project.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Import your SSH public key.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
<a name="clone-git"></a>
|
||||||
|
# Clone Git Repository
|
||||||
|
Clone the `tpotce` repository to your Ansible Master:
|
||||||
|
`git clone https://github.com/telekom-security/tpotce.git`
|
||||||
|
All Ansible related files are located in the [`cloud/ansible/openstack`](openstack) folder.
|
||||||
|
|
||||||
|
<a name="settings"></a>
|
||||||
|
# Settings and recommended values
|
||||||
|
You can configure all aspects of your Elastic Cloud Server and T-Pot before using the Playbook:
|
||||||
|
|
||||||
|
<a name="clouds-yaml"></a>
|
||||||
|
## clouds.yaml
|
||||||
|
Located at [`openstack/clouds.yaml`](openstack/clouds.yaml).
|
||||||
|
Enter your Open Telekom Cloud API user credentials here (username, password, project name, user domain name):
|
||||||
|
```
|
||||||
|
clouds:
|
||||||
|
open-telekom-cloud:
|
||||||
|
profile: otc
|
||||||
|
auth:
|
||||||
|
project_name: eu-de_your_project
|
||||||
|
username: your_api_user
|
||||||
|
password: your_password
|
||||||
|
user_domain_name: OTC-EU-DE-000000000010000XXXXX
|
||||||
|
```
|
||||||
|
You can also perform different authentication methods like sourcing OpenStack OS_* environment variables or providing an inline dictionary.
|
||||||
|
For more information have a look in the [openstack.cloud.server](https://docs.ansible.com/ansible/latest/collections/openstack/cloud/server_module.html) Ansible module documentation.
|
||||||
|
|
||||||
|
If you already have your own `clouds.yaml` file or have multiple clouds in there, you can specify which one to use in the `openstack/my_os_cloud.yaml` file:
|
||||||
|
```
|
||||||
|
# Enter the name of your cloud to use from clouds.yaml
|
||||||
|
cloud: open-telekom-cloud
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="remote-user"></a>
|
||||||
|
## Ansible remote user
|
||||||
|
You may have to adjust the `remote_user` in the Ansible Playbook under [`openstack/deploy_tpot.yaml`](openstack/deploy_tpot.yaml) depending on your Debian base image (e.g. on Open Telekom Cloud the default Debian user is `linux`).
|
||||||
|
|
||||||
|
<a name="number"></a>
|
||||||
|
## Number of instances to deploy
|
||||||
|
You can adjust the number of VMs/T-Pots that you want to create in [`openstack/deploy_tpot.yaml`](openstack/deploy_tpot.yaml):
|
||||||
|
```
|
||||||
|
loop: "{{ range(0, 1) }}"
|
||||||
|
```
|
||||||
|
One instance is set as the default, increase to your liking.
|
||||||
|
|
||||||
|
<a name="instance-settings"></a>
|
||||||
|
## Instance settings
|
||||||
|
Located at [`openstack/roles/create_vm/vars/main.yaml`](openstack/roles/create_vm/vars/main.yaml).
|
||||||
|
Here you can customize your virtual machine specifications:
|
||||||
|
- Choose an availability zone. For Open Telekom Cloud reference see [here](https://docs.otc.t-systems.com/en-us/endpoint/index.html).
|
||||||
|
- Change the OS image (For T-Pot we need Debian)
|
||||||
|
- (Optional) Change the volume size
|
||||||
|
- Specify your key pair (:warning: Mandatory)
|
||||||
|
- (Optional) Change the instance type (flavor)
|
||||||
|
`s3.medium.8` corresponds to 1 vCPU and 8GB of RAM and is the minimum required flavor.
|
||||||
|
A full list of Open Telekom Cloud flavors can be found [here](https://docs.otc.t-systems.com/en-us/usermanual/ecs/en-us_topic_0177512565.html).
|
||||||
|
|
||||||
|
```
|
||||||
|
availability_zone: eu-de-03
|
||||||
|
image: Standard_Debian_10_latest
|
||||||
|
volume_size: 128
|
||||||
|
key_name: your-KeyPair
|
||||||
|
flavor: s3.medium.8
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="user-password"></a>
|
||||||
|
## User password
|
||||||
|
Located at [`openstack/roles/install/vars/main.yaml`](openstack/roles/install/vars/main.yaml).
|
||||||
|
Here you can set the password for your Debian user (**you should definitely change that**).
|
||||||
|
```
|
||||||
|
user_password: LiNuXuSeRPaSs#
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="tpot-conf"></a>
|
||||||
|
## Configure `tpot.conf.dist`
|
||||||
|
The file is located in [`iso/installer/tpot.conf.dist`](/iso/installer/tpot.conf.dist).
|
||||||
|
Here you can choose:
|
||||||
|
- between the various T-Pot editions
|
||||||
|
- a username for the web interface
|
||||||
|
- a password for the web interface (**you should definitely change that**)
|
||||||
|
|
||||||
|
<a name="ews-cfg"></a>
|
||||||
|
## Optional: Custom `ews.cfg`
|
||||||
|
Enable this by uncommenting the role in the [deploy_tpot.yaml](openstack/deploy_tpot.yaml) playbook.
|
||||||
|
```
|
||||||
|
# - custom_ews
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use a custom config file for `ewsposter`.
|
||||||
|
e.g. when you have your own credentials for delivering data to our [Sicherheitstacho](https://sicherheitstacho.eu/start/main).
|
||||||
|
You can find the `ews.cfg` template file here: [`openstack/roles/custom_ews/templates/ews.cfg`](openstack/roles/custom_ews/templates/ews.cfg) and adapt it for your needs.
|
||||||
|
|
||||||
|
For setting custom credentials, these settings would be relevant for you (the rest of the file can stay as is):
|
||||||
|
```
|
||||||
|
[MAIN]
|
||||||
|
...
|
||||||
|
contact = your_email_address
|
||||||
|
...
|
||||||
|
|
||||||
|
[EWS]
|
||||||
|
...
|
||||||
|
username = your_username
|
||||||
|
token = your_token
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="hpfeeds"></a>
|
||||||
|
## Optional: Custom HPFEEDS
|
||||||
|
Enable this by uncommenting the role in the [deploy_tpot.yaml](openstack/deploy_tpot.yaml) playbook.
|
||||||
|
```
|
||||||
|
# - custom_hpfeeds
|
||||||
|
```
|
||||||
|
|
||||||
|
You can specify custom HPFEEDS in [`openstack/roles/custom_hpfeeds/files/hpfeeds.cfg`](openstack/roles/custom_hpfeeds/files/hpfeeds.cfg).
|
||||||
|
That file contains the defaults (turned off) and you can adapt it for your needs, e.g. for SISSDEN:
|
||||||
|
```
|
||||||
|
myENABLE=true
|
||||||
|
myHOST=hpfeeds.sissden.eu
|
||||||
|
myPORT=10000
|
||||||
|
myCHANNEL=t-pot.events
|
||||||
|
myCERT=/opt/ewsposter/sissden.pem
|
||||||
|
myIDENT=your_user
|
||||||
|
mySECRET=your_secret
|
||||||
|
myFORMAT=json
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="deploy"></a>
|
||||||
|
# Deploying a T-Pot :honey_pot::honeybee:
|
||||||
|
Now, after configuring everything, we can finally start deploying T-Pots!
|
||||||
|
|
||||||
|
Go to the [`openstack`](openstack) folder and run the Ansible Playbook with:
|
||||||
|
`ansible-playbook deploy_tpot.yaml`
|
||||||
|
(Yes, it is as easy as that :smile:)
|
||||||
|
|
||||||
|
If you are running on a machine which asks for a sudo password, you can use:
|
||||||
|
`ansible-playbook --ask-become-pass deploy_tpot.yaml`
|
||||||
|
|
||||||
|
The Playbook will first install required packages on the Ansible Master and then deploy one (or more) new server instances.
|
||||||
|
After that, T-Pot gets installed and configured on them, optionally custom configs are applied and finally it reboots.
|
||||||
|
|
||||||
|
Once this is done, you can proceed with connecting/logging in to the T-Pot according to the [documentation](https://github.com/telekom-security/tpotce#ssh-and-web-access).
|
||||||
|
|
||||||
|
<a name="documentation"></a>
|
||||||
|
# Further documentation
|
||||||
|
- [Ansible Documentation](https://docs.ansible.com/ansible/latest/)
|
||||||
|
- [openstack.cloud.server – Create/Delete Compute Instances from OpenStack](https://docs.ansible.com/ansible/latest/collections/openstack/cloud/server_module.html)
|
||||||
|
- [Open Telekom Cloud Help Center](https://docs.otc.t-systems.com/)
|
BIN
cloud/ansible/doc/otc_1_project.gif
Normal file
After Width: | Height: | Size: 204 KiB |
BIN
cloud/ansible/doc/otc_2_user.gif
Normal file
After Width: | Height: | Size: 883 KiB |
BIN
cloud/ansible/doc/otc_3_login.gif
Normal file
After Width: | Height: | Size: 148 KiB |
BIN
cloud/ansible/doc/otc_4_import_key.gif
Normal file
After Width: | Height: | Size: 193 KiB |
BIN
cloud/ansible/doc/putty_agent_forwarding.png
Normal file
After Width: | Height: | Size: 23 KiB |
6
cloud/ansible/openstack/ansible.cfg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[defaults]
|
||||||
|
host_key_checking = false
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
scp_if_ssh = true
|
||||||
|
ssh_args = -o ServerAliveInterval=60
|
9
cloud/ansible/openstack/clouds.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
clouds:
|
||||||
|
open-telekom-cloud:
|
||||||
|
profile: otc
|
||||||
|
region_name: eu-de
|
||||||
|
auth:
|
||||||
|
project_name: eu-de_your_project
|
||||||
|
username: your_api_user
|
||||||
|
password: your_password
|
||||||
|
user_domain_name: OTC-EU-DE-000000000010000XXXXX
|
30
cloud/ansible/openstack/deploy_tpot.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
- name: Check host prerequisites
|
||||||
|
hosts: localhost
|
||||||
|
become: yes
|
||||||
|
roles:
|
||||||
|
- check
|
||||||
|
|
||||||
|
- name: Deploy instances
|
||||||
|
hosts: localhost
|
||||||
|
vars_files: my_os_cloud.yaml
|
||||||
|
tasks:
|
||||||
|
- name: Create security group and network
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: create_net
|
||||||
|
- name: Create one or more instances
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: create_vm
|
||||||
|
loop: "{{ range(0, 1) }}"
|
||||||
|
loop_control:
|
||||||
|
extended: yes
|
||||||
|
|
||||||
|
- name: Install T-Pot
|
||||||
|
hosts: tpot
|
||||||
|
remote_user: linux
|
||||||
|
become: yes
|
||||||
|
gather_facts: no
|
||||||
|
roles:
|
||||||
|
- install
|
||||||
|
# - custom_ews
|
||||||
|
# - custom_hpfeeds
|
||||||
|
- reboot
|
2
cloud/ansible/openstack/my_os_cloud.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Enter the name of your cloud to use from clouds.yaml
|
||||||
|
cloud: open-telekom-cloud
|
2
cloud/ansible/openstack/requirements.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
collections:
|
||||||
|
- name: openstack.cloud
|
19
cloud/ansible/openstack/roles/check/tasks/main.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
- name: Install dependencies
|
||||||
|
ansible.builtin.package:
|
||||||
|
name:
|
||||||
|
- gcc
|
||||||
|
- python3-dev
|
||||||
|
- python3-setuptools
|
||||||
|
- python3-pip
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install openstacksdk
|
||||||
|
ansible.builtin.pip:
|
||||||
|
name: openstacksdk
|
||||||
|
executable: pip3
|
||||||
|
|
||||||
|
- name: Check if agent forwarding is enabled
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: Please enable agent forwarding to allow Ansible to connect to the remote host!
|
||||||
|
ignore_errors: yes
|
||||||
|
failed_when: lookup('env','SSH_AUTH_SOCK') == ""
|
33
cloud/ansible/openstack/roles/create_net/tasks/main.yaml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
- name: Create security group
|
||||||
|
openstack.cloud.security_group:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
name: sg-tpot-ansible
|
||||||
|
description: Security Group for T-Pot
|
||||||
|
|
||||||
|
- name: Add rules to security group
|
||||||
|
openstack.cloud.security_group_rule:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
security_group: sg-tpot-ansible
|
||||||
|
remote_ip_prefix: 0.0.0.0/0
|
||||||
|
|
||||||
|
- name: Create network
|
||||||
|
openstack.cloud.network:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
name: network-tpot-ansible
|
||||||
|
|
||||||
|
- name: Create subnet
|
||||||
|
openstack.cloud.subnet:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
network_name: network-tpot-ansible
|
||||||
|
name: subnet-tpot-ansible
|
||||||
|
cidr: 192.168.0.0/24
|
||||||
|
dns_nameservers:
|
||||||
|
- 100.125.4.25
|
||||||
|
- 100.125.129.199
|
||||||
|
|
||||||
|
- name: Create router
|
||||||
|
openstack.cloud.router:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
name: router-tpot-ansible
|
||||||
|
interfaces:
|
||||||
|
- subnet-tpot-ansible
|
24
cloud/ansible/openstack/roles/create_vm/tasks/main.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
- name: Generate T-Pot name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
tpot_name: "t-pot-ansible-{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=6') }}"
|
||||||
|
|
||||||
|
- name: Create instance {{ ansible_loop.index }} of {{ ansible_loop.length }}
|
||||||
|
openstack.cloud.server:
|
||||||
|
cloud: "{{ cloud }}"
|
||||||
|
name: "{{ tpot_name }}"
|
||||||
|
availability_zone: "{{ availability_zone }}"
|
||||||
|
image: "{{ image }}"
|
||||||
|
boot_from_volume: yes
|
||||||
|
volume_size: "{{ volume_size }}"
|
||||||
|
key_name: "{{ key_name }}"
|
||||||
|
auto_ip: yes
|
||||||
|
flavor: "{{ flavor }}"
|
||||||
|
security_groups: sg-tpot-ansible
|
||||||
|
network: network-tpot-ansible
|
||||||
|
register: tpot
|
||||||
|
|
||||||
|
- name: Add instance to inventory
|
||||||
|
ansible.builtin.add_host:
|
||||||
|
hostname: "{{ tpot_name }}"
|
||||||
|
ansible_host: "{{ tpot.server.public_v4 }}"
|
||||||
|
groups: tpot
|
5
cloud/ansible/openstack/roles/create_vm/vars/main.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
availability_zone: eu-de-03
|
||||||
|
image: Standard_Debian_10_latest
|
||||||
|
volume_size: 128
|
||||||
|
key_name: your-KeyPair
|
||||||
|
flavor: s3.medium.8
|
13
cloud/ansible/openstack/roles/custom_ews/tasks/main.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
- name: Copy ews configuration file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ews.cfg
|
||||||
|
dest: /data/ews/conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Patching tpot.yml with custom ews configuration file
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /opt/tpot/etc/tpot.yml
|
||||||
|
insertafter: "/opt/ewsposter/ews.ip"
|
||||||
|
line: " - /data/ews/conf/ews.cfg:/opt/ewsposter/ews.cfg"
|
137
cloud/ansible/openstack/roles/custom_ews/templates/ews.cfg
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[MAIN]
|
||||||
|
homedir = /opt/ewsposter/
|
||||||
|
spooldir = /opt/ewsposter/spool/
|
||||||
|
logdir = /opt/ewsposter/log/
|
||||||
|
del_malware_after_send = false
|
||||||
|
send_malware = true
|
||||||
|
sendlimit = 500
|
||||||
|
contact = your_email_address
|
||||||
|
proxy =
|
||||||
|
ip =
|
||||||
|
|
||||||
|
[EWS]
|
||||||
|
ews = true
|
||||||
|
username = your_username
|
||||||
|
token = your_token
|
||||||
|
rhost_first = https://community.sicherheitstacho.eu/ews-0.1/alert/postSimpleMessage
|
||||||
|
rhost_second = https://community.sicherheitstacho.eu/ews-0.1/alert/postSimpleMessage
|
||||||
|
ignorecert = false
|
||||||
|
|
||||||
|
[HPFEED]
|
||||||
|
hpfeed = %(EWS_HPFEEDS_ENABLE)s
|
||||||
|
host = %(EWS_HPFEEDS_HOST)s
|
||||||
|
port = %(EWS_HPFEEDS_PORT)s
|
||||||
|
channels = %(EWS_HPFEEDS_CHANNELS)s
|
||||||
|
ident = %(EWS_HPFEEDS_IDENT)s
|
||||||
|
secret= %(EWS_HPFEEDS_SECRET)s
|
||||||
|
# path/to/certificate for tls broker - or "false" for non-tls broker
|
||||||
|
tlscert = %(EWS_HPFEEDS_TLSCERT)s
|
||||||
|
# hpfeeds submission format: "ews" (xml) or "json"
|
||||||
|
hpfformat = %(EWS_HPFEEDS_FORMAT)s
|
||||||
|
|
||||||
|
[EWSJSON]
|
||||||
|
json = false
|
||||||
|
jsondir = /data/ews/json/
|
||||||
|
|
||||||
|
[GLASTOPFV3]
|
||||||
|
glastopfv3 = true
|
||||||
|
nodeid = glastopfv3-{{ ansible_hostname }}
|
||||||
|
sqlitedb = /data/glastopf/db/glastopf.db
|
||||||
|
malwaredir = /data/glastopf/data/files/
|
||||||
|
|
||||||
|
[GLASTOPFV2]
|
||||||
|
glastopfv2 = false
|
||||||
|
nodeid =
|
||||||
|
mysqlhost =
|
||||||
|
mysqldb =
|
||||||
|
mysqluser =
|
||||||
|
mysqlpw =
|
||||||
|
malwaredir =
|
||||||
|
|
||||||
|
[KIPPO]
|
||||||
|
kippo = false
|
||||||
|
nodeid =
|
||||||
|
mysqlhost =
|
||||||
|
mysqldb =
|
||||||
|
mysqluser =
|
||||||
|
mysqlpw =
|
||||||
|
malwaredir =
|
||||||
|
|
||||||
|
[COWRIE]
|
||||||
|
cowrie = true
|
||||||
|
nodeid = cowrie-{{ ansible_hostname }}
|
||||||
|
logfile = /data/cowrie/log/cowrie.json
|
||||||
|
|
||||||
|
[DIONAEA]
|
||||||
|
dionaea = true
|
||||||
|
nodeid = dionaea-{{ ansible_hostname }}
|
||||||
|
malwaredir = /data/dionaea/binaries/
|
||||||
|
sqlitedb = /data/dionaea/log/dionaea.sqlite
|
||||||
|
|
||||||
|
[HONEYTRAP]
|
||||||
|
honeytrap = true
|
||||||
|
nodeid = honeytrap-{{ ansible_hostname }}
|
||||||
|
newversion = true
|
||||||
|
payloaddir = /data/honeytrap/attacks/
|
||||||
|
attackerfile = /data/honeytrap/log/attacker.log
|
||||||
|
|
||||||
|
[RDPDETECT]
|
||||||
|
rdpdetect = false
|
||||||
|
nodeid =
|
||||||
|
iptableslog =
|
||||||
|
targetip =
|
||||||
|
|
||||||
|
[EMOBILITY]
|
||||||
|
eMobility = false
|
||||||
|
nodeid = emobility-{{ ansible_hostname }}
|
||||||
|
logfile = /data/emobility/log/centralsystemEWS.log
|
||||||
|
|
||||||
|
[CONPOT]
|
||||||
|
conpot = true
|
||||||
|
nodeid = conpot-{{ ansible_hostname }}
|
||||||
|
logfile = /data/conpot/log/conpot*.json
|
||||||
|
|
||||||
|
[ELASTICPOT]
|
||||||
|
elasticpot = true
|
||||||
|
nodeid = elasticpot-{{ ansible_hostname }}
|
||||||
|
logfile = /data/elasticpot/log/elasticpot.log
|
||||||
|
|
||||||
|
[SURICATA]
|
||||||
|
suricata = true
|
||||||
|
nodeid = suricata-{{ ansible_hostname }}
|
||||||
|
logfile = /data/suricata/log/eve.json
|
||||||
|
|
||||||
|
[MAILONEY]
|
||||||
|
mailoney = true
|
||||||
|
nodeid = mailoney-{{ ansible_hostname }}
|
||||||
|
logfile = /data/mailoney/log/commands.log
|
||||||
|
|
||||||
|
[RDPY]
|
||||||
|
rdpy = true
|
||||||
|
nodeid = rdpy-{{ ansible_hostname }}
|
||||||
|
logfile = /data/rdpy/log/rdpy.log
|
||||||
|
|
||||||
|
[VNCLOWPOT]
|
||||||
|
vnclowpot = true
|
||||||
|
nodeid = vnclowpot-{{ ansible_hostname }}
|
||||||
|
logfile = /data/vnclowpot/log/vnclowpot.log
|
||||||
|
|
||||||
|
[HERALDING]
|
||||||
|
heralding = true
|
||||||
|
nodeid = heralding-{{ ansible_hostname }}
|
||||||
|
logfile = /data/heralding/log/auth.csv
|
||||||
|
|
||||||
|
[CISCOASA]
|
||||||
|
ciscoasa = true
|
||||||
|
nodeid = ciscoasa-{{ ansible_hostname }}
|
||||||
|
logfile = /data/ciscoasa/log/ciscoasa.log
|
||||||
|
|
||||||
|
[TANNER]
|
||||||
|
tanner = true
|
||||||
|
nodeid = tanner-{{ ansible_hostname }}
|
||||||
|
logfile = /data/tanner/log/tanner_report.json
|
||||||
|
|
||||||
|
[GLUTTON]
|
||||||
|
glutton = true
|
||||||
|
nodeid = glutton-{{ ansible_hostname }}
|
||||||
|
logfile = /data/glutton/log/glutton.log
|
@ -0,0 +1,8 @@
|
|||||||
|
myENABLE=false
|
||||||
|
myHOST=host
|
||||||
|
myPORT=port
|
||||||
|
myCHANNEL=channels
|
||||||
|
myCERT=false
|
||||||
|
myIDENT=user
|
||||||
|
mySECRET=secret
|
||||||
|
myFORMAT=json
|
12
cloud/ansible/openstack/roles/custom_hpfeeds/tasks/main.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
- name: Copy hpfeeds configuration file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: hpfeeds.cfg
|
||||||
|
dest: /data/ews/conf
|
||||||
|
owner: tpot
|
||||||
|
group: tpot
|
||||||
|
mode: 0770
|
||||||
|
register: config
|
||||||
|
|
||||||
|
- name: Applying hpfeeds settings
|
||||||
|
ansible.builtin.command: /opt/tpot/bin/hpfeeds_optin.sh --conf=/data/ews/conf/hpfeeds.cfg
|
||||||
|
when: config.changed == true
|
48
cloud/ansible/openstack/roles/install/tasks/main.yaml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
- name: Waiting for SSH connection
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
|
||||||
|
- name: Gathering facts
|
||||||
|
ansible.builtin.setup:
|
||||||
|
|
||||||
|
- name: Cloning T-Pot install directory
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "https://github.com/telekom-security/tpotce.git"
|
||||||
|
dest: /root/tpot
|
||||||
|
|
||||||
|
- name: Prepare to set user password
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
user_name: "{{ ansible_user }}"
|
||||||
|
user_salt: "s0mew1ck3dTpoT"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Changing password for user {{ user_name }}
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ ansible_user }}"
|
||||||
|
password: "{{ user_password | password_hash('sha512', user_salt) }}"
|
||||||
|
state: present
|
||||||
|
shell: /bin/bash
|
||||||
|
|
||||||
|
- name: Copy T-Pot configuration file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../../../../../../iso/installer/tpot.conf.dist
|
||||||
|
dest: /root/tpot.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Install T-Pot on instance - be patient, this might take 15 to 30 minutes depending on the connection speed.
|
||||||
|
ansible.builtin.command: /root/tpot/iso/installer/install.sh --type=auto --conf=/root/tpot.conf
|
||||||
|
|
||||||
|
- name: Delete T-Pot configuration file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /root/tpot.conf
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Change unattended-upgrades to take default action
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
dest: /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
block: |
|
||||||
|
Dpkg::Options {
|
||||||
|
"--force-confdef";
|
||||||
|
"--force-confold";
|
||||||
|
}
|
1
cloud/ansible/openstack/roles/install/vars/main.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
user_password: LiNuXuSeRPaSs#
|
16
cloud/ansible/openstack/roles/reboot/tasks/main.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
- name: Finally rebooting T-Pot
|
||||||
|
ansible.builtin.command: shutdown -r now
|
||||||
|
async: 1
|
||||||
|
poll: 0
|
||||||
|
|
||||||
|
- name: Next login options
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg:
|
||||||
|
- "***** SSH Access:"
|
||||||
|
- "***** ssh {{ ansible_user }}@{{ ansible_host }} -p 64295"
|
||||||
|
- ""
|
||||||
|
- "***** Web UI:"
|
||||||
|
- "***** https://{{ ansible_host }}:64297"
|
||||||
|
- ""
|
||||||
|
- "***** Admin UI:"
|
||||||
|
- "***** https://{{ ansible_host }}:64294"
|
129
cloud/terraform/README.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# T-Pot Terraform
|
||||||
|
This [Terraform](https://www.terraform.io/) configuration can be used to launch a virtual machine, bootstrap any dependencies and install T-Pot in a single step.
|
||||||
|
Configuration for Amazon Web Services (AWS) and Open Telekom Cloud (OTC) is currently included.
|
||||||
|
This can easily be extended to support other [Terraform providers](https://registry.terraform.io/browse/providers?category=public-cloud%2Ccloud-automation%2Cinfrastructure).
|
||||||
|
|
||||||
|
[Cloud-init](https://cloudinit.readthedocs.io/en/latest/) is used to bootstrap the instance and install T-Pot on startup.
|
||||||
|
|
||||||
|
# Table of Contents
|
||||||
|
- [What get's created](#what-created)
|
||||||
|
- [Amazon Web Services (AWS)](#what-created-aws)
|
||||||
|
- [Open Telekom Cloud (OTC)](#what-created-otc)
|
||||||
|
- [Prerequisites](#pre)
|
||||||
|
- [Amazon Web Services (AWS)](#pre-aws)
|
||||||
|
- [Open Telekom Cloud (OTC)](#pre-otc)
|
||||||
|
- [Terraform Variables](#variables)
|
||||||
|
- [Common configuration items](#variables-common)
|
||||||
|
- [Amazon Web Services (AWS)](#variables-aws)
|
||||||
|
- [Open Telekom Cloud (OTC)](#variables-otc)
|
||||||
|
- [Initialising](#initialising)
|
||||||
|
- [Applying the Configuration](#applying)
|
||||||
|
- [Connecting to the Instance](#connecting)
|
||||||
|
|
||||||
|
<a name="what-created"></a>
|
||||||
|
## What get's created
|
||||||
|
|
||||||
|
<a name="what-created-aws"></a>
|
||||||
|
### Amazon Web Services (AWS)
|
||||||
|
* EC2 instance:
|
||||||
|
* t3.large (2 vCPUs, 8 GB RAM)
|
||||||
|
* 128 GB disk
|
||||||
|
* Debian 10
|
||||||
|
* Public IP
|
||||||
|
* Security Group:
|
||||||
|
* TCP/UDP ports <= 64000 open to the Internet
|
||||||
|
* TCP ports 64294, 64295 and 64297 open to a chosen administrative IP
|
||||||
|
|
||||||
|
<a name="what-created-otc"></a>
|
||||||
|
### Open Telekom Cloud (OTC)
|
||||||
|
* ECS instance:
|
||||||
|
* s3.medium.8 (1 vCPU, 8 GB RAM)
|
||||||
|
* 128 GB disk
|
||||||
|
* Debian 10
|
||||||
|
* Public EIP
|
||||||
|
* Security Group
|
||||||
|
* All TCP/UDP ports are open to the Internet
|
||||||
|
* Virtual Private Cloud (VPC) and Subnet
|
||||||
|
|
||||||
|
<a name="pre"></a>
|
||||||
|
## Prerequisites
|
||||||
|
* [Terraform](https://www.terraform.io/) 0.13
|
||||||
|
|
||||||
|
<a name="pre-aws"></a>
|
||||||
|
### Amazon Web Services (AWS)
|
||||||
|
* AWS Account
|
||||||
|
* Existing VPC: VPC ID needs to be specified in `aws/variables.tf`
|
||||||
|
* Existing subnet: Subnet ID needs to be specified in `aws/variables.tf`
|
||||||
|
* Existing SSH key pair: Key name needs to be specified in `aws/variables.tf`
|
||||||
|
* AWS Authentication credentials should be [set using environment variables](https://www.terraform.io/docs/providers/aws/index.html#environment-variables)
|
||||||
|
|
||||||
|
<a name="pre-otc"></a>
|
||||||
|
### Open Telekom Cloud (OTC)
|
||||||
|
* OTC Account
|
||||||
|
* Existing SSH key pair: Key name needs to be specified in `otc/variables.tf`
|
||||||
|
* OTC Authentication credentials (Username, Password, Project Name, User Domain Name) can be set in the `otc/clouds.yaml` file
|
||||||
|
|
||||||
|
<a name="variables"></a>
|
||||||
|
## Terraform Variables
|
||||||
|
|
||||||
|
<a name="variables-common"></a>
|
||||||
|
### Common configuration items
|
||||||
|
These variables exist in `aws/variables.tf` and `otc/variables.tf` respectively.
|
||||||
|
Settings for cloud-init:
|
||||||
|
* `timezone` - Set the Server's timezone
|
||||||
|
* `linux_password`- Set a password for the Linux Operating System user (which is also used on the Admin UI)
|
||||||
|
|
||||||
|
Settings for T-Pot:
|
||||||
|
* `tpot_flavor` - Set the flavor of the T-Pot (Available flavors are listed in the variable's description)
|
||||||
|
* `web_user` - Set a username for the T-Pot Kibana Dasboard
|
||||||
|
* `web_password` - Set a password for the T-Pot Kibana Dashboard
|
||||||
|
|
||||||
|
<a name="variables-aws"></a>
|
||||||
|
### Amazon Web Services (AWS)
|
||||||
|
In `aws/variables.tf`, you can change the additional variables:
|
||||||
|
* `admin_ip` - source IP address(es) that you will use to administer the system. Connections to TCP ports 64294, 64295 and 64297 will be allowed from this IP only. Multiple IPs or CIDR blocks can be specified in the format: `["127.0.0.1/32", "192.168.0.0/24"]`
|
||||||
|
* `ec2_vpc_id` - Specify an existing VPC ID
|
||||||
|
* `ec2_subnet_id` - Specify an existing Subnet ID
|
||||||
|
* `ec2_region`
|
||||||
|
* `ec2_ssh_key_name` - Specify an existing SSH key pair
|
||||||
|
* `ec2_instance_type`
|
||||||
|
|
||||||
|
<a name="variables-otc"></a>
|
||||||
|
### Open Telekom Cloud (OTC)
|
||||||
|
In `otc/variables.tf`, you can change the additional variables:
|
||||||
|
* `ecs_flavor`
|
||||||
|
* `ecs_disk_size`
|
||||||
|
* `availability_zone`
|
||||||
|
* `key_pair` - Specify an existing SSH key pair
|
||||||
|
* `eip_size`
|
||||||
|
|
||||||
|
... and some more, but these are the most relevant.
|
||||||
|
|
||||||
|
<a name="initialising"></a>
|
||||||
|
## Initialising
|
||||||
|
The [`terraform init`](https://www.terraform.io/docs/commands/init.html) command is used to initialize a working directory containing Terraform configuration files.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd aws
|
||||||
|
$ terraform init
|
||||||
|
```
|
||||||
|
OR
|
||||||
|
```
|
||||||
|
$ cd otc
|
||||||
|
$ terraform init
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="applying"></a>
|
||||||
|
## Applying the Configuration
|
||||||
|
The [`terraform apply`](https://www.terraform.io/docs/commands/apply.html) command is used to apply the changes required to reach the desired state of the configuration, or the pre-determined set of actions generated by a [`terraform plan`](https://www.terraform.io/docs/commands/plan.html) execution plan.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform apply
|
||||||
|
```
|
||||||
|
This will create your infrastructure and start a Cloud Server. On startup, the Server gets bootstrapped with cloud-init and will install T-Pot. Once this is done, the server will reboot.
|
||||||
|
|
||||||
|
If you want the remove the built infrastructure, you can run [`terraform destroy`](https://www.terraform.io/docs/commands/destroy.html) to delete it.
|
||||||
|
|
||||||
|
<a name="connecting"></a>
|
||||||
|
## Connecting to the Instance
|
||||||
|
When the installation is completed, you can proceed with connecting/logging in to the T-Pot according to the [documentation](https://github.com/telekom-security/tpotce#ssh-and-web-access).
|
20
cloud/terraform/aws/.terraform.lock.hcl
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# This file is maintained automatically by "terraform init".
|
||||||
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.terraform.io/hashicorp/aws" {
|
||||||
|
version = "3.26.0"
|
||||||
|
constraints = "3.26.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:0i78FItlPeiomd+4ThZrtm56P5K33k7/6dnEe4ZePI0=",
|
||||||
|
"zh:26043eed36d070ca032cf04bc980c654a25821a8abc0c85e1e570e3935bbfcbb",
|
||||||
|
"zh:2fe68f3f78d23830a04d7fac3eda550eef1f627dfc130486f70a65dc5c254300",
|
||||||
|
"zh:3d66484c608c64678e639db25d63872783ce60363a1246e30317f21c9c23b84b",
|
||||||
|
"zh:46ffd755cfd4cf94fe66342797b5afdcef010a24e126c67fee141b357d393535",
|
||||||
|
"zh:5e96f24357e945c9067cf5e032ad1d003609629c956c2f9f642fefe714e74587",
|
||||||
|
"zh:60c27aca36bb63bf3e865c2193be80ca83b376581d00f9c220af4b013e163c4d",
|
||||||
|
"zh:896f0f22d19d41e71b22f9240b261714c3915b165ddefeb771e7734d69dc47ea",
|
||||||
|
"zh:90de9966cb2fd3e2f326df291595e55d2dd2d90e7d6dd085c2c8691dce82bdb4",
|
||||||
|
"zh:ad05a91a88ceb1d6de5a568f7cc0b0e5bc0a79f3da70bc28c1e7f3750e362d58",
|
||||||
|
"zh:e8c63f59c6465329e1f3357498face3dd7ef10a033df3c366a33aa9e94b46c01",
|
||||||
|
]
|
||||||
|
}
|
66
cloud/terraform/aws/main.tf
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
provider "aws" {
|
||||||
|
region = var.ec2_region
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "tpot" {
|
||||||
|
name = "T-Pot"
|
||||||
|
description = "T-Pot Honeypot"
|
||||||
|
vpc_id = var.ec2_vpc_id
|
||||||
|
ingress {
|
||||||
|
from_port = 0
|
||||||
|
to_port = 64000
|
||||||
|
protocol = "tcp"
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
}
|
||||||
|
ingress {
|
||||||
|
from_port = 0
|
||||||
|
to_port = 64000
|
||||||
|
protocol = "udp"
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
}
|
||||||
|
ingress {
|
||||||
|
from_port = 64294
|
||||||
|
to_port = 64294
|
||||||
|
protocol = "tcp"
|
||||||
|
cidr_blocks = var.admin_ip
|
||||||
|
}
|
||||||
|
ingress {
|
||||||
|
from_port = 64295
|
||||||
|
to_port = 64295
|
||||||
|
protocol = "tcp"
|
||||||
|
cidr_blocks = var.admin_ip
|
||||||
|
}
|
||||||
|
ingress {
|
||||||
|
from_port = 64297
|
||||||
|
to_port = 64297
|
||||||
|
protocol = "tcp"
|
||||||
|
cidr_blocks = var.admin_ip
|
||||||
|
}
|
||||||
|
egress {
|
||||||
|
from_port = 0
|
||||||
|
to_port = 0
|
||||||
|
protocol = "-1"
|
||||||
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
|
}
|
||||||
|
tags = {
|
||||||
|
Name = "T-Pot"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "tpot" {
|
||||||
|
ami = var.ec2_ami[var.ec2_region]
|
||||||
|
instance_type = var.ec2_instance_type
|
||||||
|
key_name = var.ec2_ssh_key_name
|
||||||
|
subnet_id = var.ec2_subnet_id
|
||||||
|
tags = {
|
||||||
|
Name = "T-Pot Honeypot"
|
||||||
|
}
|
||||||
|
root_block_device {
|
||||||
|
volume_type = "gp2"
|
||||||
|
volume_size = 128
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
|
user_data = templatefile("../cloud-init.yaml", { timezone = var.timezone, password = var.linux_password, tpot_flavor = var.tpot_flavor, web_user = var.web_user, web_password = var.web_password })
|
||||||
|
vpc_security_group_ids = [aws_security_group.tpot.id]
|
||||||
|
associate_public_ip_address = true
|
||||||
|
}
|
12
cloud/terraform/aws/outputs.tf
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
output "Admin_UI" {
|
||||||
|
value = "https://${aws_instance.tpot.public_dns}:64294/"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "SSH_Access" {
|
||||||
|
value = "ssh -i {private_key_file} -p 64295 admin@${aws_instance.tpot.public_dns}"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "Web_UI" {
|
||||||
|
value = "https://${aws_instance.tpot.public_dns}:64297/"
|
||||||
|
}
|
||||||
|
|
93
cloud/terraform/aws/variables.tf
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
variable "admin_ip" {
|
||||||
|
default = ["127.0.0.1/32"]
|
||||||
|
description = "admin IP addresses in CIDR format"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ec2_vpc_id" {
|
||||||
|
description = "ID of AWS VPC"
|
||||||
|
default = "vpc-XXX"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ec2_subnet_id" {
|
||||||
|
description = "ID of AWS VPC subnet"
|
||||||
|
default = "subnet-YYY"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ec2_region" {
|
||||||
|
description = "AWS region to launch servers"
|
||||||
|
default = "eu-west-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ec2_ssh_key_name" {
|
||||||
|
default = "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
# https://aws.amazon.com/ec2/instance-types/
|
||||||
|
# t3.large = 2 vCPU, 8 GiB RAM
|
||||||
|
variable "ec2_instance_type" {
|
||||||
|
default = "t3.large"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Refer to https://wiki.debian.org/Cloud/AmazonEC2Image/Buster
|
||||||
|
variable "ec2_ami" {
|
||||||
|
type = map(string)
|
||||||
|
default = {
|
||||||
|
"af-south-1" = "ami-0272d4f5fb1b98a0d"
|
||||||
|
"ap-east-1" = "ami-00d242e2f23abf6d2"
|
||||||
|
"ap-northeast-1" = "ami-001c6b4d627e8be53"
|
||||||
|
"ap-northeast-2" = "ami-0d841ed4bf80e764c"
|
||||||
|
"ap-northeast-3" = "ami-01b0a01d770321320"
|
||||||
|
"ap-south-1" = "ami-04ba7e5bd7c6f6929"
|
||||||
|
"ap-southeast-1" = "ami-0dca3eabb09c32ae2"
|
||||||
|
"ap-southeast-2" = "ami-03ff8684dc585ddae"
|
||||||
|
"ca-central-1" = "ami-08af22d7c0382fd83"
|
||||||
|
"eu-central-1" = "ami-0f41e297b3c53fab8"
|
||||||
|
"eu-north-1" = "ami-0bbc6a00971c77d6d"
|
||||||
|
"eu-south-1" = "ami-03ff8684dc585ddae"
|
||||||
|
"eu-west-1" = "ami-080684ad73d431a05"
|
||||||
|
"eu-west-2" = "ami-04b259723891dfc53"
|
||||||
|
"eu-west-3" = "ami-00662eead74f66895"
|
||||||
|
"me-south-1" = "ami-021a6c6047091ab5b"
|
||||||
|
"sa-east-1" = "ami-0aac091cce68a049c"
|
||||||
|
"us-east-1" = "ami-05ad4ed7f9c48178b"
|
||||||
|
"us-east-2" = "ami-07640f3f27c0ad3d3"
|
||||||
|
"us-west-1" = "ami-0c053f1d5f22eb09f"
|
||||||
|
"us-west-2" = "ami-090cd3aed687b1ee1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## cloud-init configuration ##
|
||||||
|
variable "timezone" {
|
||||||
|
default = "UTC"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "linux_password" {
|
||||||
|
#default = "LiNuXuSeRPaSs#"
|
||||||
|
description = "Set a password for the default user"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = length(var.linux_password) > 0
|
||||||
|
error_message = "Please specify a password for the default user."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## These will go in the generated tpot.conf file ##
|
||||||
|
variable "tpot_flavor" {
|
||||||
|
default = "STANDARD"
|
||||||
|
description = "Specify your tpot flavor [STANDARD, SENSOR, INDUSTRIAL, COLLECTOR, NEXTGEN, MEDICAL]"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "web_user" {
|
||||||
|
default = "webuser"
|
||||||
|
description = "Set a username for the web user"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "web_password" {
|
||||||
|
#default = "w3b$ecret"
|
||||||
|
description = "Set a password for the web user"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = length(var.web_password) > 0
|
||||||
|
error_message = "Please specify a password for the web user."
|
||||||
|
}
|
||||||
|
}
|
9
cloud/terraform/aws/versions.tf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 0.13"
|
||||||
|
required_providers {
|
||||||
|
aws = {
|
||||||
|
source = "hashicorp/aws"
|
||||||
|
version = "3.26.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
cloud/terraform/cloud-init.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#cloud-config
|
||||||
|
timezone: ${timezone}
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- git
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
- curl -sS --retry 5 https://github.com
|
||||||
|
- git clone https://github.com/telekom-security/tpotce /root/tpot
|
||||||
|
- /root/tpot/iso/installer/install.sh --type=auto --conf=/root/tpot.conf
|
||||||
|
- rm /root/tpot.conf
|
||||||
|
- /sbin/shutdown -r now
|
||||||
|
|
||||||
|
password: ${password}
|
||||||
|
chpasswd:
|
||||||
|
expire: false
|
||||||
|
|
||||||
|
write_files:
|
||||||
|
- content: |
|
||||||
|
# tpot configuration file
|
||||||
|
myCONF_TPOT_FLAVOR='${tpot_flavor}'
|
||||||
|
myCONF_WEB_USER='${web_user}'
|
||||||
|
myCONF_WEB_PW='${web_password}'
|
||||||
|
owner: root:root
|
||||||
|
path: /root/tpot.conf
|
||||||
|
permissions: '0600'
|
38
cloud/terraform/otc/.terraform.lock.hcl
generated
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# This file is maintained automatically by "terraform init".
|
||||||
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.terraform.io/hashicorp/random" {
|
||||||
|
version = "3.1.0"
|
||||||
|
constraints = "~> 3.1.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:BZMEPucF+pbu9gsPk0G0BHx7YP04+tKdq2MrRDF1EDM=",
|
||||||
|
"zh:2bbb3339f0643b5daa07480ef4397bd23a79963cc364cdfbb4e86354cb7725bc",
|
||||||
|
"zh:3cd456047805bf639fbf2c761b1848880ea703a054f76db51852008b11008626",
|
||||||
|
"zh:4f251b0eda5bb5e3dc26ea4400dba200018213654b69b4a5f96abee815b4f5ff",
|
||||||
|
"zh:7011332745ea061e517fe1319bd6c75054a314155cb2c1199a5b01fe1889a7e2",
|
||||||
|
"zh:738ed82858317ccc246691c8b85995bc125ac3b4143043219bd0437adc56c992",
|
||||||
|
"zh:7dbe52fac7bb21227acd7529b487511c91f4107db9cc4414f50d04ffc3cab427",
|
||||||
|
"zh:a3a9251fb15f93e4cfc1789800fc2d7414bbc18944ad4c5c98f466e6477c42bc",
|
||||||
|
"zh:a543ec1a3a8c20635cf374110bd2f87c07374cf2c50617eee2c669b3ceeeaa9f",
|
||||||
|
"zh:d9ab41d556a48bd7059f0810cf020500635bfc696c9fc3adab5ea8915c1d886b",
|
||||||
|
"zh:d9e13427a7d011dbd654e591b0337e6074eef8c3b9bb11b2e39eaaf257044fd7",
|
||||||
|
"zh:f7605bd1437752114baf601bdf6931debe6dc6bfe3006eb7e9bb9080931dca8a",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "registry.terraform.io/opentelekomcloud/opentelekomcloud" {
|
||||||
|
version = "1.23.6"
|
||||||
|
constraints = "~> 1.23.4"
|
||||||
|
hashes = [
|
||||||
|
"h1:B/1Md957jWaDgFqsJDzmJc75KwL0eC/PCVuZ8HV5xSc=",
|
||||||
|
"zh:1aa79010869d082157fb44fc83c3bff4e40938ec0ca916f704d974c7f7ca39e4",
|
||||||
|
"zh:3155b8366828ce50231f69962b55df1e2261ed63c44bb64e2c950dd68769df1b",
|
||||||
|
"zh:4a909617aa96a6d8aead14f56996ad94e0a1cae9d28e8df1ddae19c2095ed337",
|
||||||
|
"zh:4f71046719632b4b90f88d29d8ba88915ee6ad66cd9d7ebe84a7459013e5003a",
|
||||||
|
"zh:67e4d10b2db79ad78ae2ec8d9dfac53c4721028f97f4436a7aa45e80b1beefd3",
|
||||||
|
"zh:7f12541fc5a3513e5522ff2bd5fee17d1e67bfe64f9ef59d03863fc7389e12ce",
|
||||||
|
"zh:86fadabfc8307cf6084a412ffc9c797ec94932d08bc663a3fcebf98101e951f6",
|
||||||
|
"zh:98744b39c2bfe3e8e6f929f750a689971071b257f3f066f669f93c8e0b76d179",
|
||||||
|
"zh:c363d41debb060804e2c6bd9cb50b4e8daa37362299e3ea74e187265cd85f2ca",
|
||||||
|
]
|
||||||
|
}
|
9
cloud/terraform/otc/clouds.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
clouds:
|
||||||
|
open-telekom-cloud:
|
||||||
|
region_name: eu-de
|
||||||
|
auth:
|
||||||
|
project_name: eu-de_your_project
|
||||||
|
username: your_api_user
|
||||||
|
password: your_password
|
||||||
|
user_domain_name: OTC-EU-DE-000000000010000XXXXX
|
||||||
|
auth_url: https://iam.eu-de.otc.t-systems.com/v3
|
68
cloud/terraform/otc/main.tf
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
data "opentelekomcloud_images_image_v2" "debian" {
|
||||||
|
name = "Standard_Debian_10_latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_networking_secgroup_v2" "secgroup_1" {
|
||||||
|
name = var.secgroup_name
|
||||||
|
description = var.secgroup_desc
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_networking_secgroup_rule_v2" "secgroup_rule_1" {
|
||||||
|
direction = "ingress"
|
||||||
|
ethertype = "IPv4"
|
||||||
|
remote_ip_prefix = "0.0.0.0/0"
|
||||||
|
security_group_id = opentelekomcloud_networking_secgroup_v2.secgroup_1.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_vpc_v1" "vpc_1" {
|
||||||
|
name = var.vpc_name
|
||||||
|
cidr = var.vpc_cidr
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_vpc_subnet_v1" "subnet_1" {
|
||||||
|
name = var.subnet_name
|
||||||
|
cidr = var.subnet_cidr
|
||||||
|
vpc_id = opentelekomcloud_vpc_v1.vpc_1.id
|
||||||
|
|
||||||
|
gateway_ip = var.subnet_gateway_ip
|
||||||
|
dns_list = ["100.125.4.25", "100.125.129.199"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "random_id" "tpot" {
|
||||||
|
byte_length = 6
|
||||||
|
prefix = var.ecs_prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_ecs_instance_v1" "ecs_1" {
|
||||||
|
name = random_id.tpot.b64_url
|
||||||
|
image_id = data.opentelekomcloud_images_image_v2.debian.id
|
||||||
|
flavor = var.ecs_flavor
|
||||||
|
vpc_id = opentelekomcloud_vpc_v1.vpc_1.id
|
||||||
|
|
||||||
|
nics {
|
||||||
|
network_id = opentelekomcloud_vpc_subnet_v1.subnet_1.id
|
||||||
|
}
|
||||||
|
|
||||||
|
system_disk_size = var.ecs_disk_size
|
||||||
|
system_disk_type = "SAS"
|
||||||
|
security_groups = [opentelekomcloud_networking_secgroup_v2.secgroup_1.id]
|
||||||
|
availability_zone = var.availability_zone
|
||||||
|
key_name = var.key_pair
|
||||||
|
user_data = templatefile("../cloud-init.yaml", { timezone = var.timezone, password = var.linux_password, tpot_flavor = var.tpot_flavor, web_user = var.web_user, web_password = var.web_password })
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_vpc_eip_v1" "eip_1" {
|
||||||
|
publicip {
|
||||||
|
type = "5_bgp"
|
||||||
|
}
|
||||||
|
bandwidth {
|
||||||
|
name = "bandwidth-${random_id.tpot.b64_url}"
|
||||||
|
size = var.eip_size
|
||||||
|
share_type = "PER"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "opentelekomcloud_compute_floatingip_associate_v2" "fip_1" {
|
||||||
|
floating_ip = opentelekomcloud_vpc_eip_v1.eip_1.publicip.0.ip_address
|
||||||
|
instance_id = opentelekomcloud_ecs_instance_v1.ecs_1.id
|
||||||
|
}
|
11
cloud/terraform/otc/outputs.tf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
output "Admin_UI" {
|
||||||
|
value = "https://${opentelekomcloud_vpc_eip_v1.eip_1.publicip.0.ip_address}:64294"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "SSH_Access" {
|
||||||
|
value = "ssh -p 64295 linux@${opentelekomcloud_vpc_eip_v1.eip_1.publicip.0.ip_address}"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "Web_UI" {
|
||||||
|
value = "https://${opentelekomcloud_vpc_eip_v1.eip_1.publicip.0.ip_address}:64297"
|
||||||
|
}
|
3
cloud/terraform/otc/provider.tf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
provider "opentelekomcloud" {
|
||||||
|
cloud = "open-telekom-cloud"
|
||||||
|
}
|
98
cloud/terraform/otc/variables.tf
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
## cloud-init configuration ##
|
||||||
|
variable "timezone" {
|
||||||
|
default = "UTC"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "linux_password" {
|
||||||
|
#default = "LiNuXuSeRPaSs#"
|
||||||
|
description = "Set a password for the default user"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = length(var.linux_password) > 0
|
||||||
|
error_message = "Please specify a password for the default user."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Security Group ##
|
||||||
|
variable "secgroup_name" {
|
||||||
|
default = "sg-tpot"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "secgroup_desc" {
|
||||||
|
default = "Security Group for T-Pot"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Virtual Private Cloud ##
|
||||||
|
variable "vpc_name" {
|
||||||
|
default = "vpc-tpot"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vpc_cidr" {
|
||||||
|
default = "192.168.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Subnet ##
|
||||||
|
variable "subnet_name" {
|
||||||
|
default = "subnet-tpot"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subnet_cidr" {
|
||||||
|
default = "192.168.0.0/24"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subnet_gateway_ip" {
|
||||||
|
default = "192.168.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Elastic Cloud Server ##
|
||||||
|
variable "ecs_prefix" {
|
||||||
|
default = "tpot-"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ecs_flavor" {
|
||||||
|
default = "s3.medium.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ecs_disk_size" {
|
||||||
|
default = "128"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "availability_zone" {
|
||||||
|
default = "eu-de-03"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "key_pair" {
|
||||||
|
#default = ""
|
||||||
|
description = "Specify your SSH key pair"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = length(var.key_pair) > 0
|
||||||
|
error_message = "Please specify a Key Pair."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Elastic IP ##
|
||||||
|
variable "eip_size" {
|
||||||
|
default = "100"
|
||||||
|
}
|
||||||
|
|
||||||
|
## These will go in the generated tpot.conf file ##
|
||||||
|
variable "tpot_flavor" {
|
||||||
|
default = "STANDARD"
|
||||||
|
description = "Specify your tpot flavor [STANDARD, SENSOR, INDUSTRIAL, COLLECTOR, NEXTGEN, MEDICAL]"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "web_user" {
|
||||||
|
default = "webuser"
|
||||||
|
description = "Set a username for the web user"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "web_password" {
|
||||||
|
#default = "w3b$ecret"
|
||||||
|
description = "Set a password for the web user"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = length(var.web_password) > 0
|
||||||
|
error_message = "Please specify a password for the web user."
|
||||||
|
}
|
||||||
|
}
|
13
cloud/terraform/otc/versions.tf
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 0.13"
|
||||||
|
required_providers {
|
||||||
|
opentelekomcloud = {
|
||||||
|
source = "opentelekomcloud/opentelekomcloud"
|
||||||
|
version = "~> 1.23.4"
|
||||||
|
}
|
||||||
|
random = {
|
||||||
|
source = "hashicorp/random"
|
||||||
|
version = "~> 3.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
216
doc/Makefile
@ -1,216 +0,0 @@
|
|||||||
# Makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
PAPER =
|
|
||||||
BUILDDIR = build
|
|
||||||
|
|
||||||
# User-friendly check for sphinx-build
|
|
||||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
|
||||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
|
||||||
|
|
||||||
.PHONY: help
|
|
||||||
help:
|
|
||||||
@echo "Please use \`make <target>' where <target> is one of"
|
|
||||||
@echo " html to make standalone HTML files"
|
|
||||||
@echo " dirhtml to make HTML files named index.html in directories"
|
|
||||||
@echo " singlehtml to make a single large HTML file"
|
|
||||||
@echo " pickle to make pickle files"
|
|
||||||
@echo " json to make JSON files"
|
|
||||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
|
||||||
@echo " qthelp to make HTML files and a qthelp project"
|
|
||||||
@echo " applehelp to make an Apple Help Book"
|
|
||||||
@echo " devhelp to make HTML files and a Devhelp project"
|
|
||||||
@echo " epub to make an epub"
|
|
||||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
|
||||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
|
||||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
|
||||||
@echo " text to make text files"
|
|
||||||
@echo " man to make manual pages"
|
|
||||||
@echo " texinfo to make Texinfo files"
|
|
||||||
@echo " info to make Texinfo files and run them through makeinfo"
|
|
||||||
@echo " gettext to make PO message catalogs"
|
|
||||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
|
||||||
@echo " xml to make Docutils-native XML files"
|
|
||||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
|
||||||
@echo " linkcheck to check all external links for integrity"
|
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -rf $(BUILDDIR)/*
|
|
||||||
|
|
||||||
.PHONY: html
|
|
||||||
html:
|
|
||||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
|
||||||
|
|
||||||
.PHONY: dirhtml
|
|
||||||
dirhtml:
|
|
||||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
|
||||||
|
|
||||||
.PHONY: singlehtml
|
|
||||||
singlehtml:
|
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
|
||||||
|
|
||||||
.PHONY: pickle
|
|
||||||
pickle:
|
|
||||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the pickle files."
|
|
||||||
|
|
||||||
.PHONY: json
|
|
||||||
json:
|
|
||||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can process the JSON files."
|
|
||||||
|
|
||||||
.PHONY: htmlhelp
|
|
||||||
htmlhelp:
|
|
||||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
|
||||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
|
||||||
|
|
||||||
.PHONY: qthelp
|
|
||||||
qthelp:
|
|
||||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
|
||||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
|
||||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/T-Pot.qhcp"
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/T-Pot.qhc"
|
|
||||||
|
|
||||||
.PHONY: applehelp
|
|
||||||
applehelp:
|
|
||||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
|
||||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
|
||||||
"~/Library/Documentation/Help or install it in your application" \
|
|
||||||
"bundle."
|
|
||||||
|
|
||||||
.PHONY: devhelp
|
|
||||||
devhelp:
|
|
||||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
|
||||||
@echo
|
|
||||||
@echo "Build finished."
|
|
||||||
@echo "To view the help file:"
|
|
||||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/T-Pot"
|
|
||||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/T-Pot"
|
|
||||||
@echo "# devhelp"
|
|
||||||
|
|
||||||
.PHONY: epub
|
|
||||||
epub:
|
|
||||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
|
||||||
|
|
||||||
.PHONY: latex
|
|
||||||
latex:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo
|
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
|
||||||
|
|
||||||
.PHONY: latexpdf
|
|
||||||
latexpdf:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
.PHONY: latexpdfja
|
|
||||||
latexpdfja:
|
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
|
||||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
|
||||||
|
|
||||||
.PHONY: text
|
|
||||||
text:
|
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
|
||||||
|
|
||||||
.PHONY: man
|
|
||||||
man:
|
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
|
||||||
|
|
||||||
.PHONY: texinfo
|
|
||||||
texinfo:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
|
||||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
|
||||||
"(use \`make info' here to do that automatically)."
|
|
||||||
|
|
||||||
.PHONY: info
|
|
||||||
info:
|
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
|
||||||
@echo "Running Texinfo files through makeinfo..."
|
|
||||||
make -C $(BUILDDIR)/texinfo info
|
|
||||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
|
||||||
|
|
||||||
.PHONY: gettext
|
|
||||||
gettext:
|
|
||||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
|
||||||
|
|
||||||
.PHONY: changes
|
|
||||||
changes:
|
|
||||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
|
||||||
@echo
|
|
||||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
|
||||||
|
|
||||||
.PHONY: linkcheck
|
|
||||||
linkcheck:
|
|
||||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
|
||||||
@echo
|
|
||||||
@echo "Link check complete; look for any errors in the above output " \
|
|
||||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
|
||||||
|
|
||||||
.PHONY: doctest
|
|
||||||
doctest:
|
|
||||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
|
||||||
@echo "Testing of doctests in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/doctest/output.txt."
|
|
||||||
|
|
||||||
.PHONY: coverage
|
|
||||||
coverage:
|
|
||||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
|
||||||
@echo "Testing of coverage in the sources finished, look at the " \
|
|
||||||
"results in $(BUILDDIR)/coverage/python.txt."
|
|
||||||
|
|
||||||
.PHONY: xml
|
|
||||||
xml:
|
|
||||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
|
||||||
|
|
||||||
.PHONY: pseudoxml
|
|
||||||
pseudoxml:
|
|
||||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
|
||||||
@echo
|
|
||||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 311 KiB |
BIN
doc/build/doctrees/environment.pickle
vendored
BIN
doc/build/doctrees/index.doctree
vendored
4
doc/build/html/.buildinfo
vendored
@ -1,4 +0,0 @@
|
|||||||
# Sphinx build info version 1
|
|
||||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
|
||||||
config: fae7c9d3df0173e81358661e32fdb8fe
|
|
||||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
|
22
doc/build/html/_sources/index.txt
vendored
@ -1,22 +0,0 @@
|
|||||||
.. T-Pot documentation master file, created by
|
|
||||||
sphinx-quickstart on Mon Aug 8 13:24:39 2016.
|
|
||||||
You can adapt this file completely to your liking, but it should at least
|
|
||||||
contain the root `toctree` directive.
|
|
||||||
|
|
||||||
Welcome to T-Pot's documentation!
|
|
||||||
=================================
|
|
||||||
|
|
||||||
Contents:
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
||||||
|
|
BIN
doc/build/html/_static/ajax-loader.gif
vendored
Before Width: | Height: | Size: 673 B |
599
doc/build/html/_static/basic.css
vendored
@ -1,599 +0,0 @@
|
|||||||
/*
|
|
||||||
* basic.css
|
|
||||||
* ~~~~~~~~~
|
|
||||||
*
|
|
||||||
* Sphinx stylesheet -- basic theme.
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
||||||
* :license: BSD, see LICENSE for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* -- main layout ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.clearer {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- relbar ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.related {
|
|
||||||
width: 100%;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related h3 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related ul {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 0 0 10px;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related li {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related li.right {
|
|
||||||
float: right;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- sidebar --------------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.sphinxsidebarwrapper {
|
|
||||||
padding: 10px 5px 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar {
|
|
||||||
float: left;
|
|
||||||
width: 230px;
|
|
||||||
margin-left: -100%;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar ul {
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar ul ul,
|
|
||||||
div.sphinxsidebar ul.want-points {
|
|
||||||
margin-left: 20px;
|
|
||||||
list-style: square;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar ul ul {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar form {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar input {
|
|
||||||
border: 1px solid #98dbcc;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar #searchbox input[type="text"] {
|
|
||||||
width: 170px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar #searchbox input[type="submit"] {
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: 0;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- search page ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
ul.search {
|
|
||||||
margin: 10px 0 0 20px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.search li {
|
|
||||||
padding: 5px 0 5px 20px;
|
|
||||||
background-image: url(file.png);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.search li a {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.search li div.context {
|
|
||||||
color: #888;
|
|
||||||
margin: 2px 0 0 30px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.keywordmatches li.goodmatch a {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- index page ------------------------------------------------------------ */
|
|
||||||
|
|
||||||
table.contentstable {
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.contentstable p.biglink {
|
|
||||||
line-height: 150%;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.biglink {
|
|
||||||
font-size: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.linkdescr {
|
|
||||||
font-style: italic;
|
|
||||||
padding-top: 5px;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- general index --------------------------------------------------------- */
|
|
||||||
|
|
||||||
table.indextable {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.indextable td {
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.indextable dl, table.indextable dd {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.indextable tr.pcap {
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.indextable tr.cap {
|
|
||||||
margin-top: 10px;
|
|
||||||
background-color: #f2f2f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.toggler {
|
|
||||||
margin-right: 3px;
|
|
||||||
margin-top: 3px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.modindex-jumpbox {
|
|
||||||
border-top: 1px solid #ddd;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
margin: 1em 0 1em 0;
|
|
||||||
padding: 0.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.genindex-jumpbox {
|
|
||||||
border-top: 1px solid #ddd;
|
|
||||||
border-bottom: 1px solid #ddd;
|
|
||||||
margin: 1em 0 1em 0;
|
|
||||||
padding: 0.4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- general body styles --------------------------------------------------- */
|
|
||||||
|
|
||||||
a.headerlink {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1:hover > a.headerlink,
|
|
||||||
h2:hover > a.headerlink,
|
|
||||||
h3:hover > a.headerlink,
|
|
||||||
h4:hover > a.headerlink,
|
|
||||||
h5:hover > a.headerlink,
|
|
||||||
h6:hover > a.headerlink,
|
|
||||||
dt:hover > a.headerlink,
|
|
||||||
caption:hover > a.headerlink,
|
|
||||||
p.caption:hover > a.headerlink,
|
|
||||||
div.code-block-caption:hover > a.headerlink {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body p.caption {
|
|
||||||
text-align: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body td {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-list ul {
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.first {
|
|
||||||
margin-top: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.rubric {
|
|
||||||
margin-top: 30px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.align-left, .figure.align-left, object.align-left {
|
|
||||||
clear: left;
|
|
||||||
float: left;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.align-right, .figure.align-right, object.align-right {
|
|
||||||
clear: right;
|
|
||||||
float: right;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.align-center, .figure.align-center, object.align-center {
|
|
||||||
display: block;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- sidebars -------------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.sidebar {
|
|
||||||
margin: 0 0 0.5em 1em;
|
|
||||||
border: 1px solid #ddb;
|
|
||||||
padding: 7px 7px 0 7px;
|
|
||||||
background-color: #ffe;
|
|
||||||
width: 40%;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.sidebar-title {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- topics ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.topic {
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: 7px 7px 0 7px;
|
|
||||||
margin: 10px 0 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.topic-title {
|
|
||||||
font-size: 1.1em;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- admonitions ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.admonition {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition dt {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition dl {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title {
|
|
||||||
margin: 0px 10px 5px 0px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body p.centered {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- tables ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
table.docutils {
|
|
||||||
border: 0;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
table caption span.caption-number {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
table caption span.caption-text {
|
|
||||||
}
|
|
||||||
|
|
||||||
table.docutils td, table.docutils th {
|
|
||||||
padding: 1px 8px 1px 5px;
|
|
||||||
border-top: 0;
|
|
||||||
border-left: 0;
|
|
||||||
border-right: 0;
|
|
||||||
border-bottom: 1px solid #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.field-list td, table.field-list th {
|
|
||||||
border: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.footnote td, table.footnote th {
|
|
||||||
border: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.citation {
|
|
||||||
border-left: solid 1px gray;
|
|
||||||
margin-left: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.citation td {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- figures --------------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.figure {
|
|
||||||
margin: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.figure p.caption {
|
|
||||||
padding: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.figure p.caption span.caption-number {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.figure p.caption span.caption-text {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -- other body styles ----------------------------------------------------- */
|
|
||||||
|
|
||||||
ol.arabic {
|
|
||||||
list-style: decimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol.loweralpha {
|
|
||||||
list-style: lower-alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol.upperalpha {
|
|
||||||
list-style: upper-alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol.lowerroman {
|
|
||||||
list-style: lower-roman;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol.upperroman {
|
|
||||||
list-style: upper-roman;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd p {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd ul, dd table {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-top: 3px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt:target, .highlighted {
|
|
||||||
background-color: #fbe54e;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl.glossary dt {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-list ul {
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-list p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.optional {
|
|
||||||
font-size: 1.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sig-paren {
|
|
||||||
font-size: larger;
|
|
||||||
}
|
|
||||||
|
|
||||||
.versionmodified {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.system-message {
|
|
||||||
background-color: #fda;
|
|
||||||
padding: 5px;
|
|
||||||
border: 3px solid red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote:target {
|
|
||||||
background-color: #ffa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-block {
|
|
||||||
display: block;
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-block .line-block {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-left: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.guilabel, .menuselection {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.accelerator {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.classifier {
|
|
||||||
font-style: oblique;
|
|
||||||
}
|
|
||||||
|
|
||||||
abbr, acronym {
|
|
||||||
border-bottom: dotted 1px;
|
|
||||||
cursor: help;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- code displays --------------------------------------------------------- */
|
|
||||||
|
|
||||||
pre {
|
|
||||||
overflow: auto;
|
|
||||||
overflow-y: hidden; /* fixes display issues on Chrome browsers */
|
|
||||||
}
|
|
||||||
|
|
||||||
td.linenos pre {
|
|
||||||
padding: 5px 0px;
|
|
||||||
border: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.highlighttable {
|
|
||||||
margin-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.highlighttable td {
|
|
||||||
padding: 0 0.5em 0 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.code-block-caption {
|
|
||||||
padding: 2px 5px;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.code-block-caption code {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.code-block-caption + div > div.highlight > pre {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.code-block-caption span.caption-number {
|
|
||||||
padding: 0.1em 0.3em;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.code-block-caption span.caption-text {
|
|
||||||
}
|
|
||||||
|
|
||||||
div.literal-block-wrapper {
|
|
||||||
padding: 1em 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.literal-block-wrapper div.highlight {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
code.descname {
|
|
||||||
background-color: transparent;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
code.descclassname {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
code.xref, a code {
|
|
||||||
background-color: transparent;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewcode-link {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewcode-back {
|
|
||||||
float: right;
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.viewcode-block:target {
|
|
||||||
margin: -1px -10px;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- math display ---------------------------------------------------------- */
|
|
||||||
|
|
||||||
img.math {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body div.math p {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.eqno {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- printout stylesheet --------------------------------------------------- */
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
div.document,
|
|
||||||
div.documentwrapper,
|
|
||||||
div.bodywrapper {
|
|
||||||
margin: 0 !important;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar,
|
|
||||||
div.related,
|
|
||||||
div.footer,
|
|
||||||
#top-link {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
261
doc/build/html/_static/classic.css
vendored
@ -1,261 +0,0 @@
|
|||||||
/*
|
|
||||||
* default.css_t
|
|
||||||
* ~~~~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* Sphinx stylesheet -- default theme.
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
||||||
* :license: BSD, see LICENSE for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@import url("basic.css");
|
|
||||||
|
|
||||||
/* -- page layout ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 100%;
|
|
||||||
background-color: #11303d;
|
|
||||||
color: #000;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.document {
|
|
||||||
background-color: #1c4e63;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.documentwrapper {
|
|
||||||
float: left;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bodywrapper {
|
|
||||||
margin: 0 0 0 230px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body {
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #000000;
|
|
||||||
padding: 0 20px 30px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer {
|
|
||||||
color: #ffffff;
|
|
||||||
width: 100%;
|
|
||||||
padding: 9px 0 9px 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer a {
|
|
||||||
color: #ffffff;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related {
|
|
||||||
background-color: #133f52;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.related a {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar {
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h3 {
|
|
||||||
font-family: 'Trebuchet MS', sans-serif;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 1.4em;
|
|
||||||
font-weight: normal;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h3 a {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar h4 {
|
|
||||||
font-family: 'Trebuchet MS', sans-serif;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 1.3em;
|
|
||||||
font-weight: normal;
|
|
||||||
margin: 5px 0 0 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar p {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar p.topless {
|
|
||||||
margin: 5px 10px 10px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar ul {
|
|
||||||
margin: 10px;
|
|
||||||
padding: 0;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar a {
|
|
||||||
color: #98dbcc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.sphinxsidebar input {
|
|
||||||
border: 1px solid #98dbcc;
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -- hyperlink styles ------------------------------------------------------ */
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #355f7c;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:visited {
|
|
||||||
color: #355f7c;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -- body styles ----------------------------------------------------------- */
|
|
||||||
|
|
||||||
div.body h1,
|
|
||||||
div.body h2,
|
|
||||||
div.body h3,
|
|
||||||
div.body h4,
|
|
||||||
div.body h5,
|
|
||||||
div.body h6 {
|
|
||||||
font-family: 'Trebuchet MS', sans-serif;
|
|
||||||
background-color: #f2f2f2;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #20435c;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
margin: 20px -20px 10px -20px;
|
|
||||||
padding: 3px 0 3px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body h1 { margin-top: 0; font-size: 200%; }
|
|
||||||
div.body h2 { font-size: 160%; }
|
|
||||||
div.body h3 { font-size: 140%; }
|
|
||||||
div.body h4 { font-size: 120%; }
|
|
||||||
div.body h5 { font-size: 110%; }
|
|
||||||
div.body h6 { font-size: 100%; }
|
|
||||||
|
|
||||||
a.headerlink {
|
|
||||||
color: #c60f0f;
|
|
||||||
font-size: 0.8em;
|
|
||||||
padding: 0 4px 0 4px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.headerlink:hover {
|
|
||||||
background-color: #c60f0f;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.body p, div.body dd, div.body li, div.body blockquote {
|
|
||||||
text-align: justify;
|
|
||||||
line-height: 130%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition p.admonition-title + p {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition p {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition pre {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.admonition ul, div.admonition ol {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note {
|
|
||||||
background-color: #eee;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.seealso {
|
|
||||||
background-color: #ffc;
|
|
||||||
border: 1px solid #ff6;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.topic {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.warning {
|
|
||||||
background-color: #ffe4e4;
|
|
||||||
border: 1px solid #f66;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.admonition-title:after {
|
|
||||||
content: ":";
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #eeffcc;
|
|
||||||
color: #333333;
|
|
||||||
line-height: 120%;
|
|
||||||
border: 1px solid #ac9;
|
|
||||||
border-left: none;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
background-color: #ecf0f3;
|
|
||||||
padding: 0 1px 0 1px;
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background-color: #ede;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning code {
|
|
||||||
background: #efc2c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.note code {
|
|
||||||
background: #d6d6d6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewcode-back {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.viewcode-block:target {
|
|
||||||
background-color: #f4debf;
|
|
||||||
border-top: 1px solid #ac9;
|
|
||||||
border-bottom: 1px solid #ac9;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.code-block-caption {
|
|
||||||
color: #efefef;
|
|
||||||
background-color: #1c4e63;
|
|
||||||
}
|
|
BIN
doc/build/html/_static/comment-bright.png
vendored
Before Width: | Height: | Size: 3.4 KiB |
BIN
doc/build/html/_static/comment-close.png
vendored
Before Width: | Height: | Size: 3.5 KiB |
BIN
doc/build/html/_static/comment.png
vendored
Before Width: | Height: | Size: 3.4 KiB |
1
doc/build/html/_static/default.css
vendored
@ -1 +0,0 @@
|
|||||||
@import url("classic.css");
|
|
263
doc/build/html/_static/doctools.js
vendored
@ -1,263 +0,0 @@
|
|||||||
/*
|
|
||||||
* doctools.js
|
|
||||||
* ~~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* Sphinx JavaScript utilities for all documentation.
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
||||||
* :license: BSD, see LICENSE for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* select a different prefix for underscore
|
|
||||||
*/
|
|
||||||
$u = _.noConflict();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* make the code below compatible with browsers without
|
|
||||||
* an installed firebug like debugger
|
|
||||||
if (!window.console || !console.firebug) {
|
|
||||||
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
|
|
||||||
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
|
|
||||||
"profile", "profileEnd"];
|
|
||||||
window.console = {};
|
|
||||||
for (var i = 0; i < names.length; ++i)
|
|
||||||
window.console[names[i]] = function() {};
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* small helper function to urldecode strings
|
|
||||||
*/
|
|
||||||
jQuery.urldecode = function(x) {
|
|
||||||
return decodeURIComponent(x).replace(/\+/g, ' ');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* small helper function to urlencode strings
|
|
||||||
*/
|
|
||||||
jQuery.urlencode = encodeURIComponent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function returns the parsed url parameters of the
|
|
||||||
* current request. Multiple values per key are supported,
|
|
||||||
* it will always return arrays of strings for the value parts.
|
|
||||||
*/
|
|
||||||
jQuery.getQueryParameters = function(s) {
|
|
||||||
if (typeof s == 'undefined')
|
|
||||||
s = document.location.search;
|
|
||||||
var parts = s.substr(s.indexOf('?') + 1).split('&');
|
|
||||||
var result = {};
|
|
||||||
for (var i = 0; i < parts.length; i++) {
|
|
||||||
var tmp = parts[i].split('=', 2);
|
|
||||||
var key = jQuery.urldecode(tmp[0]);
|
|
||||||
var value = jQuery.urldecode(tmp[1]);
|
|
||||||
if (key in result)
|
|
||||||
result[key].push(value);
|
|
||||||
else
|
|
||||||
result[key] = [value];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* highlight a given string on a jquery object by wrapping it in
|
|
||||||
* span elements with the given class name.
|
|
||||||
*/
|
|
||||||
jQuery.fn.highlightText = function(text, className) {
|
|
||||||
function highlight(node) {
|
|
||||||
if (node.nodeType == 3) {
|
|
||||||
var val = node.nodeValue;
|
|
||||||
var pos = val.toLowerCase().indexOf(text);
|
|
||||||
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
|
|
||||||
var span = document.createElement("span");
|
|
||||||
span.className = className;
|
|
||||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
|
||||||
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
|
|
||||||
document.createTextNode(val.substr(pos + text.length)),
|
|
||||||
node.nextSibling));
|
|
||||||
node.nodeValue = val.substr(0, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!jQuery(node).is("button, select, textarea")) {
|
|
||||||
jQuery.each(node.childNodes, function() {
|
|
||||||
highlight(this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.each(function() {
|
|
||||||
highlight(this);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* backward compatibility for jQuery.browser
|
|
||||||
* This will be supported until firefox bug is fixed.
|
|
||||||
*/
|
|
||||||
if (!jQuery.browser) {
|
|
||||||
jQuery.uaMatch = function(ua) {
|
|
||||||
ua = ua.toLowerCase();
|
|
||||||
|
|
||||||
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
|
|
||||||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
|
|
||||||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
|
|
||||||
/(msie) ([\w.]+)/.exec(ua) ||
|
|
||||||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
|
||||||
[];
|
|
||||||
|
|
||||||
return {
|
|
||||||
browser: match[ 1 ] || "",
|
|
||||||
version: match[ 2 ] || "0"
|
|
||||||
};
|
|
||||||
};
|
|
||||||
jQuery.browser = {};
|
|
||||||
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Small JavaScript module for the documentation.
|
|
||||||
*/
|
|
||||||
var Documentation = {
|
|
||||||
|
|
||||||
init : function() {
|
|
||||||
this.fixFirefoxAnchorBug();
|
|
||||||
this.highlightSearchWords();
|
|
||||||
this.initIndexTable();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* i18n support
|
|
||||||
*/
|
|
||||||
TRANSLATIONS : {},
|
|
||||||
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
|
|
||||||
LOCALE : 'unknown',
|
|
||||||
|
|
||||||
// gettext and ngettext don't access this so that the functions
|
|
||||||
// can safely bound to a different name (_ = Documentation.gettext)
|
|
||||||
gettext : function(string) {
|
|
||||||
var translated = Documentation.TRANSLATIONS[string];
|
|
||||||
if (typeof translated == 'undefined')
|
|
||||||
return string;
|
|
||||||
return (typeof translated == 'string') ? translated : translated[0];
|
|
||||||
},
|
|
||||||
|
|
||||||
ngettext : function(singular, plural, n) {
|
|
||||||
var translated = Documentation.TRANSLATIONS[singular];
|
|
||||||
if (typeof translated == 'undefined')
|
|
||||||
return (n == 1) ? singular : plural;
|
|
||||||
return translated[Documentation.PLURALEXPR(n)];
|
|
||||||
},
|
|
||||||
|
|
||||||
addTranslations : function(catalog) {
|
|
||||||
for (var key in catalog.messages)
|
|
||||||
this.TRANSLATIONS[key] = catalog.messages[key];
|
|
||||||
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
|
|
||||||
this.LOCALE = catalog.locale;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* add context elements like header anchor links
|
|
||||||
*/
|
|
||||||
addContextElements : function() {
|
|
||||||
$('div[id] > :header:first').each(function() {
|
|
||||||
$('<a class="headerlink">\u00B6</a>').
|
|
||||||
attr('href', '#' + this.id).
|
|
||||||
attr('title', _('Permalink to this headline')).
|
|
||||||
appendTo(this);
|
|
||||||
});
|
|
||||||
$('dt[id]').each(function() {
|
|
||||||
$('<a class="headerlink">\u00B6</a>').
|
|
||||||
attr('href', '#' + this.id).
|
|
||||||
attr('title', _('Permalink to this definition')).
|
|
||||||
appendTo(this);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* workaround a firefox stupidity
|
|
||||||
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
|
|
||||||
*/
|
|
||||||
fixFirefoxAnchorBug : function() {
|
|
||||||
if (document.location.hash)
|
|
||||||
window.setTimeout(function() {
|
|
||||||
document.location.href += '';
|
|
||||||
}, 10);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* highlight the search words provided in the url in the text
|
|
||||||
*/
|
|
||||||
highlightSearchWords : function() {
|
|
||||||
var params = $.getQueryParameters();
|
|
||||||
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
|
|
||||||
if (terms.length) {
|
|
||||||
var body = $('div.body');
|
|
||||||
if (!body.length) {
|
|
||||||
body = $('body');
|
|
||||||
}
|
|
||||||
window.setTimeout(function() {
|
|
||||||
$.each(terms, function() {
|
|
||||||
body.highlightText(this.toLowerCase(), 'highlighted');
|
|
||||||
});
|
|
||||||
}, 10);
|
|
||||||
$('<p class="highlight-link"><a href="javascript:Documentation.' +
|
|
||||||
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
|
|
||||||
.appendTo($('#searchbox'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* init the domain index toggle buttons
|
|
||||||
*/
|
|
||||||
initIndexTable : function() {
|
|
||||||
var togglers = $('img.toggler').click(function() {
|
|
||||||
var src = $(this).attr('src');
|
|
||||||
var idnum = $(this).attr('id').substr(7);
|
|
||||||
$('tr.cg-' + idnum).toggle();
|
|
||||||
if (src.substr(-9) == 'minus.png')
|
|
||||||
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
|
|
||||||
else
|
|
||||||
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
|
|
||||||
}).css('display', '');
|
|
||||||
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
|
|
||||||
togglers.click();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* helper function to hide the search marks again
|
|
||||||
*/
|
|
||||||
hideSearchWords : function() {
|
|
||||||
$('#searchbox .highlight-link').fadeOut(300);
|
|
||||||
$('span.highlighted').removeClass('highlighted');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* make the url absolute
|
|
||||||
*/
|
|
||||||
makeURL : function(relativeURL) {
|
|
||||||
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the current relative url
|
|
||||||
*/
|
|
||||||
getCurrentURL : function() {
|
|
||||||
var path = document.location.pathname;
|
|
||||||
var parts = path.split(/\//);
|
|
||||||
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
|
|
||||||
if (this == '..')
|
|
||||||
parts.pop();
|
|
||||||
});
|
|
||||||
var url = parts.join('/');
|
|
||||||
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// quick alias for translations
|
|
||||||
_ = Documentation.gettext;
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
Documentation.init();
|
|
||||||
});
|
|
BIN
doc/build/html/_static/down-pressed.png
vendored
Before Width: | Height: | Size: 347 B |
BIN
doc/build/html/_static/down.png
vendored
Before Width: | Height: | Size: 347 B |
BIN
doc/build/html/_static/file.png
vendored
Before Width: | Height: | Size: 358 B |
10351
doc/build/html/_static/jquery.js
vendored
BIN
doc/build/html/_static/minus.png
vendored
Before Width: | Height: | Size: 173 B |
BIN
doc/build/html/_static/plus.png
vendored
Before Width: | Height: | Size: 173 B |
65
doc/build/html/_static/pygments.css
vendored
@ -1,65 +0,0 @@
|
|||||||
.highlight .hll { background-color: #ffffcc }
|
|
||||||
.highlight { background: #eeffcc; }
|
|
||||||
.highlight .c { color: #408090; font-style: italic } /* Comment */
|
|
||||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
|
||||||
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
|
|
||||||
.highlight .o { color: #666666 } /* Operator */
|
|
||||||
.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
|
|
||||||
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
|
|
||||||
.highlight .cp { color: #007020 } /* Comment.Preproc */
|
|
||||||
.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
|
|
||||||
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
|
|
||||||
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
|
|
||||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
|
||||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
|
||||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
|
||||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
|
||||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
|
||||||
.highlight .go { color: #333333 } /* Generic.Output */
|
|
||||||
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
|
|
||||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
|
||||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
|
||||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
|
||||||
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
|
|
||||||
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
|
|
||||||
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
|
|
||||||
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
|
|
||||||
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
|
|
||||||
.highlight .kt { color: #902000 } /* Keyword.Type */
|
|
||||||
.highlight .m { color: #208050 } /* Literal.Number */
|
|
||||||
.highlight .s { color: #4070a0 } /* Literal.String */
|
|
||||||
.highlight .na { color: #4070a0 } /* Name.Attribute */
|
|
||||||
.highlight .nb { color: #007020 } /* Name.Builtin */
|
|
||||||
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
|
|
||||||
.highlight .no { color: #60add5 } /* Name.Constant */
|
|
||||||
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
|
|
||||||
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
|
|
||||||
.highlight .ne { color: #007020 } /* Name.Exception */
|
|
||||||
.highlight .nf { color: #06287e } /* Name.Function */
|
|
||||||
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
|
|
||||||
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
|
|
||||||
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
|
|
||||||
.highlight .nv { color: #bb60d5 } /* Name.Variable */
|
|
||||||
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
|
|
||||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
|
||||||
.highlight .mb { color: #208050 } /* Literal.Number.Bin */
|
|
||||||
.highlight .mf { color: #208050 } /* Literal.Number.Float */
|
|
||||||
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
|
|
||||||
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
|
|
||||||
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
|
|
||||||
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
|
|
||||||
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
|
|
||||||
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
|
|
||||||
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
|
|
||||||
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
|
|
||||||
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
|
|
||||||
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
|
|
||||||
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
|
|
||||||
.highlight .sr { color: #235388 } /* Literal.String.Regex */
|
|
||||||
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
|
|
||||||
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
|
|
||||||
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
|
|
||||||
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
|
|
||||||
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
|
|
||||||
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
|
|
||||||
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
|
|
651
doc/build/html/_static/searchtools.js
vendored
@ -1,651 +0,0 @@
|
|||||||
/*
|
|
||||||
* searchtools.js_t
|
|
||||||
* ~~~~~~~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* Sphinx JavaScript utilties for the full-text search.
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
||||||
* :license: BSD, see LICENSE for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Non-minified version JS is _stemmer.js if file is provided */
|
|
||||||
/**
|
|
||||||
* Porter Stemmer
|
|
||||||
*/
|
|
||||||
var Stemmer = function() {
|
|
||||||
|
|
||||||
var step2list = {
|
|
||||||
ational: 'ate',
|
|
||||||
tional: 'tion',
|
|
||||||
enci: 'ence',
|
|
||||||
anci: 'ance',
|
|
||||||
izer: 'ize',
|
|
||||||
bli: 'ble',
|
|
||||||
alli: 'al',
|
|
||||||
entli: 'ent',
|
|
||||||
eli: 'e',
|
|
||||||
ousli: 'ous',
|
|
||||||
ization: 'ize',
|
|
||||||
ation: 'ate',
|
|
||||||
ator: 'ate',
|
|
||||||
alism: 'al',
|
|
||||||
iveness: 'ive',
|
|
||||||
fulness: 'ful',
|
|
||||||
ousness: 'ous',
|
|
||||||
aliti: 'al',
|
|
||||||
iviti: 'ive',
|
|
||||||
biliti: 'ble',
|
|
||||||
logi: 'log'
|
|
||||||
};
|
|
||||||
|
|
||||||
var step3list = {
|
|
||||||
icate: 'ic',
|
|
||||||
ative: '',
|
|
||||||
alize: 'al',
|
|
||||||
iciti: 'ic',
|
|
||||||
ical: 'ic',
|
|
||||||
ful: '',
|
|
||||||
ness: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
var c = "[^aeiou]"; // consonant
|
|
||||||
var v = "[aeiouy]"; // vowel
|
|
||||||
var C = c + "[^aeiouy]*"; // consonant sequence
|
|
||||||
var V = v + "[aeiou]*"; // vowel sequence
|
|
||||||
|
|
||||||
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
|
|
||||||
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
|
|
||||||
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
|
|
||||||
var s_v = "^(" + C + ")?" + v; // vowel in stem
|
|
||||||
|
|
||||||
this.stemWord = function (w) {
|
|
||||||
var stem;
|
|
||||||
var suffix;
|
|
||||||
var firstch;
|
|
||||||
var origword = w;
|
|
||||||
|
|
||||||
if (w.length < 3)
|
|
||||||
return w;
|
|
||||||
|
|
||||||
var re;
|
|
||||||
var re2;
|
|
||||||
var re3;
|
|
||||||
var re4;
|
|
||||||
|
|
||||||
firstch = w.substr(0,1);
|
|
||||||
if (firstch == "y")
|
|
||||||
w = firstch.toUpperCase() + w.substr(1);
|
|
||||||
|
|
||||||
// Step 1a
|
|
||||||
re = /^(.+?)(ss|i)es$/;
|
|
||||||
re2 = /^(.+?)([^s])s$/;
|
|
||||||
|
|
||||||
if (re.test(w))
|
|
||||||
w = w.replace(re,"$1$2");
|
|
||||||
else if (re2.test(w))
|
|
||||||
w = w.replace(re2,"$1$2");
|
|
||||||
|
|
||||||
// Step 1b
|
|
||||||
re = /^(.+?)eed$/;
|
|
||||||
re2 = /^(.+?)(ed|ing)$/;
|
|
||||||
if (re.test(w)) {
|
|
||||||
var fp = re.exec(w);
|
|
||||||
re = new RegExp(mgr0);
|
|
||||||
if (re.test(fp[1])) {
|
|
||||||
re = /.$/;
|
|
||||||
w = w.replace(re,"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (re2.test(w)) {
|
|
||||||
var fp = re2.exec(w);
|
|
||||||
stem = fp[1];
|
|
||||||
re2 = new RegExp(s_v);
|
|
||||||
if (re2.test(stem)) {
|
|
||||||
w = stem;
|
|
||||||
re2 = /(at|bl|iz)$/;
|
|
||||||
re3 = new RegExp("([^aeiouylsz])\\1$");
|
|
||||||
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
|
||||||
if (re2.test(w))
|
|
||||||
w = w + "e";
|
|
||||||
else if (re3.test(w)) {
|
|
||||||
re = /.$/;
|
|
||||||
w = w.replace(re,"");
|
|
||||||
}
|
|
||||||
else if (re4.test(w))
|
|
||||||
w = w + "e";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1c
|
|
||||||
re = /^(.+?)y$/;
|
|
||||||
if (re.test(w)) {
|
|
||||||
var fp = re.exec(w);
|
|
||||||
stem = fp[1];
|
|
||||||
re = new RegExp(s_v);
|
|
||||||
if (re.test(stem))
|
|
||||||
w = stem + "i";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2
|
|
||||||
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
|
|
||||||
if (re.test(w)) {
|
|
||||||
var fp = re.exec(w);
|
|
||||||
stem = fp[1];
|
|
||||||
suffix = fp[2];
|
|
||||||
re = new RegExp(mgr0);
|
|
||||||
if (re.test(stem))
|
|
||||||
w = stem + step2list[suffix];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3
|
|
||||||
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
|
|
||||||
if (re.test(w)) {
|
|
||||||
var fp = re.exec(w);
|
|
||||||
stem = fp[1];
|
|
||||||
suffix = fp[2];
|
|
||||||
re = new RegExp(mgr0);
|
|
||||||
if (re.test(stem))
|
|
||||||
w = stem + step3list[suffix];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4
|
|
||||||
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
|
|
||||||
re2 = /^(.+?)(s|t)(ion)$/;
|
|
||||||
if (re.test(w)) {
|
|
||||||
var fp = re.exec(w);
|
|
||||||
stem = fp[1];
|
|
||||||
re = new RegExp(mgr1);
|
|
||||||
if (re.test(stem))
|
|
||||||
w = stem;
|
|
||||||
}
|
|
||||||
else if (re2.test(w)) {
|
|
||||||
var fp = re2.exec(w);
|
|
||||||
stem = fp[1] + fp[2];
|
|
||||||
re2 = new RegExp(mgr1);
|
|
||||||
if (re2.test(stem))
|
|
||||||
w = stem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 5
|
|
||||||
re = /^(.+?)e$/;
|
|
||||||
if (re.test(w)) {
|
|
||||||
var fp = re.exec(w);
|
|
||||||
stem = fp[1];
|
|
||||||
re = new RegExp(mgr1);
|
|
||||||
re2 = new RegExp(meq1);
|
|
||||||
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
|
||||||
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
|
|
||||||
w = stem;
|
|
||||||
}
|
|
||||||
re = /ll$/;
|
|
||||||
re2 = new RegExp(mgr1);
|
|
||||||
if (re.test(w) && re2.test(w)) {
|
|
||||||
re = /.$/;
|
|
||||||
w = w.replace(re,"");
|
|
||||||
}
|
|
||||||
|
|
||||||
// and turn initial Y back to y
|
|
||||||
if (firstch == "y")
|
|
||||||
w = firstch.toLowerCase() + w.substr(1);
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple result scoring code.
|
|
||||||
*/
|
|
||||||
var Scorer = {
|
|
||||||
// Implement the following function to further tweak the score for each result
|
|
||||||
// The function takes a result array [filename, title, anchor, descr, score]
|
|
||||||
// and returns the new score.
|
|
||||||
/*
|
|
||||||
score: function(result) {
|
|
||||||
return result[4];
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
// query matches the full name of an object
|
|
||||||
objNameMatch: 11,
|
|
||||||
// or matches in the last dotted part of the object name
|
|
||||||
objPartialMatch: 6,
|
|
||||||
// Additive scores depending on the priority of the object
|
|
||||||
objPrio: {0: 15, // used to be importantResults
|
|
||||||
1: 5, // used to be objectResults
|
|
||||||
2: -5}, // used to be unimportantResults
|
|
||||||
// Used when the priority is not in the mapping.
|
|
||||||
objPrioDefault: 0,
|
|
||||||
|
|
||||||
// query found in title
|
|
||||||
title: 15,
|
|
||||||
// query found in terms
|
|
||||||
term: 5
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search Module
|
|
||||||
*/
|
|
||||||
var Search = {
|
|
||||||
|
|
||||||
_index : null,
|
|
||||||
_queued_query : null,
|
|
||||||
_pulse_status : -1,
|
|
||||||
|
|
||||||
init : function() {
|
|
||||||
var params = $.getQueryParameters();
|
|
||||||
if (params.q) {
|
|
||||||
var query = params.q[0];
|
|
||||||
$('input[name="q"]')[0].value = query;
|
|
||||||
this.performSearch(query);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
loadIndex : function(url) {
|
|
||||||
$.ajax({type: "GET", url: url, data: null,
|
|
||||||
dataType: "script", cache: true,
|
|
||||||
complete: function(jqxhr, textstatus) {
|
|
||||||
if (textstatus != "success") {
|
|
||||||
document.getElementById("searchindexloader").src = url;
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
},
|
|
||||||
|
|
||||||
setIndex : function(index) {
|
|
||||||
var q;
|
|
||||||
this._index = index;
|
|
||||||
if ((q = this._queued_query) !== null) {
|
|
||||||
this._queued_query = null;
|
|
||||||
Search.query(q);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
hasIndex : function() {
|
|
||||||
return this._index !== null;
|
|
||||||
},
|
|
||||||
|
|
||||||
deferQuery : function(query) {
|
|
||||||
this._queued_query = query;
|
|
||||||
},
|
|
||||||
|
|
||||||
stopPulse : function() {
|
|
||||||
this._pulse_status = 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
startPulse : function() {
|
|
||||||
if (this._pulse_status >= 0)
|
|
||||||
return;
|
|
||||||
function pulse() {
|
|
||||||
var i;
|
|
||||||
Search._pulse_status = (Search._pulse_status + 1) % 4;
|
|
||||||
var dotString = '';
|
|
||||||
for (i = 0; i < Search._pulse_status; i++)
|
|
||||||
dotString += '.';
|
|
||||||
Search.dots.text(dotString);
|
|
||||||
if (Search._pulse_status > -1)
|
|
||||||
window.setTimeout(pulse, 500);
|
|
||||||
}
|
|
||||||
pulse();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* perform a search for something (or wait until index is loaded)
|
|
||||||
*/
|
|
||||||
performSearch : function(query) {
|
|
||||||
// create the required interface elements
|
|
||||||
this.out = $('#search-results');
|
|
||||||
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
|
|
||||||
this.dots = $('<span></span>').appendTo(this.title);
|
|
||||||
this.status = $('<p style="display: none"></p>').appendTo(this.out);
|
|
||||||
this.output = $('<ul class="search"/>').appendTo(this.out);
|
|
||||||
|
|
||||||
$('#search-progress').text(_('Preparing search...'));
|
|
||||||
this.startPulse();
|
|
||||||
|
|
||||||
// index already loaded, the browser was quick!
|
|
||||||
if (this.hasIndex())
|
|
||||||
this.query(query);
|
|
||||||
else
|
|
||||||
this.deferQuery(query);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* execute search (requires search index to be loaded)
|
|
||||||
*/
|
|
||||||
query : function(query) {
|
|
||||||
var i;
|
|
||||||
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
|
|
||||||
|
|
||||||
// stem the searchterms and add them to the correct list
|
|
||||||
var stemmer = new Stemmer();
|
|
||||||
var searchterms = [];
|
|
||||||
var excluded = [];
|
|
||||||
var hlterms = [];
|
|
||||||
var tmp = query.split(/\s+/);
|
|
||||||
var objectterms = [];
|
|
||||||
for (i = 0; i < tmp.length; i++) {
|
|
||||||
if (tmp[i] !== "") {
|
|
||||||
objectterms.push(tmp[i].toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
|
|
||||||
tmp[i] === "") {
|
|
||||||
// skip this "word"
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// stem the word
|
|
||||||
var word = stemmer.stemWord(tmp[i].toLowerCase());
|
|
||||||
var toAppend;
|
|
||||||
// select the correct list
|
|
||||||
if (word[0] == '-') {
|
|
||||||
toAppend = excluded;
|
|
||||||
word = word.substr(1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
toAppend = searchterms;
|
|
||||||
hlterms.push(tmp[i].toLowerCase());
|
|
||||||
}
|
|
||||||
// only add if not already in the list
|
|
||||||
if (!$u.contains(toAppend, word))
|
|
||||||
toAppend.push(word);
|
|
||||||
}
|
|
||||||
var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
|
|
||||||
|
|
||||||
// console.debug('SEARCH: searching for:');
|
|
||||||
// console.info('required: ', searchterms);
|
|
||||||
// console.info('excluded: ', excluded);
|
|
||||||
|
|
||||||
// prepare search
|
|
||||||
var terms = this._index.terms;
|
|
||||||
var titleterms = this._index.titleterms;
|
|
||||||
|
|
||||||
// array of [filename, title, anchor, descr, score]
|
|
||||||
var results = [];
|
|
||||||
$('#search-progress').empty();
|
|
||||||
|
|
||||||
// lookup as object
|
|
||||||
for (i = 0; i < objectterms.length; i++) {
|
|
||||||
var others = [].concat(objectterms.slice(0, i),
|
|
||||||
objectterms.slice(i+1, objectterms.length));
|
|
||||||
results = results.concat(this.performObjectSearch(objectterms[i], others));
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookup as search terms in fulltext
|
|
||||||
results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
|
|
||||||
|
|
||||||
// let the scorer override scores with a custom scoring function
|
|
||||||
if (Scorer.score) {
|
|
||||||
for (i = 0; i < results.length; i++)
|
|
||||||
results[i][4] = Scorer.score(results[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now sort the results by score (in opposite order of appearance, since the
|
|
||||||
// display function below uses pop() to retrieve items) and then
|
|
||||||
// alphabetically
|
|
||||||
results.sort(function(a, b) {
|
|
||||||
var left = a[4];
|
|
||||||
var right = b[4];
|
|
||||||
if (left > right) {
|
|
||||||
return 1;
|
|
||||||
} else if (left < right) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
// same score: sort alphabetically
|
|
||||||
left = a[1].toLowerCase();
|
|
||||||
right = b[1].toLowerCase();
|
|
||||||
return (left > right) ? -1 : ((left < right) ? 1 : 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// for debugging
|
|
||||||
//Search.lastresults = results.slice(); // a copy
|
|
||||||
//console.info('search results:', Search.lastresults);
|
|
||||||
|
|
||||||
// print the results
|
|
||||||
var resultCount = results.length;
|
|
||||||
function displayNextItem() {
|
|
||||||
// results left, load the summary and display it
|
|
||||||
if (results.length) {
|
|
||||||
var item = results.pop();
|
|
||||||
var listItem = $('<li style="display:none"></li>');
|
|
||||||
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
|
|
||||||
// dirhtml builder
|
|
||||||
var dirname = item[0] + '/';
|
|
||||||
if (dirname.match(/\/index\/$/)) {
|
|
||||||
dirname = dirname.substring(0, dirname.length-6);
|
|
||||||
} else if (dirname == 'index/') {
|
|
||||||
dirname = '';
|
|
||||||
}
|
|
||||||
listItem.append($('<a/>').attr('href',
|
|
||||||
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
|
|
||||||
highlightstring + item[2]).html(item[1]));
|
|
||||||
} else {
|
|
||||||
// normal html builders
|
|
||||||
listItem.append($('<a/>').attr('href',
|
|
||||||
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
|
|
||||||
highlightstring + item[2]).html(item[1]));
|
|
||||||
}
|
|
||||||
if (item[3]) {
|
|
||||||
listItem.append($('<span> (' + item[3] + ')</span>'));
|
|
||||||
Search.output.append(listItem);
|
|
||||||
listItem.slideDown(5, function() {
|
|
||||||
displayNextItem();
|
|
||||||
});
|
|
||||||
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
|
|
||||||
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
|
|
||||||
dataType: "text",
|
|
||||||
complete: function(jqxhr, textstatus) {
|
|
||||||
var data = jqxhr.responseText;
|
|
||||||
if (data !== '' && data !== undefined) {
|
|
||||||
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
|
|
||||||
}
|
|
||||||
Search.output.append(listItem);
|
|
||||||
listItem.slideDown(5, function() {
|
|
||||||
displayNextItem();
|
|
||||||
});
|
|
||||||
}});
|
|
||||||
} else {
|
|
||||||
// no source available, just display title
|
|
||||||
Search.output.append(listItem);
|
|
||||||
listItem.slideDown(5, function() {
|
|
||||||
displayNextItem();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// search finished, update title and status message
|
|
||||||
else {
|
|
||||||
Search.stopPulse();
|
|
||||||
Search.title.text(_('Search Results'));
|
|
||||||
if (!resultCount)
|
|
||||||
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
|
|
||||||
else
|
|
||||||
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
|
|
||||||
Search.status.fadeIn(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
displayNextItem();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* search for object names
|
|
||||||
*/
|
|
||||||
performObjectSearch : function(object, otherterms) {
|
|
||||||
var filenames = this._index.filenames;
|
|
||||||
var objects = this._index.objects;
|
|
||||||
var objnames = this._index.objnames;
|
|
||||||
var titles = this._index.titles;
|
|
||||||
|
|
||||||
var i;
|
|
||||||
var results = [];
|
|
||||||
|
|
||||||
for (var prefix in objects) {
|
|
||||||
for (var name in objects[prefix]) {
|
|
||||||
var fullname = (prefix ? prefix + '.' : '') + name;
|
|
||||||
if (fullname.toLowerCase().indexOf(object) > -1) {
|
|
||||||
var score = 0;
|
|
||||||
var parts = fullname.split('.');
|
|
||||||
// check for different match types: exact matches of full name or
|
|
||||||
// "last name" (i.e. last dotted part)
|
|
||||||
if (fullname == object || parts[parts.length - 1] == object) {
|
|
||||||
score += Scorer.objNameMatch;
|
|
||||||
// matches in last name
|
|
||||||
} else if (parts[parts.length - 1].indexOf(object) > -1) {
|
|
||||||
score += Scorer.objPartialMatch;
|
|
||||||
}
|
|
||||||
var match = objects[prefix][name];
|
|
||||||
var objname = objnames[match[1]][2];
|
|
||||||
var title = titles[match[0]];
|
|
||||||
// If more than one term searched for, we require other words to be
|
|
||||||
// found in the name/title/description
|
|
||||||
if (otherterms.length > 0) {
|
|
||||||
var haystack = (prefix + ' ' + name + ' ' +
|
|
||||||
objname + ' ' + title).toLowerCase();
|
|
||||||
var allfound = true;
|
|
||||||
for (i = 0; i < otherterms.length; i++) {
|
|
||||||
if (haystack.indexOf(otherterms[i]) == -1) {
|
|
||||||
allfound = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!allfound) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var descr = objname + _(', in ') + title;
|
|
||||||
|
|
||||||
var anchor = match[3];
|
|
||||||
if (anchor === '')
|
|
||||||
anchor = fullname;
|
|
||||||
else if (anchor == '-')
|
|
||||||
anchor = objnames[match[1]][1] + '-' + fullname;
|
|
||||||
// add custom score for some objects according to scorer
|
|
||||||
if (Scorer.objPrio.hasOwnProperty(match[2])) {
|
|
||||||
score += Scorer.objPrio[match[2]];
|
|
||||||
} else {
|
|
||||||
score += Scorer.objPrioDefault;
|
|
||||||
}
|
|
||||||
results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* search for full-text terms in the index
|
|
||||||
*/
|
|
||||||
performTermsSearch : function(searchterms, excluded, terms, titleterms) {
|
|
||||||
var filenames = this._index.filenames;
|
|
||||||
var titles = this._index.titles;
|
|
||||||
|
|
||||||
var i, j, file;
|
|
||||||
var fileMap = {};
|
|
||||||
var scoreMap = {};
|
|
||||||
var results = [];
|
|
||||||
|
|
||||||
// perform the search on the required terms
|
|
||||||
for (i = 0; i < searchterms.length; i++) {
|
|
||||||
var word = searchterms[i];
|
|
||||||
var files = [];
|
|
||||||
var _o = [
|
|
||||||
{files: terms[word], score: Scorer.term},
|
|
||||||
{files: titleterms[word], score: Scorer.title}
|
|
||||||
];
|
|
||||||
|
|
||||||
// no match but word was a required one
|
|
||||||
if ($u.every(_o, function(o){return o.files === undefined;})) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// found search word in contents
|
|
||||||
$u.each(_o, function(o) {
|
|
||||||
var _files = o.files;
|
|
||||||
if (_files === undefined)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (_files.length === undefined)
|
|
||||||
_files = [_files];
|
|
||||||
files = files.concat(_files);
|
|
||||||
|
|
||||||
// set score for the word in each file to Scorer.term
|
|
||||||
for (j = 0; j < _files.length; j++) {
|
|
||||||
file = _files[j];
|
|
||||||
if (!(file in scoreMap))
|
|
||||||
scoreMap[file] = {}
|
|
||||||
scoreMap[file][word] = o.score;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// create the mapping
|
|
||||||
for (j = 0; j < files.length; j++) {
|
|
||||||
file = files[j];
|
|
||||||
if (file in fileMap)
|
|
||||||
fileMap[file].push(word);
|
|
||||||
else
|
|
||||||
fileMap[file] = [word];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now check if the files don't contain excluded terms
|
|
||||||
for (file in fileMap) {
|
|
||||||
var valid = true;
|
|
||||||
|
|
||||||
// check if all requirements are matched
|
|
||||||
if (fileMap[file].length != searchterms.length)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// ensure that none of the excluded terms is in the search result
|
|
||||||
for (i = 0; i < excluded.length; i++) {
|
|
||||||
if (terms[excluded[i]] == file ||
|
|
||||||
titleterms[excluded[i]] == file ||
|
|
||||||
$u.contains(terms[excluded[i]] || [], file) ||
|
|
||||||
$u.contains(titleterms[excluded[i]] || [], file)) {
|
|
||||||
valid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have still a valid result we can add it to the result list
|
|
||||||
if (valid) {
|
|
||||||
// select one (max) score for the file.
|
|
||||||
// for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
|
|
||||||
var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
|
|
||||||
results.push([filenames[file], titles[file], '', null, score]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* helper function to return a node containing the
|
|
||||||
* search summary for a given text. keywords is a list
|
|
||||||
* of stemmed words, hlwords is the list of normal, unstemmed
|
|
||||||
* words. the first one is used to find the occurance, the
|
|
||||||
* latter for highlighting it.
|
|
||||||
*/
|
|
||||||
makeSearchSummary : function(text, keywords, hlwords) {
|
|
||||||
var textLower = text.toLowerCase();
|
|
||||||
var start = 0;
|
|
||||||
$.each(keywords, function() {
|
|
||||||
var i = textLower.indexOf(this.toLowerCase());
|
|
||||||
if (i > -1)
|
|
||||||
start = i;
|
|
||||||
});
|
|
||||||
start = Math.max(start - 120, 0);
|
|
||||||
var excerpt = ((start > 0) ? '...' : '') +
|
|
||||||
$.trim(text.substr(start, 240)) +
|
|
||||||
((start + 240 - text.length) ? '...' : '');
|
|
||||||
var rv = $('<div class="context"></div>').text(excerpt);
|
|
||||||
$.each(hlwords, function() {
|
|
||||||
rv = rv.highlightText(this, 'highlighted');
|
|
||||||
});
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
Search.init();
|
|
||||||
});
|
|
159
doc/build/html/_static/sidebar.js
vendored
@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
* sidebar.js
|
|
||||||
* ~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* This script makes the Sphinx sidebar collapsible.
|
|
||||||
*
|
|
||||||
* .sphinxsidebar contains .sphinxsidebarwrapper. This script adds
|
|
||||||
* in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
|
|
||||||
* used to collapse and expand the sidebar.
|
|
||||||
*
|
|
||||||
* When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
|
|
||||||
* and the width of the sidebar and the margin-left of the document
|
|
||||||
* are decreased. When the sidebar is expanded the opposite happens.
|
|
||||||
* This script saves a per-browser/per-session cookie used to
|
|
||||||
* remember the position of the sidebar among the pages.
|
|
||||||
* Once the browser is closed the cookie is deleted and the position
|
|
||||||
* reset to the default (expanded).
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
||||||
* :license: BSD, see LICENSE for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// global elements used by the functions.
|
|
||||||
// the 'sidebarbutton' element is defined as global after its
|
|
||||||
// creation, in the add_sidebar_button function
|
|
||||||
var bodywrapper = $('.bodywrapper');
|
|
||||||
var sidebar = $('.sphinxsidebar');
|
|
||||||
var sidebarwrapper = $('.sphinxsidebarwrapper');
|
|
||||||
|
|
||||||
// for some reason, the document has no sidebar; do not run into errors
|
|
||||||
if (!sidebar.length) return;
|
|
||||||
|
|
||||||
// original margin-left of the bodywrapper and width of the sidebar
|
|
||||||
// with the sidebar expanded
|
|
||||||
var bw_margin_expanded = bodywrapper.css('margin-left');
|
|
||||||
var ssb_width_expanded = sidebar.width();
|
|
||||||
|
|
||||||
// margin-left of the bodywrapper and width of the sidebar
|
|
||||||
// with the sidebar collapsed
|
|
||||||
var bw_margin_collapsed = '.8em';
|
|
||||||
var ssb_width_collapsed = '.8em';
|
|
||||||
|
|
||||||
// colors used by the current theme
|
|
||||||
var dark_color = $('.related').css('background-color');
|
|
||||||
var light_color = $('.document').css('background-color');
|
|
||||||
|
|
||||||
function sidebar_is_collapsed() {
|
|
||||||
return sidebarwrapper.is(':not(:visible)');
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle_sidebar() {
|
|
||||||
if (sidebar_is_collapsed())
|
|
||||||
expand_sidebar();
|
|
||||||
else
|
|
||||||
collapse_sidebar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function collapse_sidebar() {
|
|
||||||
sidebarwrapper.hide();
|
|
||||||
sidebar.css('width', ssb_width_collapsed);
|
|
||||||
bodywrapper.css('margin-left', bw_margin_collapsed);
|
|
||||||
sidebarbutton.css({
|
|
||||||
'margin-left': '0',
|
|
||||||
'height': bodywrapper.height()
|
|
||||||
});
|
|
||||||
sidebarbutton.find('span').text('»');
|
|
||||||
sidebarbutton.attr('title', _('Expand sidebar'));
|
|
||||||
document.cookie = 'sidebar=collapsed';
|
|
||||||
}
|
|
||||||
|
|
||||||
function expand_sidebar() {
|
|
||||||
bodywrapper.css('margin-left', bw_margin_expanded);
|
|
||||||
sidebar.css('width', ssb_width_expanded);
|
|
||||||
sidebarwrapper.show();
|
|
||||||
sidebarbutton.css({
|
|
||||||
'margin-left': ssb_width_expanded-12,
|
|
||||||
'height': bodywrapper.height()
|
|
||||||
});
|
|
||||||
sidebarbutton.find('span').text('«');
|
|
||||||
sidebarbutton.attr('title', _('Collapse sidebar'));
|
|
||||||
document.cookie = 'sidebar=expanded';
|
|
||||||
}
|
|
||||||
|
|
||||||
function add_sidebar_button() {
|
|
||||||
sidebarwrapper.css({
|
|
||||||
'float': 'left',
|
|
||||||
'margin-right': '0',
|
|
||||||
'width': ssb_width_expanded - 28
|
|
||||||
});
|
|
||||||
// create the button
|
|
||||||
sidebar.append(
|
|
||||||
'<div id="sidebarbutton"><span>«</span></div>'
|
|
||||||
);
|
|
||||||
var sidebarbutton = $('#sidebarbutton');
|
|
||||||
light_color = sidebarbutton.css('background-color');
|
|
||||||
// find the height of the viewport to center the '<<' in the page
|
|
||||||
var viewport_height;
|
|
||||||
if (window.innerHeight)
|
|
||||||
viewport_height = window.innerHeight;
|
|
||||||
else
|
|
||||||
viewport_height = $(window).height();
|
|
||||||
sidebarbutton.find('span').css({
|
|
||||||
'display': 'block',
|
|
||||||
'margin-top': (viewport_height - sidebar.position().top - 20) / 2
|
|
||||||
});
|
|
||||||
|
|
||||||
sidebarbutton.click(toggle_sidebar);
|
|
||||||
sidebarbutton.attr('title', _('Collapse sidebar'));
|
|
||||||
sidebarbutton.css({
|
|
||||||
'color': '#FFFFFF',
|
|
||||||
'border-left': '1px solid ' + dark_color,
|
|
||||||
'font-size': '1.2em',
|
|
||||||
'cursor': 'pointer',
|
|
||||||
'height': bodywrapper.height(),
|
|
||||||
'padding-top': '1px',
|
|
||||||
'margin-left': ssb_width_expanded - 12
|
|
||||||
});
|
|
||||||
|
|
||||||
sidebarbutton.hover(
|
|
||||||
function () {
|
|
||||||
$(this).css('background-color', dark_color);
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
$(this).css('background-color', light_color);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function set_position_from_cookie() {
|
|
||||||
if (!document.cookie)
|
|
||||||
return;
|
|
||||||
var items = document.cookie.split(';');
|
|
||||||
for(var k=0; k<items.length; k++) {
|
|
||||||
var key_val = items[k].split('=');
|
|
||||||
var key = key_val[0].replace(/ /, ""); // strip leading spaces
|
|
||||||
if (key == 'sidebar') {
|
|
||||||
var value = key_val[1];
|
|
||||||
if ((value == 'collapsed') && (!sidebar_is_collapsed()))
|
|
||||||
collapse_sidebar();
|
|
||||||
else if ((value == 'expanded') && (sidebar_is_collapsed()))
|
|
||||||
expand_sidebar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_sidebar_button();
|
|
||||||
var sidebarbutton = $('#sidebarbutton');
|
|
||||||
set_position_from_cookie();
|
|
||||||
});
|
|
BIN
doc/build/html/_static/up-pressed.png
vendored
Before Width: | Height: | Size: 345 B |
BIN
doc/build/html/_static/up.png
vendored
Before Width: | Height: | Size: 345 B |
808
doc/build/html/_static/websupport.js
vendored
@ -1,808 +0,0 @@
|
|||||||
/*
|
|
||||||
* websupport.js
|
|
||||||
* ~~~~~~~~~~~~~
|
|
||||||
*
|
|
||||||
* sphinx.websupport utilties for all documentation.
|
|
||||||
*
|
|
||||||
* :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
|
||||||
* :license: BSD, see LICENSE for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function($) {
|
|
||||||
$.fn.autogrow = function() {
|
|
||||||
return this.each(function() {
|
|
||||||
var textarea = this;
|
|
||||||
|
|
||||||
$.fn.autogrow.resize(textarea);
|
|
||||||
|
|
||||||
$(textarea)
|
|
||||||
.focus(function() {
|
|
||||||
textarea.interval = setInterval(function() {
|
|
||||||
$.fn.autogrow.resize(textarea);
|
|
||||||
}, 500);
|
|
||||||
})
|
|
||||||
.blur(function() {
|
|
||||||
clearInterval(textarea.interval);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$.fn.autogrow.resize = function(textarea) {
|
|
||||||
var lineHeight = parseInt($(textarea).css('line-height'), 10);
|
|
||||||
var lines = textarea.value.split('\n');
|
|
||||||
var columns = textarea.cols;
|
|
||||||
var lineCount = 0;
|
|
||||||
$.each(lines, function() {
|
|
||||||
lineCount += Math.ceil(this.length / columns) || 1;
|
|
||||||
});
|
|
||||||
var height = lineHeight * (lineCount + 1);
|
|
||||||
$(textarea).css('height', height);
|
|
||||||
};
|
|
||||||
})(jQuery);
|
|
||||||
|
|
||||||
(function($) {
|
|
||||||
var comp, by;
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
initEvents();
|
|
||||||
initComparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initEvents() {
|
|
||||||
$(document).on("click", 'a.comment-close', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
hide($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.vote', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
handleVote($(this));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.reply', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
openReply($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.close-reply', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
closeReply($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.sort-option', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
handleReSort($(this));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.show-proposal', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
showProposal($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.hide-proposal', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
hideProposal($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.show-propose-change', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
showProposeChange($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.hide-propose-change', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
hideProposeChange($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.accept-comment', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
acceptComment($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.delete-comment', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
deleteComment($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
$(document).on("click", 'a.comment-markup', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
toggleCommentMarkupBox($(this).attr('id').substring(2));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set comp, which is a comparator function used for sorting and
|
|
||||||
* inserting comments into the list.
|
|
||||||
*/
|
|
||||||
function setComparator() {
|
|
||||||
// If the first three letters are "asc", sort in ascending order
|
|
||||||
// and remove the prefix.
|
|
||||||
if (by.substring(0,3) == 'asc') {
|
|
||||||
var i = by.substring(3);
|
|
||||||
comp = function(a, b) { return a[i] - b[i]; };
|
|
||||||
} else {
|
|
||||||
// Otherwise sort in descending order.
|
|
||||||
comp = function(a, b) { return b[by] - a[by]; };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset link styles and format the selected sort option.
|
|
||||||
$('a.sel').attr('href', '#').removeClass('sel');
|
|
||||||
$('a.by' + by).removeAttr('href').addClass('sel');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a comp function. If the user has preferences stored in
|
|
||||||
* the sortBy cookie, use those, otherwise use the default.
|
|
||||||
*/
|
|
||||||
function initComparator() {
|
|
||||||
by = 'rating'; // Default to sort by rating.
|
|
||||||
// If the sortBy cookie is set, use that instead.
|
|
||||||
if (document.cookie.length > 0) {
|
|
||||||
var start = document.cookie.indexOf('sortBy=');
|
|
||||||
if (start != -1) {
|
|
||||||
start = start + 7;
|
|
||||||
var end = document.cookie.indexOf(";", start);
|
|
||||||
if (end == -1) {
|
|
||||||
end = document.cookie.length;
|
|
||||||
by = unescape(document.cookie.substring(start, end));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setComparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a comment div.
|
|
||||||
*/
|
|
||||||
function show(id) {
|
|
||||||
$('#ao' + id).hide();
|
|
||||||
$('#ah' + id).show();
|
|
||||||
var context = $.extend({id: id}, opts);
|
|
||||||
var popup = $(renderTemplate(popupTemplate, context)).hide();
|
|
||||||
popup.find('textarea[name="proposal"]').hide();
|
|
||||||
popup.find('a.by' + by).addClass('sel');
|
|
||||||
var form = popup.find('#cf' + id);
|
|
||||||
form.submit(function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
addComment(form);
|
|
||||||
});
|
|
||||||
$('#s' + id).after(popup);
|
|
||||||
popup.slideDown('fast', function() {
|
|
||||||
getComments(id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide a comment div.
|
|
||||||
*/
|
|
||||||
function hide(id) {
|
|
||||||
$('#ah' + id).hide();
|
|
||||||
$('#ao' + id).show();
|
|
||||||
var div = $('#sc' + id);
|
|
||||||
div.slideUp('fast', function() {
|
|
||||||
div.remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform an ajax request to get comments for a node
|
|
||||||
* and insert the comments into the comments tree.
|
|
||||||
*/
|
|
||||||
function getComments(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'GET',
|
|
||||||
url: opts.getCommentsURL,
|
|
||||||
data: {node: id},
|
|
||||||
success: function(data, textStatus, request) {
|
|
||||||
var ul = $('#cl' + id);
|
|
||||||
var speed = 100;
|
|
||||||
$('#cf' + id)
|
|
||||||
.find('textarea[name="proposal"]')
|
|
||||||
.data('source', data.source);
|
|
||||||
|
|
||||||
if (data.comments.length === 0) {
|
|
||||||
ul.html('<li>No comments yet.</li>');
|
|
||||||
ul.data('empty', true);
|
|
||||||
} else {
|
|
||||||
// If there are comments, sort them and put them in the list.
|
|
||||||
var comments = sortComments(data.comments);
|
|
||||||
speed = data.comments.length * 100;
|
|
||||||
appendComments(comments, ul);
|
|
||||||
ul.data('empty', false);
|
|
||||||
}
|
|
||||||
$('#cn' + id).slideUp(speed + 200);
|
|
||||||
ul.slideDown(speed);
|
|
||||||
},
|
|
||||||
error: function(request, textStatus, error) {
|
|
||||||
showError('Oops, there was a problem retrieving the comments.');
|
|
||||||
},
|
|
||||||
dataType: 'json'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a comment via ajax and insert the comment into the comment tree.
|
|
||||||
*/
|
|
||||||
function addComment(form) {
|
|
||||||
var node_id = form.find('input[name="node"]').val();
|
|
||||||
var parent_id = form.find('input[name="parent"]').val();
|
|
||||||
var text = form.find('textarea[name="comment"]').val();
|
|
||||||
var proposal = form.find('textarea[name="proposal"]').val();
|
|
||||||
|
|
||||||
if (text == '') {
|
|
||||||
showError('Please enter a comment.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable the form that is being submitted.
|
|
||||||
form.find('textarea,input').attr('disabled', 'disabled');
|
|
||||||
|
|
||||||
// Send the comment to the server.
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: opts.addCommentURL,
|
|
||||||
dataType: 'json',
|
|
||||||
data: {
|
|
||||||
node: node_id,
|
|
||||||
parent: parent_id,
|
|
||||||
text: text,
|
|
||||||
proposal: proposal
|
|
||||||
},
|
|
||||||
success: function(data, textStatus, error) {
|
|
||||||
// Reset the form.
|
|
||||||
if (node_id) {
|
|
||||||
hideProposeChange(node_id);
|
|
||||||
}
|
|
||||||
form.find('textarea')
|
|
||||||
.val('')
|
|
||||||
.add(form.find('input'))
|
|
||||||
.removeAttr('disabled');
|
|
||||||
var ul = $('#cl' + (node_id || parent_id));
|
|
||||||
if (ul.data('empty')) {
|
|
||||||
$(ul).empty();
|
|
||||||
ul.data('empty', false);
|
|
||||||
}
|
|
||||||
insertComment(data.comment);
|
|
||||||
var ao = $('#ao' + node_id);
|
|
||||||
ao.find('img').attr({'src': opts.commentBrightImage});
|
|
||||||
if (node_id) {
|
|
||||||
// if this was a "root" comment, remove the commenting box
|
|
||||||
// (the user can get it back by reopening the comment popup)
|
|
||||||
$('#ca' + node_id).slideUp();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(request, textStatus, error) {
|
|
||||||
form.find('textarea,input').removeAttr('disabled');
|
|
||||||
showError('Oops, there was a problem adding the comment.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively append comments to the main comment list and children
|
|
||||||
* lists, creating the comment tree.
|
|
||||||
*/
|
|
||||||
function appendComments(comments, ul) {
|
|
||||||
$.each(comments, function() {
|
|
||||||
var div = createCommentDiv(this);
|
|
||||||
ul.append($(document.createElement('li')).html(div));
|
|
||||||
appendComments(this.children, div.find('ul.comment-children'));
|
|
||||||
// To avoid stagnating data, don't store the comments children in data.
|
|
||||||
this.children = null;
|
|
||||||
div.data('comment', this);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* After adding a new comment, it must be inserted in the correct
|
|
||||||
* location in the comment tree.
|
|
||||||
*/
|
|
||||||
function insertComment(comment) {
|
|
||||||
var div = createCommentDiv(comment);
|
|
||||||
|
|
||||||
// To avoid stagnating data, don't store the comments children in data.
|
|
||||||
comment.children = null;
|
|
||||||
div.data('comment', comment);
|
|
||||||
|
|
||||||
var ul = $('#cl' + (comment.node || comment.parent));
|
|
||||||
var siblings = getChildren(ul);
|
|
||||||
|
|
||||||
var li = $(document.createElement('li'));
|
|
||||||
li.hide();
|
|
||||||
|
|
||||||
// Determine where in the parents children list to insert this comment.
|
|
||||||
for(i=0; i < siblings.length; i++) {
|
|
||||||
if (comp(comment, siblings[i]) <= 0) {
|
|
||||||
$('#cd' + siblings[i].id)
|
|
||||||
.parent()
|
|
||||||
.before(li.html(div));
|
|
||||||
li.slideDown('fast');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get here, this comment rates lower than all the others,
|
|
||||||
// or it is the only comment in the list.
|
|
||||||
ul.append(li.html(div));
|
|
||||||
li.slideDown('fast');
|
|
||||||
}
|
|
||||||
|
|
||||||
function acceptComment(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: opts.acceptCommentURL,
|
|
||||||
data: {id: id},
|
|
||||||
success: function(data, textStatus, request) {
|
|
||||||
$('#cm' + id).fadeOut('fast');
|
|
||||||
$('#cd' + id).removeClass('moderate');
|
|
||||||
},
|
|
||||||
error: function(request, textStatus, error) {
|
|
||||||
showError('Oops, there was a problem accepting the comment.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteComment(id) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: opts.deleteCommentURL,
|
|
||||||
data: {id: id},
|
|
||||||
success: function(data, textStatus, request) {
|
|
||||||
var div = $('#cd' + id);
|
|
||||||
if (data == 'delete') {
|
|
||||||
// Moderator mode: remove the comment and all children immediately
|
|
||||||
div.slideUp('fast', function() {
|
|
||||||
div.remove();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// User mode: only mark the comment as deleted
|
|
||||||
div
|
|
||||||
.find('span.user-id:first')
|
|
||||||
.text('[deleted]').end()
|
|
||||||
.find('div.comment-text:first')
|
|
||||||
.text('[deleted]').end()
|
|
||||||
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
|
|
||||||
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
|
|
||||||
.remove();
|
|
||||||
var comment = div.data('comment');
|
|
||||||
comment.username = '[deleted]';
|
|
||||||
comment.text = '[deleted]';
|
|
||||||
div.data('comment', comment);
|
|
||||||
},
|
|
||||||
error: function(request, textStatus, error) {
|
|
||||||
showError('Oops, there was a problem deleting the comment.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function showProposal(id) {
|
|
||||||
$('#sp' + id).hide();
|
|
||||||
$('#hp' + id).show();
|
|
||||||
$('#pr' + id).slideDown('fast');
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideProposal(id) {
|
|
||||||
$('#hp' + id).hide();
|
|
||||||
$('#sp' + id).show();
|
|
||||||
$('#pr' + id).slideUp('fast');
|
|
||||||
}
|
|
||||||
|
|
||||||
function showProposeChange(id) {
|
|
||||||
$('#pc' + id).hide();
|
|
||||||
$('#hc' + id).show();
|
|
||||||
var textarea = $('#pt' + id);
|
|
||||||
textarea.val(textarea.data('source'));
|
|
||||||
$.fn.autogrow.resize(textarea[0]);
|
|
||||||
textarea.slideDown('fast');
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideProposeChange(id) {
|
|
||||||
$('#hc' + id).hide();
|
|
||||||
$('#pc' + id).show();
|
|
||||||
var textarea = $('#pt' + id);
|
|
||||||
textarea.val('').removeAttr('disabled');
|
|
||||||
textarea.slideUp('fast');
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleCommentMarkupBox(id) {
|
|
||||||
$('#mb' + id).toggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Handle when the user clicks on a sort by link. */
|
|
||||||
function handleReSort(link) {
|
|
||||||
var classes = link.attr('class').split(/\s+/);
|
|
||||||
for (var i=0; i<classes.length; i++) {
|
|
||||||
if (classes[i] != 'sort-option') {
|
|
||||||
by = classes[i].substring(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setComparator();
|
|
||||||
// Save/update the sortBy cookie.
|
|
||||||
var expiration = new Date();
|
|
||||||
expiration.setDate(expiration.getDate() + 365);
|
|
||||||
document.cookie= 'sortBy=' + escape(by) +
|
|
||||||
';expires=' + expiration.toUTCString();
|
|
||||||
$('ul.comment-ul').each(function(index, ul) {
|
|
||||||
var comments = getChildren($(ul), true);
|
|
||||||
comments = sortComments(comments);
|
|
||||||
appendComments(comments, $(ul).empty());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to process a vote when a user clicks an arrow.
|
|
||||||
*/
|
|
||||||
function handleVote(link) {
|
|
||||||
if (!opts.voting) {
|
|
||||||
showError("You'll need to login to vote.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var id = link.attr('id');
|
|
||||||
if (!id) {
|
|
||||||
// Didn't click on one of the voting arrows.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If it is an unvote, the new vote value is 0,
|
|
||||||
// Otherwise it's 1 for an upvote, or -1 for a downvote.
|
|
||||||
var value = 0;
|
|
||||||
if (id.charAt(1) != 'u') {
|
|
||||||
value = id.charAt(0) == 'u' ? 1 : -1;
|
|
||||||
}
|
|
||||||
// The data to be sent to the server.
|
|
||||||
var d = {
|
|
||||||
comment_id: id.substring(2),
|
|
||||||
value: value
|
|
||||||
};
|
|
||||||
|
|
||||||
// Swap the vote and unvote links.
|
|
||||||
link.hide();
|
|
||||||
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
|
|
||||||
.show();
|
|
||||||
|
|
||||||
// The div the comment is displayed in.
|
|
||||||
var div = $('div#cd' + d.comment_id);
|
|
||||||
var data = div.data('comment');
|
|
||||||
|
|
||||||
// If this is not an unvote, and the other vote arrow has
|
|
||||||
// already been pressed, unpress it.
|
|
||||||
if ((d.value !== 0) && (data.vote === d.value * -1)) {
|
|
||||||
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
|
|
||||||
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the comments rating in the local data.
|
|
||||||
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
|
|
||||||
data.vote = d.value;
|
|
||||||
div.data('comment', data);
|
|
||||||
|
|
||||||
// Change the rating text.
|
|
||||||
div.find('.rating:first')
|
|
||||||
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
|
|
||||||
|
|
||||||
// Send the vote information to the server.
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: opts.processVoteURL,
|
|
||||||
data: d,
|
|
||||||
error: function(request, textStatus, error) {
|
|
||||||
showError('Oops, there was a problem casting that vote.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a reply form used to reply to an existing comment.
|
|
||||||
*/
|
|
||||||
function openReply(id) {
|
|
||||||
// Swap out the reply link for the hide link
|
|
||||||
$('#rl' + id).hide();
|
|
||||||
$('#cr' + id).show();
|
|
||||||
|
|
||||||
// Add the reply li to the children ul.
|
|
||||||
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
|
|
||||||
$('#cl' + id)
|
|
||||||
.prepend(div)
|
|
||||||
// Setup the submit handler for the reply form.
|
|
||||||
.find('#rf' + id)
|
|
||||||
.submit(function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
addComment($('#rf' + id));
|
|
||||||
closeReply(id);
|
|
||||||
})
|
|
||||||
.find('input[type=button]')
|
|
||||||
.click(function() {
|
|
||||||
closeReply(id);
|
|
||||||
});
|
|
||||||
div.slideDown('fast', function() {
|
|
||||||
$('#rf' + id).find('textarea').focus();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the reply form opened with openReply.
|
|
||||||
*/
|
|
||||||
function closeReply(id) {
|
|
||||||
// Remove the reply div from the DOM.
|
|
||||||
$('#rd' + id).slideUp('fast', function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Swap out the hide link for the reply link
|
|
||||||
$('#cr' + id).hide();
|
|
||||||
$('#rl' + id).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively sort a tree of comments using the comp comparator.
|
|
||||||
*/
|
|
||||||
function sortComments(comments) {
|
|
||||||
comments.sort(comp);
|
|
||||||
$.each(comments, function() {
|
|
||||||
this.children = sortComments(this.children);
|
|
||||||
});
|
|
||||||
return comments;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the children comments from a ul. If recursive is true,
|
|
||||||
* recursively include childrens' children.
|
|
||||||
*/
|
|
||||||
function getChildren(ul, recursive) {
|
|
||||||
var children = [];
|
|
||||||
ul.children().children("[id^='cd']")
|
|
||||||
.each(function() {
|
|
||||||
var comment = $(this).data('comment');
|
|
||||||
if (recursive)
|
|
||||||
comment.children = getChildren($(this).find('#cl' + comment.id), true);
|
|
||||||
children.push(comment);
|
|
||||||
});
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a div to display a comment in. */
|
|
||||||
function createCommentDiv(comment) {
|
|
||||||
if (!comment.displayed && !opts.moderator) {
|
|
||||||
return $('<div class="moderate">Thank you! Your comment will show up '
|
|
||||||
+ 'once it is has been approved by a moderator.</div>');
|
|
||||||
}
|
|
||||||
// Prettify the comment rating.
|
|
||||||
comment.pretty_rating = comment.rating + ' point' +
|
|
||||||
(comment.rating == 1 ? '' : 's');
|
|
||||||
// Make a class (for displaying not yet moderated comments differently)
|
|
||||||
comment.css_class = comment.displayed ? '' : ' moderate';
|
|
||||||
// Create a div for this comment.
|
|
||||||
var context = $.extend({}, opts, comment);
|
|
||||||
var div = $(renderTemplate(commentTemplate, context));
|
|
||||||
|
|
||||||
// If the user has voted on this comment, highlight the correct arrow.
|
|
||||||
if (comment.vote) {
|
|
||||||
var direction = (comment.vote == 1) ? 'u' : 'd';
|
|
||||||
div.find('#' + direction + 'v' + comment.id).hide();
|
|
||||||
div.find('#' + direction + 'u' + comment.id).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.moderator || comment.text != '[deleted]') {
|
|
||||||
div.find('a.reply').show();
|
|
||||||
if (comment.proposal_diff)
|
|
||||||
div.find('#sp' + comment.id).show();
|
|
||||||
if (opts.moderator && !comment.displayed)
|
|
||||||
div.find('#cm' + comment.id).show();
|
|
||||||
if (opts.moderator || (opts.username == comment.username))
|
|
||||||
div.find('#dc' + comment.id).show();
|
|
||||||
}
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple template renderer. Placeholders such as <%id%> are replaced
|
|
||||||
* by context['id'] with items being escaped. Placeholders such as <#id#>
|
|
||||||
* are not escaped.
|
|
||||||
*/
|
|
||||||
function renderTemplate(template, context) {
|
|
||||||
var esc = $(document.createElement('div'));
|
|
||||||
|
|
||||||
function handle(ph, escape) {
|
|
||||||
var cur = context;
|
|
||||||
$.each(ph.split('.'), function() {
|
|
||||||
cur = cur[this];
|
|
||||||
});
|
|
||||||
return escape ? esc.text(cur || "").html() : cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
|
|
||||||
return handle(arguments[2], arguments[1] == '%' ? true : false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Flash an error message briefly. */
|
|
||||||
function showError(message) {
|
|
||||||
$(document.createElement('div')).attr({'class': 'popup-error'})
|
|
||||||
.append($(document.createElement('div'))
|
|
||||||
.attr({'class': 'error-message'}).text(message))
|
|
||||||
.appendTo('body')
|
|
||||||
.fadeIn("slow")
|
|
||||||
.delay(2000)
|
|
||||||
.fadeOut("slow");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Add a link the user uses to open the comments popup. */
|
|
||||||
$.fn.comment = function() {
|
|
||||||
return this.each(function() {
|
|
||||||
var id = $(this).attr('id').substring(1);
|
|
||||||
var count = COMMENT_METADATA[id];
|
|
||||||
var title = count + ' comment' + (count == 1 ? '' : 's');
|
|
||||||
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
|
|
||||||
var addcls = count == 0 ? ' nocomment' : '';
|
|
||||||
$(this)
|
|
||||||
.append(
|
|
||||||
$(document.createElement('a')).attr({
|
|
||||||
href: '#',
|
|
||||||
'class': 'sphinx-comment-open' + addcls,
|
|
||||||
id: 'ao' + id
|
|
||||||
})
|
|
||||||
.append($(document.createElement('img')).attr({
|
|
||||||
src: image,
|
|
||||||
alt: 'comment',
|
|
||||||
title: title
|
|
||||||
}))
|
|
||||||
.click(function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
show($(this).attr('id').substring(2));
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
$(document.createElement('a')).attr({
|
|
||||||
href: '#',
|
|
||||||
'class': 'sphinx-comment-close hidden',
|
|
||||||
id: 'ah' + id
|
|
||||||
})
|
|
||||||
.append($(document.createElement('img')).attr({
|
|
||||||
src: opts.closeCommentImage,
|
|
||||||
alt: 'close',
|
|
||||||
title: 'close'
|
|
||||||
}))
|
|
||||||
.click(function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
hide($(this).attr('id').substring(2));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var opts = {
|
|
||||||
processVoteURL: '/_process_vote',
|
|
||||||
addCommentURL: '/_add_comment',
|
|
||||||
getCommentsURL: '/_get_comments',
|
|
||||||
acceptCommentURL: '/_accept_comment',
|
|
||||||
deleteCommentURL: '/_delete_comment',
|
|
||||||
commentImage: '/static/_static/comment.png',
|
|
||||||
closeCommentImage: '/static/_static/comment-close.png',
|
|
||||||
loadingImage: '/static/_static/ajax-loader.gif',
|
|
||||||
commentBrightImage: '/static/_static/comment-bright.png',
|
|
||||||
upArrow: '/static/_static/up.png',
|
|
||||||
downArrow: '/static/_static/down.png',
|
|
||||||
upArrowPressed: '/static/_static/up-pressed.png',
|
|
||||||
downArrowPressed: '/static/_static/down-pressed.png',
|
|
||||||
voting: false,
|
|
||||||
moderator: false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof COMMENT_OPTIONS != "undefined") {
|
|
||||||
opts = jQuery.extend(opts, COMMENT_OPTIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
var popupTemplate = '\
|
|
||||||
<div class="sphinx-comments" id="sc<%id%>">\
|
|
||||||
<p class="sort-options">\
|
|
||||||
Sort by:\
|
|
||||||
<a href="#" class="sort-option byrating">best rated</a>\
|
|
||||||
<a href="#" class="sort-option byascage">newest</a>\
|
|
||||||
<a href="#" class="sort-option byage">oldest</a>\
|
|
||||||
</p>\
|
|
||||||
<div class="comment-header">Comments</div>\
|
|
||||||
<div class="comment-loading" id="cn<%id%>">\
|
|
||||||
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
|
|
||||||
<ul id="cl<%id%>" class="comment-ul"></ul>\
|
|
||||||
<div id="ca<%id%>">\
|
|
||||||
<p class="add-a-comment">Add a comment\
|
|
||||||
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
|
|
||||||
<div class="comment-markup-box" id="mb<%id%>">\
|
|
||||||
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
|
|
||||||
<code>``code``</code>, \
|
|
||||||
code blocks: <code>::</code> and an indented block after blank line</div>\
|
|
||||||
<form method="post" id="cf<%id%>" class="comment-form" action="">\
|
|
||||||
<textarea name="comment" cols="80"></textarea>\
|
|
||||||
<p class="propose-button">\
|
|
||||||
<a href="#" id="pc<%id%>" class="show-propose-change">\
|
|
||||||
Propose a change ▹\
|
|
||||||
</a>\
|
|
||||||
<a href="#" id="hc<%id%>" class="hide-propose-change">\
|
|
||||||
Propose a change ▿\
|
|
||||||
</a>\
|
|
||||||
</p>\
|
|
||||||
<textarea name="proposal" id="pt<%id%>" cols="80"\
|
|
||||||
spellcheck="false"></textarea>\
|
|
||||||
<input type="submit" value="Add comment" />\
|
|
||||||
<input type="hidden" name="node" value="<%id%>" />\
|
|
||||||
<input type="hidden" name="parent" value="" />\
|
|
||||||
</form>\
|
|
||||||
</div>\
|
|
||||||
</div>';
|
|
||||||
|
|
||||||
var commentTemplate = '\
|
|
||||||
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
|
|
||||||
<div class="vote">\
|
|
||||||
<div class="arrow">\
|
|
||||||
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
|
|
||||||
<img src="<%upArrow%>" />\
|
|
||||||
</a>\
|
|
||||||
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
|
|
||||||
<img src="<%upArrowPressed%>" />\
|
|
||||||
</a>\
|
|
||||||
</div>\
|
|
||||||
<div class="arrow">\
|
|
||||||
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
|
|
||||||
<img src="<%downArrow%>" id="da<%id%>" />\
|
|
||||||
</a>\
|
|
||||||
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
|
|
||||||
<img src="<%downArrowPressed%>" />\
|
|
||||||
</a>\
|
|
||||||
</div>\
|
|
||||||
</div>\
|
|
||||||
<div class="comment-content">\
|
|
||||||
<p class="tagline comment">\
|
|
||||||
<span class="user-id"><%username%></span>\
|
|
||||||
<span class="rating"><%pretty_rating%></span>\
|
|
||||||
<span class="delta"><%time.delta%></span>\
|
|
||||||
</p>\
|
|
||||||
<div class="comment-text comment"><#text#></div>\
|
|
||||||
<p class="comment-opts comment">\
|
|
||||||
<a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\
|
|
||||||
<a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\
|
|
||||||
<a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\
|
|
||||||
<a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\
|
|
||||||
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
|
|
||||||
<span id="cm<%id%>" class="moderation hidden">\
|
|
||||||
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
|
|
||||||
</span>\
|
|
||||||
</p>\
|
|
||||||
<pre class="proposal" id="pr<%id%>">\
|
|
||||||
<#proposal_diff#>\
|
|
||||||
</pre>\
|
|
||||||
<ul class="comment-children" id="cl<%id%>"></ul>\
|
|
||||||
</div>\
|
|
||||||
<div class="clearleft"></div>\
|
|
||||||
</div>\
|
|
||||||
</div>';
|
|
||||||
|
|
||||||
var replyTemplate = '\
|
|
||||||
<li>\
|
|
||||||
<div class="reply-div" id="rd<%id%>">\
|
|
||||||
<form id="rf<%id%>">\
|
|
||||||
<textarea name="comment" cols="80"></textarea>\
|
|
||||||
<input type="submit" value="Add reply" />\
|
|
||||||
<input type="button" value="Cancel" />\
|
|
||||||
<input type="hidden" name="parent" value="<%id%>" />\
|
|
||||||
<input type="hidden" name="node" value="" />\
|
|
||||||
</form>\
|
|
||||||
</div>\
|
|
||||||
</li>';
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
init();
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
// add comment anchors for all paragraphs that are commentable
|
|
||||||
$('.sphinx-has-comment').comment();
|
|
||||||
|
|
||||||
// highlight search words in search results
|
|
||||||
$("div.context").each(function() {
|
|
||||||
var params = $.getQueryParameters();
|
|
||||||
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
|
|
||||||
var result = $(this);
|
|
||||||
$.each(terms, function() {
|
|
||||||
result.highlightText(this.toLowerCase(), 'highlighted');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// directly open comment window if requested
|
|
||||||
var anchor = document.location.hash;
|
|
||||||
if (anchor.substring(0, 9) == '#comment-') {
|
|
||||||
$('#ao' + anchor.substring(9)).click();
|
|
||||||
document.location.hash = '#s' + anchor.substring(9);
|
|
||||||
}
|
|
||||||
});
|
|
92
doc/build/html/genindex.html
vendored
@ -1,92 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
|
|
||||||
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
|
|
||||||
<title>Index — T-Pot 16.10 documentation</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var DOCUMENTATION_OPTIONS = {
|
|
||||||
URL_ROOT: './',
|
|
||||||
VERSION: '16.10',
|
|
||||||
COLLAPSE_INDEX: false,
|
|
||||||
FILE_SUFFIX: '.html',
|
|
||||||
HAS_SOURCE: true
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
|
||||||
<link rel="top" title="T-Pot 16.10 documentation" href="index.html" />
|
|
||||||
</head>
|
|
||||||
<body role="document">
|
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
|
||||||
<h3>Navigation</h3>
|
|
||||||
<ul>
|
|
||||||
<li class="right" style="margin-right: 10px">
|
|
||||||
<a href="#" title="General Index"
|
|
||||||
accesskey="I">index</a></li>
|
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">T-Pot 16.10 documentation</a> »</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="document">
|
|
||||||
<div class="documentwrapper">
|
|
||||||
<div class="bodywrapper">
|
|
||||||
<div class="body" role="main">
|
|
||||||
|
|
||||||
|
|
||||||
<h1 id="index">Index</h1>
|
|
||||||
|
|
||||||
<div class="genindex-jumpbox">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
||||||
<div class="sphinxsidebarwrapper">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div id="searchbox" style="display: none" role="search">
|
|
||||||
<h3>Quick search</h3>
|
|
||||||
<form class="search" action="search.html" method="get">
|
|
||||||
<input type="text" name="q" />
|
|
||||||
<input type="submit" value="Go" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
<p class="searchtip" style="font-size: 90%">
|
|
||||||
Enter search terms or a module, class or function name.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">$('#searchbox').show(0);</script>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clearer"></div>
|
|
||||||
</div>
|
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
|
||||||
<h3>Navigation</h3>
|
|
||||||
<ul>
|
|
||||||
<li class="right" style="margin-right: 10px">
|
|
||||||
<a href="#" title="General Index"
|
|
||||||
>index</a></li>
|
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">T-Pot 16.10 documentation</a> »</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="footer" role="contentinfo">
|
|
||||||
© Copyright 2016, t3chn0m4g3.
|
|
||||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
111
doc/build/html/index.html
vendored
@ -1,111 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
|
|
||||||
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
|
|
||||||
<title>Welcome to T-Pot’s documentation! — T-Pot 16.10 documentation</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var DOCUMENTATION_OPTIONS = {
|
|
||||||
URL_ROOT: './',
|
|
||||||
VERSION: '16.10',
|
|
||||||
COLLAPSE_INDEX: false,
|
|
||||||
FILE_SUFFIX: '.html',
|
|
||||||
HAS_SOURCE: true
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
|
||||||
<link rel="top" title="T-Pot 16.10 documentation" href="#" />
|
|
||||||
</head>
|
|
||||||
<body role="document">
|
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
|
||||||
<h3>Navigation</h3>
|
|
||||||
<ul>
|
|
||||||
<li class="right" style="margin-right: 10px">
|
|
||||||
<a href="genindex.html" title="General Index"
|
|
||||||
accesskey="I">index</a></li>
|
|
||||||
<li class="nav-item nav-item-0"><a href="#">T-Pot 16.10 documentation</a> »</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="document">
|
|
||||||
<div class="documentwrapper">
|
|
||||||
<div class="bodywrapper">
|
|
||||||
<div class="body" role="main">
|
|
||||||
|
|
||||||
<div class="section" id="welcome-to-t-pot-s-documentation">
|
|
||||||
<h1>Welcome to T-Pot’s documentation!<a class="headerlink" href="#welcome-to-t-pot-s-documentation" title="Permalink to this headline">¶</a></h1>
|
|
||||||
<p>Contents:</p>
|
|
||||||
<div class="toctree-wrapper compound">
|
|
||||||
<ul class="simple">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section" id="indices-and-tables">
|
|
||||||
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
|
|
||||||
<ul class="simple">
|
|
||||||
<li><a class="reference internal" href="genindex.html"><span>Index</span></a></li>
|
|
||||||
<li><a class="reference internal" href="py-modindex.html"><span>Module Index</span></a></li>
|
|
||||||
<li><a class="reference internal" href="search.html"><span>Search Page</span></a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
||||||
<div class="sphinxsidebarwrapper">
|
|
||||||
<h3><a href="#">Table Of Contents</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><a class="reference internal" href="#">Welcome to T-Pot’s documentation!</a></li>
|
|
||||||
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div role="note" aria-label="source link">
|
|
||||||
<h3>This Page</h3>
|
|
||||||
<ul class="this-page-menu">
|
|
||||||
<li><a href="_sources/index.txt"
|
|
||||||
rel="nofollow">Show Source</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div id="searchbox" style="display: none" role="search">
|
|
||||||
<h3>Quick search</h3>
|
|
||||||
<form class="search" action="search.html" method="get">
|
|
||||||
<input type="text" name="q" />
|
|
||||||
<input type="submit" value="Go" />
|
|
||||||
<input type="hidden" name="check_keywords" value="yes" />
|
|
||||||
<input type="hidden" name="area" value="default" />
|
|
||||||
</form>
|
|
||||||
<p class="searchtip" style="font-size: 90%">
|
|
||||||
Enter search terms or a module, class or function name.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">$('#searchbox').show(0);</script>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clearer"></div>
|
|
||||||
</div>
|
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
|
||||||
<h3>Navigation</h3>
|
|
||||||
<ul>
|
|
||||||
<li class="right" style="margin-right: 10px">
|
|
||||||
<a href="genindex.html" title="General Index"
|
|
||||||
>index</a></li>
|
|
||||||
<li class="nav-item nav-item-0"><a href="#">T-Pot 16.10 documentation</a> »</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="footer" role="contentinfo">
|
|
||||||
© Copyright 2016, t3chn0m4g3.
|
|
||||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
BIN
doc/build/html/objects.inv
vendored
99
doc/build/html/search.html
vendored
@ -1,99 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
|
|
||||||
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
|
|
||||||
<title>Search — T-Pot 16.10 documentation</title>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
|
|
||||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var DOCUMENTATION_OPTIONS = {
|
|
||||||
URL_ROOT: './',
|
|
||||||
VERSION: '16.10',
|
|
||||||
COLLAPSE_INDEX: false,
|
|
||||||
FILE_SUFFIX: '.html',
|
|
||||||
HAS_SOURCE: true
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
|
||||||
<script type="text/javascript" src="_static/searchtools.js"></script>
|
|
||||||
<link rel="top" title="T-Pot 16.10 documentation" href="index.html" />
|
|
||||||
<script type="text/javascript">
|
|
||||||
jQuery(function() { Search.loadIndex("searchindex.js"); });
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="text/javascript" id="searchindexloader"></script>
|
|
||||||
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body role="document">
|
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
|
||||||
<h3>Navigation</h3>
|
|
||||||
<ul>
|
|
||||||
<li class="right" style="margin-right: 10px">
|
|
||||||
<a href="genindex.html" title="General Index"
|
|
||||||
accesskey="I">index</a></li>
|
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">T-Pot 16.10 documentation</a> »</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="document">
|
|
||||||
<div class="documentwrapper">
|
|
||||||
<div class="bodywrapper">
|
|
||||||
<div class="body" role="main">
|
|
||||||
|
|
||||||
<h1 id="search-documentation">Search</h1>
|
|
||||||
<div id="fallback" class="admonition warning">
|
|
||||||
<script type="text/javascript">$('#fallback').hide();</script>
|
|
||||||
<p>
|
|
||||||
Please activate JavaScript to enable the search
|
|
||||||
functionality.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
From here you can search these documents. Enter your search
|
|
||||||
words into the box below and click "search". Note that the search
|
|
||||||
function will automatically search for all of the words. Pages
|
|
||||||
containing fewer words won't appear in the result list.
|
|
||||||
</p>
|
|
||||||
<form action="" method="get">
|
|
||||||
<input type="text" name="q" value="" />
|
|
||||||
<input type="submit" value="search" />
|
|
||||||
<span id="search-progress" style="padding-left: 10px"></span>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="search-results">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
||||||
<div class="sphinxsidebarwrapper">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="clearer"></div>
|
|
||||||
</div>
|
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
|
||||||
<h3>Navigation</h3>
|
|
||||||
<ul>
|
|
||||||
<li class="right" style="margin-right: 10px">
|
|
||||||
<a href="genindex.html" title="General Index"
|
|
||||||
>index</a></li>
|
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">T-Pot 16.10 documentation</a> »</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="footer" role="contentinfo">
|
|
||||||
© Copyright 2016, t3chn0m4g3.
|
|
||||||
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.3.6.
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
1
doc/build/html/searchindex.js
vendored
@ -1 +0,0 @@
|
|||||||
Search.setIndex({envversion:46,filenames:["index"],objects:{},objnames:{},objtypes:{},terms:{content:0,index:0,modul:0,page:0,search:0},titles:["Welcome to T-Pot’s documentation!"],titleterms:{document:0,indic:0,pot:0,tabl:0,welcom:0}})
|
|
BIN
doc/cockpit1.png
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
doc/cockpit2.png
Normal file
After Width: | Height: | Size: 185 KiB |
BIN
doc/cockpit3.png
Normal file
After Width: | Height: | Size: 336 KiB |
BIN
doc/cyberchef.png
Normal file
After Width: | Height: | Size: 101 KiB |
2737
doc/dashboard.json
Before Width: | Height: | Size: 594 KiB After Width: | Height: | Size: 368 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 127 KiB |