zoukankan      html  css  js  c++  java
  • 每天学五分钟 Liunx 011 | sudo


    回顾前两节,在 001 中介绍了怎么添加用户及用户组,在 010 中介绍了从 client 端 ssh 到 server 的详细过程,那么接下来要介绍的就是是登陆到 server 之后如何切换用户了。
    留一道真题: server 中有三个用户 lianhua,huasheng 和 lianhuasheng。lianhua 想把自己提权成 root,它自己没有权限去改 root 的文件,不过 huasheng 可以执行一些属于 root 的命令,试问这时候要怎么做才能让 lianhua 提权到 root?
     
    su 
    提权到 root 有两种方式,第一种就是 su 了,查看 su 的解释:
    [root@controller-0 sudoers.d]# su --help
    Usage:
    su [options] [-] [USER [arg]...]
     
    Change the effective user id and group id to that of USER.
    A mere - implies -l.   If USER not given, assume root.
     
    Options:
    -m, -p, --preserve-environment  do not reset environment variables
    -g, --group <group>             specify the primary group
    -G, --supp-group <group>        specify a supplemental group
     
    -, -l, --login                  make the shell a login shell
    -c, --command <command>         pass a single command to the shell with -c
    --session-command <command>     pass a single command to the shell with -c
                                     and do not create a new session
    -f, --fast                      pass -f to the shell (for csh or tcsh)
    -s, --shell <shell>             run shell if /etc/shells allows it
     
    -h, --help     display this help and exit
    -V, --version  output version information and exit
     
    通过 su 加指定 user 的方式将当前用户提权到指定用户(一般是 root)。su 提示输的密码是要提权用户的密码:
    [lianhua@***n ~]$ su - root
    Password:
    Last login: Sat Mar  7 17:55:48 CST 2020 on pts/0
    [root@*** ~]# env
    XDG_SESSION_ID=5763
    HOSTNAME=***
    SHELL=/bin/bash
    TERM=xterm
    HISTSIZE=1000
    http_proxy=http://10.110.***.***
    USER=root
    LS_COLORS=36:*.xspf=01;36:
    MAIL=/var/spool/mail/root
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
    PWD=/root
    LANG=en_US.UTF-8
    HISTCONTROL=ignoredups
    SHLVL=1
    HOME=/root
    LOGNAME=root
    LESSOPEN=||/usr/bin/lesspipe.sh %s
    _=/bin/env

     

    之所以登陆之后要 show 环境变量 env 的原因是因为加了 - 的提权方式是 login shell 的,也就是提权到指定用户之后环境变量都会变成指定用户的环境变量,如果不用 - 的话,会出现这样的情况:
    [lianhua@*** ~]$ su root
    Password:
    [root@*** ~]# env
    XDG_SESSION_ID=5763
    HOSTNAME=***
    TERM=xterm
    SHELL=/bin/bash
    HISTSIZE=1000
    USER=lianhua
    http_proxy=http://10.110.***.***
    LS_COLORS=36:*.xspf=01;36:
    PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lianhua/.local/bin:/home/lianhua/bin
    MAIL=/var/spool/mail/lianhua
    PWD=/home/lianhua
    LANG=en_US.UTF-8
    HISTCONTROL=ignoredups
    HOME=/root
    SHLVL=2
    LOGNAME=lianhua
    LESSOPEN=||/usr/bin/lesspipe.sh %s
    _=/bin/env

     

    可以看到虽然提前到 root 了,但是环境变量还是 huasheng 的,这也意味着要使用一些 root 用户才能用的命令需要使用绝对路径来指定该命令,相当麻烦!
     
    虽然 su 可以提权到 root , 但是通过 su 提权需要知道 root 的密码,如果用户多的话,很容易泄露 root 账号的密码,这是很危险的。针对这种情况,一个更安全的提权方式 sudo 就派上用场了。
     
     
    sudo
     
    sudo 可以让非 root 用户在不需要知道 root 用户密码的情况下,提权到 root 执行 root 用户才能执行的命令。
     
    查看 sudo 选项:
    Options:
      -A, --askpass                 use a helper program for password prompting
      -b, --background              run command in the background
      -C, --close-from=num          close all file descriptors >= num
      -E, --preserve-env            preserve user environment when running command
          --preserve-env=list       preserve specific environment variables
      -e, --edit                    edit files instead of running a command
      -g, --group=group             run command as the specified group name or ID
      -H, --set-home                set HOME variable to target user's home dir
      -h, --help                    display help message and exit
      -h, --host=host               run command on host (if supported by plugin)
      -i, --login                   run login shell as the target user; a command may also be specified
      -K, --remove-timestamp        remove timestamp file completely
      -k, --reset-timestamp         invalidate timestamp file
      -l, --list                    list user's privileges or check a specific command; use twice for longer format
      -n, --non-interactive         non-interactive mode, no prompts are used
      -P, --preserve-groups         preserve group vector instead of setting to target's
      -p, --prompt=prompt           use the specified password prompt
      -r, --role=role               create SELinux security context with specified role
      -S, --stdin                   read password from standard input
      -s, --shell                   run shell as the target user; a command may also be specified
      -t, --type=type               create SELinux security context with specified type
      -T, --command-timeout=timeout terminate command after the specified time limit
      -U, --other-user=user         in list mode, display privileges for user
      -u, --user=user               run command (or edit file) as specified user name or ID
      -V, --version                 display version information and exit
      -v, --validate                update user's timestamp without running a command
      --                            stop processing command line arguments
     
    可以通过 sudo -u <user> <command> 的方式来指定要提权的 user 所执行的 command,如果不指定 user 的话默认提权到 root。
     
    对 lianhua 进行提权执行 passwd 命令:
    [lianhua@*** ~]$ sudo passwd
    [sudo] password for lianhua:
    Sorry, user lianhua is not allowed to execute '/bin/passwd' as root on controller-0-forestgreen.

     

    与 su 提权输入密码不一样的是:这里 sudo 需要输入的密码是 lianhua 密码,这点要注意。
    那么问题来了,为什么 lianhua 不能执行 passwd 命令呢?
    原因在于文件 /etc/sudoers 需要修改相应的配置才能让 lianhua 执行 passwd。
     
    通过 visudo 工具查看 /etc/sudoers ,这个工具会检查 /etc/sudoers 有没有修改,修改的格式对不对。
    [root@test ~]visudo
    ...
    root ALL=(ALL) ALL
    ...

     

    主要参数是 root ALL=(ALL) ALL 这一项,列出来单独讨论。
     
    每项表示的意义是:
    用户账号   登陆者的来源主机名=[可切换的身份] 可执行的命令
    root       ALL       = (ALL)      ALL
     
    用户账号: 要使用 sudo 命令的账号;
    登陆者的来源主机名: 表示允许登陆的主机,如果不为 ALL 则表示授权用户只能在指定主机上登陆 server 执行 sudo 命令。
    可切换的身份: 当前用户可以这个身份来执行后面的命令,默认提权到 root。
    可执行的命令: 切换的身份可以执行的命令,这个命令是绝对路径,不能用相对路径!试想如果一个用户造了一个命令也叫 passwd,如果执行命令用相对路径,用户执行 passwd 的话执行到这个造出来的 passwd 命令,那是相当危险的!
     
    查看 huasheng 这个用户在 /etc/sudoers 里的配置:
    [root@*** ~]visudo
    ...
    huasheng ALL=(ALL) NOPASSWD:/usr/sbin/visudo
    ...
    与前面有一点点不一样的是,huasheng 多了一个 NOPASSWD 字段,这是因为使用 sudo 提权执行命令的时候会提示输入当前用户的密码,很麻烦,所以管理员也就是我给它加了个 NOPASSWD 字段,这样就不用每次输密码了。
     
    好了,那我们好好玩一玩 huasheng,首先把登陆者的来源主机名改掉,改成 hostname 对应的 ip,然后把这个 ip 加到 huasheng 的登陆者来源主机名中:
    [root@*** ~]# hostname
    test
    [root@*** ~]# hostname -I
    10.57.0.1
    [root@*** ~]# visudo
    ...
    huasheng 10.57.0.1=(ALL) NOPASSWD:/usr/sbin/visudo
    ...
    [root@*** ~]# su - huasheng
    Last login: Sat Mar  7 16:06:10 CST 2020 on pts/0
    [huasheng@*** ~]$ sudo visudo
    visudo: /etc/sudoers.tmp unchanged
    <关于 hostname 详解可看这里>
     
    把这个 ip 改成其它主机的 ip 看看能不能执行 visudo:
    [huasheng@*** ~]# visudo
    ...
    huasheng 10.57.1.1=(ALL) NOPASSWD:/usr/sbin/visudo
    ...
    [huasheng@*** ~]$ sudo visudo
    [sudo] password for huasheng:
    huasheng is not allowed to run sudo on test.  This incident will be reported.
    提示 hausheng 不能在当前主机 test 上执行这个 visudo 命令!
     
    把 ip 改回来,把 huasheng 的可切换身份改为 lianhua 执行 visudo 看看:
    [root@test ~]# visudo
    [root@test ~]# su - huasheng
    Last login: Sat Mar  7 19:27:29 CST 2020 on pts/0
    [huasheng@test ~]$ sudo visudo
    [sudo] password for huasheng:
    Sorry, user huasheng is not allowed to execute '/sbin/visudo' as root on test.
    提示的很明显,huasheng 没有提权到 root,所以不能执行 visudo 命令!
     
     
    真题演练
    折腾半天 huasheng 了,也得看看 lianhua 咋滴了,他还是没法提权切不了 root 。再回看开头的问题,结合前面的分析应该知道怎么提权了,直接给答案:
    [lianhua@test ~]$ su - huasheng
    Password:
    Last login: Sat Mar  7 19:52:44 CST 2020 on pts/0
    [huasheng@test ~]$ which su
    /bin/su
    [huasheng@controller-0-forestgreen ~]$ sudo visudo
    ...
    lianhua ALL=(ALL) NOPASSWD: /bin/su
    ...
     
    [huasheng@test ~]$ exit
    logout
    [lianhua@test ~]$ sudo su
    [root@test lianhua]# 
     
    题目还有个用户 lianhuasheng ,看看他的配置:
    [root@test lianhua]# visudo
    ...
    lianhuasheng ALL=(ALL) NOPASSWD: /bin/su
    ...

     

    他的配置和 hausheng / lianhua 一样,那么把他们三个加到一个组,起名叫 ADMINGROUP ,这个组里的用户可以提权到 root。但是要给他们设置不能执行 passwd 和 passwd root 命令,不然他们就能把原来的 root 密码给改掉了,这样是很危险的! 
    在 /etc/sudoers 中,组的配置是在组名前加 % 号表示,同时禁用某个命令是在命令前加 ! 号,* 号作为通配符表示可以执行目录下一系列命令。
    [root@test lianhua]# groupadd ADMINGROUP
    [root@test lianhua]# visudo
    ...
    %ADMINGROUP ALL=(ALL) NOPASSWD: /bin/su, !/bin/passwd, !/bin/passwd root
    ...
    [root@test lianhua]# usermod -G ADMINGROUP lianhua
    [root@test lianhua]# usermod -G ADMINGROUP huasheng
    [root@test lianhua]# usermod -G ADMINGROUP lianhuasheng
    [root@test lianhua]# su - lianhua
    Last login: Sat Mar  7 19:56:00 CST 2020 on pts/0
    [lianhua@test ~]$ sudo su
    [root@test lianhua]#
     
     
    现在我们改提权的方式都是直接改的 /etc/sudoers 文件,但是系统推荐的更好的方式是在 /etc/sudoers.d/ 目录下新建配置的用户。/etc/sudoers 文件默认已经配置了该目录:
    [root@test ~]# cat /etc/sudoers | grep sudoers.d
    ## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
    #includedir /etc/sudoers.d

     

    再把 ADMINGROUP 移到 /etc/sudoers.d 目录下,重新配置这三个用户:
    [root@test lianhua]# cd /etc/sudoers.d/
    [root@test sudoers.d]# vi ADMINGROUP
    %ADMINGROUP ALL=(ALL) NOPASSWD: /bin/su
    [root@test sudoers.d]# visudo
    [root@test sudoers.d]# su - lianhua
    Last login: Sat Mar  7 20:17:35 CST 2020 on pts/0
    [lianhua@test ~]$ sudo su
    [root@test lianhua]#
     
     
    (完)
  • 相关阅读:
    python mymsql sqlalchemy
    python中 wraps 的作用
    python Subprocess的使用
    实现一个命令分发器
    实现一个cache装饰器,实现过期可清除功能
    求2个字符串的最长公共子串
    Base64编码,解码的实现
    把一个字典扁平化
    hihocoder1415 重复旋律3
    hihocoder 1407 重复旋律2
  • 原文地址:https://www.cnblogs.com/xingzheanan/p/12436943.html
Copyright © 2011-2022 走看看