<?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[Coto's Blog]]></title><description><![CDATA[Linux, VoIP, Dev, Cloud and Stuff's]]></description><link>http://cotocisternas.cl/</link><generator>Ghost 0.11</generator><lastBuildDate>Sun, 09 Apr 2017 22:52:18 GMT</lastBuildDate><atom:link href="http://cotocisternas.cl/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Puppet Security Rules]]></title><description><![CDATA[<p>Some Useful safety rules for Puppet:</p>

<p>Puppetfile:</p>

<pre><code class="language-ruby">mod 'thias/sysctl', '1.0.2'  
mod 'puppetlabs/firewall', '1.8.0'  
</code></pre>

<p>manifest.pp</p>

<pre><code class="language-puppet">  Firewall {
    require =&gt; undef,
  }
  firewall { '000 INPUT allow related and established':
    proto       =&gt; 'all',
    action      =&gt; 'accept',
    state       =&gt; ['RELATED', 'ESTABLISHED']
  }
  firewall { '001 accept all icmp':
    proto       =&gt; 'icmp',</code></pre>]]></description><link>http://cotocisternas.cl/puppet-security-rules/</link><guid isPermaLink="false">79c8cfc5-c342-4553-8256-31506f63cb65</guid><category><![CDATA[puppet]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Fri, 30 Sep 2016 03:45:24 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2016/09/IMG_20141229_090431.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2016/09/IMG_20141229_090431.jpg" alt="Puppet Security Rules"><p>Some Useful safety rules for Puppet:</p>

<p>Puppetfile:</p>

<pre><code class="language-ruby">mod 'thias/sysctl', '1.0.2'  
mod 'puppetlabs/firewall', '1.8.0'  
</code></pre>

<p>manifest.pp</p>

<pre><code class="language-puppet">  Firewall {
    require =&gt; undef,
  }
  firewall { '000 INPUT allow related and established':
    proto       =&gt; 'all',
    action      =&gt; 'accept',
    state       =&gt; ['RELATED', 'ESTABLISHED']
  }
  firewall { '001 accept all icmp':
    proto       =&gt; 'icmp',
    action      =&gt; 'accept'
  }
  firewall { '002 accept all to lo interface':
    proto       =&gt; 'all',
    iniface     =&gt; 'lo',
    action      =&gt; 'accept'
  }
  firewall { '003 reject local traffic not on loopback interface':
    iniface     =&gt; '! lo',
    proto       =&gt; 'all',
    destination =&gt; '127.0.0.1/8',
    action      =&gt; 'reject',
  }
  firewall { '004 drop FRAGMENTED PACKETS':
    chain       =&gt; 'INPUT',
    action      =&gt; 'drop',
    isfragment  =&gt; true,
  }
  firewall { '005 drop MALFORMED SYN-FLOOD':
    chain       =&gt; 'INPUT',
    action      =&gt; 'drop',
    proto       =&gt; 'tcp',
    tcp_flags   =&gt; 'FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,ACK',
  }
  firewall { '006 drop MALFORMED SYN-FLOOD':
    chain       =&gt; 'INPUT',
    action      =&gt; 'drop',
    proto       =&gt; 'tcp',
    tcp_flags   =&gt; 'FIN,SYN FIN,SYN',
  }
  firewall { '007 drop MALFORMED SYN-FLOOD':
    chain       =&gt; 'INPUT',
    action      =&gt; 'drop',
    proto       =&gt; 'tcp',
    tcp_flags   =&gt; 'SYN,RST SYN,RST',
  }
  firewall { '008 drop SYN-FLOOD':
    chain       =&gt; 'INPUT',
    state       =&gt; 'NEW',
    action      =&gt; 'drop',
    proto       =&gt; 'tcp',
    tcp_flags   =&gt; '! FIN,SYN,RST,ACK SYN',
  }
  firewall { '009 MALFORMED NULL PACKETS':
    chain       =&gt; 'INPUT',
    action      =&gt; 'drop',
    proto       =&gt; 'tcp',
    tcp_flags   =&gt; 'FIN,SYN,RST,PSH,ACK,URG NONE',
  }
  firewall { '010 drop MALFORMED XMAS PACKETS':
    chain       =&gt; 'INPUT',
    action      =&gt; 'drop',
    proto       =&gt; 'tcp',
    tcp_flags   =&gt; 'FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG',
  }

  sysctl { 'net.ipv4.conf.all.rp_filter':   value =&gt; '1'      }
  sysctl { 'net.ipv4.tcp_syncookies':       value =&gt; '1'      }
  sysctl { 'net.ipv4.tcp_tw_reuse':         value =&gt; '1'      }
  sysctl { 'net.ipv4.tcp_fin_timeout':      value =&gt; '30'     }
  sysctl { 'net.ipv4.tcp_keepalive_intvl':  value =&gt; '30'     }
  sysctl { 'net.ipv4.tcp_keepalive_probes': value =&gt; '5'      }
</code></pre>]]></content:encoded></item><item><title><![CDATA[PIGZ | NC]]></title><description><![CDATA[<p>Just a memory aid:</p>

<p>Origin and Destination:  </p>

<pre><code class="language-bash">apt-get install pv pigz netcat-openbsd  
</code></pre>

<p>Origin:  </p>

<pre><code class="language-bash">tar -cf -{$PATH} | pv -s {$SIZE} | pigz -9 | nc -l 8888  
</code></pre>

<p>Destination:  </p>

<pre><code class="language-bash">nc {$ORIGIN_IP} 8888 | pigz -d | tar xf - -C  /  
</code></pre>]]></description><link>http://cotocisternas.cl/pigz-nc/</link><guid isPermaLink="false">ca56cfc7-6f1b-4b32-a2bd-d6cbab9cd59c</guid><category><![CDATA[linux]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Thu, 07 May 2015 23:46:17 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2015/08/fc-450x300-black-u6.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2015/08/fc-450x300-black-u6.jpg" alt="PIGZ | NC"><p>Just a memory aid:</p>

<p>Origin and Destination:  </p>

<pre><code class="language-bash">apt-get install pv pigz netcat-openbsd  
</code></pre>

<p>Origin:  </p>

<pre><code class="language-bash">tar -cf -{$PATH} | pv -s {$SIZE} | pigz -9 | nc -l 8888  
</code></pre>

<p>Destination:  </p>

<pre><code class="language-bash">nc {$ORIGIN_IP} 8888 | pigz -d | tar xf - -C  /  
</code></pre>]]></content:encoded></item><item><title><![CDATA[Rolify + CanCanCan #Instance level role ability]]></title><description><![CDATA[<p>This post is more of a memory aid, but a strange conjugation of black magic to do something impossible. <br>
 The solution is quite simple, but it took me several hours to realize it. <br>
 In simple terms, it is not so complex to do this if you are using ActiveRecords, I</p>]]></description><link>http://cotocisternas.cl/rolify-cancancan-instance-level-role-ability/</link><guid isPermaLink="false">fbf06787-16fc-45bc-8184-91d55d519597</guid><category><![CDATA[ruby]]></category><category><![CDATA[rails]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Fri, 11 Jul 2014 23:23:21 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2015/08/ruby-2.png" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2015/08/ruby-2.png" alt="Rolify + CanCanCan #Instance level role ability"><p>This post is more of a memory aid, but a strange conjugation of black magic to do something impossible. <br>
 The solution is quite simple, but it took me several hours to realize it. <br>
 In simple terms, it is not so complex to do this if you are using ActiveRecords, I found a couple of post describing the solution:</p>

<p><strong>app/model/ability.rb</strong>  </p>

<pre><code class="language-ruby">can [:read, :update], Company, :id =&gt; Company.with_role(:manager, user).plug(id)  
</code></pre>

<p>My problem is that I do not use ActiveRecords if not rather MongoID, and not until i check the documentation of <a href="http://mongoid.org/en/origin/" title="MongoID Origin">Origin</a> (MongoID DSL) that I realized the detail:</p>

<p><strong>app/model/ability.rb</strong>  </p>

<pre><code class="language-ruby">can [:read, :update], Company, :id.in =&gt; Company.with_role(:manager, user).map(&amp;:id)  
</code></pre>

<p>See the difference?. It took almost 4 hours to see it …</p>]]></content:encoded></item><item><title><![CDATA[Rails 4.1 secrets.yml to SYM]]></title><description><![CDATA[<p>Usually i use a application.yml for this kind of stuff, devise secret, realm definition, host etc. Is nice to have all this things in one place. Today i start testing Rails 4.1 and i stumble on this new feature, work great but i like to manage my settings</p>]]></description><link>http://cotocisternas.cl/rails-4-1-secrets-yml-to-sym/</link><guid isPermaLink="false">90edbb8b-1814-4689-8b57-40d1a74f063a</guid><category><![CDATA[ruby]]></category><category><![CDATA[rails]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Sat, 14 Jun 2014 16:53:14 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2015/08/ruby-3.png" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2015/08/ruby-3.png" alt="Rails 4.1 secrets.yml to SYM"><p>Usually i use a application.yml for this kind of stuff, devise secret, realm definition, host etc. Is nice to have all this things in one place. Today i start testing Rails 4.1 and i stumble on this new feature, work great but i like to manage my settings like symbols and the ‘Rails.application.secrets’ method is not available until the app start. So here a little help to handle this in that way.</p>

<p><strong>config/secrets.yml</strong>  </p>

<pre><code class="language-ruby">defaults: &amp;defaults  
  devise_secret: 5d612bacfae3e470caef1782feb6e648391ea76a380d1910b9732c43e614398b7d297b9c13a803a5efb835db717fc9bd2e721c3d3ea45556297627b97f4b526d
  devise_pepper: 888d5b5b31563dc774bcf18c12h4lka242447d738921832c9e253c477628a21912535342455951ca6ca9fd02682b10cbb1deaeb8557aca1cab98de5eaffefc64
  realm: cotocisternas
  host: cotocisternas.cl

development:  
  &lt;&lt;: *defaults
  secret_key_base: 3eb6db5a9026c547c72708438d496d942e976b252138db7e4e0ee5edd7539457d3ed0fa02ee5e7179420ce5290462018591adaf5f42adcf855da04877827def2
  host: localhost:3000

test:  
  &lt;&lt;: *defaults
  secret_key_base: 3eb6db5a9026c547c72708438d496d942e976b252138db7e4e0ee5edd7539457d3ed0fa02ee5e7179420ce5290462018591adaf5f42adcf855da04877827def2
  host: test.local

production:  
  &lt;&lt;: *defaults
  secret_key_base: 3eb6db5a9026c547c72708438d496d942e976b252138db7e4e0ee5edd7539457d3ed0fa02ee5e7179420ce5290462018591adaf5f42adcf855da04877827def2
</code></pre>

<p>Now we need to symbolize this values before the app kicks up, so we add this piece of code</p>

<p><strong>config/application.rb</strong>  </p>

<pre><code class="language-ruby">Bundler.require(*Rails.groups)  
[...]
CONFIG = YAML.load(File.read(File.expand_path('../secrets.yml', __FILE__)))  
CONFIG.merge! CONFIG.fetch(Rails.env, {})  
CONFIG.symbolize_keys!  
[...]
</code></pre>

<p>Now we can simple use the key CONFIG[:value] where we need to set up some secret value, for Example:</p>

<p><strong>config/initializers/devise.rb</strong></p>

<pre><code class="language-ruby">Devise.setup do |config|  
  [...]
  config.secret_key = CONFIG[:devise_secret]
  [...]
  config.http_authentication_realm = CONFIG[:realm]
  [...]
  config.pepper = CONFIG[:devise_pepper]
  [...]
end  
</code></pre>]]></content:encoded></item><item><title><![CDATA[Asterisk MultiTrunk Dial Macro]]></title><description><![CDATA[<p>Easy solution for multi-provider/failover Asterisk SIP Trunks. Just put this config in your extensions.conf</p>

<pre><code class="language-asterisk">[globals]   
TRUNK_1=sipprovider1  
TRUNK_2=sipprovider2  
TRUNK_3=sipprovider3  
TRUNK_4=sipprovider4  
TRUNK_5=sipprovider5  
TRUNK_6=sipprovider6  
TOTAL=6   

[macro-dial-out]
;ARG1 =&gt; Dialing Number
;ARG2 =&gt; Timeout   

exten =&gt; s,1,NoOp(</code></pre>]]></description><link>http://cotocisternas.cl/asterisk-multitrunk-dial-macro/</link><guid isPermaLink="false">95d25ddc-1348-4508-95b6-25bfdf7fea91</guid><category><![CDATA[voip]]></category><category><![CDATA[asterisk]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Tue, 14 Jan 2014 12:34:35 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2015/08/maxresdefault.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2015/08/maxresdefault.jpg" alt="Asterisk MultiTrunk Dial Macro"><p>Easy solution for multi-provider/failover Asterisk SIP Trunks. Just put this config in your extensions.conf</p>

<pre><code class="language-asterisk">[globals]   
TRUNK_1=sipprovider1  
TRUNK_2=sipprovider2  
TRUNK_3=sipprovider3  
TRUNK_4=sipprovider4  
TRUNK_5=sipprovider5  
TRUNK_6=sipprovider6  
TOTAL=6   

[macro-dial-out]
;ARG1 =&gt; Dialing Number
;ARG2 =&gt; Timeout   

exten =&gt; s,1,NoOp(== DIAL --&gt; ${ARG1})  
exten =&gt; s,n,Set(COUNTER=1)  
exten =&gt; s,n(while),GotoIf($["${COUNTER}"&gt;"${TOTAL}"]?fin)  
exten =&gt; s,n,Dial(SIP/${ARG1}@${TRUNK_${COUNTER}},${ARG2},rg)  
exten =&gt; s,n,NoOp( DIAL STATUS --&gt; ${DIALSTATUS})  
exten =&gt; s,n,GotoIf($["${DIALSTATUS}"="ANSWER"]?fin)  
exten =&gt; s,n,GotoIf($["${DIALSTATUS}"="NOANSWER"]?fin)  
exten =&gt; s,n,Set(COUNTER=$[${COUNTER}+1])  
exten =&gt; s,n,Goto(while)  
exten =&gt; s,n(fin),MacroExit     

[ldi]
; Example Dialplan for LDI calls

exten =&gt; _00.,1,NoOp(= DIAL STATUS --&gt; ${DIALSTATUS}===)  
exten =&gt; _00.,n,Macro(dial-out,${EXTEN},60) exten =&gt; _00.,n,Hangup()  
</code></pre>]]></content:encoded></item><item><title><![CDATA[Phone Area Codes]]></title><description><![CDATA[<p>For some time, I am developing a VoIP solution Premise / Cloud, based on Freeswitch. I stumble on a pretty simple problem … All telephone area codes in the world. There are websites that contain the info, but in a sort of “phone book” and is not very useful for creating a</p>]]></description><link>http://cotocisternas.cl/phone-area-codes/</link><guid isPermaLink="false">0e0c452b-0447-4dcf-8093-26bbb51d4eb0</guid><category><![CDATA[ruby]]></category><category><![CDATA[voip]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Tue, 14 Jan 2014 00:54:21 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2015/08/yaml_explained_b.png" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2015/08/yaml_explained_b.png" alt="Phone Area Codes"><p>For some time, I am developing a VoIP solution Premise / Cloud, based on Freeswitch. I stumble on a pretty simple problem … All telephone area codes in the world. There are websites that contain the info, but in a sort of “phone book” and is not very useful for creating a database, so I wrote some scripts based on nokogiri to download and create YAML files for all available area codes in <a href="http://countrycode.org" title="CountryCode.org">CountryCode.org</a> <br>
 Here the result: <a href="http://github.com/cotocisternas/area_codes" title="AreaCodes">AreaCodes</a></p>

<p>If you’re curious about the script, here I leave too …</p>

<pre><code>require 'rubygems'  
require 'nokogiri'  
require 'open-uri'  
require 'yaml'

def write(filename, array)  
  File.open(filename, "a") do |f|
    f.write(array)
  end
end

codes = %w[AD AE AF AG AI AL AM AN AO AQ AR AS AT AU AW AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BR BS BT BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GH GI GL GM GN GQ GR GT GU GW GY HK HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MR MS MT MU MV MW MX MY MZ NA NC NE NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PT PW PY QA RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR ST SV SY SZ TC TD TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW]

codes.each do |code|  
  page_uri = "http://countrycode.org/#{code}"
  begin
    doc = Nokogiri::HTML(open(page_uri))
    array = Array.new
    doc.css('#child_center_column #common_table &gt; tr').each do |node|
      node.css('td &gt; b').children.each do |code|
        hash = Hash.new
        if code.name == "text"
          hash["name"] = node.css('.city').text
          hash["area_code"] = code.text.gsub(/^.*\s(\d*)$/,'\\1')  
        end
        array &lt;&lt; hash
      end
    end
    file = File.dirname(__FILE__)+"/data/codes/#{code}.yaml"
    write(file, array.to_yaml)

  rescue OpenURI::HTTPError =&gt; e 
    if e.message == '404 Not Found'
      puts code+" 404 Error!"
    else
      raise e
    end
  end
end  
</code></pre>]]></content:encoded></item><item><title><![CDATA[Rails DIGEST Auth]]></title><description><![CDATA[<p><strong>app/application_controller.rb</strong></p>

<pre><code class="language-ruby">require 'digest/md5'

class ApplicationController &lt; ActionController::Base  
  protect_from_forgery with: :exception

  digest_user = CONFIG[:digest_user]
  digest_pass = CONFIG[:digest_pass]

  REALM = CONFIG[:realm]
  USERS = {"dhh" =&gt; digest_pass, digest_user =&gt; Digest::MD5.hexdigest([digest_user,REALM,digest_pass].join(":"))}

  def digest_authenticate</code></pre>]]></description><link>http://cotocisternas.cl/rails-digest-auth/</link><guid isPermaLink="false">45b1708f-dd8e-4dea-a50c-7ed80fc85581</guid><category><![CDATA[ruby]]></category><category><![CDATA[rails]]></category><dc:creator><![CDATA[Coto Cisternas]]></dc:creator><pubDate>Thu, 21 Feb 2013 17:18:49 GMT</pubDate><media:content url="http://cotocisternas.cl/content/images/2015/08/ruby-1.png" medium="image"/><content:encoded><![CDATA[<img src="http://cotocisternas.cl/content/images/2015/08/ruby-1.png" alt="Rails DIGEST Auth"><p><strong>app/application_controller.rb</strong></p>

<pre><code class="language-ruby">require 'digest/md5'

class ApplicationController &lt; ActionController::Base  
  protect_from_forgery with: :exception

  digest_user = CONFIG[:digest_user]
  digest_pass = CONFIG[:digest_pass]

  REALM = CONFIG[:realm]
  USERS = {"dhh" =&gt; digest_pass, digest_user =&gt; Digest::MD5.hexdigest([digest_user,REALM,digest_pass].join(":"))}

  def digest_authenticate
    authenticate_or_request_with_http_digest(REALM) do |username|
      USERS[username]
    end
  end

end  
</code></pre>

<p>And if you are using Devise as Auth GEM, just add this line to you’r controller:</p>

<pre><code class="language-ruby">respond_to :xml  
before_filter :digest_authenticate  
skip_before_filter :verify_authenticity_token  
</code></pre>]]></content:encoded></item></channel></rss>