ローカルマシン時間を調整せずにLXCでntpdのみをサーバーとして実行する方法

ローカルマシン時間を調整せずにLXCでntpdのみをサーバーとして実行する方法

デバイスの時計を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

これには2つの問題があります。

  1. ntpd録音後終了cap_set_proc() failed to drop root privileges: Operation not permitted
  2. ntpd現地時間を調整しようとしています。失敗しましたが試しました。これが唯一の問題であり、ログにエラーメッセージがある場合は問題ありません。

/var/log/messagesntpdを起動しようとした結果の全体出力:

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)です。

おすすめ記事