iptables - change destination port after accept

I'm working with Ubuntu 14.04.  I'm trying to set up some inbound connections to MySQL.  I need the local MySQL port to stay at 3306.  Remote users, however, should connect to port 33000, and connections should be limited by IP whitelist.

Using "-j REDIRECT" or "-j DNAT" is not working.  My tests show that is because the default policy on INPUT is DROP, and I have no rule to ACCEPT on --dport 3306.  I do not want to light up port 3306, whitelist or not.

What rule can I create to ACCEPT a packet destined for an arbitrary port (e.g., 33000), only if originating from an acceptable IP, and mangle it to send it to the proper local destination port, all without opening the local destination port?
LVL 51
Steve BinkAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Duncan RoeSoftware DeveloperCommented:
To stop packets hitting the INPUT chain of the filter table, you have to match them in the PREROUTING chain of the nat table. Packets will then hit the FORWARD chain of the filter table. This is where you can examine them to decide which ones to accept. Actually you should only examine SYN packets - any other TCP traffic that hits the FORWARD chain must have done so by reason of connection tracking (following some SYN packet that you accepted) so you should ACCEPT them.
0
Steve BinkAuthor Commented:
My rules were on the nat table, but did not seem to have the effect I wanted.  Originally, I tried:
-t nat -A PREROUTING -m tcp -p tcp --dport 33000 -j REDIRECT --to-ports 3306

Open in new window

According to the docs, though, the REDIRECT target merely pushes the mangled packet back onto the network stack.  I'm guessing it goes through iptables again and is summarily dropped because 3306 is blocked.

I also tried:
-t nat -A PREROUTING -m tcp -p tcp --dport 33000 -j DNAT --to-destination :3306

Open in new window

While the DNAT docs did not explicitly mention the same behavior as REDIRECT, it did exhibit the same behavior.

In both instances, including "-A INPUT -m tcp -p tcp --dport 3306 -j ACCEPT" allowed the packets through.

I understand your point re:SYN packets, and will remember that in my final rules.  My current rule is just whitelisting my IP, but I'd prefer something a little more specific.
0
Daniel McAllisterPresident, IT4SOHO, LLCCommented:
OK, you need a NAT PREROUTING rule to redirect the port:
  iptables -t nat -A PREROUTING -s 1.2.3.4 -m tcp -p tcp --dport 33000 -j DNAT --to-destination 127.0.0.1:3306

But then you also need a forwarding rule:
  iptables -t filter -A FORWARD -s 1.2.3.4 -m tcp -p tcp --dport 33000 -j ACCEPT

As for accepting the redirect to port 3306, that should come as a result of an early rule that allows ALL connections on lo:
  iptables -t filter -A INPUT -i lo -j ACCEPT

Now I'm no iptables expert, but my understanding is that the above 3 rules should allow a host at IP address 1.2.3.4 to connect to your server on port 33000 and actually get a response from your MySQL server.

Good Luck!

Dan
IT4SOHO
0
Increase Security & Decrease Risk with NSPM Tools

Analyst firm, Enterprise Management Associates (EMA) reveals significant benefits to enterprises when using Network Security Policy Management (NSPM) solutions, while organizations without, experienced issues including non standard security policies and failed cloud migrations

Duncan RoeSoftware DeveloperCommented:
I think the FORWARD rule has to specify --dport 3306 because the packet has been so altered by the time it hits the FORWARD chain.
0
Steve BinkAuthor Commented:
I'm a little confused.  I thought the FORWARD chain was only for packets going through the box, and not originating from or going to the box.  This image is the flowchart I have in mind.

From that, I know my packet will hit PREROUTING on the nat table.  From there, iptables sees the packet is destined for the local machine, so it enters the INPUT chain.  My rule in the INPUT chain pushes the packet to the DNAT target with some modification.  Where does it go from there?  Does it go back to the network stack, to be re-evaluated?  Does it go to the OUTPUT chain?  Where does FORWARD enter the mix?
0
Duncan RoeSoftware DeveloperCommented:
You are quite right - when I originally posted I had not realized you were running iptables and a MySQL server on the same system.
You can't do this. iptables provides a router and firewall. Routers do not host applications. You have to interpose a separate system between the internet and your MySQL server on which to run iptables.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Steve BinkAuthor Commented:
Well, I was hoping for a different response, but it is what it is.  I guess my current rule will have to suffice:

-A INPUT -m tcp -p tcp -s 1.2.3.4 --dport 3306 -j ACCEPT
0
Daniel McAllisterPresident, IT4SOHO, LLCCommented:
Ok, while you accepted this as a solution, it is not valid (ok, in my opinion).
I run IPTABLES on virtually every system I run, and several redirect ports to different locations, although mostly to VMs (Virtual Machines)

I believe that your problem stemmed from the fact that you wanted to redirect from port 33000 (or some such), but you never opened that port (33000, or whatever). So while you said to redirect port 33000, you never said to ACCEPT connections (from anywhere, or any specific location) on port 33000.

If you're happy with your current setup, so be it -- but you can always redirect from one port to another on the same machine using the loopback interface (lo or on some systems lo0, or by IP 127.0.0.1). I do this all the time!

Dan
IT4SOHO
0
Steve BinkAuthor Commented:
Two notes:

1) I did try to play with the strategy you outlined.  In my tests, I ignored the FORWARD chain, and applied the PREROUTING rule pretty much as-is.  The loopback ACCEPT was already in my rules.  Unfortunately, I've already removed the rules I tested, so I can't be sure exactly what I tried.  I do know that I did not have an explicit ACCEPT for --dport 33000.  Wouldn't the addition of that rule on the INPUT chain conflict with/override the DNAT rule?  As I read them, one rule or the other would match, depending on the order.

2) While I'm satisfied with the current config (i.e., it is working), my object here was not just to complete this piece of work - I also want to learn more about iptables.  If you're willing to take a semi-noob by the hand, I'd be happy to start another question in that context.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Linux Networking

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.