Is It Too Late To Invest In Cryptocurrencies? Not Even Close…And We’re Just Getting Started.

The best time to plant a tree was 20 years ago. The second best time is now. — Chinese Proverb
The best time to plant a tree was 20 years ago. The second best time is now. — Chinese Proverb

Plant Your Tree Now

Whenever cryptocurrencies are in a bull run, my friends, family, and coworkers reach out to me to ask whether they should invest. And like clockwork, whenever cryptocurrencies are bearish, those same friends, family, and coworkers usually make a comment or jab about how they’re glad that they didn’t invest because “Bitcoin just crashed again.”

Except, when looking at cryptocurrency charts from a 30,000-foot view, the “crash” price has been many times greater than the previous peak price, or all-time high (ATH).

What Cryptocurrency Geeks See

Ask a hundred Bitcoin enthusiasts to predict the future value of Bitcoin, and you’ll get a hundred different answers. But Bitcoin follows a fairly consistent channel pattern of breakout bull runs and bearish pullbacks and corrections.

There are countless charts, predictions, and strategies, but the following simple illustration shows where I personally believe that Bitcoin is headed.

This epoch chart was published on April 11, 2021, where light blue becomes dark blue in the Epoch 4 section. And it appears to have successfully predicted this week’s price pullback, which I have circled in red:

A speculative chart by Dion Guillaume projecting the future value of Bitcoin based on previous epochs.

It can be scary to look at daily volatility and 10% price swings but, for long-term investments, Über Holger’s Bitcoin Rainbow Price Chart illustrates Bitcoin’s history from a 30,000-foot view. While this chart was unscientifically created for fun, it does simply illustrate the concept of floors and ceilings of resistance.

And, if you think that this chart looks a bit squashed compared to the above epoch chart, then you’re correct. Note the logarithmic US dollar (USD) values on the vertical axis:

Über Holger created this logarithmic chart as a fun way of looking at long term price movements, disregarding the daily volatility “noise.” The original chart is interactive.

Do Not Take My Advice, and Don’t Overthink Things

I am not a financial advisor. Past performance is no guarantee of future results. Never invest money that you can’t afford to lose. Cryptocurrencies might be a fad, or could get regulated or banned into oblivion by governments. I am not suggesting that you invest in cryptocurrencies, because you might lose everything. Then again, you might lose everything investing in the stock market.

But, if you want to invest in Bitcoin, just do it. I invest in Bitcoin, not as a get rich quick scheme, or as a retirement fund, but because I truly believe in Bitcoin and other cryptocurrencies as a path to financial independence by eliminating reliance on conventional banks.

The emotional toll from investing in Bitcoin and other cryptocurrencies, however, is similar to investing in the stock market. Between FOMO and YOLO, it’s difficult to decide when to invest. Every time I’ve said to myself, “the price of Bitcoin is too high, I’ll wait to buy the next dip,” there’s been a bull run, and the price at the next dip is more expensive than the previous peak.

So my overly-simplified thought process is now:

If the price of Bitcoin is within or below the orange “Is this a bubble?” bar on the above rainbow chart, then I feel confident making impulse buys of a couple thousand dollars here and there.

But I also have automatic Dollar-Cost Averaging (DCA) buys that execute every week. So, regardless of price, every week one of my exchange accounts automatically buys $20 USD worth of Bitcoin and $20 USD worth of Ethereum.

This completely removes emotion from the investment process.

Resources To Get Started

Since it can take up to a month to get verified on cryptocurrency exchanges, I recommend signing up for services immediately, in advance of actually planning to invest anything.

Here are the resources that I rely on daily:

Cryptocurrency Exchanges

Hardware Wallets

Software Wallets

Cryptocurrency Portfolio Tracking and Capital Gains Taxes

Articles in This Series

  1. Attempting to Transfer Cash From My Checking Account to a Crypto Exchange Only Increased My Dislike of Banks, and Reinforced My Support for Cryptocurrencies Like Bitcoin
  2. Is It Too Late To Invest In Cryptocurrencies? Not Even Close…And We’re Just Getting Started.

Attempting to Transfer Cash From My Checking Account to a Crypto Exchange Only Increased My Dislike of Banks, and Reinforced My Support For Cryptocurrencies Like Bitcoin

Your Money Is Yours To Do With As You Please, As Long as You Keep It With Us

Consumer banking workflows appear to be designed to hoard as much client money as possible within a single institution, and to prevent consumers from moving their money elsewhere. I can instantly transfer as much cash as I want between affiliated institutions, such as between Bank of America and Merrill Lynch, or between TD Bank and TD Ameritrade.

As soon as I want to transfer cash to an unaffiliated institution, however, there are suddenly all sorts of transaction limits, identity verification requirements, verification windows, and fraud protection policies that prevent me from moving my money as I see fit.

For example, I’ve been a TD Bank customer for years, and I’ve had no problems moving tens of thousands of dollars from my TD Bank accounts to my TD Ameritrade accounts. I was even able to destructively close multiple TD Ameritrade accounts and merge them into a single consolidated account with a single click on their website.

But, as soon as I initiated a $5,000 USD ACH transfer from TD Bank to the Crypto.com exchange, my identity was suddenly in question, I had to call customer support to verify my identity, and my transfer had to be approved manually.

Even after jumping through the identity-verification hoops, I was told that it could take a multiple days for my transfer to be approved, so it might be a week before my funds appeared on the crypto exchange. Additionally, my ACH transfers were restricted to $2,500 USD per day, and $5,000 USD total per month.

When I inquired about immediately increasing my ACH transfer limits, I was told that it would take a minimum of six months to be approved for an ACH increase, even though I’d been a customer in good standing for years.

It’s Expensive to Not Be Rich

The ACH network recently increased their same-day transfer dollar limit from $25,000 USD to $100,000 USD, but consumer banks still limit their customers’ ability to transfer funds to a fraction of that limit. My $5,000 USD per month limit is generous; most TD Bank accounts have a limit of $3,000 USD per month.

I understand that wire transfers exist to move larger sums of cash, but wire transfers are expensive. A TD Bank wire transfer costs $30 USD. So, if I’m wire transferring $5,000 USD to a retirement account or a crypto exchange to bypass the ACH limit, then I’m already getting hit with over a half-percent loss on my investment just to move the funds. And that’s before any exchange fees or commissions.

Compare that to transferring Bitcoin — in January it cost a little under a dollar, and took less than two hours total, to transfer ~$160,000 USD from an Electrum software wallet to a hardware wallet.

Get Your Ducks in a Row

If you’re looking to transfer a large sum of cash for any reason, whether to pay down a loan, or to invest in conventional or crypto markets, prepare well in advance. Get your ducks in a row by signing up for all required accounts, finish the Know Your Client (KYC) identity verification for every account, and make sure that your funds have moved and settled, at least a month in advance.

Exchanges like Coinbase and Binance.US impose a 10-day cooldown on coins purchased with ACH-deposited fiat before they can be transferred to another exchange or wallet. Keep this in mind when depositing fiat to execute arbitrage between exchanges, or if you plan on immediately transferring purchased coins to a hardware wallet.

Additionally, many exchanges have degraded service or full outages during high-volatility periods, and many times you’ve missed buying the dip due to the amount of time it takes funds to deposit and settle.

The One-Month Crypto Investment Timeline

Entire books can be written about what’s involved with setting up crypto accounts, but expect it to take about a month to sign up for crypto accounts, and to get funds deposited and settled before you’re able to make your first crypto purchase, trade, or investment.

  • 2–10 days — Sign up for an account at all the crypto exchanges you think you might utilize, and immediately verify your identity. KYC identity verification will usually ask for photos of government-issued identification (such as driver’s license or passport), a selfie (sometimes holding a sheet of paper with the exchange’s name on it), social security number, and multiple-choice security questions.
  • 2–10 days — Set up ACH transfers at all the banks and crypto exchanges you think you might utilize, and verify those accounts. When configuring an outbound ACH from a bank to a crypto exchange, the bank will usually deposit two small amounts, and ask you to verify that you successfully received those amounts.
  • 2–14 days — Initiate ACH or wire transfers to fund your crypto exchange fiat account. These transfers may need to be manually approved by the bank.

It’s Hard (and Expensive) To Pay Off Loans Early

While not directly related to transferring cash to crypto exchanges, attempting to pay off loans early also exposes roadblocks to financial independence in the consumer banking system. While it’s been years since I was imposed a penalty for paying off a loan early, it can take weeks to transfer large sums of cash to a lender.

Even if you can afford to pay cash, conventional financial advice is to take out a loan to purchase a large asset, and to then invest your cash in something with a higher rate of return than the interest rate of the loan.

I bucked that usual financial advice last summer and, following the proverb of “a bird in the hand is worth two in the bush,” I decided to start paying down my mortgage and auto loan. The certainty of owning my home outright, contrasted by my high (by today’s standards) 4.125% mortgage interest rate, outweighed the potential growth of the crypto and stock markets. Investments are a gamble, but paying off debt is a sure thing.

So I initiated a $25,000 USD bill payment from Citizens Bank to Wells Fargo on the day of the month that I usually electronically pay my mortgage. After a few days, I received a message stating that my unusually-large electronic payment was delayed, and needed to be manually processed. A week later, my mortgage payment still hadn’t been processed, and the due date was fast approaching.

Begrudgingly, I initiated a second mortgage payment for $2,500 USD, which posted and applied to my mortgage within 24 hours. The initial $25,000 USD bill payment took another week to post, well after my due date, and I would have been imposed a late-payment fee had I not been carefully tracking my transfer.

And, when I finally pulled the trigger to pay off my auto loan in full, I had a similar wait for an ACH transfer to clear and settle.

My “Banking” Future

Once my mortgage is fully paid off, and I only have to worry about monthly incidentals, my end game is to abandon conventional checking and savings accounts altogether. My ideal financial workflow would be to have my payroll direct-deposited to a crypto exchange fiat wallet, diversify investments between various cryptocurrencies and conventional stocks and ETFs, and to utilize stock exchange cash sweep and crypto exchange fiat wallets in lieu of a checking account.

Crypto exchange staking-rewards debit cards could then be used in lieu of credit cards, only keeping enough coin and fiat on the exchange for incidentals, and then transferring all remaining crypto to hardware wallets or high-yield staking accounts.

Calculating capital gains tax becomes a no-brainer when utilizing services such as Cointracker.io that automatically track your entire crypto portfolio, including online exchanges, software wallets, and hardware wallets. The service even automatically differentiates income from receiving crypto payments, forks, and mining wallet deposits from gains/losses from trading and arbitrage.

Unfortunately, a conventional checking account would still be required to stage 1099-MISC payments, and to pay bills for vendors that don’t accept credit/debit cards or ACH transfers, but it’s only a matter of time before crypto exchanges start offering bill pay and mobile check deposit.

macos Big Sur 11.1 — ERROR: Failed to build gem native extension.

A while ago sudo gem update started throwing the following error:

ERROR: Failed to build gem native extension.

This wasn’t a big deal, as I wasn’t doing any any active ruby development, but it was still a minor annoyance. Missing directories reported in mkmf.log hinted at the cause:

ld: warning: directory not found for option '-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.Internal.sdk/usr/local/lib'

Searching for fixes resulted in a bunch of dangerous cargo-culted answers suggesting to curl -L https://get.rvm.io | bash -s stable and to then use rvm to update to the latest version of ruby. In other words — to trust that the code output from that website wasn’t malicious, and to blindly execute the code.

The actual solution, however, was much simpler (and didn’t require running any unknown code). It turns out that the Xcode Command Line Tools location isn’t always applied when updating Xcode. To check, simply open Xcode, and select Preferences → Locations.

If Command Line Tools is blank, or doesn’t match the currently-installed version of Xcode, then select the correct Xcode version from the dropdown menu:

That’s it. Easy, peasy, done! And the below errors are Google Juice to assist folks that are having similar issues:

Updating installed gems
Updating bigdecimal
Building native extensions. This could take a while...
ERROR:  Error installing bigdecimal:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/bigdecimal-3.0.0/ext/bigdecimal
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-1luy5zj.rb extconf.rb
checking RUBY_BIGDECIMAL_VERSION... 3.0.0
checking for labs() in stdlib.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:546:in `block in try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/tmpdir.rb:93:in `mktmpdir'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:543:in `try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:570:in `try_link'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:782:in `try_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1069:in `block in have_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1068:in `have_func'
	from extconf.rb:31:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/bigdecimal-3.0.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/bigdecimal-3.0.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/bigdecimal-3.0.0/gem_make.out
Updating date
Building native extensions. This could take a while...
ERROR:  Error installing date:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/date-3.1.1/ext/date
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-u08e31.rb extconf.rb
checking for timezone in time.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:802:in `try_var'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1091:in `block in have_var'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1090:in `have_var'
	from extconf.rb:6:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/date-3.1.1/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/date-3.1.1 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/date-3.1.1/gem_make.out
Updating etc
Building native extensions. This could take a while...
ERROR:  Error installing etc:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/etc-1.2.0/ext/etc
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-y7maqo.rb extconf.rb
checking for sys/utsname.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1109:in `block in have_header'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1108:in `have_header'
	from extconf.rb:6:in `block in <main>'
	from extconf.rb:5:in `each'
	from extconf.rb:5:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/etc-1.2.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/etc-1.2.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/etc-1.2.0/gem_make.out
Updating ffi
Building native extensions. This could take a while...
ERROR:  Error installing ffi:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/ffi-1.14.2/ext/ffi_c
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-224jk5.rb extconf.rb
checking for ffi.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
	--with-ffi_c-dir
	--without-ffi_c-dir
	--with-ffi_c-include
	--without-ffi_c-include=${ffi_c-dir}/include
	--with-ffi_c-lib
	--without-ffi_c-lib=${ffi_c-dir}/lib
	--enable-system-libffi
	--disable-system-libffi
	--with-libffi-config
	--without-libffi-config
	--with-pkg-config
	--without-pkg-config
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1109:in `block in have_header'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1108:in `have_header'
	from extconf.rb:10:in `system_libffi_usable?'
	from extconf.rb:42:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.14.2/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/ffi-1.14.2 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.14.2/gem_make.out
Updating fiddle
Building native extensions. This could take a while...
ERROR:  Error installing fiddle:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/fiddle-1.0.7/ext/fiddle
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-wsxvtp.rb extconf.rb
checking for ffi.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
	--enable-bundled-libffi
	--disable-bundled-libffi
	--with-libffi-dir
	--without-libffi-dir
	--with-libffi-include
	--without-libffi-include=${libffi-dir}/include
	--with-libffi-lib
	--without-libffi-lib=${libffi-dir}/lib
	--with-libffi-config
	--without-libffi-config
	--with-pkg-config
	--without-pkg-config
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1109:in `block in have_header'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1108:in `have_header'
	from extconf.rb:17:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/fiddle-1.0.7/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/fiddle-1.0.7 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/fiddle-1.0.7/gem_make.out
Updating irb
ERROR:  Error installing irb:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/io-console-0.5.6/ext/io/console
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-mhy66h.rb extconf.rb
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:852:in `macro_defined?'
	from extconf.rb:7:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/io-console-0.5.6/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/io-console-0.5.6 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/io-console-0.5.6/gem_make.out
Updating jekyll
ERROR:  Error installing jekyll:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-ipbh9a.rb extconf.rb
creating Makefile

current directory: /Library/Ruby/Gems/2.6.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR=" clean

current directory: /Library/Ruby/Gems/2.6.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR="
make: *** No rule to make target `/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/universal-darwin20/ruby/config.h', needed by `ruby_http_parser.o'.  Stop.

make failed, exit code 2

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/http_parser.rb-0.6.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/http_parser.rb-0.6.0/gem_make.out
Updating json
Building native extensions. This could take a while...
ERROR:  Error installing json:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/json-2.5.1/ext/json/ext/generator
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-t5kci9.rb extconf.rb
creating Makefile

current directory: /Library/Ruby/Gems/2.6.0/gems/json-2.5.1/ext/json/ext/generator
make "DESTDIR=" clean

current directory: /Library/Ruby/Gems/2.6.0/gems/json-2.5.1/ext/json/ext/generator
make "DESTDIR="
compiling generator.c
In file included from generator.c:1:
In file included from ./../fbuffer/fbuffer.h:5:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby.h:33:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/ruby.h:24:10: fatal error: 'ruby/config.h' file not found
#include "ruby/config.h"
         ^~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby/ruby.h:24:10: note: did not find header 'config.h' in framework 'ruby' (loaded from '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks')
1 error generated.
make: *** [generator.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/json-2.5.1 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/json-2.5.1/gem_make.out
Updating libxml-ruby
Building native extensions. This could take a while...
ERROR:  Error installing libxml-ruby:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/libxml-ruby-3.2.1/ext/libxml
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-xhczq.rb extconf.rb
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby: warning: shebang line ending with \r may cause problems
checking for libxml/xmlversion.h in /opt/include/libxml2,/opt/local/include/libxml2,/usr/local/include/libxml2,/usr/include/libxml2,/usr/local/include... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
	--with-xml2-config
	--without-xml2-config
	--with-xml2-dir
	--without-xml2-dir
	--with-xml2-include
	--without-xml2-include=${xml2-dir}/include
	--with-xml2-lib
	--without-xml2-lib=${xml2-dir}/lib
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1162:in `block in find_header'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1161:in `find_header'
	from extconf.rb:28:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/libxml-ruby-3.2.1/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/libxml-ruby-3.2.1 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/libxml-ruby-3.2.1/gem_make.out
Updating listen
ERROR:  Error installing listen:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1/ext/ffi_c
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-btb6k0.rb extconf.rb
checking for ffi.h... /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1109:in `block in have_header'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1108:in `have_header'
	from extconf.rb:10:in `system_libffi_usable?'
	from extconf.rb:42:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.13.1/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/ffi-1.13.1 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/ffi-1.13.1/gem_make.out
Updating openssl
Building native extensions. This could take a while...
ERROR:  Error installing openssl:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/openssl-2.2.0/ext/openssl
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-1yoyjh5.rb extconf.rb
checking for t_open() in -lnsl... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
	--with-openssl-dir
	--with-openssl-include
	--without-openssl-include=${openssl-dir}/include
	--with-openssl-lib
	--without-openssl-lib=${openssl-dir}/lib
	--with-kerberos-dir
	--without-kerberos-dir
	--with-kerberos-include
	--without-kerberos-include=${kerberos-dir}/include
	--with-kerberos-lib
	--without-kerberos-lib=${kerberos-dir}/lib
	--with-debug
	--without-debug
	--enable-debug
	--disable-debug
	--with-nsllib
	--without-nsllib
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:546:in `block in try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/tmpdir.rb:93:in `mktmpdir'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:543:in `try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:570:in `try_link'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:782:in `try_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1016:in `block in have_library'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1011:in `have_library'
	from extconf.rb:30:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/openssl-2.2.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/openssl-2.2.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/openssl-2.2.0/gem_make.out
Updating psych
Building native extensions. This could take a while...
ERROR:  Error installing psych:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/psych-3.3.0/ext/psych
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-1si57tx.rb extconf.rb
checking for yaml.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
	--with-libyaml-dir
	--without-libyaml-dir
	--with-libyaml-include
	--without-libyaml-include=${libyaml-dir}/include
	--with-libyaml-lib
	--without-libyaml-lib=${libyaml-dir}/lib
	--enable-bundled-libyaml
	--disable-bundled-libyaml
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1162:in `block in find_header'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1161:in `find_header'
	from extconf.rb:10:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/psych-3.3.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/psych-3.3.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/psych-3.3.0/gem_make.out
Updating reline
ERROR:  Error installing reline:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/io-console-0.5.6/ext/io/console
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-im8ypq.rb extconf.rb
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `block in try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:534:in `with_werror'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:585:in `try_compile'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:852:in `macro_defined?'
	from extconf.rb:7:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/io-console-0.5.6/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/io-console-0.5.6 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/io-console-0.5.6/gem_make.out
Updating stringio
Building native extensions. This could take a while...
ERROR:  Error installing stringio:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/stringio-3.0.0/ext/stringio
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-wmsbid.rb extconf.rb
checking for rb_io_extract_modeenc() in ruby/io.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:546:in `block in try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/tmpdir.rb:93:in `mktmpdir'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:543:in `try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:570:in `try_link'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:782:in `try_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1069:in `block in have_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1068:in `have_func'
	from extconf.rb:3:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/stringio-3.0.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/stringio-3.0.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/stringio-3.0.0/gem_make.out
Updating strscan
Building native extensions. This could take a while...
ERROR:  Error installing strscan:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/strscan-3.0.0/ext/strscan
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0 -r ./siteconf20210103-32419-vptjvg.rb extconf.rb
checking for onig_region_memsize() in ruby.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/$(RUBY_BASE_NAME)
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:546:in `block in try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/tmpdir.rb:93:in `mktmpdir'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:543:in `try_link0'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:570:in `try_link'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:782:in `try_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1069:in `block in have_func'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:331:in `open'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/mkmf.rb:1068:in `have_func'
	from extconf.rb:4:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/strscan-3.0.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Library/Ruby/Gems/2.6.0/gems/strscan-3.0.0 for inspection.
Results logged to /Library/Ruby/Gems/2.6.0/extensions/universal-darwin-20/2.6.0/strscan-3.0.0/gem_make.out
Gems updated: bigdecimal date etc ffi fiddle json libxml-ruby openssl psych stringio strscan

It’s Not a Conspiracy Theory—USPTO Just Doesn’t Like Facebook’s FBCLID URL Tracker

An acquaintance on Facebook was sharing some interesting information about the US Army’s Analysis and Assessment of Gateway Process. It was a fun read, and a few sections paralleled Maat Magik’s take on astral projection, and the binaural meditation tapes that my late father, who was an instructor for Dale Carnegie, had me listen to as a kid.

But one of the resources that they posted was a link to the United States Trademark and Patent Office…which promptly threw an error when clicking through from Facebook. Because of the error, they mused, “Looks like facebook isnt a fan of this .gov link to a real legal patent. Copy and paste in browser to see.”

This piqued my curiosity, so I inspected the URL:

http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL&p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=6506148.PN.&OS=PN%2F6506148&RS=PN%2F6506148&fbclid=REDACTED

My assumption was that Facebook was munging the URL somehow, so I replaced the instances of the URL-encoded hexadecimal “%2F” with a normal “/”:

http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL&p=1&u=/netahtml/PTO/srchnum.htm&r=1&f=G&l=50&s1=6506148.PN.&OS=PN/6506148&RS=PN/6506148&fbclid=REDACTED

Still no dice, and the website still threw an error. So I removed “&fbclid=REDACTED” from the end of the URL, and deep linking to the patent worked just fine.

Just for the heck of it, I added “&test=test” to the URL, and it promptly threw the error again. So USPTO is erring on the side of caution by sanitizing and rejecting all unexpected input. But, based on my completely unscientific study of a single individual, that strict error handling is possibly resulting in public mistrust, where folks may assume that either Facebook or USPTO is censoring content.

So I’ve put on my tinfoil hat, and I’ve reached out USPTO’s Electronic Business Center to report the issue. I’ve also let my acquaintance know that there was no greater conspiracy theory, and that the error was due to strict handling on USPTO’s side, and received a coveted like from them.

Nothing to see here, please move along…

How To Get Wi-Fi Working on a Dell XPS 13 9343 (Broadcom BCM4352) Running Ubuntu 20.10 (Groovy Gorilla)

The Dell XPS 13 9343 is the second-generation Sputnik Developer Edition laptop that came pre-loaded with Ubuntu 14.04 LTS (Trusty Tahr). As a former Canonical employee, I was one of the first lucky folks to put that machine into production. And now, over five years on, it’s still one of my favorite ultra-portable workhorse laptops. The only reason it’s no longer my primary Ubuntu machine is due to its paltry (by today’s standards) 8 GB RAM.

So, after picking up a new cyber security contract gig with Alpha Defense, I found myself in need of a dedicated triple-boot Ubuntu, Kali, and Tails sterile-environment machine for penetration testing. And, so I thought, what better way to resurrect the trusty Sputnik after upgrading its BIOS?

Unfortunately, Tails doesn’t support the Broadcom BCM4352 chipset. Per the Tails known-issues page, it is impossible for Tails to use any Wi-Fi card listed on Debian’s wl driver page since it’s proprietary.

But, when doing a fresh install of Ubuntu 20.10 (Groovy Gorilla), Ubuntu also failed to enable the Broadcom BCM4352 chipset, even though I had checked “Install third-party software for graphics and Wi-Fi hardware and additional media formats.”

With the help of the Ubuntu Help BCM43XX page, Wi-Fi was up and running within a few minutes, even with no Internet connection.

After inserting and mounting the Ubuntu 20.10 installation thumb drive:

cd /media/username/"Ubuntu 20.10 amd64"/pool/main/d/dkms
sudo dpkg -i dkms*
cd /media/username/"Ubuntu 20.10 amd64"/pool/main/f/fakeroot
sudo dpkg -i fakeroot*
cd /media/username/"Ubuntu 20.10 amd64"/pool/restricted/b/bcmwl
sudo dpkg -i bcmwl-kernel-source*

If you’re running with Secure Boot enabled, follow the on-screen instructions, and be sure to Enroll MOK when prompted on reboot.

I’m a bit surprised that Ubuntu 20.10 doesn’t support Wi-Fi out of the box on a machine that was certified and pre-installed with Ubuntu 14.04 LTS. But so be it, my favorite laptop is back up and running with a fresh install!

We Hire Bloggers Who Immediately Stop Blogging

Years ago in 2007, when I first joined Canonical as a staffer, I attended their yearly in-person all-hands meeting during my second week of employment. During the opening plenary, after the icebreaker where all new employees were asked to stand up and explain the history of their IRC pseudonym, the presenter lamented, “We hire bloggers who immediately stop blogging.”

The presenter then went on to talk about how many prospective candidates make it through to the final-round interviews because of their public open source contributions and blog entires. Which makes perfect sense! Ubuntu is open source. Canonical hires expert open source contributors. And what better way is there to promote your open source contributions than to blog about them!

But the comment about how new hires stop blogging really stayed with me. While working at Pepper before Canonical I used to blog daily here on Inert Ramblings and many other now-defunct platforms and forums. I blogged about everything from diet and exercise to tech industry news to photography and journalism.

I Immediately Stopped Blogging

Three months before my team was officially hired by Canonical, Pepper was contracted with Canonical for three months to work on the then-skunk works Ubuntu mobile project.

Everyone at Pepper, including myself, went heads-down with tighter deadlines and more intensive workloads. We found less time to work on our personal open source projects and endeavors. Which in turn led to less things to blog about. Even our after-hours personal time was now dedicated to Canonical projects.

Don’t get me wrong. This wasn’t a bad thing! I’m a geek. I have geek hobbies. Canonical was my dream job and my workload coincidentally paralleled my hobbies. So, for me, it was a win-win!

The only real difference was that I stopped blogging because I was so busy with work. I stopped posting to Inert Ramblings. I stopped posting to photography forums. I stopped posting to coding forums. I stopped posting to the social media platforms that were active at the time. I even stopped rally racing.

It’s not that the previous culture at Canonical dissuaded against blogging. It’s just that there was no incentive to blog anymore. If we were blogging then we weren’t working towards our deadlines. And, although Canonical management made the occasional comments wondering why folks stopped blogging, there was never an official company policy to promote blogging and make it part of our daily workflow.

Start your blogging engines!

Luckily, things changed a few years ago. Canonical holds quarterly product roadmap sprints for key managers and engineers. I organized most of these sprints and, during numerous plenary sessions over the past few years, upper management made it a point to encourage teams to blog about their non-proprietary projects.

Which is great! Canonical’s Ubuntu Blog started seeing more content and traffic. More content started appearing on employee personal blogs. News organizations started picking up stories based on employee blog entries. And, during every roadmap cycle, managers encouraged their employees to blog about what they’re working on.

And the community took notice! More blog content from Canonical and their employees started getting syndicated. My RSS reader is now filled with content from both the official Ubuntu Blog and personal employee blogs!

So, take note. Your company’s marketing team shouldn’t be your only outreach channel. Your employee’s personal blogs can be just as bolstering for your product and service offering!


Sean Sosik-Hamor is a former employee of Canonical. Working within Canonical’s IS Team Alpha Squad, Sean’s focus was end-to-end logistics, planning, implementation, and photography for corporate events, summits, conventions, data centers, facilities, equipment transport, and constructing offices and data centers.

He is currently entertaining offers for full-time positions within the photography, event, and data center fields.

Create Shell Scripts to Implement Your Own Local Fix for Poor App UI/UX

Repository: Sean Sosik-Hamor’s Snippets-Collection on GitHub.com – Newsvoice.com

I’ve recently started submitting summary posts to Newsvoice.com to expand my journalism portfolio for Hamor Photography in Pelham, NH.

But, like many web-based services, the web app doesn’t implement the same feature set as the smartphone app and vice versa. More frustratingly, neither app seems to allow editors to view a list of their submitted story links or their summaries pending moderation.

So I’ve hacked together a quick shell script to find the latest published summary URL on Newsvoice.com, iterate from that URL through a list of all recently-submitted summaries (both published and unpublished), and do a case-insensitive search for a single-word string that appears in your latest submitted title.

That way, as soon as you submit the links and title, you can immediately find the URL to your unmoderated story links page and submit your summary for moderation before another contributor claims it!

And, once the story links page is is approved by moderators, the script will also find all other stories that link to the page.

Unless I’m overlooking some obvious functionality during the submission process the workflow seems to entail:

  1. Submit multiple links for a news story from different reputable news sources with differing views, opinions, or biases.
  2. Create a short, unbiased, factual title to describe the story links.
  3. Wait for your links and title to be approved by moderators.
  4. Tap the approval notification that’s pushed to your smartphone.
  5. Create an unbiased summary of the story.
  6. Wait for your summary to be approved by moderators.
  7. The final story with summary and links will publish publicly on the Newsvoice front page or channel page once approved my moderators.

It sounds pretty straightforward. But things get frustrating going into step 4.

Once the links are approved by moderators anyone can claim the story links and write their own unbiased summary of the story. Like Wikipedia, shared editing with public accountability is the whole point of Newsvoice. But the only approval notice that you receive is via the single push notification on your smartphone.

When you tap the notification it permanently disappears. If you unlock your smartphone without tapping the notification, and the Newsvoice app was the last app that you used, then the notification permanently disappears without displaying the approved story links screen within the app.

Either way, if you forget to save the approved story links page in the smartphone app once you tap the notification, then you can’t find it again. And, since you’re not given the story ID or URL, you can’t find the story links page through the web app either.

And that’s not even taking into consideration that trying to write summaries on a tiny smartphone screen is less than ideal.

It could take a couple hours for the links to show up as a published story links page with no summary and, in the meantime, someone else could click claim.

So far I’m a fan of the idea of the Newsvoice platform. The more I use the platform as a non-moderator contributor the more frustrated I become. It should also be noted that, any time I’ve submitted more than two links to a story, only one or two links are approved. Other summary pages may show a dozen or more links so my assumption is only links submitted by multiple contributors (or merged pages) display more than a link or two.

Updated Sunday, July 26, 2020 to fix a typo, reorder paragraphs, and add a conclusion paragraph.

Configuring a TFTP server on Ubuntu for switch upgrades and maintenance

Note: Community TFTP documentation is on the Ubuntu Wiki but this short guide adds extra steps to help secure and safeguard your TFTP server.

Every Data Centre Engineer should have a TFTP server somewhere on their network whether it be running on a production host or running on their own notebook for disaster recovery. And since TFTP is lightweight without any user authentication care should be taken to prevent access to or overwriting of critical files.

The following example is similar to the configuration I run on my personal Ubuntu notebook and home Ubuntu servers. This allows me to do switch firmware upgrades and backup configuration files regardless of environment since my notebook is always with me.

Step 1: Install TFTP and TFTP server

$ sudo apt update; sudo apt install tftp-hpa tftpd-hpa

Step 2: Configure TFTP server

The default configuration below allows switches and other devices to download files but, if you have predictable filenames, then anyone can download those files if you configure TFTP Server on your notebook. This can lead to dissemination of copyrighted firmware images or config files that may contain passwords and other sensitive information.

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure"

Instead of keeping any files directly in the /var/lib/tftpboot base directory I’ll use mktemp to create incoming and outgoing directories with hard-to-guess names. This prevents guessing common filenames.

First create an outgoing directory owned by root mode 755. Files in this directory should be owned by root to prevent unauthorized or accidental overwriting. You wouldn’t want your expensive Cisco IOS firmware image accidentally or maliciously overwritten.

$ cd /var/lib/tftpboot
$ sudo chmod 755 $(sudo mktemp -d XXXXXXXXXX --suffix=-outgoing)

Next create incoming directory owned by tftp mode 700 . This allows tftpd-hpa to create files in this directory if configured to do so.

$ sudo chown tftp:tftp $(sudo mktemp -d XXXXXXXXXX --suffix=-incoming)
$ ls -1
ocSZiwPCkH-outgoing
UHiI443eTG-incoming

Configure tftpd-hpa to allow creation of new files. Simply add –create to TFTP_OPTIONS in /etc/default/tftpd-hpa.

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"

And lastly restart tftpd-hpa.

$ sudo /etc/init.d/tftpd-hpa restart
[ ok ] Restarting tftpd-hpa (via systemctl): tftpd-hpa.service.

Step 3: Firewall rules

If you have a software firewall enabled you’ll need to allow access to port 69/udp. Either add this rule to your firewall scripts if you manually configure iptables or run the following UFW command:

$ sudo ufw allow tftp

Step 4: Transfer files

Before doing a firmware upgrade or other possibly destructive maintenance I always backup my switch config and firmware.

cisco-switch#copy running-config tftp://192.168.0.1/UHiI443eTG-incoming/config-cisco-switch
Address or name of remote host [192.168.0.1]? 
Destination filename [UHiI443eTG-incoming/config-cisco-switch]? 
 
 !!
3554 bytes copied in 0.388 secs (9160 bytes/sec)
cisco-switch#copy flash:?
flash:c1900-universalk9-mz.SPA.156-3.M2.bin flash:ccpexp flash:cpconfig-19xx.cfg flash:home.shtml
flash:vlan.dat

cisco-switch#copy flash:c1900-universalk9-mz.SPA.156-3.M2.bin tftp://192.168.0.1/UHiI443eTG-incoming/c1900-universalk9-mz.SPA.156-3.M2.bin 
Address or name of remote host [192.168.0.1]? 
Destination filename [UHiI443eTG-incoming/c1900-universalk9-mz.SPA.156-3.M2.bin]? 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
85258084 bytes copied in 172.692 secs (493700 bytes/sec)

Files in incoming will be owned by tftp mode 666 (world writable) by default. Remember to move those files to your outgoing directory and change ownership to root mode 644 for safe keeping.

Once you’re sure your switch config and firmware is safely backed up it’s safe to copy new firmware to flash or do any other required destructive maintenance.

Step 5: Prevent TFTP access

It’s good practice on a notebook to deny services when not actively in-use. Assuming you have a software firewall be sure to deny access to your TFTP server when on the road or when connected to hostile networks.

$ sudo ufw deny tftp
Rule updated
Rule updated (v6)
$ sudo ufw status
Status: active

To Action From
-- ------ ----
CUPS ALLOW Anywhere 
OpenSSH DENY Anywhere 
69/udp DENY Anywhere 
CUPS (v6) ALLOW Anywhere (v6) 
OpenSSH (v6) DENY Anywhere (v6) 
69/udp (v6) DENY Anywhere (v6)

Is Google Chrome running obscenely slow on your obscenely expensive Mac Pro or Retina MacBook Pro with 4K or UHD monitor? Fear not…

My shiny Mac Pro just arrived along with a pair of Dell 28 Ultra HD (P2815Q) Monitors (2160p). I anxiously plugged everything in, fired up Google Chrome, and waited…and waited…and waited…and waited. The dreaded spinning pinwheel of death greeted me and it took minutes for each page to load. Not even the chrome://settings/ or chrome://version/ pages would load. Chrome was basically unusable.

Odd, since everything was running fine when I had the Mac Pro plugged into my Sony R550A 60″ HDTV (1080p). I begrudgingly switched to Safari and started to do some digging.

Turns out the latest Chrome Stable and Chrome Beta (as of 13-Mar-2014) eat themselves right in the face when plugged into 4K or UHD displays. I’m unable to find a specific bug report but I did manage to find a single general complaint thread in the Google Product Forums from Oct/Nov 2013. Turns out I’m not the only one experiencing this problem.

Luckily the problem has been fixed in the latest Chrome Dev 35.0.1883.0 and Chrome Canary 35.0.1888.0 builds so just download either of those versions. Chrome now completely screams on the Mac Pro.

Version information: Mac Pro Late 2013 MacPro6,1 running Mac OS X 10.9.2 Mavericks.

Wi-Fi regulatory domains are a pain

Managing multiple facilities across multiple continents can be a pain especially when Wi-Fi is involved. Different regions use different frequencies depending on regulatory domain. And, depending on your hardware vendor, compliant hardware could be backordered.

In my case, the Cisco Aironet 1140 Series Access Point (AIR-AP1142N-T-K9 802.11a/g/n Standalone AP; Int Ant; Taiwan C) is backordered by 4-6 weeks. I guess our Taipei 101 office is out of luck for a while unless I can find a different piece of compliant hardware.

Here are some miscellaneous regulatory notes for when I need to revisit this in the future:

Everything worth saying has already been said…