Category Archives: Uncategorized

Using Let’s Encrypt with acme-client on a FreeBSD 11/Apache 2.4

I recently opted to use the Let’s Encrypt project to handle my noncommercial TLS needs.  If this works well, I will probably start pushing commercial clients over to it as well.

I couldn’t find a good guide to setting it up to use multiple domains smoothly on FreeBSD.  This technique should work with a single domain or multiple domains.

About Let’s Encrypt and acme-client

Let’s Encrypt is a project to simplify, automate, and normalize the creation and maintenance of TLS certificates used by web sites.

acme-client is a C program written to interact with the Let’s Encrypt service.  It was written for the OpenBSD project, but is useful on other platforms.  The key argument in its favor is arguably security.  There are few dependencies.

Assumptions

FreeBSD 11 is assumed here, but any recent version should work work.  With some effort these instructions could surely be adapted to several other environments.

I assume you want to configure multiple sites, but this should work for a single site as well. It will simply be multi-site ready (which, to my mind, costs nothing).

I mostly use the default paths in FreeBSD for the configuration of both Apache and acme-client.

Though you don’t strictly need to use Apache to follow most of these instructions, the configuration suggests I make about challenge-response configuration are Apache-specific. Any web daemon that includes aliased folders should permit the same kind of configuration.  If you’re using something besides Apache, you’ll need to adjust accordingly but this should not prevent you from using these instructions.

Even if you do use Apache, I assume you have a configuration where Apache already basically works and is compiled and configured to use encrypted HTTP.  I used a pretty stock installation of Apache 2.4 from /etc/ports/www/apache24.   I use FreeBSD paths and conventions throughout.  FreeBSD by default uses www:www (UID/GID of 80) as the username for httpd.  I tend to configure all my web sites in /usr/vhosts/ these days and create a logs/ folder and htdocs/ folder within.

I use a fairly large number of virtual hosts in Apache.  By habit, I store these in /usr/vhosts/.  I create a new  vhost tree with a one-liner like:

export THISD="mydomain.com"; mkdir -p /usr/vhosts/$THISD/htdocs && mkdir -p /usr/vhosts/$THISD/logs && chown -R 80:80 /usr/vhosts/$THISD

Using this example would create a /usr/vhosts/mydomain.com/ directory with separate folders for logs and web content. Of course, how you organize your folders is entirely up to you.

Overview of what we want

Before I go through the steps, I want to make clear what the end result should look like. You should end up with a directory tree of TLS keys and certificates.  For example:

Certificate file:   /usr/local/etc/ssl/acme/richardfassett.com/cert.pem
Chain file: /usr/local/etc/ssl/acme/richardfassett.com/chain.pem
Full chain: /usr/local/etc/ssl/acme/richardfassett.com/fullchain.pem
Private key: /usr/local/etc/ssl/acme/private/richardfassett.com/privkey.pem

You shouldn’t need to do anything with these files except refer to them in relevant configurations (e.g., Apache, mail, PHP). acme-client will handle that for you.

Optional but highly recommended: the file /usr/local/etc/acme/domains.txt will contain a list of certificates.  Each line in the file should contain the domains for one certificate. For example:

mydomain.com www.mydomain.com
myotherdomain.com www.myotherdomain.com mail.myotherdomain.com

Each line should be unique.  The importance of this file is apparently later when it’s time to write a renewal script.

Step 1: install your software

Make sure you have a working Apache configuration already configured to use TLS. This is pretty easy to do, but there are many ways to do it and it’s generally outside the scope of this guide.

I installed acme-client from ports by running:

cd /usr/ports/security/acme-client && make install

It was not available in with the pkg utility at the time, but in the future hopefully you could run pkg install acme-client.

Step 2: configure Let’s Encrypt challenge (.well-known)

To verify you own the domain, Let’s Encrypt checks a challenge-response routine.  You write some data Let’s Encrypt asks you to write to a certain place on your web server. FreeBSD sets aside /usr/local/www/acme for this purpose, but I ended up using my own folder.

I ran this command:

mkdir -pm750 /usr/local/www/.well-known && chown -R www:www /usr/local/www/.well-known

Then I added this to my httpd.conf file:

<Directory "/usr/local/www/.well-known/">
        Options None
        AllowOverride None
        Require all granted
        Header add Content-Type text/plain
</Directory>

Now I can simply add the line

Alias /.well-known/ /usr/local/www/.well-known/

to relevant an un-encrypted Apache host to set up the challenge-response.  My way of doing this was to configure the non-SSL site like so:

<VirtualHost 23.25.105.194:80>
    ServerName mydomain.com
    RewriteEngine On
    RewriteRule ^/?(.*) http://www.mydomain.com/$1 [R,L]
</VirtualHost>
<VirtualHost 23.25.105.194:80>
    ServerAdmin webmaster@megapipe.net
    DocumentRoot "/usr/vhosts/mydomain.com/htdocs/"
    ServerName www.mydomain.com
    ServerAlias www.mydomain.com

    # share well-known for renewal via Let's Encrypt!
    Alias /.well-known/ /usr/local/www/.well-known/

    # Anything that isn't going to domain.org/.well-known gets forwarded to the https site
    RewriteEngine on
    RewriteCond %{REQUEST_URI} !^/.well-known
    RewriteRule (.*) https://www.mydomain.com/$1 [R=301,L]

    ErrorLog "/usr/vhosts/mydomain.com/logs/error_log"
    <Directory "/usr/vhosts/mydomain.com/htdocs/">
        AllowOverride All
    </Directory>
    <IfModule mod_log_config.c>
        CustomLog "|/usr/local/sbin/rotatelogs -l /usr/vhosts/mydomain.com/logs/access_log-%Y-%m-%d.log 86400" combined
    </IfModule>
</VirtualHost>

The first <VirtualHost> entry tells Apache to simply forward anything from mydomain.com to www.mydomain.com.

The second entry tells it to forward everything from http://www.mydomain.com to https://www.mydomain.com/ except the query to the .well-known folder where Let’s Encrypt will look for its challenge response.  This way I never really have an unencrypted site running, except for the minimal amount I need to in order to configure acme-client.

Step 3: run the acme-client to get a basic configuration

Configure your first domain with a command like

export DS="domain.org www.domain.org"; \
 acme-client -mvnNC /usr/local/www/.well-known/acme-challenge/ \
 $DS && echo $DS >> /usr/local/etc/acme/domains.txt

Note: I’m doing a little inline scripting to simplify the steps necessary to creating the configuration.  If you run this command twice, you may need to edit /usr/local/etc/acme/domains.txt and remove any duplicate entries.  In the event that there is a problem issuing the certificate, this should prevent the domains from being added to the domains.txt file (but check anyway).  Also, if you are skipping creating a renewal script or find yourself needing to run the command a second time after correcting your configuration, you can simplify this command to acme-client -mvnNC /usr/local/www/.well-known/acme-challenge/  domain.org www.domain.org

If all goes well, acme-client will do some initial configuration and create your first keys.

To issue another certificate, .e.g, for another domain, use a command like

export DS="anotherdomain.org www.anotherdomain.org"; \
 acme-client -mvnNC /usr/local/www/.well-known/acme-challenge/ $DS \
 && echo $DS >> /usr/local/etc/acme/domains.txt

Note: there are fewer parameters this time. We dropped the  As above, you can simplify this further if you are skipping the renewal script:

Step 4: configuring Apache vhost to use the TLS certificate

Once your certficate is successfully installed you can configure Apache’s secure HTTP sites. We’ve already configured the insecure sites to forward to the secure sites above (except for the .well-known folder), so now we just need to add the secure sites.

This is completely optional, but what I like to do is forward mydomain.com to www.mydomain.com:

<VirtualHost 23.25.105.194:443>
   ServerName mydomain.com
   SSLEngine on
   SSLCertificateFile  /usr/local/etc/ssl/acme/mydomain.com/cert.pem
   SSLCertificateKeyFile /usr/local/etc/ssl/acme/private/mydomain.com/privkey.pem
   SSLCertificateChainFile /usr/local/etc/ssl/acme/mydomain.com/fullchain.pem
   RewriteEngine On
   RewriteRule ^/?(.*) https://www.mydomain.com/$1 [R,L]
</VirtualHost>

The actual configuration for mydomain.com is:

<VirtualHost 23.25.105.194:443>
    ServerAdmin webmaster@megapipe.net
    DocumentRoot "/usr/vhosts/mydomain.com/htdocs/"
    ServerName www.mydomain.com
    ServerAlias www.mydomain.com
    <IfModule mod_rewrite.c>
        RewriteEngine on
    </IfModule>

    SSLEngine on
    SSLCertificateFile  /usr/local/etc/ssl/acme/mydomain.com/cert.pem
    SSLCertificateKeyFile /usr/local/etc/ssl/acme/private/mydomain.com/privkey.pem
    SSLCertificateChainFile /usr/local/etc/ssl/acme/mydomain.com/fullchain.pem

    # ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9001/usr/vhosts/mydomain.com/htdocs/$1 timeout=120

    ErrorLog "/usr/vhosts/mydomain.com/logs/error_log"
    <Directory "/usr/vhosts/mydomain.com/htdocs/">
        AllowOverride All
    </Directory>
    <IfModule mod_log_config.c>
        CustomLog "|/usr/local/sbin/rotatelogs -l /usr/vhosts/mydomain.com/logs/access_log-%Y-%m-%d.log 86400" combined
    </IfModule>
</VirtualHost>

Step 5: maintain your certificates

Checking to see if your certificate needs to be renewed is as simple as running:

acme-client -mv mydomain.com www.mydomain.com

As I understand it, the certificate should update if it’s older than 60 days. You can force the certificate to update early with a command like:

acme-client -Fmv mydomain.com www.mydomain.com

(-F parameter forces the update even if it’s too soon. To either of the above commands you could also add the -b parameter, which will force current certificates to backup if there is a change.)

There are several ways you could auto-renew.

Option 1: crontab

If you just have one domain, or only a few, maybe you can live with a crontab entries instead of writing a script.  If that’s the case, you might not need the domains.txt file.

This would have acme-client run every Sunday, Wednesday, and Friday at 9pm and renew if necessary.

0 21 * * 0,3,5 /usr/local/bin/acme-client -m mydomain.com www.mydomain.com 2>&1

You can have one entry for every domain.

Option 2: custom script

 

#!/bin/sh

###
#
# This script was adapted from letskencrypt.sh by Bernard Spil
# See https://brnrd.eu/security/2016-12-30/acme-client.html
#
# To initially configure a new domain, configure
# apache properly and use a command like:
#
###

# Define location of dirs and files
DOMAINSFILE="/usr/local/etc/acme/domains.txt"
CHALLENGEDIR="/usr/local/www/.well-known/acme-challenge"
SSLDIR="/usr/local/etc/ssl"

# is changed to 1 if any domains expired
CHECKEXPIRATION=0

# Check for account key and create dir and key (-n) if required
if [ ! -f "/usr/local/etc/acme/privkey.pem" ] ; then
   EXTRAARGS="${EXTRAARGS} -n"
fi

# Loop through the domains.txt file with lines like
# example.org www.example.org img.example.org
cat ${DOMAINSFILE} | while read domain subdomains ; do

    # directory where cert.pem, fullchain.pem and chain.pem are
    # saved (${SSLDIR}/acme/${domain} should be FreeBSD default) 
    # when -m is is invoked
   CERTDIR="${SSLDIR}/acme/${domain}"

    # Define the name of the private key
    #       (${SSLDIR}/acme/private/${domain}/privkey.pem should
    #       be default with the -m option invoked)
    DOMAINKEY="${SSLDIR}/acme/private/${domain}/privkey.pem"

    # acme-client returns RC=2 when certificates 
    # weren't changed; use set +e to capture the return code
    set +e
    # Renew the key and certs if required
    acme-client -mvb -C "${CHALLENGEDIR}" \
                     -k "${DOMAINKEY}" \
                     -c "${CERTDIR}" \
                     ${EXTRAARGS} ${domain} ${subdomains} RC=$?

   # now that we have the return code, set script to exit if 
   # nonzero is returned
   set -e

   # if anything is expired, we'll want to do something 
   # (e.g., restart HTTPS)
   if [ $RC -ne 2 ] ; then
        CHECKEXPIRATION=1
   fi
done

if [ "$CHECKEXPIRATION" -ne "0" ] ; then
        service apache24 restart
fi

 

Compile custom lftp for CentOS 7.x

I use lftp to do a lot of backups.  rsync would be my preferred solution, but when I have to back up a large repository of files from a Windows machine rsync isn’t an option.

I’ve found Red Hat or CentOS keeps lftp woefully out of date.   I found some annoying bugs in the in older versions (specifically it chokes on some Windows files with unusual names and spacing).  This is how how installed lftp for CentOS 7.

Step 1: get your build environment and dependencies

yum install rpm-build ncurses-devel gnutls-devel readline-devel

You may have other dependencies, but those are the ones that seem to typically be missing.

Step 2: create a spec file

I am putting the build treen in /root/rpmbuild. The spec file contains build information.  Run

mkdir -p /root/rpmbuild/SPECS/ && nano /root/rpmbuild/SPECS/lftp.spec

And then create the following file:

Summary:    A sophisticated file transfer program
Name:        lftp                                                                                                                                                                                                
Version:    4.7.5
Release:    3%{?dist}
License:    GPLv3+
Group:        Applications/Internet
Source0:    ftp://ftp.yar.ru/lftp/lftp-%{version}.tar.xz
URL:        http://lftp.yar.ru/
BuildRoot:    %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires:    ncurses-devel, gnutls-devel, pkgconfig, readline-devel, gettext
%description
LFTP is a sophisticated ftp/http file transfer program. Like bash, it has job
control and uses the readline library for input. It has bookmarks, built-in
mirroring, and can transfer several files in parallel. It is designed with
reliability in mind.
%package scripts
Summary:    Scripts for lftp
Group:        Applications/Internet
Requires:    lftp >= %{version}-%{release}
BuildArch:    noarch
%description scripts
Utility scripts for use with lftp.
%prep
%setup -q
#sed -i.rpath -e '/lftp_cv_openssl/s|-R.*lib||' configure
sed -i.norpath -e \
   '/sys_lib_dlsearch_path_spec/s|/usr/lib |/usr/lib /usr/lib64 /lib64 |' \
   configure
%build
%configure --with-modules --disable-static --with-gnutls --without-openssl --with-debug
make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
export tagname=CC
make DESTDIR=$RPM_BUILD_ROOT INSTALL='install -p' install
chmod 0755 $RPM_BUILD_ROOT%{_libdir}/lftp/*
chmod 0755 $RPM_BUILD_ROOT%{_libdir}/lftp/%{version}/*.so
iconv -f ISO88591 -t UTF8 NEWS -o NEWS.tmp
touch -c -r NEWS NEWS.tmp
mv NEWS.tmp NEWS
# Remove files from $RPM_BUILD_ROOT that we aren't shipping.
#rm $RPM_BUILD_ROOT%{_libdir}/lftp/%{version}/*.la
rm $RPM_BUILD_ROOT%{_libdir}/liblftp-jobs.la
rm $RPM_BUILD_ROOT%{_libdir}/liblftp-tasks.la
rm $RPM_BUILD_ROOT%{_libdir}/liblftp-jobs.so
rm $RPM_BUILD_ROOT%{_libdir}/liblftp-tasks.so
%find_lang %{name}
%clean
rm -rf $RPM_BUILD_ROOT
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc BUGS COPYING ChangeLog FAQ FEATURES README* NEWS THANKS TODO
%config(noreplace) %{_sysconfdir}/lftp.conf
%{_bindir}/*
%{_mandir}/*/*
%dir %{_libdir}/lftp
%dir %{_libdir}/lftp/%{version}
%{_libdir}/lftp/%{version}/cmd-torrent.so
%{_libdir}/lftp/%{version}/cmd-mirror.so
%{_libdir}/lftp/%{version}/cmd-sleep.so
%{_libdir}/lftp/%{version}/liblftp-network.so
%{_libdir}/lftp/%{version}/liblftp-pty.so
%{_libdir}/lftp/%{version}/proto-file.so
%{_libdir}/lftp/%{version}/proto-fish.so
%{_libdir}/lftp/%{version}/proto-ftp.so
%{_libdir}/lftp/%{version}/proto-http.so
%{_libdir}/lftp/%{version}/proto-sftp.so
%{_libdir}/liblftp-jobs.so.*
%{_libdir}/liblftp-tasks.so.*
%files scripts
%defattr(-,root,root,-)
%{_datadir}/lftp

You can download a spec file for lftp here, but you will need to make some modifications.  The version needs to be changed to the version you downloaded, and I removed references to distro-specific patches. (I actually have no idea what these patches do, but they are several versions old.)

Step 3: download the source

In my example, I downloaded lftp version 4.7.5.

mkdir -p /root/rpmbuild/SOURCES/ && cd /root/rpmbuild/SOURCES/ && wget http://lftp.yar.ru/ftp/lftp-4.7.5.tar.xz

Step 4: build

rpmbuild -ba lftp.spec

Step 5: install

rpm -ivvh /root/rpmbuild/RPMS/x86_64/lftp-4.7.5-3.el7.centos.x86_64.rpm

You can use the command rpm -qa lftp to confirmation successful installation.

Resuscitating my blog: miscellaneous musings, politics & urbanism roundup

I’ve been slowly reviving my personal blog.  I set most of the posts to draft status to be re-edited before I release them back into the wild. I’ve stayed somewhat active on social media over the years, but mostly haven’t felt like blogging, letting this blog largely expire for a while.  I have a fairly large amount of content I’ve written going back to 2006, with a lull after 2011.  I am slowly re-editing it to update links.

Looking back on this content, there is so much that probably would only warrant a tweet now that I blogged about at one time. A post on New York newsstands? Well, it’s still cool, but it seems so 2008 to make a wistful blog post about that. Much of the political stuff is almost like a time capsule, but I find it amusing to read. Remember how the Gang of Four cretins derailed New York politics for so long? I kind of miss Richard Ravitch. I even miss David Paterson a little.

I never thought much of Mike Bloomberg’s authoritarian politics, but sometimes I found myself defending his policies. I thought congestion pricing was a good idea, for instance, and was always amazed at how people would bend over backwards to oppose it. Even the MTA was ambivalent about it, and as I remember the local transit unions were completely silent.  I always found automobile casualties futile and needless; the way we structure our society around cars makes us less safe. Of course, maybe in some of my musings on the subject, such as this one from 2006, I should have put more thought into mitigating the downsides, whether they were real or merely perceived.

I wrote a lot on transit and urbanism, sometimes just little details I found interesting. Some of my thoughts on urbanism were often too abbreviated but I think quite prescient too. This commentary on San Francisco’s transit center. Since I wrote that, many projects like that have opened in New York and they are still unfortunate.  I’ve been on the road a lot the past few years, so I’d probably like to talk about urbanism more. Meanwhile, complaints about every little fare increase were a constant theme in New York over the years.

I meant to put more into the post at the time, but have a time capsule about Kirsten Gallibrand, whose policy focus shifted greatly after David Paterson appointed her to the U.S. Senate to replace Hillary Clinton. Then, as now, little thought about transit.

Ten years ago I was paying a lot more attention to infrastructure than I am nowadays. But it’s unfortunate how much infrastructure could have been.  Transit on the Tappan Zee? Commuter rail to Stewart Airport?  This post mentions how transit was almost guaranteed on the Tappan Zee Bridge.  Well, muscle car aficionado Andrew Cuomo killed that a few years later.

I sometimes wrote, haphazardly, about higher education.  Elliot Spitzer of all people had some lofty ambitions for improving the state of New York’s higher education. I think since I wrote that I have taken a step back and reconsidered how higher education should have a role in our society. The decade since I published that post has seen Occupy Wall Street, student debt crises, ever-higher tuition fees, and of course the fiery campaign of Bernie Sanders at least somewhat centered on free higher education.

NYC can’t prohibit soda purchases with food stamps

In his efforts to get a handle on the obesity epidemic plaguing the poor in New York City, Michael Bloomberg pushed for an “experimental” ban on purchasing soda with food stamps. Federal officials rejected (NYT: Federal Officials Reject City’s Plan to Ban Food Stamps for Soda“) that proposal on Friday.

Jessica Shahin, an associate administrator in the Agriculture Department, wrote that the waiver the city sought was denied because of the logistical difficulty of sorting out which beverages could or could not be purchased with food stamps and because it would be hard to gauge how effective the step was in reducing obesity. As an alternative, Ms. Shahin suggested the federal government could work with the city on other efforts to encourage consumers to make “healthy choices.”

Tom Vilsack, the secretary of agriculture, said in a statement that the department “has a longstanding tradition of supporting and promoting incentive-based solutions that are better-suited for the working families, elderly and other low-income individuals” who rely on food stamps than restrictions are. “We are confident that we can solve the problem of obesity and promote good nutrition and health for all Americans and stand ready to work with New York City to achieve these goals.”

Unsurprisingly, soft drink industry lobbyists saw the decision as a victory. More surprisingly, Bloomberg’s proposal had poverty advocates up in arms too.

The disappointment … was matched by the thrill in the voice of Joel Berg, the executive director of the New York City Coalition Against Hunger, who cheered the federal government for “deciding not to micromanage” the lives of poor people.

“The whole attempt was misguided and unworkable,” Mr. Berg said. “This proposal was based on the false assumption that poor people were somehow ignorant or culturally deficient.”

Similar rhetoric came from the U.S. Department of Agriculture:

The Agriculture Department questioned the merits of that plan, which focused on candy and soda, among other foods, and said it would “perpetuate the myth” that food stamp users made poor shopping decisions.

Critics commenting on The New York Times‘ CityRoom blog entry on the subject were often critical of the idea of a “nanny state” that prevented people from purchasing what they want.

Unfortunately, I see too many flaws in people’s reasoning, and USDA’s motivations seem plainly antithetical to the interests of New York and the poor. Tom Vilsack, it was frequently pointed out on the above-mentioned blog post, is a former governor of Iowa with ties to industrial food interests. Critics of the “nanny state” are forgetting that public money is already going to “nanny” people and, as a result of a complicated array of subsidies and industry conditions, the government is more or less paying people to make poor buying decisions.  The argument that New York’s waiver would be tough to administer seems to fall flat on its face; beer already is forbidden, and beer arguably is less unhealthy than soda.

On the other hand, I see Joel Berg and some other critics as well-meaning, but misguided. It may not be a popular thing to say, but I think it’s fair to say that poorer people are more likely to be uneducated on matters related to nutrition – which doesn’t make the poor stupid. Even when people are well-educated on food consumption, I think it’s safe to say that they often have other motivations, including financial ones. Non-nutritious food and beverages are low-hanging fruit that offer cheap calories. In economic terms, the “utility” of a high-calorie unhealthy meal exceeds the utility of a low-calorie, more expensive, yet healthier meal. Food stamp users must stretch tight food stamp budgets.

There are reasons to think Bloomberg’s proposal would not have worked. The biggest is, with soda banned, there would have been little to prevent people from switching to other high-calorie processed products, like bad fruit juices or foods high in sugar. Nonetheless, it deserves a try, and Federal obstruction is unfortunate.

Slackware with lighttpd, php, and mono (source installations)

This overview of installing the relevant lighttpd and mono software packages from source on Slackware 13.1 is designed as a broad overview. I’ve been using Apache and PHP for years, but I’m quite novice at lighttpd and mono. Also, despite using GNU/Linux for years at home, I’ve usually set up servers with stable, upgradeable FreeBSD.

Hopefully this will help others avoid pitfalls (or be of use to me in the future if I ever have to recover). I needed to install a fast web server with PHP and Mono. I’ve had a lot of trouble getting mono running on FreeBSD, so I decided to go with a GNU/Linux distribution for this server. Being a stickler for things I liked in the past, I went with the one I’ve always found easiest to use and upgrade: Slackware.

Software packages

As of this writing, the latest Slackware is 13.1, though I assume these techniques should mostly carry over to similar versions. I’m using the 64-bit variety. I was rather liberal about installing most software packages that came with Slackware 13.1, mostly out of laziness. After I was finished installing, I deleted Apache so I could install lighttpd.

The latest mono source files I used were for 2.6.4.

Step 1: Basic lighttpd install

I did a pretty vanilla install of lighttpd 1.4.26. Basically just did:

  1. downloaded, untar’d
  2. ./configure
  3. make
  4. make install

Simple, right? After this, I took some cues from the lighttpd documentation and set up a simple config file in /etc/lighttpd/lighttpd.conf (you have to manually create the directory). It looks like this:

server.document-root = "/var/www/servers/[site]/pages"

server.port = 80
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www"
server.groupname = "www"

mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain",
".jpg" => "image/jpeg",
".png" => "image/png"
)

static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc" )
index-file.names = ( "index.html" )

Make sure to modify the document root to wherever you keep your HTML files. You’ll want to create the www user and www group or change these to an existing user.

Next up things got a little tricky because there wasn’t a readily available Slackware init.d script to start and stop this monster. No problem; I just borrowed one from the slackbuilds.com’s pre-compiled repository. I slightly modified it to match the configuration I made:

#!/bin/sh
# Copyright (c) 2007, Daniel de Kok
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

LIGHTTPD=/usr/local/sbin/lighttpd
PIDFILE=/var/run/lighttpd.pid
LIGHTTPD_OPTIONS="-f /etc/lighttpd/lighttpd.conf"

is_pidof() {
local STATE=$(ps -p $1 -o cmd= | grep "$2" > /dev/null ; echo $?)
return $STATE
}

lighttpd_start() {
echo "Starting lighttpd: $LIGHTTPD"
if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) lighttpd ; then
echo "Already running!"
return
fi
$LIGHTTPD $LIGHTTPD_OPTIONS
}

lighttpd_stop() {
echo "Stopping lighttpd: $LIGHTTPD"
if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) lighttpd ; then
kill $(cat $PIDFILE)
rm -f $PIDFILE
else
echo "Not running!"
fi
}

lighttpd_restart() {
lighttpd_stop
sleep 1
lighttpd_start
}

lighttpd_reload() {
kill -s HUP $(cat $PIDFILE)
}

case "$1" in
'start')
lighttpd_start
;;
'stop')
lighttpd_stop
;;
restart)
lighttpd_restart
;;
reload)
lighttpd_reload
;;
*)
echo "usage $0 start|stop|restart"
esac

Save the above to /etc/rc.d/rc.lighttpd and change the permissions to allow execution (chmod u+x /etc/rc.d/rc.lighttpd).

Put an index.html file in your HTML root directory. Test your configuration by running /etc/rc.d/rc.lighttpd start and pointing your web browser to http://localhost to see that your index file loads. Next try to stop the server: /etc/rc.d/rc.lighttpd stop.

If you just want a basic lighttpd install on Slackware, you can more or less stop here.

Start on boot and stopping on shutdown

To make lighttpd start on boot simply add the following you your /etc/rc.d/rc.local file:

if [ -x /etc/rc.d/rc.lighttpd ]; then
/etc/rc.d/rc.lighttpd start
fi

Likewise, to make it stop on shutdown, add this to /etc/rc.d/rc.local_shutdown (usually empty by default):

if [ -x /etc/rc.d/rc.lighttpd ]; then
/etc/rc.d/rc.lighttpd stop
fi

Mono 2.6.4 install

This is the first time I’ve seen mono install flawlessly on Slackware without using the sources made available by the SlackBuilds. I basically followed the directions exactly as they appeared in the README.

  1. ./configure –prefix=/usr/local
  2. make
  3. make install

xsp 2.6.4

To use ASP.NET with lighttpd, xsp needs to be installed. xsp is the package that contains the fastcgi components that allow mono to interface with lighttpd. Once again, I mostly followed the accompanying documentation. I used the config prefix /usr/local rather than the one suggested in the documentation.

The steps I followed to install were:

  1. ./configure –prefix=/usr/local
  2. make
  3. make install

A little note about step 2: I had a slight hitch following the standard installation instructions. Using the installation parameters from the above mono install, I needed to specify where the directory holding the file dotnet.pc in order to make the xsp package. Using the find command:

find /usr -name dotnet.pc

I determined it was in /usr/local/lib/pkgconfig and simply added the path to the existing PKG_CONFIG_PATH environmental variable.

To find your list of environmental variables, type the env command and hit enter.

Locate get the relevant variable from the list. In my case, it was PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig

Reassign the variable by typing

PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig

into your shell prompt.

It’s quite likely a reboot would have solved this problem as well.

libgdi installation

I didn’t realize this wasn’t installed. It probably should have been installed first! This is necessary to run mono on fastcgi. Anyway, the problem is an easy one to rectify.

Once again, I did:

  1. ./configure –prefix=/usr/local
  2. make
  3. make install

Modifying lighttpd configuration to use mono

This part gets a little tricky, but it’s doable. Much of my information for this area comes from a document, also linked below, on interfacing FastCGI and lighttpd to use mono.

First of all, create a new directory in your /etc/lighttpd directory called conf.d.

Save the following to /etc/lighttpd/conf.d

# Add index.aspx and default.aspx to the list of files to check when a
# directory is requested.
index-file.names += ( “index.aspx”, “default.aspx” )

### The directory that contains your Mono installation.
var.mono_dir = “/usr/local/”

### A directory that is writable by the lighttpd process.
# This is where the log file, communication socket, and Mono’s .wapi folder
# will be created.
# For a typical system-wide installation on Linux, use:
var.mono_shared_dir = “/tmp/”

### The path to the server to launch to handle FASTCGI requests.
# For ASP.NET 1.1 support use:
#var.mono_fastcgi_server = mono_dir + “bin/” + “fastcgi-mono-server”
# For ASP.NET 2.0 support use:
var.mono_fastcgi_server = mono_dir + “bin/” + “fastcgi-mono-server2”

### The root of your applications
# For apps installed under the lighttpd document root, use:
var.mono_fcgi_root = server.document-root

### Application map
# A comma separated list of virtual directory and real directory
# for all the applications we want to manage with this server. The
# virtual and real dirs. are separated by a colon.
var.mono_fcgi_applications = “/:.”

Next up, the configuration file needs some additions and alterations.

Open /etc/lighttpd/lighttpd.conf and add the following to your configuration under the server.document-root = "/var/www/servers/[your web root]/pages" line:

server.modules = (
# "mod_rewrite",
# "mod_redirect",
# "mod_alias",
"mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
# "mod_auth",
# "mod_status",
# "mod_setenv",
"mod_fastcgi",
# "mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
# "mod_cgi",
# "mod_compress",
# "mod_ssi",
# "mod_usertrack",
# "mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
"mod_accesslog" )

This is a list of modules. I kept the ones not relevant commented out for now. Of course, many people will want to use some of them, particular rewrite, redirect, and alias. Either way, I prefer to keep things simple for now. Next change the line

index-file.names = ( "index.html" )

to

index-file.names = (
"index.xhtml", "index.html", "index.htm", "default.htm",
"index.php", "default.aspx", "index.aspx"
)

Beneath your new index file list, add the following:

include "conf.d/mono.conf"

fastcgi.server = (
".aspx" => ((
"socket" => mono_shared_dir + "fastcgi-mono-server",
"bin-path" => mono_fastcgi_server,
"bin-environment" => (
"PATH" => "/bin:/usr/bin:" + mono_dir + "bin",
"LD_LIBRARY_PATH" => mono_dir + "lib:",
"MONO_SHARED_DIR" => mono_shared_dir,
"MONO_FCGI_LOGLEVELS" => "Standard",
"MONO_FCGI_LOGFILE" => mono_shared_dir + "fastcgi.log",
"MONO_FCGI_ROOT" => mono_fcgi_root,
"MONO_FCGI_APPLICATIONS" => mono_fcgi_applications
),
"max-procs" => 1,
"check-local" => "disable"
))
)

fastcgi.map-extensions = (
".asmx" => ".aspx",
".ashx" => ".aspx",
".asax" => ".aspx",
".ascx" => ".aspx",
".soap" => ".aspx",
".rem" => ".aspx",
".axd" => ".aspx",
".cs" => ".aspx",
".config" => ".aspx",
".dll" => ".aspx"
)

Appendix: links and more

lighttpd homepage.

The mono project site:

Google code information on the install (I found this very helpful, as it was simpler than the mono documentation).

Down syndrome in the Heartland

I was Googling for yearly statistics on obesity at the urban level, which is shockingly hard to find. So there I was, mindin’ my own Google results, when I ran into the article Sprawl and Obesity in Chicago: Why All the Fuss? (which, by the way, was completely irrelevant to what I was looking for). I clicked on it, and then saw, after I clicked on it, that right there in the bloody title of the search result was appended the words “by Wendell Cox.” I learned several years ago that Wendell Cox probably ranks somewhere between a snake oil salesman and an 8-ball in his ability to offer intelligent original research. To say the least, the above headline probably says it all to any halfway discerning reader that this guy is probably a shill for shortsighted industrial interests (namely cars and smog producers). What Cox throbs most for is spinning transit use as a wasteful subsidy borne by an increasingly put-upon middle class. He does have two talents though: trying to look clever by asking dismissive rhetorical questions (“sun light: who needs it?”) and putting a scholarly spin on naked political propaganda. What Wendell lacks for in intellectual honesty, he makes up for in proliferation.

People’s Republic of New France
United States of America

(thanks Wikipedia for preserving the above abortion for all eternity; even if, as is common on Wikipedia, the above version is flawed because Alberta is a red state)

But all that’s really besides the point. My real agenda here is making fun of the site that hosted the above URL: the Heartland Institute. Everyone knows there’s a mass media narrative in America about coastal big city urban elites thumbing their effete, snobbish, latte-dipped noses at those real Americans living in places like, uh, well, it doesn’t really matter where they live. Needless to say, real Americans are too pure and wholesome to live in big cities, even if big cities are possibly the economic engines paying for bridges and signs in real America. They also don’t live in rural places like Vermont and western Massachusetts, which are full of hippies and bourgeois types who tolerate America-destroying forces like immigration and ethnic diversity. Basically, real Americans don’t live in the states where the United States was born, places like Massachusetts and Pennsylvania, regardless of what those crybabies at fuckthesouth.com say. Indeed, real Americans live in the Midwest, which wasn’t even made up of states in 1791, and the deep South, which supported American independence rather grudgingly if the musical 1776 is to be believed (and it probably is). Such jokes seem dated now, now that Barack Obama was elected and fixed the whole world, but the legendary Jesusland map kind of says it all.

There’s a religious aspect to this. Having internalized the above, which resulted in gaining a justified sense of moral superiority over the rest of humanity, The Heartland Institute found something missing: idols (e.g., saints or ikons — something to give a sensual meaning to the existence of the earthly truth). Any new religion inevitably finds itself looking to the past to seek out paragons of virtue because we inevitably don’t remember the flaws of our historical and mythological leaders. Who remembers that Heracles and Moses were both murderers? Who remembers that Thomas Jefferson kept slaves? Who remembers that Ayn Rand was a truculent, fascistic, sniveling twat?

However, picking idols is no easy task. Not just anyone can be chosen. American Christians often find Jesus to be a poor idol indeed because he really doesn’t live up to many of the beliefs they hold most dear. Thankfully, the Heartlandites have other choices. Theirs is an ideology very much the opposite of Jesus’s ideology. Flawed as Jesus the man might have been, and we really don’t know how flawed he was because of our scant records, Jesus of the Gospels favored the weak over the strong, the poor over the rich, and the sinner of the saint — if Christian theology has any elegance, it’s that occasional point that maybe it’s the fallen who need grace most of all. But Real Americans will have none of that crap. The Heartlandites are for markets, guns, property. More earthly models had to be chosen, ones that fit Real American preconceptions about themselves

To that end, the Heartlandites created an animated banner at the top of their web site to alternate through their idols.
This lead to some curious choices, many of whom have little or nothing to do with each other:

  • John Locke —moral and political philosopher; proto-liberal who favored limits on monarchical power
    • Market activities: sold future generations on charlatan contractarian philosophy, which echoes down to this day in the works of writers like John Rawls
  • Crispus Attucks — actually, nobody really knows anything about him, except that he died in the Boston Massacre and might have had dark skin
  • Benjamin Franklin — American inventor and politician (Americans get mocked for lack of civil knowledge of other cultures, but Americans who travel abroad frequently find Europeans telling them that Benny was America’s best president); born in puritanical Boston, migrated to Philadelphia, where he spent a life rich in intellectual pursuits
    • Market activities: freely initiated the exchange of money for sex
  • Thomas Paine — anti-authoritarian liberal writer, active in both the United States War for Independence and the French Revolution; anti-slavery and arguably pro-gender equality
    • Market activities: wrote stuff, TLDR
  • Thomas Jefferson — wrote the Declaration of Independence, which was fine-tuned by Franklin; third President of the United States who favored anti-mercantile policies and distrusted financial markets
    • Market activities: monopolized the loins of at least one slave for a fixed period of time, no doubt in a mutually beneficial exchange of services; as President, purchased a lot of rather marginally useful land from the French, who had only recently stolen it back from the Spanish
  • James Madison — wrote some early American political propaganda; fourth President of the United States
  • Booker T. Washington — token black man (in case Crispus doesn’t cover all the bases)
    • Market activities: credited with being the first inventive black man in American history (Benjamin Bannecker is forgotten)
  • Ayn Rand — Russian fascist
    • Market activities: author of some really crappy books
  • Milton Friedman —right-wing liberal economist

Of course, not many of them even come from the “Heartland” of the United States. Most of the American idols come from the coasts, especially Virginia. Milton Friedman may be the only true Heartlandite in the bunch, since he was seated at the University of Chicago for decades.

Financial Leverage

I love this description of the 1929 Wall Street trust as described in John Kenneth Galbraith’s The Great Crash 1929 (1988 revision published by Houghton Mifflin Company, page 57-58):

The principle of leverage is the same for an investment trust as in the game of crack-the-whip. By the application of well-known physical laws, a modest movement near the point of origin is translated into a major jolt on the extreme periphery. In an investment trust leverage was achieved by issuing bonds, preferred stock, as well as common stock to purchase, more or less exclusively, a portfolio of common stocks. When the common stock so purchased rose in value, a tendency which was always assumed, the value of the bonds and preferred stock of the trust was largely unaffected. These securities had a fixed value derived from a specified return. Most or all of the gain from rising portfolio values was concentrated on the common stock of the investment trust which, as a result, rose marvelously.

Consider, by way of illustration, the case of an investment trust organized in early 1929 with a capital of $150 million — a plausible size by them. Let it be assumed, further, that a third of the capital was realized from the sale of bonds, a third from preferred stock, and the rest from the sale of the common stock. If this $150 million were invested, and if the securities so purchased showed a normal appreciate, the portfolio value would have increased by midsummer by about 50 per cent. The assets would be worth $225 million. The bonds and preferred stock woulds till be worth only $100 million; their earnings would not have increased, and they could claim no greater share of the assets in the hypothetical event of a liquidation of the company. The remaining $125 million, therefore, would underlie the value of the common stock of the trust. The latter, in other words, would have increased in asset value from $50 million to $125 million, or by 50 per cent in the value of the assets of the trust as a whole.

This was the magic of leverage, but this was not all of it. Were the common stock of the trust, which had so miraculously increased in value, held by still another trust with similar leverage, the common stock of that trust would get an increase of between 700 and 800 per cent from the original 50 per cent advance. And so forth. In 1929 the discovery of the wonders of the geometric series struck Wall Street with a force comparable to the invention of the wheel. There was a rush to sponsor investment trusts which would sponsor investment trusts, which would, in turn, sponsor investment trusts. The miracle of leverage, moreover, made this a relatively costless operation to the ultimate man behind all of the trusts. Having launched one trust and retained a share of the common stock, the capital gains from leverage made it relatively easy to swing a second and larger one which enhanced the gains and made possible and third and still bigger trust.

Transportation policy: intractable opposition

Richard Ravitch’s commission finally made some recommendations about what to do about the MTA. The proposals include a broad range of funding sources, including a small payroll tax in the MTA’s 12-county territory and tolling the East River bridges. From The New York Times (“Mixed Reviews on Transit Plan” by William Neuman and Jeremy W. Peters, 2008-12-04):

State legislators, mainly from Brooklyn, Queens and the Bronx, said the plan by a state commission headed by Richard Ravitch, a former authority chairman, would unfairly burden drivers from their districts.

“It’d be an extreme hardship to have to pay a toll every time,” said Assemblywoman Helene E. Weinstein, a Democrat from Brooklyn. “We’re talking about people going to work, people going to doctor’s appointments, elderly people.”

The commission’s plan calls for the revenue from the new bridge tolls — about $600 million a year — to be earmarked for an aggressive expansion of bus service in the city and surrounding counties. It became immediately clear that the two main prongs of the plan would each face very different receptions in the State Legislature, whose approval is required before the plan can be put into effect.

“Any solution that disproportionately burdens middle- and working-class people who live in the Bronx, Queens and Brooklyn is not a fair way to deal with this, and that’s what tolling the bridges would do,” said Assemblyman Michael N. Gianaris, a Democrat from Queens. Mr. Paterson said that his staff would draft legislation to carry out the commission’s proposals. But he acknowledged that there might be changes made during negotiations with the Legislature.

How many working class and middle class citizens of any borough of New York City do they think drive compared to the number who take some form of public transportation? The true answer is probably very few in the region, and even fewer in the five boroughs. So, why are legislators in the city always so adamantly opposed to something that so clearly benefits the majority of their constituents?

It’s really time to let go of this myth that automobiles are the gateway to the middle class. Having automobiles thrust upon New York City made the air dirtier, the streets less safe, and has pushed respiratory diseases upwards. We depend on cars for many things, but there’s no reason we need to depend on them as much as we do.

Then, these articles very rarely touch on a larger problem: the city has very little say about its own transportation system. It’s not allowed to toll its own streets without the approval of a legislature that includes people who don’t represent the city, and the MTA controls the Subway.

San Francisco shows NYC what not to build

I have only been to San Francisco once, but I really enjoyed it. It’s dense, it’s vibrant, it’s elegant – which is why it’s sad to see it get destroyed. Check out Streetsblog’s “San Francisco Mayor to NYC: ‘Eat Your Heart Out’.” I can count quite a few problems with that rendering just based on observing form vs. function:

  1. It’s big. It takes up five blocks. It disrupts the flow of pedestrian traffic for five blocks.
  2. The park is high up and inaccessible.
  3. The transit center probably doesn’t need to be in downtown. Stops can be in downtown; transfers can be in downtown; the transit center is redundant.
  4. If this is a terminal station, it’s a real waste. There’s no need to have a terminal station built in the most expensive part of the city.