We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Use AsciiDoc to generate pretty HTML documentation from .txt.
Hongli Lai (Phusion) (author)
Tue Feb 26 10:17:23 -0800 2008
commit  13896a1a6b77e69382a48b3c91d20d53d26579db
tree    3f378a4a1f11ab703a43e9644b8b73d9a77d164f
parent  1c13adf90e40ffd9145a5cb6f2877989ff659b61
...
12
13
14
 
15
16
17
...
12
13
14
15
16
17
18
0
@@ -12,6 +12,7 @@ ext/mod_rails/Makefile
0
 ext/boost/src/*.a
0
 doc/rdoc
0
 doc/cxxapi
0
+doc/*.html
0
 test/Apache2ModuleTests
0
 test/config.yml
0
 test/stub/railsapp/log/*
0
...
122
123
124
125
 
126
 
127
128
129
...
122
123
124
 
125
126
127
128
129
130
0
@@ -122,8 +122,9 @@ The following software is optional:
0
 
0
 * RDoc, for generating HTML Ruby API documentation
0
 * Doxygen, for generating HTML C++ API documentation
0
-* dot, for generating diagrams in HTML API documentation
0
+* dot (part of Graphviz), for generating diagrams in HTML API documentation
0
 * The font "Bitstream Vera Sans", used in the class diagrams. See http://www.gnome.org/fonts
0
+* AsciiDoc >= 8.2.5, for converting various doc/*.txt documents to HTML
0
 
0
 === Compilation, unit tests and other tasks
0
 
...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
249
250
251
252
253
254
 
 
255
256
257
258
259
260
261
 
 
262
263
264
265
 
 
 
 
 
 
 
 
 
266
267
268
...
322
323
324
325
326
327
 
 
 
 
328
329
330
...
232
233
234
 
 
 
 
 
 
 
 
 
 
 
 
 
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
 
252
 
 
 
253
254
255
256
 
257
 
 
 
258
259
260
261
262
 
263
264
265
266
267
268
269
270
271
272
273
274
...
328
329
330
 
 
 
331
332
333
334
335
336
337
0
@@ -232,37 +232,43 @@ end
0
 
0
 ##### Documentation
0
 
0
-Rake::RDocTask.new do |rd|
0
- rd.main = "README"
0
- rd.rdoc_dir = "doc/rdoc"
0
- rd.rdoc_files.include("README", "lib/mod_rails/*.rb", "lib/rake/extensions.rb", "ext/mod_rails/*.c")
0
- rd.template = "./doc/template/horo"
0
- rd.title = "Passenger Ruby API"
0
- rd.options << "-S" << "-N" << "-p" << "-d"
0
-end
0
-
0
-desc "Generate Doxygen C++ API documentation if necessary"
0
-task :doxygen => ['doc/cxxapi']
0
-file 'doc/cxxapi' => Dir['ext/apache2/*.{h,c,cpp}'] do
0
- Dir.chdir('doc') do
0
+subdir 'doc' do
0
+ desc "Generate all documentation"
0
+ task :doc => [:rdoc, :doxygen, 'Security of user switching support.txt']
0
+
0
+ file 'Security of user switching support.txt' do
0
+ sh "asciidoc -a toc -a numbered -a toclevels=3 'Security of user switching support.txt'"
0
+ end
0
+
0
+ task :clobber => [:'doxygen:clobber'] do
0
+ sh "rm -f *.html"
0
+ end
0
+
0
+ desc "Generate Doxygen C++ API documentation if necessary"
0
+ task :doxygen => ['cxxapi']
0
+ file 'cxxapi' => Dir['../ext/apache2/*.{h,c,cpp}'] do
0
     sh "doxygen"
0
   end
0
-end
0
 
0
-desc "Force generation of Doxygen C++ API documentation"
0
-task 'doxygen:force' do
0
- Dir.chdir('doc') do
0
+ desc "Force generation of Doxygen C++ API documentation"
0
+ task :'doxygen:force' do
0
     sh "doxygen"
0
   end
0
-end
0
 
0
-desc "Remove generated Doxygen C++ API documentation"
0
-task 'doxygen:clobber' do
0
- Dir.chdir('doc') do
0
+ desc "Remove generated Doxygen C++ API documentation"
0
+ task :'doxygen:clobber' do
0
     sh "rm -rf cxxapi"
0
   end
0
 end
0
-task :clobber => 'doxygen:clobber'
0
+
0
+Rake::RDocTask.new do |rd|
0
+ rd.main = "README"
0
+ rd.rdoc_dir = "doc/rdoc"
0
+ rd.rdoc_files.include("README", "lib/mod_rails/*.rb", "lib/rake/extensions.rb", "ext/mod_rails/*.c")
0
+ rd.template = "./doc/template/horo"
0
+ rd.title = "Passenger Ruby API"
0
+ rd.options << "-S" << "-N" << "-p" << "-d"
0
+end
0
 
0
 
0
 ##### Gem
0
@@ -322,9 +328,10 @@ Rake::GemPackageTask.new(spec) do |pkg|
0
   pkg.need_tar_gz = true
0
 end
0
 
0
-Rake::Task['package'].prerequisites.push('rdoc', 'doxygen')
0
-Rake::Task['package:gem'].prerequisites.push('rdoc', 'doxygen')
0
-Rake::Task['package:force'].prerequisites.push('rdoc', 'doxygen')
0
+Rake::Task['package'].prerequisites.push(:doc)
0
+Rake::Task['package:gem'].prerequisites.push(:doc)
0
+Rake::Task['package:force'].prerequisites.push(:doc)
0
+task :clobber => :'package:clean'
0
 
0
 
0
 ##### Misc
...
1
 
 
2
3
4
5
 
 
6
7
8
...
23
24
25
26
27
 
 
28
29
30
...
40
41
42
43
44
 
 
 
45
46
47
48
49
50
51
52
53
54
55
 
 
 
 
 
 
56
57
58
...
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 
 
 
 
 
 
 
 
 
 
 
 
82
83
84
...
89
90
91
 
92
93
94
...
111
112
113
114
115
 
 
 
116
117
118
...
120
121
122
123
 
124
125
126
...
132
133
134
135
136
 
 
137
138
139
140
141
 
 
142
143
144
...
150
151
152
153
 
154
155
156
157
158
 
 
159
160
161
...
169
170
171
172
173
 
 
174
175
176
177
178
179
180
181
 
 
 
182
183
184
...
 
1
2
3
4
 
 
5
6
7
8
9
...
24
25
26
 
 
27
28
29
30
31
...
41
42
43
 
 
44
45
46
47
48
49
50
51
 
 
 
 
 
 
52
53
54
55
56
57
58
59
60
...
70
71
72
 
 
 
 
 
 
 
 
 
 
 
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
92
93
94
95
96
97
98
...
115
116
117
 
 
118
119
120
121
122
123
...
125
126
127
 
128
129
130
131
...
137
138
139
 
 
140
141
142
143
144
 
 
145
146
147
148
149
...
155
156
157
 
158
159
160
161
 
 
162
163
164
165
166
...
174
175
176
 
 
177
178
179
180
181
182
183
 
 
 
184
185
186
187
188
189
0
@@ -1,8 +1,9 @@
0
-= Security of user switching support in Passenger
0
+Security of user switching support in Passenger
0
+===============================================
0
 
0
 
0
-== Introduction and problem description
0
-
0
+Introduction and problem description
0
+------------------------------------
0
 Passenger is an Apache module for Ruby on Rails support. When a URL of a Rails
0
 application is accessed, Passenger will be responsible for forwarding the HTTP
0
 request to the Rails application. Passenger does not run Rails applications
0
@@ -23,8 +24,8 @@ inform the reader about the solutions have we have analyzed, so that
0
 Passenger's security may be reviewed.
0
 
0
 
0
-== Analysis of possible solutions
0
-
0
+Analysis of possible solutions
0
+------------------------------
0
 It seems that the only way to solve this problem on Unix, is to run each Rails
0
 application server as its owner's user and group. Passenger can make use of
0
 one of the following methods to implement this:
0
@@ -40,19 +41,20 @@ one of the following methods to implement this:
0
 
0
 Let us take a look at each method in detail.
0
 
0
-=== Apache must already be running as root
0
-
0
+[[apache_root]]
0
+Apache must already be running as root
0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0
 First, let us take a look at the typical Apache setup, in which Apache is bound
0
 to port 80, and uses the prefork MPM. Binding to any port lower than 1024
0
 requires root privileges, so Apache is typically run as root. This poses an
0
 unacceptable security risk, so Apache's prefork MPM will, upon receiving an
0
 HTTP request, spawn a child process with the privileges of a normal user,
0
-typically "www-data" or "nobody". See the documentation for the prefork MPM
0
-(http://httpd.apache.org/docs/2.2/mod/prefork.html) - in particular the
0
-"User" and "Group" directives - for details. The process which is responsible
0
-for spawning child processes (also called the control process) is run as root.
0
-This is also true for the worker MPM
0
-(http://httpd.apache.org/docs/2.2/mod/worker.html).
0
+typically 'www-data' or 'nobody'.
0
+See http://httpd.apache.org/docs/2.2/mod/prefork.html[the documentation for the
0
+prefork MPM] - in particular the ``User'' and ``Group'' directives - for details.
0
+The process which is responsible for spawning child processes (also called the
0
+control process) is run as root. This is also true for
0
+http://httpd.apache.org/docs/2.2/mod/worker.html[the worker MPM].
0
 
0
 Since Passenger has access to the control process, in the typical Apache setup,
0
 Passenger can already launch Rails applications as a different user. But now we
0
@@ -68,17 +70,18 @@ incredibly easy, and requires no new framework to be written. However, testing
0
 this method in automated unit tests will require running the unit test suit as
0
 root.
0
 
0
-=== Using Apache's suEXEC
0
-
0
-Apache's suEXEC allows one to run CGI processes as different users. But it
0
-seems that suEXEC can only be used for CGI, and is not a general-purpose
0
-mechanism. The PHP-suEXEC software allows one to run PHP applications via
0
-suEXEC, but it requires patching suEXEC. If Passenger is to use suEXEC, then
0
-it is likely that we'll have to patch suEXEC. The suEXEC website strongly
0
-discourages patching.
0
-
0
-=== Using a setuid root wrapper application
0
-
0
+Using Apache's suEXEC
0
+~~~~~~~~~~~~~~~~~~~~~
0
+Apache's http://httpd.apache.org/docs/2.0/suexec.html[suEXEC] allows one to
0
+run CGI processes as different users. But it seems that suEXEC can only be
0
+used for CGI, and is not a general-purpose mechanism. The
0
+http://alain.knaff.lu/howto/PhpSuexec/[PHP-suEXEC] software allows one to run
0
+PHP applications via suEXEC, but it requires patching suEXEC. If Passenger is
0
+to use suEXEC, then it is likely that we'll have to patch suEXEC. The suEXEC
0
+website strongly discourages patching.
0
+
0
+Using a setuid root wrapper application
0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0
 If we use this method, we must be extremely careful. It must not be possible
0
 for arbitrary processes to gain root privileges. We want Passenger, and only
0
 Passenger, to be able to gain root privileges.
0
@@ -89,6 +92,7 @@ the use of proper file permissions. The password file must never be world
0
 readable or writable.
0
 
0
 It works as follows:
0
+
0
 1. Passenger runs the wrapper.
0
 2. Passenger passes the content of the password file to the wrapper, via
0
    an anonymous pipe (or some other anonymous channel, that no other
0
@@ -111,8 +115,9 @@ process's user is in the whitelist.
0
 Writing a wrapper is not too hard. Furthermore, unit tests do not have to be
0
 run as root, in contrast to the run-Apache-as-root method.
0
 
0
-=== Using a setuid $X wrapper application.
0
-
0
+[[setuid_root]]
0
+Using a setuid $X wrapper application
0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0
 A setuid $X wrapper will work in a fashion similar to the setuid root wrapper,
0
 i.e. it will use a password file for authorization.
0
 
0
@@ -120,7 +125,7 @@ Passenger does not spawn Rails applications itself, but does so via the spawn
0
 server. This spawn server is also responsible for preloading the Rails
0
 framework and the Rails application code, in order to speed up the spawning
0
 of Rails applications. See the design document of the spawn server for details.
0
-The spawn server never calls exec(): doing so will make preloading useless.
0
+The spawn server never calls `exec()`: doing so will make preloading useless.
0
 If Passenger is to use a setuid $X wrapper, then it must start the spawn
0
 server via the wrapper. The spawn server itself cannot use the wrapper.
0
 
0
@@ -132,13 +137,13 @@ methods.
0
 Implementing this will also take more work. One has to create a different
0
 wrapper for each user, and to install it.
0
 
0
-=== Using 'su'
0
-
0
+Using 'su'
0
+~~~~~~~~~~
0
 The standard Unix 'su' tool asks for the root password. It's a bad idea for
0
 Apache to know the root password, so using 'su' is not a viable alternative.
0
 
0
-=== Using 'sudo'
0
-
0
+Using 'sudo'
0
+~~~~~~~~~~~~
0
 It might be possible to use the 'sudo' utility. sudo can be configured in
0
 such a way that the user Apache runs as can use sudo without having to enter a
0
 password.
0
@@ -150,12 +155,12 @@ communicate with the spawn server via a non-anonymous channel, such as a named
0
 Unix socket. Because other processes can access this channel, it can introduce
0
 potential security problems. Note that passing information via program arguments
0
 is not secure: it is possible to view that information with tools like 'ps',
0
-or (on Linux) by reading the file /proc/$PID/cmdline.
0
+or (on Linux) by reading the file `/proc/$PID/cmdline`.
0
 
0
 So it seems 'sudo' is not a viable alternative.
0
 
0
-=== Common security issues
0
-
0
+Common security issues
0
+~~~~~~~~~~~~~~~~~~~~~~
0
 Whatever method Passenger will use, the following security principles must be
0
 honored:
0
 
0
@@ -169,16 +174,16 @@ Also, the following questions remain:
0
    the ability to restrict the set of users that Passenger can switch to?
0
 
0
 
0
-== Chosen solution
0
-
0
+Chosen solution
0
+---------------
0
 Running Apache as root and writing a setuid root wrapper are the main
0
 contestants. The former is preferred, because it's easier to implement.
0
 
0
 We have had some conversations with people on the IRC channel #rubyonrails.
0
 Among those people, nobody has ever run Apache as non-root. Because of this
0
-we have chosen to implement the "Running Apache as root" solution, until
0
-a significant number of users request us to implement the "setuid root wrapper"
0
-solution.
0
+we have chosen to implement the <<apache_root,Running Apache as root>>
0
+solution, until a significant number of users request us to implement the
0
+<<setuid_root,setuid root wrapper>> solution.
0
 
0
 See the Ruby API documentation for the 'ApplicationSpawner' class for
0
 implementation details. In short: it will switch to the owner of the file

Comments

    No one has commented yet.