<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[I solve problems]]></title><description><![CDATA[Code - Electronics - IoT]]></description><link>https://ivancarosati.com/</link><image><url>https://ivancarosati.com/favicon.png</url><title>I solve problems</title><link>https://ivancarosati.com/</link></image><generator>Ghost 3.0</generator><lastBuildDate>Wed, 15 Apr 2026 09:07:30 GMT</lastBuildDate><atom:link href="https://ivancarosati.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Let's Encrypt! (SSL/TLS Setup)]]></title><description><![CDATA[Let's Encrypt is a free, automated, and open certificate authority — If you don't know them, you should.]]></description><link>https://ivancarosati.com/lets-encrypt-ssl-tls-setup/</link><guid isPermaLink="false">5d78f9d120b8b42edbf26d62</guid><category><![CDATA[Amazon Linux AMI]]></category><category><![CDATA[AWS]]></category><category><![CDATA[EC2]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Fri, 13 Sep 2019 16:52:53 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1517319821400-28323502a29a?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1517319821400-28323502a29a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=2000&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Let's Encrypt! (SSL/TLS Setup)"><p>I've been following those guys at the Internet Security Research Group (ISRG) for a while and I was very excited when they got <a href="https://letsencrypt.org">Let's Encrypt</a> out of beta!</p><p>Let's Encrypt is a free, automated, and open certificate authority — If you don't know them, <a href="https://letsencrypt.org/2016/06/22/https-progress-june-2016.html">you should</a>.</p><p>They have multiple clients you can use to setup let's encrypt certificates on your server. I liked the "suggested" one, such an awesome name.</p><p>Certbot. — You can see the <a href="https://certbot.eff.org">docs here</a>.</p><h2 id="prerequisites">Prerequisites</h2><ul><li>Amazon Linux AMI 2 / Should be fine with Ubuntu as well.</li><li>NGINX</li><li>EPEL repo enabled. (<a href="https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F">Look here for details</a>, <code>$ sudo amazon-linux-extras install epel</code>.)</li></ul><p>If you need to setup a server from scratch, <a href="https://ivancarosati.com/amazon-linux-ami-setup-ec2/">look here</a>.</p><h2 id="let-s-get-started-">Let's Get Started!</h2><p>SSH into your machine and install certbot.</p><p> <code>$ sudo yum install certbot python2-certbot-nginx</code> </p><p>Once the process finish we can start creating the certificates we need.</p><p> <code>$ sudo certbot certonly --nginx</code></p><p>After launching the command, certbot does a quick scan of your nginx configuration and it prompts you with a list. Select the one you want to create, if you want to create more than one you can use commas or a space to separate them. Please note that during the creation process certbot will try to contact your domain name and will verify that it is pointing to your server. If you don't have it setup yet, it will fail.</p><p>Once the generation is completed you should be seeing the message that the certificates are generated and stored correctly.</p><pre><code> - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2019-12-10. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
</code></pre><p>We're almost ready to add the certificates to our nginx configuration! To add a little extra security we can generate our own <code>dhparams</code>.  Usually I store them under <code>/etc/ssh/example.com/dhparam.pem</code>, but you can store them where you prefer.</p><p> <code>$ sudo mkdir -p /etc/ssl/example.com</code> </p><p> <code>$ sudo openssl dhparam -out /etc/ssl/example.com/dhparam.pem 4096</code> </p><p>Let it complete, it will take a few minutes, but you have to do it only once.</p><h2 id="nginx">NGINX</h2><p>We need to edit the server configuration and add the directives for the certificates.</p><p> <code>$ sudo vim /etc/nginx/sites-enabled/example.com.conf</code> </p><p>Modify your configuration as showed below.</p><pre><code class="language-NGINX">server {
	add_header X-Frame-Options SAMEORIGIN;
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header Strict-Transport-Security 'max-age=31536000;';

	listen 443 ssl;
	server_name example.com;
	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_dhparam /etc/ssl/example.com/dhparam.pem;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_prefer_server_ciphers on;
	ssl_session_cache shared:SSL:10m;
	ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED';
	ssl_stapling on;

	charset utf-8;

	location = /favicon.ico { access_log off; log_not_found off; }
	location = /robots.txt	{ access_log off; log_not_found off; }

	access_log /var/log/nginx/example.com_access.log;
	error_log /var/log/nginx/example.com_error.log;

	# Your directives here. 
    # This is where you're actually serving your content.
}

# Redirect HTTP to HTTPS.
server {
	listen 80;
	server_name example.com;

	return 301 https://example.com$request_uri;
}

# Redirect WWW to not WWW domain.
# Please note WWW will need his own certificate and dhparam.
server {
	listen 80;
	listen 443 ssl;
	server_name www.example.com;
	ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
	ssl_dhparam /etc/ssl/www.example.com/dhparam.pem;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_prefer_server_ciphers on;
	ssl_session_cache shared:SSL:10m;
	ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED';
	ssl_stapling on;

	return 301 https://example.com$request_uri;
}</code></pre><p>Save and restart nginx <code>$ sudo service nginx restart</code>. </p><h2 id="certificate-renewal">Certificate Renewal</h2><p>Now for automatic certificate renewals we're going to create an `.sh` script that will be executed by the cron periodically. I like to keep all my cron scripts under <code>~/scripts/cron</code> but you can save them wherever you like.</p><p> <code>$ mkdir -p ~/scripts/cron &amp;&amp; vim ~/scripts/cron/certbot-renew.sh</code></p><p>Put the following inside, save and exit!</p><pre><code>#!/bin/sh
dt=$(date '+%d/%m/%Y %H:%M:%S');
echo "### Started @ $dt ###"

python -c 'import random; import time; time.sleep(random.random() * 3600)' &amp;&amp; certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start"

dt=$(date '+%d/%m/%Y %H:%M:%S');
echo "### Ended @ $dt ###"
echo ""
echo ""</code></pre><p>The beginning &amp; ending lines simply produce an output that is useful later on to be able to create a entry on our log file. The centre piece of the script invoke a pyton script that creates a random wait time before attempting to run <code>certbot renew</code>, this helps certbot avoid that everybody is trying to perform this action at the same time around the world. The pre-hook and post-hook are run only if a certificate renewal is actually performed, so it's okay to run this often as it will not result in nginx stopping and starting, unless a certificate is renewed and replaced.</p><p>To add the above script to cron you can type <code>$ sudo crontab -e</code> to edit your crontab jobs for the user root. Certbot needs to run as root to be able to renew and write all the certificate files.</p><p> Add the following at the bottom of the file.</p><p><code>0 0,12 * * * /home/ec2-user/scripts/cron/certbot-renew.sh  &gt;&gt; /home/ec2-user/log/cron.log</code> </p><p>Save and you're good to go. Please note that I like to save a log in <code>~/log/cron.log</code> so I can see the result of the cron running.</p><h2 id="log-rotation-optional-but-nice-">Log Rotation (Optional, but nice!)</h2><p>Over time the log file can get big and it will start clogging your disk space. To avoid having to manage this manually we can use the utility <code>logrotate</code>.</p><p>To setup logrotate you have to simply edit `logrotate.conf` typing <code>$ sudo vim /etc/logrotate.conf</code>. Paste the following at the bottom of the file and save.</p><pre><code># My Log Files
/home/ec2-user/log/cron.log {
    weekly
    rotate 8
    create
}</code></pre><p>This tells the <code>logrotate</code> utility to monitor the <code>cron.log</code> file, rotate the file every week, keep 8 weeks worth of files, and create a new file every time a rotation is performed. Brilliant!</p><h2 id="test">Test</h2><p>To test your SSL setup you can head over <a href="https://www.ssllabs.com/ssltest/">https://www.ssllabs.com/ssltest/</a> and type your website domain to get an idea of how good and secure your setup is!</p><figure class="kg-card kg-image-card"><img src="https://ivancarosati.com/content/images/2019/09/let-s-encrypt-ssl-labs-reduct.png" class="kg-image" alt="Let's Encrypt! (SSL/TLS Setup)"></figure><p>Enjoy!</p>]]></content:encoded></item><item><title><![CDATA[Ender 3 - Z Cables Holder]]></title><description><![CDATA[This is a snap on holder for the Z Cables. Keeps things nice and tidy!]]></description><link>https://ivancarosati.com/ender-3-z-cables-holder/</link><guid isPermaLink="false">5c6ba8af6fb9367c5fe9c0ec</guid><category><![CDATA[3D Printing]]></category><category><![CDATA[Creality]]></category><category><![CDATA[Ender 3]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Tue, 19 Feb 2019 07:29:46 GMT</pubDate><media:content url="https://ivancarosati.com/content/images/2019/02/Cable_Holder_1.2_2019-Feb-18_07-24-13AM-000_CustomizedView276047825-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://ivancarosati.com/content/images/2019/02/Cable_Holder_1.2_2019-Feb-18_07-24-13AM-000_CustomizedView276047825-1.png" alt="Ender 3 - Z Cables Holder"><p>I've spent quite a bit looking for a cable holder for my new Ender 3 machine and I couldn't find anything that I truly liked and at the same time was easy to mount.</p><p>Soooo, I decided to make my own!</p><p>This is a snap on holder for the Z Cables. Keeps things nice and tidy!</p><p>You can download it here: <a href="https://www.thingiverse.com/thing:3437853">https://www.thingiverse.com/thing:3437853</a></p><figure class="kg-card kg-image-card"><img src="https://ivancarosati.com/content/images/2019/02/Cable_Holder_1.2.gif" class="kg-image" alt="Ender 3 - Z Cables Holder"></figure><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://ivancarosati.com/content/images/2019/02/Cable_Holder_1.2_2019-Feb-18_07-24-13AM-000_CustomizedView276047825.png" width="4000" height="4000" alt="Ender 3 - Z Cables Holder"></div><div class="kg-gallery-image"><img src="https://ivancarosati.com/content/images/2019/02/Cable_Holder_1.2_2019-Feb-18_07-24-41AM-000_CustomizedView38759758951.png" width="4000" height="4000" alt="Ender 3 - Z Cables Holder"></div><div class="kg-gallery-image"><img src="https://ivancarosati.com/content/images/2019/02/_MG_5586-HDR.jpg" width="5593" height="3729" alt="Ender 3 - Z Cables Holder"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://ivancarosati.com/content/images/2019/02/_MG_5600-HDR.jpg" width="4309" height="2873" alt="Ender 3 - Z Cables Holder"></div><div class="kg-gallery-image"><img src="https://ivancarosati.com/content/images/2019/02/_MG_5573-HDR.jpg" width="5443" height="3629" alt="Ender 3 - Z Cables Holder"></div><div class="kg-gallery-image"><img src="https://ivancarosati.com/content/images/2019/02/_MG_5552-HDR.jpg" width="4149" height="2766" alt="Ender 3 - Z Cables Holder"></div></div></div></figure><p>I'm also working on a series for all things Ender 3, upgrades, and a finishing kit that you can print yourself!</p><p>If you like this, or have suggestions, let me know in the comments below.</p>]]></content:encoded></item><item><title><![CDATA[No-IP with Raspberry PI]]></title><description><![CDATA[We're gonna be setting up a DDNS service with automatic updates from our RaspberryPi!]]></description><link>https://ivancarosati.com/no-ip-with-raspberry-pi/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a196b</guid><category><![CDATA[Snippets]]></category><category><![CDATA[Raspberry PI]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Mon, 10 Dec 2018 20:18:17 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>We're gonna be setting up a DDNS service with automatic updates from our RaspberryPi!</p>
<p>No-IP service at <a href="https://www.noip.com">noip.com</a>, provides up to 3 hostnames for free. The only caveat is that they need to be confirmed every 30 days, for a small fee all those limitations are lifted.</p>
<p>Register a new account (or use your existing one) and setup a new hostname under the hostnames section. Once this is done come back here and we're gonna setup automatic updates!</p>
<p>SHH into you RaspberryPi and let's get started. (You can do a new installation following the guide <a href="https://ivancarosati.com/raspbian-stretch-headless-setup-for-raspberry-pi/">here</a>.)</p>
<h3 id="prerequisite">Prerequisite</h3>
<p>I like to use VIM to edit files, which doesn't come by default with<br>
Raspbian Stretch Lite.<br>
Type the following to install it:<br>
<code>$ sudo apt-get install vim</code></p>
<p>Feel free to use whatever editor you know and it's comfortable to you.</p>
<h3 id="installdynamicupdateclient">Install Dynamic Update Client</h3>
<p>We're gonna be downloading the DUC from no-ip website.<br>
<code>$ cd /usr/local/src</code><br>
<code>$ sudo wget https://www.noip.com/client/linux/noip-duc-linux.tar.gz</code><br>
<code>$ sudo tar xzf noip-duc-linux.tar.gz</code></p>
<p>At this point you need to <code>ls</code> to check what version is the one you downloaded. At the time of writing the latest version is <code>noip-2.1.9-1</code>.</p>
<p>We need to build the sources now:<br>
<code>$ cd noip-2.1.9-1</code><br>
<code>$ sudo make</code><br>
<code>$ sudo make install</code></p>
<p>At this point you will be prompted by the installer for a few things:<br>
<code>Please enter the login/email string for no-ip.com</code><br>
<code>Please enter the password for user 'email@example.com'</code></p>
<p>This section only apply if you have multiple hosts for the same account.<br>
<code>2 hosts are registered to this account.</code><br>
<code>Do you wish to have them all updated?[N] (y/N)</code><br>
<code>Do you wish to have host [xxx.ddns.net] updated?[N] (y/N)</code></p>
<p><code>Please enter an update interval:[30]</code><br>
This is the interval which you want the service to update your IP address. I find 5 minutes to be frequent enough.</p>
<p><code>Do you wish to run something at successful update?[N] (y/N)</code><br>
Unless you have specific needs, you don't need to run anything after the update so you can just say no to this one.</p>
<h3 id="runducasaservice">Run DUC as a service</h3>
<p>We need to create a service to run the DUC in background.<br>
Create the following file:<br>
<code>$ sudo vim /etc/systemd/system/noip2.service</code></p>
<p>Paste the following into the newly created file:</p>
<pre><code># Simple No-ip.com Dynamic DNS Updater
#
# By Nathan Giesbrecht (http://nathangiesbrecht.com)
#
# 1) Install binary as described in no-ip.com's source file (assuming results in /usr/local/bin)
# 2) Run sudo /usr/local/bin/noip2 -C to generate configuration file
# 3) Copy this file noip2.service to /etc/systemd/system/
# 4) Execute `sudo systemctl enable noip2`
# 5) Execute `sudo systemctl start noip2`
#
# systemd supports lots of fancy features, look here (and linked docs) for a full list:
#   http://www.freedesktop.org/software/systemd/man/systemd.exec.html

[Unit]
Description=No-ip.com dynamic IP address updater
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target
Alias=noip.service

[Service]
# Start main service
ExecStart=/usr/local/bin/noip2
Restart=always
Type=forking
</code></pre>
<p>You can find Nathan's gist <a href="https://gist.github.com/NathanGiesbrecht/da6560f21e55178bcea7fdd9ca2e39b5">here</a>.<br>
(Thank you!!)</p>
<p>Save the file.</p>
<p>Enable the service (This will guarantee that it will restart after reboots.):<br>
<code>$ sudo systemctl enable noip2</code></p>
<p>Start the service:<br>
<code>$ sudo systemctl start noip2</code></p>
<h3 id="verifytheddnsgetsupdated">Verify the DDNS gets updated</h3>
<p>To verify that the DUC is updating the DDNS correctly you can go in the no-ip.com dashboard and verify that the &quot;Last Update&quot; field in <code>Dynamic DNS</code> -&gt; <code>Hostnames</code> changed.</p>
<p>Additionally you can see the status of the service by typing:<br>
<code>$ sudo service noip2 status</code><br>
This will output the last few lines of logs. You should be able to see something like this:</p>
<pre><code>Jun 02 14:12:28 pi systemd[1]: Starting No-ip.com dynamic IP address updater...
Jun 02 14:12:28 pi noip2[833]: v2.1.9 daemon started with NAT enabled
Jun 02 14:12:28 pi systemd[1]: Started No-ip.com dynamic IP address updater.
Jun 02 14:12:28 pi noip2[833]: example.ddns.net was already set to xxx.xxx.xxx.xxx.
</code></pre>
<p>Please note that the update only occurs if the IP changes. If you setup your IP when you created the new hostname it will not update until your IP differs.<br>
Usually I set it to a different IP manually and restart the DUC to validate everything is working fine!</p>
<p>To restart the service type:<br>
<code>$ sudo service noip2 stop</code><br>
<code>$ sudo service noip2 start</code></p>
<p>Now, when we look at the status again, you can see that the IP has been updated.</p>
<pre><code>Jun 02 14:29:11 pi systemd[1]: Starting No-ip.com dynamic IP address updater...
Jun 02 14:29:11 pi noip2[1173]: v2.1.9 daemon started with NAT enabled
Jun 02 14:29:11 pi systemd[1]: Started No-ip.com dynamic IP address updater.
Jun 02 14:29:11 pi noip2[1173]: example.ddns.net set to xxx.xxx.xxx.xxx
</code></pre>
<h3 id="enjoy">Enjoy!</h3>
<p>Hope I saved you some time and headache.<br>
Let me know in the comments if you encounter any issue or have any questions!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Raspbian Stretch/Buster Headless Setup for Raspberry Pi]]></title><description><![CDATA[No keyboard, mouse, display or adapters required!
Works with Raspberry Pi 3 (2 Model B and 1 Model B+), Zero and Zero W.]]></description><link>https://ivancarosati.com/raspbian-stretch-headless-setup-for-raspberry-pi/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a1968</guid><category><![CDATA[Snippets]]></category><category><![CDATA[Raspberry PI]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Thu, 12 Apr 2018 18:01:55 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>No keyboard, mouse, display or adapters required!<br>
Works with Raspberry Pi 4, 3 (2 Model B and 1 Model B+), Zero and Zero W.</p>
<p>I'll walk you through the basic setup to get WiFi and SSH up and running as well as securing your Pi installation.</p>
<h3 id="grocerylist">Grocery List</h3>
<ul>
<li>Raspberry Pi</li>
<li>8Gb+ MicroSD Card</li>
<li>Card Reader</li>
<li>Internet</li>
</ul>
<p>Let's get started.</p>
<h3 id="flashingraspbianstretch">Flashing Raspbian Stretch</h3>
<p>Start by <a href="https://www.raspberrypi.org/downloads/raspbian/">downloading the latest os from Raspbian Lite.</a> Select <code>RASPBIAN STRETCH LITE</code>.<br>
To flash the image we will use <a href="https://etcher.io">Etcher</a>. It's free, well done, and available for all operating systems.</p>
<p>Open Etcher, click &quot;Select image&quot; and select the raspbian <code>.zip</code> you just downloaded. The name will be similar to <code>2017-11-29-raspbian-stretch-lite.zip</code>.<br>
<img src="https://ivancarosati.com/content/images/2018/01/etcher.png" alt><br>
If the SD Card is connected you your computer, it will be selected automatically.<br>
Click &quot;Flash!&quot;, and give it a few minutes and then you're done!</p>
<h3 id="mountthesdcard">Mount the SD Card</h3>
<p>Eject the SD Card from your reader and put it back in.<br>
At this point, you should be able to see a mounted drive called <code>boot</code>.</p>
<h3 id="configurewifioptionalonlyforpi3andzerow">Configure WiFi (Optional, only for Pi 3 and Zero W)</h3>
<p>If you don't want to use WiFi, skip this step. <a href="#disablewifibluetoothifyourenotusingthem">See below on how to disable WiFi and Bluetooth.</a></p>
<p>Now all we have to do to supply WiFi configuration to the Raspberry is to create a file <code>wpa_supplicant.conf</code> in the root of the <code>boot</code> drive.<br>
I like to use <a href="https://atom.io">Atom</a> for this, but any editor will do.</p>
<p>Copy and paste the following:</p>
<pre><code>country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid=&quot;replace_with_your_ssid&quot;
psk=&quot;replace_with_your_password&quot;
key_mgmt=WPA-PSK
}
</code></pre>
<p>Save!</p>
<h3 id="enablessh">Enable SSH</h3>
<p>To enable SSH, create an empty file <code>ssh</code> on the root of the <code>boot</code> drive. (Without dots or extensions.)</p>
<h3 id="thatsit">That's it!</h3>
<p>Eject the SD card and boot up your raspberry pi! You can now SSH using the hostname (raspberrypi.local on mac, raspberrypi on windows).<br>
<code>$ ssh pi@raspberrypi.local</code><br>
The default password is <code>raspberry</code>.<br>
However, if you're using this as anything more than a development device, follow the additional steps below to secure the installation.</p>
<h3 id="disablewifibluetoothifyourenotusingthem">Disable WiFi / Bluetooth (If you're not using them.)</h3>
<p>Open <code>config.txt</code> on the <code>boot</code> drive.<br>
At the end of the file add the following:</p>
<pre><code>dtoverlay=pi3-disable-wifi,pi3-disable-bt
</code></pre>
<p>You can find more options here: <a href="https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README">https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README</a></p>
<h3 id="optimizegpumemorysplitifyourenotusingadisplay">Optimize GPU Memory-Split (If you're not using a display.)</h3>
<p>If you don't use the HDMI or graphical features, you may want to optimize the amount of available memory.<br>
Open <code>config.txt</code> on the <code>boot</code> drive.<br>
At the end of the file add the following:</p>
<pre><code>gpu_mem=16
</code></pre>
<p>16Mb is the minimum that we can force the GPU to use. This will free up at least ~50Mb of available memory.</p>
<h3 id="fixbashwarningsetlocalelc_allcannotchangelocale">FIX: -bash: warning: setlocale: LC_ALL: cannot change locale</h3>
<p>If you see this error after you ssh in, you can install all the locales and it will go away. This will take a few minutes.</p>
<pre><code>-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
</code></pre>
<p>Type <code>$ sudo raspi-config</code> and follow the instructions in the screenshots below. (Choices are highlighted in orange.)<br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.51.37-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.51.43-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.51.48-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.51.54-PM.png" alt><br>
Press okay and let it run until it is done.<br>
UPDATE: If you want, you can install only <code>en_US.UTF-8</code>, that's the one that is needed.</p>
<h3 id="changetimezone">Change timezone</h3>
<p>Type <code>$ sudo raspi-config</code> and follow the instructions in the screenshots below. (Choices are highlighted in orange, the last step if to select your timezone.)<br>
<img src="https://ivancarosati.com/content/images/2019/07/Screen-Shot-2019-07-20-at-9.53.11-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2019/07/Screen-Shot-2019-07-20-at-9.53.15-PM.png" alt><br>
Press okay and we're done!</p>
<h3 id="expandpartitiontouseallavailablespace">Expand partition to use all available space</h3>
<p>When we burn an image into an SD Card, not all the disk space available in the SD Card will be recognized immediately.<br>
To fix this we need to expand the partition.</p>
<p>Type <code>$ sudo raspi-config</code> and follow the instructions in the screenshots below. (Choices are highlighted in orange.)<br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.47.29-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.47.33-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-05-at-7.47.37-PM.png" alt></p>
<p>Verify the disk pace with <code>df -h</code>. Under <code>/dev/root</code> you can see the free space and disk size.</p>
<h3 id="extendingmemory">Extending Memory</h3>
<p>We only have limited memory available and little virtual memory available. Luckily Raspian has <code>dphys-swapfile</code> script to deal with this easily.<br>
To edit I like to use vim <code>$ sudo apt install vim -y</code>, but you can use anything you like.<br>
Type <code>$ sudo vim /etc/dphys-swapfile</code> to edit the file and modify the value to expand the amount of virtual memory to 2Gb. (Or more, based on your needs.)<br>
<code>CONF_SWAPSIZE=2048</code></p>
<p>Save, exit and reboot.<br>
Now that we have virtual memory, let's double check it.<br>
Type <code>$ free</code> and you should see the following.<br>
<img src="https://ivancarosati.com/content/images/2019/07/Screen-Shot-2019-07-22-at-12.03.31-AM.png" alt><br>
You can see the last line, with our 2Gb of swap file!</p>
<h3 id="changedefaulthostname">Change Default Hostname</h3>
<p>Type <code>$ sudo raspi-config</code> and follow the instructions in the screenshots below. (Choices are highlighted in orange.)<br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-07-at-8.45.30-PM.png" alt><br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-07-at-8.45.43-PM.png" alt></p>
<h3 id="changedefaultpassword">Change Default Password</h3>
<p>Type <code>$ sudo raspi-config</code> and follow the instructions in the screenshots below. (Choices are highlighted in orange.)<br>
<img src="https://ivancarosati.com/content/images/2018/01/Screen-Shot-2018-01-07-at-8.47.13-PM.png" alt></p>
<h3 id="disallowpasswordloginsoverssh">Disallow password logins over SSH</h3>
<p>Given enough time (or a weak password) a brute-force attacker could gain access to your Pi. We can make this much harder by disallowing SSH to accept password logins.</p>
<p>To do so, first, generate an <code>ssh-key</code> on your computer.<br>
Run <code>$ ssh-keygen</code>, answer all questions. This will create a private/public key-pair in the directory you specify. On a Mac, I like to keep all of them in <code>/users/my-user/.ssh/your-key-name</code>.</p>
<p>Once the new key is created, we can use <code>ssh-copy-id</code> utility to copy it over to the Pi.<br>
Type <code>$ ssh-copy-id -i ~/.ssh/your-key-name pi@pihostname</code>.</p>
<p>Now let's disable password logins over SSH. Add <code>PasswordAuthentication no</code> to your SSHD config file:<br>
<code>echo &quot;PasswordAuthentication no&quot; | sudo tee -a /etc/ssh/sshd_config</code>.</p>
<p>To speed things up on a MAC, you can edit your <code>~/.ssh/config</code> and add the following:</p>
<pre><code>Host my-pi-name
HostName pihostname.local
User pi
IdentityFile ~/.ssh/your-key-name
ServerAliveInterval 60
</code></pre>
<p>Save. Now, to ssh in, all you have to do is <code>$ ssh my-pi-name</code>!<br>
Reboot your system and check that you can still access the Pi!</p>
<h3 id="configureastaticipaddressoptional">Configure a Static IP Address (Optional)</h3>
<p>It's a good idea to setup a static IP address so you always know where to find your Pi.</p>
<p>Add the following to <code>/etc/dhcpcd.conf</code>:</p>
<pre><code>interface eth0  
static ip_address=192.168.2.200/24  
static routers=192.168.2.1  
static domain_name_servers=192.168.2.1 8.8.8.8
</code></pre>
<p><code>ip_address</code> is the static IP address you want for your Pi.<br>
<code>routers</code> is the IP of the router.<br>
<code>domain_name_servers</code> is the chain that you want for your DNS. The first one is the IP address of your router and the second one is the fallback Google DNS.</p>
<h3 id="screenoptional">Screen (Optional)</h3>
<p>Sometimes, you want to be able to run a long ssh command, be able to close the terminal, and check if the command is done at a later time. To achieve this, we will install screen.</p>
<p>Type <code>$ sudo apt-get install screen</code>.</p>
<p>Once this is done, you can start a screen session with <code>$ screen bash</code>, this will give you a long lived session.<br>
Terminate Session: <code>CTRL + D</code>.<br>
Detach Session: <code>CTRL + A</code> release and then press <code>D</code>.<br>
List All Sessions: <code>$ screen -list</code>.<br>
Reconnect Session: <code>$ screen -r 1245.pts-0.raspberrypi</code>.</p>
<h3 id="systemupdate">System Update</h3>
<p>Let's make sure you're running the latest and the greatest!</p>
<pre><code>$ sudo apt-get update
$ sudo apt-get upgrade
</code></pre>
<h3 id="done">Done!</h3>
<p>This should give you a good starting point to build something amazing! If you have any suggestions, write me or leave a comment below and I will add it in.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Ubuntu 16.04 LTS setup for AWS EC2 micro instance. The fast way. (LEMP Stack)]]></title><description><![CDATA[I've recently grown tired of using Amazon Linux AMI for my servers as you can never quite replicate the same development environment.

So.. here we are! 
LEMP stack for the Ubuntu 16.04 LTS with PHP 7. Woot!]]></description><link>https://ivancarosati.com/ubuntu-16-04-lts-setup-for-ec2/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a1963</guid><category><![CDATA[AWS]]></category><category><![CDATA[EC2]]></category><category><![CDATA[Snippets]]></category><category><![CDATA[Ubuntu 16.04 LTS]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Mon, 24 Oct 2016 04:30:19 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I've recently grown tired of using Amazon Linux AMI for my servers as you can never quite replicate the same development environment.</p>
<p>So.. here we are!<br>
LEMP stack for the Ubuntu 16.04 LTS with PHP 7. Woot!</p>
<p>If you need to start up a new instance, take a look at <a href="https://ivancarosati.com/your-first-aws-ec2-instance/">my previous post.</a> The only difference there would be to select Ubuntu OS instead of Amazon Linux AMI.<br>
I'm assuming you're already ssh-ed into your instance, so.. Let's go!</p>
<p><strong>Welcome Screen</strong><br>
As a welcome screen you see this unsettling message:</p>
<pre><code>WARNING! Your environment specifies an invalid locale.
 The unknown environment variables are:
   LC_CTYPE=en_CA.UTF-8 LC_ALL=
 This can affect your user experience significantly, including the
 ability to manage packages. You may install the locales by running:

   sudo apt-get install language-pack-en
     or
   sudo locale-gen en_CA.UTF-8

To see all available language packs, run:
   apt-cache search &quot;^language-pack-[a-z][a-z]$&quot;
To disable this message for all users, run:
   sudo touch /var/lib/cloud/instance/locale-check.skip
</code></pre>
<p>Don't panic! Just type <code>$ sudo apt-get install language-pack-en</code> to install the missing locale files.</p>
<p>First, let's make sure you have all the latest goodness.<br>
<code>$ sudo apt-get update</code><br>
<code>$ sudo apt-get upgrade</code></p>
<p>This process will take a minute or two. If you want to see what's gonna be upgraded, you can run <code>$ sudo apt-get list --upgradable</code> at any time to get a list.</p>
<p><strong>SWAP FILE</strong><br>
We only have 1 GB of memory available and no virtual memory to extend it. That alone is a major cause of server crashes and hangups. Simply creating a swap file is a well-known, effective micro instance tweak.<br>
Create and activate a 2 GB swap file with the following:<br>
<code>$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048</code><br>
<code>$ sudo mkswap /swapfile</code><br>
<code>$ sudo chmod 0600 /swapfile</code><br>
<code>$ sudo swapon /swapfile</code><br>
We generate the file with <code>dd</code>, make a swap filesystem with <code>mkswap</code>, set proper permissions with <code>chmod</code>, and mount it with <code>swapon</code>.</p>
<p>Our system is using the swap file for this session. To mount the volume at boot, we need to modify a system file. You can do this by typing:<br>
<code>$ sudo sh -c 'echo &quot;/swapfile none swap sw 0 0&quot; &gt;&gt; /etc/fstab'</code></p>
<p>Now that we have virtual memory, let's give it a double check.<br>
Type <code>$ free</code> and you should see the following.<br>
<img src="https://ivancarosati.com/content/images/2016/10/ubuntu-swap.png" alt><br>
You can see the last line, with our 2Gb of swap file!</p>
<p><strong>NGINX and PHP</strong><br>
<code>sudo atp install build-essential libssl-dev</code><br>
<code>sudo apt install nginx php-cli php-fpm php-mysqlnd php-mcrypt php-mbstring php-curl php-xdebug phpunit</code></p>
<p>Let's enable the module we just installed.<br>
<code>sudo phpenmod mcrypt</code><br>
<code>sudo phpenmod mbstring</code><br>
<code>sudo phpenmod curl</code></p>
<p>Before we can test Nginx, we need to configure our firewall to allow access to the service. You can check the configuration of the firewall at anytime typing <code>$ sudo ufw app list</code>. Pretty awesome!</p>
<p>Open up only the ports that you will need.<br>
<code>$ sudo ufw allow 'Nginx HTTP'</code> — Port 80.<br>
<code>$ sudo ufw allow 'Nginx HTTPS'</code> — Port 443.</p>
<p>Because we're running Nginx in a micro instance we need to look out for resources usage. Let's put in a few parameters to optimize it.<br>
<code>$ sudo vim /etc/php/7.0/fpm/php-fpm.conf</code></p>
<p>Paste these few lines at the end of the file:</p>
<pre><code>[global]
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s

[www]
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 200

php_admin_value[memory_limit] = 64M
</code></pre>
<p>We need to make a slight configuration change to make our setup more secure. In the main php-fpm configuration file, the standard setting for <code>cgi.fix_pathinfo</code> is set to <code>1</code>. This is extremely insecure because it tells PHP to attempt to execute the closest file it can find if the requested PHP file cannot be found. This would allow users to craft PHP requests in a way that would allow them to execute scripts that they shouldn't be allowed to execute.</p>
<p>To rectify that, type:<br>
<code>$ sudo sed -i &quot;s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/&quot; /etc/php/7.0/fpm/php.ini</code>.</p>
<p>Another best practice I suggest to remove servers tokens. This will prevent Nginx from outputting information about your current installation, version numbers, etc.<br>
To achieve this:<br>
<code>$ sudo vim /etc/nginx/nginx.conf</code><br>
Uncomment <code>server_tokens off;</code> and save.</p>
<p>Nginx by default is setup to work with the group <code>www-data</code>. We need to set the proper permission schema so that our <code>www-data</code> user will have write permissions without owning the files.<br>
Do do this we can type:<br>
<code>$ sudo usermod -a -G www-data ubuntu</code><br>
<code>$ exit</code> - this will terminate your ssh session. Ssh in again and type,<br>
<code>$ groups</code> to verify that the new <code>www-data</code> group has been added to your the <code>ubuntu</code> user.</p>
<p>It's time to set our default permissions on the <code>/var/www</code> folder where we will put our projects.<br>
Set write permissions to <code>/var/www</code> for <code>www-data</code> group.<br>
<code>$ sudo chown -R www-data:www-data /var/www</code></p>
<p>We need to change the web root directory permissions so that the <code>www</code> group has write permissions:<br>
<code>$ sudo chmod 2775 /var/www</code><br>
We also need to set the same permissions for any future subdirectories:<br>
<code>$ find /var/www -type d -exec sudo chmod 2775 {} +</code><br>
Then we do the same for files within those directories and subdirectories:<br>
<code>$ find /var/www -type f -exec sudo chmod 0664 {} +</code></p>
<p>Now we're good to configure our website and the location where your project will be. Feel free to customize this part with your own domain and project name.<br>
<code>$ sudo mkdir /etc/nginx/sites-enabled</code><br>
<code>$ sudo vim /etc/nginx/sites-enabled/example.com</code></p>
<pre><code class="language-nginx">server {
    listen 80;
    server_name example.com;

    root /var/www/example/public;
    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log /var/log/nginx/example.com_access.log;
    error_log /var/log/nginx/example.com_error.log;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }
}

server {
    listen 80;
    server_name www.example.com;

    return 301 http://example.com$request_uri;
}
</code></pre>
<p>Before we start our services, we need to create our project folder.<br>
<code>$ sudo mkdir -p /var/www/example</code></p>
<p>To test things out, let's put a piece of php in it.<br>
<code>$ cd /var/www/example</code><br>
<code>$ sudo mkdir public</code><br>
<code>$ cd public</code><br>
<code>$ sudo vim index.php</code></p>
<p>Copy and paste the following.</p>
<pre><code class="language-php">&lt;?php
  echo 'Hello Human!';
</code></pre>
<p>Save the file and exit.</p>
<p>Let's restart Nginx to apply the changes we just made.<br>
<code>$ sudo systemctl restart nginx</code></p>
<p>If you want to run a quick test, you can type in <a href="http://your-public-ip-address">http://your-public-ip-address</a> in your browser and you should see:<br>
<img src="https://ivancarosati.com/content/images/2016/02/Server-Test.png" alt="server-test"><br>
<em>Take a moment, to congratulate yourself!</em></p>
<p><strong>MYSQL</strong><br>
Install MySql server with:<br>
<code>$ sudo apt-get install mysql-server</code></p>
<p>To secure your database installation type:<br>
<code>$ sudo mysql_secure_installation</code><br>
Set a root password and accept the remaining steps.<br>
Consider your need for remote access. If you need it, say <em>no</em> when asked: &quot;<em>Disallow root login remotely?</em>&quot;.</p>
<p><strong>Enjoy your new server!</strong></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Amazon Linux AMI setup for AWS EC2 micro instance. The fast way. (LEMP Stack, PHP 7.3, MySql 5.7)]]></title><description><![CDATA[After a few years of using EC2 boxes for development and production, this has become my routine setup for micro and small instances.]]></description><link>https://ivancarosati.com/amazon-linux-ami-setup-ec2/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a195c</guid><category><![CDATA[AWS]]></category><category><![CDATA[EC2]]></category><category><![CDATA[Snippets]]></category><category><![CDATA[Amazon Linux AMI]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Sun, 13 Mar 2016 21:01:57 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>After a few years of using EC2 boxes for development and production, this has become my routine setup for micro and small instances.<br>
If you need to start up a new instance, take a look at <a href="https://ivancarosati.com/your-first-aws-ec2-instance/">my previous post.</a><br>
I'm assuming you're already ssh-ed into your instance, so.. Let's go!</p>
<p>Let's make sure you have all the latest goodness.<br>
Running the update with <code>--changelog</code> will allow you to keep track of what's changing.<br>
<code>$ sudo yum install yum-plugin-changelog</code><br>
<code>$ sudo yum update --changelog</code></p>
<p><strong>SWAP FILE</strong><br>
We only have 1 GB of memory available and no virtual memory to extend it. That alone is a major cause of server crashes and hangups. Simply creating a swap file is a well-known, effective micro instance tweak.<br>
Create and activate a 2 GB swap file with the following:<br>
<code>$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048</code><br>
<code>$ sudo mkswap /swapfile</code><br>
<code>$ sudo chmod 0600 /swapfile</code><br>
<code>$ sudo swapon /swapfile</code><br>
We generate the file with <code>dd</code>, make a swap filesystem with <code>mkswap</code>, set proper permissions with <code>chmod</code>, and mount it with <code>swapon</code>.</p>
<p>Add the following line to /etc/fstab to make it persist over reboot:<br>
<code>$ sudo vim /etc/fstab</code></p>
<pre><code class="language-bash">/swapfile swap swap defaults 0 0
</code></pre>
<p>Feel free to use any other editor than VIM.<br>
However VIM is very simple. Press <code>i</code> to be able to insert/paste text. <code>esc</code> to exit a mode, <code>:x</code> to save and quit.</p>
<p>Now that we have virtual memory, let's double check it.<br>
Type <code>$ free</code> and you should see the following.<br>
<img src="https://ivancarosati.com/content/images/2016/02/Free-SwapServer.png" alt="Free-SwapServer"><br>
You can see the last line, with our 2Gb of swap file!</p>
<p><strong>NGINX and PHP</strong><br>
<code>$ sudo amazon-linux-extras enable php7.3 nginx1.12</code></p>
<p><code>$ sudo yum install nginx php-cli php-pdo php-fpm php-json php-odbc php-soap php-mbstring php-bcmath php-ldap php-gd php-mcrypt php-mysqlnd</code></p>
<p>PHP-FPM configuration. (FastCGI Process Manager)<br>
Add the following to the end of /etc/php-fpm.d/www.conf:<br>
<code>$ sudo vim /etc/php-fpm.d/www.conf</code></p>
<p>Look for this line (towards the beginning) <code>listen.acl_users = apache,nginx</code> and put a semicolon in front of it, like the following: <code>;listen.acl_users = apache,nginx</code>.<br>
Now scroll to the end of the file and copy and paste this configuration:</p>
<pre><code class="language-bash">[global]
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s

[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = www
listen.mode = 0664
user = nginx
group = www

pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 200

php_admin_value[memory_limit] = 256M
</code></pre>
<p>Nginx is setup to work with the group <code>www</code>. We need to create the group and set the proper permission schema.<br>
Type in <code>$ groups</code> and verify that <code>www</code> doesn't already exist.</p>
<p>We can easily add it with the following commands.<br>
<code>$ sudo groupadd www</code><br>
<code>$ sudo usermod -a -G www ec2-user</code><br>
<code>$ exit</code> - this will terminate your ssh session. Ssh in again and type,<br>
<code>$ groups</code> to verify that the new <code>www</code> group has been added.</p>
<p>Let's create our <code>www</code> directory.<br>
<code>$ sudo mkdir /var/www</code><br>
Set write permissions to <code>/var/www</code> for <code>www</code> group.<br>
<code>$ sudo chown -R root:www /var/www</code></p>
<p>We need to change the web root directory permissions so that the <code>www</code> group has write permissions:<br>
<code>$ sudo chmod 2775 /var/www</code></p>
<p>We also need to set the same permissions for any future subdirectories:<br>
<code>$ find /var/www -type d -exec sudo chmod 2775 {} +</code></p>
<p>Then we do the same for files within those directories and subdirectories:<br>
<code>$ find /var/www -type f -exec sudo chmod 0664 {} +</code></p>
<p>Now we're good to configure your website and the location where your project will be. Feel free to customize this part with your own domain and project name.<br>
<code>$ sudo mkdir /etc/nginx/sites-enabled</code><br>
<code>$ sudo vim /etc/nginx/sites-enabled/example.com.conf</code></p>
<pre><code class="language-nginx">server {
    listen 80;
    server_name example.com;

    root /var/www/example/public;
    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log /var/log/nginx/example.com_access.log;
    error_log /var/log/nginx/example.com_error.log;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    location ~ /\.ht {
        deny all;
    }
}

server {
    listen 80;
    server_name www.example.com;

    return 301 http://example.com$request_uri;
}
</code></pre>
<p>To allow us to manage multiple domain or subdomain on the same server, we need to tell Nginx to load all the files under sites-enabled folder.<br>
To do so, type:<br>
<code>$ sudo vim /etc/nginx/nginx.conf</code><br>
After <code>include /etc/nginx/conf.d/*.conf;</code> add:<br>
<code>include /etc/nginx/sites-enabled/*.conf;</code><br>
and save.</p>
<p>Before we start our services, we need to create our project folder.<br>
<code>$ sudo mkdir -p /var/www/example</code></p>
<p>To test things out, let's put a piece of php in it.<br>
<code>$ cd /var/www/example</code><br>
<code>$ sudo mkdir public</code><br>
<code>$ cd public</code><br>
<code>$ sudo vim index.php</code></p>
<p>Copy and paste the following.</p>
<pre><code class="language-php">&lt;?php
  echo 'Hello Human!';
</code></pre>
<p>Comment out the section as shown, we're gonna disable the default &quot;Welcome to NGINX&quot; screen.</p>
<pre><code>#    server {
#        listen       80 default_server;
#        listen       [::]:80 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;

#        location / {
#        }

#        error_page 404 /404.html;
#            location = /40x.html {
#        }

#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
</code></pre>
<p>Save the file and exit.</p>
<p>Now let's start the engines!<br>
<code>$ sudo chkconfig nginx on</code> — Set autostart.<br>
<code>$ sudo chkconfig php-fpm on</code> — Set autostart.<br>
<code>$ sudo service nginx start</code><br>
<code>$ sudo service php-fpm start</code></p>
<p>If you want to run a quick test, you can type in <a href="http://your-public-ip-address">http://your-public-ip-address</a> in your browser and you should see:<br>
<img src="https://ivancarosati.com/content/images/2016/02/Server-Test.png" alt="server-test"><br>
<em>Take a moment, to congratulate yourself!</em></p>
<p><strong>MYSQL</strong><br>
Install MySql server with:<br>
<code>$ sudo yum install mariadb-server</code></p>
<p>Like before, start it up with:<br>
<code>$ sudo chkconfig mysqld on</code> — Set autostart.<br>
<code>$ sudo service mysqld start</code></p>
<p>To secure your database installation type:<br>
<code>$ sudo mysql_secure_installation</code><br>
Set a root password and accept the remaining steps.<br>
Consider your need for remote access. If you need it, say <em>no</em> when asked: &quot;<em>Disallow root login remotely?</em>&quot;.</p>
<p><strong>Enjoy your new server!</strong></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Your first AWS EC2 micro instance.]]></title><description><![CDATA[So, you want to get started with Amazon Elastic Compute Cloud (Amazon EC2)?
Let's get to it.]]></description><link>https://ivancarosati.com/your-first-aws-ec2-instance/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a195b</guid><category><![CDATA[AWS]]></category><category><![CDATA[EC2]]></category><category><![CDATA[Snippets]]></category><category><![CDATA[Amazon Linux AMI]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Mon, 01 Feb 2016 00:20:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>So, you want to get started with Amazon Elastic Compute Cloud (Amazon EC2)?<br>
Let's get to it.</p>
<p><a href="https://console.aws.amazon.com/console/home">Sign in</a> or if you don't have a AWS account you can create one <a href="https://console.aws.amazon.com/console/home">here</a>.<br>
<img src="https://ivancarosati.com/content/images/2016/01/1-1.png" alt><br>
Click on &quot;Launch Instance&quot;.<br>
<img src="https://ivancarosati.com/content/images/2016/01/2.png" alt><br>
Select Amazon Linux 2 AMI (HVM) instance type. This is a good choice as it is designed by Amazon specifically for use on EC2.<br>
<img src="https://ivancarosati.com/content/images/2016/01/3.png" alt><br>
Select <strong>t2.micro</strong> &quot;Free Tire&quot; instance, click on &quot;Review and Launch&quot;.<br>
<img src="https://ivancarosati.com/content/images/2016/01/4.png" alt><br>
Scroll down and click on &quot;Edit security groups&quot;<br>
<img src="https://ivancarosati.com/content/images/2016/01/5.png" alt><br>
Make sure you add HTTP rule to the group like is shown on the screenshot. Source <code>0.0.0/0</code> means you are accepting connections from any IP address.<br>
<img src="https://ivancarosati.com/content/images/2016/01/6.png" alt><br>
Scroll down and review the storage type. I recommend SSD with at least 10Gb. I'll go for 20Gb. HDD space is really cheap. (General Purpose SSD is about $0.10 per GB-month of provisioned storage.)<br>
<img src="https://ivancarosati.com/content/images/2016/01/7.png" alt><br>
Make sure to review all the settings and hit &quot;Launch&quot;.<br>
<img src="https://ivancarosati.com/content/images/2016/01/8.png" alt><br>
You'll be prompted to create a new key to connect to the server through SSH. Select &quot;Create a new key pair&quot; and insert the name of the key. Use any name you like. Hit &quot;Download Key Pair&quot; and your key will be downloaded. Make sure to back it up. If you lose it, you won't be able to connect to your server. You've been warned!<br>
Now click on &quot;Launch Instances&quot;.<br>
<img src="https://ivancarosati.com/content/images/2016/01/9.png" alt><br>
You're server is spinning up, take a moment to congratulate yourself!<br>
<img src="https://ivancarosati.com/content/images/2016/01/10.png" alt><br>
Now you need to assign an elastic IP to your instance. This ensures that if something happen to the instance, you can easily swap servers and retain the IP. Elastic IPs are re-assignable.<br>
Click on &quot;Allocate New Address&quot;.<br>
<img src="https://ivancarosati.com/content/images/2016/01/11.png" alt><br>
Select the elastic IP, click on &quot;Actions&quot; and &quot;Associate Address&quot;.<br>
<img src="https://ivancarosati.com/content/images/2016/01/12.png" alt><br>
Select your instance name and click &quot;Associate&quot;. This will be your IP address from now on. Also the previous public IP address will be released.<br>
<img src="https://ivancarosati.com/content/images/2016/01/13.png" alt><br>
That's it. If you go on the Dashboard you'll see your instance getting ready.</p>
<p>Let's configure your computer to connect to the new server when it's ready.</p>
<p>On a <em>Windows</em> you can <a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html">click here</a> and follow the guide ;)<br>
On a <em>Mac</em> you can follow those steps. Make sure you have <a href="http://www.sublimetext.com/3">Sublime Text</a> installed.</p>
<p>Copy the key file to your desktop, then rename <code>key.pem.txt</code> to <code>key.pem</code>.<br>
Open up the terminal and run:<br>
<code>$ cd desktop</code><br>
<code>$ cp key.pem ~/.ssh</code><br>
<code>$ chmod 400 ~/.ssh/key.pem</code></p>
<p>The last command makes sure your private key is protected by assigning the right permissions to it.</p>
<p>Now, with Sublime Text, open <code>~/.ssh/config</code>. If you don't see hidden files you can use the shortcut <strong>⌘ + ⇧ + .</strong> to show them in the <em>open window</em>.</p>
<p>Add this configuration and save.</p>
<pre><code class="language-bash">Host name-server
HostName 000.000.000.000
User ec2-user
IdentityFile ~/.ssh/key.pem
ServerAliveInterval 60
</code></pre>
<p>Now you can open the terminal and type <code>$ ssh name-server</code>. The first time you will be asked to accept a new fingerprint from a new machine, type yes.<br>
Congratulations! You're now logged to your server!!</p>
<p>A little explanation of the configuration:<br>
<em>Host</em> is the name the you want to use to ssh into your server.<br>
<em>HostName</em> is the IP address.<br>
<em>User</em> is always ec2-user by default.<br>
<em>IdentityFile</em> is the path to your private key.<br>
<em>ServerAliveInterval</em> keeps the connection alive while you're not using it. Even though this is not necessary, when you're connected to your servers it allows you to keep the connection open indefinitely. Without it, the connection will timeout.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Rdio Exporter]]></title><description><![CDATA[If you're reading this, you've probably heard the news. Rdio has been acquired by Pandora. It will shut down in a few weeks.
As an Rdio user and totally in love with this beautifully crafted streaming service, I felt obligated to do something about it.]]></description><link>https://ivancarosati.com/rdio-exporter/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a195f</guid><category><![CDATA[Projects]]></category><category><![CDATA[Tools]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Wed, 16 Dec 2015 20:32:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><strong>UPDATE: Rdio API has now been shut down.<br>
Thank you all for stopping by and we hope we've given a helping hand for your music's smooth sailing.</strong></p>
<p>If you're reading this, you've probably heard the news. Rdio has been acquired by Pandora. It will shut down in a few weeks.<br>
As an Rdio user and totally in love with this beautifully crafted streaming service, I felt obligated to do something about it. Also, I always wanted to <em>play</em> with the Rdio API but never had the <em>right</em> motive.</p>
<p>I started building an Rdio exporter after I first heard the news because I wanted to be able to export <em>all</em> my data while waiting to see what Rdio would come up with. Also I wanted to make sure that it was gonna be formatted not only readable by a machine, but also by me. You know.. just in case I decided to reimport all my music manually to Spotify!<br>
It took a while to get it ready for prime time.</p>
<p>A big thanks you goes to <a href="http://www.daniellesannuto.com">Danielle</a> that came up with design and user flow!</p>
<p><a href="http://rdio.ivancarosati.com">So.... here it is! — rdio.ivancarosati.com</a></p>
<p>This tool allow you to sign in with your Rdio account and export your entire collection, playlists and anything you've ever favourited. You can chooce to export in <em>.csv</em> or <em>.xlsx</em>. If you're looking to keep a reference for you of your music, .xlsx is gonna be better. Once your data is ready, I'll email you a <em>.zip</em> file with everything in it.<br>
<a href="https://ivancarosati.s3.amazonaws.com/rdio/rdio-s3297746-1450802377.zip">Click here for an example! Yes, that's my Rdio account..</a></p>
<p><em>You can see how it works below.</em><br>
<a href="https://ivancarosati.com/content/images/2015/12/1.jpg"><img src="https://ivancarosati.com/content/images/2015/12/1.jpg" alt></a><br>
<a href="https://ivancarosati.com/content/images/2015/12/2.jpg"><img src="https://ivancarosati.com/content/images/2015/12/2.jpg" alt></a><br>
<a href="https://ivancarosati.com/content/images/2015/12/3.jpg"><img src="https://ivancarosati.com/content/images/2015/12/3.jpg" alt></a><br>
<a href="https://ivancarosati.com/content/images/2015/12/4.jpg"><img src="https://ivancarosati.com/content/images/2015/12/4.jpg" alt></a><br>
<a href="https://ivancarosati.com/content/images/2015/12/5.jpg"><img src="https://ivancarosati.com/content/images/2015/12/5.jpg" alt></a><br>
<a href="https://ivancarosati.com/content/images/2015/12/6.png"><img src="https://ivancarosati.com/content/images/2015/12/6.png" alt></a></p>
<p>I would love for you to use it and let me know what you think. If you have any question shoot me a <a href="https://twitter.com/pokono">tweet</a> or comment below.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Can't find Arduino DUE in board list?]]></title><description><![CDATA[Here's how to fix it!]]></description><link>https://ivancarosati.com/cant-find-arduino-due-in-board-list/</link><guid isPermaLink="false">5c4e3ffc15f5bb227a4a195d</guid><category><![CDATA[Arduino]]></category><dc:creator><![CDATA[Ivan Carosati]]></dc:creator><pubDate>Wed, 11 Nov 2015 23:32:03 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>So, your Arduino DUE just came in the mail.<br>
You're all excited, you unpack it and connect it to your USB, Open the <a href="https://www.arduino.cc/en/Main/Software">Arduino IDE</a> and you go to <strong>Tools → Board</strong>.<br>
Nothing!<br>
The Arduino DUE is missing from the list.</p>
<p><img src="https://ivancarosati.com/content/images/2015/09/arduino-boards-list.png" alt="arduino-tools-board"><br>
Here's how you install the software for the Arduino DUE.</p>
<p><strong>Tools → Board → Boards Manager...</strong><br>
Type <mark>Arduino SAM</mark> in the search box.<br>
<img src="https://ivancarosati.com/content/images/2015/09/Screen-Shot-2015-09-22-at-12-33-29-AM.png" alt="arduino-tools-board-search"><br>
Click on the <mark>Arduino SAM Boards (32-bits ARM Cortex-M3)</mark> and hit install. It may take a while, you'll need to download ~50Mb.<br>
<img src="https://ivancarosati.com/content/images/2015/09/Screen-Shot-2015-09-22-at-12-33-33-AM.png" alt="arduino-tools-board-install"><br>
Once it's done, you'll see that package as installed. Good!<br>
<img src="https://ivancarosati.com/content/images/2015/09/Screen-Shot-2015-09-22-at-12-34-40-AM.png" alt="arduino-tools-board-installed"><br>
Now go back to <strong>Tools → Board</strong> and you'll see Arduino DUE listed at the bottom. Select it and you're done!<br>
<img src="https://ivancarosati.com/content/images/2015/09/Screen-Shot-2015-09-22-at-12-34-51-AM.png" alt="arduino-tools-board-arduino-due"></p>
<h3 id="letsmakealedblinknoextrahardwarenecessary">Let's make a LED blink! (no extra hardware necessary)</h3>
<p>Make sure you've connected the Arduino DUE to the port labeled PROGRAMMING port at the bottom of the board.<br>
Select the correct Port in <strong>Tools → Port</strong>  as shown below.<br>
<img src="https://ivancarosati.com/content/images/2015/09/Screen-Shot-2015-09-22-at-1-12-17-AM.png" alt="arduino-tools-port-arduino-due"></p>
<p>Arduino DUE comes with an on-board LED that you can control on the digital pin 13. Let's use it!<br>
Copy and paste the following code into the IDE.</p>
<pre><code class="language-c">// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);              // wait for 0.2 second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(200);              // wait for 0.2 second
}
</code></pre>
<p>Hit the upload button and let it upload.<br>
<img src="https://ivancarosati.com/content/images/2015/09/Screen-Shot-2015-09-22-at-1-17-06-AM.png" alt="arduino-ide-blink-code"></p>
<p><img src="https://ivancarosati.com/content/images/2015/09/arduino-due-blink-small.gif" alt="arduino-due-blink"></p>
<p>Awesome!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>