Current state: [One of "Under Discussion", "Accepted", "Rejected"]
Discussion thread:
JIRA or Github Issue:
Released: <Doris Version>
Google Doc: <If the design in question is unclear or needs to be discussed and reviewed, a Google Doc can be used first to facilitate comments from others.>
Currently, some http interfaces provided by doris are not authenticated (account password check and global/ database/ table permission check are not performed). These interfaces have security problems and need to be authenticated.
In addition, http data is transmitted in plaintext, which is subject to eavesdropping, tampering, and impersonation risks. https is a secure SSL encryption transmission protocol. The doris interface supports https, which greatly improves its security and provides enterprise-level security support.
Add missing documents and tidy them up.
For unauthenticated http interfaces, execute CheckPassword and CheckGlobalAuth or CheckDbAuth or CheckTblAuth;
For partially authenticated http interfaces, only CheckPassword is executed, but CheckGlobalAuth or CheckDbAuth or CheckTblAuth is not executed.
Execute CheckGlobalAuth or CheckDbAuth or CheckTblAuth based on the permissions required by the interface, as shown in follow table:
接口名称 | 功能描述 | RequestMapping | 是否鉴权 |
MetaService | fe 元数据相关API,除`/dump` 以外,都为fe 节点之间内部通讯用,/dump 用于获取image 文件的存储路径 |
| 否(checkFromValidFe)1 |
GetSmallFileAction | 下载在文件管理器中的文件 | GET /api/get_small_file?token=xxx&file_id=xxx | 否(executeCheckPassword + checkGlobalAuth-PrivPredicate.ADMIN) |
HealthAction | 返回集群当前存活与宕机的be 节点数 | GET /api/health | 否(executeCheckPassword) |
MetaInfoAction | 获取集群内的元数据信息 |
| 是(checkWithCookie) |
ShowAction | 获取集群/数据库的相关信息 |
| 否(executeCheckPassword + checkGlobalAuth-PrivPredicate.ADMIN)1,3,4 |
StmtExecutionAction |
|
| 是(checkWithCookie) |
MetricsAction | 获取metrics | GET /metrics | 否(executeCheckPassword) |
BootstrapFinishAction | 判断fe 是否启动完成 | GET /api/bootstrap | 否(executeCheckPassword) |
ExtraBasepathAction | 返回接口API 的base path | GET /api/basepath | 否(executeCheckPassword) |
ImportAction | 查看格式为CSV 或PARQUET 的文件内容 | POST /api/import/file_review | 否(executeCheckPassword) |
StatisticAction | 获取集群统计信息、库表数量等 | GET /rest/v2/api/cluster_overview | 否(executeCheckPassword) |
BackendsAction | 返回be 列表,包括IP、PORT 等信息 | GET /api/backends | 是(executeCheckPassword) |
NOTE:
1. The enable_all_http_auth parameter is added to the fe configuration file. The default value is false, indicating that only the interfaces that have been authenticated before are authenticated. If it is set true, all interfaces (including the newly added interface authentication) are authenticated.
2. For BackendsAction, as required, the interface should require user have GlobalAuth-PrivPredicate.ADMIN permission. However, a user who uses spark-doris-connector/ flink-doris-connector does not have PrivPredicate.ADMIN permission, to ensure that the connector works properly, do not verify the permission of the interface.
3. For MetricsAction, account password is authenticated. You need to configure the account and password when you use Prometheus to collect monitoring items.
We implement https based on spring boot, and implement https through configuration and http coding.
Currently doris uses many ports, so http and https are not supported at the same time. We could choose http or https by setting "ssl_enable" in fe.conf.
Add ssl certificate configuration items in the fe configuration file, including the port number, certificate path, password, format, alias, and enable or disable (ssl is disabled by default).
| http_port https_port = 8040 ssl_key_store_path ssl_key_store_password ssl_key_store_type ssl_key_store_alias ssl_enable |
|---|
When fe is started, related configuration parameters are read into the HttpServer class, and then ssl parameters are configured using SpringApplicationBuilder().properties(properties).
| server.port = https_port // https端口 server.http.port = http_port // http端口 server.ssl.key-store = ssl_key_store_path // 证书路径 server.ssl.key-store-password = ssl_key_store_password // 证书密码 server.ssl.key-store-type = ssl_key_store_type // 密钥库类型 server.ssl.keyalias: ssl_key_store_alias // 证书别名 server.ssl.enabled = ssl_enable // 是否开启ssl |
|---|
Without metadata information stored in BE, it is necessary to perform an interactive authentication with FE, which is implemented through RPC calls as follows:
THttpAuthRequest { 1: optional string cluster } THttpAuthResult { 1. reuired Status.TStatus status } |
|---|
Each Interface requires different permissions, as follows:
handler | interface | whether performs authentication | permissions required | |
JeprofileActions | get | /jeheap/dump | no | none |
HeapAction | get | /pprof/heap | ||
GrowthAction | get | /pprof/growth | ||
ProfileAction | get | /pprof/profile | ||
PmuProfileAction | get | /pprof/pmuprofile | ||
ContentionAction | get | /pprof/contention | ||
CmdlineAction | get | /pprof/cmdline | ||
SymbolAction | get | /pprof/symbol | ||
head | /pprof/symbol | |||
put | /pprof/symbol | |||
StreamLoadAction | put | /api/{db}/{table}/_load | yes | LOAD |
put | /api/{db}/{table}/_stream_load | yes | LOAD | |
StreamLoad2PCAction | put | /api/{db}/_stream_load_2pc | yes | LOAD |
put | /api/{db}/{table}/_stream_load_2pc | yes | LOAD | |
DownloadAction | head | /api/_download_load | yes | USAGE |
head | /api/_tablet/_download | |||
head | /api/_load_error_log | |||
get | /api/_download_load | |||
get | /api/_tablet/_download | |||
get | /api/_load_error_log | |||
VersionAction | get | /api/be_version_info | yes | NODE |
HealthAction | get | /api/health | yes | none |
TabletsInfoAction | get | /tablets_json | yes | NODE |
TabletsDistributionAction | get | /api/tablets_distribution | yes | NODE |
TabletMigrationAction | get | /api/tablet_migration | yes | NODE |
MetricsAction | get | /metrics | no | none |
MetaAction | get | /api/meta/header/{tablet_id} | yes | NODE |
ChecksumAction | get | /api/checksum | yes | NODE |
ReloadTabletAction | get | /api/reload_tablet | yes | NODE |
post | /api/restore_tablet | yes | NODE | |
SnapshotAction | get | /api/snapshot | yes | NODE |
CompactionAction | get | /api/compaction/show | yes | NODE |
get | /api/compaction/run_status | yes | NODE | |
post | /api/compaction/run | yes | NODE | |
ConfigAction | get | /api/show_config | yes | NODE |
post | /api/update_config | yes | NODE | |
CheckRPCChannelAction | get | /api/check_rpc_channel/{ip}/{port}/{payload_size} | yes | NODE |
ResetRPCChannelAction | get | /api/reset_rpc_channel/{endpoints} | yes | NODE |
CheckTabletSegmentAction | post | /api/check_tablet_segment_lost | yes | NODE |
PadRowsetAction | post | /api/pad_rowset | yes | NODE |
In developmet environment, SSL certificates can be generated by openssl as follow:
openssl genrsa -out private.pem 1024 openssl req -new -x509 -days 3650 -key private.pem -out cert.pem -subj "/CN=my.host.name" |
|---|
In production environment, SSL certificates need to be purchased from the CA.
enable_https = true; |
|---|
Fill the sslOption with the path of certificate and private key before starting server.
if (config::enable_https) { |
|---|
In the brpc server, SSL-only mode can only be implemented using Controller::is_ssl() in callback of each service.
if (config::ssl_only && !cntl->is_ssl()) { |
|---|
A global configure for SSL-only mode may be better than the implementation described above, which would be supported by brpc in the future.
I will implement http interface authentication and https implementation of be and fe in turn, maybe it will take about 2 months to finish this feature:
https://clickhouse.com/docs/zh/interfaces/http
https://github.com/OKaluzny/springboot-rest-api-angularjs-https
https://github.com/apache/brpc/blob/master/docs/en/server.md#turn-on-ssl