SSHSubsystemFwup

CircleCI Hex version

This library provides an ssh subsystem that applies Nerves "over-the-air" firmware updates. It is an alternative to nerves_firmware_ssh that extracts the update service to a :ssh.daemon/1 spec. This trims down the responsibilities of the library and makes it possible to:

  1. Customize ssh authentication (for example, password-based auth is possible)
  2. Handle host keys differently and more securely
  3. Run firmware updates on port 22 with other ssh services

In addition, the protocol for sending updates over ssh has been simplified. If you're coming from nerves_firmware_ssh, you'll have used the upload.sh script or mix upload. This library provides the same interface. If using upload.sh, you will need to rerun mix firmware.gen.script since the script has changed.

Installation

The easiest installation is to use nerves_ssh and have it bring in this library as a dependency. See that project for details.

However, if you do not want to use nerves_ssh, here's what do do. First, add the dependency:

def deps do
  [{:ssh_subsystem_fwup, "~> 0.5.0"}]
end

Then add ssh subsystem spec to the call that starts the ssh daemon. This code will look something like:

    {:ok, ref} =
      :ssh.daemon([
        {:subsystems, [SSHSubsystemFwup.subsystem_spec()]}
      ])

You will likely have many more options passed to the ssh.daemon.

Uploading firmware

There are two ways of uploading firmware. The first is to run:

mix upload

That doesn't work for everyone due to ssh authentication preferences. The alternative is to use commandline ssh. For convenience, ssh_subsystem_fwup can generate a script that makes this easier. Go to your Nerves project directory and run:

mix firmware.gen.script

This should create an upload.sh script. Frequently when starting out, you can run ./upload.sh without arguments since it will guess that it's supposed to upload to nerves.local. To specify a device to upload to, pass the device's hostname as the first argument. For example:

$ ./upload.sh nerves-1234.local
fwup: Upgrading partition B
|====================================| 100% (32.34 / 32.34) MB
Success!
Elapsed time: 4.720 s
Disconnected from 172.31.207.89 port 22

Note that the .local address assumes that mDNS has been configured on the device and that mDNS works on your network and OS. That's not always the case and a frequent source of frustration when it fails. When in doubt, check that you can upload to the device's IP address. You can get the IP address from your router or by connecting to the device's IEx prompt and running ifconfig.

Upload protocol

It's not necessary to use the upload.sh script. The following line is equivalent:

cat $firmware | ssh -s $nerves_device fwup

License

All source code is licensed under the Apache License, 2.0.