Traffic Proxy
This chapter covers some aspects related to the
service traffic-proxy <id> tool, which allows you to configure one or
multiple SSL Proxy instances in OSDx.
The traffic-proxy service can be used to intercept and proxy SSL traffic. This feature can be used to play the role of man-in-the-middle, allowing the inspection of encrypted traffic.
Configuration
Each instance can be bound to a different local port, where the incoming traffic, originated on the client side, is received, mangled and diverted to the server. Upon receiving the packets back from the server, the traffic proxy re-encrypts and sends them to their original destination.
The syntax to create a service traffic-proxy <id> instance is specified below:
set service traffic-proxy <NAME> [ ... ]
Where <NAME> represents the name of the instance.
When you configure a new instance, you need to specify, at least, the following parameters:
mode: SSL proxy operating mode. It accepts the following values:httporhttps: to decode plain or secure HTTP connections.pop3,pop3s,smtporsmtps: to decode plain or secure POP3 or SMTP connections.sslortcp: not to decode connections, but to treat the decrypted content as an opaque stream of bytes.autossl: not to decode connections, but to work as protocol-independent STARTTLS.
x509 ca-certandx509 ca-key: path to PEM CA certificate and key.port: local port that will be used to intercept traffic.
Warning
Make sure to select the appropriate mode. If you need to decrypt multiple
kinds of protocols, you can always configure several instances. Take into
account that if, for example, you configure https or ssl mode and the
service intercepts plain http traffic, it will reject the connection
sending an abort response.
By default, the generated traffic is not VRF-aware, which means that the main
VRF will be used. Instances can also be configured to use a specific VRF,
via the local-vrf field.
Intercepting and analyzing traffic
In order to intercept traffic, you need to create a traffic policy <txt>
and configure it to proxy the traffic to the aforementioned local port. You
should then attach that policy to an interface or configure it globally. Further
information about traffic policies can be found at the
Traffic Policy chapter.
Each instance can also be bound to a traffic queue <txt>. Although this
is not required, it’s very useful to configure a traffic queue to be able to
analyze the decrypted traffic; for example, using a firewall instance. Further
information about traffic queues can be found at the
Traffic Queue chapter.
Simple example
Imagine that you want to configure the traffic-proxy service to intercept and decrypt SSL traffic destined to another server; e.g., HTTPs traffic.
Preparing the device
First, we need to have, at least, a valid x509 certificate and private key. We can generate them using an OSDx device:
Example:
admin@DUT0$ pki generate private-key running://test.key rsa
Generated private key at 'running://test.key'
admin@DUT0$ pki generate certificate running://test.crt x509 private-key running://test.key days 3650 subject "/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*."
Generated X.509 certificate at 'running://test.crt'
Configuration commands
Now, we can create a new service instance and bind it to a local port.
Example:
set service traffic-proxy TRAFFIC_PROXY mode https
set service traffic-proxy TRAFFIC_PROXY port 3128
set service traffic-proxy TRAFFIC_PROXY x509 ca-cert running://test.crt
set service traffic-proxy TRAFFIC_PROXY x509 ca-key running://test.key
Then, we need to create and attach a traffic policy to intercept the traffic:
set traffic selector TCP_TRAFFIC rule 1 protocol tcp
set traffic selector TCP_TRAFFIC rule 1 destination port 80,443
set traffic policy TPROXY rule 1 selector TCP_TRAFFIC
set traffic policy TPROXY rule 1 action proxy tcp 3128
set interfaces eth0 traffic policy in TPROXY
set interfaces eth1 traffic policy in TPROXY
We have created a new traffic selector to match all TCP traffic with destination
port 80 or 443 (normally these ports are used for HTTP and HTTPs,
respectively). Then, we have assigned that traffic selector to a new traffic
policy that proxies the traffic to our local port. Finally, we have attached
the traffic policy to the incoming hook of two physical interfaces: eth0 and
eth1.
Monitoring commands
We can run the service traffic-proxy TRAFFIC_PROXY show connections
command to display the latest connections that were intercepted.
Example:
admin@DUT0$ service traffic-proxy TRAFFIC_PROXY show connections
2023-09-21 21:08:09 UTC CONN: ssl 10.0.0.2 1234 192.168.1.2 443 sni:- names:Server sproto:TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 dproto:TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 origcrt:188178F6F7097DC76C12FB0330D1629EBE357D78 usedcrt:D79EB0BA11576DB6233725C8E3A7807642F0F31F user:-
We can see that an SSL connection started in 10.0.0.2:1234 and destined to server 192.168.1.2:443 was intercepted at 2023-09-21 21:08:09. There’s more information like the TLS version that was used in both connections, the encryption algorithms, etc.
We can also configure the
set service traffic-proxy TRAFFIC_PROXY logging content option and then run the
service traffic-proxy TRAFFIC_PROXY show content command to display
information about the decrypted session.
Example:
admin@DUT0$ service traffic-proxy TRAFFIC_PROXY show content
2023-09-21 21:08:10 UTC [10.0.0.2]:1234 -> [192.168.1.2]:443 (18):
Hello from client
2023-09-21 21:08:10 UTC [192.168.1.2]:443 -> [10.0.0.2]:1234 (18):
Hello from server
2023-09-21 21:08:10 UTC [10.0.0.2]:1234 -> [192.168.1.2]:443 (EOF)
Block
The traffic-proxy service can create block pages for connections that have been marked with a connmark by an external service or utility. The traffic-proxy intercepts these marked connections and displays a customizable HTML page, informing the user that the connection has been blocked.
This provides a more informative experience for end users than a silent drop, since they receive a clear explanation of why their connection was denied.
Block template
The block page is generated from an HTML template file. The template supports
placeholders that use the {{ variable }} syntax, which replaces standard values with
configured variables when the page is shown.
If no custom template file is configured, a default template is used.
To configure a custom template file and its variables:
set service traffic-proxy <NAME> block template file <path>
set service traffic-proxy <NAME> block template variable <var> value <val>
Where <path> is the path to the HTML template file and <var>/<val>
are the variable name and value pairs used to populate these template
placeholders.
Note
Variable names must start with a letter and can only contain letters,
numbers and underscores (e.g., REASON, carrier_name). Variable
values can contain spaces.
Block rules
Block rules define the marked connections the traffic-proxy must intercept. Each rule matches connections based on their connmark value.
set service traffic-proxy <NAME> block rule <ID> connmark mark <mark>
set service traffic-proxy <NAME> block rule <ID> connmark vrf-mark <vrf>
set service traffic-proxy <NAME> block rule <ID> connmark extra-mark 1 value <mark>
Where <ID> is a numeric identifier for the rule and <mark> is the
connmark value set on the blocked connections.
Note
Only one connmark type can be configured per rule: either mark,
vrf-mark or extra-mark 1.
Each rule can also define its own variable overrides, which take precedence over variables at template level:
set service traffic-proxy <NAME> block rule <ID> set variable <var> value <val>
This allows different block rules to customize the content of a block page. For example, different rules could display different messages depending on the type of threat detected by an external service or utility.
Monitoring commands
To use the block monitoring commands (show connections blocked
and monitor connections blocked), the logging connection option must
be enabled on the traffic-proxy instance:
set service traffic-proxy <NAME> logging connection
The following operational commands are available to monitor blocked activity:
service traffic-proxy <NAME> show stats: displays general statistics, including a blocked row with total counts of blocked connections.service traffic-proxy <NAME> show stats detailed: displays a detailed breakdown of statistics per block rule. A JSON variant is also available withservice traffic-proxy <NAME> show stats detailed json.service traffic-proxy <NAME> show connections blocked: displays the historical log of blocked connections. Requireslogging connectionfor activation purposes.service traffic-proxy <NAME> monitor connections blocked: displays blocked connections in real time. Requireslogging connectionfor activation purposes.
Example of show stats:
admin@osdx$ service traffic-proxy TRAFFIC_PROXY show stats
Statistics for instance "TRAFFIC_PROXY":
-----------------------------
name packets bytes
-----------------------------
intercepted 117 17304
queue - orig 0 0
queue - reply 0 0
error 0 0
blocked 113 17080
Example of show stats detailed:
admin@osdx$ service traffic-proxy TRAFFIC_PROXY show stats detailed
Statistics for instance "TRAFFIC_PROXY":
-----------------------------
name packets bytes
-----------------------------
intercepted 117 17304
queue - orig 0 0
queue - reply 0 0
error 0 0
blocked 113 17080
Blocking statistics for the "TRAFFIC_PROXY" instance:
---------------------
rule packets bytes
---------------------
1 113 17080
---------------------
Total 113 17080
When a connection is blocked, “traffic-proxy” issues the rendered block page
with an HTTP 200 response for navigation requests. For embedded resources,
an HTTP 403 response is returned instead.
Customizing the block page
The block page the user sees can be fully customized using an HTML template file with placeholders. The following example shows how to create a template and configure the traffic-proxy to use it.
First, create an HTML template file (e.g., running://block.html) with
placeholders:
<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
<h1>{{ title }}</h1>
<p>{{ message }}</p>
<p>Reference: {{ reference_code }}</p>
</body>
</html>
Then, configure the traffic-proxy instance with the block template, default variables and a rule matching the connmark:
set service traffic-proxy TPROXY block template file running://block.html
set service traffic-proxy TPROXY block template variable title value "Access Denied"
set service traffic-proxy TPROXY block template variable message value "This connection has been blocked."
set service traffic-proxy TPROXY block template variable reference_code value "REF-000"
set service traffic-proxy TPROXY block rule 1 connmark mark 100
set service traffic-proxy TPROXY block rule 1 set variable message value "Blocked by security policy."
set service traffic-proxy TPROXY block rule 1 set variable reference_code value "POL-100"
set service traffic-proxy TPROXY logging connection
In this example, when rule 1 matches connmark 100, the message and
reference_code variables are overridden with rule-specific values, while
title keeps its default value.
More examples of block page customization are available in the Traffic-Proxy Basic examples page.
Firewall blocking
This example shows how to use the Firewall
to detect and block specific HTTP/s traffic (e.g., connections to
webserver.com) and have the traffic-proxy generate a block page.
The firewall uses the block keyword in a rule together with the capture
block feature to accept the packet and mark the connection with a connmark.
The traffic-proxy then intercepts connections with that mark and creates the
block page.
First, create a firewall rules file (e.g., running://block.rules):
drop tls any any -> any any (msg:"Blocked traffic to webserver.com"; block; tls.sni; content:"webserver.com"; sid:1; rev:1;)
Note
The example above uses a TLS rule (tls.sni), but rules for
plain HTTP traffic can also be used. For example:
drop http any any -> any 80 (msg:"Block HTTP"; block; http.host; content:"webserver.com"; sid:2; rev:1;)
Then, configure the traffic infrastructure. A traffic queue is created for
the firewall, and a traffic selector ensures that already-marked connections
(connmark 1000) are not enqueued again (bypass):
set traffic queue Q elements 0
set traffic selector HTTPS_FIREWALL rule 1 destination port-group PORTS
set traffic selector HTTPS_FIREWALL rule 1 not connmark 1000
set traffic selector HTTPS_FIREWALL rule 1 protocol tcp
set traffic selector HTTPS_FIREWALL rule 2 not connmark 1000
set traffic selector HTTPS_FIREWALL rule 2 protocol tcp
set traffic selector HTTPS_FIREWALL rule 2 source port-group PORTS
set traffic policy HTTPS_FIREWALL rule 1 action enqueue Q
set traffic policy HTTPS_FIREWALL rule 1 selector HTTPS_FIREWALL
Configure the firewall instance with the capture block action:
set service firewall FWL mode inline queue Q
set service firewall FWL ruleset file running://block.rules
set service firewall FWL logging outputs fast
set service firewall FWL tls-detection detection-ports 443
set service firewall FWL bypass action block set connmark mark 1000
Lastly, configure the traffic-proxy block rule to match the connmark set by the firewall:
set service traffic-proxy TRAFFIC_PROXY block rule 1 connmark mark 1000
Tip
The firewall also supports extra-mark 1 and vrf-mark for the
capture block action.
Further information about the firewall service and the capture block feature can be found at the Firewall chapter. More examples of firewall blocking are available in the Traffic-Proxy Firewall examples page.
Blocking with app-id
This example shows how to use the application identification system
(app-detect) to detect and block traffic based on the identified
application, without using a firewall instance.
A custom app-id dictionary is configured to identify connections to
webserver.com. A traffic policy then sets a connmark on the detected
connections, and the traffic-proxy serves a block page for them.
Configure the app-detect dictionary to identify the target application:
set system conntrack app-detect dictionary 1 custom app-id 1 fqdn webserver.com
set system conntrack app-detect ssl-host
set system conntrack app-detect http-host
Create a traffic selector that matches detected applications and a traffic policy that sets the connmark:
set traffic selector BLOCKED_APP rule 1 app-detect app-id custom -1
set traffic selector BLOCKED_APP rule 1 app-detect state detected
set traffic policy BLOCKED_APP rule 1 selector BLOCKED_APP
set traffic policy BLOCKED_APP rule 1 set connmark 1000
Link the traffic policy to the interface:
set interfaces ethernet eth1 traffic policy in BLOCKED_APP priority very-high
Finally, configure the traffic-proxy block rule so that it matches the connmark:
set service traffic-proxy TRAFFIC_PROXY block rule 1 connmark mark 1000
Tip
App-id dictionaries can also be configured using XML dictionary
files with set system conntrack app-detect dictionary <priority> filename <path>.
Further information about the application identification system can be found under the Conntrack chapter. More examples of app-id blocking are available in the Traffic-Proxy App Id examples page.