<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged linux</title>
    <link href="https://passingcuriosity.com/tags/linux/linux.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/linux/linux.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2023-10-20T00:00:00Z</updated>
    <entry>
    <title>Use Colima to build and run containers on macOS</title>
    <link href="https://passingcuriosity.com/2023/colima-docker-on-mac/" />
    <id>https://passingcuriosity.com/2023/colima-docker-on-mac/</id>
    <published>2023-10-20T00:00:00Z</published>
    <updated>2023-10-20T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>If you use Homebrew to install third-party packages on macOS, it’s
pretty straightforward to install and configure <a href="https://github.com/abiosoft/colima">Colima</a> along
with the various Docker and Kubernetes command-line tools.</p>
<p>First, make sure your Homebrew formulas are all up to date:</p>
<pre><code>brew update</code></pre>
<p>Install Colima along with the Docker and Kubernetes command-line tools:</p>
<pre><code>brew install colima docker kubectl</code></pre>
<p>If you work on a network controlled by an organisation that uses TLS stripping
security appliances you’ll probably need to install additional CA root
certificates before you can pull container images from the Internet, etc. You
can put them in the usual place in your home directory and Colima will
automatically install them in the VMs it starts:</p>
<pre><code>mkdir -p ~/.docker/certs.d
cd ~/.docker/certs.d
curl -o proxy-cert.crt https://insecurity.my.corp/proxy-cert.crt</code></pre>
<p>(Do make sure you put each certificate in a separate file; if they are
concatenated you’ll need to split them.)</p>
<p>With Colima installed, you should be able to start a Colima instance. There are
a handful of options to control the CPU, disk, and memory allocation for the VM,
the runtimes to configure on it, etc.</p>
<pre><code>colima start --memory 8 --kubernetes</code></pre>
<p>Check that the Docker and Kubernetes command-line tools have been configured to
talk to the new Colima instance:</p>
<pre><code>kubectl get pods -A
docker ps</code></pre>
<p>If you installed custom certs, you’d better check that it’s all working
correctly by pulling an image:</p>
<pre><code>docker pull python:3.12-slim</code></pre>
<p>Easy.</p>]]></summary>
</entry>
<entry>
    <title>Installing Python 3.5.1 from source</title>
    <link href="https://passingcuriosity.com/2015/installing-python-from-source/" />
    <id>https://passingcuriosity.com/2015/installing-python-from-source/</id>
    <published>2015-12-30T00:00:00Z</published>
    <updated>2015-12-30T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>This is an introduction to building and installing software from
source on Linux (and other UNIX-like operating systems). The example
is Python 3.5.1 but the details apply to the vast majority of open
source software. I don’t cover everything - mostly just the happy path
of everything working - but if you’ve never installed from source
before, I hope this will help guide you through the process.</p>
<p>Speaking of process, here is what we’ll be doing:</p>
<ol type="1">
<li><p>Download the source code of an official Python release.</p></li>
<li><p>Configure the build appropriately for our machine.</p></li>
<li><p>Compile the software.</p></li>
<li><p>Test the software to make sure it works properly.</p></li>
<li><p>Install the software.</p></li>
<li><p>Configure our system to make sure we can use the software easily.</p></li>
</ol>
<h2 id="getting-a-python-release">Getting a Python release</h2>
<p>Go to the <a href="https://www.python.org/downloads/source/">Python source downloads</a> and choose a version to
download (I’ll use 3.5.1 throughout this document but the process
should be similar for any other version). Download the “Gzipped source
tarball” to your server. You can do this by copying the URL in your
web browser and using the <code>wget</code> command like so:</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">wget</span> https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz</span></code></pre></div>
<p>This will download the release and save it in a file based on the
URL. In our case it’ll be called <code>Python-3.5.1.tgz</code>. If you don’t have
<code>wget</code> installed (maybe you get a <code>command not found</code> error) you can
install it using your OS package manager:</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="fu">sudo</span> yum install wget</span></code></pre></div>
<p>Once the file is downloaded you can unpack it using the <code>tar</code>
command. Originally <code>tar</code> was used with magnetic tape drives (the name
stands for tape archive) but it also works for archives stored in
plain old files on disc and it’s still the standard archive format in
UNIX environments. <code>tar</code> is often used together with <code>gzip</code>
compression to reduce the size of file but all modern <code>tar</code> commands
can handle compression and decompression transparently for you. <code>tar</code>
archives usually have the <code>.tar</code> file extension and often have another
extension for the compression format like <code>.gz</code>, <code>.bz2</code>, or <code>.xz</code> (for
GZipk, BZip2, or XZ respectively). These extensions can be piled on
top of each other like <code>.tar.gz</code> or squashed together into a single
extension like <code>.tgz</code>. You can <em>extract</em> a tar archive <em>file</em>
using the following command:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">tar</span> xf Python-3.5.1.tgz</span></code></pre></div>
<p><code>tar</code>’s argument handling is ancient and unlike almost all other UNIX
programs so you probably needn’t bother learning how the work; just
remember <code>tar xf</code> means “e<strong>x</strong>tract from a <strong>f</strong>ile”. Like most UNIX
programs, <code>tar</code> will not produce any output unless it encounters an
error or you specifically ask it to. If you’d like it to give you some
feedback as it works use <code>tar xvf</code> instead (“e<strong>x</strong>tract <strong>v</strong>erbosely
from a <strong>f</strong>ile”).</p>
<p>You should now have a directory called <code>Python-3.5.1/</code> which contains
the release files. From now on I’ll assume we’re working inside this
new directory:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> Python-3.5.1/</span></code></pre></div>
<h2 id="building-python">Building Python</h2>
<p>Most UNIX software uses a very similar build process:</p>
<ul>
<li><p>first you <em>configure</em> the build with the install location, where to
find any libraries it needs, etc.</p></li>
<li><p>then you <em>compile</em> the software</p></li>
<li><p>then you <em>test</em> the software</p></li>
<li><p>then you <em>install</em> the software</p></li>
</ul>
<p>Each step is usually a single command and the whole process usually
looks a little like this:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./configure</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> test</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> make install</span></code></pre></div>
<p>The <code>./configure</code> command runs the <em>configure script</em> which is
included in most software packages. This is usually an enormous,
automatically generated shell script which figures out how to call
your compiler, where to find the libraries the software needs, where
the new software should be installed, etc. If <code>./configure</code> cannot
find a compiler, a required library, etc. then it will report an
error. You can usually tell which command or library is missing from
the error message but it can be tricky to tell what to do to fix the
problem. Usually it’s a missing library or header file and you can
install the, e.g., <code>foo</code> and <code>foo-devel</code> packages and try to run
<code>./configure</code> again. When I’m feeling too lazy to read the
requirements for a package it’s not unusual to go through this cycle a
few times.</p>
<p>One of the things <code>./configure</code> produces is another large,
automatically generated script called <code>Makefile</code> (often there will be
several of these scattered throughout the subdirectories of the
software). The <code>Makefile</code> contains instructions on how to achive
various tasks like “build” or “make the executable called <code>python</code>” or
“run the test suite”. The <code>Makefile</code> script is executed with the
<code>make</code> command. You can run <code>make</code> to execute the default task
(i.e. the first one in the file) or, e.g., <code>make test</code> to run the
“test” task.</p>
<p>The default task for Python, like most packages, is to compile the
software so running:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
<p>should kick off the build process. For a widely used, well tested
package like Python you should expect <code>make</code> to succeed whenever
<code>./configure</code> does.</p>
<p>Once the build is finished you should run the test suite to make sure
that it all works as expected:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> test</span></code></pre></div>
<p>Again, official Python releases are exceptionally reliable and the
tests can take a long time to run so you might like to give this a
miss.</p>
<h2 id="installing">Installing</h2>
<p>Once it’s built you should install the software into some permanent
location. Almost all packages that follow the <code>./configure</code>, <code>make</code>,
<code>make install</code> convention will install under the <code>/usr/local/</code>
directory by default: they’ll put their executables in
<code>/usr/local/bin/</code>, data files in <code>/usr/local/share/</code>, etc. The
<code>/usr/local/</code> directory is properly considered part of the operating
system (as opposed to part of your user account) so you should require
<code>root</code> privileges to create files and folders there. This is why <code>make install</code> us usually run under <code>sudo</code>:</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="fu">sudo</span> make install</span></code></pre></div>
<p>This will create the directories and copy the compiled files into
place as the <code>root</code> user.</p>
<p>You might like to install it somewhere else. Perhaps you don’t have
<code>root</code> access or you’d like to install multiple versions side-by-side?
In this case you’ll need to change the <code>./configure</code> command you run
at the start to have a <code>--prefix</code> argument:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./configure</span> <span class="at">--prefix</span><span class="op">=</span>/some/other/directory</span></code></pre></div>
<p>If you’ve already used <code>./configure</code> and/or <code>make</code> with the default
settings you can use <code>make clean</code> to wipe out any work it did and
start again. For example, let’s install into the <code>py-351</code> directory
under your account home directory you could run the following command:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> clean</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="ex">./configure</span> <span class="at">--prefix</span><span class="op">=</span><span class="va">$HOME</span>/py-351</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> test</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> install</span></code></pre></div>
<p>Note that you don’t need (and shouldn’t use) <code>sudo</code> to run <code>make install</code> this time because you already own your <code>$HOME</code> directory. If
you run <code>ls $HOME/py-351</code> you should see all the installed files.</p>
<h2 id="using-the-installed-software">Using the installed software</h2>
<p>Now that the software is installed there are a few ways you can use
it; in order of difficulty:</p>
<ul>
<li><p>Specifying the full path</p></li>
<li><p>Changing your <code>$PATH</code> temporarily</p></li>
<li><p>Changing your <code>$PATH</code> permanently</p></li>
</ul>
<p>You can always run a command simply by <em>specifying the full path</em> to
the executable to run. Following on from the <code>$HOME/py-351</code> example
above:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="va">$HOME</span><span class="ex">/py-351/bin/python3</span> <span class="at">-V</span></span></code></pre></div>
<p>should run the newly installed Python interpreter and output the
version message.</p>
<p>If you want to use the new install in <em>just this shell session</em> you
can change your <code>$PATH</code> temporarily:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="va">PATH</span><span class="op">=</span><span class="st">&quot;</span><span class="va">$HOME</span><span class="st">/py-351/bin:</span><span class="va">$PATH</span><span class="st">&quot;</span></span></code></pre></div>
<p>The <code>$PATH</code> variable contains a <code>:</code> separated list of directories to
search for an executable when you run a command in the shell. The
first executable file with the right name is the one that will be
executed. The <code>which</code> command can do this search and tell you which
file will be executed or even give a list of all the options:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="fu">which</span> python3</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="fu">which</span> <span class="at">-a</span> python3</span></code></pre></div>
<p>Notice that we are set <code>PATH</code> to be our installation directory
followed by the current value of <code>$PATH</code>? If we leave the <code>:$PATH</code> off
the end we’ll <em>replace</em> our existing <code>$PATH</code> and the shell will be
able to find <em>only</em> our newly installed Python commands!</p>
<p>If you want your new <code>$PATH</code> setting to be used by all programs that
get started by you shell session (i.e. not <em>just</em> the commands you
manually type in but ones that they start in turn) you’ll need to
<code>export</code> the variable:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="bu">export</span> <span class="va">PATH</span></span></code></pre></div>
<p>For the rest of your current shell session every mention of <code>python3</code>
in the commands you type in or the commands that programs you run
execute for you mean <code>$HOME/py-351/bin/python3</code> (if that file exists).</p>
<p>To make this change permanent you need to change your shell
configuration files. The name of these configuration files and whether
or not they already exist can change from system to system but they
are always in your <code>$HOME</code> directory and are called one or more of the
following:</p>
<ul>
<li><code>.bashrc</code></li>
<li><code>.bash_rc</code></li>
<li><code>.bash_profile</code></li>
<li><code>.profile</code></li>
</ul>
<p>If any of those files already exist in your <code>$HOME</code> directory (files
beginning with a <code>.</code> are considered “hidden” by most UNIX tools,
you’ll need to use <code>ls -a</code> instead of <code>ls</code> to see them) then you
should edit that file. If not, <code>.profile</code> is probably a safe bet.</p>
<p>Create or open the chosen file in a text editor (I’ll describe using
<code>vi</code> or <code>vim</code>) and add the lines you used above to the <em>end</em> of the
file:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="va">PATH</span><span class="op">=</span><span class="st">&quot;</span><span class="va">$HOME</span><span class="st">/py-351/bin:</span><span class="va">$PATH</span><span class="st">&quot;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="bu">export</span> <span class="va">PATH</span></span></code></pre></div>
<p>To edit a file with <code>vim</code> (or <code>vi</code>, for our purposes they are
identical) just pass it the name of the file as an argument:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vim</span> .profile</span></code></pre></div>
<p>Unlike most other editors <code>vim</code> has <em>modes</em>. The most important modes
are <em>command mode</em> (where you give the editor commands like “save” or
“open a new file” or “quite”) and <em>insert mode</em> (where you insert text
into the file). By default <code>vim</code> starts in command mode but you can
enter insert mode by pressing the <code>i</code> key. When you are in insert more
you should see an <code>-- INSERT --</code> on the bottom line of your
terminal. While you are in insert mode you can use the keyboard arrow
keys to navigate and any characters you type should be inserted into
the file. Scroll to the bottom of the file and enter the two new lines
as before. To leave insert more press the escape key on your keyboard;
the <code>-- INSERT --</code> should go away. There are plenty of keyboard
shortcuts you can use in command mode but the easiest way to enter a
command is with the command line which appears when you type a
<code>:</code>. When you do you should notice the cursor jump to the bottom line
of your terminal after a <code>:</code> character. The command to write your
changes to disc and quit <code>vim</code> is <code>wq</code> (just like the shell you end a
command by pressing the enter key).</p>
<p>You should now be able to restart your shell and, if all goes well,
run the <code>python3</code> command without specifying the full path
<code>$HOME/py-351/bin/python3</code>. If it does not work after starting a new
shell (e.g. starting a new terminal or logging in again) try looking
at the output of <code>echo $PATH</code>. If it does not have new value at the
start your shell is probably using one of the other files I listed
above. Try making the same changes to each of them until it does work.</p>
<p>In this section I used the <code>$HOME/py-351</code> prefix but all of these
steps will work for the <code>/usr/local</code> prefix too and, on many systems,
you <em>will</em> need to do them.</p>]]></summary>
</entry>
<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>
