1

problem:

I have an application sitting on a host (let's call it host1) that sends TLS-encrypted TCP packets to another host's port 5015 (let's call it host2). Due to network restrictions, the host1 must have all inbound and outbound traffic enter and leave through either 80 or 443. I have no access to host2.

approach:

My thinking is that I could create an iptables rule on host1 that will route/redirect/forward the 5015 traffic out of 443 and have to have it arrive at host2:5015. The problem I'm having is creating the right rule. Here's what I have so far:

TCP_TRAFFIC_PORT=5015
PROXY_PORT=443

_apply_outbound_rules() {
    # Forward outgoing packets through the proxy port
    sudo iptables -t nat \
        -I OUTPUT 1 \
        -p tcp --destination-port $TCP_TRAFFIC_PORT \
        -j DNAT --to-destination :$PROXY_PORT

    # Send packets to host2:5015 port (this is likely the rule to fix)
    sudo iptables -t nat \
        -I POSTROUTING 1 \
        -p tcp --destination-port $PROXY_PORT \
        -j SNAT --to-source :$TCP_TRAFFIC_PORT
}

apply_outbound_rules

Does anyone know how to do this? It seems like a common thing to run into, but I'm having trouble with it.

  • and there is no port restrictions for incoming packets ? – Bharat Apr 16 '18 at 17:49
  • @Bharat I should have specified that all traffic must come in and out of either port 80 or 443 on host1, thanks for pointing that out. I'll update the question to state that – delos Apr 16 '18 at 18:29
  • Have you tried echo 1 > /proc/sys/net/ipv4/ip_forward? That will enable routing in the kernel. – dogoncouch Apr 16 '18 at 18:36
  • @dogoncouch Just checked that file, kernel routing is enabled on host1. Do you know how to modify the rules to change the packet's destination port to 5015 after it leaves 443? – delos Apr 16 '18 at 18:53
  • 1
    @Hans-MartinMosner I appreciate your advice, I'll specify and say that this is to ship application metadata using Filebeat (host1) to a hosted ELK stack on Logz.io (host2) under the network restrictions (which are a bureaucratic hassle to get altered). And of course, the module will only be deployed if all legal contracts and parameters were agreed and signed off on beforehand by all parties. – delos Apr 17 '18 at 6:10
1

First, NAT in linux is stateful. Meaning you don't need an outbound and an inbound rule. When traffic comes back in that was NATed outbound, linux will automatically un-NAT that return traffic.

Though the main problem you're going to have is that a TCP session is defined by the combination of:

  • source IP
  • source port
  • destination IP
  • destination port

Source IP is already limited to a single value (IP of host1). Destination IP is already a single value (IP of host2). Source port only has 2 possible values (80 & 443). And destination port is limited to a single value (5015).
This means that you can only establish a maximum of 2 simultaneous connections (if you load balance the SNAT across the 2 ports). And even with sequential connections, you're likely to run into issues with port reuse things like the port being in a TIME_WAIT state.

However that said, if you really want to try this, the rule that should do it is:

iptables -t nat -I POSTROUTING \
  -d $HOST2_IP -p tcp --dport $TCP_TRAFFIC_PORT \
  -j SNAT --to-source :$PROXY_PORT
  • thanks for that, it's useful to know about the possible resource contention between the ports. I tried your rule replacing the previous POSTROUTING rule (using it after the OUTPUT rule) and then again alone, but couldn't get the packets to show at host2:5015 – delos Apr 16 '18 at 23:27
  • Is the rule meant to be used with another rule before hitting POSTROUTING? Because the connection is over TLS, would an INPUT rule to initiate the first connection over host1:5015 and host2:5015 be required? I have the following, but it also seems not to work sudo iptables -t nat -I PREROUTING -p tcp --source-port $TCP_TRAFFIC_PORT --destination-port $PROXY_PORT -j REDIRECT --to-port $TCP_TRAFFIC_PORT – delos Apr 16 '18 at 23:30
  • I'm not sure what you're asking about INPUT, but no, you should not have any other iptables rules in place. – Patrick Apr 17 '18 at 0:09
  • My understanding is that for the initial TLS handshake between both hosts, an inbound rule on host1 using PREROUTING (not INPUT, my mistake) may be needed so that exchange of packets could occur. Is that correct? – delos Apr 17 '18 at 5:04
0

Do you know on which port the application runs at your host, if no then you need to map all source ports to either 80 or 443

Try below with replacing host2ip.

iptables -t nat -A POSTROUTING -p tcp -d host2ip -j SNAT -m multiport  --sports 1:65535 --to-source :443

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.