Proposed Server iptables Firewall template to work with Cloudflare Firewall

We are using Cloudflare for CDN and DNS for security.
We want to add more security by setting up an IPtables Firewall on our dedicated server
To eliminate traffic NOT coming through Cloudflare from accessing the server and
To protect server from bots as well as many all-web scanners like censys from scanning and indexing our server’s open ports.

We would like feedback/suggestions/second set of eyes on the IPTables approach we are planning.
We are proposing the iptables setup below, which essentially allows whitelisted Cloudflare IP’s,
plus essential ones like paypal, then sets the Ports/services those IP can use.
Everything else will be DROP’d.

An ip6tables will also be setup the same way, except using the Cloudflare IP6 IP’s

I am presenting here because there is no specific guide on this subject at Cloudflare

PLEASE speak up - with kindness - if you see any errors/problems/issues with our approach
We would like to end up with a template that anyone could use

We have a Centos 7 dedicated server running Plesk 12.5 with a wordpress site on the main domain
and a few web applications on a couple of sub-domains. Nothing too fancy. NOT running firewalld.

NOTE: Using #### or XXXX in some places to denote PORT numbers we changed from
‘standard’ ports or IPs.

And finally, please be kind - our normal tech guy is not available, and my tech experience
is not quite this deep, but it needs to be done, so . . . :slight_smile:

Sid B.

================================================== Proposed IPtables Setup

  1. Initially Set A Policy for the INPUT Chain to ACCEPT Everything

    iptables -P INPUT ACCEPT

  2. Allow/Set INPUT and OUTPUT for LOCALHOST so local stuff on the server continues to operate

    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT

  3. Setup some Basic DDOS Attack Security with a few quick settings

    = Drop NULL packets - they usually indicate that your host is being scanned
    iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

    = Block syn flood attack - possible threat from denial-of-service attacks
    iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

    = Block XMAS packets - Xmas tree packet has all options set (SYN, FIN, URG and PSH).
    = receiving a large number of these then someone may be trying DOS attack
    iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

  4. Setup SSH - which we use to access server - to run from an IP or set of IPs (Ours)
    so we don’t get locked out. First we allow Access from Our internal IP’s

    = whitelist IP’s from our own network for using SSH
    iptables -I INPUT -p tcp -m multiport --dport XXX -s “XXX.XXX.XXX.[0-224]” -j ACCEPT

  5. Next we setup SSH access to drop too many access attempts - Brute Force attacks.
    Note - we change the SSH port from default 22 to XXX

    = create our 1st basic ruleset Rate Limit SSH Connections to DROP if
    = more than 3 connections per minute from an IP address.
    iptables -A INPUT -i eth0 -p tcp --dport XXX -m state --state NEW -m recent --set --name SSH
    iptables -A INPUT -i eth0 -p tcp --dport XXX -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP

    iptables -A INPUT -i eth0 -p tcp --dport XXX -m state --state NEW, ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp --sport XXX -m state --state ESTABLISHED -j ACCEPT

Note that in the rules, ‘SSH’ is the name of the list of IP addresses,
-m recent finds the IPs and, -set adds them to the ‘SSH’ list.
update checks the list and count every 60 seconds and DROPs IPs that try more than 3

  1. Let’s Accept DNS inquiries to the DNS Ports

    iptables -A INPUT -i eth0 -p tcp --dport 53 -m state --state NEW,ESTABLISHED -m tcp -j ACCEPT
    iptables -A OUTPUT -o eth0 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

  2. To make sure WE always have access, Let’s Accept Connections from our in-house IPs

    = whitelist IP’s from our own network
    iptables -I INPUT -p tcp -m multiport --dports http,https -s “XXX.XXX.XXX.[0-224]” -j ACCEPT

  3. So we don’t lose our current connection let’s ACCEPT ESTABLISHED Connections

    = Accept connections that are already ESTABLISHED Like our SSH session
    = so we don’t get disconnected
    iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

ONLY NEW connections will make it past this point

  1. Our First Major Traffic control step, let’s use a Custom Chain - called WHITELIST -
    to create a list of accepted IP’s

    = create a custom chain called WHITELIST
    iptables -N WHITELIST

  2. Pass NEW TCP connections from Good IPs XXX.XXX.XXX.XXX (arriving on interface ethX)
    to the WHITELIST chain. We can Use CDIR formats XXX.XXX.XXX.0/16 or XXX.XXX.XXX.[0-254]
    NOTE: We want to allow IPs from CloadFlare, as that is the Allowed source of our Traffic

    = WHITELIST our network –
    iptables -s XXX.XXX.XXX.0/16 -i eth0 -p tcp -m state --state NEW -j WHITELIST

    = WHITELIST Cloudflare IP’s
    iptables -s XXX.XXX.XXX.0/16 -i eth0 -p tcp -m state --state NEW -j WHITELIST

And so on, including Paypal IP’s, and those Plugin services like WordFence, WordPress,
Ninja Firewall, etc.

  1. Our SECOND major Traffic control step Let’s setup all the Ports/Services the
    WHITELIST can use:

    Such AS WEB Access - Http/Https
    = Web server rules to allow incoming HTTP and HTTPS requests. In
    iptables -A WHITELIST -i eth0 -p tcp -m multiport --dports 80,443 -j ACCEPT
    = Out
    iptables -A WHITELIST -o eth0 -p tcp -m multiport --sports 80,443 -j ACCEPT

also things like MySQL, Plesk, ftp, etc. - basically every Port/service the server
is actively setup and using now.

  1. That is all that we need to allow, so we DROP the rest

    = set policy to DROP all WHITELIST chain
    iptables -P WHITELIST DROP

    = LAST Set policies to drop everything else
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT DROP


1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.