Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

chrooted ftpd?

0 views
Skip to first unread message

der Mouse

unread,
Jun 22, 2011, 9:50:30 PM6/22/11
to
I'm trying to set up a chrooted FTP area for internal use. I'm running
into roadblock after roadblock, and have finally reached the point
where I'm beginning to wonder if I'm going about this wrong.

I started out with a chroot area with an etc/inetd.conf containing just
one line

172.16.0.1:ftp stream tcp4 nowait:120 nobody /usr/libexec/ftpd ftpd -ll -d

Then I started testing and adding things (libraries, mostly) until ftpd
started.

Next problem was that ftpd doesn't tell even the local logs why it
denies access, when it does; I had to add debugging syslog() calls to
figure that out. (Turns out an entry in ftpchroot doesn't allow access
without an entry in ftpusers too.)

Then I ran into the getusershell() idiocy. I call it idiocy because
the interface design is cripplingly broken (there's no way to tell it
"any program is allowed" or "any program in this directory is allowed"
or any such). And ftpd has no configuration knob to say "yes, dammit,
allow this user (or, shell) anyway". So I ripped that code out.

Then it exploded, logging

in openpam_configure(): No required or binding component in service ftpd, facility auth
pam_start: system error

I was unable to find any documentation on what this meant or what I
would have to copy over to fix it; in particular, openpam_configure has
no manpage. I even googled for "pam" and "chroot" in netbsd.org,
though I shouldn't have to resort to anything off-system for something
like this. It turned up nothing useful anyway.

Rather than dig through the source to find it, I took this as an excuse
to finally figure out how to make PAM go away (something I've been
meaning to do ever since I discovered 4.0.1 had had PAM inflicted on
it), dusted off an old memory that there was a way to disable PAM
entirely for the whole system, dug a bit, and added MKPAM=no to
/etc/mk.conf. Rebuild ftpd yet again. Sure enough, doesn't try to
link in PAM noww.

Then it wouldn't authenticate because it couldn't read the password
hash. So I did a chmod 644 of spwd.db and master.passwd in the chroot.
It *still* wouldn't authenticate.

Turns out getpwent() refuses to even _try_ to read spwd.db unless
geteuid() returns zero!! And, as far as I can tell, ftpd has no way to
have it use anything but getpwent() to get passwords.

I'd really really prefer to not run ftpd as root inside the chroot.
Should I just stop even trying to use NetBSD's ftpd and look for
something a bit saner, or pull out the machete and wade into ftpd?

Or am I just missing some option that should be jumping off the page at
me but isn't?

/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mo...@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-...@muc.de

Christos Zoulas

unread,
Jun 22, 2011, 11:15:01 PM6/22/11
to
In article <2011062301...@Sparkle.Rodents-Montreal.ORG>,

You are missing /etc/pam.d/ in your chroot. man pam.conf

>Then it wouldn't authenticate because it couldn't read the password
>hash. So I did a chmod 644 of spwd.db and master.passwd in the chroot.
>It *still* wouldn't authenticate.
>
>Turns out getpwent() refuses to even _try_ to read spwd.db unless
>geteuid() returns zero!! And, as far as I can tell, ftpd has no way to
>have it use anything but getpwent() to get passwords.

I think this can be argued to be a bug, but I bet it is there to protect
the user.

>I'd really really prefer to not run ftpd as root inside the chroot.
>Should I just stop even trying to use NetBSD's ftpd and look for
>something a bit saner, or pull out the machete and wade into ftpd?

Unfortunately ftpd is designed to run as root. But if you make getpwent()
to be able to read spwd.db for non-root users, it will probably work.

christos

der Mouse

unread,
Jun 22, 2011, 11:59:34 PM6/22/11
to
>> Turns out getpwent() refuses to even _try_ to read spwd.db unless
>> geteuid() returns zero!! And, as far as I can tell, ftpd has no way
>> to have it use anything but getpwent() to get passwords.
> I think this can be argued to be a bug, but I bet it is there to
> protect the user.

Are you talking about getpwent or ftpd? If the latter, I disagree; I
can't see how an inability to configure any other way to get passwords
protects anyone against anything. If the former, I might agree, given
a threat that this would defeat, but I haven't managed to come up with
any; it's not as if it'd be hard to read spwd.db directly if it somehow
accidentally became world-readable on an ordinary system.

> But if you make getpwent() to be able to read spwd.db for non-root
> users, it will probably work.

Turns out it's easier than that.

Reading the code for getpwent(), it became apparent that the only
difference between pwd.db and spwd.db is the contents - the structure
is identical. So I just did "chmod 644 /ftp/etc/spwd.db" and then
"mv /ftp/etc/spwd.db /ftp/etc/pwd.db" and ftpd got hashes.

Hmm, I wonder if making ftpd provide its own geteuid() would work.
(Maybe, but that would make the ftpd binary unsuitable for
general-purpose use; I'd rather avoid that too, if I can.)

/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mo...@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--

Thor Lancelot Simon

unread,
Jun 23, 2011, 8:00:25 AM6/23/11
to
On Thu, Jun 23, 2011 at 03:15:01AM +0000, Christos Zoulas wrote:
> >
> >Turns out getpwent() refuses to even _try_ to read spwd.db unless
> >geteuid() returns zero!! And, as far as I can tell, ftpd has no way to
> >have it use anything but getpwent() to get passwords.
>
> I think this can be argued to be a bug, but I bet it is there to protect
> the user.

It's a bug. It would break the chroot environments on our own servers
in many cases if this version of the code were deployed there.

Thor

Zafer Aydoğan

unread,
Jun 23, 2011, 2:39:50 PM6/23/11
to
2011/6/23 der Mouse <mo...@rodents-montreal.org>:

I like pure-ftpd. Small, secure, easy and powerful.
You can have virtual users (non-system users) only for ftp
and you can chroot them all. (In this case not the application is
chrooted, but the users when logged in.)
Works fine, and can do stuff like throttling and ip denying, etc, etc.

Zafer.

David Holland

unread,
Jun 23, 2011, 2:51:58 PM6/23/11
to
On Wed, Jun 22, 2011 at 09:50:30PM -0400, der Mouse wrote:
> I'm trying to set up a chrooted FTP area for internal use. I'm running
> into roadblock after roadblock, and have finally reached the point
> where I'm beginning to wonder if I'm going about this wrong.
> [...]

As Christos pointed out, the traditional ftp is intended to run as
root so it can itself do chroot() calls. Otherwise, ftpchroot isn't
going to accomplish much.

> (Turns out an entry in ftpchroot doesn't allow access
> without an entry in ftpusers too.)

That sounds like a condition that should be logged, because it's a
config error. But probably it never gets as far as even opening
ftpchroot.

> Then it wouldn't authenticate because it couldn't read the password
> hash. So I did a chmod 644 of spwd.db and master.passwd in the chroot.
> It *still* wouldn't authenticate.
>
> Turns out getpwent() refuses to even _try_ to read spwd.db unless
> geteuid() returns zero!! And, as far as I can tell, ftpd has no way to
> have it use anything but getpwent() to get passwords.

I expect the intent was to protect fools who write their own code
using getpwent, run it unprivileged, and try to chmod 644 to make it
work without thought for the consequences. Seems misguided though as
that grade of fool will just do chmod +s instead.

You might be able to use nsswitch.conf to have it get passwords from
elsewhere, although I don't think there any of the currently supported
alternate methods are simple.

--
David A. Holland
dhol...@netbsd.org

David Holland

unread,
Jun 23, 2011, 2:52:28 PM6/23/11
to
On Thu, Jun 23, 2011 at 06:51:58PM +0000, David Holland wrote:
> As Christos pointed out, the traditional ftp is intended to run as
^d

der Mouse

unread,
Jun 23, 2011, 3:08:09 PM6/23/11
to
> As Christos pointed out, the traditional ftp is intended to run as
> root so it can itself do chroot() calls. Otherwise, ftpchroot isn't
> going to accomplish much.

Yeah, I came to that conclusion myself. I added code so that it
doesn't bother doing the chroot call if the string that would be passed
to it is "/", so it doesn't get gratuitous errors, but that's a frill.

For my purposes I abandoned making the user a chroot user.

>> (Turns out an entry in ftpchroot doesn't allow access without an
>> entry in ftpusers too.)
> That sounds like a condition that should be logged, because it's a
> config error. But probably it never gets as far as even opening
> ftpchroot.

I'm not sure - I no longer have the trace file - but I think ktrace
said it did.

>> Turns out getpwent() refuses to even _try_ to read spwd.db unless
>> geteuid() returns zero!!

> I expect the intent was to protect fools who write their own code
> using getpwent, run it unprivileged, and try to chmod 644 to make it
> work without thought for the consequences.

Hm, possibly. It's the first scenario I've seen mentioned where that
bit of code actually protects against something.

> Seems misguided though as that grade of fool will just do chmod +s
> instead.

True, but then the attacker is restricted to finding holes in said
fool's code, rather than being able to just waltz off with a copy of
spwd.db. (Admittedly, finding holes in code written by that grade of
fool is probably about as difficult as copying a mode 644 file.)

> You might be able to use nsswitch.conf to have it get passwords from
> elsewhere, although I don't think there any of the currently
> supported alternate methods are simple.

Possibly. But, as I think I mentioned upthread, I realized on reading
the code that spwd.db and pwd.db have the same structure - the code to
read the db doesn't know or care which it's reading - so I just renamed
spwd.db to pwd.db and made it mode 644. It's an additional step every
time something needs to change the ftp root's master.passwd, but that's
acceptable in this case.

/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mo...@rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--

0 new messages