Coder Social home page Coder Social logo

exuvia's Introduction

Exuvia

Exuvia abstracts away everything needed to connect to your Elixir node, via both SSH and the distribution protocol.

Exuvia runs an Erlang-native SSH daemon and automatically handles authentication and authorization of users, in a way that is convenient for both development and production. No more headaches trying to erl -remsh through a firewall; just SSH in!

An Exuvia connection to a node on the same machine

Bind+accept Configuration

Exuvia's listener is configured (almost) entirely by setting a single app-env variable:

  config :exuvia, :accept, "ssh://..."

The value of :accept is a URI string that represents both the bind(3) arguments for the SSH daemon listener (the host and port parts), and your choice of authentication/authorization strategy (in the schema, username, and password parts.) In most cases, it's the same URI you'd have to use, as a client, to connect!

If you don't set the value for :accept, the default value is "ssh://*:*@localhost:2022". This will start a listener on only the loopback interface, on port 2022, and will authorize any user passing any password/key.

Exuvia uses Confex for configuration, so you can also set :accept (or any of Exuvia's other options) using an OS environment variable, like so:

  config :exuvia, {:system, "EXUVIA_ACCEPT"}

:accept-string Cookbook

An OpenSSH-like public SSH server that depends on the filesystem (i.e. the host must have /home/$user/.ssh/authorized_keys files):

  config :exuvia, :accept, "ssh://0.0.0.0:2022"

An SSH server with a single, global password, and no public-key authentication:

  config :exuvia, :accept, "ssh://*:hunter2@localhost:2022"

An OpenSSH-behaving server, that only allows one particular user to authenticate, and relies on PKI (no password option):

  config :exuvia, :accept, "ssh://bob@localhost:2022"

An OpenSSH-behaving server, that only allows the user the Erlang-node runs as to authenticate, and only via PKI:

  config :exuvia, :accept, "ssh://$USER@localhost:2022"

A server that binds to a new ephemeral port on each node boot (important if you're running multiple instances of your node at once):

  config :exuvia, :accept, "ssh://localhost:0"

GitHub authentication!

Rather than managing keys on your Erlang node host—or managing an LDAP/Kerberos server or whatever else—Exuvia allows you to use GitHub as an LDAP-like server. (GitHub does have a public API for retrieving people's public SSH keys, after all.)

This is the best thing since sliced bread if you're a small devops team (like most Elixir shops are.) A representation of your team and its credentials likely already exists on GitHub. Why duplicate it elsewhere?

Here's the magic:

  config :exuvia, :accept, "github+ssh://org1,org2:[email protected]:2022"

This line configures Exuvia to connect to GitHub using a GitHub access token—mytoken above—and ask it two questions about each connecting user:

  1. what are their registered public keys (and does the client's SSH challenge-response match any of them)?

  2. what GitHub organizations does the client's passed username belong to, and do any of them match any of the orgs (org1 and org2 above) whose members are allowed in?

This is surprisingly secure: just tell Exuvia a GitHub organization name, and suddenly exactly the set of people in that organization will be able to connect to your node, using exactly the keys they have registered with GitHub. This is pleasantly stateless: it works just as well on your development machine as it does on a production server. You can just leave it running everywhere your code is. Say goodbye to local dummy auth strategies.👋

And don't worry: the responses from GitHub are cached, so frequent visits by SSH-probing bots won't get your GitHub account disabled.

Installation

  1. Add exuvia to your list of dependencies in mix.exs:
def deps, do: [
  {:exuvia, "~> 0.2.4"}
]
  1. Add a config :exuvia, accept: "..." line to your config.exs.

Additional setup for using the GitHub authentication strategy

  1. Create a GitHub personal access token. The token's owner should be a user with the right to view the organization's member list.

  2. Ensure, for each GitHub user that should be able to connect, that their visibility within your GitHub organization is set to public. Users with private visibility don't appear in the organization's members list.

  3. Ensure your users have their up-to-date SSH keys registered with GitHub.

Other Configuration

  • :host_keys_path (optional): a directory containing pre-existing SSH host keys for the SSH daemon to use. E.g.

      config :exuvia, host_keys_path: "/opt/your_elixir_project/priv/ssh"

    If this value is not set, a directory will be created under deps/exuvia/priv and new keys will be auto-generated there.

    NOTE: If you're using Elixir in Docker, I would heavily suggest creating a persistent ssh-host-keys volume and configuring Exuvia to use it. Otherwise, your SSH clients will likely spit out known-hosts-file mismatch errors.

  • :max_sessions (optional): the number of simultaneous SSH connections. Defaults to 25.

  • :shell_module (optional): a module possessing a function start/1, which will get called to create a shell upon successful connections. Look at lib/exuvia/shell.ex for an example.

exuvia's People

Contributors

tsutsu avatar mtwilliams avatar

Stargazers

 avatar Sam Gaw avatar  avatar Matthew O'Gorman avatar James Stephens avatar Denys Oblohin avatar Roman Heinrich avatar Thomas Steinhausen avatar Ho-Sheng Hsiao avatar  avatar Ole J. Rosendahl avatar  avatar

Watchers

Matthew O'Gorman avatar James Cloos avatar  avatar  avatar

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.