How can I configure bidirectional protocol-independent port forwarding?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0















I am attempting to solve the following problem:



I have a system which I will henceforth refer to as "Local" that hosts a service on port 80 and port 443, and depends on sending outgoing requests on port 25. It also hosts a separate service on port 22.

I have a system which I will call "Global" that has a globally accessible static IP address and has DNS configured for it, and is capable of accepting incoming requests on port 80, 443, 25, and 222.



Local and Global are connected (via a VPN interface, if it matters) on the reserved subnet 10.0.0.0/24



I want all incoming requests on Global ports 80 and 443 to redirect to Local on ports 80 and 443 respectively.
I also want incoming requests on Global port 222 to redirect to Local on port 22 (yes, that is an intentionally different port).
In addition, I want all outgoing requests to port 25 from Local to redirect to Global on port 25.



Both Local and Global are modern linux systems with apt, iptables, nftables, and ufw available.

I have tried a variety of iptables configurations with no success.



As far as I can tell a configuration that /should/ work (but doesn't!) is as follows:



Global:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward port 222 to Local:22
-A PREROUTING -p tcp --dport 222 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:22

# forward port 80 to Local:80
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:80

# forward port 443 to Local:443
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:443

# and forward the responses the other direction
-A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

COMMIT

Local:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward outgoing port 25 to Global:25
-A OUTPUT -p tcp --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 Subnet>:25

COMMIT


I realize that incoming requests for HTTP can be routed using nginx or apache configuration, but I want a generic solution that is not protocol-dependent and could be used for ssh or other protocols, as this traffic will not necessarily always be HTTP.



Does anyone know how this can be done?

Is there some reason that this type of configuration isn't possible?










share|improve this question
























  • Have you tried to use the FORWARD chain on the default 'filter' table rather than doing the nat rules in the PREROUTING chain? The masquerade rule looks right, the others might need to be changed.

    – datUser
    Mar 16 at 18:29












  • I tried setting it to use FORWARD but that didn't seem to work either. Interestingly however it does work with PREROUTING when I route to a different port on the same host, but it doesn't seem to forward to external hosts successfully.

    – Dan
    Mar 16 at 18:53











  • Yeah, so the PREROUTING chain is not for sending to other hosts, that would be FORWARD.

    – datUser
    Mar 16 at 21:35


















0















I am attempting to solve the following problem:



I have a system which I will henceforth refer to as "Local" that hosts a service on port 80 and port 443, and depends on sending outgoing requests on port 25. It also hosts a separate service on port 22.

I have a system which I will call "Global" that has a globally accessible static IP address and has DNS configured for it, and is capable of accepting incoming requests on port 80, 443, 25, and 222.



Local and Global are connected (via a VPN interface, if it matters) on the reserved subnet 10.0.0.0/24



I want all incoming requests on Global ports 80 and 443 to redirect to Local on ports 80 and 443 respectively.
I also want incoming requests on Global port 222 to redirect to Local on port 22 (yes, that is an intentionally different port).
In addition, I want all outgoing requests to port 25 from Local to redirect to Global on port 25.



Both Local and Global are modern linux systems with apt, iptables, nftables, and ufw available.

I have tried a variety of iptables configurations with no success.



As far as I can tell a configuration that /should/ work (but doesn't!) is as follows:



Global:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward port 222 to Local:22
-A PREROUTING -p tcp --dport 222 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:22

# forward port 80 to Local:80
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:80

# forward port 443 to Local:443
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:443

# and forward the responses the other direction
-A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

COMMIT

Local:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward outgoing port 25 to Global:25
-A OUTPUT -p tcp --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 Subnet>:25

COMMIT


I realize that incoming requests for HTTP can be routed using nginx or apache configuration, but I want a generic solution that is not protocol-dependent and could be used for ssh or other protocols, as this traffic will not necessarily always be HTTP.



Does anyone know how this can be done?

Is there some reason that this type of configuration isn't possible?










share|improve this question
























  • Have you tried to use the FORWARD chain on the default 'filter' table rather than doing the nat rules in the PREROUTING chain? The masquerade rule looks right, the others might need to be changed.

    – datUser
    Mar 16 at 18:29












  • I tried setting it to use FORWARD but that didn't seem to work either. Interestingly however it does work with PREROUTING when I route to a different port on the same host, but it doesn't seem to forward to external hosts successfully.

    – Dan
    Mar 16 at 18:53











  • Yeah, so the PREROUTING chain is not for sending to other hosts, that would be FORWARD.

    – datUser
    Mar 16 at 21:35














0












0








0








I am attempting to solve the following problem:



I have a system which I will henceforth refer to as "Local" that hosts a service on port 80 and port 443, and depends on sending outgoing requests on port 25. It also hosts a separate service on port 22.

I have a system which I will call "Global" that has a globally accessible static IP address and has DNS configured for it, and is capable of accepting incoming requests on port 80, 443, 25, and 222.



Local and Global are connected (via a VPN interface, if it matters) on the reserved subnet 10.0.0.0/24



I want all incoming requests on Global ports 80 and 443 to redirect to Local on ports 80 and 443 respectively.
I also want incoming requests on Global port 222 to redirect to Local on port 22 (yes, that is an intentionally different port).
In addition, I want all outgoing requests to port 25 from Local to redirect to Global on port 25.



Both Local and Global are modern linux systems with apt, iptables, nftables, and ufw available.

I have tried a variety of iptables configurations with no success.



As far as I can tell a configuration that /should/ work (but doesn't!) is as follows:



Global:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward port 222 to Local:22
-A PREROUTING -p tcp --dport 222 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:22

# forward port 80 to Local:80
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:80

# forward port 443 to Local:443
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:443

# and forward the responses the other direction
-A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

COMMIT

Local:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward outgoing port 25 to Global:25
-A OUTPUT -p tcp --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 Subnet>:25

COMMIT


I realize that incoming requests for HTTP can be routed using nginx or apache configuration, but I want a generic solution that is not protocol-dependent and could be used for ssh or other protocols, as this traffic will not necessarily always be HTTP.



Does anyone know how this can be done?

Is there some reason that this type of configuration isn't possible?










share|improve this question
















I am attempting to solve the following problem:



I have a system which I will henceforth refer to as "Local" that hosts a service on port 80 and port 443, and depends on sending outgoing requests on port 25. It also hosts a separate service on port 22.

I have a system which I will call "Global" that has a globally accessible static IP address and has DNS configured for it, and is capable of accepting incoming requests on port 80, 443, 25, and 222.



Local and Global are connected (via a VPN interface, if it matters) on the reserved subnet 10.0.0.0/24



I want all incoming requests on Global ports 80 and 443 to redirect to Local on ports 80 and 443 respectively.
I also want incoming requests on Global port 222 to redirect to Local on port 22 (yes, that is an intentionally different port).
In addition, I want all outgoing requests to port 25 from Local to redirect to Global on port 25.



Both Local and Global are modern linux systems with apt, iptables, nftables, and ufw available.

I have tried a variety of iptables configurations with no success.



As far as I can tell a configuration that /should/ work (but doesn't!) is as follows:



Global:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward port 222 to Local:22
-A PREROUTING -p tcp --dport 222 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:22

# forward port 80 to Local:80
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:80

# forward port 443 to Local:443
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <Local IP on 10.0.0.0/24 Subnet>:443

# and forward the responses the other direction
-A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

COMMIT

Local:
/etc/ufw/before.rules (excerpt)
*nat
:PREROUTING ACCEPT [0:0]

# forward outgoing port 25 to Global:25
-A OUTPUT -p tcp --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 Subnet>:25

COMMIT


I realize that incoming requests for HTTP can be routed using nginx or apache configuration, but I want a generic solution that is not protocol-dependent and could be used for ssh or other protocols, as this traffic will not necessarily always be HTTP.



Does anyone know how this can be done?

Is there some reason that this type of configuration isn't possible?







networking iptables ufw nftables






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 24 at 15:49







Dan

















asked Mar 16 at 18:04









DanDan

114




114












  • Have you tried to use the FORWARD chain on the default 'filter' table rather than doing the nat rules in the PREROUTING chain? The masquerade rule looks right, the others might need to be changed.

    – datUser
    Mar 16 at 18:29












  • I tried setting it to use FORWARD but that didn't seem to work either. Interestingly however it does work with PREROUTING when I route to a different port on the same host, but it doesn't seem to forward to external hosts successfully.

    – Dan
    Mar 16 at 18:53











  • Yeah, so the PREROUTING chain is not for sending to other hosts, that would be FORWARD.

    – datUser
    Mar 16 at 21:35


















  • Have you tried to use the FORWARD chain on the default 'filter' table rather than doing the nat rules in the PREROUTING chain? The masquerade rule looks right, the others might need to be changed.

    – datUser
    Mar 16 at 18:29












  • I tried setting it to use FORWARD but that didn't seem to work either. Interestingly however it does work with PREROUTING when I route to a different port on the same host, but it doesn't seem to forward to external hosts successfully.

    – Dan
    Mar 16 at 18:53











  • Yeah, so the PREROUTING chain is not for sending to other hosts, that would be FORWARD.

    – datUser
    Mar 16 at 21:35

















Have you tried to use the FORWARD chain on the default 'filter' table rather than doing the nat rules in the PREROUTING chain? The masquerade rule looks right, the others might need to be changed.

– datUser
Mar 16 at 18:29






Have you tried to use the FORWARD chain on the default 'filter' table rather than doing the nat rules in the PREROUTING chain? The masquerade rule looks right, the others might need to be changed.

– datUser
Mar 16 at 18:29














I tried setting it to use FORWARD but that didn't seem to work either. Interestingly however it does work with PREROUTING when I route to a different port on the same host, but it doesn't seem to forward to external hosts successfully.

– Dan
Mar 16 at 18:53





I tried setting it to use FORWARD but that didn't seem to work either. Interestingly however it does work with PREROUTING when I route to a different port on the same host, but it doesn't seem to forward to external hosts successfully.

– Dan
Mar 16 at 18:53













Yeah, so the PREROUTING chain is not for sending to other hosts, that would be FORWARD.

– datUser
Mar 16 at 21:35






Yeah, so the PREROUTING chain is not for sending to other hosts, that would be FORWARD.

– datUser
Mar 16 at 21:35











1 Answer
1






active

oldest

votes


















0














Okay so after much consternation I was able to solve my original problem and can therefore post the correct solution here for anyone who might come across this in the future. Application layer configuration is outside the scope of the original question.



Firstly, if you have ufw set up you will need to allow these rules to apply without being blocked by the firewall. This will need to be done on BOTH hosts, if they both have ufw. This is done with the steps described at https://help.ubuntu.com/lts/serverguide/firewall.html under section heading "IP Masquerading", and they are summarized below



0) edit /etc/default/ufw to set DEFAULT_FORWARD_POLICY="ACCEPT"
1) edit /etc/ufw/sysctl.conf to set net/ipv4/ip_forward=1 and net/ipv6/conf/default/forwarding=1
2) put the desired iptables rules in /etc/ufw/before.rules using ufw's syntax, starting with *nat and ending with COMMIT
3) restart ufw


To redirect incoming packets, and proxy them through to Local, use the following configuration on Global:



 #ensure forwarding is enabled, just for sanity's sake (for ufw sysctl.conf covers this)
sysctl -w net.ipv4.ip_forward=1

#rewrite incoming port 222 to Local:22
iptables -t nat -A PREROUTING -p tcp --dport 222 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:22

#having rewritten the destination, also rewrite the source for all packets that now have a destination of Local:22
#rewriting the source means that the ACKs and other bidirectional data gets sent back to Global instead of attempting to go from Local directly to the originator
iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 22 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

#repeat the above for ports 80 and 443, as in the original question
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:80
iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 80 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:443
iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 443 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>


That covers the incoming proxy connection. For outgoing connections, we'll need the following configuration on Local:



 #rewrite outgoing port 25 to Global:25, UNLESS it's meant for localhost (assumes lo is set up for ipv4, and not just ipv6)
iptables -t nat -A OUTPUT -p tcp '!' -d 127.0.0.1/32 --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 subnet>:25

#having rewritten the destination, also rewrite the source for all packets that now have a destination of Global:25
iptables -t nat -A POSTROUTING -p tcp '!' -d 127.0.0.1/32 --dport 25 -j SNAT --to-source <Local IP on 10.0.0.0/24 subnet>


We needed to allow localhost so that it's possible to connect to a local server on that port, as that is how SMTP and many other programs (including DNS) that do proxying at the protocol level need to operate. Therefore we forwarded everything that wasn't bound for localhost.



That's it! That's the complete configuration at this level of the stack, and it will get your packets where they need to be. Application level configuration is outside the scope of this question.






share|improve this answer























    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f506705%2fhow-can-i-configure-bidirectional-protocol-independent-port-forwarding%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Okay so after much consternation I was able to solve my original problem and can therefore post the correct solution here for anyone who might come across this in the future. Application layer configuration is outside the scope of the original question.



    Firstly, if you have ufw set up you will need to allow these rules to apply without being blocked by the firewall. This will need to be done on BOTH hosts, if they both have ufw. This is done with the steps described at https://help.ubuntu.com/lts/serverguide/firewall.html under section heading "IP Masquerading", and they are summarized below



    0) edit /etc/default/ufw to set DEFAULT_FORWARD_POLICY="ACCEPT"
    1) edit /etc/ufw/sysctl.conf to set net/ipv4/ip_forward=1 and net/ipv6/conf/default/forwarding=1
    2) put the desired iptables rules in /etc/ufw/before.rules using ufw's syntax, starting with *nat and ending with COMMIT
    3) restart ufw


    To redirect incoming packets, and proxy them through to Local, use the following configuration on Global:



     #ensure forwarding is enabled, just for sanity's sake (for ufw sysctl.conf covers this)
    sysctl -w net.ipv4.ip_forward=1

    #rewrite incoming port 222 to Local:22
    iptables -t nat -A PREROUTING -p tcp --dport 222 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:22

    #having rewritten the destination, also rewrite the source for all packets that now have a destination of Local:22
    #rewriting the source means that the ACKs and other bidirectional data gets sent back to Global instead of attempting to go from Local directly to the originator
    iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 22 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

    #repeat the above for ports 80 and 443, as in the original question
    iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:80
    iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 80 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

    iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:443
    iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 443 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>


    That covers the incoming proxy connection. For outgoing connections, we'll need the following configuration on Local:



     #rewrite outgoing port 25 to Global:25, UNLESS it's meant for localhost (assumes lo is set up for ipv4, and not just ipv6)
    iptables -t nat -A OUTPUT -p tcp '!' -d 127.0.0.1/32 --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 subnet>:25

    #having rewritten the destination, also rewrite the source for all packets that now have a destination of Global:25
    iptables -t nat -A POSTROUTING -p tcp '!' -d 127.0.0.1/32 --dport 25 -j SNAT --to-source <Local IP on 10.0.0.0/24 subnet>


    We needed to allow localhost so that it's possible to connect to a local server on that port, as that is how SMTP and many other programs (including DNS) that do proxying at the protocol level need to operate. Therefore we forwarded everything that wasn't bound for localhost.



    That's it! That's the complete configuration at this level of the stack, and it will get your packets where they need to be. Application level configuration is outside the scope of this question.






    share|improve this answer



























      0














      Okay so after much consternation I was able to solve my original problem and can therefore post the correct solution here for anyone who might come across this in the future. Application layer configuration is outside the scope of the original question.



      Firstly, if you have ufw set up you will need to allow these rules to apply without being blocked by the firewall. This will need to be done on BOTH hosts, if they both have ufw. This is done with the steps described at https://help.ubuntu.com/lts/serverguide/firewall.html under section heading "IP Masquerading", and they are summarized below



      0) edit /etc/default/ufw to set DEFAULT_FORWARD_POLICY="ACCEPT"
      1) edit /etc/ufw/sysctl.conf to set net/ipv4/ip_forward=1 and net/ipv6/conf/default/forwarding=1
      2) put the desired iptables rules in /etc/ufw/before.rules using ufw's syntax, starting with *nat and ending with COMMIT
      3) restart ufw


      To redirect incoming packets, and proxy them through to Local, use the following configuration on Global:



       #ensure forwarding is enabled, just for sanity's sake (for ufw sysctl.conf covers this)
      sysctl -w net.ipv4.ip_forward=1

      #rewrite incoming port 222 to Local:22
      iptables -t nat -A PREROUTING -p tcp --dport 222 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:22

      #having rewritten the destination, also rewrite the source for all packets that now have a destination of Local:22
      #rewriting the source means that the ACKs and other bidirectional data gets sent back to Global instead of attempting to go from Local directly to the originator
      iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 22 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

      #repeat the above for ports 80 and 443, as in the original question
      iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:80
      iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 80 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

      iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:443
      iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 443 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>


      That covers the incoming proxy connection. For outgoing connections, we'll need the following configuration on Local:



       #rewrite outgoing port 25 to Global:25, UNLESS it's meant for localhost (assumes lo is set up for ipv4, and not just ipv6)
      iptables -t nat -A OUTPUT -p tcp '!' -d 127.0.0.1/32 --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 subnet>:25

      #having rewritten the destination, also rewrite the source for all packets that now have a destination of Global:25
      iptables -t nat -A POSTROUTING -p tcp '!' -d 127.0.0.1/32 --dport 25 -j SNAT --to-source <Local IP on 10.0.0.0/24 subnet>


      We needed to allow localhost so that it's possible to connect to a local server on that port, as that is how SMTP and many other programs (including DNS) that do proxying at the protocol level need to operate. Therefore we forwarded everything that wasn't bound for localhost.



      That's it! That's the complete configuration at this level of the stack, and it will get your packets where they need to be. Application level configuration is outside the scope of this question.






      share|improve this answer

























        0












        0








        0







        Okay so after much consternation I was able to solve my original problem and can therefore post the correct solution here for anyone who might come across this in the future. Application layer configuration is outside the scope of the original question.



        Firstly, if you have ufw set up you will need to allow these rules to apply without being blocked by the firewall. This will need to be done on BOTH hosts, if they both have ufw. This is done with the steps described at https://help.ubuntu.com/lts/serverguide/firewall.html under section heading "IP Masquerading", and they are summarized below



        0) edit /etc/default/ufw to set DEFAULT_FORWARD_POLICY="ACCEPT"
        1) edit /etc/ufw/sysctl.conf to set net/ipv4/ip_forward=1 and net/ipv6/conf/default/forwarding=1
        2) put the desired iptables rules in /etc/ufw/before.rules using ufw's syntax, starting with *nat and ending with COMMIT
        3) restart ufw


        To redirect incoming packets, and proxy them through to Local, use the following configuration on Global:



         #ensure forwarding is enabled, just for sanity's sake (for ufw sysctl.conf covers this)
        sysctl -w net.ipv4.ip_forward=1

        #rewrite incoming port 222 to Local:22
        iptables -t nat -A PREROUTING -p tcp --dport 222 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:22

        #having rewritten the destination, also rewrite the source for all packets that now have a destination of Local:22
        #rewriting the source means that the ACKs and other bidirectional data gets sent back to Global instead of attempting to go from Local directly to the originator
        iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 22 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

        #repeat the above for ports 80 and 443, as in the original question
        iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:80
        iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 80 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

        iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:443
        iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 443 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>


        That covers the incoming proxy connection. For outgoing connections, we'll need the following configuration on Local:



         #rewrite outgoing port 25 to Global:25, UNLESS it's meant for localhost (assumes lo is set up for ipv4, and not just ipv6)
        iptables -t nat -A OUTPUT -p tcp '!' -d 127.0.0.1/32 --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 subnet>:25

        #having rewritten the destination, also rewrite the source for all packets that now have a destination of Global:25
        iptables -t nat -A POSTROUTING -p tcp '!' -d 127.0.0.1/32 --dport 25 -j SNAT --to-source <Local IP on 10.0.0.0/24 subnet>


        We needed to allow localhost so that it's possible to connect to a local server on that port, as that is how SMTP and many other programs (including DNS) that do proxying at the protocol level need to operate. Therefore we forwarded everything that wasn't bound for localhost.



        That's it! That's the complete configuration at this level of the stack, and it will get your packets where they need to be. Application level configuration is outside the scope of this question.






        share|improve this answer













        Okay so after much consternation I was able to solve my original problem and can therefore post the correct solution here for anyone who might come across this in the future. Application layer configuration is outside the scope of the original question.



        Firstly, if you have ufw set up you will need to allow these rules to apply without being blocked by the firewall. This will need to be done on BOTH hosts, if they both have ufw. This is done with the steps described at https://help.ubuntu.com/lts/serverguide/firewall.html under section heading "IP Masquerading", and they are summarized below



        0) edit /etc/default/ufw to set DEFAULT_FORWARD_POLICY="ACCEPT"
        1) edit /etc/ufw/sysctl.conf to set net/ipv4/ip_forward=1 and net/ipv6/conf/default/forwarding=1
        2) put the desired iptables rules in /etc/ufw/before.rules using ufw's syntax, starting with *nat and ending with COMMIT
        3) restart ufw


        To redirect incoming packets, and proxy them through to Local, use the following configuration on Global:



         #ensure forwarding is enabled, just for sanity's sake (for ufw sysctl.conf covers this)
        sysctl -w net.ipv4.ip_forward=1

        #rewrite incoming port 222 to Local:22
        iptables -t nat -A PREROUTING -p tcp --dport 222 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:22

        #having rewritten the destination, also rewrite the source for all packets that now have a destination of Local:22
        #rewriting the source means that the ACKs and other bidirectional data gets sent back to Global instead of attempting to go from Local directly to the originator
        iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 22 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

        #repeat the above for ports 80 and 443, as in the original question
        iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:80
        iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 80 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>

        iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-dest <Local IP on 10.0.0.0/24 subnet>:443
        iptables -t nat -A POSTROUTING -d <Local IP on 10.0.0.0/24 subnet> -p tcp --dport 443 -j SNAT --to-source <Global IP on 10.0.0.0/24 subnet>


        That covers the incoming proxy connection. For outgoing connections, we'll need the following configuration on Local:



         #rewrite outgoing port 25 to Global:25, UNLESS it's meant for localhost (assumes lo is set up for ipv4, and not just ipv6)
        iptables -t nat -A OUTPUT -p tcp '!' -d 127.0.0.1/32 --dport 25 -j DNAT --to-destination <Global IP on 10.0.0.0/24 subnet>:25

        #having rewritten the destination, also rewrite the source for all packets that now have a destination of Global:25
        iptables -t nat -A POSTROUTING -p tcp '!' -d 127.0.0.1/32 --dport 25 -j SNAT --to-source <Local IP on 10.0.0.0/24 subnet>


        We needed to allow localhost so that it's possible to connect to a local server on that port, as that is how SMTP and many other programs (including DNS) that do proxying at the protocol level need to operate. Therefore we forwarded everything that wasn't bound for localhost.



        That's it! That's the complete configuration at this level of the stack, and it will get your packets where they need to be. Application level configuration is outside the scope of this question.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 24 at 15:46









        DanDan

        114




        114



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f506705%2fhow-can-i-configure-bidirectional-protocol-independent-port-forwarding%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay