使用Kickstart自定义CentOS ISO镜像内置第三方软件
说明
本文档介绍了如何使用Kickstart自定义CentOS的安装过程,并在Kickstart配置文件中添加自定义内容,涉及自定义脚本、结合定义开机服务安装第三方软件等:
- 根据等保二级要求,完成CentOS安全加固。
- Docker、Docker Compose完成安装。
- MySQL完成安装,且根据等保二级要求完成安全加固。
- phpMyAdmin完成安装。
另外,此自定义CentOS 安装镜像为自动安装,中间过程无需再手动选择。
Kickstart简介:docs.centos.org/en-US/cento…
本文中制作的CentOS版本为7.6
文件/安装包
生成自定义ISO镜像时,涉及到的关键文件的目录结构如下:
自定义相关文件的用途:
文件/安装包名 | 用途 |
---|---|
ks.cfg | Kickstart配置文件,定义了CentOS安装过程,自定义脚本、第三方软件安装过程等 |
isolinux.cfg | 配置ks.cfg位置 |
phpMyAdmin.tar | phpMyAdmin的Docker镜像 |
mysql5742.tar | MySQL5.7.42的Docker镜像 |
mysoft-install.sh | 第三方软件安装脚本,CentOS安装完成且启动后执行。 |
mysoft.tar.gz | MySQL初始化数据及第三方软件安装的位置 |
initialmysoft.service | CentOS安装完成、启动且Docker启动后,要运行的服务,指定要运行mysoft-install.sh脚本 |
docker-compose-linux-x86_64 | docker-compose离线安装包 |
docker-compose.yml | docker-compose文件,完成MySQL及phpMyAdmin容器启动。 |
docker-24.0.4.tgz | docker离线安装包 |
docker.service | 用于注册的docker服务 |
1panel-v1.3.6-linux-amd64.tar.gz | 1panel的安装包,此软件主要用于监控宿主机的运行情况。 |
CentOS-7-x86_64-DVD-1810.iso | 制作自定义ISO的基础 |
ISO镜像制作
首先要有一台正常运行的CentOS的电脑或虚拟机。
镜像挂载
制作自定义镜像,要以现有的ISO镜像为基础,本文中使用的是“CentOS-7-x86_64-DVD-1810.iso”。
/home/baseISO
目录下。#创建挂载点 mkdir /mnt/cdrom #挂载 mount -o loop /home/baseISO/CentOS-7-x86_64-Minimal-1810.iso /mnt/cdrom/ # 同步/mnt/cdrom/下的文件到/ISO/路径下 /usr/bin/rsync -a /mnt/cdrom/ /home/ISO/
ks.cfg文件
ks.cfg文件内容如下:
#version=CentOS #platform=x86, AMD64, or Intel EM64T # Install OS instead of upgrade install # Keyboard layouts keyboard --vckeymap=us --xlayouts='us' # Root password rootpw --iscrypted $6$4W0hA07RBGc/HsSg$gG/K5SsPRv/IiGzCkUVuIZdAQhLcbOdKNUkD1v6P0AhiJCgWJd.KoCw.pqFTKs6fsI66QGgoZlBhtSrSvQBbv0 user --name=test --password=$6$K/D5ntSjfi4k7EG.$4tSae6Lm3wYcDbiUPPPCffCY/8kUTEXT1Ep/xucXdEMTbbEkQPxVI9X7Ms54je4NohxkAa5QBw4WXlAGMez7I. --iscrypted --gecos="test" --groups="root" # (Required) Wrapper around the authconfig command CCE-14063-2 (row 80) authconfig --enableshadow --passalgo=sha512 # System language lang en_US.UTF-8 # License agreement eula --agreed # Firewall configuration firewall --enabled --port=40000:tcp,40001:tcp,3310:tcp,30001:tcp,40002:tcp,22:tcp,18000:tcp # System authorization information auth --useshadow --passalgo=sha512 # Use CDROM installation media cdrom # Use graphical mode install graphical # Run the Setup Agent on first boot firstboot --enable ignoredisk --only-use=sda # SELinux configuration selinux --disabled # X Window System configuration information xconfig --startxonboot # Network information network --bootproto=dhcp --device=enp0s3 --ipv6=auto --activate network --hostname=localhost.localdomain # Reboot after installation reboot # System timezone timezone Asia/Shanghai --isUtc # System bootloader configuration bootloader --location=mbr --driveorder=sda --append="" # Clear the Master Boot Record zerombr # Partition clearing information clearpart --all --initlabel autopart --type=lvm # 待安装的CentOS系统软件 %packages @^gnome-desktop-environment @base @core @desktop-debugging @dial-up @directory-client @fonts @gnome-desktop @guest-agents @guest-desktop-agents @input-methods @internet-browser @java-platform @multimedia @network-file-system-client @networkmanager-submodules @print-client @x11 kexec-tools %end %post --nochroot #!/bin/sh #将待安装软件拷贝到/root目录下 cp -r /run/install/repo/postinstall /mnt/sysimage/root %end %post #!/bin/sh # 进入待安装软件的目录 cd /root/postinstall # 待安装软件拷贝到/home目录下 sudo mv docker-compose.yml mysoft-install.sh *.tar *.tar.gz /home # 离线安装docker tar -zxvf docker-24.0.4.tgz -C /home sudo cp /home/docker/* /usr/bin/ sudo cp docker.service /usr/lib/systemd/system/ sudo systemctl enable docker # 离线安装docker-compose sudo cp docker-compose-linux-x86_64 /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 通过开机运行service,完成MySQL容器启动 sudo chmod +x /home/mysoft-install.sh sudo cp initialmysoft.service /usr/lib/systemd/system/ sudo systemctl enable initialmysoft.service %end %post #!/bin/bash # 修改前备份 cp /etc/passwd /etc/passwd_bak # 注释账户:lp,sync,shutdown,halt,news,uucp,operator,games,gopher echo "###########delete user: sync,shutdown,halt,news,uucp,operator,games,gopher###########" sed -i 's/^lp/#lp/g' /etc/passwd sed -i 's/^sync/#sync/g' /etc/passwd sed -i 's/^shutdown/#shutdown/g' /etc/passwd sed -i 's/^halt/#halt/g' /etc/passwd sed -i 's/^news/#news/g' /etc/passwd sed -i 's/^uucp/#uucp/g' /etc/passwd sed -i 's/^operator/#operator/g' /etc/passwd sed -i 's/^games/#games/g' /etc/passwd sed -i 's/^gopher/#gopher/g' /etc/passwd sed -i 's/^ftp/#ftp/g' /etc/passwd echo "###########delete user success###########" # 修改密码策略 #负数:代表最少出现次数,正数:代表最多出现次数 #minlen = 8,密码长度至少8位; #lcredit=-1,至少包含一个小写字母; #ucredit=-1,至少包含一个大写字母; #dcredit=-1,至少包含要给数字; #ocredit=-1,至少包含一个特殊字符; #difok=5,新密码最多与旧密码重复5个字符; #enforce_for_root,对root强制执行密码复杂度策略 cp /etc/pam.d/system-auth /etc/pam.d/system-auth_bak sed -r -i "s/(pam_pwquality.so ).*/1try_first_pass local_users_only retry=3 authtok_type= minlen=8 ucredit=-2 lcredit=-1 dcredit=-4 ocredit=-1/" /etc/pam.d/system-auth #密码的最大有效期 cp /etc/login.defs /etc/login.defs.bak sed -i '/^PASS_MAX_DAYS/d' /etc/login.defs sed -i '/^PASS_MIN_DAYS/iPASS_MAX_DAYS 90' /etc/login.defs #密码更改之间允许的最小天数 sed -i '/^PASS_MIN_DAYS/d' /etc/login.defs sed -i '/^PASS_MIN_LEN/iPASS_MIN_DAYS 0' /etc/login.defs #密码最小长度,pam_pwquality设置优先 sed -i '/^PASS_MIN_LEN/d' /etc/login.defs sed -i '/^PASS_WARN_AGE/iPASS_MIN_LEN 8' /etc/login.defs #密码失效前多少天在用户登录时通知用户修改密码 sed -i '/^PASS_WARN_AGE/d' /etc/login.defs sed -i '/^PASS_MIN_LEN/aPASS_WARN_AGE 7' /etc/login.defs # 配置连接超时自动退出时间 cp /etc/profile /etc/profile.bak sed -i '$a TMOUT=300s' /etc/profile source /etc/profile # 配置连续登陆失败次数 cp /etc/pam.d/sshd /etc/pam.d/sshd.bak sed -i "/#%PAM-1.0/aauth required pam_tally2.so onerr=fail deny=3 unlock_time=300 even_deny_root root_unlock_time=300" /etc/pam.d/sshd sed -i "/-auth/aaccount required pam_tally2.so" /etc/pam.d/sshd %end
- 若对ks.cfg文件的制作不熟悉,有如下两种方式获取ks.cfg的基本模板
isolinux.cfg文件
修改此文件,指定ks.cfg文件位置,修改的片断如下:
label linux menu label ^Install CentOS 7 kernel vmlinuz append initrd=initrd.img inst.stage2=hd:LABEL=CentOS7 inst.ks=cdrom:/isolinux/ks.cfg quiet
制作iso镜像
cd /home/ISO genisoimage -joliet-long -V CentOS7 -o CentOS-7-custom.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -v -cache-inodes -T -eltorito-alt-boot -e images/efiboot.img -no-emul-boot /ISO
上面脚本执行后,最后输出如下内容(省略了前端的一些输出),说明成功:
97.27% done, estimate finish Sun Jul 9 14:53:02 2023 98.26% done, estimate finish Sun Jul 9 14:53:02 2023 99.26% done, estimate finish Sun Jul 9 14:53:02 2023 Total translation table size: 124018 Total rockridge attributes bytes: 55014 Total directory bytes: 92160 Path table size(bytes): 156 Done with: The File(s) Block(s) 503497 Writing: Ending Padblock Start Block 503609 Done with: Ending Padblock Block(s) 150 Max brk space used a4000 503759 extents written (983 MB)
Hybird模式
采用“hybird模式”(混合模式),操作系统可以直接刻录成物理光盘,也可以直接做成可引导的U盘。
isohybrid -v /ISO/CentOS-7-custom.iso
制作镜像MD5值
implantisomd5 /ISO/CentOS-7-custom.iso
自定义安装软件脚本
docker.service
[Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target
initialmysoft.service
[Unit] Description=Initial Mysql container After=docker.service [Service] Type=oneshot ExecStart=/home/mysoft-install.sh [Install] WantedBy=multi-user.target
关于上述两个service文件的关键点:
- [Unit]控制单元,表示启动顺序和依赖关系;[Service]服务,表示服务的定义;[Install]安装,表示如何安装配置文件。
- [Unit]中的After表示该服务在哪个服务之后启动。initialmysoft.service是在docker.service之后启动,因为initialmysoft.service执行的脚本依赖于docker。
- [Service]中的Type可取如下值:
- simple:简单类型的服务,通过启动一个进程来运行服务,可以理解为常驻型服务。示例:httpd、sshd。
- forking:分叉类型的服务,通过启动一个主进程并派生出一个或多个子进程来运行服务。主进程通常会退出,子进程继续运行。示例:apache2。
- oneshot:一次性类型的服务,运行完成后就退出,不会保持运行状态。示例:格式化文件系统的服务。
- dbus:DBus类型的服务,通过DBus接口提供服务功能。示例:NetworkManager。
- notify:通知类型的服务,服务启动后会向systemd发送通知,表示服务已经启动完成。示例:nginx。
- idle:空闲类型的服务,当CPU处于空闲状态时才会运行的服务。示例:anacron。
mysoft-install.sh
#!/bin/bash # create docker network network_name="mysql-net" if docker network ls | awk -v name="$network_name" '$2==name {found=1} END{if(found) exit 0; else exit 1}' then echo "Network $network_name exists." else echo "Network $network_name does not exist." docker network create mysql-net fi cd /home ################################# Install mysql and myphpadmin ##################################### image_name="mysql:5.7.42" # Load Image if docker image inspect $image_name >/dev/null 2>&1; then echo "Image Exist" else docker load -i mysql5742.tar docker load -i phpadmin.tar fi # Recovery Mysql data mysoftFolder="/home/mysoft/mysql" if [ -d $mysoftFolder ]; then echo "Mysql Data folder exist" else tar -zxvf mysoft.tar.gz fi # Start mysql and myphpadmin container_name="mysql_rdb" container_count=$(docker ps -a --format "{{.Names}}" | grep -w "$container_name" | wc -l) if [ "$container_count" -gt 0 ]; then echo "Docker $container_name container exist" else echo "start docker-compose" docker-compose up -d fi ################################# Install 1Panel ##################################### sudo cp 1panel-v1.3.6-linux-amd64.tar.gz /home/mysoft cd mysoft tar zxvf 1panel-v1.3.6-linux-amd64.tar.gz if [ $? != 0 ];then echo "download install package failed" rm -f ${package_file_name} exit 1 fi cd 1panel-v1.3.6-linux-amd64 /bin/bash install.sh
- 创建自定义bridge网络“mysql-net”,用在docker-compose文件中,部署MySQL和phpMyAdmin。在同一bridge网络中,可通过容器名称相互访问。
- mysoft.tar.gz压缩包中,有MySQL的数据,主要是根据等保二级要求,创建相关账户,并删除root账户,部署MySQL时,通过volumes挂载。
- 1panel安装后,访问地址要从安装日志中获取。
docker-compose.yml
version : '3' services: mysql_rdb: # 容器名(以后的控制都通过这个) container_name: mysql_rdb # 重启策略 restart: always image: mysql:5.7.42 # 自定义的bridge网络 networks: - mysql-net ports: # 指定127.0.0.1,则MySQL无法通过其他主机访问,只能本地服务器访问,保障安全 - "127.0.0.1:3306:3306" volumes: # 挂挂载配置文件 - /home/mysoft/mysql/conf:/etc/mysql/conf.d # 挂载数据 - /home/mysoft/mysql/data:/var/lib/mysql environment: # root 密码 MYSQL_ROOT_PASSWORD: 123456 TZ: Asia/Shanghai mysql_rdb_manage: container_name: mysql_rdb_manage image: phpmyadmin:latest ports: - 18000:80 environment: # 指定要连接的数据库,使用MySQL的容器名称 - PMA_HOST=mysql_rdb - PMA_PORT=3306 depends_on: - mysql_rdb networks: # 自定义的bridge网络 - mysql-net deploy: resources: limits: memory: 500M restart: always # 自定义的bridge网络 networks: mysql-net: external: true
操作系统安装
以下安装说明,以虚拟机为例。
安装后确认