Difference between revisions of "Web Application RPM"

From SME Server
Jump to navigationJump to search
m (Reverted edits by Cactus (Talk); changed back to last version by Snoble)
m (→‎Apache Authentication: add AuthBasicProvider directive)
 
(52 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 +
{{Level|Developer}}
 
=Generic Instructions for building a Web Application RPM=
 
=Generic Instructions for building a Web Application RPM=
  
Line 8: Line 9:
  
 
===Local Server===
 
===Local Server===
Create a build environment on your local server, refer to the SME Server Developer's Guide: [http://mirror.contribs.org/smeserver/contribs/gordonr/devguide/html/p1082.htm How to create an SME Server package - step by step]
+
Create a build environment on your local server, refer to the SME Server Developer's Guide: [[:SME_Server:Documentation:Developers_Manual#III._How_to_create_an_SME_Server_package_-_step_by_step | How to create a SME Server package - step by step]]
  
 
===SME Build Server===
 
===SME Build Server===
 
When you are comfortable building rpms, you are encouraged to put your source files on
 
When you are comfortable building rpms, you are encouraged to put your source files on
the SME Build Server, this allows others to more easily update and improve your rpms.
+
the SME Build Server, [[:Package Modification]], this allows others to more easily update and improve your rpms.
 
 
http://wiki.contribs.org/ReleasingContribs#Submitting_a_contrib_to_the_SME_Server_repository
 
  
 
==The Application RPM==
 
==The Application RPM==
Line 40: Line 39:
 
  BuildArchitectures: noarch
 
  BuildArchitectures: noarch
 
  BuildRoot: /var/tmp/%{name}-%{version}
 
  BuildRoot: /var/tmp/%{name}-%{version}
 +
BuildRequires: e-smith-devtools
 
  Requires: e-smith-release >= 7.0
 
  Requires: e-smith-release >= 7.0
 
  AutoReqProv: no
 
  AutoReqProv: no
Line 54: Line 54:
 
  %prep
 
  %prep
 
  %setup  -c -n %{name}
 
  %setup  -c -n %{name}
 +
 
  %build
 
  %build
 
  #drop in an unchanged .tgz, if required rename directory here, eg remove version number.
 
  #drop in an unchanged .tgz, if required rename directory here, eg remove version number.
Line 71: Line 72:
 
  cd ..
 
  cd ..
 
  rm -rf %{name}
 
  rm -rf %{name}
 
%pre
 
%preun
 
%post
 
%postun
 
 
   
 
   
 
  %files -f %{name}-%{version}-filelist
 
  %files -f %{name}-%{version}-filelist
Line 85: Line 81:
  
 
===Notes===
 
===Notes===
Add workarounds and alternate methods here ...
+
Permissions, may need tweaking but usually not many need changing, you don't want the webserver changing the distribution files.
  
Permissions, may need tweaking but usually not many need changing, you don't want the webserver changing the distribution files
+
Check the .spec files of other contribs, see the [http://fisheye1.cenqua.com/browse/smecontribs/rpms CVS (SME Contribs)]
  
==SME Intergration RPM==
+
==SME Server Intergration RPM==
  
 
===Create database===
 
===Create database===
Line 103: Line 99:
 
     my $pw = $rec->prop('DbPassword');
 
     my $pw = $rec->prop('DbPassword');
 
     return "" if $pw;
 
     return "" if $pw;
+
     $rec->set_prop('DbPassword', MIME::Base64::encode(int( (1000000000000000) * rand() )));
     $rec->set_prop('DbPassword', sprintf("%15.0f", int( (1000000000000000) * rand() )));
 
 
  }
 
  }
  
Line 136: Line 131:
  
 
The %post section of the spec file run the commands to initialise db values and create the db structure
 
The %post section of the spec file run the commands to initialise db values and create the db structure
 +
 +
===db defaults===
 +
Reserve the foo name in accounts and create default settings in configuration
 +
 +
Create files in these locations, with default values
 +
 +
root/etc/e-smith/db/accounts/defaults/foo
 +
root/etc/e-smith/db/accounts/defaults/foo/type > reserved
 +
 +
root/etc/e-smith/db/configuration/defaults/foo
 +
root/etc/e-smith/db/configuration/defaults/foo/type          > service
 +
root/etc/e-smith/db/configuration/defaults/foo/Name          > Helpdesk       
 +
root/etc/e-smith/db/configuration/defaults/foo/PublicAccess  > global-pw-remote
 +
root/etc/e-smith/db/configuration/defaults/foo/status        > enabled       
 +
root/etc/e-smith/db/configuration/defaults/foo/DbName        > foo           
 +
root/etc/e-smith/db/configuration/defaults/foo/DbUser        > foo           
 +
 +
root/etc/e-smith/templates.metadata/etc/e-smith/sql/init
 +
root/etc/e-smith/templates.metadata/etc/e-smith/sql/init/80foo  >  PERMS=0750
  
 
===Webserver templates===
 
===Webserver templates===
  
* The alias fragment tailored to suit the application
+
====Http Template 92Foo====
 
+
The alias fragment tailored to suit the application
 
root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
 
root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
  
Line 220: Line 234:
 
           $OUT .= "    AuthName \"$name\"\n";
 
           $OUT .= "    AuthName \"$name\"\n";
 
           $OUT .= "    AuthType Basic\n";
 
           $OUT .= "    AuthType Basic\n";
 +
          $OUT .= "    AuthBasicProvider external\n";
 
           $OUT .= "    AuthExternal pwauth\n";
 
           $OUT .= "    AuthExternal pwauth\n";
 
           $OUT .= "    require valid-user\n";
 
           $OUT .= "    require valid-user\n";
Line 228: Line 243:
 
  }
 
  }
  
* a workaround to enable the application to be located in a domain or subdomain root
+
====Apache Authentication====
 +
In the example above, all sme users can authenticate to the web folder /opt/foo, for an application with no matter in security, it is normal but in certain case it could be dangerous.
 +
* All users of SME Server
 +
The original template in /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
 +
      {
 +
          $OUT .= "    AuthName \"$name\"\n";
 +
          $OUT .= "    AuthType Basic\n";
 +
          $OUT .= "    AuthBasicProvider external\n";
 +
          $OUT .= "    AuthExternal pwauth\n";
 +
          '''$OUT .= "    require valid-user\n";'''
 +
          $OUT .= "    Satisfy $satisfy\n";
 +
      }
 +
* one user or several users
 +
Now you need to modify the 92foo template with these new lines
 +
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
 +
      {
 +
          $OUT .= "    AuthName \"$name\"\n";
 +
          $OUT .= "    AuthType Basic\n";
 +
          $OUT .= "    AuthBasicProvider external\n";
 +
          $OUT .= "    AuthExternal pwauth\n";
 +
          '''$OUT .= "    require user admin pierre paul\n";'''
 +
          $OUT .= "    Satisfy $satisfy\n";
 +
      }
 +
*one group or several groups with some specific users
 +
 
 +
You have to download a plugin of pwauth to authenticate unix group in SME Server 8 : http://code.google.com/p/pwauth/
 +
For SME Server 9 a nfr is raised see [[bugzilla:3690]]
 +
 
 +
wget http://pwauth.googlecode.com/files/pwauth-2.3.10.tar.gz
 +
tar xvzf pwauth-2.3.10.tar.gz
 +
cp pwauth-2.3.10/unixgroup /usr/lib/httpd/modules/
 +
chown root:www /usr/lib/httpd/modules/unixgroup
 +
chmod 750 /usr/lib/httpd/modules/unixgroup
 +
 
 +
We need to create a new fragment<br />
 +
 
 +
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/35-group-auth
 +
{
 +
        $OUT .= "    AddExternalGroup unixgroup /usr/lib/httpd/modules/unixgroup\n";
 +
        $OUT .= "    SetExternalGroupMethod unixgroup environment\n";
 +
}
 +
 
 +
Now you need to modify the 92foo template with these new lines
 +
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
 +
{
 +
          $OUT .= "    AuthName \"$name\"\n";
 +
          $OUT .= "    AuthType Basic\n";
 +
          $OUT .= "    AuthBasicProvider external\n";
 +
          $OUT .= "    AuthExternal pwauth\n";
 +
          $OUT .= "    GroupExternal unixgroup\n";
 +
          $OUT .= "    AuthzUserAuthoritative off\n";
 +
          '''$OUT .= "    require user admin pierre paul\n";'''
 +
          '''$OUT .= "    require group virt\n";'''
 +
          $OUT .= "    Satisfy $satisfy\n";
 +
}
 +
 
 +
*DB command to choose groups and users
 +
Above we have seen how to write name of groups or users directly in the template, but in the real life it is not enough good :)<br />
 +
 
 +
The purpose is to choose users or groups by command line.
  
root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/80OptDomainFoo
+
-In first you have to make other DB configuration as described [[Web_Application_RPM#db_defaults]]
 +
echo "admin" >        root/etc/e-smith/db/configuration/defaults/foo/User
 +
echo "" >              root/etc/e-smith/db/configuration/defaults/foo/Group
 +
Only the user admin is set by default
  
 +
-You have to download a plugin of pwauth to authenticate unix group in SME Server 8 : http://code.google.com/p/pwauth/
 +
wget http://pwauth.googlecode.com/files/pwauth-2.3.10.tar.gz
 +
tar xvzf pwauth-2.3.10.tar.gz
 +
cp pwauth-2.3.10/unixgroup /usr/lib/httpd/modules/
 +
chown root:www /usr/lib/httpd/modules/unixgroup
 +
chmod 750 /usr/lib/httpd/modules/unixgroup
 +
We need to create a new fragment<br />
 +
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/35-group-auth
 
  {
 
  {
    my $status = $foo{'status'} || "disabled";
+
        $OUT .= "     AddExternalGroup unixgroup /usr/lib/httpd/modules/unixgroup\n";
     return "    # foo-status is disabled.\n"
+
        $OUT .= "     SetExternalGroupMethod unixgroup environment\n";
            unless $status eq 'enabled';
+
}
 
   
 
   
    my $domain = $foo{'domain'} || "disabled";
+
 
    return "    # no hostname or domain for foo defined\n"
+
Now you need to modify the 92foo template with these new lines <br />
            if $domain eq 'disabled';
+
 
+
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
    my $DocRoot = "/opt/foo";
+
 
+
{
    $OUT = "";
+
$OUT .= "    AuthName \"$name\"\n";
    $OUT .= "\n";
+
          $OUT .= "    AuthType Basic\n";
    $OUT .= "# Redirect an existing hostname or domain to $DocRoot.\n";
+
          $OUT .= "    AuthExternal pwauth\n";
    $OUT .= "<VirtualHost 0.0.0.0:80>\n";
+
          $OUT .= "   GroupExternal unixgroup\n";
     $OUT .= "    ServerName  $domain\n";
+
          $OUT .= "   AuthzUserAuthoritative off\n";
    $OUT .= "    DocumentRoot $DocRoot\n";
+
          $OUT .= "   require user $foo{'User'}\n";
    $OUT .= "</VirtualHost>\n";
+
          $OUT .= "   require group $foo{'Group'}\n";
    $OUT .= "<VirtualHost 0.0.0.0:443>\n";
+
          $OUT .= "   Satisfy $satisfy\n";
    $OUT .= "    ServerName  $domain\n";
+
}
    $OUT .= "    DocumentRoot  $DocRoot\n";
+
 
    $OUT .= "    SSLEngine on\n";
+
-change groups and users allowed by CL
    $OUT .= "</VirtualHost>\n";
+
 
 +
config setprop foo User "admin toto"
 +
config setprop foo Group "famille virt"
 +
then
 +
signal-event console-save
 +
 
 +
=====SME Server 9=====
 +
The apache authentication is made by a new file named  authnz_external_module instead of auth_external_module, therefore you need to slightly modify the code above. <br />
 +
If it is not done you can have this error in log file and you won't be authenticated
 +
configuration error:  couldn't check user. No user file?:
 +
See this [http://code.google.com/p/mod-auth-external/wiki/ConfigApache22 howTo]. You need to verify if your /etc/httpd/conf/httpd.conf contain these lines
 +
AddExternalGroup unixgroup /usr/bin/unixgroup
 +
SetExternalGroupMethod unixgroup environment
 +
 
 +
We are waiting the default use of authenticator unixgroup in sme9 (see [[bugzilla:8008]]). For now you need to make the relevant fragment template.
 +
 
 +
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/35-group-auth
 +
{
 +
        $OUT .= "    AddExternalGroup unixgroup /usr/bin/unixgroup\n";
 +
        $OUT .= "     SetExternalGroupMethod unixgroup environment\n";
 +
}
 +
 
 +
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo
 +
 
 +
{
 +
$OUT .= "    AuthName \"$name\"\n";
 +
          $OUT .= "    '''AuthBasicProvider external'''\n";
 +
          $OUT .= "    AuthType Basic\n";
 +
          $OUT .= "   AuthExternal pwauth\n";
 +
          $OUT .= "   GroupExternal unixgroup\n";
 +
          $OUT .= "    AuthzUserAuthoritative off\n";
 +
          $OUT .= "    require user $foo{'User'}\n";
 +
          $OUT .= "    require group $foo{'Group'}\n";
 +
          $OUT .= "   Satisfy $satisfy\n";
 
  }
 
  }
  
* a hack to get https to work, a better solution is required
+
-change groups and users allowed by CL
 +
 
 +
config setprop foo User "admin toto"
 +
config setprop foo Group "famille virt"
 +
then
 +
signal-event console-save
 +
 
 +
====Upload_tmp_dir====
 +
Since SME Server V8, you could have sometime an error is thrown by PHP and you will need to  specify a temporary directory (e.g. upload_tmp_dir) which is not set in php.ini. see [[bugzilla:6650]] and [[bugzilla:7652]]. Many Php applications needs this setting, most of known are wordpress, roudcube, egroupware, etc. Symptoms are that you can't upload contents to the PHP application. 
 +
 
 +
An easy way is to make a Custom Template to resolve this issue.
 +
 
 +
see [[Uploadtmpdir]]
 +
 
 +
====Https_redirection====
 +
*a hack to get https to work, a better solution is required, you can see [[Https_redirection]]
  
 
root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30FooAlias
 
root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30FooAlias
Line 271: Line 404:
 
     }
 
     }
 
  }
 
  }
 +
 +
*or this solution which does the automatic redirection to https protocol, you have to choose either 30FooAlias or 60FooAlias but not both.
 +
 +
root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/60FooAlias
 +
 +
{
 +
    my $status = $foo{'status'} || "disabled";
 +
    return "    # foo is disabled in this VirtualHost"
 +
            unless $status eq 'enabled';
 +
 +
{
 +
if ($port ne "443")
 +
{
 +
$OUT .= <<'HERE';
 +
## Redirect Web Address to Secure Address
 +
RewriteEngine on
 +
RewriteRule ^/foo https://%{HTTP_HOST}/foo
 +
 +
## End Of Redirect
 +
HERE
 +
}
 +
}
 +
 +
}
 +
 +
*To enforce the security you can decide to prohibit all connexions which are not https. You need to add "SSLRequireSSL"  in the correct position of the 92foo template.
 +
 +
      $OUT .= "<Directory /opt/foo>\n";
 +
      '''$OUT .= "    SSLRequireSSL\n";'''
 +
      $OUT .= "    AddType application/x-httpd-php .php\n";
  
 
===System file templates===
 
===System file templates===
Line 276: Line 439:
 
You may need to create a fragment for a system file such as crontab.
 
You may need to create a fragment for a system file such as crontab.
  
http://mirror.contribs.org/smeserver/contribs/gordonr/devguide/html/c610.htm
+
http://wiki.contribs.org/SME_Server:Documentation:Developers_Manual
  
 
===Application templates===
 
===Application templates===
  
Include the original application config file in the templates directory, <br>
+
Preferably include the original application config file in the templates directory, <br>
 
then overwrite key values, some of which we keep in SME DB's
 
then overwrite key values, some of which we keep in SME DB's
  
 +
This is not always possible, eg your application modifies the config file <br>
 +
in this case leave the config file untemplated and advise the user how to configure manually.
  
 
eg . root\etc\template\opt\foo\config.php
 
eg . root\etc\template\opt\foo\config.php
Line 317: Line 482:
 
  // SME Server Settings
 
  // SME Server Settings
 
  {
 
  {
    $OUT .= "\$CFG->dbname  = \'$foo{DbName}\'\; \n";
+
  $OUT .= "\$CFG->dbname  = ini_get\(\'mysql.default_host\'\)\; \n";
    $OUT .= "\$CFG->dbuser  = \'$foo{DbUser}\'\; \n";
+
  $OUT .= "\$CFG->dbuser  = ini_get\(\'mysql.default_user\'\)\; \n";
    $OUT .= "\$CFG->dbpass  = \'$foo{DbPassword}\'\; \n";
+
  $OUT .= "\$CFG->dbpass  = ini_get\(\'mysql.default_password\'\)\; \n";
    $OUT .= "\$CFG->dirroot  = \'/opt/foo'\; \n";
+
  $OUT .= "\$CFG->dirroot  = \'/opt/foo'\; \n";
 
  }
 
  }
  
Line 358: Line 523:
 
   
 
   
 
  %build
 
  %build
mkdir -p                  root/etc/e-smith/db/accounts/defaults/foo
 
echo "reserved"        > root/etc/e-smith/db/accounts/defaults/foo/type
 
 
mkdir -p                  root/etc/e-smith/db/configuration/defaults/foo
 
echo "service"          > root/etc/e-smith/db/configuration/defaults/foo/type
 
echo "Helpdesk"        > root/etc/e-smith/db/configuration/defaults/foo/Name
 
echo "global-pw-remote" > root/etc/e-smith/db/configuration/defaults/foo/PublicAccess
 
echo "enabled"          > root/etc/e-smith/db/configuration/defaults/foo/status
 
echo "foo"              > root/etc/e-smith/db/configuration/defaults/foo/DbName
 
echo "foo"              > root/etc/e-smith/db/configuration/defaults/foo/DbUser
 
 
mkdir -p                  root/etc/e-smith/templates.metadata/etc/e-smith/sql/init
 
echo "PERMS=0750"      > root/etc/e-smith/templates.metadata/etc/e-smith/sql/init/80foo
 
 
   
 
   
 
  %install
 
  %install
Line 386: Line 538:
 
  %preun
 
  %preun
 
  %post
 
  %post
/etc/e-smith/events/actions/initialize-default-databases
 
/sbin/e-smith/expand-template /etc/e-smith/sql/init/80foo
 
/etc/rc.d/init.d/mysql.init start
 
/sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf
 
/usr/bin/sv h /service/httpd-e-smith
 
/sbin/e-smith/expand-template /opt/foo/config.php
 
/sbin/e-smith/expand-template /etc/crontab
 
 
echo ""
 
echo "see http://wiki.contribs.org/foo"
 
 
   
 
   
 
  %postun
 
  %postun
Line 429: Line 571:
 
         global-pw        => Entire Internet(password required)
 
         global-pw        => Entire Internet(password required)
 
         global-pw-remote => Entire Internet(password required outside local network)
 
         global-pw-remote => Entire Internet(password required outside local network)
 +
 +
*change groups and users allowed by CL
 +
 +
config setprop foo User "admin toto"
 +
config setprop foo Group "famille virt"
 +
then
 +
signal-event console-save
  
 
* To add a different URL eg. yourserver.net/foo
 
* To add a different URL eg. yourserver.net/foo
Line 435: Line 584:
 
  config setprop foo URL newfoo
 
  config setprop foo URL newfoo
  
* To run foo from the root of a domain eg.
+
* To run foo from the root of a domain, This option is buggy to remove
foo.yourserver.net or <br>
 
domain2.org
 
 
 
config setprop foo domain foo.yourserver.org OR
 
config setprop foo domain domain2.org
 
  
In /server-manager ''Hostnames and Addressess'' setup foo as a hostname on one of you domains or <br>
+
config delprop foo domain
in ''Domains'' setup a new domain eg. domain2.org, this will overrule the panel setting
 
  
 
To enable your changes run these commands
 
To enable your changes run these commands
Line 455: Line 598:
 
php applications may be faster with [http://sourceforge.net/projects/eaccelerator eaccelerator]
 
php applications may be faster with [http://sourceforge.net/projects/eaccelerator eaccelerator]
  
RPM prepared for sme7 by  
+
RPM originally prepared for SME by MasterSleepy and is now in the SMEContribs repo.
[http://www.vanhees.cc/index.php?name=CmodsDownload&file=index&req=viewdownloaddetails&lid=314 MasterSleepy]
 
  
  
 
<noinclude>[[Category:Howto]]</noinclude>
 
<noinclude>[[Category:Howto]]</noinclude>
 
<noinclude>[[Category:Dungog]]</noinclude>
 
<noinclude>[[Category:Dungog]]</noinclude>

Latest revision as of 09:28, 14 January 2016

PythonIcon.png Skill level: Developer
Risk of inconsistencies with Koozali SME Server methodology, upgrades & functionality is high. One must be knowledgeable about how changes impact their Koozali SME Server. Significant risk of irreversible harm.


Generic Instructions for building a Web Application RPM

RPMS make installation more reliable and removal much easier.

This guide aims to create a common structure for building rpms

Build environment

Local Server

Create a build environment on your local server, refer to the SME Server Developer's Guide: How to create a SME Server package - step by step

SME Build Server

When you are comfortable building rpms, you are encouraged to put your source files on the SME Build Server, Package Modification, this allows others to more easily update and improve your rpms.

The Application RPM

Application source

Download the application source, eg foo.tar.gz and place in the SOURCES directory

SPEC file

Edit the following sample .spec file and place in the SPECS directory

%define name foo
%define version 3.6.431
%define release 1
Summary: foo is a helpdesk system
Name: %{name}
Version: %{version}
Release: %{release}%{?dist}
Distribution: SME Server
License: GNU GPL version 2
URL: http://www.fooweb.com
Group: SMEserver/addon
#wget http://www.fooweb.com/downloads/foo-3.6.431.tar.gz
Source: foo-3.6.431.tar.gz
Packager: Stephen Foo <support@foo.net>
BuildArchitectures: noarch
BuildRoot: /var/tmp/%{name}-%{version}
BuildRequires: e-smith-devtools
Requires: e-smith-release >= 7.0
AutoReqProv: no

%description
http://foo.org/
foo is a helpdesk system 

%changelog
* Thu Sep 13 2007 Stephen Foo <support@foo.net> 3.6.431-1
- initial release
- builds from unchanged .tar.gz 

%prep
%setup  -c -n %{name}

%build
#drop in an unchanged .tgz, if required rename directory here, eg remove version number.
mkdir -p root/opt/
mv %{name} root/opt/foo

%install
rm -rf $RPM_BUILD_ROOT
(cd root   ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
rm -f %{name}-%{version}-filelist
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT \
   --dir '/opt/foo/tempdir/' 'attr(775,www,www)' \
   --file '/opt/foo/logo.gif' 'attr(660,www,www)' \
    > %{name}-%{version}-filelist

%clean
cd ..
rm -rf %{name}

%files -f %{name}-%{version}-filelist
%defattr(-,root,root)

Build the RPM

rpmbuild -ba /home/e-smith/files/users/jim/home/rpms/SPECS/foo.spec


Notes

Permissions, may need tweaking but usually not many need changing, you don't want the webserver changing the distribution files.

Check the .spec files of other contribs, see the CVS (SME Contribs)

SME Server Intergration RPM

Create database

  • Create password

root/etc/e-smith/db/configuration/migrate/80foo

{
   use MIME::Base64 qw(encode_base64);

   my $rec = $DB->get('foo') || $DB->new_record('foo', {type => 'service'});

   my $pw = $rec->prop('DbPassword');
   return "" if $pw;
   $rec->set_prop('DbPassword', MIME::Base64::encode(int( (1000000000000000) * rand() )));
}
  • Create structure

root/etc/e-smith/templates/etc/e-smith/sql/init/80foo

{
   my $db = $foo{DbName} || 'foo';
   my $user = $foo{DbUser} || 'foo';
   my $pass = $foo{DbPassword} || 'foo';
   $OUT .= <<END
#! /bin/sh
   if [ -d /var/lib/mysql/$db ]; then
     exit
   fi
   /usr/bin/mysql <<EOF
   CREATE DATABASE $db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
   use $db;
   #Insert application specific command to create database structure
   source /opt/foo/sql/mysql_foo.sql;
   use mysql;
   GRANT ALL PRIVILEGES ON $db.* TO $user\@localhost
           IDENTIFIED BY '$pass';
   flush privileges;
EOF
END
}

See the %build section of the spec file where you create the DB name & user.

The %post section of the spec file run the commands to initialise db values and create the db structure

db defaults

Reserve the foo name in accounts and create default settings in configuration

Create files in these locations, with default values

root/etc/e-smith/db/accounts/defaults/foo
root/etc/e-smith/db/accounts/defaults/foo/type > reserved

root/etc/e-smith/db/configuration/defaults/foo
root/etc/e-smith/db/configuration/defaults/foo/type           > service
root/etc/e-smith/db/configuration/defaults/foo/Name           > Helpdesk        
root/etc/e-smith/db/configuration/defaults/foo/PublicAccess   > global-pw-remote
root/etc/e-smith/db/configuration/defaults/foo/status         > enabled         
root/etc/e-smith/db/configuration/defaults/foo/DbName         > foo             
root/etc/e-smith/db/configuration/defaults/foo/DbUser         > foo             

root/etc/e-smith/templates.metadata/etc/e-smith/sql/init
root/etc/e-smith/templates.metadata/etc/e-smith/sql/init/80foo  >  PERMS=0750

Webserver templates

Http Template 92Foo

The alias fragment tailored to suit the application root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

{
    my $status = $foo{'status'} || "disabled";
    return "    # foo is disabled in this VirtualHost"
           unless $status eq 'enabled';

   $OUT = "";
   my $allow = 'all';
   my $pass = '0';
   my $satisfy = 'all';
   my $name = $foo{'Name'} || 'Application Description';
   
   for ('exit-if-none')
   {
     if ($foo{'PublicAccess'})
     {
         if ($foo{'PublicAccess'} eq 'none')
         {
          next;
         }
         elsif ($foo{'PublicAccess'} eq 'local')
         {
           $allow   = $localAccess;
           $pass    = 0;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'local-pw')
         {
           $allow   = $localAccess;
           $pass    = 1;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'global')
         {
           $allow   = 'all';
           $pass    = 0;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'global-pw')
         {
           $allow   = 'all';
           $pass    = 1;
           $satisfy = 'all';
         }
         elsif ($foo{'PublicAccess'} eq 'global-pw-remote')
         {
           $allow   = $localAccess;
           $pass    = 1;
           $satisfy = 'any';
         }
     }
     
     $OUT .= "#------------------------------------------------------------\n";
     $OUT .= "# foo - $name\n";
     $OUT .= "#------------------------------------------------------------\n";
     
     {
       if (exists $foo{'URL'})
       { $OUT .= "Alias  /$foo{'URL'}  /opt/foo\n"; }
     }
     
     $OUT .= "Alias  /foo  /opt/foo\n";
     
     $OUT .= "\n";
     $OUT .= "<Directory /opt/foo>\n";
     $OUT .= "    AddType application/x-httpd-php .php\n";
     $OUT .= "    php_admin_value open_basedir /opt/foo\n";
     $OUT .= "    Options None\n";
     $OUT .= "    order deny,allow\n";
     $OUT .= "    deny from all\n";
     $OUT .= "    allow from $allow\n";
     $OUT .= "    php_value mysql.default_host $foo{DbName}\n";
     $OUT .= "    php_value mysql.default_user $foo{DbUser}\n";
     $OUT .= "    php_value mysql.default_password $foo{DbPassword}\n";
     if ($pass)
     {
         $OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthBasicProvider external\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    require valid-user\n";
         $OUT .= "    Satisfy $satisfy\n";
     }
     $OUT .= "</Directory>\n";
   }
}

Apache Authentication

In the example above, all sme users can authenticate to the web folder /opt/foo, for an application with no matter in security, it is normal but in certain case it could be dangerous.

  • All users of SME Server

The original template in /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

     {
         $OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthBasicProvider external\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    require valid-user\n";
         $OUT .= "    Satisfy $satisfy\n";
     }
  • one user or several users

Now you need to modify the 92foo template with these new lines nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

     {
         $OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthBasicProvider external\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    require user admin pierre paul\n";
         $OUT .= "    Satisfy $satisfy\n";
     }
  • one group or several groups with some specific users

You have to download a plugin of pwauth to authenticate unix group in SME Server 8 : http://code.google.com/p/pwauth/ For SME Server 9 a nfr is raised see bugzilla:3690

wget http://pwauth.googlecode.com/files/pwauth-2.3.10.tar.gz
tar xvzf pwauth-2.3.10.tar.gz
cp pwauth-2.3.10/unixgroup /usr/lib/httpd/modules/
chown root:www /usr/lib/httpd/modules/unixgroup
chmod 750 /usr/lib/httpd/modules/unixgroup

We need to create a new fragment

nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/35-group-auth

{
       $OUT .= "     AddExternalGroup unixgroup /usr/lib/httpd/modules/unixgroup\n";
       $OUT .= "     SetExternalGroupMethod unixgroup environment\n";
}

Now you need to modify the 92foo template with these new lines nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

{
         $OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthBasicProvider external\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    GroupExternal unixgroup\n";
         $OUT .= "    AuthzUserAuthoritative off\n";
         $OUT .= "    require user admin pierre paul\n";
         $OUT .= "    require group virt\n";
         $OUT .= "    Satisfy $satisfy\n";
}
  • DB command to choose groups and users

Above we have seen how to write name of groups or users directly in the template, but in the real life it is not enough good :)

The purpose is to choose users or groups by command line.

-In first you have to make other DB configuration as described Web_Application_RPM#db_defaults

echo "admin" >         root/etc/e-smith/db/configuration/defaults/foo/User
echo "" >              root/etc/e-smith/db/configuration/defaults/foo/Group

Only the user admin is set by default

-You have to download a plugin of pwauth to authenticate unix group in SME Server 8 : http://code.google.com/p/pwauth/

wget http://pwauth.googlecode.com/files/pwauth-2.3.10.tar.gz
tar xvzf pwauth-2.3.10.tar.gz
cp pwauth-2.3.10/unixgroup /usr/lib/httpd/modules/
chown root:www /usr/lib/httpd/modules/unixgroup
chmod 750 /usr/lib/httpd/modules/unixgroup

We need to create a new fragment
nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/35-group-auth

{
       $OUT .= "     AddExternalGroup unixgroup /usr/lib/httpd/modules/unixgroup\n";
       $OUT .= "     SetExternalGroupMethod unixgroup environment\n";
}

Now you need to modify the 92foo template with these new lines

nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

{
$OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    GroupExternal unixgroup\n";
         $OUT .= "    AuthzUserAuthoritative off\n";
         $OUT .= "    require user $foo{'User'}\n";
         $OUT .= "    require group $foo{'Group'}\n";
         $OUT .= "    Satisfy $satisfy\n";
}

-change groups and users allowed by CL

config setprop foo User "admin toto"
config setprop foo Group "famille virt"

then

signal-event console-save
SME Server 9

The apache authentication is made by a new file named authnz_external_module instead of auth_external_module, therefore you need to slightly modify the code above.
If it is not done you can have this error in log file and you won't be authenticated

configuration error:  couldn't check user.  No user file?:

See this howTo. You need to verify if your /etc/httpd/conf/httpd.conf contain these lines

AddExternalGroup unixgroup /usr/bin/unixgroup
SetExternalGroupMethod unixgroup environment

We are waiting the default use of authenticator unixgroup in sme9 (see bugzilla:8008). For now you need to make the relevant fragment template.

nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/35-group-auth

{
       $OUT .= "     AddExternalGroup unixgroup /usr/bin/unixgroup\n";
       $OUT .= "     SetExternalGroupMethod unixgroup environment\n";
}

nano /etc/e-smith/templates/etc/httpd/conf/httpd.conf/92foo

{
$OUT .= "    AuthName \"$name\"\n";
         $OUT .= "    AuthBasicProvider external\n";
         $OUT .= "    AuthType Basic\n";
         $OUT .= "    AuthExternal pwauth\n";
         $OUT .= "    GroupExternal unixgroup\n";
         $OUT .= "    AuthzUserAuthoritative off\n";
         $OUT .= "    require user $foo{'User'}\n";
         $OUT .= "    require group $foo{'Group'}\n";
         $OUT .= "    Satisfy $satisfy\n";
}

-change groups and users allowed by CL

config setprop foo User "admin toto"
config setprop foo Group "famille virt"

then

signal-event console-save

Upload_tmp_dir

Since SME Server V8, you could have sometime an error is thrown by PHP and you will need to specify a temporary directory (e.g. upload_tmp_dir) which is not set in php.ini. see bugzilla:6650 and bugzilla:7652. Many Php applications needs this setting, most of known are wordpress, roudcube, egroupware, etc. Symptoms are that you can't upload contents to the PHP application.

An easy way is to make a Custom Template to resolve this issue.

see Uploadtmpdir

Https_redirection

  • a hack to get https to work, a better solution is required, you can see Https_redirection

root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/30FooAlias

{
   my $status = $foo{'status'} || "disabled";
   return "    # foo is disabled in this VirtualHost"
           unless $status eq 'enabled';

   if ($port eq "443")
   {
      $OUT .= "    ProxyPass /foo http://127.0.0.1/foo\n";
   }
}
  • or this solution which does the automatic redirection to https protocol, you have to choose either 30FooAlias or 60FooAlias but not both.

root/etc/e-smith/templates/etc/httpd/conf/httpd.conf/VirtualHosts/60FooAlias

{
   my $status = $foo{'status'} || "disabled";
   return "    # foo is disabled in this VirtualHost"
           unless $status eq 'enabled';

{
if ($port ne "443")
{
$OUT .= <<'HERE';
## Redirect Web Address to Secure Address
RewriteEngine on
RewriteRule ^/foo https://%{HTTP_HOST}/foo

## End Of Redirect
HERE
}
}

}

  • To enforce the security you can decide to prohibit all connexions which are not https. You need to add "SSLRequireSSL" in the correct position of the 92foo template.
     $OUT .= "<Directory /opt/foo>\n";
     $OUT .= "    SSLRequireSSL\n";
     $OUT .= "    AddType application/x-httpd-php .php\n";

System file templates

You may need to create a fragment for a system file such as crontab.

http://wiki.contribs.org/SME_Server:Documentation:Developers_Manual

Application templates

Preferably include the original application config file in the templates directory,
then overwrite key values, some of which we keep in SME DB's

This is not always possible, eg your application modifies the config file
in this case leave the config file untemplated and advise the user how to configure manually.

eg . root\etc\template\opt\foo\config.php

template-begin

{
   $OUT = <<HERE;
<?php
/*
HERE

   $OUT .= 
   Text::Template::_load_text("/etc/e-smith/templates-default/template-begin");

   $OUT .= <<HERE;
*/
HERE

}

template-end

?>

10config-dist

{
   $OUT = "require_once('config.php.dist');";
}

20config-sme

// SME Server Settings
{
  $OUT .= "\$CFG->dbname   = ini_get\(\'mysql.default_host\'\)\; \n";
  $OUT .= "\$CFG->dbuser   = ini_get\(\'mysql.default_user\'\)\; \n";
  $OUT .= "\$CFG->dbpass   = ini_get\(\'mysql.default_password\'\)\; \n";
  $OUT .= "\$CFG->dirroot  = \'/opt/foo'\; \n";
}

Spec file

%define name smeserver-foo
%define version 1.0
%define release 1
Summary: smserver rpm to setup foo, a foo system
Name: %{name}
Version: %{version}
Release: %{release}%{?dist}
Distribution: SME Server
License: GNU GPL version 2
URL: http://www.foo.net/
Group: SMEserver/addon
Source: %{name}-%{version}.tar.gz
#Patch0: smeserver-foo-1.0-null.patch
Packager: Stephen Foo<support@foo.net>
BuildArchitectures: noarch
BuildRequires: e-smith-devtools >= 1.13.1-03
BuildRoot: /var/tmp/%{name}-%{version}
Requires: e-smith-release >= 7.0
Requires: foo
AutoReqProv: no

%description
smserver rpm to setup foo, a helpdesk system

%changelog
* Thu Sep 13 2007 Stephen Foo<support@foo.net> 1.0-1
- initial release

%prep
%setup
#%patch0 -p1

%build

%install
rm -rf $RPM_BUILD_ROOT
(cd root   ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
rm -f %{name}-%{version}-filelist
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist
echo "%doc COPYING"  >> %{name}-%{version}-filelist

%clean
cd ..
rm -rf %{name}-%{version} 

%pre
%preun
%post

%postun
#uninstall
if [ $1 = 0 ] ; then
 /sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf
 /usr/bin/sv h /service/httpd-e-smith
 /sbin/e-smith/expand-template /etc/crontab
fi

%files -f %{name}-%{version}-filelist
%defattr(-,root,root)

Further Information

Developer guide

http://wiki.contribs.org/SME_Server:Documentation:Developers_Manual

New DB settings

  • To disable foo. (default is enabled)
config setprop foo status disabled 
  • To limit access to foo.
config setprop foo PublicAccess OPTION

OPTION is either of the following.

       none             => No access
       local            => Local network  (no password required)
       local-pw         => Local network  (password required)
       global           => Entire Internet(no password required)
       global-pw        => Entire Internet(password required)
       global-pw-remote => Entire Internet(password required outside local network)
  • change groups and users allowed by CL
config setprop foo User "admin toto"
config setprop foo Group "famille virt"

then

signal-event console-save
  • To add a different URL eg. yourserver.net/foo

note, this adds another url, it doesn't remove the default

config setprop foo URL newfoo
  • To run foo from the root of a domain, This option is buggy to remove
config delprop foo domain

To enable your changes run these commands

expand-template /etc/httpd/conf/httpd.conf
sv h /service/httpd-e-smith

Related applications

  • eaccelerator

php applications may be faster with eaccelerator

RPM originally prepared for SME by MasterSleepy and is now in the SMEContribs repo.