<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linux Archives - VirtJunkie</title>
	<atom:link href="/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>/category/linux/</link>
	<description>Virtualization, Automation, and anything else that might be on my mind</description>
	<lastBuildDate>Mon, 04 May 2020 13:00:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.2</generator>

<image>
	<url>/wp-content/uploads/2020/04/cropped-vj4-150x150.png</url>
	<title>Linux Archives - VirtJunkie</title>
	<link>/category/linux/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Jitsi for Just in Time Conferencing using Terraform on Vultr with Route 53</title>
		<link>/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/</link>
					<comments>/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Mon, 04 May 2020 13:00:00 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[Hashicorp]]></category>
		<category><![CDATA[InfrastructureAsCode]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=1304</guid>

					<description><![CDATA[<p>With everything going on in the world with COVID-19 and the social distancing that is happening, people are looking to connect with friends, family and co-workers via Video conferencing more than ever. Recent vulnerabilities in Zoom have made people more cognizant than ever that security needs to be considered when using these platforms no matter [&#8230;]</p>
<p>The post <a href="/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/">Jitsi for Just in Time Conferencing using Terraform on Vultr with Route 53</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>With everything going on in the world with COVID-19 and the social distancing that is happening, people are looking to connect with friends, family and co-workers via Video conferencing more than ever. Recent vulnerabilities in Zoom have made people more cognizant than ever that security needs to be considered when using these platforms no matter what you are using them for.</p>



<p><a href="https://jitsi.org/" target="_blank" rel="noreferrer noopener">Jitsi is an open source video conferencing platform</a> that I&#8217;ve been hearing about a lot lately, and finally had a chance to look into. In this post I&#8217;ll explain how to use Terraform to provision a Jitsi instance when you need a conference and tear it down when you are done. We&#8217;ll be using Vultr and their Jitsi &#8220;application&#8221; and AWS Route 53 for DNS.</p>



<span id="more-1304"></span>



<h2 class="wp-block-heading">Why Am I Writing This Article, and What Does It Accomplish?</h2>



<p>Why am I writing this article?</p>



<ol><li>We <strong>always</strong> want to have our apps and infrastructure defined in code</li><li>We pay for traditional web conferencing software 24 hours a day, 7 days a week, regardless of if we are are using running a conference or not. Why don&#8217;t we spin up conference infrastructure <strong>when we need it, and tear it down when we don&#8217;t</strong>?</li></ol>



<p>At a high level, this project will accomplish the following:</p>



<ol><li>Provision a Vultr VPS that is pre-configured with Jitsi</li><li>Take the IP Address that Vultr assigns the VPS and use it to create an A Record in Route 53</li><li>Copy a script to your VPS that will be used to finish the Jitsi configuration</li><li>Run the script that we copied and pass a few command line arguments that are specific to our environment</li></ol>



<h2 class="wp-block-heading">Prerequisites</h2>



<p>In addition to having Terraform downloaded and installed, we&#8217;ll need the following items:</p>



<h3 class="wp-block-heading">Vultr Account + API Access</h3>



<p>Vultr is definitely my go-to for VPS&#8217;s these days. Not only because of their price/performance/feature availability ratio, but because they provide a number of pre-configured applications that are ready, or near ready for use. <a rel="noreferrer noopener" href="https://www.vultr.com/docs/one-click-jitsi" target="_blank">Jitsi is one of these applications</a>. If you do use Vultr, please do me a favor and use&nbsp;<a rel="noreferrer noopener" href="https://www.vultr.com/?ref=8531966-6G" target="_blank">this link</a>&nbsp;to sign up. I’ll get a little kickback, but you’ll get $100 USD to use on the site in your first month.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img fetchpriority="high" decoding="async" width="1024" height="450" src="https://www.virtjunkie.com/wp-content/uploads/2020/05/2020-05-02_19-45-1024x450.png" alt="" class="wp-image-1305" srcset="/wp-content/uploads/2020/05/2020-05-02_19-45-1024x450.png 1024w, /wp-content/uploads/2020/05/2020-05-02_19-45-300x132.png 300w, /wp-content/uploads/2020/05/2020-05-02_19-45-768x338.png 768w, /wp-content/uploads/2020/05/2020-05-02_19-45.png 1273w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure><div class="wp-block-media-text__content">
<p class="has-normal-font-size">Once you have a Vultr account, you&#8217;ll need to generate and record an API key to use with Terraform. Use the steps below to generate it.</p>



<ol><li>Log into Vultr</li><li>Navigate to Settings, and then API</li><li>Generate an API key, and copy it somewhere safe, we&#8217;ll be using it later</li></ol>
</div></div>



<h3 class="wp-block-heading">AWS Account + API Access</h3>



<p>We&#8217;ll be using <a rel="noreferrer noopener" href="https://aws.amazon.com/route53/" target="_blank">AWS&#8217;s Route 53 service</a>, which is really just a fancy DNS service that&#8217;s hooked into AWS.  In order to automate Route 53 with Terraform, we&#8217;ll need to enable API access.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile" style="grid-template-columns:auto 70%"><figure class="wp-block-media-text__media"><img decoding="async" width="1024" height="400" src="https://www.virtjunkie.com/wp-content/uploads/2020/05/2020-05-02_20-13-1024x400.png" alt="" class="wp-image-1307" srcset="/wp-content/uploads/2020/05/2020-05-02_20-13-1024x400.png 1024w, /wp-content/uploads/2020/05/2020-05-02_20-13-300x117.png 300w, /wp-content/uploads/2020/05/2020-05-02_20-13-768x300.png 768w, /wp-content/uploads/2020/05/2020-05-02_20-13-1536x599.png 1536w, /wp-content/uploads/2020/05/2020-05-02_20-13-1568x612.png 1568w, /wp-content/uploads/2020/05/2020-05-02_20-13.png 1607w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure><div class="wp-block-media-text__content">
<p><a rel="noreferrer noopener" href="https://console.aws.amazon.com/iam/home?#security_credential" target="_blank">Use this link to access the IAM Management page</a></p>



<ol><li>Expand the &#8220;Access Keys&#8221; blade</li><li>Select &#8220;Create New Access Key</li><li>Save the resulting file, as we&#8217;ll use the contents later</li></ol>
</div></div>



<h3 class="wp-block-heading">Domain Registrar Using Custom Nameservers</h3>



<p>In addition to the above, the domain you want to use will need to be configured to use the Route 53 Name Servers. Route 53 will provide you the nameservers when you create a zone, and you&#8217;ll simply plug those into your registrar DNS settings page. I&#8217;m not going to explain how to create a zone in Route 53, or how to configure your registrar, but if you have questions, throw them in the comments and I&#8217;ll do my best to help.</p>



<h2 class="wp-block-heading">Getting Started</h2>



<h3 class="wp-block-heading">Run This Project</h3>



<ol><li>Grab the files below, or copy them from my <a rel="noreferrer noopener" href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53" target="_blank">Github Repository</a></li><li>Enter the directory that contains the files</li><li>At a minimum, modify the fields in the auto.tfvars file<ol><li>vultr_api_key</li></ol><ol><li>aws_access_key</li><li>aws_secret_key</li><li>domain</li><li>email</li></ol></li><li>Initialize Terraform by running <strong><code>terraform init</code></strong></li><li>Create a terraform plan by running <strong><code>terraform plan</code></strong></li><li>Apply the configuration by running <strong><code>terraform apply</code></strong></li><li>Voila! In less than 5 minutes, you&#8217;ve got a functional, secure Jitsi instance, running on a server and domain you control. Upon successful creation, you&#8217;ll see text like what we see below giving you the URL and credentials. When you are done with your conference, just run <code><strong>terraform destroy</strong></code> to stop from receiving charges on a server/service you aren&#8217;t using.</li></ol>



<pre class="urvanov-syntax-highlighter-plain-tag">null_resource.jitsi_config (remote-exec): ------------------------------
null_resource.jitsi_config (remote-exec): |                            |
null_resource.jitsi_config (remote-exec): |   JITSI SETUP COMPLETED!   |
null_resource.jitsi_config (remote-exec): |                            |
null_resource.jitsi_config (remote-exec): ------------------------------
null_resource.jitsi_config (remote-exec): JITSI URL: https://conference.yourdomain.com/

null_resource.jitsi_config (remote-exec): USERNAME: admin
null_resource.jitsi_config (remote-exec): PASSWORD: @#$asdfahgsd34579--23%4asdf</pre>



<h2 class="wp-block-heading">Code</h2>



<h3 class="wp-block-heading">Main.tf</h3>



<p>This file does all of the work.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#main.tf
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53

#Conifugre the Vultr provider
provider &quot;vultr&quot; {
  api_key = var.vultr_api_key
  rate_limit = 700
  retry_limit = 3
}

#Configure the AWS Provider
provider &quot;aws&quot; {
  #profile    = &quot;default&quot;
  #shared_credentials_file = &quot;/home/jhowe/storage/btsync/folders/Sync/awscredentials/credentials&quot;
  region     = var.aws_region
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
}

#https://www.terraform.io/docs/providers/aws/d/route53_zone.html
data &quot;aws_route53_zone&quot; &quot;selected&quot; {
  name         = &quot;${var.domain}.&quot;
  private_zone = false
}

#Provision Vultr Server
resource &quot;vultr_server&quot; &quot;my_server&quot; {
    plan_id = var.vultr_plan_id
    region_id = var.vultr_region
    app_id = var.vultr_app_id
    label = &quot;${var.hostname}.${var.domain}&quot;
    tag = var.vultr_tag
    hostname = &quot;${var.hostname}.${var.domain}&quot;
    enable_ipv6 = false
    auto_backup = false
    ddos_protection = false
    notify_activate = false

    connection {
        type     = &quot;ssh&quot;
        user     = &quot;root&quot;
        
        #https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
        password = self.default_password

        #https://www.terraform.io/docs/provisioners/connection.html#the-self-object
        host     = self.main_ip
    }

    provisioner &quot;local-exec&quot; {
      command = &quot;echo SSH to this server with the command: ssh root@${vultr_server.my_server.main_ip} with the password '${vultr_server.my_server.default_password}'&quot;
    }
}

#Create the Route 53 A Record
#https://www.terraform.io/docs/providers/aws/r/route53_record.html
resource &quot;aws_route53_record&quot; &quot;conference&quot; {
  zone_id = data.aws_route53_zone.selected.zone_id
  name    = &quot;${var.hostname}.${data.aws_route53_zone.selected.name}&quot;
  type    = &quot;A&quot;
  ttl     = &quot;300&quot;
  records = &amp;#91;&quot;${vultr_server.my_server.main_ip}&quot;]
}

#This null resource exists to handle configuration of the Vultr VPS after Route 53
resource &quot;null_resource&quot; &quot;jitsi_config&quot; {
    
    connection {
        type     = &quot;ssh&quot;
        user     = &quot;root&quot;
        
        #https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
        password = vultr_server.my_server.default_password

        #https://www.terraform.io/docs/provisioners/connection.html#the-self-object
        host     = vultr_server.my_server.main_ip
    }

    provisioner &quot;file&quot; {
        source      = &quot;./configure_jitsi_param.sh&quot;
        destination = &quot;/root/configure_jitsi_param.sh&quot;
    }

    provisioner &quot;remote-exec&quot; {
        inline = &amp;#91;
            &quot;chmod +x /root/configure_jitsi_param.sh&quot;,
            &quot;/root/configure_jitsi_param.sh ${var.hostname}.${var.domain} ${var.email} y&quot;
        ]
    }
}</pre>



<h3 class="wp-block-heading">Variables.tf</h3>



<p>This file defines the variables that we will use in main.tf</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#variables.tf
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53

variable &quot;vultr_api_key&quot; {
    description = &quot;API Key Used by Vultr (https://my.vultr.com/settings/#settingsapi)&quot;
}

variable &quot;vultr_region&quot; {
    description = &quot;Vultr Region Selection (curl https://api.vultr.com/v1/regions/availability?DCID=1)&quot;
    default = 1
}

variable &quot;vultr_plan_id&quot; {
    description = &quot;Vultr Plan for the VPS to use (curl https://api.vultr.com/v1/plans/list)&quot;
    default = 202
}

variable &quot;vultr_tag&quot; {
    description = &quot;Vultr Tag to apply to the new VPS&quot;
    default = &quot;jitsi-conference&quot;
}

variable &quot;vultr_app_id&quot; {
    description = &quot;Vultr App to pre-install. This should always be '47', if jitsi is being provisioned (curl https://api.vultr.com/v1/app/list)&quot;
    default = 47
}

variable &quot;hostname&quot; {
    description = &quot;Hostname to be used&quot;
    default = &quot;conferences&quot;
}

variable &quot;email&quot; {
    description = &quot;email to be used for let's encrypt acme config&quot;
    default = &quot;john.doe@email.com&quot;
}

variable &quot;domain&quot; {
    description = &quot;domain to be used&quot;
    default = &quot;aremyj.am&quot;
}

variable &quot;aws_access_key&quot; {
    description = &quot;AWS Access Key - get it here: (https://console.aws.amazon.com/iam/home?#security_credential)&quot;
}

variable &quot;aws_secret_key&quot; {
    description = &quot;AWS Secret Key - get it here: (https://console.aws.amazon.com/iam/home?#security_credential)&quot;
}

variable &quot;aws_region&quot; {
    description = &quot;AWS Region&quot;
    default = &quot;us-east-1&quot;
}</pre>



<h3 class="wp-block-heading">[yourdomain].auto.tfvars</h3>



<p>The auto.tfvars file provides values to the variables defined in the variables.tf file. You&#8217;ll have to create this file from scratch, and terraform best practices dictate that you exclude this file from source control. Here&#8217;s an example you can use. Modify this for your environment. The name doesn&#8217;t matter, as long as it ends with auto.tfvars.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">vultr_api_key = &quot;&amp;#91;fill this in]&quot;
vultr_region = 1
vultr_plan_id = 202
vultr_app_id = 47
vultr_tag = &quot;jitsi-conference&quot;
hostname = &quot;conference&quot;
email = &quot;your.email@address.org&quot;
domain = &quot;your-domain.com&quot;
aws_region = &quot;us-east-1&quot;
aws_access_key = &quot;&amp;#91;fill this in]&quot;
aws_secret_key = &quot;&amp;#91;fill this in]&quot;</pre>



<h3 class="wp-block-heading">configure_jitsi_param.sh</h3>



<p>Full disclosure, I did not create this script. Vultr created it, and provides it on your Jitsi VPS when you request it. Unfortunately, the version they provide is intended to be executed interactively, so I made a few very minor modifications to allow for us to run it with parameters.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash
#This script was copied from /opt/vultr/configure_jitsi.sh on a Vultr VPS that has the one-click Jitsi App
#I added lines 7-9 to allow for adding parameters on the CLI and commented lines 11-13 to force the variables to be provided on the CLI
#https://www.vultr.com/docs/one-click-jitsi
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53
HOSTNAME=$1
EMAIL=$2
response=$3
# User choices
#read -ep &quot;Please specify which domain you would like to use: &quot; HOSTNAME
#read -ep &quot;Please enter your email address for Let's Encrypt Registration: &quot; EMAIL
#read -r -p &quot;Would you like to enable password authorization? &amp;#91;y/N] &quot; response
case &quot;$response&quot; in
    &amp;#91;yY]&amp;#91;eE]&amp;#91;sS]|&amp;#91;yY])
        AUTH=1
        ;;
    *)
        AUTH=0
        ;;
esac


PROSODYPATH=/etc/prosody/conf.avail/${HOSTNAME}.cfg.lua
JITSIPATH=/etc/jitsi/meet/${HOSTNAME}-config.js
JICOFOPATH=/etc/jitsi/jicofo/sip-communicator.properties

# Remove and purge (Stop first and wait to avoid race condition)
purgeold() {        
        /opt/vultr/stopjitsi.sh
        sleep 5
        apt -y purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-turnserver jitsi-meet-web jicofo jitsi-videobridge2 jitsi*
}

# Reinstall
reinstalljitsi() {
        echo &quot;jitsi-videobridge2 jitsi-videobridge/jvb-hostname string ${HOSTNAME}&quot; | debconf-set-selections
        echo &quot;jitsi-meet-web-config jitsi-meet/cert-choice string Generate a new self-signed certificate (You will later get a chance to obtain a Let's encrypt certificate)&quot; | debconf-set-selections
        apt-get -y install jitsi-meet
}

# Remove nginx defaults
wipenginx() {
        rm -f /etc/nginx/sites-enabled/default
}

# Configure Lets Encrypt
configssl(){
    systemctl restart nginx
    sed -i -e 's/echo.*Enter your email and press.*/EMAIL=$1/' /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
    sed -i -e 's/read EMAIL//'  /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
    /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh ${EMAIL}
}

configprosody() {
  AUHTLINE='authentication = &quot;internal_plain&quot;'
  sed -i &quot;s/authentication\ \=\ \&quot;anonymous\&quot;/${AUTHLINE}/g&quot; ${PROSODYPATH}
  cat &amp;lt;&amp;lt; EOT &gt;&gt; ${PROSODYPATH}

VirtualHost &quot;guest.${HOSTNAME}&quot;
    authentication = &quot;anonymous&quot;
    c2s_require_encryption = false

EOT
}

configjitsi() {
        sed -i &quot;s/\/\/\ anonymousdomain\:\ 'guest.example.com',/anonymousdomain\:\ 'guest.${HOSTNAME}',/g&quot; ${JITSIPATH}
}

configjicofo() {
        echo &quot;org.jitsi.jicofo.auth.URL=XMPP:${HOSTNAME}&quot; &gt;&gt; ${JICOFOPATH}
}

registeruser(){
        PASSWORD=$(&amp;lt; /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16};echo;)
        prosodyctl register admin ${HOSTNAME} ${PASSWORD}
}

restartjitsi() {
        /opt/vultr/stopjitsi.sh
        /opt/vultr/startjitsi.sh
}

completedsetup(){
    echo &quot;&quot;
    echo &quot;------------------------------&quot;
    echo &quot;|                            |&quot;
    echo &quot;|   JITSI SETUP COMPLETED!   |&quot;
    echo &quot;|                            |&quot;
    echo &quot;------------------------------&quot;
    echo &quot;JITSI URL: https://${HOSTNAME}&quot;/
    echo &quot;&quot;
}

outputUser(){
    echo &quot;USERNAME: admin&quot;
    echo &quot;PASSWORD: ${PASSWORD}&quot;
    echo &quot;&quot;
}

# Script start

purgeold
reinstalljitsi
wipenginx
configssl
if &amp;#91; &quot;$AUTH&quot; == &quot;1&quot; ]; then
    configprosody
    configjitsi
    configjicofo
    registeruser
    restartjitsi    
fi
completedsetup
if &amp;#91; &quot;$AUTH&quot; == &quot;1&quot; ]; then
    outputUser
fi</pre>



<h2 class="wp-block-heading">Summary + More Reading</h2>



<p>There you have it! With this project you can have a fully functional Jitsi instance on your own domain with end to end encryption in less than 5 minutes. When you are done, there&#8217;s no harm in deleting it so you aren&#8217;t charged.</p>



<p>Here are some references I used while creating this:</p>



<ul><li><a href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53">https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53</a></li><li><a href="https://www.vultr.com/docs/one-click-jitsi">https://www.vultr.com/docs/one-click-jitsi</a></li><li><a href="https://www.terraform.io/docs/providers/aws/d/route53_zone.html">https://www.terraform.io/docs/providers/aws/d/route53_zone.html</a></li><li><a href="https://www.terraform.io/docs/providers/aws/r/route53_record.html">https://www.terraform.io/docs/providers/aws/r/route53_record.html</a></li><li><a href="https://www.terraform.io/docs/providers/vultr/r/server.html#default_password">https://www.terraform.io/docs/providers/vultr/r/server.html#default_password</a></li><li><a href="https://www.terraform.io/docs/provisioners/connection.html#the-self-object">https://www.terraform.io/docs/provisioners/connection.html#the-self-object</a></li><li>Create Vultr API Key: <a href="https://my.vultr.com/settings/#settingsapi">https://my.vultr.com/settings/#settingsapi</a></li><li>Create AWS Access/Secret Key: <a href="https://console.aws.amazon.com/iam/home?#security_credential">https://console.aws.amazon.com/iam/home?#security_credential</a></li><li>Vultr API Reference &#8211; has examples that will get you plan, region, and app IDs. <a href="https://www.vultr.com/api/">https://www.vultr.com/api/</a></li></ul>
<p>The post <a href="/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/">Jitsi for Just in Time Conferencing using Terraform on Vultr with Route 53</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Set Up Enpass With HTTPS Protected WebDAV and Ditch LastPass</title>
		<link>/2020/04/27/ditch-lastpass-for-enpass-webdav-https-traefik/</link>
					<comments>/2020/04/27/ditch-lastpass-for-enpass-webdav-https-traefik/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Mon, 27 Apr 2020 13:00:00 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Servers]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=1249</guid>

					<description><![CDATA[<p>It's time to ditch cloud based password managers. There.. I said it. What we are doing when we use them is giving ownership and management of our trusted secrets to someone else, and hoping that they will be able to protect them from bad guys, and make sure they are available when we need them.</p>
<p>The post <a href="/2020/04/27/ditch-lastpass-for-enpass-webdav-https-traefik/">Set Up Enpass With HTTPS Protected WebDAV and Ditch LastPass</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>It&#8217;s time to ditch cloud based password managers. There.. I said it. What we are doing when we use them is giving ownership and management of our trusted secrets to someone else, and hoping that they will be able to protect them from bad guys, and make sure they are available when we need them.</p>



<p>That&#8217;s a heck of an ask, isn&#8217;t it? I&#8217;ve been a LastPass customer for a very, very long time.. I use it to share secrets with my family, I use it on my mobile device to log into apps. It&#8217;s a safe bet to say it&#8217;s a critical piece of how I operate, and they have never once let me down. That said, if they asked for money to continue using their service, I&#8217;d have to pay. If they had a security event where secrets were compromised or if they lost my data, I&#8217;d be in very, very bad shape.</p>



<p>In this article, I will talk about how to set up a WebDAV share that&#8217;s protected by HTTPS using Traefik, Let&#8217;s Encrypt, and a WebDAV container on your own server, and use it to sync your secrets with devices.</p>



<span id="more-1249"></span>



<p>Before I begin, it&#8217;s important to understand that using WebDAV isn&#8217;t the only way to sync your secrets with Enpass. <a rel="noreferrer noopener" href="https://www.enpass.io/docs/manual-desktop/sync.html#supclouds" target="_blank">There are others</a>:</p>



<ul><li>Dropbox</li><li>Google Drive</li><li>OneDrive (Personal/Business)</li><li>iCloud</li><li>Box</li><li>Folder sync</li></ul>



<h2 class="wp-block-heading">Base Server Set Up</h2>



<h3 class="wp-block-heading">Get a VPS</h3>



<p>First thing we need is a server that is public internet facing. The easiest way to do this is to use a service that provides virtual private servers. I like Vultr because of their price/performance/feature availability ratio. They are cheaper than DigitalOcean and AWS, as easy, if not easier to manage, and have the scale you need to put your data pretty much wherever you want. If you do use Vultr, please do me a favor and use <a rel="noreferrer noopener" href="https://www.vultr.com/?ref=8531966-6G" target="_blank">this link</a> to sign up. I&#8217;ll get a little kickback, but you&#8217;ll get $100 USD to use on the site in your first month.</p>



<div class="wp-block-media-text alignwide is-stacked-on-mobile is-vertically-aligned-center" style="grid-template-columns:24% auto"><figure class="wp-block-media-text__media"><a href="https://www.vultr.com/?ref=8531966-6G" target="_blank" rel="noopener noreferrer"><img decoding="async" width="283" height="252" src="https://new.virtjunkie.com/wp-content/uploads/2020/04/2020-04-26_09-57.png" alt="" class="wp-image-1252"/></a></figure><div class="wp-block-media-text__content">
<p class="has-text-align-left has-normal-font-size">The OS doesn&#8217;t really matter, as long as you can install docker on it. A very small VPS will suffice, and mine costs $3.50 USD/Month.</p>
</div></div>



<h3 class="wp-block-heading">Harden the OS</h3>



<p>I won&#8217;t go into very much depth with this subject, but here are a few general guidelines:</p>



<ul><li>Disable root login via SSH</li><li>Require public key authentication for SSH sessions</li><li>Enable multi factor authentication for your remote user</li><li>Only install packages you need</li><li>Ensure all updates are installed, and continue to do so on a regular basis</li></ul>



<h2 class="wp-block-heading">Set Up Docker, Traefik, and WebDAV</h2>



<p>All code is on the GitHub repository I use to share all code for this site. You can find it here: <a href="https://github.com/jonhowe/Virtjunkie.com/tree/master/DitchLastPass">https://github.com/jonhowe/Virtjunkie.com/tree/master/DitchLastPass</a></p>



<p>First and foremost, this will not be a tutorial on how to administer Docker, WebDAV, or especially Traefik, but I&#8217;ll give you the exact steps and code for setting this up yourself, and provide some links at the end you can use to learn more about these topics.</p>



<p>All of the following steps will be executed on your VPS, so please sure you are connected to it via SSH or a similar terminal window.</p>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<p>We&#8217;ll be using an external docker bridge network in this configuration, the following command will create it</p>



<pre class="urvanov-syntax-highlighter-plain-tag">docker network create proxy</pre>
</div></div>
</div></div>
</div></div>
</div></div>
</div></div>
</div></div>



<h3 class="wp-block-heading">Create Traefik Configuration</h3>



<p>First of all, let&#8217;s create the directory structure we&#8217;ll need for Traefik (line 1). We&#8217;ll also be creating a file that will be used for storing SSL certificates (line 2), and setting permissions on it (line 3).</p>



<pre class="urvanov-syntax-highlighter-plain-tag">mkdir -p $HOME/docker/traefik/data
touch $HOME/docker/traefik/data/acme.json
chmod 600 $HOME/docker/traefik/data/acme.json</pre>



<h4 class="wp-block-heading">Create Traefik Configuration</h4>



<p>Create a new file in the <strong><code>traefik/data</code></strong> directory we just created called <code><strong>traefik.yml</strong></code> with the contents below.</p>



<p>Changes Required:</p>



<ul><li>Line 24: Modify your email address</li></ul>



<pre class="urvanov-syntax-highlighter-plain-tag">#File Path
#$HOME/docker/traefik/data/traefik.yml

#http://www.virtjunkie.com/ditch-lastpass-for-enpass-webdav-https-traefik/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/DitchLastPass

api:
  dashboard: false

entryPoints:
  http:
    address: &quot;:80&quot;
  https:
    address: &quot;:443&quot;

providers:
  docker:
    endpoint: &quot;unix:///var/run/docker.sock&quot;
    exposedByDefault: false

certificatesResolvers:
  http:
    acme:
      email: your.email@domain.com
      storage: acme.json
      httpChallenge:
        entryPoint: http</pre>



<h4 class="wp-block-heading">Define Traefik Container</h4>



<p>Create a new file in the <strong><code>traefik/data</code></strong> directory called <code><strong>docker-compose.yml</strong></code></p>



<p>Changes Required:</p>



<ul><li>Line 30: Modify to fit the hostname of your server</li><li>Line 31: Add in credentials compatible with basic auth. You can use the output from the command below to achieve this.<ul><li><code><strong>echo $(htpasswd -nb [your user] [your pass]) | sed -e s/\$/\$\$/g</strong></code></li></ul></li><li>Line 35: Modify to fit the hostname of your server</li></ul>



<pre class="urvanov-syntax-highlighter-plain-tag">#File Path
#$HOME/docker/traefik/docker-compose.yml

#http://www.virtjunkie.com/ditch-lastpass-for-enpass-webdav-https-traefik/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/DitchLastPass

version: '3'

services:
  traefik:
    image: traefik:v2.0
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
      - ./data/logs/:/logs/
    labels:
      - &quot;traefik.enable=true&quot;
      - &quot;traefik.http.routers.traefik.entrypoints=http&quot;
      - &quot;traefik.http.routers.traefik.rule=Host(`custom.hostname.com`)&quot;
      - &quot;traefik.http.middlewares.traefik-auth.basicauth.users=traefikuser:htpasswd-encrypted-string&quot;
      - &quot;traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https&quot;
      - &quot;traefik.http.routers.traefik.middlewares=traefik-https-redirect&quot;
      - &quot;traefik.http.routers.traefik-secure.entrypoints=https&quot;
      - &quot;traefik.http.routers.traefik-secure.rule=Host(`custom.hostname.com`)&quot;
      - &quot;traefik.http.routers.traefik-secure.middlewares=traefik-auth&quot;
      - &quot;traefik.http.routers.traefik-secure.tls=true&quot;
      - &quot;traefik.http.routers.traefik-secure.tls.certresolver=http&quot;
      - &quot;traefik.http.routers.traefik-secure.service=api@internal&quot;

networks:
  proxy:</pre>



<h4 class="wp-block-heading">Start Traefik Container</h4>



<pre class="urvanov-syntax-highlighter-plain-tag">cd $HOME/docker/traefik
docker-compose up -d</pre>



<h3 class="wp-block-heading">Create WebDAV Configuration</h3>



<p>Before we begin, we need to create the directory structure for the WebDAV container. Use the following command to do so.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">mkdir -p $HOME/docker/webdav/dav/</pre>



<p>We&#8217;ll be using a <a rel="noreferrer noopener" href="https://hub.docker.com/r/bytemark/webdav/" target="_blank">container authored by bytemark</a> for this project. It&#8217;s essentially just apache with the webdav module installed. As of today, the container is less than 100MB.</p>



<h4 class="wp-block-heading">Define WebDAV Application Configuration</h4>



<p>Changes Required:</p>



<ul><li>Line 15: Username used to authenticate to the WebDAV service.</li><li>Line 16: Password you&#8217;ll use to authenticate to the WebDAV service. This is stored in plaintext in this example, but storing the variable in an external file is best practice.</li><li>Line 17: Modify to fit the hostname of your server</li><li>Line 27: Modify to fit the hostname of your server</li><li>Line 31: Modify to fit the hostname of your server</li></ul>



<pre class="urvanov-syntax-highlighter-plain-tag">#File path
#$HOME/docker/webdav/docker-compose.yml

#http://www.virtjunkie.com/ditch-lastpass-for-enpass-webdav-https-traefik/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/DitchLastPass

version: '3'
services:
  webdav:
    image: bytemark/webdav
    container_name: webdav
    restart: unless-stopped
    environment:
      AUTH_TYPE: Basic
      USERNAME: your-username
      PASSWORD: secure-passsword
      SERVER_NAMES: your-dav.domain.com
    networks:
      - proxy
    security_opt:
      - no-new-privileges:true
    volumes:
      - ./dav:/var/lib/dav
    labels:
      - &quot;traefik.enable=true&quot;
      - &quot;traefik.http.routers.webdav.entrypoints=http&quot;
      - &quot;traefik.http.routers.webdav.rule=Host(`your-dav.domain.com`)&quot;
      - &quot;traefik.http.middlewares.webdav-https-redirect.redirectscheme.scheme=https&quot;
      - &quot;traefik.http.routers.webdav.middlewares=webdav-https-redirect&quot;
      - &quot;traefik.http.routers.webdav-secure.entrypoints=https&quot;
      - &quot;traefik.http.routers.webdav-secure.rule=Host(`your-dav.domain.com`)&quot;
      - &quot;traefik.http.routers.webdav-secure.tls=true&quot;
      - &quot;traefik.http.routers.webdav-secure.tls.certresolver=http&quot;
      - &quot;traefik.http.routers.webdav-secure.service=webdav&quot;
      - &quot;traefik.http.services.webdav.loadbalancer.server.port=80&quot;
      - &quot;traefik.docker.network=proxy&quot;
networks:
  proxy:
    external: true</pre>



<h4 class="wp-block-heading">Start the WebDAV Container</h4>



<p>Run the following command to bring up the webdav container</p>



<pre class="urvanov-syntax-highlighter-plain-tag">cd $HOME/docker/webdav
docker-compose up -d</pre>



<h3 class="wp-block-heading">Bringing it all together</h3>



<h4 class="wp-block-heading">Summary</h4>



<p>At this point you should have  two containers running on your VPS. Traefik is acting as a reverse proxy for the WebDAV container, and is providing SSL encryption to it. The SSL certificate is provided by <a rel="noreferrer noopener" href="https://letsencrypt.org/" target="_blank">Let&#8217;s Encrypt</a>.</p>



<h4 class="wp-block-heading">Final Directory Structure</h4>



<pre class="urvanov-syntax-highlighter-plain-tag">user@webdav-server:~/docker$ tree
.
├── traefik
│&amp;nbsp;&amp;nbsp; ├── data
│&amp;nbsp;&amp;nbsp; │&amp;nbsp;&amp;nbsp; ├── acme.json
│&amp;nbsp;&amp;nbsp; │&amp;nbsp;&amp;nbsp; └── traefik.yml
│&amp;nbsp;&amp;nbsp; └── docker-compose.yml
└── webdav
    ├── dav
    │&amp;nbsp;&amp;nbsp; ├── data
    │&amp;nbsp;&amp;nbsp; │&amp;nbsp;&amp;nbsp; └── Enpass
    │&amp;nbsp;&amp;nbsp; │&amp;nbsp;&amp;nbsp;     └── vault.enpassdbsync
    │&amp;nbsp;&amp;nbsp; ├── DavLock
    │&amp;nbsp;&amp;nbsp; ├── DavLock.dir
    │&amp;nbsp;&amp;nbsp; └── DavLock.pag
    └── docker-compose.yml

6 directories, 8 files</pre>



<h2 class="wp-block-heading">Migrate to Enpass Using WebDAV</h2>



<p>Now that we&#8217;ve got a functional and secure WebDAV instance, we just need to migrate to it. These steps are pretty easy, but I want to include them to be comprehensive.</p>



<h3 class="wp-block-heading">Export Secrets From Lastpass</h3>



<p>To make our transition from Lastpass as seamless as possible, we&#8217;ll export our secrets so we can import them into Enpass. The easiest way to do this is from the Lastpass Vault.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="359" height="444" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/2020-04-26_11-51.png" alt="" class="wp-image-1271" srcset="/wp-content/uploads/2020/04/2020-04-26_11-51.png 359w, /wp-content/uploads/2020/04/2020-04-26_11-51-243x300.png 243w" sizes="(max-width: 359px) 100vw, 359px" /></figure><div class="wp-block-media-text__content">
<p class="has-large-font-size">Step 1 &#8211; Open Your Vault</p>
</div></div>



<hr class="wp-block-separator"/>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="574" height="986" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/2020-04-26_11-55.png" alt="" class="wp-image-1272" srcset="/wp-content/uploads/2020/04/2020-04-26_11-55.png 574w, /wp-content/uploads/2020/04/2020-04-26_11-55-175x300.png 175w" sizes="(max-width: 574px) 100vw, 574px" /></figure><div class="wp-block-media-text__content">
<p class="has-large-font-size">Step 2 &#8211; Export Secrets</p>



<ol><li>Select &#8220;More Options&#8221;</li><li>Select &#8220;Advanced&#8221;</li><li>Select &#8220;Export&#8221;</li><li>If prompted, enter your Master Password, and note where the CSV export file name and path.</li></ol>
</div></div>



<h3 class="wp-block-heading">Import Secrets To Enpass</h3>



<p>Pretty easy stuff here, just open enpass, and kick off the import.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="883" height="949" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/Peek-2020-04-26-12-55.gif" alt="" class="wp-image-1287"/></figure><div class="wp-block-media-text__content">
<p class="has-normal-font-size">Import Steps:</p>



<ol><li>Open Enpass</li><li>Select Menu</li><li>Select File</li><li>Select Import</li><li>When prompted to &#8220;Select from where you want to import your data into Enpass&#8221;, select Lastpass</li><li>Navigate to the directory you exported the CSV to</li><li>Select continue to finish the import</li></ol>
</div></div>



<h3 class="wp-block-heading">Connect EnPass To WebDav Share</h3>



<p>At this point you&#8217;ve got a functioning WebDAV service protected by SSL, as well as a local instance of Enpass that has your lastpass secrets. We just need to connect EnPass to your Webdav instance to allow us to sync to it. Once you have <a rel="noreferrer noopener" href="https://www.enpass.io/downloads/" target="_blank">EnPass Installed</a>, follow the steps below to connect it to your WebDAV Service.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="881" height="558" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/Peek-2020-04-26-12-20.gif" alt="" class="wp-image-1278"/></figure><div class="wp-block-media-text__content">
<p>Connection Steps:</p>



<ol><li>Open Enpass</li><li>Select Settings</li><li>Select Vaults</li><li>Select the Vault you&#8217;d like to sync</li><li>Enter the URL of your server, and ensure to include the https:// prefix</li><li>Enter the username and password created in Section 2.2.1</li><li>Ensure that the checkbox for &#8220;Bypass SSL Certificate Validation&#8221; is unchecked. We want to validate the SSL certificate since we are using Let&#8217;s Encrypt.</li></ol>
</div></div>



<h2 class="wp-block-heading">Risks</h2>



<p>There are some things that LastPass does for us that we don&#8217;t get with this solution. In particular, we are somewhat exposed to brute force attempts to the webdav service. Also, LastPass has a number of email notifications that go out when things happen in your vault. We are really only notified when a new client joins the vault in Enpass.</p>



<h2 class="wp-block-heading">Trafeik Resources</h2>



<p><a href="https://medium.com/@containeroo/traefik-2-0-docker-a-simple-step-by-step-guide-e0be0c17cfa5">https://medium.com/@containeroo/traefik-2-0-docker-a-simple-step-by-step-guide-e0be0c17cfa5</a><br><a href="https://containo.us/blog/traefik-2-0-docker-101-fc2893944b9d/">https://containo.us/blog/traefik-2-0-docker-101-fc2893944b9d/</a></p>
<p>The post <a href="/2020/04/27/ditch-lastpass-for-enpass-webdav-https-traefik/">Set Up Enpass With HTTPS Protected WebDAV and Ditch LastPass</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2020/04/27/ditch-lastpass-for-enpass-webdav-https-traefik/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Quick Tips for freeing up space in Linux</title>
		<link>/2019/06/25/freeing-up-space-in-linux/</link>
					<comments>/2019/06/25/freeing-up-space-in-linux/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Tue, 25 Jun 2019 13:26:31 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Servers]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=766</guid>

					<description><![CDATA[<p>Practice what you preach, right? As a former sysadmin, I try to keep my root partition on my personal machine pretty anemic.. usually between 40G and 60G. However, lately I've been running out of space and I wasn't sure why. Here are a few tips and tricks for finding the culprit, and freeing up some space.</p>
<p>The post <a href="/2019/06/25/freeing-up-space-in-linux/">Quick Tips for freeing up space in Linux</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Practice what you preach, right? I try to keep my root partition on my personal machine pretty anemic.. usually between 40G and 60G. However, lately I&#8217;ve been running out of space and I wasn&#8217;t sure why. Here are a few tips and tricks for finding the culprit, and freeing up some space.</p>



<span id="more-766"></span>



<p><strong>Identify Large Files</strong><br>First thing&#8217;s first.. let&#8217;s figure out what&#8217;s taking up the space. The snippet below will locate large files</p>



<pre class="urvanov-syntax-highlighter-plain-tag">sudo find / -mount -ls | awk '{print $7, $11}' | sort -rn | less</pre>



<p><strong>Duplicate Snaps</strong><br>Snapd by default keeps 2 copies of your snaps. Unfortunately, you can&#8217;t set the default amount to keep to anything less than 2. Since this is my personal machine, and some of my snaps are pretty large (~1G in come cases), I only want to keep a single copy of them. The snippet below will remove all but the latest copy of a snap.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">snap list --all | while read snapname ver rev trk pub notes; do if [[ $notes = *disabled* ]]; then snap remove &quot;$snapname&quot; --revision=&quot;$rev&quot;; fi; done</pre>



<p>If you want to keep more than the default of 2 snaps, you can use this snippet:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">sudo snap set system refresh.retain=5</pre>



<p><strong>Snapd Snapshots?</strong><br>For some reason I had a number of snapd snapshots on my system. You can list them like this:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">snap saved</pre>



<p>The &#8220;Saved&#8221; column is a unique identifier that is required when removing a snap. To remove a snapshot with ID of 1, run the following snippet:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">snap forget 1</pre>



<p><strong>Docker Logs Are Out Of Control!</strong><br>When I identified the large files, I saw that a docker container was using &gt;20G of space. I stopped the container, removed the log file, and then started the container again. To prevent this issue from happening in the future, start your container while specifying the max-file and max-size parameters like the snippet below:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">docker run --log-opt max-size=15m --log-opt max-file=2 dockerapp</pre>



<p><strong>Journal is using way too much space</strong><br>Since this is a personal workstation and logging isn&#8217;t my biggest priority, we can limit the journal. To see how much space you&#8217;re currently using, run the following snippet</p>



<pre class="urvanov-syntax-highlighter-plain-tag">journalctl --disk-usage</pre>



<p>There are three ways you can limit the journal:</p>



<ol><li>Limit by size of all journal files</li><li>Limit by amount of journal files</li><li>Limit by age of journal files</li></ol>



<p>You can handle each one of these using the snippets below</p>



<pre class="urvanov-syntax-highlighter-plain-tag"># By Size - Specify values in bytes or use K, M, G, T, P, E as units 
# for the specified sizes
journalctl --vacuum-size=200M

# By amount of files
journalctl --vacuum-files=15

# By age of files - specified with the usual &quot;s&quot;, &quot;m&quot;, &quot;h&quot;, &quot;days&quot;, 
# &quot;months&quot;, &quot;weeks&quot; and &quot;years&quot; suffixes
journalctl --vacuum-time=7days</pre>



<p><a href="https://www.freedesktop.org/software/systemd/man/journalctl.html" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">You can check the manpage online here</a></p>



<p><strong>Spotify Cache in Snap</strong><br>I recently noticed that Spotify has been caching tons of data on my desktop. Since I pay them to be a streaming service, I don&#8217;t really appreciate this. Fortunately, there&#8217;s a way to limit how much they cache on my machine. The changes below will limit Spotify to only cache 256MB locally.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">edit this file:
/home/$USER/snap/spotify/current/.config/spotify/prefs

add the line:
storage.size=256</pre>



<p><strong>In Conclusion</strong><br>It should go without saying that you should adhere to completely different standards if you&#8217;re running out of space on a server, and that you should test these snippets on a mission critical system. These steps should all be non-intrusive on a desktop, if you&#8217;re concerned, test them on a less critical system first.</p>
<p>The post <a href="/2019/06/25/freeing-up-space-in-linux/">Quick Tips for freeing up space in Linux</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2019/06/25/freeing-up-space-in-linux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Webex Teams on Linux</title>
		<link>/2019/06/01/webex-teams-on-linux/</link>
					<comments>/2019/06/01/webex-teams-on-linux/#comments</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Sat, 01 Jun 2019 13:59:50 +0000</pubDate>
				<category><![CDATA[Electron]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=759</guid>

					<description><![CDATA[<p>Unfortunately, webex teams does not have a linux client, and recommends that people simply use the web client. Unfortunately, I'm more used to this answer than I'd like, but fortunately I don't have to any more.</p>
<p>The post <a href="/2019/06/01/webex-teams-on-linux/">Webex Teams on Linux</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="alignright is-resized"><img loading="lazy" decoding="async" src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Electron_Software_Framework_Logo.svg/1200px-Electron_Software_Framework_Logo.svg.png" alt="" width="182" height="182"/></figure></div>



<p>My company standardized on <a href="https://teams.webex.com/">Cisco Webex Teams</a> for persistent chat. Unfortunately, webex teams does not have a linux client, and recommends that people simply use the web client. Unfortunately, I&#8217;m more used to this answer than I&#8217;d like, but fortunately I don&#8217;t have to any more.</p>



<span id="more-759"></span>



<p>This morning I found a project called <a href="https://github.com/jiahaog/nativefier">Nativefier</a>. It allows you to make any web page a desktop application using electron and a handful of other tools.</p>



<p>Their github page has documentation on how to do the install, but i&#8217;ll also add my exact steps. Keep in mind, I&#8217;m using Ubuntu 19.04 so YMMV.</p>



<p>You&#8217;ll need to have npm installed, and use it to install nativefier.</p>



<ol><li>sudo apt install npm</li><li>sudo npm install nativefier -g</li></ol>



<p>I manually went to the internet to grab an icon for webex teams that I had the packager use. Feel free to download it and use it, however, from what I read in the documentation, nativefier should have the ability to find the icon automatically. I didn&#8217;t try it, but if you do, let me know how it works!</p>



<div class="wp-block-file"><a href="https://www.virtjunkie.com/wp-content/uploads/2019/06/cisco-webex-teams.png">cisco-webex-teams</a><a href="https://www.virtjunkie.com/wp-content/uploads/2019/06/cisco-webex-teams.png" class="wp-block-file__button" download>Download</a></div>



<p>You can use the following snippet to convert convert webex teams into an application.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">nativefier -n &quot;Webex-Teams&quot; -p linux -a x64 -e 4.2.3 -i [absolute-path-to]/cisco-webex-teams.png --tray https://teams.webex.com/</pre>



<p>That will create a directory called &#8220;webex-teams-linux-x64&#8221;. To open webex teams, enter that directory and run the webex-teams binary.</p>
<p>The post <a href="/2019/06/01/webex-teams-on-linux/">Webex Teams on Linux</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2019/06/01/webex-teams-on-linux/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Ubuntu Cosmic 18.10 &#8211; Use Ansible To Deploy Docker</title>
		<link>/2018/12/14/ubuntu-cosmic-18-10-use-ansible-to-deploy-docker/</link>
					<comments>/2018/12/14/ubuntu-cosmic-18-10-use-ansible-to-deploy-docker/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Fri, 14 Dec 2018 22:45:36 +0000</pubDate>
				<category><![CDATA[Ansible]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=712</guid>

					<description><![CDATA[<p>As it turns out, Docker doesn&#8217;t officially support any version of Ubuntu past Artful. This is a bit of a challenge if you want to use a state configuration manager such as Ansible to deploy Docker, or even if you want to install it manually. I was able to get this working by using the [&#8230;]</p>
<p>The post <a href="/2018/12/14/ubuntu-cosmic-18-10-use-ansible-to-deploy-docker/">Ubuntu Cosmic 18.10 &#8211; Use Ansible To Deploy Docker</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>As it turns out, Docker doesn&#8217;t <a href="https://docs.docker.com/v17.09/engine/installation/linux/docker-ce/ubuntu/#os-requirements">officially support</a> any version of Ubuntu past Artful. This is a bit of a challenge if you want to use a state configuration manager such as Ansible to deploy Docker, or even if you want to install it manually. I was able to get this working by using the test branch of the docker release for Ubuntu Cosmic.</p>



<span id="more-712"></span>



<p>&nbsp;I found a <a href="https://galaxy.ansible.com/geerlingguy/docker">popular role in Ansible Galaxy</a>&nbsp;with a ton of installs, but the documentation that comes with it doesn&#8217;t work, which is fine&#8230; not a supported version, etc. I used the steps below to get it working.<br></p>



<p>Please be aware, the test branch is likely not stable, and shouldn&#8217;t be used for production. Follow this at your own risk.</p>



<p>1.) Run the command below to install the role</p>



<pre class="urvanov-syntax-highlighter-plain-tag">root@server:~$ ansible-galaxy install geerlingguy.docker</pre>



<p>2.) Create a text file named &#8220;install-docker.yml&#8221;<br>&nbsp; &#8211; The value assigned to docker_apt_release_channel being &#8220;test&#8221;.<br>&nbsp; &#8211; Add your own username(s) under &#8220;docker_users&#8221;<br>(This yaml file is located on my github page here: <a href="https://github.com/jonhowe/Virtjunkie.com/blob/master/install-docker.yml">https://github.com/jonhowe/Virtjunkie.com/blob/master/install-docker.yml</a>)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">---
- name: Install Docker
  hosts: all
  become: yes
  become_method: sudo
  tasks:
  - name: Install Docker and docker-compose
    include_role:
       name: geerlingguy.docker
    vars:
       - docker_edition: 'ce'
       - docker_apt_release_channel: test
       - docker_package_state: present
       - docker_install_compose: true
       - docker_compose_version: &quot;1.22.0&quot;
       - docker_users:
          - jhowe</pre>



<p>3.) Then it&#8217;s as easy as running the playbook</p>



<pre class="urvanov-syntax-highlighter-plain-tag">root@server:~$ ansible-playbook -K install-docker.yml</pre>
<p>The post <a href="/2018/12/14/ubuntu-cosmic-18-10-use-ansible-to-deploy-docker/">Ubuntu Cosmic 18.10 &#8211; Use Ansible To Deploy Docker</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2018/12/14/ubuntu-cosmic-18-10-use-ansible-to-deploy-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Thin Provision VMs on Workstation Pro using the vmrun Command</title>
		<link>/2018/11/27/thin-provision-vms-on-workstation-pro-using-the-vmrun-command/</link>
					<comments>/2018/11/27/thin-provision-vms-on-workstation-pro-using-the-vmrun-command/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Tue, 27 Nov 2018 14:00:16 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=667</guid>

					<description><![CDATA[<p>Continuing my series on provisioning VMs on workstation pro outside of the GUI, I&#8217;ve got a functional script that will create a linked clone using the vmrun command. It allows you to specify the following options on the command line: Username in the provisioned VM Password in the provisioned VM Source Template Snapshot used for [&#8230;]</p>
<p>The post <a href="/2018/11/27/thin-provision-vms-on-workstation-pro-using-the-vmrun-command/">Thin Provision VMs on Workstation Pro using the vmrun Command</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Continuing my series on provisioning VMs on workstation pro outside of the GUI, I&#8217;ve got a functional script that will create a linked clone using the vmrun command.</p>
<p>It allows you to specify the following options on the command line:</p>
<p><span id="more-667"></span></p>
<ol>
<li>Username in the provisioned VM</li>
<li>Password in the provisioned VM</li>
<li>Source Template</li>
<li>Snapshot used for linked clone</li>
<li>Name of new VM</li>
</ol>
<p>It completes the following tasks</p>
<ol>
<li>Clones virtual machine</li>
<li>Modifies the new VM&#8217;s VMX file to show the correct name</li>
<li>Powers on the new VM (which also registers it to Workstation)</li>
<li>Copies a script from the host to the VM as soon as VMware tools is available</li>
<li>Copies output from the script from the VM to the host machine and prints output to the screen</li>
<li>Prints the IP of the VM as soon as it&#8217;s available</li>
</ol>
<p>The output looks like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">$ ./workstation-clone-vm.sh --user root --pass [obfuscated] \
--template /storage/virtual_machines/Ubuntu_1810_Template/Ubuntu_1810_Template.vmx \
--snapshot base-4 --name test1
Parameters are:
User=root
Pass=[obfuscated]
Template Name=/storage/virtual_machines/Ubuntu_1810_Template/Ubuntu_1810_Template.vmx
Snapshot Name=base-4
New VM Name=test1

Cloning Ubuntu_1810_Template to test1 and using the snapshot: base-4
Powering on test1
Waiting for VMware Tools to start
..
Copying script to change the hostname from the host to the guest
Running custom script in test1 to set the hostname and rebooting
Waiting for VMware Tools to start

Copying output to local machine

Below is the output from the OS Customization:
Current hostname is ubuntu_1810_template. Hostname will be changed to test1
Waiting for the VM to return an IP Address
......
VM is running and has the IP Address: 192.168.102.131

Script took 77 seconds to execute</pre><p>You can find the script source code below and on <a href="https://github.com/jonhowe/Virtjunkie.com/blob/master/workstation-clone-vm.sh" target="_blank" rel="noopener">github</a>:</p><pre class="urvanov-syntax-highlighter-plain-tag">#Original Locations:
#Blog: http://www.virtjunkie.com/thin-provision-vms-on-workstation-pro-using-the-vmrun-command/
#Github: https://github.com/jonhowe/Virtjunkie.com/blob/master/workstation-clone-vm.sh

#Example:
#testgetopt.sh --user root --pass [pass] --template /storage/virtual_machines/Ubuntu_1810_Template/Ubuntu_1810_Template.vmx --snapshot base-4 --name test1

TEMP=`getopt -o u:,p:,n:,t:,s: --long user:,pass:,name:,template:,snapshot: -n 'clone_workstation_vm' -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." &gt;&amp;2 ; exit 1 ; fi

eval set -- "$TEMP"

VMRUN=/usr/bin/vmrun



#Do not edit below this line
SOURCEVM=
SOURCESNAPSHOT=
DESTINATIONVMNAME=
GUESTUSER=
GUESTPASS=
echo "Parameters are:"
while true; do
  case "$1" in
    -u | --user )
        GUESTUSER=$2;echo "User=$GUESTUSER"; shift 2 ;;
    -p | --pass )
        GUESTPASS=$2;echo "Pass=$GUESTPASS"; shift 2 ;;
    -n | --name )
        DESTINATIONVMNAME=$2;echo "New VM Name=$DESTINATIONVMNAME"; shift 2 ;;
    -s | --snapshot )
        SOURCESNAPSHOT=$2;echo "Snapshot Name=$SOURCESNAPSHOT"; shift 2 ;;
    -t | --template )
        SOURCEVM=$2;echo "Template Name=$SOURCEVM"; shift 2 ;;
    -- ) shift; break ;;
    * ) break ;;
  esac
done
echo

wait_for_vmware_tools() {
    CMD=$1
    USER=$2
    PASS=$3
    VM=$4
    echo "Waiting for VMware Tools to start"
    until ($CMD -T ws -gu $USER -gp $PASS CheckToolsState $VM | grep -q "running"); do 
        printf '.'
        sleep 5;
    done
    sleep 10
    echo
}

wait_for_vm_ip() {
    CMD=$1
    USER=$2
    PASS=$3
    VM=$4
    echo "Waiting for the VM to return an IP Address"
    until ($CMD -t ws -gu $USER -gp $PASS getGuestIPAddress $VM | grep -q -v "Error: Unable to get the IP address"); do
        printf "."
        sleep 5
    done
    sleep 10
    echo

    IP="$($CMD -t ws -gu $USER -gp $PASS getGuestIPAddress $VM)"
    echo "VM is running and has the IP Address: $IP"
    echo
}

clone_workstation_vm() {
    SOURCE=$1
    DESTINATION=$2
    SNAPSHOT=$3
    USER=$4
    PASS=$5

    SOURCEVMX="${SOURCE##*/}"
    SOURCEVMNAME="${SOURCEVMX%%.*}"
    NEWVM=/storage/virtual_machines/$DESTINATION/$DESTINATION.vmx

    echo "Cloning $SOURCEVMNAME to $DESTINATION and using the snapshot: $SNAPSHOT"
    $VMRUN -T ws -gu $USER -gp $PASS clone $SOURCE $NEWVM linked $SNAPSHOT

    sed -i "s/displayName = \"Clone of $SOURCEVMNAME\"/displayName = \"$DESTINATION\"/g" $NEWVM

    echo "Powering on $DESTINATION"
    $VMRUN -t ws -gu $USER -gp $PASS start $NEWVM

    wait_for_vmware_tools $VMRUN $USER $PASS $NEWVM

    echo "Copying script to change the hostname from the host to the guest"
    currentDir="${0%/*}"
    $VMRUN -t ws -gu $USER -gp $PASS copyFileFromHostToGuest $NEWVM $currentDir"/JH01_Set-Hostname.sh" /tmp/JH01_Set-Hostname.sh
    echo "Running custom script in $DESTINATION to set the hostname and rebooting"
    $VMRUN -t ws -gu $USER -gp $PASS runProgramInGuest $NEWVM /tmp/JH01_Set-Hostname.sh "$DESTINATION"

    wait_for_vmware_tools $VMRUN $USER $PASS $NEWVM

    echo "Copying output to local machine"
    $VMRUN -t ws -gu $USER -gp $PASS copyFileFromGuestToHost $NEWVM /var/log/oscustomization.log $currentDir"/"$DESTINATION"_Customization.log"
    echo
    echo "Below is the output from the OS Customization:"
    cat $currentDir"/"$DESTINATION"_Customization.log"

    wait_for_vm_ip $VMRUN $USER $PASS $NEWVM
}

start=`date +%s`

clone_workstation_vm $SOURCEVM $DESTINATIONVMNAME $SOURCESNAPSHOT $GUESTUSER $GUESTPASS

end=`date +%s`
runtime=$((end-start))

echo "Script took $runtime seconds to execute"</pre><p></p>
<p>The post <a href="/2018/11/27/thin-provision-vms-on-workstation-pro-using-the-vmrun-command/">Thin Provision VMs on Workstation Pro using the vmrun Command</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2018/11/27/thin-provision-vms-on-workstation-pro-using-the-vmrun-command/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Prompt For A New Hostname on Boot</title>
		<link>/2018/11/25/prompt-for-a-new-hostname-on-boot/</link>
					<comments>/2018/11/25/prompt-for-a-new-hostname-on-boot/#comments</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Mon, 26 Nov 2018 02:52:25 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=657</guid>

					<description><![CDATA[<p>I&#8217;ve been brushing up on a few technologies in my home lab, and have found myself using VMware workstation for some simple tasks that don&#8217;t require a whole virtualized environment. Workstation didn&#8217;t set the hostname of my Ubuntu 18.xx VMs properly after they booted. Maybe I&#8217;m a little spoiled by guest OS customization or missing [&#8230;]</p>
<p>The post <a href="/2018/11/25/prompt-for-a-new-hostname-on-boot/">Prompt For A New Hostname on Boot</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been brushing up on a few technologies in my home lab, and have found myself using VMware workstation for some simple tasks that don&#8217;t require a whole virtualized environment. Workstation didn&#8217;t set the hostname of my Ubuntu 18.xx VMs properly after they booted. Maybe I&#8217;m a little spoiled by guest OS customization or missing something, but either way, I needed a way to quickly spin up a whole VM and have it&#8217;s hostname set correctly. It&#8217;s definitely not the cleanest, and I realize I would be better off using the Workstation Pro REST API, but I&#8217;m not there yet.</p>
<p><span id="more-657"></span></p>
<p>We can do this pretty easily by adding a script to the /etc/profile.d directory. The script I&#8217;m currently using is below:</p><pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash
#file /etc/profile.d/VirtJunkie.com-set_hostname.sh
FLAG="/var/log/firstboot.flag"
if [ ! -f $FLAG ]; then
    echo "Server will reboot after this process completes"
    echo -n "Current hostname is $(hostname). Enter the new hostname and press [ENTER]: "
    read newhostname
    sudo hostnamectl set-hostname $newhostname

    #the next line creates an empty file so it won't run the next boot
    sudo touch $FLAG
    sudo reboot now
fi</pre><p>Just modify your parent image, clone your test VMs, and this will prompt you to set a new hostname the first time you log in.</p>
<p>The post <a href="/2018/11/25/prompt-for-a-new-hostname-on-boot/">Prompt For A New Hostname on Boot</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2018/11/25/prompt-for-a-new-hostname-on-boot/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Set Up A Headless Raspberry Pi</title>
		<link>/2018/10/04/set-up-a-headless-raspberry-pi/</link>
					<comments>/2018/10/04/set-up-a-headless-raspberry-pi/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Fri, 05 Oct 2018 01:38:41 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=650</guid>

					<description><![CDATA[<p>I find myself setting up Raspberry Pi&#8217;s more frequently than I&#8217;d like. I never ever have a monitor connected. Below is the method I use to get wireless network connectivity without connecting an Ethernet cable or a monitor and keyboard. This is here because I&#8217;m tired of sifting through incorrect articles to find this information. [&#8230;]</p>
<p>The post <a href="/2018/10/04/set-up-a-headless-raspberry-pi/">Set Up A Headless Raspberry Pi</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I find myself setting up Raspberry Pi&#8217;s more frequently than I&#8217;d like. I never ever have a monitor connected. Below is the method I use to get wireless network connectivity without connecting an Ethernet cable or a monitor and keyboard. This is here because I&#8217;m tired of sifting through incorrect articles to find this information.</p>
<p><span id="more-650"></span></p>
<ol>
<li>Download Raspbian and flash it to your SD card. Plenty of good guides out there, <a href="https://www.raspberrypi.org/documentation/installation/installing-images/README.md">but there&#8217;s nothing quite like the source</a>.</li>
<li>Mount the SD card to your machine and navigate to the boot directory</li>
<li>Create a blank file called &#8220;ssh&#8221; in the root of the boot partition</li>
<li>Create a new file called &#8220;wpa_supplicant.conf&#8221; and include the contents below. Replace [ssid] and [password] with the values pertaining to your network.</li>
<li>Safely unmount, and have fun!</li>
</ol>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

update_config=1
country=US

network={
ssid="[ssid]"
psk="[password]"
key_mgmt=WPA-PSK
}</pre><p>If you want more information on this process &#8211; check out the <a href="https://www.raspberrypi.org/documentation/configuration/wireless/headless.md">Raspbian documentation on a headless install</a>, and the <a href="https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md">wpa_supplicant documentation</a>.</p>
<p>Until next time,</p>
<p>Jon</p>
<p>The post <a href="/2018/10/04/set-up-a-headless-raspberry-pi/">Set Up A Headless Raspberry Pi</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2018/10/04/set-up-a-headless-raspberry-pi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Power Supply Need Calculator</title>
		<link>/2007/03/17/power-supply-need-calculator/</link>
					<comments>/2007/03/17/power-supply-need-calculator/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Sat, 17 Mar 2007 19:19:37 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://www.jonhoweonline.com/blog/node/116</guid>

					<description><![CDATA[<p>I decided to get a new case for my main computer today, and chose a micro atx case due to the fact that I&#8217;ve always had a big case and am sick of it&#8230; I realized that the small PSU&#8217;s that come with micro atx cases might not support my 3 HDDs and1 DVD+RW drive, [&#8230;]</p>
<p>The post <a href="/2007/03/17/power-supply-need-calculator/">Power Supply Need Calculator</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I decided to get a new case for my main computer today, and chose a micro atx case due to the fact that I&#8217;ve always had a big case and am sick of it&#8230;</p>
<p>I realized that the small PSU&#8217;s that come with micro atx cases might not support my 3 HDDs and1 DVD+RW drive, so I found a great PSU need calculator that I wanted to share.</p>
<p><a href="http://extreme.outervision.com/PSUEngine" title="Power Supply Calculator" target="_blank" rel="noopener">Here it is.</a></p>
<p>Jon</p>
<p>The post <a href="/2007/03/17/power-supply-need-calculator/">Power Supply Need Calculator</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2007/03/17/power-supply-need-calculator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SSH Local Port Forwarding Made Easy</title>
		<link>/2007/03/14/ssh-local-port-forwarding-made-easy/</link>
					<comments>/2007/03/14/ssh-local-port-forwarding-made-easy/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Wed, 14 Mar 2007 20:03:07 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Servers]]></category>
		<guid isPermaLink="false">http://www.jonhoweonline.com/blog/node/115</guid>

					<description><![CDATA[<p>I&#8217;ve been using this for a while now, and have found it a great little trick for accessing services that are blocked due to a firewall. It&#8217;s pretty simple, you just have a few parts to the command string.  The first command argument tells ssh to forward a local port (LP) to a remote machine [&#8230;]</p>
<p>The post <a href="/2007/03/14/ssh-local-port-forwarding-made-easy/">SSH Local Port Forwarding Made Easy</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been using this for a while now, and have found it a great little trick for accessing services that are blocked due to a firewall.</p>
<p>It&#8217;s pretty simple, you just have a few parts to the command string.  The first command argument tells ssh to forward a local port (LP) to a remote machine Remote) on a remote port (RP).  The second part is something you&#8217;re probably familiar with, the destination that you&#8217;re connecting to (Destination).</p>
<p>An example with the abbreviations above would be:</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">ssh -L LP:Remote:RP Destination</pre><p></p>
<p>Say for example, you ran the command &#8220;ssh -L 1234:myInternalServer.com:80 myExternalServer&#8221;.  In order to access port 80 on myInternalServer.com you&#8217;d open up your web browser and point it to  It&#8217;s as easy as that!</p>
<p>The post <a href="/2007/03/14/ssh-local-port-forwarding-made-easy/">SSH Local Port Forwarding Made Easy</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2007/03/14/ssh-local-port-forwarding-made-easy/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
