How do I drop root privileges in shell scripts?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
11
down vote

favorite
4












The "--up" option in OpenVPN is normally used for routing etc. And so it is processed before OpenVPN drops root privileges to run as nobody. However, I am invoking shell scripts that need to run as an unprivileged user.



How do I do that? I have studied Drop Process Privileges, especially polynomial's and tylerl's answers, but I do not understand how to implement. I am working in Centos 6.5, and suid is blocked, both as "chmod u+s" and as "setuid()".



There is an OpenVPN plugin ("openvpn-down-root.so") which enables scripts invoked by the "--down" option to run as root. There could be an equivalent, such as "openvpn-up-user.so", but I have not found it.



Edit0



Per Nikola Kotur's answer, I've installed Ian Meyer's runit-rpm. Although the chpst command works in terminal, in the up script it fails with "command not found". What works is "sudo chpst" plus setting the proper display and language. Please see Why doesn't my terminal output unicode characters properly? Given that, the up script needs these four lines:



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &


Edit1



Per 0xC0000022L's comment, I find that "sudo -u user" works as well as "sudo chpst -u user -U user":



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &


I'll study man sudoers and update if/when I get sudo alone to work.










share|improve this question























  • comment left by @user66229: "May I suggest that you surf to sourceforge.net/p/openvpn/mailman and subscribe to the lists that you find most appropriate."
    – slm♦
    May 30 '14 at 13:52










  • @user66229 Thank you. But I don't believe that this is an OpenVPN-specific question. Why do you believe that it is?
    – mirimir
    May 31 '14 at 11:05














up vote
11
down vote

favorite
4












The "--up" option in OpenVPN is normally used for routing etc. And so it is processed before OpenVPN drops root privileges to run as nobody. However, I am invoking shell scripts that need to run as an unprivileged user.



How do I do that? I have studied Drop Process Privileges, especially polynomial's and tylerl's answers, but I do not understand how to implement. I am working in Centos 6.5, and suid is blocked, both as "chmod u+s" and as "setuid()".



There is an OpenVPN plugin ("openvpn-down-root.so") which enables scripts invoked by the "--down" option to run as root. There could be an equivalent, such as "openvpn-up-user.so", but I have not found it.



Edit0



Per Nikola Kotur's answer, I've installed Ian Meyer's runit-rpm. Although the chpst command works in terminal, in the up script it fails with "command not found". What works is "sudo chpst" plus setting the proper display and language. Please see Why doesn't my terminal output unicode characters properly? Given that, the up script needs these four lines:



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &


Edit1



Per 0xC0000022L's comment, I find that "sudo -u user" works as well as "sudo chpst -u user -U user":



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &


I'll study man sudoers and update if/when I get sudo alone to work.










share|improve this question























  • comment left by @user66229: "May I suggest that you surf to sourceforge.net/p/openvpn/mailman and subscribe to the lists that you find most appropriate."
    – slm♦
    May 30 '14 at 13:52










  • @user66229 Thank you. But I don't believe that this is an OpenVPN-specific question. Why do you believe that it is?
    – mirimir
    May 31 '14 at 11:05












up vote
11
down vote

favorite
4









up vote
11
down vote

favorite
4






4





The "--up" option in OpenVPN is normally used for routing etc. And so it is processed before OpenVPN drops root privileges to run as nobody. However, I am invoking shell scripts that need to run as an unprivileged user.



How do I do that? I have studied Drop Process Privileges, especially polynomial's and tylerl's answers, but I do not understand how to implement. I am working in Centos 6.5, and suid is blocked, both as "chmod u+s" and as "setuid()".



There is an OpenVPN plugin ("openvpn-down-root.so") which enables scripts invoked by the "--down" option to run as root. There could be an equivalent, such as "openvpn-up-user.so", but I have not found it.



Edit0



Per Nikola Kotur's answer, I've installed Ian Meyer's runit-rpm. Although the chpst command works in terminal, in the up script it fails with "command not found". What works is "sudo chpst" plus setting the proper display and language. Please see Why doesn't my terminal output unicode characters properly? Given that, the up script needs these four lines:



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &


Edit1



Per 0xC0000022L's comment, I find that "sudo -u user" works as well as "sudo chpst -u user -U user":



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &


I'll study man sudoers and update if/when I get sudo alone to work.










share|improve this question















The "--up" option in OpenVPN is normally used for routing etc. And so it is processed before OpenVPN drops root privileges to run as nobody. However, I am invoking shell scripts that need to run as an unprivileged user.



How do I do that? I have studied Drop Process Privileges, especially polynomial's and tylerl's answers, but I do not understand how to implement. I am working in Centos 6.5, and suid is blocked, both as "chmod u+s" and as "setuid()".



There is an OpenVPN plugin ("openvpn-down-root.so") which enables scripts invoked by the "--down" option to run as root. There could be an equivalent, such as "openvpn-up-user.so", but I have not found it.



Edit0



Per Nikola Kotur's answer, I've installed Ian Meyer's runit-rpm. Although the chpst command works in terminal, in the up script it fails with "command not found". What works is "sudo chpst" plus setting the proper display and language. Please see Why doesn't my terminal output unicode characters properly? Given that, the up script needs these four lines:



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo chpst -u user -U user /home/user/unprivileged.sh &


Edit1



Per 0xC0000022L's comment, I find that "sudo -u user" works as well as "sudo chpst -u user -U user":



LANG="en_US.UTF-8"; export LANG
GDM_LANG="en_US.UTF-8"; export GDM_LANG
DISPLAY=:0; export DISPLAY
sudo -u user /home/user/unprivileged.sh &


I'll study man sudoers and update if/when I get sudo alone to work.







shell-script root centos privileges setuid






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 23 '17 at 12:39









Community♦

1




1










asked May 30 '14 at 7:15









mirimir

2181413




2181413











  • comment left by @user66229: "May I suggest that you surf to sourceforge.net/p/openvpn/mailman and subscribe to the lists that you find most appropriate."
    – slm♦
    May 30 '14 at 13:52










  • @user66229 Thank you. But I don't believe that this is an OpenVPN-specific question. Why do you believe that it is?
    – mirimir
    May 31 '14 at 11:05
















  • comment left by @user66229: "May I suggest that you surf to sourceforge.net/p/openvpn/mailman and subscribe to the lists that you find most appropriate."
    – slm♦
    May 30 '14 at 13:52










  • @user66229 Thank you. But I don't believe that this is an OpenVPN-specific question. Why do you believe that it is?
    – mirimir
    May 31 '14 at 11:05















comment left by @user66229: "May I suggest that you surf to sourceforge.net/p/openvpn/mailman and subscribe to the lists that you find most appropriate."
– slm♦
May 30 '14 at 13:52




comment left by @user66229: "May I suggest that you surf to sourceforge.net/p/openvpn/mailman and subscribe to the lists that you find most appropriate."
– slm♦
May 30 '14 at 13:52












@user66229 Thank you. But I don't believe that this is an OpenVPN-specific question. Why do you believe that it is?
– mirimir
May 31 '14 at 11:05




@user66229 Thank you. But I don't believe that this is an OpenVPN-specific question. Why do you believe that it is?
– mirimir
May 31 '14 at 11:05










5 Answers
5






active

oldest

votes

















up vote
7
down vote



accepted










I use runit's chpst tool for tasks like this. For example, from the up script call your unprivileged script:



chpst -u nobody /path/to/script





share|improve this answer




















  • Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
    – mirimir
    May 30 '14 at 10:23










  • @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
    – Nikola Kotur
    Jun 2 '14 at 14:22

















up vote
6
down vote













Covering only runit and sudo misses a lot. There is actually a whole family of toolsets like runit, and a wide choice of tools for doing exactly this, the very task that they were designed for:



  • Daniel J. Bernstein's daemontools, has setuidgid:
    setuidgid user /home/user/unprivileged.sh


  • Adam Sampson's freedt has setuidgid:
    setuidgid user /home/user/unprivileged.sh


  • Bruce Guenter's daemontools-encore has setuidgid:
    setuidgid user /home/user/unprivileged.sh


  • Gerrit Pape's runit has chpst:
    chpst -u user /home/user/unprivileged.sh


  • Wayne Marshall's perp has runuid:
    runuid user /home/user/unprivileged.sh


  • Laurent Bercot's s6 has s6-setuidgid:
    s6-setuidgid user /home/user/unprivileged.sh


  • my nosh has setuidgid:
    setuidgid user /home/user/unprivileged.sh


They don't mix in the different task of adding privileges, and never fall into an interactive mode.



Your tacked-on problems are little more than your forgetting to have sbin as well as bin in your PATH, by the way.



Further reading



  • Jonathan de Boyne Pollard (2014). Don't abuse su for dropping user privileges. Frequently Given Answers.





share|improve this answer



























    up vote
    3
    down vote













    script which drops privileges and runs other script (but here I just made it to run itself):



    #!/bin/sh

    id=`id -u`
    safeuser="nobody"

    if [ $id = "0" ]
    then
    # we're root. dangerous!
    sudo -u $safeuser $0
    else
    echo "I'm not root"
    id
    fi


    Example:



    root@n3:/tmp/x# id
    uid=0(root) gid=0(root) группы=0(root)
    root@n3:/tmp/x# ./drop.sh
    I'm not root
    uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)





    share|improve this answer




















    • While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
      – mirimir
      May 31 '14 at 2:08







    • 1




      @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
      – 0xC0000022L
      Jun 1 '14 at 0:19










    • @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
      – mirimir
      Jun 1 '14 at 1:50







    • 1




      Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
      – Charles Duffy
      Jun 2 '17 at 0:59







    • 2




      ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
      – Charles Duffy
      Jun 2 '17 at 1:03


















    up vote
    1
    down vote













    What about:



    sudo -Eu <user> <command>


    You complained about environment in a previous comment, so you might also compare the differences between the outputs:



    sudo -u <user> printenv
    sudo -Eu <user> printenv





    share|improve this answer



























      up vote
      0
      down vote













      On Linux you can use runuser or setpriv if a PAM session is not required (both from util-linux):



      runuser -u USER [--] COMMAND [ARGUMENTS...]

      setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...] # Like su/runuser/sudo
      setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...] # Like daemontools setuid(8)


      From the su man page:




      su is mostly designed for unprivileged users, the recommended
      solution for privileged users (e.g. scripts executed by root) is to
      use non-set-user-ID command runuser(1) that does not require
      authentication and provide separate PAM configuration. If the PAM
      session is not required at all then the recommend solution is to use
      command setpriv(1).






      share








      New contributor




      dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.

















        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',
        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
        );



        );













         

        draft saved


        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f132663%2fhow-do-i-drop-root-privileges-in-shell-scripts%23new-answer', 'question_page');

        );

        Post as a guest






























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        7
        down vote



        accepted










        I use runit's chpst tool for tasks like this. For example, from the up script call your unprivileged script:



        chpst -u nobody /path/to/script





        share|improve this answer




















        • Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
          – mirimir
          May 30 '14 at 10:23










        • @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
          – Nikola Kotur
          Jun 2 '14 at 14:22














        up vote
        7
        down vote



        accepted










        I use runit's chpst tool for tasks like this. For example, from the up script call your unprivileged script:



        chpst -u nobody /path/to/script





        share|improve this answer




















        • Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
          – mirimir
          May 30 '14 at 10:23










        • @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
          – Nikola Kotur
          Jun 2 '14 at 14:22












        up vote
        7
        down vote



        accepted







        up vote
        7
        down vote



        accepted






        I use runit's chpst tool for tasks like this. For example, from the up script call your unprivileged script:



        chpst -u nobody /path/to/script





        share|improve this answer












        I use runit's chpst tool for tasks like this. For example, from the up script call your unprivileged script:



        chpst -u nobody /path/to/script






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered May 30 '14 at 9:16









        Nikola Kotur

        1862




        1862











        • Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
          – mirimir
          May 30 '14 at 10:23










        • @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
          – Nikola Kotur
          Jun 2 '14 at 14:22
















        • Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
          – mirimir
          May 30 '14 at 10:23










        • @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
          – Nikola Kotur
          Jun 2 '14 at 14:22















        Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
        – mirimir
        May 30 '14 at 10:23




        Cool :) Thank you. Is github.com/imeyer/runit-rpm the best way to get runit into Centos 6.5? Even with Red Hat repos, I'm not finding a package.
        – mirimir
        May 30 '14 at 10:23












        @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
        – Nikola Kotur
        Jun 2 '14 at 14:22




        @mirimir, yes, I use that repo when I need to build a runit package for CentOS.
        – Nikola Kotur
        Jun 2 '14 at 14:22












        up vote
        6
        down vote













        Covering only runit and sudo misses a lot. There is actually a whole family of toolsets like runit, and a wide choice of tools for doing exactly this, the very task that they were designed for:



        • Daniel J. Bernstein's daemontools, has setuidgid:
          setuidgid user /home/user/unprivileged.sh


        • Adam Sampson's freedt has setuidgid:
          setuidgid user /home/user/unprivileged.sh


        • Bruce Guenter's daemontools-encore has setuidgid:
          setuidgid user /home/user/unprivileged.sh


        • Gerrit Pape's runit has chpst:
          chpst -u user /home/user/unprivileged.sh


        • Wayne Marshall's perp has runuid:
          runuid user /home/user/unprivileged.sh


        • Laurent Bercot's s6 has s6-setuidgid:
          s6-setuidgid user /home/user/unprivileged.sh


        • my nosh has setuidgid:
          setuidgid user /home/user/unprivileged.sh


        They don't mix in the different task of adding privileges, and never fall into an interactive mode.



        Your tacked-on problems are little more than your forgetting to have sbin as well as bin in your PATH, by the way.



        Further reading



        • Jonathan de Boyne Pollard (2014). Don't abuse su for dropping user privileges. Frequently Given Answers.





        share|improve this answer
























          up vote
          6
          down vote













          Covering only runit and sudo misses a lot. There is actually a whole family of toolsets like runit, and a wide choice of tools for doing exactly this, the very task that they were designed for:



          • Daniel J. Bernstein's daemontools, has setuidgid:
            setuidgid user /home/user/unprivileged.sh


          • Adam Sampson's freedt has setuidgid:
            setuidgid user /home/user/unprivileged.sh


          • Bruce Guenter's daemontools-encore has setuidgid:
            setuidgid user /home/user/unprivileged.sh


          • Gerrit Pape's runit has chpst:
            chpst -u user /home/user/unprivileged.sh


          • Wayne Marshall's perp has runuid:
            runuid user /home/user/unprivileged.sh


          • Laurent Bercot's s6 has s6-setuidgid:
            s6-setuidgid user /home/user/unprivileged.sh


          • my nosh has setuidgid:
            setuidgid user /home/user/unprivileged.sh


          They don't mix in the different task of adding privileges, and never fall into an interactive mode.



          Your tacked-on problems are little more than your forgetting to have sbin as well as bin in your PATH, by the way.



          Further reading



          • Jonathan de Boyne Pollard (2014). Don't abuse su for dropping user privileges. Frequently Given Answers.





          share|improve this answer






















            up vote
            6
            down vote










            up vote
            6
            down vote









            Covering only runit and sudo misses a lot. There is actually a whole family of toolsets like runit, and a wide choice of tools for doing exactly this, the very task that they were designed for:



            • Daniel J. Bernstein's daemontools, has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            • Adam Sampson's freedt has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            • Bruce Guenter's daemontools-encore has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            • Gerrit Pape's runit has chpst:
              chpst -u user /home/user/unprivileged.sh


            • Wayne Marshall's perp has runuid:
              runuid user /home/user/unprivileged.sh


            • Laurent Bercot's s6 has s6-setuidgid:
              s6-setuidgid user /home/user/unprivileged.sh


            • my nosh has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            They don't mix in the different task of adding privileges, and never fall into an interactive mode.



            Your tacked-on problems are little more than your forgetting to have sbin as well as bin in your PATH, by the way.



            Further reading



            • Jonathan de Boyne Pollard (2014). Don't abuse su for dropping user privileges. Frequently Given Answers.





            share|improve this answer












            Covering only runit and sudo misses a lot. There is actually a whole family of toolsets like runit, and a wide choice of tools for doing exactly this, the very task that they were designed for:



            • Daniel J. Bernstein's daemontools, has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            • Adam Sampson's freedt has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            • Bruce Guenter's daemontools-encore has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            • Gerrit Pape's runit has chpst:
              chpst -u user /home/user/unprivileged.sh


            • Wayne Marshall's perp has runuid:
              runuid user /home/user/unprivileged.sh


            • Laurent Bercot's s6 has s6-setuidgid:
              s6-setuidgid user /home/user/unprivileged.sh


            • my nosh has setuidgid:
              setuidgid user /home/user/unprivileged.sh


            They don't mix in the different task of adding privileges, and never fall into an interactive mode.



            Your tacked-on problems are little more than your forgetting to have sbin as well as bin in your PATH, by the way.



            Further reading



            • Jonathan de Boyne Pollard (2014). Don't abuse su for dropping user privileges. Frequently Given Answers.






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 24 '17 at 22:06









            JdeBP

            30.9k465141




            30.9k465141




















                up vote
                3
                down vote













                script which drops privileges and runs other script (but here I just made it to run itself):



                #!/bin/sh

                id=`id -u`
                safeuser="nobody"

                if [ $id = "0" ]
                then
                # we're root. dangerous!
                sudo -u $safeuser $0
                else
                echo "I'm not root"
                id
                fi


                Example:



                root@n3:/tmp/x# id
                uid=0(root) gid=0(root) группы=0(root)
                root@n3:/tmp/x# ./drop.sh
                I'm not root
                uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)





                share|improve this answer




















                • While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
                  – mirimir
                  May 31 '14 at 2:08







                • 1




                  @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
                  – 0xC0000022L
                  Jun 1 '14 at 0:19










                • @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
                  – mirimir
                  Jun 1 '14 at 1:50







                • 1




                  Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
                  – Charles Duffy
                  Jun 2 '17 at 0:59







                • 2




                  ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
                  – Charles Duffy
                  Jun 2 '17 at 1:03















                up vote
                3
                down vote













                script which drops privileges and runs other script (but here I just made it to run itself):



                #!/bin/sh

                id=`id -u`
                safeuser="nobody"

                if [ $id = "0" ]
                then
                # we're root. dangerous!
                sudo -u $safeuser $0
                else
                echo "I'm not root"
                id
                fi


                Example:



                root@n3:/tmp/x# id
                uid=0(root) gid=0(root) группы=0(root)
                root@n3:/tmp/x# ./drop.sh
                I'm not root
                uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)





                share|improve this answer




















                • While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
                  – mirimir
                  May 31 '14 at 2:08







                • 1




                  @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
                  – 0xC0000022L
                  Jun 1 '14 at 0:19










                • @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
                  – mirimir
                  Jun 1 '14 at 1:50







                • 1




                  Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
                  – Charles Duffy
                  Jun 2 '17 at 0:59







                • 2




                  ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
                  – Charles Duffy
                  Jun 2 '17 at 1:03













                up vote
                3
                down vote










                up vote
                3
                down vote









                script which drops privileges and runs other script (but here I just made it to run itself):



                #!/bin/sh

                id=`id -u`
                safeuser="nobody"

                if [ $id = "0" ]
                then
                # we're root. dangerous!
                sudo -u $safeuser $0
                else
                echo "I'm not root"
                id
                fi


                Example:



                root@n3:/tmp/x# id
                uid=0(root) gid=0(root) группы=0(root)
                root@n3:/tmp/x# ./drop.sh
                I'm not root
                uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)





                share|improve this answer












                script which drops privileges and runs other script (but here I just made it to run itself):



                #!/bin/sh

                id=`id -u`
                safeuser="nobody"

                if [ $id = "0" ]
                then
                # we're root. dangerous!
                sudo -u $safeuser $0
                else
                echo "I'm not root"
                id
                fi


                Example:



                root@n3:/tmp/x# id
                uid=0(root) gid=0(root) группы=0(root)
                root@n3:/tmp/x# ./drop.sh
                I'm not root
                uid=65534(nobody) gid=65534(nogroup) группы=65534(nogroup)






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered May 30 '14 at 21:38









                yaroslaff

                762




                762











                • While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
                  – mirimir
                  May 31 '14 at 2:08







                • 1




                  @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
                  – 0xC0000022L
                  Jun 1 '14 at 0:19










                • @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
                  – mirimir
                  Jun 1 '14 at 1:50







                • 1




                  Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
                  – Charles Duffy
                  Jun 2 '17 at 0:59







                • 2




                  ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
                  – Charles Duffy
                  Jun 2 '17 at 1:03

















                • While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
                  – mirimir
                  May 31 '14 at 2:08







                • 1




                  @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
                  – 0xC0000022L
                  Jun 1 '14 at 0:19










                • @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
                  – mirimir
                  Jun 1 '14 at 1:50







                • 1




                  Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
                  – Charles Duffy
                  Jun 2 '17 at 0:59







                • 2




                  ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
                  – Charles Duffy
                  Jun 2 '17 at 1:03
















                While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
                – mirimir
                May 31 '14 at 2:08





                While using "sudo -u user" works for some commands, it doesn't provide enough user environment for my purposes. And while "su -l user" works fine in terminal, it does nothing in scripts. I suppose that's a security feature. So it seems that I'm left with installing runit.
                – mirimir
                May 31 '14 at 2:08





                1




                1




                @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
                – 0xC0000022L
                Jun 1 '14 at 0:19




                @mirimir: why? /etc/sudoers allows to be very specific what environment variables can be conveyed to the program run by sudo and so on. man sudoers. Honestly, whoever uses sudo merely for sudo su - or to switch user context has no clue about what's behind this awesome program and how much you can lock down things for individual programs, users, hosts etc ...
                – 0xC0000022L
                Jun 1 '14 at 0:19












                @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
                – mirimir
                Jun 1 '14 at 1:50





                @0xC0000022L Thanks. I took another look at sudo. And yes, "sudo -u user" plus display and language also works.
                – mirimir
                Jun 1 '14 at 1:50





                1




                1




                Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
                – Charles Duffy
                Jun 2 '17 at 0:59





                Speaking of dangerous -- you can't trust $0; the caller can set a script's $0 to literally anything they want it to be. And use more quotes.
                – Charles Duffy
                Jun 2 '17 at 0:59





                2




                2




                ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
                – Charles Duffy
                Jun 2 '17 at 1:03





                ...if your script's $0 is /directory/name with spaces/script (and remember, users can create arbitrary symlinks in locations they own, even if they don't use exec -a somename yourscript to call yourscript with a $0 of somename), then you'd get sudo -u nobody /directory/name with spaces, with with and spaces passed as separate arguments to your command.
                – Charles Duffy
                Jun 2 '17 at 1:03











                up vote
                1
                down vote













                What about:



                sudo -Eu <user> <command>


                You complained about environment in a previous comment, so you might also compare the differences between the outputs:



                sudo -u <user> printenv
                sudo -Eu <user> printenv





                share|improve this answer
























                  up vote
                  1
                  down vote













                  What about:



                  sudo -Eu <user> <command>


                  You complained about environment in a previous comment, so you might also compare the differences between the outputs:



                  sudo -u <user> printenv
                  sudo -Eu <user> printenv





                  share|improve this answer






















                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    What about:



                    sudo -Eu <user> <command>


                    You complained about environment in a previous comment, so you might also compare the differences between the outputs:



                    sudo -u <user> printenv
                    sudo -Eu <user> printenv





                    share|improve this answer












                    What about:



                    sudo -Eu <user> <command>


                    You complained about environment in a previous comment, so you might also compare the differences between the outputs:



                    sudo -u <user> printenv
                    sudo -Eu <user> printenv






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jun 1 '14 at 3:47









                    thiagowfx

                    736413




                    736413




















                        up vote
                        0
                        down vote













                        On Linux you can use runuser or setpriv if a PAM session is not required (both from util-linux):



                        runuser -u USER [--] COMMAND [ARGUMENTS...]

                        setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...] # Like su/runuser/sudo
                        setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...] # Like daemontools setuid(8)


                        From the su man page:




                        su is mostly designed for unprivileged users, the recommended
                        solution for privileged users (e.g. scripts executed by root) is to
                        use non-set-user-ID command runuser(1) that does not require
                        authentication and provide separate PAM configuration. If the PAM
                        session is not required at all then the recommend solution is to use
                        command setpriv(1).






                        share








                        New contributor




                        dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                        Check out our Code of Conduct.





















                          up vote
                          0
                          down vote













                          On Linux you can use runuser or setpriv if a PAM session is not required (both from util-linux):



                          runuser -u USER [--] COMMAND [ARGUMENTS...]

                          setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...] # Like su/runuser/sudo
                          setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...] # Like daemontools setuid(8)


                          From the su man page:




                          su is mostly designed for unprivileged users, the recommended
                          solution for privileged users (e.g. scripts executed by root) is to
                          use non-set-user-ID command runuser(1) that does not require
                          authentication and provide separate PAM configuration. If the PAM
                          session is not required at all then the recommend solution is to use
                          command setpriv(1).






                          share








                          New contributor




                          dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.



















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            On Linux you can use runuser or setpriv if a PAM session is not required (both from util-linux):



                            runuser -u USER [--] COMMAND [ARGUMENTS...]

                            setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...] # Like su/runuser/sudo
                            setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...] # Like daemontools setuid(8)


                            From the su man page:




                            su is mostly designed for unprivileged users, the recommended
                            solution for privileged users (e.g. scripts executed by root) is to
                            use non-set-user-ID command runuser(1) that does not require
                            authentication and provide separate PAM configuration. If the PAM
                            session is not required at all then the recommend solution is to use
                            command setpriv(1).






                            share








                            New contributor




                            dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            On Linux you can use runuser or setpriv if a PAM session is not required (both from util-linux):



                            runuser -u USER [--] COMMAND [ARGUMENTS...]

                            setpriv --reuid=1000 --regid=1000 --init-groups COMMAND [ARGUMENTS...] # Like su/runuser/sudo
                            setpriv --reuid=1000 --regid=1000 --clear-groups COMMAND [ARGUMENTS...] # Like daemontools setuid(8)


                            From the su man page:




                            su is mostly designed for unprivileged users, the recommended
                            solution for privileged users (e.g. scripts executed by root) is to
                            use non-set-user-ID command runuser(1) that does not require
                            authentication and provide separate PAM configuration. If the PAM
                            session is not required at all then the recommend solution is to use
                            command setpriv(1).







                            share








                            New contributor




                            dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.








                            share


                            share






                            New contributor




                            dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            answered 1 min ago









                            dcoles

                            1011




                            1011




                            New contributor




                            dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.





                            New contributor





                            dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






                            dcoles is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.



























                                 

                                draft saved


                                draft discarded















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f132663%2fhow-do-i-drop-root-privileges-in-shell-scripts%23new-answer', 'question_page');

                                );

                                Post as a guest













































































                                Popular posts from this blog

                                How to check contact read email or not when send email to Individual?

                                Bahrain

                                Postfix configuration issue with fips on centos 7; mailgun relay