summaryrefslogtreecommitdiff
path: root/nginx-confgen.pod
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2018-01-19 15:27:57 +0100
committerYorhel <git@yorhel.nl>2018-01-19 15:28:09 +0100
commit96a7a2160efc624318624049840ec67fc0820839 (patch)
tree178d56e0ec636792c1f903d12279d0b7dccd2f1f /nginx-confgen.pod
parent65dde6bfe6058080baff90c4bc89bcea49952278 (diff)
Make this 1.0 + add some docs1.0
Diffstat (limited to 'nginx-confgen.pod')
-rw-r--r--nginx-confgen.pod223
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;
+ &block;
+ }
+ }
+ # 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>