장치의 시계를 LXC 내에서 실행되는 CentOS-7 서버와 동기화해야 합니다. 서버에서는 패키지 ntpd
에서 사용하려고 시도하지만 다른 제품에는 열려 있습니다. ntp
이 질문은 ntpd
서버 또는 이에 상응하는 설정에 관한 것입니다.
지금까지 나는 이것을 시도했다/etc/ntp.conf
driftfile /var/lib/ntp/drift
restrict default nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict ::1
server 127.127.1.1 iburst
fudge 127.127.1.1 stratum 8
disable monitor
여기에는 두 가지 문제가 있습니다.
ntpd
녹음 후 종료cap_set_proc() failed to drop root privileges: Operation not permitted
ntpd
현지 시간을 조정하려고 합니다. 실패했지만 시도했습니다. 이것이 유일한 문제이고 로그에 오류 메시지가 있는 경우에는 괜찮습니다.
/var/log/messages
ntpd를 시작하려고 시도한 결과 전체 출력:
systemd: Starting Network Time Service...
ntpd[20154]: ntpd [email protected] Wed Apr 12 21:24:06 UTC 2017 (1)
ntpd[20155]: proto: precision = 0.120 usec
ntpd[20155]: ntp_adjtime() failed: Operation not permitted
systemd: Started Network Time Service.
ntpd[20155]: 0.0.0.0 c01d 0d kern kernel time sync enabled
ntpd[20155]: Listen and drop on 0 v4wildcard 0.0.0.0 UDP 123
ntpd[20155]: Listen and drop on 1 v6wildcard :: UDP 123
ntpd[20155]: Listen normally on 2 lo 127.0.0.1 UDP 123
ntpd[20155]: Listen normally on 3 eth0 hidden:A.B.C.D UDP 123
ntpd[20155]: Listen normally on 4 tun0 hidden:E.F.G.H UDP 123
ntpd[20155]: Listening on routing socket on fd #21 for interface updates
ntpd[20155]: 0.0.0.0 c016 06 restart
ntpd[20155]: ntp_adjtime() failed: Operation not permitted
ntpd[20155]: 0.0.0.0 c012 02 freq_set kernel 0.000 PPM
ntpd[20155]: 0.0.0.0 c011 01 freq_not_set
ntpd[20155]: cap_set_proc() failed to drop root privileges: Operation not permitted
systemd: ntpd.service: main process exited, code=exited, status=255/n/a
systemd: Unit ntpd.service entered failed state.
systemd: ntpd.service failed.
답변1
댓글에서 논의한 바와 같이,만성병 환자-x
최근에는 시스템 시계 변경을 시도하지 않는 새로운 옵션이 추가 되어 특히 컨테이너 작업에 적합합니다. 안타깝게도 이 옵션을 받은 첫 번째 버전(3.2)은 철저하지 않았으며 여전히 Linux 기능을 요청했기 때문에 여전히 실패했습니다.
깁스CentOS7 LXC 컨테이너(CentOS가 아닌 호스트 포함)의 chronyd 패키지 chrony 버전 3.2-2.el7에는 옵션이 포함되어 있지만 -x
실제로 버그 수정은 여기에 없습니다.
# strace /usr/sbin/chronyd -x -d
[...]
[pid 571] capget({_LINUX_CAPABILITY_VERSION_3, 0}, NULL) = 0
[pid 571] capset({_LINUX_CAPABILITY_VERSION_3, 0}, {1<<CAP_NET_BIND_SERVICE|1<<CAP_SYS_TIME, 1<<CAP_NET_BIND_SERVICE|1<<CAP_SYS_TIME, 0}) = -1 EPERM (Operation not permitted)
따라서 수정할 수 없는 바이너리 크로니드가 금지된 기능을 요청하는 것을 방지할 수 있다면 작동할 것입니다(3.3 버그 수정이 바로 이것이었습니다). 좋은 소식입니다. LD_PRELOAD
/를 사용할 수 있습니다 .dlsym()
포장지.
다른 Linux 시스템에서 컴파일(실제로는 Debian 9 호스트에서 컴파일되었으며 CentOS7 컨테이너에서 문제 없이 실행됨) 이 코드는 이라고 불리며 capsetwrapper.c
구조 정의가 발견되었습니다.거기예를 들어(커널 3.10에서도 변경되지 않았습니다).
#define _GNU_SOURCE 1
#include <dlfcn.h>
#include <sys/capability.h>
int capset(cap_user_header_t hdrp, const cap_user_data_t datap) {
int (*orig_capset)(cap_user_header_t,const cap_user_data_t)=dlsym(RTLD_NEXT,"capset");
datap->effective &= ~ (1<<CAP_SYS_TIME);
datap->permitted &= ~ (1<<CAP_SYS_TIME);
return orig_capset(hdrp, datap);
}
다음과 같은 특정 방법을 사용하십시오(라이브러리를 LD_PRELOAD
사용하기에 적합하게 만들기 위해):
gcc -shared -fPIC -o libcapsetwrapper.so capsetwrapper.c -ldl
작동 방식은 다음과 같습니다.
[root@centos7-amd64bis ~]# LD_PRELOAD=/root/libcapsetwrapper.so /usr/sbin/chronyd -x -d
2019-03-24T10:09:58Z chronyd version 3.2 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SECHASH +SIGND +ASYNCDNS +IPV6 +DEBUG)
2019-03-24T10:09:58Z Disabled control of system clock
2019-03-24T10:09:58Z Frequency 0.000 +/- 1000000.000 ppm read from /var/lib/chrony/drift
런타임 시 기능을 확인하세요.
# egrep '^Cap(Prm|Eff)' /proc/$(pidof chronyd)/status
CapPrm: 0000000000000400
CapEff: 0000000000000400
위에 표시된 나머지인 0x400을 표시합니다 1<<CAP_NET_BIND_SERVICE
.
시스템에 통합하려면:
포장지를 다음
libcapsetwrapper.so
과 같이 배치합니다./usr/local/lib/libcapsetwrapper.so
systemctl edit chronyd
재정의 검사를 사용하면CAP_SYS_TIME
실행 파일이 다음과 같이 시작됩니다.[Unit] ConditionCapability= [Service] ExecStart= ExecStart=/bin/sh -c 'export LD_PRELOAD=/usr/local/lib/libcapsetwrapper.so; exec /usr/sbin/chronyd -x'
죄송합니다. 매개변수를 재사용할 수 없습니다
$OPTIONS
(비어 있으므로-x
옵션을 에서 로드해야 함/etc/sysconfig/chronyd
). 하지만 더 체계화된 지식이 있으면 가능합니다.
작업 결과:
# systemctl status chronyd
● chronyd.service - NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
Drop-In: /etc/systemd/system/chronyd.service.d
`-override.conf
Active: active (running) since Sun 2019-03-24 10:24:26 UTC; 13min ago
Docs: man:chronyd(8)
man:chrony.conf(5)
Process: 843 ExecStartPost=/usr/libexec/chrony-helper update-daemon (code=exited, status=0/SUCCESS)
Process: 839 ExecStart=/bin/sh -c export LD_PRELOAD=/usr/local/lib/libcapsetwrapper.so; exec /usr/sbin/chronyd -x (code=exited, status=0/SUCCESS)
Main PID: 841 (chronyd)
CGroup: /system.slice/chronyd.service
`-841 /usr/sbin/chronyd -x
테스트되지 않은 것은 기본 SELinux 환경(여기에서는 사용할 수 없음)이 사전 로드 작업을 허용하는지 아니면 더 많은 작업을 수행해야 하는지 /usr/local/lib/libcapsetwrapper.so
(반드시 사용 restorecon
)입니다.
답변2
버전 이후1908년 7월 7일CentOS에는 chrony
버전이 있습니다3.4이 플래그를 올바르게 지원 하며 -x
약간의 구성 조정을 통해 LXC에서 실행될 수 있습니다.
- 기본적 으로
/usr/lib/systemd/system/chronyd.service
LXC에서ConditionCapability=CAP_SYS_TIME
실행할 때는 없어야 하므로-x
파일에 이 삭제 항목을 추가하여 제거하세요./etc/systemd/system/chronyd.service.d/lxc.conf
[Unit]
# Default service has:
# ConditionCapability=CAP_SYS_TIME
# which does not work under LXC and causes service to refuse to start
# Clear it.
ConditionCapability=
편집
/etc/sysconfig/chronyd
하고 마지막-x
에 추가하세요OPTIONS
OPTIONS="-x"
/etc/chrony.conf
NTP 서버와 동기화하지 않고 대신 로컬 시계의 시간을 제공하도록 변경합니다 . 다른 모든server
항목을 제거/비활성화하고 다음을 추가합니다.
# Comment out default/other server entries
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
#
# Add these as per https://www.thegeekdiary.com/centos-rhel-7-chrony-how-to-sync-to-local-clock/
server 127.127.1.0
local stratum 10
allow all
예제의 내용이 귀하에게 적합하지 않을 수 있으므로 allow
귀하의 필요에 맞게 지침을 검토하십시오 .allow all
- 서비스를 다시 로드하고 다시 시작하세요.
systemctl daemon-reload
systemctl restart chronyd
그래야 합니다.
답변3
작동하게 하는 방법을 찾았지만 내 솔루션이 만족스럽지 않아 여전히 더 나은 답변을 찾고 있습니다.
ntpd
파트 1: 루트 권한을 포기하려는 시도를 차단했습니다 .
기본 값은 다음 /usr/lib/systemd/system/ntpd.service
과 같습니다:
[Service]
EnvironmentFile=-/etc/sysconfig/ntpd
ExecStart=/usr/sbin/ntpd -u ntp:ntp $OPTIONS
-u ntp:ntp
그래서 배치하여 "제거"합니다./etc/systemd/system/ntpd.service.d/local.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/ntpd $OPTIONS
이를 통해 ntpd
루트로 계속 실행할 수 있습니다. 작동하지만 이 접근 방식은 만족스럽지 않습니다.
2부. 현지 시간 부분을 업데이트하지 않음
/etc/ntp.conf
이 줄을 추가하면 서비스가 시작될 때 오류를 설정하지 않고 3번 기록하는 대신 1번의 오류만 기록 disable kernel
하게 됩니다 . 시계를 변경할 수 없으므로 이는 허용됩니다. 이상적으로는 시계를 변경하려고 시도하지도 않습니다.ntpd
ntp_adjtime() failed: Operation not permitted