Skip to main content

Tools for handling Arista SWI/X

Project description

swi-tools

Scripts for operating on an Arista SWI or SWIX

A SWI is a SoftWare Image containing the software that will run on the switch when the image is booted. A SWIX is a SoftWare Image eXtension, a collection of files (ex RPMs, squashfs) that can be installed to extend the behavior of the base SWI.

Scripts

  • swi-signature: Add a cryptographic signature to an Arista SWI or SWIX
  • swix-signature: A convenience alias for the above
  • verify-swi: Verify the cryptographic signature of an Arista SWI or SWIX
  • verify-swix: A convenience alias for the above
  • swix-create: Create a new SWIX file
  • swi-signing-service: Simple example of a signing service (all local)

Installation

pip3 install switools

Alternatively:

git clone https://github.com/aristanetworks/swi-tools.git
cd swi-tools
python3 setup.py install

Dependencies

  1. Python3. For a version that works with python2, use the version 1.0 release.
  2. Zip - Used in the swi-signature script to remove a signature from the SWI/X if you want to re-sign it, this comes preinstalled on many operating systems.
  3. M2Crypto - installed automatically with the setup script.
  4. PyYAML - Used to read the manifest.yaml, if added, when creating a SWIX.
  5. jsonschema - Used to verify the manifest.yaml, if added, when creating a SWIX.

Creating a SWIX

Creating a SWIX is a straightforward process involving the swix-create command.

$ swix-create -h
usage: swix-create [-h] [-f] [-i manifest.yaml]
                   OUTFILE.swix PACKAGE.rpm [PACKAGE.rpm ...]

positional arguments:
  OUTFILE.swix          Name of output file
  PACKAGE.rpm           An RPM to add to the SWIX

optional arguments:
  -h, --help            show this help message and exit
  -f, --force           Overwrite OUTFILE.swix if it already exists
  -i manifest.yaml, --info manifest.yaml
                        Location of manifest.yaml file to add metadata to SWIX

1. Creating a simple SWIX

$ swix-create MySwix.swix MyRpm.rpm
  adding: manifest.txt (stored 0%)
  adding: MyRpm.rpm (stored 0%)

Your SWIX is ready to be installed on a switch!

(Arista)# scp user@host:/path/MySwix.swix extension:
Copy completed successfully.
(Arista)# show extensions
Name             Version/Release      Status      Extension
---------------- -------------------- ----------- ---------
MySwix.swix      1.0.3/1.el7          A, NI       1
(Arista)# extension MySwix.swix
Note: no agents to restart

Et voilà! Your extension has been installed. Note that your extension may require some agents to be restarted. e.g., A restart of ConfigAgent is required if any CLI plugins have been added.

2. Adding a manifest.yaml file

The functionality of the SWIX can be enriched by adding a YAML file which contains instructions on when and how to install certain files. Such file is added with the -i switch, followed by the file, which will get validated and added to the SWIX. A sample manifest.yaml

metadataVersion: 1.0
version:
  - 4.21.1*:
    - AppBeta.rpm
    - AppBeta-lib.rpm
    - AppBeta.squashfs:
      - mount: /opt/apps/hello_world
  - 4.20.{6-9}*:
    - AppStable.rpm
    - AppStable.squashfs:
      - mount: /opt/apps/hello_world
agentsToRestart:
  - ConfigAgent
  - IgmpSnoopingAgent

At the moment, the only supported metadata version is 1.0. The other entry is the version-specific instructions for the extension. The first indented entry reads as:

  • For EOS versions 4.25.1 (Also 4.25.1.1, 4.25.1FX, etc., but not 4.25.10)
    • Install AppBeta.rpm
    • Install AppBeta-lib.rpm
    • Mount the SquashFS file AppBeta.squashfs on /opt/apps/hello_world
    • Prompt the user that ConfigAgent and IgmpSnoopingAgent need to be restarted. This only works on EOS versions 4.25.1 and later.

This way, you can publish one SWIX that works on multiple versions of EOS.

Signing an Arista SWI/X

Signing an Arista SWI or SWIX is a multi-step process involving the swi-signature script. First, with swi-signature prepare, a null signature file (a fix-sized signature file made entirely of null bytes) is added to the SWI/X, at the path /swi-signature (for SWI files) or /swix-signature (for SWIX files) in the zip file. Next, a signature is generated from the resulting SWI/X using a signing key. Finally, with swi-signature sign, the null signature file in the SWI/X is updated to reflect both the signature that was generated and the signing certificate used to verify the signature.

For EOS images starting 4.27.2, the process changes a little. For that, version 1.2 of this tool is needed. That is because a 4.27.2 image will contain multiple images, thus the prepare/sign split becomes inpractical. Instead, one has to provide a "swi-signing-server" binary (somewhere in PATH) that given a digest will return it signed. In that case, the swi-signing-server has access to the signer's private key. There is an example of how such a swi-signing-server could look like (it is using a local key). So in case no signer key is provided on the command line, providing a signatureFile instead will no longer do (it will still work though if the image is a pre 4.27.2 image). With 4.27.2+ images, the null-signature is automaticaly added and will overwrite any pre-existing signature forcefully.

1. Preparing the SWI/X for signing

Before generating a signature of the SWI/X, the SWI/X must be pre-signed with a null signature, a fix-sized signature file made entirely of null bytes. This can be done with the prepare option in the swi-signature script. At the end of the preparation, the sha256 hash of the SWI/X with the null signature is printed out in hex format. The hash is used in the next step to generate the real signature of the SWI/X file.

$ swi-signature prepare -h
usage: swi-signature prepare [-h] [--force-sign] [--outfile OUTFILE]
                             [--size SIZE]
                             EOS.swi[x]

positional arguments:
  EOS.swi[x]         Path of the SWI/X to prepare for signing

optional arguments:
  -h, --help         show this help message and exit
  --force-sign       Force signing the SWI/X if it's already signed
  --outfile OUTFILE  Path to save SWI/X with null signature, if not replacing
                     the input SWI/X
  --size SIZE        Size of null signature to add (default 8192 bytes)

Examples:

$ swi-signature prepare EOS.swi
84f6e823976f6d499fb161c2502ba9474b68abca7e98a9c98251ea5bd5e93765

This adds a null signature of 8192 bytes (the default) to EOS.swi, and prints out its sha256 hash in hex format. Keep track of this hash for use in the next step, as input into a signing server to generate a signature signed by a private key.

$ swi-signature prepare EOS.swi --force-sign --outfile EOS_temp.swi --size 9000
deleting: swi-signature
10aa98f4bd283256c8cd922d1bf40fb1b25a13d97049e4c0135e7140cb63d579

This copies EOS.swi to EOS_temp.swi, and signs EOS_temp.swi with a null signature of 9000 bytes, even if it has been signed before (removes the old signature).

Signing SWIX files behaves the same.

2. Signing the SWI/X

After adding a null signature file to the SWI/X, the SWI/X can now be signed. The null signature will be replaced by a real signature that contains both the signature of the SWI/X and the signing certificate that will be used to verify the signature. There are two options depending on whether you have direct access to the signing private key.

$ swi-signature sign -h
usage: swi-signature sign [-h]
                          (--signature SIGNATURE.txt | --key SIGNINGKEY.key)
                          EOS.swi[x] SIGNINGCERT.crt ROOTCERT.crt

positional arguments:
  EOS.swi[x]            Path of the SWI/X to sign.
  SIGNINGCERT.crt       Path of signing certificate.
  ROOTCERT.crt          Root certificate of signing certificate to verify
                        against 

optional arguments:
  -h, --help            show this help message and exit
  --signature SIGNATURE.txt
                        Path of base64-encoded SHA-256 signature file of EOS.swi or swix, signed by
                        signing cerificate.
  --key SIGNINGKEY.key  Path of signing key, used to generate the signature

2a. Signing SWI/X without direct access to private key

If there is no direct access to the private key, we assume that the private key is stored remotely in some form of signing server. A user should be able to query this signing server to use the signing key to sign an input hash and return the resulting signature. The input hash that should be used is printed out in the swi-signature prepare step. Since it is given in hex format, the signing server should be able to accept this sha256 hash in hex format as an input. The signing server should then sign the input hash with its signing private key, and then return the resulting signature as well as the signing certificate corresponding to the private key. The resulting signature must be converted to base64 format to be used in the swi-signature sign script.

Example:

$ # Prepare EOS.swi for signing and save the hash to input_hash.txt
$ swi-signature prepare EOS.swi > input_hash.txt                    
 
$ # input_hash.txt is a sha256 hash of EOS.swi in hex format
$ cat input_hash.txt
0f1f680a7c97f274cf2b6d131595521fec2a97509aceaddac529b7ab46ef6f8f

$ # Invoke a script that talks to a signing server that takes a hash as input and returns the signing certificate and generated signature.
$ ./talk-to-signing-server --input input_hash.txt --outputCertFile signing.crt --outputSignatureFile signature.txt 

$ # The resulting signature must be in base64 format
$ cat signature.txt
MEYCIQCcpjTgTZm9c+QdlVJ0W6xe7sxhjs7KXbwDngwC3/66QwIhAL7SRpkPOtOSyJPDlEqhyLzziQyght/E1iUSpmvEXmxg
$
$ swi-signature sign EOS.swi signing.crt root.crt --signature signature.txt
SWI file EOS.swi successfully signed and verified.

Signs EOS.swi with a pre-generated signature. At the end of signing, the resulting SWI will be automatically verified with the user-provided root certificate. SWIX signing behaves the same.

2b. Signing SWI/X with direct access to private key

If there is direct access to the private key, the key can be used directly in the input to the signing script as follows: Examples:

$ swi-signature sign EOS.swi signing.crt root.crt --key signing.key
SWI file EOS.swi successfully signed and verified.

Signs EOS.swi using signing.crt. The signature used is created by signing the hash of EOS.swi with signing.key.

2c. Signing EOS 4.27.2+ SWI with direct access to private key

Example:

$ swi-signature sign EOS.swi /etc/swi-signing/signing.crt /etc/swi-signing/root.crt --key /etc/swi-signing/signing.key
Optimizations in EOS.swi: Default Sand-4GB Strata-4GB
Default sha256: a3276b9976bb2471838dc95fbd2a38dcf1e7e5510bcfa8dfe0f0eff8b935a709
Sand-4GB sha256: 4d0d23293eaecc7f55e7ee9776b0c250bef1a335e1b4ea28ef4eea989eb917f9
Strata-4GB sha256: 520cbde6d60d1089bfbc95d9086c47ce4a6fc0399a5b8a29fc6c1bd95c7d029a
Adding signature files to EOS.swi: Default.signature Sand-4GB.signature Strata-4GB.signature
EOS.swi sha256: 913eb842e408ceddea914543230c9e13ff63e360fc6a6735ef9c0c1571209fb3
SWI/X file EOS.swi successfully signed and verified.

2d. Signing EOS 4.27.2+ SWI without direct access to private key

Example:

$ which swi-signing-service
/usr/local/bin/swi-signing-service

$ swi-signature sign EOS.swi /etc/swi-signing/signing.crt /etc/swi-signing/root.crt
... (same as above)

Verifying an Arista SWI/X signature

The verify-swi script verifies the signature in a SWI or SWIX by checking that the signing certificate used to sign the SWI/X is trusted by a specified root certificate, and that signing the SWI/X with the signing certificate matches the signature of the SWI/X. By default, the script verifies the signing certificate against the Arista root certificate, which is installed with the package.

$ verify-swi -h
usage: verify-swi [-h] [--CAfile CAFILE] EOS.swi[x]

Verify Arista SWI image or SWIX extension

positional arguments:
  EOS.swi[x]       SWI/X file to verify

optional arguments:
  -h, --help       show this help message and exit
  --CAfile CAFILE  Root certificate to verify against. (default:
                   ARISTA_ROOT_CA.crt)

Examples:

$ verify-swi EOS.swi 
SWI verification failed.
$ echo $?
4

The above example verifies EOS.swi using the Arista root certificate. However, the signature is not valid. Invalid signature verification returns a non-zero return code.

$ verify-swi EOS.swi --CAfile root.crt
SWI verification successful.
$ echo $?
0

Here EOS.swi is verified using root.crt. Verification in this case was successful.

$ verify-swi EOS.swi --CAfile /etc/swi-signing/root.crt
Optimizations in EOS.swi: Default Sand-4GB Strata-4GB
Default: SWI/X verification successful.
Sand-4GB: SWI/X verification successful.
Strata-4GB: SWI/X verification successful.
SWI/X verification successful.

Above's output was for a 4.27.2+ image (which has multiple contained images)

Testing

To run unit tests:

python3 setup.py test 

End-to-end tests after install:

./tests/swim_test.sh 

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

switools-1.2.tar.gz (28.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page