mirror of
https://github.com/bin456789/reinstall.git
synced 2026-06-11 22:34:30 +08:00
core: 支持 linux 设置普通账号
This commit is contained in:
@@ -12,9 +12,11 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
command: sudo bash reinstall.sh --debug --password 123@@@
|
||||
command: sudo bash reinstall.sh --debug --username x --password x
|
||||
command_no_username_option: sudo bash reinstall.sh --debug
|
||||
- os: windows-latest
|
||||
command: ./reinstall.bat --debug --password 123@@@
|
||||
command: ./reinstall.bat --debug --username x --password x
|
||||
command_no_username_option: ./reinstall.bat --debug
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: |
|
||||
@@ -35,9 +37,9 @@ jobs:
|
||||
# ${{ matrix.command }} arch
|
||||
# ${{ matrix.command }} gentoo
|
||||
|
||||
${{ matrix.command }} netboot.xyz
|
||||
${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz
|
||||
${{ matrix.command }} windows --image-name='Windows Server blah' --iso https://aka.ms/HCIReleaseImage --username administrator
|
||||
${{ matrix.command_no_username_option }} netboot.xyz
|
||||
${{ matrix.command }} dd --img=https://cloud.debian.org/images/cloud/sid/daily/latest/debian-sid-nocloud-amd64-daily.tar.xz
|
||||
${{ matrix.command }} windows --image-name='Windows Server blah' --iso https://aka.ms/HCIReleaseImage
|
||||
|
||||
${{ matrix.command }} reset
|
||||
|
||||
|
||||
+115
-29
@@ -24,13 +24,9 @@ d-i mirror/country string manual
|
||||
# d-i mirror/http/hostname string deb.debian.org
|
||||
|
||||
# B.4.5. 帐号设置
|
||||
d-i passwd/make-user boolean false
|
||||
# 注意如果用 ssh key 后面还要删除密码
|
||||
# d-i passwd/root-password password ''
|
||||
# d-i passwd/root-password-again password ''
|
||||
# d-i passwd/root-password-crypted password ''
|
||||
# kali 需要下面这行,否则会提示输入用户名
|
||||
d-i passwd/root-login boolean true
|
||||
# kali 需要设置这行,否则会提示输入用户名
|
||||
# 因为 kali installer initrd 内置了一个 preseed.cfg,设置了 passwd/root-login false
|
||||
# d-i passwd/root-login boolean true
|
||||
|
||||
# B.4.6. 时钟与时区设置
|
||||
d-i time/zone string Asia/Shanghai
|
||||
@@ -121,6 +117,19 @@ d-i grub-installer/force-efi-extra-removable boolean true
|
||||
|
||||
# debian 11+ 才有 websocketd
|
||||
|
||||
# debian 9 sshd_config 不支持 Include
|
||||
|
||||
# di 环境下 /etc/passwd 设置了 root 的家目录是 /,不是常见的 /root
|
||||
# 我们不修改它,防止出问题
|
||||
|
||||
# di 环境下 锁定用户将无法登录 ssh
|
||||
|
||||
# passwd/root-password-crypted 是 ! 开头时会提示输入密码
|
||||
# 因此这个值设成 *
|
||||
# https://salsa.debian.org/installer-team/user-setup/-/blob/1.109/user-setup-ask?ref_type=tags#L35
|
||||
|
||||
# screen 需要设置 +s 权限,否则普通用户无法 attach 到 root 的 screen 会话
|
||||
|
||||
# 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles
|
||||
# 不然安装时 control 脚本会报错:
|
||||
# Loading simple-cdd-profiles failed for unknown reasons
|
||||
@@ -133,6 +142,9 @@ d-i grub-installer/force-efi-extra-removable boolean true
|
||||
# 此时还没有配置源,anna-install 会在配置完源后再安装
|
||||
d-i preseed/early_command string true; \
|
||||
for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \
|
||||
username=${username:-root}; \
|
||||
ssh_port=${ssh_port:-22}; \
|
||||
web_port=${web_port:-80}; \
|
||||
|
||||
di(){ \
|
||||
echo "d-i $*" >/tmp/selections.cfg; \
|
||||
@@ -150,6 +162,11 @@ d-i preseed/early_command string true; \
|
||||
cp -f /etc/screenrc.bak /etc/screenrc; \
|
||||
}; \
|
||||
|
||||
chmod +s /usr/bin/screen; \
|
||||
|
||||
screen -x root/ -X multiuser on; \
|
||||
screen -x root/ -X acladd "$username"; \
|
||||
|
||||
if [ "$hold" = 1 ]; then \
|
||||
di auto-install/enable boolean false; \
|
||||
di debconf/priority select low; \
|
||||
@@ -160,7 +177,9 @@ d-i preseed/early_command string true; \
|
||||
echo 'Option 1. View logs:'; \
|
||||
echo ' tail -fn+1 /var/log/syslog'; \
|
||||
echo 'Option 2. Attach to the installer:'; \
|
||||
echo ' TERM=screen screen -xp1'; \
|
||||
echo ' TERM=screen screen -x root/ -p 1'; \
|
||||
echo 'Option 3. Attach to the root shell if you are not root:'; \
|
||||
echo ' TERM=screen screen -x root/ -p 2'; \
|
||||
} >>/etc/motd; \
|
||||
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$((y / 1024))"; }); \
|
||||
if command -v websocketd && [ "$mem" -ge 400 ]; then \
|
||||
@@ -170,10 +189,7 @@ d-i preseed/early_command string true; \
|
||||
fi; \
|
||||
sleep 5; \
|
||||
done; \
|
||||
if [ -z "$web_port" ]; then \
|
||||
web_port=80; \
|
||||
fi; \
|
||||
run_as_service_with_screen websocketd --port 80 --loglevel=fatal --staticdir=/tmp \
|
||||
run_as_service_with_screen websocketd --port "$web_port" --loglevel=fatal --staticdir=/tmp \
|
||||
sh -c "tail -fn+0 /var/log/syslog | tr '\r' '\n' | grep -Fiv -e password -e token" ; \
|
||||
fi; \
|
||||
fi; \
|
||||
@@ -182,25 +198,64 @@ d-i preseed/early_command string true; \
|
||||
di finish-install/reboot_in_progress note; \
|
||||
fi; \
|
||||
|
||||
if [ -s /configs/ssh_keys ]; then \
|
||||
di passwd/root-password-crypted password "''"; \
|
||||
mkdir -p /home; \
|
||||
chmod 755 /home; \
|
||||
|
||||
if [ "$username" = "root" ]; then \
|
||||
uid=0; \
|
||||
scope=root; \
|
||||
user_home=/; \
|
||||
di passwd/root-login boolean true; \
|
||||
di passwd/make-user boolean false; \
|
||||
else \
|
||||
di passwd/root-password-crypted password "$(cat /configs/password-linux-sha512)"; \
|
||||
uid=1000; \
|
||||
scope=user; \
|
||||
user_home=/home/$username; \
|
||||
di passwd/root-login boolean false; \
|
||||
di passwd/make-user boolean true; \
|
||||
di passwd/user-fullname string "$username"; \
|
||||
di passwd/username string "$username"; \
|
||||
fi; \
|
||||
|
||||
mkdir -p /etc/ssh; \
|
||||
true >/etc/ssh/sshd_config; \
|
||||
if [ -s /configs/ssh_keys ]; then \
|
||||
(umask 077; mkdir -p /.ssh; cat /configs/ssh_keys >/.ssh/authorized_keys); \
|
||||
password_hash_for_initrd=''; \
|
||||
password_hash_for_preseed='*'; \
|
||||
else \
|
||||
echo "PermitRootLogin yes" >>/etc/ssh/sshd_config; \
|
||||
password_hash_for_initrd=$(cat /configs/password-linux-sha512); \
|
||||
password_hash_for_preseed=$(cat /configs/password-linux-sha512); \
|
||||
fi; \
|
||||
if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \
|
||||
echo "Port $ssh_port" >>/etc/ssh/sshd_config; \
|
||||
fi; \
|
||||
grep -qs ^root: /etc/shadow || echo "root:$(cat /configs/password-linux-sha512):1:0:99999:7:::" >>/etc/shadow; \
|
||||
|
||||
di passwd/$scope-password-crypted password "$password_hash_for_preseed"; \
|
||||
|
||||
grep -qs ^$username: /etc/passwd || echo "$username:*:$uid:$uid:$username:$user_home:/bin/sh" >>/etc/passwd; \
|
||||
grep -qs ^$username: /etc/group || echo "$username:*:$uid:" >>/etc/group; \
|
||||
grep -qs ^$username: /etc/shadow || echo "$username:$password_hash_for_initrd:1:0:99999:7:::" >>/etc/shadow; \
|
||||
grep -qs ^nogroup: /etc/group || echo "nogroup:*:65534:" >>/etc/group; \
|
||||
grep -qs ^sshd: /etc/passwd || echo "sshd:*:100:65534::/run/sshd:/bin/false" >>/etc/passwd; \
|
||||
|
||||
mkdir -p /etc/ssh/; \
|
||||
true >/etc/ssh/sshd_config; \
|
||||
|
||||
if [ -s /configs/ssh_keys ]; then \
|
||||
( \
|
||||
umask 077; \
|
||||
mkdir -p "$user_home/.ssh"; \
|
||||
cat /configs/ssh_keys >"$user_home/.ssh/authorized_keys"; \
|
||||
); \
|
||||
chown "$username:$username" "$user_home"; \
|
||||
chown "$username:$username" "$user_home/.ssh"; \
|
||||
chown "$username:$username" "$user_home/.ssh/authorized_keys"; \
|
||||
echo "PasswordAuthentication no" >>/etc/ssh/sshd_config; \
|
||||
else \
|
||||
if [ "$username" = root ]; then \
|
||||
echo "PermitRootLogin yes" >>/etc/ssh/sshd_config; \
|
||||
fi; \
|
||||
fi; \
|
||||
|
||||
if ! [ "$ssh_port" = 22 ]; then \
|
||||
echo "Port $ssh_port" >>/etc/ssh/sshd_config; \
|
||||
fi; \
|
||||
|
||||
mkdir -p /run/sshd; \
|
||||
chmod 0755 /run/sshd; \
|
||||
ssh-keygen -A; \
|
||||
@@ -230,7 +285,11 @@ d-i preseed/early_command string true; \
|
||||
# efi 分区大小未改变时,不会被格式化,因此需要手动删除旧系统的 efi 文件
|
||||
# os-prober 卡太久,因此跳过
|
||||
d-i partman/early_command string true; \
|
||||
eval "$(grep -o 'extra_confhome=[^ ]*' /proc/cmdline | sed 's/^extra_//')"; \
|
||||
for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \
|
||||
username=${username:-root}; \
|
||||
ssh_port=${ssh_port:-22}; \
|
||||
web_port=${web_port:-80}; \
|
||||
|
||||
|
||||
postinst=/var/lib/dpkg/info/bootstrap-base.postinst; \
|
||||
cp $postinst $postinst.orig; \
|
||||
@@ -276,6 +335,9 @@ d-i partman/early_command string true; \
|
||||
# debian 9 tar 不支持 --strip-components
|
||||
d-i preseed/late_command string true; \
|
||||
for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \
|
||||
username=${username:-root}; \
|
||||
ssh_port=${ssh_port:-22}; \
|
||||
web_port=${web_port:-80}; \
|
||||
|
||||
if [ "$elts" = 1 ]; then sed -i "s|deb\.freexian\.com/extended-lts|$deb_mirror|" /target/etc/apt/sources.list; fi; \
|
||||
|
||||
@@ -283,19 +345,43 @@ d-i preseed/late_command string true; \
|
||||
|
||||
in-target systemctl enable ssh; \
|
||||
|
||||
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; \
|
||||
if [ "$username" = root ]; then \
|
||||
user_home=/root; \
|
||||
else \
|
||||
user_home=/home/$username; \
|
||||
fi; \
|
||||
|
||||
if [ -s /configs/ssh_keys ]; then \
|
||||
( \
|
||||
umask 077; \
|
||||
mkdir -p "/target/$user_home/.ssh"; \
|
||||
cat /configs/ssh_keys >"/target/$user_home/.ssh/authorized_keys"; \
|
||||
); \
|
||||
in-target passwd -d -l "$username"; \
|
||||
in-target chown "$username:$username" "$user_home"; \
|
||||
in-target chown "$username:$username" "$user_home/.ssh"; \
|
||||
in-target chown "$username:$username" "$user_home/.ssh/authorized_keys"; \
|
||||
|
||||
echo "PasswordAuthentication no" >/target/etc/ssh/sshd_config.d/01-passwordauthentication.conf || \
|
||||
echo "PasswordAuthentication no" >>/target/etc/ssh/sshd_config; \
|
||||
|
||||
else \
|
||||
if [ "$username" = root ]; then \
|
||||
echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf || \
|
||||
echo "PermitRootLogin yes" >>/target/etc/ssh/sshd_config; \
|
||||
fi; \
|
||||
fi; \
|
||||
|
||||
if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \
|
||||
echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-change-ssh-port.conf || \
|
||||
if ! [ "$ssh_port" = 22 ]; then \
|
||||
echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-port.conf || \
|
||||
echo "Port $ssh_port" >>/target/etc/ssh/sshd_config; \
|
||||
fi; \
|
||||
|
||||
if ! [ "$username" = root ]; then \
|
||||
printf '%s\n' "$username ALL=(ALL) NOPASSWD:ALL" >"/target/etc/sudoers.d/99-$username"; \
|
||||
chmod 0440 "/target/etc/sudoers.d/99-$username"; \
|
||||
fi; \
|
||||
|
||||
if ls /configs/frpc.* >/dev/null 2>&1; then \
|
||||
mkdir -p /target/usr/local/bin; \
|
||||
mkdir -p /target/usr/local/etc/frpc; \
|
||||
|
||||
+159
-56
@@ -102,6 +102,7 @@ Usage: $reinstall_____ anolis 7|8|23
|
||||
reset
|
||||
|
||||
Options: For Linux/Windows:
|
||||
[--username USERNAME]
|
||||
[--password PASSWORD]
|
||||
[--ssh-key KEY]
|
||||
[--ssh-port PORT]
|
||||
@@ -1942,15 +1943,29 @@ verify_os_name() {
|
||||
}
|
||||
|
||||
verify_os_args() {
|
||||
# 必备参数
|
||||
case "$distro" in
|
||||
dd) [ -n "$img" ] || error_and_exit "dd need --img" ;;
|
||||
redhat) [ -n "$img" ] || error_and_exit "redhat need --img" ;;
|
||||
dd) [ -n "$img" ] || error_and_exit "dd need --img." ;;
|
||||
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" ;;
|
||||
netboot.xyz)
|
||||
[ -z "$username" ] || error_and_exit "not support set username for $distro."
|
||||
[ -z "$password" ] || error_and_exit "not support set password for $distro."
|
||||
[ -z "$ssh_keys" ] || error_and_exit "not support set ssh key for $distro."
|
||||
;;
|
||||
windows)
|
||||
[ -z "$ssh_keys" ] || error_and_exit "not support set ssh key for $distro."
|
||||
;;
|
||||
esac
|
||||
|
||||
# 不能同时使用证书和密码
|
||||
if [ -n "$password" ] && [ -n "$ssh_keys" ]; then
|
||||
error_and_exit "Cannot set both password and ssh key."
|
||||
fi
|
||||
}
|
||||
|
||||
get_cmd_path() {
|
||||
@@ -2341,30 +2356,28 @@ trim() {
|
||||
}
|
||||
|
||||
assert_username_valid() {
|
||||
if ! msg=$(is_username_valid); then
|
||||
error_and_exit "$msg"
|
||||
fi
|
||||
}
|
||||
|
||||
is_username_valid() {
|
||||
# https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-useraccounts-localaccounts-localaccount-name
|
||||
# 不能为 none [ ] / \ : | < > + = ; , ? * % @
|
||||
|
||||
# 账号为空,则使用 Administrator
|
||||
# 账号为空
|
||||
if [ -z "$username" ]; then
|
||||
echo "Username: Will use the built-in Administrator account in ISO language."
|
||||
return 0
|
||||
error_and_exit "Username: Can not be empty."
|
||||
fi
|
||||
|
||||
# 账号为 none
|
||||
if [ "$(to_lower <<<"$username")" = none ]; then
|
||||
echo "Username: Do not use the name \"NONE\", this is a restricted username."
|
||||
return 1
|
||||
error_and_exit "Username: Can not be 'none'."
|
||||
fi
|
||||
|
||||
# 账号包含非法字符
|
||||
if grep -q '[][/\:|<>+=;,?*%@]' <<<"$username"; then
|
||||
echo "Username: Do not use any of the following characters: / \ [ ] : | < > + = ; , ? * % @"
|
||||
return 1
|
||||
error_and_exit "Username: Do not use any of the following characters: / \ [ ] : | < > + = ; , ? * % @"
|
||||
fi
|
||||
}
|
||||
|
||||
# trans.sh 有同名方法
|
||||
is_administrator_username() {
|
||||
username_in_lower=$(to_lower <<<"$1")
|
||||
|
||||
# 如果输入以下用户名则忽略,并使用系统内置的 Administrator 账号
|
||||
# 防止系统有两个不同语言的 Administrator 账号而造成困扰
|
||||
@@ -2376,27 +2389,38 @@ is_username_valid() {
|
||||
администратор \
|
||||
järjestelmänvalvoja \
|
||||
rendszergazda; do
|
||||
if [ "$(to_lower <<<"$username")" = "$builtin_username" ]; then
|
||||
echo "Username: Will use the built-in Administrator account in ISO language."
|
||||
unset username
|
||||
if [ "$username_in_lower" = "$builtin_username" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
prompt_username() {
|
||||
info "prompt username"
|
||||
warn false "Leave blank to use Administrator"
|
||||
warn false "不填写则使用 Administrator"
|
||||
|
||||
if [ "$distro" = windows ]; then
|
||||
default_username=administrator
|
||||
else
|
||||
default_username=root
|
||||
fi
|
||||
|
||||
warn false "Set username, leave blank to use $default_username"
|
||||
warn false "设置用户名,不填写则使用 $default_username"
|
||||
IFS= read -r -p "Username: " username
|
||||
username="$(printf "%s" "$username" | trim)"
|
||||
|
||||
if [ -z "$username" ]; then
|
||||
username=$default_username
|
||||
fi
|
||||
assert_username_valid
|
||||
}
|
||||
|
||||
prompt_password() {
|
||||
info "prompt password"
|
||||
warn false "Leave blank to use a random password."
|
||||
warn false "不填写则使用随机密码"
|
||||
warn false "Set password, leave blank to use a random password."
|
||||
warn false "设置密码,不填写则使用随机密码"
|
||||
while true; do
|
||||
IFS= read -r -p "Password: " password
|
||||
if [ -n "$password" ]; then
|
||||
@@ -3626,7 +3650,7 @@ EOF
|
||||
# 2. 删除 debian busybox 无法识别的语法
|
||||
# 3. 删除 apk 语句
|
||||
# 4. debian 11/12 initrd 无法识别 > >
|
||||
# 5. debian 11/12 initrd 无法识别 < <
|
||||
# 5. debian 11/12 initrd 无法识别 < < ,注意可能分两行写
|
||||
# 6. debian 11 initrd 无法识别 set -E
|
||||
# 7. debian 11 initrd 无法识别 trap ERR
|
||||
# 8. debian 9 initrd 无法识别 ${string//find/replace}
|
||||
@@ -3637,11 +3661,16 @@ EOF
|
||||
-e "s/> >/$replace/" \
|
||||
-e "s/< </$replace/" \
|
||||
-e "s/\. <\(/$replace/" \
|
||||
-e "s/< \\\\/$replace/" \
|
||||
-e "s/ <\(/$replace/" \
|
||||
-e "s/^[[:space:]]*apk[[:space:]]/$replace/" \
|
||||
-e "s/^[[:space:]]*trap[[:space:]]/$replace/" \
|
||||
-e "s/\\$\{.*\/\/.*\/.*\}/$replace/" \
|
||||
-e "/^[[:space:]]*set[[:space:]]/s/E//" \
|
||||
$initrd_dir/trans.sh
|
||||
|
||||
# 测试魔改后的 trans.sh 有没有语法问题
|
||||
bash -n $initrd_dir/trans.sh
|
||||
}
|
||||
|
||||
get_disk_drivers() {
|
||||
@@ -4499,9 +4528,7 @@ while true; do
|
||||
shift 2
|
||||
;;
|
||||
--user | --username)
|
||||
if ! [ "$distro" = windows ]; then
|
||||
error_and_exit "$1 is only supported for installing Windows."
|
||||
fi
|
||||
[ -n "$2" ] || error_and_exit "Need value for $1"
|
||||
username="$(printf "%s" "$2" | trim)"
|
||||
assert_username_valid
|
||||
shift 2
|
||||
@@ -4682,7 +4709,7 @@ done
|
||||
verify_os_args
|
||||
|
||||
# 用户名
|
||||
if [ "$distro" = windows ] && [ -z "$username" ]; then
|
||||
if ! is_netboot_xyz && [ -z "$username" ]; then
|
||||
prompt_username
|
||||
fi
|
||||
|
||||
@@ -4964,54 +4991,130 @@ fi
|
||||
info 'info'
|
||||
echo "$distro $releasever"
|
||||
|
||||
case "$distro" in
|
||||
windows) username=${username:-administrator} ;;
|
||||
netboot.xyz) username= ;;
|
||||
dd | *) username=root ;;
|
||||
esac
|
||||
ssh_port=${ssh_port:-22}
|
||||
rdp_port=${rdp_port:-3389}
|
||||
web_port=${web_port:-80}
|
||||
|
||||
if [ -n "$username" ]; then
|
||||
if [ "$distro" = netboot.xyz ]; then
|
||||
:
|
||||
elif [ "$distro" = alpine ] && [ "$hold" = 1 ]; then
|
||||
info "Alpine Live OS"
|
||||
echo "Username: $username"
|
||||
if [ -n "$ssh_keys" ]; then
|
||||
echo "Public Key: $ssh_keys"
|
||||
else
|
||||
echo "Password: $password"
|
||||
fi
|
||||
if [ -n "$ssh_port" ]; then
|
||||
echo "SSH Port: $ssh_port"
|
||||
fi
|
||||
fi
|
||||
|
||||
if is_netboot_xyz; then
|
||||
echo 'Reboot to start netboot.xyz.'
|
||||
elif is_alpine_live; then
|
||||
echo 'Reboot to start Alpine Live OS.'
|
||||
elif is_use_dd; then
|
||||
elif [ "$distro" = fnos ]; then
|
||||
info "While Install (View Logs)"
|
||||
echo "Username: $username"
|
||||
if [ -n "$ssh_keys" ]; then
|
||||
echo "Public Key: $ssh_keys"
|
||||
else
|
||||
echo "Password: $password"
|
||||
fi
|
||||
echo "SSH Port: $ssh_port"
|
||||
echo "WEB Port: $web_port"
|
||||
|
||||
info "After Install"
|
||||
|
||||
echo "安装后不会开启 SSH 服务。"
|
||||
echo "你需要尽快到 http://IP:5666 配置账号密码。"
|
||||
echo
|
||||
echo "SSH Service is disabled after installation."
|
||||
echo "You need to config the username and password on http://IP:5666 as soon as possible."
|
||||
|
||||
elif [ "$distro" = windows ]; then
|
||||
info "While Install (View Logs)"
|
||||
echo "Username: $username"
|
||||
echo "Password: $password"
|
||||
echo "SSH Port: $ssh_port"
|
||||
echo "WEB Port: $web_port"
|
||||
|
||||
info "After Install"
|
||||
if is_administrator_username "$username"; then
|
||||
echo "Username: $username (Depends on Windows iso's language)"
|
||||
else
|
||||
echo "Username: $username"
|
||||
fi
|
||||
echo "Password: $password"
|
||||
echo "RDP Port: $rdp_port"
|
||||
|
||||
elif [ "$distro" = dd ]; then
|
||||
info "While Install (View Logs)"
|
||||
echo "Username: $username"
|
||||
if [ -n "$ssh_keys" ]; then
|
||||
echo "Public Key: $ssh_keys"
|
||||
else
|
||||
echo "Password: $password"
|
||||
fi
|
||||
echo "SSH Port: $ssh_port"
|
||||
echo "WEB Port: $web_port"
|
||||
|
||||
info "After Install"
|
||||
if [ -n "$cloud_data" ]; then
|
||||
echo "Cloud Data: $cloud_data"
|
||||
echo "Cloud Data Files: $cloud_data_files"
|
||||
else
|
||||
echo "Username: [Depends on image]"
|
||||
echo "Public Key: [Depends on image]"
|
||||
echo "Password: [Depends on image]"
|
||||
echo "SSH Port: [Depends on image]"
|
||||
fi
|
||||
show_dd_password_tips
|
||||
echo 'Reboot to start DD.'
|
||||
elif [ "$distro" = fnos ]; then
|
||||
echo "Special note for FNOS:"
|
||||
echo "Reboot to start the installation."
|
||||
echo "SSH login is disabled when installation completed."
|
||||
echo "You need to config the account and password on http://SERVER_IP:5666 as soon as possible."
|
||||
echo
|
||||
echo "飞牛 OS 注意事项:"
|
||||
echo "重启后开始安装。"
|
||||
echo "安装完成后不支持 SSH 登录。"
|
||||
echo "你需要尽快在 http://SERVER_IP:5666 配置账号密码。"
|
||||
|
||||
else
|
||||
echo "Reboot to start the installation."
|
||||
# 普通 linux
|
||||
info "While Install (View Logs)"
|
||||
echo "Username: $username"
|
||||
if [ -n "$ssh_keys" ]; then
|
||||
echo "Public Key: $ssh_keys"
|
||||
else
|
||||
echo "Password: $password"
|
||||
fi
|
||||
echo "SSH Port: $ssh_port"
|
||||
echo "WEB Port: $web_port"
|
||||
|
||||
info "After Install"
|
||||
echo "Username: $username"
|
||||
if [ -n "$ssh_keys" ]; then
|
||||
echo "Public Key: $ssh_keys"
|
||||
else
|
||||
echo "Password: $password"
|
||||
fi
|
||||
echo "SSH Port: $ssh_port"
|
||||
fi
|
||||
|
||||
if is_in_windows; then
|
||||
echo
|
||||
echo 'You can run this command to reboot:'
|
||||
echo 'shutdown /r /t 0'
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "If you want to revert all changes made by this script, run \"$reinstall_____ reset\""
|
||||
if [ "$distro" = netboot.xyz ]; then
|
||||
echo '重启后进入 netboot.xyz。'
|
||||
echo "或者现在运行 \"$reinstall_____ reset\" 以清除该引导项。"
|
||||
echo
|
||||
echo 'Reboot to start netboot.xyz.'
|
||||
echo "Or run \"$reinstall_____ reset\" now to clear this boot entry."
|
||||
echo
|
||||
|
||||
elif [ "$distro" = alpine ] && [ "$hold" = 1 ]; then
|
||||
echo '重启后进入 Alpine Live OS。'
|
||||
echo "或者现在运行 \"$reinstall_____ reset\" 以清除该引导项。"
|
||||
echo
|
||||
echo 'Reboot to start Alpine Live OS.'
|
||||
echo "Or run \"$reinstall_____ reset\" now to clear this boot entry."
|
||||
echo
|
||||
else
|
||||
warn false '警告:重装会清除主硬盘的所有数据,包括所有分区!'
|
||||
echo '重启后开始重装。'
|
||||
echo "或者现在运行 \"$reinstall_____ reset\" 以取消重装。"
|
||||
echo
|
||||
warn false 'Warning: Reinstalling will erase all data on the main disk, including all partitions!'
|
||||
echo 'Reboot to start the reinstallation.'
|
||||
echo "Or run \"$reinstall_____ reset\" now to cancel the reinstallation."
|
||||
fi
|
||||
echo
|
||||
|
||||
@@ -46,8 +46,24 @@ warn() {
|
||||
|
||||
error_and_exit() {
|
||||
error "$@"
|
||||
echo "Run '/trans.sh' to retry." >&2
|
||||
echo "Run '/trans.sh alpine' to install Alpine Linux instead." >&2
|
||||
|
||||
if is_have_cmd sudo; then
|
||||
sudo_='sudo '
|
||||
elif is_have_cmd doas; then
|
||||
sudo_='doas '
|
||||
else
|
||||
sudo_=
|
||||
fi
|
||||
|
||||
echo "Run '$sudo_/trans.sh' to retry." >&2
|
||||
echo "Run '$sudo_/trans.sh alpine' to install Alpine Linux instead." >&2
|
||||
|
||||
# 解除锁定,允许用户登录处理故障
|
||||
# passwd -u "$username" >/dev/null
|
||||
|
||||
# 用不着,因为 alpine 锁定账户后无法登录 ssh
|
||||
# 因此不会锁定
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -292,9 +308,6 @@ setup_nginx() {
|
||||
wget $confhome/logviewer.html -O /logviewer.html
|
||||
wget $confhome/logviewer-nginx.conf -O /etc/nginx/http.d/default.conf
|
||||
|
||||
if [ -z "$web_port" ]; then
|
||||
web_port=80
|
||||
fi
|
||||
sed -i "s/@WEB_PORT@/$web_port/gi" /etc/nginx/http.d/default.conf
|
||||
|
||||
# rc-service -q nginx start
|
||||
@@ -310,10 +323,6 @@ setup_websocketd() {
|
||||
wget $confhome/logviewer.html -O /tmp/index.html
|
||||
apk add coreutils
|
||||
|
||||
if [ -z "$web_port" ]; then
|
||||
web_port=80
|
||||
fi
|
||||
|
||||
pkill websocketd || true
|
||||
# websocketd 遇到 \n 才推送,因此要转换 \r 为 \n
|
||||
websocketd --port "$web_port" --loglevel=fatal --staticdir=/tmp \
|
||||
@@ -424,6 +433,16 @@ extract_env_from_cmdline() {
|
||||
fi
|
||||
done < <(xargs -n1 </proc/cmdline | grep "^${prefix}_" | sed "s/^${prefix}_//")
|
||||
done
|
||||
|
||||
# 如果空白则设置默认值
|
||||
if [ "$distro" = windows ]; then
|
||||
username=${username:-administrator}
|
||||
else
|
||||
username=${username:-root}
|
||||
fi
|
||||
ssh_port=${ssh_port:-22}
|
||||
rdp_port=${rdp_port:-3389}
|
||||
web_port=${web_port:-80}
|
||||
}
|
||||
|
||||
ensure_service_started() {
|
||||
@@ -1553,6 +1572,7 @@ install_alpine() {
|
||||
printf '\n' | chroot /os setup-ntp || true
|
||||
|
||||
# 设置公钥
|
||||
add_user_if_need /os
|
||||
if is_need_set_ssh_keys; then
|
||||
set_ssh_keys_and_del_password /os
|
||||
fi
|
||||
@@ -1795,21 +1815,69 @@ install_nixos() {
|
||||
nix_swap="swapDevices = [{ device = \"/swapfile\"; size = $swap_size; }];"
|
||||
fi
|
||||
|
||||
# keys
|
||||
if is_need_set_ssh_keys; then
|
||||
nix_ssh_keys_or_PermitRootLogin="
|
||||
services.openssh.settings.PasswordAuthentication = false;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
nix_user_keys_fragment="
|
||||
openssh.authorizedKeys.keys = [
|
||||
$(del_comment_lines </configs/ssh_keys | del_empty_lines | quote_line | add_space 2)
|
||||
];
|
||||
"
|
||||
fi
|
||||
|
||||
# root user
|
||||
if [ "$username" = root ]; then
|
||||
if is_need_set_ssh_keys; then
|
||||
nix_users="
|
||||
users.users.$username = {
|
||||
$(echo "$nix_user_keys_fragment" | add_space 2)
|
||||
};
|
||||
"
|
||||
else
|
||||
nix_ssh_keys_or_PermitRootLogin='services.openssh.settings.PermitRootLogin = "yes";'
|
||||
nix_users=""
|
||||
fi
|
||||
else
|
||||
# normal user
|
||||
# https://nixos.org/manual/nixos/stable/#sec-user-management
|
||||
nix_users=$(
|
||||
cat <<EOF
|
||||
users.users.$username = {
|
||||
isNormalUser = true;
|
||||
home = "/home/$username";
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"networkmanager"
|
||||
];
|
||||
$(echo "$nix_user_keys_fragment" | add_space 2)
|
||||
};
|
||||
|
||||
security.sudo.extraRules = [
|
||||
{ users = [ "$username" ]; commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ]; }
|
||||
];
|
||||
EOF
|
||||
)
|
||||
fi
|
||||
|
||||
# openssh
|
||||
nix_openssh="
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
$(
|
||||
{
|
||||
if is_need_change_ssh_port; then
|
||||
nix_ssh_ports="services.openssh.ports = [ $ssh_port ];"
|
||||
echo "ports = [ $ssh_port ];"
|
||||
fi
|
||||
if is_need_set_ssh_keys; then
|
||||
echo 'settings.PasswordAuthentication = false;'
|
||||
fi
|
||||
if [ "$username" = root ] && ! is_need_set_ssh_keys; then
|
||||
echo 'settings.PermitRootLogin = "yes";'
|
||||
fi
|
||||
} | add_space 2
|
||||
)
|
||||
};
|
||||
"
|
||||
|
||||
# frpc
|
||||
if ls /configs/frpc.* >/dev/null 2>&1; then
|
||||
nix_frpc=$(
|
||||
if false; then
|
||||
@@ -1856,9 +1924,8 @@ $nix_bootloader
|
||||
$nix_swap
|
||||
$nix_substituters
|
||||
boot.kernelParams = [ $(get_ttys console= | quote_word) ];
|
||||
services.openssh.enable = true;
|
||||
$nix_ssh_keys_or_PermitRootLogin
|
||||
$nix_ssh_ports
|
||||
$nix_users
|
||||
$nix_openssh
|
||||
$nix_frpc
|
||||
$(cat /tmp/nixos_network_config.nix)
|
||||
###################################################
|
||||
@@ -1906,7 +1973,7 @@ EOF
|
||||
|
||||
# 设置密码
|
||||
if ! is_need_set_ssh_keys; then
|
||||
echo "root:$(get_password_linux_sha512)" | nixos-enter --root /os -- \
|
||||
printf '%s\n' "$username:$(get_password_linux_sha512)" | nixos-enter --root /os -- \
|
||||
/run/current-system/sw/bin/chpasswd -e
|
||||
fi
|
||||
|
||||
@@ -2042,12 +2109,13 @@ basic_init() {
|
||||
fi
|
||||
|
||||
# 公钥/密码
|
||||
add_user_if_need "$os_dir"
|
||||
if is_need_set_ssh_keys; then
|
||||
set_ssh_keys_and_del_password $os_dir
|
||||
change_ssh_conf_for_root_key_login $os_dir
|
||||
change_ssh_conf_for_key_login $os_dir
|
||||
else
|
||||
change_root_password $os_dir
|
||||
change_ssh_conf_for_root_password_login $os_dir
|
||||
change_user_password $os_dir
|
||||
change_ssh_conf_for_password_login $os_dir
|
||||
fi
|
||||
|
||||
# 下载 fix-eth-name.service
|
||||
@@ -2119,6 +2187,10 @@ EOF
|
||||
if [ "$(uname -m)" = aarch64 ]; then
|
||||
pkgs="$pkgs archlinuxarm-keyring"
|
||||
fi
|
||||
if ! [ "$username" = root ]; then
|
||||
pkgs="$pkgs sudo"
|
||||
fi
|
||||
|
||||
pacstrap -K $os_dir $pkgs
|
||||
|
||||
# dns
|
||||
@@ -2270,6 +2342,10 @@ EOF
|
||||
chroot $os_dir emerge sys-fs/dosfstools
|
||||
fi
|
||||
|
||||
if ! [ "$username" = root ]; then
|
||||
chroot $os_dir emerge app-admin/sudo
|
||||
fi
|
||||
|
||||
# firmware + microcode
|
||||
if fw_pkgs=$(get_ucode_firmware_pkgs) && [ -n "$fw_pkgs" ]; then
|
||||
chroot $os_dir emerge $fw_pkgs
|
||||
@@ -3179,7 +3255,7 @@ modify_windows() {
|
||||
# 5. 设置用户密码永不过期
|
||||
# Azure 的 Windows 实例,初始用户的密码也是永不过期的
|
||||
# 管理员账号默认不会过期
|
||||
if [ -n "$username" ]; then
|
||||
if ! is_administrator_username "$username"; then
|
||||
cat <<EOF >$os_dir/windows-set-user-password-never-expires.bat
|
||||
wmic useraccount where name="$username" set passwordexpires=false || ^
|
||||
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Set-LocalUser -Name '$username' -PasswordNeverExpires \$true"
|
||||
@@ -3451,6 +3527,10 @@ remove_or_disable_cloud_init() {
|
||||
rm -f $os_dir/etc/cloud/cloud.cfg.rpmsave
|
||||
;;
|
||||
zypper)
|
||||
# 防止删除 cloud-init 时自动删除 sudo
|
||||
if ! [ "$username" = root ]; then
|
||||
sed -i '/^sudo$/d' "$os_dir/var/lib/zypp/AutoInstalled"
|
||||
fi
|
||||
# 加上 -u 才会删除依赖
|
||||
chroot $os_dir zypper remove -y -u cloud-init cloud-init-config-suse
|
||||
;;
|
||||
@@ -3562,6 +3642,7 @@ EOF
|
||||
# find_and_mount /boot
|
||||
# find_and_mount /boot/efi
|
||||
# fedora 的 fstab 还有 /home /var,因此用 mount -a
|
||||
# 不然无法往 /home/$username 写入 ssh 公钥
|
||||
chroot $os_dir mount -a
|
||||
|
||||
cp_resolv_conf $os_dir
|
||||
@@ -3823,7 +3904,7 @@ EOF
|
||||
chroot $os_dir zypper remove -y --force-resolution $origin_kernel
|
||||
fi
|
||||
if $need_password_workaround; then
|
||||
chroot $os_dir passwd -d root
|
||||
chroot $os_dir passwd -d -l root
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -3860,7 +3941,7 @@ EOF
|
||||
|
||||
# 在这里修改密码,而不是用cloud-init,因为我们的默认密码太弱
|
||||
is_password_plaintext && sed -i 's/enforce=everyone/enforce=none/' $os_dir/etc/security/passwdqc.conf
|
||||
change_root_password $os_dir
|
||||
change_user_password $os_dir
|
||||
is_password_plaintext && sed -i 's/enforce=none/enforce=everyone/' $os_dir/etc/security/passwdqc.conf
|
||||
|
||||
# 下载仓库,选择 profile
|
||||
@@ -4045,19 +4126,125 @@ create_swap() {
|
||||
fi
|
||||
}
|
||||
|
||||
set_ssh_keys_and_del_password() {
|
||||
os_dir=$1
|
||||
info 'set ssh keys'
|
||||
del_user_password_and_lock() {
|
||||
local os_dir=$1
|
||||
local username=$2
|
||||
|
||||
# 添加公钥
|
||||
(
|
||||
umask 077
|
||||
mkdir -p $os_dir/root/.ssh
|
||||
cat /configs/ssh_keys >$os_dir/root/.ssh/authorized_keys
|
||||
)
|
||||
# 锁定用户后 ssh 能否登录
|
||||
# alpine ×
|
||||
# 其它系统 √
|
||||
|
||||
# root 空密码,不锁定 root,其它用户用 su - root 能否切换到 root
|
||||
# alpine ×
|
||||
# 其它系统 √
|
||||
|
||||
# centos 7 不支持一行命令同时 -d -l
|
||||
# passwd: Only one of -l, -u, -d, -S may be specified.
|
||||
|
||||
# 删除密码
|
||||
chroot $os_dir passwd -d root
|
||||
chroot "$os_dir" passwd -d "$username"
|
||||
|
||||
# 锁定用户
|
||||
if ! [ -e "$os_dir/etc/alpine-release" ]; then
|
||||
chroot "$os_dir" passwd -l "$username"
|
||||
fi
|
||||
|
||||
# alpine 锁定用户无法登录 ssh
|
||||
# 因为 alpine 默认不开启 pam
|
||||
# 其他系统默认开启
|
||||
|
||||
# 不开启 pam 的话,锁定用户无法登录 ssh
|
||||
# 开启 pam 后可以
|
||||
|
||||
# alpine 是通过安装 openssh-server-pam 开启 pam
|
||||
# 不需要设置 UsePAM yes 也无法识别 UsePAM yes
|
||||
# localhost:~# sshd -G | grep -i pam
|
||||
# /etc/ssh/sshd_config line 88: Unsupported option UsePAM
|
||||
}
|
||||
|
||||
set_ssh_keys_and_del_password() {
|
||||
local os_dir=$1
|
||||
|
||||
info 'set ssh keys'
|
||||
|
||||
if [ "$username" = root ]; then
|
||||
local user_home="/root"
|
||||
else
|
||||
local user_home="/home/$username"
|
||||
fi
|
||||
|
||||
# 添加公钥
|
||||
if true; then
|
||||
(
|
||||
umask 077
|
||||
mkdir -p "$os_dir/$user_home/.ssh"
|
||||
cat /configs/ssh_keys >"$os_dir/$user_home/.ssh/authorized_keys"
|
||||
)
|
||||
# 注意要用 chroot,否则 uid/gid 是 alpine live os 下的 uid/gid
|
||||
chroot "$os_dir" chown "$username:$username" "$user_home"
|
||||
chroot "$os_dir" chown "$username:$username" "$user_home/.ssh"
|
||||
chroot "$os_dir" chown "$username:$username" "$user_home/.ssh/authorized_keys"
|
||||
else
|
||||
(
|
||||
# 如果日后添加 bsd 无法 chroot 时可以这样
|
||||
umask 077
|
||||
read -r owner group < \
|
||||
<(awk -F: -v user="$username" '$1==user {print $3,$4}' "$os_dir/etc/passwd")
|
||||
install -D \
|
||||
-m 600 \
|
||||
-o "$owner" \
|
||||
-g "$group" \
|
||||
/configs/ssh_keys \
|
||||
"$os_dir/$user_home/.ssh/authorized_keys"
|
||||
)
|
||||
fi
|
||||
|
||||
# 删除密码/锁定用户
|
||||
del_user_password_and_lock "$os_dir" "$username"
|
||||
|
||||
# debian 云镜像 /etc/shadow 的 root 条目为
|
||||
# root:!unprovisioned:20591:0:99999:7:::
|
||||
# 首次开机会停在设置 root 密码界面,且阻塞 ssh 服务
|
||||
# 因此这里手动清空 root 密码并锁定
|
||||
if ! [ "$username" = root ] && is_have_cmd_on_disk "$os_dir" systemd-firstboot; then
|
||||
del_user_password_and_lock "$os_dir" root
|
||||
fi
|
||||
}
|
||||
|
||||
_is_ssh_kv_effective() {
|
||||
local os_dir=$1
|
||||
local key=$2
|
||||
local value=$3
|
||||
|
||||
# centos 7 不支持 -G
|
||||
if res=$(chroot "$os_dir" sshd -G 2>/dev/null || chroot "$os_dir" sshd -T 2>/dev/null); then
|
||||
printf "%s\n" "$res" | grep -Fxiq "$key $value"
|
||||
else
|
||||
error_and_exit "Failed to verify sshd config."
|
||||
fi
|
||||
}
|
||||
|
||||
is_ssh_kv_effective() {
|
||||
local os_dir=$1
|
||||
local key=$2
|
||||
local value=$3
|
||||
|
||||
if _is_ssh_kv_effective "$os_dir" "$key" "$value"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# centos 7 设置 prohibit-password ,sshd -T 会显示成 without-password
|
||||
if [ "$(echo "$key" | to_lower)" = "permitrootlogin" ] && {
|
||||
[ "$(echo "$value" | to_lower)" = "prohibit-password" ] ||
|
||||
[ "$(echo "$value" | to_lower)" = "without-password" ]
|
||||
}; then
|
||||
if _is_ssh_kv_effective "$os_dir" "permitrootlogin" "prohibit-password" ||
|
||||
_is_ssh_kv_effective "$os_dir" "permitrootlogin" "without-password"; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
change_ssh_conf_if_different() {
|
||||
@@ -4079,7 +4266,7 @@ change_ssh_conf_if_different() {
|
||||
# PasswordAuthentication no
|
||||
|
||||
# 0. 如果已经有这个配置,则不修改,避免不必要的改动
|
||||
if chroot "$os_dir" sshd -G | grep -Fxiq "$key $value"; then
|
||||
if is_ssh_kv_effective "$os_dir" "$key" "$value"; then
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -4109,19 +4296,25 @@ change_ssh_conf_if_different() {
|
||||
echo "$key $value" >>$os_dir/etc/ssh/sshd_config
|
||||
fi
|
||||
fi
|
||||
|
||||
# 验证是否成功
|
||||
if ! is_ssh_kv_effective "$os_dir" "$key" "$value"; then
|
||||
error_and_exit "Failed to set sshd config $key $value."
|
||||
fi
|
||||
}
|
||||
|
||||
change_ssh_conf_for_root_key_login() {
|
||||
change_ssh_conf_for_key_login() {
|
||||
local os_dir=$1
|
||||
|
||||
# 目前脚本只用 root ,不需要设置这个
|
||||
# change_ssh_conf_if_different "$os_dir" PasswordAuthentication no
|
||||
change_ssh_conf_if_different "$os_dir" PasswordAuthentication no
|
||||
|
||||
# 这个也不需要设置,默认就是 prohibit-password
|
||||
# change_ssh_conf_if_different "$os_dir" PermitRootLogin prohibit-password
|
||||
# centos 7 PermitRootLogin 默认是 yes,而不是 prohibit-password
|
||||
if [ "$username" = root ]; then
|
||||
change_ssh_conf_if_different "$os_dir" PermitRootLogin prohibit-password
|
||||
fi
|
||||
}
|
||||
|
||||
change_ssh_conf_for_root_password_login() {
|
||||
change_ssh_conf_for_password_login() {
|
||||
local os_dir=$1
|
||||
|
||||
# opensuse 16/tumbleweed 安装 openssh-server-config-rootlogin
|
||||
@@ -4137,7 +4330,10 @@ change_ssh_conf_for_root_password_login() {
|
||||
# PasswordAuthentication 默认是 yes
|
||||
# 但某些发行版会在 sshd_config.d 里设置 PasswordAuthentication no
|
||||
change_ssh_conf_if_different "$os_dir" PasswordAuthentication yes
|
||||
|
||||
if [ "$username" = root ]; then
|
||||
change_ssh_conf_if_different "$os_dir" PermitRootLogin yes
|
||||
fi
|
||||
}
|
||||
|
||||
change_ssh_port() {
|
||||
@@ -4147,10 +4343,117 @@ change_ssh_port() {
|
||||
change_ssh_conf_if_different "$os_dir" Port "$ssh_port"
|
||||
}
|
||||
|
||||
change_root_password() {
|
||||
os_dir=$1
|
||||
# 暂时用不着
|
||||
add_user_if_need_for_alpine() {
|
||||
local os_dir=$1
|
||||
|
||||
info 'change root password'
|
||||
if ! grep -q "^$username:" "$os_dir/etc/passwd"; then
|
||||
# -a Create admin user. Add to wheel group and set up doas
|
||||
# -u Unlock the user automatically (eg. creating the user non-interactively
|
||||
# with an ssh key for login)
|
||||
if is_need_set_ssh_keys; then
|
||||
chroot "$os_dir" setup-user -a -u -k "$(cat /configs/ssh_keys)" "$username"
|
||||
else
|
||||
chroot "$os_dir" setup-user -a -u "$username"
|
||||
change_user_password $os_dir
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
add_user_if_need() {
|
||||
local os_dir=$1
|
||||
|
||||
# 添加用户
|
||||
if ! grep -q "^$username:" "$os_dir/etc/passwd"; then
|
||||
# debian 推荐使用 adduser 而不是 useradd
|
||||
# https://manpages.debian.org/trixie/passwd/useradd.8.en.html
|
||||
# useradd is a low level utility for adding users.
|
||||
# On Debian, administrators should usually use adduser(8) instead.
|
||||
|
||||
# adduser 会从 /etc/adduser.conf 读取默认要添加的组
|
||||
# 然而通常这个值是空白
|
||||
|
||||
# alpine
|
||||
if is_have_cmd_on_disk "$os_dir" adduser &&
|
||||
chroot "$os_dir" adduser --help 2>&1 | grep -Fq -- BusyBox; then
|
||||
chroot "$os_dir" adduser --disabled-password "$username"
|
||||
|
||||
# debian/ubuntu
|
||||
elif is_have_cmd_on_disk "$os_dir" adduser &&
|
||||
chroot "$os_dir" adduser --help 2>&1 | grep -Fq -- '--disabled-password'; then
|
||||
chroot "$os_dir" adduser --disabled-password --comment '' "$username"
|
||||
|
||||
# el
|
||||
elif is_have_cmd_on_disk "$os_dir" adduser &&
|
||||
chroot "$os_dir" adduser --help 2>&1 | grep -Fq -- '--password'; then
|
||||
chroot "$os_dir" adduser --password ! "$username"
|
||||
|
||||
# arch/gentoo 默认没有 adduser
|
||||
else
|
||||
chroot "$os_dir" useradd -m "$username"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 添加到 wheel/sudo 组
|
||||
if ! [ "$username" = root ]; then
|
||||
if [ -e "$os_dir/etc/alpine-release" ]; then
|
||||
# alpine
|
||||
# https://github.com/alpinelinux/alpine-conf/blob/master/setup-user.in#L168
|
||||
|
||||
# 安装 doas
|
||||
chroot "$os_dir" apk add doas doas-sudo-shim
|
||||
mkdir -p "$os_dir/etc/doas.d"
|
||||
|
||||
# 添加用户到组
|
||||
chroot "$os_dir" addgroup "$username" wheel
|
||||
|
||||
# doas: 添加 wheel 组
|
||||
local file="$os_dir/etc/doas.d/20-wheel.conf"
|
||||
local content="permit persist :wheel"
|
||||
if ! grep -q "^$content" "$file" 2>/dev/null; then
|
||||
echo "$content" >>"$file"
|
||||
fi
|
||||
|
||||
# doas: 添加单个用户 nopass
|
||||
echo "permit nopass $username" >"$os_dir/etc/doas.d/99-$username.conf"
|
||||
else
|
||||
# 通常用 wheel 组
|
||||
# debian/ubuntu 没有 wheel 组,只有 sudo 组
|
||||
|
||||
# aws lightsail 上测试默认用户加入了哪些组
|
||||
# debian admin : admin adm dialout cdrom floppy sudo audio dip video plugdev
|
||||
# ubuntu ubuntu : ubuntu adm cdrom sudo dip lxd
|
||||
# almalinux ec2-user : ec2-user adm systemd-journal
|
||||
# opensuse ec2-user : ec2-user
|
||||
|
||||
# 添加用户到组
|
||||
for group in \
|
||||
wheel sudo \
|
||||
adm dialout cdrom floppy audio dip video plugdev lxd systemd-journal; do
|
||||
if grep -q "^$group:" "$os_dir/etc/group"; then
|
||||
# chroot "$os_dir" addgroup "$username" "$group"
|
||||
chroot "$os_dir" usermod -aG "$group" "$username"
|
||||
fi
|
||||
done
|
||||
|
||||
# sudo: gentoo 安装 sudo 后也没有 /etc/sudoers.d
|
||||
if ! [ -d "$os_dir/etc/sudoers.d" ]; then
|
||||
install -d -m 0750 "$os_dir/etc/sudoers.d"
|
||||
fi
|
||||
|
||||
# sudo: 添加单个用户 NOPASSWD
|
||||
# https://wiki.archlinux.org/title/Sudo#Sudoers_default_file_permissions
|
||||
local file="$os_dir/etc/sudoers.d/99-$username"
|
||||
printf '%s\n' "$username ALL=(ALL) NOPASSWD:ALL" >"$file"
|
||||
chmod 0440 "$file"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
change_user_password() {
|
||||
local os_dir=$1
|
||||
|
||||
info 'change user password'
|
||||
|
||||
if is_password_plaintext; then
|
||||
pam_d=$os_dir/etc/pam.d
|
||||
@@ -4184,13 +4487,13 @@ change_root_password() {
|
||||
|
||||
# 分两行写,不然遇到错误不会终止
|
||||
plaintext=$(get_password_plaintext)
|
||||
echo "root:$plaintext" | chroot $os_dir chpasswd
|
||||
printf '%s\n' "$username:$plaintext" | chroot $os_dir chpasswd
|
||||
|
||||
if $has_pamd_chpasswd; then
|
||||
mv $pam_d/chpasswd.orig $pam_d/chpasswd
|
||||
fi
|
||||
else
|
||||
echo "root:$(get_password_linux_sha512)" | chroot $os_dir chpasswd -e
|
||||
printf '%s\n' "$username:$(get_password_linux_sha512)" | chroot $os_dir chpasswd -e
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -4460,6 +4763,7 @@ chroot_apt_autoremove() {
|
||||
del_default_user() {
|
||||
os_dir=$1
|
||||
|
||||
local user
|
||||
while read -r user; do
|
||||
if grep ^$user':\$' "$os_dir/etc/shadow"; then
|
||||
echo "Deleting user $user"
|
||||
@@ -4593,18 +4897,20 @@ install_fnos() {
|
||||
mount_pseudo_fs /os
|
||||
|
||||
# 更改密码
|
||||
if false; then
|
||||
if is_need_set_ssh_keys; then
|
||||
set_ssh_keys_and_del_password $os_dir
|
||||
else
|
||||
change_root_password $os_dir
|
||||
change_user_password $os_dir
|
||||
fi
|
||||
fi
|
||||
|
||||
# ssh root 登录,测试用
|
||||
if false; then
|
||||
if is_need_set_ssh_keys; then
|
||||
change_ssh_conf_for_root_key_login $os_dir
|
||||
change_ssh_conf_for_key_login $os_dir
|
||||
else
|
||||
change_ssh_conf_for_root_password_login $os_dir
|
||||
change_ssh_conf_for_password_login $os_dir
|
||||
fi
|
||||
chroot $os_dir systemctl enable ssh
|
||||
fi
|
||||
@@ -5756,6 +6062,26 @@ is_nt_ver_ge() {
|
||||
[ "$orig" = "$sorted" ]
|
||||
}
|
||||
|
||||
# reinstall.sh 有同名方法
|
||||
is_administrator_username() {
|
||||
username_in_lower=$(printf "%s" "$1" | to_lower)
|
||||
|
||||
for builtin_username in \
|
||||
administrator \
|
||||
administrador \
|
||||
administrateur \
|
||||
administratör \
|
||||
администратор \
|
||||
järjestelmänvalvoja \
|
||||
rendszergazda; do
|
||||
if [ "$username_in_lower" = "$builtin_username" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
get_cloud_vendor() {
|
||||
# busybox blkid 不显示 sr0 的 UUID
|
||||
apk add lsblk
|
||||
@@ -7218,26 +7544,26 @@ EOF
|
||||
/tmp/autounattend.xml
|
||||
|
||||
# 账号密码
|
||||
if [ -n "$username" ]; then
|
||||
# 普通账号
|
||||
password_base64=$(get_password_windows_user_base64)
|
||||
xmlstarlet ed -L -N x="urn:schemas-microsoft-com:unattend" \
|
||||
-d "//x:AdministratorPassword" \
|
||||
/tmp/autounattend.xml
|
||||
sed -i \
|
||||
-e "s|%enable_administrator%|0|" \
|
||||
-e "s|%user_username%|$username|" \
|
||||
-e "s|%user_password%|$password_base64|" \
|
||||
/tmp/autounattend.xml
|
||||
else
|
||||
if is_administrator_username "$username"; then
|
||||
# Administrator
|
||||
password_base64=$(get_password_windows_administrator_base64)
|
||||
xmlstarlet ed -L -N x="urn:schemas-microsoft-com:unattend" \
|
||||
-d "//x:LocalAccounts" \
|
||||
/tmp/autounattend.xml
|
||||
sed -i \
|
||||
-e "s|%enable_administrator%|1|" \
|
||||
-e "s|%administrator_password%|$password_base64|" \
|
||||
-e "s|%enable_administrator%|1|gi" \
|
||||
-e "s|%administrator_password%|$password_base64|gi" \
|
||||
/tmp/autounattend.xml
|
||||
else
|
||||
# 普通账号
|
||||
password_base64=$(get_password_windows_user_base64)
|
||||
xmlstarlet ed -L -N x="urn:schemas-microsoft-com:unattend" \
|
||||
-d "//x:AdministratorPassword" \
|
||||
/tmp/autounattend.xml
|
||||
sed -i \
|
||||
-e "s|%enable_administrator%|0|gi" \
|
||||
-e "s|%user_username%|$username|gi" \
|
||||
-e "s|%user_password%|$password_base64|gi" \
|
||||
/tmp/autounattend.xml
|
||||
fi
|
||||
|
||||
@@ -7838,13 +8164,14 @@ if is_need_change_ssh_port; then
|
||||
fi
|
||||
|
||||
# 设置密码,添加开机启动 + 开启 ssh 服务
|
||||
add_user_if_need /
|
||||
if is_need_set_ssh_keys; then
|
||||
set_ssh_keys_and_del_password /
|
||||
# 目前脚本只用 root,不需要设置这个
|
||||
# change_ssh_conf_if_different / PasswordAuthentication no
|
||||
change_ssh_conf_for_key_login /
|
||||
printf '\n' | setup-sshd
|
||||
else
|
||||
change_root_password /
|
||||
change_user_password /
|
||||
change_ssh_conf_for_password_login /
|
||||
printf '\nyes' | setup-sshd
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user