Copyright © 2005-2007 FreeNAS Documentation Project.
This document is based on the m0n0wall Developers' Handbook
All rights reserved. Redistribution and use in any form, with or without modification, are permitted provided that the following conditions are met:
Redistributions must retain the above copyright notice, this list of conditions and the following disclaimer.
Neither the name of the FreeNAS Documentation Project nor the names of its contributors may be used to endorse or promote products derived from this documentation without specific prior written permission.
THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION OR THE ASSOCIATED SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
October 2005
This is the easiest way for studing/modify FreeNAS.
Install FreeBSD 6.2 on your dedicaced PC (or under a VMware/Qemu), selecting the developers set (without X) and without ports source.
Then Install these tools:
subversion (for downloading the sources from the SVN)
pkg_add -r subversion
cdrtools
pkg_add -r cdrtools
bash
pkg_add -r bash
php (used for checking new code with the command php -l filename.php) before compiling a new ISO/IMG file)
pkg_add -r php5
Now, update your FreeBSD 6.2:
Then, as root create FreeNAS directory, and download the latest (under developement) sources:
mkdir /usr/local/freenas
cd /usr/local/freenas
svn co https://freenas.svn.sourceforge.net/svnroot/freenas/trunk svn
Then, you can run the generating script for downloading the latest FreeNAS binary file set and compile an ISO/IMG file:
cd /usr/local/freenas/svn/build
./make.sh
And select option:
20 : Build FreeNAS from scratch advanced menu
1 - Create FreeNAS filesystem structure 2 - Copy required files to FreeNAS filesystem 3 - Build kernel 4 - Software package 5 - Build bootloader 6 - Add necessary libraries
* - Quit
10: Generate a IMG file (to be write directly on a CF/USB card)
or 11: Generate an ISO file
This is the longest way for studing/modify FreeNAS, but with this can be usefull if you want to add lot's of binary file or others...
Here is where I found some information about FreeBSD:
Install FreeBSD 6.2 with the developer distribution with ports collection.
In the beginning of the install process:
Create only 2 partition the root ("/") and the SWAP: It's important because after we re-compile the system with dynamically linked library, and the system can't boot if the /usr directory is not on the same partition.
In the last configuration step of the installation process:
Create a new user at the end and put it in the “wheel” group (Mandatory for using the “su root” command).
Enable the SSHD daemon
Install Bash Shell
Personally I prefer working with the Bash Sell.
Download and Install the Bash shell:
pkg_add -r bash
(“-r“ option is for remote downloading: FTP). Then, using this command:
chpass username
and modify the shell with the Bash : /usr/local/bin/bash
Customizing the bash profile for displaying the actual directory in the prompt:
cd
cp .profile .bash_profile
And put these lines at the end of this file:
# set prompt: ``username@hostname:/directory $ ''
PS1="[\u@\h:\w] "
case `id -u` in 0)
PS1="${PS1}# ";; *)
PS1="${PS1}$ ";;
esac
Configuring the supfile copy the example supfile on the /etc with this command:
cp /usr/share/examples/cvsup/stable-supfile /etc/supfile
cp /usr/share/examples/cvsup/ports-supfile /etc/ports-supfile
Found the nearest CVSUP server of you on this mirror list: http://www.freebsd.org/doc/handbook/cvsup.html#CVSUP-MIRRORS
Editing the /etc/supfile and /etc/ports-suppfile and modify this line:
*default host=cvsup.fr.FreeBSD.org
After installing FreeBSD patches, rebuild (compile) all the program with dynamic library for save disk space.
Editing /etc/make.conf:
vi /etc/make.conf
Create /etc/make.conf and put the following lines in it:
NO_SHARED=no
Then use this commands for re-build all the source: (take some long time)
cd /usr/src
make -j4 buildworld
make buildkernel
make installkernel
reboot (in single user mode: boot -s from the loader prompt)
fsck -p
mount -u /
mount -a -t ufs
swapon -a
adjkerntz -i
mergemaster -p
cd /usr/src
make installworld
make delete-old
mergemaster
reboot
make delete-old-libs
Here is I will explain how to install the tools and PHP script use for FreeNAS...
If this instruction are not clear, download the last FreeNAS rootfilesystem .tgz file and compare the difference with yours.
Use the script freenas-create-dirs.sh (don't forget to change the MINIBSD_DIR variable with your setting before using it):
fetch http://freenas.svn.sourceforge.net/viewvc/*checkout*/freenas/trunk/misc/freenas-create-dirs.sh
./freenas-create-dirs.sh it will create the root dir for you...
Here is the content of this script:
#!/bin/sh
#
# This script was written by David Courtney of Ultradesic
# http://www.ultradesic.com
# E-Mail Contact: minibsd@ultradesic.com
#
# Adapted for FreeNAS by Olivier Cochard-Labbé (http://www.freenas.org)
# Modified by Volker Theile (votdev@gmx.de)
MINIBSD_DIR=/usr/local/freenas/rootfs;
# Initialize variables.
opt_f=0
# Parse the command-line options.
while getopts 'fh' option
do
case "$option" in
"f") opt_f=1;;
"h") echo "$(basename $0): Create FreeNAS directory structure";
echo "Common Options:";
echo " -f Force executing this script";
exit 1;;
?) echo "$0: Bad option specified. Exiting...";
exit 1;;
esac
done
shift `expr $OPTIND - 1`
echo "Create FreeNAS directory structure..."
if [ ! -z "$1" ]; then
MINIBSD_DIR=$1;
echo "Using directory $1.";
fi
if [ 1 != $opt_f -a -d "$MINIBSD_DIR" ]; then
echo ;
echo "$MINIBSD_DIR already exists. Remove the directory" ;
echo "before running this script." ;
echo ;
echo "Exiting..." ;
echo ;
exit 1 ;
fi ;
mkdir $MINIBSD_DIR ;
cd $MINIBSD_DIR ;
# Create directories
mkdir boot ;
mkdir boot/kernel ;
mkdir bin ;
mkdir cf ;
mkdir ftmp ;
mkdir conf.default ;
mkdir dev ;
mkdir etc ;
mkdir etc/defaults ;
mkdir etc/inc ;
mkdir etc/pam.d ;
mkdir etc/ssh ;
mkdir etc/iscsi ;
mkdir lib ;
mkdir lib/geom ;
mkdir libexec ;
mkdir -m 0777 mnt ;
mkdir -m 0700 root ;
mkdir sbin ;
mkdir usr ;
mkdir usr/bin ;
mkdir usr/lib ;
mkdir usr/lib/aout ;
mkdir usr/libexec ;
mkdir usr/local ;
mkdir usr/local/bin;
mkdir usr/local/lib ;
mkdir usr/local/sbin ;
mkdir usr/local/share ;
mkdir usr/local/share/locale ;
mkdir usr/local/etc ;
mkdir usr/local/www ;
mkdir usr/local/www/syntaxhighlighter ;
mkdir usr/sbin ;
mkdir usr/share ;
mkdir usr/share/misc ;
mkdir usr/share/locale ;
mkdir tmp ;
mkdir var ;
# Creating symbolic links. Most of the target files will be created at runtime.
ln -s cf/conf conf
ln -s /var/run/htpasswd usr/local/www/.htpasswd
ln -s /var/etc/resolv.conf etc/resolv.conf
ln -s /var/etc/master.passwd etc/master.passwd
ln -s /var/etc/passwd etc/passwd
ln -s /var/etc/group etc/group
ln -s /var/etc/hosts etc/hosts
ln -s /var/etc/pwd.db etc/pwd.db
ln -s /var/etc/spwd.db etc/spwd.db
ln -s /var/etc/crontab etc/crontab
ln -s /var/etc/ssh/sshd_config etc/ssh/sshd_config
ln -s /var/etc/ssh/ssh_host_dsa_key etc/ssh/ssh_host_dsa_key
ln -s /var/etc/iscsi/targets etc/iscsi/targets
ln -s /var/etc/pam.d/ftp etc/pam.d/ftp
ln -s /var/etc/pam.d/ftp etc/pam.d/pure-ftpd
ln -s /var/etc/pam.d/sshd etc/pam.d/sshd
ln -s /var/etc/pam.d/login etc/pam.d/login
ln -s /var/etc/pam.d/system etc/pam.d/system
ln -s /var/etc/ldap.conf usr/local/etc/ldap.conf
ln -s /var/etc/nsswitch.conf etc/nsswitch.conf
ln -s /libexec/ld-elf.so.1 usr/libexec/ld-elf.so.1
Here is the explanation of this directories:
/cf is where the Compact Flash card (or the hard disk, or the floppy disk) is mounted later on
/conf.default contains the factory default config.xml
/conf (or /cf/conf effectively due to the symlink) contains the current config.xml
/ftmp is used to mount a temporary memory file system during a firmware upgrade through the webGUI
/etc/inc contains PHP include files that are used by both the boot scripts and the webGUI
/usr/local/www contains the webGUI pages
the symbolic link for .htpasswd is required as the boot scripts will write the webGUI user/password to /var/run/htpasswd
/boot are used by fdisk ans bsdlabel
/boot/kernel will contain the kernel modules
This directory will become the root '/' on the FreeNAS OS, then it's normal that the symbolics links use link as '/var/etc/' (that is create when FreeNAS boot).
Download the file freenas.files that will be use with the mkmini.pl:
fetch http://freenas.svn.sourceforge.net/viewvc/*checkout*/freenas/trunk/misc/freenas.files
fetch http://www.freenas.org/downloads/mkmini.pl
This file contain the list of all the binary files used for this distribution.
Install Perl with this command:
pkg_add -r perl
Use the mkmini Perl script with this command (it will copy the file listed in freenas.files in the root directory:
perl mkmini.pl freenas.files / $FREENAS
Download the freenas-etc.tgz and decompress it in the $FREENAS/ directory:
fetch http://www.freenas.org/downloads/freenas-etc.tgz
tar -xzf freenas-etc.tgz -C $FREENAS/
Make sure that the rc.* files int etc/rc have the execute permission bits set (chmod 755).
After editing the $FREENAS/etc/master.passwd, generate newpassword database (pwd.db and spwd.db)by this command:
pwd_mkdb -p -d $FREENAS/etc $FREENAS/etc/master.passwd
For saving the file in a tgz, use this command:
tar cfvz freenas-etc.tgz $FREENAS/etc/*
Adding the version:
echo "0.67b" > $FREENAS/etc/version
Adding the version build time:
date > $FREENAS/etc/version.buildtime
Adding the platform:
/etc/platform identifies the platform for which the image is built and is very important, as the PHP scripts use it to determine e.g. how the configuration is to be stored or which options should be available in the webGUI. Possible values are:
generic-pc
generic-pc-cdrom
echo "generic-pc-cdrom" > $FREENAS/etc/platform
Download the latest default config.xml from http://www.freenas.org/downloads/config.xml and put it in $FREENAS/conf.default/config.xml:
cd $FREENAS/conf.default/
fetch http://www.freenas.org/downloads/config.xml
FreeBSD keeps time zone information files in /usr/share/zoneinfo. In order to save space, m0n0wall uses a stripped down version of the contents of that directory and keeps them in a tarball....Then FreeNAS do the same. Download zoneinfo.tgz from http://www.freenas/org/downloads/zoneinfo.tgz and place it in $FREENAS/usr/share/zoneinfo.tgz.
cd $FREENAS/usr/share/
fetch http://www.freenas.org/downloads/zoneinfo.tgz
Here is FreeBSD drivers for A100 SCSI controller (based on Initio 1060 chipset).
Download and install the drivers:
mkdir a100
cd a100
fetch http://www.freenas.org/downloads/bsd4a100.zip
gunzip bsd4a100.zip
cp a100.* /usr/src/sys/pci
echo "pci/a100.c optional ihb device-driver" >> /usr/src/sys/conf/files
Download the FreeNAS customized FreeBSD 6.1 kernel configuration file and copy it to /sys/i386/conf:
cd /sys/i386/conf/
fetch http://www.freenas.org/downloads/FREENAS
Then execute the following commands to compile the kernel and modules:
config FREENAS
cd ../compile/FREENAS/
make cleandepend; make depend
make
Compress the kernel using gzip:
gzip -9 kernel
The kernel will be installed later, as it doesn't go directly into the root file system.
If you want to modify the config file (for including modules for example), don't forget to delete the /sys/i386/compile/FREENAS_GENERIC directory, and re-start the config command.
If you have error message about the device "ihb", the drivers a100 is not correctly installed. You can remove this line from the kernel config file if you don't need them.
Copy some geom module (vinum, gpt, mirror, concact, etc..) and ntfs and ext2fs modules:
cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/geom/geom_vinum/geom_vinum.ko $FREENAS/boot/kernel
cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/geom/geom_stripe/geom_stripe.ko $FREENAS/boot/kernel
cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/geom/geom_concat/geom_concat.ko $FREENAS/boot/kernel
cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/geom/geom_mirror/geom_mirror.ko $FREENAS/boot/kernel
cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/geom/geom_gpt/geom_gpt.ko $FREENAS/boot/kernel
####cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/ntfs/ntfs.ko $FREENAS/boot/kernel
cp /sys/i386/compile/FREENAS_GENERIC/modules/usr/src/sys/modules/ext2fs/ext2fs.ko $FREENAS/boot/kernel/
Download and compile the experimental geom raid5 module
cd /usr/src
fetch http://home.tiscali.de/cmdr_faako/geom_raid5.tbz
tar zxvf geom_raid5.tbz
cd /usr/src/sys/modules/geom/geom_raid5/
make depend
make
cp geom_raid5.ko $FREENAS/boot/kernel/
cd /usr/src/sbin/geom/class/raid5/
mkdir /usr/include/geom/raid5
cp /usr/src/sys/geom/raid5/g_raid5.h /usr/include/geom/raid5/
make depend
make
make install
cp -p /sbin/graid5 $FREENAS/sbin/
mkdir $FREENAS/lib/geom/
cp geom_raid5.so $FREENAS/lib/geom/
Here the list of software compiled and added to FreeNAS. For some packages, the standard "./configure && make && make install" procedure can be used; others need a few extra configure options to produce a small binary.
Install libxml2 with this command:
pkg_add -r libxml2
PHP Download the latest version of PHP 5.2 from http://www.php.net and decompress as usual. Build/install as follows:
./configure --enable-fastcgi --enable-discard-path --enable-force-cgi-redirect --without-mysql --without-pear --with-openssl --without-sqlite --with-pcre-regex
make
install -s sapi/cgi/php $FREENAS/usr/local/bin
Put the following in $FREENAS/usr/local/lib/php.ini:
magic_quotes_gpc = Off
magic_quotes_runtime = Off
max_execution_time = 0
max_input_time = 180
register_argc_argv = Off
file_uploads = On
upload_tmp_dir = /ftmp
upload_max_filesize = 256M
post_max_size = 256M
html_errors = Off
include_path = ".:/etc/inc:/usr/local/www"
Download, compile and install Lighthttpd:
fetch http://www.lighttpd.net/download/lighttpd-1.4.13.tar.gz
tar zxvf lighttpd-1.4.13.tar.gz
cd lighttpd-1.4.13
./configure --sysconfdir=/var/etc/ --enable-lfs --without-mysql --without-ldap --with-openssl --without-lua --with-bzip2 --without-pam
make
install -s src/lighttpd $FREENAS/usr/local/sbin
mkdir $FREENAS/usr/local/bin/lighttpd
cp src/.libs/mod_indexfile.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_access.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_accesslog.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_dirlisting.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_staticfile.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_cgi.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_auth.so $FREENAS/usr/local/lib/lighttpd
cp src/.libs/mod_webdav.so $FREENAS/usr/local/lib/lighttpd
Get the clog patch and the syslog patched file (from the Pfsense project):
cd /usr/src/usr.bin/
fetch http://www.freenas.org/downloads/clog-1.0.1.tar.gz
fetch http://www.freenas.org/downloads/syslogd_clog-current.tgz
tar zxvf clog-1.0.1.tar.gz
tar zxvf syslogd_clog-current.tgz
cd syslogd
make
install -s syslogd $FREENAS/usr/sbin/
cd ../clog
gcc clog.c -o clog
install -s clog $FREENAS/usr/sbin/
Compile and install the MSNTP ports:
cd /usr/ports/net/msntp/
make
install -s work/msntp-1.6/msntp $FREENAS/usr/local/bin/
Then create this script:
vi $FREENAS/usr/local/bin/runmsntp.sh
And put this command in:
#!/bin/sh
# write our PID to file
echo $$ > $1
# execute msntp in endless loop; restart if it
# exits (wait 1 second to avoid restarting too fast in case
# the network is not yet setup)
while true; do
/usr/local/bin/msntp -r -P no -l $2 -x $3 $4
sleep 1
doneAnd change this permission:
chmod +x $FREENAS/usr/local/bin/runmsntp.sh
Compile and install the ataidle ports:
cd /usr/ports/sysutils/ataidle
make
install -s work/ataidle-0.9/ataidle $FREENAS/usr/local/sbin/
Download, compile and install the iscsi initiator:
fetch ftp://ftp.cs.huji.ac.il/users/danny/freebsd/iscsi-2.0.1.tar.bz2
tar zxvf iscsi-2.0.1.tar.bz2
cd sys
ln -s /sys/kern .
ln -s /sys/tools .
cd modules/iscsi_initiator
make clean
ln -s ../.. @
make
cp iscsi_initiator.ko $FREENAS/boot/kernel/
cd ../../../iscontrol/
make
install -s iscontrol $FREENAS/usr/local/sbin/
Download the latest source code:
cd /root
fetch http://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.21.tar.gz
tar zxvf pure-ftpd-1.0.21.tar.gz
cd pure-ftpd-1.0.21
./configure --with-rfc2640 --with-largefile --with-pam
make
install -s src/pure-ftpd $FREENAS/usr/local/sbin/
Get the last Samba source:
fetch http://us2.samba.org/samba/ftp/samba-latest.tar.gz
tar zxvf samba-latest.tar.gz
cd samba-3.0.23d/source/
Then configure and make the source:
./configure --without-cups --with-ads --disable-cups --without-ads --with-pam --with-ldapsam --with-acl-support --with-winbind --with-pam_smbpass --with-logfilebase=/var/log/samba --with-piddir=/var/run --with-privatedir=/var/etc/private --with-configdir=/var/etc --with-lockdir=/var/run --with-piddir=/var/run --with-shared-modules=idmap_rid --with-pammodulesdir=/usr/local/lib --with-syslog
make
install samba:
install -s bin/smbd $FREENAS/usr/local/sbin/
install -s bin/nmbd $FREENAS/usr/local/sbin/
install -s bin/winbindd $FREENAS/usr/local/sbin/
install -s bin/smbpasswd $FREENAS/usr/local/bin/
install -s bin/net $FREENAS/usr/local/bin/
install -s nsswitch/nss_winbind.so $FREENAS/usr/local/lib/
install -s nsswitch/nss_wins.so $FREENAS/usr/local/lib/
install -s bin/pam_winbind.so $FREENAS/usr/local/lib/
ln -s $FREENAS/usr/local/lib/nss_winbind.so $FREENAS/usr/local/lib/nss_winbind.so.1
mkdir $FREENAS/usr/local/samba/lib/idmap
mkdir $FREENAS/usr/local/samba/lib/vfs
install -s bin/rid.so $FREENAS/usr/local/samba/lib/idmap
mkdir $FREENAS/usr/local/lib/samba
mkdir $FREENAS/usr/local/lib/samba/charset
mkdir $FREENAS/usr/local/lib/samba/rpc
mkdir $FREENAS/usr/local/lib/samba/pdb
cp bin/CP*.so $FREENAS/usr/local/lib/samba/charset
cp codepages/*.dat $FREENAS/usr/local/lib/samba/
cp po/*.* $FREENAS/usr/local/lib/samba/
cp bin/recycle.so $FREENAS/usr/local/samba/lib/vfs
Install the NFS server with this commands:
cp /usr/sbin/nfsd $FREENAS/usr/sbin
cp /usr/sbin/mountd $FREENAS/usr/sbin
cp /usr/sbin/rpcbind $FREENAS/usr/sbin
Netatalk need the Database Berkeley for being compiling,
install the db 4. 2 port (or using "pkg_add -r db42") :
cd /usr/ports/databases/db42
make
make install
Then, download, compile and install netatalk:
fetch http://ovh.dl.sourceforge.net/sourceforge/netatalk/netatalk-2.0.3.tar.gz
tar zxvf netatalk-2.0.3.tar.gz
cd netatalk-2.0.3
./configure --bindir=/usr/local/bin --sbindir=/usr/local/sbin --sysconfdir=/var/etc --localstatedir=/var --enable-largefile --disable-tcp-wrappers --disable-cups --with-pam --with-uams-path=/etc/uams/
install -s etc/afpd/afpd $FREENAS/usr/local/sbin/
mkdir $FREENAS/etc/uams
cp etc/uams/.libs/uams_passwd.so $FREENAS/etc/uams
cp etc/uams/.libs/uams_dhx_passwd.so $FREENAS/etc/uams
cp etc/uams/.libs/uams_guest.so $FREENAS/etc/uams
cp etc/uams/.libs/uams_randnum.so $FREENAS/etc/uams
cd $FREENAS/etc/uams
ln -s uams_passwd.so uams_clrtxt.so
ln -s uams_dhx_passwd.so uams_dhx.so
cd $FREENAS/usr/local/lib/
cp /usr/local/lib/libdb-4.2.so.2 .
cd $FREENAS/usr/lib/
cp /usr/lib/librpcsvc.so.3 .
Download, compile and install RSYNC:
fetch http://samba.anu.edu.au/ftp/rsync/rsync-2.6.9.tar.gz
tar zxvf rsync-2.6.9.tar.gz
cd rsync-2.6.9
./configure --with-rsyncd-conf=/var/etc
make
install -s rsync $FREENAS/usr/local/bin/
Use the port for compiling Unison:
cd /usr/ports/net/unison/
make
cp work/unison-2.13.16/unison $FREENAS/usr/local/bin/
Compile and install the scponly 4.6 ports:
cd /usr/ports/shells/scponly/
Edit the Makefile, and add these lines:
WITH_SCPONLY_RSYNC=YES
WITH_SCPONLY_SCP=YES
WITH_SCPONLY_WINSCP=YES
WITH_SCPONLY_UNISON=YES
WITH_SCPONLY_SFTP_LOGGING=YES
make
install -s work/scponly-4.4/scponly $FREENAS/usr/local/bin/
Modify the Makefile of the openssh-portable port:
cd /usr/ports/security/openssh-portable
Replace this line:
HPN "Enable HPN-SSH patch" off \
With this line:
HPN "Enable HPN-SSH patch" on \
make
install -vs work/openssh-4.5p1/sshd $FREENAS/usr/sbin/
install -vs work/openssh-4.5p1/sftp-server $FREENAS/usr/libexec/
Compile and install the e2fsck ports:
cd /usr/ports/sysutils/fusefs-kmod
make
cp -pv work/fuse4bsd-*/mount_fusefs/mount_fusefs $FREENAS/usr/local/sbin/
cp -pv work/fuse4bsd-*/fuse_module/fuse.ko $FREENAS/boot/kernel
cd /usr/ports/sysutils/fusefs-ntfs/
make
cp -p work/ntfs-3g-0.20070118-BETA/libntfs-3g/.libs/libntfs-3g.so $FREENAS/usr/local/lib/libntfs-3g.so.0
install -s work/ntfs-3g-0.20070118-BETA/src/.libs/ntfs-3g $FREENAS/usr/local/bin/
install -s /usr/local/lib/libfuse.so.2 $FREENAS/usr/local/lib/
Compile and install the e2fsck ports:
cd /usr/ports/sysutils/e2fsprogs/
make
install -s work/e2fsprogs-1.39/e2fsck/e2fsck $FREENAS/usr/local/sbin/
Compile the SMART tools ports:
cd /usr/ports/sysutils/smartmontools/
make
install -s work/smartmontools-5.37/smartctl $FREENAS/usr/local/sbin/
install -s work/smartmontools-5.37/smartd $FREENAS/usr/local/sbin/
Compile the aaccli ports:
cd /usr/ports/sysutils/aaccli/
make
tar zxvf work/aaccli-1.0_0.tgz
cp work/bin/aaccli $FREENAS/usr/local/bin/
Compile the beep ports:
cd /usr/ports/audio/beep
make
install -s work/beep/beep $FREENAS/usr/local/bin/
Use the script freenas-create-bootdir.sh (don't forget to edit it before for setting the directory) for generating the file needed for booting.
Here is the contents of this script:
#!/bin/sh
#
# This script was written by David Courtney of Ultradesic
# http://www.ultradesic.com
# E-Mail Contact: minibsd@ultradesic.com
#
# Adapted for m0n0wall on FreeBSD 6.1 by Olivier Cochard-Labbé (http://www.freenas.org)
# Modified by Volker Theile (votdev@gmx.de)
MINIBSD_DIR=/usr/local/freenas/bootloader;
# Initialize variables.
opt_a=0
opt_d=0
opt_s=0
opt_f=0
# Parse the command-line options.
while getopts 'adfhs' option
do
case "$option" in
"a") opt_a=1;;
"d") opt_d=1;;
"f") opt_f=1;;
"s") opt_s=1;;
"h") echo "$(basename $0): Build boot loader";
echo "Common Options:";
echo " -a Disable ACPI"
echo " -d Enable debug"
echo " -s Enable serial console";
echo " -f Force executing this script";
exit 1;;
?) echo "$0: Bad option specified. Exiting...";
exit 1;;
esac
done
shift `expr $OPTIND - 1`
echo "Building the boot loader..."
if [ -n "$1" ]; then
MINIBSD_DIR=$1
echo "Using directory $1."
fi
if [ 1 != $opt_f -a -d "$MINIBSD_DIR" ]; then
echo
echo "=> $MINIBSD_DIR already exists. Remove the directory"
echo "=> before running this script."
echo
echo "=> Exiting..."
echo
exit 1
fi
# Create the boot directory that will contain boot, and kernel
mkdir $MINIBSD_DIR
mkdir $MINIBSD_DIR/defaults
mkdir $MINIBSD_DIR/kernel
# Copy the file in this directory:
cp -v /boot/defaults/loader.conf $MINIBSD_DIR/defaults
cp -v /boot/loader $MINIBSD_DIR
cp -v /boot/boot $MINIBSD_DIR
cp -v /boot/mbr $MINIBSD_DIR
cp -v /boot/cdboot $MINIBSD_DIR
cp -v /boot/loader.4th $MINIBSD_DIR
cp -v /boot/support.4th $MINIBSD_DIR
cp -v /boot/device.hints $MINIBSD_DIR
# Generate the loader.rc file using by bootloader
echo "Generate $MINIBSD_DIR/loader.rc"
echo 'include /boot/loader.4th
start
check-password' > $MINIBSD_DIR/loader.rc
# Generate the loader.conf file using by bootloader
echo "Generate $MINIBSD_DIR/loader.conf"
echo 'mfsroot_load="YES"
mfsroot_type="mfs_root"
mfsroot_name="/mfsroot"
autoboot_delay="-1"' > $MINIBSD_DIR/loader.conf
# Enable debug?
if [ 0 != $opt_d ]; then
echo 'verbose_loading="YES"' >> $MINIBSD_DIR/loader.conf
echo 'boot_verbose=""' >> $MINIBSD_DIR/loader.conf
fi
# Enable serial console?
if [ 0 != $opt_s ]; then
echo 'console="comconsole"' >> $MINIBSD_DIR/loader.conf
fi
# Disable ACPI?
if [ 0 != $opt_a ]; then
echo 'hint.acpi.0.disabled="1"' >> $MINIBSD_DIR/device.hints
fi
# Copy kernel.
if [ -e "/usr/obj/usr/src/sys/FREENAS/kernel.gz" ] ; then
cp /usr/obj/usr/src/sys/FREENAS/kernel.gz $MINIBSD_DIR/kernel
else
echo "=> ERROR: File kernel.gz does not exist!";
exit 1;
fiIf you don't want to use ACPI:
Adding this line to the loader.rc:
set hint.acpi.0.disabled="1"
For debug mode, add this line:
verbose_loading="YES"
boot_verbose=""
For serial support, add this line:
console="comconsole"
None of the dynamically linked libraries that are needed have been added yet. This is because a Perl script, mklibs.pl, can be run on the root file system to create a list of libraries that are actually needed (mklibs.pl does this by running ldd on each binary).
fetch http://www.freenas.org/downloads/mklibs.pl
perl mklibs.pl $FREENAS > freenas.libs
perl mkmini.pl freenas.libs / $FREENAS
Adding the PAM library:
cp -p /usr/lib/pam_*.so.3 $FREENAS/usr/lib
The LDAP PAM are not bulding by default:
cd /usr/ports/security/pam_ldap/
make install
cp -p /usr/local/lib/pam_ldap.so $FREENAS/usr/local/lib
Don't forget to copy this mandatory library :
cp /libexec/ld-elf.so.1 $FREENAS/libexec
For GEOM tools, there is other library to copy too:
mkdir $FREENAS/lib/geom
cp /lib/geom/geom
cp /lib/geom
Download the FreeNAS GUI files and copy them to $FREENAS/usr/local/www
Make sure that all *.php files have the execute permission bits set (chmod 755).
fetch http://www.freenas.org/downloads/freenas-gui.tgz
tar -zxvf freenas-gui.tgz -C $FREENAS
This step will create the compressed system image that will be run from the RAM disk.
First of all, a zero-filled image file needs to be created. The current size is 32 MB, which should be enough to fit all the files in the root file system. If you add big components, you may need to increase this. However, don't make it much bigger than necessary, as the MFS will take up as much space as you specify here, even if the file system is not full.
Use the script freenas-create-msfroot.sh (don't forget to edit it before for setting the directory):
fetch http://www.freenas.org/downloads/freenas-create-msfroot.sh
./freenas-create-msfroot.sh
Here is the contents of this script:
#!/bin/sh
# Generate the mfs ROOT file system
#Setting directory
WORKINGDIR="/usr/local/freenas"
FREENAS="/usr/local/freenas/rootfs"
CDROOT="/usr/local/freenas/cdroot"
BOOTDIR="/usr/local/freenas/bootloader"
#lauching the script
# Remove old file
if [ $WORKINGDIR/mfsroot.gz ] ; then
echo ;
echo "mfsroot.gz already exists. Removing this file" ;
echo ;
rm $WORKINGDIR/mfsroot.gz;
#exit ;
fi ;
# umount the /mnt directory
umount /mnt
# Remove the memory file
mdconfig -d -u 0
# Create a 32Mb empty file
dd if=/dev/zero of=$WORKINGDIR/mfsroot bs=1k count=32768
# Configure this file as a virtual disk
mdconfig -a -t vnode -f $WORKINGDIR/mfsroot -u 0
# Create Label on this disk
bsdlabel -w md0 auto
# format it
newfs -b 8192 -f 1024 -o space -m 0 /dev/md0c
# Mount it
mount /dev/md0c /mnt
# Copy the file on it
cd /mnt
tar -cf - -C $FREENAS ./ | tar -xvpf -
cd $WORKINGDIR
# umount the /mnt directory
umount /mnt
# Remove the memory file
mdconfig -d -u 0
echo Compresing....
gzip -9 mfsrootThis is very similar to creating the mfsroot.
Use the script freenas-create-image.sh (don't forget to edit it before for setting the directory):
fetch http://www.freenas.org/downloads/freenas-create-image.sh
./freenas-create-image.sh
it will create the image file for you...
Here is the content of this script:
#!/bin/sh
# FreeNAS script for generating .img
# setting variables
FREENAS="/usr/local/freenas/rootfs"
WORKINGDIR="/usr/local/freenas"
CDROOT="/usr/local/freenas/imgroot"
BOOTDIR="/usr/local/freenas/bootloader"
PLATFORM="generic-pc"
VERSION=`cat $FREENAS/etc/version`
ISOFILENAME="FreeNAS-$PLATFORM-$VERSION.img"
# Remove old directory
if [ -d $CDROOT ] ; then
echo ;
echo "$CDROOT already exists. Removing this directory" ;
echo ;
echo ;
rm -rf $CDROOT;
#exit ;
fi ;
if [ $WORKINGDIR/$ISOFILENAME ] ; then
echo ;
echo "$ISOFILENAME already exists. Removing this directory" ;
echo ;
echo ;
rm $WORKINGDIR/$ISOFILENAME;
#exit ;
fi ;
echo $PLATFORM > $FREENAS/etc/platform
date > $FREENAS/etc/version.buildtime
$WORKINGDIR/freenas-create-mfsroot.sh
echo Generating $CDROOT folder
mkdir $CDROOT
#Creating a 16Mb empty file
dd if=/dev/zero of=image.bin bs=1k count=18432
#use this file as a virtual RAM disk
mdconfig -a -t vnode -f image.bin -u 0
#Create partition on this disk
fdisk -BI -b $BOOTDIR/mbr /dev/md0
#Create label on this disk
bsdlabel -B -w -b $BOOTDIR/boot /dev/md0 auto
bsdlabel md0 >/tmp/label.$$
bsdlabel md0 |
egrep unused |
sed "s/c:/a:/" |
sed "s/unused/4.2BSD/" >>/tmp/label.$$
bsdlabel -R -B md0 /tmp/label.$$
rm -f /tmp/label.$$
#Create filesystem on this disk
newfs -b 8192 -f 1024 -o space -m 0 /dev/md0a
#Mount this disk
mount /dev/md0a $CDROOT
cp $WORKINGDIR/mfsroot.gz $CDROOT
mkdir $CDROOT/boot
mkdir $CDROOT/boot/kernel $CDROOT/boot/defaults
mkdir $CDROOT/conf
cp $FREENAS/conf.default/config.xml $CDROOT/conf
cp $BOOTDIR/kernel/kernel.gz $CDROOT/boot/kernel
cp $BOOTDIR/boot $CDROOT/boot
cp $BOOTDIR/loader $CDROOT/boot
cp $BOOTDIR/loader.conf $CDROOT/boot
cp $BOOTDIR/loader.rc $CDROOT/boot
cp $BOOTDIR/loader.4th $CDROOT/boot
cp $BOOTDIR/support.4th $CDROOT/boot
cp $BOOTDIR/defaults/loader.conf $CDROOT/boot/defaults/
cp $BOOTDIR/device.hints $CDROOT/boot
umount $CDROOT
mdconfig -d -u 0
gzip -9 image.bin
mv image.bin.gz $ISOFILENAME
# Cleaning directory and temp file
if [ $WORKINGDIR/mfsroot.gz ] ; then
echo ;
echo "cleaning mfsroot.gz" ;
echo ;
rm $WORKINGDIR/mfsroot.gz
fi;
if [ -d $CDROOT ] ; then
echo ;
echo "cleaning $CDROOT by Removing this directory" ;
echo ;
echo ;
rm -rf $CDROOT;
fi ;Before to create a Bootable CD, we must install CRDTools:
cd /usr/ports/sysutils/cdrtools
make
make install
Use the script freenas-create-cd.sh (don't forget to edit it before for setting the directory):
fetch http://www.freenas.org/downloads/freenas-create-cd.sh
./freenas-create-cd.sh
it will create the bootable CD ISO file for you...
Here is the content of this file:
#!/bin/sh
# FreeNAS script for generating iso file
FREENAS="/usr/local/freenas/rootfs"
WORKINGDIR="/usr/local/freenas"
CDROOT="/usr/local/freenas/cdroot"
BOOTDIR="/usr/local/freenas/bootloader"
PLATFORM="generic-pc-cdrom"
VERSION=`cat $FREENAS/etc/version`
ISOFILENAME="FreeNAS-$VERSION.iso"
#remove old directory
if [ -d $CDROOT ] ; then
echo ;
echo "$CDROOT already exists. Removing this directory" ;
echo "before running this script." ;
echo ;
#echo "Exiting..." ;
echo ;
rm -rf $CDROOT;
#exit ;
fi ;
echo "$PLATFORM" > $FREENAS/etc/platform
date > $FREENAS/etc/version.buildtime
$WORKINGDIR/freenas-create-mfsroot.sh
rm $WORKINGDIR/$ISOFILENAME
echo Generating $CDROOT folder
mkdir $CDROOT
cp $WORKINGDIR/mfsroot.gz $CDROOT
mkdir $CDROOT/boot
mkdir $CDROOT/boot/kernel $CDROOT/boot/defaults
cp $BOOTDIR/kernel/kernel.gz $CDROOT/boot/kernel
cp $BOOTDIR/cdboot $CDROOT/boot
cp $BOOTDIR/loader $CDROOT/boot
cp $BOOTDIR/loader.conf $CDROOT/boot
cp $BOOTDIR/loader.rc $CDROOT/boot
cp $BOOTDIR/loader.4th $CDROOT/boot
cp $BOOTDIR/support.4th $CDROOT/boot
cp $BOOTDIR/defaults/loader.conf $CDROOT/boot/defaults/
cp $BOOTDIR/device.hints $CDROOT/boot
###### BEGIN: NEW RELEASE CHANGE ######
$WORKINGDIR/freenas-create-image.sh
cp $WORKINGDIR/FreeNAS-generic-pc-$VERSION.img $CDROOT/FreeNAS-generic-pc.gz
###### END: NEW RELEASE CHANGE ######
mkisofs -b "boot/cdboot" -no-emul-boot -A "FreeNAS CD-ROM image" -c "boot/boot.catalog" -d -r -publisher "freenas.org" -p "Olivier Cochard" -V "freenas_cd" -o "$ISOFILENAME" $CDROOT
if [ -d $CDROOT ] ; then
echo ;
echo "Cleaning directory" ;
echo ;
echo ;
rm -rf $CDROOT;
rm mfsroot.gz;
#exit ;
fi ;
Create the tftpboot folder:
mkdir /tftpboot
$TFTPBOOT=/tftpboot
export TFTBOOT
Recompile the PXE boot loader for booting from TFTP in the place of NFS:
cd /sys/boot
make clean
make LOADER_TFTP_SUPPORT=yes
cp /usr/obj/usr/src/sys/boot/i386/pxeldr/pxeboot $TFTPBOOT
cp mfsroot.gz $TFTPBOOT
Create a new directory to hold the contents of the CD-ROM in $CDROOT.
Then copying the file on the /tftpboot folder:
cp $BOOTDIR/kernel/kernel.gz $TFTPBOOT/boot/kernel
cp $BOOTDIR/kernel/acpi.ko $TFTPBOOT/boot/kernel
This section describe the scripts in /etc and /etc/inc
Here are the files used:
Table 3.1. Startup files listing
| dir | filename | description |
| config.xml | XML configuration file | |
| /etc/ | rc | First launched script |
| /etc/ | rc.bootup | Launch all the services. |
| /etc/ | rc.banner | Display version and IP information |
| /etc/ | rc.initial | Configuration menu |
| /etc/ | rc.initial.setports | Link physical interface with name |
| /etc/ | rc.initial.setlanip | Configure the IP adress of "lan" interface |
| /etc/ | rc.initial.password | Reset the password for WebGUI |
| /etc/ | rc.initial.defaults | reset the configuration |
| /etc/ | rc.initial.reboot | Reboot the system |
| /etc/ | rc.initial.ping | Ping an IP adress |
| /etc/ | rc.initial.install | Install FreeNAS on harddrive or CF |
| /etc/inc/ | global.inc | Set the global variable |
| /etc/inc/ | config.inc | Parse the config file |
| /etc/inc/ | functions.inc | Group the files |
| /etc/inc/ | xmlparse.inc | Parse the XML config file |
| /etc/inc/ | util.inc | Lot's of utilities |
| /etc/inc/ | system.inc | Configure system part (hostname, hosts,etc..) |
| /etc/inc/ | interface.inc | Configure interface (loopack, Ethernet, etc..) |
| /etc/inc/ | disks.inc | Manage disk and mount point |
| /etc/inc/ | ||
| /etc/inc/ | ||
| /etc/inc/ | ||
| /etc/inc/ | ||
| /etc/inc/ | ||
| /etc/inc/ |
This script does:
set the PATH and HOME variable
TESTING: Force the mount of / to RW
Make some directory in /var
Adjust local time CMOS clock to reflect time zone changes and keep current timezone offset for the kernel
Create an initial utmp file
Run ldconfig
launch /etc/rc.bootup
launch /etc/rc.banner
This script display the console menu and launch the initial configuration script.
This script is launched by the menu (rc.initial) and configure link the physical interface with a name.
This script is launched by the menu (rc.initial) and configure the IP of the interface "lan".
This script does:
Ask the IP address and test the result with is_ipaddr()
Ask the Subnet Mask and test the result with is_numeric() and between 1 and 31
If the Web interface is in HTTPS mode, ask for HTTP mode (Why??)
Save the configuration: write_config()
Configure the IP adresse: interfaces_lan_configure()
Display the new IP adress
This script is launched by the menu (rc.initial) reset the password to the default.
This script is launched by the menu (rc.initial) install FreeNAS on an harddrive or CF.
This script manage disk detection and volume mountage.
TO DO:
- Using dmesg message for adding information to a variable?
- Detecte physical disks and partitions.
- Menu disk: Put in variable the formattet result of (atacontrol list ) the line that contain "ad" only.
- Menu partition, (fdisk) where we see all the existing partitions, create, mount, etc....
This script manage the detected disks:
- Saving disk detection information in XML
- For check missing disk after a reboot ?
- Create directory /mnt/device
- mount the device configured in
This script looks for and loads the XML config file.
It defines some functions too.
This script does:
Get the platform type: cdrom, cf, etc…
If we are in « booting » mode then it :
Look for the file “config.xml” on all possible storage place
Write the storage place in the file “cfdevice » (whitch is use by the upgrade script « rc.firmware”)
Create the fstab with the partition containing the file “config.xml”
Mount all filesystem
In parse mode (variable “noparseconfig” NOT set):
Lock the config filen: config_lock()
If there is a config.xml in the cache : use it, else :
In “cdrom” and “booting”: Ask for insering a floppy disk for the configuration save and reset_factory_defaults()
Load the config.xml in the variable $config : parse_xml_config()
Test the config file version : Display a warning if the config file is more recent than m0n0wall
Create the config cache
Unlock the config file: config_unlock()
make alias table (for faster lookups): alias_make_table()
This script looks for and loads the XML config file.
It defines some functions too.
This script does:
Get the platform type: cdrom, cf, etc…
If we are in « booting » mode then it :
Look for the file “config.xml” on all possible storage place
Write the storage place in the file “cfdevice » (whitch is use by the upgrade script « rc.firmware”)
Create the fstab with the partition containing the file “config.xml”
Mount all filesystem
In parse mode (variable “noparseconfig” NOT set):
Lock the config filen: config_lock()
If there is a config.xml in the cache : use it, else :
In “cdrom” and “booting”: Ask for insering a floppy disk for the configuration save and reset_factory_defaults()
Load the config.xml in the variable $config : parse_xml_config()
Test the config file version : Display a warning if the config file is more recent than m0n0wall
Create the config cache
Unlock the config file: config_unlock()
make alias table (for faster lookups): alias_make_table()
This script defined all the function called “system_*” that are used for the configuration of the system itself (hostname, syslog, routing, etc…).
Here is the list of defined functions:
Table 3.2. Functions lists
| Name | Descriptions |
| system_resolvconf_generate() | Generate the resolv.conf file |
| system_hosts_generate() | Generate the hosts file |
| system_hostname_configure() | Configure the hostname |
| system_routing_configure() | Clean up and install IP routes |
| system_routing_enable() | Enable IP forwarding |
| system_syslogd_start() | Generate the syslog file and process |
| system_pccard_start() | Launch PCcard service |
| system_webgui_start() | Configure and start mini_httpd |
| system_password_configure() | Generate the htpasswd file |
| system_timezone_configure() | Generate /etc/local/timezone |
| system_ntp_configure() | Start ntp client with the timeserver configured |
| system_reboot() | |
| system_reboot_sync() | |
| system_reboot_cleanup() | |
| system_do_shell_commands() | |
| system_do_extensions() | |
| system_console_configure() | |
| system_dmesg_save() | Save dmesg to dmesg.boot |
| system_set_harddisk_standby() | |
| system_polling_configure() | |
| system_set_termcap() | |
This section describe the PHP file in /usr/local/www
Table 3.3. Files lists
| name | Description |
|---|---|
| index.php | Start page that display system information |
| fbegin.inc | Page header and Left menu |
| fend.inc | Page food (link to licence) |
| guiconfig.inc | Define global variable and functions |
| disks_show.php | Display detected phyisical disks |
| isks_mount.php | Display the mount point |
| disks_mount_edit.php | Add a mount point |
| disks_tools.php | Provide some tools: Format, check, etc.. |
This file define the global variable and functions that will be used with the other pages.
This script does:
Define the header for no caching
Define the dirty path
Define lot's of common variable
Define lot's of functions
Table 3.4. List of functions define in guiconfig.inc
| name | description |
|---|---|
| do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) | check for bad control characters |
| print_input_errors($input_errors) | |
| exec_rc_script($scriptname) | |
| exec_rc_script_async($scriptname) | |
| verify_gzip_file($fname) | |
| print_info_box_np($msg) | |
| print_info_box($msg) | |
| format_bytes($bytes) | |
| get_std_save_message($ok) | |
| pprint_address($adr) | |
| pprint_port($port) | |
| filter_rules_sort() | |
| nat_rules_sort() | |
| nat_1to1_rules_sort() | |
| nat_server_rules_sort() | |
| nat_out_rules_sort() | |
| pptpd_users_sort() | |
| captiveportal_users_sort() | |
| staticroutes_sort() | |
| hosts_sort() | |
| domainoverrides_sort() | |
| staticmaps_sort($if) | |
| aliases_sort() | |
| ipsec_mobilekey_sort() | |
| proxyarp_sort() | |
| passthrumacs_sort() | |
| allowedips_sort() | |
| wol_sort() | |
| ipsec_ca_sort() | |
| mount_sort() | |
This page display the detected ATA and SCSI drive detected.
It will be use for check that the hardware RAID disks are invisible to FreeNAS (because managed by the RAID Bios).
This page display the configured mount point.
Bug: the < and > character are bad interpreted in HTML. Must use htmlspecialchar().