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

auth: Use authmap for auth_required policies #24410

Merged
merged 5 commits into from
Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 30 additions & 48 deletions bpf/bpf_lxc.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#define EVENT_SOURCE LXC_ID

#include "lib/auth.h"
#include "lib/tailcall.h"
#include "lib/common.h"
#include "lib/config.h"
Expand Down Expand Up @@ -399,8 +400,6 @@ static __always_inline int handle_ipv6_from_lxc(struct __ctx_buff *ctx, __u32 *d
trace.reason = (enum trace_reason)ret;

#if defined(ENABLE_L7_LB)
from_l7lb = ctx_load_meta(ctx, CB_FROM_HOST) == FROM_HOST_L7_LB;

if (proxy_port > 0) {
/* tuple addresses have been swapped by CT lookup */
cilium_dbg3(ctx, DBG_L7_LB, tuple->daddr.p4, tuple->saddr.p4,
Expand Down Expand Up @@ -436,17 +435,8 @@ static __always_inline int handle_ipv6_from_lxc(struct __ctx_buff *ctx, __u32 *d
verdict = policy_can_egress6(ctx, tuple, SECLABEL, *dst_id,
&policy_match_type, &audited, ext_err, &proxy_port);

/* Create CT entry if drop for auth required. */
if (verdict == DROP_POLICY_AUTH_REQUIRED) {
if (ct_status == CT_NEW) {
ct_state_new.src_sec_id = SECLABEL;
ct_create6(get_ct_map6(tuple), &CT_MAP_ANY6, tuple, ctx,
CT_EGRESS, &ct_state_new, proxy_port > 0, from_l7lb,
true);
} else if (!ct_state->auth_required) {
verdict = CTX_ACT_OK; /* allow if auth done */
}
}
if (verdict == DROP_POLICY_AUTH_REQUIRED)
verdict = auth_lookup(SECLABEL, *dst_id, node_id, (__u8)*ext_err);

/* Emit verdict if drop or if allow for CT_NEW or CT_REOPENED. */
if (verdict != CTX_ACT_OK || ct_status != CT_ESTABLISHED) {
Expand All @@ -460,6 +450,9 @@ static __always_inline int handle_ipv6_from_lxc(struct __ctx_buff *ctx, __u32 *d
return verdict;

skip_policy_enforcement:
#if defined(ENABLE_L7_LB)
from_l7lb = ctx_load_meta(ctx, CB_FROM_HOST) == FROM_HOST_L7_LB;
#endif
switch (ct_status) {
case CT_NEW:
ct_recreate6:
Expand All @@ -470,7 +463,7 @@ static __always_inline int handle_ipv6_from_lxc(struct __ctx_buff *ctx, __u32 *d
*/
ct_state_new.src_sec_id = SECLABEL;
ret = ct_create6(get_ct_map6(tuple), &CT_MAP_ANY6, tuple, ctx,
CT_EGRESS, &ct_state_new, proxy_port > 0, from_l7lb, false);
CT_EGRESS, &ct_state_new, proxy_port > 0, from_l7lb);
if (IS_ERR(ret))
return ret;
trace.monitor = TRACE_PAYLOAD_LEN;
Expand Down Expand Up @@ -851,8 +844,6 @@ static __always_inline int handle_ipv4_from_lxc(struct __ctx_buff *ctx, __u32 *d
trace.reason = (enum trace_reason)ret;

#if defined(ENABLE_L7_LB)
from_l7lb = ctx_load_meta(ctx, CB_FROM_HOST) == FROM_HOST_L7_LB;

if (proxy_port > 0) {
/* tuple addresses have been swapped by CT lookup */
cilium_dbg3(ctx, DBG_L7_LB, tuple->daddr, tuple->saddr, bpf_ntohs(proxy_port));
Expand Down Expand Up @@ -887,17 +878,8 @@ static __always_inline int handle_ipv4_from_lxc(struct __ctx_buff *ctx, __u32 *d
verdict = policy_can_egress4(ctx, tuple, SECLABEL, *dst_id,
&policy_match_type, &audited, ext_err, &proxy_port);

/* Create CT entry if drop for auth required. */
if (verdict == DROP_POLICY_AUTH_REQUIRED) {
if (ct_status == CT_NEW) {
ct_state_new.src_sec_id = SECLABEL;
ct_create4(get_ct_map4(tuple), &CT_MAP_ANY4, tuple, ctx,
CT_EGRESS, &ct_state_new, proxy_port > 0, from_l7lb,
true);
} else if (!ct_state->auth_required) {
verdict = CTX_ACT_OK; /* allow if auth done */
}
}
if (verdict == DROP_POLICY_AUTH_REQUIRED)
verdict = auth_lookup(SECLABEL, *dst_id, node_id, (__u8)*ext_err);

/* Emit verdict if drop or if allow for CT_NEW or CT_REOPENED. */
if (verdict != CTX_ACT_OK || ct_status != CT_ESTABLISHED) {
Expand All @@ -911,6 +893,9 @@ static __always_inline int handle_ipv4_from_lxc(struct __ctx_buff *ctx, __u32 *d
return verdict;

skip_policy_enforcement:
#if defined(ENABLE_L7_LB)
from_l7lb = ctx_load_meta(ctx, CB_FROM_HOST) == FROM_HOST_L7_LB;
#endif
switch (ct_status) {
case CT_NEW:
ct_recreate4:
Expand All @@ -933,7 +918,7 @@ static __always_inline int handle_ipv4_from_lxc(struct __ctx_buff *ctx, __u32 *d
* handling here, but turns out that verifier cannot handle it.
*/
ret = ct_create4(ct_map, ct_related_map, tuple, ctx,
CT_EGRESS, &ct_state_new, proxy_port > 0, from_l7lb, false);
CT_EGRESS, &ct_state_new, proxy_port > 0, from_l7lb);
if (IS_ERR(ret))
return ret;
break;
Expand Down Expand Up @@ -1398,7 +1383,7 @@ ipv6_policy(struct __ctx_buff *ctx, int ifindex, __u32 src_label,
{
struct ct_state *ct_state, ct_state_new = {};
struct ipv6_ct_tuple *tuple;
int ret, verdict = CTX_ACT_OK, hdrlen, zero = 0;
int ret, verdict, hdrlen, zero = 0;
struct ct_buffer6 *ct_buffer;
void *data, *data_end;
struct ipv6hdr *ip6;
Expand Down Expand Up @@ -1481,17 +1466,20 @@ ipv6_policy(struct __ctx_buff *ctx, int ifindex, __u32 src_label,
verdict = policy_can_access_ingress(ctx, src_label, SECLABEL,
tuple->dport, tuple->nexthdr, false,
&policy_match_type, &audited, ext_err, proxy_port);
if (verdict == DROP_POLICY_AUTH_REQUIRED &&
ret != CT_NEW && !ct_state->auth_required)
verdict = CTX_ACT_OK; /* allow if auth done */
if (verdict == DROP_POLICY_AUTH_REQUIRED) {
struct remote_endpoint_info *sep = lookup_ip6_remote_endpoint(&orig_sip, 0);

if (sep)
verdict = auth_lookup(SECLABEL, src_label, sep->node_id, (__u8)*ext_err);
}

/* Emit verdict if drop or if allow for CT_NEW or CT_REOPENED. */
if (verdict != CTX_ACT_OK || ret != CT_ESTABLISHED)
send_policy_verdict_notify(ctx, src_label, tuple->dport,
tuple->nexthdr, POLICY_INGRESS, 1,
verdict, *proxy_port, policy_match_type, audited);

if (verdict != CTX_ACT_OK && verdict != DROP_POLICY_AUTH_REQUIRED)
if (verdict != CTX_ACT_OK)
return verdict;

skip_policy_enforcement:
Expand All @@ -1518,17 +1506,13 @@ ipv6_policy(struct __ctx_buff *ctx, int ifindex, __u32 src_label,
if (ret == CT_NEW) {
ct_state_new.src_sec_id = src_label;
ret = ct_create6(get_ct_map6(tuple), &CT_MAP_ANY6, tuple, ctx, CT_INGRESS,
&ct_state_new, *proxy_port > 0, false,
verdict == DROP_POLICY_AUTH_REQUIRED);
&ct_state_new, *proxy_port > 0, false);
if (IS_ERR(ret))
return ret;

/* NOTE: tuple has been invalidated after this */
}

if (verdict != CTX_ACT_OK)
return verdict;

if (!revalidate_data(ctx, &data, &data_end, &ip6))
return DROP_INVALID;

Expand Down Expand Up @@ -1705,7 +1689,7 @@ ipv4_policy(struct __ctx_buff *ctx, int ifindex, __u32 src_label, enum ct_status
struct ct_buffer4 *ct_buffer;
__u32 monitor = 0, zero = 0;
enum trace_reason reason;
int ret, verdict = CTX_ACT_OK;
int ret, verdict;
__be32 orig_sip;
__u8 policy_match_type = POLICY_MATCH_NONE;
__u8 audited = 0;
Expand Down Expand Up @@ -1802,17 +1786,19 @@ ipv4_policy(struct __ctx_buff *ctx, int ifindex, __u32 src_label, enum ct_status
tuple->dport, tuple->nexthdr,
is_untracked_fragment,
&policy_match_type, &audited, ext_err, proxy_port);
if (verdict == DROP_POLICY_AUTH_REQUIRED &&
ret != CT_NEW && !ct_state->auth_required)
verdict = CTX_ACT_OK; /* allow if auth done */
if (verdict == DROP_POLICY_AUTH_REQUIRED) {
struct remote_endpoint_info *sep = lookup_ip4_remote_endpoint(orig_sip, 0);

if (sep)
verdict = auth_lookup(SECLABEL, src_label, sep->node_id, (__u8)*ext_err);
}
/* Emit verdict if drop or if allow for CT_NEW or CT_REOPENED. */
if (verdict != CTX_ACT_OK || ret != CT_ESTABLISHED)
send_policy_verdict_notify(ctx, src_label, tuple->dport,
tuple->nexthdr, POLICY_INGRESS, 0,
verdict, *proxy_port, policy_match_type, audited);

if (verdict != CTX_ACT_OK && verdict != DROP_POLICY_AUTH_REQUIRED)
if (verdict != CTX_ACT_OK)
return verdict;

skip_policy_enforcement:
Expand Down Expand Up @@ -1841,17 +1827,13 @@ ipv4_policy(struct __ctx_buff *ctx, int ifindex, __u32 src_label, enum ct_status
ct_state_new.src_sec_id = src_label;
ct_state_new.from_tunnel = from_tunnel;
ret = ct_create4(get_ct_map4(tuple), &CT_MAP_ANY4, tuple, ctx, CT_INGRESS,
&ct_state_new, *proxy_port > 0, false,
verdict == DROP_POLICY_AUTH_REQUIRED);
&ct_state_new, *proxy_port > 0, false);
if (IS_ERR(ret))
return ret;

/* NOTE: tuple has been invalidated after this */
}

if (verdict != CTX_ACT_OK)
return verdict;

if (!revalidate_data(ctx, &data, &data_end, &ip4))
return DROP_INVALID;

Expand Down
33 changes: 33 additions & 0 deletions bpf/lib/auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/* Copyright Authors of Cilium */

#ifndef __LIB_AUTH_H_
#define __LIB_AUTH_H_

#include "common.h"
#include "maps.h"
#include "utime.h"

static __always_inline int
auth_lookup(__u32 local_id, __u32 remote_id, __u16 remote_node_id, __u8 auth_type)
{
struct auth_info *auth;
struct auth_key key = {
.local_sec_label = local_id,
.remote_sec_label = remote_id,
.remote_node_id = remote_node_id,
.auth_type = auth_type,
.pad = 0,
};

/* Check L3-proto policy */
auth = map_lookup_elem(&AUTH_MAP, &key);
if (likely(auth)) {
/* check that entry has not expired */
if (utime_get_time() < auth->expiration)
return CTX_ACT_OK;
}

return DROP_POLICY_AUTH_REQUIRED;
}
#endif
12 changes: 10 additions & 2 deletions bpf/lib/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,18 @@ struct auth_key {
__u8 pad;
};

/* expiration is Unix epoch time in unit nanosecond/2^9 (ns/512). */
struct auth_info {
__u64 expiration;
};

/*
* Runtime configuration items for the datapath.
*/
enum {
RUNTIME_CONFIG_UTIME_OFFSET = 0, /* Index to Unix time offset in 512 ns units */
};

struct metrics_key {
__u8 reason; /* 0: forwarded, >0 dropped */
__u8 dir:2, /* 1: ingress 2: egress */
Expand Down Expand Up @@ -883,7 +891,7 @@ struct ct_entry {
proxy_redirect:1, /* Connection is redirected to a proxy */
dsr:1,
from_l7lb:1, /* Connection is originated from an L7 LB proxy */
auth_required:1,
jrajahalme marked this conversation as resolved.
Show resolved Hide resolved
reserved1:1, /* Was auth_required, not used in production anywhere */
from_tunnel:1, /* Connection is over tunnel */
reserved:5;
__u16 rev_nat_index;
Expand Down Expand Up @@ -1072,7 +1080,7 @@ struct ct_state {
syn:1,
proxy_redirect:1, /* Connection is redirected to a proxy */
from_l7lb:1, /* Connection is originated from an L7 LB proxy */
auth_required:1,
jrajahalme marked this conversation as resolved.
Show resolved Hide resolved
reserved1:1, /* Was auth_required, not used in production anywhere */
from_tunnel:1, /* Connection is from tunnel */
reserved:8;
__be32 addr;
Expand Down
9 changes: 2 additions & 7 deletions bpf/lib/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ static __always_inline __u8 __ct_lookup(const void *map, struct __ctx_buff *ctx,
ct_state->dsr = entry->dsr;
ct_state->proxy_redirect = entry->proxy_redirect;
ct_state->from_l7lb = entry->from_l7lb;
ct_state->auth_required = entry->auth_required;
ct_state->from_tunnel = entry->from_tunnel;
ct_state->ifindex = entry->ifindex;
}
Expand Down Expand Up @@ -832,8 +831,7 @@ static __always_inline int ct_create6(const void *map_main, const void *map_rela
struct ipv6_ct_tuple *tuple,
struct __ctx_buff *ctx, const enum ct_dir dir,
const struct ct_state *ct_state,
bool proxy_redirect, bool from_l7lb,
bool auth_required)
bool proxy_redirect, bool from_l7lb)
{
/* Create entry in original direction */
struct ct_entry entry = { };
Expand All @@ -853,7 +851,6 @@ static __always_inline int ct_create6(const void *map_main, const void *map_rela
*/
entry.proxy_redirect = proxy_redirect;
entry.from_l7lb = from_l7lb;
entry.auth_required = auth_required;
}

entry.rev_nat_index = ct_state->rev_nat_index;
Expand Down Expand Up @@ -903,8 +900,7 @@ static __always_inline int ct_create4(const void *map_main,
struct ipv4_ct_tuple *tuple,
struct __ctx_buff *ctx, const enum ct_dir dir,
const struct ct_state *ct_state,
bool proxy_redirect, bool from_l7lb,
bool auth_required)
bool proxy_redirect, bool from_l7lb)
{
/* Create entry in original direction */
struct ct_entry entry = { };
Expand All @@ -925,7 +921,6 @@ static __always_inline int ct_create4(const void *map_main,
*/
entry.proxy_redirect = proxy_redirect;
entry.from_l7lb = from_l7lb;
entry.auth_required = auth_required;
}

entry.rev_nat_index = ct_state->rev_nat_index;
Expand Down