diff options
author | Yorhel <git@yorhel.nl> | 2018-01-19 15:27:57 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2018-01-19 15:28:09 +0100 |
commit | 96a7a2160efc624318624049840ec67fc0820839 (patch) | |
tree | 178d56e0ec636792c1f903d12279d0b7dccd2f1f /nginx-confgen.pod | |
parent | 65dde6bfe6058080baff90c4bc89bcea49952278 (diff) |
Make this 1.0 + add some docs1.0
Diffstat (limited to 'nginx-confgen.pod')
-rw-r--r-- | nginx-confgen.pod | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/nginx-confgen.pod b/nginx-confgen.pod new file mode 100644 index 0000000..eb71451 --- /dev/null +++ b/nginx-confgen.pod @@ -0,0 +1,223 @@ +=pod + +=head1 NAME + +nginx-confgen - A preprocessor and macro system for nginx(-like) configuration +files. + +=head1 SYNOPSIS + +nginx-confgen <input.conf >output.conf + +=head1 DESCRIPTION + +nginx-confgen can be used to do pre-processing for nginx configuration files +(and other configuration files with a similar syntax). It has support for +"compile-time" macro expansion and variable interpolation, which should make it +less tedious to maintain large and complex configurations. + +nginx-confgen does not currently support any command-line arguments. It simply +reads the configuration from standard input, and writes the processed +configuration to standard output. + +nginx-confgen works by parsing the input into a syntax tree, modifying this +tree, and then formatting the tree to generate the output. It is completely +oblivious to nginx contexts and directives, so it is possible to do nonsensical +transformations and generate incorrect configuration files. Comments in the +input file will not be present in the output. See also the L</BUGS & WARTS> +below. + +B<WARNING:> Do NOT use nginx-confgen with untrusted input, the C<pre_exec> +directive allows, by design, arbitrary code execution. + + +=head1 DIRECTIVES + +nginx-confgen recognizes and interprets the following directives: + +=head2 pre_include + +Similar to the C<include> directive in nginx, except that the file is included +during preprocessing. The included file may contain any preprocessing +directives supported by nginx-confgen. Variables and macros defined in the +included file will be available in the parent file. + +Beware that relative paths are resolved from the working directory that +nginx-confgen is run from. + +=head2 pre_set + +Similar to the C<set> directive in nginx, except that variables defined with +C<pre_set> are resolved during preprocessing. Note that variables defined with +C<pre_set> are only available in the same scope as they are defined, for +example: + + pre_set $var outer; + location / { + pre_set $var inner; + # $var is now "inner" within this location block. + } + # $var is "outer" again after the location block. + +(This may change in the future) + +=head2 pre_exec + +Run a shell command, and store the output in a variable. For example, nginx +will not use your system's DNS resolution methods to resolve domain names. +Instead you need to manually set a C<resolver> address. With the following hack +you can fetch the nameserver from C</etc/resolv.conf> and use that as the +C<resolver>: + + pre_exec $nameserver "grep nameserver /etc/resolv.conf \\ + | head -n 1 | sed 's/^nameserver //'"; + resolver $nameserver; + +(The C<\\> is necessary, otherwise your shell will consider the newline as a +new command). + +=head2 pre_if + +Similar to the C<if> directive in nginx, except that this is evaluated during +preprocessing. nginx-confgen has a few warts with regards to parenthesis, +things usually work better without: + + pre_if -f $certdir/ocsp.der { + ssl_stapling on; + ssl_stapling_file $certdir/ocsp.der; + } + pre_if !-f $certdir/ocsp.der { + ssl_stapling off; + } + + # You can have different configuration depending on the name of + # the system on which nginx-confgen runs. Like... yeah. + pre_exec $hostname 'hostname'; + pre_if $hostname ~* ^proxy_for_(.+) { + proxy_pass http://$1/; + } + +=head2 macro + +Define a I<macro>, which is a configuration block that you can later refer to. +The general syntax is as follows: + + macro macro_name $var1 $var2 @remaining_vars &block_var { + # contents + } + +The optional C<@remaining_vars> argument will capture any number of variables, +and can be passed to another directive inside the macro contents. The optional +C<&block_var> allows the macro to be invoked with a block argument, which will +expand to any number of directives. Some examples: + + macro le { + location /.well-known/acme-challenge { + alias /etc/letsencrypt/challenge; + } + } + # Usage: + le; + + macro redir $path $to { + location $path { + return 301 $to; + } + } + # Usage: + redir / http://blicky.net/; + + macro vhost $primary_name @aliases &block { + server { + listen [::]:443 ssl; + server_name $primary_name @aliases; + ssl_certificate $crtdir/$primary_name/fullchain.pem; + ssl_certificate_key $crtdir/$primary_name/privkey.pem; + █ + } + } + # Usage: + vhost example.com { + root /var/www/example.com; + } + vhost example.org alias.example.org { + root /var/www/example.org; + } + +Note that these are I<hygienic> macros, so variable capture is predictable (but +not necessarily the most useful): + + pre_var $dest /a; + macro redir { + # This will be /a, regardless of the context in which this macro is called. + return 301 $dest; + } + # $dest is still '/a' inside the macro after this new variable definition. + pre_var $dest /b; + redir; + +Similarly, macro arguments will not be available inside C<&block> expansion or +nested macro expansion. + + +=head1 BUGS & WARTS + +nginx-confgen is a quickly written hack to solve a particular use case, it is +quite likely to have some weird behavior and bugs. Here's a few I am aware of: + +=over + +=item * + +Be careful with parenthesis around if statements, e.g.: + + if ($a == $b) { } + +Will get converted into: + + if "(${a}" == "${b})" { } + +Which is unlikely what you want. As a workaround, add some spaces: + + if ( $a == $b ) { } + +=item * + +Arguments to directives may get reformatted, especially if they contain a +variable. This I<should> not matter in most cases, but in some particular +scenarios it does. Here's a few examples of reformatting: + + return 301 http://blicky.net$request_uri; + # becomes: + return 301 "http://blicky.net${request_uri}"; + + add_header Something "${header}"; + # becomes: + add_header Something $header; + +This reformatting may cause different behavior for nginx directives that do not +support variable interpolation, such as C<error_log>. + +=item * + +C<pre_if> does not like empty strings, e.g. + + pre_if $x == "" { } + +Will throw an error, use the following instead: + + pre_if $x { } + +=item * + +The error messages aren't always useful. + +=back + + + +=head1 AUTHOR + +nginx-confgen is written by Yoran Heling <projects@yorhel.nl> + +Web: L<https://dev.yorhel.nl/nginx-confgen> |