============= Traffic Proxy ============= .. sidebar:: Contents .. contents:: :depth: 2 :local: This chapter covers some aspects related to the :osdx:cfg:`service traffic-proxy *` 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. This is the syntax to create a :osdx:cfg:`service traffic-proxy *` instance: .. code-block:: none set service traffic-proxy [ ... ] Where ```` 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: * ``http`` or ``https``: to decode plain or secure HTTP connections. * ``pop3``, ``pop3s``, ``smtp`` or ``smtps``: to decode plain or secure POP3 or SMTP connections. * ``ssl`` or ``tcp``: to not decode connections, but treat the decrypted content as an opaque stream of bytes. * ``autossl``: to not decode connections, but work as protocol-independent STARTTLS. * ``x509 ca-cert`` and ``x509 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 you configure, for example, ``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. The instances can also be configured to use a **specific VRF**, using the ``local-vrf`` field. Intercepting and analyzing traffic ================================== In order to intercept traffic, you need to create a :osdx:cfg:`traffic policy *` and configure it to proxy the traffic to the aforementioned local port. Then, you should attach that policy to an interface or configure it globally. Further information about traffic policies can be found at the :doc:`/articles/routing/traffic/policy/index` chapter. Each instance can also be bound to a :osdx:cfg:`traffic queue *`. 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 :doc:`/articles/routing/traffic/queue/index` 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:* .. code-block:: none 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:* .. code-block:: none 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: .. code-block:: none 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 equals to 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 command ``service traffic-proxy TRAFFIC_PROXY show connections`` to display the latest connections that were intercepted. *Example:* .. code-block:: none 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 a SSL connection that was started in 10.0.0.2:1234 and destined to the 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 option ``set service traffic-proxy TRAFFIC_PROXY logging content`` and then run the command ``service traffic-proxy TRAFFIC_PROXY show content`` to display information about the decrypted session. *Example:* .. code-block:: none 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 serve **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 serves a customizable HTML page to the user, informing them that the connection has been blocked. This provides a more informative experience for end users compared to a silent drop, since they receive a clear notification explaining why their connection was denied. Block template -------------- The block page is rendered from an HTML template file. The template supports placeholders using the ``{{ variable }}`` syntax, which are replaced with the configured variable values when the page is served. If no custom template file is configured, a default template is used. To configure a custom template file and its variables: .. code-block:: none set service traffic-proxy block template file set service traffic-proxy block template variable value Where ```` is the path to the HTML template file and ````/```` are the variable name and value pairs used to populate the 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 which marked connections should be intercepted by the traffic-proxy. Each rule matches connections based on their connmark value. .. code-block:: none set service traffic-proxy block rule connmark mark set service traffic-proxy block rule connmark vrf-mark set service traffic-proxy block rule connmark extra-mark 1 value Where ```` is a numeric identifier for the rule and ```` 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 the template-level variables: .. code-block:: none set service traffic-proxy block rule set variable value This allows different block rules to customize the block page content. For example, different rules could display different messages depending on the type of threat detected by an external service or utility. Monitoring commands ------------------- In order 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: .. code-block:: none set service traffic-proxy logging connection The following operational commands are available to monitor block activity: * ``service traffic-proxy show stats``: displays general statistics, including a **blocked** row with total counts of blocked connections. * ``service traffic-proxy show stats detailed``: displays a detailed breakdown of statistics per block rule. A JSON variant is also available with ``service traffic-proxy show stats detailed json``. * ``service traffic-proxy show connections blocked``: displays the historical log of blocked connections. Requires ``logging connection`` to be enabled. * ``service traffic-proxy monitor connections blocked``: displays blocked connections in real time. Requires ``logging connection`` to be enabled. *Example of* ``show stats``: .. code-block:: none 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``: .. code-block:: none 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 instance "TRAFFIC_PROXY": --------------------- rule packets bytes --------------------- 1 113 17080 --------------------- Total 113 17080 When a connection is blocked, the traffic-proxy serves 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 served to the user 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: .. code-block:: html {{ title }}

{{ title }}

{{ message }}

Reference: {{ reference_code }}

Then, configure the traffic-proxy instance with the block template, default variables and a rule matching the connmark: .. code-block:: none 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 :doc:`/examples/service/traffic-proxy/block/basic` examples page. Blocking with firewall ---------------------- This example shows how to use the :doc:`/articles/local_services/firewall/index` to detect and block specific HTTP/s traffic (e.g., connections to ``webserver.com``) and have the traffic-proxy serve 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 serves 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): .. code-block:: none 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: .. code-block:: none 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 Finally, configure the traffic-proxy block rule to match the connmark set by the firewall: .. code-block:: none 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 :doc:`/articles/local_services/firewall/index` chapter. More examples of blocking with firewall are available in the Traffic-Proxy :doc:`/examples/service/traffic-proxy/block/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: .. code-block:: none 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: .. code-block:: none 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 Attach the traffic policy to the interface: .. code-block:: none set interfaces ethernet eth1 traffic policy in BLOCKED_APP priority very-high Finally, configure the traffic-proxy block rule to match the connmark: .. code-block:: none 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 filename ``. Further information about the application identification system can be found at the :doc:`/articles/system/conntrack/index` chapter. More examples of blocking with app-id are available in the Traffic-Proxy :doc:`/examples/service/traffic-proxy/block/appid` examples page. .. osdx:cmdtree:: cfg :maxdepth: 6 service traffic-proxy .. osdx:cmdtree:: op :maxdepth: 5 service traffic-proxy