welcome: please sign in

Diff for "MemberManual/RunningUnattendedCommands"

Differences between revisions 7 and 78 (spanning 71 versions)
Revision 7 as of 2007-10-27 22:59:27
Size: 8900
Editor: DavorOcelic
Comment:
Revision 78 as of 2023-04-05 15:42:46
Size: 11405
Editor: 128
Comment: add recursive fs sa
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
This is the chapter of the MemberManual that describes how to periodically run unattended commands using cron. This is the chapter of the MemberManual that describes how to periodically run unattended commands, either as long-running processes (daemons) or as short periodic tasks from cron or at.
Line 5: Line 5:
[[TableOfContents]] {{{#!wiki caution
'''This manual page needs major revision.''' Issues include
 * Outright misleading information regarding PAGs (`pagsh` is almost never helpful!)
 * Unnecessary detail. Folks who want to know about TGTs and PAGs can read the relevant external documentation. At least use hypertext to clarify concepts instead of just expanding acronyms.
 * Essential information is on other pages: e.g. RunningUnattendedCommandsWithoutRunInPagsh.
   * `run-in-pagsh` might work, but is at best not encouraged or supported so it should be moved off to another page. Justification: using `k5start` is no more challenging than configuring `run-in-pagsh`.
   * Anyone running a daemon probably needs to know about `@reboot` cron jobs without having to self-discover MemberManual/UsingCron
   * It does not stress the importance of the `-t` argument to `k5start`
}}}
Line 7: Line 15:
= Introduction = <<TableOfContents>>
Line 9: Line 17:
All users' home directories in HCoop setup are located on AFS partitions. The use of AFS implies the use of Kerberos. In essence, your Kerberos (and AFS) "identity" is completely unrelated to your Unix username. While you do automatically obtain Kerberos and AFS identity (so-called "tokens") when you log-in to HCoop machines over ssh, be aware that Unix and Kerberos/AFS login are two separate things. That's why the scripts you run unattended cannot write (or read) files because, without extra steps taken, they do not have any useful identity or access privileges to partitions where all the relevant data is residing. = Quick Example =
Line 11: Line 19:
So, in general, when you want to access AFS space (that means any file in your home directory), you first need to authenticate with Kerberos to obtain a valid TGT ("Ticket-granting ticket"). As the name implies, the TG Ticket is then used in automatically obtaining futher tickets for access to specific services (such as to ssh, ftp, bugzilla, members portal or AFS on any of the servers in the HCoop administration "realm"). In order to execute a long-running or unattended command:

 1. Ensure that any directories needed to read/write have the right permission for the ${USER}.daemon (otherwise file access will start to fail)
 2. Execute the command with `k5start` to keep the process authenticating while it runs

For the first part, replace "DIRECTORY" with the directory that the process will need to read or write from:
{{{
fs sa DIRECTORY ${USER}.daemon read
fs sa DIRECTORY ${USER}.daemon write
}}}

For the second part, replace "COMMANDHERE" with the command you wish to run:
{{{#!code
k5start -t -U -f /etc/keytabs/user.daemon/${USER} -- COMMANDHERE
}}}

= Overview =

All users' home directories in HCoop setup are located on AFS volumes. The use of AFS implies the use of Kerberos. In essence, your Kerberos (and AFS) "identity" is completely unrelated to your Unix username. While you automatically obtain Kerberos and AFS identity (so-called "tokens") when you log-in to HCoop machines over ssh, be aware that Unix and Kerberos/AFS login are two separate things. That's why the scripts you run unattended cannot write (or read) files because, without extra steps taken, they do not have any useful identity or access privileges to volumes where all the relevant data is residing.

So, in general, when you want to access AFS space (that means any file in your home directory), you first need to authenticate with Kerberos to obtain a valid TGT ("Ticket-granting ticket"). As the name implies, the TG Ticket is then used in automatically obtaining further tickets for access to your files (in AFS) or to specific services (such as to ssh, ftp, bugzilla or members portal).
Line 40: Line 68:
 1. Your USER.daemon principal has a very long random secret assigned to it and its key exported to a file named ''/etc/keytabs/user.daemon/USER''. Your scripts will use the file ''/etc/keytabs/user.daemon/USER'' as a password in obtaining Kerberos/AFS identity "USER.daemon". In fact, all shared HCoop daemons also use that file to obtain permissions to write into your home directory (such as to deliver mail).  1. Your USER.daemon principal has a very long random secret assigned to it and its key exported to a file named ''/etc/keytabs/user.daemon/USER''. Your scripts will use the file ''/etc/keytabs/user.daemon/USER'' as a password in obtaining Kerberos/AFS identity "USER.daemon". In fact, all shared HCoop daemons also use that file to obtain permissions to write into your home directory (such as to deliver mail). Of course, Unix permissions and ownership on the keytab file are such that no other user can read your keytab file.
Line 49: Line 77:
To "enter" a PAG, you start shell named '''/usr/bin/pagsh.openafs'''. With SSH, even though you find yourself in the shell of preference, a PAG is created for you just beforehand. (Verify by running '''id''' and noticing one numerical, untranslated entry such as 1105575254). Once within a PAG, there is basically no way to "escape" from it, so in effect, it is not possible to affect Kerberos/AFS identity of any of your other running processes by SSH-ing into a machine and kinitting as a different principal or obtaining different AFS tokens - they only apply to your current shell and its subprocesses. To "enter" a PAG, you start shell named '''/usr/bin/pagsh.openafs'''. With SSH, even though you find yourself in the shell of preference, a PAG is created for you just beforehand. (Verify by running '''id''' and noticing one numerical, untranslated entry such as 1105575254). Once within a PAG, there is basically no way to "escape" from it, so in effect, it is not possible to affect Kerberos/AFS identity of any of your other running processes by SSH-ing into a machine and doing `kinit` as a different principal or obtaining different AFS tokens - they only apply to your current shell and its subprocesses.
Line 61: Line 89:
In any case, using file ''/etc/keytabs/user.daemon/USER'' to obtain your Kerberos/AFS identity will "log you in" into AFS as USER.daemon, not USER. Therefore, make sure that all directories you want to access have read or write access allowed for USER.daemon in addition to USER. In any case, using file ''/etc/keytabs/user.daemon/USER'' to obtain your Kerberos/AFS identity will "log you in" into AFS as USER.daemon, not USER. Therefore, make sure that all directories you want to access from unattended scripts have read or write permission for USER.daemon in addition to USER.
Line 63: Line 91:
For example, here's how the permissions look for your ~/Maildir/ which gives USER.daemon write permissions: For example, here's how the permissions look for your ~/Maildir/ which gives USER.daemon write access:
Line 74: Line 102:
To give read permission on a directory, use '''fs sa DIRECTORY USER.daemon read'''.

To give write permission on a directory, use '''fs sa DIRECTORY USER.daemon write'''.

Note that we mention directory permissions only - in AFS, there are no file permissions. Directory permissions apply to all contained files, except subdirectories. Each subdirectory defines its own permissions. When new subdirectories are created, they inherit the ACL list from the parent directory. If you want to change ACLs on an existing directory tree, you have to do it manually and recursively with an elegant construct like this:
To give read permission on a directory, use
Line 80: Line 104:
$ find STARTING_DIRECTORY -type d -print0 | xargs -0n1 -i fs sa '{}' USER.daemon PERMISSION fs sa DIRECTORY USER.daemon read
Line 83: Line 107:
By using '''find -print0 | xargs -0''' combination, you eliminate all problems with unsafe or weird file names. To give write permission on a directory, use
{{{
fs sa DIRECTORY USER.daemon write
}}}

To recursively give write permission for all subdirectories,
{{{
find DIRECTORY -type d -exec fs sa {} ${USER}.daemon write \;
}}}


Note that we mention directory permissions only - in AFS, there are no file permissions. Directory permissions apply to all contained files, except subdirectories. Each subdirectory defines its own permissions. When new subdirectories are created, they inherit the ACL list from the parent directory. If you want to change ACLs on an existing directory tree, just use the '''fsr''' command in place of '''fs''', with the same arguments.
Line 88: Line 123:

== Example 1: unattended.sh ==

1. Create a script, ex: ''unattended.sh'', in your ~/bin that is readable by USER.daemon.

{{{#!code
#!/bin/sh
k5start -t -U -f /etc/keytabs/user.daemon/USER -- COMMANDHERE
}}}
(Replace USER with your username and COMMANDHERE with the command you want to run)

2. Edit your crontab to call the script as ''~/bin/unattended.sh''
Line 98: Line 145:
Make sure your ~/.bash_profile or equivalent file has ~/bin/ at the beginning of PATH, by enabling this within ~/.bash_profile: Make sure your {{{~/.bash_profile}}} or equivalent file has ~/bin/ at the beginning of PATH, by enabling this within {{{~/.bash_profile}}}:
Line 107: Line 154:
Create a directory that will contain PID files for all your user processes and give unauthenticated users read access to it: Create a directory that will contain PID files for all your user processes:
Line 110: Line 157:
$ mkdir ~/pidfiles/
$ fs sa ~/pidfiles system:anyuser rl
$ mkdir ~/.run
$ fs sa ~/.run system:anyuser rl
$ fs sa ~/.run USER.daemon write
Line 114: Line 162:
== Script Running a Particular Service Within Pagsh == == Script to Run a Particular Service Within Pagsh ==
Line 116: Line 164:
Here's a wrapper script to run Interchange daemon on Mire (could trivially be adjusted to any other daemon): Please be sure to also check RunningUnattendedCommandsWithoutRunInPagsh.

''Someone should write a better script that automates `k5start` and setting up an `@reboot` cron job instead of this'' -- ClintonEbadi <<DateTime(2013-07-13T06:11:39-0400)>>

A wrapper script that runs a user-specified daemon is provided on Mire as {{{run-in-pagsh}}}. When calling it, the first argument should be a unique name with no spaces that describes the daemon, and then provide the command line for calling that daemon afterwards. Be sure to follow the instructions in the previous section for creating a {{{~/.run}}} directory with correct permissions.

Here is an example of calling this script:
Line 119: Line 173:
#!/usr/bin/pagsh.openafs

# Should only have to adjust following 2 lines
K5PID=$HOME/pidfiles/k5ic.pid
CMD="$HOME/interchange/bin/interchange $*"

KTAB=/etc/keytabs/user.daemon/$USER

# Terminate current k5start process, if one is running.
test -e "$K5PID" && kill `cat -- "$K5PID"`

# Start fresh k5start daemon which will be refreshing tickets every 540 min
/usr/bin/k5start -U -b -K 540 -t -p "$K5PID" -f "$KTAB"

# Run actual service with arguments as provided on command line
$CMD
run-in-pagsh interch ~/bin/interchange
Line 137: Line 176:
Note that the PID file handling could be improved in the above script; feel welcome to do so. If you want to run a command from cron then use the following instead. The '''{{{--fg}}}''' argument tells {{{run-in-pagsh}}} that the command will run in the foreground, rather than the background.

{{{
run-in-pagsh --fg clean-mail ~/scripts/clean-mail
}}}

For the curious, the {{{run-in-pagsh}}} script may be viewed [[http://git.hcoop.net/?p=hcoop/misc.git;a=blob_plain;f=bin/run-in-pagsh;hb=HEAD|here]].
----
CategoryNeedsWork CategoryMemberManual CategoryNeedsWork

This is the chapter of the MemberManual that describes how to periodically run unattended commands, either as long-running processes (daemons) or as short periodic tasks from cron or at.

This manual page needs major revision. Issues include

  • Outright misleading information regarding PAGs (pagsh is almost never helpful!)

  • Unnecessary detail. Folks who want to know about TGTs and PAGs can read the relevant external documentation. At least use hypertext to clarify concepts instead of just expanding acronyms.
  • Essential information is on other pages: e.g. RunningUnattendedCommandsWithoutRunInPagsh.

    • run-in-pagsh might work, but is at best not encouraged or supported so it should be moved off to another page. Justification: using k5start is no more challenging than configuring run-in-pagsh.

    • Anyone running a daemon probably needs to know about @reboot cron jobs without having to self-discover MemberManual/UsingCron

    • It does not stress the importance of the -t argument to k5start

Quick Example

In order to execute a long-running or unattended command:

  1. Ensure that any directories needed to read/write have the right permission for the ${USER}.daemon (otherwise file access will start to fail)
  2. Execute the command with k5start to keep the process authenticating while it runs

For the first part, replace "DIRECTORY" with the directory that the process will need to read or write from:

fs sa DIRECTORY ${USER}.daemon read
fs sa DIRECTORY ${USER}.daemon write

For the second part, replace "COMMANDHERE" with the command you wish to run:

k5start -t -U -f /etc/keytabs/user.daemon/${USER} -- COMMANDHERE

Overview

All users' home directories in HCoop setup are located on AFS volumes. The use of AFS implies the use of Kerberos. In essence, your Kerberos (and AFS) "identity" is completely unrelated to your Unix username. While you automatically obtain Kerberos and AFS identity (so-called "tokens") when you log-in to HCoop machines over ssh, be aware that Unix and Kerberos/AFS login are two separate things. That's why the scripts you run unattended cannot write (or read) files because, without extra steps taken, they do not have any useful identity or access privileges to volumes where all the relevant data is residing.

So, in general, when you want to access AFS space (that means any file in your home directory), you first need to authenticate with Kerberos to obtain a valid TGT ("Ticket-granting ticket"). As the name implies, the TG Ticket is then used in automatically obtaining further tickets for access to your files (in AFS) or to specific services (such as to ssh, ftp, bugzilla or members portal).

The AFS "Login" Process

Following the above, here's the complete, "expanded" series of events that take place in a typical remote shell session:

  1. You log in by providing your Unix username and password
  2. You authenticate to Kerberos and obtain the TGT by running kinit. (Verify with klist -5).

  3. You use the TGT to obtain AFS "token" by running aklog. (Verify with tokens).

  4. You access files in the AFS space. Actual access privileges are determined by the combination of the token you are holding and the access control lists (ACLs) set on a directory. (List access rules with fs la DIRECTORY).

Interactive SSH process

Our SSH service is configured in such a way that your password is, in fact, the secret Kerberos key. So when you log in over SSH, steps 1 to 3 above are performed for you automatically and you can use AFS right away.

Non-interactive (Unattended) Processes

When a script is started in your Unix name by Cron, At or any other delayed/controlled-execution facility, no Kerberos ticket (or AFS token) is obtained automatically. Part of the reason lies in the fact that Kerberos' security model makes it almost impossible - even for root users - to authenticate as yourself if the password is not provided. (Where in Unix we would use "sudo" to easily impersonate any user, here it is impossible).

So the way to obtain Kerberos ticket and AFS token from unattended processes will be explained.

Ways of Obtaining AFS Tokens from Unattended Scripts

As hinted before, a password must be present to obtain any Kerberos identity. However, that password may come either from an interactive terminal, or from a file. (A file that is residing outside of the AFS space, of course!).

Kerberos discourages exporting of actual password keys into files, so at HCoop we create two Kerberos "identities" for each user: one named USER (your Unix username) for interactive sessions, and the other named USER.daemon for unattended sessions.

  1. Your USER principal has the password saved only in the protected Kerberos database and it is not possible to obtain its ticket without providing the password.
  2. Your USER.daemon principal has a very long random secret assigned to it and its key exported to a file named /etc/keytabs/user.daemon/USER. Your scripts will use the file /etc/keytabs/user.daemon/USER as a password in obtaining Kerberos/AFS identity "USER.daemon". In fact, all shared HCoop daemons also use that file to obtain permissions to write into your home directory (such as to deliver mail). Of course, Unix permissions and ownership on the keytab file are such that no other user can read your keytab file.

Token "scope"

Kerberos and AFS introduce a concept called Process Authentication Group ("PAG").

  • If you obtain the Kerberos ticket and AFS token within the PAG, the tokens will apply only to the current process (usually a shell) and the processes started from it (its children).

  • If you obtain the Kerberos ticket and AFS token outside the PAG, the tokens will apply to all processes running under your Unix username (well, to those that are not members of some existing PAGs, of course).

To "enter" a PAG, you start shell named /usr/bin/pagsh.openafs. With SSH, even though you find yourself in the shell of preference, a PAG is created for you just beforehand. (Verify by running id and noticing one numerical, untranslated entry such as 1105575254). Once within a PAG, there is basically no way to "escape" from it, so in effect, it is not possible to affect Kerberos/AFS identity of any of your other running processes by SSH-ing into a machine and doing kinit as a different principal or obtaining different AFS tokens - they only apply to your current shell and its subprocesses.

In contrast, when unattended processes are started in your name, they are free of a PAG so you have the freedom of choice - influencing all "pagless" processes running under your Unix username, or starting pagsh manually and restricting influence to the current process and its children.

This quickly leads to two possible strategies:

  1. Have one pagless process running which is refreshing USER.daemon token periodically (to keep it from expiring), and also run all scripts pagless - they will automatically find themselves to have that USER.daemon token.
  2. Invoke all your scripts with shell /usr/bin/pagsh.openafs (can be in the #! "shebang" line) and obtain AFS token immediately after. Then rely on all subprocesses started from that script to inherit the obtained identity.

Unattended Access Privileges

In any case, using file /etc/keytabs/user.daemon/USER to obtain your Kerberos/AFS identity will "log you in" into AFS as USER.daemon, not USER. Therefore, make sure that all directories you want to access from unattended scripts have read or write permission for USER.daemon in addition to USER.

For example, here's how the permissions look for your ~/Maildir/ which gives USER.daemon write access:

$ fs la ~/Maildir/

Access list for /afs/hcoop.net/user/U/US/USER/Maildir/ is
Normal rights:
  system:administrators rlidwka
  USER rlidwka
  USER.daemon rlidwka

To give read permission on a directory, use

fs sa DIRECTORY USER.daemon read

To give write permission on a directory, use

fs sa DIRECTORY USER.daemon write

To recursively give write permission for all subdirectories,

find DIRECTORY -type d -exec fs sa {} ${USER}.daemon write \;

Note that we mention directory permissions only - in AFS, there are no file permissions. Directory permissions apply to all contained files, except subdirectories. Each subdirectory defines its own permissions. When new subdirectories are created, they inherit the ACL list from the parent directory. If you want to change ACLs on an existing directory tree, just use the fsr command in place of fs, with the same arguments.

Recipes and Examples

While you can use kinit to obtain tokens, we will use k5start in all examples. K5start is equivalent or better to kinit for all purposes.

Example 1: unattended.sh

1. Create a script, ex: unattended.sh, in your ~/bin that is readable by USER.daemon.

#!/bin/sh
k5start -t -U -f /etc/keytabs/user.daemon/USER -- COMMANDHERE

(Replace USER with your username and COMMANDHERE with the command you want to run)

2. Edit your crontab to call the script as ~/bin/unattended.sh

Creating the Directories Used in Examples

Create a directory that will contain your local executables and give USER.daemon read permission to it:

$ mkdir ~/bin/
$ fs sa ~/bin USER.daemon read

Make sure your ~/.bash_profile or equivalent file has ~/bin/ at the beginning of PATH, by enabling this within ~/.bash_profile:

# set PATH so it includes user's private bin if it exists
if [ -d ~/bin ] ; then
    PATH=~/bin:"${PATH}"
fi

Create a directory that will contain PID files for all your user processes:

$ mkdir ~/.run
$ fs sa ~/.run system:anyuser rl
$ fs sa ~/.run USER.daemon write

Script to Run a Particular Service Within Pagsh

Please be sure to also check RunningUnattendedCommandsWithoutRunInPagsh.

Someone should write a better script that automates k5start and setting up an @reboot cron job instead of this -- ClintonEbadi 2013-07-13 10:11:39

A wrapper script that runs a user-specified daemon is provided on Mire as run-in-pagsh. When calling it, the first argument should be a unique name with no spaces that describes the daemon, and then provide the command line for calling that daemon afterwards. Be sure to follow the instructions in the previous section for creating a ~/.run directory with correct permissions.

Here is an example of calling this script:

run-in-pagsh interch ~/bin/interchange

If you want to run a command from cron then use the following instead. The --fg argument tells run-in-pagsh that the command will run in the foreground, rather than the background.

run-in-pagsh --fg clean-mail ~/scripts/clean-mail

For the curious, the run-in-pagsh script may be viewed here.


CategoryNeedsWork CategoryMemberManual CategoryNeedsWork

MemberManual/RunningUnattendedCommands (last edited 2023-04-05 15:42:46 by 128)