Compare commits
1428 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bdde68ece | |||
| 50f92f55e2 | |||
| 370db62bf0 | |||
| 65f34f1d31 | |||
| 00a3908abb | |||
| 32034d590a | |||
| 3635fb3910 | |||
| d2ecfe5491 | |||
| 1f759dce5b | |||
| ae41c6038b | |||
| f41f7eb2ad | |||
| d04f383161 | |||
| cb989d7489 | |||
| b5cba19d26 | |||
| b7271d7a46 | |||
| 521083a309 | |||
| 6d35325601 | |||
| 3c65f37d84 | |||
| d75dd058d6 | |||
| 40475e02ec | |||
| f6ea9c1300 | |||
| 902359f24e | |||
| bb4d5f1e93 | |||
| 1dec3f000e | |||
| 6d89814795 | |||
| f339bc9f7f | |||
| bb80bc0c07 | |||
| 96677ff8bf | |||
| c7b6a6df79 | |||
| 8bb7e8bfb2 | |||
| 02ab343e22 | |||
| 4d875a18de | |||
| cff2336923 | |||
| 0e96bfdfa3 | |||
| a24ef48ad1 | |||
| fe9c4f3391 | |||
| 6cbb0739f8 | |||
| 79ebabfcfb | |||
| 0c8e3262fe | |||
| c24a040c19 | |||
| 4f39cb8dfa | |||
| cdd2816642 | |||
| 27b6dfa4d2 | |||
| 204cbd0209 | |||
| b7980aad5a | |||
| e175729e2c | |||
| c26ad4c807 | |||
| 4372adc703 | |||
| 8a0c2b9b13 | |||
| 4443a1c030 | |||
| 39a02235cf | |||
| db89561480 | |||
| a4cbb11693 | |||
| 1ceeacc526 | |||
| b59052cc43 | |||
| 44019e1042 | |||
| fd0e1da4a2 | |||
| f6c67b475a | |||
| ea18a5ad15 | |||
| 4d0cd3f497 | |||
| 7dbdeaebe0 | |||
| 2085bcceb6 | |||
| c09c962cb6 | |||
| 9108459ae4 | |||
| 992bac0b1f | |||
| ebd6917a1d | |||
| 3e079e3b80 | |||
| 2ca20be197 | |||
| 17f23f3751 | |||
| 8e3d699856 | |||
| f1a168fa53 | |||
| 3575113655 | |||
| 9feb9d04b3 | |||
| 5419b1439a | |||
| e4489343fe | |||
| d9f4a5793d | |||
| 70fcdc9ebb | |||
| 78e7a81638 | |||
| 58e82d5dbd | |||
| 06d15be43a | |||
| e1e7011853 | |||
| eff7645035 | |||
| eb75e52278 | |||
| 15e6148272 | |||
| ccd448a675 | |||
| db54c019ad | |||
| b762b4d72c | |||
| 2f8faa839d | |||
| 831c325c63 | |||
| f4f73078c5 | |||
| f7d43ad5af | |||
| a77c777980 | |||
| a34db7449e | |||
| 0283bd2f97 | |||
| a8de2f8ae7 | |||
| d5dee75df3 | |||
| 79cb5c0631 | |||
| 7d9901540f | |||
| e979e9c9fb | |||
| de719df6fe | |||
| 38d7f91ea0 | |||
| a20a429e8c | |||
| 9b63fb4ee2 | |||
| 099efdbc1d | |||
| af9120fc7a | |||
| 798a48aa96 | |||
| 462e22a3b0 | |||
| 4e432ed03f | |||
| dfa74a69f7 | |||
| 9e1e4eeec2 | |||
| 221e068bac | |||
| 1bdceeecf4 | |||
| a6824d9cd0 | |||
| fe03f9942b | |||
| 4c196922fb | |||
| 2a9a513d85 | |||
| 2bcea27ecd | |||
| fb7341f1f7 | |||
| f327daa12d | |||
| 2872b9fbf9 | |||
| cedd5c9c96 | |||
| 60e6aa9b54 | |||
| 541f482518 | |||
| 4019b7939a | |||
| 013b9c4c7c | |||
| 79addfda42 | |||
| 8546bda471 | |||
| 0770f174a1 | |||
| 5f4a89cecc | |||
| cbe0b1c5a6 | |||
| 0af193c505 | |||
| fdcfcc77a0 | |||
| 06d166d0d7 | |||
| b1b3e39fcd | |||
| 5ec025a3b9 | |||
| 58b7fbcf75 | |||
| be053d47e4 | |||
| fae1981161 | |||
| fd95549de9 | |||
| ff10bc05ec | |||
| eb8cd53de2 | |||
| 3fc863561a | |||
| 131cd94495 | |||
| f3a90a63b6 | |||
| 2494173aec | |||
| 866eb6241b | |||
| 86b3df1941 | |||
| e87f6d56f5 | |||
| acc890730f | |||
| b0707739fd | |||
| 251dd1fe45 | |||
| b9f3dc65e0 | |||
| 238ad7ce51 | |||
| 99fd5fca4d | |||
| 8eda77b76d | |||
| 81ac240ac8 | |||
| 6109798fab | |||
| 95715a007d | |||
| b33ec201ac | |||
| b53fbaf5b3 | |||
| 1e03a2e553 | |||
| fda7c6f67a | |||
| fabb7982ff | |||
| cbf206be60 | |||
| aa0c282205 | |||
| 9759365329 | |||
| e3738f6422 | |||
| 9746d169f9 | |||
| 2e6d03ff00 | |||
| f7b7d3d65e | |||
| 4037cf11aa | |||
| 02aeb321ce | |||
| 0012619257 | |||
| 6f3ade0d94 | |||
| cf572f328a | |||
| d1ce36038c | |||
| b382351c7b | |||
| 4e5e862f58 | |||
| ab84835362 | |||
| 41ce8489dc | |||
| ef3faf5832 | |||
| edf089ec9e | |||
| 0ae9a3605c | |||
| 7f9c4e52ac | |||
| 35947f96a8 | |||
| b0f91f1eea | |||
| 13dfca1749 | |||
| 9d9cd8a362 | |||
| 5e5c41fda5 | |||
| 3ebdc52b3e | |||
| af54f48cec | |||
| 8656059151 | |||
| a6d38f2458 | |||
| 085bdf5cfa | |||
| 6883bcacee | |||
| 2ecc6e0368 | |||
| 8fb5ca2fe1 | |||
| e40345095f | |||
| ffc0c7bb7b | |||
| 58fadc8928 | |||
| d96a607c04 | |||
| 2ea2c8c05f | |||
| b15f514018 | |||
| 05a33a0ec9 | |||
| 747d266742 | |||
| 522d30545b | |||
| 6135a44a8d | |||
| 7c7d646792 | |||
| 4a36fd2ec3 | |||
| b1bcc287cb | |||
| 6f5868a9d7 | |||
| 75863441f4 | |||
| 9763cb00e5 | |||
| 521599ef39 | |||
| 1921a64f4b | |||
| 6b73f5d555 | |||
| e0408f30ba | |||
| dca44fa093 | |||
| bbacb76581 | |||
| 1da8617a53 | |||
| e5967f7e9d | |||
| 65d84f9e9d | |||
| 93e9498b41 | |||
| 95332d5db9 | |||
| 9864792bbf | |||
| ca9d1eed7a | |||
| 38e867c917 | |||
| 1ff6daaa27 | |||
| 3ee1dbb8a5 | |||
| b4571d5c98 | |||
| 29d49d72f9 | |||
| 81de0fc7e4 | |||
| 9d5d266d2a | |||
| b97935299f | |||
| 32a7ea1c16 | |||
| 9fd95e6a1e | |||
| 61ba83c775 | |||
| 6369fed5fc | |||
| 42f4d1477d | |||
| 609ac9c9a2 | |||
| 79f2367472 | |||
| dfc9362084 | |||
| 487b469603 | |||
| 19e1df1e5d | |||
| fc55010888 | |||
| 56a36aa595 | |||
| 0b3158fdd5 | |||
| 896cd950e9 | |||
| af5e1b805f | |||
| 3f9943270c | |||
| 902d246d1a | |||
| 785bee2b39 | |||
| 4b335db31c | |||
| 4bef527ebb | |||
| 8273031d7e | |||
| dbf69bcd98 | |||
| 24d3096752 | |||
| 9a3754fbf8 | |||
| c2a95a13fe | |||
| b46466ac96 | |||
| 06991ddb17 | |||
| 4b3f4a868a | |||
| 014eff3534 | |||
| c01b7ddb59 | |||
| 0ff700849f | |||
| 5c695dea20 | |||
| c7ee4ca4db | |||
| c3da026b33 | |||
| 98da4e1791 | |||
| 8626b6d9f2 | |||
| 80c5331a5d | |||
| 39dc5c8160 | |||
| f3002e4fb6 | |||
| c451823c2b | |||
| b37cffd704 | |||
| 2af91dbf2a | |||
| f2551318fc | |||
| 22eb84f944 | |||
| 1ece0915f1 | |||
| 87853a2015 | |||
| 46a1b74799 | |||
| 0f6e7e5eab | |||
| 5dfa9615d2 | |||
| 1bde777bee | |||
| fa4f5df3e7 | |||
| 8a3c3810e0 | |||
| 144532530a | |||
| 0f1129e19b | |||
| 1f74580f15 | |||
| f93ba9970c | |||
| f87a3d0892 | |||
| c661ad67d0 | |||
| ce4dc9e3fa | |||
| 3d2c6e6032 | |||
| 6000a0cfe3 | |||
| b80c60997a | |||
| 35e45f0df1 | |||
| e65f5b9f78 | |||
| 5969f71e67 | |||
| b1307863eb | |||
| 9d0abe993b | |||
| c53bb7cf67 | |||
| 0cea26c628 | |||
| 610c919c72 | |||
| 2c35f94f7c | |||
| cd9a3870b3 | |||
| e11373f23a | |||
| f591635fc1 | |||
| 474b57ca61 | |||
| 8671887abc | |||
| 8274d1baa5 | |||
| bde601bfff | |||
| a2e0951042 | |||
| 3c9a8a38dd | |||
| 4c067fd39f | |||
| 5c251ee774 | |||
| ddda691552 | |||
| ba73090d53 | |||
| a080b606ab | |||
| 7c0f43c8a3 | |||
| 4fad1aee6b | |||
| 19aec5bc8d | |||
| 33ee60736c | |||
| c1bccb970f | |||
| 481cc029fa | |||
| bdaf58a3c4 | |||
| 0f64671dc0 | |||
| 60f055f293 | |||
| c67a9215e3 | |||
| a0e9df6d6d | |||
| 8341749c04 | |||
| 66d1886663 | |||
| 710e1fc278 | |||
| 4cf98584da | |||
| 3fb3cee423 | |||
| 2d1504a057 | |||
| 4fcfd089d8 | |||
| 04422a4637 | |||
| 37e6548246 | |||
| a761989f3e | |||
| acaa8b1731 | |||
| 082f47663d | |||
| 92f42154d5 | |||
| fc1084ce33 | |||
| adc3ab7e0a | |||
| dcc8c56969 | |||
| 0b3472d227 | |||
| b50121ad0b | |||
| dfddfc3e06 | |||
| 34ec6210c6 | |||
| daaef316e9 | |||
| cdac12bb2f | |||
| 3ab99647aa | |||
| 529482a83e | |||
| 29906ec057 | |||
| 9296ba7492 | |||
| 821c6d807d | |||
| 991b741cbe | |||
| 2559f0e822 | |||
| 8bb1ed3e95 | |||
| 56ba3fcb92 | |||
| e99a20a120 | |||
| f1a25b21a6 | |||
| cf9595ce58 | |||
| 7feece597a | |||
| fa16c782ca | |||
| a03d0b6a4a | |||
| dff76b8912 | |||
| cffea9a9bc | |||
| 43fee42198 | |||
| 5cd3968929 | |||
| 65dcae79f8 | |||
| 2b3b75a4a5 | |||
| 26b395110c | |||
| e11b3becfd | |||
| 73fa937f5c | |||
| 6ebe2e54ac | |||
| fb29a11cc9 | |||
| a9e06cbf92 | |||
| 93017c044d | |||
| c223ddbb9a | |||
| f00aeacb8b | |||
| 5b49071d6b | |||
| 17053a882b | |||
| 5e723d31a4 | |||
| 3283bd8b75 | |||
| 770d3c0015 | |||
| d15dfafd5d | |||
| 545c13d55c | |||
| e2099ac9ca | |||
| c937583a50 | |||
| 43c7a19849 | |||
| 83543487e7 | |||
| 434b259525 | |||
| add8efaba8 | |||
| 12ed79ca60 | |||
| 1e863382d3 | |||
| bad3504d4a | |||
| d94f207162 | |||
| 2c4b7781a4 | |||
| 4574c6ff07 | |||
| 7b5043e87b | |||
| a06f3ac5da | |||
| 721346a40a | |||
| f252871fb8 | |||
| 107196122c | |||
| 563c02d8da | |||
| 765934970a | |||
| 9cbdfda829 | |||
| c1fbc8cd68 | |||
| a92107cc47 | |||
| 3e84e116e8 | |||
| 7c0cdd169e | |||
| 424fd96615 | |||
| ebfcea88da | |||
| 3c7eb2f5e2 | |||
| 936167972f | |||
| 7f6070c960 | |||
| 0aea9c129c | |||
| d20fb7daa8 | |||
| a619f8a2fe | |||
| 0acb858d7b | |||
| e459be76fe | |||
| c4c59ccc75 | |||
| c820315409 | |||
| 2a19b61b7a | |||
| e1cf64ae16 | |||
| d3c2f8eb43 | |||
| a00453c83a | |||
| 2eb0e54909 | |||
| ac87bc57e9 | |||
| 2b8ea857f0 | |||
| 11c52114b2 | |||
| f55f9b4dd3 | |||
| cdd369ea98 | |||
| f2aab9f476 | |||
| 2619dc3556 | |||
| 1bbed351ba | |||
| 4cfb2644c6 | |||
| 5b85c7ad39 | |||
| ab3a3156f2 | |||
| 28a582025e | |||
| 8451a83a3a | |||
| 92c8dcc666 | |||
| da68b02e1e | |||
| 2d7729dbe9 | |||
| 6467edb843 | |||
| 1f01b3a9ff | |||
| 8aa1f8926d | |||
| ace363fa35 | |||
| 919f70a5fd | |||
| 9d6ad771a3 | |||
| bafccb20c6 | |||
| cef30c2af0 | |||
| ca58056a75 | |||
| 03e2e99498 | |||
| fba7afc4e9 | |||
| d7dda336ec | |||
| 55d4395160 | |||
| f7d5baa6d0 | |||
| 6ff509d263 | |||
| 57778981a7 | |||
| 6ac3bc564f | |||
| 82d08e2153 | |||
| 6212cd77e8 | |||
| 170034f943 | |||
| e639a8f9f1 | |||
| 9d10c45dac | |||
| b84159f2f1 | |||
| 49f26b4049 | |||
| 0e7e44cee2 | |||
| 36e769502c | |||
| a4b6580247 | |||
| 84fb1c5127 | |||
| ddfd0fb81d | |||
| 37edbf5824 | |||
| e15212bf49 | |||
| 6a0cc1b1f3 | |||
| 0e8339c701 | |||
| 5d71a4dbde | |||
| 0b78030c59 | |||
| 24237c16bf | |||
| c48da5dea7 | |||
| 6702ca10a1 | |||
| 4b44bd5e61 | |||
| 8a55beda92 | |||
| a12b824339 | |||
| c4a743189e | |||
| 85f9ef35f6 | |||
| 6de220e38a | |||
| 0d455d8c2f | |||
| f7b0b44ef6 | |||
| 81282a9c88 | |||
| a9b302e38d | |||
| 1fe4c367f7 | |||
| 2de7583900 | |||
| 356703c83e | |||
| 1cae709b2b | |||
| 46a492248f | |||
| d876ea6711 | |||
| b40b4c3cfd | |||
| 44980d6c46 | |||
| 442f9647a2 | |||
| a06ef07178 | |||
| 0c2ea5da4c | |||
| 45814ceb49 | |||
| 41f4617e66 | |||
| a463711b03 | |||
| 3a147141b1 | |||
| aea1c13bd3 | |||
| 9cc4c017ae | |||
| 88022747be | |||
| ebb292a2f7 | |||
| 818998259d | |||
| 36b02c2cec | |||
| e6195ade3e | |||
| 231a875bb4 | |||
| 378c777a38 | |||
| 8ef63916ef | |||
| f32ecdf5f1 | |||
| 94739b9b8e | |||
| 023db4e04e | |||
| 5a4b95f5fe | |||
| b091657b5c | |||
| f7bf5c9328 | |||
| 86e521b9aa | |||
| e08cf57b72 | |||
| 9e06cb9a83 | |||
| c65e8622b8 | |||
| 7795efeb7a | |||
| e725e0020e | |||
| 8478ce25f1 | |||
| 22cdac6210 | |||
| 3422a1a59f | |||
| f807b8cb46 | |||
| e1e510ce1e | |||
| 36bc3ff22d | |||
| 1db1ffde99 | |||
| 7984b625ba | |||
| bb22f062ed | |||
| a3086e6a5b | |||
| 1eb9bd34fd | |||
| cff7baaaad | |||
| 47af700375 | |||
| eb7f53a1e3 | |||
| d23792fda2 | |||
| b5cbb8e450 | |||
| fc037b4518 | |||
| c04921f42b | |||
| 8af3463668 | |||
| 094565ccd6 | |||
| 07b9769504 | |||
| 566b12f5d1 | |||
| a560999d13 | |||
| a818a3d293 | |||
| 4d68a174cb | |||
| 905219e523 | |||
| c675b87040 | |||
| e2dadfdc40 | |||
| a66f9aa04d | |||
| 863e74dd2e | |||
| aebb07c5cc | |||
| 677fec0a0b | |||
| 61f06faaf5 | |||
| fcf8309c23 | |||
| 76b19a4980 | |||
| ed1a9fc7aa | |||
| b71e30755d | |||
| fe196d1b20 | |||
| 0b152a3cb8 | |||
| 1a0e096ddb | |||
| bf040d4c42 | |||
| 3e2101aa5b | |||
| 44f11b38e7 | |||
| 06f8514bc1 | |||
| d9a9f1c25c | |||
| e77f7244ba | |||
| 09779cd1e1 | |||
| 11024168db | |||
| 304914513e | |||
| 03d0efcfc6 | |||
| 0c2bdc9146 | |||
| 188450b0c0 | |||
| ddf6bbfa46 | |||
| 2c7c98a152 | |||
| d31ac75718 | |||
| 4b28c659de | |||
| 00b937e52a | |||
| 68f333fb87 | |||
| 085b4d9319 | |||
| b8edd14f39 | |||
| 61a19d694b | |||
| aa96859798 | |||
| abf015f485 | |||
| 0b9a02afde | |||
| e332ce28f8 | |||
| 08e779f9f1 | |||
| a53b6cd28f | |||
| 47ebab237b | |||
| 5a5af60f97 | |||
| 50cc17c7cb | |||
| a1e504c138 | |||
| 4cc413047c | |||
| 2397097e4d | |||
| c88f959ec9 | |||
| 0b2e28b62d | |||
| c7f2ead696 | |||
| b454e02d01 | |||
| 47df2ffc3e | |||
| d18e431e2f | |||
| 0a147d2db7 | |||
| ccdc933064 | |||
| 023f2d4569 | |||
| 06a7371d2b | |||
| 626f5d3487 | |||
| 8cd3b9fe2e | |||
| 716c35d52a | |||
| 8cc0f3918b | |||
| 98b51f0799 | |||
| 81d6dad548 | |||
| 41bc11cf96 | |||
| 721dbe415a | |||
| f5c0b51428 | |||
| 892c6ad80c | |||
| a47805e494 | |||
| 9dd49054d1 | |||
| f5d1d1a0b7 | |||
| d75fcb7fec | |||
| 826be45b6a | |||
| d35d9c17c5 | |||
| f9553e7d44 | |||
| 638c9720cf | |||
| 08a190882f | |||
| bfa7530a39 | |||
| 6c74148c27 | |||
| 480cad0fed | |||
| 32be489136 | |||
| 11801d8e2e | |||
| 1b280a2940 | |||
| 424890a1e1 | |||
| 5f85219495 | |||
| a63d687f1c | |||
| f2d6c3ad83 | |||
| 0b6941d5ce | |||
| 048696ee93 | |||
| ae51676471 | |||
| 27a405fb1d | |||
| e2cf65b591 | |||
| 9749fc817d | |||
| e6600f2c43 | |||
| a664931e7a | |||
| a2ba965600 | |||
| 65255dbb50 | |||
| a5cb8761a5 | |||
| e3930e0717 | |||
| afd59e9933 | |||
| 8087524bef | |||
| 605440812f | |||
| b10c6eb615 | |||
| a96264ff6a | |||
| deb3893820 | |||
| 9b1d822b5b | |||
| f933fb705c | |||
| 5cd61c4c02 | |||
| 586fa70eac | |||
| 9b420ad33f | |||
| 5891290672 | |||
| 72a7b51d47 | |||
| 2943e0e58d | |||
| 5abce916a8 | |||
| 89d4be8a0a | |||
| b7113bda23 | |||
| 0088929622 | |||
| b3468cf7f2 | |||
| f88c5c8528 | |||
| 687fdda7f7 | |||
| aec51e514c | |||
| 308d4600ef | |||
| 50a5fa15bb | |||
| 7d96a57d73 | |||
| 162ebfd4e0 | |||
| a586a92d5e | |||
| 3df20a924f | |||
| ddcf466e4e | |||
| 5d10cbf18d | |||
| 918ea59b9a | |||
| 8d9afa7592 | |||
| 95e05336c2 | |||
| a188385817 | |||
| 0a6baf331b | |||
| 0e29e052d5 | |||
| d8d255980e | |||
| dc5a5fa543 | |||
| 8638fc91ff | |||
| 96a0900edc | |||
| abea80e3ab | |||
| 42dfe936b7 | |||
| 8385bcc2d7 | |||
| 9b8f60b64b | |||
| b9dab77c8b | |||
| 474114236e | |||
| 238b0b421a | |||
| 8abe62886a | |||
| 78cc9cffe4 | |||
| 59a5dd713f | |||
| a39024ff03 | |||
| 72bfbd93a8 | |||
| c9a3e3d9d2 | |||
| 8387708901 | |||
| b565b4b3b9 | |||
| 893dcd4f24 | |||
| d613aa8f3e | |||
| 5750bb7067 | |||
| 0e07ae6ce8 | |||
| 02b6351e13 | |||
| 78367af830 | |||
| dc05cd481f | |||
| 7daad5477a | |||
| 45cdfbfae8 | |||
| 4159534a64 | |||
| 3fb5c38571 | |||
| 59f80ebc47 | |||
| 198a97b00c | |||
| 3ea4e917e8 | |||
| 60ad077172 | |||
| 356ad28e41 | |||
| e241141220 | |||
| 14bb1b467a | |||
| 2bbea6fd3f | |||
| 48aef25b3f | |||
| 8e50e5dee3 | |||
| d5d54d4d3b | |||
| 412e8a32dd | |||
| 0f82cf409b | |||
| 79df39acab | |||
| d00177a9b6 | |||
| 8786bae7dc | |||
| 4b3f8ca361 | |||
| 03183218f7 | |||
| 95b6db57e1 | |||
| bbe0c2457b | |||
| c894c53e69 | |||
| 5b3fb7387d | |||
| feac310caf | |||
| d67ec3feb3 | |||
| cf8abb4528 | |||
| d66de26de4 | |||
| e5a7ada3cf | |||
| b76fdd7fe4 | |||
| 7edf3f6147 | |||
| 2143dff2ae | |||
| 32c714d1b6 | |||
| 84e699ee24 | |||
| 7fdb572b8b | |||
| 91ffb0820a | |||
| cfd3b66be9 | |||
| 75c4f9dea8 | |||
| a76a32230d | |||
| 0730f5ff4f | |||
| c43d0a684c | |||
| 66f1eda6cf | |||
| bf4d191c8b | |||
| d76d56fcce | |||
| 251b0c58de | |||
| 073cca4e8e | |||
| a4ad99f189 | |||
| d37b910889 | |||
| be69244e8d | |||
| 617f74a225 | |||
| a2710ddc25 | |||
| 70101bfa7a | |||
| 203f2984d7 | |||
| 1d510e76b8 | |||
| 64244af2cc | |||
| 35e109882e | |||
| 18a32ffb0b | |||
| a5af3ba0cb | |||
| 83bd39a9a8 | |||
| cc0657aaa8 | |||
| 965dc2cb47 | |||
| 9c4cbe17a2 | |||
| 835fcfa4ea | |||
| 932780c578 | |||
| 37f160a452 | |||
| f80b706fc3 | |||
| f78cbed4d8 | |||
| e0b12c78ff | |||
| e7cf814a59 | |||
| 865c45593b | |||
| 62e6f109c7 | |||
| 60be8ed022 | |||
| c157882900 | |||
| a23c211a65 | |||
| 293ed6bd7e | |||
| 13ddd7c5f9 | |||
| 0de015fc8b | |||
| d34fedae01 | |||
| 7c623fc467 | |||
| 359079c3e6 | |||
| ba72fa3f05 | |||
| 23caab5b06 | |||
| b506bd15a5 | |||
| d0d9d68fe6 | |||
| 88134ac130 | |||
| 3d8a5196a0 | |||
| c4fb138ae8 | |||
| 759cfdaabd | |||
| 3d9620abb0 | |||
| 420b0394a7 | |||
| 84bb4c8b07 | |||
| 310dbb61ee | |||
| 9b536af9e6 | |||
| c2ca1ea1e5 | |||
| ada4b226de | |||
| 67f956d4a0 | |||
| f68af7dcf2 | |||
| be1b6f8edc | |||
| 1150f62927 | |||
| b4c7a521b4 | |||
| 5d083a1536 | |||
| 2f5ed3aead | |||
| 2951df0cd9 | |||
| ec22070957 | |||
| 0e36f03954 | |||
| 57309ae3d5 | |||
| 7545194f97 | |||
| 4bb0918e27 | |||
| 64e5449ab3 | |||
| a0eeb17d73 | |||
| c021dd03d3 | |||
| 2f1683b26a | |||
| c99939f435 | |||
| efad8bac3c | |||
| eaf68fa463 | |||
| 9475f2e56c | |||
| 2e0c067cd2 | |||
| 59a6043549 | |||
| 840a7b7c73 | |||
| 61e322678b | |||
| 04acd08ad2 | |||
| f3bf4faee0 | |||
| c3603ba220 | |||
| a3a52fd12c | |||
| 7c4756da81 | |||
| f4fe03c790 | |||
| a748bb9352 | |||
| d24fb6ed48 | |||
| 021dc5b82c | |||
| 9339b78f80 | |||
| 8449f8580d | |||
| 0948c5bc69 | |||
| 857589b365 | |||
| c39b1bf823 | |||
| 545aa50898 | |||
| 298006a4b9 | |||
| 903a4131ab | |||
| a0ec0ddb14 | |||
| 46eb876f9b | |||
| 8374c3941a | |||
| 8cec14c2ff | |||
| c716f105bd | |||
| 737be1f571 | |||
| 6f17c700b8 | |||
| 04d79f9117 | |||
| 8145808c43 | |||
| 86d5626d92 | |||
| 071ef281c1 | |||
| 70760e4ede | |||
| 8a32fd36ad | |||
| 2e30fff221 | |||
| 667ffa5dff | |||
| d271120c24 | |||
| a03ae5a216 | |||
| 0e73fa40bc | |||
| 5d6f0d8546 | |||
| 41e23fb6a8 | |||
| 4e15556e5e | |||
| bf30b7afae | |||
| 8801afa586 | |||
| 47804353f9 | |||
| be58e3084b | |||
| 71d5ab21ed | |||
| 993bc7432f | |||
| 99ff879d93 | |||
| caa15b4735 | |||
| cc8da0cf13 | |||
| 0b6618ff70 | |||
| 6f180f534c | |||
| 4220ef2a5b | |||
| 2acaa66635 | |||
| ee5eecbec1 | |||
| 687bb8a237 | |||
| e51123a951 | |||
| 92bb12e2e3 | |||
| fd0536bd4b | |||
| 57389a79a1 | |||
| 6cd7bddc37 | |||
| c3c5006daa | |||
| 27a8a57cf5 | |||
| 3bded6fdcc | |||
| c7f31337ce | |||
| fd507f2692 | |||
| 96a39ef9c3 | |||
| 81a8d6c3bf | |||
| d4719208f0 | |||
| c36dce6464 | |||
| 2da4474bb1 | |||
| cab11202c7 | |||
| 21d7d35bb1 | |||
| 0725c663c4 | |||
| ce82239c8b | |||
| 2523008cb6 | |||
| 69212b9ad1 | |||
| 636cb3399b | |||
| 86ca35ce33 | |||
| 675ab31305 | |||
| 83c2d743bc | |||
| 2c87b3d906 | |||
| 05b6159802 | |||
| c56f48c1e3 | |||
| e18e399ce6 | |||
| d66ade4e47 | |||
| 90b045af6d | |||
| 5cccb21175 | |||
| 1a71969403 | |||
| 389a1fbd04 | |||
| ca02ae6183 | |||
| 92446cb048 | |||
| 954ce4533f | |||
| f7b88f9e3b | |||
| 736fe038eb | |||
| abcd257db0 | |||
| c38b5f3cdc | |||
| b649617e04 | |||
| a4e2287101 | |||
| fbb66f3c43 | |||
| fedf90ea78 | |||
| d558d50102 | |||
| 656cb89fe8 | |||
| 1e6ddd250e | |||
| 1de8eee6ea | |||
| 425bba67c5 | |||
| 8b0daf7200 | |||
| 589a373142 | |||
| 0cfc71e4bf | |||
| 92dabe6276 | |||
| d1b61b6bf9 | |||
| 873f2b618b | |||
| 4453070060 | |||
| de40be430b | |||
| 29a6a992f0 | |||
| 0a7d2d6264 | |||
| e09f92f9ee | |||
| 9be1ecc8aa | |||
| 729b19c8da | |||
| a9fffa5180 | |||
| 0069c0e399 | |||
| b6fd38e293 | |||
| 36aa7f82b0 | |||
| d01004d530 | |||
| d85a02feeb | |||
| b82e1dcd62 | |||
| 74c6a2266f | |||
| 9754223f31 | |||
| cfbbac9796 | |||
| fece8955cf | |||
| 170b2afb0e | |||
| ee8af18d0a | |||
| 27386ea04d | |||
| 0d71a8ee50 | |||
| 82a72e0b49 | |||
| 5035c123f0 | |||
| 474b3372d8 | |||
| be87124ada | |||
| aa3032db35 | |||
| a4ead79888 | |||
| 98445afd3e | |||
| 3eb9671640 | |||
| 95fb4e3e8b | |||
| 818015d24a | |||
| e11bd3e813 | |||
| 2a4d64af95 | |||
| d73cb4be2b | |||
| 82752040f8 | |||
| 1bde6d8b9c | |||
| be55d36f67 | |||
| f07724372d | |||
| 5b8d5dd975 | |||
| e36aa065e9 | |||
| 45486ef399 | |||
| 4fedf6f452 | |||
| 702b80ef75 | |||
| a5c7789dbc | |||
| bddef199ff | |||
| fa6fc07009 | |||
| 8d9b44528b | |||
| 1d108d775c | |||
| 7af111ac57 | |||
| 6451f00639 | |||
| 31718d1a4a | |||
| 832b74b66b | |||
| 082802e119 | |||
| efa9c748c5 | |||
| fc8bef5aae | |||
| 441b15ed2f | |||
| 11d1f6e141 | |||
| 0f5b9564c6 | |||
| 0c8a84656a | |||
| 330f91e15b | |||
| 490141a920 | |||
| 1e288b14d0 | |||
| 81df96bf45 | |||
| d1ab5f74a6 | |||
| e43dd03132 | |||
| 2c6d64976f | |||
| 065713cdb6 | |||
| 746d3c97c3 | |||
| 9557fc799e | |||
| 8fcabc5e9f | |||
| 2b4b15f558 | |||
| 057b0b4565 | |||
| 70a2402521 | |||
| de34db3394 | |||
| 0c2ae792ec | |||
| a4c0b92777 | |||
| b9d78135e0 | |||
| 5641c19502 | |||
| 0110dfdb70 | |||
| 140606744b | |||
| 335d175d57 | |||
| 779db9da70 | |||
| 5d29a08ab7 | |||
| 1fe3365e10 | |||
| f0584c88e8 | |||
| c7620dfc48 | |||
| 5d6a945763 | |||
| 4fe5939d0b | |||
| bcaf54d4cb | |||
| 44d43f45cb | |||
| de26ee9383 | |||
| d442462952 | |||
| 558fc9f306 | |||
| 9f0ee219d0 | |||
| 5164116bde | |||
| 02404bc97e | |||
| 0ebdb037b5 | |||
| a8b60c32b3 | |||
| 416621d503 | |||
| b917eb447c | |||
| 2ce3c71b88 | |||
| ca13bfa5f8 | |||
| d8812196f3 | |||
| 4e750bdbe1 | |||
| f59a37b77c | |||
| ea3db93db9 | |||
| 26f2c9fea2 | |||
| 290cc0d1bb | |||
| 78044c062e | |||
| 3a2f653229 | |||
| bbe22e6f36 | |||
| d4474ff0fb | |||
| c7979f1be5 | |||
| ada0b7106e | |||
| c3a5542935 | |||
| 2eebb3388a | |||
| 287c3688fd | |||
| 3948b3993f | |||
| bcacafeb84 | |||
| 2193ddfabe | |||
| 29ae0b7dca | |||
| 904837df12 | |||
| 00c2da444f | |||
| 13d0dde9f4 | |||
| 548f2a960c | |||
| fe4367c580 | |||
| 71803f891d | |||
| 75a38d95f3 | |||
| c89686a2fd | |||
| 398323533a | |||
| a773872cf3 | |||
| 2eb0d55f92 | |||
| 54bd1ad0fa | |||
| 089825d360 | |||
| 333629caff | |||
| d715cd1129 | |||
| 15d6eaf553 | |||
| ae5dfc3bee | |||
| 6ab83b662a | |||
| 52ae6902d2 | |||
| c30adb2671 | |||
| e95d29f446 | |||
| c20bb38b06 | |||
| d0213d275d | |||
| 9a78dad576 | |||
| 880f1aeb66 | |||
| e764eabd97 | |||
| 235f9cf854 | |||
| d10795ecd9 | |||
| a7e45dace0 | |||
| 7e482f798c | |||
| c085bac5d8 | |||
| 653940a0ca | |||
| 417d37b199 | |||
| 3b2107a4f1 | |||
| 7f6d03c02a | |||
| 5fc07d4dd4 | |||
| 3fb9524cbd | |||
| e79703e49b | |||
| b829bd1341 | |||
| 8cbab7525a | |||
| 93b37a89c9 | |||
| 87620b9072 | |||
| 6877b865a7 | |||
| d6b3142a02 | |||
| 14cdb54212 | |||
| 91e7f45a1c | |||
| 709105120c | |||
| 865f26d75c | |||
| 52a4fd3318 | |||
| e70732c9ac | |||
| c6c269f9e4 | |||
| 42ad04cabd | |||
| 2a8eeaf240 | |||
| f7dcff5113 | |||
| 98a81385a6 | |||
| 7bdc277b58 | |||
| f57116d2be | |||
| 85c99f7f80 | |||
| 75081ceac3 | |||
| 65da3ca298 | |||
| 94509c64b9 | |||
| 4f36d94726 | |||
| 05c284b999 | |||
| 635b042690 | |||
| 1cb4a539cc | |||
| 46b87250b2 | |||
| 1a05355e54 | |||
| c81c17d17b | |||
| 7b4f8d31e8 | |||
| 5cef28c5bd | |||
| 6e68da7936 | |||
| 0c130f9596 | |||
| f156f4cb4e | |||
| fa3bfa2ea8 | |||
| ab5c7bb75a | |||
| 81b322cd60 | |||
| e6dd7cd54a | |||
| aa1da7c11a | |||
| 3f74d4d9e5 | |||
| 297d09c5ad | |||
| 07e1dbb4cc | |||
| 3c6618b4fc | |||
| 54db744282 | |||
| 03b751fa13 | |||
| ec342708b2 | |||
| 405591c5d0 | |||
| 7f5e89d489 | |||
| c504f33b1f | |||
| 67af67b92d | |||
| 8644348fc4 | |||
| 00dc226bd2 | |||
| b6b7c3e2e0 | |||
| 246ef348d3 | |||
| 3e9ba1a30a | |||
| 598cde4865 | |||
| fc4a716b4e | |||
| ed5634ff83 | |||
| 884af1ea62 | |||
| 01ad62df16 | |||
| 512a667e44 | |||
| d0e841f7de | |||
| c04641d835 | |||
| f9128d4d45 | |||
| 2026211622 | |||
| 9d0f21a9e5 | |||
| 26adf7d437 | |||
| d2d6f12218 | |||
| b31c0b6a8d | |||
| 472f06c2d1 | |||
| f5ec9870fd | |||
| 66fb9e5f49 | |||
| a323f3aa2c | |||
| fe4786e168 | |||
| ed6a18dae7 | |||
| 83185c8c50 | |||
| 83ae9db02d | |||
| 8bf328ca94 | |||
| 36993cb6f8 | |||
| c854415319 | |||
| aecc1cd979 | |||
| b2f3b0b584 | |||
| c937f5afc7 | |||
| 2d580a26af | |||
| 4a00a3cc1b | |||
| d3935219f2 | |||
| 040788c793 | |||
| 005622307e | |||
| 8ebf95a222 | |||
| 7f596ed315 | |||
| ffa4de6911 | |||
| cb27d4b490 | |||
| bb4910f4e5 | |||
| 89c7f07034 | |||
| b150b2f034 | |||
| 45d6347f5b | |||
| 67d762b6a5 | |||
| faa28f88f9 | |||
| 9c8c7a7812 | |||
| a019956698 | |||
| d70e2b66a3 | |||
| 5d568efac3 | |||
| 08111f1418 | |||
| 45839f227a | |||
| 8814ffeda6 | |||
| d224c4c124 | |||
| 549525fb37 | |||
| 1c8e25beb3 | |||
| eda45c1528 | |||
| 53c38cf714 | |||
| 0e7578043e | |||
| 21f50e0b38 | |||
| 515f00c7cd | |||
| 8057586dc1 | |||
| b101ac7c7f | |||
| 64319937a1 | |||
| 1c0cfd6769 | |||
| f8e17d5285 | |||
| d4385ad8a5 | |||
| da07ce419f | |||
| 714e0206c4 | |||
| 40da82666a | |||
| 79f7ec4672 | |||
| 0f5c69040b | |||
| c9d1c45d97 | |||
| ea8fdb120c | |||
| f6fa830ffe | |||
| 992e50c014 | |||
| bd705d91ba | |||
| 2656394195 | |||
| c8df9e698c | |||
| 19b78a1d2f | |||
| 8039e8baf8 | |||
| 9c5142c73c | |||
| 8e3dcdde17 | |||
| 34023adafb | |||
| 79914e8d08 | |||
| 454fbda581 | |||
| 2c32703e6b | |||
| b561535626 | |||
| 1fc684d995 | |||
| 7595d9fdfd | |||
| 3bf7732a21 | |||
| 71b5aaf8ab | |||
| e1e5347476 | |||
| cdcdb6a2d9 | |||
| ec79104ad2 | |||
| ff083ce684 | |||
| 0f051e322e | |||
| 657a2ae032 | |||
| 0db3570026 | |||
| 0ae39f160a | |||
| b45977c29a | |||
| b7f5740c57 | |||
| 21e23369d3 | |||
| fca598991a | |||
| aa5b909486 | |||
| 0a888cf51a | |||
| e5c164065c | |||
| 8bc241ca14 | |||
| 15beb79631 | |||
| fef1305e41 | |||
| 498cf34999 | |||
| 7cde1fdc4a | |||
| 228fdf0a0d | |||
| fdb5ea0ff4 | |||
| a0e838d1ee | |||
| 30ddf5ec41 | |||
| cfd3b7b3ae | |||
| a6cd532035 | |||
| b1db952fcb | |||
| 51e8bab352 | |||
| 618ec93786 | |||
| a673f9c8ca | |||
| e8c9c2a47d | |||
| aafa5d5f90 | |||
| 8b9c47daf1 | |||
| 4042577c0b | |||
| 6c9f9940e3 | |||
| 8f7b3f29ce | |||
| 6bca7333c9 | |||
| 3dfeeec899 | |||
| 138dc286f6 | |||
| 07cee2aadf | |||
| 1b267813c9 | |||
| 96b5981f8c | |||
| a2fd9559c5 | |||
| 3f06419d47 | |||
| 2aefca3813 | |||
| 844c4bf983 | |||
| 6aa487269c | |||
| 43961c1c18 | |||
| 393ea27fa4 | |||
| febe87508c | |||
| 30db27980c | |||
| 4e768ec50f | |||
| 4467e09426 | |||
| 66b95d52fd | |||
| 1398417829 | |||
| 58dd5e2750 | |||
| 70210f567a | |||
| 49e7dc56e1 | |||
| 72cc586f88 | |||
| 94fa77fcd2 | |||
| 2c0cbdd29e | |||
| 68a503796c | |||
| 48cf28dd7f | |||
| 7e103b7744 | |||
| 79d637c9bf | |||
| 7c8d551fe1 | |||
| 72862c8be8 | |||
| 4f1bb48bf7 | |||
| 15740a6d8a | |||
| 2bc3456400 | |||
| 5a607efa9f | |||
| 1c8163dd82 | |||
| 327a919958 | |||
| a847e66c4f | |||
| 0772d3b3fd | |||
| 61d6b06c56 | |||
| 1534f45236 | |||
| aedc462135 | |||
| 7b55337c5e | |||
| 87bbf6f140 | |||
| 0d8913ea2f | |||
| 387bcc5fa4 | |||
| 5a20242111 | |||
| 196f7d9dc2 | |||
| 954b6df360 | |||
| 8002a56efc | |||
| 7e5ea0cee0 | |||
| 7b42d7252e | |||
| 3254afc756 | |||
| e3553d4c8c | |||
| 7be14ee905 | |||
| fc234314b7 | |||
| cf19363092 | |||
| 589b38c75d | |||
| 90a8f818bf | |||
| 642f57ff6d | |||
| cbccd9e3d0 | |||
| cf7a3e6f70 | |||
| 8993687c37 | |||
| ff1d7b115a | |||
| 98bd5149e9 | |||
| 4efa2e0c6a | |||
| f805036054 | |||
| 3c723c4325 | |||
| 14a83f6b52 | |||
| ff0686670c | |||
| 3198d07553 | |||
| c7e2896326 | |||
| 0db5381a8b | |||
| cb86151deb | |||
| d6c7326467 | |||
| 92c6c45e77 | |||
| c6fff4950d | |||
| 81a8123725 | |||
| d0d3e74d55 | |||
| b54ae272eb | |||
| 3af6d96e6e | |||
| f38b33ea39 | |||
| dd2b0a1595 | |||
| c96fcb7afc | |||
| b805a29259 | |||
| 5450246f06 | |||
| d9a00eeaf7 | |||
| 131ed13df1 | |||
| 5f8d70028a | |||
| c222b702c3 | |||
| de43391e4c | |||
| 547c0b8399 | |||
| fcbb5e46a1 | |||
| 7c5166c8bb | |||
| fab66606b3 | |||
| 1d143f7103 | |||
| 4955fcd12a | |||
| 817e9663fa | |||
| 85ca850453 | |||
| 3baefb2b60 | |||
| ffea5a0e02 | |||
| be55695691 | |||
| ea27c96362 | |||
| 7a73a01999 | |||
| 018dee6c38 | |||
| c7cf2e6f16 | |||
| 9ab9a6e8b0 | |||
| 4aa136189a | |||
| 67ccff3e86 | |||
| 40c09ce26a | |||
| d6a2e4aee9 | |||
| c66802af2d | |||
| d8a134fe7e | |||
| 16748a75d5 | |||
| 0e33dfa019 | |||
| 49e65c611f | |||
| abf29bc164 | |||
| 08854e0ab9 | |||
| 575416a16d | |||
| 3dd0783510 | |||
| fc9ac23725 | |||
| 0f426b9c19 | |||
| a7d4710702 | |||
| 6946279f03 | |||
| fadb1d35b3 | |||
| 27a9fc32a6 | |||
| 7008a408ca | |||
| b928bb46c7 | |||
| 18c9c4a166 | |||
| 49fa01f209 | |||
| fe9d443100 | |||
| 3dec43d8d4 | |||
| 5ab2943c3a | |||
| 6e8b0eeca9 | |||
| d0c4dfca97 | |||
| f4a11ed328 | |||
| b2971cf5fb | |||
| f97827ec76 | |||
| f230a2a94d |
@@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
# http://editorconfig.org
|
||||||
|
#
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: Plugin Apply
|
||||||
|
about: 部署插件申请支持
|
||||||
|
title: "[Plugin] "
|
||||||
|
labels: feature
|
||||||
|
---
|
||||||
|
|
||||||
|
> > 感谢您支持certd,请按如下规范提交issue
|
||||||
|
> 如果有条件,请尽量在[github上提交](https://github.com/certd/certd/issues)
|
||||||
|
|
||||||
|
# 新部署插件申请支持
|
||||||
|
|
||||||
|
## 1. 需求描述
|
||||||
|
`请在此处简要描述你的需求`
|
||||||
|
|
||||||
|
|
||||||
|
## 2. 要部署证书应用的信息
|
||||||
|
|
||||||
|
1. 应用名称:
|
||||||
|
|
||||||
|
|
||||||
|
2. 应用网址/项目地址/官方网站:
|
||||||
|
|
||||||
|
|
||||||
|
3. 管理证书界面截图(或者手动部署证书方式介绍及截图):
|
||||||
|
|
||||||
|
|
||||||
|
4. 是否有API接口,接口地址:
|
||||||
|
|
||||||
|
|
||||||
|
5. 如果没有API接口,网页登录是否需要验证码:
|
||||||
|
|
||||||
|
|
||||||
|
6. 是否可以提供测试账号?(如果可以请留下联系方式或者加作者好友)
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: DNS Provider Apply
|
||||||
|
about: 域名提供商申请支持
|
||||||
|
title: "[DNS] "
|
||||||
|
labels: feature
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
> 感谢您支持certd,请按如下规范提交issue
|
||||||
|
> 如果有条件,请尽量在[github上提交](https://github.com/certd/certd/issues)
|
||||||
|
|
||||||
|
# 新域名提供商支持申请
|
||||||
|
|
||||||
|
## 1. 基本信息
|
||||||
|
请填写如下内容:
|
||||||
|
|
||||||
|
1. 域名提供商名称:
|
||||||
|
|
||||||
|
|
||||||
|
2. 管理页面地址:
|
||||||
|
|
||||||
|
|
||||||
|
3. 是否有API接口,接口地址:
|
||||||
|
|
||||||
|
|
||||||
|
4. 如果没有API接口,网页登录是否有验证码:
|
||||||
|
|
||||||
|
|
||||||
|
5. 是否可以提供测试账号?(如果可以请留下联系方式或者加作者好友)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 2. 截图
|
||||||
|
|
||||||
|
`域名管理页面截图`
|
||||||
|
|
||||||
@@ -1,21 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: 错误或问题报告
|
||||||
|
title: "[BUG] "
|
||||||
|
labels: bug
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
> 感谢您支持certd,请按如下规范提交issue
|
> 感谢您支持certd,请按如下规范提交issue
|
||||||
> 如果有条件,请尽量在[github上提交](https://github.com/certd/certd/issues)
|
> 如果有条件,请尽量在[github上提交](https://github.com/certd/certd/issues)
|
||||||
|
|
||||||
|
# bug提交
|
||||||
## 一、问题描述
|
## 1、问题描述
|
||||||
`请在此处简要描述你所遇到的问题,必要时请贴出相关截图辅助理解和定位`
|
`请在此处简要描述你所遇到的问题,必要时请贴出相关截图辅助理解和定位`
|
||||||
|
|
||||||
### 复现步骤
|
### 2、复现步骤
|
||||||
`请描述复现问题的详细步骤`
|
`请描述复现问题的详细步骤`
|
||||||
`如果非示例页面的问题,最好能提供最小复现示例的代码、或者仓库链接`
|
`如果非示例页面的问题,最好能提供最小复现示例的代码、或者仓库链接`
|
||||||
|
|
||||||
|
|
||||||
### 报错截图
|
### 3.报错截图
|
||||||
`请贴出报错日志截图`
|
`请贴出报错日志截图`
|
||||||
|
|
||||||
### 效果截图
|
### 4、效果截图
|
||||||
`请贴出效果截图`
|
`请贴出效果截图`
|
||||||
#### 1. 期望效果
|
#### 4.1. 期望效果
|
||||||
|
|
||||||
#### 2. 实际效果
|
|
||||||
|
|
||||||
|
#### 4.2. 实际效果
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: 新需求、新特性申请支持
|
||||||
|
title: "[Feature] "
|
||||||
|
labels: feature
|
||||||
|
---
|
||||||
|
|
||||||
|
> > 感谢您支持certd,请按如下规范提交issue
|
||||||
|
> 如果有条件,请尽量在[github上提交](https://github.com/certd/certd/issues)
|
||||||
|
|
||||||
|
|
||||||
|
# 新特性申请
|
||||||
|
>注意:这里仅供如果是要申请新的部署插件,请提交插件申请
|
||||||
|
|
||||||
|
## 1. 需求描述,需求背景
|
||||||
|
`请在此处简要描述你所遇到的问题,必要时请贴出相关截图辅助理解`
|
||||||
|
|
||||||
|
|
||||||
|
## 2. 期望效果
|
||||||
|
`必要时可以截图描述你的期望效果`
|
||||||
|
|
||||||
|
|
||||||
|
## 3. 你的解决方案
|
||||||
|
`如果你有解决方案,请描述你的方案`
|
||||||
@@ -10,6 +10,7 @@ on:
|
|||||||
# - cron: '17 19 * * *'
|
# - cron: '17 19 * * *'
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-certd-image:
|
build-certd-image:
|
||||||
@@ -43,7 +44,7 @@ jobs:
|
|||||||
# cache: 'npm'
|
# cache: 'npm'
|
||||||
# working-directory: ./packages/ui/certd-client
|
# working-directory: ./packages/ui/certd-client
|
||||||
- run: |
|
- run: |
|
||||||
npm install -g pnpm@8.15.7
|
npm install -g pnpm
|
||||||
pnpm install
|
pnpm install
|
||||||
npm run build
|
npm run build
|
||||||
working-directory: ./packages/ui/certd-client
|
working-directory: ./packages/ui/certd-client
|
||||||
@@ -61,19 +62,38 @@ jobs:
|
|||||||
username: ${{ secrets.aliyun_cs_username }}
|
username: ${{ secrets.aliyun_cs_username }}
|
||||||
password: ${{ secrets.aliyun_cs_password }}
|
password: ${{ secrets.aliyun_cs_password }}
|
||||||
|
|
||||||
|
- name: Login to GitHub Packages
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.dockerhub_username }}
|
username: ${{ secrets.dockerhub_username }}
|
||||||
password: ${{ secrets.dockerhub_password }}
|
password: ${{ secrets.dockerhub_password }}
|
||||||
|
|
||||||
- name: Build default platforms
|
# - name: Build default platforms
|
||||||
|
# uses: docker/build-push-action@v6
|
||||||
|
# with:
|
||||||
|
# platforms: linux/amd64,linux/arm64
|
||||||
|
# push: true
|
||||||
|
# context: ./packages/ui/
|
||||||
|
# tags: |
|
||||||
|
# registry.cn-shenzhen.aliyuncs.com/handsfree/certd-dev:latest
|
||||||
|
# greper/certd-dev:latest
|
||||||
|
# ghcr.io/${{ github.repository }}:dev-latest
|
||||||
|
|
||||||
|
- name: Build armv7
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/arm/v7
|
||||||
push: true
|
push: true
|
||||||
context: ./packages/ui/
|
context: ./packages/ui/
|
||||||
tags: |
|
tags: |
|
||||||
registry.cn-shenzhen.aliyuncs.com/handsfree/certd-dev:latest
|
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7
|
||||||
greper/certd-dev:latest
|
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}-armv7
|
||||||
|
greper/certd:armv7
|
||||||
|
greper/certd:${{steps.get_certd_version.outputs.result}}-armv7
|
||||||
@@ -10,6 +10,7 @@ on:
|
|||||||
# - cron: '17 19 * * *'
|
# - cron: '17 19 * * *'
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-certd-image:
|
build-certd-image:
|
||||||
@@ -43,7 +44,7 @@ jobs:
|
|||||||
# cache: 'npm'
|
# cache: 'npm'
|
||||||
# working-directory: ./packages/ui/certd-client
|
# working-directory: ./packages/ui/certd-client
|
||||||
- run: |
|
- run: |
|
||||||
npm install -g pnpm@8.15.7
|
npm install -g pnpm
|
||||||
pnpm install
|
pnpm install
|
||||||
npm run build
|
npm run build
|
||||||
working-directory: ./packages/ui/certd-client
|
working-directory: ./packages/ui/certd-client
|
||||||
@@ -61,6 +62,13 @@ jobs:
|
|||||||
username: ${{ secrets.aliyun_cs_username }}
|
username: ${{ secrets.aliyun_cs_username }}
|
||||||
password: ${{ secrets.aliyun_cs_password }}
|
password: ${{ secrets.aliyun_cs_password }}
|
||||||
|
|
||||||
|
- name: Login to GitHub Packages
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
@@ -78,27 +86,30 @@ jobs:
|
|||||||
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}
|
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}
|
||||||
greper/certd:latest
|
greper/certd:latest
|
||||||
greper/certd:${{steps.get_certd_version.outputs.result}}
|
greper/certd:${{steps.get_certd_version.outputs.result}}
|
||||||
|
ghcr.io/${{ github.repository }}:latest
|
||||||
# - name: Build armv7
|
ghcr.io/${{ github.repository }}:${{steps.get_certd_version.outputs.result}}
|
||||||
# uses: docker/build-push-action@v6
|
- name: Build armv7
|
||||||
# with:
|
|
||||||
# platforms: linux/arm/v7
|
|
||||||
# push: true
|
|
||||||
# context: ./packages/ui/
|
|
||||||
# tags: |
|
|
||||||
# registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7
|
|
||||||
# registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}-armv7
|
|
||||||
# greper/certd:armv7
|
|
||||||
# greper/certd:${{steps.get_certd_version.outputs.result}}-armv7
|
|
||||||
|
|
||||||
- name: Build agent
|
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/arm/v7
|
||||||
push: true
|
push: true
|
||||||
context: ./packages/ui/agent/
|
context: ./packages/ui/
|
||||||
tags: |
|
tags: |
|
||||||
registry.cn-shenzhen.aliyuncs.com/handsfree/certd-agent:latest
|
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7
|
||||||
registry.cn-shenzhen.aliyuncs.com/handsfree/certd-agent:${{steps.get_certd_version.outputs.result}}
|
registry.cn-shenzhen.aliyuncs.com/handsfree/certd:${{steps.get_certd_version.outputs.result}}-armv7
|
||||||
greper/certd-agent:latest
|
greper/certd:armv7
|
||||||
greper/certd-agent:${{steps.get_certd_version.outputs.result}}
|
greper/certd:${{steps.get_certd_version.outputs.result}}-armv7
|
||||||
|
ghcr.io/${{ github.repository }}:armv7
|
||||||
|
ghcr.io/${{ github.repository }}:${{steps.get_certd_version.outputs.result}}-armv7
|
||||||
|
|
||||||
|
# - name: Build agent
|
||||||
|
# uses: docker/build-push-action@v6
|
||||||
|
# with:
|
||||||
|
# platforms: linux/amd64,linux/arm64
|
||||||
|
# push: true
|
||||||
|
# context: ./packages/ui/agent/
|
||||||
|
# tags: |
|
||||||
|
# registry.cn-shenzhen.aliyuncs.com/handsfree/certd-agent:latest
|
||||||
|
# registry.cn-shenzhen.aliyuncs.com/handsfree/certd-agent:${{steps.get_certd_version.outputs.result}}
|
||||||
|
# greper/certd-agent:latest
|
||||||
|
# greper/certd-agent:${{steps.get_certd_version.outputs.result}}
|
||||||
|
|||||||
@@ -17,11 +17,12 @@ gen
|
|||||||
/test/*.private.*
|
/test/*.private.*
|
||||||
|
|
||||||
/*.log
|
/*.log
|
||||||
|
nohup.out
|
||||||
|
|
||||||
/packages/ui/*/.idea
|
/packages/ui/*/.idea
|
||||||
/packages/ui/*/node_modules
|
/packages/ui/*/node_modules
|
||||||
/packages/*/node_modules
|
/packages/*/node_modules
|
||||||
/pnpm-lock.yaml
|
#/pnpm-lock.yaml
|
||||||
|
|
||||||
|
|
||||||
tsconfig.tsbuildinfo
|
tsconfig.tsbuildinfo
|
||||||
|
|||||||
@@ -1,21 +1,39 @@
|
|||||||
# Certd
|
# Certd
|
||||||
|
|
||||||
Certd 是一个免费全自动申请和自动部署更新SSL证书的管理系统。
|
中文 | [English](./README_en.md)
|
||||||
后缀d取自linux守护进程的命名风格,意为证书守护进程。
|
|
||||||
|
|
||||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
Certd® 是一个免费的全自动证书管理系统,让你的网站证书永不过期。
|
||||||
|
后缀d取自linux守护进程的命名风格,意为证书守护进程
|
||||||
|
|
||||||
|
|
||||||
|
>首创流水线申请部署证书模式,已被多个项目“借鉴”,被抄也是一种成功。
|
||||||
|
|
||||||
|
> 关于证书续期:
|
||||||
|
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||||
|
>* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||||
|
>* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||||
|
|
||||||
|
|
||||||
|
> 流水线数量现已调整为无限制,欢迎大家使用
|
||||||
|
|
||||||
## 一、特性
|
## 一、特性
|
||||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||||
|
|
||||||
* 全自动申请证书(支持所有注册商注册的域名)
|
* 全自动申请证书(支持所有注册商注册的域名,支持DNS-01、HTTP-01、CNAME代理等多种域名验证方式)
|
||||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持30+部署插件)
|
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
||||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||||
* 邮件通知
|
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||||
* 私有化部署,数据保存本地,镜像由Github Actions构建,过程公开透明
|
* 私有化部署,数据保存本地,安装简单快捷,镜像由Github Actions构建,过程公开透明
|
||||||
* 支持sqlite,postgresql数据库
|
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||||
|
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
||||||
|
* 开放接口支持
|
||||||
|
* 站点证书监控
|
||||||
|
* 多用户管理
|
||||||
|
* 多语言支持(中英双语切换)
|
||||||
|
* 各版本向下兼容,一键无忧升级
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
## 二、在线体验
|
## 二、在线体验
|
||||||
@@ -55,7 +73,7 @@ https://certd.handfree.work/
|
|||||||
-------> [点我查看详细使用步骤演示](./step.md) <--------
|
-------> [点我查看详细使用步骤演示](./step.md) <--------
|
||||||
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||||
|
|
||||||
更多教程请访问文档网站 [certd.docmirror.cn](https://certd.docmirror.cn/)
|
更多教程请访问官方文档 [certd.docmirror.cn](https://certd.docmirror.cn/guide/)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -65,10 +83,12 @@ https://certd.handfree.work/
|
|||||||
|
|
||||||
您可以根据实际情况从如下方式中选择一种方式进行私有化部署:
|
您可以根据实际情况从如下方式中选择一种方式进行私有化部署:
|
||||||
|
|
||||||
1. [宝塔面板方式部署](https://certd.docmirror.cn/guide/install/docker/)
|
1. 【推荐】[Docker方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
2. [1Panel面板方式部署](https://certd.docmirror.cn/guide/install/1panel/)
|
2. 【推荐】[宝塔面板方式部署 ](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
3. [Docker方式部署](https://certd.docmirror.cn/guide/install/docker/)
|
3. 【推荐】[1Panel面板方式部署](https://certd.docmirror.cn/guide/install/1panel/)
|
||||||
4. [源码方式部署](https://certd.docmirror.cn/guide/install/source/)
|
4. 【推荐】[雨云一键部署](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2) : 首充翻倍,每月仅需2.2元
|
||||||
|
[<img src="https://rainyun-apps.cn-nb1.rains3.com/materials/deploy-on-rainyun-cn.svg">](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2)
|
||||||
|
5. 【不推荐】[源码方式部署 ](https://certd.docmirror.cn/guide/install/source/)
|
||||||
|
|
||||||
#### Docker镜像说明:
|
#### Docker镜像说明:
|
||||||
* 国内镜像地址:
|
* 国内镜像地址:
|
||||||
@@ -78,56 +98,45 @@ https://certd.handfree.work/
|
|||||||
* `https://hub.docker.com/r/greper/certd`
|
* `https://hub.docker.com/r/greper/certd`
|
||||||
* `greper/certd:latest`
|
* `greper/certd:latest`
|
||||||
* `greper/certd:armv7`、`greper/certd:[version]-armv7`
|
* `greper/certd:armv7`、`greper/certd:[version]-armv7`
|
||||||
|
* GitHub Packages地址:
|
||||||
|
* `ghcr.io/certd/certd:latest`
|
||||||
|
* `ghcr.io/certd/certd:armv7`、`ghcr.io/certd/certd:[version]-armv7`
|
||||||
|
|
||||||
* 镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
* 镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
||||||
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
> 注意:
|
||||||
## 五、 升级
|
> * 本应用存储的证书、授权信息等属于高度敏感数据,请做好安全防护
|
||||||
如果使用固定版本号
|
> * 请务必使用HTTPS协议访问本应用,避免被中间人攻击
|
||||||
1. 修改`docker-compose.yaml`中的镜像版本号
|
> * 请务必使用web应用防火墙防护本应用,防止XSS、SQL注入等攻击
|
||||||
2. 运行`docker compose up -d` 即可
|
> * 请务必做好服务器本身的安全防护,防止数据库泄露
|
||||||
|
> * 请务必做好数据备份,避免数据丢失
|
||||||
如果使用`latest`版本
|
> * [更多安全生产建议点我](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
```shell
|
|
||||||
#重新拉取镜像
|
|
||||||
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
|
||||||
# 重新启动容器
|
|
||||||
docker compose down
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
> 数据默认存在`/data/certd`目录下,不用担心数据丢失
|
|
||||||
|
|
||||||
|
|
||||||
更新日志: [CHANGELOG](./CHANGELOG.md)
|
## 五、生态
|
||||||
|
|
||||||
|
### 1. 客户端工具 SSL-Assistant
|
||||||
|
`SSL Assistant` 是一个运行于主机上的证书部署管理助手客户端。
|
||||||
|
支持自动扫描主机`Nginx`配置,然后从`Certd`拉取证书并部署。
|
||||||
|
在不想暴露ssh主机密码情况下,该工具非常好用。
|
||||||
|
|
||||||
|
开源地址: https://github.com/Youngxj/SSL-Assistant
|
||||||
|
|
||||||
|
|
||||||
## 六、一些说明
|
## 六、更多帮助
|
||||||
* 本项目ssl证书提供商为letencrypt/Google/ZeroSSL
|
请访问官方文档:[https://certd.docmirror.cn/](https://certd.docmirror.cn/guide/)
|
||||||
* 申请过程遵循acme协议
|
|
||||||
* 需要验证域名所有权,一般有两种方式(目前本项目仅支持dns-01)
|
* 升级方法:[升级方法](https://certd.docmirror.cn/guide/install/upgrade/)
|
||||||
* http-01: 在网站根目录下放置一份txt文件
|
* 常见问题:[忘记密码](https://certd.docmirror.cn/guide/use/forgotpasswd/)
|
||||||
* dns-01: 需要给域名添加txt解析记录,通配符域名只能用这种方式
|
* 多数据库:[多数据库配置](https://certd.docmirror.cn/guide/install/database/)
|
||||||
* 证书续期:
|
* 站点安全:[站点安全特性](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
* 更新日志:[CHANGELOG](./CHANGELOG.md)
|
||||||
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
|
||||||
* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
|
||||||
* 设置每天自动运行,当证书过期前35天,会自动重新申请证书并部署
|
|
||||||
|
|
||||||
|
|
||||||
## 七、不同平台的设置说明
|
## 七、联系作者
|
||||||
|
|
||||||
* 已迁移到新的文档网站,请到常见问题章节查看
|
|
||||||
* [最新文档站链接 https://certd.docmirror.cn](https://certd.docmirror.cn/)
|
|
||||||
|
|
||||||
## 八、问题处理
|
|
||||||
### 7.1 忘记管理员密码
|
|
||||||
[重置管理员密码方法](https://certd.docmirror.cn/guide/use/forgotpasswd/)
|
|
||||||
|
|
||||||
## 九、联系作者
|
|
||||||
如有疑问,欢迎加入群聊(请备注certd)
|
如有疑问,欢迎加入群聊(请备注certd)
|
||||||
|
|
||||||
| 加群 | 微信群 | QQ群 |
|
| 加群 | 微信群 | QQ群 |
|
||||||
@@ -141,7 +150,7 @@ docker compose up -d
|
|||||||
| 二维码 | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
| 二维码 | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
||||||
|
|
||||||
|
|
||||||
## 十、捐赠
|
## 八、捐赠
|
||||||
************************
|
************************
|
||||||
支持开源,为爱发电,我已入驻爱发电
|
支持开源,为爱发电,我已入驻爱发电
|
||||||
https://afdian.com/a/greper
|
https://afdian.com/a/greper
|
||||||
@@ -150,47 +159,44 @@ https://afdian.com/a/greper
|
|||||||
1. 可加入发电专属群,可以获得作者一对一技术支持
|
1. 可加入发电专属群,可以获得作者一对一技术支持
|
||||||
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
||||||
3. 一年期专业版激活码
|
3. 一年期专业版激活码
|
||||||
4. 赠送国外免费服务器部署方案(0成本使用Certd,可能需要翻墙,不过现在性能越来越差了)
|
|
||||||
|
|
||||||
|
|
||||||
专业版特权对比
|
专业版特权对比
|
||||||
|
|
||||||
| 功能 | 免费版 | 专业版 |
|
| 功能 | 免费版 | 专业版 |
|
||||||
|---------|-------------------|-----------------------|
|
|---------|---------------------------------------|--------------------------------|
|
||||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||||
| 自动部署插件 | 阿里云、腾讯云、七牛云、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
| 域名数量 | 无限制 | 无限制 |
|
||||||
| 发邮件功能 | 需要配置 | 免配置 |
|
| 证书流水线条数 | 无限制 | 无限制 |
|
||||||
| 证书流水线条数 | 10条 | 无限制 |
|
| 站点证书监控 | 限制1条 | 无限制 |
|
||||||
|
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署、宝塔、1Panel等大部分插件 | 群晖 |
|
||||||
|
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、钉钉、飞书、anpush、server酱等 |
|
||||||
|
|
||||||
|
|
||||||
************************
|
************************
|
||||||
|
|
||||||
## 十一、贡献代码
|
## 九、贡献代码
|
||||||
|
|
||||||
1. 本地开发 [贡献插件](https://certd.docmirror.cn/guide/development/)
|
1. 本地开发请参考 [贡献插件向导](https://certd.docmirror.cn/guide/development/)
|
||||||
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
2. 作为贡献者,代表您同意您贡献的代码如下许可:
|
||||||
1. 可以调整开源协议以使其更严格或更宽松。
|
1. 可以调整开源协议以使其更严格或更宽松。
|
||||||
2. 可以用于商业用途。
|
2. 可以用于商业用途。
|
||||||
|
|
||||||
|
感谢以下贡献者做出的贡献。
|
||||||
|
|
||||||
|
<a href="https://github.com/certd/certd/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
||||||
|
</a>
|
||||||
|
|
||||||
## 十二、 开源许可
|
## 十、 开源许可
|
||||||
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
* 本项目遵循 GNU Affero General Public License(AGPL)开源协议。
|
||||||
* 允许个人和公司内部自由使用、复制、修改和分发本项目,未获得商业授权情况下禁止任何形式的商业用途
|
* 允许个人和公司内部自由使用、复制、修改和分发本项目,未获得商业授权情况下禁止任何形式的商业用途
|
||||||
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
* 未获得商业授权情况下,禁止任何对logo、版权信息及授权许可相关代码的修改。
|
||||||
* 如需商业授权,请联系作者。
|
* 如需商业授权,请联系作者。
|
||||||
|
|
||||||
## 十三、我的其他项目(求Star)
|
|
||||||
|
## 十一、我的其他项目(求Star)
|
||||||
|
|
||||||
| 项目名称 | stars | 项目描述 |
|
| 项目名称 | stars | 项目描述 |
|
||||||
|---------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-----------------------------------|
|
| --------- |--------- |----------- |
|
||||||
| [袖手AI](https://ai.handsfree.work/) | | 袖手GPT,国内可用,无需FQ,每日免费额度 |
|
|
||||||
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | 基于vue3的crud快速开发框架 |
|
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | 基于vue3的crud快速开发框架 |
|
||||||
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | 直连访问github工具,无需FQ,解决github无法访问的问题 |
|
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | 直连访问github工具,无需FQ,解决github无法访问的问题 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 十四、更新日志
|
|
||||||
|
|
||||||
更新日志:[CHANGELOG](./CHANGELOG.md)
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
# Certd
|
||||||
|
|
||||||
|
[中文](./README.md) | English
|
||||||
|
|
||||||
|
Certd® is a free, fully automated certificate management system that ensures your website certificates never expire. The suffix 'd' is inspired by the naming convention of Linux daemons, representing a certificate daemon.
|
||||||
|
|
||||||
|
> We pioneered the pipeline-based certificate application and deployment model, which has been "referenced" by multiple projects. Being copied is also a form of success.
|
||||||
|
|
||||||
|
> Regarding certificate renewal:
|
||||||
|
>* In fact, it's impossible to renew or reissue a certificate without modifying the certificate file itself.
|
||||||
|
>* What we refer to as renewal is essentially applying for a new certificate following the full process and redeploying it.
|
||||||
|
>* Free certificates expire in 90 days, which may be shortened in the future. Therefore, automated deployment is essential.
|
||||||
|
|
||||||
|
> The number of pipelines is now unlimited. Welcome to use it.
|
||||||
|
|
||||||
|
## 1. Features
|
||||||
|
This project not only supports automated certificate application but also automated certificate deployment and updates, ensuring your certificates never expire.
|
||||||
|
|
||||||
|
* Fully automated certificate application (supports domains registered with all registrars and multiple domain verification methods such as DNS-01, HTTP-01, and CNAME proxy).
|
||||||
|
* Fully automated certificate deployment and updates (currently supports deployment to over 70 plugins, including hosts, Alibaba Cloud, Tencent Cloud, etc.).
|
||||||
|
* Supports wildcard domains/pan-domains, allows multiple domains in a single certificate, and supports various certificate formats such as pem, pfx, der, and jks.
|
||||||
|
* Multiple notification methods, including email, webhook, WeChat Work, DingTalk, Lark, and anpush.
|
||||||
|
* On-premises deployment, local data storage, simple and quick installation. Images are built by Github Actions, with a transparent process.
|
||||||
|
* Multiple security measures, including authorization encryption, site hiding, 2FA, and password brute-force protection.
|
||||||
|
* Supports multiple databases such as SQLite, PostgreSQL, and MySQL.
|
||||||
|
* Open API support.
|
||||||
|
* Site certificate monitoring.
|
||||||
|
* Multi-user management.
|
||||||
|
* Multi-language support (Chinese and English switching).
|
||||||
|
* Downward compatibility across all versions, with one-click worry-free upgrades.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 2. Online Experience
|
||||||
|
Visit the official demo site and register to experience it.
|
||||||
|
|
||||||
|
https://certd.handfree.work/
|
||||||
|
|
||||||
|
> Note: Data will be cleaned up irregularly, and scheduled tasks may be stopped. For production use, please deploy it yourself.
|
||||||
|
> The content contains sensitive information. Make sure to deploy it locally for production use.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 3. Usage Tutorial
|
||||||
|
Just 3 steps to ensure your certificates never expire.
|
||||||
|
|
||||||
|
### 1. Create a Certificate Pipeline
|
||||||
|

|
||||||
|
|
||||||
|
> After successful addition, you can directly run the pipeline to apply for a certificate.
|
||||||
|
|
||||||
|
### 2. Add a Deployment Task
|
||||||
|
Normally, we need to deploy certificates to applications. Certd supports a wide range of deployment plugins. You can choose based on your needs, such as deploying to Nginx, Alibaba Cloud, Tencent Cloud, K8S, CDN, Baota, 1Panel, etc.
|
||||||
|
|
||||||
|
Here's a demonstration of deploying certificates to a host's Nginx:
|
||||||
|

|
||||||
|
|
||||||
|
If the current deployment plugins don't meet your needs, you can also download them manually and deploy them yourself.
|
||||||
|

|
||||||
|
|
||||||
|
### 3. Run Scheduled Tasks
|
||||||
|

|
||||||
|
|
||||||
|
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||||
|
-------> [Click here to view detailed usage steps](./step.md) <--------
|
||||||
|
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||||
|
|
||||||
|
For more tutorials, please visit the official documentation [certd.docmirror.cn](https://certd.docmirror.cn/guide/).
|
||||||
|
|
||||||
|
## 4. On-Premises Deployment
|
||||||
|
Since certificates, authorization information, and other data are highly sensitive, please make sure to deploy them on-premises to ensure data security.
|
||||||
|
|
||||||
|
You can choose one of the following deployment methods based on your needs:
|
||||||
|
|
||||||
|
1. 【Recommended】[Docker Deployment](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
|
2. 【Recommended】[BT Panel Deployment](https://certd.docmirror.cn/guide/install/docker/)
|
||||||
|
3. 【Recommended】[1Panel Deployment](https://certd.docmirror.cn/guide/install/1panel/)
|
||||||
|
4. 【Recommended】[Rainyun One-Click Deployment](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_): Double your first recharge, only $2.2 per month.
|
||||||
|
[<img src="https://rainyun-apps.cn-nb1.rains3.com/materials/deploy-on-rainyun-cn.svg">](https://app.rainyun.com/apps/rca/store/6646/?ref=NzExMDQ2_)
|
||||||
|
5. 【Not Recommended】[Source Code Deployment](https://certd.docmirror.cn/guide/install/source/)
|
||||||
|
|
||||||
|
#### Docker Image Information:
|
||||||
|
* Domestic Image Addresses:
|
||||||
|
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest`
|
||||||
|
* `registry.cn-shenzhen.aliyuncs.com/handsfree/certd:armv7`, `[version]-armv7`
|
||||||
|
* DockerHub Addresses:
|
||||||
|
* `https://hub.docker.com/r/greper/certd`
|
||||||
|
* `greper/certd:latest`
|
||||||
|
* `greper/certd:armv7`, `greper/certd:[version]-armv7`
|
||||||
|
* GitHub Packages Addresses:
|
||||||
|
* `ghcr.io/certd/certd:latest`
|
||||||
|
* `ghcr.io/certd/certd:armv7`, `ghcr.io/certd/certd:[version]-armv7`
|
||||||
|
|
||||||
|
* Images are built automatically by `Actions`, with a transparent process. Please use them with confidence.
|
||||||
|
* [Click here to view image build logs](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> Note:
|
||||||
|
> * The certificates, authorization information, and other data stored in this application are highly sensitive. Please take appropriate security measures.
|
||||||
|
> * Make sure to use the HTTPS protocol to access this application to avoid man-in-the-middle attacks.
|
||||||
|
> * Make sure to use a web application firewall to protect this application from attacks such as XSS and SQL injection.
|
||||||
|
> * Make sure to secure the server itself to prevent database leakage.
|
||||||
|
> * Make sure to back up your data to avoid data loss.
|
||||||
|
> * [Click here for more production safety suggestions](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
|
|
||||||
|
## 5. Ecosystem
|
||||||
|
|
||||||
|
### 1. Client Tool: SSL-Assistant
|
||||||
|
`SSL Assistant` is a certificate deployment and management assistant client that runs on hosts. It supports automatic scanning of the host's `Nginx` configuration and pulling certificates from `Certd` for deployment. This tool is very useful when you don't want to expose your SSH host password.
|
||||||
|
|
||||||
|
Open-source Address: https://github.com/Youngxj/SSL-Assistant
|
||||||
|
|
||||||
|
## 6. More Help
|
||||||
|
Please visit the official documentation: [https://certd.docmirror.cn/](https://certd.docmirror.cn/guide/).
|
||||||
|
|
||||||
|
* Upgrade Method: [Upgrade Guide](https://certd.docmirror.cn/guide/install/upgrade/)
|
||||||
|
* Common Issues: [Forgot Password](https://certd.docmirror.cn/guide/use/forgotpasswd/)
|
||||||
|
* Multi-Database: [Multi-Database Configuration](https://certd.docmirror.cn/guide/install/database/)
|
||||||
|
* Site Security: [Site Security Features](https://certd.docmirror.cn/guide/feature/safe/)
|
||||||
|
* Changelog: [CHANGELOG](./CHANGELOG.md)
|
||||||
|
|
||||||
|
## 7. Contact the Author
|
||||||
|
If you have any questions, feel free to join the group chat (please mention 'certd' in your message).
|
||||||
|
|
||||||
|
| Join Group | WeChat Group | QQ Group |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| QR Code | <img height="230" src="./docs/guide/contact/images/wx.png"> | <img height="230" src="./docs/guide/contact/images/qq.png"> |
|
||||||
|
|
||||||
|
You can also add the author as a friend.
|
||||||
|
|
||||||
|
| Add Author as Friend | WeChat QQ |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| QR Code | <img height="230" src="./docs/guide/contact/images/me.png"> |
|
||||||
|
|
||||||
|
## 8. Donation
|
||||||
|
************************
|
||||||
|
Support open-source projects and contribute with love. I've joined Afdian.
|
||||||
|
https://afdian.com/a/greper
|
||||||
|
|
||||||
|
Benefits of Contribution:
|
||||||
|
1. Join the exclusive contributor group and get one-on-one technical support from the author.
|
||||||
|
2. Your requests will be prioritized and implemented as professional edition features.
|
||||||
|
3. Receive a one-year professional edition activation code.
|
||||||
|
|
||||||
|
Comparison of Professional Edition Privileges:
|
||||||
|
|
||||||
|
| Feature | Free Edition | Professional Edition |
|
||||||
|
|---------|---------------------------------------|--------------------------------|
|
||||||
|
| Free Certificate Application | Unlimited for free | Unlimited for free |
|
||||||
|
| Number of Domains | Unlimited | Unlimited |
|
||||||
|
| Number of Certificate Pipelines | Unlimited | Unlimited |
|
||||||
|
| Site Certificate Monitoring | Limited to 1 | Unlimited |
|
||||||
|
| Automatic Deployment Plugins | Most plugins such as Alibaba Cloud CDN, Tencent Cloud, QiNiu CDN, Host Deployment, Baota, 1Panel | Synology |
|
||||||
|
| Notifications | Email, Custom Webhook | Email without configuration, WeChat Work, DingTalk, Lark, anpush, ServerChan, etc. |
|
||||||
|
|
||||||
|
************************
|
||||||
|
|
||||||
|
## 9. Contribute Code
|
||||||
|
|
||||||
|
1. For local development, please refer to the [Plugin Contribution Guide](https://certd.docmirror.cn/guide/development/).
|
||||||
|
2. As a contributor, you agree that your contributed code is subject to the following license:
|
||||||
|
1. The open-source license can be adjusted to be more or less restrictive.
|
||||||
|
2. It can be used for commercial purposes.
|
||||||
|
|
||||||
|
Thank you to the following contributors.
|
||||||
|
|
||||||
|
<a href="https://github.com/certd/certd/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=certd/certd" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## 10. Open-Source License
|
||||||
|
* This project follows the GNU Affero General Public License (AGPL).
|
||||||
|
* Individuals and companies are allowed to use, copy, modify, and distribute this project freely for internal use. Any form of commercial use is prohibited without obtaining commercial authorization.
|
||||||
|
* Without commercial authorization, any modification of the logo, copyright information, and license-related code is prohibited.
|
||||||
|
* For commercial authorization, please contact the author.
|
||||||
|
|
||||||
|
## 11. My Other Projects (Please Star)
|
||||||
|
|
||||||
|
| Project Name | Stars | Project Description |
|
||||||
|
|----------------|---------------|--------------|
|
||||||
|
| [fast-crud](https://gitee.com/fast-crud/fast-crud/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/fast-crud/fast-crud?logo=github"/> | A fast CRUD development framework based on Vue3. |
|
||||||
|
| [dev-sidecar](https://github.com/docmirror/dev-sidecar/) | <img alt="GitHub stars" src="https://img.shields.io/github/stars/docmirror/dev-sidecar?logo=github"/> | A tool to access GitHub directly without a VPN, solving the problem of inaccessible GitHub. |
|
||||||
@@ -1 +1 @@
|
|||||||
1
|
2
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
21:55
|
00:34
|
||||||
|
|||||||
@@ -1,40 +1,57 @@
|
|||||||
version: '3.3' # 兼容旧版docker-compose
|
version: '3.3' # 兼容旧版docker-compose
|
||||||
services:
|
services:
|
||||||
certd:
|
certd:
|
||||||
# 镜像 # ↓↓↓↓↓ ---- 镜像版本号,建议改成固定版本号
|
# 镜像 # ↓↓↓↓↓ ---- 镜像版本号,建议改成固定版本号,例如:certd:1.29.0
|
||||||
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||||
|
# image: ghcr.io/certd/certd:latest # --------- 如果 报镜像not found,可以尝试其他镜像源
|
||||||
|
# image: greper/certd:latest
|
||||||
container_name: certd # 容器名
|
container_name: certd # 容器名
|
||||||
restart: unless-stopped # 自动重启
|
restart: unless-stopped # 自动重启
|
||||||
volumes:
|
volumes:
|
||||||
# ↓↓↓↓↓ -------------------------------------------------------- 数据库以及证书存储路径,默认存在宿主机的/data/certd/目录下,【您需要定时备份此目录,以保障数据容灾】
|
# ↓↓↓↓↓ -------------------------------------------------------- 数据库以及证书存储路径,默认存在宿主机的/data/certd/目录下,【您需要定时备份此目录,以保障数据容灾】
|
||||||
|
# 只要修改冒号前面的,冒号后面的/app/data不要动
|
||||||
- /data/certd:/app/data
|
- /data/certd:/app/data
|
||||||
|
# ↓↓↓↓↓ -------------------------------------------------------- 如果走时不准,考虑挂载localtime文件
|
||||||
|
#- /etc/localtime:/etc/localtime
|
||||||
|
#- /etc/timezone:/etc/timezone
|
||||||
ports: # 端口映射
|
ports: # 端口映射
|
||||||
# ↓↓↓↓ ---------------------------------------------------------- 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号
|
# ↓↓↓↓ ---------------------------------------------------------- 如果端口有冲突,可以修改第一个7001为其他不冲突的端口号,第二个7001不要动
|
||||||
- "7001:7001"
|
- "7001:7001"
|
||||||
# ↓↓↓↓ ---------------------------------------------------------- https端口,可以根据实际情况,是否暴露该端口
|
# ↓↓↓↓ ---------------------------------------------------------- https端口,可以根据实际情况,是否暴露该端口
|
||||||
- "7002:7002"
|
- "7002:7002"
|
||||||
#↓↓↓↓ -------------------------------------------------------------- 如果出现getaddrinfo ENOTFOUND错误,可以尝试设置dns
|
#↓↓↓↓ -------------------------------------------------------------- 如果出现getaddrinfo EAI_AGAIN 或 getaddrinfo ENOTFOUND 错误,可以尝试设置dns
|
||||||
dns:
|
# dns:
|
||||||
- 223.5.5.5 # 阿里云公共dns
|
# - 223.5.5.5 # 阿里云公共dns
|
||||||
- 223.6.6.6
|
# - 223.6.6.6
|
||||||
# # ↓↓↓↓ --------------------------------------------------------- 如果你服务器在腾讯云,可以用这个替换上面阿里云的公共dns
|
# # ↓↓↓↓ --------------------------------------------------------- 如果你服务器在腾讯云,可以用这个替换上面阿里云的公共dns
|
||||||
# - 119.29.29.29 # 腾讯云公共dns
|
# - 119.29.29.29 # 腾讯云公共dns
|
||||||
# - 182.254.116.116
|
# - 182.254.116.116
|
||||||
# # ↓↓↓↓ --------------------------------------------------------- 如果你服务器部署在国外,可以用这个替换上面阿里云的公共dns
|
# # ↓↓↓↓ --------------------------------------------------------- 如果你服务器部署在国外,可以用这个替换上面阿里云的公共dns
|
||||||
# - 8.8.8.8 # 谷歌公共dns
|
# - 8.8.8.8 # 谷歌公共dns
|
||||||
# - 8.8.4.4
|
# - 8.8.4.4
|
||||||
|
|
||||||
# extra_hosts:
|
# extra_hosts:
|
||||||
# # ↓↓↓↓ -------------------------------------------------------- 这里可以配置自定义hosts,外网域名可以指向本地局域网ip地址
|
# # ↓↓↓↓ -------------------------------------------------------- 这里可以配置自定义hosts,外网域名可以指向本地局域网ip地址
|
||||||
# - "localdomain.comm:192.168.1.3"
|
# - "localdomain.com:192.168.1.3"
|
||||||
|
# # ↓↓↓↓ ------------------------------------------------ 直接使用主机的网络,如果网络问题实在找不到原因,可以尝试打开此参数
|
||||||
|
# network_mode: host
|
||||||
|
labels:
|
||||||
|
com.centurylinklabs.watchtower.enable: "true"
|
||||||
|
# ↓↓↓↓ -------------------------------------------------------------- 启用ipv6网络,还需要把下面networks的注释放开
|
||||||
|
# networks:
|
||||||
|
# - ip6net
|
||||||
environment:
|
environment:
|
||||||
|
# ↓↓↓↓ ----------------------------------------------------- 使用上海东八时区
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
# 设置环境变量即可自定义certd配置
|
# 设置环境变量即可自定义certd配置
|
||||||
# 配置项见: packages/ui/certd-server/src/config/config.default.ts
|
# 配置项见: packages/ui/certd-server/src/config/config.default.ts
|
||||||
# 配置规则: certd_ + 配置项, 点号用_代替
|
# 配置规则: certd_ + 配置项, 点号用_代替
|
||||||
# #↓↓↓↓ ----------------------------- 如果忘记管理员密码,可以设置为true,重启之后,管理员密码将改成123456,然后请及时修改回false
|
# #↓↓↓↓ ----------------------------- 如果忘记管理员密码,可以设置为true,docker compose up -d 重建容器之后,管理员密码将改成123456,然后请及时修改回false
|
||||||
- certd_system_resetAdminPasswd=false
|
- certd_system_resetAdminPasswd=false
|
||||||
# #↓↓↓↓ ----------------------------- 使用postgresql数据库
|
|
||||||
|
# 默认使用sqlite文件数据库,如果需要使用其他数据库,请设置以下环境变量
|
||||||
|
# 注意: 选定使用一种数据库之后,不支持更换数据库。
|
||||||
|
# 数据库迁移方法:1、使用新数据库重新部署一套,然后将旧数据同步过去,注意flyway_history表的数据不要同步
|
||||||
|
# #↓↓↓↓ ----------------------------- 使用postgresql数据库,需要提前创建数据库
|
||||||
# - certd_flyway_scriptDir=./db/migration-pg # 升级脚本目录
|
# - certd_flyway_scriptDir=./db/migration-pg # 升级脚本目录
|
||||||
# - certd_typeorm_dataSource_default_type=postgres # 数据库类型
|
# - certd_typeorm_dataSource_default_type=postgres # 数据库类型
|
||||||
# - certd_typeorm_dataSource_default_host=localhost # 数据库地址
|
# - certd_typeorm_dataSource_default_host=localhost # 数据库地址
|
||||||
@@ -43,9 +60,31 @@ services:
|
|||||||
# - certd_typeorm_dataSource_default_password=yourpasswd # 密码
|
# - certd_typeorm_dataSource_default_password=yourpasswd # 密码
|
||||||
# - certd_typeorm_dataSource_default_database=certd # 数据库名
|
# - certd_typeorm_dataSource_default_database=certd # 数据库名
|
||||||
|
|
||||||
# #↓↓↓↓ ------------------------------------------------------------- 启用ipv6网络
|
# #↓↓↓↓ ----------------------------- 使用mysql数据库,需要提前创建数据库 charset=utf8mb4, collation=utf8mb4_bin
|
||||||
# networks:
|
# - certd_flyway_scriptDir=./db/migration-mysql # 升级脚本目录
|
||||||
# - ip6net
|
# - certd_typeorm_dataSource_default_type=mysql # 数据库类型, 或者 mariadb
|
||||||
|
# - certd_typeorm_dataSource_default_host=localhost # 数据库地址
|
||||||
|
# - certd_typeorm_dataSource_default_port=3306 # 数据库端口
|
||||||
|
# - certd_typeorm_dataSource_default_username=root # 用户名
|
||||||
|
# - certd_typeorm_dataSource_default_password=yourpasswd # 密码
|
||||||
|
# - certd_typeorm_dataSource_default_database=certd # 数据库名
|
||||||
|
|
||||||
|
# ↓↓↓↓ --------------------------------------------------------- 自动升级,上面certd的版本号要保持为latest
|
||||||
|
# certd-updater: # 添加 Watchtower 服务
|
||||||
|
# image: containrrr/watchtower:latest
|
||||||
|
# container_name: certd-updater
|
||||||
|
# restart: unless-stopped
|
||||||
|
# volumes:
|
||||||
|
# - /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
# # 配置 自动更新
|
||||||
|
# environment:
|
||||||
|
# - WATCHTOWER_CLEANUP=true # 自动清理旧版本容器
|
||||||
|
# - WATCHTOWER_INCLUDE_STOPPED=false # 不更新已停止的容器
|
||||||
|
# - WATCHTOWER_LABEL_ENABLE=true # 根据容器标签进行更新
|
||||||
|
# - WATCHTOWER_POLL_INTERVAL=600 # 每 10 分钟检查一次更新
|
||||||
|
|
||||||
|
|
||||||
|
# ↓↓↓↓ -------------------------------------------------------------- 启用ipv6网络,还需要把上面networks的注释放开
|
||||||
#networks:
|
#networks:
|
||||||
# ip6net:
|
# ip6net:
|
||||||
# enable_ipv6: true
|
# enable_ipv6: true
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import lightbox from "vitepress-plugin-lightbox";
|
|||||||
// https://vitepress.dev/reference/site-config
|
// https://vitepress.dev/reference/site-config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
title: "Certd",
|
title: "Certd",
|
||||||
|
titleTemplate: "开源SSL证书管理工具,证书自动化申请部署,让你的网站证书永不过期",
|
||||||
description: "Certd帮助文档,Certd是一款开源免费的全自动SSL证书管理工具;证书自动化申请部署流水线;自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔。",
|
description: "Certd帮助文档,Certd是一款开源免费的全自动SSL证书管理工具;证书自动化申请部署流水线;自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔。",
|
||||||
markdown: {
|
markdown: {
|
||||||
config: (md) => {
|
config: (md) => {
|
||||||
@@ -12,6 +13,9 @@ export default defineConfig({
|
|||||||
md.use(lightbox, {});
|
md.use(lightbox, {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
sitemap: {
|
||||||
|
hostname: 'https://certd.docmirror.cn'
|
||||||
|
},
|
||||||
head: [
|
head: [
|
||||||
// [
|
// [
|
||||||
// 'meta',
|
// 'meta',
|
||||||
@@ -25,9 +29,9 @@ export default defineConfig({
|
|||||||
name: "keywords",
|
name: "keywords",
|
||||||
content: "证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具、Certd、SSL证书自动部署、证书自动化,https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署,SSL平台,证书管理平台,证书流水线"
|
content: "证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具、Certd、SSL证书自动部署、证书自动化,https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署,SSL平台,证书管理平台,证书流水线"
|
||||||
}],
|
}],
|
||||||
["meta", { name: "google-site-verification",content: "V5XLTSnXoT15uQotwpxJoQolUo2d5UbSL-TacsyOsC0"}],
|
// ["meta", { name: "google-site-verification",content: "V5XLTSnXoT15uQotwpxJoQolUo2d5UbSL-TacsyOsC0"}],
|
||||||
//<meta name="baidu-site-verification" content="codeva-MiWN8Y07Ua" />
|
//<meta name="baidu-site-verification" content="codeva-MiWN8Y07Ua" />
|
||||||
["meta", {name: "baidu-site-verification",content: "codeva-MiWN8Y07Ua"}],
|
// ["meta", {name: "baidu-site-verification",content: "codeva-MiWN8Y07Ua"}],
|
||||||
["link", {rel: "icon", href: "/static/logo/logo.svg"}]
|
["link", {rel: "icon", href: "/static/logo/logo.svg"}]
|
||||||
],
|
],
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
@@ -76,20 +80,33 @@ export default defineConfig({
|
|||||||
{text: "源码部署", link: "/guide/install/source/"}
|
{text: "源码部署", link: "/guide/install/source/"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ text: "演示教程", link: "/guide/tutorial.md" }
|
{text: "演示教程", link: "/guide/tutorial.md"},
|
||||||
|
{text: "版本升级", link: "/guide/install/upgrade.md"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "特性",
|
text: "特性",
|
||||||
items: [
|
items: [
|
||||||
{text: "CNAME代理校验", link: "/guide/feature/cname/index.md"},
|
{text: "CNAME代理校验", link: "/guide/feature/cname/index.md"},
|
||||||
{ text: "插件列表", link: "/guide/plugins.md" }
|
{text: "多数据库支持", link: "/guide/install/database.md"},
|
||||||
|
{text: "开放接口", link: "/guide/open/index.md"},
|
||||||
|
{
|
||||||
|
text: "站点安全", link: "/guide/feature/safe/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "插件列表", items: [
|
||||||
|
{text: "授权提供商", link: "/guide/plugins/access.md"},
|
||||||
|
{text: "DNS提供商", link: "/guide/plugins/dns-provider.md"},
|
||||||
|
{text: "任务插件", link: "/guide/plugins/deploy.md"},
|
||||||
|
{text: "通知插件", link: "/guide/plugins/notification.md"},
|
||||||
|
]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "常见问题",
|
text: "常见问题",
|
||||||
items: [
|
items: [
|
||||||
|
{text: "QA", link: "/guide/qa/use.md"},
|
||||||
{text: "群晖证书部署", link: "/guide/use/synology/"},
|
{text: "群晖证书部署", link: "/guide/use/synology/"},
|
||||||
{text: "腾讯云密钥获取", link: "/guide/use/tencent/"},
|
{text: "腾讯云密钥获取", link: "/guide/use/tencent/"},
|
||||||
{text: "连接windows主机", link: "/guide/use/host/windows.md"},
|
{text: "连接windows主机", link: "/guide/use/host/windows.md"},
|
||||||
@@ -101,23 +118,32 @@ export default defineConfig({
|
|||||||
{text: "js脚本插件使用", link: "/guide/use/custom-script/index.md"},
|
{text: "js脚本插件使用", link: "/guide/use/custom-script/index.md"},
|
||||||
{text: "邮箱配置", link: "/guide/use/email/index.md"},
|
{text: "邮箱配置", link: "/guide/use/email/index.md"},
|
||||||
{text: "IPv6支持", link: "/guide/use/setting/ipv6.md"},
|
{text: "IPv6支持", link: "/guide/use/setting/ipv6.md"},
|
||||||
{ text: "如何贡献代码", link: "/guide/development/index.md" },
|
{text: "ESXi", link: "/guide/use/ESXi/index.md"},
|
||||||
|
{text: "子域名托管", link: "/guide/use/cert/subdomain.md"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "商业版配置", link: "/guide/use/comm/", items: [
|
||||||
|
{text: "支付宝配置", link: "/guide/use/comm/payments/alipay.md"},
|
||||||
|
{text: "微信支付配置", link: "/guide/use/comm/payments/wxpay.md"},
|
||||||
|
{text: "彩虹易支付配置", link: "/guide/use/comm/payments/yizhifu.md"},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "其他",
|
text: "其他",
|
||||||
items: [
|
items: [
|
||||||
|
{text: "贡献代码", link: "/guide/development/index.md"},
|
||||||
{text: "更新日志", link: "/guide/changelogs/CHANGELOG.md"},
|
{text: "更新日志", link: "/guide/changelogs/CHANGELOG.md"},
|
||||||
{text: "镜像说明", link: "/guide/image.md"},
|
{text: "镜像说明", link: "/guide/image.md"},
|
||||||
{text: "联系我们", link: "/guide/contact/"},
|
{text: "联系我们", link: "/guide/contact/"},
|
||||||
{text: "捐赠", link: "/guide/donate/"},
|
{text: "捐赠", link: "/guide/donate/"},
|
||||||
{text: "开源协议", link: "/guide/license/"},
|
{text: "开源协议", link: "/guide/license/"},
|
||||||
{text: "我的其他开源项目", link: "/guide/link/"},
|
{text: "我的其他开源项目", link: "/guide/link/"},
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{icon: "github", link: "https://github.com/certd/certd"}
|
{icon: "github", link: "https://github.com/certd/certd"}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
# 授权插件Demo
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { AccessInput, BaseAccess, IsAccess } from '@certd/pipeline';
|
||||||
|
import { isDev } from '../../utils/env.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这个注解将注册一个授权配置
|
||||||
|
* 在certd的后台管理系统中,用户可以选择添加此类型的授权
|
||||||
|
*/
|
||||||
|
@IsAccess({
|
||||||
|
name: 'demo',
|
||||||
|
title: '授权插件示例',
|
||||||
|
icon: 'clarity:plugin-line',
|
||||||
|
desc: '',
|
||||||
|
})
|
||||||
|
export class DemoAccess extends BaseAccess {
|
||||||
|
/**
|
||||||
|
* 授权属性配置
|
||||||
|
*/
|
||||||
|
@AccessInput({
|
||||||
|
title: '密钥Id',
|
||||||
|
component: {
|
||||||
|
placeholder: 'demoKeyId',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
demoKeyId = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权属性配置
|
||||||
|
*/
|
||||||
|
@AccessInput({
|
||||||
|
//标题
|
||||||
|
title: '密钥串',
|
||||||
|
component: {
|
||||||
|
//input组件的placeholder
|
||||||
|
placeholder: 'demoKeySecret',
|
||||||
|
},
|
||||||
|
//是否必填
|
||||||
|
required: true,
|
||||||
|
//改属性是否需要加密
|
||||||
|
encrypt: true,
|
||||||
|
})
|
||||||
|
//属性名称
|
||||||
|
demoKeySecret = '';
|
||||||
|
}
|
||||||
|
new DemoAccess();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# 阿里云授权
|
||||||
|
```ts
|
||||||
|
|
||||||
|
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||||
|
|
||||||
|
@IsAccess({
|
||||||
|
name: "aliyun",
|
||||||
|
title: "阿里云授权",
|
||||||
|
desc: "",
|
||||||
|
icon: "ant-design:aliyun-outlined",
|
||||||
|
order: 0,
|
||||||
|
})
|
||||||
|
export class AliyunAccess extends BaseAccess {
|
||||||
|
@AccessInput({
|
||||||
|
title: "accessKeyId",
|
||||||
|
component: {
|
||||||
|
placeholder: "accessKeyId",
|
||||||
|
},
|
||||||
|
helper: "登录阿里云控制台->AccessKey管理页面获取。",
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
accessKeyId = "";
|
||||||
|
@AccessInput({
|
||||||
|
title: "accessKeySecret",
|
||||||
|
component: {
|
||||||
|
placeholder: "accessKeySecret",
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
encrypt: true,
|
||||||
|
helper: "注意:证书申请需要dns解析权限;其他阿里云插件,需要对应的权限,比如证书上传需要证书管理权限;嫌麻烦就用主账号的全量权限的accessKey",
|
||||||
|
})
|
||||||
|
accessKeySecret = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
new AliyunAccess();
|
||||||
|
```
|
||||||
@@ -14,9 +14,6 @@ git clone https://github.com/certd/certd --depth=1
|
|||||||
#进入项目目录
|
#进入项目目录
|
||||||
cd certd
|
cd certd
|
||||||
|
|
||||||
# 切换到最新版本代码【如果v2分支无法编译,请尝试切换到最新版tag】
|
|
||||||
# git checkout v1.27.0 # 这里换成最新版本号
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 修改pnpm-workspace.yaml文件
|
### 修改pnpm-workspace.yaml文件
|
||||||
@@ -31,7 +28,7 @@ packages:
|
|||||||
### 安装依赖和初始化:
|
### 安装依赖和初始化:
|
||||||
```shell
|
```shell
|
||||||
# 安装pnpm,如果提示npm命令不存在,就需要先安装nodejs
|
# 安装pnpm,如果提示npm命令不存在,就需要先安装nodejs
|
||||||
npm install -g pnpm@8.15.7 --registry=https://registry.npmmirror.com
|
npm install -g pnpm--registry=https://registry.npmmirror.com
|
||||||
|
|
||||||
# 使用国内镜像源,如果有代理,就不需要
|
# 使用国内镜像源,如果有代理,就不需要
|
||||||
pnpm config set registry https://registry.npmmirror.com
|
pnpm config set registry https://registry.npmmirror.com
|
||||||
@@ -39,19 +36,19 @@ pnpm config set registry https://registry.npmmirror.com
|
|||||||
pnpm install
|
pnpm install
|
||||||
|
|
||||||
# 初始化构建
|
# 初始化构建
|
||||||
npm run init
|
pnpm init
|
||||||
```
|
```
|
||||||
|
|
||||||
### 启动 server:
|
### 启动 server:
|
||||||
```shell
|
```shell
|
||||||
cd packages/ui/certd-server
|
cd packages/ui/certd-server
|
||||||
npm run dev
|
pnpm dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### 启动 client:
|
### 启动 client:
|
||||||
```shell
|
```shell
|
||||||
cd packages/ui/certd-client
|
cd packages/ui/certd-client
|
||||||
npm run dev
|
pnpm dev
|
||||||
|
|
||||||
# 会自动打开浏览器,确认正常运行
|
# 会自动打开浏览器,确认正常运行
|
||||||
|
|
||||||
@@ -109,4 +106,4 @@ throw new Error("错误信息")
|
|||||||
## 五、贡献插件送激活码
|
## 五、贡献插件送激活码
|
||||||
|
|
||||||
- PR要求,插件功能完整,代码规范
|
- PR要求,插件功能完整,代码规范
|
||||||
- PR通过后,联系我们,送您一个专业版激活码
|
- PR通过后,联系我们,送您一个半年期专业版激活码
|
||||||
|
After Width: | Height: | Size: 130 KiB |
@@ -7,16 +7,22 @@ https://afdian.com/a/greper
|
|||||||
1. 可加入发电专属群,可以获得作者一对一技术支持
|
1. 可加入发电专属群,可以获得作者一对一技术支持
|
||||||
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
2. 您的需求我们将优先实现,并且将作为专业版功能提供
|
||||||
3. 一年期专业版激活码
|
3. 一年期专业版激活码
|
||||||
4. 赠送国外免费服务器部署方案(0成本使用Certd,可能需要翻墙,不过现在性能越来越差了)
|
|
||||||
|
|
||||||
|
|
||||||
## 专业版特权对比
|
## 专业版特权对比
|
||||||
|
|
||||||
| 功能 | 免费版 | 专业版 |
|
| 功能 | 免费版 | 专业版 |
|
||||||
|---------|------------------------|-----------------------|
|
|---------|------------------------|-----------------------------|
|
||||||
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
| 免费证书申请 | 免费无限制 | 免费无限制 |
|
||||||
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
| 自动部署插件 | 阿里云CDN、腾讯云、七牛CDN、主机部署等 | 支持群晖、宝塔、1Panel等,持续开发中 |
|
||||||
| 发邮件功能 | 需要配置 | 免配置 |
|
| 证书流水线条数 | 无限制 | 无限制 |
|
||||||
| 证书流水线条数 | 10条 | 无限制 |
|
| 站点证书监控 | 限制1条 | 无限制 |
|
||||||
|
| 通知 | 邮件通知、自定义webhook | 邮件免配置、企微、飞书、anpush、server酱等 |
|
||||||
|
|
||||||
|
|
||||||
|
## 专业版激活方式
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
发电后,在私信中获取激活码
|
||||||
************************
|
************************
|
||||||
|
|||||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1,27 @@
|
|||||||
|
# 站点隐藏
|
||||||
|
|
||||||
|
* 一般来说Certd设置好之后,很少需要访问。
|
||||||
|
* 所以我们`平时`可以把`站点访问关闭`,需要的时候再打开,减少站点被攻击的风险
|
||||||
|
|
||||||
|
## 1、开启站点隐藏
|
||||||
|
`系统管理->系统设置->安全设置->站点隐藏 `
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
:::warning
|
||||||
|
|
||||||
|
注意保存好`解除地址`和`解除密码`
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 2、临时关闭站点隐藏
|
||||||
|
|
||||||
|
访问上面的`解除地址`,输入`解除密码`,`临时解除`站点隐藏
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 3、忘记解除地址和解除密码怎么办
|
||||||
|
登录服务器,在数据库平级的目录下创建`.unhidden`命名的空白文件,即可临时解除站点隐藏
|
||||||
|
临时解除后会自动删除`.unhidden`文件,请尽快设置好新的`解除地址`和`解除密码`,并记住
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,49 @@
|
|||||||
|
# 安全特性
|
||||||
|
|
||||||
|
Certd 存储了证书以及授权等敏感数据,所以需要严格保障安全。
|
||||||
|
我们提供了以下安全特性,以及安全生产建议(请遵照建议进行生产部署以保障数据安全)
|
||||||
|
|
||||||
|
## 一、站点安全特性
|
||||||
|
|
||||||
|
### 1、 授权数据加密存储【默认开启】
|
||||||
|
* 所有的授权敏感字段会加密后存储
|
||||||
|
* 每个用户独立维护授权数据,连管理员都无权查看
|
||||||
|
|
||||||
|

|
||||||
|
星号部分为加密数据
|
||||||
|
|
||||||
|
### 2、 密码防爆破【默认开启】
|
||||||
|
* 登录失败次数过多,账号将被锁定,最高24小时(重启服务可解除锁定)
|
||||||
|
* 用户登录密码加密hash后存储,无法计算出密码明文
|
||||||
|

|
||||||
|
|
||||||
|
### 3、站点隐藏【建议开启】
|
||||||
|
* 一般来说Certd设置好之后,后续很少需要访问修改。
|
||||||
|
* 所以我们平时可以把站点访问关闭,需要的时候再打开,减少站点被攻击的风险
|
||||||
|
* 请前往 `系统管理->系统设置->安全设置->开启站点隐藏`
|
||||||
|

|
||||||
|
|
||||||
|
点击查看 [站点隐藏功能详细使用说明](./hidden/)
|
||||||
|
|
||||||
|
|
||||||
|
### 4、登录双重验证
|
||||||
|
|
||||||
|
支持2FA双重认证
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 5、数据库自动备份【建议开启】
|
||||||
|
* [自动备份设置说明](../../use/backup/)
|
||||||
|
|
||||||
|
|
||||||
|
## 二、安全生产建议
|
||||||
|
|
||||||
|
尽管`Cert`本身实现了很多安全特性,但`外部环境的安全`仍需要您来确保。
|
||||||
|
请`务必`遵循如下建议做好安全防护
|
||||||
|
|
||||||
|
* 请`务必`使用`HTTPS协议`访问本应用,避免被中间人攻击
|
||||||
|
* 请`务必`使用`web应用防火墙`防护本应用,防止XSS、SQL注入等攻击
|
||||||
|
* 请`务必`做好`服务器本身`的安全防护,防止数据库泄露
|
||||||
|
* 请`务必`做好[`数据备份`](../../use/backup/),避免数据丢失
|
||||||
|
* 请`务必`修改管理员账号用户名,且建议将admin注册为普通用户,且设置为禁用。
|
||||||
|
* 建议开启[`站点隐藏`](./hidden/)功能
|
||||||
@@ -9,6 +9,10 @@
|
|||||||
* `greper/certd:latest`
|
* `greper/certd:latest`
|
||||||
* `greper/certd:armv7`、`greper/certd:[version]-armv7`
|
* `greper/certd:armv7`、`greper/certd:[version]-armv7`
|
||||||
|
|
||||||
|
## GitHub Packages地址:
|
||||||
|
* `ghcr.io/certd/certd:latest`
|
||||||
|
* `ghcr.io/certd/certd:armv7`、`ghcr.io/certd/certd:[version]-armv7`
|
||||||
|
*
|
||||||
## 镜像构建公开
|
## 镜像构建公开
|
||||||
镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
镜像构建通过`Actions`自动执行,过程公开透明,请放心使用
|
||||||
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
* [点我查看镜像构建日志](https://github.com/certd/certd/actions/workflows/build-image.yml)
|
||||||
|
|||||||
@@ -5,30 +5,28 @@ Certd 是一款开源、免费、全自动申请和部署更新SSL证书的工
|
|||||||
|
|
||||||
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
关键字:证书自动申请、证书自动更新、证书自动续期、证书自动续签、证书管理工具
|
||||||
|
|
||||||
|
## 1、关于证书续期
|
||||||
|
>* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
||||||
|
>* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
||||||
|
>* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
||||||
|
|
||||||
## 一、特性
|
|
||||||
|
## 2、项目特性
|
||||||
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
本项目不仅支持证书申请过程自动化,还可以自动化部署更新证书,让你的证书永不过期。
|
||||||
|
|
||||||
* 全自动申请证书(支持所有注册商注册的域名)
|
* 全自动申请证书(支持所有注册商注册的域名,支持DNS-01、HTTP-01、CNAME代理等多种域名验证方式)
|
||||||
* 全自动部署更新证书(目前支持部署到主机、部署到阿里云、腾讯云等,目前已支持30+部署插件)
|
* 全自动部署更新证书(目前支持部署到主机、阿里云、腾讯云等70+部署插件)
|
||||||
* 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
* 支持通配符域名/泛域名,支持多个域名打到一个证书上,支持pem、pfx、der、jks等多种证书格式
|
||||||
* 邮件通知
|
* 邮件通知、webhook通知、企微、钉钉、飞书、anpush等多种通知方式
|
||||||
* 私有化部署,保障数据安全
|
* 私有化部署,数据保存本地,安装升级非常简单快捷
|
||||||
* 支持sqlite,postgresql数据库
|
* 镜像由Github Actions构建,过程公开透明
|
||||||
|
* 授权加密,站点隐藏,2FA,密码防爆破等多重安全保障
|
||||||
|
* 支持SQLite,PostgreSQL、MySQL多种数据库
|
||||||
|
* 开放接口支持
|
||||||
|
* 站点证书监控
|
||||||
|
* 多用户管理
|
||||||
|
|
||||||
|
|
||||||
## 二、一些说明
|

|
||||||
* 本项目申请证书过程遵循acme协议
|
|
||||||
* 需要验证域名所有权,一般有两种方式
|
|
||||||
* http-01: 在网站根目录下放置一份txt文件
|
|
||||||
* dns-01: 需要给域名添加txt解析记录,通配符域名只能用这种方式(本项目仅支持dns-01)
|
|
||||||
* 证书续期:
|
|
||||||
* 实际上没有办法不改变证书文件本身情况下直接续期或者续签。
|
|
||||||
* 我们所说的续期,其实就是按照全套流程重新申请一份新证书,然后重新部署上去。
|
|
||||||
* 免费证书过期时间90天,以后可能还会缩短,所以自动化部署必不可少
|
|
||||||
* 设置每天自动运行,当证书过期前35天,会自动重新申请证书并部署
|
|
||||||
|
|
||||||
## 三、证书颁发机构对比
|
|
||||||
* Let's Encrypt:申请最简单。
|
|
||||||
* Google: 大厂光环,兼容性好,需要翻墙获取EAB。
|
|
||||||
* ZeroSSL: 有数量限制,获取EAB无需翻墙。
|
|
||||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -19,7 +19,8 @@ https://1panel.cn/docs/installation/online_installation/
|
|||||||
3. 点击确定,启动容器
|
3. 点击确定,启动容器
|
||||||

|

|
||||||
|
|
||||||
> 默认数据保存在`/data/certd`目录下,可以手动备份
|
> 默认使用sqlite数据库,数据保存在`/data/certd`目录下,您可以手动备份该目录
|
||||||
|
> certd还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
|
||||||
|
|
||||||
3. 访问测试
|
3. 访问测试
|
||||||
|
|
||||||
@@ -31,15 +32,12 @@ admin/123456
|
|||||||
|
|
||||||
## 三、升级
|
## 三、升级
|
||||||
|
|
||||||
1. 找到容器,点击编辑
|
1. 找到容器,点击更多->升级
|
||||||

|

|
||||||
|
|
||||||
2. 将latest修改为最新版本号
|
2. 选择强制拉取镜像,点击确认即可
|
||||||

|

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

|
|
||||||
|
|
||||||
3. 点击确定,重启容器
|
|
||||||
|
|
||||||
## 四、数据备份
|
## 四、数据备份
|
||||||
|
|
||||||
@@ -48,4 +46,4 @@ admin/123456
|
|||||||
|
|
||||||
## 五、备份恢复
|
## 五、备份恢复
|
||||||
|
|
||||||
将备份的`db.sqlite`覆盖到原来的位置即可
|
将备份的`db.sqlite`及同目录下的其他文件一起覆盖到原来的位置,重启certd即可
|
||||||
|
|||||||
|
After Width: | Height: | Size: 82 KiB |
@@ -10,15 +10,16 @@
|
|||||||
* 登录宝塔面板,在菜单栏中点击 Docker,首次进入会提示安装Docker服务,点击立即安装,按提示完成安装
|
* 登录宝塔面板,在菜单栏中点击 Docker,首次进入会提示安装Docker服务,点击立即安装,按提示完成安装
|
||||||
|
|
||||||
### 2、部署certd
|
### 2、部署certd
|
||||||
|
以下两种方式任选一种:
|
||||||
|
|
||||||
#### 2.1 应用商店一键部署【推荐】
|
#### 2.1 应用商店方式一键部署【推荐】
|
||||||
|
|
||||||
* 在应用商店中找到`certd`(要先点右上角更新应用)
|
* 在宝塔Docker应用商店中找到`certd`(要先点右上角更新应用)
|
||||||
* 点击安装,配置域名等基本信息即可完成安装
|
* 点击安装,配置域名等基本信息即可完成安装
|
||||||
|
|
||||||
> 需要宝塔9.2.0及以上版本才支持
|
> 需要宝塔9.2.0及以上版本才支持
|
||||||
|
|
||||||
#### 2.2 容器编排部署
|
#### 2.2 容器编排方式部署
|
||||||
|
|
||||||
1. 打开`docker-compose.yaml`,整个内容复制下来
|
1. 打开`docker-compose.yaml`,整个内容复制下来
|
||||||
https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
https://gitee.com/certd/certd/raw/v2/docker/run/docker-compose.yaml
|
||||||
@@ -29,6 +30,9 @@
|
|||||||
点击确定,等待启动完成
|
点击确定,等待启动完成
|
||||||

|

|
||||||
|
|
||||||
|
> certd默认使用sqlite数据库,另外支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
|
||||||
|
|
||||||
|
|
||||||
## 二、访问应用
|
## 二、访问应用
|
||||||
|
|
||||||
http://ip:7001
|
http://ip:7001
|
||||||
@@ -38,30 +42,17 @@ admin/123456
|
|||||||
登录后请及时修改密码
|
登录后请及时修改密码
|
||||||
|
|
||||||
## 三、如何升级
|
## 三、如何升级
|
||||||
|
宝塔升级certd非常简单
|
||||||
|
|
||||||
### 1. 应用商店安装,直接更新镜像即可
|
打开容器页面: `docker`->`容器编排`->`左侧选择Certd`->`更新镜像`
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### 2. latest更新方式
|
|
||||||
在主机上拉取最新镜像,然后面板上重启容器
|
|
||||||
```shell
|
|
||||||
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 固定版本号方式
|
|
||||||
|
|
||||||
修改容器编排模版中的镜像版本号,然后面板上重启容器
|
|
||||||
```shell
|
|
||||||
services:
|
|
||||||
certd:
|
|
||||||
# 镜像 # 修改最新版本号 ---- ↓↓↓↓↓
|
|
||||||
image: registry.cn-shenzhen.aliyuncs.com/handsfree/certd:v1.xx.x
|
|
||||||
```
|
|
||||||
|
|
||||||
## 四、数据备份
|
## 四、数据备份
|
||||||
|
|
||||||
|
部署方式不同,数据保存位置不同
|
||||||
|
|
||||||
### 4.1 应用商店部署方式
|
### 4.1 应用商店部署方式
|
||||||
点击进入安装路径,数据保存在`./data`目录下,可以手动备份
|
点击进入安装路径,数据保存在`./data`目录下,可以手动备份
|
||||||
|
|
||||||
@@ -81,4 +72,13 @@ services:
|
|||||||
|
|
||||||
## 五、备份恢复
|
## 五、备份恢复
|
||||||
|
|
||||||
将备份的`db.sqlite`覆盖到原来的位置即可
|
将备份的`db.sqlite`及同目录下的其他文件一起覆盖到原来的位置,重启certd即可
|
||||||
|
|
||||||
|
|
||||||
|
## 六、宝塔部署相关问题排查
|
||||||
|
|
||||||
|
### 1. 无法访问Certd
|
||||||
|
1. 确认服务器的安全规则,是否放开了对应端口
|
||||||
|
2. 确认宝塔防火墙是否放开对应端口
|
||||||
|
3. 尝试将Certd容器加入宝塔的`bridge`网络
|
||||||
|

|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# 切换数据库
|
||||||
|
|
||||||
|
certd支持如下几种数据库:
|
||||||
|
1. sqlite3 (默认)
|
||||||
|
2. mysql
|
||||||
|
3. postgresql
|
||||||
|
|
||||||
|
您可以按如下两种方式切换数据库
|
||||||
|
|
||||||
|
|
||||||
|
## 一、全新安装
|
||||||
|
::: tip
|
||||||
|
以下按照`docker-compose`安装方式介绍如何使用mysql或postgresql数据库
|
||||||
|
如果您使用其他方式部署,请自行修改对应的环境变量即可。
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 1.1、使用mysql数据库
|
||||||
|
|
||||||
|
1. 安装mysql,创建数据库 `(注意:charset=utf8mb4, collation=utf8mb4_bin)`
|
||||||
|
2. 下载最新的docker-compose.yaml
|
||||||
|
3. 修改环境变量配置
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
certd:
|
||||||
|
environment:
|
||||||
|
# 使用mysql数据库,需要提前创建数据库 charset=utf8mb4, collation=utf8mb4_bin
|
||||||
|
- certd_flyway_scriptDir=./db/migration-mysql # 升级脚本目录 【照抄】
|
||||||
|
- certd_typeorm_dataSource_default_type=mysql # 数据库类型, 或者 mariadb
|
||||||
|
- certd_typeorm_dataSource_default_host=localhost # 数据库地址
|
||||||
|
- certd_typeorm_dataSource_default_port=3306 # 数据库端口
|
||||||
|
- certd_typeorm_dataSource_default_username=root # 用户名
|
||||||
|
- certd_typeorm_dataSource_default_password=yourpasswd # 密码
|
||||||
|
- certd_typeorm_dataSource_default_database=certd # 数据库名
|
||||||
|
|
||||||
|
```
|
||||||
|
4. 启动certd
|
||||||
|
```shell
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 1.2、使用Postgresql数据库
|
||||||
|
|
||||||
|
1. 安装postgresql,创建数据库
|
||||||
|
2. 下载最新的docker-compose.yaml
|
||||||
|
3. 修改环境变量配置
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
certd:
|
||||||
|
environment:
|
||||||
|
# 使用postgresql数据库,需要提前创建数据库
|
||||||
|
- certd_flyway_scriptDir=./db/migration-pg # 升级脚本目录 【照抄】
|
||||||
|
- certd_typeorm_dataSource_default_type=postgres # 数据库类型 【照抄】
|
||||||
|
- certd_typeorm_dataSource_default_host=localhost # 数据库地址
|
||||||
|
- certd_typeorm_dataSource_default_port=5433 # 数据库端口
|
||||||
|
- certd_typeorm_dataSource_default_username=postgres # 用户名
|
||||||
|
- certd_typeorm_dataSource_default_password=yourpasswd # 密码
|
||||||
|
- certd_typeorm_dataSource_default_database=certd # 数据库名
|
||||||
|
|
||||||
|
```
|
||||||
|
4. 启动certd
|
||||||
|
```shell
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 二、从旧版的sqlite切换数据库
|
||||||
|
|
||||||
|
1. 先将`旧certd`升级到最新版 (`建议:备份sqlite数据库` )
|
||||||
|
2. 按照上面全新安装方式部署一套`新的certd` (`注意:新旧版本的certd要一致`)
|
||||||
|
3. 使用数据库工具将数据从sqlite导入到mysql或postgresql (`注意:flyway_history数据表不要导入`)
|
||||||
|
4. 重启新certd
|
||||||
|
5. 确认没有问题之后,删除旧版certd
|
||||||
|
|
||||||
@@ -41,7 +41,9 @@ docker compose up -d
|
|||||||
|
|
||||||
> 如果提示 没有docker compose命令,请安装docker-compose
|
> 如果提示 没有docker compose命令,请安装docker-compose
|
||||||
> https://docs.docker.com/compose/install/linux/
|
> https://docs.docker.com/compose/install/linux/
|
||||||
> 然后使用 `docker-compose up -d` 启动
|
|
||||||
|
> certd默认使用sqlite数据库,另外还支持`mysql`和`postgresql`数据库,[点我了解如何切换其他数据库](../database)
|
||||||
|
|
||||||
|
|
||||||
### 3. 访问测试
|
### 3. 访问测试
|
||||||
|
|
||||||
@@ -53,6 +55,11 @@ https://your_server_ip:7002
|
|||||||
|
|
||||||
## 二、升级
|
## 二、升级
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
如果您是第一次升级certd版本,切记切记先备份一下数据
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
### 如果使用固定版本号
|
### 如果使用固定版本号
|
||||||
1. 修改`docker-compose.yaml`中的镜像版本号
|
1. 修改`docker-compose.yaml`中的镜像版本号
|
||||||
2. 运行`docker compose up -d` 即可
|
2. 运行`docker compose up -d` 即可
|
||||||
@@ -71,4 +78,4 @@ docker compose up -d
|
|||||||
|
|
||||||
## 四、备份恢复
|
## 四、备份恢复
|
||||||
|
|
||||||
将备份的`db.sqlite`覆盖到原来的位置即可
|
将备份的`db.sqlite`及同目录下的其他文件一起覆盖到原来的位置,重启certd即可
|
||||||
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -1,11 +1,15 @@
|
|||||||
# 源码部署
|
# 源码部署
|
||||||
|
如果没有开发基础、没有运维基础、没有`git`和`nodejs`基础,强烈不推荐此方式
|
||||||
|
|
||||||
## 一、源码安装
|
## 一、源码安装
|
||||||
|
|
||||||
|
### 环境要求
|
||||||
|
- nodejs 22 及以上
|
||||||
### 源码启动
|
### 源码启动
|
||||||
```shell
|
```shell
|
||||||
# 克隆代码
|
# 克隆代码
|
||||||
git clone https://github.com/certd/certd
|
git clone https://github.com/certd/certd --depth=1
|
||||||
# git checkout v1.x.x # 1.x.x换成最新版本号,当v2主干分支代码无法正常启动时,可以尝试此命令
|
# git checkout v1.x.x # 当v2主干分支代码无法正常启动时,可以尝试此命令,1.x.x换成最新版本号
|
||||||
cd certd
|
cd certd
|
||||||
# 启动服务
|
# 启动服务
|
||||||
./start.sh
|
./start.sh
|
||||||
@@ -26,14 +30,25 @@ https://your_server_ip:7002
|
|||||||
## 二、升级
|
## 二、升级
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# 更新代码并启动
|
|
||||||
cd certd
|
cd certd
|
||||||
|
# 确保数据安全,备份一下数据
|
||||||
|
cp -rf ./packages/ui/certd-server/data ../certd-data-backup
|
||||||
|
|
||||||
git pull
|
git pull
|
||||||
|
# 如果提示pull失败,可以尝试强制更新
|
||||||
|
# git checkout v2 -f && git pull
|
||||||
|
|
||||||
# 先停止旧的服务,7001是certd的默认端口
|
# 先停止旧的服务,7001是certd的默认端口
|
||||||
kill -9 $(lsof -t -i:7001)
|
kill -9 $(lsof -t -i:7001)
|
||||||
# 重新编译启动
|
# 重新编译启动
|
||||||
./start.sh
|
./start.sh
|
||||||
|
|
||||||
```
|
```
|
||||||
|
::: warning
|
||||||
|
升级certd版本前,切记切记先备份一下数据
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
## 三、数据备份
|
## 三、数据备份
|
||||||
> 数据默认保存在 `./packages/ui/certd-server/data` 目录下
|
> 数据默认保存在 `./packages/ui/certd-server/data` 目录下
|
||||||
@@ -42,4 +57,19 @@ kill -9 $(lsof -t -i:7001)
|
|||||||
|
|
||||||
## 四、备份恢复
|
## 四、备份恢复
|
||||||
|
|
||||||
将备份的`db.sqlite`覆盖到原来的位置即可
|
将备份的`db.sqlite`及同目录下的其他文件覆盖到原来的位置,重启certd即可
|
||||||
|
|
||||||
|
## 六、常见问题
|
||||||
|
|
||||||
|
### 1. npm install better-sqlite3 时,提示node-gyp需要vscode环境编译
|
||||||
|
|
||||||
|
1. 首先确保node版本为22以上
|
||||||
|
2. 将下面两行加到 ~/.npmrc 里面
|
||||||
|
3. 重新install
|
||||||
|
> better_sqlite3_binary_host=https://registry.npmmirror.com/-/binary/better-sqlite3
|
||||||
|
> better_sqlite3_binary_host_mirror=https://registry.npmmirror.com/-/binary/better-sqlite3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# 版本升级
|
||||||
|
|
||||||
|
## 升级方法
|
||||||
|
根据不同部署方式查看升级方法
|
||||||
|
|
||||||
|
1. [Docker方式部署升级](./docker/#二、升级)
|
||||||
|
2. [宝塔面板方式部署升级](./baota/#三、如何升级)
|
||||||
|
3. [1Panel面板方式部署升级](./1panel/#三、升级)
|
||||||
|
4. [源码方式部署](./source/#二、升级)
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
如果您是第一次升级certd版本,切记切记先备份一下数据
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 升级日志
|
||||||
|
可以查看最新版本号,以及所有版本的更新日志
|
||||||
|
[CHANGELOG](../changelogs/CHANGELOG.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 自动升级配置
|
||||||
|
|
||||||
|
### 1. 方法一:使用watchtower监控
|
||||||
|
|
||||||
|
修改docker-compose.yaml文件增加如下配置, 使用watchtower监控自动升级
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
certd:
|
||||||
|
...
|
||||||
|
labels:
|
||||||
|
com.centurylinklabs.watchtower.enable: "true"
|
||||||
|
|
||||||
|
# ↓↓↓↓ --------------------------------------------------------- 自动升级,上面certd的版本号要保持为latest
|
||||||
|
certd-updater: # 添加 Watchtower 服务
|
||||||
|
image: containrrr/watchtower:latest
|
||||||
|
container_name: certd-updater
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
# 配置 自动更新
|
||||||
|
environment:
|
||||||
|
- WATCHTOWER_CLEANUP=true # 自动清理旧版本容器
|
||||||
|
- WATCHTOWER_INCLUDE_STOPPED=false # 不更新已停止的容器
|
||||||
|
- WATCHTOWER_LABEL_ENABLE=true # 根据容器标签进行更新
|
||||||
|
- WATCHTOWER_POLL_INTERVAL=600 # 每 10 分钟检查一次更新
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 2. 方法二:使用Certd版本监控功能
|
||||||
|
|
||||||
|
选择Github-检查Release版本插件
|
||||||
|

|
||||||
|
按如下图填写配置
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
检测到新版本后执行宿主机升级命令:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 拉取最新镜像
|
||||||
|
docker pull registry.cn-shenzhen.aliyuncs.com/handsfree/certd:latest
|
||||||
|
# 升级容器命令, 替换成你自己的certd更新命令
|
||||||
|
export RESTART_CERT='sleep 10; cd ~/deploy/certd/ ; docker compose down; docker compose up -d'
|
||||||
|
# 构造一个脚本10s后在后台执行,避免容器销毁时执行太快,导致流水线任务无法结束
|
||||||
|
nohup sh -c '$RESTART_CERT' >/dev/null 2>&1 & echo '10秒后重启' && exit
|
||||||
|
```
|
||||||
|
After Width: | Height: | Size: 54 KiB |
@@ -0,0 +1,30 @@
|
|||||||
|
# 开放接口
|
||||||
|
被动方式对第三方提供证书, 支持根据域名或证书id获取证书。
|
||||||
|
|
||||||
|
## 获取keyId和KeySecret
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 接口文档
|
||||||
|
|
||||||
|
https://apifox.com/apidoc/shared-2e76f8c4-7c58-413b-a32d-a1316529af44/254949529e0
|
||||||
|
|
||||||
|
## Token生成方法
|
||||||
|
|
||||||
|
header中传入x-certd-token即可调用开放接口
|
||||||
|
1、首先从OpenKey页面生成keyId,keySecret;
|
||||||
|
2、准备一个content( json字符串): content={"keyId":keyId, t:时间戳秒数, encrypt:false, signType:"md5"} `// encrypt返回结果是否加密`
|
||||||
|
3、将content加上keySecret进行签名: sign = md5(content + keySecret)
|
||||||
|
4、然后将content和sign分别base64后用.号连接: x-certd-token = base64(content) +"."+base64(sign)
|
||||||
|
|
||||||
|
## SDK
|
||||||
|
待开发
|
||||||
|
|
||||||
|
## 客户端工具
|
||||||
|
|
||||||
|
### SSL-Assistant
|
||||||
|
`SSL Assistant` 是一个基于 Go 语言开发的跨平台证书部署管理助手。
|
||||||
|
支持自动扫描主机`Nginx`配置,然后从Certd拉取证书并部署。
|
||||||
|
在不想暴露ssh主机密码情况下,该工具非常好用。
|
||||||
|
|
||||||
|
开源地址: https://github.com/Youngxj/SSL-Assistant
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# 插件列表
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# 授权列表
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **阿里云授权** | |
|
||||||
|
| 2.| **EAB授权** | ZeroSSL证书申请需要EAB授权 |
|
||||||
|
| 3.| **google cloud** | 谷歌云授权 |
|
||||||
|
| 4.| **主机登录授权** | |
|
||||||
|
| 5.| **SFTP授权** | |
|
||||||
|
| 6.| **阿里云OSS授权** | 包含地域和Bucket |
|
||||||
|
| 7.| **FTP授权** | |
|
||||||
|
| 8.| **腾讯云** | |
|
||||||
|
| 9.| **腾讯云COS授权** | 腾讯云对象存储授权,包含地域和存储桶 |
|
||||||
|
| 10.| **七牛云授权** | |
|
||||||
|
| 11.| **七牛OSS授权** | |
|
||||||
|
| 12.| **天翼云授权** | |
|
||||||
|
| 13.| **s3/minio授权** | S3/minio oss授权 |
|
||||||
|
| 14.| **baota授权** | |
|
||||||
|
| 15.| **易盾DCDN授权** | https://user.yiduncdn.com |
|
||||||
|
| 16.| **易盾rcdn授权** | 易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8) |
|
||||||
|
| 17.| **易发云短信** | sms.yfyidc.cn/ |
|
||||||
|
| 18.| **cdnfly授权** | |
|
||||||
|
| 19.| **群晖登录授权** | |
|
||||||
|
| 20.| **k8s授权** | |
|
||||||
|
| 21.| **1panel授权** | 账号和密码 |
|
||||||
|
| 22.| **百度云授权** | |
|
||||||
|
| 23.| **LeCDN授权** | |
|
||||||
|
| 24.| **白山云授权** | |
|
||||||
|
| 25.| **plesk授权** | |
|
||||||
|
| 26.| **易支付** | |
|
||||||
|
| 27.| **支付宝** | |
|
||||||
|
| 28.| **微信支付** | |
|
||||||
|
| 29.| **长亭雷池授权** | |
|
||||||
|
| 30.| **lucky** | |
|
||||||
|
| 31.| **括彩云cdn授权** | 括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
|
||||||
|
| 32.| **uniCloud** | unicloud授权 |
|
||||||
|
| 33.| **华为云授权** | |
|
||||||
|
| 34.| **西部数码授权** | |
|
||||||
|
| 35.| **多吉云** | |
|
||||||
|
| 36.| **我爱云授权** | 我爱云CDN |
|
||||||
|
| 37.| **CacheFly** | CacheFly |
|
||||||
|
| 38.| **Gcore** | Gcore |
|
||||||
|
| 39.| **亚马逊云aws授权** | |
|
||||||
|
| 40.| **dns.la授权** | |
|
||||||
|
| 41.| **又拍云** | |
|
||||||
|
| 42.| **火山引擎** | |
|
||||||
|
| 43.| **京东云** | |
|
||||||
|
| 44.| **51dns授权** | |
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
table th:first-of-type {
|
||||||
|
width: 65px;
|
||||||
|
}
|
||||||
|
table th:nth-of-type(2) {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
# 任务插件
|
||||||
|
共 `70` 款任务插件
|
||||||
|
## 1. 证书申请
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **证书申请(JS版)** | 免费通配符域名证书申请,支持多个域名打到同一个证书上 |
|
||||||
|
| 2.| **证书申请(Lego)** | 支持海量DNS解析提供商,推荐使用,一样的免费通配符域名证书申请,支持多个域名打到同一个证书上 |
|
||||||
|
| 3.| **商用证书托管** | 手动上传自定义证书后,自动部署(每次证书有更新,都需要手动上传一次) |
|
||||||
|
## 2. 主机
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **FTP-上传证书到FTP** | 将证书上传到FTP服务器 |
|
||||||
|
| 2.| **IIS-部署到IIS站点** | |
|
||||||
|
| 3.| **主机-执行远程主机脚本命令** | 可以执行重启nginx等操作让证书生效 |
|
||||||
|
| 4.| **主机-部署证书到SSH主机** | SFTP上传证书到主机,然后SSH执行部署脚本命令 |
|
||||||
|
## 3. CDN
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **易盾-部署到易盾DCDN** | 主要是防御,http://user.yiduncdn.com/ |
|
||||||
|
| 2.| **易盾-部署到易盾RCDN** | 易盾CDN,每月免费30G,[注册即领](https://rhcdn.yiduncdn.com/register?code=8mn536rrzfbf8) |
|
||||||
|
| 3.| **cdnfly-部署证书到cdnfly** | cdnfly |
|
||||||
|
| 4.| **百度云-部署证书到CDN** | 部署到百度云CDN |
|
||||||
|
| 5.| **LeCDN-更新证书** | |
|
||||||
|
| 6.| **LeCDN-更新证书V2** | 支持新版本LeCDN |
|
||||||
|
| 7.| **白山云-更新证书** | |
|
||||||
|
| 8.| **天翼云-部署证书到CDN** | 部署证书到天翼云CDN和全站加速 |
|
||||||
|
| 9.| **括彩云-部署到括彩云CDN** | 括彩云CDN,每月免费30G,[注册即领](https://kuocaicdn.com/register?code=8mn536rrzfbf8) |
|
||||||
|
| 10.| **多吉云-部署到多吉云CDN** | |
|
||||||
|
| 11.| **我爱云-部署证书到我爱云CDN** | 部署证书到我爱云CDN |
|
||||||
|
| 12.| **CacheFly-部署证书到CacheFly** | 部署证书到 CacheFly |
|
||||||
|
| 13.| **Gcore-部署证书到Gcore** | 仅上传 并不会部署到cdn |
|
||||||
|
| 14.| **Gcore-刷新Gcore证书** | 刷新现有的证书 |
|
||||||
|
| 15.| **又拍云-部署证书到CDN/USS** | 支持又拍云CDN,又拍云云存储USS |
|
||||||
|
## 4. 面板
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **宝塔-面板证书部署** | 部署宝塔面板本身的ssl证书 |
|
||||||
|
| 2.| **宝塔-网站证书部署** | 部署宝塔管理的站点的ssl证书,目前支持网站站点、docker站点等 |
|
||||||
|
| 3.| **群晖-部署证书到群晖面板** | Synology,支持6.x以上版本 |
|
||||||
|
| 4.| **K8S-部署证书到Secret** | 部署证书到k8s的secret |
|
||||||
|
| 5.| **K8S-Ingress 证书部署** | 部署证书到k8s的Ingress |
|
||||||
|
| 6.| **1Panel-部署证书到1Panel** | 更新1Panel的证书 |
|
||||||
|
| 7.| **Plesk-部署Plesk网站证书** | |
|
||||||
|
| 8.| **雷池-更新证书** | 更新长亭雷池WAF的证书 |
|
||||||
|
| 9.| **lucky-更新Lucky证书** | |
|
||||||
|
| 10.| **uniCloud-部署到服务空间** | 部署到服务空间 |
|
||||||
|
| 11.| **威联通-部署证书到威联通** | 部署证书到qnap |
|
||||||
|
## 5. 阿里云
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **阿里云-部署到Ack** | 部署到阿里云Ack集群Ingress等通过Secret管理证书的应用 |
|
||||||
|
| 2.| **阿里云-部署至任意云资源** | 【不建议使用】需要消耗阿里云自动部署次数,支持SLB、LIVE、webHosting、VOD、CR、DCDN、DDoS、CDN、ALB、APIGateway、FC、GA、MSE、NLB、OSS、SAE、WAF等云产品 |
|
||||||
|
| 3.| **阿里云-部署证书至CDN** | 自动部署域名证书至阿里云CDN |
|
||||||
|
| 4.| **阿里云-部署证书至DCDN** | 依赖证书申请前置任务,自动部署域名证书至阿里云DCDN |
|
||||||
|
| 5.| **阿里云-部署证书至OSS** | 自动部署域名证书至阿里云OSS |
|
||||||
|
| 6.| **阿里云-上传证书到阿里云** | 如果不想在阿里云上同一份证书上传多次,可以把此任务作为前置任务,其他阿里云任务证书那一项选择此任务的输出 |
|
||||||
|
| 7.| **阿里云-部署至阿里云WAF** | 部署证书到阿里云WAF |
|
||||||
|
| 8.| **阿里云-部署至ALB(应用负载均衡)** | ALB,更新监听器的默认证书 |
|
||||||
|
| 9.| **阿里云-部署至NLB(网络负载均衡)** | NLB,网络负载均衡,更新监听器的默认证书 |
|
||||||
|
| 10.| **阿里云-部署至SLB(传统负载均衡)** | 部署证书到阿里云SLB(传统负载均衡) |
|
||||||
|
| 11.| **阿里云-部署至阿里云FC(3.0)** | 部署证书到阿里云函数计算(FC3.0),【注意】证书的加密算法必须选择【pkcs1旧版】 |
|
||||||
|
## 6. 华为云
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **华为云-部署证书至CDN** | |
|
||||||
|
## 7. 腾讯云
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **腾讯云-部署证书到任意云资源** | 支持负载均衡、CDN、DDoS、直播、点播、Web应用防火墙、API网关、TEO、容器服务、对象存储、轻应用服务器、云原生微服务、云开发 |
|
||||||
|
| 2.| **腾讯云-部署到CLB** | 暂时只支持单向认证证书,暂时只支持通用负载均衡 |
|
||||||
|
| 3.| **腾讯云-部署到CDN(废弃)** | 已废弃,请使用v2版 |
|
||||||
|
| 4.| **腾讯云-部署到CDN-v2** | 推荐使用 |
|
||||||
|
| 5.| **腾讯云-上传证书到腾讯云** | 上传成功后输出:tencentCertId |
|
||||||
|
| 6.| **腾讯云-部署证书到COS** | 部署到腾讯云COS源站域名证书【注意:很不稳定,需要重试很多次偶尔才能成功一次】 |
|
||||||
|
| 7.| **腾讯云-部署到腾讯云EO** | 腾讯云边缘安全加速平台EO,必须配置上传证书到腾讯云任务 |
|
||||||
|
| 8.| **腾讯云-删除即将过期证书** | 仅删除未使用的证书 |
|
||||||
|
| 9.| **腾讯云-部署到TKE-ingress** | serverless集群请使用K8S部署插件;Qcloud类型需要【上传到腾讯云】作为前置任务;ApiServer未开启外网访问则需要做域名的内网IP映射 |
|
||||||
|
## 8. 火山引擎
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **火山引擎-部署证书至CDN** | 支持网页,文件下载,音视频点播 |
|
||||||
|
| 2.| **火山引擎-部署证书至CLB** | 部署至火山引擎负载均衡 |
|
||||||
|
| 3.| **火山引擎-上传证书至证书中心** | 上传证书至火山引擎证书中心 |
|
||||||
|
| 4.| **火山引擎-部署证书至ALB** | 部署至火山引擎应用负载均衡 |
|
||||||
|
| 5.| **火山引擎-部署证书至Live** | 部署至火山引擎视频直播 |
|
||||||
|
## 9. 京东云
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **京东云-部署证书至CDN** | 京东云内容分发网络 |
|
||||||
|
| 2.| **京东云-更新已有证书** | 更新SSL数字证书中的证书 |
|
||||||
|
| 3.| **京东云-上传新证书** | 上传证书到SSL数字证书中心 |
|
||||||
|
## 10. 七牛云
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **七牛云-部署证书至OSS** | 自动部署域名证书至七牛云KODO,注意是自定义源站域名,不是CDN域名 |
|
||||||
|
| 2.| **七牛云-部署证书至CDN** | 自动部署域名证书至七牛云CDN |
|
||||||
|
## 11. 亚马逊云
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **AWS-部署证书到CloudFront** | 部署证书到 AWS CloudFront |
|
||||||
|
## 12. 其他
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **Demo-测试插件** | |
|
||||||
|
| 2.| **重启 Certd** | 【仅管理员可用】 重启 certd的https服务,用于更新 Certd 的 ssl 证书 |
|
||||||
|
| 3.| **自定义js脚本** | 【仅管理员】运行自定义js脚本执行 |
|
||||||
|
| 4.| **等待** | 等待一段时间 |
|
||||||
|
| 5.| **数据库备份** | 仅支持备份SQLite数据库 |
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
table th:first-of-type {
|
||||||
|
width: 65px;
|
||||||
|
}
|
||||||
|
table th:nth-of-type(2) {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# DNS提供商
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **阿里云** | 阿里云DNS解析提供商 |
|
||||||
|
| 2.| **腾讯云** | 腾讯云域名DNS解析提供者 |
|
||||||
|
| 3.| **华为云** | 华为云DNS解析提供商 |
|
||||||
|
| 4.| **西部数码** | west dns provider |
|
||||||
|
| 5.| **dns.la** | dns.la |
|
||||||
|
| 6.| **火山引擎** | 火山引擎DNS解析提供商 |
|
||||||
|
| 7.| **京东云** | 京东云DNS解析提供商 |
|
||||||
|
| 8.| **51dns** | 51DNS |
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
table th:first-of-type {
|
||||||
|
width: 65px;
|
||||||
|
}
|
||||||
|
table th:nth-of-type(2) {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# 通知插件
|
||||||
|
|
||||||
|
| 序号 | 名称 | 说明 |
|
||||||
|
|-----|-----|-----|
|
||||||
|
| 1.| **企业微信通知** | 企业微信群聊机器人通知 |
|
||||||
|
| 2.| **电子邮件** | 电子邮件通知 |
|
||||||
|
| 3.| **爱语飞飞微信通知(iyuu)** | https://iyuu.cn/ |
|
||||||
|
| 4.| **自定义webhook** | 根据模版自定义http请求 |
|
||||||
|
| 5.| **Server酱ᵀ** | https://sct.ftqq.com/ |
|
||||||
|
| 6.| **Server酱³** | https://doc.sc3.ft07.com/serverchan3 |
|
||||||
|
| 7.| **AnPush** | https://anpush.com |
|
||||||
|
| 8.| **Telegram通知** | Telegram Bot推送通知 |
|
||||||
|
| 9.| **Discord 通知** | Discord 机器人通知 |
|
||||||
|
| 10.| **Slack通知** | Slack消息推送通知 |
|
||||||
|
| 11.| **Bark 通知** | Bark 推送通知插件 |
|
||||||
|
| 12.| **飞书通知** | 飞书群聊webhook通知 |
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
table th:first-of-type {
|
||||||
|
width: 65px;
|
||||||
|
}
|
||||||
|
table th:nth-of-type(2) {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 82 KiB |
@@ -0,0 +1,20 @@
|
|||||||
|
# 常见问题
|
||||||
|
|
||||||
|
|
||||||
|
## 1. 是否支持IP证书
|
||||||
|
|
||||||
|
因为ACME协议不支持IP证书,所以certd目前也不支持IP证书
|
||||||
|
|
||||||
|
|
||||||
|
## 2. 建议设置多长时间运行一次流水线
|
||||||
|
建议每天运行一次,检查证书过期时间
|
||||||
|
当证书没过期时,自动跳过部署
|
||||||
|
当证书到期前35天(创建流水线时可以修改),将会自动重新申请证书,自动部署
|
||||||
|
|
||||||
|
|
||||||
|
## 3. too many certificates 错误
|
||||||
|
当出现如下报错时,说明相同的域名短时间内申请超过5次
|
||||||
|
解决方案:可以加多一个子域名,重新执行就可以规避次错误
|
||||||
|
```
|
||||||
|
"detail": too many certificates (5) already issued for this exact set of idantifiers in the last 168hm0s
|
||||||
|
```
|
||||||
|
After Width: | Height: | Size: 47 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
# 部署证书到ESXi
|
||||||
|
|
||||||
|
使用`部署证书到主机插件`即可
|
||||||
|
|
||||||
|
|
||||||
|
## 开启ssh
|
||||||
|
登陆ESXi Web后台,点击 主机 -> 操作 -> 服务 -> 启用 Secure Shell(SSH)打开SSH
|
||||||
|
|
||||||
|
## 添加部署到主机任务
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 配置重启脚本
|
||||||
|
```bash
|
||||||
|
/etc/init.d/hostd restart
|
||||||
|
/etc/init.d/vpxa restart
|
||||||
|
```
|
||||||
@@ -9,3 +9,13 @@ ALIYUN_CLIENT_CONNECT_TIMEOUT=10000 # 连接超时,单位毫秒
|
|||||||
ALIYUN_CLIENT_READ_TIMEOUT=10000 #读取数据超时,单位毫秒
|
ALIYUN_CLIENT_READ_TIMEOUT=10000 #读取数据超时,单位毫秒
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 阿里云Access权限设置
|
||||||
|
|
||||||
|
|
||||||
|
* 申请证书 :`AliyunDNSFullAccess`
|
||||||
|
* 上传证书到阿里云: `AliyunYundunCertFullAccess`
|
||||||
|
* 部署证书到OSS: `AliyunYundunCertFullAccess`、`AliyunOSSFullAccess`
|
||||||
|
* 部署证书到CDN: `AliyunYundunCertFullAccess`、`AliyunCDNFullAccess`
|
||||||
|
* 部署证书到DCDN: `AliyunYundunCertFullAccess`、`AliyunDCDNFullAccess`
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
# 数据库自动备份
|
# 数据库备份
|
||||||
|
* 两种备份方法: 1、手动备份 2、自动备份
|
||||||
|
* 本文仅限sqlite数据库。
|
||||||
## 一、手动备份
|
## 一、手动备份
|
||||||
数据库文件根据不同的部署方式保存的位置不一样,您可以手动复制出来进行备份
|
数据库文件根据不同的部署方式保存的位置不一样,您可以手动复制出来进行备份
|
||||||
|
|
||||||
@@ -27,4 +28,4 @@
|
|||||||
|
|
||||||
## 三、备份恢复
|
## 三、备份恢复
|
||||||
|
|
||||||
将备份的`db.sqlite`覆盖到原来的位置即可
|
将备份的`db.sqlite`覆盖到原来的位置,重启certd即可
|
||||||
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
# 证书申请失败情况
|
||||||
|
|
||||||
|
|
||||||
|
## DNS记录问题
|
||||||
|
|
||||||
|
1. DNS 不要设置CAA记录,删除即可
|
||||||
|
|
||||||
|
2. DNSSEC相关报错,DNSSEC管理中删除即可
|
||||||
|
|
||||||
|
3. DNS 有其他平台申请过的_acme-challenge记录,删除即可
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# 二级子域名托管
|
||||||
|
如果你的域名是免费的二级域名(比如:sub.handsfree.work),托管在CF或者阿里云上
|
||||||
|
在使用DNS方式校验时需要设置子域名托管
|
||||||
|
|
||||||
|
[阿里云子域名托管说明](https://help.aliyun.com/zh/dns/pubz-subdomain-management)
|
||||||
|
|
||||||
|
|
||||||
|

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

|
||||||
|
After Width: | Height: | Size: 165 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
# 商业版文档
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 支付方式配置
|
||||||
|
|
||||||
|
* [支付宝支付配置](./payments/alipay.md)
|
||||||
|
* [微信支付配置](./payments/wxpay.md)
|
||||||
|
* [彩虹易支付配置](./payments/yizhifu.md)
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# 支付宝配置
|
||||||
|
|
||||||
|
## 配置步骤
|
||||||
|
|
||||||
|
|
||||||
|
1. 注册支付宝商家账号
|
||||||
|
* 开通电脑网站支付产品(需营业执照): https://b.alipay.com/page/product-workspace/all-product
|
||||||
|
|
||||||
|
|
||||||
|
2. 开放平台,创建应用,获取APPID
|
||||||
|
* 登录支付宝开放平台,进入开发者中心,创建网页应用,获取应用的AppId(左上角复制)
|
||||||
|
* 开发者中心:https://open.alipay.com/develop/manage
|
||||||
|
|
||||||
|
|
||||||
|
3. 进入应用详情,选择开发设置,配置接口加签方式 (选择密钥类型)
|
||||||
|
|
||||||
|
* 参考文档:https://opendocs.alipay.com/common/02kdnc?pathHash=fb0c752a
|
||||||
|
* 此步骤完成后,可以获取应用的私钥、支付宝公钥。
|
||||||
|
* 注意:支付宝不会保存应用的私钥,你需要自己保管好私钥。
|
||||||
|
|
||||||
|
|
||||||
|
4. 在Certd后台配置支付宝
|
||||||
|
|
||||||
|
* 进入“系统”->"设置"->“支付设置”
|
||||||
|
* 启用支付宝,选择“支付宝配置”,点击添加
|
||||||
|
* 填写支付宝AppId、应用私钥、支付宝公钥等信息即可。
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# 微信支付配置
|
||||||
|
|
||||||
|
## 配置步骤
|
||||||
|
|
||||||
|
1. 开通Native支付
|
||||||
|
* 登录微信支付平台
|
||||||
|
* 进入产品中心: https://pay.weixin.qq.com/index.php/extend/product/lists?tid=3
|
||||||
|
* 选择开通Native支付
|
||||||
|
|
||||||
|
2. 申请证书
|
||||||
|
|
||||||
|
* 进入“账户中心”->“API安全”->“商户API证书”->“管理证书”
|
||||||
|
* 根据指引生成证书
|
||||||
|
* 得到私钥和公钥
|
||||||
|
|
||||||
|
|
||||||
|
3. 填写APIv3密钥
|
||||||
|
|
||||||
|
* 进入“账户中心”->“API安全”->“解密回调”
|
||||||
|
* 填写APIv3密钥
|
||||||
|
* 参考文档 https://kf.qq.com/faq/180830E36vyQ180830AZFZvu.html
|
||||||
|
|
||||||
|
|
||||||
|
4. 在Certd后台配置微信支付
|
||||||
|
* 进入“系统”->"设置"->“支付设置”
|
||||||
|
* 启用微信支付,选择“微信支付配置”,点击添加
|
||||||
|
* 填写微信支付商户号、证书私钥、证书公钥、APIv3密钥即可。
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# 彩虹易支付配置
|
||||||
|
|
||||||
|
彩虹易支付是一款非常流行的php聚合支付系统。
|
||||||
|
|
||||||
|
## 配置步骤
|
||||||
|
|
||||||
|
1. 获取商户ID、商户密钥
|
||||||
|
|
||||||
|
* 登录彩虹易支付平台
|
||||||
|
* 进入用户中心:https://xxxxxx.com/user/userinfo.php?mod=api
|
||||||
|
* 点击API信息
|
||||||
|
* 可以复制:接口地址、商户ID、商户密钥(key)
|
||||||
|
* 点击查看文档,了解支持的签名类型,一般为MD5
|
||||||
|
|
||||||
|
2. 进入Certd后台配置彩虹易支付
|
||||||
|
|
||||||
|
* 进入“系统”->"设置"->“支付设置”
|
||||||
|
* 启用彩虹易支付,选择“彩虹易支付配置”,点击添加
|
||||||
|
* 填写接口地址、商户ID、商户密钥、签名方式等信息即可。
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
## 2. 使用示例
|
## 2. 使用示例
|
||||||
```js
|
```js
|
||||||
|
|
||||||
|
// 如果需要引用第三方库,必须使用import语法
|
||||||
|
// const thirdSdk = await import("third-sdk-name")
|
||||||
|
|
||||||
const certPem = ctx.self.cert.crt
|
const certPem = ctx.self.cert.crt
|
||||||
const certKey = ctx.self.cert.key
|
const certKey = ctx.self.cert.key
|
||||||
|
|
||||||
|
|||||||
@@ -25,3 +25,15 @@ win+R 弹出运行对话框,输入 services.msc 打开服务管理器
|
|||||||
C:\Users\xxxxx>
|
C:\Users\xxxxx>
|
||||||
↑↑↑↑---------这个就是windows ssh的登录用户名
|
↑↑↑↑---------这个就是windows ssh的登录用户名
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 4. 切换默认shell终端
|
||||||
|
安装openssh后,默认终端是cmd,建议切换成powershell
|
||||||
|
```shell
|
||||||
|
# powershell中执行如下命令切换
|
||||||
|
# 设置默认shell为powershell 【推荐】
|
||||||
|
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
|
||||||
|
|
||||||
|
# 恢复默认shell为cmd 【不推荐】
|
||||||
|
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\cmd.exe" -PropertyType String -Force
|
||||||
|
|
||||||
|
```
|
||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 51 KiB |
@@ -18,6 +18,8 @@ CERTD_HTTPS_port=7002
|
|||||||
|
|
||||||
### 2、配置复制到本机任务
|
### 2、配置复制到本机任务
|
||||||
将证书复制到certd的证书安装位置
|
将证书复制到certd的证书安装位置
|
||||||
|
证书路径:`ssl/cert.crt`
|
||||||
|
私钥路径:`ssl/cert.key`
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|||||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,13 @@
|
|||||||
|
# 带输出的前置任务
|
||||||
|
|
||||||
|
前置任务输出可以在后续任务中使用
|
||||||
|
|
||||||
|
比如上传证书到阿里云,会返回阿里云的CertId,之后其他阿里云的部署任务可以选择复用这个证书
|
||||||
|
|
||||||
|
## 复用证书
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
在后续任务中可以选择前置任务的输出
|
||||||
|
|
||||||
|

|
||||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 53 KiB |
@@ -1,8 +1,12 @@
|
|||||||
# 群晖部署和证书更新
|
# 群晖部署和证书更新
|
||||||
|
|
||||||
|
支持群晖`6.x`、`7.x`
|
||||||
|
|
||||||
## 一、群晖部署Certd
|
## 一、群晖部署Certd
|
||||||
|
|
||||||
|
以下是群晖`7.x`的部署`certd`步骤。
|
||||||
|
群晖`6.x`请参考[docker部署](./../../install/docker/)
|
||||||
|
|
||||||
### 1. 打开Container Manager
|
### 1. 打开Container Manager
|
||||||
|
|
||||||

|

|
||||||
@@ -32,6 +36,8 @@
|
|||||||
|
|
||||||
## 二、更新群晖证书
|
## 二、更新群晖证书
|
||||||
|
|
||||||
|
证书部署插件支持群晖`6.x`、`7.x`
|
||||||
|
|
||||||
## 1. 前提条件
|
## 1. 前提条件
|
||||||
* 已经部署了certd
|
* 已经部署了certd
|
||||||
* 群晖上已经设置好了证书(证书建议设置好描述,插件需要根据描述查找证书)
|
* 群晖上已经设置好了证书(证书建议设置好描述,插件需要根据描述查找证书)
|
||||||
|
|||||||
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 54 KiB |
@@ -8,8 +8,11 @@
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 如何避免收到腾讯云证书过期邮件
|
## 如何避免收到腾讯云证书过期邮件
|
||||||
|
|
||||||
|
> 新版本已经自动将证书设置为免提醒,certd上传的证书后续都不会再提醒了。
|
||||||
|
|
||||||
腾讯云在证书有效期还剩28天时会发送过期通知邮件
|
腾讯云在证书有效期还剩28天时会发送过期通知邮件
|
||||||
您可以通过配置“腾讯云过期证书删除”任务来避免收到此类邮件。
|
您可以通过配置“腾讯云过期证书删除”任务来避免收到此类邮件。
|
||||||
|
|
||||||
@@ -19,3 +22,16 @@
|
|||||||
> 1. 选择腾讯云授权,需授权`服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate`权限
|
> 1. 选择腾讯云授权,需授权`服务角色SSL_QCSLinkedRoleInReplaceLoadCertificate`权限
|
||||||
> 2. `1.26.14`版本之前Certd创建的证书流水线默认是到期前20天才更新证书,需要将之前创建的证书申请任务的更新天数修改为35天,保证删除之前就已经替换掉即将过期证书
|
> 2. `1.26.14`版本之前Certd创建的证书流水线默认是到期前20天才更新证书,需要将之前创建的证书申请任务的更新天数修改为35天,保证删除之前就已经替换掉即将过期证书
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## TKE service 的 TCP_SSL Opaque类型证书授权
|
||||||
|
|
||||||
|
部署证书到腾讯云TKE,如果报以下错误:
|
||||||
|
`is forbidden: User "xxxxxx-xxxxx" cannot get resource "secrets" in API group "" in the namespace "default"'`
|
||||||
|
则需要单独从授权管理侧再授权子用户的权限
|
||||||
|
|
||||||
|

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

|
||||||
|
|||||||
|
After Width: | Height: | Size: 60 KiB |
@@ -24,13 +24,13 @@ features:
|
|||||||
- title: 全自动申请证书
|
- title: 全自动申请证书
|
||||||
details: 支持所有注册商注册的域名
|
details: 支持所有注册商注册的域名
|
||||||
- title: 全自动部署证书
|
- title: 全自动部署证书
|
||||||
details: 支持部署到主机、阿里云、腾讯云等,目前已支持30+部署插件
|
details: 支持部署到主机、阿里云、腾讯云等,目前已支持60+部署插件
|
||||||
- title: 多域名、泛域名打到一个证书上
|
- title: 多域名、泛域名打到一个证书上
|
||||||
details: 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
details: 支持通配符域名/泛域名,支持多个域名打到一个证书上
|
||||||
- title: 多证书格式支持
|
- title: 多证书格式支持
|
||||||
details: 支持pem、pfx、der、jks等多种证书格式,支持Google、Letsencrypt、ZeroSSL证书颁发机构
|
details: 支持pem、pfx、der、jks等多种证书格式,支持Google、Letsencrypt、ZeroSSL证书颁发机构
|
||||||
- title: 支持私有化部署
|
- title: 支持私有化部署
|
||||||
details: 保障数据安全
|
details: 授权数据加密存储,保障数据安全
|
||||||
- title: 多数据库支持
|
- title: 多数据库支持
|
||||||
details: 支持sqlite,postgresql数据库
|
details: 支持SQLite、Postgresql、MySQL数据库
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmClient": "pnpm",
|
"npmClient": "pnpm",
|
||||||
"version": "1.27.5"
|
"version": "1.36.19"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,18 +9,19 @@
|
|||||||
"@lerna-lite/run": "^3.9.3",
|
"@lerna-lite/run": "^3.9.3",
|
||||||
"@lerna-lite/version": "^3.9.3",
|
"@lerna-lite/version": "^3.9.3",
|
||||||
"medium-zoom": "^1.1.0",
|
"medium-zoom": "^1.1.0",
|
||||||
"vitepress": "^1.4.1",
|
"vitepress": "^2.0.0-alpha.4",
|
||||||
"vitepress-plugin-lightbox": "^1.0.2"
|
"vitepress-plugin-lightbox": "^1.0.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "lerna bootstrap --hoist",
|
"start": "lerna bootstrap --hoist",
|
||||||
|
"start:server": "cd ./packages/ui/certd-server && npm start",
|
||||||
"devb": "lerna run dev-build",
|
"devb": "lerna run dev-build",
|
||||||
"i-all": "lerna link && lerna exec npm install ",
|
"i-all": "lerna link && lerna exec npm install ",
|
||||||
"publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly && npm run commitAll",
|
"publish": "npm run prepublishOnly2 && lerna publish --force-publish=pro/plus-core --conventional-commits --create-release github && npm run afterpublishOnly && npm run commitAll",
|
||||||
"afterpublishOnly": "npm run copylogs && time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
"afterpublishOnly": "npm run copylogs && time /t >build.trigger && git add ./build.trigger && git commit -m \"build: trigger build image\" && TIMEOUT /T 10 && git push",
|
||||||
"transform-sql": "cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js",
|
"transform-sql": "cd ./packages/ui/certd-server/db/ && node --experimental-json-modules transform.js",
|
||||||
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",
|
"commitAll": "git add . && git commit -m \"build: publish\" && git push && npm run commitPro",
|
||||||
"commitPro": "cd ./packages/core/ && git add . && git commit -m \"build: publish\" && git push",
|
"commitPro": "cd ./packages/pro/ && git add . && git commit -m \"build: publish\" && git push",
|
||||||
"copylogs": "copyfiles \"CHANGELOG.md\" ./docs/guide/changelogs/",
|
"copylogs": "copyfiles \"CHANGELOG.md\" ./docs/guide/changelogs/",
|
||||||
"prepublishOnly1": "npm run check && lerna run build ",
|
"prepublishOnly1": "npm run check && lerna run build ",
|
||||||
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
"prepublishOnly2": "npm run check && npm run before-build && lerna run build ",
|
||||||
@@ -28,12 +29,15 @@
|
|||||||
"deploy1": "node --experimental-json-modules deploy.js ",
|
"deploy1": "node --experimental-json-modules deploy.js ",
|
||||||
"check": "node --experimental-json-modules publish-check.js",
|
"check": "node --experimental-json-modules publish-check.js",
|
||||||
"init": "lerna run build",
|
"init": "lerna run build",
|
||||||
|
"init:dev": "lerna run build",
|
||||||
"docs:dev": "vitepress dev docs",
|
"docs:dev": "vitepress dev docs",
|
||||||
"docs:build": "vitepress build docs",
|
"docs:build": "npm run copylogs && vitepress build docs",
|
||||||
"docs:preview": "vitepress preview docs"
|
"docs:preview": "vitepress preview docs",
|
||||||
|
"pub": "echo 1"
|
||||||
},
|
},
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@certd/ui-server": "link:packages/ui/certd-server",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
@@ -41,5 +45,8 @@
|
|||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/**"
|
"packages/**"
|
||||||
]
|
],
|
||||||
|
"pnpm": {
|
||||||
|
"neverBuiltDependencies": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ root = true
|
|||||||
|
|
||||||
[*]
|
[*]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 2
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[{*.yml,*.yaml}]
|
[{*.yml,*.yaml}]
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 220,
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"singleQuote": false,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
}
|
||||||
@@ -3,6 +3,373 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.19](https://github.com/publishlab/node-acme-client/compare/v1.36.18...v1.36.19) (2025-09-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持ssl.com证书颁发机构 ([27b6dfa](https://github.com/publishlab/node-acme-client/commit/27b6dfa4d2ab3bddd284c3a34511a72e1a513a4c))
|
||||||
|
|
||||||
|
## [1.36.18](https://github.com/publishlab/node-acme-client/compare/v1.36.17...v1.36.18) (2025-08-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.17](https://github.com/publishlab/node-acme-client/compare/v1.36.16...v1.36.17) (2025-08-17)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.16](https://github.com/publishlab/node-acme-client/compare/v1.36.15...v1.36.16) (2025-08-16)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 部署到百度cdn支持自动获取域名列表选择 ([4e432ed](https://github.com/publishlab/node-acme-client/commit/4e432ed03f4fb564e85a2f284ee26b58400b82f5))
|
||||||
|
|
||||||
|
## [1.36.15](https://github.com/publishlab/node-acme-client/compare/v1.36.14...v1.36.15) (2025-08-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.14](https://github.com/publishlab/node-acme-client/compare/v1.36.13...v1.36.14) (2025-07-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.13](https://github.com/publishlab/node-acme-client/compare/v1.36.12...v1.36.13) (2025-07-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.12](https://github.com/publishlab/node-acme-client/compare/v1.36.11...v1.36.12) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.11](https://github.com/publishlab/node-acme-client/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/publishlab/node-acme-client/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/publishlab/node-acme-client/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/publishlab/node-acme-client/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.6](https://github.com/publishlab/node-acme-client/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/publishlab/node-acme-client/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/publishlab/node-acme-client/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/publishlab/node-acme-client/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/publishlab/node-acme-client/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/publishlab/node-acme-client/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/publishlab/node-acme-client/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/publishlab/node-acme-client/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/publishlab/node-acme-client/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/publishlab/node-acme-client/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/publishlab/node-acme-client/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/publishlab/node-acme-client/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书申请支持letencrypt profile选项 ([2eb0e54](https://github.com/publishlab/node-acme-client/commit/2eb0e54909d8ad36708e07c12fd598998159bc43))
|
||||||
|
|
||||||
|
# [1.35.0](https://github.com/publishlab/node-acme-client/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/publishlab/node-acme-client/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复中文域名使用cname方式校验无法通过的问题 ([f7d5baa](https://github.com/publishlab/node-acme-client/commit/f7d5baa6d04cb83c572b06e62f885890cfa0143a))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化cname检查,当有冲突的cname记录时,给出提示 ([e639a8f](https://github.com/publishlab/node-acme-client/commit/e639a8f9f12640ffcca69f1a6a0324459924afbd))
|
||||||
|
|
||||||
|
## [1.34.10](https://github.com/publishlab/node-acme-client/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.9](https://github.com/publishlab/node-acme-client/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.8](https://github.com/publishlab/node-acme-client/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.7](https://github.com/publishlab/node-acme-client/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.6](https://github.com/publishlab/node-acme-client/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.5](https://github.com/publishlab/node-acme-client/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.4](https://github.com/publishlab/node-acme-client/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.3](https://github.com/publishlab/node-acme-client/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.34.2](https://github.com/publishlab/node-acme-client/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* http方式支持校验443端口 ([d75fcb7](https://github.com/publishlab/node-acme-client/commit/d75fcb7fec421a9a638eaa27fe9378c84b5e0f19))
|
||||||
|
|
||||||
|
## [1.34.1](https://github.com/publishlab/node-acme-client/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 根据SOA记录判断子域名托管有缺陷,改回手动配置子域名托管记录的方式 ([1b280a2](https://github.com/publishlab/node-acme-client/commit/1b280a2940f9e2d919b0bf23b89cc185be1fa498))
|
||||||
|
|
||||||
|
# [1.34.0](https://github.com/publishlab/node-acme-client/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.8](https://github.com/publishlab/node-acme-client/compare/v1.33.7...v1.33.8) (2025-04-26)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复http上传方式无法清除记录文件的bug ([72a7b51](https://github.com/publishlab/node-acme-client/commit/72a7b51d479602b2c54c6c3ac8d8a0dcb9664e73))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 从域名的soa获取主域名,子域名托管无需额外配置 ([a586a92](https://github.com/publishlab/node-acme-client/commit/a586a92d5e32ea846ac37be52a7ad8c328d89966))
|
||||||
|
* 七牛oss支持删除过期备份 ([b7113bd](https://github.com/publishlab/node-acme-client/commit/b7113bda2378116d6c116dc583f563cce7cf9f00))
|
||||||
|
|
||||||
|
## [1.33.7](https://github.com/publishlab/node-acme-client/compare/v1.33.6...v1.33.7) (2025-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.6](https://github.com/publishlab/node-acme-client/compare/v1.33.5...v1.33.6) (2025-04-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.5](https://github.com/publishlab/node-acme-client/compare/v1.33.4...v1.33.5) (2025-04-17)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.4](https://github.com/publishlab/node-acme-client/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.3](https://github.com/publishlab/node-acme-client/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.2](https://github.com/publishlab/node-acme-client/compare/v1.33.1...v1.33.2) (2025-04-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.33.1](https://github.com/publishlab/node-acme-client/compare/v1.33.0...v1.33.1) (2025-04-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.33.0](https://github.com/publishlab/node-acme-client/compare/v1.32.0...v1.33.0) (2025-04-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.32.0](https://github.com/publishlab/node-acme-client/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复从本地dns获取记录报错的bug ([c39b1bf](https://github.com/publishlab/node-acme-client/commit/c39b1bf823ddc6216bed2049e4c87e6107def08a))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 优化证书申请速度,修复某些情况下letsencrypt 校验失败的问题 ([857589b](https://github.com/publishlab/node-acme-client/commit/857589b365c6f709e0ae67914d2f50ce182e6dd6))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化华为dns解析记录创建和删除问题 ([0948c5b](https://github.com/publishlab/node-acme-client/commit/0948c5bc691d2ee6eb47c72a85da1b7453361878))
|
||||||
|
|
||||||
|
## [1.31.11](https://github.com/publishlab/node-acme-client/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.10](https://github.com/publishlab/node-acme-client/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.9](https://github.com/publishlab/node-acme-client/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* dns支持火山引擎 ([99ff879](https://github.com/publishlab/node-acme-client/commit/99ff879d93658c29ea493a4bde7e9e3f85996d64))
|
||||||
|
|
||||||
|
## [1.31.8](https://github.com/publishlab/node-acme-client/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化txt本地校验效率 ([fd507f2](https://github.com/publishlab/node-acme-client/commit/fd507f269253607e68c5c099c99e0de11636f229))
|
||||||
|
|
||||||
|
## [1.31.7](https://github.com/publishlab/node-acme-client/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.6](https://github.com/publishlab/node-acme-client/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.5](https://github.com/publishlab/node-acme-client/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.4](https://github.com/publishlab/node-acme-client/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.3](https://github.com/publishlab/node-acme-client/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.2](https://github.com/publishlab/node-acme-client/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.31.1](https://github.com/publishlab/node-acme-client/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.31.0](https://github.com/publishlab/node-acme-client/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.30.6](https://github.com/publishlab/node-acme-client/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.30.5](https://github.com/publishlab/node-acme-client/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.30.4](https://github.com/publishlab/node-acme-client/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.30.3](https://github.com/publishlab/node-acme-client/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.30.2](https://github.com/publishlab/node-acme-client/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.30.1](https://github.com/publishlab/node-acme-client/compare/v1.30.0...v1.30.1) (2025-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.30.0](https://github.com/publishlab/node-acme-client/compare/v1.29.5...v1.30.0) (2025-01-19)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复查看任务日志偶发性无法自动滚动底部的bug ([7e482f7](https://github.com/publishlab/node-acme-client/commit/7e482f798c0142bce1866f84676cb40210f9638a))
|
||||||
|
|
||||||
|
## [1.29.5](https://github.com/publishlab/node-acme-client/compare/v1.29.4...v1.29.5) (2025-01-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.29.4](https://github.com/publishlab/node-acme-client/compare/v1.29.3...v1.29.4) (2025-01-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.29.3](https://github.com/publishlab/node-acme-client/compare/v1.29.2...v1.29.3) (2025-01-04)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化acme sdk ([54db744](https://github.com/publishlab/node-acme-client/commit/54db74428259de64d12230c2ab7353ae11197bbc))
|
||||||
|
|
||||||
|
## [1.29.2](https://github.com/publishlab/node-acme-client/compare/v1.29.1...v1.29.2) (2024-12-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.29.1](https://github.com/publishlab/node-acme-client/compare/v1.29.0...v1.29.1) (2024-12-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.29.0](https://github.com/publishlab/node-acme-client/compare/v1.28.4...v1.29.0) (2024-12-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.28.4](https://github.com/publishlab/node-acme-client/compare/v1.28.3...v1.28.4) (2024-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.28.3](https://github.com/publishlab/node-acme-client/compare/v1.28.2...v1.28.3) (2024-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.28.2](https://github.com/publishlab/node-acme-client/compare/v1.28.1...v1.28.2) (2024-12-09)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持mysql ([7cde1fd](https://github.com/publishlab/node-acme-client/commit/7cde1fdc4a9ed851900d231a5460c8dbfbcd148e))
|
||||||
|
|
||||||
|
## [1.28.1](https://github.com/publishlab/node-acme-client/compare/v1.28.0...v1.28.1) (2024-12-08)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
# [1.28.0](https://github.com/publishlab/node-acme-client/compare/v1.27.9...v1.28.0) (2024-11-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.27.9](https://github.com/publishlab/node-acme-client/compare/v1.27.8...v1.27.9) (2024-11-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.27.8](https://github.com/publishlab/node-acme-client/compare/v1.27.7...v1.27.8) (2024-11-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.27.7](https://github.com/publishlab/node-acme-client/compare/v1.27.6...v1.27.7) (2024-11-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
|
## [1.27.6](https://github.com/publishlab/node-acme-client/compare/v1.27.5...v1.27.6) (2024-11-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|
||||||
## [1.27.5](https://github.com/publishlab/node-acme-client/compare/v1.27.4...v1.27.5) (2024-11-18)
|
## [1.27.5](https://github.com/publishlab/node-acme-client/compare/v1.27.4...v1.27.5) (2024-11-18)
|
||||||
|
|
||||||
**Note:** Version bump only for package @certd/acme-client
|
**Note:** Version bump only for package @certd/acme-client
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "Simple and unopinionated ACME client",
|
"description": "Simple and unopinionated ACME client",
|
||||||
"private": false,
|
"private": false,
|
||||||
"author": "nmorsman",
|
"author": "nmorsman",
|
||||||
"version": "1.27.5",
|
"version": "1.36.19",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "scr/index.js",
|
"module": "scr/index.js",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"types"
|
"types"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.27.5",
|
"@certd/basic": "^1.36.19",
|
||||||
"@peculiar/x509": "^1.11.0",
|
"@peculiar/x509": "^1.11.0",
|
||||||
"asn1js": "^3.0.5",
|
"asn1js": "^3.0.5",
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
@@ -26,10 +26,13 @@
|
|||||||
"http-proxy-agent": "^7.0.2",
|
"http-proxy-agent": "^7.0.2",
|
||||||
"https-proxy-agent": "^7.0.5",
|
"https-proxy-agent": "^7.0.5",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"node-forge": "^1.3.1"
|
"node-forge": "^1.3.1",
|
||||||
|
"punycode.js": "^2.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.14.10",
|
"@types/node": "^20.14.10",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||||
|
"@typescript-eslint/parser": "^8.26.1",
|
||||||
"chai": "^4.4.1",
|
"chai": "^4.4.1",
|
||||||
"chai-as-promised": "^7.1.2",
|
"chai-as-promised": "^7.1.2",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
@@ -48,7 +51,8 @@
|
|||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"lint-types": "tsd",
|
"lint-types": "tsd",
|
||||||
"prepublishOnly": "npm run build-docs",
|
"prepublishOnly": "npm run build-docs",
|
||||||
"test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\""
|
"test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\"",
|
||||||
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -65,5 +69,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "339554bdbf61c4784614747734a420e744e13bfb"
|
"gitHead": "6d8981479517b5de9634e242c1ebf22e70527ec4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* ACME auto helper
|
* ACME auto helper
|
||||||
*/
|
*/
|
||||||
import { readCsrDomains } from './crypto/index.js';
|
import { readCsrDomains } from "./crypto/index.js";
|
||||||
import { log } from './logger.js';
|
import { log } from "./logger.js";
|
||||||
import { wait } from './wait.js';
|
import { wait } from "./wait.js";
|
||||||
import { CancelError } from './error.js';
|
import { CancelError } from "./error.js";
|
||||||
|
|
||||||
|
|
||||||
const defaultOpts = {
|
const defaultOpts = {
|
||||||
@@ -13,13 +13,13 @@ const defaultOpts = {
|
|||||||
preferredChain: null,
|
preferredChain: null,
|
||||||
termsOfServiceAgreed: false,
|
termsOfServiceAgreed: false,
|
||||||
skipChallengeVerification: false,
|
skipChallengeVerification: false,
|
||||||
challengePriority: ['http-01', 'dns-01'],
|
challengePriority: ["http-01", "dns-01"],
|
||||||
challengeCreateFn: async () => {
|
challengeCreateFn: async () => {
|
||||||
throw new Error('Missing challengeCreateFn()');
|
throw new Error("Missing challengeCreateFn()");
|
||||||
},
|
},
|
||||||
challengeRemoveFn: async () => {
|
challengeRemoveFn: async () => {
|
||||||
throw new Error('Missing challengeRemoveFn()');
|
throw new Error("Missing challengeRemoveFn()");
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,14 +49,13 @@ export default async (client, userOpts) => {
|
|||||||
* Register account
|
* Register account
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log('[auto] Checking account');
|
log("[auto] Checking account");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getAccountUrl();
|
client.getAccountUrl();
|
||||||
log('[auto] Account URL already exists, skipping account registration');
|
log("[auto] Account URL already exists, skipping account registration( 证书申请账户已存在,跳过注册 )");
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
log("[auto] Registering account (注册证书申请账户)");
|
||||||
log('[auto] Registering account');
|
|
||||||
await client.createAccount(accountPayload);
|
await client.createAccount(accountPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +63,7 @@ export default async (client, userOpts) => {
|
|||||||
* Parse domains from CSR
|
* Parse domains from CSR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log('[auto] Parsing domains from Certificate Signing Request');
|
log("[auto] Parsing domains from Certificate Signing Request ");
|
||||||
const { commonName, altNames } = readCsrDomains(opts.csr);
|
const { commonName, altNames } = readCsrDomains(opts.csr);
|
||||||
const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d)));
|
const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d)));
|
||||||
|
|
||||||
@@ -74,8 +73,11 @@ export default async (client, userOpts) => {
|
|||||||
* Place order
|
* Place order
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log('[auto] Placing new certificate order with ACME provider');
|
log("[auto] Placing new certificate order with ACME provider");
|
||||||
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: 'dns', value: d })) };
|
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: "dns", value: d })) };
|
||||||
|
if (opts.profile && client.sslProvider === 'letsencrypt' ){
|
||||||
|
orderPayload.profile = opts.profile;
|
||||||
|
}
|
||||||
const order = await client.createOrder(orderPayload);
|
const order = await client.createOrder(orderPayload);
|
||||||
const authorizations = await client.getAuthorizations(order);
|
const authorizations = await client.getAuthorizations(order);
|
||||||
|
|
||||||
@@ -85,99 +87,81 @@ export default async (client, userOpts) => {
|
|||||||
* Resolve and satisfy challenges
|
* Resolve and satisfy challenges
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log('[auto] Resolving and satisfying authorization challenges');
|
log("[auto] Resolving and satisfying authorization challenges");
|
||||||
|
|
||||||
const clearTasks = [];
|
const clearTasks = [];
|
||||||
|
const localVerifyTasks = [];
|
||||||
|
const completeChallengeTasks = [];
|
||||||
|
|
||||||
const challengeFunc = async (authz) => {
|
const challengeFunc = async (authz) => {
|
||||||
const d = authz.identifier.value;
|
const d = authz.identifier.value;
|
||||||
let challengeCompleted = false;
|
let challengeCompleted = false;
|
||||||
|
|
||||||
/* Skip authz that already has valid status */
|
/* Skip authz that already has valid status */
|
||||||
if (authz.status === 'valid') {
|
if (authz.status === "valid") {
|
||||||
log(`[auto] [${d}] Authorization already has valid status, no need to complete challenges`);
|
log(`[auto] [${d}] Authorization already has valid status, no need to complete challenges`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
const keyAuthorizationGetter = async (challenge) => {
|
||||||
/* Select challenge based on priority */
|
return await client.getChallengeKeyAuthorization(challenge);
|
||||||
const challenge = authz.challenges.sort((a, b) => {
|
};
|
||||||
const aidx = opts.challengePriority.indexOf(a.type);
|
|
||||||
const bidx = opts.challengePriority.indexOf(b.type);
|
|
||||||
|
|
||||||
if (aidx === -1) return 1;
|
async function deactivateAuth(e) {
|
||||||
if (bidx === -1) return -1;
|
|
||||||
return aidx - bidx;
|
|
||||||
}).slice(0, 1)[0];
|
|
||||||
|
|
||||||
if (!challenge) {
|
|
||||||
throw new Error(`Unable to select challenge for ${d}, no challenge found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
log(`[auto] [${d}] Found ${authz.challenges.length} challenges, selected type: ${challenge.type}`);
|
|
||||||
|
|
||||||
/* Trigger challengeCreateFn() */
|
|
||||||
log(`[auto] [${d}] Trigger challengeCreateFn()`);
|
|
||||||
const keyAuthorization = await client.getChallengeKeyAuthorization(challenge);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { recordReq, recordRes, dnsProvider } = await opts.challengeCreateFn(authz, challenge, keyAuthorization);
|
|
||||||
log(`[auto] [${d}] challengeCreateFn success`);
|
|
||||||
log(`[auto] [${d}] add challengeRemoveFn()`);
|
|
||||||
clearTasks.push(async () => {
|
|
||||||
/* Trigger challengeRemoveFn(), suppress errors */
|
|
||||||
log(`[auto] [${d}] Trigger challengeRemoveFn()`);
|
|
||||||
try {
|
|
||||||
await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// throw new Error('测试异常');
|
|
||||||
/* Challenge verification */
|
|
||||||
if (opts.skipChallengeVerification === true) {
|
|
||||||
log(`[auto] [${d}] Skipping challenge verification since skipChallengeVerification=true,wait 60s`);
|
|
||||||
await wait(60 * 1000);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log(`[auto] [${d}] Running challenge verification`);
|
|
||||||
try {
|
|
||||||
await client.verifyChallenge(authz, challenge);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
log(`[auto] [${d}] challenge verification threw error: ${e.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Complete challenge and wait for valid status */
|
|
||||||
log(`[auto] [${d}] Completing challenge with ACME provider and waiting for valid status`);
|
|
||||||
await client.completeChallenge(challenge);
|
|
||||||
challengeCompleted = true;
|
|
||||||
|
|
||||||
await client.waitForValidStatus(challenge);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
log(`[auto] [${d}] challengeCreateFn threw error: ${e.message}`);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
/* Deactivate pending authz when unable to complete challenge */
|
|
||||||
if (!challengeCompleted) {
|
|
||||||
log(`[auto] [${d}] Unable to complete challenge: ${e.message}`);
|
log(`[auto] [${d}] Unable to complete challenge: ${e.message}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log(`[auto] [${d}] Deactivating failed authorization`);
|
log(`[auto] [${d}] Deactivating failed authorization`);
|
||||||
await client.deactivateAuthorization(authz);
|
await client.deactivateAuthorization(authz);
|
||||||
}
|
} catch (f) {
|
||||||
catch (f) {
|
|
||||||
/* Suppress deactivateAuthorization() errors */
|
/* Suppress deactivateAuthorization() errors */
|
||||||
log(`[auto] [${d}] Authorization deactivation threw error: ${f.message}`);
|
log(`[auto] [${d}] Authorization deactivation threw error: ${f.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(`[auto] [${d}] Trigger challengeCreateFn()`);
|
||||||
|
try {
|
||||||
|
const { recordReq, recordRes, dnsProvider, challenge, keyAuthorization ,httpUploader} = await opts.challengeCreateFn(authz, keyAuthorizationGetter);
|
||||||
|
clearTasks.push(async () => {
|
||||||
|
/* Trigger challengeRemoveFn(), suppress errors */
|
||||||
|
log(`[auto] [${d}] Trigger challengeRemoveFn()`);
|
||||||
|
try {
|
||||||
|
await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordReq, recordRes, dnsProvider,httpUploader);
|
||||||
|
} catch (e) {
|
||||||
|
log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
localVerifyTasks.push(async () => {
|
||||||
|
/* Challenge verification */
|
||||||
|
log(`[auto] [${d}] 开始本地验证, type = ${challenge.type}`);
|
||||||
|
try {
|
||||||
|
await client.verifyChallenge(authz, challenge);
|
||||||
|
} catch (e) {
|
||||||
|
log(`[auto] [${d}] 本地验证失败,尝试请求ACME提供商获取状态: ${e.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
completeChallengeTasks.push(async () => {
|
||||||
|
/* Complete challenge and wait for valid status */
|
||||||
|
log(`[auto] [${d}] 请求ACME提供商完成验证`);
|
||||||
|
try{
|
||||||
|
await client.completeChallenge(challenge);
|
||||||
|
}catch (e) {
|
||||||
|
await deactivateAuth(e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
challengeCompleted = true;
|
||||||
|
log(`[auto] [${d}] 等待返回valid状态`);
|
||||||
|
await client.waitForValidStatus(challenge,d);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
log(`[auto] [${d}] challengeCreateFn threw error: ${e.message}`);
|
||||||
|
await deactivateAuth(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
const domainSets = [];
|
const domainSets = [];
|
||||||
|
|
||||||
@@ -185,7 +169,7 @@ export default async (client, userOpts) => {
|
|||||||
const d = authz.identifier.value;
|
const d = authz.identifier.value;
|
||||||
log(`authorization:domain = ${d}, value = ${JSON.stringify(authz)}`);
|
log(`authorization:domain = ${d}, value = ${JSON.stringify(authz)}`);
|
||||||
|
|
||||||
if (authz.status === 'valid') {
|
if (authz.status === "valid") {
|
||||||
log(`[auto] [${d}] Authorization already has valid status, no need to complete challenges`);
|
log(`[auto] [${d}] Authorization already has valid status, no need to complete challenges`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -209,8 +193,9 @@ export default async (client, userOpts) => {
|
|||||||
|
|
||||||
const allChallengePromises = [];
|
const allChallengePromises = [];
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
for (const domainSet of domainSets) {
|
|
||||||
const challengePromises = [];
|
const challengePromises = [];
|
||||||
|
allChallengePromises.push(challengePromises);
|
||||||
|
for (const domainSet of domainSets) {
|
||||||
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
||||||
for (const domain in domainSet) {
|
for (const domain in domainSet) {
|
||||||
const authz = domainSet[domain];
|
const authz = domainSet[domain];
|
||||||
@@ -219,12 +204,11 @@ export default async (client, userOpts) => {
|
|||||||
await challengeFunc(authz);
|
await challengeFunc(authz);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
allChallengePromises.push(challengePromises);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log(`[auto] challengeGroups:${allChallengePromises.length}`);
|
log(`[auto] challengeGroups:${allChallengePromises.length}`);
|
||||||
|
|
||||||
function runAllPromise(tasks) {
|
async function runAllPromise(tasks) {
|
||||||
let promise = Promise.resolve();
|
let promise = Promise.resolve();
|
||||||
tasks.forEach((task) => {
|
tasks.forEach((task) => {
|
||||||
promise = promise.then(task);
|
promise = promise.then(task);
|
||||||
@@ -232,18 +216,21 @@ export default async (client, userOpts) => {
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runPromisePa(tasks) {
|
async function runPromisePa(tasks, waitTime = 8000) {
|
||||||
const results = [];
|
const results = [];
|
||||||
|
let j = 0
|
||||||
// eslint-disable-next-line no-await-in-loop,no-restricted-syntax
|
// eslint-disable-next-line no-await-in-loop,no-restricted-syntax
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
|
j++
|
||||||
|
log(`开始第${j}个任务`);
|
||||||
results.push(task());
|
results.push(task());
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await wait(10000);
|
log(`wait ${Math.floor(waitTime/1000)}s`)
|
||||||
|
await wait(waitTime);
|
||||||
}
|
}
|
||||||
return Promise.all(results);
|
return Promise.all(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
log(`开始challenge,共${allChallengePromises.length}组`);
|
log(`开始challenge,共${allChallengePromises.length}组`);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
@@ -251,54 +238,44 @@ export default async (client, userOpts) => {
|
|||||||
i += 1;
|
i += 1;
|
||||||
log(`开始第${i}组`);
|
log(`开始第${i}组`);
|
||||||
if (opts.signal && opts.signal.aborted) {
|
if (opts.signal && opts.signal.aborted) {
|
||||||
throw new CancelError('用户取消');
|
throw new CancelError("用户取消");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const waitDnsDiffuseTime = opts.waitDnsDiffuseTime || 30;
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await runPromisePa(challengePromises);
|
await runPromisePa(challengePromises);
|
||||||
|
if (opts.skipChallengeVerification === true) {
|
||||||
|
log(`跳过本地验证(skipChallengeVerification=true),等待 60s`);
|
||||||
|
await wait(60 * 1000);
|
||||||
|
} else {
|
||||||
|
log("开始本地校验")
|
||||||
|
await runPromisePa(localVerifyTasks, 1000);
|
||||||
|
log(`本地校验完成,等待${waitDnsDiffuseTime}s`)
|
||||||
|
await wait(waitDnsDiffuseTime * 1000)
|
||||||
}
|
}
|
||||||
catch (e) {
|
|
||||||
|
log("开始向提供商请求挑战验证");
|
||||||
|
await runPromisePa(completeChallengeTasks, 1000);
|
||||||
|
} catch (e) {
|
||||||
log(`证书申请失败${e.message}`);
|
log(`证书申请失败${e.message}`);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
if (client.opts.sslProvider !== 'google') {
|
|
||||||
// letsencrypt 如果同时检出两个TXT记录,会以第一个为准,就会校验失败,所以需要提前删除
|
// letsencrypt 如果同时检出两个TXT记录,会以第一个为准,就会校验失败,所以需要提前删除
|
||||||
// zerossl 此方式测试无问题
|
// zerossl 此方式测试无问题
|
||||||
log(`清理challenge痕迹,length:${clearTasks.length}`);
|
log(`清理challenge痕迹,length:${clearTasks.length}`);
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await runAllPromise(clearTasks);
|
await runAllPromise(clearTasks);
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
log("清理challenge失败");
|
||||||
log('清理challenge失败');
|
|
||||||
log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (client.opts.sslProvider === 'google') {
|
|
||||||
// google 相同的域名txt记录是一样的,不能提前删除,否则校验失败,报错如下
|
|
||||||
// Error: The TXT record retrieved from _acme-challenge.bbc.handsfree.work.
|
|
||||||
// at the time the challenge was validated did not contain JshHVu7dt_DT6uYILWhokHefFVad2Q6Mw1L-fNZFcq8
|
|
||||||
// (the base64url-encoded SHA-256 digest of RlJZNBR0LWnxNK_xd2zqtYVvCiNJOKJ3J1NmCjU_9BjaUJgL3k-qSpIhQ-uF4FBS.NRyqT8fRiq6THzzrvkgzgR5Xai2LsA2SyGLAq_wT3qc).
|
|
||||||
// See https://tools.ietf.org/html/rfc8555#section-8.4 for more information.
|
|
||||||
log(`清理challenge痕迹,length:${clearTasks.length}`);
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
|
||||||
await runAllPromise(clearTasks);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
log('清理challenge失败');
|
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log('challenge结束');
|
|
||||||
|
log("challenge结束");
|
||||||
|
|
||||||
// log('[auto] Waiting for challenge valid status');
|
// log('[auto] Waiting for challenge valid status');
|
||||||
// await Promise.all(challengePromises);
|
// await Promise.all(challengePromises);
|
||||||
@@ -306,7 +283,7 @@ export default async (client, userOpts) => {
|
|||||||
* Finalize order and download certificate
|
* Finalize order and download certificate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log('[auto] Finalizing order and downloading certificate');
|
log("[auto] Finalizing order and downloading certificate");
|
||||||
const finalized = await client.finalizeOrder(order, opts.csr);
|
const finalized = await client.finalizeOrder(order, opts.csr);
|
||||||
const res = await client.getCertificate(finalized, opts.preferredChain);
|
const res = await client.getCertificate(finalized, opts.preferredChain);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ instance.interceptors.response.use(null, async (error) => {
|
|||||||
|
|
||||||
/* Wait and retry the request */
|
/* Wait and retry the request */
|
||||||
await new Promise((resolve) => { setTimeout(resolve, (retryAfter * 1000)); });
|
await new Promise((resolve) => { setTimeout(resolve, (retryAfter * 1000)); });
|
||||||
|
log(`Retrying request to URL ${config.url}`);
|
||||||
return instance(config);
|
return instance(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,10 +90,12 @@ const defaultOpts = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class AcmeClient {
|
class AcmeClient {
|
||||||
|
sslProvider
|
||||||
constructor(opts) {
|
constructor(opts) {
|
||||||
if (!Buffer.isBuffer(opts.accountKey)) {
|
if (!Buffer.isBuffer(opts.accountKey)) {
|
||||||
opts.accountKey = Buffer.from(opts.accountKey);
|
opts.accountKey = Buffer.from(opts.accountKey);
|
||||||
}
|
}
|
||||||
|
this.sslProvider = opts.sslProvider;
|
||||||
|
|
||||||
this.opts = { ...defaultOpts, ...opts };
|
this.opts = { ...defaultOpts, ...opts };
|
||||||
this.backoffOpts = {
|
this.backoffOpts = {
|
||||||
@@ -500,7 +502,7 @@ class AcmeClient {
|
|||||||
await verify[challenge.type](authz, challenge, keyAuthorization);
|
await verify[challenge.type](authz, challenge, keyAuthorization);
|
||||||
};
|
};
|
||||||
|
|
||||||
log('Waiting for ACME challenge verification', this.backoffOpts);
|
log('Waiting for ACME challenge verification(等待ACME挑战验证)', this.backoffOpts);
|
||||||
return util.retry(verifyFn, this.backoffOpts);
|
return util.retry(verifyFn, this.backoffOpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,9 +556,9 @@ class AcmeClient {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async waitForValidStatus(item) {
|
async waitForValidStatus(item,d) {
|
||||||
if (!item.url) {
|
if (!item.url) {
|
||||||
throw new Error('Unable to verify status of item, URL not found');
|
throw new Error(`[${d}] Unable to verify status of item, URL not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const verifyFn = async (abort) => {
|
const verifyFn = async (abort) => {
|
||||||
@@ -568,23 +570,23 @@ class AcmeClient {
|
|||||||
const resp = await this.api.apiRequest(item.url, null, [200]);
|
const resp = await this.api.apiRequest(item.url, null, [200]);
|
||||||
|
|
||||||
/* Verify status */
|
/* Verify status */
|
||||||
log(`Item has status: ${resp.data.status}`);
|
log(`[${d}] Item has status(挑战状态): ${resp.data.status}`);
|
||||||
|
|
||||||
if (invalidStates.includes(resp.data.status)) {
|
if (invalidStates.includes(resp.data.status)) {
|
||||||
abort();
|
abort();
|
||||||
throw new Error(util.formatResponseError(resp));
|
throw new Error(util.formatResponseError(resp));
|
||||||
}
|
}
|
||||||
else if (pendingStates.includes(resp.data.status)) {
|
else if (pendingStates.includes(resp.data.status)) {
|
||||||
throw new Error('Operation is pending or processing');
|
throw new Error(`[${d}] Operation is pending or processing(当前仍然在等待状态)`);
|
||||||
}
|
}
|
||||||
else if (validStates.includes(resp.data.status)) {
|
else if (validStates.includes(resp.data.status)) {
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Unexpected item status: ${resp.data.status}`);
|
throw new Error(`[${d}] Unexpected item status: ${resp.data.status}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
log(`Waiting for valid status from: ${item.url}`, this.backoffOpts);
|
log(`[${d}] Waiting for valid status (等待valid状态): ${item.url}`, this.backoffOpts);
|
||||||
return util.retry(verifyFn, this.backoffOpts);
|
return util.retry(verifyFn, this.backoffOpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ export class CancelError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export const directory = {
|
|||||||
staging: 'https://acme.zerossl.com/v2/DV90',
|
staging: 'https://acme.zerossl.com/v2/DV90',
|
||||||
production: 'https://acme.zerossl.com/v2/DV90',
|
production: 'https://acme.zerossl.com/v2/DV90',
|
||||||
},
|
},
|
||||||
|
sslcom:{
|
||||||
|
staging: 'https://acme.ssl.com/sslcom-dv-rsa',
|
||||||
|
production: 'https://acme.ssl.com/sslcom-dv-rsa',
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,3 +50,5 @@ export * from './axios.js'
|
|||||||
export * from './logger.js'
|
export * from './logger.js'
|
||||||
export * from './verify.js'
|
export * from './verify.js'
|
||||||
export * from './error.js'
|
export * from './error.js'
|
||||||
|
|
||||||
|
export * from './util.js'
|
||||||
@@ -60,8 +60,9 @@ async function retryPromise(fn, attempts, backoff) {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(`Promise rejected: ${e.message}`);
|
||||||
const duration = backoff.duration();
|
const duration = backoff.duration();
|
||||||
log(`Promise rejected attempt #${backoff.attempts}, retrying in ${duration}ms: ${e.message}`);
|
log(`Promise rejected attempt #${backoff.attempts}, ${duration}ms 后重试: ${e.message}`);
|
||||||
|
|
||||||
await new Promise((resolve) => { setTimeout(resolve, duration); });
|
await new Promise((resolve) => { setTimeout(resolve, duration); });
|
||||||
return retryPromise(fn, attempts, backoff);
|
return retryPromise(fn, attempts, backoff);
|
||||||
@@ -218,15 +219,15 @@ function formatResponseError(resp) {
|
|||||||
async function resolveDomainBySoaRecord(recordName) {
|
async function resolveDomainBySoaRecord(recordName) {
|
||||||
try {
|
try {
|
||||||
await dns.resolveSoa(recordName);
|
await dns.resolveSoa(recordName);
|
||||||
log(`Found SOA record, considering domain to be: ${recordName}`);
|
log(`找到${recordName}的SOA记录`);
|
||||||
return recordName;
|
return recordName;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
log(`Unable to locate SOA record for name: ${recordName}`);
|
log(`找不到${recordName}的SOA记录,继续往主域名查找`);
|
||||||
const parentRecordName = recordName.split('.').slice(1).join('.');
|
const parentRecordName = recordName.split('.').slice(1).join('.');
|
||||||
|
|
||||||
if (!parentRecordName.includes('.')) {
|
if (!parentRecordName.includes('.')) {
|
||||||
throw new Error('Unable to resolve domain by SOA record');
|
throw new Error('SOA record查找失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolveDomainBySoaRecord(parentRecordName);
|
return resolveDomainBySoaRecord(parentRecordName);
|
||||||
@@ -241,7 +242,7 @@ async function resolveDomainBySoaRecord(recordName) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
async function getAuthoritativeDnsResolver(recordName) {
|
async function getAuthoritativeDnsResolver(recordName) {
|
||||||
log(`Locating authoritative NS records for name: ${recordName}`);
|
log(`获取域名${recordName}的权威NS服务器: `);
|
||||||
const resolver = new dns.Resolver();
|
const resolver = new dns.Resolver();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -249,13 +250,14 @@ async function getAuthoritativeDnsResolver(recordName) {
|
|||||||
const domain = await resolveDomainBySoaRecord(recordName);
|
const domain = await resolveDomainBySoaRecord(recordName);
|
||||||
|
|
||||||
/* Resolve authoritative NS addresses */
|
/* Resolve authoritative NS addresses */
|
||||||
log(`Looking up authoritative NS records for domain: ${domain}`);
|
log(`获取到权威NS服务器name: ${domain}`);
|
||||||
const nsRecords = await dns.resolveNs(domain);
|
const nsRecords = await dns.resolveNs(domain);
|
||||||
|
log(`域名权威NS服务器:${nsRecords}`);
|
||||||
const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r)));
|
const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r)));
|
||||||
const nsAddresses = [].concat(...nsAddrArray).filter((a) => a);
|
const nsAddresses = [].concat(...nsAddrArray).filter((a) => a);
|
||||||
|
|
||||||
if (!nsAddresses.length) {
|
if (!nsAddresses.length) {
|
||||||
throw new Error(`Unable to locate any valid authoritative NS addresses for domain: ${domain}`);
|
throw new Error(`Unable to locate any valid authoritative NS addresses for domain(获取权威服务器IP失败): ${domain}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Authoritative NS success */
|
/* Authoritative NS success */
|
||||||
@@ -263,12 +265,12 @@ async function getAuthoritativeDnsResolver(recordName) {
|
|||||||
resolver.setServers(nsAddresses);
|
resolver.setServers(nsAddresses);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
log(`Authoritative NS lookup error: ${e.message}`);
|
log(`Authoritative NS lookup error(获取权威NS服务器地址失败): ${e.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return resolver */
|
/* Return resolver */
|
||||||
const addresses = resolver.getServers();
|
const addresses = resolver.getServers();
|
||||||
log(`DNS resolver addresses: ${addresses.join(', ')}`);
|
log(`DNS resolver addresses(域名的权威NS服务器地址): ${addresses.join(', ')}`);
|
||||||
|
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
@@ -338,5 +340,6 @@ export {
|
|||||||
formatResponseError,
|
formatResponseError,
|
||||||
getAuthoritativeDnsResolver,
|
getAuthoritativeDnsResolver,
|
||||||
retrieveTlsAlpnCertificate,
|
retrieveTlsAlpnCertificate,
|
||||||
|
resolveDomainBySoaRecord
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,21 +24,45 @@ const dns = dnsSdk.promises
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix = `/.well-known/acme-challenge/${challenge.token}`) {
|
async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix = `/.well-known/acme-challenge/${challenge.token}`) {
|
||||||
const httpPort = axios.defaults.acmeSettings.httpChallengePort || 80;
|
|
||||||
const challengeUrl = `http://${authz.identifier.value}:${httpPort}${suffix}`;
|
async function doQuery(challengeUrl){
|
||||||
|
log(`正在测试请求 ${challengeUrl} `)
|
||||||
|
// const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443;
|
||||||
|
// const challengeUrl = `https://${authz.identifier.value}:${httpsPort}${suffix}`;
|
||||||
|
|
||||||
/* May redirect to HTTPS with invalid/self-signed cert - https://letsencrypt.org/docs/challenge-types/#http-01-challenge */
|
/* May redirect to HTTPS with invalid/self-signed cert - https://letsencrypt.org/docs/challenge-types/#http-01-challenge */
|
||||||
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
||||||
|
|
||||||
log(`Sending HTTP query to ${authz.identifier.value}, suffix: ${suffix}, port: ${httpPort}`);
|
log(`Sending HTTP query to ${authz.identifier.value}, suffix: ${suffix}, port: ${httpPort}`);
|
||||||
|
let data = ""
|
||||||
|
try{
|
||||||
const resp = await axios.get(challengeUrl, { httpsAgent });
|
const resp = await axios.get(challengeUrl, { httpsAgent });
|
||||||
const data = (resp.data || '').replace(/\s+$/, '');
|
data = (resp.data || '').replace(/\s+$/, '');
|
||||||
|
}catch (e) {
|
||||||
log(`Query successful, HTTP status code: ${resp.status}`);
|
log(`[error] HTTP request error from ${authz.identifier.value}`,e.message);
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (!data || (data !== keyAuthorization)) {
|
if (!data || (data !== keyAuthorization)) {
|
||||||
throw new Error(`Authorization not found in HTTP response from ${authz.identifier.value}`);
|
log(`[error] Authorization not found in HTTP response from ${authz.identifier.value}`);
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const httpPort = axios.defaults.acmeSettings.httpChallengePort || 80;
|
||||||
|
const challengeUrl = `http://${authz.identifier.value}:${httpPort}${suffix}`;
|
||||||
|
|
||||||
|
if (!await doQuery(challengeUrl)) {
|
||||||
|
const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443;
|
||||||
|
const httpsChallengeUrl = `https://${authz.identifier.value}:${httpsPort}${suffix}`;
|
||||||
|
const res = await doQuery(httpsChallengeUrl)
|
||||||
|
if (!res) {
|
||||||
|
throw new Error(`[error] 验证失败,请检查以上测试url是否可以正常访问`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
log(`Key authorization match for ${challenge.type}/${authz.identifier.value}, ACME challenge verified`);
|
log(`Key authorization match for ${challenge.type}/${authz.identifier.value}, ACME challenge verified`);
|
||||||
return true;
|
return true;
|
||||||
@@ -48,56 +72,86 @@ async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix =
|
|||||||
* Walk DNS until TXT records are found
|
* Walk DNS until TXT records are found
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function walkDnsChallengeRecord(recordName, resolver = dns) {
|
async function walkDnsChallengeRecord(recordName, resolver = dns,deep = 0) {
|
||||||
/* Resolve CNAME record first */
|
|
||||||
// try {
|
let records = [];
|
||||||
// log(`Checking name for CNAME records: ${recordName}`);
|
|
||||||
// const cnameRecords = await resolver.resolveCname(recordName);
|
|
||||||
//
|
|
||||||
// if (cnameRecords.length) {
|
|
||||||
// log(`CNAME record found at ${recordName}, new challenge record name: ${cnameRecords[0]}`);
|
|
||||||
// return walkDnsChallengeRecord(cnameRecords[0]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (e) {
|
|
||||||
// log(`No CNAME records found for name: ${recordName}`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* Resolve TXT records */
|
/* Resolve TXT records */
|
||||||
try {
|
try {
|
||||||
log(`Checking name for TXT records: ${recordName}`);
|
log(`检查域名 ${recordName} 的TXT记录`);
|
||||||
const txtRecords = await resolver.resolveTxt(recordName);
|
const txtRecords = await resolver.resolveTxt(recordName);
|
||||||
|
|
||||||
if (txtRecords && txtRecords.length) {
|
if (txtRecords && txtRecords.length) {
|
||||||
log(`Found ${txtRecords.length} TXT records at ${recordName}`);
|
log(`找到 ${txtRecords.length} 条 TXT记录( ${recordName})`);
|
||||||
log(`TXT records: ${JSON.stringify(txtRecords)}`);
|
log(`TXT records: ${JSON.stringify(txtRecords)}`);
|
||||||
return [].concat(...txtRecords);
|
records = records.concat(...txtRecords);
|
||||||
}
|
}
|
||||||
return [];
|
} catch (e) {
|
||||||
|
log(`解析 TXT 记录出错, ${recordName} :${e.message}`);
|
||||||
}
|
}
|
||||||
catch (e) {
|
|
||||||
log(`Resolve TXT records error, ${recordName} :${e.message}`);
|
/* Resolve CNAME record first */
|
||||||
throw e;
|
try {
|
||||||
|
log(`检查是否存在CNAME映射: ${recordName}`);
|
||||||
|
const cnameRecords = await resolver.resolveCname(recordName);
|
||||||
|
|
||||||
|
if (cnameRecords.length) {
|
||||||
|
const cnameRecord = cnameRecords[0];
|
||||||
|
log(`已找到${recordName}的CNAME记录,将检查: ${cnameRecord}`);
|
||||||
|
let res= await walkTxtRecord(cnameRecord,deep+1);
|
||||||
|
if (res && res.length) {
|
||||||
|
log(`从CNAME中找到TXT记录: ${JSON.stringify(res)}`);
|
||||||
|
records = records.concat(...res);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
log(`没有CNAME映射(${recordName})`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(`检查CNAME出错(${recordName}) :${e.message}`);
|
||||||
|
}
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function walkTxtRecord(recordName,deep = 0) {
|
||||||
|
if(deep >5){
|
||||||
|
log(`walkTxtRecord too deep (#${deep}) , skip walk`)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const txtRecords = []
|
||||||
|
try {
|
||||||
|
/* Default DNS resolver first */
|
||||||
|
log('从本地DNS服务器获取TXT解析记录');
|
||||||
|
const res = await walkDnsChallengeRecord(recordName,dns,deep);
|
||||||
|
if (res && res.length > 0) {
|
||||||
|
for (const item of res) {
|
||||||
|
txtRecords.push(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function walkTxtRecord(recordName) {
|
} catch (e) {
|
||||||
|
log(`本地获取TXT解析记录失败:${e.message}`)
|
||||||
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
/* Default DNS resolver first */
|
|
||||||
log('Attempting to resolve TXT with default DNS resolver first');
|
|
||||||
const res = await walkDnsChallengeRecord(recordName);
|
|
||||||
if (res && res.length > 0) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
throw new Error('No TXT records found');
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
/* Authoritative DNS resolver */
|
/* Authoritative DNS resolver */
|
||||||
log(`Error using default resolver, attempting to resolve TXT with authoritative NS: ${e.message}`);
|
log(`从域名权威服务器获取TXT解析记录`);
|
||||||
const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName);
|
const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName);
|
||||||
return await walkDnsChallengeRecord(recordName, authoritativeResolver);
|
const res = await walkDnsChallengeRecord(recordName, authoritativeResolver,deep);
|
||||||
|
if (res && res.length > 0) {
|
||||||
|
for (const item of res) {
|
||||||
|
txtRecords.push(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}catch (e) {
|
||||||
|
log(`权威服务器获取TXT解析记录失败:${e.message}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txtRecords.length === 0) {
|
||||||
|
throw new Error(`没有找到TXT解析记录(${recordName})`);
|
||||||
|
}
|
||||||
|
return txtRecords;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify ACME DNS challenge
|
* Verify ACME DNS challenge
|
||||||
@@ -113,14 +167,16 @@ export async function walkTxtRecord(recordName) {
|
|||||||
|
|
||||||
async function verifyDnsChallenge(authz, challenge, keyAuthorization, prefix = '_acme-challenge.') {
|
async function verifyDnsChallenge(authz, challenge, keyAuthorization, prefix = '_acme-challenge.') {
|
||||||
const recordName = `${prefix}${authz.identifier.value}`;
|
const recordName = `${prefix}${authz.identifier.value}`;
|
||||||
log(`Resolving DNS TXT from record: ${recordName}`);
|
log(`本地校验TXT记录): ${recordName}`);
|
||||||
const recordValues = await walkTxtRecord(recordName);
|
let recordValues = await walkTxtRecord(recordName);
|
||||||
log(`DNS query finished successfully, found ${recordValues.length} TXT records`);
|
//去重
|
||||||
|
recordValues = [...new Set(recordValues)];
|
||||||
|
log(`DNS查询成功, 找到 ${recordValues.length} 条TXT记录:${recordValues}`);
|
||||||
if (!recordValues.length || !recordValues.includes(keyAuthorization)) {
|
if (!recordValues.length || !recordValues.includes(keyAuthorization)) {
|
||||||
throw new Error(`Authorization not found in DNS TXT record: ${recordName},need:${keyAuthorization},found:${recordValues}`);
|
throw new Error(`没有找到需要的DNS TXT记录: ${recordName},期望:${keyAuthorization},结果:${recordValues}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
log(`Key authorization match for ${challenge.type}/${recordName}, ACME challenge verified`);
|
log(`关键授权匹配成功(${challenge.type}/${recordName}):${keyAuthorization},校验成功, ACME challenge verified`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import {assert} from 'chai'
|
||||||
|
import {resolveDomainBySoaRecord} from "../src/util.js"
|
||||||
|
describe('dns', () => {
|
||||||
|
it('resolveDomainBySoaRecord', async () => {
|
||||||
|
const resp = await resolveDomainBySoaRecord("a.corp.smartdeer.com")
|
||||||
|
|
||||||
|
assert.equal(resp, "smartdeer.com")
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
import { AxiosInstance } from 'axios';
|
import { AxiosInstance } from 'axios';
|
||||||
import * as rfc8555 from './rfc8555';
|
import * as rfc8555 from './rfc8555';
|
||||||
|
import {CancelError} from '../src/error.js'
|
||||||
|
export * from '../src/error.js'
|
||||||
|
|
||||||
export type PrivateKeyBuffer = Buffer;
|
export type PrivateKeyBuffer = Buffer;
|
||||||
export type PublicKeyBuffer = Buffer;
|
export type PublicKeyBuffer = Buffer;
|
||||||
@@ -56,14 +58,15 @@ export interface ClientExternalAccountBindingOptions {
|
|||||||
|
|
||||||
export interface ClientAutoOptions {
|
export interface ClientAutoOptions {
|
||||||
csr: CsrBuffer | CsrString;
|
csr: CsrBuffer | CsrString;
|
||||||
challengeCreateFn: (authz: Authorization, challenge: rfc8555.Challenge, keyAuthorization: string) => Promise<{recordReq:any,recordRes:any,dnsProvider:any}>;
|
challengeCreateFn: (authz: Authorization, keyAuthorization: (challenge:rfc8555.Challenge)=>Promise<string>) => Promise<{recordReq?:any,recordRes?:any,dnsProvider?:any,challenge: rfc8555.Challenge,keyAuthorization:string}>;
|
||||||
challengeRemoveFn: (authz: Authorization, challenge: rfc8555.Challenge, keyAuthorization: string,recordReq:any, recordRes:any,dnsProvider:any) => Promise<any>;
|
challengeRemoveFn: (authz: Authorization, challenge: rfc8555.Challenge, keyAuthorization: string,recordReq:any, recordRes:any,dnsProvider:any,httpUploader:any) => Promise<any>;
|
||||||
email?: string;
|
email?: string;
|
||||||
termsOfServiceAgreed?: boolean;
|
termsOfServiceAgreed?: boolean;
|
||||||
skipChallengeVerification?: boolean;
|
skipChallengeVerification?: boolean;
|
||||||
challengePriority?: string[];
|
challengePriority?: string[];
|
||||||
preferredChain?: string;
|
preferredChain?: string;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
|
profile?:string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Client {
|
export class Client {
|
||||||
@@ -201,5 +204,8 @@ export const agents: any;
|
|||||||
export function setLogger(fn: (message: any, ...args: any[]) => void): void;
|
export function setLogger(fn: (message: any, ...args: any[]) => void): void;
|
||||||
|
|
||||||
export function walkTxtRecord(record: any): Promise<string[]>;
|
export function walkTxtRecord(record: any): Promise<string[]>;
|
||||||
|
export function getAuthoritativeDnsResolver(record:string): Promise<any>;
|
||||||
|
|
||||||
export const CancelError: Error;
|
export const CancelError: typeof CancelError;
|
||||||
|
|
||||||
|
export function resolveDomainBySoaRecord(domain: string): Promise<string>;
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
"@typescript-eslint/ban-ts-ignore": "off",
|
"@typescript-eslint/ban-ts-ignore": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
// "no-unused-expressions": "off",
|
"@typescript-eslint/no-empty-function": "off",
|
||||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
"@typescript-eslint/no-unused-vars": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 220,
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"singleQuote": false,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
}
|
||||||
@@ -3,6 +3,378 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.36.19](https://github.com/certd/certd/compare/v1.36.18...v1.36.19) (2025-09-05)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复批量流水线执行时日志显示错乱的问题 ([4372adc](https://github.com/certd/certd/commit/4372adc703b9a4c785664054ab2a533626d815a8))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 去掉宝塔url后面的斜杠 ([8a0c2b9](https://github.com/certd/certd/commit/8a0c2b9b13628da750c25757e0cb8ed3038775ba))
|
||||||
|
|
||||||
|
## [1.36.18](https://github.com/certd/certd/compare/v1.36.17...v1.36.18) (2025-08-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.17](https://github.com/certd/certd/compare/v1.36.16...v1.36.17) (2025-08-17)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.16](https://github.com/certd/certd/compare/v1.36.15...v1.36.16) (2025-08-16)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.15](https://github.com/certd/certd/compare/v1.36.14...v1.36.15) (2025-08-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.14](https://github.com/certd/certd/compare/v1.36.13...v1.36.14) (2025-07-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.13](https://github.com/certd/certd/compare/v1.36.12...v1.36.13) (2025-07-23)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.12](https://github.com/certd/certd/compare/v1.36.11...v1.36.12) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.9](https://github.com/certd/certd/compare/v1.36.7...v1.36.9) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.7](https://github.com/certd/certd/compare/v1.36.6...v1.36.7) (2025-07-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.6](https://github.com/certd/certd/compare/v1.36.5...v1.36.6) (2025-07-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.5](https://github.com/certd/certd/compare/v1.36.4...v1.36.5) (2025-07-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.4](https://github.com/certd/certd/compare/v1.36.3...v1.36.4) (2025-07-10)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.3](https://github.com/certd/certd/compare/v1.36.2...v1.36.3) (2025-07-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.36.2](https://github.com/certd/certd/compare/v1.36.1...v1.36.2) (2025-07-06)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 证书检查支持自定义dns服务器 ([c53bb7c](https://github.com/certd/certd/commit/c53bb7cf677faa32729709ae0c10359db5194d7a))
|
||||||
|
|
||||||
|
## [1.36.1](https://github.com/certd/certd/compare/v1.36.0...v1.36.1) (2025-07-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.36.0](https://github.com/certd/certd/compare/v1.35.5...v1.36.0) (2025-07-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.5](https://github.com/certd/certd/compare/v1.35.4...v1.35.5) (2025-06-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.4](https://github.com/certd/certd/compare/v1.35.3...v1.35.4) (2025-06-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.3](https://github.com/certd/certd/compare/v1.35.2...v1.35.3) (2025-06-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.2](https://github.com/certd/certd/compare/v1.35.1...v1.35.2) (2025-06-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.35.1](https://github.com/certd/certd/compare/v1.35.0...v1.35.1) (2025-06-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.35.0](https://github.com/certd/certd/compare/v1.34.11...v1.35.0) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.11](https://github.com/certd/certd/compare/v1.34.10...v1.34.11) (2025-06-05)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.10](https://github.com/certd/certd/compare/v1.34.9...v1.34.10) (2025-06-03)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署到飞牛OS ([ddfd0fb](https://github.com/certd/certd/commit/ddfd0fb81d6638352920261065f1ab8e27bdd564))
|
||||||
|
* 支持日志写入文件 ([37edbf5](https://github.com/certd/certd/commit/37edbf5824d6aaae68ea1ef7259c6f739d418d2c))
|
||||||
|
|
||||||
|
## [1.34.9](https://github.com/certd/certd/compare/v1.34.8...v1.34.9) (2025-05-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.8](https://github.com/certd/certd/compare/v1.34.7...v1.34.8) (2025-05-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.7](https://github.com/certd/certd/compare/v1.34.6...v1.34.7) (2025-05-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.6](https://github.com/certd/certd/compare/v1.34.5...v1.34.6) (2025-05-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.5](https://github.com/certd/certd/compare/v1.34.4...v1.34.5) (2025-05-19)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署到宝塔aaWAF ([094565c](https://github.com/certd/certd/commit/094565ccd619ef671c6c11ce5fb7fd54a7a21d1c))
|
||||||
|
|
||||||
|
## [1.34.4](https://github.com/certd/certd/compare/v1.34.3...v1.34.4) (2025-05-16)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复导入在线插件不生效的bug ([fcf8309](https://github.com/certd/certd/commit/fcf8309c238208281ecb4575b2c3cfe50c11d783))
|
||||||
|
* 修复自建插件保存丢失部署策略的bug ([863e74d](https://github.com/certd/certd/commit/863e74dd2e3912f950ff5025b5ed0070aeb37035))
|
||||||
|
|
||||||
|
## [1.34.3](https://github.com/certd/certd/compare/v1.34.2...v1.34.3) (2025-05-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.2](https://github.com/certd/certd/compare/v1.34.1...v1.34.2) (2025-05-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.34.1](https://github.com/certd/certd/compare/v1.34.0...v1.34.1) (2025-05-05)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署证书到火山dcdn ([5f85219](https://github.com/certd/certd/commit/5f852194953dc1b4e6336770f417507b8f5a33ad))
|
||||||
|
|
||||||
|
# [1.34.0](https://github.com/certd/certd/compare/v1.33.8...v1.34.0) (2025-04-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.33.8](https://github.com/certd/certd/compare/v1.33.7...v1.33.8) (2025-04-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.33.7](https://github.com/certd/certd/compare/v1.33.6...v1.33.7) (2025-04-22)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持51dns ([96a0900](https://github.com/certd/certd/commit/96a0900edc95dcfd9acccf9d13592f12f5a09b3d))
|
||||||
|
|
||||||
|
## [1.33.6](https://github.com/certd/certd/compare/v1.33.5...v1.33.6) (2025-04-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.33.5](https://github.com/certd/certd/compare/v1.33.4...v1.33.5) (2025-04-17)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 多重认证登录 ([0f82cf4](https://github.com/certd/certd/commit/0f82cf409bc60706ab07e4ca4f272b9a1ca7eecb))
|
||||||
|
|
||||||
|
## [1.33.4](https://github.com/certd/certd/compare/v1.33.3...v1.33.4) (2025-04-15)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.33.3](https://github.com/certd/certd/compare/v1.33.2...v1.33.3) (2025-04-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.33.2](https://github.com/certd/certd/compare/v1.33.1...v1.33.2) (2025-04-12)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复某些情况下无法输出日志的bug ([70101bf](https://github.com/certd/certd/commit/70101bfa7ade65678d9202c804bbae2cb808b594))
|
||||||
|
|
||||||
|
## [1.33.1](https://github.com/certd/certd/compare/v1.33.0...v1.33.1) (2025-04-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.33.0](https://github.com/certd/certd/compare/v1.32.0...v1.33.0) (2025-04-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.32.0](https://github.com/certd/certd/compare/v1.31.11...v1.32.0) (2025-04-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.11](https://github.com/certd/certd/compare/v1.31.10...v1.31.11) (2025-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.10](https://github.com/certd/certd/compare/v1.31.9...v1.31.10) (2025-03-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.9](https://github.com/certd/certd/compare/v1.31.8...v1.31.9) (2025-03-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.8](https://github.com/certd/certd/compare/v1.31.7...v1.31.8) (2025-03-26)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持又拍云cdn ([fd0536b](https://github.com/certd/certd/commit/fd0536bd4b41f15b6b5d42e0b447f0dcbf73b8a8))
|
||||||
|
|
||||||
|
## [1.31.7](https://github.com/certd/certd/compare/v1.31.6...v1.31.7) (2025-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.6](https://github.com/certd/certd/compare/v1.31.5...v1.31.6) (2025-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.5](https://github.com/certd/certd/compare/v1.31.4...v1.31.5) (2025-03-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.4](https://github.com/certd/certd/compare/v1.31.3...v1.31.4) (2025-03-21)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.3](https://github.com/certd/certd/compare/v1.31.2...v1.31.3) (2025-03-13)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持部署到天翼云CDN ([82a72e0](https://github.com/certd/certd/commit/82a72e0b497efa043d342ad0e33c083a2de79a05))
|
||||||
|
|
||||||
|
## [1.31.2](https://github.com/certd/certd/compare/v1.31.1...v1.31.2) (2025-03-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.31.1](https://github.com/certd/certd/compare/v1.31.0...v1.31.1) (2025-03-11)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.31.0](https://github.com/certd/certd/compare/v1.30.6...v1.31.0) (2025-03-10)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 流水线同一个阶段任务优化为并行执行 ([efa9c74](https://github.com/certd/certd/commit/efa9c748c5c07fc950af3db742ef9310f1ac9a4b))
|
||||||
|
* 支持易盾RCDN部署 ([065713c](https://github.com/certd/certd/commit/065713cdb6953d16df08585c316c1a7a8eaec437))
|
||||||
|
|
||||||
|
## [1.30.6](https://github.com/certd/certd/compare/v1.30.5...v1.30.6) (2025-02-24)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 支持新版本LeCDN ([44d43f4](https://github.com/certd/certd/commit/44d43f45cb9094619df7494c2a64a51ba77ad116))
|
||||||
|
|
||||||
|
## [1.30.5](https://github.com/certd/certd/compare/v1.30.4...v1.30.5) (2025-02-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.30.4](https://github.com/certd/certd/compare/v1.30.3...v1.30.4) (2025-02-14)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.30.3](https://github.com/certd/certd/compare/v1.30.2...v1.30.3) (2025-02-13)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.30.2](https://github.com/certd/certd/compare/v1.30.1...v1.30.2) (2025-02-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.30.1](https://github.com/certd/certd/compare/v1.30.0...v1.30.1) (2025-01-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
# [1.30.0](https://github.com/certd/certd/compare/v1.29.5...v1.30.0) (2025-01-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.29.5](https://github.com/certd/certd/compare/v1.29.4...v1.29.5) (2025-01-07)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.29.4](https://github.com/certd/certd/compare/v1.29.3...v1.29.4) (2025-01-06)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.29.3](https://github.com/certd/certd/compare/v1.29.2...v1.29.3) (2025-01-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.29.2](https://github.com/certd/certd/compare/v1.29.1...v1.29.2) (2024-12-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.29.1](https://github.com/certd/certd/compare/v1.29.0...v1.29.1) (2024-12-25)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复某处金额转换丢失精度的bug ([d2d6f12](https://github.com/certd/certd/commit/d2d6f12218cbe7bd55f4ae082b93084be85f0a7b))
|
||||||
|
|
||||||
|
# [1.29.0](https://github.com/certd/certd/compare/v1.28.4...v1.29.0) (2024-12-24)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 用户套餐,用户支付功能 ([a019956](https://github.com/certd/certd/commit/a019956698acaf2c4beb620b5ad8c18918ead6a1))
|
||||||
|
* 支持微信支付 ([45d6347](https://github.com/certd/certd/commit/45d6347f5b6199493b11aabdd74177f6dca2cea4))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 站点证书监控通知发送,每天定时检查 ([bb4910f](https://github.com/certd/certd/commit/bb4910f4e57234e42b44505f4620ae7af66025c5))
|
||||||
|
* 支持plesk网站证书部署 ([eda45c1](https://github.com/certd/certd/commit/eda45c1528199648b3970505e87f492d398226cd))
|
||||||
|
|
||||||
|
## [1.28.4](https://github.com/certd/certd/compare/v1.28.3...v1.28.4) (2024-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.28.3](https://github.com/certd/certd/compare/v1.28.2...v1.28.3) (2024-12-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.28.2](https://github.com/certd/certd/compare/v1.28.1...v1.28.2) (2024-12-09)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.28.1](https://github.com/certd/certd/compare/v1.28.0...v1.28.1) (2024-12-08)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 通知选择器优化 ([2c0cbdd](https://github.com/certd/certd/commit/2c0cbdd29ecb74cc939b2ae7ee86b8d40f70ba31))
|
||||||
|
|
||||||
|
# [1.28.0](https://github.com/certd/certd/compare/v1.27.9...v1.28.0) (2024-11-30)
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化证书申请成功通知发送方式 ([8002a56](https://github.com/certd/certd/commit/8002a56efc5998aa03db5711ae87f9eb4bc9e160))
|
||||||
|
* 支持短信验证码登录 ([387bcc5](https://github.com/certd/certd/commit/387bcc5fa418cdeea81a06da5e3f8cd6b43cd082))
|
||||||
|
|
||||||
|
## [1.27.9](https://github.com/certd/certd/compare/v1.27.8...v1.27.9) (2024-11-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.27.8](https://github.com/certd/certd/compare/v1.27.7...v1.27.8) (2024-11-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.27.7](https://github.com/certd/certd/compare/v1.27.6...v1.27.7) (2024-11-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
|
## [1.27.6](https://github.com/certd/certd/compare/v1.27.5...v1.27.6) (2024-11-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @certd/basic
|
||||||
|
|
||||||
## [1.27.5](https://github.com/certd/certd/compare/v1.27.4...v1.27.5) (2024-11-18)
|
## [1.27.5](https://github.com/certd/certd/compare/v1.27.4...v1.27.5) (2024-11-18)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
21:57
|
00:30
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@certd/basic",
|
"name": "@certd/basic",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "1.27.5",
|
"version": "1.36.19",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.js",
|
"module": "./dist/index.js",
|
||||||
@@ -12,7 +12,8 @@
|
|||||||
"build": "npm run before-build && tsc --skipLibCheck",
|
"build": "npm run before-build && tsc --skipLibCheck",
|
||||||
"dev-build": "npm run build",
|
"dev-build": "npm run build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "mocha --loader=ts-node/esm"
|
"test": "mocha --loader=ts-node/esm",
|
||||||
|
"pub": "npm publish"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.7.2",
|
"axios": "^1.7.2",
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"log4js": "^6.9.1",
|
"log4js": "^6.9.1",
|
||||||
"lru-cache": "^10.0.0",
|
"lru-cache": "^10.0.0",
|
||||||
|
"mitt": "^3.0.1",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
"node-forge": "^1.3.1",
|
"node-forge": "^1.3.1",
|
||||||
"nodemailer": "^6.9.3"
|
"nodemailer": "^6.9.3"
|
||||||
@@ -32,8 +34,8 @@
|
|||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/mocha": "^10.0.1",
|
"@types/mocha": "^10.0.1",
|
||||||
"@types/node-forge": "^1.3.2",
|
"@types/node-forge": "^1.3.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||||
"@typescript-eslint/parser": "^5.59.7",
|
"@typescript-eslint/parser": "^8.26.1",
|
||||||
"chai": "4.3.10",
|
"chai": "4.3.10",
|
||||||
"eslint": "^8.41.0",
|
"eslint": "^8.41.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
@@ -43,5 +45,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "339554bdbf61c4784614747734a420e744e13bfb"
|
"gitHead": "6d8981479517b5de9634e242c1ebf22e70527ec4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,40 @@
|
|||||||
export * from './util.request.js';
|
export * from "./util.request.js";
|
||||||
export * from './util.env.js';
|
export * from "./util.env.js";
|
||||||
export * from './util.log.js';
|
export * from "./util.log.js";
|
||||||
export * from './util.file.js';
|
export * from "./util.file.js";
|
||||||
export * from './util.sp.js';
|
export * from "./util.sp.js";
|
||||||
export * from './util.promise.js';
|
export * from "./util.promise.js";
|
||||||
export * from './util.hash.js';
|
export * from "./util.hash.js";
|
||||||
export * from './util.merge.js';
|
export * from "./util.merge.js";
|
||||||
export * from './util.cache.js';
|
export * from "./util.cache.js";
|
||||||
export * from './util.string.js';
|
export * from "./util.string.js";
|
||||||
import { stringUtils } from './util.string.js';
|
export * from "./util.lock.js";
|
||||||
import sleep from './util.sleep.js';
|
export * from "./util.mitter.js";
|
||||||
import { http, download } from './util.request.js';
|
export * from "./util.id.js";
|
||||||
|
export * from "./util.domain.js";
|
||||||
|
export * from "./util.amount.js";
|
||||||
|
import { stringUtils } from "./util.string.js";
|
||||||
|
import sleep from "./util.sleep.js";
|
||||||
|
import { http, download } from "./util.request.js";
|
||||||
|
|
||||||
import { mergeUtils } from './util.merge.js';
|
import { mergeUtils } from "./util.merge.js";
|
||||||
import { sp } from './util.sp.js';
|
import { sp } from "./util.sp.js";
|
||||||
import { hashUtils } from './util.hash.js';
|
import { hashUtils } from "./util.hash.js";
|
||||||
import { promises } from './util.promise.js';
|
import { promises } from "./util.promise.js";
|
||||||
import { fileUtils } from './util.file.js';
|
import { fileUtils } from "./util.file.js";
|
||||||
import * as _ from 'lodash-es';
|
import * as _ from "lodash-es";
|
||||||
import { cache } from './util.cache.js';
|
import { cache } from "./util.cache.js";
|
||||||
import dayjs from 'dayjs';
|
import dayjs from "dayjs";
|
||||||
import { domainUtils } from './util.domain.js';
|
import { domainUtils } from "./util.domain.js";
|
||||||
import { optionsUtils } from './util.options.js';
|
import { optionsUtils } from "./util.options.js";
|
||||||
import { nanoid } from 'nanoid';
|
import { amountUtils } from "./util.amount.js";
|
||||||
import * as id from './util.id.js';
|
import { nanoid } from "nanoid";
|
||||||
|
import * as id from "./util.id.js";
|
||||||
|
import { locker } from "./util.lock.js";
|
||||||
|
import { mitter } from "./util.mitter.js";
|
||||||
|
|
||||||
|
import * as request from "./util.request.js";
|
||||||
|
export * from "./util.cache.js";
|
||||||
export const utils = {
|
export const utils = {
|
||||||
sleep,
|
sleep,
|
||||||
http,
|
http,
|
||||||
@@ -41,4 +52,8 @@ export const utils = {
|
|||||||
domain: domainUtils,
|
domain: domainUtils,
|
||||||
options: optionsUtils,
|
options: optionsUtils,
|
||||||
string: stringUtils,
|
string: stringUtils,
|
||||||
|
locker,
|
||||||
|
mitter,
|
||||||
|
amount: amountUtils,
|
||||||
|
request,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export const amountUtils = {
|
||||||
|
toCent(amount: number): number {
|
||||||
|
return parseInt((amount * 100).toFixed(0));
|
||||||
|
},
|
||||||
|
|
||||||
|
toYuan(amount: number): number {
|
||||||
|
return parseFloat((amount / 100).toFixed(2));
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,8 +1,53 @@
|
|||||||
// LRUCache
|
// LRUCache
|
||||||
|
|
||||||
import { LRUCache } from 'lru-cache';
|
import { LRUCache } from "lru-cache";
|
||||||
|
|
||||||
export const cache = new LRUCache<string, any>({
|
export const cache = new LRUCache<string, any>({
|
||||||
max: 1000,
|
max: 1000,
|
||||||
ttl: 1000 * 60 * 10,
|
ttl: 1000 * 60 * 10,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export class LocalCache<V = any> {
|
||||||
|
cache: Map<string, { value: V; expiresAt: number }>;
|
||||||
|
constructor(opts: { clearInterval?: number } = {}) {
|
||||||
|
this.cache = new Map();
|
||||||
|
setInterval(() => {
|
||||||
|
this.clearExpires();
|
||||||
|
}, opts.clearInterval ?? 5 * 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key: string): V | undefined {
|
||||||
|
const entry = this.cache.get(key);
|
||||||
|
if (!entry) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否过期
|
||||||
|
if (Date.now() > entry.expiresAt) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: string, value: V, ttl = 300000) {
|
||||||
|
// 默认5分钟 (300000毫秒)
|
||||||
|
this.cache.set(key, {
|
||||||
|
value,
|
||||||
|
expiresAt: Date.now() + ttl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearExpires() {
|
||||||
|
for (const [key, entry] of this.cache) {
|
||||||
|
if (entry.expiresAt < Date.now()) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||