Saturday, June 5, 2010

Implementing Network Intrusion Detection for Home Network


My home gateway is providing wireless internet access for all home computing devices, including the computer which I am writing on. For an added layer of security, I have recently added network intrusion detection (NIDS) function on the unix box using Snort.

Snort is an open-source Network Intrusion Detection System capable of analyzing packets and identify potential security threats, and BASE is a php-based program providing a graphical interface, analyzing network statistics and data collected by Snort. [http://en.wikipedia.org/wiki/Snort_(software)].

Having done some research online, I came across this great guide on installing "Snort and BASE on FreeBSD". [http://rackerhacker.com/2007/05/27/install-snort-and-base-on-freebsd/]


Giving credit to the guide mentioned above, I pretty much referenced it throughout the entire installation of Snort, except for the BASE part which isn't covered. Here is my interpretation of the entire "HowTo" base on my installation experience:

- Update BSD ports collection using "portsnap fetch extract update"
- Install Snort (enable MySQL option) and Oinkmaster under /usr/ports/security
- Install MySQL from /usr/ports/database/mysql50-server. I used version 50 while newer versions are available, because MySQL client was already installed on my system and their versions need to match.
- Modify "oinkmaster.conf" file (copied from /usr/local/etc/oinkmaster.conf.sample), and specify rule file's location:
url = file:///snortrules-snapshot-2860.tar.gz
The rules file has to be .tar.gz format. In my case, it is saved to hard-drive, so for the above example I used "file" option. Oinkmaster also supports retrieving rules file over the internet, allowing for periodic update using crontab (see other examples in the configuration file for more details).
Note, register with Snort to obtain the latest rule files, and download from their site is only permitted once every 15 minutes for security reasons.
- Extract Snort rules to rules directory
# oinkmaster -o /usr/local/etc/snort/rules/

- Configure MySQL database. Create database "testdb" using "# mysql -u snort -psnortpassword testdb < /usr/local/share/examples/snort/create_mysql", and the database will be where Snort writes to and BASE reads from.

- Grant user "snort" access to database "testdb". Login to MySQL as root user, using "mysql -u root".
> GRANT ALL PRIVILEGES ON testdb.* TO 'snort'@'localhost' IDENTIFIED BY 'snortpassword';
- To confirm, login to MySQL as snort using "mysql -u snort -p". You will then be prompted for password.
> show databases;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| testdb |

- Configure "snort.conf" file under /usr/local/etc/snort/ and uncomment the lines:
# config detection: search-method lowmem
# output alert_syslog: LOG_AUTH LOG_ALERT
# output database: log, mysql, user=snort password=snortpassword dbname=testdb host=localhost
Ensure the database name matches that previously created.

- Configure "rules" file - I was using rules file snortrules-snapshot-2860.tar.gz, and noted quite alot of errors (e.g. data_type not known) when I test run Snort. So, I commented out some lines in the following rules in addition to "local.rules":
> web-client.rules
> x11.rules
> attack-responses.rules
> backdoor.rules
> spyware-put.rules # I had to comment this file out entirely due to large number of errors...

Finally, update "/etc/rc.conf" so it starts automatically:
### Snort/BASE Solution ###
mysql_enable="YES"
snort_enable="YES"
snort_interface="tun0" # I am using PPPoE access at home

Start Snort using "/usr/local/etc/rc.d/snort start", if there are no errors then the following messages should appear in /var/log/messges:
Jun 5 00:12:48 HomeFreeBSD snort[1273]: [1:5998:4] P2P Skype client login startup [Classification: Potential Corporate Privacy Violation] [Priority: 1]: {TCP} 192.168.2.10:50854 -> 212.8.163.76:12350
Jun 5 00:12:48 HomeFreeBSD snort[1273]: [1:5999:4] P2P Skype client login [Classification: Potential Corporate Privacy Violation] [Priority: 1]: {TCP} 212.8.163.76:12350 -> 192.168.2.10:50854
Jun 5 00:12:48 HomeFreeBSD snort[1273]: [1:5998:4] P2P Skype client login startup [Classification: Potential Corporate Privacy Violation] [Priority: 1]: {TCP} 192.168.2.10:50854 -> 212.8.163.76:12350
Jun 5 00:12:48 HomeFreeBSD snort[1273]: [1:5693:4] P2P Skype client start up get latest version attempt [Classification: Potential Corporate Privacy Violation] [Priority: 1]: {TCP} 192.168.2.10:50855 -> 204.9.163.158:80


BASE Installation
- Install BASE (enable MySQL) and adodb from /usr/ports/security/base and /usr/ports/database/adodb respectively.
I already have apache (HTTP Server) previously installed on my system, otherwise it is located under /usr/ports/www/apache22 and there are lots of good tutorials on how to get your web-server up and running.
The following is for configuring BASE:
# /usr/local/etc/apache22/httpd.conf
DocumentRoot "/usr/local/www/base"
...
# This should be changed to whatever you set DocumentRoot to.

...
Allow from All
# Enable PHP in apache
LoadModule php5_module libexec/apache22/libphp5.so

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

Update $Dblib variable to /usr/local/share/adodb/ in /usr/local/www/base/base_conf.php
$DBlib_path = '/usr/local/share/adodb/';
$DBtype = 'mysql';

/* Alert DB connection parameters*/
$alert_dbname = 'testdb';
$alert_host = 'localhost';
$alert_port = '';
$alert_user = 'snort';
$alert_password = 'snortpassword';

Lastly, MySQL by default listens over network. This means anyone can connect to the database over the internet; an unnecessary security risk. Disable MySQL listening to network connection:
# cp /usr/local/share/mysql/my-large.cnf /usr/local/etc/my.cnf
# vi /usr/local/etc/my.cnf
# Don't listen on a TCP/IP port at all...
skip-networking

If things go well, Snort and BASE system should be up and running and you should see the following (as you can see, my database name is "snort_log"):















Sunday, May 9, 2010

XBMC and DD-WRT Wireless Client

The "Home Media Centre" concept can be summarized as turning your television set into an entertainment centre, i.e. migrating what you usually do on your computer to your TV; such as watching mpeg videos, photos, DVDs, YouTube, IPTV, internet radio and various other medias stored on a hard-drive or over the internet.

Over the past couple of weeks, I have managed to setup my own low-cost media center for around $130, with most of the cost going to a brand-new wireless router as you shall read.

A couple of months ago, I bought a pre-owned Microsoft XBox (the original one) for $50 and installed XBox Media Centre (XBMC http://xbmc.org/) onto it. I followed one of the softmod installation guides found on the internet, which was pretty straight-forward. I completed the whole process at home without needing to bring the console to a shop and modify its hardware. The installation process basically utilizes another desktop PC as a platform to load XBMC OS onto XBox's harddrive (through IDE cable) as though it were its own, and then it's done.

Then I connect the media centre to the internet. My ADSL modem is located quite far away from the television set. As I have previously setup wireless internet, I decided to install dd-wrt (v24-sp2) onto D-Link's DIR 600, set it to "repeater bridge" mode and connect to the xbox with Ethernet cable. As a side note, the wireless router cost me more than $70 but supports only 802.11g...

In terms of functionalities, the original Xbox has component cables (Yellow/Green/White) supporting SD (standard definition) video - good enough for watching DVDs.

The whole setup is now sitting in my living room. I use it mostly for listening to internet radio provided by my ISP and occasionally watching DVD. I have also downloaded a YouTube script so I can watch YouTube on TV... although the Xbox seems to struggle with High-Definition videos. Nonetheless, it is still good value for $50.

As a side note, I also purchased Xbox's DVD kit over Ebay, giving me a remote controller to this media centre. There are some photos of this setup in the "photo gallery"...

Saturday, May 8, 2010

Hard-Drive Short-Stroking

I read an article on Tom's Hardware page about short-stroking, and found it quite an interesting concept. The idea is to limit the "usage" of an hard-drive to its out-most rim. By under-utilizing the hard-drive, the mechanical movement of its arm is also reduced, hence increasing the r/w performance...


Giving credit to the original author, there are more information on  the following link:
http://www.tomshardware.com/reviews/short-stroking-hdd,2157.html

Monday, March 29, 2010

Enabling IPv6 on BSD with v4 only Internet Access

Background
For those working in the ICT industry, IPv4 exhaustion is not a new issue. Google search returns a wiki page discussing this topic in lengthshttp://en.wikipedia.org/wiki/IPv4_address_exhaustion. There is even an online counter displaying the remaining IPv4 addresses available. http://www.potaroo.net/tools/ipv4/

The only formal solution to IPv4 address shortage is using IPv6, by expanding the address space from 32bits to 128bits (along with other protocol details such as fixed header length replacing options, which I shall avoid going into details).

However, the protocol was not designed to directly interwork with IPv4 (hosts and routers). This means, IPv6 is and will exist as a "parallel universe" to the IPv4 internet the majority of us as using.

I would like to setup my BSD gateway as a IPv6 router. It establishes an IPv6 tunnel over IPv4 internet, terminating at a public Tunnel Broker. The default IPv6 route on BSD is this v6 tunnel. Its NAT clients can access IPv6 contents by routing through this machine.

Finding the Program
I did a search through BSD port tree (key word "IPv6") and found several interesting programs...
- 6tunnel http://toxygen.net/6tunnel/ 2005-08-18, Allow for non-v6 hosts (v4) to communicate with v6 hosts and vice versa
"the host computer to connect to a tunnel broker using the TSP protocol and to get the information for its tunnel"
"setup IPv6 on home machine and network for exploring IPv6 without any registration".
- Sixxs http://www.freebsd.org/cgi/cvsweb.cgi/ports/net/sixxs-aiccu/pkg-descr. Released in 2005 "This is the TIC+ heartbeart client for the public dynamic-IPv4 IPv6 tunnel beta test from the SixXS tunnel service provider."
Tunneling IPv6 over UDP through NATs, RFC 4380.

There is also a great chapter in FreeBSD handbook on getting started with IPv6.http://www.freebsd.org/doc/en/books/handbook/network-ipv6.html


Being an IPv4 user, the easiest way to access IPv6 webpages is visitinghttp://www.sixxs.net/tools/gateway/, which provides "IPv4 Gateways" to access IPv6 only sites using HTTP1.1. However, I wish to bring IPv6 directly onto my laptop and netbook connected over WiFi.

Referencing the handbook again, it suggests "Use the net/freenet6 port if you are on a dial-up connection"...which will be referred to as "gogoClient" http://www.freebsd.org/cgi/url.cgi?ports/net/freenet6/pkg-descr

Reading the ports description, this program aims at assigning IPv6 address to IPv4 end-users including hosts residing behind NAT. So, I signed up for an accounthttp://gogonet.gogo6.com/page/freenet6-services. This is required to obtain the gogoClient userguide and register for tunnel credentials (required).

In gogoClient's user-guide, there are four scenarios. Scenario three interest me most as it establishes BSD as IPv6 router on IPv4 network with delegated IPv6 prefix.

Afterwards, install the program through ports:
cd /usr/ports/net/freenet6/
make; make install
The program's configuration file is "/usr/local/etc/freenet6/gw6c.conf", herewith my configuration:
template freebsd # FreeBSD Specific
server broker.freenet6.net # default value
auth_method=any
userid=your_username # Different from gogonet web login.
passwd=your_passwd
host_type=router
if_prefix=wlan0 # internal interface routing with IPv6 tunnel interface.
prefixlen=64 # value could be 48 or 60 depending on gogoServer.
tunnel_mode v6anyv4 # v6anyv4 - gogoSERVER suggest correct encapsulation to client
log_file=3 # Set maximum verbosity option for "file" log option.
log_filename=/var/log/gw6c.log # Define full path
last_server Tsp-last-server.txt # (info) last gogoSERVER with successful connection
broker_list tsp-broker-list.txt # (info) gogoSERVER list

gogoClient program is invoked through CLI "gw6c", invoked in the directory where configuration file resides.

I live in Melbourne, Australia. Invoking gw6c returns the following message:
The Gateway6 redirection list is [ taipei.freenet6.net, sydney.freenet6.net, amsterdam.freenet6.net, montreal.freenet6.net ].
The optimized Gateway6 redirection list is [ sydney.freenet6.net, montreal.freenet6.net, taipei.freenet6.net, amsterdam.freenet6.net ].
So I updated the configuration file's "server" parameter accordingly.

I initiate the program again, and looking at the log-file "/var/log/gw6c.log". I have added some comments to the excerpt of my logs:

# gogClient version is v6.0-Release
2010/03/26 23:51:44 I gw6c: Gateway6 Client v6.0-RELEASE build Mar 16 2010-22:51:10
2010/03/26 23:51:44 I gw6c: Built on ///FreeBSD HomeFreeBSD 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Mon Feb 15 20:33:54 EST 2010 root@HomeFreeBSD:/usr/obj/usr/src/sys/HomeFreeBSD i386///
2010/03/26 23:51:44 I gw6c: Establishing connection to Gateway6 sydney.freenet6.net using reliable UDP.

# Negotiating tunnel parameters. Host requested to be "router" mode with /64 prefix, but received a /56 prefix.
2010/03/26 23:51:48 I gw6c: Sending: 'Content-length: 269(tunnel action="create" type="v6anyv4" proxy="no") (client) (address type="ipv4")local-public-ipv4(/address) (keepalive interval="30") (address type="ipv6")::(/address) (/keepalive) (router) (prefix length="64"/) (/router) (/client)(/tunnel)'

2010/03/26 23:51:48 I gw6c: Received: '200 Success(tunnel action="info" type="v6v4" lifetime="604800") (server) (address type="ipv4")(ipv4-address)(/address) (address type="ipv6")(ipv6-address)(/address) (/server) (client) (address type="ipv4")(ipv4-address)(/address) (address type="ipv6")(ipv6-address)(/address) (address type="dn")your_username.broker.freenet6.net(/address) (router) (prefix length="56")(local-ipv6-address)(/prefix) (/router) (keepalive interval="30") (address type="ipv6")(ipv6-address)(/address) (/keepalive) (/client)(/tunnel)'

# IPv6 interface, gif0, being created and configured locally. Sysctl parameters and wlan0 interface updated:
2010/03/26 23:51:48 I gw6c: /sbin/ifconfig gif0 create
2010/03/26 23:51:48 I gw6c: /sbin/ifconfig gif0 tunnel (local ipv4) (remote ipv4)
2010/03/26 23:51:48 I gw6c: /sbin/ifconfig gif0 inet6(ipv6-address) prefixlen 128 alias
2010/03/26 23:51:48 I gw6c: /sbin/ifconfig gif0 mtu 1280
2010/03/26 23:51:48 I gw6c: /sbin/route add -inet6 default (ipv6-address)
2010/03/26 23:51:48 I gw6c: /sbin/sysctl -w net.inet6.ip6.forwarding=1
2010/03/26 23:51:48 I gw6c: net.inet6.ip6.forwarding: 1 -> 1
2010/03/26 23:51:48 I gw6c: /sbin/sysctl -w net.inet6.ip6.accept_rtadv=0
2010/03/26 23:51:48 I gw6c: net.inet6.ip6.accept_rtadv: 0 -> 0
2010/03/26 23:51:48 I gw6c: /sbin/ifconfig wlan0 inet6 (local-ipv6-address) prefixlen 64

# Tunnel Creation success message...
2010/03/26 23:51:48 I gw6c: The host type is 'router'.
2010/03/26 23:51:48 I gw6c: The tunnel type is v6v4.
2010/03/26 23:51:48 I gw6c: Your IPv6 address is (ipv6-address).
2010/03/26 23:51:48 I gw6c: Your IPv6 prefix is (local-ipv6-address)/56.

Also note the gw6c script pushes the IPv6 default route onto BSD system. To check, use "netstat -rn".

I have not been able to find a startup configuration for gw6c program. However, I have enabled both IPv6 and IPv6 Gateway parameters in "/etc/rc.conf":
ipv6_enable="YES"
ipv6_gateway_enable="YES"

I use a Windows laptop as an IPv6 client, residing in the WiFi blanket. Its IPv6 address is set to match BSD's Wifi adapter (wlan0) IP subnet.

Now, I can access IPv6 webpages from my laptop... e.g. ipv6.google.com





Converting WiFi Adapter into 802.11g Access Point (WPA2-PSK) on FreeBSD

I originally had an ASUS WL500g Premium running on DD-WRT (released back in 2006), configured as Access Point with DHCP forwarding enabled. This allowed my laptops and iPhone at home to connect to this AP and automatically connect to the internet through BSD gateway.

I bricked this WiFi router when I did a software upgrade. At the same time, I also have two other WiFi routers at home - NetGear WNR2000 and TP-Link TL-WR740N. Both cannot be configured as WiFi Ethernet Bridge, nor have DHCP forwarding options. Also, there's no DD-WRT support.

I do not wish to add another layer of NAT for my home network, so I purchased the most economical WiFi Adapter I could find and convert it into a WiFi access point. The Adapter is TP-Link TL-WN851N (onboard PCI), running on Atheros 9280 chipset.


Configuring WiFi Access Point
From memory, the necessary kernel options for Atheros driver are already present in GENERIC file by default, so probably no further work was required... there is a chapter in FreeBSD handbook on "Wireless Network" for reference. http://www.freebsd.org/doc/handbook/network-wireless.html


Afterwards, I installed the hardware, startup BSD and the WiFi adapter was correctly recognized as "ath0":
ath0: (Atheros 9280) mem 0xfc500000-0xfc50ffff irq 5 at device 4.0 on pci5
ath0: [ITHREAD]
ath0: AR9280 mac 128.2 RF5133 phy 13.0

Then I proceeded to configure it. It was when I noted the system wouldn't allow me to provision any parameters using "ifconfig ath0". Did some research online and noted in FreeBSD 8.0, a virtual device (wlan0) has to be created prior to provisioning any WiFi configuration... which is different from previous BSD releases [http://forums.freebsd.org/showthread.php?t=11978].

Here is how I created my pseudo wireless device, wlan0. I also needed to set the option "wlanmode hostap" for it to be created as access point:
# ifconfig wlan0 create wlandev ath0 wlanmode hostap

Setting the AP to be WPA-PSK mode requires hostapd. There is an rc.d script to start this. My configuration file "/etc/hostapd.conf" is as follows:
interface=wlan0
debug=1
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=(your-ssid)
country_code=AU
hw_mode=g # I tried setting this to 802.11n, but encountered some error.
channel=0
basic_rates=60 120 240
wpa=1
wpa_passphrase=(wifi-passphrase)
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP

Finally, set IP interface on wlan0 and update DHCP daemon, along with other services to listen on this interface.

To startup this service when system boots, add the following to "/etc/rc.conf" file
wlans_ath0="wlan0"
create_args_wlan0="wlanmode hostap"
hostapd_enable="YES"
ifconfig_wlan0="inet 192.168.2.1 netmask 255.255.255.0 up" # Gateway

So this is how to set your WiFi adapter to become a Wireless Access Point.


After Thoughts - Usage Notes
Having used this for awhile, I must admit it is not as stable as having a dedicated Wireless router. The wireless connection would drop occassionally while "dmesg" kept displaying the message "ath0: stuck beacon; resetting (bmiss count 4)".

I found this wikipage dedicated to the stuck beacon issue. [http://madwifi-project.org/wiki/StuckBeacon]. While I have not resolved the root cause, the issue has been mitigated through running the sysctl variable: net.wlan.0.bmiss_max: 2 -> 10

Here with my setup today... 












[Jan 2012] An additional note: this wireless setting supports WPA authentication, but not WPA2 authentication.