├── Dockerfile.template ├── LICENSE ├── README.md ├── app ├── start.sh └── windows │ ├── setup-windows-pxe.sh │ └── windows-pxeconfig ├── dnsmasq.conf └── smb.conf /Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM resin/%%RESIN_MACHINE_NAME%%-node 2 | 3 | # Install apt deps 4 | RUN apt-get clean && apt-get update && apt-get upgrade -y && apt-get install -y \ 5 | wget \ 6 | curl \ 7 | apt-utils \ 8 | build-essential \ 9 | openssh-server \ 10 | vim \ 11 | raspberrypi-sys-mods \ 12 | dnsmasq \ 13 | samba \ 14 | genisoimage \ 15 | syslinux-common \ 16 | pxelinux \ 17 | && rm -rf /var/lib/apt/lists/* 18 | 19 | # We need wimtools from debian unstable, but everything else (above) should be stable only 20 | RUN echo "deb http://deb.debian.org/debian sid main" > /etc/apt/sources.list.d/debian-unstable.list \ 21 | && echo 'APT::Default-Release "testing";' > /etc/apt/apt.conf.d/default \ 22 | && apt-get update && apt-get install -y -t unstable wimtools \ 23 | && rm -rf /var/lib/apt/lists/* \ 24 | && rm /etc/apt/sources.list.d/debian-unstable.list 25 | 26 | # mkwinpeimg requires mkisofs, but for licensing reasons debian instead ships genisoimage 27 | RUN ln -s /usr/bin/genisoimage /usr/local/bin/mkisofs 28 | 29 | # Configure openssh 30 | RUN mkdir /var/run/sshd \ 31 | && echo 'root:resin' | chpasswd \ 32 | && sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config \ 33 | && sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config 34 | 35 | # Set up DHCP, TFTP, Samba and PXE 36 | COPY dnsmasq.conf /etc/dnsmasq.conf 37 | COPY smb.conf /etc/samba/smb.conf 38 | RUN mkdir -p /data/tftp/syslinux \ 39 | && cp /usr/lib/syslinux/modules/bios/* /data/tftp/syslinux/ \ 40 | && cp /usr/lib/syslinux/memdisk /data/tftp/ \ 41 | && cp /usr/lib/PXELINUX/pxelinux.0 /data/tftp/ 42 | 43 | # App setup 44 | WORKDIR /usr/src/app 45 | COPY app ./ 46 | 47 | # Move to / 48 | WORKDIR / 49 | 50 | ENV INITSYSTEM on 51 | 52 | # Start app 53 | CMD ["bash", "/usr/src/app/start.sh"] 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rpi-pxe-server 2 | A ready-to-go PXE + TFTP network boot server for Raspberry Pi, with Resin deployment. 3 | 4 | Want to boot a machine from the network, don't want to have to fight with all the configuration and setup yourself, and have a raspberry pi to hand? This is the solution. 5 | 6 | Tested with: 7 | * Raspberry Pi 3B 8 | * Windows 10 iso from https://www.microsoft.com/es-es/software-download/windows10ISO 9 | 10 | ## Set up 11 | 12 | 1. Set up your device, with reliable power, a network cable, and optionally wifi (if you want logging or easy access). 13 | 2. Sign up for free on [resin.io](https://dashboard.resin.io/signup), create an application, and provision it, optionally with your wifi credentials. 14 | 3. Set the following environmental variables: 15 | - RESIN_SUPERVISOR_DELTA: 1 // Enables deltas for updates keeping later changes quick 16 | 4. Clone/fork this repo, and push it to your resin.io application's repository to deploy this setup. 17 | 5. Set up your specific PXE config over samba (to /tftp), SCP (to /data/tftp), or over tftp by: 18 | 1. Uploading your PXE bootable image 19 | 2. Adding your PXE config at `pxelinux.cfg/default` 20 | 6. You're ready to go: put the device on the same network as the target machine (directly or through a router, as long as DHCP is disabled on the router), tell that target machine to boot from the network, and enjoy. 21 | 22 | You can change and push a new Dockerfile to your application if you want to carefully update your device to do this differently, or for quick changes there's an SSH port exposed that allows root login with the default password of 'resin'. 23 | 24 | ### Windows example 25 | 26 | For the specific Windows boot process this was tested with, scripts are included. See `app/windows/setup-windows-pxe.sh` in this repo (in `/usr/src/app` on the device) for full details. 27 | 28 | This script: 29 | * Builds a Windows PE image from a full Windows image. 30 | * Mounts the full Windows image within the Samba share to make it accessible. 31 | * Makes the Windows PE image bootable through PXE. 32 | 33 | To run this script: 34 | 35 | 1. Copy a Windows iso across to the device, either via samba or scp. 36 | 2. SSH into the device 37 | 3. Run `/usr/src/app/windows/setup-windows-pxe.sh ` 38 | 39 | Once this is complete, any machine attached to the device should now boot into Windows PE, from which you can start the full Windows install process. 40 | 41 | Note that it seems Microsoft's iso download process makes it easy to end up with corrupted iso's, which will typicall start up, but refuse to install. To check for this, run `md5sum` on your iso to get its md5, and google for the hash. Any valid official image should return a huge number of related results. 42 | 43 | ## Security 44 | 45 | This setup has pretty much no security - **do not connect this device to any untrusted network (e.g. the public internet)**. Root SSH is set up with a default password, and file sharing services are configure with public read/write access to the image you will be booting from. That's super convenient and effective if the device is only connected to you, but it's trivial complete control of both the device and the machine you're booting from if anybody else can connect. 46 | 47 | ## Technical details 48 | 49 | * Device will run as 192.168.0.1, and provide DHCP for the rest of the 255.255.255.0 range. 50 | * DHCP and TFTP configuration are done with Dnsmasq, see `dnsmasq.conf` (`/etc/dnsmasq.conf` on device) 51 | * TFTP is preconfigured for BIOS PXE, using files from `syslinux` and `pxelinux` (see `Dockerfile.template` for details). 52 | * A samba share is available, see `smb.conf` (`/etc/smb.conf` on device) 53 | * Direct SSH access is available to examine and change the device at runtime, or transfer files over SCP. 54 | 55 | ## Potential extensions: 56 | 57 | I'm open to PRs for these, but I don't need them myself right now, so they won't happen without help. 58 | 59 | - Preprepared config/scripts for other scenarios. 60 | - Allow setting a BOOT_IMAGE_URL environmental variable for a URL to get the boot image from. 61 | - UEFI boots. I don't know much about this, but I know this currently supports only BIOS PXE. I believe most current motherboards support this, sometimes with an option like `LAN Boot Rom`, but for very new machines/in future this may not be true. -------------------------------------------------------------------------------- /app/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | printf "\n ** Starting up **\n\n" 4 | 5 | printf "Setting ethernet ip to 192.168.0.1\n" 6 | ifconfig eth0 192.168.0.1 netmask 255.255.255.0 up 7 | 8 | printf "Setting up tftp share at /data/tftp and samba at /data/public\n" 9 | mkdir -p /data/tftp 10 | mkdir -p /data/public 11 | 12 | printf "\n ** Following journalctl logs: **\n\n" 13 | journalctl -f -------------------------------------------------------------------------------- /app/windows/setup-windows-pxe.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Takes a path to a windows image on the command line 5 | # - Builds a Windows PE image, puts it into tftp 6 | # - Mounts the Windows image within the samba share 7 | # - Sets up PXE to boot from the PE image 8 | 9 | WINDOWS_IMAGE_PATH=$1 10 | 11 | mkdir -p /data/public/windows-image 12 | mount "$WINDOWS_IMAGE_PATH" /data/public/windows-image 13 | mkwinpeimg --iso --windows-dir=/data/public/windows-image /data/tftp/winpe.iso 14 | 15 | mkdir -p /data/tftp/pxelinux.cfg 16 | cp /usr/src/app/windows/windows-pxeconfig /data/tftp/pxelinux.cfg/default 17 | 18 | printf " ** All done! Connect this device to a target machine to boot into Windows PE ** \n" 19 | printf " ** To install windows: `wpeinit`, `net use Q: \\192.168.0.1\public /user:root`, `Q:\windows-image\setup` ** \n 20 | -------------------------------------------------------------------------------- /app/windows/windows-pxeconfig: -------------------------------------------------------------------------------- 1 | MENU TITLE Network Boot Menu 2 | DEFAULT pe 3 | 4 | LABEL pe 5 | MENU LABEL Boot Windows PE from network 6 | KERNEL /memdisk 7 | INITRD winpe.iso 8 | APPEND iso raw -------------------------------------------------------------------------------- /dnsmasq.conf: -------------------------------------------------------------------------------- 1 | interface=eth0 2 | port=0 # Disable DNS, since that's already handled 3 | dhcp-range=192.168.0.2,192.168.0.253,255.255.255.0,1h 4 | dhcp-script=/bin/echo 5 | dhcp-boot=pxelinux.0 6 | #pxe-service=x86PC, "Install Linux", pxelinux 7 | enable-tftp 8 | tftp-root=/data/tftp -------------------------------------------------------------------------------- /smb.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | workgroup = WORKGROUP 3 | dns proxy = no 4 | log file = /var/log/samba/log.%m 5 | max log size = 1000 6 | syslog = 0 7 | panic action = /usr/share/samba/panic-action %d 8 | server role = standalone server 9 | passdb backend = tdbsam 10 | obey pam restrictions = yes 11 | unix password sync = yes 12 | map to guest = bad user 13 | usershare allow guests = yes 14 | 15 | [public] 16 | browsable = true 17 | read only = no 18 | guest ok = yes 19 | path = /data/public 20 | 21 | [tftp] 22 | browsable = true 23 | read only = no 24 | guest ok = yes 25 | path = /data/tftp --------------------------------------------------------------------------------