喜欢关注安全问题的朋友可能对MongoDB数据库勒索事件有过了解,整件事情其实在一定程度上来说是可以进行规避的,如果用户没有使用MongoDB的默认安全设置或是直接裸跑在服务器上就不会导致数据外泄,也就不会被黑客用数据库数据进行勒索。当然这个安全事故只是一个例子而已,在我们的日常开发环境或一些生产环境上不免也会遇到这样的安全问题,不管是服务器安全、数据安全还是我们开发时使用的中间件的安全都是不能够被忽略掉的。本文就为你简单讲解一下如何加固你的ElasticSearch,为你的海量数据保驾护航。
1、本次使用的环境是centos7和docker-compose 1.1.8。
首先我通过docker-compose方式分别部署了版本为6.6.0的一套ElasticSearch和一套Kibana服务,然后本次需要将ElasticSearch升级到6.8.4并加上安全验证功能。
2、准备好6.8.4版本的ik分词器放入现ElasticSearch配置对应的插件目录;
3、环境介绍:A、在根目录下创建docker目录存放一些配置文件、日志纪录和数据存储
[root@localhost ~]# cd /docker/
[root@localhost docker]# ls
elasticsearch kibana
[root@localhost docker]# pwd
/docker
[root@localhost docker]# ls
elasticsearch kibana
[root@localhost docker]# ls elasticsearch/
config data data-bak logs plugins
[root@localhost docker]# ls kibana/
config data
[root@localhost docker]#
B、在opt目录下创建docker-compose目录存放docker-compose.yml以及一些中间件的docker-compose的yml文件:
[root@localhost docker-compose]# ls
docker-compose.yml
[root@localhost docker-compose]# pwd
/opt/docker-compose
[root@localhost docker-compose]#
[root@localhost docker-compose]# cat docker-compose.yml
version: '3'
services:
elasticsearch:
image: elasticsearch:6.8.4 //原先为6.6.0,本次需升级至6.8.4
environment:
TZ: Asia/Shanghai
volumes:
- /docker/elasticsearch/data:/usr/share/elasticsearch/data
- /docker/elasticsearch/config:/usr/share/elasticsearch/config
- /docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins
- /etc/localtime:/etc/localtime
container_name: elasticsearch
network_mode: host
restart: always
kibana:
image: kibana:6.8.4 //原先为6.6.0,本次需升级至6.8.4
environment:
TZ: Asia/Shanghai
volumes:
- /docker/kibana/data:/usr/share/kibana/data
- /docker/kibana/config:/usr/share/kibana/config
- /etc/localtime:/etc/localtime
container_name: kibana
network_mode: "host"
restart: always
[root@localhost docker-compose]#
修改好后docker-compose.yml后将原先运行的elasticSearch和kibana服务关闭,并重启
[root@localhost docker-compose]# docker-compose -f /opt/docker-compose/docker-compose.yml down
Stopping elasticsearch ... done
Stopping kibana ... done
Removing elasticsearch ... done
Removing kibana ... done
[root@localhost docker-compose]# docker-compose -f /opt/docker-compose/docker-compose.yml up -d
Pulling kibana (kibana:6.8.4)...
6.8.4: Pulling from library/kibana
d8d02d457314: Already exists
6962446443a4: Pull complete
628f51417676: Pull complete
4dc1cdc8a1d9: Pull complete
9d3bfb93ff44: Pull complete
7dcfacc7c91b: Pull complete
d98901bd2778: Pull complete
71248cd8cef2: Pull complete
Digest: sha256:c422412b8b554f484b375a97c561151a1456c29465b6e59e322bdaecc8ad7d85
Status: Downloaded newer image for kibana:6.8.4
Creating kibana ... done
Creating elasticsearch ..
[root@localhost docker-compose]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d33777fc3863 elasticsearch:6.8.4 "/usr/local/bin/dock…" 10 seconds ago Up 9 seconds elasticsearch
569cdde73001 kibana:6.8.4 "/usr/local/bin/kiba…" 10 seconds ago Up 9 seconds kibana
[root@localhost docker-compose]#
修改/docker/elasticsearch/config目录下的elasticsearch.yml配置文件,添加配置:
[root@localhost config]# cat elasticsearch.yml
cluster.name: "qgs-elasticsearch"
http.port: 9201
transport.tcp.port: 9301
network.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
# 添加 x-pack验证,打开安全验证和传输安全验证
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
[root@localhost config]#
修改好配置后重启ElasticSerch服务并进入到容器内部进行用户权限设置:
进入到容器内部通过以下命令创建elasticsearch的用户名密码:elasticsearch.keystore
[root@localhost elasticsearch]# bin/elasticsearch-setup-passwords -h
Sets the passwords for reserved users
Commands
--------
auto - Uses randomly generated passwords //设置默认的用户名密码
interactive - Uses passwords entered by a user //对默认的用户elastic设置自己的密码
Non-option arguments:
command
Option Description
------ -----------
-h, --help show help
-s, --silent show minimal output
-v, --verbose show verbose output
[root@localhost elasticsearch]# bin/elasticsearch-keystore create //创建elasticsearch.keystore文件
An elasticsearch keystore already exists. Overwrite? [y/N]y
Created elasticsearch keystore in /usr/share/elasticsearch/config
[root@localhost elasticsearch]# bin/elasticsearch-setup-passwords interactive //设置密码命令
Enter password for [elastic]: //输入要设置的密码
Reenter password for [elastic]:
Enter password for [apm_system]:
Reenter password for [apm_system]:
Enter password for [kibana]:
Reenter password for [kibana]:
Enter password for [logstash_system]:
Reenter password for [logstash_system]:
Enter password for [beats_system]:
Reenter password for [beats_system]:
Enter password for [remote_monitoring_user]:
Reenter password for [remote_monitoring_user]:
Changed password for user [apm_system]
Changed password for user [kibana]
Changed password for user [logstash_system]
Changed password for user [beats_system]
Changed password for user [remote_monitoring_user]
Changed password for user [elastic]
在执行命令 bin/elasticsearch-setup-passwords interactive的时候可能会出现以下错误:
Possible causes include:
* The password for the 'elastic' user has already been changed on this cluster
* Your elasticsearch node is running against a different keystore
* This tool used the keystore at /usr/share/elasticsearch/config/elasticsearch.keystore
出现这个错误表面是密码已经设置过了,如果忘记了之前设置的密码可以根据以下操作进行密码重置:
curl -XDELETE http://localhost:9201/.secutity-6
设置好用户名密码后测试是否成功:
浏览器中访问es服务如果弹出提示框要输入用户名密码则说明开启安全验证是成功的,然后输入设置的用户名密码进行登录进行登录
登录成功方可查看到以下界面:
修改/docker/kibana/config目录下的kibana.yml文件,修改内容如下:
[root@localhost kibana]# cat config/kibana.yml
# Default Kibana configuration from kibana-docker.
server.name: kibana
server.host: "0.0.0.0"
elasticsearch.url: http://localhost:9201 //配置ElasticSearch的服务地址
elasticsearch.username: "elastic" //配置ElasticSearch的用户名
elasticsearch.password: "admin@qgs" //配置ElasticSearch的密码
xpack.monitoring.ui.container.elasticsearch.enabled: false
[root@localhost kibana]#
重启kibana服务后在浏览器上访问对应ip和kibana的端口正常结果如下:
以上的操作是使用ElasticSearch的默认用户elastic,拥有最高的操作权限。当然我们在实际的应用场景中我们也可以自己定义用户组,使用自定义的用户权限。
- 首先在/docker/elasticsearch/config目录下创建users 、user_roles俩目录
[root@localhost elasticsearch]# cd config/
[root@localhost config]# ls
elasticsearch.keystore elasticsearch.yml jvm.options log4j2.properties synonyms
[root@localhost config]# touch users
[root@localhost config]# touch users_roles
[root@localhost config]# chmod -R 777 users
[root@localhost config]# chmod -R 777 users_roles
[root@localhost config]# ls
elasticsearch.keystore elasticsearch.yml jvm.options log4j2.properties synonyms users users_roles
[root@localhost config]#
- 进入到ElasticSearch容器内并查看自定义用户相关命令
[root@localhost]# docker exec -it elasticsearch bash
[root@localhost elasticsearch]# bin/elasticsearch-users -h
Manages elasticsearch file users
Commands
--------
useradd - Adds a file user //添加用户命令
userdel - Deletes a file based user //删除用户
passwd - Changes the password of an existing file based user //修改现有用户密码
roles - Edit roles of an existing user //修改用户角色
list - List existing file based users and their corresponding roles //展示现有的用户数据
Non-option arguments:
command
Option Description
------ -----------
-h, --help show help
-s, --silent show minimal output
-v, --verbose show verbose output
- 添加自定义用户
[root@localhost elasticsearch]# bin/elasticsearch-users useradd testElastic
Enter new password:
Retype new password:
eruserlocalhost elasticsearch]# bin/elasticsearch-users roles testElastic -a super
[root@localhost elasticsearch]#
- 添加好自定义用户后同理根据以上的方式测试用户是否可用;
- 首先在项目的application.yml配置中找到ES的配置,添加token项:
# es配置信息:
elasticsearch:
host: 192.168.X.XXX
port: 920
url: http://192.168.X.XXX:9201
token: 这里填写ElasticSearch中配置的用户名密码生成的token
reactorConfig:
connectTimeout: 3000
soTimeout: 3000
ioThreadCount: 4
requestConfig:
connectionRequestTimeout: 3000
maxRetryTimeout: 6000
注:这里的token是使用Base64的方式进行加密的,我们可以在控制台输入以下命令进行获取token:
## echo -n ES配置的用户名:ES配置的用户密码 | base64
czt@yf-czt-ts:~$ echo -n test:test | base64
dGVzdDp0ZXN0
czt@yf-czt-ts:~$
- 修改项目中ES配置类:
@Configuration
public class ESConfig {
@Value("${elasticsearch.url}")
private String url;
@Value("${elasticsearch.token}")
private String token;
@Value("${sync.elasticsearch.url}")
private String syncLogUrl;
private Logger logger = LoggerFactory.getLogger(getClass());
@Bean(destroyMethod = "close", name = "highLevelClient")
public RestHighLevelClient highLevelClient() {
RestClientBuilder builder = RestClient.builder(HttpHost.create(url));
//添加es安全认证
Header[] defaultHeaders = new Header[]{new BasicHeader("Authorization", "Basic " + token.trim())};
builder.setDefaultHeaders(defaultHeaders);
RestHighLevelClient client = new RestHighLevelClient(builder);
logger.info("Elasticsearch init url:{}", url);
return client;
}
@Bean(destroyMethod = "close", name = "syncLogHighLevelClient")
public RestHighLevelClient syncLogHighLevelClient() {
RestClientBuilder builder = RestClient.builder(HttpHost.create(syncLogUrl));
//添加es安全认证
Header[] defaultHeaders = new Header[]{new BasicHeader("Authorization", "Basic " + token.trim())};
builder.setDefaultHeaders(defaultHeaders);
RestHighLevelClient client = new RestHighLevelClient(builder);
logger.info("Elasticsearch init url:{}", syncLogUrl);
return client;
}
}
这里主要是在每一次请求ES的时候在请求头上添加我们配置的token。
这里粗略的讲解了一下如何给ElasticSearch升级并做简单的安全加固,如若有不妥之处,请及时联系我进行更正,以便误导。