<?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: ant Kenworthy</title>
    <description>The latest articles on DEV Community by ant Kenworthy (@mcrmonkey).</description>
    <link>https://dev.to/mcrmonkey</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%2F298001%2Ffbcb3dbe-a14d-48cf-8a89-76a36da2f484.png</url>
      <title>DEV Community: ant Kenworthy</title>
      <link>https://dev.to/mcrmonkey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mcrmonkey"/>
    <language>en</language>
    <item>
      <title>Linux Firewall: Blocking a lot with a little</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Fri, 30 Aug 2024 17:00:00 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/linux-firewall-blocking-a-lot-with-a-little-4bk7</link>
      <guid>https://dev.to/mcrmonkey/linux-firewall-blocking-a-lot-with-a-little-4bk7</guid>
      <description>&lt;p&gt;I have a need to block a large list of ever changing IP addresses from servers and systems I operate.&lt;/p&gt;

&lt;p&gt;The list of IP's I'm using can change hour by hour based on certain signals obtained from different logging and monitoring systems that are in place and some times the list of IP's can belong to an entire country!&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Blocking
&lt;/h2&gt;

&lt;p&gt;I can block single things easily with iptables by using this on the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -A INPUT -s 1.1.1.1 -j REJECT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will &lt;code&gt;REJECT&lt;/code&gt; incoming connections from &lt;code&gt;1.1.1.1&lt;/code&gt; ( Cloudflaire's public DNS resolver )&lt;/p&gt;

&lt;p&gt;You probably don't want to do this as its just an example of a simple block command but the IP address listed there can be changed for something different or it can be changed for a network prefix for example &lt;code&gt;10.0.0.0/16&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Grouping things
&lt;/h2&gt;

&lt;p&gt;I can create an additional &lt;code&gt;Chain&lt;/code&gt; in iptables to group a bunch of things together.&lt;/p&gt;

&lt;p&gt;for example, I may want to filter things heading to my mail services&lt;br&gt;
I'd create a new chain with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -N mail-services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I would point all of my mail services in that direction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -A INPUT -p tcp -m multiport --dports 25,465,587,143,993,110,995 -j mail-services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As before I can then add in specific rules for servers to the &lt;code&gt;mail-services&lt;/code&gt; chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -A mail-services -s 1.1.1.1 -j REJECT
iptables -A mail-services -s 8.8.8.8 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example I am rejecting connections from &lt;code&gt;1.1.1.1&lt;/code&gt; but &lt;code&gt;ACCEPT&lt;/code&gt;ing connections from &lt;code&gt;8.8.8.8&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending further
&lt;/h2&gt;

&lt;p&gt;Now I have a chain setup for my mail services I can now start blocking ( or allowing ) certain sources attempting to connect.&lt;/p&gt;

&lt;p&gt;I have a handy selection of IP addresses gathered from my monitoring systems of IP addresses that are stored safely within a database which I can access by running a local script.&lt;/p&gt;

&lt;p&gt;The script returns a list of IP addresses from the database on each line.&lt;/p&gt;

&lt;p&gt;The output of the script would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.1.1.1
1.1.2.2
192.168.1.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;etc&lt;/p&gt;

&lt;p&gt;I make use of this script output by wrapping it in another shell script like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
## Flush the mail-services chain
iptables -F mailservices
for ipaddr in $(./spot-block-ips); do iptables -A mail-services -s ${ipaddr} -j REJECT; done

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add in all IP addresses flagged to be blocked to the servers firewall after all the old ones have been cleaned out ("flushed")&lt;/p&gt;

&lt;h2&gt;
  
  
  CPU Overhead
&lt;/h2&gt;

&lt;p&gt;This works really well when there's a nice handful of IP's to block from the mail services.&lt;/p&gt;

&lt;p&gt;However, now the list has grown quite large there is a slight overhead on CPU time to do this now.&lt;/p&gt;

&lt;h2&gt;
  
  
  IPset's
&lt;/h2&gt;

&lt;p&gt;Turns out there's a better way of doing firewalling with much bigger lists and that's by using &lt;code&gt;ipset&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;From the man page for the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ipset is used to set up, maintain and inspect so called IP sets in the Linux kernel. Depending on the type of the set, an IP set may store IP(v4/v6) addresses, (TCP/UDP) port numbers, IP and MAC address pairs, IP address and port number pairs, etc. See the set type definitions below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may need to install that tool to use it. On Debian based distributions that will be &lt;code&gt;apt install ipset&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;To simplify this process a little; if an IP address has broken one of our rules we'll now block it outright from all services rather than just the services it has attacked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a new set
&lt;/h3&gt;

&lt;p&gt;Run the following command to create a new ipset called &lt;code&gt;blocklist&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ipset create blocklist hash:net counters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:&lt;br&gt;
Its best to try and plan ahead here when you create a new set.&lt;br&gt;
&lt;code&gt;hash:net&lt;/code&gt; will define how the IP addresses are stored in the set inside the kernel&lt;/p&gt;

&lt;p&gt;by specifying &lt;code&gt;ip&lt;/code&gt; here, in place of &lt;code&gt;net&lt;/code&gt;, it will allow for single IP's and network blocks of IP addresses. &lt;br&gt;
be aware however; adding a netblock of &lt;code&gt;192.168.1.0/24&lt;/code&gt; will add in 192.168.1.0, 192.168.1.1, 192.168.1.2 etc individually.&lt;br&gt;
You may opt to select &lt;code&gt;ip&lt;/code&gt; here in place of &lt;code&gt;net&lt;/code&gt; depending on your needs. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;counters&lt;/code&gt; option here allows us to keep an eye on the number of hits we've had against an IP address in a similar fashion to how we would see this in iptables list entries ( &lt;code&gt;iptables -L INPUT -v -n&lt;/code&gt; )&lt;/p&gt;

&lt;p&gt;If items are present in the list but are getting no hits then the IP address could perhaps be flagged for removal from the block list.&lt;/p&gt;
&lt;h3&gt;
  
  
  Populating the list
&lt;/h3&gt;

&lt;p&gt;We can very easily adapt the wrapper script from earlier to use this new set.&lt;/p&gt;

&lt;p&gt;here is an updated version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
for ipaddr in $(./spot-block-ips); do ipset add -exist blocklist ${ipaddr}; done

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the number of IP address you have to hand this may take a moment to complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the list
&lt;/h3&gt;

&lt;p&gt;Now the list is populated we have to make use of it.&lt;br&gt;
As mentioned earlier we're not paying attention to the service the IP is trying to access anymore, we're just blocking all services for that IP instead.&lt;/p&gt;

&lt;p&gt;Run the following to enable the ipset list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -A INPUT -m set --match-set blocklist src -j REJECT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done !&lt;/p&gt;

&lt;p&gt;The list is now in use on your system and you should be blocking the things you've decided to block! 🎉&lt;/p&gt;

&lt;p&gt;Depending on the frequency of a connection attempt you should be able to see any new hits by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ipset list blocklist |less
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updating the list
&lt;/h3&gt;

&lt;p&gt;From time to time you may want to add or remove items to the list&lt;/p&gt;

&lt;p&gt;you can use the &lt;code&gt;ipset add blocklist &amp;lt;ip&amp;gt;&lt;/code&gt; and &lt;code&gt;ipset del blocklist &amp;lt;ip&amp;gt;&lt;/code&gt; to add and remove single items on the list.&lt;/p&gt;

&lt;p&gt;You can also clean out the list with the &lt;code&gt;flush&lt;/code&gt; option&lt;/p&gt;

&lt;p&gt;The wrapper script in use here will add IP addresses to the list regardless of if they are present or not but will not remove them.&lt;/p&gt;

&lt;p&gt;A fix for this would be to use a temporary list and then switch the lists round.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

## End the script if there's an issue
set -e

## Create a new temp blocklist
ipset create blocklist-tmp

## Add IP addresses to it
for ipaddr in $(./spot-block-ips); do ipset add -exist blocklist-tmp ${ipaddr}; done

## Swap the tmp list in place of the old list 
ipset swap blocklist-tmp blocklist

## Destroy the now old list
ipset destroy blocklist-tmp

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a better way of performing updates to our lists as there is now no gap between the iptables flush command and the new IP addresses making an appearance. &lt;/p&gt;

&lt;h2&gt;
  
  
  Dedicated firewalling
&lt;/h2&gt;

&lt;p&gt;You'll correctly ask why dedicated firewalls, Hardware or otherwise, are not in use for this.&lt;/p&gt;

&lt;p&gt;While they are already in use for more static rules some service providers some times struggle with the number of entries and frequency of updates to the IP addresses in the system that are put through.&lt;/p&gt;

&lt;p&gt;At time of writing there's about 7741 IP entries in the database with would mean multiple entries with cloud providers or many hours of work with others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;By switching the list of blocked IP addresses out of a multi rule iptables chain in to a hash list stored in the kernel we saved about 1% cpu overhead on the systems its deployed on.&lt;/p&gt;

&lt;p&gt;🎉&lt;/p&gt;

</description>
      <category>linux</category>
      <category>firewall</category>
      <category>iptables</category>
      <category>ipsets</category>
    </item>
    <item>
      <title>Packer: Using an image family from another project</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Mon, 22 Mar 2021 21:45:23 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/packer-using-a-family-from-another-project-52j</link>
      <guid>https://dev.to/mcrmonkey/packer-using-a-family-from-another-project-52j</guid>
      <description>&lt;p&gt;Following on from my previous post: &lt;a href="https://dev.to/mcrmonkey/packer-building-images-on-google-cloud-ape"&gt;Packer: Building images on Google Cloud&lt;/a&gt; You should now be able to build compute images on GCP and you may have used this to build a pre-configured image you can effortlessly deploy again and again without having to wait to install software.&lt;/p&gt;

&lt;p&gt;You may now want to use that image, or someone else's image from a different project as a starting point for your web or database server.&lt;/p&gt;

&lt;p&gt;If you do you, can add the following line to your packer template in the builders section to specify another project to source your image from:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Here's how that may look when used in your packer template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"builders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"googlecompute"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-central1-a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source_image_family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"base-image-linux"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source_image_project_id"&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ssh_username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"packer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"packer-{{timestamp}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image_family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"socks-web"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;base-image-linux&lt;/code&gt; may contain our companies standard logging setup and common utilities. From this you could then install your web server or database utilities on top of that common image.&lt;/p&gt;

&lt;p&gt;Another example may be to use the public images provided by a regulatory body where you need to add some helper scripts before you deploy it to your project.&lt;/p&gt;

&lt;p&gt;🎉&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>gcp</category>
      <category>packer</category>
    </item>
    <item>
      <title>Google Cloud: IAM Conditions</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Mon, 15 Mar 2021 23:32:55 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/google-cloud-iam-conditions-4l0f</link>
      <guid>https://dev.to/mcrmonkey/google-cloud-iam-conditions-4l0f</guid>
      <description>&lt;p&gt;We can use IAM to control who has access to what within our project and who can do what to things like storage buckets, but what if we wanted to restrict &lt;em&gt;when&lt;/em&gt; someone could do something or to &lt;em&gt;what&lt;/em&gt; object in a bucket. That's where IAM Conditions come in to play.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are IAM Conditions ?
&lt;/h2&gt;

&lt;p&gt;IAM conditions are one or more rules written in "CEL" or Common Expression Language. Each rule must evaluate as true before the defined access role associated with it is permitted.&lt;br&gt;
These rules can specify the type of resource we want to control, time, date's and some string operations.&lt;/p&gt;

&lt;p&gt;Here is a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource.type == "compute.googleapis.com/Instance"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are expecting the resource type we're trying to use to be an instance ( which are part of the compute API ). If the resource we are trying to use is something else this condition will fail and our request will be denied.&lt;/p&gt;

&lt;p&gt;There's more information about CEL and its specifications &lt;a href="https://github.com/google/cel-spec/blob/master/doc/langdef.md"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Can you give some examples ?
&lt;/h2&gt;

&lt;p&gt;Sure, here's one which will restrict access to a specific time period and between certain days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;request.time.getHours("Europe/London") &amp;gt;= 9 &amp;amp;&amp;amp;
request.time.getHours("Europe/London") &amp;lt;= 17 &amp;amp;&amp;amp;
// Days of the week range from 0 to 6, where 0 == Sunday and 6 == Saturday.
request.time.getDayOfWeek("Europe/London") &amp;gt;= 1 &amp;amp;&amp;amp;
request.time.getDayOfWeek("Europe/London") &amp;lt;= 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When combined with &lt;code&gt;roles/compute.admin&lt;/code&gt; it would restrict the user and/or group to only be granted the role during office hours ( Monday to Friday between 9am and 5pm ). &lt;/p&gt;

&lt;p&gt;Here's another that can be used to restrict what objects in a storage bucket can be manipulated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource.type == "storage.googleapis.com/Bucket" &amp;amp;&amp;amp;
resource.name.startsWith("projects/_/buckets/inputbucket-001/objects/example-folder")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When combined with the role &lt;code&gt;roles/storage.objectCreator&lt;/code&gt; it would restrict the user and/or group so that its only able to create new objects in our bucket named &lt;code&gt;inputbucket-001&lt;/code&gt; in the folder &lt;code&gt;example-folder&lt;/code&gt;. Uploading to the root of the bucket or any other root level folder would be denied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are there any limitations to using IAM conditions ?
&lt;/h2&gt;

&lt;p&gt;Yes, there are some:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;They cannot be used with basic roles ( formally "primitive" ), &lt;code&gt;allUsers&lt;/code&gt; or &lt;code&gt;allAuthenticatedUsers&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They only work with certain services at the moment. Check the &lt;a href="https://cloud.google.com/iam/docs/conditions-overview#resources"&gt;documentation here&lt;/a&gt; for more information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a maximum number of 12 logical operators in one condition expression&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a maximum of 20 role bindings for same role and same member&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is a maximum of 100 conditional role bindings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Attempting to exceed these limits will return a fail message when you apply your change.&lt;/p&gt;

&lt;p&gt;Also, conditional role bindings will not override role bindings with no conditions. If a user and/or group is bound to a role which does not have a condition, then the member always has that role. Adding the member to a conditional binding for the same role will have no effect&lt;/p&gt;

&lt;h2&gt;
  
  
  Can this be applied via terraform ?
&lt;/h2&gt;

&lt;p&gt;Yes! Here's an example directly from the &lt;a href="https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam#google_project_iam_member"&gt;terraform documentation&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_project_iam_member"&lt;/span&gt; &lt;span class="s2"&gt;"project"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"your-project-id"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"roles/firebase.admin"&lt;/span&gt;
  &lt;span class="nx"&gt;member&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"user:jane@example.com"&lt;/span&gt;

  &lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"expires_after_2019_12_31"&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Expiring at midnight of 2019-12-31"&lt;/span&gt;
    &lt;span class="nx"&gt;expression&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"request.time &amp;lt; timestamp(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;2020-01-01T00:00:00Z&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see from the &lt;code&gt;description&lt;/code&gt; field any requests made after &lt;code&gt;2019-12-31&lt;/code&gt; by &lt;code&gt;jane@example.com&lt;/code&gt; will be denied.&lt;/p&gt;

&lt;p&gt;🎉&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>security</category>
      <category>gcp</category>
      <category>iam</category>
    </item>
    <item>
      <title>Terraform: Getting started with GCP</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Fri, 12 Mar 2021 22:34:35 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/terraform-getting-started-with-gcp-54db</link>
      <guid>https://dev.to/mcrmonkey/terraform-getting-started-with-gcp-54db</guid>
      <description>&lt;h1&gt;
  
  
  What's Terraform?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.terraform.io/"&gt;Terraform&lt;/a&gt; is a tool created by &lt;a href="https://www.hashicorp.com/"&gt;Hashicorp&lt;/a&gt; which allows us to describe our infrastructure in easily readable code. This code can also be stored in our source code management system to allow us to track changes to our infrastructure over time.&lt;/p&gt;

&lt;p&gt;Terraform works by talking to the API endpoints Google provide for the platform to setup our desired infrastructure.&lt;/p&gt;

&lt;h1&gt;
  
  
  Where do I start ?
&lt;/h1&gt;

&lt;p&gt;First we'll need to configure a "provider" so we can talk to the platform.&lt;/p&gt;

&lt;p&gt;You'll need to put the following in your terraform file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;google&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/google"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt;3.57"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"google"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my_Project"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;terraform&lt;/code&gt; block above the first thing we're doing is setting up our required providers, where to get the google provider from and the version of that provider.&lt;/p&gt;

&lt;p&gt;When we specify the source as &lt;code&gt;hashicorp/google&lt;/code&gt; terraform knows to get the provider from the &lt;a href="https://registry.terraform.io/"&gt;terraform registry&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While setting the version options isn't required, it does help us to track any changes and mitigate possible breaking changes when applying our infrastructure.&lt;/p&gt;

&lt;p&gt;Above we're setting the version of the provider to &lt;code&gt;3.57&lt;/code&gt; however we are also allowing for any minor bug fixes by using the &lt;code&gt;~&amp;gt;&lt;/code&gt; prefix in the version field.&lt;/p&gt;

&lt;p&gt;More info on version constraints in terraform can be found &lt;a href="https://www.terraform/io/docs/configuration/version-constraints.html"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our provider configuration we're also setting our default project to &lt;code&gt;my_Project&lt;/code&gt;.&lt;br&gt;
Setting the default project here will prevent us from having to set it for each google resource we define.&lt;/p&gt;
&lt;h1&gt;
  
  
  How will Google know who I am?
&lt;/h1&gt;

&lt;p&gt;As with any good cloud provider Google won't just let any one through the door. So we'll have to let Google know who we are first before we can do anything else.&lt;/p&gt;

&lt;p&gt;When we're using terraform there are couple of ways to do this: &lt;/p&gt;
&lt;h2&gt;
  
  
  Application Default Credentials (ADC)
&lt;/h2&gt;

&lt;p&gt;With the &lt;a href="https://cloud.google.com/sdk/docs/install"&gt;Google Cloud SDK installed on your system&lt;/a&gt;; You can run the following commands on your computer to login to google cloud and set your &lt;code&gt;default application&lt;/code&gt; credentials:&lt;/p&gt;

&lt;p&gt;First you'll need to login: &lt;code&gt;gcloud auth login&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you're on Windows, Mac or Linux (FreeDesktop.org compatible) it will open your default web browser and prompt you to login to google cloud.&lt;/p&gt;

&lt;p&gt;Once complete, you'll need to run &lt;code&gt;gcloud auth application-default login&lt;/code&gt; to trigger&lt;br&gt;
a similar process and set your default application credentials.&lt;/p&gt;

&lt;p&gt;If a web browser cannot be opened automatically you will be presented with a URL you can copy and paste into your browser.&lt;/p&gt;

&lt;p&gt;If you have multiple browser windows logged in to different accounts it may be a good idea to add the &lt;code&gt;--no-launch-browser&lt;/code&gt; command line option to prevent &lt;code&gt;gcloud&lt;/code&gt; from trying to open the URL for you. You can then copy and paste this in to the browser session you'd like to use for your login.&lt;/p&gt;
&lt;h2&gt;
  
  
  Credentials file
&lt;/h2&gt;

&lt;p&gt;A Credentials file contains a private key we can use to talk to Google’s API’s and is linked with a service account that has been allocated specific set of permissions.&lt;/p&gt;

&lt;p&gt;More information about creating and downloading the service account key can be found &lt;a href="https://cloud.google.com/iam/docs/creating-managing-service-account-keys"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can reference our credentials file by adding the following line to our google provider configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;google&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;credentials&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“/&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;keyfile&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
  &lt;span class="nx"&gt;Project&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;my_Project&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively we can also reference our credentials file by setting the &lt;code&gt;GOOGLE_APPLICATION_CREDENTIALS&lt;/code&gt; environment variable, for example:&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;export &lt;/span&gt;&lt;span class="nv"&gt;GOOGLE_APPLICATION_CREDENTIALS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;”/path/to/keyfile.json”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where you need to make use of a service account key; using the environment variable would be a better option so we can avoid having to change the path to the key file for each person or system that uses it.&lt;/p&gt;

&lt;p&gt;It's recommended that a user account is used outside of any automated pipeline operations as these are linked to people and can be deactivated when a user leaves a project or if you need to consult the logs to see who created a resource.&lt;/p&gt;

&lt;p&gt;Now you're setup you can start making use of the platform's resources and benefits!&lt;/p&gt;

&lt;p&gt;🎉&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>googlecloud</category>
      <category>gcp</category>
    </item>
    <item>
      <title>Packer: Building images on Google Cloud</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Tue, 08 Sep 2020 00:29:57 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/packer-building-images-on-google-cloud-ape</link>
      <guid>https://dev.to/mcrmonkey/packer-building-images-on-google-cloud-ape</guid>
      <description>&lt;p&gt;Installing the software we need to run our website or tools, can take some time to complete. This isn't ideal when our deployments are time sensitive, like when we need to scale up the web server pool to handle that sudden interest in your latest line of fancy socks.&lt;/p&gt;

&lt;p&gt;We can solve this issue by pre-installing the software we need and setting the configuration options, which we can then turn in to an image we can deploy over and over again.&lt;/p&gt;

&lt;p&gt;To make this entire process quicker, repeatable and something we can easily template - We'll use packer&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Packer?
&lt;/h2&gt;

&lt;p&gt;Packer is a Hashicorp tool that can be used to ease the creation of system images on cloud platforms or for other local tools like Vagrant ( another Hashicorp tool), Docker and VirtualBox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where can I get it ?
&lt;/h2&gt;

&lt;p&gt;You can download the HashiCorp Packer tool from the &lt;a href="https://www.packer.io/downloads"&gt;download page on the packer website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's also a handy guide on the &lt;a href="https://learn.hashicorp.com/"&gt;hashicorp learning portal&lt;/a&gt; for &lt;a href="https://learn.hashicorp.com/tutorials/packer/getting-started-install"&gt;how to install it on your operating system&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I use it with the Google Cloud Platform?
&lt;/h2&gt;

&lt;p&gt;You'll need to create a "builder" configuration in your packer file.&lt;br&gt;
Here's a basic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"builders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"googlecompute"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-central1-a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source_image_family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"debian-10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ssh_username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"packer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"packer-{{timestamp}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image_family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"socks-web"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The options we have set above do the following things:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;type&lt;/code&gt;&lt;br&gt;
  is the type of builder we're using. Here its &lt;code&gt;googlecompute&lt;/code&gt; because we're talking to GCP&lt;/p&gt;

&lt;p&gt;&lt;code&gt;project_id&lt;/code&gt;&lt;br&gt;
  is the project where the final image will be stored&lt;/p&gt;

&lt;p&gt;&lt;code&gt;zone&lt;/code&gt;&lt;br&gt;
  Will be the zone we build our image in&lt;/p&gt;

&lt;p&gt;&lt;code&gt;source_image_family&lt;/code&gt;&lt;br&gt;
  This is the group of images where our base image will be taken from&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssh_username&lt;/code&gt;&lt;br&gt;
  The ssh username we'll use to talk to the instance that will create our image&lt;/p&gt;

&lt;p&gt;&lt;code&gt;image_name&lt;/code&gt;&lt;br&gt;
  The name of the image we will create.&lt;br&gt;
The image name needs to be unique within our project so we're using the packer variable &lt;code&gt;timestamp&lt;/code&gt; to do that.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;image_family&lt;/code&gt;&lt;br&gt;
  The name of our image family. This is optional but is useful later on.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is this &lt;code&gt;image_family&lt;/code&gt; thing ?
&lt;/h2&gt;

&lt;p&gt;Images can be stored in groups referred to as image families. When building instances we can ask GCP to get our image from our family which will return the latest image that was added to it.&lt;/p&gt;

&lt;p&gt;If something is found to be wrong with a new image we can &lt;a href="https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#setting_families"&gt;tag it as deprecated&lt;/a&gt; and the family will offer up a previous version next time we deploy an instance.&lt;/p&gt;

&lt;p&gt;More info on image families can be found in &lt;a href="https://cloud.google.com/compute/docs/images#image_families"&gt;the GCP documentation&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How do I install that web server in my image?
&lt;/h2&gt;

&lt;p&gt;You'll need to add a &lt;a href="https://www.packer.io/docs/provisioners"&gt;provisioner&lt;/a&gt; or two, to your packer config file.&lt;/p&gt;

&lt;p&gt;Provisioner's are usually shell scripts or file uploads but could be a puppet, ansible, salt or chef operation. &lt;/p&gt;

&lt;p&gt;Here's a complete example of our packer file including our new provisioners:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"builders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"googlecompute"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"zone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-central1-a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source_image_family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"debian-10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ssh_username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"packer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"packer-{{timestamp}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"image_family"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"socks-web"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"provisioners"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;                                                           
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;                                                                         
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                                                           
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                                           
      &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/tmp/index.html"&lt;/span&gt;&lt;span class="w"&gt;                                            
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;                                                                         
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                                                        
        &lt;/span&gt;&lt;span class="nl"&gt;"inline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;                                                             
            &lt;/span&gt;&lt;span class="s2"&gt;"sudo apt-get update -qq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"sudo apt-get upgrade -qq"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;                                     
            &lt;/span&gt;&lt;span class="s2"&gt;"sudo apt-get install -qq apache2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"sudo cp /tmp/index.html /var/www/html/index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;                                                                      
    &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we copy our &lt;code&gt;index.html&lt;/code&gt; file to &lt;code&gt;/tmp&lt;/code&gt;, Update the cache for apt, perform a system upgrade to make sure we have all the updates installed then install apache and finally copy our index page in to place.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I build that image ?
&lt;/h2&gt;

&lt;p&gt;You can now run the following command from the directory where you've saved the packer file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;packer build example.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Packer will now go away and build that image for you and will store the resulting image as &lt;code&gt;packer-xxxxxxxxx&lt;/code&gt; ( where &lt;code&gt;xxxxxxxxx&lt;/code&gt; is a timestamped value ) The resulting image will be linked to the image family &lt;code&gt;socks-web&lt;/code&gt; which you will then be able to reference in your terraform template for your project.&lt;/p&gt;

&lt;p&gt;🎉 Tada!&lt;/p&gt;

&lt;h2&gt;
  
  
  Are there other things to know ?
&lt;/h2&gt;

&lt;p&gt;Yes, there are a couple of things:&lt;/p&gt;

&lt;h4&gt;
  
  
  Networking
&lt;/h4&gt;

&lt;p&gt;The example above assumes the project you are using contains a default networking setup with subnetworks available in your chosen zone. If these things aren't available the build process will fail and you'll need to add a &lt;code&gt;network&lt;/code&gt; OR &lt;code&gt;subnetwork&lt;/code&gt; option to the builder config which lines up with your chosen zone.&lt;/p&gt;

&lt;p&gt;It also assumes that the default firewall rules are in place so packer can ssh to the instance it creates.&lt;br&gt;
If you don't have the needed firewall rules to allow access your build process will time out while waiting to connect.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;machine_type&lt;/code&gt; has been omitted from the example
&lt;/h4&gt;

&lt;p&gt;It will default to &lt;code&gt;n1-standard-1&lt;/code&gt; but you may need to increase its size depending on what you're doing. A larger machine type will help it run faster.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cost
&lt;/h4&gt;

&lt;p&gt;There is a cost for storing your images.&lt;br&gt;
At time of writing its about $0.050 for US and EU multi region storage but it can be as high as $0.075 is specific regions.&lt;/p&gt;

&lt;p&gt;There will also be a cost for building the image.&lt;br&gt;
This will vary based on the image size you use and where you choose to build it.&lt;br&gt;
At time of writing the cost of the the given example should be in the region of $0.04749975 Per hour&lt;/p&gt;

&lt;p&gt;Check the &lt;a href="https://cloud.google.com/compute/all-pricing#machine_image"&gt;pricing page&lt;/a&gt; for more info.&lt;/p&gt;

&lt;p&gt;To quote the pricing pages:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you pay in a currency other than USD, the prices listed in your currency on &lt;a href="https://cloud.google.com/skus/"&gt;Cloud Platform SKUs&lt;/a&gt; apply.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;❗  &lt;strong&gt;Make sure you check the cost before you run up a big bill&lt;/strong&gt; ❗ &lt;/p&gt;

&lt;h4&gt;
  
  
  Cleaning up
&lt;/h4&gt;

&lt;p&gt;If you don't want that image you've just created you can head over to &lt;a href="https://console.cloud.google.com/compute/images"&gt;images&lt;/a&gt; in the compute section of the console and delete the image you no longer want. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; You cannot delete public images from your project - They are free anyway 😃 &lt;/p&gt;

</description>
      <category>gcp</category>
      <category>googlecloud</category>
      <category>packer</category>
      <category>hashitools</category>
    </item>
    <item>
      <title>SSH: Multiplexing</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Sat, 11 Jan 2020 22:37:22 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/ssh-multiplexing-b39</link>
      <guid>https://dev.to/mcrmonkey/ssh-multiplexing-b39</guid>
      <description>&lt;h2&gt;
  
  
  What is it ?
&lt;/h2&gt;

&lt;p&gt;Multiplexing, sometimes referred to as muxing, is a way of making use of one connection for a number of signals.&lt;br&gt;
The internet connection you're reading this on may have been multiplexed at some stage along its physical route to your building or local communications tower and can used to reduce the overall cost of having to lay multiple cables to endpoints.&lt;/p&gt;

&lt;p&gt;There is an article on Wikipedia about &lt;a href="https://en.wikipedia.org/wiki/Multiplexing"&gt;multiplexing&lt;/a&gt; which goes in to more depth about what and where else in the world its used.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the link to SSH ?
&lt;/h2&gt;

&lt;p&gt;We can use multiplexing for our SSH connections to help speed up processes where multiple commands need to be executed on the same server or via the same jump host.&lt;/p&gt;
&lt;h2&gt;
  
  
  How does SSH do this ?
&lt;/h2&gt;

&lt;p&gt;Your SSH client can create a control ( 'master' ) connection to the server which can then be used for multiple sessions without having to create a new TCP connection for each one. OpenSSH shares this connection via a socket that it can create on disk.&lt;/p&gt;
&lt;h2&gt;
  
  
  How can I do it ?
&lt;/h2&gt;

&lt;p&gt;You can either do this via your command line by setting some options at run time or you can add some configuration options to your SSH client configuration file.&lt;/p&gt;

&lt;p&gt;For ease and and some clarity; here's a quick configuration example for our jump-box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ssh"&gt;&lt;code&gt;
&lt;span class="k"&gt;Host&lt;/span&gt; jump-box
  &lt;span class="k"&gt;HostName&lt;/span&gt; jump-box.example.org
  &lt;span class="k"&gt;ControlPath&lt;/span&gt; ~/.ssh/controlmasters/%r@%h:%p
  &lt;span class="k"&gt;ControlMaster&lt;/span&gt; &lt;span class="no"&gt;auto&lt;/span&gt;
  &lt;span class="k"&gt;ControlPersist&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;m

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once this is in place the next connection you make to jump-box will create a control connection and then create a session within in it which will contain your terminal.&lt;/p&gt;

&lt;p&gt;The important configuration bits here are the &lt;code&gt;ControlPath&lt;/code&gt; &lt;code&gt;ControlMaster&lt;/code&gt; and &lt;code&gt;ControlPersist&lt;/code&gt; options.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;ControlPath&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Sets the place the socket file will be created. openSSH uses this to talk to the control process. The &lt;code&gt;%r&lt;/code&gt; &lt;code&gt;%h&lt;/code&gt; and &lt;code&gt;%p&lt;/code&gt; tokens correspond to the &lt;strong&gt;remote username&lt;/strong&gt;, &lt;strong&gt;remote host&lt;/strong&gt; and the &lt;strong&gt;port&lt;/strong&gt; of the remote host respectively. As per our example this will create the control socket at &lt;code&gt;~/.ssh/controlmasters/user@jump-box.example.org:22&lt;/code&gt;.&lt;br&gt;
This ensures you get a different socket for each connection you make.&lt;br&gt;
See &lt;code&gt;man 5 ssh_config&lt;/code&gt; for more info on the different tokens you can use here.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;ControlMaster&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Sets how SSH will use the multiplexing. Here we set it to &lt;code&gt;auto&lt;/code&gt; so that our client will first check for existing connection and make use of it if one is found and if none are present one will be created. see &lt;code&gt;man 5 ssh_config&lt;/code&gt; for info on other options.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;code&gt;ControlPersist&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This tells SSH how long it should keep a control session open for after the last session has closed. We're using 10m in case we've forgotten something or want to repeat a task.&lt;/p&gt;
&lt;h2&gt;
  
  
  How can I use this for &lt;em&gt;all&lt;/em&gt; of my SSH connections ?
&lt;/h2&gt;

&lt;p&gt;You'll need to adjust the configuration you put in to your SSH configuration file like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;Host&lt;/span&gt; *
  &lt;span class="k"&gt;ControlPath&lt;/span&gt; ~/.ssh/controlmasters/%r@%h:%p
  &lt;span class="k"&gt;ControlMaster&lt;/span&gt; &lt;span class="no"&gt;auto&lt;/span&gt;
  &lt;span class="k"&gt;ControlPersist&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All of your new SSH connections will now be multiplexed&lt;/p&gt;

&lt;h3&gt;
  
  
  Controlling Port forwarding when multiplexing
&lt;/h3&gt;

&lt;p&gt;Port forwarding and related controls are transferred to the control session. So restarting a SSH session with the same port forwarding options set will show an error message about the port already being in use.&lt;/p&gt;

&lt;p&gt;The same controls you would expect to be accessible via the escape sequence are not present either.&lt;/p&gt;

&lt;p&gt;Instead you have to control these features via the -O command line option. Here are some examples:&lt;/p&gt;

&lt;p&gt;To add a new forward without starting a new session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-O&lt;/span&gt; forward &lt;span class="nt"&gt;-L&lt;/span&gt; 8080:localhost:80 jump-box.example.org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Removing a port forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-O&lt;/span&gt; cancel &lt;span class="nt"&gt;-L&lt;/span&gt; 8080:localhost:80 jump-box.example.org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: If you specified a user on your initial connection ( user@server ) you also have to specify it here to find the control socket &lt;/p&gt;

&lt;p&gt;Unfortunately there doesn't appear to be a way to list the existing forwarding options you may have set.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server side support
&lt;/h3&gt;

&lt;p&gt;The only service I've been unable to use multiplexing with is bitbucket and the reasons for why are noted &lt;a href="https://jira.atlassian.com/browse/BCLOUD-13465"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can remove hosts from the multiplex configuration by adjusting the Host line, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ssh"&gt;&lt;code&gt;&lt;span class="k"&gt;Host&lt;/span&gt; * !bitbucket.org

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This would remove the bitbucket domain from this host configuration block&lt;/p&gt;

&lt;p&gt;Happy Multiplexing ! .o/&lt;/p&gt;

</description>
      <category>ssh</category>
    </item>
    <item>
      <title>SSH: Tunneling to remote servers</title>
      <dc:creator>ant Kenworthy</dc:creator>
      <pubDate>Tue, 24 Dec 2019 16:59:32 +0000</pubDate>
      <link>https://dev.to/mcrmonkey/ssh-tunneling-to-remote-servers-2kfc</link>
      <guid>https://dev.to/mcrmonkey/ssh-tunneling-to-remote-servers-2kfc</guid>
      <description>&lt;p&gt;When creating our infrastructure, either in the cloud or on prem, we &lt;del&gt;often&lt;/del&gt; usually need a way to connect to machines running behind the scenes to do things, such as upgrades or fixing problems.&lt;/p&gt;

&lt;p&gt;Typically the tool of choice for most remote system administration work is ssh. &lt;a href="https://www.openssh.com/"&gt;openssh&lt;/a&gt; is probably the most common version of ssh that is used on systems today and is often pre-built and installed on your operating system.&lt;/p&gt;

&lt;p&gt;When we need to connect to our web servers that are safely tucked behind a firewall on local IP addresses ( &lt;a href="https://tools.ietf.org/html/rfc1918"&gt;RFC1918&lt;/a&gt; ) we can use SSH to tunnel through our bastion or jump-host, here's how:&lt;/p&gt;

&lt;p&gt;Here's a basic diagram of how I'll be connecting to a web server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  { Internet } ------ [ Jump-box ] ------ [ Web-server-1 ]

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I need to connect to &lt;code&gt;web-server-1&lt;/code&gt; to fix an issue but it doesn't have direct exposure to the internet. I can use the jump-box to make that connection like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
ssh &lt;span class="nt"&gt;-J&lt;/span&gt; jump-box.example.com web-server-1

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. It really is that simple!&lt;/p&gt;

&lt;p&gt;You may notice that the webserver isn't using a fully qualified domain name such as &lt;code&gt;web-server-1.example.com&lt;/code&gt;. This is because the ssh client will make use of the DNS configuration of the jump host to find &lt;code&gt;web-server-1&lt;/code&gt;. If the DNS isn't configured properly on the jump-box, or you make a typo, you'll get an error message back saying it couldn't be found.&lt;/p&gt;

&lt;p&gt;You can add as many servers to the -J option as needed in a comma separated format. The highest number of jumps I've made is 3. The client will connect to each of the servers in order to establish a connection to the end point web-server-1. An example maybe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
ssh &lt;span class="nt"&gt;-J&lt;/span&gt; jump-box.example.com,jump-box-2 web-server-1

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt; : &lt;em&gt;The &lt;code&gt;-J&lt;/code&gt; option was &lt;a href="https://www.openssh.com/txt/release-7.3"&gt;introduced in openssh version 7.3&lt;/a&gt;. If you have an earlier version of the client the command line option may not be available to you.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;-J&lt;/code&gt; option is a shortcut for the &lt;code&gt;ProxyJump&lt;/code&gt; configuration option. That you could find in your ssh client configuration files already ( &lt;code&gt;.ssh/config&lt;/code&gt; for user configurations or &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt; for system wide )&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
In my ssh client configuration it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ssh"&gt;&lt;code&gt;
&lt;span class="k"&gt;host&lt;/span&gt; web-server-1
 &lt;span class="k"&gt;ProxyJump&lt;/span&gt; jump-box.example.com

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This would create an alias for &lt;code&gt;web-server-1&lt;/code&gt; that the ssh client can use. Now I'd only have to type &lt;code&gt;ssh web-server-1&lt;/code&gt; and ssh would take care of the rest.&lt;/p&gt;

&lt;p&gt;But wait, there's more!&lt;/p&gt;

&lt;p&gt;An alternative method for doing this would be to use the proxy-command option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
ssh &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;ProxyCommand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ssh -W %h:%p jump-box.example.com"&lt;/span&gt; web-server-1

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This first starts an ssh connection to the jump box and then, with the &lt;code&gt;-W&lt;/code&gt; option, requests that standard input and output on the client be forwarded to host on port over the secure channel&lt;/p&gt;

&lt;p&gt;Sometimes the ssh client you have may not have these features or they could be restricted in some fashion. For this we have to revert to good old fashioned port forwarding. &lt;/p&gt;

&lt;p&gt;In our first terminal we would run this command to setup a connection to the jump box but at the same time we ask it to listen on port 2222 on our local machine and pass those connections through to port 22 on web-server-1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
ssh &lt;span class="nt"&gt;-L&lt;/span&gt; 2222:web-server-1:22 jump-box.example.com

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then in our second terminal we would run this to initiate a connection to port 2222 on our local machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
ssh &lt;span class="nt"&gt;-P&lt;/span&gt; 2222 localhost

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using port forwards in this way works well but becomes cumbersome if you need to connect to more than one jump-box or more than one endpoint within your network.&lt;/p&gt;

&lt;p&gt;Ta-da! \o/&lt;/p&gt;

&lt;p&gt;&lt;em&gt;tldr&lt;/em&gt;: use &lt;code&gt;ssh -J jump-box.example.com web-server-1&lt;/code&gt; to tunnel ssh connections to web-server-1 via jump-box.example.com&lt;/p&gt;

</description>
      <category>ssh</category>
    </item>
  </channel>
</rss>
