Halt pollLoop when PollingPacketConn is closed.
[champa.git] / README
blob1dd7fb7c9d170b04764906ca17fa257dd40921bc
1 Champa – general-purpose proxy through an AMP cache
2 David Fifield <david@bamsoftware.com>
3 Public domain
6 Champa is a pair of programs—champa-client and champa-server—that
7 implements a proxy tunnel over an AMP cache, with the goal of
8 circumventing Internet censorship. It is not limited to tunneling HTTP;
9 it encodes data into HTTP requests that satisfy the requirements of AMP.
11 AMP ("Accelerated Mobile Pages") is a framework for mobile web pages.
12 AMP pages are written in a restricted subset of HTML. An
13 [AMP cache](https://amp.dev/documentation/guides-and-tutorials/learn/amp-caches-and-cors/how_amp_pages_are_cached/)
14 is a cache and proxy for AMP HTML pages: it forwards HTTP requests from
15 a client to an origin server, and relays HTTP responses back to the
16 client, while enforcing the requirement that responses be written in AMP
17 HTML. Champa transforms a specialized AMP cache proxy into a
18 general-purpose proxy.
20 Access through an AMP cache normally exposes the domain name of the
21 origin server in the hostname of the URL by which the cache is accessed.
22 To hide the origin server from an observer, the champa-client supports
23 domain fronting to make it appear to an external observer that you are
24 accessing a different domain. When you run champa-client, you provide
25 both the URL of an AMP cache
27 As of 2021, there is really only one option for an AMP cache,
28 [Google AMP Cache](https://developers.google.com/amp/cache/) at
29 https://cdn.ampproject.org/. When you run champa-client, you will
30 therefore always use the `-cache https://cdn.ampproject.org/` option,
31 along with a `-front` option specifying a Google domain for domain
32 fronting.
34 Champa is an application-layer tunnel that runs in userspace. It doesn't
35 provide a TUN/TAP interface; it only connects a local TCP port to a
36 remote TCP port by way of an AMP cache tunnel DNS resolver. It does not
37 itself provide a SOCKS or HTTP proxy interface, but you can get the same
38 effect by running a proxy on the tunnel server and having the tunnel
39 forward to the proxy.
42 ## Tunnel server
44 The server end of the tunnel must be run on a publicly accessible
45 server, outside the censor's zone of control. champa-server is a
46 plaintext HTTP server. It is meant to listen on localhost, behind a
47 reverse web proxy that can provide TLS to incoming traffic, such as
48 Apache or Nginx.
50 Compile champa-server:
51 ```
52 tunnel-server$ cd champa-server
53 tunnel-server$ go build
54 ```
56 Generate a keypair that will be used for end-to-end confidentiality and
57 integrity with tunnel clients. The server needs to keep a copy of the
58 private key. Each clients needs a copy of the public key.
59 ```
60 tunnel-server$ ./champa-server -gen-key -privkey-file server.key -pubkey-file server.pub
61 privkey written to server.key
62 pubkey  written to server.pub
63 ```
65 Run champa-server. In this example `127.0.0.1:8080` is the port that the
66 HTTP server will listen on. `127.0.0.1:7001` is the TCP address to which
67 incoming tunneled connection will be forwarded—this can be a proxy
68 server, for example.
69 ```
70 tunnel-server$ ./champa-server -privkey-file server.key 127.0.0.1:8080 127.0.0.1:7001
71 ```
73 Next, you need to configure a reverse web proxy to connect
74 champa-server's HTTP port to the outside world. Below are instructions
75 for how to do this using Apache and Nginx on Debian. The examples assume
76 that you have already installed a web server and configured it to answer
77 requests for the domain example.com. Clients will access the server at
78 the URL `https://example.com/champa/` (through an AMP cache).
81 ### Apache reverse proxy
83 For general information on configuring a reverse proxy with Apache, see
84 https://httpd.apache.org/docs/current/howto/reverse_proxy.html#simple.
86 Configure the server to use TLS, if it does not already. You can do this
87 using Certbot:
88 ```
89 tunnel-server$ apt install python3-certbot-apache
90 tunnel-server$ certbot
91 ```
93 Enable the proxy_http Apache module. Although not required, you probably
94 also want to enable the http2 module.
95 ```
96 tunnel-server$ a2enmod proxy_http http2
97 ```
99 Find the `<VirtualHost>` directive, and add a new `<Location>` directive
100 with the path prefix you want to reserve for Champa traffic (here,
101 `"/champa/"`). Add `ProxyPass` and `ProxyPassReverse` directives
102 pointing to champa-server's HTTP listening port. You may also want to
103 disable logging for requests under the path prefix.
105 <VirtualHost *:443>
106         ServerName example.com
107         <Location "/champa/">
108                 ProxyPass http://127.0.0.1:8080/
109                 ProxyPassReverse http://127.0.0.1:8080/
110                 SetEnv nolog
111         </Location>
112         CustomLog ${APACHE_LOG_DIR}/access.log combined env=!nolog
113 </VirtualHost>
116 Restart Apache:
118 tunnel-server$ apache2ctl restart
122 ### Nginx reverse proxy
124 For general information on configuring a reverse proxy with Nginx, see
125 https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/#passing-a-request-to-a-proxied-server.
127 Configure the server to use TLS, if it does not already. You can do this
128 using Certbot:
130 tunnel-server$ apt install python3-certbot-nginx
131 tunnel-server$ certbot
134 Find the `server` directive, and add a new `location` directive with the
135 path prefix you want to reserve for Champa traffic (here, `/champa/`).
136 Add a `proxy_pass` directive pointing to champa-server's HTTP listening
137 port. The trailing slash in the URL after `proxy_pass` is important. You
138 may also want to disable logging for requests under the path prefix. Add
139 `http2` to the `listen` directives, if it is not there already.
141 server {
142         server_name example.com;
143         location /champa/ {
144                 proxy_pass http://127.0.0.1:8080/;
145                 proxy_redirect default;
146                 access_log off;
147         }
148         listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
149         listen 443 ssl http2; # managed by Certbot
153 Restart Nginx:
155 tunnel-server$ nginx -s reload
159 ## Tunnel client
161 Compile champa-client:
163 tunnel-client$ cd champa-client
164 tunnel-client$ go build
167 Copy the server's public key (server.pub) to the client. You don't need
168 the private key (server.key) on the client.
170 Run champa-server.
172 tunnel-client$ ./champa-client -pubkey-file server.pub -cache https://cdn.ampproject.org/ -front www.google.com https://example.com/champa/ 127.0.0.1:7000
175 The champa-client command line requires five pieces of information:
176 * `-pubkey-file server.pub`
177   The server's public key.
178 * `-cache https://cdn.ampproject.org/`
179   The URL of the AMP cache to proxy through.
180 * `-front www.google.com`
181   The externally visible domain name to use when connecting to the AMP
182   cache. You can use a Google-operated domain here.
183 * `https://example.com/champa/`
184   The URL of the tunnel server.
185 * `127.0.0.1:7000`
186   The local TCP port that will receive connections and forward them
187   through the tunnel.
189 In this example, connections to 127.0.0.1:7000 on the tunnel client
190 will be tunneled through the AMP cache at https://cdn.ampproject.org/
191 with www.google.com as a domain front, arriving at the tunnel server at
192 https://example.com/champa/, which will then forward the tunneled
193 connections to its own 127.0.0.1:7001.
196 ## How to make a proxy
198 Champa is only a tunnel: it connects a local TCP port to a remote TCP
199 port in a hard-to-detect way. What you connect to those ports is your
200 choice, but generally it will be some kind of proxy.
203 ### Ncat HTTP proxy
205 [Ncat](https://nmap.org/ncat/) has a simple built-in HTTP/HTTPS proxy,
206 good for testing. Be aware that Ncat's proxy isn't intended for use by
207 untrusted clients; it won't prevent them from connecting to localhost
208 ports on the tunnel server, for example.
211 tunnel-server$ ncat -l -k --proxy-type http 127.0.0.1 7001
212 tunnel-server$ ./champa-server -privkey-file server.key 127.0.0.1:8080 127.0.0.1:7001
215 On the client, have the tunnel client listen on 127.0.0.1:7000, and
216 configure your applications to use 127.0.0.1:7000 as an HTTP proxy.
219 tunnel-client$ ./champa-client -pubkey-file server.pub -cache https://cdn.ampproject.org/ -front www.google.com https://example.com/champa/ 127.0.0.1:7000
220 tunnel-client$ curl --proxy http://127.0.0.1:7000/ https://wtfismyip.com/text