Skip to content

Feat: mTLS support#26

Merged
oschwartz10612 merged 7 commits into
fosrl:devfrom
progressive-kiwi:feat-mtls-support
Apr 3, 2025
Merged

Feat: mTLS support#26
oschwartz10612 merged 7 commits into
fosrl:devfrom
progressive-kiwi:feat-mtls-support

Conversation

@progressive-kiwi

@progressive-kiwi progressive-kiwi commented Mar 30, 2025

Copy link
Copy Markdown
Contributor

Community Contribution License Agreement

By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.

Description

This PR adds basic support for connecting to servers requiring a client certificate, aka mTLS.
Some restrictions for now (all documented):

  • only p12 and pfx formats
  • key, cert and ca cert must all be present
  • encryption is NOT supported ( because I couldn't find a go module to decrypt all formats without weird error messages that'd be difficult to debug for enduser

How to test?

I am planning on a PR against the pangolin repo too with similar contents, but first, newt :)
(This was tested only on macos so far)

Positive test

  1. Have a pangolin deployment
  2. Generate custom certs. If you want an example, check self-signed-certs-for-mtls.sh
  3. Modify a pangolin server's Traefik dynamic_config.yaml by adding the following
http:
  routers:
    next-router:
     # ...
      tls:
        certResolver: letsencrypt
        options: mtlsConfig
    api-router:
      # ...
      tls:
        certResolver: letsencrypt
        options: mtlsConfig
    ws-router:
      # ...
      tls:
        certResolver: letsencrypt
        options: mtlsConfig

tls:
  options:
      mtlsConfig:
          clientAuth:
              clientAuthType: RequireAndVerifyClientCert
              caFiles:
                  - |
                      -----BEGIN CERTIFICATE-----
                      .... <content of the ca.cert>
                      -----END CERTIFICATE-----
  1. Add the generated client cert, eg alice-at-example-com.eng.12 to your client
  • On a mac
    1. double click, import to KeyChain, using the password. (You could also just import the non-encrypted version)
    2. Right click the imported item, Get Info
    3. Open Trust
    4. Set SSL to Always Trust
  • (Sry, haven't tested this on Linux or Windows, so can't describe )
  1. Visit your admin pangolin portal using a browser supporting mTLS, and select the proposed cert.
  2. Create a new Site, and copy the newt cli command
  3. Start newt with the copied command, with the extra arg: --tls-client-cert=./certs/clients/alice-at-example-com.p12
  4. Verify both in terminal and both in pangolin admin that the site is connected

Negative test

  1. Same as above but run newt without the --tls-client-cert=... arg.
  2. Verify error in terminal, explaining TLS connectivity issue.

@progressive-kiwi progressive-kiwi marked this pull request as draft March 30, 2025 23:12
@progressive-kiwi progressive-kiwi changed the title feat/mtls-support Feat: mTLS support Mar 30, 2025
@progressive-kiwi progressive-kiwi marked this pull request as ready for review March 30, 2025 23:14
@oschwartz10612

Copy link
Copy Markdown
Member

This is an awesome addition thank you for taking the time to work on this!

I was just trying to test and want to just make sure I understand something: if I do not make any change to the traefik config it still seems to work and connect. Is this expected? Like my config is just stock with no cert defined.

sudo ./newt --id sghg4ofa518u2g3 --secret a305klknfgqhj6ons12el2fn5yft42ivj9m6sslr7c3vhq2y --endpoint https://p.fosrl.io --tls-client-cert=./certs/clients/test-at-p-fosrl.io.enc.p12
INFO: 2025/04/01 21:01:05 Loading tls-client-cert ./certs/clients/test-at-p-fosrl.io.enc.p12
INFO: 2025/04/01 21:01:06 Adding tls to req
INFO: 2025/04/01 21:01:06 Loading tls-client-cert ./certs/clients/test-at-p-fosrl.io.enc.p12
INFO: 2025/04/01 21:01:06 Sent registration message
INFO: 2025/04/01 21:01:06 Received registration message
INFO: 2025/04/01 21:01:06 Received: {Type:newt/wg/connect Data:map[endpoint:p.fosrl.io:51820 publicKey:tng9Z/BN32flFjqwwT1yAxN/twFkmgbZA+D9N+YqdjM= serverIP:100.89.128.1 targets:map[tcp:[] udp:[]] tunnelIP:100.89.128.8]}
INFO: 2025/04/01 21:01:06 WireGuard device created. Lets ping the server now...
INFO: 2025/04/01 21:01:06 Ping attempt 1 of 15
INFO: 2025/04/01 21:01:06 Pinging 100.89.128.1
INFO: 2025/04/01 21:01:06 Ping latency: 11.464252ms
INFO: 2025/04/01 21:01:06 Starting ping check

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread websocket/client.go
Comment thread websocket/client.go
Comment thread websocket/config.go
…duplicates, handling null-pointer case and some logging
@progressive-kiwi

progressive-kiwi commented Apr 2, 2025

Copy link
Copy Markdown
Contributor Author

Added one, not feature related fix: at the end of main(), it is possible that the device is not yet initialized, so dev.Close() panics with nil pointer error

@oschwartz10612 oschwartz10612 changed the base branch from main to dev April 3, 2025 01:23
@oschwartz10612 oschwartz10612 merged commit e7c8dbc into fosrl:dev Apr 3, 2025
@oschwartz10612

Copy link
Copy Markdown
Member

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants