Composing a customized RHEL system image Red Hat Enterprise Linux 8 Creating customized system images with RHEL image builder on Red Hat Enterprise Linux 8 Red Hat Customer Content Services

Commands:
composer-cli compose types
yum install osbuild-composer composer-cli cockpit-composer
systemctl enable --now osbuild-composer.socket
systemctl enable --now cockpit.socket
source /etc/bash_completion.d/composer-cli
composer-cli status show
journalctl | grep osbuild
journalctl -u osbuild-worker*
journalctl -u osbuild-composer.service
yum remove osbuild-composer yum remove weldr-client
cat /etc/yum.conf [main] gpgcheck=1 installonly_limit=3 clean_requirements_on_remove=True best=True skip_if_unavailable=False exclude=osbuild-composer weldr-client
yum install lorax-composer composer-cli
systemctl enable --now lorax-composer.socket systemctl start lorax-composer
id = "k8s" name = "Kubernetes" type = "yum-baseurl" url = "https://server.example.com/repos/company_internal_packages/" check_gpg = false check_ssl = false system = false
composer-cli sources add <file-name> .toml
composer-cli sources list
composer-cli sources info <source_id>
check_gpg = true check_ssl = true distros = ["rhel-8"] id = "rh9-local" name = "packages for RHEL" system = false type = "yum-baseurl" url = " https://local/repos/rhel8/projectrepo/ "
composer-cli sources add <file-name> .toml
composer-cli sources list
composer-cli sources info <source_id>
cd repo/
createrepo_c .
cd repodata/
gpg -u <_gpg-key-email_> --yes --detach-sign --armor /srv/repo/example/repomd.xml
check_gpg = true check_ssl = true id = "signed local packages" name = " repository_name " type = "yum-baseurl" url = " https://local/repos/projectrepo/ " check_repogpg = true gpgkeys=[" https://local/keys/repokey.pub "]
check_gpg = true check_ssl = true check_repogpg id = "custom-local" name = "signed local packages" type = "yum-baseurl" url = " https://local/repos/projectrepo/ " gpgkeys=[" https://remote/keys/other-repokey.pub ", '''-----BEGIN PGP PUBLIC KEY BLOCK----- ... -----END PGP PUBLIC KEY BLOCK-----''']
GPG verification is enabled, but GPG signature is not available. This may be an error or the repository does not support GPG verification: Status code: 404 for http://repo-server/rhel/repodata/repomd.xml.asc (IP: 192.168.1.3)
repomd.xml GPG signature verification error: Bad GPG signature
gpg --verify /srv/repo/example/repomd.xml.asc
sudo mkdir -p /etc/osbuild-composer/repositories
{ "x86_64": [ { "name": "baseos", "baseurl": "http://mirror.example.com/composes/released/RHEL-8/8.0/BaseOS/x86_64/os/", "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n (... )", "check_gpg": true } ] }
cp /usr/share/osbuild-composer/repositories/rhel- version .json /etc/osbuild-composer/repositories/
json_verify < /etc/osbuild-composer/repositories/rhel- version .json
/etc/osbuild-composer/repositories/rhel- version .json
sudo systemctl restart osbuild-composer.service
cat /etc/yum.repos.d/redhat.repo
cat /etc/yum.repos.d/redhat.repo [AppStream] name = AppStream mirror example baseurl = https://mirror.example.com/RHEL-8/8.0/AppStream/x86_64/os/ enabled = 1 gpgcheck = 0 sslverify = 1 sslcacert = /etc/pki/ca1/ca.crt sslclientkey = /etc/pki/ca1/client.key sslclientcert = /etc/pki/ca1/client.crt metadata_expire = 86400 enabled_metadata = 0
{ "x86_64": [ { "name": "AppStream mirror example", "baseurl": "https://mirror.example.com/RHEL-8/8.0/AppStream/x86_64/os/", "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n (... )", "check_gpg": true, "rhsm": true } ] }
sudo systemctl restart osbuild-composer.service
sudo yum -v repolist "-baseos-rpms" | grep -i repo-baseurl Repo-baseurl :
https://satellite6.example.com/pulp/content/YourOrg/YourEnv/YourCV/content/dist/rhel8/8/x86_64/baseos/os
sudo mkdir -pvm 0755 /etc/osbuild-composer/repositories
sudo cp /usr/share/osbuild-composer/repositories/*.json /etc/osbuild-composer/repositories/
sudo sed -i -e 's|cdn.redhat.com|satellite6.example.com/pulp/content/YourOrg/YourEnv/YourCV|' /etc/osbuild-composer/repositories/*.json
sudo vi /etc/osbuild-composer/repositories/rhel-8.json
sudo systemctl restart osbuild-worker@1.service osbuild-composer.service
sudo usermod -a -G weldr user newgrp weldr
name = " BLUEPRINT-NAME " description = " LONG FORM DESCRIPTION TEXT " version = " 0.0.1 " modules = [] groups = []
[[packages]] name = " package-name " version = " package-version "
[customizations.kernel] append = "nosmt=force"
composer-cli blueprints save BLUEPRINT-NAME .toml
composer-cli blueprints push BLUEPRINT-NAME .toml
usermod -a -G weldr user newgrp weldr
composer-cli blueprints list
composer-cli blueprints show BLUEPRINT-NAME
composer-cli blueprints depsolve BLUEPRINT-NAME
sudo rm -rf /var/cache/osbuild-composer/* sudo systemctl restart osbuild-composer
composer-cli blueprints list
composer-cli blueprints save BLUEPRINT-NAME
packages = []
composer-cli blueprints push BLUEPRINT-NAME .toml
composer-cli blueprints show BLUEPRINT-NAME
composer-cli blueprints depsolve BLUEPRINT-NAME
composer-cli compose types
composer-cli compose start BLUEPRINT-NAME IMAGE-TYPE
composer-cli compose status
composer-cli compose image UUID
sudo composer-cli compose metadata UUID
sudo composer-cli compose logs UUID
journalctl | grep osbuild
sudo cat /var/lib/osbuild-composer/jobs/ job_UUID .json
composer-cli blueprints list
composer-cli blueprints show <BLUEPRINT-NAME>
composer-cli blueprints save <BLUEPRINT-NAME>
composer-cli blueprints delete <BLUEPRINT-NAME>
composer-cli blueprints push <BLUEPRINT-NAME>
composer-cli compose types
composer-cli compose start <BLUEPRINT> <COMPOSE-TYPE>
composer-cli compose list
composer-cli compose status
composer-cli compose cancel <COMPOSE-UUID>
composer-cli compose delete <COMPOSE-UUID>
composer-cli compose info <COMPOSE-UUID>
composer-cli compose image <COMPOSE-UUID>
composer-cli help
name = " <BLUEPRINT-NAME> " description = " <LONG FORM DESCRIPTION TEXT> " version = " <VERSION> "
[[groups]] name = " group-name "
[[packages]] name = " <package-name> " version = " <package-version> "
name = " blueprint_name " description = " blueprint_version " version = "0.1" distro = " different_minor_version "
name = "tmux" description = "tmux image with openssh" version = "1.2.16" distro = "rhel-9.5"
[[groups]] name = " group_name "
[[groups]] name = "anaconda-tools"
[[containers]] source = "registry.access.redhat.com/ubi9/ubi:latest" name = "local-name" tls-verify = true [[containers]] source = "localhost/test:latest" local-storage = true
[customizations] hostname = "baseimage"
[[customizations.user]] name = " USER-NAME " description = " USER-DESCRIPTION " password = " PASSWORD-HASH " key = " PUBLIC-SSH-KEY " home = "/home/ USER-NAME /" shell = " /usr/bin/bash " groups = [ "users", "wheel" ] uid = NUMBER gid = NUMBER
[[customizations.user]] name = "admin" description = "Administrator account" password = "USD6USDCHO2USD3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31L..." key = "PUBLIC SSH KEY" home = "/srv/widget/" shell = "/usr/bin/bash" groups = ["widget", "users", "wheel"] uid = 1200 gid = 1200 expiredate = 12345
python3 -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'
[[customizations.group]] name = " GROUP-NAME " gid = NUMBER
[[customizations.group]] name = "widget" gid = 1130
[[customizations.sshkey]] user = " root " key = " PUBLIC-SSH-KEY "
[[customizations.sshkey]] user = "root" key = "SSH key for root"
[customizations.kernel] append = " KERNEL-OPTION "
[customizations.kernel] name = "kernel-debug" append = "nosmt=force"
mkdir /etc/osbuild-composer/repositories/
cp /usr/share/osbuild-composer/repositories/rhel-8. version .json /etc/osbuild-composer/repositories
grep -C 6 kernel-rt /etc/osbuild-composer/repositories/rhel-8. version .json "baseurl": "https://cdn.redhat.com/content/dist/rhel8/8. version /x86_64/appstream/os", "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nm...........=\n=UZd/\n-----END PGP PUBLIC KEY BLOCK-----\n", "rhsm": true, "check_gpg": true }, { "name": "kernel-rt", "baseurl": "https://cdn.redhat.com/content/dist/rhel8/8. version /x86_64/rt/os", "gpgkey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQINBEr.........fg==\n=UZd/\n-----END PGP PUBLIC KEY BLOCK-----\n", "rhsm": true, "check_gpg": true },
systemctl restart osbuild-composer
composer-cli sources list composer-cli sources info kernel-rt
name = "rt-kernel-image" description = "" version = "2.0.0" modules = [] groups = [] distro = "rhel-8_version_" [[customizations.user]] name = "admin" password = "admin" groups = ["users", "wheel"] [customizations.kernel] name = "kernel-rt" append = ""
composer-cli blueprints push rt-kernel-image.toml
composer-cli compose start rt-kernel-image qcow2
cat /proc/cmdline BOOT_IMAGE=(hd0,got3)/vmlinuz-5.14.0-362.24.1..el8_version_.x86_64+rt
[customizations.timezone] timezone = " TIMEZONE " ntpservers = " NTP_SERVER "
[customizations.timezone] timezone = "US/Eastern" ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"]
[customizations.locale] languages = ["LANGUAGE"] keyboard = " KEYBOARD "
[customizations.locale] languages = ["en_US.UTF-8"] keyboard = "us"
localectl list-locales
localectl list-keymaps
[customizations.firewall] ports = ["PORTS"]
[customizations.firewall] ports = ["22:tcp", "80:tcp", "imap:tcp", "53:tcp", "53:udp", "30000-32767:tcp", "30000-32767:udp"]
[customizations.firewall.services] enabled = ["SERVICES"] disabled = ["SERVICES"]
firewall-cmd --get-services
[customizations.firewall.services] enabled = ["ftp", "ntp", "dhcp"] disabled = ["telnet"]
[customizations.services] enabled = ["SERVICES"] disabled = ["SERVICES"]
[customizations.services] enabled = ["sshd", "cockpit.socket", "httpd"] disabled = ["postfix", "telnetd"]
[customizations] partitioning_mode = "lvm"
[[customizations.filesystem]] mountpoint = "MOUNTPOINT" minsize = MINIMUM-PARTITION-SIZE
[[customizations.filesystem]] mountpoint = "/var" minsize = 1073741824
[[customizations.filesystem]] mountpoint = "/opt" minsize = "20 GiB"
[[customizations.filesystem]] mountpoint = "/boot" minsize = "1 GiB"
[[customizations.filesystem]] mountpoint = "/var" minsize = 2147483648
[[customizations.directories]] path = "/etc/ directory_name " mode = " octal_access_permission " user = " user_string_or_integer " group = " group_string_or_integer " ensure_parents = boolean
[[customizations.files]] path = "/etc/ directory_name " mode = " octal_access_permission " user = " user_string_or_integer " group = " group_string_or_integer " data = "Hello world!"
composer-cli blueprints depsolve BLUEPRINT-NAME
composer-cli distros list
rhel-8 rhel-84 rhel-85 rhel-86 rhel-87 rhel-88 rhel-89
name = " <blueprint_name> " description = " <image-description> " version = "0.0.1" modules = [] groups = [] distro = " <distro-version> "
composer-cli blueprints save EXISTING-BLUEPRINT
name = "blueprint_84" description = "A 8.8 base image" version = "0.0.1" modules = [] groups = [] distro = "rhel-88"
composer-cli blueprints push EXISTING-BLUEPRINT .toml
composer-cli compose start BLUEPRINT-NAME IMAGE-TYPE
composer-cli compose status
composer-cli compose image UUID
check_gpg = true check_ssl = true distros = [" <distro-version> "] id = " <image-id> " name = " <image-name >_" system = false type = " <image-type> " url = " \http://local/repos/rhel- <distro-version>_/ <project-repo> /"
check_gpg = true check_ssl = true distros = ["rhel-84"] id = "rhel-84-local" name = "local packages for rhel-84" system = false type = "yum-baseurl" url = " \http://local/repos/rhel-84/projectrepo/ "
composer-cli compose start BLUEPRINT-NAME image-installer
composer-cli compose status
composer-cli compose list
composer-cli compose image UUID
mount -o ro path_to_ISO /mnt
tar ztvf /mnt/liveimg.tar.gz
tar -xf content .tar
dd if=installer.iso of=/dev/sdX
If you want to use the data stream from the 'scap-security-guide' package the 'datastream' key could be omitted. datastream = "/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml" profile_id = "xccdf_org.ssgproject.content_profile_cis"
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
oscap xccdf generate fix --profile=cis --fix-type=blueprint /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
Blueprint for CIS Red Hat Enterprise Linux 8 Benchmark for Level 2 - Server # Profile Description: This profile defines a baseline that aligns to the "Level 2 - Server" configuration from the Center for Internet Security(R) Red Hat Enterprise Linux 8 BenchmarkTM, v3.0.0, released 2023-10-30. This profile includes Center for Internet Security(R) Red Hat Enterprise Linux 8 CIS BenchmarksTM content. # Profile ID: xccdf_org.ssgproject.content_profile_cis Benchmark ID: xccdf_org.ssgproject.content_benchmark_RHEL-8 Benchmark Version: 0.1.74 XCCDF Version: 1.2 name = "hardened_xccdf_org.ssgproject.content_profile_cis" description = "CIS Red Hat Enterprise Linux 8 Benchmark for Level 2 - Server" version = "0.1.74" [customizations.openscap] profile_id = "xccdf_org.ssgproject.content_profile_cis" If your hardening data stream is not part of the 'scap-security-guide' package provide the absolute path to it (from the root of the image filesystem). datastream = "/usr/share/xml/scap/ssg/content/ssg-xxxxx-ds.xml" [[customizations.filesystem]] mountpoint = "/home" size = 1073741824 [[customizations.filesystem]] mountpoint = "/tmp" size = 1073741824 [[customizations.filesystem]] mountpoint = "/var" size = 3221225472 [[customizations.filesystem]] mountpoint = "/var/tmp" size = 1073741824 [[packages]] name = "aide" version = "*" [[packages]] name = "libselinux" version = "*" [[packages]] name = "audit" version = "*" [customizations.kernel] append = "audit_backlog_limit=8192 audit=1" [customizations.services] enabled = ["auditd","crond","firewalld","systemd-journald","rsyslog"] disabled = [] masked = ["nfs-server","rpcbind","autofs","bluetooth","nftables"]
oscap xccdf generate fix --profile= <profileID> --fix-type= <blueprint_name> .toml /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml > cis.toml
composer-cli blueprints push <blueprint_name> .toml
composer-cli compose start <blueprint_name> <image_type>
oscap xccdf generate fix --profile= <profileID> --fix-type=blueprint /usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml > <profileID>-tailored .toml
Blueprint for CIS Red Hat Enterprise Linux 8 Benchmark for Level 2 - Server [customizations.openscap.tailoring] selected = [ "xccdf_org.ssgproject.content_bind_crypto_policy" ] unselected = [ "grub2_password" ]
composer-cli blueprints push <blueprintProfileID> - tailored .toml
composer-cli compose start <blueprintProfileID> <image_type>
name = "system-fips-mode-enabled" description = "blueprint with FIPS enabled " version = "0.0.1" [customizations] fips = true [[customizations.user]] name = "admin" password = "admin" groups = ["users", "wheel"]
composer-cli blueprints push <blueprint-name> .toml
composer-cli blueprints show <blueprint-name>
composer-cli blueprints depsolve <blueprint-name>
composer-cli compose start \ <blueprint-name> \ <image-type> \
composer-cli compose status ... <UUID> FINISHED <date> <blueprint-name> <blueprint-version> <image-type> ...
composer-cli compose image <UUID>
<UUID-image-name.type> : <size> MB
fips-mode-setup --check FIPS mode is enabled.
mkdir cloudinitiso cd cloudinitiso
instance-id: citest local-hostname: vmname
#cloud-config user: admin password: password chpasswd: {expire: False} ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAA...fhHQ== your.email@example.com
genisoimage -output cloud-init.iso -volid cidata -joliet -rock user-data meta-data I: -input-charset not specified, using utf-8 (detected in locale settings) Total translation table size: 0 Total rockridge attributes bytes: 331 Total directory bytes: 0 Path table size(bytes): 10 Max brk space used 0 183 extents written (0 MB)
virt-install --memory 4096 --vcpus 4 --name myvm --disk rhel-8-x86_64-kvm.qcow2,device=disk,bus=virtio,format=qcow2 --disk cloud-init.iso,device=cdrom --os-variant rhel 8 --virt-type kvm --graphics none --import
Starting install Connected to domain mytestcivm [ OK ] Started Execute cloud user/final scripts. [ OK ] Reached target Cloud-init target. Red Hat Enterprise Linux 8 (Ootpa) Kernel 4.18.0-221.el8.x86_64 on an x86_64
[[containers]] source = "registry.access.redhat.com/ubi9/ubi:latest" name = "local-name" tls-verify = true
systemctl restart osbuild-worker@*
[containers] auth_file_path = "/etc/osbuild-worker/containers-auth.json"
provider = " container_provider " [settings] tls_verify = false username = " admin " password = " your_password "
name = "simple-container" description = "Simple RHEL container" version = "0.0.1" [[packages]] name = "nginx" version = "*"
composer-cli blueprints push blueprint.toml
composer-cli compose start simple-container container "quay.io:8080/osbuild/ repository " registry-config.toml
You can see details about the container you created, such as: - last modified - image size - the `manifest ID`, that you can copy to the clipboard.
name = "image" description = "A qcow2 image with a container" version = "0.0.1" distro = "rhel-90" [[packages]] name = "podman" version = "*" [[containers]] source = "registry.access.redhat.com/ubi9:8080/osbuild/container/container-image@sha256:manifest-ID-from-Repository-tag: tag-version" name = "source-name" tls-verify = true
composer-cli blueprints push blueprint-image .toml
composer-cli start compose image qcow2
composer-cli compose status
composer-cli compose image UUID
podman run -it registry.access.redhat.com/ubi9:8080/osbuild/ repository /bin/bash/
type -a nginx
yum install python3 python3-pip
pip3 install awscli
aws configure AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [None]: Default output format [None]:
BUCKET= bucketname aws s3 mb s3://USDBUCKET
{ "Version": "2022-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "vmie.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:Externalid": "vmimport" } } }] }
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket"], "Resource": ["arn:aws:s3:::%s", "arn:aws:s3:::%s/ "] }, { "Effect": "Allow", "Action": ["ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe "], "Resource": "*" }] } USDBUCKET USDBUCKET
aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json
aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
provider = "aws" [settings] accessKeyID = " AWS_ACCESS_KEY_ID " secretAccessKey = "AWS_SECRET_ACCESS_KEY" bucket = "AWS_BUCKET" region = "AWS_REGION" key = "IMAGE_KEY"
composer-cli compose start blueprint-name image-type image-key configuration-file .toml
composer-cli compose status
chmod 400 <_your-instance-name.pem_>
ssh -i <_your-instance-name.pem_> ec2-user@<_your-instance-IP-address_>
rpm --import https://packages.microsoft.com/keys/microsoft.asc
[azure-cli] name=Azure CLI baseurl=https://packages.microsoft.com/yumrepos/vscode enabled=1 gpgcheck=1 gpgkey=https://packages.microsoft.com/keys/microsoft.asc
yumdownloader azure-cli rpm -ivh --nodeps azure-cli-2.0.64-1.el7.x86_64.rpm
az login
az storage account keys list --resource-group <resource_group_name> --account-name <storage_account_name>
az resource list
az storage container create --account-name <storage_account_name> --account-key <key1_value> --name <storage_account_name>
az storage blob upload --account-name <_account_name_> --container-name <_container_name_> --file <_image_-disk.vhd> --name <_image_-disk.vhd> --type page
az image create --resource-group <_resource_group_name_> --name <_image_>-disk.vhd --os-type linux --location <_location_> --source https://USD<_account_name_>.blob.core.windows.net/<_container_name_>/<_image_>-disk.vhd - Running
az vm create --resource-group <_resource_group_name_> --location <_location_> --name <_vm_name_> --image <_image_>-disk.vhd --admin-username azure-user --generate-ssh-keys - Running
GOVC_URL GOVC_DATACENTER GOVC_FOLDER GOVC_DATASTORE GOVC_RESOURCE_POOL GOVC_NETWORK
govc import.vmdk ./composer-api.vmdk foldername
govc import.ova ./composer-api.ova foldername
govc vm.create -net.adapter=vmxnet3 -m=4096 -c=2 -g=rhel8_64Guest -firmware=efi -disk=" foldername /composer-api.vmdk" -disk.controller=scsi -on=false vmname
govc vm.power -on vmname
govc vm.ip vmname
ssh admin@<_ip_address_of_the_vm_>
rpm -qa | grep firefox
provider = "gcp" [settings] bucket = "GCP_BUCKET" region = "GCP_STORAGE_REGION" object = "OBJECT_KEY" credentials = "GCP_CREDENTIALS"
sudo base64 -w 0 cee-gcp-nasa-476a1fa485b7.json
sudo composer-cli compose start BLUEPRINT-NAME gce IMAGE_KEY gcp-config.toml
sudo composer-cli compose status
base64 -w 0 "USD{GOOGLE_APPLICATION_CREDENTIALS}"
provider = "gcp" [settings] provider = "gcp" [settings] credentials = "GCP_CREDENTIALS"
[gcp] credentials = " PATH_TO_GCP_ACCOUNT_CREDENTIALS "
composer-cli compose start blueprint_name openstack
composer-cli compose status
composer-cli compose image UUID
curl -O https://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/73848/cn_zh/1557459863884/image_check
chmod +x image_check
./image_check