Commit Graph

216 Commits

Author SHA1 Message Date
Thomas Lamprecht
9205e65d21 rest-server: bump version to 0.8.5
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-12-02 18:15:11 +01:00
Fabian Grünbichler
b2d31f075d rest-server: increase task index lock timeout to 15s
this lock can be quite contended, until the surrounding code is properly split
to reduce this contention it should help to give the worker task
creation/cleanup code a bit more breathing room.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-12-02 16:56:46 +01:00
Fabian Grünbichler
57c8242dc2 rest-server: close race window when updating worker task count
this mimics how the count is updated when spawning a new task - the lock scope
needs to cover the count update itself, else there's a race when multiple
worker's log their result at the same time..

Co-developed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-12-02 16:54:52 +01:00
Fabian Grünbichler
4e51ac3527 rest-server: handle failure in worker task setup correctly
if setting up a new worker fails after it has been inserted into the
WORKER_TASK_LIST, we need to clean it up instead of bubbling up the error right
away, else we "leak" the worker task and it never finishes..

a worker task that never finishes will indefinitely block shutdown
of the rest server process, including the "old" process when reloading
the rest server.

this issue was found in the wild on a system with lock contention on the
file-based lock covering task index updating leading to lock acquiring
timeouts.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-12-02 16:54:18 +01:00
Thomas Lamprecht
bfe099f4f1 workspace: update proxmox-http-client to 0.9.4
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-26 14:37:43 +01:00
Thomas Lamprecht
cc85a72391 rest-server: bump version to 0.8.4-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-25 17:16:16 +01:00
Gabriel Goller
34e307461b rest-server: add custom handlebars escape fn
Add a custom handlebars escape function. It's nearly identical to the
default `html_escape` fn [0], but it does not escape the '='. This is
needed to support base64 encoded values.

[0]: https://docs.rs/handlebars/latest/handlebars/fn.html_escape.html

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
 [ TL: use full width for comment ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-25 16:34:30 +01:00
Thomas Lamprecht
1e7c0fc3ac rest-server: bump version to 0.8.3-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-15 11:28:04 +01:00
Thomas Lamprecht
9529f730e0 rest-server: drop log intended for debugging again
I considered keeping it as log::trace level, but IMO that's just not
worth it, as just the peek_len is not giving one much more and can
also be basically also gathered through strace.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-15 10:29:33 +01:00
Thomas Lamprecht
1539bc1ce3 rest-server: bump version to 0.8.2-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-14 14:39:19 +01:00
Dominik Csapak
dc9531d302 fix #5868: rest-server: handshake detection: avoid infinite loop on connections abort
When a connection is closed by the client before we have enough data
to determine if it contains a TLS Handshake or not, the socket stays
in a readable state.
While we setup a tokio backed timeout of 10s for the connection
build-up here, this timeout does not trigger on said early connection
abort from the client side, causing then the async_io loop to
endlessly loop around peeking into the client, which always returns
the last available bytes before the connection was closed. This in
turn causes 100% CPU usage for one of the PBS threads.
The timeout not triggering is rather odd, and does indicate some
potential for further improvement in tokio itself, but our
questionable use of the WouldBlock error does violate the API
contract, so this is not a clear cut.

Such an early connection abort is often triggered by monitoring
solutions, which use it to relatively cheaply check if TCP on a port
still works as "is service up" heuristic.

To fix this, save the amount of bytes peek returned and if they did
not change between invocations of the callback, we can assume that the
connection was closed and thus exit the connection attempt with an
error.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [ TL: reword commit message and change error to ConnectionAborted ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-14 14:31:47 +01:00
Wolfgang Bumiller
0ea27021a2 rest-server: bump to 0.8.1-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-11-08 12:09:53 +01:00
Wolfgang Bumiller
a092b06d9f rest-server: shorten some format strings
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-11-08 12:09:53 +01:00
Gabriel Goller
d8fa495a50 rest-server: check permissions on proxy.key and proxy.pem files
To avoid openssl's unhelpful error messages when the proxy.key or
proxy.pem files have the wrong permissions, we open the files. To load
the private key, we can simply read from the file and pass it to the
`set_private_key` openssl function. Sadly such a function does not exist
for loading certificate chains, so we have to open and close the file
before calling the `set_certificate_chain_file` fn.

Motivation: https://forum.proxmox.com/threads/proxmox-backup-tailscale-proxmox-backup-proxy-service-wont-boot.153204

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
2024-11-08 12:09:53 +01:00
Wolfgang Bumiller
db69867d4d rest-server: pass cipher suite/list to acceptor
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-11-08 12:09:53 +01:00
Wolfgang Bumiller
d6e86d670b tree-wide: unify workspace inherited attributes
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-09-20 08:42:45 +02:00
Wolfgang Bumiller
ddbada0668 rest-server: bump to 0.8.0-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-09-05 14:15:11 +02:00
Wolfgang Bumiller
2a4cf83799 rest-server: utilize flush_window for streams
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-09-05 14:15:11 +02:00
Wolfgang Bumiller
17bd32e90e router, rest-server: add StreamSync and StreamAsync API handlers
These are Iterators or Streams which continuously produce output. They
can either be formatted, in which they are serialized like the as
usually, or, if the client caccepts `application/json-seq` via an
`Accept` header, it will be streamed as a sequence directly.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-09-05 14:15:11 +02:00
Wolfgang Bumiller
c31eaf0018 router, rest-server, api-macro: rename Streaming api to Serializing
This does not "stream", but rather skips the intermediate step to
serialize the entire output into a local json string.

We now reserve the "Stream*" prefix for actual *streaming*, that is,
producing an API response which gets streamed continuously as it is
asynchronously produced.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-09-05 14:15:11 +02:00
Wolfgang Bumiller
693d206c94 rest-server: bump to 0.7.1-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-14 11:34:15 +02:00
Maximiliano Sandoval
21a39b3cda rest-server: remove use of once_cell
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-08-14 11:32:23 +02:00
Maximiliano Sandoval
901f2fb1bb rest-server: remove unused dependencies
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-08-14 11:32:23 +02:00
Maximiliano Sandoval
25f83bce19 rest-server: remove lazy_static dependency
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-08-14 10:33:42 +02:00
Maximiliano Sandoval
77fe0f6954 docs: clippy: add indentation to doc list items
Fixes the clippy warning:

warning: doc list item missing indentation
   --> proxmox-subscription/src/subscription_info.rs:179:9
    |
179 |     ///  (this mode is used to decide whether to refresh the subscription information)
    |         ^
    |
    = help: if this is supposed to be its own paragraph, add a blank line
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation
    = note: `#[warn(clippy::doc_lazy_continuation)]` on by default
help: indent this line
    |
179 |     ///   (this mode is used to decide whether to refresh the subscription information)
    |          +

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
2024-08-07 20:58:04 +02:00
Wolfgang Bumiller
9d921901d3 rest-server: update examples code to daemon split
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-08-01 10:27:44 +02:00
Wolfgang Bumiller
15200b9f64 rest-server: bump to 0.7.0-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-24 14:32:01 +02:00
Wolfgang Bumiller
d3abd366c4 introduce proxmox-daemon crate
split from rest-server:
- "state" module (shutdown/reload state)
- shutdown futures
- "daemon" module (named 'server' module in proxmox-daemon)
- command socket

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-24 14:25:50 +02:00
Wolfgang Bumiller
2783f062a6 update rest-server to use proxmox-systemd crate
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-24 14:25:50 +02:00
Wolfgang Bumiller
ab41d326e4 introduce proxmox-systemd crate
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-24 14:25:50 +02:00
Wolfgang Bumiller
a38b46b27d rest-server: drop proxmox-io dependency
Used only for read/writing a pid_t (an integer) to a socket.
The standard to_ne_bytes()/from_ne_bytes() should be sufficient here,
we already have libc::pid_t which we can use to get the correct type
namespace for accessing ::from_ne_bytes().

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-24 14:06:40 +02:00
Maximiliano Sandoval
254a37ae07 fix typos in code documentation
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-07-22 08:49:42 +02:00
Maximiliano Sandoval
a50d2c715e rest-server: Encode with zlib headers
As per [RFC9110] the Deflate encoding is a "zlib" data format. This
makes the rest-server compatible with the http-client.

[RFC9110] https://www.rfc-editor.org/rfc/rfc9110#field.content-encoding

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
Reviewed-by: Max Carrara <m.carrara@proxmox.com>
Tested-by: Max Carrara <m.carrara@proxmox.com>
2024-07-22 08:11:14 +02:00
Wolfgang Bumiller
ad60e1bde5 rest-server: bump to 0.6.0-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-11 15:13:36 +02:00
Wolfgang Bumiller
4b9c907b68 log: introduce a shareable LogContext struct
Since hyper can spawn() more tasks, when we stop passing `WorkerTask`
references down the stack, we still need to be able to *inherit* the
current logging context. Hyper provides a way to replace its used
`spawn()` method, so we need to provide a way to reuse the logging
context.

Instead of having the `FileLogger` and warn counter separately
available with local-only access, put them behind an Arc<Mutex<>>.
Previously they already *were* behind an Arc<Mutex<>> as part of the
WorkerTaskState.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-11 14:45:26 +02:00
Wolfgang Bumiller
847a57740b new worker-task crate, move WorkerTaskContext from sys
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-11 14:43:37 +02:00
Gabriel Goller
ddb91a6594 enable tracing logger, remove task_log macros
Enable the tracing-system by setting the LOGGER task local variable
to a instance of a FileLogger and initializing the WARN_COUNTER.
Removed the task_log! macros and some occurences.

Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
[WB: remove flog! import in doctests]
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-11 14:43:37 +02:00
Wolfgang Bumiller
f1920d9b94 rest-server: fix a build warning
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-11 14:43:37 +02:00
Wolfgang Bumiller
9c3e4d5ccf rest-server: bump version to 0.5.4-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-10 12:44:29 +02:00
Wolfgang Bumiller
ce802d8320 rest-server: drop some unnecessary 'pub's
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-10 12:37:51 +02:00
Max Carrara
f6bacbb58f fix #5105: rest-server: connection: overhaul TLS handshake check logic
On rare occasions, the TLS "client hello" message [1] is delayed after
a connection with the server was established, which causes HTTPS
requests to fail before TLS was even negotiated. In these cases, the
server would incorrectly respond with "HTTP/1.1 400 Bad Request"
instead of closing the connection (or similar).

The reasons for the "client hello" being delayed seem to vary; one
user noticed that the issue went away completely after they turned off
UFW [2]. Another user noticed (during private correspondence) that the
issue only appeared when connecting to their PBS instance via WAN, but
not from within their VPN. In the WAN case a firewall was also
present. The same user kindly provided tcpdumps and strace logs on
request.

The issue was finally reproduced with the following Python script:

  import socket
  import time

  HOST: str = ...
  PORT: int = ...

  with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
      sock.connect((HOST, PORT))
      time.sleep(1.5) # simulate firewall / proxy / etc. delay
      sock.sendall(b"\x16\x03\x01\x02\x00")
      data = sock.recv(256)
      print(data)

The additional delay before sending the first 5 bytes of the "client
hello" message causes the handshake checking logic to incorrectly fall
back to plain HTTP.

All of this is fixed by the following:

  1. Increase the timeout duration to 10 seconds (from 1)
  2. Instead of falling back to plain HTTP, refuse to accept the
     connection if the TLS handshake wasn't initiated before the
     timeout limit is reached
  3. Only accept plain HTTP if the first 5 bytes do not correspond to
     a TLS handshake fragment [3]
  4. Do not take the last number of bytes that were in the buffer into
     account; instead, only perform the actual handshake check if
     5 bytes are in the peek buffer using some of tokio's low-level
     functionality

Regarding 1.: This should be generous enough for any client to be able
to initiate a TLS handshake, despite its surrounding circumstances.

Regarding 4.: While this is not 100% related to the issue, peeking into
the buffer in this manner should ensure that our implementation here
remains correct, even if the kernel's underlying behaviour regarding
edge-triggering is changed [4]. At the same time, there's no need for
busy-waiting and continuously yielding to the event loop anymore.

[1]: https://www.rfc-editor.org/rfc/rfc8446.html#section-4.1.2
[2]: https://forum.proxmox.com/threads/disable-default-http-redirects-on-8007.142312/post-675352
[3]: https://www.rfc-editor.org/rfc/rfc8446.html#section-5.1
[4]: https://lwn.net/Articles/864947/

Signed-off-by: Max Carrara <m.carrara@proxmox.com>
2024-07-10 12:22:17 +02:00
Max Carrara
847ca5d14d rest-server: connection: log peer address on error
.. in order to make debugging easier and logs more helpful.

Signed-off-by: Max Carrara <m.carrara@proxmox.com>
2024-07-10 12:22:17 +02:00
Max Carrara
0d3e7c8eaf rest-server: connection: clean up accept data flow
This adds the structs `AcceptState` and `AcceptFlags` and adapts
relevant method signatures of `AcceptBuilder` accordingly. This makes
it easier to add further parameters in the future.

Signed-off-by: Max Carrara <m.carrara@proxmox.com>
2024-07-10 12:22:17 +02:00
Wolfgang Bumiller
0652d81977 tree-wide: enable doc_cfg and doc_auto_cfg for docs
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-07-02 11:59:53 +02:00
Wolfgang Bumiller
0e17606caf rest-server: bump to 0.5.3-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-06-20 14:06:12 +02:00
Fabian Grünbichler
6f532dfb7d various clippy fixes
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-06-06 11:40:49 +02:00
Thomas Lamprecht
d73eb3dcf1 tree-wide: run cargo fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-03-25 17:04:17 +01:00
Wolfgang Bumiller
890d9e58f7 bump proxmox-rest-server to 0.5.2-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2024-02-02 13:58:05 +01:00
Wolfgang Bumiller
2bba40f604 rest-server: support configuring the privileged connection
Adds a privileged_addr to ApiConfig, and some helpers for
hyper (both server and client)

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
2024-02-01 14:00:22 +01:00
Wolfgang Bumiller
aad01f7a90 rest-server: support unix sockets in create_daemon
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: Lukas Wagner <l.wagner@proxmox.com>
2024-02-01 13:59:48 +01:00