Monday, September 26, 2016

The Definitive How-To for BOINC with SETI@HOME on Fedora / CentOS / RedHat Linux (x64 / x86)

I rediscover these steps every time I deploy a new real or virtual machine for BOINC - need to write these down once and for all. Currently participating in SETI@HOME for over 15 years and a few Large Hedron Collider (LHC) projects from the inception of LHC@HOME; here are my BOINC Stats.

I have no headless BOINCTasks PC; all computers run their own BOINC servers and command clients all on localhost.

This post is not very original; it is basically a mashup with some tweaks of (a) http://hardforum.com/showthread.php?t=1854569 and (b) http://boinc.berkeley.edu/dev/forum_thread.php?id=7358. To install boinc attached to seti@home:

Open a terminal or over ssh
(Install BOINC Compile Essentials after becoming root (because we did basic dev most of these are already installed))
su -
yum install gcc-c++ autoconf openssl-devel automake libtool libcurl-devel

(These were some other libraries I found that the configure step requested. I don’t think all of these are absolutely necessary for a basic client-only install, but who doesn’t like a configure without warnings)
yum install libGL-devel libGLU-devel freeglut-devel libXmu-devel libXi-devel libnotify-devel xcb-util-devel libjpeg-devel git

(Create boinc user, then login as boinc user)
useradd boinc
su - boinc

(Next you’ll need to git the boinc source code; when you logged in as boinc you should have been placed in boinc’s home directory (check using pwd); then create a directory for the repository; then git it)
mkdir boinc_source
git clone https://github.com/BOINC/boinc boinc_source/


(Navigate into Repo)
cd boinc_source/

(Run _autosetup)
./_autosetup

(For the configure step there are tons of options (you can look at them by searching online or ./configure --help); for this I will just use two: no server (we are not a boinc work server) and optimize (because why not))
./configure --disable-server --enable-optimize

(Now we build the monster we just created  (note – I got a few warnings which were nothing to worry about))
make

(Now we install it – I login as root for this step (exit boinc user) so that it can install boinc with the full daemon/etc.)
exit
cd /home/boinc/boinc_source
make install

Add the boinc-client service - we check and add the service if chkconfig does not see it
chkconfig --list | grep boinc
(If the above comes up empty, add it and set correct directory ownership)
chkconfig --add boinc-client
chkconfig --list | grep boinc # should produce boinc-client   0:off 1:off 2:off 3:on   4:on   5:on   6:off

(It is okay if /var/lib/boinc does not exist in the following two commands)
chown boinc /var/lib/boinc
chgrp boinc /var/lib/boinc


(Set boinc-client to start at boot and Start the boinc daemon)
chkconfig boinc-client on
service boinc-client start
service boinc-client status

(All the boinc data files end up in the boinc user home directory. Now we log back in as boinc and go there to create/modify those files for remote access)
su - boinc

(How you setup your remote login is up to you. What I do is remove the client password and the restrict access to only my BOINCTasks computer’s static IP address. This is what I show below)
vi gui_rpc_auth.cfg
Delete the password and leave only a newline (return/enter key)
Write and save the file

(Note that this next file does not yet exist – vi will create it)
vi remote_hosts.cfg
Type in your BOINCTasks PC IP address (127.0.0.1 for localhost) and the newline
Write and save the file

(Now go back to root and restart the boinc daemon)
exit
service boinc-client restart
service boinc-client status

(Now we need to add a port to firewalld so that the BOINCTasks can communicate with the boinc client)
(This is not applicable to older distros)
If your firewall is configured to allow all traffiic on localhost 127.0.0.1 this is not required.
firewall-cmd --permanent --zone=public --add-port=31416/tcp
firewall-cmd --reload

(Now your BOINCTasks should be able to connect to the computer’s IP)

To attach to SETI@Home do:

Get your account key:
boinccmd --lookup_account http://setiathome.berkeley.edu email_address password

Then attach to seti@home using your account key:

su - boinc
boinccmd --project_attach http://setiathome.berkeley.edu account_key

boinccmd --get_state

Adjust resource limits and restart. vi the following file and adjust the numbers (example below)
vi global_prefs.xml

example of global_prefs.xml:

Restart the boinc daemon, you are done:
exit
service boinc restart

Check the status - switch to boinc account.
su - boinc
boinccmd --get_project_status

======== Projects ========
1) -----------
   name: SETI@home
   master URL: http://setiathome.berkeley.edu/
   user_name: Supratim Sanyal
   team_name: The Knights Who Say Ni!
   resource share: 100.000000
   user_total_credit: 7649132.533274
   user_expavg_credit: 4777.286713
   host_total_credit: 0.000000
   host_expavg_credit: 0.000000
   nrpc_failures: 0
   master_fetch_failures: 0
   master fetch pending: no
   scheduler RPC pending: no
   trickle upload pending: no
   attached via Account Manager: no
   ended: no
   suspended via GUI: no
   don't request more work: no
   disk usage: 0.000000
   last RPC: Mon Sep 26 17:39:52 2016

   project files downloaded: 0.000000
GUI URL:
   name: Message boards
   description: Correspond with other users on the SETI@home message boards
   URL: http://setiathome.berkeley.edu/forum_index.php
GUI URL:
   name: Help
   description: Ask questions and report problems
   URL: http://setiathome.berkeley.edu/forum_help_desk.php
GUI URL:
   name: Account
   description: View your account information
   URL: http://setiathome.berkeley.edu/home.php
GUI URL:
   name: Preferences
   description: View and modify your computing preferences
   URL: http://setiathome.berkeley.edu/prefs.php?subset=global
GUI URL:
   name: Tasks
   description: View your recent tasks
   URL: http://setiathome.berkeley.edu/results.php?userid=8104231
GUI URL:
   name: Computers
   description: View a list of the computers on which you are running SETI@Home
   URL: http://setiathome.berkeley.edu/hosts_user.php?userid=8104231
GUI URL:
   name: Team
   description: View information about your team: The Knights Who Say Ni!
   URL: http://setiathome.berkeley.edu/team_display.php?teamid=30195
GUI URL:
   name: Donate
   description: Donate to SETI@home
   URL: http://setiathome.berkeley.edu/sah_donate.php
   jobs succeeded: 0
   jobs failed: 0
   elapsed time: 0.000000
   cross-project ID: 1d3ecb3f16a31376b937493d3feb0af1

Saturday, September 24, 2016

Simple Basic Working VARNISH 4.0 Configuration: default.vcl and varnish.params for a functional HTTPD web server cache for LIGHTTPD


Ever since I started maintaining a free public IP address blocklist listing sources of brute-force attacks I am seeing and putting the list up on the lighttpd web-server for anyone to use, there has been a remarkable growth of traffic that lighttpd is being asked to service.

This blocklist is based on the jail contents of fail2ban, generated hourly from fail2ban jails using a cron job, that I describe here. My fail2ban setup including automated reporting to blocklist.de over email is documented here.

Though lighttpd is not overwhelmed yet, I decided to take some load off it and put a varnish server-side cache before it, working purely off an in-memory cache since all the web-server does is provide a static page and a hourly-updated bloc-klist.

With Varnish cache delivering web pages from memory, a load test via loader.io shows 57 milliseconds average response time with  0.0 % error rate for 100 to 250 clients over 1 minute. The varnishtop screenshot at the top was taken during this test.


It took some effort to configure varnish http cache to get it to work. Here are the configuration files for varnish reverse cache and lighttpd that I am using.

My lighttpd configuration gets lighttpd to bind to and listen on the localhost (127.0.0.1) IP address on port 65481. Varnishd uses this local lighttpd server and port as the backend and serves HTTP requests from external clients on the usual port 80 on the internet-facing interfaces.

The varnish configuration below is generic, i.e. it has no dependency on lighttpd - any httpd will work as the backend of Varnish as long as Varnish knows what IP and Port Number to use as the backend.

I am using varnish version 4.0.3 and lighttpd version 1.4.41.

# varnishd -V
varnishd (varnish-4.0.3 revision b8c4a34)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2014 Varnish Software AS
# lighttpd -V
lighttpd/1.4.41 (ssl) - a light and fast webserver
Build-Date: Aug  1 2016 14:19:06

Varnish 4.0 Configuration

/etc/varnish/default.vcl



/etc/varnish/varnish.params



Lighttpd Configuration


Friday, September 23, 2016

Got Fail2Ban working? Have a Web Server running? Post a public blocklist for others to use!

So I have fail2ban working, reporting happily to blocklist.de, as documented in this post.

I also happen to have lighthttpd web server running on the server. The fail2ban-client tool that is included with fail2ban can list out all the IP addresses in a jail. So I wrote a simple script to dump the banned IPs in the fail2ban jail into a file in a location under the web server's root. Then, adding it to cron, I have a free brute force attack source public IP address blocklist based on real brute-force attacks on my server. Others can use this list as one of the sources of bad IP addresses to block on their own server.

Here is the little script:


And here is the cron job file saved in /etc/cron.d/dump-fail2ban-blocklist


Remember - files in the /etc/cron.d directory should not have write permissions, i.e. the permissions on /etc/cron.d/dump-fail2ban-blocklist should be:

# ls -l /etc/cron.d/dump-fail2ban-blocklist
-r-------- 1 root root 284 Sep 23 17:22 /etc/cron.d/dump-fail2ban-blocklist



Tuesday, September 20, 2016

FAIL2BAN FOR CENTOS 7 WITH IPSET FILTERING FOR INTRUSION IP ADDRESS BLOCKING AND FEEDBACK TO BLOCKLIST.DE

This is a quick recap of how I set up fail2ban with real-time reporting to blocklist.de from my public internet-facing Virtual Private Server (sanyalnet-cloud-vps.freeddns.org) running CentOS 7.

Fail2ban continues to provide a robust first line of defense against the numerous dictionary and ddos or brute force attacks faced by any internet-facing cloud server. blocklist.de has been providing a very valuable blacklist for a long time for free, and I wanted to take this opportunity to contribute back to blocklist.de as well.

Right after installing an operating system and bringing it up, any new cloud server open to the internet should be hardened first. For my CentOS 7 installation, I found and followed a great set of basic hardening instructions at the highon.coffee blog and also made more tweaks that I documented here.

Then set up your internet email service. I installed and configured my email service to use postfix for SMTP and dovecot for POP and IMAP. I used the awesome instructions here to do so.

Fail2ban defaults to sending emails from the address of "fail2ban@<hostname>" and there is no need to change this behavior. A quick way to validate your email MTA is to install the mailx utility and confirm that outgoing emails are being sent successfully - you can send a email from the server to your gmail account, for example.

I then registered an account at blocklist.de and added my server. While adding the server, provide your current IP (dynamic IPs are okay as blocklist provides a separate email address for reporting intrusions on a server with dynamic IP). Also leave the API Key field empty - it will be filled in for you later.

blocklist.de add server form

I configured fail2ban to use ipset (instead of, and better than, iptables) to keep track of addresses to block. Check if you have ipset installed, and if not, install the ipset packages using yum install ipset. You should have the packages similar to the following installed to proceed.

# rpm -qa | grep ipset
ipset-6.19-4.el7.x86_64
ipset-libs-6.19-4.el7.x86_64

As the attackers started coming in fast and furious, fail2ban was the logical next step. Installing fail2ban is a breeze, thanks to its easy availability from the epel repository. The three steps below are all that are needed to install and bring up the initial configuration of fail2ban and get it ready for modifications needed to use ipset and send intrusion activity reports to blocklist.de.

# yum -y install epel-release
# yum -y install fail2ban
# systemctl enable fail2ban

Once the default fail2ban configuration is up and running with ipset, I created a /etc/fail2ban/jail.local file that overrides a few configuration items with what I need.
  • Default ban action is iptables-ipset-proto4
  • Since I use the free and very nice Uptime Robot service to monitor my servers, I whitelisted the Uptime Robot IPs that reach out to my server often enough to be flagged as intrusions with failed logon attempts by fail2ban. The list of IP addresses that Uptime Robot's robots use are conveniently listed on the Locations and IPs page on Uptime Robot web-site.
  • Tweaked findtime, bantime and maxretry a bit. I use a ban time of 48 hours only because blocklist.de automatically un-bans IP addresses 48 hours after adding them to their banned IP block list.
  • Adjusted destemail and sender email addresses to match with my account at blocklist.de
  • Adjusted the action to be email with log entries, i.e. %(action_mwl)s
  • Enabled the fail2ban intrusion reporting filters corresponding to the services provided by my server - ssh, postfix, sendmail and dovecot.
Here is my complete /etcfail2ban/jail.local file:


The results can be seen readily if the server name is googled. Also look at your /var/log/maillog and /var/log/fail2ban.log to verify everything is working as expected.


You can download a complete tarball of my /etc/fail2ban directory including default and custom configuration files that report intrusions to blocklist.de from my google drive.







Thursday, September 15, 2016

Free Online Public FORTUNE - COWSAY Server : Fun with TELNET and C/C++ Linux Multi-threaded Socket Server Programming (CentOS 7)

 ________________________________________
/ Necessity is the plea for every        \
| infringement of human freedom. It is   |
| the argument of tyrants; it is the     |
\ creed of slaves. -- William Pitt, 1783 /
 ----------------------------------------
    \               ,-----._
  .  \         .  ,'        `-.__,------._
 //   \      __\\'                        `-.
((    _____-'___))                           |
 `:='/     (alf_/                            |
 `.=|      |='                               |
    |)   O |                                  \
    |      |                               /\  \
    |     /                          .    /  \  \
    |    .-..__            ___   .--' \  |\   \  |
   |o o  |     ``--.___.  /   `-'      \  \\   \ |
    `--''        '  .' / /             |  | |   | \
                 |  | / /              |  | |   mmm
                 |  ||  |              | /| |
                 ( .' \ \              || | |
                 | |   \ \            // / /
                 | |    \ \          || |_|
                /  |    |_/         /_|
               /__/


Open a terminal or a command prompt, enter telnet sanyalnet-cloud-vps.freeddns.org and press Enter again quickly. A random fortune cookie message will be returned to you, formatted by cowsay.


Do it again. A different random cowsay formatted fortune cookie will be presented to you.


These are delivered by a little Linux server daemon "cowsayd" I wrote in C for really no good reason in the spirit of fortune and cowsay. Running on my CentOS 7 hobbyist VPS, the publicly accessible daemon serves cookies on the standard TELNET TCP port 23 from the Linux fortune database, which is based on Ken Arnold's BSD implementation.

After a connection is received and accepted, I require some input from the client (just pressing the Enter key suffices) before sending back a cowsay formatted fortune cookie. This is an attempt at gracefully handling the continuous connections from automated bots which are probably looking for a "username:", "login:" or some such prompt and rarely send any inputs. So I hope mostly humans will read what is shown on the screen ("Enter anything to hear the cow speak.") and react correctly to receive a fortune-cowsay message for fun.

The C / C++ program is based off my Brain-damaged http 410 server with the same features as discussed there, but with a couple of important differences:
  • This fortune/cowsay server does not need to listen to connections from more than one port, as it servers clients on just one port. Hence, the select() system call and associated family of macros are not needed by the fortune+cowsay server.
  • The server works by invoking a shell command that in turn executes fortune and cowsay and returns the output back to the server, which passes it on to the client and closes the connection. The shell command is invoked using popen() which is thread-safe in Linux, and works well for getting a message from fortune/cowsay.
  • The use of pthread_attr_setdetachstate with PTHREAD_CREATE_DETACHED is demonstrated. This server spawns a thread to service every connection and the spawned thread exits after servicing a connection. The main thread never waits to join the spawned threads. If we do not create detached threads for this scenario, memory usage will keep increasing every time a thread is spawned since the default attribute of PTHREAD_CREATE_JOINABLE will never release all service thread resources becuase it expecting the main thread to join and ask for the return value.
  • Obtaining the client IP address is demonstrated using the inet_ntop() function.
  • It logs into the same file as sshd (usually /var/log/secure) in a format designed for abusers to be picked up and banned by fail2ban if installed. fail2ban is configured on my server to also automatically email blocklist.de for more general dissemination of telnet spammers. I also maintain a blocklist file free for public use.
Both fortune and cowsay need be installed and working for this server to deliver the messages. I describe how to install them later in this article (see "How to install Fortune and Cowsay on CentOS 7" below.)

To compile the cowsayd server, we need to include the -lpthread switch on the gcc command line, since it is a multi-threaded server.

  • gcc -o cowsayd -lpthread cowsayd.c

    Once compiled, copy the binary to the directory  /usr/local/bin.

    The server is designed to run continuously. Starting it up at boot time is done by a custom init script in the /etc/init.d directory. The server logs to syslog, check /var/log/messages for log output for troubleshooting,


    Here is the complete source code of cowsayd.c.



    The init script I use to start, restart or stop the cowsayd daemon follows. Copy this to /etc/init.d/ and make it executable using chmod +x /etc/init.d/cowsayd and then chkconfig --add cowsayd to add it to the chkconfig daemon management system. If correctly done, chkconfig --list will show the cowsayd daemon and the runlevels it is enabled for. chkconfig cowsayd on will enable starting up the daemon on reboot.

    The /etc/init.d/cowsayd script is below:



    HOW TO INSTALL FORTUNE and COWSAY on CentOS 7

     _________________________________________
    / Did you hear that Captain Crunch, Sugar \
    | Bear, Tony the Tiger, and Snap, Crackle |
    | and Pop were all murdered recently...   |
    | Police suspect the work of a cereal     |
    \ killer!                                 /
     -----------------------------------------
        \               ,-----._
      .  \         .  ,'        `-.__,------._
     //   \      __\\'                        `-.
    ((    _____-'___))                           |
     `:='/     (alf_/                            |
     `.=|      |='                               |
        |)   O |                                  \
        |      |                               /\  \
        |     /                          .    /  \  \
        |    .-..__            ___   .--' \  |\   \  |
       |o o  |     ``--.___.  /   `-'      \  \\   \ |
        `--''        '  .' / /             |  | |   | \
                     |  | / /              |  | |   mmm
                     |  ||  |              | /| |
                     ( .' \ \              || | |
                     | |   \ \            // / /
                     | |    \ \          || |_|
                    /  |    |_/         /_|
                   /__/


    All CentOS package installations are usually via the yum tool. Use yum install <rpm-filename> to install RPM packages.

    The Fortune RPM fortune-mod-1.99.1-17.el7.x86_64.rpm is easily available from the EPEL repository. If you have not added the EPEL repository already follow these steps:

    • head over to http://dl.fedoraproject.org/pub/epel/7/x86_64/e and download the latest epel-release*.rpm  (epel-release-7-8.noarch.rpm at the time of writing).
    • Install and enable the EPEL release repository: 
      • rpm -Uvh epel-release*rpm
    With EPEL repository enabled, fortune can be simply installed using:
    • yum install fortune-mod
    Cowsay is implemented in perl, and is therefore a set of perl scripts with no dependency on architecture as long as there is a usable perl interpreter installed, which should be the case with most installations of CentOS. If perl is not available, install perl first using yum install perl.

    To install cowsay, you need cowsay-3.03-20.el7.noarch.rpm, and optionally cowsay-beefymiracle-1.0-6.fc24.noarch.rpm and cowsay-morecows-1.0-11.4.casjay.el7.x86_64.rpm. The latter two provide various additional cows and other assorted animal art.

    With the EPEL repository enabled, cowsay can be easily installed using:

    • yum install cowsay

    Then yum install the beefymiracle and morecows RPMs - if the links above do not work, use the download link to my google drive at the bottom of this post.

    HOW TO ENABLE FORTUNE - COWSAY MESSAGE ON LOGIN

     _________________________________________
    / We are preparing to think about         \
    | contemplating preliminary work on plans |
    | to develop a schedule for producing the |
    | 10th Edition of the Unix Programmers    |
    \ Manual. -- Andrew Hume                  /
     -----------------------------------------
     \                   .,
       \         .      .TR   d'
         \      k,l    .R.b  .t .Je
           \   .P q.   a|.b .f .Z%
               .b .h  .E` # J: 2`     .
          .,.a .E  ,L.M'  ?:b `| ..J9!`.,
           q,.h.M`   `..,   ..,""` ..2"`
           .M, J8`   `:       `   3;
       .    Jk              ...,   `^7"90c.
        j,  ,!     .7"'`j,.|   .n.   ...
       j, 7'     .r`     4:      L   `...
      ..,m.      J`    ..,|..    J`  7TWi
      ..JJ,.:    %    oo      ,. ....,
        .,E      3     7`g.M:    P  41
       JT7"'      O.   .J,;     ``  V"7N.
       G.           ""Q+  .Zu.,!`      Z`
       .9.. .         J&..J!       .  ,:
          7"9a                    JM"!
             .5J.     ..        ..F`
                78a..   `    ..2'
                    J9Ksaw0"'
                   .EJ?A...a.
                   q...g...gi
                  .m...qa..,y:
                  .HQFNB&...mm
                   ,Z|,m.a.,dp
                .,?f` ,E?:"^7b
                `A| . .F^^7'^4,
                 .MMMMMMMMMMMQzna,
             ...f"A.JdT     J:    Jp,
              `JNa..........A....af`
                   `^^^^^'`


    To get a mood-lifting fortune-cowsay message every time you log in, create a file /etc/profile.d/custom.sh with the following contents.



    DOWNLOAD

    You can download everything you need for free, including the cowsayd source, binary, init script, login script and Fortune and Cowsay RPMs for CentOS 7 from my google drive.



    Thursday, September 1, 2016

    Centos 7 Network Hardening: How to Protect Your Server from Basic Network Attacks using IPTABLES Firewall

    Linux iptables, included in Centos 7 distribution, provides a mechanism to block basic network attacks. This is a guide to set up basic iptables firewall rules to protect your server from some of the most common and simplest network attacks.



    Since you are here reading this, I assume you already have iptables installed and running, i.e. the command systemctl status iptables produces an output similar to this:

    iptables.service - IPv4 firewall with iptables
       Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
       Active: active (exited) since Mon 2016-08-22 23:37:19 UTC; 1 weeks 2 days ago
     Main PID: 598 (code=exited, status=0/SUCCESS)
       CGroup: /system.slice/iptables.service

    Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.

    Also disable the Centos 7 firewalld daemon. It attempts to provide an interface to manipulating iptables which I do not want and do not use at all.

    # systemctl stop firewalld
    # systemctl disable firewalld

    The first step now is to examine your existing rules with line numbers.

    # iptables -nL --line-numbers

    If you have no rules defined, you will see empty lists:

    Chain INPUT (policy ACCEPT)
    num  target     prot opt source               destination

    Chain FORWARD (policy ACCEPT)
    num  target     prot opt source               destination

    Chain OUTPUT (policy ACCEPT)
    num  target     prot opt source               destination

    Otherwise, if some rules are defined, you will see them with line numbers, as in the following example of what I see. Note: I use fail2ban and custom blocklist scripts; the following example includes the resulting rules.

    Chain INPUT (policy ACCEPT)
    num  target     prot opt source               destination
    1    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 110,995,143,993,587,465,4190 match-set f2b-dovecot src reject-with icmp-port-unreachable
    2    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587,220,993,110,995 match-set f2b-postfix-sasl src reject-with icmp-port-unreachable
    3    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix src reject-with icmp-port-unreachable
    4    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-sendmail-reject src reject-with icmp-port-unreachable
    5    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix-rbl src reject-with icmp-port-unreachable
    6    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 587,465,25 match-set f2b-sendmail-auth src reject-with icmp-port-unreachable
    7    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 8080 match-set f2b-squid src reject-with icmp-port-unreachable
    8    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd-ddos src reject-with icmp-port-unreachable
    9    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd src reject-with icmp-port-unreachable
    10   ACCEPT     all  --  64.137.248.161       0.0.0.0/0
    11   DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set blacklist src
    12   DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set blacklistnet src
    13   IP4BOGONS  all  --  0.0.0.0/0            0.0.0.0/0
    14   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 110,995,143,993,587,465,4190 match-set f2b-dovecot src reject-with icmp-port-unreachable
    15   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-sendmail-reject src reject-with icmp-port-unreachable
    16   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587,220,993,110,995 match-set f2b-postfix-sasl src reject-with icmp-port-unreachable
    17   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 587,465,25 match-set f2b-sendmail-auth src reject-with icmp-port-unreachable
    18   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix-rbl src reject-with icmp-port-unreachable
    19   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 8080 match-set f2b-squid src reject-with icmp-port-unreachable
    20   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 25,465,587 match-set f2b-postfix src reject-with icmp-port-unreachable
    21   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd-ddos src reject-with icmp-port-unreachable
    22   REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22 match-set f2b-sshd src reject-with icmp-port-unreachable
    23   ACCEPT     all  --  64.137.248.161       0.0.0.0/0
    24   DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set block src
    25   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 state NEW
    26   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x3F
    27   DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x00
    28   DROP       all  -f  0.0.0.0/0            0.0.0.0/0
    29   ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    30   ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
    31   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
    32   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:23
    33   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:25
    34   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:53
    35   ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53
    36   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:80
    37   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:110
    38   ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:123
    39   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:143
    40   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:443
    41   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:465
    42   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:587
    43   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:993
    44   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:995
    45   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:4190
    46   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:8080
    47   ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:65514
    48   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:65515
    49   REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

    Chain FORWARD (policy ACCEPT)
    num  target     prot opt source               destination
    1    REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

    Chain OUTPUT (policy ACCEPT)
    num  target     prot opt source               destination
    1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

    Chain IP4BOGONS (1 references)
    num  target     prot opt source               destination
    1    RETURN     all  --  10.0.0.0/8           0.0.0.0/0
    2    RETURN     all  --  172.16.0.0/12        0.0.0.0/0
    3    RETURN     all  --  192.168.0.0/16       0.0.0.0/0
    4    DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set fullbogons-ipv4 src

    In any case, we start by inserting a rule at the top of, i.e. line number 1, the ACCEPT list to drop fragmented packets. This blocks IP fragmentation exploits like IP fragment overlapped (teardrop), IP fragmentation buffer full, IP fragment overrun, IP fragment too many data-grams, IP fragment incomplete, IP Fragment Too Small and similar attacks. We use the -I switch with iptables to insert a rule at a position 1.

    # iptables -I INPUT 1 -f -j DROP

    Next, we stop Null Scans, which are basically a bunch of TCP packets with sequence number 0 and no flags set. Such packets are not used in proper network communications, and are used to find open ports or holes by hackers. The following command will insert the rule at the top of the ACCEPT table, pushing the existing rules down by one line.

    # iptables -I INPUT 1 -p tcp --tcp-flags ALL NONE -j DROP

    We next stop TCP "Christmas Tree" packets - unusual packets that have all flags set. These packets are used by hackers to explore the security and features of servers, and often provide clues to the underlying operating system because operating systems react differently to such packets. Again we insert this rule at the top (line number 1), pushing existing rules down.

    # iptables -I INPUT 1 -p tcp --tcp-flags ALL ALL -j DROP

    Finally we attempt to check TCP SYN Flood attacks by inserting a rule at the top.

    # iptables -I INPUT 1 -p tcp ! --syn -m state --state NEW -j DROP

    After executing these four commands, the first four rules in the ACCEPT change should show the resulting iptables firewall rules, followed by whatever other rules existed before.

    # iptables -nL --line-numbers
    Chain INPUT (policy ACCEPT)
    num  target     prot opt source               destination
    1    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:!0x16/0x02 state NEW
    2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x3F/0x3F
    3    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x3F/0x00
    4    DROP       all  -f  0.0.0.0/0            0.0.0.0/0
    ...
    ...
    ...

    Making it permanent

    We need to make the changes permanent, i.e. persistent across system restarts and reboots. On my server, iptables starts up on reboot using the default rules file /etc/sysconfig/iptables and then eventually other applications add what they need later on (e.g. a script I run to block of malware / attack sources based on publicly available blocklists, fail2ban jails created by fail2ban, etc.).

    Therefore, I just saved the four rules in the default iptables system configuration file /etc/sysconfig/iptables


    Finally, please make sure your /etc/sysctl.conf file has some server hardening parameters, including for securing your network. Here is mine.





    Starter /etc/sysconfig/iptables

    You can use the following iptables as the starting point. Simply copy and put it into /etc/sysconfig/iptables and then adjust the ports that it opens up for the services your server provides.