securing a linux workstation

  • @name: securing a linux workstation
    @author: c0re 
    @year: 2011
    @version: 1.0 <2011.03.27>
    
    
     [TOC - TableOfContent]
    -------------------------
     0x00	Introduction
     0x01	Basics
     0x02	Hardening SSH
     0x03	Simple Firewall
     0x04	Port Knocking
     0x05	ARPalert
     0x06	Final words
    -------------------------
    
    
    
    --[0x00 - Introduction]--
    
    this paper should cover most of the basic stuff to secure your linux home workstation and your LAN. 
    it is in no way advanced (you can do too many things to 'lock-down' your system or monitor your LAN), but it should get you the idea of what you can do.
    I'm using debian(squeeze) to demonstrate things in this paper, so the commands and locations may vary on other distros - this shouldn't be a copy&paste anyway..
    please note that I can't explain every parameter used in the commands below as this would take another 150+ lines of writing, just read the man pages on those commands/parameters.
    
    
    
    
    --[0x01 - Basics]--
    
    1. before we can start to secure our system we need to make sure that all unnecessary software is removed from it.
    start be going through all installed software and remove those you don't need. you can list the currently dpkg installed software by:
    	root@c0re:/# dpkg --list
    
    2. disable DHCP whenever possible, start planning your LAN with a limited range of IPs (Class C Network). a sample IP assigning scheme can look like this:
    	192.168.0.1 - 192.168.0.9	#1-9 for you and your roommate (pc,iphone,pda..)
    	192.168.0.10 - 192.168.0.19	#10-19 hardware devices (printers,xbox,ps3,..)
    	192.168.0.20 - 192.168.0.39	#20-39 frinds/people who come to your home regularly
    	192.168.0.254			#your router/modem
    
    you can set static IPs in /etc/network/interfaces and DNS server in /etc/resolv.conf
    	root@c0re:/# cat /etc/network/interfaces
    	#loopback	
    	auto lo
    	iface lo inet loopback
    	#home-LAN
    	auto eth0
    	iface eth0 inet static
    	  address 192.168.0.1
    	  network 192.168.0.0
    	  netmask 255.255.255.0
    	  gateway 192.168.0.254
    
    ..and do yourself a favor and remove the network-manager, it causes a lot of trouble and you really don't need it.
     
    3. since we expect our box to be offline/shutdown for at least some time each day we set some anacron-jobs (cron is more for 24x7 systems) to securely destroy data we don't need anymore.
    a few examples here, just define some jobs you need.
    	root@c0re:/# cat /etc/anacrontab
    	# /etc/anacrontab: configuration file for anacron
    	# See anacron(8) and anacrontab(5) for details.
    	SHELL=/bin/sh
    	PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    	# These replace cron's entries
    	1	5	cron.daily	 nice run-parts --report /etc/cron.daily
    	7	10	cron.weekly	 nice run-parts --report /etc/cron.weekly
    	@monthly	15	cron.monthly nice run-parts --report /etc/cron.monthly
    	# shred all files in /tmp and /var/tmp not used since 3 days 
    	1	11	shred.tmp	 find /tmp -type f -atime +3 -exec shred -f -u -z {} +
    	1	12	shred.var.tmp	 find /var/tmp -type f -atime +3 -exec shred -f -u -z {} +
    	# shred roots .bash_history after 2 days
    	2	13	shred.bash.history find /root/.bash_history -type f -exec shred -f -u -z {} + && touch /root/.bash_history
    
    4. you should also consider mounting /tmp as 'noexec'. you can do this by changing the entry in /etc/fstab from 'exec' to 'noexec'
    (assuming that you don't have just a single partition for your whole file system...)
    	root@c0re:/# vi /etc/fstab
    	#Entry for /dev/sdc5 :	
    	UUID=f4e1b18a-62be-4f60-9b0d-5ee81005ea66	/tmp	ext4	noatime,noexec 0 0
    
    5. check for open ports and services listening on your loopback interface and close all you don't really need. if you don't need ipv6 disable it!
    	root@c0re:/# netstat -tulpen
    	Active Internet connections (only servers)
    	Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
    	tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      0          7032        2105/cupsd      
    	tcp        0      0 0.0.0.0:22		    0.0.0.0:*               LISTEN      0          6592        1925/sshd       
    	udp        0      0 0.0.0.0:631             0.0.0.0:*                           0          7035        2105/cupsd      
    	udp        0      0 0.0.0.0:51789           0.0.0.0:*                           104        6799        1998/avahi-daemon: 
    	udp        0      0 0.0.0.0:5353            0.0.0.0:*                           104        6798        1998/avahi-daemon:
    	
    	root@c0re:/# nmap -v -sT localhost
    	Starting Nmap 5.00 ( http://nmap.org ) at 2011-03-21 14:33 CET
    	NSE: Loaded 0 scripts for scanning.
    	Initiating Connect Scan at 14:33
    	Scanning localhost (127.0.0.1) [1000 ports]
    	Discovered open port 631/tcp on 127.0.0.1
    	Completed Connect Scan at 14:33, 0.01s elapsed (1000 total ports)
    	Host localhost (127.0.0.1) is up (0.00026s latency).
    	Interesting ports on localhost (127.0.0.1):
    	Not shown: 999 closed ports
    	PORT    STATE SERVICE
    	631/tcp open  ipp
    
    	Read data files from: /usr/share/nmap
    	Nmap done: 1 IP address (1 host up) scanned in 0.04 seconds
    		   Raw packets sent: 0 (0B) | Rcvd: 0 (0B)
    
    as you can see I already closed some ports like :111 which was used for portmap. in case you don't need portmap just remove it
    	root@c0re:/# update-rc.d portmap remove
    	root@c0re:/# apt-get remove portmap
    
    6. you should also consider storing all your passwords for all your websites/computers/etc in a key-database.
    'keepassx' comes in handy here, which is a port from KeePass for windows, but sadly it can only handle 1.x keepass databases.
    make sure to use the database only with a .key file and keep either the database itself or the keyfile on an usb stick.
    
    7. have you got those super l33t friends too, which try to fuck with your system using a fork bomb? you can easy secure this by limiting the number of processes per user
    	root@c0re:/# vi /etc/security/limits.conf
    	#we hate forkbombs
    	@users		soft	nproc		100
    	@users		hard	nproc		150
    
    8. try to remove all users from /etc/passwd which you don't need. for example exim,saned,sendmail leave their users there, even if you uninstalled them.
    	root@c0re:/# cat /etc/passwd
    	root@c0re:/# userdel 
    
    9. you should disable root login via su and enable root privileges using sudo. you can use visudo to make changes in /etc/sudoers
    	root@c0re:/# man sudoers
    	root@c0re:/# visudo
    	# /etc/sudoers
    	# This file MUST be edited with the 'visudo' command as root.
    	# See the man page for details on how to write a sudoers file.
    	#
    	Defaults	rootpw
    	# Host alias specification
    	# User alias specification
    	# Cmnd alias specification
    	# User privilege specification
    	root	ALL=(ALL) ALL
    	# Allow user c0re to gain root
    	c0re	ALL=(ALL) ALL
    
    here I changed the default method to 'rootpw' which would require the user to enter the root password instead of his own to gain the privileges.
    after you have verified that you made no errors just disable all attempts to log in via 'su' by removing the SUID bits. then just exit and try to log in again:
    	root@c0re:/# chmod 0511 /bin/su
    	root@c0re:/# exit
    	c0re@c0re:/# sudo -s
    	[sudo] password for root: 
    
    10. last but not least: read your logs, watch your running processes and set up logrotate to rotate your logs once in a while.
    	root@c0re:/# less /var/log/messages
    	root@c0re:/# ps aux
    
    
    
    
    --[0x02 - Hardening SSH]--
    
    i think i don't need to tell you that you shouldn't use anything like telnet or vnc to connect to your box because the traffic will not be encrypted and you are sending plain text passwords.
    so we are going to configure ssh and its daemon sshd.
    if you haven't done already install the required packets
    	root@c0re:/# apt-get install ssh openssh-server
    
    after that there should be a file which configures the daemon in /etc/ssh/ which is called 'sshd_config'
    there are some things you need to change:
    	root@c0re:/# vi /etc/ssh/sshd_config
    	+) change the default port :22 to something different :8089 or :1337
    	+) only allow protocol version 2
    	+) uncomment 'ListAddress 0.0.0.0' or ::1 of you need ipv6
    	+) set 'LoginGraceTime' to 60
    	+) set 'PermitRootLogin' to 'no'
    	+) make sure 'PermitEmptyPasswords' is set to 'no'
    
    sure you got a file for user configuration too
    there is also some stuff you should enable:
    	root@c0re:/# vi /etc/ssh/ssh_config
    	+) ForwardAgent no	
    	+) ForwardX11 no
        	+) ForwardX11Trusted yes
    	+) RhostsRSAAuthentication no
        	+) RSAAuthentication yes
        	+) PasswordAuthentication yes
    	+) CheckHostIP yes
    	+) ConnectTimeout 0
        	+) StrictHostKeyChecking yes
    	+) Protocol 2
    	+) Cipher blowfish
    	+) EscapeChar ~
    
    after you're done just restart the sshd and all changes should take affect
    	root@c0re:/# /etc/init.d/ssh restart
    	Restarting OpenBSD Secure Shell server: sshd.
    
    so this is all working fine from your LAN, but i think you also want to connect to your box from outside of your LAN. in this case we need to set up a port forwarding for the port where sshd is listening on.
    there is a great website which has a how-to for a shitload of routers/modems 
    to test if your port forwarding works get a device which is not in your LAN, maybe use your iPhone over 3G/EDGE, and try to connect via ssh to your WAN ip and forwarded port.
    
    if you want to log & ban all people who try to bruteforce your ssh login automatically you can set up 'fail2ban' 
    "Fail2ban's main function is to block selected IP addresses that may belong to hosts that are trying to breach the system's security.
    It determines the hosts to be blocked by monitoring log files (e.g. /var/log/pwdfail, /var/log/auth.log, etc.) and bans any host IP that makes too many login attempts or
    performs any other unwanted action within a time frame defined by the administrator." so lets install it:
    	root@c0re:/# apt-get install fail2ban
    
    you can leave the settings in /etc/fail2ban/fail2ban.conf the way they are. the real config file is jail.conf. just read through it, the basic settings should fit most of you by default.
    turn on other stuff like [ssh-ddos] and [apache] if you want to and restart fail2ban after you are done.
    	root@c0re:/# vi /etc/fail2ban/jail.conf
    	root@c0re:/# /etc/init.d/fail2ban restart
    	Restarting authentication failure monitor: fail2ban.
    
    
    
    
    --[0x03 - Simple Firewall]--
    
    every system needs a firewall, so I'm going to show you how to set up a straight firewall.
    this part is split into two subparts, the first part is about setting up a firewall using iptables. the second sub part is about configuring a advanced policy firewall.
    make sure that you have a look at the man pages of those two first, otherwise it could be very confusing.
    you will also need to decide what you would like to have as a firewall, iptables or APF, but for a non-server a simple iptables firewall like the one we are going to configure in subpart one, is good enough.
    so lets start:
    
    1. IPTables Firewall:
    ---------------------
    it should be already installed on your system, you can check this by running
    	root@c0re:/# dpkg --list | grep iptables
    	ii  iptables                                 1.4.8-3		administration tools for packet filtering and NAT
    
    fine, lets take a look at our current configuration
    	root@c0re:/# iptables -L
    	Chain INPUT (policy ACCEPT)
    	target     prot opt source               destination
    
    	Chain FORWARD (policy ACCEPT)
    	target     prot opt source               destination
    
    	Chain OUTPUT (policy ACCEPT)
    	target     prot opt source               destination
    
    not much there right? well we are going to change this soon, first you need to understand what all this means.
    I will just give you a basic overview, please read iptables man page.
    ok, you can see that we have 3 main things to configure:
    	INPUT 		(stuff that wants to connect to your computer)
    	FORWARD 	(routing packets)
    	OUTPUT		(stuff you send to other computers/servers)
    
    we start by dropping all OUTPUT & FORWARD packets. don't do this for INPUT yet, otherwise it may lock you out if you are currently connected via ssh to your box.
    	root@c0re:/# iptables -P OUTPUT DROP
    	root@c0re:/# iptables -P FORWARD DROP
    
    the next thing you want to do is add a rule to INPUT to keep all connections established which are currently connected.
    	root@c0re:/# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    
    this will keep your current established sessions alive, then its safe to DROP all other INPUT stuff:
    	root@c0re:/# iptables -P INPUT DROP
    
    so your current table should look like this:
    	root@c0re:/# iptables -vL
    	Chain INPUT (policy DROP 110 packets, 18280 bytes)
     	pkts bytes target      prot opt in     out     source              destination         
    	11279   11M ACCEPT     all  --  any    any     anywhere            anywhere            state RELATED,ESTABLISHED 
    
    	Chain FORWARD (policy DROP 0 packets, 0 bytes)
    	 pkts bytes target    prot opt in     out     source               destination         
    
    	Chain OUTPUT (policy DROP 10114 packets, 976K bytes)
     	pkts bytes target     prot opt in     out     source               destination 
    
    after we've done this we should allow any incoming packets which come from our loopback interface, you want to see your local web-server correct?
    	root@c0re:/# iptables -A INPUT -i lo -j ACCEPT
    
    you want to ssh in that box in the future too, so we set up an INPUT rule to allow this.
    NOTE: if you changed the port sshd listens on please adapt it in the example below.
    	root@c0re:/# iptables -A INPUT -p tcp --dport 1337 -j ACCEPT
    
    we should also allow some OUTPUT connections to ports which are widely used, e.g for sending/receiving emails or connecting to irc servers.
    I don't like the --multiport options because its hard to see which port receives data and how much, so we are just doing a few more lines instead of a single one.
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 25 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 143 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 993 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 465 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 6667 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 6697 -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p tcp --dport 8080 -j ACCEPT
    
    you will at least need the above config if you want to use a DNS server,a webbrowser(http,https),proxies,email or irc.
    I made a list to show you which port is used for what:
    	25 	default smtp
    	53	dns
    	80	http
    	143 	default imap
    	443	https
    	465 	google mail smtp
    	993 	google mail imap
    	6667	irc
    	6697	ssl-irc
    	8080	proxies
    
    so you thought we would forget our friend icmp right?, well not at all, we let him in, but we prevent a flood of echo requests (ping)
    and we also permit all icmp in OUTPUT, so you can ping others on the network, etc. 
    	root@c0re:/# iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 10/second -j ACCEPT
    	root@c0re:/# iptables -A OUTPUT -p icmp -j ACCEPT
    
    lets check our current iptable to see if all our rules are set properly:
    	root@c0re:/#  iptables -vL
    	Chain INPUT (policy DROP 1063 packets, 230K bytes)
    	 pkts bytes target     prot opt in     out     source               destination
    	12911 8543K ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED      
    	    0     0 ACCEPT     icmp --  any    any     anywhere             anywhere            icmp echo-request limit: avg 10/sec burst 5 
    	    2   100 ACCEPT     all  --  lo     any     anywhere             anywhere            
    	    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:1337
    
    	Chain FORWARD (policy DROP 0 packets, 0 bytes)
    	 pkts bytes target     prot opt in     out     source               destination         
    
    	Chain OUTPUT (policy DROP 2 packets, 124 bytes)
    	 pkts bytes target     prot opt in     out     source               destination         
    	  538 34446 ACCEPT     udp  --  any    any     anywhere             anywhere            udp dpt:domain 
    	 1227  160K ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:www 
    	  193 24808 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:https
    	 6624   14M ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED 
    	    9   540 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:imap2 
    	    1    60 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:submission 
    	    5   300 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:imaps 
    	    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssmtp
    	    1    60 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:6667
    	    1    60 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:6697
    	    1    84 ACCEPT     icmp --  any    any     anywhere             anywhere
    
    nice one, you set up a tiny firewall using iptables. but what happens if you reboot?!
    ..then all of our hard work is gone, since debian doesn't save the iptables and also doesn't load them during boot. but there is a work-around:
    
    lets save our current table in a file, I call it firewall.conf which is in /etc/iptables/
    	root@c0re:/# touch /etc/iptables/firewall.conf && iptables-save > /etc/iptables/firewall.conf
    
    after that you need to create a little shell script in /etc/network/if-pre-up.d/ which should execute what you want before the network is initialized. this may look like this:
    	root@c0re:/# cat /etc/network/if-pre-up.d/iptables
    	#!/bin/sh
    	RESTORE=/sbin/iptables-restore
    	STAT=/usr/bin/stat
    	IPSTATE=/etc/iptables/firewall.conf #change the path to your table here
    	test -x $RESTORE || exit 0
    	test -x $STAT || exit 0
    	if test `$STAT --format="%a" $IPSTATE` -ne "600"; then
    	  echo "Permissions for $IPSTATE must be 600 (rw-------)"
    	  exit 0
    	fi
    	if test `$STAT --format="%u" $IPSTATE` -ne "0"; then
    	  echo "The superuser must have ownership for $IPSTATE (uid 0)"
    	  exit 0
    	fi
    	$RESTORE < $IPSTATE
    
    lastly chmod this shell script and your firewall.conf and set its owner to root.
    	root@c0re:/# chmod +x /etc/network/if-pre-up.d/iptables && chmod 0600 /etc/iptables/firewall.conf
    	root@c0re:/# chown root:root /etc/network/if-pre-up.d/iptables
    
    
    
    2. Advanced Policy Firewall:
    ----------------------------
    now that we know how iptables work and how to define some rules with it, its time to make our life a little bit easier.
    Advanced Policy Firewall, APF, is an iptables(netfilter) based firewall system, known for its easy general configuration.
    we are going to set up APF with DDOS deflate script.
    so at this point you need to make a decision: are you happy with your hand-made iptables firewall?, then don't install apf-firewall.
    but if you need a firewall for a server you should consider flushing all your previous iptables rules and install apf.
    I will assume here that you either want to install a firewall for a server or you are not happy with the somewhat difficult config of iptables.
    	root@c0re:/# apt-get install apf-firewall && man apf
    
    the config file for APF is located in /etc/apf-firewall/conf.apf
    you can set inbound and outbound rules in there. we are going to implement the same rules used in the iptables example above. this is what the variables in conf.apf represent:
    	'IG_TCP_CPORTS'  ==  inbound tcp ports
    	'IG_UDP_CPORTS'  ==  inbound udp ports
    	'IG_ICMP_TYPES'  ==  inbound icmp types
    	'EG_TCP_CPORTS'  ==  outbound tcp ports
    	'EG_UDP_CPORTS'  ==  outbound udp ports
    	'EG_ICMP_TYPES'  ==  outbound icmp types
    
    so to implement all the rules in iptables we can set the variables like this:
    	IG_TCP_CPORTS="1337"
    	IG_UDP_CPORTS=""
    	IG_ICMP_TYPES="0,3,5,8,11,30"
    	EGF="1"
    	EG_TCP_CPORTS="25,80,143,443,1337,993,465,6697,6667,8080"
    	EG_UDP_CPORTS="53"
    	EG_ICMP_TYPES="all"
    
    the variable 'EGF' turns the firewall on for outbound ports. by this point you should already notice that it requires much less typing work than setting rules in iptables.
    now that we did the main config stuff we can restart APF for the first time (the failed is ok at the moment)
    	root@c0re:/# /etc/init.d/apf-firewall restart
    	apf-firewall disabled, please adjust the configuration to your needs ... failed!
    	and then set RUN to 'yes' in /etc/default/apf-firewall to enable it. ... failed!
    
    recheck your config in /etc/apf-firewall/conf.apf if everything is set properly, and then change RUN to 'yes' in /etc/default/apf-firewall and restart it once more.
    	root@c0re:/# cat /etc/apf-firewall/conf.apf
    	# Defaults for apf-firewall initscript
    	# sourced by /etc/init.d/apf-firewall
    	# installed at /etc/default/apf-firewall by the maintainer scripts
    	# Configure APF editing /etc/apf-firewall files (conf.apf is the principal config files)
    	# Modify to RUN="yes" when you are ready
    	RUN="yes"
    	
    	root@c0re:/# /etc/init.d/apf-firewall restart
    
    ok now test if everything works as expected. if you get locked out for some odd reason just wait 5 minutes, unless you didn't set 'DEVEL_MODE="0"' in /etc/apf-firewall/conf.apf,
    all config settings get discarded after 5 minutes. also watch your logfile of APF to detect misbehavior.
    	
    when APF is working as expected, then you may also add DOS-Defalte to it.
    (D)DoS Deflate is a shell script to assist in combating denial of service attacks. please note that DOS-Deflate uses APF to ban IPs so you must have it installed for DOS-Deflate to work properly.
    the installation of it is pretty simple:
    	root@masta:/# wget http://www.inetbase.com/scripts/ddos/install.sh
    	--2011-03-26 14:02:47--  http://www.inetbase.com/scripts/ddos/install.sh
    	Resolving www.inetbase.com... 205.234.99.83
    	Connecting to www.inetbase.com|205.234.99.83|:80... connected.
    	HTTP request sent, awaiting response... 200 OK
    	Length: 1067 (1.0K) [application/x-sh]
    	Saving to: “install.sh”
    	100%[======================================>] 1,067       --.-K/s   in 0.001s  
    	2011-03-26 14:02:47 (1.75 MB/s) - “install.sh” saved [1067/1067]
    	
    	root@masta:/# chmod 0777 install.sh && ./install.sh
    	Installing DOS-Deflate 0.6
    	Downloading source files...
    	.....done
    	Creating cron to run script every minute.....(Default setting)
    	.....done
    	Installation has completed.
    	Config file is at /usr/local/ddos/ddos.conf
    
    also if you wish to uninstall it someday for any reason you can do this nearly the same as you installed (D)DoS-Defalte:
    	root@masta:/# wget http://www.inetbase.com/scripts/ddos/uninstall.sh
    	--2011-03-26 14:09:38--  http://www.inetbase.com/scripts/ddos/uninstall.sh
    	Resolving www.inetbase.com... 205.234.99.83
    	Connecting to www.inetbase.com|205.234.99.83|:80... connected.
    	HTTP request sent, awaiting response... 200 OK
    	Length: 443 [application/x-sh]
    	Saving to: “uninstall.sh”
    	100%[======================================>] 443         --.-K/s   in 0s      
    	2011-03-26 14:09:38 (59.9 MB/s) - “uninstall.sh” saved [443/443]
    
    	root@masta:/# chmod 0777 uninstall.sh && ./uninstall.sh
    
    after you installed (D)DoS-Deflate its main config files reside in /usr/local/ddos/ddos.conf.
    the settings in there are very well explained so I will not go over them. restart apf once more and you are done.
    	root@masta:/# /etc/init.d/apf-firewall restart
    
    
    
    
    --[0x04 - Port Knocking]--
    
    so whats portknocking? well wikipedia can't explain it any better: 
    "In computer networking, port knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of prespecified closed ports.
    Once a correct sequence of connection attempts is received, the firewall rules are dynamically modified to allow the host which sent the connection attempts to connect over specific port(s)
    The primary purpose of port knocking is to prevent an attacker from scanning a system for potentially exploitable services by doing a port scan, 
    because unless the attacker sends the correct knock sequence, the protected ports will appear closed."
    
    here I will show you how to set up port knocking for ssh. you can however define it for ftp,telnet,etc. too if you like.
    let's assume you have already done some hardening on your ssh and have choosen to set your sshd to listen on port 1337.
    let us also assume that you decided to set up a 'hand made' iptables firewall like in we discussed before and are not using APF or something similar.
    so we are going to install knockd, a daemon which will wait and listen for our secret knocking sequence.
    please do yourself a favor and read the man page of knockd to fully understand all config options of it.
    	root@c0re:/# apt-get install knockd && man knockd
    
    after that we are going to define the knocking sequence, the iptables rule and the logfile to monitor whats going on.
    we are going to set the port to be open for 90 seconds, which should be enough for you to establish a connection to the ssh port.
    and after 90 seconds the port will be auto-closed and new connection is not possible. lets have a look at my config:
    	root@c0re:/# cat /etc/knockd.conf
    	[options]
            	logfile = /var/log/knockd.log
    
    	[opencloseSSH]
            	sequence    = 31337,73313,31337
    		seq_timeout = 5
    		start_command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 1337 -j ACCEPT
    		cmd_timeout     = 90
    		stop_command    = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 1337 -j ACCEPT
    		tcpflags    = syn
    
    NOTE: if you have set an iptables rule to allow INPUT on your ssh port, you need to remove it now before enabling knockd, because otherwise port knocking wouldn't make much sense, would it?
    you can do this simply issuing the following command, or remove the line from your /etc/iptables/firewall.conf by hand.
    	root@c0re:/# iptables -D INPUT -p tcp --dport 1337 -j ACCEPT
    
    I have set a different log file than syslog, simply because syslog gets filled with a lot of logs from other applications.
    my config also looks different than the default one, but thats just because I don't want to send a 'STOP' signal to close the port again when I'm done.
    so next thing would be to enable knockd by changing 'START_KNOCKD=0' to 'START_KNOCKD=1' and then restart the daemon.
    	root@c0re:/# cat /etc/default/knockd
    	################################################
    	# knockd's default file, for generic sys config
    	################################################
    	# control if we start knockd at init or not
    	# 1 = start
    	# anything else = don't start
    	#
    	# PLEASE EDIT /etc/knockd.conf BEFORE ENABLING
    	START_KNOCKD=1
    	# command line options
    	#KNOCKD_OPTS="-i eth1"
    
    	root@c0re:/# /etc/init.d/knockd restart
    	Stopping Port-knock daemon: knockd.
    	Starting Port-knock daemon: knockd.
    
    to send the knocks from the connecting computer/device you have many tools available. you may use telnet,knock,netcat,hping,sendip or packit:
    telnet:	c0re@OtherPC:/# telnet 192.168.0.1 31337
    	c0re@OtherPC:/# telnet 192.168.0.1 73313
    	c0re@OtherPC:/# telnet 192.168.0.1 31337
    	c0re@OtherPC:/# ssh -p 1337 c0re@192.168.0.1
    
    knock:	c0re@OtherPC: knock 192.168.0.1 31337 73313 31337
    	c0re@OtherPC:/# ssh -p 1337 c0re@192.168.0.1
    
    hping:  c0re@OtherPC:/# hping -i eth0 -c 1 -S 192.168.0.1 -p 31337
    	c0re@OtherPC:/# hping -i eth0 -c 1 -S 192.168.0.1 -p 73313
    	c0re@OtherPC:/# hping -i eth0 -c 1 -S 192.168.0.1 -p 31337
    	c0re@OtherPC:/# ssh -p 1337 c0re@192.168.0.1
    
    NOTE: some telnet implementations (e.g. windows) retry each connection 3 times, so you may not send the correct knocking sequence.
    you may end up sending sequences like "port1 port1 port1 port2 port2 port2 port3 port3 port3"
    so after we send a valid sequence from the other computer wanting to connect to our box our iptable INPUT chain should looks something like this:
    	root@c0re:/# iptables -L
    	Chain INPUT (policy DROP)
    	target     prot opt source               destination         
    	ACCEPT     icmp --  anywhere             anywhere            icmp echo-request limit: avg 10/sec burst 5 
    	ACCEPT     all  --  anywhere             anywhere            
    	ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
    	ACCEPT     tcp  --  192.168.0.5		 0.0.0.0/0           tcp dpt:1337 
    
    you see the added ip address in there? this is the connection knockd opened for you.
    now that we already established a connection we don't care if our port is being closed again by the firewall, because we defined earlier that all existing connections
    should stay established using this line:
    	root@c0re:/# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    
    
    
    
    --[0x04 - ARPalert]--
    
    I hope you know what ARP (Address Resolution Protocol) is, if not then please consider learning TCP/IP .
    we will assume that you already know at least the basics of TCP/IP and its protocols and layers, so we jump right into it:
    
    "arpalert - This software is used for monitoring ethernet networks. It listens on a network interface (without using 'promiscuous' mode) and catches all conversations of MAC address to IP request.
    It then compares the MAC addresses it detected with a pre-configured list of authorized MAC addresses. 
    If the MAC is not in list, arpalert launches a pre-defined user script with the MAC address and ip address as parameters.
    This software can run in daemon mode; it's very fast (low CPU and memory consumption).
    It responds at signal SIGHUP (configuration reload) and at signals SIGTERM, SIGINT, SIGQUIT and SIGABRT (arpalert stops itself)"
    
    in other words this means: you can detect MITM (Man In The Middle) attacks, MAC spoofing, etc. in your LAN.
    great that arpalert is also available in the default debian repository so we can install it quite simple.
    please read the man page for arpalert after you installed it.
    	root@c0re:/# apt-get install arpalert && man arpalert
    
    the main config files of arpalert reside in /etc/arpalert/
    	root@c0re:/# ls -lah /etc/arpalert/
    	total 1.6M
    	drwxr-xr-x   2 root root 4.0K Mar 20 20:55 .
    	drwxr-xr-x 139 root root  12K Mar 21 15:00 ..
    	-rw-r--r--   1 root root 4.7K Mar 17 18:48 arpalert.conf
    	-rw-r--r--   1 root root    2 Mar 20 20:55 maclist.allow
    	-rw-r--r--   1 root root    0 Mar  9  2010 maclist.deny
    	-rw-r--r--   1 root root 1.6M Mar  9  2010 oui.txt
    
    there are just a few things you need to change in the config file
    	+) uncomment the log file, and change its path to /var/log/arpalert/arpalert.log
    	+) set daemon to 'yes'
    	+) uncomment the interface (e.g.: eth0)
    	+) set a 'action to detect' command (best thing would be to code a quick alert-email script or something similar)
    
    well now that you got the main config restart arpalert and it should start logging all MACs and IPs in a .leases file.
    just leave it like this for a couple of days until all IPs and MACs appear in this file.
    	root@c0re:/# /etc/init.d/arpalert restart
    	Stopping Ethernet station monitor daemon: arpalert.
    	Starting Ethernet station monitor daemon: arpalert: Selected device: eth0
    	
    	root@c0re:/# cat /var/lib/arpalert/arpalert.leases
    	dc:c5:3c:bb:8b:2d 192.168.0.2 eth0 1300689040 385784
    	b4:07:f6:b5:27:22 192.168.0.5 eth0 1300653081 822336
    	22:cf:30:78:f3:b2 192.168.0.1 eth0 1300690390 897939
    	00:26:bb:0f:6b:10 192.168.0.6 eth0 1300655358 730242
    	00:26:b5:cf:10:97 192.168.0.10 eth0 1300652579 545369
    	00:26:bc:02:8a:f1 192.168.0.4 eth0 1300656049 209712
    	00:1f:69:64:26:51 192.168.0.254 eth0 1300690390 898555
    
    don't forget to double check this list before proceeding!
    so after you got all those addresses we need to fill them in the maclist.allow file, so all changes to those IPs and MACs will be logged.
    	root@c0re:/# cat /etc/arpalert/maclist.allow
    	22:cf:30:78:f3:b2 192.168.0.1 eth0
    	dc:c5:3c:bb:8b:2d 192.168.0.2 eth0
    	00:26:bc:02:8a:f1 192.168.0.4 eth0
    	b4:07:f6:b5:27:22 192.168.0.5 eth0
    	00:26:bb:0f:6b:10 192.168.0.6 eth0
    	00:26:b5:cf:10:97 192.168.0.10 eth0
    	00:1f:69:64:26:51 192.168.0.254 eth0
    
    once you filled something in maclist.allow arpalert threads all others as potential intruders.
    now that's it. if you configured it properly it should at least log all changes at the path you gave it in the .conf file
    	root@c0re:/# less /var/log/arpalert/arpalert.log
    
    if you set up an 'action on detect' script in the config file it should launch once an intruder is detected.
    
    NOTE: if you have 'network-manager' installed you will most likely have this line in your logs:
    "arpalert: [./capture.c 232] pcap_open_live error: eth0: That device is not up"
    this is caused because network-manager is to damn slow to fully bring your card online before arpalert tries to listen on it.
    if so, please consider removing it and set a static ip (you already should have done this in the basics..), after that the error is gone.
    
    
    
    
    --[0x05 - Final words]--
    
    yeah that's about it, you're done.
    your debian box is now much better configured/secured. please keep in mind that this paper is not the 'non plus ultra' in security, as I already said, it should just provide
    you a leading path to secure your box.
    if you think an important step/part is missing, feel free to write it down and send it over to me, if it fits the subject i will add it to this tutorial
    ..and for all those wondering: no, those are not my real MAC/IPs/UUIDs/etc. - sorry guys
    
    further reading:
    	*) Securing Debian Manual  
    	*) Keeping Your Documents Safe In a Digital Age  
    	*) Staying Anonymous in a Heavily Monitored World  
    	*) Recent Debian Security Advisories 
    	*) Wikipedia on Network Security 
    	*) IPTables Tutorial by Oskar Andreasson 
    	*) Advanced Policy Firewall Readme