Skip to content

Commit 08ad618

Browse files
authored
shttp, skip: use net/http instead of quic-go/http3, support tunneling (#198)
The "default" HTTP package for HTTP over SCION, shttp, now uses HTTP/1 or HTTP/2 based on the net/http standard library. This allows our applications to talk to "normal" (i.e. non-HTTP/3) web servers / clients when suitably proxied/tunneled. Also, this now supports http://, which is useful for quickly running the demo applications without nasty tricks or having to hassle with TLS setup. The existing library for HTTP/3 over SCION is moved to a separate package shttp3, overhauled and reduced to the bare necessities. This will need some additional love to make it useful (and used). Normally HTTP/3 is using the same port as HTTPS but on UDP instead of TCP -- we run both over UDP so we'll have to come up with something to disambiguate. Implement CONNECT in skip to support HTTPS. Change the way that SCION hosts are identified, as the `.scion`-TLD approach is incompatible with HTTPS (wrong name for certificates). Instead, it just looks at the list of hosts for which a SCION address is configured in `/etc/hosts` or `/etc/scion/hosts`. Add a web gateway that acts as a proxy/gateway to allow mirroring some content on the TCP/IP web into the SCION based web.
1 parent 5c51332 commit 08ad618

File tree

22 files changed

+745
-341
lines changed

22 files changed

+745
-341
lines changed

Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ build: scion-bat \
2424
scion-skip \
2525
scion-ssh scion-sshd \
2626
scion-webapp \
27+
scion-web-gateway \
2728
example-helloworld \
2829
example-hellodrkey \
2930
example-shttp-client example-shttp-server example-shttp-fileserver example-shttp-proxy
@@ -33,15 +34,15 @@ clean:
3334
rm -f bin/*
3435

3536
test:
36-
go test -v -tags=$(TAGS) ./...
37+
go test -tags=$(TAGS) ./...
3738

3839
setup_lint:
3940
@# Install golangci-lint (as dumb as this looks, this is the recommended way to install)
4041
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b ${DESTDIR} v1.37.1
4142

4243
lint:
4344
@type golangci-lint > /dev/null || ( echo "golangci-lint not found. Install it manually or by running 'make setup_lint'."; exit 1 )
44-
golangci-lint run --build-tags=$(TAGS) --timeout=2m0s -v
45+
golangci-lint run --build-tags=$(TAGS) --timeout=2m0s
4546

4647
install: all
4748
# Note: install everything but the examples
@@ -107,6 +108,10 @@ scion-sshd:
107108
scion-webapp:
108109
go build -tags=$(TAGS) -o $(BIN)/$@ ./webapp/
109110

111+
.PHONY: scion-web-gateway
112+
scion-web-gateway:
113+
go build -tags=$(TAGS) -o $(BIN)/$@ ./web-gateway/
114+
110115
.PHONY: example-helloworld
111116
example-helloworld:
112117
go build -tags=$(TAGS) -o $(BIN)/$@ ./_examples/helloworld/

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,9 @@ netcat contains a SCION port of the netcat application. See the [netcat README](
139139
Pkg contains underlaying library code for scion-apps.
140140

141141
- appnet: simplified and functionally extended wrapper interfaces for the SCION core libraries
142-
- appquic: a simple interface to use QUIC over SCION
143-
- shttp: a client/server implementation of HTTP/3 over SCION/QUIC
142+
- appquic: a simple interface to use QUIC over SCION
143+
- shttp: glue library to use net/http libraries for HTTP over SCION
144+
- shttp3: glue library to use quic-go/http3 for HTTP/3 over SCION
144145
- integration: a simple framework to support intergration testing for the demo applications in this repository
145146

146147

@@ -161,6 +162,10 @@ Directory ssh contains a SSH client and server running over SCION network.
161162
More documentation is available in the [ssh README](ssh/README.md).
162163

163164

165+
## web-gateway
166+
167+
web-gateway is a SCION web server that proxies web content from the TCP/IP web to the SCION web.
168+
164169
## webapp
165170

166171
Webapp is a Go application that will serve up a static web portal to make it easy to experiment with SCIONLab test apps on a virtual machine.

_examples/shttp/README.md

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,129 +2,140 @@
22

33
This directory contains small example programs that show how HTTP can be used over SCION/QUIC for servers, proxies, and clients:
44

5-
- fileserver: a server that serves the files from its working directory
6-
- proxy: a proxy server that can translate between HTTP and HTTP-over-SCION
75
- server: a server with friendly greetings and other examples
86
- client: a client that talks to the example server
7+
- fileserver: a server that serves the files from its working directory.
8+
This includes an example for serving both HTTP and HTTPS.
9+
- proxy: a proxy server that can translate between HTTP and HTTP-over-SCION
910

1011
See also the package [shttp](../../pkg/shttp/README.md) for the underlaying library code.
1112

1213
## Build:
1314

14-
Clone the repository netsec-ethz/scion-apps and build the eaxample applications:
15-
1615
```
17-
git clone https://github.com/netsec-ethz/scion-apps.git
18-
cd scion-apps
1916
make example-shttp-fileserver \
2017
example-shttp-proxy \
2118
example-shttp-server \
22-
example-shttp-client
19+
example-shttp-client \
20+
scion-bat
2321
```
2422

2523
## Running:
2624

2725
All examples require a running SCION endhost stack, i.e. a running SCION dispatcher and SCION daemon. Please refer to '[Running](../../README.md#Running)' in this repository's main README and the [SCIONLab tutorials](https://docs.scionlab.org) to get started.
26+
See '[Environment](../../README.md#Environment)' on how to set the dispatcher and sciond environment variables when e.g. running multiple local ASes.
2827

29-
### Generic file server example
28+
### Simple server example
3029

31-
Run `example-shttp-fileserver`:
30+
Open a shell in the root of the scion-apps repository and run the `example-shttp-server`:
3231

3332
```
34-
bin/example-shttp-fileserver
33+
bin/example-shttp-server
3534
```
3635

37-
See '[Environment](../../README.md#Environment)' on how to set the dispatcher and sciond environment variables in the server's AS.
38-
39-
Build `scion-bat` as a client for `example-shttp-fileserver`:
36+
Open a new shell and run the custom `example-shttp-client` to interact with the `example-shttp-server`:
4037

4138
```
42-
make scion-bat
39+
bin/example-shttp-client -s 17-ffaa:1:a,127.0.0.1
4340
```
41+
Replace '17-ffaa:1:a' with your server's ISD and AS numbers.
4442

45-
See also the application '[bat](../../bat/README.md)' for more details on the cURL-like CLI tool `scion-bat`.
46-
47-
Access `example-shttp-fileserver` with `scion-bat`:
43+
Alternatively, we can also use the more generic command line HTTP client
44+
`scion-bat` to interact with the `example-shttp-server`. See also the
45+
application '[bat](../../bat/README.md)' for more details on the cURL-like CLI
46+
tool `scion-bat`.
4847

4948
```
50-
bin/scion-bat 17-ffaa:1:a,[127.0.0.1]:443/
49+
bin/scion-bat 17-ffaa:1:a,127.0.0.1/hello
50+
bin/scion-bat 17-ffaa:1:a,127.0.0.1/json
51+
bin/scion-bat -f 17-ffaa:1:a,127.0.0.1/form foo=bar
5152
```
5253

53-
Replace '17-ffaa:1:a' with your server's ISD and AS numbers and see '[Environment](../../README.md#Environment)' on how to set the dispatcher and sciond environment variables in the client's (or proxy's) AS.
54+
### File server example
5455

55-
Run `example-shttp-proxy` to provide `example-shttp-fileserver` functionality via HTTP:
56+
Run `example-shttp-fileserver`:
5657

5758
```
58-
bin/example-shttp-proxy --remote=17-ffaa:1:a,[127.0.0.1]:443 --local=0.0.0.0:8080
59+
bin/example-shttp-fileserver
5960
```
6061

61-
Access `example-shttp-fileserver` via HTTP with `cURL`:
62+
Access `example-shttp-fileserver` with `scion-bat`:
6263

6364
```
64-
curl -v http://127.0.0.1:8080/
65+
bin/scion-bat http://17-ffaa:1:a,127.0.0.1/
6566
```
6667

67-
(Or navigate to http://127.0.0.1:8080/ in a web browser.)
68-
69-
`example-shttp-proxy` can also be used as a proxy from SCION to HTTP, from SCION to SCION, and from HTTP to HTTP. See package [shttp](../../pkg/shttp/README.md) for more details.
7068

71-
### Simple shttp-based server example
69+
### File server example with HTTPS
7270

73-
Open a shell in the root of the scion-apps repository and run `example-shttp-server`:
71+
The file server optionally supports serving via HTTPS.
72+
For this, we need a **hostname** for the server, as a raw SCION address cannot
73+
(currently) be used as the subject of a TLS certificate.
74+
Then, we'll need to create a **key** and obtain a **certificate** for our server.
75+
We use a self signed certificate here and we cheat by installing the self
76+
signed certificate to the host's root CA list.
7477

7578
```
76-
cd _examples/shttp/server
77-
go run .
79+
# echo "1-ff00:0:111,[127.0.0.1] foo-server" >> /etc/scion/hosts
80+
$ mkdir certs; openssl req -newkey rsa:2048 -nodes -keyout certs/server.key -x509 -days 365 -subj '/CN=foo-server' -addext "subjectAltName = DNS:foo-server" -out certs/server.crt
81+
# cp -n certs/server.crt /etc/ssl/certs/ # for ubuntu/debian etc.
7882
```
7983

80-
Open a new shell in the scion-apps repository and access `example-shttp-server` with `scion-bat`:
81-
84+
Then we provide the key/certs for the server at startup:
8285
```
83-
bin/scion-bat 17-ffaa:1:a,[127.0.0.1]:443/hello
86+
bin/example-shttp-fileserver -cert certs/server.crt -key certs/server.key
8487
```
8588

86-
or
87-
89+
And then access it with bat:
8890
```
89-
bin/scion-bat 17-ffaa:1:a,[127.0.0.1]:443/json
91+
bin/scion-bat https://foo-server
9092
```
9193

92-
or
94+
Don't forget to remove `/etc/ssl/certs/server.crt` once you're done.
9395

94-
```
95-
bin/scion-bat -f 17-ffaa:1:a,[127.0.0.1]:443/form foo=bar
96-
```
96+
**Note**: Instead of using a hostname and installing the certificate in the
97+
root CA store, we can also use `scion-bat`'s flag `-insecure=true`, to allow
98+
connections with unchecked certificates. But that's a bit boring, right?
9799

98-
Run the custom `example-shttp-client` for `example-shttp-server`:
99100

100-
```
101-
bin/example-shttp-client -s 17-ffaa:1:a,[127.0.0.1]:443
102-
```
101+
### Proxy example: SCION server, TCP/IP client
102+
103+
The `example-shttp-proxy` is a reverse proxy that can proxy requests on TCP/IP to a SCION web server, or vice versa.
103104

104-
Run `example-shttp-proxy` to provide `bin/example-shttp-server` functionality via HTTP:
105+
Listen on TCP/IP port 8888 and proxy request to a SCION URL, e.g. start the `example-shttp-server` as described above and then
105106

106107
```
107-
bin/example-shttp-proxy --remote=17-ffaa:1:a,[127.0.0.1]:443 --local=0.0.0.0:8080
108+
bin/example-shttp-proxy --port 8888 --remote=http://17-ffaa:1:a,127.0.0.1
108109
```
109110

110-
Access `example-shttp-server` via HTTP with `cURL`:
111+
Now we can access `example-shttp-server` via TCP/IP with `cURL`:
111112

112113
```
113-
curl http://127.0.0.1:8080/hello
114+
curl -sfS http://127.0.0.1:8888/hello
115+
curl -sfS http://127.0.0.1:8888/json
116+
curl -sfS -d foo=bar http://127.0.0.1:8888/form
114117
```
115118

116-
or
119+
And, finally, to see the cute dog picture:
120+
121+
Navigate to http://127.0.0.1:8888/image in a web browser.
122+
123+
### Proxy example: TCP/IP server, SCION client
124+
125+
Listen on SCION port 8888 and proxy request to TCP/IP URL, e.g. https://www.scionlab.org
117126

118127
```
119-
curl http://127.0.0.1:8080/json
128+
bin/example-shttp-proxy --listen-scion --port 8888 --remote=https://www.scionlab.org
120129
```
121130

122-
or
131+
Now we can access www.scionlab.org via SCION with `scion-bat` (note the `Host:www.scionlab.org` directive, alternatively we could add a corresponding hostname entry in the hosts file).
123132

124133
```
125-
curl -d foo=bar http://127.0.0.1:8080/form
134+
bin/scion-bat http://17-ffaa:1:a,127.0.0.1:8888/ Host:www.scionlab.org
126135
```
127136

128-
And, finally, to see the cute dog picture:
137+
or alternatively
129138

130-
Navigate to http://127.0.0.1:8080/image in a web browser.
139+
```
140+
bin/scion-bat --proxy http://17-ffaa:1:a,127.0.0.1:8888/ http://www.scionlab.org
141+
```

_examples/shttp/client/main.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package main
1616

1717
import (
18-
"crypto/tls"
1918
"flag"
2019
"fmt"
2120
"io/ioutil"
@@ -37,16 +36,14 @@ func main() {
3736
os.Exit(2)
3837
}
3938

40-
// Create a standard server with our custom RoundTripper
39+
// Create a standard client with our custom Transport/Dialer
4140
c := &http.Client{
42-
Transport: shttp.NewRoundTripper(&tls.Config{InsecureSkipVerify: true}, nil),
41+
Transport: shttp.DefaultTransport,
4342
}
44-
// (just for demonstration on how to use Close. Clients are safe for concurrent use and should be re-used)
45-
defer c.Transport.(shttp.RoundTripper).Close()
4643

4744
// Make a get request
4845
start := time.Now()
49-
query := fmt.Sprintf("https://%s/hello", *serverAddrStr)
46+
query := fmt.Sprintf("http://%s/hello", *serverAddrStr)
5047
resp, err := c.Get(shttp.MangleSCIONAddrURL(query))
5148
if err != nil {
5249
log.Fatal("GET request failed: ", err)
@@ -57,8 +54,11 @@ func main() {
5754
log.Printf("\nGET request succeeded in %v seconds", end.Sub(start).Seconds())
5855
printResponse(resp)
5956

57+
// (just for demonstration on how to use Close. Clients are safe for concurrent use and should be re-used)
58+
c.CloseIdleConnections()
59+
6060
start = time.Now()
61-
query = fmt.Sprintf("https://%s/form", *serverAddrStr)
61+
query = fmt.Sprintf("http://%s/form", *serverAddrStr)
6262
resp, err = c.Post(
6363
shttp.MangleSCIONAddrURL(query),
6464
"application/x-www-form-urlencoded",

_examples/shttp/fileserver/main.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package main
1818

1919
import (
2020
"flag"
21-
"fmt"
2221
"log"
2322
"net/http"
2423
"os"
@@ -28,12 +27,16 @@ import (
2827
)
2928

3029
func main() {
31-
port := flag.Uint("p", 443, "port the server listens on")
30+
certFile := flag.String("cert", "", "Path to TLS server certificate for optional https")
31+
keyFile := flag.String("key", "", "Path to TLS server key for optional https")
3232
flag.Parse()
3333

3434
handler := handlers.LoggingHandler(
3535
os.Stdout,
3636
http.FileServer(http.Dir("")),
3737
)
38-
log.Fatal(shttp.ListenAndServe(fmt.Sprintf(":%d", *port), handler, nil))
38+
if *certFile != "" && *keyFile != "" {
39+
go func() { log.Fatal(shttp.ListenAndServeTLS(":443", *certFile, *keyFile, handler)) }()
40+
}
41+
log.Fatal(shttp.ListenAndServe(":80", handler))
3942
}

0 commit comments

Comments
 (0)