This recipe demonstrates how to keep a single webpage up-to-date using WebJob. Payload and Delivery (PaD) technology will be used to turn the webpage into a self extracting executable. WebJob will then be configured to download, unpack, and execute this PaD file. The motivating factors behind this recipe are: 1) it's desirable to have a way to keep webpages up-to-date, 2) having the ability to automatically detect and repair damaged or corrupted content makes webpages more resilient to defacement, and 3) minimizing user activity on production systems helps to establish well-behaved profiles -- an important factor in identifying abnormal activity. Cooking with this recipe requires that you already have an operational WebJob server. If this is not the case, refer to the instructions provided in the INSTALL file that comes with the source distribution. While this recipe was written for UNIX environments, the concepts should be portable. You need to have at least the following programs available on your production system: diff, chmod, mv, rm, sh, and webjob (1.4.0 or higher). This recipe assumes that for a given client, say client_0001, you wish to periodically inspect a webpage and repair or update it as necessary. 1. Obtain a copy of the webpage you wish to monitor as it would be deployed on the production Web server. To keep things simple, let's assume that your webpage has the content shown here: --- webpage.html --- Welcome!

Welcome to my world!


--- webpage.html --- sed -e '1,/^--- webpage.html ---$/d; /^--- webpage.html ---$/,$d' webjob-pad-update-webpage.txt > webpage.html Next, create webpage.html.pad and copy it to client_0001's commands directory on the WebJob server. pad-make-script --create webpage.html > webpage.html.pad chmod 644 webpage.html.pad scp -p webpage.html.pad you@your.webjob.server.net:/integrity/profiles/client_0001/commands/ The server should now have an integrity tree similar to the one shown here: integrity | - incoming | - logfiles | - profiles | - client_0001 | - baseline | - commands | - webpage.html.pad 2. At this point, the WebJob server has been configured. Now, we'll focus on the production server. Log into the production server, and create upload.cfg as shown below. Be sure to set URLGetURL, URLPutURL, URLUsername, and URLPassword as appropriate. Install this config file in /usr/local/integrity/etc. If necessary, create /usr/local/integrity/run with: mkdir -m 755 -p /usr/local/integrity/run --- upload.cfg --- ClientId=client_0001 URLGetURL=https://your.webjob.server.net/cgi-webjob/nph-webjob.cgi URLPutURL=https://your.webjob.server.net/cgi-webjob/nph-webjob.cgi URLUsername=client_0001 URLPassword=password URLAuthType=basic RunType=snapshot OverwriteExecutable=Y UnlinkOutput=Y UnlinkExecutable=Y GetTimeLimit=0 RunTimeLimit=0 PutTimeLimit=0 URLDownloadLimit=10000000 TempDirectory=/usr/local/integrity/run --- upload.cfg --- sed -e '1,/^--- upload.cfg ---$/d; /^--- upload.cfg ---$/,$d' webjob-pad-update-webpage.txt > upload.cfg install -m 600 -o root -g wheel upload.cfg /usr/local/integrity/etc 3. Next, create update-webpage.sh as shown below, and install it in /usr/local/integrity/bin. This script is actually one big command -- look at the last line. The WebJob portion of this command downloads, and executes webpage.html.pad using upload.cfg as its config file. The PaD portion of this command unpacks the webpage, compares it to the deployed page, and if they are different, updates the deployed page by replacing it. Finally, the run status and any differences are posted back to the WebJob server. Before running this script, be sure to set PAD_FILE, JOB_HOME, and WEB_PAGE as appropriate. --- update-webpage.sh --- #!/bin/sh PAD_FILE=webpage.html.pad JOB_HOME=/usr/local/integrity WEB_PAGE=/usr/local/www/htdocs/webpage.html PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:${JOB_HOME}/bin DODIFF="( echo \"Checking webpage...\" 1>&2 && diff -uP ${WEB_PAGE} ${JOB_HOME}/run/%payload )" UPDATE="( echo \"Updating webpage...\" 1>&2 && mv ${JOB_HOME}/run/%payload ${WEB_PAGE} && chmod 644 ${WEB_PAGE} )" FINISH="( echo \"Cleaning workdir...\" 1>&2 && rm -rf ${JOB_HOME}/run/%payload )" ${JOB_HOME}/bin/webjob -e -f ${JOB_HOME}/etc/upload.cfg ${PAD_FILE} ${DODIFF} \|\| ${UPDATE} \; ${FINISH} --- update-webpage.sh --- sed -e '1,/^--- update-webpage.sh ---$/d; /^--- update-webpage.sh ---$/,$d' webjob-pad-update-webpage.txt > update-webpage.sh install -m 755 -o root -g wheel update-webpage.sh /usr/local/integrity/bin 4. At this point, you are ready to test everything out. Run the update script as follows: /usr/local/integrity/bin/update-webpage.sh If it completes successfully, you should find four files on the WebJob server in its incoming directory. The files listed here will give you an idea of what to look for: client_0001_20021111210945_update-webpage.sh.env client_0001_20021111210945_update-webpage.sh.err client_0001_20021111210945_update-webpage.sh.out client_0001_20021111210945_update-webpage.sh.rdy Inspect these files. Their content should be similar to that shown below. The .rdy file is simply a lock release mechanism. Therefore, it's content has not been listed. --- client_0001_20021111210945_update-webpage.sh.env --- CommandLine=webpage.html.pad ( echo "Checking webpage..." 1>&2 && diff -uP /usr/local/www/htdocs/webpage.html /usr/local/integrity/run/%payload ) || ( echo "Updating webpage..." 1>&2 && mv /usr/local/integrity/run/%payload /usr/local/www/htdocs/webpage.html && chmod 644 /usr/local/www/htdocs/webpage.html ) ; ( echo "Cleaning workdir..." 1>&2 && rm -rf /usr/local/integrity/run/%payload ) JobPid=20094 KidPid=8539 KidStatus=0 KidSignal=0 KidReason=The kid exited cleanly. Hostname=your.production.server.net SystemOS=i686 Linux 2.4.18-grsec-1.9.4 JobEpoch=2002-11-11 18:08:06 PST (1037066886.700503) GetEpoch=2002-11-11 18:08:06 PST (1037066886.980652) RunEpoch=2002-11-11 18:08:07 PST (1037066887.625140) PutEpoch=2002-11-11 18:08:08 PST (1037066888.640114) --- client_0001_20021111210945_update-webpage.sh.env --- --- client_0001_20021111210945_update-webpage.sh.err --- Extracting payload... Delivering payload... ( echo "Checking webpage..." 1>&2 && diff -uP /usr/local/www/htdocs/webpage.html /usr/local/integrity/run/webpage.html ) || ( echo "Updating webpage..." 1>&2 && mv /usr/local/integrity/run/webpage.html /usr/local/www/htdocs/webpage.html && chmod 644 /usr/local/www/htdocs/webpage.html ) ; ( echo "Cleaning workdir..." 1>&2 && rm -rf /usr/local/integrity/run/webpage.html ) Checking webpage... Updating webpage... Cleaning workdir... DeliveryStatus='0' --- client_0001_20021111210945_update-webpage.sh.err --- Note that the following output implies that the file webpage.html was not deployed on the production server prior to the invocation of the update script. This should lead you to conclude that the update script can also be used to deploy new content. --- client_0001_20021111210945_update-webpage.sh.out --- --- /usr/local/www/htdocs/webpage.html Wed Dec 31 16:00:00 1969 +++ /usr/local/integrity/run/webpage.html Mon Nov 11 18:08:08 2002 @@ -0,0 +1,8 @@ + +Welcome! + +
+

Welcome to my world!

+
+ + --- client_0001_20021111210945_update-webpage.sh.out --- 5. Once you are satisfied that all is well, add the following cron job to the production server's crontab -- it runs every five minutes. --- crontab.5min --- */5 * * * * /usr/local/integrity/bin/update-webpage.sh > /dev/null 2>&1 --- crontab.5min --- From this point forward, the webpage will be automatically repaired if the deployed content differs from the PaD content for any reason. When you want to update the webpage, simply put a new PaD file on the WebJob server. As an added benefit, the diff output preserved in the WebJob upload can be used as a negative or reverse patch. Applying this patch to the page extracted from the PaD file allows you to reconstruct the original webpage as deployed. Thus, there is an inherit quarantining property built into this scheme.