Showing posts with label FreeBSD. Show all posts
Showing posts with label FreeBSD. Show all posts

Monday, August 22, 2011

BSD Mail/ SendMail 101

While working on HE's IPv6 certification, I gathered some useful experiences with setting up a basic mail server on FreeBSD so I thought it would be worthwhile to do a quick blog on this...
Overview
Firstly, the Mail User Agent (MUA) is what the user uses to compose emails. BSD Mail is the default MUA which comes with FreeBSD. Its syntax is as follows (for composing emails):
#mail
Subject:
[Mail Content]
. Remember to enter a “.” in a new line to end writing the email
EOT
Secondly, the Mail Transfer Agent (MTA) is what interacts with the rest of the internet i.e. the MTA is responsible for sending and receiving emails. Sendmail is the default FreeBSD's MTA.
I configured the following files (under /etc/mail) to have this setup working:
1. "virtualusertable" - the email address accepted and local user to forward the email to.
2. "access" - like an ACL for emails, it identifies the incoming/ outgoing email addresses permitted/ denied.
3. local-host-names - email domain accepted into local machine.
In /etc/rc.conf, I have also added "sendmail_enable=yes"; along with setting my NAT gateway to accept TCP 25.
For those interested in more details, FreeBSD Handbook has dedicated a page on Sendmail. According to this page, there are certain occasions when either a "make" or process restart is required for the configuration changes to take effect but in the interest of keeping this post simple I will not go into any details here.
That seems to be it, Sendmail was running fine and accepting emails:
home-unix6# /etc/rc.d/sendmail status
sendmail is running as pid 1170.
sendmail_clientmqueue is running as pid 1174.
On DNS
Also worth noting is when you send an email, the local MTA actually perform two DNS queries:
1. MX (Mail Exchange) query against the destination email domain - to resolve the mail server's hostname.
2. A (or AAAA) query against the MX response, to resolve the IP address of the receiving SMTP server.
P.S. As a test, I tried sending an email to my service provider, iiNet email account, using this machine. Interesting enough, I received an error message informing me the email I sent has been rejected due to the "poor reputation" of the MTA...at least I can be sure my setup is working (there is a Whirlpool forum on this from others with similar experiences).

Saturday, May 28, 2011

Quick note on "Wall" command

On a FreeBSD system, if you would like to send messages to all users, then login as root and type:
#wall
-- Message
[Ctrl-D]

Wednesday, July 28, 2010

Some useful UNIX commands

Haven't done a post for awhile, so thought I should do a quick one on some handy UNIX commands...
A couple of days ago, I was doing some admin work on a BSD system. "df -kh" showed me that the /var partition had 35G used, taking up over 98% of its allocated space...

I found this nice command displaying the disk usage of each file/ directory:
# cd /var
# du -sk *
"du" stands for disk usage, the "k" option means KBytes (alternatively, use "m" for MB).
It turned out the /var/spool/clientmqueue/* was full, possibly because one of the programs kept trying to send mail (although I had sendmail disabled under /etc/rc.conf, but that's a different story).

There were so many files under this directory that a "rm -rf ./*" returned a "Argument list too long" error. Instead, I had to use:
# ls | xargs rm
Which pipes the outputs from "ls" to "rm". Unfortunately, there were also too much arguments for "ls" to handle.

As I was about to head off, I decided to remove the entire directory:

# nohup rm -rf /var/spool/clientmqueue/* &
"nohup" lets the process run after I have logged off, with "&" putting it into the background... and problem solved.

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"):















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. 



Thursday, March 25, 2010

Internet Connection Failover with PPPoE (DSL) and 3G USB Wireless

Prior to signing up my DSL connection, I also have 3g wireless internet access, which comes with a Huawei E220 dongle. "dmesg" confirms the BSD system can detect this dongle correctly:

ugen1.2: HUAWEI Technologies at usbus1
umass0: HUAWEI Technologies HUAWEI Mobile, class 0/0, rev 1.10/0.00, addr 2 on usbus1
cd0: HUAWEI Mass Storage 2.31 Removable CD-ROM SCSI-2 device

In addition, I have also purchased a TP-Link TD8810, 1 port DSL modem to replace the D-Link DSL modem which bricked. TP-Link modem is cheap ($39 from MSY I last checked), and is configured as an DSL bridge.

Hence, I have created two profiles in the ppp daemon configuration (/etc/ppp/ppp.conf) respectively:

dsl:
set device PPPoE:fxp0 # interface where PPPoE session is dialed out.
set authname
set authkey
set dial
set login
add default HISADDR

3g:
set device /dev/cuaU0.0
set speed 57600
set phone *99\#
set authname
set authkey
set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.0
set vj slotcomp off
add default HISADDR

Choose any name you like for both dsl and 3g. Note that for the 3g profile, the line "set ifaddr" is required otherwise dialing ppp gives you an "unable to create IPCP interface" error.

The ppp connection is invoked through "ppp -nat -ddial DSL/3g". Upon successful establishment, "ifconfig" would display a "tun0" interface with two IP addresses (lo0 and public IP).

Add the following to "/etc/rc.conf" so that everytime BSD starts up, it dials PPPoE out of the DSL link:
router_enable="NO" # So BSD does not removes ppp learnt default route
ppp_enable="YES"
ppp_mode="ddial"
ppp_nat="YES" # Original "natd" has been disabled.
ppp_profile="DSL"

I also wished to implement some failover feature. In case if the PPPoE session over DSL gets disconnected, the system would automatically dial out of USB dongle.

By googling failover scripts, I found a very simple script and modified it slightly to suit my needs:

#!/bin/sh
# 1. ping "www.google.com.au" five times. Count the successful pings by grepping the words "bytes from".
count=$(/sbin/ping -c 5 www.google.com.au | grep -c 'bytes from' )

# 2. if ping failed, then stop VoIP and remove "tun0" ppp interface.
# Re-dial ppp session using 3g profile, with "nat" option.
if [ $count -eq 0 ]; then
/usr/local/etc/rc.d/asterisk stop
/etc/rc.d/ppp stop
/sbin/ifconfig tun0 destroy
/usr/sbin/ppp -nat -ddial 3g
fi

I placed this into crontab and runs it once every minute or so. Not the most sophisticated script I admit, although it certainly does the job.


P.S. I have also read about "mpd" multi-protocol daemon being a good choice in implementing what I wish to achieve, and BSD has some firewall packages supporting connection failover or even load sharing (per TCP session, I suppose?). I must admit I have not look deeply into them, so any comments or ideas to improve this implementation is much welcomed.