Skip to content

tls: support HTTPS proxy#11778

Open
antoniomrfranco wants to merge 5 commits intofluent:masterfrom
antoniomrfranco:https-proxy-support
Open

tls: support HTTPS proxy#11778
antoniomrfranco wants to merge 5 commits intofluent:masterfrom
antoniomrfranco:https-proxy-support

Conversation

@antoniomrfranco
Copy link
Copy Markdown

@antoniomrfranco antoniomrfranco commented May 6, 2026

Add support for HTTPS proxy URLs (https://) in Fluent Bit's proxy handling. Previously only plain http:// proxy URLs were accepted.
This change allows outbound connections to be routed through a TLS-secured proxy, including to TLS-enabled endpoints such as S3.


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
  • Debug log output from testing the change
Click to toggle debug output
Fluent Bit v5.0.4
* Copyright (C) 2015-2026 The Fluent Bit Authors
* Fluent Bit is a CNCF graduated project under the Fluent organization
* https://fluentbit.io

______ _                  _    ______ _ _           _____  _____ 
|  ___| |                | |   | ___ (_) |         |  ___||  _  |
| |_  | |_   _  ___ _ __ | |_  | |_/ /_| |_  __   _|___ \ | |/' |
|  _| | | | | |/ _ \ '_ \| __| | ___ \ | __| \ \ / /   \ \|  /| |
| |   | | |_| |  __/ | | | |_  | |_/ / | |_   \ V //\__/ /\ |_/ /
\_|   |_|\__,_|\___|_| |_|\__| \____/|_|\__|   \_/ \____(_)\___/


[2026/05/06 13:11:12.127] [ info] Configuration:
[2026/05/06 13:11:12.128] [ info]  flush time     | 1.000000 seconds
[2026/05/06 13:11:12.129] [ info]  grace          | 5 seconds
[2026/05/06 13:11:12.129] [ info]  daemon         | 0
[2026/05/06 13:11:12.129] [ info] ___________
[2026/05/06 13:11:12.129] [ info]  inputs:
[2026/05/06 13:11:12.129] [ info]      forward
[2026/05/06 13:11:12.129] [ info] ___________
[2026/05/06 13:11:12.129] [ info]  filters:
[2026/05/06 13:11:12.129] [ info] ___________
[2026/05/06 13:11:12.129] [ info]  outputs:
[2026/05/06 13:11:12.129] [ info]      stdout.0
[2026/05/06 13:11:12.129] [ info]      stdout.1
[2026/05/06 13:11:12.129] [ info]      s3.2
[2026/05/06 13:11:12.129] [ info] ___________
[2026/05/06 13:11:12.129] [ info]  collectors:
[2026/05/06 13:11:12.131] [ info] [fluent bit] version=5.0.4, commit=b7416e3d8c, pid=1
[2026/05/06 13:11:12.132] [debug] [engine] coroutine stack size: 24576 bytes (24.0K)
[2026/05/06 13:11:12.133] [ info] [storage] ver=1.5.4, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2026/05/06 13:11:12.133] [ info] [simd    ] SSE2
[2026/05/06 13:11:12.133] [ info] [cmetrics] version=2.1.2
[2026/05/06 13:11:12.133] [ info] [ctraces ] version=0.7.1
[2026/05/06 13:11:12.134] [ info] [input:forward:forward.0] initializing
[2026/05/06 13:11:12.134] [ info] [input:forward:forward.0] storage_strategy='memory' (memory only)
[2026/05/06 13:11:12.134] [debug] [forward:forward.0] created event channels: read=24 write=25
[2026/05/06 13:11:12.134] [debug] [in_fw] Listen='0.0.0.0' TCP_Port=24224
[2026/05/06 13:11:12.135] [debug] [downstream] listening on 0.0.0.0:24224
[2026/05/06 13:11:12.136] [ info] [input:forward:forward.0] listening on 0.0.0.0:24224
[2026/05/06 13:11:12.136] [debug] [stdout:stdout.0] created event channels: read=27 write=28
[2026/05/06 13:11:12.136] [debug] [stdout:stdout.1] created event channels: read=34 write=35
[2026/05/06 13:11:12.136] [debug] [s3:s3.2] created event channels: read=41 write=42
[2026/05/06 13:11:12.138] [ info] [output:stdout:stdout.0] worker #0 started
[2026/05/06 13:11:12.138] [ info] [output:stdout:stdout.1] worker #0 started
[2026/05/06 13:11:12.159] [ info] [fstore] created root path /tmp/fluent-bit/s3/my-https-proxy-test-bucket
[2026/05/06 13:11:12.160] [ info] [output:s3:s3.2] Using upload size 100000000 bytes
[2026/05/06 13:11:12.161] [debug] [aws_credentials] Initialized Env Provider in standard chain
[2026/05/06 13:11:12.161] [debug] [aws_credentials] creating profile (null) provider
[2026/05/06 13:11:12.161] [debug] [aws_credentials] Initialized AWS Profile Provider in standard chain
[2026/05/06 13:11:12.161] [debug] [aws_credentials] Not initializing EKS provider because AWS_ROLE_ARN was not set
[2026/05/06 13:11:12.161] [debug] [aws_credentials] Not initializing ECS/EKS HTTP Provider because AWS_CONTAINER_CREDENTIALS_RELATIVE_URI and AWS_CONTAINER_CREDENTIALS_FULL_URI is not set
[2026/05/06 13:11:12.162] [debug] [aws_credentials] Initialized EC2 Provider in standard chain
[2026/05/06 13:11:12.162] [debug] [upstream] config->http_proxy: https://https-proxy.local
[2026/05/06 13:11:12.162] [debug] [aws_credentials] Sync called on the EC2 provider
[2026/05/06 13:11:12.162] [debug] [aws_credentials] Init called on the env provider
[2026/05/06 13:11:12.162] [debug] [aws_credentials] upstream_set called on the EC2 provider
[2026/05/06 13:11:12.162] [ warn] [router] NO match for stdout.0 output instance
[2026/05/06 13:11:12.162] [debug] [router] match rule forward.0:stdout.1
[2026/05/06 13:11:12.162] [debug] [router] match rule forward.0:s3.2
[2026/05/06 13:11:12.179] [ info] [sp] stream processor started
[2026/05/06 13:11:12.179] [ info] [output:s3:s3.2] initializing worker
[2026/05/06 13:11:12.179] [ info] [output:s3:s3.2] worker #0 started
[2026/05/06 13:11:12.180] [ info] [engine] Shutdown Grace Period=5, Shutdown Input Grace Period=2
[2026/05/06 13:11:16.585] [debug] [task] created task=0x7ffffc62ebe0 id=0 OK
[2026/05/06 13:11:16.585] [debug] [output:stdout:stdout.1] task_id=0 assigned to thread #0
[2026/05/06 13:11:16.585] [debug] [output:s3:s3.2] task_id=0 assigned to thread #0
[2026/05/06 13:11:16.587] [debug] [output:s3:s3.2] Creating upload timer with frequency 6s
[0] a2a0c17b99f7: [[1778073076.000000000, {}], {"container_id"=>"a2a0c17b99f7221579e99f7c74fe12772d95ca0d7bc286408a213f0fa867e635", "co"}]iner_name"=>"/exciting_euler", "source"=>"stdout", "log"=>"Testing a log message
[2026/05/06 13:11:16.589] [debug] [out flush] cb_destroy coro_id=0
[2026/05/06 13:11:16.591] [debug] [out flush] cb_destroy coro_id=0
[2026/05/06 13:11:16.591] [debug] [task] destroy task=0x7ffffc62ebe0 (task_id=0)
[2026/05/06 13:11:22.583] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 13:11:22.583] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 13:11:22.583] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 13:11:28.583] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 13:11:28.583] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 13:11:28.583] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 13:11:29.311] [debug] [upstream] establishing http tunneling to proxy: host https-proxy.local port 443
[2026/05/06 13:11:29.312] [debug] [http_client] using HTTP CONNECT for proxy: proxy host s3.us-west-2.amazonaws.com, proxy port 443
[2026/05/06 13:11:29.516] [debug] [upstream] proxy returned 200
[2026/05/06 13:11:29.517] [debug] [http_client] flb_http_client_proxy_connect connection #74 connected to https-proxy.local:443.
[2026/05/06 13:11:29.738] [debug] [upstream] KA connection #74 to https-proxy.local:443 is connected
[2026/05/06 13:11:29.738] [debug] [http_client] not using http_proxy for header
[2026/05/06 13:11:29.738] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/05/06 13:11:29.985] [debug] [upstream] KA connection #74 to https-proxy.local:443 is now available
[2026/05/06 13:11:29.985] [debug] [output:s3:s3.2] PutObject http status=200
[2026/05/06 13:11:29.985] [ info] [output:s3:s3.2] Successfully uploaded object /fluent-bit-logs/a2a0c17b99f7/2026/05/06/13/11/16-objectvql50Omd
^C[2026/05/06 13:11:33] [engine] caught signal (SIGINT)
[2026/05/06 13:11:33.374] [ warn] [engine] service will shutdown in max 5 seconds
[2026/05/06 13:11:33.374] [ info] [engine] pausing all inputs..
[2026/05/06 13:11:33.374] [ info] [input] pausing forward.0
[2026/05/06 13:11:33.583] [ info] [engine] service has stopped (0 pending tasks)
[2026/05/06 13:11:33.584] [ info] [input] pausing forward.0
[2026/05/06 13:11:33.585] [ info] [output:stdout:stdout.0] thread worker #0 stopping...
[2026/05/06 13:11:33.585] [ info] [output:stdout:stdout.0] thread worker #0 stopped
[2026/05/06 13:11:33.593] [ info] [output:stdout:stdout.1] thread worker #0 stopping...
[2026/05/06 13:11:33.593] [ info] [output:stdout:stdout.1] thread worker #0 stopped
[2026/05/06 13:11:33.594] [ info] [output:s3:s3.2] thread worker #0 stopping...
[2026/05/06 13:11:33.594] [ info] [output:s3:s3.2] terminating worker
[2026/05/06 13:11:33.598] [ info] [output:s3:s3.2] thread worker #0 stopped
  • Attached Valgrind output that shows no leaks or memory corruption was found
Click to toggle Valgrind output
==1== Memcheck, a memory error detector
==1== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==1== Using Valgrind-3.24.0 and LibVEX; rerun with -h for copyright info
==1== Command: /fluent-bit/bin/fluent-bit -i forward -o stdout -p format=json_lines -f 1 -c /fluent-bit/etc/fluent-bit.conf
==1== 
Fluent Bit v5.0.4
* Copyright (C) 2015-2026 The Fluent Bit Authors
* Fluent Bit is a CNCF graduated project under the Fluent organization
* https://fluentbit.io

______ _                  _    ______ _ _           _____  _____ 
|  ___| |                | |   | ___ (_) |         |  ___||  _  |
| |_  | |_   _  ___ _ __ | |_  | |_/ /_| |_  __   _|___ \ | |/' |
|  _| | | | | |/ _ \ '_ \| __| | ___ \ | __| \ \ / /   \ \|  /| |
| |   | | |_| |  __/ | | | |_  | |_/ / | |_   \ V //\__/ /\ |_/ /
\_|   |_|\__,_|\___|_| |_|\__| \____/|_|\__|   \_/ \____(_)\___/


[2026/05/06 14:02:47.258] [ info] Configuration:
[2026/05/06 14:02:47.331] [ info]  flush time     | 1.000000 seconds
[2026/05/06 14:02:47.354] [ info]  grace          | 5 seconds
[2026/05/06 14:02:47.355] [ info]  daemon         | 0
[2026/05/06 14:02:47.356] [ info] ___________
[2026/05/06 14:02:47.357] [ info]  inputs:
[2026/05/06 14:02:47.358] [ info]      forward
[2026/05/06 14:02:47.359] [ info] ___________
[2026/05/06 14:02:47.360] [ info]  filters:
[2026/05/06 14:02:47.360] [ info] ___________
[2026/05/06 14:02:47.361] [ info]  outputs:
[2026/05/06 14:02:47.362] [ info]      stdout.0
[2026/05/06 14:02:47.363] [ info]      stdout.1
[2026/05/06 14:02:47.363] [ info]      s3.2
[2026/05/06 14:02:47.363] [ info] ___________
[2026/05/06 14:02:47.364] [ info]  collectors:
[2026/05/06 14:02:47.518] [ info] [fluent bit] version=5.0.4, commit=daf51056d3, pid=1
[2026/05/06 14:02:47.553] [debug] [engine] coroutine stack size: 24576 bytes (24.0K)
[2026/05/06 14:02:47.575] [ info] [storage] ver=1.5.4, type=memory, sync=normal, checksum=off, max_chunks_up=128
[2026/05/06 14:02:47.577] [ info] [simd    ] SSE2
[2026/05/06 14:02:47.578] [ info] [cmetrics] version=2.1.2
[2026/05/06 14:02:47.579] [ info] [ctraces ] version=0.7.1
[2026/05/06 14:02:47.635] [ info] [input:forward:forward.0] initializing
[2026/05/06 14:02:47.636] [ info] [input:forward:forward.0] storage_strategy='memory' (memory only)
[2026/05/06 14:02:47.641] [debug] [forward:forward.0] created event channels: read=30 write=31
[2026/05/06 14:02:47.668] [debug] [in_fw] Listen='0.0.0.0' TCP_Port=24224
[2026/05/06 14:02:47.712] [debug] [downstream] listening on 0.0.0.0:24224
[2026/05/06 14:02:47.715] [ info] [input:forward:forward.0] listening on 0.0.0.0:24224
[2026/05/06 14:02:47.734] [debug] [stdout:stdout.0] created event channels: read=33 write=34
[2026/05/06 14:02:47.823] [debug] [stdout:stdout.1] created event channels: read=40 write=41
[2026/05/06 14:02:47.855] [debug] [s3:s3.2] created event channels: read=47 write=48
[2026/05/06 14:02:48.065] [ info] [output:stdout:stdout.0] worker #0 started
[2026/05/06 14:02:48.067] [ info] [output:stdout:stdout.1] worker #0 started
[2026/05/06 14:02:49.278] [ info] [fstore] created root path /tmp/fluent-bit/s3/my-https-proxy-test-bucket
[2026/05/06 14:02:49.318] [ info] [output:s3:s3.2] Using upload size 100000000 bytes
[2026/05/06 14:02:49.354] [debug] [aws_credentials] Initialized Env Provider in standard chain
[2026/05/06 14:02:49.355] [debug] [aws_credentials] creating profile (null) provider
[2026/05/06 14:02:49.365] [debug] [aws_credentials] Initialized AWS Profile Provider in standard chain
[2026/05/06 14:02:49.373] [debug] [aws_credentials] Not initializing EKS provider because AWS_ROLE_ARN was not set
[2026/05/06 14:02:49.379] [debug] [aws_credentials] Not initializing ECS/EKS HTTP Provider because AWS_CONTAINER_CREDENTIALS_RELATIVE_URI and AWS_CONTAINER_CREDENTIALS_FULL_URI is not set
[2026/05/06 14:02:49.390] [debug] [aws_credentials] Initialized EC2 Provider in standard chain
[2026/05/06 14:02:49.397] [debug] [upstream] config->http_proxy: https://https-proxy.local
[2026/05/06 14:02:49.418] [debug] [aws_credentials] Sync called on the EC2 provider
[2026/05/06 14:02:49.420] [debug] [aws_credentials] Init called on the env provider
[2026/05/06 14:02:49.425] [debug] [aws_credentials] upstream_set called on the EC2 provider
[2026/05/06 14:02:49.466] [ warn] [router] NO match for stdout.0 output instance
[2026/05/06 14:02:49.470] [debug] [router] match rule forward.0:stdout.1
[2026/05/06 14:02:49.471] [debug] [router] match rule forward.0:s3.2
[2026/05/06 14:02:49.476] [ info] [sp] stream processor started
[2026/05/06 14:02:49.491] [ info] [engine] Shutdown Grace Period=5, Shutdown Input Grace Period=2
[2026/05/06 14:02:49.510] [ info] [output:s3:s3.2] initializing worker
[2026/05/06 14:02:49.513] [ info] [output:s3:s3.2] worker #0 started
[2026/05/06 14:03:00.733] [debug] [task] created task=0x66862d0 id=0 OK
[2026/05/06 14:03:00.744] [debug] [output:stdout:stdout.1] task_id=0 assigned to thread #0
[2026/05/06 14:03:00.746] [debug] [output:s3:s3.2] task_id=0 assigned to thread #0
[2026/05/06 14:03:00.770] [debug] [output:s3:s3.2] Creating upload timer with frequency 6s
[0] 3e8384f2fc06: [[1778076180.000000000, {}], {"container_id"=>"3e8384f2fc06995f243ce872cacd22f14e8f40f62a5be5e78184fafb5c3b8eff", "co"}]iner_name"=>"/bold_jackson", "source"=>"stdout", "log"=>"Testing a log message
[2026/05/06 14:03:00.879] [debug] [out flush] cb_destroy coro_id=0
[2026/05/06 14:03:00.935] [debug] [out flush] cb_destroy coro_id=0
[2026/05/06 14:03:00.939] [debug] [task] destroy task=0x66862d0 (task_id=0)
[2026/05/06 14:03:06.610] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 14:03:06.613] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 14:03:06.617] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 14:03:12.606] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 14:03:12.608] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 14:03:12.608] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 14:03:16.615] [debug] [upstream] establishing http tunneling to proxy: host https-proxy.local port 443
[2026/05/06 14:03:16.618] [debug] [http_client] using HTTP CONNECT for proxy: proxy host s3.us-west-2.amazonaws.com, proxy port 443
[2026/05/06 14:03:16.902] [debug] [upstream] proxy returned 200
[2026/05/06 14:03:16.912] [debug] [http_client] flb_http_client_proxy_connect connection #80 connected to https-proxy.local:443.
[2026/05/06 14:03:17.750] [debug] [upstream] KA connection #80 to https-proxy.local:443 is connected
[2026/05/06 14:03:17.754] [debug] [http_client] not using http_proxy for header
[2026/05/06 14:03:17.773] [debug] [aws_credentials] Requesting credentials from the env provider..
[2026/05/06 14:03:18.136] [debug] [upstream] KA connection #80 to https-proxy.local:443 is now available
[2026/05/06 14:03:18.141] [debug] [output:s3:s3.2] PutObject http status=200
[2026/05/06 14:03:18.144] [ info] [output:s3:s3.2] Successfully uploaded object /fluent-bit-logs/3e8384f2fc06/2026/05/06/14/03/00-objectUAYZ6HXy
[2026/05/06 14:03:18.602] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 14:03:18.603] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 14:03:18.604] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 14:03:24.606] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 14:03:24.607] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 14:03:24.607] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 14:03:26.120] [debug] [upstream] KA connection #80 to https-proxy.local:443 has been disconnected by the remote service
[2026/05/06 14:03:30.606] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 14:03:30.607] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 14:03:30.607] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
[2026/05/06 14:03:36.608] [debug] [output:s3:s3.2] Running upload timer callback (upload_queue)..
[2026/05/06 14:03:36.609] [debug] [output:s3:s3.2] No files found in upload_queue. Scanning for timed out chunks
[2026/05/06 14:03:36.609] [ info] [output:s3:s3.2] Running upload timer callback (cb_s3_upload)..
^C[2026/05/06 14:03:37] [engine] caught signal (SIGINT)
[2026/05/06 14:03:37.645] [ warn] [engine] service will shutdown in max 5 seconds
[2026/05/06 14:03:37.648] [ info] [engine] pausing all inputs..
[2026/05/06 14:03:37.651] [ info] [input] pausing forward.0
[2026/05/06 14:03:38.620] [ info] [engine] service has stopped (0 pending tasks)
[2026/05/06 14:03:38.622] [ info] [input] pausing forward.0
[2026/05/06 14:03:38.636] [ info] [output:stdout:stdout.0] thread worker #0 stopping...
[2026/05/06 14:03:38.658] [ info] [output:stdout:stdout.0] thread worker #0 stopped
[2026/05/06 14:03:38.805] [ info] [output:stdout:stdout.1] thread worker #0 stopping...
[2026/05/06 14:03:38.808] [ info] [output:stdout:stdout.1] thread worker #0 stopped
[2026/05/06 14:03:38.815] [ info] [output:s3:s3.2] thread worker #0 stopping...
[2026/05/06 14:03:38.818] [ info] [output:s3:s3.2] terminating worker
[2026/05/06 14:03:38.823] [ info] [output:s3:s3.2] thread worker #0 stopped
==1== 
==1== HEAP SUMMARY:
==1==     in use at exit: 0 bytes in 0 blocks
==1==   total heap usage: 25,249 allocs, 25,249 frees, 6,192,917 bytes allocated
==1== 
==1== All heap blocks were freed -- no leaks are possible
==1== 
==1== For lists of detected and suppressed errors, rerun with: -s
==1== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

Summary by CodeRabbit

  • New Features

    • Added support for HTTPS proxies and TLS-over-proxy (TLS‑in‑TLS) chaining.
    • Proxy URL parsing now accepts http/https and uses protocol-appropriate default ports.
  • Bug Fixes

    • Improved TLS handshake handling, error logging, and cleanup when using proxied connections.
  • Tests

    • Expanded test coverage for HTTPS proxy scenarios (explicit/default ports and credentials).

@antoniomrfranco antoniomrfranco changed the title Https proxy support feat: HTTPS proxy support May 6, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds HTTPS-proxy support with TLS-in-TLS chaining: proxy URL parsing accepts https, upstreams can hold a proxy TLS context, OpenSSL backend can chain an inner TLS session to an outer TLS session, and a proxy TLS handshake is performed before HTTP CONNECT tunneling.

Changes

HTTPS Proxy with TLS-in-TLS Support

Layer / File(s) Summary
Data Shape / API hooks
include/fluent-bit/flb_upstream.h, include/fluent-bit/tls/flb_tls.h
Add proxy_tls_context to struct flb_upstream (guarded by FLB_HAVE_TLS) and add int (*session_set_outer)(void *inner, void *outer); to the TLS backend interface.
Proxy URL parsing
src/flb_utils.c
Accept http and https (when TLS enabled) as proxy schemes and use protocol-dependent default ports (80/443) for bracketed and non-bracketed hosts.
Upstream creation / teardown
src/flb_upstream.c
When an HTTPS proxy is detected, create and attach a dedicated TLS context to the upstream; on failure abort creation and free proxy resources. Destroy the proxy TLS context during upstream teardown.
Proxy handshake integration
src/flb_io.c
If proxy_tls_context is configured, perform TLS handshake to proxy before executing HTTP CONNECT; on handshake failure close fd, reset state, and return error. Enable TLS on the stream so subsequent I/O uses the proxy TLS session.
TLS session orchestration
src/tls/flb_tls.c
Refine SNI/vhost selection (prefer explicit tls->vhost, then proxied_host, then tcp_host) and, when an outer TLS session exists, chain the new inner session via the backend session_set_outer hook with error handling.
OpenSSL backend wiring
src/tls/openssl.c
Add outer_session to per-session struct; implement tls_session_set_outer to wrap outer SSL with a BIO and attach to inner SSL; update session destroy to detach/free outer session; register session_set_outer in backend.
Tests
tests/internal/utils.c, tests/internal/upstream_tls.c
Expand proxy URL parsing tests for HTTPS variants and add upstream tests to assert proxy_tls_context presence for HTTPS proxies and absence for HTTP proxies.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Proxy as HTTPS Proxy
    participant Server
    participant OpenSSL as OpenSSL Backend

    Client->>Proxy: TCP connect
    Client->>Proxy: TLS handshake (outer)
    Proxy-->>Client: Outer TLS established
    Note over Client,OpenSSL: Outer session available

    Client->>Proxy: HTTP CONNECT (over outer TLS)
    Proxy-->>Client: 200 OK

    Client->>Server: TCP connect through tunnel
    Client->>Server: TLS handshake for destination (inner)
    OpenSSL->>OpenSSL: Chain inner TLS session to outer via session_set_outer/BIO
    Server-->>Client: Inner TLS established
    Client->>Server: Application traffic (nested TLS)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • edsiper
  • fujimotos
  • koleini

Poem

🐰 I hop through tunnels, soft and bright,
Outer cloak then inner light.
I stitch the BIO, snug and neat,
Proxy handshakes drum the beat.
Nested TLS — hop, hop, repeat!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'tls: support HTTPS proxy' directly and clearly describes the main feature added: support for HTTPS proxies with TLS, which is evident across all changed files that implement TLS-in-TLS proxy handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@antoniomrfranco antoniomrfranco changed the title feat: HTTPS proxy support tls: support HTTPS proxy May 6, 2026
@antoniomrfranco antoniomrfranco marked this pull request as ready for review May 6, 2026 14:10
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: daf51056d3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/flb_upstream.c
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/flb_io.c`:
- Around line 146-159: The proxy TLS session is created too late for the CONNECT
exchange; set the connection to use TLS before calling
flb_http_client_proxy_connect so flb_io_net_write()/flb_io_net_read() use the
TLS session (e.g., after flb_tls_session_create(...) succeeds, set
connection->io.flags |= FLB_IO_TLS), then call
flb_http_client_proxy_connect(...). If the ultimate upstream endpoint is plain
HTTP (no upstream TLS), clear the flag after a successful CONNECT
(connection->io.flags &= ~FLB_IO_TLS) so subsequent traffic uses plaintext
inside the established tunnel; reference flb_tls_session_create,
flb_http_client_proxy_connect, flb_io_net_write, flb_io_net_read, and the
FLB_IO_TLS flag when making this change.

In `@src/flb_upstream.c`:
- Around line 347-352: The proxy TLS context created by flb_tls_create for
u->proxy_tls_context is leaving hostname verification disabled, weakening the
proxy leg; after creating u->proxy_tls_context enable hostname verification (set
its verify_hostname flag) — e.g. call the appropriate API such as
flb_tls_set_verify_hostname(u->proxy_tls_context, FLB_TRUE) or directly set
u->proxy_tls_context->verify_hostname = FLB_TRUE if no setter exists — so the
proxy TLS hop enforces certificate name checks just like the destination leg.

In `@src/flb_utils.c`:
- Around line 1872-1875: The code currently allows "https" in the protocol
variable and logs only a generic error, causing broken behavior when the build
lacks TLS; update the conditional that checks protocol (the strcmp calls) to
also check the FLB_HAVE_TLS compile-time flag and, if FLB_HAVE_TLS is not
defined, treat "https" as unsupported: call flb_error with a descriptive message
and goto error (same error path). In other words, augment the existing protocol
check to reject "https" when FLB_HAVE_TLS is not enabled so CONNECT attempts
cannot proceed in non-TLS builds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b65c4757-d5fe-4e45-b7a7-d44d20e2b6b9

📥 Commits

Reviewing files that changed from the base of the PR and between eae3ebf and daf5105.

📒 Files selected for processing (8)
  • include/fluent-bit/flb_upstream.h
  • include/fluent-bit/tls/flb_tls.h
  • src/flb_io.c
  • src/flb_upstream.c
  • src/flb_utils.c
  • src/tls/flb_tls.c
  • src/tls/openssl.c
  • tests/internal/utils.c

Comment thread src/flb_io.c
Comment thread src/flb_upstream.c
Comment thread src/flb_utils.c Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/flb_utils.c (1)

1833-1837: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update stale proxy parser comment to match new behavior.

The function header still says “currently only HTTP is supported,” but Line 1872+ now supports HTTPS when TLS is enabled. Please update this comment to avoid misleading future maintainers.

✏️ Suggested doc-comment fix
- * Note: currently only HTTP is supported.
+ * Note: HTTP is always supported; HTTPS is supported when built with TLS.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/flb_utils.c` around lines 1833 - 1837, The doc-comment for
flb_utils_proxy_url_split is outdated stating “currently only HTTP is
supported”; update the header comment to reflect that the parser now accepts
HTTPS when TLS is enabled and clarify supported URL forms (e.g.
`http://[user:pass@]host:port` and `https://[user:pass@]host:port` with TLS
conditional support). Edit the comment above flb_utils_proxy_url_split to remove
the HTTP-only note and add a brief line about HTTPS support when TLS is enabled
and any relevant limitations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/flb_utils.c`:
- Around line 1833-1837: The doc-comment for flb_utils_proxy_url_split is
outdated stating “currently only HTTP is supported”; update the header comment
to reflect that the parser now accepts HTTPS when TLS is enabled and clarify
supported URL forms (e.g. `http://[user:pass@]host:port` and
`https://[user:pass@]host:port` with TLS conditional support). Edit the comment
above flb_utils_proxy_url_split to remove the HTTP-only note and add a brief
line about HTTPS support when TLS is enabled and any relevant limitations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 27d9809d-2c6b-4131-ba81-84a19d90045a

📥 Commits

Reviewing files that changed from the base of the PR and between daf5105 and 07101af.

📒 Files selected for processing (1)
  • src/flb_utils.c

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/flb_upstream.c (1)

379-382: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

flb_free(u) here leaks proxy_tls_context (and pre-existing siblings) on the OOM path.

If the flb_strdup(proxy_host) at line 329 fails (OOM), control still falls through the new block at lines 339-366 and may allocate u->proxy_tls_context, plus the already-existing u->proxied_host, u->proxy_username, u->proxy_password. Then this branch only flb_free(u)s the struct, leaking all of them. Use flb_upstream_destroy(u) to centralize cleanup; it now also handles proxy_tls_context (lines 720-725).

🛡️ Proposed fix
     if (!u->tcp_host) {
-        flb_free(u);
+        flb_upstream_destroy(u);
         return NULL;
     }

Note: flb_upstream_destroy walks the queues (initialized to empty here) and the TLS cleanup is NULL-guarded, so calling it on a partially-initialized upstream is safe. Verify the upstream isn't already linked into config->upstreams at this point (it isn't — mk_list_add happens at line 389).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/flb_upstream.c` around lines 379 - 382, The free-on-OOM path currently
calls flb_free(u) which leaks allocated fields like u->proxy_tls_context,
u->proxied_host, u->proxy_username and u->proxy_password after a failed
flb_strdup(proxy_host); replace the raw flb_free(u) call with
flb_upstream_destroy(u) so the centralized destructor frees all subsidiary
allocations (including proxy_tls_context), noting it is safe here because the
upstream has not yet been linked via mk_list_add; ensure the conditional that
checks !u->tcp_host uses flb_upstream_destroy(u) instead of flb_free(u).
🧹 Nitpick comments (1)
src/flb_upstream.c (1)

339-366: 🏗️ Heavy lift

Proxy TLS context has no user-configurable options for CA, client certs, or verification.

flb_tls_create() is called with NULL for ca_path, ca_file, crt_file, key_file, and key_passwd, and verify/verify_hostname are hard-coded to FLB_TRUE. The proxy TLS context is intentionally separate from the destination TLS context (per the code comment), so destination tls.* settings do not apply to the proxy leg either.

Practical impact:

  • Users behind a corporate HTTPS proxy with a private CA cannot point to a custom CA bundle for the proxy handshake; the connection will fail when OpenSSL falls back to the system default trust store.
  • Mutual-TLS proxies are not supported (no client cert/key plumbing).
  • No escape hatch exists to disable verification for testing or override CA validation.

Web search confirms Fluent Bit currently has no proxy_tls.* or net.proxy_tls.* configuration options to expose these settings.

Since the PR is already marked docs-required, at minimum document this limitation. For broader usability, consider either propagating the destination tls context's CA/verify settings as sensible defaults, or introducing dedicated proxy_tls.* config entries to allow per-proxy TLS customization.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/flb_upstream.c` around lines 339 - 366, The proxy TLS context is created
with flb_tls_create(...) using NULL for ca_path, ca_file, crt_file, key_file,
key_passwd and hard-coded verification via flb_tls_set_verify_hostname(...),
preventing custom CA, client certs, or verification control for HTTPS proxies;
update the upstream/proxy config parsing to accept proxy-specific TLS options
(e.g., proxy_ca_path, proxy_ca_file, proxy_crt_file, proxy_key_file,
proxy_key_passwd, proxy_verify/verify_hostname) or, if not introducing new
options, propagate the destination tls.* settings into the proxy leg, then pass
those variables into flb_tls_create when creating u->proxy_tls_context and set
verification with flb_tls_set_verify_hostname using the configured flag (and
ensure proper freeing/error handling for the new strings like proxy_host,
proxy_port, proxy_username, proxy_password on failure), and add docs noting the
new options or the propagated behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/flb_upstream.c`:
- Around line 379-382: The free-on-OOM path currently calls flb_free(u) which
leaks allocated fields like u->proxy_tls_context, u->proxied_host,
u->proxy_username and u->proxy_password after a failed flb_strdup(proxy_host);
replace the raw flb_free(u) call with flb_upstream_destroy(u) so the centralized
destructor frees all subsidiary allocations (including proxy_tls_context),
noting it is safe here because the upstream has not yet been linked via
mk_list_add; ensure the conditional that checks !u->tcp_host uses
flb_upstream_destroy(u) instead of flb_free(u).

---

Nitpick comments:
In `@src/flb_upstream.c`:
- Around line 339-366: The proxy TLS context is created with flb_tls_create(...)
using NULL for ca_path, ca_file, crt_file, key_file, key_passwd and hard-coded
verification via flb_tls_set_verify_hostname(...), preventing custom CA, client
certs, or verification control for HTTPS proxies; update the upstream/proxy
config parsing to accept proxy-specific TLS options (e.g., proxy_ca_path,
proxy_ca_file, proxy_crt_file, proxy_key_file, proxy_key_passwd,
proxy_verify/verify_hostname) or, if not introducing new options, propagate the
destination tls.* settings into the proxy leg, then pass those variables into
flb_tls_create when creating u->proxy_tls_context and set verification with
flb_tls_set_verify_hostname using the configured flag (and ensure proper
freeing/error handling for the new strings like proxy_host, proxy_port,
proxy_username, proxy_password on failure), and add docs noting the new options
or the propagated behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9773efe6-4295-467e-80b9-538e5e705d9a

📥 Commits

Reviewing files that changed from the base of the PR and between 07101af and 4a22ce3.

📒 Files selected for processing (2)
  • src/flb_io.c
  • src/flb_upstream.c

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/flb_upstream.c (1)

318-330: ⚡ Quick win

Use centralized teardown in the proxy URL split failure branch as well.

At Line [329], this path still calls flb_free(u) directly. It should follow the same centralized cleanup path (flb_upstream_destroy(u)) and free any partially filled proxy_* outputs first.

Proposed patch
         ret = flb_utils_proxy_url_split(config->http_proxy, &proxy_protocol,
                                         &proxy_username, &proxy_password,
                                         &proxy_host, &proxy_port);
         if (ret == -1) {
-            flb_free(u);
+            flb_free(proxy_protocol);
+            flb_free(proxy_host);
+            flb_free(proxy_port);
+            flb_free(proxy_username);
+            flb_free(proxy_password);
+            flb_upstream_destroy(u);
             return NULL;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/flb_upstream.c` around lines 318 - 330, The error path after
flb_utils_proxy_url_split() failure currently calls flb_free(u) directly; change
it to perform centralized teardown by freeing any partially populated proxy_*
outputs (proxy_protocol, proxy_username, proxy_password, proxy_host, proxy_port)
as appropriate and then call flb_upstream_destroy(u) before returning NULL.
Locate the branch where flb_utils_proxy_url_split() returns -1 (within the
flb_upstream_needs_proxy() block) and replace the flb_free(u) call with code
that cleans up the proxy_* variables and invokes flb_upstream_destroy(u) to
ensure consistent centralized cleanup started by flb_upstream_queue_init().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/flb_upstream.c`:
- Around line 318-330: The error path after flb_utils_proxy_url_split() failure
currently calls flb_free(u) directly; change it to perform centralized teardown
by freeing any partially populated proxy_* outputs (proxy_protocol,
proxy_username, proxy_password, proxy_host, proxy_port) as appropriate and then
call flb_upstream_destroy(u) before returning NULL. Locate the branch where
flb_utils_proxy_url_split() returns -1 (within the flb_upstream_needs_proxy()
block) and replace the flb_free(u) call with code that cleans up the proxy_*
variables and invokes flb_upstream_destroy(u) to ensure consistent centralized
cleanup started by flb_upstream_queue_init().

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cbd45429-0ce2-4dc2-86e9-f533e2b0a9ef

📥 Commits

Reviewing files that changed from the base of the PR and between 4a22ce3 and 665d27a.

📒 Files selected for processing (1)
  • src/flb_upstream.c

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/internal/upstream_tls.c (1)

154-156: ⚡ Quick win

Strengthen the HTTP-proxy test by keeping upstream transport as TLS.

This case currently uses FLB_IO_TCP, so it doesn’t fully isolate “proxy scheme decides proxy TLS context.” Using FLB_IO_TLS here would better catch regressions where http:// might incorrectly create proxy TLS when destination transport is TLS.

Suggested tweak
-    u = flb_upstream_create(config, "dest.example.com", 80,
-                            FLB_IO_TCP, NULL);
+    u = flb_upstream_create(config, "dest.example.com", 443,
+                            FLB_IO_TLS, NULL);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/internal/upstream_tls.c` around lines 154 - 156, The test creates the
upstream with FLB_IO_TCP which doesn't exercise TLS behavior; change the
transport passed to flb_upstream_create so the upstream uses TLS by replacing
FLB_IO_TCP with FLB_IO_TLS in the flb_upstream_create call that assigns to
variable u (destination "dest.example.com", port 80) so the test keeps the
upstream transport as TLS and validates proxy-scheme TLS handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/internal/upstream_tls.c`:
- Around line 154-156: The test creates the upstream with FLB_IO_TCP which
doesn't exercise TLS behavior; change the transport passed to
flb_upstream_create so the upstream uses TLS by replacing FLB_IO_TCP with
FLB_IO_TLS in the flb_upstream_create call that assigns to variable u
(destination "dest.example.com", port 80) so the test keeps the upstream
transport as TLS and validates proxy-scheme TLS handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: df0213b8-27f5-4429-836e-a5fac21761a8

📥 Commits

Reviewing files that changed from the base of the PR and between 665d27a and b89e9a7.

📒 Files selected for processing (2)
  • tests/internal/upstream_tls.c
  • tests/internal/utils.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/internal/utils.c

Accept https:// in flb_utils_proxy_url_split alongside http://.
Default port for https:// proxies is 443.  Error messages and the
default-port strdup calls are guarded behind FLB_HAVE_TLS so that
non-TLS builds retain the original behaviour and error message
('only HTTP proxy is supported.').

Signed-off-by: Antônio Franco <13881523+antoniomrfranco@users.noreply.github.com>
When the configured proxy URL uses https://, create a dedicated
flb_tls context (proxy_tls_context) for the proxy TLS leg, stored
in struct flb_upstream and freed in flb_upstream_destroy.

The context uses the proxy hostname as its SNI vhost, and hostname
verification is explicitly enabled via flb_tls_set_verify_hostname
so the proxy certificate is fully validated.

Also fixes two error-path bugs in flb_upstream_create:
- flb_upstream_queue_init is now called immediately after
  flb_stream_setup so all subsequent error paths can safely call
  flb_upstream_destroy for centralised cleanup.
- The unzip>tcp_host OOM check now calls flb_upstream_destroy instead
  of bare flb_free, preventing leaks of proxied_host,
  proxy_username, proxy_password, and proxy_tls_context.

Signed-off-by: Antônio Franco <13881523+antoniomrfranco@users.noreply.github.com>
In flb_io_net_connect, when the upstream has a proxy_tls_context,
perform a TLS handshake with the proxy before sending the HTTP
CONNECT request.

After a successful proxy TLS handshake, enable FLB_IO_TLS on the
stream so that flb_io_net_write/read route all subsequent I/O
(the CONNECT request and post-CONNECT data) through the proxy TLS
session.  Without this flag, plain-HTTP destinations would fall
through to an unhandled path because their stream flags do not
include FLB_IO_TLS.  For HTTPS destinations the flag is already
set, making this a no-op.

Signed-off-by: Antônio Franco <13881523+antoniomrfranco@users.noreply.github.com>
Two related changes:

SNI priority fix: when the TLS context carries an explicit vhost
(e.g. the proxy hostname on a proxy TLS context), that vhost now
takes priority over proxied_host in flb_tls_session_create.
Previously proxied_host was used unconditionally for upstream
connections, causing the proxy TLS handshake to advertise the
destination hostname instead of the proxy hostname.

TLS-in-TLS chaining: add session_set_outer to struct flb_tls_backend
and implement tls_session_set_outer in the OpenSSL backend using
BIO_f_ssl.  When flb_tls_session_create detects an existing
tls_session on the connection (the proxy TLS session), it chains
the new inner session's I/O through the outer session via
SSL_set_bio, so that the destination TLS handshake travels inside
the already-established proxy TLS tunnel rather than going directly
to the raw socket.

Signed-off-by: Antônio Franco <13881523+antoniomrfranco@users.noreply.github.com>
Extend proxy_url_checks in utils.c with HTTPS proxy cases
(explicit port, default port 443, credentials) and rejection
cases for unsupported schemes (ftp://, socks5://).

Add two tests to upstream_tls.c: one verifies that
flb_upstream_create with an https:// proxy sets a non-NULL
proxy_tls_context with verify_hostname enabled; another verifies
that a plain http:// proxy leaves proxy_tls_context NULL.

Signed-off-by: Antônio Franco <13881523+antoniomrfranco@users.noreply.github.com>
@antoniomrfranco
Copy link
Copy Markdown
Author

Hi @edsiper, @cosmo0920,

Would this be something you'd consider for a future release? Happy to adjust scope, split further, or address any concerns before this is ready for a deeper review.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant