<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Bastion Archives - OVHcloud Blog</title>
	<atom:link href="https://blog.ovhcloud.com/tag/the-bastion/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.ovhcloud.com/tag/the-bastion/</link>
	<description>Innovation for Freedom</description>
	<lastBuildDate>Thu, 07 Jan 2021 17:05:51 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.ovhcloud.com/wp-content/uploads/2019/07/cropped-cropped-nouveau-logo-ovh-rebranding-32x32.gif</url>
	<title>The Bastion Archives - OVHcloud Blog</title>
	<link>https://blog.ovhcloud.com/tag/the-bastion/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>The Bastion &#8211; Part 4 &#8211; A new era</title>
		<link>https://blog.ovhcloud.com/the-bastion-part-4-a-new-era/</link>
		
		<dc:creator><![CDATA[Stéphane Lesimple]]></dc:creator>
		<pubDate>Thu, 29 Oct 2020 09:25:56 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[The Bastion]]></category>
		<guid isPermaLink="false">https://www.ovh.com/blog/?p=19446</guid>

					<description><![CDATA[This is the last article in the series about The Bastion. In the previous parts, we covered the principles of The Bastion, and talked about how delegation was at the core of the system. Then we explained how Security was at the heart of the design principles, in a detailed but hopefully not too-long article. [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-bastion-part-4-a-new-era%2F&amp;action_name=The%20Bastion%20%26%238211%3B%20Part%204%20%26%238211%3B%20A%20new%20era&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img fetchpriority="high" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0347-1024x537.png" alt="The Bastion - Part 4 - A new era" class="wp-image-19637" width="768" height="403" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0347-1024x537.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0347-300x157.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0347-768x403.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0347.png 1200w" sizes="(max-width: 768px) 100vw, 768px" /></figure></div>



<p>This is the last article in the series about The Bastion. In the previous parts, we covered <a rel="noreferrer noopener" href="https://www.ovh.com/blog/the-ovhcloud-bastion-part-1/" target="_blank" data-wpel-link="exclude">the principles of The Bastion</a>, and talked about how <a rel="noreferrer noopener" href="https://www.ovh.com/blog/the-ovhcloud-ssh-bastion-part-2-delegation-dizziness/" target="_blank" data-wpel-link="exclude">delegation was at the core of the system</a>. Then we explained how <a rel="noreferrer noopener" href="https://www.ovh.com/blog/the-bastion-part-3-security-at-the-core/" target="_blank" data-wpel-link="exclude">Security was at the heart</a> of the design principles, in a detailed but hopefully not too-long article.</p>



<p>Today, we&#8217;re announcing something special. You might have guessed it already, thanks to the (not so) little breadcrumbs trail we left in the previous articles. Without further ado, and because pictures can say a thousand words on their own:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img decoding="async" width="1024" height="372" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0348-1024x372.png" alt="" class="wp-image-19638" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0348-1024x372.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0348-300x109.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0348-768x279.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0348.png 1221w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>We&#8217;re going open-source! We&#8217;re very excited to share this news with you, and to mark this new milestone in the lifecycle of The Bastion. We think it&#8217;s a perfect reason to bump to the next major version: v3.00.00! Obviously, all previous versions were internal-only.</p>



<p>The code is available at <a rel="noreferrer noopener nofollow external" href="https://github.com/ovh/the-bastion" target="_blank" data-wpel-link="external">GitHub</a>, and we&#8217;re also moving all the non-OVHcloud-specific development there from now on.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img decoding="async" width="612" height="325" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/bastionstats1.png" alt="" class="wp-image-19624" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/bastionstats1.png 612w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/bastionstats1-300x159.png 300w" sizes="(max-width: 612px) 100vw, 612px" /></figure></div>



<p>The <a href="https://ovh.github.io/the-bastion/" target="_blank" rel="noreferrer noopener nofollow external" data-wpel-link="external">documentation</a> is also available online (<a rel="noreferrer noopener nofollow external" href="https://github.com/ovh/the-bastion/tree/master/doc/sphinx" target="_blank" data-wpel-link="external">as well as offline</a> as reStructuredText files), we encourage you to read it. For the most impatient, there is also a docker image available on Docker hub if you want to give it a try: the <em>TL;DR</em> section of <a rel="noreferrer noopener nofollow external" href="https://github.com/ovh/the-bastion/blob/master/README.md" target="_blank" data-wpel-link="external">the <em>README.md</em> on GitHub</a> will get you started.</p>



<p>Many of the more advanced features (such as PIV support, 2FA/MFA support, the notion of <em>realms</em>, the HTTPS proxy, etc.) are not yet fully documented, but all the basics are already there. We will enhance this during the next few weeks/months. A few features are not yet open-sourced either, such as the db plugin we talked about in the previous post. But it&#8217;ll make it to the open-source version eventually.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="598" height="328" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/bastionstats2.png" alt="" class="wp-image-19625" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/bastionstats2.png 598w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/bastionstats2-300x165.png 300w" sizes="auto, (max-width: 598px) 100vw, 598px" /></figure></div>



<p>We hope it&#8217;ll be of use to the community, as much as it is to us, and we can&#8217;t wait to hear from you! The GitHub page is <a href="https://ovh.github.io/the-bastion/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">over here</a>.</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-bastion-part-4-a-new-era%2F&amp;action_name=The%20Bastion%20%26%238211%3B%20Part%204%20%26%238211%3B%20A%20new%20era&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Bastion &#8211; Part 3 &#8211; Security at the core</title>
		<link>https://blog.ovhcloud.com/the-bastion-part-3-security-at-the-core/</link>
		
		<dc:creator><![CDATA[Stéphane Lesimple]]></dc:creator>
		<pubDate>Fri, 23 Oct 2020 15:33:49 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[The Bastion]]></category>
		<guid isPermaLink="false">https://www.ovh.com/blog/?p=19407</guid>

					<description><![CDATA[In previous parts, we&#8217;ve covered the basic principles of the bastion. We then explained how delegation was at the core of the system. This time, we&#8217;ll dig into some governing principles of how The Bastion is written. In a nutshell, the main purpose of the bastion is to ensure security, auditability and reliability in all [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-bastion-part-3-security-at-the-core%2F&amp;action_name=The%20Bastion%20%26%238211%3B%20Part%203%20%26%238211%3B%20Security%20at%20the%20core&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p>In previous parts, we&#8217;ve covered <a href="https://www.ovh.com/blog/the-ovhcloud-bastion-part-1/" data-wpel-link="exclude">the basic principles of the bastion</a>. We then explained how <a href="https://www.ovh.com/blog/the-ovhcloud-ssh-bastion-part-2-delegation-dizziness/" data-wpel-link="exclude">delegation was at the core of the system</a>. This time, we&#8217;ll dig into some governing principles of how The Bastion is written.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0338-1024x537.png" alt="The Bastion - Part 3" class="wp-image-19442" width="768" height="403" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0338-1024x537.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0338-300x157.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0338-768x403.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0338.png 1200w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<p>In a nutshell, the main purpose of the bastion is to ensure <strong>security</strong>, <strong>auditability</strong> and <strong>reliability</strong> in all cases. To this end, the bastion is engineered in a very specific way, with some principles that must be respected when implementing new features. Today we&#8217;re going to zoom in on how one of the functionalities of the bastion has been implemented to ensure an in-depth security. There are technical details ahead, so viewer discretion is advised!</p>



<h3 class="wp-block-heading">The operating system is not just a scheduler</h3>



<p>One of the engineering principles of the bastion is to leverage the underlying operating system&#8217;s security features, as additional guards on top of the code&#8217;s logic itself.</p>



<p>Usually, when developing a program, one doesn&#8217;t really need to think about the OS it&#8217;ll be running on, because all the business logic goes directly into the code. At its basic level, the OS&#8217;s job is to ensure the program runs on top of the hardware it has in charge, by abstracting it, along with the other pieces of software that might be sharing this hardware. In other words, most of the time the OS is mainly a scheduler, whose job is to ensure all the programs are running properly, and don&#8217;t step on each other&#8217;s toes.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0339-1024x423.png" alt="Apps on OS" class="wp-image-19444" width="512" height="212" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0339-1024x423.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0339-300x124.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0339-768x317.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0339.png 1454w" sizes="auto, (max-width: 512px) 100vw, 512px" /></figure>



<p>To this end, an OS has the notion of <strong>user </strong>(or &#8220;account&#8221;), who may be the owner of some running programs and some files on the filesystem, alongside the notion of <strong>group</strong> (of users), so that e.g. a folder can be written to by several users. We&#8217;ll go back to this in a few minutes.</p>



<p>Now, let&#8217;s talk about applications. Most of the time, applications needing to handle users have a database with a &#8220;users&#8221; table, detailing the information about each user. In that case, the application&#8217;s code logic handles all the behaviour the program must have with respect to its users. For example, to authenticate a user, it stores a hash of each user password in the database, and checks whether the entered password&#8217;s hash matches what is stored in the database. If it does, then it deems the user to be successfully logged in. All this logic is entirely expressed in the code, the operating system plays no role in the process whatsoever.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0340-1024x538.png" alt="Application users &amp; OS users" class="wp-image-19447" width="768" height="404" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0340-1024x538.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0340-300x158.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0340-768x404.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0340.png 1267w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<p>There is then, only one operating system user dedicated to the application, regardless of how many users exist in the application&#8217;s database. The application will run under this OS user, and all files logically pertaining to different users in the application&#8217;s functional view, will be owned by this same OS user. It works because the segregation between the functional users is done entirely by the code: even if the application can <em>technically </em>access all its users files, it will only allow, through its code logic, access to the proper files for the proper user.</p>



<h3 class="wp-block-heading">Code has bugs, but it shouldn&#8217;t matter</h3>



<p>Now, let&#8217;s imagine we&#8217;re talking about a program &#8211; let&#8217;s name it <em>MySuperCloudApp</em> &#8211; whose job is to store files for its users, so that they can later fetch them from the cloud. Let&#8217;s imagine there is a flaw in the code (of course, <a href="https://www.cvedetails.com/vulnerability-list/" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">this never happens</a>), which doesn&#8217;t properly escape the user&#8217;s requested file name. If, once logged in as my user, I request a download of the file named <code>myfile.txt</code>, the application will allow it because I&#8217;m logged in. </p>



<p>But what happens if I request <code>../somebodyelse/herfile.txt</code>, instead? If the code hasn&#8217;t been engineered to detect and filter out this weird request, it&#8217;ll just pass the read command to the underlying filesystems, which will allow it because, remember, the application runs under one OS user and all the actual user logic is handled by the application itself. All the application files are owned by the same OS user, so the request seems completely legitimate from an OS standpoint. I&#8217;ve just found a way to steal all the other users files. This type of flaw is called a <a href="https://owasp.org/www-community/attacks/Path_Traversal" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">path traversal</a>, and is, unfortunately, pretty common.</p>



<p>For the bastion, the OS is more than a scheduler: every bastion user is actually mapped to an operating system user underneath. Likewise, every bastion group is mapped to an operating system group underneath. So are all the group roles we&#8217;ve talked about in the previous post. This is a strong design choice: we end up with an application that is deeply intertwined with the OS it&#8217;s running on, and this comes with some cons. However, for a security asset, which the bastion is, the pros vastly outgrow them.</p>



<p>Had <em>MySuperCloudApp </em>have adopted this design, mapping its application users to actual OS users, then the attack we&#8217;ve talked about before wouldn&#8217;t have worked. Even if the application&#8217;s code was flawed, and passed the read request to the OS below, the OS would have denied it, because down at the OS level,&nbsp; <code>../somebodyelse/herfile.txt</code> is <strong>not</strong> owned by the same user. This is where the OS comes to rescue a flawed portion of code (which still needs to be corrected in all cases, of course!).</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0341-1024x610.png" alt="The Bastion users mapped on OS users" class="wp-image-19450" width="768" height="458" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0341-1024x610.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0341-300x179.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0341-768x458.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0341.png 1141w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<p>To take a more Bastion-y example, if a user pertains to <code>groupA</code>, and tricks the code into thinking it also pertains to <code>groupB </code>(because of a flaw in the bastion&#8217;s code logic), then it doesn&#8217;t matter too much because the OS will deny this user access to <code>groupB</code>&#8216;s keys, as he won&#8217;t have access to read the file down to the OS level. So he still won&#8217;t be able to access any of <code>groupB</code>&#8216;s servers. Technically, this is done by offloading the authentication part to <code>sshd</code>, which is well-known and does it quite well. When this phase succeeds, <code>sshd </code>creates a session under the proper OS user, and starts the bastion code entry point under this session.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>We use the OS as an additional safety net in case there is a logic error or a vulnerability in the code: even if the code is tricked into taking bad decisions, the underlying OS will be there to deny the action, hence nullifying the impact.</p></blockquote>



<p>In other words, all the OS bastion users have the bastion code declared as their system shell (instead of the usual <code>/bin/sh</code>). We&#8217;re even going further than that: the code is engineered in such a way that if a user succeeded in getting a real shell on the bastion, i.e. being able to run any command he&#8217;d like on the OS itself, completely bypassing all of the bastion code&#8217;s logic and checks, then he shouldn&#8217;t be able to do much more that what the normal bastion code logic allows him to. That&#8217;s another strong design principle, but helps to drastically reduce the impact of a security vulnerability, should it happen.</p>



<h3 class="wp-block-heading">Trust no one</h3>



<p>For some features to work correctly, the design choices we&#8217;ve outlined above implies that the bastion must sometimes create and delete users on the OS level. This can&#8217;t be done using unprivileged accounts, hence some parts of the code need to run under elevated privileges.</p>



<p>In The Bastion jargon, those portions of the code are called <em>helpers</em>, and are separated from the other portions of the code, normally running under the OS user corresponding to the functional bastion user who&#8217;s running them.</p>



<p>The <em>helpers </em>don&#8217;t trust the rest of the bastion code, so they never blindly trust what is passed as input to them, even if theoretically, this input has already been validated by the bastion code launching the helper. Their higher privilege is granted using the <code>sudo </code>command, with a very strict&nbsp;<code>sudoers </code>configuration which ensures that the caller can only run the helpers it&#8217;s supposed to run, and with the parameters it&#8217;s supposed to be allowed to specify. Once the helper has finished working, it communicates back information to its caller using JSON.</p>



<p>Let&#8217;s take the example of the <code>groupAddServer </code>command. As its name implies, this command is used by a group <code>aclkeeper </code>to add a new server to a bastion group. Let&#8217;s say the user <code>guybrush</code> is a gatekeeper of the bastion group <code>island</code>. On the OS level, the OS user&nbsp;<code>guybrush </code>will be a member of the <code>island-aclkeeper</code> system group. One part of the <code>sudoers </code>configuration will say this:</p>



<pre class="wp-block-code"><code class="">%island-aclkeeper ALL=(island) NOPASSWD: /usr/bin/env perl -T /opt/bastion/bin/helper/osh-groupAddServer --group island *</code></pre>



<p>This line translates to:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>all the members of the <code>island-aclkeeper</code> system group (i.e. all the aclkeepers of the <code>island </code>bastion group) can run, as the <code>island </code>system user, the <code>osh-groupAddServer</code> perl script, in tainted mode, but with the command line options forced to start with <code>--group island</code></p></blockquote>



<p>The <code>island </code>system user is not mapped to a logical user of the bastion, this is a technical account representing the <code>island </code>bastion group. The file listing the servers of the <code>island </code>bastion group is owned by this system user, and only the <code>aclkeepers</code>, through this <code>sudo </code>rule, can impersonate this system user to add a server to their group. Also note, that the Perl taint mode is used here (-T). This is a special mode that instructs Perl to immediately halt execution of the program (here, the <em>helper</em>) if an attempt is made to use a variable influenced (<em>tainted</em>) by the outside environment, without checking for its validity first. This is an additional protection to ensure that an improperly sanitized input can&#8217;t make it through the program&#8217;s execution flow.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="332" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/IMG_0343-1024x332.png" alt="guybrush, bastion and island" class="wp-image-19464" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0343-1024x332.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0343-300x97.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0343-768x249.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0343-1536x498.png 1536w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/IMG_0343.png 1538w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h1 class="wp-block-heading">Going down the rabbit hole with minijail</h1>



<p>For some plugins, we even went one level deeper. For example, we have a plugin to allow users to connect to a PostgreSQL database, using the classic <code>psql </code>client, but directly from the bastion. The idea is that the password to access the database is known to the bastion, not to the user, so the password can be extremely complex, and change every day if necessary. This is completely transparent to the user, who just connects to the bastion and asks to run the database plugin. This scheme is the same than when using SSH on both sides: as seen in the first post of this series, the ingress connection is between the user and the bastion (SSH), and the egress connection is between the bastion and the remote server. The only difference is that, in this case, the egress connection is not SSH, but SQL.</p>



<p>But how to secure <code>psql </code>so that, when running on the bastion, the user can&#8217;t escape from it? The problem is the same with the <code>mysql </code>client. Those programs are engineered to be run from the local computer, where the user can already run any command, so there&#8217;s no real reason to add a configuration option to those programs that forbids local execution of arbitrary commands (shell escape). However on the bastion, we don&#8217;t want to allow that. Of course maintaining a forked version of these SQL clients is a complete no-no, because the time we would allocate to maintaining these forks would be of better use in other projects. Instead, we&#8217;ve used a tool named <a href="https://github.com/google/minijail" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer"><code>minijail</code></a>, whose purpose is to make readily available, to any program, the (not so) recent features from the Linux Kernel &#8211; such as <a href="https://man7.org/linux/man-pages/man7/namespaces.7.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">namespaces</a>, <a href="https://man7.org/linux/man-pages/man7/capabilities.7.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">capabilities</a>, <a href="https://www.kernel.org/doc/html/v4.16/userspace-api/seccomp_filter.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">seccomp</a>, the <a href="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer">no_new_privs</a> <code>prctl()</code> flag, etc. We&#8217;re not going to detail each and every one of these features, there&#8217;s a lot of material online about these, but rather zoom in on how we&#8217;ve used them in the context of The Bastion.</p>



<p>Let&#8217;s start with the conclusion: here is how it looks on the bastion system itself, while somebody is using the database plugin:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/10/screen2.png" alt="Minijail in action" class="wp-image-19457" width="803" height="206" title="Stephane Lesimple &gt; The Bastion - Part 3 - Security at the core &gt; screen2.png" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/10/screen2.png 803w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/screen2-300x77.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/10/screen2-768x197.png 768w" sizes="auto, (max-width: 803px) 100vw, 803px" /></figure></div>



<p>Don&#8217;t Panic yet, let&#8217;s go through this line by line.</p>



<p><span style="text-decoration: underline">The first line</span> (PID <code>16</code>) is the <code>sshd </code>system daemon. Nothing fancy here, this is your usual friendly daemon, listening on port 22 for incoming SSH connections.</p>



<p><span style="text-decoration: underline">The second line</span> (PID <code>413</code>) is the privileged process specially spawned when <code>guybrush </code>logged in successfully on the server. This is also completely standard SSH behavior: when somebody logs in, two <code>sshd </code>processes are spawned by the daemon, a privileged one, and an unprivileged one. Both are dedicated to handling the user, while the parent (the daemon) continues listening for new connections.</p>



<p><span style="text-decoration: underline">The third line</span> (PID <code>417</code>) is the corresponding unprivileged <code>sshd </code>process for <code>guybrush</code>. This one is responsible for starting up <code>guybrush</code>&#8216;s shell as soon as he&#8217;s logged in. Note that from now on, and until further notice, all code is executed under the own user&#8217;s (absence of) privileges.</p>



<p><span style="text-decoration: underline">The fourth line</span> (PID <code>418</code>) is <code>guybrush</code>&#8216;s shell. This is where it&#8217;s starting to differ from your usual server. In this case, the shell is not <code>/bin/bash </code>or <code>/bin/zsh</code>, but a portion of the code of the Bastion. As explained above, the bastion is declared as the user&#8217;s shell, so when somebody logs in, this is what gets executed instead of a more regular POSIX shell. This portion of the code is responsible for parsing the command-line the user specified, and executing the corresponding action, if this action is allowed. In this case, the user passed the <code>-i</code> parameter, which asks the bastion to start in interactive mode. This is a special mode where it&#8217;s easier to launch several bastion commands without having to re-authenticate oneself each time. So, this process is listening for commands from the user. Note that, at this stage, the user has already been authenticated by the system &#8211; as this is completely delegated to <code>sshd</code>. If the authentication fails, the user&#8217;s shell (here, the bastion code) is never executed.</p>



<p><span style="text-decoration: underline">The fifth line</span> (PID <code>497</code>) is the child of the interactive process, re-executing the users shell (<code>osh.pl</code>) with new parameters: <code>--osh db</code>, which will instruct this instance of the shell that the user wants to run the <code>db </code>bastion command.</p>



<p><span style="text-decoration: underline">The sixth line</span> (PID <code>502</code>) is the current bastion command the user is executing. This is the <code>db </code>plugin, and we can see part of the command line: <code>--name lechuck</code>, this tells the plugin that the users wants to connect to the database named <code>lechuck</code>.</p>



<p><span style="text-decoration: underline">The seventh line</span> (PID <code>503</code>) is the <code>ttyrec </code>parent process, as explained in the first post series, the entire console output of the session is being recorded by the bastion &#8211; this process is in charge of doing it.</p>



<p><span style="text-decoration: underline">The eighth line</span> (PID <code>504</code>) is the <code>ttyrec </code>child process, needed for pseudo-tty support, which in turn is needed for the recording. If you <em>really</em> want to know more about <code>pseudo-ttys</code>, head on to <a href="https://www.man7.org/linux/man-pages/man3/openpty.3.html" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer"><code>man openpty</code></a> and/or the <a href="https://github.com/ovh/ovh-ttyrec" data-wpel-link="external" target="_blank" rel="nofollow external noopener noreferrer"><code>ttyrec code</code></a> itself.</p>



<p><span style="text-decoration: underline">The ninth line</span> (PID <code>505</code>) is the <code>sudo </code>call to start <code>minijail</code>. This is needed because <code>minijail </code>needs to be <code>root </code>for a proper setup of the jail, before downgrading itself to an unprivileged account</p>



<p><span style="text-decoration: underline">The tenth line</span> (PID <code>506</code>) is <code>sudo</code>&#8216;s child, this one is in charge of starting the subcommand (<code>minijail </code>in that case)</p>



<p><span style="text-decoration: underline">The eleventh line</span> (PID <code>507</code>) is the invocation of <code>minijail</code>. The complete command line we&#8217;re launching is:</p>



<pre class="wp-block-preformatted"><code>/bin/minijail0 --logging=stderr -u guybrush -g&nbsp;guybrush -n -v --uts -d -P /tmp/chroot-guybrush-psql-wsvhp4 -S /etc/bastion/minijail/db-psql.seccomp -b /lib64 -b /lib -b /usr/lib -b /usr/share -k /home/guybrush/.psql /profile bind 0x10100E rw --set-env HOME=/ --set-env USER=guybrush --set-env LOGNAME=guybrush -- /usr/lib/postgresql/11/bin/psql --pset=pager=off -h dbserver.example.org -p 5432 -U lechuck -- lechuck</code></pre>



<p>Quite a beast. But let&#8217;s go through this step by step.</p>



<p>This tells <code>minijail </code>to setup a new IPC namespace (<code>--uts</code>), and to set the <code>no_new_privs</code> flag (-n), so that any part of the process it creates (and those processes own children) will never ever be able to be root again, no matter what. Under a <code>no_new_privs</code> process, even having a wildcard <code>sudoers </code>file, or knowing the root password and attempting to use <code>su</code>, is not enough to get back to UID <code>0</code>. You just can&#8217;t. </p>



<p>We also ask <code>minijail </code>to create a new mount namespace (-v) then <code>pivot_root</code> (<code>-P</code>) to a temporary empty directory, <code>/tmp/chroot-guybrush-psql-wsvhp4</code>, so that the whole filesystem becomes completely inaccessible. As we still need to be able to run an SQL client in this environment, we <code>bind-mount </code>a few important directories in this new namespace, such as <code>/lib64</code>, <code>/lib</code> and such, and also just one directory in read-write, located into the users&#8217;s own home directory, so that from inside this jail, it can still have its <code>.psql_history</code> and <code>.psqlrc</code> files from past sessions. </p>



<p>We also set a few environments variables, so that the SQL CLI is not lost (<code>HOME</code>, <code>USER</code>, <code>LOGNAME</code>), then setup a seccomp policy on top of all that, to limit which syscalls can be made from this environment. For example, the <code>execve()</code> syscall is forbidden: the SQL CLI can not create any other process, or it&#8217;ll get terminated. Last but not least, when all of this has been set up by <code>minijail</code>, it drops its privileges to the <code>guybrush </code>user (<code>-u</code>) and <code>guybrush </code>group (<code>-g</code>), before executing the <code>psql </code>binary.</p>



<p><span style="text-decoration: underline">The twelfth line</span> (PID <code>508</code>) is the <code>psql </code>process itself, running inside the jail we&#8217;ve built above. This way, it is extremely difficult to escape the <code>psql </code>binary and get out of the jail. The whole setup instantly disappears when the user disconnects. The only remains will be his <code>.psql_history</code> and <code>.psqlrc</code> files. Of course, the <code>ttyrec </code>session record of his SQL usage will remain, too (as executed outside of the jail).</p>



<p>This concludes the post, where we&#8217;ve been detailing how some design principles help in delivering a resilient and secure system. Next week, in the final post of this series, we&#8217;ll be announcing something special. Stay tuned!</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-bastion-part-3-security-at-the-core%2F&amp;action_name=The%20Bastion%20%26%238211%3B%20Part%203%20%26%238211%3B%20Security%20at%20the%20core&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The OVHcloud SSH Bastion – Part 2: delegation dizziness</title>
		<link>https://blog.ovhcloud.com/the-ovhcloud-ssh-bastion-part-2-delegation-dizziness/</link>
		
		<dc:creator><![CDATA[Stéphane Lesimple]]></dc:creator>
		<pubDate>Fri, 11 Sep 2020 15:05:44 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[The Bastion]]></category>
		<guid isPermaLink="false">https://www.ovh.com/blog/?p=18452</guid>

					<description><![CDATA[This is the second part of a blog series, here is part one. We&#8217;ve previously found that the bastion is not your usual SSH jumphost (in fact, we found it is not a jumphost at all) and we discussed how the delegation was one of the core features we&#8217;d originally needed. So, let&#8217;s dive into [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-ovhcloud-ssh-bastion-part-2-delegation-dizziness%2F&amp;action_name=The%20OVHcloud%20SSH%20Bastion%20%E2%80%93%20Part%202%3A%20delegation%20dizziness&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">This is the second part of a blog series, here is <a href="https://www.ovh.com/blog/the-ovhcloud-bastion-part-1/" data-wpel-link="exclude">part one</a>. We&#8217;ve previously found that the bastion is not your usual SSH jumphost (in fact, we found it is not a jumphost at all) and we discussed how the delegation was one of the core features we&#8217;d originally needed. So, let&#8217;s dive into these concepts. There are two compatible accesses models on the bastion: personal and group-based.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/09/IMG_0266-1024x537.png" alt="The OVHcloud Bastion - Part 2" class="wp-image-19254" width="768" height="403" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0266-1024x537.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0266-300x157.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0266-768x403.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0266.png 1200w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<h2 class="wp-block-heading">Personal Accesses &#8211; Piece of Cake</h2>



<p>On the bastion, each account has (at least) one set of <strong>personal egress keys</strong>. These beasts are generated when the account is first created. The personal egress <strong>private key</strong> sits in the bastion account home. The account user has no way to see it, or export it out of the bastion, but they can use it through the bastion&#8217;s code logic. The user can retrieve the corresponding <strong>public key</strong> at any time, and install it &#8211; or get it installed &#8211; on the remote servers he needs to access. Depending on your use case &#8211; and the level of autonomy you want to give to the teams &#8211; there are two ways of managing these personal accesses.</p>



<h3 class="wp-block-heading">Help yourself</h3>



<p>The first way mimics how you would manage accesses if you weren&#8217;t using an SSH bastion at all. This is a perfectly valid way to handle accesses on a simple level, without too many users and a limited number of machines. This allows anyone to grant themselves personal accesses on the bastion, without having to ask anyone else to do it. It sounds like a security hole, but it&#8217;s not. If someone adds themself a personal access to the remote server, it will only work if his personal egress public key has <em>already</em> been installed on the remote server. In other words, he either already had access to the remote server to do this &#8211; using means other than the bastion &#8211; or somebody who had access to the remote server accepted the addition of his key. Either way, he cannot magically grant himself personal access without the admins of the remote server first permitting his key.</p>



<h3 class="wp-block-heading">Ask the IT crowd</h3>



<p>Another way to handle this can be to grant a limited number of people, such as security teams, the right to add personal accesses to others. This way people are less autonomous, but it might be useful if adding accesses has to be enacted via normalized processes. It also has some nice effects: as a sysadmin, one of the pros is that you can create 3 separate accounts on the remote machine, and map them to each bastion account you&#8217;re adding. This is a good method for achieving <strong>end-to-end traceability</strong>; including on the remote server; where you might want to install <strong>auditd</strong> or similar tools. It&#8217;s also doable in the <em>help yourself</em> mode, but it may be harder to enforce.</p>



<p>To be clear, this access model doesn&#8217;t scale so efficiently when we&#8217;re dealing with whole teams, or big infrastructures &#8211; this is where group-based access comes handy.</p>



<h2 class="wp-block-heading">Group Accesses &#8211; Let&#8217;s Rock</h2>



<p>A group has three components:</p>



<ul class="wp-block-list"><li>A list of members (accounts, representing individual people)</li><li>At least one set of group egress keys</li><li>A list of servers (actually IPs)</li></ul>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/09/IMG_0263.png" alt="Bastion - Group" class="wp-image-19249" width="638" height="343" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0263.png 850w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0263-300x161.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0263-768x413.png 768w" sizes="auto, (max-width: 638px) 100vw, 638px" /></figure>



<h3 class="wp-block-heading">Servers list</h3>



<p>The servers list is actually a list of IPs, or IP blocks. They map to your servers, network devices, or anything else with SSH capability that has an IP (on which the egress group key has been installed). Technically, this list is actually composed of 3-tuple items: <em>remote user</em>, <em>remote IP</em> (or IP block), <em>remote port</em>. That which applies to the personal accesses, also applies here: adding a server to the list doesn&#8217;t magically give access to it, it is first necessary to install the <strong>egress group public key</strong>. Of course, managing the installation of these keys manually quickly becomes impractical, but you can consider these part of the configuration of the servers, hence they should be managed with whichever centralized configuration system you already use (Puppet, Chef, Ansible, /bin/cp&#8230; <em>wait, no, strike this last one</em>).</p>



<h3 class="wp-block-heading">Members list</h3>



<p>The members are people who can connect to any server listed in the group server list. They&#8217;ll be using the <strong>private egress group key</strong> they have access to, as members of said group. Of course, they have no way to extract this private key for their own use outside of the bastion, they can only use it through the bastion&#8217;s code logic.</p>



<p>Got a new team member? Just add them as a member of your group, and they instantly get access to all the group servers. Somebody leaves the company? Just delete there account on the bastion, and all the accesses are instantly gone. This is the case because all your servers should have incoming SSH sessions limited to your bastions. This way, any rogue SSH key that would have been added, is no longer of any use.</p>



<h3 class="wp-block-heading">And some more</h3>



<p>We&#8217;ve covered the basics of the group-based approach, but as we need a lot of flexibility and delegation, there is a little more to cover. Remember when I said a group had 3 components? Well, I lied. A group has more than just <em>members</em>. Additional group roles include:</p>



<ul class="wp-block-list"><li>Guests</li><li>Gatekeepers</li><li>Aclkeepers</li><li>Owners</li></ul>



<p>All of these are lists of accounts that have a specific role in the group.</p>



<p>First, <strong>guests</strong>. These are a bit like <strong>members</strong>, but with less privileges: they can connect to remote machines using the group key, but not to all the machines of the group, only to a subset. This is useful when somebody outside of the team needs a specific access to a specific server, potentially for a limited amount of time (as such accesses can be set to expire).</p>



<p>Then, <strong>gatekeepers</strong>. Those guys manage the list of members and guests of the group. In other terms, <em>they have the right to give the right to get access</em>. Nothing too complicated here. Then, there are the <strong>aclkeepers</strong>. As you may have guessed, they manage the list of servers that are part of the group. If you happen to have some automation managing the provisioning of servers of your infrastructure, this role could be granted to a robot account whose sole purpose would be to update the servers list on the bastion, in a completely integrated way with your provisioning. You can even tag such accounts so that they&#8217;ll never be able to use SSH through the bastion, even if somebody grants them by mistake!</p>



<p>Last but not least, the <strong>owners</strong> have the highest privilege level on the group, which means they can manage the gatekeepers, aclkeepers and owners list. They are permitted to give the right<em> to give the right</em> to get access. Moreover, users can accumulate these roles, which means some accounts may be a member and a gatekeeper at the same time, for example.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/09/IMG_0264-1024x833.png" alt="Bastion - Group roles" class="wp-image-19252" width="768" height="625" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0264-1024x833.png 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0264-300x244.png 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0264-768x625.png 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/09/IMG_0264.png 1359w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<h2 class="wp-block-heading">Global roles &#8211; Come Get Some</h2>



<p>Beyond the roles we have just described &#8211; which are all scoped to a group &#8211; there are two additional roles, which are scoped to the whole bastion: the &#8216;superowner&#8217; and the &#8216;bastion admin&#8217;.</p>



<p>In a nutshell, a <strong>superowner</strong> is the implicit owner of all groups present on the bastion. This comes in handy if the group becomes ownerless, as superowners are able to nominate a brand new owner. See where I&#8217;m going? Superowners are permitted<em> </em>to give the right to give the right<em> to give the right to get access</em>.</p>



<p>Dizzy yet? Now, for the most powerful role: the <strong>bastion admin</strong>. This role should only be given to a few individuals, as they can impersonate anyone (even if, of course, when they do, this is logged, and makes our SIEM go red), and in practice should not be given to anyone who is not already root on the bastion&#8217;s operating system itself. Among other things, they manage the configuration of the bastion, where the superowners are declared. Hold your breath. Ready? They are permitted to give the right to give the right to give the right<em> to give the right </em>to get access. This is why delegation is at the core of the system: everybody has their own set of responsibilities, and potential action, without having to ask the bastion admin.</p>



<h2 class="wp-block-heading">Wrapping up</h2>



<p>All the access management concepts we&#8217;ve talked about are mapped to actual commands. These can be run on the bastion after the user has authenticated himself (the famous ingress connection). They&#8217;re called <em>osh commands</em> in bastion jargon. There are no egress connections in this case, as these commands interact with the bastion itself:</p>



<p><img loading="lazy" decoding="async" width="791" height="1373" class="wp-image-19011" style="width: 700px" src="https://www.ovh.com/blog/wp-content/uploads/2020/07/bastion_help.png" alt="" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/07/bastion_help.png 791w, https://blog.ovhcloud.com/wp-content/uploads/2020/07/bastion_help-173x300.png 173w, https://blog.ovhcloud.com/wp-content/uploads/2020/07/bastion_help-590x1024.png 590w, https://blog.ovhcloud.com/wp-content/uploads/2020/07/bastion_help-768x1333.png 768w" sizes="auto, (max-width: 791px) 100vw, 791px" /></p>



<p>As you may notice in the above screenshot, the version of the bastion software seems to be very close to <strong>3.00.00</strong>! Perhaps, an interesting milestone is coming up?</p>



<p>In the next part of this blog series, we dig into some implementation details of one of those <em>osh plugins</em> and, more precisely, on our <a href="https://www.ovh.com/blog/the-bastion-part-3-security-at-the-core/" data-wpel-link="exclude">security  and defense-programming approach</a>.</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-ovhcloud-ssh-bastion-part-2-delegation-dizziness%2F&amp;action_name=The%20OVHcloud%20SSH%20Bastion%20%E2%80%93%20Part%202%3A%20delegation%20dizziness&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The OVHcloud Bastion &#8211; Part 1</title>
		<link>https://blog.ovhcloud.com/the-ovhcloud-bastion-part-1/</link>
		
		<dc:creator><![CDATA[Stéphane Lesimple]]></dc:creator>
		<pubDate>Wed, 03 Jun 2020 13:50:56 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[The Bastion]]></category>
		<guid isPermaLink="false">https://www.ovh.com/blog/?p=18163</guid>

					<description><![CDATA[Bastion? Are we talking about the indie game? Not this time! (albeit it&#8217;s a good game!). At OVHcloud, a fair amount of our infrastructures are built on top of Linux boxes. We have a lot of different flavours; such as Debian, Ubuntu, Red Hat&#8230; and the list goes on. We even had good old Gentoos [&#8230;]<img src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-ovhcloud-bastion-part-1%2F&amp;action_name=The%20OVHcloud%20Bastion%20%26%238211%3B%20Part%201&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="BastionBlogpostDRAFT/PART1-&quot;Bastion&quot;?Arewetalkingabouttheindiegame?"><em>Bastion</em>? Are we talking about the indie game?</h2>



<p>Not this time! (albeit it&#8217;s a good game!).</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" decoding="async" src="https://www.ovh.com/blog/wp-content/uploads/2020/06/E7F04C67-65D2-40A1-A95F-98B2768491BF.jpeg" alt="" class="wp-image-18442" width="312" height="205" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/06/E7F04C67-65D2-40A1-A95F-98B2768491BF.jpeg 416w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/E7F04C67-65D2-40A1-A95F-98B2768491BF-300x197.jpeg 300w" sizes="auto, (max-width: 312px) 100vw, 312px" /></figure></div>



<p>At OVHcloud, a fair amount of our infrastructures are built on top of Linux boxes. We have a lot of different flavours; such as Debian, Ubuntu, Red Hat&#8230; and the list goes on. We even had good old Gentoos once! These are all stored on bare metal servers, on VMs, and in containers everywhere. As long as it has a CPU (or vCPU), we probably booted some kind of Linux distro on it. But that&#8217;s not the whole story. We also had Solaris boxes, that later turned into OmniOS boxes, that have now turned into shiny FreeBSD boxes. We also have a lot of network devices, split against different constructors, spanning a wide range of model generations.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="537" src="https://www.ovh.com/blog/wp-content/uploads/2020/06/4D168231-4B36-4068-B81E-B20315B33227-1024x537.jpeg" alt="" class="wp-image-18446" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/06/4D168231-4B36-4068-B81E-B20315B33227-1024x537.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/4D168231-4B36-4068-B81E-B20315B33227-300x157.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/4D168231-4B36-4068-B81E-B20315B33227-768x403.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/4D168231-4B36-4068-B81E-B20315B33227.jpeg 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>As you&#8217;ve probably guessed, we have heterogeneous systems that are running to provide a handful of different services. But regardless of this heterogeneity, do you know what they all have in common? Yes, they all <em><code>ping</code></em>, but there&#8217;s something more interesting: they can all be administered through <code>ssh</code>.</p>



<h2 class="wp-block-heading" id="BastionBlogpostDRAFT/PART1-Theproblem">The problem</h2>



<p>SSH has been the de-facto admin standard for quite some time now &#8211; replacing obsolete programs such as <code>rlogin</code>, that were happily transferring your password in plaintext over the network &#8211; so we use it all the time, as most of the industry does.</p>



<p><br>There are two regular ways of using it: either you just type your account password when the remote server asks for it, which is more or less like <code>rlogin</code> (without your password transmitted in plaintext over the wire); or you use a public key authentication, by generating a so-called &#8220;keypair&#8221;, with the private key sitting on your desk (or in a smartcard), and the corresponding public key sitting on a remote server.</p>



<p>The issue is that none of these two ways are really satisfactory in an enterprise context.</p>



<h3 class="wp-block-heading">Password authentication</h3>



<p>First, the password way. Well, we all already know that passwords suck. Either you pick one that is too easy to crack, or you pick some very complex one that you&#8217;ll never remember. This forces you to use a password manager that is protected by&#8230; a master password. Even strong passphrases such as &#8220;<a rel="noreferrer noopener nofollow external" href="https://xkcd.com/936/" target="_blank" data-wpel-link="external">Correct Horse Battery Staple</a>&#8220;, are nothing more than an elaborate password in the end. They bring a whole range of problems, such as the fact that they&#8217;re always subject to bruteforce attacks, and some users might get hit by <a rel="noreferrer noopener nofollow external" href="https://xkcd.com/792/" target="_blank" data-wpel-link="external">the password reuse plague</a>. As a sysadmin, you never really sleep well when you know that the security of your systems are just one password away. Of course there are ways to mitigate the risk, such as forcing a periodic password renew, a minimum password length and/or complexity, or disabling an account after several failures, etc. But you&#8217;re just putting additional burden on your users and still not achieving a satisfactory level of security. </p>



<h3 class="wp-block-heading">Public key authentication</h3>



<p>Second, the pubkey way. It goes a long way to fixing password issues, but then the problem becomes scalability. Pushing your public key to your home server is easy, but when you have tens of thousands of servers/devices, as well as thousands of employees, administering some always-changing subset of said servers/devices, it quickly becomes complicated. Indeed, doing it properly and maintaining it in the long-term in an enterprise context is a real challenge.</p>



<h3 class="wp-block-heading">PKI-based authentication</h3>



<p>For the sake of completeness &#8211; because I can hear you from here SSH gurus! &#8211; there is a third way in recent versions of SSH servers, namely authentication based on a PKI with a trusted Certificate Authority (CA). You install the public certificate of your CA on all your servers, and they&#8217;ll accept any connection authenticated by a certificate delivered by said CA, relying on the <code>subjectName</code> of the certificate. This specifies which account can be accessed on the server, among other things. This is a very centralized way of managing your accesses, with all the power in the hands of whoever controls your CA. It can be a highly successful if done very carefully, with a lot of security and processes around the certificates delivery workflows. Managing a CA correctly is no joke and can bite you quite hard if done improperly. This also happens to be a somewhat recent addition to OpenSSH, and given the heterogeneity we outlined above, it would have left a lot of systems on the side. There is also another reason why we haven&#8217;t chosen this method, but before diving into it, let&#8217;s talk about our needs.</p>



<h2 class="wp-block-heading" id="BastionBlogpostDRAFT/PART1-Whatweneeded">What we needed</h2>



<p>At OVHcloud, we have various technical teams that manage their own infrastructure, rather than relying on a generic internal IT department. This principle is part of the company culture and DNA. It does have its drawbacks; such as the added complexity in maintaining an exhaustive and up-to-date inventory of our own assets, but its advantages far outweigh them: multiple teams can iterate faster, as they can use existing OVHcloud products as building blocks to create new, innovative products. This must not, however, come at the cost of security, which is fundamental to everything we do at OVHcloud. </p>



<p>But how did we manage to develop security systems around the SSH management of all these servers without getting in the way of various operational teams?</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="721" src="https://www.ovh.com/blog/wp-content/uploads/2020/06/4F43B5A8-9237-46DF-8DC2-36A1DD94D72D-1024x721.jpeg" alt="" class="wp-image-18489" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/06/4F43B5A8-9237-46DF-8DC2-36A1DD94D72D-1024x721.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/4F43B5A8-9237-46DF-8DC2-36A1DD94D72D-300x211.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/4F43B5A8-9237-46DF-8DC2-36A1DD94D72D-768x541.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/4F43B5A8-9237-46DF-8DC2-36A1DD94D72D.jpeg 1375w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></div>



<p><br>A few important items are required:</p>



<ul class="wp-block-list"><li><strong>DELEGATION</strong><ul><li>Any kind of centralized &#8220;security team&#8221; responsible for handling access clearances for the whole company is a no-go. It doesn&#8217;t scale, no matter how you do it.</li><li>Managers or technical leads should be completely autonomous in managing their own perimeter, in terms of servers/systems/devices, and regarding those persons who are granted access within their perimeter.</li><li>A member from a team moving to another team or out of the company should be a completely seamless process, regardless of the kind of systems this person had access to (remember the heterogeneity above?).</li><li>Giving access to a new team member must also be seamless, so they can get their hands dirty as fast as possible.</li><li>Temporarily granting access to somebody outside of the team (or company) to a given asset for a limited amount of time should be easy.</li><li>All of these actions should be easy to do autonomously</li></ul></li></ul>



<ul class="wp-block-list"><li><strong>AUDITABILITY &amp; TRACEABILITY</strong><ul><li>Every action must be logged with a lot of details; be it a clearance modification, or a connection to a system; whether it&#8217;s successful or not. We also want it to be pushable to some <acronym title="Security Information and Event Management">SIEM</acronym>.</li><li>Every terminal session should be recorded. Yup, you read correctly. This is the kind of feature you don&#8217;t ever need.. until you do.</li><li>It must be easy to generate reports for conducting access reviews.</li></ul></li></ul>



<ul class="wp-block-list"><li><strong>SECURITY &amp; RESILIENCE</strong><ul><li>We must bring more security than a bare direct SSH access, with no additional cost.</li><li>Any component that we have to add to answer those needs must be up and running at all times, even (and especially) when the rest of your infrastructure is falling apart, because that&#8217;s exactly when you&#8217;ll need SSH.</li></ul></li></ul>



<p>So what is the other reason we didn&#8217;t choose the PKI way? Well, this would have limited the autonomy of the team leads: only the CA would be able to deliver or revoke certificates, but we want this power in the hands of our team leads. With the PKI way, if we wanted to give some power to them, we would have had to implement a complex logic around the CA to make this possible, and we didn&#8217;t want to go down this route.</p>



<h2 class="wp-block-heading" id="BastionBlogpostDRAFT/PART1-Enterthebastion!">Enter the bastion!</h2>



<p>To respond to our complex requirements, we have a specialized machine that sits between the admins and the infrastructures &#8211; a bastion &#8211;  whose job it is to handle all the important items above, in addition to the decoupling of the authentication and the authorization phases. We&#8217;ll use public key authentication on both sides. Let&#8217;s take a moment to see a simple example of a connection workflow using this design:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="306" src="https://www.ovh.com/blog/wp-content/uploads/2020/06/253F3120-454D-4A74-A8FE-0EED266E33CE-1024x306.jpeg" alt="" class="wp-image-18433" srcset="https://blog.ovhcloud.com/wp-content/uploads/2020/06/253F3120-454D-4A74-A8FE-0EED266E33CE-1024x306.jpeg 1024w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/253F3120-454D-4A74-A8FE-0EED266E33CE-300x90.jpeg 300w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/253F3120-454D-4A74-A8FE-0EED266E33CE-768x229.jpeg 768w, https://blog.ovhcloud.com/wp-content/uploads/2020/06/253F3120-454D-4A74-A8FE-0EED266E33CE.jpeg 1467w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>An admin wants to connect to a machine named server42</li><li>He can&#8217;t SSH directly from his company laptop to server42 because server42 is firewalled, and only allows incoming SSH connections from the company&#8217;s bastion clusters</li><li>The admin starts an SSH session to the bastion instead, using his nominative account on it. His laptop negotiates the SSH session using his private key. This is the authentication phase: the bastion ensures that the admin presenting himself as John Admin is indeed this person, which is possible thanks to the fact that the public key of John Admin sits inside his bastion account. We call this the *ingress* connection.</li><li>Once John Admin is authenticated, he asks the bastion to open a connection to the root account on server42.</li><li>The bastion verifies whether John Admin is allowed to access the root account on server42, this is the authorization part. Let&#8217;s say for the sake of this example that John Admin is indeed allowed to connect to this server, using his team&#8217;s bastion private key (more details about this later).</li><li>The bastion initiates an SSH connection to server42, on John Admin&#8217;s behalf, using his team&#8217;s bastion private key.</li><li>The firewall of server42 allows incoming SSH connections from the bastion, and the connection is negotiated successfully as the John Admin team&#8217;s bastion public key is installed on server42&#8217;s root account. We call this the *egress* connection.</li></ul>



<p>We now have two established SSH connections: the ingress connection, between John Admin and the bastion, and the egress connection, between the bastion and server42.<br></p>



<p>Now, some magic happens, and the bastion &#8220;plugs&#8221; these two connections together, using a pseudo-terminal (a <code>pty</code>) in between. John Admin is now under the impression that he&#8217;s directly connected to server42, and can interact with it as if this were the case.<br>Meanwhile, the bastion can record everything that is typed by John Admin (or, more accurately, everything that is *seen* by John Admin, we won&#8217;t record passwords he types on <code>noecho</code> terminals!), this is handled by the <code><a rel="noreferrer noopener nofollow external" href="https://github.com/ovh/ovh-ttyrec" target="_blank" data-wpel-link="external">ovh-ttyrec</a></code> program.</p>



<p>To be perfectly clear, server42 doesn&#8217;t know who John Admin is, and doesn&#8217;t need to: we&#8217;ve decoupled the authentication and authorization part. Only the bastion needs to know and authenticate the admin, the remote server only knows and trusts the bastion (or, more accurately, John Admin&#8217;s team existence on the bastion). This opens up a whole range of possibilities&#8230; <a href="https://www.ovh.com/blog/the-ovhcloud-ssh-bastion-part-2-delegation-dizziness/" data-wpel-link="exclude">but more about that in the next post</a>!</p>



<p><em>This post is the first of a series of posts regarding the bastion. In the next posts, we&#8217;ll dig into the authorization part, namely the personal keys and accesses, the groups, and everything that goes along with those. We will also look at the different roles that exist on the bastion to make it so versatile. We&#8217;ll talk about some design choices, and how we want security to be at the centre of these choices &#8211; with some gory technical details.</em> <a href="https://www.ovh.com/blog/the-ovhcloud-ssh-bastion-part-2-delegation-dizziness/" data-wpel-link="exclude"><em>Click here to read the Part 2: Delegation Dizziness</em></a>.</p>
<img loading="lazy" decoding="async" src="//blog.ovhcloud.com/wp-content/plugins/matomo/app/matomo.php?idsite=1&amp;rec=1&amp;url=https%3A%2F%2Fblog.ovhcloud.com%2Fthe-ovhcloud-bastion-part-1%2F&amp;action_name=The%20OVHcloud%20Bastion%20%26%238211%3B%20Part%201&amp;urlref=https%3A%2F%2Fblog.ovhcloud.com%2Ffeed%2F" style="border:0;width:0;height:0" width="0" height="0" alt="" />]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
