In the last couple of months I tried three approaches to disallow unencrypted HTTP traffic leaving my home network. When Google says the web should be secure by default let's give it a shot.

  1. Disallow outgoing port 80 completly
  2. Intercept outgoing port 80 and redirect it to its HTTPS counterpart
  3. Intercept outgoing port 80 and proxy it to its HTTPS counterpart transparently

Disallowing outgoing port 80 completly

/etc/sysconfig/iptables rule

$ iptables -A FORWARD -i br0 -o enp1s0 -p tcp -m tcp --dport 80 -j REJECT --reject-with icmp-port-unreachable

As one can imagine this broke a lot of things including most update mechanisms like Windows, Linux repo and package updates as well as videostreaming on Amazon's FireTV Stick. The most annoying issue was that typing example.com in ones browser address bar actually means http://example.com.


Intercept outgoing port 80 and redirect it to its HTTPS counterpart

/etc/sysconfig/iptables rule

iptables -A PREROUTING ! -d 192.168.1.0/24 -i br0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:8118

Apache vhost snippet

Listen 192.168.1.1:8118
Listen fe80::20d:b9ff:fe42:63fd%br0:8118
LogFormat "%h %l %u %t \"%m http://%{Host}i%U%q\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" \"%{Cookie}i\"" proxyaccess
<VirtualHost 192.168.1.1:8118>

ServerName home.lan
ServerAlias *

    <Proxy *>
            Order deny,allow
            Allow from all
    </Proxy>

    RewriteEngine on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [NC,R=302,L]


ErrorLog "/var/log/httpd/proxy-error.log"
CustomLog "/var/log/httpd/proxy-access.log" proxyaccess

</VirtualHost>

This interception was quite unnoticeable while normal browsing. Most websites I visit regulary have valid certificates and continued to work. Some special clients however had issues with that. My FireTV Stick fired 30 req/s towards my webserver and ignored the redirect.

192.168.1.183 - - [19/Jan/2019:12:58:59 +0100] "GET /kindle-wifi/wifistub.html HTTP/1.1" 302 361 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)"

Intercept outgoing port 80 and proxy it to its HTTPS counterpart transparently

/etc/sysconfig/iptables rule

iptables -A PREROUTING ! -d 192.168.1.0/24 -i br0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.1:8118

Apache vhost snippet

Listen 192.168.1.1:8118
Listen fe80::20d:b9ff:fe42:63fd%br0:8118
LogFormat "%h %l %u %t \"%m http://%{Host}i%U%q\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" \"%{Cookie}i\"" proxyaccess
<VirtualHost 192.168.1.1:8118>

ServerName cerberus.us.to
ServerAlias *

    <Proxy *>
            Order deny,allow
            Allow from all
    </Proxy>

    RewriteEngine on
    ProxyRequests on
    SSLProxyEngine on
    SSLProxyCipherSuite EECDH+AES:CHACHA20:EDH+AES:!SHA1:!aNULL

    RewriteCond %{HTTP_HOST} ^(.*)?playstation.net$
    RewriteRule ^(.*)$ http://%{HTTP_HOST}$1 [NC,P,QSA,L]

    RewriteCond %{HTTP_HOST} ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$
    RewriteRule ^(.*)$ http://%{HTTP_HOST}$1 [NC,P,QSA,L]

    RewriteCond %{HTTP_HOST} !^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [NC,P,QSA,L]

ErrorLog "/var/log/httpd/proxy-error.log"
CustomLog "/var/log/httpd/proxy-access.log" proxyaccess

</VirtualHost>

This Apache snippet already indicates what needed an exception. *.playstation.net was a CNAME to a CDN and has no valid certificate for that particular name. The second exception is because the FireTV Stick initially resolves some names to a bunch of CloudFront IPs and continues to use solely the IP adresses for some amount of time.

192.168.1.183 - - [20/Jan/2019:18:59:22 +0100] "GET http://52.216.164.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:23 +0100] "GET http://52.216.164.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:24 +0100] "GET http://52.216.169.91/kindle-wifi/wifistub.html" 200 924 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:25 +0100] "GET http://52.216.239.75/kindle-wifi/wifistub.html" 200 924 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:26 +0100] "GET http://52.216.239.75/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:27 +0100] "GET http://52.216.239.75/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:28 +0100] "GET http://52.216.239.75/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:29 +0100] "GET http://52.216.239.75/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:30 +0100] "GET http://52.216.239.75/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:31 +0100] "GET http://52.216.137.188/kindle-wifi/wifistub.html" 200 924 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:32 +0100] "GET http://52.216.137.188/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:33 +0100] "GET http://52.216.137.188/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:34 +0100] "GET http://52.216.137.188/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:35 +0100] "GET http://52.216.137.188/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:36 +0100] "GET http://52.216.137.188/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:37 +0100] "GET http://52.216.165.51/kindle-wifi/wifistub.html" 200 924 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:38 +0100] "GET http://52.216.165.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:39 +0100] "GET http://52.216.165.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:40 +0100] "GET http://52.216.165.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:41 +0100] "GET http://52.216.165.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:42 +0100] "GET http://52.216.165.51/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:43 +0100] "GET http://52.216.132.19/kindle-wifi/wifistub.html" 200 924 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:44 +0100] "GET http://52.216.132.19/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:45 +0100] "GET http://52.216.132.19/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:46 +0100] "GET http://52.216.132.19/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:47 +0100] "GET http://52.216.132.19/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"
192.168.1.183 - - [20/Jan/2019:18:59:48 +0100] "GET http://52.216.132.19/kindle-wifi/wifistub.html" 200 923 "-" "Dalvik/2.1.0 (Linux; U; Android 5.1.1; AFTM Build/LVY48F)" "-"

Streaming with the stick from CloudFront or LimeLight Networks however worked perfectly.


Conclusion

Disabling HTTP completly still has some flaws.

  • despite SNI not every CDN has valid certificates for every name
  • most OCSP requests still use HTTP (OCSP stapling is prefered anyway)

The third approach turned out be pretty useful but I will need to add some more exceptions which are not yet applied.

At last I have to mention two outstanding results which was surprising, one good and one really bad.

My Google Chromecast Ultra did not make a single request using HTTP.

In all 3 cases my iOS online banking app stopped working.

192.168.1.170 - - [20/Jan/2019:17:54:56 +0100] "POST http://s.some-bank.com/ssms-services/asm/rest/device" 200 383 "-" "-" "-"

The request was successfully proxied to its HTTPS counterpart but the app just showed an error. Besides that, its unbelievable that a banking app does unencrypted requests regardless of its content.