I wanted to give a buddy access to a website hosted on my box. So I tried scponly, since I only wanted to provide SFTP access to that particular directory, using a chroot jail. The steps are as follows.

  1. Install the scponly package using Ubuntu’s APT package management system.
  2. Use the script provided to set up your first jail and your user’s home directory. For the location of the user’s jail, give the path of the directory you want to share.
  3. Provide a password for the new user.
  4. Ensure that the new user has permissions to read and write all the necessary directories in your Web site.


$ sudo apt-get install scponly
$ gzip -dc /usr/share/doc/scponly/setup_chroot/setup_chroot.sh.gz > /tmp/setup_chroot.sh
$ sudo /tmp/setup_chroot.sh


Next we need to set the home directory for this scponly user.
please note that the user's home directory MUST NOT be writeable
by the scponly user. this is important so that the scponly user
cannot subvert the .ssh configuration parameters.


for this reason, a writeable subdirectory will be created that
the scponly user can write into.

Note that I removed the /incoming subdirectory created by this script. There was no need for a separate directory for my buddy to upload files. He could have permissions over the whole site tree.


-en Username to install [scponly]
bob
-en home directory you wish to set for this user [/home/bob]
/var/www/sites/bobsite/htdocs
-en name of the writeable subdirectory [incoming]


-e
creating /var/www/sites/bobsite/htdocs/incoming directory for uploading files


Your platform (Linux) does not have a platform specific setup script.
This install script will attempt a best guess.
If you perform customizations, please consider sending me your changes.
Look to the templates in build_extras/arch.
- joe at sublimation dot org


please set the password for bob:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
if you experience a warning with winscp regarding groups, please install
the provided hacked out fake groups program into your chroot, like so:
cp groups /var/www/sites/bobsite/htdocs/bin/groups

This script added certain directories to the site root (/var/www/sites/bobsite/htdocs). Every other directory needed to be writable by Bob. So let’s add Bob to a special group, and allow that group write access on all the website’s files.


$ sudo adduser bob www-data

We can ignore /bin, /etc, /lib and other directories added to the chroot jail (the website filesystem):


$ sudo find . \! -user root -exec chgrp www-data \{\} \;
$ sudo find . \! -user root -exec chmod g+w \{\} \;

Good to go!

I migrated a bunch of stuff from a CentOS 4 server to Ubuntu 8.04 LTS over the last couple of days.

  • Five websites: One Moodle and one Drupal site backed by MySQL databases, and three static sites. SSL setup.
  • Added some software. How can I work without vim and slocate?
  • Security hardening, including a service review, permissions, firewall setup, administrative access through SSH, sudo config, and Postfix with spam filtering.
  • Nagios server monitoring config.

I checked my work logs and decided that I did pretty well, considering I got it all done in 10 hours 35 minutes.

This one’s an easy one, from the tzselect (1) manpage:

sudo dpkg-reconfigure tzdata

Interested in getting Java to work in the just-released Google Chrome on your Ubuntu install? You can always try linking directly to the plugin binary:

$ locate libnpjp2.so
/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libnpjp2.so
$ sudo mkdir /opt/google/chrome/plugins
$ cd /opt/google/chrome/plugins/
$ sudo ln -s /usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/libnpjp2.so .

Works for me!

Ever seen this when in Drupal’s administration pages?

Fatal error: Cannot redeclare getnodecount() (previously declared in /var/www/sites/site.org/htdocs/includes/common.inc(1685) : eval()'d code:3) in /var/www/sites/site.org/htdocs/includes/common.inc(1685) : eval()'d code on line 9

There are a few causes for this, as mentioned on drupal.org, but the one in which you might be interested (because your error message looks more similar to mine, above, than to the drupal.org documentation) is when PHP is actually contained in a block or node body. That’s something you should suspect if you see the above error message referring to PHP’s eval() function.

To fix this, do something in MySQL like

SELECT nid
FROM node_revisions
WHERE body LIKE '%getnodecount%';

And edit the offending nodes in Drupal with a URL such as

http://example.com/node/123/edit

Whoops! Chris Wilson had one good point, but some big misses in this article. I guess this is a danger for a writer — for example, the “PHP” input filter setting allows JavaScript by default, but Chris didn’t select that setting.

The biggest problem is that he claims that Drupal is impenetrable, which it is. For many beginners, it has a steep learning curve. But he never makes the connection; why do your site visitors care? If millions of them appear, and your site continues to work well in response because it was built with a solid operational foundation instead of being built with something that has a cute-but-heavy GUI on the backend, don’t they benefit? It looks to me like Chris has unfortunately conflated the needs of end-users with the needs of site developers.

Also, I’d like to take my hat off to the organization that landed the $18M contract to migrate recovery.gov into Sharepoint. That’s a lot of money for a site built using tables in HTML and containing leftover hidden cruft like “this Web Part Page has been personalized. As a result, one or more Web Part properties may contain confidential information. Make sure the properties contain information that is safe for others to read. After exporting this Web Part…”

Interested in flushing your Ubuntu DNS cache? Note: I’m running Jaunty Jackalope as of the date of this post.

Well, Ubuntu doesn’t cache DNS by default. Your cache rests within your router, or your assigned DNS servers. You could restart your router, if you have access to it. Or wait until the time-to-live has expired.

You can install a local resolver that will cache DNS addresses, if you like. It will speed up your Web access slightly, since your Web browser will check the local cache first. I imagine the time you save will be measured in milliseconds.

Do that with:

sudo apt-get update && sudo apt-get install nscd

And to clear your local cache, restart the service:

sudo /etc/init.d/nscd restart

Are you creating a new password for every login you create, at every new Web site you visit?

Of course you are, because that’s more secure than just using the same password for e-mail, banking, hotel reservations, online photos, and chat.

So, you need a way to keep those passwords organized.

I recommend KeePass Password Safe. It’s very easy to use and works on Linux, Windows, and Mac OS X.

And if you want to keep that password file synchronized with the other computers you might use (for example, your home computer, and a laptop), you should try Dropbox. Here’s my referral link for Dropbox. That will give both you and me an extra 250MB of space when you sign up. Dropbox will transparently keep your files synchronized between any number of computers, and will keep file revisions as well.

Can’t beat the command line for flexibility and power in accomplishing system administration tasks. Here’s one way to recursively list the filesizes and full paths of files with a particular extension from the command line:

nice find . -name "*.swf" -type f -print0 | xargs -0r ls -skS | less

This is a succinct way to say:
“Show me all Flash files in the current directory hierarchy, descending to unlimited depth. Print the full filename on standard output followed by a null character. Send each filename in turn to the ‘ls’ command, which will look up each file’s size and print that in 1K blocks followed by the filename. (If there aren’t any results from the first command, don’t even run the ‘ls’ command, since that will just give us a list of all the files in the current directory.) Finally, send all that output to the ‘less’ command, which will allow me to page through and view it easily.”

EDIT: Added -r switch to xargs command to ensure we don’t see a list of all files, if the first ‘find’ command doesn’t find any. That sort of thing could be confusing.

I’m working with an organization that has been refusing “share this” e-mails from our Web site; specifically, e-mails that originate at our Web server that have that organization’s domain name in the “From:” header.

Here’s the problem with this. Let’s say that Joe Bloggs works at Bloggy Spot, and his e-mail address is “joe@bloggyspot.com.” His coworker Carl really wants to forward him a relevant article from the Time Magazine Web site, so he fills out the form, enters his e-mail address (which is required), and Joe’s, and hits “send.”

But since that message from Time Magazine does not originate from inside your network — as far as you can tell — and it claims to come from Joe’s coworker Carl (“carl@bloggyspot.com”), you refuse that message. “Sorry, can’t deliver to Joe,” you say. “There’s no way you could be Carl. Carl wouldn’t send e-mail from anywhere other than here.”

Don’t refuse those e-mails. Allow them. Rely on other, more reliable methods, and be happy.

Why shouldn’t you base your filtering on the From: header?

For two reasons.

First, you’re trying to fight against something that has been part of the nature of e-mail since its beginning, and second, you’re trying to fight against the nature of the Web today.

  1. This has been the nature of e-mail since its beginning.
    The e-mail protocol standard has always allowed e-mail clients, and hence people, to put whatever they want in the “from” box — so from the beginning, conscientious system administrators have had to rely
    on much more robust methods of content and spam filtering. Looking in the “From:” header for an e-mail supposedly sent from “bloggyspot.com,” and prohibiting e-mail that way, will only make it harder on users. Regarding the organization I’m negotiating with, their system administrator did point out that they already have multiple other layers of filtering and spam protection in place. I argued that since that was the case and since those methods are much more reliable, they should be relying on these instead.

    Perhaps you see the issue: a system that relied only on this level of filtering would be quite easy to defeat, and a system that relied on more filtering than this, wouldn’t need this type of quasi-effective filtering anyway.

  2. This is the nature of the Web today.
    When you visit a Web site and forward an article to someone you know, your message in the vast majority of cases comes “from” your e-mail address. Obviously, this is done so that the recipient will be more
    likely to accept the e-mail when it arrives. The Web’s most popular sites all follow this practice.

    The New York Times, Time Magazine, CNN, and Fox News sites, for example, allow — and in the case of the Times, require — a user to enter their own e-mail address as the “From:” address. Yahoo!, the Web’s third most visited site, does this as well. I’m sure there are many, many more examples.

Spam is a big problem for organizations, but when filtering spam, you’ve got to choose your battles carefully. If you hamstring your users too much, the costs probably won’t be worth the benefits.