BenTasker.co.uk is now available as an Eepsite

I've long felt that it's important to offer a privacy preserving route to view my content - I've no particular need or desire to know who's visiting, and I do sometimes carry content/documentation that censorious states would prefer their citizens not be able to reach.

As a result, www.bentasker.co.uk has been available as a Tor Onion service since 2015 - though admittedly the address changed during that time as a result of Tor shifting to only supporting V3 Onions.

However, Tor is not the only anonymous overlay network, and it's always been my intention to try and add support for I2P too - it's just taken a bit longer than expected to get around to it.

My site is now available as an eepsite, you should be able to reach it at either of the following two addresses

  • gdncgijky3xvocpkq6xqk5uda4vsnvzuk7ke7jrvxnvyjwkq35iq.b32.i2p
  • bentasker.i2p

There are probably some improvements I can make to improve delivery speed, but the eepsite is up and running.

Recent changes to the videos.bentasker.co.uk embed code mean that my video content can be watched on I2P without need for an outproxy. My privacy friendly analytics has also been updated to use I2P as a transport, so that I can spot I2P specific delivery issues and (hopefully) address them.


Handling external references

I'm planning to write a post soon about multi-homing a site onto both the WWW and I2P, so will likely go into more detail then, but one of the things that I needed to try and address was the use of external links to pull in resources such as the video player.

A few days back, I adjusted the videos.bentasker.co.uk embed code so that video content could be delivered via hidden service rather than using exit capacity.

However, that switch occurs after the embed code has first been fetched, so the browser's request flow looks something like this

GET https://videos.bentasker.co.uk/resources/embed/embed.min.js
GET http://dnkpodkuqowld7pnmpt5droubfzgv7tziz2fbiuufpvocbdonobq4xyd.onion/resources/player/player.js
GET http://dnkpodkuqowld7pnmpt5droubfzgv7tziz2fbiuufpvocbdonobq4xyd.onion/2021/20210605_sparkler_b1_w_slowmo/sparkler_b1_w_slowmo.mp4_2000.m3u8

On Tor this works fine, because we can natively reach the clearnet to fetch the initial embed. But, this may not be the case on I2P - not all users have an outproxy configured (in fact, most probably don't).

So, implementing for I2P is a little different: although we still need a supporting change in embed.min.js (to rewrite the address of dependencies and video chunks), we also need switch to use an eepsite address in order to fetch the embed code itself. With a dynamic site, you could hack in some logic, but my site has been static since November 2021.

I decided to implement some Javascript that would

  • Look for <script> tags
  • Check whether they were external
  • Check whether they linked to a domain that I had eepified (so, for now, videos and pfanalytics)
  • Insert a second <script> tag using the eepsite domain instead

You can see the original implementation in the release notes for version 0.19 - it's a thing of beauty.

But, it's also actually massively overengineered. Given that we'll generally only be linking to one of two resources (the embed script, or the analytics agent) there's no good reason to be inserting a copy for every instance of the <script> tag, so the code that's actually live is much, much simpler.

function Clearnet2I2P(){
    if (window.location.hostname.split(".").pop().toLowerCase() != "i2p"){
        /* Nothing to do */
        return;
    }

    // Embed the video script
    s = document.createElement('script');
    s.setAttribute('src', 'http://bapmqkdc7xotvlym3bj75gdb4tlgg2poezkmz36w64qum4racpyq.b32.i2p/resources/embed/embed.min.js');
    s.addEventListener('load',function(){embedBensPlayerDivs()});
    document.body.appendChild(s);        

    // Embed the analytics agent
    s2 = document.createElement('script');
    s2.setAttribute('src', 'http://5es4aj6pfdxoz6oz6vbcczix25dlfelrdav6a6hw7tuudb7kxwba.b32.i2p/agent.js');
    document.body.appendChild(s2);        
}

We still check if we're on an eepsite, but then - rather than messing around with lookups - we just add a reference to each script. It's a little inefficient, in that it means fetching the video embed script even on pages without videos, but it's only about 9KB and the script is highly cacheable (because a lot of users use their own browser with I2P there's a much better chance of cross-session cacheability than with Tor users).

I also needed to change the way that videos are embedded (the other purpose of v0.19) so that it was easier to re-trigger the embed, but that change had been loosely on the books anyway (the old approach was a blocker for implementing Content-Security-Policy headers).


Known Issues

Media in some older posts may not load because certain image types are served via static1.bentasker.co.uk. This is fine on the Clearnet and Tor, but not on I2P as the domain isn't reachable for most users.

The plan is to address this at some point, but I haven't yet decided on a preferred approach. I could do it in Javascript, but that's an issue for anyone with Javascript disabled (using the JS approach is fine for fetching Javascript - if it's disabled you lose nothing - but more problematic for things like images).

The search box at the top of my site is affected by a similar issue: on the Clearnet and Tor it'll take you to duckduckgo.com, but a lot of I2P users won't be able to reach that. Once the Eepsite has been indexed by some of the I2P search engines, I'll probably look at adjusting so that the search submits to one of those (and at the same time, likely also have Tor users go to Duck Duck Go's hidden service).

Although not an issue as such, it's still worth noting: I've registered the shortname bentasker.i2p, however this will only work if your I2P addressbook is up to date (so probably won't be working yet for some users). I only really created it as a memorable convenience: my site does well enough on Tor despite the long/inconvenient onion address, so I'll likely use the b32 name in any integrations to maximise accessibility/availability. I did consider redirecting one to the other, but that feels like an anti-pattern.


Conclusion

My site is now available across three different networks, so can be reached at

There are still some teething issues that'll need resolving, but it should be possible to get the same experience and content on each network. If you do find something that isn't working as it should, please Contact Me.