<?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: Perttu Ehn</title>
    <description>The latest articles on DEV Community by Perttu Ehn (@rpsu).</description>
    <link>https://dev.to/rpsu</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%2F274048%2Fd1b46e62-eb0f-4179-9728-d523e2cc9337.png</url>
      <title>DEV Community: Perttu Ehn</title>
      <link>https://dev.to/rpsu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rpsu"/>
    <language>en</language>
    <item>
      <title>DynDNS with OVH hosting</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Sat, 29 Jan 2022 15:07:39 +0000</pubDate>
      <link>https://dev.to/rpsu/dyndns-with-ovh-hosting-45og</link>
      <guid>https://dev.to/rpsu/dyndns-with-ovh-hosting-45og</guid>
      <description>&lt;p&gt;I use my own domain to access some specific services when I am not home or just feel lazy because I can do things over my mobile like this. Typing and remembering IP addresses isn't too much fun so I use my own domain to simplify my life.&lt;/p&gt;

&lt;p&gt;I have opened some services to be accessed only from my home wifi network. Some services I have opened also are accessible from outside my home.&lt;/p&gt;

&lt;p&gt;I did not want to pay for a fixed IP address and hence the internet service provider (ISP) may change my IP whenever they like. This would usually make reaching those services unreliable.&lt;/p&gt;

&lt;p&gt;Since I have a few other things hosted at OVH Hosting and they offer &lt;a href="https://en.wikipedia.org/wiki/Dynamic_DNS"&gt;DynDNS&lt;/a&gt; as well I went and set up a couple of subdomains with it. DynDNS  is a dynamic domain  name system service which allows some specified domain to be updated automatically. The update is initiated by some device behind the changing IP address (ie. your home).&lt;/p&gt;

&lt;p&gt;Earlier I have had &lt;a href="https://en.wikipedia.org/wiki/Network-attached_storage"&gt;NASs'&lt;/a&gt; (tiny linux servers) which I used to update my home domains. All of my NASes have been turned off for a while now. Also I prefer handling the incoming traffic based on domain name rather than port so I can use nginx in my word facing Raspberry PI's to proxy the traffic where needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proxying&lt;/strong&gt; means I forward my incoming traffic coming to my hypothetical fridge domain with &lt;code&gt;nginx&lt;/code&gt;  to the fridge but the access to the fridge would happen via address &lt;code&gt;https://fridge.example.com&lt;/code&gt; and the outer most Raspberry PI would pass the request coming with that domain to the fridge. This way it is easy to handle incoming requests with one &lt;code&gt;nginx&lt;/code&gt; in cheap Raspberry PI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating DynDNS IP address
&lt;/h2&gt;

&lt;p&gt;I wrote this small script I run for each of my home domains in the Raspberry PI. What the script does is it checks the currently configured IP address for the given domain, compares it with the public IP address it has and updates the OVH Hosting DNS with the new IP address if necessary.&lt;/p&gt;

&lt;p&gt;Because the IP address comparison script can be run every few minutes with no worries querying the OVH side too often. Basically it sends update requests to OVH only when the IP address has been changed.&lt;/p&gt;

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

&lt;p&gt;Let's put the script under path &lt;code&gt;/path/to/&lt;/code&gt; and the domain we configure is &lt;code&gt;home.example.com&lt;/code&gt;. Let's assume also that our username is &lt;code&gt;janedoe&lt;/code&gt; and the matching password is &lt;code&gt;mysecret&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The credentials file format is &lt;em&gt;very&lt;/em&gt; strict since we pass it forward with the request to update domain - exactly one line and username and password separated with a single colon.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Save the files&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need to have credentials for your request (so only you can update your domains):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"home.example.com-janedoe:mysecret"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; dyndns-update.sh_home.example.com.creds.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make the script executable and owned by &lt;code&gt;root&lt;/code&gt; and credentials files readable &lt;strong&gt;only&lt;/strong&gt; by &lt;code&gt;root&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;700 dyndns-update.sh &lt;span class="c"&gt;# the main script&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chown &lt;/span&gt;root:root dyndns-update.sh
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;400 dyndns-update.sh_home.example.com.creds.txt
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chown &lt;/span&gt;root:root dyndns-update.sh_home.example.com.creds.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute the script manually to see it works:&lt;br&gt;
&lt;/p&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;sh dyndns-update.sh home.example.com
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;If the execution fails uncomment the DEBUG=1 line to get more output.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When the script works, set up cronjob to run the script every few minutes.&lt;/p&gt;

&lt;p&gt;The longer time between the executions you have the longer time it takes for the domain IP address to get corrected.&lt;/p&gt;

&lt;p&gt;Edit your cronjob table with &lt;code&gt;sudo crontab -e&lt;/code&gt; (or however the similar scheduled jobs configuration is done in your system).&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt;/10 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; sh /path/to/dyndns-update.sh home.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Script
&lt;/h3&gt;

&lt;p&gt;This script works with OVH Hosting. You may need to adjust the &lt;code&gt;curl&lt;/code&gt; command if your DynDNS host has a different API to update the domain IP addresses. Check with your hosting provider for the details.&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;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# /path/to/dyndns-update.sh&lt;/span&gt;

&lt;span class="c"&gt;# 1. Create a credentials file in the same folder with this script named &lt;/span&gt;
&lt;span class="c"&gt;# dyndns-update.sh_EXAMPLE.COM.creds.txt &lt;/span&gt;
&lt;span class="c"&gt;# with user credentials, such as &lt;/span&gt;
&lt;span class="c"&gt;# example.com-username:USER-PASSWORD&lt;/span&gt;
&lt;span class="c"&gt;# &lt;/span&gt;
&lt;span class="c"&gt;# 2. Try this at least once. The output of curl commands tells if update is successful, not necessary or if something was wrong.&lt;/span&gt;
&lt;span class="c"&gt;# sudo sh /path/to/dyndns-update.sh&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# 3. Run this as a cronjob&lt;/span&gt;
&lt;span class="c"&gt;# $ sudo crontab -e&lt;/span&gt;
&lt;span class="c"&gt;# and add something like this to your crontab (this checks IP every 10 mins):&lt;/span&gt;
&lt;span class="c"&gt;# */10 * * * * sh /path/to/dyndns-update.sh EXAMPLE.COM&lt;/span&gt;

&lt;span class="c"&gt;# Disable to get less output:&lt;/span&gt;
&lt;span class="nv"&gt;DEBUG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="nv"&gt;USER_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$USER_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;This script must be run as a root.
  &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage: "&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;0&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; example.com"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nv"&gt;SCRIPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;realpath&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="nv"&gt;SCRIPT_FOLDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="nv"&gt;$SCRIPT&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SCRIPT_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="nv"&gt;$SCRIPT&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;DOMAIN_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;host &lt;span class="nv"&gt;$DOMAIN&lt;/span&gt; |awk &lt;span class="s1"&gt;'{print $4}'&lt;/span&gt; | xargs&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--silent&lt;/span&gt; https://ipinfo.io/ip | xargs&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DOMAIN_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PUBLIC_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"Domain &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; public IP is &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN_IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. "&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Your local IP is &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, so DynHost needs updating. "&lt;/span&gt;
  &lt;span class="nv"&gt;FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SCRIPT_FOLDER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SCRIPT_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.creds.txt "&lt;/span&gt;
  &lt;span class="c"&gt;# Reads the 1st line of a file $FILE  into a PASS varible.&lt;/span&gt;
  &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; PASS &amp;lt; &lt;span class="nv"&gt;$FILE&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PASS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No password (tried &lt;/span&gt;&lt;span class="nv"&gt;$FILE&lt;/span&gt;&lt;span class="s2"&gt;), exiting!"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Next (with creds):"&lt;/span&gt; &lt;span class="s2"&gt;"https://www.ovh.com/nic/update?system=dyndns&amp;amp;hostname=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;myip=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  curl &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PASS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;                       &lt;span class="s2"&gt;"https://www.ovh.com/nic/update?system=dyndns&amp;amp;hostname=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;myip=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;  &lt;span class="s2"&gt;"Domain &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; public IP is &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN_IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Your local IP is &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Domain &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOMAIN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; IP still ok."&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://gist.github.com/rpsu/7570c47ad3b5335087a0dee5170aac51"&gt;https://gist.github.com/rpsu/7570c47ad3b5335087a0dee5170aac51&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dyndns</category>
      <category>raspi</category>
      <category>ovhhosting</category>
      <category>homeautomation</category>
    </item>
    <item>
      <title>Security in Code Deployment - part 5: Patching with Composer and Deploy</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Wed, 19 Jan 2022 14:12:27 +0000</pubDate>
      <link>https://dev.to/rpsu/security-in-code-deployment-part-5-patching-with-composer-and-deploy-3o04</link>
      <guid>https://dev.to/rpsu/security-in-code-deployment-part-5-patching-with-composer-and-deploy-3o04</guid>
      <description>&lt;p&gt;&lt;strong&gt;Part 5/5.&lt;/strong&gt; The article was initially published in &lt;a href="https://shop.linuxnewmedia.com/us/magazines/drupal-watchdog/eh35014.html"&gt;Drupal Watchdog 7.01&lt;/a&gt;, spring 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code examples for this article&lt;/strong&gt;: &lt;a href="https://github.com/rpsu/dwd-security-in-code-deployment"&gt;https://github.com/rpsu/dwd-security-in-code-deployment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security in Code Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-1-drush-make-file-b6i"&gt;Part 1: Drush make file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-2-patch-modules-with-drush-4g6a"&gt;Part 2: Patch modules with Drush&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-3-unknown-drupal-codebase-2f3"&gt;Part 3: Unknown Drupal codebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-4-advantages-of-using-composer-json-ijm"&gt;Part 4: Advantages of using Composer JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 5: Patching with Composer and Deploy&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Composer is able to apply patches if you are using &lt;code&gt;drupal-composer/drupal-project&lt;/code&gt; or some other patching plugin for Composer (Listing 14).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 14: Composer Patching&lt;/strong&gt;&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="nl"&gt;"extra"&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;"patches"&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;"drupal/field_group"&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;"A patch with URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.drupal.org/files/issues/ field_group-empty_group_nonnumeric_index-2761159-2-D8.patch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
      &lt;/span&gt;&lt;span class="nl"&gt;"A local patch file, path relative to the composer.json file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"patches/field_group-fix_it.patch"&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;After you have added the patch files to the composer. json file, apply the changes and update the &lt;code&gt;composer.lock&lt;/code&gt; 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;composer &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;composer update &lt;span class="nt"&gt;--lock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently with Drupal 8, all contrib modules and other resources must be added manually one by one. If you are creating a &lt;code&gt;composer.json&lt;/code&gt; file from a Drupal 7 site, you might benefit by using the &lt;a href="https://www.drupal.org/project/composer_generate"&gt;Composer Generate module&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are interested in building your Drupal 8 projects with Composer, two good resources are &lt;a href="http://www.slideshare.net/nuppla/efficient-development-workflows-with-composer"&gt;Wolfgang Ziegler’s presentation&lt;/a&gt; from Drupal Iron Camp 2016 and the &lt;a href="https://www.drupal.org/docs/develop/using-composer"&gt;Composer documentation at Drupal.org&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment Process
&lt;/h2&gt;

&lt;p&gt;For codebase deployment, it is best to rely on a builder tool. Ideally, you commit only your custom code (e.g., modules and themes and a Drush make file or the &lt;code&gt;composer.json&lt;/code&gt; and &lt;code&gt;composer.lock&lt;/code&gt; files) to the project repository, with specific versions and, optionally, patching information. With proper versioning (think Git tags), you can test your next release’s code in development and staging environments and reduce the probability of reintroducing old or introducing new issues.&lt;/p&gt;

&lt;p&gt;Web server configuration is very much related to deployment security, too. However, because it is too broad a topic to be covered here, just remember to make sure your server does not allow end users access to any files other than those they absolutely need. Patch files, Drupal core, and a module’s text files – especially &lt;code&gt;CHANGELOG.txt&lt;/code&gt; and build time &lt;code&gt;PATCHES.txt&lt;/code&gt; – are good examples of files that have no business being visible to the world. Even when most of the attacks against websites are automated, there is no reason to leave information about website internals in the open.&lt;/p&gt;




&lt;p&gt;*Special thanks to &lt;a href="https://www.exove.com/author/rami-jarvinen/"&gt;Rami Järvinen&lt;/a&gt; for contributions to this blog post and to &lt;a href="https://www.exove.com/author/anastasios-daskalopoulos/"&gt;Anastasios Daskalopoulos&lt;/a&gt; and &lt;a href="https://www.exove.com/author/james-narraway/"&gt;James Narraway&lt;/a&gt; for their help correcting my words to much better English.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drush</category>
      <category>composer</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Security in Code Deployment - part 4: Advantages of using Composer JSON</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Wed, 19 Jan 2022 14:08:33 +0000</pubDate>
      <link>https://dev.to/rpsu/security-in-code-deployment-part-4-advantages-of-using-composer-json-ijm</link>
      <guid>https://dev.to/rpsu/security-in-code-deployment-part-4-advantages-of-using-composer-json-ijm</guid>
      <description>&lt;p&gt;&lt;strong&gt;Part 4/5.&lt;/strong&gt; The article was initially published in &lt;a href="https://shop.linuxnewmedia.com/us/magazines/drupal-watchdog/eh35014.html"&gt;Drupal Watchdog 7.01&lt;/a&gt;, spring 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code examples for this article&lt;/strong&gt;: &lt;a href="https://github.com/rpsu/dwd-security-in-code-deployment"&gt;https://github.com/rpsu/dwd-security-in-code-deployment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security in Code Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-1-drush-make-file-b6i"&gt;Part 1: Drush make file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-2-patch-modules-with-drush-4g6a"&gt;Part 2: Patch modules with Drush&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-3-unknown-drupal-codebase-2f3"&gt;Part 3: Unknown Drupal codebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 4: Advantages of using Composer JSON&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-5-patching-with-composer-and-deploy-3o04"&gt;Part 5: Patching with Composer and Deploy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;You are most probably familiar with &lt;a href="https://getcomposer.org/doc/00-intro.md"&gt;Composer&lt;/a&gt;, at least on a conceptual level. It is a dependency manager with all of the functionality of Drush, and more. From the perspective of building the codebase, the difference between Drush and Composer is the recipe file format and the use or Composer, not Drush, as the build tool. Drush and Composer are not mutually exclusive, you can use both; you can even install Drush along with Drupal using Composer.&lt;/p&gt;

&lt;p&gt;Composer uses JSON files, which use curly brackets instead of indentation, as in YAML files. However, unlike Drush make files, &lt;code&gt;composer.json&lt;/code&gt; files are not meant to be edited in quite the same way. Composer keeps the &lt;code&gt;composer.json&lt;/code&gt; and &lt;code&gt;composer.lock&lt;/code&gt; files up-to-date according to your instructions. You still need to add some things manually to &lt;code&gt;composer.json&lt;/code&gt;, such as the patches you want to use in modules.&lt;/p&gt;

&lt;p&gt;From a code deployment perspective, using Composer is just a better way to manage all required resources, because it also makes sure all the module requirements are met; you could learn the hard way that something is missing with the use of an (incomplete) Drush make file.&lt;/p&gt;

&lt;p&gt;Start by generating the project in a &lt;code&gt;drupal.local&lt;/code&gt; folder. The following example uses the GitHub-based &lt;a href="https://github.com/drupal-composer/drupal-project"&gt;Composer template project&lt;/a&gt;. Before you start, make sure you have Composer &lt;a href="https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx"&gt;installed&lt;/a&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="nv"&gt;$ &lt;/span&gt;composer create-project drupal-composer/drupal-project:8.x-dev drupal.local
&lt;span class="nt"&gt;--stability&lt;/span&gt; dev &lt;span class="nt"&gt;--no-interaction&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;drupal.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Composer can be used with Drupal 7 projects, too. All you have to change is the branch name in the command to &lt;code&gt;7.x-dev&lt;/code&gt;. Now the &lt;code&gt;composer.json&lt;/code&gt; and &lt;code&gt;composer.lock&lt;/code&gt; files have been created. The Drupal root (the &lt;code&gt;index.php&lt;/code&gt; file) is in the &lt;code&gt;web&lt;/code&gt; folder, as are other Drupal modules and themes. Other resources (dependencies) are in the &lt;code&gt;vendor&lt;/code&gt; folder. You might take a look at what is in the folders; just remember that &lt;code&gt;composer.lock&lt;/code&gt; contains the whole dependency tree, which easily makes it quite long when compared with the &lt;code&gt;composer.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Start by adding Drupal.org as one of the package (module) sources; then, start adding your project dependencies. In Listing 13, I’m adding the very latest version of the Token module that is compatible with the defined Drupal core, as well as a specific version of the Field Group module and a specific commit (1fe3649) from Ctools module’s 8.x-3.x branch. Composer will update &lt;code&gt;composer.json&lt;/code&gt; and &lt;code&gt;composer.lock&lt;/code&gt; files when you add (or remove) dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 13: Add Modules with Composer&lt;/strong&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="c"&gt;# Configure Drupal.org as a package source&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;composer config repositories.drupal composer https://packages.drupal.org/8
&lt;span class="c"&gt;# Add some modules&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;composer require drupal/token
&lt;span class="nv"&gt;$ &lt;/span&gt;composer require drupal/field_group:1.0-rc4
&lt;span class="nv"&gt;$ &lt;/span&gt;composer require drupal/ctools:dev-3.x#1fe3649
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have committed and pushed changes, your colleagues can get exactly the same codebase every time, with all dependencies included. All they have to do is clone your repository and run:&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;composer &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--prefer-dist&lt;/span&gt; &lt;span class="nt"&gt;--optimize-autoloader&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drush</category>
      <category>composer</category>
      <category>deployment</category>
    </item>
    <item>
      <title>Security in Code Deployment - part 3: Unknown Drupal codebase</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Wed, 19 Jan 2022 14:07:31 +0000</pubDate>
      <link>https://dev.to/rpsu/security-in-code-deployment-part-3-unknown-drupal-codebase-2f3</link>
      <guid>https://dev.to/rpsu/security-in-code-deployment-part-3-unknown-drupal-codebase-2f3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Part 3/5.&lt;/strong&gt; The article was initially published in &lt;a href="https://shop.linuxnewmedia.com/us/magazines/drupal-watchdog/eh35014.html"&gt;Drupal Watchdog 7.01&lt;/a&gt;, spring 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code examples for this article&lt;/strong&gt;: &lt;a href="https://github.com/rpsu/dwd-security-in-code-deployment"&gt;https://github.com/rpsu/dwd-security-in-code-deployment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security in Code Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-1-drush-make-file-b6i"&gt;Part 1: Drush make file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-2-patch-modules-with-drush-4g6a"&gt;Part 2: Patch modules with Drush&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 3: Unknown Drupal codebase&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-4-advantages-of-using-composer-json-ijm"&gt;Part 4: Advantages of using Composer JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-5-patching-with-composer-and-deploy-3o04"&gt;Part 5: Patching with Composer and Deploy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Some day you will receive a project that you must start maintaining - &lt;em&gt;the unknown Drupal codebase&lt;/em&gt;. In the best case, you get an up-to-date Drush make file with properly declared resource versions, database dumps, and &lt;code&gt;sites/example.com&lt;/code&gt; folder content.. In the worst case, you get a huge, uncompressed file containing the whole Drupal site starting from the Drupal root, including core and contrib modules and a database dump.&lt;/p&gt;

&lt;p&gt;In the first case, codebase reviewing and building is fairly easy – all information for the codebase is written into the make file: Build the codebase, extract &lt;code&gt;sites/example.com&lt;/code&gt; folder contents, import the database, and you’re good to go.&lt;/p&gt;

&lt;p&gt;In the worst-case scenario, you must review the entire codebase and create the missing make file yourself. Provided you have Drush installed, generating a make file is fairly simple. Set up the site in your local development environment and enter:&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;cd &lt;/span&gt;DRUPAL_ROOT/sites/example.com  
&lt;span class="nv"&gt;$ &lt;/span&gt;drush make-generate path/to/example.com.make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have at least a base for your make file, but the file is not ready yet. Open your example.com.make file and add the missing components. Components that require editing are clearly marked. For example, a missing component might be that the required libraries aren’t yet set because Drush has no way of knowing where they came from – Drush only queries information about the resources from Drupal.org. If you are lucky, you can find &lt;code&gt;PATCHES.txt&lt;/code&gt; files or similar in the extracted codebase for help.&lt;/p&gt;

&lt;p&gt;The next thing you must do is verify that the received codebase has not been tampered with. The previous maintainer might have changed the codebase in some manner. As with so many other things, you can use a Drupal module to offload this tedious and error-prone work to the machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.drupal.org/project/hacked"&gt;The Hacked! module&lt;/a&gt; compares the codebase – Drupal core, modules, and themes – to the versions on Drupal. org by downloading the supposedly same files and verifying that they match the local versions. When you also use the &lt;a href="https://www.drupal.org/project/diff"&gt;Diff module&lt;/a&gt;, it is easy to see what has changed. Both  of these modules have at least beta-versions available for both Drupal 7 and Drupal 8.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drush</category>
    </item>
    <item>
      <title>Security in Code Deployment - part 1: Drush make file</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Wed, 19 Jan 2022 14:07:19 +0000</pubDate>
      <link>https://dev.to/rpsu/security-in-code-deployment-part-1-drush-make-file-b6i</link>
      <guid>https://dev.to/rpsu/security-in-code-deployment-part-1-drush-make-file-b6i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Part 1/5.&lt;/strong&gt; The article was initially published in &lt;a href="https://shop.linuxnewmedia.com/us/magazines/drupal-watchdog/eh35014.html"&gt;Drupal Watchdog 7.01&lt;/a&gt;, spring 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code examples for this article&lt;/strong&gt;: &lt;a href="https://github.com/rpsu/dwd-security-in-code-deployment"&gt;https://github.com/rpsu/dwd-security-in-code-deployment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security in Code Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part 1: Drush make file&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-2-patch-modules-with-drush-4g6a"&gt;Part 2: Patch modules with Drush&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-3-unknown-drupal-codebase-2f3"&gt;Part 3: Unknown Drupal codebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-4-advantages-of-using-composer-json-ijm"&gt;Part 4: Advantages of using Composer JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-5-patching-with-composer-and-deploy-3o04"&gt;Part 5: Patching with Composer and Deploy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Considering the full life cycle of any website, REST service, or similar utility, development of secure code covers only part of the whole. A properly functioning backup process with tested recovery, along with hardened settings for the web server and database applications running the website, is key to running successful businesses on the web, be they profit or nonprofit. Add some load balancing, architecture with multiple servers, and strict firewall rules to the mix, and you’re good to go, even with bigger sites.&lt;/p&gt;

&lt;p&gt;What is far too often ignored is the process of managing the codebase. We’ve all heard stories or seen practices in which nobody knows how exactly to rebuild the production server codebase, requiring it to be cloned from the production site.&lt;/p&gt;

&lt;p&gt;You must be able to reproduce the codebase from any given point in time or release version, including each instance you need to have of the website, from local development up to the production site. The codebase must be predictable to the last line of code for each release of your website, and you have a few different ways to get there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Codebase in Version Control
&lt;/h2&gt;

&lt;p&gt;One way to control your website codebase is to store it entirely in a version control system &lt;a href="https://git-scm.com/"&gt;such as Git&lt;/a&gt;. Although it is a pretty bulletproof way to manage the codebase, it might require quite a bit of manual work. Drupal core and contributed (contrib) modules and themes and external libraries are already stored elsewhere and are updated regularly, so each of these updates must be imported and committed manually. Additionally, any custom code changes need to be re-implemented during this process. Largely because of these issues, it is often considered unnecessary to store code that is hosted elsewhere in the project repository.&lt;/p&gt;

&lt;p&gt;Fortunately, this problem has already been addressed: There is no need to store any publicly available code for Drupal sites in the project repository. With the help of a couple of tools, you can offload the manual processing of each update to your contributed code or libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drush Make File to the Rescue
&lt;/h2&gt;

&lt;p&gt;A predictable way to build your Drupal codebase is to use &lt;a href="http://www.drush.org/"&gt;Drush&lt;/a&gt; and its ability to take a simple text file and create &lt;a href="https://drushcommands.com/"&gt;a full Drupal codebase with core and contrib modules and themes and external libraries&lt;/a&gt;. This simple text file is called a "make file", because it usually has the file extension &lt;code&gt;.make&lt;/code&gt;.&lt;br&gt;
The make file comes in &lt;a href="https://github.com/rpsu/dwd-security-in-code-deployment"&gt;two flavors&lt;/a&gt;: in the older &lt;a href="https://www.drupal.org/docs/develop/packaging-a-distribution/example-drupalorg-make-file"&gt;plain text (INI) format&lt;/a&gt; and in the &lt;a href="http://www.yaml.org/start.html"&gt;newer YAML format&lt;/a&gt;. Whereas the old-style INI make files have fairly loose format requirements (Listing 1), YAML indenting is important and dictates how your data is interpreted (Listing 2). Both are human readable, but YAML might be easier to scan. If you are working with Drupal 8, the YAML format of Drush make files is recommended; however, INI-style files will also work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 1: INI Make File&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; Older format is in INI format  
; Line with comment starts with a semicolon  
; Attributes are declared like this:  
; attribute = value  
; Attribute values with spaces and float-like string values must be quoted: ; attribute = "long value with spaces"
&lt;/span&gt;
&lt;span class="c"&gt;; Core must be defined.
&lt;/span&gt;&lt;span class="py"&gt;core&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;8.x&lt;/span&gt;
&lt;span class="c"&gt;; (Drush) api must be defined, always to '2'.
&lt;/span&gt;&lt;span class="py"&gt;api&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;2&lt;/span&gt;

&lt;span class="c"&gt;; Here you see the format of an array in a .make-file. Text enclosed
; in brackets are array keys, and each set to the right of the last is
; a layer deeper in the array. Note that the root array element is
; not enclosed in brackets.
; root_element[first_key][next_key] = value
&lt;/span&gt;
&lt;span class="c"&gt;; Define the Drupal core version you need to the last digit projects[drupal][version] = "8.2.3"
&lt;/span&gt;
&lt;span class="c"&gt;; Then define contrib modules etc.
; Define OAuth version to 8.x-2.0, do not include Drupal core version
; This is the same as
; projects[views][version] = "2.0"
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[oauth]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"2.0"&lt;/span&gt;

&lt;span class="c"&gt;; Define the where to put the module (should be inside sites/all/modules)
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[commerce][version]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"2.0-beta3"&lt;/span&gt;
&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[commerce][subdir]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"commerce"&lt;/span&gt;

&lt;span class="c"&gt;; You may also provide default values to all projects
; Now OAuth and other modules with no subdir definition will be placed in
&lt;/span&gt;&lt;span class="err"&gt;sites/all/modules/contrib&lt;/span&gt; &lt;span class="err"&gt;defaults&lt;/span&gt;&lt;span class="nn"&gt;[projects][subdir]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"contrib"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 2: YAML Make File&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# YAML format&lt;/span&gt;
&lt;span class="c1"&gt;# Line with comment starts with a hash&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Attributes are declared like this:&lt;/span&gt;
&lt;span class="c1"&gt;# attribute: value&lt;/span&gt;
&lt;span class="c1"&gt;# Attribute values with spaces and float-like string values must be quoted:&lt;/span&gt;
&lt;span class="c1"&gt;# attribute: 'long value'&lt;/span&gt;

&lt;span class="c1"&gt;# Core must be defined.&lt;/span&gt;
&lt;span class="na"&gt;core&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8.x&lt;/span&gt;
&lt;span class="c1"&gt;# (Drush) api must be defined, always to '2'.&lt;/span&gt;
&lt;span class="c1"&gt;# Version numbers that can be interpreted as floats must be quoted.&lt;/span&gt;
&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2'&lt;/span&gt;

&lt;span class="c1"&gt;# Here you see the format of an array in a .make.yml-file. Indented text&lt;/span&gt;
&lt;span class="c1"&gt;# "inside" a parent are array keys, and each set to the right of the last is&lt;/span&gt;
&lt;span class="c1"&gt;# a layer deeper in the array.&lt;/span&gt;
&lt;span class="c1"&gt;# Define the exact Drupal core version you need:&lt;/span&gt;
&lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;drupal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Version numbers that can't be interpreted as floats do not need quotes:&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8.2.3&lt;/span&gt;
  &lt;span class="c1"&gt;# Then define contrib modules etc.&lt;/span&gt;
  &lt;span class="c1"&gt;# Note that we're still inside 'projects' -array/object, hence the indenting:&lt;/span&gt;
  &lt;span class="na"&gt;oauth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2.0'&lt;/span&gt;
  &lt;span class="na"&gt;commerce&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;subdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;commerce&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2.0-beta3&lt;/span&gt;

&lt;span class="c1"&gt;# You may also provide default values to all projects&lt;/span&gt;
&lt;span class="c1"&gt;# Now OAuth and other modules with no subdir definition will be placed &lt;/span&gt;
&lt;span class="c1"&gt;# in sites/all/modules/contrib&lt;/span&gt;
&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;subdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;contrib'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use Resource Versions
&lt;/h2&gt;

&lt;p&gt;To make the codebase building process predictable to the last line of code, it is important to declare all versions, including core and contrib modules and themes and external libraries. Drupal core and module version declarations are explained in Listings 1 and 2, but you can set the contrib versions on the Git commit level, too (Listings 3 and 4).&lt;br&gt;
You need to specify the source URL and some other information to download external libraries in the make file (Listing 5 and 6).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 3: INI Git Commit&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; INI format, get a specific version of ctools module
; Download method defaults to git, so this is not necessary
; projects[ctools][download][type] = "git"
; Optionally provide git branch so Drush can write that to .info file
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[ctools][download][branch]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"8.x-3.x"&lt;/span&gt;
&lt;span class="c"&gt;; Git commit hash
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[ctools][download][revision]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1fe3649&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 4: YAML Git Commit&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# YAML format, get a specific version of ctools module&lt;/span&gt;
&lt;span class="c1"&gt;# Note continuous, we're still inside "projects" array.&lt;/span&gt;
  &lt;span class="na"&gt;ctools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;download&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Download method defaults to git, so this is not necessary&lt;/span&gt;
      &lt;span class="c1"&gt;# type: git&lt;/span&gt;
      &lt;span class="c1"&gt;# Optionally provide git branch so Drush can write that to&lt;/span&gt;
      &lt;span class="c1"&gt;# .info file&lt;/span&gt;
      &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8.x-3.X&lt;/span&gt;
      &lt;span class="c1"&gt;# Git commit hash&lt;/span&gt;
      &lt;span class="na"&gt;revision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1fe3649&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 5: INI – Source URL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; INI format, get a specific version of ckeditor library
; ckeditor (library) will be extracted
; Drupal 8: libraries/ckeditor
; Drupal 7: sites/all/libraries/ckeditor
&lt;/span&gt;&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[ckeditor][download][type]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;file&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[ckeditor][download][request_type]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;get&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[ckeditor][download][url]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"https://download.cksource.com/CKEditor%20for%20Drupal/edit/ckeditor_4.4.6_edit.zip"&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[ckeditor][directory_name]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"ckeditor"&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[ckeditor][type]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"library"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 6: YAML – Source URL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# YAML format, get a specific version of ckeditor module # ckeditor (library) will be extracted&lt;/span&gt;
&lt;span class="c1"&gt;# Drupal 8: libraries/ckeditor&lt;/span&gt;
&lt;span class="c1"&gt;# Drupal 7: sites/all/libraries/ckeditor&lt;/span&gt;
&lt;span class="na"&gt;libraries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="na"&gt;ckeditor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;download&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;file&lt;/span&gt;
    &lt;span class="na"&gt;request_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://download.cksource.com/CKEditor%20for%20Drupal/edit/ckeditor_4.4.6_edit.zip'&lt;/span&gt;
  &lt;span class="na"&gt;directory_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ckeditor&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library you want to use might not provide releases or files for download. If the code repository isn’t public or you are unable to follow the updates, there is not much to be done besides store that code to your project’s version control – or at least verify downloadable file checksums to prevent unpleasant surprises (Listing 7 and 8). (This project repository is in fact publicly available at GitHub, and you could, instead of relying on a file hash, use a specific commit.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 7: INI – Verify Checksum&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; INI format, make sure file has not changed verifying file hash
&lt;/span&gt;&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[isotope][download][type]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;get&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[isotope][download][url]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;http://isotope.metafizzy.co/jquery.isotope.min.js&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[isotope][download][md5]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;ac35f7863494170cddea8ddb144675d5&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[isotope][directory_name]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;jquery.isotope&lt;/span&gt;
&lt;span class="err"&gt;libraries&lt;/span&gt;&lt;span class="nn"&gt;[isotope][type]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 8: YAML – Verify Checksum&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Yaml format, make sure file has not changed verifying file hash&lt;/span&gt;
&lt;span class="na"&gt;libraries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;isotope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;download&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://isotope.metafizzy.co/jquery.isotope.min.js'&lt;/span&gt;
      &lt;span class="na"&gt;md5&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ac35f7863494170cddea8ddb144675d5&lt;/span&gt;
    &lt;span class="na"&gt;directory_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jquery.isotope&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Failing to provide versions or at least to verify the retrieved file checksums, you can’t be sure you have the same codebase when compared with other builds. It is time dependent in the sense that it can’t be predicted when a module will have an update available and will replace some previously downloaded older version of itself. In practice, this might mean one of your colleagues is facing an issue, bug, or even vulnerability that has already been fixed in your codebase – simply because you happened to build your local this week, and your colleague did the same the previous week (Listing 9 and 10).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 9: INI – Get Specific Version&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; INI format
; Get the latest release within 8.x-1 -version:
; projects[role_expose] = 1
; Get the latest development version:
; projects[role_expose] = 1.x
; Get the specified version even when it is not the latest release:
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[role_expose]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 10: YAML – Get Specific Version&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Yaml format&lt;/span&gt;
&lt;span class="c1"&gt;# Note the indentation, we're still inside "projects" array.&lt;/span&gt;
&lt;span class="na"&gt;role_expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the latest release within 8.x-1 -version:&lt;/span&gt;
  &lt;span class="c1"&gt;# version: 1&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the latest development version:&lt;/span&gt;
  &lt;span class="c1"&gt;# version: 1.x&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the specified version even when it is not the latest&lt;/span&gt;
  &lt;span class="c1"&gt;# release&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short: Always use fixed versions and specific commits, or at least verify checksums if none are available.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drush</category>
    </item>
    <item>
      <title>Security in Code Deployment - part 2: Patch modules with Drush</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Wed, 19 Jan 2022 14:03:09 +0000</pubDate>
      <link>https://dev.to/rpsu/security-in-code-deployment-part-2-patch-modules-with-drush-4g6a</link>
      <guid>https://dev.to/rpsu/security-in-code-deployment-part-2-patch-modules-with-drush-4g6a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Part 2/5.&lt;/strong&gt; The article was initially published in &lt;a href="https://shop.linuxnewmedia.com/us/magazines/drupal-watchdog/eh35014.html"&gt;Drupal Watchdog 7.01&lt;/a&gt;, spring 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code examples for this article&lt;/strong&gt;: &lt;a href="https://github.com/rpsu/dwd-security-in-code-deployment"&gt;https://github.com/rpsu/dwd-security-in-code-deployment&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security in Code Deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-1-drush-make-file-b6i"&gt;Part 1: Drush make file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2: Patch modules with Drush&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-3-unknown-drupal-codebase-2f3"&gt;Part 3: Unknown Drupal codebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-4-advantages-of-using-composer-json-ijm"&gt;Part 4: Advantages of using Composer JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/rpsu/security-in-code-deployment-part-5-patching-with-composer-and-deploy-3o04"&gt;Part 5: Patching with Composer and Deploy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Occasionally (or more often) your project could have needs that require you to modify the available module code. Maybe the module has a bug or lacks a required feature, which has in fact already been addressed in the module issue queue on Drupal.org (see “Checking the Issue Queue” box) – after all, Drupal has a large and active community. All you need to do is find out if a working patch is available that fits your needs or fixes the bug in question.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CHECKING THE ISSUE QUEUE
Go to the specific module’s page on Drupal.org, find the Issues for section in the sidebar, and search. If a proposed solution to your problem exists, patches can be found after the Issue de- scription. Be sure to read the whole discussion to see if it actually solves your problem.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A patch file is a recipe describing what changes should be made and to which files. Explaining and creating patch files is outside the scope of this article, but you should be able to find help on &lt;a href="https://www.drupal.org/patch"&gt;Drupal.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You could fix the issue manually or apply the patch and leave it fixed on the server, but this solution is against best practices, because the very next codebase update will override the changes you’ve made and reintroduce the issue.&lt;/p&gt;

&lt;p&gt;You could also try to remember to apply the patch or changes each time you do updates, but that’s quite an error-prone process. You can and should offload this work to Drush. If you need a custom patch for your module, you have two options: (1) let Drush patch your module using a public patch file or (2) use a local patch file.&lt;/p&gt;

&lt;p&gt;Drush is fully capable of patching your code as instructed in the make file. All it needs is the path to the patch file. The path can be a full URL or a path to a local file relative to the make file itself (e.g., Listings 11 and 12). When you build a codebase with patches in the make file, Drush will create a &lt;code&gt;PATCHES.txt&lt;/code&gt; file for each patched module, which can be found next to the project .info file and Drupal core installation root.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LISTING 11: INI – Patching a Module&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;;  INI format, patching the module, both public and local patch files
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[field_group][version]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;"1.0-rc4"&lt;/span&gt;
&lt;span class="c"&gt;; Explain briefly why this patch is needed.
; Get the file path from the drupal.org issue in question and
; use issue number as patch array key.
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[field_group][patch][2761159]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;https://www.drupal.org/files/issues/field_group-empty_group_nonnumeric_index-2761159-2-D8.patch&lt;/span&gt;
&lt;span class="c"&gt;; Use file in patches-folder (relative to .make-file location)
&lt;/span&gt;&lt;span class="err"&gt;projects&lt;/span&gt;&lt;span class="nn"&gt;[field_group][patch][other_fix]&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;patches/field_group-fix_it.patch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LISTING 12: YAML – Patching a Module&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Yaml format, patching the module, both public and local patch files # Note the indentation, we're still inside "projects" array.&lt;/span&gt;
&lt;span class="na"&gt;field_group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="c1"&gt;# Get the latest release within 8.x-1 -version:&lt;/span&gt;
&lt;span class="c1"&gt;# version: 1&lt;/span&gt;
&lt;span class="c1"&gt;# Get the latest development version:&lt;/span&gt;
&lt;span class="c1"&gt;# version: 1.x&lt;/span&gt;
&lt;span class="c1"&gt;# Get the specified version even when it is not the latest release&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.0-rc4'&lt;/span&gt;
&lt;span class="na"&gt;patch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Explain briefly why this patch is needed.&lt;/span&gt;
  &lt;span class="c1"&gt;# Get the file path from the drupal.org issue in question and&lt;/span&gt;
  &lt;span class="c1"&gt;# use issue number as patch array key.&lt;/span&gt;
  &lt;span class="na"&gt;2761159&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.drupal.org/files/issues/field_group-empty_group_nonnumeric_index-2761159-2-D8.patch'&lt;/span&gt;

  &lt;span class="c1"&gt;# Use file in patches-folder (relative to .make-file location)&lt;/span&gt;
  &lt;span class="na"&gt;other_fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;patches/field_group-fix_it.patch'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short, out of all possible solutions, do not simply fix the code on your server. Extract the changes regardless of how you’ve made them, patch your code with a Drush make file, and preferably use a public patch file from the Drupal. org issue queue.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>drush</category>
      <category>patching</category>
    </item>
    <item>
      <title>Create new base box for Vagrant development</title>
      <dc:creator>Perttu Ehn</dc:creator>
      <pubDate>Wed, 19 Jan 2022 08:00:22 +0000</pubDate>
      <link>https://dev.to/rpsu/create-new-base-box-for-vagrant-development-2apa</link>
      <guid>https://dev.to/rpsu/create-new-base-box-for-vagrant-development-2apa</guid>
      <description>&lt;p&gt;This blog post has been initially released in &lt;a href="https://www.exove.com"&gt;Exove&lt;/a&gt;'s Tech blog, but &lt;a href="https://web.archive.org/web/20160624001745/http://www.exove.com/techblog/create-new-base-box-for-vagrant-development/"&gt;can only be found on the Archive Org's magnificient webarchive&lt;/a&gt; since the blog has disappeared after the publication day.&lt;br&gt;&lt;br&gt;
As turned out, the "first post" ended up being the only one, not a serie of blog posts.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;This is a first post of series "Get your local [Drupal] development environment in decent shape". Although this is targeted to Drupal developers, first three parts are fully CMS agnostic. So you could use this as a basis to get any other - say Wordpress, Ez or any other PHP based CMS developing platform up and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Distro of our choise is Scientific Linux 7
&lt;/h2&gt;

&lt;p&gt;We at &lt;a href="https://dev.toat%20Exove"&gt;http://www.exove.com&lt;/a&gt; are using &lt;a href="https://dev.toScientific%20Linux%207"&gt;http://scientificlinux.org/&lt;/a&gt; [SL7] as development environment distribution. It is a close relative to Red Hat Entrerprice Linux (and therefore also Centos et.al.) and there are &lt;a href="http://scientificlinux.org/about/why-make-scientific-linux/"&gt;no significant differences to Red Hat&lt;/a&gt; used so often as production site platform. It is fairly lightweight and as easy to configure as any Red Hat derivative.&lt;/p&gt;

&lt;p&gt;Here you can find a list of Scientific Linux source mirrors. &lt;strong&gt;Pick the closest one&lt;/strong&gt; to you instad of blindly copy-pasting all URL in this blog post. It is really not that difficult.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://scientificlinux.org/downloads/sl-mirrors/"&gt;http://scientificlinux.org/downloads/sl-mirrors/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this blog post's purpose the closest mirror is the one in Finland, so URL's are something like this: &lt;a href="http://www.nic.funet.fi/pub/mirrors/scientificlinux.org/scientific/7/x86_64/iso/"&gt;http://www.nic.funet.fi/pub/mirrors/scientificlinux.org/scientific/7/x86_64/iso/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools you should have installed
&lt;/h2&gt;

&lt;p&gt;These instructions assume you are using&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OS X (10.9 or newer should be fine)&lt;/li&gt;
&lt;li&gt;VirtualBox 5.0.0 or newer&lt;/li&gt;
&lt;li&gt;Vagrant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that OS X El Capitano works best with VirtualBox 5 and Vagrant 1.7.3 or newer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Download a Scientific Linux installation media
&lt;/h2&gt;

&lt;p&gt;Start by downloading SL7 installation media. Netinst-image is the smallest and all we need here. Other images have a lot of stuff we have no need for.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.nic.funet.fi/pub/mirrors/scientificlinux.org/scientific/7/x86_64/iso/SL-7.1-x86_64-netinst.iso"&gt;http://www.nic.funet.fi/pub/mirrors/scientificlinux.org/scientific/7/x86_64/iso/SL-7.1-x86_64-netinst.iso&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; Check SHA1, SHA256 before using any such image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up VirtualBox
&lt;/h2&gt;

&lt;p&gt;Launch VirtualBox and start by creating new virtual machine instance with name 'SL7-server'. &lt;strong&gt;Do not power it up&lt;/strong&gt;, but configure it's settings first (CMD + S sould bring up the configure options).&lt;/p&gt;

&lt;p&gt;Turn off some unnecessary hardware options and configure network and "insert" the installation media:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;General / Advanced / Shared clipboard&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Set to &lt;strong&gt;none&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;General / Advanced / Drag'n'drop&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Set to &lt;strong&gt;none&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;System / Motherboard / Pointing device:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;PS/2&lt;/strong&gt; (instead of available USB -options)&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Audio&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;strong&gt;disabled&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Network - Adapter 1&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;NAT&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Network - Adapter 1 / Advanced / Port Forwarding&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Set forwarding SSH &lt;strong&gt;2222 -&amp;gt; 22&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Network - Adapter 2,3,4&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;strong&gt;disabled&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Ports / USB&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Enable USB Controller -&amp;gt; &lt;strong&gt;unchecked&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;SerialPort&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Enable Serial port -&amp;gt; &lt;strong&gt;unchecked&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Add installation media to DVD slot&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install SL7 server in virtual machine
&lt;/h2&gt;

&lt;p&gt;Power up the machine and start regular installation using UI provided by VirtualBox. These setting may vary depending your needs. For example most people might not set timezone and keyboard like this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set used keyboards (feel free to skip this part)&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Finnish Macintosh&lt;/li&gt;
&lt;li&gt;English US&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Set timezone (feel free to skip this part)&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Europe/Helsinki&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Enable networking (disabled by default)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set installation source &lt;em&gt;to the closest mirror to you&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.nic.funet.fi/pub/mirrors/scientificlinux.org/scientific/7/x86_64/os/"&gt;http://www.nic.funet.fi/pub/mirrors/scientificlinux.org/scientific/7/x86_64/os/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Wait for a while to fetch repository data from the mirror.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Choose installation type&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;We'll install now a minimal server with only limited amount of packages to&lt;/li&gt;
&lt;li&gt;keep the box small.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Install&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start installation, and...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;During the OS installation process (which will take a few minutes)&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Set root passwd to vagrant&lt;/li&gt;
&lt;li&gt;Add new user vagrant with password vagrant&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;REBOOT&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The installation media will be "ejected" automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install/remove packages
&lt;/h2&gt;

&lt;p&gt;Now you can install the tools you wish to have already in place in the base box. We'll add only two smallish packages, rest of the packages will be taken care of our Ansible roles when setting up the actual vagrant box instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remove unnecssary packages
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Stop and remove Postfix &lt;strong&gt;[optional]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;systemctl stop postfix yum remove postfix&lt;/p&gt;

&lt;h3&gt;
  
  
  Install other packages
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install packages &lt;em&gt;nano&lt;/em&gt; and &lt;em&gt;wget&lt;/em&gt; (not required by any means, just my personally preferred tools over other options) &lt;strong&gt;[optional]&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum install nano bash-completion wget
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure networking in on at boot&lt;/p&gt;

&lt;p&gt;grep -Hn '^ONBOOT' /etc/sysconfig/network-scripts/*&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This should result to 2 files witn &lt;code&gt;ONBOOT="yes"&lt;/code&gt; -values. If you see line &lt;code&gt;/etc/sysconfig/network-scripts/ifcfg-enp0s3:ONBOOT="no"&lt;/code&gt;, edit the file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /etc/sysconfig/network-scripts/ifofg-enp0s3`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;..and check again that the value is now changed.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep -Hn '^ONBOOT' /etc/sysconfig/network-scripts/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Pass Grub 2 bootloader faster &lt;strong&gt;[optional]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Set timeout 1 second, as default seems to be 5 seconds. This is changed only to make booting 4 seconds faster.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -i 's/GRUB_TIMEOUT=[\d]{1,2}/GRUB_TIMEOUT=1/' /etc/default/grub`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Compile Grub config using &lt;code&gt;grub2-mkconfig&lt;/code&gt;tool:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grub2-mkconfig -o /boot/grub2/grub.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Turn SELinux off &lt;strong&gt;[optional but recommended]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As this box is a base for a local development vagrant box, there is no need to have SELinux enabled. It will most probably just make your life more difficult.&lt;br&gt;&lt;br&gt;
   Make sure to &lt;strong&gt;reboot&lt;/strong&gt; after this; &lt;code&gt;init 6&lt;/code&gt; will do it for you, though.&lt;/p&gt;

&lt;p&gt;sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config init 6`&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add sudo-permission to vagrant user&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;echo 'vagrant ALL=(ALL) NOPASSWD:ALL' &amp;gt; /etc/sudoers.d/vagrant&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update sshd-configuration where needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;nano /etc/ssh/sshd_config&lt;/p&gt;

&lt;p&gt;Port 22 (or have Port -setting disabled by adding a # in front of the line)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PubKeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PermitEmptyPasswords no`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Restart ssh daemon:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service sshd restart`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Install vagrant insecure key&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  mkdir -p /home/vagrant/.ssh
  wget --no-check-certificate https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub -O /home/vagrant/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ensure we have the correct permissions set&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 0700 /home/vagrant/.ssh
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant:vagrant /home/vagrant/.ssh`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Test ssh'ing as vagrant-user from you &lt;em&gt;current&lt;/em&gt; root session (create keys, test access, delete keys and known_hosts etc. after testing):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -v vagrant@localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After succesful login exit and remove (all) keys from root's known_hosts -file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo &amp;gt; /root/.ssh/known_hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Disbable tty -requirement for sudoers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;visudo&lt;/p&gt;

&lt;p&gt;Comment out requiretty -setting changing this line&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Defaults requiretty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; You may use simpler text editor &lt;em&gt;nano&lt;/em&gt; instad of &lt;em&gt;vim&lt;/em&gt; if you change your EDITOR value with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EDITOR=$(which nano)
export EDITOR`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This change is temporary and is valid only within current shell session.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install DKMS -package required by VirtualBox Guest additions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;..as described in &lt;a href="https://dev.tohere"&gt;http://www.linuxquestions.org/questions/linux-software-2/installing-dkms-on-rhel-7-0-a-4175510666/#post5239266&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Closest download mirrors can be found in from &lt;a href="http://rpmfind.net//linux/RPM/epel/7/x86_64/d/dkms-2.2.0.3-30.git.7c3e7c5.el7.noarch.html"&gt;http://rpmfind.net//linux/RPM/epel/7/x86_64/d/dkms-2.2.0.3-30.git.7c3e7c5.el7.noarch.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Downlaod DKMS pacakge:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget ftp://rpmfind.net/linux/epel/7/x86_64/d/dkms-2.2.0.3-30.git.7c3e7c5.el7.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Install DKMS requirements (these will install also 30+ other packages):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum install gcc kernel-devel kernel-headers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Install the local DKMS package you've just downloaded:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum localinstall dkms-2.2.0.3-30.git.7c3e7c5.el7.noarch.rpm --nogpgcheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Install Development Tools (this will install also 60+ other packages):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum groupinstall 'Development Tools'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add/update kernel for VBoxGuestAdditions. This should install kernel version 3.10.0-229 or newer:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum update kernel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Install VirtualBox guest additions:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;.. as described in &lt;a href="http://download.virtualbox.org/virtualbox/5.0.0/"&gt;http://download.virtualbox.org/virtualbox/5.0.0/&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  wget http://download.virtualbox.org/virtualbox/5.0.0/VBoxGuestAdditions_5.0.0.iso
  sudo mkdir /media/VBoxGuestAdditions
  sudo mount -o loop,ro VBoxGuestAdditions_4.3.8.iso /media/VBoxGuestAdditions
  /media/VBoxGuestAdditions/VBoxLinuxAdditions.run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Correct missing locale -settings &lt;strong&gt;[optional]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add locale -settings to avoid repeating error message when logging through ssh to your box (as in every single time you use &lt;code&gt;vagrant ssh&lt;/code&gt; -command). Edit this file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano /etc/environments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add these lines:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LANG=en_US.utf-8
LC_ALL=en_US.utf-8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Save and exit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give box a hostname &lt;strong&gt;[optional]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use &lt;code&gt;nmcli&lt;/code&gt; tool to to set a more desctiptive hostname (default is localhost.localdomain)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nmcli general hostname sl7-dev.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Check that changes was made with&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nmcli general hostname`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;REBOOT NOW&lt;/strong&gt;:&lt;/p&gt;

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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Finalize and cleanup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ensure all packages are up to date, once more.&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;Clean up yum cache&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum clean all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Minimize the size of VirtualBox virtual machine file&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run this command to 1st fill up the virtual drive with an empty file and then removing the empty file. It will help VirtualBox to minimize the virtual drive.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dd if=/dev/zero of=/EMPTY bs=1M
rm -f /EMPTY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Clean up bash history &lt;strong&gt;[optional]&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Empty bash history and exit. Note that last session history is saved when exiting to the history file, so you might need to do this twice (and log out in between) to get empty history file:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo &amp;gt; .bash_history&lt;br&gt;
exit`&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Package the virtual machine for vagrant -use&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Package newly baked Scientific Linux ready for Vagrant and do a test run.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Assuming&lt;/strong&gt; VBox server name &lt;code&gt;SL7-server&lt;/code&gt;, change accoringly&lt;/p&gt;

&lt;p&gt;vagrant box remove test-sl7 2&amp;amp;&amp;gt;/dev/null rm package.box 2&amp;amp;&amp;gt;/dev/null vagrant package --base SL7-server vagrant box add test-sl7 package.box mkdir test cd test vagrant init test-sl7 vagrant up vagrant ssh&lt;/p&gt;

&lt;h2&gt;
  
  
  Credit
&lt;/h2&gt;

&lt;p&gt;Putting the credit wher it belongs! Main sources used to get this stuff in order are (but here just as a list without any spesific order of imortance):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://docs.vagrantup.com/v2/virtualbox/boxes.html"&gt;http://docs.vagrantup.com/v2/virtualbox/boxes.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://aruizca.com/steps-to-create-a-vagrant-base-box-with-ubuntu-14-04-desktop-gui-and-virtualbox/"&gt;http://aruizca.com/steps-to-create-a-vagrant-base-box-with-ubuntu-14-04-desktop-gui-and-virtualbox/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.tecmint.com/remove-unwanted-services-in-centos-7/"&gt;http://www.tecmint.com/remove-unwanted-services-in-centos-7/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vishmule.wordpress.com/2015/02/17/how-to-change-the-grub-timeout-in-rhel-7/"&gt;https://vishmule.wordpress.com/2015/02/17/how-to-change-the-grub-timeout-in-rhel-7/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xuri.me/2015/09/06/resolve-setting-locale-failed-on-linux.html"&gt;https://xuri.me/2015/09/06/resolve-setting-locale-failed-on-linux.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.itzgeek.com/how-tos/linux/centos-how-tos/change-hostname-in-centos-7-rhel-7.html"&gt;http://www.itzgeek.com/how-tos/linux/centos-how-tos/change-hostname-in-centos-7-rhel-7.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;h3&gt;
  
  
  Found a typo? Spotted grammar mistakes or confusing phrases?
&lt;/h3&gt;

&lt;p&gt;If you've found a typo, a sentence that could be improved or anything else that should be updated on this blog post, you can access it through a git repository and make a pull request. Instead of posting a comment, please go directly to &lt;a href="https://github.com/rpsu/devto-blog/tree/main/blog-posts"&gt;my Dev.to Github repository&lt;/a&gt; and open a new pull request with your changes.&lt;/p&gt;

</description>
      <category>vagrant</category>
      <category>scientificlinux</category>
      <category>localdev</category>
      <category>drupal</category>
    </item>
  </channel>
</rss>
