<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://chameth.com/">
    <title>Chameth.com - posts like obfuscating-kotlin-proguard, shoring-up-sshd, why-you-should-be-using-https but not debugging-beyond-the-debugger</title>
    <subtitle>Personal homepage of Chris Smith</subtitle>
    <link href="https://chameth.com/feeds/posts/like/obfuscating-kotlin-proguard,shoring-up-sshd,why-you-should-be-using-https/unlike/debugging-beyond-the-debugger/" rel="self"/>
    <link href="https://chameth.com/"/>
    <icon>https://chameth.com/favicon.png</icon>
    <updated>2019-10-21T00:00:00Z</updated>
    <id>https://chameth.com/</id>
    <author>
        <name>Chris Smith</name>
    </author>
    <entry>
        <title>Obfuscating Kotlin code with ProGuard</title>
        <link href="https://chameth.com/obfuscating-kotlin-proguard/"/>
        <updated>2019-10-21T00:00:00Z</updated>
        <id>https://chameth.com/obfuscating-kotlin-proguard/</id>
        <content xml:lang="en" type="html">&lt;figure class=&#34;image left&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/obfuscating-kotlin-proguard/kotlin-proguard.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/obfuscating-kotlin-proguard/kotlin-proguard.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/obfuscating-kotlin-proguard/kotlin-proguard.png&#34; alt=&#34;Kotlin and Proguard logos&#34; loading=&#34;lazy&#34; width=&#34;343&#34; height=&#34;207&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Kotlin + Proguard = fun&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Obfuscating code is the process of modifying source code or build output in
order to make it harder for humans to understand. It’s often employed as a
tactic to deter reverse engineering of commercial applications or libraries
when you have no choice but to ship binaries or byte code. For Android apps,
&lt;a href=&#34;https://www.guardsquare.com/en/products/proguard&#34;&gt;ProGuard&lt;/a&gt; is part of the
default toolchain and obfuscation is usually only a config switch away.&lt;/p&gt;
&lt;p&gt;I was recently working on an Android library written in Kotlin that my client
wanted obfuscated to try and protect some of their trade secrets that were
included. Not a problem, I thought: it’s just a few lines of ProGuard config
and we’re away. Four hours and lots of hair pulling later I finally got it
working…&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3 id=&#34;if-at-first-you-dont-succeed&#34;&gt;If at first you don’t succeed…&lt;/h3&gt;
&lt;p&gt;At first it seemed like ProGuard was refusing to obfuscate any class with a
&lt;code&gt;keep&lt;/code&gt; rule. With a simple test class:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;chroma-nc&#34;&gt;Test&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;val&lt;/span&gt; &lt;span class=&#34;chroma-py&#34;&gt;secret&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;chroma-mi&#34;&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;chroma-py&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;fun&lt;/span&gt; &lt;span class=&#34;chroma-nf&#34;&gt;greet&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;        &lt;span class=&#34;chroma-n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;Hi &lt;/span&gt;&lt;span class=&#34;chroma-si&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;! Enter a number: &amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;        &lt;span class=&#34;chroma-n&#34;&gt;readLine&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;?.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;guess&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-k&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;toInt&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;fun&lt;/span&gt; &lt;span class=&#34;chroma-nf&#34;&gt;guess&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;attempt&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;        &lt;span class=&#34;chroma-k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;attempt&lt;/span&gt; &lt;span class=&#34;chroma-o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;secret&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;            &lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;Correct!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;        &lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;            &lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;Nope!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;        &lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And a ProGuard rule of:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;-keep public class Test {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    public void greet();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I expected that the &lt;code&gt;Test&lt;/code&gt; class and the &lt;code&gt;greet&lt;/code&gt; method would remain, but both
fields and the &lt;code&gt;guess&lt;/code&gt; method would be obfuscated. When I built the project
and opened the class from Android Studio’s APK inspector I was disappointed:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;chroma-nc&#34;&gt;Test&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;constructor&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;chroma-py&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;kotlin&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;chroma-cm&#34;&gt;/* compiled code */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;val&lt;/span&gt; &lt;span class=&#34;chroma-py&#34;&gt;secret&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;kotlin&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;chroma-cm&#34;&gt;/* compiled code */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;fun&lt;/span&gt; &lt;span class=&#34;chroma-nf&#34;&gt;greet&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;():&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;kotlin&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;Unit&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;chroma-cm&#34;&gt;/* compiled code */&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    &lt;span class=&#34;chroma-k&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;chroma-k&#34;&gt;fun&lt;/span&gt; &lt;span class=&#34;chroma-nf&#34;&gt;guess&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;attempt&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;kotlin&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;):&lt;/span&gt; &lt;span class=&#34;chroma-n&#34;&gt;kotlin&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;Unit&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;chroma-cm&#34;&gt;/* compiled code */&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Having your secret sauce in a field labelled “secret” isn’t exactly the level of
obfuscation I was hoping for. ProGuard has lots of knobs that you can twist to
affect what it keeps and what it renames, but all the incantations of &lt;code&gt;-keep&lt;/code&gt;,
&lt;code&gt;-keepmembernames&lt;/code&gt;, &lt;code&gt;-allowobfuscation&lt;/code&gt;, and so on, that I could come up with
either resulted in the class completely vanishing (because it wasn’t kept) or
showing up with all its symbols intact.&lt;/p&gt;
&lt;p&gt;There are lots of useful Stack Overflow posts describing how to obfuscate
a single method, or keep a single method and obfuscate the rest, but nothing
I tried seemed to make a difference. I’m not the biggest fan of ProGuard, but
I’ve used it enough before to know that it’s not usually that hard to make
it submit to your demands. Obviously something else was going on.&lt;/p&gt;
&lt;h3 id=&#34;-maybe-youre-solving-the-wrong-problem&#34;&gt;… Maybe you’re solving the wrong problem&lt;/h3&gt;
&lt;p&gt;My next thought was that perhaps Android Studio was doing something clever
like reading the ProGuard mapping file and automatically deobfuscating the
output for me. Looking at the mapping file it seems that ProGuard has
indeed decided to rename some things:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;Test -&amp;gt; Test:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    int secret -&amp;gt; a
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    java.lang.String name -&amp;gt; b
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    void greet() -&amp;gt; greet
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    void &amp;lt;init&amp;gt;() -&amp;gt; &amp;lt;init&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The obvious solution is to look at the class file in something less smart
than Android Studio. A couple of unzips later and I could do a quick test
to see if the original names were still present:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;$ strings Test.class | grep secret
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;secret
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem is evidently not with Android Studio, as &lt;code&gt;secret&lt;/code&gt; shouldn’t end
up in the class file at all: it should have been entirely replaced with &lt;code&gt;a&lt;/code&gt; like
the mapping file says. The output from &lt;code&gt;javap -p&lt;/code&gt; doesn’t show any hint of the
original names, however:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;$ javap -p Test
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;public final class Test {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  private final int a;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  private java.lang.String b;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  public final void greet();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  public Test();
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But, given the names show up in &lt;code&gt;strings&lt;/code&gt;, they must be kicking around
somewhere. None of the various outputs from &lt;code&gt;javap&lt;/code&gt; helped until I hit
&lt;code&gt;-verbose&lt;/code&gt;. Right at the end of the class is:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;RuntimeVisibleAnnotations:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  0: #58(#84=[I#2,I#2,I#4],#69=[I#2,I#1,I#3],#81=I#2,#70=[s#40],#71=[s#55,s#39,s#43,s#85,s#39,s#72,s#42,s#91,s#47,s#90,s#39,s#73,s#39,s#74,s#67,s#83])
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    kotlin.Metadata(
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;      mv=[1,1,15]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;      bv=[1,0,3]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;      k=1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;      d1=[&amp;#34;\u0000\&amp;#34;\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0005\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0003\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u0006\u0010\u000b\u001a\u00020\fJ\u0010\u0010\r\u001a\u00020\f2\u0006\u0010\u000e\u001a\u00020\nH\u0002R\u001a\u0010\u0003\u001a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\&amp;#34;\u0004\b\u0007\u0010\bR\u000e\u0010\t\u001a\u00020\nX\u0082D¢\u0006\u0002\n\u0000¨\u0006\u000f&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;      d2=[&amp;#34;LTest;&amp;#34;,&amp;#34;&amp;#34;,&amp;#34;()V&amp;#34;,&amp;#34;name&amp;#34;,&amp;#34;&amp;#34;,&amp;#34;getName&amp;#34;,&amp;#34;()Ljava/lang/String;&amp;#34;,&amp;#34;setName&amp;#34;,&amp;#34;(Ljava/lang/String;)V&amp;#34;,&amp;#34;secret&amp;#34;,&amp;#34;&amp;#34;,&amp;#34;greet&amp;#34;,&amp;#34;&amp;#34;,&amp;#34;guess&amp;#34;,&amp;#34;attempt&amp;#34;,&amp;#34;lib_release&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There’s a Kotlin &lt;em&gt;annotation&lt;/em&gt; containing all of the symbols we were trying to
obfuscate away! Kotlin apparently uses this annotation for reflection and for
keeping track of various language features that don’t have a direct mapping in
Java bytecode (such as members with &lt;code&gt;internal&lt;/code&gt; access). Sure enough, switching
back to Android Studio and making it “decompile” the Kotlin code into Java
shows the annotation:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-nd&#34;&gt;@Metadata&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;mv&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;bv&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;d1&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;\u0000\&amp;#34;\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0005\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0003\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u0006\u0010\u000b\u001a\u00020\fJ\u0010\u0010\r\u001a\u00020\f2\u0006\u0010\u000e\u001a\u00020\nH\u0002R\u001a\u0010\u0003\u001a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\&amp;#34;\u0004\b\u0007\u0010\bR\u000e\u0010\t\u001a\u00020\nX\u0082D¢\u0006\u0002\n\u0000¨\u0006\u000f&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;d2&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;LTest;&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;()V&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;getName&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;()Ljava/lang/String;&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;setName&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;(Ljava/lang/String;)V&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;secret&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;greet&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;guess&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;attempt&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;lib_release&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;chroma-nc&#34;&gt;Test&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;solving-the-right-problem&#34;&gt;Solving the right problem&lt;/h3&gt;
&lt;p&gt;Now I had an idea of what was happening I was able to find a couple of other
reports of people having the same issue. There’s an open
&lt;a href=&#34;https://sourceforge.net/p/proguard/feature-requests/182/&#34;&gt;feature request for ProGuard to support Kotlin’s metadata annotation&lt;/a&gt;
but it’s not yet supported.&lt;/p&gt;
&lt;p&gt;As this was a library with a fairly straight forward interface I reasoned I
could probably get ProGuard to strip out the metadata annotation. If I stopped
Kotlin reflection working in the process then that would actually be a small
bonus. Unfortunately other people with the same idea had reported back that
they were unsuccessful: even when not using the default ProGuard config,
somehow the annotations are kept.&lt;/p&gt;
&lt;p&gt;Adding a &lt;code&gt;-printconfiguration&lt;/code&gt; instruction to my configuration lets me see
the full configuration being passed to ProGuard, and the reason for keeping
quickly becomes obvious:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;-keepattributes *Annotation*,*Annotation*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This appears to be added by the Android build plugin before it invokes
ProGuard, and there’s no obvious way to disable it. ProGuard doesn’t offer
a way to reverse this instruction, either, but fortunately the build plugin
seems to concatenate all of the &lt;code&gt;-keepattribute&lt;/code&gt; values together and puts our
user-supplied ones first. Adding a negative filter:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;-keepattributes !*Annotation*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Results in the following in the printed configuration:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;-keepattributes !*Annotation*,*Annotation*,*Annotation*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The negative filter prevents any subsequent filters from matching. Recompiling
and looking at the class file again looks a lot more sensible:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nn&#34;&gt;kotlin.io.ConsoleKt&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;chroma-nc&#34;&gt;Test&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;123&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;private&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;Chris&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;final&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nf&#34;&gt;greet&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var1&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;Hi &amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;! Enter a number: &amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var10000&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;ConsoleKt&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;readLine&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;chroma-k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var10000&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var1&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var10000&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;chroma-kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var3&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;parseInt&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var1&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var3&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;123&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;Correct!&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s&#34;&gt;&amp;#34;Nope!&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-na&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-n&#34;&gt;var1&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that’s the story of how I spent half a day making a one line change.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>Shoring up SSHd configuration</title>
        <link href="https://chameth.com/shoring-up-sshd/"/>
        <updated>2016-10-18T00:00:00Z</updated>
        <id>https://chameth.com/shoring-up-sshd/</id>
        <content xml:lang="en" type="html">&lt;p&gt;I recently came across a useful tool on GitHub called
&lt;a href=&#34;https://github.com/arthepsy/ssh-audit&#34;&gt;ssh-audit&lt;/a&gt;. It’s a small Python script
that connects to an SSH server, gathers a bunch of information, and then
highlights any problems it has detected. The problems it reports range from
potentially weak algorithms right up to know remote code execution
vulnerabilities.&lt;/p&gt;
&lt;p&gt;This is the kind of output you get when running ssh-audit. In this particular
example, I’m looking at GitHub’s SSH server and have filtered the output to
just warnings and failures:&lt;/p&gt;
&lt;!--more--&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/shoring-up-sshd/ssh-audit-github.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/shoring-up-sshd/ssh-audit-github.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/shoring-up-sshd/ssh-audit-github.png&#34; alt=&#34;Output of ssh-audit pointing at GitHub&amp;#39;s SSH servers&#34; loading=&#34;lazy&#34; width=&#34;1042&#34; height=&#34;791&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Output of ssh-audit pointing at GitHub’s SSH servers&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;GitHub’s a bit of a special case, as they’re trying to cope with scores of
developers pushing code: they can’t disable weaker algorithms without also
stopping lots of people being able to use their service. Still, from the
output you can see that ssh-audit has spotted a known vulnerability
(&lt;a href=&#34;http://cve.circl.lu/cve/CVE-2016-0739&#34;&gt;CVE-2016-076&lt;/a&gt;) and has a lot to
say about the various types of supported algorithms.&lt;/p&gt;
&lt;h3 id=&#34;background-crypto-algorithms-used-by-ssh&#34;&gt;Background: crypto algorithms used by SSH&lt;/h3&gt;
&lt;p&gt;Establishing an SSH connection is a moderately complex endeavour, and various
parts involve the use of a number of different cryptographic algorithms:&lt;/p&gt;
&lt;p&gt;The first such algorithm is the &lt;em&gt;key exchange algorithm&lt;/em&gt;. This is the process
by which the client and the server &lt;a href=&#34;https://en.wikipedia.org/wiki/Key-agreement_protocol&#34;&gt;agree on a shared key&lt;/a&gt;
that will be used later. Next comes the &lt;em&gt;host-key algorithm&lt;/em&gt;;
this is how the server proves its identity to the client. Most SSH users
will be familiar with warnings like the following:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;$ ssh server.example.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;The authenticity of host &amp;#39;server.example.com (11.22.33.444)&amp;#39; can&amp;#39;t be established.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;ED25519 key fingerprint is SHA256:rPVMho1fhEkJqvgce/8iAl353dX5QkGT9F3uCFndsa.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;Are you sure you want to continue connecting (yes/no)?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The warning means that the SSH client doesn’t recognise the server’s key, and
is asking the user to confirm it. If the key changes later, the SSH client
will refuse to connect. In the warning above you can see the algorithm used
by the server was &lt;code&gt;ED25519&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next up is the &lt;em&gt;encryption algorithm&lt;/em&gt;, which handles actually encrypting the
data sent over the connection. Finally comes the &lt;em&gt;message authentication code
algorithm&lt;/em&gt;, commonly referred to as ‘mac’. The mac algorithm is effectively
responsible for signing each message as a proof that it came from the other
party.&lt;/p&gt;
&lt;h3 id=&#34;following-the-recommendations&#34;&gt;Following the recommendations&lt;/h3&gt;
&lt;p&gt;ssh-audit’s recommendations are pretty easy to follow. It points and shouts
at a particular algorithm, and you configure SSHd to not allow it. This is
a snippet from my new SSHd config, which gets no complaints from ssh-audit:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;HostKey /etc/ssh/ssh_host_rsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;HostKey /etc/ssh/ssh_host_ed25519_key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;KexAlgorithms curve25519-sha256@libssh.org
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What’s more interesting is the reasoning behind some of the algorithms removed.
The &lt;code&gt;ecdh-sha2-nistp&lt;/code&gt; series of key exchange algorithms are subject to a
sidechannel attack described &lt;a href=&#34;https://eprint.iacr.org/2014/161.pdf&#34;&gt;in a paper in 2014&lt;/a&gt;.
Some people are also concerned about the involvement of NIST, and the
potential for backdoors. Various other key exchange algorithms
use too small a number of bits in the key exchange (e.g.
&lt;code&gt;diffie-hellman-group1-sha1&lt;/code&gt;, which uses 1024). Others still use known-bad hash
algorithms (e.g. &lt;code&gt;diffie-hellman-group14-sha1&lt;/code&gt;, which uses an acceptable 2048
bit modulus, but relies on SHA1 hashes). ssh-audit only treats the use of SHA1
as a warning, but there’s no compelling reason to keep it around if you’re
using remotely modern clients to connect. Similarly the host-key DSA algorithm
uses a 1024 bit key, so should be disabled.&lt;/p&gt;
&lt;p&gt;Many of the rejected encryption algorithms use basically-broken algorithms
(&lt;code&gt;3des-cbc&lt;/code&gt; and &lt;code&gt;arcfour&lt;/code&gt; for example). Some of the remaining are block ciphers
with small block sizes, which makes them weak (e.g. &lt;code&gt;blockfish-cbc&lt;/code&gt; uses a
block size of 64 bits).&lt;/p&gt;
&lt;p&gt;Many of these concerns also apply to mac algorithms (e.g. eliminating
&lt;code&gt;hmac-md5&lt;/code&gt;, &lt;code&gt;hmac-sha1-etm@openssh.com&lt;/code&gt;, etc, as they use weak hash algos).
Of particular note, OpenSSH supports the &lt;code&gt;hmac-ripemd160&lt;/code&gt; and
&lt;code&gt;hmac-ripemd160-etm@openssh.com&lt;/code&gt; algorithms. RIPEMD160 isn’t that common but,
like SHA1, is considered to be weak. One other concern with mac algorithms is
the order in which the encryption and mac attachment are performed.
Encrypt-then-mac is the preferred way of doing it (i.e., the message is
encrypted, then a MAC of the ciphertext is attached). The default used in SSH
is encrypt-and-mac, where the mac of the &lt;em&gt;plaintext&lt;/em&gt; is attached after
encryption. Attaching the plaintext mac potentially leaks information (a mac
is designed to provide integrity, not confidentiality, after all). The
encrypt-then-mac algorithms are indicated by the &lt;code&gt;-etm&lt;/code&gt; suffix.&lt;/p&gt;
&lt;h3 id=&#34;other-changes&#34;&gt;Other changes&lt;/h3&gt;
&lt;p&gt;In addition to the ssh-audit inspired changes, I took the time to review the
rest of my standard SSH configuration. The config touches on a few areas; I’m
only going to highlight a couple of them:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  PubkeyAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  RhostsRSAAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  HostbasedAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  ChallengeResponseAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  PasswordAuthentication no
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here all authentication methods other than public key are disabled. A
decent key (used in combination with good crypto algorithms!) is drastically
harder to brute force than a very good password. It’s also less prone to
accidentally being copied into the wrong place, provided to the wrong server,
etc.&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-gd&#34;&gt;- UsePrivilegeSeparation yes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-gi&#34;&gt;+ UsePrivilegeSeparation sandbox
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Switching &lt;code&gt;UsePrivilegeSeparation&lt;/code&gt; from ‘yes’ to ‘sandbox’ tells OpenSSH to
employ kernel sandbox mechanisms on the unprivileged process. This adds another
layer of defence in case there’s a severe exploit in OpenSSH itself.&lt;/p&gt;
&lt;h3 id=&#34;an-unexpected-side-effect&#34;&gt;An unexpected side effect&lt;/h3&gt;
&lt;p&gt;After reconfiguring OpenSSH, all of my servers stopped reporting SSH brute
force attempts. Every day prior to the change saw hundreds of connections and,
after rate limiting and automatic banning blocked a fair chunk, about two dozen
unsuccessful login attempts. With the new algorithm selections in place, there
were still hundreds of connections, but no failed login attempts at all. A
closer look at the logs showed this:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;fatal: Unable to negotiate with 1.2.3.4 port 55025:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;  no matching key exchange method found. Their offer:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    diffie-hellman-group14-sha1,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    diffie-hellman-group-exchange-sha1,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;    diffie-hellman-group1-sha1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Apparently not a single one of the clients trying to bruteforce their way in
supported the one key exchange algorithm I now allow. I guess at some point
they’ll be updated with a modern crypto stack, but until then it’s going to be
oddly peaceful…&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>Why you should be using HTTPS</title>
        <link href="https://chameth.com/why-you-should-be-using-https/"/>
        <updated>2016-06-17T00:00:00Z</updated>
        <id>https://chameth.com/why-you-should-be-using-https/</id>
        <content xml:lang="en" type="html">&lt;figure class=&#34;image left&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/why-you-should-be-using-https/https-everywhere.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/why-you-should-be-using-https/https-everywhere.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/why-you-should-be-using-https/https-everywhere.jpg&#34; alt=&#34;The EFF&amp;#39;s HTTPS Everywhere logo&#34; loading=&#34;lazy&#34; width=&#34;300&#34; height=&#34;260&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;The EFF’s HTTPS Everywhere logo&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of my favourite hobbyhorses recently has been the use of HTTPS, or lack thereof. HTTPS is the
thing that makes the little padlock appear in your browser, and has existed for over 20 years.
In the past, that little padlock was the exclusive preserve of banks and other ‘high security’
establishments; over time its use has gradually expanded to most (but not all) websites
that handle user information, and the time is now right for it to become ubiquitous.&lt;/p&gt;
&lt;h3 id=&#34;why-use-https&#34;&gt;Why use HTTPS?&lt;/h3&gt;
&lt;p&gt;There are numerous advantages to using HTTPS, both for the users of a website and for the
operator:&lt;/p&gt;
&lt;h4 id=&#34;privacy&#34;&gt;Privacy&lt;/h4&gt;
&lt;p&gt;The most obvious advantage is that HTTPS gives your users additional privacy. An insecure (HTTP)
request can potentially be read by anyone on the same network, or the network operators, or anyone
who happens to operate a network along the path between the user and the server.&lt;/p&gt;
&lt;p&gt;Users on shared WiFi networks (such as those in coffee shops, hotels, or offices) are particularly
vulnerable to passive sniffing by anyone else on that network. If the network is open (as is
frequently the case) then anyone in radio range can see exactly what the user is up to.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h4 id=&#34;integrity&#34;&gt;Integrity&lt;/h4&gt;
&lt;p&gt;HTTPS also helps to maintain the integrity of your site. With a plain HTTP request, there’s nothing
to stop anyone in between the server and the user from modifying the content of the request or the
response. This is a frequent tactic used by annoying WiFi gateways (such as the ones &lt;a href=&#34;http://justinsomnia.org/2012/04/hotel-wifi-javascript-injection/&#34;&gt;you’d find in
a hotel&lt;/a&gt;), dubious ISPs who want
to serve you extra adverts, or just plain old nefarious attackers.&lt;/p&gt;
&lt;p&gt;If you’re trying to convey some kind of information to users (and if you aren’t, why exactly are
you running a website again?) it seems beneficial to both you and them if the information arrives
as you intended, rather than in a modified form due to someone or something tampering with it.&lt;/p&gt;
&lt;h4 id=&#34;security&#34;&gt;Security&lt;/h4&gt;
&lt;p&gt;If your website has any kind of authentication, or session identifiers, it becomes extremely
vulnerable to an attacker monitoring the traffic and stealing the credentials. This was
starkly demonstrated in 2010 when &lt;a href=&#34;https://en.wikipedia.org/wiki/Firesheep&#34;&gt;Firesheep&lt;/a&gt; was
released. This tool allowed anyone to quickly and automatically hijack social media accounts of
anyone on the same network who was using HTTP to access them.&lt;/p&gt;
&lt;p&gt;Even if your login pages are served over HTTPS, if you send a single session ID cookie over HTTP
(such as a page you decided wasn’t particularly ‘important’) then an attacker can probably spoof
the user’s session and gain full access to their account.  Again, in the case of open WiFi networks
that could be anyone in radio range.&lt;/p&gt;
&lt;h4 id=&#34;search-engine-rankings&#34;&gt;Search engine rankings&lt;/h4&gt;
&lt;p&gt;Some search engines use HTTPS as a signal in their ranking algorithms. &lt;a href=&#34;https://security.googleblog.com/2014/08/https-as-ranking-signal_6.html&#34;&gt;Google announced in
2004&lt;/a&gt; that it was using
the presence of HTTPS as a small positive signal, but that it may strengthen that signal over time
as more and more websites switch to using a secure transport. It’s not unthinkable that at some
point in the future there will be HTTPS-only search engines.&lt;/p&gt;
&lt;h3 id=&#34;but-but-but&#34;&gt;But… But… But…&lt;/h3&gt;
&lt;p&gt;There are lots of excuses for not implementing HTTPS. Most of them are either misguided or outdated.&lt;/p&gt;
&lt;h4 id=&#34;its-too-expensive-andor-complicated&#34;&gt;It’s too expensive and/or complicated&lt;/h4&gt;
&lt;p&gt;In the past, getting HTTPS certificates was a pain. A number of free suppliers have existed for
a while but the process for getting their certificates wasn’t particularly straight forward, and
many imposed arbitrary restrictions on the certificate parameters. Even once you had the
certificate, you had to fiddle about with your HTTP server configuration to make it work, remember
to manually get a new certificate when the old one expired, and lots of other annoying busywork.&lt;/p&gt;
&lt;p&gt;With the arrival of &lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let’s Encrypt&lt;/a&gt;, all that changed. You can retrieve
and deploy a free HTTPS certificate with two or three commands. Renewal can be handled completely
automatically with a single command executed by cron.&lt;/p&gt;
&lt;h4 id=&#34;theres-no-point-nothing-on-my-site-is-sensitive&#34;&gt;There’s no point; nothing on my site is sensitive&lt;/h4&gt;
&lt;p&gt;You might not think your content warrants privacy, but can you speak for everyone who accesses it?
Even content that seems mundane to you — such as travel advice, or technical writing — could be
used to build up a profile of a user. If an attacker is monitoring traffic in a coffee shop and
sees a user looking at travel advice and weather forecasts for a foreign country, he could use that
information to plan a burglary knowing that the user will be away. Similarly, some content which
is perfectly mundane to you may actually be very sensitive in other countries with repressive
governments. HTTPS makes it much harder for these people to snoop on traffic.&lt;/p&gt;
&lt;p&gt;From another angle, if you’re offering any kind of information, instructions, or especially file
downloads, there’s a severe risk to users if the content is modified on its way to them. An evil
sysadmin could rewrite your travel advice to suggest visiting the local drug dealer’s hangout, or
replace your download with a malware-infested version.&lt;/p&gt;
&lt;h4 id=&#34;https-is-slower-uses-more-resources-etc&#34;&gt;HTTPS is slower, uses more resources, etc&lt;/h4&gt;
&lt;p&gt;Back in 1995 this might have been a valid argument. Enabling HTTPS on a modern server will make
an almost negligible difference to performance. If you also enable HTTP/2 (which most
implementations only support over HTTPS), it’s likely to actually use fewer resources, and result
in a faster, smoother experience for your users. HTTP/2 was designed to work with HTTPS, and
designed with modern requirements and networking techniques in mind.&lt;/p&gt;
&lt;p&gt;CloudFlare have an &lt;a href=&#34;https://www.cloudflare.com/http2/&#34;&gt;excellent demonstration&lt;/a&gt; of the benefits of
HTTP/2, and it can show speed improvements of 2-3x in a typical environment. On top of being faster,
HTTP/2 uses fewer connections which results in less resource overhead on both the server and the
client.&lt;/p&gt;
&lt;h3 id=&#34;so-what-are-you-waiting-for&#34;&gt;So what are you waiting for?&lt;/h3&gt;
&lt;p&gt;If you run a website and aren’t using HTTPS, &lt;a href=&#34;https://certbot.eff.org/&#34;&gt;give it a try&lt;/a&gt;.&lt;/p&gt;
</content>
    </entry>
</feed>
