2

私の要件

私のpythonサーバーはRHELで通常のユーザーとして実行されますが、アクセスできない場所にファイル/ディレクトリを作成する必要があります。また、ランダムな UID/GID でこれらのファイルを chown する必要があります

私のアプローチ

機能のみの環境でこれを試してみてください。setuid はありません。cap_chown および cap_dac_override 機能を利用しようとしています。しかし、systemctlのような環境で動作させる方法が完全に失われています

現在、サービスファイルには次のものがあります。

#cat /usr/lib/systemd/system/my_server.service 

[Service]
Type=simple
SecureBits=keep-caps
User=testuser
CapabilityBoundingSet=~
Capabilities=cap_dac_override,cap_chown=eip
ExecStart=/usr/bin/linux_capability_test.py

そして、バイナリ自体に続きます:

# getcap /usr/bin/linux_capability_test.py
/usr/bin/linux_capability_test.py = cap_chown,cap_dac_override+ei

しかし、これは、スクリプトでは決して機能しないと言っています。 非ルートプロセスが Linux の「特権」ポートにバインドする方法はありますか?

現在の設定では、実行中のプロセスに対して私が持っている機能は次のとおりです。

# ps -ef | grep lin
testuser    28268     1  0 22:31 ?        00:00:00 python /usr/bin/linux_capability_test.py

# getpcaps 28268
Capabilities for `28268': = cap_chown,cap_dac_override+i

しかし、そのスクリプト内から /etc/ にファイルを作成しようとすると:

try:
    file_name = '/etc/junk'
    with open(file_name, 'w') as f:
        os.utime(file_name,None)

「許可が拒否されました」で失敗します

それがうまくいかないのは私にとって同じケースですか?ここで python-prctl モジュールを使用して動作させることはできますか?

4

3 に答える 3

0

更新:これを行う方法ですが、最良の方法かどうかはわかりません。「python-prctl」モジュールの使用:

1. Ditch 'User=testuser' from my-server.service
2. Start server as root
3. Set 'keep_caps' flag True
4. Do 'setgroups, setgid and setuid'
5. And immediately limit the permitted capability set to 'DAC_OVERRIDE' and 'CHOWN' capability only
6. Set the effective capability for both to True

ここに同じコードがあります

import prctl

prctl.securebits.keep_caps = True

os.setgroups([160])
os.setgid(160)
os.setuid(160)

prctl.cap_permitted.limit(prctl.CAP_CHOWN, prctl.CAP_DAC_OVERRIDE)
prctl.cap_effective.dac_override = True
prctl.cap_effective.chown = True`

終わり !!

于 2015-08-08T09:34:03.177 に答える
0

上記の議論に基づいて、私は次のことを行いました。

[Service]
Type=simple
User=testuser
SecureBits=keep-caps
Capabilities=cap_chown,cap_dac_override=i
ExecStart=/usr/bin/linux_capability_test.py

これにより、これらの両方の機能を継承可能としてサーバーが起動します。

chownファイルに小さなC、テストコードを書きました

#include <unistd.h>

int main()
  {
    int ret = 0;

    ret = chown("/etc/junk", 160, 160);

    return ret;
  }

gcc 化されたバイナリで次のように設定します

chown testuser:testuser /usr/bin/chown_c
chmod 550 /usr/bin/chown_c
setcap cap_chown,cap_dac_override=ie /usr/bin/chown_c

サーバーはバイナリを呼び出すために次のことを行います

import prctl
prctl.cap_inheritable.chown = True
prctl.cap_inheritable.dac_override = True
execve('/usr/bin/chown_c',[],os.environ)

そして、私は望ましい結果を得ることができました

# ll /etc/junk 
-rw-r--r-- 1 root root 0 Aug  8 22:33 /etc/junk

# python capability_client.py 

# ll /etc/junk 
-rw-r--r-- 1 testuser testuser 0 Aug  8 22:33 /etc/junk
于 2015-08-08T17:16:09.843 に答える
0

setuid は、スクリプトの実行方法によるセキュリティ ホールであるため、スクリプトでは機能しません。これについてはいくつかの文書があります。ウィキペディアのページを見ることから始めることもできます。

非常に良い回避策は、Python スクリプトとスクリプトへのパスをハードコーディングして Python スクリプトを起動する小さな C プログラムを作成することです。すべての問題に関する本当に良い議論がここにあります

于 2015-08-08T02:50:22.683 に答える