Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add white list for graph connection ip and port #221

Merged
merged 2 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package com.baidu.hugegraph.controller;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.regex.Pattern;

Expand All @@ -35,30 +37,33 @@

import com.baidu.hugegraph.common.Constant;
import com.baidu.hugegraph.common.Response;
import com.baidu.hugegraph.config.HugeConfig;
import com.baidu.hugegraph.driver.HugeClient;
import com.baidu.hugegraph.entity.GraphConnection;
import com.baidu.hugegraph.exception.ExternalException;
import com.baidu.hugegraph.exception.InternalException;
import com.baidu.hugegraph.options.HubbleOptions;
import com.baidu.hugegraph.service.GraphConnectionService;
import com.baidu.hugegraph.service.HugeClientPoolService;
import com.baidu.hugegraph.service.license.LicenseService;
import com.baidu.hugegraph.util.HubbleUtil;
import com.baidu.hugegraph.util.Ex;
import com.baidu.hugegraph.util.HubbleUtil;
import com.baidu.hugegraph.util.HugeClientUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;

import lombok.extern.log4j.Log4j2;

@Log4j2
@RestController
@RequestMapping(Constant.API_VERSION + "graph-connections")
public class GraphConnectionController extends BaseController {

private static final Pattern GRAPH_PATTERN = Pattern.compile(
"^[A-Za-z][A-Za-z0-9_]{0,47}$"
);
private static final Pattern HOST_PATTERN = Pattern.compile(
"(([0-9]{1,3}\\.){3}[0-9]{1,3}|" +
"([0-9A-Za-z_!~*'()-]+\\.)*[0-9A-Za-z_!~*'()-]+)$"
);

@Autowired
private HugeConfig config;
@Autowired
private GraphConnectionService connService;
@Autowired
Expand Down Expand Up @@ -123,6 +128,7 @@ public GraphConnection create(@RequestBody GraphConnection newEntity) {
verifyResult.getMessage());

this.checkParamsValid(newEntity, true);
this.checkAddressSecurity(newEntity);
// Make sure the new entity doesn't conflict with exists
this.checkEntityUnique(newEntity, true);

Expand All @@ -148,6 +154,7 @@ public GraphConnection update(@PathVariable("id") int id,
@RequestBody GraphConnection newEntity) {
this.checkIdSameAsBody(id, newEntity);
this.checkParamsValid(newEntity, false);
this.checkAddressSecurity(newEntity);

// Check exist connection with this id
GraphConnection oldEntity = this.connService.get(id);
Expand Down Expand Up @@ -204,7 +211,8 @@ private void checkParamsValid(GraphConnection newEntity, boolean creating) {

String host = newEntity.getHost();
this.checkParamsNotEmpty("host", host, creating);
Ex.check(host != null, () -> HOST_PATTERN.matcher(host).matches(),
Ex.check(host != null, () -> HubbleUtil.HOST_PATTERN.matcher(host)
.matches(),
"graph-connection.host.unmatch-regex");

Integer port = newEntity.getPort();
Expand All @@ -217,6 +225,33 @@ private void checkParamsValid(GraphConnection newEntity, boolean creating) {
"common.param.must-be-null", "create_time");
}

private void checkAddressSecurity(GraphConnection newEntity) {
String host = newEntity.getHost();
Integer port = newEntity.getPort();
InetAddress address;
try {
address = InetAddress.getByName(host);
} catch (UnknownHostException e) {
throw new ExternalException("graph-connection.host.unresolved");
}
String ip = address.getHostAddress();
log.debug("The host: {}, ip: {}", address.getHostName(), ip);

List<String> ipWhiteList = this.config.get(
HubbleOptions.CONNECTION_IP_WHITE_LIST);
if (!ipWhiteList.contains("*")) {
Ex.check(ipWhiteList.contains(host) || ipWhiteList.contains(ip),
"graph-connection.host.unauthorized");
}

List<Integer> portWhiteList = this.config.get(
HubbleOptions.CONNECTION_PORT_WHITE_LIST);
if (!portWhiteList.contains(-1)) {
Ex.check(portWhiteList.contains(port),
"graph-connection.port.unauthorized");
}
}

private void checkEntityUnique(GraphConnection newEntity,
boolean creating) {
List<GraphConnection> oldEntities = this.connService.listAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@
import static com.baidu.hugegraph.config.OptionChecker.disallowEmpty;
import static com.baidu.hugegraph.config.OptionChecker.rangeInt;

import org.springframework.util.CollectionUtils;

import com.baidu.hugegraph.config.ConfigListOption;
import com.baidu.hugegraph.config.ConfigOption;
import com.baidu.hugegraph.config.OptionHolder;
import com.baidu.hugegraph.util.HubbleUtil;

public class HubbleOptions extends OptionHolder {

Expand Down Expand Up @@ -65,6 +69,46 @@ public static synchronized HubbleOptions instance() {
8088
);

public static final ConfigListOption<String> CONNECTION_IP_WHITE_LIST =
new ConfigListOption<>(
"graph_connection.ip_white_list",
"The ip white list available for connecting to " +
"HugeGraphServer, * means no ip limited.",
input -> {
if (CollectionUtils.isEmpty(input)) {
return false;
}
if (input.contains("*") && input.size() > 1) {
return false;
}
for (String ip : input) {
if (!HubbleUtil.HOST_PATTERN.matcher(ip)
.matches()) {
return false;
}
}
return true;
},
"*"
);

public static final ConfigListOption<Integer> CONNECTION_PORT_WHITE_LIST =
new ConfigListOption<>(
"graph_connection.port_white_list",
"The port white list available for connecting to " +
"HugeGraphServer, -1 means no port limited.",
input -> {
if (CollectionUtils.isEmpty(input)) {
return false;
}
if (input.contains(-1) && input.size() > 1) {
return false;
}
return true;
},
-1
);

public static final ConfigOption<Integer> GREMLIN_SUFFIX_LIMIT =
new ConfigOption<>(
"gremlin.suffix_limit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@
import java.time.Instant;
import java.util.Collection;
import java.util.Date;
import java.util.regex.Pattern;

import org.apache.commons.collections.CollectionUtils;

public final class HubbleUtil {

public static final Pattern HOST_PATTERN = Pattern.compile(
"(([0-9]{1,3}\\.){3}[0-9]{1,3}|" +
"([0-9A-Za-z_!~*'()-]+\\.)*[0-9A-Za-z_!~*'()-]+)$"
);

public static Date nowDate() {
return new Date();
}
Expand Down
3 changes: 3 additions & 0 deletions hubble-be/src/main/resources/hugegraph-hubble.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
server.host=localhost
server.port=8088

graph_connection.ip_white_list=[*]
graph_connection.port_white_list=[-1]

gremlin.suffix_limit=250
gremlin.vertex_degree_limit=100
gremlin.edges_total_limit=500
Expand Down
9 changes: 6 additions & 3 deletions hubble-be/src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ service.unknown-host=The host {0} is unknown
graph-connection.name.unmatch-regex=Invalid connection name, valid name is up to 48 alpha-numeric characters and underscores
graph-connection.graph.unmatch-regex=Invalid connection graph, valid graph is up to 48 alpha-numeric characters and underscores and only letters are supported as first letter
graph-connection.graph.unexist=There is no graph with the name {0} on service {1}:{2}
graph-connection.host.unmatch-regex=Invalid connection host, valid host is ip address or alpha-numeric characters and some special symbol like: _!~*'()-.
graph-connection.host.unmatch-regex=Invalid connection host, valid host is IP address or alpha-numeric characters and some special symbol like: _!~*'()-.
graph-connection.host.unresolved=Unresolved host or IP
graph-connection.host.unauthorized=Unauthorized host or IP
graph-connection.port.must-be-in-range=The param port must be in the range of {0}, but got {1}
graph-connection.port.unauthorized=Unauthorized port
graph-connection.username-or-password.incorrect=Incorrect username or password
graph-connection.exist.name=Already exists connection with same name {0}
graph-connection.exist.graph-host-port=Already exists connection with same graph {0}, host {1} and port {2}
Expand Down Expand Up @@ -118,6 +121,6 @@ license.verify.version.unmatch=The hugegraph-hubble's version {0} exceeded the a
license.verify.graphs.exceed=The hugegraph-hubble's graphs {0} exceeded the authorized {1}
license.verify.datasize.exceed=The hugegraph-hubble's graph {0} data size {1}MB exceeded the authorized {2}MB
license.datasize.no-limit=no limit
license.verify.ip.unauthorized=The hugegraph-hubble's ip {0} doesn't match the authorized {1}
license.verfiy.mac-unmatch-ip=Failed to get mac address for ip {0}
license.verify.ip.unauthorized=The hugegraph-hubble's IP {0} doesn't match the authorized {1}
license.verfiy.mac-unmatch-ip=Failed to get mac address for IP {0}
license.verify.mac.unauthorized=The hugegraph-hubble's mac {0} doesn't match the authorized {1}
3 changes: 3 additions & 0 deletions hubble-be/src/main/resources/i18n/messages_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ graph-connection.name.unmatch-regex=连接名不合法,连接名允许字母
graph-connection.graph.unmatch-regex=连接的图名不合法,图名应该由字母,数字以及下划线组成,第一个字符必须是字母,最多 48 个字符
graph-connection.graph.unexist=不存在名字为 {0} 的图在服务 {1}:{2} 上
graph-connection.host.unmatch-regex=连接的主机名不合法, 主机名应该由字母,数字以及一些特殊字符组成,比如:_!~*'()-.
graph-connection.host.unresolved=无法解析的主机名或 IP
graph-connection.host.unauthorized=未经授权的主机名或 IP
graph-connection.port.must-be-in-range=端口号必须属于区间 {0},但实际为 {1}
graph-connection.port.unauthorized=未经授权的端口
graph-connection.username-or-password.incorrect=用户名或密码不正确
graph-connection.exist.name=图 id {0} 已存在
graph-connection.exist.graph-host-port=已存在相同的图名 {0}, 主机名 {1} 和端口号 {2} 的图连接
Expand Down