Ejecución de trabajos iniciales como usuarios sin privilegios

142

¿Cuál es la forma canónica de hacer que un trabajo inicial cambie su ID de usuario y ejecute el script como un usuario sin privilegios?

Obviamente uno puede usar suo sudo, pero esto parece hacky (y puede generar líneas de registro innecesarias).

aaronsw
fuente

Respuestas:

108

Con la versión inicial 1.4, setuid y setgid son compatibles de forma nativa en el archivo de configuración.

qsun
fuente
77
Consulte el libro de cocina para obtener información específica sobre esto: upstart.ubuntu.com/cookbook/#run-a-job-as-a-different-user
Jason Navarrete
10
En otras palabras, es compatible con Precise (12.04) y posteriores.
Edward Anderson el
8
En otras palabras, no se admite en centos 6
socketpair
55
Para el registro, initctl --versionpara encontrar su versión actual de advenedizo.
Mahn
44
Molesto, la distribución de Amazon Linux en AWS usa la versión nueva de RHEL 6 (0.6.5 !!!!) por lo que cualquiera que use eso tendrá que usar la solución 'su'.
Asfand Qazi
86

Al preguntar sobre el canal #upstart en freenode, la opinión oficial sobre el asunto es:

Una versión futura de Upstart tendrá soporte nativo para eso, pero por ahora, puede usar algo como:

exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]
Roman Gaufman
fuente
77
Esta es la única respuesta que funcionó en Amazon Linue EC2 (probé todas las variaciones de sudo y su, incluyendo --session-command, -c, ad nauseum); ninguno de ellos permitió que el proceso se detuviera una vez iniciado; Muchas gracias por esto.
Kato
Esa es una magia de concha elegante, +1.
Steve Kehlet
66
Esto no funcionó para mí en CentOS 6 (Upstart 0.6.5). Hay una serie de horquillas (4 profundas, creo) iniciadas por suese medio expect forke incluso expect daemonno atrapan el PID final.
Mark Lakata
2
Utilicé esto en Amazon Linux (Upstart 0.6.5) para arrancar un proceso de Jenkins (que afortunadamente no se demoniza), ¡y funcionó! Tuve que cambiarlo un poco para redirigir la salida estándar a un archivo de registro y establecer algunas variables de entorno, ¡pero funcionó! Mi versión se ve así:exec su -s /bin/sh -c 'HOME=/foo/bar exec "$0" "$@" &>/var/log/foobar.log' username -- /path/to/command [parameters...]
Asfand Qazi
17

¿Qué tal usar start-stop-daemon?

exec start-stop-daemon --start --chuid daemonuser --exec /bin/server_cmd

Del libro de cocina Upstart :

El método recomendado para los sistemas Debian y Ubuntu es utilizar la utilidad auxiliar start-stop-daemon. [...] start-stop-daemonno impone límites PAM ("Módulo de autenticación enchufable") al proceso que inicia.

Nota: start-stop-daemonno admitido en RHEL.

Jason R. Coombs
fuente
2
También puede usar el grupo, si lo necesita. Con --chuid daemonuser: daemongroup
Evgeny
13

Hay varias formas de hacerlo, todas con una semántica ligeramente diferente, particularmente en relación con la pertenencia a grupos:

  • setuidgid te colocará en el grupo que especifiques.

    • Las herramientas daemontools originales setuidgidlo pondrán solo en ese grupo, por lo que no podrá acceder a los archivos que pertenecen a otros grupos de los que es miembro.
    • El setuidgidde daemontools-bis y la setuidgiddel conjunto de herramientas nosh ambos tienen una -s(también conocido como --supplementaryopción), que le pondrá en ese grupo, y también le puso en todos los grupos suplementarios para el usuario que especifique.
  • Usando newgrpuna vez que te has convertido en el usuario menos privilegiado añadirá un solo grupo a su groupset, sino que también crea una nueva subcapa, por lo que es difícil de usar dentro de las secuencias de comandos.

  • start-stop-daemon preserva la membresía de su grupo y hace mucho más que solo setuid / setgid.

  • chpst -u username:group1:group2:group3... commandnamele permitirá especificar exactamente qué membresías de grupo adoptar, pero (en Ubuntu ) solo viene con el runitpaquete, que es una alternativa a upstart.

  • su -c commandname usernamerecoge todas las membresías de grupos de nombre de usuario, como lo hace sudo -u username commandname, por lo que probablemente sean la ruta para menos asombro.

Jason Holt
fuente
8

Uso setuidgiddel paquete daemontools.

Documentación aquí: http://cr.yp.to/daemontools/setuidgid.html

aaronsw
fuente
77
daemontools no es un requisito previo para el advenedizo, por lo que esta no parece ser la respuesta 'canónica'
Adam Nelson el
2
Además, daemontools está en el universo (ubuntu 10.04) y el sistema de arranque está en main.
jtimberman
4

En una instancia de Ubuntu 10.10 en Amazon EC2, tuve mejor suerte con el start-stop-daemoncomando.

También luché con algunas de las otras estrofas advenedizas . Estoy llamando a una aplicación python con un virtualenvparámetro específico y algunos para mi programa ejecutado.

Lo siguiente es lo que funcionó para mí.

script
  export PYTHONPATH=.:/home/ubuntu/.local/lib/python2.7/site-packages/:/home/ubuntu/python/lib/python2.7/site-packages/
  exec start-stop-daemon --start  --chuid ubuntu --exec /home/ubuntu/python_envs/MyProj/bin/python /home/ubuntu/www/MyProj/MyProj.py -- --config-file-dir=/home/ubuntu/www/MyProj/config/ >> /home/ubuntu/startup.log 2>&1 &
end script

El PYTHONPATHobjetivo es instalar algunos paquetes desde el origen en la ruta del módulo PYTHON cuando se ejecuta este trabajo inicial. Tenía que hacer todo en caminos absolutos porque la chdirestrofa no parecía funcionar.

Jesse Smith
fuente
También he tenido problemas con las variables env utilizadas con exec start-stop-daemon .
Thomas Bratt
3

Estaba usando CentOS 6, y no pude conseguir que el truco recomendado (para Upstart 0.6.5) funcionara para mí, ni el truco 'su' porque la cantidad de horquillas involucradas (4 creo) no fue rastreada por 'fork esperada 'o' esperar demonio '.

Finalmente acabo de hacer

chown user:group executable
chmod +s executable

(es decir, establecer el bit setuid y cambiar la propiedad).

Puede que no sea el método más seguro, pero para un proyecto interno de I + D, en nuestro caso no importó.

Mark Lakata
fuente
Si tuviera que hacer una chmod 1700o al menos una chmod u+sx,go-xallí en lugar de solo +s, calificaría como "lo suficientemente seguro". :)
dannysauer
0

Hay una tercera posibilidad dependiendo de lo que intente lograr. Es posible que pueda aflojar los controles de acceso en los archivos / dispositivos en cuestión . Esto puede permitir que un usuario sin privilegios monte o acceda a elementos que normalmente no se les permitiría. Solo asegúrate de no estar regalando las llaves del reino en el proceso.

También puede cambiar el tiempo de espera de la caché de contraseñas sudo . Pero no lo recomiendo a menos que su máquina sea físicamente segura (es decir, cree que es poco probable que un transeúnte intente obtener acceso a sudo).

Hay una buena razón por la que hay muy pocas formas de realizar acciones privilegiadas y que realizan registros innecesarios y necesarios . Las restricciones flojas serían un peligro para la seguridad de su sistema, y ​​la falta de registro significaría que no hay forma de saber qué sucedió cuando se vio comprometido.

Si el tamaño de sus archivos de registro es una preocupación, entonces probablemente algo esté mal. Sudo genera solo una línea por uso en condiciones normales.

Chris Nava
fuente
0

En CentOS 6, upstart 0.6.5, lo siguiente es lo que funcionó para mí.

script

    exec su user_name << EOF
        exec /path/to/command [parameters...]
EOF

end script

o:

script

    exec su user_name << EOF
       ..... what you want to do ....
EOF

end script

Cuando uso

exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]

No se puede detener el proceso de trabajo initclt stop. Creo que la razón es:

1. the job forked and the main process is not tracked.
2. the main process changed its process group,because of `su -c`
hxysayhi
fuente