YAWS.CONF(5) | User Commands | YAWS.CONF(5) |
/etc/yaws/yaws.conf - Configuration file for the Yaws web server
Yaws is fast lightweight web server. It reads a configuration file called yaws.conf to control its operations. The configuration contains two distinct parts: a global part which affects all the virtual hosts and a server part where options for each virtual host is supplied.
report.log - this is a text file that contains all error logger printouts from Yaws.
<Host>.access - for each virtual host served by Yaws, a file <Host>.access will be written that contains an access log in NCSA combined/XLF/ELF log format. (See http://www.w3.org/TR/WD-logfile.html for more details on Extended Log File Format.)
<Host>.auth - for each virtual host served by Yaws, a file <Host>.auth will be written which contains all http auth related messages.
trace_<YYYYMMDD_hhmmss> - Trace files are written in this subdirectory, suffixed by the creation date.
trace.<Pid>.traffic - this file contains the traffic trace if that is enabled, where <Pid> is the process id handling the TCP connection.
# /usr/local/bin/yaws --id foobar --stop
To stop the Yaws server with id "foobar". Each Yaws server will write its internal data into a file called $HOME/.yaws/yaws/ID where ID is the identity of the server. Yaws also creates a file called $HOME/.yaws/yaws/ID/CTL which contains the port number where the server is listening for control commands. The default id is "default".
erlang - use file:sendfile/5.
disable - use gen_tcp:send/2.
The default value is erlang.
For example, we can specify
soap_srv_mods=<Mod1, Handler, Wsdl1> <Mod2, Handler, Wsdl2, Prefix> ...
subconfig = /etc/yaws/global.conf subconfig = /etc/yaws/vhosts/*.conf
Or, relatively to the configuration location:
subconfig = global.conf subconfig = vhosts/*.conf
# Lines beginning with a '#' or a whitespace are ignored # blank lines are also ignored <MIME type> <space separated file extensions>
The default file is located at ${PREFIX}/lib/yaws/priv/mime.types. You should not edit this file because it may be replaced when you upgrade your server.
add_types = <MimeType1, Ext> <MimeType2, Ext1 Ext2 ...> ...
The mappings defined using this directive will overload all other definitions. If a file extension is defined several times, only the last one is kept. Multiple add_types directives may be used.
add_charsets = <Charset1, Ext> <Charset2, Ext1 Ext2 ...> ...
The mappings defined using this directive will overload all other definitions. If a file extension is defined several times, only the last one is kept. Multiple add_charsets directives may be used.
When disabled (or not supported), all virtual servers in the same group (same IP/Port) must share the same SSL configuration, especially the same SSL certificate. Only the HTTP Host header will be considered to find the right virtual server.
When enabled, SSL configuration can be different from one virtual server to another; each one can have its own SSL certificate. In this case, if a client provides a SNI hostname, it will be used to find the right virtual server. To accept the SNI information from the client, the first virtual server -- the default one, see pick_first_virthost_on_nomatch -- must include TLS as a permitted protocol.
If the sni directive is set to enable, non-SNI clients are allowed. For such clients, virtual servers are selected as if Yaws did not have SNI support. If it is set to strict, SNI hostname is mandatory to access a SSL virtual server. But in all cases, when SNI support is enabled, if a client provides a SNI hostname, it must match the HTTP Host header (which is mandatory too). Note that the first virtual server (the default one) will be used for any request where the provided SNI hostname doesn't match any of virtual server names. So, it is important that the first virtual server have the most restrictive access control, otherwise clients can access restricted resources by sending a request for any unknown hostname. (This isn't actually any different from using virtual servers without SNI support.) If you're using self-signed certificates, be sure to also set the depth configuration variable to 0 to avoid following certificate chains.
The sni directive is a global one, so if you set it to strict, non-SNI clients will be refused for all SSL groups. See require_sni directive from the server part to mitigate this requirement.
Default is disable.
Yaws can virthost several web servers on the same IP address as well as several web servers on different IP addresses. This includes SSL servers.
Each virtual host is defined within a matching pair of <server ServerName> and </server>. The ServerName will be the name of the webserver.
The following directives are allowed inside a server definition.
buffer = Integer (default: same as inet:setopts/2)
delay_send = true | false (default: same as inet:setopts/2)
linger = Integer | false (default: same as inet:setopts/2)
nodelay = true | false (default: same as inet:setopts/2)
priority = Integer (default: same as inet:setopts/2)
sndbuf = Integer (default: same as inet:setopts/2)
recbuf = Integer (default: same as inet:setopts/2)
send_timeout = Integer | infinity (default: same as inet:setopts/2)
send_timeout_close = true | false (default: same as inet:setopts/2)
The following functions should be exported:
Module:open_log(ServerName, Type, LogDir)
Ip - IP address of the accessing client (as a tuple).
Req - the HTTP method, URI path, and HTTP version of the request (as a #http_request{} record).
InHdrs - the HTTP headers which were received from the WWW client (as a #headers{} record).
OutHdrs - the HTTP headers sent to the WWW client (as a #outh{} record)
Path - the URI path of the request (as a string).
Item - the result of an authentication request. May be {ok,User}, 403 or {401,Realm}.
Time - The time taken to serve the request, in microseconds.
There is no such module configured by default.
<extra_cgi_vars dir='/path/to/some/scripts'> var = val ... </extra_cgi_vars>
min_compress_size = nolimit | Integer
mime_types = default image/* mime_types = application/xml application/xhtml+xml application/rss+xml
By default, the following MIME types are compressed (if deflate is set to true): text/*, application/rtf, application/msword, application/pdf, application/x-dvi, application/javascript. Multiple mime_types directives can be used.
Note: for fcgi scripts, the FastCGI application server is only called if a local file with the .fcgi extension exists. However, the contents of the local .fcgi file are ignored.
appmods = <Path1, Module1> <Path2, Modules2> ...
Assume for example that we have the URL
http://www.hyber.org/myapp/foo/bar/baz?user=joe while we have the module
foo defined as an appmod, the function foo:out(Arg) will be invoked
instead of searching the filesystems below the point foo.
The Arg argument will have the missing path part supplied in its
appmoddata field.
It is also possible to exclude certain directories from appmod processing. This is particulaly interesting for '/' appmods. Here is an example:
appmods = </, myapp exclude_paths icons js top/static>
The above configuration will invoke the 'myapp' erlang module on everything except any file found in directories 'icons', 'js' and 'top/static' relative to the docroot.
closed - same as done but the DispatchModule also closed the connection
continue - the dispatch module has decided not to handle the request, and instead wants Yaws to perform its regular request dispatching
GC - a #gconf{} record (defined in yaws.hrl)
SC - a #sconf{} record (defined in yaws.hrl)
Auth - a #auth{} record
Realm - a string
expires = <MimeType1, access+Seconds> <MimeType2, modify+Seconds> <MimeType3, always> ...
A MimeType can also have a wildcard as subtype or both as subtype and type, like type/* or */*.
These HTTP headers are an instruction to the client about the document's validity and persistence. If cached, the document may be fetched from the cache rather than from the source until this time has passed. After that, the cache copy is considered "expired" and invalid, and a new copy must be obtained from the source. Here is an example:
expires = <image/gif, access+2592000> <image/png, access+2592000> expires = <image/jpeg, access+2592000> <text/css, access+2592000> expires = <text/*, always>
and here is another:
expires = <*/*, always>
The module yaws_vdir can be used in case you want to serve static content that is not located in your docroot. See the example at the bottom of this man page for how to use the opaque + vdir elements to instruct the yaws_vdir module what paths to rewrite.
revproxy = /tmp/foo http://yaws.hyber.org
makes the hyber website appear under /tmp/foo.
It is possible to have multiple reverse proxies inside the same server.
You can optionally configure an interception module for each reverse proxy, allowing your application to examine and modify requests and HTTP headers as they pass through the proxy from client to backend server and also examine and modify responses and HTTP headers as they return from the backend server through the proxy to the client.
You specify an interception module by including the optional intercept_mod keyword followed by Module, which should be the name of your interception module.
An interception module is expected to export two functions: rewrite_request/2 and rewrite_response/2. The two arguments passed to rewrite_request/2 function are a #http_request{} record and a #headers{} record, whereas rewrite_response/2 function takes a #http_response{} record and also a #headers{} record. You can find definitions for these record types in the yaws_api.hrl header file. Each function can examine each record instance and can either return each original instance or can return a modified copy of each instance in its response. The rewrite_request/2 function should return a tuple of the following form:
{ok, #http_request{}, #headers{}}
and the rewrite_response/2 function should similarly return a tuple of the following form:
{ok, #http_response{}, #headers{}}
A #headers{} record can easily be manipulated in an interceptor using the functions listed below:
yaws_api:set_header/2, yaws_api:set_header/3 yaws_api:get_header/2, yaws_api:get_header/3 yaws_api:delete_header/2
Any failures in your interception module's functions will result in HTTP status code 500, indicating an internal server error.
This directive sets the alternate names for a virtual host. A server alias may contain wildcards:
<server server.domain.com> serveralias = server server2.domain.com server2 serveralias = *.server.domain.com *.server?.domain.com ... </server>
php_handler = <cgi, Filename> - The name of (and possibly path to) the php executable used to interpret php scripts (if allowed).
php_handler = <fcgi, Host:Port> - Use the specified fastcgi server to interpret .php files (if allowed).
php5-cgi -b '127.0.0.1:54321'
This starts a php5 in fastcgi mode listening on the local network interface. To make use of this PHP server from Yaws, specify:
php_handler = <fcgi, 127.0.0.1:54321>
If you need to specify an IPv6 address, use square brackets:
php_handler = <fcgi, [::1]:54321>
The PHP interpreter needs read access to the files it is to serve.
Thus, if you run it in a different security context than Yaws itself, make
sure it has access to the .php files.
Please note that anyone who is able to connect to the php fastcgi server
directly can use it to read any file to which it has read access. You should
consider this when setting up a system with several mutually untrusted
instances of php.
This begins and ends an SSL configuration for this server. It's possible to virthost several SSL servers on the same IP/Port. If SNI support is disabled or not supported, they must share the same certificate configuration. In this situation, it is complicated to virthost several SSL servers on the same IP/Port since the certificate is typically bound to a domainname in the common name part of the certificate. One solution to this problem is to have a certificate with multiple subjectAltNames. If SNI support is enabled, SSL servers on the same IP/Port can have their own SSL configuration with a different SSL certificate for each one. See the global sni directive.
The SNI support was introduced in the SSL application in Erlang/OTP 18.0. It is an extension to the TLS protocol (RFC 4366), which allows the client to include the requested hostname in the first message of its SSL handshake.
See also http://wiki.cacert.org/VhostTaskForce#Interoperability_Test for browser compatibility.
keyfile = File
You might want to use fail_if_no_peer_cert in combination with verify_peer.
ciphers = "[{dhe_rsa,aes_256_cbc,sha,default_prf}, \ {dhe_dss,aes_256_cbc,sha,default_prf}]"
In older versions of Yaws, a cipher tuple lacked the #{prf} element. When Yaws reads a cipher of the old format from configuration, it attempts to convert it to a 4-tuple by adding default_prf for the #{prf} element. Be aware that this may not work for all ciphers; if it fails, manual intervention is needed to properly configure the ciphers in the new format.
eccs = "[sect571r1, sect571k1, secp521r1, brainpoolP512r1, \ sect409k1, sect409r1, brainpoolP384r1, secp384r1, \ sect283k1, sect283r1, brainpoolP256r1, secp256k1, \ secp256r1, sect239k1, xsect233k1, sect233r1, \ secp224k1, secp224r1]"
protocol_version = tlsv1.3, tlsv1.2, tlsv1.1, tlsv1
Default is false.
We can have a series of redirect rules in one of the formats below:
Path = URL Path = code Path = code URL
Path must be an url-decoded path beginning with a slash. URL may be either a relative URL (a path beginning with a slash), or an absolute URL. In the first case, the scheme:hostname:port of the current server will be added. All accesses to Path will be redirected to URL/Path (or scheme:hostname:port/URL/Path if URL is relative). URL must be url-encoded. Note that the original path is appended to the redirected URL.
For example, assume we have the following redirect configuration:
<redirect> /foo = http://www.mysite.org/zapp /bar = /tomato.html </redirect>
Assuming this config resides on a site called http://abc.com, we have the following redirects:
http://abc.com/foo -> http://www.mysite.org/zapp/foo http://abc.com/foo/test -> http://www.mysite.org/zapp/foo/test http://abc.com/bar -> http://abc.com/tomato.html/bar http://abc.com/bar/x/y/z -> http://abc.com/tomato.html/bar/x/y/z
By default, Yaws will perform a 302 redirect. The HTTP status code can be changed using the code parameter. Note that the status code must be known by Yaws.
<redirect> /foo == http://www.mysite.org/zapp /bar = /tomato.html </redirect>
Now a request for http://abc.com/foo/x/y/z simply gets redirected to http://www.mysite.org/zapp. This is typically used when we simply want a static redirect at some place in the docroot.
When we specify a relative URL as the target for the redirect, the redirect will be to the current http(s) server.
docroot = Docroot
This can, for example, be used to implement cookie authentication. The auth() callback would check if a valid cookie header is present, if not it would return {appmod, ?MODULE} and the out401/1 function in the same module would return {redirect_local, "/login.html"}.
md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512
It is possible to use salted hashes. If so, the Salt must be provided, encoded in base64. We can specify multiple users inside a single <auth> </auth> pair.
pam authentication is performed by an Erlang port program which is typically installed as suid root by the Yaws install script.
A full IP address
allow = 10.1.2.3 allow = 192.168.1.104, 192.168.1.205
A network/netmask pair
allow = 10.1.0.0/255.255.0.0
A network/nnn CIDR specification
allow = 10.1.0.0/16
Ordering is one of (Default value is deny,allow):
This mechanism can be used to pass data from a surrounding application into the individual .yaws pages.
This setting applies only for out/1 content, not to static pages or other returned content.
200 OK 201 Created 204 No Content 206 Partial Content 301 Moved Permanently 302 Found 303 See Other 304 Not Modified 307 Temporary Redirect 308 Permanent Redirect
For any other status code, Hdr is not added.
The Module:extra_response_headers/3 function should return either the original header map or a modified map where headers have been added, changed, or deleted. Added headers are not subject to the status code restrictions for the add extra response header directive, but the function can call yaws_api:http_extra_response_headers_add_status_codes/0 to retrieve the list of the status codes for which adding headers is normally allowed.
For response headers that can have multiple settings, such as Set-Cookie, multiple values can be specified in the extra response header map by using a value of {multi, [Value]} where [Value] is a list of one or more header values. The Set-Cookie header is a standard special case for which Yaws converts a multi header into a separate Set-Cookie header for each value; for other headers, Yaws converts a multi header into a single HTTP header with a comma-separated value.
Note that extra response headers do not apply to responses returned directly by any DispatchModule.
GET, HEAD, POST, PUT, DELETE, OPTIONS
RFC 7231 section 4.3 lists the standard HTTP method names:
GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE
An options_asterisk_methods setting can include any of these HTTP method names as well as PATCH. PATCH is not mentioned in RFC 7231 but Yaws supports it. Yaws does not implement CONNECT, but it supports it in options_asterisk_methods because it's possible to implement support for it using a dispatchmod.
If options_asterisk_methods is set to an empty value, Yaws responds to OPTIONS * requests with status 400 Bad Request.
The following example defines a single server on port 80.
logdir = /var/log/yaws <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www </server>
And this example shows a similar setup but two web servers on the same IP address.
logdir = /var/log/yaws <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www </server> <server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org </server>
An example with www-authenticate and no access logging at all.
logdir = /var/log/yaws <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www access_log = false <auth> dir = secret/dir1 realm = foobar user = jonny:verysecretpwd user = benny:thequestion user = ronny:havinganamethatendswithy </auth> </server>
An example specifying a user defined module to be called at startup, as well as some user specific configuration.
<server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org start_mod = btt <opaque> mydbdir = /tmp mylogdir = /tmp/log </opaque> </server>
An example specifying the GSSAPI/SPNEGO module (authmod_gssapi) to be used for authentication. This module requires egssapi version 0.1~pre2 or later available at http://www.hem.za.org/egssapi/.
The Kerberos5 keytab is specified as 'keytab = File' directive in opaque. This keytab should contain the keys of the HTTP service principal, 'HTTP/www.funky.org' in this example.
<server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org start_mod = authmod_gssapi <auth> authmod = authmod_gssapi dir = secret/dir1 </auth> <opaque> keytab = /etc/yaws/http.keytab </opaque> </server>
And finally a slightly more complex example with two servers on the same IP, and one SSL server on a different IP.
When there are more than one server on the same IP, and they have different names the server must be able to choose one of them if the client doesn't send a Host: header. Yaws will choose the first one defined in the conf file.
logdir = /var/log/yaws max_num_cached_files = 8000 max_num_cached_bytes = 6000000 <server www.mydomain.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www </server> <server www.funky.org> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www_funky_org </server> <server www.funky.org> port = 443 listen = 192.168.128.32 docroot = /var/yaws/www_funky_org <ssl> keyfile = /etc/funky.key certfile = /etc/funky.cert password = gazonk </ssl> </server>
Finally an example with virtual directories, vdirs.
<server server.domain> port = 80 listen = 192.168.128.31 docroot = /var/yaws/www arg_rewrite_mod = yaws_vdir <opaque> vdir = "/virtual1/ /usr/local/somewhere/notrelated/to/main/docroot" vdir = "/myapp/ /some/other/path can include/spaces" vdir = "/icons/ /usr/local/www/yaws/icons" </opaque> </server>
The first defined vdir can then be accessed at or under http://server.domain/virtual1/ or http://server.domain/virtual1
Written by Claes Wikstrom
yaws(1) erl(1)