I try to block all ports except 22, 80, and 443. I added the following rules to iptables
.
*filter
:INPUT ACCEPT [36878:18003219]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [33947:26518456]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -s MY_IP -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -j DROP
COMMIT
Port 22 is working, but Cloudflare cannot connect to the webserver. -A INPUT -j DROP
causes the problem. In fact, 443 connection does not match a rule until the end of the list.
So after a lengthy comment session, here is what we've put together:
When you enabled your custom firewall, CloudFlare reported a 504 Gateway Timeout. But notably, it said that that was the error it received from your server, not that it timed out trying to reach your server. The difference is subtle but important: This means CloudFlare was talking to your server fine, but your server was not talking to itself.
You have a web server that proxies to an internal web application running on localhost. But your custom firewall did not allow localhost connections. This is required for the web server to talk to the web app, as well as for so many other internal services to talk to each other, that every professional firewall builder you ever may use will simply allow localhost traffic without question.
(PS: You should leave ICMP enabled to prevent other sorts of breakage, such as Path MTU Discovery.)