CentOS 7.9
Videos
Overview: CentOS 7.9 on Azure: overview (watch on YouTube)
Launch and log in: CentOS 7.9 on Azure: launch and log in (watch on YouTube)
Overview
This guide covers how to deploy and configure CentOS 7.9 (CentOS Linux release 7.9.2009, the final CentOS 7 release) on Microsoft Azure. It uses SecureAnyCloud's CentOS 7.9 virtual machine image from the Azure Marketplace.
CentOS Linux is a community rebuild of Red Hat Enterprise Linux and is binary compatible with RHEL 7. This image is for existing CentOS 7 workloads: software that is still certified only on the CentOS 7 / RHEL 7 platform. Use it to keep that software running while you move it to a supported distribution.
Every command and every output in this guide was run on a virtual machine deployed from the public Marketplace image (image version 3.0.0), as the azureuser account that a customer gets.
End of life notice: read this first
CentOS Linux 7 reached end of life on 30 June 2024. The CentOS Project publishes no further updates for it, security updates included (CentOS Project, Red Hat). The final CentOS 7 packages were archived on vault.centos.org, and nothing newer will ever be released. As a result:
- This image was patched when it was built, and its running kernel is
3.10.0-1160.66.1.el7. The CentOS 7 updates published after that build, up to the last ones in the vault, are not applied. A fresh virtual machine has about 80 newer packages waiting, including kernel3.10.0-1160.119.1.el7. Step 5 applies them. - Even with every vault package applied, the system carries vulnerabilities that updating CentOS 7 can never fix, because upstream ships nothing further.
- Plan a migration to a supported distribution, such as AlmaLinux, Rocky Linux, CentOS Stream or a current RHEL, for any workload that must remain secure.
The image's CentOS repositories still use the original mirrorlist.centos.org service, which was retired at end of life. Step 4 points them at the CentOS 7.9.2009 vault, the only lasting source of CentOS 7 packages. Do this first on every new virtual machine.
What you get
- CentOS Linux 7.9.2009 (Core), binary compatible with RHEL 7, on the 3.10.0 el7 kernel
- The Azure Linux Agent (
waagent, WALinuxAgent 2.9.1.1), active and enabled, plus cloud-init 19.4 for Azure provisioning - Azure CLI 2.38.1 (
az) and Python 3.6.8 (python3), preinstalled - Chronyd for NTP time synchronisation
- EPEL 7 and the Microsoft Azure CLI repository, configured alongside the CentOS base, updates and extras repositories
- firewalld, installed but disabled (see Step 8)
- A Gen1 Hyper-V virtual machine (BIOS boot)
- 24/7 SecureAnyCloud support
The platform is Microsoft Azure (Gen1 Hyper-V). The default user is azureuser, or the administrator name you choose at create time.
Security posture
This image ships with no default password, and SSH accepts keys only:
PasswordAuthenticationisnoin/etc/ssh/sshd_config, so every login is by key.- The key that logs you in is the public key you supply when you create the virtual machine. Azure installs it for your administrator user at first boot.
- The root password is locked. The
centosaccount that the image also carries is locked and has no SSH key. - SSH logins as
rootare refused with a message./root/.ssh/authorized_keysholds entries that only printPlease login as the user "azureuser" rather than the user "root".and close the connection. Two of those entries were left in the image from before it was captured. They carry the same command, so they cannot open a shell. Step 6 shows how to remove them and turn root login off in the SSH daemon as well. - SELinux is disabled on this image (
SELINUX=disabledin/etc/selinux/config).
Prerequisites
Before you deploy this image, make sure you have:
- An active Microsoft Azure subscription
- Access to the Azure Portal or the Azure CLI
- An SSH key pair for Linux virtual machine access
- Familiarity with Azure virtual machine management
Choose a virtual machine size that suits your workload. The image is Gen1 (BIOS boot), so pick a size that supports Gen1 virtual machines.
Deploy the virtual machine
Option A: Azure Portal
- Go to the Azure Marketplace and search for "CentOS 7.9 SecureAnyCloud".
- Open the CentOS 7.9 listing, choose Get it now, then choose Create.
- Configure the basics:
- Subscription: select your Azure subscription.
- Resource group: create a new one or select an existing one.
- Virtual machine name: enter a name for your VM.
- Region: select your preferred Azure region.
- Size: select a size for your workload.
- Under Administrator account, select SSH public key and enter your key.
- Under Inbound port rules, allow SSH (port 22), ideally from your own network only.
- Choose Review + create, then Create.
Option B: Azure CLI
The image carries a Marketplace purchase plan. Accept its terms once per subscription, then create the virtual machine. Replace <your-vm-size> with the size you chose:
az vm image terms accept --urn sac1647283583153:3119f0ab-69f5-4bcf-a596-73f9e705f670:3119f0ab-69f5-4bcf-a596-73f9e705f670:latest
az vm create \
--resource-group myResourceGroup \
--name my-centos-7-9-vm \
--image sac1647283583153:3119f0ab-69f5-4bcf-a596-73f9e705f670:3119f0ab-69f5-4bcf-a596-73f9e705f670:latest \
--size <your-vm-size> \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardThe offer and plan are both named by the same identifier (3119f0ab-69f5-4bcf-a596-73f9e705f670), so it appears twice in the URN.
Connect via SSH
Run these on your own workstation, not on the VM. Find the public IP, then connect:
az vm show --resource-group myResourceGroup --name my-centos-7-9-vm --show-details --query publicIps -o tsv ssh azureuser@<vm-ip>There is no password to enter. If SSH asks for one, your client is not offering the key you supplied at create time.
Your first login prints a Last login: line dated 17 November 2023. That record was left in the image from before it was captured, and it is not a login to your virtual machine. From the second login on, the line shows your own previous session.
If your workstation sends a locale that CentOS 7 does not have (for example C.UTF-8), bash prints setlocale: LC_ALL: cannot change locale. In that case, connect with a locale the image has, such as LC_ALL=en_US.UTF-8 ssh azureuser@<vm-ip>.
Confirm the release
Check that the machine runs the CentOS Linux 7.9.2009 release you expect:
cat /etc/centos-release grep -E '^(NAME|VERSION|ID|VERSION_ID)=' /etc/os-release uname -rmExpected output on a fresh virtual machine:
CentOS Linux release 7.9.2009 (Core) NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" VERSION_ID="7" 3.10.0-1160.66.1.el7.x86_64 x86_64After Step 5 and a reboot, uname -r reports 3.10.0-1160.119.1.el7.x86_64, the last CentOS 7 kernel.
Point yum at the CentOS vault
The CentOS base, updates and extras repositories in /etc/yum.repos.d/CentOS-Base.repo still use mirrorlist=http://mirrorlist.centos.org/.... That service was retired at end of life, so yum falls back to a list of mirrors cached in the image. Most of those mirrors no longer carry CentOS 7 and return 404.
The vault is the lasting home of the final packages. Switch the repositories to it:
sudo cp -a /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.orig
sudo sed -i -e 's/^mirrorlist=/#mirrorlist=/' \
-e 's|^#baseurl=http://mirror.centos.org/centos/$releasever|baseurl=https://vault.centos.org/7.9.2009|' \
/etc/yum.repos.d/CentOS-Base.repo
sudo yum clean all grep '^baseurl' /etc/yum.repos.d/CentOS-Base.repo yum repolist enabledExpected output of the grep (the fourth line is the centosplus repository, which stays disabled):
baseurl=https://vault.centos.org/7.9.2009/os/$basearch/ baseurl=https://vault.centos.org/7.9.2009/updates/$basearch/ baseurl=https://vault.centos.org/7.9.2009/extras/$basearch/ baseurl=https://vault.centos.org/7.9.2009/centosplus/$basearch/yum repolist enabled then lists five enabled repositories: azure-cli, base, epel, extras and updates. To confirm where each one is fetched from, run:
yum -v repolist enabled 2>/dev/null | grep -i '^Repo-baseurl'The base, updates and extras repositories report https://vault.centos.org/7.9.2009/.... The azure-cli repository reports packages.microsoft.com. The epel repository reports a mirror of the Fedora archive, because EPEL 7 is archived too.
Apply the final CentOS 7 updates
With the vault in place, check which updates are waiting:
sudo yum -q check-update; echo "check-update exit: $?"On a fresh virtual machine, check-update lists about 80 packages and exits 100, which means "updates are available". They include kernel 3.10.0-1160.119.1.el7, glibc, openssl, openssh, sudo, systemd and azure-cli. Apply them and reboot onto the new kernel:
sudo yum -y update
sudo rebootAfter the reboot, sudo yum -q check-update; echo "check-update exit: $?" prints check-update exit: 0: nothing newer exists in the vault. That marks the end of the CentOS 7 lifecycle, not a guarantee of security. No further security updates will ever be published upstream.
While the kernel installs, you may see /usr/lib/dracut/modules.d/95involflt/installkernel: line 6: /tmp/MobSvcInstaller/ASR/Vx/bin/check_drivers.sh: No such file or directory. It comes from a replication agent left in the image (see Troubleshooting). It does not stop the update, and the new kernel boots normally.
Verify the security posture
Confirm that SSH is key-only, that root is locked, and what state SELinux is in:
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication) '
sudo passwd -S root getenforceExpected output on a fresh virtual machine:
permitrootlogin yes pubkeyauthentication yes passwordauthentication no root LK 1969-12-30 0 99999 7 -1 (Password locked.) Disabledpermitrootlogin yes is the CentOS 7 default. Root still cannot log in, because its password is locked and every entry in /root/.ssh/authorized_keys only prints the "Please login as the user" message. Run this to remove the two entries left in the image and turn root login off in the SSH daemon as well:
sudo truncate -s 0 /root/.ssh/authorized_keys
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.orig echo "PermitRootLogin no" | sudo tee -a /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl restart sshd
sudo sshd -T | grep '^permitrootlogin'The last command then prints permitrootlogin no. Keep your current session open until you have checked that a new ssh azureuser@<vm-ip> connection still works.
Verify Azure integration
Confirm the Azure Linux Agent, cloud-init and time synchronisation are healthy:
systemctl is-active waagent
systemctl is-enabled waagent cloud-init --version sudo cloud-init status
systemctl is-active chronyd timedatectl | grep 'Time zone'Expected output:
active enabled /usr/bin/cloud-init 19.4 status: done active Time zone: America/New_York (EST, -0500)In summer, the zone shows EDT, -0400. waagent lets Azure provision your SSH key, run extensions and report VM health, so it should always be active and enabled.
Run cloud-init status with sudo on this image. Without sudo, CentOS 7's cloud-init 19.4 crashes with NameError: global name 'PermissionError' is not defined when it cannot read its root-only status file. The bug is in the command's error handling only and is harmless. Provisioning ran: cloud-init created your user and installed your SSH key.
The image's clock zone is America/New_York, so local timestamps and log times are US Eastern. To use UTC or your own zone, run:
sudo timedatectl set-timezone UTCThe preinstalled tools are ready to use. Check them with:
python3 --version az versionpython3 reports Python 3.6.8 and az version reports "azure-cli": "2.38.1" (Step 5 upgrades it to 2.38.2). Run az login before you use the Azure CLI against your subscription.
Networking and the firewall
The Azure Network Security Group controls inbound and outbound traffic. It is the first, and usually the only, place you need to open a port. The image needs a single inbound port: SSH on 22.
Confirm what is listening before you open anything:
sudo ss -tlnpThe only externally reachable listener is sshd on port 22. You will also see master (postfix) bound to 127.0.0.1:25 and [::1]:25. That is the local mail transport, reachable only from the machine itself.
firewalld is installed but disabled. If your policy also requires a host firewall, enable it and keep SSH open so that you do not lock yourself out:
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reload sudo firewall-cmd --list-services--list-services then prints dhcpv6-client ssh. The firewalld default zone already allows SSH, so --add-service=ssh may answer Warning: ALREADY_ENABLED: ssh.
Server components
Component Version Notes
CentOS Linux 7.9.2009 (Core) End of life 30 June 2024
Linux kernel 3.10.0-1160.66.1.el7 3.10.0-1160.119.1.el7 after Step 5
Azure Linux Agent WALinuxAgent 2.9.1.1 waagent, active and enabled
cloud-init 19.4 Use sudo cloud-init status
Azure CLI 2.38.1 az, from packages.microsoft.com
Python 3 3.6.8 python3
OpenSSH server 7.4p1 Key-only login
chrony 3.4 chronyd, active
firewalld 0.6.3 Installed, disabled
Filesystem layout
Mount Point Size Description
/ 38 GB Root filesystem (ext4, /dev/sda2)
/boot 2 GB Kernel files (ext4, /dev/sda1)
/mnt varies Azure temporary resource disk; its contents are lost when the VM is deallocated
The 50 GB OS disk also holds a 10 GB partition (/dev/sda3) formatted as swap. It is not in /etc/fstab and is not used, so the image runs without swap. That partition sits after the root partition, so / cannot simply be grown into the rest of the disk. If you need more space, attach a data disk and mount it.
Scripts and log files
Path Purpose
/stage/scripts/initial_boot_update.sh Runs at every boot from root's crontab (see On Startup)
/stage/scripts/initial_boot_update.log Output of that script; it also holds entries from boots before the image was captured
/var/log/cloud-init.log cloud-init provisioning log
/var/log/waagent.log Azure Linux Agent log
/var/log/yum.log Packages installed and updated by yum
On startup
Root's crontab runs /stage/scripts/initial_boot_update.sh at every boot (@reboot). The script runs:
yum -y update --security --exclude=kernel*On CentOS, this applies nothing. CentOS repositories publish no security advisory metadata, so yum --security reports No packages needed for security and leaves every package as it is. Use Step 5 to update this image. To stop the boot-time job, remove its line with sudo crontab -e.
Common use cases
- Running software that is certified only on the CentOS 7 / RHEL 7 platform while you re-platform it
- Lift-and-shift of an existing CentOS 7 estate into Azure as a migration staging step
- Reproducing and testing against a CentOS 7 environment for compatibility work
For any workload that must stay secure long term, migrate to AlmaLinux, Rocky Linux, CentOS Stream or a current RHEL. CentOS 7 receives no further upstream security updates.
Troubleshooting
Cannot connect via SSH
- Verify that the VM is in the Running state in the Azure Portal.
- Check that port 22 is allowed in the Network Security Group.
- Make sure you are using the correct username:
azureuser, or the administrator name you chose. - Verify that your SSH key matches the one you supplied at create time. Password login is disabled, so a wrong key cannot fall back to a password prompt.
yum reports 404 errors or "Cannot find a valid baseurl"
The image's cached CentOS mirror list points at mirrors that have dropped CentOS 7. Point the repositories at the vault (Step 4), then run sudo yum clean all. If you add a third-party .repo file that references mirror.centos.org or mirrorlist.centos.org, repoint it to https://vault.centos.org/7.9.2009/... as well.
A failed vxagent.service at every boot
systemctl --failed shows vxagent.service as failed. It is the start script of an Azure Site Recovery replication agent (package InMageVx) left in the image. Its program files are not present, so it fails at boot and does nothing. It does not affect the virtual machine. To stop it from starting, run:
sudo chkconfig vxagent off
sudo systemctl reset-failed vxagentThe same agent adds the dracut module that prints the check_drivers.sh: No such file or directory line when a kernel is installed (Step 5). That message is harmless.
cloud-init status prints a NameError
Run it with sudo: sudo cloud-init status (see Step 7).
Azure agent not running
Check the agent's status:
systemctl status waagent --no-pagerIf it is not running, start and enable it with sudo systemctl enable --now waagent.
Security recommendations
- Do Steps 4 and 5 on every new virtual machine, then plan the migration off CentOS 7.
- Remove the leftover entries from
/root/.ssh/authorized_keysand setPermitRootLogin no(Step 6). - Allow SSH in the Network Security Group from your own address ranges only.
- The image runs with SELinux disabled. If your policy requires SELinux, test your workload with it enabled on a separate virtual machine before you change a running one.
- Enable firewalld if you need a host firewall (Step 8).
Important notes
CentOS Linux is free and open source. A single licence does not cover it. It is a distribution assembled from thousands of independently packaged components, each with its own terms, including the GPL, LGPL, MIT, BSD, Apache 2.0 and MPL. You can read every package's terms with rpm -qi <package> and under /usr/share/licenses/. No subscription, licence key or Red Hat entitlement is required.
CentOS Linux 7 reached end of life on 30 June 2024 and receives no further upstream security updates. This image was patched when it was built, and Step 5 brings it to the last packages in the CentOS 7.9.2009 vault. Plan a migration to a supported distribution (AlmaLinux, Rocky Linux, CentOS Stream or a current RHEL) for any workload that must remain secure.
CentOS is a trademark of Red Hat, Inc. The name is used here only to identify the distribution this image contains. SecureAnyCloud is not affiliated with, endorsed by or sponsored by Red Hat.
Support
For help with this image, contact SecureAnyCloud support:
- Website: secureanycloud.com
- Product catalogue: secureanycloud.com/products
- User guides: secureanycloud.com/guides
- SLA: 24-hour response guaranteed
Deploy on Azure
Launch CentOS 7.9 on Azure with 24/7 support from SecureAnyCloud.
View on Marketplace
Need help?
Our support team is available 24/7.
sales@secureanycloud.com