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