Hey All; 

I just got Alt-Svc to mostly-work for my blog at https://dropsafe.crypticide.com/

Here's what I did, and why:

I set up a dummy interface on my blogserver (for rationale/instructions, see link below)

$ grep osite0 /etc/hosts
169.254.255.253 osite0.onion
$ ifconfig dummy0
dummy0: flags=195<UP,BROADCAST,RUNNING,NOARP>  mtu 1500
        inet 169.254.255.253  netmask 255.255.255.252  broadcast 169.254.255.255
$ ping -c 1 osite0.onion
PING osite0.onion (169.254.255.253) 56(84) bytes of data.
64 bytes from osite0.onion (169.254.255.253): icmp_seq=1 ttl=64 time=0.167 ms
 
Set up an onion service, pointing at the dummy interface (rather than localhost or the machine's physical network interface):

HiddenServiceDir /path/to/wherever
HiddenServicePort 80 osite0.onion:80
HiddenServicePort 443 osite0.onion:443
HiddenServiceVersion 3
HiddenServiceNumIntroductionPoints 3

Configured Apache:

# Set ALT_SVC_PORT explicitly because SERVER_PORT fails curiously
SetEnv ALT_SVC_PORT 443
SetEnv ALT_SVC_ONION kfq56...trimmed...o6uqd.onion
SetEnv ALT_SVC_MAXAGE 600
# Set the Alt-Svc header if the request has not arrived via EOTK;
# You almost certainly do not need to do this, it's specific to EOTK development.
# EOTK sets "X-From-Onion: 1" so if that value is empty, set the flag to true:
RewriteCond %{HTTP:X-From-Onion} ^$
RewriteRule ^ - [ENV=USE_ALT_SVC:true]
# ...maybe put other tests here, and then eventually we do:
Header set 'Alt-Svc' 'h2="%{ALT_SVC_ONION}e:%{ALT_SVC_PORT}e"; ma=%{ALT_SVC_MAXAGE}e; persist=1' env=USE_ALT_SVC

Enabled HTTP/2 on my Apache server (it's not enabled by default):

# a2enmod http2 # ...after adding "Protocols h2 http/1.1" to the vhost config
# systemctl restart apache2

...then I found this error message in /var/log/apache2/error.log: 

The mpm module (prefork.c) is not supported by mod_http2. The mpm determines how things are processed in your server. HTTP/2 has more demands in this regard and the currently selected mpm will just not do. This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive.

Bother.  I found mpm_prefork really was enabled by default, and was a hard dependency for php7.0 operation (necessary for Wordpress):

# apache2ctl -M | grep mpm

Then I found this answer: https://serverfault.com/a/904115 ...which told me how to fix this by swapping over to mpm_event and php_fpm. I followed the instructions (needed to tweak the cited path for the ProxyPassMatch line) and tested that the header was being generated and looks sane, via my TorBrowser's tor daemon:

$ curl --http1.1 -x socks5h://127.0.0.1:9150/ -I https://dropsafe.crypticide.com/ | grep -i Alt-Svc
Alt-Svc: h2="kfq56...trimmed...o6uqd.onion:443"; ma=600; persist=1

The test required the --http1.1 option for curl, otherwise if the curl client negotiated a h2 connection, I wouldn't apparently see any of the options in a greppable manner.

Re: the dummy interface, as described elsewhere:

https://github.com/alecmuffett/the-onion-diaries/blob/master/basic-production-onion-server.md

...the joy of using a dummy interface in this fashion is that all connections from the Tor daemon to a webserver on the same machine will be logged as coming "from" the IP address of the dummy interface. This means that you can track accesses that arrive via the Alt-Svc onion connection, separately from all the others:

$ grep 169.254 www-dropsafe-access.log
169.254.255.253 - - [22/Sep/2018:23:05:48 +0000] "GET / HTTP/1.1" 200 231583 "-" "curl/7.54.0"

...which provides the otherwise-missing information of whether the Alt-Svc Onion Link is actually being used.

Setting up a dummy interface on Ubuntu is fairly easy, but on Raspbian was a pain because dhcpcd gets in the way; eventually I just disabled dhcpcd and went back to /etc/network/interfaces, which was okay because my blog server only has static addresses. I'm still not entirely convinced that everything is working as expected/desired, but I'll update again when I am more certain.

The blog is also available via EOTK at https://dropsafe.dropsafezeahmyho.onion/ - requires SSL acceptance.

Best of luck.

    - alec

--