.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings.  \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
.    ds -- \(*W-
.    ds PI pi
.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
.    ds L" ""
.    ds R" ""
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds -- \|\(em\|
.    ds PI \(*p
.    ds L" ``
.    ds R" ''
.    ds C`
.    ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
.    if \nF \{\
.        de IX
.        tm Index:\\$1\t\\n%\t"\\$2"
..
.        if !\nF==2 \{\
.            nr % 0
.            nr F 2
.        \}
.    \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
.    \" fudge factors for nroff and troff
.if n \{\
.    ds #H 0
.    ds #V .8m
.    ds #F .3m
.    ds #[ \f1
.    ds #] \fP
.\}
.if t \{\
.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
.    ds #V .6m
.    ds #F 0
.    ds #[ \&
.    ds #] \&
.\}
.    \" simple accents for nroff and troff
.if n \{\
.    ds ' \&
.    ds ` \&
.    ds ^ \&
.    ds , \&
.    ds ~ ~
.    ds /
.\}
.if t \{\
.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
.    \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
.    \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
.    \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
.    ds : e
.    ds 8 ss
.    ds o a
.    ds d- d\h'-1'\(ga
.    ds D- D\h'-1'\(hy
.    ds th \o'bp'
.    ds Th \o'LP'
.    ds ae ae
.    ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "REMCTL-SHELL 8"
.TH REMCTL-SHELL 8 "2022-05-09" "3.18" "remctl"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
remctl\-shell \- Restricted shell that mimics a remctl server
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
remctl-shell [\fB\-dhqSv\fR] [\fB\-f\fR \fIconfig\fR] \fB\-c\fR \fIcommand\fR
.PP
remctl-shell [\fB\-dqS\fR] [\fB\-f\fR \fIconfig\fR] \fIuser\fR
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
\&\fBremctl-shell\fR is a restricted shell that mimics the behavior of the
\&\fBremctld\fR server without using the remctl protocol, GSS-API, or Kerberos.
It's intended to be run via ssh as either the shell or the forced command
for a special user (by convention, \f(CW\*(C`remctl\*(C'\fR, although \fBremctl-shell\fR
doesn't care), with an \fIauthorized_keys\fR file that specifies the user
identity corresponding to each key that is allowed to run remctl commands.
All access control then works as normal.
.PP
The output of the command ran is returned on standard output and standard
error, like a normal command run via ssh, and the exit status of
\&\fBremctl-shell\fR will be the exit status of the command.  Only one command
can be run per ssh connection, so this will be noticeably slower for each
command execution than a well-designed remctl client and server design
that holds connections open for multiple commands.
.PP
\&\fBremctl-shell\fR is designed to mimic the behavior of \fBremctld\fR and uses
the same configuration syntax and environment variables.  See
\&\*(L"\s-1CONFIGURATION FILE\*(R"\s0 in \fBremctld\fR\|(8) for configuration information and
\&\s-1ENVIRONMENT\s0 below for more specific details about environment variable
handling.  The location of the configuration file may be specified with
the \fB\-f\fR option.  The default location is \fI\f(CI@sysconfdir\fI@/remctl.conf\fR.
.PP
Since \fBremctl-shell\fR is designed to be run by a potentially untrusted
user as a shell, normally all error messages and logging is done via
syslog and not sent to standard error.  See the \fB\-S\fR, \fB\-d\fR, and \fB\-q\fR
options when running it manually to debug problems.  (When running
manually, you will also normally need to set the \s-1SSH_CONNECTION\s0
environment variable and either \s-1REMCTL_USER\s0 or \s-1SSH_ORIGINAL_COMMAND\s0
depending on how you invoke it.)
.SS "Quoting and Command Limitations"
.IX Subsection "Quoting and Command Limitations"
The ssh protocol is much less sophisticated than remctl at passing command
arguments from the client to the server, so \fBremctl-shell\fR requires
careful attention to command arguments and quoting.  ssh does no quoting
of arguments, just adds a single space between each argument and passes
them verbatim to the shell on the server side.  This means the client has
to add quoting to any arguments containing whitespace.  \fBremctl-shell\fR
supports single and double quotes, and supports using backslash to escape
any character inside or outside either quotes.  However, be aware, when
running ssh from the command line, that your shell will remove another
level of quoting.  You will therefore usually have to double-quote
arguments.
.PP
For example, to run the command \f(CW\*(C`log message\*(C'\fR with argument \f(CW\*(C`this is a
message\*(C'\fR via ssh from the command line, use:
.PP
.Vb 1
\&    ssh remctl@example.com log message "\*(Aqthis is a message\*(Aq"
.Ve
.PP
The first level of \f(CW""\fR quoting will be removed by your local shell, and
\&\fBremctl-shell\fR will interpret the second level of \f(CW\*(Aq\*(Aq\fR quotes.  Note
that, because of how ssh does command argument passing, this is exactly
equivalent to:
.PP
.Vb 1
\&    ssh remctl@example.com "log message \*(Aqthis is a message\*(Aq"
.Ve
.PP
since ssh doesn't preserve the distinction between separate arguments when
creating the command to send to the remote server.  It may be less
confusing to get in the habit of quoting the entire command.
.PP
Also be aware that the full command is passed via command line arguments,
which means, when invoking \fBremctl-shell\fR as a shell, there is a tight
limit on the length of the whole command plus arguments.  Expect to have
problems if the total command length exceeds 1000 characters.  For the
same reason, binary data including null characters cannot be passed via
\&\fBremctl-shell\fR.  Invoking it as a forced command may work around these
limitations by putting the command into the environment instead, but there
may still be restrictions on that.  (The regular remctl protocol supports
arbitrary-length arguments, limited only by server-side configuration and
available server memory, and supports arbitrary binary data in arguments.)
.ie n .SS """authorized_keys"" Configuration"
.el .SS "\f(CWauthorized_keys\fP Configuration"
.IX Subsection "authorized_keys Configuration"
\&\fBremctl-shell\fR is intended for use via ssh using \f(CW\*(C`authorized_keys\*(C'\fR to
manage authentication.  (If you have Kerberos available, it's generally
better to use the normal \fBremctld\fR server and native remctl protocol.)
.PP
There are two ways to set up \fBremctl-shell\fR: either by specifying forced
commands, or by configuring \fBremctl-shell\fR as the shell of the account.
The forced command approach is recommended, since it doesn't require
setting a non-default \fIsshd_config\fR option.
.PP
\fIUsing forced commands\fR
.IX Subsection "Using forced commands"
.PP
For the role account that you want to use to run remctl commands
(\f(CW\*(C`remctl\*(C'\fR by convention), create an \fIauthorized_keys\fR file listing
everyone who should be able to run commands.  Before each key, set the
\&\f(CW\*(C`command\*(C'\fR option like the below:
.PP
.Vb 1
\&    command="@sbindir@/remctl\-shell example@EXAMPLE.ORG"
.Ve
.PP
where the argument to \fBremctl-shell\fR is the identity matching the ssh key
on that line.  A more complete example of a line in \fIauthorized_keys\fR:
.PP
.Vb 4
\&    command="@sbindir@/remctl\-shell example@EXAMPLE.ORG",\e
\&    no\-agent\-forwarding,no\-port\-forwarding,no\-pty,no\-user\-rc,\e
\&    no\-X11\-forwarding ssh\-rsa AAAAB3NzaC1yc2EA... \e
\&    example@some\-host.example.org
.Ve
.PP
Backslashes and line breaks were added for clarity.  The actual entry
should be a single long line.  For more information on the other settings
here, see Examples below.
.PP
\fIUsing a shell\fR
.IX Subsection "Using a shell"
.PP
When running \fBremctl-shell\fR as the shell of the account, instead of using
forced commands, the \fIauthorized_keys\fR configuration must be set up to
associate each key with an identity by setting the \s-1REMCTL_USER\s0 environment
variable.  Using user identities that look like Kerberos principal names
is strongly recommended, since it may make it easier to use some of the
\&\s-1ACL\s0 methods intended for the normal remctl server.
.PP
Since this relies on setting environment variables via \f(CW\*(C`authorized_keys\*(C'\fR,
you unfortunately have to enable \f(CW\*(C`PermitUserEnvironment\*(C'\fR in
\&\fIsshd_config\fR (this is not the default) by adding:
.PP
.Vb 1
\&    PermitUserEnvironment yes
.Ve
.PP
\fIOther options\fR
.IX Subsection "Other options"
.PP
\&\fBremctl-shell\fR will not make use of forwarded connections or agents, and
will not pass them along to the processes they run, so all such ssh
options should normally be disabled for defense in depth security.
.PP
\fIExamples\fR
.IX Subsection "Examples"
.PP
Here is a recommended line in \f(CW\*(C`authorized_keys\*(C'\fR for the account managed
by \fBremctl-shell\fR, with appropriate restrictions and an example of how to
set the \s-1REMCTL_USER\s0 variable.  Backslashes and line breaks were added for
clarity.  The actual entry should be a single long line.
.PP
.Vb 3
\&    environment="REMCTL_USER=example@EXAMPLE.ORG",no\-agent\-forwarding,\e
\&    no\-port\-forwarding,no\-pty,no\-user\-rc,no\-X11\-forwarding ssh\-rsa \e
\&    AAAAB3NzaC1yc2EA... example@some\-host.example.org
.Ve
.PP
Setting \f(CW\*(C`no\-user\-rc\*(C'\fR is particularly important for \fBremctl-shell\fR.  If
you have OpenSSH 7.2 or later, which added the \f(CW\*(C`restrict\*(C'\fR keyword, you
can instead use the much simpler:
.PP
.Vb 2
\&    environment="REMCTL_USER=example@EXAMPLE.ORG",restrict ssh\-rsa \e
\&    AAAAB3NzaC1yc2EA... example@some\-host.example.org
.Ve
.PP
\&\s-1REMCTL_USER\s0 should be set to the identity string for the owner of that key
pair, as used in the ACLs in your remctl configuration.
.SH "OPTIONS"
.IX Header "OPTIONS"
\&\fBremctl-shell\fR is normally only run with either the \fB\-c\fR option or with
a user, since it's intended for use as a shell or forced command.
However, it does support some other options for testing, which may be
useful in \fIauthorized_keys\fR.  If using it as a shell, one can use a small
wrapper program as the configured shell that passes additional options
into \fBremctl-shell\fR if needed.
.PP
The start of each option description is annotated with the version of
\&\fBremctl-shell\fR in which that option was added with its current meaning.
.IP "\fB\-c\fR \fIcommand\fR" 4
.IX Item "-c command"
[3.12] The command to run.  This is how ssh passes the command string into
\&\fBremctl-shell\fR.  \fBremctl-shell\fR will then parse it into separate
arguments using an algorithm similar to that used by a shell.  See the
above discussion of quoting for more information.
.Sp
This is mandatory when using \fBremctl-shell\fR as a shell.  If using it as a
forced command, pass the user on the command line instead and do not use
this option.
.IP "\fB\-d\fR" 4
.IX Item "-d"
[3.12] Enable verbose debug logging to syslog (or to standard output if
\&\fB\-S\fR is also given).
.IP "\fB\-f\fR \fIconfig\fR" 4
.IX Item "-f config"
[3.12] The configuration file for \fBremctld\fR, overriding the default path.
.IP "\fB\-h\fR" 4
.IX Item "-h"
[3.12] Show a brief usage message and then exit.  This usage method will
include a list of supported \s-1ACL\s0 types and can be used to determine if
optional \s-1ACL\s0 methods were compiled into a given \fBremctl-shell\fR build.
.IP "\fB\-q\fR" 4
.IX Item "-q"
[3.12] Suppress the normal informational logging of what commands are
being executed and by whom.  This is intended primarily to avoid spamming
syslog during testing.
.IP "\fB\-S\fR" 4
.IX Item "-S"
[3.12] Rather than logging to syslog, log debug and routine connection
messages to standard output and error messages to standard error.  In
normal usage, this would send all the logging back to the client,
intermixed with program output, so it's normally useful only for testing
and debugging.
.IP "\fB\-v\fR" 4
.IX Item "-v"
[3.12] Print the version of \fBremctl-shell\fR and exit.
.SH "ENVIRONMENT"
.IX Header "ENVIRONMENT"
\&\fBremctl-shell\fR itself requires the following environment variables be set
when it is invoked, or it exits with an error and doesn't do anything.
.IP "\s-1REMCTL_USER\s0" 4
.IX Item "REMCTL_USER"
The user used for logging and to make authorization decisions, unless that
was passed on the command line.  The security of all \fBremctl-shell\fR
authorization checks is based on the accuracy of this environment
variable, so be sure that it is set correctly.  The best way to do this is
via \f(CW\*(C`environment\*(C'\fR stanzas in \fIauthorized_keys\fR as described above.  If
the user is passed on the command line, this is ignored.
.IP "\s-1SSH_CONNECTION\s0" 4
.IX Item "SSH_CONNECTION"
\&\fBsshd\fR uses this environment variable to communication information about
the local and remote \s-1IP\s0 addresses and ports of the ssh connection.
\&\fBremctl-shell\fR expects the first space-separated token in this
environment variable to be the \s-1IP\s0 address of the client.  It then uses
that to set \s-1REMOTE_ADDR\s0 in the environment of any commands it runs.
.IP "\s-1SSH_ORIGINAL_COMMAND\s0" 4
.IX Item "SSH_ORIGINAL_COMMAND"
When run as a forced command, the command run by the user is taken from
this environment variable, which is set by \fBsshd\fR.
.PP
The following environment variables will be set for any commands run via
\&\fBremctl-shell\fR (annotated with the version at which they were added).
These are mostly the same as those set by \fBremctld\fR.  Differences are
noted in each description.
.IP "\s-1REMCTL_COMMAND\s0" 4
.IX Item "REMCTL_COMMAND"
[3.12] The command string that caused this command to be run.  This
variable will contain only the command, not the subcommand or any
additional arguments (which are passed as command arguments).
.IP "\s-1REMOTE_ADDR\s0" 4
.IX Item "REMOTE_ADDR"
[3.12] The \s-1IP\s0 address of the remote host.  This may be IPv4 or IPv6.  This
is taken from the \s-1SSH_CONNECTION\s0 environment variable.
.IP "\s-1REMOTE_EXPIRES\s0" 4
.IX Item "REMOTE_EXPIRES"
[3.12] Normally, this communicates the time (in seconds since \s-1UNIX\s0 epoch)
when the authenticated remote session will expire.  However, this is not a
meaningful concept for ssh authentication via public key, and regardless
is not communicated by \fBsshd\fR to the shell.  It is therefore always set
to \f(CW0\fR by \fBremctl-shell\fR.
.IP "\s-1REMOTE_HOST\s0" 4
.IX Item "REMOTE_HOST"
[3.12] The hostname of the remote host, if it was available.  If reverse
name resolution failed, this environment variable will not be set.
.Sp
This is determined via a simple reverse \s-1DNS\s0 lookup and should be
considered under the control of the client.  remctl commands should treat
it with skepticism and not use it for anything other than logging
purposes.
.IP "\s-1REMOTE_USER\s0" 4
.IX Item "REMOTE_USER"
.PD 0
.IP "\s-1REMUSER\s0" 4
.IX Item "REMUSER"
.PD
[3.12] Set to the value of \s-1REMCTL_CLIENT\s0 as set in the environment of
\&\fBremctl-shell\fR. This should be set securely via \fIauthorized_keys\fR as
discussed above.
.PP
Note that \s-1REMOTE_HOST\s0 is not set by \fBremctl-shell\fR, at least currently.
.SH "EXAMPLES"
.IX Header "EXAMPLES"
Typically, \fBremctl-shell\fR will either be run as a forced command or set
as the shell for a dedicated user, normally \f(CW\*(C`remctl\*(C'\fR, via the normal
mechanism for local account creation.  That account should be configured
with an ssh \fIauthorized_keys\fR file as discussed above.  \fBremctl-shell\fR
will then be invoked with:
.PP
.Vb 1
\&    remctl\-shell \-c \*(Aqcommand subcommand argument\*(Aq
.Ve
.PP
(if used as a shell) or with:
.PP
.Vb 1
\&    remctl\-shell user@EXAMPLE.ORG
.Ve
.PP
(if used as a forced command) by \fBsshd\fR for each incoming connection from
a user that has a key in the \fIauthorized_keys\fR file.
.PP
If you need to run a command manually for debugging, you can run the same
command as above, but it's often more useful to send errors to standard
error instead of to syslog.  You can do that with:
.PP
.Vb 1
\&    remctl\-shell \-S \-c \*(Aqcommand subcommand argument\*(Aq
.Ve
.PP
If you don't want to see the normal command logging, add the \fB\-q\fR option
as well.  You can test an alternate configuration file by specifying it
with the \fB\-f\fR option.  You will need to set \s-1SSH_CONNECTION\s0 and either
\&\s-1REMCTL_USER\s0 (if using \fB\-c\fR) or \s-1SSH_ORIGINAL_COMMAND\s0 (if passing the user
on the command line).
.SH "COMPATIBILITY"
.IX Header "COMPATIBILITY"
\&\fBremctl-shell\fR was added in the remctl 3.12 release.
.PP
The forced command mode where the user can be passed on the command line
and the command retrieved from \s-1SSH_ORIGINAL_COMMAND\s0 was added in the
remctl 3.13 release.
.SH "CAVEATS"
.IX Header "CAVEATS"
Most of the caveats and differences between \fBremctl-shell\fR and the normal
\&\fBremctld\fR server are from quoting and the limitations of passing
arguments via the command line.  Review the section on quoting above for
more information.
.PP
Normally, \fBremctl-shell\fR runs as a dedicated non-root user (as opposed to
often running as root like \fBremctld\fR), which means that all commands will
normally run as that user and the \f(CW\*(C`user\*(C'\fR configuration option will not
work.  The easiest way to run commands as other users is to have the
underlying command use \fBsudo\fR or some other user switching mechanism,
which will normally require additional local configuration.
.PP
User environment setting has to be enabled in \fBsshd\fR by setting the
non-default \f(CW\*(C`PermitUserEnvironment\*(C'\fR configuration option.  A future
version of \fBremctl-shell\fR may use forced commands with an argument
instead of a shell to avoid this.
.SH "AUTHOR"
.IX Header "AUTHOR"
\&\fBremctl-shell\fR was written by Russ Allbery <eagle@eyrie.org>.  Many
thanks to Dropbox, Inc. for providing the time to write the initial
implementation during Dropbox's annual Hack Week.
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
Copyright 2016 Russ Allbery <eagle@eyrie.org>
.PP
Copyright 2016 Dropbox, Inc.
.PP
Copying and distribution of this file, with or without modification, are
permitted in any medium without royalty provided the copyright notice and
this notice are preserved.  This file is offered as-is, without any
warranty.
.PP
SPDX-License-Identifier: \s-1FSFAP\s0
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fBremctld\fR\|(8), \fBsshd\fR\|(8)
.PP
The current version of this program is available from its web page at
<https://www.eyrie.org/~eagle/software/remctl/>.
