# Quick Start (from Marketplace)

> So you've heard about DiscrimiNAT, and would like to take it for a test drive? This is the page for you!

So you've heard about DiscrimiNAT, and would like to take it for a test drive? This is the page for you!

Here you'll find easy instructions on how to deploy a brand new VPC in AWS, secured by the [DiscrimiNAT Firewall](/discriminat/) for egress traffic filtering right from the onset, and instructions on how to evaluate its capabilities in order to see if it fits your business needs.

:::info
Contact us for expert help at `devsecops@chasersystems.com` at any stage of your journey – we'll jump on a screen-sharing call right away!
:::

---

### i. MARKETPLACE SUBSCRIBE

![AWS Marketplace Subscription](img/01_subscribe.png)

Proceed to our [AWS Marketplace page](https://aws.amazon.com/marketplace/pp/prodview-7ulmdnoq5jnwu) and click the **Continue to Subscribe** button. This step is entirely self-service.

---

![AWS Marketplace Subscription](img/01_accept-terms.png)

You will need to press the **Accept Terms** button next and wait until it's ready for configuration.

---

![AWS Marketplace Subscription](img/01_subscribed.png)

Once ready, do **not** proceed with the configuration, instead read on and press the **Launch Stack** button present in the next section here.

---

### ii. CLOUDFORMATION TEMPLATE – DEMO ENVIRONMENT

:::tip
If you have [deployed through Terraform](/docs/discriminat/aws/iac/#terraform-modules) or are considering, you may jump straight to [Configuring an Allowlist](#vi-configuring-an-allowlist).
:::

Our self-service demo (using CloudFormation) includes a couple of instances to make it easy to evaluate the capabilities of DiscrimiNAT.

Ensure you are logged into the AWS console and have selected the intended region for the demo before you click the following button.

[![Launch Stack](img/launch-stack.svg)](https://console.aws.amazon.com/cloudformation/home?#/stacks/create/review?templateURL=https://cloudformation-aws-discriminat-gwlb.s3.eu-west-2.amazonaws.com/2az_demo.json&stackName=plugleak)

---

### iii. STACK PARAMETERS

![CloudFormation Stack Parameters](img/03_stack-parameters.png)

:::info
Contact us for expert help at `devsecops@chasersystems.com` at any stage of your journey – we'll jump on a screen-sharing call right away!
:::

You may want to change the **Stack name**, everything else has safe defaults.

**Stack name:** This is a unique identifier for your deployment. In our case, and the case of this documentation, we have chosen _plugleak_. This name will prefix a lot of the resources that the stack will create. If you choose a different name and are following this demo through, don't forget to replace _plugleak_ with _your-chosen-name_ in the relevant steps.

#### EXAMPLE APPLICATION EGRESS ALLOWLIST CONFIGURATION

This section contains optional customisation for the demo allowlist.

**MyAppHTTPSAllowlist:** A comma-separated list of domains (without whitespace) that you wish your demo app to be able to connect to via a HTTPS or TLS connection. Note: Most services now use TLS for end-to-end encryption. It's not just for web page traffic, this also covers a number of other services such as SMTP, Databases, Kafka, etc.

**MyAppSSHAllowlist:** A comma-separated list of domains (without whitespace) that you wish your demo app to be able to connect to via SSH. Note: This will also cover SFTP, SCP and GitLab/GitHub runners.

:::info
Feel free to change these to whatever you like, but for the rest of the documentation for this demo, I'll assume you left the defaults in place. If you're following along and have changed these, don't forget to substitute the domains shown for your domains.
:::

#### OPTIONAL Example VPC Network Configuration

If you wish to customise the network configuration, you can do so here. But it is not necessary for the purposes of this demo. The fields are fairly self explanatory, but I'll briefly describe them now.

**VpcCidr:** The VPC-level CIDR block to deploy in this region.

**PrivateSubnetAZ1:** CIDR for the Private Subnet in Availability Zone 1.

**PrivateSubnetAZ2:** CIDR for the Private Subnet in Availability Zone 2.

**PublicSubnetAZ1:** CIDR for the Public Subnet in Availability Zone 1.

**PublicSubnetAZ2:** CIDR for the Public Subnet in Availability Zone 2.

#### OPTIONAL DiscrimiNAT ADVANCED CONFIGURATION

**InstanceType:** this, by default is set to `t3.small`. This is completely adequate for the purposes of this demo, as it will only require a small instance. In production, we'd suggest a more powerful instance type. Valid values are `t3.small` , `c6i.large` , `c6i.xlarge` , `c6a.large` , `c6a.xlarge` .

:::info
The default of `t3.small` should suffice for light to medium levels of usage. Anything less than 2 CPU cores and 2 GB of RAM is not recommended. For performance testing, faster access to the Internet or for accounts with a large number of instances (ENIs, rather), you may want to choose a machine type with dedicated CPU cores.
:::

Finally, just tick on the checkbox that says _I acknowledge that AWS CloudFormation might create IAM resources with customised names_ then click on **Create stack** and the stack will begin to build.

---

### iv. SMALL WAIT

![CloudFormation Deployment Wait](img/08_cloudformation_05.png)

The stack is now being deployed, it should only take a few minutes, and assuming your IAM permissions are correct, it should complete successfully like so:

![CloudFormation Stack Deployed](img/09_cloudformation_06.png)

:::caution
We will be using AWS Session Manager to connect to demo instances later, and due to a race condition between when the DiscrimiNAT Firewall comes up and when the SSM agent checks its connection, it could be **around 5 minutes** after creation before you're able to connect to them due to the agent back-off time period, so it is advisable to wait a few minutes after creation before continuing.
:::

---

### v. OVERVIEW OF WHAT'S BEEN CREATED

#### v(a). THE ARCHITECTURE OF DiscrimiNAT INSIDE THE VPC

The very short version is DiscrimiNAT replaces your NAT Gateways. If that's all you want to know, feel free to jump to [section v(b)](#vb-the-demo-environment) otherwise, let's take a look.

First you'll see we have the VPC which has both private and public subnets. These subnets are set up with the CIDR ranges given by the stack variables. You'll also see the route tables for the public and private subnets

![VPC Layout](img/10a-vpc.png)

You can see from here that the public subnet route tables go through the Internet Gateway as usual. This is also where the DiscrimiNAT instances sit, much like NAT Gateways.

However the private routing is slightly different, so lets take a look at the private route tables.

![Private Route](img/10a_private_route.png)

As we can see here the route to `0.0.0.0/0` is going out via a VPC endpoint.

![GWLB Endpoint](img/10a_endpoint.png)

And that endpoint is a GatewayLoadBalancer (GWLB) type.

:::info
Due to the way GWLBs and AWS Networking interact, GWLBs require a VPC Endpoint per subnet.
:::

Looking in Load Balancers under EC2 we see that there is only one in this VPC and it's of type `gateway`.

![Gateway Load Balancer](img/10a_gwlb.png)

And looking at the load balancer, it's forwarding to this target group, which contains the DiscrimiNAT instances.

![Target Group](img/10a_target_group.png)

The short version of this is the following:

The private subnets (where your protected instances will live) route via a VPC endpoint to a GWLB which then forwards on to the DiscrimiNAT instances. This means that, unlike other architectures, if a DiscrimiNAT instance becomes unhealthy there will be no break in service while it's replaced. You can read more about this in our [99 Problems but Load Balancing ain't one](/blog/99-problems-but-load-balacing-aint-one/) blog post, or the [Reference Architectures](/docs/discriminat/aws/reference-architectures/) page.

An even shorter version is that functionally, DiscrimiNAT replaces your NAT Gateways.

:::info
You *can* run NAT Gateways along with DiscrimiNAT, but you will be both double NATing and paying for extra services. We haven't found a practical benefit to running both.
:::

#### v(b). The demo environment

Looking at the instances we can see there are 4 instances here.

![Instances](img/10b_instances.png)

The top two are instances of DiscrimiNAT Firewall, but we also have two other instances. These are here to emulate protected instances.

**MySecuredApp-plugleak:** This instance has allowlists applied to it, both for TLS traffic and SSH traffic. We will look into how this is done shortly.

**MyMonitoredApp-plugleak:** This instance has been put into our _see-thru_ mode which allows you to monitor the traffic the instance is generating without affecting the connections in any way.

:::info
Monitoring, or _see-thru_ mode, is exceptionally useful in the discovery phase of your implementation. Unlike a lot of solutions, we allow you to examine the traffic going out, so you can add what's needed, know if needed rules are present, and then switch over to a secured mode with confidence. See our video guide 🎥 on that [here](/docs/discriminat/aws/logs-ref/#building-an-allowlist-from-scratch-video-version).
:::

---

### vi. CONFIGURING AN ALLOWLIST

#### vi(a) LOCATION AND SYNTAX

If we look at the instance called **MySecuredApp-plugleak** we will see it has three Security Groups attached.

![Security Group list](img/11_secgroups_list.png)

DiscrimiNAT checks what domains each instance is allowed to access by seeing what Security Groups are attached to the instance, and then looking at the description of the Outbound Security Group Rules. Let's take a look at one.

![zoomed out view](img/11_secgrp_zoomout.png)

If we look at the highlighted section more closely, we can see that the outbound rule has text in the description field. Specifically some colon-separated values. This is where DiscrimiNAT reads its config from.

![config view](img/11_secgrp_zoomin.png)

We can break this down as follows:

**discriminat:** this tells DiscrimiNAT that this description field should be parsed and the rules found within should be applied to anything attached to this Security Group.

**tls:** this tells DiscrimiNAT that this is for TLS connections rather than SSH.

**api.github.com,icanhazdadjoke.com:** this is a comma-separated list of domains that any instance attached to this Security Group can have access to. Alternatively, this list can be stored in an [SSM Parameter in JSON format](/docs/discriminat/aws/config-ref/#tls-and-ssh-mode).

As you can see, this allows for least-privilege allowlisting, each instance only needs to have the list of domains that **it** needs to access in its allowlist.

We encourage you to create Security Groups as you would normally. Tight in scope and **attached to their respective applications**.

#### vi(b) EFFECTIVE USE OF DiscrimiNAT USING SECURITY GROUPS
This section is to give you a basic grounding on how to configure Security Groups for use with DiscrimiNAT, if you are simply interested in going through the demo, you can carry on to [section vii](#vii-discriminat-in-action).

For an effective use of the DiscrimiNAT Firewall:

- Add destination protocols and [FQDNs](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) to the description field of each **outbound rule**. The format of this text is `DiscrimiNAT:<protocol>:<fqdn>[,<fqdn>]` . Alternatively, the list can be stored in an [SSM Parameter in JSON format](/docs/discriminat/aws/config-ref/#tls-and-ssh-mode).

  - Valid protocols are `ssh` and `tls` only.
  - There can be as many FQDNs as you can fit separated by commas. There cannot be whitespace, though.

- Some examples of what can go in the description field:

  - `DiscrimiNAT:TLS:api.foo.example.com,downloads.example.net`
  - `DiscrimiNAT:SSH:sftp.txs.example.org,ssh.github.com`

- All DiscrimiNAT rules must be under `Outbound rules`. Inbound Rules are not read.

- Under `Type`, choose any TCP protocol type and **specify exactly one port number** in `Port range`. Multiple ports, ranges, other protocols, and so on are **not** supported.

  - For your typical **HTTPS** outbound connection, the port number would be `443`.
  - A typical **SFTP** connection has the port number of `22`.

- `Destination` must be set to the narrowest IP block you can think of. Now if you don't have anything narrower than `0.0.0.0/0` that is absolutely fine! The firewall takes care of validating the destination IP address of actual packets against the given domain names' DNS etc., but the Outbound Rule at the AWS networking and security level must allow the packet to leave the EC2 Instance. **`0.0.0.0/0` is a safe choice with the DiscrimiNAT Firewall in the way.**

- That's it! Although you may want to check the [full reference](/docs/discriminat/aws/config-ref/) for more possibilities.

---

### vii. DiscrimiNAT IN ACTION

Now we're going to connect to one of our instances using AWS Session Manager. In the AWS EC2 console, find the instance called **MySecuredApp-plugleak** and click on its name, then click on **Connect**.

:::tip
It is advisable to **wait for over 5 minutes** after stack creation to do this, as the SSM agent might not have had the time to reconnect. The instances come up at the same time as the DiscrimiNAT instances in this CloudFormation stack and there can be a race condition as described earlier.
:::

On the next page, ensure you have chosen to connect via **Session Manager**. If this is disabled, wait for a few minutes for the agent to reconnect.

![SSM Connect](img/12_ssm_connect.png)

Now we're connected, let's test `curl`ing to an FQDN we have configured in the allowlist. Then let's test an FQDN we haven't configured in the allowlist.

First run `curl https://istio.io` (an FQDN not in our allowlist). We will immediately see a connection reset. This is because the rules attached to this machine do not include this FQDN.

:::tip
We give a connection reset rather than a hang as it gives fast feedback to developers. A hang (drop & timeout), especially if connecting to multiple domains, or the same domain multiple times, can waste developer time or stall applications.
:::

Now run `curl https://icanhazdadjoke.com` (an FQDN in our allowlist) and we'll see a dad joke appear in the command line because this FQDN is allowed.

:::info
Chaser Systems are not responsible for the quality of dad joke you are given. Dad jokes are read at your own risk.
:::

![Command Output](img/12_curl_view.png)

Let's take the view that our organisation has decided they need this machine to be able to connect to **istio.io**. It's been agreed by everyone, so let's add **istio.io** to our Security Group Rule Description to add it to DiscrimiNAT's config.

![Add istio to security group](img/12_add_istio.png)

We will now need to wait around a minute for the rule to be picked up.

:::info
DiscrimiNAT polls the AWS API at 1-3 times a minute, and as there is no global store, each instance picks up the config individually, so new rules usually take around a minute to go live.

The lack of a global store means no databases are required and makes the machines stateless and easily replaceable.
:::

Now we will try `curl https://istio.io` and we'll get a very large HTML response.

![istio now works](img/12_istio_works.png)

As you can see, DiscrimiNAT is simple to configure and does exactly what it's supposed to do.

However one thing we haven't shown you yet is something most of our competitors _can't_ do. And that is: Combat **SNI Spoofing**.

:::info
SNI Spoofing put simply is when an attacker attempts to make a connection by claiming they're connecting to a specific DNS host in [TLS SNI](https://www.cloudflare.com/en-gb/learning/ssl/what-is-sni/) but are actually using an IP address completely unrelated to that domain name.

A [lot of firewalls](/discriminat/comparison/aws-network-firewall/) just check to see if the TLS SNI contains the correct domain name, without checking whether the IP is actually valid for that domain name. The other competitors that *do* check the IP is valid are prone to false positives, and the destination only works *some* of the time.

DiscrimiNAT combats this using our proprietary **Wormhole DNS** technology.
:::

One of the simplest ways to spoof SNI is to edit the *hosts* file, so let's do that.

* Run `sudo vi /etc/hosts`
* Once the file is open press the **o** key.
* insert the following line `8.8.8.8        istio.io`
* press **escape** then the following keys **:wq** then **return**

Now, when you try to `curl https://istio.io`, it will use the IP address in the *hosts* file (which is a Google IP) instead of doing a DNS query. [Lesser firewalls would let this through](/discriminat/comparison/aws-network-firewall/#litmus-test), but DiscrimiNAT won't.

![You Shall Not Pass!](img/12_sni_proof.png)

As you can see, DiscrimiNAT has blocked the traffic instantly. It will even report on this on the logs. Talking of which...

---

### viii. HOW DiscrimiNAT LOGS WORK

DiscrimiNAT has no UI of its own, instead it ties into your cloud service, so in this case we'll be looking at CloudWatch.

:::tip
DiscrimiNAT can send its logs to wherever you need, and can support most Linux-based logging agents such as Splunk, Rapid7, etc.
:::

In CloudWatch, browse to **Logs -> Log Management -> DiscrimiNAT -> flow**. The flow log shows all hosts going through the DiscrimiNAT instances and whether the traffic was allowed out or not, along with some other information. Let's search in here specifically for **istio**.

![Cloudwatch Search Results](img/13_istio_search.png)

You should see at least 3 results here, one where you `curl`ed at first and it was disallowed, one after the rule was in place and it worked, and one where we tried to SNI spoof. Let's look at these one by one.

![Istio wasn't allowed](img/13_istio_disallow.png)

We can see here that this was an attempt to connect to **istio.io** that was **disallowed** and the reason is because there were no matching rules found.

Now let's have a look at the working one.

![Istio was allowed through](img/13_istio_allowed.png)

We can see here that this was an attempt to connect to **istio.io** that was **allowed** and the reason is because there was a matching rule in Security Group **sg-0daabff1c073ac1f7** that was attached to the instance.

So let's take a look at when we tried to trick the firewall into letting spurious traffic through.

![No Spoofing Allowed](img/13_istio_spoofed.png)

We can see here that this was an attempt to connect to **istio.io** that was **disallowed** and the reason is because there was **spoofing detected**. As you can imagine, this is something your security team would be very interested in as it indicates an exfiltration or a C2 attempt.

Let’s now look at the configuration logs. Browse to **CloudWatch -> Logs -> Log Management -> DiscrimiNAT -> config**. Here we can see any config changes and errors. For example here we can see our *istio* rule being picked up by both DiscrimiNAT instances.

![Config logs](img/13_config_log.png)

This is useful not only for fault diagnosis, but also for compliance reasons as any changes to the allowlists are logged.

:::tip
As you can see, all our logs are JSON and therefore you can query them and pull information out easily. You can even do it on the Cloud Shell CLI using a combination of the **aws** command and **jq**. For an example, see the recipe [here](/docs/discriminat/aws/logs-ref/#building-an-allowlist-from-scratch-video-version).
:::

---

### ix. MONITORING (see-thru) MODE

One of the toughest parts of adopting egress filtering is the initial phase. Planning, knowing what to actually put in your allowlists, trying to make sure they're not too open, while making sure your app and the underlying OS have everything they need to function correctly. Our monitoring mode is designed specifically to help with this and aid with the adoption.

We have an instance configured in _see-thru_ in our demo environment, so let's look at the Security Groups attached to the instance called **MyMonitoredApp-plugleak**.

![Security Groups attached to the monitored instance](img/14_sec_groups.png)

As we can see here, one of the groups is called **MyApp-Monitored-Egress-plugleak**, lets take a look at this, and the description on the outbound rule.

![The configuration for monitoring mode](img/14_sec_group_config.png)

So we can see here that we have _discriminat_ to indicate the DiscrimiNAT should read this config, followed by _see-thru_ which tells DiscrimiNAT that the instances attached to this Security Group are in monitoring mode, followed by _2026-12-31_ which is the date when the monitoring mode will expire.

:::caution
When monitoring mode expires, the rule is disregarded and the traffic goes back to being blocked.
:::

Let's connect to the monitored box using SSM (using the same method as the other instance) and run the following commands.

```
curl --head https://yahoo.com
curl --head https://graph.facebook.com
curl --head https://apple.com
curl --head https://youtube.com
```

You'll find they all work. It's as if DiscrimiNAT isn't there. So let's take a look at the logs. Navigate to **CloudWatch -> Logs -> Log Management -> DiscrimiNAT -> flow**, then search for **yahoo.com**.

![log results](img/14_yahoo.png)

Let's expand that log entry.

![The log entry for yahoo.com](img/14_yahoo_log_entry.png)

You may notice that there are extra fields in this log entry compared to the others we've looked at. These are **see_thru_exerted**, **see_thru_gid**, and **see_thru_days_remaining**. This is an easy way to tell that this log entry comes from a monitored group. Let's go through what these mean.

**see_thru_gid**: this tells you which Security Group this log entry has come from. So if you have multiple apps, all in monitor mode, you can still tell which is which.

**see_thru_days_remaining**: How many days there are until the monitoring shuts off and the traffic starts being blocked as normal. _(Note, we do not use 0. The last day is 1 and the first non-working day is -1.)_

**see_thru_exerted**: Did the object (eg. an instance or a lambda) needed to have the monitoring mode on to be able to access this host? For example, if there is another Security Group attached to it allowing it through, then this value would be `false`. If this has been set to `true` then this traffic would not have been allowed through under normal circumstances.

:::tip
Using an `aws logs` command, you can pull through all the hosts that the machine connects to, and even more than that, using **see_thru_exerted**, you can choose to see which hosts haven't been allowed through via other Security Groups yet. For a fully worked out example, see the recipe [here](/docs/discriminat/aws/logs-ref/#building-an-allowlist-from-scratch-video-version).
:::

### x. TEARDOWN

Teardown is just as simple as deleting the CloudFormation stack. Navigate to **CloudFormation** in the AWS console, find the stack named **plugleak** and delete it.

It will then tear down all the resources in the demo environment.

---

### xi. NEXT STEPS

Hopefully now you've seen what DiscrimiNAT can do for your organisation, and how easy it is to configure.

<CTA link="/demo/">Get a Demo</CTA>

<CTA link="https://registry.terraform.io/modules/ChaserSystems/discriminat-gwlb/aws/latest">Explore the Terraform module</CTA>

:::tip
DiscrimiNAT has an ever-growing feature set. If there is a feature you think is missing and that is blocking your adoption, please get in touch. It may already be on our roadmap. If it isn't and we think it's a good idea, it can be added to our roadmap.
:::

---

<CTA link="/docs/discriminat/aws/troubleshooting/">Troubleshooting</CTA>

<CTA link="/docs/discriminat/aws/logs-ref/#recipes">Discovering FQDNs Recipe</CTA>
