2022年 AHWA比武题 k8s服务器集群分析 k8s证书更新教程:
更新脚本
1 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 #!/usr/bin/env bash set -o errexitset -o pipefailNC='\033[0m' RED='\033[31m' GREEN='\033[32m' YELLOW='\033[33m' BLUE='\033[34m' CRI="docker" log ::err () { printf "[$(date +'%Y-%m-%dT%H:%M:%S.%2N%z') ][${RED} ERROR${NC} ] %b\n" "$@ " } log ::info () { printf "[$(date +'%Y-%m-%dT%H:%M:%S.%2N%z') ][INFO] %b\n" "$@ " } log ::warning () { printf "[$(date +'%Y-%m-%dT%H:%M:%S.%2N%z') ][${YELLOW} WARNING${NC} ] \033[0m%b\n" "$@ " } check_file () { if [[ ! -r ${1} ]]; then log ::err "can not find ${1} " exit 1 fi } cert::get_subject_alt_name () { local cert=${1} .crt local alt_name check_file "${cert} " alt_name=$(openssl x509 -text -noout -in "${cert} " | grep -A1 'Alternative' | tail -n1 | sed 's/[[:space:]]*Address//g' ) printf "%s\n" "${alt_name} " } cert::get_subj () { local cert=${1} .crt local subj check_file "${cert} " subj=$(openssl x509 -text -noout -in "${cert} " | grep "Subject:" | sed 's/Subject:/\//g;s/\,/\//;s/[[:space:]]//g' ) printf "%s\n" "${subj} " } cert::backup_file () { local file=${1} if [[ ! -e ${file} .old-$(date +%Y%m%d) ]]; then cp -rp "${file} " "${file} .old-$(date +%Y%m%d) " log ::info "backup ${file} to ${file} .old-$(date +%Y%m%d) " else log ::warning "does not backup, ${file} .old-$(date +%Y%m%d) already exists" fi } cert::check_cert_expiration () { local cert=${1} .crt local cert_expires cert_expires=$(openssl x509 -text -noout -in "${cert} " | awk -F ": " '/Not After/{print$2}' ) printf "%s\n" "${cert_expires} " } cert::check_kubeconfig_expiration () { local config=${1} .conf local cert local cert_expires cert=$(grep "client-certificate-data" "${config} " | awk '{print$2}' | base64 -d) cert_expires=$(openssl x509 -text -noout -in <(printf "%s" "${cert} " ) | awk -F ": " '/Not After/{print$2}' ) printf "%s\n" "${cert_expires} " } cert::check_etcd_certs_expiration () { local cert local certs certs=( "${ETCD_CERT_CA} " "${ETCD_CERT_SERVER} " "${ETCD_CERT_PEER} " "${ETCD_CERT_HEALTHCHECK_CLIENT} " "${ETCD_CERT_APISERVER_ETCD_CLIENT} " ) for cert in "${certs[@]} " ; do if [[ ! -r ${cert} ]]; then printf "%-50s%-30s\n" "${cert} .crt" "$(cert::check_cert_expiration "${cert} " ) " fi done } cert::check_master_certs_expiration () { local certs local kubeconfs local cert local conf certs=( "${CERT_CA} " "${CERT_APISERVER} " "${CERT_APISERVER_KUBELET_CLIENT} " "${FRONT_PROXY_CA} " "${FRONT_PROXY_CLIENT} " ) kubeconfs=( "${CONF_CONTROLLER_MANAGER} " "${CONF_SCHEDULER} " "${CONF_ADMIN} " ) printf "%-50s%-30s\n" "CERTIFICATE" "EXPIRES" for conf in "${kubeconfs[@]} " ; do if [[ ! -r ${conf} ]]; then printf "%-50s%-30s\n" "${conf} .config" "$(cert::check_kubeconfig_expiration "${conf} " ) " fi done for cert in "${certs[@]} " ; do if [[ ! -r ${cert} ]]; then printf "%-50s%-30s\n" "${cert} .crt" "$(cert::check_cert_expiration "${cert} " ) " fi done } cert::check_all_expiration () { cert::check_master_certs_expiration cert::check_etcd_certs_expiration } cert::gen_cert () { local cert_name=${1} local cert_type=${2} local subj=${3} local cert_days=${4} local ca_name=${5} local alt_name=${6} local ca_cert=${ca_name} .crt local ca_key=${ca_name} .key local cert=${cert_name} .crt local key=${cert_name} .key local csr=${cert_name} .csr local common_csr_conf='distinguished_name = dn\n[dn]\n[v3_ext]\nkeyUsage = critical, digitalSignature, keyEncipherment\n' for file in "${ca_cert} " "${ca_key} " "${cert} " "${key} " ; do check_file "${file} " done case "${cert_type} " in client) csr_conf=$(printf "%bextendedKeyUsage = clientAuth\n" "${common_csr_conf} " ) ;; server) csr_conf=$(printf "%bextendedKeyUsage = serverAuth\nsubjectAltName = %b\n" "${common_csr_conf} " "${alt_name} " ) ;; peer) csr_conf=$(printf "%bextendedKeyUsage = serverAuth, clientAuth\nsubjectAltName = %b\n" "${common_csr_conf} " "${alt_name} " ) ;; *) log ::err "unknow, unsupported certs type: ${YELLOW} ${cert_type} ${NC} , supported type: client, server, peer" exit 1 ;; esac openssl req -new -key "${key} " -subj "${subj} " -reqexts v3_ext \ -config <(printf "%b" "${csr_conf} " ) \ -out "${csr} " >/dev/null 2>&1 openssl x509 -in "${csr} " -req -CA "${ca_cert} " -CAkey "${ca_key} " -CAcreateserial -extensions v3_ext \ -extfile <(printf "%b" "${csr_conf} " ) \ -days "${cert_days} " -out "${cert} " >/dev/null 2>&1 rm -f "${csr} " } cert::update_kubeconf () { local cert_name=${1} local kubeconf_file=${cert_name} .conf local cert=${cert_name} .crt local key=${cert_name} .key local subj local cert_base64 check_file "${kubeconf_file} " grep "client-key-data" "${kubeconf_file} " | awk '{print$2}' | base64 -d >"${key} " grep "client-certificate-data" "${kubeconf_file} " | awk '{print$2}' | base64 -d >"${cert} " subj=$(cert::get_subj "${cert_name} " ) cert::gen_cert "${cert_name} " "client" "${subj} " "${CERT_DAYS} " "${CERT_CA} " cert_base64=$(base64 -w 0 "${cert} " ) sed -i 's/client-certificate-data:.*/client-certificate-data: ' "${cert_base64} " '/g' "${kubeconf_file} " rm -f "${cert} " rm -f "${key} " } cert::update_etcd_cert () { local subj local subject_alt_name local cert for cert in ${ETCD_CERT_SERVER} ${ETCD_CERT_PEER} ; do subj=$(cert::get_subj "${cert} " ) subject_alt_name=$(cert::get_subject_alt_name "${cert} " ) cert::gen_cert "${cert} " "peer" "${subj} " "${CERT_DAYS} " "${ETCD_CERT_CA} " "${subject_alt_name} " log ::info "${GREEN} updated ${BLUE} ${cert} .conf${NC} " done for cert in ${ETCD_CERT_HEALTHCHECK_CLIENT} ${ETCD_CERT_APISERVER_ETCD_CLIENT} ; do subj=$(cert::get_subj "${cert} " ) cert::gen_cert "${cert} " "client" "${subj} " "${CERT_DAYS} " "${ETCD_CERT_CA} " log ::info "${GREEN} updated ${BLUE} ${cert} .conf${NC} " done case $CRI in "docker" ) docker ps | awk '/k8s_etcd/{print$1}' | xargs -r -I '{}' docker restart {} >/dev/null 2>&1 || true ;; "containerd" ) crictl ps | awk '/etcd-/{print$(NF-1)}' | xargs -r -I '{}' crictl stopp {} >/dev/null 2>&1 || true ;; esac log ::info "restarted etcd with ${CRI} " } cert::update_master_cert () { local subj local subject_alt_name local conf subj=$(cert::get_subj "${CERT_APISERVER} " ) subject_alt_name=$(cert::get_subject_alt_name "${CERT_APISERVER} " ) cert::gen_cert "${CERT_APISERVER} " "server" "${subj} " "${CERT_DAYS} " "${CERT_CA} " "${subject_alt_name} " log ::info "${GREEN} updated ${BLUE} ${CERT_APISERVER} .crt${NC} " subj=$(cert::get_subj "${CERT_APISERVER_KUBELET_CLIENT} " ) cert::gen_cert "${CERT_APISERVER_KUBELET_CLIENT} " "client" "${subj} " "${CERT_DAYS} " "${CERT_CA} " log ::info "${GREEN} updated ${BLUE} ${CERT_APISERVER_KUBELET_CLIENT} .crt${NC} " for conf in ${CONF_CONTROLLER_MANAGER} ${CONF_SCHEDULER} ${CONF_ADMIN} ${CONF_KUBELET} ; do if [[ ${conf##*/} == "kubelet" ]]; then set +e grep kubelet-client-current.pem /etc/kubernetes/kubelet.conf >/dev/null 2>&1 kubelet_cert_auto_update=$? set -e if [[ "$kubelet_cert_auto_update " == "0" ]]; then log ::info "does not need to update kubelet.conf" continue fi fi cert::update_kubeconf "${conf} " log ::info "${GREEN} updated ${BLUE} ${conf} .conf${NC} " if [[ ${conf##*/} == "admin" ]]; then mkdir -p "${HOME} /.kube" local config=${HOME} /.kube/config local config_backup config_backup=${HOME} /.kube/config.old-$(date +%Y%m%d) if [[ -f ${config} ]] && [[ ! -f ${config_backup} ]]; then cp -fp "${config} " "${config_backup} " log ::info "backup ${config} to ${config_backup} " fi cp -fp "${conf} .conf" "${HOME} /.kube/config" log ::info "copy the admin.conf to ${HOME} /.kube/config" fi done subj=$(cert::get_subj "${FRONT_PROXY_CLIENT} " ) cert::gen_cert "${FRONT_PROXY_CLIENT} " "client" "${subj} " "${CERT_DAYS} " "${FRONT_PROXY_CA} " log ::info "${GREEN} updated ${BLUE} ${FRONT_PROXY_CLIENT} .crt${NC} " for item in "apiserver" "controller-manager" "scheduler" ; do case $CRI in "docker" ) docker ps | awk '/k8s_kube-' ${item} '/{print$1}' | xargs -r -I '{}' docker restart {} >/dev/null 2>&1 || true ;; "containerd" ) crictl ps | awk '/kube-' ${item} '-/{print $(NF-1)}' | xargs -r -I '{}' crictl stopp {} >/dev/null 2>&1 || true ;; esac log ::info "restarted ${item} with ${CRI} " done systemctl restart kubelet || true log ::info "restarted kubelet" } main () { local node_type=$1 ARGS=`getopt -o c: --long cri: -- "$@ " ` eval set -- "$ARGS " while true do case "$1 " in -c|--cri) case "$2 " in "docker" |"containerd" ) CRI=$2 shift 2 ;; *) echo 'Unsupported cri. Valid options are "docker", "containerd".' exit 1 ;; esac ;; --) shift break ;; *) echo "Invalid arguments." exit 1 ;; esac done CERT_DAYS=3650 KUBE_PATH=/etc/kubernetes PKI_PATH=${KUBE_PATH} /pki CERT_CA=${PKI_PATH} /ca CERT_APISERVER=${PKI_PATH} /apiserver CERT_APISERVER_KUBELET_CLIENT=${PKI_PATH} /apiserver-kubelet-client CONF_CONTROLLER_MANAGER=${KUBE_PATH} /controller-manager CONF_SCHEDULER=${KUBE_PATH} /scheduler CONF_ADMIN=${KUBE_PATH} /admin CONF_KUBELET=${KUBE_PATH} /kubelet FRONT_PROXY_CA=${PKI_PATH} /front-proxy-ca FRONT_PROXY_CLIENT=${PKI_PATH} /front-proxy-client ETCD_CERT_CA=${PKI_PATH} /etcd/ca ETCD_CERT_SERVER=${PKI_PATH} /etcd/server ETCD_CERT_PEER=${PKI_PATH} /etcd/peer ETCD_CERT_HEALTHCHECK_CLIENT=${PKI_PATH} /etcd/healthcheck-client ETCD_CERT_APISERVER_ETCD_CLIENT=${PKI_PATH} /apiserver-etcd-client case ${node_type} in master) cert::check_master_certs_expiration cert::backup_file "${KUBE_PATH} " log ::info "${GREEN} updating...${NC} " cert::update_master_cert log ::info "${GREEN} done!!!${NC} " cert::check_master_certs_expiration ;; all) cert::check_all_expiration cert::backup_file "${KUBE_PATH} " log ::info "${GREEN} updating...${NC} " cert::update_etcd_cert cert::update_master_cert log ::info "${GREEN} done!!!${NC} " cert::check_all_expiration ;; check) cert::check_all_expiration ;; *) log ::err "unknown, unsupported cert type: ${node_type} , supported type: \"all\", \"master\"" printf "Documentation: https://github.com/yuyicai/update-kube-cert example: '\033[32m./update-kubeadm-cert.sh all\033[0m' update all etcd certificates, master certificates and kubeconf /etc/kubernetes ├── admin.conf ├── controller-manager.conf ├── scheduler.conf ├── kubelet.conf └── pki ├── apiserver.crt ├── apiserver-etcd-client.crt ├── apiserver-kubelet-client.crt ├── front-proxy-client.crt └── etcd ├── healthcheck-client.crt ├── peer.crt └── server.crt '\033[32m./update-kubeadm-cert.sh master\033[0m' update only master certificates and kubeconf /etc/kubernetes ├── admin.conf ├── controller-manager.conf ├── scheduler.conf ├── kubelet.conf └── pki ├── apiserver.crt ├── apiserver-kubelet-client.crt └── front-proxy-client.crt " exit 1 ;; esac } main "$@ "
复制脚本至master的root目录
提权限 : chmod +x update-kubeadm-cert.sh
执行 ./update-kubeadm-cert.sh all ,更新证书
然后拷贝 admin.conf 到 kubelet.conf ,cp -a /etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf
重启 kubelet 服务 systemctl daemon-reload && systemctl restart kubelet
两个子节点因为没有管理功能没法生成证书 直接把master的admin.conf重命名为kubelet.conf丢到两个子节点的/etc/kubernetes/kubelet.conf
在做题之前我们需要先把三个镜像检材三,检材四,检材五,仿真起来,
进入后cat /etc/hosts文件内容
发现master,node1,node3三个节点,ip分别为192.168.110.135,192.168.110.132,192.168.110.133
但是在检材五中,其hostname却是node2
我们需要恢复其网络配置,将master节点的/etc/hostsh中的133对应的node3改为node2
接着ip a查看网卡情况不出意外的话是和hosts文件中不相符的
遂修改ens33网卡的配置,或者重新添加内部网卡
将BOOTPROTO=dhcp改为BOOTPROTO=static,从dhcp自动分配ip改为静态分配,并按照hosts文件添加ipaddr,netmask和gateway
其他两台同样操作
然后三台机器systemctl restart network重启网络服务,互ping检查是否联通ping -c 4 master && ping -c 4 node1 && ping -c 4 node2
然后重启k8s服务service docker restart && service kubelet restart
1. 该服务器集群处于什么时区?
EST
1 cat /etc/localtime | tail -n 1
2. 服务器检材三中,主要分区的起始扇区和扇区数分别是多少
123729920
fdisk -l
/dev/sda2起始2099200,截止125829119,合计扇区125829119-2099200+1=123729920
3. 在主机master中,不属于Centos原本一级目录的有哪些?
a /project b /opt c /srv d/www
4. 服务器检材五的主机名是什么?区分大小写
node2
之前看到了
7. 该k8s服务器集群中,有多少pod
2
kubectl get pods -A
9. 该集群中,k8s初始化后生成的秘钥的sha256哈希值是多少(答案格式:全部小写)
4ce0bd8ce22014dd7f88944cd0aebc6d02845bf2806ac3a96eb6b39cba6a6725
kubeadm token create --print-join-command
或者任意一个节点
1 openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
11. 该集群连接数据库的密码是?区分大小写
H8621790L
在master节点中kubectl describe pod ssx-mysql-dm-68f975f9d-47z8p -n ssx-nsorkubectl get pod ssx-mysql-dm-68f975f9d-47z8p -n ssx-ns -o yaml
12. 该集群kubernetes的cluster ip是多少
10.96.0.1
13. 该k8s集群中数据库所在容器的主机名是多少?区分大小写
ssx-mysql-dm-68f975f9d-47z8p
54. 该k8s集群中,数据库映射到主机的端口是什么(答案格式:80)
31090
恢复网站 数据库修复 kubectl exec -it nginx-php-989598646-726jx /bin/bash进入容器操作
发现hostname和username和password和hostport都有问题,
我们可以修改hostname为10.110.144.185对应的hostport改为3306或者hostname为10.244.104.15hostport为31090
用户名和密码改为root H8621790L
网站配置修复 网站显示403forbideen
需要修复nginx配置文件find / -name nginx.conf
在第一个文件中并没有发现server部分。则继续查看其include的文件
逐个看一下
发现 都没有什么东西,所以我们需要添加网络配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 server { listen 80 default_server; listen [::]:80 default_server; root /www/public ; index index.php; server_name _; location ~* (runtime|application)/{ return 403 ; } location / { if (!-e $request_filename ){ rewrite ^(.*)$ /index.php?s=$1 last; break ; } location ~ \.php$ { include fastcgi_params; fastcgi_param REQUEST_METHOD $request_method ; fastcgi_param SCRIPT_FILENAME $document _root$fastcgi_script_name ; fastcgi_pass 127.0 .0.1 :9000 ; } } }
将这个内容添加到/etc/nginx/conf.d/default/conf文件中,之后重启服务
发现可以正常运行服务,尝试访问后台发现,没有这个模块
vim /www/config/app.php,将admin删除
删除即可,然后发现又爆了另一个错误
PHP 进程没有权限在 /www/runtime/temp目录下创建子目录 ,
www目录下的权限所有者为root,所有我们需要将权限所有者换为www-data
1 2 chown -R www-data /www && chgrp -R www-data /www && chmod -R 777 /www/runtime/ service nginx restart
成功恢复后台,需要修改admin的密码
admin密码修复 去寻找密码的验证和生成策略
发现了password是以password+auth_key,然后MD5后传参,在/wwwconfig/app.php中发现了auth_keyb5MV=IsXUKxc2@u]"l(hdpg$?o0E1NGr4;BP76Wf
方法1.绕密 尝试账号admin密码123456登录
伪造密码,修改数据库值
7aa5e695be95cdd64a88410a64dfe2c1
1 2 3 kubectl exec -it ssx-mysql-dm-68f975f9d-47z8p -n ssx-ns -- mysql -uroot -pH8621790L use cengji update pay_admin set password='7aa5e695be95cdd64a88410a64dfe2c1' where username='admin';
但是登录后
进入库名为mysql中
发现root用户的身份验证方式为caching_sha2_password修改为mysql_native_password
1 2 3 4 5 6 7 drop user root@'%'; flush privileges; CREATE USER 'root'@'%' IDENTIFIED BY 'H8621790L'; ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'H8621790L'; grant all privileges on *.* to 'root'@'%' ; flush privileges; quit
然后需要重新设置一下database.php的设置,然后就能登录成功了
方法2.
1 vi /www/application/admin/controller/Login.php
修改
1 if(md5($password . config('auth_key')) != $info['password']){
为
1 if(md5($password . config('auth_key')) == $info['password']){
使用账号admin密码任意登录
55. 该集群中有部署一个网站,该网站的后台首页名称是什么(答案格式:xxxx系统)
星滢博瑞后台管理系统
由之前的配置过程可知
56. 该集群中有部署一个网站,网站中会员鲍泓江的推荐人手机号是多少
13857050043
57. 网站中周海燕于2021-11-25 22:17:01提现了一笔款项,该款项数额为多少(答案格式:1111.11)
11121.00
58. 总订单管理中的订单列表有多少页(答案格式:11)
33023
59. 该网站中总共多少六级团队(答案格式:11)
14
1 select count(oldgrade) from pay_user where oldgrade='6';
60. 该网站中下属会员数为437的会员手机号码是多少
15015707404
1 select username,mobile from pay_user where teamnum='437';