Giter Club home page Giter Club logo

ya-runtime-http-auth's Introduction

ya-runtime-http-auth

ya-runtime-http-auth is a Yagna runtime binary for advertising HTTP-based services on the Golem Network.


Quick links:


Overview

ya-runtime-http-auth serves as a gateway between the Golem Marketplace and an HTTP-based service accessible over the Internet.

                                +-------------- Provider's machine --------------+
+-----------+   Golem Network   | +----------+      +---------+      +---------+ |
| Requestor | <=================> | Provider | <--> | ExeUnit | <--> | Runtime | |
+-----------+                   | +----------+      +---------+      +---------+ |
                                +------------------------------------------------+

All HTTP requests to the service are routed via a custom reverse HTTP proxy implementation. The proxy authorizes users and collects per-user, per-endpoint usage statistics. These statistics will be used for billing purposes and sent to the Requestor.

The runtime binary is responsible for managing users authorized to use the service. Requestor's commands are translated into proxy's Management API calls, upon prior identity verification.

-------------- Provider's machine -----------+
  +---------+   Management API   +---------+ |     Internet      +------+
  | Runtime | <----------------> |  Proxy  | <=================> | User |
  +---------+                    +---------+ |                   +------+
                                     ||      |
                                 +---------+ |
                                 | Service | |
                                 +---------+ |
---------------------------------------------+                                                      

Runtime specification proposal can be found here.


Provider Agent - advertising a service

At the moment, it is required from the user to manually perform the setup steps below. This process will be largely automated in the future.

Preparing your service

  1. Ensure that the service is listening on a local socket (a private IP address).

  2. Configure a daemon supervisor for your service. In case of a crash, it should be automatically restarted.

  3. The service needs to be running when advertised on the Golem Network.

Please note that if your HTTP service requires some additional authorization (e.g. user certificates), it may not be supported by ya-runtime-http-auth in the current version.

Installation

  1. yagna

In order to install yagna, please refer to this handbook chapter.

  1. ya-runtime-http-auth

Download and install the latest deb package from the releases page. You will find the installed runtime and proxy binaries at the /usr/lib/yagna/plugins directory.

Service definition

Service definition files contain basic information on the service and the configuration of the proxy HTTP server. There can be multiple services exposed by a single server as long as they are configured with the distinct from endpoints.

The definition files are, by default, located at ~/.local/share/ya-runtime-http-auth/services. Create the path by typing the following command in a terminal:

mkdir -p ~/.local/share/ya-runtime-http-auth/services

Now, save this service definition file called acme-service.json at the newly created location:

{
  "name": "acme-service",
  "description": "ACME service v1.42",
  "serverName": ["service.acme.com", "1.2.3.4"],
  "bindHttps": "0.0.0.0:443",
  "bindHttp": "0.0.0.0:80",
  "from": "/acme",
  "to": "http://127.0.0.1:10000",
  "cert": {
    "path": "/secure/acme/certs/server.cert",
    "keyPath": "/secure/acme/certs/server.key"
  }
}
  • name - name of the service
  • description - extended service information
  • serverName - list of assigned domain names and / or public IP addresses
  • bindHttps - address to bind the HTTPS server to (required if bindHttp is not set)
  • bindHttp - address to bind the HTTP server to (required if bindHttps is not set)
  • from - source service endpoint. In this case, service.acme.com/acme or 1.2.3.4/acme
  • to - service listening URL
  • cert - certificate and private key paths (required for HTTPS)

In this example, all requests from e.g. https://1.2.3.4/acme/register will be redirected to http://127.0.0.1:10000/register.

It's not recommended to use an HTTP-only proxy server for the service. Unencrypted credentials sent by the users can be captured by malicious actors in their local networks. Please create and use self-signed certificates when facing real-world users. You might find the following chapter helpful.

Provider configuration

Runtime definition

Each advertised service acts as a separate runtime and requires a new descriptor file, located at

a. ~/.local/lib/yagna/plugins when using golemsp b. /usr/lib/yagna/plugins when running the ya-provider binary directly

Runtime definition file's name needs to match the ya-*.json pattern to be discovered by the Provider Agent. In this case, the file will be called ya-runtime-acme.json and contain the following:

[
  {
    "name": "acme-service",
    "version": "0.1.0",
    "supervisor-path": "exe-unit",
    "runtime-path": "ya-runtime-http-auth/ya-runtime-http-auth",
    "extra-args": [
      "--runtime-managed-image",
      "--runtime-arg", "acme-service"
    ],
    "config": {
    	"counters": {
    	  "http-auth.requests": {
            "name": "requests",
            "description": "Total number of HTTP requests",
            "price": true
    	  }
    	}
    }
  }
]
  • name - name of the service, advertised in the Golem Network
  • version - service version
  • supervisor-path - path to ExeUnit Supervisor, most often located in the same directory
  • extra-args - extra arguments passed to the ExeUnit Supervisor
    • --runtime-managed-image - the Supervisor will not be responsible for downloading an image / payload to be executed by the Runtime
    • --runtime-arg acme-service - the Runtime will look for a service definition file with a name set to acme-service
  • config -> counters
    • http-auth.requests - defines the service's HTTP request counter by ya-runtime-http-auth. "price": true informs the Supervisor that this counter will be used in calculating the price. The counter only includes users created by the current Requestor

Billing configuration

In order to advertise the newly-created service in the Golem Network, a billing profile needs to be created. This can be achieved by editing the Provider Agent's presets file (~/.local/share/ya-provider/presets.json) to include the following:

{
  "ver": "V1",
  "active": [
    "acme"
  ],
  "presets": [
    {
      "name": "acme",
      "exeunit-name": "acme-service",
      "pricing-model": "linear",
      "initial-price": 0,
      "usage-coeffs": {
        "golem.usage.duration_sec": 0.001,
        "golem.usage.cpu_sec": 0.001,
        "http-auth.requests": 0.00001
      }
    }
  ]
}

This configuration file contains a single active preset called acme, defined for the runtime acme-service, as stated in the ya-runtime-acme.json definition file. Each HTTP call made by an authorized user will cost the Requestor 0.00001 GLM (or tGLM when running on the test network).

Starting the provider

The configuration process is complete. Start your provider by typing golemsp run in the terminal.

Requestor Agent - overview

This link will point you to the minimal implementation of an HTTP service advertised on Golem Marketplace.

However, the real-world implementation would contain:

  • a custom market strategy that takes the HTTP request price into account
  • code to constrain the golem.runtime.http-auth.https property in the Offer to true. This way Requestors enable their users to establish secure HTTPS connections with the service.
  • the service info command outputs a certificate hash, which should be used by clients to verify certificate's contents

Self-signed certificates

In most cases, a provider's machine won't be addressable by a domain name and their certificate won't be signed by a trusted authority. When the server presents a self-signed certificate, users will only be able to verify the embedded signature.

However, the Requestor can equip each user with a certificate hash returned by the service info runtime command. Each user's HTTPS client may verify the certificate's hash, so that Man-in-the-Middle attacks can be prevented. The client should ignore the missing Certificate Authority signature and the domain name included in the certificate.

Creating a self-signed certificate with OpenSSL

Currently application do not support keys encrypted with des. Use nodes options to generate unecrypted private key.

openssl req -nodes -x509 -newkey rsa:4096 -keyout server.key -out server.cert -sha256 -days 3650

ya-runtime-http-auth's People

Contributors

mfranciszkiewicz avatar prekucki avatar scx1332 avatar wkargul avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

ya-runtime-http-auth's Issues

README for `ya-runtime-http-auth`

  • provide an overview of repository contents
  • include a step by step provider configuration example
  • link to requestor example in yapapi

Prototype a reverse HTTP proxy server

What:

  • create a reverse HTTP proxy server prototype
  • benchmark the implementation using a popular benchmarking tool (e.g. siege)
    • vs a static site served by nginx
    • vs a static site served by nginx, secured by a custom auth_request endpoint
      • create a simple server with a no-op auth endpoint

Why:

  • verify feasibility of the solution proposed in GAP-8
  • gather basic information on performance differences between the proxy implementation and nginx w/ auth_request
    • use nginx static site endpoint as reference

Follow GAP-8

Port `htpasswd.sh` to Rust

What:

  • port the minimal re-implementation of htpasswd to Rust (lib)
    • consider using the htpasswd-verify crate, an implementation of the apr1 digest and a .htpasswd formatter
  • the library should internally implement or provide helpers for locking files during .htpasswd file update
  • .htpasswd files should be flushed and synced as soon as possible
  • in the existing codebase, replace htpasswd.sh invocations with library calls

Why:

  • htpasswd.sh is a shell script which relies on external tools and proper environment (e.g. PATH configuration)
  • the library would allow for better error handling and portability (across Linux distros, across Windows / macOS)
  • .htpasswd locks are required when multiple runtimes (activities) modify the same access file

Publish API call counters

What:

  • periodically publish custom runtime counters (API calls per authenticated user)
  • publish the last known counter value on shutdown

Follow GAP-8

Why:

  • the number of API calls will be used for billing purposes; pass that information to ExeUnit supervisor

Blocked by #3

Implement `Runtime::{start, stop, test, offer-template}`

What:

  • the start command should add the designated service within the proxy via Management API:

    • when the proxy is responding, use the "add service" endpoint to register the service
    • when the API server responds with 409 (CONFLICT), get the information from the server
      • if the server configuration does not match the local one, return an error in start
  • for the stop command:

    • fetch last available counter values via Management API
    • publish the latest known counter values via ya-runtime-sdk
    • de-register users (if any) via Management API
  • implement the test command to verify that:

    • the runtime can discover service configuration files and their contents can be parsed successfully,
    • the proxy binary is runnable and starts successfully

    Note: test command is executed automatically by the provider agent on startup

  • implement the offer-template command so that the following will be included in the offer:

    • HTTPS support capability (always on in the current version)
    • certificate hash property (e.g. sha3:deadbeef..)
    • extra properties defined in the service configuration file (prefix with golem.runtime.http-auth.)
  • update the implementation of existing commands according to GAP-8

Why:

  • the runtime should be disabled if the proxy cannot be run successfully
  • requestors should be informed on provider's runtime capabilities (i.e. HTTPS support)

Blocked by #3 #5

Start the reverse proxy process

What:

  • spawn and detach the ya-http-proxy process to background
    • perform a readiness check (via e.g. running a GET /services HTTP request on Management API)
      • if a file lock is present, actively loop and wait until the API is ready
      • if there is no file lock, verify that API is responding
      • if any case that the proxy is not running, spawn the process; use a file locking mechanism to prevent multiple instances being spawned by multiple runtimes
  • follow GAP-8

Why:

  • we want to automate the process of starting the proxy server so that Provider's do not need to register it as a system service

Create Github Actions workflows

What:

  • CI workflow for running code test suites
  • CI workflow for creating releases and building runtime binaries
    • triggered by pushing tags matching v* or pre-rel-*
    • build for the following CPU architectures:
      • x86-64
      • aarch64

Why:

  • any available test suites should be run automatically against new pull requests in order to verify correctness of the new code
  • releases should be built in a static and pre-configured environment
  • the release process should be automated as much as possible

Implement log rotation support

What:

  • the access log reader is aware that the log can be rotated. The implementation detects that the file has been truncated and peeks the rotated file first
  • rotated file is chosen based on the log name value in runtime's configuration and file creation / modification time

Why:

  • logs can be rotated by a system daemon; remaining (rotated) log data must be parsed in order to preserve data (i.e. request counter) coherency

Blocked by #3

Implement an API call request counter module

What:

  • propose a name for the custom counter (main counter) of total number of requests made by all registered users within the runtime
  • in Runtime::start function, spawn a background task responsible for:
    • periodically fetch per-user and per-endpoint counter values from the proxy server for all registered users
    • publish the per-user counter via Runtime API to ExeUnit Supervisor (see the GAP for examples)
    • publish the last known counter value on shutdown

Why:

  • we need to provide a number of total calls per authenticated user as a custom runtime counter

Follow GAP-8

Management API client

What:

  • implement an HTTP client for the ya-http-proxy-client crate
  • the client sends and receives JSON responses only
    • supports deserialization of response body sizes up to 8 MB
    • returns deserialized body for erroneous (non-200) responses
  • compliant with the ya-http-proxy-client's Management API
    • provides helper functions for calling each available endpoint

Why:

  • external developers obtain an implementation of a read-to-use Management API client in Rust
  • the client will be used to develop a management CLI within ya-http-proxy

Support multiple services via a single binary

What:

  • Refactor the existing code according to GAP-8 in order to support multiple services via a single binary (via golemfactory/ya-runtime-sdk#19)
    • update the command line interface
    • update runtime configuration
    • implement service configuration file lookup
    • implement binary startup file lock mechanism
    • update the deploy and start commands

Why:

  • previous runtime implementation supported only a single service per binary / runtime configuration

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.