OpenWRT与QNAP上通过PXE安装Xenial (by quqi99)


版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (


本文将打开OpenWRT dnsmasq上的PXE支持并设置和QNAP上的tftp关联,然后根据preseed自动安装Ubuntu 16.04 (注:kickstart是Redhat用于自动安装的机制)。

Set up tftp on QNAP

# NOTE: We need to configure PXE dir and authority to /Public/tftpboot in QNPA GUI, then use 'tftp' to test
# /etc/init.d/ restart
# [/share/HDA_DATA/Public/tftpboot] # ps |grep tftp
# 15861 admin      1016 S   /usr/sbin/opentftpd -i /etc/opentftpd.ini -l /share/HDA_DATA/Public/tftpboot/opentftpd.log
sudo mount -o loop /bak/images/ubuntu-16.04.2-server-amd64.iso /mnt/
mkdir /tmp/tftpboot && sudo cp -r /mnt/install/netboot/* /tmp/tftpboot/
sudo bash -c 'cat > /tmp/tftpboot/pxelinux.cfg/default << EOF
default linux 
label linux
    kernel ubuntu-installer/amd64/linux
    append vga=normal initrd=ubuntu-installer/amd64/initrd.gz --
scp -r /tmp/tftpboot/* admin@

Configure dnsmasq on OpenWRT to use external tftp server

cat >> /etc/dnsmasq.conf << EOF
/etc/init.d/dnsmasq restart

Create Preseed file on QNAP

cat > /home/httpd/ubuntu-auto.seed << EOF
## Options to set on the command line
d-i debian-installer/locale string en_US.UTF-8
d-i console-setup/ask_detect boolean false
d-i console-setup/layout string us

d-i netcfg/get_hostname string ubuntu
d-i netcfg/get_domain string local

### Clock and time zone setup
d-i time/zone string UTC
d-i clock-setup/utc boolean true
d-i clock-setup/ntp boolean false

d-i kbd-chooser/method select us

d-i mirror/country string manual
d-i mirror/http/hostname string
d-i mirror/http/directory string /ubuntu
d-i mirror/http/proxy string

d-i partman-auto/choose_recipe select root
d-i partman-auto/disk string /dev/[sv]da
d-i partman-auto/method string regular
d-i partman-auto/expert_recipe string root :: \
500 10000 1000000 ext4 \
          $primary{ } \
          $bootable{ } \
          method{ format } \
          format{ } \
          use_filesystem{ } \
          filesystem{ ext4 } \
          mountpoint{ / } .

d-i partman-basicfilesystems/no_swap boolean false
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

d-i base-installer/kernel/image string linux-virtual
d-i debian-installer/quiet  boolean false
d-i debian-installer/splash boolean false

d-i tasksel/first select openssh-server
d-i pkgsel/include string openssh-server ntp python sudo
d-i pkgsel/install-language-support boolean false
d-i pkgsel/upgrade select none
d-i pkgsel/update-policy select none
d-i pkgsel/updatedb boolean true

# Account setup
d-i passwd/root-login boolean true
d-i passwd/root-password password password
d-i passwd/root-password-again password password
d-i passwd/make-user boolean false
d-i user-setup/password-weak boolean true
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false

# Disable WEP dialog
d-i netcfg/wireless_wep string

# Security
d-i apt-setup/services-select multiselect security
d-i apt-setup/security_host string
d-i apt-setup/security_path string /ubuntu

# No multiarch by default
d-i apt-setup/multiarch string

d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true

d-i finish-install/reboot_in_progress note

d-i debian-installer/exit/halt boolean false
d-i debian-installer/exit/poweroff boolean false

# Late command for Packer to auth as root with password
d-i preseed/late_command string \
    sed -i -e 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /target/etc/ssh/sshd_config;\
    sed -i -e 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /target/etc/ssh/sshd_config

Use preseed

The configuration of domain and host name, and keymap are still being asked, even if you have them in your preseed file as shown above. So if you want to kickstart the preseeded installation without a single questions asked, append the following more options to kernel boot prompt (
console-keymaps-at/keymap=us hostname=myhost locale=en_US

## Modify the file /share/HDA_DATA/Public
/tftpbootdefault linux
label linux
    kernel ubuntu-installer/amd64/linux
    append vga=normal initrd=ubuntu-installer/amd64/initrd.gz locale=en_US keyboard-configuration/layoutcode=us ipv6.disable=1 hostname=maas auto url= --


append ks= preseed/url= vga=normal initrd=ubuntu-installer/amd64/initrd.gz --


dpkg -s virtinst &>/dev/null || sudo apt install virtinst -y
if ! [ -e "$rootdisk" ]; then
    qemu-img create -f qcow2 $rootdisk 20G
sudo bash -c 'cat >> /etc/network/interfaces << EOF
auto enp0s25
iface enp0s25 inet manual
    mtu 1500
auto br-enp0s25
iface br-enp0s25 inet static
    bridge_ports enp0s25
ifup br-enp0s25
sudo virt-install \
    --name=bootstrap \
    --connect=qemu:///system --ram=2048 --vcpus=1 --hvm \
    --virt-type=kvm \
    --pxe --boot network,hd \
    --graphics vnc --noautoconsole --os-type=linux --accelerate \
    --disk=${rootdisk},bus=virtio,format=qcow2 \
    --network=bridge=juju-vm-br,model=virtio \
    --print-xml 2 > $domain_xml
echo "test domain definition is now available at $domain_xml"


[/home/httpd] # tail -f /share/HDA_DATA/Public/tftpboot/opentftpd.log           
[02-Dec-17 19:54:25] Client /share/HDA_DATA/Public/tftpboot/pxelinux.cfg/default, 2 Blocks Served
[02-Dec-17 19:54:44] Client /share/HDA_DATA/Public/tftpboot/ubuntu-installer/amd64/linux, 5025 Blocks Served
[02-Dec-17 19:56:30] Client /share/HDA_DATA/Public/tftpboot/ubuntu-installer/amd64/initrd.gz, 28718 Blocks Served
[02-Dec-17 20:20:44] Client /share/HDA_DATA/Public/tftpboot/pxelinux.0, 31 Blocks Served
[02-Dec-17 20:20:45] Client /share/HDA_DATA/Public/tftpboot/ldlinux.c32, 84 Blocks Served
[02-Dec-17 20:20:45] Client /share/HDA_DATA/Public/tftpboot/pxelinux.cfg/default, 2 Blocks Served
[02-Dec-17 20:21:01] Client /share/HDA_DATA/Public/tftpboot/ubuntu-installer/amd64/linux, 5025 Blocks Served
[02-Dec-17 20:22:44] Client /share/HDA_DATA/Public/tftpboot/ubuntu-installer/amd64/initrd.gz, 28718 Blocks Served


sudo mkdir -p /mnt/mini
sudo mount mini.iso /mnt/mini/
mkdir ./miniiso
sudo cp -rT /mnt/mini ./miniiso

$ more ./miniiso/txt.cfg 
default install
label install
    menu label ^Install
    menu default
    kernel linux
    #append vga=788 initrd=initrd.gz --- quiet 
    append  auto=true preseed/file=/cdrom/preseed.cfg initrd=initrd.gz quiet ---
    append  auto=true console-keymaps-at/keymap=us hostname=myhost locale=en_US file=/cdrom/preseed.cfg initrd=initrd.gz quiet ---

$ cat ./miniiso/preseed.cfg
d-i netcfg/disable_autoconfig boolean true
d-i netcfg/get_nameservers string
d-i netcfg/get_ipaddress string
d-i netcfg/get_netmask string
d-i netcfg/get_gateway string
#d-i preseed/late_command string in-target wget -P /tmp/ ; in-target chmod +x /tmp/; in-target /tmp/

sudo mkisofs -D -r -V "UNATTENDED_UBUNTU" -cache-inodes -J -l -b isolinux.bin -c -no-emul-boot -boot-load-size 4 -boot-info-table -o ./mini-test.iso ./miniiso

附录 - 一个KickStart的例子

# then can visit via -, so the key line is 'url --url'
cat > /home/httpd/ks.cfg << EOF
#Generated by Kickstart Configurator
#platform=AMD64 or Intel EM64T
#System language
lang en_US
#Language modules to install
langsupport en_US
#System keyboard
keyboard us
#System mouse
#System timezone
timezone Asia/Chongqing
#Root password
rootpw --disabled
#Initial user
user hua --fullname hua --password password
#Reboot after installation
#Use text mode install
#Install OS instead of upgrade
#Use Web installation media
url --url
#System bootloader configuration
bootloader --location=mbr 
#Clear the Master Boot Record
zerombr yes
#Partition clearing information
clearpart --all --initlabel 
#Disk partitioning information
part swap --size 2048 
part /boot --fstype ext4 --size 512 
part / --fstype ext4 --size 1 --grow 
#System authorization infomation
auth  --useshadow  --enablemd5 
#Network information
network --bootproto=dhcp --device=eth0
#network --bootproto=static--ip= --netmask= --gateway= --device=eth0
#Firewall configuration
firewall --disabled 
#Do not configure the X Window System
# Additional packages to install
# Add your custom post installation script here
# Add post installation script to /usr/local/bin/ directory
ls .
# Fix locale
echo 'LANG="en_US.UTF-8"' > /etc/default/locale
echo 'LANGUAGE="en_US:en"' >> /etc/default/locale
echo 'LC_ALL="en_US.UTF-8"' >> /etc/default/locale
# Clean
apt-get -f -y install
apt-get -y autoremove
apt-get clean