Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Embedded CAs #42

Merged
merged 19 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ Tunnels BEAST and MLAT data from your client to plane.watch over a TLS tunnel.

## Runtime Configuration

| Option | Environment Variable | Description | Default |
| ------ | -------------------- | ----------- | ------- |
| `--apikey` | `API_KEY` | plane.watch user API Key | *unset* |
| `--beasthost` | `BEASTHOST` | Host to connect to BEAST data | `127.0.0.1` |
| `--beastport` | `BEASTPORT` | Port to connect to BEAST data | `30005` |
| `--mlatserverhost` | `MLATSERVERHOST` | Listen host for `mlat-client` server connection | `127.0.0.1` |
| `--mlatserverport` | `MLATSERVERPORT` | Listen port for `mlat-client` server connection | `30105` |
| `--debug` | `DEBUG` | Enable debug logging | `false` |
| Option | Environment Variable | Description | Default |
|--------------------|----------------------|-------------------------------------------------|-------------|
| `--apikey` | `API_KEY` | plane.watch user API Key | *unset* |
| `--beasthost` | `BEASTHOST` | Host to connect to BEAST data | `127.0.0.1` |
| `--beastport` | `BEASTPORT` | Port to connect to BEAST data | `30005` |
| `--mlatserverhost` | `MLATSERVERHOST` | Listen host for `mlat-client` server connection | `127.0.0.1` |
| `--mlatserverport` | `MLATSERVERPORT` | Listen port for `mlat-client` server connection | `30105` |
| `--debug` | `DEBUG` | Enable debug logging | `false` |

## Installing from Binary

Expand All @@ -28,3 +28,39 @@ Tunnels BEAST and MLAT data from your client to plane.watch over a TLS tunnel.
* Run `go generate ./...` to download required CA certs
* Test: `go test ./...`
* Build & Install: `go build -o /usr/local/bin/pw-feeder ./cmd/pw-feeder`

## Installing CA Certificates

If you receive an error `x509: certificate signed by unknown authority` when `pw-feeder` attempts to connect, you will need to install the [Let's Encrypt CA certificates](https://letsencrypt.org/certificates/).

We provide a helper script to do this on Debian and Ubuntu flavours of Linux. This script can be execute with the following command:

```bash
curl https://raw.githubusercontent.com/plane-watch/pw-feeder/main/install_ca_certs.sh | bash
```

The script uses `sudo`, so you will be prompted to enter your password. If you'd prefer to do this manually, the commands are shown and explained below.

| Command | Explanation |
|-------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------|
| `sudo mkdir -p /usr/share/ca-certificates/letsencrypt` | Create the directory `/usr/share/ca-certificates/letsencrypt` to hold the CA certificates |
| `cd /usr/share/ca-certificates/letsencrypt` | Change into the directory `/usr/share/ca-certificates/letsencrypt` |
| `sudo curl -o isrg-root-x1.crt https://letsencrypt.org/certs/isrgrootx1.pem` | Download the **ISRG Root X1** certificate |
| `sudo curl -o isrg-root-x2.crt https://letsencrypt.org/certs/isrg-root-x2.pem` | Download the **ISRG Root X2** certificate |
| `sudo curl -o lets-encrypt-e5.crt https://letsencrypt.org/certs/2024/e5.pem` | Download the **Let’s Encrypt E5** certificate |
| `sudo curl -o lets-encrypt-e6.crt https://letsencrypt.org/certs/2024/e6.pem` | Download the **Let’s Encrypt E6** certificate |
| `sudo curl -o lets-encrypt-e7.crt https://letsencrypt.org/certs/2024/e7.pem` | Download the **Let’s Encrypt E7** certificate |
| `sudo curl -o lets-encrypt-e8.crt https://letsencrypt.org/certs/2024/e8.pem` | Download the **Let’s Encrypt E8** certificate |
| `sudo curl -o lets-encrypt-e9.crt https://letsencrypt.org/certs/2024/e9.pem` | Download the **Let’s Encrypt E9** certificate |
| `sudo curl -o lets-encrypt-r10.crt https://letsencrypt.org/certs/2024/r10.pem` | Download the **Let’s Encrypt R10** certificate |
| `sudo curl -o lets-encrypt-r11.crt https://letsencrypt.org/certs/2024/r11.pem` | Download the **Let’s Encrypt R11** certificate |
| `sudo curl -o lets-encrypt-r12.crt https://letsencrypt.org/certs/2024/r12.pem` | Download the **Let’s Encrypt R12** certificate |
| `sudo curl -o lets-encrypt-r13.crt https://letsencrypt.org/certs/2024/r13.pem` | Download the **Let’s Encrypt R13** certificate |
| `sudo curl -o lets-encrypt-r14.crt https://letsencrypt.org/certs/2024/r14.pem` | Download the **Let’s Encrypt R14** certificate |
| `sudo curl -o lets-encrypt-e1.crt https://letsencrypt.org/certs/lets-encrypt-e1.pem` | Download the **Let’s Encrypt E1** certificate |
| `sudo curl -o lets-encrypt-e2.crt https://letsencrypt.org/certs/lets-encrypt-e2.pem` | Download the **Let’s Encrypt E2** certificate |
| `sudo curl -o lets-encrypt-r3.crt https://letsencrypt.org/certs/lets-encrypt-r3.pem` | Download the **Let’s Encrypt R3** certificate |
| `sudo curl -o lets-encrypt-r4.crt https://letsencrypt.org/certs/lets-encrypt-r4.pem` | Download the **Let’s Encrypt R4** certificate |
| `cd /usr/share/ca-certificates` | Change into the directory `/usr/share/ca-certificates` |
| `find letsencrypt/ -maxdepth 1 -type f -iname '*.crt' \| sudo tee -a /etc/ca-certificates.conf` | Append the newly downloaded certificates to `/etc/ca-certificates.conf` |
| `sudo update-ca-certificates` | Regenerates ca-certificates.crt, a concatenated single-file list of CA certificates. |
23 changes: 23 additions & 0 deletions install_ca_certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -xe
sudo mkdir -p /usr/share/ca-certificates/letsencrypt
cd /usr/share/ca-certificates/letsencrypt
sudo curl -o isrg-root-x1.crt https://letsencrypt.org/certs/isrgrootx1.pem
sudo curl -o isrg-root-x2.crt https://letsencrypt.org/certs/isrg-root-x2.pem
sudo curl -o lets-encrypt-e5.crt https://letsencrypt.org/certs/2024/e5.pem
sudo curl -o lets-encrypt-e6.crt https://letsencrypt.org/certs/2024/e6.pem
sudo curl -o lets-encrypt-e7.crt https://letsencrypt.org/certs/2024/e7.pem
sudo curl -o lets-encrypt-e8.crt https://letsencrypt.org/certs/2024/e8.pem
sudo curl -o lets-encrypt-e9.crt https://letsencrypt.org/certs/2024/e9.pem
sudo curl -o lets-encrypt-r10.crt https://letsencrypt.org/certs/2024/r10.pem
sudo curl -o lets-encrypt-r11.crt https://letsencrypt.org/certs/2024/r11.pem
sudo curl -o lets-encrypt-r12.crt https://letsencrypt.org/certs/2024/r12.pem
sudo curl -o lets-encrypt-r13.crt https://letsencrypt.org/certs/2024/r13.pem
sudo curl -o lets-encrypt-r14.crt https://letsencrypt.org/certs/2024/r14.pem
sudo curl -o lets-encrypt-e1.crt https://letsencrypt.org/certs/lets-encrypt-e1.pem
sudo curl -o lets-encrypt-e2.crt https://letsencrypt.org/certs/lets-encrypt-e2.pem
sudo curl -o lets-encrypt-r3.crt https://letsencrypt.org/certs/lets-encrypt-r3.pem
sudo curl -o lets-encrypt-r4.crt https://letsencrypt.org/certs/lets-encrypt-r4.pem
cd /usr/share/ca-certificates
find letsencrypt/ -maxdepth 1 -type f -iname '*.crt' | sudo tee -a /etc/ca-certificates.conf
sudo update-ca-certificates
2 changes: 1 addition & 1 deletion pw-feeder/cmd/pw-feeder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var (
Name: "pw-feeder",
Usage: "feed ADS-B data to plane.watch",
Description: `Plane Watch Feeder Client`,
Version: "0.0.3",
Version: "0.0.4",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "apikey",
Expand Down
27 changes: 0 additions & 27 deletions pw-feeder/lib/stunnel/cacerts.go

This file was deleted.

58 changes: 0 additions & 58 deletions pw-feeder/lib/stunnel/stunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,13 @@ package stunnel
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"net"
"strings"
"time"

"github.com/rs/zerolog/log"
)

func addEmbeddedCertsToCertPool(scp *x509.CertPool) error {
// load embedded Let's Encrypt CAs
// get list of files in caCertPEMs embed.FS
pemFiles, err := caCertPEMs.ReadDir(".")
if err != nil {
return err
}

// for each file...
for _, pemFile := range pemFiles {

func() {

log := log.With().Str("cafile", pemFile.Name()).Logger()

// open file
f, err := caCertPEMs.Open(pemFile.Name())
if err != nil {
log.Err(err).Msg("could not open embedded CA cert")
}
defer f.Close()

// get file stat (for size)
s, err := f.Stat()
if err != nil {
log.Err(err).Msg("could not stat embedded CA cert")
}

// read bytes from file
b := make([]byte, s.Size())
n, err := f.Read(b)
if err != nil {
log.Err(err).Msg("could not read embedded CA cert")
}

// parse cert
p, _ := pem.Decode(b[:n])
c, err := x509.ParseCertificate(p.Bytes)
if err != nil {
log.Err(err).Msg("could not parse embedded CA cert")
}

// add cert to system cert pool
scp.AddCert(c)
}()
}
return nil
}

func StunnelConnect(name, addr, sni string) (c *tls.Conn, err error) {

log := log.With().Str("name", name).Str("addr", addr).Logger()
Expand Down Expand Up @@ -96,10 +46,6 @@ func StunnelConnect(name, addr, sni string) (c *tls.Conn, err error) {
log.Err(err).Caller().Msg("could not use system cert pool")
return err
}
err = addEmbeddedCertsToCertPool(scp)
if err != nil {
return err
}

// TODO: fix this
// verify server cert
Expand All @@ -122,10 +68,6 @@ func StunnelConnect(name, addr, sni string) (c *tls.Conn, err error) {
// log.Err(err).Caller().Msg("could not use system cert pool")
return c, err
}
err = addEmbeddedCertsToCertPool(scp)
if err != nil {
return c, err
}

// set up tls config
tlsConfig := tls.Config{
Expand Down
39 changes: 0 additions & 39 deletions pw-feeder/lib/stunnel/stunnel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,45 +33,6 @@ func init() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.UnixDate})
}

func TestCACerts(t *testing.T) {

// get list of files in caCertPEMs embed.FS
pemFiles, err := caCertPEMs.ReadDir(".")
require.NoError(t, err)

// for each file...
for _, pemFile := range pemFiles {
t.Run(pemFile.Name(), func(t *testing.T) {

// open file
f, err := caCertPEMs.Open(pemFile.Name())
require.NoError(t, err)
defer f.Close()

// get file stat (for size)
s, err := f.Stat()
require.NoError(t, err)

// read bytes from file
b := make([]byte, s.Size())
n, err := f.Read(b)
require.NoError(t, err)

// parse cert
p, _ := pem.Decode(b[:n])
c, err := x509.ParseCertificate(p.Bytes)
require.NoError(t, err)

// check validity
assert.True(t, c.NotBefore.Before(time.Now()), "Certificate not yet valid")
assert.False(t, c.NotAfter.Before(time.Now()), "Certificate expired")

// check if certs are due to expire within 90 days
assert.True(t, c.NotAfter.After(time.Now().Add(time.Hour*24*90)), "Certificate expires within 90 days")
})
}
}

func GenerateSelfSignedTLSCertAndKey(keyFile, certFile *os.File) error {
// Thanks to: https://go.dev/src/crypto/tls/generate_cert.go

Expand Down
Loading