简体   繁体   English

如果您不想在 root 上运行,为什么 Linux 自托管运行器上的 Github 操作需要用户交换每个命令

[英]Why does a Github Action on a Linux self-hosted runner require a user swap for every command if you dont want to run on root

I'm wrote a workflow to install some tool dependencies on a Linux self-hosted GitHub runner VM.我编写了一个工作流来在 Linux 自托管 GitHub 运行器 VM 上安装一些工具依赖项。 I'm using homebrew to do the tool installs.我正在使用自制软件来安装工具。 Using homebrew requires that it not be run on the root user which is what the GitHub Runner logs in as.使用 homebrew 要求它不在 root 用户上运行,这是 GitHub Runner 登录的身份。 I'm wondering why when I create a step that switches the user from root to my test user things break but when I sudo to that user in every step things work fine, I think I explained this poorly so see below:我想知道为什么当我创建一个将用户从 root 切换到我的测试用户的步骤时,事情会中断,但是当我在每个步骤中对那个用户执行 sudo 时一切正常,我想我解释得不好,所以见下文:

Failing Workflow (you can see the first step switches the user to testUser):失败的工作流程(可以看到第一步将用户切换到 testUser):

 installHomebrew:
    name: Install Homebrew
    runs-on: [self-hosted]
        
    steps:
      - name: Switch to etpAdmin user
        run: sudo -u testUser -i

      - name: Install Homebrew silently
        run: sudo apt install linuxbrew-wrapper -y
        
      - name: Run brew for the first time to create the .linuxbrew directory
        run: brew -h

This will fail on the last step claiming homebrew shouldn't be run on root while the following workflow works just fine.这将在最后一步失败,声称不应在 root 上运行自制软件,而以下工作流程可以正常工作。

 installHomebrew:
    name: Install Homebrew
    runs-on: [self-hosted]
        
    steps:
      - name: Install Homebrew silently
        run: sudo apt install linuxbrew-wrapper -y
        
      - name: Run brew for the first time to create the .linuxbrew directory
        run: sudo -u testUser -i brew -h

My Linux is a little rusty but I was under the impression using sudo -u (username) -i will log the terminal into the specified user until logout/switching user again, am I wrong or is there a better way to accomplish this?我的 Linux 有点生锈,但我的印象是使用sudo -u (username) -i将终端登录到指定的用户,直到再次注销/切换用户,我错了还是有更好的方法来完成这个?

Disclaimer;免责声明; I'm not familiar with the platform you are running on or the tool you are using, but I do have an educated guess.. and I hope this also how the -i flag behaves.我不熟悉您正在运行的平台或您正在使用的工具,但我确实有一个有根据的猜测......我希望这也是-i标志的行为方式。

As most provisioners work, they usually run each step (mostly) independently from other steps.由于大多数供应商都在工作,它们通常(大部分)独立于其他步骤运行每个步骤。 Which (again, usually) means that environment from one step is not carried over to the next one.这(再次,通常)意味着环境不会从一个步骤转移到下一个步骤。 So in this case, running sudo -i in one step will not have any effect on subsequent steps.所以在这种情况下,一步运行sudo -i不会对后续步骤产生任何影响。 You can try this to see how the provisioner in your case operates:您可以试试这个,看看您的情况下的配置程序是如何运行的:

testUserChange:
    name: Test active user
    runs-on: [self-hosted]
        
    steps:
      - name: Default user
        run: whoami
        
      - name: Sudo user
        run: sudo -u testUser -i whoami

      - name: Should be default user again
        run: whoami

      - name: Maybe interactive shell like in first attempt
        run: sudo -u testUser -i

      - name: Who am I now
        run: whoami

Now as for the -i , the manual states:现在至于-i ,手册指出:

This means that login-specific resource files such as.profile or.login will be read by the shell.这意味着 shell 将读取特定于登录的资源文件,例如 .profile 或 .login。 If a command is specified, it is passed to the shell for execution via the shell's -c option.如果指定了命令,则通过 shell 的 -c 选项将其传递给 shell 以执行。 If no command is specified, an interactive shell is executed.如果未指定命令,则执行交互式 shell。

While this may be a bit confusing, as most provisioners don't expect user interactive input at runtime, they would usually close the STDIN handle (the input to the process).虽然这可能有点令人困惑,因为大多数供应商不希望用户在运行时进行交互式输入,他们通常会关闭 STDIN 句柄(进程的输入)。 If we have two users, user0ne and usertw0 , I hope I can demonstrate the behavior;如果我们有两个用户user0neusertw0 ,我希望我能演示一下行为;

$ export PS1="This is user0ne env \$ " # just to show when environment variables are re-set due to loading the login scripts
This is user0ne env $
This is user0ne env $ whoami
user0ne
This is user0ne env $ sudo -u usertw0 /bin/sh
This is user0ne env $ whoami
usertw0
This is user0ne env $ exit
This is user0ne env $ whoami
user0ne
This is user0ne env $

In the above example, you can see that while the effective user is tw0, the environment is still set to what 0ne has set.在上面的示例中,您可以看到虽然有效用户是 tw0,但环境仍然设置为 0ne 设置的设置。 Let's try with -i :让我们试试-i

This is user0ne env $ sudo -u usertw0 -i /bin/sh
$ whoami
usertw0
$ exit
This is user0ne env $

So by now, looks like -i sets the environment (and login) to tw0's.所以到目前为止,看起来-i将环境(和登录)设置为 tw0。 Now, while the documentation does state that without any argument an interactive shell is opened:现在,虽然文档确实 state 没有任何参数,但打开了交互式 shell:

This is user0ne env $ sudo -u usertw0 -i
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

usertw0@ubuntu:~$ logout
This is user0ne env $

Let's see what happens if we close the input handler (or more accurately, input nothing):让我们看看如果我们关闭输入处理程序(或者更准确地说,不输入任何内容)会发生什么:

This is user0ne env $ sudo -u usertw0 -i < /dev/null
This is user0ne env $ whoami
user0ne
This is user0ne env $

And the same will happen even if you provide /bin/sh as the command to run, like shown in a snippet above:即使您提供/bin/sh作为要运行的命令,也会发生同样的情况,如上面的片段所示:

This is user0ne env $ sudo -u usertw0 -i /bin/sh < /dev/null
This is user0ne env $ whoami
user0ne
This is user0ne env $

So even though the documentation does state it will open an interactive shell, the shell closes once there is no input to be read, and the state returns to the previous user. So even though the documentation does state it will open an interactive shell, the shell closes once there is no input to be read, and the state returns to the previous user.

Cheers: :)干杯::)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在Linux中的mount --bind需要root特权? - Why does mount --bind in linux require root privileges? GitHub 作为服务失败的自托管运行器 - GitHub action self-host runner as service fails linux从以普通用户身份运行的c代码中以root身份运行命令 - linux running command as root from c code that run as normal user 如何通过 bash 检查 Linux 上自托管 Azure DevOps 代理上正在运行的作业 - How to check running job on self-hosted Azure DevOps Agent on Linux via bash 为什么“谁”命令不显示从“ root”用户登录的“用户名”? - Why does the “who” command not show “username” logged from “root” user? 想通过 ansible 运行一个简单的 root 命令 - want to run a easy root command by ansible 在Linux上通过CIM会话运行DSC cmdlet是否需要root用户? - Is running DSC cmdlets through CIM session on Linux require root user? 在BeagleBone Black上,如何获得以非root用户身份启动时运行的命令? - How would you get a command to run on startup as a non-root user, on BeagleBone Black? Linux上的共享库:为什么动态链接程序在用户上下文中运行? - Shared Libs on Linux: why does the dynamic linker run in user context? 以 root 用户身份在 jenkins 中运行 shell 命令? - Run shell command in jenkins as root user?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM