Skip to content
This repository was archived by the owner on Mar 24, 2026. It is now read-only.

Commit b503ce7

Browse files
Privacy Sandbox Teamcopybara-github
authored andcommitted
feat: Add tool for getting host /etc/resolv.conf
Bug: 311652459 Change-Id: I99238200bb27ffc16c6fee7e3ce7080a3f3a44c2 GitOrigin-RevId: 4f8952399815d0900f93d935c96895e81663fb11
1 parent a1c4af1 commit b503ce7

7 files changed

Lines changed: 300 additions & 1 deletion

File tree

scp/cc/aws/proxy/readme.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ If you'd like to try out this proxy with your own application, follow these step
7878
unlinks it and creates a new one with pre-defined content that defines the nameservers to 8.8.8.8
7979
and 1.1.1.1. This will make the enclave application talk to these servers during DNS resolution.
8080
It may not work in a private VPC without internet access. You may need to override the
81-
`/etc/resolv.conf` inside the enclave with your desired private DNS settings.
81+
`/etc/resolv.conf` inside the enclave with your desired private DNS settings. To use the host DNS
82+
settings within the enclave, run `./resolv_conf_getter_server &` on the host outside the enclave;
83+
Then run `/proxify /resolv_conf_getter_client` inside the enclave.
8284
1. AmazonLinux2 (AL2) uses an old version of glibc. Newer compilers with newer glibc on your build
8385
machine may generate binary that's not runnable on AL2. That's why we created
8486
`//scp/cc/aws/proxy:reproducible_proxy_outputs` target to generate binaries that's guaranteed

scp/cc/aws/proxy/src/BUILD.bazel

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,62 @@
2121
doesn't have std::filesystem, instead it's in std::experimental
2222
"""
2323

24+
load("@com_github_grpc_grpc//bazel:grpc_build_system.bzl", "grpc_proto_library")
2425
load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_layer")
26+
load("@rules_buf//buf:defs.bzl", "buf_lint_test")
2527
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
2628
load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_files")
2729
load("@rules_pkg//pkg:pkg.bzl", "pkg_tar")
30+
load("@rules_proto//proto:defs.bzl", "proto_library")
2831

2932
package(default_visibility = ["//scp/cc/aws/proxy/test:__subpackages__"])
3033

34+
cc_binary(
35+
name = "resolv_conf_getter_client",
36+
srcs = ["resolv_conf_getter_client.cc"],
37+
visibility = ["//visibility:public"],
38+
deps = [
39+
":resolv_conf_getter_grpc",
40+
"//scp/cc:cc_base_include_dir",
41+
"@com_github_grpc_grpc//:grpc++",
42+
"@com_google_absl//absl/flags:flag",
43+
"@com_google_absl//absl/flags:parse",
44+
"@com_google_absl//absl/status:statusor",
45+
"@com_google_absl//absl/strings",
46+
],
47+
)
48+
49+
cc_binary(
50+
name = "resolv_conf_getter_server",
51+
srcs = ["resolv_conf_getter_server.cc"],
52+
visibility = ["//visibility:public"],
53+
deps = [
54+
":resolv_conf_getter_grpc",
55+
"//scp/cc:cc_base_include_dir",
56+
"@com_github_grpc_grpc//:grpc++",
57+
"@com_google_absl//absl/flags:flag",
58+
"@com_google_absl//absl/flags:parse",
59+
"@com_google_absl//absl/strings",
60+
],
61+
)
62+
63+
proto_library(
64+
name = "resolv_conf_getter_proto",
65+
srcs = ["resolv_conf_getter.proto"],
66+
)
67+
68+
grpc_proto_library(
69+
name = "resolv_conf_getter_grpc",
70+
srcs = ["resolv_conf_getter.proto"],
71+
)
72+
73+
buf_lint_test(
74+
name = "resolv_conf_getter_proto_lint",
75+
size = "small",
76+
config = "//scp:buf.yaml",
77+
targets = [":resolv_conf_getter_proto"],
78+
)
79+
3180
cc_library(
3281
name = "acceptor_pool",
3382
hdrs = ["acceptor_pool.h"],
@@ -297,6 +346,7 @@ pkg_files(
297346
name = "proxify_executables",
298347
srcs = [
299348
"//scp/cc/aws/proxy/src:proxify",
349+
"//scp/cc/aws/proxy/src:resolv_conf_getter_client",
300350
"//scp/cc/aws/proxy/src:socket_vendor",
301351
],
302352
attributes = pkg_attributes(mode = "0555"),
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
syntax = "proto3";
16+
17+
package privacy_sandbox.server_common;
18+
19+
service ResolvConfGetterService {
20+
rpc GetResolvConf(GetResolvConfRequest) returns (GetResolvConfResponse) {}
21+
}
22+
23+
message GetResolvConfRequest {}
24+
25+
message GetResolvConfResponse {
26+
string content = 1;
27+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <fstream>
16+
#include <iostream>
17+
#include <memory>
18+
#include <string>
19+
#include <string_view>
20+
#include <utility>
21+
22+
#include <grpcpp/channel.h>
23+
#include <grpcpp/client_context.h>
24+
#include <grpcpp/create_channel.h>
25+
#include <grpcpp/security/credentials.h>
26+
27+
#include "absl/flags/flag.h"
28+
#include "absl/flags/parse.h"
29+
#include "absl/status/statusor.h"
30+
#include "absl/strings/str_cat.h"
31+
#include "aws/proxy/src/resolv_conf_getter.grpc.pb.h"
32+
33+
ABSL_FLAG(int, port, 1600, "Port on which client and server communicate.");
34+
35+
namespace {
36+
37+
using privacy_sandbox::server_common::GetResolvConfRequest;
38+
using privacy_sandbox::server_common::GetResolvConfResponse;
39+
using privacy_sandbox::server_common::ResolvConfGetterService;
40+
41+
class Client {
42+
public:
43+
explicit Client(std::shared_ptr<grpc::Channel> channel)
44+
: stub_(ResolvConfGetterService::NewStub(std::move(channel))) {}
45+
46+
absl::StatusOr<std::string> GetResolvConf() {
47+
grpc::ClientContext context;
48+
GetResolvConfResponse response;
49+
GetResolvConfRequest request;
50+
if (grpc::Status status =
51+
stub_->GetResolvConf(&context, request, &response);
52+
!status.ok()) {
53+
const grpc::StatusCode grpc_code = status.error_code();
54+
const absl::StatusCode absl_code = (grpc_code != grpc::DO_NOT_USE)
55+
? absl::StatusCode(grpc_code)
56+
: absl::StatusCode::kUnknown;
57+
return absl::Status(absl_code, std::move(status).error_message());
58+
}
59+
return response.content();
60+
}
61+
62+
private:
63+
std::unique_ptr<ResolvConfGetterService::Stub> stub_;
64+
};
65+
66+
} // namespace
67+
68+
int main(int argc, char** argv) {
69+
absl::ParseCommandLine(argc, argv);
70+
Client client(
71+
grpc::CreateChannel(absl::StrCat("localhost:", absl::GetFlag(FLAGS_port)),
72+
grpc::InsecureChannelCredentials()));
73+
const absl::StatusOr<std::string> content = client.GetResolvConf();
74+
if (!content.ok()) {
75+
std::cerr << content.status() << std::endl;
76+
return -1;
77+
}
78+
std::ofstream ofs("/etc/resolv.conf");
79+
ofs << R"resolv(
80+
; BEGIN Enclave configuration.
81+
; These lines are added by `resolv_conf_getter_client`.
82+
; use-vc forces use of TCP for DNS resolutions.
83+
; See https://man7.org/linux/man-pages/man5/resolv.conf.5.html
84+
options use-vc timeout:2 attempts:5
85+
; END Enclave configuration.
86+
)resolv";
87+
ofs << *content;
88+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <fstream>
16+
#include <iostream>
17+
#include <memory>
18+
#include <string>
19+
#include <string_view>
20+
#include <utility>
21+
22+
#include <grpcpp/security/server_credentials.h>
23+
#include <grpcpp/server.h>
24+
#include <grpcpp/server_builder.h>
25+
#include <grpcpp/server_context.h>
26+
27+
#include "absl/flags/flag.h"
28+
#include "absl/flags/parse.h"
29+
#include "absl/strings/str_cat.h"
30+
#include "aws/proxy/src/resolv_conf_getter.grpc.pb.h"
31+
32+
ABSL_FLAG(int, port, 1600, "Port on which client and server communicate.");
33+
34+
namespace {
35+
36+
using privacy_sandbox::server_common::GetResolvConfRequest;
37+
using privacy_sandbox::server_common::GetResolvConfResponse;
38+
using privacy_sandbox::server_common::ResolvConfGetterService;
39+
40+
class ResolvConfGetterImpl final : public ResolvConfGetterService::Service {
41+
public:
42+
grpc::Status GetResolvConf(grpc::ServerContext* /*context*/,
43+
const GetResolvConfRequest* /*request*/,
44+
GetResolvConfResponse* response) {
45+
std::ifstream ifs("/etc/resolv.conf");
46+
response->mutable_content()->assign((std::istreambuf_iterator<char>(ifs)),
47+
(std::istreambuf_iterator<char>()));
48+
return grpc::Status::OK;
49+
}
50+
};
51+
52+
} // namespace
53+
54+
int main(int argc, char** argv) {
55+
absl::ParseCommandLine(argc, argv);
56+
const std::string server_address =
57+
absl::StrCat("localhost:", absl::GetFlag(FLAGS_port));
58+
ResolvConfGetterImpl service;
59+
60+
grpc::ServerBuilder builder;
61+
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
62+
builder.RegisterService(&service);
63+
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
64+
std::cout << "Server listening on " << server_address << std::endl;
65+
server->Wait();
66+
}

scp/cc/aws/proxy/test/BUILD.bazel

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ sh_test(
9090
],
9191
)
9292

93+
sh_test(
94+
name = "resolv_conf_getter_test",
95+
size = "small",
96+
srcs = ["resolv_conf_getter_test_app"],
97+
args = [
98+
"$(location //scp/cc/aws/proxy/src:resolv_conf_getter_client)",
99+
"$(location //scp/cc/aws/proxy/src:resolv_conf_getter_server)",
100+
],
101+
data = [
102+
"//scp/cc/aws/proxy/src:resolv_conf_getter_client",
103+
"//scp/cc/aws/proxy/src:resolv_conf_getter_server",
104+
],
105+
)
106+
93107
sh_test(
94108
name = "preload_exported_symbols_test",
95109
size = "small",
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2023 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -o errexit
17+
set -o nounset
18+
set -o pipefail
19+
20+
readonly client_path="$1"
21+
readonly server_path="$2"
22+
23+
if ! [[ -x ${client_path} ]]; then
24+
printf "client: %s is not accessible\n" "${client_path}" &> /dev/stderr
25+
exit 1
26+
fi
27+
28+
if ! [[ -x ${server_path} ]]; then
29+
printf "server: %s is not accessible\n" "${server_path}" &> /dev/stderr
30+
exit 1
31+
fi
32+
33+
# Run the server, get pid.
34+
"${server_path}" &
35+
declare -i -r server_pid=$!
36+
function _cleanup() {
37+
local -r -i STATUS=$?
38+
if [[ -v server_pid ]]; then
39+
kill ${server_pid}
40+
fi
41+
exit ${STATUS}
42+
}
43+
trap _cleanup EXIT
44+
sleep 1
45+
46+
"${client_path}"
47+
declare -i NS_COUNT
48+
NS_COUNT=$(grep -cw ^nameserver /etc/resolv.conf)
49+
if [[ ${NS_COUNT} -eq 0 ]]; then
50+
printf "resolv.conf contains no nameserver entries\n"
51+
exit 1
52+
fi

0 commit comments

Comments
 (0)