Skip to content

TSL support #584

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 7 commits into from
May 16, 2024
Merged

TSL support #584

merged 7 commits into from
May 16, 2024

Conversation

josecelano
Copy link
Member

@josecelano josecelano commented May 15, 2024

TSL support. Allow using HTTPs providing the cert and cert key.

TOML

[net]
port = 3001

[net.tsl]
ssl_cert_path = "./storage/index/lib/tls/localhost.crt"
ssl_key_path = "./storage/index/lib/tls/localhost.key"

JSON

{
  "net": {
    "port": 3001,
    "tsl": {
      "ssl_cert_path": "./storage/index/lib/tls/localhost.crt",
      "ssl_key_path": "./storage/index/lib/tls/localhost.key"
    }
  }
}

The TSL configuration is optional, but if you have that toml table ([net.tsl]), it must contain the fields. This is an invalid configuration:

[net.tsl]
ssl_cert_path = ""
ssl_key_path = ""

See torrust/torrust-tracker#853.

Subtasks

  • Migrate to axum-server.
  • Add a wrapper to axum-server with timeouts.
  • Add TSL values to the configuration.
  • Start with TSL support when enabled in the configuration.

…m server with timeouts

Two levels of wrappers for the Axum server:

Custom (with timeouts) -> axum-server -> axum
@josecelano josecelano self-assigned this May 15, 2024
@josecelano josecelano linked an issue May 15, 2024 that may be closed by this pull request
@josecelano josecelano requested a review from da2ce7 May 15, 2024 15:55
- Use axum-server isntead of directly the axum crate (like in the
  tracker).
- Add wrapper to axum-server to enable timeouts.
…oml file

```toml
[net]
port = 3001

[net.tsl]
ssl_cert_path = "./storage/index/lib/tls/localhost.crt"
ssl_key_path = "./storage/index/lib/tls/localhost.key"
```

```json
{
  "net": {
    "port": 3001,
    "tsl": {
      "ssl_cert_path": "./storage/index/lib/tls/localhost.crt",
      "ssl_key_path": "./storage/index/lib/tls/localhost.key"
    }
  }
}
```

The TSL configuration is optional, but if you have that table (dict), it must contain the fields. This is an invalid configuration:

```
[net.tsl]
ssl_cert_path = ""
ssl_key_path = ""
```

See torrust/torrust-tracker#853.
You can provide a certificate and certificate key files to run the API
with HTTPs.
@josecelano
Copy link
Member Author

I can run the API with a self-signed certificate as described in:

cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s
     Running `target/debug/torrust-index`
Loading default configuration file: `./share/default/config/index.development.sqlite3.toml` ...
2024-05-15T18:38:14.092322751+01:00 [torrust_index::bootstrap::logging][INFO] logging initialized.
2024-05-15T18:38:14.114368143+01:00 [torrust_index::web::api::server][INFO] Using https. Cert path: ./storage/index/lib/tls/localhost.crt.
2024-05-15T18:38:14.114382073+01:00 [torrust_index::web::api::server][INFO] Using https. Key path: ./storage/index/lib/tls/localhost.key.

However, I can't load any page.

With curl:

*   Trying 127.0.0.1:3001...
* Connected to localhost (127.0.0.1) port 3001 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version number
* Closing connection 0
curl: (35) OpenSSL/3.0.8: error:0A00010B:SSL routines::wrong version number

With Firefox:

image

I've tried with these files:

  • ssl_cert_path = "./storage/index/lib/tls/localhost.crt
  • ssl_key_path = "./storage/index/lib/tls/localhost.key"

Generated with:

openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

And also with certificates from https://github.com/programatik29/axum-server/tree/master/examples/self-signed-certs:

  • ssl_cert_path = "./storage/index/lib/tls/cert.pem"
  • ssl_key_path = "./storage/index/lib/tls/key.pem"

This is an example from axum-server:

https://github.com/programatik29/axum-server/blob/master/examples/from_std_listener_rustls.rs

I think I'm doing the same.

@da2ce7 any idea?

@josecelano
Copy link
Member Author

I made it work by commenting on the TimeoutAcceptor. It's a custom acceptor that introduces timeouts for the first client request after opening the HTTP connection.

    match tls {
        Some(tls) => custom_axum::from_tcp_rustls_with_timeouts(socket, tls)
            .handle(handle)
            //.acceptor(TimeoutAcceptor)
            .serve(router.into_make_service_with_connect_info::<std::net::SocketAddr>())
            .await
            .expect("API server should be running"),
        None => custom_axum::from_tcp_with_timeouts(socket)
            .handle(handle)
            .acceptor(TimeoutAcceptor)
            .serve(router.into_make_service_with_connect_info::<std::net::SocketAddr>())
            .await
            .expect("API server should be running"),
    };

I added this TimeAcceptor to the Tracker, but I did not check that the TSL worked fine. I have to open an issue there to check it. I will probably not work. I'm going to remove that TimeoutAcceptor for HTTPs in order to merge this PR and I will open a new issue to fix that problem. We probably need to fix that TimeoutAcceptor to make it work with TSL.

@josecelano
Copy link
Member Author

ACK 5d9e068

TSL does work with the TimeoutAccetor.

How to enabled TSL for development with:

```
[net]
port = 3001

[net.tsl]
ssl_cert_path = "./storage/index/lib/tls/localhost.crt"
ssl_key_path = "./storage/index/lib/tls/localhost.key"
```

You can fin the certificates in `./share/tsl`.

This means there is no timeout for the first client request when you use
TSL. The way to test tiemouts is:

1. Open a connection using telnet: `telnet 127.0.0.1 3001`
2. Wait 5 seconds.

The connection should be closed after 5 seconds. That's what the
TimeoutAcceptor does. Without the TimeoutAcceptor the connection will
remain open until the client closes it.
@josecelano josecelano merged commit b2d864a into torrust:develop May 16, 2024
12 of 13 checks passed
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TLS support
1 participant