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

Mutual authentication #379

Merged
merged 22 commits into from
Dec 6, 2022
Merged

Conversation

DariusIMP
Copy link
Member

Features

  • Upgraded the async-rustls library, now using rustls 0.20
  • Adapted the zenoh-link-tls package to work with this new version of async-rustls
  • Added two way authentication if configured that way.

How to test the 2 way authentication

Let's create 2 certificates, one for the "server" and one for the "client". For this, it is explained in the zenoh documentation regarding TLS (https://zenoh.io/docs/manual/tls/) how to create certificates using MiniCA.

You can store the certificates as follows, under a certificates folder on your zenoh folder. It should look like this:

certificates
├── client
│   ├── localhost
│   │   ├── cert.pem
│   │   └── key.pem
│   ├── minica-key.pem
│   └── minica.pem
└── server
    ├── localhost
    │   ├── cert.pem
    │   └── key.pem
    ├── minica-key.pem
    └── minica.pem

From your zenoh folder, after having build this branch,

1- run the router with: RUST_LOG=debug cargo run --bin=zenohd -- -c configs/router.json5

2- run a publisher with: RUST_LOG=debug ./target/debug/examples/z_pub -c configs/client.json5

3- run a subscriber with: RUST_LOG=debug ./target/debug/examples/z_sub -c configs/client.json5

where configs/client.json5 is

{
  /// The node's mode (router, peer or client)
  mode: "client",
  connect: {
    endpoints: [ "tls/localhost:7447" ]
  },
  transport: {
    link: {
      tls: {
        root_ca_certificate: "./certificates/client/minica.pem",
        client_auth: true,
        client_private_key: "./certificates/server/localhost/key.pem",
        client_certificate: "./certificates/server/localhost/cert.pem",
      },
    },
  },
}

and configs/router.json5 is:

{
  /// The node's mode (router, peer or client)
  mode: "router",
  listen: {
    endpoints: [ "tls/localhost:7447" ]
  },
  transport: {
    link: {
      tls: {
        client_auth: true,
        root_ca_certificate: "./certificates/server/minica.pem",
        server_private_key: "./certificates/client/localhost/key.pem",
        server_certificate: "./certificates/client/localhost/cert.pem",
      },
    },
  },
}

(see the configs are inside a folder configs under your /zenoh folder).

@Mallets
Copy link
Member

Mallets commented Nov 15, 2022

Hello @DariusIMP ,

In order to accept your PR, you should sign the Eclipse CA first.
Could you please sign it here? https://accounts.eclipse.org/legal/eca/validation/127610

@DariusIMP
Copy link
Member Author

Hello @DariusIMP ,

In order to accept your PR, you should sign the Eclipse CA first. Could you please sign it here? https://accounts.eclipse.org/legal/eca/validation/127610

Done. Also fixed the code for a failing test. I still need to add tests to this PR.

@Mallets
Copy link
Member

Mallets commented Nov 21, 2022

I reckon the benefit of using the latest version (i.e. pointing to git) of async-rustls for security reasons.

However, to be able accept the PR, we need a specific async-rustls dependency (i.e. published on crates.io) in the Cargo.toml to be able in turn to publish zenoh on crates.io.
Unfortunately crates.io does not allow packages to be published with git dependencies.

I've opened an issue on async-rustls to ask for more information about their intended plan: smol-rs/async-rustls#10

io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Outdated Show resolved Hide resolved
io/zenoh-transport/tests/unicast_transport.rs Show resolved Hide resolved
@DariusIMP DariusIMP force-pushed the async-rustls-update branch from 492c9db to 865e02a Compare December 2, 2022 14:31
@DariusIMP DariusIMP marked this pull request as draft December 5, 2022 09:19
@DariusIMP DariusIMP marked this pull request as ready for review December 6, 2022 08:15
@Mallets
Copy link
Member

Mallets commented Dec 6, 2022

I reckon the benefit of using the latest version (i.e. pointing to git) of async-rustls for security reasons.

However, to be able accept the PR, we need a specific async-rustls dependency (i.e. published on crates.io) in the Cargo.toml to be able in turn to publish zenoh on crates.io. Unfortunately crates.io does not allow packages to be published with git dependencies.

I've opened an issue on async-rustls to ask for more information about their intended plan: smol-rs/async-rustls#10

The issue has been closed and async-rustls 0.3.0 has been published 🥳

@Mallets Mallets merged commit 7af3a49 into eclipse-zenoh:master Dec 6, 2022
@DariusIMP DariusIMP deleted the async-rustls-update branch December 6, 2022 15:54
@Ricardicus
Copy link

Ricardicus commented Jan 4, 2023

Thank you for this fix!

Just for future reference, I would like to point out that this set up for testing 2 way authentication only works for the localhost case.

I used this on two containers with their own hostnames and needed another configuration. The fix is valid and works well for this use case as well. For future reference, I'll just specify another layout.

Say we have the hostnames "server" and "client" as above. Then the minica workflow for generating the keys would be like this:

# Getting minica
$ git clone https://github.com/jsha/minica.git
$ cd minica
$ go build
# create CA and server certificates
$ ./minica --domains server,client
$ ./minica --domains client,server
$ find . 
...
./minica-key.pem
./server
./server/cert.pem
./server/key.pem
./minica.pem
./client
./client/cert.pem
./client/key.pem
...

The configuration files

For the server:

{
  mode: "router",
  listen: {
    endpoints: [ "tls/server:7447" ]
  },
  transport: {
    link: {
      tls: {
        client_auth: true,
        root_ca_certificate: "./minica/minica.pem",
	server_private_key: "./minica/server/key.pem",
	server_certificate: "./minica/server/cert.pem",
      },
    },
  },
}

For the client:

{
  mode: "client",
  connect: {
    endpoints: [ "tls/server:7447" ]
  },
  transport: {
    link: {
      tls: {
        client_auth: true,
        root_ca_certificate: "./minica/minica.pem",
        client_private_key: "./minica/client/key.pem",
        client_certificate: "./minica/client/cert.pem",
      },
    },
  },
}

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.

3 participants