endpoint auth whitelist

pull/1306/head
Jeff Becker 4 years ago
parent 9f11b03016
commit 5abf111159
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -165,17 +165,24 @@ namespace llarp
conf.defineOption<std::string>("network", "keyfile", false, "", AssignmentAcceptor(m_keyfile));
conf.defineOption<std::string>("network", "auth-url", false, "", [this](std::string arg) {
if (arg.empty())
return;
m_AuthUrl = std::move(arg);
});
conf.defineOption<bool>("network", "auth", false, false, AssignmentAcceptor(m_AuthEnabled));
conf.defineOption<std::string>("network", "auth-method", false, "", [this](std::string arg) {
if (arg.empty())
return;
m_AuthMethod = std::move(arg);
});
conf.defineOption<std::string>("network", "auth-url", false, "", AssignmentAcceptor(m_AuthUrl));
conf.defineOption<std::string>(
"network", "auth-method", false, "llarp.auth", [this](std::string arg) {
if (arg.empty())
return;
m_AuthMethod = std::move(arg);
});
conf.defineOption<std::string>(
"network", "auth-whitelist", false, true, "", [this](std::string arg) {
service::Address addr;
if (not addr.FromString(arg))
throw std::invalid_argument(stringify("bad loki address: ", arg));
m_AuthWhitelist.emplace(std::move(addr));
});
conf.defineOption<bool>(
"network", "reachable", false, ReachableDefault, AssignmentAcceptor(m_reachable));
@ -864,6 +871,46 @@ namespace llarp
"Permanently map a `.loki` address to an IP owned by the snapp. Example:",
"mapaddr=whatever.loki:10.0.10.10 # maps `whatever.loki` to `10.0.10.10`.",
});
// extra [network] options
// TODO: probably better to create an [exit] section and only allow it for routers
def.addOptionComments(
"network",
"exit",
{
"Whether or not we should act as an exit node. Beware that this increases demand",
"on the server and may pose liability concerns. Enable at your own risk.",
});
def.addOptionComments(
"network",
"auth",
{
"authenticate remote sessions against a whitelist or an external lmq server",
"true/false",
});
def.addOptionComments(
"network",
"auth-url",
{
"lmq endpoint to talk to for authenticating new sessions",
"ipc:///var/lib/lokinet/auth.socket",
});
def.addOptionComments(
"network",
"auth-method",
{
"lmq function to call for authenticating new sessions",
"llarp.auth",
});
def.addOptionComments(
"network",
"auth-whitelist",
{
"manually add a remote endpoint by .loki address to the access whitelist",
});
return def.generateINIConfig(true);
}
@ -908,47 +955,6 @@ namespace llarp
"File containing service node's seed.",
});
// extra [network] options
// TODO: probably better to create an [exit] section and only allow it for routers
def.addOptionComments(
"network",
"exit",
{
"Whether or not we should act as an exit node. Beware that this increases demand",
"on the server and may pose liability concerns. Enable at your own risk.",
});
def.addOptionComments(
"network",
"auth-url",
{
"lmq endpoint to talk to for authenticating new sessions",
});
def.addOptionComments(
"network",
"auth-method",
{
"lmq function to call for authenticating new sessions",
});
// TODO: define the order of precedence (e.g. is whitelist applied before blacklist?)
// additionally, what's default? What if I don't whitelist anything?
def.addOptionComments(
"network",
"exit-whitelist",
{
"List of destination protocol:port pairs to whitelist, example: udp:*",
"or tcp:80. Multiple values supported.",
});
def.addOptionComments(
"network",
"exit-blacklist",
{
"Blacklist of destinations (same format as whitelist).",
});
return def.generateINIConfig(true);
}

@ -82,8 +82,10 @@ namespace llarp
std::optional<service::Address> m_exitNode;
std::unordered_map<huint128_t, service::Address> m_mapAddrs;
bool m_AuthEnabled = false;
std::optional<std::string> m_AuthUrl;
std::optional<std::string> m_AuthMethod;
std::unordered_set<service::Address, service::Address::Hash> m_AuthWhitelist;
// TODO:
// on-up

@ -118,7 +118,11 @@ namespace llarp
if (conf.m_AuthUrl.has_value() and conf.m_AuthMethod.has_value())
{
auto auth = std::make_shared<rpc::EndpointAuthRPC>(
*conf.m_AuthUrl, *conf.m_AuthMethod, Router()->lmq(), shared_from_this());
*conf.m_AuthUrl,
*conf.m_AuthMethod,
conf.m_AuthWhitelist,
Router()->lmq(),
shared_from_this());
auth->Start();
m_AuthPolicy = std::move(auth);
}

@ -4,9 +4,14 @@
namespace llarp::rpc
{
EndpointAuthRPC::EndpointAuthRPC(
std::string url, std::string method, LMQ_ptr lmq, Endpoint_ptr endpoint)
std::string url,
std::string method,
Whitelist_t whitelist,
LMQ_ptr lmq,
Endpoint_ptr endpoint)
: m_AuthURL(std::move(url))
, m_AuthMethod(std::move(method))
, m_AuthWhitelist(std::move(whitelist))
, m_LMQ(std::move(lmq))
, m_Endpoint(std::move(endpoint))
{
@ -15,11 +20,13 @@ namespace llarp::rpc
void
EndpointAuthRPC::Start()
{
if (m_AuthURL.empty())
return;
m_LMQ->connect_remote(
m_AuthURL,
[self = shared_from_this()](lokimq::ConnectionID c) {
self->m_Conn = std::move(c);
LogInfo("connected to endpoint auth server via ", c);
LogInfo("connected to endpoint auth server via ", *self->m_Conn);
},
[self = shared_from_this()](lokimq::ConnectionID, std::string_view fail) {
LogWarn("failed to connect to endpoint auth server: ", fail);
@ -33,13 +40,16 @@ namespace llarp::rpc
llarp::service::ConvoTag,
std::function<void(service::AuthResult)> hook)
{
if (m_AuthWhitelist.count(from))
{
m_Endpoint->RouterLogic()->Call([hook]() { hook(service::AuthResult::eAuthAccepted); });
return;
}
if (not m_Conn.has_value())
{
LogWarn("No connection to ", m_AuthURL);
m_Endpoint->RouterLogic()->Call([hook]() { hook(service::AuthResult::eAuthFailed); });
return;
}
LogInfo("try auth: ", m_AuthMethod);
// call method with 1 parameter: the loki address of the remote
m_LMQ->request(
*m_Conn,
@ -49,14 +59,12 @@ namespace llarp::rpc
service::AuthResult result = service::AuthResult::eAuthFailed;
if (success and not data.empty())
{
LogInfo("auth reply: ", data[0]);
const auto maybe = service::ParseAuthResult(data[0]);
if (maybe.has_value())
{
result = *maybe;
}
}
LogInfo("auth result for ", from, " ", result);
self->m_Endpoint->RouterLogic()->Call([hook, result]() { hook(result); });
},
from.ToString());

@ -15,9 +15,14 @@ namespace llarp::rpc
{
using LMQ_ptr = std::shared_ptr<lokimq::LokiMQ>;
using Endpoint_ptr = std::shared_ptr<llarp::service::Endpoint>;
using Whitelist_t = std::unordered_set<llarp::service::Address, llarp::service::Address::Hash>;
explicit EndpointAuthRPC(
std::string url, std::string method, LMQ_ptr lmq, Endpoint_ptr endpoint);
std::string url,
std::string method,
Whitelist_t whitelist,
LMQ_ptr lmq,
Endpoint_ptr endpoint);
~EndpointAuthRPC() = default;
void
@ -32,6 +37,7 @@ namespace llarp::rpc
private:
const std::string m_AuthURL;
const std::string m_AuthMethod;
const Whitelist_t m_AuthWhitelist;
LMQ_ptr m_LMQ;
Endpoint_ptr m_Endpoint;
std::optional<lokimq::ConnectionID> m_Conn;

@ -4,6 +4,7 @@
#include <functional>
#include "address.hpp"
#include "handler.hpp"
#include <crypto/types.hpp>
namespace llarp::service
{

Loading…
Cancel
Save