| |
| #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; |
| } |