Remotely Upgrade SmartOS

Purpose

This document explains how to remotely upgrade a SmartOS server using Jakob Borgʼs smartos-platform-upgrade script.

Requirements

This how-to requires that you have SSH access to the global zone of a SmartOS server and that the SmartOS server can download a script from GitHub and an updated SmartOS system image from Joyent.

Process

First we will install the smartos-platform-upgrade script. Then we will run the script to upgrade SmartOS.

Install smartos-platform-upgrade

SmartOS boots from a USB stick. Most files in the global zone files are ephemeral. In order to install any script, it must be stored in a location which is preserved on the USB stick. As suggested by the projectʼs README.md file, weʼll install it in /opt/local/bin.

SmartOS is missing a store of certificate authorities in the Global Zone. Specifically, the Certificate Authority used by GitHub, the DigiCert High Assurance EV Root CA, is not trusted in the SmartOS Global Zone.

You can fix that by copying and pasting from your browser:

-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----

Weʼre going to save this as /root/digicert-ha-ev-root.pem.

Alternately, you can download it:

curl -skL https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt | openssl x509 -inform der -out /root/digicert-ha-ev-root.pem

Itʼs always a good idea to verify the signature. DigiCert says that the fingerprints are D4:74:DE:57:5C:39:B2:D3:9C:85:83:C5:C0:65:49:8A (MD5) and 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 (SHA-1):

# openssl x509 -in digicert-ha-ev-root.pem -noout -fingerprint -md5 | grep D4:74:DE:57:5C:39:B2:D3:9C:85:83:C5:C0:65:49:8A > /dev/null && echo Matched MD5. || echo MD5 did not match.
Matched MD5.
# openssl x509 -in digicert-ha-ev-root.pem -noout -fingerprint -sha1 | grep 5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25 > /dev/null && echo Matched SHA-1. || echo SHA-1 did not match.
Matched SHA-1.

Finally, I note that the SHA-256 fingerprint of the authentic certificate is 74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF:

# openssl x509 -in digicert-ha-ev-root.pem -noout -fingerprint -sha256
SHA256 Fingerprint=74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF

This matches the SHA-256 fingerprint from my browserʼs certificate store.

Now, we can download the platform-upgrade script from GitHub and make the script executable:

[root@smartos ~]# mkdir -p /opt/local/bin
[root@smartos ~]# curl --cacert /root/digicert-ha-ev-root.pem -L https://raw.githubusercontent.com/calmh/smartos-platform-upgrade/master/platform-upgrade > /opt/local/bin/platform-upgrade
[root@smartos ~]# chmod 755 /opt/local/bin/platform-upgrade

Upgrade SmartOS

At this point, you should read the script to understand how it works. (As of July 2016, it is 158 lines of BASH.) When you are satisfied that you understand the script, run it to upgrade your SmartOS installation:

[root@smartos ~]# platform-upgrade
Downloading latest platform (platform-20170202T040152Z.tgz)... OK
Verifying checksum... OK
Extracting latest platform... OK
Marking release version... OK
Checking current boot device... detected c0t0d0, mounted, OK
Updating platform on boot device... OK
Remounting boot device... OK
Verifying kernel checksum on boot device... OK
Verifying boot_archive checksum on boot device... OK
Activating new platform on /dev/dsk/c0t0d0p1... OK

Boot device upgraded. To do:

 1) Sanity check the contents of /tmp/tmp.dVaUJe/usb
 2) umount /dev/dsk/c0t0d0p1
 3) reboot
[root@smartos ~]#

You should do a sanity check before you reboot. The usb and platform directories should look something like this:

[root@smartos ~]# cd /tmp/tmp.dVaUJe/usb/
[root@smartos /tmp/tmp.dVaUJe/usb]# ls -al
total 4622
drwxrwxrwx   1 root     root        1024 Feb  7 05:15 .
drwx------   4 root     root         699 Feb  7 05:15 ..
-rwxrwxrwx   1 root     root     2359350 Aug  2  2016 160802082402.bmp
drwxrwxrwx   1 root     root         512 Jun  9  2016 boot
drwxrwxrwx   1 root     root         512 Feb  7 05:15 old
drwxrwxrwx   1 root     root         512 Feb  7 05:14 platform
[root@smartos /tmp/tmp.dVaUJe/usb]# cd platform/
[root@smartos /tmp/tmp.dVaUJe/usb/platform]# ls -al
total 6
drwxrwxrwx   1 root     root         512 Feb  7 05:14 .
drwxrwxrwx   1 root     root        1024 Feb  7 05:15 ..
drwxrwxrwx   1 root     root         512 Feb  7 05:14 i86pc
-rwxrwxrwx   1 root     root          17 Feb  2 06:11 root.password
-rwxrwxrwx   1 root     root          17 Feb  7 05:13 version

Then you should unmount the USB partition and reboot:

[root@smartos /tmp/tmp.dVaUJe/usb/platform]# cd
[root@smartos ~]# umount /dev/dsk/c0t0d0p1
[root@smartos ~]# reboot
reboot: Halting 9 zones.

If everything went well, your SmartOS system will be running the latest version. You can check with uname -a:

[root@smartos ~]# uname -a
SunOS smartos 5.11 joyent_20170202T040152Z i86pc i386 i86pc