Skip to content

Commit fea2728

Browse files
committed
feat: adding https mode to credentialConfig
Signed-off-by: Julius <juliusl@microsoft.com>
1 parent d5f4b06 commit fea2728

3 files changed

Lines changed: 77 additions & 1 deletion

File tree

README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,11 @@ Default configure file `overlaybd.json` is installed to `/etc/overlaybd/`.
193193
| gzipCacheConfig.cacheSizeGB | The max size of cache, in GB. |
194194
| gzipCacheConfig.refillSize | The refill size from source, in byte. `262144` is default (256 KB). |
195195
| credentialFilePath(legacy) | The credential used for fetching images on registry. `/opt/overlaybd/cred.json` is the default value. |
196-
| credentialConfig.mode | Authentication mode for lazy-loading. <br> - `file` means reading credential from `credentialConfig.path`. <br> - `http` means sending an http request to `credentialConfig.path` |
196+
| credentialConfig.mode | Authentication mode for lazy-loading. <br> - `file` means reading credential from `credentialConfig.path`. <br> - `http` means sending an http request to `credentialConfig.path` <br> - `https` means sending an https request with mTLS (mutual TLS) to `credentialConfig.path` |
197197
| credentialConfig.path | credential file path or url which is determined by `mode` |
198+
| credentialConfig.client_cert_path | Path to the client certificate file for mTLS (used by `https` mode) |
199+
| credentialConfig.client_key_path | Path to the client private key file for mTLS (used by `https` mode) |
200+
| credentialConfig.server_ca_path | Path to the CA certificate used to verify the server for mTLS (used by `https` mode) |
198201
| download.enable | Whether background downloading is enabled or not. |
199202
| download.delay | The seconds waiting to start downloading task after the overlaybd device launched. |
200203
| download.delayExtra | A random extra delay is attached to delay, avoiding too many tasks started at the same time. |
@@ -293,6 +296,30 @@ Overlaybd supports serveral credential mode. Here are some example `credentialCo
293296
```
294297
we write a sample http server in `test/simple_auth_server.cpp`
295298

299+
- mode **https**
300+
301+
the `credentialConfig.path` should be an HTTPS server listening address. This mode uses mTLS (mutual TLS) for secure communication with the auth server. The client presents its certificate and key, and verifies the server against a trusted CA certificate.
302+
303+
```json
304+
#### /etc/overlaybd/config.json ####
305+
{
306+
"logLevel": 1,
307+
"logPath": "/var/log/overlaybd.log",
308+
...
309+
"credentialConfig": {
310+
"mode": "https",
311+
"path": "https://localhost:19876/auth",
312+
"client_cert_path": "/etc/overlaybd/client.crt",
313+
"client_key_path": "/etc/overlaybd/client.key",
314+
"server_ca_path": "/etc/overlaybd/ca.crt"
315+
},
316+
...
317+
}
318+
```
319+
overlaybd will send an https request with mTLS to the server with `remote_url` like this:
320+
> GET "https://localhost:19876/auth?remote_url=https://hub.docker.com/v2/overlaybd/ubuntu/blobs/sha256:47e63559a8487efb55b2f1ccea9cfc04110a185c49785fdf1329d1ea462ce5f0"
321+
the server response format is the same as the `http` mode.
322+
296323

297324
## Usage
298325

src/config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ struct CredentialConfig : public ConfigUtils::Config {
9797
APPCFG_PARA(mode, std::string, "");
9898
APPCFG_PARA(path, std::string, "");
9999
APPCFG_PARA(timeout, int, 1);
100+
APPCFG_PARA(client_cert_path, std::string, "");
101+
APPCFG_PARA(client_key_path, std::string, "");
102+
APPCFG_PARA(server_ca_path, std::string, "");
100103
};
101104

102105
struct CacheConfig : public ConfigUtils::Config {

src/image_service.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,45 @@ int load_cred_from_http(const std::string addr /* http server */, const std::str
166166
return parse_auths(response.data().auths(), remote_path, username, password);
167167
}
168168

169+
int load_cred_from_https(const std::string addr /* https server */, const std::string &remote_path,
170+
std::string &username, std::string &password, int timeout,
171+
const std::string &client_cert_path, const std::string &client_key_path,
172+
const std::string &server_ca_path) {
173+
174+
auto request = new photon::net::cURL();
175+
DEFER({ delete request; });
176+
177+
// Configure mTLS: client certificate, client key, and server CA verification
178+
if (!server_ca_path.empty()) {
179+
request->set_cafile(server_ca_path.c_str());
180+
request->setopt(CURLOPT_SSL_VERIFYPEER, 1L).setopt(CURLOPT_SSL_VERIFYHOST, 2L);
181+
}
182+
if (!client_cert_path.empty() && !client_key_path.empty()) {
183+
request->setopt(CURLOPT_SSLCERT, client_cert_path.c_str());
184+
request->setopt(CURLOPT_SSLKEY, client_key_path.c_str());
185+
}
186+
187+
auto request_url = addr + "?remote_url=" + remote_path;
188+
LOG_INFO("request url: `", request_url);
189+
photon::net::StringWriter writer;
190+
auto ret = request->GET(request_url.c_str(), &writer, (int64_t)timeout * 1000000);
191+
if (ret != 200) {
192+
LOG_ERRNO_RETURN(0, -1, "connect to auth component failed. http response code: `", ret);
193+
}
194+
LOG_DEBUG(writer.string);
195+
ImageAuthResponse response;
196+
LOG_DEBUG("response size: `", writer.string.size());
197+
if (response.ParseJSONStream(writer.string) == false) {
198+
LOG_ERRNO_RETURN(0, -1, "parse http response message failed: `", writer.string);
199+
}
200+
LOG_INFO("traceId: `, succ: `", response.traceId(), response.success());
201+
if (response.success() == false) {
202+
LOG_ERRNO_RETURN(0, -1, "http request failed.");
203+
}
204+
ImageConfigNS::AuthConfig cfg;
205+
return parse_auths(response.data().auths(), remote_path, username, password);
206+
}
207+
169208
int ImageService::read_global_config_and_set() {
170209
LOG_INFO("using config `", m_config_path);
171210
if (!global_conf.ParseJSON(m_config_path)) {
@@ -241,6 +280,13 @@ ImageService::reload_auth(const char *remote_path) {
241280
} else if (mode == "http") {
242281
auto timeout = global_conf.credentialConfig().timeout();
243282
res = load_cred_from_http(path, std::string(remote_path), username, password, timeout);
283+
} else if (mode == "https") {
284+
auto timeout = global_conf.credentialConfig().timeout();
285+
auto client_cert = global_conf.credentialConfig().client_cert_path();
286+
auto client_key = global_conf.credentialConfig().client_key_path();
287+
auto server_ca = global_conf.credentialConfig().server_ca_path();
288+
res = load_cred_from_https(path, std::string(remote_path), username, password,
289+
timeout, client_cert, client_key, server_ca);
244290
} else {
245291
LOG_ERROR("invalid mode for authentication.");
246292
return std::make_pair("","");

0 commit comments

Comments
 (0)