Giter Club home page Giter Club logo

lsaas's Introduction

Local network security as a service (LSaaS)

Note: this service is currently offline, and it will stay offline for the foreseeable future.

This free service allows you to obtain a publicly trusted TLS certificate for your local network service (e.g. a MusicBot instance).

It works by creating a subdomain pointing to the local IP you supplied, solving a DNS-01 challenge and giving you the certificate signed by Let's Encrypt.

Motivation

Imagine you want to distribute a network service that's deployed in the respective local network of your users. Let's say the service is now available at the IP 192.168.1.52. To properly encrypt connections to that service, you'll want to use HTTPS. The problem is: HTTPS relies on your server serving a trusted certificate. To achieve that, you have two options:

  1. Create a self-signed certificate and install it on every single client device.
  2. Create a DNS entry for some domain pointing to the local IP and obtain a publicly trusted certificate for that domain (e.g. through LetsEncrypt).

Using option 1 is easy to set up server-side, but requires access to every client device and may be unreasonably cumbersome on some devices. It's essentially deferring the setup to every single end user.

Using option 2 requires your user โ€“ that's the one who sets up the server software โ€“ to set up his own (sub-)domain. It's unreasonable to expect your users to own a domain to deploy your software in their local network. Obtaining a certificate for that domain would then require solving a DNS-01 challenge, as the domain isn't available from outside the local network. Solving that either requires your user to obtain the certificate themselves or giving your software access to modify the domain's DNS entries, which requires more trust from the user than should be required to use your software. It also adds another pile of complexity to your local software because it has to access different DNS registrar APIs.

How LSaaS works

This project provides a public API that receives a list of your local IP addresses (e.g. 10.0.0.42, 192.168.178.14) and then performs all steps necessary to serve your local service at those IP addresses using a unique subdomain with a valid TLS certificate (equivalent of option 2 above). To achieve that it performs the following steps:

  • Create a new subdomain as your namespace: request-id.kiu.party
  • Obtain a wildcard certificate for that subdomain (*.request-id.kiu.party) from LetsEncrypt
  • Create DNS A and/or AAAA records for your supplied IPs (encoded-ip.request-id.kiu.party)
  • Give you the certificate and the names of the created domains
  • Delete the certificate so you're the only one in possession of it

Using this service of course requires you to trust this service not to create more certificates for "your" subdomain/namespace and not to delete the DNS records before expiration. That's because the created subdomains are technically still under full control of the domain owner, who's also the service provider.

Self-hosting the service

The infrastructure for this service is described as code in the terraform directory, so it's theoretically possible to easily host the service yourself. The code is geared towards a very specific setup though: It assumes you're hosting the service itself on AWS (using API Gateway + Lambda), and use Cloudflare for DNS management.

Requesting an instance certificate

Send a request containing up to 20 IP address groups with up to 5 IP addresses each and the desired key format to the service:

POST https://instance.kiu.party

{
    "ips": [
        "192.168.178.42",
        // These three will be associated with the same domain
        ["192.168.0.142", "10.0.0.2", "fde4:8dba:82e1::"]
    ],
    // Can be "pem", "p12" or "jks". Defaults to "pem" if missing.
    "keyFormat": "pem"
}

The IP addresses must be a private/local. Publicly available IP addresses will be rejected.

You'll get a response containing your new subdomains and a token to retrieve your certificate:

{
    "wildcardDomain": "*.your-random-subdomain.instance.kiu.party",
    "domains": [
      {
        "domain": "first.your-random-subdomain.instance.kiu.party",
        "ips": ["192.168.178.42"]
      },
      {
        "domain": "second.your-random-subdomain.instance.kiu.party",
        "ips": ["192.168.0.142", "10.0.0.2", "fde4:8dba:82e1:0000:0000:0000:0000:0000"]
      }
    ],
    "token": "your-super-secret-token",
    "keyFormat": "pem"
}

Retrieving your certificate

Solving the ACME-Challenge to get a certificate from Let's Encrypt might take a few minutes. You'll have to check whether the certificate is ready yet until the process is done. The recommended checking interval is 10 seconds.

Your request body should contain the token from the previous step:

GET https://instance.kiu.party/your-super-secret-token

While the certificate is still being requested, the response will be:

{
    "hasCertificate": false
}

When the process is done, you'll get a response containing the certificate for your subdomain. You'll only get a successful response once, afterwards the certificate and private key are deleted from the server and you are the only one who has it. Keep your private key secret as it allows any holder of it to impersonate you.

Depending on the requested key format, exactly one of the keys pem, p12 or jks will be present. For p12 and jks keys, your token will be the keystore passphrase.

{
    "hasCertificate": true,
    "pem": {
        "crt": "Base64-encoded-certificate",
        "key": "Base64-encoded-private-key"
    },
    "p12": {
        "p12": "Base64-encoded-p12-file"
    },
    "jks": {
        "jks": "Base64-encoded-jks-file"
    }
}

Certificate expiration

The certificate you'll receive is valid for 90 days and cannot be renewed. When your certificate expires, your subdomain DNS records will be deleted and you'll have to request a new domain and certificate.

lsaas's People

Contributors

bjoernpetersen avatar felixgail avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

felixgail

lsaas's Issues

Allow multiple IP addresses per domain

The way I currently aim to do this is the following:

  • Accept multiple IPs in the POST request
  • Create a domain suffix for the request: <requestId>.instance.kiu.party
  • Create a subdomain for each IP <ipderived>.<requestId>.instance.kiu.party
  • Request a wildcard certificate for the domain suffix from Let's Encrypt
  • Return the certificate and a list of all domains to the client

That way clients can use a single key/certificate for any local IPs they might have, which would be very hard to manage otherwise.

No Wildcard certificate?

Websites prove their identity via certificates. Firefox does not trust this site because it uses a certificate that is not valid for 192.168.178.120.2a10228b-c5dd-401a-8a62-fb4feb26e225.instance.kiu.party. The certificate is only valid for *.2a10228b-c5dd-401a-8a62-fb4feb26e225.instance.kiu.party.

Error code: SSL_ERROR_BAD_CERT_DOMAIN

Wrong format

Altough specified by the readme as

"domains": [
      {
        "domain": "first.some-random-subdomain.instance.kiu.party",
        "ip": "192.168.178.42"
      }
]

the initial request returns a response with the schema shown below

"domains":[
    "192.168.178.120.18aeb99f-7a5e-4a81-8af9-4d40e515ff33.instance.kiu.party"
]

Accept multiple IP addresses per domain

Since there may be multiple IP addresses per network interface (especially IPv4 and IPv6), it should possible to group IP addresses that should be associated with the same subdomain.

I propose changing the request schema to allow for the following structure:

{
  "ips": [
    "10.0.0.2",
    ["192.168.178.42", "192.168.178.43"]
  ]
}

where 192.168.178.42 and 192.168.178.43 would be associated with the same subdomain.

Use standard Authorization header for token in GET request

Using a header instead of putting the token in the path would be better style, as request paths tend to end up in logs. Since a token is more or less single-use, that's not really a big deal though.

This change will be backwards compatible, i.e. the current method won't be removed.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • Lock file maintenance

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/deploy.yml
  • actions/checkout v3
  • actions/setup-python v4
  • hashicorp/setup-terraform v2
gradle
jks/build.gradle.kts
  • com.github.ben-manes.versions 0.44.0
  • com.amazonaws:aws-lambda-java-core 1.2.2
  • io.sentry:sentry 6.13.0
gradle-wrapper
jks/gradle/wrapper/gradle-wrapper.properties
  • gradle 7.6
pip_requirements
requirements.txt
  • cloudflare ==2.11.1
  • pendulum ==2.1.2
  • sentry-sdk ==1.14.0
  • sewer ==0.8.3
terraform
terraform/main.tf
  • aws >= 4.0.0, < 5.0.0
  • cloudflare >= 3.0.0, < 4.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.