blob: 4c5bfbe8473d350da7eb7f1573bf568aad7803e1 [file]
#include <fcntl.h>
#include <memory>
#include <string>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "grpc/grpc_security_constants.h"
#include "grpcpp/ext/proto_server_reflection_plugin.h"
#include "grpcpp/security/authorization_policy_provider.h"
#include "grpcpp/security/server_credentials.h"
#include "proxy_builder.h"
#include "proxy_config.pb.h"
#include "tls_auth.h"
ABSL_FLAG(std::string, config_file, "",
"Proxy configuration textproto file (proxy_config.proto)");
using ::grpc::experimental::AuthorizationPolicyProviderInterface;
static absl::Status ValidateMtlsServerCredentials(
const milotic_grpc_proxy::MtlsServerCredentialsConfiguration& config) {
if (config.keypair_path().empty()) {
return absl::InvalidArgumentError("keypair_path is empty");
}
if (config.trust_bundle_path().empty()) {
return absl::InvalidArgumentError("trust_bundle_path is empty");
}
if (config.root_cert_name().empty()) {
return absl::InvalidArgumentError("root_cert_name is empty");
}
if (config.keypair_file_check_retry_duration_sec() <= 0) {
return absl::InvalidArgumentError(
"keypair_file_check_retry_duration_sec is invalid");
}
if (config.keypair_refresh_interval_sec() <= 0) {
return absl::InvalidArgumentError(
"keypair_refresh_interval_sec is invalid");
}
if (config.authz_policy_path().empty()) {
return absl::InvalidArgumentError("authz_policy_path is empty");
}
if (config.authz_policy_refresh_interval_sec() <= 0) {
return absl::InvalidArgumentError(
"authz_policy_refresh_interval_sec is invalid");
}
return absl::OkStatus();
}
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
absl::StatusOr<milotic_grpc_proxy::Configuration> config =
milotic::internal::LoadConfig(absl::GetFlag(FLAGS_config_file));
if (!config.ok()) {
LOG(ERROR) << "Failed to load config: " << config.status();
return 1;
}
milotic::ProxyBuilder::Options options;
for (const auto& proxy : config->proxy_configuration()) {
if (proxy.grpc_configuration().has_mtls_server_credentials()) {
auto mtls_config = proxy.grpc_configuration().mtls_server_credentials();
if (!ValidateMtlsServerCredentials(mtls_config).ok()) {
LOG(ERROR) << "Invalid mtls server credentials: " << mtls_config;
return 1;
}
absl::StatusOr<std::shared_ptr<grpc::ServerCredentials>> creds =
auth::GetCredsInfo(mtls_config);
if (!creds.ok()) {
LOG(ERROR) << "Failed to get credentials: " << creds.status();
return 1;
}
LOG(INFO) << "Credentials loaded";
options.AddCredentials(
{.net_creds = *creds,
.uds_creds = grpc::experimental::LocalServerCredentials(UDS)});
absl::StatusOr<std::shared_ptr<AuthorizationPolicyProviderInterface>>
policy = auth::GetAuthPolicy(mtls_config);
if (!policy.ok()) {
LOG(ERROR) << "Failed to get authorization policy: " << policy.status();
return 1;
}
LOG(INFO) << "Authorization policy loaded";
options.AddAuthorizationPolicy(*policy);
} else {
options.AddCredentials(
{.net_creds = grpc::InsecureServerCredentials(),
.uds_creds = grpc::experimental::LocalServerCredentials(UDS)});
}
}
absl::StatusOr<milotic::ProxyBuilder> proxies =
milotic::ProxyBuilder::CreateAndStart(*config, options);
if (!proxies.ok()) {
LOG(ERROR) << "Failed to create and start proxies: " << proxies.status();
return 1;
}
absl::Status status = proxies->Wait();
if (!status.ok()) {
LOG(ERROR) << status;
return 1;
}
return 0;
}