Skip to content

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TLS support

1 participant