Galera + systemd: wsrep_notify_cmd가 sudo로 실패함(sudoers gid로 변경할 수 없음: 작업이 허용되지 않음)

Galera + systemd: wsrep_notify_cmd가 sudo로 실패함(sudoers gid로 변경할 수 없음: 작업이 허용되지 않음)

우리는 sysv를 사용하여 CentOS 7에서 실행되는 Galera 클러스터를 보유하고 있으며 systemd로 마이그레이션하는 것을 고려하고 있습니다. 노드 상태 변경을 애플리케이션에 알리기 위해 a를 호출하고 , 애플리케이션이 액세스 권한이 없는 다른 사용자/그룹의 디렉터리 에 있으므로 wsrep_notify_cmd이를 결합해야 합니다 .sudomysql

sysv init를 사용하면 명령/스크립트가 루트로 시작되므로 제대로 작동합니다. systemd를 사용하면 명령/스크립트가 사용자 아래에서 실행되므로 mysql이것이 작동하려면 sudoer를 구성해야 합니다. 아니면 우리는 그렇게 생각했습니다.

systemd로 전환한 후 sudo: unable to change to sudoers gid: Operation not permitted로그를 계속 살펴보며 테스트/디버깅을 수행했습니다. 먼저 mysql권한이 있는 스크립트를 시작한 다음 해당 스크립트 wsrep_notify_cmd가 ./data/app/notify.shsudo

노트:SELinux가 비활성화되었습니다.

MySQL 서버 구성

MySQL 서버(테스트) 구성:wsrep_notify_cmd='/mysql/notify.sh'

Sudoers 구성

/etc/sudoers.d/mysql구성은 다음과 같습니다.

Defaults:mysql !requiretty
Defaults:mysql umask=0007

Cmnd_Alias NOTIFY = /bin/bash /data/app/notify.sh*
mysql ALL=(app_user) NOPASSWD: NOTIFY

수동 테스트

이제 sudo su - mysql수동으로 실행하면 /mysql/notify.sh트릭이 수행됩니다.

[mysql@testhost /mysql]$ /bin/sudo -u app_user /bin/bash /data/app/notify.sh --status Synced
[mysql@testhost /mysql]$ 

/data/app/notify.sh실행되는 스크립트는 app_user전달된 모든 매개변수를 파일에 기록하고 위 명령을 수동으로 실행할 때 성공적으로 실행됩니다.

[root@testhost /data/app]# cat output.log 
--status Synced

같은 일이지만 systemd mysql 서비스 초기화 내부에서

그러나 실행될 때 service mysql start스크립트 /mysql/notify.sh는 예상된 작업을 수행하지 않고 대신 액세스가 거부됩니다.어느 sudo주문하다: sudo: unable to change to sudoers gid: Operation not permitted.

stderr을 사용하여 이 스크립트를 실행 #!/bin/bash -xv하고 로그 파일로 리디렉션합니다.

[mysql@testhost /mysql]$ cat debug.log 

file=/mysql/args.log
+ file=/mysql/args.log

echo $USER
+ echo mysql

ARGS="$@"
+ ARGS='--status Synced'

/bin/sudo -K
+ /bin/sudo -K
sudo: unable to change to sudoers gid: Operation not permitted
/bin/sudo -u app_user /bin/bash /data/app/notify.sh $ARGS
+ /bin/sudo -u app_user /bin/bash /data/app/notify.sh --status Synced
sudo: unable to change to sudoers gid: Operation not permitted

보시다시피, mysql사용자 셸에서 수동으로 실행할 수 있었던 것과 동일한 명령은 다음과 같습니다.아니요systemd 의 일부로 실행될 때 동일한 스크립트에서 호출될 때 작동합니다 service mysql start.

이 문제의 원인은 무엇입니까?

답변1

여기에서 시스템 보안을 무력화하려면 다음과 같이 장치의 기능을 수정할 수 있습니다.

# systemctl show mysql | grep Cap

-- CapabilityBoundingSet=16384

# vim /usr/lib/systemd/system/mariadb.service

-- CapabilityBoundingSet=CAP_IPC_LOCK CAP_SETGID CAP_NET_RAW CAP_NET_ADMIN CAP_SETUID CAP_SYS_ADMIN

systemctl daemon-reload

systemctl restart mysqld

systemctl show mysql | grep Cap

-- CapabilityBoundingSet=2126016

더 적은 수의 기능이 필요할 수도 있습니다. 이는 단지 빠른 테스트일 뿐입니다.

실제 파일을 수정하지 마십시오. 예를 들어 /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf를 사용하십시오.

답변2

다른 답변에 설명된 기능을 설정해야 하지만 적어도 mySQL 대신 MariaDB를 사용하는 경우에는 충분하지 않습니다.
기능을 추가하는 경우를 제외하고는 NoNewPrivilegesfalse(또는 없음)여야 합니다 . 이는 set 으로 암시되므로
이를 false로 재정의해야 합니다.NoNewPrivilegesPrivateDevicesmariadb.service

/etc/systemd/system/mariadb.service.d/mariadb-sudo.confUbuntu 18 LTS에서 이러한 설정을 성공적으로 사용했습니다 (원본 파일을 편집하지 않고 ) (Galera는 제공된 mysql 패키지를 지원하지 않습니다) mariadb.service.
[Service] CapabilityBoundingSet=CAP_SETUID CapabilityBoundingSet=CAP_SETGID CapabilityBoundingSet=CAP_AUDIT_WRITE PrivateDevices=false

mariadb.service가 있으므로 로 Alias=mysql.service시작하는 것이 가능
service mysql start하므로 원래 질문과 일치하는 것 같습니다.

관련 정보