blob: c3a8559fa889a55ccbbe355880474fd22f7510ab [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="keywords" content="blogarchitectureconnectivity, ">
<title> Support SSH tunneling for managed connections </title>
<link rel="stylesheet" href="css/syntax.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="css/modern-business.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="css/customstyles.css">
<link rel="stylesheet" href="css/boxshadowproperties.css">
<link rel="stylesheet" href="css/theme-ditto.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" crossorigin="anonymous"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/anchor-js/2.0.0/anchor.min.js" crossorigin="anonymous"></script>
<script src="js/toc.js"></script>
<script src="js/customscripts.js"></script>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Organization",
"url": "https://eclipse.org/ditto/",
"logo": "https://eclipse.org/ditto/images/ditto.svg"
}
</script>
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96">
<link rel="alternate" type="application/rss+xml" title="Eclipse Ditto Blog" href="https://www.eclipse.org/ditto/feed.xml">
<!-- Eclipse Foundation cookie consent: -->
<link rel="stylesheet" type="text/css" href="//www.eclipse.org/eclipse.org-common/themes/solstice/public/stylesheets/vendor/cookieconsent/cookieconsent.min.css" />
<script src="//www.eclipse.org/eclipse.org-common/themes/solstice/public/javascript/vendor/cookieconsent/default.min.js"></script>
<script>
$(document).ready(function() {
$("#tg-sb-link").click(function() {
$("#tg-sb-sidebar").toggle();
$("#tg-sb-content").toggleClass('col-md-9');
$("#tg-sb-content").toggleClass('col-md-12');
$("#tg-sb-icon").toggleClass('fa-toggle-on');
$("#tg-sb-icon").toggleClass('fa-toggle-off');
});
});
</script>
</head>
<script>
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),
dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5WLCZXC');
</script>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container topnavlinks">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-ditto-home" href="index.html">&nbsp;<img src="images/ditto_allwhite_symbolonly.svg" class="ditto-navbar-symbol" alt="Home"> <img src="images/ditto_allwhite_textonly.svg" class="ditto-navbar-symbol-text" alt="Eclipse Ditto™"></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<!-- toggle sidebar button -->
<!--<li><a id="tg-sb-link" href="#"><i id="tg-sb-icon" class="fa fa-toggle-on"></i> Nav</a></li>-->
<!-- entries without drop-downs appear here -->
<li><a href="blog.html">Blog</a></li>
<li><a href="intro-overview.html">Documentation</a></li>
<li><a href="http-api-doc.html">HTTP API</a></li>
<li><a href="sandbox.html">Sandbox</a></li>
<li><a href="https://github.com/eclipse/ditto" target="_blank">
<img src="images/GitHub-Mark-Light-32px.png" alt="Sources at GitHub">
</a></li>
<li><a href="https://github.com/eclipse/ditto-clients" target="_blank">
<img src="images/GitHub-Mark-Light-32px.png" alt="SDK sources at GitHub">SDKs
</a></li>
<li><a href="https://github.com/eclipse/ditto-examples" target="_blank">
<img src="images/GitHub-Mark-Light-32px.png" alt="Example sources at GitHub">examples
</a></li>
<!-- entries with drop-downs appear here -->
<!-- conditional logic to control which topnav appears for the audience defined in the configuration file.-->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Links<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://projects.eclipse.org/projects/iot.ditto" target="_blank">Eclipse Ditto Project</a></li>
<li><a href="https://www.eclipse.org/forums/index.php/f/364/" target="_blank">Forum</a></li>
<li><a href="https://ci.eclipse.org/ditto/" target="_blank">Jenkins</a></li>
<li><a href="https://dev.eclipse.org/mhonarc/lists/ditto-dev/" target="_blank">Mailing list archives</a></li>
<li><a href="https://gitter.im/eclipse/ditto" target="_blank">Gitter.im chat</a></li>
</ul>
</li>
<!--comment out this block if you want to hide search-->
<li>
<!--start search-->
<div id="search-demo-container">
<input type="text" id="search-input" placeholder="search...">
<ul id="results-container"></ul>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/simple-jekyll-search/0.0.9/jekyll-search.js" type="text/javascript"></script>
<script type="text/javascript">
SimpleJekyllSearch.init({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
dataSource: 'search.json',
searchResultTemplate: '<li><a href="{url}" title="Support SSH tunneling for managed connections">{title}</a></li>',
noResultsText: 'No results found.',
limit: 10,
fuzzy: true,
})
</script>
<!--end search-->
</li>
</ul>
</div>
</div>
<!-- /.container -->
</nav>
<!-- Page Content -->
<div class="container">
<div id="main">
<!-- Content Row -->
<div class="row">
<!-- Content Column -->
<div class="col-md-12" id="tg-sb-content">
<!-- Look the author details up from the site config. -->
<!-- Output author details if some exist. -->
<!-- Output author details if some exist. -->
<!---->
<!--<span>-->
<!--&lt;!&ndash; Mugshot. &ndash;&gt;-->
<!--<img src="https://www.gravatar.com/avatar/c6d7916bf0fd9cb08b047602bfc4deab?s=135" alt="A photo of Vadim Günther" />-->
<!--&lt;!&ndash; Personal Info. &ndash;&gt;-->
<!--Written by <a href="https://github.com/VadimGue" target="_blank">Vadim Günther</a>-->
<!--</span>-->
<!---->
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">Support SSH tunneling for managed connections</h1>
<p class="post-meta">Published by <img src="https://www.gravatar.com/avatar/c6d7916bf0fd9cb08b047602bfc4deab?s=135" alt="A photo of Vadim Günther" style="width:50px;border-radius:50%;display:inline-block;margin-right:5px;" /><span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name"><a href="https://github.com/VadimGue" target="_blank">Vadim Günther</a> </span></span> on <time datetime="2021-03-31T00:00:00+00:00" itemprop="datePublished">Mar 31, 2021</time> - Tags:
<a href="tag_blog.html">blog</a>,
<a href="tag_architecture.html">architecture</a>,
<a href="tag_connectivity.html">connectivity</a>
</p>
</header>
<div class="post-content" itemprop="articleBody">
<!-- this handles the automatic toc. use ## for subheads to auto-generate the on-page minitoc. if you use html tags, you must supply an ID for the heading element in order for it to appear in the minitoc. -->
<script>
$( document ).ready(function() {
// Handler for .ready() called.
$('#toc').toc({ minimumHeaders: 0, listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4' });
/* this offset helps account for the space taken up by the floating toolbar. */
$('#toc').on('click', 'a', function() {
var target = $(this.getAttribute('href'))
, scroll_target = target.offset().top
$(window).scrollTop(scroll_target - 10);
return false
})
});
</script>
<div id="toc"></div>
<p>With the upcoming release of Eclipse Ditto <strong>version 2.0.0</strong> it will be possible to</p>
<h1 id="ssh-tunneling-for-managed-connections">SSH tunneling for managed connections</h1>
<p>With the upcoming release of Eclipse Ditto version 2.0.0, managed connections support establishing
an SSH tunnel, which is then used to connect to the actual target endpoint. This is useful when the target endpoint is
not directly accessible. Currently, this feature is available for all connection types supported in Ditto, except for
Kafka 2.x.</p>
<p><img src="images/blog/2021-04-06-ssh-tunnel-for-managed-connections-shema.png" alt="Connection Overview" /></p>
<p>For further information, see <a href="https://tools.ietf.org/html/rfc4254#section-7">Secure Shell (SSH) Connection Protocol, RFC4254</a></p>
<h2 id="setting-up-connections-with-ssh-tunneling-in-ditto">Setting up connections with SSH tunneling in Ditto</h2>
<p>When setting up a tunneled connection, the configuration must specify the <code class="highlighter-rouge">sshTunnel</code> section, which contains
the necessary information to establish the SSH port forwarding. For authentication, password and public
key are supported. Also, host validation using public key fingerprints are supported. The tunnel configuration does not
affect the other parts of your connection configuration. If the feature is enabled the connection will establish an SSH
tunnel and afterwards use this tunnel to connect to the desired endpoint. In case you later disable the SSH tunnel
feature, the payload will be processed directly to the desired endpoint.</p>
<h3 id="basic-authentication">Basic Authentication</h3>
<p>When using basic authenticating the <code class="highlighter-rouge">sshTunnel</code> configuration should contain the <code class="highlighter-rouge">credentials.type</code> <code class="highlighter-rouge">plain</code>, as
well as the <code class="highlighter-rouge">username</code> and <code class="highlighter-rouge">password</code> fields:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tunneled-connection"</span><span class="p">,</span><span class="w">
</span><span class="s2">"connectionType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt"</span><span class="p">,</span><span class="w">
</span><span class="s2">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tcp://mqtt.eclipseprojects.io:1883"</span><span class="p">,</span><span class="w">
</span><span class="s2">"sources"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}],</span><span class="w">
</span><span class="s2">"sshTunnel"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="s2">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ssh://ssh-host:2222"</span><span class="p">,</span><span class="w">
</span><span class="s2">"credentials"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"plain"</span><span class="p">,</span><span class="w">
</span><span class="s2">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"username"</span><span class="p">,</span><span class="w">
</span><span class="s2">"password"</span><span class="p">:</span><span class="w"> </span><span class="s2">"password"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"validateHost"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="s2">"knownHosts"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"MD5:e0:3a:34:1c:68:ed:c6:bc:7c:ca:a8:67:c7:45:2b:19"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="authentication-with-public-key">Authentication with public key</h3>
<p>On public key authentication the <code class="highlighter-rouge">credentials.type</code> is <code class="highlighter-rouge">public-key</code>. In addition to the <code class="highlighter-rouge">username</code> the <code class="highlighter-rouge">publicKey</code> and
<code class="highlighter-rouge">privateKey</code> have to be provided. The public key must be provided as PEM-encoded key in <code class="highlighter-rouge">X.509</code> format. The private
key must be provided as PEM-encoded key in unencrypted <code class="highlighter-rouge">PKCS8</code> format as specified by <a href="https://tools.ietf.org/html/rfc7468">RFC-7468</a>.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tunneled-connection"</span><span class="p">,</span><span class="w">
</span><span class="s2">"connectionType"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mqtt"</span><span class="p">,</span><span class="w">
</span><span class="s2">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tcp://mqtt.eclipseprojects.io:1883"</span><span class="p">,</span><span class="w">
</span><span class="s2">"sources"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="w"> </span><span class="err">...</span><span class="w"> </span><span class="p">}],</span><span class="w">
</span><span class="s2">"sshTunnel"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="s2">"uri"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ssh://ssh-host:2222"</span><span class="p">,</span><span class="w">
</span><span class="s2">"credentials"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"public-key"</span><span class="p">,</span><span class="w">
</span><span class="s2">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"username"</span><span class="p">,</span><span class="w">
</span><span class="s2">"publicKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"-----BEGIN PUBLIC KEY-----</span><span class="se">\n</span><span class="s2">MIIBIjANBgkqhkiG9.....</span><span class="se">\n</span><span class="s2">-----END PUBLIC KEY-----"</span><span class="p">,</span><span class="w">
</span><span class="s2">"privateKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"-----BEGIN PRIVATE KEY-----</span><span class="se">\n</span><span class="s2">MIIEvAIBADANBgkqhki....</span><span class="se">\n</span><span class="s2">-----END PRIVATE KEY-----"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="s2">"validateHost"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="s2">"knownHosts"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"MD5:e0:3a:34:1c:68:ed:c6:bc:7c:ca:a8:67:c7:45:2b:19"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>The following command can be used to convert a standard OpenSSL key in PKCS1 format to the PKCS8 format accepted by Ditto:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>openssl pkcs8 -topk8 -nocrypt -in client-private.pem.key -out client-private.pem.pk8
</code></pre></div></div>
<h3 id="host-validation-using-public-key-fingerprints">Host validation using public key fingerprints</h3>
<p>When <code class="highlighter-rouge">validateHost</code> is enabled, the host public key fingerprints are validated. They can be provided
in the format the standard command line tool <code class="highlighter-rouge">ssh-keygen</code> produces them. The fingerprints are
prefixed with an alias of the hash algorithm that was used to calculate the fingerprint. Ditto supports the following
hash algorithms for public key fingerprints: <code class="highlighter-rouge">MD5</code>, <code class="highlighter-rouge">SHA1</code>, <code class="highlighter-rouge">SHA224</code>, <code class="highlighter-rouge">SHA256</code>, <code class="highlighter-rouge">SHA384</code> and <code class="highlighter-rouge">SHA512</code>. To generate a
valid fingerprint with an <code class="highlighter-rouge">MD5</code> hash algorithm from the public key, following can be used:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -lf id_rsa.pub -E md5
</code></pre></div></div>
<h2 id="feedback">Feedback?</h2>
<p>Please <a href="feedback.html">get in touch</a> if you have feedback or questions regarding this new functionality.</p>
<p><br />
<br /></p>
<figure><img class="docimage" src="images/ditto.svg" alt="Ditto" style="max-width: 500px" /></figure>
<p><br />
The Eclipse Ditto team</p>
</div>
</article>
<hr class="shaded"/>
<footer>
<div class="row">
<div class="col-lg-12 footer">
<div class="logo">
<a href="https://eclipse.org"><img src="images/eclipse_foundation_logo.svg" alt="Eclipse logo"/></a>
</div>
<p class="notice">
&copy;2021 Eclipse Ditto™.
Site last generated: Jul 23, 2021 <br />
</p>
<div class="quickLinks">
<a href="https://www.eclipse.org/legal/privacy.php" target="_blank">
&gt; Privacy Policy
</a>
<a href="https://www.eclipse.org/legal/termsofuse.php" target="_blank">
&gt; Terms of Use
</a>
<a href="https://www.eclipse.org/legal/copyright.php" target="_blank">
&gt; Copyright Agent
</a>
<a href="https://www.eclipse.org/legal" target="_blank">
&gt; Legal
</a>
<a href="https://www.eclipse.org/legal/epl-2.0/" target="_blank">
&gt; License
</a>
<a href="https://eclipse.org/security" target="_blank">
&gt; Report a Vulnerability
</a>
</div>
</div>
</div>
</footer>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
</div>
<!-- /#main -->
</div>
</body>
</html>