dev.FreshPorts.org now using jail

The jail approach mentioned in previous articles has been implemented on the dev system. It took about 4 hours of coding this afternoon.

The setup script

I spent some time today gathering together the stuff I’d mentioned in the two previous posts on this topic. The result is a one-line command which will create a chroot environment, complete with mount points and scripts, and output the required /etc/fstab entries. I created a Jail subdirectory in the main scripts directory. In there, we have:

$ find .
.
./CVS
./CVS/Root
./CVS/Repository
./CVS/Entries
./scripts
./scripts/CVS
./scripts/CVS/Root
./scripts/CVS/Repository
./scripts/CVS/Entries
./scripts/vars.sh
./scripts/make-port.sh
./scripts/make-master-port-test.sh
./scripts/make-category-comment.sh
./README.txt
./create-jail-directories.sh
$ cat README.txt
FreshPorts now uses a chroot strategy for extracting information from the ports tree.

To create the chroot structure, which I often refer to as a jail, issue the
following command:

 ./create-jail-directories.sh ~/tmp/JAIL /home/dan/PORTS-SVN

The directory structure will be created at ~/tmp/JAIL
The system expects an up-to-date copy of the ports tree at /home/dan/PORTS-SVN
The scripts required for the jail will be copied to the base directory of
the jail.  These scripts are located in the scripts subdirectory relative to
the file you are reading now.

This script will output a number of mount points which need to be added to
/etc/fstab.  After doing that, issue a 'mount -a' command and your jail
structure is complete and ready to do.

To setup my jail directory, I issued this command:

$ ./create-jail-directories.sh /var/FreshPorts/jail /wdc/dan/PORTS-SVNSVN

# Put the following in /etc/fstab
/wdc/dan/PORTS-SVN              /var/FreshPorts/jail/usr/ports        nullfs  ro,nosuid,noexec        0       0
/usr/share/mk                   /var/FreshPorts/jail/usr/share/mk     nullfs  ro,nosuid,noexec        0       0
/usr/sbin                       /var/FreshPorts/jail/usr/sbin         nullfs  ro,nosuid               0       0
/usr/bin                        /var/FreshPorts/jail/usr/bin          nullfs  ro,nosuid               0       0
/libexec                        /var/FreshPorts/jail/libexec          nullfs  ro,nosuid               0       0
/usr/lib                        /var/FreshPorts/jail/usr/lib          nullfs  ro,nosuid               0       0
/sbin                           /var/FreshPorts/jail/sbin             nullfs  ro,nosuid               0       0
/lib                            /var/FreshPorts/jail/lib              nullfs  ro,nosuid               0       0
/bin                            /var/FreshPorts/jail/bin              nullfs  ro,nosuid               0       0
none                            /var/FreshPorts/jail/dev              devfs   rw                      0       0

As you can see, the root directory is populated with the required scripts:

$ ls /var/FreshPorts/jail
bin                      lib                      make-category-comment.sh make-port.sh             usr
dev                      libexec                  make-master-port-test.sh sbin                     vars.sh

The code changes

The source code changes were pretty minimal. I’ll let you judge for yourself:

cvs diff: Diffing .
Index: category.pm
===================================================================
RCS file: /home/repositories/freshports-1/scripts/category.pm,v
retrieving revision 1.10
diff -u -r1.10 category.pm
--- category.pm	18 Dec 2009 17:22:04 -0000	1.10
+++ category.pm	29 Dec 2012 21:48:04 -0000
@@ -202,10 +202,11 @@
 
 	chdir "$MakefileDirectory";
 
-	my $makecommand = "make -V COMMENT " .
-	               "DISTDIR=$FreshPorts::Constants::DISTDIR " .
-	               "PORTSDIR=$FreshPorts::Config::path_to_ports LOCALBASE=/nonexistentlocal 2>$TmpFile";
+#	my $makecommand = "make -V COMMENT " .
+#	               "DISTDIR=$FreshPorts::Constants::DISTDIR " .
+#	               "PORTSDIR=$FreshPorts::Config::path_to_ports LOCALBASE=/nonexistentlocal 2>$TmpFile";
 	
+	my $makecommand = "/usr/local/bin/sudo /usr/sbin/chroot -u $FreshPorts::Config::JailUser $FreshPorts::Config::JailBaseDir $FreshPorts::Config::JailCategoryDescrptionScript $category 2>$TmpFile";
 	print "makecommand = $makecommand\n";
 
 	my $MakeResults = `$makecommand`;
Index: port.pm
===================================================================
RCS file: /home/repositories/freshports-1/scripts/port.pm,v
retrieving revision 1.69
diff -u -r1.69 port.pm
--- port.pm	25 Sep 2012 18:11:23 -0000	1.69
+++ port.pm	29 Dec 2012 21:48:04 -0000
@@ -442,14 +442,16 @@
 	# IF YOU CHANGE THE MAKE COMMAND, CHANGE THE SPLIT!!!!!!!!!!!!!!!
 	#
 	#
-	$makecommand = "make -V PORTNAME -V PKGNAME -V DESCR -V CATEGORIES -V PORTVERSION -V PORTREVISION " .
-		" -V COMMENT -V COMMENTFILE -V MAINTAINER -V EXTRACT_SUFX " .
-		" -V BUILD_DEPENDS -V RUN_DEPENDS -V LIB_DEPENDS -V FORBIDDEN -V BROKEN -V DEPRECATED -V IGNORE ".
-		" -V MASTER_PORT -V LATEST_LINK -V NO_LATEST_LINK -V NO_PACKAGE -V PKGNAMEPREFIX -V PKGNAMESUFFIX -V PORTEPOCH " .
-		" -V RESTRICTED -V NO_CDROM -V EXPIRATION_DATE -V IS_INTERACTIVE " . 
-		" -V ONLY_FOR_ARCHS -V NOT_FOR_ARCHS -V LICENSE -f $Makefile " .
-		" DISTDIR=$FreshPorts::Constants::DISTDIR " .
-		" PORTSDIR=$FreshPorts::Config::path_to_ports LOCALBASE=/nonexistentlocal 2>$TmpFile";
+#	$makecommand = "make -V PORTNAME -V PKGNAME -V DESCR -V CATEGORIES -V PORTVERSION -V PORTREVISION " .
+#		" -V COMMENT -V COMMENTFILE -V MAINTAINER -V EXTRACT_SUFX " .
+#		" -V BUILD_DEPENDS -V RUN_DEPENDS -V LIB_DEPENDS -V FORBIDDEN -V BROKEN -V DEPRECATED -V IGNORE ".
+#		" -V MASTER_PORT -V LATEST_LINK -V NO_LATEST_LINK -V NO_PACKAGE -V PKGNAMEPREFIX -V PKGNAMESUFFIX -V PORTEPOCH " .
+#		" -V RESTRICTED -V NO_CDROM -V EXPIRATION_DATE -V IS_INTERACTIVE " . 
+#		" -V ONLY_FOR_ARCHS -V NOT_FOR_ARCHS -V LICENSE -f $Makefile " .
+#		" DISTDIR=$FreshPorts::Constants::DISTDIR " .
+#		" PORTSDIR=$FreshPorts::Config::path_to_ports LOCALBASE=/nonexistentlocal 2>$TmpFile";
+		
+    $makecommand = "/usr/local/bin/sudo /usr/sbin/chroot -u $FreshPorts::Config::JailUser $FreshPorts::Config::JailBaseDir $FreshPorts::Config::JailPortScript $this->{category}/$this->{name} 2>$TmpFile";
 
 	print "makecommand = $makecommand\n";
 
@@ -801,7 +803,7 @@
 	return $result;
 }
 
-sub _FetchFilesNeedingRefresh {
+sub _FetchFilesNeedingRefresh_DELETE_ME {
 	# returns 0 for success, 1 for failure
 	# a return of -1 indicates an error.
 
@@ -858,7 +860,7 @@
 
 		my $makecommand = "make -V DESCR -f $SVNDIR/$SVNITEM PORTSDIR=$FreshPorts::Config::path_to_ports " .
 		                  "LOCALBASE=/nonexistentlocal 2>$TmpFile";
-
+		                  
 		print "makecommand = $makecommand\n";
 		my $MakeResults = `$makecommand`;
 		my $Result = $?;
@@ -1040,7 +1042,7 @@
             }
             else
             {
-               $result = $this->_FetchFilesNeedingRefresh();
+               die('I have no idea what I am doing here in RefreshFromFiles....');
             }
 			if ($result == -1) {
 				$FetchAttempts = 0;
Index: test-master-port.sh
===================================================================
RCS file: /home/repositories/freshports-1/scripts/test-master-port.sh,v
retrieving revision 1.5
diff -u -r1.5 test-master-port.sh
--- test-master-port.sh	15 Aug 2012 11:48:47 -0000	1.5
+++ test-master-port.sh	29 Dec 2012 21:48:04 -0000
@@ -15,8 +15,7 @@
 
 MASTER='sysutils/bacula-server'
 
-cd ${PORTSDIR}/sysutils/bacula-client
-COMMAND="make -V MASTER_PORT PORTSDIR=${PORTSDIR} LOCALBASE=/nonexistentlocal X11BASE=/nonexistentx"
+COMMAND="/usr/local/bin/sudo /usr/sbin/chroot -u ${FRESHPORTS_JAIL_USER} ${FRESHPORTS_JAIL_BASE_DIR} ${FRESHPORTS_JAIL_MASTER_PORT_SCRIPT} sysutils/bacula-client"
 MASTER_PORT=`${COMMAND}`
 
 if [ "${MASTER_PORT}X" != "${MASTER}X" ]

Not shown are some changes to sample configuration files. They appear here:

--- scripts/config.sh.sample	2007/10/15 18:17:22	1.8
+++ scripts/config.sh.sample	2012/12/29 21:51:51	1.11
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $Id: config.sh.sample,v 1.8 2007/10/15 18:17:22 dan Exp $
+# $Id: config.sh.sample,v 1.11 2012/12/29 21:51:51 dan Exp $
 #
 
 # this must always be defined and functional.
@@ -71,3 +71,8 @@ fi
 
 # define your local cvsup host here
 FREEBSDCVSUPHOST="cvsup.unixathome.org"
+
+# scripts for the jail
+FRESHPORTS_JAIL_BASE_DIR="/var/FreshPorts/jail"
+FRESHPORTS_JAIL_MASTER_PORT_SCRIPT="/make-master-port-test.sh"
+FRESHPORTS_JAIL_USER="freshports"
--- scripts/config.pm.sample	2012/09/26 19:32:03	1.22
+++ scripts/config.pm.sample	2012/12/29 21:51:50	1.24
@@ -1,5 +1,5 @@
 #
-# $Id: config.pm.sample,v 1.22 2012/09/26 19:32:03 dan Exp $
+# $Id: config.pm.sample,v 1.24 2012/12/29 21:51:50 dan Exp $
 #
 # Copyright (c) 2001-2007 DVL Software
 #
@@ -129,4 +129,11 @@ $FreshPorts::Config::DB_Root_Prefix_SRC 
 
 $FreshPorts::Config::Ports_Default_Directory = $FreshPorts::Config::DB_Root_Prefix_PORTS . '/head';
 
+# scripts for the jail
+$FreshPorts::Config::JailBaseDir = '/var/FreshPorts/jail'
+
+$FreshPorts::Config::JailCategoryDescrptionScript = '/make-category-comment.sh';
+$FreshPorts::Config::JailPortScript               = '/make-port.sh';
+$FreshPorts::Config::JailUser                     = 'freshports';
+
 1;

visudo

The command to run in the chroot environment uses sudo. To allow that to happen without passwords, I’ve added the following lines to sudoers:

freshports      ALL=(ALL) NOPASSWD:/usr/sbin/chroot -u dan /wdc/dan/FreshPorts/ports-jail /make-port.sh *
freshports      ALL=(ALL) NOPASSWD:/usr/sbin/chroot -u dan /wdc/dan/FreshPorts/ports-jail /make-category-comment.sh *
freshports      ALL=(ALL) NOPASSWD:/usr/sbin/chroot -u dan /wdc/dan/FreshPorts/ports-jail /make-master-port-test.sh *

You will notice that I have used a wildcard at the end of the line. How big of a security risk is this? What could possibly go wrong there? The expected values are category names and port names (e.g. sysutils and sysutils/bacula-server, respectively). I guess I could make those more specific… Anyone want to take a try at that?

Left to do

  1. You can see I use the freshports user above. There is no such thing. I run these commands under my own user login. I should create a separate user.
  2. At present, this code is sitting in my development environment. I’ll check it in later.
  3. I need a new category to be created. Anyone got one ready to go? I guess I could test this by setting up my own SVN, committing to it, and using that for testing. One day… one day.
  4. All the ports need to refreshed now that we extract values from a jail. The script do to this exists. But it takes a long time to run it over all the ports.
Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

1 thought on “dev.FreshPorts.org now using jail”

Leave a Comment

Scroll to Top