731 karma · joined April 28, 2011
https://www.github.com/firezone/firezone
Reach me: jamil AT firezone.dev
[ my public key: https://keybase.io/jamilbk; my proof: https://keybase.io/jamilbk/sigs/er-2zgQKQlBJEqbqmSFS2pxF01P8Hw5icoZ9WtUWxcE ]
If you're embarking upon a refactoring / rewriting journey for your docs, the only advice I'd share is to actually read the website beginning to end before starting. Especially this page: https://diataxis.fr/complex-hierarchies/. The guide is (unsurprisingly) very well written, and it's easy to internalize the concepts because they're repeated often.
Two related contexts that I've found to be much more friendly for this:
1. Climbing gyms, for reasons mentioned previously
2. The sauna! Actually very ideal for convos with strangers. Max overlap time is ~15 minutes, people are generally relaxed, no phones to distract and if it doesn't go well either party can always leave.
Kudos to Rivian for making this a supported user privacy feature.
We've switched to CDC using Postgres which emits into another (non-replicated) write-optimized table. The replication connection maintains a 'subject' variable to provide audit context for each INSERT/UPDATE/DELETE. So far, CDC has worked very well for us in this manner (Elixir / Postgrex).
I do think soft-deletes have their place in this world, maybe for user-facing "restore deleted" features. I don't think compliance or audit trails are the right place for them however.
If the source code is available for you to fork, modify, and maintain as you see fit, what's the complaining really about?
libp2p [4] may be what you're after if you want something geared more towards general purpose connectivity.
[1] https://datatracker.ietf.org/doc/html/rfc8445
[2] https://github.com/pion/webrtc
We do have a self-hosted community support channel on Discord if you are feeling adventurous: https://discord.gg/DY8gxpSgep
I would recommend starting here with a local development cluster:
https://github.com/firezone/firezone/blob/main/docs/CONTRIBU...
https://github.com/firezone/firezone/issues/3553
We didn't invent these techniques. Host candidates are part of standard ICE:
https://datatracker.ietf.org/doc/html/rfc8445#section-5.1.1....
It took a couple iterations to get it right - lots of fun edge cases involved. We ended up having to build automatic NAT64 and 46 for DNS resources to handle some of them. We wrote a post on how this works: https://www.firezone.dev/blog/how-dns-works-in-firezone
In terms of attributes for allowing access, we currently support time-based, country/region-based, auth method, and IP-based, with more planned: https://www.firezone.dev/kb/deploy/policies#conditional-acce...
Erlang/OTP has so far been an excellent platform to build on for a product like Firezone. We chose it specifically for its reputation for powering soft realtime systems. Phoenix Channels are an added bonus that allow us to push all updates where they need to go, in just a few hundred lines of code.
We couldn't be happier with the stack choice.
We're trying to stay focused on keeping policies easy to define and manage so that access management is... manageable as you scale. That and the fact data doesn't go through the cloud / intermediary have been a couple of the reasons customers say they prefer us.
Definitely an exciting space to be building in!
In terms of scalability, are you referring to throughput or simply the complexity of policy management as the number of resources grows?
void
sigdie(const char *fmt,...)
{
#ifdef DO_LOG_SAFE_IN_SIGHAND
va_list args;
va_start(args, fmt);
do_log(SYSLOG_LEVEL_FATAL, fmt, args);
va_end(args);
#endif
_exit(1);
}
to this: void
sshsigdie(const char *file, const char *func, int line, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
sshlogv(file, func, line, 0, SYSLOG_LEVEL_FATAL, fmt, args);
va_end(args);
_exit(1);
}
which lacks the #ifdef.What could have prevented this? More eyes on the pull request? It's wild that software nearly the entire world relies on for secure access is maintained by seemingly just two people [2].
[1] https://github.com/openssh/openssh-portable/commit/752250caa...
[2] https://github.com/openssh/openssh-portable/graphs/contribut...
In our case, we call into Rust from Kotlin using JNI [0] and Swift using swift-bridge [1]. Thankfully our use case for the FFI [2] is for non-performance-critical calls and the data structures are fairly simple, so we just serialize objects with JSON.
No major issues so far.
One thing I am surprised hasn't been mentioned so far is Mozilla's UniFFI [3] which seems to solve some of the issues brought up in the article. We plan to switch to that once our FFI requirements become more complex.
[0] https://docs.rs/jni/latest/jni/
[1] https://github.com/chinedufn/swift-bridge
[2] https://www.firezone.dev/kb/architecture/tech-stack#client-a...
In the time it takes to research the timing behavior of your runtime, you could have reached for a constant-time comparison instead.
Similarly, in the time it takes you to reach the conclusion the comparison you're using isn't vulnerable, you could have reached for a secure compare instead.
I'm not convinced this post makes a compelling case against the best practice of always using a secure compare for secret strings.