# Firefox inside a  CHROOT JAIL

## Barabbas

I am running Gentoo hardened ~amd64 and am trying to build a minimal functional chroot jail for firefox.I already tried running it inside a VM, and a stage3 chroot jail, it works, but IMHO seems a bit like an overkill.

I was following some related HOWTO's on doing this and I tried to build the chroot environment the usual way, manually:

(replicate the basic fs layout,chroot inside, run -> strace -> grep for files -> cp required bins/libs/conf files -> repeat until not crashes)

and it has proven to be a nightmare, there are just way to many files to be included in the layout (but, i straced most of them and it runs, barely -> crashes,needz more filez  :Rolling Eyes:  ).

I was thinking of a more KISS approach, maybe:

1 replicate the basic fs layout, mount dev and proc,cp /etc/resolv.conf

2 install only the apsolute most basic system tools + portage with deps + some shell

3 chroot inside, emerge firefox

4 unmerge bloat (shell, system tools,everything)

5 delete whatever cannot be unmerged (if anything)

The problem is, i dont know what are the dependencies for portage. There are no stage1 and stage2 archives any more and stage3 has got too much stuff inside. Should I emerge firefox in stage3, then simply unmerge system (well whatever's not a firefox dependecy) or the opposite, start blank and build the environment myself?

Does anyone have any ideas? Some help or tutorial on builing chroot jails, please?  :Confused: 

----------

## Bones McCracker

Another alternative is to use lxc (linux containers), but instead of providing it with a whole "stage 3" of its own, just read-only-bind-mount your regular filesystem to the container's filesystem.  There will be some files that might be unique to the container, and some directories that firefox will need to be able to write to; these you can simply create somewhere else and mount over the non-writable bind-mounted filesystem.

This way, you have complete isolation (better than chroot) with all the power of namespaces, cgroups, and so on.  But, you don't have the headache of having to maintain an entirely separate filesystem for the virtual machine.

The down side is that linux containers is pretty much beta-ware, and you'd have to learn about it.

Here is an example lxc configuration (you could also do the equivalent with just a chroot, although it won't be as effectively isolated).  The main take-away here is not that you should be able to use this file; it's that you should have an idea that it's possible to reuse most (or some) of the host's actual files inside your container (or inside your chroot) by bind-mounting them read-only.  Since bind-mounting an entire partition or directory is a lower-overhead option to copying even one file, this technique might also resolve your problem on having to copy so many files over (i.e. just bind-mount everything, and remount it read-only, then add whatever writable and unique files you need.

This one happened to be for running an ftp and ssh server, but the same concept applies with slight alternations to what you are mounting.

```
# /etc/lxc/beta/config

# hostname for virtual private server

lxc.utsname = beta

# network configuration

lxc.network.type = veth

lxc.network.flags = up

lxc.network.link = br0

lxc.network.hwaddr = b6:67:82:92:ca:a0

lxc.network.ipv4 = 0.0.0.0

# pseudo-filesystems to be created and isolated in the container

lxc.mount.entry = none /srv/lxc/beta/proc proc defaults 0 0

#lxc.mount.entry = none /srv/lxc/beta/sys sysfs defaults 0 0

lxc.mount.entry = none /srv/lxc/beta/dev/pts devpts defaults 0 0

lxc.mount.entry = none /srv/lxc/beta/dev/shm tmpfs defaults 0 0

lxc.mount.entry = none /srv/lxc/beta/var/run tmpfs defaults 0 0

# files to be reused from host system (read-only bind mounts)

lxc.mount.entry = /bin /srv/lxc/beta/bin none ro,bind 0 0

lxc.mount.entry = /etc /srv/lxc/beta/etc none ro,bind 0 0

lxc.mount.entry = /lib /srv/lxc/beta/lib none ro,bind 0 0

lxc.mount.entry = /sbin /srv/lxc/beta/sbin none ro,bind 0 0

lxc.mount.entry = /usr /srv/lxc/beta/usr none ro,bind 0 0

# files unique to container, overlayed on the bind-mounts from host (some ro, some rw)

lxc.mount.entry = /etc/lxc/beta/sbin/init /srv/lxc/beta/sbin/init none ro,bind 0 0

lxc.mount.entry = /etc/lxc/beta/etc/ssh /srv/lxc/beta/etc/ssh none ro,bind 0 0

lxc.mount.entry = /etc/lxc/beta/etc/vsftpd /srv/lxc/beta/etc/vsftpd none ro,bind 0 0

lxc.mount.entry = /etc/lxc/beta/etc/resolv.conf /srv/lxc/beta/etc/resolv.conf none bind 0 0

#lxc.mount.entry = /etc/lxc/beta/etc/mtab /srv/lxc/beta/etc/mtab none bind 0 0

lxc.rootfs = /srv/lxc/beta

lxc.pts = 128

lxc.cgroup.cpu.shares = 512

lxc.cgroup.devices.deny = a

lxc.cgroup.devices.allow = c 1:3 rw

lxc.cgroup.devices.allow = c 1:9 rw

lxc.cgroup.devices.allow = c 5:2 rw

lxc.cgroup.devices.allow = c 136:* rw

#lxc.cgroup.devices.allow = b 8:0 rw

#lxc.cap.drop = <capabilities to drop>
```

----------

## depontius

 *BoneKracker wrote:*   

> Another alternative is to use lxc (linux containers), but instead of providing it with a whole "stage 3" of its own, just read-only-bind-mount your regular filesystem to the container's filesystem.

 

Do read-only bind-mounts work, finally?  I've been wanting them for a while, pretty much for the same reason as you.  I tried it a year or so back, but found that making the bind-mount ro made the parent filesystem ro as well.  Are any special kernel config options necessary?  I guess I can just try this, but if you have more information about this, I'd like to hear it.  A few years back I contacted a kernel developer in my company, found out that he'd done some work on ro bind-mounts, and prodded him to submit his patches again.  They were rejected because while the kernel masters weren't against the general idea, they wanted it done deeper in the VFS system.  I've kept an occasional eye on lkml and changelogs, but hadn't seen that the concept ever got accepted.

----------

## Bones McCracker

 *depontius wrote:*   

>  *BoneKracker wrote:*   Another alternative is to use lxc (linux containers), but instead of providing it with a whole "stage 3" of its own, just read-only-bind-mount your regular filesystem to the container's filesystem. 
> 
> Do read-only bind-mounts work, finally?  I've been wanting them for a while, pretty much for the same reason as you.  I tried it a year or so back, but found that making the bind-mount ro made the parent filesystem ro as well.  Are any special kernel config options necessary?  I guess I can just try this, but if you have more information about this, I'd like to hear it.  A few years back I contacted a kernel developer in my company, found out that he'd done some work on ro bind-mounts, and prodded him to submit his patches again.  They were rejected because while the kernel masters weren't against the general idea, they wanted it done deeper in the VFS system.  I've kept an occasional eye on lkml and changelogs, but hadn't seen that the concept ever got accepted.

 

You are correct, to an extent.

You can't do:

```
mount --bind -o ro' /foo /bar
```

The explanation is that a '--bind' mount mirrors the mount options of the original (it uses the same -o options).  To make matters worse, the the read-only option used to (2008) fail silently, leaving your bind mount marked read-only in mtab, but completely writable.

As I understand it, the temporary "fix" (2009) for this (in util-linux) is that the above command will still "succeed" (exit 0), but /bar will be correctly marked as 'rw' in mtab, and a warning will be returned:

```
mount: warning: /bar seems to be mounted read-write.
```

However, one can pretty easily work around the problem like so:

```
mount --bind /foo /bar

mount -o remount,ro /bar
```

And no, this does not make /foo read-only.  (If that was once the case, I suppose it must have been fixed along with the above, around 2009.)

However, the requirement for doing this a two-step operation does not exist with linux containers (lxc), because I submitted a bug pointing out that it was not possible to create read-only bind mounts in a single lxc.mount.option entry (which are fstab-like entries in an lxc container's config file).  Iit works there, as shown in my example above.

Based on what little I know and what you've said, it sounds to me like the util-linux (mount) developers decided to wait for a fix at the linux-vfs level rather than alter the 'mount' command to call itself recursively to handle -o options when given along with the --bind option, whereas the lxc developers decided to go ahead and do that, in their handler for the fstab-like entries in lxc configuration files.

What I have not myself tried in implementing a read-only bind mount outside of lxc by way of a regular linux fstab entry (which might be useful for a chroot that used every time a machine runs).  I imagine that it might be possible using two entries that mirror the two mount commands necessary at the command line, but I haven't tried it.  Nevertheless, if you are writing a script to activate your chroot, this is kind of irrelevant, because you can simply use the two-command work-around.

Please do play around with it, and let me know if I'm wrong about this.

----------

## depontius

I'll give that a pop.  One spot in particular I'm curious about is the chroot option for bind.  In the older versions it would copy everything to the chroot.  The newest version copies chroot basics, but bind-mounts the zone directories and the named.conf directory.  It's better in that there aren't two copies to get out-of-sync, but they're now exposed.  I need to look in the init script and see if I can do your two-step process there - then submit it as a bug.

----------

## Bones McCracker

 *depontius wrote:*   

> I'll give that a pop.  One spot in particular I'm curious about is the chroot option for bind.  In the older versions it would copy everything to the chroot.  The newest version copies chroot basics, but bind-mounts the zone directories and the named.conf directory.  It's better in that there aren't two copies to get out-of-sync, but they're now exposed.  I need to look in the init script and see if I can do your two-step process there - then submit it as a bug.

 

You confused me for a minute by talking about bind (as in "bin d") when we had been talking about 'mount --bind'.  I was like, "chroot options for bind"... wtf?   :Laughing: 

----------

## depontius

Bind, as in the nameserver.  It offers an option to run in a chroot.  Withe new newest Gentoo release, then you run bind in a chroot, by default it bind-mounts the configuration and zone directories out of /etc and /var into the chroot.  I'd feel safer with ro bind-mounts, using your 2-step process.  I just checked, and it's in the init script in plain text.

----------

## Bones McCracker

 *depontius wrote:*   

> Bind, as in the nameserver.  It offers an option to run in a chroot.  Withe new newest Gentoo release, then you run bind in a chroot, by default it bind-mounts the configuration and zone directories out of /etc and /var into the chroot.  I'd feel safer with ro bind-mounts, using your 2-step process.  I just checked, and it's in the init script in plain text.

 

Yes, I'm familiar with bind, I just didn't realize that's what you were talking about and was momentarily confused.  I referred to it as "bin d" because that's how it's pronounced (like "bin dee"), unlike the the "bind" option to mount.  And, I found this humorous enough to mention, which may have been a mistake.

Since it's carrying out the mount options in the initscript, I suppose you could then simply back up the initscript and modify it to test the idea.  And if it works, you could submit a proposed patch along with your bug.  If there is a reason people would not want those files to be read-only in the chroot, you could make it optional (controlled by a switch in /etc/conf.d/bind).

----------

## depontius

 *BoneKracker wrote:*   

> I referred to it as "bin d" because that's how it's pronounced (like "bin dee"), unlike the the "bind" option to mount.

 

I never knew that.  Or as my mother likes to say, "You learn something new every day."

----------

