On CentOS 7 Linux (acting as LAMP - and not "firewall/gateway") I have created a custom systemd service for running embedded Jetty at port 8080 as user nobody
:
[Unit]
Description=WebSocket Handler Service
After=network-online.target
[Service]
Type=simple
User=nobody
Group=nobody
ExecStart=/usr/bin/java -classpath '/usr/share/java/jetty/*' de.afarber.MyHandler 123.123.123.123:8080
ExecStop=/bin/kill ${MAINPID}
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
However I actually need the server to listen at the port 80 - so that WebSocket connections to it work even through corporate firewalls.
The Jetty document on Setting Port 80 Access for a Non-Root User suggests to run the following command:
# iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
Luckily I already use iptables-services
package at my dedicated server and the current /etc/sysconfig/iptables
file contains:
*filter
:INPUT DROP
:FORWARD DROP
:OUTPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp -m multiport --dports 25,80,443,8080 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 2/min --limit-burst 1 -j ACCEPT
COMMIT
My problem is that I don't know the proper PREROUTING-syntax for the above file.
I have tried running the command above and then iptables -S
in the hope that iptables will list the needed line for me - but that didn't happen.
UPDATE:
Unfortunately the following /etc/sysconfig/iptables
file does not work:
*nat
:INPUT ACCEPT
:OUTPUT ACCEPT
:PREROUTING ACCEPT
:POSTROUTING ACCEPT
-A PREROUTING -p tcp -m tcp --dst 123.123.123.123 --dport 80 -j REDIRECT --to-ports 8080
COMMIT
*filter
:INPUT ACCEPT
:OUTPUT ACCEPT
:FORWARD ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A INPUT -p tcp -m tcp -m state --state NEW -m multiport --dports 25,80,443,8080 -j ACCEPT
-A INPUT -p tcp -m tcp -m state --state NEW --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 2/min --limit-burst 1 -j ACCEPT
-A FORWARD -p tcp -m tcp --dst 123.123.123.123 --dport 8080 -j ACCEPT
COMMIT
I need incoming HTTP-connections to 123.123.123.123:80 to be redirected to 123.123.123.123:8080 (where Jetty is listening as user "nobody"), but for some reason this does not happen.
When I browse to http://123.123.123.123:8080 then I see Jetty response.
But when I browse to http://123.123.123.123 connection is refused.
Can anybody please spot the error for me?
Here is my current nat
table:
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- anywhere afarber.de tcp dpt:http redir ports 8080
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Here is my current filter
table:
# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT icmp -- anywhere anywhere icmp any
ACCEPT tcp -- anywhere anywhere tcp state NEW multiport dports smtp,http,https,webcache
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN state NEW limit: avg 2/min burst 1
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere afarber.de tcp dpt:webcache
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Here my /etc/sysctl.conf
file:
net.ipv4.ip_forward=1
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
Problem: requests to -d 123.123.123.123 --dport 80
are not redirected to 8080
UPDATE 2:
The line does not help either:
-A PREROUTING -p tcp -m tcp -i eth0:1 --dst 123.123.123.123 --dport 80 -j DNAT --to-destination :8080
the connection to 123.123.123.123:80
is still dropped
It would be like this:
Do you know how to do it the easy way? I assume you have disabled the firewalld and installed iptables-services because you wanted your centos7 to work as centos6.
"/etc/sysconfig/iptables" is the file where iptables-services save the rules. You can edit it manualy, but there is no need to. You can just enter any rules using the "iptables" command and then "service iptables save" to save the currently active rules to the file.
You can also make is so that the rules will be saved every time the iptables service is restrted by setting here "/etc/sysconfig/iptables-config" IPTABLES_SAVE_ON_STOP and IPTABLES_SAVE_ON_RESTART
I think I have finally figured it out - the NAT HOWTO says, that
-j REDIRECT
is just a shortcut for-j DNAT
with destination address being the one of the interface:But in my case that just can not work, because my CentOS 7 server has 4 IP addresses.
(I am sorry, that I haven't mentioned it, because I didn't think it would matter).
At
eth0
port 80 runs Apache (which can drop root rights).And at
eth0:1
port 8080 runs Jetty (which can not drop root rights). But I need Jetty at port 80 (so that websockets work for corporate users behind proxies) and I want it to run as user "nobody".And now I have figured out, how to redirect the incoming requests with
net.ipv4.ip_forward=1
in /etc/sysctl.conf and with the following /etc/sysconfig/iptables: