pull/8/head
Bohan Yang 5 years ago committed by GitHub
parent b87ce94baf
commit 732d3092c4
  1. 46
      README.md
  2. 177
      debi.sh

@ -28,27 +28,27 @@ This script is written to reinstall a VPS/virtual machine to Debian 10 Buster.
## Usage ## Usage
curl -fLO https://raw.githubusercontent.com/bohanyang/debi/master/debi.sh && sudo bash debi.sh <OPTIONS> curl -fL https://raw.githubusercontent.com/bohanyang/debi/master/debi.sh | sudo bash -s -- <OPTIONS>
## Available Options ## Available Options
* `--preset <string>` Shortcut for applying [preset options](#presets)
* `--ip <string>` Static public/private IP, e.g. `10.0.0.2` * `--ip <string>` Static public/private IP, e.g. `10.0.0.2`
* `--netmask <string>` e.g. `255.255.255.0` / `ffff:ffff:ffff:ffff::` * `--netmask <string>` e.g. `255.255.255.0` / `ffff:ffff:ffff:ffff::`. Ignored if `--ip` is not specified
* `--gateway <string>` e.g. `10.0.0.1` * `--gateway <string>` e.g. `10.0.0.1`. Ignored if `--ip` is not specified
* `--dns '8.8.8.8 8.8.4.4'` Ignored if `--ip` is not specified. Quoted string where IP addresses are seperated by spaces * `--dns '8.8.8.8 8.8.4.4'` Quoted string where IP addresses are seperated by spaces. Ignored if `--ip` is not specified
* `--hostname debian` * `--hostname debian`
* `--installer-password <string>` Enable installer network console to monitor installation status. e.g. `ssh installer@10.0.0.2` * `--network-console` Enable the network console of the installer. `ssh installer@ip` to connect
* `--authorized-keys-url <string>` Setup SSH public key authentication for the new user and enable installer network console. e.g. `https://github.com/bohanyang.keys`
* `--suite buster` * `--suite buster`
* `--mirror-protocol http` or `https` or `ftp` * `--mirror-protocol http` or `https` or `ftp`
* `--https` alias to `--mirror-protocol https`
* `--mirror-host deb.debian.org` * `--mirror-host deb.debian.org`
* `--mirror-directory /debian` * `--mirror-directory /debian`
* `--security-repository http://security.debian.org/debian-security` Magic value: `'mirror' = <mirror-protocol>://<mirror-host>/<mirror-directory>/../debian-security` * `--security-repository http://security.debian.org/debian-security` Magic value: `'mirror' = <mirror-protocol>://<mirror-host>/<mirror-directory>/../debian-security`
* `--skip-account-setup` * `--skip-account-setup`
* `--username debian` New user with `sudo` privilege or `root` * `--username debian` New user with `sudo` privilege or `root`
* `--password <string>` New user password to set. **Will be prompted if not specified here** * `--password <string>` Password of the new user. **You'll be prompted if you choose to not specify it here**
* `--sudo-password` Verify the user's password when running "sudo" commands * `--authorized-keys-url <string>` URL to your authorized keys for SSH authentication. e.g. `https://github.com/torvalds.keys`
* `--sudo-with-password` Require password when the user invokes `sudo` command
* `--timezone UTC` https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List * `--timezone UTC` https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
* `--ntp 0.debian.pool.ntp.org` * `--ntp 0.debian.pool.ntp.org`
* `--skip-partitioning` * `--skip-partitioning`
@ -60,11 +60,11 @@ This script is written to reinstall a VPS/virtual machine to Debian 10 Buster.
* `--kernel <string>` Choose an package for the kernel image * `--kernel <string>` Choose an package for the kernel image
* `--cloud-kernel` Choose `linux-image-cloud-amd64` as the kernel image * `--cloud-kernel` Choose `linux-image-cloud-amd64` as the kernel image
* `--no-install-recommends` * `--no-install-recommends`
* `--install 'ca-certificates libpam-systemd'` Additional packages to install. Quoted string where package names are seperated by spaces. **Package names specified here will override the default list, rather than append to it** * `--install 'ca-certificates libpam-systemd'` Additional packages to install. Quoted string where package names are seperated by spaces. Package names specified here will override the default list, rather than append to it
* `--safe-upgrade` **(Default)** `apt upgrade --with-new-pkgs`. [See](https://salsa.debian.org/installer-team/pkgsel/-/blob/master/debian/postinst) * `--safe-upgrade` **(Default)** `apt upgrade --with-new-pkgs`. [See](https://salsa.debian.org/installer-team/pkgsel/-/blob/master/debian/postinst)
* `--full-upgrade` `apt dist-upgrade` * `--full-upgrade` `apt dist-upgrade`
* `--no-upgrade` * `--no-upgrade`
* `--eth` Disable *Consistent Network Device Naming* to get `eth0`, `eth1`, etc. back * `--eth` Disable *Consistent Network Device Naming* to get interface names like *ethX* back
* `--bbr` Enable TCP BBR congestion control * `--bbr` Enable TCP BBR congestion control
* `--hold` Don't reboot or power off after installation * `--hold` Don't reboot or power off after installation
* `--power-off` Power off after installation rather than reboot * `--power-off` Power off after installation rather than reboot
@ -72,23 +72,27 @@ This script is written to reinstall a VPS/virtual machine to Debian 10 Buster.
* `--boot-partition` Should be used if `/boot` directory is mounted from a dedicated partition like a LVM setup * `--boot-partition` Should be used if `/boot` directory is mounted from a dedicated partition like a LVM setup
* `--firmware` Load additional [non-free firmwares](https://wiki.debian.org/Firmware#Firmware_during_the_installation) * `--firmware` Load additional [non-free firmwares](https://wiki.debian.org/Firmware#Firmware_during_the_installation)
* `--force-efi-extra-removable` [See](https://wiki.debian.org/UEFI#Force_grub-efi_installation_to_the_removable_media_path). **Useful on Oracle Cloud** * `--force-efi-extra-removable` [See](https://wiki.debian.org/UEFI#Force_grub-efi_installation_to_the_removable_media_path). **Useful on Oracle Cloud**
* `--grub-timeout 5` How many seconds the GRUB menu shows **before entering the installer** * `--grub-timeout 5` How many seconds the GRUB menu shows before entering the installer
* `--dry-run` Print generated preseed and GRUB entry without downloading the installer and actually saving them * `--dry-run` Print generated preseed and GRUB entry without downloading the installer and actually saving them
## Presets ### Presets
### `china` ### `--cdn`
* `--dns '223.5.5.5 223.6.6.6'`
* `--mirror-protocol https` * `--mirror-protocol https`
* `--mirror-host mirrors.aliyun.com` * `--mirror-host deb.debian.org`
* `--security-repository mirror` * `--security-repository mirror`
* `--ntp ntp.aliyun.com`
### `cloud` ### `--aws`
* `--dns '1.1.1.1 1.0.0.1'`
* `--mirror-protocol https` * `--mirror-protocol https`
* `--mirror-host deb.debian.org` * `--mirror-host cdn-aws.deb.debian.org`
* `--security-repository mirror` * `--security-repository mirror`
* `--ntp 0.debian.pool.ntp.org`
### `--china`
* `--dns '223.5.5.5 223.6.6.6'`
* `--mirror-protocol https`
* `--mirror-host mirrors.aliyun.com`
* `--security-repository mirror`
* `--ntp ntp.aliyun.com`

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/sh
# shellcheck shell=dash
set -euo pipefail set -euo pipefail
@ -11,20 +12,34 @@ command_exists() {
command -v "$1" > /dev/null 2>&1 command -v "$1" > /dev/null 2>&1
} }
late_command= in_target=
run_later() { late_command() {
[ -z "$late_command" ] && late_command='true' local cmd
late_command="$late_command; $1" for arg in "$@"; do
cmd="$cmd $arg"
done
if [ -n "$cmd" ]; then
[ -z "$in_target" ] && in_target='true'
in_target="$in_target;$cmd"
fi
}
in_target_backup() {
late_command "if [ ! -e \"$1.backup\" ]; then cp \"$1\" \"$1.backup\"; fi"
} }
backup() { sshd_conf() {
run_later "if [ ! -e \"$1.backup\" ]; then cp \"$1\" \"$1.backup\"; fi" [ -z ${backed_sshd+1} ] && in_target_backup /etc/ssh/sshd_config
backed_sshd=
late_command sed -Ei \""s/^#?$1 .+/$1 $2/"\" /etc/ssh/sshd_config
} }
prompt_password() { prompt_password() {
if [ -z "$password" ]; then stty -echo
read -rs -p 'Password: ' password echo -n "Choose a password for the new user $username: " > /dev/tty
fi read -r password < /dev/tty
stty echo
echo > /dev/tty
} }
ip= ip=
@ -32,9 +47,7 @@ netmask=
gateway= gateway=
dns='8.8.8.8 8.8.4.4' dns='8.8.8.8 8.8.4.4'
hostname= hostname=
installer_ssh=false network_console=false
installer_password=
authorized_keys_url=
suite=buster suite=buster
mirror_protocol=http mirror_protocol=http
mirror_host=deb.debian.org mirror_host=deb.debian.org
@ -43,8 +56,8 @@ security_repository=http://security.debian.org/debian-security
skip_account_setup=false skip_account_setup=false
username=debian username=debian
password= password=
sudo_password=false authorized_keys_url=
cleartext_password=false sudo_with_password=false
timezone=UTC timezone=UTC
ntp=0.debian.pool.ntp.org ntp=0.debian.pool.ntp.org
skip_partitioning=false skip_partitioning=false
@ -69,25 +82,17 @@ dry_run=false
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case $1 in case $1 in
--preset) --cdn|--aws)
case "$2" in mirror_protocol=https
china) [ "$1" = '--aws' ] && mirror_host=cdn-aws.deb.debian.org
dns='223.5.5.5 223.6.6.6' security_repository=mirror
mirror_protocol=https ;;
mirror_host=mirrors.aliyun.com --china)
ntp=ntp.aliyun.com dns='223.5.5.5 223.6.6.6'
security_repository=mirror mirror_protocol=https
;; mirror_host=mirrors.aliyun.com
cloud) ntp=ntp.aliyun.com
dns='1.1.1.1 1.0.0.1' security_repository=mirror
mirror_protocol=https
mirror_host=deb.debian.org
security_repository=mirror
;;
*)
err "No such preset $2"
esac
shift
;; ;;
--ip) --ip)
ip=$2 ip=$2
@ -109,15 +114,8 @@ while [ $# -gt 0 ]; do
hostname=$2 hostname=$2
shift shift
;; ;;
--installer-password) --network-console)
installer_ssh=true network_console=true
installer_password=$2
shift
;;
--authorized-keys-url)
installer_ssh=true
authorized_keys_url=$2
shift
;; ;;
--suite) --suite)
suite=$2 suite=$2
@ -142,7 +140,7 @@ while [ $# -gt 0 ]; do
--skip-account-setup) --skip-account-setup)
skip_account_setup=true skip_account_setup=true
;; ;;
--username) --user|--username)
username=$2 username=$2
shift shift
;; ;;
@ -150,8 +148,12 @@ while [ $# -gt 0 ]; do
password=$2 password=$2
shift shift
;; ;;
--sudo-password) --authorized-keys-url)
sudo_password=true authorized_keys_url=$2
shift
;;
--sudo-with-password)
sudo_with_password=true
;; ;;
--timezone) --timezone)
timezone=$2 timezone=$2
@ -287,30 +289,21 @@ fi
echo 'd-i hw-detect/load_firmware boolean true' | $save_preseed echo 'd-i hw-detect/load_firmware boolean true' | $save_preseed
if [ "$installer_ssh" = true ]; then while [ -z "$password" ]; do
$save_preseed << 'EOF' prompt_password
done
if [ "$network_console" = true ]; then
$save_preseed << EOF
# Network console # Network console
d-i anna/choose_modules string network-console d-i anna/choose_modules string network-console
d-i preseed/early_command string anna-install network-console d-i preseed/early_command string anna-install network-console
d-i network-console/password password $password
d-i network-console/password-again password $password
EOF EOF
[ -n "$authorized_keys_url" ] && echo "d-i network-console/authorized_keys_url string $authorized_keys_url" | $save_preseed
if [ -n "$authorized_keys_url" ]; then
backup /etc/ssh/sshd_config
run_later 'sed -Ei "s/^#?PasswordAuthentication .+/PasswordAuthentication no/" /etc/ssh/sshd_config'
$save_preseed << EOF
d-i network-console/password-disabled boolean true
d-i network-console/authorized_keys_url string $authorized_keys_url
EOF
elif [ -n "$installer_password" ]; then
$save_preseed << EOF
d-i network-console/password-disabled boolean false
d-i network-console/password password $installer_password
d-i network-console/password-again password $installer_password
EOF
fi
echo 'd-i network-console/start select Continue' | $save_preseed echo 'd-i network-console/start select Continue' | $save_preseed
fi fi
@ -328,24 +321,15 @@ d-i mirror/udeb/suite string $suite
EOF EOF
if [ "$skip_account_setup" != true ]; then if [ "$skip_account_setup" != true ]; then
password_hash=
if command_exists mkpasswd; then if command_exists mkpasswd; then
if [ -z "$password" ]; then password_hash=$(mkpasswd -m sha-512 "$password")
password="$(mkpasswd -m sha-512)"
else
password="$(mkpasswd -m sha-512 "$password")"
fi
elif command_exists busybox && busybox mkpasswd --help >/dev/null 2>&1; then elif command_exists busybox && busybox mkpasswd --help >/dev/null 2>&1; then
prompt_password password_hash=$(busybox mkpasswd -m sha512 "$password")
password="$(busybox mkpasswd -m sha512 "$password")"
elif command_exists python3; then elif command_exists python3; then
if [ -z "$password" ]; then password_hash=$(python3 -c 'import crypt, sys; print(crypt.crypt(sys.argv[1], crypt.mksalt(crypt.METHOD_SHA512)))' "$password")
password="$(python3 -c 'import crypt, getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))')" elif command_exists python; then
else password_hash=$(python -c 'import crypt, sys; print(crypt.crypt(sys.argv[1], crypt.mksalt(crypt.METHOD_SHA512)))' "$password" 2> /dev/null) || password_hash=
password="$(python3 -c "import crypt; print(crypt.crypt('$password', crypt.mksalt(crypt.METHOD_SHA512)))")"
fi
else
cleartext_password=true
prompt_password
fi fi
$save_preseed << 'EOF' $save_preseed << 'EOF'
@ -353,13 +337,15 @@ if [ "$skip_account_setup" != true ]; then
# Account setup # Account setup
EOF EOF
if [ -n "$authorized_keys_url" ]; then
sshd_conf PasswordAuthentication no
fi
if [ "$username" = root ]; then if [ "$username" = root ]; then
if [ -z "$authorized_keys_url" ]; then if [ -z "$authorized_keys_url" ]; then
backup /etc/ssh/sshd_config sshd_conf PermitRootLogin yes
run_later 'sed -Ei "s/^#?PermitRootLogin .+/PermitRootLogin yes/" /etc/ssh/sshd_config'
else else
run_later "mkdir -m 0700 -p ~root/.ssh && busybox wget -O - \"$authorized_keys_url\" >> ~root/.ssh/authorized_keys" late_command "mkdir -m 0700 -p ~root/.ssh && busybox wget -O - \"$authorized_keys_url\" >> ~root/.ssh/authorized_keys"
fi fi
$save_preseed << 'EOF' $save_preseed << 'EOF'
@ -367,24 +353,23 @@ d-i passwd/root-login boolean true
d-i passwd/make-user boolean false d-i passwd/make-user boolean false
EOF EOF
if [ "$cleartext_password" = true ]; then if [ -z "$password_hash" ]; then
$save_preseed << EOF $save_preseed << EOF
d-i passwd/root-password password $password d-i passwd/root-password password $password
d-i passwd/root-password-again password $password d-i passwd/root-password-again password $password
EOF EOF
else else
echo "d-i passwd/root-password-crypted password $password" | $save_preseed echo "d-i passwd/root-password-crypted password $password_hash" | $save_preseed
fi fi
else else
backup /etc/ssh/sshd_config sshd_conf PermitRootLogin no
run_later 'sed -Ei "s/^#?PermitRootLogin .+/PermitRootLogin no/" /etc/ssh/sshd_config'
if [ -n "$authorized_keys_url" ]; then if [ -n "$authorized_keys_url" ]; then
run_later "sudo -u $username mkdir -m 0700 -p ~$username/.ssh && busybox wget -O - \"$authorized_keys_url\" | sudo -u $username tee -a ~$username/.ssh/authorized_keys" late_command "sudo -u $username mkdir -m 0700 -p ~$username/.ssh && busybox wget -O - \"$authorized_keys_url\" | sudo -u $username tee -a ~$username/.ssh/authorized_keys"
fi fi
if [ "$sudo_password" = false ]; then if [ "$sudo_with_password" = false ]; then
run_later "echo \"$username ALL=(ALL:ALL) NOPASSWD:ALL\" > \"/etc/sudoers.d/90-user-$username\"" late_command "echo \"$username ALL=(ALL:ALL) NOPASSWD:ALL\" > \"/etc/sudoers.d/90-user-$username\""
fi fi
$save_preseed << EOF $save_preseed << EOF
@ -394,13 +379,13 @@ d-i passwd/user-fullname string
d-i passwd/username string $username d-i passwd/username string $username
EOF EOF
if [ "$cleartext_password" = true ]; then if [ -z "$password_hash" ]; then
$save_preseed << EOF $save_preseed << EOF
d-i passwd/user-password password $password d-i passwd/user-password password $password
d-i passwd/user-password-again password $password d-i passwd/user-password-again password $password
EOF EOF
else else
echo "d-i passwd/user-password-crypted password $password" | $save_preseed echo "d-i passwd/user-password-crypted password $password_hash" | $save_preseed
fi fi
fi fi
fi fi
@ -524,9 +509,9 @@ EOF
[ "$hold" != true ] && echo 'd-i finish-install/reboot_in_progress note' | $save_preseed [ "$hold" != true ] && echo 'd-i finish-install/reboot_in_progress note' | $save_preseed
[ "$bbr" = true ] && run_later '{ echo "net.core.default_qdisc=fq"; echo "net.ipv4.tcp_congestion_control=bbr"; } > /etc/sysctl.d/bbr.conf' [ "$bbr" = true ] && late_command '{ echo "net.core.default_qdisc=fq"; echo "net.ipv4.tcp_congestion_control=bbr"; } > /etc/sysctl.d/bbr.conf'
[ -n "$late_command" ] && echo "d-i preseed/late_command string in-target bash -c '$late_command'" | $save_preseed [ -n "$in_target" ] && echo "d-i preseed/late_command string in-target dash -c '$in_target'" | $save_preseed
[ "$power_off" = true ] && echo 'd-i debian-installer/exit/poweroff boolean true' | $save_preseed [ "$power_off" = true ] && echo 'd-i debian-installer/exit/poweroff boolean true' | $save_preseed
@ -534,7 +519,7 @@ save_grub_cfg='cat'
if [ "$dry_run" != true ]; then if [ "$dry_run" != true ]; then
if [ -z "$architecture" ]; then if [ -z "$architecture" ]; then
architecture=amd64 architecture=amd64
command_exists dpkg && architecture="$(dpkg --print-architecture)" command_exists dpkg && architecture=$(dpkg --print-architecture)
fi fi
base_url="$mirror_protocol://$mirror_host$mirror_directory/dists/$suite/main/installer-$architecture/current/images/netboot/debian-installer/$architecture" base_url="$mirror_protocol://$mirror_host$mirror_directory/dists/$suite/main/installer-$architecture/current/images/netboot/debian-installer/$architecture"
@ -572,7 +557,7 @@ EOF
grub_cfg=/boot/grub/grub.cfg grub_cfg=/boot/grub/grub.cfg
update-grub update-grub
elif command_exists grub2-mkconfig; then elif command_exists grub2-mkconfig; then
tmp="$(mktemp)" tmp=$(mktemp)
grep -vF zz_debi /etc/default/grub > "$tmp" grep -vF zz_debi /etc/default/grub > "$tmp"
cat "$tmp" > /etc/default/grub cat "$tmp" > /etc/default/grub
rm "$tmp" rm "$tmp"
@ -590,7 +575,7 @@ fi
installer_directory="$boot_directory$installer" installer_directory="$boot_directory$installer"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
mem="$(grep ^MemTotal: /proc/meminfo | { read -r x y z; echo "$y"; })" mem=$(grep ^MemTotal: /proc/meminfo | { read -r x y z; echo "$y"; })
[ $((mem / 1024)) -lt 483 ] && kernel_params="$kernel_params lowmem/low=" [ $((mem / 1024)) -lt 483 ] && kernel_params="$kernel_params lowmem/low="
$save_grub_cfg 1>&2 << EOF $save_grub_cfg 1>&2 << EOF

Loading…
Cancel
Save