Beginners question about nat table entry in iptables

Hi there

I am a long term linux desktop user but I am not very technical.

I have in the past also set up and run a couple of VPSs to handle personal email, wordpress and nextcoud. Recently I have been introduced to LXD and it offers the potential to manage these kinds of services through one vps using containers. So I have set up a VPS and installed LXD 4.0.1 I have created two containers, one running nginx and one running my mailserver.

I am very new to this type of configuration, for example I had never used nginx or iptables before the last couple of weeks but with the help of one contributor to a forum and other forum posts I am making some progress.

I have used IP Tables to set up a nat configuration as follows
iptables -t nat -A PREROUTING -d /32 -i eth0 -p tcp -m multiport --dports 80,443 -m comment --comment NGINX -j DNAT --to-destination 10.133.231.106
iptables -t nat -A PREROUTING -d /32 -i eth0 -p tcp -m multiport --dports 25,143,993,587,465,4190 -m comment --comment MAIL -j DNAT --to-destination 10.133.231.181

I have configured nginx as a reverse proxy to handle port 80 and 443 traffic for my mailserver to be routed to my mailserver, which I can see is receiving this traffic.

However I am confused about whether I need to set up post-routing entries in the nat table with Iptables and whether there are other obvious things that I should be exploring.

My immediate question is what post routing commands do I need in iptables and what would be the appropriate syntax.

Thanks in advance for any help you can give.

Hi!

You can use iptables rules, or you can use LXD proxy devices instead.
Personally, I would recommend LXD proxy devices because

  1. you avoid iptables
  2. you do not need to figure out a mechanism to save them and apply after reboot
  3. the LXD proxy device is bound to the container, so no need to remember IP addresses.

See How to use the LXD Proxy Device to map ports between the host and the containers on how to set them up.

If you want to use iptables instead, you do not need POSTROUTING rules.

1 Like

Thank you for this helpful suggestion. I did not know about the proxy device option. I have read your post and I will try to explore this option a little further. I have a couple of questions.

  1. Can I add multiple ports in a single lxd proxy command?
  2. If I use a reverse proxy can it be in a container or does it need to be on the host?
  3. Is the configuration of the the reverse proxy on nginx, for example, achieved by the normal nginx configuration files or is there an LXD method?
  4. Is there a detailed documentation for LXD and LXC commands for LXD ver 4 that I can access with explanations of their usage.

Thanks in advance for any further help.

Theres some really recent threads by @Skyrider with the whole nginx scenario it might be worth taking a look over those

(In short your reverse proxy goes in a container - you add a proxy device for 80/443 to your reverse proxy container - your reverse proxy (nginx) follows the normal config)

  1. You add pairs of ports. Like 80 on the host to 80 to the container. You can repeat with 443, 465, or any other port. Works on both TCP and UDP.
  2. You would put the reverse proxy in a container. And you can also enable to PROXY protocol on the proxy device for extra awesomeness. If you end up putting the reverse proxy on the host, you do not need any LXD proxy devices.
  3. The nginx reverse proxy is transparent of LXD. That is, there is nothing specific to LXD in nginx, when used as a reverse proxy.
  4. There are several types of technical documentation. For example, there is reference documentation, and here is the part about the LXD proxy devices, https://linuxcontainers.org/lxd/docs/master/instances#type-proxy There are tutorials, like on my blog. Another type of technical documentation is the user guide. If you are referring to that, there is no user guide for LXD at the moment. In most cases, you can find your way in one way or another. In all cases, you can ask here.

Thanks again for the helpful replies. I have started to test out the proposed solution. I have so far 2 containers, one of which is acting as my nginx reverse proxy and the other contains my mailserver. I have used the LXD proxy command for both containers. The nginx one is proxied on port 80 and port 443. I have used 127.0.0.1 for the “connect” part of the command. The mailserver is proxied on ports 25, 143, 993, 465, 587 and 4190. I have used 127.0.0.2 as the ip address for the “connect” part of the command.

Is that the right thing to do?

I am reaching the nginx reverse proxy in my web browser but have yet to properly configure the nginx sites available file for forwarding some port 443 traffic to my mail server.

However I do have another problem. At the moment neither container can reach the internet for basic apt-get update and upgrade commands or ping. This predates the changes above but remains after them. As far as I know I have no other firewall rules, i have removed the original iptables pre-routing commands in the original posts and have not created any other rules.

The host can update fine, it is just the containers.

Could you suggest how I have manged to do this and how I might put it right?

Thanks again for any help.

Ideally, you would use the reverse proxy as the only container to send connections from the Internet. nginx, as a reverse proxy, can also proxy TCP connections (apart from HTTP connections). Of course, it will still work if you do not do it like that.

The connect= field can be any IP address for localhost. As a habit, it is good to stick to 127.0.0.1 unless you have reason to use something else. Between two containers, their 127.0.0.1 is different from each other.

I suppose you meant to forward HTTP traffic to some new containers with Web servers.

One thing to do, is install all from scratch to be sure there are no more remnants.
Alternatively, show the output of the commands

lxc network show lxdbr0
sudo iptables -S
sudo iptables -S -t nat

Thanks for the response.

This is the output of the three commands

lxc network show lxdbr0

config:
  ipv4.address: 10.133.231.1/24
  ipv4.nat: "true"
  ipv6.address: fd42:26a9:d871:74f3::1/64
  ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
used_by:
- /1.0/instances/box
- /1.0/instances/ngproxy
managed: true
status: Created
locations:
- none

sudo iptables -S

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N ufw-after-forward
-N ufw-after-input
-N ufw-after-logging-forward
-N ufw-after-logging-input
-N ufw-after-logging-output
-N ufw-after-output
-N ufw-before-forward
-N ufw-before-input
-N ufw-before-logging-forward
-N ufw-before-logging-input
-N ufw-before-logging-output
-N ufw-before-output
-N ufw-reject-forward
-N ufw-reject-input
-N ufw-reject-output
-N ufw-track-forward
-N ufw-track-input
-N ufw-track-output
-A INPUT -i lxdbr0 -p tcp -m tcp --dport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i lxdbr0 -p udp -m udp --dport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i lxdbr0 -p udp -m udp --dport 67 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -j ufw-before-logging-input
-A INPUT -j ufw-before-input
-A INPUT -j ufw-after-input
-A INPUT -j ufw-after-logging-input
-A INPUT -j ufw-reject-input
-A INPUT -j ufw-track-input
-A FORWARD -o lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A FORWARD -i lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A FORWARD -j ufw-before-logging-forward
-A FORWARD -j ufw-before-forward
-A FORWARD -j ufw-after-forward
-A FORWARD -j ufw-after-logging-forward
-A FORWARD -j ufw-reject-forward
-A FORWARD -j ufw-track-forward
-A OUTPUT -o lxdbr0 -p tcp -m tcp --sport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -o lxdbr0 -p udp -m udp --sport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -o lxdbr0 -p udp -m udp --sport 67 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -j ufw-before-logging-output
-A OUTPUT -j ufw-before-output
-A OUTPUT -j ufw-after-output
-A OUTPUT -j ufw-after-logging-output
-A OUTPUT -j ufw-reject-output
-A OUTPUT -j ufw-track-output

:~$ sudo iptables -S -t nat

-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -s 10.133.231.0/24 ! -d 10.133.231.0/24 -m comment --comment "generated for LXD network lxdbr0" -j MASQUERADE

Hi there
I havent been able to do much on this recently as life took over for a while. I did re-install from scratch my nginix reverse proxy server and my mailserver. I have set up the reverse proxy in nginx and the mail server reports in its self check messages that it is working in all respects except for an error message as follows

Public DNS (nsd4) is not running (port 53).

I am not as yet able to send or receive mail through this mailserver. I am not sure whether this is because of this DNS issue or other, as yet un-diagnosed matters. If it is the DNS issue do you have a suggestion for how port 53 (on both TCP and UDP) on the mailserver container can receive the appropriate traffic?

You mentioned in a previous reply
Ideally, you would use the reverse proxy as the only container to send connections from the Internet. nginx , as a reverse proxy, can also proxy TCP connections.

Do I achieve this in the same way as port 80 and 443? Do I use the same configuration file and add the other ports using the same syntax in the nginx sites available file or is there another way?

Thanks in advance for any advice.