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

TSL support #584

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
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