给VPS重装自定义系统(Linux)
文章目录
【注意】最后更新于 December 6, 2021,文中内容可能已过时,请谨慎使用。
关于 VPS
安装网上提供不少一键安装的脚本,但是不少服务器都不支持,会出现不少问题。我想用 openSUSE
,却没有找到相关的资料。
其实安装系统挺简单的,这个暂不提,最重要的还是引导的工作。而我们要远程安装一个系统,这个同样道理的,只要考虑下怎么把我们的安装程序启动就行。
openSUSE
提供相应的教程: OpenSUSE Remote Install。
接下来我们进行具体的操作。
获取基本配置
需要远程,我们得与 VPS
通网。如果可以的话,使用 Centos
目录结构更方便些。此处以 Debain
为示例。最后可以通过 VNC
查看信息,确保处理某些错误。
默认情况下,服务商已经为我们做好了这些,我们可以直接使用 SSH
远程连接上这台机器,一般的,我们需要获取到该机器现在配置的 IP
地址,我们后期需要配置该信息。同时还需要观察现有系统 boot
结构,这是我们用以启动的程序。
-
查看本机
IP
信息,部分服务商的网络方案不同,其IP
配置不同,有些是和你的外网IP
一致,有些则不然,只需要进入VPS
查看就行:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff altname enp0s3 altname ens3 inet <IPV4 ADDR> brd <IPV4 BRD> scope global eth0 valid_lft forever preferred_lft forever inet6 <IPV6 ADDR> scope link valid_lft forever preferred_lft forever
这台
VPS
有一张名为eth0
网卡,这里我们只需要记录IPV4 ADDR
上的信息即可。routel
命令是可以直接获取我们需要的信息:1 2 3 4 5 6 7
root@WHYQ:~# routel target gateway source proto scope dev tbl <TARGET> <GATEWAY> <IP > kernel link eth0 127.0.0.0 broadcast 127.0.0.1 kernel link lo local 127.0.0.0/ 8 local 127.0.0.1 kernel host lo local 127.0.0.1 local 127.0.0.1 kernel host lo local 127.255.255.255 broadcast 127.0.0.1 kernel link lo local
source
是IP
的信息,gateway
网关信息,我们后面都需要用到。 -
查看本机启动配置。一般的,
Linux
发行版都会有boot
目录,不同的服务商处理启动的方式也有所不同:1 2 3 4 5 6 7 8
# ls /boot/ -l total 34388 -rw-r--r-- 1 root root 236220 Aug 3 05:50 config-5.10.0-8-amd64 drwxr-xr-x 5 root root 4096 Oct 29 13:49 grub lrwxrwxrwx 1 root root 4 Aug 18 10:32 grub2 -> grub -rw-r--r-- 1 root root 28139888 Aug 18 10:13 initrd.img-5.10.0-8-amd64 -rw-r--r-- 1 root root 83 Aug 3 05:50 System.map-5.10.0-8-amd64 -rw-r--r-- 1 root root 6821216 Aug 3 05:50 vmlinuz-5.10.0-8-amd64
可以观察到
boot
目录下有内核相关的信息,其中grub
和grub2
分别是对应的启动文件,grub2
连接到grub
配置。我本地主机的目录:1 2 3 4 5 6
❯ ls /boot/ grub/ initramfs-5.10.61-gentoo-x86_64.img.old* initramfs-5.10.61-gentoo-x86_64.img* config-5.10.61-gentoo-x86_64.old* config-5.10.61-gentoo-x86_64* System.map-5.10.61-gentoo-x86_64.old* System.map-5.10.61-gentoo-x86_64* vmlinuz-5.10.61-gentoo-x86_64.old* vmlinuz-5.10.61-gentoo-x86_64* EFI/
还是有稍微区别的,
VPS
明显是不支持EFI
的,但那并不影响,无论是传统启动还是EFI
启动,最终还是击中grub
上面的配置,这个细节暂时不提。你也可以查看本机是否支持
EFI
:1 2
# ls /lib/firmware/efi ls: cannot access '/lib/firmware/efi': No such file or directory?
可以判断系统的磁盘类型是
gpt
还是mbr
,后续安装系统的使用还需要依造该类型选择的磁盘类型,否则系统可能无法正常启动,还需要自行配置grub
的配置指向,则该虚拟机默认情况下root
指向的是(hd0, msdos1)
,是mbr
了引导的系统。openSUSE
默认使用gpt
磁盘类型,必须在后续安装的过程中修改磁盘类型,才能确保系统正确引导。 -
观察
grub
配置,后续需要依造现有的配置模仿改造配置程序,确保适应服务商的启动方案:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
root@WHYQ:/boot# cat grub2/grub.cfg # # DO NOT EDIT THIS FILE # # It is automatically generated by grub-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ## ... set default="0" set linux_gfx_mode= export linux_gfx_mode menuentry 'Debian GNU/Linux' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-/dev/vda1' { load_video insmod gzio if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 echo 'Loading Linux 5.10.0-8-amd64 ...' linux /boot/vmlinuz-5.10.0-8-amd64 root=/dev/vda1 ro net.ifnames=0 biosdevname=0 quiet echo 'Loading initial ramdisk ...' initrd /boot/initrd.img-5.10.0-8-amd64 } submenu 'Advanced options for Debian GNU/Linux' $menuentry_id_option 'gnulinux-advanced-/dev/vda1' { menuentry 'Debian GNU/Linux, with Linux 5.10.0-8-amd64' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.10.0-8-amd64-advanced-/dev/vda1' { load_video insmod gzio if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 echo 'Loading Linux 5.10.0-8-amd64 ...' linux /boot/vmlinuz-5.10.0-8-amd64 root=/dev/vda1 ro net.ifnames=0 biosdevname=0 quiet echo 'Loading initial ramdisk ...' initrd /boot/initrd.img-5.10.0-8-amd64 } } ## ... ### END /etc/grub.d/10_linux ### END /etc/grub.d/41_custom ###
此处保留了核心配置。查看其中的
menuentry
部分,就是需要配置内核的地方,其中linux
和initrd
是配置启动参数和内核的地方,我们需要做的修改就在这一部分。
该文章是 21 过年左右写的,那时候该服务商的启动脚本还很坑爹,
grub:1
和grub:2
共存,先走grub:1
,再走grub:2
,因为太繁杂了,当时就没有注意,直接借助VNC
跳过了,现在的配置看起来相对正常了。原有的问题复现也没有太大意义,于是删除了。
配置安装程序
实际上就是让启动菜单引导到发行版提供的内核文件中,initramfs
中可以编译进一个小的应急系统(看发行版如何配置),这个系统直接写进内存,就可以当作安装程序来用了,理论上只有能联网,啥都能干。当然,部分服务商也提供应急系统,那就不用做任何配置,直接进系统,把文件写进系统盘,就成装系统了。
openSUSE
提供的远程安装方法中,需要下载两个文件:
|
|
一个小白都能比对出来,我们下的文件就是之前 grub
配置中的 linux
和 initrd
。这是 linux
内核相关的配置,linux
自然是内核程序,initrd
是我们前面提到的 initramfs
,可以理解它能直接写进内存(实际就是 RAM
磁盘),编译过程可以给它写很多东西,看你自己的需求。如果你使用 Gentoo
,编译内核是常用的事情,initramfs
可以包含 btrfs
lvm
之类的核心依赖,如果里面不写进这些东西,那么安装了该文件系统的系统就无法启动起来。当然其他发行版都可以自行编译内核和自己的 initramfs
,不管出于什么目的。
下面有两个方法,请查看完再选择对应的方法。
方法一: grub
引导
而 openSUSE
提供的是一个用于引导安装的程序,我们可以通过内核参数来配置初始化该程序,如下(grub
配置):
|
|
其他引导器也是一样的,都需要配置 linux
和 initrd
两个选项,不提。
此处更新文章,打算直接使用最新版本的
openSUSE Leap
。如果该文章太久远了,你可以自行通过Get openSUSE
查看相应的版本。
Get openSUSE
中提供了不少镜像,如果需要本地安装,均可在此下载,我们需要下载的文件需要点击需要进入他们的镜像源才能找到,该页面只提供 ISO
安装盘。我们需要的是一个可以执行远程安装的 linux
和 initrd
。
镜像源 中包含了几乎所有镜像,我们进入 15.3/repo/oss/boot/x86_64
,可以对应你的系统架构进入,架构查看使用 uname -m
查看。
该处提供了几乎所有情况下可供系统启动的配置文件,openSUSE
中 grub
使用的主题也有,我们就不需要这么麻烦了,直接拿 linux
和 initrd
来用就是了。
|
|
与之前一样,只是更换了版本,如果需要其他版本,更换 15.3
就行,可能镜像源的结构会发生改变,应当先通过链接查看以下结构,在将链接替换即可。
随后我们可以看到以下结构:
|
|
之后我们只要将 grub
指向到我们的 vmlinuz.install
和 initrd.install
即可。我们前面已经了解了 grub.cfg
的配置了,只需要替换相关的字段就行了。
|
|
我们已经将 vmlinuz
和 initrd
下载到 boot
文件夹。但是我们还需要配置内核相关信息,因此直接用 sed
不大方便,我们直接编辑文件。一般系统自带 vi
(不是 vim
),可以用 vi
直接编辑。
但可能 vi
会提醒你:W10: Warning: Changing a readonly file
。
|
|
文件权限现在只有只读权限,添加即可:
|
|
u+w
是给当前用户添加可写权限,VPS
可以获取 root
权限,自然可以直接操作。(无 root
就别提重装系统啦。)
|
|
其中 linux
配置了不少选项:
usessh=1
,提供ssh
服务,同时需要设置密码sshpassword
,此后可以使用该密码进行安装了;install
是安装源,如果不指定,登录上也会要求指定的;hostip
、gateway
和nameserver
就是我们之前查看的信息了,nameserver
你可以看看本机原来使用的是:cat /etc/resolv.conf
。
hostip
和 gateway
一定要和 ip addr
查看的一致,否则的话可能会连接不上网络,就无法打通连接了。
配置好后重置系统即可,如果有 VNC
连接可以查看重启的过程,如果没有就等一阵子重连即可。实在崩了,可以尝试通过面板重装再来。
如果你的系统还使用 grub:1
,同理,可以这么配置:
|
|
一般 VNC
登录上去可以使用,有可能程序的流程配置修改了,导致系统无法正常启动,可以参考前文提到的文档 查看最新信息。
方法二: kexec
启动
只要你的系统不是需要编译的 Gentoo
或者 LFS
,例如 Debian
,直接安装 kexec-tools
就可以实现内核热启动了。
|
|
查看 kexec
文档:
|
|
可以看到这个参数配置和我们配置 grub
是一致的,那我们照猫画虎来一波:
|
|
或者可以修改官方提供的脚本:
|
|
如果 IP
信息配置出错,无法联网就需要借助其他工具重启连接上主机了。而且 vmlinuz
和 initrd
的版本要和 install
配置的 repo
一致,否则系统会请求确定是否重启,没有连接 VNC
则很难处理这个请求,因为此时 SSH
还没有启动。
安装系统
等待安装系统完成重启,信息配置准确,则可以进入系统。
|
|
或者:
|
|
用以启动 X
界面,图形化安装。
如果使用终端界面,直接执行 yast.ssh
即可,此处我们直接使用终端进行安装,图形界面连接不太稳定。
|
|
<TAB>
键可以更换按钮,其他的按提示进行即可,你甚至可以切换中文界面进行安装,安装系统会自动添加依赖信息。
图形化安装界面后续就不做介绍了,openSUSE
的安装做的很友好,Enter
Enter
就行了。当然,我们前面查看到了系统不支持 EFI
,如果支持,你可以直接默认进行下去,不支持的话需要在分配磁盘的时候自定义修改磁盘类型为 MBR
。
在最后的确认安装界面当中看到:
|
|
就说明磁盘配置是正确的。具体方法可以自行搜索,这部份并不难。
配置系统
系统完成安装后,需要做一些简单的配置,也可以说是加强的配置。
首先方便自己的远程控制,可以将自己的公钥发布到 VPS
当中:
|
|
之后就不需要输入密码登录的,当然也应该关闭 SSH
密码登录,这样只要你本机的私钥不泄漏,谁都进不了你的主机了。
同时,为了方便自己本机的登录,可以给 SSH Client
添加配置,使用别名进行登录:
|
|
SSH
配置
此配置在 VPS
当中。
-
sshd
加强配置登录成功之后,确保安全(最基本避免暴力破解,但要确保存有密钥的电脑不被破解),我们就可以禁止密码登录了,仅允许密钥登录与修改端口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
### 服务器 vim /etc/ssh/sshd_config # 修改部分内容 PermitRootLogin no # 禁用root登录,可以普通用户su PasswordAuthentication no ChallengeResponseAuthentication no # 禁用密码登录 ## 可以修改端口 Port 22 # 保留一个可以使用的端口,测试新端口可用后再关闭原来的端口 # 如果系统设置了apparmor或者selinux,需要同时开启对应的端口 Port 10222 # 改成你需要的 ## selinux semanage port -m -t ssh_port_t -p tcp 10222 # 开放端口给ssh ## apparmor 暂时找不到对应的方法 # 可以参考https://gitlab.com/apparmor/apparmor/-/raw/master/profiles/apparmor/profiles/extras/usr.sbin.sshd ## 端口修改注意,应该提前在防火墙开通端口,否则会造成无法ssh登录的窘境 # 随后重启ssh服务 systemctl restart sshd # openrc使用 rc-service sshd restart ## 完成后,不要退出当前用户,先行测试是否能够登录(避免错误设置)
其中修改端口,我个人认为实用性质不大,端口扫描只是一会儿的事情,你开
22
端口还是开20002
端口都是一样的,只要端口扫描出来,还是能够暴力登录的,因此限制好服务的安全性就好,尽量避免被暴力破解,至于被暴力的入口,那是封不死的,你只能找办法把施暴者隔离起来不理会。 -
确保只有某个用户可以通过ssh登录也很重要(可以生成随机名称作为
ssh
登录用户名,其他用户依靠su
登录)。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
### 服务器 vim /etc/ssh/sshd_config # 限制用户访问 AllowUsers <users> # 空闲时间退出(在线时间) ClientAliveInterval 600 ClientAliveCountMax 0 #- 此处设置为600s,即十分钟无操作,将用户下线; # 限制登录次数,认证失误一次就断开链接 MaxAuthTries 1 # 随后重启ssh服务 systemctl restart sshd # openrc使用 rc-service sshd restart ## 同样,完成后,不要退出当前用户,先行测试是否能够登录(避免错误设置) # 其他用户无法认证 Received disconnect from <ip> port 22:2: Too many authentication failures Disconnected from <ip> port 22
``
-
限制
IP
登录,如果你有固定IP
,而且只希望该IP
登录主机,那么就更好了:1 2 3 4 5 6 7 8 9 10 11 12 13
### 服务器 vim /etc/ssh/sshd_config AllowUsers <user>@<ip> # 允许ip段 vim /etc/hosts.allow sshd:<ip>:allow # 禁止其他ip段 vim /etc/hosts.deny sshd:ALL ## 如此只有你允许的ip和用户可以登录了 # 重启sshd即可
小结
其实这里总归总的只是借用了 openSUSE
的文档,重新整理之后才发现这一部分官网本来就描述的很清楚。
总而言之,对于 Linux
系统,只有你有一个系统,就能尝试将引导文件写入引导,从而跳转到另一个系统当中去,但是由于服务商提供的不同架构(VPS
: 虚拟主机),虚拟主机的架构各有不同,主要做的事情是仿造现有的架构执行安装,就没有太大的问题啦。
如果你想在你现在的 Linux
下安装另外一个系统,不必要加个 U盘
:
- 观察现有的
boot
目录结构及配置文件相关; - 记录现在配置的网络连接信息;
- 找到目标系统的
Network Install
或者是Remote Install
的相关文件; - 引导目标系统的
initrd
和vmlinuz
; - 正常系统一样安装;
其实就这么几个步骤。!