solidproxy

package module
v0.0.0-...-5842ef2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2017 License: MIT Imports: 22 Imported by: 0

README

solidproxy

Build Status Coverage Status Go report GoDoc

Agent/Proxy server with authentication (for WebID-TLS delegation) that can be used as a micro-service along a Solid server.

Installation

Using the source code on Github

go get -u github.com/deiu/solidproxy/proxy-server

Using the Docker image

Note: The docker image is configured to run on HTTP by default. This means that you should set up a reverse proxy using Nginx or Apache, and handle the HTTPS configuration there.

First, you have to pull the docker image:

docker pull deiu/solidproxy

Next, create a file called env.list in which you set the configuration variables (read below to find more about them).

Once you're done with the config, save the file and run the docker image:

docker run --env-file ./env.list -p <host_proxyport>:<container_proxyport> -p <host_agentport>:<container_agentport> deiu/solidproxy

Replace the above port values with your own port numbers from your configuration.

Configuration for standalone server or docker image

Solidproxy uses environment variables (for docker compatibility).

  • SOLIDPROXY_VERBOSE [default false] -- enables logging to stderr
  • SOLIDPROXY_INSECURE [default false] -- accept bad certificates (self-signed, expired, etc.) when connecting to remore servers
  • SOLIDPROXY_PROXYPORT [default 3129]-- the default port for the proxy service
  • SOLIDPROXY_AGENTPORT [default 3200]-- the default port for the agent WebID service
  • SOLIDPROXY_AGENT -- the URL (WebID) of the agent (in case it's on a different server). This is important if you want to use the proxy for delegation of authenticated requests.
  • SOLIDPROXY_ENABLEPROXYTLS -- enable HTTPS for the proxy service
  • SOLIDPROXY_ENABLEAGENTTLS -- enable HTTPS for the agent service
  • SOLIDPROXY_TLSKEY -- path to the TLS key file (using PEM format)
  • SOLIDPROXY_TLSCERT -- path to the TLS cert file (using PEM format)

Example:

export SOLIDPROXY_VERBOSE="1"
export SOLIDPROXY_INSECURE="1"

export SOLIDPROXY_PROXYPORT="3129"
export SOLIDPROXY_AGENTPORT="3200"

export SOLIDPROXY_AGENT="https://example.org:3200/webid#me"

export SOLIDPROXY_ENABLEPROXYTLS="1"
export SOLIDPROXY_ENABLEAGENTTLS="1"
export SOLIDPROXY_TLSKEY="test_key.pem"
export SOLIDPROXY_TLSCERT="test_cert.pem"
User profile configuration

For the delegated authentication to work, you need to indicate that you trust and use a third party agent to authenticate and perform requests on your behalf.

This is just a simple matter of adding the following triple to your WebID profile:

<https://bob.com/profile#me> <http://www.w3.org/ns/auth/acl#delegates> <https://example.org:3200/webid#me> .

This triple says that you delegate the agent with the WebID https://example.org:3200/webid#me.

Usage

The app spawns two servers. One that serves the proxy on port 3129 and route /proxy by default (i.e. example.org:3129/proxy). And another one on port 3200 and route webid (i.e. example.org:3200/webid), which serves the agent's WebID profile for authenticated requests.

Running as a micro-service

If you want to use the proxy, your Solid server needs to forward requests to the following URL:

https://example.org:3129/proxy?uri=https://alice.com/foo/bar

Say your Solid is available at https://bob.com/. You need to configure it so that it forwards all requests it receives at https://bob.com/proxy to the solidproxy server running at https://bob.com:3129/proxy.

Aditionally, if you want to use the delegation feature of the server, you need to specify the user on whose behalf the request is made. To do this, your server needs to set the User header to the WebID of the user.

For example, if your server considers Bob to be authenticated and wants to perform a request on Bob's behalf, then it will set the User header to Bob's WebID: https://bob.com/webid#me as seen below.

GET /proxy?uri=https://alice.com/foo/bar HTTP/1.1
Host: example.org:3129
User: https://bob.com/webid#me
...
Running as a library

Here is a short example showing how you can use the proxy as a library in your own Go project.

package main

import (
	"log"
	"net/http"
	"os"

	"github.com/deiu/solidproxy"
)

func main() {
	mux := http.NewServeMux()

	// Init logger
	logger := log.New(os.Stderr, "[debug] ", log.Flags()|log.Lshortfile)

	// Next we create a new (local) agent object with its corresponding key
	// pair and profile document and serve it under /agent
	// Alternatively, we can create a "remote" agent to which we need to 
	// provide a cert (tls.Certificate) you can load from somewhere:
	// agent, err := solidproxy.NewAgent("https://example.org/agent#me")
	// agent.Cert = someTLScert
	
	agent, err := solidproxy.NewAgentLocal("http://localhost:8080/agent#me")
	if err != nil {
		log.Println("Error creating new agent:", err.Error())
		return
	}
	// assign logger
	agent.Log = logger
	
	// Skip verifying trust chain for certificates?
	// Use true when dealing with self-signed certs (testing, etc.)
	insecureSkipVerify := true
	// Create a new proxy object
	proxy := solidproxy.NewProxy(agent, insecureSkipVerify)
	// assign logger
	proxy.Log = logger

	// Prepare proxy handler and serve it at http://localhost:8080/proxy
	mux.HandleFunc("/proxy", proxy.Handler) 

	// The handleAgent is only needed if you plan to serve the agent's WebID
	// profile yourself; it will be available at http://localhost:8080/agent
	mux.HandleFunc("/agent", agent.Handler) 

	logger.Println("Listening...")
	http.ListenAndServe(":8080", mux)
}

Documentation

Index

Constants

View Source
const (
	// ServerVersion is used to display the server version number during HTTP requests
	ServerVersion = "v2.1.3"
	// ServerName is used to display the server name during HTTP requests
	ServerName = "SolidProxy"
)

Variables

This section is empty.

Functions

func CopyHeaders

func CopyHeaders(from http.Header, to http.Header)

CopyHeaders is used to copy headers between two http.Header objects (usually two request/response objects)

func GetServerFullName

func GetServerFullName() string

GetServerFullName returns the concatenated server name and version

func GetServerName

func GetServerName() string

GetServerName returns the current server name

func GetServerVersion

func GetServerVersion() string

GetServerVersion returns the current server version

func InitLogger

func InitLogger(verbose bool) *log.Logger

InitLogger is used to initialize the log system; if verbose is set to false, it will discard all messages

func NewAgentHandler

func NewAgentHandler(config *ServerConfig, agent *Agent) http.Handler

NewAgentHandler creates a new http.Handler object using the provided server configuration and agent object

func NewAgentProfile

func NewAgentProfile(exp string, mod string) string

NewAgentProfile returns a new WebID profile document for the agent

func NewClient

func NewClient(skip bool) *http.Client

NewClient creates a new http.Client object to be used for fetching resources. The skip parameter is used to indicate if the client should ship server certificate verification.

func NewProxyHandler

func NewProxyHandler(config *ServerConfig, proxy *Proxy) http.Handler

NewProxyHandler creates a new server handler

func NewRSAKey

func NewRSAKey(bits int) (*rsa.PrivateKey, string, string, error)

NewRSAKey creates a new RSA key pair

func NewRSAcert

func NewRSAcert(uri string, name string, priv *rsa.PrivateKey) (*tls.Certificate, error)

NewRSAcert creates a new RSA x509 self-signed certificate to use for WebID-TLS authentication

func NewTLSConfig

func NewTLSConfig(config *ServerConfig) (*tls.Config, error)

NewTLSConfig creates an new tls.Config object based on the provided server configuration

func SetRequestTimeout

func SetRequestTimeout(sec int)

SetRequestTimeout sets the timeout value in seconds for all request

func WebIDFromBytes

func WebIDFromBytes(cert []byte) (string, error)

WebIDFromBytes takes a certificate and extracts the subjectAlternativeName value from it.

func WebIDFromCert

func WebIDFromCert(cert *tls.Certificate) (string, error)

WebIDFromCert returns a WebID value (URI) from a given tls.Certificate

func WebIDFromReq

func WebIDFromReq(req *http.Request) (string, error)

WebIDFromReq takes an http.Request object and extracts the WebID value (URI) from it

Types

type Agent

type Agent struct {
	WebID   string
	Profile string
	Cert    *tls.Certificate
	Key     *rsa.PrivateKey
	Log     *log.Logger
}

Agent is a structure which contains all the information necessary for WebID-TLS auth.

func NewAgent

func NewAgent(uri string) (*Agent, error)

NewAgent creates a new agent object using an existing WebID (URI)

func NewAgentLocal

func NewAgentLocal(uri string, bits ...int) (*Agent, error)

NewAgentLocal creates a new agent object together with a full profile and certificate

func (*Agent) Handler

func (agent *Agent) Handler(w http.ResponseWriter, req *http.Request)

Handler function handles requests for the agent's WebID profile document

func (*Agent) NewAgentClient

func (agent *Agent) NewAgentClient(skip bool) *http.Client

NewAgentClient creates a new http.Client to be used for agent requests. The skip parameter is used to indicate if the client should ship server certificate verification.

func (*Agent) NewRSAAuthorizationHeader

func (agent *Agent) NewRSAAuthorizationHeader(auth *RSAAuthentication) (string, error)

NewRSAAuthorizationHeader returns a new Authorization header for WebID-RSA auth

type Proxy

type Proxy struct {
	HTTPClient      *http.Client
	HTTPAgentClient *http.Client
	Log             *log.Logger
	Agent           *Agent
}

Proxy is a structure that encapsulates both clients (agent and fetcher), agent object and logger object.

func NewProxy

func NewProxy(agent *Agent, skip bool) *Proxy

NewProxy returns a new Proxy object based on the provided agent configuration. The skip parameter is used to indicate if the client should ship server certificate verification.

func (*Proxy) Handler

func (p *Proxy) Handler(w http.ResponseWriter, req *http.Request)

Handler is the main HTTP handler for the proxy/agent server.

func (*Proxy) NewRequest

func (p *Proxy) NewRequest(req *http.Request, body []byte, user string, authenticated bool, authHeader string) (*http.Response, error)

NewRequest creates a new HTTP request for a given resource and user.

type RSAAuthentication

type RSAAuthentication struct {
	Source, Nonce, Username string
}

RSAAuthentication structure

func ParseRSAAuthenticateHeader

func ParseRSAAuthenticateHeader(header string) (*RSAAuthentication, error)

ParseRSAAuthenticateHeader parses an Authenticate header and returns an RSAAuthentication object

type RSAAuthorization

type RSAAuthorization struct {
	Source, Username, Nonce, Signature string
}

RSAAuthorization structure

type ServerConfig

type ServerConfig struct {
	Verbose            bool
	InsecureSkipVerify bool
	Version            string
	Agent              string
	EnableTLS          bool
	TLSKey             string
	TLSCert            string
	Port               string
}

ServerConfig contains all the configuration parameters for the proxy server

func NewServerConfig

func NewServerConfig() *ServerConfig

NewServerConfig creates a new ServerConfig object with a few default settings

type Signer

type Signer interface {
	Sign(data []byte) ([]byte, error)
}

Signer creates signatures that verify against a public key.

func ParseRSAPrivatePEMKey

func ParseRSAPrivatePEMKey(pemBytes []byte) (Signer, error)

ParseRSAPrivatePEMKey parses a PEM encoded private key and returns a Signer.

type Verifier

type Verifier interface {
	Verify(data []byte, sig []byte) error
}

Verifier verifies signatures against a public key.

func ParseRSAPublicPEMKey

func ParseRSAPublicPEMKey(pemBytes []byte) (Verifier, error)

ParseRSAPublicPEMKey parses a PEM encoded private key and returns a new verifier object

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL