Thread: Running Postgres 7.0.2 in a chroot environment, Linux 2.2 series, glibc
Running Postgres 7.0.2 in a chroot environment, Linux 2.2 series, glibc
From
"Samuel Greenfeld"
Date:
I have been trying to put postgres into its own changed root (chroot) environment for security purposes. However, ithas been fighting me tooth and nail over this. I would be curious to know if such a move is actually possible, since Ihave 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 ldconfigand 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 copiedin the shell and its support utilities (really, all the things you do not want in a chroot environment), su'ed to postgresand made the database. I then tried starting up postmaster from the shell I did not want to have in that environmentonce postgres was formally running. Postgres worked fine. So I shut down postmaster, and tried starting itup via the chroot command. Postgres muttered (and rightfully so) that I should not run it as root, but the chroot commandneeds 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 notwrite another setuid program that called postgres, since it would still think it was run as root. For lack of anotheroption, I decided to let su function in the chrooted area. However, it only can start an executable without givingit parameters (if you give it a -c, it tries to run "/bin/sh -c", and that is what we're trying to avoid having nearbypostgres - 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 asthe "shell" via su in the chroot environment. I know I'm getting technical here - basically, I ran "chroot /jail1 supostgres -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 messagethat said that postmaster could not access the database postgres. This seemed strange, as using the non chrootedpostgres (/usr/local/pgsql/bin/postmaster -D /jail1/home/postgres/data ) worked to start the postmaster, as wellas 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 calledpostgres 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. Ido 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 otherprograms on the system. I intended to use the "-i" option so programs outside of its jail could access it But rightnow 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 howto 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)