Secure Raspberry Pi with iptables, PSAD, Fail2ban and OSSEC

Read Time:11 Minute, 59 Second

Disable ping

$ echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

 

Install iptables and iptables-persistent

$ sudo apt-get install iptables iptables-persistent
$ sudo service iptables-persistent start

 

Create shell script

$ nano reset_iptables.sh
#!/usr/bin/env bash
iptables -F
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -A INPUT -f -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
#
# PACKETS chain
#
iptables -N PACKET
iptables -A PACKET -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j ACCEPT
iptables -A PACKET -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK RST -m limit --limit 1/sec -j ACCEPT
#limit ping to 1 per second
#iptables -A INPUT -p icmp -j DROP
#iptables -A PACKET -p icmp -m icmp --icmp-type 8 -m limit --limit 1/sec -j ACCEPT
#
# STATE_TRACK chain (connection tracking)
#
iptables -N STATE_TRACK
iptables -A STATE_TRACK -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A STATE_TRACK -m state --state INVALID -j DROP
#
# PORTSCAN chain (drop common attacks)
#
iptables -N PORTSCAN
iptables -A PORTSCAN -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ALL ALL -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ALL NONE -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
iptables -A PORTSCAN -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

# Disable ping response
iptables -A OUTPUT -p icmp -o eth0 -j ACCEPT
iptables -A INPUT -p icmp -j DROP

#allow all outgoing access
iptables -A OUTPUT -o eth0 -j ACCEPT
iptables -I INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
$ sudo chmod a+x reset_iptables.sh
$ sudo ./reset_iptables.sh

 

Install PSAD (Port Scan Attack Detection)

References:

$ wget http://cipherdyne.org/psad/download/psad-2.4.3.tar.gz
$ tar xvfz psad-2.4.3.tar.gz
$ cd psad-2.4.3
$ sudo ./install.pl

Set configurations

$ sudo nano /etc/psad/psad.conf
EMAIL_ADDRESSES psad@loopback; # Don't want to receive any email
HOSTNAME raspberrypi; # Set to hostname
HOME_NET 192.168.1.0/24; # Set to internal IP
HTTP_PORTS 8080; # Set custom HTTP port
SHELLCODE_PORTS !8080; # Set custom HTTP port
ENABLE_AUTO_IDS Y; # Set to automatically configure iptables
AUTO_IDS_DANGER_LEVEL 1; # Set to 1 for strict
AUTO_BLOCK_TIMEOUT 999999999; # Make permanent
ENABLE_AUTO_IDS_EMAILS N;
IPT_AUTO_CHAIN1 DROP, src, filter, INPUT, 1, PSAD_BLOCK_INPUT, 1;
#IPT_AUTO_CHAIN2 DROP, dst, filter, OUTPUT, 1, PSAD_BLOCK_OUTPUT, 1;
#IPT_AUTO_CHAIN3 DROP, both, filter, FORWARD, 1, PSAD_BLOCK_FORWARD, 1;

Set IP address that to be ignored

$ nano /etc/psad/auto_dl
192.168.1.0/24 0; #ignore interal ip
221.229.1.0/24 5; # permanent ban
$ sudo psad --sig-update
$ sudo service psad restart
$ sudo service psad status

 

Install Fail2ban

References:

$ sudo apt-get install fail2ban postfix

Set configurations

$ sudo nano /etc/fail2ban/jail.conf
# Fail2Ban configuration file.
#
# This file was composed for Debian systems from the original one
#  provided now under /usr/share/doc/fail2ban/examples/jail.conf
#  for additional examples.
#
# To avoid merges during upgrades DO NOT MODIFY THIS FILE
# and rather provide your changes in /etc/fail2ban/jail.local
#
# Author: Yaroslav O. Halchenko <debian@onerussian.com>
#
# $Revision$
#

# The DEFAULT allows a global definition of the options. They can be overridden
# in each jail afterwards.

[DEFAULT]

# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.0/24 192.168.1.0/24
bantime  = -1
maxretry = 3

# "backend" specifies the backend used to get files modification. Available
# options are "gamin", "polling" and "auto".
backend = auto

#
# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = fail2ban@loopback

#
# ACTIONS
#

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = iptables-multiport

# email action. Since 0.8.1 upstream fail2ban uses sendmail
# MTA for the mailing. Change mta configuration parameter to mail
# if you want to revert to conventional 'mail'.
mta = sendmail

# Default protocol
protocol = tcp

# Specify chain where jumps would need to be added in iptables-* actions
chain = INPUT

#
# Action shortcuts. To be used to define action parameter

# The simplest action to take: ban only
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
              %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
               %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]

# Choose default action.  To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_)s

#
# JAILS
#

# Next jails corresponds to the standard configuration in Fail2ban 0.6 which
# was shipped in Debian. Enable any defined here jail by including
#
# [SECTION_NAME]
# enabled = true

#
# in /etc/fail2ban/jail.local.
#
# Optionally you may override any other parameter (e.g. banaction,
# action, port, logpath, etc) in that section within jail.local

[ssh]

enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3


[ssh-ddos]

enabled  = true
port     = ssh
filter   = sshd-ddos
logpath  = /var/log/auth.log
maxretry = 3

#
# HTTP servers
#

[apache]

enabled  = true
port     = http,https
filter   = apache-auth
logpath  = /var/log/apache*/*error.log
maxretry = 3

# default action is now multiport, so apache-multiport jail was left
# for compatibility with previous (<0.7.6-2) releases
[apache-multiport]

enabled   = true
port      = http,https
filter    = apache-auth
logpath   = /var/log/apache*/*error.log
maxretry  = 3

[apache-noscript]

enabled  = true
port     = http,https
filter   = apache-noscript
logpath  = /var/log/apache*/*error.log
maxretry = 3

[apache-overflows]

enabled  = true
port     = http,https
filter   = apache-overflows
logpath  = /var/log/apache*/*error.log
maxretry = 2

[invalidmethod]

enabled  = true
port     = http,https
filter	 = invalidmethod
logpath	 = /var/log/apache*/*access.log
findtime = 10800
maxretry = 3

#
# FTP servers
#

[vsftpd]

enabled  = true
port     = ftp,ftp-data,ftps,ftps-data
filter   = vsftpd
logpath  = /var/log/vsftpd.log
# or overwrite it in jails.local to be
# logpath = /var/log/auth.log
# if you want to rely on PAM failed login attempts
# vsftpd's failregex should match both of those formats
maxretry = 3


#
# Mail servers
#

[postfix]

enabled  = true
port     = smtp,ssmtp
filter   = postfix
logpath  = /var/log/mail.log



 

Update iptables-multiport.conf to set persistent.bans

$ sudo nano /etc/fail2ban/action.d/iptables-multiport.conf
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
# $Revision$
#

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = iptables -N fail2ban-<name>
              iptables -A fail2ban-<name> -j RETURN
              iptables -I <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
	      cat /etc/fail2ban/persistent.bans | awk '/^fail2ban-<name>/ {print $2}' \
               | while read IP; do iptables -I fail2ban-<name> 1 -s $IP -j DROP; done

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
             iptables -F fail2ban-<name>
             iptables -X fail2ban-<name>

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = iptables -n -L <chain> | grep -q fail2ban-<name>

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    <ip>  IP address
#          <failures>  number of failures
#          <time>  unix timestamp of the ban time
# Values:  CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
	echo "fail2ban-<name> <ip>" >> /etc/fail2ban/persistent.bans

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    <ip>  IP address
#          <failures>  number of failures
#          <time>  unix timestamp of the ban time
# Values:  CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
		sed -i /<ip>/d /etc/fail2ban/persistent.bans

[Init]

# Defaut name of the chain
#
name = default

# Option:  port
# Notes.:  specifies port to monitor
# Values:  [ NUM | STRING ]  Default:
#
port = ssh

# Option:  protocol
# Notes.:  internally used by config reader for interpolations.
# Values:  [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcp

# Option:  chain
# Notes    specifies the iptables chain to which the fail2ban rules should be
#          added
# Values:  STRING  Default: INPUT
chain = INPUT

Add extra filter to prevent unauthorised access to http

$ sudo nano /etc/fail2ban/filter.d/invalidmethod.conf
# Fail2Ban configuration file
#
#
# $Revision: 1 $
#

[Definition]
# Option: failregex Notes.: Regexp to catch invalid method 
# abovementioned bots. Values: TEXT
#
failregex = ^<HOST> .*\"(GET|HEAD|PUT|POST) [^\"]+\" 401.*

# Option: ignoreregex Notes.: regex to ignore. If this regex 
# matches, the line is ignored. Values: TEXT
#
ignoreregex = ^<HOST> .*\"(GET|POST) [^\"]+\" 200.*

$ sudo nano /etc/fail2ban/jail.conf
[invalidmethod]

enabled  = true
port     = http,https
filter	 = invalidmethod
logpath	 = /var/log/apache*/*access.log
findtime = 10800
maxretry = 3
$ sudo /etc/init.d/fail2ban restart

 

Check jail is configured correctly

$ sudo fail2ban-client status
Status
|- Number of jail:     	9
`- Jail list:  		invalidmethod, apache-noscript, postfix, ssh-ddos, apache-multiport, vsftpd, ssh, apache-overflows, apache

 

Install OSSEC (Open Source HIDS SECurity)

References

$ sudo apt-get install build-essential inotify-tools
$ wget https://bintray.com/artifact/download/ossec/ossec-hids/ossec-hids-2.8.3.tar.gz
$ tar -zxf ossec-hids-2.8.3.tar.gz
$ cd ossec-hids-2.8.3
$ sudo ./install.sh
(en/br/cn/de/el/es/fr/hu/it/jp/nl/pl/ru/sr/tr) [en]:

OSSEC HIDS v2.8 Installation Script - http://www.ossec.net

 You are about to start the installation process of the OSSEC HIDS.
 You must have a C compiler pre-installed in your system.
 If you have any questions or comments, please send an e-mail
 to dcid@ossec.net (or daniel.cid@gmail.com).

  - System: Linux kuruji 3.13.0-36-generic
  - User: root
  - Host: kuruji

  -- Press ENTER to continue or Ctrl-C to abort. --

1- What kind of installation do you want (server, agent, local, hybrid or help)? local

  - Local installation chosen.

2- Setting up the installation environment.

  - Choose where to install the OSSEC HIDS [/var/ossec]:
  - Installation will be made at  /var/ossec .

3- Configuring the OSSEC HIDS.

  3.1- Do you want e-mail notification? (y/n) [y]:

  - What's your e-mail address? sammy@example.com
  - We found your SMTP server as: mail.example.com.
  - Do you want to use it? (y/n) [y]:

--- Using SMTP server:  mail.example.com.

  3.2- Do you want to run the integrity check daemon? (y/n) [y]:

- Running syscheck (integrity check daemon).

  3.3- Do you want to run the rootkit detection engine? (y/n) [y]:

- Running rootcheck (rootkit detection).

  3.4- Active response allows you to execute a specific command based on the events received.  

   Do you want to enable active response? (y/n) [y]:

   Active response enabled.

  Do you want to enable the firewall-drop response? (y/n) [y]:

- firewall-drop enabled (local) for levels >= 6

   - Default white list for the active response:
      - 8.8.8.8
      - 8.8.4.4

   - Do you want to add more IPs to the white list? (y/n)? [n]:

3.6- Setting the configuration to analyze the following logs:
    -- /var/log/auth.log
    -- /var/log/syslog
    -- /var/log/dpkg.log

 - If you want to monitor any other file, just change
   the ossec.conf and add a new localfile entry.
   Any questions about the configuration can be answered
   by visiting us online at http://www.ossec.net .


   --- Press ENTER to continue ---

 - System is Debian (Ubuntu or derivative).
 - Init script modified to start OSSEC HIDS during boot.

 - Configuration finished properly.

 - To start OSSEC HIDS:
                /var/ossec/bin/ossec-control start

 - To stop OSSEC HIDS:
                /var/ossec/bin/ossec-control stop

 - The configuration can be viewed or modified at /var/ossec/etc/ossec.conf

    ---  Press ENTER to finish (maybe more information below). ---
$ sudo /var/ossec/bin/ossec-control start
$ cd /var/www
$ git clone https://github.com/ossec/ossec-wui.git ossec
$ cd ossec
$ ./setup.sh

Open http://{http_host}/ossec

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.