Yubikey / FIDO?

Hello everyone

I ask more information about Yubikey

i have read YubiKey by Yubico | OpenZiti
and I would like to know to what extent the yubikey can be used with Ziti.
Let me explain, in a multi-service and multi-user context can we choose to assign the yubikey or not? for example if I want User1 and User2 to have access to services XX and YY only accessible via Yubikey but that he can have access to services ZZ without Yubikey.

In addition, how will Ziti react to this, will a popup appear asking to insert the yubikey if the user has not put it in yet?

I'm exploring Ziti because I really like the concept. I placed it behind my Traefik reverse proxy and now I'm looking at all the possibilities to further increase security at the user level (I think that at the server level I'm not too bad thanks to you :))

1 Like

your scenario is possible (in a way):

  • add separate service policy for XX+YY with MFA posture check
  • use yubikey totp feature enable those services

a few caveats:

  • openziti cannot enforce that totp codes must come from a yubikey/hardware device
  • users identity cannot be based on yubikey -- because ZZ service must be accessible without it

thanks for the answer. So if I understand correctly we use the "code" functionality as with Microsoft Authenticator or Google Authentication. It is not yet possible to use the actual Yubico hardware and insert the Yubikey into the USB or NFC to authorize access?

you can use yubikey for hw-based identity, but in that case all services will affected.

So you'd have to have multiple identities. One for those services that require a hardware-based identity, that is, the private key lives in the Yubikey, and another identity for services that do not require the Yubikey, which private key is a regular file. All tunneler apps support multiple identities.

Ziti itself doesn't initiate interactive pinentry for unlocking hardware private key slots, but passes the PIN to libpkcs11 as a query parameter recorded in the Ziti identity configuration file.

Ok thank you for your answer and all information. I don't mind that yubikey is mandatory :slight_smile:

I followed the documentation to the end and I added my Yubikey!

I have two entities created RSA and EC for my user.

After enrollment, I have two JSON files! I may have been too fast because I no longer have the JWT but only the JSON
How do I now add this to the Ziti client to use? because client accept Only JWT file and URL methode dont work...

root@ziti:/home/dejan# ziti edge enroll "/usr/local/lib/Deki-Yubi/Deki-Yubi01_rsa.jwt"
INFO generating 4096 bit RSA key
INFO enrolled successfully. identity file written to: /usr/local/lib/Deki-Yubi/Deki-Yubi01_rsa.json
root@ziti:/home/dejan# ziti edge enroll "/usr/local/lib/Deki-Yubi/Deki-Yubi03_ec.jwt"
INFO generating 4096 bit RSA key
INFO enrolled successfully. identity file written to: /usr/local/lib/Deki-Yubi/Deki-Yubi03_ec.json
root@ziti:/home/dejan#

image

in my yubikey i have sucessfully import 2 certificats

So i have try with tutorial : Enhance your Network Security with Zero Trust and OTP

in windows !

and I'm still confused about how it works... I don't have the JSON this time!

If I register the yubikey with Zidi Edge Desktop even without yubikey I have access to my services :smiley:

C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge>"C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge\ziti-edge-tunnel.exe" enroll -j "C:\Users\Dejan\Downloads\Dejan-Yubi.jwt" -k "pkcs11://C:\Program Files\OpenSC Project\OpenSC\pkcs11\opensc-pkcs11.dll?id=01^&pin=1234" -i "C:\Users\Dejan\AppData\Local\Yubico\yubi.json"
StartServiceCtrlDispatcher failed (1063)
(8124)[        0.000]    INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO
(8124)[        0.000]    INFO ziti-sdk:utils.c:167 ziti_log_init() Ziti C SDK version 1.3.7 @g94225a3(HEAD) starting at (2025-02-07T15:37:41.497)
(8124)[        0.000]    INFO ziti-sdk:ziti_enroll.c:112 ziti_enroll() Ziti C SDK version 1.3.7 @g94225a3(HEAD) starting enrollment at (2025-02-07T15:37:41.500)

C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge>

I will retest on Linux but one thing is not clear. Plus the documentation on the blog: YubiKey by Yubico | OpenZiti

contains commands that don't work :slight_smile:

I made a small BASH script for adding yubi to your commands but I think it's the enrolling that is wrong

I can say that it should work when fully configured, and you found some documentation and a blog post that has drifted from how things currently work. :slightly_smiling_face:

Recap: The Ziti Desktop Edge application will configure Windows DNS and networking so that any process can use the authorized Ziti services. The Ziti identity's private key lives on a YubiKey, so the Ziti services will not work unless it's present.

Drift: The main difference between the info you found and how things work now is that the documented executable no longer exists. That's unsurprising since you saw the (newer) ziti-edge-tunnel.exe.

Here's an overview.

  • Install Ziti Desktop Edge. This includes the (newer) ziti-edge-tunnel.exe, replacing (old) ziti-tunnel.exe.
  • Obtain an enrollment token for a Ziti identity that allows you to use the desired Ziti services.
  • Configure your YubiKey with a private key and certificate you wish to use as a Ziti identity. A self-signed cert issued by YubiKey Manager is fine because you're enrolling with a one-time token.
  • Configure your system with a PKCS#11 driver, e.g. libpkcs11, probably OpenSC.
  • Using YubiKey tools, identify a slot for your Ziti identity's private key and specify a PIN for the slot.
  • Run ziti-edge-tunnel.exe enroll to craft the JSON configuration file with slot and pin details.
  • Move the JSON identity configuration file to ${env:SYSTEMROOT}\System32\config\systemprofile\AppData\Roaming\NetFoundry
  • Restart the Ziti tunnel service by pressing the big button in the UI twice

Over the next few days, I'll see if I can get this working in Windows.

Thank you for the response and details. On Linux I had gone all the way and obtained the JSON but I did not have the detail that it was necessary to place them on Windows in system32.

However, a question that may be of importance is there a difference between enrollment via ziti-edge-tunnel enroll and ziti edge enroll??
Because I used ziti edge enroll in my script and not ziti-edge-tunnel

for information in windows allway block to enroll with same result

StartServiceCtrlDispatcher failed (1063)
(8124)[        0.000]    INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO
(8124)[        0.000]    INFO ziti-sdk:utils.c:167 ziti_log_init() Ziti C SDK version 1.3.7 @g94225a3(HEAD) starting at (2025-02-07T15:37:41.497)
(8124)[        0.000]    INFO ziti-sdk:ziti_enroll.c:112 ziti_enroll() Ziti C SDK version 1.3.7 @g94225a3(HEAD) starting enrollment at (2025-02-07T15:37:41.500)

personally I forget the enrollement on windows with the tunnel lol

so,

root@ziti:/home/dejan# ./ziti-edge-tunnel enroll -j "/usr/local/lib/Dejan_Yubi/Dejan_Yubi03_ec.jwt" -i "/usr/local/lib/Dejan_Yubi/Dejan_Yubi03_ec.json"
(8155)[        0.000]    INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO
(8155)[        0.000]    INFO ziti-sdk:utils.c:169 ziti_log_init() Ziti C SDK version 1.4.4 @g9a16a32(HEAD) starting at (2025-02-09T08:53:48.069)
(8155)[        0.000]    INFO ziti-sdk:ziti_enroll.c:114 ziti_enroll() Ziti C SDK version 1.4.4 @g9a16a32(HEAD) starting enrollment at (2025-02-09T08:53:48.069)
(8155)[        0.000]    INFO ziti-sdk:ziti_ctrl.c:626 ziti_ctrl_init() ctrl[(null):] using https://XXXXX:443
(8155)[        0.000]    INFO ziti-sdk:ziti_ctrl.c:626 ziti_ctrl_init() ctrl[(null):] using https://XXXXX:443
root@ziti:/home/dejan#

I completely redid the process on Linux following the information, and on linux ziti-edge-tunnel works fine !
I generated on the yubikey everything is OK! I save the JSON that I placed in the systeme32 folder and when I launch Ziti Edge it loads my profile created with yubikey! on the other hand, whether the yubikey is there or not he doesn't really care lol that's okay.... :smiley:

Yubi is not plugged and i have access to service :crazy_face:
image

I think I'll stick to the classic MFA with a code lol

1 Like

If you're willing to help me debug this I'd love to know if the enroll command created the expected configuration JSON.

In the JSON, the id.cert and id.key props must contain a pkcs11:// URI with correct slot and pin for your YubiKey PIV. The slot identifier must be the one your PKCS#11 driver expects, even if different from the slot ID that's displayed by YubiKey Manager.

I have not that on json only

and nothing contains pkcs11 URI

A bugfix for enrolling with key/cert from pkcs11 was just published as a pre-release!

I successfully tested enrolling with a private key from a YubiKey with ziti-edge-tunnel 1.5.0 on Linux and Windows. On Windows, here's what I did to fast-forward my ziti-edge-tunnel.exe version to 1.5.0. I don't know if I must rewind the version before upgrading Ziti Desktop Edge.

  1. Downloaded the 1.5.0 ZIP and unzip the EXE in C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge.

  2. Saved an identity enrollment JWT from the Ziti controller in Downloads.

  3. Enrolled by running:

    C:\> "C:\Program Files (x86)\NetFoundry Inc\Ziti Desktop Edge\ziti-edge-tunnel.exe" `
    enroll `
    --jwt C:\Users\w\Downloads\yubikey.jwt `
    --identity C:\Users\w\Downloads\yubikey.json `
    --key "pkcs11:///C:/Program Files/OpenSC Project/OpenSC/pkcs11/opensc-pkcs11.dll?id=1&pin=12345678"
    
  4. Moved the identity config from C:\Users\w\Downloads\yubikey.json to C:\Windows\System32\config\systemprofile\AppData\Roaming\NetFoundry

  5. Restarted the tunnel service.

For future readers, in case this doesn't become documentation, the folder may change from the Windows Service's APPDATA to PROGRAMDATA (link to GitHub issue). I think this means the folder in which to place the enrolled identity configuration JSON file will be a path like C:\ProgramData\NetFoundry.

2 Likes