Compare commits

...

176 Commits

Author SHA1 Message Date
zyb
d32177f1e7 modified: .github/workflows/mikrotik_patch_6.yml 2025-06-21 09:49:51 +08:00
zyb
2ad3d69a4d modified: .github/workflows/mikrotik_patch_7.yml 2025-06-21 09:47:49 +08:00
zyb
70819de5a4 modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 14:31:23 +08:00
zyb
f22db63a10 modified: npk.py 2025-06-19 13:48:23 +08:00
zyb
178ffcbadb modified: .github/workflows/mikrotik_patch_7.yml
modified:   patch.py
2025-06-19 13:45:31 +08:00
zyb
70bca68232 modified: npk.py
modified:   patch.py
2025-06-19 13:38:45 +08:00
zyb
4cdd6d5619 modified: patch.py 2025-06-19 13:31:48 +08:00
zyb
af97ad2a07 modified: .github/workflows/mikrotik_patch_7.yml
modified:   patch.py
2025-06-19 13:28:29 +08:00
zyb
fd50885bf4 modified: patch.py 2025-06-19 13:23:52 +08:00
zyb
2551551828 modified: .github/workflows/mikrotik_patch_7.yml
modified:   patch.py
2025-06-19 13:21:08 +08:00
zyb
d8f092eb80 modified: patch.py 2025-06-19 13:16:46 +08:00
zyb
fe68e753c6 modified: patch.py 2025-06-19 13:15:26 +08:00
zyb
9ca203dcad modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 13:11:50 +08:00
zyb
939e01725c modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 13:07:24 +08:00
zyb
1935f35864 modified: .github/workflows/mikrotik_patch_7.yml
modified:   npk.py
2025-06-19 12:48:56 +08:00
zyb
676f0e0f82 modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 12:43:23 +08:00
zyb
b50ba21932 modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 12:34:03 +08:00
zyb
78f63469c9 modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 12:30:13 +08:00
zyb
511392906b modified: .github/workflows/mikrotik_patch_7.yml 2025-06-19 12:22:59 +08:00
elseif
2d2ca3e493 Merge pull request #118 from PauloNRocha/main
Add Portuguese translation of README
2025-06-19 12:12:44 +08:00
zyb
3f988f27ed modified: .github/workflows/mikrotik_patch_7.yml
deleted:    .github/workflows/self_hosted_patch.yml
	modified:   .gitignore
2025-06-19 12:09:51 +08:00
elseif
8a2b8f629c Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 10:26:00 +08:00
elseif
2ce0f85f8a Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 10:17:52 +08:00
elseif
a07fe281f1 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 10:07:34 +08:00
elseif
70321348ad Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 10:04:58 +08:00
Paulo Rocha
6b1d9a4a62 minor spelling corrections 2025-06-18 23:04:09 -03:00
elseif
9f5f72bb03 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 10:00:30 +08:00
Paulo Rocha
173dfd69e3 Add Portuguese translation of README
Added README_PT.md with full Brazilian Portuguese translation of the original README. Helpful for Portuguese-speaking users.
2025-06-18 22:57:15 -03:00
elseif
f0698d8814 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 09:50:58 +08:00
elseif
db75ad1711 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 09:47:03 +08:00
elseif
f54f9f15b6 Update chr.sh
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 09:13:42 +08:00
elseif
17b37b7124 Delete mbr.bin
Signed-off-by: elseif <elseif@live.cn>
2025-06-19 09:09:13 +08:00
elseif
48ce77cf80 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 19:32:27 +08:00
elseif
202dab0201 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 19:23:34 +08:00
elseif
ef13a0cf68 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 19:22:07 +08:00
elseif
cc05886c0a Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 19:16:56 +08:00
elseif
018f060462 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 18:52:44 +08:00
elseif
fcd6926272 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 18:37:08 +08:00
elseif
6cd71c9efe Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 18:33:59 +08:00
elseif
a350e2badd Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 18:24:26 +08:00
elseif
9bad9f06f1 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 18:15:06 +08:00
elseif
a5db54eca5 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 18:11:41 +08:00
elseif
dedfe06698 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:55:56 +08:00
elseif
cdae26e673 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:46:50 +08:00
elseif
33cd5313f0 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:41:27 +08:00
elseif
2b0548ba76 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:33:59 +08:00
elseif
4a9d5672c1 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:22:06 +08:00
elseif
23dd4c7f43 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:10:48 +08:00
elseif
80bda12745 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 14:01:56 +08:00
elseif
954fcfdbe3 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 13:53:19 +08:00
elseif
78516e3695 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 13:29:47 +08:00
elseif
e43686eca2 Update self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 13:25:01 +08:00
elseif
3f3bd3978b self_hosted_patch.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-18 13:04:42 +08:00
elseif
d6c9e7c528 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-17 15:54:00 +08:00
elseif
476691ac29 Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2025-06-17 15:20:57 +08:00
elseif
8e3ff90b2d Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2025-06-17 15:20:15 +08:00
elseif
50a2f3f03b Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-06-14 20:19:25 +08:00
elseif
317904dfbf Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-14 19:48:15 +08:00
elseif
6e0c8a52bd Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-12 00:29:26 +08:00
elseif
2fe1832095 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-12 00:17:39 +08:00
elseif
7a15204f3a Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-12 00:15:02 +08:00
elseif
6e0c64cd73 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-06-12 00:10:46 +08:00
elseif
f4a4187e23 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-03-04 11:23:03 +08:00
elseif
66323bbfea Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-25 13:14:44 +08:00
elseif
7f2ec84067 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-25 13:13:36 +08:00
elseif
5589babdcc Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-25 13:09:00 +08:00
elseif
18bae23bf3 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-25 12:47:17 +08:00
elseif
3d52d65eb5 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-25 12:39:41 +08:00
elseif
a951a224b0 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-25 12:37:48 +08:00
elseif
343fe653ee Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-24 14:37:08 +08:00
elseif
bfb4e91be7 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-24 14:19:57 +08:00
elseif
898d1c1789 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-22 15:34:42 +08:00
elseif
e4167afbec Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-22 15:33:07 +08:00
elseif
aeaf99729f Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-22 15:27:06 +08:00
elseif
d125a063ce Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-22 15:22:40 +08:00
elseif
ce926f7cc9 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 17:45:20 +08:00
elseif
aea2da2a36 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 17:31:26 +08:00
elseif
c869dca3c1 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 17:23:14 +08:00
elseif
cbe8254d84 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 17:18:39 +08:00
elseif
331df17ee7 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 17:12:01 +08:00
elseif
35852182b2 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 16:30:46 +08:00
elseif
e0d1eb1a98 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 16:26:17 +08:00
elseif
0717a39c02 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 16:24:30 +08:00
elseif
4993be82a6 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 16:22:42 +08:00
elseif
0dbed4777f Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 16:17:23 +08:00
elseif
3b529862d1 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 15:43:29 +08:00
elseif
6da98653fc Update README_EN.md
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 15:43:02 +08:00
elseif
27e023fb28 Update README_EN.md
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 15:42:28 +08:00
elseif
df6b25a30e Update README.md
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 15:42:06 +08:00
elseif
60294067c7 Merge pull request #80 from emam06/patch-3
Update
2025-02-19 15:41:19 +08:00
elseif
d309253b06 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 11:12:54 +08:00
elseif
b3579cb363 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-19 11:09:18 +08:00
elseif
0f2c5e6081 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 20:50:25 +08:00
elseif
8f59465bf0 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 20:43:39 +08:00
elseif
736af6817b Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 20:33:03 +08:00
elseif
10a56eb673 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 20:31:07 +08:00
elseif
6518dda504 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 15:42:28 +08:00
elseif
74e812fa2b Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 15:40:17 +08:00
elseif
810909828a Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 15:16:22 +08:00
elseif
49f4ad0a59 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 15:02:01 +08:00
elseif
ece607c8f7 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-18 15:01:10 +08:00
elseif
1426fc061a Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-17 12:44:05 +08:00
elseif
7579dadaea Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-17 12:29:48 +08:00
elseif
6b6669fb23 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-17 12:27:07 +08:00
elseif
5f603dcebc Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-11 17:47:22 +08:00
elseif
e1994f69d6 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-07 13:43:33 +08:00
elseif
39af3326bd Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-07 03:39:14 +08:00
elseif
c657f2e736 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-07 03:08:29 +08:00
elseif
a8dd672a66 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-07 00:51:42 +08:00
elseif
cf01bbda4d Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-07 00:43:57 +08:00
elseif
1c9207d498 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-07 00:40:47 +08:00
elseif
f1ed27cb52 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-05 23:32:42 +08:00
elseif
8d38a80dd8 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-02-05 23:30:14 +08:00
elseif
f4af3671be Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-05 23:19:28 +08:00
elseif
2f0f0b1abb Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-05 23:01:27 +08:00
elseif
ea10a1a4c7 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-02-05 22:47:38 +08:00
emam06
bd03ecb963 Update
Signed-off-by: emam06 <egr7yco@gmail.com>
2025-01-27 15:17:41 +02:00
elseif
5b909283a0 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 21:35:52 +08:00
elseif
289ea3a34f Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 03:15:17 +08:00
elseif
aaf997c20d Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 03:06:18 +08:00
elseif
ab61c4937f Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 03:04:50 +08:00
elseif
8790f8f322 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 02:51:46 +08:00
elseif
5137e190ac Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 02:46:33 +08:00
elseif
97974bd9c6 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 02:39:29 +08:00
elseif
a99490184d Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 02:22:55 +08:00
elseif
da97108900 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-25 02:06:07 +08:00
elseif
ba72caaead Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 23:28:49 +08:00
elseif
8e8f42831f Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 23:16:16 +08:00
elseif
aea034bcf6 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 22:55:09 +08:00
elseif
a7ddc582b1 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 21:57:12 +08:00
elseif
cb0310bbcd Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 21:50:09 +08:00
elseif
38b73158f4 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 21:42:02 +08:00
elseif
ac9c61924d Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 21:32:29 +08:00
elseif
073e8811d8 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-19 21:24:07 +08:00
elseif
3207b0ccd3 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-18 11:13:51 +08:00
elseif
65dff5204a Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2025-01-18 11:13:31 +08:00
elseif
10349947e6 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-01-18 11:11:16 +08:00
elseif
2e7b31abf5 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-01-18 10:55:50 +08:00
elseif
32ef5f3aeb Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-01-18 10:53:36 +08:00
elseif
3ba9e027e3 Update patch.py
Signed-off-by: elseif <elseif@live.cn>
2025-01-18 10:46:54 +08:00
elseif
f6fea00c16 Merge pull request #74 from vnxme/system-random
Use SystemRandom to ensure crossplatform compatibility
2024-12-30 11:21:29 +08:00
vnxme
391d019a42 Use random.SystemRandom().randint
instead of toyecc.Random.secure_rand_int_between
2024-12-28 10:57:32 +03:00
elseif
4c6ab80b09 Merge pull request #66 from vnxme/env-consistency-fixes
Env consistency fixes
2024-12-14 12:40:16 +08:00
elseif
098f967cfd Merge pull request #69 from loskiq/patch-1
Update mikro.py
2024-12-14 12:40:05 +08:00
Amir
e61c981f84 Update mikro.py
Signed-off-by: Amir <loskiq@gmail.com>
2024-12-13 17:23:54 +03:00
vnxme
29663ed175 Fix *_LICENSE_URL spelling 2024-12-12 11:45:40 +03:00
vnxme
fd2baf25a0 Fix MIKRO_NPK_SIGN_PUBLIC_KEY spelling 2024-12-12 11:45:40 +03:00
elseif
f65a65e830 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-12-06 03:00:00 +08:00
elseif
dc8118e5ab Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-29 11:30:52 +08:00
elseif
9b4d525aa2 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-29 11:30:14 +08:00
elseif
eef9552fda Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-29 11:03:27 +08:00
elseif
2126382b54 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-29 11:03:24 +08:00
elseif
a9eef1d574 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-29 10:51:22 +08:00
elseif
bd097583eb Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-29 10:50:39 +08:00
elseif
23a853d585 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-19 10:06:44 +08:00
elseif
9b6b8c7e2f Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-15 07:11:44 +08:00
elseif
4c52806821 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-15 06:54:21 +08:00
elseif
136c1ddcd4 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-15 06:50:21 +08:00
elseif
e5fb3ff784 Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-15 06:45:54 +08:00
elseif
9dd745578b Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-11-15 06:27:16 +08:00
elseif
9d06111ac5 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-10-20 18:58:03 +08:00
elseif
7fdd5724bb Update mikrotik_patch_7.yml
Signed-off-by: elseif <elseif@live.cn>
2024-10-20 18:56:38 +08:00
elseif
7719188665 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-30 14:06:45 +08:00
elseif
016a2de24f Update README_EN.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-30 14:06:32 +08:00
elseif
2957c5a6ef Update README.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-26 14:48:15 +08:00
elseif
ec407be988 Update README_EN.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-26 14:48:04 +08:00
elseif
ed0815f070 Update README_EN.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-26 14:47:29 +08:00
elseif
e88fbc0161 Update README.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-22 18:28:53 +08:00
elseif
6d1ebb4d8a Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 19:25:03 +08:00
elseif
ca24fa62b1 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 19:24:52 +08:00
elseif
73f15e63e7 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 19:21:23 +08:00
elseif
96df91e97c Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 19:19:07 +08:00
elseif
65fd858255 Update mikrotik_patch_6.yml
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 19:11:44 +08:00
elseif
208a160edc Update README_EN.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 00:33:28 +08:00
elseif
c3781d822e Update README.md
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 00:33:07 +08:00
elseif
f2eefbcc8f Add files via upload
Signed-off-by: elseif <elseif@live.cn>
2024-08-19 00:32:26 +08:00
17 changed files with 555 additions and 221 deletions

View File

@@ -3,10 +3,28 @@ name: Patch Mikrotik RouterOS 6.x
on:
# push:
# branches: [ "main" ]
schedule:
- cron: "0 0 * * *"
# schedule:
# - cron: "0 0 * * *"
workflow_dispatch:
inputs:
channel:
description: 'Channel (stable, long-term)'
required: true
default: 'stable'
type: choice
options:
- stable
- long-term
version:
description: "Version ('', 6.49.17, 6.49.18,...)"
required: false
default: ''
type: string
buildtime:
description: "Build Time"
required: false
default: ''
type: string
permissions:
contents: write
@@ -17,7 +35,7 @@ env:
CUSTOM_NPK_SIGN_PUBLIC_KEY: ${{ secrets.CUSTOM_NPK_SIGN_PUBLIC_KEY }}
CUSTOM_CLOUD_PUBLIC_KEY: ${{ secrets.CUSTOM_CLOUD_PUBLIC_KEY }}
MIKRO_LICENSE_PUBLIC_KEY: ${{ secrets.MIKRO_LICENSE_PUBLIC_KEY }}
MIKRO_NPK_SIGN_PUBLIC_LKEY: ${{ secrets.MIKRO_NPK_SIGN_PUBLIC_LKEY }}
MIKRO_NPK_SIGN_PUBLIC_KEY: ${{ secrets.MIKRO_NPK_SIGN_PUBLIC_KEY }}
MIKRO_CLOUD_PUBLIC_KEY: ${{ secrets.MIKRO_CLOUD_PUBLIC_KEY }}
MIKRO_LICENCE_URL: ${{ secrets.MIKRO_LICENCE_URL }}
CUSTOM_LICENCE_URL: ${{ secrets.CUSTOM_LICENCE_URL }}
@@ -36,14 +54,20 @@ jobs:
steps:
- name: Set build time
id: set_buildtime
run: echo "BUILD_TIME=$(date +'%s')" >> $GITHUB_OUTPUT
run: |
_BUILD_TIME=${{ github.event.inputs.buildtime }}
if [ -z "$_BUILD_TIME" ]; then
echo "BUILD_TIME=$(date +'%s')" >> $GITHUB_OUTPUT
else
echo "BUILD_TIME=$_BUILD_TIME" >> $GITHUB_OUTPUT
fi
Patch_RouterOS:
needs: Set_BuildTime
runs-on: ubuntu-22.04
strategy:
matrix:
channel: [long-term,stable]
channel: ${{ fromJSON(format('["{0}"]', github.event.inputs.channel || 'stable')) }}
env:
TZ: 'Asia/Shanghai'
LATEST_VERSION: ""
@@ -60,7 +84,10 @@ jobs:
id: get_latest
run: |
echo $(uname -a)
LATEST_VERSION=$(wget -nv -O - https://upgrade.mikrotik.com/routeros/NEWEST6.${{ matrix.channel }} | cut -d ' ' -f1)
LATEST_VERSION=${{ github.event.inputs.version }}
if [ -z "$_LATEST_VERSION" ]; then
LATEST_VERSION=$(wget -nv -O - https://${{ env.MIKRO_UPGRADE_URL }}/routeros/NEWEST6.${{ matrix.channel }} | cut -d ' ' -f1)
fi
echo Latest Version:$LATEST_VERSION
if [ "${{ github.event_name }}" == "schedule" ]; then
_LATEST_VERSION=$(wget -nv -O - https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/NEWEST6.${{ matrix.channel }} | cut -d ' ' -f1)
@@ -77,8 +104,48 @@ jobs:
cat CHANGELOG
echo "LATEST_VERSION=${LATEST_VERSION}" >> $GITHUB_ENV
echo "BUILD_TIME=${BUILD_TIME}" >> $GITHUB_ENV
has_patched_npk=false
if wget -nv --spider https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/$LATEST_VERSION/routeros-x86-$LATEST_VERSION.npk; then
echo "RouterOS NPK file exists, attempting to download..."
if wget -nv -O routeros-x86-$LATEST_VERSION.npk https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/$LATEST_VERSION/routeros-x86-$LATEST_VERSION.npk; then
echo "RouterOS NPK file downloaded successfully."
if wget -nv --spider https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/$LATEST_VERSION/system-$LATEST_VERSION.npk; then
echo "System NPK file exists, attempting to download..."
if wget -nv -O system-$LATEST_VERSION.npk https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/$LATEST_VERSION/system-$LATEST_VERSION.npk; then
has_patched_npk=true
fi
fi
fi
fi
echo "has_patched_npk=$has_patched_npk" >> $GITHUB_OUTPUT
- name: Cache Squashfs
if: steps.get_latest.outputs.has_new_version == 'true'
id: cache-squashfs
uses: actions/cache@v4
with:
path: |
option.sfs
key: busybox-squashfs
- name: Create Squashfs for option
if: steps.get_latest.outputs.has_new_version == 'true' && steps.cache-squashfs.outputs.cache-hit != 'true'
run: |
sudo mkdir -p ./option-root/bin/
sudo cp busybox/busybox_x86 ./option-root/bin/busybox
sudo chmod +x ./option-root/bin/busybox
sudo cp keygen/keygen_x86 ./option-root/bin/keygen
sudo chmod +x ./option-root/bin/keygen
sudo chmod +x ./busybox/busybox_x86
COMMANDS=$(./busybox/busybox_x86 --list)
for cmd in $COMMANDS; do
sudo ln -sf /pckg/option/bin/busybox ./option-root/bin/$cmd
done
sudo mksquashfs option-root option.sfs -quiet -comp xz -no-xattrs -b 256k
sudo rm -rf option-root
- name: Cache mikrotik-${{ env.LATEST_VERSION }}.iso
if: steps.get_latest.outputs.has_new_version == 'true'
id: cache-mikrotik
@@ -105,14 +172,20 @@ jobs:
sudo rsync -a ./iso/ ./new_iso/
sudo umount ./iso
sudo rm -rf ./iso
sudo mv ./new_iso/system-$LATEST_VERSION.npk ./
sudo -E python3 patch.py npk system-$LATEST_VERSION.npk
if [ "${{ steps.get_latest.outputs.has_patched_npk }}" == "false" ]; then
sudo mv ./new_iso/system-$LATEST_VERSION.npk ./
sudo -E python3 patch.py npk system-$LATEST_VERSION.npk
else
sudo -E python3 npk.py sign system-$LATEST_VERSION.npk system-$LATEST_VERSION.npk
fi
sudo -E python3 patch.py kernel ./new_iso/isolinux/initrd.rgz
NPK_FILES=$(find ./new_iso/*.npk)
for file in $NPK_FILES; do
sudo -E python3 npk.py sign $file $file
done
sudo cp system-$LATEST_VERSION.npk ./new_iso/
#sudo -E python3 npk.py create ./new_iso/gps-$LATEST_VERSION.npk ./option-$LATEST_VERSION.npk option ./option.sfs -desc="busybox"
#sudo cp option-$LATEST_VERSION.npk ./new_iso/
sudo mkisofs -o mikrotik-$LATEST_VERSION.iso \
-V "MikroTik $LATEST_VERSION" \
-sysid "" -preparer "MiKroTiK" \
@@ -129,15 +202,12 @@ jobs:
sudo mkdir ./all_packages
sudo cp ./new_iso/*.npk ./all_packages/
sudo rm -rf ./new_iso
cd ./all_packages
sudo zip ../all_packages-x86-$LATEST_VERSION.zip *.npk
cd ..
- name: Create install-image-${{ env.LATEST_VERSION }}.img
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true' && steps.get_latest.outputs.has_patched_npk == 'true'
run: |
sudo modprobe nbd
sudo apt-get update
sudo apt-get install -y qemu-utils extlinux > /dev/null
truncate --size 64M install-image-$LATEST_VERSION.img
sudo qemu-nbd -c /dev/nbd0 -f raw install-image-$LATEST_VERSION.img
@@ -183,18 +253,27 @@ jobs:
- name: Create chr-${{ env.LATEST_VERSION }}.img
if: steps.get_latest.outputs.has_new_version == 'true'
run: |
sudo modprobe nbd
sudo apt-get install -y qemu-utils extlinux > /dev/null
sudo mkdir ./chr
sudo cp chr.img chr-$LATEST_VERSION.img
sudo qemu-nbd -c /dev/nbd0 -f raw chr-$LATEST_VERSION.img
sudo -E python3 patch.py block /dev/nbd0p1 boot/initrd.rgz
sudo mount /dev/nbd0p1 ./chr
sudo cp ./all_packages/dude-$LATEST_VERSION.npk ./chr/var/pdb/dude/image
sudo -E python3 patch.py npk ./chr/var/pdb/routeros-x86/image
sudo cp ./chr/var/pdb/routeros-x86/image ./all_packages/routeros-x86-$LATEST_VERSION.npk
if [ "${{ steps.get_latest.outputs.has_patched_npk }}" == "false" ]; then
sudo -E python3 patch.py npk ./chr/var/pdb/routeros-x86/image
sudo cp ./chr/var/pdb/routeros-x86/image ./all_packages/routeros-x86-$LATEST_VERSION.npk
else
sudo -E python3 npk.py sign routeros-x86-$LATEST_VERSION.npk routeros-x86-$LATEST_VERSION.npk
sudo cp -f routeros-x86-$LATEST_VERSION.npk ./chr/var/pdb/routeros-x86/image
sudo cp routeros-x86-$LATEST_VERSION.npk ./all_packages/routeros-x86-$LATEST_VERSION.npk
fi
#sudo mkdir -p ./chr/var/pdb/option
#sudo cp ./all_packages/option-$LATEST_VERSION.npk ./chr/var/pdb/option/image
sudo umount ./chr
sudo qemu-nbd -d /dev/nbd0
sudo rm -rf ./chr
sudo qemu-img convert -f raw -O qcow2 chr-$LATEST_VERSION.img chr-$LATEST_VERSION.qcow2
sudo qemu-img convert -f raw -O vmdk chr-$LATEST_VERSION.img chr-$LATEST_VERSION.vmdk
sudo qemu-img convert -f raw -O vpc chr-$LATEST_VERSION.img chr-$LATEST_VERSION.vhd
@@ -208,27 +287,36 @@ jobs:
sudo zip chr-$LATEST_VERSION.vdi.zip chr-$LATEST_VERSION.vdi
sudo zip chr-$LATEST_VERSION.img.zip chr-$LATEST_VERSION.img
sudo rm chr-$LATEST_VERSION$ARCH.qcow2
sudo rm chr-$LATEST_VERSION$ARCH.vmdk
sudo rm chr-$LATEST_VERSION$ARCH.vhd
sudo rm chr-$LATEST_VERSION$ARCH.vhdx
sudo rm chr-$LATEST_VERSION$ARCH.vdi
sudo rm chr-$LATEST_VERSION$ARCH.img
sudo rm chr-$LATEST_VERSION.qcow2
sudo rm chr-$LATEST_VERSION.vmdk
sudo rm chr-$LATEST_VERSION.vhd
sudo rm chr-$LATEST_VERSION.vhdx
sudo rm chr-$LATEST_VERSION.vdi
sudo rm chr-$LATEST_VERSION.img
cd ./all_packages
sudo zip ../all_packages-x86-$LATEST_VERSION.zip *.npk
cd ..
- name: Upload Files
if: steps.get_latest.outputs.has_new_version == 'true'
run: |
mkdir -p ./publish/$LATEST_VERSION
echo $LATEST_VERSION $BUILD_TIME > ./publish/NEWEST6.${{ matrix.channel }}
cp CHANGELOG ./publish/$LATEST_VERSION/
cp ./all_packages/*.npk ./publish/$LATEST_VERSION/
sudo apt-get install -y lftp > /dev/null 2>&1
if [ "${{ steps.get_latest.outputs.has_patched_npk }}" == "false" ]; then
OUTDIR="$LATEST_VERSION-UNDONE"
else
OUTDIR="$LATEST_VERSION"
fi
sudo mkdir -p ./publish/$OUTDIR
sudo cp CHANGELOG ./publish/$OUTDIR/
sudo cp ./all_packages/*.npk ./publish/$OUTDIR/
sudo chown -R root:root ./publish/
sudo apt-get install -y lftp ssh sshpass > /dev/null 2>&1
sudo -E lftp -u ${{ secrets.SSH_USERNAME }},'${{ secrets.SSH_PASSWORD }}' sftp://${{ secrets.SSH_SERVER }}:${{ secrets.SSH_PORT }} <<EOF
set sftp:auto-confirm yes
mirror --reverse --verbose --only-newer ./publish ${{ secrets.SSH_DIRECTORY }}
bye
EOF
sshpass -p "${{ secrets.SSH_PASSWORD }}" ssh -o StrictHostKeyChecking=no -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_SERVER }} "echo $LATEST_VERSION $BUILD_TIME | tee /rw/disk/${{ secrets.SSH_DIRECTORY }}/NEWEST6.${{ matrix.channel }}; chown -R 32768:32768 /rw/disk/${{ secrets.SSH_DIRECTORY }}/"
- name: Clear Cloudflare cache
if: steps.get_latest.outputs.has_new_version == 'true'
@@ -239,23 +327,23 @@ jobs:
--data '{"purge_everything": true}'
- name: Delete Release tag ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true' && steps.get_latest.outputs.has_patched_npk == 'true'
run: |
HEADER="Authorization: token ${{ secrets.GITHUB_TOKEN }}"
RELEASE_INFO=$(curl -s -H $HEADER https://api.github.com/repos/${{ github.repository }}/releases/tags/$LATEST_VERSION$ARCH)
RELEASE_INFO=$(curl -s -H $HEADER https://api.github.com/repos/${{ github.repository }}/releases/tags/$LATEST_VERSION)
RELEASE_ID=$(echo $RELEASE_INFO | jq -r '.id')
echo "Release ID: $RELEASE_ID"
if [ "$RELEASE_ID" != "null" ]; then
curl -X DELETE -H "$HEADER" https://api.github.com/repos/${{ github.repository }}/git/refs/tags/$LATEST_VERSION$ARCH
echo "Tag $LATEST_VERSION$ARCH deleted successfully."
curl -X DELETE -H "$HEADER" https://api.github.com/repos/${{ github.repository }}/git/refs/tags/$LATEST_VERSION
echo "Tag $LATEST_VERSION deleted successfully."
curl -X DELETE -H "$HEADER" https://api.github.com/repos/${{ github.repository }}/releases/$RELEASE_ID
echo "Release with tag $LATEST_VERSION$ARCH deleted successfully."
echo "Release with tag $LATEST_VERSION deleted successfully."
else
echo "Release not found for tag: $LATEST_VERSION)"
fi
- name: Create Release tag ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true' && steps.get_latest.outputs.has_patched_npk == 'true'
uses: softprops/action-gh-release@v2
with:
name: "RouterOS ${{ env.LATEST_VERSION }}"
@@ -267,5 +355,5 @@ jobs:
mikrotik-${{ env.LATEST_VERSION }}.iso
chr-${{ env.LATEST_VERSION }}*.zip
install-image-${{ env.LATEST_VERSION }}.zip
system-${{ env.LATEST_VERSION }}.npk
routeros-x86-${{ env.LATEST_VERSION }}.npk
all_packages-x86-${{ env.LATEST_VERSION }}.zip

View File

@@ -5,6 +5,38 @@ on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
inputs:
arch:
description: 'Architecture (x86, arm64)'
required: true
default: 'x86'
type: choice
options:
- x86
- arm64
channel:
description: 'Channel (stable, testing)'
required: true
default: 'stable'
type: choice
options:
- stable
- testing
version:
description: "Specify version (e.g., 7.17.2), empty for latest"
required: false
default: ''
type: string
buildtime:
description: "Custom build time, leave empty for now"
required: false
default: ''
type: string
release:
description: "Release to GitHub & Upload "
required: false
default: 'false'
type: boolean
permissions:
contents: write
@@ -16,7 +48,7 @@ env:
CUSTOM_NPK_SIGN_PUBLIC_KEY: ${{ secrets.CUSTOM_NPK_SIGN_PUBLIC_KEY }}
CUSTOM_CLOUD_PUBLIC_KEY: ${{ secrets.CUSTOM_CLOUD_PUBLIC_KEY }}
MIKRO_LICENSE_PUBLIC_KEY: ${{ secrets.MIKRO_LICENSE_PUBLIC_KEY }}
MIKRO_NPK_SIGN_PUBLIC_LKEY: ${{ secrets.MIKRO_NPK_SIGN_PUBLIC_LKEY }}
MIKRO_NPK_SIGN_PUBLIC_KEY: ${{ secrets.MIKRO_NPK_SIGN_PUBLIC_KEY }}
MIKRO_CLOUD_PUBLIC_KEY: ${{ secrets.MIKRO_CLOUD_PUBLIC_KEY }}
MIKRO_LICENCE_URL: ${{ secrets.MIKRO_LICENCE_URL }}
CUSTOM_LICENCE_URL: ${{ secrets.CUSTOM_LICENCE_URL }}
@@ -28,27 +60,50 @@ env:
CUSTOM_CLOUD_URL: ${{ secrets.CUSTOM_CLOUD_URL }}
jobs:
Set_BuildTime:
Set_Variables:
runs-on: ubuntu-22.04
outputs:
BUILD_TIME: ${{ steps.set_buildtime.outputs.BUILD_TIME }}
BUILD_TIME: ${{ steps.set_vars.outputs.BUILD_TIME }}
RELEASE: ${{ steps.set_vars.outputs.RELEASE }}
MATRIX_JSON: ${{ steps.set_vars.outputs.MATRIX_JSON }}
steps:
- name: Set build time
id: set_buildtime
run: echo "BUILD_TIME=$(date +'%s')" >> $GITHUB_OUTPUT
- name: Set variables
id: set_vars
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
BUILD_TIME="${{ github.event.inputs.buildtime }}"
RELEASE="${{ github.event.inputs.release }}"
if [ -z "$BUILD_TIME" ]; then
BUILD_TIME=$(date +'%s')
fi
if [ -z "$RELEASE" ]; then
RELEASE=false
fi
ARCH="${{ github.event.inputs.arch }}"
CHANNEL="${{ github.event.inputs.channel }}"
MATRIX_JSON=$(jq -nc --arg arch "$ARCH" --arg channel "$CHANNEL" '[{arch: $arch, channel: $channel}]')
else
BUILD_TIME=$(date +'%s')
RELEASE=true
MATRIX_JSON='[{"arch":"x86","channel":"stable"},{"arch":"arm64","channel":"stable"},{"arch":"x86","channel":"testing"},{"arch":"arm64","channel":"testing"}]'
fi
echo "BUILD_TIME=$BUILD_TIME" >> $GITHUB_OUTPUT
echo "RELEASE=$RELEASE" >> $GITHUB_OUTPUT
echo "MATRIX_JSON=$MATRIX_JSON" >> $GITHUB_OUTPUT
echo "BUILD_TIME: $BUILD_TIME"
echo "RELEASE: $RELEASE"
echo "MATRIX_JSON: $MATRIX_JSON"
Patch_RouterOS:
needs: Set_BuildTime
needs: Set_Variables
runs-on: ubuntu-22.04
strategy:
matrix:
arch: [x86,arm64]
channel: [stable, testing]
matrix:
include: ${{ fromJSON(needs.Set_Variables.outputs.MATRIX_JSON) }}
env:
TZ: 'Asia/Shanghai'
LATEST_VERSION: ""
ARCH: ""
BUILD_TIME: ${{ needs.Set_Variables.outputs.BUILD_TIME }}
RELEASE: ${{ needs.Set_Variables.outputs.RELEASE }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -62,7 +117,16 @@ jobs:
id: get_latest
run: |
echo $(uname -a)
LATEST_VERSION=$(wget -nv -O - https://${{ env.MIKRO_UPGRADE_URL }}/routeros/NEWESTa7.${{ matrix.channel }} | cut -d ' ' -f1)
echo Build Time:$BUILD_TIME
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
if [ -n "${{ github.event.inputs.version }}" ]; then
LATEST_VERSION="${{ github.event.inputs.version }}"
else
LATEST_VERSION=$(wget -nv -O - https://${{ env.MIKRO_UPGRADE_URL }}/routeros/NEWESTa7.${{ matrix.channel }} | cut -d ' ' -f1)
fi
else
LATEST_VERSION=$(wget -nv -O - https://${{ env.MIKRO_UPGRADE_URL }}/routeros/NEWESTa7.${{ matrix.channel }} | cut -d ' ' -f1)
fi
echo Latest Version:$LATEST_VERSION
if [ "${{ github.event_name }}" == "schedule" ]; then
_LATEST_VERSION=$(wget -nv -O - https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/NEWESTa7.${{ matrix.channel }} | cut -d ' ' -f1)
@@ -73,19 +137,23 @@ jobs:
fi
fi
echo "has_new_version=true" >> $GITHUB_OUTPUT
BUILD_TIME=${{ needs.Set_BuildTime.outputs.BUILD_TIME }}
echo Build Time:$BUILD_TIME
wget -nv -O CHANGELOG https://${{ env.MIKRO_UPGRADE_URL }}/routeros/$LATEST_VERSION/CHANGELOG
cat CHANGELOG
echo "LATEST_VERSION=${LATEST_VERSION}" >> $GITHUB_ENV
echo "BUILD_TIME=${BUILD_TIME}" >> $GITHUB_ENV
if [ "${{ matrix.arch }}" == "x86" ]; then
ARCH=''
echo "ARCH=$ARCH" >> $GITHUB_ENV
elif [ "${{ matrix.arch }}" == "arm64" ]; then
ARCH='-arm64'
echo "ARCH=$ARCH" >> $GITHUB_ENV
if [[ "${{ matrix.arch }}" == "arm64" ]]; then
echo "ARCH=-arm64" >> $GITHUB_ENV
else
echo "ARCH=" >> $GITHUB_ENV
fi
echo "LATEST_VERSION=${LATEST_VERSION}" >> $GITHUB_ENV
sudo apt-get update > /dev/null
- name: Get loader patch files
if: steps.get_latest.outputs.has_new_version == 'true'
run: |
wget -nv -O loader.7z https://${{ env.CUSTOM_UPGRADE_URL }}/routeros/loader.7z
sudo apt-get install -y p7zip-full > /dev/null
7z x -p"${{ secrets.LOADER_7Z_PASSWORD }}" loader.7z >> /dev/null
rm loader.7z
- name: Cache Squashfs
if: steps.get_latest.outputs.has_new_version == 'true'
@@ -120,43 +188,17 @@ jobs:
sudo mksquashfs option-root option.sfs -quiet -comp xz -no-xattrs -b 256k
sudo rm -rf option-root
if [ "${{ matrix.arch }}" == "x86" ]; then
sudo wget -O cpython-3.11.9.tar.gz -nv https://github.com/indygreg/python-build-standalone/releases/download/20240713/cpython-3.11.9+20240713-x86_64-unknown-linux-gnu-install_only.tar.gz
sudo wget -O cpython.tar.gz -nv https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-3.11.10+20241016-x86_64-unknown-linux-musl-install_only_stripped.tar.gz
elif [ "${{ matrix.arch }}" == "arm64" ]; then
sudo wget -O cpython-3.11.9.tar.gz -nv https://github.com/indygreg/python-build-standalone/releases/download/20240713/cpython-3.11.9+20240713-aarch64-unknown-linux-gnu-install_only.tar.gz
sudo wget -O cpython.tar.gz -nv https://github.com/indygreg/python-build-standalone/releases/download/20241016/cpython-3.11.10+20241016-aarch64-unknown-linux-gnu-install_only_stripped.tar.gz
fi
sudo tar -xf cpython-3.11.9.tar.gz
sudo rm cpython-3.11.9.tar.gz
sudo tar -xf cpython.tar.gz
sudo rm cpython.tar.gz
sudo rm -rf ./python/include
sudo rm -rf ./python/share
sudo mksquashfs python python3.sfs -quiet -comp xz -no-xattrs -b 256k
sudo rm -rf ./python
- name: Cache NetInstall ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86'
id: cache-netinstall
uses: actions/cache@v4
with:
path: |
netinstall.zip
netinstall.tar.gz
key: netinstall-${{ env.LATEST_VERSION }}
- name: Get netinstall ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && steps.cache-netinstall.outputs.cache-hit != 'true'
run: |
sudo wget -nv -O netinstall.zip https://download.mikrotik.com/routeros/$LATEST_VERSION/netinstall-$LATEST_VERSION.zip
sudo wget -nv -O netinstall.tar.gz https://download.mikrotik.com/routeros/$LATEST_VERSION/netinstall-$LATEST_VERSION.tar.gz
- name: Patch netinstall ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86'
run: |
sudo unzip netinstall.zip
sudo -E python3 patch.py netinstall netinstall.exe
sudo zip netinstall-$LATEST_VERSION.zip ./netinstall.exe
sudo tar -xvf netinstall.tar.gz
sudo -E python3 patch.py netinstall netinstall-cli
sudo tar -czvf netinstall-$LATEST_VERSION.tar.gz ./netinstall-cli
- name: Cache mikrotik-${{ env.LATEST_VERSION }}${{ env.ARCH }}.iso
if: steps.get_latest.outputs.has_new_version == 'true'
id: cache-mikrotik
@@ -179,7 +221,6 @@ jobs:
sudo mkdir ./iso
sudo mount -o loop,ro mikrotik.iso ./iso
sudo mkdir ./new_iso
sudo cp -r ./iso/* ./new_iso/
sudo rsync -a ./iso/ ./new_iso/
sudo umount ./iso
sudo rm -rf ./iso
@@ -189,7 +230,7 @@ jobs:
for file in $NPK_FILES; do
sudo -E python3 npk.py sign $file $file
done
sudo cp routeros-$LATEST_VERSION$ARCH.npk ./new_iso/
sudo cp -f routeros-$LATEST_VERSION$ARCH.npk ./new_iso/
sudo -E python3 npk.py create ./new_iso/gps-$LATEST_VERSION$ARCH.npk ./option-$LATEST_VERSION$ARCH.npk option ./option.sfs -desc="busybox"
sudo cp option-$LATEST_VERSION$ARCH.npk ./new_iso/
sudo -E python3 npk.py create ./new_iso/gps-$LATEST_VERSION$ARCH.npk ./python3-$LATEST_VERSION$ARCH.npk python3 ./python3.sfs -desc="python 3.11.9"
@@ -237,58 +278,8 @@ jobs:
sudo zip ../all_packages-${{ matrix.arch }}-$LATEST_VERSION.zip *.npk
cd ..
- name: Cache refind
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86'
id: cache-refind
uses: actions/cache@v4
with:
path: refind-bin-0.14.2.zip
key: refind
- name: Get refind
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && steps.cache-refind.outputs.cache-hit != 'true'
run: sudo wget -nv -O refind-bin-0.14.2.zip https://nchc.dl.sourceforge.net/project/refind/0.14.2/refind-bin-0.14.2.zip
- name: Create install-image-${{ env.LATEST_VERSION }}.img
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86'
run: |
sudo modprobe nbd
sudo apt-get install -y qemu-utils extlinux > /dev/null
truncate --size 128M install-image-$LATEST_VERSION.img
sudo qemu-nbd -c /dev/nbd0 -f raw install-image-$LATEST_VERSION.img
sudo mkfs.vfat -n "Install" /dev/nbd0
sudo mkdir ./install
sudo mount /dev/nbd0 ./install
sudo mkdir -p ./install/EFI/BOOT
sudo unzip refind-bin-0.14.2.zip refind-bin-0.14.2/refind/refind_x64.efi
sudo cp refind-bin-0.14.2/refind/refind_x64.efi ./install/EFI/BOOT/BOOTX64.EFI
sudo rm -rf refind-bin-0.14.2
echo -e 'timeout 0\ntextonly\ntextmode 0\nshowtools shutdown, reboot, exit\nmenuentry "Install RouterOS" {\n\tloader /linux\n\toptions "load_ramdisk=1 root=/dev/ram0 -install -hdd"\n}\ndefault_selection /EFI/BOOT/BOOTX64.EFI' \
> refind.conf
sudo cp refind.conf ./install/EFI/BOOT/
sudo rm refind.conf
sudo extlinux --install -H 64 -S 32 ./install/
echo -e 'default system\nLABEL system\n\tKERNEL linux\n\tAPPEND load_ramdisk=1 -install -hdd' \
> syslinux.cfg
sudo cp syslinux.cfg ./install/
sudo rm syslinux.cfg
sudo cp ./BOOTX64.EFI ./install/linux
NPK_FILES=($(find ./all_packages/*.npk))
for ((i=1; i<=${#NPK_FILES[@]}; i++))
do
echo "${NPK_FILES[$i-1]}=>$i.npk"
sudo cp ${NPK_FILES[$i-1]} ./install/$i.npk
done
sudo touch ./install/CHOOSE
sudo touch ./install/autorun.scr
sudo umount /dev/nbd0
sudo qemu-nbd -d /dev/nbd0
sudo rm -rf ./install
sudo zip install-image-$LATEST_VERSION.zip ./install-image-$LATEST_VERSION.img
sudo rm ./install-image-$LATEST_VERSION.img
- name: Cache chr-${{ env.LATEST_VERSION }}${{ env.ARCH }}.img.zip
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'arm64'
if: steps.get_latest.outputs.has_new_version == 'true'
id: cache-chr-img
uses: actions/cache@v4
with:
@@ -297,7 +288,7 @@ jobs:
key: chr-${{ env.LATEST_VERSION }}-${{ matrix.arch }}.img
- name: Get chr-${{ env.LATEST_VERSION }}${{ env.ARCH }}.img
if: steps.get_latest.outputs.has_new_version == 'true' && steps.cache-chr-img.outputs.cache-hit != 'true' && matrix.arch == 'arm64'
if: steps.get_latest.outputs.has_new_version == 'true' && steps.cache-chr-img.outputs.cache-hit != 'true'
run: |
sudo wget -nv -O chr.img.zip https://download.mikrotik.com/routeros/$LATEST_VERSION/chr-$LATEST_VERSION$ARCH.img.zip
sudo unzip chr.img.zip
@@ -305,16 +296,17 @@ jobs:
sudo mv chr-$LATEST_VERSION$ARCH.img chr.img
- name: Create chr-${{ env.LATEST_VERSION }}${{ env.ARCH }}.img
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true'
run: |
sudo modprobe nbd
sudo apt-get install -y qemu-utils extlinux > /dev/null
sudo apt-get install -y qemu-utils > /dev/null
truncate --size 128M chr-$LATEST_VERSION$ARCH.img
sgdisk --clear --set-alignment=2 \
--new=1::+32M --typecode=1:8300 --change-name=1:"RouterOS Boot" --attributes=1:set:2 \
--new=2::-0 --typecode=2:8300 --change-name=2:"RouterOS" \
--gpttombr=1:2 \
chr-$LATEST_VERSION$ARCH.img
dd if=chr.img of=mbr.bin bs=1 count=446 skip=0
dd if=chr-$LATEST_VERSION$ARCH.img of=pt.bin bs=1 count=66 skip=446
echo -e "\x80" | dd of=pt.bin bs=1 count=1 conv=notrunc
sgdisk --mbrtogpt --clear --set-alignment=2 \
@@ -329,12 +321,44 @@ jobs:
sudo mkdir -p ./img/{boot,routeros}
sudo mount /dev/nbd0p1 ./img/boot/
if [ "${{ matrix.arch }}" == "x86" ]; then
sudo mkdir -p ./img/boot/{BOOT,EFI/BOOT}
sudo cp BOOTX64.EFI ./img/boot/EFI/BOOT/BOOTX64.EFI
sudo extlinux --install -H 64 -S 32 ./img/boot/BOOT
echo -e "default system\nlabel system\n\tkernel /EFI/BOOT/BOOTX64.EFI\n\tappend load_ramdisk=1 root=/dev/ram0 quiet" > syslinux.cfg
sudo cp syslinux.cfg ./img/boot/BOOT/
sudo rm syslinux.cfg
sudo cp chr.img chr-$LATEST_VERSION$ARCH-legacy-bios.img
sudo qemu-nbd -c /dev/nbd1 -f raw chr-$LATEST_VERSION$ARCH-legacy-bios.img
sudo -E python3 patch.py block /dev/nbd1p1 EFI/BOOT/BOOTX64.EFI
sudo mkdir -p ./chr/{boot,routeros}
sudo mount /dev/nbd1p1 ./chr/boot/
sudo mkdir -p ./img/boot/EFI/BOOT
sudo cp ./chr/boot/EFI/BOOT/BOOTX64.EFI ./img/boot/EFI/BOOT/BOOTX64.EFI
sudo umount /dev/nbd1p1
sudo shred -v -n 1 -z /dev/nbd1p2
sudo mkfs.ext4 -F -L "RouterOS" -m 0 /dev/nbd1p2
sudo mount /dev/nbd1p2 ./chr/routeros/
sudo mkdir -p ./chr/routeros/{var/pdb/{system,option},boot,rw}
sudo cp ./all_packages/option-$LATEST_VERSION$ARCH.npk ./chr/routeros/var/pdb/option/image
sudo cp ./all_packages/routeros-$LATEST_VERSION$ARCH.npk ./chr/routeros/var/pdb/system/image
sudo umount /dev/nbd1p2
sudo qemu-nbd -d /dev/nbd1
sudo rm -rf ./chr
sudo qemu-img convert -f raw -O qcow2 chr-$LATEST_VERSION$ARCH-legacy-bios.img chr-$LATEST_VERSION$ARCH-legacy-bios.qcow2
sudo qemu-img convert -f raw -O vmdk chr-$LATEST_VERSION$ARCH-legacy-bios.img chr-$LATEST_VERSION$ARCH-legacy-bios.vmdk
sudo qemu-img convert -f raw -O vpc chr-$LATEST_VERSION$ARCH-legacy-bios.img chr-$LATEST_VERSION$ARCH-legacy-bios.vhd
sudo qemu-img convert -f raw -O vhdx chr-$LATEST_VERSION$ARCH-legacy-bios.img chr-$LATEST_VERSION$ARCH-legacy-bios.vhdx
sudo qemu-img convert -f raw -O vdi chr-$LATEST_VERSION$ARCH-legacy-bios.img chr-$LATEST_VERSION$ARCH-legacy-bios.vdi
sudo zip chr-$LATEST_VERSION$ARCH-legacy-bios.qcow2.zip chr-$LATEST_VERSION$ARCH-legacy-bios.qcow2
sudo zip chr-$LATEST_VERSION$ARCH-legacy-bios.vmdk.zip chr-$LATEST_VERSION$ARCH-legacy-bios.vmdk
sudo zip chr-$LATEST_VERSION$ARCH-legacy-bios.vhd.zip chr-$LATEST_VERSION$ARCH-legacy-bios.vhd
sudo zip chr-$LATEST_VERSION$ARCH-legacy-bios.vhdx.zip chr-$LATEST_VERSION$ARCH-legacy-bios.vhdx
sudo zip chr-$LATEST_VERSION$ARCH-legacy-bios.vdi.zip chr-$LATEST_VERSION$ARCH-legacy-bios.vdi
sudo zip chr-$LATEST_VERSION$ARCH-legacy-bios.img.zip chr-$LATEST_VERSION$ARCH-legacy-bios.img
sudo rm chr-$LATEST_VERSION$ARCH-legacy-bios.qcow2
sudo rm chr-$LATEST_VERSION$ARCH-legacy-bios.vmdk
sudo rm chr-$LATEST_VERSION$ARCH-legacy-bios.vhd
sudo rm chr-$LATEST_VERSION$ARCH-legacy-bios.vhdx
sudo rm chr-$LATEST_VERSION$ARCH-legacy-bios.vdi
sudo rm chr-$LATEST_VERSION$ARCH-legacy-bios.img
elif [ "${{ matrix.arch }}" == "arm64" ]; then
sudo qemu-nbd -c /dev/nbd1 -f raw chr.img
sudo mkdir -p ./chr/boot
@@ -375,22 +399,118 @@ jobs:
sudo rm chr-$LATEST_VERSION$ARCH.vdi
sudo rm chr-$LATEST_VERSION$ARCH.img
- name: Upload Files
if: steps.get_latest.outputs.has_new_version == 'true'
- name: Cache refind
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && env.RELEASE == 'true'
id: cache-refind
uses: actions/cache@v4
with:
path: refind-bin-0.14.2.zip
key: refind
- name: Get refind
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && steps.cache-refind.outputs.cache-hit != 'true' && env.RELEASE == 'true'
run: sudo wget -nv -O refind-bin-0.14.2.zip https://nchc.dl.sourceforge.net/project/refind/0.14.2/refind-bin-0.14.2.zip
- name: Create install-image-${{ env.LATEST_VERSION }}.img
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && env.RELEASE == 'true'
run: |
mkdir -p ./publish/$LATEST_VERSION
echo $LATEST_VERSION $BUILD_TIME > ./publish/NEWESTa7.${{ matrix.channel }}
cp CHANGELOG ./publish/$LATEST_VERSION/
cp ./all_packages/*.npk ./publish/$LATEST_VERSION/
sudo apt-get install -y lftp > /dev/null 2>&1
sudo -E lftp -u ${{ secrets.SSH_USERNAME }},'${{ secrets.SSH_PASSWORD }}' sftp://${{ secrets.SSH_SERVER }}:${{ secrets.SSH_PORT }} <<EOF
sudo modprobe nbd
sudo apt-get install -y qemu-utils extlinux > /dev/null
truncate --size 128M install-image-$LATEST_VERSION.img
sudo qemu-nbd -c /dev/nbd0 -f raw install-image-$LATEST_VERSION.img
sudo mkfs.vfat -n "Install" /dev/nbd0
sudo mkdir ./install
sudo mount /dev/nbd0 ./install
sudo mkdir -p ./install/EFI/BOOT
sudo unzip refind-bin-0.14.2.zip refind-bin-0.14.2/refind/refind_x64.efi
sudo cp refind-bin-0.14.2/refind/refind_x64.efi ./install/EFI/BOOT/BOOTX64.EFI
sudo rm -rf refind-bin-0.14.2
echo -e 'timeout 0\ntextonly\ntextmode 0\nshowtools shutdown, reboot, exit\nmenuentry "Install RouterOS" {\n\tloader /linux\n\toptions "load_ramdisk=1 root=/dev/ram0 -install -hdd"\n}\ndefault_selection /EFI/BOOT/BOOTX64.EFI' \
> refind.conf
sudo cp refind.conf ./install/EFI/BOOT/
sudo rm refind.conf
sudo extlinux --install -H 64 -S 32 ./install/
echo -e 'default system\nLABEL system\n\tKERNEL linux\n\tAPPEND load_ramdisk=1 -install -hdd' \
> syslinux.cfg
sudo cp syslinux.cfg ./install/
sudo rm syslinux.cfg
sudo cp ./BOOTX64.EFI ./install/linux
NPK_FILES=($(find ./all_packages/*.npk))
for ((i=1; i<=${#NPK_FILES[@]}; i++))
do
echo "${NPK_FILES[$i-1]}=>$i.npk"
sudo cp ${NPK_FILES[$i-1]} ./install/$i.npk
done
sudo touch ./install/CHOOSE
sudo touch ./install/autorun.scr
sudo umount /dev/nbd0
sudo qemu-nbd -d /dev/nbd0
sudo rm -rf ./install
sudo zip install-image-$LATEST_VERSION.zip ./install-image-$LATEST_VERSION.img
sudo rm ./install-image-$LATEST_VERSION.img
- name: Cache NetInstall ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && env.RELEASE == 'true'
id: cache-netinstall
uses: actions/cache@v4
with:
path: |
netinstall.zip
netinstall.tar.gz
key: netinstall-${{ env.LATEST_VERSION }}
- name: Get netinstall ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && steps.cache-netinstall.outputs.cache-hit != 'true' && env.RELEASE == 'true'
run: |
sudo wget -nv -O netinstall.zip https://download.mikrotik.com/routeros/$LATEST_VERSION/netinstall-$LATEST_VERSION.zip
sudo wget -nv -O netinstall.tar.gz https://download.mikrotik.com/routeros/$LATEST_VERSION/netinstall-$LATEST_VERSION.tar.gz
- name: Patch netinstall ${{ env.LATEST_VERSION }}
if: steps.get_latest.outputs.has_new_version == 'true' && matrix.arch == 'x86' && env.RELEASE == 'true'
run: |
sudo unzip netinstall.zip
sudo -E python3 patch.py netinstall netinstall.exe
sudo zip netinstall-$LATEST_VERSION.zip ./netinstall.exe
sudo tar -xvf netinstall.tar.gz
sudo -E python3 patch.py netinstall netinstall-cli
sudo tar -czvf netinstall-$LATEST_VERSION.tar.gz ./netinstall-cli
- name: Upload Files
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'true'
run: |
sudo mkdir -p ./publish/$LATEST_VERSION
sudo cp CHANGELOG ./publish/$LATEST_VERSION/
sudo cp ./all_packages/*.npk ./publish/$LATEST_VERSION/
sudo chown -R root:root ./publish/
LOCAL_PATH=./publish/$LATEST_VERSION
REMOTE_PATH=${{ secrets.SSH_DIRECTORY }}
SERVER=${{ secrets.SSH_SERVER }}
USER=${{ secrets.SSH_USERNAME }}
PASS=${{ secrets.SSH_PASSWORD }}
PORT=${{ secrets.SSH_PORT }}
CHANNEL=${{ matrix.channel }}
sudo apt-get install -y lftp ssh sshpass > /dev/null 2>&1
sudo -E lftp -u "$USER","$PASS" sftp://$SERVER:$PORT <<EOF
set sftp:auto-confirm yes
mirror --reverse --verbose --only-newer ./publish ${{ secrets.SSH_DIRECTORY }}
mirror --reverse --verbose --only-newer ./publish "$REMOTE_PATH"
bye
EOF
sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER \
"echo $LATEST_VERSION $BUILD_TIME | tee /rw/disk/$REMOTE_PATH/NEWESTa7.$CHANNEL; /rw/disk/$REMOTE_PATH/packages.sh /rw/disk/$REMOTE_PATH/$LATEST_VERSION"
sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no -p $PORT $USER@$SERVER \
"chown -R 32768:32768 /rw/disk/$REMOTE_PATH/"
- name: Clear Cloudflare cache
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'true'
run: |
curl --request POST --url "https://api.cloudflare.com/client/v4/zones/fe6831ed6dc9e6235e69ef2a31f2e7fe/purge_cache" \
--header "Authorization: Bearer 9GDQkzU51QXaqzp1qMjyFKpyeJyOdnNoG9GZQaGP" \
@@ -398,10 +518,10 @@ jobs:
--data '{"purge_everything": true}'
- name: Delete Release tag ${{ env.LATEST_VERSION }} ${{ matrix.arch }}
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'true'
run: |
HEADER="Authorization: token ${{ secrets.GITHUB_TOKEN }}"
RELEASE_INFO=$(curl -s -H $HEADER https://api.github.com/repos/${{ github.repository }}/releases/tags/$LATEST_VERSION$ARCH)
RELEASE_INFO=$(curl -s -H "$HEADER" https://api.github.com/repos/${{ github.repository }}/releases/tags/$LATEST_VERSION$ARCH)
RELEASE_ID=$(echo $RELEASE_INFO | jq -r '.id')
echo "Release ID: $RELEASE_ID"
if [ "$RELEASE_ID" != "null" ]; then
@@ -414,7 +534,7 @@ jobs:
fi
- name: Create Release tag ${{ env.LATEST_VERSION }} ${{ matrix.arch }}
if: steps.get_latest.outputs.has_new_version == 'true'
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'true'
uses: softprops/action-gh-release@v2
with:
name: "RouterOS ${{ env.LATEST_VERSION }} ${{ matrix.arch }}"
@@ -428,6 +548,14 @@ jobs:
netinstall-${{ env.LATEST_VERSION }}.*
install-image-${{ env.LATEST_VERSION }}.zip
routeros-${{ env.LATEST_VERSION }}${{ env.ARCH }}.npk
option-${{ env.LATEST_VERSION }}${{ env.ARCH }}.npk
all_packages-*-${{ env.LATEST_VERSION }}.zip
*.EFI
- name: Upload Files as Artifact (No Release)
if: steps.get_latest.outputs.has_new_version == 'true' && env.RELEASE == 'false'
uses: actions/upload-artifact@v4
with:
name: mikrotik-${{ env.LATEST_VERSION }}-${{ matrix.arch }}
path: |
all_packages-*-${{ env.LATEST_VERSION }}.zip
mikrotik-${{ env.LATEST_VERSION }}${{ env.ARCH }}.iso
chr-${{ env.LATEST_VERSION }}*.zip

1
.gitignore vendored
View File

@@ -2,4 +2,5 @@ __pycache__/
.vscode/
venv/
app/
loader/
test_*.py

View File

@@ -1,5 +1,8 @@
[![Patch Mikrotik RouterOS 6.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml)
[![Patch Mikrotik RouterOS 7.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml)
# MikroTik RouterOS Patch [[English](README_EN.md)]
### [[Discord](https://discord.gg/keV6MWQFtX)] [[Telegram](https://t.me/mikrotikpatch)] [[Keygen(Telegram Bot)](https://t.me/ROS_Keygen_Bot)]
### 国内镜像下载 密码: elseif
[ [123pan](https://www.123pan.com/s/IpxgTd-BYjQh.html) ]
@@ -22,6 +25,9 @@
### Chr模式授权许可
![](image/chr.png)
![](image/arm.png)
![](image/mips.png)
## 如何使用Shell
安装 option-{version}.npk 包
telnet到RouterOS,用户名devel,密码与admin的密码相同
@@ -46,3 +52,4 @@

View File

@@ -1,6 +1,8 @@
[![Patch Mikrotik RouterOS 6.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml)
[![Patch Mikrotik RouterOS 7.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml)
# MikroTik RouterOS Patch [[中文](README.md)]
### [[Discord](https://discord.gg/keV6MWQFtX)] [[Telegram](https://t.me/+99Mw06p3K7NlMmNl)]
### [[Discord](https://discord.gg/keV6MWQFtX)] [[Telegram](https://t.me/mikrotikpatch)] [[Keygen(Telegram Bot)](https://t.me/ROS_Keygen_Bot)]
### Download [Latest Patched](https://github.com/elseif/MikroTikPatch/releases/latest) iso file,install it and enjoy.
### CHR image is both support BIOS and UEFI boot mode.
@@ -19,6 +21,9 @@
### license RouterOS for chr
![](image/chr.png)
![](image/arm.png)
![](image/mips.png)
## How to use shell
install option-{version}.npk package
run telnet to routeros with username devel and password is same as admin
@@ -41,4 +46,3 @@

61
README_PT.md Normal file
View File

@@ -0,0 +1,61 @@
[![Patch Mikrotik RouterOS 6.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_6.yml)
[![Patch Mikrotik RouterOS 7.x](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml/badge.svg)](https://github.com/elseif/MikroTikPatch/actions/workflows/mikrotik_patch_7.yml)
# Patch para MikroTik RouterOS [[中文](README.md)]
### [[Discord](https://discord.gg/keV6MWQFtX)] [[Telegram](https://t.me/mikrotikpatch)] [[Keygen (Bot do Telegram)](https://t.me/ROS_Keygen_Bot)]
### Baixe a [ISO modificada mais recente](https://github.com/elseif/MikroTikPatch/releases/latest), instale e aproveite.
### A imagem CHR suporta modo de boot tanto BIOS quanto UEFI.
### Suporte a atualização online, licença online, backup em nuvem e DDNS em nuvem
![](image/install.png)
![](image/routeros.png)
### Licenciar o RouterOS para x86
![](image/x86.png)
### Renovar a licença para x86 v6.x
![](image/renew_v6.png)
### Renovar a licença para CHR
![](image/renew.png)
### Licenciar o RouterOS para CHR
![](image/chr.png)
![](image/arm.png)
![](image/mips.png)
## Como usar o shell
```bash
instale o pacote option-{versão}.npk
acesse via telnet o routeros com o usuário devel e a senha igual a do usuário admin
```
## Como licenciar o RouterOS
```bash
acesse via telnet o routeros com o usuário devel e a senha igual a do admin
execute o keygen
modo CHR pode usar a renovação de licença online
```
## Como usar o Python 3
```bash
instale o pacote python3-{versão}.npk
acesse via telnet o routeros com o usuário devel e a senha igual a do admin
execute `python -V`
```
### npk.py
```bash
Assina, verifica, cria e extrai arquivos .npk
```
### patch.py
```bash
Altera a chave pública e assina arquivos .npk
```
## Todos os patches são aplicados automaticamente com [GitHub Actions](https://github.com/elseif/MikroTikPatch/blob/main/.github/workflows/)

Binary file not shown.

Binary file not shown.

41
chr.sh
View File

@@ -1,26 +1,15 @@
#!/bin/bash
apt-get install -y gdisk extlinux
dd if=/dev/zero of=/dev/sda bs=1 count=512 conv=notrunc
sgdisk --clear --set-alignment=2 --new=1::+32M --typecode=1:8300 --change-name=1:"RouterOS Boot" --attributes=1:set:2 --new=2::-0 --typecode=2:8300 --change-name=2:"RouterOS" --gpttombr=1:2 /dev/sda
dd if=/dev/sda of=/tmp/pt.bin bs=1 count=66 skip=446
echo -e "\x80" | dd of=/tmp/pt.bin bs=1 count=1 conv=notrunc
dd if=/dev/zero of=/dev/sda bs=1 count=512 conv=notrunc
sgdisk --clear --set-alignment=2 --new=1::+32M --typecode=1:8300 --change-name=1:"RouterOS Boot" --attributes=1:set:2 --new=2::-0 --typecode=2:8300 --change-name=2:"RouterOS" /dev/sda
wget -O /tmp/mbr.bin https://raw.gitmirror.com/elseif/MikroTikPatch/main/mbr.bin
dd if=/tmp/mbr.bin of=/dev/sda bs=1 count=446 conv=notrunc
dd if=/tmp/pt.bin of=/dev/sda bs=1 count=66 seek=446 conv=notrunc
sync
mkfs.vfat -n "Boot" /dev/sda1
mkfs.ext4 -F -L "RouterOS" -m 0 /dev/sda2
mkdir -p /tmp/{boot,routeros}
mount -o loop,rw /dev/sda1 /tmp/boot
mkdir -p /tmp/boot/{BOOT,EFI/BOOT}
wget -O /tmp/boot/EFI/BOOT/BOOTX64.EFI https://hub.gitmirror.com/https://github.com/elseif/MikroTikPatch/releases/download/7.15.2/BOOTX64.EFI
extlinux --install -H 64 -S 32 /tmp/boot/BOOT
echo -e "default system\nlabel system\n\tkernel /EFI/BOOT/BOOTX64.EFI\n\tappend load_ramdisk=1 root=/dev/ram0 quiet" > /tmp/boot/BOOT/syslinux.cfg
umount /tmp/boot
mount -o loop,rw /dev/sda2 /tmp/routeros
mkdir -p /tmp/routeros/{var/pdb/{system,option},boot,rw}
wget -O /tmp/routeros/var/pdb/option/image https://hub.gitmirror.com/https://github.com/elseif/MikroTikPatch/releases/download/7.15.2/option-7.15.2.npk
wget -O /tmp/routeros/var/pdb/system/image https://hub.gitmirror.com/https://github.com/elseif/MikroTikPatch/releases/download/7.15.2/routeros-7.15.2.npk
umount /tmp/routeros
curl -# -L https://github.com/elseif/MikroTikPatch/releases/download/7.19.1/chr-7.19.1-legacy-bios.img.zip -o /tmp/chr.img.zip && cd /tmp && \
gunzip -c chr.img.zip > chr.img && \
STORAGE=`lsblk | grep disk | cut -d ' ' -f 1 | head -n 1` && \
echo STORAGE is $STORAGE && \
ETH=`ip route show default | sed -n 's/.* dev \([^\ ]*\) .*/\1/p'` && \
echo ETH is $ETH && \
ADDRESS=`ip addr show $ETH | grep global | cut -d' ' -f 6 | head -n 1` && \
echo ADDRESS is $ADDRESS && \
GATEWAY=`ip route list | grep default | cut -d' ' -f 3` && \
echo GATEWAY is $GATEWAY && \
sleep 5 && \
dd if=chr.img of=/dev/$STORAGE bs=4M oflag=sync && \
echo "Ok, reboot" && \
echo 1 > /proc/sys/kernel/sysrq && \
echo b > /proc/sysrq-trigger

BIN
image/arm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

BIN
image/mips.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 KiB

Binary file not shown.

Binary file not shown.

BIN
mbr.bin

Binary file not shown.

View File

@@ -1,8 +1,7 @@
import random
import struct
from sha256 import SHA256
from toyecc import AffineCurvePoint, getcurvebyname, FieldElement,ECPrivateKey,ECPublicKey,Tools
from toyecc.Random import secure_rand_int_between
MIKRO_BASE64_CHARACTER_TABLE = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
@@ -39,8 +38,8 @@ def mikro_softwareid_encode(id:int)->str:
assert(isinstance(id, int))
ret = ''
for i in range(8):
ret += chr(SOFTWARE_ID_CHARACTER_TABLE[id % 0x23])
id //= 0x23
ret += chr(SOFTWARE_ID_CHARACTER_TABLE[id % len(SOFTWARE_ID_CHARACTER_TABLE)])
id //= len(SOFTWARE_ID_CHARACTER_TABLE)
if i == 3:
ret += '-'
return ret
@@ -167,7 +166,7 @@ def mikro_kcdsa_sign(data:bytes,private_key:bytes)->bytes:
private_key:ECPrivateKey = ECPrivateKey(Tools.bytestoint_le(private_key), curve)
public_key:ECPublicKey = private_key.pubkey
while True:
nonce_secret = secure_rand_int_between(1, curve.n - 1)
nonce_secret = random.SystemRandom().randint(1, curve.n - 1)
nonce_point = nonce_secret * curve.G
nonce = int(nonce_point.x) % curve.n
nonce_hash = mikro_sha256(Tools.inttobytes_le(nonce,32))
@@ -205,4 +204,4 @@ def mikro_kcdsa_verify(data:bytes, signature:bytes, public_key:bytes)->bool:
nonce = int((public_key * signature + curve.G * data_hash).x)
if mikro_sha256(Tools.inttobytes_le(nonce,32))[:len(nonce_hash)] == nonce_hash:
return True
return False
return False

2
npk.py
View File

@@ -228,7 +228,7 @@ class NovaPackage(Package):
def sign(self,kcdsa_private_key:bytes,eddsa_private_key:bytes):
import hashlib
from mikro import mikro_kcdsa_sign,mikro_eddsa_sign
build_time = os.environ['BUILD_TIME'] if 'BUILD_TIME' in os.environ else None
build_time = os.getenv('BUILD_TIME',None)
if len(self._packages) > 0:
if build_time:
self[NpkPartID.PKG_INFO].data._build_time = int(build_time)

View File

@@ -1,7 +1,42 @@
import subprocess,lzma
import struct,os
import struct,os,re
from npk import NovaPackage,NpkPartID,NpkFileContainer
def replace_chunks(old_chunks,new_chunks,data,name):
pattern_parts = [re.escape(chunk) + b'(.{0,6})' for chunk in old_chunks[:-1]]
pattern_parts.append(re.escape(old_chunks[-1]))
pattern_bytes = b''.join(pattern_parts)
pattern = re.compile(pattern_bytes, flags=re.DOTALL)
def replace_match(match):
replaced = b''.join([new_chunks[i] + match.group(i+1) for i in range(len(new_chunks) - 1)])
replaced += new_chunks[-1]
print(f'{name} public key patched {b"".join(old_chunks)[:16].hex().upper()}...')
return replaced
return re.sub(pattern, replace_match, data)
def replace_key(old,new,data,name=''):
old_chunks = [old[i:i+4] for i in range(0, len(old), 4)]
new_chunks = [new[i:i+4] for i in range(0, len(new), 4)]
data = replace_chunks(old_chunks, new_chunks, data,name)
key_map = [28,19,25,16,14,3,24,15,22,8,6,17,11,7,9,23,18,13,10,0,26,21,2,5,20,30,31,4,27,29,1,12,]
old_chunks = [bytes([old[i]]) for i in key_map]
new_chunks = [bytes([new[i]]) for i in key_map]
data = replace_chunks(old_chunks, new_chunks, data,name)
arch = os.getenv('ARCH') or 'x86'
arch = arch.replace('-', '')
if arch == 'arm64':
old_chunks = [old[i:i+4] for i in range(0, len(old), 4)]
new_chunks = [new[i:i+4] for i in range(0, len(new), 4)]
old_bytes = old_chunks[4] + old_chunks[5] + old_chunks[2] + old_chunks[0] + old_chunks[1] + old_chunks[6] + old_chunks[7]
new_bytes = new_chunks[4] + new_chunks[5] + new_chunks[2] + new_chunks[0] + new_chunks[1] + new_chunks[6] + new_chunks[7]
if old_bytes in data:
print(f'{name} public key patched {old[:16].hex().upper()}...')
data = data.replace(old_bytes,new_bytes)
old_codes = [bytes.fromhex('793583E2'),bytes.fromhex('FD3A83E2'),bytes.fromhex('193D83E2')]
new_codes = [bytes.fromhex('FF34A0E3'),bytes.fromhex('753C83E2'),bytes.fromhex('FC3083E2')]
data = replace_chunks(old_codes, new_codes, data,name)
return data
def patch_bzimage(data:bytes,key_dict:dict):
PE_TEXT_SECTION_OFFSET = 414
HEADER_PAYLOAD_OFFSET = 584
@@ -22,9 +57,7 @@ def patch_bzimage(data:bytes,key_dict:dict):
initramfs = initramfs[:cpio_offset2]
new_initramfs = initramfs
for old_public_key,new_public_key in key_dict.items():
if old_public_key in new_initramfs:
print(f'initramfs public key patched {old_public_key[:16].hex().upper()}...')
new_initramfs = new_initramfs.replace(old_public_key,new_public_key)
new_initramfs = replace_key(old_public_key,new_public_key,new_initramfs,'initramfs')
new_vmlinux = vmlinux.replace(initramfs,new_initramfs)
new_vmlinux_xz = lzma.compress(new_vmlinux,check=lzma.CHECK_CRC32,filters=[
{"id": lzma.FILTER_X86},
@@ -53,6 +86,7 @@ def patch_block(dev:str,file:str,key_dict):
stdout,_ = run_shell_command(f"debugfs {dev} -R 'stat {file}' 2> /dev/null | sed -n '11p' ")
#(0-11):1592-1603, (IND):1173, (12-15):1604-1607, (16-26):1424-1434
blocks_info = stdout.decode().strip().split(',')
print(f'blocks_info : {blocks_info}')
blocks = []
ind_block_id = None
for block_info in blocks_info:
@@ -60,6 +94,7 @@ def patch_block(dev:str,file:str,key_dict):
if _tmp[0].strip() == '(IND)':
ind_block_id = int(_tmp[1])
else:
print(f'block_info : {block_info}')
id_range = _tmp[0].strip().replace('(','').replace(')','').split('-')
block_range = _tmp[1].strip().replace('(','').replace(')','').split('-')
blocks += [id for id in range(int(block_range[0]),int(block_range[1])+1)]
@@ -81,15 +116,23 @@ def patch_initrd_xz(initrd_xz:bytes,key_dict:dict,ljust=True):
initrd = lzma.decompress(initrd_xz)
new_initrd = initrd
for old_public_key,new_public_key in key_dict.items():
if old_public_key in new_initrd:
print(f'initrd public key patched {old_public_key[:16].hex().upper()}...')
new_initrd = new_initrd.replace(old_public_key,new_public_key)
new_initrd_xz = lzma.compress(new_initrd,check=lzma.CHECK_CRC32,filters=[{"id": lzma.FILTER_LZMA2, "preset": 9,}] )
new_initrd = replace_key(old_public_key,new_public_key,new_initrd,'initrd')
preset = 6
new_initrd_xz = lzma.compress(new_initrd,check=lzma.CHECK_CRC32,filters=[{"id": lzma.FILTER_LZMA2, "preset": preset }] )
while len(new_initrd_xz) > len(initrd_xz) and preset < 9:
print(f'preset:{preset}')
print(f'new initrd xz size:{len(new_initrd_xz)}')
print(f'old initrd xz size:{len(initrd_xz)}')
preset += 1
new_initrd_xz = lzma.compress(new_initrd,check=lzma.CHECK_CRC32,filters=[{"id": lzma.FILTER_LZMA2, "preset": preset }] )
if len(new_initrd_xz) > len(initrd_xz):
new_initrd_xz = lzma.compress(new_initrd,check=lzma.CHECK_CRC32,filters=[{"id": lzma.FILTER_LZMA2, "preset": 9 | lzma.PRESET_EXTREME,'dict_size': 32*1024*1024,"lc": 4,"lp": 0, "pb": 0,}] )
if ljust:
assert len(new_initrd_xz) <= len(initrd_xz),'new initrd xz size is too big'
print(f'preset:{preset}')
print(f'new initrd xz size:{len(new_initrd_xz)}')
print(f'old initrd xz size:{len(initrd_xz)}')
print(f'ljust size:{len(initrd_xz)-len(new_initrd_xz)}')
assert len(new_initrd_xz) <= len(initrd_xz),'new initrd xz size is too big'
new_initrd_xz = new_initrd_xz.ljust(len(initrd_xz),b'\0')
return new_initrd_xz
@@ -239,24 +282,38 @@ def patch_kernel(data:bytes,key_dict):
else:
raise Exception('unknown kernel format')
def patch_loader(loader_file):
try:
from package import check_install_package
check_install_package(['pyelftools'])
from loader.patch_loader import patch_loader as do_patch_loader
arch = os.getenv('ARCH') or 'x86'
arch = arch.replace('-', '')
do_patch_loader(loader_file,loader_file,arch)
except ImportError as e:
print(e)
print("loader module import failed. cannot run patch_loader.py")
def patch_squashfs(path,key_dict):
for root, dirs, files in os.walk(path):
for file in files:
file = os.path.join(root,file)
for _file in files:
file = os.path.join(root,_file)
if os.path.isfile(file):
if _file =='loader':
patch_loader(file)
continue
data = open(file,'rb').read()
for old_public_key,new_public_key in key_dict.items():
if old_public_key in data:
print(f'{file} public key patched {old_public_key[:16].hex().upper()}...')
data = data.replace(old_public_key,new_public_key)
open(file,'wb').write(data)
data = open(file,'rb').read()
_data = replace_key(old_public_key,new_public_key,data,file)
if _data != data:
open(file,'wb').write(_data)
url_dict = {
os.environ['MIKRO_LICENCE_URL'].encode():os.environ['CUSTOM_LICENCE_URL'].encode(),
os.environ['MIKRO_UPGRADE_URL'].encode():os.environ['CUSTOM_UPGRADE_URL'].encode(),
os.environ['MIKRO_CLOUD_URL'].encode():os.environ['CUSTOM_CLOUD_URL'].encode(),
os.environ['MIKRO_CLOUD_PUBLIC_KEY'].encode():os.environ['CUSTOM_CLOUD_PUBLIC_KEY'].encode(),
}
data = open(file,'rb').read()
for old_url,new_url in url_dict.items():
if old_url in data:
print(f'{file} url patched {old_url.decode()[:7]}...')
@@ -331,7 +388,7 @@ if __name__ == '__main__':
args = parser.parse_args()
key_dict = {
bytes.fromhex(os.environ['MIKRO_LICENSE_PUBLIC_KEY']):bytes.fromhex(os.environ['CUSTOM_LICENSE_PUBLIC_KEY']),
bytes.fromhex(os.environ['MIKRO_NPK_SIGN_PUBLIC_LKEY']):bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PUBLIC_KEY'])
bytes.fromhex(os.environ['MIKRO_NPK_SIGN_PUBLIC_KEY']):bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PUBLIC_KEY'])
}
kcdsa_private_key = bytes.fromhex(os.environ['CUSTOM_LICENSE_PRIVATE_KEY'])
eddsa_private_key = bytes.fromhex(os.environ['CUSTOM_NPK_SIGN_PRIVATE_KEY'])