Running Postgres 7.0.2 in a chroot environment, Linux 2.2 series, glibc

From: "Samuel Greenfeld" <Gree3776(at)rowan(dot)edu>
To: <pgsql-admin(at)postgresql(dot)org>
Subject: Running Postgres 7.0.2 in a chroot environment, Linux 2.2 series, glibc
Date: 2000-07-11 02:10:30
Message-ID: s96a49db.057@groupwise.rowan.edu
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-admin


I have been trying to put postgres into its own changed root (chroot) environment for security purposes. However, it has been fighting me tooth and nail over this. I would be curious to know if such a move is actually possible, since I have had no trouble getting most other applications to run in such a situation.

I first compiled postgres into /usr/local/pgsql on the main filesystem. I then copied this directory to /jail1/usr/local/pgsql. My intentions were to use chroot so anything started via it in /jail1 can not leave this directory. This is done my making /jail1 the root directory, so /jail1/usr becomes /usr, etc. I did some work with ldconfig and strace to hunt down all the needed libraries, set up the base directories (/usr, /etc, /lib, /tmp, /var, etc.) and I thought this would be it. /dev/zero,null, and log were provided in case postgres wanted them. For most applications, this would be all I needed. Unfortunately, luck would not make things this easy.

First, I tried creating the initial database using the initdb command. This was found to be a shell script, so I copied in the shell and its support utilities (really, all the things you do not want in a chroot environment), su'ed to postgres and made the database. I then tried starting up postmaster from the shell I did not want to have in that environment once postgres was formally running. Postgres worked fine. So I shut down postmaster, and tried starting it up via the chroot command. Postgres muttered (and rightfully so) that I should not run it as root, but the chroot command needs root access, so this startup attempt failed.

I wrote a shell script that temporarily set postmaster to be a set uid/gid program owned by the postgres user, set PGDATA, PATH, etc., appropriately, and ran postmaster in the chroot environment, but postgres still thought it was run root. This kind of made sense (it was checking its real uid as opposed to the effective one). It also meant I could not write another setuid program that called postgres, since it would still think it was run as root. For lack of another option, I decided to let su function in the chrooted area. However, it only can start an executable without giving it parameters (if you give it a -c, it tries to run "/bin/sh -c", and that is what we're trying to avoid having nearby postgres - a shell).

So I wrote a short c program to start postgres and hand it all of its parameters (see below). This would be called as the "shell" via su in the chroot environment. I know I'm getting technical here - basically, I ran "chroot /jail1 su postgres -s /bin/postgres_start" where /jail1 is the directory I'm setting as root, and /jail1/bin/postgres_start (no, that's not a typo - that's its full path) is the program I wrote to start the postmaster. This led to an error message that said that postmaster could not access the database postgres. This seemed strange, as using the non chrooted postgres (/usr/local/pgsql/bin/postmaster -D /jail1/home/postgres/data ) worked to start the postmaster, as well as using a postmaster started from a chrooted shell ("chroot /jail1 su postgres -s /bin/sh" then "/usr/local/pgsql/bin/postmaster -D /home/postgres/data"). Starting up a shell in the chroot environment, su'ing to postgres, and starting up postmaster (which worked, but required the unwanted shell), I ran createdb to make a database called postgres just to see what would happen.

Low and behold, using chroot, su, and my calling program, postgres dumped me to a backend prompt (see capture below). This prompt does not seem to be the same as the normal SQL one. It did not seem to know the help commands. I do not see it documented anywhere, so I am quite confused as to what I found.

I apologize for the long email, but I would like to run postgres in an environment where it is isolated from the other programs on the system. I intended to use the "-i" option so programs outside of its jail could access it But right now I just need a good way to get it started on its own where it is restricted to the /jail1 directory.

So, short of hacking out the security checks in postgres so chroot will run properly, does anyone have a good idea how to do this? I know most administrators do not bother to use the chroot command, but that is standard practice here.

Sincerely,
Samuel Greenfeld

postgres_start.c: (see "man 2 execve" if you have it)
#include<unistd.h>

int main() {

char *envr[3];
char *argv[2];

envr[0]= "PATH=/usr/bin:/bin:/usr/local/pgsql/bin:.";
envr[1]= "PGDATA=/home/postgres/data";
envr[2]= NULL;

argv[0]= "-i";
argv[1]= NULL;

execve ("/usr/local/pgsql/bin/postmaster", argv, envr);
return 0;

}

Command run: "chroot /jail1 su postgres -s /bin/postgres_start"
The result:
DEBUG: Data Base System is starting up at Mon Jul 10 21:58:14 2000
DEBUG: Data Base System was shut down at Mon Jul 10 20:55:01 2000
DEBUG: Data Base System is in production state at Mon Jul 10 21:58:14 2000

POSTGRES backend interactive interface
$Revision: 1.155 $ $Date: 2000/05/21 02:23:30 $

backend> \h
ERROR: parser: parse error at or near "\"
ERROR: parser: parse error at or near "\"
backend>

/etc/passwd and /jail/etc/passwd line for postgres:
postgres:x:70:70:Postgres Daemon:/home/postgres:/bin/postgres_start
(account is disabled in /etc/shadow)

Browse pgsql-admin by date

  From Date Subject
Next Message Jochen Topf 2000-07-11 07:01:01 Re: Running Postgres 7.0.2 in a chroot environment
Previous Message XWorkers 2000-07-11 01:55:25 Replication