9

I have a LXC container (10.0.3.2) running on a host. A service is running inside the container on port 7000.

From the host (10.0.3.1, lxcbr0), I can reach the service:

$ telnet 10.0.3.2 7000
Trying 10.0.3.2...
Connected to 10.0.3.2.
Escape character is '^]'.

I'd love to make the service running inside the container accessible to the outer world. Therefore, I want to forward port 7002 on the host to port 7000 on the container:

iptables -t nat -A PREROUTING -p tcp --dport 7002 -j DNAT --to 10.0.3.2:7000

Which results in (iptables -t nat -L):

DNAT   tcp  --  anywhere     anywhere     tcp dpt:afs3-prserver to:10.0.3.2:7000

Still, I cannot access the service from the host using the forwarded port:

$ telnet 10.0.3.1 7002
Trying 10.0.3.1...
telnet: Unable to connect to remote host: Connection refused

I feel like I'm missing something stupid here. What things should I check? What's a good strategy to debug these situations?

For completeness, here is how iptables are set on the host:

iptables -F
iptables -F -t nat
iptables -F -t mangle
iptables -X

iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o lxcbr0 -j MASQUERADE

iptables -t nat -A PREROUTING -p tcp --dport 7002 -j DNAT --to 10.0.3.2:7000
Roberto Aloi
  • 575
  • 2
  • 5
  • 14

6 Answers6

3

Seems you have blocked 7002 port on 10.0.3.1 as your default policy is DROP

Try adding it to INPUT rules:

iptables -A INPUT -p tcp --dport 7002 -j ACCEPT
insider
  • 211
  • 2
  • 7
1

I ran into the same problem. I have not found solution yet, but following I note down some observations.

I have a host ${host} machine (Ubuntu 12.04) and it runs a guest machine via LXC. The guest is on IP 10.0.3.248 and gateway is 10.0.3.1. I run a web server in the guest and want to port forward traffic from ${host}:8888 to 10.0.3.248:80. Following is the relevant iptables entries:

-A PREROUTING -p tcp --dport 8888 -j DNAT --to-destination 10.0.3.248:80
-A POSTROUTING -j MASQUERADE

With the current configuration, I can successfully visit the web server on 10.0.3.248:80 from another physical machine. However, it fails when I try to visit 10.0.3.248:80 from ${host}. Maybe you can try to visit that service inside LXC from another machine.

My understanding is that, when I visit from ${host}, the packet go through loopback interface and enters the INPUT chain directly. Although I allow everything on INPUT, there is no service listening at ${host}:8888. From wireshark, I see a RST is sent received. When I visit from another physical machine, the packet goes into PREROUTING chain and was DNAT-ed as expected.

One related post:

user199716
  • 11
  • 2
0

Following the tutorial from lxcware got the job done for me. I think it will be easier for most users to use the lxc commands instead. A short synopsis, assuming your container's name is container1 and you are forwarding from your host 7002 to container's 7000:

$ lxc profile create proxy-80
$ lxc profile device add proxy-80 hostport80 proxy \
 connect="tcp:127.0.0.1:7000" listen="tcp:0.0.0.0:7002"
$ lxc profile add container1 proxy-80

Check that it applied correctly to your container:

$ lxc config show container1 -e
vecf
  • 1
0

I needed to add a FORWARD rule

iptables -A FORWARD -p tcp -d 10.0.3.2 --dport 7002 -j ACCEPT
teknopaul
  • 639
  • 6
  • 4
0

ok, my 5 cents from year 2018:

I did install LXC and play around it. My container IP is 10.0.0.10

I added this rule:

iptables -t nat -A PREROUTING -p tcp -i ens192 --dport 81 -j DNAT --to-destination 10.0.0.10:22

It did not worked. Then I realized, that even FORWARD policy is ACCEPT, there is a rule that blocks all FORWARD's.

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      virbr0  0.0.0.0/0            10.0.0.0/24          ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  virbr0 *       10.0.0.0/24          0.0.0.0/0           
    0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0           
    5   268 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

So I had to inject rule at the top:

iptables -I FORWARD -p tcp -d 10.0.0.10 --dport 22 -j ACCEPT

Now forward host:81 -> 10.0.0.10:22 works.

Nick
  • 826
  • 2
  • 15
  • 42
-2

Your container is accessible from LAN via a host bridge interface, and thus connected to the same subnet as the host.

You need to have your router forward those ports to your container.