//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

=== Remote

Apache Karaf supports a complete remote mechanism allowing you to remotely connect to a running Apache Karaf instance.
More over, you can also browse, download, and upload files remotely to a running Apache Karaf instance.

Apache Karaf embeds a complete SSHd server.

[NOTE]
====
For security reason, by default, `karaf` user is disabled. To allow the logon, you have to have an user. You can enable
`karaf` user by uncommenting the user in `etc/users.properties`:

----
karaf = karaf,_g_:admingroup
_g_\:admingroup = group,admin,manager,viewer,systembundles,ssh
----
====

==== SSHd server

When you start Apache Karaf, it enables a remote console that can be accessed over SSH.

This remote console provides all the features of the "local" console, and gives a remote user complete control over the
container and services running inside of it. As the "local" console, the remote console is secured by a RBAC mechanism
(see the link:security[Security section] of the user guide for details).

In addition to the remote console, Apache Karaf also provides a remote filesystem. This remote filesystem can be accessed
using a SCP/SFTP client.

===== Configuration

The configuration of the SSHd server is stored in the `etc/org.apache.karaf.shell.cfg` file:

----
################################################################################
#
#    Licensed to the Apache Software Foundation (ASF) under one or more
#    contributor license agreements.  See the NOTICE file distributed with
#    this work for additional information regarding copyright ownership.
#    The ASF licenses this file to You under the Apache License, Version 2.0
#    (the "License"); you may not use this file except in compliance with
#    the License.  You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
#
################################################################################

#
# These properties are used to configure Karaf's ssh shell.
#

#
# Via sshPort and sshHost you define the address you can login into Karaf.
#
sshPort = 8101
sshHost = 0.0.0.0

#
# The sshIdleTimeout defines the inactivity timeout to logout the SSH session.
# The sshIdleTimeout is in milliseconds, and the default is set to 30 minutes.
#
sshIdleTimeout = 1800000

#
# sshRealm defines which JAAS domain to use for password authentication.
#
sshRealm = karaf

#
# The location of the hostKey file defines where the private key of the server
# is located. If no file is at the defined location it will be ignored.
#
hostKey = ${karaf.etc}/host.key

#
# The password required to decrypt the private key of the server stored in
# 'hostKey'. This is not required if the private key stored in 'hostKey' is
# not encrypted
#hostKeyPassword =

#
# The location of the hostKeyPub file defines where the public key of the server
# is located. If no file is at the defined location it will be ignored.
#
#hostKeyPub = ${karaf.etc}/host.key.pub

#
# sshRole defines the role required to access the console through ssh
#
# sshRole = ssh

#
# Defines if the SFTP system is enabled or not in the SSH server
#
sftpEnabled=true

#
# Self defined key size in 1024, 2048, 3072, or 4096
# If not set, this defaults to 2048.
#
# keySize = 2048

#
# Specify host key algorithm, defaults to RSA
#
# algorithm = RSA

#
# Defines the completion mode on the Karaf shell console. The possible values are:
# - GLOBAL: it's the same behavior as in previous Karaf releases. The completion displays all commands and all aliases
#           ignoring if you are in a subshell or not.
# - FIRST: the completion displays all commands and all aliases only when you are not in a subshell. When you are
#          in a subshell, the completion displays only the commands local to the subshell.
# - SUBSHELL: the completion displays only the subshells on the root level. When you are in a subshell, the completion
#             displays only the commands local to the subshell.
# This property define the default value when you use the Karaf shell console.
# You can change the completion mode directly in the shell console, using shell:completion command.
#
completionMode = GLOBAL
----

The `etc/org.apache.karaf.shell.cfg` configuration file contains different properties to configure the SSHd server:

* `sshPort` is the port number where the SSHd server is bound (by default, it's 8101).
* `sshHost` is the address of the network interface where the SSHd server is bound. The default value is 0.0.0.0,
 meaning that the SSHd server is bound on all network interfaces. You can bind on a target interface by providing the IP
 address of the network interface.
* `hostKey` is the location of the `host.key` file. By defaut, it uses `etc/host.key`. This file stores the 
 private key of the SSHd server.
* `hostKeyPassword` is the password required to decrypt the private key of the server stored in `hostKey`, if the key
is stored in an encrypted form. Note that Karaf does not use this property to
encrypt the private key when generating it, only for reading external keys
that are already encrypted. Also note that specifying a `hostKeyPassword`
might require installing the BouncyCastle provider to support the desired
encryption algorithm.
* `hostKeyPub` is the location of the public key of the server.
* `sshRole` is the default role used for SSH access. See the [Security section|security] of this user guide for details.
* `sftpEnabled` controls if the SSH server starts the SFTP system or not. When enabled, Karaf SSHd supports SFTP, meaning
 that you can remotely access the Karaf filesystem with any sftp client.
* `keySize` is the key size used by the SSHd server. The possible values are 1024, 2048, 3072, or 4096. The default
 value is 2048.
* `algorithm` is the host key algorithm used by the SSHd server. The possible values are DSA, EC or RSA. The default
 value is RSA.

The SSHd server configuration can be changed at runtime:

* by editing the `etc/org.apache.karaf.shell.cfg` configuration file
* by using the `config:*` commands

At runtime, when you change the SSHd server configuration, you have to restart the SSHd server to load the changes.
You can do it with:

----
karaf@root()> bundle:restart -f org.apache.karaf.shell.ssh
----

The Apache Karaf SSHd server supports key/agent authentication and password authentication.

===== Console clients

====== System native clients

The Apache Karaf SSHd server is a pure SSHd server, similar to a OpenSSH daemon.

It means that you can directly use a SSH client from your system.

For instance, on Unix, you can directly use OpenSSH:

----
~$ ssh -p 8101 karaf@localhost
Authenticated with partial success.
Authenticated with partial success.
Authenticated with partial success.
Password authentication
Password:
        __ __                  ____
       / //_/____ __________ _/ __/
      / ,<  / __ `/ ___/ __ `/ /_
     / /| |/ /_/ / /  / /_/ / __/
    /_/ |_|\__,_/_/   \__,_/_/

  Apache Karaf (4.0.0)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit 'system:shutdown' to shutdown Karaf.
Hit '<ctrl-d>' or type 'logout' to disconnect shell from current session.

karaf@root()>
----

On Windows, you can use Putty, Kitty, etc.

If you don't have a SSH client installed on your machine, you can use the Apache Karaf client.

====== `ssh:ssh` command

Apache Karaf itself provides a SSH client. When you are on the Apache Karaf console, you have the `ssh:ssh` command:

----
karaf@root()> ssh:ssh --help
DESCRIPTION
        ssh:ssh

        Connects to a remote SSH server

SYNTAX
        ssh:ssh [options] hostname [command]

ARGUMENTS
        hostname
                The host name to connect to via SSH
        command
                Optional command to execute

OPTIONS
        --help
                Display this help message
        -p, --port
                The port to use for SSH connection
                (defaults to 22)
        -P, --password
                The password for remote login
        -q
                Quiet Mode. Do not ask for confirmations
        -l, --username
                The user name for remote login

----

Thanks to the `ssh:ssh` command, you can connect to another running Apache Karaf instance:

----
karaf@root()> ssh:ssh -p 8101 karaf@192.168.134.2
Connecting to host 192.168.134.2 on port 8101
Connecting to unknown server. Add this server to known hosts ? (y/n)
Storing the server key in known_hosts.
Connected
        __ __                  ____
       / //_/____ __________ _/ __/
      / ,<  / __ `/ ___/ __ `/ /_
     / /| |/ /_/ / /  / /_/ / __/
    /_/ |_|\__,_/_/   \__,_/_/

  Apache Karaf (4.0.0)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit 'system:shutdown' to shutdown Karaf.
Hit '<ctrl-d>' or type 'logout' to disconnect shell from current session.

karaf@root()>
----

When you don't provide the `command` argument to the `ssh:ssh` command, you are in the interactive mode: you have
a complete remote console available, where you can type commands, etc.

You can also provide directly a command to execute using the `command` argument. For instance, to remotely shutdown
a Apache Karaf instance:

----
karaf@root()> ssh:ssh -p 8101 karaf@localhost system:shutdown -f
Connecting to host localhost on port 8101
Connected
----

As the `ssh:ssh` command is a pure SSH client, it means that you can connect to a Unix OpenSSH daemon:

----
karaf@root()> ssh:ssh user@localhost
Connecting to host localhost on port 22
Connecting to unknown server. Add this server to known hosts ? (y/n)
Storing the server key in known_hosts.
Agent authentication failed, falling back to password authentication.
Password: Connected
Last login: Sun Sep  8 19:21:12 2013
user@server:~$
----

====== Apache Karaf client

The `ssh:ssh` command can only be run in a running Apache Karaf console.

For convenience, the `ssh:ssh` command is "wrapped" as a standalone client: the `bin/client` Unix script (`bin\client.bat` on Windows).

----
bin/client --help
Apache Karaf client
  -a [port]     specify the port to connect to
  -h [host]     specify the host to connect to
  -u [user]     specify the user name
  --help        shows this help message
  -v            raise verbosity
  -r [attempts] retry connection establishment (up to attempts times)
  -d [delay]    intra-retry delay (defaults to 2 seconds)
  -b            batch mode, specify multiple commands via standard input
  -f [file]     read commands from the specified file
  [commands]    commands to run
If no commands are specified, the client will be put in an interactive mode
----

For instance, to connect to a local Apache Karaf instance (on the default SSHd server 8101 port), you can directly use
`bin/client` Unix script (`bin\client.bat` on Windows) without any argument or option:

----
bin/client
Logging in as karaf
343 [pool-2-thread-4] WARN org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier - Server at /0.0.0.0:8101 presented unverified key:
        __ __                  ____
       / //_/____ __________ _/ __/
      / ,<  / __ `/ ___/ __ `/ /_
     / /| |/ /_/ / /  / /_/ / __/
    /_/ |_|\__,_/_/   \__,_/_/

  Apache Karaf (4.0.0)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit 'system:shutdown' to shutdown Karaf.
Hit '<ctrl-d>' or type 'logout' to disconnect shell from current session.

karaf@root()>
----

When you don't provide the `command` argument to the `bin/client` Unix script (`bin\client.bat` on Windows), you are
in the interactive mode: you have a complete remote console available, where you can type commands, etc.

You can also provide directly a command to execute using the `command` argument. For instance, to remotely shutdown
a Apache Karaf instance:

----
bin/client "system:shutdown -f"
Logging in as karaf
330 [pool-2-thread-3] WARN org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier - Server at /0.0.0.0:8101 presented unverified key:
----

As the Apache Karaf client is a pure SSH client, you can use to connect to any SSHd daemon (like Unix OpenSSH daemon):

----
bin/client -a 22 -h localhost -u user
Logging in as user
353 [pool-2-thread-2] WARN org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier - Server at localhost/127.0.0.1:22 presented unverified key:
Password:
Welcome to Ubuntu 13.10 (GNU/Linux 3.11.0-13-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

Last login: Tue Dec  3 18:18:31 2013 from localhost
----

====== Logout

When you are connected to a remote Apache Karaf console, you can logout using:

* using CTRL-D key binding. Note that CTRL-D just logs out from the remote console in this case, it doesn't shutdown
 the Apache Karaf instance (as CTRL-D does when used on a local console).
* using `shell:logout` command (or simply `logout`)

===== Filesystem clients

Apache Karaf SSHd server also provides complete fileystem access via SSH. For security reasons, the available filesystem
is limited to `KARAF_BASE` directory.

You can use this remote filesystem with any SCP/SFTP compliant clients.

====== Native SCP/SFTP clients

On Unix, you can directly use `scp` command to download/upload files to the Apache Karaf filesystem. For instance,
to retrieve the `karaf.log` file remotely:

----
~$ scp -P 8101 karaf@localhost:/data/log/karaf.log .
Authenticated with partial success.
Authenticated with partial success.
Authenticated with partial success.
Password authentication
Password:
karaf.log
----

As you have access to the complete `KARAF_BASE` directory, you can remotely change the configuration file in the `etc`
folder, retrieve log files, populate the `system` folder.

On Windows, you can use WinSCP to access the Apache Karaf filesystem.

It's probably easier to use a SFTP complient client.

For instance, on a Unix system, you can use `lftp` or `ncftp`:

----
$ lftp
lftp :~> open -u karaf sftp://localhost:8101
Password:
lftp karaf@localhost:~> ls
-rw-r--r--   1 jbonofre jbonofre    27754 Oct 26 10:50 LICENSE
-rw-r--r--   1 jbonofre jbonofre     1919 Dec  3 05:34 NOTICE
-rw-r--r--   1 jbonofre jbonofre     3933 Aug 18  2012 README.md
-rw-r--r--   1 jbonofre jbonofre   101041 Dec  3 05:34 RELEASE-NOTES.md
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 12:51 bin
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 18:57 data
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 12:51 examples
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 13:02 deploy
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 17:59 etc
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 13:02 instances
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 13:02 lib
-rw-r--r--   1 jbonofre jbonofre        0 Dec  3 13:02 lock
drwxr-xr-x   1 jbonofre jbonofre     4096 Dec  3 12:51 system
lftp karaf@localhost:/>
----

You can also use a graphic client like `filezilla`, `gftp`, `nautilus`, etc.

On Windows, you can use `filezilla`, `WinSCP`, etc.

====== Apache Maven

The Apache Karaf `system` folder is the Karaf repository, that uses a Maven directory structure. It's where Apache Karaf
looks for the artifacts (bundles, features, kars, etc).

Using Apache Maven, you can populate the `system` folder using the `deploy:deploy-file` goal.

For instance, you want to add the Apache ServiceMix facebook4j OSGi bundle, you can do:

----
mvn deploy:deploy-file -Dfile=org.apache.servicemix.bundles.facebook4j-2.0.2_1.jar -DgroupId=org.apache.servicemix.bundles -DartifactId=org.apache.servicemix.bundles.facebook4j -Dversion=2.0.2_1 -Dpackaging=jar -Durl=scp://localhost:8101/system
----

[NOTE]
====
If you want to turn Apache Karaf as a simple Maven repository, you can use link:https://karaf.apache.org/projects.html[Apache Karaf Cave].
====

==== JMX MBeanServer

Apache Karaf provides a JMX MBeanServer.

This MBeanServer is available remotely, using any JMX client like `jconsole`.

You can find details on the [Monitoring section|monitoring] of the user guide.
