tipidee
Software
skarnet.org
The /etc/tipidee.conf configuration file
Goal and usage
/etc/tipidee.conf is a text file written by the web administrator
to configure the tipideed server. After writing
or modifying this file, the administrator is expected to run the
tipidee-config program, that will read
/etc/tipidee.conf and output a /etc/tipidee.conf.cdb file
that will be suitable for tipideed to use.
tipidee-config provides sane defaults,
so an empty /etc/tipidee.conf file is perfectly usable
for purely static installations. But an empty file still needs to be
created, unless tipidee-config is run
with the -i /dev/null option.
Description
The /etc/tipidee.conf file contains a series of lines; every line is an
instruction. Lines do not wrap around and there is no quoting, so a newline is
always the end of an instruction. Empty lines, or lines containing only
whitespace, or lines beginning with # (comments), are ignored.
If a line contains a # that is not in the middle or end of a word, the
rest of the line is also considered a comment, and ignored.
Words on a line are separated by whitespace (spaces or tabs).
Instructions are one directive, the first word in the line, followed by
one or more arguments. Most directives take a fixed number of
arguments; some of them take a variable number. There are several types
of directives.
Preprocessing directives
These are meta-directives: they do not control tipideed's
behaviour directly, but tell tipidee-config to
include other files. They allow administrators and packagers to write modular, pluggable
configuration files. Preprocessing directives always start with a !
(exclamation point, or bang) character.
You will probably never see preprocessing directives in simple configuration files.
They are meant for bigger or more generic configurations.
The !include directive
!include file
- This directive will replace itself with the contents of file.
- file can be a relative or absolute path. If relative, then
it is relative to the directory of the file being currently processed, i.e.
the file containing the !include directive. In other words, things
will work as you intuitively expect.
The !includedir directive
!includedir dir
- This directive will include every file in directory dir.
- File names starting with a . (dot) will be ignored (i.e. not included).
- The inclusion order is deterministic: file names are sorted according to the C locale.
- dir can be a relative or absolute path. If relative, then
it is relative to the directory of the file being currently processed, i.e.
the file containing the !includedir directive. In other words, things
will work as you intuitively expect.
The !included: directive
!included: unique
!included: multiple
- This directive is usually written at the beginning of a file. Only one
such directive per file is allowed.
- !included: governs what happens when a file is included
more than once.
- If a file contains an !included: unique line, then all
inclusions of this file after the first one will be ignored: the contents
of the file will appear only once.
- If a file contains an !included: multiple line, then the
file will be expanded into its contents every time the file is
included.
- If a file does not contain an !included: directive, then
including it twice is an error, and
tipidee-config-preprocess,
the program in charge of the preprocessing directives, will complain and
exit.
- Don't forget the : (colon) at the end of the !included:
directive!
Global directives
Global directives control global aspects of tipideed
— values that apply to the server itself, no matter what domain it is
serving. The directive name is global, and it takes two arguments: the
name and the value of a setting.
verbosity
global verbosity v
- v is a non-negative integer, describing the level of verbosity that
tipideed will write to its stderr with.
- 0 means only error messages will be printed.
- 1 is the default; it means error messages and warnings will be printed.
- 2 is more verbose, also printing a summary of every HTTP request.
- 3 is like 2 but also prints personally identifiable client information,
such as its IP address.
- 4 prints a lot of details for every request.
- 5 or more is debugging output.
- The configuration file setting can be overwritten by a -v
option on the tipideed command line.
read_timeout
global read_timeout t
- t is a non-negative integer, in milliseconds. It represents
the maximum duration that a client is allowed to be idle.
- If t milliseconds elapse without the client sending a request,
tipideed will assume it is done, close the
connection and exit. Also, if t milliseconds elapse while the client
is sending a request, and the request is still not complete,
tipideed will also close the connection.
- The default is 0, meaning infinite: tipideed
will never slam the door into a client's face, even if the client is
excessively slow or fails to close a connection it's not using anymore.
- A good setting is global read_timeout 60000, closing connections
after one minute of inactivity.
write_timeout
global write_timeout t
- t is a non-negative integer, in milliseconds. It represents
the maximum duration that tipideed will accept
to wait when sending data to the client.
- If t milliseconds elapse while tipideed
is sending data to the client, tipideed will
give up and exit with an error message.
- This typically happens when the network is congested, and the kernel's
socket send buffers are full. It could also mean that a client is failing to
read the data it has requested; or that the data is very large and
taking time to transfer.
- The default is 0, meaning infinite: tipideed
will wait forever until the network uncongests and its client starts to behave.
- An example setting is global write_timeout 600000, closing connections
if a transfer takes more than 10 minutes; but servers serving large files to
clients on slow connections will want a larger value.
cgi_timeout
global cgi_timeout t
- t is a non-negative integer, in milliseconds. It represents
the maximum duration that a CGI script spawned by
tipideed is allowed to run.
- If t milliseconds elapse while a CGI script is running, and
tipideed hasn't gotten a full response yet,
the script will be killed, and tipideed will
send a 504 (Gateway Timeout) response to the client.
- The default is 0, meaning infinite: tipideed
will wait forever until CGI scripts write their output.
- An example setting is global cgi_timeout 10000, giving any
CGI scripts 10 seconds to complete — most users aren't willing to wait
more than a few seconds for a page to render anyway.
max_request_body_length
global max_request_body_length n
- n is a non-negative integer, in bytes. It represents the
maximum size that tipideed will accept for
the body of an HTTP request.
- If the client sends a request with a body larger than n bytes,
tipideed will send a 413 (Content Too Large)
response and close the connection.
- The default is 8192, which is large enough for most.
- An example setting is global max_request_body_length 500,
when the administrator knows that no script on the site needs an input of
more than 500 bytes and anything larger is malicious.
max_cgi_body_length
global max_cgi_body_length n
- n is a non-negative integer, in bytes. It represents the
maximum size that tipideed will accept for
a CGI script's answer that it needs to process.
- If a CGI script writes more than n bytes to its stdout,
tipideed will send a 502 (Bad Gateway)
response to the client and die with an error message.
- This limit does not apply to NPH scripts, which send their stdout
directly to the client without any processing by tipideed.
- The default is 4194304 (4 mebibytes).
- An example setting is global max_cgi_body_length 100000000,
when the administrator knows that CGI scripts can write up to 100 megabytes.
Note that the CGI specification forces web servers to read the whole CGI
output in memory, so the larger the value, the more RAM
tipideed may consume in order to hold CGI
output data. And this is "private dirty" memory, i.e. memory that
really counts towards resource use on your server, so be careful with
that setting — and with the CGI scripts you choose to run.
index_file
global index_file file1 file2 ...
- The global index_file directive has a variable number of
arguments. file1, file2, and so on are the names of the
files that should be used to try and complete the URI when a client request
resolves to a directory.
- For instance: global index_file index.cgi index.html index.htm
means that when tipideed is asked to serve
http://example.com, it will first try to serve as if the request
had been http://example.com/index.cgi, then
http://example.com/index.html, then http://example.com/index.htm.
The first resource found is the one that is served; if none of the
resources exist, tipideed responds 404 (Not Found).
- This is valid for any subdirectory: http://example.com/foo, if the
/foo resource resolves to a directory, is expanded to
http://example.com/foo/index.cgi, then (if not found)
http://example.com/foo/index.html, then (if not found)
http://example.com/foo/index.htm.
- The default is global index_file index.html, meaning that
only the index.html file will be looked up when a resource resolves
to a directory.
The log directive
log is also a global directive, but is introduced by the
keyword log, without prepending global. It allows
the user to control what will appear in
tipideed's log output.
log nothing
log keyword1 keyword2 ...
- tipideed writes all its logs to stderr.
It prints fatal error messages
with the prefix "tipideed: pid pid: fatal: ",
and warning messages
with the prefix "tipideed: pid pid: warning: ".
In normal operation, if everything goes well, you should never see
any of these.
- Depending on what the log directive says, it also prints
informational messages related to what it's doing. These informational
messages all have the prefix "tipideed: pid pid: info: ".
- If no log directive has been provided, the default is
log request answer size.
Here are the informational log lines printed by tipideed,
depending on the keywords in the log directive:
- nothing
- Don't log anything else than warning and error messages. This
keyword cannot be given with other keywords.
- start
- Log a start line when tipideed starts
and an exit exitcode line when it exits.
- ip
- Add an ip client_ip field to the start line.
This is potentially PII, so make sure to stay compliant with your local laws if you activate it.
client_ip is read from the TCPREMOTEIP environment variable.
This keyword has no effect when given without the start keyword.
- hostname
- Add a host client_hostname field to the start line.
This is potentially PII, so make sure to stay compliant with your local laws if you activate it.
client_hostname is read from the TCPREMOTEHOST environment variable if it exists, or made up from
TCPREMOTEIP otherwise. Make sure to invoke
s6-tcpserver-access before
tipideed in order to get meaningful values for this field.
This keyword has no effect when given without the start keyword.
- host_as_prefix
- Prepend all request, resource and answer
lines with a host host field. This field will not be repeated in the request
line, so it changes the order of the fields. host is the virtual host the request is addressed
to. host_as_prefix is useful when you want to log entries for different virtual hosts to
different locations. For instance, if you're using
s6-log, and want entries for example.com and
example.org to be logged to different backends, you would use the host_as_prefix directive,
and use
- +"^tipidee: pid [[:digit:]]*: info: host example\\.com "
to select example.com-related
lines, and - +"^tipidee: pid [[:digit:]]*: info: host example\\.org "
to select example.org-related lines. Note that warning and error messages would still need an additional
backend, as well as start and exit lines if you add the start directive
to your log configuration.
- request
- Log a request line when tipideed
receives a request from its client. The line looks like request method host host path "path"
http version. The path is decoded, but if there are non-printable characters in it, they are
encoded as hexadecimal values \0xab. If the request line includes a query, a query query field
is added before the http field.
- referrer
- Add a referrer "referrer" field to the request line, for
requests that include a Referrer: header. referrer is quoted like path, to avoid
malicious clients messing with log lines.
This keyword has no effect when given without the request keyword.
- user-agent
- Add a user-agent "user-agent" field to the request line, for
requests that include a User-Agent: header. user-agent is quoted like path, to avoid
malicious clients messing with log lines.
This keyword has no effect when given without the request keyword.
- resource
- Log a resource line when tipideed
has found a resource corresponding to the URI and is willing to serve it. The line looks like
resource docroot docroot file file type type. docroot is
the document root of the virtual host; file is the path to the served file; type
is nph for an NPH script, cgi for a CGI script, or the Content-Type for a regular file.
- answer
- Log an answer line when tipideed
answers the currently processed request. The line looks like answer status, where status is
the 3-digit status code returned to the client.
- size
- Add a size size field to the answer line,
containing the Content-Length of the answer.
This keyword has no effect when given without the answer keyword.
- debug
- Log debug information. You should not need this in regular use.
The content-type directive
content-type is also a global directive, but is introduced by the
keyword content-type, without prepending global. It allows
the user to define mappings from a document's extension to a standard Content-Type.
content-type type extension1 extension2 ...
- Files ending with extension1, extension2, and so on, will be served
to clients with the Content-Type: type header.
- Extensions must be listed with their initial dot.
- Example: content-type text/html .html .htm means that files
ending in .html or .htm should be served as text/html.
- tipidee already comes with a
large
list of default Content-Type mappings; this directive should only be necessary if you're
serving files with uncommon extensions or have specific needs.
Local directives
All the other directives are local: they only apply to the current domain.
Except for domain, they can only be used after a domain directive.
domain
domain domain
- domain is a special directive in that it is stateful. Instead of
having a direct effect on the configuration, it merely defines the domain that
the next local directives will apply to. domain example.com means
that a subsequent cgi /cgi-bin/ line will declare that a resource
under //example.com/cgi-bin/ is a CGI script.
- The current domain remains defined and active until the next
domain directive.
- Global directives are unaffected by the current domain. It is good
practice to declare global directives before the first domain
line, but it is not mandatory.
- If your resources are accessible via several URIs, the declared domain
should be the canonical one, i.e. the name of the real
directory hosting them, and not the symlinks. E.g. if you are serving files in
the real directory /home/www/docs/example.com, with example.com:80
and example.com:443 being symlinks to example.com, then
domain example.com is the correct declaration for settings that will apply
to these files. And if you are hosting a different set of documents in the real
directory /home/www/docs/example.com:81, and example.com:444 is
a symlink to example.com:81, then these will be affected by the settings
declared under domain example.com:81.
- The point of all this is to make virtual hosting as flexible as possible,
allowing you to have different configurations for different virtual hosts —
including serving different sets of documents for the same host on different ports!)
— without needing to duplicate the configuration when you are serving the same
sets of documents over several ports, e.g. when you're serving both HTTP and HTTPS.
- Complex configurations can benefit from the !include or
!includedir primitives, by putting the configuration related to one domain
in a dedicated file, and having the main /etc/tipidee.conf only declare
global configuration and include all the domain-specific files.
cgi
cgi directory
cgi file
- The cgi directory directive tells
tipideed that under the current domain,
all the files under directory (and its whole sub-hierarchy)
are CGI scripts. directory is absolute (it must start with
a slash, referring to the document root for the current domain), and
must end with a slash as well.
- The cgi file directive tells
tipideed that under the current domain,
file is a CGI script, regardless of its location.
file is absolute (it must start with
a slash, referring to the document root for the current domain), but
must not end with a slash.
- A common use is: cgi /cgi-bin/
- By default, no CGI directories or files are defined, so an
empty tipidee configuration will only serve static files.
noncgi
noncgi directory
noncgi file
- The noncgi directory directive tells
tipideed that under the current domain,
all the files under directory (and its whole sub-hierarchy)
are not CGI scripts.
- The noncgi file directive tells
tipideed that under the current domain,
file is not a CGI script, regardless of its location.
- This is a rare directive, only useful if for some reason you have
a static document under /cgi-bin or equivalent.
nph-prefix
nph-prefix prefix
- This directive tells tipideed that
CGI scripts (recognized as such by a cgi directive) whose name
starts with prefix are
non-parsed header
scripts.
- Common usage is nph-prefix nph- — paired with cgi /cgi-bin/,
this means that under the current domain, scripts of the form
/cgi-bin/nph-foobar are NPH.
nph
nph directory
nph file
- This is an alternative way of specifying which scripts are
NPH.
This directive says that CGI scripts under directory are NPH
(provided they're also recognized as CGI), and that file is NPH
(provided it's also recognized as CGI).
- For instance, having both cgi /cgi-bin/ and nph /cgi-bin/
means that all the CGI scripts under /cgi-bin are considered NPH.
nonnph
nonnph directory
nonnph file
- This is the opposite, saying that CGI scripts under directory,
or CGI script file, are not NPH.
- This is a rare directive, only useful if the vast majority of your
scripts, but not all of them, are NPH.
basic-auth
basic-auth directory
basic-auth file
- This directive tells tipideed that
file file, or all files under directory, are protected
by Basic HTTP
authentication.
- This feature is currently unimplemented, so
tipidee-config will print a warning if
it finds such a directive in your configuration file.
- Implementation of this feature has been delayed because it needs an
additional database to store the resource:user:password tuples,
with more restricted permissions than /etc/tipidee.conf.cdb, since
passwords are confidential information. This is planned in a future version
of tipidee. And yes, existing web servers that make the administrator store
cleartext passwords in the generic configuration file are terrible.
no-auth
no-auth directory
no-auth file
- This is the opposite, saying that files under directory,
or specific file file, do not require authentication.
- This is a rare directive, only useful if you have a whole directory
under basic-auth but want to carve exceptions.
file-type
file-type directory type
file-type file
type
- file-type is similar to content-type,
but local. For files under directory, or for specific file file, it
overrides the default Content-Type associated with their extension, and gives them the
Content-Type type instead.
- file-type /source/ text/plain will serve all files under the current
domain under the /source directory as text/plain.
- file-type /source/file.html text/html will serve /source/file.html
under the current domain as text/html, even with the previous more generic
rule applying to /source.
redirect
redirect resource rtype target
- resource is the URI to redirect, relative to the current domain.
For instance, if the current domain is example.com and resource
is foobar.html, then a request for http://example.com/foobar.html
will be redirected to target.
- rtype is the type of redirection. It is one of the following four numbers:
- 308: permanent redirection
- 307: temporary redirection
- 301: permanent redirection
while allowing the client to change the request method. You generally should not need this.
- 302: temporary redirection
while allowing the client to change the request method. You generally should not need this.
- target is the target of the redirection. It must be a full URL starting
with http:// or https://. (If you want local redirection under the
same virtual domain, this directive is not what you want: instead, you can make a
symbolic link in your filesystem.)
- Unlike files or directories given as arguments in other local directives,
resource does not need to exist in the filesystem.
tipideed processes redirections before looking
up resources in the filesystem. This is more efficient, but comes with a caveat:
a file will only be served if there is no redirection directive for that resource,
so make sure to keep your configuration file up-to-date.
- This also means that the "real directory" rule does not apply to redirections.
Instead, you can declare a redirection under the example.com:80 domain, whether
or not /home/www/docs/example.com:80 is a real directory; the redirection
will only apply to requests received on port 80 (and not, for instance, to
requests received on port 443). But if you declare a redirection under the
example.com domain, it will apply to requests received on any port.