<?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: Henrique A. Lavezzo</title>
    <description>The latest articles on DEV Community by Henrique A. Lavezzo (@rynaro).</description>
    <link>https://dev.to/rynaro</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%2F120869%2F17a5ac2f-be0e-4d4e-b628-ef3fffbfb31a.jpeg</url>
      <title>DEV Community: Henrique A. Lavezzo</title>
      <link>https://dev.to/rynaro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rynaro"/>
    <language>en</language>
    <item>
      <title>First voyage of a Rubist into Clojure</title>
      <dc:creator>Henrique A. Lavezzo</dc:creator>
      <pubDate>Tue, 14 Jan 2020 01:47:18 +0000</pubDate>
      <link>https://dev.to/rynaro/first-voyage-of-rubist-into-clojure-j94</link>
      <guid>https://dev.to/rynaro/first-voyage-of-rubist-into-clojure-j94</guid>
      <description>&lt;p&gt;Few days ago, I've decided to learn something new. But, not a new framework in a known language, in my safety zone. I wanted something, a new flame to expurge the ashes of daily issues that were consuming my motivation one month per time.&lt;/p&gt;

&lt;p&gt;Then I have tried some languages, some tools, more than one time. I could list all techs that I've tried, but that not the focus of this post. And the fire was unexpected lit, after few minutes reading about Clojure. I felt the exact same feeling when I was tried Ruby by myself for the first time. That's was a clearly match!&lt;/p&gt;

&lt;p&gt;My study flow is always evolving, and under strict adaptation. For Clojure studies, I've read a lot about language and functional paradigm. Write few random codes on &lt;code&gt;lein repl&lt;/code&gt;, to train some basics of language. And after this read more about language.&lt;/p&gt;

&lt;p&gt;After 3 days, I felt really confortable with language. And I would like to go deep, and try to build things on Clojure. That's right, I could write some codes from exercises list, but I always felt supressed when I face a list of exercises, and I subconsiously refuses to follow the exercises. (In fact, I had some problems in school classes with this kind of activities. Sometimes I was labelled "lazy student with good grades.")&lt;/p&gt;

&lt;p&gt;Ok, list of exercises was out of options. On Ruby I really like to write granular code, and I have several "in company" private gems, and some public gems. And in Clojure we have clojars, the idea raises up. Let's build a clojar.&lt;/p&gt;

&lt;p&gt;Recently I've a demand on Ruby code, to handle a realtime zipcode validation (we call CEP in Brazil), for boleto generation. (We'll stop here about the demand, thats other topic, we can talk about it in other post. Who knows? 😬 )&lt;/p&gt;

&lt;p&gt;That's perfect, the idea was fresh in my brain. And the target service for consumption has a little outdated documentation. Then I will use this as point to research.&lt;/p&gt;

&lt;p&gt;I've go into service sources, and tests, to learn and get new brand resources to insert into my clojar. I've tested all endpoints, and it's all clear, working perfectly. (At this point, I really in debt with this project. I'm perfect able to update the documentation. I've put in my TODO list)&lt;/p&gt;

&lt;p&gt;The service return the REST pattern, an 200 code with body when data cames from API. And a 404 code when API does not returns nothing. When I receives a 200, its easy to return a map with contents to user, with &lt;code&gt;cheshire&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Note: When you call &lt;code&gt;parse-string&lt;/code&gt;, to convert the json into map, all keys cames as string too. If you want to get symbol-like in clojure. You need to fill a argument/parameter with &lt;code&gt;true&lt;/code&gt;. I really don't like it. Does not sound idiomatic.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But when you get a 404 from service, &lt;code&gt;clj-http&lt;/code&gt; raises a exception. The odds is always with us, we can perfectly handle this problem with &lt;code&gt;slingshot&lt;/code&gt;, creating a custom catch for 404 code. I really like to throw exceptions, it's more than a error for me. We can express unexpected behaviors, and handle with a situation without a cascade of conditionals (Let the destiny defines what you do).&lt;br&gt;
And I choose to throw an custom exception for user, but more idiomatic. (&lt;code&gt;:type ::nothing-returned&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Alongside this code flow, I built the tests, for sure. And I really like the &lt;code&gt;clojure.test&lt;/code&gt;, it's simple and get the job done. One of the points what I really like, is the use of &lt;code&gt;with-redefs&lt;/code&gt;. I could do mock all &lt;code&gt;clj-http&lt;/code&gt; client requests, and set responses without problem, and everything is core builted in language. And I write tests to cover all critical points of the simple "clojar".&lt;/p&gt;

&lt;p&gt;It's done! Tests covering the code. And I think, it's simple to use, and the source code is simple, and easier to maintain too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's deploy on &lt;a href="https://clojars.org/"&gt;Clojars&lt;/a&gt; !
&lt;/h3&gt;

&lt;p&gt;I needed to create an account, just like rubygems. And after some few adjustments on &lt;code&gt;project.clj&lt;/code&gt;, I was able to deploy the lib.&lt;/p&gt;

&lt;p&gt;Just executing &lt;code&gt;lein deploy clojars&lt;/code&gt;. It's dead simple, like the website  says. After some seconds, I get my clojar badge, and updates the README on GitHub.&lt;/p&gt;

&lt;p&gt;After this, I built a simple Travis workflow, to test the code under &lt;code&gt;openjdk-8&lt;/code&gt; and &lt;code&gt;openjdk-11&lt;/code&gt; at every commit on &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I found in Clojure a new way to think, and build things. I fell in my Ruby codes today, a huge influence of Clojure way to handle things. And I really like it.&lt;/p&gt;

&lt;p&gt;If you have interest to see my "lib", here's url &lt;a href="https://github.com/Rynaro/postmon-clj"&gt;https://github.com/Rynaro/postmon-clj&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! 🎉&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>clojure</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Setup simple SFTP server in minutes</title>
      <dc:creator>Henrique A. Lavezzo</dc:creator>
      <pubDate>Thu, 12 Dec 2019 22:18:48 +0000</pubDate>
      <link>https://dev.to/rynaro/setup-simple-sftp-server-in-minutes-1p20</link>
      <guid>https://dev.to/rynaro/setup-simple-sftp-server-in-minutes-1p20</guid>
      <description>&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;One of most common ways to share files between companies is still FTP servers. And sometimes, you need to setup a FTP in-house, whether out compliance control, security, cost, or 'cause its simple enough to do it yourself.&lt;/p&gt;

&lt;p&gt;I've one FTP server in company that I work. It's a simple FTP server, developed with Python, using &lt;code&gt;pyftpdlib&lt;/code&gt; package, and aws S3 integration. We have a hook action, that send file into a folder mirror named bucket, to secure files, and after 15 days, we made a server FS clean, to guarantee healthy disk space level.&lt;/p&gt;

&lt;p&gt;But recently, we get a specific trait from new partner, we need to expose an sftp server. In a quick search, &lt;code&gt;pyftpdlib&lt;/code&gt; does not support sftp protocol. After this, I go to aws services, to see how much cost the use of &lt;strong&gt;AWS Transfer&lt;/strong&gt;. It's easy to use service, but expensive for a small startup, and I don't think we need an entire service for this. In other situation, our monthly invoice will be affected by third-party factor, and one mistake made by our partner, could increase the invoice numbers.&lt;/p&gt;

&lt;p&gt;Given the above factors, I decided to build a simple sftp from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  DIY Setup
&lt;/h2&gt;

&lt;p&gt;First of all, you'll need a server instance. In this case, I've used a DigitalOcean Droplet. My decision was driven by low-cost purposes.&lt;/p&gt;

&lt;p&gt;I like Ubuntu server instances, and this "paper" uses the assumption the server is a Ubuntu server.&lt;/p&gt;

&lt;h4&gt;
  
  
  Packages
&lt;/h4&gt;

&lt;p&gt;Make sure, your instance is updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# apt update &amp;amp;&amp;amp; apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install vim, &lt;del&gt;or use nano&lt;/del&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# apt install vim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create user
&lt;/h4&gt;

&lt;p&gt;You'll need to create a user, for your third-party user. We'll call our friend, as &lt;strong&gt;partner&lt;/strong&gt; here. Say hello to &lt;strong&gt;Partner&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# adduser --shell /bin/false partner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can allow your Linux, to create home folders. But actually, I like to stay in front of situation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create user folder
&lt;/h4&gt;

&lt;p&gt;If you allowed &lt;code&gt;adduser&lt;/code&gt; to create home folders, then you don't need to create a permitted folder space.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# mkdir -p /var/sftp/partner/files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to guarantee permissions to &lt;strong&gt;Partner&lt;/strong&gt; in your &lt;em&gt;home sweet home&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# chown partner:partner /var/sftp/partner
# chmod 755 /var/sftp/partner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  SFTP access restrictions
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Partner&lt;/strong&gt; is a common user inside our server. And without other (recommended) security rules, &lt;strong&gt;Partner&lt;/strong&gt; will be able to make an ssh connection. And we don't want this.&lt;/p&gt;

&lt;p&gt;We'll create a rule at end of file of &lt;code&gt;sshd_config&lt;/code&gt;, for sftp only restriction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# vim /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Match User partner
    ForceCommand internal-sftp
    PasswordAuthentication yes
    ChrootDirectory /var/sftp/partner
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Restart SSH Service
&lt;/h4&gt;

&lt;p&gt;After configure &lt;strong&gt;Partner&lt;/strong&gt; restriction, you'll need to restart SSH service to make sure changes take effect on server.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can be disconnected after this. Just reconnect.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Create password
&lt;/h4&gt;

&lt;p&gt;Create a password for partner if didn’t create one yet.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Testing sftp server
&lt;/h4&gt;

&lt;h5&gt;
  
  
  SFTP Connection
&lt;/h5&gt;

&lt;p&gt;For sftp connection, try to connect in your server with &lt;strong&gt;partner&lt;/strong&gt; credentials.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sftp partner@your-sftp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type password, and if everything is alright, you'll enter inside &lt;strong&gt;partner&lt;/strong&gt; sftp home folder.&lt;/p&gt;

&lt;h5&gt;
  
  
  SSH Connection
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Partner&lt;/strong&gt; should has access only to sftp and no ssh connections should be allowed. The test is simple, just try to connect with SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh partner@your-sftp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type password, hit enter. And you expect to receive this warning message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This service allows sftp connections only.
Connection to your-sftp-server closed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;After this, you can send the &lt;strong&gt;partner&lt;/strong&gt; credentials to &lt;strong&gt;Partner&lt;/strong&gt;. 😂&lt;/p&gt;

&lt;p&gt;This "tutorial" has the purpose to show a simple way to build an sftp server using only Linux resources. As you can see, this "tutorial" doesn't go deep inside major security efforts. But, you can easily enforce your security, using Linux resources too, or using the service providers (aws, Digital Ocean, etc) tools.&lt;/p&gt;

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