sudo Replace Current Process?
Clash Royale CLAN TAG#URR8PPP
I have an interesting use case. I'm running systemd in a container to simulate a VM for testing purposes. I'm able to run systemd just fine, but I need my default user to not be root so that anything execing into the container will get the right user and only then become root via sudo.
My ENTRYPOINT
is sudo /usr/lib/systemd/systemd --system --unit=multi-user.target
, and it works just fine for most things. However, due to the sudo
invocation, systemd does not get PID 1, which some downstream systemd units depend on.
According to the docs:
Process model
When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process. The main sudo process waits until the command has completed, then passes the command's exit status to the security policy's close function and exits. If an I/O logging plugin is configured or if the security policy explicitly requests it, a new pseudo-terminal (“pty”) is created and a second sudo process is used to relay job control signals between the user's existing pty and the new pty the command is being run in. This extra process makes it possible to, for example, suspend and resume the command. Without it, the command would be in what POSIX terms an “orphaned process group” and it would not receive any job control signals. As a special case, if the policy plugin does not define a close function and no pty is required, sudo will execute the command directly instead of calling fork(2) first. The sudoers policy plugin will only define a close function when I/O logging is enabled, a pty is required, or the pam_session or pam_setcred options are enabled. Note that pam_session and pam_setcred are enabled by default on systems using PAM.
Is there a way to tell sudo to replace itself with the child process that it runs, similar to exec
in Bash? Is there another better way to do this? It seems that I'd need to change "the policy plugin" potentially for just this one command, but I'm not sure how to do this.
systemd sudo docker
add a comment |
I have an interesting use case. I'm running systemd in a container to simulate a VM for testing purposes. I'm able to run systemd just fine, but I need my default user to not be root so that anything execing into the container will get the right user and only then become root via sudo.
My ENTRYPOINT
is sudo /usr/lib/systemd/systemd --system --unit=multi-user.target
, and it works just fine for most things. However, due to the sudo
invocation, systemd does not get PID 1, which some downstream systemd units depend on.
According to the docs:
Process model
When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process. The main sudo process waits until the command has completed, then passes the command's exit status to the security policy's close function and exits. If an I/O logging plugin is configured or if the security policy explicitly requests it, a new pseudo-terminal (“pty”) is created and a second sudo process is used to relay job control signals between the user's existing pty and the new pty the command is being run in. This extra process makes it possible to, for example, suspend and resume the command. Without it, the command would be in what POSIX terms an “orphaned process group” and it would not receive any job control signals. As a special case, if the policy plugin does not define a close function and no pty is required, sudo will execute the command directly instead of calling fork(2) first. The sudoers policy plugin will only define a close function when I/O logging is enabled, a pty is required, or the pam_session or pam_setcred options are enabled. Note that pam_session and pam_setcred are enabled by default on systems using PAM.
Is there a way to tell sudo to replace itself with the child process that it runs, similar to exec
in Bash? Is there another better way to do this? It seems that I'd need to change "the policy plugin" potentially for just this one command, but I'm not sure how to do this.
systemd sudo docker
sounds like you want a small setuid exec wrapper, security concerns of which being lessened if it is only used on a test virt
– thrig
Feb 14 at 20:57
1
Are you trying to start a Docker container with a user that is not root?
– ctrl-alt-delor
Feb 14 at 22:55
The use case is that I need to mimic a VM as closely as possible from within Docker (so I can run "VMs" on Travis CI). Thus, I want to run the actual init system as PID 1. However, I want it so thatdocker exec
gets an unprivileged user instead. It seems that I need to write some C or rust tosetuid
/setgid
to root and thenexecve
, replacing the current program with systemd as true PID 1.
– Naftuli Kay
Feb 14 at 23:08
add a comment |
I have an interesting use case. I'm running systemd in a container to simulate a VM for testing purposes. I'm able to run systemd just fine, but I need my default user to not be root so that anything execing into the container will get the right user and only then become root via sudo.
My ENTRYPOINT
is sudo /usr/lib/systemd/systemd --system --unit=multi-user.target
, and it works just fine for most things. However, due to the sudo
invocation, systemd does not get PID 1, which some downstream systemd units depend on.
According to the docs:
Process model
When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process. The main sudo process waits until the command has completed, then passes the command's exit status to the security policy's close function and exits. If an I/O logging plugin is configured or if the security policy explicitly requests it, a new pseudo-terminal (“pty”) is created and a second sudo process is used to relay job control signals between the user's existing pty and the new pty the command is being run in. This extra process makes it possible to, for example, suspend and resume the command. Without it, the command would be in what POSIX terms an “orphaned process group” and it would not receive any job control signals. As a special case, if the policy plugin does not define a close function and no pty is required, sudo will execute the command directly instead of calling fork(2) first. The sudoers policy plugin will only define a close function when I/O logging is enabled, a pty is required, or the pam_session or pam_setcred options are enabled. Note that pam_session and pam_setcred are enabled by default on systems using PAM.
Is there a way to tell sudo to replace itself with the child process that it runs, similar to exec
in Bash? Is there another better way to do this? It seems that I'd need to change "the policy plugin" potentially for just this one command, but I'm not sure how to do this.
systemd sudo docker
I have an interesting use case. I'm running systemd in a container to simulate a VM for testing purposes. I'm able to run systemd just fine, but I need my default user to not be root so that anything execing into the container will get the right user and only then become root via sudo.
My ENTRYPOINT
is sudo /usr/lib/systemd/systemd --system --unit=multi-user.target
, and it works just fine for most things. However, due to the sudo
invocation, systemd does not get PID 1, which some downstream systemd units depend on.
According to the docs:
Process model
When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process. The main sudo process waits until the command has completed, then passes the command's exit status to the security policy's close function and exits. If an I/O logging plugin is configured or if the security policy explicitly requests it, a new pseudo-terminal (“pty”) is created and a second sudo process is used to relay job control signals between the user's existing pty and the new pty the command is being run in. This extra process makes it possible to, for example, suspend and resume the command. Without it, the command would be in what POSIX terms an “orphaned process group” and it would not receive any job control signals. As a special case, if the policy plugin does not define a close function and no pty is required, sudo will execute the command directly instead of calling fork(2) first. The sudoers policy plugin will only define a close function when I/O logging is enabled, a pty is required, or the pam_session or pam_setcred options are enabled. Note that pam_session and pam_setcred are enabled by default on systems using PAM.
Is there a way to tell sudo to replace itself with the child process that it runs, similar to exec
in Bash? Is there another better way to do this? It seems that I'd need to change "the policy plugin" potentially for just this one command, but I'm not sure how to do this.
systemd sudo docker
systemd sudo docker
edited Feb 14 at 19:39
Naftuli Kay
asked Feb 14 at 19:21
Naftuli KayNaftuli Kay
12.5k56161256
12.5k56161256
sounds like you want a small setuid exec wrapper, security concerns of which being lessened if it is only used on a test virt
– thrig
Feb 14 at 20:57
1
Are you trying to start a Docker container with a user that is not root?
– ctrl-alt-delor
Feb 14 at 22:55
The use case is that I need to mimic a VM as closely as possible from within Docker (so I can run "VMs" on Travis CI). Thus, I want to run the actual init system as PID 1. However, I want it so thatdocker exec
gets an unprivileged user instead. It seems that I need to write some C or rust tosetuid
/setgid
to root and thenexecve
, replacing the current program with systemd as true PID 1.
– Naftuli Kay
Feb 14 at 23:08
add a comment |
sounds like you want a small setuid exec wrapper, security concerns of which being lessened if it is only used on a test virt
– thrig
Feb 14 at 20:57
1
Are you trying to start a Docker container with a user that is not root?
– ctrl-alt-delor
Feb 14 at 22:55
The use case is that I need to mimic a VM as closely as possible from within Docker (so I can run "VMs" on Travis CI). Thus, I want to run the actual init system as PID 1. However, I want it so thatdocker exec
gets an unprivileged user instead. It seems that I need to write some C or rust tosetuid
/setgid
to root and thenexecve
, replacing the current program with systemd as true PID 1.
– Naftuli Kay
Feb 14 at 23:08
sounds like you want a small setuid exec wrapper, security concerns of which being lessened if it is only used on a test virt
– thrig
Feb 14 at 20:57
sounds like you want a small setuid exec wrapper, security concerns of which being lessened if it is only used on a test virt
– thrig
Feb 14 at 20:57
1
1
Are you trying to start a Docker container with a user that is not root?
– ctrl-alt-delor
Feb 14 at 22:55
Are you trying to start a Docker container with a user that is not root?
– ctrl-alt-delor
Feb 14 at 22:55
The use case is that I need to mimic a VM as closely as possible from within Docker (so I can run "VMs" on Travis CI). Thus, I want to run the actual init system as PID 1. However, I want it so that
docker exec
gets an unprivileged user instead. It seems that I need to write some C or rust to setuid
/setgid
to root and then execve
, replacing the current program with systemd as true PID 1.– Naftuli Kay
Feb 14 at 23:08
The use case is that I need to mimic a VM as closely as possible from within Docker (so I can run "VMs" on Travis CI). Thus, I want to run the actual init system as PID 1. However, I want it so that
docker exec
gets an unprivileged user instead. It seems that I need to write some C or rust to setuid
/setgid
to root and then execve
, replacing the current program with systemd as true PID 1.– Naftuli Kay
Feb 14 at 23:08
add a comment |
1 Answer
1
active
oldest
votes
If you have control of the docker run
command line, then you could consider passing it a --user
option (such as --user=0:0
) instead of using sudo
in the ENTRYPOINT command.
In that case you can use ENTRYPOINT set to /usr/lib/systemd/systemd --system --unit=multi-user.target
, which will run systemd as PID 1, while still keeping a USER setting to take effect in your docker exec
commands.
See overriding USER in the docker run
reference manual.
Conversely, if you don't have control over the docker run
command line, you could try to pass --user
to the docker exec
commands, keeping USER as root in the container definition. That has some disadvantages, such as the fact you have to pass that option to all invocations and you need to figure out what user:group (or uid:gid) to pass it (root is easy, always 0:0.)
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f500693%2fsudo-replace-current-process%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you have control of the docker run
command line, then you could consider passing it a --user
option (such as --user=0:0
) instead of using sudo
in the ENTRYPOINT command.
In that case you can use ENTRYPOINT set to /usr/lib/systemd/systemd --system --unit=multi-user.target
, which will run systemd as PID 1, while still keeping a USER setting to take effect in your docker exec
commands.
See overriding USER in the docker run
reference manual.
Conversely, if you don't have control over the docker run
command line, you could try to pass --user
to the docker exec
commands, keeping USER as root in the container definition. That has some disadvantages, such as the fact you have to pass that option to all invocations and you need to figure out what user:group (or uid:gid) to pass it (root is easy, always 0:0.)
add a comment |
If you have control of the docker run
command line, then you could consider passing it a --user
option (such as --user=0:0
) instead of using sudo
in the ENTRYPOINT command.
In that case you can use ENTRYPOINT set to /usr/lib/systemd/systemd --system --unit=multi-user.target
, which will run systemd as PID 1, while still keeping a USER setting to take effect in your docker exec
commands.
See overriding USER in the docker run
reference manual.
Conversely, if you don't have control over the docker run
command line, you could try to pass --user
to the docker exec
commands, keeping USER as root in the container definition. That has some disadvantages, such as the fact you have to pass that option to all invocations and you need to figure out what user:group (or uid:gid) to pass it (root is easy, always 0:0.)
add a comment |
If you have control of the docker run
command line, then you could consider passing it a --user
option (such as --user=0:0
) instead of using sudo
in the ENTRYPOINT command.
In that case you can use ENTRYPOINT set to /usr/lib/systemd/systemd --system --unit=multi-user.target
, which will run systemd as PID 1, while still keeping a USER setting to take effect in your docker exec
commands.
See overriding USER in the docker run
reference manual.
Conversely, if you don't have control over the docker run
command line, you could try to pass --user
to the docker exec
commands, keeping USER as root in the container definition. That has some disadvantages, such as the fact you have to pass that option to all invocations and you need to figure out what user:group (or uid:gid) to pass it (root is easy, always 0:0.)
If you have control of the docker run
command line, then you could consider passing it a --user
option (such as --user=0:0
) instead of using sudo
in the ENTRYPOINT command.
In that case you can use ENTRYPOINT set to /usr/lib/systemd/systemd --system --unit=multi-user.target
, which will run systemd as PID 1, while still keeping a USER setting to take effect in your docker exec
commands.
See overriding USER in the docker run
reference manual.
Conversely, if you don't have control over the docker run
command line, you could try to pass --user
to the docker exec
commands, keeping USER as root in the container definition. That has some disadvantages, such as the fact you have to pass that option to all invocations and you need to figure out what user:group (or uid:gid) to pass it (root is easy, always 0:0.)
answered Feb 21 at 5:51
filbrandenfilbranden
10.5k21645
10.5k21645
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f500693%2fsudo-replace-current-process%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
sounds like you want a small setuid exec wrapper, security concerns of which being lessened if it is only used on a test virt
– thrig
Feb 14 at 20:57
1
Are you trying to start a Docker container with a user that is not root?
– ctrl-alt-delor
Feb 14 at 22:55
The use case is that I need to mimic a VM as closely as possible from within Docker (so I can run "VMs" on Travis CI). Thus, I want to run the actual init system as PID 1. However, I want it so that
docker exec
gets an unprivileged user instead. It seems that I need to write some C or rust tosetuid
/setgid
to root and thenexecve
, replacing the current program with systemd as true PID 1.– Naftuli Kay
Feb 14 at 23:08