eureka 添加白名单限制 支持正则配置
- 问题 有同学本地启动prd配置,注册到生产环境,造成服务不可用,p0级生产事故
- 事后复盘 本地禁止连接生产环境,验证问题可以同步数据到dev test验证,
- 生产环境注册中心添加白名单限制
eureka 白名单限制实现
@Slf4j
public class CustomInstanceRegistry extends PeerAwareInstanceRegistryImpl
implements ApplicationContextAware {
private ApplicationContext ctxt;
private List<String> allowedRegisteredIpAddress;
public CustomInstanceRegistry(EurekaServerConfig serverConfig,
EurekaClientConfig clientConfig, ServerCodecs serverCodecs,
EurekaClient eurekaClient,
List<String> allowedRegisteredIpAddress) {
super(serverConfig, clientConfig, serverCodecs, eurekaClient);
this.allowedRegisteredIpAddress=allowedRegisteredIpAddress;
}
public CustomInstanceRegistry(EurekaServerConfig serverConfig, EurekaClientConfig clientConfig, ServerCodecs serverCodecs, EurekaClient eurekaClient) {
super(serverConfig, clientConfig, serverCodecs, eurekaClient);
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.ctxt = context;
}
@Override
public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) {
super.openForTraffic(applicationInfoManager, count);
}
@Override
public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {
handleRegistration(info, leaseDuration, isReplication);
if (allowedAddr( info)){
super.register(info, leaseDuration, isReplication);
}
}
@Override
public void register(final InstanceInfo info, final boolean isReplication) {
handleRegistration(info, resolveInstanceLeaseDuration(info), isReplication);
if (allowedAddr( info)){
super.register(info, isReplication);
}
}
public boolean allowedAddr(InstanceInfo info) {
if (allowedRegisteredIpAddress.isEmpty()) {
return true;
}
for (String regex : allowedRegisteredIpAddress) {
final String hostAddress = info.getIPAddr();
if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
log.trace("access_address: {}" ,info.getIPAddr());
return true;
}
}
log.trace("reject_address: {}" , info.getIPAddr());
return false;
}
@Override
public boolean cancel(String appName, String serverId, boolean isReplication) {
handleCancelation(appName, serverId, isReplication);
return super.cancel(appName, serverId, isReplication);
}
@Override
public boolean renew(final String appName, final String serverId,
boolean isReplication) {
log("renew " + appName + " serverId " + serverId + ", isReplication {}"
+ isReplication);
List<Application> applications = getSortedApplications();
for (Application input : applications) {
if (input.getName().equals(appName)) {
InstanceInfo instance = null;
for (InstanceInfo info : input.getInstances()) {
if (info.getId().equals(serverId)) {
instance = info;
break;
}
}
publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId,
instance, isReplication));
break;
}
}
return super.renew(appName, serverId, isReplication);
}
@Override
protected boolean internalCancel(String appName, String id, boolean isReplication) {
handleCancelation(appName, id, isReplication);
return super.internalCancel(appName, id, isReplication);
}
private void handleCancelation(String appName, String id, boolean isReplication) {
log("cancel " + appName + ", serverId " + id + ", isReplication " + isReplication);
publishEvent(new EurekaInstanceCanceledEvent(this, appName, id, isReplication));
}
private void handleRegistration(InstanceInfo info, int leaseDuration,
boolean isReplication) {
log("register " + info.getAppName() + ", vip " + info.getVIPAddress()
+ ", leaseDuration " + leaseDuration + ", isReplication "
+ isReplication);
publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration,
isReplication));
}
private void log(String message) {
if (log.isDebugEnabled()) {
log.debug(message);
}
}
private void publishEvent(ApplicationEvent applicationEvent) {
this.ctxt.publishEvent(applicationEvent);
}
private int resolveInstanceLeaseDuration(final InstanceInfo info) {
int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
leaseDuration = info.getLeaseInfo().getDurationInSecs();
}
return leaseDuration;
}
}
@Configuration
public class RegisterConfig {
@Autowired
private EurekaServerConfig eurekaServerConfig;
@Autowired
private EurekaClientConfig eurekaClientConfig;
@Autowired
@Qualifier(value = "eurekaClient")
private EurekaClient eurekaClient;
@Value("${eureka.server.allowed.address:}")
private List<String> allowedAddress;
@Primary
@Bean(name = "instanceRegistry")
public PeerAwareInstanceRegistry peerAwareInstanceRegistry(
ServerCodecs serverCodecs) {
this.eurekaClient.getApplications();
return new CustomInstanceRegistry(
this.eurekaServerConfig,
this.eurekaClientConfig,
serverCodecs,
this.eurekaClient,
allowedAddress
);
}
}
eureka:
server:
allowed:
address: 192.16.202.*