├── README.md └── pxeboot.cgi /README.md: -------------------------------------------------------------------------------- 1 | PXE Script Dispatcher 2 | --------------------- 3 | 4 | Copy or symlink pxeboot.cgi into your webserver webroot, and make it executable 5 | (chmod +x). Enable your web server to execute CGI scripts. 6 | 7 | Add the following to your dhcpd.conf to allow fetching of the iPXE boot 8 | script when running under iPXE. The file undionly.kpxe is part of the iPXE 9 | project. 10 | 11 | allow booting; 12 | next-server 10.1.1.2; 13 | if exists user-class and ( option user-class = "gPXE" or option user-class = "iPXE" ) { 14 | filename "http://your.server.here/path/to/pxeboot.cgi"; 15 | } else { 16 | filename "undionly.kpxe"; 17 | } 18 | 19 | The iPXE scripts should be named $root_url/pxeboot/.pxe. 20 | 21 | If $root_url/pxeboot/default.pxe is found, it is run if no MAC-specific script is found. 22 | 23 | $root_url is the url mentioned in the dhcpd.conf chunk above minus 24 | '/pxeboot.cgi'. 25 | 26 | If you also install pxelinux.0 in the same folder as pxeboot.cgi, it will try 27 | to load it unless any other script was found. 28 | 29 | This boot script generator should work with both gPXE and iPXE, but for any 30 | kind of sophisticated scripting only iPXE has enough features. 31 | 32 | AUTHOR 33 | ------ 34 | 35 | Robin Smidsrød 36 | 37 | COPYRIGHT 38 | --------- 39 | 40 | Copyright (C) Robin Smidsrød. All rights reserved. 41 | 42 | This script is licensed under the same terms as the iPXE project itself. 43 | 44 | SEE ALSO 45 | -------- 46 | 47 | * [iPXE command line overview](http://www.ipxe.org/cmd) 48 | * [iPXE project](http://www.ipxe.org/) 49 | * [Etherboot/gPXE project page](http://www.etherboot.org/) 50 | -------------------------------------------------------------------------------- /pxeboot.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use CGI (); 7 | 8 | # Change this line if you rename the script 9 | my $myself = "pxeboot.cgi"; 10 | my $subdir = "pxeboot"; 11 | my $ext = "pxe"; 12 | 13 | my $q = CGI->new(); 14 | 15 | # Build root url of script 16 | my $root_url = $q->url( -path_info => 1 ); 17 | $root_url =~ s{/\Q$myself\E$}{}; # Strip out filename of this script from URL 18 | 19 | # If mac query param is present, and looks like a mac address, 20 | # try to load specific script, else load chaining script 21 | my $hex = qr/[0-9a-f]{2}/; 22 | if ( $q->param('mac') and lc( $q->param('mac') ) =~ m{\A(?:$hex:){5}$hex\Z} ) { 23 | script_for_mac( lc( $q->param('mac') ) ); 24 | } 25 | else { 26 | no_params(); 27 | } 28 | 29 | exit; 30 | 31 | # Send default iPXE script that chainloads and calls script again with MAC address 32 | sub no_params { 33 | print $q->header('text/plain'), <<"EOM"; 34 | #!gpxe 35 | echo Loading PXE script for \${mac} 36 | chain $root_url/$myself?uuid=\${uuid}&mac=\${mac}&busid=\${busid}&ip=\${ip}&hostname=\${hostname:uristring}&serial=\${serial:uristring}&asset=\${asset:uristring}&manufacturer=\${manufacturer:uristring}&product=\${product:uristring} 37 | EOM 38 | return 1; 39 | } 40 | 41 | # Chainload $root_url/$subdir/.$ext 42 | # or $root_url/pxelinux.0 (if exists) 43 | # or just exit (if none found) 44 | sub script_for_mac { 45 | my ($mac) = @_; 46 | my $filename = $mac; 47 | $filename =~ s/://g; 48 | $filename = "$subdir/$filename.$ext"; 49 | my $url = "$root_url/$filename"; 50 | if ( -r $filename ) { 51 | print $q->header('text/plain'), <<"EOM"; 52 | #!gpxe 53 | echo 54 | echo Loading PXE script for $mac 55 | chain $url 56 | EOM 57 | return 1; 58 | } 59 | 60 | # Boot with pxeboot/default.$ext 61 | if ( -r "$subdir/default.$ext" ) { 62 | print $q->header('text/plain'), <<"EOM"; 63 | #!gpxe 64 | echo 65 | echo Loading $subdir/default.$ext for $mac 66 | chain $root_url/$subdir/default.$ext 67 | EOM 68 | return 1; 69 | } 70 | 71 | # Boot with default PXELinux 72 | if ( -r 'pxelinux.0' ) { 73 | print $q->header('text/plain'), <<"EOM"; 74 | #!gpxe 75 | echo 76 | echo URL unavailable: $url 77 | echo Loading PXELinux for $mac 78 | chain $root_url/pxelinux.0 79 | EOM 80 | return 1; 81 | } 82 | 83 | # Abort boot sequence if no pxelinux.0 found 84 | print $q->header('text/plain'), <<'EOM'; 85 | #!gpxe 86 | echo 87 | echo URL unavailable: $url 88 | echo No PXELinux available, aborting netboot 89 | exit 90 | EOM 91 | return 1; 92 | } 93 | --------------------------------------------------------------------------------