<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://tom.busby.ninja/feed.xml" rel="self" type="application/atom+xml" /><link href="https://tom.busby.ninja/" rel="alternate" type="text/html" /><updated>2022-02-20T23:03:56+00:00</updated><id>https://tom.busby.ninja/feed.xml</id><title type="html">Tom Busby</title><subtitle>A man who writes about computing stuff</subtitle><entry><title type="html">Setting Up a ZNC IRC Bouncer to Use Tor</title><link href="https://tom.busby.ninja/setting-up-znc-IRC-bouncer-to-use-tor/" rel="alternate" type="text/html" title="Setting Up a ZNC IRC Bouncer to Use Tor" /><published>2019-08-04T23:47:00+00:00</published><updated>2019-08-04T23:47:00+00:00</updated><id>https://tom.busby.ninja/setting-up-znc-IRC-bouncer-to-use-tor</id><content type="html" xml:base="https://tom.busby.ninja/setting-up-znc-IRC-bouncer-to-use-tor/">&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;I’m at least partially writing this as an aid to my own memory. It took me a little while to muddle through and get everything set up. I recently had to do part of the process again and struggled to remember. Writing this blog post seems like a good way to help my future self and others looking to do the same thing.&lt;/p&gt;

&lt;p&gt;I’m going to assume that you want your bouncer to connect to Freenode. The steps should be fairly similar for other IRC servers.&lt;/p&gt;

&lt;h4 id=&quot;znc&quot;&gt;ZNC&lt;/h4&gt;

&lt;p&gt;Why use a bouncer at all? Couldn’t I just directly connect to the IRC server?&lt;/p&gt;

&lt;p&gt;Yes, you could. The disadvantage is that you will not receive messages sent while you were away. For some channels you may not want to miss a single message. For others, you may just want the last 50 messages so that you have the context of the conversation that you just entered.&lt;/p&gt;

&lt;p&gt;Another advantage of a bouncer is that we can also set up “client buffers”. These are separate buffers for the different clients that you may connect from. This ensures that if I connect from my desktop’s IRC client, then my laptop, the messages will be replayed correctly for both.&lt;/p&gt;

&lt;p&gt;This is similar to the problem that IMAP email solves. Emails are synced accross devices these days. In the 90s, we used POP3. This pulled emails from the server; clearing the buffer in the process. This meant that (in the standard configuration), if you had two devices, your emails would be split accross them. If an email was pulled to your laptop then it wouldn’t be pulled to your desktop later.&lt;/p&gt;

&lt;h4 id=&quot;tor&quot;&gt;Tor&lt;/h4&gt;

&lt;p&gt;When using IRC, we tend to leak quite a lot of information about the hostname we’re connecting from. This is somewhat undesirable if you’re connecting directly or self-hosting an IRC bouncer, since it may make you a target for people probing for vulnerabilities. Generally speaking, revealing your hostname and/or IP address publicly when engaging in an online community is best avoided if possible.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-your-freenode-account&quot;&gt;Setting Up Your Freenode Account&lt;/h2&gt;

&lt;p&gt;Firstly, we need to set up a Freenode account. We will be directly connecting to Freenode from the IRC client (without using a bouncer) for this step. The ultra-paranoid may want to connect to a VPN (or perhaps take their laptop to a coffee shop) before doing this step. This is to prevent your true origin IP ever being leaked.&lt;/p&gt;

&lt;p&gt;We will be using &lt;a href=&quot;https://weechat.org/&quot;&gt;Weechat&lt;/a&gt; as our IRC client since it’s free/open-source and cross-platform.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you’re using a different IRC client, this tutorial will still be fairly applicable to you but you’ll need to look up how to achieve the same things with your client. &lt;a href=&quot;https://wiki.znc.in/Category:Clients&quot;&gt;This page&lt;/a&gt; may be of assistance. If you use Textual, &lt;a href=&quot;https://help.codeux.com/textual/Connecting-to-ZNC-Bouncer.kb&quot;&gt;this page&lt;/a&gt; helped me get set up.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To install on OSX (with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew&lt;/code&gt;):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;weechat&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To install on a Debian-based Linux (such as Ubuntu):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; weechat&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For other OSes, either install from source or look up weechat in your system’s package manager.&lt;/p&gt;

&lt;p&gt;Next launch weechat by entering &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;weechat&lt;/code&gt; at the terminal.&lt;/p&gt;

&lt;p&gt;The program will launch and you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/01-weechat.png&quot; alt=&quot;Weechat&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You’ll notice that you have a prompt at the bottom of the terminal window. We’re going to use that to set up our connection with freenode:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/server add freenode-direct chat.freenode.net/6697 -ssl
/set irc.server.freenode-direct.nicks &quot;zncblogpost,_zncblogpost&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Note: if you don’t want to manually connect each time time you run weechat, you can set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-autoconnect&lt;/code&gt; flag when adding the server config. For the purposes of this tutorial, I recommend leaving autoconnect off for any connections we create until everything is set up.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After executing these two commands you should see similar output to the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/02-network-added.png&quot; alt=&quot;Network added&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can specify multiple comma-separated names. These will be tried in order and your nick will be the first name in the list that isn’t already in use.&lt;/p&gt;

&lt;p&gt;We connect via the following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/connect freenode-direct&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/03-after-connect.png&quot; alt=&quot;After connect&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You should see a successful connect operation signified by a lot of text appearing in the buffer welcoming you to freenode.&lt;/p&gt;

&lt;p&gt;At this point there’s nothing stopping you from joining a channel and chatting. You’ll notice though that many channels redirect you to some other channel:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/join #ubuntu&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you do this, you’ll see you’re actually redirected to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#ubuntu-unregged&lt;/code&gt;. The reason why is explained to you upon joining the channel:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/04-join-redirect.png&quot; alt=&quot;Join redirect&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can follow the instructions here (use Ctrl+N and Ctrl+P to navigate forward and back through your channel buffers to  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freenode&lt;/code&gt; to see the output of executing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/msg nickserv help register&lt;/code&gt; command) but I’ll summarise it here so that isn’t necessary.&lt;/p&gt;

&lt;p&gt;Registration essentially marks a given nick as yours. This is analagous to signing up for an account with a given username on other services. We do this in the following way (your password will show up in the prompt as asterixes):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/msg NickServ REGISTER qwerty123 tom+zncblogpost@busby.ninja&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Note: I changed this password prior to making this blog post public :P&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/05-nickserv-register.png&quot; alt=&quot;NickServ register&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When you check your inbox you’ll find an email from freenode with further instructions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;In order to complete your account registration, you must type the following
command on IRC:

/msg NickServ VERIFY REGISTER zncblogpost mzubwubihvmn&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After running this you should see something like the following in your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freenode&lt;/code&gt; buffer:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/06-email-verify.png&quot; alt=&quot;Email verify&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you now try to join &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#ubuntu&lt;/code&gt; you’ll see that it connects normally and you can chat freely:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/07-join-channel.png&quot; alt=&quot;PLAIN SASL&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, currently, you’ll need to run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/msg NickServ identify &amp;lt;password&amp;gt;&lt;/code&gt; every time you connect. We can prevent the need to do this with &lt;a href=&quot;https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer&quot;&gt;SASL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To start with, we’ll set this up using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PLAIN&lt;/code&gt; method which takes your username/password but later on we’ll be authenticating with an SSL certificate. Instructions for this section from &lt;a href=&quot;https://freenode.net/kb/answer/weechat&quot;&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/set irc.server.freenode-direct.sasl_mechanism PLAIN
/set irc.server.freenode-direct.sasl_username zncblogpost
/set irc.server.freenode-direct.sasl_password qwerty123
/save&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/08-plain-sasl.png&quot; alt=&quot;PLAIN SASL&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If we &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/quit&lt;/code&gt; and then open up weechat again we’ll see that when we connect (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/connect freenode-direct&lt;/code&gt;), it will authenticate with the freenode network automatically:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;...
19:51:06 freenode-direct  -- | SASL authentication successful
...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We have now set up our connection with freenode and registered our nick. If we didn’t care about using Tor or a bouncer we could stop here.&lt;/p&gt;

&lt;h2 id=&quot;installing-your-znc-bouncer&quot;&gt;Installing Your ZNC Bouncer&lt;/h2&gt;

&lt;p&gt;I will assume that you already have SSH access to a suitable server. Getting an externally-accessible server set up is outside the scope of this tutorial. There are many other tutorials which cover this for the various hosting providers. I’ll be using a fresh Amazon AWS instance in the following section and will loosely follow instructions from &lt;a href=&quot;https://wiki.znc.in/Tor&quot;&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Firstly, let’s install znc:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; znc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next item on the agenda is to install Tor:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Further details about this process &lt;a href=&quot;https://2019.www.torproject.org/docs/debian.html.en&quot;&gt;here&lt;/a&gt;. I’m using Ubuntu 18.04 LTS. For other OSs, see the linked page for instructions.&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;su -
⌗ &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deb https://deb.torproject.org/torproject.org bionic main&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;deb-src https://deb.torproject.org/torproject.org bionic main&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /etc/apt/sources.list.d/tor.list
⌗ curl https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg &lt;span class=&quot;nt&quot;&gt;--import&lt;/span&gt;
⌗ gpg &lt;span class=&quot;nt&quot;&gt;--export&lt;/span&gt; A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | apt-key add -
⌗ &lt;span class=&quot;nb&quot;&gt;logout&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/apt/sources.list.d/tor.list
deb https://deb.torproject.org/torproject.org bionic main
deb-src https://deb.torproject.org/torproject.org bionic main
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; tor deb.torproject.org-keyring&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next we need to install proxy chains and bind the freenode onion address to a local IP&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; proxychains
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;mapaddress 10.99.99.90 freenodeok2gncmy.onion&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sudo tee&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; /etc/tor/torrc
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl restart tor&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now that Tor is installed we can look into getting ZNC running and connecting to freenode via Tor. We want ZNC to run as a system daemon so we’ll be following the instuctions on &lt;a href=&quot;https://wiki.znc.in/Running_ZNC_as_a_system_daemon&quot;&gt;this page&lt;/a&gt;. If your server OS does not use systemd, consult the page I just mentioned. Your instructions will differ slightly.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;useradd &lt;span class=&quot;nt&quot;&gt;--create-home&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; /var/lib/znc &lt;span class=&quot;nt&quot;&gt;--system&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--shell&lt;/span&gt; /sbin/nologin &lt;span class=&quot;nt&quot;&gt;--comment&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Account to run ZNC daemon&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--user-group&lt;/span&gt; znc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We now need to create the skeleton config for the server:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; znc /usr/bin/znc &lt;span class=&quot;nt&quot;&gt;--datadir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/lib/znc &lt;span class=&quot;nt&quot;&gt;--makeconf&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Note: if you want, you can enable SSL. However, the cert won’t be signed by a CA so you’ll receive a warning about this from your browser when you navigate to the page. See &lt;a href=&quot;#is-the-connection-between-weechat-and-znc-secure&quot;&gt;this footnote&lt;/a&gt; for notes about securing the connection to the web admin.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/09-znc-makeconf.png&quot; alt=&quot;ZNC makeconf&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now create the systemd unit:&lt;/p&gt;

&lt;p style=&quot;margin-bottom: 0; font-weight: bold&quot;&gt;&lt;code&gt;/etc/systemd/system/znc.service&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Unit]
&lt;span class=&quot;nv&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ZNC, an advanced IRC bouncer
&lt;span class=&quot;nv&quot;&gt;After&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;network-online.target

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Service]
&lt;span class=&quot;nv&quot;&gt;ExecStart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/bin/znc &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--datadir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/lib/znc
&lt;span class=&quot;nv&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;znc

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Install]
&lt;span class=&quot;nv&quot;&gt;WantedBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It’s time to start the service.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;znc.service
Created symlink /etc/systemd/system/multi-user.target.wants/znc.service → /etc/systemd/system/znc.service.
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl start znc.service&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we’ve done that we can go to znc’s web interface at &amp;lt;host IP/DNS Name&amp;gt;:&amp;lt;Port we chose above&amp;gt;. For me this is http://52.16.112.138:8000/.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Those of you following along using an AWS instance, don’t forget to allow incoming connections on any exposed ports via the security group.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Log in to the web interface and go to “Global settings”. We want to add a specific port for SSL IRC connections:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/10-listen-ports.png&quot; alt=&quot;Listen Ports&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next we need to modify our systemd unit so that ZNC is loaded via proxychains:&lt;/p&gt;

&lt;p style=&quot;margin-bottom: 0; font-weight: bold&quot;&gt;&lt;code&gt;/etc/systemd/system/znc.service&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Unit]
&lt;span class=&quot;nv&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ZNC, an advanced IRC bouncer
&lt;span class=&quot;nv&quot;&gt;After&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;network-online.target

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Service]
&lt;span class=&quot;nv&quot;&gt;ExecStart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/bin/proxychains /usr/bin/znc &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--datadir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/lib/znc
&lt;span class=&quot;nv&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;znc

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Install]
&lt;span class=&quot;nv&quot;&gt;WantedBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now restart znc:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl restart znc.service&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;configuring-your-znc-bouncer-to-connect-to-freenode&quot;&gt;Configuring Your ZNC Bouncer to Connect to Freenode&lt;/h2&gt;

&lt;p&gt;After this we’ll set up freenode in ZNC. Go to “Your settings” and then click “Add” in the Networks section:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/11-add-network.png&quot; alt=&quot;Add Network&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: the IP is the mapped local IP address that we set up in the torrc file.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/12-new-network-form.png&quot; alt=&quot;New Network Form&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/13-cert-module.png&quot; alt=&quot;Cert Module&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/14-sasl-and-simple_away-modules.png&quot; alt=&quot;sasl and simple_away Modules&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At this point I also set up the DNS so that our server is available at blogpost.busby.ninja.&lt;/p&gt;

&lt;p&gt;Now we need to follow the instructions (taken from &lt;a href=&quot;https://wiki.znc.in/Weechat&quot;&gt;this page&lt;/a&gt;) to connect to our ZNC bouncer from weechat.&lt;/p&gt;

&lt;p&gt;On our server, we need to get the SSL cert fingerprint:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; znc &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /var/lib/znc/znc.pem | openssl x509 &lt;span class=&quot;nt&quot;&gt;-sha512&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-fingerprint&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-noout&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;':'&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'A-Z'&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'a-z'&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;cut&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; 2
162f9c92f80b048efb1ec06d4d04edab9fb7c399c36a2879a23994197970c8fbcefbe264401ea626b600b01e04bf99a4b483cdfd16ca4246de7958bad54bda11&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;While inside weechat (replacing the relevant details with your own):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/server add freenode-znc blogpost.busby.ninja/6697 -ssl -username=tom/freenode -password=same_as_webadmin_password123
/set irc.server.freenode-znc.ssl_fingerprint 162f9c92f80b048efb1ec06d4d04edab9fb7c399c36a2879a23994197970c8fbcefbe264401ea626b600b01e04bf99a4b483cdfd16ca4246de7958bad54bda11
/save
/connect freenode-znc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You should see something like this in the buffer:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/15-first-znc-connection.png&quot; alt=&quot;First ZNC Connection&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A short while later, you’ll notice another buffer pop up in the left hand bar called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*status&lt;/code&gt;. Use Ctrl+N to navigate to that buffer.&lt;/p&gt;

&lt;p&gt;You’ll see a lot of information about an SSL cert ending with something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/16-trust-certificate-request.png&quot; alt=&quot;Trust Certificate Request&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is a message from ZNC asking us to approve the SSL cert that freenode is presenting to ZNC as it attempts to connect on our behalf.&lt;/p&gt;

&lt;p&gt;By default, weechat won’t transmit commands it doesn’t recognise, so we need to whitelist &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/znc&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/alias add znc /quote znc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We will now follow the instructions and trust this fingerprint:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/znc AddTrustedServerFingerprint e9:db:e1:0c:79:66:a8:da:0c:84:18:bc:81:59:6c:87:b0:25:7f:b4:80:2d:94:25:d6:40:2c:dc:96:03:51:c8&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/17-after-trusting-cert.png&quot; alt=&quot;After Trusting Certificate&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SASL access only&lt;/code&gt; error relates to what is mentioned in the &lt;a href=&quot;https://freenode.net/news/tor-online&quot;&gt;freenode tor blogpost&lt;/a&gt; which is that, when connecting to freenode via Tor, you must authenticate via a more secure means than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PLAIN&lt;/code&gt;. We’ll set this up next. For now, let’s disconnect from ZNC:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/disconnect -all&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To get set up with certificate-based SASL authentication, we’ll be following instructions from &lt;a href=&quot;https://wiki.znc.in/Cert&quot;&gt;this page&lt;/a&gt; and &lt;a href=&quot;https://wiki.znc.in/Sasl&quot;&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the server execute the following commands (replacing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zncblogpost&lt;/code&gt; with your own nick):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;openssl req &lt;span class=&quot;nt&quot;&gt;-nodes&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-newkey&lt;/span&gt; rsa:4096 &lt;span class=&quot;nt&quot;&gt;-keyout&lt;/span&gt; user.pem &lt;span class=&quot;nt&quot;&gt;-x509&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-days&lt;/span&gt; 3650 &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; user.pem &lt;span class=&quot;nt&quot;&gt;-subj&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/CN=zncblogpost&quot;&lt;/span&gt;
...
writing new private key to &lt;span class=&quot;s1&quot;&gt;'user.pem'&lt;/span&gt;
...
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;openssl x509 &lt;span class=&quot;nt&quot;&gt;-sha1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-noout&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-fingerprint&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-in&lt;/span&gt; user.pem | &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/^.*=//;s/://g;y/ABCDEF/abcdef/'&lt;/span&gt;
c745ff09c1c5e11fef6fd8d9249124ce49a80194&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/18-create-sasl-auth-cert.png&quot; alt=&quot;Create Certificate for SASL Auth&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve acquired a certificate and calculated its fingerprint, let’s move it to where ZNC cert module can find it (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tom&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freenode&lt;/code&gt; will be replaced with your ZNC username and ZNC network name):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo chown &lt;/span&gt;znc:znc user.pem
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo mv &lt;/span&gt;user.pem /var/lib/znc/users/tom/networks/freenode/moddata/cert/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next, we need to inform freenode’s NickServ of our certificate’s fingerprint. Because we don’t yet have a working ZNC connection, we’re going to reuse our old &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freenode-direct&lt;/code&gt; connection in weechat:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/connect freenode-direct&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once connected we’ll inform NickServ of our fingerprint:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/msg NickServ cert add c745ff09c1c5e11fef6fd8d9249124ce49a80194&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/19-nickserv-add-fingerprint.png&quot; alt=&quot;NickServ Add Fingerprint&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can double check that things worked correctly:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/query NickServ cert list&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/20-check-cert-via-nickserv.png&quot; alt=&quot;Check Fingerprint via NickServ&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s all we need to do here, so let’s disconnect and reconnect to znc:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/disconnect -all
/connect freenode-znc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Note: you can navigate between open buffers with Ctrl+P/Ctrl+N and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/close&lt;/code&gt; the old unused ones.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s check in with the cert module to make sure it can see our certificate:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/query *cert info&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/21-check-cert-module-has-cert.png&quot; alt=&quot;Check cert Module has Certificate&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you have a different output than above then your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user.pem&lt;/code&gt; file is not in the right directory or maybe has the wrong permissions.&lt;/p&gt;

&lt;p&gt;Next we need to tell ZNC’s sasl module to use our certificate:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/query *sasl Mechanism
/query *sasl Mechanism EXTERNAL&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/22-set-sasl-module-to-use-external.png&quot; alt=&quot;Set SASL EXTERNAL Auth Mechanism&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can now navigate to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*status&lt;/code&gt; buffer and watch it connect:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;15:25:16 *status | Connected!&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/23-successful-connection.png&quot; alt=&quot;Set SASL EXTERNAL Auth Mechanism&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And now, the part we’ve all been waiting for… Let’s actually connect to a channel:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/join #ubuntu&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/24-join-channel.png&quot; alt=&quot;Connect to a channel&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Congrats, you’re up and running. The next section will deal with some recommended configuration and how to sync with multiple devices via ClientBuffer.&lt;/p&gt;

&lt;h2 id=&quot;futher-configuration&quot;&gt;Futher Configuration&lt;/h2&gt;

&lt;h4 id=&quot;enabling-colours-for-znc-playback&quot;&gt;Enabling Colours for ZNC Playback&lt;/h4&gt;

&lt;p&gt;To get this working, we’ll be using an unofficial script called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zncplayback.py&lt;/code&gt;. This is hosted &lt;a href=&quot;https://github.com/m4v/weechat-scripts/blob/master/znc-playback.py&quot;&gt;here&lt;/a&gt; if you’d like to read the source. All that’s required in order to install it is the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/script install zncplayback.py&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/25-zncplayback-installed.png&quot; alt=&quot;Installing zncplayback.py&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/26-coloured-playback.png&quot; alt=&quot;Coloured Playback&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;auto-sort-channel-buffers-by-name&quot;&gt;Auto-sort Channel Buffers by Name&lt;/h4&gt;

&lt;p&gt;When you are a member of many channels, keeping track of them can be a pain. It is possible to manually sort them, but it’s much easier to let a script do it for you. we’ll be using an unofficial script called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autosort.py&lt;/code&gt;. This is hosted &lt;a href=&quot;https://github.com/de-vri-es/weechat-autosort/blob/master/autosort.py&quot;&gt;here&lt;/a&gt; if you’d like to read the source.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/script install autosort.py&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;hide-joinleave-messages&quot;&gt;Hide Join/Leave Messages&lt;/h4&gt;

&lt;p&gt;As per &lt;a href=&quot;https://weechat.org/blog/post/2008/10/25/Smart-IRC-join-part-quit-message-filter&quot;&gt;this blog post&lt;/a&gt;, removing all the annoying join-message spam is very simple:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/set irc.look.smart_filter on
/filter add irc_smart * irc_smart_filter *&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Before and after:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/27-with-join-messges.png&quot; alt=&quot;With Join Messages&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/28-join-messages-filtered.png&quot; alt=&quot;Join Messages Filtered&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;enable-the-mouse&quot;&gt;Enable the Mouse&lt;/h4&gt;

&lt;p&gt;I have mixed feelings about whether this is a good idea. If you’re interested in being able to use the mouse then I recommend &lt;a href=&quot;https://weechat.org/files/doc/stable/weechat_user.en.html#mouse_enable&quot;&gt;reading the manual&lt;/a&gt;. Using the mouse lets you click on channel names and scroll in buffers with the mouse wheel. I suspect that just learning the keyboard shortcuts well, and setting up your own, is more productive long term.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-the-clientbuffer-module&quot;&gt;Setting Up the ClientBuffer Module&lt;/h2&gt;

&lt;p&gt;If you’d like to connect to ZNC from mutiple devices, this section is necessary. If you only ever intend to connect from one device, it is not.&lt;/p&gt;

&lt;p&gt;As described in the introduction, if you use the same ZNC playback buffer for both devices, the replayed messages will be split across the devices. The ClientBuffer module solves this problem by having ZNC maintain a separate playback buffers for each.&lt;/p&gt;

&lt;p&gt;We will be following instructions on &lt;a href=&quot;https://wiki.znc.in/Compiling_modules&quot;&gt;this page&lt;/a&gt; to install the module and &lt;a href=&quot;https://wiki.znc.in/Clientbuffer&quot;&gt;this page&lt;/a&gt; to configure the module. The source code for the module is hosted &lt;a href=&quot;https://github.com/CyberShadow/znc-clientbuffer&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Firstly, it’s nessesary to acquire the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;znc-buildmod&lt;/code&gt; tool:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; znc-dev
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;znc-buildmod
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; USAGE: /usr/bin/znc-buildmod &amp;lt;file.cpp&amp;gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;file.cpp ... &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next we have to get hold of the ClientBuffer source:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you don’t have git on the server and don’t want to install it, you can get a zip from the repository’s “Releases” page.&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone https://github.com/CyberShadow/znc-clientbuffer.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;znc-clientbuffer
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;znc-buildmod clientbuffer.cpp
Building &lt;span class=&quot;s2&quot;&gt;&quot;clientbuffer.so&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;ZNC 1.6.6... &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ok &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo chown &lt;/span&gt;znc:znc clientbuffer.so
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo mv &lt;/span&gt;clientbuffer.so /usr/lib/znc/
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl restart znc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;em&gt;Note: I don’t believe the service restart is necessary, but better safe than sorry.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With the module built and installed, we need to enable the module in our Network’s settings:&lt;/p&gt;

&lt;p&gt;Log in to the web admin and navigate to the “Your settings” page. Next, scroll down to the networks section and edit your network. Enable the module from its list of available modules:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/29-your-settings-networks.png&quot; alt=&quot;Your Settings - Networks&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/30-clientbuffer-module-ticked.png&quot; alt=&quot;ClientBuffer Module Ticked&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that the module is enabled, it’s time to add a client:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/query *clientbuffer Help
/query *clientbuffer ListClients
/query *clientbuffer AddClient mac
/query *clientbuffer ListClients&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/31-setting-up-new-cientbuffer.png&quot; alt=&quot;New ClientBuffer Client Created&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In order to tell ZNC which client we want to use, we need to include it in our usename upon connection:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/disconnect -all
/set irc.server.freenode-znc.username &quot;tom@mac/freenode&quot;
/connect freenode-znc
/query *clientbuffer ListClients&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;https://tom.busby.ninja/assets/images/znc/32-clientbuffer-enabled.png&quot; alt=&quot;New ClientBuffer Client Enabled&quot; class=&quot;image-center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For any other devices, all we need to do is create a new client (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddClient&lt;/code&gt;) like we did above and include that with our ZNC username upon connection. That way messages will be correctly replayed on both devices. Don’t use the same client name for multiple connections or you’ll run back into the “messages split across devices” issue.&lt;/p&gt;

&lt;h2 id=&quot;conclusion-and-clean-up&quot;&gt;Conclusion and Clean-up&lt;/h2&gt;

&lt;p&gt;If you installed ClientBuffer, I recommend leaving your working dir where you have access to it. You may need to recompile the module in future.&lt;/p&gt;

&lt;p&gt;Removing our direct connection that we used to get the cerificate set up is likely desirable at this point:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/server del freenode-direct&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We may also want to set up our ZNC-based connection to autoconnect when weechat is opened:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot; data-lang=&quot;plaintext&quot;&gt;/set irc.server.freenode-znc.autoconnect on&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;is-the-connection-between-weechat-and-znc-secure&quot;&gt;Is the connection between weechat and ZNC secure?&lt;/h4&gt;

&lt;p&gt;I’ve heard talk of people making ZNC itself also a tor hidden service. I personally don’t see the point. A tor hidden service is meant to protect the client and server from revealing their true source IP to one-another (and also to hide who is communicating with whom from global observers - Hello Five Eyes!). In this case, we are both client and server so we’d be protecting ourselves from ourselves.&lt;/p&gt;

&lt;p&gt;It’s sufficient to encrypt the traffic between our IRC client and ZNC. We may not have a certificate signed by a certificate authority, but given that ZNC generated the certificate itself and we added the fingerprint to weechat’s config, we can be pretty sure we aren’t under a man-in-the-middle attack while communicating with our bouncer. If you don’t trust ZNC’s autogenerated cert, you can replace it with your own without much issue. All a global observer sees is encrypted traffic between one IP and another.&lt;/p&gt;

&lt;p&gt;Currently though, we’re serving the web admin over plaintext HTTP. That isn’t ideal. If you would like to encrypt that traffic, you have a couple of options:&lt;/p&gt;

&lt;p&gt;The first is to just enable SSL for the web admin port (via the web admin). If your’re using the web admin to do this, you may have to create a new HTTP port temporarily. This is because the web admin won’t allow you to alter the port you’re currently connected via. Next time you navigate to the page via HTTPS, you’ll get a warning from your browser. You can check that the fingerprint is what you expect and tell the browser to ignore the warning.&lt;/p&gt;

&lt;p&gt;The second option involves using Let’s Encrypt to get a valid, signed certificate from a trusted authority. If you’re interested in that approach, you should check out &lt;a href=&quot;/letsencrypt-nginx-reverse-proxy-no-downtime/&quot;&gt;my other blog post on the subject&lt;/a&gt; or read about &lt;a href=&quot;https://wiki.znc.in/Signed_SSL_certificate&quot;&gt;signed SSL certificates&lt;/a&gt; on the ZNC wiki.&lt;/p&gt;

&lt;p&gt;If we use the method I wrote about, we can also replace our generated certificate for the IRC connection with the new Let’s Encrypt certificate too. In this instance, you should unset &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssl_fingerprint&lt;/code&gt; in your weechat server config. When using a signed certificate, you can rely on the &lt;a href=&quot;https://en.wikipedia.org/wiki/Public_key_infrastructure&quot;&gt;Public Key Infrastructure&lt;/a&gt; to validate it. The frequently-renewing nature of Let’s Encrypt certificates means that not removing the fingerprint will cause you problems when the certificate is renewed (because the fingerprint will no longer match). I may write this up in future.&lt;/p&gt;</content><author><name>tombusby</name></author><category term="blog" /><category term="irc" /><category term="freenode" /><category term="znc" /><category term="tor" /><summary type="html">Motivation</summary></entry><entry><title type="html">Cypherpunks Mailing List Archive - Archive of posts to the list during its 90s heyday. Soon to be expanded to include the 2000-2016 currently-unarchived “dark ages” of the list.</title><link href="https://tom.busby.ninja/cryptoanarchy-wiki-mailing-list-archive/" rel="alternate" type="text/html" title="Cypherpunks Mailing List Archive - Archive of posts to the list during its 90s heyday. Soon to be expanded to include the 2000-2016 currently-unarchived “dark ages” of the list." /><published>2018-07-11T21:42:00+00:00</published><updated>2018-07-11T21:42:00+00:00</updated><id>https://tom.busby.ninja/cryptoanarchy-wiki-mailing-list-archive</id><content type="html" xml:base="https://tom.busby.ninja/cryptoanarchy-wiki-mailing-list-archive/"></content><author><name>tombusby</name></author><category term="project" /><category term="cryptography" /><category term="cryptoanarchy" /><category term="cypherpunk" /><summary type="html"></summary></entry><entry><title type="html">cryptoanarchy.wiki - An encyclopedia of cypherpunk thought, people and events.</title><link href="https://tom.busby.ninja/cryptoanarchy-wiki/" rel="alternate" type="text/html" title="cryptoanarchy.wiki - An encyclopedia of cypherpunk thought, people and events." /><published>2018-07-11T21:30:00+00:00</published><updated>2018-07-11T21:30:00+00:00</updated><id>https://tom.busby.ninja/cryptoanarchy-wiki</id><content type="html" xml:base="https://tom.busby.ninja/cryptoanarchy-wiki/"></content><author><name>tombusby</name></author><category term="project" /><category term="cryptography" /><category term="cryptoanarchy" /><category term="cypherpunk" /><summary type="html"></summary></entry><entry><title type="html">Understanding Cryptography by Christof Paar and Jan Pelzl - All Problems and Solutions</title><link href="https://tom.busby.ninja/understanding-cryptography-full-solution-set/" rel="alternate" type="text/html" title="Understanding Cryptography by Christof Paar and Jan Pelzl - All Problems and Solutions" /><published>2017-12-10T00:50:00+00:00</published><updated>2017-12-10T00:50:00+00:00</updated><id>https://tom.busby.ninja/understanding-cryptography-full-solution-set</id><content type="html" xml:base="https://tom.busby.ninja/understanding-cryptography-full-solution-set/">&lt;h2 id=&quot;useful-links&quot;&gt;Useful links&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.crypto-textbook.com/&quot;&gt;Official Website for “Understanding Cryptography” - crypto-textbook.com&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC1usFRN4LCMcfIV7UjHNuQg/videos&quot;&gt;University Lecture Series Covering the Material from the Book&lt;/a&gt; - taught by Christof Paar&lt;/li&gt;
  &lt;li&gt;Problem sets from the book:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_1.pdf&quot;&gt;Chapter 1&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_2.pdf&quot;&gt;Chapter 2&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_3.pdf&quot;&gt;Chapter 3&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_4.pdf&quot;&gt;Chapter 4&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_5.pdf&quot;&gt;Chapter 5&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_6.pdf&quot;&gt;Chapter 6&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_7.pdf&quot;&gt;Chapter 7&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_8.pdf&quot;&gt;Chapter 8&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_9.pdf&quot;&gt;Chapter 9&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_10.pdf&quot;&gt;Chapter 10&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_11.pdf&quot;&gt;Chapter 11&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_12.pdf&quot;&gt;Chapter 12&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/problems_only/problems_chaptr_13.pdf&quot;&gt;Chapter 13&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/Understanding_Cryptography_Odd_Solutions.pdf&quot;&gt;Solutions for Odd-Numbered Questions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;During my self-study on the topic of cryptography, I’ve found that the textbook “&lt;a href=&quot;http://www.crypto-textbook.com/&quot;&gt;Understanding Cryptography&lt;/a&gt;” by Christof Paar and Jan Pelzl, and the accompanying &lt;a href=&quot;https://www.youtube.com/channel/UC1usFRN4LCMcfIV7UjHNuQg/videos&quot;&gt;YouTube lectures&lt;/a&gt;, are the most accessible introductory material I have found. The book contains a great many exercises related to the material.&lt;/p&gt;

&lt;p&gt;There is a solution manual freely available from the website called &lt;a href=&quot;http://wiki.crypto.rub.de/Buch/en/download/Understanding_Cryptography_Odd_Solutions.pdf&quot;&gt;Solutions for Odd-Numbered Questions&lt;/a&gt;, however the even numbered questions are unavailable. I have contacted the authors, but licensing restrictions prevent them providing the full manual to anyone except instructors in educational institutions. It does not appear that anyone has leaked the manual to the internet either.&lt;/p&gt;

&lt;p&gt;As such, I have decided to create a comprehensive solution set to all problems in the book.&lt;/p&gt;

&lt;h2 id=&quot;list-of-questions-and-answers&quot;&gt;List of Questions and Answers&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Chapter 1 - Introduction to Cryptography and Data Security&lt;/li&gt;
  &lt;ul&gt;
    
        
          &lt;li&gt;Ex 1.1 - &lt;a href=&quot;/understanding-cryptography/ex1-1/&quot;&gt;Breaking a Substitution Cipher by Frequency Analysis&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.2 - &lt;a href=&quot;/understanding-cryptography/ex1-2/&quot;&gt;Breaking a Caesar/Shift Cipher by Frequency Analysis&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.3 - &lt;a href=&quot;/understanding-cryptography/ex1-3/&quot;&gt;Calculating the Length of Brute-Force Attacks against AES&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.4 - &lt;a href=&quot;/understanding-cryptography/ex1-4/&quot;&gt;Password Length and Key Sizes in Bits&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.5 - &lt;a href=&quot;/understanding-cryptography/ex1-5/&quot;&gt;Multiplication in Finite Sets&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.6 - &lt;a href=&quot;/understanding-cryptography/ex1-6/&quot;&gt;Division in Finite Sets&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.7 - &lt;a href=&quot;/understanding-cryptography/ex1-7/&quot;&gt;Computing Addition and Multiplication Tables in Finite Sets&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.8 - &lt;a href=&quot;/understanding-cryptography/ex1-8/&quot;&gt;Computing Multiplicative Inverses of 5 in Several Finite Sets&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.9 - &lt;a href=&quot;/understanding-cryptography/ex1-9/&quot;&gt;Computing Large Exponents in Finite Sets&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.10 - &lt;a href=&quot;/understanding-cryptography/ex1-10/&quot;&gt;Computing Euler's Phi Function&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.11 - &lt;a href=&quot;/understanding-cryptography/ex1-11/&quot;&gt;Decrypting with the Affine Cipher&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.12 - &lt;a href=&quot;/understanding-cryptography/ex1-12/&quot;&gt;Decrypting with the Extended German-Alphabet Affine Cipher&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.13 - &lt;a href=&quot;/understanding-cryptography/ex1-13/&quot;&gt;Breaking the Affine Cipher with a Chosen Plaintext Attack&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 1.14 - &lt;a href=&quot;/understanding-cryptography/ex1-14/&quot;&gt;Proving that Double Encryption with the Affine Cipher is Equivalent to Single Encryption&lt;/a&gt;&lt;/li&gt;
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
  &lt;/ul&gt;
  &lt;li&gt;Chapter 2 - Stream Ciphers&lt;/li&gt;
  &lt;ul&gt;
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
          &lt;li&gt;Ex 2.1 - &lt;a href=&quot;/understanding-cryptography/ex2-1/&quot;&gt;Developing a Stream Cipher which Operates on the Latin Alphabet&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.2 - &lt;a href=&quot;/understanding-cryptography/ex2-2/&quot;&gt;Discussion of Key Management Issues with One Time Pads (OTPs)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.3 - &lt;a href=&quot;/understanding-cryptography/ex2-3/&quot;&gt;The Dangers of Key Reuse with One Time Pads (OTPs)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.4 - &lt;a href=&quot;/understanding-cryptography/ex2-4/&quot;&gt;The Impossibility of Brute Force Attacks on One Time Pads (OTPs)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.5 - &lt;a href=&quot;/understanding-cryptography/ex2-5/&quot;&gt;Calculating the Output and State of Linear Feedback Shift Registers (LFSRs)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.6 - &lt;a href=&quot;/understanding-cryptography/ex2-6/&quot;&gt;Chosen Plaintext Attacks Against Stream Ciphers with Short Periods&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.7 - &lt;a href=&quot;/understanding-cryptography/ex2-7/&quot;&gt;Computing the First Two Bytes of Output from an LSFR with an 8th Degree Polynomial&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.8 - &lt;a href=&quot;/understanding-cryptography/ex2-8/&quot;&gt;Computing All Sequences from Reducible, Irriducible and Primitive Polynomial LFSRs&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.9 - &lt;a href=&quot;/understanding-cryptography/ex2-9/&quot;&gt;Discussion of Attacks Against LFSRs&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.10 - &lt;a href=&quot;/understanding-cryptography/ex2-10/&quot;&gt;Performing a Chosen Plaintext Attack to Break an LFSR and Reveal its Feedback Coefficients&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.11 - &lt;a href=&quot;/understanding-cryptography/ex2-11/&quot;&gt;Performing Another Chosen Plaintext Attack to Break an LFSR and Reveal the Full Plaintext&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 2.12 - &lt;a href=&quot;/understanding-cryptography/ex2-12/&quot;&gt;Calculating the First 70 Bits of Output During Trivium's Warm-up Phase&lt;/a&gt;&lt;/li&gt;
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
  &lt;/ul&gt;
  &lt;li&gt;Chapter 3 - The Data Encryption Standard (DES) and Alternatives&lt;/li&gt;
  &lt;ul&gt;
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
          &lt;li&gt;Ex 3.1 - &lt;a href=&quot;/understanding-cryptography/ex3-1/&quot;&gt;Verifying the Non-Linearity of the DES S-boxes&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.2 - &lt;a href=&quot;/understanding-cryptography/ex3-2/&quot;&gt;Veryifying that IP and IP-1 are Each Other's Inverse&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.3 - &lt;a href=&quot;/understanding-cryptography/ex3-3/&quot;&gt;Calculating the Output of the First Round of DES Encryption with All 0s&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.4 - &lt;a href=&quot;/understanding-cryptography/ex3-4/&quot;&gt;Calculating the Output of the First Round of DES Encryption with All 1s&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.5 - &lt;a href=&quot;/understanding-cryptography/ex3-5/&quot;&gt;Demonstrating the Avalanche Effect of a 1-bit Input Change in DES&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.6 - &lt;a href=&quot;/understanding-cryptography/ex3-6/&quot;&gt;Demonstrating the Avalanche Effect of a 1-bit Key Change in DES&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.7 - &lt;a href=&quot;/understanding-cryptography/ex3-7/&quot;&gt;Discussion of What Constitutes a &quot;Weak Key&quot; in DES&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.8 - &lt;a href=&quot;/understanding-cryptography/ex3-8/&quot;&gt;Proving that When the DES Key and Input are Bitwise Inverted, So is the Output&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.9 - &lt;a href=&quot;/understanding-cryptography/ex3-9/&quot;&gt;Discussion of Number of Key Checks Required to Brute-Force a DES Key from a Chosen Plaintext&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.10 - &lt;a href=&quot;/understanding-cryptography/ex3-10/&quot;&gt;Discussion of Clock Frequency Requirements for DES Hardware Implementations&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.11 - &lt;a href=&quot;/understanding-cryptography/ex3-11/&quot;&gt;Using COPACOBANA to Brute-Force DES Keys&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.12 - &lt;a href=&quot;/understanding-cryptography/ex3-12/&quot;&gt;Calculating Equivalent Key Lengths for DES Keys With Flawed Generation Procedures&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 3.13 - &lt;a href=&quot;/understanding-cryptography/ex3-13/&quot;&gt;Calculating the State After Round 1 for the PRESENT-80 Block Cipher&lt;/a&gt;&lt;/li&gt;
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
  &lt;/ul&gt;
  &lt;li&gt;Chapter 4 - The Advanced Encryption Standard (AES)&lt;/li&gt;
  &lt;ul&gt;
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
          &lt;li&gt;Ex 4.1 - &lt;a href=&quot;/understanding-cryptography/ex4-1/&quot;&gt;The AES Development Process and How that Differed from DES&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.2 - &lt;a href=&quot;/understanding-cryptography/ex4-2/&quot;&gt;Computing Addition and Multiplication Tables in Galois Prime Fields&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.3 - &lt;a href=&quot;/understanding-cryptography/ex4-3/&quot;&gt;Computing Addition and Multiplication Tables in Galois Extension Fields&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.4 - &lt;a href=&quot;/understanding-cryptography/ex4-4/&quot;&gt;Performing Addition and Reduction in GF(2⁴)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.5 - &lt;a href=&quot;/understanding-cryptography/ex4-5/&quot;&gt;Performing Multiplication and Reduction in GF(2⁴)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.6 - &lt;a href=&quot;/understanding-cryptography/ex4-6/&quot;&gt;Calculating a Division in GF(2⁸) and Reducing via the AES Irreducible Polynomial&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.7 - &lt;a href=&quot;/understanding-cryptography/ex4-7/&quot;&gt;Finding Multiplicative Inverses in GF(2⁴)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.8 - &lt;a href=&quot;/understanding-cryptography/ex4-8/&quot;&gt;Finding Irreducible Polynomials in GF(2)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.9 - &lt;a href=&quot;/understanding-cryptography/ex4-9/&quot;&gt;Calculating the Output of the First Round of AES Encryption with All 1s&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.10 - &lt;a href=&quot;/understanding-cryptography/ex4-10/&quot;&gt;Calculating the State After One Round for AES&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.11 - &lt;a href=&quot;/understanding-cryptography/ex4-11/&quot;&gt;Deriving Equations for the Constant Multiplications Done in the MixColumn GF Computations&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.12 - &lt;a href=&quot;/understanding-cryptography/ex4-12/&quot;&gt;Calculating the Number of XOR Gates Required for AES Diffusion&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.13 - &lt;a href=&quot;/understanding-cryptography/ex4-13/&quot;&gt;Checking Multiplicative Inverses in GF(2⁸)&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.14 - &lt;a href=&quot;/understanding-cryptography/ex4-14/&quot;&gt;Calculating the AES S-box for Certain Values Using the Affine Mapping&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.15 - &lt;a href=&quot;/understanding-cryptography/ex4-15/&quot;&gt;Derive RC Constants in AES Key Schedule&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 4.16 - &lt;a href=&quot;/understanding-cryptography/ex4-16/&quot;&gt;Calculating the Length of Brute-Force Attacks against AES&lt;/a&gt;&lt;/li&gt;
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
  &lt;/ul&gt;
  &lt;li&gt;Chapter 5 - More about Block Ciphers&lt;/li&gt;
  &lt;ul&gt;
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
    
        
          &lt;li&gt;Ex 5.1 - &lt;a href=&quot;/understanding-cryptography/ex5-1/&quot;&gt;Selecting the Appropriate Mode of Operation for a Block Cipher in a Specific Use-Case&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.2 - &lt;a href=&quot;/understanding-cryptography/ex5-2/&quot;&gt;Comparison of Brute-force Costs for Ciphers in ECB or CBC Modes&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.3 - &lt;a href=&quot;/understanding-cryptography/ex5-3/&quot;&gt;Discussion of Deriving the IV of a Cipher in CBC Mode where Key is Known&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.4 - &lt;a href=&quot;/understanding-cryptography/ex5-4/&quot;&gt;Why Keeping the IV Secret Does not Increase Security for Ciphers in OFB Mode&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.5 - &lt;a href=&quot;/understanding-cryptography/ex5-5/&quot;&gt;The Problems of IV Reuse with Ciphers in OFB Mode&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.6 - &lt;a href=&quot;/understanding-cryptography/ex5-6/&quot;&gt;Designing an OFB Mode Scheme for Byte Encryption&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.7 - &lt;a href=&quot;/understanding-cryptography/ex5-7/&quot;&gt;Weakening an OFB Mode Scheme by Truncating the Feedback Bytes&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.8 - &lt;a href=&quot;/understanding-cryptography/ex5-8/&quot;&gt;Designing a CFB Mode Scheme for Byte Encryption&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.9 - &lt;a href=&quot;/understanding-cryptography/ex5-9/&quot;&gt;Discussion of the Number of IV Bits Available in AES CTR (Counter) Mode for 1TB of Plaintext&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.10 - &lt;a href=&quot;/understanding-cryptography/ex5-10/&quot;&gt;Propagation of Errors in Various Block Cipher Modes of Operation&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.11 - &lt;a href=&quot;/understanding-cryptography/ex5-11/&quot;&gt;Reestablishing Synchronisation and Correctness in the Case of Bit Insertion/Deletion during Transmission&lt;/a&gt;&lt;/li&gt;
        
    
        
          &lt;li&gt;Ex 5.12 - &lt;a href=&quot;/understanding-cryptography/ex5-12/&quot;&gt;Calculating the Length of Brute-Force Attacks against 2DES with &quot;Meet in the Middle&quot; Attack&lt;/a&gt;&lt;/li&gt;
        
    
  &lt;/ul&gt;
&lt;/ul&gt;</content><author><name>tombusby</name></author><category term="project" /><category term="cryptography" /><category term="understanding-cryptography" /><category term="even-numbered-solutions" /><summary type="html">Useful links</summary></entry><entry><title type="html">Let’s Encrypt Auto-Renewal for Nginx Reverse Proxies</title><link href="https://tom.busby.ninja/letsencrypt-nginx-reverse-proxy-no-downtime/" rel="alternate" type="text/html" title="Let’s Encrypt Auto-Renewal for Nginx Reverse Proxies" /><published>2016-05-27T11:03:00+00:00</published><updated>2016-05-27T11:03:00+00:00</updated><id>https://tom.busby.ninja/letsencrypt-nginx-reverse-proxy-no-downtime</id><content type="html" xml:base="https://tom.busby.ninja/letsencrypt-nginx-reverse-proxy-no-downtime/">&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;If you are familiar with using Nginx as a reverse proxy and have already used Let’s Encrypt, skip to “&lt;a href=&quot;#provisioning-a-server&quot;&gt;Provisioning a Server&lt;/a&gt;“.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2016-06-11 - Improved the nginx config based on a suggestion from &lt;a href=&quot;https://www.reddit.com/r/programming/comments/4m2avd/free_lets_encrypt_ssl_certs_howto_autorenewal_for/d3s85ur&quot;&gt;/u/nikomo&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;nginx&quot;&gt;Nginx&lt;/h4&gt;

&lt;p&gt;A very useful feature of &lt;a href=&quot;https://www.nginx.com&quot;&gt;nginx&lt;/a&gt; is that you can host multiple services on the same host and the same IP. For example, you could have a &lt;a href=&quot;https://nodejs.org&quot;&gt;Node.js&lt;/a&gt; application running on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8080&lt;/code&gt;, a &lt;a href=&quot;https://jenkins.io&quot;&gt;Jenkins CI&lt;/a&gt; service running on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8088&lt;/code&gt; and any other combination of web services written in various languages.&lt;/p&gt;

&lt;p&gt;These local ports are not exposed to the pubic internet. Instead, nginx listens on port 80/443 and proxies the relevent service based on what domain name is being requested. For example, a request to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jenkins.example.com&lt;/code&gt; would be proxied to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8080&lt;/code&gt; in our earlier example.&lt;/p&gt;

&lt;p&gt;In order to secure our connection with the client, HTTPS connections can be set up in the nginx configuration. The local services can safely serve plaintext HTTP since all connections are local.&lt;/p&gt;

&lt;h4 id=&quot;lets-encrypt&quot;&gt;Let’s Encrypt&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://letsencrypt.org&quot;&gt;Let’s Encrypt&lt;/a&gt; is a new certificate authority which aims to provide free, automated SSL certificates. All the major browsers have now added Let’s Encrypt to their default list of trusted providers. This means that site operators who wanted to serve HTTPS but didn’t want to pay for a certificate now can.&lt;/p&gt;

&lt;p&gt;This is actually very exciting for ordinary internet users’ privacy and security!&lt;/p&gt;

&lt;h4 id=&quot;certbot&quot;&gt;Certbot&lt;/h4&gt;

&lt;p&gt;Let’s Encrypt provide an automated CLI tool to obtain certificates called &lt;a href=&quot;https://github.com/certbot/certbot&quot;&gt;Certbot&lt;/a&gt;. Certbot proves to the Let’s Encrypt certificate authority that you own the domain by simply listning on port 80/443 and having the certificate authority make a request.&lt;/p&gt;

&lt;p&gt;If you’re trying to acquire a certificate for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newdomain.example.com&lt;/code&gt; then Let’s Encrypt will just resolve that domain name and make a request. If they receive the response they’re expecting then this proves that whoever is running certbot does control that domain.&lt;/p&gt;

&lt;p&gt;There are currently three modes you can use to obtain your certificate:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Apache&lt;/code&gt; - Certbot is able to plug-in directly to the &lt;a href=&quot;https://httpd.apache.org&quot;&gt;Apache&lt;/a&gt; web server and allow Let’s Encrypt to make their request without any down-time for what’s normally hosted there. This is an ideal solution for Apache users.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Webroot&lt;/code&gt; - If you’re not hosting your site with Apache, but have write access to the directory which serves as the web-root for the service, Certbot can drop some files in here and they’ll be served up when Let’s Encrypt comes knocking just as normal. Again, no interruption in service.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Standalone&lt;/code&gt; - Certbot will directly listen on the required port. This obviously requires some down-time for whatever service is normally listening on that port.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unfortunately, a lot of the time when we’re using nginx as a reverse proxy, it (at first) appears that we need to use Standalone. For example, if you’re proxying a service that’s running in a &lt;a href=&quot;https://www.docker.com&quot;&gt;Docker&lt;/a&gt; container, then you don’t have access to the web-root.&lt;/p&gt;

&lt;p&gt;To make things worse, every time you need to renew the certificate for that one service, you need to stop nginx (severing the link to all other services too) so that Certbot can listen on those ports.&lt;/p&gt;

&lt;p&gt;Fortunately, I’m going to show you a way around this. There is an easy way to set up your services behind an nginx reverse proxy and still get the benefits of automated certificate renewal.&lt;/p&gt;

&lt;h2 id=&quot;provisioning-a-server&quot;&gt;Provisioning a server&lt;/h2&gt;

&lt;p&gt;For this example, I’m starting out by spinning up a fresh &lt;a href=&quot;http://www.ubuntu.com&quot;&gt;Ubuntu&lt;/a&gt; instance on &lt;a href=&quot;https://aws.amazon.com&quot;&gt;Amazon EC2&lt;/a&gt; (t2.micro). I’ve assigned an Elastic IP and, to begin with, allowed all incoming traffic via its security group. I’ve also pointed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssltest.busby.ninja&lt;/code&gt; at the instance. I’ll be including all installation commands so this tutorial can be followed exactly.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-the-services&quot;&gt;Setting up the services&lt;/h2&gt;

&lt;p&gt;For this example, I’m going to use a &lt;a href=&quot;http://rancher.com&quot;&gt;Rancher&lt;/a&gt; server as my example service. I’m doing this precisely because it runs in a Docker container, so I can’t use Certbot’s Apache mode, and I don’t have access to the service’s web-root directory.&lt;/p&gt;

&lt;p&gt;The first thing we need to do after SSHing into the instance is install nginx and docker:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get update &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;nginx &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt;
wget &lt;span class=&quot;nt&quot;&gt;-qO-&lt;/span&gt; https://get.docker.com/ | sh
&lt;span class=&quot;c&quot;&gt;# The next command is optional, it allows you to run docker without sudo&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Replace ubuntu with whatever your user is called&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;usermod &lt;span class=&quot;nt&quot;&gt;-aG&lt;/span&gt; docker ubuntu&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After this, double-check that you see the default nginx page when you navigate to the domain. If this works correctly, then the next thing to do is start up our rancher server. Retrieving and running the server can be done with a single docker command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;c&quot;&gt;# If you want to listen on another port, change only the first 8080&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;cid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;docker run &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8080:8080 rancher/server&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It may take a little while for rancher to be downloaded and run. Once the previous command has terminated, you can watch Rancher’s progress as it boots up using the following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;docker logs &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$cid&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When you see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Connection established&lt;/code&gt; in the logs, it should be ready and listening. Assuming you didn’t change it, you can test that by calling port 8080. In my case, that means navigating to &lt;a href=&quot;http://ssltest.busby.ninja:8080&quot;&gt;http://ssltest.busby.ninja:8080&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;basic-nginx-configuration&quot;&gt;Basic nginx configuration&lt;/h2&gt;

&lt;p&gt;Now that we have nginx and rancher running, we can configure it as a basic reverse proxy that supports HTTP (but not HTTPS yet). You’ll want to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo su -&lt;/code&gt; to login as root, then navigate to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/nginx/sites-available&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Below are the two configuration files which you need to create in this directory. The first ensures that if you enter the server’s IP into the browser, or nginx doesn’t recognise the domain in the HTTP host, then it will refuse to serve any content. The second is the configuration for our reverse proxy to rancher.&lt;/p&gt;

&lt;p style=&quot;margin-bottom: 0; font-weight: bold&quot;&gt;&lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nginx&quot; data-lang=&quot;nginx&quot;&gt;&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;deny&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p style=&quot;margin-bottom: 0; font-weight: bold&quot;&gt;&lt;code&gt;/etc/nginx/sites-available/rancher&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nginx&quot; data-lang=&quot;nginx&quot;&gt;&lt;span class=&quot;k&quot;&gt;upstream&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rancher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# change this if you used a port other than 8080&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8080&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fail_timeout=0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;[::]:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;server_name&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ssltest.busby.ninja&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# replace this with your domain&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Some of these might not be required for other services&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# proxy_pass is the most important&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Host&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$scheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-Port&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-For&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_pass&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://rancher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_http_version&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Upgrade&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;upgrade&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_read_timeout&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;900s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next you need to symlink these into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/nginx/sites-enabled&lt;/code&gt; and restart the server.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ../sites-enabled
&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-sf&lt;/span&gt; ../sites-available/default
&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-sf&lt;/span&gt; ../sites-available/rancher
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;service nginx restart&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If restarting nginx fails, then the logs are at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/nginx/error.log&lt;/code&gt;. If it succeeds, you should now be able to navigate to your domain (in my case &lt;a href=&quot;http://ssltest.busby.ninja&quot;&gt;http://ssltest.busby.ninja&lt;/a&gt;) and see rancher load as if you’d accessed it directly. If you see the nginx default page again, try refreshing, it may be the browser cache. You should also try accessing the server directly by IP (in my case &lt;a href=&quot;http://52.51.228.42&quot;&gt;http://52.51.228.42&lt;/a&gt;). If all has gone well you’ll see a 403 Forbidden message.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-a-web-root&quot;&gt;Setting up a web-root&lt;/h2&gt;

&lt;p&gt;As discussed in the introduction, we will be using the Certbot tool that Let’s Encrypt provide.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;While we could use the standalone mode, this would involve shutting down nginx while it runs and disrupting service to rancher.&lt;/li&gt;
  &lt;li&gt;We can’t use the apache mode since we’re using nginx and rancher.&lt;/li&gt;
  &lt;li&gt;We don’t have access to rancher’s web-root so we also can’t use the webroot mode…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…or can we.&lt;/p&gt;

&lt;p&gt;This is one of the ways in which nginx is really very cool. It’s possible for us to configure a separate web-root in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/nginx/sites-available/rancher&lt;/code&gt; file. When Let’s Encrypt make the request, it expects to find the proof file located within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/.well-known&lt;/code&gt; subdirectory of the web-root. This is a relatively new &lt;a href=&quot;https://tools.ietf.org/html/rfc5785&quot;&gt;IETF standard&lt;/a&gt; to prevent things like favicon.ico and other things cluttering the web-root.&lt;/p&gt;

&lt;p&gt;As such we can recognise paths beginning with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/.well-known&lt;/code&gt; as SSL proof requests and serve it up correctly. A previous version of this blog post used a solution that required checking the file system to see if the path existed for every request. If no file was found in the web-root it was proxied. This avoids that overhead: we only do web-root file system checks for requests beginning with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/.well-known&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Firstly let’s create the webroot (I’m assuming you’re still root here):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /var/www/ssl-proof/rancher/.well-known
&lt;span class=&quot;c&quot;&gt;# Create file we'll use later to test &lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;nginx is awesome!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /var/www/ssl-proof/rancher/.well-known/test.html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next, we need to modify our nginx config:&lt;/p&gt;

&lt;p style=&quot;margin-bottom: 0; font-weight: bold&quot;&gt;&lt;code&gt;/etc/nginx/sites-available/rancher&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nginx&quot; data-lang=&quot;nginx&quot;&gt;&lt;span class=&quot;k&quot;&gt;upstream&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rancher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# change this if you used a port other than 8080&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8080&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fail_timeout=0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;[::]:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;server_name&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ssltest.busby.ninja&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# replace this with your domain&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Here we define the web-root for our SSL proof&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/.well-known&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# Note that a request for /.well-known/test.html will&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# look for /var/www/ssl-proof/rancher/.well-known/test.html&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# and not /var/www/ssl-proof/rancher/test.html&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/var/www/ssl-proof/rancher/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Host&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$scheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-Port&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-For&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_pass&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://rancher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_http_version&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Upgrade&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;upgrade&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_read_timeout&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;900s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart nginx and access /.well-known/test.html (&lt;a href=&quot;http://ssltest.busby.ninja/.well-known/test.html&quot;&gt;http://ssltest.busby.ninja/.well-known/test.html&lt;/a&gt; for me). You should see a message correctly stating how awesome nginx is. You should also check that other paths are still redirecting to rancher. If you’re a clean-freak like me you’ll probably want to delete test.html after confirming that everything is working. You can also log out of root for now.&lt;/p&gt;

&lt;h2 id=&quot;acquiring-an-ssl-certificate&quot;&gt;Acquiring an SSL certificate&lt;/h2&gt;

&lt;p&gt;Next, we’ll need to get Certbot installed. Many of you might want to run it in its own user, and to get the latest version via GitHub. I’m going to keep things simple and just directly download a stable version to the ubuntu user’s home directory (and it also ensures hopefully the tutorial will still work in the medium-term future).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Important note&lt;/strong&gt;: If you’re following along on a low power instance like the EC2 t2.micro that I’m using, the certbot install my cause errors. You just need to stop the rancher service while you do this segment since it’s a bit of a memory hog. I realise that this defeats the purpose of using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webroot&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;standalone&lt;/code&gt; but this is intended as a demonstration. On a more powerful machine, or with less demanding services, you won’t have this issue. The commands to do this are below:&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Look for rancher, the container ID is on the left&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# You can use ps -a to see stopped containers&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;docker ps
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;docker stop &amp;lt;container &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# To restart it later:&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;docker start &amp;lt;container &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the latest version of ubuntu you can actually install certbot via apt-get:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;letsencrypt &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To make this tutorial a little more universal though, I won’t do that. I’m going to get a stable version from &lt;a href=&quot;https://certbot.eff.org&quot;&gt;https://certbot.eff.org&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;c&quot;&gt;# &amp;lt;Log out of root if necessary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~
wget https://dl.eff.org/certbot-auto
&lt;span class=&quot;nb&quot;&gt;chmod &lt;/span&gt;a+x certbot-auto
&lt;span class=&quot;c&quot;&gt;# Run certbot once with no arguments&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This will install its dependencies&lt;/span&gt;
./certbot-auto&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we get to the important part: actually requesting the certificate!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;c&quot;&gt;# Change the webroot and the domain to your own values if needed&lt;/span&gt;
./certbot-auto certonly &lt;span class=&quot;nt&quot;&gt;--webroot&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt; /var/www/ssl-proof/rancher/ &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; ssltest.busby.ninja&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You’ll be prompted for an email, and to accept some terms and conditions. When you’ve done that, you’ll see something like the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/ssltest.busby.ninja/fullchain.pem. Your cert
   will expire on 2016-08-24. To obtain a new version of the
   certificate in the future, simply run Certbot again.
 - If you lose your account credentials, you can recover through
   e-mails sent to tom@busby.ninja.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;configuring-nginx-to-use-the-ssl-certificate&quot;&gt;Configuring nginx to use the SSL certificate&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Users affected by the out-of-memory errors mentioned earlier will want to restart rancher now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Again, it’s time to modify the rancher nginx config:&lt;/p&gt;

&lt;p style=&quot;margin-bottom: 0; font-weight: bold&quot;&gt;&lt;code&gt;/etc/nginx/sites-available/rancher&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nginx&quot; data-lang=&quot;nginx&quot;&gt;&lt;span class=&quot;k&quot;&gt;upstream&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;rancher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# change this if you used a port other than 8080&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8080&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fail_timeout=0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This block 301 redirects HTTP requests to HTTPS&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;[::]:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;server_name&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ssltest.busby.ninja&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# replace this with your domain&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;301&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$server_name$request_uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;443&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;[::]:443&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;server_name&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ssltest.busby.ninja&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# replace this with your domain&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/var/www/rancher-certbot-webroot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# The public and private parts of the certificate are linked here&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;ssl_certificate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/etc/letsencrypt/live/ssltest.busby.ninja/fullchain.pem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;ssl_certificate_key&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/etc/letsencrypt/live/ssltest.busby.ninja/privkey.pem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/.well-known&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/var/www/ssl-proof/rancher/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Host&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$scheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-Port&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$server_port&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;X-Forwarded-For&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_pass&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;http://rancher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_http_version&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Upgrade&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Connection&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;upgrade&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;proxy_read_timeout&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;900s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is quite a basic, naive way of setting up SSL but I’ll include instructions for increasing the security with extra configuration options in a future post.&lt;/p&gt;

&lt;p&gt;Once you’ve restarted nginx then you should confirm by navigating to your domain name. You should be redirected to HTTPS and served up rancher with a nice green padlock showing in the address bar.&lt;/p&gt;

&lt;p&gt;At this point, you’re basically done. You have your reverse proxy set up with a valid SSL cert (at least until the certificate expires) and you can repeat this process to proxy as many other services as you like.&lt;/p&gt;

&lt;h2 id=&quot;automated-renewal-and-revoking-certificates&quot;&gt;Automated renewal and revoking certificates&lt;/h2&gt;

&lt;p&gt;In order to renew your certificates, you simply run the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;c&quot;&gt;# You can add --dry-run to test without changes&lt;/span&gt;
./certbot-auto renew&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you have any certificates that are within the renewal window (usually 30 days before expiry, Let’s Encrypt certs typically expire after three months) then these will be automatically renewed. Given that we left the web-root infrastructure in place, this can be done without any interruption to the service.&lt;/p&gt;

&lt;p&gt;It’s a good idea to set up a &lt;a href=&quot;http://www.thegeekstuff.com/2009/06/15-practical-crontab-examples/&quot;&gt;cron job&lt;/a&gt; to run periodically. The consensus seems to be that you should run renew once or twice a day.&lt;/p&gt;

&lt;p&gt;If, at this point, you’ve followed the tutorial and understood it then you should revoke your certificate before destroying your instance or test environment. This is accomplished with the following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;c&quot;&gt;#Change the path to reflect your domain name&lt;/span&gt;
./certbot-auto revoke &lt;span class=&quot;nt&quot;&gt;--cert-path&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    /etc/letsencrypt/live/ssltest.busby.ninja/fullchain.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As a final note, I encourage you to have a read of &lt;a href=&quot;https://letsencrypt.org/getting-started/&quot;&gt;Let’s Encrypt’s own documentation&lt;/a&gt;. There are things I haven’t covered (such as acquiring one certificate for multiple domains) and the things they cover, they do so in more detail than me. If, like me, you find ngnix to be a very powerful, flexible piece of software then you can find their documentation &lt;a href=&quot;http://nginx.org/en/docs/&quot;&gt;here&lt;/a&gt;. I haven’t scratched the surface of what it’s capable of.&lt;/p&gt;

&lt;p&gt;Thank you to everyone who read this. (Constructive) feedback and corrections are always welcome.&lt;/p&gt;</content><author><name>tombusby</name></author><category term="blog" /><category term="letsencrypt" /><category term="privacy" /><category term="nginx" /><category term="proxy" /><category term="ssl" /><summary type="html">Motivation</summary></entry></feed>