Sudo: disallow shell escapes as a default

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











up vote
2
down vote

favorite












I cannot work out how to disable shell escapes for any command, so that I could (this is an example!) do something like:



sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


The sudoers manual says this:




A command may have zero or more tags associated with it. There are
eight possible tag values, NOPASSWD, PASSWD, NOEXEC, EXEC, SETENV,
NOSETENV, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT and NOLOG_OUTPUT. Once a
tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit
the tag unless it is overridden by the opposite tag (i.e.: PASSWD
overrides NOPASSWD and NOEXEC overrides EXEC)




But this doesn't describe how to set more than one flag.
Using a comma doesn't appear to work (it treats the second tag as an alias)



Better still, I'd like to set a default, so the line above would be:




defaults NOEXEC



sudo-user ALL=(ALL) NOPASSWD: ALL




I know that sudo can be compiled with noexec, but that's not practical in this instance. I also know that this isn't the whole answer - it's possible to subvert by setting LD_PRELOAD appropriately, but it's a start.



Sudo version:



Sudo version 1.8.19p2
Sudoers policy plugin version 1.8.19p2
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.19p2
On RHEL 7.5









share|improve this question























  • If you are worried about shell escapes, then you should not give sudo.
    – Rui F Ribeiro
    1 hour ago










  • Yeah, that's my position too, TBH. I suspect though that sudo offers enough security theatre for the powers that be to be happy.
    – Graham Nicholls
    24 mins ago














up vote
2
down vote

favorite












I cannot work out how to disable shell escapes for any command, so that I could (this is an example!) do something like:



sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


The sudoers manual says this:




A command may have zero or more tags associated with it. There are
eight possible tag values, NOPASSWD, PASSWD, NOEXEC, EXEC, SETENV,
NOSETENV, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT and NOLOG_OUTPUT. Once a
tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit
the tag unless it is overridden by the opposite tag (i.e.: PASSWD
overrides NOPASSWD and NOEXEC overrides EXEC)




But this doesn't describe how to set more than one flag.
Using a comma doesn't appear to work (it treats the second tag as an alias)



Better still, I'd like to set a default, so the line above would be:




defaults NOEXEC



sudo-user ALL=(ALL) NOPASSWD: ALL




I know that sudo can be compiled with noexec, but that's not practical in this instance. I also know that this isn't the whole answer - it's possible to subvert by setting LD_PRELOAD appropriately, but it's a start.



Sudo version:



Sudo version 1.8.19p2
Sudoers policy plugin version 1.8.19p2
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.19p2
On RHEL 7.5









share|improve this question























  • If you are worried about shell escapes, then you should not give sudo.
    – Rui F Ribeiro
    1 hour ago










  • Yeah, that's my position too, TBH. I suspect though that sudo offers enough security theatre for the powers that be to be happy.
    – Graham Nicholls
    24 mins ago












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I cannot work out how to disable shell escapes for any command, so that I could (this is an example!) do something like:



sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


The sudoers manual says this:




A command may have zero or more tags associated with it. There are
eight possible tag values, NOPASSWD, PASSWD, NOEXEC, EXEC, SETENV,
NOSETENV, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT and NOLOG_OUTPUT. Once a
tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit
the tag unless it is overridden by the opposite tag (i.e.: PASSWD
overrides NOPASSWD and NOEXEC overrides EXEC)




But this doesn't describe how to set more than one flag.
Using a comma doesn't appear to work (it treats the second tag as an alias)



Better still, I'd like to set a default, so the line above would be:




defaults NOEXEC



sudo-user ALL=(ALL) NOPASSWD: ALL




I know that sudo can be compiled with noexec, but that's not practical in this instance. I also know that this isn't the whole answer - it's possible to subvert by setting LD_PRELOAD appropriately, but it's a start.



Sudo version:



Sudo version 1.8.19p2
Sudoers policy plugin version 1.8.19p2
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.19p2
On RHEL 7.5









share|improve this question















I cannot work out how to disable shell escapes for any command, so that I could (this is an example!) do something like:



sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


The sudoers manual says this:




A command may have zero or more tags associated with it. There are
eight possible tag values, NOPASSWD, PASSWD, NOEXEC, EXEC, SETENV,
NOSETENV, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT and NOLOG_OUTPUT. Once a
tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit
the tag unless it is overridden by the opposite tag (i.e.: PASSWD
overrides NOPASSWD and NOEXEC overrides EXEC)




But this doesn't describe how to set more than one flag.
Using a comma doesn't appear to work (it treats the second tag as an alias)



Better still, I'd like to set a default, so the line above would be:




defaults NOEXEC



sudo-user ALL=(ALL) NOPASSWD: ALL




I know that sudo can be compiled with noexec, but that's not practical in this instance. I also know that this isn't the whole answer - it's possible to subvert by setting LD_PRELOAD appropriately, but it's a start.



Sudo version:



Sudo version 1.8.19p2
Sudoers policy plugin version 1.8.19p2
Sudoers file grammar version 45
Sudoers I/O plugin version 1.8.19p2
On RHEL 7.5






linux sudo






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 24 mins ago









GAD3R

23.3k164896




23.3k164896










asked 2 hours ago









Graham Nicholls

17912




17912











  • If you are worried about shell escapes, then you should not give sudo.
    – Rui F Ribeiro
    1 hour ago










  • Yeah, that's my position too, TBH. I suspect though that sudo offers enough security theatre for the powers that be to be happy.
    – Graham Nicholls
    24 mins ago
















  • If you are worried about shell escapes, then you should not give sudo.
    – Rui F Ribeiro
    1 hour ago










  • Yeah, that's my position too, TBH. I suspect though that sudo offers enough security theatre for the powers that be to be happy.
    – Graham Nicholls
    24 mins ago















If you are worried about shell escapes, then you should not give sudo.
– Rui F Ribeiro
1 hour ago




If you are worried about shell escapes, then you should not give sudo.
– Rui F Ribeiro
1 hour ago












Yeah, that's my position too, TBH. I suspect though that sudo offers enough security theatre for the powers that be to be happy.
– Graham Nicholls
24 mins ago




Yeah, that's my position too, TBH. I suspect though that sudo offers enough security theatre for the powers that be to be happy.
– Graham Nicholls
24 mins ago










2 Answers
2






active

oldest

votes

















up vote
6
down vote













Don't do this.



You're giving the sudo-user the ability to run any commands as any user. That includes the ability to modify /etc/sudoers using any tool that does not require executing sub-processes. You may be thinking that excludes visudo, but strictly speaking, you don't need visudo to edit /etc/sudoers.



Like, for example:



sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers


...and the user has just removed the NOEXEC: restriction.



A restriction that the user can remove at will is not a true restriction.




Also, NOEXEC: may cause problems. It does not just prevent shell escapes: it prevents the program executed with sudo from directly starting any other programs. This can have a lot of consequences.



For example, if your sudo-user stops and later restarts the cron daemon (e.g. to stop scheduled jobs for the duration of some maintenance), the restarted cron daemon will be unable to actually execute any scheduled jobs because of the NOEXEC: restriction.



NOEXEC: exists so that the sysadmin can apply it to carefully selected programs that are found to be able to perform their task without exec()ing any sub-processes. Applying it blindly to everything is going to cause problems.




But if you absolutely must, here's how.



From the sudoers(5) man page:



User specification
User_Spec ::= User_List Host_List '=' Cmnd_Spec_List
(':' Host_List '=' Cmnd_Spec_List)*

Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec ',' Cmnd_Spec_List

Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd

Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'

SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')

Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')


This is a detailed description on how to construct a user specification line for the sudoers file. It may be a little tedious to read, but it does hold the information you need.



Let's work it out using your example line:



sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


The entire line is known as the user specification, or User_Spec.



It breaks down as follows:




  • User_List has just one user in your example: sudo-user


  • Host_List has just one entry, ALL


  • Cmnd_Spec_List in your example is (ALL) NOEXEC: NOPASSWD: ALL

  • there are no further : Host_List = Cmnd_Spec_List units on this line (the asterisk after parentheses suggests there might be zero or more additional units like this.)

Your Cmnd_Spec_List has no commas, so it has just one Cmnd_Spec.



Cmnd_Spec breaks down into:



  • optional Runas_Spec: in your case, (ALL)

  • optional SELinux_Spec, which does not exist in your example

  • zero or more Tag_Specs, which is the part you want to know about


  • Cmnd, the command, which is ALL in your case.

And a single Tag_Spec is just one of the listed keywords with a colon at the end, with no comma, space or other delimiter explicitly listed. The Cmnd_Spec ::= line tells us exactly where to put spaces on that line. Since there is no instruction to put spaces or any other delimiters between tags, don't do that.



So, just put the tags one after the other, like this:



sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL





share|improve this answer




















  • I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
    – Graham Nicholls
    10 mins ago

















up vote
3
down vote













You don't need a tag for this, as noexec is also a boolean flag to the Default entry line:




noexec



If set, all commands run via sudo will behave as if the
NOEXEC tag has been set, unless overridden by a EXEC
tag. See the description of NOEXEC and EXEC below as
well as the Preventing shell escapes section at the end
of this manual. This flag is off by default.




So all you need is



Defaults noexec


This will have the same problems that telcoM notes in their answer
. It will prevent visudo from running (as that needs to start a separate editor process), so it will be harder to undo the change afterwards.






share|improve this answer




















    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: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    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%2f473950%2fsudo-disallow-shell-escapes-as-a-default%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    6
    down vote













    Don't do this.



    You're giving the sudo-user the ability to run any commands as any user. That includes the ability to modify /etc/sudoers using any tool that does not require executing sub-processes. You may be thinking that excludes visudo, but strictly speaking, you don't need visudo to edit /etc/sudoers.



    Like, for example:



    sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers


    ...and the user has just removed the NOEXEC: restriction.



    A restriction that the user can remove at will is not a true restriction.




    Also, NOEXEC: may cause problems. It does not just prevent shell escapes: it prevents the program executed with sudo from directly starting any other programs. This can have a lot of consequences.



    For example, if your sudo-user stops and later restarts the cron daemon (e.g. to stop scheduled jobs for the duration of some maintenance), the restarted cron daemon will be unable to actually execute any scheduled jobs because of the NOEXEC: restriction.



    NOEXEC: exists so that the sysadmin can apply it to carefully selected programs that are found to be able to perform their task without exec()ing any sub-processes. Applying it blindly to everything is going to cause problems.




    But if you absolutely must, here's how.



    From the sudoers(5) man page:



    User specification
    User_Spec ::= User_List Host_List '=' Cmnd_Spec_List
    (':' Host_List '=' Cmnd_Spec_List)*

    Cmnd_Spec_List ::= Cmnd_Spec |
    Cmnd_Spec ',' Cmnd_Spec_List

    Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd

    Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'

    SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')

    Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
    'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
    'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
    'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')


    This is a detailed description on how to construct a user specification line for the sudoers file. It may be a little tedious to read, but it does hold the information you need.



    Let's work it out using your example line:



    sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


    The entire line is known as the user specification, or User_Spec.



    It breaks down as follows:




    • User_List has just one user in your example: sudo-user


    • Host_List has just one entry, ALL


    • Cmnd_Spec_List in your example is (ALL) NOEXEC: NOPASSWD: ALL

    • there are no further : Host_List = Cmnd_Spec_List units on this line (the asterisk after parentheses suggests there might be zero or more additional units like this.)

    Your Cmnd_Spec_List has no commas, so it has just one Cmnd_Spec.



    Cmnd_Spec breaks down into:



    • optional Runas_Spec: in your case, (ALL)

    • optional SELinux_Spec, which does not exist in your example

    • zero or more Tag_Specs, which is the part you want to know about


    • Cmnd, the command, which is ALL in your case.

    And a single Tag_Spec is just one of the listed keywords with a colon at the end, with no comma, space or other delimiter explicitly listed. The Cmnd_Spec ::= line tells us exactly where to put spaces on that line. Since there is no instruction to put spaces or any other delimiters between tags, don't do that.



    So, just put the tags one after the other, like this:



    sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL





    share|improve this answer




















    • I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
      – Graham Nicholls
      10 mins ago














    up vote
    6
    down vote













    Don't do this.



    You're giving the sudo-user the ability to run any commands as any user. That includes the ability to modify /etc/sudoers using any tool that does not require executing sub-processes. You may be thinking that excludes visudo, but strictly speaking, you don't need visudo to edit /etc/sudoers.



    Like, for example:



    sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers


    ...and the user has just removed the NOEXEC: restriction.



    A restriction that the user can remove at will is not a true restriction.




    Also, NOEXEC: may cause problems. It does not just prevent shell escapes: it prevents the program executed with sudo from directly starting any other programs. This can have a lot of consequences.



    For example, if your sudo-user stops and later restarts the cron daemon (e.g. to stop scheduled jobs for the duration of some maintenance), the restarted cron daemon will be unable to actually execute any scheduled jobs because of the NOEXEC: restriction.



    NOEXEC: exists so that the sysadmin can apply it to carefully selected programs that are found to be able to perform their task without exec()ing any sub-processes. Applying it blindly to everything is going to cause problems.




    But if you absolutely must, here's how.



    From the sudoers(5) man page:



    User specification
    User_Spec ::= User_List Host_List '=' Cmnd_Spec_List
    (':' Host_List '=' Cmnd_Spec_List)*

    Cmnd_Spec_List ::= Cmnd_Spec |
    Cmnd_Spec ',' Cmnd_Spec_List

    Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd

    Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'

    SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')

    Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
    'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
    'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
    'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')


    This is a detailed description on how to construct a user specification line for the sudoers file. It may be a little tedious to read, but it does hold the information you need.



    Let's work it out using your example line:



    sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


    The entire line is known as the user specification, or User_Spec.



    It breaks down as follows:




    • User_List has just one user in your example: sudo-user


    • Host_List has just one entry, ALL


    • Cmnd_Spec_List in your example is (ALL) NOEXEC: NOPASSWD: ALL

    • there are no further : Host_List = Cmnd_Spec_List units on this line (the asterisk after parentheses suggests there might be zero or more additional units like this.)

    Your Cmnd_Spec_List has no commas, so it has just one Cmnd_Spec.



    Cmnd_Spec breaks down into:



    • optional Runas_Spec: in your case, (ALL)

    • optional SELinux_Spec, which does not exist in your example

    • zero or more Tag_Specs, which is the part you want to know about


    • Cmnd, the command, which is ALL in your case.

    And a single Tag_Spec is just one of the listed keywords with a colon at the end, with no comma, space or other delimiter explicitly listed. The Cmnd_Spec ::= line tells us exactly where to put spaces on that line. Since there is no instruction to put spaces or any other delimiters between tags, don't do that.



    So, just put the tags one after the other, like this:



    sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL





    share|improve this answer




















    • I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
      – Graham Nicholls
      10 mins ago












    up vote
    6
    down vote










    up vote
    6
    down vote









    Don't do this.



    You're giving the sudo-user the ability to run any commands as any user. That includes the ability to modify /etc/sudoers using any tool that does not require executing sub-processes. You may be thinking that excludes visudo, but strictly speaking, you don't need visudo to edit /etc/sudoers.



    Like, for example:



    sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers


    ...and the user has just removed the NOEXEC: restriction.



    A restriction that the user can remove at will is not a true restriction.




    Also, NOEXEC: may cause problems. It does not just prevent shell escapes: it prevents the program executed with sudo from directly starting any other programs. This can have a lot of consequences.



    For example, if your sudo-user stops and later restarts the cron daemon (e.g. to stop scheduled jobs for the duration of some maintenance), the restarted cron daemon will be unable to actually execute any scheduled jobs because of the NOEXEC: restriction.



    NOEXEC: exists so that the sysadmin can apply it to carefully selected programs that are found to be able to perform their task without exec()ing any sub-processes. Applying it blindly to everything is going to cause problems.




    But if you absolutely must, here's how.



    From the sudoers(5) man page:



    User specification
    User_Spec ::= User_List Host_List '=' Cmnd_Spec_List
    (':' Host_List '=' Cmnd_Spec_List)*

    Cmnd_Spec_List ::= Cmnd_Spec |
    Cmnd_Spec ',' Cmnd_Spec_List

    Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd

    Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'

    SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')

    Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
    'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
    'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
    'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')


    This is a detailed description on how to construct a user specification line for the sudoers file. It may be a little tedious to read, but it does hold the information you need.



    Let's work it out using your example line:



    sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


    The entire line is known as the user specification, or User_Spec.



    It breaks down as follows:




    • User_List has just one user in your example: sudo-user


    • Host_List has just one entry, ALL


    • Cmnd_Spec_List in your example is (ALL) NOEXEC: NOPASSWD: ALL

    • there are no further : Host_List = Cmnd_Spec_List units on this line (the asterisk after parentheses suggests there might be zero or more additional units like this.)

    Your Cmnd_Spec_List has no commas, so it has just one Cmnd_Spec.



    Cmnd_Spec breaks down into:



    • optional Runas_Spec: in your case, (ALL)

    • optional SELinux_Spec, which does not exist in your example

    • zero or more Tag_Specs, which is the part you want to know about


    • Cmnd, the command, which is ALL in your case.

    And a single Tag_Spec is just one of the listed keywords with a colon at the end, with no comma, space or other delimiter explicitly listed. The Cmnd_Spec ::= line tells us exactly where to put spaces on that line. Since there is no instruction to put spaces or any other delimiters between tags, don't do that.



    So, just put the tags one after the other, like this:



    sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL





    share|improve this answer












    Don't do this.



    You're giving the sudo-user the ability to run any commands as any user. That includes the ability to modify /etc/sudoers using any tool that does not require executing sub-processes. You may be thinking that excludes visudo, but strictly speaking, you don't need visudo to edit /etc/sudoers.



    Like, for example:



    sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers


    ...and the user has just removed the NOEXEC: restriction.



    A restriction that the user can remove at will is not a true restriction.




    Also, NOEXEC: may cause problems. It does not just prevent shell escapes: it prevents the program executed with sudo from directly starting any other programs. This can have a lot of consequences.



    For example, if your sudo-user stops and later restarts the cron daemon (e.g. to stop scheduled jobs for the duration of some maintenance), the restarted cron daemon will be unable to actually execute any scheduled jobs because of the NOEXEC: restriction.



    NOEXEC: exists so that the sysadmin can apply it to carefully selected programs that are found to be able to perform their task without exec()ing any sub-processes. Applying it blindly to everything is going to cause problems.




    But if you absolutely must, here's how.



    From the sudoers(5) man page:



    User specification
    User_Spec ::= User_List Host_List '=' Cmnd_Spec_List
    (':' Host_List '=' Cmnd_Spec_List)*

    Cmnd_Spec_List ::= Cmnd_Spec |
    Cmnd_Spec ',' Cmnd_Spec_List

    Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd

    Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'

    SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')

    Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
    'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
    'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
    'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')


    This is a detailed description on how to construct a user specification line for the sudoers file. It may be a little tedious to read, but it does hold the information you need.



    Let's work it out using your example line:



    sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL


    The entire line is known as the user specification, or User_Spec.



    It breaks down as follows:




    • User_List has just one user in your example: sudo-user


    • Host_List has just one entry, ALL


    • Cmnd_Spec_List in your example is (ALL) NOEXEC: NOPASSWD: ALL

    • there are no further : Host_List = Cmnd_Spec_List units on this line (the asterisk after parentheses suggests there might be zero or more additional units like this.)

    Your Cmnd_Spec_List has no commas, so it has just one Cmnd_Spec.



    Cmnd_Spec breaks down into:



    • optional Runas_Spec: in your case, (ALL)

    • optional SELinux_Spec, which does not exist in your example

    • zero or more Tag_Specs, which is the part you want to know about


    • Cmnd, the command, which is ALL in your case.

    And a single Tag_Spec is just one of the listed keywords with a colon at the end, with no comma, space or other delimiter explicitly listed. The Cmnd_Spec ::= line tells us exactly where to put spaces on that line. Since there is no instruction to put spaces or any other delimiters between tags, don't do that.



    So, just put the tags one after the other, like this:



    sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 47 mins ago









    telcoM

    12.3k11435




    12.3k11435











    • I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
      – Graham Nicholls
      10 mins ago
















    • I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
      – Graham Nicholls
      10 mins ago















    I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
    – Graham Nicholls
    10 mins ago




    I was kind of hoping to avoid the "Don't do this" responses with the "this is an example" text, but I guess it was always inevitable. Nevertheless, thank you for the rest of the post which is very informative. I tried putting the two tags together, but the second was interpreted as a command alias. I notice that you have no space between the two, which was, I suspect my problem. Anyway, I upvoted you and thanks again. What's your take on @Ruis' comment, which was the conclusion I was coming to?
    – Graham Nicholls
    10 mins ago












    up vote
    3
    down vote













    You don't need a tag for this, as noexec is also a boolean flag to the Default entry line:




    noexec



    If set, all commands run via sudo will behave as if the
    NOEXEC tag has been set, unless overridden by a EXEC
    tag. See the description of NOEXEC and EXEC below as
    well as the Preventing shell escapes section at the end
    of this manual. This flag is off by default.




    So all you need is



    Defaults noexec


    This will have the same problems that telcoM notes in their answer
    . It will prevent visudo from running (as that needs to start a separate editor process), so it will be harder to undo the change afterwards.






    share|improve this answer
























      up vote
      3
      down vote













      You don't need a tag for this, as noexec is also a boolean flag to the Default entry line:




      noexec



      If set, all commands run via sudo will behave as if the
      NOEXEC tag has been set, unless overridden by a EXEC
      tag. See the description of NOEXEC and EXEC below as
      well as the Preventing shell escapes section at the end
      of this manual. This flag is off by default.




      So all you need is



      Defaults noexec


      This will have the same problems that telcoM notes in their answer
      . It will prevent visudo from running (as that needs to start a separate editor process), so it will be harder to undo the change afterwards.






      share|improve this answer






















        up vote
        3
        down vote










        up vote
        3
        down vote









        You don't need a tag for this, as noexec is also a boolean flag to the Default entry line:




        noexec



        If set, all commands run via sudo will behave as if the
        NOEXEC tag has been set, unless overridden by a EXEC
        tag. See the description of NOEXEC and EXEC below as
        well as the Preventing shell escapes section at the end
        of this manual. This flag is off by default.




        So all you need is



        Defaults noexec


        This will have the same problems that telcoM notes in their answer
        . It will prevent visudo from running (as that needs to start a separate editor process), so it will be harder to undo the change afterwards.






        share|improve this answer












        You don't need a tag for this, as noexec is also a boolean flag to the Default entry line:




        noexec



        If set, all commands run via sudo will behave as if the
        NOEXEC tag has been set, unless overridden by a EXEC
        tag. See the description of NOEXEC and EXEC below as
        well as the Preventing shell escapes section at the end
        of this manual. This flag is off by default.




        So all you need is



        Defaults noexec


        This will have the same problems that telcoM notes in their answer
        . It will prevent visudo from running (as that needs to start a separate editor process), so it will be harder to undo the change afterwards.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 26 mins ago









        JigglyNaga

        3,092626




        3,092626



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f473950%2fsudo-disallow-shell-escapes-as-a-default%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            List of Gilmore Girls characters

            Confectionery