diff options
Diffstat (limited to 'lib/ssh/doc/src/configurations.xml')
-rw-r--r-- | lib/ssh/doc/src/configurations.xml | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/lib/ssh/doc/src/configurations.xml b/lib/ssh/doc/src/configurations.xml new file mode 100644 index 0000000000..cd55e87027 --- /dev/null +++ b/lib/ssh/doc/src/configurations.xml @@ -0,0 +1,341 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2020</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Configuration in SSH</title> + <prepared></prepared> + <docno></docno> + <approved></approved> + <date></date> + <rev></rev> + <file>configurations.xml</file> + </header> + + <section> + <marker id="introduction"/> + <title>Introduction</title> + <p>The OTP SSH app can be configurated by a large amount of <i>Options</i>. This chapter will not go into + details of what each of the options does. It will however describe and define different ways by which they + could be entered. + </p> + <p>Options for hardening are described in the <seeguide marker="hardening">Hardening SSH</seeguide> chapter. + How the options for algorithm configuration interact are described in the + <seeguide marker="configure_algos">Configuring algorithms in SSH</seeguide> chapter. + </p> + </section> + + <section> + <title>Options configuration</title> + <p>There are from OTP-23.0 two main ways to set an option: + </p> + <list> + <item>Like before, in the <c>Options</c> parameter in the Erlang code + in a call to for example + <seemfa marker="ssh#daemon/3">ssh:daemon/3</seemfa> or + <seemfa marker="ssh#connect/3">ssh:connect/3</seemfa> or + any of their variants. Example: + <code>ssh:connect(22, [{user,"foo"}])</code> + </item> + + <item>In <seefile marker="kernel:config">OTP Configuration Parameters</seefile>: + <p/> + <list> + <item>In the erl command line: + <pre>erl -ssh user \"foo\"</pre> + </item> + <item>In the <c>ssh.app</c> file, in the <c>env</c> part + <code> +{application, ssh, + [{description, "SSH-2 for Erlang/OTP"}, + {vsn, "4.9"}, + {modules, [ssh, + ... + ssh_xfer]}, + {registered, []}, + {applications, [kernel, stdlib, crypto, public_key]}, + {env, [{user, "bar"]}, % <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< HERE + {mod, {ssh_app, []}}, + ... +</code> + </item> + <item>In a .config file: + <pre>erl -config ex1</pre> + where <c>ex1.config</c> contains: + <code>[ +{ssh, [{user, "foo"}]} +]. +</code> + </item> + </list> + <p>If the option is intended only for a server or for a client, it may be set in this way: + </p> + <code>[ +{ssh, [{server_options,[{user, "foo"}]}, + {client_options,[{user, "bar"}]} +]. + </code> + <p>A server (daemon) will use the user name <c>foo</c>, and a client will use the name <c>bar</c>.</p> + </item> + </list> + </section> + + <section> + <title>Precedens</title> + <p>If an option is set in more than one way, what happens?</p> + <p>There is an ordering, which is: + </p> + <list> + <item>Level 0: Hard-coded default values in the source code</item> + <item>Level 1: <seefile marker="kernel:config">OTP Configuration Parameters</seefile></item> + <item>Level 2: Options in the <seefile marker="kernel:config">OTP Configuration Parameters</seefile> + <c>server_options</c> or <c>client_options</c></item> + <item>Level 3: Options in argument list to a function</item> + </list> + <p>If the same option is set at two different levels, the one at the highest level is used. + </p> + <p>The only exception is the + <seetype marker="ssh#modify_algorithms_common_option">modify_algorithms</seetype> + common option. They are all applied in ascending level order on the set of algorithms. So a + <c>modify_algorithms</c> on level zero is applied before one of level one and so on. + </p> + <p>If there is an + <seetype marker="ssh#preferred_algorithms_common_option">preferred_algorithms</seetype> + option on some level the whole set is replaced by that in that option and <em>all modify_algorithms + are applied</em> in level ordering. + </p> + <p>The reason for applying all + <seetype marker="ssh#modify_algorithms_common_option">modify_algorithms</seetype> + in level order, is to enable the user to add an algorithm that has been removed from the + default set without code changes, only by adding an option in a config file. + This can be used to interoperate with legacy systems that still uses algorithms no longer + considered secure enough to be supported by default. + </p> + + <section> + <title>Algorithm configuration</title> + <p>There is a <seeguide marker="configure_algos#introduction">separate chapter</seeguide> about how + <seetype marker="ssh#preferred_algorithms_common_option">preferred_algorithms</seetype> and + <seetype marker="ssh#modify_algorithms_common_option">modify_algorithms</seetype> + co-operate. How the different configuration levels affect them, is described here in this section. + </p> + <section> + <title>The ssh:start/0 function</title> + <p>If the application SSH is <em>not</em> <seemfa marker="ssh#start/0">started</seemfa>, the command + <seemfa marker="ssh#default_algorithms/0">ssh:default_algorithms/0</seemfa> + delivers the list of default (hardcoded) algorithms with respect to the support in the current cryptolib. + </p> + <p>If the application SSH <em>is</em> <seemfa marker="ssh#start/0">started</seemfa>, the command + <seemfa marker="ssh#default_algorithms/0">ssh:default_algorithms/0</seemfa> + delvers the list of algorithms after application of level 0 and level 1 configurations. + </p> + <p>Here is an example. The config-file has the following contents:</p> + <code> +$ cat ex2.config +[ + {ssh, [{preferred_algorithms, [{cipher, ['aes192-ctr']}, + {public_key, ['ssh-rsa']}, + {kex, ['ecdh-sha2-nistp384']}, + {mac, ['hmac-sha1']}]}]} +]. + </code> + <p>Erlang is started with <c>ex2.config</c> as configuration and we check the default set of + algorithms before starting ssh:</p> + <code> +$ erl -config ex2 +Erlang/OTP 23 [RELEASE CANDIDATE 1] [erts-10.6.4] [source-96a0823109] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] + +Eshell V10.6.4 (abort with ^G) +1> ssh:default_algorithms(). +[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521', + 'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group18-sha512', + 'diffie-hellman-group14-sha256','curve25519-sha256', + 'curve25519-sha256@libssh.org','curve448-sha512', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group-exchange-sha1']}, + {public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-ed25519','ssh-ed448','ssh-rsa', + 'rsa-sha2-256','rsa-sha2-512','ssh-dss']}, + {cipher,[{client2server,['chacha20-poly1305@openssh.com', + 'aes256-gcm@openssh.com','aes256-ctr','aes192-ctr', + 'aes128-gcm@openssh.com','aes128-ctr','aes256-cbc', + 'aes192-cbc','aes128-cbc','3des-cbc']}, + {server2client,['chacha20-poly1305@openssh.com', + 'aes256-gcm@openssh.com','aes256-ctr','aes192-ctr', + 'aes128-gcm@openssh.com','aes128-ctr','aes256-cbc', + 'aes192-cbc','aes128-cbc','3des-cbc']}]}, + {mac,[{client2server,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}, + {server2client,['hmac-sha2-256','hmac-sha2-512', + 'hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}] + </code> + <p>Note that the algorithms in the file <c>ex2.config</c> is not yet applied. They will be + when we start ssh: + </p> + <code> +2> ssh:start(). +ok +3> ssh:default_algorithms(). +[{kex,['ecdh-sha2-nistp384']}, + {public_key,['ssh-rsa']}, + {cipher,[{client2server,['aes192-ctr']}, + {server2client,['aes192-ctr']}]}, + {mac,[{client2server,['hmac-sha1']}, + {server2client,['hmac-sha1']}]}, + {compression,[{client2server,[none,'zlib@openssh.com',zlib]}, + {server2client,[none,'zlib@openssh.com',zlib]}]}] +4> + + </code> + <p>We see that the algorithm set is changed to the one in the <c>ex2.config</c>. Since + <c>compression</c> is not specified in the file, the hard-coded default is still used + for that entry. + </p> + </section> + + <section> + <title>Establishing a connection (ssh:connect et al) or starting a daemon (ssh:daemon)</title> + <p>Both when the client establishes a connection with ssh:connect or other functions, or a + daemon is started with ssh:daemon, the option lists in the function calls are also used. + </p> + <p>If a client is started (ssh:connect et al), the environment variable <c>client_options</c> is used. + Similarly for a daemon the <c>server_options</c> variable is handled. + </p> + <p>If any + <seetype marker="ssh#preferred_algorithms_common_option">preferred_algorithms</seetype> is + present, the one with the highest level is used, that is, the <c>Option</c> list parameter has the highest + priority. Then the + <seetype marker="ssh#modify_algorithms_common_option">modify_algorithms</seetype> + on all levels in order starting with level 0 are applied. + + </p> + <p>We continue the example above by connecting to a server and modifying the <c>kex</c> + algorithm set. We remove the only one (<c>'ecdh-sha2-nistp384'</c>) and add + <c>'curve25519-sha256@libssh.org'</c> + by appending it to the now empty list:</p> + <code> +4> {ok,C} = ssh:connect(loopback, 22, + [{modify_algorithms, + [{rm, + [ {kex,['ecdh-sha2-nistp384']} ] + }, + {append, + [ {kex,['curve25519-sha256@libssh.org']} ] + } + ] + } + ]). +{ok,>0.118.0>} + </code> + <p>We check which algoritms are negotiated by the client and the server, and note that + the (only) <c>kex</c> algorithm <c>'curve25519-sha256@libssh.org'</c> was selected: + </p> + <code> +5> ssh:connection_info(C, algorithms). +{algorithms,[{kex,'curve25519-sha256@libssh.org'}, + {hkey,'ssh-rsa'}, + {send_mac,'hmac-sha1'}, + {recv_mac,'hmac-sha1'}, + {encrypt,'aes192-ctr'}, + {decrypt,'aes192-ctr'}, + {compress,none}, + {decompress,none}, + {send_ext_info,false}, + {recv_ext_info,true}]} + </code> + </section> + + <section> + <title>Example of modify_algorithms handling</title> + <p>We will now check if the + <seetype marker="ssh#modify_algorithms_common_option">modify_algorithms</seetype> + on a lower level is applied to a + <seetype marker="ssh#preferred_algorithms_common_option">preferred_algorithms</seetype> + on a higher level. We will do that by enabling the <c>ssh-dss</c> + algorithm that is supported, but not in the default set. + </p> + <p>The config file <c>ex3.config</c> has the contents: + </p> + <code> +[ + {ssh, [{modify_algorithms, + [ {prepend, [{public_key, ['ssh-dss']}]} ] + }]} +]. + </code> + <p>A newly started erlang shell shows that no <c>'ssh-dss'</c> is present in the + <c>public_key</c> entry:</p> + <code> +1> proplists:get_value(public_key, ssh:default_algorithms()). +['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521', + 'ecdsa-sha2-nistp256','ssh-ed25519','ssh-ed448', + 'rsa-sha2-256','rsa-sha2-512','ssh-rsa'] +2> + </code> + <p>A call to <c>ssh:connect/3</c> removes all algorithms but one of each type: + </p> + <code> +2> ssh:start(). +ok +3> {ok,C} = ssh:connect(loopback, 22, + [{preferred_algorithms, + [{public_key, ['ecdsa-sha2-nistp256']}, + {kex, ['ecdh-sha2-nistp256']}, + {cipher, ['chacha20-poly1305@openssh.com']}, + {mac, ['hmac-sha2-256']}, + {compression, [none]} + ]} + ]). +{ok,<0.101.0>} +4> ssh:connection_info(C,algorithms). +{algorithms,[{kex,'ecdh-sha2-nistp256'}, + {hkey,'ssh-dss'}, + {send_mac,'chacha20-poly1305@openssh.com'}, + {recv_mac,'chacha20-poly1305@openssh.com'}, + {encrypt,'chacha20-poly1305@openssh.com'}, + {decrypt,'chacha20-poly1305@openssh.com'}, + {compress,none}, + {decompress,none}, + {send_ext_info,false}, + {recv_ext_info,true}]} +5> + </code> + <p>But <c>'ssh-dss'</c> is selected although the call inserted <em>only</em> + <c>'ecdsa-sha2-nistp256'</c> as acceptable. + </p> + <p>This example showed that we could augment the set of algorithms with a + config-file without the need to change the actual call. + </p> + <p>For demonstration purposes we used <c>prepend</c> instead of <c>append</c>. + This forces the negotiation to select <c>ssh-dss</c> since the the full list + of public key algorithms was + <c>['ssh-dss','ecdsa-sha2-nistp256']</c>. + Normally it is safer to append a non-default algorithm. + </p> + </section> + </section> + </section> +</chapter> |