Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49c2250900 | ||
|
|
a6d70cd8a6 | ||
|
|
ed6d8e0d34 | ||
|
|
c0f37ceb08 | ||
|
|
d2160f388d | ||
|
|
1617bd521a | ||
|
|
15e475d667 | ||
|
|
ed779fd026 | ||
|
|
214634606f | ||
|
|
afaecef2d7 | ||
|
|
c76920f531 | ||
|
|
1657823988 | ||
|
|
df9c7928ae | ||
|
|
f44710c0f1 | ||
|
|
adbfe2fdef | ||
|
|
910198ffc3 | ||
|
|
19a172347f | ||
|
|
ccf00d17f6 | ||
|
|
1ac01637ef | ||
|
|
3861de61aa | ||
|
|
549686b9ef | ||
|
|
c484fd5136 | ||
|
|
1f3cb33bd2 | ||
|
|
438628c773 | ||
|
|
aeac132b09 | ||
|
|
8664186f7c | ||
|
|
07e716c95f | ||
|
|
092b9ed4e8 | ||
|
|
2ae578a010 | ||
|
|
df14029aa9 | ||
|
|
4b3c44cc18 | ||
|
|
859df3cb04 | ||
|
|
51485fcabb | ||
|
|
43d2dcb81c | ||
|
|
9d020beff0 | ||
|
|
02af143025 | ||
|
|
826bf7f540 | ||
|
|
8f4b72d551 | ||
|
|
67dbfc8569 | ||
|
|
71c7a38297 | ||
|
|
7c3ba76494 | ||
|
|
a223f1e722 | ||
|
|
a71d0b5a55 | ||
|
|
37cb8c3898 | ||
|
|
c3b4fffd17 | ||
|
|
b3c917f456 | ||
|
|
7f58398a43 | ||
|
|
777eb0c4a2 | ||
|
|
9c69443e2f | ||
|
|
440f68529c | ||
|
|
50706f9286 | ||
|
|
44e3434b6d | ||
|
|
a096631ab0 | ||
|
|
25ee8ab83b | ||
|
|
28a9fdcdc8 | ||
|
|
ee12d11709 | ||
|
|
6db083584e | ||
|
|
d833c9b441 | ||
|
|
7c2e77dbc5 | ||
|
|
2e0dcb9b00 | ||
|
|
6063ce9fcb | ||
|
|
2d6c2e8f9c | ||
|
|
e6b9427b3a | ||
|
|
6a0a53ce7e | ||
|
|
5cec4d5c82 | ||
|
|
0d403c9c8f | ||
|
|
c1e66ba5a7 | ||
|
|
94c3d7d2e2 | ||
|
|
202cfdb628 | ||
|
|
d9176781ab | ||
|
|
0979dc67e8 | ||
|
|
2e02f6d274 | ||
|
|
3893f057e1 | ||
|
|
7a25982022 | ||
|
|
824abad8e5 | ||
|
|
94239e2e44 | ||
|
|
72f1d1c43a | ||
|
|
a026da484f | ||
|
|
2e5c5efde7 | ||
|
|
72edb784db | ||
|
|
53c66ed216 | ||
|
|
f510735231 | ||
|
|
e6ea2737c0 | ||
|
|
65e84830a2 | ||
|
|
687decec5f | ||
|
|
967ca42c6b | ||
|
|
457f861ee0 | ||
|
|
572a8d82b0 | ||
|
|
0cbf7bb65a | ||
|
|
647c997a21 | ||
|
|
1575e2976b | ||
|
|
9198799caa | ||
|
|
e766058c57 | ||
|
|
d7c758ccd5 | ||
|
|
ed3f29b824 | ||
|
|
789bd8fd70 | ||
|
|
c4f11af537 | ||
|
|
fe939bc073 | ||
|
|
ae18a12894 | ||
|
|
0f51e27a14 | ||
|
|
3409849c4a | ||
|
|
72900d7df6 | ||
|
|
2dae8ff902 | ||
|
|
b1dbaf1d6d | ||
|
|
7bd49e6de1 | ||
|
|
a63bf8c39a | ||
|
|
8e14e0c82f | ||
|
|
e631259caa | ||
|
|
ff7b6a52e6 | ||
|
|
f336d977ef | ||
|
|
3b9d2c8c37 | ||
|
|
22699b9d6b | ||
|
|
2468e8ca6b | ||
|
|
dfad245187 | ||
|
|
3d2bc25355 | ||
|
|
1f4095fa65 | ||
|
|
6898193218 | ||
|
|
fccf4fcd5b | ||
|
|
183b142203 | ||
|
|
70e87ff5d6 | ||
|
|
77174243ed | ||
|
|
db4136ef62 | ||
|
|
220ca5a0a2 | ||
|
|
9bdf449d38 | ||
|
|
e2be44ad78 | ||
|
|
3913a77265 | ||
|
|
f395469a09 | ||
|
|
0101516935 | ||
|
|
d726fca5d0 | ||
|
|
39902363ab | ||
|
|
4b93a7e3a1 | ||
|
|
9152fca0c9 | ||
|
|
e5393b2127 | ||
|
|
034939a0c5 | ||
|
|
d35c6bb02f | ||
|
|
56746d9c01 | ||
|
|
b2fe702d51 | ||
|
|
c6282d5660 | ||
|
|
a2851b2787 | ||
|
|
26f41228db | ||
|
|
f5cb06ea53 | ||
|
|
a16441e87d | ||
|
|
3b4601e083 | ||
|
|
556f8175e8 | ||
|
|
13d6128e39 | ||
|
|
3bd56d161a | ||
|
|
eed88c721e | ||
|
|
0fbb507b07 | ||
|
|
57516929c1 | ||
|
|
a8d6a7eaf2 | ||
|
|
49022b2f57 | ||
|
|
a7cd64a54c | ||
|
|
db4a7af2b5 | ||
|
|
c746876026 | ||
|
|
7578aa32ae | ||
|
|
9cae0dc4ab | ||
|
|
cc97c6299d | ||
|
|
e6e0f7dea7 | ||
|
|
bdfcf9179d | ||
|
|
cdb50b681f | ||
|
|
8ca50abb0c | ||
|
|
0196a7a622 | ||
|
|
835a575535 | ||
|
|
d54d123850 | ||
|
|
83f033427d | ||
|
|
de8242e5e5 | ||
|
|
8f416db0ad | ||
|
|
2323cbdf77 | ||
|
|
925bb15d7b | ||
|
|
50e18bb3d9 | ||
|
|
c15b97f2ba | ||
|
|
f367f10d02 | ||
|
|
9ee3e2a88e | ||
|
|
5e0f877d20 | ||
|
|
6e3d9e6983 | ||
|
|
b1d04333bf | ||
|
|
1af55a1dd3 | ||
|
|
5f9cee95e6 | ||
|
|
f139587464 | ||
|
|
0f2ee7ae54 | ||
|
|
eff62918ba | ||
|
|
345808c200 | ||
|
|
15eabc51cb | ||
|
|
a7c6a89583 | ||
|
|
5acba5ad76 | ||
|
|
40f782c602 | ||
|
|
1c0ac62b4f | ||
|
|
3d13ab9096 | ||
|
|
29bdbf0d5e | ||
|
|
555fdb4ff0 | ||
|
|
541d74fc71 | ||
|
|
aee77b2ec6 | ||
|
|
fdbc8ad689 | ||
|
|
3200412e0b | ||
|
|
39af5b6702 | ||
|
|
c18f3c11f6 | ||
|
|
f5e55d4f58 | ||
|
|
2438d2ab61 | ||
|
|
7bd906d374 | ||
|
|
6a326649f9 | ||
|
|
72636d598f | ||
|
|
bd6635ee09 | ||
|
|
ef9bb2c4a6 | ||
|
|
f8f892e323 | ||
|
|
7eeec1625b | ||
|
|
26a33573fd | ||
|
|
72c7044465 | ||
|
|
5191c711c3 | ||
|
|
6a536c14fd | ||
|
|
63a965f978 | ||
|
|
e2b4c330fc | ||
|
|
02431fdd9e | ||
|
|
7a8bd83ab8 | ||
|
|
3475dd5036 | ||
|
|
8771059682 | ||
|
|
48990384df | ||
|
|
0c84f0da80 | ||
|
|
a1d701cd9f | ||
|
|
b23315f19b | ||
|
|
0ee844ee5b | ||
|
|
0d4d20553d | ||
|
|
457a86b742 | ||
|
|
3482d5cb3e | ||
|
|
4ce30ff46e | ||
|
|
bceec90de4 | ||
|
|
3e396f9e60 | ||
|
|
9370884eb5 | ||
|
|
8627925274 | ||
|
|
2bfb240c7f | ||
|
|
acbf965f94 | ||
|
|
74800f70bc | ||
|
|
003c8f856c | ||
|
|
29c3557c66 | ||
|
|
f7f8a5042a | ||
|
|
19911de04f | ||
|
|
954df1b522 | ||
|
|
e1d6a16672 | ||
|
|
536138b9ce | ||
|
|
33e311f98e | ||
|
|
66c542dbc8 | ||
|
|
bd333d9854 | ||
|
|
ecad6fe891 | ||
|
|
f709bef197 | ||
|
|
980392b811 | ||
|
|
497217446b | ||
|
|
f82c66a6bd | ||
|
|
e1c10caf81 | ||
|
|
bdea272028 | ||
|
|
e6e6dab8f6 | ||
|
|
03655f16eb | ||
|
|
b11f8793e3 | ||
|
|
595219da19 | ||
|
|
735aa7224b | ||
|
|
8a522c43e5 | ||
|
|
c5b6df846b | ||
|
|
4326e2c7ca | ||
|
|
d899e332e0 | ||
|
|
0eeedf22ea | ||
|
|
c56e487e8d | ||
|
|
0d753f0c9d | ||
|
|
9a3855f2df | ||
|
|
7d4a0bb1d4 | ||
|
|
49be7f3779 | ||
|
|
01288d2fa9 | ||
|
|
527a1a70c8 | ||
|
|
cfe1b29518 | ||
|
|
c0335f0936 | ||
|
|
f1156b221d | ||
|
|
43c260522c | ||
|
|
2272242493 | ||
|
|
4bc68d1f17 | ||
|
|
3f0957e3df | ||
|
|
77c5ead2b6 | ||
|
|
19674add02 | ||
|
|
064bd1a810 | ||
|
|
1f11d6b622 | ||
|
|
e5374afee3 | ||
|
|
c874c3e6b2 | ||
|
|
bdc5c7b85c | ||
|
|
9b55c92dc2 | ||
|
|
b838831970 | ||
|
|
21fcf429b6 | ||
|
|
8d19106412 | ||
|
|
4b6460bd5b | ||
|
|
5c5cddd1bf | ||
|
|
5b6db26617 | ||
|
|
a40fc46f47 | ||
|
|
490daa14de | ||
|
|
a022ea419f | ||
|
|
54c6ab3f08 | ||
|
|
83a9accf0f | ||
|
|
956e3b3ca2 | ||
|
|
83cf0c2604 | ||
|
|
7999108b91 | ||
|
|
b80de25598 | ||
|
|
7c25ae0ec2 | ||
|
|
84e9c4a484 | ||
|
|
5178e11e44 | ||
|
|
0e7c2769c8 | ||
|
|
6651a706b7 | ||
|
|
a81f922592 | ||
|
|
2b87887054 | ||
|
|
7859bfb451 | ||
|
|
35369f8f41 | ||
|
|
a47166d547 | ||
|
|
457a69b34a | ||
|
|
881f571902 | ||
|
|
d889c3305f | ||
|
|
cb793d5f3f | ||
|
|
b4882aa0fc | ||
|
|
ef3b5b2a6c | ||
|
|
d4501b736b | ||
|
|
261e24390f | ||
|
|
10abbd7efd | ||
|
|
e2196735d9 | ||
|
|
dbbc243359 | ||
|
|
94bb8e31cf | ||
|
|
282bcccf39 | ||
|
|
886f6c2369 | ||
|
|
ab822f0572 | ||
|
|
4ec2355182 | ||
|
|
a4237ca213 | ||
|
|
4615b70c60 | ||
|
|
97b9d12769 | ||
|
|
35a7c2d96f | ||
|
|
11ea1e2e1f | ||
|
|
1860dda320 | ||
|
|
5610b1b1da | ||
|
|
422dea0e3f | ||
|
|
d52a355cc9 | ||
|
|
389d87c2b5 | ||
|
|
7ef8322731 | ||
|
|
d1a0b32bf6 | ||
|
|
295cb399e3 | ||
|
|
db9477c22e | ||
|
|
b2ae6b67d6 | ||
|
|
bf5f0cecff | ||
|
|
251503952d | ||
|
|
60445a565d | ||
|
|
6a8db02aa7 | ||
|
|
ac50b335c3 | ||
|
|
c9826d5daf | ||
|
|
ada8225e05 | ||
|
|
613ca4bce0 | ||
|
|
1bdfb0625a | ||
|
|
ad2e33fcd2 | ||
|
|
6e846a4a51 | ||
|
|
dc76f0ca33 | ||
|
|
c619f00c54 | ||
|
|
015b132b85 | ||
|
|
4e4b4ad308 | ||
|
|
1226caaa39 | ||
|
|
5a92027f20 | ||
|
|
ea6ed08461 | ||
|
|
009231bbcf | ||
|
|
d6fa8ca2a5 | ||
|
|
e3bfca777d | ||
|
|
292fb9362a | ||
|
|
f68a8c88d7 | ||
|
|
4175a71547 | ||
|
|
0a5680de12 | ||
|
|
b3df13210d | ||
|
|
55c9cb8856 | ||
|
|
740ad102ea | ||
|
|
1af0097673 | ||
|
|
b86a2f4243 | ||
|
|
9500e4a39d | ||
|
|
73b5d91ddc | ||
|
|
645cf21898 | ||
|
|
04e4e5a9dd | ||
|
|
3d215ba96d | ||
|
|
9b7722f847 | ||
|
|
040a6c0ed1 | ||
|
|
ef2a04e886 | ||
|
|
e656c64fee | ||
|
|
0ee24a763a | ||
|
|
26120018c6 | ||
|
|
ae78b0aa8c | ||
|
|
3cca69ae9f | ||
|
|
422460c422 | ||
|
|
47a60b3465 | ||
|
|
701ff6f817 | ||
|
|
385fa4bb5d | ||
|
|
f410727d42 | ||
|
|
f9baee0a4a | ||
|
|
c97e1ad3a7 | ||
|
|
deaa193478 | ||
|
|
e290af5403 | ||
|
|
f6f160883c | ||
|
|
0a2f8c9765 | ||
|
|
788a672e74 | ||
|
|
2a078d3290 | ||
|
|
03d3761805 | ||
|
|
6d16ae5767 | ||
|
|
66c9828b68 | ||
|
|
cf2ea6e16c | ||
|
|
b2533943ed | ||
|
|
5c9ccd9bd2 | ||
|
|
fa48db5f1b | ||
|
|
79a45082c1 | ||
|
|
7998afb78a | ||
|
|
492f875205 | ||
|
|
5e767fde08 | ||
|
|
15acc8c67c | ||
|
|
6234188ceb | ||
|
|
36842c8b2c | ||
|
|
089de80c59 | ||
|
|
c60e9aabcd | ||
|
|
3195f915f5 | ||
|
|
24191e082a | ||
|
|
c2745a5f16 | ||
|
|
7d03e6ddf3 | ||
|
|
77cfc12013 | ||
|
|
0bf9c06ef2 | ||
|
|
d2b40b3399 | ||
|
|
482f4072c7 | ||
|
|
4879fee9a8 | ||
|
|
51307c31f8 | ||
|
|
db451b630c | ||
|
|
400ea68cc9 | ||
|
|
078c755684 | ||
|
|
f17c89605f | ||
|
|
5f961febac | ||
|
|
1fb2c3ed5d | ||
|
|
acc6cd0c73 | ||
|
|
4e27082225 | ||
|
|
6563bb0044 | ||
|
|
d4b2a1214e | ||
|
|
097fb3b4cb | ||
|
|
f3f69767a1 | ||
|
|
dc149ac022 | ||
|
|
37cde7a7af | ||
|
|
e320104fb8 | ||
|
|
af4ad33031 | ||
|
|
2038111a11 | ||
|
|
3481e660a3 | ||
|
|
4651bf782c | ||
|
|
608a78ac67 | ||
|
|
4a12128315 | ||
|
|
746b3295cb | ||
|
|
3d42cf67d7 | ||
|
|
b7f5b7b5e5 | ||
|
|
5e548f7899 | ||
|
|
fb68ad7705 | ||
|
|
e959ae2494 | ||
|
|
3a6e84119f | ||
|
|
4f3f7a70a9 | ||
|
|
e1bf1e306d | ||
|
|
c9333a3023 | ||
|
|
840fd5243a | ||
|
|
dde8fb3202 | ||
|
|
0f5ef505d0 | ||
|
|
1673a23455 | ||
|
|
b4b16ada27 | ||
|
|
a4d75bfc04 | ||
|
|
61bd4f799b | ||
|
|
002a3ea79e | ||
|
|
5dce56357b | ||
|
|
89ab800565 | ||
|
|
349741b31b | ||
|
|
725b398da9 | ||
|
|
ce9f53dddb | ||
|
|
fc37413d91 | ||
|
|
ba39c39622 | ||
|
|
6c5ee78b18 | ||
|
|
eafa575e8e | ||
|
|
a3dd458cb2 | ||
|
|
c5cb8b65f3 | ||
|
|
994b93852e | ||
|
|
912eda2cb8 | ||
|
|
0461fabab0 | ||
|
|
0324872499 | ||
|
|
5877644570 | ||
|
|
f292fdd354 | ||
|
|
85ce4dc462 | ||
|
|
a9d3aa4962 | ||
|
|
9a562934e5 | ||
|
|
784304f639 | ||
|
|
582792c2bf | ||
|
|
946523a73d | ||
|
|
39021dca1e | ||
|
|
e240ef713b | ||
|
|
2b1f88ae0f | ||
|
|
8259823451 | ||
|
|
05109a500d | ||
|
|
78b156aeed | ||
|
|
39789bcc33 | ||
|
|
310c8a57e7 | ||
|
|
3b947d6446 | ||
|
|
d163c84916 | ||
|
|
ef43ceab48 | ||
|
|
665952869a | ||
|
|
942a1fbf1a | ||
|
|
0c05f87acd | ||
|
|
ef856a1420 | ||
|
|
0ea666bb7c | ||
|
|
5fc3a8607f | ||
|
|
163ca52b7f | ||
|
|
dbcf62edb1 | ||
|
|
6e1ef774df | ||
|
|
84e646dbe4 | ||
|
|
705ea56813 | ||
|
|
91ae7244b0 | ||
|
|
1539504258 | ||
|
|
1ef899d11e | ||
|
|
e36df4fff5 | ||
|
|
76a1fed75d | ||
|
|
338ccef6d6 | ||
|
|
1fa7fbda45 | ||
|
|
4459d296eb | ||
|
|
a9f7a47022 | ||
|
|
e1e69a4677 | ||
|
|
6827de3f67 | ||
|
|
bffd4c1150 | ||
|
|
ad44c255cb | ||
|
|
c884197f2e | ||
|
|
1bc335d715 | ||
|
|
a10f5a3337 | ||
|
|
c2c413a9ef | ||
|
|
c9eea53ff5 | ||
|
|
e176ac2e8d | ||
|
|
522f9f22e4 | ||
|
|
8fded1c678 | ||
|
|
2b0782f125 | ||
|
|
f7c2e38a5e | ||
|
|
93d3fc3cef | ||
|
|
0e200e8c12 | ||
|
|
28ddb57c8e | ||
|
|
348ecd938e | ||
|
|
6de200a294 | ||
|
|
8b0dc43f74 | ||
|
|
e14d8109f2 | ||
|
|
ea8b829c6e | ||
|
|
faf637aae1 | ||
|
|
bb69c92a9c | ||
|
|
3886888843 | ||
|
|
1bd0a38f6b | ||
|
|
ac7fe66734 | ||
|
|
3365ab9a49 | ||
|
|
3cfaa5361f | ||
|
|
43800b6578 | ||
|
|
0891e206d5 | ||
|
|
8f6aae7e4c | ||
|
|
d860405b16 | ||
|
|
df4f1aa28b | ||
|
|
b464c848a9 | ||
|
|
04780d8094 | ||
|
|
e41604499a | ||
|
|
ef90ba7aab | ||
|
|
b5954be201 | ||
|
|
5d7b37cb18 | ||
|
|
71026d74e9 | ||
|
|
d656d07487 | ||
|
|
3bf395c86f | ||
|
|
f841a89940 | ||
|
|
287de96277 | ||
|
|
860bcd0c9d | ||
|
|
73f6354332 | ||
|
|
9770821628 | ||
|
|
dff57a4b13 | ||
|
|
cfed5e813d | ||
|
|
2518e53abc | ||
|
|
bf970dbd02 | ||
|
|
aa583e4586 | ||
|
|
07a33f1a5f | ||
|
|
bd1eff9fc8 | ||
|
|
ded6dad023 | ||
|
|
52f7bdd65d | ||
|
|
6874bfc059 | ||
|
|
bef439ce55 | ||
|
|
726c684a94 |
@@ -116,6 +116,10 @@ data/iplist.txt
|
||||
data/json/index.json
|
||||
data/json/config.json
|
||||
data/site.pl
|
||||
data/admin_path.pl
|
||||
data/close.pl
|
||||
data/admin_path.pl
|
||||
data/close.pl
|
||||
ssl/input.pl
|
||||
data/datadir.pl
|
||||
data/502Task.pl
|
||||
data/default.pl
|
||||
data/backup.pl
|
||||
|
||||
@@ -1,7 +1,46 @@
|
||||
# mdserver-web
|
||||
简单的Linux面板
|
||||
### mdserver-web 0.8.0
|
||||
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
|
||||
复制了后台管理界面,按照自己想要的方式写了一版。
|
||||
|
||||
* ssh工具优化
|
||||
* 面板收藏功能完成
|
||||
* 网站子目录绑定
|
||||
* 网站备份功能
|
||||
* 自动更新优化
|
||||
* 插件方式管理
|
||||
|
||||
基本上可以使用,后续会继续优化!欢迎提供意见!
|
||||
|
||||
### 主要插件介绍
|
||||
* OpenResty - 轻量级,占有内存少,并发能力强。
|
||||
* PHP[53-74] - PHP是世界上最好的编程语言。
|
||||
* MySQL - MySQL是一种关系数据库管理系统。
|
||||
* phpMyAdmin - 著名Web端MySQL管理工具。
|
||||
* Memcached - 一个高性能的分布式内存对象缓存系统。
|
||||
* Redis - 一个高性能的key-value数据库。
|
||||
* CSVN - 最流行的SVN代码共享管理软件。
|
||||
* PureFtpd - 一款专注于程序健壮和软件安全的免费FTP服务器软件。
|
||||
* Gogs - 一款极易搭建的自助Git服务。
|
||||
* Rsyncd - 通用同步服务。
|
||||
|
||||
### 版本更新 0.8.0
|
||||
* 添加PHP74版本
|
||||
* 优化PHP及扩展安装脚本
|
||||
|
||||
### 自动安装
|
||||
```
|
||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | sh
|
||||
```
|
||||
```
|
||||
|
||||
### 更新
|
||||
|
||||
```
|
||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | sh
|
||||
```
|
||||
|
||||
### 无图不真相
|
||||
[](/route/static/mdw.jpg)
|
||||
|
||||
### wiki
|
||||
[了解更多...](https://github.com/midoks/mdserver-web/wiki)
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ def initInitD():
|
||||
import shutil
|
||||
shutil.copyfile(script_bin, initd_bin)
|
||||
public.execShell('chmod +x ' + initd_bin)
|
||||
#加入自启动
|
||||
public.execShell('chkconfig --add mw')
|
||||
|
||||
|
||||
def initUserInfo():
|
||||
|
||||
@@ -15,7 +15,9 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.0.5'
|
||||
# 本版解决自启动问题
|
||||
# 文件管理重命名
|
||||
__version = '0.8.0'
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -64,14 +66,14 @@ class config_api:
|
||||
isSave = public.M('panel').where(
|
||||
'(title=? OR url=?) AND id!=?', (title, url, mid)).count()
|
||||
if isSave:
|
||||
return public.returnMsg(False, '备注或面板地址重复!')
|
||||
return public.returnJson(False, '备注或面板地址重复!')
|
||||
|
||||
# 更新到数据库
|
||||
isRe = public.M('panel').where('id=?', (mid,)).save(
|
||||
'title,url,username,password', (title, url, username, password))
|
||||
if isRe:
|
||||
return public.returnMsg(True, '修改成功!')
|
||||
return public.returnMsg(False, '修改失败!')
|
||||
return public.returnJson(True, '修改成功!')
|
||||
return public.returnJson(False, '修改失败!')
|
||||
|
||||
def syncDateApi(self):
|
||||
if public.isAppleSystem():
|
||||
|
||||
@@ -13,6 +13,7 @@ import shutil
|
||||
from flask import request
|
||||
from flask import send_file, send_from_directory
|
||||
from flask import make_response
|
||||
from flask import session
|
||||
|
||||
|
||||
class files_api:
|
||||
@@ -51,7 +52,7 @@ class files_api:
|
||||
if not os.path.exists(filename):
|
||||
return ''
|
||||
response = make_response(send_from_directory(
|
||||
os.path.dirname(filename), os.path.basename(filename), as_attachment=True))
|
||||
os.path.dirname(filename).encode('utf-8'), os.path.basename(filename).encode('utf-8'), as_attachment=True))
|
||||
return response
|
||||
|
||||
def zipApi(self):
|
||||
@@ -61,6 +62,27 @@ class files_api:
|
||||
path = request.form.get('path', '').encode('utf-8')
|
||||
return self.zip(sfile, dfile, stype, path)
|
||||
|
||||
# 移动文件或目录
|
||||
def mvFileApi(self):
|
||||
sfile = request.form.get('sfile', '').encode('utf-8')
|
||||
dfile = request.form.get('dfile', '').encode('utf-8')
|
||||
if not self.checkFileName(dfile):
|
||||
return public.returnJson(False, '文件名中不能包含特殊字符!')
|
||||
if not os.path.exists(sfile):
|
||||
return public.returnJson(False, '指定文件不存在!')
|
||||
|
||||
if not self.checkDir(sfile):
|
||||
return public.returnJson(False, 'FILE_DANGER')
|
||||
|
||||
import shutil
|
||||
try:
|
||||
shutil.move(sfile, dfile)
|
||||
msg = public.getInfo('移动文件或目录[{1}]到[{2}]成功!', (sfile, dfile,))
|
||||
public.writeLog('文件管理', msg)
|
||||
return public.returnJson(True, '移动文件或目录成功!')
|
||||
except:
|
||||
return public.returnJson(False, '移动文件或目录失败!')
|
||||
|
||||
def deleteApi(self):
|
||||
path = request.form.get('path', '').encode('utf-8')
|
||||
return self.delete(path)
|
||||
@@ -70,6 +92,32 @@ class files_api:
|
||||
data = self.getAccess(filename)
|
||||
return public.getJson(data)
|
||||
|
||||
def setFileAccessApi(self):
|
||||
|
||||
if public.isAppleSystem():
|
||||
return public.returnJson(True, '开发机不设置!')
|
||||
|
||||
filename = request.form.get('filename', '').encode('utf-8')
|
||||
user = request.form.get('user', '').encode('utf-8')
|
||||
access = request.form.get('access', '755')
|
||||
sall = '-R'
|
||||
try:
|
||||
if not self.checkDir(filename):
|
||||
return public.returnJson(False, '请不要花样作死')
|
||||
|
||||
if not os.path.exists(filename):
|
||||
return public.returnJson(False, '指定文件不存在!')
|
||||
|
||||
os.system('chmod ' + sall + ' ' + access + " '" + filename + "'")
|
||||
os.system('chown ' + sall + ' ' + user +
|
||||
':' + user + " '" + filename + "'")
|
||||
msg = public.getInfo(
|
||||
'设置[{1}]权限为[{2}]所有者为[{3}]', (filename, access, user,))
|
||||
public.writeLog('文件管理', msg)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
except:
|
||||
return public.returnJson(False, '设置失败!')
|
||||
|
||||
def getDirSizeApi(self):
|
||||
path = request.form.get('path', '').encode('utf-8')
|
||||
tmp = self.getDirSize(path)
|
||||
@@ -82,6 +130,10 @@ class files_api:
|
||||
search = request.args.get('search', '').strip().lower()
|
||||
page = request.args.get('p', '1').strip().lower()
|
||||
row = request.args.get('showRow', '10')
|
||||
disk = request.form.get('disk', '')
|
||||
if disk == 'True':
|
||||
row = 1000
|
||||
|
||||
return self.getDir(path, int(page), int(row), search)
|
||||
|
||||
def createFileApi(self):
|
||||
@@ -310,7 +362,7 @@ done
|
||||
if os.path.exists('data/recycle_bin.pl'):
|
||||
if self.mvRecycleBin(path):
|
||||
return public.returnJson(True, '已将文件移动到回收站!')
|
||||
os.remove(path)
|
||||
public.execShell('rm -rf ' + path)
|
||||
public.writeLog('文件管理', '删除文件成功!', (path,))
|
||||
return public.returnJson(True, '删除文件成功!')
|
||||
except:
|
||||
@@ -325,8 +377,189 @@ done
|
||||
tmp = self.getDirSize(logPath)
|
||||
return public.returnJson(True, tmp[0].split()[0])
|
||||
|
||||
def setBatchDataApi(self):
|
||||
path = request.form.get('path', '').encode('utf-8')
|
||||
stype = request.form.get('type', '').encode('utf-8')
|
||||
access = request.form.get('access', '').encode('utf-8')
|
||||
user = request.form.get('user', '').encode('utf-8')
|
||||
data = request.form.get('data')
|
||||
if stype == '1' or stype == '2':
|
||||
session['selected'] = {
|
||||
'path': path,
|
||||
'type': stype,
|
||||
'access': access,
|
||||
'user': user,
|
||||
'data': data
|
||||
}
|
||||
return public.returnJson(True, '标记成功,请在目标目录点击粘贴所有按钮!')
|
||||
elif stype == '3':
|
||||
for key in json.loads(data):
|
||||
try:
|
||||
key = key.encode('utf-8')
|
||||
filename = path + '/' + key
|
||||
if not self.checkDir(filename):
|
||||
return public.returnJson(False, 'FILE_DANGER')
|
||||
os.system('chmod -R ' + access + " '" + filename + "'")
|
||||
os.system('chown -R ' + user + ':' +
|
||||
user + " '" + filename + "'")
|
||||
except:
|
||||
continue
|
||||
public.writeLog('文件管理', '批量设置权限成功!')
|
||||
return public.returnJson(True, '批量设置权限成功!')
|
||||
else:
|
||||
import shutil
|
||||
isRecyle = os.path.exists('data/recycle_bin.pl')
|
||||
data = json.loads(data)
|
||||
l = len(data)
|
||||
i = 0
|
||||
for key in data:
|
||||
try:
|
||||
filename = path + '/' + key.encode('utf-8')
|
||||
topath = filename
|
||||
if not os.path.exists(filename):
|
||||
continue
|
||||
|
||||
i += 1
|
||||
public.writeSpeed(key, i, l)
|
||||
if os.path.isdir(filename):
|
||||
if not self.checkDir(filename):
|
||||
return public.returnJson(False, '请不要花样作死!')
|
||||
if isRecyle:
|
||||
self.mvRecycleBin(topath)
|
||||
else:
|
||||
shutil.rmtree(filename)
|
||||
else:
|
||||
if key == '.user.ini':
|
||||
os.system('which chattr && chattr -i ' + filename)
|
||||
if isRecyle:
|
||||
self.mvRecycleBin(topath)
|
||||
else:
|
||||
os.remove(filename)
|
||||
except:
|
||||
continue
|
||||
public.writeSpeed(None, 0, 0)
|
||||
public.writeLog('文件管理', '批量删除成功!')
|
||||
return public.returnJson(True, '批量删除成功!')
|
||||
|
||||
def checkExistsFilesApi(self):
|
||||
dfile = request.form.get('dfile', '').encode('utf-8')
|
||||
filename = request.form.get('filename', '').encode('utf-8')
|
||||
data = []
|
||||
filesx = []
|
||||
if filename == '':
|
||||
filesx = json.loads(session['selected']['data'])
|
||||
else:
|
||||
filesx.append(filename)
|
||||
|
||||
print filesx
|
||||
|
||||
for fn in filesx:
|
||||
if fn == '.':
|
||||
continue
|
||||
filename = dfile + '/' + fn
|
||||
if os.path.exists(filename):
|
||||
tmp = {}
|
||||
stat = os.stat(filename)
|
||||
tmp['filename'] = fn
|
||||
tmp['size'] = os.path.getsize(filename)
|
||||
tmp['mtime'] = str(int(stat.st_mtime))
|
||||
data.append(tmp)
|
||||
return public.returnJson(True, 'ok', data)
|
||||
|
||||
def batchPasteApi(self):
|
||||
path = request.form.get('path', '').encode('utf-8')
|
||||
stype = request.form.get('type', '').encode('utf-8')
|
||||
# filename = request.form.get('filename', '').encode('utf-8')
|
||||
import shutil
|
||||
if not self.checkDir(path):
|
||||
return public.returnJson(False, '请不要花样作死!')
|
||||
i = 0
|
||||
myfiles = json.loads(session['selected']['data'])
|
||||
l = len(myfiles)
|
||||
if stype == '1':
|
||||
for key in myfiles:
|
||||
i += 1
|
||||
public.writeSpeed(key, i, l)
|
||||
try:
|
||||
|
||||
sfile = session['selected'][
|
||||
'path'] + '/' + key.encode('utf-8')
|
||||
dfile = path + '/' + key.encode('utf-8')
|
||||
|
||||
if os.path.isdir(sfile):
|
||||
shutil.copytree(sfile, dfile)
|
||||
else:
|
||||
shutil.copyfile(sfile, dfile)
|
||||
stat = os.stat(sfile)
|
||||
os.chown(dfile, stat.st_uid, stat.st_gid)
|
||||
except:
|
||||
continue
|
||||
msg = public.getInfo('从[{1}]批量复制到[{2}]成功',
|
||||
(session['selected']['path'], path,))
|
||||
public.writeLog('文件管理', msg)
|
||||
else:
|
||||
for key in myfiles:
|
||||
try:
|
||||
i += 1
|
||||
public.writeSpeed(key, i, l)
|
||||
|
||||
sfile = session['selected'][
|
||||
'path'] + '/' + key.encode('utf-8')
|
||||
dfile = path + '/' + key.encode('utf-8')
|
||||
|
||||
shutil.move(sfile, dfile)
|
||||
except:
|
||||
continue
|
||||
msg = public.getInfo('从[{1}]批量移动到[{2}]成功',
|
||||
(session['selected']['path'], path,))
|
||||
public.writeLog('文件管理', msg)
|
||||
public.writeSpeed(None, 0, 0)
|
||||
errorCount = len(myfiles) - i
|
||||
del(session['selected'])
|
||||
msg = public.getInfo('批量操作成功[{1}],失败[{2}]', (str(i), str(errorCount)))
|
||||
return public.returnJson(True, msg)
|
||||
|
||||
def copyFileApi(self):
|
||||
sfile = request.form.get('sfile', '').encode('utf-8')
|
||||
dfile = request.form.get('dfile', '').encode('utf-8')
|
||||
|
||||
if not os.path.exists(sfile):
|
||||
return public.returnJson(False, '指定文件不存在!')
|
||||
|
||||
if os.path.isdir(sfile):
|
||||
return self.copyDir(sfile, dfile)
|
||||
|
||||
import shutil
|
||||
try:
|
||||
shutil.copyfile(sfile, dfile)
|
||||
msg = public.getInfo('复制文件[{1}]到[{2}]成功!', (sfile, dfile,))
|
||||
public.writeLog('文件管理', msg)
|
||||
stat = os.stat(sfile)
|
||||
os.chown(dfile, stat.st_uid, stat.st_gid)
|
||||
return public.returnJson(True, '文件复制成功!')
|
||||
except:
|
||||
return public.returnJson(False, '文件复制失败!')
|
||||
|
||||
##### ----- end ----- ###
|
||||
|
||||
def copyDir(self, sfile, dfile):
|
||||
|
||||
if not os.path.exists(sfile):
|
||||
return public.returnJson(False, '指定目录不存在!')
|
||||
|
||||
if os.path.exists(dfile):
|
||||
return public.returnJson(False, '指定目录已存在!')
|
||||
import shutil
|
||||
try:
|
||||
shutil.copytree(sfile, dfile)
|
||||
stat = os.stat(sfile)
|
||||
os.chown(dfile, stat.st_uid, stat.st_gid)
|
||||
msg = public.getInfo('复制目录[{1}]到[{2}]成功!', (sfile, dfile))
|
||||
public.writeLog('文件管理', msg)
|
||||
return public.returnJson(True, '目录复制成功!')
|
||||
except:
|
||||
return public.returnJson(False, '目录复制失败!')
|
||||
|
||||
# 检查敏感目录
|
||||
def checkDir(self, path):
|
||||
path = path.replace('//', '/')
|
||||
@@ -397,11 +630,11 @@ done
|
||||
try:
|
||||
import shutil
|
||||
shutil.move(path, rFile)
|
||||
public.writeLog('TYPE_FILE', public.getInfo(
|
||||
public.writeLog('文件管理', public.getInfo(
|
||||
'移动文件[{1}]到回收站成功!', (path)))
|
||||
return True
|
||||
except:
|
||||
public.writeLog('TYPE_FILE', public.getInfo(
|
||||
public.writeLog('文件管理', public.getInfo(
|
||||
'移动文件[{1}]到回收站失败!', (path)))
|
||||
return False
|
||||
|
||||
@@ -477,7 +710,7 @@ done
|
||||
fp.write(data)
|
||||
fp.close()
|
||||
|
||||
public.writeLog('TYPE_FILE', '文件保存成功', (path,))
|
||||
public.writeLog('文件管理', '文件保存成功', (path,))
|
||||
return public.returnJson(True, '文件保存成功')
|
||||
except Exception as ex:
|
||||
return public.returnJson(False, 'FILE_SAVE_ERR:' + str(ex))
|
||||
@@ -501,7 +734,7 @@ done
|
||||
os.system("cd '" + path + "' && tar -zcvf '" +
|
||||
dfile + "' " + sfiles + " > " + tmps + " 2>&1")
|
||||
self.setFileAccept(dfile)
|
||||
public.writeLog("TYPE_FILE", '文件压缩成功!', (sfile, dfile))
|
||||
public.writeLog("文件管理", '文件压缩成功!', (sfile, dfile))
|
||||
return public.returnJson(True, '文件压缩成功!')
|
||||
except:
|
||||
return public.returnJson(False, '文件压缩失败!')
|
||||
@@ -520,7 +753,7 @@ done
|
||||
if self.mvRecycleBin(path):
|
||||
return public.returnJson(True, '已将文件移动到回收站!')
|
||||
os.remove(path)
|
||||
public.writeLog('TYPE_FILE', public.getInfo(
|
||||
public.writeLog('文件管理', public.getInfo(
|
||||
'删除文件[{1}]成功!', (path)))
|
||||
return public.returnJson(True, '删除文件成功!')
|
||||
except:
|
||||
|
||||
@@ -289,6 +289,7 @@ class firewall_api:
|
||||
return
|
||||
if self.__isFirewalld:
|
||||
public.execShell('systemctl stop firewalld.service')
|
||||
public.execShell('systemctl disable firewalld.service')
|
||||
elif self.__isMac:
|
||||
pass
|
||||
else:
|
||||
@@ -300,6 +301,7 @@ class firewall_api:
|
||||
return
|
||||
if self.__isFirewalld:
|
||||
public.execShell('systemctl start firewalld.service')
|
||||
public.execShell('systemctl enable firewalld.service')
|
||||
elif self.__isMac:
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -98,10 +98,10 @@ class plugins_api:
|
||||
return public.returnJson(False, '缺少版本信息!', ())
|
||||
|
||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
||||
print infoJsonPos
|
||||
# print infoJsonPos
|
||||
|
||||
if not os.path.exists(infoJsonPos):
|
||||
return public.retJson(False, '配置文件不存在!', ())
|
||||
return public.returnJson(False, '配置文件不存在!', ())
|
||||
|
||||
pluginInfo = json.loads(public.readFile(infoJsonPos))
|
||||
|
||||
@@ -115,6 +115,34 @@ class plugins_api:
|
||||
public.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
|
||||
return public.returnJson(True, '已将安装任务添加到队列!')
|
||||
|
||||
def uninstallOldApi(self):
|
||||
rundir = public.getRunDir()
|
||||
name = request.form.get('name', '')
|
||||
version = request.form.get('version', '')
|
||||
if name.strip() == '':
|
||||
return public.returnJson(False, "缺少插件名称!", ())
|
||||
|
||||
if version.strip() == '':
|
||||
return public.returnJson(False, "缺少版本信息!", ())
|
||||
|
||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
||||
|
||||
if not os.path.exists(infoJsonPos):
|
||||
return public.returnJson(False, "配置文件不存在!", ())
|
||||
|
||||
pluginInfo = json.loads(public.readFile(infoJsonPos))
|
||||
|
||||
execstr = "cd " + os.getcwd() + "/plugins/" + \
|
||||
name + " && /bin/bash " + pluginInfo["shell"] \
|
||||
+ " uninstall " + version
|
||||
|
||||
taskAdd = (None, '卸载[' + name + '-' + version + ']',
|
||||
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
|
||||
|
||||
public.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
|
||||
return public.returnJson(True, '已将卸载任务添加到队列!')
|
||||
|
||||
# 卸载时间短,不加入任务中...
|
||||
def uninstallApi(self):
|
||||
rundir = public.getRunDir()
|
||||
name = request.form.get('name', '')
|
||||
@@ -128,7 +156,7 @@ class plugins_api:
|
||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
||||
|
||||
if not os.path.exists(infoJsonPos):
|
||||
return public.retJson(False, "配置文件不存在!", ())
|
||||
return public.returnJson(False, "配置文件不存在!", ())
|
||||
|
||||
pluginInfo = json.loads(public.readFile(infoJsonPos))
|
||||
|
||||
@@ -136,11 +164,15 @@ class plugins_api:
|
||||
name + " && /bin/bash " + pluginInfo["shell"] \
|
||||
+ " uninstall " + version
|
||||
|
||||
taskAdd = (None, '卸载[' + name + '-' + version + ']',
|
||||
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
|
||||
|
||||
public.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
|
||||
return public.returnJson(True, '已将卸载任务添加到队列!')
|
||||
data = public.execShell(execstr)
|
||||
if public.isAppleSystem():
|
||||
print execstr
|
||||
print data[0], data[1]
|
||||
return public.returnJson(True, '卸载执行成功!')
|
||||
# if data[1] == '':
|
||||
# return public.returnJson(True, '已将卸载成功!')
|
||||
# else:
|
||||
# return public.returnJson(False, '卸载出现错误信息!' + data[1])
|
||||
|
||||
def checkApi(self):
|
||||
name = request.form.get('name', '')
|
||||
@@ -177,6 +209,17 @@ class plugins_api:
|
||||
return public.returnJson(True, "OK", data[0].strip())
|
||||
return public.returnJson(False, data[1].strip())
|
||||
|
||||
def callbackApi(self):
|
||||
name = request.form.get('name', '')
|
||||
func = request.form.get('func', '')
|
||||
args = request.form.get('args', '')
|
||||
script = request.form.get('script', 'index')
|
||||
|
||||
data = self.callback(name, func, args, script)
|
||||
if data[0]:
|
||||
return public.returnJson(True, "OK", data[1])
|
||||
return public.returnJson(False, data[1])
|
||||
|
||||
def updateZipApi(self):
|
||||
tmp_path = public.getRootDir() + '/temp'
|
||||
if not os.path.exists(tmp_path):
|
||||
@@ -228,6 +271,9 @@ class plugins_api:
|
||||
except:
|
||||
public.execShell("rm -rf " + tmp_path)
|
||||
return public.returnJson(False, '在压缩包中没有找到插件信息,请检查插件包!')
|
||||
protectPlist = ('openresty', 'mysql', 'php', 'csvn', 'gogs', 'pureftp')
|
||||
if data['name'] in protectPlist:
|
||||
return public.returnJson(False, '[' + data['name'] + '],重要插件不可修改!')
|
||||
return public.getJson(data)
|
||||
|
||||
def inputZipApi(self):
|
||||
@@ -271,17 +317,10 @@ class plugins_api:
|
||||
return True
|
||||
|
||||
# 检查是否正在安装
|
||||
def checkSetupTask(self, sName):
|
||||
sName = ''
|
||||
version = ''
|
||||
def checkSetupTask(self, sName, sVer, sCoexist):
|
||||
if not self.__tasks:
|
||||
self.__tasks = public.M('tasks').where(
|
||||
"status!=?", ('1',)).field('status,name').select()
|
||||
|
||||
if sName.find('php-') != -1:
|
||||
tmp = sName.split('-')
|
||||
sName = tmp[0]
|
||||
version = tmp[1]
|
||||
isTask = '1'
|
||||
for task in self.__tasks:
|
||||
tmpt = public.getStrBetween('[', ']', task['name'])
|
||||
@@ -289,12 +328,10 @@ class plugins_api:
|
||||
continue
|
||||
tmp1 = tmpt.split('-')
|
||||
name1 = tmp1[0].lower()
|
||||
if sName == 'php':
|
||||
if name1 == sName and tmp1[1] == version:
|
||||
if sCoexist:
|
||||
if name1 == sName and tmp1[1] == sVer:
|
||||
isTask = task['status']
|
||||
else:
|
||||
if name1 == 'pure':
|
||||
name1 = 'pure-ftpd'
|
||||
if name1 == sName:
|
||||
isTask = task['status']
|
||||
return isTask
|
||||
@@ -410,7 +447,7 @@ class plugins_api:
|
||||
if info.has_key('coexist') and info['coexist']:
|
||||
coexist = True
|
||||
|
||||
pluginInfo = {
|
||||
pInfo = {
|
||||
"id": 10000,
|
||||
"pid": info['pid'],
|
||||
"type": 1000,
|
||||
@@ -431,29 +468,28 @@ class plugins_api:
|
||||
"status": False,
|
||||
}
|
||||
|
||||
pluginInfo['task'] = self.checkSetupTask(pluginInfo['name'])
|
||||
|
||||
if checks.find('VERSION') > -1:
|
||||
pluginInfo['install_checks'] = checks.replace(
|
||||
pInfo['install_checks'] = checks.replace(
|
||||
'VERSION', info['versions'])
|
||||
|
||||
if path.find('VERSION') > -1:
|
||||
pluginInfo['path'] = path.replace(
|
||||
pInfo['path'] = path.replace(
|
||||
'VERSION', info['versions'])
|
||||
|
||||
pluginInfo['display'] = self.checkDisplayIndex(
|
||||
info['name'], pluginInfo['versions'])
|
||||
pInfo['task'] = self.checkSetupTask(
|
||||
pInfo['name'], info['versions'], coexist)
|
||||
pInfo['display'] = self.checkDisplayIndex(
|
||||
info['name'], pInfo['versions'])
|
||||
|
||||
pluginInfo['setup'] = os.path.exists(pluginInfo['install_checks'])
|
||||
pInfo['setup'] = os.path.exists(pInfo['install_checks'])
|
||||
|
||||
if coexist and pluginInfo['setup']:
|
||||
pluginInfo['setup_version'] = info['versions']
|
||||
if coexist and pInfo['setup']:
|
||||
pInfo['setup_version'] = info['versions']
|
||||
else:
|
||||
pluginInfo['setup_version'] = self.getVersion(
|
||||
pluginInfo['install_checks'])
|
||||
pInfo['setup_version'] = self.getVersion(pInfo['install_checks'])
|
||||
# pluginInfo['status'] = self.checkStatus(pluginInfo)
|
||||
pluginInfo['status'] = False
|
||||
return pluginInfo
|
||||
pInfo['status'] = False
|
||||
return pInfo
|
||||
|
||||
def makeCoexist(self, data):
|
||||
plugins_info = []
|
||||
@@ -738,6 +774,7 @@ class plugins_api:
|
||||
public.writeFile(self.__index, json.dumps(indexList))
|
||||
return public.returnJson(True, '删除成功!')
|
||||
|
||||
# shell 调用
|
||||
def run(self, name, func, version, args='', script='index'):
|
||||
path = public.getRunDir() + '/' + self.__plugin_dir + \
|
||||
'/' + name + '/' + script + '.py'
|
||||
@@ -754,6 +791,20 @@ class plugins_api:
|
||||
# data = os.popen(py_cmd).read()
|
||||
|
||||
if public.isAppleSystem():
|
||||
print py_cmd
|
||||
print 'run', py_cmd
|
||||
# print os.path.exists(py_cmd)
|
||||
return (data[0].strip(), data[1].strip())
|
||||
|
||||
# 映射包调用
|
||||
def callback(self, name, func, args='', script='index'):
|
||||
package = public.getRunDir() + '/plugins/' + name
|
||||
if not os.path.exists(package):
|
||||
return (False, "插件不存在!")
|
||||
|
||||
sys.path.append(package)
|
||||
eval_str = "__import__('" + script + "')." + func + '(' + args + ')'
|
||||
newRet = eval(eval_str)
|
||||
if public.isAppleSystem():
|
||||
print 'callback', eval_str
|
||||
|
||||
return (True, newRet)
|
||||
|
||||
@@ -355,13 +355,16 @@ def HttpGet(url, timeout=10):
|
||||
|
||||
|
||||
def HttpGet2(url, timeout):
|
||||
import urllib
|
||||
import urllib2
|
||||
|
||||
req = urllib2.Request(url)
|
||||
res = urllib2.urlopen(req, timeout=timeout)
|
||||
result = res.read()
|
||||
return result
|
||||
try:
|
||||
req = urllib2.Request(url)
|
||||
res = urllib2.urlopen(req, timeout=timeout)
|
||||
result = res.read()
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
def httpGet(url, timeout=10):
|
||||
@@ -426,7 +429,7 @@ def writeSpeed(title, used, total, speed=0):
|
||||
|
||||
def getSpeed():
|
||||
# 取进度
|
||||
path = public.getRootDir()
|
||||
path = getRootDir()
|
||||
data = readFile(path + '/tmp/panelSpeed.pl')
|
||||
if not data:
|
||||
data = json.dumps({'title': None, 'progress': 0,
|
||||
|
||||
@@ -9,6 +9,8 @@ import json
|
||||
import pwd
|
||||
import shutil
|
||||
sys.path.append("/usr/local/lib/python2.7/site-packages")
|
||||
sys.path.append("/usr/lib64/python2.7/site-packages")
|
||||
|
||||
import psutil
|
||||
|
||||
from flask import request
|
||||
@@ -51,9 +53,15 @@ class site_api:
|
||||
def listApi(self):
|
||||
limit = request.form.get('limit', '').encode('utf-8')
|
||||
p = request.form.get('p', '').encode('utf-8')
|
||||
type_id = request.form.get('type_id', '').encode('utf-8')
|
||||
|
||||
start = (int(p) - 1) * (int(limit))
|
||||
_list = public.M('sites').where('', ()).field('id,name,path,status,ps,addtime,edate').limit(
|
||||
|
||||
siteM = public.M('sites')
|
||||
if type_id != '' and type_id == '-1' and type_id == '0':
|
||||
siteM.where('type_id=?', (type_id))
|
||||
|
||||
_list = siteM.field('id,name,path,status,ps,addtime,edate').limit(
|
||||
(str(start)) + ',' + limit).order('id desc').select()
|
||||
|
||||
for i in range(len(_list)):
|
||||
@@ -63,7 +71,7 @@ class site_api:
|
||||
_ret = {}
|
||||
_ret['data'] = _list
|
||||
|
||||
count = public.M('sites').where('', ()).count()
|
||||
count = siteM.count()
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['tojs'] = 'getWeb'
|
||||
@@ -73,6 +81,41 @@ class site_api:
|
||||
_ret['page'] = public.getPage(_page)
|
||||
return public.getJson(_ret)
|
||||
|
||||
def setDefaultSiteApi(self):
|
||||
name = request.form.get('name', '').encode('utf-8')
|
||||
import time
|
||||
# 清理旧的
|
||||
defaultSite = public.readFile('data/defaultSite.pl')
|
||||
if defaultSite:
|
||||
path = self.getHostConf(defaultSite)
|
||||
if os.path.exists(path):
|
||||
conf = public.readFile(path)
|
||||
rep = "listen\s+80.+;"
|
||||
conf = re.sub(rep, 'listen 80;', conf, 1)
|
||||
rep = "listen\s+443.+;"
|
||||
conf = re.sub(rep, 'listen 443 ssl;', conf, 1)
|
||||
public.writeFile(path, conf)
|
||||
|
||||
path = self.getHostConf(name)
|
||||
if os.path.exists(path):
|
||||
conf = public.readFile(path)
|
||||
rep = "listen\s+80\s*;"
|
||||
conf = re.sub(rep, 'listen 80 default_server;', conf, 1)
|
||||
rep = "listen\s+443\s*ssl\s*\w*\s*;"
|
||||
conf = re.sub(rep, 'listen 443 ssl default_server;', conf, 1)
|
||||
public.writeFile(path, conf)
|
||||
|
||||
public.writeFile('data/defaultSite.pl', name)
|
||||
public.restartWeb()
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
def getDefaultSiteApi(self):
|
||||
data = {}
|
||||
data['sites'] = public.M('sites').field(
|
||||
'name').order('id desc').select()
|
||||
data['defaultSite'] = public.readFile('data/defaultSite.pl')
|
||||
return public.getJson(data)
|
||||
|
||||
def setPsApi(self):
|
||||
mid = request.form.get('id', '').encode('utf-8')
|
||||
ps = request.form.get('ps', '').encode('utf-8')
|
||||
@@ -403,9 +446,9 @@ class site_api:
|
||||
'rm -rf /etc/letsencrypt/archive/' + siteName + '-00*')
|
||||
public.execShell(
|
||||
'rm -f /etc/letsencrypt/renewal/' + siteName + '.conf')
|
||||
public.execShell('rm -f /etc/letsencrypt/renewal/' +
|
||||
public.execShell('rm -rf /etc/letsencrypt/renewal/' +
|
||||
siteName + '-00*.conf')
|
||||
public.execShell('rm -f ' + path + '/README')
|
||||
public.execShell('rm -rf ' + path + '/README')
|
||||
public.execShell('mkdir -p ' + path)
|
||||
|
||||
public.writeFile(keypath, key)
|
||||
@@ -424,9 +467,38 @@ class site_api:
|
||||
return public.returnJson(False, 'ERROR: <br><a style="color:red;">' + isError.replace("\n", '<br>') + '</a>')
|
||||
|
||||
public.restartWeb()
|
||||
public.writeLog('TYPE_SITE', '证书已保存!')
|
||||
public.writeLog('网站管理', '证书已保存!')
|
||||
return public.returnJson(True, '证书已保存!')
|
||||
|
||||
def setCertToSiteApi(self):
|
||||
certName = request.form.get('certName', '').encode('utf-8')
|
||||
siteName = request.form.get('siteName', '').encode('utf-8')
|
||||
try:
|
||||
path = self.sslDir + siteName
|
||||
if not os.path.exists(path):
|
||||
return public.returnJson(False, '证书不存在!')
|
||||
|
||||
result = self.setSslConf(siteName)
|
||||
if not result['status']:
|
||||
return public.getJson(result)
|
||||
|
||||
public.restartWeb()
|
||||
public.writeLog('网站管理', '证书已部署!')
|
||||
return public.returnJson(True, '证书已部署!')
|
||||
except Exception as ex:
|
||||
return public.returnJson(False, '设置错误,' + str(ex))
|
||||
|
||||
def removeCertApi(self):
|
||||
certName = request.form.get('certName', '').encode('utf-8')
|
||||
try:
|
||||
path = self.sslDir + certName
|
||||
if not os.path.exists(path):
|
||||
return public.returnJson(False, '证书已不存在!')
|
||||
os.system("rm -rf " + path)
|
||||
return public.returnJson(True, '证书已删除!')
|
||||
except:
|
||||
return public.returnJson(False, '删除失败!')
|
||||
|
||||
def closeSslConfApi(self):
|
||||
siteName = request.form.get('siteName', '').encode('utf-8')
|
||||
|
||||
@@ -471,7 +543,7 @@ class site_api:
|
||||
public.writeFile(file, conf)
|
||||
|
||||
msg = public.getInfo('网站[{1}]关闭SSL成功!', (siteName,))
|
||||
public.writeLog('TYPE_SITE', msg)
|
||||
public.writeLog('网站管理', msg)
|
||||
public.restartWeb()
|
||||
return public.returnJson(True, 'SSL已关闭!')
|
||||
|
||||
@@ -498,7 +570,7 @@ class site_api:
|
||||
if siteConf.find('301-START') != -1:
|
||||
return public.returnJson(False, '检测到您的站点做了301重定向设置,请先关闭重定向!')
|
||||
|
||||
letpath = public.getServerDir() + '/letsencrypt/live/' + siteName
|
||||
letpath = self.sslDir + siteName
|
||||
csrpath = letpath + "/fullchain.pem" # 生成证书路径
|
||||
keypath = letpath + "/privkey.pem" # 密钥文件路径
|
||||
|
||||
@@ -556,8 +628,7 @@ class site_api:
|
||||
if domainCount == 0:
|
||||
return public.returnJson(False, '请选择域名(不包括IP地址与泛域名)!')
|
||||
|
||||
home_path = public.getServerDir() + '/openresty/nginx/conf/cert/' + \
|
||||
domains[0]
|
||||
home_path = '/root/.acme.sh/' + domains[0]
|
||||
home_cert = home_path + '/fullchain.cer'
|
||||
home_key = home_path + '/' + domains[0] + '.key'
|
||||
|
||||
@@ -566,11 +637,6 @@ class site_api:
|
||||
home_cert = home_path + '/fullchain.cer'
|
||||
home_key = home_path + '/' + domains[0] + '.key'
|
||||
|
||||
if not os.path.exists(home_cert):
|
||||
home_path = '/root/.acme.sh/' + domains[0]
|
||||
home_cert = home_path + '/fullchain.cer'
|
||||
home_key = home_path + '/' + domains[0] + '.key'
|
||||
|
||||
if public.isAppleSystem():
|
||||
user = public.execShell(
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
@@ -582,6 +648,8 @@ class site_api:
|
||||
|
||||
# print home_cert
|
||||
cmd = 'export ACCOUNT_EMAIL=' + email + ' && ' + execStr
|
||||
print domains
|
||||
print cmd
|
||||
result = public.execShell(cmd)
|
||||
|
||||
if not os.path.exists(home_cert.replace("\*", "*")):
|
||||
@@ -616,7 +684,6 @@ class site_api:
|
||||
|
||||
# 写入配置文件
|
||||
result = self.setSslConf(siteName)
|
||||
# print result['msg']
|
||||
if not result['status']:
|
||||
return public.getJson(result)
|
||||
result['csr'] = public.readFile(csrpath)
|
||||
@@ -625,6 +692,39 @@ class site_api:
|
||||
|
||||
return public.returnJson(True, 'OK', result)
|
||||
|
||||
def httpToHttpsApi(self):
|
||||
siteName = request.form.get('siteName', '').encode('utf-8')
|
||||
file = self.getHostConf(siteName)
|
||||
conf = public.readFile(file)
|
||||
if conf:
|
||||
# if conf.find('ssl_certificate') == -1:
|
||||
# return public.returnJson(False, '当前未开启SSL')
|
||||
to = """#error_page 404/404.html;
|
||||
# HTTP_TO_HTTPS_START
|
||||
if ($server_port !~ 443){
|
||||
rewrite ^(/.*)$ https://$host$1 permanent;
|
||||
}
|
||||
# HTTP_TO_HTTPS_END"""
|
||||
conf = conf.replace('#error_page 404/404.html;', to)
|
||||
public.writeFile(file, conf)
|
||||
|
||||
public.restartWeb()
|
||||
return public.returnJson(True, '设置成功!证书也要设置好哟!')
|
||||
|
||||
def closeToHttpsApi(self):
|
||||
siteName = request.form.get('siteName', '').encode('utf-8')
|
||||
file = self.getHostConf(siteName)
|
||||
conf = public.readFile(file)
|
||||
if conf:
|
||||
rep = "\n\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
conf = re.sub(rep, '', conf)
|
||||
public.writeFile(file, conf)
|
||||
|
||||
public.restartWeb()
|
||||
return public.returnJson(True, '关闭HTTPS跳转成功!')
|
||||
|
||||
def getIndexApi(self):
|
||||
sid = request.form.get('id', '').encode('utf-8')
|
||||
data = {}
|
||||
@@ -757,7 +857,7 @@ class site_api:
|
||||
|
||||
public.restartWeb()
|
||||
msg = public.getInfo('网站[{1}]添加域名[{2}]成功!', (webname, domain_name))
|
||||
public.writeLog('TYPE_SITE', msg)
|
||||
public.writeLog('网站管理', msg)
|
||||
public.M('domain').add('pid,name,port,addtime',
|
||||
(pid, domain_name, domain_port, public.getDate()))
|
||||
|
||||
@@ -894,7 +994,6 @@ class site_api:
|
||||
path = request.form.get('path', '').encode('utf-8')
|
||||
|
||||
path = self.getPath(path)
|
||||
print path
|
||||
if path == "" or mid == '0':
|
||||
return public.returnJson(False, "目录不能为空!")
|
||||
|
||||
@@ -913,13 +1012,13 @@ class site_api:
|
||||
public.writeFile(file, conf)
|
||||
|
||||
# 创建basedir
|
||||
userIni = path + '/.user.ini'
|
||||
if os.path.exists(userIni):
|
||||
public.execShell("chattr -i " + userIni)
|
||||
public.writeFile(userIni, 'open_basedir=' + path + '/:/tmp/:/proc/')
|
||||
public.execShell('chmod 644 ' + userIni)
|
||||
public.execShell('chown root:root ' + userIni)
|
||||
public.execShell('chattr +i ' + userIni)
|
||||
# userIni = path + '/.user.ini'
|
||||
# if os.path.exists(userIni):
|
||||
# public.execShell("chattr -i " + userIni)
|
||||
# public.writeFile(userIni, 'open_basedir=' + path + '/:/tmp/:/proc/')
|
||||
# public.execShell('chmod 644 ' + userIni)
|
||||
# public.execShell('chown root:root ' + userIni)
|
||||
# public.execShell('chattr +i ' + userIni)
|
||||
|
||||
public.restartWeb()
|
||||
public.M("sites").where("id=?", (mid,)).setField('path', path)
|
||||
@@ -1056,7 +1155,7 @@ class site_api:
|
||||
|
||||
public.M('domain').where("id=?", (find['id'],)).delete()
|
||||
msg = public.getInfo('网站[{1}]删除域名[{2}]成功!', (webname, domain))
|
||||
public.writeLog('TYPE_SITE', msg)
|
||||
public.writeLog('网站管理', msg)
|
||||
public.restartWeb()
|
||||
return public.returnJson(True, '站点删除成功!')
|
||||
|
||||
@@ -1107,9 +1206,72 @@ class site_api:
|
||||
proxylist.append(i)
|
||||
return public.getJson(proxylist)
|
||||
|
||||
def getSiteTypesApi(self):
|
||||
# 取网站分类
|
||||
data = public.M("site_types").field("id,name").order("id asc").select()
|
||||
data.insert(0, {"id": 0, "name": "默认分类"})
|
||||
return public.getJson(data)
|
||||
|
||||
def getSiteDocApi(self):
|
||||
stype = request.form.get('type', '0').strip().encode('utf-8')
|
||||
vlist = []
|
||||
vlist.append('')
|
||||
vlist.append(public.getServerDir() +
|
||||
'/openresty/nginx/html/index.html')
|
||||
vlist.append(public.getServerDir() + '/openresty/nginx/html/404.html')
|
||||
vlist.append(public.getServerDir() +
|
||||
'/openresty/nginx/html/index.html')
|
||||
vlist.append(public.getServerDir() + '/web_conf/stop/index.html')
|
||||
data = {}
|
||||
data['path'] = vlist[int(stype)]
|
||||
return public.returnJson(True, 'ok', data)
|
||||
|
||||
def addSiteTypeApi(self):
|
||||
name = request.form.get('name', '').strip().encode('utf-8')
|
||||
if not name:
|
||||
return public.returnJson(False, "分类名称不能为空")
|
||||
if len(name) > 18:
|
||||
return public.returnJson(False, "分类名称长度不能超过6个汉字或18位字母")
|
||||
if public.M('site_types').count() >= 10:
|
||||
return public.returnJson(False, '最多添加10个分类!')
|
||||
if public.M('site_types').where('name=?', (name,)).count() > 0:
|
||||
return public.returnJson(False, "指定分类名称已存在!")
|
||||
public.M('site_types').add("name", (name,))
|
||||
return public.returnJson(True, '添加成功!')
|
||||
|
||||
def removeSiteTypeApi(self):
|
||||
mid = request.form.get('id', '').encode('utf-8')
|
||||
if public.M('site_types').where('id=?', (mid,)).count() == 0:
|
||||
return public.returnJson(False, "指定分类不存在!")
|
||||
public.M('site_types').where('id=?', (mid,)).delete()
|
||||
public.M("sites").where("type_id=?", (mid,)).save("type_id", (0,))
|
||||
return public.returnJson(True, "分类已删除!")
|
||||
|
||||
def modifySiteTypeNameApi(self):
|
||||
# 修改网站分类名称
|
||||
name = request.form.get('name', '').strip().encode('utf-8')
|
||||
mid = request.form.get('id', '').encode('utf-8')
|
||||
if not name:
|
||||
return public.returnJson(False, "分类名称不能为空")
|
||||
if len(name) > 18:
|
||||
return public.returnJson(False, "分类名称长度不能超过6个汉字或18位字母")
|
||||
if public.M('site_types').where('id=?', (mid,)).count() == 0:
|
||||
return public.returnJson(False, "指定分类不存在!")
|
||||
public.M('site_types').where('id=?', (mid,)).setField('name', name)
|
||||
return public.returnJson(True, "修改成功!")
|
||||
|
||||
def setSiteTypeApi(self):
|
||||
# 设置指定站点的分类
|
||||
site_ids = request.form.get('site_ids', '').encode('utf-8')
|
||||
mid = request.form.get('id', '').encode('utf-8')
|
||||
site_ids = json.loads(site_ids)
|
||||
for sid in site_ids:
|
||||
print public.M('sites').where('id=?', (sid,)).setField('type_id', mid)
|
||||
return public.returnJson(True, "设置成功!")
|
||||
|
||||
##### ----- end ----- ###
|
||||
|
||||
# 域名编码转换
|
||||
# 域名编码转换
|
||||
def toPunycode(self, domain):
|
||||
import re
|
||||
if sys.version_info[0] == 2:
|
||||
@@ -1514,13 +1676,12 @@ location /{
|
||||
self.sitePort = port.strip().replace(' ', '')
|
||||
self.phpVersion = version
|
||||
|
||||
siteM = public.M('sites')
|
||||
if siteM.where("name=?", (self.siteName,)).count():
|
||||
if public.M('sites').where("name=?", (self.siteName,)).count():
|
||||
return public.returnJson(False, '您添加的站点已存在!')
|
||||
|
||||
# 写入数据库
|
||||
pid = siteM.add('name,path,status,ps,edate,addtime',
|
||||
(self.siteName, self.sitePath, '1', ps, '0000-00-00', public.getDate()))
|
||||
pid = public.M('sites').add('name,path,status,ps,edate,addtime,type_id',
|
||||
(self.siteName, self.sitePath, '1', ps, '0000-00-00', public.getDate(), 0,))
|
||||
opid = public.M('domain').where(
|
||||
"name=?", (self.siteName,)).getField('pid')
|
||||
if opid:
|
||||
@@ -1532,14 +1693,13 @@ location /{
|
||||
for domain in siteMenu['domainlist']:
|
||||
sdomain = domain
|
||||
swebname = self.siteName
|
||||
spid = str(get.pid)
|
||||
spid = str(pid)
|
||||
# self.addDomain(domain, webname, pid)
|
||||
|
||||
public.M('domain').add('pid,name,port,addtime',
|
||||
(pid, self.siteName, self.sitePort, public.getDate()))
|
||||
|
||||
self.createRootDir(self.sitePath)
|
||||
|
||||
self.nginxAddConf()
|
||||
|
||||
data = {}
|
||||
@@ -1550,16 +1710,22 @@ location /{
|
||||
def deleteWSLogs(self, webname):
|
||||
assLogPath = public.getLogsDir() + '/' + webname + '.log'
|
||||
errLogPath = public.getLogsDir() + '/' + webname + '.error.log'
|
||||
confFile = self.setupPath + '/openresty/nginx/conf/vhost/' + webname + '.conf'
|
||||
rewriteFile = self.setupPath + '/openresty/nginx/conf/rewrite/' + webname + '.conf'
|
||||
logs = [assLogPath, errLogPath, confFile, rewriteFile]
|
||||
confFile = self.setupPath + '/nginx/vhost/' + webname + '.conf'
|
||||
rewriteFile = self.setupPath + '/nginx/rewrite/' + webname + '.conf'
|
||||
rewriteFile = self.setupPath + '/nginx/pass/' + webname + '.conf'
|
||||
keyPath = self.sslDir + webname + '/privkey.pem'
|
||||
certPath = self.sslDir + webname + '/fullchain.pem'
|
||||
logs = [assLogPath,
|
||||
errLogPath,
|
||||
confFile,
|
||||
rewriteFile,
|
||||
keyPath,
|
||||
certPath]
|
||||
for i in logs:
|
||||
public.deleteFile(i)
|
||||
|
||||
def delete(self, sid, webname, path):
|
||||
|
||||
self.deleteWSLogs(webname)
|
||||
|
||||
if path == '1':
|
||||
rootPath = public.getWwwDir() + '/' + webname
|
||||
public.execShell('rm -rf ' + rootPath)
|
||||
@@ -1617,7 +1783,7 @@ location /{
|
||||
self.saveCert(keyPath, certPath)
|
||||
|
||||
msg = public.getInfo('网站[{1}]开启SSL成功!', siteName)
|
||||
public.writeLog('TYPE_SITE', msg)
|
||||
public.writeLog('网站管理', msg)
|
||||
return public.returnData(True, 'SSL开启成功!')
|
||||
|
||||
def saveCert(self, keyPath, certPath):
|
||||
|
||||
@@ -103,7 +103,8 @@ class system_api:
|
||||
@async
|
||||
def restartMw(self):
|
||||
sleep(1)
|
||||
cmd = public.getRunDir() + '/scripts/init.d/mw reload'
|
||||
cmd = public.getRunDir() + '/scripts/init.d/mw restart'
|
||||
#print cmd
|
||||
public.execShell(cmd)
|
||||
|
||||
@async
|
||||
@@ -601,13 +602,18 @@ class system_api:
|
||||
return 'test'
|
||||
|
||||
old_list = old.split('.')
|
||||
|
||||
ret = 'none'
|
||||
for i in range(len(old_list)):
|
||||
tm_new = int(new_list[i])
|
||||
tm_old = int(new_list[i])
|
||||
if tm_new > tm_old:
|
||||
return 'new'
|
||||
|
||||
# t = [0] * 3
|
||||
isHasNew = True
|
||||
for i in range(3):
|
||||
if int(new_list[i]) > int(old_list[i]):
|
||||
pass
|
||||
else:
|
||||
isHasNew = False
|
||||
|
||||
if isHasNew:
|
||||
return 'new'
|
||||
return ret
|
||||
|
||||
def getServerInfo(self):
|
||||
@@ -634,6 +640,7 @@ class system_api:
|
||||
|
||||
diff = self.versionDiff(
|
||||
version_now, version_new_info['version'])
|
||||
print diff
|
||||
if diff == 'new':
|
||||
return public.returnJson(True, '有新版本!', version_new_info['version'])
|
||||
elif diff == 'test':
|
||||
|
||||
@@ -15,12 +15,15 @@ mw_start_debug(){
|
||||
gunicorn -b :7200 -k gevent -w 1 app:app
|
||||
# gunicorn -b :7200 -k eventlet -w 1 app:app
|
||||
# gunicorn -c setting.py app:app
|
||||
|
||||
}
|
||||
|
||||
mw_stop()
|
||||
{
|
||||
ps -ef|grep app:app |grep -v grep|awk '{print $2}'|xargs kill -9
|
||||
PLIST=`ps -ef|grep app:app |grep -v grep|awk '{print $2}'`
|
||||
for i in $PLIST
|
||||
do
|
||||
kill -9 $i
|
||||
done
|
||||
ps -ef|grep task.py |grep -v grep|awk '{print $2}'|xargs kill -9
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
qpzw99oc
|
||||
@@ -0,0 +1 @@
|
||||
t.vvv
|
||||
@@ -65,11 +65,17 @@ CREATE TABLE IF NOT EXISTS `sites` (
|
||||
`path` TEXT,
|
||||
`status` TEXT,
|
||||
`index` TEXT,
|
||||
`type_id` INTEGER,
|
||||
`ps` TEXT,
|
||||
`edate` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `site_types` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `domain` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`pid` INTEGER,
|
||||
|
||||
|
Before Width: | Height: | Size: 181 B |
@@ -1,16 +0,0 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('abkill');">服务</p>
|
||||
<p onclick="pluginInitD('abkill');">自启动</p>
|
||||
<p onclick="pluginConfig('abkill');">黑名单</p>
|
||||
<p onclick="pluginConfig('abkill');">异常日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=abkill&f=js/abkill.js");
|
||||
</script>
|
||||
@@ -1,172 +0,0 @@
|
||||
# coding: utf-8
|
||||
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
import urllib
|
||||
import binascii
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import public
|
||||
|
||||
|
||||
app_debug = False
|
||||
if public.getOs() == 'darwin':
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'abkill'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return public.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return public.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
return '/tmp/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def initDreplace():
|
||||
initd_file = getInitDFile()
|
||||
|
||||
if not os.path.exists(initd_file):
|
||||
return getServerDir()
|
||||
|
||||
return initd_file
|
||||
|
||||
|
||||
def status():
|
||||
data = public.execShell(
|
||||
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def csvnOp(method):
|
||||
|
||||
if app_debug:
|
||||
os_name = public.getOs()
|
||||
if os_name == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
_initd_csvn = '/etc/init.d/csvn'
|
||||
_initd_csvn_httpd = '/etc/init.d/csvn-httpd'
|
||||
#_csvn = getServerDir() + '/bin/csvn'
|
||||
#_csvn_httpd = getServerDir() + '/bin/csvn-httpd'
|
||||
|
||||
ret_csvn_httpd = public.execShell(_initd_csvn_httpd + ' ' + method)
|
||||
# ret_csvn = public.execShell(_initd_csvn + ' ' + method)
|
||||
subprocess.Popen(_initd_csvn + ' ' + method,
|
||||
stdout=subprocess.PIPE, shell=True)
|
||||
if ret_csvn_httpd[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def start():
|
||||
return csvnOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return csvnOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
return csvnOp('restart')
|
||||
|
||||
|
||||
def reload():
|
||||
return csvnOp('reload')
|
||||
|
||||
|
||||
def initdStatus():
|
||||
if not app_debug:
|
||||
if public.getOs() == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
_initd_csvn = '/etc/init.d/csvn'
|
||||
_initd_csvn_httpd = '/etc/init.d/csvn-httpd'
|
||||
|
||||
if os.path.exists(_initd_csvn) and os.path.exists(_initd_csvn_httpd):
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
import shutil
|
||||
if not app_debug:
|
||||
if public.getOs() == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
_csvn = getServerDir() + '/bin/csvn'
|
||||
_csvn_httpd = getServerDir() + '/bin/csvn-httpd'
|
||||
|
||||
ret_csvn = public.execShell(_csvn + ' install')
|
||||
ret_csvn_httpd = public.execShell(_csvn_httpd + ' install')
|
||||
if ret_csvn[1] == '' and ret_csvn_httpd[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
if not app_debug:
|
||||
if public.getOs() == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
_csvn = getServerDir() + '/bin/csvn'
|
||||
_csvn_httpd = getServerDir() + '/bin/csvn-httpd'
|
||||
|
||||
ret_csvn = public.execShell(_csvn + ' remove')
|
||||
ret_csvn_httpd = public.execShell(_csvn_httpd + ' remove')
|
||||
return 'ok'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print status()
|
||||
elif func == 'start':
|
||||
print start()
|
||||
elif func == 'stop':
|
||||
print stop()
|
||||
elif func == 'restart':
|
||||
print restart()
|
||||
elif func == 'reload':
|
||||
print reload()
|
||||
elif func == 'initd_status':
|
||||
print initdStatus()
|
||||
elif func == 'initd_install':
|
||||
print initdInstall()
|
||||
elif func == 'initd_uninstall':
|
||||
print initdUinstall()
|
||||
else:
|
||||
print 'fail'
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "异常程序监控和KILL",
|
||||
"shell": "install.sh",
|
||||
"name": "abkill",
|
||||
"title": "异常程序监控",
|
||||
"versions": "0.1",
|
||||
"updates":"0.1",
|
||||
"tip": "soft",
|
||||
"checks": "server/abkill",
|
||||
"author": "midoks",
|
||||
"date": "201-04-01",
|
||||
"home": "https://www.collab.net",
|
||||
"type": "异常程序监控和KILL",
|
||||
"pid": "4"
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
|
||||
ak_path={$SERVER_PATH}/abkill
|
||||
|
||||
ak_start(){
|
||||
isStart=$(ps aux |grep 'abkill.py'|grep -v grep|awk '{print $2}')
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "Starting abkill... \c"
|
||||
cd $ak_path && nohup python abkill.py >> $ak_path/task.log 2>&1 &
|
||||
sleep 0.3
|
||||
isStart=$(ps aux |grep 'abkill.py'|grep -v grep|awk '{print $2}')
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "\033[31mfailed\033[0m"
|
||||
echo '------------------------------------------------------'
|
||||
tail -n 20 $ak_path/task.log
|
||||
echo '------------------------------------------------------'
|
||||
echo -e "\033[31mError: abkill service startup failed.\033[0m"
|
||||
return;
|
||||
fi
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
else
|
||||
echo "Starting abkill(pid $isStart) already running"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
ak_stop()
|
||||
{
|
||||
echo -e "Stopping abkill... \c";
|
||||
pids=$(ps aux | grep 'abkill.py' | grep -v grep|awk '{print $2}')
|
||||
arr=($pids)
|
||||
|
||||
for p in ${arr[@]}
|
||||
do
|
||||
kill -9 $p
|
||||
done
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
|
||||
}
|
||||
|
||||
ak_status()
|
||||
{
|
||||
isStart=$(ps aux|grep 'abkill.py'|grep -v grep|awk '{print $2}')
|
||||
if [ "$isStart" != '' ];then
|
||||
echo -e "\033[32mabkill (pid $(echo $isStart)) already running\033[0m"
|
||||
else
|
||||
echo -e "\033[31mabkill not running\033[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
ak_reload()
|
||||
{
|
||||
isStart=$(ps aux|grep 'abkill.py'|grep -v grep|awk '{print $2}')
|
||||
|
||||
if [ "$isStart" != '' ];then
|
||||
ak_stop
|
||||
ak_start
|
||||
else
|
||||
echo -e "\033[31mmw not running\033[0m"
|
||||
mw_start
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
'start') ak_start;;
|
||||
'stop') ak_stop;;
|
||||
'reload') ak_reload;;
|
||||
'restart')
|
||||
ak_stop
|
||||
sleep 0.3
|
||||
ak_start;;
|
||||
'status') ak_status;;
|
||||
esac
|
||||
@@ -1 +0,0 @@
|
||||
pluginService('abkill');
|
||||
@@ -1,85 +0,0 @@
|
||||
# coding: utf-8
|
||||
|
||||
# 使用示例:
|
||||
# 1、将此文件重命名为btkill.py , 然后上传到服务器/root目录
|
||||
# 2、执行 python /root/btkill.py
|
||||
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
sys.path.append("/usr/local/lib/python2.7/site-packages")
|
||||
import psutil
|
||||
|
||||
|
||||
class btkill:
|
||||
__limit = 10 # Cpu使用率触发上限
|
||||
__vmsize = 1048576 / 4 # 虚拟内存触发上限(字节)
|
||||
|
||||
def checkMain(self):
|
||||
pids = psutil.pids()
|
||||
print pids
|
||||
num = 0
|
||||
for pid in pids:
|
||||
try:
|
||||
p = psutil.Process(pid)
|
||||
if p.exe() == "":
|
||||
continue
|
||||
name = p.name()
|
||||
if self.whiteList(name):
|
||||
continue
|
||||
cputimes = p.cpu_times()
|
||||
if cputimes.user < 0.1:
|
||||
continue
|
||||
print p
|
||||
percent = p.cpu_percent(interval=1)
|
||||
vm = p.memory_info().vms
|
||||
if percent > self.__limit or vm > self.__vmsize:
|
||||
log = time.strftime('%Y-%m-%d %X', time.localtime()) + " (PID=" + str(
|
||||
pid) + ", NAME=" + name + ", VMS=" + str(vm) + ", PERCENT=" + str(percent) + "%)"
|
||||
# p.kill()
|
||||
num += 1
|
||||
print log + " >> killed\n"
|
||||
except Exception as ex:
|
||||
print str(ex)
|
||||
return num
|
||||
|
||||
# 检查白名单
|
||||
def whiteList(self, name):
|
||||
wlist = ['yum', 'apt-get', 'apt', 'redis-cli', 'memcached', 'sshd', 'vm', 'vim', 'htop', 'top', 'sh', 'bash', 'zip', 'gzip', 'rsync',
|
||||
'tar', 'unzip', 'php', 'composer', 'pkill', 'mongo', 'mongod', 'php-fpm', 'nginx', 'httpd', 'lsof', 'ps', 'redis-server',
|
||||
'mysqld', 'mysqld_safe', 'mysql', 'pure-ftpd', 'sparse_dd', 'stunnel', 'squeezed', 'vncterm', 'awk', 'ruby', 'postgres',
|
||||
'mpathalert', 'vncterm', 'multipathd', 'fe', 'elasticsyslog', 'syslogd', 'v6d', 'xapi', 'screen', 'runsvdir', 'svlogd',
|
||||
'java', 'udevd', 'ntpd', 'irqbalance', 'qmgr', 'wpa_supplicant', 'mysqld_safe', 'sftp-server', 'lvmetad', 'gitlab-web',
|
||||
'pure-ftpd', 'auditd', 'master', 'dbus-daemon', 'tapdisk', 'sshd', 'init', 'ksoftirqd', 'kworker', 'kmpathd',
|
||||
'kmpath_handlerd', 'python', 'kdmflush', 'bioset', 'crond', 'kthreadd', 'migration', 'rcu_sched', 'kjournald',
|
||||
'gcc', 'gcc++', 'nginx', 'mysqld', 'php-cgi', 'login', 'firewalld', 'iptables', 'systemd', 'network', 'dhclient',
|
||||
'systemd-journald', 'NetworkManager', 'systemd-logind', 'systemd-udevd', 'polkitd', 'tuned', 'rsyslogd', 'AliYunDunUpdate', 'AliYunDun', 'sendmail']
|
||||
wslist = ['vif', 'qemu', 'scsi_eh', 'xcp',
|
||||
'xen', 'docker', 'yunsuo', 'aliyun', 'PM2']
|
||||
|
||||
for key in wlist:
|
||||
if key == name:
|
||||
return True
|
||||
|
||||
for key in wslist:
|
||||
if name.find(key) != -1:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
# 开始处理
|
||||
def start(self):
|
||||
num = 0
|
||||
while True:
|
||||
num += self.checkMain()
|
||||
print "查杀完成, 共查杀[" + str(num) + "]个异常进程!"
|
||||
time.sleep(3)
|
||||
print '======================================='
|
||||
print "查杀完成, 共查杀[" + str(num) + "]个异常进程!"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "正在检测异常进程..."
|
||||
print '======================================='
|
||||
c = btkill()
|
||||
c.start()
|
||||
|
After Width: | Height: | Size: 498 B |
@@ -0,0 +1,17 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('bbr');">服务</p>
|
||||
<p onclick="readme();">说明</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=bbr&f=js/bbr.js", function() {
|
||||
pluginService('bbr');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,109 @@
|
||||
# coding: utf-8
|
||||
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import public
|
||||
|
||||
|
||||
app_debug = False
|
||||
if public.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'bbr'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return public.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return public.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
return '/tmp/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def status():
|
||||
if not app_debug:
|
||||
if public.isAppleSystem():
|
||||
return "stop"
|
||||
|
||||
data = public.execShell('sudo sysctl -n net.ipv4.tcp_congestion_control')
|
||||
r = data[0].strip()
|
||||
if r == 'bbr':
|
||||
return 'start'
|
||||
return 'stop'
|
||||
|
||||
|
||||
def start():
|
||||
if not app_debug:
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
public.execShell('echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf')
|
||||
cmd = 'echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf'
|
||||
public.execShell(cmd)
|
||||
public.execShell('sysctl -p')
|
||||
return '执行成功!重启系统生效'
|
||||
|
||||
|
||||
def stop():
|
||||
if not app_debug:
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
cmd1 = "sed -i '/net\.core\.default_qdisc/d' /etc/sysctl.conf"
|
||||
public.execShell(cmd1)
|
||||
cmd2 = "sed -i '/net\.ipv4\.tcp_congestion_control/d' /etc/sysctl.conf"
|
||||
public.execShell(cmd2)
|
||||
public.execShell("sysctl -p")
|
||||
return '执行成功!重启系统生效'
|
||||
|
||||
|
||||
def restart():
|
||||
return '无效'
|
||||
|
||||
|
||||
def reload():
|
||||
return '无效'
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print status()
|
||||
elif func == 'start':
|
||||
print start()
|
||||
elif func == 'stop':
|
||||
print stop()
|
||||
elif func == 'restart':
|
||||
print restart()
|
||||
elif func == 'reload':
|
||||
print reload()
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"id":4,
|
||||
"title":"BBR",
|
||||
"tip":"soft",
|
||||
"name":"bbr",
|
||||
"type":"软件",
|
||||
"ps":"[DEV][谨慎]BBR是Google提出的一种新型拥塞控制算法",
|
||||
"versions":"1.0",
|
||||
"shell":"install.sh",
|
||||
"checks":"server/bbr",
|
||||
"path":"server/bbr",
|
||||
"author":"Google",
|
||||
"home":"https://github.com/google/bbr",
|
||||
"date":"2019-03-29",
|
||||
"pid":"4"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
Install_bbr()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
chmod +x $curPath/scripts/bbr.sh
|
||||
sh $curPath/scripts/bbr.sh
|
||||
|
||||
mkdir -p $serverPath/bbr
|
||||
echo '1.0' > $serverPath/bbr/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_bbr()
|
||||
{
|
||||
rm -rf $serverPath/bbr
|
||||
echo "卸载完成" > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_bbr
|
||||
else
|
||||
Uninstall_bbr
|
||||
fi
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
function readme(){
|
||||
var con = '<ul class="help-info-text c7">';
|
||||
con += '<li>一旦安装无法退回!谨慎使用</li>';
|
||||
con += '<li>只有KVM架构的VPS才能使用</li>';
|
||||
con += '<li>安装 Google BBR 需升级系统内核,而安装锐速则需降级系统内核,<br/>故两者不能同时安装。</li>';
|
||||
con += '<li>安装 Google BBR 需升级系统内核,有可能造成系统不稳定,<br/>故不建议将其应用在重要的生产环境中</li>';
|
||||
con += '<hr/>';
|
||||
con += '<li>安装升级后,可删除无用的旧内核[谨慎操作]</li>';
|
||||
con += '<li>yum remove $(rpm -qa | grep kernel | grep -v $(uname -r))</li>';
|
||||
con += '</ul>';
|
||||
$(".soft-man-con").html(con);
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Auto install latest kernel for TCP BBR
|
||||
#
|
||||
# System Required: CentOS 6+, Debian7+, Ubuntu12+
|
||||
#
|
||||
# Copyright (C) 2016-2018 Teddysun <i@teddysun.com>
|
||||
#
|
||||
# URL: https://teddysun.com/489.html
|
||||
#
|
||||
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
yellow='\033[0;33m'
|
||||
plain='\033[0m'
|
||||
|
||||
cur_dir=$(pwd)
|
||||
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}Error:${plain} This script must be run as root!" && exit 1
|
||||
|
||||
[[ -d "/proc/vz" ]] && echo -e "${red}Error:${plain} Your VPS is based on OpenVZ, which is not supported." && exit 1
|
||||
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
release="centos"
|
||||
elif cat /etc/issue | grep -Eqi "debian"; then
|
||||
release="debian"
|
||||
elif cat /etc/issue | grep -Eqi "ubuntu"; then
|
||||
release="ubuntu"
|
||||
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
|
||||
release="centos"
|
||||
elif cat /proc/version | grep -Eqi "debian"; then
|
||||
release="debian"
|
||||
elif cat /proc/version | grep -Eqi "ubuntu"; then
|
||||
release="ubuntu"
|
||||
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
|
||||
release="centos"
|
||||
else
|
||||
release=""
|
||||
fi
|
||||
|
||||
is_digit(){
|
||||
local input=${1}
|
||||
if [[ "$input" =~ ^[0-9]+$ ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_64bit(){
|
||||
if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_valid_valname(){
|
||||
local val=${1}
|
||||
local new_val=$(eval echo $val | sed 's/[-.]/_/g')
|
||||
echo ${new_val}
|
||||
}
|
||||
|
||||
get_hint(){
|
||||
local val=${1}
|
||||
local new_val=$(get_valid_valname $val)
|
||||
eval echo "\$hint_${new_val}"
|
||||
}
|
||||
|
||||
#Display Memu
|
||||
display_menu(){
|
||||
local soft=${1}
|
||||
local default=${2}
|
||||
eval local arr=(\${${soft}_arr[@]})
|
||||
local default_prompt
|
||||
if [[ "$default" != "" ]]; then
|
||||
if [[ "$default" == "last" ]]; then
|
||||
default=${#arr[@]}
|
||||
fi
|
||||
default_prompt="(default ${arr[$default-1]})"
|
||||
fi
|
||||
local pick
|
||||
local hint
|
||||
local vname
|
||||
local prompt="which ${soft} you'd select ${default_prompt}: "
|
||||
|
||||
while :
|
||||
do
|
||||
echo -e "\n------------ ${soft} setting ------------\n"
|
||||
for ((i=1;i<=${#arr[@]};i++ )); do
|
||||
vname="$(get_valid_valname ${arr[$i-1]})"
|
||||
hint="$(get_hint $vname)"
|
||||
[[ "$hint" == "" ]] && hint="${arr[$i-1]}"
|
||||
echo -e "${green}${i}${plain}) $hint"
|
||||
done
|
||||
echo
|
||||
read -p "${prompt}" pick
|
||||
if [[ "$pick" == "" && "$default" != "" ]]; then
|
||||
pick=${default}
|
||||
break
|
||||
fi
|
||||
|
||||
if ! is_digit "$pick"; then
|
||||
prompt="Input error, please input a number"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then
|
||||
prompt="Input error, please input a number between 1 and ${#arr[@]}: "
|
||||
continue
|
||||
fi
|
||||
|
||||
break
|
||||
done
|
||||
|
||||
eval ${soft}=${arr[$pick-1]}
|
||||
vname="$(get_valid_valname ${arr[$pick-1]})"
|
||||
hint="$(get_hint $vname)"
|
||||
[[ "$hint" == "" ]] && hint="${arr[$pick-1]}"
|
||||
echo -e "\nyour selection: $hint\n"
|
||||
}
|
||||
|
||||
version_ge(){
|
||||
test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"
|
||||
}
|
||||
|
||||
get_latest_version() {
|
||||
latest_version=($(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ | awk -F'\"v' '/v[4-9]./{print $2}' | cut -d/ -f1 | grep -v - | sort -V))
|
||||
|
||||
[ ${#latest_version[@]} -eq 0 ] && echo -e "${red}Error:${plain} Get latest kernel version failed." && exit 1
|
||||
|
||||
kernel_arr=()
|
||||
for i in ${latest_version[@]}; do
|
||||
if version_ge $i 4.14; then
|
||||
kernel_arr+=($i);
|
||||
fi
|
||||
done
|
||||
|
||||
display_menu kernel last
|
||||
|
||||
if [[ `getconf WORD_BIT` == "32" && `getconf LONG_BIT` == "64" ]]; then
|
||||
deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
|
||||
deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
|
||||
deb_kernel_name="linux-image-${kernel}-amd64.deb"
|
||||
modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/amd64.deb/{print $2}' | cut -d'<' -f1 | head -1)
|
||||
deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
|
||||
deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb"
|
||||
else
|
||||
deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
|
||||
deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
|
||||
deb_kernel_name="linux-image-${kernel}-i386.deb"
|
||||
modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F'\">' '/i386.deb/{print $2}' | cut -d'<' -f1 | head -1)
|
||||
deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
|
||||
deb_kernel_modules_name="linux-modules-${kernel}-i386.deb"
|
||||
fi
|
||||
|
||||
[ -z ${deb_name} ] && echo -e "${red}Error:${plain} Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again." && exit 1
|
||||
}
|
||||
|
||||
get_opsy() {
|
||||
[ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
|
||||
[ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
|
||||
[ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
|
||||
}
|
||||
|
||||
opsy=$( get_opsy )
|
||||
arch=$( uname -m )
|
||||
lbit=$( getconf LONG_BIT )
|
||||
kern=$( uname -r )
|
||||
|
||||
get_char() {
|
||||
SAVEDSTTY=`stty -g`
|
||||
stty -echo
|
||||
stty cbreak
|
||||
dd if=/dev/tty bs=1 count=1 2> /dev/null
|
||||
stty -raw
|
||||
stty echo
|
||||
stty $SAVEDSTTY
|
||||
}
|
||||
|
||||
getversion() {
|
||||
if [[ -s /etc/redhat-release ]]; then
|
||||
grep -oE "[0-9.]+" /etc/redhat-release
|
||||
else
|
||||
grep -oE "[0-9.]+" /etc/issue
|
||||
fi
|
||||
}
|
||||
|
||||
centosversion() {
|
||||
if [ x"${release}" == x"centos" ]; then
|
||||
local code=$1
|
||||
local version="$(getversion)"
|
||||
local main_ver=${version%%.*}
|
||||
if [ "$main_ver" == "$code" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_bbr_status() {
|
||||
local param=$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')
|
||||
if [[ x"${param}" == x"bbr" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_kernel_version() {
|
||||
local kernel_version=$(uname -r | cut -d- -f1)
|
||||
if version_ge ${kernel_version} 4.9; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_elrepo() {
|
||||
|
||||
if centosversion 5; then
|
||||
echo -e "${red}Error:${plain} not supported CentOS 5."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
|
||||
|
||||
if centosversion 6; then
|
||||
rpm -Uvh https://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
|
||||
elif centosversion 7; then
|
||||
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
|
||||
fi
|
||||
|
||||
if [ ! -f /etc/yum.repos.d/elrepo.repo ]; then
|
||||
echo -e "${red}Error:${plain} Install elrepo failed, please check it."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
sysctl_config() {
|
||||
sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf
|
||||
sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
|
||||
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
|
||||
sysctl -p >/dev/null 2>&1
|
||||
}
|
||||
|
||||
install_config() {
|
||||
if [[ x"${release}" == x"centos" ]]; then
|
||||
if centosversion 6; then
|
||||
if [ ! -f "/boot/grub/grub.conf" ]; then
|
||||
echo -e "${red}Error:${plain} /boot/grub/grub.conf not found, please check it."
|
||||
exit 1
|
||||
fi
|
||||
sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf
|
||||
elif centosversion 7; then
|
||||
if [ ! -f "/boot/grub2/grub.cfg" ]; then
|
||||
echo -e "${red}Error:${plain} /boot/grub2/grub.cfg not found, please check it."
|
||||
exit 1
|
||||
fi
|
||||
grub2-set-default 0
|
||||
fi
|
||||
elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
|
||||
/usr/sbin/update-grub
|
||||
fi
|
||||
}
|
||||
|
||||
reboot_os() {
|
||||
echo
|
||||
echo -e "${green}Info:${plain} The system needs to reboot."
|
||||
# read -p "Do you want to restart system? [y/n]" is_reboot
|
||||
# if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then
|
||||
# reboot
|
||||
# else
|
||||
# echo -e "${green}Info:${plain} Reboot has been canceled..."
|
||||
# exit 0
|
||||
# fi
|
||||
}
|
||||
|
||||
install_bbr() {
|
||||
check_bbr_status
|
||||
if [ $? -eq 0 ]; then
|
||||
echo
|
||||
echo -e "${green}Info:${plain} TCP BBR has already been installed. nothing to do..."
|
||||
exit 0
|
||||
fi
|
||||
check_kernel_version
|
||||
if [ $? -eq 0 ]; then
|
||||
echo
|
||||
echo -e "${green}Info:${plain} Your kernel version is greater than 4.9, directly setting TCP BBR..."
|
||||
sysctl_config
|
||||
echo -e "${green}Info:${plain} Setting TCP BBR completed..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ x"${release}" == x"centos" ]]; then
|
||||
install_elrepo
|
||||
[ ! "$(command -v yum-config-manager)" ] && yum install -y yum-utils > /dev/null 2>&1
|
||||
[ x"$(yum-config-manager elrepo-kernel | grep -w enabled | awk '{print $3}')" != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null 2>&1
|
||||
if centosversion 6; then
|
||||
if is_64bit; then
|
||||
rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm"
|
||||
rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm"
|
||||
rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/x86_64/RPMS/"
|
||||
else
|
||||
rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.i686.rpm"
|
||||
rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm"
|
||||
rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/i386/RPMS/"
|
||||
fi
|
||||
rpm_kernel_url_2="https://dl.lamp.sh/files/"
|
||||
wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_1}${rpm_kernel_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf ${rpm_kernel_name}
|
||||
wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_2}${rpm_kernel_name}
|
||||
fi
|
||||
wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_1}${rpm_kernel_devel_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
rm -rf ${rpm_kernel_devel_name}
|
||||
wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_2}${rpm_kernel_devel_name}
|
||||
fi
|
||||
if [ -f "${rpm_kernel_name}" ]; then
|
||||
rpm -ivh ${rpm_kernel_name}
|
||||
else
|
||||
echo -e "${red}Error:${plain} Download ${rpm_kernel_name} failed, please check it."
|
||||
exit 1
|
||||
fi
|
||||
if [ -f "${rpm_kernel_devel_name}" ]; then
|
||||
rpm -ivh ${rpm_kernel_devel_name}
|
||||
else
|
||||
echo -e "${red}Error:${plain} Download ${rpm_kernel_devel_name} failed, please check it."
|
||||
exit 1
|
||||
fi
|
||||
rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name}
|
||||
elif centosversion 7; then
|
||||
yum -y install kernel-ml kernel-ml-devel
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error:${plain} Install latest kernel failed, please check it."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
|
||||
[[ ! -e "/usr/bin/wget" ]] && apt-get -y update && apt-get -y install wget
|
||||
echo -e "${green}Info:${plain} Getting latest kernel version..."
|
||||
get_latest_version
|
||||
if [ -n ${modules_deb_name} ]; then
|
||||
wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error:${plain} Download ${deb_kernel_modules_name} failed, please check it."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error:${plain} Download ${deb_kernel_name} failed, please check it."
|
||||
exit 1
|
||||
fi
|
||||
[ -f ${deb_kernel_modules_name} ] && dpkg -i ${deb_kernel_modules_name}
|
||||
dpkg -i ${deb_kernel_name}
|
||||
rm -f ${deb_kernel_name} ${deb_kernel_modules_name}
|
||||
else
|
||||
echo -e "${red}Error:${plain} OS is not be supported, please change to CentOS/Debian/Ubuntu and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install_config
|
||||
sysctl_config
|
||||
reboot_os
|
||||
}
|
||||
|
||||
|
||||
clear
|
||||
echo "---------- System Information ----------"
|
||||
echo " OS : $opsy"
|
||||
echo " Arch : $arch ($lbit Bit)"
|
||||
echo " Kernel : $kern"
|
||||
echo "----------------------------------------"
|
||||
echo " Auto install latest kernel for TCP BBR"
|
||||
echo
|
||||
echo " URL: https://teddysun.com/489.html"
|
||||
echo "----------------------------------------"
|
||||
echo
|
||||
# echo "Press any key to start...or Press Ctrl+C to cancel"
|
||||
# char=`get_char`
|
||||
|
||||
#install_bbr 2>&1 | tee ${cur_dir}/install_bbr.log
|
||||
install_bbr
|
||||
@@ -25,14 +25,17 @@ resetPluginWinWidth(700);
|
||||
$.getScript( "/plugins/file?name=csvn&f=js/csvn.js");
|
||||
|
||||
function csvnReadme(){
|
||||
var html = '<p>* 注意:在启动时会比较慢,需要耐心等待一会</p>';
|
||||
html += '<p>* 注意:csvn需要java环境,在安装会自动检查并安装</p>';
|
||||
html += '<p>* 注意:默认后台密码admin:admin,最好马上修改</p>';
|
||||
html += '<p>* 注意:牢记admin的密码,在后csvn的管理后台和这里不同步</p>';
|
||||
html += '<p>* 注意:在这里添加用户和csvn后台并不同步</p>';
|
||||
html += '<p>* 注意:项目管理的地址一般是正确的,但在特殊环境下,地址可能不一致</p>';
|
||||
html += '<p>* 注意:脚本内使用sudo名,需要注释(vi /etc/sudoers)[#Default requiretty]</p>';
|
||||
|
||||
$('.bt-w-main .soft-man-con').html(html);
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>注意:在启动时会比较慢,需要耐心等待一会</li>';
|
||||
readme += '<li>注意:csvn需要java环境,在安装会自动检查并安装</li>';
|
||||
readme += '<li>注意:默认后台密码admin:admin,最好马上修改</li>';
|
||||
readme += '<li>注意:牢记admin的密码,在后csvn的管理后台和这里不同步</li>';
|
||||
readme += '<li>注意:在这里添加用户和csvn后台并不同步</li>';
|
||||
readme += '<li>注意:项目管理的地址一般是正确的,但在特殊环境下,地址可能不一致</li>';
|
||||
readme += '<li>注意:脚本内使用sudo名,需要注释(vi /etc/sudoers)[#Default requiretty]</li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.bt-w-main .soft-man-con').html(readme);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"updates":"5.1.4",
|
||||
"tip": "soft",
|
||||
"checks": "server/csvn",
|
||||
"path":"server/csvn",
|
||||
"author": "midoks",
|
||||
"date": "2017-04-01",
|
||||
"home": "https://www.collab.net",
|
||||
|
||||
@@ -7,7 +7,7 @@ rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
CSVN_SOURCE='https://github.com/midoks/mdserver-web/releases/download/init/CollabNetSubversionEdge-5.1.4_linux-x86_64.tar.xz'
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"title":"GAE",
|
||||
"tip":"soft",
|
||||
"name":"gae",
|
||||
"ps":"GAE(Google App Engine)。它是Google管理的数据中心中用于WEB应用程序的开发和托管的平台",
|
||||
"ps":"GAE是Google用于WEB应用程序的开发和托管的平台",
|
||||
"versions": "0.1",
|
||||
"shell":"install.sh",
|
||||
"checks":"server/gae",
|
||||
|
||||
@@ -7,7 +7,7 @@ rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
Install_gae()
|
||||
{
|
||||
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,21 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('go-fastdfs-web');">服务</p>
|
||||
<p onclick="pluginInitD('go-fastdfs-web');">自启动</p>
|
||||
<p onclick="pluginConfig('go-fastdfs-web');">配置</p>
|
||||
<p onclick="pluginLogs('go-fastdfs-web','','run_log');">运行日志</p>
|
||||
<p onclick="pRead()">说明</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(700);
|
||||
$.getScript( "/plugins/file?name=go-fastdfs-web&f=js/fastdfs.js", function() {
|
||||
pluginService('go-fastdfs');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,195 @@
|
||||
# coding: utf-8
|
||||
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import public
|
||||
|
||||
app_debug = False
|
||||
if public.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'go-fastdfs-web'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return public.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return public.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
return '/tmp/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
return getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
|
||||
|
||||
def getLog():
|
||||
return getServerDir() + "/log/fileserver.log"
|
||||
|
||||
|
||||
def gfBreakpointLog():
|
||||
return getServerDir() + "/log/tusd.log"
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, public.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, public.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def status():
|
||||
pn = getPluginName()
|
||||
data = public.execShell(
|
||||
"ps -ef|grep " + pn + " | grep -v grep | grep -v python | awk '{print $2}'")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
if not os.path.exists(file_bin):
|
||||
content = public.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
public.writeFile(file_bin, content)
|
||||
public.execShell('chmod +x ' + file_bin)
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def start():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' start')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def stop():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' stop')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def restart():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' restart')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def reload():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' reload')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdStatus():
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
import shutil
|
||||
|
||||
source_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(source_bin, initd_bin)
|
||||
public.execShell('chmod +x ' + initd_bin)
|
||||
|
||||
if not app_debug:
|
||||
public.execShell('chkconfig --add ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
if not app_debug:
|
||||
public.execShell('chkconfig --del ' + getPluginName())
|
||||
|
||||
initd_bin = getInitDFile()
|
||||
|
||||
if os.path.exists(initd_bin):
|
||||
os.remove(initd_bin)
|
||||
return 'ok'
|
||||
|
||||
|
||||
def gfConf():
|
||||
return getServerDir() + "/config/application-prod.properties"
|
||||
|
||||
def getLog():
|
||||
return getServerDir() + "/logs/go-fastdfs-web.log"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print status()
|
||||
elif func == 'start':
|
||||
print start()
|
||||
elif func == 'stop':
|
||||
print stop()
|
||||
elif func == 'restart':
|
||||
print restart()
|
||||
elif func == 'reload':
|
||||
print reload()
|
||||
elif func == 'initd_status':
|
||||
print initdStatus()
|
||||
elif func == 'initd_install':
|
||||
print initdInstall()
|
||||
elif func == 'initd_uninstall':
|
||||
print initdUinstall()
|
||||
elif func == 'run_log':
|
||||
print getLog()
|
||||
elif func == 'conf':
|
||||
print gfConf()
|
||||
else:
|
||||
print 'error'
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"id":10,
|
||||
"title":"go-fastdfs-web",
|
||||
"tip":"soft",
|
||||
"name":"go-fastdfs-web",
|
||||
"type":"软件",
|
||||
"ps":"Go-Fastdfs web管理平台",
|
||||
"versions":"1.1.2",
|
||||
"shell":"install.sh",
|
||||
"checks":"server/go-fastdfs-web",
|
||||
"path": "server/go-fastdfs-web",
|
||||
"author":"midoks",
|
||||
"home":"https://github.com/perfree/go-fastdfs-web",
|
||||
"date":"2019-08-07",
|
||||
"pid":"2"
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
# chkconfig: 2345 55 25
|
||||
# description: go-fastdfs-web Cloud Service
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: bt
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: starts go-fastdfs-web
|
||||
# Description: starts the go-fastdfs-web
|
||||
### END INIT INFO
|
||||
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
|
||||
SpringBoot=go-fastdfs-web.jar
|
||||
gf_path={$SERVER_PATH}/go-fastdfs-web/$SpringBoot
|
||||
|
||||
if [ "$1" = "" ];
|
||||
then
|
||||
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$SpringBoot" = "" ];
|
||||
then
|
||||
echo -e "\033[0;31m 未输入应用名 \033[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function start()
|
||||
{
|
||||
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
|
||||
if [ $count != 0 ];then
|
||||
echo "$SpringBoot is running..."
|
||||
else
|
||||
echo "Start $SpringBoot success..."
|
||||
cd $gf_path
|
||||
nohup java -jar $SpringBoot > /dev/null 2>&1 &
|
||||
fi
|
||||
}
|
||||
|
||||
function stop()
|
||||
{
|
||||
echo "Stop $SpringBoot"
|
||||
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
|
||||
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
|
||||
|
||||
if [ $count != 0 ];then
|
||||
kill $boot_id
|
||||
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
|
||||
|
||||
boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'`
|
||||
kill -9 $boot_id
|
||||
fi
|
||||
}
|
||||
|
||||
function restart()
|
||||
{
|
||||
stop
|
||||
sleep 2
|
||||
start
|
||||
}
|
||||
|
||||
function status()
|
||||
{
|
||||
count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l`
|
||||
if [ $count != 0 ];then
|
||||
echo "$SpringBoot is running..."
|
||||
else
|
||||
echo "$SpringBoot is not running..."
|
||||
fi
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
start;;
|
||||
stop)
|
||||
stop;;
|
||||
restart)
|
||||
restart;;
|
||||
status)
|
||||
status;;
|
||||
*)
|
||||
|
||||
echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m
|
||||
\033[0;31m Example: \033[0m
|
||||
\033[0;33m sh $0 start esmart-test.jar \033[0m"
|
||||
esac
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
action=$1
|
||||
version=$2
|
||||
Install_gf()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/go-fastdfs-web
|
||||
FF_DIR=${serverPath}/go-fastdfs-web
|
||||
cd $FF_DIR
|
||||
|
||||
if [ $sysName == 'Darwin' ]; then
|
||||
FF_SS_DIR=${serverPath}/source/go-fastdfs-web
|
||||
mkdir -p $FF_SS_DIR
|
||||
if [ ! -f $FF_SS_DIR/go-fastdfs-web-1.1.2.tar.gz ]; then
|
||||
wget -O $FF_SS_DIR/go-fastdfs-web-1.1.2.tar.gz https://github.com/perfree/go-fastdfs-web/releases/download/1.1.2/go-fastdfs-web-1.1.2.tar.gz
|
||||
fi
|
||||
|
||||
cd $FF_SS_DIR
|
||||
if [ ! -d $FF_SS_DIR/go-fastdfs-web ]; then
|
||||
tar -zxvf $FF_SS_DIR/go-fastdfs-web-1.1.2.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d $FF_DIR/config ];then
|
||||
cp -rf $FF_SS_DIR/go-fastdfs-web/* $FF_DIR/
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$version" > $FF_DIR/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_gf()
|
||||
{
|
||||
rm -rf $serverPath/go-fastdfs-web
|
||||
echo "卸载完成" > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_gf $version
|
||||
else
|
||||
Uninstall_gf $version
|
||||
fi
|
||||
@@ -0,0 +1,47 @@
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function pPost(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var _title = '正在获取...';
|
||||
if (typeof(title) != 'undefined'){
|
||||
_title = title;
|
||||
}
|
||||
|
||||
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'go-fastdfs-web', func:method, args:_args}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
|
||||
function pRead(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>根据配置查看,开启相应防火墙端口</li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,23 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('go-fastdfs');">服务</p>
|
||||
<p onclick="pluginInitD('go-fastdfs');">自启动</p>
|
||||
<p onclick="pluginConfig('go-fastdfs');">配置文件</p>
|
||||
<p onclick="gfConfigSet()">重要配置查看</p>
|
||||
<p onclick="pluginLogs('go-fastdfs','','run_log');">运行日志</p>
|
||||
<p onclick="pluginLogs('go-fastdfs','','breakpoint_log');">断点日志</p>
|
||||
<p onclick="pRead()">说明</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(700);
|
||||
$.getScript( "/plugins/file?name=go-fastdfs&f=js/fastdfs.js", function() {
|
||||
pluginService('go-fastdfs');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,224 @@
|
||||
# coding: utf-8
|
||||
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import public
|
||||
|
||||
app_debug = False
|
||||
if public.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'go-fastdfs'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return public.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return public.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
return '/tmp/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
return getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
|
||||
|
||||
def getLog():
|
||||
return getServerDir() + "/log/fileserver.log"
|
||||
|
||||
|
||||
def gfBreakpointLog():
|
||||
return getServerDir() + "/log/tusd.log"
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, public.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, public.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def status():
|
||||
pn = getPluginName()
|
||||
data = public.execShell(
|
||||
"ps -ef|grep " + pn + " |grep -v grep |grep -v .jar | grep -v python | awk '{print $2}'")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
if not os.path.exists(file_bin):
|
||||
content = public.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
public.writeFile(file_bin, content)
|
||||
public.execShell('chmod +x ' + file_bin)
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def start():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' start')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def stop():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' stop')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def restart():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' restart')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def reload():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' reload')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdStatus():
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
import shutil
|
||||
|
||||
source_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(source_bin, initd_bin)
|
||||
public.execShell('chmod +x ' + initd_bin)
|
||||
|
||||
if not app_debug:
|
||||
public.execShell('chkconfig --add ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
if not app_debug:
|
||||
public.execShell('chkconfig --del ' + getPluginName())
|
||||
|
||||
initd_bin = getInitDFile()
|
||||
|
||||
if os.path.exists(initd_bin):
|
||||
os.remove(initd_bin)
|
||||
return 'ok'
|
||||
|
||||
|
||||
def gfConf():
|
||||
return getServerDir() + "/conf/cfg.json"
|
||||
|
||||
|
||||
def gfConfSet():
|
||||
gets = [
|
||||
{'name': 'addr', 'type': -1, 'ps': '绑定端口'},
|
||||
{'name': 'peer_id', 'type': -1, 'ps': '集群内唯一,请使用0-9的单字符'},
|
||||
{'name': 'host', 'type': -1, 'ps': '本主机地址'},
|
||||
{'name': 'group', 'type': -1, 'ps': '组号'},
|
||||
{'name': 'support_group_manage', 'type': 0, 'ps': '是否支持按组(集群)管理'},
|
||||
{'name': 'enable_merge_small_file', 'type': 0, 'ps': '是否合并小文件'},
|
||||
{'name': 'refresh_interval', 'type': 1, 'ps': '重试同步失败文件的时间'},
|
||||
{'name': 'rename_file', 'type': 0, 'ps': '是否自动重命名'},
|
||||
{'name': 'enable_web_upload', 'type': 0, 'ps': '是否支持web上传,方便调试'},
|
||||
{'name': 'enable_custom_path', 'type': 0, 'ps': '是否支持非日期路径'},
|
||||
{'name': 'enable_migrate', 'type': 0, 'ps': '是否启用迁移'},
|
||||
{'name': 'enable_cross_origin', 'type': 0, 'ps': '是否开启跨站访问'},
|
||||
{'name': 'enable_tus', 'type': 0, 'ps': '是否开启断点续传'}
|
||||
]
|
||||
file = public.readFile(gfConf())
|
||||
data = json.loads(file)
|
||||
|
||||
result = []
|
||||
for g in gets:
|
||||
if g['name'] in data:
|
||||
g['value'] = data[g['name']]
|
||||
result.append(g)
|
||||
|
||||
return public.getJson(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print status()
|
||||
elif func == 'start':
|
||||
print start()
|
||||
elif func == 'stop':
|
||||
print stop()
|
||||
elif func == 'restart':
|
||||
print restart()
|
||||
elif func == 'reload':
|
||||
print reload()
|
||||
elif func == 'initd_status':
|
||||
print initdStatus()
|
||||
elif func == 'initd_install':
|
||||
print initdInstall()
|
||||
elif func == 'initd_uninstall':
|
||||
print initdUinstall()
|
||||
elif func == 'run_log':
|
||||
print getLog()
|
||||
elif func == 'breakpoint_log':
|
||||
print gfBreakpointLog()
|
||||
elif func == 'conf':
|
||||
print gfConf()
|
||||
elif func == 'gf_conf_set':
|
||||
print gfConfSet()
|
||||
else:
|
||||
print 'error'
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"id":10,
|
||||
"title":"go-fastdfs",
|
||||
"tip":"soft",
|
||||
"name":"go-fastdfs",
|
||||
"type":"软件",
|
||||
"ps":"一个基于http协议的分布式文件系统",
|
||||
"versions":"1.3.1",
|
||||
"shell":"install.sh",
|
||||
"checks":"server/go-fastdfs",
|
||||
"path": "server/go-fastdfs",
|
||||
"author":"midoks",
|
||||
"home":"https://github.com/sjqzhang/go-fastdfs",
|
||||
"date":"2019-08-02",
|
||||
"pid":"2"
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
# chkconfig: 2345 55 25
|
||||
# description: go-fastdfs Cloud Service
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: bt
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: starts go-fastdfs
|
||||
# Description: starts the go-fastdfs
|
||||
### END INIT INFO
|
||||
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
|
||||
gf_path={$SERVER_PATH}/go-fastdfs
|
||||
|
||||
gf_start(){
|
||||
isStart=`ps -ef| grep -v python|grep -v bash |grep go-fastdfs |grep -v .jar | grep -v grep|awk '{print $2}'`
|
||||
if [ "$isStart" == '' ];then
|
||||
echo -e "Starting go-fastdfs... \c"
|
||||
cd $gf_path
|
||||
nohup ./go-fastdfs > /dev/null 2>&1 &
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
else
|
||||
echo -e "Starting go-fastdfs(pid $(echo $isStart)) already running"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
gf_stop()
|
||||
{
|
||||
echo -e "Stopping go-fastdfs... \c"
|
||||
|
||||
pids=$(ps -ef| grep -v python |grep -v bash |grep go-fastdfs |grep -v .jar | grep -v grep | awk '{print $2}')
|
||||
arr=($pids)
|
||||
|
||||
for p in ${arr[@]}
|
||||
do
|
||||
kill -9 $p
|
||||
done
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
}
|
||||
|
||||
gf_status()
|
||||
{
|
||||
isStart=$(ps -ef | grep -v python | grep -v bash | grep go-fastdfs |grep -v .jar | grep -v grep | awk '{print $2}')
|
||||
if [ "$isStart" != '' ];then
|
||||
echo -e "\033[32mgo-fastdfs (pid $(echo $isStart)) already running\033[0m"
|
||||
else
|
||||
echo -e "\033[31mgo-fastdfs not running\033[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
gf_reload()
|
||||
{
|
||||
gf_stop
|
||||
gf_start
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'start') gf_start;;
|
||||
'stop') gf_stop;;
|
||||
'reload') gf_reload;;
|
||||
'status') gf_status;;
|
||||
'restart')
|
||||
gf_stop
|
||||
gf_start;;
|
||||
esac
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
action=$1
|
||||
version=$2
|
||||
Install_gf()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/go-fastdfs
|
||||
FF_DIR=${serverPath}/go-fastdfs
|
||||
cd $FF_DIR
|
||||
|
||||
if [ $sysName == 'Darwin' ]; then
|
||||
FF_SS_DIR=${serverPath}/source/go-fastdfs
|
||||
mkdir -p $FF_SS_DIR
|
||||
if [ ! -f $FF_SS_DIR/v1.3.1.tar.gz ]; then
|
||||
wget -O $FF_SS_DIR/v1.3.1.tar.gz https://github.com/sjqzhang/go-fastdfs/archive/v1.3.1.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d $FF_SS_DIR/go-fastdfs-1.3.1 ]; then
|
||||
cd $FF_SS_DIR && tar -zxvf $FF_SS_DIR/v1.3.1.tar.gz
|
||||
fi
|
||||
|
||||
|
||||
cd $FF_SS_DIR/go-fastdfs-1.3.1
|
||||
|
||||
if [ -d $FF_SS_DIR/go-fastdfs-1.3.1/vendor ];then
|
||||
mv vendor src
|
||||
fi
|
||||
|
||||
if [ ! -f $FF_SS_DIR/go-fastdfs-1.3.1/fileserver ]; then
|
||||
pwd=`pwd`
|
||||
echo "$pwd go build -o fileserver fileserver.go"
|
||||
GOPATH=$pwd go build -o fileserver fileserver.go
|
||||
fi
|
||||
|
||||
if [ ! -f $FF_DIR/go-fastdfs ];then
|
||||
cp -f fileserver $FF_DIR/go-fastdfs
|
||||
|
||||
cd $FF_DIR
|
||||
fi
|
||||
else
|
||||
cd $FF_DIR
|
||||
if [ ! -f ${FF_DIR}/fileserver ];then
|
||||
wget --no-check-certificate https://github.com/sjqzhang/go-fastdfs/releases/download/v1.3.1/fileserver -O fileserver
|
||||
chmod +x fileserver
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
echo "$version" > $FF_DIR/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_gf()
|
||||
{
|
||||
rm -rf $serverPath/go-fastdfs
|
||||
echo "卸载完成" > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_gf $version
|
||||
else
|
||||
Uninstall_gf $version
|
||||
fi
|
||||
@@ -0,0 +1,93 @@
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function pPost(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var _title = '正在获取...';
|
||||
if (typeof(title) != 'undefined'){
|
||||
_title = title;
|
||||
}
|
||||
|
||||
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'go-fastdfs', func:method, args:_args}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
|
||||
function gfConfigSet(){
|
||||
pPost('gf_conf_set', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
var mlist = '';
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
var w = '140';
|
||||
if (rdata[i].name == 'error_reporting') w = '250';
|
||||
var ibody = '<input style="width: ' + w + 'px;" class="bt-input-text mr5" name="' + rdata[i].name + '" value="' + rdata[i].value + '" type="text" >';
|
||||
switch (rdata[i].type) {
|
||||
case 0:
|
||||
var selected_1 = (rdata[i].value == 1) ? 'selected' : '';
|
||||
var selected_0 = (rdata[i].value == 0) ? 'selected' : '';
|
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
|
||||
<option value="1" ' + selected_1 + '>开启</option>\
|
||||
<option value="0" ' + selected_0 + '>关闭</option>\
|
||||
</select>';
|
||||
break;
|
||||
case 1:
|
||||
var selected_1 = (rdata[i].value == 'On') ? 'selected' : '';
|
||||
var selected_0 = (rdata[i].value == 'Off') ? 'selected' : '';
|
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
|
||||
<option value="On" ' + selected_1 + '>开启</option>\
|
||||
<option value="Off" ' + selected_0 + '>关闭</option></select>'
|
||||
break;
|
||||
case 2:
|
||||
var selected_1 = (rdata[i].value == 'true') ? 'selected' : '';
|
||||
var selected_0 = (rdata[i].value == 'false') ? 'selected' : '';
|
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
|
||||
<option value="true" ' + selected_1 + '>开启</option>\
|
||||
<option value="false" ' + selected_0 + '>关闭</option></select>'
|
||||
break;
|
||||
}
|
||||
mlist += '<p><span>' + rdata[i].name + '</span>' + ibody + ', <font>' + rdata[i].ps + '</font></p>'
|
||||
}
|
||||
var html = '<style>.conf_p p{margin-bottom: 2px}</style><div class="conf_p" style="margin-bottom:0">\
|
||||
' + mlist + '\
|
||||
<div style="margin-top:10px; padding-right:15px" class="text-right">\
|
||||
</div>';
|
||||
$(".soft-man-con").html(html);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function pRead(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>官方地址<a target="_blank" href="https://github.com/sjqzhang/go-fastdfs">查看</a></li>';
|
||||
readme += '<li>如果开启防火墙,需要放行端口,例如(8080)</li>';
|
||||
readme += '<li>要自行配置openresty</li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
@@ -13,7 +13,7 @@ PATH = data/gogs.db
|
||||
|
||||
[repository]
|
||||
ROOT = {$ROOT_PATH}/gogs-repositories
|
||||
FORCE_PRIVATE = false
|
||||
FORCE_PRIVATE = true
|
||||
|
||||
[server]
|
||||
DOMAIN = 127.0.0.1
|
||||
@@ -35,9 +35,9 @@ USE_PLAIN_TEXT = true
|
||||
[service]
|
||||
REGISTER_EMAIL_CONFIRM = false
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
DISABLE_REGISTRATION = false
|
||||
DISABLE_REGISTRATION = true
|
||||
ENABLE_CAPTCHA = true
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
REQUIRE_SIGNIN_VIEW = true
|
||||
|
||||
[picture]
|
||||
DISABLE_GRAVATAR = false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
GITADDR="{$GITROOTURL}{$USERNAME}/{$PROJECT}"
|
||||
GITADDR="{$GITROOTURL}/{$USERNAME}/{$PROJECT}"
|
||||
GIT_SDIR="{$CODE_DIR}"
|
||||
|
||||
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -14,7 +14,7 @@ import public
|
||||
|
||||
|
||||
app_debug = False
|
||||
if public.getOs() == 'darwin':
|
||||
if public.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
@@ -46,11 +46,11 @@ def getArgs():
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
t = t.split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
t = args[i].split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
@@ -84,19 +84,37 @@ def status():
|
||||
return 'start'
|
||||
|
||||
|
||||
def contentReplace(content):
|
||||
user = 'root'
|
||||
def getHomeDir():
|
||||
if public.isAppleSystem():
|
||||
user = public.execShell(
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
content = content.replace('{$HOME_DIR}', '/Users/' + user)
|
||||
return '/Users/' + user
|
||||
else:
|
||||
content = content.replace('{$HOME_DIR}', '/root')
|
||||
return '/root'
|
||||
|
||||
|
||||
def getRunUser():
|
||||
if public.isAppleSystem():
|
||||
user = public.execShell(
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
return user
|
||||
else:
|
||||
return 'root'
|
||||
|
||||
__SR = '''#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
export USER=%s
|
||||
export HOME=%s && ''' % ( getRunUser(), getHomeDir())
|
||||
|
||||
|
||||
def contentReplace(content):
|
||||
|
||||
service_path = public.getServerDir()
|
||||
content = content.replace('{$ROOT_PATH}', public.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$RUN_USER}', user)
|
||||
content = content.replace('{$RUN_USER}', getRunUser())
|
||||
content = content.replace('{$HOME_DIR}', getHomeDir())
|
||||
|
||||
return content
|
||||
|
||||
@@ -141,6 +159,15 @@ def getRootUrl():
|
||||
return tmp.groups()[0]
|
||||
|
||||
|
||||
def getSshPort():
|
||||
content = public.readFile(getConf())
|
||||
rep = 'SSH_PORT\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if not tmp:
|
||||
return ''
|
||||
return tmp.groups()[0]
|
||||
|
||||
|
||||
def getRootPath():
|
||||
content = public.readFile(getConf())
|
||||
rep = 'ROOT\s*=\s*(.*)'
|
||||
@@ -221,7 +248,7 @@ def start():
|
||||
if not data['status']:
|
||||
return data['msg']
|
||||
|
||||
data = public.execShell(file + ' start')
|
||||
data = public.execShell(__SR + file + ' start')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[0]
|
||||
@@ -229,7 +256,7 @@ def start():
|
||||
|
||||
def stop():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' stop')
|
||||
data = public.execShell(__SR + file + ' stop')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
@@ -237,7 +264,7 @@ def stop():
|
||||
|
||||
def restart():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' reload')
|
||||
data = public.execShell(__SR + file + ' restart')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
@@ -245,7 +272,7 @@ def restart():
|
||||
|
||||
def reload():
|
||||
file = initDreplace()
|
||||
data = public.execShell(file + ' reload')
|
||||
data = public.execShell(__SR + file + ' reload')
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
@@ -273,6 +300,7 @@ def initdInstall():
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(mem_bin, initd_bin)
|
||||
public.execShell('chmod +x ' + initd_bin)
|
||||
public.execShell('chkconfig --add ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
@@ -283,6 +311,7 @@ def initdUinstall():
|
||||
return "Apple Computer does not support"
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
public.execShell('chkconfig --del ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
@@ -476,7 +505,7 @@ def projectScriptEdit():
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
post_receive = getRootPath() + '/' + user + '/' + name + \
|
||||
'/custom_hooks/post-receive'
|
||||
'/custom_hooks/commit'
|
||||
if os.path.exists(post_receive):
|
||||
return public.returnJson(True, 'OK', {'path': post_receive})
|
||||
else:
|
||||
@@ -512,7 +541,9 @@ def projectScriptLoad():
|
||||
codeDir = public.getRootDir() + '/git'
|
||||
|
||||
cc_content = public.readFile(commit_tpl)
|
||||
cc_content = cc_content.replace('{$GITROOTURL}', getRootUrl())
|
||||
|
||||
sshUrl = 'ssh://127.0.0.1:' + getSshPort()
|
||||
cc_content = cc_content.replace('{$GITROOTURL}', sshUrl)
|
||||
cc_content = cc_content.replace('{$CODE_DIR}', codeDir)
|
||||
cc_content = cc_content.replace('{$USERNAME}', user)
|
||||
cc_content = cc_content.replace('{$PROJECT}', args['name'])
|
||||
@@ -574,6 +605,17 @@ def gogsEdit():
|
||||
return public.getJson(data)
|
||||
|
||||
|
||||
def getRsaPublic():
|
||||
path = getHomeDir()
|
||||
path += '/.ssh/id_rsa.pub'
|
||||
|
||||
content = public.readFile(path)
|
||||
|
||||
data = {}
|
||||
data['public'] = content
|
||||
return public.getJson(data)
|
||||
|
||||
|
||||
def getTotalStatistics():
|
||||
st = status()
|
||||
data = {}
|
||||
@@ -591,6 +633,7 @@ def getTotalStatistics():
|
||||
data['count'] = 0
|
||||
return public.returnJson(False, 'fail', data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
@@ -635,6 +678,8 @@ if __name__ == "__main__":
|
||||
print projectScriptDebug()
|
||||
elif func == 'gogs_edit':
|
||||
print gogsEdit()
|
||||
elif func == 'get_rsa_public':
|
||||
print getRsaPublic()
|
||||
elif func == 'get_total_statistics':
|
||||
print getTotalStatistics()
|
||||
else:
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
"ps": "Gogs是一款极易搭建的自助Git服务",
|
||||
"name": "gogs",
|
||||
"title": "Gogs",
|
||||
"versions": ["0.11.86","0.11.79"],
|
||||
"versions": ["0.11.86"],
|
||||
"tip": "soft",
|
||||
"checks": "server/gogs",
|
||||
"path":"server/gogs",
|
||||
"author": "midoks",
|
||||
"date": "201-04-01",
|
||||
"home": "https://gogs.io",
|
||||
|
||||
@@ -25,12 +25,17 @@ if [ -f /etc/init.d/functions ];then
|
||||
. /etc/init.d/functions
|
||||
fi
|
||||
|
||||
if [ -f /etc/rc.d/init.d/functions ];then
|
||||
. /etc/rc.d/init.d/functions
|
||||
fi
|
||||
|
||||
# Default values
|
||||
HOME={$HOME_DIR}
|
||||
export HOME={$HOME_DIR}
|
||||
export USER={$RUN_USER}
|
||||
NAME=gogs
|
||||
GOGS_HOME={$SERVER_PATH}/gogs
|
||||
GOGS_PATH=${GOGS_HOME}/$NAME
|
||||
GOGS_USER=midoks
|
||||
GOGS_USER={$RUN_USER}
|
||||
SERVICENAME="Gogs"
|
||||
LOCKFILE=/tmp/gogs.lock
|
||||
LOGPATH=${GOGS_HOME}/log
|
||||
@@ -38,12 +43,17 @@ LOGFILE=${LOGPATH}/gogs.log
|
||||
RETVAL=0
|
||||
|
||||
|
||||
[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME
|
||||
DAEMON_OPTS="--check $NAME"
|
||||
[ ! -z "$GOGS_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${GOGS_USER}"
|
||||
|
||||
|
||||
status(){
|
||||
isStart=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
|
||||
if [ "$isStart" == '' ];then
|
||||
echo "${SERVICENAME} not running"
|
||||
echo -e "${SERVICENAME} not running"
|
||||
else
|
||||
echo "${SERVICENAME}(pid $(echo $isStart)) already running"
|
||||
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -55,24 +65,23 @@ start() {
|
||||
fi
|
||||
|
||||
cd ${GOGS_HOME}
|
||||
echo "Starting ${SERVICENAME}: \c"
|
||||
echo -e "Starting ${SERVICENAME}: \c"
|
||||
${GOGS_PATH} web > ${LOGFILE} 2>&1 &
|
||||
RETVAL=$?
|
||||
[ $RETVAL = 0 ] && touch ${LOCKFILE} && echo "\033[32mdone\033[0m"
|
||||
[ $RETVAL = 0 ] && touch ${LOCKFILE} && echo -e "\033[32mdone\033[0m"
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
stop() {
|
||||
cd ${GOGS_HOME}
|
||||
echo "Shutting down ${SERVICENAME}: \c"
|
||||
which "killproc" > /dev/null
|
||||
if [ $? -eq 0 ];then
|
||||
killproc ${NAME}
|
||||
else
|
||||
pkill ${NAME}
|
||||
fi
|
||||
RETVAL=$?
|
||||
[ $RETVAL = 0 ] && rm -f ${LOCKFILE} && echo "\033[32mdone\033[0m"
|
||||
|
||||
pids=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
|
||||
arr=($pids)
|
||||
echo -e "Stopping gogs... \c"
|
||||
for p in ${arr[@]}
|
||||
do
|
||||
kill -9 $p
|
||||
done
|
||||
echo -e "\033[32mdone\033[0m"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
|
||||
@@ -7,7 +7,7 @@ rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
GOGS_DOWNLOAD='https://dl.gogs.io'
|
||||
@@ -49,6 +49,14 @@ Install_gogs()
|
||||
mv $serverPath/source/gogs/gogs_${version}/gogs/ $serverPath/gogs
|
||||
echo $version > $serverPath/gogs/version.pl
|
||||
|
||||
# if id -u gogs > /dev/null 2>&1; then
|
||||
# echo "gogs user exists"
|
||||
# else
|
||||
# useradd gogs
|
||||
# cp /etc/sudoers{,.`date +"%Y-%m-%d_%H-%M-%S"`}
|
||||
# echo "gogs ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
# fi
|
||||
|
||||
echo 'install success' > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
@@ -87,13 +87,12 @@ function gogsSetConfig(){
|
||||
//提交PHP配置
|
||||
function submitGogsConf() {
|
||||
var data = {
|
||||
DOMAIN: $("select[name='DOMAIN']").val(),
|
||||
ROOT_URL: $("select[name='ROOT_URL']").val(),
|
||||
DOMAIN: $("input[name='DOMAIN']").val(),
|
||||
ROOT_URL: $("input[name='ROOT_URL']").val(),
|
||||
HTTP_ADDR: $("select[name='HTTP_ADDR']").val(),
|
||||
HTTP_PORT: $("select[name='HTTP_PORT']").val(),
|
||||
HTTP_PORT: $("input[name='HTTP_PORT']").val(),
|
||||
START_SSH_SERVER: $("select[name='START_SSH_SERVER']").val() || 'false',
|
||||
SSH_PORT: $("select[name='SSH_PORT']").val(),
|
||||
ROOT_URL: $("select[name='ROOT_URL']").val(),
|
||||
SSH_PORT: $("input[name='SSH_PORT']").val(),
|
||||
REQUIRE_SIGNIN_VIEW: $("select[name='REQUIRE_SIGNIN_VIEW']").val() || 'false',
|
||||
ENABLE_CAPTCHA: $("select[name='ENABLE_CAPTCHA']").val() || 'true',
|
||||
DISABLE_REGISTRATION: $("select[name='DISABLE_REGISTRATION']").val() || 'false',
|
||||
@@ -313,8 +312,35 @@ function projectScriptDebug(user,name){
|
||||
});
|
||||
}
|
||||
|
||||
function getRsaPublic(){
|
||||
gogsPost('get_rsa_public', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var con = '<div class="tab-con">\
|
||||
<div class="myKeyCon ptb15">\
|
||||
<textarea style="margin:0px;width:580px;height:110px;outline:none;" spellcheck="false">'+rdata.public+'</textarea>\
|
||||
</div>\
|
||||
<ul class="help-info-text c7 pull-left"></ul>\
|
||||
</div>'
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: "600px",
|
||||
title: '本机公钥',
|
||||
closeBtn: 2,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:con
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function gogsRead(){
|
||||
var readme = '<p>* 默认使用MySQL,第一个启动加载各种配置,并修改成正确的数据库配置</p>';
|
||||
readme += '<p>* 邮件端口使用456,gogs仅支持使用STARTTLS的SMTP协议</p>';
|
||||
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>默认使用MySQL,第一个启动加载各种配置,并修改成正确的数据库配置</li>';
|
||||
readme += '<li>邮件端口使用456,gogs仅支持使用STARTTLS的SMTP协议</li>';
|
||||
readme += '<li>如果使用项目中脚本本地同步,<a target="_blank" href="https://github.com/midoks/mdserver-web/wiki/%E6%8F%92%E4%BB%B6%E7%AE%A1%E7%90%86%5Bgogs%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%5D#%E5%90%AF%E5%8A%A8gogs%E5%90%8E%E5%A6%82%E6%9E%9C%E8%A6%81%E4%BD%BF%E7%94%A8hook%E8%84%9A%E6%9C%AC%E5%90%8C%E6%AD%A5%E4%BB%A3%E7%A0%81%E9%9C%80%E8%A6%81%E5%BC%80%E5%90%AFssh%E7%AB%AF%E5%8F%A3">点击查看</></li>';
|
||||
readme += '<li><a href="#" onclick="getRsaPublic();">点击查看本机公钥</></li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Mr Chen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,19 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('l2tp');">服务</p>
|
||||
<p onclick="pluginConfig('l2tp',null, 'conf');">用户配置</p>
|
||||
<p onclick="pluginConfig('l2tp',null, 'conf_psk');">PSK配置</p>
|
||||
<p onclick="userList();">用户列表</p>
|
||||
<p onclick="readme();">说明</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=l2tp&f=js/l2tp.js", function(){
|
||||
pluginService('l2tp');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,233 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import public
|
||||
|
||||
app_debug = False
|
||||
if public.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'l2tp'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return public.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return public.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, public.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, public.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def status():
|
||||
cmd = "ps -ef|grep xl2tpd |grep -v grep | grep -v python | awk '{print $2}'"
|
||||
data = public.execShell(cmd)
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initConf():
|
||||
l2tp_cs = getServerDir() + '/chap-secrets'
|
||||
if not os.path.exists(l2tp_cs):
|
||||
public.execShell('cp -rf ' + getPluginDir() +
|
||||
'/tmp/chap-secrets' + ' ' + getServerDir())
|
||||
|
||||
l2tp_is = getServerDir() + '/ipsec.secrets'
|
||||
if not os.path.exists(l2tp_is):
|
||||
public.execShell('cp -rf ' + getPluginDir() +
|
||||
'/tmp/ipsec.secrets' + ' ' + getServerDir())
|
||||
|
||||
|
||||
def start():
|
||||
initConf()
|
||||
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
data = public.execShell('service xl2tpd start')
|
||||
if data[0] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def stop():
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
data = public.execShell('service xl2tpd stop')
|
||||
if data[0] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def restart():
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
data = public.execShell('service xl2tpd restart')
|
||||
if data[0] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def reload():
|
||||
data = public.execShell('service xl2tpd reload')
|
||||
if data[0] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def getPathFile():
|
||||
if public.isAppleSystem():
|
||||
return getServerDir() + '/chap-secrets'
|
||||
return '/etc/ppp/chap-secrets'
|
||||
|
||||
|
||||
def getPathFilePsk():
|
||||
if public.isAppleSystem():
|
||||
return getServerDir() + '/ipsec.secrets'
|
||||
return '/etc/ipsec.secrets'
|
||||
|
||||
|
||||
def getUserList():
|
||||
import re
|
||||
path = getPathFile()
|
||||
if not os.path.exists(path):
|
||||
return public.returnJson(False, '密码配置文件不存在!')
|
||||
conf = public.readFile(path)
|
||||
|
||||
conf = re.sub('#(.*)\n', '', conf)
|
||||
|
||||
if conf.strip() == '':
|
||||
return public.returnJson(True, 'ok', [])
|
||||
|
||||
ulist = conf.strip().split('\n')
|
||||
|
||||
user = []
|
||||
for line in ulist:
|
||||
line_info = {}
|
||||
line = re.match(r'(\w*)\s*(\w*)\s*(\w*)\s*(.*)',
|
||||
line.strip(), re.M | re.I).groups()
|
||||
line_info['user'] = line[0]
|
||||
line_info['pwd'] = line[2]
|
||||
line_info['type'] = line[1]
|
||||
line_info['ip'] = line[3]
|
||||
user.append(line_info)
|
||||
|
||||
return public.returnJson(True, 'ok', user)
|
||||
|
||||
|
||||
def addUser():
|
||||
if public.isAppleSystem():
|
||||
return public.returnJson(False, "Apple Computer does not support")
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['username'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
ret = public.execShell('echo ' + args['username'] + '|l2tp -a')
|
||||
if ret[1] == '':
|
||||
return public.returnJson(True, '添加成功!:' + ret[0])
|
||||
return public.returnJson(False, '添加失败:' + ret[0])
|
||||
|
||||
|
||||
def delUser():
|
||||
if public.isAppleSystem():
|
||||
return public.returnJson(False, "Apple Computer does not support")
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['username'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
ret = public.execShell('echo ' + args['username'] + '|l2tp -d')
|
||||
if ret[1] == '':
|
||||
return public.returnJson(True, '删除成功!:' + ret[0])
|
||||
return public.returnJson(False, '删除失败:' + ret[0])
|
||||
|
||||
|
||||
def modUser():
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['username', 'password'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = getPathFile()
|
||||
username = args['username']
|
||||
password = args['password']
|
||||
|
||||
# sed -i "/^\<${user}\>/d" /etc/ppp/chap-secrets
|
||||
# echo "${user} l2tpd ${pass} *" >> /etc/ppp/chap-secrets
|
||||
|
||||
if public.isAppleSystem():
|
||||
public.execShell("sed -i .bak '/^\(" + username + "\)/d' " + path)
|
||||
else:
|
||||
public.execShell("sed -i '/^\(" + username + "\)/d' " + path)
|
||||
# print 'echo "' + username + " l2tpd " + password + " *\" >>"
|
||||
# + path
|
||||
ret = public.execShell("echo \"" + username +
|
||||
" l2tpd " + password + " *\" >>" + path)
|
||||
if ret[1] == '':
|
||||
return public.returnJson(True, '修改成功!')
|
||||
return public.returnJson(False, '修改失败')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print status()
|
||||
elif func == 'start':
|
||||
print start()
|
||||
elif func == 'stop':
|
||||
print stop()
|
||||
elif func == 'restart':
|
||||
print restart()
|
||||
elif func == 'reload':
|
||||
print reload()
|
||||
elif func == 'conf':
|
||||
print getPathFile()
|
||||
elif func == 'conf_psk':
|
||||
print getPathFilePsk()
|
||||
elif func == 'user_list':
|
||||
print getUserList()
|
||||
elif func == 'add_user':
|
||||
print addUser()
|
||||
elif func == 'del_user':
|
||||
print delUser()
|
||||
elif func == 'mod_user':
|
||||
print modUser()
|
||||
else:
|
||||
print 'error'
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title":"L2TP",
|
||||
"tip":"soft",
|
||||
"name":"l2tp",
|
||||
"type":"运行环境",
|
||||
"ps":"VPN网关",
|
||||
"versions":"1.0",
|
||||
"shell":"install.sh",
|
||||
"checks":"server/l2tp",
|
||||
"author":"teddysun",
|
||||
"home":"https://github.com/teddysun/across/blob/master/l2tp.sh",
|
||||
"date":"2019-02-27",
|
||||
"pid": "4"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
SYSOS=`uname`
|
||||
|
||||
Install_l2tp()
|
||||
{
|
||||
isStart=""
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/l2tp
|
||||
echo '1.0' > $serverPath/l2tp/version.pl
|
||||
|
||||
cp -rf scripts/l2tp.sh $serverPath/l2tp
|
||||
chmod +x $serverPath/l2tp/l2tp.sh
|
||||
|
||||
if [ "Darwin" == "$SYSOS" ];then
|
||||
echo 'macosx unavailable' > $install_tmp
|
||||
exit 0
|
||||
fi
|
||||
|
||||
/bin/sh $serverPath/l2tp/l2tp.sh
|
||||
|
||||
echo 'install complete' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_l2tp()
|
||||
{
|
||||
rm -rf $serverPath/l2tp
|
||||
echo "Uninstall completed" > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_l2tp
|
||||
else
|
||||
Uninstall_l2tp
|
||||
fi
|
||||
@@ -0,0 +1,158 @@
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function lpPost(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var _title = '正在获取...';
|
||||
if (typeof(title) != 'undefined'){
|
||||
_title = title;
|
||||
}
|
||||
|
||||
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'l2tp', func:method, args:_args}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function lpAsyncPost(method,args){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
return syncPost('/plugins/run', {name:'l2tp', func:method, args:_args});
|
||||
}
|
||||
|
||||
function userList(){
|
||||
lpPost('user_list', '' ,function(data){
|
||||
var rdata = $.parseJSON(data['data']);
|
||||
|
||||
if (!rdata['status']){
|
||||
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
var list = rdata['data'];
|
||||
|
||||
var con = '';
|
||||
con += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
|
||||
con += '<thead><tr>';
|
||||
con += '<th>用户</th>';
|
||||
con += '<th>密码</th>';
|
||||
con += '<th>操作(<a class="btlink" onclick="addUser()">添加</a>)</th>';
|
||||
con += '</tr></thead>';
|
||||
|
||||
con += '<tbody>';
|
||||
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
con += '<tr>'+
|
||||
'<td>' + list[i]['user']+'</td>' +
|
||||
'<td>' + list[i]['pwd']+'</td>' +
|
||||
'<td><a class="btlink" onclick="modUser(\''+list[i]['user']+'\')">改密</a>|<a class="btlink" onclick="delUser(\''+list[i]['user']+'\')">删除</a></td></tr>';
|
||||
}
|
||||
|
||||
con += '</tbody>';
|
||||
con += '</table></div>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function addUser(){
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '添加用户',
|
||||
area: '240px',
|
||||
content:"<div class='bt-form pd20 pb70 c6'>\
|
||||
<div class='version line'>\
|
||||
<div><input class='bt-input-text mr5 outline_no' type='text' id='username' name='username' style='height: 28px; border-radius: 3px;width: 200px;' placeholder='输入用户名'></div>\
|
||||
</div>\
|
||||
<div class='bt-form-submit-btn'>\
|
||||
<button type='button' id='add_ok' class='btn btn-success btn-sm btn-title bi-btn'>确认</button>\
|
||||
</div>\
|
||||
</div>"
|
||||
});
|
||||
|
||||
$('#add_ok').click(function(){
|
||||
_data = {};
|
||||
_data['username'] = $('#username').val();
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
lpPost('add_user', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.close(loadOpen);
|
||||
layer.msg(rdata.msg,{icon:rdata.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){userList();},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delUser(username){
|
||||
lpPost('del_user', {username:username}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg,{icon:rdata.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){userList();},2000);
|
||||
});
|
||||
}
|
||||
|
||||
function modUser(username){
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '修改密码',
|
||||
area: '240px',
|
||||
content:"<div class='bt-form pd20 pb70 c6'>\
|
||||
<div class='version line'>\
|
||||
<div><input class='bt-input-text mr5 outline_no' type='text' id='password' name='password' style='height: 28px; border-radius: 3px;width: 200px;' placeholder='输入密码'></div>\
|
||||
</div>\
|
||||
<div class='bt-form-submit-btn'>\
|
||||
<button type='button' id='mod_ok' class='btn btn-success btn-sm btn-title bi-btn'>确认</button>\
|
||||
</div>\
|
||||
</div>"
|
||||
});
|
||||
|
||||
$('#mod_ok').click(function(){
|
||||
_data = {};
|
||||
_data['username'] = username;
|
||||
_data['password'] = $('#password').val();
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
lpPost('mod_user', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.close(loadOpen);
|
||||
layer.msg(rdata.msg,{icon:rdata.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){userList();},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function readme(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>PPTP需开放端口:UDP:1723</li>';
|
||||
readme += '<li>L2TP需开放端口:UDP:500,UDP:4500,UDP:1701</li>';
|
||||
readme += '</ul>';
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
@@ -0,0 +1,820 @@
|
||||
#!/usr/bin/env bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
#=======================================================================#
|
||||
# System Supported: CentOS 6+ / Debian 7+ / Ubuntu 12+ #
|
||||
# Description: L2TP VPN Auto Installer #
|
||||
# Author: Teddysun <i@teddysun.com> #
|
||||
# Intro: https://teddysun.com/448.html #
|
||||
#=======================================================================#
|
||||
cur_dir=`pwd`
|
||||
|
||||
libreswan_filename="libreswan-3.27"
|
||||
download_root_url="https://dl.lamp.sh/files"
|
||||
|
||||
rootness(){
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Error:This script must be run as root!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
tunavailable(){
|
||||
if [[ ! -e /dev/net/tun ]]; then
|
||||
echo "Error:TUN/TAP is not available!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
disable_selinux(){
|
||||
if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
|
||||
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
|
||||
setenforce 0
|
||||
fi
|
||||
}
|
||||
|
||||
get_opsy(){
|
||||
[ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
|
||||
[ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
|
||||
[ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
|
||||
}
|
||||
|
||||
get_os_info(){
|
||||
IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 )
|
||||
[ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
|
||||
|
||||
local cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
|
||||
local cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo )
|
||||
local freq=$( awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
|
||||
local tram=$( free -m | awk '/Mem/ {print $2}' )
|
||||
local swap=$( free -m | awk '/Swap/ {print $2}' )
|
||||
local up=$( awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60;d=$1%60} {printf("%ddays, %d:%d:%d\n",a,b,c,d)}' /proc/uptime )
|
||||
local load=$( w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//' )
|
||||
local opsy=$( get_opsy )
|
||||
local arch=$( uname -m )
|
||||
local lbit=$( getconf LONG_BIT )
|
||||
local host=$( hostname )
|
||||
local kern=$( uname -r )
|
||||
|
||||
echo "########## System Information ##########"
|
||||
echo
|
||||
echo "CPU model : ${cname}"
|
||||
echo "Number of cores : ${cores}"
|
||||
echo "CPU frequency : ${freq} MHz"
|
||||
echo "Total amount of ram : ${tram} MB"
|
||||
echo "Total amount of swap : ${swap} MB"
|
||||
echo "System uptime : ${up}"
|
||||
echo "Load average : ${load}"
|
||||
echo "OS : ${opsy}"
|
||||
echo "Arch : ${arch} (${lbit} Bit)"
|
||||
echo "Kernel : ${kern}"
|
||||
echo "Hostname : ${host}"
|
||||
echo "IPv4 address : ${IP}"
|
||||
echo
|
||||
echo "########################################"
|
||||
}
|
||||
|
||||
check_sys(){
|
||||
local checkType=$1
|
||||
local value=$2
|
||||
|
||||
local release=''
|
||||
local systemPackage=''
|
||||
|
||||
if [[ -f /etc/redhat-release ]]; then
|
||||
release="centos"
|
||||
systemPackage="yum"
|
||||
elif cat /etc/issue | grep -Eqi "debian"; then
|
||||
release="debian"
|
||||
systemPackage="apt"
|
||||
elif cat /etc/issue | grep -Eqi "ubuntu"; then
|
||||
release="ubuntu"
|
||||
systemPackage="apt"
|
||||
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
|
||||
release="centos"
|
||||
systemPackage="yum"
|
||||
elif cat /proc/version | grep -Eqi "debian"; then
|
||||
release="debian"
|
||||
systemPackage="apt"
|
||||
elif cat /proc/version | grep -Eqi "ubuntu"; then
|
||||
release="ubuntu"
|
||||
systemPackage="apt"
|
||||
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
|
||||
release="centos"
|
||||
systemPackage="yum"
|
||||
fi
|
||||
|
||||
if [[ ${checkType} == "sysRelease" ]]; then
|
||||
if [ "$value" == "$release" ];then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
elif [[ ${checkType} == "packageManager" ]]; then
|
||||
if [ "$value" == "$systemPackage" ];then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
rand(){
|
||||
index=0
|
||||
str=""
|
||||
for i in {a..z}; do arr[index]=${i}; index=`expr ${index} + 1`; done
|
||||
for i in {A..Z}; do arr[index]=${i}; index=`expr ${index} + 1`; done
|
||||
for i in {0..9}; do arr[index]=${i}; index=`expr ${index} + 1`; done
|
||||
for i in {1..10}; do str="$str${arr[$RANDOM%$index]}"; done
|
||||
echo ${str}
|
||||
}
|
||||
|
||||
is_64bit(){
|
||||
if [ `getconf WORD_BIT` = '32' ] && [ `getconf LONG_BIT` = '64' ] ; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
download_file(){
|
||||
if [ -s ${1} ]; then
|
||||
echo "$1 [found]"
|
||||
else
|
||||
echo "$1 not found!!!download now..."
|
||||
if ! wget -c -t3 -T60 ${download_root_url}/${1}; then
|
||||
echo "Failed to download $1, please download it to ${cur_dir} directory manually and try again."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
versionget(){
|
||||
if [[ -s /etc/redhat-release ]];then
|
||||
grep -oE "[0-9.]+" /etc/redhat-release
|
||||
else
|
||||
grep -oE "[0-9.]+" /etc/issue
|
||||
fi
|
||||
}
|
||||
|
||||
centosversion(){
|
||||
if check_sys sysRelease centos;then
|
||||
local code=${1}
|
||||
local version="`versionget`"
|
||||
local main_ver=${version%%.*}
|
||||
if [ "${main_ver}" == "${code}" ];then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
debianversion(){
|
||||
if check_sys sysRelease debian;then
|
||||
local version=$( get_opsy )
|
||||
local code=${1}
|
||||
local main_ver=$( echo ${version} | sed 's/[^0-9]//g')
|
||||
if [ "${main_ver}" == "${code}" ];then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
version_check(){
|
||||
if check_sys packageManager yum; then
|
||||
if centosversion 5; then
|
||||
echo "Error: CentOS 5 is not supported, Please re-install OS and try again."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
get_char(){
|
||||
SAVEDSTTY=`stty -g`
|
||||
stty -echo
|
||||
stty cbreak
|
||||
dd if=/dev/tty bs=1 count=1 2> /dev/null
|
||||
stty -raw
|
||||
stty echo
|
||||
stty $SAVEDSTTY
|
||||
}
|
||||
|
||||
preinstall_l2tp(){
|
||||
|
||||
echo
|
||||
if [ -d "/proc/vz" ]; then
|
||||
echo -e "\033[41;37m WARNING: \033[0m Your VPS is based on OpenVZ, and IPSec might not be supported by the kernel."
|
||||
echo "Continue installation? (y/n)"
|
||||
read -p "(Default: n)" agree
|
||||
[ -z ${agree} ] && agree="n"
|
||||
if [ "${agree}" == "n" ]; then
|
||||
echo
|
||||
echo "L2TP installation cancelled."
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
echo "Please enter IP-Range:"
|
||||
# read -p "(Default Range: 192.168.18):" iprange
|
||||
# [ -z ${iprange} ] && iprange="192.168.18"
|
||||
iprange="192.168.18"
|
||||
echo ${iprange}
|
||||
|
||||
echo "Please enter PSK:"
|
||||
# read -p "(Default PSK: teddysun.com):" mypsk
|
||||
# [ -z ${mypsk} ] && mypsk="teddysun.com"
|
||||
mypsk="midoks"
|
||||
echo ${mypsk}
|
||||
|
||||
echo "Please enter Username:"
|
||||
# read -p "(Default Username: teddysun):" username
|
||||
# [ -z ${username} ] && username="teddysun"
|
||||
username="midoks"
|
||||
echo ${username}
|
||||
|
||||
# password=`rand`
|
||||
echo "Please enter ${username}'s password:"
|
||||
# read -p "(Default Password: ${password}):" tmppassword
|
||||
# [ ! -z ${tmppassword} ] && password=${tmppassword}
|
||||
password=midoks
|
||||
echo ${password}
|
||||
|
||||
echo
|
||||
echo "ServerIP:${IP}"
|
||||
echo "Server Local IP:${iprange}.1"
|
||||
echo "Client Remote IP Range:${iprange}.2-${iprange}.254"
|
||||
echo "PSK:${mypsk}"
|
||||
echo
|
||||
echo "Press any key to start... or press Ctrl + C to cancel."
|
||||
char=`get_char`
|
||||
|
||||
}
|
||||
|
||||
install_l2tp(){
|
||||
|
||||
mknod /dev/random c 1 9
|
||||
|
||||
if check_sys packageManager apt; then
|
||||
apt-get -y update
|
||||
|
||||
if debianversion 7; then
|
||||
if is_64bit; then
|
||||
local libnspr4_filename1="libnspr4_4.10.7-1_amd64.deb"
|
||||
local libnspr4_filename2="libnspr4-0d_4.10.7-1_amd64.deb"
|
||||
local libnspr4_filename3="libnspr4-dev_4.10.7-1_amd64.deb"
|
||||
local libnspr4_filename4="libnspr4-dbg_4.10.7-1_amd64.deb"
|
||||
local libnss3_filename1="libnss3_3.17.2-1.1_amd64.deb"
|
||||
local libnss3_filename2="libnss3-1d_3.17.2-1.1_amd64.deb"
|
||||
local libnss3_filename3="libnss3-tools_3.17.2-1.1_amd64.deb"
|
||||
local libnss3_filename4="libnss3-dev_3.17.2-1.1_amd64.deb"
|
||||
local libnss3_filename5="libnss3-dbg_3.17.2-1.1_amd64.deb"
|
||||
else
|
||||
local libnspr4_filename1="libnspr4_4.10.7-1_i386.deb"
|
||||
local libnspr4_filename2="libnspr4-0d_4.10.7-1_i386.deb"
|
||||
local libnspr4_filename3="libnspr4-dev_4.10.7-1_i386.deb"
|
||||
local libnspr4_filename4="libnspr4-dbg_4.10.7-1_i386.deb"
|
||||
local libnss3_filename1="libnss3_3.17.2-1.1_i386.deb"
|
||||
local libnss3_filename2="libnss3-1d_3.17.2-1.1_i386.deb"
|
||||
local libnss3_filename3="libnss3-tools_3.17.2-1.1_i386.deb"
|
||||
local libnss3_filename4="libnss3-dev_3.17.2-1.1_i386.deb"
|
||||
local libnss3_filename5="libnss3-dbg_3.17.2-1.1_i386.deb"
|
||||
fi
|
||||
rm -rf ${cur_dir}/l2tp
|
||||
mkdir -p ${cur_dir}/l2tp
|
||||
cd ${cur_dir}/l2tp
|
||||
download_file "${libnspr4_filename1}"
|
||||
download_file "${libnspr4_filename2}"
|
||||
download_file "${libnspr4_filename3}"
|
||||
download_file "${libnspr4_filename4}"
|
||||
download_file "${libnss3_filename1}"
|
||||
download_file "${libnss3_filename2}"
|
||||
download_file "${libnss3_filename3}"
|
||||
download_file "${libnss3_filename4}"
|
||||
download_file "${libnss3_filename5}"
|
||||
dpkg -i ${libnspr4_filename1} ${libnspr4_filename2} ${libnspr4_filename3} ${libnspr4_filename4}
|
||||
dpkg -i ${libnss3_filename1} ${libnss3_filename2} ${libnss3_filename3} ${libnss3_filename4} ${libnss3_filename5}
|
||||
|
||||
apt-get -y install wget gcc ppp flex bison make pkg-config libpam0g-dev libcap-ng-dev iptables \
|
||||
libcap-ng-utils libunbound-dev libevent-dev libcurl4-nss-dev libsystemd-daemon-dev
|
||||
else
|
||||
apt-get -y install wget gcc ppp flex bison make python libnss3-dev libnss3-tools libselinux-dev iptables \
|
||||
libnspr4-dev pkg-config libpam0g-dev libcap-ng-dev libcap-ng-utils libunbound-dev \
|
||||
libevent-dev libcurl4-nss-dev libsystemd-dev
|
||||
fi
|
||||
apt-get -y --no-install-recommends install xmlto
|
||||
apt-get -y install xl2tpd
|
||||
|
||||
compile_install
|
||||
elif check_sys packageManager yum; then
|
||||
echo "Adding the EPEL repository..."
|
||||
yum -y install epel-release yum-utils
|
||||
[ ! -f /etc/yum.repos.d/epel.repo ] && echo "Install EPEL repository failed, please check it." && exit 1
|
||||
yum-config-manager --enable epel
|
||||
echo "Adding the EPEL repository complete..."
|
||||
|
||||
if centosversion 7; then
|
||||
yum -y install ppp libreswan xl2tpd firewalld
|
||||
yum_install
|
||||
elif centosversion 6; then
|
||||
yum -y remove libevent-devel
|
||||
yum -y install libevent2-devel
|
||||
yum -y install nss-devel nspr-devel pkgconfig pam-devel \
|
||||
libcap-ng-devel libselinux-devel lsof \
|
||||
curl-devel flex bison gcc ppp make iptables gmp-devel \
|
||||
fipscheck-devel unbound-devel xmlto libpcap-devel xl2tpd
|
||||
|
||||
compile_install
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
config_install(){
|
||||
|
||||
cat > /etc/ipsec.conf<<EOF
|
||||
version 2.0
|
||||
|
||||
config setup
|
||||
protostack=netkey
|
||||
nhelpers=0
|
||||
uniqueids=no
|
||||
interfaces=%defaultroute
|
||||
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!${iprange}.0/24
|
||||
|
||||
conn l2tp-psk
|
||||
rightsubnet=vhost:%priv
|
||||
also=l2tp-psk-nonat
|
||||
|
||||
conn l2tp-psk-nonat
|
||||
authby=secret
|
||||
pfs=no
|
||||
auto=add
|
||||
keyingtries=3
|
||||
rekey=no
|
||||
ikelifetime=8h
|
||||
keylife=1h
|
||||
type=transport
|
||||
left=%defaultroute
|
||||
leftid=${IP}
|
||||
leftprotoport=17/1701
|
||||
right=%any
|
||||
rightprotoport=17/%any
|
||||
dpddelay=40
|
||||
dpdtimeout=130
|
||||
dpdaction=clear
|
||||
sha2-truncbug=yes
|
||||
EOF
|
||||
|
||||
cat > /etc/ipsec.secrets<<EOF
|
||||
%any %any : PSK "${mypsk}"
|
||||
EOF
|
||||
|
||||
cat > /etc/xl2tpd/xl2tpd.conf<<EOF
|
||||
[global]
|
||||
port = 1701
|
||||
|
||||
[lns default]
|
||||
ip range = ${iprange}.2-${iprange}.254
|
||||
local ip = ${iprange}.1
|
||||
require chap = yes
|
||||
refuse pap = yes
|
||||
require authentication = yes
|
||||
name = l2tpd
|
||||
ppp debug = yes
|
||||
pppoptfile = /etc/ppp/options.xl2tpd
|
||||
length bit = yes
|
||||
EOF
|
||||
|
||||
cat > /etc/ppp/options.xl2tpd<<EOF
|
||||
ipcp-accept-local
|
||||
ipcp-accept-remote
|
||||
require-mschap-v2
|
||||
ms-dns 8.8.8.8
|
||||
ms-dns 8.8.4.4
|
||||
noccp
|
||||
auth
|
||||
hide-password
|
||||
idle 1800
|
||||
mtu 1410
|
||||
mru 1410
|
||||
nodefaultroute
|
||||
debug
|
||||
proxyarp
|
||||
connect-delay 5000
|
||||
EOF
|
||||
|
||||
rm -f /etc/ppp/chap-secrets
|
||||
cat > /etc/ppp/chap-secrets<<EOF
|
||||
# Secrets for authentication using CHAP
|
||||
# client server secret IP addresses
|
||||
${username} l2tpd ${password} *
|
||||
EOF
|
||||
|
||||
}
|
||||
|
||||
compile_install(){
|
||||
|
||||
rm -rf ${cur_dir}/l2tp
|
||||
mkdir -p ${cur_dir}/l2tp
|
||||
cd ${cur_dir}/l2tp
|
||||
download_file "${libreswan_filename}.tar.gz"
|
||||
tar -zxf ${libreswan_filename}.tar.gz
|
||||
|
||||
cd ${cur_dir}/l2tp/${libreswan_filename}
|
||||
cat > Makefile.inc.local <<'EOF'
|
||||
WERROR_CFLAGS =
|
||||
USE_DNSSEC = false
|
||||
USE_DH31 = false
|
||||
USE_GLIBC_KERN_FLIP_HEADERS = true
|
||||
EOF
|
||||
make programs && make install
|
||||
|
||||
/usr/local/sbin/ipsec --version >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "${libreswan_filename} install failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
config_install
|
||||
|
||||
cp -pf /etc/sysctl.conf /etc/sysctl.conf.bak
|
||||
|
||||
sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
|
||||
|
||||
for each in `ls /proc/sys/net/ipv4/conf/`; do
|
||||
echo "net.ipv4.conf.${each}.accept_source_route=0" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.${each}.accept_redirects=0" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.${each}.send_redirects=0" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.${each}.rp_filter=0" >> /etc/sysctl.conf
|
||||
done
|
||||
sysctl -p
|
||||
|
||||
if centosversion 6; then
|
||||
[ -f /etc/sysconfig/iptables ] && cp -pf /etc/sysconfig/iptables /etc/sysconfig/iptables.old.`date +%Y%m%d`
|
||||
|
||||
if [ "`iptables -L -n | grep -c '\-\-'`" == "0" ]; then
|
||||
cat > /etc/sysconfig/iptables <<EOF
|
||||
# Added by L2TP VPN script
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A INPUT -p icmp -j ACCEPT
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
-A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
-A INPUT -p udp -m multiport --dports 500,4500,1701 -j ACCEPT
|
||||
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -s ${iprange}.0/24 -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
-A POSTROUTING -s ${iprange}.0/24 -j SNAT --to-source ${IP}
|
||||
COMMIT
|
||||
EOF
|
||||
else
|
||||
iptables -I INPUT -p udp -m multiport --dports 500,4500,1701 -j ACCEPT
|
||||
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
iptables -I FORWARD -s ${iprange}.0/24 -j ACCEPT
|
||||
iptables -t nat -A POSTROUTING -s ${iprange}.0/24 -j SNAT --to-source ${IP}
|
||||
/etc/init.d/iptables save
|
||||
fi
|
||||
|
||||
if [ ! -f /etc/ipsec.d/cert9.db ]; then
|
||||
echo > /var/tmp/libreswan-nss-pwd
|
||||
certutil -N -f /var/tmp/libreswan-nss-pwd -d /etc/ipsec.d
|
||||
rm -f /var/tmp/libreswan-nss-pwd
|
||||
fi
|
||||
|
||||
chkconfig --add iptables
|
||||
chkconfig iptables on
|
||||
chkconfig --add ipsec
|
||||
chkconfig ipsec on
|
||||
chkconfig --add xl2tpd
|
||||
chkconfig xl2tpd on
|
||||
|
||||
/etc/init.d/iptables restart
|
||||
/etc/init.d/ipsec start
|
||||
/etc/init.d/xl2tpd start
|
||||
|
||||
else
|
||||
[ -f /etc/iptables.rules ] && cp -pf /etc/iptables.rules /etc/iptables.rules.old.`date +%Y%m%d`
|
||||
|
||||
if [ "`iptables -L -n | grep -c '\-\-'`" == "0" ]; then
|
||||
cat > /etc/iptables.rules <<EOF
|
||||
# Added by L2TP VPN script
|
||||
*filter
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A INPUT -p icmp -j ACCEPT
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
-A INPUT -p tcp --dport 22 -j ACCEPT
|
||||
-A INPUT -p udp -m multiport --dports 500,4500,1701 -j ACCEPT
|
||||
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -s ${iprange}.0/24 -j ACCEPT
|
||||
COMMIT
|
||||
*nat
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
-A POSTROUTING -s ${iprange}.0/24 -j SNAT --to-source ${IP}
|
||||
COMMIT
|
||||
EOF
|
||||
else
|
||||
iptables -I INPUT -p udp -m multiport --dports 500,4500,1701 -j ACCEPT
|
||||
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
iptables -I FORWARD -s ${iprange}.0/24 -j ACCEPT
|
||||
iptables -t nat -A POSTROUTING -s ${iprange}.0/24 -j SNAT --to-source ${IP}
|
||||
/sbin/iptables-save > /etc/iptables.rules
|
||||
fi
|
||||
|
||||
cat > /etc/network/if-up.d/iptables <<EOF
|
||||
#!/bin/sh
|
||||
/sbin/iptables-restore < /etc/iptables.rules
|
||||
EOF
|
||||
chmod +x /etc/network/if-up.d/iptables
|
||||
|
||||
if [ ! -f /etc/ipsec.d/cert9.db ]; then
|
||||
echo > /var/tmp/libreswan-nss-pwd
|
||||
certutil -N -f /var/tmp/libreswan-nss-pwd -d /etc/ipsec.d
|
||||
rm -f /var/tmp/libreswan-nss-pwd
|
||||
fi
|
||||
|
||||
update-rc.d -f xl2tpd defaults
|
||||
|
||||
cp -f /etc/rc.local /etc/rc.local.old.`date +%Y%m%d`
|
||||
sed --follow-symlinks -i -e '/^exit 0/d' /etc/rc.local
|
||||
cat >> /etc/rc.local <<EOF
|
||||
|
||||
# Added by L2TP VPN script
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
/usr/sbin/service ipsec start
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x /etc/rc.local
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
|
||||
/sbin/iptables-restore < /etc/iptables.rules
|
||||
/usr/sbin/service ipsec start
|
||||
/usr/sbin/service xl2tpd restart
|
||||
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
yum_install(){
|
||||
|
||||
config_install
|
||||
|
||||
cp -pf /etc/sysctl.conf /etc/sysctl.conf.bak
|
||||
|
||||
echo "# Added by L2TP VPN" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.tcp_syncookies=1" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.icmp_echo_ignore_broadcasts=1" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.icmp_ignore_bogus_error_responses=1" >> /etc/sysctl.conf
|
||||
|
||||
for each in `ls /proc/sys/net/ipv4/conf/`; do
|
||||
echo "net.ipv4.conf.${each}.accept_source_route=0" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.${each}.accept_redirects=0" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.${each}.send_redirects=0" >> /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.${each}.rp_filter=0" >> /etc/sysctl.conf
|
||||
done
|
||||
sysctl -p
|
||||
|
||||
cat > /etc/firewalld/services/xl2tpd.xml<<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<service>
|
||||
<short>xl2tpd</short>
|
||||
<description>L2TP IPSec</description>
|
||||
<port protocol="udp" port="4500"/>
|
||||
<port protocol="udp" port="1701"/>
|
||||
</service>
|
||||
EOF
|
||||
chmod 640 /etc/firewalld/services/xl2tpd.xml
|
||||
|
||||
systemctl enable ipsec
|
||||
systemctl enable xl2tpd
|
||||
systemctl enable firewalld
|
||||
|
||||
systemctl status firewalld > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
firewall-cmd --reload
|
||||
echo "Checking firewalld status..."
|
||||
firewall-cmd --list-all
|
||||
echo "add firewalld rules..."
|
||||
firewall-cmd --permanent --add-service=ipsec
|
||||
firewall-cmd --permanent --add-service=xl2tpd
|
||||
firewall-cmd --permanent --add-masquerade
|
||||
firewall-cmd --reload
|
||||
else
|
||||
echo "Firewalld looks like not running, trying to start..."
|
||||
systemctl start firewalld
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Firewalld start successfully..."
|
||||
firewall-cmd --reload
|
||||
echo "Checking firewalld status..."
|
||||
firewall-cmd --list-all
|
||||
echo "adding firewalld rules..."
|
||||
firewall-cmd --permanent --add-service=ipsec
|
||||
firewall-cmd --permanent --add-service=xl2tpd
|
||||
firewall-cmd --permanent --add-masquerade
|
||||
firewall-cmd --reload
|
||||
else
|
||||
echo "Failed to start firewalld. please enable udp port 500 4500 1701 manually if necessary."
|
||||
fi
|
||||
fi
|
||||
|
||||
systemctl restart ipsec
|
||||
systemctl restart xl2tpd
|
||||
echo "Checking ipsec status..."
|
||||
systemctl -a | grep ipsec
|
||||
echo "Checking xl2tpd status..."
|
||||
systemctl -a | grep xl2tpd
|
||||
echo "Checking firewalld status..."
|
||||
firewall-cmd --list-all
|
||||
|
||||
}
|
||||
|
||||
finally(){
|
||||
|
||||
cd ${cur_dir}
|
||||
rm -fr ${cur_dir}/l2tp
|
||||
# create l2tp command
|
||||
cp -f ${cur_dir}/`basename $0` /usr/bin/l2tp
|
||||
|
||||
echo "Please wait a moment..."
|
||||
sleep 5
|
||||
ipsec verify
|
||||
echo
|
||||
echo "###############################################################"
|
||||
echo "# L2TP VPN Auto Installer #"
|
||||
echo "# System Supported: CentOS 6+ / Debian 7+ / Ubuntu 12+ #"
|
||||
echo "# Intro: https://teddysun.com/448.html #"
|
||||
echo "# Author: Teddysun <i@teddysun.com> #"
|
||||
echo "###############################################################"
|
||||
echo "If there is no [FAILED] above, you can connect to your L2TP "
|
||||
echo "VPN Server with the default Username/Password is below:"
|
||||
echo
|
||||
echo "Server IP: ${IP}"
|
||||
echo "PSK : ${mypsk}"
|
||||
echo "Username : ${username}"
|
||||
echo "Password : ${password}"
|
||||
echo
|
||||
echo "If you want to modify user settings, please use below command(s):"
|
||||
echo "l2tp -a (Add a user)"
|
||||
echo "l2tp -d (Delete a user)"
|
||||
echo "l2tp -l (List all users)"
|
||||
echo "l2tp -m (Modify a user password)"
|
||||
echo
|
||||
echo "Welcome to visit our website: https://teddysun.com/448.html"
|
||||
echo "Enjoy it!"
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
l2tp(){
|
||||
clear
|
||||
echo
|
||||
echo "###############################################################"
|
||||
echo "# L2TP VPN Auto Installer #"
|
||||
echo "# System Supported: CentOS 6+ / Debian 7+ / Ubuntu 12+ #"
|
||||
echo "# Intro: https://teddysun.com/448.html #"
|
||||
echo "# Author: Teddysun <i@teddysun.com> #"
|
||||
echo "###############################################################"
|
||||
echo
|
||||
rootness
|
||||
tunavailable
|
||||
disable_selinux
|
||||
version_check
|
||||
get_os_info
|
||||
preinstall_l2tp
|
||||
install_l2tp
|
||||
finally
|
||||
}
|
||||
|
||||
list_users(){
|
||||
if [ ! -f /etc/ppp/chap-secrets ];then
|
||||
echo "Error: /etc/ppp/chap-secrets file not found."
|
||||
exit 1
|
||||
fi
|
||||
local line="+-------------------------------------------+\n"
|
||||
local string=%20s
|
||||
printf "${line}|${string} |${string} |\n${line}" Username Password
|
||||
grep -v "^#" /etc/ppp/chap-secrets | awk '{printf "|'${string}' |'${string}' |\n", $1,$3}'
|
||||
printf ${line}
|
||||
}
|
||||
|
||||
add_user(){
|
||||
while :
|
||||
do
|
||||
read -p "Please input your Username:" user
|
||||
if [ -z ${user} ]; then
|
||||
echo "Username can not be empty"
|
||||
else
|
||||
grep -w "${user}" /etc/ppp/chap-secrets > /dev/null 2>&1
|
||||
if [ $? -eq 0 ];then
|
||||
echo "Username (${user}) already exists. Please re-enter your username."
|
||||
else
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
pass=`rand`
|
||||
echo "Please input ${user}'s password:"
|
||||
read -p "(Default Password: ${pass}):" tmppass
|
||||
[ ! -z ${tmppass} ] && pass=${tmppass}
|
||||
echo "${user} l2tpd ${pass} *" >> /etc/ppp/chap-secrets
|
||||
echo "Username (${user}) add completed."
|
||||
}
|
||||
|
||||
del_user(){
|
||||
while :
|
||||
do
|
||||
read -p "Please input Username you want to delete it:" user
|
||||
if [ -z ${user} ]; then
|
||||
echo "Username can not be empty"
|
||||
else
|
||||
grep -w "${user}" /etc/ppp/chap-secrets >/dev/null 2>&1
|
||||
if [ $? -eq 0 ];then
|
||||
break
|
||||
else
|
||||
echo "Username (${user}) is not exists. Please re-enter your username."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
sed -i "/^\<${user}\>/d" /etc/ppp/chap-secrets
|
||||
echo "Username (${user}) delete completed."
|
||||
}
|
||||
|
||||
mod_user(){
|
||||
while :
|
||||
do
|
||||
read -p "Please input Username you want to change password:" user
|
||||
if [ -z ${user} ]; then
|
||||
echo "Username can not be empty"
|
||||
else
|
||||
grep -w "${user}" /etc/ppp/chap-secrets >/dev/null 2>&1
|
||||
if [ $? -eq 0 ];then
|
||||
break
|
||||
else
|
||||
echo "Username (${user}) is not exists. Please re-enter your username."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
pass=`rand`
|
||||
echo "Please input ${user}'s new password:"
|
||||
read -p "(Default Password: ${pass}):" tmppass
|
||||
[ ! -z ${tmppass} ] && pass=${tmppass}
|
||||
sed -i "/^\<${user}\>/d" /etc/ppp/chap-secrets
|
||||
echo "${user} l2tpd ${pass} *" >> /etc/ppp/chap-secrets
|
||||
echo "Username ${user}'s password has been changed."
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Main process
|
||||
action=$1
|
||||
if [ -z ${action} ] && [ "`basename $0`" != "l2tp" ]; then
|
||||
action=install
|
||||
fi
|
||||
|
||||
case ${action} in
|
||||
install)
|
||||
l2tp 2>&1 | tee ${cur_dir}/l2tp.log
|
||||
;;
|
||||
-l|--list)
|
||||
list_users
|
||||
;;
|
||||
-a|--add)
|
||||
add_user
|
||||
;;
|
||||
-d|--del)
|
||||
del_user
|
||||
;;
|
||||
-m|--mod)
|
||||
mod_user
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: `basename $0` -l,--list List all users"
|
||||
echo " `basename $0` -a,--add Add a user"
|
||||
echo " `basename $0` -d,--del Delete a user"
|
||||
echo " `basename $0` -m,--mod Modify a user password"
|
||||
echo " `basename $0` -h,--help Print this help information"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: `basename $0` [-l,--list|-a,--add|-d,--del|-m,--mod|-h,--help]" && exit
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,3 @@
|
||||
# Secrets for authentication using CHAP
|
||||
# client server secret IP addresses
|
||||
demo demo demo *
|
||||
@@ -0,0 +1 @@
|
||||
%any %any : PSK "midoks"
|
||||
@@ -194,10 +194,12 @@ def initdInstall():
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
|
||||
mem_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(mem_bin, initd_bin)
|
||||
public.execShell('chmod +x ' + initd_bin)
|
||||
public.execShell('chkconfig --add ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
@@ -205,6 +207,8 @@ def initdUinstall():
|
||||
if not app_debug:
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
public.execShell('chkconfig --del ' + getPluginName())
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
return 'ok'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "Memcached 是一个高性能的分布式内存对象缓存系统",
|
||||
"ps": "是一个高性能的分布式内存对象缓存系统",
|
||||
"name": "memcached",
|
||||
"title": "Memcached",
|
||||
"shell": "install.sh",
|
||||
@@ -8,6 +8,7 @@
|
||||
"updates":["1.5.12"],
|
||||
"tip": "soft",
|
||||
"checks": "server/memcached",
|
||||
"path":"server/memcached",
|
||||
"display": 1,
|
||||
"author": "Zend",
|
||||
"date": "2017-04-01",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
@@ -7,35 +8,31 @@ rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
Install_mem()
|
||||
{
|
||||
Install_mem(){
|
||||
mkdir -p $serverPath/source
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if [ ! -f $serverPath/source/memcached.tar.gz ];then
|
||||
wget -O $serverPath/source/memcached.tar.gz http://www.memcached.org/files/memcached-1.5.12.tar.gz
|
||||
if
|
||||
fi
|
||||
|
||||
cd $serverPath/source && tar -zxvf memcached.tar.gz
|
||||
|
||||
mkdir -p $serverPath/memcached
|
||||
cd memcached* && ./configure --prefix=$serverPath/memcached && make && make install
|
||||
cd $serverPath/source/memcached*
|
||||
./configure --prefix=$serverPath/memcached && make && make install
|
||||
|
||||
echo '1.5' > $serverPath/memcached/version.pl
|
||||
|
||||
echo '安装完成' > $install_tmp
|
||||
|
||||
echo 'install ok' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_mem()
|
||||
{
|
||||
$serverPath/memcached/init.d/memcached stop
|
||||
rm -rf mkdir -p $serverPath/memcached
|
||||
${serverPath}/memcached/init.d/memcached stop
|
||||
rm -rf $serverPath/memcached
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 388 B |
@@ -31,6 +31,7 @@
|
||||
<p class="bgw" onclick="pluginService('mysql');">服务</p>
|
||||
<p onclick="pluginInitD('mysql');">自启动</p>
|
||||
<p onclick="pluginConfig('mysql');">配置文件</p>
|
||||
<p onclick="myDbPos();">存储位置</p>
|
||||
<p onclick="myPort();">端口</p>
|
||||
<p onclick="runInfo();">当前状态</p>
|
||||
<p onclick="myPerfOpt();">性能优化</p>
|
||||
|
||||
@@ -151,10 +151,6 @@ def getDataDir():
|
||||
|
||||
def binLog():
|
||||
args = getArgs()
|
||||
# data = checkArgs(args, ['status'])
|
||||
# if not data[0]:
|
||||
# return data[1]
|
||||
|
||||
conf = getConf()
|
||||
con = public.readFile(conf)
|
||||
|
||||
@@ -163,7 +159,7 @@ def binLog():
|
||||
return public.returnJson(False, '0')
|
||||
con = con.replace('#log-bin=mysql-bin', 'log-bin=mysql-bin')
|
||||
con = con.replace('#binlog_format=mixed', 'binlog_format=mixed')
|
||||
os.system('sync')
|
||||
public.execShell('sync')
|
||||
restart()
|
||||
else:
|
||||
path = getDataDir()
|
||||
@@ -177,9 +173,9 @@ def binLog():
|
||||
return public.returnJson(True, dsize)
|
||||
con = con.replace('log-bin=mysql-bin', '#log-bin=mysql-bin')
|
||||
con = con.replace('binlog_format=mixed', '#binlog_format=mixed')
|
||||
os.system('sync')
|
||||
public.execShell('sync')
|
||||
restart()
|
||||
os.system('rm -f ' + path + '/mysql-bin.*')
|
||||
public.execShell('rm -f ' + path + '/mysql-bin.*')
|
||||
|
||||
public.writeFile(conf, con)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
@@ -195,12 +191,14 @@ def getErrorLog():
|
||||
if n == 'error.log':
|
||||
filename = path + '/' + n
|
||||
break
|
||||
print filename
|
||||
if not os.path.exists(filename):
|
||||
return public.returnJson(False, '指定文件不存在!')
|
||||
if args.has_key('close'):
|
||||
public.writeFile(filename, '')
|
||||
return public.returnJson(True, '日志已清空')
|
||||
return public.getNumLines(filename, 1000)
|
||||
return public.returnJson(False, '日志已清空')
|
||||
info = public.getNumLines(filename, 1000)
|
||||
return public.returnJson(True, 'OK', info)
|
||||
|
||||
|
||||
def getShowLogFile():
|
||||
@@ -295,6 +293,7 @@ def initdInstall():
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(mysql_bin, initd_bin)
|
||||
public.execShell('chmod +x ' + initd_bin)
|
||||
public.execShell('chkconfig --add ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
@@ -302,11 +301,63 @@ def initdUinstall():
|
||||
if not app_debug:
|
||||
if public.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
public.execShell('chkconfig --del ' + getPluginName())
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
return 'ok'
|
||||
|
||||
|
||||
def getMyDbPos():
|
||||
file = getConf()
|
||||
content = public.readFile(file)
|
||||
rep = 'datadir\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def setMyDbPos():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['datadir'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
s_datadir = getMyDbPos()
|
||||
t_datadir = args['datadir']
|
||||
if t_datadir == s_datadir:
|
||||
return public.returnJson(False, '与当前存储目录相同,无法迁移文件!')
|
||||
|
||||
if not os.path.exists(t_datadir):
|
||||
public.execShell('mkdir -p ' + t_datadir)
|
||||
|
||||
# public.execShell('/etc/init.d/mysqld stop')
|
||||
stop()
|
||||
public.execShell('cp -rf ' + s_datadir + '/* ' + t_datadir + '/')
|
||||
public.execShell('chown -R mysql.mysql ' + t_datadir)
|
||||
public.execShell('chmod -R 755 ' + t_datadir)
|
||||
public.execShell('rm -f ' + t_datadir + '/*.pid')
|
||||
public.execShell('rm -f ' + t_datadir + '/*.err')
|
||||
|
||||
path = getServerDir()
|
||||
myfile = path + '/etc/my.cnf'
|
||||
mycnf = public.readFile(myfile)
|
||||
public.writeFile(path + '/etc/my_backup.cnf', mycnf)
|
||||
|
||||
mycnf = mycnf.replace(s_datadir, t_datadir)
|
||||
public.writeFile(myfile, mycnf)
|
||||
start()
|
||||
|
||||
result = public.execShell(
|
||||
'ps aux|grep mysqld| grep -v grep|grep -v python')
|
||||
if len(result[0]) > 10:
|
||||
public.writeFile('data/datadir.pl', t_datadir)
|
||||
return public.returnJson(True, '存储目录迁移成功!')
|
||||
else:
|
||||
public.execShell('pkill -9 mysqld')
|
||||
public.writeFile(myfile, public.readFile(path + '/etc/my_backup.cnf'))
|
||||
start()
|
||||
return public.returnJson(False, '文件迁移失败!')
|
||||
|
||||
|
||||
def getMyPort():
|
||||
file = getConf()
|
||||
content = public.readFile(file)
|
||||
@@ -317,8 +368,9 @@ def getMyPort():
|
||||
|
||||
def setMyPort():
|
||||
args = getArgs()
|
||||
if not 'port' in args:
|
||||
return 'port missing'
|
||||
data = checkArgs(args, ['port'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
port = args['port']
|
||||
file = getConf()
|
||||
@@ -586,8 +638,10 @@ def syncToDatabases():
|
||||
|
||||
def setRootPwd():
|
||||
args = getArgs()
|
||||
if not 'password' in args:
|
||||
return 'password missing'
|
||||
data = checkArgs(args, ['password'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
password = args['password']
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
@@ -648,15 +702,31 @@ def setUserPwd():
|
||||
return isError
|
||||
pdb.execute("flush privileges")
|
||||
psdb.where("id=?", (id,)).setField('password', newpassword)
|
||||
return public.returnJson(True, public.getInfo('修改数据库[{1}]密码成功!', (name)))
|
||||
return public.returnJson(True, public.getInfo('修改数据库[{1}]密码成功!', (name,)))
|
||||
except Exception as ex:
|
||||
print str(ex)
|
||||
return public.returnJson(False, public.getInfo('修改数据库[{1}]密码失败!', (name)))
|
||||
# print str(ex)
|
||||
return public.returnJson(False, public.getInfo('修改数据库[{1}]密码失败!', (name,)))
|
||||
|
||||
|
||||
def setDbPs():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id', 'name', 'ps'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
ps = args['ps']
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
try:
|
||||
psdb = pSqliteDb('databases')
|
||||
psdb.where("id=?", (sid,)).setField('ps', ps)
|
||||
return public.returnJson(True, public.getInfo('修改数据库[{1}]备注成功!', (name,)))
|
||||
except Exception as e:
|
||||
return public.returnJson(True, public.getInfo('修改数据库[{1}]备注失败!', (name,)))
|
||||
|
||||
|
||||
def addDb():
|
||||
args = getArgs()
|
||||
|
||||
data = checkArgs(args,
|
||||
['password', 'name', 'codeing', 'db_user', 'dataAccess', 'ps'])
|
||||
if not data[0]:
|
||||
@@ -990,6 +1060,10 @@ if __name__ == "__main__":
|
||||
print getErrorLog()
|
||||
elif func == 'show_log':
|
||||
print getShowLogFile()
|
||||
elif func == 'my_db_pos':
|
||||
print getMyDbPos()
|
||||
elif func == 'set_db_pos':
|
||||
print setMyDbPos()
|
||||
elif func == 'my_port':
|
||||
print getMyPort()
|
||||
elif func == 'set_my_port':
|
||||
@@ -1014,6 +1088,8 @@ if __name__ == "__main__":
|
||||
print getDbAccess()
|
||||
elif func == 'set_db_access':
|
||||
print setDbAccess()
|
||||
elif func == 'set_db_ps':
|
||||
print setDbPs()
|
||||
elif func == 'get_db_info':
|
||||
print getDbInfo()
|
||||
elif func == 'repair_table':
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
"tip":"soft",
|
||||
"name":"mysql",
|
||||
"type":"运行环境",
|
||||
"ps":"MySQL是一种关系数据库管理系统!",
|
||||
"versions":["5.5","5.6","5.7","8.0"],
|
||||
"ps":"一种关系数据库管理系统!",
|
||||
"todo_versions":["5.6","5.7","8.0"],
|
||||
"versions":["5.5"],
|
||||
"updates":["5.5.62"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/mysql",
|
||||
"path":"server/mysql",
|
||||
"author":"mysql",
|
||||
"home":"https://dev.mysql.com/downloads/mysql",
|
||||
"date":"2017-11-24",
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
#!/bin/sh
|
||||
# chkconfig: 2345 55 25
|
||||
# Description: mysql service
|
||||
# distro. For CentOS/Redhat run: 'chkconfig --add mysql'
|
||||
|
||||
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
|
||||
# This file is public domain and comes with NO WARRANTY of any kind
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
action=$1
|
||||
|
||||
@@ -88,6 +88,26 @@ function runInfo(){
|
||||
}
|
||||
|
||||
|
||||
function myDbPos(){
|
||||
myPost('my_db_pos','',function(data){
|
||||
var con = '<div class="line ">\
|
||||
<div class="info-r ml0">\
|
||||
<input id="datadir" name="datadir" class="bt-input-text mr5 port" type="text" style="width:330px" value="'+data.data+'">\
|
||||
<span class="glyphicon cursor mr5 glyphicon-folder-open icon_datadir" onclick="changePath(\'datadir\')"></span>\
|
||||
<button id="btn_change_path" name="btn_change_path" class="btn btn-success btn-sm mr5 ml5 btn_change_port">迁移</button>\
|
||||
</div></div>';
|
||||
$(".soft-man-con").html(con);
|
||||
|
||||
$('#btn_change_path').click(function(){
|
||||
var datadir = $("input[name='datadir']").val();
|
||||
myPost('set_db_pos','datadir='+datadir,function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg,{icon:rdata.status ? 1 : 5,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function myPort(){
|
||||
myPost('my_port','',function(data){
|
||||
var con = '<div class="line ">\
|
||||
@@ -469,15 +489,6 @@ function copyPass(password){
|
||||
$("#bt_copys").click();
|
||||
}
|
||||
|
||||
function readerTableChecked(){
|
||||
$('table').find('th').find('input').bind('click',function(){
|
||||
$('table').find('td').find('input').each(function(i,obj){
|
||||
checked = $(this).prop('checked');
|
||||
$(this).prop('checked',!checked);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkSelect(){
|
||||
setTimeout(function () {
|
||||
var num = $('input[type="checkbox"].check:checked').length;
|
||||
@@ -749,36 +760,26 @@ function delDbBatch(){
|
||||
}
|
||||
|
||||
|
||||
function setDataByKey(tab, key, obj) {
|
||||
function setDbPs(id, name, obj) {
|
||||
var _span = $(obj);
|
||||
var _input = $("<input class='baktext' value="+_span.text()+" type='text' placeholder='备注信息' />");
|
||||
var _input = $("<input class='baktext' value=\""+_span.text()+"\" type='text' placeholder='备注信息' />");
|
||||
_span.hide().after(_input);
|
||||
_input.focus();
|
||||
_input.blur(function(){
|
||||
// var item = $(this).parents('tr').data('item');
|
||||
// console.log(item);
|
||||
// var _txt = $(this);
|
||||
// var data = {table:tab,id:item.id};
|
||||
// data[key] = _txt.val()
|
||||
// bt.pub.set_data_ps(data,function(rdata){
|
||||
// if(rdata.status){
|
||||
// _span.text(_txt.val());
|
||||
// _span.show();
|
||||
// _txt.remove();
|
||||
// }
|
||||
// })
|
||||
})
|
||||
$(this).remove();
|
||||
var ps = _input.val();
|
||||
_span.text(ps).show();
|
||||
var data = {name:name,id:id,ps:ps};
|
||||
myPost('set_db_ps', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
});
|
||||
_input.keyup(function(){
|
||||
if(event.keyCode == 13){
|
||||
_input.trigger('blur');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function setDbPs(data,callback){
|
||||
bt.send('setPs','data/setPs',data,function(rdata){
|
||||
if(callback) callback(rdata);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function openPhpmyadmin(name,username,password){
|
||||
@@ -847,7 +848,7 @@ function dbList(page, search){
|
||||
'<span class="ico-copy cursor btcopy" style="margin-left:10px" title="复制密码" onclick="copyPass(\''+rdata.data[i]['password']+'\')"></span>'+
|
||||
'</td>';
|
||||
// list += '<td>备份</td>';
|
||||
list += '<td><span class="c9 input-edit" onclick="setDataByKey(\'databases\',\'ps\',this)" style="display: inline-block;">'+rdata.data[i]['ps']+'</span></td>';
|
||||
list += '<td><span class="c9 input-edit" onclick="setDbPs(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['name']+'\',this)" style="display: inline-block;">'+rdata.data[i]['ps']+'</span></td>';
|
||||
list += '<td style="text-align:right">' +
|
||||
'<a href="javascript:;" class="btlink" onclick="openPhpmyadmin(\''+rdata.data[i]['name']+'\',\''+rdata.data[i]['username']+'\',\''+rdata.data[i]['password']+'\')" title="数据库管理">管理</a> | ' +
|
||||
'<a href="javascript:;" class="btlink" onclick="repTools(\''+rdata.data[i]['name']+'\')" title="MySQL优化修复工具">工具</a> | ' +
|
||||
@@ -944,9 +945,12 @@ function myLogs(){
|
||||
})
|
||||
|
||||
myPost('error_log', 'p=1', function(data){
|
||||
var error_body = data.data;
|
||||
if (error_body == "") {
|
||||
error_body = '当前没有日志内容!';
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var error_body = '';
|
||||
if (rdata.status){
|
||||
error_body = rdata.data;
|
||||
} else {
|
||||
error_body = rdata.msg;
|
||||
}
|
||||
$("#error_log").text(error_body);
|
||||
var ob = document.getElementById('error_log');
|
||||
@@ -1093,16 +1097,5 @@ function repTools(db_name, res){
|
||||
</ul></div>'
|
||||
});
|
||||
tableFixed('database_fix');
|
||||
//表格头固定
|
||||
function tableFixed(name) {
|
||||
var tableName = document.querySelector('#' + name);
|
||||
tableName.addEventListener('scroll', scrollHandle);
|
||||
}
|
||||
|
||||
function scrollHandle(e) {
|
||||
var scrollTop = this.scrollTop;
|
||||
//this.querySelector('thead').style.transform = 'translateY(' + scrollTop + 'px)';
|
||||
$(this).find("thead").css({ "transform": "translateY(" + scrollTop + "px)", "position": "relative", "z-index": "1" });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mysqlDir=${serverPath}/source/mysql
|
||||
|
||||
Install_mysql()
|
||||
@@ -54,7 +54,7 @@ Install_mysql()
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
#rm -rf $serverPath/mysql
|
||||
rm -rf $serverPath/mysql
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
lua_shared_dict limit 30m;
|
||||
lua_shared_dict drop_ip 30m;
|
||||
lua_shared_dict drop_sum 30m;
|
||||
lua_package_path "{$WAF_PATH}/lua/?.lua";
|
||||
access_by_lua_file {$WAF_PATH}/lua/init.lua;
|
||||
|
||||
#init_by_lua_file {$WAF_PATH}/lua/init.lua;
|
||||
#access_by_lua_file {$WAF_PATH}/lua/waf.lua;
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,249 @@
|
||||
<style>
|
||||
/*waf*/
|
||||
.lib-con-title {
|
||||
height: 26px;
|
||||
border-bottom: #ccc 1px solid;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.lib-con-title span {
|
||||
font-weight: bold;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.lib-con-title .ssh-item {
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.lib-con {
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.waftable .ssh-item {
|
||||
display: inline-block;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.waftable .ssh-item .btswitch + .btswitch-btn, .lib-con-title .ssh-item .btswitch + .btswitch-btn {
|
||||
width: 2.0em;
|
||||
height: 1.2em;
|
||||
margin-bottom: 0
|
||||
}
|
||||
|
||||
.rule_btn button {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.table .gztr td, #LogDayCon td {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.wavbox {
|
||||
width: 314px;
|
||||
float: left;
|
||||
height: 60px;
|
||||
line-height: 52px;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 5px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.wavbox span {
|
||||
font-size: 18px;
|
||||
margin: 0 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.screen .line {
|
||||
width: 33.333%;
|
||||
text-align: center;
|
||||
height: 70px;
|
||||
float: left;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.screen .line:nth-of-type(3n-1) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.screen .line .name {
|
||||
width: auto;
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin: 5px 0 8px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.screen .line .val {
|
||||
font-size: 18px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.wafview-head {
|
||||
height: 30px;
|
||||
border-bottom: #ccc 1px solid;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.waf-switch {
|
||||
margin-left: 20px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.wafinfo {
|
||||
line-height: 18px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.wafinfo .safetotal {
|
||||
margin: 0 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.screen {
|
||||
background-color: #fafafa;
|
||||
border: #ddd 1px solid;
|
||||
padding: 0;
|
||||
float: left;
|
||||
border-radius: 4px;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
width: 645px;
|
||||
}
|
||||
|
||||
.table .sitename, .filtertext {
|
||||
width: 100px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.td3txt {
|
||||
max-width: 200px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tdhide {
|
||||
display: none
|
||||
}
|
||||
|
||||
.divpre {
|
||||
padding: 9.5px;
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
background-color: #f6f6f6;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
max-height: 100px;
|
||||
overflow: auto
|
||||
}
|
||||
|
||||
.lib-con .table > tbody > tr.active td {
|
||||
background-color: #E4EEE0;
|
||||
}
|
||||
|
||||
.table_head_fix {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tipsval {
|
||||
margin-left: 2px;
|
||||
color: #fc6d26;
|
||||
padding: 0 2px;
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
border-radius: 3px;
|
||||
font-family: arial;
|
||||
vertical-align: 2px;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.tipsvalnull {
|
||||
color: #ccc;
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
.dot {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dot:after {
|
||||
content: "";
|
||||
height: 4px;
|
||||
width: 4px;
|
||||
border-radius: 2px;
|
||||
background: #fc6d26;
|
||||
position: absolute;
|
||||
left: -7px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.soft-man-con .CodeMirror {
|
||||
height: 250px;
|
||||
}
|
||||
.tab_list{
|
||||
width: 100%;
|
||||
}
|
||||
.tab_list .tab_block{
|
||||
width: 50%;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
border:1px solid #cfcfcfcf;
|
||||
border-top:0;
|
||||
background: #ececec;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tab_list .tab_block.active{
|
||||
background: #fff;
|
||||
border: 0;
|
||||
}
|
||||
.table_fix{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.help-info-text {
|
||||
margin-top: 0px;
|
||||
}
|
||||
</style>
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('op_waf');">服务</p>
|
||||
<p onclick="wafScreen();">首页</p>
|
||||
<p onclick="wafGloabl();">全局配置</p>
|
||||
<p onclick="wafSite();">站点配置</p>
|
||||
<p onclick="wafHistory();">封锁历史</p>
|
||||
<!-- <p onclick="wafLogs();">操作日志</p> -->
|
||||
</div>
|
||||
<!-- lib-con -->
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(800);
|
||||
$.getScript( "/plugins/file?name=op_waf&f=js/op_waf.js", function(){
|
||||
pluginService('op_waf');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,987 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import public
|
||||
|
||||
|
||||
app_debug = False
|
||||
if public.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'op_waf'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return public.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return public.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, public.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, public.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def getConf():
|
||||
path = public.getServerDir() + "/openresty/nginx/conf/nginx.conf"
|
||||
return path
|
||||
|
||||
|
||||
def initDomainInfo():
|
||||
data = []
|
||||
path_domains = getJsonPath('domains')
|
||||
|
||||
_list = public.M('sites').field('id,name,path').where(
|
||||
'status=?', ('1',)).order('id desc').select()
|
||||
|
||||
for i in range(len(_list)):
|
||||
tmp = {}
|
||||
tmp['name'] = _list[i]['name']
|
||||
tmp['path'] = _list[i]['path']
|
||||
|
||||
_list_domain = public.M('domain').field('name').where(
|
||||
'pid=?', (_list[i]['id'],)).order('id desc').select()
|
||||
|
||||
tmp_j = []
|
||||
for j in range(len(_list_domain)):
|
||||
tmp_j.append(_list_domain[j]['name'])
|
||||
|
||||
tmp['domains'] = tmp_j
|
||||
data.append(tmp)
|
||||
cjson = public.getJson(data)
|
||||
public.writeFile(path_domains, cjson)
|
||||
|
||||
|
||||
def initSiteInfo():
|
||||
data = []
|
||||
path_domains = getJsonPath('domains')
|
||||
path_config = getJsonPath('config')
|
||||
path_site = getJsonPath('site')
|
||||
|
||||
config_contents = public.readFile(path_config)
|
||||
config_contents = json.loads(config_contents)
|
||||
|
||||
domain_contents = public.readFile(path_domains)
|
||||
domain_contents = json.loads(domain_contents)
|
||||
|
||||
try:
|
||||
site_contents = public.readFile(path_site)
|
||||
except Exception as e:
|
||||
site_contents = "{}"
|
||||
|
||||
site_contents = json.loads(site_contents)
|
||||
site_contents_new = {}
|
||||
for x in range(len(domain_contents)):
|
||||
name = domain_contents[x]['name']
|
||||
if name in site_contents:
|
||||
site_contents_new[name] = site_contents[name]
|
||||
else:
|
||||
tmp = {}
|
||||
tmp['cdn'] = False
|
||||
tmp['log'] = True
|
||||
tmp['get'] = True
|
||||
tmp['post'] = True
|
||||
tmp['open'] = False
|
||||
|
||||
tmp['cc'] = config_contents['cc']
|
||||
tmp['retry'] = config_contents['retry']
|
||||
tmp['get'] = config_contents['get']
|
||||
tmp['post'] = config_contents['post']
|
||||
tmp['user-agent'] = config_contents['user-agent']
|
||||
tmp['cookie'] = config_contents['cookie']
|
||||
tmp['scan'] = config_contents['scan']
|
||||
|
||||
cdn_header = ['x-forwarded-for',
|
||||
'x-real-ip', 'HTTP_CF_CONNECTING_IP']
|
||||
tmp['cdn_header'] = cdn_header
|
||||
|
||||
disable_upload_ext = ["php", "jsp"]
|
||||
tmp['disable_upload_ext'] = disable_upload_ext
|
||||
|
||||
disable_path = ['sql']
|
||||
tmp['disable_ext'] = disable_path
|
||||
|
||||
site_contents_new[name] = tmp
|
||||
|
||||
cjson = public.getJson(site_contents_new)
|
||||
public.writeFile(path_site, cjson)
|
||||
|
||||
|
||||
def initTotalInfo():
|
||||
data = []
|
||||
path_domains = getJsonPath('domains')
|
||||
path_total = getJsonPath('total')
|
||||
|
||||
domain_contents = public.readFile(path_domains)
|
||||
domain_contents = json.loads(domain_contents)
|
||||
|
||||
try:
|
||||
total_contents = public.readFile(path_total)
|
||||
except Exception as e:
|
||||
total_contents = "{}"
|
||||
|
||||
total_contents = json.loads(total_contents)
|
||||
total_contents_new = {}
|
||||
for x in range(len(domain_contents)):
|
||||
name = domain_contents[x]['name']
|
||||
if 'sites' in total_contents and name in total_contents['sites']:
|
||||
pass
|
||||
else:
|
||||
tmp = {}
|
||||
tmp['cdn'] = 0
|
||||
tmp['log'] = 0
|
||||
tmp['get'] = 0
|
||||
tmp['post'] = 0
|
||||
tmp['total'] = 0
|
||||
_name = {}
|
||||
_name[name] = tmp
|
||||
total_contents['sites'] = _name
|
||||
|
||||
cjson = public.getJson(total_contents)
|
||||
public.writeFile(path_total, cjson)
|
||||
|
||||
|
||||
def status():
|
||||
initDomainInfo()
|
||||
initSiteInfo()
|
||||
initTotalInfo()
|
||||
|
||||
path = getConf()
|
||||
if not os.path.exists(path):
|
||||
return 'stop'
|
||||
|
||||
conf = public.readFile(path)
|
||||
if conf.find("#include luawaf.conf;") != -1:
|
||||
return 'stop'
|
||||
if conf.find("luawaf.conf;") == -1:
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = public.getServerDir()
|
||||
waf_path = public.getServerDir() + "/openresty/nginx/conf/waf"
|
||||
content = content.replace('{$ROOT_PATH}', public.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$WAF_PATH}', waf_path)
|
||||
return content
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
config = getPluginDir() + '/waf/config.json'
|
||||
content = public.readFile(config)
|
||||
content = json.loads(content)
|
||||
content['reqfile_path'] = public.getServerDir(
|
||||
) + "/openresty/nginx/conf/waf/html"
|
||||
public.writeFile(config, public.getJson(content))
|
||||
|
||||
path = public.getServerDir() + "/openresty/nginx/conf"
|
||||
if not os.path.exists(path + '/waf'):
|
||||
sdir = getPluginDir() + '/waf'
|
||||
cmd = 'cp -rf ' + sdir + ' ' + path
|
||||
public.execShell(cmd)
|
||||
|
||||
config = public.getServerDir() + "/openresty/nginx/conf/waf/lua/init.lua"
|
||||
content = public.readFile(config)
|
||||
content = contentReplace(content)
|
||||
public.writeFile(config, content)
|
||||
|
||||
waf_conf = public.getServerDir() + "/openresty/nginx/conf/luawaf.conf"
|
||||
waf_tpl = getPluginDir() + "/conf/luawaf.conf"
|
||||
content = public.readFile(waf_tpl)
|
||||
content = contentReplace(content)
|
||||
public.writeFile(waf_conf, content)
|
||||
|
||||
|
||||
def start():
|
||||
initDreplace()
|
||||
|
||||
path = getConf()
|
||||
conf = public.readFile(path)
|
||||
conf = conf.replace('#include luawaf.conf;', "include luawaf.conf;")
|
||||
|
||||
public.writeFile(path, conf)
|
||||
public.restartWeb()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def stop():
|
||||
path = public.getServerDir() + "/openresty/nginx/conf/waf"
|
||||
if os.path.exists(path):
|
||||
cmd = 'rm -rf ' + path
|
||||
public.execShell(cmd)
|
||||
|
||||
path = getConf()
|
||||
conf = public.readFile(path)
|
||||
conf = conf.replace('include luawaf.conf;', "#include luawaf.conf;")
|
||||
|
||||
public.writeFile(path, conf)
|
||||
public.restartWeb()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def restart():
|
||||
public.restartWeb()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def reload():
|
||||
stop()
|
||||
public.execShell('rm -rf ' + public.getServerDir() +
|
||||
"/openresty/nginx/logs/error.log")
|
||||
start()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def getJsonPath(name):
|
||||
path = public.getServerDir() + "/openresty/nginx/conf/waf/" + name + ".json"
|
||||
return path
|
||||
|
||||
|
||||
def getRuleJsonPath(name):
|
||||
path = public.getServerDir() + "/openresty/nginx/conf/waf/rule/" + name + ".json"
|
||||
return path
|
||||
|
||||
|
||||
def getRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['rule_name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
rule_name = args['rule_name']
|
||||
fpath = getRuleJsonPath(rule_name)
|
||||
content = public.readFile(fpath)
|
||||
return public.returnJson(True, 'ok', content)
|
||||
|
||||
|
||||
def addRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['ruleName', 'ruleValue', 'ps'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
ruleValue = args['ruleValue']
|
||||
ruleName = args['ruleName']
|
||||
ps = args['ps']
|
||||
|
||||
fpath = getRuleJsonPath(ruleName)
|
||||
content = public.readFile(fpath)
|
||||
content = json.loads(content)
|
||||
|
||||
tmp_k = []
|
||||
tmp_k.append(1)
|
||||
tmp_k.append(ruleValue)
|
||||
tmp_k.append(ps)
|
||||
tmp_k.append(1)
|
||||
|
||||
content.append(tmp_k)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(fpath, cjson)
|
||||
|
||||
return public.returnJson(True, '设置成功!', content)
|
||||
|
||||
def removeRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['ruleName', 'index'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
index = int(args['index'])
|
||||
ruleName = args['ruleName']
|
||||
|
||||
fpath = getRuleJsonPath(ruleName)
|
||||
content = public.readFile(fpath)
|
||||
content = json.loads(content)
|
||||
|
||||
k = content[index]
|
||||
content.remove(k)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(fpath, cjson)
|
||||
|
||||
return public.returnJson(True, '设置成功!', content)
|
||||
|
||||
def setRuleState():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['ruleName', 'index'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
index = int(args['index'])
|
||||
ruleName = args['ruleName']
|
||||
|
||||
fpath = getRuleJsonPath(ruleName)
|
||||
content = public.readFile(fpath)
|
||||
content = json.loads(content)
|
||||
|
||||
b = content[index][0]
|
||||
if b == 1:
|
||||
content[index][0] = 0
|
||||
else:
|
||||
content[index][0] = 1
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(fpath, cjson)
|
||||
|
||||
return public.returnJson(True, '设置成功!', content)
|
||||
|
||||
|
||||
|
||||
def modifyRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['index', 'ruleName', 'ruleBody', 'rulePs'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
index = int(args['index'])
|
||||
ruleName = args['ruleName']
|
||||
ruleBody = args['ruleBody']
|
||||
rulePs = args['rulePs']
|
||||
|
||||
fpath = getRuleJsonPath(ruleName)
|
||||
content = public.readFile(fpath)
|
||||
content = json.loads(content)
|
||||
|
||||
tmp = content[index]
|
||||
|
||||
tmp_k = []
|
||||
tmp_k.append(tmp[0])
|
||||
tmp_k.append(ruleBody)
|
||||
tmp_k.append(rulePs)
|
||||
tmp_k.append(tmp[3])
|
||||
|
||||
content[index] = tmp_k
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(fpath, cjson)
|
||||
|
||||
return public.returnJson(True, '设置成功!', content)
|
||||
|
||||
|
||||
def getSiteRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'ruleName'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
siteName = args['siteName']
|
||||
siteRule = args['ruleName']
|
||||
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
r = content[siteName][siteRule]
|
||||
|
||||
cjson = public.getJson(r)
|
||||
return public.returnJson(True, 'ok!', cjson)
|
||||
|
||||
|
||||
def addSiteRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'ruleName', 'ruleValue'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
siteName = args['siteName']
|
||||
siteRule = args['ruleName']
|
||||
ruleValue = args['ruleValue']
|
||||
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
content[siteName][siteRule].append(ruleValue)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def addIpWhite():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['start_ip', 'end_ip'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
start_ip = args['start_ip']
|
||||
end_ip = args['end_ip']
|
||||
|
||||
path = getRuleJsonPath('ip_white')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
data = []
|
||||
|
||||
start_ip_list = start_ip.split('.')
|
||||
tmp = []
|
||||
for x in range(len(start_ip_list)):
|
||||
tmp.append(int(start_ip_list[x]))
|
||||
|
||||
end_ip_list = end_ip.split('.')
|
||||
tmp2 = []
|
||||
for x in range(len(end_ip_list)):
|
||||
tmp2.append(int(end_ip_list[x]))
|
||||
|
||||
data.append(tmp)
|
||||
data.append(tmp2)
|
||||
|
||||
content.append(data)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def removeIpWhite():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['index'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
index = args['index']
|
||||
|
||||
path = getRuleJsonPath('ip_white')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
k = content[int(index)]
|
||||
content.remove(k)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def addIpBlack():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['start_ip', 'end_ip'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
start_ip = args['start_ip']
|
||||
end_ip = args['end_ip']
|
||||
|
||||
path = getRuleJsonPath('ip_black')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
data = []
|
||||
|
||||
start_ip_list = start_ip.split('.')
|
||||
tmp = []
|
||||
for x in range(len(start_ip_list)):
|
||||
tmp.append(int(start_ip_list[x]))
|
||||
|
||||
end_ip_list = end_ip.split('.')
|
||||
tmp2 = []
|
||||
for x in range(len(end_ip_list)):
|
||||
tmp2.append(int(end_ip_list[x]))
|
||||
|
||||
data.append(tmp)
|
||||
data.append(tmp2)
|
||||
|
||||
content.append(data)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def removeIpBlack():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['index'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
index = args['index']
|
||||
|
||||
path = getRuleJsonPath('ip_black')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
k = content[int(index)]
|
||||
content.remove(k)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def setIpv6Black():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['addr'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
addr = args['addr'].replace('_', ':')
|
||||
path = getRuleJsonPath('ipv6_black')
|
||||
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
content.append(addr)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def delIpv6Black():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['addr'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
addr = args['addr'].replace('_', ':')
|
||||
path = getRuleJsonPath('ipv6_black')
|
||||
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
content.remove(addr)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def removeSiteRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'ruleName', 'index'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
siteName = args['siteName']
|
||||
siteRule = args['ruleName']
|
||||
index = args['index']
|
||||
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
ruleValue = content[siteName][siteRule][int(index)]
|
||||
content[siteName][siteRule].remove(ruleValue)
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def setObjStatus():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['obj', 'statusCode'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conf = getJsonPath('config')
|
||||
content = public.readFile(conf)
|
||||
cobj = json.loads(content)
|
||||
|
||||
o = args['obj']
|
||||
status = args['statusCode']
|
||||
cobj[o]['status'] = status
|
||||
|
||||
cjson = public.getJson(cobj)
|
||||
public.writeFile(conf, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def setRetry():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['retry', 'retry_time',
|
||||
'retry_cycle', 'is_open_global'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conf = getJsonPath('config')
|
||||
content = public.readFile(conf)
|
||||
cobj = json.loads(content)
|
||||
|
||||
cobj['retry'] = args
|
||||
|
||||
cjson = public.getJson(cobj)
|
||||
public.writeFile(conf, cjson)
|
||||
|
||||
return public.returnJson(True, '设置成功!', [])
|
||||
|
||||
|
||||
def setSiteRetry():
|
||||
return public.returnJson(True, '设置成功-?!', [])
|
||||
|
||||
|
||||
def setCcConf():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'cycle', 'limit', 'endtime','is_open_global','increase'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conf = getJsonPath('config')
|
||||
content = public.readFile(conf)
|
||||
cobj = json.loads(content)
|
||||
|
||||
tmp = cobj['cc']
|
||||
|
||||
|
||||
tmp['cycle'] = int(args['cycle'])
|
||||
tmp['limit'] = int(args['limit'])
|
||||
tmp['endtime'] = int(args['endtime'])
|
||||
tmp['is_open_global'] = args['is_open_global']
|
||||
tmp['increase'] = args['increase']
|
||||
cobj['cc'] = tmp
|
||||
|
||||
cjson = public.getJson(cobj)
|
||||
public.writeFile(conf, cjson)
|
||||
return public.returnJson(True, '设置成功!', [])
|
||||
|
||||
def setSiteCcConf():
|
||||
return public.returnJson(True, '设置成功-?!', [])
|
||||
|
||||
def saveScanRule():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['header', 'cookie', 'args'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = getRuleJsonPath('scan_black')
|
||||
cjson = public.getJson(args)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!', [])
|
||||
|
||||
|
||||
def getSiteConfig():
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
|
||||
content = json.loads(content)
|
||||
|
||||
total = getJsonPath('total')
|
||||
total_content = public.readFile(total)
|
||||
total_content = json.loads(total_content)
|
||||
|
||||
# print total_content
|
||||
|
||||
for x in content:
|
||||
tmp = []
|
||||
tmp_v = {}
|
||||
if 'sites' in total_content and x in total_content['sites']:
|
||||
tmp_v = total_content['sites'][x]
|
||||
|
||||
key_list = ['get', 'post', 'user-agent', 'cookie', 'cdn', 'cc']
|
||||
for kx in range(len(key_list)):
|
||||
ktmp = {}
|
||||
|
||||
if kx in tmp_v:
|
||||
ktmp['value'] = tmp_v[key_list[kx]]
|
||||
else:
|
||||
ktmp['value'] = ''
|
||||
ktmp['key'] = key_list[kx]
|
||||
tmp.append(ktmp)
|
||||
|
||||
# print tmp
|
||||
content[x]['total'] = tmp
|
||||
|
||||
content = public.getJson(content)
|
||||
return public.returnJson(True, 'ok!', content)
|
||||
|
||||
|
||||
def getSiteConfigByName():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
siteName = args['siteName']
|
||||
retData = {}
|
||||
if siteName in content:
|
||||
retData = content[siteName]
|
||||
|
||||
return public.returnJson(True, 'ok!', retData)
|
||||
|
||||
|
||||
def addSiteCdnHeader():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'cdn_header'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
siteName = args['siteName']
|
||||
retData = {}
|
||||
if siteName in content:
|
||||
content[siteName]['cdn_header'].append(args['cdn_header'])
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '添加成功!')
|
||||
|
||||
|
||||
def removeSiteCdnHeader():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'cdn_header'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
siteName = args['siteName']
|
||||
retData = {}
|
||||
if siteName in content:
|
||||
content[siteName]['cdn_header'].remove(args['cdn_header'])
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '删除成功!')
|
||||
|
||||
|
||||
def outputData():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['s_Name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = getRuleJsonPath(args['s_Name'])
|
||||
content = public.readFile(path)
|
||||
return public.returnJson(True, 'ok', content)
|
||||
|
||||
|
||||
def importData():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['s_Name', 'pdata'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = getRuleJsonPath(args['s_Name'])
|
||||
public.writeFile(path, args['pdata'])
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def getLogsList():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
data = []
|
||||
path = public.getLogsDir() + '/waf'
|
||||
files = os.listdir(path)
|
||||
for f in files:
|
||||
if f == '.DS_Store':
|
||||
continue
|
||||
f = f.split('_')
|
||||
if f[0] == args['siteName']:
|
||||
fl = f[1].split('.')
|
||||
data.append(fl[0])
|
||||
|
||||
return public.returnJson(True, 'ok!', data)
|
||||
|
||||
|
||||
def getSafeLogs():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'toDate', 'p'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = public.getLogsDir() + '/waf'
|
||||
file = path + '/' + args['siteName'] + '_' + args['toDate'] + '.log'
|
||||
if not os.path.exists(file):
|
||||
return public.returnJson(False, "文件不存在!")
|
||||
|
||||
retData = []
|
||||
file = open(file)
|
||||
while 1:
|
||||
lines = file.readlines(100000)
|
||||
if not lines:
|
||||
break
|
||||
for line in lines:
|
||||
|
||||
retData.append(json.loads(line))
|
||||
|
||||
return public.returnJson(True, '设置成功!', retData)
|
||||
|
||||
|
||||
def setObjOpen():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['obj'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conf = getJsonPath('config')
|
||||
content = public.readFile(conf)
|
||||
cobj = json.loads(content)
|
||||
|
||||
o = args['obj']
|
||||
if cobj[o]["open"]:
|
||||
cobj[o]["open"] = False
|
||||
else:
|
||||
cobj[o]["open"] = True
|
||||
|
||||
cjson = public.getJson(cobj)
|
||||
public.writeFile(conf, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def setSiteObjOpen():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['siteName', 'obj'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
siteName = args['siteName']
|
||||
obj = args['obj']
|
||||
|
||||
path = getJsonPath('site')
|
||||
content = public.readFile(path)
|
||||
content = json.loads(content)
|
||||
|
||||
if type(content[siteName][obj]) == bool:
|
||||
if content[siteName][obj]:
|
||||
content[siteName][obj] = False
|
||||
else:
|
||||
content[siteName][obj] = True
|
||||
else:
|
||||
if content[siteName][obj]['open']:
|
||||
content[siteName][obj]['open'] = False
|
||||
else:
|
||||
content[siteName][obj]['open'] = True
|
||||
|
||||
cjson = public.getJson(content)
|
||||
public.writeFile(path, cjson)
|
||||
return public.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
|
||||
def getWafSrceen():
|
||||
conf = getJsonPath('total')
|
||||
return public.readFile(conf)
|
||||
|
||||
|
||||
def getWafConf():
|
||||
conf = getJsonPath('config')
|
||||
return public.readFile(conf)
|
||||
|
||||
|
||||
def getWafSite():
|
||||
return ''
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print status()
|
||||
elif func == 'start':
|
||||
print start()
|
||||
elif func == 'stop':
|
||||
print stop()
|
||||
elif func == 'restart':
|
||||
print restart()
|
||||
elif func == 'reload':
|
||||
print reload()
|
||||
elif func == 'conf':
|
||||
print getConf()
|
||||
elif func == 'get_rule':
|
||||
print getRule()
|
||||
elif func == 'add_rule':
|
||||
print addRule()
|
||||
elif func == 'remove_rule':
|
||||
print removeRule()
|
||||
elif func == 'set_rule_state':
|
||||
print setRuleState()
|
||||
elif func == 'modify_rule':
|
||||
print modifyRule()
|
||||
elif func == 'get_site_rule':
|
||||
print getSiteRule()
|
||||
elif func == 'add_site_rule':
|
||||
print addSiteRule()
|
||||
elif func == 'add_ip_white':
|
||||
print addIpWhite()
|
||||
elif func == 'remove_ip_white':
|
||||
print removeIpWhite()
|
||||
elif func == 'add_ip_black':
|
||||
print addIpBlack()
|
||||
elif func == 'remove_ip_black':
|
||||
print removeIpBlack()
|
||||
elif func == 'set_ipv6_black':
|
||||
print setIpv6Black()
|
||||
elif func == 'del_ipv6_black':
|
||||
print delIpv6Black()
|
||||
elif func == 'remove_site_rule':
|
||||
print removeSiteRule()
|
||||
elif func == 'set_obj_status':
|
||||
print setObjStatus()
|
||||
elif func == 'set_obj_open':
|
||||
print setObjOpen()
|
||||
elif func == 'set_site_obj_open':
|
||||
print setSiteObjOpen()
|
||||
elif func == 'set_cc_conf':
|
||||
print setCcConf()
|
||||
elif func == 'set_site_cc_conf':
|
||||
print setSiteCcConf()
|
||||
elif func == 'set_retry':
|
||||
print setRetry()
|
||||
elif func == 'set_site_retry':
|
||||
print setSiteRetry()
|
||||
elif func == 'save_scan_rule':
|
||||
print saveScanRule()
|
||||
elif func == 'get_site_config':
|
||||
print getSiteConfig()
|
||||
elif func == 'get_site_config_byname':
|
||||
print getSiteConfigByName()
|
||||
elif func == 'add_site_cdn_header':
|
||||
print addSiteCdnHeader()
|
||||
elif func == 'remove_site_cdn_header':
|
||||
print removeSiteCdnHeader()
|
||||
elif func == 'get_logs_list':
|
||||
print getLogsList()
|
||||
elif func == 'get_safe_logs':
|
||||
print getSafeLogs()
|
||||
elif func == 'output_data':
|
||||
print outputData()
|
||||
elif func == 'import_data':
|
||||
print importData()
|
||||
elif func == 'waf_srceen':
|
||||
print getWafSrceen()
|
||||
elif func == 'waf_conf':
|
||||
print getWafConf()
|
||||
elif func == 'waf_site':
|
||||
print getWafSite()
|
||||
else:
|
||||
print 'error'
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title":"OP防火墙[DEV]",
|
||||
"tip":"soft",
|
||||
"name":"op_waf",
|
||||
"type":"其他插件",
|
||||
"ps":"有效防止sql注入/xss/一句话木马等常见渗透攻击",
|
||||
"shell":"install.sh",
|
||||
"checks":"server/op_waf",
|
||||
"path":"server/op_waf",
|
||||
"author":"loveshell",
|
||||
"home":"https://github.com/loveshell/ngx_lua_waf",
|
||||
"date":"2019-04-21",
|
||||
"pid": "1",
|
||||
"versions": ["0.1"]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
Install_of(){
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/op_waf
|
||||
|
||||
echo '0.1' > $serverPath/op_waf/version.pl
|
||||
echo 'install ok' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_of(){
|
||||
rm -rf $serverPath/op_waf
|
||||
}
|
||||
|
||||
|
||||
action=$1
|
||||
type=$2
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_of
|
||||
else
|
||||
Uninstall_of
|
||||
fi
|
||||
@@ -0,0 +1 @@
|
||||
{"reqfile_path":"/Users/midoks/Desktop/fwww/server/openresty/nginx/conf/waf/html","retry":{"retry_time":180,"is_open_global":0,"retry":6,"retry_cycle":60},"log":true,"scan":{"status":444,"ps":"过滤常见扫描测试工具的渗透测试","open":true,"reqfile":""},"cc":{"status":444,"ps":"过虑CC攻击","limit":120,"endtime":300,"open":true,"reqfile":"","cycle":60},"get":{"status":403,"ps":"过滤uri、uri参数中常见sql注入、xss等攻击","open":true,"reqfile":"get.html"},"log_save":30,"user-agent":{"status":403,"ps":"通常用于过滤浏览器、蜘蛛及一些自动扫描器","open":true,"reqfile":"user_agent.html"},"other":{"status":403,"ps":"其它非通用过滤","reqfile":"other.html"},"cookie":{"status":403,"ps":"过滤利用Cookie发起的渗透攻击","open":true,"reqfile":"cookie.html"},"logs_path":"/www/wwwlogs/btwaf","post":{"status":403,"ps":"过滤POST参数中常见sql注入、xss等攻击","open":true,"reqfile":"post.html"},"open":true}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>网站防火墙</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;color:#444}
|
||||
body{font-size:14px;font-family:"宋体"}
|
||||
.main{width:600px;margin:10% auto;}
|
||||
.title{background: #20a53a;color: #fff;font-size: 16px;height: 40px;line-height: 40px;padding-left: 20px;}
|
||||
.content{background-color:#f3f7f9; height:280px;border:1px dashed #c6d9b6;padding:20px}
|
||||
.t1{border-bottom: 1px dashed #c6d9b6;color: #ff4000;font-weight: bold; margin: 0 0 20px; padding-bottom: 18px;}
|
||||
.t2{margin-bottom:8px; font-weight:bold}
|
||||
ol{margin:0 0 20px 22px;padding:0;}
|
||||
ol li{line-height:30px}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="title">网站防火墙</div>
|
||||
<div class="content">
|
||||
<p class="t1">您的请求带有不合法参数,已被网站管理员设置拦截!</p>
|
||||
<p class="t2">可能原因:</p>
|
||||
<ol>
|
||||
<li>您提交的内容包含危险的攻击请求</li>
|
||||
</ol>
|
||||
<p class="t2">如何解决:</p>
|
||||
<ol>
|
||||
<li>检查提交内容;</li>
|
||||
<li>如网站托管,请联系空间提供商;</li>
|
||||
<li>普通网站访客,请联系网站管理员;</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>网站防火墙</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;color:#444}
|
||||
body{font-size:14px;font-family:"宋体"}
|
||||
.main{width:600px;margin:10% auto;}
|
||||
.title{background: #20a53a;color: #fff;font-size: 16px;height: 40px;line-height: 40px;padding-left: 20px;}
|
||||
.content{background-color:#f3f7f9; height:280px;border:1px dashed #c6d9b6;padding:20px}
|
||||
.t1{border-bottom: 1px dashed #c6d9b6;color: #ff4000;font-weight: bold; margin: 0 0 20px; padding-bottom: 18px;}
|
||||
.t2{margin-bottom:8px; font-weight:bold}
|
||||
ol{margin:0 0 20px 22px;padding:0;}
|
||||
ol li{line-height:30px}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="title">网站防火墙</div>
|
||||
<div class="content">
|
||||
<p class="t1">您的请求带有不合法参数,已被网站管理员设置拦截!</p>
|
||||
<p class="t2">可能原因:</p>
|
||||
<ol>
|
||||
<li>您提交的内容包含危险的攻击请求</li>
|
||||
</ol>
|
||||
<p class="t2">如何解决:</p>
|
||||
<ol>
|
||||
<li>检查提交内容;</li>
|
||||
<li>如网站托管,请联系空间提供商;</li>
|
||||
<li>普通网站访客,请联系网站管理员;</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>网站防火墙</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;color:#444}
|
||||
body{font-size:14px;font-family:"宋体"}
|
||||
.main{width:600px;margin:10% auto;}
|
||||
.title{background: #20a53a;color: #fff;font-size: 16px;height: 40px;line-height: 40px;padding-left: 20px;}
|
||||
.content{background-color:#f3f7f9; height:280px;border:1px dashed #c6d9b6;padding:20px}
|
||||
.t1{border-bottom: 1px dashed #c6d9b6;color: #ff4000;font-weight: bold; margin: 0 0 20px; padding-bottom: 18px;}
|
||||
.t2{margin-bottom:8px; font-weight:bold}
|
||||
ol{margin:0 0 20px 22px;padding:0;}
|
||||
ol li{line-height:30px}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="title">网站防火墙</div>
|
||||
<div class="content">
|
||||
<p class="t1">您的请求带有不合法参数,已被网站管理员设置拦截!</p>
|
||||
<p class="t2">可能原因:</p>
|
||||
<ol>
|
||||
<li>您提交的内容包含危险的攻击请求</li>
|
||||
</ol>
|
||||
<p class="t2">如何解决:</p>
|
||||
<ol>
|
||||
<li>检查提交内容;</li>
|
||||
<li>如网站托管,请联系空间提供商;</li>
|
||||
<li>普通网站访客,请联系网站管理员;</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>网站防火墙</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;color:#444}
|
||||
body{font-size:14px;font-family:"宋体"}
|
||||
.main{width:600px;margin:10% auto;}
|
||||
.title{background: #20a53a;color: #fff;font-size: 16px;height: 40px;line-height: 40px;padding-left: 20px;}
|
||||
.content{background-color:#f3f7f9; height:280px;border:1px dashed #c6d9b6;padding:20px}
|
||||
.t1{border-bottom: 1px dashed #c6d9b6;color: #ff4000;font-weight: bold; margin: 0 0 20px; padding-bottom: 18px;}
|
||||
.t2{margin-bottom:8px; font-weight:bold}
|
||||
ol{margin:0 0 20px 22px;padding:0;}
|
||||
ol li{line-height:30px}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="title">网站防火墙</div>
|
||||
<div class="content">
|
||||
<p class="t1">您的请求带有不合法参数,已被网站管理员设置拦截!</p>
|
||||
<p class="t2">可能原因:</p>
|
||||
<ol>
|
||||
<li>您提交的内容包含危险的攻击请求</li>
|
||||
</ol>
|
||||
<p class="t2">如何解决:</p>
|
||||
<ol>
|
||||
<li>检查提交内容;</li>
|
||||
<li>如网站托管,请联系空间提供商;</li>
|
||||
<li>普通网站访客,请联系网站管理员;</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>网站防火墙</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;color:#444}
|
||||
body{font-size:14px;font-family:"宋体"}
|
||||
.main{width:600px;margin:10% auto;}
|
||||
.title{background: #20a53a;color: #fff;font-size: 16px;height: 40px;line-height: 40px;padding-left: 20px;}
|
||||
.content{background-color:#f3f7f9; height:280px;border:1px dashed #c6d9b6;padding:20px}
|
||||
.t1{border-bottom: 1px dashed #c6d9b6;color: #ff4000;font-weight: bold; margin: 0 0 20px; padding-bottom: 18px;}
|
||||
.t2{margin-bottom:8px; font-weight:bold}
|
||||
ol{margin:0 0 20px 22px;padding:0;}
|
||||
ol li{line-height:30px}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="title">网站防火墙</div>
|
||||
<div class="content">
|
||||
<p class="t1">您的请求带有不合法参数,已被网站管理员设置拦截!</p>
|
||||
<p class="t2">可能原因:</p>
|
||||
<ol>
|
||||
<li>您提交的内容包含危险的攻击请求</li>
|
||||
</ol>
|
||||
<p class="t2">如何解决:</p>
|
||||
<ol>
|
||||
<li>检查提交内容;</li>
|
||||
<li>如网站托管,请联系空间提供商;</li>
|
||||
<li>普通网站访客,请联系网站管理员;</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local _M = { _VERSION = '0.01' }
|
||||
local mt = { __index = _M }
|
||||
local json = require "cjson"
|
||||
local ngx_match = ngx.re.find
|
||||
|
||||
|
||||
function _M.new(self, cpath, rpath, logdir)
|
||||
-- ngx.log(ngx.ERR,"read:"..cpath..",rpath:"..rpath)
|
||||
local opt = {
|
||||
cpath = cpath,
|
||||
rpath = rpath,
|
||||
logdir = logdir,
|
||||
config = '',
|
||||
site_config = '',
|
||||
params = nil
|
||||
}
|
||||
local p = setmetatable(opt, mt)
|
||||
return p
|
||||
end
|
||||
|
||||
|
||||
function _M.setConfData( self, config, site_config )
|
||||
self.config = config
|
||||
self.site_config = site_config
|
||||
|
||||
end
|
||||
|
||||
|
||||
function _M.setParams( self, params )
|
||||
self.params = params
|
||||
end
|
||||
|
||||
|
||||
function _M.is_min(self, ip1, ip2)
|
||||
n = 0
|
||||
for _,v in ipairs({1,2,3,4})
|
||||
do
|
||||
if ip1[v] == ip2[v] then
|
||||
n = n + 1
|
||||
elseif ip1[v] > ip2[v] then
|
||||
break
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _M.is_max(self,ip1,ip2)
|
||||
n = 0
|
||||
for _,v in ipairs({1,2,3,4})
|
||||
do
|
||||
if ip1[v] == ip2[v] then
|
||||
n = n + 1
|
||||
elseif ip1[v] < ip2[v] then
|
||||
break
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _M.split(self, str,reps )
|
||||
local resultStrList = {}
|
||||
string.gsub(str,'[^'..reps..']+',function(w)
|
||||
table.insert(resultStrList,w)
|
||||
end)
|
||||
return resultStrList
|
||||
end
|
||||
|
||||
function _M.arrip(self, ipstr)
|
||||
if ipstr == 'unknown' then return {0,0,0,0} end
|
||||
if string.find(ipstr,':') then return ipstr end
|
||||
iparr = self:split(ipstr,'.')
|
||||
iparr[1] = tonumber(iparr[1])
|
||||
iparr[2] = tonumber(iparr[2])
|
||||
iparr[3] = tonumber(iparr[3])
|
||||
iparr[4] = tonumber(iparr[4])
|
||||
return iparr
|
||||
end
|
||||
|
||||
|
||||
function _M.compare_ip(self,ips)
|
||||
local ip = self.params["ip"]
|
||||
local ipn = self.params["ipn"]
|
||||
if ip == 'unknown' then return true end
|
||||
if string.find(ip,':') then return false end
|
||||
if not self:is_max(ipn,ips[2]) then return false end
|
||||
if not self:is_min(ipn,ips[1]) then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function _M.return_message(self, status, msg)
|
||||
ngx.header.content_type = "application/json;"
|
||||
ngx.status = status
|
||||
ngx.say(json.encode(msg))
|
||||
ngx.exit(status)
|
||||
end
|
||||
|
||||
|
||||
function _M.return_html(self,status,html)
|
||||
ngx.header.content_type = "text/html"
|
||||
ngx.status = status
|
||||
ngx.say(html)
|
||||
ngx.exit(status)
|
||||
end
|
||||
|
||||
function _M.read_file_body(self, filename)
|
||||
-- ngx.log(ngx.ERR,"read_file_body:"..filename)
|
||||
fp = io.open(filename, 'r')
|
||||
if fp == nil then
|
||||
return nil
|
||||
end
|
||||
fbody = fp:read("*a")
|
||||
fp:close()
|
||||
if fbody == '' then
|
||||
return nil
|
||||
end
|
||||
return fbody
|
||||
end
|
||||
|
||||
|
||||
|
||||
function _M.write_file(self, filename, body)
|
||||
fp = io.open(filename,'ab')
|
||||
if fp == nil then
|
||||
return nil
|
||||
end
|
||||
fp:write(body)
|
||||
fp:flush()
|
||||
fp:close()
|
||||
return true
|
||||
end
|
||||
|
||||
function _M.write_file_clear(self, filename, body)
|
||||
fp = io.open(filename,'w')
|
||||
if fp == nil then
|
||||
return nil
|
||||
end
|
||||
fp:write(body)
|
||||
fp:flush()
|
||||
fp:close()
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function _M.write_drop_ip(self, is_drop, drop_time)
|
||||
local filename = self.cpath .. 'drop_ip.log'
|
||||
local fp = io.open(filename,'ab')
|
||||
local server_name = self.params["server_name"]
|
||||
local ip = self.params["server_name"]
|
||||
local request_uri = self.params["request_uri"]
|
||||
|
||||
if fp == nil then return false end
|
||||
local logtmp = {os.time(),ip,server_name,request_uri,drop_time,is_drop}
|
||||
local logstr = json.encode(logtmp) .. "\n"
|
||||
fp:write(logstr)
|
||||
fp:flush()
|
||||
fp:close()
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function _M.write_to_file(self, logstr)
|
||||
local server_name = self.params['server_name']
|
||||
local filename = self.logdir .. '/' .. server_name .. '_' .. ngx.today() .. '.log'
|
||||
self:write_file(filename, logstr)
|
||||
return true
|
||||
end
|
||||
|
||||
function _M.continue_key(self,key)
|
||||
key = tostring(key)
|
||||
if string.len(key) > 64 then return false end;
|
||||
local keys = {"content","contents","body","msg","file","files","img","newcontent"}
|
||||
for _,k in ipairs(keys)
|
||||
do
|
||||
if k == key then return false end;
|
||||
end
|
||||
return true;
|
||||
end
|
||||
|
||||
|
||||
function _M.array_len(self, arr)
|
||||
if not arr then return 0 end
|
||||
local count = 0
|
||||
for _,v in ipairs(arr)
|
||||
do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
function _M.is_ipaddr(self, client_ip)
|
||||
local cipn = split(client_ip,'.')
|
||||
if self:array_len(cipn) < 4 then return false end
|
||||
for _,v in ipairs({1,2,3,4})
|
||||
do
|
||||
local ipv = tonumber(cipn[v])
|
||||
if ipv == nil then return false end
|
||||
if ipv > 255 or ipv < 0 then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function _M.read_file_body_decode(self, filename)
|
||||
return json.decode(self:read_file_body(filename))
|
||||
end
|
||||
|
||||
function _M.select_rule(self, rules)
|
||||
if not rules then return {} end
|
||||
new_rules = {}
|
||||
for i,v in ipairs(rules)
|
||||
do
|
||||
if v[1] == 1 then
|
||||
table.insert(new_rules,v[2])
|
||||
end
|
||||
end
|
||||
return new_rules
|
||||
end
|
||||
|
||||
|
||||
function _M.read_file(self, name)
|
||||
f = self.rpath .. name .. '.json'
|
||||
fbody = self:read_file_body(f)
|
||||
if fbody == nil then
|
||||
return {}
|
||||
end
|
||||
return json.decode(fbody)
|
||||
end
|
||||
|
||||
function _M.read_file_table( self, name )
|
||||
return self:select_rule(self:read_file('args'))
|
||||
end
|
||||
|
||||
|
||||
function _M.inc_log(self, name, rule)
|
||||
local server_name = self.params['server_name']
|
||||
local total_path = self.cpath .. 'total.json'
|
||||
local tbody = ngx.shared.limit:get(total_path)
|
||||
if not tbody then
|
||||
tbody = self:read_file_body(total_path)
|
||||
if not tbody then return false end
|
||||
end
|
||||
local total = json.decode(tbody)
|
||||
if not total['sites'] then total['sites'] = {} end
|
||||
if not total['sites'][server_name] then total['sites'][server_name] = {} end
|
||||
if not total['sites'][server_name][name] then total['sites'][server_name][name] = 0 end
|
||||
if not total['rules'] then total['rules'] = {} end
|
||||
if not total['rules'][name] then total['rules'][name] = 0 end
|
||||
if not total['total'] then total['total'] = 0 end
|
||||
total['total'] = total['total'] + 1
|
||||
total['sites'][server_name][name] = total['sites'][server_name][name] + 1
|
||||
total['rules'][name] = total['rules'][name] + 1
|
||||
local total_log = json.encode(total)
|
||||
if not total_log then return false end
|
||||
ngx.shared.limit:set(total_path,total_log)
|
||||
if not ngx.shared.limit:get('mw_waf_timeout') then
|
||||
self:write_file_clear(total_path,total_log)
|
||||
ngx.shared.limit:set('mw_waf_timeout',1,5)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
|
||||
function _M.get_server_name(self)
|
||||
local c_name = ngx.var.server_name
|
||||
local my_name = ngx.shared.limit:get(c_name)
|
||||
if my_name then return my_name end
|
||||
local tmp = self:read_file_body(self.cpath .. 'domains.json')
|
||||
if not tmp then return c_name end
|
||||
local domains = json.decode(tmp)
|
||||
for _,v in ipairs(domains)
|
||||
do
|
||||
for _,d_name in ipairs(v['domains'])
|
||||
do
|
||||
if c_name == d_name then
|
||||
ngx.shared.limit:set(c_name,v['name'],3600)
|
||||
return v['name']
|
||||
end
|
||||
end
|
||||
end
|
||||
return c_name
|
||||
end
|
||||
|
||||
|
||||
-- function _M.get_sn(self)
|
||||
-- retun string.gsub(self:get_server_name(),'_','.')
|
||||
-- end
|
||||
|
||||
|
||||
function _M.is_ngx_match(self, rules, sbody, rule_name)
|
||||
if rules == nil or sbody == nil then return false end
|
||||
if type(sbody) == "string" then
|
||||
sbody = {sbody}
|
||||
end
|
||||
|
||||
if type(rules) == "string" then
|
||||
rules = {rules}
|
||||
end
|
||||
|
||||
for k,body in pairs(sbody)
|
||||
do
|
||||
if self:continue_key(k) then
|
||||
for i,rule in ipairs(rules)
|
||||
do
|
||||
if self.site_config[server_name] and rule_name then
|
||||
local n = i - 1
|
||||
for _,j in ipairs(self.site_config[server_name]['disable_rule'][rule_name])
|
||||
do
|
||||
if n == j then
|
||||
rule = ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if body and rule ~="" then
|
||||
if type(body) == "string" then
|
||||
if ngx_match(ngx.unescape_uri(body),rule,"isjo") then
|
||||
error_rule = rule .. ' >> ' .. k .. ':' .. body
|
||||
return true
|
||||
end
|
||||
end
|
||||
if type(k) == "string" then
|
||||
if ngx_match(ngx.unescape_uri(k),rule,"isjo") then
|
||||
error_rule = rule .. ' >> ' .. k
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function _M.write_log(self, name, rule)
|
||||
local ip = self.params['ip']
|
||||
local retry = self.config['retry']['retry']
|
||||
local retry_time = self.config['retry']['retry_time']
|
||||
local retry_cycle = self.config['retry']['retry_cycle']
|
||||
|
||||
local count, _ = ngx.shared.drop_ip:get(ip)
|
||||
if count then
|
||||
ngx.shared.drop_ip:incr(ip,1)
|
||||
else
|
||||
ngx.shared.drop_ip:set(ip,1,retry_cycle)
|
||||
end
|
||||
if self.config['log'] ~= true or self:is_site_config('log') ~= true then return false end
|
||||
local method = ngx.req.get_method()
|
||||
if error_rule then
|
||||
rule = error_rule
|
||||
error_rule = nil
|
||||
end
|
||||
|
||||
local logtmp = {ngx.localtime(), ip, method, ngx.var.request_uri, ngx.var.http_user_agent, name, rule}
|
||||
local logstr = json.encode(logtmp) .. "\n"
|
||||
local count,_ = ngx.shared.drop_ip:get(ip)
|
||||
if count > retry and name ~= 'cc' then
|
||||
local safe_count,_ = ngx.shared.drop_sum:get(ip)
|
||||
if not safe_count then
|
||||
ngx.shared.drop_sum:set(ip,1,86400)
|
||||
safe_count = 1
|
||||
else
|
||||
ngx.shared.drop_sum:incr(ip,1)
|
||||
end
|
||||
local lock_time = retry_time * safe_count
|
||||
if lock_time > 86400 then lock_time = 86400 end
|
||||
logtmp = {ngx.localtime(),ip,method,ngx.var.request_uri, ngx.var.http_user_agent,name,retry_cycle .. '秒以内累计超过'..retry..'次以上非法请求,封锁'.. lock_time ..'秒'}
|
||||
logstr = logstr .. json.encode(logtmp) .. "\n"
|
||||
ngx.shared.drop_ip:set(ip,retry+1,lock_time)
|
||||
self:write_drop_ip('inc',lock_time)
|
||||
end
|
||||
self:write_to_file(logstr)
|
||||
self:inc_log(name,rule)
|
||||
end
|
||||
|
||||
|
||||
function _M.get_client_ip(self)
|
||||
local client_ip = "unknown"
|
||||
if self.site_config[server_name] then
|
||||
if self.site_config[server_name]['cdn'] then
|
||||
for _,v in ipairs(self.site_config[server_name]['cdn_header'])
|
||||
do
|
||||
if request_header[v] ~= nil and request_header[v] ~= "" then
|
||||
local header_tmp = request_header[v]
|
||||
if type(header_tmp) == "table" then header_tmp = header_tmp[1] end
|
||||
client_ip = split(header_tmp,',')[1]
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if string.match(client_ip,"%d+%.%d+%.%d+%.%d+") == nil or not self:is_ipaddr(client_ip) then
|
||||
client_ip = ngx.var.remote_addr
|
||||
if client_ip == nil then
|
||||
client_ip = "unknown"
|
||||
end
|
||||
end
|
||||
return client_ip
|
||||
end
|
||||
|
||||
|
||||
function _M.is_site_config(self,cname)
|
||||
local server_name = self.params["server_name"]
|
||||
if self.site_config[server_name] ~= nil then
|
||||
if cname == 'cc' then
|
||||
return self.site_config[server_name][cname]['open']
|
||||
else
|
||||
return self.site_config[server_name][cname]
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function _M.get_boundary(self)
|
||||
local header = self.params["request_header"]["content-type"]
|
||||
if not header then return nil end
|
||||
if type(header) == "table" then
|
||||
header = header[1]
|
||||
end
|
||||
|
||||
local m = string.match(header, ";%s*boundary=\"([^\"]+)\"")
|
||||
if m then
|
||||
return m
|
||||
end
|
||||
return string.match(header, ";%s*boundary=([^\",;]+)")
|
||||
end
|
||||
|
||||
|
||||
function _M.return_post_data(self)
|
||||
if method ~= "POST" then return false end
|
||||
content_length = tonumber(self.params["request_header"]['content-length'])
|
||||
if not content_length then return false end
|
||||
max_len = 2560 * 1024000
|
||||
if content_length > max_len then return false end
|
||||
local boundary = self:get_boundary()
|
||||
if boundary then
|
||||
ngx.req.read_body()
|
||||
local data = ngx.req.get_body_data()
|
||||
if not data then return false end
|
||||
local tmp = ngx.re.match(data,[[filename=\"(.+)\.(.*)\"]])
|
||||
if not tmp then return false end
|
||||
if not tmp[2] then return false end
|
||||
return tmp[2]
|
||||
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function _M.t(self)
|
||||
ngx.say(',,,')
|
||||
end
|
||||
|
||||
|
||||
return _M
|
||||
@@ -0,0 +1,578 @@
|
||||
|
||||
local cpath = "/Users/midoks/Desktop/fwww/server/openresty/nginx/conf/waf/"
|
||||
local rpath = "/Users/midoks/Desktop/fwww/server/openresty/nginx/conf/waf/rule/"
|
||||
local logdir = "/Users/midoks/Desktop/fwww/wwwlogs/waf/"
|
||||
local json = require "cjson"
|
||||
local ngx_match = ngx.re.find
|
||||
|
||||
local _C = require "common"
|
||||
local C = _C:new(cpath, rpath, logdir)
|
||||
|
||||
config = C:read_file_body_decode(cpath .. 'config.json')
|
||||
local site_config = C:read_file_body_decode(cpath .. 'site.json')
|
||||
C:setConfData(config, site_config)
|
||||
|
||||
function initParams()
|
||||
local data = {}
|
||||
data['ip'] = C:get_client_ip()
|
||||
data['ipn'] = C:arrip(data['ip'])
|
||||
data['request_header'] = ngx.req.get_headers()
|
||||
data['uri'] = ngx.unescape_uri(ngx.var.uri)
|
||||
data['server_name'] = string.gsub(C:get_server_name(),'_','.')
|
||||
data['uri_request_args'] = ngx.req.get_uri_args()
|
||||
data['method'] = ngx.req.get_method()
|
||||
data['request_uri'] = ngx.var.request_uri
|
||||
return data
|
||||
end
|
||||
|
||||
local params = initParams()
|
||||
C:setParams(params)
|
||||
|
||||
|
||||
|
||||
function get_return_state(rstate,rmsg)
|
||||
result = {}
|
||||
result['status'] = rstate
|
||||
result['msg'] = rmsg
|
||||
return result
|
||||
end
|
||||
|
||||
function get_waf_drop_ip()
|
||||
local data = ngx.shared.drop_ip:get_keys(0)
|
||||
return data
|
||||
end
|
||||
|
||||
|
||||
function is_chekc_table(data,strings)
|
||||
if type(data) ~= 'table' then return 1 end
|
||||
if not data then return 1 end
|
||||
data=chekc_ip_timeout(data)
|
||||
for k,v in pairs(data)
|
||||
do
|
||||
if strings ==v['ip'] then
|
||||
return 3
|
||||
end
|
||||
end
|
||||
return 2
|
||||
end
|
||||
|
||||
function save_ip_on(data)
|
||||
locak_file=read_file_body(cpath2 .. 'stop_ip.lock')
|
||||
if not locak_file then
|
||||
C:write_file(cpath2 .. 'stop_ip.lock','1')
|
||||
end
|
||||
name='stop_ip'
|
||||
local extime=18000
|
||||
data=json.encode(data)
|
||||
ngx.shared.btwaf:set(cpath2 .. name,data,extime)
|
||||
if not ngx.shared.btwaf:get(cpath2 .. name .. '_lock') then
|
||||
ngx.shared.btwaf:set(cpath2 .. name .. '_lock',1,0.5)
|
||||
C:write_file(cpath2 .. name .. '.json',data)
|
||||
end
|
||||
end
|
||||
|
||||
function remove_btwaf_drop_ip()
|
||||
if not uri_request_args['ip'] or not C:is_ipaddr(uri_request_args['ip']) then return get_return_state(true,'格式错误') end
|
||||
if ngx.shared.btwaf:get(cpath2 .. 'stop_ip') then
|
||||
ret=ngx.shared.btwaf:get(cpath2 .. 'stop_ip')
|
||||
ip_data=json.decode(ret)
|
||||
result=is_chekc_table(ip_data,uri_request_args['ip'])
|
||||
os.execute("sleep " .. 0.6)
|
||||
ret2=ngx.shared.btwaf:get(cpath2 .. 'stop_ip')
|
||||
ip_data2=json.decode(ret2)
|
||||
if result == 3 then
|
||||
for k,v in pairs(ip_data2)
|
||||
do
|
||||
if uri_request_args['ip'] == v['ip'] then
|
||||
v['time']=0
|
||||
end
|
||||
end
|
||||
end
|
||||
save_ip_on(ip_data2)
|
||||
end
|
||||
ngx.shared.drop_ip:delete(uri_request_args['ip'])
|
||||
return get_return_state(true,uri_request_args['ip'] .. '已解封')
|
||||
end
|
||||
|
||||
function clean_btwaf_drop_ip()
|
||||
if ngx.shared.btwaf:get(cpath2 .. 'stop_ip') then
|
||||
ret2=ngx.shared.btwaf:get(cpath2 .. 'stop_ip')
|
||||
ip_data2=json.decode(ret2)
|
||||
for k,v in pairs(ip_data2)
|
||||
do
|
||||
v['time']=0
|
||||
end
|
||||
save_ip_on(ip_data2)
|
||||
os.execute("sleep " .. 2)
|
||||
end
|
||||
local data = get_btwaf_drop_ip()
|
||||
for _,value in ipairs(data)
|
||||
do
|
||||
ngx.shared.drop_ip:delete(value)
|
||||
end
|
||||
return get_return_state(true,'已解封所有封锁IP')
|
||||
end
|
||||
|
||||
function min_route()
|
||||
if ngx.var.remote_addr ~= '127.0.0.1' then return false end
|
||||
if uri == '/get_waf_drop_ip' then
|
||||
return_message(200,get_waf_drop_ip())
|
||||
elseif uri == '/remove_waf_drop_ip' then
|
||||
return_message(200,remove_waf_drop_ip())
|
||||
elseif uri == '/clean_waf_drop_ip' then
|
||||
return_message(200,clean_waf_drop_ip())
|
||||
end
|
||||
end
|
||||
|
||||
local get_html = C:read_file_body(config["reqfile_path"] .. '/' .. config["get"]["reqfile"])
|
||||
local post_html = C:read_file_body(config["reqfile_path"] .. '/' .. config["post"]["reqfile"])
|
||||
local user_agent_html = C:read_file_body(config["reqfile_path"] .. '/' .. config["user-agent"]["reqfile"])
|
||||
local args_rules = C:read_file_table('args')
|
||||
local ip_white_rules = C:read_file('ip_white')
|
||||
local ip_black_rules = C:read_file('ip_black')
|
||||
local scan_black_rules = C:read_file('scan_black')
|
||||
|
||||
function waf_args()
|
||||
if not config['get']['open'] or not C:is_site_config('get') then return false end
|
||||
if C:is_ngx_match(args_rules, params['uri_request_args'],'args') then
|
||||
C:write_log('args','regular')
|
||||
C:return_html(config['get']['status'], get_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function waf_ip_white()
|
||||
for _,rule in ipairs(ip_white_rules)
|
||||
do
|
||||
if C:compare_ip(rule) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function waf_ip_black()
|
||||
for _,rule in ipairs(ip_black_rules)
|
||||
do
|
||||
if C:compare_ip(rule) then
|
||||
ngx.exit(config['cc']['status'])
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function waf_drop()
|
||||
local count,_ = ngx.shared.drop_ip:get(ip)
|
||||
if not count then return false end
|
||||
if count > config['retry'] then
|
||||
ngx.exit(config['cc']['status'])
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function waf_user_agent()
|
||||
if not config['user-agent']['open'] or not C:is_site_config('user-agent') then return false end
|
||||
if C:is_ngx_match(user_agent_rules,params['request_header']['user-agent'],'user_agent') then
|
||||
C:write_log('user_agent','regular')
|
||||
C:return_html(config['user-agent']['status'],user_agent_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- function cc()
|
||||
-- local ip = params['ip']
|
||||
-- local request_uri = params['request_uri']
|
||||
-- local endtime = config['cc']['endtime']
|
||||
|
||||
-- if not config['cc']['open'] or not site_cc then return false end
|
||||
-- local token = ngx.md5(ip .. '_' .. request_uri)
|
||||
-- local count,_ = ngx.shared.limit:get(token)
|
||||
-- if count then
|
||||
-- if count > limit then
|
||||
-- local safe_count,_ = ngx.shared.drop_sum:get(ip)
|
||||
-- if not safe_count then
|
||||
-- ngx.shared.drop_sum:set(ip,1,86400)
|
||||
-- safe_count = 1
|
||||
-- else
|
||||
-- ngx.shared.drop_sum:incr(ip,1)
|
||||
-- end
|
||||
-- local lock_time = (endtime * safe_count)
|
||||
-- if lock_time > 86400 then lock_time = 86400 end
|
||||
-- ngx.shared.drop_ip:set(ip,retry+1,lock_time)
|
||||
-- C:write_log('cc',cycle..'秒内累计超过'..limit..'次请求,封锁' .. lock_time .. '秒')
|
||||
-- C:write_drop_ip('cc',lock_time)
|
||||
-- if not server_name then
|
||||
-- insert_ip_list(ip,lock_time,os.time(),'1111')
|
||||
-- else
|
||||
-- insert_ip_list(ip,lock_time,os.time(),server_name)
|
||||
-- end
|
||||
|
||||
-- ngx.exit(config['cc']['status'])
|
||||
-- return true
|
||||
-- else
|
||||
-- ngx.shared.limit:incr(token,1)
|
||||
-- end
|
||||
-- else
|
||||
-- ngx.shared.limit:set(token,1,cycle)
|
||||
-- end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
--强制验证是否使用正常浏览器访问网站
|
||||
function waf_cc_increase()
|
||||
|
||||
if not config['cc']['open'] or not site_cc then return false end
|
||||
if not site_config[server_name] then return false end
|
||||
if not site_config[server_name]['cc']['increase'] then return false end
|
||||
local cache_token = ngx.md5(ip .. '_' .. server_name)
|
||||
--判断是否已经通过验证
|
||||
if ngx.shared.btwaf:get(cache_token) then return false end
|
||||
if cc_uri_white() then
|
||||
ngx.shared.btwaf:delete(cache_token .. '_key')
|
||||
ngx.shared.btwaf:set(cache_token,1,60)
|
||||
return false
|
||||
end
|
||||
if security_verification() then return false end
|
||||
send_check_heml(cache_token)
|
||||
end
|
||||
|
||||
|
||||
function waf_url()
|
||||
if not config['get']['open'] or not C:is_site_config('get') then return false end
|
||||
--正则--
|
||||
if C:is_ngx_match(url_rules,params["uri"],'url') then
|
||||
C:write_log('url','regular')
|
||||
C:return_html(config['get']['status'],get_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function waf_scan_black()
|
||||
if not config['scan']['open'] or not C:is_site_config('scan') then return false end
|
||||
if C:is_ngx_match(scan_black_rules['cookie'],params["request_header"]["cookie"],false) then
|
||||
C:write_log('scan','regular')
|
||||
ngx.exit(config['scan']['status'])
|
||||
return true
|
||||
end
|
||||
if C:is_ngx_match(scan_black_rules['args'],params["request_uri"],false) then
|
||||
C:write_log('scan','regular')
|
||||
ngx.exit(config['scan']['status'])
|
||||
return true
|
||||
end
|
||||
for key,value in pairs(params["request_header"])
|
||||
do
|
||||
if C:is_ngx_match(scan_black_rules['header'], key, false) then
|
||||
C:write_log('scan','regular')
|
||||
ngx.exit(config['scan']['status'])
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function waf_post_referer()
|
||||
if params['method'] ~= "POST" then return false end
|
||||
if C:is_ngx_match(referer_local, params['request_header']['Referer'],'post') then
|
||||
C:write_log('post_referer','regular')
|
||||
C:return_html(config['post']['status'],post_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function waf_post()
|
||||
if not config['post']['open'] or not C:is_site_config('post') then return false end
|
||||
if params['method'] ~= "POST" then return false end
|
||||
if waf_post_referer() then return true end
|
||||
content_length = tonumber(params["request_header"]['content-length'])
|
||||
max_len = 640 * 1020000
|
||||
if content_length > max_len then return false end
|
||||
if C:get_boundary() then return false end
|
||||
ngx.req.read_body()
|
||||
request_args = ngx.req.get_post_args()
|
||||
if not request_args then
|
||||
return false
|
||||
end
|
||||
|
||||
if C:is_ngx_match(post_rules,request_args,'post') then
|
||||
C:write_log('post','regular')
|
||||
C:return_html(config['post']['status'],post_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function post_data_chekc()
|
||||
if params['method'] =="POST" then
|
||||
if C:return_post_data() then return false end
|
||||
request_args = ngx.req.get_post_args()
|
||||
if not request_args then return false end
|
||||
if not request_header['Content-Type'] then return false end
|
||||
av=string.match(request_header['Content-Type'],"=.+")
|
||||
if not av then return false end
|
||||
ac=split(av,'=')
|
||||
if not ac then return false end
|
||||
list_list=nil
|
||||
for i,v in ipairs(ac)
|
||||
do
|
||||
list_list='--'..v
|
||||
end
|
||||
if not list_list then return false end
|
||||
aaa=nil
|
||||
for k,v in pairs(request_args)
|
||||
do
|
||||
aaa=v
|
||||
end
|
||||
if not aaa then return false end
|
||||
if tostring(aaa) == 'true' then return false end
|
||||
if type(aaa) ~= "string" then return false end
|
||||
data_len=split(aaa,list_list)
|
||||
--return return_message(200,data_len)
|
||||
if not data_len then return false end
|
||||
if arrlen(data_len) ==0 then return false end
|
||||
|
||||
if C:is_ngx_match(post_rules,data_len,'post') then
|
||||
C:write_log('post','regular')
|
||||
C:return_html(config['post']['status'],post_html)
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function X_Forwarded()
|
||||
if params['method'] ~= "GET" then return false end
|
||||
if not config['get']['open'] or not C:is_site_config('get') then return false end
|
||||
if C:is_ngx_match(args_rules,params["request_header"]['X-forwarded-For'],'args') then
|
||||
C:write_log('args','regular')
|
||||
C:return_html(config['get']['status'],get_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function post_X_Forwarded()
|
||||
if not config['post']['open'] or not C:is_site_config('post') then return false end
|
||||
if params['method'] ~= "POST" then return false end
|
||||
if C:is_ngx_match(post_rules,params["request_header"]['X-forwarded-For'],'post') then
|
||||
C:write_log('post','regular')
|
||||
C:return_html(config['post']['status'],post_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function php_path()
|
||||
if site_config[server_name] == nil then return false end
|
||||
for _,rule in ipairs(site_config[server_name]['disable_php_path'])
|
||||
do
|
||||
if ngx_match(uri,rule .. "/?.*\\.php$","isjo") then
|
||||
C:write_log('php_path','regular')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return C:return_message(200,uri)
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function url_path()
|
||||
if site_config[server_name] == nil then return false end
|
||||
for _,rule in ipairs(site_config[server_name]['disable_path'])
|
||||
do
|
||||
if ngx_match(uri,rule,"isjo") then
|
||||
C:write_log('path','regular')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function url_ext()
|
||||
if site_config[server_name] == nil then return false end
|
||||
for _,rule in ipairs(site_config[server_name]['disable_ext'])
|
||||
do
|
||||
if ngx_match(uri,"\\."..rule.."$","isjo") then
|
||||
C:write_log('url_ext','regular')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function url_rule_ex()
|
||||
if site_config[server_name] == nil then return false end
|
||||
if method == "POST" and not request_args then
|
||||
content_length=tonumber(request_header['content-length'])
|
||||
max_len = 640 * 102400000
|
||||
request_args = nil
|
||||
if content_length < max_len then
|
||||
ngx.req.read_body()
|
||||
request_args = ngx.req.get_post_args()
|
||||
end
|
||||
end
|
||||
for _,rule in ipairs(site_config[server_name]['url_rule'])
|
||||
do
|
||||
if ngx_match(uri,rule[1],"isjo") then
|
||||
if C:is_ngx_match(rule[2],uri_request_args,false) then
|
||||
C:write_log('url_rule','regular')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
end
|
||||
|
||||
if params['method'] == "POST" and request_args ~= nil then
|
||||
if C:is_ngx_match(rule[2],request_args,'post') then
|
||||
C:write_log('post','regular')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function url_tell()
|
||||
if site_config[server_name] == nil then return false end
|
||||
for _,rule in ipairs(site_config[server_name]['url_tell'])
|
||||
do
|
||||
if ngx_match(uri,rule[1],"isjo") then
|
||||
if uri_request_args[rule[2]] ~= rule[3] then
|
||||
C:write_log('url_tell','regular')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
function disable_upload_ext(ext)
|
||||
if not ext then return false end
|
||||
ext = string.lower(ext)
|
||||
if is_key(site_config[server_name]['disable_upload_ext'],ext) then
|
||||
C:write_log('upload_ext','上传扩展名黑名单')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function data_in_php(data)
|
||||
if not data then
|
||||
return false
|
||||
else
|
||||
if C:is_ngx_match('php',data,'post') then
|
||||
C:write_log('upload_ext','上传扩展名黑名单')
|
||||
C:return_html(config['other']['status'],other_html)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function post_data()
|
||||
if params["method"] ~= "POST" then return false end
|
||||
content_length = tonumber(params["request_header"]['content-length'])
|
||||
if not content_length then return false end
|
||||
max_len = 2560 * 1024000
|
||||
if content_length > max_len then return false end
|
||||
local boundary = C:get_boundary()
|
||||
if boundary then
|
||||
ngx.req.read_body()
|
||||
local data = ngx.req.get_body_data()
|
||||
if not data then return false end
|
||||
local tmp = ngx.re.match(data,[[filename=\"(.+)\.(.*)\"]])
|
||||
if not tmp then return false end
|
||||
if not tmp[2] then return false end
|
||||
local tmp2=ngx.re.match(ngx.req.get_body_data(),[[Content-Type:[^\+]{45}]])
|
||||
--return return_message(200,tmp2[0])
|
||||
disable_upload_ext(tmp[2])
|
||||
if tmp2 == nil then return false end
|
||||
data_in_php(tmp2[0])
|
||||
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function waf_cookie()
|
||||
if not config['cookie']['open'] or not C:is_site_config('cookie') then return false end
|
||||
if not params["request_header"]['cookie'] then return false end
|
||||
if type(params["request_header"]['cookie']) ~= "string" then return false end
|
||||
request_cookie = string.lower(params["request_header"]['cookie'])
|
||||
if C:is_ngx_match(cookie_rules,request_cookie,'cookie') then
|
||||
C:write_log('cookie','regular')
|
||||
C:return_html(config['cookie']['status'],cookie_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function waf_referer()
|
||||
if params["method"] ~= "GET" then return false end
|
||||
if not config['get']['open'] or not C:is_site_config('get') then return false end
|
||||
if C:is_ngx_match(referer_local,params["request_header"]['Referer'],'args') then
|
||||
C:write_log('get_referer','regular')
|
||||
C:return_html(config['get']['status'], get_html)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function waf()
|
||||
min_route()
|
||||
|
||||
if waf_ip_white() then return true end
|
||||
waf_ip_black()
|
||||
|
||||
|
||||
waf_drop()
|
||||
waf_user_agent()
|
||||
|
||||
waf_url()
|
||||
|
||||
if params["method"] == "GET" then
|
||||
waf_referer()
|
||||
waf_cookie()
|
||||
end
|
||||
|
||||
if params["method"] == "POST" then
|
||||
waf_referer()
|
||||
waf_cookie()
|
||||
end
|
||||
|
||||
waf_args()
|
||||
waf_scan_black()
|
||||
|
||||
waf_post()
|
||||
post_data_chekc()
|
||||
|
||||
local server_name = params["server_name"]
|
||||
if site_config[server_name] then
|
||||
X_Forwarded()
|
||||
post_X_Forwarded()
|
||||
php_path()
|
||||
url_path()
|
||||
url_ext()
|
||||
url_rule_ex()
|
||||
url_tell()
|
||||
post_data()
|
||||
end
|
||||
end
|
||||
|
||||
waf()
|
||||
@@ -0,0 +1 @@
|
||||
waf()
|
||||
@@ -0,0 +1 @@
|
||||
[[1, "\\.\\./\\.\\./", "\u76ee\u5f55\u4fdd\u62a41", 0], [1, "/\\*", "\u76ee\u5f55\u4fdd\u62a42", 0], [1, "(?:etc\\/\\W*passwd)", "\u76ee\u5f55\u4fdd\u62a43", 0], [1, "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/", "PHP\u6d41\u534f\u8bae\u8fc7\u6ee41", 0], [1, "\\:\\$", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee41", 0], [1, "\\$\\{", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee42", 0], [1, "base64_decode\\(", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee43", 0], [1, "(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|char|chr|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\\(", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee44", 0], [1, "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\[", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee45", 0], [1, "\\s+(or|xor|and)\\s+.*(=|<|>|'|\")", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0], [1, "select.+(from|limit)", "SQL\u6ce8\u5165\u8fc7\u6ee42", 0], [1, "(?:(union(.*?)select))", "SQL\u6ce8\u5165\u8fc7\u6ee43", 0], [1, "sleep\\((\\s*)(\\d*)(\\s*)\\)", "SQL\u6ce8\u5165\u8fc7\u6ee45", 0], [1, "benchmark\\((.*)\\,(.*)\\)", "SQL\u6ce8\u5165\u8fc7\u6ee46", 0], [1, "(?:from\\W+information_schema\\W)", "SQL\u6ce8\u5165\u8fc7\u6ee47", 0], [1, "(?:(?:current_)user|database|schema|connection_id)\\s*\\(", "SQL\u6ce8\u5165\u8fc7\u6ee48", 0], [1, "into(\\s+)+(?:dump|out)file\\s*", "SQL\u6ce8\u5165\u8fc7\u6ee49", 0], [1, "group\\s+by.+\\(", "SQL\u6ce8\u5165\u8fc7\u6ee410", 0], [1, "\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)", "XSS\u8fc7\u6ee41", 0], [0, "(onmouseover|onerror|onload)\\=", "XSS\u8fc7\u6ee42", 0], [1, "(invokefunction|call_user_func_array|\\\\think\\\\)", "ThinkPHP payload\u5c01\u5835", 0], [1, "^url_array\\[.*\\]$", "Metinfo6.x XSS\u6f0f\u6d1e", 0], [1, "(extractvalue\\(|concat\\(0x|user\\(\\)|substring\\(|count\\(\\*\\)|substring\\(hex\\(|updatexml\\()", "SQL\u62a5\u9519\u6ce8\u5165\u8fc7\u6ee401", 0], [1, "(@@version|load_file\\(|NAME_CONST\\(|exp\\(\\~|floor\\(rand\\(|geometrycollection\\(|multipoint\\(|polygon\\(|multipolygon\\(|linestring\\(|multilinestring\\()", "SQL\u62a5\u9519\u6ce8\u5165\u8fc7\u6ee402", 0], [1, "(substr\\()", "SQL\u6ce8\u5165\u8fc7\u6ee410", 0], [1, "\\|+\\s+[\\w\\W]+=[\\w\\W]+", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[1, "\\.\\./\\.\\./", "\u76ee\u5f55\u4fdd\u62a41", 0], [1, "(?:etc\\/\\W*passwd)", "\u76ee\u5f55\u4fdd\u62a43", 0], [1, "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/", "PHP\u6d41\u534f\u8bae\u8fc7\u6ee41", 0], [1, "\\:\\$", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee41", 0], [1, "\\$\\{", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee42", 0], [1, "base64_decode\\(", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee43", 0], [1, "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)\\[", "\u4e00\u53e5\u8bdd\u6728\u9a6c\u8fc7\u6ee45", 0], [1, "\\b(or|xor|and)\\b.*(=|<|>|'|\")", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0], [1, "select.+(from|limit)", "SQL\u6ce8\u5165\u8fc7\u6ee42", 0], [1, "(?:(union(.*?)select))", "SQL\u6ce8\u5165\u8fc7\u6ee43", 0], [0, "having|load_file", "SQL\u6ce8\u5165\u8fc7\u6ee44", 0], [1, "sleep\\((\\s*)(\\d*)(\\s*)\\)", "SQL\u6ce8\u5165\u8fc7\u6ee45", 0], [1, "benchmark\\((.*)\\,(.*)\\)", "SQL\u6ce8\u5165\u8fc7\u6ee46", 0], [1, "(?:from\\W+information_schema\\W)", "SQL\u6ce8\u5165\u8fc7\u6ee47", 0], [1, "(?:(?:current_)user|database|schema|connection_id)\\s*\\(", "SQL\u6ce8\u5165\u8fc7\u6ee48", 0], [1, "into(\\s+)+(?:dump|out)file\\s*", "SQL\u6ce8\u5165\u8fc7\u6ee49", 0], [1, "group\\s+by.+\\(", "SQL\u6ce8\u5165\u8fc7\u6ee410", 0], [0, "\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)", "XSS\u8fc7\u6ee41", 0], [1, "(onmouseover|onerror|onload)\\=", "XSS\u8fc7\u6ee42", 0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[[94, 130, 9, 116], [94, 130, 9, 116]]]
|
||||
@@ -0,0 +1 @@
|
||||
[[[127, 0, 0, 2], [127, 0, 0, 255]]]
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
[[1, "(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\\:\\/", "PHP\u6d41\u534f\u8bae\u8fc7\u6ee41", 0], [1, "base64_decode\\(", "\u4e00\u53e5\u8bdd*\u5c4f\u853d\u7684\u5173\u952e\u5b57*\u8fc7\u6ee41", 0], [1, "(?:define|eval|file_get_contents|include|require_once|shell_exec|phpinfo|system|passthru|chr|char|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog|file_put_contents|fopen|urldecode|scandir)\\(", "\u4e00\u53e5\u8bdd*\u5c4f\u853d\u7684\u5173\u952e\u5b57*\u8fc7\u6ee42", 0], [1, "\\$_(GET|post|cookie|files|session|env|phplib|GLOBALS|SERVER)", "\u4e00\u53e5\u8bdd*\u5c4f\u853d\u7684\u5173\u952e\u5b57*\u8fc7\u6ee43", 0], [1, "\\s+(or|xor|and)\\s+(=|<|>|'|\")", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0], [1, "select\\s+.+(from|limit)\\s+", "SQL\u6ce8\u5165\u8fc7\u6ee42", 0], [1, "(?:(union(.*?)select))", "SQL\u6ce8\u5165\u8fc7\u6ee43", 0], [1, "sleep\\((\\s*)(\\d*)(\\s*)\\)", "SQL\u6ce8\u5165\u8fc7\u6ee45", 0], [1, "benchmark\\((.*)\\,(.*)\\)", "SQL\u6ce8\u5165\u8fc7\u6ee46", 0], [1, "(?:from\\W+information_schema\\W)", "SQL\u6ce8\u5165\u8fc7\u6ee47", 0], [1, "(?:(?:current_)user|database|schema|connection_id)\\s*\\(", "SQL\u6ce8\u5165\u8fc7\u6ee48", 0], [1, "into(\\s+)+(?:dump|out)file\\s*", "SQL\u6ce8\u5165\u8fc7\u6ee49", 0], [1, "group\\s+by.+\\(", "SQL\u6ce8\u5165\u8fc7\u6ee410", 0], [0, "\\<(iframe|script|body|img|layer|div|meta|style|base|object|input)", "XSS\u8fc7\u6ee41", 0], [0, "(onmouseover|onerror|onload)\\=", "XSS\u8fc7\u6ee42", 0], [1, "(extractvalue\\(|concat\\(0x|user\\(\\)|substring\\(|count\\(\\*\\)|substring\\(hex\\(|updatexml\\()", "SQL\u62a5\u9519\u6ce8\u5165\u8fc7\u6ee401", 0], [1, "(@@version|load_file\\(|NAME_CONST\\(|exp\\(\\~|floor\\(rand\\(|geometrycollection\\(|multipoint\\(|polygon\\(|multipolygon\\(|linestring\\(|multilinestring\\()", "SQL\u62a5\u9519\u6ce8\u5165\u8fc7\u6ee402", 0], [1, "(substr\\()", "SQL\u6ce8\u5165\u8fc7\u6ee410", 0], [1, "(ORD\\(|MID\\(|IFNULL\\(|CAST\\(|CHAR\\))", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0], [1, "(EXISTS\\(|SELECT\\#|\\(SELECT)", "SQL\u6ce8\u5165\u8fc7\u6ee41", 0], [1, "(array_map\\(\"ass)", "\u83dc\u5200\u6d41\u91cf\u8fc7\u6ee4", 0], [1, "(?:define|eval|file_get_contents|include|require_once|shell_exec|phpinfo|system|passthru|chr|char|preg_\\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog|file_put_contents|fopen|urldecode)\\(", "\u4e00\u53e5\u8bdd*\u5c4f\u853d\u7684\u5173\u952e\u5b57*\u8fc7\u6ee42", 0]]
|
||||
@@ -0,0 +1 @@
|
||||
{"header": "(Acunetix-Aspect|Acunetix-Aspect-Password|Acunetix-Aspect-Queries|X-WIPP|X-RequestManager-Memo|X-Request-Memo|X-Scan-Memo)", "args": "(/acunetix-wvs-test-for-some-inexistent-file|netsparker|acunetix_wvs_security_test|AppScan|XSS@HERE)", "cookie": "(CustomCookie|acunetixCookie)"}
|
||||