Skip to content

Commit

Permalink
EndpointAuthentication filter
Browse files Browse the repository at this point in the history
Implementation of the filter that will route
packets to Endpoints that have a matching
connection_id to the auth token found in the
dynamic metadata.

Closes #8
  • Loading branch information
markmandel committed Nov 18, 2020
1 parent cc5dafc commit 1636934
Show file tree
Hide file tree
Showing 10 changed files with 491 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/extensions/filters/capture_bytes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ down the chain.

This is often used as a way of retrieving authentication tokens from a packet, and used in combination with
[ConcatenateBytes](./concatenate_bytes.md) and
`[[TODO: add router filter name when ready]]` filter to provide common packet routing utilities.
[EndpointAuthentication](endpoint_authentication.md) filter to provide common packet routing utilities.

#### Filter name
```text
Expand Down
70 changes: 70 additions & 0 deletions docs/extensions/filters/endpoint_authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# EndpointAuthentication

The `EndpointAuthentication` filter's job is to ensure only authorised clients are able to send packets to Endpoints that
they have access to.

It does this via matching an authentication token found in the
[Filter dynamic metadata]`(TODO: add link to dynamic metadata docs)`, and comparing it to Endpoint's connection_id
values, and only letting packets through to those Endpoints if there is a match.

Capturing the authentication token from an incoming packet can be implemented via the [CaptureByte](./capture_bytes.md)
filter, with an example outlined below, or any other filter that populates the configured dynamic metadata key for the
authentication token to reside.

On the game client side the [ConcatenateBytes](./concatenate_bytes.md) filter can be used to add authentication tokens
to outgoing packets.

#### Filter name
```text
quilkin.extensions.filters.endpoint_authentication.v1alpha1.EndpointAuthentication
```

### Configuration Examples
```rust
# let yaml = "
local:
port: 7000
filters:
- name: quilkin.extensions.filters.capture_bytes.v1alpha1.CaptureBytes # This filter is often used in conjunction to capture the authentication token
config:
metadataKey: myapp.com/myownkey
size: 3
remove: true
- name: quilkin.extensions.filters.endpoint_authentication.v1alpha1.EndpointAuthentication
config:
metadataKey: myapp.com/myownkey
server:
endpoints:
- name: Game Server No. 1
address: 127.0.0.1:26000
connection_ids:
- MXg3aWp5Ng== # Authentication is provided by these ids, and matched against
- OGdqM3YyaQ== # the value stored in Filter dynamic metadata
- name: Game Server No. 2
address: 127.0.0.1:26001
connection_ids:
- bmt1eTcweA==
# ";
# let config = quilkin::config::Config::from_reader(yaml.as_bytes()).unwrap();
# assert_eq!(config.filters.len(), 2);
# quilkin::proxy::Builder::from(std::sync::Arc::new(config)).validate().unwrap();
```

View the [CaptureBytes](./capture_bytes.md) filter documentation for more details.

### Configuration Options

```yaml
properties:
metadataKey:
type: string
default: quilkin.dev/captured_bytes
description: |
The key under which the captured bytes are stored in the Filter invocation values.
```
### Metrics
* `quilkin_filter_EndpointAuthentication_packets_dropped`
A counter of the total number of packets that have been dropped as they could not be authenticated against an
Endpoint.
3 changes: 2 additions & 1 deletion docs/extensions/filters/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ Quilkin includes several filters out of the box.
| [Debug](debug.md) | Logs every packet |
| [LocalRateLimiter](./local_rate_limit.md) | Limit the frequency of packets. |
| [ConcatenateBytes](./concatenate_bytes.md) | Add authentication tokens to packets. |
| [CaptureBytes](capture_bytes.md) | Capture bytes from a packet into the Filter Context. |
| [CaptureBytes](capture_bytes.md) | Capture specific bytes from a packet and store them in filter dynamic metadata. |
| [EndpointAuthentication](endpoint_authentication.md) | Only sends packets to Endpoints that they are authenticated to access. |

### FilterConfig <a name="filter-config"></a>
Represents configuration for a filter instance.
Expand Down
6 changes: 6 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ impl From<&str> for ConnectionId {
}
}

impl PartialEq<Vec<u8>> for ConnectionId {
fn eq(&self, other: &Vec<u8>) -> bool {
self.0.eq(other)
}
}

/// ConnectionConfig is the configuration for either a Client or Server proxy
#[derive(Debug, Deserialize, Serialize)]
pub enum ConnectionConfig {
Expand Down
38 changes: 38 additions & 0 deletions src/extensions/filters/endpoint_authentication/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2020 Google LLC All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use prometheus::core::{AtomicI64, GenericCounter};
use prometheus::Result as MetricsResult;
use prometheus::{IntCounter, Registry};

use crate::metrics::{filter_opts, CollectorExt};

/// Register and manage metrics for this filter
pub(super) struct Metrics {
pub(super) packets_dropped_total: GenericCounter<AtomicI64>,
}

impl Metrics {
pub(super) fn new(registry: &Registry) -> MetricsResult<Self> {
Ok(Metrics {
packets_dropped_total: IntCounter::with_opts(filter_opts(
"packets_dropped",
"EndpointAuthentication",
"Total number of packets dropped due to invalid connection_id values.",
))?
.register(registry)?,
})
}
}
Loading

0 comments on commit 1636934

Please sign in to comment.