---
# System prepended metadata

title: Refactored Holo Init

---

Refactored Holo Init 
===
## Longer term discussion

### Security implications of controlling a machine through web application

We are recommending that we continue to pursue "access on local network" options for security reasons.

The hAppy team has written their code to date with a context assumption of "local access".


So, we are still working under that paradigm

Under a local network access paradigm for hp-admin:

Key issues:


1. We do NOT want to produce an outcome that introduces imperative management of state of the machine. This is an absolute critical requirement. We have the option not to do that in the execution of any request, and so the solution provided will utilize the underlying nix system to make changes to state of the system at all times.
2. Direct access to underlying system should not be granted to any application, and the actions should instead be abstracted by services that live on the machine that can perform validation/authorize changes based on the best possible validation of the request. 



The specified actions at https://hackmd.io/UI8da3lxRbCJjf8nfQyudA#In-version-2-closed-alpha-wave-1 range from just getting information off of the machine, all the way to changing the state of the machine. But a simple "API" for any application can be 

1. Create signed request in queue
2. Wait for response
3. Display response 


... and then on the back end we would handle these as we see fit: running a command, generating a nix expression, etc


## Notes on the specification for this sprint

Per user story https://www.pivotaltracker.com/story/show/168404617


### Claim machine API/Application

We are proposing 

Data collected
```mermaid
sequenceDiagram
    participant B as Browser
    participant A as Auth Server
    participant F as FreshDesk
    participant E as Email
    participant Z as ZeroTier
    
    B->>A: I want to verify *this* email
    A-->>+F: Checks that *this* email is allowed in Closed Alpha
    F-->>-A: Yes
    A->>E: Send a verification code to *this* email
    E->>B: User clicks link
    B->>+A: Link contains signature and ZeroTier ID
    A-->>Z: Authorize given ID
    Z-->>A: Success
    A->>-B: Success
```

http://authorizer.holohost.net - **will ignore requests without a valid path**

- Data currently stored
  - freshdesk_key (freshdesk api auth key)
  - freshdesk_pass (is ignored)
  - network_id (zerotier network id)
  - super_secret_hmac_key (our symmetric key)
  - zerotier_auth_token (zerotier api auth key)

#### `POST /v1/auth`

POST http://authorizer.holo.host/v1/auth - **requires POST and params**

```
{ 
  "email": "sam.rose@holo.host",
  "zerotier_address": "ab01cf1594"
}
```
- Checks email against Freshdesk API. Exits with 401 on error
- Creates `hmac` from worker's symmetric key and data
```
{
  "zerotier_address": <ZeroTier address>
}
```
- Sends an authorization email with https://authorizor.holo.host/v1/challenge link. 

Responses:

- 200 OK
- 400 Bad Request: missing parameter
- 401 Unauthorized: email address not found

#### `GET /v1/challenge`

GET http://authorizer.holohost.net/v1/challenge?hmac=validhmac&addr=someaddr&exp=exp
**requires GET & hmac & network address & expiration**

Example: `/v1/challenge?hmac=uG1XC4EsfqTNL9xu4k77ort/1pW7wOrFrwgzhlS75ONeWnkMVmsFmQ&addr=ab01cf1594&exp=1570739123388`

`hmac` is Base64-encoded [keyed BLAKE2b](https://tools.ietf.org/html/rfc7693#section-1) HMAC of:

```
{
  "zerotier_address": <ZeroTier address>
}
```

To determine validity, Cloudflare worker should reconstruct message and try to validate `hmac`

If valid, adds given ZeroTier address to Holo networks using https://my.zerotier.com/central-api.html#member-member-post endpoint.

Responses:

- 200 OK
- 400 Bad Request: missing parameter or malformed data


## New Holo Init Workflow 

Initial configuration of blank HoloPort comes from key material and user configured email + password (salted+hashed) saved as a JSON file on USB stick.

### Entropy for Holochain + ZT Key Generation

This can be generated offline on an air-gapped machine (eg. from DPKI), if desired, or online directly at https://quickstart.holo.host for less security-conscious people.



```mermaid
sequenceDiagram
    participant quickstart.holo.host
    participant Browser
    participant User
    participant USB
    participant HoloPort
    participant CloudFlare Worker
    
    quickstart.holo.host->>Browser: UI Application
    Note over Browser,User: Save Page for offline use
    User->>Browser: Select 'Configure New HoloPort' page
    Browser->>User: Present UI to collect Entropy, etc.
    User->>Browser: Select Create Key / Supply DPKI Entropy
    User->>Browser: Enter email + password
    Browser->>User: Compute JSON HoloPort config package, present Link
    User->>USB: Save JSON file via link
    USB->>HoloPort: Insert USB w/ JSON, reboot HoloPort
    Note over USB,HoloPort: - conf. BIOS to boot from USB
    Note over USB,HoloPort: - Loader checks kernel+initrd sig. on hard drive
    Note over USB,HoloPort: - boot kernel+initrd from hard drive
    USB->>HoloPort: Kernel starts Holochain conductor w/ key from USB
    HoloPort--xUSB: Service ejects USB, blacklists device kernel module
    User->>Browser: Select 'Monitor HoloPort Status' page
    Browser-->CloudFlare Worker: Establish Websocket to receive Status Updates
```

#### Preventing Post-Boot USB Access

Booting from USB into a signature-checking bootloader that confirms the signature of the kernel + initrd before loading is the first step.

To protect this phase, we must also prevent access to the USB after boot, and also prevent changing the BIOS:

1) Prevent kernel modules from being loaded:
- https://www.google.ru/amp/s/linux-audit.com/increase-kernel-integrity-with-disabled-linux-kernel-modules-loading/amp/
> The Linux kernel can be configured to disallow loading new kernel modules. The sysctl key kernel.modules_disabled is very straightforward for this purpose. In this article, we will have a look at the configuration of this option.
1) Prevent BIOS from being updated:
- https://wiki.archlinux.org/index.php/Flashing_BIOS_from_Linux
> Note: With Linux kernel versions greater than 4.4, CONFIG_IO_STRICT_DEVMEM a new kernel security measure can make flashrom stop working, in that case you can try adding iomem=relaxed to your kernel parameters.

By ensuring that immediately after the Holochain conductor loads the key material from the USB, that the USB is ejected, modules removed, and the kernel permanently prevented from loading new modules, no further access to the USB is possible.  Any new kernel modules must be included in a signed kernel+initrd update from Holo.

By preventing access to device memory, and preventing upgrading the BIOS, we prevent post-boot programs from adjusting the boot procedure.

Of course, physical access to the HoloPort allows circumvention of all of these protectsion.

### Booting HoloPort & Authenticating to Holo ZT Network

1 cloudflare worker microservice (zato is deprecated)

HC key is generated, data sent to service, Email sent, email validation link clicked, node authorized on zerotier

Holoport detects it is authorized on zerotier

We now map into Holo router.


```mermaid
sequenceDiagram
    participant quickstart.holo.host
    participant Holoport
    participant Cloudflare Worker
    participant Freshdesk API
    participant Email Validate
    participant Zerotier API
    participant Holo Router
    quickstart.holo.host->>Holoport: Submit email, key entropy via USB stick
    loop Holoport
        Holoport->>Holoport: Generate keys
    end
    Holoport->>Cloudflare Worker: POST email, zt_address
    Cloudflare Worker->>Freshdesk API: check email
    # Cloudflare Worker->>quickstart.holo.host: email found/not found in freshdesk.
    Freshdesk API->>Cloudflare Worker: email valid
    Cloudflare Worker->>Email Validate: Validation Email sent.
    #Cloudflare Worker->>quickstart.holo.host: Validation Email event.
    Email Validate->>Cloudflare Worker: link clicked
    #Cloudflare Worker->>quickstart.holo.host: email validation link clicked.
    Cloudflare Worker->>Zerotier API: Node authorized on zerotier network 
    #Cloudflare Worker->>quickstart.holo.host: node authorized on zerotier.
    Zerotier API->>Holoport: Holoport Recognizes Node Auth on zerotier
    Holoport->>Holo Router: Holoport writes key and signature to router
    quickstart.holo.host->>Holo Router: test for hp-admin DNS
    Holo Router->>quickstart.holo.host: Success! Start hp-admin
    
```


## HP Admin API 

## Authentication

http basic auth


### OS Update
```
user:pass (signed requests with key derived from password)

POST /os-update


Responses


HTTP 200 OK
HTTP 401 Unauthorized
```

## OS info
```
user:pass


GET /os-info

Reponses

HTTP 200 OK

{
    "public_key":"<key>",
    "email":"</email>",
    "registered":true,
    "zero_tier":"status from zt listnetworks info",
    "os_version":"<version>",
    "os_release_version":"<release_version>"
}

HTTP 401 Unauthorized
```


## Reset holoport

A rescue image on USB stick will be required to address this


### Reset states:

#### Factory reset zero out to virgin OS uninitialized

(Throw away all data on restored machine)

#### Restore or transfer to another machine initialized state

Reset and save all data


#### Backup all mutable data

We just back up all mutable data



### Sketch of Holoport services


