Note: The pagekite.net service does not require TLS client authentication, so this HowTo is only useful to folks who are running their own front-end relays.
Version 0.5.4a and later of pagekite.py
are capable of providing a client SSL certificate for authentication in addition to the native PageKite protocol challenge-response methods. However, at the moment there is no native support for checking client certificates. This means that in order to restrict access by certificate it is necessary to use a TLS proxy such as stunnel
(pound
may also work) in combination with pagekite.py
. The proxy will then handle the TLS authentication and encryption work.
This how-to provides one example of how to configure pagekite.py
back- and front-ends, using stunnel
for authentication and openssl
to generate certificates. Note that this document only goes through the steps required to get things "up and running", proper system integration is left as an exercise for the reader.
This is a rough transcript of the commands used to generate a local certificate authority (for signing keys), a certificate for the front-end relay and a certificate for the back-end. This was tested on a Debian system, paths may differ on yours. Output has been omitted.
# Create a working directory
mkdir clientauth
cd clientauth
# Creates a new certificate authority in the subdirectory demoCA
$ /usr/lib/ssl/misc/CA.sh -newca
...
# Generate backend key and certificate signing request
$ openssl genrsa -out backend.key 1024
...
$ openssl req -new -key backend.key -out backend.csr
...
# Do the same for the front-end. Note that in the second step,
# the answer to the common name question is important, as it will
# be checked for validity by the pagekite.py backend.
#
$ openssl genrsa -out frontend.key 1024
...
$ openssl req -new -key frontend.key -out frontend.csr
...
# Sign backend certificate, combine into single .pem
$ cp backend.csr newreq.pem
$ /usr/lib/ssl/misc/CA.sh -sign
...
$ mv newcert.pem backend.crt
$ cat backend.key backend.crt | tee be-cert.pem
# Sign frontend certificate:
$ cp frontend.csr newreq.pem
$ /usr/lib/ssl/misc/CA.sh -sign
...
$ mv newcert.pem frontend.crt
$ cat frontend.key frontend.crt | tee fe-cert.pem
# Make a copy of the CA cert, for convenience
$ cp demoCA/cacert.pem ca-cert.pem
Now you should have three .pem
files, one for the backend, one for the frontend, and one containing the certificate authority's public key.
First, we start stunnel
in a shell:
$ sudo stunnel -f -v 2 \
-A /path/to/ca-cert.pem \
-p /path/to/fe-cert.pem \
-P /path/to/stunnel.pid \
-d 0.0.0.0:443 \
-r localhost:80
Note we are assuming port 80 for pagekite.py
and 443 for stunnel
, replace with whatever values you deem appropriate. You don't need sudo
if you are using non-privileged ports.
In another shell, we start pagekite.py
:
$ sudo pagekite.py --clean --isfrontend \
--ports=80 --protos=http,raw \
--domain=http,raw:EXAMPLE.COM:yourpassword \
--tunnel_acl=allow:localhost
This configures pagekite.py
to only accept tunnel requests originating from localhost, which hopefully means they come from an authenticated stunnel
session or some other trusted source. Other flags you may find useful for restricting access include --host
and --client_acl
, for debugging check out --logfile=stdio
and --debugio
.
Once things are working, you can save the configuration by appending these arguments: --savefile=/path/to/frontend.rc --save
The backend can be run like so:
$ pagekite.py --clean \
--ca_certs=/path/to/ca-cert.pem \
--frontend=EXAMPLE.COM:80 \
--proxy=ssl:/path/to/be-cert.pem@EXAMPLE.COM,commonName:443 \
--backend=http:EXAMPLE.COM:localhost:80:yourpassword
Note that debugging why connections fail is much easier if you also add the following arguments: --logfile=stdio --debugio
Once things are working, you can save the configuration by appending these arguments: --savefile=/path/to/backend.rc --save
Note that pagekite.py
will obey the http_proxy
environment variable if it is set, connecting via. that proxy before chaining through to the SSL proxy on the command line. If you need to connect through a longer chain of proxies, this is also possible by listing multiple --proxy
lines, they will be chained in the order listed.
One potential point of confusion, is that pagekite.py
treats SSL/TLS as a seperate proxy hop. This means if you are connecting through an SSL-secured HTTP proxy, you will need two --proxy
lines to connect through it, first the SSL hop and then the HTTP proxy hop, like so:
$ pagekite.py --clean \
--ca_certs=/path/to/ca-cert.pem \
--frontend=EXAMPLE.COM:80 \
--proxy=ssl:/path/to/be-cert.pem@EXAMPLE.COM,commonName:443 \
--proxy=http:EXAMPLE.COM:443 \
--backend=http:EXAMPLE.COM:localhost:80:yourpassword
This is unnecessary with stunnel
as described above, as it is not an HTTP proxy, it simply forwards all connections directly to pagekite.py
for processing.
Comments