iptables Not Forwarding Port as Expected - express

I'm trying to get a basic Express application running on an AWS EC2 Ubuntu Linux instance.
On such systems, the server has to be run as a super user to listen to port 80. But that would be a bad practice, so instead you're supposed to listen to a different port (eg. 3000) and redirect traffic from port 80 to 3000.
To forward the port I tried using this command from another Stack Overflow answer, Node.js + Express: app won't start listening on port 80):
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 3000
I've run that command (and re-run it to be sure), but even so it doesn't seem to be forwarding 3000 to 80, because I can only access my server on port 3000:
curl localhost:3000
*html*
curl localhost
curl: (7) Failed to connect to localhost port 80 after 0 ms: Connection refused
I have no idea what I did wrong, but I know nothing about iptables, so any help would be appreciated.
P.S. I've tried checking the iptables records with the command sudo iptables -L -n -v, but the results don't say anything about ports (and again, I don't know iptables), so I'm not sure if it's saying my command worked or not:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target
prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target
prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target
prot opt in out source destination

The reason your test doesn't work is because trying to access the service from localhost bypasses the NAT table. You need to test from a different host. It should then work presuming the rule is loaded correctly and there is no firewall or other rules interfering.
Note, there are multiple other, probably better ways, to get get a non-privileged process bound to a privileged port. There is a big discussion in Is there a way for non-root processes to bind to "privileged" ports on Linux? which includes the solution your using among others.

Related

Haproxy gateway settings - client and server are on the same subnetwork

I'm trying to setup a haproxy gateway between server and client for full transparent proxy like below diagram. My main aim is to provide load balancing.
There is a simple application that listens port 25 in the server side. The client tries to connect port 25 on the gateway machine, and haproxy on the gateway chooses an avaliable server then redirects the connection to the server.
Network analysis of this approach produces tcp flow like diagram: The client resets the connection at the end since it doesn't send a syn packet to the server.
Is this haproxy usage true and my problem related configuation? Or should the client connect to the server directly (This doesn't make much sense to me but I'm not sure actually. If this is true then how haproxy will intervene the connection and make load balancing)?
EDIT:
I've started to think this problem is related to routing and NAT on the gateway. All of these three machines are in same subnetwork but I've added routes to the gateway for both client and server. Also rules on the gateway are:
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 0x01/0x01
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A PREROUTING -p tcp --dport 25 -j TPROXY \
--tproxy-mark 0x1/0x1 --on-port 10025
ip route flush table 100
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
Now the question is what should I do in the gateway to change "syn-ack (src: S, dst: C)" to "syn-ack (src: GW, dst: C)"?
Here is the definition of my situation.
Here comes the transparent proxy mode: HAProxy can be configured to spoof the client IP address when establishing the TCP connection to the server. That way, the server thinks the connection comes from the client directly (of course, the server must answer back to HAProxy and not to the client, otherwise it can’t work: the client will get an acknowledge from the server IP while it has established the connection on HAProxy‘s IP).
And the answer is to set ip_nonlocal_bind system control.

Configuring IP Tables

I want to make sure that the only network traffic on my linux CentOS server is my own.
All my server runs is a Tomcat instance with one servlet. This servlet takes a parameter, which is a URL to download. It will download from that url, and pass the contents back to the calling program through the usual http response.
I want to block all network traffic to this server except
1) Ability to ssh
2) Ability to download from host abc.xyz.com
3) Ability for server with IP 111.222.333.444 to download from me
Can someone please tell me the commands to do this in iptables? I tried finding this out myself but I was a bit out my depth with the lingo.
thanks
Configuring a firewall is simple, first of all select what ports you want to be open.
For example Webserver ports:
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
For example SSH port:
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
In any way your server is able to download files from other server/hosts.
3) Ability for server with IP 111.222.333.444 to download from me
I suppose that must be port 80, (or any port where the server is downloading from) if your uploading files to your website.
After these steps you need to look if the firewall is configured right:
iptables -L -n
If it's looking good then you're able to save your iptables, and restart the service.
If there is any problem configureren your firewall, please let me know.

Accessing Apache Server from a remote machine

I am using Red Hat 4.4.7-4 . I have installed Apache Server using
yum install httpd
/etc/init.d/httpd start
/etc/init.d/httpd status
httpd (pid 1371) is running...
This machine can be accesses through a VPN client using ssh terminal. When I hit
http://ip address:80
in a browser, the page doesnt load. I get the following error:
This Page Cannot Be Displayed
The system cannot communicate with the external server ( 173.39.232.226 ). The Internet server may be busy, may be permanently down, or may be unreachable because of network problems.
Please check the spelling of the Internet address entered. If it is correct, try this request later.
If you have questions, or feel this is an error, please contact your corporate network administrator and provide the codes shown below.
Notification codes: (1, GATEWAY_TIMEOUT, 173.39.232.226)
Also, below is the output of iptables
[root#blended-services-demo html]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:http
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
You probalby need to enable access to your server on port 80 as it is currently being blocked by iptables.
sudo /sbin/iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT
This will insert the rule into your iptables configuration at the start. Once you have done this and tested that it works then you should save the configuration so that it it is used next time the service starts,
sudo /sbin/service iptables save
this will write the current configuration to /etc/sysconfig/iptables.
if this dont solve your problem, i suggest you take a look here:
apache not accepting incoming connections from outside of localhost

Iptables sniffing traffic not sent to local machine

I have a switch configured to mirror all traffic to an ethernet interface of a server. I can actually see the packets received with tshark, tcpdump, etc, but iptables doesn't seem to see this traffic. My ultimate goal is to ulog syn packets for connection accounting.
I tried to place rules in PREROUTING chain, unsuccessfully.
Can iptable capture packets not sent to the local machine? If no, is there a way to do this?
Which table do you use for monitoring?
What you want to do is to use the filter table (the default one) and the FORWARDING chain: it is specifically designed to capture packets which "traverse" the machine. For instance:
iptables -A FORWARDING -p tcp --dport 80 -j LOG
The INPUT chain will capture packets from the outside destined to the local machine, and the OUTPUT chain will capture packets originating from the machine and going outside.
One side note: packets transiting through loopback go through both INPUT and OUTPUT chains.
As to PREROUTING, it is a chain meant to modify packets, if necessary, before the routing decision -- this is why, for instance, port redirection is done in there. And this is why the filter table has no hook in it: it does not make sense.
iptables will only work with IP packets somehow directed at your machine. So what you are trying to achieve will not be doable with iptables. For it to work would require that you set up your accounting machine as a router for all IP traffic.
What’s wrong with tcpdump for this task?
tcpdump -G 3600 -w tcpsyn-%FT%T.pcap tcp and 'tcp[tcpflags] & (tcp-ack|tcp-syn) = tcp-syn'
If you want all TCP initiation attempts.
tcpdump -G 3600 -w tcpsynack-%FT%T.pcap tcp and 'tcp[tcpflags] & (tcp-ack|tcp-syn) = (tcp-ack|tcp-syn)'
If you want all TCP sessions actually established.

Iptables : forward port from another server than the gateway

Here is the situation.
We have multiple server on our intranet 192.168.1.0/24
One of them is the default gateway for all of them and have two interfaces ($GATEWAY_INTERNAL_IP and $GATEWAY_EXTERNAL_IP).
We have also another server PUBLICHOST2 which has two IP as well $PUBLICHOST_EXTERNAL_IP and $PUBLICHOST_INTERNAL_IP.
We have a third server SERVER which have only one IP $PRIVIP and bind on port $PORT.
What we want is to be able to forward port $PORT on $PUBLICHOST_EXTERNAL_IP to host SERVER on $PRIVIP.
But when we do the port forwarding using iptables on PUBLICHOST2, SERVER receive the request but the response goes through the gateway and the connection is not successfull.
How can we properly do the setup so that the response can go back through PUBLICHOST2 ?
Thanks
You may need to set forwarding on for the interface. Try tne command.
sysctl -w net.ipv4.conf.eth0.forwarding=1
If you need additional help look for documentation on routeback or the Shorewall FAQ.
Well here what happens:
Client1 sends a request to PublicHost
The requests arrives and the iptables rules redirects the traffic (PAT) to the Server on the correct AppPort
Server sends back a reply to Client1 which will be routed by Gateway
Gateway is doing NAT and replaces the source IP with it's own
Client1 or Client1sGateway receives the IP packet with Gateway as the source but it expected PublicHost's IP in the source field of the IP packet.
Eventually Client1 resends the SYN/ACK (except if you're using a synproxy) to PublicHost and then drops the connection when whatever network related timer expires.
Now if you want to fix this, you should route all TCP traffic going OUT of Server and with a source port of AppPort to PublicHost.
If this doesn't work, PublicHost is not properly configured. Be sure to test the configuration with tcpdump.
I've been trying to do something similar. After running through a bunch of tutorials that never seemed to work until I Wiresharked the connection to discover that the destination address was still set to the external IP address, (exactly like you've described), I tried using the POSTROUTING chain to change the source IP address to that of the server:
iptables -t nat -A POSTROUTING -p <tcp/udp> --dport <destination_port> -j SNAT --to <$PUBLICHOST_INTERNAL_IP>
After I added that rule, the connection was forwarded into the private network and the response packets retraced the same path back to the client, rather than through the network gateway. I'm not positive what allowed the response packets back out through the firewall server, but I think it was because of the rule I already had on the INPUT chain to allow established connections:
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
The thing to be sure to keep in mind with this solution is: if you ever change the firewall server's internal IP address, then you will need to update the above POSTROUTING rule. (Needless to say, it's probably best if the firewall server has a statically assigned internal IP address).