JumpServer堡垒机
# JumpServer介绍
# 简介
JumpServer是一款开源的使用Python/Django为主进行开发的堡垒机,它是符合4A规范的运维安全审计系统。它采纳分布式架构,支持多机房跨区域部署,支持横向扩展,无资产数量及并发限制。
特点:开源、分布式、无插件、多云支持、云端存储、多租户、多应用支持。
运维安全审计的4A规范,也就是堡垒机需要具备的四个核心能力:身份鉴别、授权控制、账号管理、安全审计。
# 组件
LINA
:前端模块,负责页面展示。
Luna
:现在是Web Terminal前端,但计划和LINA项目合并。
CORE
:JumpServer的核心组件,也就是管理后台,使用Django Class Based View风格开发。
CoCo/Koko
:实现SSH Server和Web Terminal Server的组件,提供SSH和WebSocket接口。
Guacamole
:Apache跳板机项目,用于提供RDP功能实现Windows连接等。
# JumpServer安装部署
# 环境准备
存储空间评估参考:
- 100台Linux虚拟机资产,正常使用的情况下,200G可以存储5-6个月的录像,Windows录像会需要更多。
JumpServer服务需要打开的端口:
SSH端口,默认:22。
JumpServer的Web服务端口,默认:80、8080。
JumpServer的终端连接端口,默认:2222。
- 用于第三方工具连接资产主机时使用,如:Xshell、Putty等
# 安装部署
脚本一键部署
# 下载并执行部署脚本
# 默认会安装到/opt/jumpserver-installer-v2.22.1 目录
# 安装完成后配置文件/opt/jumpserver/config/config.txt
curl -sSL https://github.com/jumpserver/jumpserver/releases/download/v2.22.1/quick_start.sh | bash
# 启动JumpServer服务
bash /opt/jumpserver-installer-v2.22.1/jmsctl.sh start
2
3
4
5
6
7
手动部署
# 下载并解压安装包
wget https://github.com/jumpserver/installer/releases/download/v2.22.1/jumpserver-installer-v2.22.1.tar.gz
tar -zxf jumpserver-installer-v2.22.1.tar.gz
cd jumpserver-installer-v2.22.1
# 修改配置文件模板
vim config-example.txt
# 安装程序,安装完成后配置文件/opt/jumpserver/config/config.txt
./jmsctl.sh install
# 启动程序
./jmsctl.sh start
2
3
4
5
6
7
8
9
10
11
12
13
编译部署
环境要求
Python >= 3.8
MySQL >= 5.7 || MariaDB >= 10.2
Redis >= 6
安装方法
- https://docs.jumpserver.org/zh/master/dev/build/
- 该安装方式解耦合性高,需要分布式部署JumpServer服务时可以使用。
K8S部署
参考配置文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-redis-deploy
namespace: default
spec:
selector:
matchLabels:
app: jms-redis
replicas: 1
template:
metadata:
labels:
app: jms-redis
spec:
containers:
- name: jms-redis
image: jumpserver/redis:6-alpine
imagePullPolicy: IfNotPresent
args:
- redis-server
- --requirepass
- 18B5m3XSgaHWD90Z
volumeMounts:
- name: redis-data
mountPath: /data
volumes:
- name: redis-data
hostPath:
path: /data/jumpserver/redis/data
type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
name: jms-redis-svc
namespace: default
spec:
selector:
app: jms-redis
type: ClusterIP
ports:
- name: redis
protocol: TCP
port: 6379
targetPort: 6379
# Core =====================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-core-deploy
namespace: default
labels:
app: jms-core
spec:
selector:
matchLabels:
app: jms-core
replicas: 1
template:
metadata:
labels:
app: jms-core
spec:
restartPolicy: Always
containers:
- name: core
image: jumpserver/core:v2.22.2
imagePullPolicy: IfNotPresent
tty: true
args: ["start", "web"]
env:
# Core配置
- name: SECRET_KEY
value: "BxFGM9Ly1eyA3qoTZYAFDUDkEcGyqk79cHvCOMbMaVG3FOP7"
- name: BOOTSTRAP_TOKEN
value: "OKnEyCOWa7k14AwFwzrjsdxh"
- name: LOG_LEVEL
value: "ERROR"
# 数据库配置
- name: DB_HOST
value: "10.102.140.18"
- name: DB_PORT
value: "3306"
- name: DB_USER
value: "root"
- name: DB_PASSWORD
value: "qwe123123"
- name: DB_NAME
value: "jumpserver"
# Redis配置
- name: REDIS_HOST
value: "jms-redis-svc.default.svc.cluster.local"
- name: REDIS_PORT
value: "6379"
- name: REDIS_PASSWORD
value: 18B5m3XSgaHWD90Z
ports:
- name: core-http
containerPort: 8080
protocol: TCP
- name: core-ws
containerPort: 8070
protocol: TCP
livenessProbe:
httpGet:
path: /api/health/
port: core-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /api/health/
port: core-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
lifecycle:
postStart:
exec:
# 修改数据库过期时间的默认300秒为15天
command: ["/bin/bash", "-c", 'sed -ri "s/(def create_token.*?) ttl=5 \* 60/\1 ttl=15 * 86400/" /opt/jumpserver/apps/authentication/api/connection_token.py']
volumeMounts:
- name: core-data
mountPath: /opt/jumpserver/data
- name: core-logs
mountPath: /opt/jumpserver/logs
volumes:
- name: core-data
hostPath:
path: /data/jumpserver/core/data
type: DirectoryOrCreate
- name: core-logs
---
# Celery =====================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-celery-deploy
namespace: default
labels:
app: jms-celery
spec:
selector:
matchLabels:
app: jms-celery
replicas: 1
template:
metadata:
labels:
app: jms-celery
spec:
restartPolicy: Always
containers:
- name: celery
image: jumpserver/core:v2.22.2
imagePullPolicy: IfNotPresent
tty: true
args: ["start", "task"]
env:
# Core配置
- name: SECRET_KEY
value: "BxFGM9Ly1eyA3qoTZYAFDUDkEcGyqk79cHvCOMbMaVG3FOP7"
- name: BOOTSTRAP_TOKEN
value: "OKnEyCOWa7k14AwFwzrjsdxh"
- name: LOG_LEVEL
value: "ERROR"
# 数据库配置
- name: DB_HOST
value: "10.102.140.18"
- name: DB_PORT
value: "3306"
- name: DB_USER
value: "root"
- name: DB_PASSWORD
value: "qwe123123"
- name: DB_NAME
value: "jumpserver"
# Redis配置
- name: REDIS_HOST
value: "jms-redis-svc.default.svc.cluster.local"
- name: REDIS_PORT
value: "6379"
- name: REDIS_PASSWORD
value: 18B5m3XSgaHWD90Z
livenessProbe:
exec:
command: ["/bin/bash", "/opt/jumpserver/utils/check_celery.sh"]
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
readinessProbe:
exec:
command: ["/bin/bash", "/opt/jumpserver/utils/check_celery.sh"]
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
lifecycle:
postStart:
exec:
# 修改数据库过期时间的默认300秒为15天
command: ["/bin/bash", "-c", 'sed -ri "s/(def create_token.*?) ttl=5 \* 60/\1 ttl=15 * 86400/" /opt/jumpserver/apps/authentication/api/connection_token.py']
volumeMounts:
- name: core-data
mountPath: /opt/jumpserver/data
- name: core-logs
mountPath: /opt/jumpserver/logs
volumes:
- name: core-data
hostPath:
path: /data/jumpserver/core/data
type: DirectoryOrCreate
- name: core-logs
hostPath:
path: /data/jumpserver/core/logs
type: DirectoryOrCreate
---
# Koko =====================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-koko-deploy
namespace: default
labels:
app: jms-koko
spec:
selector:
matchLabels:
app: jms-koko
replicas: 1
template:
metadata:
labels:
app: jms-koko
spec:
restartPolicy: Always
containers:
- name: koko
image: jumpserver/koko:v2.22.2
imagePullPolicy: IfNotPresent
tty: true
env:
- name: CORE_HOST
value: "http://jms-core-svc.default.svc.cluster.local:8080"
- name: BOOTSTRAP_TOKEN
value: "OKnEyCOWa7k14AwFwzrjsdxh"
- name: LOG_LEVEL
value: "ERROR"
ports:
- name: koko-http
containerPort: 5000
protocol: TCP
- name: koko-ssh
containerPort: 2222
protocol: TCP
livenessProbe:
httpGet:
path: /koko/health/
port: koko-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /koko/health/
port: koko-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
volumeMounts:
- name: koko-data
mountPath: /opt/koko/data
volumes:
- name: koko-data
hostPath:
path: /data/jumpserver/koko/data
type: DirectoryOrCreate
---
# Lion =====================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-lion-deploy
namespace: default
labels:
app: jms-lion
spec:
selector:
matchLabels:
app: jms-lion
replicas: 1
template:
metadata:
labels:
app: jms-lion
spec:
restartPolicy: Always
containers:
- name: lion
image: jumpserver/lion:v2.22.2
imagePullPolicy: IfNotPresent
tty: true
env:
- name: CORE_HOST
value: "http://jms-core-svc.default.svc.cluster.local:8080"
- name: BOOTSTRAP_TOKEN
value: "OKnEyCOWa7k14AwFwzrjsdxh"
- name: LOG_LEVEL
value: "ERROR"
- name: JUMPSERVER_ENABLE_FONT_SMOOTHING
value: "true"
ports:
- name: lion-http
containerPort: 8081
protocol: TCP
livenessProbe:
httpGet:
path: /lion/health/
port: lion-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /lion/health/
port: lion-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
volumeMounts:
- name: lion-data
mountPath: /opt/lion/data
volumes:
- name: lion-data
hostPath:
path: /data/jumpserver/lion/data
type: DirectoryOrCreate
---
# Magnus =====================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-magnus-deploy
namespace: default
labels:
app: jms-magnus
spec:
selector:
matchLabels:
app: jms-magnus
replicas: 1
template:
metadata:
labels:
app: jms-magnus
spec:
restartPolicy: Always
containers:
- name: magnus
image: jumpserver/magnus:v2.22.2
imagePullPolicy: IfNotPresent
tty: true
env:
- name: CORE_HOST
value: "http://jms-core-svc.default.svc.cluster.local:8080"
- name: BOOTSTRAP_TOKEN
value: "OKnEyCOWa7k14AwFwzrjsdxh"
- name: LOG_LEVEL
value: "ERROR"
ports:
- name: magnus-mysql
containerPort: 33060
protocol: TCP
- name: magnus-mariadb
containerPort: 33061
protocol: TCP
- name: magnus-postgre
containerPort: 54320
protocol: TCP
livenessProbe:
tcpSocket:
port: magnus-mysql
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
readinessProbe:
tcpSocket:
port: magnus-mysql
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
volumeMounts:
- name: magnus-data
mountPath: /opt/magnus/data
volumes:
- name: magnus-data
hostPath:
path: /data/jumpserver/magnus/data
type: DirectoryOrCreate
---
# Web(Nginx) =====================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: jms-web-deploy
namespace: default
labels:
app: jms-web
spec:
selector:
matchLabels:
app: jms-web
replicas: 1
template:
metadata:
labels:
app: jms-web
spec:
restartPolicy: Always
containers:
- name: web
image: jumpserver/web:v2.22.2
imagePullPolicy: IfNotPresent
tty: true
env:
- name: CORE_HOST
value: "http://jms-core-svc.default.svc.cluster.local:8080"
- name: BOOTSTRAP_TOKEN
value: "OKnEyCOWa7k14AwFwzrjsdxh"
- name: LOG_LEVEL
value: "ERROR"
- name: CLIENT_MAX_BODY_SIZE
value: 4096m
ports:
- name: web-http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /api/health/
port: web-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /api/health/
port: web-http
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 10
volumeMounts:
- name: web-conf
mountPath: /etc/nginx/sites-enabled/jumpserver.conf
- name: web-data
mountPath: /opt/jumpserver/data
- name: web-log
mountPath: /var/log/nginx
volumes:
- name: web-conf
hostPath:
path: /data/jumpserver/nginx/jumpserver.conf
type: FileOrCreate
- name: web-log
hostPath:
path: /data/jumpserver/nginx/log
type: DirectoryOrCreate
- name: web-data
hostPath:
path: /data/jumpserver/core/data
type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
name: jms-core-svc
namespace: default
spec:
selector:
app: jms-core
type: ClusterIP
ports:
- name: core-http
protocol: TCP
port: 8080
targetPort: 8080
- name: core-ws
protocol: TCP
port: 8070
targetPort: 8070
---
apiVersion: v1
kind: Service
metadata:
name: jms-web-svc
namespace: default
spec:
selector:
app: jms-web
type: NodePort
ports:
- name: web-http
protocol: TCP
port: 80
targetPort: 80
nodePort: 32080
---
apiVersion: v1
kind: Service
metadata:
name: jms-magnus-svc
namespace: default
spec:
selector:
app: jms-magnus
type: NodePort
ports:
- name: magnus-mysql
protocol: TCP
port: 33060
targetPort: 33060
nodePort: 32221
- name: magnus-mariadb
protocol: TCP
port: 33061
targetPort: 33061
nodePort: 32222
- name: magnus-postgre
protocol: TCP
port: 54320
targetPort: 54320
nodePort: 32223
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# JumpServer身份认证
# 用户
可用于登录JumpServer的Web管理后台、和JumpServer的SSH终端。
# 用户组
用户组即给用户分组,在用户多时,有用户组可以方便的进行资产授权管理
当某个资产对一个用户组授权后,这个用户组下面的所有用户就都可以使用这个资产,资产授权可以直接授权给用户、也可以授权给用户组。
# 身份认证安全设置
系统设置 -> 安全设置
连接最大空闲时间。
密码过期时间。
登录限制。
- 限制登录失败次数。
- IP 登录限制。
- 禁止登录时间间隔。
# MFA - 多因子认证
配置开启MFA后,登录需要通过身份验证APP获取动态码才能登录。
默认是全局关闭,可以全局开启,或者局部给某些用户配置。
# 账号管理
资产管理 -> 系统用户
普通用户
用于用户连接、使用资产主机时使用的用户。
认证方式
托管密码,登录该用户时会自动使用托管的密码。
手动输入,登录该用户时需要手动输入密码。
自动推送
如果选择了自动推送,JumpServer会自动推送该用户到资产主机中。
推送就是推送配置的用户账号密码到资产中,如果用户不存在则创建,如果密码不一致则改密。
也可以手动点击推送、或者手动创建用户。
特权用户
root或者有NOPASSWD: ALL sudo权限的用户,用于JumpServer服务管理资产主机时使用。
如:JumpServer获取主机信息、自动推送普通用户、执行后台任务等情况。
# 资产管理
资产管理 -> 资产列表 -> 左侧资产树
资产树作用
多维度管理,可以根据管理需要建立不同的资产树节点,来实现资产的不同管理目的。
灵活分配,资产可以分组与多个不同的资产节点,保证了资产管理的灵活性。
交叉授权,可以对资产节点进行授权,节点下的资产会自动继承授权规则。
无限延伸,资产树可以无限级建立,以保证满足管理需求。
资产树注意事项
- 资产树节点不能重名,右击可以添加、删除、重命名节点,以及对资产进行相关操作。
- JumpServer堡垒机可以对资产进行批量删除、批量更新、批量节点移除、批量禁用、批量激活等操作,批量更新需要在提交后填写修改信息。
- 删除节点的前提是该节点下没有资产。