<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged sftp</title>
    <link href="https://passingcuriosity.com/tags/sftp/sftp.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/sftp/sftp.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2014-01-15T00:00:00Z</updated>
    <entry>
    <title>Restricted SFTP-only access to a single directory using OpenSSH</title>
    <link href="https://passingcuriosity.com/2014/openssh-restrict-to-sftp-chroot/" />
    <id>https://passingcuriosity.com/2014/openssh-restrict-to-sftp-chroot/</id>
    <published>2014-01-15T00:00:00Z</published>
    <updated>2014-01-15T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Most UNIX-like operating systems include the <a href="http://openssh.org/">OpenSSH</a> project’s SSH client
and server software. It’s relatively straightforward to configure the OpenSSH
server for a range of usecases. In this post we’ll do the following:</p>
<ul>
<li><p>Create a system group <code>exchangefiles</code>.</p></li>
<li><p>Create a <code>/home/exchangefiles/</code> directory and <code>files/</code> directory within it.</p></li>
<li><p>Allow users in the <code>exchangefiles</code> group to connect to the server using SFTP
(but not SSH).</p></li>
<li><p>Lock users in the <code>exchangefiles</code> group into the <code>/home/exchangefiles/</code>
directory using a chroot.</p></li>
<li><p>Restrict some other options for users in the <code>exchangefiles</code> group.</p></li>
</ul>
<p>So we’ll allow these users to connect to the SSH server and use SFTP to access
a specific directory, <em>and nothing else</em>.</p>
<h2 id="preparations">Preparations</h2>
<p>First, lets create the new group:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> addgroup exchangefiles</span></code></pre></div>
<p>Then create the new directories:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Create the chroot directory</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> mkdir /home/exchangefiles/</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> chmod g+rx /home/exchangefiles/</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="co"># Create the group-writable directory</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> mkdir <span class="at">-p</span> /home/exchangefiles/files/</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> chmod g+rwx /home/exchangefiles/files/</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="co"># Give them both to the new group.</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> chgrp <span class="at">-R</span> exchangefiles /home/exchangefiles/</span></code></pre></div>
<h2 id="sshd-configuration">SSHD configuration</h2>
<p>The OpenSSH server configuration is typically called something like
<code>/etc/ssh/sshd_config</code>. Find this file and open it in an editor. First
we’ll make sure it will support SFTP in a chrooted environment. Search
for a existing <code>Subsystem sftp</code> statement or insert it if it’s missing:</p>
<pre><code># Enable to built-in implementation of SFTP.
Subsystem sftp internal-sftp</code></pre>
<p>Here <code>internal-sftp</code> means “use the SFTP server built into
<code>sshd</code>”. The default on many platforms is to use an external SFTP
implementation (<code>/usr/libexec/sftp-server</code> on Mac OS X or
<code>/usr/libexec/openssh/sftp-server</code> on RedHat-y Linux distros) but this
won’t exist inside the chroot. (Previous versions of this post omitted
discussion of <code>Subsystem</code>; thanks to
<a href="http://www.math.clemson.edu/~mjs/">Matthew Saltzman</a> for suggesting
the improvement.)</p>
<p>Next we’re going to add a section to the <strong>end</strong> of the file using the
<code>Match</code> directive which applies to users in our group:</p>
<pre><code>Match Group exchangefiles</code></pre>
<p>After that we specify the configuration directives which apply the matched
connections:</p>
<pre><code>
# Force the connection to use the built-in SFTP support.
ForceCommand internal-sftp
# Chroot the connection into the specified directory.
ChrootDirectory /home/exchangefiles</code></pre>
<p>Let’s lock down some of the additional capabilities of the OpenSSH server so
these people can’t, e.g., forward connections through the server and into our
private network:</p>
<pre><code># Disable network tunneling
PermitTunnel no
# Disable authentication agent forwarding.
AllowAgentForwarding no
# Disable TCP connection forwarding.
AllowTcpForwarding no
# Disable X11 remote desktop forwarding.
X11Forwarding no</code></pre>
<p>So the whole block looks like this:</p>
<pre><code>Match Group exchangefiles
  # Force the connection to use SFTP and chroot to the required directory.
  ForceCommand internal-sftp
  ChrootDirectory /home/exchangefiles
  # Disable tunneling, authentication agent, TCP and X11 forwarding.
  PermitTunnel no
  AllowAgentForwarding no
  AllowTcpForwarding no
  X11Forwarding no</code></pre>
<h2 id="testing">Testing</h2>
<p>To apply the configuration change, just restart your SSH server, create a user
and try to access the site.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co"># On the server:</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> adduser <span class="at">--ingroup</span> exchangefiles testfiles</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> service ssh restart</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="co"># On a test machine:</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="ex">sftp</span> testfiles@server.example.com</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="fu">ssh</span> testfiles@server.example.com</span></code></pre></div>
<p>Connecting with <code>sftp</code> should result in a connection, but <code>ssh</code> should return
an error message:</p>
<blockquote>
<p>This service allows sftp connections only.</p>
<p>Connection to server.example.com closed.</p>
</blockquote>
<p>When connected you should be able to list, upload and delete files under
<code>/files/</code>.</p>
<h2 id="todo">TODO</h2>
<p>If you’re doing something like this, you probably want the users to be able to
access each other’s files – otherwise why bother sharing a space? To do this
you’ll need to set the umask so that files are created with the correct
permissions.</p>
<p>The <code>internal-sftp</code> command has a <code>-u</code> option which might help, but I haven’t
tested this.</p>
<h2 id="updates">Updates</h2>
<ul>
<li>2015-01-08: Tweaked group write permissions on <code>/home/exchangefiles</code> after
feedback from “Nik”. Thanks Nik!</li>
</ul>]]></summary>
</entry>

</feed>
