Skip to content

Act as HTTP PROXY for http://<cidv1b32>.ipfs.localhost #5982

@lidel

Description

@lidel

Version information:

0.4.18

Type:

feature

Description:

Problem

CID-in-subdomain creates Origin-based isolation if website is loaded from public gateway:

..however we continue to have a single Origin for all websites loaded from local gateway:

This means use of local gateway decreases some of security guarantees web developers are used to, and removes some incentives to run local go-ipfs (and redirect to it via ipfs-companion).

Solution

What if go-ipfs could act as HTTP PROXY for requests made to http://*.ipfs.*/ and http://*.ipns.*/ ?

Having that, IPFS Companion could automatically set Gateway port as PROXY for requests to http://*.ipfs.localhost, which would create very nice URLs for local gateway, solving the Origin problem for local go-ipfs 👌

Initial look at technical feasibility

My hope is that we could keep changes to minimum and reuse Gateway port to also act as HTTP PROXY for requests to *.ipfs.localhost.

In other words, in addition to regular HTTP GET:

$  curl -v 'http://127.0.0.1:8080/ipfs/bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy/'
> GET /ipfs/bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va HTTP/1.1
> Host: 127.0.0.1:8080
< HTTP/1.1 200 OK

Gateway port should also respond to PROXY requests:

$ curl -v --proxy 'http://127.0.0.1:8080' 'http://bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy.ipfs.localhost'
> GET http://bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy.ipfs.localhost/ HTTP/1.1
> Host: bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy.ipfs.localhost

AFAIK all HTTP PROXY needs to do is to support HTTP CONNECT Method (but I think some non-https proxies work even without it):

CONNECT bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy.ipfs.localhost:80 HTTP/1.1 
Host: bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy.ipfs.localhost:80 

After looking at golang's net/http, my initial intuition says it should be possible to detect such requests early via something like:

http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.Method == http.MethodConnect {
        handleProxyRequest(w, r)
    } else {
        handleRegularRequest(w, r)
    }
})

Would love to get some feedback on this idea

I feel this is a huge win for both security and UX, and should be done before we switch to CIDv1 in base32 by default.

As a sidenote: this technique opens us a venue for future support of alternative naming systems such as ENS (*.eth.localhost) or Namecoin (*.bit.localhost).

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions