海运的博客

ubuntu linux vps通过ipxe网络引导alpine dd备份/恢复vps系统

发布时间:February 8, 2020 // 分类: // No Comments

alpine从硬盘grub引导到内存中运行,重启后会破坏原硬盘分区,使用alpine官方推荐的使用ipxe netboot。
生成ipxe grub引导脚本,ssh_key为后续ssh登录目标系统操作的机器ssh public key,grub引导的ipxe lkrn可自行编译

#!/bin/bash
#set -x
network=static
dns=8.8.8.8
ssh_key="ssh_key=https://www.haiyun.me/id_rsa.pub"
mirror="http://mirrors.aliyun.com/alpine/v3.11"
ipxe_file="https://www.haiyun.me/ipxe.lkrn"

valid_ip() {
  [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
  state=$?
  return $state 
}
cidr2mask() {
    value=$(( 0xffffffff ^ ((1 << (32 - $1)) - 1) ))
    echo "$(( ($value >> 24) & 0xff )).$(( ($value >> 16) & 0xff )).$(( ($value >> 8) & 0xff )).$(( $value & 0xff ))"
}
which wget &> /dev/null && which ip &> /dev/null || {
  echo '请先安装wget和ip'
  exit
}
alpine_addr="ip=dhcp"
if [ "$network" == 'static' ]; then
  address=$(ip -o -f inet addr show | awk '/scope global/ {print $4}' | head -n 1)
  addr=$(echo $address | awk -F'/' '{print $1}')
  cidr=$(echo $address | awk -F'/' '{print $2}')
  gw=$(ip rou | awk '/default via/ {print $3}')
  mask=$(cidr2mask $cidr)
  alpine_addr="ip=${addr}::${gw}:${mask}::::${dns}:"
  echo 'ip:' $addr
  echo 'route:' $gw
  echo 'netmask:' $mask
  valid_ip "$addr" && valid_ip "$mask" && valid_ip "$gw" || {
    echo '获取网络信息失败'
    exit
  }
  read -r -p "以上IP信息是否正确? [Y/n] " input
  if [[ $input != "y" && $input != "Y" ]]; then
    echo "abort"
    exit
  fi
fi

if [ -f "/etc/redhat-release" ]; then
  grubfile=/boot/grub2/grub.cfg
  grubcmd=grub2-mkconfig
else
  grubfile=/boot/grub/grub.cfg
  grubcmd=grub-mkconfig
fi
#root=`grep "set root" $grubfile|sed -e 's/^[ \t]*//'|head -n 1`
root=$(grep 'set root' $grubfile | sed -e 's/^[ \t]*//' | sort | uniq -c | head -n 1 | awk '{print $2,$3}')
if mount | grep -q /boot; then
  dir=/
else
  dir=/boot/
fi
vmlinuzfile=${dir}ipxe.lkrn
initrdfile=${dir}ipxe.initrd
wget -q $ipxe_file -O /boot/ipxe.lkrn
cat > /boot/ipxe.initrd << EOF
#!ipxe
imgfree
set net0/ip ${addr}
set net0/netmask ${mask}
set net0/gateway ${gw}
set dns ${dns}
ifopen net0

:boot
kernel ${mirror}/releases/x86_64/netboot/vmlinuz-virt ${alpine_addr} modules=loop,squashfs quiet nomodeset alpine_repo=${mirror}/main/ modloop=${mirror}/releases/x86_64/netboot/modloop-virt console=tty0 ${ssh_key} || goto boot
initrd ${mirror}/releases/x86_64/netboot/initramfs-virt || goto boot

boot || shell
EOF

[[ -f /boot/ipxe.lkrn ]] && [[ -f /boot/ipxe.initrd ]] || {
  echo '引导文件不存在'
  exit
}

cat > /etc/grub.d/40_custom << EOF
#!/bin/sh
exec tail -n +3 \$0
menuentry 'netinstall' {
$root
linux16 $vmlinuzfile
initrd16 $initrdfile
}
EOF
sed -i 's/GRUB_DEFAULT=.*/GRUB_DEFAULT="netinstall"/' /etc/default/grub
$grubcmd -o $grubfile
cat /etc/grub.d/40_custom

ssh登录到alpine系统,dd备份的系统镜像保存到sshfs挂载远程服务器上,也可使用nfs。

apk add sshfs
modprobe fuse
sshfs -p 22 www.haiyun.me:/mnt/ /mnt/
dd if=/dev/vda | gzip > /mnt/pr.img
sync
umount /mnt/

恢复备份系统的grub引导:

mount -t ext4 /dev/vda1 /mnt/
chmod 644 /mnt/boot/grub/grub.cfg
sed -i 's/default="netinstall"/default="0"/' /mnt/boot/grub/grub.cfg
chmod 444 /mnt/boot/grub/grub.cfg
sed -i 's/GRUB_DEFAULT="netinstall"/GRUB_DEFAULT="0"/' /mnt/etc/default/grub
umount /mnt/

将要dd的目标系统通过以上方法引导至alpine系统并挂载sshfs,然后将之前备份的img dd到目标系统:

gzip -dc /mnt/pr.img |dd of=/dev/vda

如果要dd的目标系统硬盘比备份的系统硬盘大,要进行linux系统分区扩容,如果要扩容的分区下面有swap分区,记住swap的扇区大小和要扩容的分区起始位置,根据总扇区大小计算要扩充的分区扇区大小,将swap分区和扩充的分区删除再新建。

apk add util-linux e2fsprogs-extra
#修改分区扇区大小及位置,方法见上面链接
fdisk /dev/vda
partprobe 
e2fsck -yf /dev/vda1
resize2fs /dev/vda1
#如果有删除并新建swap分区,后面还要修改fstab swap uuid
mkswap /dev/vda2

挂载恢复后硬盘镜像,修改目标系统的IP地址和启动项:

mount -t ext4 /dev/vda1 /mnt/
#如果有更改swap分区,修改fstab uuid
blkid
vim /mnt/etc/fstab 
vim /mnt/etc/network/interfaces
chmod 644 /mnt/boot/grub/grub.cfg
sed -i 's/default="netinstall"/default="0"/' /mnt/boot/grub/grub.cfg
chmod 444 /mnt/boot/grub/grub.cfg
sed -i 's/GRUB_DEFAULT="netinstall"/GRUB_DEFAULT="0"/' /mnt/etc/default/grub
umount /mnt/

为n1制作aarcm64/arm64 ubuntu rootfs系统

发布时间:October 20, 2018 // 分类:N1 // No Comments

安装debootstrap和qemu-user-static:

apt install apt-transport-https qemu qemu-user-static binfmt-support debootstrap

构建ubuntu 18.04系统,基础包为minbase,使用清大的源:

qemu-debootstrap --arch arm64 --variant=minbase --include=whiptail,ca-certificates,tzdata bionic rootfs http://mirrors.ustc.edu.cn/ubuntu-ports/

配置软件源:

cat > rootfs/etc/apt/sources.list <<EOF
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse
EOF

配置网络信息:

mkdir rootfs/etc/network/ 
echo 'nameserver 192.168.168.1' > rootfs/etc/resolv.conf
echo 'ubuntu-18.04' > rootfs/etc/hostname
cat > rootfs/etc/netplan/50-cloud-init.yaml <<EOF
network:
    ethernets:
        eth0:
            addresses:
            - 192.168.168.6/24
            dhcp4: false
            gateway4: 192.168.168.1
            nameservers:
                addresses:
                - 192.168.168.1
                search: []
    version: 2
EOF

挂载本地设备文件到rootfs:

mount -t proc /proc  rootfs/proc 
mount -t sysfs /sys  rootfs/sys 
mount -o bind /dev  rootfs/dev 
mount -o bind /dev/pts  rootfs/dev/pts 

chroot rootfs内配置:

LANG=C.UTF-8 chroot rootfs/  /bin/bash

在rootfs内执行:

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
apt update
apt upgrade
apt install systemd -y 
apt install wireless-regdb crda -y
apt install rsyslog udev dbus kmod openssh-server netplan.io man vim wget net-tools sysstat tmux less wireless-regdb crda dosfstools parted rng-tools -y
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
passwd root
umount /dev/pts/ /dev/ /proc/ /sys 
exit

为方便使用之前编译的内核和armbian的uInitrd、firmware文件,挂载armbian的img镜像到本地:

losetup -P -f --show Armbian_5.62_Aml-s9xxx_Ubuntu_bionic_default_4.18.7_20181012.img
mount /dev/loop3p2 /mnt
mount /dev/loop3p2 /mnt/boot
mv /mnt/boot/* rootfs/boot/
mv /mnt/lib/modules/ rootfs/lib/
#也可安装armbian的firmware-aml-4.18-20181011_5.62_arm64.deb
mv /mnt/lib/firmware/ rootfs/lib/
mv /mnt/etc/modprobe.d/ rootfs/etc/
mv /mnt/etc/fstab rootfs/etc/
mv /mnt/root/install.sh rootfs/root/

将armbain镜像内的文件全部删除,将新做的系统移动过去。

rm -rf /mnt/*
mv rootfs/boot/* /mnt/boot/
mv rootfs/* /mnt/

参考:
https://help.ubuntu.com/lts/installation-guide/s390x/apds04.html

使用kickstart安装ubuntu

发布时间:September 30, 2018 // 分类: // No Comments

preseed安装ubuntu见:https://www.haiyun.me/archives/1246.html
启动参数:

ks=https://www.haiyun.me/ubuntu-ks.cfg domain= hostname=ubuntu-server interface=auto netcfg/get_ipaddress=${ip} netcfg/get_netmask=${mask} netcfg/get_gateway=${rou} netcfg/get_nameservers=8.8.8.8 netcfg/disable_autoconfig=true

配置文件,ks不支持部分ubuntu设置,可在ks文件中嵌入preseed命令:

install
url --url=http://mirrors.aliyun.com/ubuntu/
text
skipx

unsupported_hardware
eula --agreed

#rootpw --plaintext 123456 
#echo 'import crypt,getpass; print crypt.crypt(getpass.getpass(), "$6$16_CHARACTER_SALT_HERE")' | python -
rootpw --iscrypted $6$16_CHARACTER_SAL$dvFZEFR66m38M3u3K4os2Yi4j88oTRaF9Q7XkKK4VFlMlwS9l17oTjXI043rfpNxDkB8/1ntrOiAFQGeYgwEZ.
authconfig --enableshadow --passalgo=sha512
preseed passwd/make-user boolean false

keyboard --vckeymap=us --xlayouts='us'
lang en_US.UTF-8
timezone Asia/Shanghai

firstboot --disable
firewall --disabled
selinux --disabled
reboot

#network --bootproto=static --device=eth0 --gateway=192.168.168.1 --ip=192.168.168.50 --nameserver=192.168.168.1 --netmask=255.255.255.0 --ipv6=auto --activate
#network --hostname=ubuntu-server

preseed partman-lvm/device_remove_lvm boolean true
preseed partman-md/device_remove_md boolean true
#preseed partman-lvm/confirm boolean true                                                                                                                                                                                                      
#preseed partman-lvm/confirm_nooverwrite boolean true

zerombr
clearpart --all --drives=sda
ignoredisk --only-use=sda
bootloader --location=mbr --boot-drive=sda
#autopart

#part / --asprimary --fstype ext4 --size=5120
#part swap --asprimary --size=1024
#part /home --asprimary --fstype ext4 --size=5120 --grow

part /boot --fstype ext4 --size 200 --asprimary
part swap  --size 1024 --asprimary 
part pv.01 --size 1 --grow --asprimary 
volgroup rootvg pv.01
logvol / --fstype ext4 --vgname=rootvg --size=1 --grow --name=rootlv

#preseed anna/choose_modules string network-console
#preseed network-console/password password 123456
#preseed network-console/password-again password 123456

preseed pkgsel/update-policy select none
preseed pkgsel/upgrade select none
#ubuntu-minimal
%packages
openssh-server

%post
sed -ri 's/^#?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
%end

参考:
https://help.ubuntu.com/community/KickstartCompatibility
https://help.ubuntu.com/lts/installation-guide/i386/ch04s06.html

IPXE网络引导通过kickstart和preseed自动安装centos/ubuntu/debian系统

发布时间:September 28, 2018 // 分类: // No Comments

编译ipxe,也可从netboot.xyz下载编译好的,netboot默认包含一些常用系统的安装规则。

apt install git make gcc mtools binutils liblzma-dev -y
git clone git://git.ipxe.org/ipxe.git
cd ipxe/src
sed -i -e '/DOWNLOAD_PROTO_HTTPS/ s/#undef/#define/' config/general.h
sed -i 's/#undef\tDOWNLOAD_PROTO_NFS/#define\tDOWNLOAD_PROTO_NFS/' config/general.h
sed -i 's/\/\/#define\ PING_CMD/#define\ PING_CMD/' config/general.h
sed -i 's/\/\/#define\ IPSTAT_CMD/#define\ IPSTAT_CMD/' config/general.h
sed -i 's/\/\/#define\ REBOOT_CMD/#define\ REBOOT_CMD/' config/general.h
sed -i 's/\/\/#define\ POWEROFF/#define\ POWEROFF/' config/general.h
make bin/ipxe.lkrn

如需iso:

apt install genisoimage isolinux
make bin/ipxe.iso

加入grub引导项,set root为boot目录所在分区,/ipxe.lkrn为文件相对于boot所在分区的绝对路径,如果boot为单独分区刚为/ipxe.lkrn,非单独分区为/boot/ipxe.lkrn,hd0为第一个硬盘,msdos1为第一个mbr分区,如果是gpt使用gpt1。

cat >> /etc/grub.d/40_custom <<EOF
menuentry 'ipxe boot' {
    set root='hd0,msdos1'
    linux16 /ipxe.lkrn
    initrd16 /ipxe.initrd
}
EOF
sed -i 's/GRUB_DEFAULT=.*/GRUB_DEFAULT="ipxe boot"/' /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg 

调用ipxe规则的几种方法:
1.grub引导参数和HTTP调用远程文件:

#ipxe启动后dhcp获取IP然后获取netboot规则。
linux16 /ipxe.lkrn dhcp && chain --autofree https://boot.netboot.xyz

2.本地文件ipxe.initrd:

#!ipxe
imgfree
set net0/ip 192.168.168.4
set net0/netmask 255.255.255.0
set net0/gateway 192.168.168.1
set dns 192.168.168.1
ifopen net0
chain --autofree https://boot.netboot.xyz

3.编译时也可将规则嵌入进去:

make bin/ipxe.lkrn EMBED=boot.ipxe

centos7 ipx网络安装规则:

#!ipxe
set base http://mirrors.aliyun.com/centos/7/os/x86_64
kernel ${base}/images/pxeboot/vmlinuz inst.repo=${base} ks=https://www.haiyun.me/centos7.cfg inst.vnc inst.vncpassword=12345678 net.ifnames=0 biosdevname=0 inst.headless ip=192.168.168.4::192.168.168.1:255.255.255.0::eth0:none nameserver=192.168.168.1
initrd ${base}/images/pxeboot/initrd.img
boot

生成ubuntu ipxe网络安装规则:

#!/bin/bash
set -x
network=dhcp
network=static
release=bionic
release=focal
address=192.168.1.9
netmask=255.255.255.0
gateway=192.168.1.1
nameserver=192.168.1.1
mirror="http://mirrors.aliyun.com"
mirror="http://archive.ubuntu.com"
cfg="https://www.haiyun.me/ubuntu.cfg"
file="ubuntu.ipxe"
#file="/www/ubuntu.ipxe"
if [ "$release" == 'focal' ]; then
  base=${mirror}/ubuntu/dists/${release}/main/installer-amd64/current/legacy-images/netboot/ubuntu-installer/amd64
else
  base=${mirror}/ubuntu/dists/${release}/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64
fi

if [ "$network" == 'static' ]; then
  cat > $file << EOF
#!ipxe
kernel ${base}/linux auto=true url=${cfg} keymap=us domain= hostname=ubuntu-server interface=auto netcfg/get_ipaddress=${address} netcfg/get_netmask=${netmask} netcfg/get_gateway=${gateway} netcfg/get_nameservers=${nameserver} netcfg/disable_autoconfig=true netcfg/do_not_use_netplan=true
initrd ${base}/initrd.gz
boot
EOF
else
  cat > $file << EOF
#!ipxe
kernel ${base}/linux auto=true url=${cfg} keymap=us domain= hostname=ubuntu-server interface=auto netcfg/do_not_use_netplan=true
initrd ${base}/initrd.gz
boot
EOF
fi

kickstart文件:

install
#url --url="http://mirror.centos.org/centos/7/os/x86_64/"
url --url="http://mirrors.aliyun.com/centos/7/os/x86_64/"
text
skipx
unsupported_hardware
eula --agreed

#rootpw --plaintext 123456 
#echo 'import crypt,getpass; print crypt.crypt(getpass.getpass(), "$6$16_CHARACTER_SALT_HERE")' | python -
rootpw --iscrypted $6$16_CHARACTER_SAL$dvFZEFR66m38M3u3K4os2Yi4j88oTRaF9Q7XkKK4VFlMlwS9l17oTjXI043rfpNxDkB8/1ntrOiAFQGeYgwEZ.
authconfig --enableshadow --passalgo=sha512

keyboard --vckeymap=us --xlayouts='us'
lang en_US.UTF-8
timezone Asia/Shanghai

firstboot --disable
firewall --disabled
selinux --disabled

#network --bootproto=static --device=eth0 --gateway=192.168.168.1 --ip=192.168.168.50 --nameserver=192.168.168.1 --netmask=255.255.255.0 --ipv6=auto --activate
network --hostname=centos7-x64

reboot
services --enabled="chronyd"

zerombr
clearpart --all --drives=sda
ignoredisk --only-use=sda
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
#autopart --type=lvm

#part / --asprimary --fstype ext4 --size=5120
#part swap --asprimary --size=1024
#part /home --asprimary --fstype ext4 --size=5120 --grow

part /boot --fstype ext4 --size 200 --asprimary
part swap  --size 1024 --asprimary 
part pv.01 --size 1 --grow --asprimary 
volgroup rootvg pv.01
logvol / --fstype ext4 --vgname=rootvg --size=1 --grow --name=rootlv

vnc --password=12345678

#repo --name=base --baseurl=http://mirror.centos.org/centos/7/os/x86_64/

%packages
@^minimal
@core
chrony
kexec-tools

%end

ubuntu18.04 ipx网络安装规则:

#!ipxe
set mirror https://mirrors.aliyun.com/
set release bionic
set arch amd64
set base-url ${mirror}/ubuntu/dists/${release}/main/installer-${arch}/current/images/netboot/ubuntu-installer/${arch}
kernel ${base-url}/linux auto=true url=https://www.haiyun.me/ubuntu.cfg keymap=us domain= hostname=ubuntu-server interface=auto netcfg/get_ipaddress=192.168.168.4 netcfg/get_netmask=255.255.255.0 netcfg/get_gateway=192.168.168.1 netcfg/get_nameservers=192.168.168.1 netcfg/disable_dhcp=true
initrd ${base-url}/initrd.gz
boot

preseed文件:

d-i debian-installer/locale string en_US
d-i console-setup/ask_detect boolean false
d-i keyboard-configuration/xkb-keymap select us

#使用静态IP
#d-i netcfg/choose_interface select auto
#d-i netcfg/disable_autoconfig boolean true
#d-i netcfg/dhcp_failed note
#d-i netcfg/dhcp_options select Configure network manually
#d-i netcfg/get_ipaddress string 192.168.168.4
#d-i netcfg/get_netmask string 255.255.255.0
#d-i netcfg/get_gateway string 192.168.168.1
#d-i netcfg/get_nameservers string 192.168.168.1
#d-i netcfg/confirm_static boolean true
#d-i netcfg/get_hostname string ubuntu-server
#d-i netcfg/get_domain string 
d-i hw-detect/load_firmware boolean true

d-i mirror/country string manual
#d-i mirror/http/hostname string mirrors.aliyun.com
d-i mirror/http/hostname string archive.ubuntu.com
d-i mirror/http/directory string /ubuntu
d-i mirror/http/proxy string

d-i passwd/root-login boolean ture
d-i passwd/make-user boolean false
#d-i passwd/root-password password 123456
#d-i passwd/root-password-again password 123456
#echo 'import crypt,getpass; print crypt.crypt(getpass.getpass(), "$6$16_CHARACTER_SALT_HERE")' | python -
d-i passwd/root-password-crypted password $6$16_CHARACTER_SAL$CIIxSZip5SHbUDtMlgweMCsEMqUsp4kGjo
d-i user-setup/allow-password-weak boolean true
d-i user-setup/encrypt-home boolean false

d-i clock-setup/utc boolean false
d-i time/zone string Asia/Shanghai
d-i clock-setup/ntp boolean true


#d-i partman-auto/disk string /dev/sda
d-i partman/early_command string debconf-set partman-auto/disk "$(list-devices disk | head -n1)"
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
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 partman/default_filesystem string ext4
d-i partman/mount_style select uuid


d-i partman-auto/choose_recipe select boot-root
d-i partman-auto/method string regular
d-i partman-auto/expert_recipe string                         \
      boot-root ::                                            \
              5120 1 5120 ext4                                \
                     $primary{ } $bootable{ }                 \
                     method{ format } format{ }               \
                     use_filesystem{ } filesystem{ ext4 }     \
                     mountpoint{ / }                          \
              .                                               \
              1 3 -1 ext4                                     \
                      $primary{ }                             \
                      method{ format } format{ }              \
                      use_filesystem{ } filesystem{ ext4 }    \
                      mountpoint{ /home }                     \
              .                                               \
              1024 2 1024 linux-swap                          \
                      $primary{ }                             \
                      method{ swap } format{ }                \
              .

 
#d-i partman-auto/choose_recipe select boot-root
#d-i partman-auto/method string regular
#d-i partman-auto/expert_recipe string                         \
#      boot-root ::                                            \
#              1 2 -1 ext4                                     \
#                     $primary{ }                              \
#                     method{ format } format{ }               \
#                     use_filesystem{ } filesystem{ ext4 }     \
#                     mountpoint{ / }                          \
#              .                                               \
#              128 1 128 linux-swap                            \
#                      $primary{ }                             \
#                      method{ swap } format{ }                \
#              .


#d-i partman-auto/choose_recipe select boot-lvm
#d-i partman-auto/method string lvm
#d-i partman-auto-lvm/guided_size string 100%
#d-i partman-auto-lvm/new_vg_name string vg00
#d-i partman-lvm/confirm boolean true
#d-i partman-lvm/confirm_nooverwrite boolean true
#d-i partman-auto/expert_recipe string                         \
#      boot-lvm ::                                             \
#              1024 1 1024 ext4                                \
#                      $primary{ } $bootable{ }                \
#                      method{ format } format{ }              \
#                      use_filesystem{ } filesystem{ ext4 }    \
#                      mountpoint{ /boot }                     \
#              .                                               \
#              1 2 -1 ext4                                     \
#                      $primary{ }                             \
#                      $defaultignore{ }                       \
#                      method{ lvm }                           \
#                      device{ /dev/sda }                      \
#                      vg_name{ vg00 }                         \
#              .                                               \
#              1024 3 1024 swap                                \
#                      $lvmok{ } lv_name{ lv_swap } in_vg{ vg00 } \
#                      method{ swap } format{ }                   \
#          .                                                      \
#              1 4 -1 ext4                                        \
#                      $lvmok{} lv_name{ lv_root } in_vg{ vg00 }  \
#                      method{ format } format{ }                 \
#                      use_filesystem{ } filesystem{ ext4 }       \
#                      mountpoint{ / }                            \
#          .                                                      


tasksel tasksel/first multiselect minimal
d-i pkgsel/update-policy select none
d-i pkgsel/include string openssh-server vim wget tmux net-tools software-properties-common
d-i pkgsel/upgrade select none

d-i grub-installer/only_debian boolean true
d-i grub-installer/bootdev string default
d-i finish-install/reboot_in_progress note
d-i debian-installer/exit/reboot boolean true
d-i preseed/late_command string cd /target/;\
    echo 'UseDNS no' >> etc/ssh/sshd_config;\
    echo 'AddressFamily inet' >> etc/ssh/sshd_config;\
    echo 'PermitRootLogin yes' >> etc/ssh/sshd_config;

#d-i anna/choose_modules string network-console
#d-i network-console/password password 123456
#d-i network-console/password-again password 123456

注:Centos7安装内存不得小于2G,可不使用ipxe直接下载centos/ubuntu网络安装文件到本地添加到grub自动安装,使用ipxe方便管理。
参考:
https://netboot.xyz/providers/digitalocean/
https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/installation_guide/chap-anaconda-boot-options
https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/installation_guide/sect-kickstart-syntax
https://help.ubuntu.com/lts/installation-guide/amd64/apbs02.html
https://help.ubuntu.com/lts/installation-guide/amd64/apbs04.html
https://help.ubuntu.com/lts/installation-guide/example-preseed.txt

php ssh/expect登录服务器执行命令

发布时间:April 21, 2018 // 分类:PHP // No Comments

<?php
$conn = ssh2_connect('1.1.1.1', 22);
if (!$conn) {
  die("conn fail\n");
}
if (ssh2_auth_password($conn, 'root', 'password')) {
  echo "auth sus\n";
} else {
  die("auth fail\n");
}
$stream = ssh2_exec($conn, "df  --output=avail /|tail -n 1");  
stream_set_blocking($stream, true);  
$res = trim(stream_get_contents($stream));
var_dump($res);

php使用ssh交互式执行命令:

<?php
$host = '192.168.1.1';
$port = 2222;
$pass = 'xxxx';
if (!($conn = ssh2_connect($host, $port, array('hostkey'=>'ssh-rsa')))) {
  die("conn fail\n");
}
//注意路径不要使用~/.ssh/id_rsa.pub,会遇到段错误和其它莫名其妙的问题
if (ssh2_auth_pubkey_file($conn, 'root', '/root/.ssh/id_rsa.pub', '/root/.ssh/id_rsa')) {
  echo "auth sus\n";
} else {
  die("auth fail\n");
}
function expect($stream, $match) {
  $time = time();
  $res = '';
  while(!feof($stream)){
    //if (($buffer = fgets($stream, 4096)) !== false) {
    if (($buffer = fread($stream, 4096)) !== false) {
      $res .= $buffer;
    }
    if (stristr($res, $match)) {
      return 'sus';
    }
    $now = time();
    if (($now - $time) >= 10) {
      return 'timeout';
    }
    usleep(100);
  }
  return 'disconnect';
}

$shell=ssh2_shell($conn, 'xterm');
fwrite($shell, "/usr/bin/cryptroot-unlock\n");
$res = expect($shell, 'Please unlock disk');
if ($res == 'sus') {
  fwrite($shell, "{$pass}\n");
  $res = expect($shell, 'set up successfully');
  if ($res == 'sus') {
  }
  var_dump($res);
}

php也可安装expect扩展调用ssh命令交互式执行命令:

apt install php-dev tcl-dev tcl-expect-dev
wget https://pecl.php.net/get/expect-0.4.0.tgz
tar zxvf expect-0.4.0.tgz 
cd expect-0.4.0/
 phpize
./configure
make && make install
echo 'extension=expect.so' > /etc/php/7.4/cli/conf.d/20-expect.ini
php -m|grep expect

make时如果出现错误php_expect.h:34:10: fatal error: expect_tcl.h: 没有那个文件或目录:

sed -i 's/^INCLUDES =/INCLUDES = -I\/usr\/include\/tcl8.6/' Makefile

php使用expect连接ssh执行命令:

<?php
ini_set("expect.timeout", 2);
ini_set("expect.loguser", "off");

$stream = expect_popen("ssh -o StrictHostKeyChecking=no -p 22 root@www.haiyun.me");
$cases = array(
  array("password:", "password"),
  array("Last login", "shell"),
  array("yes/no)?",  "yes/no")
);

while (true) {
  switch (expect_expectl($stream, $cases)) {
  case "password":
    fwrite($stream, "password\n");
    break;
  case "yes/no":
    fwrite($stream, "yes\n");
    break;
  case "shell":
    fwrite($stream, "uptime\n");
    break;
  case EXP_TIMEOUT:
  case EXP_EOF:
    break 2; 
  default:
    die("Error has occurred!");
  }
}
fclose ($stream);
分类
最新文章
最近回复
  • opnfense: 谢谢博主!!!解决问题了!!!我之前一直以为内置的odhcp6就是唯一管理ipv6的方式
  • liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
  • 海运: 不好意思,没有。
  • zongboa: 您好,請問一下有immortalwrt設定guest Wi-Fi的GUI教學嗎?感謝您。
  • 海运: 恩山有很多。
  • swsend: 大佬可以分享一下固件吗,谢谢。
  • Jimmy: 方法一 nghtp3步骤需要改成如下才能编译成功: git clone https://git...
  • 海运: 地址格式和udpxy一样,udpxy和msd_lite能用这个就能用。
  • 1: 怎么用 编译后的程序在家里路由器内任意一台设备上运行就可以吗?比如笔记本电脑 m参数是笔记本的...
  • 孤狼: ups_status_set: seems that UPS [BK650M2-CH] is ...