Git Product home page Git Product logo

unshare's Introduction

Rust Unshare

Status: 90% feature-complete, works in production in lithos and powers vagga

Github | Documentaion | Crate

Unshare is a low-level library to create linux containers.

It contains the following:

  • Process creation interface similar to std::process::Command
  • Unsharing arbitrary linux namespaces
  • Ability to change root (chroot/pivot_root), uid, gid, gid_map
  • Some signal mask handling (especially for new processes)
  • Forwarding file descriptors and other unixy stuff (sessions, terminals)
  • Setting few important prctl flags (PR_SET_PDEATHSIG)
  • Runs both as root user and as unprivileged user

Not implemeneted yet:

  • Fine grained capabilities control (currently you may change user or use user namespaces)

The following is considered:

  • Capture input (should be, because part of std::process interface)
  • Pseudo tty creation for child
  • The unshare and setns

The following is out of scope:

  • mounting file systems
  • setting up network
  • in-container and out of container supervision
  • handing child signals

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

unshare's People

Contributors

anti-social avatar iohannesarnold avatar joshtriplett avatar nivkner avatar tailhook avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

unshare's Issues

Fails to build for target aarch64-unknown-linux-gnu

On aarch64-unknown-linux-gnu, unshare fails to build with the following error:

error[E0308]: mismatched types
  --> src/child.rs:94:28
   |
94 |                 .copy_from(data.as_ptr() as *const i8, data.len());
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `i8`
   |
   = note: expected raw pointer `*const u8`
              found raw pointer `*const i8`

error[E0308]: mismatched types
   --> src/child.rs:229:18
    |
229 |                  child.environ.as_ptr() as *const *const i8);
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `i8`
    |
    = note: expected raw pointer `*const *const u8`
               found raw pointer `*const *const i8`

You can reproduce this by installing the aarch64-unknown-linux-gnu target with rustup target add, then building with cargo build --target aarch64-unknown-linux-gnu.

See rust-lang/rust#79089 for a proposed lint that would have caught this.

Support changing the Command program

Since Command mostly adheres to a builder pattern, and spawn can be called multiple times, it would be useful to change the program.

Motivating example: a user wants to fall back to an less common filename or path in the case of a failure to spawn.

Proposed signature would look:
pub fn program<S: AsRef<OsStr>>(&mut self, program: S) -> &mut Command

Calling program would imply calling arg0.

It doesn't look like the effected filename has a whole lot of other implications to worry about.

I could put together a PR for this if you're interested.

environment ordering

I'd like to be able to control the ordering of variables in the environment. Would it be reasonable for the environment hash to become an ordered hash-map, rather than an unordered one?

pivot_root fails with user namespace used

pivot_root succeeds if user namespace is not used, but fails with EINVAL (os error 22). Bind mounting the new_root to itself solves it. I think that's a hack used by go example as well. Maybe the CloneCb should include this logic?

Environment: Xenial 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Missing many capabilities

Hello, thank you very much for your project!
I am using the Linux capabilities feature, and many are missing. There are 42 in today's Linux kernels, but only 38 are available in your library. Could you please make it generic or refer to a capability-focused library?

Thank you very much.

Support additional isolation features

Would you consider PRs that add support for Linux sandboxing features that are complementary to namespaces, such as MAC (via AppArmor, for example) and seccomp filters?

This would enable using unshare to build safe(r) sandboxes, by limiting the exposed attack surface on the rest of the system, esp. the kernel.

bump nix dependency

we received a dependency bot alert suggesting we bump our nix dependency to 0.20.2 or greater. our dependency is coming from this project which is locked to 0.20.0.

would you consider a PR to update to 0.20.2?

setns happens in child process after uid/gid mapping

I want to put the child into a network namespace by calling setns, but this requires CAP_SYS_ADMIN, which I've lost after the uid/gid mapping. (Basically building a rootless container). The calls to setns happen in child_after_clone, which is called after the uid/gid mapping is done in after_start, which then wakes the child process. So the order currently is:

clone->wait->after_start (which does uid/gid mapping) -> wakeup -> child_after_clone (which calls setns)

Am I doing something wrong?

unshare --map-root-user

Hi,

Thanks for this amazing library. I need to execute a binary using unshare. I am able to execute it in my shell using: unshare --map-root-user --net -- /path/to/binary just fine.

I have this so far but I get errors:

let mut namespaces: Vec<unshare::Namespace> = Vec::new();
namespaces.push(unshare::Namespace::Net);
namespaces.push(unshare::Namespace::User);

let mut executor = unshare::Command::new(dest);
executor
  .arg("job_id")
  .arg(job_path1)
  .arg("--verbose")
  .unshare(&namespaces)
  .uid(0)
  .gid(0);


let executor_process_handle = executor
  .spawn()
  .map_err(|e| tonic::Status::internal(format!("Unable to spawn executor {}", e)))?;

And this gives me:

Unable to spawn executor error when forking: Operation not permitted (os error 1)

I also tried this:

let mut namespaces: Vec<unshare::Namespace> = Vec::new();
namespaces.push(unshare::Namespace::Net);
namespaces.push(unshare::Namespace::User);
namespaces.push(unshare::Namespace::Pid);

let uid_map = UidMap {
     inside_uid: 0,
     outside_uid: getuid().as_raw(),
     count: 1,
 };
 let gid_map = GidMap {
     inside_gid: 0,
     outside_gid: getgid().as_raw(),
     count: 0,
 };

 let mut executor = unshare::Command::new(dest);

 executor
     .arg("job_id")
     .arg(job_path1)
     .arg("--verbose")
     .unshare(&namespaces)
     .set_id_maps(vec![uid_map], vec![gid_map]);

let executor_process_handle = executor
  .spawn()
  .map_err(|e| tonic::Status::internal(format!("Unable to spawn executor {}", e)))?;

And this gives me: Unable to spawn executor error setting uid/gid mappings: Permission denied (os error 13).

Just not sure what I am missing. Any help would be appreciated.

Best,
Shriphani

Allow changing namespaces for child process

We need to implement support for setns syscall.

Documentation says that setns supports 0 as nstype argument:

0      Allow any type of namespace to be joined.

How we can implement this?

Specific method:

cmd.setns_any(fd);

Or using Option:

cmd.setns(fd, None)

Or with special type:

cmd.setns(fd, SetNs::Any)

ping: is this project active?

Hi,
I'm very interested in this project. I have tried it out and made some slight changes in my fork at https://github.com/sjames/unshare.
I'm posting this to check if someone is listening and whether they may be interested in a pull request.

I'm also curious to learn where this library is being used.

Thanks and regards,
Sojan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.