<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Server on Techformist</title>
    <link>https://techformist.com/tags/server/</link>
    <description>Recent content in Server on Techformist</description>
    <image>
      <url>https://techformist.com/logo.svg</url>
      <link>https://techformist.com/logo.svg</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 11 Jun 2020 06:30:00 +0000</lastBuildDate><atom:link href="https://techformist.com/tags/server/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Setup Ubuntu VPS - First Few Steps</title>
      <link>https://techformist.com/ubuntu-vps-setup-first-steps/</link>
      <pubDate>Thu, 11 Jun 2020 06:30:00 +0000</pubDate>
      
      <guid>https://techformist.com/ubuntu-vps-setup-first-steps/</guid>
      <description>&lt;p&gt;I create virtual private servers at least 8-12 times an year for client and personal projects. The steps to go live remain the same -&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get a cheapo VPS on &lt;a href=&#34;https://m.do.co/c/9f3b578e40ef&#34;&gt;Digital Ocean&lt;/a&gt;, &lt;a href=&#34;https://www.vultr.com/?ref=8605620&#34;&gt;Vultr&lt;/a&gt; (&lt;a href=&#34;https://www.vultr.com/?ref=8605622-6G&#34;&gt;get $100 credit&lt;/a&gt;), Hetzner, OVH, and friends - I end up choosing Ubuntu as the OS&lt;/li&gt;
&lt;li&gt;Secure your server&lt;/li&gt;
&lt;li&gt;Setup app server, database server and tools&lt;/li&gt;
&lt;li&gt;Stitch together various components through configuration files&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have thought about switching to Docker (or Caprover) for months, but keep putting off any kind of automation. The adhoc sharing of DB servers, file systems, report/analytics servers make it a tricky exercise. I don&amp;rsquo;t quite spend more than 4 hours on a crazy day - so it&amp;rsquo;s not quite a big deal.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I create virtual private servers at least 8-12 times an year for client and personal projects. The steps to go live remain the same -</p>
<ol>
<li>Get a cheapo VPS on <a href="https://m.do.co/c/9f3b578e40ef">Digital Ocean</a>, <a href="https://www.vultr.com/?ref=8605620">Vultr</a> (<a href="https://www.vultr.com/?ref=8605622-6G">get $100 credit</a>), Hetzner, OVH, and friends - I end up choosing Ubuntu as the OS</li>
<li>Secure your server</li>
<li>Setup app server, database server and tools</li>
<li>Stitch together various components through configuration files</li>
</ol>
<p>I have thought about switching to Docker (or Caprover) for months, but keep putting off any kind of automation. The adhoc sharing of DB servers, file systems, report/analytics servers make it a tricky exercise. I don&rsquo;t quite spend more than 4 hours on a crazy day - so it&rsquo;s not quite a big deal.</p>
<p>Not being a sys admin myself I follow a few &ldquo;best practice&rdquo; steps recommended by smarter people on the Internet. Here&rsquo;s an easy-to-follow list for setting up a secure VPS.</p>
<h2 id="1-get-access-and-logon">1. Get Access and Logon</h2>
<p>I assume that you have -</p>
<ol>
<li>Already created the server using the browser console provided by your favourite service provider</li>
<li>You have chosen Ubuntu LTS (v20.4 at this time, though it should quite happily work the same for v18.4)</li>
<li>I use a Windows computer to connect to VPS. A few steps for configuring client will differ if you are using Linux or Mac</li>
</ol>
<p>Login to your server.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh root@<span class="p">&lt;</span>password_in_email<span class="p">&gt;</span>@<span class="p">&lt;</span>server_ip&gt;
</span></span></code></pre></div><p>You will get a message like this -</p>
<pre tabindex="0"><code>The authenticity of host &#39;11.11.111.111 (11.11.111.111)&#39; can&#39;t be established.
ECDSA key fingerprint is SHA256:XXBLAH.
Are you sure you want to continue connecting (yes/no)? yes
</code></pre><p>Enter <code>yes</code> to continue.</p>
<p>You can make this step more secure when creating servers with some providers like Hetzner. You can enter the SSH public key at the time of server creation and get seamless access to the server once it is created. We will get to the public key part soon.</p>
<p>Change root password.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">passwd
</span></span></code></pre></div><p>Enter new password for root. It is a good idea to store this in LastPass or some other password management tool.</p>
<p>Add a new admin user. This id will be the default to login to your server.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">adduser aweadmin
</span></span></code></pre></div><p>Enter password for new user. Next allow the new user to <code>sudo</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">usermod -aG sudo aweadmin
</span></span></code></pre></div><p>The goal is to get farther from defaults to make it more safe. This by itself will not completely secure the server, but reduce the risk of your server being of any interest to hackers.</p>
<h2 id="2-enable-automatic-security-updates">2. Enable Automatic Security Updates</h2>
<p>First, let us update the OS.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apt update
</span></span><span class="line"><span class="cl">apt dist-upgrade
</span></span></code></pre></div><p>Once the update is complete, reboot server.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">reboot
</span></span></code></pre></div><p>Your SSH session will disconnect and server will reboot. Re-login using SSH to your server.</p>
<p>Recent versions of Ubuntu have unattended updates by default. You can verify or change those updates -</p>
<pre tabindex="0"><code>sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
</code></pre><p>If you are using an older version, you may need to install and configure automatic updates.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apt install unattended-upgrades
</span></span><span class="line"><span class="cl">nano /etc/apt/apt.conf.d/50unattended-upgrades
</span></span></code></pre></div><p>Comment out everything other than the security updates.</p>
<pre tabindex="0"><code>Unattended-Upgrade::Allowed-Origins {
//      &#34;${distro_id}:${distro_codename}&#34;;
        &#34;${distro_id}:${distro_codename}-security&#34;;
        // Extended Security Maintenance; doesn&#39;t necessarily exist for
        // every release and this system may not have it installed, but if
        // available, the policy for updates is such that unattended-upgrades
        // should also install from here by default.
        &#34;${distro_id}ESM:${distro_codename}&#34;;
//      &#34;${distro_id}:${distro_codename}-updates&#34;;
//      &#34;${distro_id}:${distro_codename}-proposed&#34;;
//      &#34;${distro_id}:${distro_codename}-backports&#34;;
};
</code></pre><p>Save file with <code>Ctrl+O</code> &gt; <code>Enter</code>. Exit the editor with <code>Ctrl+X</code>.</p>
<p>So far you have configured automatic updates. Next, enable the automatic updates.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nano /etc/apt/apt.conf.d/20auto-upgrades
</span></span></code></pre></div><p>Copy/paste the following lines -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">APT::Periodic::Update-Package-Lists <span class="s2">&#34;1&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">APT::Periodic::Download-Upgradeable-Packages <span class="s2">&#34;1&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">APT::Periodic::AutocleanInterval <span class="s2">&#34;7&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">APT::Periodic::Unattended-Upgrade <span class="s2">&#34;1&#34;</span><span class="p">;</span>
</span></span></code></pre></div><h2 id="3-change-ssh-port-and-default-user-access">3. Change SSH Port and Default User Access</h2>
<p>We will do two things here -</p>
<ol>
<li>Change SSH port &amp; protocol</li>
<li>Enable additional SSH user and disable root access</li>
</ol>
<h3 id="change-port-and-use-protocol-2">Change Port and Use Protocol 2</h3>
<p>SSH uses port <code>22</code> by default. But, you can choose any free port between 1023 and 65535. You can find out whether a port is free with the following command -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ss -tulpn <span class="p">|</span> grep LISTEN
</span></span></code></pre></div><p>Open the config file and change the default <code>22</code> port used by SSH.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nano /etc/ssh/sshd_config
</span></span></code></pre></div><p>Find the line which begins with <code>Port</code> and change it -</p>
<pre tabindex="0"><code>Port 65432
</code></pre><p>While we are at it, let us also add a line to force SSH to always use <code>Protocol 2</code>. Just add the below line anywhere in the file.</p>
<pre tabindex="0"><code>Protocol 2
</code></pre><p><code>Ctrl+o</code> &gt; <code>Enter</code> + <code>Ctrl+x</code> to save and exit out of the editor.</p>
<p>Restart SSH.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl restart ssh
</span></span></code></pre></div><h3 id="enable-non-root-ssh-user">Enable non-root SSH user</h3>
<p>Open another command prompt. Try logging in to your server with the user id that was created earlier.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh -p 65432 aweadmin@11.11.111.111
</span></span></code></pre></div><p>Once you are in, try to run a <code>sudo</code> command.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ls /root
</span></span></code></pre></div><p>If things worked well so far, it is time to disable root login using SSH.</p>
<p>Open the SSH config on server.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo nano /etc/ssh/sshd_config
</span></span></code></pre></div><p>Change the below parameter to <code>no</code> and insert a new line to enable access for the new admin user.</p>
<pre tabindex="0"><code>PermitRootLogin no
AllowUsers aweadmin
</code></pre><p><code>Ctrl+o</code> &gt; <code>Enter</code> + <code>Ctrl+x</code> to save and exit out of the editor.</p>
<p>Restart SSH.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl restart ssh
</span></span></code></pre></div><p>Open yet another command prompt and try logging in as <code>root</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh -p 65432 root@11.11.111.111
</span></span></code></pre></div><p>This should not work but <code>aweadmin</code> will login without problems.</p>
<h2 id="4-disable-ssh-login-with-password">4. Disable SSH login with password</h2>
<p>If you ever check the security logs on your server, you will find a series of attempts to access your server with default user ids, ports and common passwords. In this section, we will disable SSH access using password altogether and enable only clients with trusted keys to login.</p>
<p>Let us first set up the client (which is our computer = not server).</p>
<p>Run following command to generate a public/private key on your computer.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh-keygen -N <span class="s2">&#34;securepassphrase&#34;</span> -t ed25519 -C <span class="s2">&#34;mycomputer&#34;</span>
</span></span></code></pre></div><ul>
<li><code>securepassphrase</code> - can be anything that you can remember but at the same time secures access to SSH server from your computer</li>
<li><code>ed25519</code> provides the encryption algorithm used to generate keys</li>
<li><code>mycomputer</code> is just a random name which is a description for the key. You may want to provide different descriptions on other computers</li>
</ul>
<p>Accept the default file names for public and private keys (or change them). You should have two files in <code>c:\user\&lt;user_name&gt;\.ssh\</code> folder.</p>
<ul>
<li><code>id_ed25519</code> - file with private key</li>
<li><code>id_ed25519.pub</code> - public key</li>
</ul>
<p>Next, we update the generated public key on the server.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh -p 65432 aweadmin@11.11.111.111
</span></span></code></pre></div><p>Create <code>.ssh</code> directory (if it doesn&rsquo;t exist) and create a new file within in.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir /home/aweadmin/.ssh
</span></span><span class="line"><span class="cl">nano /home/aweadmin/.ssh/authorized_keys
</span></span></code></pre></div><p>Copy / paste the public key from <code>id_ed25519.pub</code>.</p>
<p><code>Ctrl+o</code> &gt; <code>Enter</code> + <code>Ctrl+x</code> to save and exit out of the editor.</p>
<p>Change the default permission for the newly created file -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">chmod <span class="m">0600</span> /home/aweadmin/.ssh/authorized_keys
</span></span></code></pre></div><p>Open a command prompt on client, and login with key.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh aweadmin@11.11.11.1111
</span></span></code></pre></div><p>You will get a different prompt that asks for the key passphrase. Enter the passphrase to gain access to the server - you are not required to type the <code>aweadmin</code>&rsquo;s password again.</p>
<p>Next, we will disable password logins in the SSH config file -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo nano /etc/ssh/sshd_config
</span></span></code></pre></div><p>Change following parameter -</p>
<pre tabindex="0"><code>PasswordAuthentication no
</code></pre><p><code>Ctrl+o</code> &gt; <code>Enter</code> + <code>Ctrl+x</code> to save and exit out of the editor.</p>
<p>You are required to enter passphrase when logging in each time. We can work around that.</p>
<p>Go to <code>Start</code> &gt; <code>Services</code> to list Windows services (or <code>Start</code> &gt; <code>Run</code> &gt; Enter <code>services.msc</code>). You should find a service called <code>OpenSSH Authentication Agent</code> service that will be in <code>disabled</code> state by default. Enable the service to start automatically with Windows and start the service.</p>
<p>Go to <code>Start</code> &gt; <code>Run</code> &gt; type <code>notepad c:\&lt;user&gt;\.ssh\config</code>. Enter following lines -</p>
<pre tabindex="0"><code>Host 11.11.111.111
  User aweadmin
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  Port 65432
</code></pre><p>Save file. Ensure that the file is saved without the default <code>txt</code> extension.</p>
<p>You should now be able to login to the server without entering user id, password or key passphrase.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">ssh 11.11.111.111
</span></span></code></pre></div><p>If you use multiple computers, or want to provide access to other users, just repeat the steps to generate distinct private keys and update public key on the server.</p>
<h2 id="5-secure-your-server">5. Secure Your Server</h2>
<p>Let us install and enable software to secure the server.</p>
<h3 id="firewall">Firewall</h3>
<p>I typically use <code>UFW</code> because it is quite simple to setup and understand.</p>
<p>You can install / update <code>ufw</code> with -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install ufw
</span></span></code></pre></div><p>Check status by using -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw status
</span></span></code></pre></div><p>Configure <code>ufw</code> to allow SSH sessions on our SSH port. This is important since <code>ufw</code> closes all ports by default. Enable firewall.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw allow 65432/tcp
</span></span><span class="line"><span class="cl">sudo ufw <span class="nb">enable</span>
</span></span></code></pre></div><p>Open another command prompt and try accessing the server with default port - you should be able to login.</p>
<p>You can check the rules with the command -</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw show added
</span></span></code></pre></div><h3 id="intrusion-detection">Intrusion Detection</h3>
<p>We will install <code>Fail2Ban</code> to work alongside the firewall and secure our server. <code>fail2ban</code> is an intrusion detection and prevention framework that can automatically ban IPs temporarily (or otherwise) based on invalid login attempts.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo add-apt-repository universe
</span></span><span class="line"><span class="cl">sudo apt-update
</span></span><span class="line"><span class="cl">sudo apt install fail2ban
</span></span></code></pre></div><p>Copy the default config file to <code>jail.local</code> and restart service.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
</span></span><span class="line"><span class="cl">service fail2ban restart
</span></span></code></pre></div><h2 id="6-get-on-with-your-apps">6. Get on with your apps</h2>
<p>With your server setup you can start installing your applications. A few of those are super useful -</p>
<ol>
<li>
<p>Vim Editor</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt-get install vim
</span></span></code></pre></div></li>
<li>
<p>Install <code>fish</code> as default shell, and <code>omf</code> to configure <code>fish</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apt-get install fish
</span></span><span class="line"><span class="cl">chsh -s /usr/bin/fish
</span></span><span class="line"><span class="cl">curl -L https://get.oh-my.fish <span class="p">|</span> fish
</span></span></code></pre></div></li>
<li>
<p><a href="https://caddyserver.com/docs/install">Caddy Web server</a></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt-get install caddy
</span></span></code></pre></div></li>
<li>
<p>Install <a href="https://github.com/nodesource/distributions/blob/master/README.md">Node</a> (v12.x)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sL https://deb.nodesource.com/setup_12.x <span class="p">|</span> sudo -E bash -
</span></span><span class="line"><span class="cl">sudo apt-get install -y nodejs
</span></span></code></pre></div></li>
<li>
<p><a href="https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-18-04">Install MySQL database</a> and configure MySQL. You will also need to open port in <code>ufw</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install mysql-server
</span></span><span class="line"><span class="cl">sudo mysql_secure_installation
</span></span></code></pre></div></li>
</ol>
<p>That&rsquo;s all folks - enjoy your brand new VPS!</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
