<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Nahum Shalman]]></title><description><![CDATA[Open Source Software: Operating Systems and Beyond.]]></description><link>https://blog.shalman.org/</link><image><url>https://blog.shalman.org/favicon.png</url><title>Nahum Shalman</title><link>https://blog.shalman.org/</link></image><generator>Ghost 5.46</generator><lastBuildDate>Fri, 17 Oct 2025 15:48:40 GMT</lastBuildDate><atom:link href="https://blog.shalman.org/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Triton on SmartOS bhyve]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h1 id="motivation">Motivation</h1>
<p>I (still) don&apos;t run VMware but I do have a SmartOS machine (it&apos;s a little nicer than the one from a decade ago).<br>
I now work on Triton for my day job and I want to run CoaL for some testing.</p>
<h1 id="networking">Networking</h1>
<p>The first trick</p>]]></description><link>https://blog.shalman.org/triton-on-smartos-bhyve/</link><guid isPermaLink="false">686f046122be109cb43b35dd</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Thu, 10 Jul 2025 00:34:24 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h1 id="motivation">Motivation</h1>
<p>I (still) don&apos;t run VMware but I do have a SmartOS machine (it&apos;s a little nicer than the one from a decade ago).<br>
I now work on Triton for my day job and I want to run CoaL for some testing.</p>
<h1 id="networking">Networking</h1>
<p>The first trick is going to be to get some appropriate network tags set up and configured in the way that the CoaL image expects. I&apos;m going to set up both an admin network and an &quot;external&quot; network. The latter will perform the same NAT that gets configured by the scripts for use with VMware.</p>
<h2 id="admin-network">Admin network.</h2>
<p>This is a private network that doesn&apos;t need to reach the internet. Since I&apos;ll be confining my experiments to a single SmartOS hypervisor I&apos;ll just use an etherstub:</p>
<pre><code>nictagadm add -l sdc_admin0
</code></pre>
<h2 id="external-network">External network.</h2>
<p>This one is tricker. CoaL expects this to be a network that can reach the network via NAT. We&apos;ll create another etherstub for it, then we&apos;ll create a  zone to do <a href="https://wiki.smartos.org/display/DOC/NAT+using+Etherstubs?ref=blog.shalman.org">NAT using Etherstubs</a>:</p>
<pre><code>nictagadm add -l sdc_external0
</code></pre>
<p>Provision a zone to be the NAT router using the following json (you can use whatever image_uuid you want, it doesn&apos;t actually matter):<br>
<code>coal-nat.json</code></p>
<pre><code class="language-json">{
  &quot;alias&quot;: &quot;coal-nat&quot;,
  &quot;hostname&quot;: &quot;coal-nat&quot;,
  &quot;brand&quot;: &quot;joyent-minimal&quot;,
  &quot;max_physical_memory&quot;: 128,
  &quot;image_uuid&quot;: &quot;2f1dc911-6401-4fa4-8e9d-67ea2e39c271&quot;,
  &quot;nics&quot;: [
    {
      &quot;nic_tag&quot;: &quot;external&quot;,
      &quot;ip&quot;: &quot;dhcp&quot;,
      &quot;allow_ip_spoofing&quot;: &quot;1&quot;,
      &quot;primary&quot;: &quot;1&quot;
    },
    {
      &quot;nic_tag&quot;: &quot;sdc_external0&quot;,
      &quot;ip&quot;: &quot;10.88.88.2&quot;,
      &quot;netmask&quot;: &quot;255.255.255.0&quot;,
      &quot;allow_ip_spoofing&quot;: &quot;1&quot;,
      &quot;gateway&quot;: &quot;10.88.88.2&quot;
    }
  ],
  &quot;customer_metadata&quot; : {
    &quot;manifests&quot; : &quot;network/forwarding.xml\nnetwork/routing/route.xml\nnetwork/routing/ripng.xml\nnetwork/routing/legacy-routing.xml\nnetwork/ipfilter.xml\nsystem/identity.xml\n&quot;,
    &quot;smf-import&quot; : &quot;mdata-get manifests | while read name; do svccfg import /lib/svc/manifest/$name; done;&quot;,
    &quot;user-script&quot; : &quot;mdata-get smf-import | bash -x; echo -e &apos;map net0 10.88.88.0/24 -&gt; 0/32\nrdr net0 0/0 port 22 -&gt; 10.88.88.200 port 22 tcp&apos; &gt; /etc/ipf/ipnat.conf; routeadm -u -e ipv4-forwarding; svcadm enable identity:domain; svcadm enable ipfilter&quot;
  }
}
</code></pre>
<p>You can also set a static IP address on the first NIC if you prefer.</p>
<p>Create the zone:</p>
<pre><code>vmadm create -f coal-nat.json
</code></pre>
<h1 id="building-the-headnode-vm">Building the headnode VM</h1>
<p>Normally SmartOS provides a lot of protection on the vnics. We&apos;ll be turning them all off so that the guest can do whatever it wants. This is one of the reasons I like setting up the etherstubs. Even if this VM runs amok the only other zone it can reach is that very minimal NAT zone.</p>
<p>We need to specify the hardcoded MAC addresses that the answers.json file is expecting to see as well:<br>
<code>coal-headnode.json</code>:</p>
<pre><code class="language-json">{
  &quot;alias&quot;: &quot;coal-headnode&quot;,
  &quot;brand&quot;: &quot;bhyve&quot;,
  &quot;bootrom&quot;: &quot;uefi&quot;,
  &quot;ram&quot;: 16384,
  &quot;vcpus&quot;: 4,
  &quot;autoboot&quot;: false,
  &quot;nics&quot;: [
    {
      &quot;mac&quot;: &quot;00:50:56:34:60:4c&quot;,
      &quot;nic_tag&quot;: &quot;sdc_admin0&quot;,
      &quot;model&quot;: &quot;virtio&quot;,
      &quot;ip&quot;: &quot;dhcp&quot;,
      &quot;allow_dhcp_spoofing&quot;: true,
      &quot;allow_ip_spoofing&quot;: true,
      &quot;allow_mac_spoofing&quot;: true,
      &quot;allow_restricted_traffic&quot;: true,
      &quot;allow_unfiltered_promisc&quot;: true,
      &quot;dhcp_server&quot;: true
    },
    {
      &quot;mac&quot;: &quot;00:50:56:3d:a7:95&quot;,
      &quot;nic_tag&quot;: &quot;sdc_external0&quot;,
      &quot;model&quot;: &quot;virtio&quot;,
      &quot;ip&quot;: &quot;dhcp&quot;,
      &quot;allow_dhcp_spoofing&quot;: true,
      &quot;allow_ip_spoofing&quot;: true,
      &quot;allow_mac_spoofing&quot;: true,
      &quot;allow_restricted_traffic&quot;: true,
      &quot;allow_unfiltered_promisc&quot;: true,
      &quot;dhcp_server&quot;: true
    }
  ],
  &quot;disks&quot;: [
    {
      &quot;boot&quot;: true,
      &quot;size&quot;: 8192,
      &quot;model&quot;: &quot;virtio&quot;
    },
    {
      &quot;size&quot;: 65440,
      &quot;model&quot;: &quot;virtio&quot;
    }
  ]
}
</code></pre>
<p>Create the VM and get the UUID:</p>
<pre><code>vmadm create -f coal-headnode.json
UUID=$(vmadm list -H -o uuid alias=coal-headnode)
</code></pre>
<h2 id="copying-over-the-coal-usb-stick-image">Copying over the CoaL USB stick image</h2>
<p>Triton releases live at <a href="https://us-central.manta.mnx.io/Joyent_Dev/public/SmartDataCenter/triton.html?ref=blog.shalman.org">https://us-central.manta.mnx.io/Joyent_Dev/public/SmartDataCenter/triton.html</a></p>
<pre><code>zfs set refreservation=0 zones/${UUID}/disk0

RELEASE=release-20250724-20250724T033959Z-gb8f2d08
curl -fLO https://us-central.manta.mnx.io/Joyent_Dev/public/SmartDataCenter/${RELEASE?}/headnode/usb-${RELEASE?}.tgz
tar xvf usb-${RELEASE?}.tgz usb-${RELEASE?}-8gb.img
qemu-img convert -f raw -O host_device usb-${RELEASE?}-8gb.img /dev/zvol/dsk/zones/${UUID?}/disk0

zfs snapshot zones/${UUID?}/disk0@sdc-pristine
zfs snapshot zones/${UUID?}/disk1@sdc-pristine
</code></pre>
<h2 id="pre-configuring-triton">Pre-configuring Triton</h2>
<p>We need to obtain the CoaL answers.json file and reconfigure Loader so that it will behave correctly in the VM.</p>
<pre><code>lofiadm -l -a /dev/zvol/dsk/zones/${UUID?}/disk0
mount -F pcfs /devices/pseudo/lofi@2:c /mnt
curl -kL https://raw.githubusercontent.com/tritondatacenter/sdc-headnode/master/answers.json.tmpl.external | sed &apos;s/vga/ttya/g&apos; &gt; /mnt/private/answers.json
cp /mnt/boot/loader.conf /mnt/boot/loader.conf.orig
cat /mnt/boot/loader.conf.orig | sed &apos;/hash_name=/d;/console/s/ttyb/ttya/;/console/s/,.*text/,text/;/tty[^a]-mode/d;s/ipxe=&quot;true&quot;/ipxe=&quot;false&quot;/&apos; &gt; /mnt/boot/loader.conf
umount /mnt
lofiadm -d /dev/lofi/2
zfs snapshot zones/${UUID?}/disk0@configured
</code></pre>
<p>Optional: Get a performance boost at the cost of potential VM data corruption if the host loses power:</p>
<pre><code>zfs set sync=disabled zones/${UUID?}
</code></pre>
<p>Now you&apos;re ready to boot your VM.</p>
<pre><code>vmadm start ${UUID?} ; vmadm console ${UUID?}
</code></pre>
<h1 id="adding-a-compute-node">Adding a Compute Node</h1>
<p>For the moment I don&apos;t have a great answer to how to make the Compute Node PXE boot. This is my current workaround:</p>
<p><code>coal-computenode.json</code>:</p>
<pre><code class="language-json">{
  &quot;alias&quot;: &quot;coal-computenode&quot;,
  &quot;brand&quot;: &quot;bhyve&quot;,
  &quot;bootrom&quot;: &quot;uefi&quot;,
  &quot;ram&quot;: 4096,
  &quot;vcpus&quot;: 4,
  &quot;autoboot&quot;: false,
  &quot;nics&quot;: [
    {
      &quot;nic_tag&quot;: &quot;sdc_admin0&quot;,
      &quot;model&quot;: &quot;virtio&quot;,
      &quot;ip&quot;: &quot;dhcp&quot;,
      &quot;allow_dhcp_spoofing&quot;: true,
      &quot;allow_ip_spoofing&quot;: true,
      &quot;allow_mac_spoofing&quot;: true,
      &quot;allow_restricted_traffic&quot;: true,
      &quot;allow_unfiltered_promisc&quot;: true,
      &quot;dhcp_server&quot;: true
    },
    {
      &quot;nic_tag&quot;: &quot;sdc_external0&quot;,
      &quot;model&quot;: &quot;virtio&quot;,
      &quot;ip&quot;: &quot;dhcp&quot;,
      &quot;allow_dhcp_spoofing&quot;: true,
      &quot;allow_ip_spoofing&quot;: true,
      &quot;allow_mac_spoofing&quot;: true,
      &quot;allow_restricted_traffic&quot;: true,
      &quot;allow_unfiltered_promisc&quot;: true,
      &quot;dhcp_server&quot;: true
    }
  ],
  &quot;disks&quot;: [
    {
      &quot;boot&quot;: true,
      &quot;media&quot;: &quot;cdrom&quot;,
      &quot;path&quot;: &quot;/ipxe/ipxe.iso&quot;,
      &quot;model&quot;: &quot;virtio&quot;
    },
    {
      &quot;size&quot;: 16000,
      &quot;model&quot;: &quot;virtio&quot;
    }
  ]
}
</code></pre>
<p>Create the VM and get the UUID, then inject a usable ipxe ISO for netbooting:</p>
<pre><code>CN_UUID=$(vmadm create -f coal-computenode.json 2&gt;&amp;1 |tee /dev/stderr | awk &apos;END{print $NF}&apos;)
mkdir -p /zones/${CN_UUID?}/root/ipxe
curl -fL -o /zones/${CN_UUID?}/root/ipxe/ipxe.iso https://raw.githubusercontent.com/tinkerbell/ipxedust/refs/heads/main/binary/ipxe.iso
vmadm start ${CN_UUID?} ; vmadm console ${CN_UUID?}
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Tailscale for SunOS in 2025]]></title><description><![CDATA[<p>Happy New Year! The <a href="https://github.com/nshalman/wireguard-go?ref=blog.shalman.org">wireguard-go</a> port is still sitting around in my fork. I don&apos;t know when I will have the energy for the next attempt to get it upstream. In the meantime, I&apos;ve made some fun progress on the <a href="https://github.com/tailscale/tailscale/?ref=blog.shalman.org">Tailscale</a> side.</p><h1 id="taildrive">Taildrive</h1><p>The Tailscale folks</p>]]></description><link>https://blog.shalman.org/tailscale-for-sunos-in-2025/</link><guid isPermaLink="false">67851aa38bb7ad9cd4c2a21c</guid><category><![CDATA[illumos]]></category><category><![CDATA[tailscale]]></category><category><![CDATA[wireguard]]></category><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Mon, 13 Jan 2025 14:47:52 GMT</pubDate><content:encoded><![CDATA[<p>Happy New Year! The <a href="https://github.com/nshalman/wireguard-go?ref=blog.shalman.org">wireguard-go</a> port is still sitting around in my fork. I don&apos;t know when I will have the energy for the next attempt to get it upstream. In the meantime, I&apos;ve made some fun progress on the <a href="https://github.com/tailscale/tailscale/?ref=blog.shalman.org">Tailscale</a> side.</p><h1 id="taildrive">Taildrive</h1><p>The Tailscale folks have shipped <a href="https://tailscale.com/kb/1369/taildrive?ref=blog.shalman.org">Taildrive</a> (currently in alpha) and it&apos;s pretty neat. Naturally those of us using Tailscale on illumos wanted to try it out. There was nothing needed directly to get it working, but we had an indirect problem. The tailscale binary communicates with the tailscaled daemon over a unix socket, and the Tailscale folks had added some basic unix based authentication / authorization abstracted in their <a href="https://github.com/tailscale/peercred?ref=blog.shalman.org">peercred</a> library. That library needed support added for <a href="https://illumos.org/man/3C/getpeerucred?ref=blog.shalman.org">getpeerucred</a> which meant I had to <a href="https://go-review.googlesource.com/c/sys/+/639755?ref=blog.shalman.org">wire things up all the way down in x/sys/unix</a> before then <a href="https://github.com/tailscale/peercred/pull/10?ref=blog.shalman.org">getting it into peercred</a>. But with that work done, Taildrive now works! <a href="https://github.com/nshalman/tailscale/releases/tag/v1.78.1-taildrive-sunos?ref=blog.shalman.org">I tagged a release with that enabled if you&apos;re in a rush to play with it.</a></p><h1 id="using-userspace-networking">Using userspace-networking</h1><p>Tailscale has a way to run without creating a TUN device. It means that client software on the machine can&apos;t connect directly to IPs on the Tailnet (though there is a <a href="https://blog.shalman.org/ssh-socks-proxy-but-its-tailscale/">SOCKS proxy</a> you can use) but tailscaled can still lots of other server-y things (including Taildrive!) That&apos;s how Tailscale has been supporting AIX. Which led me to a strange realization: Tailscale had better in-tree support for AIX than it did for illumos and Solaris. No more! <a href="https://github.com/tailscale/tailscale/pull/14571?ref=blog.shalman.org">We are now on-par with AIX in the official tree!</a></p><h1 id="whats-next">What&apos;s next</h1><p>I don&apos;t know if the Tailscale folks intend to ship binaries for us from their tree, but after their next release it should be possible to build illumos binaries from their tree that you could use to serve up a ZFS filesystem with Taildrive to your tailnet using the userspace-networking driver.</p><p>I will of course also rebase my TUN driver patches and tag a release as well.</p><p>Are you running Tailscale on illumos or Solaris? Let me know on <a href="https://bsky.app/profile/nahum.shalman.org?ref=blog.shalman.org">Bluesky</a> or <a href="https://hachyderm.io/@nahumshalman?ref=blog.shalman.org">Mastodon</a>.</p>]]></content:encoded></item><item><title><![CDATA[OpenTelemetry Tracing for Dropshot]]></title><description><![CDATA[<p>I spoke at <a href="https://oxide.computer/?ref=blog.shalman.org">Oxide</a>&apos;s dtrace.conf(24) about a project I&apos;ve been hacking on for the past couple weeks:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/P81LhhtIsQ0?list=PLaakI37KgzsE98Tp-8wV-1MKXw4qm5Y1c" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>Slides:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://docs.google.com/presentation/d/1AW_ugVrmkXDTROgPbEt7bCLrLhFo8-z13PoJAdfPO78?ref=blog.shalman.org"><div class="kg-bookmark-content"><div class="kg-bookmark-title">OpenTelemetry Tracing for Dropshot</div><div class="kg-bookmark-description">OpenTelemetry Tracing for Dropshot Nahum Shalman The QR code links to this presentation for anyone who wants to read the speaker notes</div></div></a></figure>]]></description><link>https://blog.shalman.org/opentelemetry-tracing-for-dropshot/</link><guid isPermaLink="false">6761af0f8bb7ad9cd4c2a0e3</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Tue, 17 Dec 2024 17:08:32 GMT</pubDate><content:encoded><![CDATA[<p>I spoke at <a href="https://oxide.computer/?ref=blog.shalman.org">Oxide</a>&apos;s dtrace.conf(24) about a project I&apos;ve been hacking on for the past couple weeks:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/P81LhhtIsQ0?list=PLaakI37KgzsE98Tp-8wV-1MKXw4qm5Y1c" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></figure><p>Slides:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://docs.google.com/presentation/d/1AW_ugVrmkXDTROgPbEt7bCLrLhFo8-z13PoJAdfPO78?ref=blog.shalman.org"><div class="kg-bookmark-content"><div class="kg-bookmark-title">OpenTelemetry Tracing for Dropshot</div><div class="kg-bookmark-description">OpenTelemetry Tracing for Dropshot Nahum Shalman The QR code links to this presentation for anyone who wants to read the speaker notes or reread them later. 1 github.com/nshalman</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://ssl.gstatic.com/docs/presentations/images/favicon-2023q4.ico" alt><span class="kg-bookmark-author">Google Docs</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://lh7-us.googleusercontent.com/docs/AHkbwyIV_ejpISEm1fphc4pvL3iefYRyfRQXTNkxcLV2xUlL5suUlgCzTJ6lnlVHxFTybNqYNiZT-SvcC-5vMql12EFwyHhiIwl0yF10S00_SoUAYUoHdtQ=w1200-h630-p" alt></div></a></figure><p>Code:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/oxidecomputer/dropshot/pull/1201?ref=blog.shalman.org"><div class="kg-bookmark-content"><div class="kg-bookmark-title">[DRAFT - DO NOT MERGE] Basic OpenTelemetry integration by nshalman &#xB7; Pull Request #1201 &#xB7; oxidecomputer/dropshot</div><div class="kg-bookmark-description">OpenTelemetry for DropshotThis is still very much a rough draft, but I want it to be clearly available for anyone interested.Checklist of things that are needed (note that much of it is currently&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.com/fluidicon.png" alt><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">oxidecomputer</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/e2883a0f6ad3fab8db58856fe5c8f022269f7a3237b393bd119949cb667705db/oxidecomputer/dropshot/pull/1201" alt></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Tragedy Older Than Me]]></title><description><![CDATA[<p>In July of 2021, in anticipation of the upcoming <a href="https://en.wikipedia.org/wiki/High_Holy_Days?ref=blog.shalman.org">High Holy Days</a> I purchased a copy of <em><a href="This Is Real and You Are Completely Unprepared: The Days of Awe as a Journey of Transformation">This Is Real and You Are Completely Unprepared: The Days of Awe as a Journey of Transformation</a></em> by Rabbi Alan Lew, published in 2003. I was in fact completely unprepared to even read</p>]]></description><link>https://blog.shalman.org/tragedy-older-than-me/</link><guid isPermaLink="false">6761f1e78bb7ad9cd4c2a101</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Mon, 07 Oct 2024 14:24:00 GMT</pubDate><content:encoded><![CDATA[<p>In July of 2021, in anticipation of the upcoming <a href="https://en.wikipedia.org/wiki/High_Holy_Days?ref=blog.shalman.org">High Holy Days</a> I purchased a copy of <em><a href="This Is Real and You Are Completely Unprepared: The Days of Awe as a Journey of Transformation">This Is Real and You Are Completely Unprepared: The Days of Awe as a Journey of Transformation</a></em> by Rabbi Alan Lew, published in 2003. I was in fact completely unprepared to even read it. It sat in or on my nightstand for more than three years. I finally started reading it during the high holidays in October of 2024 (a few days before the one year anniversary of the events of October 7, 2023).</p><p>When I read the section excerpted here, I had to immediately flip back to check the publication date. 2003. In so many ways the ongoing tragedy today is in the same place it was over 20 years ago. Rabbi Lew died in 2009. We cannot ask him what he thinks of the world today, but in many ways there is no need. Little has changed. So, to emphasize one more time, let&apos;s go back to 2003:</p><blockquote><em>I think that the great philosopher George Santayana got it exactly wrong. I think it is precisely those who insist on remembering history who are doomed to repeat it. For a subject with so little substance, for something that is really little more than a set of intellectual interpretations, history can become a formidable trap&#x2014; a sticky snare from which we may find it impossible to extricate ourselves. I find it impossible to read the texts of Tisha B&#x2019;Av, with their great themes of exile and return, and their endless sense of longing for the land of Israel, without thinking of the current political tragedy in the Middle East. I write this at a very dark moment in the long and bleak history of that conflict. Who knows what will be happening there when you read this? But I think it&#x2019;s a safe bet that whenever you do, one thing is unlikely to have changed. There will likely be a tremendous compulsion for historical vindication on both sides. Very often, I think it is precisely the impossible yearning for historical justification that makes resolution of this conflict seem so impossible. The Jews want vindication for the Holocaust, and for the two thousand years of European persecution and ostracism that preceded it; the Jews want the same Europeans who now give them moral lectures to acknowledge that this entire situation would never have come about if not for two thousand years of European bigotry, barbarism, and xenophobia. They want the world to acknowledge that Israel was attacked first, in 1948, in 1967, in 1973, and in each of the recent Intifadas. They want acknowledgment that they only took the lands from which they were attacked during these conflicts, and offered to return them on one and only one condition&#x2014; the acknowledgment of their right to exist. When Anwar Sadat met that condition, the Sinai Peninsula, with its rich oil fields and burgeoning settlement towns, was returned to him. And they want acknowledgment that there are many in the Palestinian camp who truly wish to destroy them, who have used the language of peace as a ploy to buy time until they have the capacity to liquidate Israel and the Jews once and for all. They want acknowledgment that they have suffered immensely from terrorism, that a people who lost six million innocents scarcely seventy years ago should not have had to endure the murder of its innocent men, women, and children so soon again. And they want acknowledgment that in spite of all this, they stood at Camp David prepared to offer the Palestinians everything they claimed to have wanted&#x2014; full statehood, a capital in East Jerusalem&#x2014; and the response of the Palestinians was the second Intifada, a murderous campaign of terror and suicide bombings.</em><br><br><em>And the Palestinians? They would like the world to acknowledge that they lived in the land now called Israel for centuries, that they planted olive trees, shepherded flocks, and raised families there for hundreds of years; they would like the world to acknowledge that when they look up from their blue-roofed villages, their trees and their flowers, their fields and their flocks, they see the horrific, uninvited monolith of western culture&#x2014; immense apartment complexes, shopping centers, and industrial plants on the once-bare and rocky hills where the voice of God could be heard and where Muhammad ascended to heaven. And they would like the world to acknowledge that it was essentially a European problem that was plopped into their laps at the end of the last great war, not one of their own making. They would like the world to acknowledge that there has always been a kind of arrogance attached to this problem; that it was as if the United States and England said to them, Here are the Jews, get used to them. And they would like the world to acknowledge that it is a great indignity, not to mention a significant hardship, to have been an occupied people for so long, to have had to submit to strip searches on the way to work, and intimidation on the way to the grocery store, and the constant humiliation of being subject&#x2014; a humiliation rendered nearly bottomless when Israel, with the benefit of the considerable intellectual and economic resources of world Jewry, made the desert bloom, in a way they had never been able to do. And they would like the world to acknowledge that there are those in Israel who are determined never to grant them independence, who have used the language of peace as a ploy to fill the West Bank with settlement after settlement until the facts on the ground are such that an independent Palestinian state on the West Bank is an impossibility. They would like the world to acknowledge that there is no such thing as a gentle occupation&#x2014; that occupation corrodes the humanity of the occupier and makes the occupied vulnerable to brutality.</em><br><br><em>And I think the need to have these things acknowledged&#x2014; the need for historical affirmation&#x2014; is so great on both sides that both the Israelis and the Palestinians would rather perish as peoples than give this need up. In fact, I think they both feel that they would perish as peoples precisely if they did. They would rather die than admit their own complicity in the present situation, because to make such an admission would be to acknowledge the suffering of the other and the legitimacy of the other&#x2019;s complaint, and that might mean that they themselves were wrong, that they were evil, that they were bad. That might give the other an opening to annihilate or enslave them. That might make such behavior seem justifiable.</em><br><br><em>I wonder how many of us are stuck in a similar snare. I wonder how many of us are holding on very hard to some piece of personal history that is preventing us from moving on with our lives, and keeping us from those we love. I wonder how many of us cling so tenaciously to a version of a story of our lives in which we appear to be utterly blameless and innocent, that we become oblivious to the pain we have inflicted on others, no matter how unconsciously or inevitably or innocently we have have inflicted it. I wonder how many of us are terrified of acknowledging the truth of our lives because we think it will expose us. How many of us stand paralyzed between the moon and the sun; frozen &#x2014; unable to act in the moment &#x2014; because of our terror of the past and because of the intractability of the present circumstances that past has wrought? Forgiveness, it has been said, means giving up our hopes for a better past. This may sound like a joke, but how many of us refuse to give up our version of the past, and so find it impossible to forgive ourselves or others, impossible to act in the present?</em></blockquote><p>I don&apos;t have answers. In my childhood I was promised peace in the Middle East. I am still waiting. I wish I knew what was needed to get us there.</p><p><a href="https://www.sefaria.org/Pirkei_Avot.5.21?ref=blog.shalman.org">Pirkei_Avot Chapter 5, Verse 21</a> implies that I am perhaps old enough to have some Wisdom, but am not yet old enough to give Counsel. The only wisdom I have obtained so far is that in most disagreements, people can disagree about the &quot;facts&quot;, be aproaching the situation with fundamentally different values, or both. I believe that to have any meaningful discussion on a topic as fraught as this one, first common values must be established. Only then can we approach reality side-by-side, examine our beliefs, find mutually trustworthy sources of information, and find agreement about the state of reality. When values are aligned and facts are agreed upon, we might have some hope of letting go of just enough bits of history to find a path through this mess.</p><p>Decades ago I was a child promised peace. Today I have children of my own. Today on both side there are children suffering from the choices of their parents and grandparents. All the children deserve better.</p><p>There are people on both sides with genocide in their hearts. I don&apos;t yet know what to do about that, but we cannot let them win.</p><p>I wish that those who should be wise enough to provide counsel, particularly those with power, would get their acts together.</p><p>I wish for the peace and safety of all the innocents.</p><p>I wish for peace. In my lifetime. This year. Tomorrow. Or even today.</p><p>I hope that these words of Rabbi Alan Lew will reach just a few more people thanks to this post being on the internet. I hope they have touched you. Thank you for reading.</p>]]></content:encoded></item><item><title><![CDATA[Difficult Hardware]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This content can also be found as part of <a href="https://github.com/tinkerbell/ipxedust/pull/88?ref=blog.shalman.org">https://github.com/tinkerbell/ipxedust/pull/88</a> in <a href="https://github.com/nshalman/ipxedust/blob/2ac6660dc9da1e9912e8fd13f956f0c60b29f651/docs/DifficultHardware.md?ref=blog.shalman.org">DifficultHardware.md</a>.</p>
<p>Most modern hardware is capable of PXE booting just fine. Sometimes strange combinations of different NIC hardware / firmware connected to specific switches can misbehave.</p>
<p>In those situations you might want to</p>]]></description><link>https://blog.shalman.org/difficult-hardware/</link><guid isPermaLink="false">64ff4c672bb3debf673d3f1b</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Mon, 11 Sep 2023 17:25:53 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>This content can also be found as part of <a href="https://github.com/tinkerbell/ipxedust/pull/88?ref=blog.shalman.org">https://github.com/tinkerbell/ipxedust/pull/88</a> in <a href="https://github.com/nshalman/ipxedust/blob/2ac6660dc9da1e9912e8fd13f956f0c60b29f651/docs/DifficultHardware.md?ref=blog.shalman.org">DifficultHardware.md</a>.</p>
<p>Most modern hardware is capable of PXE booting just fine. Sometimes strange combinations of different NIC hardware / firmware connected to specific switches can misbehave.</p>
<p>In those situations you might want to boot into a build of iPXE but completely sidestep the PXE stack in your NIC firmware.</p>
<p>We already ship ipxe.iso that can be used in many situations, but most of the time that requires either an active connection from a virtual KVM client or network access from the BMC to a storage target hosting the ISO.</p>
<p>Some BMCs support uploading a floppy image into BMC memory and booting from that. To support that use case we have started packaging our EFI build into a bootable floppy image that can be used for this purpose.</p>
<p>For other projects or use cases that wish to replicate this functionality, with the appropriate versions of qemu-img, dosfstools and mtools you can build something similar yourself from upstream iPXE like so:</p>
<pre><code># create a 1440K raw disk image
qemu-img create -f raw ipxe-efi.img 1440K
# format it with an MBR and a FAT12 filesystem
mkfs.vfat --mbr=y -F 12 -n IPXE ipxe-efi.img

# Create the EFI expected directory structure
mmd -i ipxe-efi.img ::/EFI
mmd -i ipxe-efi.img ::/EFI/BOOT

# Copy ipxe.efi as the default x86_64 efi boot file
curl -LO https://boot.ipxe.org/ipxe.efi
mcopy -i ipxe-efi.img ipxe.efi ::/EFI/BOOT/BOOTX64.efi
</code></pre>
<p>As of writing other projects are working on automating the upload<br>
of this floppy to a BMC.<br>
See draft PR <a href="https://github.com/bmc-toolbox/bmclib/pull/347?ref=blog.shalman.org">https://github.com/bmc-toolbox/bmclib/pull/347</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Private Web based IDE]]></title><description><![CDATA[<p>These notes are a riff on a post by <a href="https://twitter.com/ChrisShort?ref=blog.shalman.org">Chris Short</a>. The biggest difference is that I will use the Tailscale TLS support rather than using external DNS access and a custom DNS record. This removes the need for a sensitive DNS API key. Chris&apos;s post is definitely</p>]]></description><link>https://blog.shalman.org/private-web-based-ide/</link><guid isPermaLink="false">62c6f9f9a2c584cf60de6c0b</guid><category><![CDATA[tailscale]]></category><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Fri, 08 Jul 2022 02:10:28 GMT</pubDate><content:encoded><![CDATA[<p>These notes are a riff on a post by <a href="https://twitter.com/ChrisShort?ref=blog.shalman.org">Chris Short</a>. The biggest difference is that I will use the Tailscale TLS support rather than using external DNS access and a custom DNS record. This removes the need for a sensitive DNS API key. Chris&apos;s post is definitely worth a read first:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://chrisshort.net/code-server-caddy-tailscale-and-hugo-my-ultimate-dev-environment/?ref=blog.shalman.org"><div class="kg-bookmark-content"><div class="kg-bookmark-title">code-server, Caddy, Tailscale, and Hugo = My ultimate dev environment</div><div class="kg-bookmark-description">I think I&#x2019;ve discovered my development environment equivalent to nirvana: code-server, Caddy, Tailscale, and Hugo</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://chrisshort.net/android-icon-192x192.png" alt><span class="kg-bookmark-author">ChrisShort.net</span><span class="kg-bookmark-publisher">Chris Short</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://shortcdn.com/file/chrisshort/code-server-caddy-tailscale-and-hugo-my-ultimate-dev-environment.webp" alt></div></a></figure><!--kg-card-begin: markdown--><p>Welcome back. Here&apos;s the plan:</p>
<ol>
<li>Spin up an Ubuntu instance</li>
<li>Add it to my Tailnet</li>
<li>Install and run code-server</li>
<li>Install, configure, and run Caddy</li>
<li>...</li>
<li>Profit?</li>
</ol>
<p>When we&apos;re done we should be able to go to a browser on any machine in the Tailnet and type <code>http://vscode</code> (I&apos;m assuming you&apos;ve set the hostname of the new instance to &quot;vscode&quot;) and be redirected to the full https URL which will help reassure the browser (even though HTTP over Tailscale is already secure.)</p>
<p>Prerequisites:</p>
<ol>
<li>An existing Tailscale account and a machine on it to use as the client</li>
<li>A <a href="https://login.tailscale.com/admin/settings/keys?ref=blog.shalman.org">Tailscale Auth Key</a> to use</li>
<li>MagicDNS needs to be enabled on your Tailnet.</li>
<li>The Tailscale HTTPS Beta feature also needs to be enabled on your Tailnet.</li>
</ol>
<p>Here&apos;s the code:</p>
<!--kg-card-end: markdown--><!--kg-card-begin: html--><script src="https://gist.github.com/nshalman/31e10edf7ad22da427122041d0babf36.js"></script><!--kg-card-end: html--><!--kg-card-begin: markdown--><p>I tested that code by using it as user-data for cloud-init, so you can go from zero to code-server over Tailscale mostly unattended.</p>
<p>So, spin up Ubuntu in your favorite place and either add that as the user-data or run it as root manually. When it&apos;s done you can fetch the default password with:</p>
<pre><code>ssh vscode grep password: .config/code-server/config.yaml
</code></pre>
<p>You should be able to navigate to <a href="http://vscode/?ref=blog.shalman.org">http://vscode</a> (or whatever hostname you used) and get redirected to the TLS-ified URL to log in.</p>
<p>Check back later for more shenanigans where I&apos;ll do this inside LX branded zones on illumos!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[SSH SOCKS proxy but it's Tailscale]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Have you ever run <code>ssh -D 9999 somehost</code>?<br>
You might find the rest of this interesting.</p>
<p>I&apos;m not going to go into detail for the use cases of why you might want to use a SOCKS proxy with e.g. your web browser, but if, like me, you&</p>]]></description><link>https://blog.shalman.org/ssh-socks-proxy-but-its-tailscale/</link><guid isPermaLink="false">6269654b86a731332d7b5aca</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Thu, 28 Apr 2022 12:40:32 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Have you ever run <code>ssh -D 9999 somehost</code>?<br>
You might find the rest of this interesting.</p>
<p>I&apos;m not going to go into detail for the use cases of why you might want to use a SOCKS proxy with e.g. your web browser, but if, like me, you&apos;ve ever done it, you might be interested in this method of doing something comparable with Tailscale. You&apos;ll need an existing Tailscale account and an exit node set up.</p>
<p>Run the daemon using userspace networking</p>
<pre><code>tailscaled -tun userspace-networking -socket ~/.ssh/tailscale.socket -state ~/.ssh/tailscale.state -socks5-server localhost:9999 &amp;
</code></pre>
<p>Configure it to use your exitnode and give it an identifiable hostname (you&apos;ll need to then auth the machine):</p>
<pre><code>tailscale -socket ~/.ssh/tailscale.socket up --exit-node exitnode --hostname=laptop-proxy
</code></pre>
<p>Now you can configure your browser (I find Firefox easiest to use for this purpose) to use the SOCKS proxy just as you would have when you used SSH.</p>
<p>This can even be run on a machine that is already set up for Tailscale allowing use of the exit node just for this particular browser while all other network traffic from the machine behaves normally.</p>
<p>The tailscale.state file is sensitive; it contains the private key used for the wireguard traffic from this tailscaled process. Protect it. I put it in my <code>.ssh</code> directory to remind me of that.</p>
<p>References:</p>
<ul>
<li><a href="https://tailscale.com/kb/1112/userspace-networking/?ref=blog.shalman.org">https://tailscale.com/kb/1112/userspace-networking/</a></li>
<li><a href="https://tailscale.com/kb/1103/exit-nodes/?ref=blog.shalman.org">https://tailscale.com/kb/1103/exit-nodes/</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Tailscale for illumos]]></title><description><![CDATA[Current status: Up to date with Tailscale 1.24.2.
My SMF manifest and build script are checked in to my branch.
I've added notes on how to set up an exit node.]]></description><link>https://blog.shalman.org/tailscale-for-illumos/</link><guid isPermaLink="false">5f4d9cc286c7c394cd4c069c</guid><category><![CDATA[smartos]]></category><category><![CDATA[illumos]]></category><category><![CDATA[wireguard]]></category><category><![CDATA[tailscale]]></category><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Wed, 14 Jul 2021 02:00:00 GMT</pubDate><content:encoded><![CDATA[<p>NOTE: This page is <s>probably</s> still a work in progress. I&apos;m slowly working on upstreaming the necessary changes in small bits of spare time as I find them. If others have time/interest to help, I&apos;d certainly appreciate it!</p><h2 id="june-2022">June 2022</h2><!--kg-card-begin: markdown--><p>Someone asked on Twitter and while my response was enough for them:</p>
<blockquote>
<p>my ipnat.conf contains &quot;map net0 100.64.0.0/10 -&gt; 0/32&quot; and &quot;svc:/network/ipfilter:default&quot; and &quot;svc:/network/ipv4-forwarding:default&quot; should be online.</p>
</blockquote>
<p>... I should probably spell out the details for others.</p>
<p>So, notes on running an ipv4 exit node as demonstrated in a SmartOS zone:</p>
<p>json payload for vmadm:</p>
<pre><code class="language-json">{
  &quot;alias&quot;: &quot;exitnode-illumos&quot;,
  &quot;hostname&quot;: &quot;exitnode-illumos&quot;,
  &quot;brand&quot;: &quot;joyent&quot;,
  &quot;max_physical_memory&quot;: 256,
  &quot;quota&quot;: 10,
  &quot;image_uuid&quot;: &quot;39f99738-9a4c-11ec-8e1c-3b65b9abc26a&quot;,
  &quot;resolvers&quot;: [&quot;8.8.8.8&quot;,&quot;8.8.4.4&quot;],
  &quot;nics&quot;: [
    {
      &quot;nic_tag&quot;: &quot;admin&quot;,
      &quot;ips&quot;: [&quot;dhcp&quot;]
    }
  ]
}
</code></pre>
<p>Preparatory steps to run inside the zone to setup NAT and forwarding:</p>
<pre><code class="language-console">echo &quot;map net0 100.64.0.0/10 -&gt; 0/32&quot; &gt; /etc/ipf/ipnat.conf
svcadm enable ipfilter
svcadm enable ipv4-forwarding
</code></pre>
<p>Obtain <code>tailscale</code>, <code>tailscaled</code>, and <code>tailscale.xml</code> and put them into place (make sure the binaries are marked executable):</p>
<pre><code class="language-console">cp ./tailscale{,d} /usr/local/sbin/
svccfg import tailscale.xml
mkdir -p /var/lib/tailscale
svcadm enable tailscale
tailscale up --advertise-exit-node
</code></pre>
<p>Authenticate the machine and mark it as allowed to be an exit node in the admin console (give it a nice ACL tag if you&apos;re feeling fancy.)</p>
<p>Note, the current branch has a <code>build.sh</code> script that you can run anywhere you have a golang toolchain (it assumes the build system is <code>GOARCH=amd64</code> so if that&apos;s not the case on your build system, modify it accordingly) or as always, hit me up on IRC or DM me on Twitter and I can provide the link to my binaries.</p>
<!--kg-card-end: markdown--><h2 id="july-2021">July 2021</h2><p>Work on wireguard-go has been paused. I&apos;ve been working on getting Event Ports support into x/sys/unix. The code for that seems to be complete but is blocked on landing until the release of Go 1.17. See <a href="https://go-review.googlesource.com/c/sys/+/324630?ref=blog.shalman.org">CR324630</a><br>After that lands, I can finish cleaning up my work adding Event Ports to fsnotify, though that project isn&apos;t looking very active which has me a little nervous. See <a href="https://github.com/fsnotify/fsnotify/pull/371?ref=blog.shalman.org">fsnotify#371</a><br>Hopefully I&apos;ll find some time to pick up wireguard-go again soon, but in the meantime, last week I did a quick cleanup and rebase of my Tailscale branch. It is now based on Tailscale 1.10.1 and today I even checked in my current SMF manifests for reference: <a href="https://github.com/nshalman/tailscale/tree/illumos-1.10.1?ref=blog.shalman.org">https://github.com/nshalman/tailscale/tree/illumos-1.10.1</a><br>I have been doing my builds with go 1.16.5 natively in a SmartOS zone, but because my fork of wireguard-go no longer uses cgo, it should be possible to cross compile binaries using a go 1.16.5 toolchain anywhere.<br>Rough instructions for a non-global zone (not fully tested; if you test or have changes let me know so that I can fix them and remove this note):</p><!--kg-card-begin: markdown--><pre><code>git clone https://github.com/nshalman/tailscale -b illumos-1.10.1
cd tailscale
GOOS=illumos go build ./cmd/tailscaled
GOOS=illumos go build ./cmd/tailscale
sudo cp ./tailscale{,d} /usr/local/sbin/
sudo svccfg import ./cmd/tailscaled/tailscale.xml
sudo mkdir -p /var/lib/tailscale
sudo svcadm enable tailscale
sudo tailscale up
</code></pre>
<!--kg-card-end: markdown--><p>Thanks to <a href="https://twitter.com/richlowe?ref=blog.shalman.org">@richlowe</a> for the nudge for this update. If anyone would like binaries, let me know and I&apos;ll post some and link them here.</p><h2 id="march-2021">March 2021</h2><p>Alpha grade binaries of Tailscale 1.6 for illumos:<br><a href="https://www.shalman.org/files/tailscale-v1.6-illumos-alpha/tailscale?ref=blog.shalman.org">https://www.shalman.org/files/tailscale-v1.6-illumos-alpha/tailscale</a><br><a href="https://www.shalman.org/files/tailscale-v1.6-illumos-alpha/tailscaled?ref=blog.shalman.org">https://www.shalman.org/files/tailscale-v1.6-illumos-alpha/tailscaled</a></p><p>There&apos;s progress in getting lots of the syscall and ioctl bits into golang&apos;s x/sys/unix and that should pave the way for a simplified patch against wireguard-go which should eventually be good enough to be upstreamed. I&apos;ve rebased and rebuilt a bunch of my changes on top of Tailscale 1.6.0 and even ipv6 support seems to work. More to come.</p><h2 id="original-post-august-2020-">Original Post (August 2020)</h2><p>Background reading:</p><ul><li>Wireguard: <a href="https://www.wireguard.com/?ref=blog.shalman.org">https://www.wireguard.com/</a></li><li>Tailscale: <a href="https://tailscale.com/?ref=blog.shalman.org">https://tailscale.com/</a></li></ul><p>A while back, <a href="https://github.com/jclulow?ref=blog.shalman.org">Josh Clulow</a> <a href="https://github.com/jclulow/wireguard-go-illumos-wip?ref=blog.shalman.org">did an initial port of wireguard-go to illumos</a>. I was able to make some small modifications to it sufficient to get it to point the Tailscale client code at it and build tailscale binaries for illumos. Here&apos;s how to build them yourself:</p><!--kg-card-begin: markdown--><p>You&apos;ll need <code>git</code> and a Go toolchain. I tested in a SmartOS zone using <code>go114-1.14.4</code> and that seems to work. In the future we&apos;ll need Go 1.15.</p>
<pre><code>&lt;install git and a go toolchain&gt;
git clone https://github.com/nshalman/wireguard-go -b tailscale-illumos wireguard-go
git clone https://github.com/nshalman/tailscale -b illumos tailscale
cd tailscale
sed -e &quot;s|/home/admin/wireguard-go|$(cd ../wireguard-go ; pwd)|&quot; -i go.mod
GOOS=illumos go build tailscale.com/cmd/tailscale
GOOS=illumos go build tailscale.com/cmd/tailscaled
</code></pre>
<!--kg-card-end: markdown--><p>As of the time of writing, <a href="https://github.com/WireGuard/wireguard-go/pull/39?ref=blog.shalman.org">my initial pull request</a> to get the wireguard-go bits upstreamed is waiting on a combination of cleanups, and hopefully some additional functionality being added to x/sys/unix. Once that&apos;s done, a cleanup of <a href="https://github.com/nshalman/tailscale/tree/illumos?ref=blog.shalman.org">my fork of tailscale</a> to be ready for upstreaming will hopefully follow (<a href="https://github.com/tailscale/tailscale/issues/697?ref=blog.shalman.org">the feature request where it&apos;s being tracked is here</a>).</p><p>Since you shouldn&apos;t trust random people on the internet, you should probably review the code and build it yourself, however, if you know and trust me, I&apos;ve uploaded binaries and my SMF manifest which you can download and experiment with (the version strings in the binaries are patched so that you know you got them from me):</p><ul><li><a href="https://www.shalman.org/tailscale/tailscaled?ref=blog.shalman.org">tailscaled</a></li><li><a href="https://www.shalman.org/tailscale/tailscale?ref=blog.shalman.org">tailscale</a></li><li><a href="https://www.shalman.org/tailscale/tailscale.xml?ref=blog.shalman.org">tailscale.xml</a></li></ul><!--kg-card-begin: markdown--><p>To use them, drop the binaries into <code>/usr/local/sbin</code>, <code>mkdir /etc/tailscale</code> import them manifest (<code>svccfg import tailscale.xml</code>), start the daemon <code>svcadm enable tailscale</code>, then run <code>tailscale up</code> (I&apos;m assuming you&apos;ve already set up your Tailscale account, etc.)</p>
<!--kg-card-end: markdown--><p>Help is welcome and I intend to update this page as the work makes progress. <s>Last updated August 31,2020. Feel free to troll me on Twitter if this note is still here and it&apos;s 2021. :)</s></p><p>On a related note, if you only need Wireguard and not Tailscale, you should also check out <a href="https://github.com/papertigers?ref=blog.shalman.org">Mike Zeller</a>&apos;s <a href="https://github.com/papertigers/boringtun/tree/illumos-eventports?ref=blog.shalman.org">illumos port of boringtun</a> which is a rust implementation. I think I managed to get it working, but stopped experimenting with it when Tailscale came out...</p>]]></content:encoded></item><item><title><![CDATA[A Four Axis Model of Work]]></title><description><![CDATA[Mission, Technology, Culture, Compensation]]></description><link>https://blog.shalman.org/four-axis-model/</link><guid isPermaLink="false">602a9f767b79295ee4cb0f43</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Tue, 09 Mar 2021 16:01:49 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In mid December I received (a generous) two month&apos;s notice that I would need to find a new job. I had the luxury of being able to reach out to people I&apos;d be interested in working with while wrapping up loose ends at work for one month, and the further luxury of being paid for another month while searching for a new job. With that much time to think about what I want to do next I came up with a framework for how to approach my search, and how to compare different opportunities should I find myself blessed with choices. What I came up with I&apos;ve taken to calling a four axis model.</p>
<h1 id="importantcaveats">Important Caveats</h1>
<p>I don&apos;t presume to be able to offer advice. I&apos;ve been incredibly fortunate in so many ways in my life that I find myself standing on top of many different layers of privilege. These are things for which I can take no credit, but have made my life dramatically easier than for the average person. There&apos;s an important conversation to be had about how to make what has been possible for me possible for more people, but that is not what this post is about.</p>
<h1 id="thefouraxes">The Four Axes</h1>
<p>These are my one-word shorthand:</p>
<ol>
<li>Mission</li>
<li>Technology</li>
<li>Culture</li>
<li>Compensation</li>
</ol>
<p>For most readers, the use of the word axis probably hints sufficiently, but in case someone else stumbles across this post, the idea here is multidimensional optimization. If all I cared about was money, I could optimize for that 4th axis by interviewing with a bunch of different companies, comparing the compensation, and simply choose the job that pays the most. Since I care about more than just money, I have to be willing to make trade-offs between these different dimensions and try to maximize the overall value that a job offer presents.</p>
<h2 id="mission">Mission</h2>
<p>What is the company trying to accomplish in the world? What are they actually accomplishing? How does that mission connect to my values and add meaning to my day-to-day work? What story (real or imagined) will I tell myself each day about why I work where I work? Will ongoing reality re-enforce that story, or undermine it?</p>
<h2 id="technology">Technology</h2>
<p>This is where it becomes very clear that my 4 axes are shorthand for more than 4 axes. Technology is shorthand for:</p>
<ol>
<li>Do they use technologies with which I am already familiar? Will I be able to ramp up in a reasonable amount of time and be productive?</li>
<li>Will I learn and grow as a technologist?</li>
<li>Will I be able to contribute to open source projects?</li>
<li>Do they get bonus points using any of my favorite &quot;nice to have&quot; technologies? (For me, &quot;nice to have&quot; includes things like running illumos instead of Linux, using ZFS, using rust, etc.)</li>
</ol>
<h2 id="culture">Culture</h2>
<p>What are the the company&apos;s professed values? What values do their actions reveal? How do people interact within the team, across teams, across larger organizations within the company, etc. Does the company care about diversity? Is the workforce already diverse including if not particularly in upper management? Is the workplace (physical and/or digital) inclusive?</p>
<h2 id="compensation">Compensation</h2>
<p>Compensation is the value a company provides back to you in exchange for your labor. Some of it is things like an hourly rate or a base salary. Some of it is some form of equity in the company. Some of it is agreed upon explicitly at hiring time, while some of it could be a bonus based on your performance, or the company&apos;s performance, or both. Some of it could be contributing some or all of the cost of various things like insurance. Some companies offer fancy offices with catered food and snacks. Some companies will contribute to a retirement account for you. Heck, in some professions they still have pensions! Some companies will match your charitable donations. All of these things are forms of compensation, and you have to figure out how to weight each of the components of the compensation you&apos;re being offered.<br>
I&apos;m still relatively inexperienced with how lots of different companies try to balance their compensation packages, and I think I could have done more research during my job search. In the end, I consulted with a financial advisor to help me understand how to value base salary, public company equity, private company equity, etc. I do think it&apos;s very important to ensure that your base salary covers your critical expenses, but beyond that, I&apos;m probably the wrong person to provide advice on compensation.</p>
<p>In broad strokes, however, I have started to bucket compensation into three categories:</p>
<ol>
<li>Money for me for right now - base salary, insurance and other similar benefits. Additional considerations: inflation, raises, liquid equity</li>
<li>Money for me for later - Considerations: 401k matching, equity</li>
<li>Money for donating - Considerations: charitable matching, liquid equity for donating</li>
</ol>
<h1 id="howiusethisframework">How I use this framework</h1>
<p>I will once again repeat the caveat that this post is not advice. I&apos;ve linked some other resources at the end of this post for further reading (and if you have a favorite resource not listed, let me know about it and I&apos;ll add it!)</p>
<h2 id="asafilter">As a filter</h2>
<p>Again, fully recognizing how fortunate I am that simply marking myself as &quot;open to work&quot; on LinkedIn provided me with a steady stream of inquiries from recruiters, this framework allowed me to, for example, politely decline some companies in industries that are just not of interest to me (even though by reputation they pay very very well.)<br>
Similarly, I&apos;ve come across companies which have pages on the their website  showing the leadership team and it&apos;s ALL white men.... They might be very nice people, but chances are their workforce isn&apos;t particularly diverse.</p>
<h2 id="asatoolforansweringquestions">As a tool for answering questions:</h2>
<p>Question: &quot;What are you looking for in your next job?&quot;<br>
Answer: Well, here&apos;s this framework I have in my head....</p>
<p>Question: &quot;Why do you want to work at X?&quot;<br>
Answer: Well, here&apos;s this framework I have in my head, and here&apos;s how I think X maps onto it so far, but also, I&apos;m still wondering about this aspect. Can you tell me more?</p>
<h2 id="asatoolforaskingquestions">As a tool for asking questions:</h2>
<p>This is where I don&apos;t know if what I&apos;m doing is a good idea, but here it is:<br>
In every interview where I get the chance to ask questions (most of them) I quickly run through a very brief explanation of &quot;I&apos;m looking to optimize across Mission, Technology, and Culture and here&apos;s what I mean by those.... Please tell me about your experience with this company along those lines.&quot;<br>
The great thing about asking the same question of everyone is that the answers across individuals within the same company are revealing in their similarities and differences and comparing the answers across companies helps with decision making.</p>
<h2 id="asatoolformakingachoice">As a tool for making a choice:</h2>
<p>I was fortunate to get more than one offer at roughly the same time. Having criteria for comparing offers helped me with deciding on which offer to accept.</p>
<h1 id="furtherreading">Further Reading</h1>
<ul>
<li><a href="https://github.com/viraptor/reverse-interview?ref=blog.shalman.org">Reverse Interview</a></li>
<li><a href="https://www.kalzumeus.com/2012/01/23/salary-negotiation/?ref=blog.shalman.org">Salary Negotiation</a> from <a href="https://twitter.com/patio11?ref=blog.shalman.org">Patrick McKenzie</a></li>
<li><a href="https://www.levels.fyi/?ref=blog.shalman.org">levels.fyi</a> has salary information about lots of companies and how they compare</li>
<li><a href="https://www.linkedin.com/pulse/mibest-career-decision-app-help-you-make-one-lifes-most-silverman/?ref=blog.shalman.org">MIBEST Framework</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Silly SmartOS hack: ipf/ipnat in lx zones]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Someone on IRC in #smartos was <a href="https://freenode.logbot.info/smartos/20210205?ref=blog.shalman.org#c6800202">asking</a> about how to turn on NAT in lx branded zones. I was pretty sure it should be possible, and found myself <a href="https://xkcd.com/356/?ref=blog.shalman.org">nerd-sniped</a> into figuring out the exact solution.</p>
<p>I don&apos;t think I particularly recommend doing this, but figuring out how to</p>]]></description><link>https://blog.shalman.org/ipnat-in-lx-zones/</link><guid isPermaLink="false">601d9dc07b79295ee4cb0e13</guid><category><![CDATA[smartos]]></category><category><![CDATA[illumos]]></category><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Mon, 08 Feb 2021 16:28:28 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Someone on IRC in #smartos was <a href="https://freenode.logbot.info/smartos/20210205?ref=blog.shalman.org#c6800202">asking</a> about how to turn on NAT in lx branded zones. I was pretty sure it should be possible, and found myself <a href="https://xkcd.com/356/?ref=blog.shalman.org">nerd-sniped</a> into figuring out the exact solution.</p>
<p>I don&apos;t think I particularly recommend doing this, but figuring out how to do it is a good exercise in figuring out how certain things work in illumos in general, so we&apos;ll take a brief excursion into what actually happens in a joyent branded zone when you follow the steps in the <a href="https://wiki.smartos.org/nat-using-etherstubs/?ref=blog.shalman.org">wiki page</a> I wrote forever ago. From there we&apos;ll figure out a relatively minimal set of commands to run in lx branded zones to accomplish the same thing.</p>
<p>The <a href="https://wiki.smartos.org/nat-using-etherstubs/?ref=blog.shalman.org#configure-nat">instructions</a> list three commands to run in the firewall zone, but the third is just to verify that NAT is indeed configured, so let&apos;s look closely at the first two which do all the work:</p>
<pre><code>routeadm -u -e ipv4-forwarding
svcadm enable ipfilter
</code></pre>
<p>The first one is turning on packet forwarding for ipv4, and the second turns on ipf filtering and NAT. But what do those commands do under the hood and can we replicate that in the lx zone?</p>
<p>If we look at the <a href="https://illumos.org/man/1m/routeadm?ref=blog.shalman.org">routeadm man page</a> it helpfully points out that those features are also represented as SMF services which you could manage directly with <a href="https://illumos.org/man/1m/svcadm?ref=blog.shalman.org">svcadm</a> and the EXAMPLES section even suggests that we could turn on ipv4 forwarding using <code>svcadm enable ipv4-forwarding</code>.</p>
<p>Once we have an SMF service, we can see how it works by looking at the service manifest. When I was poking around I did this live in a zone by running <code>svccfg export ipv4-forwarding</code> but for the ease of just clicking links, the source for what you&apos;d see there is in <a href="https://github.com/illumos/illumos-gate/blob/f4fe62a3c26a7b15283589c57a3c10ed9695b529/usr/src/cmd/cmd-inet/usr.sbin/routeadm/forwarding.xml?ref=blog.shalman.org#L70-L78">/usr/src/cmd/cmd-inet/usr.sbin/routeadm/forwarding.xml</a>.</p>
<p>Narrowing in on the start method which wants to run <code>/lib/svc/method/svc-forwarding %m ipv4</code> we see that there&apos;s a helper script we need to read. Again, I looked at it at that path on my system but the source is in <a href="https://github.com/illumos/illumos-gate/blob/f4fe62a3c26a7b15283589c57a3c10ed9695b529/usr/src/cmd/cmd-inet/usr.sbin/routeadm/svc-forwarding?ref=blog.shalman.org#L57">/usr/src/cmd/cmd-inet/usr.sbin/routeadm/svc-forwarding</a>.<br>
In there we find the critical line of <code>/usr/sbin/ipadm set-prop -p forwarding=on $proto</code></p>
<p>What have we learned so far? <code>routeadm</code> behind the scene enables the <code>ipv4-forwarding</code> SMF service that in turn runs an <a href="https://illumos.org/man/1m/ipadm?ref=blog.shalman.org">ipadm</a> command.</p>
<p>So now what about that <code>ipfilter</code> service?<br>
Again, on a live system we can run <code>svccfg export ipfilter</code>  to find the start method (source in <a href="https://github.com/illumos/illumos-gate/blob/f4fe62a3c26a7b15283589c57a3c10ed9695b529/usr/src/cmd/ipf/svc/ipfilter.xml?ref=blog.shalman.org#L89-L94">/usr/src/cmd/ipf/svc/ipfilter.xml</a>) and we find that it calls <code>/lib/svc/method/ipfilter</code> (source: <a href="https://github.com/illumos/illumos-gate/blob/f4fe62a3c26a7b15283589c57a3c10ed9695b529/usr/src/cmd/ipf/svc/ipfilter?ref=blog.shalman.org">/usr/src/cmd/ipf/svc/ipfilter</a>).</p>
<p>If you read through this script you find some places where it calls out to <a href="https://illumos.org/man/1m/ipf?ref=blog.shalman.org">ipf</a> and <a href="https://illumos.org/man/1m/ipnat?ref=blog.shalman.org">ipnat</a> whose manpages can be used to figure out what those various commands do.</p>
<p>Through reading the script and the man page and some experimentation I narrowed down a minimal set of steps of:</p>
<pre><code>ipf -E    # enable IPF
ipnat -CF # Delete all existing rules and active mappings
ipnat -f ${ipnat_config_file:?} # load NAT rules from a file
</code></pre>
<p>There&apos;s one last wrinkle that tripped me up and wasted some of my time. I blithely copy-and-pasted the ipnat.conf content, ran my commands, and wondered why the packets weren&apos;t flowing. The lx brand names network interfaces with a more linux-y eth0, eth1, etc. rather than net0, net1, etc.</p>
<p>So, let&apos;s put this all together:</p>
<p>firewall-lx.json:</p>
<pre><code>{
  &quot;alias&quot;: &quot;firewall-lx&quot;,
  &quot;hostname&quot;: &quot;firewall-lx&quot;,
  &quot;brand&quot;: &quot;lx&quot;,
  &quot;kernel_version&quot;: &quot;3.10.0&quot;,
  &quot;max_physical_memory&quot;: 512,
  &quot;image_uuid&quot;: &quot;63d6e664-3f1f-11e8-aef6-a3120cf8dd9d&quot;,
  &quot;nics&quot;: [
    {
      &quot;nic_tag&quot;: &quot;admin&quot;,
      &quot;ip&quot;: &quot;dhcp&quot;,
      &quot;allow_ip_spoofing&quot;: &quot;1&quot;
    },
    {
      &quot;nic_tag&quot;: &quot;stub0&quot;,
      &quot;ip&quot;: &quot;10.0.0.1&quot;,
      &quot;netmask&quot;: &quot;255.255.255.0&quot;,
      &quot;allow_ip_spoofing&quot;: &quot;1&quot;,
      &quot;primary&quot;: &quot;1&quot;
    }
  ]
}
</code></pre>
<p>client.json:</p>
<pre><code>{
  &quot;alias&quot;: &quot;client&quot;,
  &quot;hostname&quot;: &quot;client&quot;,
  &quot;brand&quot;: &quot;joyent-minimal&quot;,
  &quot;max_physical_memory&quot;: 256,
  &quot;image_uuid&quot;: &quot;cfa9c88e-03f8-11eb-9980-879ff7980a9f&quot;,
  &quot;nics&quot;: [
    {
      &quot;nic_tag&quot;: &quot;stub0&quot;,
      &quot;ip&quot;: &quot;10.0.0.2&quot;,
      &quot;netmask&quot;: &quot;255.255.255.0&quot;,
      &quot;gateway&quot;: &quot;10.0.0.1&quot;,
      &quot;primary&quot;: &quot;1&quot;
    }
  ]
}
</code></pre>
<p>On the host:</p>
<pre><code>nictagadm add -l stub0
vmadm create -f client.json
</code></pre>
<p>In a separate window, zlogin into the client zone and start pinging an external ip with <code>ping -ns</code> e.g. <code>ping -ns 8.8.8.8</code><br>
So far no packets should be flowing, let&apos;s fix that.</p>
<p>Back out on the host</p>
<pre><code>vmadm create -f firewall-lx.json
</code></pre>
<p>Now zlogin into your lx branded &quot;firewall&quot; zone and let&apos;s get packets flowing (note how we invoke the native illumos tools from under <code>/native</code>):</p>
<pre><code>echo &quot;map eth0 10.0.0.2/32 -&gt; 0/32&quot; &gt; /etc/ipnat.conf
/native/usr/sbin/ipadm set-prop -p forwarding=on ipv4
/native/usr/sbin/ipf -E
/native/usr/sbin/ipnat -CF
/native/usr/sbin/ipnat -f /etc/ipnat.conf
</code></pre>
<p>At this point, your client zone should start seeing ping replies.<br>
Whether to use this in production and how to get it to survive reboots of the &quot;firewall&quot; zone is left as an exercise for the reader.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[ZFS send/receive]]></title><description><![CDATA[<p>A few weeks back I needed to migrate an entire ZFS pool from one machine to another. I used raw send to keep the stream compressed, and I used mbuffer to smooth out the send/receive (see the reference link at the bottom)</p><!--kg-card-begin: markdown--><p>First, prepare the receiving end by creating</p>]]></description><link>https://blog.shalman.org/zfs-send-receive/</link><guid isPermaLink="false">60071d497b79295ee4cb0de7</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Tue, 19 Jan 2021 18:10:54 GMT</pubDate><content:encoded><![CDATA[<p>A few weeks back I needed to migrate an entire ZFS pool from one machine to another. I used raw send to keep the stream compressed, and I used mbuffer to smooth out the send/receive (see the reference link at the bottom)</p><!--kg-card-begin: markdown--><p>First, prepare the receiving end by creating the pool. If this is not a bootable pool, just create it the simple way:</p>
<pre><code>poolname=rpool
disk=/dev/sda
zpool create ${poolname:?} ${disk:?}
</code></pre>
<p>Now start up mbuffer to receive the initial send stream (&quot;-s&quot; is for resumable receive in case the receive gets interrupted part way through)<br>
I&apos;m using a block size of 128k, a buffer size of 1G and listening on port 9090:</p>
<pre><code>mbuffer -s 128k -m 1G -I 9090 | zfs receive -Fs ${poolname:?}
</code></pre>
<p>Now switch over to the sending machine. Here we will take a snapshot, and then send it over mbuffer to the receving machine. We&apos;ll do a raw and resumable send.</p>
<pre><code>poolname=rpool
snapname=migration-snap1
receiver=receiver.example.com
zfs snapshot -r ${poolname:?}@${snapname:?}
zfs send -Rvw ${poolname:?}@${snapname:?} | mbuffer -s 128k -m 1G -O ${receiver:?}:9090
</code></pre>
<p>If the sending side has changed since the first snapshot completed sending, do an incremental send/receive to sync up the last changes (repeat as needed)</p>
<p>On receving machine, rerun the receiving command:</p>
<pre><code>mbuffer -s 128k -m 1G -I 9090 | zfs receive -Fs ${poolname:?}
</code></pre>
<p>On the sending machine, take another snapshot and send over the incremental stream:</p>
<pre><code>snap2=migration-snap2
zfs snapshot -r ${poolname:?}@${snap2:?}
zfs send -Rvw ${poolname:?}@${snapname:?} ${poolname:?}@${snap2:?} | mbuffer -s 128k -m 1G -O ${receiver:?}:9090
</code></pre>
<!--kg-card-end: markdown--><p>References:</p><ul><li><a href="https://web.archive.org/web/20130922023108/https://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send-zfs-receive/">https://web.archive.org/web/20130922023108/https://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send-zfs-receive/</a></li><li><a href="https://openzfs.github.io/openzfs-docs/man/8/zfs-send.8.html?ref=blog.shalman.org">https://openzfs.github.io/openzfs-docs/man/8/zfs-send.8.html</a></li><li><a href="https://openzfs.github.io/openzfs-docs/man/8/zfs-receive.8.html?ref=blog.shalman.org">https://openzfs.github.io/openzfs-docs/man/8/zfs-receive.8.html</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Migration Notes]]></title><description><![CDATA[Some notes I took down as I stood up my new zone hosted by https://mnx.io.]]></description><link>https://blog.shalman.org/migration-notes/</link><guid isPermaLink="false">5d9cc0e102dd2e6e4ae456cd</guid><category><![CDATA[ghost]]></category><category><![CDATA[salt]]></category><category><![CDATA[smartos]]></category><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Fri, 11 Oct 2019 00:47:36 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Some notes I took down as I stood up my new zone hosted by <a href="https://mnx.io/?ref=blog.shalman.org">https://mnx.io</a>.</p>
<h4 id="pkgsrcbranchswitch">Pkgsrc branch switch</h4>
<pre><code>pkgin up
pkgin fug
curl -LO https://pkgsrc.joyent.com/packages/SmartOS/bootstrap-upgrade/bootstrap-2019Q2-x86_64-upgrade.tar.gz
curl -LO https://pkgsrc.joyent.com/packages/SmartOS/bootstrap-upgrade/bootstrap-2019Q2-x86_64-upgrade.tar.gz.asc
curl -sS https://pkgsrc.joyent.com/pgp/DE817B8E.asc | gpg --import
gpg --verify bootstrap-2019Q2-x86_64-upgrade.tar.gz.asc
PKG_PATH=http://pkgsrc.joyent.com/packages/SmartOS/2019Q2/x86_64/All pkg_add -U pkg_install pkgin
gtar -xzvf bootstrap-2019Q2-x86_64-upgrade.tar.gz -C /
pkgin full-upgrade
rm bootstrap-2019Q2-x86_64-upgrade.tar.gz*
sm-set-hostname shalman-20191007
</code></pre>
<p>Reference: <a href="https://pkgsrc.joyent.com/install-on-illumos/?ref=blog.shalman.org#64bit-upgrade">https://pkgsrc.joyent.com/install-on-illumos/#64bit-upgrade</a></p>
<h4 id="salt">Salt</h4>
<pre><code>pkgin in salt
mkdir -p /srv/spm/salt
# put stuff into place under /srv/spm/salt
salt-call --local state.apply
</code></pre>
<h4 id="hurricaneelectrictunnel">Hurricane Electric Tunnel</h4>
<pre><code>dladm create-iptun -T ipv4 -a \
  local=67.158.54.193,remote=184.105.253.14 v4_he0
ipadm create-addr -T static -a \
  local=2001:470:1f10:251::2,remote=2001:470:1f10:251::1 v4_he0/v6
route -p add -inet6 default 2001:470:1f10:251::1
</code></pre>
<p>Reference: <a href="https://web.archive.org/web/20191011225153/https://blog.brianewell.com/hurricane-electric-on-smartos/">https://blog.brianewell.com/hurricane-electric-on-smartos/</a></p>
<h4 id="sslrelatedupdates">SSL related updates</h4>
<ul>
<li><a href="https://ssl-config.mozilla.org/?ref=blog.shalman.org">https://ssl-config.mozilla.org/</a></li>
<li><a href="https://letsencrypt.org/docs/caa/?ref=blog.shalman.org">https://letsencrypt.org/docs/caa/</a></li>
<li><a href="https://www.ssllabs.com/ssltest/index.html?ref=blog.shalman.org">https://www.ssllabs.com/ssltest/index.html</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Upcoming Downtime]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Just a heads-up that I have to migrate my domain off of the JPC and there will probably be a downtime of my blog and other services for an unknown duration (though I&apos;ll do my best to keep it as short as possible) to complete the migration.</p>
<p>It</p>]]></description><link>https://blog.shalman.org/upcoming-downtime/</link><guid isPermaLink="false">5d9cc0e102dd2e6e4ae456cc</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Fri, 04 Oct 2019 14:40:04 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Just a heads-up that I have to migrate my domain off of the JPC and there will probably be a downtime of my blog and other services for an unknown duration (though I&apos;ll do my best to keep it as short as possible) to complete the migration.</p>
<p>It might also take a while for me to restore IPv6 connectivity.</p>
<p>If you come across any broken links after I complete the migration, let me know.</p>
<p>Update: If you can see this message, clearly migration is nearly complete. This blog has been upgraded to the latest version of Ghost, and I&apos;m redirecting all traffic to HTTPs.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Wireguard - Android Road Warrior]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="motivation">Motivation</h2>
<p>There are a lot of blog posts and wiki pages about how to set up <a href="https://www.wireguard.com/?ref=blog.shalman.org">Wireguard</a>, but I still had to do a bunch of trial and error to come up with a configuration that worked for me. I have two goals:</p>
<ol>
<li>Secure all traffic from my Android phone</li></ol>]]></description><link>https://blog.shalman.org/wireguard-android-road-warrior/</link><guid isPermaLink="false">5d9cc0e102dd2e6e4ae456ca</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Tue, 01 Jan 2019 14:45:13 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="motivation">Motivation</h2>
<p>There are a lot of blog posts and wiki pages about how to set up <a href="https://www.wireguard.com/?ref=blog.shalman.org">Wireguard</a>, but I still had to do a bunch of trial and error to come up with a configuration that worked for me. I have two goals:</p>
<ol>
<li>Secure all traffic from my Android phone for privacy / when on unsecured WiFi.</li>
<li>Full access to my home network resources when away from home.</li>
</ol>
<p>Caveats:</p>
<ul>
<li>This does client key generation on the server, which is fine for this simple use case, but not a cryptographic best practice.</li>
<li>This sets up only a single client. If you need multiple clients, you&apos;ll have to get fancier.</li>
<li>As part of meeting my goals, <strong>ALL</strong> phone traffic goes through the VPN. That may not be your desired configuration.</li>
</ul>
<h2 id="preparation">Preparation</h2>
<p>You will need:</p>
<ol>
<li>The public IP address of your router (or a DNS record that points to it)</li>
<li>An open port on your router forwarded to wherever you run Wireguard</li>
<li>The IP address of the DNS server your phone should use when connected to your home network (maybe your router, maybe not)</li>
<li>Two addresses in a private subnet not used elsewhere on your home network</li>
</ol>
<h2 id="implementation">Implementation</h2>
<p>I hosted all of this in a VM running Ubuntu 18.04.1.<br>
At the end of this process, a QR Code is displayed to be scanned by the <a href="https://play.google.com/store/apps/details?id=com.wireguard.android&amp;ref=blog.shalman.org">Wireguard Android app</a>.<br>
This script is run as root <code>sudo bash -x simple-wireguard.sh</code>:</p>
<pre><code>#!/bin/bash -x

################ CHANGE THESE ##################
# Your Home IP or DNS record
WG_ADDRESS=wireguard.your.domain
# UDP port forwarded to this machine
WG_PORT=12345
# DNS entries for the client to use when on VPN
WG_DNS=192.168.1.1,8.8.8.8
# Unused private IPs for this connection
WG_SERVER_INT=172.16.17.1
WG_CLIENT_INT=172.16.17.2
################################################

add-apt-repository -y ppa:wireguard/wireguard
apt-get -y update
apt-get -y install wireguard qrencode

# Enable Packet Forwarding
echo net.ipv4.ip_forward=1 &gt; /etc/sysctl.d/wireguard.conf
sysctl -p /etc/sysctl.d/wireguard.conf

# Generate Keys and Configurations
cd /etc/wireguard
wg genkey | tee server.private | wg pubkey &gt; server.public
wg genkey | tee client.private | wg pubkey &gt; client.public

# Server Configuration sets up NAT
cat &gt;wg0.conf &lt;&lt;EOF
[Interface]
Address = ${WG_SERVER_INT}
SaveConfig = false
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o net0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o net0 -j MASQUERADE
ListenPort = ${WG_PORT}
PrivateKey = $(cat server.private)

[Peer]
PublicKey = $(cat client.public)
AllowedIPs = ${WG_CLIENT_INT}
EOF

cat &gt;client.conf &lt;&lt;EOF
[Interface]
Address = ${WG_CLIENT_INT}
PrivateKey = $(cat client.private)
DNS = ${WG_DNS}

[Peer]
PublicKey = $(cat server.public)
Endpoint = ${WG_ADDRESS}:${WG_PORT}
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 10
EOF

# Turn on and enable for boot
systemctl start wg-quick@wg0
systemctl enable wg-quick@wg0

# Show the QR Code
qrencode -t ansiutf8 &lt; client.conf
</code></pre>
<h2 id="bettertools">Better Tools</h2>
<p>I wanted something simple and comprehensible that I built myself, but there are tools out there that build fancier configurations that are recommended by smart people in this space:</p>
<ul>
<li><a href="https://github.com/trailofbits/algo?ref=blog.shalman.org">https://github.com/trailofbits/algo</a></li>
<li><a href="https://github.com/StreisandEffect/streisand?ref=blog.shalman.org">https://github.com/StreisandEffect/streisand</a></li>
</ul>
<p>Another option that is built atop <code>wireguard-go</code> is <a href="https://tailscale.com/?ref=blog.shalman.org">Tailscale</a>. Their service is proprietary, though many of their client implementations are open-source.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.wireguard.com/quickstart/?ref=blog.shalman.org">https://www.wireguard.com/quickstart/</a></li>
<li><a href="https://www.stavros.io/posts/how-to-configure-wireguard/?ref=blog.shalman.org">https://www.stavros.io/posts/how-to-configure-wireguard/</a></li>
<li><a href="https://wiki.debian.org/Wireguard?ref=blog.shalman.org">https://wiki.debian.org/Wireguard</a></li>
<li><a href="https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/?ref=blog.shalman.org">https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/</a></li>
<li><a href="https://emanuelduss.ch/2018/09/wireguard-vpn-road-warrior-setup/?ref=blog.shalman.org">https://emanuelduss.ch/2018/09/wireguard-vpn-road-warrior-setup/</a></li>
<li><a href="https://github.com/michaeljs1990/docs/blob/master/software/wireguard.md?ref=blog.shalman.org">https://github.com/michaeljs1990/docs/blob/master/software/wireguard.md</a></li>
</ul>
<!--kg-card-end: markdown--><p>Below are a couple of gists I worked on when helping someone else trying to use the code above:</p><!--kg-card-begin: html--><script src="https://gist.github.com/nshalman/211e3be2094cfac022e26a723fd935ae.js"></script><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Silly tricks with Docker in the JPC]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Message from 2018: I was going through my blog post drafts and found this post.<br>
I&apos;ve made few small tweaks to it that seem to be what I was hoping to add before publishing.<br>
If you&apos;ve ever wanted to replace your SSH access to a native</p>]]></description><link>https://blog.shalman.org/silly-tricks-with-docker-in-the-jpc/</link><guid isPermaLink="false">5d9cc0e102dd2e6e4ae456b8</guid><dc:creator><![CDATA[Nahum Shalman]]></dc:creator><pubDate>Mon, 19 Feb 2018 12:46:36 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Message from 2018: I was going through my blog post drafts and found this post.<br>
I&apos;ve made few small tweaks to it that seem to be what I was hoping to add before publishing.<br>
If you&apos;ve ever wanted to replace your SSH access to a native branded zone with <code>docker exec</code> access, this is the blog post for you. We now return you to the bleeding edge of at least 1 or 2 years ago:</p>
<p>As a quick pre-emptive caveat, this post describes using the Docker CLI tool basically to managed what Joyent are calling &quot;infrastructure containers&quot;. Classic illumos zones with many processes in them, not the kind of containers that you typically create and run with Docker. It&apos;s a how-to on using the Docker CLI instead of the CloudAPI tools you might usually use in the Joyent Public Cloud (JPC).</p>
<p>I stumbled across <a href="https://apidocs.joyent.com/docker/features/smartos?ref=blog.shalman.org">this gem</a> in the Joyent docs the other day. It turns out that you can use the Docker CLI tool to create and manage &quot;joyent-minimal&quot; branded zones. Getting Docker set up with your JPC account is beyond the scope of this blog post but it&apos;s covered <a href="https://docs.joyent.com/public-cloud/api-access/docker?ref=blog.shalman.org">here</a>.</p>
<p>As that first link describes, if instead of a regular image name you provide the uuid of a &quot;smartos&quot; type image it will be used to provision a joyent-minimal branded zone.</p>
<p>Let&apos;s fire up a recent image with 128 MB of RAM and a public IP:</p>
<pre><code>docker run -P -d -m 128 --name=tiny 390639d4-f146-11e7-9280-37ae5c6d53d4 /sbin/init
</code></pre>
<p>It will sidestep all the normal zone setup, so we have to manually set the default route:</p>
<pre><code>docker exec -it tiny /bin/bash -c &apos;route -p add default $(mdata-get sdc:nics | json 1.gateway)&apos;
</code></pre>
<p>Thanks to <a href="https://github.com/joyent/smartos-live/pull/339?ref=blog.shalman.org">changes I worked on a while back</a> you can import pretty much any service manifest you want quite easily to bring various services online.</p>
<p>Instead of SSH access, use the docker cli to log in to your container:</p>
<pre><code>docker exec -it tiny /bin/bash
</code></pre>
<p>Experiment with installing packages and enabling any necessary SMF services; have fun!</p>
<p>And of course, don&apos;t forget to delete this zone when you&apos;re done with it:</p>
<pre><code>docker rm -f tiny
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>