Changes between Initial Version and Version 1 of howto/ShareArchives2


Ignore:
Timestamp:
Aug 3, 2011, 4:56:47 AM (13 years ago)
Author:
fracai
Comment:

Initial dump of instructions for configuring archive sharing

Legend:

Unmodified
Added
Removed
Modified
  • howto/ShareArchives2

    v1 v1  
     1[wiki:howto <- Back to the HOWTO section]
     2
     3= Sharing Archives under MacPorts 2 (incomplete) =
     4
     5 * Audience: Users who want to share binary archives between machines
     6 * Requires: MacPorts >= 2.0.0
     7
     8== Introduction ==
     9
     10Users with multiple machines can save significant compilation effort by installing pre-built ports from binary archives that have been assembled on another system. Under previous MacPorts releases this [https://trac.macports.org/wiki/howto/ShareArchives involved] enabling archive mode on all systems, manually transferring archives, and sometimes manually unpacking the archive before proceeding with the installation. MacPorts 2.0.0 introduces features which permanently enables archive mode and includes support for fetching archives from local or remote sources.
     11
     12== Installation ==
     13
     14=== Step 1: '''Generate signing keys''' ===
     15
     16Before MacPorts will install software from a binary archive, it will test that the package has a valid signature that is locally trusted. For now, we just need to generate the keys and sign the packages.
     17
     18The public and private keys are generated as described below.
     19{{{
     20openssl genrsa -des3 -out privkey.pem 2048
     21openssl rsa -in privkey.pem -pubout -out pubkey.pem
     22}}}
     23
     24You will be prompted to enter a passphrase to protect the private key. It is up to you to decide how complex this protection should be. Note that it is possible to store this key in your Keychain.app (using /usr/bin/ssh-add). This has the advantage of passing the key security on to the OS, though it may not be an acceptable option for automating package signing.
     25
     26It is also possible to create a key without a passphrase. If you are not distributing packages outside of a home network, this is likely not a problem. An unprotected private key is generated as below; the command to generate the public key is unchanged.
     27
     28{{{
     29openssl genrsa -out privkey.pem 2048
     30}}}
     31
     32The passphrase can also be stripped from an existing private key using the following:
     33{{{
     34openssl rsa -in privkey.pem -out newprivkey.pem
     35}}}
     36
     37The public and private keys can be stored anywhere as long as they are accessible to the following steps. This tutorial has them placed on the build system at '''/usr/local/share/macports/'''.
     38
     39Note: While the build system need only have access to the private key, it's a good idea to store both the public and private keys in the same location. The installation system should only have access to the public key.
     40
     41=== Step 2: '''Let's sign some packages''' ===
     42
     43Now that the keys are generated, we can test signing a package. Any archive will do; the following example uses '''archive.tbz'''. Your example should specify the full path to the private key, the archive, and the archive signature that should be named identically to the input archive and suffixed with '''.rmd160'''.
     44
     45{{{
     46openssl dgst -ripemd160 -sign privkey.pem -out archive.tbz2.rmd160 archive.tbz2
     47}}}
     48
     49You can verify the signature as well:
     50{{{
     51openssl dgst -ripemd160 -verify pubkey.pem -signature archive.tbz2.rmd160 archive.tbz2
     52}}}
     53
     54Signing an archive for the '''lighttpd''' port might look something like this:
     55
     56{{{
     57openssl dgst -ripemd160 \
     58    -sign /usr/local/share/macports/privkey.pem \
     59    -out /opt/local/var/macports/software/lighttpd/lighttpd-1.4.28_0+ssl+universal.darwin_10.i386-x86_64.tbz2.rmd160 \
     60    /opt/local/var/macports/software/lighttpd/lighttpd-1.4.28_0+ssl+universal.darwin_10.i386-x86_64.tbz2
     61}}}
     62
     63Now, signing every individual archive like this would be quite time consuming. It'd be better to run a script which finds and signs every archive. Such a script is displayed below:
     64
     65{{{
     66#!/bin/sh
     67
     68PRIVKEY="/usr/local/share/macports/macports-donnybrook.priv"
     69PUBKEY="/usr/local/share/macports/macports-donnybrook.pub"
     70SOFTWARE="/opt/local/var/macports/software"
     71
     72# First, clear out any outdated signatures
     73for SIGNATURE in "$SOFTWARE"/*/*.rmd160
     74do
     75    ARCHIVE_DIR="$(dirname "$SIGNATURE")"
     76    ARCHIVE="$(basename "$SIGNATURE" .rmd160)"
     77
     78    if [ "$SIGNATURE" -ot "$ARCHIVE_DIR"/"$ARCHIVE" -o ! -f "$ARCHIVE_DIR"/"$ARCHIVE" ]
     79    then
     80        /bin/echo removing outdated signature: "$SIGNATURE"
     81        /bin/rm -f "$SIGNATURE"
     82    fi
     83done
     84
     85# Now, find every archive that doesn't have a signature
     86for ARCHIVE in "$SOFTWARE"/*/*.{tbz2,tgz,tar,tbz,tlz,txz,xar,zip,cpgz,cpio}
     87do
     88    PORTNAME="$(basename "$(dirname "$ARCHIVE")")"
     89    ANAME="$(basename "$ARCHIVE")"
     90
     91    if [ "$ARCHIVE" -nt "$ARCHIVE".rmd160 ]
     92    then
     93        /bin/echo -n deploying archive: "$ANAME "
     94        /usr/bin/openssl dgst -ripemd160 -sign "$PRIVKEY" -out "$ARCHIVE".rmd160 "$ARCHIVE"
     95        /usr/bin/openssl dgst -ripemd160 -verify "$PUBKEY" -signature "$ARCHIVE".rmd160 "$ARCHIVE"
     96    fi
     97done
     98}}}
     99
     100The script can be run after upgrading, installing, or uninstalling ports to remove outdated signatures and generate updated signatures for all available archives.
     101
     102=== Step 3: '''Share archives''' ===
     103
     104In order to retrieve archives from the build system, they must first be shared. MacPorts expects this to be a basic web listing of the software directory ('''${prefix}/var/macports/software/'''). While Mac OS X ships with an installation of Apache, that's a bit heavy for what we need. Instead, the light weight web server [http://www.lighttpd.net/ lighttpd] can be used with minimal configuration.
     105
     106Conveniently, it's available through MacPorts, so go ahead and install that.
     107{{{
     108port install lighttpd
     109}}}
     110
     111Create the configuration file and save it next to the public and private keys. (Like the keys, this file can be stored anywhere that is accessible.)
     112
     113{{{
     114server.document-root = "/opt/local/var/macports/software/"
     115
     116server.username  = "_www"
     117server.groupname = "_www"
     118
     119server.port = 6227
     120
     121dir-listing.activate = "enable"
     122
     123mimetype.assign = (
     124    ".tbz2"     => "application/x-bzip-compressed-tar",
     125    ".rmd160"   => "text/binary",
     126
     127    # make the default mime type application/octet-stream.
     128    ""          => "application/octet-stream",
     129)
     130}}}
     131
     132Note: The '''server.port''' configuration is somewhat arbitrary as long as something non-standard is used so as not to collide with an existing service. The standard ports 80 or 8080 are options if you are not running another web server.
     133
     134You should now be able to start the service...
     135{{{
     136/opt/local/sbin/lighttpd -D -f /usr/local/share/macports/macports-archives-lighttpd.conf
     137}}}
     138and view your software archives in a browser:
     139[http://localhost:6267]
     140
     141There is also a simple tutorial for enabling [http://redmine.lighttpd.net/wiki/1/HowToSimpleSSL SSL] support for additional security if it is desired. Be sure to install '''lighttpd''' with the '''+ssl'''.
     142
     143You'll also want the lighttpd service to run at all times so your client machines are not deprived of access to the port archives. A simple LaunchD task will handle this:
     144
     145'''/Library/LaunchDaemons/org.macports.share-archives.plist'''
     146{{{
     147<?xml version="1.0" encoding="UTF-8"?>
     148<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     149<plist version="1.0">
     150<dict>
     151    <key>KeepAlive</key>
     152    <true/>
     153    <key>Label</key>
     154    <string>org.macports.share-archives</string>
     155    <key>LowPriorityIO</key>
     156    <true/>
     157    <key>Nice</key>
     158    <integer>1</integer>
     159    <key>ProgramArguments</key>
     160    <array>
     161        <string>/opt/local/sbin/lighttpd</string>
     162        <string>-D</string>
     163        <string>-f</string>
     164        <string>/usr/local/share/macports/macports-archives-lighttpd.conf</string>
     165    </array>
     166    <key>StandardErrorPath</key>
     167    <string>/var/log/macports-archives-lighttpd.out</string>
     168    <key>StandardOutPath</key>
     169    <string>/var/log/macports-archives-lighttpd.out</string>
     170</dict>
     171</plist>
     172}}}
     173
     174Make sure your test server has been killed and then load the task with:
     175{{{
     176launchctl load /Library/LaunchDaemons/org.macports.share-archives.plist
     177}}}
     178
     179Ensure that the server is running again by browsing the page as before.
     180
     181=== Step 4: '''Fetch archives''' ===
     182
     183Finally we're ready to actually fetch some archives.
     184
     185First, copy the public key to each client system that will be installing from archives. As before, '''/usr/local/share/macports/''' is a decent enough location.
     186
     187Now, MacPorts needs to be configured to fetch archives from the build system. The '''archive_site_local''' setting can be set to an IP, but it will likely be more convenient to use the Bonjour name of the local system. This name can be found in the '''Sharing''' preference pane.
     188
     189Add the following to '''${prefix}/etc/macports/macports.conf'''
     190{{{
     191archive_site_local      http://bonjour.local:6227/
     192}}}
     193
     194A line indicating the location of the public key must also be added to '''${prefix}/etc/macports/pubkeys.conf'''. Something like:
     195{{{
     196/usr/local/share/macports/pubkey.pem
     197}}}
     198
     199
     200And you're done! You should now be able to compile ports once on your build system and install on as many client systems as you like (as long as the requested variants and architectures are the same).
     201
     202
     203[wiki:howto <- Back to the HOWTO section]