1===================== 2the FastCGI Interface 3===================== 4 5------------------- 6Module: mod_fastcgi 7------------------- 8 9:Author: Jan Kneschke 10:Date: $Date: 2004/11/03 22:26:05 $ 11:Revision: $Revision: 1.3 $ 12 13:abstract: 14 The FastCGI interface is the fastest and most secure way 15 to interface external process-handlers like Perl, PHP and 16 your self-written applications. 17 18.. meta:: 19 :keywords: lighttpd, FastCGI 20 21.. contents:: Table of Contents 22 23Description 24=========== 25 26lighttpd provides an interface to a external programs that 27support the FastCGI interface. The FastCGI Interface is 28defined by http://www.fastcgi.com/ and is a 29platform-independent and server independent interface between 30a web-application and a webserver. 31 32This means that FastCGI programs that run with the Apache 33Webserver will run seamlessly with lighttpd and vice versa. 34 35 36FastCGI 37------- 38 39FastCGI is removes a lot of the limitations of CGI programs. 40CGI programs have the problem that they have to be restarted 41by the webserver for every request which leads to really bad 42performance values. 43 44FastCGI removes this limitation by keeping the process running 45and handling the requests by this always running process. This 46removes the time used for the fork() and the overall startup 47and cleanup time which is necessary to create and destroy a 48process. 49 50While CGI programs communicate to the server over pipes, 51FastCGI processes use Unix-Domain-Sockets or TCP/IP to talk 52with the webserver. This gives you the second advantage over 53simple CGI programs: FastCGI don't have to run on the Webserver 54itself but everywhere in the network. 55 56lighttpd takes it a little bit further by providing a internal 57FastCGI load-balancer which can be used to balance the load 58over multiple FastCGI Servers. In contrast to other solutions 59only the FastCGI process has to be on the cluster and not the 60whole webserver. That gives the FastCGI process more resources 61than a e.g. load-balancer+apache+mod_php solution. 62 63If you compare FastCGI against a apache+mod_php solution you 64should note that FastCGI provides additional security as the 65FastCGI process can be run under different permissions that 66the webserver and can also live a chroot which might be 67different than the one the webserver is running in. 68 69Options 70======= 71 72lighttpd provides the FastCGI support via the fastcgi-module 73(mod_fastcgi) which provides 2 options in the config-file: 74 75fastcgi.debug 76 a value between 0 and 65535 to set the debug-level in the 77 FastCGI module. Currently only 0 and 1 are used. Use 1 to 78 enable some debug output, 0 to disable it. 79 80fastcgi.map-extensions 81 map multiple extensions to the same fastcgi server 82 83 Example: :: 84 85 fastcgi.map-extensions = ( ".php3" => ".php" ) 86 87fastcgi.server 88 tell the module where to send FastCGI requests to. Every 89 file-extension can have it own handler. Load-Balancing is 90 done by specifying multiple handles for the same extension. 91 92 structure of fastcgi.server section: :: 93 94 ( <extension> => 95 ( 96 ( "host" => <string> , 97 "port" => <integer> , 98 "socket" => <string>, # either socket 99 # or host+port 100 "bin-path" => <string>, # OPTIONAL 101 "bin-environment" => <array>, # OPTIONAL 102 "bin-copy-environment" => <array>, # OPTIONAL 103 "mode" => <string>, # OPTIONAL 104 "docroot" => <string> , # OPTIONAL if "mode" 105 # is not "authorizer" 106 "check-local" => <string>, # OPTIONAL 107 "max-procs" => <integer>, # OPTIONAL 108 "broken-scriptfilename" => <boolean>, # OPTIONAL 109 "disable-time" => <integer>, # optional 110 "x-sendfile" => <boolean>, # optional (replaces "allow-x-send-file") 111 "x-sendfile-docroot" => <boolean>, # optional 112 "kill-signal" => <integer>, # OPTIONAL 113 "fix-root-scriptname" => <boolean>, 114 # OPTIONAL 115 ( "host" => ... 116 ) 117 ) 118 ) 119 120 :<extension>: is the file-extension or prefix 121 (if started with "/") 122 :"host": is hostname/ip of the FastCGI process 123 :"port": is tcp-port on the "host" used by the FastCGI 124 process 125 :"bin-path": path to the local FastCGI binary which should be 126 started if no local FastCGI is running 127 :"socket": path to the unix-domain socket 128 :"mode": is the FastCGI protocol mode. 129 Default is "responder", also "authorizer" 130 mode is implemented. 131 :"docroot": is optional and is the docroot on the remote 132 host for default "responder" mode. For 133 "authorizer" mode it is MANDATORY and it points 134 to docroot for authorized requests. For security 135 reasons it is recommended to keep this docroot 136 outside of server.document-root tree. 137 :"check-local": is optional and may be "enable" (default) or 138 "disable". If enabled the server first check 139 for a file in local server.document-root tree 140 and return 404 (Not Found) if no such file. 141 If disabled, the server forward request to 142 FastCGI interface without this check. 143 :"broken-scriptfilename": breaks SCRIPT_FILENAME in a wat that 144 PHP can extract PATH_INFO from it (default: disabled) 145 :"disable-time": time to wait before a disabled backend is checked 146 again 147 :"x-sendfile": controls if X-Sendfile backend response header is allowed 148 (deprecated headers: X-Sendfile2 and X-LIGHTTPD-send-file) 149 ("x-sendfile" replaces "allow-x-sendfile") 150 :"x-sendfile-docroot": list of directory trees permitted with X-Sendfile 151 :"fix-root-scriptname": fix broken path-info split for "/" extension ("prefix") 152 153 If bin-path is set: 154 155 :"max-procs": the upper limit of the processes to start 156 :"bin-environment": put an entry into the environment of 157 the started process 158 :"bin-copy-environement": clean up the environment and copy 159 only the specified entries into the fresh 160 environment of the spawn process 161 :"kill-signal": signal to terminate the FastCGI process with, 162 defaults to SIGTERM 163 164Examples 165-------- 166 167 Multiple extensions for the same host :: 168 169 fastcgi.server = ( ".php" => 170 (( "host" => "127.0.0.1", 171 "port" => 1026, 172 "bin-path" => "/usr/local/bin/php" 173 )), 174 ".php4" => 175 (( "host" => "127.0.0.1", 176 "port" => 1026 177 )) 178 ) 179 180 Example with prefix: :: 181 182 fastcgi.server = ( "/remote_scripts/" => 183 (( "host" => "192.168.0.3", 184 "port" => 9000, 185 "check-local" => "disable", 186 "docroot" => "/" # remote server may use 187 # it's own docroot 188 )) 189 ) 190 191 The request `http://my.host.com/remote_scripts/test.cgi` will 192 be forwarded to fastcgi server at 192.168.0.3 and the value 193 "/remote_scripts/test.cgi" will be used for the SCRIPT_NAME 194 variable. Remote server may prepend it with its own 195 document root. The handling of index files is also the 196 responsibility of remote server for this case. 197 198 In the case that the prefix is not terminated with a slash 199 the prefix will be handled as file and /test.cgi would become 200 a PATH_INFO instead of part of SCRIPT_NAME. 201 202 203 Example for "authorizer" mode: :: 204 205 fastcgi.server = ( "/remote_scripts/" => 206 (( "host" => "10.0.0.2", 207 "port" => 9000, 208 "docroot" => "/path_to_private_docs", 209 "mode" => "authorizer" 210 )) 211 ) 212 213 Note that if "docroot" is specified then its value will be 214 used in DOCUMENT_ROOT and SCRIPT_FILENAME variables passed 215 to FastCGI server. 216 217Load-Balancing 218============== 219 220The FastCGI plugin provides automatically a load-balancing between 221multiple FastCGI servers. :: 222 223 fastcgi.server = ( ".php" => 224 (( "host" => "10.0.0.2", "port" => 1030 ), 225 ( "host" => "10.0.0.3", "port" => 1030 )) 226 ) 227 228 229To understand how the load-balancing works you can enable the 230fastcgi.debug option and will get a similar output as here: :: 231 232 proc: 127.0.0.1 1031 1 1 1 31454 233 proc: 127.0.0.1 1028 1 1 1 31442 234 proc: 127.0.0.1 1030 1 1 1 31449 235 proc: 127.0.0.1 1029 1 1 2 31447 236 proc: 127.0.0.1 1026 1 1 2 31438 237 got proc: 34 31454 238 release proc: 40 31438 239 proc: 127.0.0.1 1026 1 1 1 31438 240 proc: 127.0.0.1 1028 1 1 1 31442 241 proc: 127.0.0.1 1030 1 1 1 31449 242 proc: 127.0.0.1 1031 1 1 2 31454 243 proc: 127.0.0.1 1029 1 1 2 31447 244 245Even if this for multiple FastCGI children on the local machine 246the following explanation is valid for remote connections too. 247 248The output shows: 249 250- IP, port, unix-socket (is empty here) 251- is-local, state (0 - unset, 1 - running, ... ) 252- active connections (load) 253- PID 254 255As you can see the list is always sorted by the load field. 256 257Whenever a new connection is requested, the first entry (the one 258with the lowest load) is selected, the load is increased (got proc: ...) 259and the list is sorted again. 260 261If a FastCGI request is done or the connection is dropped, the load on the 262FastCGI proc decreases and the list is sorted again (release proc: ...) 263 264This behaviour is very light-weight in code and still very efficient 265as it keeps the fastcgi-servers equally loaded even if they have different 266CPUs. 267 268Adaptive Process Spawning 269========================= 270 271.. note:: This feature is disabled in 1.3.14 again. min-procs is 272 ignored in that release 273 274Starting with 1.3.8 lighttpd can spawn processes on demand if 275a bin-path is specified and the FastCGI process runs locally. 276 277If you want to have a least one FastCGI process running and 278more of the number of requests increases you can use min-procs 279and max-procs. 280 281A new process is spawned as soon as the average number of 282requests waiting to be handle by a single process increases the 283max-load-per-proc setting. 284 285The idle-timeout specifies how long a fastcgi-process should wait 286for a new request before it kills itself. 287 288Example 289------- 290:: 291 292 fastcgi.server = ( ".php" => 293 (( "socket" => "/tmp/php.socket", 294 "bin-path" => "/usr/local/bin/php", 295 "min-procs" => 1, 296 "max-procs" => 32, 297 "max-load-per-proc" => 4, 298 "idle-timeout" => 20 299 )) 300 ) 301 302Disabling Adaptive Spawning 303--------------------------- 304 305Adaptive Spawning is a quite new feature and it might misbehave 306for your setup. There are several ways to control how the spawning 307is done: 308 3091. ``"max-load-per-proc" => 1`` 310 if that works for you, great. 311 3122. If not set ``min-procs == max-procs``. 313 3143. For PHP you can also use: :: 315 316 $ PHP_FCGI_CHILDREN=384 ./lighttpd -f ./lighttpd.conf 317 318 fastcgi.server = ( ".php" => 319 (( "socket" => "/tmp/php.socket", 320 "bin-path" => "/usr/local/bin/php", 321 "min-procs" => 1, 322 "max-procs" => 1, 323 "max-load-per-proc" => 4, 324 "idle-timeout" => 20 325 )) 326 ) 327 328 It will create one socket and let's PHP create the 384 processes itself. 329 3304. If you don't want lighttpd to manage the fastcgi processes, remove the 331 bin-path and use spawn-fcgi to spawn them itself. 332 333 334FastCGI and Programming Languages 335================================= 336 337Preparing PHP as a FastCGI program 338---------------------------------- 339 340One of the most important application that has a FastCGI 341interface is php which can be downloaded from 342http://www.php.net/ . You have to recompile the php from 343source to enable the FastCGI interface as it is normally 344not enabled by default in the distributions. 345 346If you already have a working installation of PHP on a 347webserver execute a small script which just contains :: 348 349 <?php phpinfo(); ?> 350 351and search for the line in that contains the configure call. 352You can use it as the base for the compilation. 353 354You have to remove all occurrences of `--with-apxs`, `--with-apxs2` 355and the like which would build PHP with Apache support. Add the 356next three switches to compile PHP with FastCGI support:: 357 358 $ ./configure \ 359 --enable-fastcgi \ 360 --enable-force-cgi-redirect \ 361 ... 362 363After compilation and installation check that your PHP 364binary contains FastCGI support by calling: :: 365 366 $ php -v 367 PHP 4.3.3RC2-dev (cgi-fcgi) (built: Oct 19 2003 23:19:17) 368 369The important part is the (cgi-fcgi). 370 371 372Starting a FastCGI-PHP 373---------------------- 374 375Starting with version 1.3.6 lighttpd can spawn the FastCGI 376processes locally itself if necessary: :: 377 378 fastcgi.server = ( ".php" => 379 (( "socket" => "/tmp/php-fastcgi.socket", 380 "bin-path" => "/usr/local/bin/php" 381 )) 382 ) 383 384PHP provides 2 special environment variables which control the number of 385spawned works under the control of a single watching process 386(PHP_FCGI_CHILDREN) and the number of requests what a single worker 387handles before it kills itself. :: 388 389 fastcgi.server = ( ".php" => 390 (( "socket" => "/tmp/php-fastcgi.socket", 391 "bin-path" => "/usr/local/bin/php", 392 "bin-environment" => ( 393 "PHP_FCGI_CHILDREN" => "16", 394 "PHP_FCGI_MAX_REQUESTS" => "10000" 395 ) 396 )) 397 ) 398 399To increase the security of the started process you should only pass 400the necessary environment variables to the FastCGI process. :: 401 402 fastcgi.server = ( ".php" => 403 (( "socket" => "/tmp/php-fastcgi.socket", 404 "bin-path" => "/usr/local/bin/php", 405 "bin-environment" => ( 406 "PHP_FCGI_CHILDREN" => "16", 407 "PHP_FCGI_MAX_REQUESTS" => "10000" ), 408 "bin-copy-environment" => ( 409 "PATH", "SHELL", "USER" ) 410 )) 411 ) 412 413Configuring PHP 414--------------- 415 416If you want to use PATH_INFO and PHP_SELF in you PHP scripts you have to 417configure php and lighttpd. The php.ini needs the option: :: 418 419 cgi.fix_pathinfo = 1 420 421and the option ``broken-scriptfilename`` in your fastcgi.server config: :: 422 423 fastcgi.server = ( ".php" => 424 (( "socket" => "/tmp/php-fastcgi.socket", 425 "bin-path" => "/usr/local/bin/php", 426 "bin-environment" => ( 427 "PHP_FCGI_CHILDREN" => "16", 428 "PHP_FCGI_MAX_REQUESTS" => "10000" ), 429 "bin-copy-environment" => ( 430 "PATH", "SHELL", "USER" ), 431 "broken-scriptfilename" => "enable" 432 )) 433 ) 434 435Why this ? the ``cgi.fix_pathinfo = 0`` would give you a working ``PATH_INFO`` 436but no ``PHP_SELF``. If you enable it, it turns around. To fix the 437``PATH_INFO`` `--enable-discard-path` needs a SCRIPT_FILENAME which is against the CGI spec, a 438broken-scriptfilename. With ``cgi.fix_pathinfo = 1`` in php.ini and 439``broken-scriptfilename => "enable"`` you get both. 440 441 442External Spawning 443----------------- 444 445Spawning FastCGI processes directly in the webserver has some 446disadvantages like 447 448- FastCGI process can only run locally 449- has the same permissions as the webserver 450- has the same base-dir as the webserver 451 452As soon as you are using a separate FastCGI Server to 453take off some load from the webserver you have to control 454the FastCGI process by a external program like spawn-fcgi. 455 456spawn-fcgi is used to start a FastCGI process in its own 457environment and set the user-id, group-id and change to 458another root-directory (chroot). 459 460For convenience a wrapper script should be used which takes 461care of all the necessary option. Such a script in included 462in the lighttpd distribution and is call spawn-php.sh. 463 464The script has a set of config variables you should take 465a look at: :: 466 467 ## ABSOLUTE path to the spawn-fcgi binary 468 SPAWNFCGI="/usr/local/sbin/spawn-fcgi" 469 470 ## ABSOLUTE path to the PHP binary 471 FCGIPROGRAM="/usr/local/bin/php" 472 473 ## bind to tcp-port on localhost 474 FCGIPORT="1026" 475 476 ## bind to unix domain socket 477 # FCGISOCKET="/tmp/php.sock" 478 479 ## number of PHP children to spawn 480 PHP_FCGI_CHILDREN=10 481 482 ## number of request server by a single php-process until 483 ## is will be restarted 484 PHP_FCGI_MAX_REQUESTS=1000 485 486 ## IP addresses where PHP should access server connections 487 ## from 488 FCGI_WEB_SERVER_ADDRS="127.0.0.1,192.168.0.1" 489 490 # allowed environment variables sperated by spaces 491 ALLOWED_ENV="ORACLE_HOME PATH USER" 492 493 ## if this script is run as root switch to the following user 494 USERID=wwwrun 495 GROUPID=wwwrun 496 497If you have set the variables to values that fit to your 498setup you can start it by calling: :: 499 500 $ spawn-php.sh 501 spawn-fcgi.c.136: child spawned successfully: PID: 6925 502 503If you get "child spawned successfully: PID:" the php 504processes could be started successfully. You should see them 505in your processlist: :: 506 507 $ ps ax | grep php 508 6925 ? S 0:00 /usr/local/bin/php 509 6928 ? S 0:00 /usr/local/bin/php 510 ... 511 512The number of processes should be PHP_FCGI_CHILDREN + 1. 513Here the process 6925 is the master of the slaves which 514handle the work in parallel. Number of parallel workers can 515be set by PHP_FCGI_CHILDREN. A worker dies automatically of 516handling PHP_FCGI_MAX_REQUESTS requests as PHP might have 517memory leaks. 518 519If you start the script as user root php processes will be 520running as the user USERID and group GROUPID to drop the 521root permissions. Otherwise the php processes will run as 522the user you started script as. 523 524As the script might be started from a unknown stage or even 525directly from the command-line it cleans the environment 526before starting the processes. ALLOWED_ENV contains all 527the external environment variables that should be available 528to the php-process. 529 530 531Perl 532---- 533 534For Perl you have to install the FCGI module from CPAN. 535 536Skeleton for remote authorizer 537============================== 538 539The basic functionality of authorizer is as follows (see 540http://www.fastcgi.com/devkit/doc/fcgi-spec.html, 6.3 for 541details). :: 542 543 #include <fcgi_stdio.h> 544 #include <stdlib.h> 545 #include <unistd.h> 546 int main () { 547 char* p; 548 549 while (FCGI_Accept() >= 0) { 550 /* wait for fastcgi authorizer request */ 551 552 printf("Content-type: text/html\r\n"); 553 554 if ((p = getenv("QUERY_STRING")) == NULL) || 555 <QUERY_STRING is unauthorized>) 556 printf("Status: 403 Forbidden\r\n\r\n"); 557 558 else printf("\r\n"); 559 /* default Status is 200 - allow access */ 560 } 561 562 return 0; 563 } 564 565It is possible to use any other variables provided by 566FastCGI interface for authorization check. Here is only an 567example. 568 569 570Troubleshooting 571=============== 572 573fastcgi.debug should be enabled for troubleshooting. 574 575If you get: :: 576 577 (fcgi.c.274) connect delayed: 8 578 (fcgi.c.289) connect succeeded: 8 579 (fcgi.c.745) unexpected end-of-file (perhaps the fastcgi 580 process died): 8 581 582the fastcgi process accepted the connection but closed it 583right away. This happens if FCGI_WEB_SERVER_ADDRS doesn't 584include the host where you are connection from. 585 586If you get :: 587 588 (fcgi.c.274) connect delayed: 7 589 (fcgi.c.1107) error: unexpected close of fastcgi connection 590 for /peterp/seite1.php (no fastcgi process on host/port ?) 591 (fcgi.c.1015) emergency exit: fastcgi: connection-fd: 5 592 fcgi-fd: 7 593 594the fastcgi process is not running on the host/port you are 595connection to. Check your configuration. 596 597If you get :: 598 599 (fcgi.c.274) connect delayed: 7 600 (fcgi.c.289) connect succeeded: 7 601 602everything is fine. The connect() call just was delayed a 603little bit and is completely normal. 604 605