347 lines
10 KiB
Markdown
347 lines
10 KiB
Markdown
|
---
|
||
|
title: "Site to Site WireGuard: Part 4 - HTTPS"
|
||
|
date: 2019-04-16
|
||
|
series: site-to-site-wireguard
|
||
|
---
|
||
|
|
||
|
# Site to Site WireGuard: Part 4 - HTTPS
|
||
|
|
||
|
This is the fourth post in my Site to Site WireGuard VPN series. You can read the other articles here:
|
||
|
|
||
|
- [Part 1 - Names and Numbers](https://christine.website/blog/site-to-site-wireguard-part-1-2019-04-02)
|
||
|
- [Part 2 - DNS](https://christine.website/blog/site-to-site-wireguard-part-2-2019-04-07)
|
||
|
- [Part 3 - Custom TLS Certificate Authority](https://christine.website/blog/site-to-site-wireguard-part-3-2019-04-11)
|
||
|
- Part 4 - HTTPS (this post)
|
||
|
- Setting up additional iOS, macOS, Android and Linux clients
|
||
|
- Other future fun things (seamless tor2web routing, etc)
|
||
|
|
||
|
In this article, we are going to install [Caddy](https://caddyserver.com) and set up the following:
|
||
|
|
||
|
- A plaintext markdown site to demonstrate the process
|
||
|
- A URL shortener at https://g.o/ (with DNS and TLS certificates too)
|
||
|
|
||
|
## HTTPS and Caddy
|
||
|
|
||
|
[Caddy](https://caddyserver.com) is a general-purpose HTTP server. One of its main features is automatic [Let's Encrypt](https://letsencrypt.org) support. We are using it here to serve HTTPS because it has a very, very simple configuration file format.
|
||
|
|
||
|
Caddy doesn't have a stable package in Ubuntu yet, but it is fairly simple to install it by hand.
|
||
|
|
||
|
## Installing Caddy
|
||
|
|
||
|
One of the first things you should do when installing Caddy is picking the list of extra plugins you want in addition to the core ones. I generally suggest the following plugins:
|
||
|
|
||
|
- [`http.cors`](https://caddyserver.com/docs/http.cors) - [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), because we can't trust browsers
|
||
|
- [`http.git`](https://caddyserver.com/docs/http.git) - it facilitates automatic deployment
|
||
|
- [`http.supervisor`](https://caddyserver.com/docs/http.supervisor) - run background processes
|
||
|
|
||
|
First we are going to need to download Caddy (please do this as root):
|
||
|
|
||
|
```console
|
||
|
curl https://getcaddy.com > install_caddy.sh
|
||
|
bash install_caddy.sh -s personal http.cors,http.git,http.supervisor
|
||
|
chown root:root /usr/local/bin/caddy
|
||
|
chmod 755 /usr/local/bin/caddy
|
||
|
```
|
||
|
|
||
|
These permissions are set as such:
|
||
|
|
||
|
| Facet | Read | Write | Directory Listing |
|
||
|
| :--------------- | :--- | :---- | :---------------- |
|
||
|
| User (root) | Yes | Yes | Yes |
|
||
|
| Group (root) | Yes | No | Yes |
|
||
|
| Others | Yes | No | Yes |
|
||
|
|
||
|
In order for Caddy to bind to the standard HTTP and HTTPS ports as non-root (this is a workaround for the fact that [Go can't currently drop permissions with suid() cleanly](https://github.com/golang/go/issues/1435)), run the following:
|
||
|
|
||
|
```console
|
||
|
setcap 'cap_net_bind_service=+eip' /usr/local/bin/caddy
|
||
|
```
|
||
|
|
||
|
Caddy expects configuration file/s to exist at `/etc/caddy`, so let's create the folders for them:
|
||
|
|
||
|
```console
|
||
|
mkdir -p /etc/caddy
|
||
|
touch /etc/caddy/Caddyfile
|
||
|
chown -R root:www-data /etc/caddy
|
||
|
```
|
||
|
|
||
|
### Let's Encrypt Certificate Permissions
|
||
|
|
||
|
Caddy's systemd unit expects to be able to create new certificates at `/etc/ssl/caddy`:
|
||
|
|
||
|
```console
|
||
|
mkdir -p /etc/ssl/caddy
|
||
|
chown -R www-data:root /etc/ssl/caddy
|
||
|
chmod 770 /etc/ssl/caddy
|
||
|
```
|
||
|
|
||
|
These permissions are set as such:
|
||
|
|
||
|
| Facet | Read | Write | Directory Listing |
|
||
|
| :--------------- | :--- | :---- | :---------------- |
|
||
|
| User (www-data) | Yes | Yes | Yes |
|
||
|
| Group (root) | Yes | Yes | Yes |
|
||
|
| Others | No | No | No |
|
||
|
|
||
|
This will allow only Caddy and root to manage certificates in that folder.
|
||
|
|
||
|
### Custom CA Certificate Permissions
|
||
|
|
||
|
In the [last post](https://christine.website/blog/site-to-site-wireguard-part-3-2019-04-11), custom certificates were created at `/srv/within/certs`. Caddy is going to need to have the correct permissions in order to be able to read them.
|
||
|
|
||
|
```shell
|
||
|
#!/bin/sh
|
||
|
chmod -R 750 .
|
||
|
chown -R root:www-data .
|
||
|
chmod 600 minica-key.pem
|
||
|
```
|
||
|
|
||
|
Then mark it executable:
|
||
|
|
||
|
```
|
||
|
chmod +x fixperms.sh
|
||
|
```
|
||
|
|
||
|
These permissions are set as such:
|
||
|
|
||
|
| Facet | Read | Write | Execute/Directory Listing |
|
||
|
| :--------------- | :--- | :---- | :------------------------ |
|
||
|
| User (root) | Yes | Yes | Yes |
|
||
|
| Group (www-data) | Yes | No | Yes |
|
||
|
| Others | No | No | No |
|
||
|
|
||
|
This will allow Caddy to be able to read the certificates later in the post. Run this after certificates are created.
|
||
|
|
||
|
```
|
||
|
cd /srv/within/certs
|
||
|
./fixperms.sh
|
||
|
```
|
||
|
|
||
|
### HTTP Root Permissions
|
||
|
|
||
|
I dypically store all of my websites under `/srv/http/domain.name.here`. To create a folder like this:
|
||
|
|
||
|
```console
|
||
|
mkdir -p /srv/http
|
||
|
chown www-data:www-data /srv/http
|
||
|
chmod 755 /srv/http
|
||
|
```
|
||
|
|
||
|
These permissions are set as such:
|
||
|
|
||
|
| Facet | Read | Write | Directory Listing |
|
||
|
| :--------------- | :--- | :---- | :---------------- |
|
||
|
| User (www-data) | Yes | Yes | Yes |
|
||
|
| Group (www-data) | Yes | No | Yes |
|
||
|
| Others | Yes | No | Yes |
|
||
|
|
||
|
### Systemd
|
||
|
|
||
|
To install the [upstream systemd unit](https://github.com/mholt/caddy/blob/master/dist/init/linux-systemd/caddy.service), run the following:
|
||
|
|
||
|
```console
|
||
|
curl -L https://github.com/mholt/caddy/raw/master/dist/init/linux-systemd/caddy.service \
|
||
|
| sed "s/;CapabilityBoundingSet/CapabilityBoundingSet/" \
|
||
|
| sed "s/;AmbientCapabilities/AmbientCapabilities/" \
|
||
|
| sed "s/;NoNewPrivileges/NoNewPrivileges/" \
|
||
|
| tee /etc/systemd/system/caddy.service
|
||
|
chown root:root /etc/systemd/system/caddy.service
|
||
|
chmod 744 /etc/systemd/system/caddy.service
|
||
|
systemctl daemon-reload
|
||
|
systemctl enable caddy.service
|
||
|
```
|
||
|
|
||
|
These permissions are set as such:
|
||
|
|
||
|
| Facet | Read | Write | Execute |
|
||
|
| :----------- | :--- | :---- | :------ |
|
||
|
| User (root) | Yes | Yes | Yes |
|
||
|
| Group (root) | Yes | No | No |
|
||
|
| Others | Yes | No | No |
|
||
|
|
||
|
This will also configure Caddy to start on boot.
|
||
|
|
||
|
* Configure Caddy for static file serving for aloha.pele
|
||
|
* root directive
|
||
|
* browse directive
|
||
|
* Link to Caddy documentation
|
||
|
|
||
|
## Configure aloha.pele
|
||
|
|
||
|
In the last post, we created the domain and TLS certificates for `aloha.pele`. Let's create a website for it.
|
||
|
|
||
|
Open `/etc/caddy/Caddyfile` and add the following:
|
||
|
|
||
|
```
|
||
|
# /etc/caddy/Caddyfile
|
||
|
|
||
|
aloha.pele:80 {
|
||
|
tls off
|
||
|
redir / https://aloha.pele:443
|
||
|
}
|
||
|
|
||
|
aloha.pele:443 {
|
||
|
tls /srv/within/certs/aloha.pele/cert.pem /srv/within/certs/aloha.pele/key.pem
|
||
|
|
||
|
internal /templates
|
||
|
|
||
|
markdown / {
|
||
|
template templates/page.html
|
||
|
}
|
||
|
|
||
|
ext .md
|
||
|
browse /
|
||
|
|
||
|
root /srv/http/aloha.pele
|
||
|
}
|
||
|
```
|
||
|
|
||
|
And create `/srv/http/aloha.pele/templates`:
|
||
|
|
||
|
```console
|
||
|
mkdir -p /srv/http/aloha.pele/templates
|
||
|
chown -R www-data:www-data /srv/http/aloha.pele/templates
|
||
|
```
|
||
|
|
||
|
And open `/srv/http/aloha.pele/templates/page.html`:
|
||
|
|
||
|
```html
|
||
|
<!-- /srv/http/aloha.pele/templates/page.html -->
|
||
|
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>{{ .Doc.title }}</title>
|
||
|
<style>
|
||
|
main {
|
||
|
max-width: 38rem;
|
||
|
padding: 2rem;
|
||
|
margin: auto;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<main>
|
||
|
<nav>
|
||
|
<a href="/">Aloha</a>
|
||
|
</nav>
|
||
|
|
||
|
{{ .Doc.body }}
|
||
|
</main>
|
||
|
</body>
|
||
|
</html>
|
||
|
```
|
||
|
|
||
|
This will give a nice [simple style kind of like this](https://jrl.ninja/etc/1/) using [Caddy's built-in markdown templating support](https://caddyserver.com/docs/markdown). Now create `/srv/http/aloha.pele/index.md`:
|
||
|
|
||
|
```markdown
|
||
|
<!-- /srv/http/aloha.pele/index.md -->
|
||
|
|
||
|
# Aloha!
|
||
|
|
||
|
This is an example page, but it doesn't have anything yet. If you see me, HTTPS is probably working.
|
||
|
```
|
||
|
|
||
|
Now let's enable and test it:
|
||
|
|
||
|
```
|
||
|
systemctl restart caddy
|
||
|
systemctl status caddy
|
||
|
```
|
||
|
|
||
|
If Caddy shows as running, then testing it via [LibTerm](https://itunes.apple.com/us/app/libterm/id1380911705?ls=1&mt=8) should work:
|
||
|
|
||
|
```
|
||
|
curl -v https://aloha.pele
|
||
|
```
|
||
|
|
||
|
## URL Shortener
|
||
|
|
||
|
I have created a simple [URL shortener backend](https://github.com/Xe/surl) on my GitHub. I personally have it accessible at https://g.o for my internal network. It is very simple to configure:
|
||
|
|
||
|
| Environment Variable | Value |
|
||
|
| :------------------- | :--------------------------------- |
|
||
|
| `DOMAIN` | `g.o` |
|
||
|
| `THEME` | `solarized.css` (or `gruvbox.css`) |
|
||
|
|
||
|
surl requires a SQLite database to function. To store it, create a docker volume:
|
||
|
|
||
|
```console
|
||
|
docker volume create surl
|
||
|
```
|
||
|
|
||
|
And to create the surl container and register it for automatic restarts:
|
||
|
|
||
|
```console
|
||
|
docker run --name surl -dit -p 10.55.0.1:5000 \
|
||
|
--restart=always \
|
||
|
-e DOMAIN=g.o \
|
||
|
-e THEME=solarized.css \
|
||
|
-v surl:/data xena/surl:v0.4.0
|
||
|
```
|
||
|
|
||
|
Now create a DNS record for `g.o.`:
|
||
|
|
||
|
```
|
||
|
; pele.zone
|
||
|
|
||
|
;; URL shortener
|
||
|
g.o. IN CNAME oho.pele.
|
||
|
```
|
||
|
|
||
|
And a TLS certificate:
|
||
|
|
||
|
```console
|
||
|
cd /srv/within/certs
|
||
|
minica -domains g.o
|
||
|
./fixperms.sh
|
||
|
```
|
||
|
|
||
|
And add Caddy configuration for it:
|
||
|
|
||
|
```
|
||
|
# /etc/caddy/Caddyfile
|
||
|
|
||
|
g.o:80 {
|
||
|
tls off
|
||
|
|
||
|
redir / https://g.o
|
||
|
}
|
||
|
|
||
|
g.o:443 {
|
||
|
tls /srv/within/certs/g.o/cert.pem /srv/within/certs/g.o/key.pem
|
||
|
|
||
|
proxy / http://10.55.0.1:5000
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Now restart Caddy to load the configuration and make sure it works:
|
||
|
|
||
|
```console
|
||
|
systemctl restart caddy
|
||
|
systemctl status caddy
|
||
|
```
|
||
|
|
||
|
And open [https://g.o](https://g.o) on your iOS device:
|
||
|
|
||
|
<style>
|
||
|
img {
|
||
|
max-width: 400px;
|
||
|
display: block;
|
||
|
margin-left: auto;
|
||
|
margin-right: auto;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
![An image of the URL shortener in action](/static/img/site-to-site-part-4-gdoto.jpg)
|
||
|
|
||
|
You can use the other [directives](https://caddyserver.com/docs) in the Caddy documentation to do more elaborate things. [When Then Zen](https://when-then-zen.christine.website) is hosted completely with [Caddy using the markdown directive](https://github.com/Xe/when-then-zen/blob/master/Caddyfile); but even this is ultimately a simple configuration.
|
||
|
|
||
|
---
|
||
|
|
||
|
This seems like enough for this time. Next time we are going to approach adding other devices of yours to this network: iOS, Android, macOS and Linux.
|
||
|
|
||
|
Please give me [feedback](/contact) on my approach to this. I also have a [Patreon](https://www.patreon.com/cadey) and a [Ko-Fi](https://ko-fi.com/A265JE0) in case you want to support this series. I hope this is useful to you all in some way. Stay tuned for the future parts of this series as I build up the network infrastructure from scratch. If you would like to give feedback on the posts as they are written, please watch [this page](https://github.com/Xe/site/pulls) for new pull requests.
|
||
|
|
||
|
Be well. The sky is the limit, Creator!
|
||
|
|