diff --git a/README.en.md b/README.en.md index eb85fcc..ed4ee10 100644 --- a/README.en.md +++ b/README.en.md @@ -150,6 +150,14 @@ bash reinstall.sh anolis 7|8|23 #### Optional Parameters - `--password PASSWORD` Set the password +- `--ssh-key KEY` Set up SSH public key, supports these formats. When using public key, password is empty. + - `--ssh-key "ssh-rsa ..."` + - `--ssh-key "ssh-ed25519 ..."` + - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."` + - `--ssh-key http://url` + - `--ssh-key github:your_username` + - `--ssh-key gitlab:your_username` + - `--ssh-key /path/to/public_key` - `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system) - `--web-port PORT` Change the Web port (for log observation during installation) - `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/os` (this feature is not supported on Debian/Kali). @@ -228,6 +236,14 @@ bash reinstall.sh alpine --hold=1 - `--password PASSWORD` Set password - `--ssh-port PORT` Change SSH port +- `--ssh-key KEY` Set up SSH public key, supports these formats. When using public key, password is empty. + - `--ssh-key ssh-rsa ...` + - `--ssh-key ssh-ed25519 ...` + - `--ssh-key ecdsa-sha2-nistp256/384/521 ...` + - `--ssh-key http://url` + - `--ssh-key github:your_username` + - `--ssh-key gitlab:your_username` + - `--ssh-key /path/to/public_key` ### Feature 4: Reboot to netboot.xyz diff --git a/README.md b/README.md index 89e83d1..5767306 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,15 @@ bash reinstall.sh anolis 7|8|23 #### 可选参数 - `--password PASSWORD` 设置密码 -- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也用于新系统) +- `--ssh-key KEY` 设置 SSH 公钥登录,支持以下格式。当使用公钥时,密码为空 + - `--ssh-key "ssh-rsa ..."` + - `--ssh-key "ssh-ed25519 ..."` + - `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."` + - `--ssh-key http://url` + - `--ssh-key github:your_username` + - `--ssh-key gitlab:your_username` + - `--ssh-key /path/to/public_key` +- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统) - `--web-port PORT` 修改 Web 端口(安装期间观察日志用) - `--hold 2` 安装结束后不重启,此时可以 SSH 登录修改系统内容,系统挂载在 `/os` (此功能不支持 Debian/Kali) @@ -228,6 +236,14 @@ bash reinstall.sh alpine --hold=1 - `--password PASSWORD` 设置密码 - `--ssh-port PORT` 修改 SSH 端口 +- `--ssh-key KEY` 设置 SSH 公钥登录,支持以下格式。当使用公钥时,密码为空 + - `--ssh-key ssh-rsa ...` + - `--ssh-key ssh-ed25519 ...` + - `--ssh-key ecdsa-sha2-nistp256/384/521 ...` + - `--ssh-key http://url` + - `--ssh-key github:your_username` + - `--ssh-key gitlab:your_username` + - `--ssh-key /path/to/public_key` ### 功能 4: 重启到 netboot.xyz diff --git a/debian.cfg b/debian.cfg index f61a330..e30e4d9 100644 --- a/debian.cfg +++ b/debian.cfg @@ -26,6 +26,7 @@ d-i mirror/country string manual # B.4.5. 帐号设置 d-i passwd/make-user boolean false # 单纯为了跳过设置,实际上是在 partman/early_command 里设置密码,preseed/early_command 无法设置密码 +# 注意如果用 ssh key 后面还要删除密码 d-i passwd/root-password password '' d-i passwd/root-password-again password '' # kali 需要下面这行,否则会提示输入用户名 @@ -172,8 +173,13 @@ d-i preseed/late_command string true; \ in-target systemctl enable ssh; \ - echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf || \ - echo "PermitRootLogin yes" >>/target/etc/ssh/sshd_config; \ + if [ -s /configs/ssh_keys ]; then \ + (umask 077; mkdir -p /target/root/.ssh; cat /configs/ssh_keys >/target/root/.ssh/authorized_keys); \ + in-target passwd -d root; \ + else \ + echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf || \ + echo "PermitRootLogin yes" >>/target/etc/ssh/sshd_config; \ + fi; \ if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \ echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-change-ssh-port.conf || \ diff --git a/reinstall.sh b/reinstall.sh index 0e8ac69..9bd09aa 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -69,7 +69,9 @@ Usage: $reinstall_____ anolis 7|8|23 windows --image-name="windows xxx yyy" --iso="http://xxx.com/xxx.iso" netboot.xyz - Options: [--ssh-port PORT] + Options: [--password PASSWORD] + [--ssh-key KEY] + [--ssh-port PORT] [--rdp-port PORT] [--web-port PORT] [--allow-ping] @@ -1790,6 +1792,10 @@ verify_os_args() { redhat) [ -n "$img" ] || error_and_exit "redhat need --img" ;; windows) [ -n "$image_name" ] || error_and_exit "Install Windows need --image-name." ;; esac + + case "$distro" in + netboot.xyz | windows) [ -z "$ssh_keys" ] || error_and_exit "not support ssh key for $distro" ;; + esac } get_cmd_path() { @@ -3471,7 +3477,11 @@ This script is outdated, please download reinstall.sh again. # 保存配置 mkdir -p $initrd_dir/configs - save_password $initrd_dir/configs + if [ -n "$ssh_keys" ]; then + cat <<<"$ssh_keys" >$initrd_dir/configs/ssh_keys + else + save_password $initrd_dir/configs + fi if is_distro_like_debian $nextos_distro; then mod_initrd_debian_kali @@ -3572,6 +3582,15 @@ remove_useless_initrd_files() { du -sh . } +get_unix_path() { + if is_in_windows; then + # 输入的路径是 / 开头也没问题 + cygpath -u "$1" + else + printf '%s' "$1" + fi +} + # 脚本入口 if mount | grep -q 'tmpfs on / type tmpfs'; then error_and_exit "Can't run this script in Live OS." @@ -3620,6 +3639,7 @@ for o in ci installer debug minimal allow-ping force-cn \ lang: \ passwd: password: \ ssh-port: \ + ssh-key: public-key: \ rdp-port: \ web-port: http-port: \ allow-ping: \ @@ -3687,6 +3707,73 @@ while true; do --passwd | --password) [ -n "$2" ] || error_and_exit "Need value for $1" password=$2 + shift 2 + ;; + --ssh-key | --public-key) + ssh_key_error_and_exit() { + error "$1" + cat <"/configs/$1" } +# ubuntu 安装版、el/ol 安装版不使用该密码 get_password_linux_sha512() { get_config password-linux-sha512 } @@ -544,7 +545,6 @@ get_password_windows_administrator_base64() { get_config password-windows-administrator-base64 } -# debian 安装版、ubuntu 安装版、el/ol 安装版不使用该密码 get_password_plaintext() { get_config password-plaintext } @@ -726,6 +726,10 @@ is_elts() { [ -n "$elts" ] && [ "$elts" = 1 ] } +is_need_set_ssh_keys() { + [ -s /configs/ssh_keys ] +} + is_need_change_ssh_port() { [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ] } @@ -771,6 +775,10 @@ del_cr() { sed 's/\r//g' } +del_comment_lines() { + sed '/^[[:space:]]*#/d' +} + del_empty_lines() { sed '/^[[:space:]]*$/d' } @@ -1376,6 +1384,11 @@ install_alpine() { chroot /os setup-timezone -i Asia/Shanghai chroot /os setup-ntp chrony || true + # 设置公钥 + if is_need_set_ssh_keys; then + set_ssh_keys_and_del_password /os + fi + # 下载 fix-eth-name download "$confhome/fix-eth-name.sh" /os/fix-eth-name.sh download "$confhome/fix-eth-name.initd" /os/etc/init.d/fix-eth-name @@ -1571,6 +1584,17 @@ install_nixos() { if [ -e /os/swapfile ] && $keep_swap; then nix_swap="swapDevices = [{ device = \"/swapfile\"; size = $swap_size; }];" fi + + if is_need_set_ssh_keys; then + nix_ssh_keys_or_PermitRootLogin=" +users.users.root.openssh.authorizedKeys.keys = [ +$(del_comment_lines $os_dir/root/.ssh/authorized_keys + ) + + # 删除密码 + chroot $os_dir passwd -d root +} + # 除了 alpine 都会用到 change_ssh_conf() { os_dir=$1 @@ -3562,20 +3607,25 @@ change_ssh_conf() { value=$3 sub_conf=$4 - # arch 没有 /etc/ssh/sshd_config.d/ 文件夹 - # opensuse tumbleweed 没有 /etc/ssh/sshd_config - # 有 /etc/ssh/sshd_config.d/ 文件夹 - # 有 /usr/etc/ssh/sshd_config - if { grep -q 'Include.*/etc/ssh/sshd_config.d' $os_dir/etc/ssh/sshd_config || - grep -q '^Include.*/etc/ssh/sshd_config.d/' $os_dir/usr/etc/ssh/sshd_config; } 2>/dev/null; then + if line="^$key .*" && grep -Exq "$line" $os_dir/etc/ssh/sshd_config; then + # 如果 sshd_config 存在此 key(非注释状态),则替换 + sed -Ei "s/$line/$key $value/" $os_dir/etc/ssh/sshd_config + elif { + # arch 没有 /etc/ssh/sshd_config.d/ 文件夹 + # opensuse tumbleweed 没有 /etc/ssh/sshd_config + # 有 /etc/ssh/sshd_config.d/ 文件夹 + # 有 /usr/etc/ssh/sshd_config + grep -q 'Include.*/etc/ssh/sshd_config.d' $os_dir/etc/ssh/sshd_config || + grep -q '^Include.*/etc/ssh/sshd_config.d/' $os_dir/usr/etc/ssh/sshd_config + } 2>/dev/null; then mkdir -p $os_dir/etc/ssh/sshd_config.d/ echo "$key $value" >"$os_dir/etc/ssh/sshd_config.d/$sub_conf" else - # 如果 sshd_config 存在此 key,则替换 + # 如果 sshd_config 存在此 key (无论是否已注释),则替换,包括删除注释 # 否则追加 line="^#?$key .*" if grep -Exq "$line" $os_dir/etc/ssh/sshd_config; then - sed -Eiq "s/$line/$key $value/" $os_dir/etc/ssh/sshd_config + sed -Ei "s/$line/$key $value/" $os_dir/etc/ssh/sshd_config else echo "$key $value" >>$os_dir/etc/ssh/sshd_config fi @@ -3584,17 +3634,15 @@ change_ssh_conf() { allow_password_login() { os_dir=$1 - change_ssh_conf "$os_dir" PasswordAuthentication yes 02-PasswordAuthenticaton.conf + change_ssh_conf "$os_dir" PasswordAuthentication yes 01-PasswordAuthenticaton.conf } -# arch gentoo 常规安装用 allow_root_password_login() { os_dir=$1 change_ssh_conf "$os_dir" PermitRootLogin yes 01-permitrootlogin.conf } -# arch gentoo 常规安装用 change_ssh_port() { os_dir=$1 ssh_port=$2 @@ -3974,8 +4022,11 @@ install_fnos() { # chroot $os_dir update-initramfs -u # 更改密码 - # chroot $os_dir passwd -d root - echo "root:$(get_password_linux_sha512)" | chroot $os_dir chpasswd -e + if is_need_set_ssh_keys; then + set_ssh_keys_and_del_password $os_dir + else + change_root_password $os_dir + fi # ssh root 登录,测试用 if false; then @@ -6328,13 +6379,20 @@ mount / -o remount,size=100% # 4. 允许同步失败,因为不是关键步骤 sync_time || true -# 设置密码,安装并打开 ssh -echo "root:$(get_password_linux_sha512)" | chpasswd -e +# 安装 ssh 并更改端口 apk add openssh if is_need_change_ssh_port; then change_ssh_port / $ssh_port fi -printf '\nyes' | setup-sshd + +# 设置密码,添加开机启动 + 开启 ssh 服务 +if is_need_set_ssh_keys; then + set_ssh_keys_and_del_password / + printf '\n' | setup-sshd +else + change_root_password / + printf '\nyes' | setup-sshd +fi # shellcheck disable=SC2154 if [ "$hold" = 1 ]; then