Discussion:
cgi with chroot
prad
2006-05-30 22:34:00 UTC
Permalink
i'm using php right now and things are fine.
however, after reading various threads on the (recommended by several people
here) MARC (http://marc.theaimsgroup.com/?l=openbsd-misc) list, i was curious
about learning some new things like:

cgi
fastcgi
lighttpd
ruby

which came up in the discussions.

i tried to got a ksh script to work after i copied the ksh into /var/www/bin
my understanding is that the chrooted environment doesn't give access to
the /bin/ksh program.

i tried the same thing with python, but kept getting
Internal Server Error on the browser

and the following in the error_log:
No such file or directory: exec of /htdocs/z/jonpy1.cgi failed
Premature end of script headers: /htdocs/z/jonpy1.cgi

i tried the same thing with ruby (copied both ruby and erb into /var/www/bin)
and got the same thing again.

so is there something else i need to do to get cgi working in openbsd's
chrooted environment?

(also, lighttpd looks really neat and clean, but i don't think it runs
chrooted by default, right? (it's .conf file is in /etc) so to get it to do
that would require understanding just what the chrooted process involves,
which i can find from the web.)
--
In friendship,
prad

... with you on your journey
Towards Freedom
http://www.towardsfreedom.com (website)
Information, Inspiration, Imagination - truly a site for soaring I's
Jacob Yocom-Piatt
2006-05-30 23:09:35 UTC
Permalink
---- Original message ----
Date: Tue, 30 May 2006 15:34:00 -0700
Subject: cgi with chroot
i'm using php right now and things are fine.
however, after reading various threads on the (recommended by several people
here) MARC (http://marc.theaimsgroup.com/?l=openbsd-misc) list, i was curious
cgi
fastcgi
lighttpd
ruby
which came up in the discussions.
i tried to got a ksh script to work after i copied the ksh into /var/www/bin
my understanding is that the chrooted environment doesn't give access to
the /bin/ksh program.
this seems like it could be a security worry, but i'm not qualified to say that
with certainty.
i tried the same thing with python, but kept getting
Internal Server Error on the browser
No such file or directory: exec of /htdocs/z/jonpy1.cgi failed
Premature end of script headers: /htdocs/z/jonpy1.cgi
i tried the same thing with ruby (copied both ruby and erb into /var/www/bin)
and got the same thing again.
so is there something else i need to do to get cgi working in openbsd's
chrooted environment?
man ldd. it will tell you which, if any, dynamic libraries you need in your chroot.
(also, lighttpd looks really neat and clean, but i don't think it runs
chrooted by default, right? (it's .conf file is in /etc) so to get it to do
that would require understanding just what the chrooted process involves,
which i can find from the web.)
--
In friendship,
prad
... with you on your journey
Towards Freedom
http://www.towardsfreedom.com (website)
Information, Inspiration, Imagination - truly a site for soaring I's
prad
2006-05-31 00:20:30 UTC
Permalink
Post by Jacob Yocom-Piatt
---- Original message ----
man ldd. it will tell you which, if any, dynamic libraries you need in your chroot.
thank jacob. it certainly seems like a good idea!

ldd /usr/local/bin/ruby gave

Start End Type Open Ref GrpRef Name
00000000 00000000 exe 1 0 0 /usr/local/bin/ruby
0e71b000 2e749000 rlib 0 1 0 /usr/local/lib/libruby.so.1.84
03e03000 23e0a000 rlib 0 2 0 /usr/lib/libm.so.2.1
08573000 285a4000 rlib 0 1 0 /usr/lib/libc.so.39.0
0e0c0000 0e0c0000 rtld 0 1 0 /usr/libexec/ld.so

so i copied them appropriately into a usr dir under /var/www

i have mod_ruby and the appropriate changes in the httpd.conf file.

but still no go :(

actually, i'm puzzled suddenly by all this.
php sits in /usr/local/bin - yet it runs find having just the php.ini file
inside the chroot environment. may be that file may give some clues as to how
this was done for php and may point the way for ruby.
--
In friendship,
prad

... with you on your journey
Towards Freedom
http://www.towardsfreedom.com (website)
Information, Inspiration, Imagination - truly a site for soaring I's
Adam
2006-05-31 00:47:11 UTC
Permalink
Post by prad
i have mod_ruby and the appropriate changes in the httpd.conf file.
You are going to need to copy the entire ruby module directory. I think
that that is all you will need, since the other libs should be loaded
when mod_ruby is loaded (when apache first starts, before chrooting).
Mod_ruby, mod_perl, etc aren't designed with chrooted apache in mind.
If you want to use cgi, then you need the ruby interpreter itself and
all the libs, and all the modules.
Post by prad
php sits in /usr/local/bin - yet it runs find having just the php.ini file
inside the chroot environment. may be that file may give some clues as to how
this was done for php and may point the way for ruby.
The php binary isn't involved, its the PHP apache module that is used.
And it does need its modules in the chroot too, see /var/www/lib/php.

Adam
Adam
2006-05-31 00:51:15 UTC
Permalink
Post by prad
(also, lighttpd looks really neat and clean, but i don't think it runs
chrooted by default, right? (it's .conf file is in /etc) so to get it to do
that would require understanding just what the chrooted process involves,
which i can find from the web.)
It can run chrooted if you want. I'm not sure I would trust it though,
its had some really dumb security problems in the past, and they haven't
been particularly upfront about it. Just sticking "secure" in the list
of design goals doesn't mean anything.

Adam
Marcus Glocker
2006-05-31 04:10:13 UTC
Permalink
Post by prad
i'm using php right now and things are fine.
however, after reading various threads on the (recommended by several people
here) MARC (http://marc.theaimsgroup.com/?l=openbsd-misc) list, i was curious
cgi
fastcgi
lighttpd
ruby
which came up in the discussions.
i tried to got a ksh script to work after i copied the ksh into /var/www/bin
my understanding is that the chrooted environment doesn't give access to
the /bin/ksh program.
i tried the same thing with python, but kept getting
Internal Server Error on the browser
No such file or directory: exec of /htdocs/z/jonpy1.cgi failed
Premature end of script headers: /htdocs/z/jonpy1.cgi
i tried the same thing with ruby (copied both ruby and erb into /var/www/bin)
and got the same thing again.
so is there something else i need to do to get cgi working in openbsd's
chrooted environment?
(also, lighttpd looks really neat and clean, but i don't think it runs
chrooted by default, right? (it's .conf file is in /etc) so to get it to do
that would require understanding just what the chrooted process involves,
which i can find from the web.)
Hello prad,

Of course if you run a webserver chrooted you have to care that all
library and stuff a program (in that case a CGI) needs, are
accessibly withing the chrooted environment. But you already got
that tip.

The error message you get "Premature end of script headers" means
that the HTTP header generated by your CGI is not correct. You need
at least to tell the webserver what content type your CGI generates
before sending any further data. For example in a sh script:

#!/bin/sh

echo "Content-Type: text/html"
echo ""
echo "I'm sorry Dave, I'm afraid I can't do that."

The empty echo represents a second \n which signals the end of
a HTTP header.

Regards,
Marcus
--
Marcus Glocker, ***@nazgul.ch, http://www.nazgul.ch -----------------
Marcus Glocker
2006-05-31 04:13:12 UTC
Permalink
Post by Marcus Glocker
Hello prad,
Of course if you run a webserver chrooted you have to care that all
library and stuff a program (in that case a CGI) needs, are
accessibly withing the chrooted environment. But you already got
that tip.
The error message you get "Premature end of script headers" means
that the HTTP header generated by your CGI is not correct. You need
at least to tell the webserver what content type your CGI generates
#!/bin/sh
echo "Content-Type: text/html"
echo ""
echo "I'm sorry Dave, I'm afraid I can't do that."
Oh, for that example "Content-Type: text/plain" would be correct :)
--
Marcus Glocker, ***@nazgul.ch, http://www.nazgul.ch -----------------
Adam
2006-05-31 04:38:10 UTC
Permalink
Post by Marcus Glocker
#!/bin/sh
echo "Content-Type: text/html"
echo ""
echo "I'm sorry Dave, I'm afraid I can't do that."
HTTP headers are terminated by "\r\n" not "\n".

Adam
Marcus Glocker
2006-05-31 04:58:51 UTC
Permalink
Post by Adam
Post by Marcus Glocker
#!/bin/sh
echo "Content-Type: text/html"
echo ""
echo "I'm sorry Dave, I'm afraid I can't do that."
HTTP headers are terminated by "\r\n" not "\n".
Yes, correctly HTTP headers are terminated by "\r\n". But most
webservers also understand "\n" in case of a CGI header. And this
example generates "\n" not "\r\n":

0000000 C o n t e n t - T y p e : t e
0000010 x t / p l a i n \n \n I ' m s o
0000020 r r y D a v e , I ' m a f
0000030 r a i d I c a n ' t d o
0000040 t h a t . \n
0000046

Have a nice day.
--
Marcus Glocker, ***@nazgul.ch, http://www.nazgul.ch -----------------
Adam
2006-05-31 16:07:16 UTC
Permalink
Post by Marcus Glocker
Post by Adam
Post by Marcus Glocker
#!/bin/sh
echo "Content-Type: text/html"
echo ""
echo "I'm sorry Dave, I'm afraid I can't do that."
HTTP headers are terminated by "\r\n" not "\n".
Yes, correctly HTTP headers are terminated by "\r\n". But most
webservers also understand "\n" in case of a CGI header. And this
I know that example generates "\n" instead of "\r\n", that's why I said
its wrong. Just because apache will fix your incorrect output, doesn't
mean you should go ahead and write CGIs that way and rely on webservers
to fix it for you. Not all of them will, and there's no benefit from
doing it wrong.

Adam
Marcus Glocker
2006-05-31 17:40:14 UTC
Permalink
Post by Adam
I know that example generates "\n" instead of "\r\n", that's why I said
its wrong. Just because apache will fix your incorrect output, doesn't
mean you should go ahead and write CGIs that way and rely on webservers
to fix it for you. Not all of them will, and there's no benefit from
doing it wrong.
Well, I wouldn't say that I am doing it wrong, maybe you are just a
little bit intolerant;

<snip>
RFC2616, 19.3, Tolerant Applications
...

The line terminator for message-header fields is the sequence CRLF.
However, we recommend that applications, when parsing such headers,
recognize a single LF as a line terminator and ignore the leading CR.

...
</snip>

The HTTP header termination is a empty message-header field line.

In the real world I don't know a single HTTP server which is that
intolerant, including my own webserver. My intention was to give
somebody a help and not starting an argue with you.

And before you start to offend that <snip> is not a vaild HTML tag,
I know that by myself ;)

Thread over for me.

Regards,
Marcus
--
Marcus Glocker, ***@nazgul.ch, http://www.nazgul.ch -----------------
John Draper
2006-06-14 16:16:25 UTC
Permalink
Post by Marcus Glocker
The error message you get "Premature end of script headers" means
that the HTTP header generated by your CGI is not correct. You need
at least to tell the webserver what content type your CGI generates
#!/bin/sh
echo "Content-Type: text/html"
echo ""
echo "I'm sorry Dave, I'm afraid I can't do that."
Yes - in my experience, this is prolly the cause. It usually happens
when you try to print before printing this header above.

When I write CGI's I usually break my code into sections.

* Grab any field data from the request, making sure I don't print
anything.
(I usually will store any errors I get into a string, for later
printing)

* Process the field data, and store any resulting errors into a string.

* print out the HTML response - Here is where you have to print the
"Content-Type" header...

Very often when debugging CGI's I work from the Python shell, and by
breaking
it up like this, makes it easy to debug. Run the cgi from the python
shell, and
see what you get back, should be HTML.

You wouldn't be able to process the forms data of course, but we are
just making
sure the printing part is working. Any errors you get before that part
of the code
has to be put into a error_result string, which is usually the HTML one
gets back
after submitting the form.

Sometimes when I have to "fake it", I make up a special test module and
import it
if running from the shell - it would then put "fake" form data, and
return a "cgi"
dictionary just like what you would get from the initial request.

Hope this helps - I don't know much about chrooted cgi's, because now I use
Twisted Python for my back end web processing, with my own security
systems.

John

Aiko Barz
2006-05-31 07:20:45 UTC
Permalink
Post by prad
i tried to got a ksh script to work after i copied the ksh into /var/www/bin
my understanding is that the chrooted environment doesn't give access to
the /bin/ksh program.
/var/www/bin/sh is working for me.
Post by prad
i tried the same thing with ruby (copied both ruby and erb into /var/www/bin)
and got the same thing again.
Ruby is working for me too. Check this out:

#!/bin/sh
WWW="/var/www"
# Path
[ ! -d "$WWW/bin" ] && mkdir -p $WWW/bin
[ ! -d "$WWW/usr/bin" ] && mkdir -p $WWW/usr/bin
[ ! -d "$WWW/usr/local/bin" ] && mkdir -p $WWW/usr/local/bin
[ ! -d "$WWW/usr/local/sbin" ] && mkdir -p $WWW/usr/local/sbin
[ ! -d "$WWW/usr/local/lib" ] && mkdir -p $WWW/usr/local/lib
[ ! -d "$WWW/usr/lib" ] && mkdir -p $WWW/usr/lib
[ ! -d "$WWW/var/run" ] && mkdir -p $WWW/var/run
# cp ruby
RUBY=$(which ruby)
cp -f $RUBY $WWW/$RUBY
# cp env
ENV=$(which env)
cp -f $ENV $WWW/$ENV
# Ruby stuff
rsync -va /usr/local/lib/ruby $WWW/usr/local/lib
# cp libs
for LIB in $(ldd $RUBY | awk '{if ($3 == "rlib") {print $7}}'); do
cp -f $LIB $WWW/$LIB
done
# cp hints
cp -f /var/run/ld.so.hints $WWW/var/run/ld.so.hints


I have got one more script that fixes ImageMagick which is needed by
Typo3.

Bye,
Aiko
--
Aiko Barz <***@haeckser.de>
Web: http://www.haeckser.de
prad
2006-05-31 21:28:48 UTC
Permalink
the script is great, aiko and has helped my understanding a lot (i'm trying to
learn ksh as well and it was nice to see a script like this in action!)

(also thanks to marcus (and others) for the various tips. marcus, i will
follow through on the scripting as per your suggestions, after i get the
embedded ruby with mod_ruby to work.)

i ran the script and the environment is all setup nicely.
then i went to /usr/local/share/examples/mod_ruby and got the httpd.conf
addititons (copied below) from there and put it into my httpd.conf file.

then something happens that i don't understand.

the RubyRequire apache/ruby-run
causes no problems when i start apache,

but

when i try
RubyRequire apache/eruby-run (which i need, i presume, to run the
embedded .rhtml files)
i get error messages spewed out:
[Wed May 31 14:13:04 2006] [error] mod_ruby: failed to require
apache/eruby-run
[Wed May 31 14:13:04 2006] [notice] Accept mutex: sysvsem (Default: sysvsem)
[Wed May 31 14:13:04 2006] [error] mod_ruby: failed to require
apache/eruby-run
[Wed May 31 14:13:04 2006] [error] mod_ruby: error in ruby
[Wed May 31 14:13:04 2006] [error] mod_ruby: error in ruby
[Wed May 31 14:13:04 2006] [error]
mod_ruby: /usr/local/lib/ruby/1.8/apache/eruby-run.rb:45:in `require': no
such file to load -- eruby (LoadError)

i find this weird because eruby is sitting right beside ruby in the apache
folder!!??? yet it seems that it can't be found.

finally, don't i also need a
AddType application/x-httpd-ruby .rhtml
--
In friendship,
prad

... with you on your journey
Towards Freedom
http://www.towardsfreedom.com (website)
Information, Inspiration, Imagination - truly a site for soaring I's


# You should specify the correct path to mod_ruby.so.
LoadModule ruby_module /usr/local/apache/libexec/mod_ruby.so
#####note: this needs to be /usr/lib/apache/modules/mod_ruby.so#####

# # If ClearModuleList is used in your httpd.conf, you should use AddModule
# # to activate the ruby module.
# AddModule mod_ruby.c

# If the ruby module is installed, this will be enabled.
<IfModule mod_ruby.c>
# for Apache::RubyRun
RubyRequire apache/ruby-run

# exec files under /ruby as ruby scripts.
<Location /ruby>
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance
Options +ExecCGI
</Location>

# exec *.rbx as ruby scripts.
<Files *.rbx>
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance
</Files>

# # for Apache::ERubyRun
# RubyRequire apache/eruby-run
#
# # handle files under /eruby as eRuby files by eruby.
# <Location /eruby>
# SetHandler ruby-object
# RubyHandler Apache::ERubyRun.instance
# </Location>
#
# # handle *.rhtml as eruby files.
# <Files *.rhtml>
# SetHandler ruby-object
# RubyHandler Apache::ERubyRun.instance
# </Files>

# # for Apache::ERbRun
# RubyRequire apache/erb-run
#
# # handle files under /erb as eRuby files by ERb.
# <Location /erb>
# SetHandler ruby-object
# RubyHandler Apache::ERbRun.instance
# </Location>

# # for debug
# RubyRequire auto-reload
</IfModule>
Continue reading on narkive:
Loading...