I cannot find python-capng for Ubuntu 14.04, Python 2.7, so I'm guessing it's a new critter.
On Mon, Apr 27, 2015 at 8:33 AM, edso <[email protected]> wrote: > looks like capng is difficult to retrieve. if so i would hesitate to make > duplicity depend on it by default. > > does it work with older python? we officially support python 2.6+ still. > > ..ede/duply.net > > On 27.04.2015 15:15, Kenneth Loafman wrote: > > If I understand this correctly, then new files will be created by > > 'duplicity', but older files owned by root will not be deletable. > > Correct? I'm thinking a one-time 'chown -R duplicity: > ~/cache/duplicity/*' > > would fix that problem. > > > > > > On Sun, Apr 26, 2015 at 7:31 PM, James Wilson <[email protected]> wrote: > > > >> James Wilson has proposed merging lp:~jmwilson/duplicity/capabilities > into > >> lp:duplicity. > >> > >> Requested reviews: > >> duplicity-team (duplicity-team) > >> > >> For more details, see: > >> > https://code.launchpad.net/~jmwilson/duplicity/capabilities/+merge/257488 > >> > >> Proposal is to add an unprivileged "duplicity" user during installation > >> that is used to limit the capabilities when duplicity is run as root. To > >> manage capabilities, I'm using the python bindings for libcap-ng (which > >> needs its own updating since at least the current vivid package is empty > >> for some reason, but is correct when built from source). > >> > >> I've been interested in using duplicity for system-wide backups, but one > >> thing that is troubling is that it must be run as root. As an > interpreted > >> program that communicates on the network, this exposes the host to > possible > >> bugs in python or any other packages imported in duplicity. > >> > >> First, examining the code in bin/duplicity: > >> # if python is run setuid, it's only partway set, > >> # so make sure to run with euid/egid of root > >> if os.geteuid() == 0: > >> # make sure uid/gid match euid/egid > >> os.setuid(os.geteuid()) > >> os.setgid(os.getegid()) > >> > >> I'm not sure what this is for; if you're root (i.e., os.geteuid() == 0) > >> then there's no need to switch the real uid. When the machination of > >> "setuid(geteuid())" is used it is typically when the ruid=0 and we want > to > >> irrevocably drop privileges to a euid!=0 normal user. That's not the > case > >> here, so this doesn't help or harm us. > >> > >> Then there's the issue of running duplicity as root. Since it's an > >> interpreted program, the normal ways of expanding privileges (SUID > >> executable or setcap on the script) are unavailable, and the other > options > >> are to run it as root, or put SUID or file capabilities on the python > >> interpreter. > >> > >> The only reason to run duplicity as root is get read access to the whole > >> file system. We can safely drop all capabilities other than > >> CAP_DAC_READ_SEARCH. Since we're still root, we'll get all capabilities > >> back if we do execve, so we could also change the bounding set or lock > the > >> securebits to prevent the kernel from re-granting privileges on execve. > >> Nonetheless, we're still root, and lots of important files are owned by > and > >> writable to root, so the best choice is to change uid to an unprivileged > >> user who maintains only the ability to read the whole file system. > >> > >> It's hard to test the change directly, since it doesn't change the > output > >> or actions of duplicity. The following python script mimics what the > code > >> does and demonstrates the reduction of capabilities: > >> > >> #!/usr/bin/env python > >> > >> from __future__ import print_function > >> from capng import * > >> import fcntl > >> import os > >> import pwd > >> import signal > >> import sys > >> > >> if os.geteuid() != 0: > >> sys.exit() > >> > >> user = pwd.getpwnam("nobody") > >> capng_clear(CAPNG_SELECT_CAPS) > >> capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, > >> CAP_DAC_READ_SEARCH) > >> capng_change_id(user.pw_uid, user.pw_gid, CAPNG_DROP_SUPP_GRP) > >> > >> print("getuid = {}, geteuid = {}".format(os.getuid(), os.geteuid())) > >> print("After dropping capabilities:") > >> capng_get_caps_process() > >> capng_print_caps_numeric(CAPNG_PRINT_STDOUT, CAPNG_SELECT_BOTH) > >> print() > >> > >> pread, pwrite = os.pipe() > >> pid = os.fork() > >> if pid == 0: > >> os.close(pread) > >> fcntl.fcntl(pwrite, fcntl.F_SETFD, fcntl.FD_CLOEXEC) > >> os.execl('/usr/bin/tail', '-f', '/dev/null') > >> else: > >> os.close(pwrite) > >> os.read(pread, 1) > >> capng_setpid(pid) > >> capng_get_caps_process() > >> print("getuid = {}, geteuid = {}".format(os.getuid(), os.geteuid())) > >> print("Capabilities after execve:") > >> caps = capng_print_caps_numeric(CAPNG_PRINT_STDOUT, > CAPNG_SELECT_BOTH) > >> os.kill(pid, signal.SIGTERM) > >> > >> which when run as root (sudo python script.py) should produce this > output: > >> getuid = 65534, geteuid = 65534 > >> After dropping capabilities: > >> Effective: 00000000, 00000004 > >> Permitted: 00000000, 00000004 > >> Inheritable: 00000000, 00000000 > >> Bounding Set: 0000003F, FFFFFFFF > >> > >> getuid = 65534, geteuid = 65534 > >> Capabilities after execve: > >> Effective: 00000000, 00000000 > >> Permitted: 00000000, 00000000 > >> Inheritable: 00000000, 00000000 > >> Bounding Set: 0000003F, FFFFFFFF > >> > >> -- > >> Your team duplicity-team is requested to review the proposed merge of > >> lp:~jmwilson/duplicity/capabilities into lp:duplicity. > >> > >> === modified file 'README' > >> --- README 2014-10-18 19:44:29 +0000 > >> +++ README 2015-04-27 00:30:33 +0000 > >> @@ -23,6 +23,7 @@ > >> * librsync v0.9.6 or later > >> * GnuPG v1.x for encryption > >> * python-lockfile for concurrency locking > >> + * python-capng for managing capabilities when run as root > >> * for scp/sftp -- python-paramiko and python-pycryptopp > >> * for ftp -- lftp version 3.7.15 or later > >> * Boto 2.0 or later for single-processing S3 or GCS access (default) > >> > >> === modified file 'bin/duplicity' > >> --- bin/duplicity 2015-03-09 18:50:58 +0000 > >> +++ bin/duplicity 2015-04-27 00:30:33 +0000 > >> @@ -38,6 +38,8 @@ > >> import resource > >> import re > >> import threading > >> +import capng > >> +import pwd > >> from datetime import datetime > >> from lockfile import FileLock > >> > >> @@ -1340,12 +1342,18 @@ > >> See https://bugs.launchpad.net/duplicity/+bug/931175 > >> """), log.ErrorCode.pythonoptimize_set) > >> > >> - # if python is run setuid, it's only partway set, > >> - # so make sure to run with euid/egid of root > >> + # if python is running as root, then drop all capabilities except > >> + # unrestricted read access and then change user to prevent > regaining > >> + # capabilities via execve. > >> if os.geteuid() == 0: > >> - # make sure uid/gid match euid/egid > >> - os.setuid(os.geteuid()) > >> - os.setgid(os.getegid()) > >> + user = pwd.getpwnam("duplicity") > >> + capng.capng_clear(capng.CAPNG_SELECT_CAPS) > >> + if (capng.capng_update(capng.CAPNG_ADD, > >> + capng.CAPNG_EFFECTIVE | > >> capng.CAPNG_PERMITTED, > >> + capng.CAP_DAC_READ_SEARCH) > >> + or capng.capng_change_id(user.pw_uid, user.pw_gid, > >> + capng.CAPNG_DROP_SUPP_GRP)): > >> + log.FatalError("Unable to drop root privileges.") > >> > >> # set the current time strings (make it available for command line > >> processing) > >> dup_time.setcurtime() > >> > >> === modified file 'debian/control' > >> --- debian/control 2014-10-27 14:15:52 +0000 > >> +++ debian/control 2015-04-27 00:30:33 +0000 > >> @@ -27,6 +27,7 @@ > >> gnupg, > >> python-lockfile, > >> python-pexpect, > >> + python-capng, > >> Suggests: ncftp, > >> python-boto, > >> python-paramiko, > >> > >> === added file 'debian/duplicity.postinst' > >> --- debian/duplicity.postinst 1970-01-01 00:00:00 +0000 > >> +++ debian/duplicity.postinst 2015-04-27 00:30:33 +0000 > >> @@ -0,0 +1,7 @@ > >> +#!/bin/sh -e > >> + > >> +if [ "$1" = "configure" ]; then > >> + if ! getent passwd duplicity >/dev/null; then > >> + adduser --quiet --system --no-create-home --home /nonexistant > --shell > >> /usr/sbin/nologin duplicity > >> + fi > >> +fi > >> > >> > >> _______________________________________________ > >> Mailing list: https://launchpad.net/~duplicity-team > >> Post to : [email protected] > >> Unsubscribe : https://launchpad.net/~duplicity-team > >> More help : https://help.launchpad.net/ListHelp > >> > >> > > > > -- > https://code.launchpad.net/~jmwilson/duplicity/capabilities/+merge/257488 > You are subscribed to branch lp:duplicity. > -- https://code.launchpad.net/~jmwilson/duplicity/capabilities/+merge/257488 Your team duplicity-team is requested to review the proposed merge of lp:~jmwilson/duplicity/capabilities into lp:duplicity. _______________________________________________ Mailing list: https://launchpad.net/~duplicity-team Post to : [email protected] Unsubscribe : https://launchpad.net/~duplicity-team More help : https://help.launchpad.net/ListHelp

