<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Filipe Fortes</title>
    <description>The latest articles on DEV Community by Filipe Fortes (@fortesdotcom).</description>
    <link>https://dev.to/fortesdotcom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F116840%2F53cc8cfc-9105-4030-8db3-6b83331b2ceb.png</url>
      <title>DEV Community: Filipe Fortes</title>
      <link>https://dev.to/fortesdotcom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fortesdotcom"/>
    <language>en</language>
    <item>
      <title>Linux disk encryption with LUKS and LVM</title>
      <dc:creator>Filipe Fortes</dc:creator>
      <pubDate>Fri, 28 Feb 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/fortesdotcom/linux-disk-encryption-with-luks-and-lvm-aeb</link>
      <guid>https://dev.to/fortesdotcom/linux-disk-encryption-with-luks-and-lvm-aeb</guid>
      <description>&lt;h4&gt;
  
  
  An unreasonable number of steps to get reasonable disk security on Linux
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YcJdoOYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/2020/linux-disk-encryption-with-luks-and-lvm/2017-downtown-seattle_hu292b0d6b94fcd6ef2222e71e16967253_1099656_800x0_resize_q75_box.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YcJdoOYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/2020/linux-disk-encryption-with-luks-and-lvm/2017-downtown-seattle_hu292b0d6b94fcd6ef2222e71e16967253_1099656_800x0_resize_q75_box.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don’t let lack of knowledge stop me from trying to run and maintain a few Linux machines. Just like &lt;a href="https://dev.to/2019/merging-piped-stdin-with-command-line-arguments-within-bash/"&gt;writing bash scripts&lt;/a&gt;, I’m always forgetting how I did things previously so I’m writing it all down this time so I can copy and paste it again later in a few years.&lt;/p&gt;

&lt;p&gt;I don’t reach tinfoil hat level paranoia, but I do like having some level of data security so thieves can’t read my journal and figure out which BTS member I’m currently crushing on (Jungkook). Full disk encryption is pretty easy on Windows or Mac, and it seems easy on Linux, but you always have to be your toes in the land of the penguin. Specifically, the following two requirements are typically at odds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Full disk encryption&lt;/li&gt;
&lt;li&gt;Ability to boot without being physically present&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’ve only ever used &lt;a href="https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup"&gt;LUKS&lt;/a&gt; for disk encryption because it’s the default with Debian and I’m too lazy to research alternatives. The default setup has a tiny unencrypted boot partition that prompts you to unlock the main disk so you can actually use the computer. This is fine for a desktop or laptop, but not really tenable for situations where you can’t physically type in the password on the machine.&lt;/p&gt;

&lt;p&gt;Fortunately, there’s a nifty package called &lt;a href="https://packages.debian.org/buster/dropbear-initramfs"&gt;&lt;code&gt;dropbear-initramfs&lt;/code&gt;&lt;/a&gt; which adds a barebones SSH server to that tiny boot partition which allows you to unlock the machine remotely. Installation is pretty straightforward, you’ll need to set up your SSH key by creating a &lt;code&gt;/etc/dropbear-initramfs/authorized_keys&lt;/code&gt; file and adding your public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/cryptroot-unlock" ssh-rsa &amp;lt;SSH public key goes here&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;command=/bin/cryptroot-unlock&lt;/code&gt; part is optional, but very convenient since it means you’ll automatically be prompted to unlock the drive whenever you connect to the server. It’s also a way to lock down the machine a bit more. Once you’ve added your key, make sure to set the correct permissions and make another offering to the boot gods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# File is ignored if permissions aren't strict
chmod 400 /etc/dropbear-initramfs/authorized_keys
# Changes don't take effect if you don't update!
sudo update-initramfs -u

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now reboot your machine and (assuming it can get network access) it will open up an SSH server so you can connect and input the encryption passphrase. Note that the server key for this miniserver is gonna be different than your server once booted. So I recommend doing the following in your &lt;code&gt;~/.ssh/config&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hostname *_unlock
  UserKnownHostsFile /home/fortes/.ssh/known_hosts_unlock

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make sure SSH doesn’t freak out and worry that your server is being hijacked all the time.&lt;/p&gt;

&lt;p&gt;So now the machine can boot without a sweet human caress, congratulations you might be done!&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding encrypted drives
&lt;/h2&gt;

&lt;p&gt;If you have more than one drive, you still have a little more work left. This will set up what is apparently called &lt;a href="https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS"&gt;LVM on LUKS&lt;/a&gt;, a popular alternative is called LUKS on LVM and it might be better for you? The &lt;a href="https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS"&gt;Arch Wiki&lt;/a&gt; has a lot of information that I definitely did not read.&lt;/p&gt;

&lt;p&gt;Make sure your drive is connected, and then you’ll need to figure out what device it’s been assigned. This is typically something like &lt;code&gt;/dev/sdb&lt;/code&gt; or whatever. The best way to find out which disk you want is via &lt;code&gt;lsblk&lt;/code&gt; (or possibly &lt;code&gt;sudo blkid&lt;/code&gt;, I can never remember). If the drive was previously formatted, you may need wipe out the existing partitions via &lt;code&gt;fdisk /dev/sdb&lt;/code&gt;. The interface is (of course) a bit cryptic, you’ll need to keep on hitting &lt;code&gt;d&lt;/code&gt; at the prompt to delete all the partitions. I &lt;em&gt;highly&lt;/em&gt; recommend double and triple checking which drive you’re operating on, since recovering from deleting all those partitions is not very fun. Or you can just YOLO, whatever I’m not your dad.&lt;/p&gt;

&lt;p&gt;Now that the drive is wiped, it’s time to set up encryption. You should generate a nice long passphrase and save it in your password manager. The partition can also be unlocked with the contents of a static file, and we’ll use that for the automatic unlocking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# You should be _very_ confident about this choice
export DRIVE_TO_ADD="/dev/sdc"

# Create a file full of random noise used
sudo dd if=/dev/random bs=32 count=1 of=/root/.data-keyfile
# Unless you trust everyone/everything with access to your machine, you should
# lock down permissions for the keyfile
sudo chmod 400 /root/.data-keyfile

# This will prompt you for a passphrase, pick a secure one and store it in
# your password manager (you should rarely, if ever, need to type it in)
sudo cryptsetup luksFormat ${DRIVE_TO_ADD}
# Add the generated file as a second encryption key (will prompt you for the
# passphrase you just generated)
sudo cryptsetup luksAddKey ${DRIVE_TO_ADD} /root/.data-keyfile

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The disk is now encrypted. We still need to do a few things to get it mounted automatically though. First, add an entry to &lt;code&gt;/etc/crypttab&lt;/code&gt; in order to make the disk decrypt on boot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Append to /etc/crypttab

# Find the disk UUID via `sudo blkid`, which will output something like:
# /dev/sdc: UUID="YOUR-DISK-UUID" TYPE="crypto_LUKS"
sdc_crypt UUID=YOUR-DISK-UUID /root/.data-keyfile luks,discard

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file gets used by the system to automatically decrypt drives at boot. Although the decryption key is a file on the system, it’s sitting the main (encrypted) drive that’s only accessible after unlocking the entire machine at boot.&lt;/p&gt;

&lt;p&gt;Now test to make sure it gets automatically decrypted via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cryptdisks_start sdc_crypt

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming no errors, you should have the unencrypted disk available at &lt;code&gt;/dev/mapper/sdc_crypt&lt;/code&gt;. In theory, you should now be able to format this directly via &lt;code&gt;mkfs.ext4&lt;/code&gt; or your favorite disk format.&lt;/p&gt;

&lt;p&gt;On my machines, I still go ahead and set up my partitions via LVM since that’s what Debian does by default and I’m just cargo culting my way through this whole thing. In theory there is a bunch of flexibility to be gained via LVM, but I’ve never actually learned how it all works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# You might need to do this LVM will complain about device filter
sudo wipefs -a ${DRIVE_TO_ADD}

# Create a bunch of LVM stuff that I don't understand
sudo pvcreate /dev/mapper/sdc_crypt # confirm with `pvdisplay /dev/mapper/sdc_crypt`
sudo vgcreate data-vg /dev/mapper/sdc_crypt # confirm with `vgdisplay data`
sudo lvcreate -n data -l100%FREE data-vg # confirm with `lvdisplay data`

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we’re ready to actually format the drive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkfs.ext4 -m 0 /dev/data-vg/data

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to automatically mount the drive, we need to edit &lt;code&gt;/etc/fstab&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add into /etc/fstab
/dev/mapper/data--vg-data /mnt/data ext4 defaults,user,noatime,nofail 0 2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test that the &lt;code&gt;/etc/fstab&lt;/code&gt; setup worked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mount -a

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila, you should now see your disk mounted at &lt;code&gt;/mnt/data&lt;/code&gt;, and all it took was a crazy number of error-prone steps written by a total stranger with, at best, a passing understanding of how it all works.&lt;/p&gt;

</description>
      <category>luks</category>
      <category>lvm</category>
    </item>
    <item>
      <title>Working From Everywhere</title>
      <dc:creator>Filipe Fortes</dc:creator>
      <pubDate>Wed, 17 Jul 2019 12:00:00 +0000</pubDate>
      <link>https://dev.to/fortesdotcom/working-from-everywhere-25f6</link>
      <guid>https://dev.to/fortesdotcom/working-from-everywhere-25f6</guid>
      <description>&lt;p&gt;For the past year and a half, I’ve been working remotely for &lt;a href="https://coda.io"&gt;Coda&lt;/a&gt;. Fortunately, this has worked well since the company was already distributed with offices in California and Washington State.&lt;/p&gt;

&lt;p&gt;Coda relies heavily on video conferencing, we use Zoom which has a &lt;a href="https://support.zoom.us/hc/en-us/articles/210707503-Virtual-Background"&gt;virtual background feature&lt;/a&gt; that lets you choose a custom image as your backdrop, absolutely fooling all your co-workers into thinking that you’re not actually working from home (assuming your co-workers are as gullible as mine).&lt;/p&gt;

&lt;p&gt;Zoom uses chroma key compositing to add a virtual background, which works best with a green backdrop since it doesn’t match non-Martian skin tones. I don’t like doing things halfway, so I decided to go all out and spend about $70 to buy a &lt;a href="https://amzn.to/2Ye3h4O"&gt;green screen&lt;/a&gt; and &lt;a href="https://amzn.to/32rIjip"&gt;stand&lt;/a&gt; in order to add to make the most realistic virtual scene possible.&lt;/p&gt;

&lt;p&gt;The set up is relatively painless and can be done in a couple of minutes, as shown here by a handsome anonymous model:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/x0DWXTz-Kew"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Every once in a while, I remember to take screen captures of the backgrounds I’ve used. I’ve collected a few here (I’ll try to update these, but no promises):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CRASpynI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/media/2019-green-screen-montage-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CRASpynI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/media/2019-green-screen-montage-2.jpg" alt=""&gt;&lt;/a&gt;Dogs and Cats live together at the US Open before the Benfica match in a Black Hole within the White House Sauna which arrived via NYC subway to the Indy 500&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IZg210-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/media/2019-green-screen-montage-3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IZg210-b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/media/2019-green-screen-montage-3.jpg" alt=""&gt;&lt;/a&gt;English countryside in Bellevue / West Village with Winterfell's armies supporting Wreck-It Ralph in the Spider-Verse in Bliss on Mars in King's Landing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p3Pheq7E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/media/2019-green-screen-montage-4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p3Pheq7E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://fortes.com/media/2019-green-screen-montage-4.jpg" alt=""&gt;&lt;/a&gt;King's Landing gets Hamilton with source code in a doctor's office on the NYSE candle-lit floor inside an airplane hosting the Democratic debates with E.T. in the background.&lt;/p&gt;

&lt;p&gt;Have suggestions for an upcoming background? Let me know!&lt;/p&gt;

</description>
      <category>remoteworking</category>
      <category>remotework</category>
      <category>greenscreen</category>
      <category>chromakey</category>
    </item>
    <item>
      <title>Merging piped `stdin` with command-line arguments within Bash</title>
      <dc:creator>Filipe Fortes</dc:creator>
      <pubDate>Tue, 02 Apr 2019 16:00:00 +0000</pubDate>
      <link>https://dev.to/fortesdotcom/merging-piped-stdin-with-command-line-arguments-within-bash-1h3j</link>
      <guid>https://dev.to/fortesdotcom/merging-piped-stdin-with-command-line-arguments-within-bash-1h3j</guid>
      <description>&lt;p&gt;I am computer nerd who is easily seduced by &lt;a href="https://xkcd.com/1319/"&gt;automation&lt;/a&gt;, which means I end up writing a fair number of shell scripts. Even though I’ve written my fair share of Bash, my small primate brain never quite grasps the language and I always copy-paste my way through the task at hand, absorb nothing, and then pat myself on the back for being such a &lt;em&gt;1337 h4x0r&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Typically my needs are quite pedestrian, and I can immediately find an answer to plagiarize. My latest script, however, wasn’t solved within seconds so I’ve written up the solution for my very handsome future self.&lt;/p&gt;

&lt;h2&gt;
  
  
  The “Problem”
&lt;/h2&gt;

&lt;p&gt;My script takes one or more command-line parameters, which is straightforward to invoke when you know the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Called via command-line arguments&lt;/span&gt;
my_script item_one item_two

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In other cases, the values I’m passing in are the output of some other command. As a &lt;a href="https://linux.die.net/Linux-CLI/c1089.htm"&gt;godly Unix user&lt;/a&gt;, my instinct is to pipe the output (&lt;code&gt;printf&lt;/code&gt; just for illustration):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Called with piped input, one argument per line&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"item_one&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;item_two"&lt;/span&gt; | my_script

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The argument-handling Bash code I copy-paste every time only handles command-line arguments, and completely ignores any piped input. Here’s code that will read in the piped input and convert to command-line arguments, one per line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Copy command-line arguments over to new array&lt;/span&gt;
&lt;span class="nv"&gt;ARGS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Read in from piped input, if present, and append to newly-created array&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[!&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 0]&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;readarray STDIN_ARGS &amp;lt; /dev/stdin
  &lt;span class="nv"&gt;ARGS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;STDIN_ARGS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Single loop to process all arguments&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;ARG &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ARGS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ARG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I’ve already forgotten I wrote this code, so don’t ask me what it does. I’m just gonna copy-paste it again in a few months, leave me alone!&lt;/p&gt;

&lt;p&gt;Note that you can get around supporting piped input if you’re just willing to use &lt;code&gt;xargs&lt;/code&gt; (which I also make sure to regularly forget how to use):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is way easier than what I just showed you&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"item_one&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;item_two"&lt;/span&gt; | xargs my_script

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Farewell, future self. Be glad that your tiny brain retains the vital lyrics to &lt;em&gt;Ice Ice Baby&lt;/em&gt; instead of something as useless as &lt;code&gt;xargs&lt;/code&gt; and Bash arrays.&lt;/p&gt;

</description>
      <category>bash</category>
    </item>
  </channel>
</rss>
