Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactors and Updates #14

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
_build
deps
68 changes: 55 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,41 +1,83 @@
FROM elixir:1.16.2-alpine AS build
FROM hexpm/elixir:1.16.2-erlang-26.2.5-ubuntu-noble-20240429 AS build

ARG MIX_ENV=prod
ARG UBOOT_ENV_SIZE=0x20000
ENV DEBIAN_FRONTEND=noninteractive

RUN apk add --no-cache --update-cache \
git \
make
RUN apt-get update \
&& apt-get install -y \
git make build-essential \
u-boot-tools \
libsodium-dev \
autotools-dev \
autoconf \
libtool \
pkg-config \
libarchive-dev \
libconfuse-dev \
zlib1g-dev \
xdelta3 \
dosfstools \
help2man \
curl \
mtools \
unzip \
zip

RUN mix archive.install github hexpm/hex branch latest --force
RUN /usr/local/bin/mix local.rebar --force

# Build fwup here to ensure that its built for the arch
WORKDIR /opt
RUN git clone https://github.com/fwup-home/fwup --depth 1 --branch v1.10.2
WORKDIR /opt/fwup
RUN ./autogen.sh && PKG_CONFIG_PATH=$PKG_CONFIG_PATH ./configure --enable-shared=no && make && make install

RUN mkdir -p /opt/app
ADD . /opt/app/

WORKDIR /opt/app

RUN echo "/etc/peridiod/uboot.env 0x0000 ${UBOOT_ENV_SIZE}" > /opt/app/support/fw_env.config
RUN mkenvimage -s ${UBOOT_ENV_SIZE} -o /opt/app/support/uboot.env /opt/app/support/uEnv.txt
RUN PERIDIO_META_PRODUCT=peridiod \
PERIDIO_META_DESCRIPTION=peridiod-dev \
PERIDIO_META_VERSION=1.0.0 \
PERIDIO_META_PLATFORM=docker \
PERIDIO_META_ARCHITECTURE=docker \
PERIDIO_META_AUTHOR=peridio \
fwup -c -f support/fwup.conf -o support/peridiod.fw
RUN fwup -a -t complete -i support/peridiod.fw -d support/peridiod.img
RUN mix deps.get --only $MIX_ENV
RUN mix release --overwrite

FROM alpine:3.19 as app
FROM ubuntu:noble as app

ENV DEBIAN_FRONTEND=noninteractive

RUN apk --no-cache add wireguard-tools iptables ip6tables inotify-tools libstdc++ libgcc u-boot-tools socat iproute2-ss agetty cgroup-tools
RUN apk --no-cache add 'fwup~=1.10' \
--repository http://nl.alpinelinux.org/alpine/edge/community/
RUN apt-get update && apt-get -y install locales socat libconfuse-dev libarchive-dev && apt-get clean
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

RUN useradd -ms /bin/bash peridio
RUN echo "peridio:peridio" | chpasswd

ENV PERIDIO_CONFIG_FILE=/etc/peridiod/peridio.json
ARG UBOOT_ENV_SIZE=0x20000

RUN mkdir -p /etc/peridiod
RUN mkdir -p /boot
RUN echo "echo \"Reboot Requested\"" > /usr/bin/reboot && chmod +x /usr/bin/reboot

COPY --from=build /opt/app/priv/peridio-cert.pem /etc/peridiod/peridio-cert.pem
COPY --from=build /opt/app/_build/prod/rel/peridiod /opt/peridiod
COPY --from=build /opt/app/support/peridio.json /etc/peridiod/peridio.json
COPY --from=build /opt/app/support/uEnv.txt /etc/peridiod/uEnv.txt

RUN echo "/etc/peridiod/uboot.env 0x0000 ${UBOOT_ENV_SIZE}" > /etc/fw_env.config
RUN mkenvimage -s ${UBOOT_ENV_SIZE} -o /etc/peridiod/uboot.env /etc/peridiod/uEnv.txt
COPY --from=build /opt/app/support/uboot.env /etc/peridiod/uboot.env
COPY --from=build /opt/app/support/fw_env.config /etc/fw_env.config
COPY --from=build /opt/app/support/peridiod.img /etc/peridiod/peridiod.img
COPY --from=build /opt/fwup/src/fwup /usr/bin/fwup

WORKDIR /opt/peridiod
CMD ["/opt/peridiod/bin/peridiod", "start_iex"]
68 changes: 64 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ Peridiod is configured via a json formatted file on the filesystem. The location
* `fwup`: Keys related to the use of fwup for the last mile.
* `devpath`: The block storage device path to use for applying firmware updates.
* `public_keys`: A list of authorized public keys used when verifying update archives.
* `remote_shell`: Enable or disable the remote console feature.
* `extra_args`: A list of extra arguments to pass to the fwup command used for applying fwup archives. Helpful when needing to use the --unsafe flag in fwup.
* `env`: A json object of `"ENV_VAR": "value"` pairs to decorate the environment which fwup is executed from.
* `remote_shell`: Enable or disable the remote getty feature.
* `remote_iex`: Enable or disable the remote IEx feature. Useful if you are deploying a Nerves distribution.
mobileoverlord marked this conversation as resolved.
Show resolved Hide resolved
* `node`: Node configuration settings
* `key_pair_source`: Options are `file`, `uboot-env`, `pkcs11`. This determines the source of the identity key information.
* `key_pair_config`: Different depending on the `key_pair_source`

`key_pair_source: file`:
* `private_key_path`: Path on the filesystem to a PEM encoded private key file.
* `certificate_path`: Path on the filesystem to a PEM encoded x509 certificate file.

`key_pair_source: uboot-env`:
* `private_key`: The key in the uboot environment which contains a PEM encoded private key.
* `certificate`: The key in the uboot environment which contains a PEM encoded x509 certificate.

`key_pair_source: pkcs11`:
* `key_id`: The `PKCS11` URI used to for private key operations.
Examples:
Expand Down Expand Up @@ -99,3 +102,60 @@ PKCS11 Identity using ATECC608B TrustAndGo
"cert_id": "pkcs11:token=MCHP;object=device;type=cert"
}
```

### Configuring with Elixir

The peridiod application can be set using config.exs in a Nerves based application. The following is an example of the keys that can be set:

```elixir
config :peridiod,
device_api_host: "device.cremini.peridio.com",
device_api_port: 443,
device_api_sni: "device.cremini.peridio.com",
device_api_verify: :verify_peer,
device_api_ca_certificate_path: nil,
key_pair_source: "env",
key_pair_config: %{"private_key" => "PERIDIO_PRIVATE_KEY", "certificate" => "PERIDIO_CERTIFICATE"},
fwup_public_keys: [],
fwup_devpath: "/dev/mmcblk0",
fwup_env: [],
fwup_extra_args: [],
remote_shell: false,
remote_iex: true,
```

## Running with Docker

You can debug using docker by generating an SSL certificta eand private key pair that is trusted by Peridio Cloud and pass it into the container.
mobileoverlord marked this conversation as resolved.
Show resolved Hide resolved

Building the container:

```bash
docker build --tag peridio/peridiod .
danielspofford marked this conversation as resolved.
Show resolved Hide resolved
```

Running the container:

```bash
podman run -it --rm --env PERIDIO_CERTIFICATE="$(cat /path/to/end-entity-certificate.pem)" --env PERIDIO_PRIVATE_KEY="$(cat /path/to/end-entity-private-key.pem)" peridio/peridiod:latest
```

The container will be built using the `peridio.json` configuration file in the support directory. For testing you can modify this as you please. It is configured by default to allow testing for the remote shell and even firmware updates using deployments. You can create firmware to test for deployments using the following:

```bash
PERIDIO_META_PRODUCT=peridiod \
PERIDIO_META_DESCRIPTION=peridiod-dev \
PERIDIO_META_VERSION=1.0.1 \
PERIDIO_META_PLATFORM=docker \
PERIDIO_META_ARCHITECTURE=docker \
PERIDIO_META_AUTHOR=peridio \
fwup -c -f support/fwup.conf -o support/peridiod.fw
```

Then sign the firmwaare using a key pair that is trusted by Peridio Cloud

```bash
fwup --sign -i support/peridiod.fw -o support/peridiod-signed.fw --public-key "$(cat ./path/to/fwup-key.pub)" --private-key "$(cat /path/to/fwup-key.priv)"
```

You can then upload `support/peridiod-signed.fw` to Peridio Cloud and configure a deployment. The container will not actually apply anything persistent, but it will simulate downloading and applying an update.
3 changes: 2 additions & 1 deletion lib/peridiod/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ defmodule Peridiod.Application do

def start(_type, _args) do
application_config = Application.get_all_env(:peridiod)
configurator_config = struct(Configurator.Config, application_config)

children = [
{KV, application_config},
Configurator,
{Configurator, configurator_config},
UpdateManager,
Connection,
Socket
Expand Down
Loading