From a7cb73e38777d97ec143fee535a478584b3f7ab9 Mon Sep 17 00:00:00 2001 From: Alec Muffett Date: Mon, 17 May 2021 21:20:54 +0100 Subject: [PATCH] commit: first cut. --- .gitignore | 1 - demo.d/example.tconf | 10 ++++- demo.d/wikipedia.tconf | 80 -------------------------------------- docs.d/HOW-TO-INSTALL.md | 30 ++++++++------ lib.d/do-configure.pl | 1 + lib.d/lint.pl | 1 + templates.d/nginx.conf.txt | 34 +++++++++++++--- 7 files changed, 58 insertions(+), 99 deletions(-) delete mode 100644 demo.d/wikipedia.tconf diff --git a/.gitignore b/.gitignore index 544098c..d2c93bb 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ __* *~ -? .DS_Store !demo.d/*.tconf diff --git a/demo.d/example.tconf b/demo.d/example.tconf index 2fe0633..4f20656 100644 --- a/demo.d/example.tconf +++ b/demo.d/example.tconf @@ -35,7 +35,15 @@ # set x_from_onion_value 1 # When you're proving SSL ownership, you may want arbitrary text -# strings to be returned for a GET upon an arbitrary "/path" regexp +# strings to be returned for a GET upon an arbitrary "/path" +# +# set ssl_proof_csv \ +# /.well_known/fookey1,fooval1 \ +# /.well_known/fookey2,fooval2 + +# ...and a similar, more generic, regular-expression-based solution +# for fixed strings to be returned for a GET upon an arbitrary +# location (restricted to HTTPS-only) # # set hardcoded_endpoint_csv ^/regexp/pattern/?$,stringvalue ... diff --git a/demo.d/wikipedia.tconf b/demo.d/wikipedia.tconf deleted file mode 100644 index 1f15e6c..0000000 --- a/demo.d/wikipedia.tconf +++ /dev/null @@ -1,80 +0,0 @@ -# -*- conf -*- -# eotk (c) 2017 Alec Muffett - -# CSVs of canonical domains (eg: email) to preserve (todo: more here?) -# nb: you must explicitly list all domains that are of preservation; -# "foo.com" & "www.foo.com" are treated as separate, for this purpose -set preserve_csv \ - tld-wp,wikipedia\\.org,i,wikipedia.org \ - tld-wm,wikimedia\\.org,i,wikimedia.org - -# FIX THIS TO USE A LOCAL RESOLVER, BECAUSE PERFORMANCE -set nginx_resolver \ - 8.8.8.8 \ - 8.8.4.4 \ - ipv6=off - -# cache persistence & size; sized for RaspberryPi (256m) -set nginx_cache_seconds 60 -set nginx_cache_size 256m -set nginx_tmpfile_size 64m - -# proof-of-concept: let's make this read-only: -set suppress_methods_except_get 1 - -# proof-of-concept: block access to some hosts -set block_host_re \ - ^(login|donate)\\. - -# proof-of-concept: block access to some paths -set block_path_re \ - /User: \ - /Special:(UserLogin|(Create|Merge)Account|RenameRequest)\\b - -# proof-of-concept: block requests where parameters have certain values -set block_param_re \ - title,^User: \ - title,^Special:(UserLogin|(Create|Merge)Account|RenameRequest)\\b - -# proof-of-concept: blacklist requests to some paths -set path_blacklist_re \ - ^\\. \ - ^\\w+\\.php$ \ - \\.(sql|gz|tgz|zip|bz2)$ \ - ^server-status$ - -# proof-of-concept: whitelist reasonable user-agents (anything else => ded) -set user_agent_whitelist_re \ - ^Mozilla.*Gecko - -# suggestion: you might want to investigate "no_cache_content_type" or -# "no_cache_host" if you want limitations on caching... - -# demo: CSV list to implement ownership proof URIs for EV SSL issuance -# set hardcoded_endpoint_csv \ -# ^/proof/foo/?$,"FOOPROOF" \ -# ^/proof/bar/?$,"BARPROOF" - -# demo: magic cookie-issuing URL to restrict access until ready to launch -# set cookie_lock /open-sesame - -# index of other onion sites ("what happens in onion, should stay in onion") -foreignmap facebookcorewwwi facebook.com -foreignmap nytimes3xbfgragh nytimes.com - -# the Wikimedia Foundation have lots of sites -set project wikipedia -hardmap %NEW_ONION% mediawiki.org -hardmap %NEW_ONION% wikidata.org -hardmap %NEW_ONION% wikimedia.org -hardmap %NEW_ONION% wikimediafoundation.org -# the following have an `m` subdomain -hardmap %NEW_ONION% wikibooks.org m -hardmap %NEW_ONION% wikinews.org m -hardmap %NEW_ONION% wikipedia.org m -hardmap %NEW_ONION% wikiquote.org m -hardmap %NEW_ONION% wikisource.org m -hardmap %NEW_ONION% wikiversity.org m -hardmap %NEW_ONION% wikivoyage.org m -hardmap %NEW_ONION% wiktionary.org m -# nb: by subdomain we mean FOO in en.FOO.wikipedia.org, etc. diff --git a/docs.d/HOW-TO-INSTALL.md b/docs.d/HOW-TO-INSTALL.md index 8260c6e..710dab0 100644 --- a/docs.d/HOW-TO-INSTALL.md +++ b/docs.d/HOW-TO-INSTALL.md @@ -121,20 +121,28 @@ rendering these issues moot. ## IMPORTANT: if all of your "proof" URLs have DIFFERENT pathnames? -Small amounts of plain-text page content may be embedded using -regular-expressions for pathnames; this is done using -`hardcoded_endpoint_csv` and the following example will emit -`FOOPROOF` (or `BARPROOF`) for accesses to `/www/.well_known/foo` or -`../.well_known/bar` respectively, ignoring trailing slashes. Note -the use of double-backslash to escape "dots" in the regular -expression, and use of backslash-indent to continue/enable several -such paths. +Small amounts of plain-text page content may be embedded using small, +fixed pathname strings; this is done using `ssl_proof_csv` and the +following example will emit `FOOPROOF` (or `BARPROOF`) for accesses to +`/www/.well_known/foo` (or `.../bar`) respectively. + +Note: unlike the previous mechanism which was based on the +regular-expression-based `hardcoded_endpoint_csv`, these strings are +checked verbatim against the location, so that `/.well_known/FOO` +becomes `location = "/.well_known/FOO" {...}` in the NGINX +configuration. + +Also, as an improvement to the previous mechanism, these endpoints are +available in **both** HTTP and HTTPS, irrespective of the state of +the `force_ssl` setting. + +Example code: ``` # demo: CSV list to implement ownership proof URIs for EV SSL issuance -set hardcoded_endpoint_csv \ - ^/www/\\.well_known/foo/?$,"FOOPROOF" \ - ^/www/\\.well_known/bar/?$,"BARPROOF" +set ssl_proof_csv \ + /.well_known/FOO,FOOPROOF \ + /.well_known/BAR,BARPROOF ``` ## IMPORTANT: if all your "proof" URLs have THE SAME pathname? diff --git a/lib.d/do-configure.pl b/lib.d/do-configure.pl index 32936ef..13b830e 100755 --- a/lib.d/do-configure.pl +++ b/lib.d/do-configure.pl @@ -619,6 +619,7 @@ my @set_blank = qw( referer_blacklist_re referer_whitelist referer_whitelist_re + ssl_proof_csv tor_intros_per_daemon user_agent_blacklist user_agent_blacklist_re diff --git a/lib.d/lint.pl b/lib.d/lint.pl index 70a243b..79d9a0f 100755 --- a/lib.d/lint.pl +++ b/lib.d/lint.pl @@ -129,6 +129,7 @@ my %known = 'SOFTMAP_TOR_WORKERS' => 1, 'SSL_DIR' => 1, # where ssl certs for the current project live 'SSL_MKCERT' => 1, + 'SSL_PROOF_CSV' => 1, 'SSL_TOOL' => 1, 'SUPPRESS_HEADER_CSP' => 1, 'SUPPRESS_HEADER_HPKP' => 1, diff --git a/templates.d/nginx.conf.txt b/templates.d/nginx.conf.txt index b83d23f..311f82f 100644 --- a/templates.d/nginx.conf.txt +++ b/templates.d/nginx.conf.txt @@ -608,6 +608,17 @@ http { # tor2web not suppressed %%ENDIF + %%IF %SSL_PROOF_CSV% + # ssl_proof: 1=fixed_path,2=response + %%CSV %SSL_PROOF_CSV% + location = "%1%" { + return 200 "%2%"; + } + %%ENDCSV + %%ELSE + # no ssl_proof + %%ENDIF + # tell the client to try again as HTTPS without ever leaving the onion # use 307 / temporary redirect because your URIs may change in future # use $host (not $server) to copy-over subdomains, etc, transparently @@ -670,15 +681,26 @@ http { # no "hello-onion" endpoint %%ENDIF - %%IF %HARDCODED_ENDPOINT_CSV% - # hardcoded_endpoints: 1=path_re,2=response - %%CSV %HARDCODED_ENDPOINT_CSV% - location ~ "%1%" { - return 200 %2%; + %%IF %SSL_PROOF_CSV% + # ssl_proof: 1=fixed_path,2=response + %%CSV %SSL_PROOF_CSV% + location = "%1%" { + return 200 "%2%"; } %%ENDCSV %%ELSE - # no hardcoded_endpoints + # no ssl_proof + %%ENDIF + + %%IF %HARDCODED_ENDPOINT_CSV% + # hardcoded_endpoint: 1=path_re,2=response + %%CSV %HARDCODED_ENDPOINT_CSV% + location ~ "%1%" { + return 200 "%2%"; + } + %%ENDCSV + %%ELSE + # no hardcoded_endpoint %%ENDIF %%IF exists templates.d/nginx-site-%ONION_ADDRESS%.conf