├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── run_reinstall.yml │ └── sync_to_cnb.yml ├── LICENSE ├── README.en.md ├── README.md ├── cloud-init-fix-onlink.sh ├── cloud-init.yaml ├── debian.cfg ├── fix-eth-name.initd ├── fix-eth-name.service ├── fix-eth-name.sh ├── frpc-example.toml ├── frpc.service ├── get-frpc-url.sh ├── get-xda.sh ├── initrd-network.sh ├── logviewer-nginx.conf ├── logviewer.html ├── redhat.cfg ├── reinstall.bat ├── reinstall.sh ├── resize.sh ├── trans.sh ├── ttys.sh ├── ubuntu-storage-early.sh ├── ubuntu.yaml ├── windows-allow-ping.bat ├── windows-change-rdp-port.bat ├── windows-del-gpo.bat ├── windows-driver-utils.sh ├── windows-frpc.bat ├── windows-frpc.xml ├── windows-resize.bat ├── windows-set-netconf.bat ├── windows-setup.bat ├── windows.xml └── wmic.ps1 /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{windows.xml,windows-*.xml}] 12 | end_of_line = crlf 13 | 14 | [windows-frpc.xml] 15 | charset = utf-16-le 16 | indent_size = 2 17 | 18 | [*.{bat,cmd,ps1}] 19 | end_of_line = crlf 20 | 21 | [*.ps1] 22 | charset = utf-8-bom 23 | 24 | [*.{yml,yaml}] 25 | indent_size = 2 26 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: bin456789 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report (问题反馈) 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 原来的系统: 11 | 要安装的系统: 12 | 遇到的问题:截图或者登录 SSH 获取日志 /reinstall.log 13 | 14 | Original system: 15 | System to be installed: 16 | Issues encountered: Screenshot or log in via SSH to get the logs from /reinstall.log 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request (功能请求) 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/run_reinstall.yml: -------------------------------------------------------------------------------- 1 | name: 运行主程序 2 | on: 3 | workflow_dispatch: 4 | push: 5 | paths: 6 | - "reinstall.*" 7 | jobs: 8 | run: 9 | name: 运行主程序 10 | strategy: 11 | matrix: 12 | os: [ubuntu-latest, windows-latest] 13 | include: 14 | - os: ubuntu-latest 15 | command: sudo bash reinstall.sh --debug --password 123@@@ 16 | - os: windows-latest 17 | command: ./reinstall.bat --debug --password 123@@@ 18 | runs-on: ${{ matrix.os }} 19 | steps: 20 | - run: | 21 | git config --global core.autocrlf false 22 | - uses: actions/checkout@v4 23 | - run: | 24 | ${{ matrix.command }} centos 25 | ${{ matrix.command }} almalinux 8 26 | ${{ matrix.command }} rocky 9 27 | ${{ matrix.command }} fedora 28 | ${{ matrix.command }} ubuntu 29 | ${{ matrix.command }} debian 30 | ${{ matrix.command }} debian --ci 31 | ${{ matrix.command }} kali 32 | ${{ matrix.command }} alpine 33 | ${{ matrix.command }} opensuse 34 | ${{ matrix.command }} arch 35 | ${{ matrix.command }} gentoo 36 | 37 | ${{ matrix.command }} netboot.xyz 38 | ${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz 39 | ${{ matrix.command }} windows --image-name='Windows Server blah' --iso https://aka.ms/HCIReleaseImage 40 | 41 | # 测试失败例子 42 | # ${{ matrix.command }} wrong-os 43 | # ${{ matrix.command }} dd --img=https://github.com/ 44 | # ${{ matrix.command }} windows --iso=https://github.com/ --image-name=abc 45 | -------------------------------------------------------------------------------- /.github/workflows/sync_to_cnb.yml: -------------------------------------------------------------------------------- 1 | name: 同步到 CNB 2 | on: 3 | workflow_dispatch: 4 | push: 5 | jobs: 6 | run: 7 | name: 同步到 CNB 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | fetch-depth: 0 13 | - uses: yesolutions/mirror-action@master 14 | with: 15 | REMOTE: https://cnb.cool/bin456789/reinstall.git 16 | GIT_USERNAME: cnb 17 | GIT_PASSWORD: ${{ secrets.CNB_TOKEN }} 18 | PUSH_ALL_REFS: false 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | <one line to give the program's name and a brief idea of what it does.> 635 | Copyright (C) <year> <name of author> 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see <https://www.gnu.org/licenses/>. 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | <program> Copyright (C) <year> <name of author> 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | <https://www.gnu.org/licenses/>. 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | <https://www.gnu.org/licenses/why-not-lgpl.html>. 675 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | <!-- markdownlint-disable MD028 MD033 MD045 --> 2 | 3 | # reinstall 4 | 5 | [](https://app.codacy.com/gh/bin456789/reinstall/dashboard) 6 | [](https://www.codefactor.io/repository/github/bin456789/reinstall) 7 | [](https://github.com/XAMPPRocky/tokei_rs) 8 | [](https://t.me/reinstall_os) 9 | [](https://github.com/sponsors/bin456789) 10 | 11 | One-Click Script to Reinstall System [中文](README.md) 12 | 13 | [](https://github.com/sponsors/bin456789) 14 | 15 | ## Highlights 16 | 17 | - One-click Linux installation: Supports 19 common distributions. 18 | - One-click Windows installation: Uses the official ISO for installation instead of custom images. The script can automatically retrieves the ISO link and installs common drivers like `Virtio`. 19 | - Supports installation in any direction, i.e., `Linux to Linux`, `Linux to Windows`, `Windows to Windows`, `Windows to Linux` 20 | - No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC` 21 | - Specially optimized for low-spec servers, requires less memory than the official netboot 22 | - Uses partition table ID to identify hard drives throughout the process, ensuring no wrong disk is written 23 | - Supports BIOS and EFI boot, and ARM Server 24 | - No homemades image included, all resources are obtained in real-time from mirror sites 25 | 26 | ## System Requirements 27 | 28 | The original system can be any system listed in the table. 29 | 30 | The system requirements for the target system are as follows: 31 | 32 | | System | Version | Memory | Disk | 33 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- | 34 | | <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB | 35 | | <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12 | 256 MB | 1 ~ 1.5 GB ^ | 36 | | <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | Rolling | 256 MB | 1 ~ 1.5 GB ^ | 37 | | <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.04 | 512 MB \* | 2 GB | 38 | | <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB | 39 | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL <img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux <img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky <img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (if released) | 512 MB \* | 5 GB | 40 | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | 41 | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | 42 | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 41, 42 | 512 MB \* | 5 GB | 43 | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.03 | 512 MB \* | 5 GB | 44 | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, Tumbleweed (Rolling) | 512 MB \* | 5 GB | 45 | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.05 | 512 MB | 5 GB | 46 | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB | 47 | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB | 48 | | <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> AOSC OS | Rolling | 512 MB | 5 GB | 49 | | <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS | Beta | 512 MB | 8 GB | 50 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | Any | 512 MB | Depends on image | 51 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB | 52 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB | 53 | 54 | \* Indicates installation using cloud images, not traditional network installation. 55 | 56 | ^ Indicates requiring either 256 MB memory + 1.5 GB disk, or 512 MB memory + 1 GB disk 57 | 58 | > [!WARNING] 59 | > ❌ This script does not support OpenVZ or LXC virtual machines. 60 | > 61 | > Please use <https://github.com/LloydAsp/OsMutation> instead. 62 | 63 | ## Download (Current system is <img width="20" height="20" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux) 64 | 65 | For server outside China: 66 | 67 | ```bash 68 | curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_ 69 | ``` 70 | 71 | For server inside China: 72 | 73 | ```bash 74 | curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_ 75 | ``` 76 | 77 | ## Download (Current system is <img width="20" height="20" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows) 78 | 79 | > [!IMPORTANT] 80 | > Before proceeding, please disable the 'Real-time protection' feature in `Windows Defender`. This feature may prevent `certutil` from downloading any files. 81 | 82 | <details> 83 | 84 | <summary>Resolving Script Download Issues on Windows 7</summary> 85 | 86 | Due to lack of support for TLS 1.2, SHA-256, or outdated root certificates, Windows Vista, 7, and Server 2008 (R2) may not be able to download scripts automatically. Manual downloading is required, as follows: 87 | 88 | Use Internet Explorer (enable TLS 1.2 in IE's advanced settings first) to download, or use Remote Desktop to save the following two files into the same directory: 89 | 90 | - <https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat> 91 | 92 | - <https://www.cygwin.com/setup-x86.exe> 93 | 94 | To use, run the downloaded `reinstall.bat`. 95 | 96 | </details> 97 | 98 | For server outside China: 99 | 100 | ```batch 101 | certutil -urlcache -f -split https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat 102 | ``` 103 | 104 | For server inside China: 105 | 106 | ```batch 107 | certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.bat 108 | ``` 109 | 110 | ## Usage 111 | 112 | **All features** can be used on both Linux and Windows. 113 | 114 | - on Linux, run `bash reinstall.sh ...` 115 | - on Windows, first run `cmd`, then run `.\reinstall.bat ...` 116 | - If the link in the parameter contains special characters, it should be enclosed in `""`, not `''`. 117 | 118 | ### Feature 1: Install <img width="16" height="16" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux 119 | 120 | - The username is `root` with a default password of `123@@@`. 121 | - When installing the latest version, the version number does not need to be specified. 122 | - Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition. 123 | - Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels. 124 | - When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`. 125 | - After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`. 126 | 127 | ```bash 128 | bash reinstall.sh anolis 7|8|23 129 | rocky 8|9|10 130 | oracle 8|9 131 | almalinux 8|9|10 132 | opencloudos 8|9|23 133 | centos 9|10 134 | fedora 41|42 135 | nixos 25.05 136 | debian 9|10|11|12 137 | opensuse 15.6|tumbleweed 138 | alpine 3.19|3.20|3.21|3.22 139 | openeuler 20.03|22.03|24.03|25.03 140 | ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal] 141 | kali 142 | arch 143 | gentoo 144 | aosc 145 | fnos 146 | redhat --img="http://access.cdn.redhat.com/xxx.qcow2" 147 | ``` 148 | 149 | #### Optional Parameters 150 | 151 | - `--password PASSWORD` Set the password 152 | - `--ssh-key KEY` Set up SSH login public key, supports these formats. When using public key, password is empty. 153 | - `--ssh-key "ssh-rsa ..."` 154 | - `--ssh-key "ssh-ed25519 ..."` 155 | - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."` 156 | - `--ssh-key http://path/to/public_key` 157 | - `--ssh-key github:your_username` 158 | - `--ssh-key gitlab:your_username` 159 | - `--ssh-key /path/to/public_key` 160 | - `--ssh-key C:\path\to\public_key` 161 | - `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system) 162 | - `--web-port PORT` Change the Web port (for log observation during installation) 163 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling 164 | - `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/os` (this feature is not supported on Debian/Kali). 165 | 166 | > [!TIP] 167 | > When installing Debian/Kali, x86 architectures can monitor the installation progress through VNC from server provider, while ARM architectures can use the serial console. 168 | > 169 | > When installing other systems, can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console). 170 | > <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine` 171 | 172 | <details> 173 | 174 | <summary>Experimental Features</summary> 175 | 176 | Install Debian using a cloud image 177 | 178 | - Suitable for machines with slower CPUs 179 | 180 | ```bash 181 | bash reinstall.sh debian --ci 182 | ``` 183 | 184 | Install CentOS, AlmaLinux, Rocky, Fedora using ISO 185 | 186 | - Only supports machines with more than 2G of memory and dynamic IP. 187 | - Password is `123@@@`, and the SSH port is `22`; modifying them using parameters is not supported. 188 | 189 | ```bash 190 | bash reinstall.sh centos --installer 191 | ``` 192 | 193 | Install Ubuntu using ISO 194 | 195 | - Only supports machines with more than 1G of memory and dynamic IP. 196 | - Password is `123@@@`, and the SSH port is `22`; modifying them using parameters is not supported. 197 | 198 | ```bash 199 | bash reinstall.sh ubuntu --installer 200 | ``` 201 | 202 | </details> 203 | 204 | ### Feature 2: DD 205 | 206 | - Supports `raw` and `vhd` image formats (either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`). 207 | - When deploy a Windows image, the system disk will be automatically expanded, and machines with a static IP will have their IP configured, and may take a few minutes after the first boot for the configuration to take effect. 208 | - When deploy a Linux image, will **NOT** modify any contents of the image. 209 | 210 | ```bash 211 | bash reinstall.sh dd --img "https://example.com/xxx.xz" 212 | ``` 213 | 214 | #### Optional Parameters 215 | 216 | - `--allow-ping` Configure Windows Firewall to Allow Ping Responses (DD Windows only) 217 | - `--rdp-port PORT` Change RDP port (DD Windows only) 218 | - `--ssh-port PORT` Change SSH port (for log observation during installation) 219 | - `--web-port PORT` Change Web port (for log observation during installation) 220 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling (DD Windows only) 221 | - `--hold 2` Prevent reboot after the DD process finishes, allowing SSH login to modify system content. The Windows system will be mounted at `/os`, but Linux systems will **NOT** be automatically mounted. 222 | 223 | > [!TIP] 224 | > Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console). 225 | > <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine` 226 | 227 | ### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS (RAM OS) 228 | 229 | - You can use SSH to backup/restore disk, manually perform DD operations, modify partitions, and manually install Alpine, Arch, Gentoo, and other systems. 230 | - Username `root`, Default password `123@@@` 231 | - If manual operations do not damage the original system, rebooting will return to the original system. 232 | 233 | ```bash 234 | bash reinstall.sh alpine --hold=1 235 | ``` 236 | 237 | #### Optional Parameters 238 | 239 | - `--password PASSWORD` Set password 240 | - `--ssh-port PORT` Change SSH port 241 | - `--ssh-key KEY` Set up SSH login public key, supports these formats. When using public key, password is empty. 242 | - `--ssh-key "ssh-rsa ..."` 243 | - `--ssh-key "ssh-ed25519 ..."` 244 | - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."` 245 | - `--ssh-key http://path/to/public_key` 246 | - `--ssh-key github:your_username` 247 | - `--ssh-key gitlab:your_username` 248 | - `--ssh-key /path/to/public_key` 249 | - `--ssh-key C:\path\to\public_key` 250 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling 251 | 252 | ### Feature 4: Reboot to <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz 253 | 254 | - Can manually install [more systems](https://github.com/netbootxyz/netboot.xyz?tab=readme-ov-file#what-operating-systems-are-currently-available-on-netbootxyz) using vendor backend VNC. 255 | - If manual operations do not damage the original system, rebooting will return to the original system. 256 | 257 | ```bash 258 | bash reinstall.sh netboot.xyz 259 | ``` 260 | 261 |  262 | 263 | ### Feature 5: Install <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows ISO 264 | 265 |  266 | 267 | - Username `administrator`, Default password `123@@@` 268 | - If remote login fails, try using the username `.\administrator`. 269 | - The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot. 270 | - Supports all languages. 271 | 272 | #### Supported Systems 273 | 274 | - Windows (Vista ~ 11) 275 | - Windows Server (2008 ~ 2025) 276 | - Windows Server Essentials \* 277 | - Windows Server (Semi) Annual Channel \* 278 | - Hyper-V Server \* 279 | - Azure Stack HCI \* 280 | 281 | #### Method 1: Let the Script Automatically Search for ISO 282 | 283 | - The script will search for ISOs from <https://massgrave.dev/genuine-installation-media>, a site that collects official ISOs. 284 | - Systems marked with \* do not support automatic ISO searching. 285 | 286 | ```bash 287 | bash reinstall.sh windows \ 288 | --image-name "Windows 11 Enterprise LTSC 2024" \ 289 | --lang zh-cn 290 | ``` 291 | 292 | <details> 293 | <summary>Supported languages</summary> 294 | 295 | ```text 296 | ar-sa 297 | bg-bg 298 | cs-cz 299 | da-dk 300 | de-de 301 | el-gr 302 | en-gb 303 | en-us 304 | es-es 305 | es-mx 306 | et-ee 307 | fi-fi 308 | fr-ca 309 | fr-fr 310 | he-il 311 | hr-hr 312 | hu-hu 313 | it-it 314 | ja-jp 315 | ko-kr 316 | lt-lt 317 | lv-lv 318 | nb-no 319 | nl-nl 320 | pl-pl 321 | pt-pt 322 | pt-br 323 | ro-ro 324 | ru-ru 325 | sk-sk 326 | sl-si 327 | sr-latn-rs 328 | sv-se 329 | th-th 330 | tr-tr 331 | uk-ua 332 | zh-cn 333 | zh-hk 334 | zh-tw 335 | ``` 336 | 337 | </details> 338 | 339 | #### Method 2: Specify the ISO link manually 340 | 341 | - If you don't know the `--image-name`, you can enter any value. After rebooting, connect via SSH and re-enter the correct value based on the error messages. 342 | 343 | ```bash 344 | bash reinstall.sh windows \ 345 | --image-name "Windows 11 Enterprise LTSC 2024 Evaluation" \ 346 | --iso "https://go.microsoft.com/fwlink/?linkid=2289029" 347 | ``` 348 | 349 | or Magnet Link 350 | 351 | ```bash 352 | bash reinstall.sh windows \ 353 | --image-name "Windows 11 Enterprise LTSC 2024" \ 354 | --iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff" 355 | ``` 356 | 357 | <details> 358 | 359 | <summary>The following website provides ISO links.</summary> 360 | 361 | - General 362 | - <https://msdl.gravesoft.dev> 363 | - <https://massgrave.dev/genuine-installation-media> 364 | - <https://next.itellyou.cn> 365 | - <https://www.xitongku.com> 366 | - <https://www.microsoft.com/software-download/windows10> (Need to open it with a non-Windows User-Agent) 367 | - <https://www.microsoft.com/software-download/windows11> 368 | - <https://www.microsoft.com/software-download/windows11arm64> 369 | - Evaluation 370 | - <https://www.microsoft.com/evalcenter/download-windows-10-enterprise> 371 | - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise> 372 | - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval> 373 | - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2> 374 | - <https://www.microsoft.com/evalcenter/download-windows-server-2016> 375 | - <https://www.microsoft.com/evalcenter/download-windows-server-2019> 376 | - <https://www.microsoft.com/evalcenter/download-windows-server-2022> 377 | - <https://www.microsoft.com/evalcenter/download-windows-server-2025> 378 | - Insider Preview 379 | - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewiso> 380 | - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver> 381 | 382 | </details> 383 | 384 | #### Optional Parameters 385 | 386 | - `--password PASSWORD` Set Password 387 | - `--allow-ping` Configure Windows Firewall to Allow Ping Responses 388 | - `--rdp-port PORT` Change RDP port 389 | - `--ssh-port PORT` Change SSH port (for log observation during installation) 390 | - `--web-port PORT` Change Web port (for log observation during installation) 391 | - `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file. 392 | - The driver must be downloaded locally first. 393 | - This parameter can be set multiple times to add different driver. 394 | - `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling 395 | - `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`. 396 | 397 | #### The following drivers will automatic download and install as needed, without the need for manual addition 398 | 399 | - Virtio ([Virtio][virtio-virtio], [Alibaba Cloud][virtio-aliyun], [Tencent Cloud][virtio-qcloud], [GCP][virtio-gcp]) 400 | - XEN ([~~XEN~~][xen-xen] (unsigned), [Citrix][xen-citrix], [AWS][xen-aws]) 401 | - AWS ([ENA Network Adapter][aws-ena], [NVME Storage Controller][aws-nvme]) 402 | - GCP ([gVNIC Network Adapter][gcp-gvnic], [GGA Display Adapter][gcp-gga]) 403 | - Azure ([MANA Network Adapter][azure-mana]) 404 | - Intel ([VMD Storage Controller][intel-vmd], Network Adapter: [7][intel-nic-7], [8][intel-nic-8], [8.1][intel-nic-8.1], [10][intel-nic-10], [11][intel-nic-11], [2008 R2][intel-nic-2008-r2], [2012][intel-nic-2012], [2012 R2][intel-nic-2012-r2], [2016][intel-nic-2016], [2019][intel-nic-2019], [2022][intel-nic-2022], [2025][intel-nic-2025]) 405 | 406 | [virtio-virtio]: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/ 407 | [virtio-aliyun]: https://www.alibabacloud.com/help/ecs/user-guide/install-the-virtio-driver-1 408 | [virtio-qcloud]: https://cloud.tencent.com/document/product/213/17815#b84b2032-752c-43c4-a509-73530b8f82ff 409 | [virtio-gcp]: https://console.cloud.google.com/storage/browser/gce-windows-drivers-public 410 | [xen-xen]: https://xenproject.org/resources/downloads/ 411 | [xen-aws]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/xen-drivers-overview.html 412 | [xen-citrix]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Upgrading_PV_drivers.html#win2008-citrix-upgrade 413 | [aws-ena]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ena-driver-releases-windows.html 414 | [aws-nvme]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-driver-version-history.html 415 | [gcp-gvnic]: https://cloud.google.com/compute/docs/networking/using-gvnic 416 | [gcp-gga]: https://cloud.google.com/compute/docs/instances/enable-instance-virtual-display 417 | [azure-mana]: https://learn.microsoft.com/azure/virtual-network/accelerated-networking-mana-windows 418 | [intel-vmd]: https://www.intel.com/content/www/us/en/download/849936/intel-rapid-storage-technology-driver-installation-software-with-intel-optane-memory-12th-to-15th-gen-platforms.html 419 | [intel-nic-7]: https://www.intel.com/content/www/us/en/download/15590/intel-network-adapter-driver-for-windows-7-final-release.html 420 | [intel-nic-8]: https://www.intel.com/content/www/us/en/download/16765/intel-network-adapter-driver-for-windows-8-final-release.html 421 | [intel-nic-8.1]: https://www.intel.com/content/www/us/en/download/17479/intel-network-adapter-driver-for-windows-8-1.html 422 | [intel-nic-10]: https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driver-for-windows-10.html 423 | [intel-nic-11]: https://www.intel.com/content/www/us/en/download/727998/intel-network-adapter-driver-for-microsoft-windows-11.html 424 | [intel-nic-2008-r2]: https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html 425 | [intel-nic-2012]: https://www.intel.com/content/www/us/en/download/16789/intel-network-adapter-driver-for-windows-server-2012.html 426 | [intel-nic-2012-r2]: https://www.intel.com/content/www/us/en/download/17480/intel-network-adapter-driver-for-windows-server-2012-r2.html 427 | [intel-nic-2016]: https://www.intel.com/content/www/us/en/download/18737/intel-network-adapter-driver-for-windows-server-2016.html 428 | [intel-nic-2019]: https://www.intel.com/content/www/us/en/download/19372/intel-network-adapter-driver-for-windows-server-2019.html 429 | [intel-nic-2022]: https://www.intel.com/content/www/us/en/download/706171/intel-network-adapter-driver-for-windows-server-2022.html 430 | [intel-nic-2025]: https://www.intel.com/content/www/us/en/download/838943/intel-network-adapter-driver-for-windows-server-2025.html 431 | 432 | #### How to Specify the Image Name `--image-name` 433 | 434 | Typically, an ISO will contain multiple system versions, such as Home Edition and Professional Edition. The image name `--image-name` is used to specify the version to be installed, and it is case-insensitive when entered. 435 | 436 | You can use tools like DISM, DISM++, or Wimlib to query the image names included in the ISO. 437 | 438 | Commonly used image names include: 439 | 440 | ```text 441 | Windows 7 Ultimate 442 | Windows 11 Pro 443 | Windows 11 Enterprise LTSC 2024 444 | Windows Server 2025 SERVERDATACENTER 445 | ``` 446 | 447 | #### How to Use [DISM++](https://github.com/Chuyu-Team/Dism-Multi-language/releases) to Query the Image Names Included in the ISO 448 | 449 | Open File menu > Open Image File, select the iso to be installed to get the image name (full system name), and all available image names are installable. 450 | 451 |  452 | 453 | > [!WARNING] 454 | > Vista (Server 2008) and 32-bit systems may lack drivers. 455 | 456 | > [!WARNING] 457 | > For EFI machines without CSM enabled, Windows 7 (Server 2008 R2) cannot be installed. 458 | > 459 | > Hyper-V (Azure) requires selecting the appropriate VM generation: <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v> 460 | 461 | > [!WARNING] 462 | > In the Chinese version of Windows 10 LTSC 2021 ISO `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso`, the `wsappx` process may indefinitely consume CPU resources. 463 | > 464 | > The solution is to update the system patches or manually install the `VCLibs` library <https://www.google.com/search?q=ltsc+wsappx>. 465 | 466 | #### Considerations for Installing Windows on ARM 467 | 468 | Most ARM machines support installing latest Windows 11. 469 | 470 | During the installation process, you might encounter a black screen, and the serial console may display `ConvertPages: failed to find range`, but neither issue affects the installation. 471 | 472 | | Compatibility | Cloud Provider | Instance Type | Issues | 473 | | ------------- | -------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | 474 | | ✔️ | Azure | B2pts_v2 | | 475 | | ✔️ | Alibaba Cloud | g6r, c6r | | 476 | | ✔️ | Alibaba Cloud | g8y, c8y, r8y | There is a chance of hanging at the boot logo during restart; forced reboot will resolve it. | 477 | | ✔️ | AWS | T4g | | 478 | | ✔️ | Scaleway | COPARM1 | | 479 | | ✔️ | Gcore | | | 480 | | ❔ | Oracle Cloud | A1.Flex | Installation success is not guaranteed; newer instances are more likely to succeed.<br />Manual loading of GPU drivers is required after installation. | 481 | | ❌ | Google Cloud | t2a | Missing network card drivers | 482 | 483 | <details> 484 | 485 | <summary>Loading Graphics Driver on Oracle Cloud</summary> 486 | 487 | Log in to the server using Remote Desktop, open Device Manager, locate the graphics card, select "Update Driver," and choose `Red Hat VirtIO GPU DOD controller` from the list. There's no need to download the drivers in advance. 488 | 489 |  490 |  491 |  492 | 493 | </details> 494 | 495 | ## Discussion 496 | 497 | [](https://github.com/bin456789/reinstall/issues) 498 | [](https://t.me/reinstall_os) 499 | 500 | ## How to Modify the Script for Your Own 501 | 502 | 1. Fork this repository. 503 | 2. Modify the `confhome` and `confhome_cn` at the beginning of `reinstall.sh` and `reinstall.bat`. 504 | 3. Make changes to the other code. 505 | 506 | ## Thanks 507 | 508 | [](https://github.com/sponsors/bin456789) 509 | 510 | Thanks to the following businesses for providing free servers. 511 | 512 | [](https://www.oracle.com/cloud/) 513 | [](https://dartnode.com/) 514 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | <!-- markdownlint-disable MD028 MD033 MD045 --> 2 | 3 | # reinstall 4 | 5 | [](https://app.codacy.com/gh/bin456789/reinstall/dashboard) 6 | [](https://www.codefactor.io/repository/github/bin456789/reinstall) 7 | [](https://github.com/XAMPPRocky/tokei_rs) 8 | [](https://t.me/reinstall_os) 9 | [](https://github.com/sponsors/bin456789) 10 | 11 | 一键重装脚本 [English](README.en.md) 12 | 13 | [](https://github.com/sponsors/bin456789) 14 | 15 | ## 亮点 16 | 17 | - 一键安装 Linux,支持 19 种常见发行版 18 | - 一键安装 Windows,使用官方 ISO 安装而非自制镜像,脚本会自动获取 ISO 链接、自动安装 Virtio 等常见驱动 19 | - 支持任意方向重装,即 `Linux to Linux`、`Linux to Windows`、`Windows to Windows`、`Windows to Linux` 20 | - 无需填写 IP 参数,自动识别动静态,支持 `/32`、`/128`、`网关不在子网范围内`、`纯 IPv6`、`双网卡` 21 | - 专门适配低配小鸡,比官方 netboot 需要更少的内存 22 | - 全程用分区表 ID 识别硬盘,确保不会写错硬盘 23 | - 支持 BIOS、EFI 引导,支持 ARM 服务器 24 | - 不含自制包,所有资源均实时从镜像源获得 25 | 26 | ## 系统要求 27 | 28 | 原系统可以是表格中的任意系统 29 | 30 | 目标系统的配置要求如下: 31 | 32 | | 系统 | 版本 | 内存 | 硬盘 | 33 | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ | 34 | | <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB | 35 | | <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12 | 256 MB | 1 ~ 1.5 GB ^ | 36 | | <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | 滚动 | 256 MB | 1 ~ 1.5 GB ^ | 37 | | <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.04 | 512 MB \* | 2 GB | 38 | | <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB | 39 | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL <img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux <img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky <img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (如果有) | 512 MB \* | 5 GB | 40 | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | 41 | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | 42 | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 41, 42 | 512 MB \* | 5 GB | 43 | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.03 | 512 MB \* | 5 GB | 44 | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, Tumbleweed (滚动) | 512 MB \* | 5 GB | 45 | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.05 | 512 MB | 5 GB | 46 | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB | 47 | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB | 48 | | <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB | 49 | | <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 公测 | 512 MB | 8 GB | 50 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | 任何 | 512 MB | 取决于镜像 | 51 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB | 52 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB | 53 | 54 | \* 表示使用云镜像安装,非传统网络安装 55 | 56 | ^ 表示需要 256 MB 内存 + 1.5 GB 硬盘,或 512 MB 内存 + 1 GB 硬盘 57 | 58 | > [!WARNING] 59 | > ❌ 本脚本不支持 OpenVZ、LXC 虚拟机 60 | > 61 | > 请改用 <https://github.com/LloydAsp/OsMutation> 62 | 63 | ## 下载(当前系统是 <img width="20" height="20" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux) 64 | 65 | 国外服务器: 66 | 67 | ```bash 68 | curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_ 69 | ``` 70 | 71 | 国内服务器: 72 | 73 | ```bash 74 | curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_ 75 | ``` 76 | 77 | ## 下载(当前系统是 <img width="20" height="20" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows) 78 | 79 | > [!IMPORTANT] 80 | > 请先关闭 `Windows Defender` 的 `实时保护` 功能。该功能会阻止 `certutil` 下载任何文件。 81 | 82 | <details> 83 | 84 | <summary>解决 Windows 7 下无法下载脚本</summary> 85 | 86 | 由于不支持 TLS 1.2、SHA-256、根证书没有更新等原因,Vista,7 和 Server 2008 (R2) 可能无法自动下载脚本,因此需要手动下载,具体操作如下: 87 | 88 | 用 IE 下载 (先在 IE 高级设置里启用 TLS 1.2),或者通过远程桌面,将这两个文件保存到同一个目录 89 | 90 | - <https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat> 91 | 92 | - <https://www.cygwin.com/setup-x86.exe> 93 | 94 | 使用时运行下载的 `reinstall.bat` 95 | 96 | </details> 97 | 98 | 国外服务器: 99 | 100 | ```batch 101 | certutil -urlcache -f -split https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.bat 102 | ``` 103 | 104 | 国内服务器: 105 | 106 | ```batch 107 | certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.bat 108 | ``` 109 | 110 | ## 使用 111 | 112 | **所有功能** 都可在 Linux / Windows 下运行 113 | 114 | - Linux 下运行 `bash reinstall.sh ...` 115 | - Windows 下先运行 `cmd`,再运行 `reinstall.bat ...` 116 | - 如果参数中的链接包含特殊字符,要用 `""` 将链接包起来,不能用 `''` 117 | 118 | ### 功能 1: 安装 <img width="16" height="16" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux 119 | 120 | - 用户名 `root` 默认密码 `123@@@` 121 | - 安装最新版可不输入版本号 122 | - 最大化利用磁盘空间:不含 boot 分区(Fedora 例外),不含 swap 分区 123 | - 自动根据机器类型选择不同的优化内核,例如 `Cloud`、`HWE` 内核 124 | - 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统,例如 `Alibaba Cloud Linux` 和 `TencentOS Server` 125 | - 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件 126 | 127 | ```bash 128 | bash reinstall.sh anolis 7|8|23 129 | rocky 8|9|10 130 | oracle 8|9 131 | almalinux 8|9|10 132 | opencloudos 8|9|23 133 | centos 9|10 134 | fedora 41|42 135 | nixos 25.05 136 | debian 9|10|11|12 137 | opensuse 15.6|tumbleweed 138 | alpine 3.19|3.20|3.21|3.22 139 | openeuler 20.03|22.03|24.03|25.03 140 | ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal] 141 | kali 142 | arch 143 | gentoo 144 | aosc 145 | fnos 146 | redhat --img="http://access.cdn.redhat.com/xxx.qcow2" 147 | ``` 148 | 149 | #### 可选参数 150 | 151 | - `--password PASSWORD` 设置密码 152 | - `--ssh-key KEY` 设置 SSH 登录公钥,支持以下格式。当使用公钥时,密码为空 153 | - `--ssh-key "ssh-rsa ..."` 154 | - `--ssh-key "ssh-ed25519 ..."` 155 | - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."` 156 | - `--ssh-key http://path/to/public_key` 157 | - `--ssh-key github:your_username` 158 | - `--ssh-key gitlab:your_username` 159 | - `--ssh-key /path/to/public_key` 160 | - `--ssh-key C:\path\to\public_key` 161 | - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统) 162 | - `--web-port PORT` 修改 Web 端口(安装期间观察日志用) 163 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 164 | - `--hold 2` 安装结束后不重启,此时可以 SSH 登录修改系统内容,系统挂载在 `/os` (此功能不支持 Debian/Kali) 165 | 166 | > [!TIP] 167 | > 安装 Debian/Kali 时,x86 可通过商家后台 VNC 查看安装进度,ARM 可通过串行控制台查看安装进度。 168 | > 169 | > 安装其它系统时,可通过多种方式(SSH、HTTP 80 端口、商家后台 VNC、串行控制台)查看安装进度。 170 | > <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。 171 | 172 | <details> 173 | 174 | <summary>实验性功能</summary> 175 | 176 | 云镜像安装 Debian 177 | 178 | - 适合于 CPU 较慢的机器 179 | 180 | ```bash 181 | bash reinstall.sh debian --ci 182 | ``` 183 | 184 | ISO 安装 CentOS, AlmaLinux, Rocky, Fedora 185 | 186 | - 仅支持内存大于 2G 且为动态 IP 的机器 187 | - 密码 `123@@@`,SSH 端口 `22`,不支持用参数修改 188 | 189 | ```bash 190 | bash reinstall.sh centos --installer 191 | ``` 192 | 193 | ISO 安装 Ubuntu 194 | 195 | - 仅支持内存大于 1G 且为动态 IP 的机器 196 | - 密码 `123@@@`,SSH 端口 `22`,不支持用参数修改 197 | 198 | ```bash 199 | bash reinstall.sh ubuntu --installer 200 | ``` 201 | 202 | </details> 203 | 204 | ### 功能 2: DD 205 | 206 | - 支持 `raw` `vhd` 格式的镜像(未压缩,或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst`) 207 | - DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP,可能首次开机几分钟后才生效 208 | - DD Linux 镜像时,**不会**修改镜像的任何内容 209 | 210 | ```bash 211 | bash reinstall.sh dd --img "https://example.com/xxx.xz" 212 | ``` 213 | 214 | #### 可选参数 215 | 216 | - `--allow-ping` 设置 Windows 防火墙允许被 Ping (仅限 DD Windows) 217 | - `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows) 218 | - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用) 219 | - `--web-port PORT` 修改 Web 端口(安装期间观察日志用) 220 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透(仅限 DD Windows) 221 | - `--hold 2` DD 结束后不重启,此时可以 SSH 登录修改系统内容,Windows 系统会挂载在 `/os`,Linux 系统**不会**自动挂载 222 | 223 | > [!TIP] 224 | > 可通过多种方式(SSH、HTTP 80 端口、商家后台 VNC、串行控制台)查看安装进度。 225 | > <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。 226 | 227 | ### 功能 3: 重启到 <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS(内存系统) 228 | 229 | - 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine/Arch/Gentoo 等操作 230 | - 用户名 `root` 默认密码 `123@@@` 231 | - 如果手动操作没有破坏原系统,再次重启将回到原系统 232 | 233 | ```bash 234 | bash reinstall.sh alpine --hold=1 235 | ``` 236 | 237 | #### 可选参数 238 | 239 | - `--password PASSWORD` 设置密码 240 | - `--ssh-port PORT` 修改 SSH 端口 241 | - `--ssh-key KEY` 设置 SSH 登录公钥,支持以下格式。当使用公钥时,密码为空 242 | - `--ssh-key "ssh-rsa ..."` 243 | - `--ssh-key "ssh-ed25519 ..."` 244 | - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."` 245 | - `--ssh-key http://path/to/public_key` 246 | - `--ssh-key github:your_username` 247 | - `--ssh-key gitlab:your_username` 248 | - `--ssh-key /path/to/public_key` 249 | - `--ssh-key C:\path\to\public_key` 250 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 251 | 252 | ### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz 253 | 254 | - 可使用商家后台 VNC 手动安装 [更多系统](https://github.com/netbootxyz/netboot.xyz?tab=readme-ov-file#what-operating-systems-are-currently-available-on-netbootxyz) 255 | - 如果手动操作没有破坏原系统,再次重启将回到原系统 256 | 257 | ```bash 258 | bash reinstall.sh netboot.xyz 259 | ``` 260 | 261 |  262 | 263 | ### 功能 5: 安装 <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows ISO 264 | 265 |  266 | 267 | - 用户名 `administrator` 默认密码 `123@@@` 268 | - 如果远程登录失败,可以尝试使用用户名 `.\administrator` 269 | - 静态机器会自动配置好 IP,可能首次开机几分钟后才生效 270 | - 支持所有语言 271 | 272 | #### 支持的系统 273 | 274 | - Windows (Vista ~ 11) 275 | - Windows Server (2008 ~ 2025) 276 | - Windows Server Essentials \* 277 | - Windows Server (Semi) Annual Channel \* 278 | - Hyper-V Server \* 279 | - Azure Stack HCI \* 280 | 281 | #### 方法 1: 让脚本自动查找 ISO 282 | 283 | - 脚本会从 <https://massgrave.dev/genuine-installation-media> 查找 ISO,该网站专门提供官方 ISO 下载 284 | - 上面带 \* 的系统不支持自动查找 ISO 285 | 286 | ```bash 287 | bash reinstall.sh windows \ 288 | --image-name "Windows 11 Enterprise LTSC 2024" \ 289 | --lang zh-cn 290 | ``` 291 | 292 | <details> 293 | <summary>支持的语言</summary> 294 | 295 | ```text 296 | ar-sa 297 | bg-bg 298 | cs-cz 299 | da-dk 300 | de-de 301 | el-gr 302 | en-gb 303 | en-us 304 | es-es 305 | es-mx 306 | et-ee 307 | fi-fi 308 | fr-ca 309 | fr-fr 310 | he-il 311 | hr-hr 312 | hu-hu 313 | it-it 314 | ja-jp 315 | ko-kr 316 | lt-lt 317 | lv-lv 318 | nb-no 319 | nl-nl 320 | pl-pl 321 | pt-pt 322 | pt-br 323 | ro-ro 324 | ru-ru 325 | sk-sk 326 | sl-si 327 | sr-latn-rs 328 | sv-se 329 | th-th 330 | tr-tr 331 | uk-ua 332 | zh-cn 333 | zh-hk 334 | zh-tw 335 | ``` 336 | 337 | </details> 338 | 339 | #### 方法 2: 自行指定 ISO 连接 340 | 341 | - 如果不知道 `--image-name`,可以随便填,在重启后连接 SSH,根据错误提示重新输入正确的值 342 | 343 | ```bash 344 | bash reinstall.sh windows \ 345 | --image-name "Windows 11 Enterprise LTSC 2024 Evaluation" \ 346 | --iso "https://go.microsoft.com/fwlink/?linkid=2289029" 347 | ``` 348 | 349 | 或者磁力链接 350 | 351 | ```bash 352 | bash reinstall.sh windows \ 353 | --image-name "Windows 11 Enterprise LTSC 2024" \ 354 | --iso "magnet:?xt=urn:btih:7352bd2db48c3381dffa783763dc75aa4a6f1cff" 355 | ``` 356 | 357 | <details> 358 | 359 | <summary>以下网站可找到 ISO 链接</summary> 360 | 361 | - 正式版 362 | - <https://msdl.gravesoft.dev> 363 | - <https://massgrave.dev/genuine-installation-media> 364 | - <https://next.itellyou.cn> 365 | - <https://www.xitongku.com> 366 | - <https://www.microsoft.com/software-download/windows10> (需用非 Windows User-Agent 打开) 367 | - <https://www.microsoft.com/software-download/windows11> 368 | - <https://www.microsoft.com/software-download/windows11arm64> 369 | - 评估版 370 | - <https://www.microsoft.com/evalcenter/download-windows-10-enterprise> 371 | - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise> 372 | - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval> 373 | - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2> 374 | - <https://www.microsoft.com/evalcenter/download-windows-server-2016> 375 | - <https://www.microsoft.com/evalcenter/download-windows-server-2019> 376 | - <https://www.microsoft.com/evalcenter/download-windows-server-2022> 377 | - <https://www.microsoft.com/evalcenter/download-windows-server-2025> 378 | - Insider 预览版 379 | - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewiso> 380 | - <https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver> 381 | 382 | </details> 383 | 384 | #### 可选参数 385 | 386 | - `--password PASSWORD` 设置密码 387 | - `--allow-ping` 设置 Windows 防火墙允许被 Ping 388 | - `--rdp-port PORT` 更改 RDP 端口 389 | - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用) 390 | - `--web-port PORT` 修改 Web 端口(安装期间观察日志用) 391 | - `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹 392 | - 需先下载驱动到本地 393 | - 可多次设置该参数以添加不同的驱动 394 | - `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 395 | - `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os` 396 | 397 | #### 以下驱动会自动按需下载安装,无需手动添加 398 | 399 | - Virtio ([Virtio][virtio-virtio], [阿里云][virtio-aliyun], [腾讯云][virtio-qcloud], [GCP][virtio-gcp]) 400 | - XEN ([~~XEN~~][xen-xen] (未签名), [Citrix][xen-citrix], [AWS][xen-aws]) 401 | - AWS ([ENA 网卡][aws-ena], [NVME 存储控制器][aws-nvme]) 402 | - GCP ([gVNIC 网卡][gcp-gvnic], [GGA 显卡][gcp-gga]) 403 | - Azure ([MANA 网卡][azure-mana]) 404 | - Intel ([VMD 存储控制器][intel-vmd], 网卡: [7][intel-nic-7], [8][intel-nic-8], [8.1][intel-nic-8.1], [10][intel-nic-10], [11][intel-nic-11], [2008 R2][intel-nic-2008-r2], [2012][intel-nic-2012], [2012 R2][intel-nic-2012-r2], [2016][intel-nic-2016], [2019][intel-nic-2019], [2022][intel-nic-2022], [2025][intel-nic-2025]) 405 | 406 | [virtio-virtio]: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/ 407 | [virtio-aliyun]: https://www.alibabacloud.com/help/ecs/user-guide/install-the-virtio-driver-1 408 | [virtio-qcloud]: https://cloud.tencent.com/document/product/213/17815#b84b2032-752c-43c4-a509-73530b8f82ff 409 | [virtio-gcp]: https://console.cloud.google.com/storage/browser/gce-windows-drivers-public 410 | [xen-xen]: https://xenproject.org/resources/downloads/ 411 | [xen-aws]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/xen-drivers-overview.html 412 | [xen-citrix]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Upgrading_PV_drivers.html#win2008-citrix-upgrade 413 | [aws-ena]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ena-driver-releases-windows.html 414 | [aws-nvme]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-driver-version-history.html 415 | [gcp-gvnic]: https://cloud.google.com/compute/docs/networking/using-gvnic 416 | [gcp-gga]: https://cloud.google.com/compute/docs/instances/enable-instance-virtual-display 417 | [azure-mana]: https://learn.microsoft.com/azure/virtual-network/accelerated-networking-mana-windows 418 | [intel-vmd]: https://www.intel.com/content/www/us/en/download/849936/intel-rapid-storage-technology-driver-installation-software-with-intel-optane-memory-12th-to-15th-gen-platforms.html 419 | [intel-nic-7]: https://www.intel.com/content/www/us/en/download/15590/intel-network-adapter-driver-for-windows-7-final-release.html 420 | [intel-nic-8]: https://www.intel.com/content/www/us/en/download/16765/intel-network-adapter-driver-for-windows-8-final-release.html 421 | [intel-nic-8.1]: https://www.intel.com/content/www/us/en/download/17479/intel-network-adapter-driver-for-windows-8-1.html 422 | [intel-nic-10]: https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driver-for-windows-10.html 423 | [intel-nic-11]: https://www.intel.com/content/www/us/en/download/727998/intel-network-adapter-driver-for-microsoft-windows-11.html 424 | [intel-nic-2008-r2]: https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html 425 | [intel-nic-2012]: https://www.intel.com/content/www/us/en/download/16789/intel-network-adapter-driver-for-windows-server-2012.html 426 | [intel-nic-2012-r2]: https://www.intel.com/content/www/us/en/download/17480/intel-network-adapter-driver-for-windows-server-2012-r2.html 427 | [intel-nic-2016]: https://www.intel.com/content/www/us/en/download/18737/intel-network-adapter-driver-for-windows-server-2016.html 428 | [intel-nic-2019]: https://www.intel.com/content/www/us/en/download/19372/intel-network-adapter-driver-for-windows-server-2019.html 429 | [intel-nic-2022]: https://www.intel.com/content/www/us/en/download/706171/intel-network-adapter-driver-for-windows-server-2022.html 430 | [intel-nic-2025]: https://www.intel.com/content/www/us/en/download/838943/intel-network-adapter-driver-for-windows-server-2025.html 431 | 432 | #### 如何填写映像名称 `--image-name` 433 | 434 | 通常一个 ISO 会包含多个系统版本,例如家庭版、专业版。映像名称 `--image-name` 就是用来指定要安装的版本,填写时不区分大小写 435 | 436 | 可以用 DISM、DISM++、Wimlib 等工具查询 ISO 包含的映像名称 437 | 438 | 常用的映像名称有: 439 | 440 | ```text 441 | Windows 7 Ultimate 442 | Windows 11 Pro 443 | Windows 11 Enterprise LTSC 2024 444 | Windows Server 2025 SERVERDATACENTER 445 | ``` 446 | 447 | #### 如何用 [DISM++](https://github.com/Chuyu-Team/Dism-Multi-language/releases) 查询 ISO 包含的映像名称 448 | 449 | 打开文件菜单 > 打开映像文件,选择要安装的 iso,即可得到映像名称,所有映像名称都可以安装 450 | 451 |  452 | 453 | > [!WARNING] 454 | > Vista (Server 2008) 和 32 位系统可能会缺少驱动 455 | 456 | > [!WARNING] 457 | > 未开启 CSM 的 EFI 机器,无法安装 Windows 7 (Server 2008 R2) 458 | > 459 | > Hyper-V (Azure) 需选择合适的虚拟机代系 <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v> 460 | 461 | > [!WARNING] 462 | > Windows 10 LTSC 2021 中文版镜像 `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso` 的 `wsappx` 进程会长期占用 CPU 463 | > 464 | > 解决方法是更新系统补丁,或者手动安装 `VCLibs` 库 <https://www.google.com/search?q=ltsc+wsappx> 465 | 466 | #### ARM 安装 Windows 的注意事项 467 | 468 | 大部分 ARM 机器都支持安装最新版 Windows 11 469 | 470 | 安装过程可能会黑屏,串行控制台可能会显示 `ConvertPages: failed to find range`,均不影响正常安装 471 | 472 | | 兼容性 | 云服务商 | 实例类型 | 问题 | 473 | | ------ | -------- | ------------- | ---------------------------------------------------------------------------- | 474 | | ✔️ | Azure | B2pts_v2 | | 475 | | ✔️ | 阿里云 | g6r, c6r | | 476 | | ✔️ | 阿里云 | g8y, c8y, r8y | 有几率重启时卡开机 Logo,强制重启即可 | 477 | | ✔️ | AWS | T4g | | 478 | | ✔️ | Scaleway | COPARM1 | | 479 | | ✔️ | Gcore | | | 480 | | ❔ | 甲骨文云 | A1.Flex | 不一定能安装成功,越新创建的实例越容易成功<br />安装后还需要手动加载显卡驱动 | 481 | | ❌ | 谷歌云 | t2a | 缺少网卡驱动 | 482 | 483 | <details> 484 | 485 | <summary>甲骨文云加载显卡驱动</summary> 486 | 487 | 使用远程桌面登录到服务器,打开设备管理器,找到显卡,选择更新驱动,在列表中选择 `Red Hat VirtIO GPU DOD controller` 即可。不需要提前下载驱动。 488 | 489 |  490 |  491 |  492 | 493 | </details> 494 | 495 | ## 讨论 496 | 497 | [](https://github.com/bin456789/reinstall/issues) 498 | [](https://t.me/reinstall_os) 499 | 500 | ## 如何修改脚本自用 501 | 502 | 1. Fork 本仓库 503 | 2. 修改 `reinstall.sh` 和 `reinstall.bat` 开头的 `confhome` 和 `confhome_cn` 504 | 3. 修改其它代码 505 | 506 | ## 感谢 507 | 508 | [](https://github.com/sponsors/bin456789) 509 | 510 | 感谢以下商家提供白嫖机器 511 | 512 | [](https://www.oracle.com/cloud/) 513 | [](https://dartnode.com/) 514 | -------------------------------------------------------------------------------- /cloud-init-fix-onlink.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 修复 cloud-init 没有正确渲染 onlink 网关 3 | 4 | set -eE 5 | os_dir=$1 6 | 7 | # 该脚本也会在 alpine live 下调用 8 | # 防止在 alpine live 下运行 systemctl netplan 报错 9 | systemctl() { 10 | if systemd-detect-virt --chroot; then 11 | return 12 | fi 13 | command systemctl "$@" 14 | } 15 | 16 | netplan() { 17 | if systemd-detect-virt --chroot; then 18 | return 19 | fi 20 | command netplan "$@" 21 | } 22 | 23 | insert_into_file() { 24 | file=$1 25 | location=$2 26 | regex_to_find=$3 27 | 28 | if [ "$location" = head ]; then 29 | bak=$(mktemp) 30 | cp "$file" "$bak" 31 | cat - "$bak" >"$file" 32 | else 33 | line_num=$(grep -E -n "$regex_to_find" "$file" | cut -d: -f1) 34 | 35 | found_count=$(echo "$line_num" | wc -l) 36 | if [ ! "$found_count" -eq 1 ]; then 37 | return 1 38 | fi 39 | 40 | case "$location" in 41 | before) line_num=$((line_num - 1)) ;; 42 | after) ;; 43 | *) return 1 ;; 44 | esac 45 | 46 | sed -i "${line_num}r /dev/stdin" "$file" 47 | fi 48 | } 49 | 50 | fix_netplan_conf() { 51 | # 修改前 52 | # gateway4: 1.1.1.1 53 | # gateway6: ::1 54 | 55 | # 修改后 56 | # routes: 57 | # - to: 0.0.0.0/0 58 | # via: 1.1.1.1 59 | # on-link: true 60 | # routes: 61 | # - to: ::/0 62 | # via: ::1 63 | # on-link: true 64 | conf=$os_dir/etc/netplan/50-cloud-init.yaml 65 | if ! [ -f "$conf" ]; then 66 | return 67 | fi 68 | 69 | # 判断 bug 是否已经修复 70 | if grep -q 'on-link:' "$conf"; then 71 | return 72 | fi 73 | 74 | # 获取网关 75 | gateways=$(grep 'gateway[4|6]:' "$conf" | awk '{print $2}') 76 | if [ -z "$gateways" ]; then 77 | return 78 | fi 79 | 80 | # 获取缩进 81 | spaces=$(grep 'gateway[4|6]:' "$conf" | head -1 | grep -o '^[[:space:]]*') 82 | 83 | { 84 | # 网关头部 85 | cat <<EOF 86 | ${spaces}routes: 87 | EOF 88 | # 网关条目 89 | for gateway in $gateways; do 90 | # debian 11 的 netplan 不支持 to: default 91 | case $gateway in 92 | *.*) to='0.0.0.0/0' ;; 93 | *:*) to='::/0' ;; 94 | esac 95 | 96 | cat <<EOF 97 | ${spaces} - to: $to 98 | ${spaces} via: $gateway 99 | ${spaces} on-link: true 100 | EOF 101 | done 102 | } | insert_into_file "$conf" before 'match:' 103 | 104 | # 删除原来的条目 105 | sed -i '/gateway[4|6]:/d' "$conf" 106 | 107 | # 重新应用配置 108 | if command -v netplan && { 109 | systemctl -q is-enabled systemd-networkd || systemctl -q is-enabled NetworkManager 110 | }; then 111 | netplan apply 112 | fi 113 | } 114 | 115 | fix_networkd_conf() { 116 | # 修改前 gentoo 117 | # [Route] 118 | # Gateway=1.1.1.1 119 | # Gateway=2602::1 120 | 121 | # 修改前 arch 122 | # [Route] 123 | # Gateway=1.1.1.1 124 | # 125 | # [Route] 126 | # Gateway=2602::1 127 | 128 | # 修改后 129 | # [Route] 130 | # Gateway=1.1.1.1 131 | # GatewayOnLink=yes 132 | # 133 | # [Route] 134 | # Gateway=2602::1 135 | # GatewayOnLink=yes 136 | 137 | if ! confs=$(ls "$os_dir"/etc/systemd/network/10-cloud-init-*.network 2>/dev/null); then 138 | return 139 | fi 140 | 141 | for conf in $confs; do 142 | # 判断 bug 是否已经修复 143 | if grep -q '^GatewayOnLink=' "$conf"; then 144 | return 145 | fi 146 | 147 | # 获取网关 148 | gateways=$(grep '^Gateway=' "$conf" | cut -d= -f2) 149 | if [ -z "$gateways" ]; then 150 | return 151 | fi 152 | 153 | # 删除原来的条目 154 | sed -i '/^\[Route\]/d; /^Gateway=/d; /^GatewayOnLink=/d' "$conf" 155 | 156 | # 创建新条目 157 | for gateway in $gateways; do 158 | echo " 159 | [Route] 160 | Gateway=$gateway 161 | GatewayOnLink=yes 162 | " 163 | done >>"$conf" 164 | done 165 | 166 | # 重新应用配置 167 | # networkctl reload 不起作用 168 | if systemctl -q is-enabled systemd-networkd; then 169 | systemctl restart systemd-networkd 170 | fi 171 | } 172 | 173 | fix_wicked_conf() { 174 | # https://github.com/openSUSE/wicked/wiki/FAQ#q-why-wicked-does-not-set-my-default-static-route 175 | 176 | # 修改前 177 | # default 1.1.1.1 - - 178 | # default 2602::1 - - 179 | 180 | # 修改后 181 | # 1.1.1.1 - - 182 | # 2602::1 - - 183 | # default 1.1.1.1 - - 184 | # default 2602::1 - - 185 | 186 | if ! confs=$(ls "$os_dir/etc/sysconfig/network/ifroute-"* 2>/dev/null); then 187 | return 188 | fi 189 | 190 | for conf in $confs; do 191 | # 判断 bug 是否已经修复 192 | if grep -v 'default' "$conf" | grep -q '-'; then 193 | return 194 | fi 195 | 196 | # 获取网关 197 | gateways=$(awk '$1=="default" {print $2}' "$conf") 198 | if [ -z "$gateways" ]; then 199 | return 200 | fi 201 | 202 | # 创建新条目 203 | for gateway in $gateways; do 204 | echo "$gateway - -" 205 | done | insert_into_file "$conf" head 206 | done 207 | 208 | # 重新应用配置 209 | if systemctl -q is-enabled wicked; then 210 | systemctl restart wicked 211 | fi 212 | } 213 | 214 | # ubuntu 18.04 cloud-init 版本 23.1.2,因此不用处理 215 | 216 | # debian 10/11 云镜像原本用 ifupdown + resolvconf,脚本改成用 netplan + networkd/resolved 217 | # debian 12 云镜像: netplan + networkd/resolved 218 | # 23.1.1 修复 219 | fix_netplan_conf 220 | 221 | # arch: networkd/resolved 222 | # gentoo: networkd/resolved 223 | # 24.2 修复 224 | # 只需对云镜像处理 225 | # 因为普通安装用的是 alpine 的 cloud-init,版本够新,不用处理 226 | fix_networkd_conf 227 | 228 | # opensuse 15.5: ifcfg + netconfig (dns) + wicked 229 | fix_wicked_conf 230 | -------------------------------------------------------------------------------- /cloud-init.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | datasource_list: [None] 3 | timezone: Asia/Shanghai 4 | disable_root: false 5 | ssh_pwauth: true 6 | users: 7 | - name: root 8 | lock_passwd: false 9 | chpasswd: 10 | expire: false 11 | # <= cloud-init 22.2.x 需要 12 | list: | 13 | root:@PASSWORD@ 14 | users: 15 | - name: root 16 | password: "@PASSWORD@" 17 | type: hash 18 | runcmd: 19 | # opensuse tumbleweed 镜像有 /etc/ssh/sshd_config.d/ 文件夹,没有 /etc/ssh/sshd_config,有/usr/etc/ssh/sshd_config 20 | # opensuse tumbleweed cloud-init 直接创建并写入 /etc/ssh/sshd_config,造成默认配置丢失 21 | # 下面这行删除 clout-init 创建的 sshd_config 22 | - test $(wc -l </etc/ssh/sshd_config) -le 1 && cat /etc/ssh/sshd_config >>/etc/ssh/sshd_config.d/50-cloud-init.conf && rm -f /etc/ssh/sshd_config 23 | - echo "PermitRootLogin yes" >/etc/ssh/sshd_config.d/01-permitrootlogin.conf 2>/dev/null || sed -Ei 's/^#?PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config 24 | - echo "Port @SSH_PORT@" >/etc/ssh/sshd_config.d/01-change-ssh-port.conf || sed -Ei 's/^#?Port .*/Port @SSH_PORT@/' /etc/ssh/sshd_config 25 | # 已创建的 ssh 连接会沿用旧的配置(未开启密码登录),这时即使输入正确的密码,也会提示 Access Denied 26 | # systemctl restart sshd 只会重启监听进程,不会关闭已创建的连接(子进程) 27 | - pkill sshd || true 28 | # daemon-reload 会刷新 /run/systemd/generator/ssh.socket.d/addresses.conf 29 | - systemctl daemon-reload 30 | - for s in ssh.socket ssh.service sshd.socket sshd.service; do systemctl is-enabled $s 2>/dev/null && systemctl restart $s && break; done 31 | # 删除有密码的行 32 | - sed -i -e '/^[[:space:]]*password:/d' -e '/[[:space:]]*root:/d' /etc/cloud/cloud.cfg.d/99_fallback.cfg 33 | - touch /etc/cloud/cloud-init.disabled 34 | # ubuntu 镜像运行 echo -e '\nDone' ,-e 会被显示出来 35 | # 加 true 因为有的 tty 不可写 36 | - for tty in tty0 ttyS0 ttyAMA0; do [ -c /dev/$tty ] && printf '\n%s\n' 'reinstall done' >/dev/$tty || true; done 37 | -------------------------------------------------------------------------------- /debian.cfg: -------------------------------------------------------------------------------- 1 | #_preseed_V1 2 | # shellcheck disable=SC1091,SC2148 3 | # https://www.debian.org/releases/stable/amd64/apbs04.zh-cn.html 4 | # https://www.debian.org/releases/stable/example-preseed.txt 5 | # https://preseed.debian.net/debian-preseed/bookworm/amd64-main-full.txt 6 | # 需要留意 kali initrd 自带的 /preseed.cfg 7 | 8 | # 下面这行语句无效,因为本行后面有反斜杠,前面有空格(安装器认为不算注释)\ 9 | d-i debian-installer/locale string en_US 10 | 11 | # B.4.1. 本地化 12 | d-i debian-installer/locale string en_US 13 | d-i keyboard-configuration/xkb-keymap select us 14 | 15 | # B.4.2. 网络设置 16 | d-i netcfg/get_hostname string unassigned-hostname 17 | d-i netcfg/get_domain string unassigned-domain 18 | d-i netcfg/hostname string localhost 19 | 20 | # B.4.3. 网络控制台 21 | 22 | # B.4.4. 镜像设置 23 | d-i mirror/country string manual 24 | # d-i mirror/http/hostname string deb.debian.org 25 | 26 | # B.4.5. 帐号设置 27 | d-i passwd/make-user boolean false 28 | # 单纯为了跳过设置,实际上是在 partman/early_command 里设置密码,preseed/early_command 无法设置密码 29 | # 注意如果用 ssh key 后面还要删除密码 30 | d-i passwd/root-password password '' 31 | d-i passwd/root-password-again password '' 32 | # kali 需要下面这行,否则会提示输入用户名 33 | d-i passwd/root-login boolean true 34 | 35 | # B.4.6. 时钟与时区设置 36 | d-i time/zone string Asia/Shanghai 37 | 38 | # B.4.7. 分区 39 | d-i partman-auto/method string regular 40 | d-i partman-lvm/device_remove_lvm boolean true 41 | d-i partman-md/device_remove_md boolean true 42 | d-i partman-partitioning/confirm_write_new_label boolean true 43 | d-i partman/choose_partition select finish 44 | d-i partman/confirm boolean true 45 | d-i partman/confirm_nooverwrite boolean true 46 | 47 | # vm 原有系统是 bios + gpt,切换成 efi,用 iso 重装,需要确认此项 48 | # 用脚本重装的话,强制安装在第二个硬盘上也可能会遇到? 49 | d-i partman-efi/non_efi_system boolean true 50 | 51 | ### Description: Do you want to return to the partitioning menu? 52 | # You have not selected any partitions for use as swap space. Enabling swap 53 | # space is recommended so that the system can make better use of the 54 | # available physical memory, and so that it behaves better when physical 55 | # memory is scarce. You may experience installation problems if you do not 56 | # have enough physical memory. 57 | # . 58 | # If you do not go back to the partitioning menu and assign a swap partition, 59 | # the installation will continue without swap space. 60 | # 坑的一比 61 | # 不是确认是否 no_swap 62 | # 而是 recipe no_swap 时,确认是否返回上一级重新分区 63 | # 选择 true 就一直死循环 64 | d-i partman-basicfilesystems/no_swap boolean false 65 | 66 | # 最小值 膨胀权重 最大值 67 | # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes/atomic?ref_type=heads 68 | # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes-amd64-efi/atomic?ref_type=heads 69 | # shellcheck disable=SC1083,SC2086,SC2154 70 | d-i partman-auto/expert_recipe_efi string efi :: \ 71 | 106 1 106 free \ 72 | $iflabel{ gpt } method{ efi } format{ } . \ 73 | 1 1 -1 $default_filesystem \ 74 | method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } . 75 | 76 | # shellcheck disable=SC1083,SC2086,SC2154 77 | d-i partman-auto/expert_recipe_bios string bios :: \ 78 | 1 1 1 free \ 79 | $iflabel{ gpt } method{ biosgrub } . \ 80 | 1 1 -1 $default_filesystem \ 81 | method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } . 82 | 83 | # B.4.8. 基本系统安装 84 | 85 | # B.4.9. 设置 apt 86 | d-i apt-setup/non-free boolean true 87 | d-i apt-setup/non-free-firmware boolean true 88 | d-i apt-setup/contrib boolean true 89 | d-i apt-setup/enable-source-repositories boolean false 90 | # kali 不要设置 91 | # d-i apt-setup/security_host string security.debian.org 92 | 93 | # B.4.10. 选择软件包 94 | tasksel tasksel/first multiselect ssh-server 95 | d-i pkgsel/upgrade select none 96 | 97 | # B.4.11. 安装 bootloader 98 | # 添加 bootx64.efi 99 | d-i grub-installer/force-efi-extra-removable boolean true 100 | 101 | # B.4.12. 完成安装 102 | d-i finish-install/reboot_in_progress note 103 | 104 | # B.4.13. 预置其他的软件包 105 | 106 | # 其他设置 107 | # d-i anna/standard_modules boolean false 108 | # d-i anna/choose_modules string network-console 109 | # d-i network-console/password password 123@@@ 110 | # d-i network-console/password-again password 123@@@ 111 | 112 | # B.5.1. 安装过程中运行用户命令 113 | # 注意所有命令都会合并成一行命令 114 | 115 | # 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误 116 | 117 | # 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles 118 | # 不然安装时 control 脚本会报错: 119 | # Loading simple-cdd-profiles failed for unknown reasons 120 | d-i preseed/early_command string true; \ 121 | if [ -d /cdrom/simple-cdd ]; then anna-install simple-cdd-profiles; fi 122 | 123 | # debian 11 initrd 没有 xargs awk 124 | # debian 12 initrd 没有 xargs 125 | # efi 分区大小未改变时,不会被格式化,因此需要手动删除旧系统的 efi 文件 126 | # os-prober 卡太久,因此跳过 127 | d-i partman/early_command string true; \ 128 | eval "$(grep -o 'extra_confhome=[^ ]*' /proc/cmdline | sed 's/^extra_//')"; \ 129 | 130 | postinst=/var/lib/dpkg/info/bootstrap-base.postinst; \ 131 | cp $postinst $postinst.orig; \ 132 | true >$postinst; \ 133 | 134 | swapfile=/target/swapfile; \ 135 | mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$y"; }); \ 136 | mem=$((mem / 1024)); \ 137 | swap_size=$((512 - mem)); \ 138 | [ $swap_size -gt 0 ] && echo "fallocate -l ${swap_size}M $swapfile; mkswap $swapfile; swapon $swapfile" >>$postinst; \ 139 | 140 | echo "swapoff -a; rm -f $swapfile" >/usr/lib/finish-install.d/95swapoff; \ 141 | chmod a+x /usr/lib/finish-install.d/95swapoff; \ 142 | 143 | echo "rm -rf /target/boot/efi/*; $postinst.orig" >>$postinst; \ 144 | 145 | xda=$(sh /get-xda.sh); \ 146 | debconf-set partman-auto/disk "/dev/$xda"; \ 147 | debconf-set grub-installer/bootdev "/dev/$xda"; \ 148 | rm -rf /usr/sbin/fdisk /usr/sbin/sfdisk; \ 149 | 150 | ttys=$(sh /ttys.sh console=); \ 151 | debconf-set debian-installer/add-kernel-opts "$ttys"; \ 152 | 153 | eths=$(cd /dev/netconf/ && ls); \ 154 | 155 | sh /can_use_cloud_kernel.sh "$xda" $eths || debconf-set base-installer/kernel/image "$(debconf-get base-installer/kernel/image | sed 's/-cloud//')"; \ 156 | 157 | [ -d /sys/firmware/efi ] && debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \ 158 | [ -d /sys/firmware/efi ] || debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \ 159 | 160 | debconf-set passwd/root-password-crypted "$(cat /configs/password-linux-sha512)"; \ 161 | 162 | true >/bin/os-prober 163 | 164 | # kali ssh 默认关闭 165 | # 另一种方法处理 cloudcone 166 | # if [ "$link_grub_dir" = 1 ]; then mkdir /target/boot/grub2; echo 'chainloader (hd0)+1' >/target/boot/grub2/grub.cfg; fi; \ 167 | # debian 9 tar 不支持 --strip-components 168 | d-i preseed/late_command string true; \ 169 | for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \ 170 | 171 | if [ "$elts" = 1 ]; then sed -i "s|deb\.freexian\.com/extended-lts|$deb_mirror|" /target/etc/apt/sources.list; fi; \ 172 | 173 | if [ "$link_grub_dir" = 1 ]; then ln -s grub /target/boot/grub2; fi; \ 174 | 175 | in-target systemctl enable ssh; \ 176 | 177 | if [ -s /configs/ssh_keys ]; then \ 178 | (umask 077; mkdir -p /target/root/.ssh; cat /configs/ssh_keys >/target/root/.ssh/authorized_keys); \ 179 | in-target passwd -d root; \ 180 | else \ 181 | echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf || \ 182 | echo "PermitRootLogin yes" >>/target/etc/ssh/sshd_config; \ 183 | fi; \ 184 | 185 | if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \ 186 | echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-change-ssh-port.conf || \ 187 | echo "Port $ssh_port" >>/target/etc/ssh/sshd_config; \ 188 | fi; \ 189 | 190 | if [ -s /configs/frpc.toml ]; then \ 191 | url=$(sh /get-frpc-url.sh linux); \ 192 | basename=$(echo "$url" | sed 's,.*/,,' | sed 's,\.tar\.gz,,'); \ 193 | mkdir -p /target/usr/local/bin; \ 194 | mkdir -p /target/usr/local/etc/frpc; \ 195 | for i in {1..5}; do \ 196 | wget -O /target/frpc.tar.gz "$url" && break; \ 197 | done; \ 198 | tar xzf /target/frpc.tar.gz "$basename/frpc" -O >/target/usr/local/bin/frpc; \ 199 | rm -f /target/frpc.tar.gzx; \ 200 | chmod a+x /target/usr/local/bin/frpc; \ 201 | cp /configs/frpc.toml /target/usr/local/etc/frpc/; \ 202 | cp /frpc.service /target/etc/systemd/system/; \ 203 | in-target systemctl enable frpc; \ 204 | fi; \ 205 | 206 | cp /fix-eth-name.sh /target/; \ 207 | cp /fix-eth-name.service /target/etc/systemd/system/; \ 208 | in-target systemctl enable fix-eth-name 209 | -------------------------------------------------------------------------------- /fix-eth-name.initd: -------------------------------------------------------------------------------- 1 | #!/sbin/openrc-run 2 | 3 | Description="Fix Eth Name" 4 | 5 | # https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/openrc/networking.initd 6 | # https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/dhcpcd/dhcpcd.initd 7 | depend() { 8 | need localmount 9 | want dev-settle 10 | 11 | after bootmisc hwdrivers modules 12 | before net networking dhcpcd 13 | } 14 | 15 | start() { 16 | ebegin "Fix Eth Name" 17 | ash /fix-eth-name.sh 18 | eend $? 19 | } 20 | 21 | start_post() { 22 | rc-service fix-eth-name zap 23 | rc-update del fix-eth-name boot 24 | rm -f /etc/init.d/fix-eth-name 25 | rm -f /fix-eth-name.sh 26 | } 27 | -------------------------------------------------------------------------------- /fix-eth-name.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Fix Eth Name 3 | ConditionPathExists=/fix-eth-name.sh 4 | 5 | After=dbus.service 6 | 7 | Before=cloud-init-local.service 8 | Before=network.service 9 | Before=networking.service 10 | Before=systemd-networkd.service 11 | Before=NetworkManager.service 12 | Before=wickedd-auto4.service 13 | Before=wickedd-dhcp4.service 14 | Before=wickedd-dhcp6.service 15 | Before=wickedd.service 16 | 17 | Before=network.target 18 | 19 | [Service] 20 | Type=oneshot 21 | ExecStart=/usr/bin/env bash /fix-eth-name.sh 22 | ExecStart=/usr/bin/env rm -f /fix-eth-name.sh 23 | ExecStart=/usr/bin/env rm -f /etc/systemd/system/fix-eth-name.service 24 | ExecStart=/usr/bin/env rm -f /etc/systemd/system/multi-user.target.wants/fix-eth-name.service 25 | ExecStart=/usr/bin/env rm -f /lib/systemd/system-preset/01-fix-eth-name.preset 26 | ExecStart=/usr/bin/env rm -f /usr/lib/systemd/system-preset/01-fix-eth-name.preset 27 | 28 | [Install] 29 | WantedBy=multi-user.target 30 | -------------------------------------------------------------------------------- /fix-eth-name.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck shell=dash 3 | # shellcheck disable=SC3001,SC3010 4 | # alpine 使用 busybox ash 5 | 6 | set -eE 7 | 8 | # openeuler 需等待 udev 将网卡名从 eth0 改为 enp3s0 9 | sleep 10 10 | # 不知道有没有用 11 | if command -v udevadm >/dev/null; then 12 | # udevadm trigger 13 | udevadm settle 14 | elif command -v mdev >/dev/null; then 15 | mdev -sf 16 | fi 17 | 18 | # 本脚本在首次进入新系统后运行 19 | # 将 trans 阶段生成的网络配置中的网卡名(eth0) 改为正确的网卡名,也适用于以下情况 20 | # 1. alpine 要运行此脚本,因为安装后的内核可能有 netboot 没有的驱动 21 | # 2. dmit debian 普通内核(安装时)和云内核网卡名不一致 22 | # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928923 23 | 24 | # todo: 删除 cloud-init 25 | 26 | to_lower() { 27 | tr '[:upper:]' '[:lower:]' 28 | } 29 | 30 | retry() { 31 | local max_try=$1 32 | shift 33 | 34 | for i in $(seq "$max_try"); do 35 | if "$@"; then 36 | return 37 | else 38 | ret=$? 39 | if [ "$i" -ge "$max_try" ]; then 40 | return $ret 41 | fi 42 | sleep 1 43 | fi 44 | done 45 | } 46 | 47 | # openeuler 本脚本运行一秒后才有 enp3s0 48 | # 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后 49 | # 因此需要等待网卡出现 50 | get_ethx_by_mac() { 51 | mac=$(echo "$1" | to_lower) 52 | retry 10 _get_ethx_by_mac "$mac" 53 | } 54 | 55 | _get_ethx_by_mac() { 56 | if true; then 57 | # 过滤 azure vf (带 master ethx) 58 | ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep . 59 | return 60 | else 61 | for i in $(cd /sys/class/net && echo *); do 62 | if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then 63 | echo "$i" 64 | return 65 | fi 66 | done 67 | return 1 68 | fi 69 | } 70 | 71 | fix_rh_sysconfig() { 72 | for file in /etc/sysconfig/network-scripts/ifcfg-eth*; do 73 | # 没有 ifcfg-eth* 也会执行一次,因此要判断文件是否存在 74 | [ -f "$file" ] || continue 75 | mac=$(grep ^HWADDR= "$file" | cut -d= -f2 | grep .) || continue 76 | ethx=$(get_ethx_by_mac "$mac") || continue 77 | 78 | proper_file=/etc/sysconfig/network-scripts/ifcfg-$ethx 79 | if [ "$file" != "$proper_file" ]; then 80 | # 更改文件内容 81 | sed -i "s/^DEVICE=.*/DEVICE=$ethx/" "$file" 82 | 83 | # 不要直接更改文件名,因为可能覆盖已有文件 84 | mv "$file" "$proper_file.tmp" 85 | fi 86 | done 87 | 88 | # 更改文件名 89 | for tmp_file in /etc/sysconfig/network-scripts/ifcfg-e*.tmp; do 90 | if [ -f "$tmp_file" ]; then 91 | mv "$tmp_file" "${tmp_file%.tmp}" 92 | fi 93 | done 94 | } 95 | 96 | fix_suse_sysconfig() { 97 | for file in /etc/sysconfig/network/ifcfg-eth*; do 98 | [ -f "$file" ] || continue 99 | 100 | # 可能两边有引号 101 | mac=$(grep ^LLADDR= "$file" | cut -d= -f2 | sed "s/'//g" | grep .) || continue 102 | ethx=$(get_ethx_by_mac "$mac") || continue 103 | 104 | old_ethx=${file##*-} 105 | if ! [ "$old_ethx" = "$ethx" ]; then 106 | # 不要直接更改文件名,因为可能覆盖已有文件 107 | for type in ifcfg ifroute; do 108 | old_file=/etc/sysconfig/network/$type-$old_ethx 109 | new_file=/etc/sysconfig/network/$type-$ethx.tmp 110 | # 防止没有 ifroute-eth* 导致中断脚本 111 | if [ -f "$old_file" ]; then 112 | mv "$old_file" "$new_file" 113 | fi 114 | done 115 | fi 116 | done 117 | 118 | # 上面的循环结束后,再将 tmp 改成正式文件 119 | for tmp_file in \ 120 | /etc/sysconfig/network/ifcfg-e*.tmp \ 121 | /etc/sysconfig/network/ifroute-e*.tmp; do 122 | if [ -f "$tmp_file" ]; then 123 | mv "$tmp_file" "${tmp_file%.tmp}" 124 | fi 125 | done 126 | } 127 | 128 | fix_network_manager() { 129 | for file in /etc/NetworkManager/system-connections/cloud-init-eth*.nmconnection; do 130 | [ -f "$file" ] || continue 131 | mac=$(grep ^mac-address= "$file" | cut -d= -f2 | grep .) || continue 132 | ethx=$(get_ethx_by_mac "$mac") || continue 133 | 134 | proper_file=/etc/NetworkManager/system-connections/$ethx.nmconnection 135 | 136 | # 更改文件内容 137 | sed -i "s/^id=.*/id=$ethx/" "$file" 138 | 139 | # 更改文件名 140 | mv "$file" "$proper_file" 141 | done 142 | } 143 | 144 | # debian 9 IPV6 onlink 路由需要 post-up 145 | 146 | # auto lo 147 | # iface lo inet loopback 148 | 149 | # # mac 11:22:33:44:55:66 # 用此行匹配网卡 150 | # auto eth0 151 | # iface eth0 inet static 152 | # address 1.1.1.1/25 153 | # gateway 1.1.1.1 154 | # dns-nameservers 1.1.1.1 155 | # dns-nameservers 8.8.8.8 156 | # iface eth0 inet6 static 157 | # address 2602:1:0:80::100/64 158 | # gateway 2602:1:0:80::1 159 | # post-up ip route add 2602:1:0:80::1 dev eth0 160 | # post-up ip route add default via 2602:1:0:80::1 dev eth0 161 | # dns-nameserver 2606:4700:4700::1111 162 | # dns-nameserver 2001:4860:4860::8888 163 | 164 | fix_ifupdown() { 165 | file=/etc/network/interfaces 166 | tmp_file=$file.tmp 167 | 168 | rm -f "$tmp_file" 169 | 170 | if [ -f "$file" ]; then 171 | while IFS= read -r line; do 172 | del_this_line=false 173 | if [[ "$line" = "# mac "* ]]; then 174 | ethx= 175 | if mac=$(echo "$line" | awk '{print $NF}'); then 176 | ethx=$(get_ethx_by_mac "$mac") || true 177 | fi 178 | del_this_line=true 179 | elif [[ "$line" = "iface e"* ]] || 180 | [[ "$line" = "auto e"* ]] || 181 | [[ "$line" = "allow-hotplug e"* ]]; then 182 | if [ -n "$ethx" ]; then 183 | line=$(echo "$line" | awk "{\$2=\"$ethx\"; print \$0}") 184 | fi 185 | elif [[ "$line" = *" dev e"* ]]; then 186 | if [ -n "$ethx" ]; then 187 | # awk 会去除前面的空格 188 | line=$(echo "$line" | sed -E "s/[^ ]*$/$ethx/") 189 | fi 190 | fi 191 | if ! $del_this_line; then 192 | echo "$line" >>"$tmp_file" 193 | fi 194 | done <"$file" 195 | 196 | mv "$tmp_file" "$file" 197 | fi 198 | } 199 | 200 | fix_netplan() { 201 | file=/etc/netplan/50-cloud-init.yaml 202 | tmp_file=$file.tmp 203 | 204 | rm -f "$tmp_file" 205 | 206 | if [ -f "$file" ]; then 207 | while IFS= read -r line; do 208 | if echo "$line" | grep -Eq '^[[:space:]]+macaddress:'; then 209 | # 得到正确的网卡名 210 | mac=$(echo "$line" | awk '{print $NF}' | sed 's/"//g') 211 | ethx=$(get_ethx_by_mac "$mac") || true 212 | elif echo "$line" | grep -Eq '^[[:space:]]+eth[0-9]+:'; then 213 | # 改成正确的网卡名 214 | if [ -n "$ethx" ]; then 215 | line=$(echo "$line" | sed -E "s/[^[:space:]]+/$ethx:/") 216 | fi 217 | fi 218 | echo "$line" >>"$tmp_file" 219 | 220 | # 删除 set-name 不过这一步在 trans 已完成 221 | # 因为 netplan-generator 会在 systemd generator 阶段就根据 netplan 配置重命名网卡 222 | # systemd generator 阶段比本脚本和 systemd-networkd 更早运行 223 | 224 | # 倒序 225 | done < <(grep -Ev "^[[:space:]]+set-name:" "$file" | tac) 226 | 227 | # 再倒序回来 228 | tac "$tmp_file" >"$file" 229 | rm -f "$tmp_file" 230 | 231 | # 通过 systemd netplan generator 生成 /run/systemd/network/10-netplan-enp3s0.network 232 | systemctl daemon-reload 233 | fi 234 | } 235 | 236 | fix_systemd_networkd() { 237 | for file in /etc/systemd/network/10-cloud-init-eth*.network; do 238 | [ -f "$file" ] || continue 239 | mac=$(grep ^MACAddress= "$file" | cut -d= -f2 | grep .) || continue 240 | ethx=$(get_ethx_by_mac "$mac") || continue 241 | 242 | proper_file=/etc/systemd/network/10-$ethx.network 243 | 244 | # 更改文件内容 245 | sed -Ei "s/^Name=eth[0-9]+/Name=$ethx/" "$file" 246 | 247 | # 更改文件名 248 | mv "$file" "$proper_file" 249 | done 250 | } 251 | 252 | fix_rh_sysconfig 253 | fix_suse_sysconfig 254 | fix_network_manager 255 | fix_ifupdown 256 | fix_netplan 257 | fix_systemd_networkd 258 | -------------------------------------------------------------------------------- /frpc-example.toml: -------------------------------------------------------------------------------- 1 | serverAddr = "YOUR_FRP_SERVER_IP" 2 | serverPort = 7000 3 | auth.token = "YOUR_FRP_TOKEN" 4 | 5 | [[proxies]] 6 | name = "ssh" 7 | type = "tcp" 8 | localIP = "127.0.0.1" 9 | localPort = 22 10 | remotePort = 2222 11 | 12 | [[proxies]] 13 | name = "rdp_tcp" 14 | type = "tcp" 15 | localIP = "127.0.0.1" 16 | localPort = 3389 17 | remotePort = 33890 18 | 19 | [[proxies]] 20 | name = "rdp_udp" 21 | type = "udp" 22 | localIP = "127.0.0.1" 23 | localPort = 3389 24 | remotePort = 33890 25 | -------------------------------------------------------------------------------- /frpc.service: -------------------------------------------------------------------------------- 1 | # https://github.com/archlinuxcn/repo/blob/master/archlinuxcn/frp/frpc.service 2 | 3 | [Unit] 4 | Description=Frp Client Service 5 | After=network-online.target 6 | Wants=network-online.target 7 | 8 | [Service] 9 | Type=simple 10 | User=nobody 11 | Restart=on-failure 12 | RestartSec=5s 13 | ExecStart=/usr/local/bin/frpc -c /usr/local/etc/frpc/frpc.toml 14 | ExecReload=/usr/local/bin/frpc reload -c /usr/local/etc/frpc/frpc.toml 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /get-frpc-url.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | # shellcheck shell=dash 3 | # trans.sh/debian.cfg 共用此脚本 4 | 5 | # debian 9 不支持 set -E 6 | set -e 7 | 8 | is_in_china() { 9 | grep -q 1 /dev/netconf/*/is_in_china 10 | } 11 | 12 | is_ipv6_only() { 13 | ! grep -q 1 /dev/netconf/eth*/ipv4_has_internet 14 | } 15 | 16 | get_frpc_url() { 17 | # 传入 windows 或者 linux 18 | local os_type=$1 19 | local nt_ver=$2 20 | 21 | is_need_old_version() { 22 | [ "$nt_ver" = "6.0" ] || [ "$nt_ver" = "6.1" ] 23 | } 24 | 25 | version=$( 26 | if is_need_old_version; then 27 | echo 0.54.0 28 | else 29 | # debian 11 initrd 没有 xargs awk 30 | # debian 12 initrd 没有 xargs 31 | # github 不支持 ipv6 32 | if is_in_china || is_ipv6_only; then 33 | wget -O- https://mirrors.nju.edu.cn/github-release/fatedier/frp/LatestRelease/frp_sha256_checksums.txt | 34 | grep -m1 frp_ | cut -d_ -f2 35 | else 36 | # https://api.github.com/repos/fatedier/frp/releases/latest 有请求次数限制 37 | 38 | # root@localhost:~# wget --spider -S https://github.com/fatedier/frp/releases/latest 2>&1 | grep Location: 39 | # Location: https://github.com/fatedier/frp/releases/tag/v0.62.0 40 | # Location: https://github.com/fatedier/frp/releases/tag/v0.62.0 [following] # 原版 wget 多了这行 41 | 42 | wget --spider -S https://github.com/fatedier/frp/releases/latest 2>&1 | 43 | grep -m1 '^ Location:' | sed 's,.*/tag/v,,' 44 | fi 45 | fi 46 | ) 47 | 48 | if [ -z "$version" ]; then 49 | echo 'cannot find version' 50 | return 1 51 | fi 52 | 53 | suffix=$( 54 | case "$os_type" in 55 | linux) echo tar.gz ;; 56 | windows) echo zip ;; 57 | esac 58 | ) 59 | 60 | mirror=$( 61 | # nju 没有 win7 用的旧版 62 | # github 不支持 ipv6 63 | # jsdelivr 不支持 github releases 文件 64 | if is_ipv6_only; then 65 | if is_need_old_version; then 66 | echo 'NOT_SUPPORT' 67 | return 1 68 | else 69 | echo https://mirrors.nju.edu.cn/github-release/fatedier/frp 70 | fi 71 | else 72 | if is_in_china; then 73 | if is_need_old_version; then 74 | echo https://github.com/fatedier/frp/releases/download 75 | else 76 | echo https://mirrors.nju.edu.cn/github-release/fatedier/frp 77 | fi 78 | else 79 | echo https://github.com/fatedier/frp/releases/download 80 | fi 81 | fi 82 | ) 83 | 84 | arch=$( 85 | case "$(uname -m)" in 86 | x86_64) echo amd64 ;; 87 | aarch64) echo arm64 ;; 88 | esac 89 | ) 90 | 91 | filename=frp_${version}_${os_type}_${arch}.$suffix 92 | 93 | echo "${mirror}/v${version}/${filename}" 94 | } 95 | 96 | get_frpc_url "$@" 97 | -------------------------------------------------------------------------------- /get-xda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # debian ubuntu redhat 安装模式共用此脚本 3 | # alpine 未用到此脚本 4 | 5 | get_all_disks() { 6 | # shellcheck disable=SC2010 7 | ls /sys/block/ | grep -Ev '^(loop|sr|nbd)' 8 | } 9 | 10 | get_xda() { 11 | # 如果没找到 main_disk 或 xda 12 | # 返回假的值,防止意外地格式化全部盘 13 | eval "$(grep -o 'extra_main_disk=[^ ]*' /proc/cmdline | sed 's/^extra_//')" 14 | 15 | if [ -z "$main_disk" ]; then 16 | echo 'MAIN_DISK_NOT_FOUND' 17 | return 1 18 | fi 19 | 20 | for disk in $(get_all_disks); do 21 | if fdisk -l "/dev/$disk" | grep -iq "$main_disk"; then 22 | echo "$disk" 23 | return 24 | fi 25 | done 26 | 27 | echo 'XDA_NOT_FOUND' 28 | return 1 29 | } 30 | 31 | get_xda 32 | -------------------------------------------------------------------------------- /initrd-network.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | # shellcheck shell=dash 3 | # alpine/debian initrd 共用此脚本 4 | 5 | # accept_ra 接收 RA + 自动配置网关 6 | # autoconf 自动配置地址,依赖 accept_ra 7 | 8 | mac_addr=$1 9 | ipv4_addr=$2 10 | ipv4_gateway=$3 11 | ipv6_addr=$4 12 | ipv6_gateway=$5 13 | is_in_china=$6 14 | 15 | DHCP_TIMEOUT=15 16 | DNS_FILE_TIMEOUT=5 17 | TEST_TIMEOUT=10 18 | 19 | # 检测是否有网络是通过检测这些 IP 的端口是否开放 20 | # 因为 debian initrd 没有 nslookup 21 | # 改成 generate_204?但检测网络时可能 resolv.conf 为空 22 | # HTTP 80 23 | # HTTPS/DOH 443 24 | # DOT 853 25 | if $is_in_china; then 26 | ipv4_dns1='223.5.5.5' 27 | ipv4_dns2='119.29.29.29' # 不开放 853 28 | ipv6_dns1='2400:3200::1' 29 | ipv6_dns2='2402:4e00::' # 不开放 853 30 | else 31 | ipv4_dns1='1.1.1.1' 32 | ipv4_dns2='8.8.8.8' # 不开放 80 33 | ipv6_dns1='2606:4700:4700::1111' 34 | ipv6_dns2='2001:4860:4860::8888' # 不开放 80 35 | fi 36 | 37 | # 找到主网卡 38 | # debian 11 initrd 没有 xargs awk 39 | # debian 12 initrd 没有 xargs 40 | get_ethx() { 41 | # 过滤 azure vf (带 master ethx) 42 | # 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000\ link/ether 60:45:bd:21:8a:51 brd ff:ff:ff:ff:ff:ff 43 | # 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP800> mtu 1500 qdisc mq master eth0 state UP qlen 1000\ link/ether 60:45:bd:21:8a:51 brd ff:ff:ff 44 | if false; then 45 | ip -o link | grep -i "$mac_addr" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep . 46 | else 47 | ip -o link | grep -i "$mac_addr" | grep -v master | cut -d' ' -f2 | cut -d: -f1 | grep . 48 | fi 49 | } 50 | 51 | get_ipv4_gateway() { 52 | # debian 11 initrd 没有 xargs awk 53 | # debian 12 initrd 没有 xargs 54 | ip -4 route show default dev "$ethx" | head -1 | cut -d ' ' -f3 55 | } 56 | 57 | get_ipv6_gateway() { 58 | # debian 11 initrd 没有 xargs awk 59 | # debian 12 initrd 没有 xargs 60 | ip -6 route show default dev "$ethx" | head -1 | cut -d ' ' -f3 61 | } 62 | 63 | get_first_ipv4_addr() { 64 | # debian 11 initrd 没有 xargs awk 65 | # debian 12 initrd 没有 xargs 66 | if false; then 67 | ip -4 -o addr show scope global dev "$ethx" | head -1 | awk '{print $4}' 68 | else 69 | ip -4 -o addr show scope global dev "$ethx" | head -1 | grep -o '[0-9\.]*/[0-9]*' 70 | fi 71 | } 72 | 73 | get_first_ipv4_gateway() { 74 | # debian 11 initrd 没有 xargs awk 75 | # debian 12 initrd 没有 xargs 76 | if false; then 77 | ip -4 route show default dev "$ethx" | head -1 | awk '{print $3}' 78 | else 79 | ip -4 route show default dev "$ethx" | head -1 | cut -d' ' -f3 80 | fi 81 | } 82 | 83 | remove_netmask() { 84 | cut -d/ -f1 85 | } 86 | 87 | get_first_ipv6_addr() { 88 | # debian 11 initrd 没有 xargs awk 89 | # debian 12 initrd 没有 xargs 90 | if false; then 91 | ip -6 -o addr show scope global dev "$ethx" | head -1 | awk '{print $4}' 92 | else 93 | ip -6 -o addr show scope global dev "$ethx" | head -1 | grep -o '[0-9a-f\:]*/[0-9]*' 94 | fi 95 | } 96 | 97 | get_first_ipv6_gateway() { 98 | # debian 11 initrd 没有 xargs awk 99 | # debian 12 initrd 没有 xargs 100 | if false; then 101 | ip -6 route show default dev "$ethx" | head -1 | awk '{print $3}' 102 | else 103 | ip -6 route show default dev "$ethx" | head -1 | cut -d' ' -f3 104 | fi 105 | } 106 | 107 | is_have_ipv4_addr() { 108 | ip -4 addr show scope global dev "$ethx" | grep -q inet 109 | } 110 | 111 | is_have_ipv6_addr() { 112 | ip -6 addr show scope global dev "$ethx" | grep -q inet6 113 | } 114 | 115 | is_have_ipv4_gateway() { 116 | ip -4 route show default dev "$ethx" | grep -q . 117 | } 118 | 119 | is_have_ipv6_gateway() { 120 | ip -6 route show default dev "$ethx" | grep -q . 121 | } 122 | 123 | is_have_ipv4() { 124 | is_have_ipv4_addr && is_have_ipv4_gateway 125 | } 126 | 127 | is_have_ipv6() { 128 | is_have_ipv6_addr && is_have_ipv6_gateway 129 | } 130 | 131 | is_have_ipv4_dns() { 132 | [ -f /etc/resolv.conf ] && grep -q '^nameserver .*\.' /etc/resolv.conf 133 | } 134 | 135 | is_have_ipv6_dns() { 136 | [ -f /etc/resolv.conf ] && grep -q '^nameserver .*:' /etc/resolv.conf 137 | } 138 | 139 | add_missing_ipv4_config() { 140 | if [ -n "$ipv4_addr" ] && [ -n "$ipv4_gateway" ]; then 141 | if ! is_have_ipv4_addr; then 142 | ip -4 addr add "$ipv4_addr" dev "$ethx" 143 | fi 144 | 145 | if ! is_have_ipv4_gateway; then 146 | # 如果 dhcp 无法设置onlink网关,那么在这里设置 147 | # debian 9 ipv6 不能识别 onlink,但 ipv4 能识别 onlink 148 | if true; then 149 | ip -4 route add "$ipv4_gateway" dev "$ethx" 150 | ip -4 route add default via "$ipv4_gateway" dev "$ethx" 151 | else 152 | ip -4 route add default via "$ipv4_gateway" dev "$ethx" onlink 153 | fi 154 | fi 155 | fi 156 | } 157 | 158 | add_missing_ipv6_config() { 159 | if [ -n "$ipv6_addr" ] && [ -n "$ipv6_gateway" ]; then 160 | if ! is_have_ipv6_addr; then 161 | ip -6 addr add "$ipv6_addr" dev "$ethx" 162 | fi 163 | 164 | if ! is_have_ipv6_gateway; then 165 | # 如果 dhcp 无法设置onlink网关,那么在这里设置 166 | # debian 9 ipv6 不能识别 onlink 167 | if true; then 168 | ip -6 route add "$ipv6_gateway" dev "$ethx" 169 | ip -6 route add default via "$ipv6_gateway" dev "$ethx" 170 | else 171 | ip -6 route add default via "$ipv6_gateway" dev "$ethx" onlink 172 | fi 173 | fi 174 | fi 175 | } 176 | 177 | is_need_test_ipv4() { 178 | is_have_ipv4 && ! $ipv4_has_internet 179 | } 180 | 181 | is_need_test_ipv6() { 182 | is_have_ipv6 && ! $ipv6_has_internet 183 | } 184 | 185 | # 测试方法: 186 | # ping 有的机器禁止 187 | # nc 测试 dot doh 端口是否开启 188 | # wget 测试下载 189 | 190 | # initrd 里面的软件版本,是否支持指定源IP/网卡 191 | # 软件 nc wget nslookup 192 | # debian9 × √ 没有此软件 193 | # alpine √ × × 194 | 195 | test_by_wget() { 196 | src=$1 197 | dst=$2 198 | 199 | # ipv6 需要添加 [] 200 | if echo "$dst" | grep -q ':'; then 201 | url="https://[$dst]" 202 | else 203 | url="https://$dst" 204 | fi 205 | 206 | # tcp 443 通了就算成功,不管 http 是不是 404 207 | # grep -m1 快速返回 208 | wget -T "$TEST_TIMEOUT" \ 209 | --bind-address="$src" \ 210 | --no-check-certificate \ 211 | --max-redirect 0 \ 212 | --tries 1 \ 213 | -O /dev/null \ 214 | "$url" 2>&1 | grep -iq -m1 connected 215 | } 216 | 217 | test_by_nc() { 218 | src=$1 219 | dst=$2 220 | 221 | # tcp 443 通了就算成功 222 | nc -z -v \ 223 | -w "$TEST_TIMEOUT" \ 224 | -s "$src" \ 225 | "$dst" 443 226 | } 227 | 228 | is_debian_kali() { 229 | [ -f /etc/lsb-release ] && grep -Eiq 'Debian|Kali' /etc/lsb-release 230 | } 231 | 232 | test_connect() { 233 | if is_debian_kali; then 234 | test_by_wget "$1" "$2" 235 | else 236 | test_by_nc "$1" "$2" 237 | fi 238 | } 239 | 240 | test_internet() { 241 | for i in $(seq 5); do 242 | echo "Testing Internet Connection. Test $i... " 243 | if is_need_test_ipv4 && { local current_ipv4_addr; current_ipv4_addr="$(get_first_ipv4_addr | remove_netmask)"; test_connect "$current_ipv4_addr" "$ipv4_dns1" >/dev/null 2>&1 || test_connect "$current_ipv4_addr" "$ipv4_dns2" >/dev/null 2>&1; }; then 244 | echo "IPv4 has internet." 245 | ipv4_has_internet=true 246 | fi 247 | if is_need_test_ipv6 && { local current_ipv6_addr; current_ipv6_addr="$(get_first_ipv6_addr | remove_netmask)"; test_connect "$current_ipv6_addr" "$ipv6_dns1" >/dev/null 2>&1 || test_connect "$current_ipv6_addr" "$ipv6_dns2" >/dev/null 2>&1; }; then 248 | echo "IPv6 has internet." 249 | ipv6_has_internet=true 250 | fi 251 | if ! is_need_test_ipv4 && ! is_need_test_ipv6; then 252 | break 253 | fi 254 | sleep 1 255 | done 256 | } 257 | 258 | flush_ipv4_config() { 259 | ip -4 addr flush scope global dev "$ethx" 260 | ip -4 route flush dev "$ethx" 261 | # DHCP 获取的 IP 不是重装前的 IP 时,一并删除 DHCP 获取的 DNS,以防 DNS 无效 262 | sed -i "/\./d" /etc/resolv.conf 263 | } 264 | 265 | should_disable_dhcpv4=false 266 | should_disable_accept_ra=false 267 | should_disable_autoconf=false 268 | 269 | flush_ipv6_config() { 270 | if $should_disable_accept_ra; then 271 | echo 0 >"/proc/sys/net/ipv6/conf/$ethx/accept_ra" 272 | fi 273 | if $should_disable_autoconf; then 274 | echo 0 >"/proc/sys/net/ipv6/conf/$ethx/autoconf" 275 | fi 276 | ip -6 addr flush scope global dev "$ethx" 277 | ip -6 route flush dev "$ethx" 278 | # DHCP 获取的 IP 不是重装前的 IP 时,一并删除 DHCP 获取的 DNS,以防 DNS 无效 279 | sed -i "/:/d" /etc/resolv.conf 280 | } 281 | 282 | for i in $(seq 20); do 283 | if ethx=$(get_ethx); then 284 | break 285 | fi 286 | sleep 1 287 | done 288 | 289 | if [ -z "$ethx" ]; then 290 | echo "Not found network card: $mac_addr" 291 | exit 292 | fi 293 | 294 | echo "Configuring $ethx ($mac_addr)..." 295 | 296 | # 不开启 lo 则 frp 无法连接 127.0.0.1 22 297 | ip link set dev lo up 298 | 299 | # 开启 ethx 300 | ip link set dev "$ethx" up 301 | sleep 1 302 | 303 | # 开启 dhcpv4/v6 304 | # debian / kali 305 | if [ -f /usr/share/debconf/confmodule ]; then 306 | # shellcheck source=/dev/null 307 | . /usr/share/debconf/confmodule 308 | 309 | db_progress STEP 1 310 | 311 | # dhcpv4 312 | # 无需等待写入 dns,在 dhcpv6 等待 313 | db_progress INFO netcfg/dhcp_progress 314 | udhcpc -i "$ethx" -f -q -n || true 315 | db_progress STEP 1 316 | 317 | # slaac + dhcpv6 318 | db_progress INFO netcfg/slaac_wait_title 319 | # https://salsa.debian.org/installer-team/netcfg/-/blob/master/autoconfig.c#L148 320 | cat <<EOF >/var/lib/netcfg/dhcp6c.conf 321 | interface $ethx { 322 | send ia-na 0; 323 | request domain-name-servers; 324 | request domain-name; 325 | script "/lib/netcfg/print-dhcp6c-info"; 326 | }; 327 | 328 | id-assoc na 0 { 329 | }; 330 | EOF 331 | dhcp6c -c /var/lib/netcfg/dhcp6c.conf "$ethx" || true 332 | sleep $DHCP_TIMEOUT # 等待获取 ip 和写入 dns 333 | # kill-all-dhcp 334 | kill -9 "$(cat /var/run/dhcp6c.pid)" || true 335 | db_progress STEP 1 336 | 337 | # 静态 + 检测网络提示 338 | db_subst netcfg/link_detect_progress interface "$ethx" 339 | db_progress INFO netcfg/link_detect_progress 340 | else 341 | # alpine 342 | # h3c 移动云电脑使用 udhcpc 会重复提示 sending select,无法获得 ipv6,因此使用 dhcpcd 343 | method=dhcpcd 344 | 345 | case "$method" in 346 | udhcpc) 347 | udhcpc -i "$ethx" -f -q -n || true 348 | udhcpc6 -i "$ethx" -f -q -n || true 349 | sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns,但是以防万一 350 | ;; 351 | dhcpcd) 352 | # https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/dhcpcd/dhcpcd.pre-install 353 | grep -q dhcpcd /etc/group || addgroup -S dhcpcd 354 | grep -q dhcpcd /etc/passwd || adduser -S -D -H \ 355 | -h /var/lib/dhcpcd \ 356 | -s /sbin/nologin \ 357 | -G dhcpcd \ 358 | -g dhcpcd \ 359 | dhcpcd 360 | 361 | # --noipv4ll 禁止生成 169.254.x.x 362 | if false; then 363 | # 等待 DHCP 全过程 364 | timeout $DHCP_TIMEOUT \ 365 | dhcpcd --persistent --noipv4ll --nobackground "$ethx" 366 | else 367 | # 等待 DNS 368 | dhcpcd --persistent --noipv4ll "$ethx" # 获取到 IP 后立即切换到后台 369 | sleep $DNS_FILE_TIMEOUT # 需要等待写入 dns 370 | dhcpcd -x "$ethx" # 终止 371 | fi 372 | ;; 373 | esac 374 | fi 375 | 376 | # 等待slaac 377 | # 有ipv6地址就跳过,不管是slaac或者dhcpv6 378 | # 因为会在trans里判断 379 | # 这里等待5秒就够了,因为之前尝试获取dhcp6也用了一段时间 380 | for i in $(seq 5 -1 0); do 381 | is_have_ipv6 && break 382 | echo "waiting slaac for ${i}s" 383 | sleep 1 384 | done 385 | 386 | # 记录是否有动态地址 387 | # 由于还没设置静态ip,所以有条目表示有动态地址 388 | is_have_ipv4_addr && dhcpv4=true || dhcpv4=false 389 | is_have_ipv6_addr && dhcpv6_or_slaac=true || dhcpv6_or_slaac=false 390 | is_have_ipv6_gateway && ra_has_gateway=true || ra_has_gateway=false 391 | 392 | # 如果自动获取的 IP 不是重装前的,则改成静态,使用之前的 IP 393 | # 只比较 IP,不比较掩码/网关,因为 394 | # 1. 假设掩码/网关导致无法上网,后面也会检测到并改成静态 395 | # 2. openSUSE wicked dhcpv6 是 64 位掩码,aws lightsail 模板上的也是,而其它 dhcpv6 软件都是 128 位掩码 396 | if $dhcpv4 && [ -n "$ipv4_addr" ] && [ -n "$ipv4_gateway" ] && 397 | ! [ "$(echo "$ipv4_addr" | cut -d/ -f1)" = "$(get_first_ipv4_addr | cut -d/ -f1)" ]; then 398 | echo "IPv4 address obtained from DHCP is different from old system." 399 | should_disable_dhcpv4=true 400 | flush_ipv4_config 401 | fi 402 | if $dhcpv6_or_slaac && [ -n "$ipv6_addr" ] && [ -n "$ipv6_gateway" ] && 403 | ! [ "$(echo "$ipv6_addr" | cut -d/ -f1)" = "$(get_first_ipv6_addr | cut -d/ -f1)" ]; then 404 | echo "IPv6 address obtained from SLAAC/DHCPv6 is different from old system." 405 | should_disable_accept_ra=true 406 | should_disable_autoconf=true 407 | flush_ipv6_config 408 | fi 409 | 410 | # 设置静态地址,或者设置 debian 9 udhcpc 无法设置的网关 411 | add_missing_ipv4_config 412 | add_missing_ipv6_config 413 | 414 | # 检查 ipv4/ipv6 是否连接联网 415 | ipv4_has_internet=false 416 | ipv6_has_internet=false 417 | test_internet 418 | 419 | # 如果无法上网,并且自动获取的 掩码/网关 不是重装前的,则改成静态 420 | # ip_addr 包括 IP/掩码,所以可以用来判断掩码是否不同 421 | # IP 不同的情况在前面已经改成静态了 422 | if ! $ipv4_has_internet && 423 | $dhcpv4 && [ -n "$ipv4_addr" ] && [ -n "$ipv4_gateway" ] && 424 | ! { [ "$ipv4_addr" = "$(get_first_ipv4_addr)" ] && [ "$ipv4_gateway" = "$(get_first_ipv4_gateway)" ]; }; then 425 | echo "IPv4 netmask/gateway obtained from DHCP is different from old system." 426 | should_disable_dhcpv4=true 427 | flush_ipv4_config 428 | add_missing_ipv4_config 429 | test_internet 430 | fi 431 | # 有可能是静态 IPv6 但能从 RA 获取到网关,因此加上 || $ra_has_gateway 432 | if ! $ipv6_has_internet && 433 | { $dhcpv6_or_slaac || $ra_has_gateway; } && 434 | [ -n "$ipv6_addr" ] && [ -n "$ipv6_gateway" ] && 435 | ! { [ "$ipv6_addr" = "$(get_first_ipv6_addr)" ] && [ "$ipv6_gateway" = "$(get_first_ipv6_gateway)" ]; }; then 436 | echo "IPv6 netmask/gateway obtained from SLAAC/DHCPv6 is different from old system." 437 | should_disable_accept_ra=true 438 | should_disable_autoconf=true 439 | flush_ipv6_config 440 | add_missing_ipv6_config 441 | test_internet 442 | fi 443 | 444 | # 要删除不联网协议的ip,因为 445 | # 1 甲骨文云管理面板添加ipv6地址然后取消 446 | # 依然会分配ipv6地址,但ipv6没网络 447 | # 此时alpine只会用ipv6下载apk,而不用会ipv4下载 448 | # 2 有ipv4地址但没有ipv4网关的情况(vultr $2.5 ipv6 only),aria2会用ipv4下载 449 | 450 | # 假设 ipv4 ipv6 在不同网卡,ipv4 能上网但 ipv6 不能上网,这时也要删除 ipv6 451 | # 不能用 ipv4_has_internet && ! ipv6_has_internet 判断,因为它判断的是同一个网卡 452 | if ! $ipv4_has_internet; then 453 | if $dhcpv4; then 454 | should_disable_dhcpv4=true 455 | fi 456 | flush_ipv4_config 457 | fi 458 | if ! $ipv6_has_internet; then 459 | # 防止删除 IPv6 后再次通过 SLAAC 获得 460 | # 不用判断 || $ra_has_gateway ,因为没有 IPv6 地址但有 IPv6 网关时,不会出现下载问题 461 | if $dhcpv6_or_slaac; then 462 | should_disable_accept_ra=true 463 | should_disable_autoconf=true 464 | fi 465 | flush_ipv6_config 466 | fi 467 | 468 | # 如果联网了,但没获取到默认 DNS,则添加我们的 DNS 469 | 470 | # 有一种情况是,多网卡,且能上网的网卡先完成了这个脚本,不能上网的网卡后完成 471 | # 无法上网的网卡通过 flush_ipv4_config 删除了不能上网的 IP 和 dns 472 | # (原计划是删除无法上网的网卡 dhcp4 获取的 dns,但实际上无法区分) 473 | # 因此这里直接添加 dns,不判断是否联网 474 | if ! is_have_ipv4_dns; then 475 | echo "nameserver $ipv4_dns1" >>/etc/resolv.conf 476 | echo "nameserver $ipv4_dns2" >>/etc/resolv.conf 477 | fi 478 | if ! is_have_ipv6_dns; then 479 | echo "nameserver $ipv6_dns1" >>/etc/resolv.conf 480 | echo "nameserver $ipv6_dns2" >>/etc/resolv.conf 481 | fi 482 | 483 | # 传参给 trans.start 484 | netconf="/dev/netconf/$ethx" 485 | mkdir -p "$netconf" 486 | $dhcpv4 && echo 1 >"$netconf/dhcpv4" || echo 0 >"$netconf/dhcpv4" 487 | $dhcpv6_or_slaac && echo 1 >"$netconf/dhcpv6_or_slaac" || echo 0 >"$netconf/dhcpv6_or_slaac" 488 | $should_disable_dhcpv4 && echo 1 >"$netconf/should_disable_dhcpv4" || echo 0 >"$netconf/should_disable_dhcpv4" 489 | $should_disable_accept_ra && echo 1 >"$netconf/should_disable_accept_ra" || echo 0 >"$netconf/should_disable_accept_ra" 490 | $should_disable_autoconf && echo 1 >"$netconf/should_disable_autoconf" || echo 0 >"$netconf/should_disable_autoconf" 491 | $is_in_china && echo 1 >"$netconf/is_in_china" || echo 0 >"$netconf/is_in_china" 492 | echo "$ethx" >"$netconf/ethx" 493 | echo "$mac_addr" >"$netconf/mac_addr" 494 | echo "$ipv4_addr" >"$netconf/ipv4_addr" 495 | echo "$ipv4_gateway" >"$netconf/ipv4_gateway" 496 | echo "$ipv6_addr" >"$netconf/ipv6_addr" 497 | echo "$ipv6_gateway" >"$netconf/ipv6_gateway" 498 | $ipv4_has_internet && echo 1 >"$netconf/ipv4_has_internet" || echo 0 >"$netconf/ipv4_has_internet" 499 | $ipv6_has_internet && echo 1 >"$netconf/ipv6_has_internet" || echo 0 >"$netconf/ipv6_has_internet" 500 | -------------------------------------------------------------------------------- /logviewer-nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen @WEB_PORT@; 3 | listen [::]:@WEB_PORT@; 4 | root /; 5 | 6 | gzip on; 7 | gzip_types text/plain; 8 | 9 | 10 | location = / { 11 | try_files /logviewer.html 404; 12 | } 13 | 14 | location = /reinstall.log { 15 | types { 16 | text/plain log; 17 | } 18 | 19 | try_files $uri 404; 20 | } 21 | 22 | location / { 23 | return 404; 24 | } 25 | } -------------------------------------------------------------------------------- /logviewer.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html> 3 | 4 | <head> 5 | <title>Reinstall Logs</title> 6 | <style> 7 | body { 8 | margin: 0; 9 | padding: 0; 10 | overflow: hidden; 11 | } 12 | 13 | #log-container { 14 | height: calc(100vh); 15 | margin: 0; 16 | padding: 8px; 17 | overflow-y: scroll; 18 | } 19 | 20 | #scroll-to-bottom { 21 | position: fixed; 22 | bottom: 24px; 23 | right: 24px; 24 | background-color: #0099FF; 25 | color: #fff; 26 | border: none; 27 | cursor: pointer; 28 | display: none; 29 | width: 48px; 30 | height: 48px; 31 | border-radius: 50%; 32 | } 33 | 34 | #scroll-to-bottom:hover { 35 | background-color: #00CCFF; 36 | } 37 | 38 | #scroll-to-bottom svg { 39 | fill: #fff; 40 | } 41 | 42 | .done { 43 | background-color: #cfc; 44 | } 45 | 46 | .error { 47 | background-color: #fcc; 48 | } 49 | </style> 50 | </head> 51 | 52 | <body> 53 | <pre id="log-container"></pre> 54 | <button id="scroll-to-bottom"> 55 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> 56 | <path d="M5 10l7 7 7-7H5z" /> 57 | </svg> 58 | </button> 59 | 60 | <script 61 | src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-d/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" 62 | type="application/javascript"></script> 63 | 64 | <script> 65 | const logContainer = document.getElementById('log-container'); 66 | const scrollToBottomButton = document.getElementById('scroll-to-bottom'); 67 | let shouldScrollToBottom = true; 68 | 69 | scrollToBottomButton.addEventListener('click', () => { 70 | logContainer.scrollTop = logContainer.scrollHeight; 71 | }); 72 | 73 | logContainer.addEventListener('scroll', () => { 74 | const isAtBottom = Math.ceil(logContainer.scrollTop + logContainer.clientHeight) >= logContainer.scrollHeight; 75 | if (isAtBottom) { 76 | scrollToBottomButton.style.display = 'none'; 77 | } else { 78 | scrollToBottomButton.style.display = 'block'; 79 | } 80 | 81 | shouldScrollToBottom = isAtBottom; 82 | }); 83 | 84 | var ws = new ReconnectingWebSocket('ws://' + location.host + '/'); 85 | ws.onopen = function () { 86 | logContainer.textContent += '\nWebSocket Connected.'; 87 | }; 88 | ws.onclose = function () { 89 | logContainer.textContent += '\nWebSocket Disconnected.'; 90 | }; 91 | ws.onmessage = function (event) { 92 | logContainer.textContent += '\n' + event.data; 93 | if (shouldScrollToBottom) { 94 | logContainer.scrollTop = logContainer.scrollHeight; 95 | } 96 | // 开始/重新开始 97 | if (event.data.includes('***** START TRANS *****')) { 98 | document.body.className = '' 99 | } 100 | // 错误 101 | else if (event.data.includes('***** ERROR *****')) { 102 | document.body.className = 'error' 103 | } 104 | // 完成 105 | else if (event.data.includes('***** DONE *****')) { 106 | document.body.className = 'done' 107 | } 108 | }; 109 | </script> 110 | </body> 111 | 112 | </html> 113 | -------------------------------------------------------------------------------- /redhat.cfg: -------------------------------------------------------------------------------- 1 | # shellcheck disable=SC2148 2 | # 设置 3 | keyboard --vckeymap=us --xlayouts='us' 4 | lang en_US.UTF-8 5 | timezone Asia/Shanghai --utc 6 | rootpw --plaintext 123@@@ 7 | text 8 | reboot 9 | %include /tmp/include-url-command 10 | 11 | # 分区 12 | %include /tmp/include-disk-only-use 13 | %include /tmp/include-bootloader 14 | clearpart --all --initlabel 15 | reqpart # 如果需要,自动创建 efi 或 biosboot 分区 16 | part / --fstype=xfs --grow 17 | 18 | # 软件 19 | %packages --ignoremissing # el9 minimal.iso fedora Server repo/iso 没有 tuned 20 | @^Minimal Install 21 | %include /tmp/include-packages-for-resize 22 | %include /tmp/exclude-packages-for-vm 23 | %end 24 | 25 | # 禁用防火墙 26 | # firewall --disabled 27 | 28 | # 禁用 selinux 29 | selinux --disabled 30 | 31 | # 禁用 kdump 32 | %addon com_redhat_kdump --disable 33 | %end 34 | 35 | ############################################## 36 | %pre 37 | distro=$(awk -F: '{ print $3 }' </etc/system-release-cpe) 38 | releasever=$(awk -F: '{ print $5 }' </etc/system-release-cpe) 39 | 40 | # 重新整理 extra,grub把两侧的引号吃掉了,eval出错,要重新添加引号 41 | # 提取 extra_confhome extra_mirrorlist extra_main_disk 42 | prefix=extra 43 | for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do 44 | eval "$(echo "$var" | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")" 45 | done 46 | 47 | # centos7 证书链未更新,需要 --no-check-certificate 48 | 49 | # 只使用主硬盘 50 | include=/tmp/include-disk-only-use 51 | xda=$(wget --no-check-certificate --tries=5 "$confhome/get-xda.sh" -O- | sh -s) 52 | echo "ignoredisk --only-use=$xda" >$include 53 | 54 | # 设置 tty 55 | include=/tmp/include-bootloader 56 | # shellcheck disable=SC2154 57 | console_cmdline=$(wget --no-check-certificate --tries=5 "$confhome/ttys.sh" -O- | sh -s console=) 58 | echo "bootloader --append=\"$console_cmdline\"" >$include 59 | 60 | # 有 installer 分区,表示用了两步安装 61 | include=/tmp/include-packages-for-resize 62 | touch $include 63 | if [ -e /dev/disk/by-label/installer ]; then 64 | # 1g内存下,安装器默认开启了zram ,但安装f38还是不够内存 65 | # 具体表现为不断重启安装界面,所以还要开启swap 66 | ram_size=$(lsmem -b 2>/dev/null | grep 'Total online memory:' | awk '{ print $NF/1024/1024 }') 67 | if [ -z "$ram_size" ] || [ "$ram_size" -le 1024 ]; then 68 | mount /dev/disk/by-label/installer /run/install/repo -o remount,rw 69 | swapfile=/run/install/repo/swapfile 70 | if command -v fallocate; then 71 | fallocate -l 1G $swapfile 72 | else 73 | dd if=/dev/zero of=$swapfile bs=1M count=1024 74 | fi 75 | chmod 0600 $swapfile 76 | mkswap $swapfile 77 | swapon $swapfile 78 | fi 79 | 80 | # feroda 默认不包含 cronie 81 | echo cronie >>$include 82 | 83 | # el7 的parted不支持在线扩容,要用 growpart 和 gdisk 处理 gpt 分区 84 | if [ "$releasever" = "7" ]; then 85 | echo cloud-utils-growpart >>$include 86 | echo gdisk >>$include 87 | fi 88 | fi 89 | 90 | # 排除虚拟机用不上的组件 91 | include=/tmp/exclude-packages-for-vm 92 | touch $include 93 | if systemd-detect-virt -v; then 94 | cat <<EOF >$include 95 | # 不删除usb相关的包 因为甲骨文云有usb设备 作用未知 96 | # -usb_modeswitch 97 | # -usbutils 98 | 99 | # 无线 100 | -iw 101 | -crda 102 | -rfkill 103 | -iwl*-firmware 104 | 105 | # 其他 106 | -irqbalance # 多核+直通设备可能有用? 107 | -microcode_ctl 108 | -smartmontools 109 | 110 | # 各种固件 111 | -aic94xx-firmware 112 | -alsa-firmware 113 | -ivtv-firmware 114 | # -linux-firmware # 去除后安装centos 8会报错 115 | 116 | # fedora 特有固件 117 | -amd-gpu-firmware 118 | -atheros-firmware 119 | -brcmfmac-firmware 120 | -intel-gpu-firmware 121 | -mt7xxx-firmware 122 | -nvidia-gpu-firmware 123 | -realtek-firmware 124 | EOF 125 | fi 126 | 127 | # 设置安装源 128 | include=/tmp/include-url-command 129 | # shellcheck disable=SC2154 130 | if [ "$localtest" = 1 ]; then 131 | echo "url --url=$confhome/$releasever/" >$include 132 | # echo cdrom >$include 133 | else 134 | echo "url --mirrorlist=$mirrorlist" >$include 135 | # 对于el7/fedora, 添加了 updates repo 才会安装最新的包 136 | if [ "$releasever" = "7" ] || [ "$distro" = "fedoraproject" ]; then 137 | echo "repo --name=updates" >>$include 138 | fi 139 | fi 140 | %end 141 | 142 | ############################################## 143 | %post 144 | # el9/fedora的sshd默认不允许root密码登录,需手动开启 145 | # rootpw --allow-ssh 9.1 以上才支持 146 | distro=$(awk -F: '{ print $3 }' </etc/system-release-cpe) 147 | releasever=$(awk -F: '{ print $5 }' </etc/system-release-cpe) 148 | if [ "$releasever" = "9" ] || [ "$distro" = "fedoraproject" ]; then 149 | echo "PermitRootLogin yes" >/etc/ssh/sshd_config.d/01-permitrootlogin.conf 150 | fi 151 | 152 | # 分步安装的系统,要将最后一个分区(installer)合并到系统分区 153 | if [ -e /dev/disk/by-label/installer ]; then 154 | # 提取 extra_localtest extra_confhome extra_mirrorlist 155 | prefix=extra 156 | for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do 157 | eval "$(echo "$var" | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")" 158 | done 159 | 160 | cd / 161 | curl -O "$confhome/resize.sh" 162 | echo '@reboot root bash /resize.sh' >/etc/cron.d/resize 163 | fi 164 | %end 165 | -------------------------------------------------------------------------------- /reinstall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | setlocal EnableDelayedExpansion 4 | 5 | set confhome=https://raw.githubusercontent.com/bin456789/reinstall/main 6 | set confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main 7 | rem set confhome_cn=https://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main 8 | 9 | set pkgs=curl,cpio,p7zip,dos2unix,jq,xz,gzip,zstd,openssl,bind-utils,libiconv,binutils 10 | set cmds=curl,cpio,p7zip,dos2unix,jq,xz,gzip,zstd,openssl,nslookup,iconv,ar 11 | 12 | rem 65001 代码页会乱码 13 | 14 | rem 不要用 :: 注释 15 | rem 否则可能会出现 系统找不到指定的驱动器 16 | 17 | rem Windows 7 SP1 winhttp 默认不支持 tls 1.2 18 | rem https://support.microsoft.com/en-us/topic/update-to-enable-tls-1-1-and-tls-1-2-as-default-secure-protocols-in-winhttp-in-windows-c4bd73d2-31d7-761e-0178-11268bb10392 19 | rem 有些系统根证书没更新 20 | rem 所以不要用https 21 | rem 进入脚本目录 22 | cd /d %~dp0 23 | 24 | rem 检查是否有管理员权限 25 | fltmc >nul 2>&1 26 | if errorlevel 1 ( 27 | echo Please run as administrator^^! 28 | exit /b 29 | ) 30 | 31 | rem 有时 %tmp% 带会话 id,且文件夹不存在 32 | rem https://learn.microsoft.com/troubleshoot/windows-server/shell-experience/temp-folder-with-logon-session-id-deleted 33 | rem if not exist %tmp% ( 34 | rem md %tmp% 35 | rem ) 36 | 37 | rem 下载 geoip 38 | if not exist geoip ( 39 | rem www.cloudflare.com/dash.cloudflare.com 国内访问的是美国服务器,而且部分地区被墙 40 | call :download http://www.qualcomm.cn/cdn-cgi/trace %~dp0geoip || goto :download_failed 41 | ) 42 | 43 | rem 判断是否有 loc= 44 | findstr /c:"loc=" geoip >nul 45 | if errorlevel 1 ( 46 | echo Invalid geoip file 47 | del geoip 48 | exit /b 1 49 | ) 50 | 51 | rem 检查是否国内 52 | findstr /c:"loc=CN" geoip >nul 53 | if not errorlevel 1 ( 54 | rem mirrors.tuna.tsinghua.edu.cn 会强制跳转 https 55 | set mirror=http://mirror.nju.edu.cn 56 | if defined confhome_cn ( 57 | set confhome=!confhome_cn! 58 | ) else if defined github_proxy ( 59 | echo !confhome! | findstr /c:"://raw.githubusercontent.com/" >nul 60 | if not errorlevel 1 ( 61 | set confhome=!confhome:http://=https://! 62 | set confhome=!confhome:https://raw.githubusercontent.com=%github_proxy%! 63 | ) 64 | ) 65 | ) else ( 66 | rem 服务器在美国 equinix 机房,不是 cdn 67 | set mirror=http://mirrors.kernel.org 68 | ) 69 | 70 | call :check_cygwin_installed || ( 71 | rem win10 arm 支持运行 x86 软件 72 | rem win11 arm 支持运行 x86 和 x86_64 软件 73 | 74 | rem windows 11 24h2 没有 wmic 75 | rem wmic os get osarchitecture 显示中文,即使设置了 mode con cp select=437 76 | rem wmic ComputerSystem get SystemType 显示英文 77 | rem for /f "tokens=*" %%a in ('wmic ComputerSystem get SystemType ^| find /i "based"') do ( 78 | rem set "SystemType=%%a" 79 | rem ) 80 | 81 | rem 有的系统精简了 powershell 82 | rem for /f "delims=" %%a in ('powershell -NoLogo -NoProfile -NonInteractive -Command "(Get-WmiObject win32_computersystem).SystemType"') do ( 83 | rem set "SystemType=%%a" 84 | rem ) 85 | 86 | rem SystemArch 87 | for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PROCESSOR_ARCHITECTURE') do ( 88 | set SystemArch=%%a 89 | ) 90 | 91 | rem 也可以用 PROCESSOR_ARCHITEW6432 和 PROCESSOR_ARCHITECTURE 判断 92 | rem ARM64 win11 PROCESSOR_ARCHITEW6432 PROCESSOR_ARCHITECTURE 93 | rem 原生cmd 未定义 ARM64 94 | rem 32位cmd ARM64 x86 95 | 96 | rem if defined PROCESSOR_ARCHITEW6432 ( 97 | rem set "SystemArch=%PROCESSOR_ARCHITEW6432%" 98 | rem ) else ( 99 | rem set "SystemArch=%PROCESSOR_ARCHITECTURE%" 100 | rem ) 101 | 102 | rem BuildNumber 103 | for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do ( 104 | set /a BuildNumber=%%a 105 | ) 106 | 107 | set CygwinEOL=1 108 | 109 | echo !SystemArch! | find "ARM" > nul 110 | if not errorlevel 1 ( 111 | if !BuildNumber! GEQ 22000 ( 112 | set CygwinEOL=0 113 | ) 114 | ) else ( 115 | echo !SystemArch! | find "AMD64" > nul 116 | if not errorlevel 1 ( 117 | if !BuildNumber! GEQ 9600 ( 118 | set CygwinEOL=0 119 | ) 120 | ) 121 | ) 122 | 123 | rem win7/8 cygwin 已 EOL,不能用最新 cygwin 源,而要用 Cygwin Time Machine 源 124 | rem 但 Cygwin Time Machine 没有国内源 125 | rem 为了保证国内下载速度, cygwin EOL 统一使用 cygwin-archive x86 源 126 | if !CygwinEOL! == 1 ( 127 | set CygwinArch=x86 128 | set dir=/sourceware/cygwin-archive/20221123 129 | ) else ( 130 | set CygwinArch=x86_64 131 | set dir=/sourceware/cygwin 132 | ) 133 | 134 | rem 下载 Cygwin 135 | if not exist setup-!CygwinArch!.exe ( 136 | call :download http://www.cygwin.com/setup-!CygwinArch!.exe %~dp0setup-!CygwinArch!.exe || goto :download_failed 137 | ) 138 | 139 | rem 少于 1M 视为无效 140 | rem 有的 IP 被官网拉黑,无法下载 exe,下载得到 html 141 | for %%A in (setup-!CygwinArch!.exe) do if %%~zA LSS 1048576 ( 142 | echo Invalid Cgywin installer 143 | del setup-!CygwinArch!.exe 144 | exit /b 1 145 | ) 146 | 147 | rem 安装 Cygwin 148 | set site=!mirror!!dir! 149 | start /wait setup-!CygwinArch!.exe ^ 150 | --allow-unsupported-windows ^ 151 | --quiet-mode ^ 152 | --only-site ^ 153 | --site !site! ^ 154 | --root %SystemDrive%\cygwin ^ 155 | --local-package-dir %~dp0cygwin-local-package-dir ^ 156 | --packages %pkgs% 157 | 158 | rem 检查 Cygwin 是否成功安装 159 | if errorlevel 1 goto :install_cygwin_failed 160 | call :check_cygwin_installed || goto :install_cygwin_failed 161 | ) 162 | 163 | rem 在c盘根目录下执行 cygpath -ua . 会得到 /cygdrive/c,因此末尾要有 / 164 | for /f %%a in ('%SystemDrive%\cygwin\bin\cygpath -ua ./') do set thisdir=%%a 165 | 166 | rem 下载 reinstall.sh 167 | if not exist reinstall.sh ( 168 | call :download_with_curl %confhome%/reinstall.sh %thisdir%reinstall.sh || goto :download_failed 169 | call :chmod a+x %thisdir%reinstall.sh 170 | ) 171 | 172 | rem %* 无法处理 --iso https://x.com/?yyy=123 173 | rem 为每个参数添加引号,使参数正确传递到 bash 174 | rem for %%a in (%*) do ( 175 | rem set "param=!param! "%%~a"" 176 | rem ) 177 | 178 | rem 转成 unix 格式,避免用户用 windows 记事本编辑后换行符不对 179 | %SystemDrive%\cygwin\bin\dos2unix -q '%thisdir%reinstall.sh' 180 | 181 | rem 用 bash 运行 182 | rem %SystemDrive%\cygwin\bin\bash -l %thisdir%reinstall.sh %* 运行后会清屏 183 | rem 因此不能用 -l 184 | rem 这就需要在 reinstall.sh 里运行 source /etc/profile 185 | rem 或者添加 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH 186 | %SystemDrive%\cygwin\bin\bash %thisdir%reinstall.sh %* 187 | exit /b 188 | 189 | rem bits 要求有 Content-Length 才能下载 190 | rem cloudflare 的 cdn-cgi/trace 没有 Content-Length 191 | rem 据说如果网络设为“按流量计费” bits 也无法下载 192 | rem https://learn.microsoft.com/en-us/windows/win32/bits/http-requirements-for-bits-downloads 193 | rem bitsadmin /transfer "%~3" /priority foreground %~1 %~2 194 | 195 | :download 196 | rem certutil 会被 windows Defender 报毒 197 | rem windows server 2019 要用第二条 certutil 命令 198 | echo Download: %~1 %~2 199 | del /q "%~2" 2>nul 200 | if exist "%~2" (echo Cannot delete %~2 & exit /b 1) 201 | 202 | certutil -urlcache -f -split "%~1" "%~2" >nul 203 | if not errorlevel 1 if exist "%~2" exit /b 0 204 | 205 | certutil -urlcache -split "%~1" "%~2" >nul 206 | if not errorlevel 1 if exist "%~2" exit /b 0 207 | 208 | rem 下载失败时删除文件,防止下载了一部分导致下次运行时跳过了下载 209 | del /q "%~2" 2>nul 210 | exit /b 1 211 | 212 | :download_with_curl 213 | rem 加 --insecure 防止以下错误 214 | rem curl: (77) error setting certificate verify locations: 215 | rem CAfile: /etc/ssl/certs/ca-certificates.crt 216 | rem CApath: none 217 | echo Download: %~1 %~2 218 | %SystemDrive%\cygwin\bin\curl -L --insecure "%~1" -o "%~2" 219 | exit /b 220 | 221 | :chmod 222 | %SystemDrive%\cygwin\bin\chmod "%~1" "%~2" 223 | exit /b 224 | 225 | :download_failed 226 | echo Download failed. 227 | exit /b 1 228 | 229 | :install_cygwin_failed 230 | echo Failed to install Cygwin. 231 | exit /b 1 232 | 233 | :check_cygwin_installed 234 | set "cmds_space=%cmds:,= %" 235 | for %%c in (%cmds_space%) do ( 236 | if not exist "%SystemDrive%\cygwin\bin\%%c" if not exist "%SystemDrive%\cygwin\bin\%%c.exe" ( 237 | exit /b 1 238 | ) 239 | ) 240 | exit /b 0 241 | -------------------------------------------------------------------------------- /resize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH="/usr/sbin:/usr/bin" 3 | 4 | update_part() { 5 | partx -u "$1" 6 | udevadm trigger 7 | udevadm settle 8 | } 9 | 10 | # el 自带 fdisk parted (el7的part不支持在线扩容) 11 | # ubuntu 自带 fdisk growpart 12 | 13 | # 删除分区用 14 | # el/ubuntu fdisk 15 | 16 | # 扩容分区用 17 | # el7 grownparted 额外安装 18 | # el8/9/fedora parted 19 | # ubuntu grownpart 20 | 21 | # 找出主硬盘 22 | root_drive=$(mount | awk '$3=="/" {print $1}') 23 | xda=$(lsblk -r --inverse "$root_drive" | grep -w disk | awk '{print $1}') 24 | 25 | # 删除 installer 分区 26 | installer_num=$(readlink -f /dev/disk/by-label/installer | grep -o '[0-9]*#39;) 27 | if [ -n "$installer_num" ]; then 28 | # 要添加 LC_NUMERIC 或者将%转义成\%才能在cron里正确运行 29 | # locale -a 不一定有"en_US.UTF-8",但肯定有"C.UTF-8" 30 | LC_NUMERIC="C.UTF-8" 31 | printf "d\n%s\nw" "$installer_num" | fdisk "/dev/$xda" 32 | update_part "/dev/$xda" 33 | fi 34 | 35 | # 找出现在的最后一个分区,也就是系统分区 36 | # el7 的 lsblk 没有 --sort,所以用其他方法 37 | # shellcheck disable=2012 38 | part_num=$(ls -1v "/dev/$xda"* | tail -1 | grep -o '[0-9]*#39;) 39 | part_fstype=$(lsblk -no FSTYPE "/dev/$xda"*"$part_num") 40 | 41 | # 扩容分区 42 | # ubuntu 和 el7 用 growpart,其他用 parted 43 | # el7 不能用parted在线扩容,而fdisk扩容会改变 PARTUUID,所以用 growpart 44 | if grep -E -i 'centos:7|ubuntu' /etc/os-release; then 45 | growpart "/dev/$xda" "$part_num" 46 | else 47 | printf 'yes\n100%%' | parted "/dev/$xda" resizepart "$part_num" ---pretend-input-tty 48 | fi 49 | update_part "/dev/$xda" 50 | 51 | # 扩容最后一个分区的文件系统 52 | case $part_fstype in 53 | xfs) xfs_growfs / ;; 54 | ext*) resize2fs "/dev/$xda"*"$part_num" ;; 55 | btrfs) btrfs filesystem resize max / ;; 56 | esac 57 | update_part "/dev/$xda" 58 | 59 | # 删除脚本自身 60 | rm -f /resize.sh /etc/cron.d/resize 61 | -------------------------------------------------------------------------------- /ttys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | prefix=$1 3 | 4 | # 不要在 windows 上使用,因为不准确 5 | # 在原系统上使用,也可能不准确?例如安装了 cloud 内核的甲骨文? 6 | 7 | # 注意 debian initrd 没有 xargs 8 | 9 | # 最后一个 tty 是主 tty,显示的信息最全 10 | is_first=true 11 | if [ "$(uname -m)" = "aarch64" ]; then 12 | ttys="ttyS0 ttyAMA0 tty0" 13 | else 14 | ttys="ttyS0 tty0" 15 | fi 16 | 17 | for tty in $ttys; do 18 | # hytron 有ttyS0 但无法写入 19 | if stty -g -F "/dev/$tty" >/dev/null 2>&1; then 20 | if $is_first; then 21 | is_first=false 22 | else 23 | printf " " 24 | fi 25 | 26 | printf "%s" "$prefix$tty" 27 | 28 | if [ "$prefix" = "console=" ] && 29 | { [ "$tty" = ttyS0 ] || [ "$tty" = ttyAMA0 ]; }; then 30 | printf ",115200n8" 31 | fi 32 | fi 33 | done 34 | -------------------------------------------------------------------------------- /ubuntu-storage-early.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sed -i -E '/^\.{3}$/d' /autoinstall.yaml 3 | echo 'storage:' >>/autoinstall.yaml 4 | 5 | # 禁用 swap 6 | cat <<EOF >>/autoinstall.yaml 7 | swap: 8 | size: 0 9 | EOF 10 | 11 | # 是用 size 寻找分区,number 没什么用 12 | # https://curtin.readthedocs.io/en/latest/topics/storage.html 13 | size_os=$(lsblk -bn -o SIZE /dev/disk/by-label/os) 14 | 15 | # shellcheck disable=SC2154 16 | if parted "/dev/$xda" print | grep '^Partition Table' | grep gpt; then 17 | # efi 18 | if [ -e /dev/disk/by-label/efi ]; then 19 | size_efi=$(lsblk -bn -o SIZE /dev/disk/by-label/efi) 20 | cat <<EOF >>/autoinstall.yaml 21 | config: 22 | # disk 23 | - ptable: gpt 24 | path: /dev/$xda 25 | preserve: true 26 | type: disk 27 | id: disk-xda 28 | # efi 分区 29 | - device: disk-xda 30 | size: $size_efi 31 | number: 1 32 | preserve: true 33 | grub_device: true 34 | type: partition 35 | id: partition-efi 36 | - fstype: fat32 37 | volume: partition-efi 38 | type: format 39 | id: format-efi 40 | # os 分区 41 | - device: disk-xda 42 | size: $size_os 43 | number: 2 44 | preserve: true 45 | type: partition 46 | id: partition-os 47 | - fstype: ext4 48 | volume: partition-os 49 | type: format 50 | id: format-os 51 | # mount 52 | - path: / 53 | device: format-os 54 | type: mount 55 | id: mount-os 56 | - path: /boot/efi 57 | device: format-efi 58 | type: mount 59 | id: mount-efi 60 | EOF 61 | else 62 | # bios > 2t 63 | size_biosboot=$(parted "/dev/$xda" unit b print | grep bios_grub | awk '{print $4}' | sed 's/B$//') 64 | cat <<EOF >>/autoinstall.yaml 65 | config: 66 | # disk 67 | - ptable: gpt 68 | path: /dev/$xda 69 | preserve: true 70 | grub_device: true 71 | type: disk 72 | id: disk-xda 73 | # biosboot 分区 74 | - device: disk-xda 75 | size: $size_biosboot 76 | number: 1 77 | preserve: true 78 | type: partition 79 | id: partition-biosboot 80 | # os 分区 81 | - device: disk-xda 82 | size: $size_os 83 | number: 2 84 | preserve: true 85 | type: partition 86 | id: partition-os 87 | - fstype: ext4 88 | volume: partition-os 89 | type: format 90 | id: format-os 91 | # mount 92 | - path: / 93 | device: format-os 94 | type: mount 95 | id: mount-os 96 | EOF 97 | fi 98 | else 99 | # bios 100 | cat <<EOF >>/autoinstall.yaml 101 | config: 102 | # disk 103 | - ptable: msdos 104 | path: /dev/$xda 105 | preserve: true 106 | grub_device: true 107 | type: disk 108 | id: disk-xda 109 | # os 分区 110 | - device: disk-xda 111 | size: $size_os 112 | number: 1 113 | preserve: true 114 | type: partition 115 | id: partition-os 116 | - fstype: ext4 117 | volume: partition-os 118 | type: format 119 | id: format-os 120 | # mount 121 | - path: / 122 | device: format-os 123 | type: mount 124 | id: mount-os 125 | EOF 126 | fi 127 | echo ... >>/autoinstall.yaml 128 | -------------------------------------------------------------------------------- /ubuntu.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | # 顺序 early-commands > 安装系统 > late-commands > 重启进入系统 > cloud-init: runcmd > cloud-init: 其他 3 | autoinstall: 4 | version: 1 5 | apt: 6 | fallback: offline-install 7 | source: 8 | id: "@SOURCE_ID@" 9 | kernel: 10 | package: linux-generic 11 | timezone: Asia/Shanghai 12 | ssh: 13 | allow-pw: true 14 | authorized-keys: [] 15 | install-server: true 16 | early-commands: 17 | - | 18 | # 解决 20.04 不能识别硬盘 19 | # https://askubuntu.com/questions/1302392/ubuntu-server-20-04-setup-stuck-at-block-probing-did-not-discover-any-disks 20 | mount | grep /isodevice && { losetup -d /dev/loop0; umount -l /isodevice; } || true 21 | 22 | # 提取 extra_confhome extra_kernel 23 | prefix=extra 24 | for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do 25 | eval "$(echo $var | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")" 26 | done 27 | 28 | # 生成分区信息 29 | xda=$(curl -L "$confhome/get-xda.sh" | sh -s) 30 | export xda 31 | curl -L "$confhome/ubuntu-storage-early.sh" | sh -s 32 | 33 | # 要安装的版本 34 | # 有的镜像只有一个版本,没有 install-sources.yaml 35 | # 因此提取不到 $source_id,此时 $source_id 参数为空 36 | if [ -n "$source_id" ]; then 37 | sed -i "s/@SOURCE_ID@/$source_id/" /autoinstall.yaml 38 | else 39 | sed -i "/@SOURCE_ID@/d" /autoinstall.yaml 40 | fi 41 | 42 | # 内核风味 43 | # https://bugs.launchpad.net/subiquity/+bug/1989353 44 | sed -i "s/generic/$kernel/" /run/kernel-meta-package 45 | sed -i "/package:/s/generic/$kernel/" /autoinstall.yaml 46 | 47 | # 跳过最后的更新 48 | cp /usr/sbin/chroot /usr/sbin/chroot.bin 49 | cat >/usr/sbin/chroot <<EOF 50 | #!/bin/sh 51 | [ "\$2" = "unattended-upgrades" ] || /usr/sbin/chroot.bin "\$@" 52 | EOF 53 | 54 | # 禁用 DNS 强制离线安装内核和跳过最后的更新 55 | # 但安装器会配置时区和写入最近的mirror到/etc/apt/sources.list 所以要提前解析 56 | # dig会显示cname结果,cname会以.结尾,grep -v '\.#39; 表示去除 cname 结果 57 | # echo $(dig +short geoip.ubuntu.com | grep -v '\.#39; | head -1) geoip.ubuntu.com >>/etc/hosts 58 | # sed -i -E 's/(^nameserver )/#\1/' /etc/resolv.conf 59 | late-commands: 60 | - | 61 | # root ssh 登录 62 | echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf 63 | 64 | # 还原 DNS 65 | # sed -i -E 's/^#(nameserver )/\1/' /etc/resolv.conf 66 | 67 | # 提取 extra_confhome 68 | prefix=extra 69 | for var in $(grep -o "\b${prefix}_[^ ]*" /proc/cmdline | xargs); do 70 | eval "$(echo $var | sed -E "s/${prefix}_([^=]*)=(.*)/\1='\2'/")" 71 | done 72 | 73 | # 下载合并分区脚本 74 | cd /target 75 | curl -LO $confhome/resize.sh 76 | 77 | # 升级 cloud-init 78 | # curtin in-target --target=/target -- apt update 79 | # curtin in-target --target=/target -- apt install --only-upgrade cloud-init 80 | user-data: 81 | runcmd: 82 | - | 83 | # 合并分区 84 | bash /resize.sh 85 | disable_root: false 86 | users: 87 | - name: root 88 | lock_passwd: false 89 | chpasswd: 90 | expire: false 91 | # 20.04 arm 需要 92 | list: | 93 | root:123@@@ 94 | users: 95 | - name: root 96 | password: 123@@@ 97 | type: text 98 | -------------------------------------------------------------------------------- /windows-allow-ping.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | setlocal EnableDelayedExpansion 4 | 5 | rem https://learn.microsoft.com/troubleshoot/windows-server/networking/netsh-advfirewall-firewall-control-firewall-behavior#command-example-4-configure-icmp-settings 6 | rem 旧版命令 netsh firewall set icmpsetting 8 对应的配置是:文件和打印机共享(回显请求 - ICMPv4-In) 7 | 8 | set ICMPv4EchoTypeNum=8 9 | set ICMPv6EchoTypeNum=128 10 | 11 | for %%i in (4, 6) do ( 12 | netsh advfirewall firewall add rule ^ 13 | name="ICMP Echo Request (ICMPv%%i-In)" ^ 14 | dir=in ^ 15 | action=allow ^ 16 | program=System ^ 17 | protocol=ICMPv%%i:!ICMPv%%iEchoTypeNum!,any 18 | ) 19 | 20 | rem 删除此脚本 21 | del "%~f0" 22 | -------------------------------------------------------------------------------- /windows-change-rdp-port.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | 4 | rem set RdpPort=3333 5 | 6 | rem https://learn.microsoft.com/windows-server/remote/remote-desktop-services/clients/change-listening-port 7 | rem HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules 8 | 9 | rem RemoteDesktop-Shadow-In-TCP 10 | rem v2.33|Action=Allow|Active=TRUE|Dir=In|Protocol=6|App=%SystemRoot%\system32\RdpSa.exe|Name=@FirewallAPI.dll,-28778|Desc=@FirewallAPI.dll,-28779|EmbedCtxt=@FirewallAPI.dll,-28752|Edge=TRUE|Defer=App| 11 | 12 | rem RemoteDesktop-UserMode-In-TCP 13 | rem v2.33|Action=Allow|Active=TRUE|Dir=In|Protocol=6|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28775|Desc=@FirewallAPI.dll,-28756|EmbedCtxt=@FirewallAPI.dll,-28752| 14 | 15 | rem RemoteDesktop-UserMode-In-UDP 16 | rem v2.33|Action=Allow|Active=TRUE|Dir=In|Protocol=17|LPort=3389|App=%SystemRoot%\system32\svchost.exe|Svc=termservice|Name=@FirewallAPI.dll,-28776|Desc=@FirewallAPI.dll,-28777|EmbedCtxt=@FirewallAPI.dll,-28752| 17 | 18 | rem 设置端口 19 | reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d %RdpPort% /f 20 | 21 | rem 设置防火墙 22 | rem 各个版本的防火墙自带的 rdp 规则略有不同 23 | rem 全部版本都有: program=%SystemRoot%\system32\svchost.exe service=TermService 24 | rem win7 还有: program=System service= 25 | rem 以下为并集 26 | for %%a in (TCP, UDP) do ( 27 | netsh advfirewall firewall add rule ^ 28 | name="Remote Desktop - Custom Port (%%a-In)" ^ 29 | dir=in ^ 30 | action=allow ^ 31 | service=any ^ 32 | protocol=%%a ^ 33 | localport=%RdpPort% 34 | ) 35 | 36 | rem 家庭版没有 rdp 服务 37 | sc query TermService 38 | if %errorlevel% == 1060 goto :del 39 | 40 | rem 重启服务 可以用 sc 或者 net 41 | rem UmRdpService 依赖 TermService 42 | rem sc stop 不能处理依赖关系,因此 sc stop TermService 前需要 sc stop UmRdpService 43 | rem net stop 可以处理依赖关系 44 | rem sc stop 是异步的,net stop 不是异步,但有 timeout 时间 45 | rem TermService 运行后,UmRdpService 会自动运行 46 | 47 | rem 如果刚好系统在启动 rdp 服务,则会失败,因此要用 goto 循环 48 | rem The Remote Desktop Services service could not be stopped. 49 | 50 | rem 有的机器会死循环,开机 logo 不断转圈 51 | rem 通过 netstat netstat -ano 可以看到端口已修改成功,但rdp服务不断重启 (pid一直改变) 52 | rem 因此限定重试次数避免死循环 53 | 54 | set retryCount=5 55 | 56 | :restartRDP 57 | if %retryCount% LEQ 0 goto :del 58 | net stop TermService /y && net start TermService || ( 59 | set /a retryCount-=1 60 | timeout 10 61 | goto :restartRDP 62 | ) 63 | 64 | :del 65 | del "%~f0" 66 | -------------------------------------------------------------------------------- /windows-del-gpo.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | setlocal enabledelayedexpansion 4 | 5 | set "files[1]=%windir%\System32\GroupPolicy\gpt.ini" 6 | set "files[2]=%windir%\System32\GroupPolicy\Machine\Scripts\scripts.ini" 7 | 8 | for %%i in (1 2) do ( 9 | set "ini=!files[%%i]!" 10 | if exist "!ini!.orig" ( 11 | move /y "!ini!.orig" "!ini!" 12 | ) else ( 13 | del "!ini!" 14 | ) 15 | ) 16 | 17 | del "%~f0" 18 | -------------------------------------------------------------------------------- /windows-driver-utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | # shellcheck shell=dash 3 | # shellcheck disable=SC3001,SC3003,SC3010 4 | # reinstall.sh / trans.sh 共用此文件 5 | 6 | # grep 无法处理 UTF-16LE 编码的 inf,有以下几种解决方法 7 | # 1. 使用 ripgrep (rg) 或者 ugrep,但 cygwin 没有 8 | # 2. grep -a a.b.c.d 9 | # 3. iconv -f UTF-16 -t UTF-8 10 | 11 | del_inf_comment() { 12 | sed 's/;.*//' 13 | } 14 | 15 | simply_inf() { 16 | convert_file_to_utf8 "$1" | del_cr | del_inf_comment | trim | del_empty_lines 17 | } 18 | 19 | convert_file_to_utf8() { 20 | # ash 用 * 比较字符串有问题 21 | # [[ #39;\xEF\xBB' = #39;\xEF\xBB*' ]] && echo 1 22 | 23 | # UTF-16LE without BOM 要处理吗? windows 支持这种编码的 inf? 24 | 25 | # UTF-16LE with BOM 26 | if [ "$(head -c2 "$1")" = #39;\xFF\xFE' ]; then 27 | # -f UTF-16LE -t UTF-8 会添加 UTF-8 BOM 28 | iconv -f UTF-16 -t UTF-8 "$1" 29 | 30 | # UTF-8 with BOM 31 | elif [ "$(head -c3 "$1")" = #39;\xEF\xBB\xBF' ]; then 32 | # busybox sed 不支持 33 | # sed '1s/^\xEF\xBB\xBF//' "$1" 34 | tail -c +4 "$1" 35 | 36 | # 其它 37 | else 38 | cat "$1" 39 | fi 40 | } 41 | 42 | simply_inf_word() { 43 | # 1 删除引号 " 44 | # 2 删除两边空格 45 | # 3 \ 和 .\ 换成 / 46 | # 4 连续的 / 替换成单个 / 47 | # 5 删除最前面的 / 48 | sed -E \ 49 | -e 's,",,g' \ 50 | -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' \ 51 | -e 's,\.?\\,/,g' \ 52 | -e 's,/+,/,g' \ 53 | -e 's,^/,,' 54 | } 55 | 56 | # reinstall.sh 下无法判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 true 57 | # trans.sh 下可以判断 iso 是 32 位还是 64 位,此时 mix_x86_x86_64 为 false 58 | list_files_from_inf() { 59 | local inf=$1 60 | local arch=$2 # x86 amd64 arm64 61 | local mix_x86_x86_64=$3 62 | 63 | # 所有字段不区分大小写 64 | inf_txts=$(simply_inf "$inf" | to_lower) 65 | 66 | is_match_section() { 67 | local section=$1 68 | 69 | [ "$line" = "[$section]" ] || [ "$line" = "[$section.$arch]" ] || 70 | { $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$line" = "[$section.amd64]" ]; } || 71 | { $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$line" = "[$section.x86]" ]; } 72 | } 73 | 74 | is_match_catalogfile() { 75 | local left 76 | left=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word) 77 | 78 | # catalogfile.nt 是指所有 nt ? 79 | [ "$left" = "catalogfile" ] || 80 | [ "$left" = "catalogfile.nt" ] || 81 | [ "$left" = "catalogfile.nt$arch" ] || 82 | { $mix_x86_x86_64 && [ "$arch" = x86 ] && [ "$left" = "catalogfile.ntamd64" ]; } || 83 | { $mix_x86_x86_64 && [ "$arch" = amd64 ] && [ "$left" = "catalogfile.ntx86" ]; } 84 | } 85 | 86 | is_match_manufacturer_arch() { 87 | # x86 可写 NT / NTx86, 其它必须明确架构 88 | # https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-manufacturer-section 89 | case "$arch" in 90 | x86) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NT|NTx86' ;; 91 | amd64) $mix_x86_x86_64 && regex='NT|NTx86|NTamd64' || regex='NTamd64' ;; 92 | arm64) regex='NTarm64' ;; 93 | esac 94 | 95 | # 注意 cut awk 结果不同 96 | # 虽然在这里不会造成影响 97 | # echo 1 | cut -d, -f2- 98 | # 1 99 | # echo 1 | awk -F, '{print $2}' 100 | # 空白 101 | 102 | echo "$line" | awk -F, '{for(i=2;i<=NF;i++) print $i}' | grep -Eiwq "$regex" 103 | } 104 | 105 | # 还需要从 [Strings] 读取字符串? 106 | 107 | # 0. 检测 inf 是否适合当前架构 108 | # 目前没有对比版本号 109 | 110 | ############################################## 111 | # 注意这种情况, NTamd64.6.0 为空,表示不支持 6.0 112 | 113 | # [Manufacturer] 114 | # %V_INTEL% = Intel, NTamd64.6.0, NTamd64.6.1.1 115 | 116 | # [Intel.NTamd64.6.0] 117 | # ; Empty section. 118 | 119 | # 如果后期改成不从 Manufacturer 获取支持的架构,而是从[]获取支持的架构,注意这种情况 120 | # [Intel.NTamd64.10.0.1..22000] 121 | ############################################## 122 | 123 | # 例子1 124 | # [Manufacturer] 125 | # %Amazon% = AWSNVME, NTamd64, NTARM64 126 | 127 | # 例子2 128 | # [Manufacturer] 129 | # %MyName% = MyName,NTx86.6.0,NTx86.5.1, 130 | # . 131 | # [MyName.NTx86.6.0] ; Empty section, so this INF does not support 132 | # . ; NT 6.0 and later. 133 | # . 134 | # [MyName.NTx86.5.1] ; Used for NT 5.1 and later 135 | # . ; (but not NT 6.0 and later due to the NTx86.6.0 entry) 136 | # %MyDev% = InstallB,hwid 137 | # . 138 | # [MyName] ; Empty section, so this INF does not support 139 | # . ; Win2000 140 | # . 141 | 142 | # 例子3 143 | # 系统自带的驱动,没有 [Manufacturer] 144 | 145 | # 例子4 146 | # C:\Windows\INF\wfcvsc.inf 147 | # %StdMfg%=Standard,NTamd64...0x0000001,NTamd64...0x0000002,NTamd64...0x0000003 148 | 149 | in_section=false 150 | arch_matched=false 151 | has_manufacturer=false 152 | # 未添加 IFS= 时,read 会删除行首行尾的空白字符 153 | while read -r line; do 154 | if [[ "$line" = "["* ]]; then 155 | is_match_section manufacturer && has_manufacturer=true && in_section=true || in_section=false 156 | continue 157 | fi 158 | 159 | if $in_section; then 160 | if is_match_manufacturer_arch; then 161 | arch_matched=true 162 | break 163 | fi 164 | fi 165 | done < <(echo "$inf_txts") 166 | 167 | if $has_manufacturer && ! $arch_matched; then 168 | return 10 169 | fi 170 | 171 | # 1. 输出 .inf 文件名 172 | basename "$inf" 173 | 174 | # 2. 输出 .cat 相对路径 175 | # 例子 176 | # [version] 177 | # CatalogFile = "xxxxx.cat" 178 | # CatalogFile.NTAMD64=Balloon.cat 179 | in_section=false 180 | # 未添加 IFS= 时,read 会删除行首行尾的空白字符 181 | while read -r line; do 182 | if [[ "$line" = "["* ]]; then 183 | is_match_section version && in_section=true || in_section=false 184 | continue 185 | fi 186 | 187 | if $in_section && is_match_catalogfile; then 188 | echo "$line" | awk -F= '{print $2}' | simply_inf_word 189 | fi 190 | done < <(echo "$inf_txts") 191 | 192 | # 3. 获取 SourceDisksNames 193 | # 例子 194 | # [SourceDisksNames] 195 | # 1 = "Windows NT CD-ROM",file.tag,, "\common" 196 | SourceDisksNames= 197 | in_section=false 198 | # 未添加 IFS= 时,read 会删除行首行尾的空白字符 199 | while read -r line; do 200 | if [[ "$line" = "["* ]]; then 201 | is_match_section sourcedisksnames && in_section=true || in_section=false 202 | continue 203 | fi 204 | # 注意可能有空格和引号 205 | 206 | if $in_section; then 207 | local num dir 208 | num=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word) 209 | dir=$(echo "$line" | awk -F, '{print $4}' | simply_inf_word) 210 | # 每行一条记录 211 | if [ -n "$SourceDisksNames" ]; then 212 | SourceDisksNames=$SourceDisksNames#39;\n' 213 | fi 214 | SourceDisksNames="$SourceDisksNames$num:$dir" 215 | fi 216 | done < <(echo "$inf_txts") 217 | 218 | # 4. 打印 SourceDisksFiles 的绝对路径 219 | # 例子 220 | # [SourceDisksFiles] 221 | # aha154x.sys = 1 , "\x86" ,, 222 | in_section=false 223 | # 未添加 IFS= 时,read 会删除行首行尾的空白字符 224 | while read -r line; do 225 | if [[ "$line" = "["* ]]; then 226 | is_match_section sourcedisksfiles && in_section=true || in_section=false 227 | continue 228 | fi 229 | 230 | if $in_section; then 231 | file=$(echo "$line" | awk -F= '{print $1}' | simply_inf_word) 232 | num=$(echo "$line" | awk -F'=|,' '{print $2}' | simply_inf_word) 233 | sub_dir=$(echo "$line" | awk -F, '{print $2}' | simply_inf_word) 234 | # 可能有多个 235 | while IFS= read -r parent_dir; do 236 | echo "$parent_dir/$sub_dir/$file" | simply_inf_word 237 | done < <(echo "$SourceDisksNames" | awk -F: "\$1==\"$num\" {print \$2}") 238 | fi 239 | done < <(echo "$inf_txts") 240 | } 241 | 242 | # windows 安装驱动时,只会安装相同架构的驱动文件到系统,即使 inf 里有列出其它架构的驱动 243 | # 因此 DISM 导出驱动时,也就没有包含其它架构的驱动文件 244 | 245 | # 用于尽可能匹配路径大小写 246 | get_path_in_correct_case() { 247 | # 同时支持参数和管道 248 | local path 249 | path=$({ if [ -n "$1" ]; then echo "$1"; else cat; fi; }) 250 | 251 | # 用 / 分割路径,提取成列表 252 | # 例如: ///a///b/c.inf -> a b c.inf 253 | # shellcheck disable=SC2046 254 | set -- $(echo "$path" | grep -o '[^/]*') 255 | ( 256 | local output= 257 | if is_absolute_path "$path"; then 258 | cd / 259 | output=/ 260 | fi 261 | 262 | stop_find=false 263 | 264 | while [ $# -gt 0 ]; do 265 | local part=$1 266 | local tmp 267 | # shellcheck disable=SC2010 268 | if ! $stop_find; then 269 | if tmp=$(ls -1 | grep -Fix "$part"); then 270 | part=$tmp 271 | # 大于 1 表示当前 part 是目录 272 | if [ $# -gt 1 ]; then 273 | if ! cd "$part" 2>/dev/null; then 274 | warn "Can't cd $path" 275 | stop_find=true 276 | fi 277 | fi 278 | else 279 | stop_find=true 280 | fi 281 | fi 282 | 283 | if [ $# -gt 1 ]; then 284 | output="$output$part/" 285 | else 286 | # 最后 part 287 | output="$output$part" 288 | fi 289 | shift 290 | done 291 | 292 | echo "$output" 293 | ) 294 | } 295 | 296 | is_file_or_link() { 297 | # -e / -f 坏软连接,返回 false 298 | # -L 坏软连接,返回 true 299 | [ -f "$1" ] || [ -L "$1" ] 300 | } 301 | 302 | find_file_ignore_case() { 303 | # 同时支持参数和管道 304 | local path 305 | path=$({ if [ -n "$1" ]; then echo "$1"; else cat; fi; }) 306 | 307 | path=$(get_path_in_correct_case "$path") 308 | if is_file_or_link "$path"; then 309 | echo "$path" 310 | else 311 | warn "Can't find $path" >&2 312 | return 1 313 | fi 314 | } 315 | 316 | parse_inf_and_cp_driever() { 317 | local inf=$1 318 | local dst=$2 319 | local arch=$3 320 | local mix_x86_x86_64=$4 321 | 322 | info false "Add driver: $inf" 323 | 324 | # 首先创建目录,否则无法通过 ls 文件数得到编号 325 | mkdir -p "$dst" 326 | # shellcheck disable=SC2012 327 | inf_index=$(($(ls -1 "$dst" | wc -l) + 1)) 328 | inf_old_dir=$(dirname "$inf") 329 | inf_new_dir=$dst/$inf_index 330 | if driver_files=$(list_files_from_inf "$inf" "$arch" "$mix_x86_x86_64"); then 331 | mkdir -p "$inf_new_dir" 332 | ( 333 | cd "$inf_old_dir" || error_and_exit "Can't cd $inf_old_dir" 334 | while read -r file; do 335 | if file=$(find_file_ignore_case "$file"); then 336 | cp -v --parents "$file" "$inf_new_dir" 337 | fi 338 | done < <(echo "$driver_files") 339 | ) 340 | else 341 | if [ $? -eq 10 ]; then 342 | warn "$inf arch not match." 343 | else 344 | error_and_exit "Unknown error while parse $inf." 345 | fi 346 | fi 347 | } 348 | 349 | get_sys_dir_for_eth() { 350 | ( 351 | cd "$(readlink -f "/sys/class/net/$1")" || error_and_exit "Can't cd to $1" 352 | while ! [ "$(pwd)" = / ]; do 353 | # DRIVER=virtio-pci 354 | # PCI_CLASS=20000 # 2 开头表示网络设备 355 | # PCI_ID=1AF4:1041 356 | # PCI_SUBSYS_ID=1AF4:1100 357 | # PCI_SLOT_NAME=0000:03:00.0 358 | if [ -f uevent ] && grep -q 'PCI_CLASS=2' uevent && grep -q 'PCI_ID' uevent; then 359 | pwd 360 | return 361 | fi 362 | cd .. 363 | done 364 | return 1 365 | ) 366 | } 367 | -------------------------------------------------------------------------------- /windows-frpc.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | 4 | rem Windows Deferder 会误报,因此要添加白名单 5 | powershell -ExecutionPolicy Bypass -Command "Add-MpPreference -ExclusionPath '%SystemDrive%\frpc\frpc.exe'" 6 | 7 | rem 启用日志 8 | rem wevtutil set-log Microsoft-Windows-TaskScheduler/Operational /enabled:true 9 | 10 | rem 创建计划任务并立即运行 11 | schtasks /Create /TN "frpc" /XML "%SystemDrive%\frpc\frpc.xml" 12 | schtasks /Run /TN "frpc" 13 | del "%SystemDrive%\frpc\frpc.xml" 14 | 15 | rem win10+ 在首次登录后计划任务才生效 16 | rem 即使手动重启,计划任务也没有运行 17 | 18 | rem 如果 10 秒内有 frpc 进程,则代表计划任务已经生效,不需要首次登录 19 | rem 如果 10 秒后也没有 frpc 进程,则需要临时改用 SYSTEM 用户运行计划任务 20 | for /L %%i in (1,1,10) do ( 21 | timeout 1 22 | tasklist /FI "IMAGENAME eq frpc.exe" | find /I "frpc.exe" && ( 23 | goto :end 24 | ) 25 | ) 26 | 27 | rem 临时改用 SYSTEM 用户运行计划任务,运行后再改回 Local Service 用户 28 | schtasks /Change /TN "frpc" /RU "S-1-5-18" 29 | schtasks /Run /TN "frpc" 30 | schtasks /Change /TN "frpc" /RU "S-1-5-19" 31 | 32 | :end 33 | rem 删除此脚本 34 | del "%~f0" 35 | -------------------------------------------------------------------------------- /windows-frpc.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bin456789/reinstall/02ae82128f96702a4c0caade2414e8457434fe1d/windows-frpc.xml -------------------------------------------------------------------------------- /windows-resize.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | 4 | set C=%SystemDrive:~0,1% 5 | for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<installer\>"') do (echo select vol %%a & echo delete partition) | diskpart 6 | for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<%C%\>"') do (echo select vol %%a & echo extend) | diskpart 7 | del "%~f0" 8 | -------------------------------------------------------------------------------- /windows-set-netconf.bat: -------------------------------------------------------------------------------- 1 | rem set mac_addr=11:22:33:aa:bb:cc 2 | 3 | rem set ipv4_addr=192.168.1.2/24 4 | rem set ipv4_gateway=192.168.1.1 5 | rem set ipv4_dns1=192.168.1.1 6 | rem set ipv4_dns2=192.168.1.2 7 | 8 | rem set ipv6_addr=2222::2/64 9 | rem set ipv6_gateway=2222::1 10 | rem set ipv6_dns1=::1 11 | rem set ipv6_dns2=::2 12 | 13 | @echo off 14 | mode con cp select=437 >nul 15 | setlocal EnableDelayedExpansion 16 | 17 | rem 禁用 IPv6 地址标识符的随机化,防止 IPv6 和后台面板不一致 18 | netsh interface ipv6 set global randomizeidentifiers=disabled 19 | 20 | rem 检查是否定义了 MAC 地址 21 | if defined mac_addr ( 22 | for /f %%a in ('wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex ^| findstr [0-9]') do set id=%%a 23 | if defined id ( 24 | rem 配置静态 IPv4 地址和网关 25 | if defined ipv4_addr if defined ipv4_gateway ( 26 | rem gwmetric 默认值为 1,自动跃点需设为 0 27 | netsh interface ipv4 set address !id! static !ipv4_addr! gateway=!ipv4_gateway! gwmetric=0 28 | ) 29 | 30 | rem 配置静态 IPv4 DNS 服务器 31 | for %%i in (1, 2) do ( 32 | if defined ipv4_dns%%i ( 33 | netsh interface ipv4 add | findstr "dnsservers" 34 | if ErrorLevel 1 ( 35 | rem vista 36 | netsh interface ipv4 add dnsserver !id! !ipv4_dns%%i! %%i 37 | ) else ( 38 | rem win7 39 | netsh interface ipv4 add dnsservers !id! !ipv4_dns%%i! %%i no 40 | ) 41 | ) 42 | ) 43 | 44 | rem 配置 IPv6 地址和网关 45 | if defined ipv6_addr if defined ipv6_gateway ( 46 | netsh interface ipv6 set address !id! !ipv6_addr! 47 | netsh interface ipv6 add route prefix=::/0 !id! !ipv6_gateway! 48 | ) 49 | 50 | rem 配置 IPv6 DNS 服务器 51 | for %%i in (1, 2) do ( 52 | if defined ipv6_dns%%i ( 53 | netsh interface ipv6 add | findstr "dnsservers" 54 | if ErrorLevel 1 ( 55 | rem vista 56 | netsh interface ipv6 add dnsserver !id! !ipv6_dns%%i! %%i 57 | ) else ( 58 | rem win7 59 | netsh interface ipv6 add dnsservers !id! !ipv6_dns%%i! %%i no 60 | ) 61 | ) 62 | ) 63 | ) 64 | ) 65 | 66 | rem 删除此脚本 67 | del "%~f0" 68 | -------------------------------------------------------------------------------- /windows-setup.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con cp select=437 >nul 3 | 4 | rem 还原 setup.exe 5 | rename X:\setup.exe.disabled setup.exe 6 | 7 | rem 等待 10 秒才自动安装 8 | cls 9 | for /l %%i in (10,-1,1) do ( 10 | echo Press Ctrl+C within %%i seconds to cancel the automatic installation. 11 | call :sleep 1000 12 | cls 13 | ) 14 | 15 | rem win7 find 命令在 65001 代码页下有问题,仅限 win 7 16 | rem findstr 就正常,但安装程序又没有 findstr 17 | rem echo a | find "a" 18 | 19 | rem 使用高性能模式 20 | rem https://learn.microsoft.com/windows-hardware/manufacture/desktop/capture-and-apply-windows-using-a-single-wim 21 | rem win8 pe 没有 powercfg 22 | powercfg /s SCHEME_MIN 2>nul 23 | 24 | rem 安装 SCSI 驱动 25 | if exist X:\drivers\ ( 26 | for /f "delims=" %%F in ('dir /s /b "X:\drivers\*.inf" 2^>nul') do ( 27 | call :drvload_if_scsi "%%~F" 28 | ) 29 | 30 | rem 官网写了可以安装但仅会加载关键驱动 31 | rem Gcore 的 virtio-gpu 在安装时没有显示 32 | rem 即使安装时加载了显卡驱动 33 | rem 进入系统后才有显示 34 | rem find /i "viogpudo" "%%~F" >nul 35 | rem if not errorlevel 1 ( 36 | rem drvload "%%~F" 37 | rem ) 38 | ) 39 | 40 | rem 安装自定义 SCSI 驱动 41 | rem 可以用 forfiles /p X:\custom_drivers /m *.inf /c "cmd /c echo @path" 42 | rem 不可以用 for %%F in ("X:\custom_drivers\*\*.inf") 43 | if exist X:\custom_drivers\ ( 44 | for /f "delims=" %%F in ('dir /s /b "X:\custom_drivers\*.inf" 2^>nul') do ( 45 | call :drvload_if_scsi "%%~F" 46 | ) 47 | ) 48 | 49 | rem 等待加载分区 50 | call :sleep 5000 51 | echo rescan | diskpart 52 | 53 | rem 判断 efi 还是 bios 54 | rem 或者用 https://learn.microsoft.com/windows-hardware/manufacture/desktop/boot-to-uefi-mode-or-legacy-bios-mode 55 | rem pe 下没有 mountvol 56 | echo list vol | diskpart | find "efi" && ( 57 | set BootType=efi 58 | ) || ( 59 | set BootType=bios 60 | ) 61 | 62 | rem 获取 ProductType 63 | rem for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions" /v ProductType') do ( 64 | rem set "ProductType=%%a" 65 | rem ) 66 | 67 | rem 获取 BuildNumber 68 | for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do ( 69 | set "BuildNumber=%%a" 70 | ) 71 | 72 | rem 获取 installer 卷 id 73 | for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find "installer"') do ( 74 | set "VolIndex=%%a" 75 | ) 76 | 77 | rem 将 installer 分区设为 Y 盘 78 | (echo select vol %VolIndex% & echo assign letter=Y) | diskpart 79 | 80 | rem 旧版安装程序会自动在 C 盘设置虚拟内存 81 | rem 新版安装程序(24h2)不会自动设置虚拟内存 82 | rem 在 installer 分区创建虚拟内存,不用白不用 83 | call :createPageFile 84 | 85 | rem 查看虚拟内存 86 | rem wmic pagefile 87 | 88 | rem 获取主硬盘 id 89 | rem vista pe 没有 wmic,因此用 diskpart 90 | (echo select vol %VolIndex% & echo list disk) | diskpart | find "* Disk " > X:\disk.txt 91 | for /f "tokens=3" %%a in (X:\disk.txt) do ( 92 | set "DiskIndex=%%a" 93 | ) 94 | del X:\disk.txt 95 | 96 | rem 这个变量会被 trans.sh 修改 97 | set is4kn=0 98 | if "%is4kn%"=="1" ( 99 | set EFISize=260 100 | ) else ( 101 | set EFISize=100 102 | ) 103 | 104 | rem 重新分区/格式化 105 | (if "%BootType%"=="efi" ( 106 | echo select disk %DiskIndex% 107 | 108 | echo select part 1 109 | echo delete part override 110 | echo select part 2 111 | echo delete part override 112 | echo select part 3 113 | echo delete part override 114 | 115 | echo create part efi size=%EFISize% 116 | echo format fs=fat32 quick 117 | 118 | echo create part msr size=16 119 | 120 | echo create part primary 121 | echo format fs=ntfs quick 122 | rem echo assign letter=Z 123 | ) else ( 124 | echo select disk %DiskIndex% 125 | 126 | echo select part 1 127 | rem echo delete part override 128 | rem echo create part primary 129 | echo format fs=ntfs quick 130 | echo active 131 | rem echo assign letter=Z 132 | )) > X:\diskpart.txt 133 | 134 | rem 使用 diskpart /s ,出错不会执行剩下的 diskpart 命令 135 | diskpart /s X:\diskpart.txt 136 | del X:\diskpart.txt 137 | 138 | rem 盘符 139 | rem X boot.wim (ram) 140 | rem Y installer 141 | rem Z os 142 | 143 | rem 旧版安装程序会自动在C盘设置虚拟内存,新版安装程序(24h2)不会 144 | rem 如果不创建虚拟内存,1g 内存的机器安装时会报错/杀进程 145 | if %BuildNumber% GEQ 26040 ( 146 | rem 已经在 installer 分区创建了虚拟内存,约等于 boot.wim 的大小,因此这步不需要 147 | rem vista/2008 没有删除 boot.wim,200M预留空间-(文件系统占用+驱动占用)后,实测能创建1个64M虚拟内存文件 148 | rem call :createPageFileOnZ 149 | ) 150 | 151 | rem 设置应答文件的主硬盘 id 152 | set "file=X:\windows.xml" 153 | set "tempFile=X:\tmp.xml" 154 | 155 | set "search=%%disk_id%%" 156 | set "replace=%DiskIndex%" 157 | 158 | (for /f "delims=" %%i in (%file%) do ( 159 | set "line=%%i" 160 | 161 | setlocal EnableDelayedExpansion 162 | echo !line:%search%=%replace%! 163 | endlocal 164 | 165 | )) > %tempFile% 166 | move /y %tempFile% %file% 167 | 168 | 169 | rem https://github.com/pbatard/rufus/issues/1990 170 | for %%a in (RAM TPM SecureBoot) do ( 171 | reg add HKLM\SYSTEM\Setup\LabConfig /t REG_DWORD /v Bypass%%aCheck /d 1 /f 172 | ) 173 | 174 | rem 设置 175 | set ForceOldSetup=0 176 | set EnableUnattended=1 177 | set EnableEMS=0 178 | 179 | rem 运行 ramdisk X:\setup.exe 的话 180 | rem vista 会找不到安装源 181 | rem server 23h2 会无法运行 182 | rem 使用 /installfrom 可以解决? 183 | if "%ForceOldSetup%"=="1" ( 184 | set setup=Y:\sources\setup.exe 185 | ) else ( 186 | set setup=Y:\setup.exe 187 | ) 188 | 189 | if "%EnableUnattended%"=="1" ( 190 | set Unattended=/unattend:X:\windows.xml 191 | ) 192 | 193 | rem 新版安装程序默认开了 Compact OS 194 | 195 | rem 新版安装程序不会创建 BIOS MBR 引导 196 | rem 因此要回退到旧版,或者手动修复 MBR 197 | rem server 2025 + bios 也是 198 | rem 但是 server 2025 官网写支持 bios 199 | rem TODO: 使用 ms-sys 可以不修复? 200 | if %BuildNumber% GEQ 26040 if "%BootType%"=="bios" ( 201 | rem set ForceOldSetup=1 202 | bootrec /fixmbr 203 | ) 204 | 205 | rem 旧版安装程序不会创建 winre 分区 206 | rem 新版安装程序会创建 winre 分区 207 | rem winre 分区创建在 installer 分区前面 208 | rem 禁止 winre 分区后,winre 储存在 C 盘,依然有效 209 | if %BuildNumber% GEQ 26040 if "%ForceOldSetup%"=="0" ( 210 | set ResizeRecoveryPartition=/ResizeRecoveryPartition Disable 211 | ) 212 | 213 | rem 为 windows server 打开 EMS/SAC 214 | rem 普通 windows 没有自带 SAC 组件,暂不处理 215 | rem 现在通过 trans.sh 准确检测系统是否有 SAC 组件,有则修改 EnableEMS 变量打开 EMS 216 | if "%EnableEMS%"=="1" ( 217 | rem set EMS=/EMSPort:UseBIOSSettings /EMSBaudRate:115200 218 | set EMS=/EMSPort:COM1 /EMSBaudRate:115200 219 | ) 220 | 221 | echo on 222 | %setup% %ResizeRecoveryPartition% %EMS% %Unattended% 223 | exit /b 224 | 225 | :sleep 226 | rem 没有加载网卡驱动,无法用 ping 来等待 227 | rem 没有 timeout 命令 228 | rem timeout /t 10 /nobreak 229 | echo wscript.sleep(%~1) > X:\sleep.vbs 230 | cscript //nologo X:\sleep.vbs 231 | del X:\sleep.vbs 232 | exit /b 233 | 234 | :createPageFile 235 | rem 尽量填满空间,pagefile 默认 64M 236 | for /l %%i in (1, 1, 100) do ( 237 | wpeutil CreatePageFile /path=Y:\pagefile%%i.sys >nul 2>nul && echo Created pagefile%%i.sys || exit /b 238 | ) 239 | exit /b 240 | 241 | :createPageFileOnZ 242 | wpeutil CreatePageFile /path=Z:\pagefile.sys /size=512 243 | exit /b 244 | 245 | :drvload_if_scsi 246 | rem 不要查找 Class=SCSIAdapter 因为有些驱动等号两边有空格 247 | find /i "SCSIAdapter" "%~1" >nul 248 | if not errorlevel 1 ( 249 | drvload "%~1" 250 | ) 251 | exit /b 252 | -------------------------------------------------------------------------------- /windows.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <unattend xmlns="urn:schemas-microsoft-com:unattend"> 3 | 4 | <settings pass="windowsPE"> 5 | <component name="Microsoft-Windows-Setup" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 6 | <!-- 安装过程可节省一点内存?vista 要删除不然报错 --> 7 | <EnableFirewall>false</EnableFirewall> 8 | <UserData> 9 | <AcceptEula>true</AcceptEula> 10 | <ProductKey> 11 | <Key>%key%</Key> 12 | </ProductKey> 13 | </UserData> 14 | <ImageInstall> 15 | <OSImage> 16 | <InstallFrom> 17 | <MetaData wcm:action="add"> 18 | <Key>/IMAGE/NAME</Key> 19 | <Value>%image_name%</Value> 20 | </MetaData> 21 | </InstallFrom> 22 | <InstallTo> 23 | <DiskID>%disk_id%</DiskID> 24 | <PartitionID>%installto_partitionid%</PartitionID> 25 | </InstallTo> 26 | </OSImage> 27 | </ImageInstall> 28 | <!-- 用注册表无法绕过 cpu 核数限制 --> 29 | <!-- https://github.com/pbatard/rufus/issues/1990 --> 30 | <!-- https://learn.microsoft.com/windows/iot/iot-enterprise/Hardware/System_Requirements --> 31 | <!-- <RunSynchronous> 32 | <RunSynchronousCommand wcm:action="add"> 33 | <Order>1</Order> 34 | <Path>cmd /c for %a in (RAM TPM SecureBoot) do reg add HKLM\SYSTEM\Setup\LabConfig /t REG_DWORD /v Bypass%aCheck /d 1 /f</Path> 35 | </RunSynchronousCommand> 36 | </RunSynchronous> --> 37 | </component> 38 | <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 39 | <InputLocale>%locale%</InputLocale> 40 | <SystemLocale>%locale%</SystemLocale> 41 | <UILanguage>%locale%</UILanguage> 42 | <UserLocale>%locale%</UserLocale> 43 | </component> 44 | </settings> 45 | 46 | <!-- vultr win8/8.1/2012/2012r2 在 windowsPE/Microsoft-Windows-PnpCustomizationsWinPE 下载加载气球驱动 47 | 会出现 Windows Cannot find Microsoft software license terms 错误 --> 48 | 49 | <settings pass="offlineServicing"> 50 | <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 51 | <DriverPaths> 52 | <!-- 目录为空不会报错 --> 53 | <!-- 驱动可以放在子目录 --> 54 | <PathAndCredentials wcm:action="add" wcm:keyValue="1"> 55 | <Path>X:\drivers</Path> 56 | </PathAndCredentials> 57 | <PathAndCredentials wcm:action="add" wcm:keyValue="2"> 58 | <Path>X:\custom_drivers</Path> 59 | </PathAndCredentials> 60 | </DriverPaths> 61 | </component> 62 | </settings> 63 | 64 | <settings pass="specialize"> 65 | <component name="Microsoft-Windows-Deployment" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 66 | <RunSynchronous> 67 | <!-- 大厂都要求设置高性能和从不关闭显示器 68 | https://learn.microsoft.com/en-us/azure/virtual-machines/windows/prepare-for-upload-vhd-image#set-windows-configurations-for-azure 69 | https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/migrating-latest-types.html 70 | https://support.huaweicloud.com/usermanual-ims/zh-cn_topic_0047501112.html 71 | powercfg /aliases 能显示 GUID/名称 的对应关系,vista 也能使用名称 --> 72 | <RunSynchronousCommand wcm:action="add"> 73 | <Order>1</Order> 74 | <Path>powercfg /setacvalueindex SCHEME_BALANCED SUB_VIDEO VIDEOIDLE 0</Path> 75 | </RunSynchronousCommand> 76 | <RunSynchronousCommand wcm:action="add"> 77 | <Order>2</Order> 78 | <Path>powercfg /setacvalueindex SCHEME_MIN SUB_VIDEO VIDEOIDLE 0</Path> 79 | </RunSynchronousCommand> 80 | <RunSynchronousCommand wcm:action="add"> 81 | <Order>3</Order> 82 | <Path>powercfg /setacvalueindex SCHEME_MAX SUB_VIDEO VIDEOIDLE 0</Path> 83 | </RunSynchronousCommand> 84 | <!-- 设为高性能 --> 85 | <RunSynchronousCommand wcm:action="add"> 86 | <Order>4</Order> 87 | <Path>powercfg /setactive SCHEME_MIN</Path> 88 | </RunSynchronousCommand> 89 | <!-- 启用 administrator 账户 --> 90 | <RunSynchronousCommand wcm:action="add"> 91 | <Order>5</Order> 92 | <!-- vista 没有自带 powershell --> 93 | <!-- <Path>powershell "$User = Get-WmiObject Win32_UserAccount | where SID -like *-500; $User.Disabled = $False; $User.Put()"</Path> --> 94 | <!-- win7 此时无法用 wmic useraccount --> 95 | <!-- <Path>wmic useraccount where "sid like '%-500'" set Disabled=false</Path> --> 96 | <!-- https://learn.microsoft.com/archive/technet-wiki/13813.localized-names-for-administrator-account-in-windows --> 97 | <Path>cmd /c "for %a in (Administrator Administrador Administrateur Administratör Администратор Järjestelmänvalvoja Rendszergazda) do (net user %a /active:yes && exit)"</Path> 98 | </RunSynchronousCommand> 99 | <!-- 禁用保留空间 --> 100 | <RunSynchronousCommand wcm:action="add"> 101 | <Order>6</Order> 102 | <Path>reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager /v ShippedWithReserves /t REG_DWORD /d 0 /f</Path> 103 | <!-- 此时以下命令无效 --> 104 | <!-- <Path>DISM /Online /Set-ReservedStorageState /State:Disabled</Path> --> 105 | <!-- <Path>powershell "Set-WindowsReservedStorageState -State Disabled; exit"</Path> --> 106 | </RunSynchronousCommand> 107 | <!-- win7 在此阶段找不到网卡 --> 108 | <!-- <RunSynchronousCommand wcm:action="add"> 109 | <Order>5</Order> 110 | <Path>cmd /c "if exist %SystemDrive%\windows-resize.bat (call %SystemDrive%\windows-resize.bat)"</Path> 111 | </RunSynchronousCommand> 112 | <RunSynchronousCommand wcm:action="add"> 113 | <Order>6</Order> 114 | <Path>cmd /c "if exist %SystemDrive%\windows-set-netconf.bat (call %SystemDrive%\windows-set-netconf.bat)"</Path> 115 | </RunSynchronousCommand> --> 116 | </RunSynchronous> 117 | </component> 118 | <component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 119 | <fDenyTSConnections>false</fDenyTSConnections> 120 | </component> 121 | <component name="Networking-MPSSVC-Svc" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 122 | <FirewallGroups> 123 | <FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop"> 124 | <Profile>all</Profile> 125 | <!-- HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules --> 126 | <!-- Get-NetFirewallRule | Where-Object Name -like 'RemoteDesktop*' | fl Name,DisplayName,Description,DisplayGroup,Group --> 127 | <!-- https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/networking-mpssvc-svc-firewallgroups-firewallgroup-group --> 128 | <Group>@FirewallAPI.dll,-28752</Group> 129 | <Active>%use_default_rdp_port%</Active> 130 | </FirewallGroup> 131 | </FirewallGroups> 132 | </component> 133 | <component name="Microsoft-Windows-powercpl" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 134 | <PreferredPlan>8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c</PreferredPlan> 135 | </component> 136 | <component name="Microsoft-Windows-ErrorReportingCore" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 137 | <DisableWER>1</DisableWER> 138 | </component> 139 | <component name="Microsoft-Windows-SQMApi" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 140 | <CEIPEnabled>0</CEIPEnabled> 141 | </component> 142 | </settings> 143 | 144 | <settings pass="oobeSystem"> 145 | <!-- 好像不起作用 --> 146 | <!-- <component name="Microsoft-Windows-WinRE-RecoveryAgent" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 147 | <UninstallWindowsRE>true</UninstallWindowsRE> 148 | </component> --> 149 | <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="%arch%" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 150 | <UserAccounts> 151 | <AdministratorPassword> 152 | <Value>%administrator_password%</Value> 153 | <PlainText>false</PlainText> 154 | </AdministratorPassword> 155 | </UserAccounts> 156 | <OOBE> 157 | <HideEULAPage>true</HideEULAPage> 158 | <ProtectYourPC>3</ProtectYourPC> 159 | <SkipMachineOOBE>true</SkipMachineOOBE> 160 | <SkipUserOOBE>true</SkipUserOOBE> 161 | </OOBE> 162 | <!-- 不设置时区,则使用镜像的默认时区 --> 163 | <!-- <TimeZone>China Standard Time</TimeZone> --> 164 | </component> 165 | </settings> 166 | </unattend> 167 | -------------------------------------------------------------------------------- /wmic.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string]$Namespace, 3 | [string]$Class, 4 | [string]$Filter, 5 | [string]$Properties 6 | ) 7 | 8 | $propertiesToDisplay = if ($Properties) { $Properties.Split(",") } else { @("*") } 9 | 10 | $wmiQuery = @{ 11 | Namespace = $Namespace 12 | Class = $Class 13 | } 14 | 15 | if ($Filter) { 16 | $wmiQuery.Filter = $Filter 17 | } 18 | 19 | Get-WmiObject @wmiQuery | ForEach-Object { 20 | $_.PSObject.Properties | Where-Object { 21 | -not $_.Name.StartsWith("__") -and 22 | ($propertiesToDisplay -contains $_.Name -or $propertiesToDisplay -contains "*") 23 | } | ForEach-Object { 24 | $name = $_.Name 25 | $value = $_.Value 26 | 27 | # 改成 wmic 的输出格式 28 | if ($value -is [Array]) { 29 | $formattedValue = ($value | ForEach-Object { "`"$_`"" }) -join "," 30 | Write-Output "$name={$formattedValue}" 31 | } 32 | else { 33 | Write-Output "$name=$value" 34 | } 35 | } 36 | } 37 | --------------------------------------------------------------------------------