netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Motiejus Jakštys" <desired.mta@gmail.com>
To: netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org,
	linux-doc@vger.kernel.org
Cc: trivial@kernel.org, "Motiejus Jakštys" <desired.mta@gmail.com>
Subject: [PATCH] Documentation: tproxy: more gentle intro
Date: Tue, 27 Oct 2020 14:06:20 +0200	[thread overview]
Message-ID: <20201027120620.476066-1-desired.mta@gmail.com> (raw)

Clarify tproxy odcumentation, so it's easier to read/understand without
a-priori in-kernel transparent proxying knowledge:

- re-shuffle the sections, as the "router" section is easier to
  understand when getting started.
- add a link to HAProxy page. This is where I learned most about what
  tproxy is, so I believe it is reasonable to include.
- removed a reference to linux 2.2.

Plus Sphinx formatting/cosmetic changes.

Signed-off-by: Motiejus Jakštys <desired.mta@gmail.com>
---
 Documentation/networking/tproxy.rst | 155 +++++++++++++++-------------
 1 file changed, 83 insertions(+), 72 deletions(-)

diff --git a/Documentation/networking/tproxy.rst b/Documentation/networking/tproxy.rst
index 00dc3a1a66b4..0f43159046fb 100644
--- a/Documentation/networking/tproxy.rst
+++ b/Documentation/networking/tproxy.rst
@@ -1,42 +1,77 @@
 .. SPDX-License-Identifier: GPL-2.0
 
-=========================
-Transparent proxy support
-=========================
+==========================
+Transparent proxy (TPROXY)
+==========================
 
-This feature adds Linux 2.2-like transparent proxy support to current kernels.
-To use it, enable the socket match and the TPROXY target in your kernel config.
-You will need policy routing too, so be sure to enable that as well.
+TPROXY enables forwarding and intercepting packets that were destined
+for other destination IPs, without using NAT chain or REDIRECT targets.
 
-From Linux 4.18 transparent proxy support is also available in nf_tables.
+Redirecting traffic
+===================
 
-1. Making non-local sockets work
-================================
+TPROXY is often used to "intercept" traffic on a router. This is usually done
+with the iptables ``REDIRECT`` target, however, there are serious limitations:
+it modifies the packets to change the destination address -- which might not be
+acceptable in certain situations, e.g.:
+- UDP: you won't be able to find out the original destination address.
+- TCP: getting the original destination address is racy.
 
-The idea is that you identify packets with destination address matching a local
-socket on your box, set the packet mark to a certain value::
+The ``TPROXY`` target provides similar functionality without relying on NAT.
+Simply add rules like this to the iptables ruleset above:
 
-    # iptables -t mangle -N DIVERT
-    # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
-    # iptables -t mangle -A DIVERT -j MARK --set-mark 1
-    # iptables -t mangle -A DIVERT -j ACCEPT
+.. code-block:: sh
 
-Alternatively you can do this in nft with the following commands::
+    iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
+      --tproxy-mark 0x1/0x1 --on-port 50080
+
+Or the following rule to nft:
+
+.. code-block:: sh
+
+    nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept
+
+Note that for this to work you'll have to modify the proxy to enable
+(``SOL_IP``, ``IP_TRANSPARENT``) for the listening socket.
+
+As an example implementation, tcprdr is available here:
+https://git.breakpoint.cc/cgit/fw/tcprdr.git/
+This tool is written by Florian Westphal and it was used for testing during the
+nf_tables implementation.
+
+Intercepting non-local packets
+==============================
+
+To identify packets with destination address matching a local socket on your
+box, set the packet mark to a certain value:
+
+.. code-block:: sh
+
+    iptables -t mangle -N DIVERT
+    iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
+    iptables -t mangle -A DIVERT -j MARK --set-mark 1
+    iptables -t mangle -A DIVERT -j ACCEPT
+
+Alternatively in nft:
+
+.. code-block:: sh
+
+    nft add table filter
+    nft add chain filter divert "{ type filter hook prerouting priority -150; }"
+    nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
 
-    # nft add table filter
-    # nft add chain filter divert "{ type filter hook prerouting priority -150; }"
-    # nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
+Then match on that value using policy routing to deliver those packets locally:
 
-And then match on that value using policy routing to have those packets
-delivered locally::
+.. code-block:: sh
 
-    # ip rule add fwmark 1 lookup 100
-    # ip route add local 0.0.0.0/0 dev lo table 100
+    ip rule add fwmark 1 lookup 100
+    ip route add local 0.0.0.0/0 dev lo table 100
 
-Because of certain restrictions in the IPv4 routing output code you'll have to
-modify your application to allow it to send datagrams _from_ non-local IP
-addresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
-option before calling bind::
+Because of certain restrictions in the IPv4 routing application will need to be
+modified to allow it to send datagrams *from* non-local IP addresses. Enable
+the ``SOL_IP``, ``IP_TRANSPARENT`` socket options before calling ``bind``:
+
+.. code-block:: c
 
     fd = socket(AF_INET, SOCK_STREAM, 0);
     /* - 8< -*/
@@ -51,59 +86,35 @@ option before calling bind::
 A trivial patch for netcat is available here:
 http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
 
+Kernel configuration
+====================
 
-2. Redirecting traffic
-======================
-
-Transparent proxying often involves "intercepting" traffic on a router. This is
-usually done with the iptables REDIRECT target; however, there are serious
-limitations of that method. One of the major issues is that it actually
-modifies the packets to change the destination address -- which might not be
-acceptable in certain situations. (Think of proxying UDP for example: you won't
-be able to find out the original destination address. Even in case of TCP
-getting the original destination address is racy.)
-
-The 'TPROXY' target provides similar functionality without relying on NAT. Simply
-add rules like this to the iptables ruleset above::
-
-    # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
-      --tproxy-mark 0x1/0x1 --on-port 50080
-
-Or the following rule to nft:
-
-# nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept
-
-Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
-IP_TRANSPARENT) for the listening socket.
+To use tproxy you'll need to have the following modules compiled for iptables:
 
-As an example implementation, tcprdr is available here:
-https://git.breakpoint.cc/cgit/fw/tcprdr.git/
-This tool is written by Florian Westphal and it was used for testing during the
-nf_tables implementation.
+ - ``NETFILTER_XT_MATCH_SOCKET``
+ - ``NETFILTER_XT_TARGET_TPROXY``
 
-3. Iptables and nf_tables extensions
-====================================
+For nf_tables:
 
-To use tproxy you'll need to have the following modules compiled for iptables:
+ - ``NFT_TPROXY``
+ - ``NFT_SOCKET``
 
- - NETFILTER_XT_MATCH_SOCKET
- - NETFILTER_XT_TARGET_TPROXY
+Application support
+======================
 
-Or the floowing modules for nf_tables:
+Squid
+-----
 
- - NFT_SOCKET
- - NFT_TPROXY
+Squid 3.1+ has built-in support for TPROXY. To use it, pass
+``--enable-linux-netfilter`` to configure and set the 'tproxy' option on the
+HTTP listener you redirect traffic to with the TPROXY iptables target.
 
-4. Application support
-======================
+For more information please consult the `Squid wiki`_.
 
-4.1. Squid
-----------
+HAproxy
+-------
 
-Squid 3.HEAD has support built-in. To use it, pass
-'--enable-linux-netfilter' to configure and set the 'tproxy' option on
-the HTTP listener you redirect traffic to with the TPROXY iptables
-target.
+Documented in `Haproxy blog`_.
 
-For more information please consult the following page on the Squid
-wiki: http://wiki.squid-cache.org/Features/Tproxy4
+.. _`Squid wiki`: http://wiki.squid-cache.org/Features/Tproxy4
+.. _`HAproxy blog`: https://www.haproxy.com/blog/howto-transparent-proxying-and-binding-with-haproxy-and-aloha-load-balancer/

base-commit: 4525c8781ec0701ce824e8bd379ae1b129e26568
-- 
2.28.0


             reply	other threads:[~2020-10-27 12:06 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-27 12:06 Motiejus Jakštys [this message]
2020-10-30 22:52 ` [PATCH] Documentation: tproxy: more gentle intro Jakub Kicinski
  -- strict thread matches above, loose matches on Subject: below --
2020-11-05 10:13 Motiejus Jakštys

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201027120620.476066-1-desired.mta@gmail.com \
    --to=desired.mta@gmail.com \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=trivial@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).