[opensuse] Question about iptables and port forward masquerading
Hi - I dunno if this is a good group to ask this question but I will give it a shot and perhaps get pointed to a better group... I am running the Apache James email server on an OpenSuSE 15.0 x64 system and because of some other requirements I have to run the James daemon under a system user name and not under root. To accomplish that I had to change all the standard email ports that it listens on, to higher ones (I added 10000 to the standard port numbers so for example instead of having the smtp server listen on port 25 I configured it to listen on port 10025. Then using SuSEfirewall2 I configured it to do forward masquerading to route connections from port 25 to port 10025. So for example, and in particular for localhost which is shown here, I did the following - (sorry about the formatting, Thunderbird seems to be making choices that I don't want and I haven't got the time to figure out how to tell Thunderbird to knock it off!.) FW_FORWARD_MASQ=" ... \ (ext and int interface routing not shown but it is similar to what is shown below for localhost) 0/0,127.0.0.1,tcp,25,10025,127.0.0.1 \ 0/0,127.0.0.1,tcp,465,10465,127.0.0.1 \ 0/0,127.0.0.1,tcp,587,10587,127.0.0.1 \ 0/0,127.0.0.1,tcp,110,10110,127.0.0.1 \ 0/0,127.0.0.1,tcp,995,10995,127.0.0.1 \ 0/0,127.0.0.1,tcp,143,10143,127.0.0.1 \ 0/0,127.0.0.1,tcp,993,10993,127.0.0.1" The server is not protected from the internal network (this is a SOHO net) and all the external ports are opened. From either the internal network, or from the external network I can use telnet to connect to either the low number ports or the high numbered ports successfully. But from the localhost I can only connect to the high numbered ports. Connecting to the low number ports, such as 25, gets me a Connection Refused message when I try and do a 'telnet localhost 25'. ('telnet localhost 10025' works!) Using netstat shows that indeed Apache James (a java application) is listening on for example port 10025 - netstat -plnt Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:10025 0.0.0.0:* LISTEN 25012/java and from a snip of the iptables I see this - iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 226K packets, 15M bytes) pkts bytes target prot opt in out source destination (lots of other stuff removed, in particular the external interface as I don't want to show the IP addresses, but here is a bit showing some of the internal interface) 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 192.168.10.100 tcp dpt:25 to:192.168.10.100:10025 0 0 DNAT tcp -- lo * 0.0.0.0/0 192.168.10.100 tcp dpt:25 to:192.168.10.100:10025 22 1320 DNAT tcp -- p3p1 * 0.0.0.0/0 192.168.10.100 tcp dpt:25 to:192.168.10.100:10025 0 0 DNAT tcp -- p3p2 * 0.0.0.0/0 192.168.10.100 tcp dpt:25 to:192.168.10.100:10025 0 0 DNAT tcp -- tun0 * 0.0.0.0/0 192.168.10.100 tcp dpt:25 to:192.168.10.100:10025 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 192.168.10.100 tcp dpt:465 to:192.168.10.100:10465 0 0 DNAT tcp -- lo * 0.0.0.0/0 192.168.10.100 tcp dpt:465 to:192.168.10.100:10465 9 468 DNAT tcp -- p3p1 * 0.0.0.0/0 192.168.10.100 tcp dpt:465 to:192.168.10.100:10465 0 0 DNAT tcp -- p3p2 * 0.0.0.0/0 192.168.10.100 tcp dpt:465 to:192.168.10.100:10465 (and here is some of the things showing the localhost interface) 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 0 0 DNAT tcp -- lo * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 0 0 DNAT tcp -- p3p1 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 0 0 DNAT tcp -- p3p2 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 0 0 DNAT tcp -- tun0 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:465 to:127.0.0.1:10465 0 0 DNAT tcp -- lo * 0.0.0.0/0 127.0.0.1 tcp dpt:465 to:127.0.0.1:10465 0 0 DNAT tcp -- p3p1 * 0.0.0.0/0 127.0.0.1 tcp dpt:465 to:127.0.0.1:10465 0 0 DNAT tcp -- p3p2 * 0.0.0.0/0 127.0.0.1 tcp dpt:465 to:127.0.0.1:10465 0 0 DNAT tcp -- tun0 * 0.0.0.0/0 127.0.0.1 tcp dpt:465 to:127.0.0.1:10465 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:587 to:127.0.0.1:10587 0 0 DNAT tcp -- lo * 0.0.0.0/0 127.0.0.1 tcp dpt:587 to:127.0.0.1:10587 0 0 DNAT tcp -- p3p1 * 0.0.0.0/0 127.0.0.1 tcp dpt:587 to:127.0.0.1:10587 0 0 DNAT tcp -- p3p2 * 0.0.0.0/0 127.0.0.1 tcp dpt:587 to:127.0.0.1:10587 0 0 DNAT tcp -- tun0 * 0.0.0.0/0 127.0.0.1 tcp dpt:587 to:127.0.0.1:10587 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:110 to:127.0.0.1:10110 0 0 DNAT tcp -- lo * 0.0.0.0/0 127.0.0.1 tcp dpt:110 to:127.0.0.1:10110 0 0 DNAT tcp -- p3p1 * 0.0.0.0/0 127.0.0.1 tcp dpt:110 to:127.0.0.1:10110 yada yada yada... So what am I missing? It is important that I get localhost to accept connections on the low ports since I am using other tools, such as sendmail (in non-daemon mode) and I want it to use Apache James as it's MTA. Yet I cannot get connections to the low ports on localhost to work, but I am doing exactly the same sort of setup for the internal and external interfaces and there everything does work! Thanks in advance for any thoughts and ideas. I will be happy to provide more information, just ask! Marc.. -- --... ...-- .----. ... -.. . .-- .- --... .--. -..- .-- -- .- .-. -.-. <b>Computers: the final frontier. These are the voyages of the user Marc.<br> His mission: to explore strange new hardware. To seek out new software and new applications.<br> To boldly go where no Marc has gone before!<br></b> -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
11.06.2019 3:49, Marc Chamberlin пишет: ...
port 10025. Then using SuSEfirewall2 I configured it to do forward masquerading to route connections from port 25 to port 10025. So for example, and in particular for localhost which is shown here, ...
FW_FORWARD_MASQ=" ... \ (ext and int interface routing not shown but it is similar to what is shown below for localhost) 0/0,127.0.0.1,tcp,25,10025,127.0.0.1 \ 0/0,127.0.0.1,tcp,465,10465,127.0.0.1 \ 0/0,127.0.0.1,tcp,587,10587,127.0.0.1 \ 0/0,127.0.0.1,tcp,110,10110,127.0.0.1 \ 0/0,127.0.0.1,tcp,995,10995,127.0.0.1 \ 0/0,127.0.0.1,tcp,143,10143,127.0.0.1 \ 0/0,127.0.0.1,tcp,993,10993,127.0.0.1"
The server is not protected from the internal network (this is a SOHO net) and all the external ports are opened. From either the internal network, or from the external network I can use telnet to connect to either the low number ports or the high numbered ports successfully. But from the localhost I can only connect to the high numbered ports. Connecting to the low number ports, such as 25, gets me a Connection Refused message when I try and do a 'telnet localhost 25'. ('telnet localhost 10025' works!) ...
(and here is some of the things showing the localhost interface)
0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025
Without knowing what table and chain this is output does not say much. Anyway, packets originated locally do not traverse usual PREROUTING or FORWARD chains so any rule added there will not affect them and connection goes to port 25. As nothing is listens on port 25 you get connection refused. You will need to setup your port redirection rules in OUTPUT chain. See https://netfilter.org/documentation/HOWTO//netfilter-hacking-HOWTO-3.html for explanation how packets traverse netfilter. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 6/10/19 8:30 PM, Andrei Borzenkov wrote:
11.06.2019 3:49, Marc Chamberlin пишет: ...
port 10025. Then using SuSEfirewall2 I configured it to do forward masquerading to route connections from port 25 to port 10025. So for example, and in particular for localhost which is shown here, ... FW_FORWARD_MASQ=" ... \ (ext and int interface routing not shown but it is similar to what is shown below for localhost) 0/0,127.0.0.1,tcp,25,10025,127.0.0.1 \ 0/0,127.0.0.1,tcp,465,10465,127.0.0.1 \ 0/0,127.0.0.1,tcp,587,10587,127.0.0.1 \ 0/0,127.0.0.1,tcp,110,10110,127.0.0.1 \ 0/0,127.0.0.1,tcp,995,10995,127.0.0.1 \ 0/0,127.0.0.1,tcp,143,10143,127.0.0.1 \ 0/0,127.0.0.1,tcp,993,10993,127.0.0.1"
The server is not protected from the internal network (this is a SOHO net) and all the external ports are opened. From either the internal network, or from the external network I can use telnet to connect to either the low number ports or the high numbered ports successfully. But from the localhost I can only connect to the high numbered ports. Connecting to the low number ports, such as 25, gets me a Connection Refused message when I try and do a 'telnet localhost 25'. ('telnet localhost 10025' works!) ...
(and here is some of the things showing the localhost interface)
0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 Without knowing what table and chain this is output does not say much.
Anyway, packets originated locally do not traverse usual PREROUTING or FORWARD chains so any rule added there will not affect them and connection goes to port 25. As nothing is listens on port 25 you get connection refused. You will need to setup your port redirection rules in OUTPUT chain. See https://netfilter.org/documentation/HOWTO//netfilter-hacking-HOWTO-3.html for explanation how packets traverse netfilter.
Thanks Andrie, we collided and posted at the same time and yes I have managed to stumble my way to understanding that packets generated on the localhost do not traverse the PREROUTING chain which is where SuSEfirewall2 was sticking the ones I was trying to define for localhost. So as I mentioned in my last post, my quest is now to figure out how (if possible) to coax SuSEfirewall2 to put the rules I want, for localhost, in the OUTPUT chain. Marc... -- --... ...-- .----. ... -.. . .-- .- --... .--. -..- .-- -- .- .-. -.-. <b>Computers: the final frontier. These are the voyages of the user Marc.<br> His mission: to explore strange new hardware. To seek out new software and new applications.<br> To boldly go where no Marc has gone before!<br></b> -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 6/10/19 8:38 PM, Marc Chamberlin wrote:
On 6/10/19 8:30 PM, Andrei Borzenkov wrote:
11.06.2019 3:49, Marc Chamberlin пишет: ...
port 10025. Then using SuSEfirewall2 I configured it to do forward masquerading to route connections from port 25 to port 10025. So for example, and in particular for localhost which is shown here, ... FW_FORWARD_MASQ=" ... \ (ext and int interface routing not shown but it is similar to what is shown below for localhost) 0/0,127.0.0.1,tcp,25,10025,127.0.0.1 \ 0/0,127.0.0.1,tcp,465,10465,127.0.0.1 \ 0/0,127.0.0.1,tcp,587,10587,127.0.0.1 \ 0/0,127.0.0.1,tcp,110,10110,127.0.0.1 \ 0/0,127.0.0.1,tcp,995,10995,127.0.0.1 \ 0/0,127.0.0.1,tcp,143,10143,127.0.0.1 \ 0/0,127.0.0.1,tcp,993,10993,127.0.0.1"
The server is not protected from the internal network (this is a SOHO net) and all the external ports are opened. From either the internal network, or from the external network I can use telnet to connect to either the low number ports or the high numbered ports successfully. But from the localhost I can only connect to the high numbered ports. Connecting to the low number ports, such as 25, gets me a Connection Refused message when I try and do a 'telnet localhost 25'. ('telnet localhost 10025' works!) ...
(and here is some of the things showing the localhost interface)
0 0 DNAT tcp -- eth0 * 0.0.0.0/0 127.0.0.1 tcp dpt:25 to:127.0.0.1:10025 Without knowing what table and chain this is output does not say much.
Anyway, packets originated locally do not traverse usual PREROUTING or FORWARD chains so any rule added there will not affect them and connection goes to port 25. As nothing is listens on port 25 you get connection refused. You will need to setup your port redirection rules in OUTPUT chain. See https://netfilter.org/documentation/HOWTO//netfilter-hacking-HOWTO-3.html for explanation how packets traverse netfilter.
Thanks Andrie, we collided and posted at the same time and yes I have managed to stumble my way to understanding that packets generated on the localhost do not traverse the PREROUTING chain which is where SuSEfirewall2 was sticking the ones I was trying to define for localhost. So as I mentioned in my last post, my quest is now to figure out how (if possible) to coax SuSEfirewall2 to put the rules I want, for localhost, in the OUTPUT chain.
Marc...
I think I have a solution but am not sure if it is truly correct as I had to do a bit of guesswork. But it seems to be working as I expect, i.e. I can now telnet to port 25, for example, on localhost and get routed to port 10025 where Apache James is listening for SMTP connections. Mail and Sendmail are also happy campers and can use Apache James as their MTA. I added the following rules in /etc/sysconfig/scripts/SuSEfirewall2-custom - fw_custom_before_denyall() { # could also be named "after_forwardmasq()" # these are the rules to be loaded after IP forwarding and masquerading # but before the logging and deny all section is set by SuSEfirewall2. # You can use this hook to prevent the logging of annoying packets. iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 25 -j REDIRECT --to-ports 10025 iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 465 -j REDIRECT --to-ports 10465 iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 587 -j REDIRECT --to-ports 10587 iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 110 -j REDIRECT --to-ports 10110 iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 995 -j REDIRECT --to-ports 10995 iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 143 -j REDIRECT --to-ports 10143 iptables -t nat -I OUTPUT -p tcp -o lo -d 127.0.0.1 --dport 993 -j REDIRECT --to-ports 10993 true } As I said, not sure if this is correct but it is similar to examples I found while Googling. Dunno if this was the right routine to put these rules in either. Thoughts? Marc... -- --... ...-- .----. ... -.. . .-- .- --... .--. -..- .-- -- .- .-. -.-. <b>Computers: the final frontier. These are the voyages of the user Marc.<br> His mission: to explore strange new hardware. To seek out new software and new applications.<br> To boldly go where no Marc has gone before!<br></b> -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 2019/06/10 17:49, Marc Chamberlin wrote:
Hi - I dunno if this is a good group to ask this question but I will give it a shot and perhaps get pointed to a better group...
I am running the Apache James email server on an OpenSuSE 15.0 x64 system and because of some other requirements I have to run the James daemon under a system user name and not under root. To accomplish that I had to change all the standard email ports that it listens on, to higher ones (I added 10000 to the standard port numbers so for example instead of having the smtp server listen on port 25 I configured it to listen on port 10025.
Probably a bit late for this, but you never know... You could have run as any arbitrary user, and simply set the binary to "SETCAP xxx' to re-enable the various root privileges in the kernel that you needed. It might be as simple as making the binary have CAP_NET_ADMIN (or maybe CAP_NET_BIND_SERVICE) to bind the ports you needed. It would likely be more portable than something bound to some specific firewall implementation since the Capabilities are in the kernel so any any version of Suse or any other distro would work. Example is /usr/bin/ping needing the 'net_raw' capability to send out ICMP pings:
filecap /usr/bin/ping file capabilities /usr/bin/ping net_raw
-- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
On 6/10/19 9:26 PM, L A Walsh wrote:
On 2019/06/10 17:49, Marc Chamberlin wrote:
Hi - I dunno if this is a good group to ask this question but I will give it a shot and perhaps get pointed to a better group...
I am running the Apache James email server on an OpenSuSE 15.0 x64 system and because of some other requirements I have to run the James daemon under a system user name and not under root. To accomplish that I had to change all the standard email ports that it listens on, to higher ones (I added 10000 to the standard port numbers so for example instead of having the smtp server listen on port 25 I configured it to listen on port 10025.
Probably a bit late for this, but you never know...
You could have run as any arbitrary user, and simply set the binary to "SETCAP xxx' to re-enable the various root privileges in the kernel that you needed. It might be as simple as making the binary have CAP_NET_ADMIN (or maybe CAP_NET_BIND_SERVICE) to bind the ports you needed. It would likely be more portable than something bound to some specific firewall implementation since the Capabilities are in the kernel so any any version of Suse or any other distro would work.
Example is /usr/bin/ping needing the 'net_raw' capability to send out ICMP pings:
filecap /usr/bin/ping file capabilities /usr/bin/ping net_raw
Well THANKS Walsh, you certainly presented another interesting path to follow down! I have never heard of SETCAP before but it certainly seems like a logical way to get around the requirement that only ROOT can use the low numbered ports! I may have already found the brute force solution of setting iptables rules, and when I get some spare time I will look further into SETCAP as a more elegant solution. It is on my TODO list! Marc... -- --... ...-- .----. ... -.. . .-- .- --... .--. -..- .-- -- .- .-. -.-. <b>Computers: the final frontier. These are the voyages of the user Marc.<br> His mission: to explore strange new hardware. To seek out new software and new applications.<br> To boldly go where no Marc has gone before!<br></b> -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org
participants (3)
-
Andrei Borzenkov
-
L A Walsh
-
Marc Chamberlin