
Debianで実行され、SELinuxを適用するいくつかのOpenVPNインスタンス(サーバー1台、複数のクライアント)を持つサーバーがあります。マイコンピュータに接続されているVPNサーバーの一部は、接続がやや不安定で、マイコンピュータのOpenVPNインスタンスが時々クラッシュするため、クラッシュ時に再起動するようにcronjobを設定しました。
今の問題は、SELinuxの問題によってこのcronjobが失敗するということですが、私はよく理解していません。同じコマンドを使用してコマンドラインからOpenVPNインスタンスを手動で再起動すると、問題はありません。監査結果は次のとおりです。
type=AVC msg=audit(1422960005.730:3567927): avc: denied { sys_module } for pid=14309 comm="ifconfig" capability=16 scontext=system_u:system_r:openvpn_t:s0 tcontext=system_u:system_r:openvpn_t:s0 tclass=capability
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
type=AVC msg=audit(1422960005.722:3567921): avc: denied { relabelfrom } for pid=14295 comm="openvpn" scontext=system_u:system_r:openvpn_t:s0 tcontext=unconfined_u:system_r:openvpn_t:s0-s0:c0.c1023 tclass=tun_socket
Was caused by:
#Constraint rule:
constrain tun_socket { create relabelfrom relabelto } ((u1 == u2 -Fail-) or (t1 == { logrotate_t ldconfig_t initrc_t sysadm_t dpkg_t lvm_t mdadm_t unconfined_mount_t dpkg_script_t newrole_t local_login_t sysadm_passwd_t system_cronjob_t tmpreaper_t unconfined_execmem_t httpd_unconfined_script_t groupadd_t depmod_t insmod_t kernel_t passwd_t updpwd_t apmd_t apt_t chfn_t init_t sshd_t udev_t remote_login_t inetd_child_t restorecond_t setfiles_t unconfined_t systemd_tmpfiles_t sulogin_t useradd_t } -Fail-) ); Constraint DENIED
# Possible cause is the source user (system_u) and target user (unconfined_u) are different.
# Possible cause is the source level (s0) and target level (s0-s0:c0.c1023) are different.
SELinuxが動作するようにローカルopenvpn設定を設定しました。次のようになります。
module openvpn_local 1.0;
require {
type openvpn_t;
type kernel_t;
type udev_t;
type var_run_t;
class system module_request;
class file { read append };
class capability sys_module;
class tun_socket { relabelfrom relabelto };
}
#============= openvpn_t ==============
allow openvpn_t kernel_t:system module_request;
# allow openvpn_t self:capability sys_module;
allow openvpn_t self:tun_socket { relabelfrom relabelto };
allow udev_t var_run_t:file { read append };
この設定は、静的デバイスノードでOpenVPNインスタンスを実行するために設定をいくつか変更する必要があるまで機能しました。その時点から与えられた権利はもはや十分ではないように見えました。
このための細かいソリューションを構築するのに役立つか、OpenVPNの基本的なSELinuxモジュールを改善する方法について教えてください。
答え1
最初のエラーは明らかです。コメントアウトした行は、監査から欠落していると思う権限を提供します。
2番目の部分はもっと面白いですが、修正中のソケット(unconfined_u所有)のターゲットコンテキストに問題があると考えられます。静的デバイスノードに移動したので、インターフェイスを変更するopenvpnプロセスによってもはやインターフェイスが作成されなくなり、self:tun_socketではもう十分ではないと思います。 system_uが所有するようにノードのコンテキストを変更してこの問題を解決することもできます。
すべてのネットワーク設定がinitscriptで処理され、起動時にすべてが正常に機能する場合は、run_init /etc/init.d/openvpn start
rootのcrontabでそれを使用して操作を実行できます。run_init
スクリプトの起動時と同じコンテキストで実行されていることを確認してください。
編集:クラッシュに敏感でデーモンにpidファイルがある場合は、inotify
/proc/pidでいくつかの魔法を使用してファイルが消えることを確認してから、再起動スクリプトを呼び出すことができます。waitpid
より良いでしょうが、子プロセスに固有のものです。
答え2
SELinux がないため、お手伝いできません。ただし、OpenVPN を引き続き実行できない場合は、次のコードを検討してください。
while sleep 5; do
/command/to/start/OpenVPN
done
これは、OpenVPNがフォアグラウンドで実行されていると仮定します。 OpenVPNコマンドラインオプションを変更してフォアグラウンドに維持する必要があるかもしれません。スクリプトは5秒待ってからOpenVPNを起動します。 OpenVPNが終了したら、5秒間スリープモードに切り替えてOpenVPNを起動します。泡立て、すすぎ、繰り返します。
見苦しいハッキングですが、スクリーンセッションで実行すると操作は完了です。必要に応じて、画面上で実行されるすべてのスクリプトで作成できます。このハッキングがどれほど醜いかは、どんなに強調しても過度ではありません...しかし、cronで定期的にサービスを再起動することも同様です。