<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aaron Peschel</title>
    <description>The latest articles on DEV Community by Aaron Peschel (@apeschel).</description>
    <link>https://dev.to/apeschel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1204120%2F54039f6e-a858-428a-b42b-eb230eba81d8.png</url>
      <title>DEV Community: Aaron Peschel</title>
      <link>https://dev.to/apeschel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/apeschel"/>
    <language>en</language>
    <item>
      <title>Compiling OpenVPN in an Ubuntu 14.04 Chroot</title>
      <dc:creator>Aaron Peschel</dc:creator>
      <pubDate>Tue, 07 Nov 2023 22:02:10 +0000</pubDate>
      <link>https://dev.to/apeschel/compiling-openvpn-in-an-ubuntu-1404-chroot-368</link>
      <guid>https://dev.to/apeschel/compiling-openvpn-in-an-ubuntu-1404-chroot-368</guid>
      <description>&lt;p&gt;Originally published by apeschel on July 11, 2016, 6:35 p.m. &lt;/p&gt;

&lt;h2&gt;
  
  
  Set up chroot build environment
&lt;/h2&gt;

&lt;p&gt;Digital Ocean has a good guide for setting up a build chroot available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-configure-chroot-environments-for-testing-on-an-ubuntu-12-04-vps"&gt;https://www.digitalocean.com/community/tutorials/how-to-configure-chroot-environments-for-testing-on-an-ubuntu-12-04-vps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only thing of note is that they recommend putting your chroot in your root &lt;code&gt;/&lt;/code&gt; directory on your base host. I suggest using &lt;code&gt;/srv/schroot/&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;The instructions provided here are for Ubuntu &lt;code&gt;trusty&lt;/code&gt;, which is what we will be using to build OpenVPN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;dchroot debootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /srv/schroot/ubuntu14.04
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;debootstrap &lt;span class="nt"&gt;--variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;buildd &lt;span class="nt"&gt;--arch&lt;/span&gt; amd64 trusty /srv/schroot/ubuntu14.04/ http://us.archive.ubuntu.com/ubuntu/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;proc                        /srv/schroot/ubuntu14.04/proc proc    defaults        0       0
sysfs                       /srv/schroot/ubuntu14.04/sys  sysfs   defaults        0       0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount proc /srv/schroot/ubuntu14.04/proc &lt;span class="nt"&gt;-t&lt;/span&gt; proc
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount sysfs /srv/schroot/ubuntu14.04/sys &lt;span class="nt"&gt;-t&lt;/span&gt; sysfs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/hosts /srv/schroot/ubuntu14.04/etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chroot&lt;/span&gt; /srv/schroot/ubuntu14.04/ /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set Up Build Environment
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.openvpn.net/openvpn/wiki/TesterDocumentation"&gt;https://community.openvpn.net/openvpn/wiki/TesterDocumentation&lt;/a&gt; &lt;a href="http://packaging.ubuntu.com/html/"&gt;http://packaging.ubuntu.com/html/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having a text editor in our chroot environment will reduce the number of times we have to leave and enter the chroot, thus it is installed for convenience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our chroot environment will have a very bare-bones &lt;code&gt;sources.list&lt;/code&gt;. We will need to add some entries to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/apt/sources.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deb-src http://us.archive.ubuntu.com/ubuntu trusty main

deb http://us.archive.ubuntu.com/ubuntu trusty universe
deb-src http://us.archive.ubuntu.com/ubuntu trusty universe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to update Ubuntu's &lt;code&gt;policy-rc.d&lt;/code&gt; to let it know that we are in a chroot environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /usr/sbin/policy-rc.d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following to the file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;exit &lt;/span&gt;101
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will install any additional build tools that will be required. We will use &lt;code&gt;bzr&lt;/code&gt; (bazzar) to build the OpenVPN package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
locale-gen en_US.UTF-8
apt-get update
apt-get &lt;span class="nb"&gt;install &lt;/span&gt;net-tools autoconf libtool dialog
apt-get &lt;span class="nb"&gt;install &lt;/span&gt;bzr bzr-builddeb devscripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build OpenVPN
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-get build-dep openvpn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Canonical Bazaar
&lt;/h2&gt;

&lt;p&gt;Here we download the 14.04 OpenVPN source in a new package branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
bzr branch lp:ubuntu/trusty/openvpn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TLS keys that are used for the OpenVPN tests in the 14.04 source have expired. This will cause the tests to fail. We can use the keys from the latest OpenVPN release instead to fix this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;git
git clone git://git.code.sf.net/p/openvpn/openvpn-testing openvpn-openvpn-testing
&lt;span class="nb"&gt;cp &lt;/span&gt;openvpn-openvpn-testing/sample/sample-keys/&lt;span class="k"&gt;*&lt;/span&gt; openvpn/sample/sample-keys/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to finally build the OpenVPN package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;openvpn
bzr bd &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-us&lt;/span&gt; &lt;span class="nt"&gt;-uc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build Raw binaries using make
&lt;/h3&gt;

&lt;p&gt;This will skip the testing phase, which takes a long time with the OpenVPN package. However, it will not create a package and will require installation via &lt;code&gt;make install&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
apt-get &lt;span class="nb"&gt;source &lt;/span&gt;openvpn
&lt;span class="nb"&gt;cd &lt;/span&gt;openvpn-&lt;span class="k"&gt;*&lt;/span&gt;
autoreconf &lt;span class="nt"&gt;-vi&lt;/span&gt;
./configure
make all
make check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build openvpn-auth-ldap
&lt;/h2&gt;

&lt;p&gt;This follows the same core process as building the OpenVPN package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-get build-dep openvpn-auth-ldap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Canonical Bazaar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
bzr branch lp:ubuntu/trusty/openvpn-auth-ldap
&lt;span class="nb"&gt;cd &lt;/span&gt;openvpn-auth-ldap
bzr bd &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-us&lt;/span&gt; &lt;span class="nt"&gt;-uc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Make
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
apt-get &lt;span class="nb"&gt;source &lt;/span&gt;openvpn-auth-ldap
&lt;span class="nb"&gt;cd &lt;/span&gt;openvpn-auth-ldap-&lt;span class="k"&gt;*&lt;/span&gt;
./configure
make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ubuntu</category>
      <category>openvpn</category>
      <category>buildtools</category>
      <category>linux</category>
    </item>
    <item>
      <title>Using Native Python Libraries in Lambda</title>
      <dc:creator>Aaron Peschel</dc:creator>
      <pubDate>Tue, 07 Nov 2023 20:06:54 +0000</pubDate>
      <link>https://dev.to/apeschel/using-native-python-libraries-in-lambda-39a1</link>
      <guid>https://dev.to/apeschel/using-native-python-libraries-in-lambda-39a1</guid>
      <description>&lt;p&gt;It is possible to use native libraries in Amazon Lambda. In this example, we will be building a native &lt;code&gt;bcrypt&lt;/code&gt; library against &lt;code&gt;libcrypt&lt;/code&gt;, using &lt;code&gt;virtualenv&lt;/code&gt; to manage our libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create an Amazon EC2 Instance to build the native library
&lt;/h2&gt;

&lt;p&gt;Amazon Lambda runs on the Amazon Linux distribution, so we will need to target our compiled libraries against this distribution. Unfortunately, there doesn't appear to be any sort of &lt;code&gt;debootstrap&lt;/code&gt; equivalent for Amazon Linux, so an instance using Amazon Linux will be needed for the build process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create an instance using Amazon Linux&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect to the server&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Set up the build environment on the server
&lt;/h2&gt;

&lt;p&gt;We will need to install the build tools for the library we are building, as well as any build dependencies that are required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum update
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; gcc44 gcc-c++ libgcc44 cmake
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; python27-devel python27-pip gcc libjpeg-devel zlib-devel gcc-c++
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;libffi-devel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Update/upgrade pip and setuptools
&lt;/h2&gt;

&lt;p&gt;Make sure you are using the latest version of pip to prevent any issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip update
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip setuptools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set up Virtualenv for your project
&lt;/h2&gt;

&lt;p&gt;We will need to package any libraries that the lambda requires along with the lambda. Virtualenv provides us with a convenient method to bundle the libraries along with our lambda function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a directory for your project, and enter it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nv"&gt;$WORK&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$WORK&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;virtualenv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Activate virtualenv and install libraries
&lt;/h2&gt;

&lt;p&gt;Here we will build and install the libraries into the virtualenv directory, which will make them available for packaging later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bcrypt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Place your lambda function into the working directory.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/lambda_function.py &lt;span class="nv"&gt;$WORK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verify the script is working as expected.
&lt;/h2&gt;

&lt;p&gt;Run your lambda and/or tests locally to verify all the libraries are working as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Package the project, according to the lambda requirements.
&lt;/h2&gt;

&lt;p&gt;Here's the tricky part -- Amazon Lambda requires all the libraries to be at the top level in the zip file that you upload. The following will create a zip file with the lambda function and all required libraries at the top level of the zip file. Since virtualenv contains all the libraries that we need for the project, we will copy all the libraries from the virtualenv environment to the zip file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;zip &lt;span class="nt"&gt;-9&lt;/span&gt; bcrypt_lambda.zip lambda_function.py
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;/lib/python2.7/site-packages
&lt;span class="nv"&gt;$ &lt;/span&gt;zip &lt;span class="nt"&gt;-r9&lt;/span&gt; &lt;span class="nv"&gt;$WORK&lt;/span&gt;/bcrypt_lambda.zip &lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;/lib64/python2.7/site-packages
&lt;span class="nv"&gt;$ &lt;/span&gt;zip &lt;span class="nt"&gt;-r9&lt;/span&gt; &lt;span class="nv"&gt;$WORK&lt;/span&gt;/bcrypt_lambda.zip &lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Upload the zip to Amazon Lambda.
&lt;/h2&gt;

&lt;p&gt;Now that you have the zip file, upload it to Amazon Lambda as you normally would. Remember to set up the test data for the lambda to verify that the function is working as expected.&lt;/p&gt;

</description>
      <category>lambda</category>
      <category>aws</category>
      <category>python</category>
    </item>
    <item>
      <title>Impact of Hosting Large Numbers of Nginx SSL VHosts</title>
      <dc:creator>Aaron Peschel</dc:creator>
      <pubDate>Tue, 07 Nov 2023 18:22:41 +0000</pubDate>
      <link>https://dev.to/apeschel/impact-of-hosting-large-numbers-of-nginx-ssl-vhosts-4me5</link>
      <guid>https://dev.to/apeschel/impact-of-hosting-large-numbers-of-nginx-ssl-vhosts-4me5</guid>
      <description>&lt;p&gt;Originally posted by apeschel on Aug. 19, 2015, 6:08 p.m. &lt;/p&gt;

&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;A question was raised recently about what the impact of hosting extremely large amounts of SSL certificates via Nginx would be. This document provides an explanation of how Nginx manages SSL, provides data about the impact of hosting large numbers of certificates, and provides an analysis of what the data means.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Nginx Manages SSL Certificates
&lt;/h2&gt;

&lt;p&gt;Logically, each SSL certificate will be associated with a separate host. In Nginx, separate hosts are managed via VHosts. A VHost is a collection of the IP, Port, Hostname, and other relevant data about a host. Nginx collects the information relevant to a VHosts into a &lt;code&gt;ngx_http_core_srv_conf_t&lt;/code&gt; struct. These structs are contained within the &lt;code&gt;server_names_hash&lt;/code&gt;, which uses the hostname string as a key.&lt;/p&gt;

&lt;p&gt;Nginx defers SSL management to OpenSSL. It stores certificates in OpenSSL's &lt;code&gt;SSL_CTX&lt;/code&gt; global context structure, and uses the OpenSSL API for any SSL-related interaction between the client and server.&lt;/p&gt;

&lt;p&gt;When a connection is made to an nginx server, nginx looks up the given hostname in its server names hash, to find the relevant structure containing the information for that VHost. Once the struct is found, it can use the OpenSSL API to establish the SSL connection with the correct certificate for the requested domain.&lt;/p&gt;

&lt;p&gt;There is an upper limit on the number of VHosts that Nginx can fit into its server hash. This upper limit is configurable via two settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server_names_hash_bucket_size
server_names_hash_max_size
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For optimal performance, server_names_hash_bucket_size should be set to the same size as your processor's cache line. In Linux, you can find this value at &lt;code&gt;/sys/devices/system/cpu/cpu0/cache/index*/coherency_line_size&lt;/code&gt;. This leaves you with &lt;code&gt;server_names_hash_max_size&lt;/code&gt; as the value that should be modified to increase the VHosts maximum.&lt;/p&gt;

&lt;p&gt;For more information about how Nginx manages this stuff, refer to the following Nginx docs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/hash.html"&gt;Setting up hashes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/en/docs/http/request_processing.html"&gt;How nginx processes a request&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing and Analyzing Nginx Performance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;A simple Nginx host was set up in Digital Ocean for testing. The tests were run on a 2CPU / 2GB instance.&lt;/p&gt;

&lt;p&gt;For each iteration, all VHosts were running SSL on the same IP:Port pair, utilizing SNI to do so. Each VHost was configured with an SSL certificate, a corresponding private key, and a unique static file to host. All SSL certificates were generated using a 4096-bit RSA key.&lt;/p&gt;

&lt;p&gt;siege was used for stress testing. All the hostnames were put into urls.txt, which is what siege uses to determine what hosts to send traffic to. Siege was configured to use 100 concurrently running clients, with each client attempting to retrieve 50 pages from hosts listed in urls.txt. This totals to 5000 total pages requested from the Nginx host, spread across all the VHosts running on it.&lt;/p&gt;

&lt;p&gt;It was noted to me after initially writing this article that siege did not support SNI. It seemed unlikely that SNI support on the client side would have any impact on the results. In the interest of accuracy, I worked with the siege maintainer to add support for SNI and reran the tests. As expected, there was no impact on the results.&lt;/p&gt;

&lt;p&gt;The goal of this testing was to determine the memory and performance overhead of hosting a large number of SSL certificates. This means the servers do not very closely reflect what an actual production host would look like. This is a deliberate attempt to isolate only the dependent variables for testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summarized Results
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|Num Certs|Memory (KiB)|Time (seconds)|
---------------------------------------
|        1|        3000|            41|
|        2|        3200|            42|
|      100|        9600|            41|
|     1000|       40000|            44|
|    10000|      370000|            43|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Analysis
&lt;/h3&gt;

&lt;p&gt;Nginx took approximately the same amount of time, regardless of the number of VHosts. This is what would be expected from Nginx's use of a hash for managing the VHosts.&lt;/p&gt;

&lt;p&gt;Performing a linear regression against the memory data provides us with the following relationship:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;m = 3900 + 37 * n

Where

m = Expected Memory Usage (in KiB)
n = Num of VHosts using SSL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates that each additional VHost consumes approximately 37 KiB of memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Raw Data
&lt;/h2&gt;

&lt;p&gt;The following values are used unless otherwise noted;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server_names_hash_bucket_size: 64
server_names_hash_max_size: 512
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  No Certificates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root      1740  0.0  0.1  85880  1344 ?        Ss   18:36   0:00 nginx: master process /usr/sbin/nginx
www-data  1741  0.0  0.2  86224  2268 ?        S    18:36   0:00  \_ nginx: worker process
www-data  1742  0.0  0.2  86224  2276 ?        S    18:36   0:00  \_ nginx: worker process
www-data  1743  0.0  0.2  86224  2408 ?        S    18:36   0:00  \_ nginx: worker process
www-data  1744  0.0  0.1  86224  2028 ?        S    18:36   0:00  \_ nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;siege -q -b -c 100 -r 50 http://1.apestest/

Transactions:                   5000 hits
Availability:                 100.00 %
Elapsed time:                  17.87 secs
Data transferred:               1.83 MB
Response time:                  0.30 secs
Transaction rate:             279.80 trans/sec
Throughput:                     0.10 MB/sec
Concurrency:                   83.88
Successful transactions:        5000
Failed transactions:               0
Longest transaction:            4.11
Shortest transaction:           0.05
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One Certificate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root      1740  0.0  0.2  85992  3012 ?        Ss   18:36   0:00 nginx: master process /usr/sbin/nginx
www-data  2377  0.0  0.1  86276  1904 ?        S    19:10   0:00  \_ nginx: worker process
www-data  2378  0.0  0.1  86276  1904 ?        S    19:10   0:00  \_ nginx: worker process
www-data  2379  0.0  0.1  86276  1904 ?        S    19:10   0:00  \_ nginx: worker process
www-data  2380  0.0  0.3  86276  3116 ?        S    19:10   0:00  \_ nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;siege -q -b -c 100 -r 50 https://1.apestest/

Transactions:                   5000 hits
Availability:                 100.00 %
Elapsed time:                  40.97 secs
Data transferred:               1.83 MB
Response time:                  0.73 secs
Transaction rate:             122.04 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                   89.43
Successful transactions:        5000
Failed transactions:               0
Longest transaction:            5.80
Shortest transaction:           0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Two Certificates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root      1740  0.0  0.3  86680  3216 ?        Ss   Aug10   0:00 nginx: master process /usr/sbin/nginx
www-data 22502  0.0  0.1  86680  1992 ?        S    21:32   0:00  \_ nginx: worker process
www-data 22503  0.3  0.3  86680  3440 ?        S    21:32   0:00  \_ nginx: worker process
www-data 22504  0.0  0.1  86680  1992 ?        S    21:32   0:00  \_ nginx: worker process
www-data 22505  0.0  0.1  86680  1992 ?        S    21:32   0:00  \_ nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;siege -q -b -c 100 -r 50

Transactions:                   5000 hits
Availability:                 100.00 %
Elapsed time:                  41.92 secs
Data transferred:               1.83 MB
Response time:                  0.75 secs
Transaction rate:             119.27 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                   89.68
Successful transactions:        5000
Failed transactions:               0
Longest transaction:            7.86
Shortest transaction:           0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One Hundred Certificates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root      1740  0.0  0.9  92476  9560 ?        Ss   Aug10   0:00 nginx: master process /usr/sbin/nginx
www-data 30236  0.0  0.8  92476  8156 ?        S    13:13   0:00  \_ nginx: worker process
www-data 30237  0.0  0.8  92476  8156 ?        S    13:13   0:00  \_ nginx: worker process
www-data 30238  0.0  0.8  92476  8156 ?        S    13:13   0:00  \_ nginx: worker process
www-data 30239  0.0  0.8  92476  8156 ?        S    13:13   0:00  \_ nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;siege -q -b -c 100 -r 50

Transactions:                   5000 hits
Availability:                 100.00 %
Elapsed time:                  40.50 secs
Data transferred:               0.67 MB
Response time:                  0.73 secs
Transaction rate:             123.46 trans/sec
Throughput:                     0.02 MB/sec
Concurrency:                   90.17
Successful transactions:           0
Failed transactions:               0
Longest transaction:            6.91
Shortest transaction:           0.00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  One Thousand Certificates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server_names_hash_max_size: 1024
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root       912  0.0  1.9 124704 40272 ?        Ss   Aug17   0:00 nginx: master process /usr/sbin/nginx
www-data  6543 18.2  1.9 124704 40288 ?        S    02:54   1:01  \_ nginx: worker process
www-data  6544 17.3  1.9 124704 40288 ?        S    02:54   0:58  \_ nginx: worker process
www-data  6545 18.2  1.9 124704 40288 ?        S    02:54   1:01  \_ nginx: worker process
www-data  6546 16.3  1.9 124704 40288 ?        S    02:54   0:55  \_ nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10079&amp;gt; siege -q -b -c 100 -r 50

Transactions:                   5000 hits
Availability:                 100.00 %
Elapsed time:                  43.83 secs
Data transferred:               1.83 MB
Response time:                  0.77 secs
Transaction rate:             114.08 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                   87.71
Successful transactions:        5000
Failed transactions:               0
Longest transaction:           17.73
Shortest transaction:           0.13
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ten Thousand Certificates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server_names_hash_max_size: 16384
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root       912  0.0 17.8 449596 365304 ?       Ss   Aug17   0:04 nginx: master process /usr/sbin/nginx
www-data 15625  0.0 17.7 449596 363992 ?       S    03:09   0:00  \_ nginx: worker process
www-data 15626  0.0 17.7 449596 363992 ?       S    03:09   0:00  \_ nginx: worker process
www-data 15627  0.0 17.7 449596 363992 ?       S    03:09   0:00  \_ nginx: worker process
www-data 15628  0.0 17.7 449596 363992 ?       S    03:09   0:00  \_ nginx: worker process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;siege -q -b -c 100 -r 50

Transactions:                   5000 hits
Availability:                 100.00 %
Elapsed time:                  42.71 secs
Data transferred:               1.83 MB
Response time:                  0.74 secs
Transaction rate:             117.07 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                   87.15
Successful transactions:        5000
Failed transactions:               0
Longest transaction:           14.30
Shortest transaction:           0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nginx</category>
      <category>tls</category>
      <category>networking</category>
    </item>
    <item>
      <title>Bringing Up a Bonded Interface in Linux Without a Reboot</title>
      <dc:creator>Aaron Peschel</dc:creator>
      <pubDate>Tue, 07 Nov 2023 11:26:11 +0000</pubDate>
      <link>https://dev.to/apeschel/bringing-up-a-bonded-interface-in-linux-without-a-reboot-4o6m</link>
      <guid>https://dev.to/apeschel/bringing-up-a-bonded-interface-in-linux-without-a-reboot-4o6m</guid>
      <description>&lt;p&gt;Originally by apeschel on Jan. 28, 2015, 7:18 p.m.&lt;/p&gt;

&lt;p&gt;There was an issue with some servers I was working on recently where two interfaces were meant to be set up with bonding. Unfortunately, due to a misunderstanding, the servers were brought up and put into production without the bonding being set up. When the problem was noticed later, the initial assumption was that fixing the bonding would require a reboot, which meant we would need to schedule downtime for the servers. We had a week scheduled to cycle through the servers, but I was determined to find a way to cut down the time by figuring out how to fix the bonding without a reboot.&lt;/p&gt;

&lt;p&gt;After digging around, and asking around on FreeNode, I was not able to find anyone who had come up with a solution to this problem. So I did some experimentation, and came up with a process that only resulted in a couple seconds of downtime for each server while the IP switched from eth0 to bond0.&lt;/p&gt;

&lt;p&gt;The initial state of the servers looked like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq state UP qlen 1000
    link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
    inet 1.1.1.2/24 brd 1.1.1.255 scope global eth0
3: eth1: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether aa:bb:cc:dd:ee:f1 brd ff:ff:ff:ff:ff:ff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the IP address is associated with the eth0 interface, and neither interface is associated with the bond.&lt;/p&gt;

&lt;p&gt;The first step is to get the corrected configs for the interfaces in place. These servers were running Ubuntu, which uses &lt;code&gt;/etc/network/interfaces&lt;/code&gt; for managing interfaces. After reading the associated &lt;a href="https://www.kernel.org/doc/Documentation/networking/bonding.txt"&gt;kernel documentation&lt;/a&gt;, I came up with the following config. Read through the kernel docs and update the config for your distribution according to what you need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual
  bond-master bond0
  bond-primary eth0 eth1

auto eth1
iface eth1 inet manual
  bond-master bond0
  bond-primary eth0 eth1

auto bond0
iface bond0 inet static
  bond-slaves none
  bond-mode 802.3ad
  bond-miimon 100
  address 1.1.1.2
  netmask 255.255.255.0
  gateway 1.1.1.2
  bond-xmit_hash_policy layer3+4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final step is to enact the changes. There is risk involved in doing this via a network connection. I was able to do this via SSH by taking down the interfaces and bringing them back up all in one command. Having a local console open on the machine is a better method, in case something goes wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ifdown eth0 &amp;amp;&amp;amp; sudo ifdown eth1 &amp;amp;&amp;amp; sudo ifup eth0 &amp;amp;&amp;amp; sudo ifup eth1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the IP address will be associated with both the eth0 and bond0 interfaces, and needs to be cleared from eth0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ip addr del 1.1.1.2/24 dev eth0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now everything should be set up correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: &amp;lt;BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq master bond0 state UP qlen 1000
    link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
3: eth1: &amp;lt;BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP&amp;gt; mtu 1500 qdisc mq master bond0 state UP qlen 1000
    link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
6: bond0: &amp;lt;BROADCAST,MULTICAST,MASTER,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP
    link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff
    inet 1.1.1.2/24 brd 1.1.1.255 scope global bond0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>networking</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
